mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-11-14 02:29:33 +01:00
86 lines
3.2 KiB
TypeScript
86 lines
3.2 KiB
TypeScript
/**
|
|||
|
|
* @fileoverview Tests for src/local-model/format.ts: the ONE place a byte count becomes a size a
|
||
|
|
* person reads, and the memory class a Mac is sold as.
|
||
|
|
*
|
||
|
|
* What is pinned here is a contract with the browser: it prints the text it was sent and adds
|
||
|
|
* ' GB' itself, so the text must be decimal GB, carry no unit, and round the same way everywhere.
|
||
|
|
*
|
||
|
|
* Port: N/A (pure functions).
|
||
|
|
*/
|
||
|
|
|
||
|
|
import { describe, expect, it } from 'vitest';
|
||
|
|
import { formatGb, GB, GIB, memClassGb, MIB } from '../src/local-model/format.js';
|
||
|
|
|
||
|
|
describe('byte units', () => {
|
||
|
|
it('keeps decimal GB (what a person reads) apart from the binary units of the budget math', () => {
|
||
|
|
expect(GB).toBe(1_000_000_000);
|
||
|
|
expect(GIB).toBe(1_073_741_824);
|
||
|
|
expect(MIB).toBe(1_048_576);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('formatGb', () => {
|
||
|
|
it('prints decimal GB, so a Mac sold as 16 GB reads 17.2 and one sold as 48 GB reads 51.5', () => {
|
||
|
|
expect(formatGb(17_179_869_184)).toBe('17.2');
|
||
|
|
expect(formatGb(51_539_607_552)).toBe('51.5');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('prints the registry sizes of the catalogue models as the registry shows them', () => {
|
||
|
|
expect(formatGb(6_550_825_373)).toBe('6.6');
|
||
|
|
expect(formatGb(13_793_441_427)).toBe('13.8');
|
||
|
|
expect(formatGb(17_741_871_939)).toBe('17.7');
|
||
|
|
expect(formatGb(22_621_314_161)).toBe('22.6');
|
||
|
|
expect(formatGb(81_370_035_877)).toBe('81.4');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('keeps one decimal below 100 and none from 100', () => {
|
||
|
|
expect(formatGb(1 * GB)).toBe('1.0');
|
||
|
|
expect(formatGb(99.94 * GB)).toBe('99.9');
|
||
|
|
// Rounds to 100.0, which is already "from 100".
|
||
|
|
expect(formatGb(99.96 * GB)).toBe('100');
|
||
|
|
expect(formatGb(100 * GB)).toBe('100');
|
||
|
|
// The free disk of the two test Macs, from their `df -k` lines.
|
||
|
|
expect(formatGb(890_926_084 * 1024)).toBe('912');
|
||
|
|
expect(formatGb(41_752_848 * 1024)).toBe('42.8');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('never prints a unit, a thousands separator or an exponent', () => {
|
||
|
|
for (const bytes of [1, 5 * MIB, 3 * GIB, 250 * GB, 4000 * GB, 2.5e15]) {
|
||
|
|
expect(formatGb(bytes)).toMatch(/^\d+(\.\d)?$/);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
it("reads '0.0' for anything that is not a positive size", () => {
|
||
|
|
for (const bytes of [0, -1, -5 * GB, Number.NaN, Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY]) {
|
||
|
|
expect(formatGb(bytes)).toBe('0.0');
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
it('shows a size too small for one decimal as 0.0, never as an empty text', () => {
|
||
|
|
expect(formatGb(10 * MIB)).toBe('0.0');
|
||
|
|
expect(formatGb(512 * MIB)).toBe('0.5');
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('memClassGb', () => {
|
||
|
|
it('names the size a Mac is sold as: whole binary gigabytes', () => {
|
||
|
|
for (const sold of [8, 16, 18, 24, 32, 36, 48, 64, 96, 128, 192]) {
|
||
|
|
expect(memClassGb(sold * GIB)).toBe(sold);
|
||
|
|
}
|
||
|
|
// The exact `hw.memsize` of the two test Macs.
|
||
|
|
expect(memClassGb(17_179_869_184)).toBe(16);
|
||
|
|
expect(memClassGb(51_539_607_552)).toBe(48);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('rounds a size that is not a whole number of gigabytes', () => {
|
||
|
|
// `hw.memsize_usable` of the 16 GB test Mac is a little below 16 GiB.
|
||
|
|
expect(memClassGb(16_631_808_000)).toBe(15);
|
||
|
|
expect(memClassGb(16 * GIB - 100 * MIB)).toBe(16);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('reads 0 for anything that is not a positive size', () => {
|
||
|
|
for (const bytes of [0, -1, Number.NaN, Number.POSITIVE_INFINITY]) {
|
||
|
|
expect(memClassGb(bytes)).toBe(0);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
});
|