Skip to content

Commit bd24bc9

Browse files
committed
Transport tests
1 parent 6076e5a commit bd24bc9

File tree

1 file changed

+142
-2
lines changed

1 file changed

+142
-2
lines changed

test/transport.test.ts

Lines changed: 142 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,20 @@
22

33
import type { MockedObject } from "vitest";
44
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
5+
import type { AbstractTransport } from "../src/core/Transport.js";
56
import {
67
NativeWebSocketTransport,
78
WebSocketTransportFactory,
89
WsWebSocketTransport,
910
} from "../src/core/Transport.js";
1011
import * as ws from "ws";
11-
import type { RosbridgeMessage } from "../src/types/protocol.js";
12+
import type {
13+
RosbridgeMessage,
14+
RosbridgePngMessage,
15+
} from "../src/types/protocol.js";
16+
import pngparse from "pngparse";
17+
18+
vi.mock("pngparse");
1219

1320
describe("Transport", () => {
1421
afterEach(() => {
@@ -17,7 +24,140 @@ describe("Transport", () => {
1724
});
1825

1926
describe("AbstractTransport", () => {
20-
it.todo("todo");
27+
let mockPngParseModule: MockedObject<typeof pngparse>;
28+
let mockSocket: MockedObject<WebSocket>;
29+
let transport: AbstractTransport;
30+
31+
beforeEach(() => {
32+
// So that the nodejs decompress png util is used, not the browser one
33+
vi.stubGlobal("window", undefined);
34+
35+
mockPngParseModule = vi.mocked(pngparse);
36+
37+
mockSocket = {
38+
send: vi.fn(),
39+
close: vi.fn(),
40+
readyState: WebSocket.OPEN,
41+
onopen: null,
42+
onclose: null,
43+
onerror: null,
44+
onmessage: null,
45+
} as unknown as MockedObject<WebSocket>;
46+
47+
transport = new NativeWebSocketTransport(mockSocket);
48+
});
49+
50+
it("should handle RosbridgeMessage", () => {
51+
const messageListener = vi.fn();
52+
53+
transport.on("message", messageListener);
54+
55+
const message: RosbridgeMessage = {
56+
op: "test",
57+
};
58+
59+
const messageEvent: Partial<MessageEvent> = {
60+
type: "message",
61+
data: JSON.stringify(message),
62+
};
63+
64+
mockSocket.onmessage?.(messageEvent as MessageEvent);
65+
66+
expect(messageListener).toHaveBeenCalledWith(message);
67+
});
68+
69+
it("should handle RosbridgeFragmentMessage", () => {
70+
// TODO
71+
});
72+
73+
it("should handle RosbridgePngMessage", async () => {
74+
mockPngParseModule.parse.mockImplementation(
75+
(
76+
// Normally, this is the compressed PNG data.
77+
// For our tests, it's a string buffer of "success" or "failure".
78+
data: Buffer,
79+
cb: (error?: Error, data?: pngparse.ImageData) => void,
80+
) => {
81+
const decodedImage: pngparse.ImageData = {
82+
width: 100,
83+
height: 100,
84+
channels: 1,
85+
data: Buffer.from(JSON.stringify({ op: "test" })),
86+
trailer: Buffer.from(""),
87+
};
88+
switch (data.toString()) {
89+
case "success":
90+
cb(undefined, decodedImage);
91+
break;
92+
case "failure":
93+
cb(new Error("test"), undefined);
94+
break;
95+
}
96+
},
97+
);
98+
99+
const messageListener = vi.fn();
100+
const errorListener = vi.fn();
101+
102+
transport.on("message", messageListener);
103+
transport.on("error", errorListener);
104+
105+
// Obviously these are not real PNG encoded messages.
106+
// But they're good enough for mocking responses in our tests.
107+
const successMessage: RosbridgePngMessage = {
108+
op: "png",
109+
data: Buffer.from("success").toString("base64"),
110+
};
111+
112+
const failureMessage: RosbridgePngMessage = {
113+
op: "png",
114+
data: Buffer.from("failure").toString("base64"),
115+
};
116+
117+
// -- SUCCESS -- //
118+
119+
mockSocket.onmessage?.({
120+
type: "message",
121+
data: JSON.stringify(successMessage),
122+
} as MessageEvent);
123+
124+
// Wait for the message to be processed.
125+
// PNG decompression occurs asynchronously.
126+
await vi.waitFor(() => {
127+
expect(errorListener).not.toHaveBeenCalled();
128+
expect(messageListener).toHaveBeenCalledWith({ op: "test" });
129+
}, 500);
130+
131+
vi.clearAllMocks();
132+
133+
// -- FAILURE -- //
134+
135+
mockSocket.onmessage?.({
136+
type: "message",
137+
data: JSON.stringify(failureMessage),
138+
} as MessageEvent);
139+
140+
// Wait for the message to be processed.
141+
// PNG decompression occurs asynchronously.
142+
await vi.waitFor(() => {
143+
expect(errorListener).toHaveBeenCalledWith(
144+
new Error("Cannot process PNG encoded message: test"),
145+
);
146+
expect(messageListener).not.toHaveBeenCalled();
147+
}, 500);
148+
});
149+
150+
it("should handle BSON message", () => {
151+
// TODO
152+
});
153+
154+
it("should handle CBOR message", () => {
155+
// TODO
156+
});
157+
158+
it("should handle JSON message", () => {
159+
// TODO
160+
});
21161
});
22162

23163
describe("NativeWebSocketTransport", () => {

0 commit comments

Comments
 (0)