The tables gate also fails when a skipped build-only table is named by anything shipped, reading the list from generate-tree
This commit is contained in:
parent
48006a51be
commit
59a3cbc6ba
2 changed files with 28 additions and 11 deletions
|
|
@ -12,7 +12,11 @@
|
|||
* their `card-` pattern.
|
||||
* (b) every literal `tables/<name>.json` a shipped file fetches EXISTS in the tree, so a skip list can never
|
||||
* take away a table a map needs.
|
||||
* `--poison` plants an unnamed table into the shipped list and drops a fetched one; both must be caught.
|
||||
* (c) every table on generate-tree's TABLES_BUILD_ONLY list (read from the script, never restated here) is
|
||||
* named by NOTHING shipped. Five fetches compute their name (`${base}/tables/${file}.json` from a config or
|
||||
* a quoted literal), which (b) cannot see; a skipped stem named anywhere shipped would be one of them.
|
||||
* `--poison` plants an unnamed table, drops a fetched one and names a skipped stem in a shipped file; all three
|
||||
* must be caught.
|
||||
* `--tree <dir>` checks another built tree (default public/dx-maps). Exit 0 pass · 1 fail · 75 not measured.
|
||||
*/
|
||||
import { readdirSync, readFileSync, statSync, existsSync } from 'node:fs'
|
||||
|
|
@ -37,36 +41,49 @@ let corpus = ''
|
|||
}
|
||||
})(TREE)
|
||||
|
||||
// The build-only list, read from generate-tree.mjs itself so this check and the skip can never disagree.
|
||||
const GT = join(resolve('.'), 'internal', 'generate-tree.mjs')
|
||||
const block = existsSync(GT) ? (readFileSync(GT, 'utf8').match(/TABLES_BUILD_ONLY = \[([\s\S]*?)\]/) || [])[1] : null
|
||||
if (!block) { console.log('TABLES-SHIPPED-ARE-USED: NOT MEASURED — no TABLES_BUILD_ONLY list in internal/generate-tree.mjs'); process.exit(75) }
|
||||
const BUILD_ONLY = [...block.matchAll(/'([^']+\.json)'/g)].map((m) => m[1])
|
||||
|
||||
const CARD = /^card-[0-9a-f]+\.json$/
|
||||
const esc = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
||||
const named = (file) => new RegExp(`["'\`/]${esc(file.replace(/\.json$/, ''))}(\\.json)?["'\`]`).test(corpus)
|
||||
const namedIn = (text, file) => new RegExp(`["'\`/]${esc(file.replace(/\.json$/, ''))}(\\.json)?["'\`]`).test(text)
|
||||
const named = (file) => namedIn(corpus, file)
|
||||
const cardsNamed = /tables\/card-|card-\$\{|["'`]card-["'`]\s*\+/.test(corpus)
|
||||
const fetched = [...new Set([...corpus.matchAll(/tables\/([a-z0-9][a-z0-9_-]*)\.json/g)].map((m) => m[1] + '.json'))]
|
||||
|
||||
function verdict(shipped) {
|
||||
const unnamed = shipped.filter((f) => !CARD.test(f) && !named(f))
|
||||
function verdict(shipped, text = corpus) {
|
||||
const unnamed = shipped.filter((f) => !CARD.test(f) && !namedIn(text, f))
|
||||
const cards = shipped.filter((f) => CARD.test(f))
|
||||
const cardFail = cards.length && !cardsNamed
|
||||
const missing = fetched.filter((f) => !shipped.includes(f))
|
||||
return { unnamed, cards: cards.length, cardFail, missing }
|
||||
const skippedNamed = BUILD_ONLY.filter((f) => namedIn(text, f))
|
||||
return { unnamed, cards: cards.length, cardFail, missing, skippedNamed }
|
||||
}
|
||||
|
||||
const shipped = readdirSync(TABLES).filter((f) => f.endsWith('.json'))
|
||||
if (POISON) {
|
||||
const firstFetched = fetched.find((f) => shipped.includes(f))
|
||||
const r = verdict([...shipped.filter((f) => f !== firstFetched), 'poison-unnamed-table.json'])
|
||||
const plant = BUILD_ONLY[0]
|
||||
const r = verdict([...shipped.filter((f) => f !== firstFetched), 'poison-unnamed-table.json'], corpus + `\nfetch(base + "/tables/${plant}")\n`)
|
||||
const caughtA = r.unnamed.includes('poison-unnamed-table.json'), caughtB = !!firstFetched && r.missing.includes(firstFetched)
|
||||
const caughtC = r.skippedNamed.includes(plant)
|
||||
console.log(`poison (a) a shipped table nothing names: ${caughtA ? 'caught' : 'MISSED'}`)
|
||||
console.log(`poison (b) a fetched table not shipped (${firstFetched || 'none fetched'}): ${caughtB ? 'caught' : 'MISSED'}`)
|
||||
console.log(caughtA && caughtB ? 'POISON OK: 2 caught' : 'POISON FAILED')
|
||||
process.exit(caughtA && caughtB ? 0 : 1)
|
||||
console.log(`poison (c) a skipped table named by a shipped file (${plant}): ${caughtC ? 'caught' : 'MISSED'}`)
|
||||
console.log(caughtA && caughtB && caughtC ? 'POISON OK: 3 caught' : 'POISON FAILED')
|
||||
process.exit(caughtA && caughtB && caughtC ? 0 : 1)
|
||||
}
|
||||
|
||||
const r = verdict(shipped)
|
||||
console.log(`build-only list: ${BUILD_ONLY.length} tables, none may be named by a shipped file`)
|
||||
console.log(`tree ${TREE}: ${shipped.length} table files (${r.cards} card shards${r.cards ? (cardsNamed ? ', named by their card- pattern' : ', NOT named') : ''}); ${fetched.length} fetched by a literal tables/ path`)
|
||||
for (const f of r.unnamed) console.log(`FAIL shipped but named by nothing in the tree: ${f}`)
|
||||
if (r.cardFail) console.log('FAIL card shards ship but no shipped file names the card- pattern')
|
||||
for (const f of r.missing) console.log(`FAIL fetched as tables/${f} but not shipped`)
|
||||
const n = r.unnamed.length + (r.cardFail ? 1 : 0) + r.missing.length
|
||||
console.log(n ? `TABLES-SHIPPED-ARE-USED: FAIL — ${n} problem(s)` : 'TABLES-SHIPPED-ARE-USED: PASS — every shipped table is named, every fetched one ships')
|
||||
for (const f of r.skippedNamed) console.log(`FAIL skipped as build-only but named by a shipped file (a computed fetch would 404): ${f}`)
|
||||
const n = r.unnamed.length + (r.cardFail ? 1 : 0) + r.missing.length + r.skippedNamed.length
|
||||
console.log(n ? `TABLES-SHIPPED-ARE-USED: FAIL — ${n} problem(s)` : 'TABLES-SHIPPED-ARE-USED: PASS — every shipped table is named, every fetched one ships, no skipped one is named')
|
||||
process.exit(n ? 1 : 0)
|
||||
|
|
|
|||
|
|
@ -359,7 +359,7 @@
|
|||
"dev": "bun x vite",
|
||||
"fix:sri": "node internal/fix-sri.mjs",
|
||||
"gallery": "node internal/generate-gallery.mjs",
|
||||
"gates:post": "node internal/run-parallel.mjs --label=post -- check:capability-derived check:drop check:parse verify check:sri check:public-hygiene check:label-joins check:facet-cascade check:facet-one-field check:heartbeat check:kpi-unit check:composite-reg check:descriptions check:no-abs-paths check:no-codename check:dep-names check:composite-srcs check:embed-targets check:nested-token check:i18n-parity check:tabs-localized check:packets-all check:packet-strings-parity check:zone-census check:zoning-declared check:share-policy check:library-index check:csv-shape check:capability-citations check:catalog-identity check:no-orphan-gates check:quoted-scripts check:script-flags check:capability-exemplars check:packet-fixture check:packet-browser check:provider-switch check:locale-reachable check:url-resolver check:manifest-covers check:one-palette check:pin-dim-slider check:legend-source check:clustering-modes check:composite-embed-knobs check:composite-locale-leaks check:linked-vocabulary check:wp-embed check:dashboard-geocoder-provider check:leaf-engine-per-provider check:auto-engine check:engine-contract check:map-props-unit check:composites-mount check:composite-interop check:no-free-identifiers check:map-fly-reduced-motion check:mst-clustering check:list-prop-unit check:profiles-mount check:cdn-pins check:no-eval check:popup-escaping check:i18n-treeshake check:pinned-umd check:one-palette:self-test check:no-cross-plugin-imports check:no-cross-plugin-imports:self-test check:map-attribution check:studio-rail check:approx-pin-note check:embedder-keys check:provider-for check:legend-logical-insets check:legend-logical-insets:self-test check:optional-t-equivalence check:text-highlight check:religion-label-not-value check:i18n-stopped-scope check:no-silent-engine check:no-silent-engine:self-test check:regions-uses-library check:shadow-css-parses check:square-map-controls check:preset-config-merge check:instance-config-keys check:frozen-labels check:plural-forms check:region-fill-repaint check:region-paint-single-source check:poster-print-fallback check:posters-exportable check:country-names check:reduced-motion check:no-dead-library check:universal-props check:readme-size check:tree-relative check:leaf-hints check:snippet-engine check:snippet-engine:self-test check:embed-base check:link-coverage check:no-public-binds check:shared-reached check:tree-weight check:no-fleet-names:self-test check:pin-hint-floor:self-test check:poster-sizes:self-test check:shell-header:self-test check:preview-flag-dev-only:self-test check:poster-type-registry:self-test check:host-floor:self-test check:phone-print-keep:self-test check:pinned-fetch-fresh:self-test",
|
||||
"gates:post": "node internal/run-parallel.mjs --label=post -- check:capability-derived check:drop check:parse verify check:sri check:public-hygiene check:tables-shipped-are-used check:label-joins check:facet-cascade check:facet-one-field check:heartbeat check:kpi-unit check:composite-reg check:descriptions check:no-abs-paths check:no-codename check:dep-names check:composite-srcs check:embed-targets check:nested-token check:i18n-parity check:tabs-localized check:packets-all check:packet-strings-parity check:zone-census check:zoning-declared check:share-policy check:library-index check:csv-shape check:capability-citations check:catalog-identity check:no-orphan-gates check:quoted-scripts check:script-flags check:capability-exemplars check:packet-fixture check:packet-browser check:provider-switch check:locale-reachable check:url-resolver check:manifest-covers check:one-palette check:pin-dim-slider check:legend-source check:clustering-modes check:composite-embed-knobs check:composite-locale-leaks check:linked-vocabulary check:wp-embed check:dashboard-geocoder-provider check:leaf-engine-per-provider check:auto-engine check:engine-contract check:map-props-unit check:composites-mount check:composite-interop check:no-free-identifiers check:map-fly-reduced-motion check:mst-clustering check:list-prop-unit check:profiles-mount check:cdn-pins check:no-eval check:popup-escaping check:i18n-treeshake check:pinned-umd check:one-palette:self-test check:no-cross-plugin-imports check:no-cross-plugin-imports:self-test check:map-attribution check:studio-rail check:approx-pin-note check:embedder-keys check:provider-for check:legend-logical-insets check:legend-logical-insets:self-test check:optional-t-equivalence check:text-highlight check:religion-label-not-value check:i18n-stopped-scope check:no-silent-engine check:no-silent-engine:self-test check:regions-uses-library check:shadow-css-parses check:square-map-controls check:preset-config-merge check:instance-config-keys check:frozen-labels check:plural-forms check:region-fill-repaint check:region-paint-single-source check:poster-print-fallback check:posters-exportable check:country-names check:reduced-motion check:no-dead-library check:universal-props check:readme-size check:tree-relative check:leaf-hints check:snippet-engine check:snippet-engine:self-test check:embed-base check:link-coverage check:no-public-binds check:shared-reached check:tree-weight check:no-fleet-names:self-test check:pin-hint-floor:self-test check:poster-sizes:self-test check:shell-header:self-test check:preview-flag-dev-only:self-test check:poster-type-registry:self-test check:host-floor:self-test check:phone-print-keep:self-test check:pinned-fetch-fresh:self-test",
|
||||
"gates:pre": "node internal/run-parallel.mjs --label=pre -- check:template-literal check:mjs-parse check:sfc-parse check:tab-radius check:synced-css check:doc-scripts check:setup-order check:package-json-unique-keys check:no-repo-pb-hooks check:no-credentials-omit check:no-credentials-omit:self-test check:shadow-reduced-motion check:poster-action-print check:targets check:targets:self-test check:browser-gates-guarded check:pin-selection check:facet-shape check:hardcoded-english:self-test check:list-selection check:selector-fields check:upg-zone-joins check:gospel-set-charts check:gospel-set-fit check:describe-group check:one-scroll-container check:packet-charts check:pins-in-state check:fork-leaders check:circular-layout check:composite-token-url check:language-tree-layout check:i18n-keys-exist check:i18n-never-translated check:packet-variants check:profile-table check:element-bootstrap check:embed-url-absolute check:frame-target check:language-tree-model check:map-menu-anchor check:selection-kinds check:tiered-points check:whiteboard-projection check:mercator-slice check:ring-vocabulary check:map-props-unit check:mobile-gating check:provide-shadowing check:legend-top-offset check:cdn-cache check:plural-forms check:select-zone-race check:script-registry check:map-control-overlap check:poster-attribution check:board-map-options check:gospel-whiteboard check:packet-map-missing-loud check:poster-layout-optin check:ported-globals-identical check:ring-bands check:packet-a1-structure check:india-states check:batch-selection-export check:zone-title-tier-a check:evangelical-share check:map-labels check:packet-offline check:help-reachable check:gated-not-in-tree check:window-globals-released check:legend-data-contract check:no-internal-role-nouns check:poster-fetch-guard check:people-group-records check:sentence-slots check:popup-href-escaped check:popup-pan-controls check:country-map-refetch check:pane-config-reforward check:viewport-meta check:viewport-meta:self-test check:label-key-coverage check:poster-browser-equiv check:poster-render-pinned check:country-sheet-one-path check:country-sheet-one-path:self-test check:side-lanes check:side-lanes:self-test check:poster-section check:poster-section:self-test check:posterverse-shelf check:host-locale-fetch check:print-frame-reclaim check:click-sheet check:coverage-consistent:chained check:coverage-consistent:poison check:dashboard-filter-a11y check:filter-multivalue check:hover-channel check:kit-options-reachable check:layout-key-namespaced check:legend-mirrors check:map-unmount-race check:no-conflict-markers check:series-isolation check:snapshot-guard check:stale-sweep-claim check:surfaces-read-the-tier check:translator-contacts check:wall-wysiwyg check:wall-print-watch check:wall-no-bg-photos check:wall-pan check:template-i18n check:list-pattern-doc check:shadow-style-labels-unique check:grid-image-loading check:retry-fetch check:panel-sheets check:poster-wall-host-seams check:poster-sections check:poster-sections:self-test check:poster-design-catalogue check:poster-design-catalogue:self-test check:upg100-zone-copy check:upg100-zone-copy:self-test check:wall-photo-weight check:no-fleet-names check:pin-hint-floor check:poster-sizes check:upg-count check:shell-header check:pg-name-gate check:preview-flag-dev-only check:poster-type-registry check:host-floor check:phone-print-keep check:pinned-fetch-fresh check:view-address check:view-address:self-test",
|
||||
"gen:iso3-to-alpha2": "node library/scripts/generate-iso3-to-alpha2.mjs",
|
||||
"internet:adm1": "node plugin-designs/cities-internet/scripts/build-adm1-internet.mjs",
|
||||
|
|
|
|||
Loading…
Reference in a new issue