71 lines
4.3 KiB
JavaScript
71 lines
4.3 KiB
JavaScript
import test from 'node:test';
|
||
import assert from 'node:assert/strict';
|
||
import {readFileSync} from 'node:fs';
|
||
import ts from 'typescript';
|
||
|
||
const source=readFileSync(new URL('../../../plugins/vesc/frontend/src/model.ts',import.meta.url),'utf8');
|
||
const code=ts.transpileModule(source,{compilerOptions:{module:ts.ModuleKind.ESNext}}).outputText;
|
||
const {vescLabel,testInput,speedInput,rotationResult,driveTestIds}=await import('data:text/javascript;base64,'+Buffer.from(code).toString('base64'));
|
||
const controller={online:true,prepared:true,verified:true,vesc_status:{identity:{uuid:'synthetic'},readable:true}};
|
||
|
||
test('speed mode requires board capability and reports measured rotation time',()=>{
|
||
assert.ok(speedInput('1200',undefined).error);
|
||
const bounds={min_erpm:300,max_erpm:3000,duration_basis:'measured_speed'};
|
||
assert.equal(speedInput('1200',bounds).error,null);
|
||
for(const value of ['', 'NaN','299','3001'])assert.ok(speedInput(value,bounds).error);
|
||
const text=rotationResult({outcome:'stopped',rotation_s:2.5,release_confirmed:true,limits_restored:true});
|
||
assert.match(text,/2,5 с/);
|
||
assert.match(text,/Проверка остановлена/);
|
||
assert.doesNotMatch(text,/время вращения набрано/);
|
||
});
|
||
|
||
test('USB discovery and model preparation never claim a verified VESC',()=>{
|
||
assert.equal(vescLabel({...controller,prepared:false},true).label,'Требуется подготовка');
|
||
assert.equal(vescLabel({...controller,vesc_status:{identity:null,readable:false}},true).tone,'warning');
|
||
});
|
||
test('fresh read capability is distinct from unsupported firmware and offline state',()=>{
|
||
assert.equal(vescLabel(controller,true).label,'Готов к чтению');
|
||
assert.equal(vescLabel(controller,false).label,'Нет связи');
|
||
assert.equal(vescLabel({...controller,online:false},true).label,'Нет связи');
|
||
assert.equal(vescLabel({...controller,vesc_status:{identity:{uuid:'synthetic'},readable:false}},true).label,'Прошивка не поддерживается');
|
||
});
|
||
|
||
test('test fields accept entered values only inside the board capability bounds',()=>{
|
||
const bounds={min_current_a:0.5,max_current_a:5,min_duration_s:0.5,max_duration_s:10};
|
||
assert.equal(testInput('3.7','7.2',bounds).valid,true);
|
||
assert.equal(testInput('5','10',bounds).valid,true);
|
||
for(const [amps,seconds] of [['','5'],['5',''],['60','10'],['5','11'],['NaN','1'],['Infinity','1']])assert.equal(testInput(amps,seconds,bounds).valid,false);
|
||
assert.equal(testInput('2','1.5',undefined).valid,false);
|
||
const overlong=testInput('5','15',bounds);
|
||
assert.equal(overlong.valid,false);
|
||
assert.equal(overlong.currentError,null);
|
||
assert.equal(overlong.durationError,'Длительность должна быть от 0,5 до 10 с.');
|
||
assert.equal(testInput('5','10',bounds).durationError,null);
|
||
});
|
||
|
||
// Capabilities come from the installed board: a newer Core must retain old bounds.
|
||
test('extended board accepts 30 A / 30 s without changing older board bounds',()=>{
|
||
const old={min_current_a:0.5,max_current_a:5,min_duration_s:0.5,max_duration_s:10};
|
||
const expanded={...old,max_current_a:30,max_duration_s:30,continuous_current:true};
|
||
assert.equal(testInput('30','30',expanded).valid,true);
|
||
assert.equal(testInput('30.1','30',expanded).valid,false);
|
||
assert.equal(testInput('30','30.1',expanded).valid,false);
|
||
assert.equal(testInput('30','30',old).valid,false);
|
||
});
|
||
|
||
|
||
test('group spin requires a complete unique profile containing the selected controller',()=>{
|
||
const profile={layout:'1x1',revision:3,bindings:{'left.1':{device_id:'left',uuid:'a'},'right.1':{device_id:'right',uuid:'b'}}};
|
||
assert.deepEqual(driveTestIds(profile,'left'),['left','right']);
|
||
assert.deepEqual(driveTestIds(profile,'unassigned'),[]);
|
||
assert.deepEqual(driveTestIds({...profile,bindings:{'left.1':profile.bindings['left.1']}},'left'),[]);
|
||
assert.deepEqual(driveTestIds({...profile,bindings:{...profile.bindings,'right.1':profile.bindings['left.1']}},'left'),[]);
|
||
assert.deepEqual(driveTestIds(undefined,'left'),[]);
|
||
});
|
||
|
||
test('four-wheel profile preserves front and rear membership for common testing',()=>{
|
||
const ids=['lf','lr','rf','rr'];
|
||
const bindings=Object.fromEntries(['left.1','left.2','right.1','right.2'].map((slot,i)=>[slot,{device_id:ids[i],uuid:ids[i]}]));
|
||
assert.deepEqual(driveTestIds({layout:'2x2',revision:4,bindings},'rf'),ids);
|
||
});
|