fix(docs): [SITE-ROUTES-01] track added HTML without replacing baseline

This commit is contained in:
Harvey Zhao committed 2026-09-15 19:40:48 +08:00
1 parent 876fa4c328
commit 210484c443
12 files changed
+612 -11

No files matched your search

+14 -2
View File
@@ -39,6 +39,16 @@ export function validateDemoInventory(inventory, additions = JSON.parse(read('re
assert.equal(inventory.schemaVersion, 1)
assert.equal(additions.schemaVersion, 1)
const taskIds = new Set(JSON.parse(read('refactor/tasks.json')).tasks.map(task => task.id))
const addedPages = additions.pages ?? []
assert(Array.isArray(addedPages), 'Invalid added pages')
for (const page of addedPages) {
assert(/^docs\/(?:[a-z0-9][a-z0-9._-]*\/)*[a-z0-9][a-z0-9._-]*\.html$/.test(page.source), 'Invalid added HTML path')
const references = ['introducedBy', 'introducedAfter'].filter(key => Object.hasOwn(page, key))
assert.equal(references.length, 1, 'Page requires one introduction reference')
assert(/^[a-f0-9]{40}$/.test(page[references[0]]), 'Missing page introduction commit')
assert(taskIds.has(page.owner) && page.finalDemoOwner === 'EX-03', 'Missing added page owner')
assert.equal(page.route, `/${page.source.slice(5)}`.replace(/index\.html$/, ''), 'Added page route does not match its HTML path')
}
for (const addition of additions.examples) {
assert(/^docs\/assets\/example\/[a-z0-9.]+\.js$/.test(addition.source), 'Invalid added example path')
assert(/^[a-f0-9]{40}$/.test(addition.introducedBy), 'Missing introduction commit')
@@ -48,7 +58,9 @@ export function validateDemoInventory(inventory, additions = JSON.parse(read('re
const sources = [...inventory.examples, ...additions.examples].map(item => item.source)
assert.equal(new Set(sources).size, sources.length, 'Duplicate baseline/addition paths')
assert.deepEqual(sources.sort(), fs.readdirSync(path.join(root, 'docs/assets/example')).filter(name => name.endsWith('.js')).map(name => `docs/assets/example/${name}`).sort(), 'Demo file coverage drift')
assert.deepEqual(inventory.pages.map(item => item.source).sort(), htmlFiles(), 'HTML route coverage drift')
const pages = [...inventory.pages, ...addedPages].map(item => item.source)
assert.equal(new Set(pages).size, pages.length, 'Duplicate baseline/addition HTML paths')
assert.deepEqual(pages.sort(), htmlFiles(), 'HTML route coverage drift')
assert.deepEqual(inventory.examples.flatMap(item => item.menuLinks).sort(), menuLinks().sort(), 'Editor link coverage drift')
assert.deepEqual(inventory.packages.map(item => item.name).sort(), JSON.parse(read('refactor/package-inventory.json')).packages.map(item => item.name).sort(), 'Package demo coverage drift')
const names = new Set(inventory.examples.map(item => item.name))
@@ -70,6 +82,6 @@ if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.me
const inventory = JSON.parse(fs.readFileSync(filename, 'utf8'))
validateDemoInventory(inventory)
const additions = JSON.parse(read('refactor/baselines/demo-additions.json'))
console.log(`Demo coverage: ${inventory.examples.length} historical + ${additions.examples.length} added examples, ${inventory.pages.length} HTML paths, ${inventory.packages.length} packages; no browser pass implied`)
console.log(`Demo coverage: ${inventory.examples.length} historical + ${additions.examples.length} added examples, ${inventory.pages.length} historical + ${additions.pages?.length || 0} added HTML paths, ${inventory.packages.length} packages; no browser pass implied`)
}
}
+27
View File
@@ -24,6 +24,7 @@ test('Demo inventory rejects missing files, routes and ecosystem packages', () =
test('Demo additions require complete paths, specific routes and task ownership', () => {
const inventory = JSON.parse(fs.readFileSync(path.join(refactorDir, 'baselines/demo-inventory.json'), 'utf8'))
const additions = JSON.parse(fs.readFileSync(path.join(refactorDir, 'baselines/demo-additions.json'), 'utf8'))
assert.doesNotThrow(() => validateDemoInventory(inventory, additions))
for (const mutate of [
value => value.examples.pop(),
value => value.examples.push(value.examples[0]),
@@ -37,3 +38,29 @@ test('Demo additions require complete paths, specific routes and task ownership'
assert.throws(() => validateDemoInventory(inventory, changed))
}
})
test('Added HTML pages retain exact routes, unique paths and accountable introductions', () => {
const inventory = JSON.parse(fs.readFileSync(path.join(refactorDir, 'baselines/demo-inventory.json'), 'utf8'))
const additions = JSON.parse(fs.readFileSync(path.join(refactorDir, 'baselines/demo-additions.json'), 'utf8'))
assert.doesNotThrow(() => validateDemoInventory(inventory, additions))
const pending = structuredClone(additions)
delete pending.pages[0].introducedBy
pending.pages[0].introducedAfter = JSON.parse(fs.readFileSync(path.join(refactorDir, 'tasks.json'), 'utf8')).baselineCommit
assert.doesNotThrow(() => validateDemoInventory(inventory, pending), 'A new page can record its pre-change baseline without requiring its own future commit hash')
for (const [mutate, error] of [
[value => value.pages.pop(), /HTML route coverage drift/],
[value => value.pages.push(value.pages[0]), /Duplicate baseline\/addition HTML paths/],
[value => value.pages[0].source = 'docs/document/../private.html', /Invalid added HTML path/],
[value => value.pages[0].route += '?ignored=1', /Added page route does not match its HTML path/],
[value => value.pages[0].owner = 'UNKNOWN-01', /Missing added page owner/],
[value => value.pages[0].finalDemoOwner = 'SITE-01', /Missing added page owner/],
[value => value.pages[0].introducedBy = '', /Missing page introduction commit/],
[value => value.pages[0].introducedAfter = value.pages[0].introducedBy, /Page requires one introduction reference/],
[value => delete value.pages[0].introducedBy, /Page requires one introduction reference/],
[value => value.pages = false, /Invalid added pages/],
]) {
const changed = structuredClone(additions)
mutate(changed)
assert.throws(() => validateDemoInventory(inventory, changed), error)
}
})