39 lines
2.8 KiB
JavaScript
39 lines
2.8 KiB
JavaScript
import test from 'node:test';
|
|||
|
|
import assert from 'node:assert/strict';
|
||
|
|
import fs from 'node:fs';
|
||
|
|
import ts from 'typescript';
|
||
|
|
const source = fs.readFileSync(new URL('../src/components/device-control-model.ts', import.meta.url), 'utf8');
|
||
|
|
const compiled = ts.transpileModule(source, { compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2022 } });
|
||
|
|
const module = { exports: {} };
|
||
|
|
new Function('exports', compiled.outputText)(module.exports);
|
||
|
|
const { speakerVolume, volumeFeedback, powerPending, deviceStateLabel } = module.exports;
|
||
|
|
const twin = (changes = {}) => ({ desired_revision: 4, reported_revision: 4, desired_config: { volume: { speaker: 0 }, power: { mode: 'active' } }, reported_config: { volume: { speaker: 0 }, power: { mode: 'active' } }, ...changes });
|
||
|
|
|
||
|
|
test('zero volume is a valid confirmed setting; malformed hardware values stay unknown', () => {
|
||
|
|
assert.equal(speakerVolume({ volume: { speaker: 0 } }), 0);
|
||
|
|
for (const value of ['60', -1, 101, 2.5, NaN]) assert.equal(speakerVolume({ volume: { speaker: value } }), undefined);
|
||
|
|
assert.deepEqual(volumeFeedback(twin(), true), { state: 'applied', text: '已生效' });
|
||
|
|
});
|
||
|
|
test('saving a target is not an acknowledgment, even if the old reported value happens to match', () => {
|
||
|
|
assert.equal(volumeFeedback(twin({ reported_revision: 3 }), true).state, 'pending');
|
||
|
|
assert.equal(volumeFeedback(twin({ reported_config: { volume: { speaker: 20 } } }), true).state, 'pending');
|
||
|
|
assert.equal(volumeFeedback(twin({ reported_revision: 3 }), false).text, '已保存,等待设备连接');
|
||
|
|
assert.equal(volumeFeedback(twin(), false).text, '上次已生效');
|
||
|
|
});
|
||
|
|
test('missing reports and read-only state never imply readiness or successful application', () => {
|
||
|
|
assert.equal(volumeFeedback(undefined).state, 'loading');
|
||
|
|
assert.equal(volumeFeedback(twin({ desired_config: {}, reported_config: {} }), true).state, 'unknown');
|
||
|
|
assert.equal(deviceStateLabel(twin({ reported_config: {} }), true), '在线 · 状态待确认');
|
||
|
|
assert.equal(deviceStateLabel(twin(), undefined), '正在确认连接');
|
||
|
|
assert.equal(deviceStateLabel(twin(), false), '设备离线');
|
||
|
|
});
|
||
|
|
test('standby uses the reported mode, and a queued request remains pending until the revision is acknowledged', () => {
|
||
|
|
const waiting = twin({ desired_revision: 5, desired_config: { power: { mode: 'standby' } } });
|
||
|
|
assert.equal(powerPending(waiting), true);
|
||
|
|
assert.equal(deviceStateLabel(waiting, true), '在线 · 使用中');
|
||
|
|
const applied = twin({ desired_config: { power: { mode: 'standby' } }, reported_config: { power: { mode: 'standby' } } });
|
||
|
|
assert.equal(powerPending(applied), false);
|
||
|
|
assert.equal(deviceStateLabel(applied, true), '在线 · 已待机');
|
||
|
|
assert.equal(powerPending({ ...applied, reported_revision: 3 }), true);
|
||
|
|
});
|