sku-pg
Version:
Skulpt is a Javascript implementation of Python 2.x. Python that runs in your browser!
296 lines (233 loc) • 8.59 kB
HTML
<html>
<!--
Copyright 2012 The Closure Library Authors. All Rights Reserved.
Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
-->
<!--
-->
<head>
<meta http-equiv="X-IframePollingTransport-Compatible" content="IE=edge">
<title>NativeMessagingTransport Unit-Tests</title>
<script src="../../base.js"></script>
<script>
goog.require('goog.Timer');
goog.require('goog.dom');
goog.require('goog.dom.TagName');
goog.require('goog.functions');
goog.require('goog.net.xpc');
goog.require('goog.net.xpc.CrossPageChannel');
goog.require('goog.net.xpc.CrossPageChannelRole');
goog.require('goog.object');
goog.require('goog.testing.MockClock');
goog.require('goog.testing.jsunit');
goog.require('goog.testing.recordFunction');
</script>
<script>
var mockClock = null;
var outerChannel = null;
var innerChannel = null;
function setUp() {
mockClock = new goog.testing.MockClock(true /* opt_autoInstall */);
// Create the peer windows.
var outerPeerHostName = 'https://www.youtube.com';
var outerPeerWindow = createMockPeerWindow(outerPeerHostName);
var innerPeerHostName = 'https://www.google.com';
var innerPeerWindow = createMockPeerWindow(innerPeerHostName);
// Create the channels.
outerChannel = createChannel(goog.net.xpc.CrossPageChannelRole.OUTER, 'test',
outerPeerHostName, outerPeerWindow, innerPeerHostName, innerPeerWindow);
innerChannel = createChannel(goog.net.xpc.CrossPageChannelRole.INNER, 'test',
innerPeerHostName, innerPeerWindow, outerPeerHostName, outerPeerWindow);
};
function tearDown() {
outerChannel.dispose();
innerChannel.dispose();
mockClock.uninstall();
};
/** Tests that connection happens normally and callbacks are invoked. */
function testConnect() {
var outerConnectCallback = goog.testing.recordFunction();
var innerConnectCallback = goog.testing.recordFunction();
// Connect the two channels.
outerChannel.connect(outerConnectCallback);
innerChannel.connect(innerConnectCallback);
mockClock.tick(1000);
// Check that channels were connected and callbacks invoked.
assertEquals(1, outerConnectCallback.getCallCount());
assertEquals(1, innerConnectCallback.getCallCount());
assertTrue(outerChannel.isConnected());
assertTrue(innerChannel.isConnected());
};
/** Tests that messages are successfully delivered to the inner peer. */
function testSend_outerToInner() {
var serviceCallback = goog.testing.recordFunction();
// Register a service handler in the inner channel.
innerChannel.registerService('svc', function(payload) {
assertEquals('hello', payload);
serviceCallback();
});
// Connect the two channels.
outerChannel.connect();
innerChannel.connect();
mockClock.tick(1000);
// Send a message.
outerChannel.send('svc', 'hello');
mockClock.tick(1000);
// Check that the message was handled.
assertEquals(1, serviceCallback.getCallCount());
};
/** Tests that messages are successfully delivered to the outer peer. */
function testSend_innerToOuter() {
var serviceCallback = goog.testing.recordFunction();
// Register a service handler in the inner channel.
outerChannel.registerService('svc', function(payload) {
assertEquals('hello', payload);
serviceCallback();
});
// Connect the two channels.
outerChannel.connect();
innerChannel.connect();
mockClock.tick(1000);
// Send a message.
innerChannel.send('svc', 'hello');
mockClock.tick(1000);
// Check that the message was handled.
assertEquals(1, serviceCallback.getCallCount());
};
/** Tests that closing the outer peer does not cause an error. */
function testSend_outerPeerClosed() {
// Connect the inner channel.
innerChannel.connect();
mockClock.tick(1000);
// Close the outer peer before it has a chance to connect.
closeWindow(innerChannel.getPeerWindowObject());
// Allow timers to execute (and fail).
mockClock.tick(1000);
};
/** Tests that closing the inner peer does not cause an error. */
function testSend_innerPeerClosed() {
// Connect the outer channel.
outerChannel.connect();
mockClock.tick(1000);
// Close the inner peer before it has a chance to connect.
closeWindow(outerChannel.getPeerWindowObject());
// Allow timers to execute (and fail).
mockClock.tick(1000);
};
/** Tests that partially closing the outer peer does not cause an error. */
function testSend_outerPeerClosing() {
// Connect the inner channel.
innerChannel.connect();
mockClock.tick(1000);
// Close the outer peer before it has a chance to connect, but
// leave closed set to false to simulate a partially closed window.
closeWindow(innerChannel.getPeerWindowObject());
innerChannel.getPeerWindowObject().closed = false;
// Allow timers to execute (and fail).
mockClock.tick(1000);
};
/** Tests that partially closing the inner peer does not cause an error. */
function testSend_innerPeerClosing() {
// Connect the outer channel.
outerChannel.connect();
mockClock.tick(1000);
// Close the inner peer before it has a chance to connect, but
// leave closed set to false to simulate a partially closed window.
closeWindow(outerChannel.getPeerWindowObject());
outerChannel.getPeerWindowObject().closed = false;
// Allow timers to execute (and fail).
mockClock.tick(1000);
};
/**
* Creates a channel with the specified configuration, using frame polling.
* @param {!goog.net.xpc.CrossPageChannelRole} role The channel role.
* @param {string} channelName The channel name.
* @param {string} fromHostName The host name of the window hosting the channel.
* @param {!Object} fromWindow The window hosting the channel.
* @param {string} toHostName The host name of the peer window.
* @param {!Object} toWindow The peer window.
*/
function createChannel(role, channelName, fromHostName, fromWindow, toHostName,
toWindow) {
// Build a channel config using frame polling.
var channelConfig = goog.object.create(
goog.net.xpc.CfgFields.ROLE,
role,
goog.net.xpc.CfgFields.PEER_HOSTNAME,
toHostName,
goog.net.xpc.CfgFields.CHANNEL_NAME,
channelName,
goog.net.xpc.CfgFields.LOCAL_POLL_URI,
fromHostName + '/robots.txt',
goog.net.xpc.CfgFields.PEER_POLL_URI,
toHostName + '/robots.txt',
goog.net.xpc.CfgFields.TRANSPORT,
goog.net.xpc.TransportTypes.IFRAME_POLLING);
// Build the channel.
var channel = new goog.net.xpc.CrossPageChannel(channelConfig);
channel.setPeerWindowObject(toWindow);
// Update the transport's getWindow, to return the correct host window.
channel.createTransport_();
channel.transport_.getWindow = goog.functions.constant(fromWindow);
return channel;
};
/**
* Creates a mock window to use as a peer. The peer window will host the frame
* elements.
* @param {string} url The peer window's initial URL.
*/
function createMockPeerWindow(url) {
var mockPeer = createMockWindow(url);
// Update the appendChild method to use a mock frame window.
mockPeer.document.body.appendChild = function(el) {
assertEquals(goog.dom.TagName.IFRAME, el.tagName);
mockPeer.frames[el.name] = createMockWindow(el.src);
mockPeer.document.body.element.appendChild(el);
};
return mockPeer;
};
/**
* Creates a mock window.
* @param {string} url The window's initial URL.
*/
function createMockWindow(url) {
// Create the mock window, document and body.
var mockWindow = {};
var mockDocument = {};
var mockBody = {};
var mockLocation = {};
// Configure the mock window's document body.
mockBody.element = goog.dom.createDom(goog.dom.TagName.BODY);
// Configure the mock window's document.
mockDocument.body = mockBody;
// Configure the mock window's location.
mockLocation.href = url;
mockLocation.replace = function(value) { mockLocation.href = value; }
// Configure the mock window.
mockWindow.document = mockDocument;
mockWindow.frames = {};
mockWindow.location = mockLocation;
mockWindow.setTimeout = goog.Timer.callOnce;
return mockWindow;
};
/**
* Emulates closing the specified window by clearing frames, document and
* location.
*/
function closeWindow(targetWindow) {
// Close any child frame windows.
for (var frameName in targetWindow.frames) {
closeWindow(targetWindow.frames[frameName]);
}
// Clear the target window, set closed to true.
targetWindow.closed = true;
targetWindow.frames = null;
targetWindow.document = null;
targetWindow.location = null;
};
</script>
</head>
<body></body>
</html>