diff --git a/frontend/index.html b/frontend/index.html index c10388a..b364346 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -7640,6 +7640,7 @@ async function profilerRunRule(r) { const exp = r.content.records || []; const act = rd.records || []; const n = Math.min(exp.length, act.length); + let recMismatch = exp.length !== act.length; if (exp.length !== act.length) { res.status = 'fail'; const numRec = res.checks.find(c => c.label === 'numRecords'); @@ -7651,10 +7652,11 @@ async function profilerRunRule(r) { 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 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 }); } if (matched.length) res.recordsMatched = matched; + if (recMismatch) res.recordsMismatch = true; } else { 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'; @@ -7777,7 +7779,7 @@ function profilerRenderReport(results) { html += '
' + esc(c.label) + ': ' + esc(t('expected')) + ' ' + esc(String(c.expected)) + ', ' + esc(t('actual')) + ' ' + esc(String(c.actual)) + '
'; } } - 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) { html += '
' + esc(t('matching records')) + ': ' + esc(profilerNumRanges(r.recordsMatched)) + '
'; } diff --git a/frontend/sw.js b/frontend/sw.js index 7c2fe36..bf57a60 100644 --- a/frontend/sw.js +++ b/frontend/sw.js @@ -1,4 +1,4 @@ -const CACHE = 'otaman-v65'; +const CACHE = 'otaman-v66'; const URLS = [ 'index.html', 'help.html', diff --git a/frontend/tests/profiler.test.js b/frontend/tests/profiler.test.js index 4442bd1..42a5384 100644 --- a/frontend/tests/profiler.test.js +++ b/frontend/tests/profiler.test.js @@ -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' }] }, }); assert.strictEqual(res.status, 'fail'); + assert.strictEqual(res.recordsMismatch, true); 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.ok(res.checks.some(c => c.label === 'numRecords' && c.ok === false)); 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 () => {