aboutsummaryrefslogtreecommitdiff
path: root/packages/bun-vscode/test/jsc.test.ts
blob: fa9158aa2ded3c3e119afc7f0732d19eb965a47d (plain) (blame)
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();
  });
});