mirror of
https://github.com/rstrouse/ESPSomfy-RTS.git
synced 2026-10-31 13:52:15 +01:00
- data-src/js: ProtoSchema (schema from the sync, short keys and names, defaults, cached by hash), ProtoModel (rooms, shades, groups, repeaters, header and status from the sync and the events) and ProtoClient (/ws, hello, sync with next, op() as a Promise of its reply, events, feeds, reconnect). Nothing uses them yet: 2b moves the UI onto them. - minify.py joins js/*.js and index.js into index.js, and the three CSS files into app.css, so a page load opens fewer connections. - test/js: node --test on the three modules, replaying the recorded fixtures; a CI job runs it and the firmware build waits for it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
56 lines
2.6 KiB
JavaScript
56 lines
2.6 KiB
JavaScript
// The web UI's ProtoSchema (data-src/js/schema.js) against the schema a
|
|
// device sent (test/fixtures/proto2).
|
|
const test = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const { ProtoSchema } = require('../../data-src/js/schema.js');
|
|
const { recordedSchema, schemaJson } = require('./helpers.js');
|
|
|
|
test('the schema is collected from every sync frame it spans', () => {
|
|
const s = recordedSchema();
|
|
assert.equal(Object.keys(s.types).length, Object.keys(schemaJson.types).length);
|
|
assert.equal(Object.keys(s.fields).length, Object.keys(schemaJson.fields).length);
|
|
assert.equal(s.typeNumbers.shadeCommand, 16);
|
|
assert.equal(s.typeNumbers.saveSettings, 50);
|
|
assert.equal(s.keys.shadeId, 's');
|
|
assert.equal(s.errorNumbers.busy, 5);
|
|
assert.equal(s.feedNumbers.frequencyScan, 2);
|
|
});
|
|
|
|
test('short keys become names, and 1/0 booleans, all the way down', () => {
|
|
const s = recordedSchema();
|
|
const shade = s.expand({ s: 3, n: 'Office', i: 1, fp: 0, lk: [{ a: 5, c: 9 }] });
|
|
assert.deepEqual(shade, { shadeId: 3, name: 'Office', paired: true, flipPosition: false,
|
|
linkedRemotes: [{ remoteAddress: 5, lastRollingCode: 9 }] });
|
|
// A whole number that happens to be 1 stays a number.
|
|
assert.deepEqual(s.expand({ p: 1 }), { position: 1 });
|
|
});
|
|
|
|
test('names become short keys for an op', () => {
|
|
const s = recordedSchema();
|
|
assert.deepEqual(s.pack({ shadeId: 3, command: 'Up', paired: true, sunny: false }), { s: 3, cm: 'Up', i: 1, sn: 0 });
|
|
assert.deepEqual(s.pack({ ids: [3, 1, 2] }), { is: [3, 1, 2] });
|
|
// Left out, not sent as undefined.
|
|
assert.deepEqual(s.pack({ shadeId: 3, target: undefined }), { s: 3 });
|
|
assert.throws(() => s.pack({ nonsense: 1 }), /no field nonsense/);
|
|
});
|
|
|
|
test('a field left out is its default', () => {
|
|
const s = recordedSchema();
|
|
assert.equal(s.defaultOf('myPos'), -1);
|
|
assert.equal(s.defaultOf('stepSize'), 100);
|
|
assert.equal(s.defaultOf('bitLength'), 56);
|
|
assert.equal(s.defaultOf('paired'), false);
|
|
assert.equal(s.defaultOf('name'), '');
|
|
assert.deepEqual(s.defaultOf('linkedShades'), []);
|
|
assert.deepEqual(s.fill({ shadeId: 2 }, ['shadeId', 'position', 'myPos']), { shadeId: 2, position: 0, myPos: -1 });
|
|
});
|
|
|
|
test('a cached schema comes back whole, with its hash', () => {
|
|
const s = recordedSchema();
|
|
const back = ProtoSchema.load(JSON.parse(JSON.stringify(s.save())));
|
|
assert.equal(back.hash, s.hash);
|
|
assert.deepEqual(back.fields, s.fields);
|
|
assert.deepEqual(back.types, s.types);
|
|
assert.equal(ProtoSchema.load(null), null);
|
|
assert.equal(ProtoSchema.load({ hash: 'x', rows: {} }), null);
|
|
});
|