Measure refresh latency independently and retain intended result selection
This commit is contained in:
1 parent
373ed1ed49
commit
8b993b23d7
7 files changed
+188
-11
No files matched your search
@@ -100,3 +100,64 @@ test('an in-flight attempt keeps its captured submission when a refresh queues',
|
||||
assert.equal(attempts[1].retry_wait_ms, 0);
|
||||
assert.notEqual(attempts[0].submission, attempts[1].submission);
|
||||
});
|
||||
|
||||
test('filesystem refresh excludes long idle time and retains original input timings separately', () => {
|
||||
const original = new SearchMeasurement(100, 160, true, { device: 'cpu' });
|
||||
original.submitted('lexical', 160);
|
||||
finish(original, 'lexical', 165, 177, native, false);
|
||||
original.displayed('lexical', 177, 180, 2);
|
||||
original.submitted('hybrid', 510);
|
||||
finish(original, 'hybrid', 510, 522, native, false);
|
||||
original.displayed('hybrid', 522, 524, 3);
|
||||
const before = original.export();
|
||||
const refreshed = original.freshForRefresh(83500);
|
||||
refreshed.submitted('lexical', 83500);
|
||||
finish(refreshed, 'lexical', 83502, 83514, native, false);
|
||||
refreshed.displayed('lexical', 83514, 83515, 3);
|
||||
const report = refreshed.export();
|
||||
assert.equal(report.trigger, 'filesystem_refresh');
|
||||
assert.equal(report.first_results_ms, 15);
|
||||
assert.equal(report.latest_displayed_ms, 15);
|
||||
assert.equal(report.debounce_ms, 0);
|
||||
assert.equal(report.hybrid_final_results_ms, null);
|
||||
assert.deepEqual(report.original_input, {
|
||||
debounce_ms: 60, first_results_ms: 80, latest_displayed_ms: 424,
|
||||
hybrid_final_results_ms: 424,
|
||||
});
|
||||
assert.equal(report.attempts.length, 1);
|
||||
assert.equal(report.attempts[0].attempt, 1);
|
||||
assert.equal(report.attempts[0].queued_ms, 2);
|
||||
assert.deepEqual(original.export(), before);
|
||||
});
|
||||
|
||||
test('repeated refreshes retain a bounded immutable numeric origin without replaying failures or private spans', () => {
|
||||
const original = new SearchMeasurement(0, 60, false);
|
||||
original.submitted('lexical', 60);
|
||||
finish(original, 'lexical', 60, 70, {
|
||||
...native, trace: [{ name: 'private-path-and-snippet', start_ms: 0, duration_ms: 1, parent: null, counters: {} }],
|
||||
}, true);
|
||||
original.displayed('lexical', 70, 72, 1);
|
||||
let refreshed = original.freshForRefresh(10000);
|
||||
const origin = refreshed.export().original_input;
|
||||
original.displayed('hybrid', 10001, 10002, 5);
|
||||
for (let i = 0; i < 100; i++) {
|
||||
const now = 20000 + i * 10000;
|
||||
refreshed = refreshed.freshForRefresh(now);
|
||||
assert.equal(refreshed.export().attempts.length, 0);
|
||||
assert.equal(refreshed.export().displays.length, 0);
|
||||
refreshed.submitted('lexical', now);
|
||||
finish(refreshed, 'lexical', now + 2, now + 14, native, false);
|
||||
refreshed.displayed('lexical', now + 14, now + 15, 2);
|
||||
const report = refreshed.export();
|
||||
assert.equal(report.latest_displayed_ms, 15);
|
||||
assert.equal(report.attempts[0].retry_wait_ms, 0);
|
||||
assert.equal(report.attempts[0].attempt, 1);
|
||||
assert.deepEqual(report.original_input, origin);
|
||||
report.original_input.first_results_ms = 999;
|
||||
assert.deepEqual(refreshed.export().original_input, origin);
|
||||
assert.doesNotMatch(JSON.stringify(report), /private-path-and-snippet|ended_at/);
|
||||
assert.ok(JSON.stringify(report).length < 1500);
|
||||
}
|
||||
assert.equal(origin.first_results_ms, 72);
|
||||
assert.equal(origin.hybrid_final_results_ms, null);
|
||||
});
|
||||
@@ -0,0 +1,45 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { ResultSelection } from '../src/selection-state.ts';
|
||||
|
||||
test('restores intended result after temporary absence across empty and fallback responses', () => {
|
||||
const selection = new ResultSelection();
|
||||
selection.begin('supplier/all');
|
||||
assert.equal(selection.resolve(['supplier', 'retry']), 0);
|
||||
assert.equal(selection.resolve(['retry']), 0);
|
||||
assert.equal(selection.resolve([]), -1);
|
||||
assert.equal(selection.resolve(['retry', 'supplier']), 1);
|
||||
});
|
||||
|
||||
test('explicit user navigation supersedes the hidden result even when choosing the fallback', () => {
|
||||
const selection = new ResultSelection();
|
||||
selection.begin('supplier/all');
|
||||
selection.resolve(['supplier', 'retry']);
|
||||
selection.resolve(['retry']);
|
||||
selection.choose('retry');
|
||||
assert.equal(selection.resolve(['supplier', 'retry']), 1);
|
||||
});
|
||||
|
||||
test('changed query or filters reset intent, while same-scope retries retain it', () => {
|
||||
const selection = new ResultSelection();
|
||||
selection.begin('supplier/all');
|
||||
selection.resolve(['supplier', 'retry']);
|
||||
selection.choose('retry');
|
||||
selection.begin('supplier/all');
|
||||
assert.equal(selection.resolve(['supplier', 'retry']), 1);
|
||||
selection.begin('supplier/code');
|
||||
assert.equal(selection.resolve(['code', 'retry']), 0);
|
||||
selection.begin('garden/code');
|
||||
assert.equal(selection.resolve(['garden', 'code']), 0);
|
||||
selection.begin('');
|
||||
selection.begin('garden/code');
|
||||
assert.equal(selection.resolve(['code', 'garden']), 0);
|
||||
});
|
||||
|
||||
test('initially empty search establishes its first choice only when results arrive', () => {
|
||||
const selection = new ResultSelection();
|
||||
selection.begin('new/all');
|
||||
assert.equal(selection.resolve([]), -1);
|
||||
assert.equal(selection.resolve(['new', 'other']), 0);
|
||||
assert.equal(selection.resolve(['other', 'new']), 1);
|
||||
});
|
||||
Reference in new issue
Block a user