Skip to content
Source
Sign inSign up

readableSyntaxTheme.test.ts

53 lines2.1 KB

1import { describe, expect, it } from "vite-plus/test";
2​
3import { readableOnLightCode, readableSyntaxColor } from "./readableSyntaxTheme";
4​
5function luminance(hex: string): number {
6 const [r, g, b] = [1, 3, 5].map((start) => {
7 const value = Number.parseInt(hex.slice(start, start + 2), 16) / 255;
8 return value <= 0.03928 ? value / 12.92 : ((value + 0.055) / 1.055) ** 2.4;
9 }) as [number, number, number];
10 return 0.2126 * r + 0.7152 * g + 0.0722 * b;
12​
13function contrast(foreground: string, background: string): number {
14 return (luminance(background) + 0.05) / (luminance(foreground) + 0.05);
16​
17// pierre-light's faintest syntax colors: yellow, cyan, orange, teal, green, pink.
18const PIERRE_LIGHT_FAINT = ["#d5a910", "#08c0ef", "#d5901c", "#1ca1c7", "#199f43", "#d32a61"];
19// Light code surfaces: the code background, added and deleted lines, and changed words on each.
20const LIGHT_CODE_SURFACES = ["#fcfcfc", "#ecf9f4", "#fef0f0", "#ccecdf", "#f8d3d4"];
21​
22describe("readableOnLightCode", () => {
23 it("brings pierre-light's faint colors to 4.5:1 on every light code surface", () => {
24 for (const color of PIERRE_LIGHT_FAINT) {
25 for (const surface of LIGHT_CODE_SURFACES) {
26 expect(contrast(readableOnLightCode(color), surface)).toBeGreaterThanOrEqual(4.5);
27 }
28 }
29 });
30​
31 it("keeps tokens that differed only in lightness apart, in pierre-light's order", () => {
32 // [lighter, darker] in pierre-light: comment/punctuation, operator/number, property/decorator.
33 for (const [lighter, darker] of [
34 ["#737373", "#636363"],
35 ["#08c0ef", "#1ca1c7"],
36 ["#009fff", "#1a85d4"],
37 ] as const) {
38 expect(luminance(readableSyntaxColor(lighter))).toBeGreaterThan(
39 luminance(readableSyntaxColor(darker)) + 0.02,
40 );
41 }
42 });
43​
44 it("leaves colors that already read unchanged", () => {
45 expect(readableOnLightCode("#693acf")).toBe("#693acf");
46 expect(readableOnLightCode("#0a0a0a")).toBe("#0a0a0a");
47 });
48​
49 it("keeps an alpha suffix and ignores non-hex values", () => {
50 expect(readableOnLightCode("#d5a91080")).toMatch(/80$/);
51 expect(readableOnLightCode("var(--x)")).toBe("var(--x)");
52 });
53});