Files
documentation/scripts/skills-stories.test.mjs
jarvis-at-skic ad7312b65a
Build and publish Eldorado documentation / build (pull_request) Successful in 39s
feat: [verified] widen Skills Adoption diagram stories
2026-10-06 19:37:49 +00:00

49 lines
3.4 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import {test} from 'node:test';
import assert from 'node:assert/strict';
import {readFileSync, mkdtempSync, rmSync} from 'node:fs';
import {tmpdir} from 'node:os';
import {join} from 'node:path';
import {execFileSync} from 'node:child_process';
import {skillsViewer,isSkillsStory} from './skills-viewer.mjs';
const read = p => readFileSync(p,'utf8');
const topics = ['governance','quality','adoption','measurement','maintenance'];
test('all six Skills Adoption pages account for exactly five diagrams and ten sources',()=>{
let count=0;
for(const route of ['stage-01-skills-adoption',...topics.map(t=>t==='measurement'?t:`skills-${t}`)]){
const diagrams=[...read(`docs/strategy/${route}.mdx`).matchAll(/<ArchifyDiagram name="([^"]+)"/g)];
assert.equal(diagrams.length,route.startsWith('stage-')?0:1);
for(const [,name] of diagrams){assert(isSkillsStory(name));for(const suffix of ['','-mobile'])JSON.parse(read(`diagrams/${name}${suffix}.architecture.json`));count++;}
}
assert.equal(count,5);assert(!isSkillsStory('strategy-target'));assert(!isSkillsStory('strategy-roadmap'));
});
for(const topic of topics) test(`${topic}: rich native source, wide desktop, mobile parity and checked adapter`,()=>{
const name=`strategy-${topic}`;const desktop=JSON.parse(read(`diagrams/${name}.architecture.json`));
const mobile=JSON.parse(read(`diagrams/${name}-mobile.architecture.json`));
const semantic = d=>d.components.map(({pos,size,...n})=>n);
assert.deepEqual(semantic(desktop),semantic(mobile));
assert.equal(new Set(desktop.components.map(n=>n.pos[0])).size,3);
assert.equal(new Set(mobile.components.map(n=>n.pos[0])).size,1);
for(const n of desktop.components){assert(n.tag);assert(n.sublabel.split('\n').length>=4);}
const dir=mkdtempSync(join(tmpdir(),'skills-viewer-'));
try{
const path=join(dir,'native.html');
execFileSync(process.execPath,['vendor/archify/renderers/architecture/render-architecture.mjs',`diagrams/${name}.architecture.json`,path]);
const native=read(path);const html=skillsViewer(native,desktop);
assert.equal((html.match(/<g\b[^>]*data-node-id=/g)||[]).length,6);
assert.equal((html.match(/<text data-node-label=/g)||[]).length,0); // Adapter uses explicit position before semantic attributes.
assert.equal((html.match(/data-node-label=""/g)||[]).length,6);
assert(html.includes('eldorado-skills-typography'));
assert.throws(()=>skillsViewer(native.replace('data-node-id="'+desktop.components[0].id+'"','data-node-id="missing"'),desktop));
const bad=structuredClone(desktop);bad.components[0].sublabel='not a full story';assert.throws(()=>skillsViewer(native,bad));
}finally{rmSync(dir,{recursive:true,force:true});}
});
test('domain contracts retain human authority, honest measures and Delivery-first rollout',()=>{
const text=t=>read(`diagrams/strategy-${t}.architecture.json`);
assert(text('governance').includes('Author is not sole approver'));
assert(text('quality').includes('Critical effect blocks'));
assert(text('adoption').includes('Delivery first')&&text('adoption').includes('Later order undecided'));
assert(text('adoption').includes('No quotas or rankings'));
for(const marker of ['Tracker:','Invoices + review minutes','linked defect records','Anonymous 1–5 survey','Missing buckets = partial','Zero denominator = N/A'])assert(text('measurement').includes(marker),marker);
assert(text('maintenance').includes('No automatic reinstatement'));
});