Fun picker improvements
This commit is contained in:
parent
427f91f903
commit
b0653d06fe
142 changed files with 3581 additions and 1280 deletions
135
ts/test-node/components/fun/segments_test.ts
Normal file
135
ts/test-node/components/fun/segments_test.ts
Normal file
|
@ -0,0 +1,135 @@
|
|||
// Copyright 2025 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
import assert from 'node:assert/strict';
|
||||
import {
|
||||
_getSegmentRanges,
|
||||
_getSegmentSize,
|
||||
_SEGMENT_SIZE_BUCKETS,
|
||||
type _SegmentRange,
|
||||
} from '../../../components/fun/data/segments';
|
||||
|
||||
const SMALLEST_BUCKET = Math.min(..._SEGMENT_SIZE_BUCKETS);
|
||||
|
||||
describe('segments', () => {
|
||||
describe('_getSegmentSize', () => {
|
||||
function check(contentLength: number, expectedSize: number, label: string) {
|
||||
assert.equal(_getSegmentSize(contentLength), expectedSize, label);
|
||||
}
|
||||
|
||||
it('should use the content-length if its shorter than the smallest segment size', () => {
|
||||
check(0, 0, 'zero');
|
||||
check(1, 1, 'one');
|
||||
check(10, 10, 'ten');
|
||||
check(SMALLEST_BUCKET - 1, SMALLEST_BUCKET - 1, 'smallest - 1');
|
||||
check(SMALLEST_BUCKET - 10, SMALLEST_BUCKET - 10, 'smallest - 10');
|
||||
});
|
||||
|
||||
it('should pick the closest smaller bucket to the content-length', () => {
|
||||
_SEGMENT_SIZE_BUCKETS.forEach((size, index) => {
|
||||
check(size, size, `exact size ${size}`);
|
||||
check(size + 1, size, `size ${size} + 1`);
|
||||
check(size + 10, size, `size ${size} + 10`);
|
||||
const largerSize = _SEGMENT_SIZE_BUCKETS[index - 1] ?? null; // Note: at() wraps
|
||||
if (largerSize != null) {
|
||||
check(largerSize - 1, size, `larger size ${largerSize} - 1`);
|
||||
check(largerSize - 10, size, `larger size ${largerSize} - 10`);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('_getSegmentRanges', () => {
|
||||
function check(
|
||||
contentLength: number,
|
||||
segmentSize: number,
|
||||
expected: ReadonlyArray<_SegmentRange>
|
||||
) {
|
||||
assert.deepEqual(_getSegmentRanges(contentLength, segmentSize), expected);
|
||||
}
|
||||
|
||||
function segmentAtIndex(segmentSize: number, index: number): _SegmentRange {
|
||||
return {
|
||||
startIndex: segmentSize * index,
|
||||
endIndexInclusive: segmentSize * (index + 1) - 1,
|
||||
sliceStart: 0,
|
||||
sliceSize: segmentSize,
|
||||
segmentSize,
|
||||
};
|
||||
}
|
||||
|
||||
function finalSegment(contentLength: number, segmentSize: number) {
|
||||
const offset = contentLength % segmentSize;
|
||||
return {
|
||||
startIndex: contentLength - segmentSize,
|
||||
endIndexInclusive: contentLength - 1,
|
||||
sliceStart: segmentSize - offset,
|
||||
sliceSize: offset,
|
||||
segmentSize,
|
||||
};
|
||||
}
|
||||
|
||||
it('should return 0 segments for contentLength 0', () => {
|
||||
const contentLength = 0;
|
||||
const segmentSize = SMALLEST_BUCKET;
|
||||
check(contentLength, segmentSize, []);
|
||||
});
|
||||
|
||||
it('should return 1 segments for contentLength equal to bucket segmentSize', () => {
|
||||
const contentLength = SMALLEST_BUCKET;
|
||||
const segmentSize = SMALLEST_BUCKET;
|
||||
check(contentLength, segmentSize, [segmentAtIndex(segmentSize, 0)]);
|
||||
});
|
||||
|
||||
it('should return 2 segments for contentLength slightly bigger than segmentSize', () => {
|
||||
const offset = 10;
|
||||
const contentLength = SMALLEST_BUCKET + offset;
|
||||
const segmentSize = SMALLEST_BUCKET;
|
||||
check(contentLength, segmentSize, [
|
||||
segmentAtIndex(segmentSize, 0),
|
||||
finalSegment(contentLength, segmentSize),
|
||||
]);
|
||||
});
|
||||
|
||||
it('should return 2 segments for contentLength equal to 2x segmentSize', () => {
|
||||
const contentLength = SMALLEST_BUCKET * 2;
|
||||
const segmentSize = SMALLEST_BUCKET;
|
||||
check(contentLength, segmentSize, [
|
||||
segmentAtIndex(segmentSize, 0),
|
||||
segmentAtIndex(segmentSize, 1),
|
||||
]);
|
||||
});
|
||||
|
||||
it('should return 3 segments for contentLength slightly bigger than 2x segmentSize', () => {
|
||||
const offset = 10;
|
||||
const contentLength = SMALLEST_BUCKET * 2 + offset;
|
||||
const segmentSize = SMALLEST_BUCKET;
|
||||
check(contentLength, segmentSize, [
|
||||
segmentAtIndex(segmentSize, 0),
|
||||
segmentAtIndex(segmentSize, 1),
|
||||
finalSegment(contentLength, segmentSize),
|
||||
]);
|
||||
});
|
||||
|
||||
it('should return 3 segments for contentLength equal to 3x segmentSize', () => {
|
||||
const contentLength = SMALLEST_BUCKET * 3;
|
||||
const segmentSize = SMALLEST_BUCKET;
|
||||
check(contentLength, segmentSize, [
|
||||
segmentAtIndex(segmentSize, 0),
|
||||
segmentAtIndex(segmentSize, 1),
|
||||
segmentAtIndex(segmentSize, 2),
|
||||
]);
|
||||
});
|
||||
|
||||
it('should return 4 segments for contentLength slightly bigger than 3x segmentSize', () => {
|
||||
const offset = 10;
|
||||
const contentLength = SMALLEST_BUCKET * 3 + offset;
|
||||
const segmentSize = SMALLEST_BUCKET;
|
||||
check(contentLength, segmentSize, [
|
||||
segmentAtIndex(segmentSize, 0),
|
||||
segmentAtIndex(segmentSize, 1),
|
||||
segmentAtIndex(segmentSize, 2),
|
||||
finalSegment(contentLength, segmentSize),
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue