Skip to content

Commit 7afa20a

Browse files
committed
test: upgrade to h3 v2
1 parent 675bde2 commit 7afa20a

File tree

3 files changed

+93
-95
lines changed

3 files changed

+93
-95
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@
8282
"eslint-config-unjs": "^0.5.0",
8383
"fetch-blob": "^4.0.0",
8484
"formdata-polyfill": "^4.0.10",
85-
"h3": "^1.15.4",
85+
"h3": "^2.0.1-rc.5",
8686
"jiti": "^2.6.1",
8787
"listhen": "^1.9.0",
8888
"prettier": "^3.6.2",

pnpm-lock.yaml

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

test/index.test.ts

Lines changed: 64 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,3 @@
1-
import { Readable } from "node:stream";
2-
import { listen } from "listhen";
3-
import { getQuery, joinURL } from "ufo";
4-
import {
5-
createApp,
6-
createError,
7-
eventHandler,
8-
readBody,
9-
readRawBody,
10-
toNodeListener,
11-
} from "h3";
121
import {
132
describe,
143
beforeEach,
@@ -18,81 +7,66 @@ import {
187
expect,
198
vi,
209
} from "vitest";
10+
import { Readable } from "node:stream";
11+
import { H3, HTTPError, readBody, serve } from "h3";
2112
import { Headers, FormData, Blob } from "node-fetch-native";
2213
import { nodeMajorVersion } from "std-env";
2314
import { $fetch } from "../src/node";
2415

2516
describe("ofetch", () => {
26-
let listener;
27-
const getURL = (url) => joinURL(listener.url, url);
17+
let listener: ReturnType<typeof serve>;
18+
const getURL = (url: string = "/") =>
19+
listener.url! + (url.replace(/^\//, "") || "");
2820

2921
const fetch = vi.spyOn(globalThis, "fetch");
3022

3123
beforeAll(async () => {
32-
const app = createApp()
33-
.use(
34-
"/ok",
35-
eventHandler(() => "ok")
36-
)
37-
.use(
38-
"/params",
39-
eventHandler((event) => getQuery(event.node.req.url || ""))
40-
)
41-
.use(
42-
"/url",
43-
eventHandler((event) => event.node.req.url)
44-
)
45-
.use(
46-
"/echo",
47-
eventHandler(async (event) => ({
48-
path: event.path,
49-
body:
50-
event.node.req.method === "POST"
51-
? await readRawBody(event)
52-
: undefined,
53-
headers: event.node.req.headers,
54-
}))
55-
)
56-
.use(
57-
"/post",
58-
eventHandler(async (event) => ({
59-
body: await readBody(event),
60-
headers: event.node.req.headers,
61-
}))
62-
)
63-
.use(
64-
"/binary",
65-
eventHandler((event) => {
66-
event.node.res.setHeader("Content-Type", "application/octet-stream");
67-
return new Blob(["binary"]);
68-
})
69-
)
70-
.use(
24+
const app = new H3({ debug: true })
25+
// .use(async (event) => {
26+
// console.log({
27+
// body: await event.req.clone().text(),
28+
// url: event.url.href,
29+
// headers: event.req.headers,
30+
// });
31+
// })
32+
.all("/ok", () => "ok")
33+
.all("/params", (event) => Object.fromEntries(event.url.searchParams))
34+
.all("/url/**", (event) => event.url.pathname + event.url.search)
35+
.all("/echo", async (event) => ({
36+
path: event.url.pathname + event.url.search,
37+
body: event.req.method === "POST" ? await event.req.text() : undefined,
38+
headers: Object.fromEntries(event.req.headers),
39+
}))
40+
.all("/post", async (event) => ({
41+
body: event.req.headers
42+
.get("content-type")
43+
?.includes("multipart/form-data")
44+
? await event.req.text()
45+
: await readBody(event),
46+
headers: Object.fromEntries(event.req.headers),
47+
}))
48+
.all("/binary", (event) => {
49+
event.res.headers.set("Content-Type", "application/octet-stream");
50+
return new Blob(["binary"]);
51+
})
52+
.all(
7153
"/403",
72-
eventHandler(() =>
73-
createError({ status: 403, statusMessage: "Forbidden" })
74-
)
75-
)
76-
.use(
77-
"/408",
78-
eventHandler(() => createError({ status: 408 }))
54+
() => new HTTPError({ status: 403, statusMessage: "Forbidden" })
7955
)
80-
.use(
56+
.all("/408", () => new HTTPError({ status: 408 }))
57+
.all(
8158
"/204",
82-
eventHandler(() => null) // eslint-disable-line unicorn/no-null
59+
() => null // eslint-disable-line unicorn/no-null
8360
)
84-
.use(
85-
"/timeout",
86-
eventHandler(async () => {
87-
await new Promise((resolve) => {
88-
setTimeout(() => {
89-
resolve(createError({ status: 408 }));
90-
}, 1000 * 5);
91-
});
92-
})
93-
);
61+
.all("/timeout", async () => {
62+
await new Promise((resolve) => {
63+
setTimeout(() => {
64+
resolve(new HTTPError({ status: 408 }));
65+
}, 1000 * 5);
66+
});
67+
});
9468

95-
listener = await listen(toNodeListener(app));
69+
listener = await serve(app, { port: 0, hostname: "localhost" }).ready();
9670
});
9771

9872
afterAll(() => {
@@ -109,7 +83,7 @@ describe("ofetch", () => {
10983

11084
it("custom parseResponse", async () => {
11185
let called = 0;
112-
const parser = (r) => {
86+
const parser = (r: any) => {
11387
called++;
11488
return "C" + r;
11589
};
@@ -128,7 +102,7 @@ describe("ofetch", () => {
128102
).to.be.instanceOf(Blob);
129103
expect(
130104
await $fetch(getURL("params?test=true"), { responseType: "text" })
131-
).to.equal('{"test":"true"}');
105+
).to.equal('{\n "test": "true"\n}');
132106
expect(
133107
await $fetch(getURL("params?test=true"), { responseType: "arrayBuffer" })
134108
).to.be.instanceOf(ArrayBuffer);
@@ -140,7 +114,7 @@ describe("ofetch", () => {
140114

141115
it("baseURL", async () => {
142116
expect(await $fetch("/x?foo=123", { baseURL: getURL("url") })).to.equal(
143-
"/x?foo=123"
117+
"/url/x?foo=123"
144118
);
145119
});
146120

@@ -162,15 +136,12 @@ describe("ofetch", () => {
162136
let body3;
163137
await $fetch(getURL("post"), {
164138
method: "POST",
165-
headers: {
166-
"Content-Type": "application/x-www-form-urlencoded",
167-
},
168139
body: { num: 42 },
169140
onResponse(ctx) {
170141
body3 = ctx.options.body;
171142
},
172143
});
173-
expect(body3).equals("num=42");
144+
expect(JSON.parse(body3! as string)).toMatchObject({ num: 42 });
174145

175146
const headerFetches = [
176147
[["X-header", "1"]],
@@ -267,25 +238,26 @@ describe("ofetch", () => {
267238

268239
it("404", async () => {
269240
const error = await $fetch(getURL("404")).catch((error_) => error_);
270-
expect(error.toString()).to.contain("Cannot find any path matching /404.");
271-
expect(error.data).to.deep.eq({
272-
stack: [],
273-
statusCode: 404,
274-
statusMessage: "Cannot find any path matching /404.",
241+
expect(error.toString()).toBe(
242+
`FetchError: [GET] "${getURL("404")}": 404 Not Found`
243+
);
244+
expect(error.data).toMatchObject({
245+
status: 404,
246+
message: expect.stringContaining("Cannot find any route matching"),
275247
});
276248
expect(error.response?._data).to.deep.eq(error.data);
277249
expect(error.request).to.equal(getURL("404"));
278250
});
279251

280252
it("403 with ignoreResponseError", async () => {
281253
const res = await $fetch(getURL("403"), { ignoreResponseError: true });
282-
expect(res?.statusCode).to.eq(403);
283-
expect(res?.statusMessage).to.eq("Forbidden");
254+
expect(res?.status).to.eq(403);
255+
expect(res?.message).to.eq("Forbidden");
284256
});
285257

286258
it("204 no content", async () => {
287259
const res = await $fetch(getURL("204"));
288-
expect(res).toBeUndefined();
260+
expect(res).toBe("");
289261
});
290262

291263
it("HEAD no content", async () => {
@@ -328,7 +300,7 @@ describe("ofetch", () => {
328300
expect(race).to.equal("fast");
329301
});
330302

331-
it("abort with retry", () => {
303+
it("abort with retry", async () => {
332304
const controller = new AbortController();
333305
async function abortHandle() {
334306
controller.abort();
@@ -339,15 +311,15 @@ describe("ofetch", () => {
339311
});
340312
console.log("response", response);
341313
}
342-
expect(abortHandle()).rejects.toThrow(/aborted/);
314+
await expect(abortHandle()).rejects.toThrow(/aborted/);
343315
});
344316

345317
it("passing request obj should return request obj in error", async () => {
346318
const error = await $fetch(getURL("/403"), { method: "post" }).catch(
347319
(error) => error
348320
);
349321
expect(error.toString()).toBe(
350-
'FetchError: [POST] "http://localhost:3000/403": 403 Forbidden'
322+
`FetchError: [POST] "${getURL("403")}": 403 Forbidden`
351323
);
352324
expect(error.request).to.equal(getURL("403"));
353325
expect(error.options.method).to.equal("POST");
@@ -411,8 +383,8 @@ describe("ofetch", () => {
411383
});
412384

413385
const parseParams = (str: string) =>
414-
Object.fromEntries(new URLSearchParams(str).entries());
415-
expect(parseParams(path)).toMatchObject(parseParams("?b=2&c=3&a=1"));
386+
Object.fromEntries(new URL(str, "http://_").searchParams.entries());
387+
expect(parseParams(path)).toMatchObject({ a: "1", b: "2", c: "3" });
416388
});
417389

418390
it("uses request headers", async () => {

0 commit comments

Comments
 (0)