1 if (window
.testRunner
) {
2 testRunner
.dumpAsText();
3 testRunner
.waitUntilDone();
6 description("This test checks the various use cases around sending multiple ports through MessagePort.postMessage");
8 var channel
= new MessageChannel();
9 var channel2
= new MessageChannel();
10 var channel3
= new MessageChannel();
11 var channel4
= new MessageChannel();
13 shouldThrow("channel.port1.postMessage()");
15 channel
.port1
.postMessage("noport");
16 channel
.port1
.postMessage("zero ports", []);
17 channel
.port1
.postMessage("two ports", [channel2
.port1
, channel2
.port2
]);
19 // Now test various failure cases
20 shouldThrow('channel.port1.postMessage("same port", [channel.port1])', '"DataCloneError: Failed to execute \'postMessage\' on \'MessagePort\': Port at index 0 contains the source port."');
21 shouldThrow('channel.port1.postMessage("null port", [channel3.port1, null, channel3.port2])', '"TypeError: Failed to execute \'postMessage\' on \'MessagePort\': Value at index 1 is an untransferable \'null\' value."');
22 shouldThrow('channel.port1.postMessage("notAPort", [channel3.port1, {}, channel3.port2])', '"TypeError: Failed to execute \'postMessage\' on \'MessagePort\': Value at index 1 does not have a transferable type."');
23 shouldThrow('channel.port1.postMessage("duplicate port", [channel3.port1, channel3.port1])', '"DataCloneError: Failed to execute \'postMessage\' on \'MessagePort\': Message port at index 1 is a duplicate of an earlier port."');
24 // Should be OK to send channel3.port1 (should not have been disentangled by the previous failed calls).
25 channel
.port1
.postMessage("entangled ports", [channel3
.port1
, channel3
.port2
]);
27 shouldThrow('channel.port1.postMessage("notAnArray", channel3.port1)', '"TypeError: Failed to execute \'postMessage\' on \'MessagePort\': The 2nd argument is neither an array, nor does it have indexed properties."');
28 shouldThrow('channel.port1.postMessage("notASequence", [{length: 3}])', '"TypeError: Failed to execute \'postMessage\' on \'MessagePort\': Value at index 0 does not have a transferable type."');
29 var arrayBuffer
= new ArrayBuffer(2);
30 shouldThrow('channel.port1.postMessage("duplicate buffer", [arrayBuffer, arrayBuffer])', '"DataCloneError: Failed to execute \'postMessage\' on \'MessagePort\': ArrayBuffer at index 1 is a duplicate of an earlier ArrayBuffer."');
32 // Should not crash (we should figure out that the array contains undefined
34 var largePortArray
= [];
35 largePortArray
[1234567890] = channel4
.port1
;
36 shouldThrow('channel.port1.postMessage("largeSequence", largePortArray)', '"TypeError: Failed to execute \'postMessage\' on \'MessagePort\': Value at index 0 is an untransferable \'undefined\' value."');
38 channel
.port1
.postMessage("done");
40 function testTransfers() {
41 var channel0
= new MessageChannel();
43 var c1
= new MessageChannel();
44 channel0
.port1
.postMessage({id
:"send-port", port
:c1
.port1
}, [c1
.port1
]);
45 var c2
= new MessageChannel();
46 channel0
.port1
.postMessage({id
:"send-port-twice", port0
:c2
.port1
, port1
:c2
.port1
}, [c2
.port1
]);
47 var c3
= new MessageChannel();
48 channel0
.port1
.postMessage({id
:"send-two-ports", port0
:c3
.port1
, port1
:c3
.port2
}, [c3
.port1
, c3
.port2
]);
49 var c4
= new MessageChannel();
51 channel0
.port1
.postMessage({id
:"host-object", hostObject
:c3
, port
:c4
.port1
}, [c4
.port1
]);
52 testFailed("Sending host object should throw");
54 if (e
.code
== DOMException
.DATA_CLONE_ERR
)
55 testPassed("Sending host object has thrown " + e
);
57 testFailed("Sending host object should throw a DataCloneError, got: " + e
);
60 channel0
.port1
.postMessage({id
:"host-object2", hostObject
:navigator
, port
:c4
.port1
}, [c4
.port1
]);
61 testFailed("Sending host object should throw");
63 if (e
.code
== DOMException
.DATA_CLONE_ERR
)
64 testPassed("Sending host object has thrown " + e
);
66 testFailed("Sending host object should throw a DataCloneError, got: " + e
);
69 var f1 = function() {}
70 channel0
.port1
.postMessage({id
:"function-object", function:f1
, port
:c4
.port1
}, [c4
.port1
]);
71 testFailed("Sending Function object should throw");
73 if (e
.code
== DOMException
.DATA_CLONE_ERR
)
74 testPassed("Sending Function object has thrown " + e
);
76 testFailed("Sending Function object should throw a DataCloneError, got: " + e
);
79 var err
= new Error();
80 channel0
.port1
.postMessage({id
:"error-object", error
:err
, port
:c4
.port1
}, [c4
.port1
]);
81 testFailed("Sending Error object should throw");
83 if (e
.code
== DOMException
.DATA_CLONE_ERR
)
84 testPassed("Sending Error object has thrown " + e
);
86 testPassed("Sending Error object should throw a DataCloneError, got: " + e
);
88 c4
.port1
.postMessage("Should succeed");
89 channel0
.port1
.postMessage({id
:"done"});
91 channel0
.port2
.onmessage = function(event
) {
92 if (event
.data
.id
== "send-port") {
93 if (event
.ports
&& event
.ports
.length
> 0 && event
.ports
[0] === event
.data
.port
)
94 testPassed("send-port: transferred one port");
96 testFailed("send-port: port transfer failed");
97 } else if (event
.data
.id
== "send-port-twice") {
98 if (event
.ports
&& event
.ports
.length
== 1 &&
99 event
.ports
[0] === event
.data
.port0
&& event
.ports
[0] === event
.data
.port1
)
100 testPassed("send-port-twice: transferred one port twice");
102 testFailed("send-port-twice: failed to transfer one port twice");
103 } else if (event
.data
.id
== "send-two-ports") {
104 if (event
.ports
&& event
.ports
.length
== 2 &&
105 event
.ports
[0] === event
.data
.port0
&& event
.ports
[1] === event
.data
.port1
)
106 testPassed("send-two-ports: transferred two ports");
108 testFailed("send-two-ports: failed to transfer two ports");
109 } else if (event
.data
.id
== "done") {
110 debug('<br><span class="pass">TEST COMPLETE</span>');
111 if (window
.testRunner
)
112 testRunner
.notifyDone();
114 testFailed("Unexpected message " + event
.data
);
119 channel
.port2
.onmessage = function(event
) {
120 if (event
.data
== "noport") {
121 if (event
.ports
&& !event
.ports
.length
)
122 testPassed("event.ports is non-null and zero length when no port sent");
124 testFailed("event.ports is null or non-zero length when no port sent");
125 } else if (event
.data
== "zero ports") {
126 if (event
.ports
&& !event
.ports
.length
)
127 testPassed("event.ports is non-null and zero length when empty array sent");
129 testFailed("event.ports is null or non-zero length when empty array sent");
130 } else if (event
.data
== "two ports") {
132 testFailed("event.ports should be non-null when ports sent");
135 if (event
.ports
.length
== 2)
136 testPassed("event.ports contains two ports when two ports sent");
138 testFailed("event.ports contained " + event
.ports
.length
+ " when two ports sent");
140 } else if (event
.data
== "entangled ports") {
141 if (event
.ports
.length
== 2)
142 testPassed("event.ports contains two ports when two ports re-sent after error");
144 testFailed("event.ports contained " + event
.ports
.length
+ " when two ports re-sent after error");
145 } else if (event
.data
== "done") {
148 testFailed("Received unexpected message: " + event
.data
);