Build and publish Eldorado documentation / build (pull_request) Successful in 39s
49 lines
3.4 KiB
JavaScript
49 lines
3.4 KiB
JavaScript
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'));
|
||
});
|