txw/txw-mhzc-web/tests/unit/gxnlpt-scroll-helpers.test.js
2026-05-25 20:19:55 +08:00

86 lines
2.1 KiB
JavaScript

const test = require('node:test');
const assert = require('node:assert/strict');
const {
buildScrollRequestKey,
getSectionTargetTop,
resolveAnchorScrollAction,
resolveActiveSectionIndex,
} = require('../../src/pages/index/utils/gxnlpt-scroll-helpers.js');
test('buildScrollRequestKey builds stable request keys', () => {
assert.equal(buildScrollRequestKey('content-1', 2), 'content-1::2');
assert.equal(buildScrollRequestKey('content-1'), 'content-1::na');
});
test('getSectionTargetTop uses offsetTop chain instead of viewport coordinates', () => {
const scrollRoot = { offsetTop: 0 };
const mid = { offsetTop: 120, offsetParent: scrollRoot };
const target = { offsetTop: 260, offsetParent: mid };
assert.equal(getSectionTargetTop(target, scrollRoot, 24), 356);
assert.equal(getSectionTargetTop(target, scrollRoot, 0), 380);
});
test('resolveAnchorScrollAction skips duplicate or near-target scrolls', () => {
assert.equal(
resolveAnchorScrollAction({
currentTop: 198,
targetTop: 200,
pendingRequestKey: '',
nextRequestKey: 'content-1::0',
suppressSectionObserver: false,
}),
'skip-near-target'
);
assert.equal(
resolveAnchorScrollAction({
currentTop: 0,
targetTop: 320,
pendingRequestKey: 'content-2::1',
nextRequestKey: 'content-2::1',
suppressSectionObserver: true,
}),
'skip-duplicate-pending'
);
});
test('resolveActiveSectionIndex uses scrollTop-based coordinates for active tab', () => {
const sectionTops = [
{ index: 0, top: 0 },
{ index: 1, top: 420 },
{ index: 2, top: 860 },
];
assert.equal(
resolveActiveSectionIndex({
sectionTops,
currentTop: 0,
anchorOffset: 96,
defaultIndex: 0,
}),
0
);
assert.equal(
resolveActiveSectionIndex({
sectionTops,
currentTop: 360,
anchorOffset: 96,
defaultIndex: 0,
}),
1
);
assert.equal(
resolveActiveSectionIndex({
sectionTops,
currentTop: 820,
anchorOffset: 96,
defaultIndex: 0,
}),
2
);
});