profiler: list matching record numbers when only the record count differs
The 'matching records: N-M' note was suppressed when every compared record matched but the record count differed (e.g. 30 expected vs 10 read): the renderer only looked for failed per-record checks, so the report showed just the count lines. profilerRunRule now sets res.recordsMismatch whenever the count or any record differs, and the renderer uses it (with the old per-record check as fallback), so the matching-record ranges are listed in that case too. Tests cover the count-only mismatch and the per-record case. SW cache v65 -> v66.
This commit is contained in:
+4
-2
@@ -7640,6 +7640,7 @@ async function profilerRunRule(r) {
|
|||||||
const exp = r.content.records || [];
|
const exp = r.content.records || [];
|
||||||
const act = rd.records || [];
|
const act = rd.records || [];
|
||||||
const n = Math.min(exp.length, act.length);
|
const n = Math.min(exp.length, act.length);
|
||||||
|
let recMismatch = exp.length !== act.length;
|
||||||
if (exp.length !== act.length) {
|
if (exp.length !== act.length) {
|
||||||
res.status = 'fail';
|
res.status = 'fail';
|
||||||
const numRec = res.checks.find(c => c.label === 'numRecords');
|
const numRec = res.checks.find(c => c.label === 'numRecords');
|
||||||
@@ -7651,10 +7652,11 @@ async function profilerRunRule(r) {
|
|||||||
for (let j = 0; j < n; j++) {
|
for (let j = 0; j < n; j++) {
|
||||||
const dataOk = sizeMismatch ? profilerMatchMin(r.content.mode, exp[j].data, act[j].data) : profilerMatch(r.content.mode, exp[j].data, act[j].data);
|
const dataOk = sizeMismatch ? profilerMatchMin(r.content.mode, exp[j].data, act[j].data) : profilerMatch(r.content.mode, exp[j].data, act[j].data);
|
||||||
const ok = exp[j].num === act[j].num && dataOk;
|
const ok = exp[j].num === act[j].num && dataOk;
|
||||||
if (!ok) res.status = 'fail'; else matched.push(exp[j].num);
|
if (!ok) { res.status = 'fail'; recMismatch = true; } else matched.push(exp[j].num);
|
||||||
res.checks.push({ label: 'content.rec' + exp[j].num, expected: exp[j].data, actual: act[j].data, ok: ok });
|
res.checks.push({ label: 'content.rec' + exp[j].num, expected: exp[j].data, actual: act[j].data, ok: ok });
|
||||||
}
|
}
|
||||||
if (matched.length) res.recordsMatched = matched;
|
if (matched.length) res.recordsMatched = matched;
|
||||||
|
if (recMismatch) res.recordsMismatch = true;
|
||||||
} else {
|
} else {
|
||||||
const ok = sizeMismatch ? profilerMatchMin(r.content.mode, r.content.expected, rd.data) : profilerMatch(r.content.mode, r.content.expected, rd.data);
|
const ok = sizeMismatch ? profilerMatchMin(r.content.mode, r.content.expected, rd.data) : profilerMatch(r.content.mode, r.content.expected, rd.data);
|
||||||
if (!ok) res.status = 'fail';
|
if (!ok) res.status = 'fail';
|
||||||
@@ -7777,7 +7779,7 @@ function profilerRenderReport(results) {
|
|||||||
html += '<div class="text-xs text-red-600 mt-1">' + esc(c.label) + ': ' + esc(t('expected')) + ' <b>' + esc(String(c.expected)) + '</b>, ' + esc(t('actual')) + ' <b>' + esc(String(c.actual)) + '</b></div>';
|
html += '<div class="text-xs text-red-600 mt-1">' + esc(c.label) + ': ' + esc(t('expected')) + ' <b>' + esc(String(c.expected)) + '</b>, ' + esc(t('actual')) + ' <b>' + esc(String(c.actual)) + '</b></div>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const recFailed = (r.checks || []).some(c => /^content\.rec\d+$/.test(c.label) && !c.ok);
|
const recFailed = r.recordsMismatch || (r.checks || []).some(c => /^content\.rec\d+$/.test(c.label) && !c.ok);
|
||||||
if (recFailed && r.recordsMatched && r.recordsMatched.length) {
|
if (recFailed && r.recordsMatched && r.recordsMatched.length) {
|
||||||
html += '<div class="text-xs text-emerald-600 mt-1">' + esc(t('matching records')) + ': ' + esc(profilerNumRanges(r.recordsMatched)) + '</div>';
|
html += '<div class="text-xs text-emerald-600 mt-1">' + esc(t('matching records')) + ': ' + esc(profilerNumRanges(r.recordsMatched)) + '</div>';
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
const CACHE = 'otaman-v65';
|
const CACHE = 'otaman-v66';
|
||||||
const URLS = [
|
const URLS = [
|
||||||
'index.html',
|
'index.html',
|
||||||
'help.html',
|
'help.html',
|
||||||
|
|||||||
@@ -471,6 +471,7 @@ test('profilerRunRule records which records matched on a record mismatch', async
|
|||||||
content: { mode: 'exact', kind: 'record', records: [{ num: 1, data: 'AA' }, { num: 2, data: 'BB' }, { num: 3, data: 'CC' }] },
|
content: { mode: 'exact', kind: 'record', records: [{ num: 1, data: 'AA' }, { num: 2, data: 'BB' }, { num: 3, data: 'CC' }] },
|
||||||
});
|
});
|
||||||
assert.strictEqual(res.status, 'fail');
|
assert.strictEqual(res.status, 'fail');
|
||||||
|
assert.strictEqual(res.recordsMismatch, true);
|
||||||
assert.deepStrictEqual(res.recordsMatched, [1, 3]);
|
assert.deepStrictEqual(res.recordsMatched, [1, 3]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -487,6 +488,13 @@ test('record count mismatch is reported once when numRecords is checked', async
|
|||||||
assert.strictEqual(res.status, 'fail');
|
assert.strictEqual(res.status, 'fail');
|
||||||
assert.ok(res.checks.some(c => c.label === 'numRecords' && c.ok === false));
|
assert.ok(res.checks.some(c => c.label === 'numRecords' && c.ok === false));
|
||||||
assert.ok(!res.checks.some(c => c.label === 'content.records'));
|
assert.ok(!res.checks.some(c => c.label === 'content.records'));
|
||||||
|
assert.strictEqual(res.recordsMismatch, true);
|
||||||
|
assert.deepStrictEqual(res.recordsMatched, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||||
|
global.t = s => s;
|
||||||
|
global.pysimCustomFiles = [];
|
||||||
|
const report = profilerRenderReport([res]);
|
||||||
|
assert.ok(report.includes('matching records: 1-10'), report);
|
||||||
|
delete global.t;
|
||||||
});
|
});
|
||||||
|
|
||||||
test('record count mismatch keeps content.records when numRecords is not checked (type mode)', async () => {
|
test('record count mismatch keeps content.records when numRecords is not checked (type mode)', async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user