diff options
author | scr@chromium.org <scr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-11 22:02:24 +0000 |
---|---|---|
committer | scr@chromium.org <scr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-11 22:02:24 +0000 |
commit | 066f4a4b01e9d88caadb9a35420172241fa7e93b (patch) | |
tree | b0c4b37ff4d3a72fdda2a433864f6d5cc3edfaa5 /chrome/test/data/webui | |
parent | 6fd34434d5265f8c726ef351f494a623483e66a9 (diff) | |
download | chromium_src-066f4a4b01e9d88caadb9a35420172241fa7e93b.zip chromium_src-066f4a4b01e9d88caadb9a35420172241fa7e93b.tar.gz chromium_src-066f4a4b01e9d88caadb9a35420172241fa7e93b.tar.bz2 |
WebUI test framework: fix Mock4JS verification, allow chrome.send passthrough.
1) Add test for Bug 99970 Comment 6 & fix
2) Allow chrome.send to be mocked outside of preLoad call.
3) add chrome.originalSend to allow mocked messages to pass through to C++.
Also to address need for .cc file to be correct for clang, and prevent ugliness in js with a lot of GEN lines, allow the header and .cc to not have a suffix, and the generated file to end in -gen.cc. While doing this, addressed crbug.com/102794 to put in <(INTERMEDIATE_DIR) preventing collisions across rules.
R=flackr@chromium.org,wyck@chromium.org
BUG=103740,99970,102794
TEST=browser_tests --gtest_filter=Mock4JS*.* AND ChromeSend*.*
Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=109678
Review URL: http://codereview.chromium.org/8515016
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@109711 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/test/data/webui')
-rw-r--r-- | chrome/test/data/webui/chrome_send_browsertest.cc | 40 | ||||
-rw-r--r-- | chrome/test/data/webui/chrome_send_browsertest.h | 54 | ||||
-rw-r--r-- | chrome/test/data/webui/chrome_send_browsertest.js | 70 | ||||
-rw-r--r-- | chrome/test/data/webui/mock4js_browsertest.js | 76 | ||||
-rw-r--r-- | chrome/test/data/webui/test_api.js | 65 |
5 files changed, 292 insertions, 13 deletions
diff --git a/chrome/test/data/webui/chrome_send_browsertest.cc b/chrome/test/data/webui/chrome_send_browsertest.cc new file mode 100644 index 0000000..b835d98 --- /dev/null +++ b/chrome/test/data/webui/chrome_send_browsertest.cc @@ -0,0 +1,40 @@ +// Copyright (c) 2011 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. + +#include "chrome/test/data/webui/chrome_send_browsertest.h" + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/values.h" +#include "testing/gmock/include/gmock/gmock.h" + +ChromeSendWebUITest::ChromeSendWebUITest() {} + +ChromeSendWebUITest::~ChromeSendWebUITest() {} + +ChromeSendWebUITest::ChromeSendWebUIMessageHandler:: + ChromeSendWebUIMessageHandler() {} + +ChromeSendWebUITest::ChromeSendWebUIMessageHandler:: + ~ChromeSendWebUIMessageHandler() {} + +void ChromeSendWebUITest::ChromeSendWebUIMessageHandler::RegisterMessages() { + web_ui_->RegisterMessageCallback( + "checkSend", + base::Bind(&ChromeSendWebUIMessageHandler::HandleCheckSend, + base::Unretained(this))); +} + +WebUIMessageHandler* ChromeSendWebUITest::GetMockMessageHandler() { + return &message_handler_; +} + +ChromeSendPassthroughWebUITest::ChromeSendPassthroughWebUITest() {} + +ChromeSendPassthroughWebUITest::~ChromeSendPassthroughWebUITest() {} + +void ChromeSendPassthroughWebUITest::SetUpOnMainThread() { + ChromeSendWebUITest::SetUpOnMainThread(); + EXPECT_CALL(message_handler_, HandleCheckSend(::testing::_)); +} diff --git a/chrome/test/data/webui/chrome_send_browsertest.h b/chrome/test/data/webui/chrome_send_browsertest.h new file mode 100644 index 0000000..0262a46 --- /dev/null +++ b/chrome/test/data/webui/chrome_send_browsertest.h @@ -0,0 +1,54 @@ +// Copyright (c) 2011 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. +#ifndef CHROME_TEST_DATA_WEBUI_CHROME_SEND_BROWSERTEST_H_ +#define CHROME_TEST_DATA_WEBUI_CHROME_SEND_BROWSERTEST_H_ +#pragma once + +#include "chrome/browser/ui/webui/web_ui_browsertest.h" +#include "testing/gmock/include/gmock/gmock.h" + +// Test fixture for testing chrome.send. This class registers the "checkSend" +// message, but should NOT receive it. +class ChromeSendWebUITest : public WebUIBrowserTest { + public: + ChromeSendWebUITest(); + virtual ~ChromeSendWebUITest(); + + // Mocked message handler class to register expects using gmock framework. + class ChromeSendWebUIMessageHandler : public WebUIMessageHandler { + public: + ChromeSendWebUIMessageHandler(); + ~ChromeSendWebUIMessageHandler(); + + MOCK_METHOD1(HandleCheckSend, void(const base::ListValue*)); + + private: + virtual void RegisterMessages() OVERRIDE; + }; + + + protected: + // Strict mock will fail when unexpected chrome.send messages are received. + ::testing::StrictMock<ChromeSendWebUIMessageHandler> message_handler_; + + private: + virtual WebUIMessageHandler* GetMockMessageHandler() OVERRIDE; + + DISALLOW_COPY_AND_ASSIGN(ChromeSendWebUITest); +}; + +// Test fixture for verifying chrome.send messages are passed through. This +// class DOES expect to receive the "checkSend" message. +class ChromeSendPassthroughWebUITest : public ChromeSendWebUITest { + public: + ChromeSendPassthroughWebUITest(); + virtual ~ChromeSendPassthroughWebUITest(); + + private: + virtual void SetUpOnMainThread() OVERRIDE; + + DISALLOW_COPY_AND_ASSIGN(ChromeSendPassthroughWebUITest); +}; + +#endif // CHROME_TEST_DATA_WEBUI_CHROME_SEND_BROWSERTEST_H_ diff --git a/chrome/test/data/webui/chrome_send_browsertest.js b/chrome/test/data/webui/chrome_send_browsertest.js new file mode 100644 index 0000000..a20eb5f --- /dev/null +++ b/chrome/test/data/webui/chrome_send_browsertest.js @@ -0,0 +1,70 @@ +// Copyright (c) 2011 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 Tests to ensure that chrome.send mocking works as expected. + * @author scr@chromium.org (Sheridan Rawlins) + * @see test_api.js + */ + +GEN('#include "chrome/test/data/webui/chrome_send_browsertest.h"'); + +/** + * Test fixture for chrome send WebUI testing. + * @constructor + * @extends {testing.Test} + */ +function ChromeSendWebUITest() {} + +ChromeSendWebUITest.prototype = { + __proto__: testing.Test.prototype, + + /** + * Generate a real C++ class; don't typedef. + * @type {?string} + * @override + */ + typedefCppFixture: null, + + /** @inheritDoc */ + browsePreload: DUMMY_URL, + + /** @inheritDoc */ + setUp: function() { + // Set up a mock handler class to catch the 'checkSend' message. + function MockHandler() {} + MockHandler.prototype = { + checkSend: function() {}, + }; + this.mockHandler = mock(MockHandler); + registerMockMessageCallbacks(this.mockHandler, MockHandler); + } +}; + +// Test that chrome.send can be mocked outside the preLoad method. +TEST_F('ChromeSendWebUITest', 'NotInPreload', function() { + this.mockHandler.expects(once()).checkSend(); + chrome.send('checkSend'); +}); + +/** + * Test fixture for chrome send WebUI testing with passthrough. + * @constructor + * @extends {ChromeSendWebUITest} + */ +function ChromeSendPassthroughWebUITest() {} + +ChromeSendPassthroughWebUITest.prototype = { + __proto__: ChromeSendWebUITest.prototype, +}; + +// Test that the mocked chrome.send can call the original. +TEST_F('ChromeSendPassthroughWebUITest', 'CanCallOriginal', function() { + chrome.send('expectCheckSend'); + this.mockHandler.expects(once()).checkSend(). + will(callFunction(function() { + chrome.originalSend('checkSend'); + })); + chrome.send('checkSend'); +}); diff --git a/chrome/test/data/webui/mock4js_browsertest.js b/chrome/test/data/webui/mock4js_browsertest.js new file mode 100644 index 0000000..1fd0cfe --- /dev/null +++ b/chrome/test/data/webui/mock4js_browsertest.js @@ -0,0 +1,76 @@ +// Copyright (c) 2011 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 Tests for Mock4JS to ensure that expectations pass or fail as + * expected using the test framework. + * @author scr@chromium.org (Sheridan Rawlins) + * @see test_api.js + */ + +/** + * Test fixture for Mock4JS testing. + * @constructor + * @extends {testing.Test} + */ +function Mock4JSWebUITest() {} + +Mock4JSWebUITest.prototype = { + __proto__: testing.Test.prototype, + + /** @inheritDoc */ + browsePreload: DUMMY_URL, + + /** @inheritDoc */ + setUp: function() { + function MockHandler() {} + MockHandler.prototype = { + callMe: function() {}, + }; + this.mockHandler = mock(MockHandler); + }, +}; + +TEST_F('Mock4JSWebUITest', 'CalledExpectPasses', function() { + this.mockHandler.expects(once()).callMe(); + this.mockHandler.proxy().callMe(); +}); + +TEST_F('Mock4JSWebUITest', 'CalledTwiceExpectTwice', function() { + this.mockHandler.expects(exactly(2)).callMe(); + var proxy = this.mockHandler.proxy(); + proxy.callMe(); + proxy.callMe(); +}); + +/** + * Test fixture for Mock4JS testing which is expected to fail. + * @constructor + * @extends {Mock4JSWebUITest} + */ +function Mock4JSWebUITestFails() {} + +Mock4JSWebUITestFails.prototype = { + __proto__: Mock4JSWebUITest.prototype, + + /** @inheritDoc */ + testShouldFail: true, +}; + +TEST_F('Mock4JSWebUITestFails', 'NotCalledExpectFails', function() { + this.mockHandler.expects(once()).callMe(); +}); + +TEST_F('Mock4JSWebUITestFails', 'CalledTwiceExpectOnceFails', function() { + this.mockHandler.expects(once()).callMe(); + var proxy = this.mockHandler.proxy(); + proxy.callMe(); + proxy.callMe(); +}); + +TEST_F('Mock4JSWebUITestFails', 'CalledOnceExpectTwiceFails', function() { + this.mockHandler.expects(exactly(2)).callMe(); + var proxy = this.mockHandler.proxy(); + proxy.callMe(); +}); diff --git a/chrome/test/data/webui/test_api.js b/chrome/test/data/webui/test_api.js index c9f2313..baf629a 100644 --- a/chrome/test/data/webui/test_api.js +++ b/chrome/test/data/webui/test_api.js @@ -13,6 +13,11 @@ var testing = {}; (function(exports) { /** + * Holds the original version of the |chrome| object. + */ + var originalChrome = null; + + /** * Hold the currentTestCase across between preLoad and run. * @type {TestCase} */ @@ -338,8 +343,11 @@ var testing = {}; * @param {Mock4JS.Mock} mockObject The mock to register callbacks against. * @param {function(new:Object)} mockClAss Constructor for the mocked class. * @see registerMessageCallback + * @see overrideChrome */ function registerMockMessageCallbacks(mockObject, mockClass) { + if (!deferGlobalOverrides && !originalChrome) + overrideChrome(); var mockProxy = mockObject.proxy(); for (var func in mockClass.prototype) { if (typeof mockClass.prototype[func] === 'function') { @@ -556,7 +564,11 @@ var testing = {}; try { currentTestCase.tearDown(); } catch (e) { + // Caught an exception in tearDown; Register the error and recreate + // the result if it is passed in. errors.push(e); + if (result) + result = [false, errorsToMessage([e], result[1])]; } currentTestCase = null; } @@ -568,6 +580,26 @@ var testing = {}; } /** + * Converts each Error in |errors| to a suitable message, adding them to + * |message|, and returns the message string. + * @param {Array.<Error>} errors Array of errors to add to |message|. + * @param {string?} message When supplied, error messages are appended to it. + * @return {string} |message| + messages of all |errors|. + */ + function errorsToMessage(errors, message) { + for (var i = 0; i < errors.length; ++i) { + var errorMessage = errors[i].stack || errors[i].message; + if (message) + message += '\n'; + + message += 'Failed: ' + currentTestFunction + '(' + + currentTestArguments.map(JSON.stringify) + + ')\n' + errorMessage; + } + return message; + } + + /** * Returns [success, message] & clears |errors|. * @param {boolean} errorsOk When true, errors are ok. * @return {Array.<boolean, string>} @@ -575,13 +607,7 @@ var testing = {}; function testResult(errorsOk) { var result = [true, '']; if (errors.length) { - var message = ''; - for (var i = 0; i < errors.length; ++i) { - message += 'Failed: ' + currentTestFunction + '(' + - currentTestArguments.map(JSON.stringify) + - ')\n' + errors[i].stack; - } - result = [!!errorsOk, message]; + result = [!!errorsOk, errorsToMessage(errors)]; } return result; } @@ -821,6 +847,23 @@ var testing = {}; } /** + * Overrides the |chrome| object to enable mocking calls to chrome.send(). + */ + function overrideChrome() { + if (originalChrome) { + console.error('chrome object already overridden'); + return; + } + + originalChrome = chrome; + chrome = { + __proto__: originalChrome, + send: send, + originalSend: originalChrome.send.bind(originalChrome), + }; + } + + /** * Used by WebUIBrowserTest to preload the javascript libraries at the * appropriate time for javascript injection into the current page. This * creates a test case and calls its preLoad for any early initialization such @@ -835,12 +878,8 @@ var testing = {}; function preloadJavascriptLibraries(testFixture, testName) { deferGlobalOverrides = true; - exports.addEventListener('DOMContentLoaded', function() { - var oldChrome = chrome; - chrome = { - __proto__: oldChrome, - send: send, - }; + window.addEventListener('DOMContentLoaded', function() { + overrideChrome(); // Override globals at load time so they will be defined. assertTrue(deferGlobalOverrides); |