Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions scripts/lib/validate-utils.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -271,23 +271,32 @@ export function checkPublishableSourceUrl(errors, path, value) {
* Push a "duplicate or missing id" error when `id` is falsy or already in
* `seen`, then record `id` in `seen` regardless.
*
* validate-case-studies.mjs and validate-radar-reports.mjs each carried an
* validate-case-studies.mjs, validate-radar-reports.mjs,
* validate-metrics.mjs, and validate-launch-metrics.mjs each carried an
* independent copy of this per-entry id-dedup check, byte-identical apart
* from the `errors`/`ids` variable names.
* from the `errors`/`ids` variable names and the entry-type noun in the
* message.
*
* @param {Array<Object>} errors - Array to accumulate errors.
* @param {string} path - File path or identifier used as the error's path.
* @param {unknown} id - Candidate entry id (entry.id, not a display fallback).
* @param {Set<unknown>} seen - Set of ids already encountered; mutated.
* @param {string} [message] - Error message; defaults to the generic form.
* @returns {boolean} Whether `id` passed the check.
*/
export function checkDuplicateOrMissingId(errors, path, id, seen) {
export function checkDuplicateOrMissingId(
errors,
path,
id,
seen,
message = 'duplicate or missing id',
) {
const ok = Boolean(id) && !seen.has(id);
if (!ok) {
errors.push({
path,
severity: 'error',
message: 'duplicate or missing id',
message,
});
}
seen.add(id);
Expand Down
15 changes: 8 additions & 7 deletions scripts/validate-launch-metrics.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env node
import { readFileSync } from 'node:fs';
import {
checkDuplicateOrMissingId,
checkIsoTimestamp,
checkUrl as checkUrlImpl,
reportAndExit,
Expand Down Expand Up @@ -72,13 +73,13 @@ if (signals.length < 3 || signals.length > 5)
const ids = new Set();
for (const signal of signals) {
const path = signal.id || '(missing id)';
if (!signal.id || ids.has(signal.id))
errors.push({
path,
severity: 'error',
message: 'duplicate or missing signal id',
});
ids.add(signal.id);
checkDuplicateOrMissingId(
errors,
path,
signal.id,
ids,
'duplicate or missing signal id',
);
if (!signal.label)
errors.push({ path, severity: 'error', message: 'missing label' });
if (!signal.sourceUrl || !signal.collectedAt)
Expand Down
15 changes: 8 additions & 7 deletions scripts/validate-metrics.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env node
import { readFileSync } from 'node:fs';
import {
checkDuplicateOrMissingId,
checkIsoTimestamp,
checkUrl as checkUrlImpl,
reportAndExit,
Expand Down Expand Up @@ -69,13 +70,13 @@ checkUrl(
);
const ids = new Set();
for (const metric of data.metrics || []) {
if (!metric.id || ids.has(metric.id))
errors.push({
path: metric.id,
severity: 'error',
message: 'duplicate or missing metric id',
});
ids.add(metric.id);
checkDuplicateOrMissingId(
errors,
metric.id,
metric.id,
ids,
'duplicate or missing metric id',
);
if (
metric.value === undefined ||
metric.value === null ||
Expand Down
19 changes: 19 additions & 0 deletions tests/validate-utils.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,25 @@ test('checkDuplicateOrMissingId reports a missing id and a repeat of one already
}
});

test('checkDuplicateOrMissingId uses a caller-supplied message when given one', () => {
const errors = [];
const seen = new Set();
checkDuplicateOrMissingId(
errors,
'display-path',
undefined,
seen,
'duplicate or missing metric id',
);
assert.deepEqual(errors, [
{
path: 'display-path',
severity: 'error',
message: 'duplicate or missing metric id',
},
]);
});

test('checkIsoTimestamp accepts a strict ISO 8601 UTC value and pushes no error', () => {
const errors = [];
const ok = checkIsoTimestamp(
Expand Down
Loading