Skip to content

Commit d97aba9

Browse files
committed
fix(scroll): observe the movement a directional scroll can claim
1 parent a266c39 commit d97aba9

5 files changed

Lines changed: 1204 additions & 13 deletions

File tree

‎src/daemon/__tests__/interaction-outcome-policy.test.ts‎

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
buildInteractionSurfaceSignature,
66
classifyBaselineSurfaceEvidence,
77
classifyInteractionSurfaceChange,
8+
discriminatingSurfaceChangedWithinRect,
89
markPendingInteractionOutcome,
910
stripInternalInteractionFlags,
1011
} from '../interaction-outcome-policy.ts';
@@ -411,3 +412,58 @@ function makeSnapshotWithExtraText(label: string, y = 100): SnapshotState {
411412
],
412413
};
413414
}
415+
416+
// ---------------------------------------------------------------------------
417+
// discriminatingSurfaceChangedWithinRect (#2714 review): a whole-surface
418+
// difference that lives outside the region a command acted on is not that
419+
// command's doing. Measured on the Android tester, the status bar changed on
420+
// its own over a list that never moved. The strict key-matched view stays
421+
// owned here; this only narrows the region it is asked about.
422+
// ---------------------------------------------------------------------------
423+
424+
const LIST_RECT = { x: 0, y: 150, width: 390, height: 600 };
425+
426+
function rowAt(index: number, y: number) {
427+
return {
428+
type: 'StaticText',
429+
identifier: `row-${index}`,
430+
label: `Row ${index}`,
431+
rect: { x: 12, y, width: 300, height: 24 },
432+
} as SnapshotState['nodes'][number];
433+
}
434+
435+
function surfaceWithClock(clock: string, secondRowY: number) {
436+
return [
437+
{
438+
type: 'Image',
439+
identifier: 'status-clock',
440+
label: clock,
441+
rect: { x: 12, y: 12, width: 40, height: 18 },
442+
} as SnapshotState['nodes'][number],
443+
rowAt(1, 200),
444+
rowAt(2, secondRowY),
445+
];
446+
}
447+
448+
test('discriminatingSurfaceChangedWithinRect reads a movement inside the region', () => {
449+
const before = buildInteractionSurfaceSignature(surfaceWithClock('2:40', 300));
450+
const after = buildInteractionSurfaceSignature(surfaceWithClock('2:40', 420));
451+
452+
assert.equal(discriminatingSurfaceChangedWithinRect(before, after, LIST_RECT), true);
453+
});
454+
455+
test('discriminatingSurfaceChangedWithinRect does not read a movement outside the region', () => {
456+
const before = buildInteractionSurfaceSignature(surfaceWithClock('2:40', 300));
457+
const after = buildInteractionSurfaceSignature(surfaceWithClock('2:41', 300));
458+
459+
// The whole surface did change — that is the trap this reader exists to refuse.
460+
assert.equal(classifyBaselineSurfaceEvidence(before, after), 'changed');
461+
assert.equal(discriminatingSurfaceChangedWithinRect(before, after, LIST_RECT), false);
462+
});
463+
464+
test('discriminatingSurfaceChangedWithinRect counts content appearing inside the region', () => {
465+
const before = buildInteractionSurfaceSignature(surfaceWithClock('2:40', 300));
466+
const after = buildInteractionSurfaceSignature([...surfaceWithClock('2:40', 300), rowAt(3, 640)]);
467+
468+
assert.equal(discriminatingSurfaceChangedWithinRect(before, after, LIST_RECT), true);
469+
});

0 commit comments

Comments
 (0)