Files
xmarre-ComfyUI-Image-Conveyor/tests/test_gallery_math.mjs
T

123 lines
3.9 KiB
JavaScript

import assert from 'node:assert/strict'
import test from 'node:test'
import {
calculateGalleryMetrics,
calculateVisibleCardRange,
isDragLeavingDocument,
isHighVelocityScroll,
planCardSlotReuse,
planViewScrollSwitch
} from '../web/image_conveyor_math.mjs'
test('responsive metrics add columns as width grows', () => {
const medium = calculateGalleryMetrics(520, 172, 10)
const wide = calculateGalleryMetrics(1040, 172, 10)
assert.equal(medium.columns, 2)
assert.ok(wide.columns > medium.columns)
assert.ok(medium.mediaHeight / medium.cardHeight >= 0.68)
})
test('ten thousand items keep a bounded live-card range', () => {
const metrics = calculateGalleryMetrics(720, 172, 10)
const range = calculateVisibleCardRange(
10_000,
metrics.columns,
metrics.rowStride,
10,
250_000,
700,
2
)
assert.ok(range.end - range.start <= 40)
assert.ok(range.start > 0)
assert.ok(range.end < 10_000)
})
test('range clamps scroll after filtering to a smaller collection', () => {
const metrics = calculateGalleryMetrics(520, 172, 10)
const range = calculateVisibleCardRange(3, metrics.columns, metrics.rowStride, 10, 999_999, 700, 2)
assert.equal(range.scrollTop, 0)
assert.deepEqual([range.start, range.end], [0, 3])
})
test('recycled card slots stay attached to overlapping item identities', () => {
const assignments = planCardSlotReuse(
['a', 'b', 'c', 'd', null],
['c', 'd', 'e', 'f', 'g']
)
assert.deepEqual(assignments, [2, 3, 0, 1, 4])
assert.equal(new Set(assignments).size, assignments.length)
const previous = Array.from({ length: 40 }, (_, index) => `item-${index}`)
const next = Array.from({ length: 40 }, (_, index) => `item-${index + 4}`)
const shiftedAssignments = planCardSlotReuse(previous, next)
const retained = shiftedAssignments.filter((slotIndex, index) => previous[slotIndex] === next[index])
assert.equal(retained.length, 36)
})
test('only high-velocity scrolling defers intermediate thumbnail requests', () => {
assert.equal(isHighVelocityScroll(80, 16, 220), false)
assert.equal(isHighVelocityScroll(20, 0, 220), false)
assert.equal(isHighVelocityScroll(240, 16, 220), true)
assert.equal(isHighVelocityScroll(350, 100, 220), true)
})
test('tab switches preserve independent scroll positions', () => {
const toInput = planViewScrollSwitch(
'conveyor',
'input',
42_500,
{ conveyor: 0, input: 317_250 }
)
assert.deepEqual(toInput.positions, { conveyor: 42_500, input: 317_250 })
assert.deepEqual(toInput.restore, { view: 'input', scrollTop: 317_250 })
const backToConveyor = planViewScrollSwitch(
'input',
'conveyor',
317_250,
toInput.positions
)
assert.deepEqual(backToConveyor.positions, { conveyor: 42_500, input: 317_250 })
assert.deepEqual(backToConveyor.restore, { view: 'conveyor', scrollTop: 42_500 })
})
test('rapid tab switches do not replace an unrendered destination position', () => {
const switchedBack = planViewScrollSwitch(
'input',
'conveyor',
42_500,
{ conveyor: 42_500, input: 317_250 },
'input'
)
assert.equal(switchedBack.positions.input, 317_250)
assert.deepEqual(switchedBack.restore, { view: 'conveyor', scrollTop: 42_500 })
})
test('external drag exit distinguishes viewport exits from child transitions', () => {
const documentNode = {}
const insideNode = {}
const outsideNode = {}
const documentElement = {
ownerDocument: documentNode,
contains: (target) => target === insideNode
}
assert.equal(
isDragLeavingDocument({ target: insideNode, relatedTarget: insideNode }, documentElement),
false
)
assert.equal(
isDragLeavingDocument({ target: insideNode, relatedTarget: null }, documentElement),
true
)
assert.equal(
isDragLeavingDocument({ target: insideNode, relatedTarget: outsideNode }, documentElement),
true
)
assert.equal(
isDragLeavingDocument({ target: documentNode, relatedTarget: insideNode }, documentElement),
true
)
})