import { describe, expect, it } from "vite-plus/test"; import { resolveWorkGroupScrollAnchor } from "./scrollAnchor.js"; describe("tool-group scroll anchors", () => { const data = Array.from({ length: 18 }, (_, index) => ({ id: `call-${index}` })); const state = { data, positionAtIndex: (index: number) => index * 33 }; it("returns to the top after a fast flick even when the cached start is five rows behind", () => { const snapshot = { ...state, scroll: 0, start: 5 }; expect(resolveWorkGroupScrollAnchor(snapshot)).toEqual({ rowId: "call-0", offsetWithinRow: 0, scrollOffset: 0, }); }); it.each([ { scroll: 302, start: 0, rowId: "call-9", offsetWithinRow: 5 }, { scroll: 40, start: 12, rowId: "call-1", offsetWithinRow: 7 }, { scroll: 165, start: 4, rowId: "call-5", offsetWithinRow: 0 }, ])("uses the measured position at $scroll rather than cached row $start", (example) => { expect(resolveWorkGroupScrollAnchor({ ...state, ...example })).toEqual({ rowId: example.rowId, offsetWithinRow: example.offsetWithinRow, scrollOffset: example.scroll, }); }); it("preserves an offset within expanded output", () => { const positions = [0, 33, 600]; expect( resolveWorkGroupScrollAnchor({ data: [{ id: "first" }, { id: "output" }, { id: "last" }], scroll: 153, positionAtIndex: (index) => positions[index], }), ).toEqual({ rowId: "output", offsetWithinRow: 120, scrollOffset: 153 }); }); it("does not preserve overscroll before the first row", () => { expect(resolveWorkGroupScrollAnchor({ ...state, scroll: -20 })).toEqual({ rowId: "call-0", offsetWithinRow: 0, scrollOffset: 0, }); }); it("skips incomplete layout snapshots instead of saving an invalid anchor", () => { expect(resolveWorkGroupScrollAnchor({ ...state, data: [], scroll: 0 })).toBeUndefined(); expect(resolveWorkGroupScrollAnchor({ ...state, scroll: Number.NaN })).toBeUndefined(); expect( resolveWorkGroupScrollAnchor({ ...state, scroll: 165, positionAtIndex: () => undefined }), ).toBeUndefined(); expect( resolveWorkGroupScrollAnchor({ ...state, scroll: 165, positionAtIndex: (index) => (index === 0 ? 0 : Number.NaN), }), ).toBeUndefined(); });});
import { describe, expect, it } from "vite-plus/test";
import { resolveWorkGroupScrollAnchor } from "./scrollAnchor.js";
describe("tool-group scroll anchors", () => {
const data = Array.from({ length: 18 }, (_, index) => ({ id: `call-${index}` }));
const state = { data, positionAtIndex: (index: number) => index * 33 };
it("returns to the top after a fast flick even when the cached start is five rows behind", () => {
const snapshot = { ...state, scroll: 0, start: 5 };
expect(resolveWorkGroupScrollAnchor(snapshot)).toEqual({
rowId: "call-0",
offsetWithinRow: 0,
scrollOffset: 0,
});
});
it.each([
{ scroll: 302, start: 0, rowId: "call-9", offsetWithinRow: 5 },
{ scroll: 40, start: 12, rowId: "call-1", offsetWithinRow: 7 },
{ scroll: 165, start: 4, rowId: "call-5", offsetWithinRow: 0 },
])("uses the measured position at $scroll rather than cached row $start", (example) => {
expect(resolveWorkGroupScrollAnchor({ ...state, ...example })).toEqual({
rowId: example.rowId,
offsetWithinRow: example.offsetWithinRow,
scrollOffset: example.scroll,
});
});
it("preserves an offset within expanded output", () => {
const positions = [0, 33, 600];
expect(
resolveWorkGroupScrollAnchor({
data: [{ id: "first" }, { id: "output" }, { id: "last" }],
scroll: 153,
positionAtIndex: (index) => positions[index],
}),
).toEqual({ rowId: "output", offsetWithinRow: 120, scrollOffset: 153 });
});
it("does not preserve overscroll before the first row", () => {
expect(resolveWorkGroupScrollAnchor({ ...state, scroll: -20 })).toEqual({
rowId: "call-0",
offsetWithinRow: 0,
scrollOffset: 0,
});
});
it("skips incomplete layout snapshots instead of saving an invalid anchor", () => {
expect(resolveWorkGroupScrollAnchor({ ...state, data: [], scroll: 0 })).toBeUndefined();
expect(resolveWorkGroupScrollAnchor({ ...state, scroll: Number.NaN })).toBeUndefined();
expect(
resolveWorkGroupScrollAnchor({ ...state, scroll: 165, positionAtIndex: () => undefined }),
).toBeUndefined();
expect(
resolveWorkGroupScrollAnchor({
...state,
scroll: 165,
positionAtIndex: (index) => (index === 0 ? 0 : Number.NaN),
}),
).toBeUndefined();
});
});