44 lines
2.0 KiB
TypeScript
44 lines
2.0 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|||
|
|
import { decodeViewerText, encodeViewerText } from "./textFormat";
|
||
|
|
import type { Editability } from "./editability";
|
||
|
|
|
||
|
|
const editable: Editability = { kind: "text", editable: true, reason: null };
|
||
|
|
const bytes = (s: string) => new TextEncoder().encode(s);
|
||
|
|
const BOM = [0xef, 0xbb, 0xbf];
|
||
|
|
|
||
|
|
/** What CodeMirror hands back: every line break normalised to "\n". */
|
||
|
|
const asEditorText = (s: string) => s.replace(/\r\n?/g, "\n");
|
||
|
|
|
||
|
|
describe("decodeViewerText / encodeViewerText", () => {
|
||
|
|
it("round-trips an LF file byte for byte", () => {
|
||
|
|
const d = decodeViewerText(bytes("a\nb\n"), editable);
|
||
|
|
expect(d.format).toEqual({ bom: false, eol: "\n" });
|
||
|
|
expect(Array.from(encodeViewerText(asEditorText(d.text), d.format))).toEqual(Array.from(bytes("a\nb\n")));
|
||
|
|
});
|
||
|
|
|
||
|
|
it("keeps CRLF line endings through the editor's LF buffer", () => {
|
||
|
|
const d = decodeViewerText(bytes("a\r\nb\r\nc"), editable);
|
||
|
|
expect(d.format.eol).toBe("\r\n");
|
||
|
|
const edited = asEditorText(d.text).replace("b", "B");
|
||
|
|
expect(new TextDecoder().decode(encodeViewerText(edited, d.format))).toBe("a\r\nB\r\nc");
|
||
|
|
});
|
||
|
|
|
||
|
|
it("uses the dominant separator for a mixed file", () => {
|
||
|
|
expect(decodeViewerText(bytes("a\r\nb\r\nc\nd"), editable).format.eol).toBe("\r\n");
|
||
|
|
expect(decodeViewerText(bytes("a\nb\nc\r\nd"), editable).format.eol).toBe("\n");
|
||
|
|
expect(decodeViewerText(bytes("a\rb\rc"), editable).format.eol).toBe("\r");
|
||
|
|
});
|
||
|
|
|
||
|
|
it("strips a UTF-8 BOM from the text and puts it back on save", () => {
|
||
|
|
const d = decodeViewerText(new Uint8Array([...BOM, ...bytes("hi\n")]), editable);
|
||
|
|
expect(d.text).toBe("hi\n");
|
||
|
|
expect(d.format.bom).toBe(true);
|
||
|
|
expect(Array.from(encodeViewerText("hi\n", d.format))).toEqual([...BOM, ...bytes("hi\n")]);
|
||
|
|
});
|
||
|
|
|
||
|
|
it("makes invalid UTF-8 read-only rather than rewriting it", () => {
|
||
|
|
const d = decodeViewerText(new Uint8Array([0x61, 0xff, 0x62]), editable);
|
||
|
|
expect(d.editability).toMatchObject({ editable: false, reason: expect.stringMatching(/not valid UTF-8/) });
|
||
|
|
});
|
||
|
|
});
|