Skip to content

Commit e977ed7

Browse files
committed
test: add caniuse and w3c route tests
1 parent 39ce491 commit e977ed7

2 files changed

Lines changed: 536 additions & 0 deletions

File tree

Lines changed: 306 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,306 @@
1+
import {
2+
BROWSERS,
3+
DEFAULT_BROWSERS,
4+
SUPPORT_TITLES,
5+
} from "../../../../build/routes/caniuse/lib/constants.js";
6+
7+
import { mkdtemp, writeFile, mkdir, rm } from "fs/promises";
8+
import path from "path";
9+
import { tmpdir } from "os";
10+
11+
describe("caniuse - constants", () => {
12+
describe("BROWSERS", () => {
13+
it("is a Map", () => {
14+
expect(BROWSERS).toBeInstanceOf(Map);
15+
});
16+
17+
it("has expected browser names", () => {
18+
const expected = [
19+
"chrome",
20+
"firefox",
21+
"safari",
22+
"edge",
23+
"opera",
24+
"ios_saf",
25+
"samsung",
26+
"and_chr",
27+
"and_ff",
28+
"android",
29+
];
30+
for (const name of expected) {
31+
expect(BROWSERS.has(name))
32+
.withContext(`missing browser: ${name}`)
33+
.toBeTrue();
34+
}
35+
});
36+
37+
it("maps browser IDs to human-readable names", () => {
38+
expect(BROWSERS.get("chrome")).toBe("Chrome");
39+
expect(BROWSERS.get("firefox")).toBe("Firefox");
40+
expect(BROWSERS.get("safari")).toBe("Safari");
41+
expect(BROWSERS.get("edge")).toBe("Edge");
42+
expect(BROWSERS.get("ios_saf")).toBe("Safari (iOS)");
43+
expect(BROWSERS.get("and_chr")).toBe("Chrome (Android)");
44+
});
45+
46+
it("does not contain empty values", () => {
47+
for (const [key, value] of BROWSERS) {
48+
expect(key).withContext("key is non-empty").toBeTruthy();
49+
expect(value).withContext(`value for "${key}" is non-empty`).toBeTruthy();
50+
}
51+
});
52+
});
53+
54+
describe("DEFAULT_BROWSERS", () => {
55+
it("is an array", () => {
56+
expect(Array.isArray(DEFAULT_BROWSERS)).toBeTrue();
57+
});
58+
59+
it("is a valid subset of BROWSERS", () => {
60+
for (const browser of DEFAULT_BROWSERS) {
61+
expect(BROWSERS.has(browser))
62+
.withContext(`"${browser}" should be in BROWSERS`)
63+
.toBeTrue();
64+
}
65+
});
66+
67+
it("includes major browsers", () => {
68+
expect(DEFAULT_BROWSERS).toContain("chrome");
69+
expect(DEFAULT_BROWSERS).toContain("firefox");
70+
expect(DEFAULT_BROWSERS).toContain("safari");
71+
expect(DEFAULT_BROWSERS).toContain("edge");
72+
});
73+
74+
it("does not include all browsers", () => {
75+
expect(DEFAULT_BROWSERS.length).toBeLessThan(BROWSERS.size);
76+
});
77+
});
78+
79+
describe("SUPPORT_TITLES", () => {
80+
it("is a Map", () => {
81+
expect(SUPPORT_TITLES).toBeInstanceOf(Map);
82+
});
83+
84+
it("has all expected support keys", () => {
85+
const expectedKeys = ["y", "a", "n", "p", "u", "x", "d"];
86+
for (const key of expectedKeys) {
87+
expect(SUPPORT_TITLES.has(key))
88+
.withContext(`missing support key: "${key}"`)
89+
.toBeTrue();
90+
}
91+
});
92+
93+
it("maps single keys to descriptive titles", () => {
94+
expect(SUPPORT_TITLES.get("y")).toBe("Supported.");
95+
expect(SUPPORT_TITLES.get("n")).toBe("No support, or disabled by default.");
96+
expect(SUPPORT_TITLES.get("a")).toBe(
97+
"Almost supported (aka Partial support).",
98+
);
99+
expect(SUPPORT_TITLES.get("u")).toBe("Support unknown.");
100+
expect(SUPPORT_TITLES.get("x")).toBe("Requires prefix to work.");
101+
expect(SUPPORT_TITLES.get("p")).toBe("No support, but has Polyfill.");
102+
expect(SUPPORT_TITLES.get("d")).toBe(
103+
"Disabled by default (needs to enabled).",
104+
);
105+
});
106+
107+
it("returns undefined for unknown keys", () => {
108+
expect(SUPPORT_TITLES.get("z")).toBeUndefined();
109+
expect(SUPPORT_TITLES.get("")).toBeUndefined();
110+
});
111+
});
112+
});
113+
114+
describe("caniuse - sanitizeBrowsersList (via createResponseBody)", () => {
115+
let tmpDir;
116+
let caniuseDir;
117+
let createResponseBody;
118+
119+
beforeAll(async () => {
120+
tmpDir = await mkdtemp(path.join(tmpdir(), "caniuse-test-"));
121+
caniuseDir = path.join(tmpDir, "caniuse");
122+
await mkdir(caniuseDir, { recursive: true });
123+
124+
// Write a minimal fixture for a feature called "test-feature"
125+
const fixtureData = {
126+
all: {
127+
chrome: [
128+
["120", ["y"]],
129+
["119", ["y"]],
130+
["118", ["y"]],
131+
["117", ["a"]],
132+
["116", ["n"]],
133+
],
134+
firefox: [
135+
["121", ["y"]],
136+
["120", ["y"]],
137+
["119", ["a"]],
138+
],
139+
safari: [
140+
["17", ["y"]],
141+
["16", ["a"]],
142+
],
143+
edge: [
144+
["120", ["y"]],
145+
],
146+
opera: [
147+
["100", ["n"]],
148+
],
149+
},
150+
summary: {
151+
chrome: [["120", ["y"]]],
152+
firefox: [["121", ["y"]]],
153+
safari: [["17", ["y"]]],
154+
edge: [["120", ["y"]]],
155+
opera: [["100", ["n"]]],
156+
},
157+
};
158+
await writeFile(
159+
path.join(caniuseDir, "test-feature.json"),
160+
JSON.stringify(fixtureData),
161+
);
162+
163+
// Set DATA_DIR before importing the module that reads it at load time
164+
process.env.DATA_DIR = tmpDir;
165+
166+
// Dynamic import after env is set
167+
const mod = await import(
168+
"../../../../build/routes/caniuse/lib/index.js"
169+
);
170+
createResponseBody = mod.createResponseBody;
171+
});
172+
173+
afterAll(async () => {
174+
delete process.env.DATA_DIR;
175+
await rm(tmpDir, { recursive: true, force: true });
176+
});
177+
178+
it("returns default browsers for undefined input", async () => {
179+
const result = await createResponseBody({
180+
feature: "test-feature",
181+
format: "json",
182+
});
183+
expect(result).not.toBeNull();
184+
// Should include default browsers (chrome, firefox, safari, edge, etc.)
185+
// but not all browsers. The defaults include "samsung", "and_chr", etc.
186+
expect(Object.keys(result)).toContain("chrome");
187+
expect(Object.keys(result)).toContain("firefox");
188+
expect(Object.keys(result)).toContain("safari");
189+
});
190+
191+
it("returns default browsers for non-array, non-'all' input", async () => {
192+
const result = await createResponseBody({
193+
feature: "test-feature",
194+
browsers: "invalid-string",
195+
format: "json",
196+
});
197+
expect(result).not.toBeNull();
198+
// Should return defaults since "invalid-string" is not "all"
199+
expect(Object.keys(result)).toContain("chrome");
200+
});
201+
202+
it("returns empty browsers list (all browsers) when 'all' is passed", async () => {
203+
const result = await createResponseBody({
204+
feature: "test-feature",
205+
browsers: "all",
206+
format: "json",
207+
});
208+
expect(result).not.toBeNull();
209+
// When "all" is passed, sanitizeBrowsersList returns [], which means
210+
// createResponseBodyJSON pushes all keys from data.all
211+
expect(Object.keys(result)).toContain("chrome");
212+
expect(Object.keys(result)).toContain("firefox");
213+
expect(Object.keys(result)).toContain("safari");
214+
expect(Object.keys(result)).toContain("edge");
215+
expect(Object.keys(result)).toContain("opera");
216+
});
217+
218+
it("filters invalid browser names from array input", async () => {
219+
const result = await createResponseBody({
220+
feature: "test-feature",
221+
browsers: ["chrome", "invalid-browser", "firefox"],
222+
format: "json",
223+
});
224+
expect(result).not.toBeNull();
225+
expect(Object.keys(result)).toContain("chrome");
226+
expect(Object.keys(result)).toContain("firefox");
227+
// "invalid-browser" should be filtered out
228+
expect(Object.keys(result)).not.toContain("invalid-browser");
229+
});
230+
231+
it("returns defaults when all array entries are invalid", async () => {
232+
const result = await createResponseBody({
233+
feature: "test-feature",
234+
browsers: ["not-a-browser", "also-invalid"],
235+
format: "json",
236+
});
237+
expect(result).not.toBeNull();
238+
// Filtered array is empty, so defaults are used
239+
expect(Object.keys(result)).toContain("chrome");
240+
expect(Object.keys(result)).toContain("firefox");
241+
});
242+
243+
it("returns null for non-existent feature", async () => {
244+
const result = await createResponseBody({
245+
feature: "nonexistent-feature",
246+
format: "json",
247+
});
248+
expect(result).toBeNull();
249+
});
250+
251+
it("defaults to 4 versions when none specified", async () => {
252+
const result = await createResponseBody({
253+
feature: "test-feature",
254+
browsers: ["chrome"],
255+
format: "json",
256+
});
257+
expect(result).not.toBeNull();
258+
// Chrome has 5 versions in fixture, should be capped at 4
259+
expect(result.chrome.length).toBe(4);
260+
});
261+
262+
it("respects custom version count", async () => {
263+
const result = await createResponseBody({
264+
feature: "test-feature",
265+
browsers: ["chrome"],
266+
format: "json",
267+
versions: 2,
268+
});
269+
expect(result).not.toBeNull();
270+
expect(result.chrome.length).toBe(2);
271+
});
272+
});
273+
274+
describe("caniuse - getSupportTitle logic", () => {
275+
// getSupportTitle is a closure inside formatAsHTML, so test the logic
276+
// using the SUPPORT_TITLES map directly (same algorithm).
277+
function getSupportTitle(keys) {
278+
return keys
279+
.filter(key => SUPPORT_TITLES.has(key))
280+
.map(key => SUPPORT_TITLES.get(key))
281+
.join(" ");
282+
}
283+
284+
it("maps a single key correctly", () => {
285+
expect(getSupportTitle(["y"])).toBe("Supported.");
286+
expect(getSupportTitle(["n"])).toBe("No support, or disabled by default.");
287+
});
288+
289+
it("handles compound key arrays", () => {
290+
expect(getSupportTitle(["y", "x"])).toBe(
291+
"Supported. Requires prefix to work.",
292+
);
293+
expect(getSupportTitle(["a", "d"])).toBe(
294+
"Almost supported (aka Partial support). Disabled by default (needs to enabled).",
295+
);
296+
});
297+
298+
it("filters out unknown keys", () => {
299+
expect(getSupportTitle(["y", "unknown"])).toBe("Supported.");
300+
expect(getSupportTitle(["unknown"])).toBe("");
301+
});
302+
303+
it("returns empty string for empty array", () => {
304+
expect(getSupportTitle([])).toBe("");
305+
});
306+
});

0 commit comments

Comments
 (0)