Skip to content

Commit ac73ae0

Browse files
committed
test: add caniuse and w3c route tests
1 parent 5916d39 commit ac73ae0

2 files changed

Lines changed: 499 additions & 0 deletions

File tree

Lines changed: 308 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,308 @@
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+
let origDataDir;
119+
120+
beforeAll(async () => {
121+
tmpDir = await mkdtemp(path.join(tmpdir(), "caniuse-test-"));
122+
caniuseDir = path.join(tmpDir, "caniuse");
123+
await mkdir(caniuseDir, { recursive: true });
124+
125+
// Write a minimal fixture for a feature called "test-feature"
126+
const fixtureData = {
127+
all: {
128+
chrome: [
129+
["120", ["y"]],
130+
["119", ["y"]],
131+
["118", ["y"]],
132+
["117", ["a"]],
133+
["116", ["n"]],
134+
],
135+
firefox: [
136+
["121", ["y"]],
137+
["120", ["y"]],
138+
["119", ["a"]],
139+
],
140+
safari: [
141+
["17", ["y"]],
142+
["16", ["a"]],
143+
],
144+
edge: [
145+
["120", ["y"]],
146+
],
147+
opera: [
148+
["100", ["n"]],
149+
],
150+
},
151+
summary: {
152+
chrome: [["120", ["y"]]],
153+
firefox: [["121", ["y"]]],
154+
safari: [["17", ["y"]]],
155+
edge: [["120", ["y"]]],
156+
opera: [["100", ["n"]]],
157+
},
158+
};
159+
await writeFile(
160+
path.join(caniuseDir, "test-feature.json"),
161+
JSON.stringify(fixtureData),
162+
);
163+
164+
// Set DATA_DIR before importing the module that reads it at load time
165+
origDataDir = process.env.DATA_DIR;
166+
process.env.DATA_DIR = tmpDir;
167+
168+
// Dynamic import after env is set
169+
const mod = await import(
170+
"../../../../build/routes/caniuse/lib/index.js"
171+
);
172+
createResponseBody = mod.createResponseBody;
173+
});
174+
175+
afterAll(async () => {
176+
process.env.DATA_DIR = origDataDir;
177+
await rm(tmpDir, { recursive: true, force: true });
178+
});
179+
180+
it("returns default browsers for undefined input", async () => {
181+
const result = await createResponseBody({
182+
feature: "test-feature",
183+
format: "json",
184+
});
185+
expect(result).not.toBeNull();
186+
// Should include default browsers (chrome, firefox, safari, edge, etc.)
187+
// but not all browsers. The defaults include "samsung", "and_chr", etc.
188+
expect(Object.keys(result)).toContain("chrome");
189+
expect(Object.keys(result)).toContain("firefox");
190+
expect(Object.keys(result)).toContain("safari");
191+
});
192+
193+
it("returns default browsers for non-array, non-'all' input", async () => {
194+
const result = await createResponseBody({
195+
feature: "test-feature",
196+
browsers: "invalid-string",
197+
format: "json",
198+
});
199+
expect(result).not.toBeNull();
200+
// Should return defaults since "invalid-string" is not "all"
201+
expect(Object.keys(result)).toContain("chrome");
202+
});
203+
204+
it("returns empty browsers list (all browsers) when 'all' is passed", async () => {
205+
const result = await createResponseBody({
206+
feature: "test-feature",
207+
browsers: "all",
208+
format: "json",
209+
});
210+
expect(result).not.toBeNull();
211+
// When "all" is passed, sanitizeBrowsersList returns [], which means
212+
// createResponseBodyJSON pushes all keys from data.all
213+
expect(Object.keys(result)).toContain("chrome");
214+
expect(Object.keys(result)).toContain("firefox");
215+
expect(Object.keys(result)).toContain("safari");
216+
expect(Object.keys(result)).toContain("edge");
217+
expect(Object.keys(result)).toContain("opera");
218+
});
219+
220+
it("filters invalid browser names from array input", async () => {
221+
const result = await createResponseBody({
222+
feature: "test-feature",
223+
browsers: ["chrome", "invalid-browser", "firefox"],
224+
format: "json",
225+
});
226+
expect(result).not.toBeNull();
227+
expect(Object.keys(result)).toContain("chrome");
228+
expect(Object.keys(result)).toContain("firefox");
229+
// "invalid-browser" should be filtered out
230+
expect(Object.keys(result)).not.toContain("invalid-browser");
231+
});
232+
233+
it("returns defaults when all array entries are invalid", async () => {
234+
const result = await createResponseBody({
235+
feature: "test-feature",
236+
browsers: ["not-a-browser", "also-invalid"],
237+
format: "json",
238+
});
239+
expect(result).not.toBeNull();
240+
// Filtered array is empty, so defaults are used
241+
expect(Object.keys(result)).toContain("chrome");
242+
expect(Object.keys(result)).toContain("firefox");
243+
});
244+
245+
it("returns null for non-existent feature", async () => {
246+
const result = await createResponseBody({
247+
feature: "nonexistent-feature",
248+
format: "json",
249+
});
250+
expect(result).toBeNull();
251+
});
252+
253+
it("defaults to 4 versions when none specified", async () => {
254+
const result = await createResponseBody({
255+
feature: "test-feature",
256+
browsers: ["chrome"],
257+
format: "json",
258+
});
259+
expect(result).not.toBeNull();
260+
// Chrome has 5 versions in fixture, should be capped at 4
261+
expect(result.chrome.length).toBe(4);
262+
});
263+
264+
it("respects custom version count", async () => {
265+
const result = await createResponseBody({
266+
feature: "test-feature",
267+
browsers: ["chrome"],
268+
format: "json",
269+
versions: 2,
270+
});
271+
expect(result).not.toBeNull();
272+
expect(result.chrome.length).toBe(2);
273+
});
274+
});
275+
276+
describe("caniuse - getSupportTitle logic", () => {
277+
// getSupportTitle is a closure inside formatAsHTML, so test the logic
278+
// using the SUPPORT_TITLES map directly (same algorithm).
279+
function getSupportTitle(keys) {
280+
return keys
281+
.filter(key => SUPPORT_TITLES.has(key))
282+
.map(key => SUPPORT_TITLES.get(key))
283+
.join(" ");
284+
}
285+
286+
it("maps a single key correctly", () => {
287+
expect(getSupportTitle(["y"])).toBe("Supported.");
288+
expect(getSupportTitle(["n"])).toBe("No support, or disabled by default.");
289+
});
290+
291+
it("handles compound key arrays", () => {
292+
expect(getSupportTitle(["y", "x"])).toBe(
293+
"Supported. Requires prefix to work.",
294+
);
295+
expect(getSupportTitle(["a", "d"])).toBe(
296+
"Almost supported (aka Partial support). Disabled by default (needs to enabled).",
297+
);
298+
});
299+
300+
it("filters out unknown keys", () => {
301+
expect(getSupportTitle(["y", "unknown"])).toBe("Supported.");
302+
expect(getSupportTitle(["unknown"])).toBe("");
303+
});
304+
305+
it("returns empty string for empty array", () => {
306+
expect(getSupportTitle([])).toBe("");
307+
});
308+
});

0 commit comments

Comments
 (0)