~james/core

core/web/src/lib/api/blob.test.ts -rw-r--r-- 3.0 KiB
452f17b7 — james chore(import): snapshot james.dad.town/core at f70c71c7696a 15 hours ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import { describe, expect, it } from "vitest";
import {
	blobTransport,
	contentStats,
	formatBytes,
	MAX_INLINE_SIZE,
	renderedInPage,
	textCheck,
	type RepoBlobView
} from "#lib/api/blob.ts";

describe("contentStats", () => {
	it("counts an empty string as no lines and no bytes", () => {
		expect(contentStats("")).toEqual({ lines: 0, bytes: 0, sizeLabel: "0 B" });
	});

	it("treats a trailing newline as a terminator, matching the repo blob header", () => {
		expect(contentStats("a\nb").lines).toBe(2);
		expect(contentStats("a\nb\n").lines).toBe(2);
		expect(contentStats("a\n").lines).toBe(1);
	});

	it("sizes utf-8 rather than utf-16 code units", () => {
		expect(contentStats("é").bytes).toBe(2);
		expect(contentStats("hi").bytes).toBe(2);
	});

	it("keeps the 1MiB inline cap meaningful for the string loader", () => {
		expect(contentStats("x".repeat(MAX_INLINE_SIZE)).bytes).toBeLessThanOrEqual(
			MAX_INLINE_SIZE
		);
		expect(contentStats("x".repeat(MAX_INLINE_SIZE + 1)).bytes).toBeGreaterThan(
			MAX_INLINE_SIZE
		);
	});
});

describe("formatBytes", () => {
	it("promotes a rounded spill into the next unit", () => {
		expect(formatBytes(999)).toBe("999 B");
		expect(formatBytes(1000)).toBe("1.0 kB");
		expect(formatBytes(999_999)).toBe("1.0 MB");
	});
});

describe("blobTransport", () => {
	const blob = (overrides: Partial<RepoBlobView> = {}): RepoBlobView => ({
		ref: "main",
		path: "go.mod",
		kind: "code",
		sizeLabel: "12 B",
		lines: 1,
		contents: "module x\n",
		fileTooLarge: false,
		defaultView: "code",
		submodule: null,
		lastCommit: null,
		...overrides
	});

	it("leaves the text of a server rendered code view out of the data", () => {
		expect(blobTransport.encode(renderedInPage(blob()))).toEqual([
			blob({ contents: null, contentsCheck: textCheck("module x\n") })
		]);
	});

	it("keeps the text of a blob nobody marked", () => {
		expect(blobTransport.encode(blob())).toBe(false);
	});

	it("keeps the text when the page renders markup instead", () => {
		const markup = blob({ kind: "markup", defaultView: "rendered" });
		expect(blobTransport.encode(renderedInPage(markup))).toBe(false);
	});

	it("keeps text with carriage returns or NUL", () => {
		expect(blobTransport.encode(renderedInPage(blob({ contents: "a\r\nb\r\n" })))).toBe(false);
		expect(blobTransport.encode(renderedInPage(blob({ contents: "a\u0000b\n" })))).toBe(false);
	});

	it("decodes to the view it encoded", () => {
		const encoded = blob({ contents: null, contentsCheck: textCheck("module x\n") });
		expect(blobTransport.decode([encoded])).toEqual(encoded);
	});
});

describe("textCheck", () => {
	it("matches the same text", () => {
		expect(textCheck("a\tb\n")).toBe(textCheck("a\tb\n"));
	});

	it("misses text that differs by one character or one carriage return", () => {
		const check = textCheck("a\r\nb\n");
		expect(textCheck("a\nb\n")).not.toBe(check);
		expect(textCheck("a\r\nc\n")).not.toBe(check);
	});

	it("misses a same-length swap", () => {
		expect(textCheck("ba")).not.toBe(textCheck("ab"));
	});
});