49 lines
3.0 KiB
JavaScript
49 lines
3.0 KiB
JavaScript
const {test}=require('node:test');
|
|
const assert=require('node:assert/strict');
|
|
const {readFileSync,readdirSync}=require('node:fs');
|
|
const {join}=require('node:path');
|
|
const vm=require('node:vm');
|
|
const {transport}=require('./download-actions');
|
|
test('transport symbols cover all actions and layouts with monochrome SVG',()=>{
|
|
for(const kind of ['play','pause','previous','next','back10','forward10','back15','forward']){
|
|
assert.match(transport.svg(kind),new RegExp(`href="#transport-${kind}"`));
|
|
assert.match(transport.svg(kind),/stroke="currentColor"/);
|
|
assert.equal((transport.svg(kind).match(/<use /g)||[]).length,4,'layout selection lives on visible use elements');
|
|
for(const layout of ['classic','f7-swipe','glass-stage','bento-hub'])assert.ok(transport.variants[layout][kind]);
|
|
}
|
|
assert.throws(()=>transport.svg('unknown'),/Unknown transport/);
|
|
});
|
|
test('playback UI swaps shared symbols and accessible names without changing handlers',()=>{
|
|
const buttons=Object.fromEntries(['playBtn','stgPlay','miniPlayBtn','servicePlayBtn'].map(id=>[id,{onclick:()=>id,setAttribute(k,v){this[k]=v;}}]));
|
|
const handlers=Object.values(buttons).map(b=>b.onclick);let changes=0;
|
|
const Player={master:{paused:true}},classes=[];
|
|
const app=readFileSync(join(__dirname,'app.js'),'utf8');
|
|
const body=app.slice(app.indexOf('function updatePlayBtn() {'),app.indexOf('// "⚠ Broken"'));
|
|
const sandbox={Player,TransportIcons:transport,Remote:{changed(){changes++;}},$:id=>buttons[id],document:{querySelector:()=>({classList:{toggle:(...args)=>classes.push(args)}})}};
|
|
vm.runInNewContext(body,sandbox);
|
|
for(const paused of [true,false,true]){
|
|
Player.master.paused=paused;sandbox.updatePlayBtn();
|
|
for(const b of Object.values(buttons)){assert.match(b.innerHTML,new RegExp(`#transport-${paused?'play':'pause'}`));assert.equal(b['aria-label'],paused?'Play':'Pause');}
|
|
}
|
|
assert.equal(changes,3);assert.deepEqual(Object.values(buttons).map(b=>b.onclick),handlers);
|
|
assert.deepEqual(classes,[['is-paused',true],['is-paused',false],['is-paused',true]]);
|
|
});
|
|
test('runtime sources never render legacy transport glyphs',()=>{
|
|
const failures=[];
|
|
for(const file of readdirSync(__dirname).filter(f=>/\.(js|html|css)$/.test(f)&&!f.endsWith('.test.js'))){
|
|
readFileSync(join(__dirname,file),'utf8').split('\n').forEach((line,i)=>{
|
|
// Legacy input decoder accepts old labels; its output uses shared symbols.
|
|
if(file==='glass-controls.js'&&line.startsWith(' const glyphs = '))return;
|
|
if(/[▶⏸⏮⏭⏪⏩⏯◀❚]/u.test(line))failures.push(`${file}:${i+1}`);
|
|
});
|
|
}
|
|
assert.deepEqual(failures,[]);
|
|
});
|
|
|
|
test('state changes preserve named SVG nodes used by editor controls',()=>{
|
|
let icon={id:'playIcon'};
|
|
const button={querySelector(){return icon;},set innerHTML(value){this.markup=value;icon={id:''};},setAttribute(name,value){this[name]=value;}};
|
|
transport.set(button,'pause');
|
|
assert.equal(icon.id,'playIcon');assert.equal(button['aria-label'],'Pause');assert.match(button.markup,/#transport-pause-f7-swipe/);
|
|
});
|