From 56907d24b6c168af769ebb2a4fc6f332f5ba3b92 Mon Sep 17 00:00:00 2001 From: quality Date: Mon, 5 Oct 2026 01:01:23 -0400 Subject: [PATCH] test: pin parentOf's empty-prefix fallback in the overlay machinery parentOf() rejects an overlay path the real data does not have with `${label}: "${walked.join('.') || dottedPath}" is not an object ...` and the `|| dottedPath` arm was the file's only uncovered region: npm run test:unit:coverage reported tests/tools/e2e-data-fixtures.cjs at 100.00% lines but 98.59% regions, uncovered at line 130. The existing non-object-parent test walks one segment before the array stops it, so it only ever reaches the `walked.join('.')` arm. The fallback is what the message uses when the *first* segment fails and there is no prefix to name; without it the overlay is rejected with "" is not an object in the real data, which identifies no path. It is reachable rather than defensive: applyOverlay validates the overlay document but never the real data, so a data file parsed as a top-level array lands here on its first segment. Adds one case driving an array, null and two non-object primitives -- each disjunct of the guard -- and asserting the message names the whole dotted path. tests/tools/e2e-data-fixtures.cjs is now 100.00% regions. No source change: the fallback was correct, only unpinned. Closes #1077 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: quality --- tests/e2e-data-fixtures.test.mjs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/e2e-data-fixtures.test.mjs b/tests/e2e-data-fixtures.test.mjs index d182a45e..9d7262da 100644 --- a/tests/e2e-data-fixtures.test.mjs +++ b/tests/e2e-data-fixtures.test.mjs @@ -82,6 +82,29 @@ test('setting through a non-object parent is rejected', () => { ); }); +// The test above walks one segment before it throws, so the error names the +// prefix it reached. Nothing reached the other arm of that message. When the +// very first segment fails there is no prefix: `walked.join('.')` is '', and +// without the `|| dottedPath` fallback the overlay would be rejected with +// `"" is not an object in the real data`, naming nothing a reader could act +// on. +// +// It is reachable because applyOverlay validates the *overlay* document but +// never the real data it patches: `overlaySource` hands it whatever +// `JSON.parse` returned for the data file, which is an object today only +// because every file under data/ happens to be one. A data file regenerated +// as a top-level array — the shape a list of records most naturally takes — +// would land here, which is exactly the case the message has to explain. +test('a document that is not an object names the whole path, not an empty prefix', () => { + for (const document of [[], null, 'text', 7]) { + assert.throws( + () => applyOverlay(document, overlay({ set: { 'a.b': 1 } }), 'f'), + /"a\.b" is not an object in the real data/, + `${JSON.stringify(document) ?? 'undefined'}: the message must name the path`, + ); + } +}); + test('setting a leaf whose parent is an array is rejected', () => { assert.throws( () =>