Commit eeff0a91 authored by Trent Apted's avatar Trent Apted Committed by Commit Bot

JS type-check chrome/test/data/webui/test_api.js .

This is needed to allow JS tests themselves to be compiled to ease
future maintenance. js2gtest.js also needs to be compiled for that,
which will be done in a follow-up.

Hand-crafted externs are added for mock4js since it is not able to
be consumed by the compiler directly.

axs_testing.js is precompiled and also not easily consumed by the
compiler, so appropriate suppressions are added to the a11y methods
of test_api.js that deal with it.

Bug: 1000989
Change-Id: Ife6b7595674ffc79c2eadc5484d0804830a648ee
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1787477
Commit-Queue: Trent Apted <tapted@chromium.org>
Reviewed-by: default avatarDan Beam <dbeam@chromium.org>
Reviewed-by: default avatarAndrew Grieve <agrieve@chromium.org>
Cr-Commit-Position: refs/heads/master@{#713357}
parent 8624ee2a
...@@ -1308,6 +1308,7 @@ if (closure_compile) { ...@@ -1308,6 +1308,7 @@ if (closure_compile) {
testonly = true testonly = true
data_deps = [ data_deps = [
"chrome/browser/resources:closure_compile", "chrome/browser/resources:closure_compile",
"chrome/test:closure_compile",
"components/neterror/resources:closure_compile", "components/neterror/resources:closure_compile",
"components/security_interstitials/core/common/resources:closure_compile", "components/security_interstitials/core/common/resources:closure_compile",
"components/sync/driver/resources:closure_compile", "components/sync/driver/resources:closure_compile",
......
...@@ -6585,3 +6585,12 @@ if (is_win) { ...@@ -6585,3 +6585,12 @@ if (is_win) {
] ]
} }
} }
group("closure_compile") {
testonly = true
deps = [
"data:closure_compile",
# TODO(crbug/1000989): Add a dep for base/js2gtest.js.
]
}
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import("//chrome/common/features.gni") import("//chrome/common/features.gni")
import("//mojo/public/tools/bindings/mojom.gni") import("//mojo/public/tools/bindings/mojom.gni")
import("//third_party/closure_compiler/compile_js.gni")
import("//tools/grit/grit_rule.gni") import("//tools/grit/grit_rule.gni")
grit("webui_test_resources") { grit("webui_test_resources") {
...@@ -30,3 +31,23 @@ mojom("web_ui_test_bindings") { ...@@ -30,3 +31,23 @@ mojom("web_ui_test_bindings") {
"webui/web_ui_test.mojom", "webui/web_ui_test.mojom",
] ]
} }
js_type_check("closure_compile") {
deps = [
":test_api_js",
]
}
js_library("test_api_js") {
sources = [
"webui/test_api.js",
]
externs_list = [
"webui/mock4js_externs.js",
"//third_party/chaijs/externs/chai-3.5.js",
"//ui/webui/resources/js/dom_automation_controller.js",
]
deps = [
":web_ui_test_bindings_js_library_for_compile",
]
}
// Copyright 2019 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
* Limited externs used by webui testing from http://mock4js.sourceforge.net/.
* Mock4JS is not closure-annotated and unmaintained.
* TODO(crbug/844820): Eliminate/replace usage of mock4js and delete this file.
*/
function mock(klass) {}
const Mock4JS = {
verifyAllMocks: function() {},
addMockSupport: function(exports) {},
};
class Mock {
proxy() {}
expects(expectedCallCount) {}
stubs() {}
verify() {}
}
...@@ -6,9 +6,13 @@ ...@@ -6,9 +6,13 @@
* @fileoverview Library providing basic test framework functionality. * @fileoverview Library providing basic test framework functionality.
*/ */
// See assert.js for where this is used. /**
* See assert.js for where this is used.
* @suppress {globalThis}
*/
this.traceAssertionsForTesting = true; this.traceAssertionsForTesting = true;
/** @suppress {globalThis} */
var hasWindow = !!this.window; var hasWindow = !!this.window;
/** /**
...@@ -101,7 +105,7 @@ Test.prototype = { ...@@ -101,7 +105,7 @@ Test.prototype = {
* When set to a string value representing a url, generate BrowsePreload * When set to a string value representing a url, generate BrowsePreload
* call, which will browse to the url and call fixture.preLoad of the * call, which will browse to the url and call fixture.preLoad of the
* currentTestCase. * currentTestCase.
* @type {string} * @type {?string}
*/ */
browsePreload: null, browsePreload: null,
...@@ -110,7 +114,7 @@ Test.prototype = { ...@@ -110,7 +114,7 @@ Test.prototype = {
* directory, generate BrowsePrintPreload call, which will browse to a url * directory, generate BrowsePrintPreload call, which will browse to a url
* representing the file, cause print, and call fixture.preLoad of the * representing the file, cause print, and call fixture.preLoad of the
* currentTestCase. * currentTestCase.
* @type {string} * @type {?string}
*/ */
browsePrintPreload: null, browsePrintPreload: null,
...@@ -118,14 +122,14 @@ Test.prototype = { ...@@ -118,14 +122,14 @@ Test.prototype = {
* When set to a function, will be called in the context of the test * When set to a function, will be called in the context of the test
* generation inside the function, after AddLibrary calls and before * generation inside the function, after AddLibrary calls and before
* generated C++. * generated C++.
* @type {function(string,string)} * @type {?function(string,string)}
*/ */
testGenPreamble: null, testGenPreamble: null,
/** /**
* When set to a function, will be called in the context of the test * When set to a function, will be called in the context of the test
* generation inside the function, and after any generated C++. * generation inside the function, and after any generated C++.
* @type {function(string,string)} * @type {?function(string,string)}
*/ */
testGenPostamble: null, testGenPostamble: null,
...@@ -139,7 +143,7 @@ Test.prototype = { ...@@ -139,7 +143,7 @@ Test.prototype = {
/** /**
* This should be initialized by the test fixture and can be referenced * This should be initialized by the test fixture and can be referenced
* during the test run. It holds any mocked handler methods. * during the test run. It holds any mocked handler methods.
* @type {?Mock4JS.Mock} * @type {?Mock}
*/ */
mockHandler: null, mockHandler: null,
...@@ -180,14 +184,17 @@ Test.prototype = { ...@@ -180,14 +184,17 @@ Test.prototype = {
/** /**
* Configuration for the accessibility audit. * Configuration for the accessibility audit.
* @type {axs.AuditConfiguration} * TODO(crbug/1000989): Enable type checks for axs.
* @type {Object} an axs.AuditConfiguration
*/ */
accessibilityAuditConfig_: null, accessibilityAuditConfig_: null,
/** /**
* Returns the configuration for the accessibility audit, creating it * Returns the configuration for the accessibility audit, creating it
* on-demand. * on-demand.
* @return {!axs.AuditConfiguration} * TODO(crbug/1000989): Enable type checks for axs.
* @suppress {undefinedVars|missingProperties}
* @return {Object} an axs.AuditConfiguration!
*/ */
get accessibilityAuditConfig() { get accessibilityAuditConfig() {
if (!this.accessibilityAuditConfig_) { if (!this.accessibilityAuditConfig_) {
...@@ -294,6 +301,8 @@ Test.prototype = { ...@@ -294,6 +301,8 @@ Test.prototype = {
/** /**
* Override this method to perform tasks before running your test. * Override this method to perform tasks before running your test.
* TODO(crbug/1000989): Enable type checks for axs.
* @suppress {missingProperties}
* @type {Function} * @type {Function}
*/ */
setUp: function() { setUp: function() {
...@@ -357,12 +366,12 @@ Test.prototype = { ...@@ -357,12 +366,12 @@ Test.prototype = {
* used as a listener function. * used as a listener function.
* @param {WhenTestDone} whenTestDone Call testDone() at the appropriate * @param {WhenTestDone} whenTestDone Call testDone() at the appropriate
* time. * time.
* @param {Function} completion The function to call to complete the test. * @param {!Function} completion The function to call to complete the test.
* @param {...*} var_args Arguments to pass when calling completionAction. * @param {...*} var_args Arguments to pass when calling completionAction.
* @return {function(): void} Return a function, bound to this test fixture, * @return {function(): void} Return a function, bound to this test fixture,
* which continues the test. * which continues the test.
*/ */
continueTest: function(whenTestDone, completion) { continueTest: function(whenTestDone, completion, var_args) {
var savedArgs = new SaveMockArguments(); var savedArgs = new SaveMockArguments();
var completionAction = new CallFunctionAction( var completionAction = new CallFunctionAction(
this, savedArgs, completion, Array.prototype.slice.call(arguments, 2)); this, savedArgs, completion, Array.prototype.slice.call(arguments, 2));
...@@ -379,7 +388,6 @@ Test.prototype = { ...@@ -379,7 +388,6 @@ Test.prototype = {
/** /**
* Call this during setUp to defer the call to runTest() until later. The * Call this during setUp to defer the call to runTest() until later. The
* caller must call the returned function at some point to run the test. * caller must call the returned function at some point to run the test.
* @type {Function}
* @param {WhenTestDone} whenTestDone Call testDone() at the appropriate * @param {WhenTestDone} whenTestDone Call testDone() at the appropriate
* time. * time.
* @param {...*} var_args Arguments to pass when running the * @param {...*} var_args Arguments to pass when running the
...@@ -387,7 +395,7 @@ Test.prototype = { ...@@ -387,7 +395,7 @@ Test.prototype = {
* @return {function(): void} A function which will run the current body of * @return {function(): void} A function which will run the current body of
* the currentTestCase. * the currentTestCase.
*/ */
deferRunTest: function(whenTestDone) { deferRunTest: function(whenTestDone, var_args) {
if (whenTestDone === WhenTestDone.DEFAULT) { if (whenTestDone === WhenTestDone.DEFAULT) {
whenTestDone = WhenTestDone.ALWAYS; whenTestDone = WhenTestDone.ALWAYS;
} }
...@@ -415,13 +423,13 @@ function TestCase(name, fixture, body) { ...@@ -415,13 +423,13 @@ function TestCase(name, fixture, body) {
TestCase.prototype = { TestCase.prototype = {
/** /**
* The name of this test. * The name of this test.
* @type {string} * @type {?string}
*/ */
name: null, name: null,
/** /**
* The test fixture to set |this| to when running the test |body|. * The test fixture to set |this| to when running the test |body|.
* @type {testing.Test} * @type {Test}
*/ */
fixture: null, fixture: null,
...@@ -512,7 +520,6 @@ TestCase.prototype = { ...@@ -512,7 +520,6 @@ TestCase.prototype = {
/** /**
* Cause this TestCase to be deferred (don't call runTest()) until the * Cause this TestCase to be deferred (don't call runTest()) until the
* returned function is called. * returned function is called.
* @type {Function}
* @param {WhenTestDone} whenTestDone Call testDone() at the appropriate * @param {WhenTestDone} whenTestDone Call testDone() at the appropriate
* time. * time.
* @param {...*} var_args Arguments to pass when running the * @param {...*} var_args Arguments to pass when running the
...@@ -520,7 +527,7 @@ TestCase.prototype = { ...@@ -520,7 +527,7 @@ TestCase.prototype = {
* @return {function(): void} A function that will run this TestCase when * @return {function(): void} A function that will run this TestCase when
* called. * called.
*/ */
deferRunTest: function(whenTestDone) { deferRunTest: function(whenTestDone, var_args) {
this.deferred_ = true; this.deferred_ = true;
var savedArgs = new SaveMockArguments(); var savedArgs = new SaveMockArguments();
var completionAction = new CallFunctionAction( var completionAction = new CallFunctionAction(
...@@ -556,8 +563,8 @@ function registerMessageCallback(name, messageHandler, callback) { ...@@ -556,8 +563,8 @@ function registerMessageCallback(name, messageHandler, callback) {
* Register all methods of {@code mockClass.prototype} with messages of the * Register all methods of {@code mockClass.prototype} with messages of the
* same name as the method, using the proxy of the |mockObject| as the * same name as the method, using the proxy of the |mockObject| as the
* |messageHandler| when registering. * |messageHandler| when registering.
* @param {Mock4JS.Mock} mockObject The mock to register callbacks against. * @param {Mock} mockObject The mock to register callbacks against.
* @param {function(new:Object)} mockClAss Constructor for the mocked class. * @param {Function} mockClass Constructor for the mocked class.
* @see registerMessageCallback * @see registerMessageCallback
* @see overrideChrome * @see overrideChrome
*/ */
...@@ -670,8 +677,8 @@ function resetTestState() { ...@@ -670,8 +677,8 @@ function resetTestState() {
/** /**
* Notifies the running browser test of the test results. Clears |errors|. * Notifies the running browser test of the test results. Clears |errors|.
* @param {Array<boolean, string>=} result When passed, this is used for the * No tuple type: b/131114945 (result should be {[boolean, string]}).
* testResult message. * @param {Array=} result When passed, this is used for the testResult message.
*/ */
function testDone(result) { function testDone(result) {
if (!testIsDone) { if (!testIsDone) {
...@@ -701,9 +708,15 @@ function testDone(result) { ...@@ -701,9 +708,15 @@ function testDone(result) {
if (webUiTest.mojom.TestRunnerPtr) { if (webUiTest.mojom.TestRunnerPtr) {
// For mojo WebUI tests. // For mojo WebUI tests.
testRunner = new webUiTest.mojom.TestRunnerPtr(); testRunner = new webUiTest.mojom.TestRunnerPtr();
/**
* @suppress {missingProperties} for mojo.makeRequest - internal method
* declared in mojo/public/js/bindings.js.
*/
const mojoMakeRequest = () => mojo.makeRequest(testRunner);
Mojo.bindInterface( Mojo.bindInterface(
webUiTest.mojom.TestRunner.name, webUiTest.mojom.TestRunner.name, mojoMakeRequest().handle);
mojo.makeRequest(testRunner).handle);
} else if (webUiTest.mojom.TestRunnerRemote) { } else if (webUiTest.mojom.TestRunnerRemote) {
// For mojo-lite WebUI tests. // For mojo-lite WebUI tests.
testRunner = webUiTest.mojom.TestRunner.getRemote(); testRunner = webUiTest.mojom.TestRunner.getRemote();
...@@ -721,7 +734,7 @@ function testDone(result) { ...@@ -721,7 +734,7 @@ function testDone(result) {
chrome.send('testResult', result); chrome.send('testResult', result);
} else if (window.domAutomationController.send) { } else if (window.domAutomationController.send) {
// For extension tests. // For extension tests.
valueResult = {'result': result[0], message: result[1]}; const valueResult = {'result': result[0], message: result[1]};
window.domAutomationController.send(JSON.stringify(valueResult)); window.domAutomationController.send(JSON.stringify(valueResult));
} else { } else {
assertNotReached('No test framework available'); assertNotReached('No test framework available');
...@@ -747,16 +760,20 @@ function errorsToMessage(errors, opt_message) { ...@@ -747,16 +760,20 @@ function errorsToMessage(errors, opt_message) {
for (var i = 0; i < errors.length; ++i) { for (var i = 0; i < errors.length; ++i) {
var errorMessage = errors[i].stack || errors[i].message; var errorMessage = errors[i].stack || errors[i].message;
// Cast JSON.stringify to Function to avoid formal parameter mismatch.
message += 'Failed: ' + currentTestFunction + '(' + message += 'Failed: ' + currentTestFunction + '(' +
currentTestArguments.map(JSON.stringify) + ')\n' + errorMessage; currentTestArguments.map(/** @type{Function} */ (JSON.stringify)) +
')\n' + errorMessage;
} }
return message; return message;
} }
/** /**
* Returns [success, message] & clears |errors|. * Returns [success, message] & clears |errors|.
* @param {boolean} errorsOk When true, errors are ok. * @param {boolean=} errorsOk When true, errors are ok.
* @return {Array<boolean, string>} *
* No tuple type: b/131114945 (result should be {[boolean, string]}).
* @return {Array}
*/ */
function testResult(errorsOk) { function testResult(errorsOk) {
var result = [true, '']; var result = [true, ''];
...@@ -867,22 +884,39 @@ function assertNotReached(opt_message) { ...@@ -867,22 +884,39 @@ function assertNotReached(opt_message) {
} }
/** /**
* @param {Function} testFunction * @param {function()} testFunction
* @param {Function=|string=|RegExp=} opt_expected The expected Error * @param {(Function|string|RegExp)=} opt_expected_or_constructor The expected
* constructor, partial or complete error message string, or RegExp to * Error constructor, partial or complete error message string, or RegExp to
* test the error message. * test the error message.
* @param {string=} opt_message Additional error message. * @param {string=} opt_message Additional error message.
* @throws {Error} * @throws {Error}
*/ */
function assertThrows(testFunction, opt_expected, opt_message) { function assertThrows(testFunction, opt_expected_or_constructor, opt_message) {
chai.assert.throws(testFunction, opt_expected, opt_message); // The implementation of assert.throws goes like:
// function (fn, errt, errs, msg) {
// if ('string' === typeof errt || errt instanceof RegExp) {
// errs = errt;
// errt = null;
// }
// ...
// That is, if the second argument is string or RegExp, the type of the
// exception is not checked: only the error message. This is achieved by
// partially "shifting" parameters (the "additional error message" is not
// shifted and will be lost). "Shifting" isn't a thing Closure understands, so
// just cast to string.
// TODO(crbug/1000989): Refactor this into something that makes sense when
// tests are actually compiled and we can do that safely.
chai.assert.throws(
testFunction,
/** @type{string} */ (opt_expected_or_constructor), opt_message);
} }
/** /**
* Run an accessibility audit on the current page state. * Run an accessibility audit on the current page state.
* @type {Function} * TODO(crbug/1000989): Enable type checks for axs.
* @suppress {checkTypes}
* @param {Array} a11yResults * @param {Array} a11yResults
* @param {axs.AuditConfiguration=} opt_config * @param {Object=} opt_config, an axs.AuditConfiguration=
* @return {boolean} Whether there were any errors or warnings * @return {boolean} Whether there were any errors or warnings
* @private * @private
*/ */
...@@ -907,11 +941,14 @@ function runAccessibilityAudit(a11yResults, opt_config) { ...@@ -907,11 +941,14 @@ function runAccessibilityAudit(a11yResults, opt_config) {
* |a11yResults| and * |a11yResults| and
* |a11yWarnings| in to an accessibility report, appends it to the given * |a11yWarnings| in to an accessibility report, appends it to the given
* |message| and returns the resulting message string. * |message| and returns the resulting message string.
* @param {Array<string>} a11yResults The list of accessibility results * TODO(crbug/1000989): Enable type checks for axs.
* @suppress {missingProperties}
* @param {Array<Object>} a11yResults The list of accessibility results
* @param {string=} opt_message
* @return {string} |message| + accessibility report. * @return {string} |message| + accessibility report.
*/ */
function accessibilityAuditReport(a11yResults, message) { function accessibilityAuditReport(a11yResults, opt_message) {
message = message ? message + '\n\n' : '\n'; let message = opt_message ? opt_message + '\n\n' : '\n';
message += 'Accessibility issues found on ' + window.location.href + '\n'; message += 'Accessibility issues found on ' + window.location.href + '\n';
message += axs.Audit.createReport(a11yResults); message += axs.Audit.createReport(a11yResults);
return message; return message;
...@@ -935,7 +972,7 @@ function assertAccessibilityOk(opt_results) { ...@@ -935,7 +972,7 @@ function assertAccessibilityOk(opt_results) {
* checking by runTest. This allows tests to continue running other checks, * checking by runTest. This allows tests to continue running other checks,
* while failing the overall test if any errors occurred. * while failing the overall test if any errors occurred.
* @param {Function} assertFunc The function which may throw an Error. * @param {Function} assertFunc The function which may throw an Error.
* @return {function(...*):bool} A function that applies its arguments to * @return {function(...*):boolean} A function that applies its arguments to
* |assertFunc| and returns true if |assertFunc| passes. * |assertFunc| and returns true if |assertFunc| passes.
* @see errors * @see errors
* @see runTestFunction * @see runTestFunction
...@@ -976,6 +1013,7 @@ function runTest(isAsync, testFunction, testArguments) { ...@@ -976,6 +1013,7 @@ function runTest(isAsync, testFunction, testArguments) {
// Avoid eval() if at all possible, since it will not work on pages // Avoid eval() if at all possible, since it will not work on pages
// that have enabled content-security-policy. // that have enabled content-security-policy.
/** @type {?Function} */
var testBody = this[testFunction]; // global object -- not a method. var testBody = this[testFunction]; // global object -- not a method.
var testName = testFunction; var testName = testFunction;
...@@ -986,7 +1024,7 @@ function runTest(isAsync, testFunction, testArguments) { ...@@ -986,7 +1024,7 @@ function runTest(isAsync, testFunction, testArguments) {
} }
if (typeof testBody === 'undefined') { if (typeof testBody === 'undefined') {
testBody = eval(testFunction); testBody = /** @type{Function} */ (eval(testFunction));
testName = testBody.toString(); testName = testBody.toString();
} }
if (testBody != RUN_TEST_F) { if (testBody != RUN_TEST_F) {
...@@ -1012,7 +1050,9 @@ function runTest(isAsync, testFunction, testArguments) { ...@@ -1012,7 +1050,9 @@ function runTest(isAsync, testFunction, testArguments) {
* @param {Array} testArguments The arguments to call |testBody| with. * @param {Array} testArguments The arguments to call |testBody| with.
* @param {boolean} onlyAssertFails When true, only assertions cause failing * @param {boolean} onlyAssertFails When true, only assertions cause failing
* testResult. * testResult.
* @return {Array<boolean, string>} [test-succeeded, message-if-failed] *
* No tuple type: b/131114945 (result should be {[boolean, string]}).
* @return {Array} [test-succeeded, message-if-failed]
* @see createExpect * @see createExpect
* @see testResult * @see testResult
*/ */
...@@ -1054,6 +1094,7 @@ function overrideChrome() { ...@@ -1054,6 +1094,7 @@ function overrideChrome() {
} }
originalChrome = chrome; originalChrome = chrome;
/** @suppress {const|checkTypes} */
chrome = { chrome = {
__proto__: originalChrome, __proto__: originalChrome,
send: send, send: send,
...@@ -1202,7 +1243,6 @@ function RUN_TEST_F(testFixture, testName) { ...@@ -1202,7 +1243,6 @@ function RUN_TEST_F(testFixture, testName) {
* @param {Array} args The array to push |actualArgument| onto. * @param {Array} args The array to push |actualArgument| onto.
* @param {Object} realMatcher The real matcher check arguments with. * @param {Object} realMatcher The real matcher check arguments with.
* @constructor * @constructor
* @extends {realMatcher}
*/ */
function SaveMockArgumentMatcher(args, realMatcher) { function SaveMockArgumentMatcher(args, realMatcher) {
this.arguments_ = args; this.arguments_ = args;
...@@ -1253,7 +1293,6 @@ SaveMockArgumentMatcher.prototype = { ...@@ -1253,7 +1293,6 @@ SaveMockArgumentMatcher.prototype = {
* the mocked method. This class works with SaveMockArgumentMatcher to save * the mocked method. This class works with SaveMockArgumentMatcher to save
* arguments so that the invoked Action can pass arguments through to the * arguments so that the invoked Action can pass arguments through to the
* invoked function. * invoked function.
* @param {!Object} realMatcher The real matcher to perform matching with.
* @constructor * @constructor
*/ */
function SaveMockArguments() { function SaveMockArguments() {
...@@ -1284,44 +1323,39 @@ SaveMockArguments.prototype = { ...@@ -1284,44 +1323,39 @@ SaveMockArguments.prototype = {
* @param {Object} obj The object to set |this| to when calling |func_|. * @param {Object} obj The object to set |this| to when calling |func_|.
* @param {?SaveMockArguments} savedArgs when non-null, saved arguments are * @param {?SaveMockArguments} savedArgs when non-null, saved arguments are
* passed to |func|. * passed to |func|.
* @param {Function} func The function to call. * @param {!Function} func The function to call.
* @param {Array=} args Any arguments to pass to func. * @param {Array=} args Any arguments to pass to func.
* @constructor * @constructor
*/ */
function CallFunctionAction(obj, savedArgs, func, args) { function CallFunctionAction(obj, savedArgs, func, args) {
this.obj_ = obj;
this.savedArgs_ = savedArgs;
this.func_ = func;
this.args_ = args ? args : [];
}
CallFunctionAction.prototype = {
/** /**
* Set |this| to |obj_| when calling |func_|. * Set |this| to |obj_| when calling |func_|.
* @type {?Object} * @type {?Object}
*/ */
obj_: null, this.obj_ = obj;
/** /**
* The SaveMockArguments to hold arguments when invoking |func_|. * The SaveMockArguments to hold arguments when invoking |func_|.
* @type {?SaveMockArguments} * @type {?SaveMockArguments}
* @private * @private
*/ */
savedArgs_: null, this.savedArgs_ = savedArgs;
/** /**
* The function to call when invoked. * The function to call when invoked.
* @type {!Function} * @type {!Function}
* @private * @private
*/ */
func_: null, this.func_ = func;
/** /**
* Arguments to pass to |func_| when invoked. * Arguments to pass to |func_| when invoked.
* @type {!Array} * @type {!Array}
*/ */
args_: null, this.args_ = args || [];
}
CallFunctionAction.prototype = {
/** /**
* Accessor for |func_|. * Accessor for |func_|.
* @return {Function} The function to invoke. * @return {Function} The function to invoke.
...@@ -1356,11 +1390,11 @@ CallFunctionAction.prototype = { ...@@ -1356,11 +1390,11 @@ CallFunctionAction.prototype = {
/** /**
* Syntactic sugar for use with will() on a Mock4JS.Mock. * Syntactic sugar for use with will() on a Mock4JS.Mock.
* @param {Function} func The function to call when the method is invoked. * @param {!Function} func The function to call when the method is invoked.
* @param {...*} var_args Arguments to pass when calling func. * @param {...*} var_args Arguments to pass when calling func.
* @return {CallFunctionAction} Action for use in will. * @return {CallFunctionAction} Action for use in will.
*/ */
function callFunction(func) { function callFunction(func, var_args) {
return new CallFunctionAction( return new CallFunctionAction(
null, null, func, Array.prototype.slice.call(arguments, 1)); null, null, func, Array.prototype.slice.call(arguments, 1));
} }
...@@ -1369,11 +1403,11 @@ function callFunction(func) { ...@@ -1369,11 +1403,11 @@ function callFunction(func) {
* Syntactic sugar for use with will() on a Mock4JS.Mock. * Syntactic sugar for use with will() on a Mock4JS.Mock.
* @param {SaveMockArguments} savedArgs Arguments saved with this object * @param {SaveMockArguments} savedArgs Arguments saved with this object
* are passed to |func|. * are passed to |func|.
* @param {Function} func The function to call when the method is invoked. * @param {!Function} func The function to call when the method is invoked.
* @param {...*} var_args Arguments to pass when calling func. * @param {...*} var_args Arguments to pass when calling func.
* @return {CallFunctionAction} Action for use in will. * @return {CallFunctionAction} Action for use in will.
*/ */
function callFunctionWithSavedArgs(savedArgs, func) { function callFunctionWithSavedArgs(savedArgs, func, var_args) {
return new CallFunctionAction( return new CallFunctionAction(
null, savedArgs, func, Array.prototype.slice.call(arguments, 2)); null, savedArgs, func, Array.prototype.slice.call(arguments, 2));
} }
...@@ -1491,10 +1525,10 @@ RunAllAction.prototype = { ...@@ -1491,10 +1525,10 @@ RunAllAction.prototype = {
/** /**
* Syntactic sugar for use with will() on a Mock4JS.Mock. * Syntactic sugar for use with will() on a Mock4JS.Mock.
* @param {...Object} var_actions Actions to run. * @param {...*} var_args Actions to run.
* @return {RunAllAction} Action for use in will. * @return {RunAllAction} Action for use in will.
*/ */
function runAllActions() { function runAllActions(var_args) {
return new RunAllAction( return new RunAllAction(
false, WhenTestDone.NEVER, Array.prototype.slice.call(arguments)); false, WhenTestDone.NEVER, Array.prototype.slice.call(arguments));
} }
...@@ -1503,10 +1537,10 @@ function runAllActions() { ...@@ -1503,10 +1537,10 @@ function runAllActions() {
* Syntactic sugar for use with will() on a Mock4JS.Mock. * Syntactic sugar for use with will() on a Mock4JS.Mock.
* @param {WhenTestDone} whenTestDone Call testDone() at the appropriate * @param {WhenTestDone} whenTestDone Call testDone() at the appropriate
* time. * time.
* @param {...Object} var_actions Actions to run. * @param {...*} var_args Actions to run.
* @return {RunAllAction} Action for use in will. * @return {RunAllAction} Action for use in will.
*/ */
function runAllActionsAsync(whenTestDone) { function runAllActionsAsync(whenTestDone, var_args) {
return new RunAllAction( return new RunAllAction(
true, whenTestDone, Array.prototype.slice.call(arguments, 1)); true, whenTestDone, Array.prototype.slice.call(arguments, 1));
} }
......
...@@ -16,3 +16,5 @@ Local Modifications: ...@@ -16,3 +16,5 @@ Local Modifications:
- Copied license text out of README.md. - Copied license text out of README.md.
- Externs file from - Externs file from
https://github.com/google/closure-compiler/tree/master/contrib/externs https://github.com/google/closure-compiler/tree/master/contrib/externs
- Add mising assert.notStrictEqual
- Add missing export of chai.expect
...@@ -310,6 +310,13 @@ assert.equal = function(actual, expected, opt_message) {}; ...@@ -310,6 +310,13 @@ assert.equal = function(actual, expected, opt_message) {};
*/ */
assert.strictEqual = function(actual, expected, opt_message) {}; assert.strictEqual = function(actual, expected, opt_message) {};
/**
* @param {*} actual
* @param {*} expected
* @param {string=} opt_message
*/
assert.notStrictEqual = function(actual, expected, opt_message) {};
/** /**
* @param {*} actual * @param {*} actual
* @param {*} expected * @param {*} expected
...@@ -535,6 +542,9 @@ chai.Assertion.prototype.assert = function( ...@@ -535,6 +542,9 @@ chai.Assertion.prototype.assert = function(
/** @const */ /** @const */
chai.assert = assert; chai.assert = assert;
/** @const */
chai.expect = expect;
/** @const */ /** @const */
chai.util = {}; chai.util = {};
......
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