Commit 09d947a9 authored by dpapad's avatar dpapad Committed by Commit bot

WebUI: Replacing cr.sendWithCallback with cr.sendWithPromise.

BUG=580633

Review URL: https://codereview.chromium.org/1622663002

Cr-Commit-Position: refs/heads/master@{#371448}
parent 551228a5
......@@ -124,8 +124,9 @@ Polymer({
/** @override */
attached: function() {
// Query the initial state.
cr.sendWithCallback('getResetThemeEnabled', undefined,
this.setResetThemeEnabled.bind(this));
cr.sendWithPromise('getResetThemeEnabled').then(function(response) {
this.setResetThemeEnabled(response[0]);
}.bind(this));
// Set up the change event listener.
cr.addWebUIListener('reset-theme-enabled-changed',
......
......@@ -1001,6 +1001,7 @@
'test/data/webui/settings/settings_page_browsertest.js',
'test/data/webui/settings/settings_passwords_section_browsertest.js',
'test/data/webui/settings/settings_subpage_browsertest.js',
'test/data/webui/webui_resource_async_browsertest.js',
],
# TODO(rockot) bug 505926: These should be moved to a target in
# //extensions but have old dependencies on chrome files. The chrome
......
......@@ -243,7 +243,7 @@ function testAddSingletonGetter() {
assertEquals('object', typeof z, 'Should work after clearing for testing');
assertNotEqual(null, z, 'Created object should not be null');
assertNotEqual(x, z,
assertNotEqual(x, z,
'Should return a different object after clearing for testing');
}
......@@ -264,70 +264,7 @@ function testDefineWithGetter() {
}
/**
* Executes a function given a potentially namespaced function name, e.g.,
* cr.webUIListenerCallback.
* @param {string} functionName The name of the function, including any
* namespaces, to execute.
*/
function executeFunctionByName(functionName) {
var args = Array.prototype.slice.call(arguments, 1);
var func = (0, eval)(functionName);
func.apply(undefined, args);
}
/**
* Tests that cr.sendWithCallback correctly handles the case where the JS sends
* no arguments to the WebUI handler.
*/
function testSendWithCallback_PassesJSArgs() {
var testMethodName = 'getFullscreenState';
// Mock out chrome.send to emulate a WebUI handler calling back with the
// result of a getFullscreenState call.
window.chrome = {};
window.chrome.send = function(method, args) {
assertEquals(testMethodName, method);
var callbackName = args[0];
var id = args[1];
executeFunctionByName(callbackName, id, /* fullscreen */ true);
};
var callbackResponse;
cr.sendWithCallback(testMethodName, undefined, function(fullscreen) {
callbackResponse = fullscreen;
});
assertTrue(callbackResponse);
}
/**
* Tests that cr.sendWithCallback passes arguments from JS to the WebUI
* handler.
*/
function testSendWithCallback_PassesJSArgs() {
var testMethodName = 'getSquareOfX';
// Mock out chrome.send to emulate a WebUI handler calling back with the
// result of a getSquareOfX call.
window.chrome = {};
window.chrome.send = function(method, args) {
assertEquals(testMethodName, method);
var callbackName = args[0];
var id = args[1];
var x = args[2];
executeFunctionByName(callbackName, id, x * x);
};
var callbackResponse;
cr.sendWithCallback(testMethodName, [5], function(square) {
callbackResponse = square;
});
assertEquals(25, callbackResponse);
}
/**
* Tests that an event fired by a WebUI handler is sent to all listeners.
* Tests that an event fired by a WebUI handler is sent to all listeners.
*/
function testAddWebUIListener() {
var responses = new Map();
......@@ -338,9 +275,7 @@ function testAddWebUIListener() {
responses.set('second', enabled);
});
executeFunctionByName(
'cr.webUIListenerCallback', 'fullscreen-enabled', true);
cr.webUIListenerCallback('fullscreen-enabled', true);
assertTrue(responses.get('first'));
assertTrue(responses.get('second'));
}
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @fileoverview Framework for running async JS tests for cr.js utility methods.
*/
/** @const {string} Path to source root. */
var ROOT_PATH = '../../../../';
/** @const {string} Name of the chrome.send() message to be used in tests. */
var CHROME_SEND_NAME = 'echoMessage';
/**
* Test fixture for testing async methods of cr.js.
* @constructor
* @extends testing.Test
*/
function WebUIResourceAsyncTest() {}
WebUIResourceAsyncTest.prototype = {
__proto__: testing.Test.prototype,
/** @override */
browsePreload: DUMMY_URL,
/** @override */
isAsync: true,
/** @override */
runAccessibilityChecks: false,
/** @override */
extraLibraries: [
ROOT_PATH + 'third_party/mocha/mocha.js',
ROOT_PATH + 'chrome/test/data/webui/mocha_adapter.js',
ROOT_PATH + 'ui/webui/resources/js/cr.js',
],
};
TEST_F('WebUIResourceAsyncTest', 'SendWithPromise', function() {
/**
* TODO(dpapad): Move this helper method in test_api.js.
* @param {string} name chrome.send message name.
* @return {!Promise} Fires when chrome.send is called with the given message
* name.
*/
function whenChromeSendCalled(name) {
return new Promise(function(resolve, reject) {
registerMessageCallback(name, null, resolve);
});
}
suite('cr.js', function() {
setup(function() {
// Simulate a WebUI handler that echoes back all parameters passed to it.
whenChromeSendCalled(CHROME_SEND_NAME).then(function(args) {
assertEquals('cr.webUIResponse', args[0]);
var globalCallbackArgs = args.slice(1);
cr.webUIResponse.apply(null, globalCallbackArgs);
});
});
test('sendWithPromise_MultipleArgs', function() {
return cr.sendWithPromise(CHROME_SEND_NAME, 'foo', 'bar').then(
function(response) {
assertEquals(['foo', 'bar'].join(), response.join());
});
});
test('sendWithPromise_NoArgs', function() {
return cr.sendWithPromise(CHROME_SEND_NAME).then(function(response) {
assertEquals([].join(), response.join());
});
});
});
// Run all registered tests.
mocha.run();
});
......@@ -313,48 +313,50 @@ var cr = function() {
}
/**
* The mapping used by the sendWithCallback mechanism to tie the callback
* supplied to an invocation of sendWithCallback with the WebUI response
* sent by the browser in response to the chrome.send call. The mapping is
* from ID to callback function; the ID is generated by sendWithCallback and
* is unique across all invocations of said method.
* @type {!Object<Function>}
* The mapping used by the sendWithPromise mechanism to tie the Promise
* returned to callers with the corresponding WebUI response. The mapping is
* from ID to the Promise resolver function; the ID is generated by
* sendWithPromise and is unique across all invocations of said method.
* @type {!Object<!Function>}
*/
var chromeSendCallbackMap = Object.create(null);
var chromeSendResolverMap = {};
/**
* The named method the WebUI handler calls directly in response to a
* chrome.send call that expects a callback. The handler requires no knowledge
* chrome.send call that expects a response. The handler requires no knowledge
* of the specific name of this method, as the name is passed to the handler
* as the first argument in the arguments list of chrome.send. The handler
* must pass the ID, also sent via the chrome.send arguments list, as the
* first argument of the JS invocation; additionally, the handler may
* supply any number of other arguments that will be forwarded to the
* callback.
* @param {string} id The unique ID identifying the callback method this
* response is tied to.
* supply any number of other arguments that will be included in the response.
* @param {string} id The unique ID identifying the Promise this response is
* tied to.
* @param {...*} var_args Variable number of arguments to be included in the
* response.
*/
function webUIResponse(id) {
chromeSendCallbackMap[id].apply(
null, Array.prototype.slice.call(arguments, 1));
delete chromeSendCallbackMap[id];
function webUIResponse(id, var_args) {
var resolverFn = chromeSendResolverMap[id];
delete chromeSendResolverMap[id];
// Promise#resolve accepts only one value, therefore wrapping all arguments
// passed from C++ to JS in an array.
resolverFn(Array.prototype.slice.call(arguments, 1));
}
/**
* A variation of chrome.send which allows the client to receive a direct
* callback without requiring the handler to have specific knowledge of any
* JS internal method names or state. The callback will be removed from the
* mapping once it has fired.
* A variation of chrome.send, suitable for messages that expect a single
* response from C++.
* @param {string} methodName The name of the WebUI handler API.
* @param {Array|undefined} args Arguments for the method call sent to the
* WebUI handler. Pass undefined if no args should be sent to the handler.
* @param {Function} callback A callback function which is called (indirectly)
* by the WebUI handler.
* @param {...*} var_args Varibale number of arguments to be forwarded to the
* C++ call.
* @return {!Promise}
*/
function sendWithCallback(methodName, args, callback) {
var id = methodName + createUid();
chromeSendCallbackMap[id] = callback;
chrome.send(methodName, ['cr.webUIResponse', id].concat(args || []));
function sendWithPromise(methodName, var_args) {
var args = Array.prototype.slice.call(arguments, 1);
return new Promise(function(resolve, reject) {
var id = methodName + '_' + createUid();
chromeSendResolverMap[id] = resolve;
chrome.send(methodName, ['cr.webUIResponse', id].concat(args));
});
}
/**
......@@ -403,7 +405,7 @@ var cr = function() {
getUid: getUid,
makePublic: makePublic,
webUIResponse: webUIResponse,
sendWithCallback: sendWithCallback,
sendWithPromise: sendWithPromise,
webUIListenerCallback: webUIListenerCallback,
addWebUIListener: addWebUIListener,
PropertyKind: PropertyKind,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment