aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorGravatar Dylan Conway <35280289+dylan-conway@users.noreply.github.com> 2023-08-01 18:40:02 -0700
committerGravatar GitHub <noreply@github.com> 2023-08-01 18:40:02 -0700
commit6c40d6f2f51474c6a38d509417db903385f48f2b (patch)
treed441b10de162e443d572b47ca9c278e3cd345f26 /test
parent0ced5520e6ae8061b2acaab2cbc26431e10182a6 (diff)
downloadbun-6c40d6f2f51474c6a38d509417db903385f48f2b.tar.gz
bun-6c40d6f2f51474c6a38d509417db903385f48f2b.tar.zst
bun-6c40d6f2f51474c6a38d509417db903385f48f2b.zip
add `BroadcastChannel` (#3922)
* copy and format * update `SerializedScriptValue.cpp` * use `expect().fail()` in message channel tests * rename `BroadcastChannelIdentifier.h` * copy registries * progress and tests * cleanup * worker and broadcast channel test * `BroadcastChannel` ref and unref * `MessagePort` ref, unref, and hasRef * remove `SecurityContext.cpp/h` * add types
Diffstat (limited to 'test')
-rw-r--r--test/js/web/broadcastchannel/broadcast-channel-worker.ts3
-rw-r--r--test/js/web/broadcastchannel/broadcast-channel.test.ts153
-rw-r--r--test/js/web/workers/message-channel.test.ts24
3 files changed, 166 insertions, 14 deletions
diff --git a/test/js/web/broadcastchannel/broadcast-channel-worker.ts b/test/js/web/broadcastchannel/broadcast-channel-worker.ts
new file mode 100644
index 000000000..12f32dbe8
--- /dev/null
+++ b/test/js/web/broadcastchannel/broadcast-channel-worker.ts
@@ -0,0 +1,3 @@
+const bc = new BroadcastChannel("hello test");
+bc.postMessage("hello from worker");
+bc.close();
diff --git a/test/js/web/broadcastchannel/broadcast-channel.test.ts b/test/js/web/broadcastchannel/broadcast-channel.test.ts
new file mode 100644
index 000000000..b60bbb18b
--- /dev/null
+++ b/test/js/web/broadcastchannel/broadcast-channel.test.ts
@@ -0,0 +1,153 @@
+test("postMessage results in correct event", done => {
+ let c1 = new BroadcastChannel("eventType");
+ let c2 = new BroadcastChannel("eventType");
+
+ c2.onmessage = (e: MessageEvent) => {
+ expect(e).toBeInstanceOf(MessageEvent);
+ expect(e.target).toBe(c2);
+ expect(e.type).toBe("message");
+ expect(e.origin).toBe("");
+ expect(e.data).toBe("hello world");
+ expect(e.source).toBe(null);
+ done();
+ };
+
+ c1.postMessage("hello world");
+});
+
+test("broadcast channel properties", () => {
+ let c1 = new BroadcastChannel("props");
+ expect(c1.name).toBe("props");
+ expect(c1.onmessage).toBe(null);
+ expect(c1.onmessageerror).toBe(null);
+ expect(c1.close).toBeInstanceOf(Function);
+ expect(c1.postMessage).toBeInstanceOf(Function);
+ expect(c1.ref).toBeInstanceOf(Function);
+ expect(c1.unref).toBeInstanceOf(Function);
+});
+
+test("messages are delivered in port creation order", done => {
+ let c1 = new BroadcastChannel("order");
+ let c2 = new BroadcastChannel("order");
+ let c3 = new BroadcastChannel("order");
+
+ let events: MessageEvent[] = [];
+ let doneCount = 0;
+ let handler = (e: MessageEvent) => {
+ events.push(e);
+ if (e.data == "done") {
+ doneCount++;
+ if (doneCount == 2) {
+ expect(events.length).toBe(6);
+ expect(events[0].target).toBe(c2);
+ expect(events[0].data).toBe("from c1");
+ expect(events[1].target).toBe(c3);
+ expect(events[1].data).toBe("from c1");
+ expect(events[2].target).toBe(c1);
+ expect(events[2].data).toBe("from c3");
+ expect(events[3].target).toBe(c2);
+ expect(events[3].data).toBe("from c3");
+ expect(events[4].target).toBe(c1);
+ expect(events[4].data).toBe("done");
+ expect(events[5].target).toBe(c3);
+ expect(events[5].data).toBe("done");
+ done();
+ }
+ }
+ };
+
+ c1.onmessage = handler;
+ c2.onmessage = handler;
+ c3.onmessage = handler;
+
+ c1.postMessage("from c1");
+ c3.postMessage("from c3");
+ c2.postMessage("done");
+});
+
+test("messages aren't deliverd to a closed port.", done => {
+ let c1 = new BroadcastChannel("closed");
+ let c2 = new BroadcastChannel("closed");
+ let c3 = new BroadcastChannel("closed");
+
+ c2.onmessage = () => {
+ expect().fail();
+ };
+ c2.close();
+ c3.onmessage = () => {
+ done();
+ };
+ c1.postMessage("test");
+});
+
+test("messages aren't delivered to a port closed after calling postMessage.", done => {
+ let c1 = new BroadcastChannel("closed");
+ let c2 = new BroadcastChannel("closed");
+ let c3 = new BroadcastChannel("closed");
+
+ c2.onmessage = () => expect().fail();
+ c3.onmessage = () => done();
+ c1.postMessage("test");
+ c2.close();
+});
+
+test("closing and creating channels during message delivery works correctly.", done => {
+ let c1 = new BroadcastChannel("create-in-onmessage");
+ let c2 = new BroadcastChannel("create-in-onmessage");
+
+ c2.onmessage = (e: MessageEvent) => {
+ expect(e.data).toBe("first");
+ c2.close();
+ let c3 = new BroadcastChannel("create-in-onmessage");
+ c3.onmessage = (event: MessageEvent) => {
+ expect(event.data).toBe("done");
+ done();
+ };
+ c1.postMessage("done");
+ };
+ c1.postMessage("first");
+ c2.postMessage("second");
+});
+
+test("Closing a channel in onmessage prevents already queued tasks from firing onmessage events", done => {
+ let c1 = new BroadcastChannel("close-in-onmessage");
+ let c2 = new BroadcastChannel("close-in-onmessage");
+ let c3 = new BroadcastChannel("close-in-onmessage");
+
+ let events: string[] = [];
+ c1.onmessage = (e: MessageEvent) => events.push("c1: " + e.data);
+ c2.onmessage = (e: MessageEvent) => events.push("c2: " + e.data);
+ c3.onmessage = (e: MessageEvent) => events.push("c3: " + e.data);
+
+ // c2 closes itself when it receives the first message
+ c2.addEventListener("message", (e: MessageEvent) => {
+ c2.close();
+ });
+
+ c3.addEventListener("message", (e: MessageEvent) => {
+ if (e.data == "done") {
+ expect(events).toEqual(["c2: first", "c3: first", "c3: done"]);
+ done();
+ }
+ });
+ c1.postMessage("first");
+ c1.postMessage("done");
+});
+
+test("broadcast channel used with workers", done => {
+ var bc = new BroadcastChannel("hello test");
+ var count = 0;
+ var workersCount = 100;
+ bc.onmessage = (e: MessageEvent) => {
+ expect(e).toBeInstanceOf(MessageEvent);
+ expect(e.target).toBe(bc);
+ expect(e.data).toBe("hello from worker");
+ if (++count == workersCount) {
+ bc.close();
+ done();
+ }
+ };
+ for (var i = 0; i < workersCount; i++) {
+ new Worker(new URL("./broadcast-channel-worker.ts", import.meta.url).href);
+ }
+});
diff --git a/test/js/web/workers/message-channel.test.ts b/test/js/web/workers/message-channel.test.ts
index 40c74e097..e0e318172 100644
--- a/test/js/web/workers/message-channel.test.ts
+++ b/test/js/web/workers/message-channel.test.ts
@@ -46,8 +46,7 @@ test("tranfer array buffer", done => {
test("non-transferable", () => {
var channel = new MessageChannel();
channel.port2.onmessage = function (e) {
- // not reached
- expect(1).toBe(2);
+ expect().fail("should not be reached");
};
expect(() => {
channel.port1.postMessage("hello", [channel.port1]);
@@ -87,8 +86,7 @@ test("transfer message ports and post messages", done => {
};
c2.port2.onmessage = e => {
- // should not be reached. onmessage defined in c1.port1 should be called instead
- expect(1).toBe(2);
+ expect().fail("onmessage defined on c1.port1 should be called instead");
};
c1.port2.postMessage("hello from channel 1 port 2", [c2.port2]);
@@ -97,7 +95,7 @@ test("transfer message ports and post messages", done => {
test("message channel created on main thread", done => {
var worker = new Worker(new URL("receive-port-worker.js", import.meta.url).href);
worker.onerror = e => {
- expect(1).toBe(2);
+ expect().fail();
done();
};
var channel = new MessageChannel();
@@ -112,7 +110,7 @@ test("message channel created on main thread", done => {
test("message channel created on other thread", done => {
var worker = new Worker(new URL("create-port-worker.js", import.meta.url).href);
worker.onerror = e => {
- expect(1).toBe(2);
+ expect().fail();
done();
};
worker.onmessage = e => {
@@ -202,10 +200,10 @@ test("many message channels", done => {
}).toThrow();
// Sending Error object should not throw
- // expect(() => {
- // var err = new Error();
- // channel0.port1.postMessage({ id: "error-object", error: err, port: c4.port1 }, [c4.port1]);
- // }).not.toThrow();
+ expect(() => {
+ var err = new Error();
+ channel0.port1.postMessage({ id: "error-object", error: err, port: c4.port1 }, [c4.port1]);
+ }).not.toThrow();
c4.port1.postMessage("Should succeed");
channel0.port1.postMessage({ id: "done" });
@@ -229,8 +227,7 @@ test("many message channels", done => {
} else if (event.data.id == "done") {
done();
} else {
- // should not be reached
- expect(1).toBe(2);
+ expect().fail("branch should not be reached");
}
};
}
@@ -251,8 +248,7 @@ test("many message channels", done => {
} else if (event.data == "done") {
testTransfers(done);
} else {
- // should not be reached
- expect(1).toBe(2);
+ expect().fail("branch should not be reached");
}
};
});