61ab7bc304
- Show Size only for transparent/ber_tlv; Record length/count only for linear_fixed/cyclic; hide all size/record fields for df (unknown shows all) - Hide the Contents section entirely for df (existence-only check) - Changing file type clears now-inapplicable fields and resets content (keeps mode) when its kind switches between record and transparent - profilerSetContent defaults content kind from the selected file type Add profilerFileFields + profilerContentKindForFileType helpers + tests. SW cache v45.
102 lines
4.6 KiB
JavaScript
102 lines
4.6 KiB
JavaScript
const { test } = require('node:test');
|
|
const assert = require('node:assert');
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
|
|
const html = fs.readFileSync(path.join(__dirname, '..', 'index.html'), 'utf8');
|
|
|
|
function extractFunc(src, name) {
|
|
const re = new RegExp('function\\s+' + name + '\\s*\\([^)]*\\)\\s*\\{');
|
|
const m = re.exec(src);
|
|
if (!m) throw new Error('function ' + name + ' not found');
|
|
let i = m.index + m[0].length - 1;
|
|
let depth = 0;
|
|
for (; i < src.length; i++) {
|
|
if (src[i] === '{') depth++;
|
|
else if (src[i] === '}') {
|
|
depth--;
|
|
if (depth === 0) break;
|
|
}
|
|
}
|
|
return src.slice(m.index, i + 1);
|
|
}
|
|
|
|
const FNS = ['profilerNormHex', 'profilerMatch', 'profilerMatchMin', 'profilerMaskPrefix4', 'profilerFileFields', 'profilerContentKindForFileType', 'profilerValidateProfile'];
|
|
let code = '';
|
|
for (const f of FNS) code += extractFunc(html, f) + '\n';
|
|
eval(code);
|
|
|
|
test('profilerNormHex uppercases and strips non-hex', () => {
|
|
assert.strictEqual(profilerNormHex('aabbcc'), 'AABBCC');
|
|
assert.strictEqual(profilerNormHex(' aa bb cc '), 'AABBCC');
|
|
assert.strictEqual(profilerNormHex('08?91?'), '08?91?');
|
|
assert.strictEqual(profilerNormHex(''), '');
|
|
});
|
|
|
|
test('exact match requires full equality', () => {
|
|
assert.ok(profilerMatch('exact', 'AABBCC', 'aabbcc'));
|
|
assert.ok(!profilerMatch('exact', 'AABB', 'AABBCC'));
|
|
assert.ok(!profilerMatch('exact', 'AABBCC', 'AABB'));
|
|
assert.ok(!profilerMatch('exact', '', 'AABB'));
|
|
});
|
|
|
|
test('mask with ? wildcard matches per nibble', () => {
|
|
assert.ok(profilerMatch('mask', '08?91?', '081910'));
|
|
assert.ok(profilerMatch('mask', '08?91?', '08A91B'));
|
|
assert.ok(!profilerMatch('mask', '08?91?', '091910'));
|
|
assert.ok(!profilerMatch('mask', '08?91?', '0891')); // length mismatch
|
|
});
|
|
|
|
test('mask without ? is a prefix match', () => {
|
|
assert.ok(profilerMatch('mask', '0891', '08911012345678'));
|
|
assert.ok(profilerMatch('mask', '0891', '0891'));
|
|
assert.ok(!profilerMatch('mask', '0891', '081910'));
|
|
assert.ok(!profilerMatch('mask', '', '0891'));
|
|
});
|
|
|
|
test('profilerMatchMin compares the shorter overlapping portion', () => {
|
|
// shorter expected vs longer actual -> compare prefix
|
|
assert.ok(profilerMatchMin('exact', '1122FFFF', '1122FFFFFF'));
|
|
assert.ok(!profilerMatchMin('exact', '1122FFFF', '1122FFAA'));
|
|
// shorter actual vs longer expected -> compare prefix
|
|
assert.ok(profilerMatchMin('exact', '1122FFFFFF', '1122FFFF'));
|
|
// equal lengths behave like profilerMatch
|
|
assert.ok(profilerMatchMin('exact', '1122FFFF', '1122FFFF'));
|
|
assert.ok(!profilerMatchMin('exact', '1122FFFF', '1122FFEE'));
|
|
// mask with ? over a shorter actual
|
|
assert.ok(profilerMatchMin('mask', '08?91?AA', '081910'));
|
|
assert.ok(!profilerMatchMin('mask', '08?91?AA', '091110'));
|
|
});
|
|
|
|
test('profilerMaskPrefix4 keeps first 4 bytes and masks the rest', () => {
|
|
assert.strictEqual(profilerMaskPrefix4('082905911234567890'), '08290591??????????');
|
|
assert.strictEqual(profilerMaskPrefix4('08290591'), '08290591');
|
|
assert.strictEqual(profilerMaskPrefix4('1234'), '1234');
|
|
});
|
|
|
|
test('profilerFileFields maps file type to applicable fields', () => {
|
|
assert.deepStrictEqual(profilerFileFields('transparent'), { size: true, records: false });
|
|
assert.deepStrictEqual(profilerFileFields('ber_tlv'), { size: true, records: false });
|
|
assert.deepStrictEqual(profilerFileFields('linear_fixed'), { size: false, records: true });
|
|
assert.deepStrictEqual(profilerFileFields('cyclic'), { size: false, records: true });
|
|
assert.deepStrictEqual(profilerFileFields('df'), { size: false, records: false });
|
|
assert.deepStrictEqual(profilerFileFields(null), { size: true, records: true });
|
|
assert.deepStrictEqual(profilerFileFields(''), { size: true, records: true });
|
|
});
|
|
|
|
test('profilerContentKindForFileType', () => {
|
|
assert.strictEqual(profilerContentKindForFileType('linear_fixed'), 'record');
|
|
assert.strictEqual(profilerContentKindForFileType('cyclic'), 'record');
|
|
assert.strictEqual(profilerContentKindForFileType('transparent'), 'transparent');
|
|
assert.strictEqual(profilerContentKindForFileType('ber_tlv'), 'transparent');
|
|
assert.strictEqual(profilerContentKindForFileType('df'), 'transparent');
|
|
});
|
|
|
|
test('profile validation', () => {
|
|
assert.strictEqual(profilerValidateProfile(null), 'Not an object');
|
|
assert.strictEqual(profilerValidateProfile({ name: 'x' }), 'Missing rules array');
|
|
assert.strictEqual(profilerValidateProfile({ name: 'x', rules: [{ type: 'ota' }] }), 'Unsupported rule type: ota');
|
|
assert.strictEqual(profilerValidateProfile({ name: 'x', rules: [{ type: 'file' }] }), 'Rule missing path');
|
|
assert.strictEqual(profilerValidateProfile({ name: 'x', rules: [{ type: 'file', path: 'MF/7F10/6F3A' }] }), null);
|
|
});
|