1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
import { beforeAll, afterAll, describe, test, expect, mock } from "bun:test";
import { Worker } from "node:worker_threads";
import { JSCClient, type JSC } from "../src/jsc";
let worker: Worker;
beforeAll(async () => {
const { pathname } = new URL("./fixtures/echo.ts", import.meta.url);
worker = new Worker(pathname, { smol: true });
while (true) {
try {
await fetch("http://localhost:9229/");
break;
} catch {}
}
});
afterAll(() => {
worker?.terminate();
});
describe("JSCClient", () => {
const onRequest = mock((request: JSC.Request) => {
expect(request).toBeInstanceOf(Object);
expect(request.id).toBeNumber();
expect(request.method).toBeString();
if (request.params) {
expect(request.params).toBeInstanceOf(Object);
} else {
expect(request).toBeUndefined();
}
});
const onResponse = mock((response: JSC.Response) => {
expect(response).toBeInstanceOf(Object);
expect(response.id).toBeNumber();
if ("result" in response) {
expect(response.result).toBeInstanceOf(Object);
} else {
expect(response.error).toBeInstanceOf(Object);
expect(response.error.message).toBeString();
}
});
const onEvent = mock((event: JSC.Event) => {
expect(event).toBeInstanceOf(Object);
expect(event.method).toBeString();
if (event.params) {
expect(event.params).toBeInstanceOf(Object);
} else {
expect(event).toBeUndefined();
}
});
const onError = mock((error: Error) => {
expect(error).toBeInstanceOf(Error);
});
const client = new JSCClient({
url: "ws://localhost:9229/bun:inspect",
onRequest,
onResponse,
onEvent,
onError,
});
test("can connect", () => {
expect(client.ready).resolves.toBeUndefined();
});
test("can send a request", () => {
expect(client.fetch("Runtime.evaluate", { expression: "1 + 1" })).resolves.toStrictEqual({
result: {
type: "number",
value: 2,
description: "2",
},
wasThrown: false,
});
expect(onRequest).toHaveBeenCalled();
expect(onRequest.mock.lastCall[0]).toStrictEqual({
id: 1,
method: "Runtime.evaluate",
params: { expression: "1 + 1" },
});
expect(onResponse).toHaveBeenCalled();
expect(onResponse.mock.lastCall[0]).toMatchObject({
id: 1,
result: {
result: {
type: "number",
value: 2,
description: "2",
},
wasThrown: false,
},
});
});
test("can send an invalid request", () => {
expect(
client.fetch("Runtime.awaitPromise", {
promiseObjectId: "this-does-not-exist",
}),
).rejects.toMatchObject({
name: "Error",
message: expect.stringMatching(/promiseObjectId/),
});
expect(onRequest).toHaveBeenCalled();
expect(onRequest.mock.lastCall[0]).toStrictEqual({
id: 2,
method: "Runtime.awaitPromise",
params: {
promiseObjectId: "this-does-not-exist",
},
});
expect(onResponse).toHaveBeenCalled();
expect(onResponse.mock.lastCall[0]).toMatchObject({
id: 2,
error: {
code: expect.any(Number),
message: expect.stringMatching(/promiseObjectId/),
},
});
expect(onError).toHaveBeenCalled();
});
test("can disconnect", () => {
expect(() => client.close()).not.toThrow();
});
});
|