Skip to content
This repository was archived by the owner on Mar 1, 2025. It is now read-only.

Commit 8730e21

Browse files
committed
feat: add vitest-fetch-mock for enhanced testing and setup configuration
1 parent d6453b5 commit 8730e21

File tree

7 files changed

+187
-168
lines changed

7 files changed

+187
-168
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
"tsx": "^4.19.2",
5555
"typescript": "^5.7.3",
5656
"vitest": "^3.0.5",
57+
"vitest-fetch-mock": "^0.4.3",
5758
"vitest-testdirs": "^2.1.1"
5859
},
5960
"pnpm": {

pnpm-lock.yaml

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/utils.ts

Lines changed: 0 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -28,137 +28,6 @@ export function slugify(val: string): string {
2828
.replace(/^-+|-+$/g, "");
2929
}
3030

31-
/**
32-
* Retrieves all available emoji versions from Unicode.org.
33-
* This function fetches both the root Unicode directory and the emoji-specific directory
34-
* to compile a comprehensive list of valid emoji versions.
35-
*
36-
* The function performs the following steps:
37-
* 1. Fetches content from Unicode.org's public directories
38-
* 2. Extracts version numbers using regex
39-
* 3. Validates each version
40-
* 4. Normalizes version numbers to valid semver format
41-
*
42-
* @throws {Error} When either the root or emoji page fetch fails
43-
* @returns {Promise<EmojiVersion[]>} A promise that resolves to an array of emoji versions,
44-
* sorted according to semver rules
45-
*/
46-
export async function getAllEmojiVersions(): Promise<EmojiVersion[]> {
47-
const [rootResult, emojiResult] = await Promise.allSettled([
48-
"https://unicode.org/Public/",
49-
"https://unicode.org/Public/emoji/",
50-
].map(async (url) => {
51-
const res = await fetch(url);
52-
53-
if (!res.ok) {
54-
throw new Error(`failed to fetch ${url}: ${res.statusText}`);
55-
}
56-
57-
return res.text();
58-
}));
59-
60-
if (rootResult == null || emojiResult == null) {
61-
throw new Error("failed to fetch root or emoji page");
62-
}
63-
64-
if (rootResult.status === "rejected" || emojiResult.status === "rejected") {
65-
consola.error({
66-
root: rootResult.status === "rejected" ? rootResult.reason : "ok",
67-
emoji: emojiResult.status === "rejected" ? emojiResult.reason : "ok",
68-
});
69-
70-
throw new Error("failed to fetch root or emoji page");
71-
}
72-
73-
const rootHtml = rootResult.value;
74-
const emojiHtml = emojiResult.value;
75-
76-
const versionRegex = /href="(\d+\.\d+(?:\.\d+)?)\/?"/g;
77-
78-
const draft = await getCurrentDraftVersion();
79-
80-
if (draft == null) {
81-
throw new Error("failed to fetch draft version");
82-
}
83-
84-
const versions: EmojiVersion[] = [];
85-
86-
for (const match of rootHtml.matchAll(versionRegex)) {
87-
if (match == null || match[1] == null) continue;
88-
89-
const version = match[1];
90-
91-
if (!await isEmojiVersionValid(version)) {
92-
continue;
93-
}
94-
95-
if (versions.some((v) => v.unicode_version === version)) {
96-
continue;
97-
}
98-
99-
versions.push({
100-
emoji_version: null,
101-
unicode_version: version,
102-
draft: version === draft.unicode_version || version === draft.emoji_version,
103-
});
104-
}
105-
106-
for (const match of emojiHtml.matchAll(versionRegex)) {
107-
if (match == null || match[1] == null) continue;
108-
109-
let version = match[1];
110-
111-
// for the emoji page, the versions is not valid semver.
112-
// so we will add the last 0 to the version.
113-
// handle both 5.0 and 12.0 -> 5.0.0 and 12.0.0
114-
if (version.length === 3 || version.length === 4) {
115-
version += ".0";
116-
}
117-
118-
if (!await isEmojiVersionValid(version)) {
119-
continue;
120-
}
121-
122-
// check if the unicode_version already exists.
123-
// if it does, we will update the emoji version.
124-
const existing = versions.find((v) => v.unicode_version === version);
125-
126-
let unicode_version = null;
127-
128-
// the emoji version 13.1 is using the unicode
129-
// 13.0, since it was never released.
130-
if (match[1] === "13.1") {
131-
unicode_version = "13.0.0";
132-
}
133-
134-
if (match[1] === "5.0") {
135-
unicode_version = "10.0.0";
136-
}
137-
138-
if (match[1] === "4.0" || match[1] === "3.0") {
139-
unicode_version = "9.0.0";
140-
}
141-
142-
if (match[1] === "2.0" || match[1] === "1.0") {
143-
unicode_version = "8.0.0";
144-
}
145-
146-
if (existing) {
147-
existing.unicode_version = unicode_version || existing.unicode_version;
148-
existing.emoji_version = match[1];
149-
continue;
150-
}
151-
152-
versions.push({
153-
emoji_version: match[1],
154-
unicode_version,
155-
draft: version === draft.unicode_version || version === draft.emoji_version,
156-
});
157-
}
158-
159-
return versions.sort((a, b) => semver.compare(`${b.emoji_version}.0`, `${a.emoji_version}.0`));
160-
}
161-
16231
/**
16332
* Checks if the given emoji version is valid according to Unicode Consortium standards.
16433
*

src/versions.ts

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import type { EmojiVersion } from "./lockfile";
12
import consola from "consola";
23
import semver from "semver";
4+
import { isEmojiVersionValid } from "./utils";
35

46
export interface DraftVersion {
57
emoji_version: string;
@@ -167,3 +169,134 @@ export function extractUnicodeVersion(emojiVersion: string | null, unicodeVersio
167169
return "6.0";
168170
}
169171
}
172+
173+
/**
174+
* Retrieves all available emoji versions from Unicode.org.
175+
* This function fetches both the root Unicode directory and the emoji-specific directory
176+
* to compile a comprehensive list of valid emoji versions.
177+
*
178+
* The function performs the following steps:
179+
* 1. Fetches content from Unicode.org's public directories
180+
* 2. Extracts version numbers using regex
181+
* 3. Validates each version
182+
* 4. Normalizes version numbers to valid semver format
183+
*
184+
* @throws {Error} When either the root or emoji page fetch fails
185+
* @returns {Promise<EmojiVersion[]>} A promise that resolves to an array of emoji versions,
186+
* sorted according to semver rules
187+
*/
188+
export async function getAllEmojiVersions(): Promise<EmojiVersion[]> {
189+
const [rootResult, emojiResult] = await Promise.allSettled([
190+
"https://unicode.org/Public/",
191+
"https://unicode.org/Public/emoji/",
192+
].map(async (url) => {
193+
const res = await fetch(url);
194+
195+
if (!res.ok) {
196+
throw new Error(`failed to fetch ${url}: ${res.statusText}`);
197+
}
198+
199+
return res.text();
200+
}));
201+
202+
if (rootResult == null || emojiResult == null) {
203+
throw new Error("failed to fetch root or emoji page");
204+
}
205+
206+
if (rootResult.status === "rejected" || emojiResult.status === "rejected") {
207+
consola.error({
208+
root: rootResult.status === "rejected" ? rootResult.reason : "ok",
209+
emoji: emojiResult.status === "rejected" ? emojiResult.reason : "ok",
210+
});
211+
212+
throw new Error("failed to fetch root or emoji page");
213+
}
214+
215+
const rootHtml = rootResult.value;
216+
const emojiHtml = emojiResult.value;
217+
218+
const versionRegex = /href="(\d+\.\d+(?:\.\d+)?)\/?"/g;
219+
220+
const draft = await getCurrentDraftVersion();
221+
222+
if (draft == null) {
223+
throw new Error("failed to fetch draft version");
224+
}
225+
226+
const versions: EmojiVersion[] = [];
227+
228+
for (const match of rootHtml.matchAll(versionRegex)) {
229+
if (match == null || match[1] == null) continue;
230+
231+
const version = match[1];
232+
233+
if (!await isEmojiVersionValid(version)) {
234+
continue;
235+
}
236+
237+
if (versions.some((v) => v.unicode_version === version)) {
238+
continue;
239+
}
240+
241+
versions.push({
242+
emoji_version: null,
243+
unicode_version: version,
244+
draft: version === draft.unicode_version || version === draft.emoji_version,
245+
});
246+
}
247+
248+
for (const match of emojiHtml.matchAll(versionRegex)) {
249+
if (match == null || match[1] == null) continue;
250+
251+
let version = match[1];
252+
253+
// for the emoji page, the versions is not valid semver.
254+
// so we will add the last 0 to the version.
255+
// handle both 5.0 and 12.0 -> 5.0.0 and 12.0.0
256+
if (version.length === 3 || version.length === 4) {
257+
version += ".0";
258+
}
259+
260+
if (!await isEmojiVersionValid(version)) {
261+
continue;
262+
}
263+
264+
// check if the unicode_version already exists.
265+
// if it does, we will update the emoji version.
266+
const existing = versions.find((v) => v.unicode_version === version);
267+
268+
let unicode_version = null;
269+
270+
// the emoji version 13.1 is using the unicode
271+
// 13.0, since it was never released.
272+
if (match[1] === "13.1") {
273+
unicode_version = "13.0.0";
274+
}
275+
276+
if (match[1] === "5.0") {
277+
unicode_version = "10.0.0";
278+
}
279+
280+
if (match[1] === "4.0" || match[1] === "3.0") {
281+
unicode_version = "9.0.0";
282+
}
283+
284+
if (match[1] === "2.0" || match[1] === "1.0") {
285+
unicode_version = "8.0.0";
286+
}
287+
288+
if (existing) {
289+
existing.unicode_version = unicode_version || existing.unicode_version;
290+
existing.emoji_version = match[1];
291+
continue;
292+
}
293+
294+
versions.push({
295+
emoji_version: match[1],
296+
unicode_version,
297+
draft: version === draft.unicode_version || version === draft.emoji_version,
298+
});
299+
}
300+
301+
return versions.sort((a, b) => semver.compare(`${b.emoji_version}.0`, `${a.emoji_version}.0`));
302+
}

test/__setup.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { vi } from "vitest";
2+
import createFetchMock from "vitest-fetch-mock";
3+
4+
const fetchMocker = createFetchMock(vi);
5+
6+
fetchMocker.enableMocks();

0 commit comments

Comments
 (0)