Signal-Desktop/ts/test-node/components/fun/segments_test.ts

136 lines
4.6 KiB
TypeScript

// 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),
]);
});
});
});