import { readFileSync } from 'node:fs' import { dirname, join } from 'node:path' import { fileURLToPath } from 'node:url' import { describe, expect, it } from 'vitest' import { CODE_LIKE_ATTRIBUTE_WORDS } from '../code-pattern-grammar.js' // The code-like lexicon is drift-locked between its SSOT export // (lib/code-pattern-grammar.CODE_LIKE_ATTRIBUTE_WORDS) and the authoring doc // that teaches it (create-data-model levels/attributes.md, block // `code-like-lexicon:v1`) — same discipline as platform-capabilities:v1. const HERE = dirname(fileURLToPath(import.meta.url)) function attributesMdPath(): string { // Source tree: business-analyse/create-data-model ; deployed: ba-create-data-model. const source = join(HERE, '..', '..', 'business-analyse', 'create-data-model', 'levels', 'attributes.md') try { readFileSync(source) return source } catch { return join(HERE, '..', '..', 'ba-create-data-model', 'levels', 'attributes.md') } } describe('code-like-lexicon:v1 — attributes.md ⇔ lib drift lock', () => { it('the doc block lists exactly the exported lexicon words', () => { const md = readFileSync(attributesMdPath(), 'utf8') const block = /([\s\S]*?)/.exec(md)?.[1] expect(block, 'attributes.md lost the code-like-lexicon:v1 block').toBeTruthy() // The lexicon words are the backticked tokens AFTER the colon — the prose // before it backticks examples (`NumeroClient`, `Preference`, `ReferenceId`). const listPart = block!.split(':').at(-1)! const words = [...listPart.matchAll(/`([a-z]+)`/g)].map((m) => m[1]) expect(words).toEqual([...CODE_LIKE_ATTRIBUTE_WORDS]) }) })