blob: fc7d7afb81106a2ad0e943241fb719ed47f519b4 [file] [log] [blame]
<html>
<head>
<script src="../../resources/js-test.js"></script>
</head>
<body>
<script>
description("Tests various use cases when cloning MessagePorts.");
window.jsTestIsAsync = true;
var channel = new MessageChannel;
channel.port1.onmessage = channel.port2.onmessage = function(evt) {
testFailed("Should not have received message: " + evt.data);
}
// Posting port to itself should throw an exception.
shouldThrow("channel.port1.postMessage('msg', [channel.port1])", '"DataCloneError: Failed to execute \'postMessage\' on \'MessagePort\': Port at index 0 contains the source port."');
debug("Posting port to entangled pair neuters the port and does nothing else:");
channel = new MessageChannel;
var channel2 = new MessageChannel;
channel.port1.postMessage("msg", [channel.port2]);
shouldThrow("channel2.port1.postMessage('msg', [channel.port2])", '"DataCloneError: Failed to execute \'postMessage\' on \'MessagePort\': Port at index 0 is already neutered."');
channel = new MessageChannel;
channel2 = new MessageChannel
channel.port1.postMessage("msg", [channel2.port1]);
debug("Posting a detached ArrayBuffer should throw.");
channel = new MessageChannel;
var arrayBuffer = new ArrayBuffer(2);
channel.port1.postMessage("msg", [arrayBuffer]);
shouldThrow("channel.port1.postMessage(arrayBuffer, [])", '"DataCloneError: Failed to execute \'postMessage\' on \'MessagePort\': An ArrayBuffer is detached and could not be cloned."');
debug("Posting a detached ArrayBufferView should throw.");
channel = new MessageChannel;
var uint16Array = new Uint16Array(10);
shouldThrow("channel.port1.postMessage('msg', [uint16Array])", '"TypeError: Failed to execute \'postMessage\' on \'MessagePort\': Value at index 0 does not have a transferable type."');
channel.port1.postMessage("msg", [uint16Array.buffer]);
shouldThrow("channel.port1.postMessage(uint16Array, [])", '"DataCloneError: Failed to execute \'postMessage\' on \'MessagePort\': An ArrayBuffer is detached and could not be cloned."');
// Should not be able to post a cloned port.
shouldThrow("channel.port1.postMessage('msg', [channel2.port1])", '"DataCloneError: Failed to execute \'postMessage\' on \'MessagePort\': Port at index 0 is already neutered."');
// Test posting messages to a port in cloned state.
var channel = new MessageChannel;
var channel2 = new MessageChannel;
// Post messages before and after clone to make sure ordering is preserved and all messages are received.
channel2.port2.postMessage("1");
channel.port1.postMessage("msg", [channel2.port1]);
channel2.port2.postMessage("2");
channel2.port2.postMessage("3");
var testEvent;
var messageIndex = 1;
channel.port2.onmessage = function(evt) {
testEvent = evt;
shouldBe("testEvent.ports.length", "1");
evt.ports[0].onmessage = function(evt) {
testEvent = evt;
shouldBe("parseInt(testEvent.data)", "" + messageIndex);
messageIndex++;
if (messageIndex == 4) {
testPassed("Posted messages to cloned port.");
testDoublyClonedPort();
}
}
}
function testDoublyClonedPort()
{
var channel = new MessageChannel;
var channel2 = new MessageChannel;
channel.port1.postMessage("msg", [channel2.port1]);
channel.port2.postMessage("msg", [channel2.port2]);
gc();
channel.port1.onmessage = function(evt) {
evt.ports[0].postMessage("testme");
}
channel.port2.onmessage = function(evt) {
evt.ports[0].onmessage = function (evt) {
testEvent = evt;
shouldBe("testEvent.data", "'testme'");
testPostClosePort();
}
}
}
// *Should* be able to post a closed port.
function testPostClosePort()
{
var channel = new MessageChannel;
var channel2 = new MessageChannel;
channel2.port2.close();
channel.port1.postMessage("closed", [channel2.port2]);
channel.port2.onmessage = function(evt) {
testEvent = evt;
shouldNotBe("testEvent.ports", "null");
shouldBe("testEvent.ports.length", "1");
shouldBe("testEvent.data", "'closed'");
finishJSTest();
}
}
</script>
</body>
</html>