зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1313865
- Centralise common Marionette assertions; r=automatedtester,maja_zf
Many tests that result in throwing errors, amongst those many type- and platform checks, are repeated throughout the Marionette code base. This patch centralises the most common of these, typically reducing consumer calls from three to one line. Example usage: assert.defined(cmd.parameters.value); assert.postiveInteger(cmd.parameters.value, error.pprint`Expected 'value' (${value}) to be a signed integer`); // InvalidArgumentError: Expected 'value' ([object Object] {"foo": "bar"}) to be a positive integer MozReview-Commit-ID: BHOaDazeGer --HG-- extra : rebase_source : 1d35c10e29d4fd536829e9714ae65bcd14ad21f8
This commit is contained in:
Родитель
4b027e3645
Коммит
e5010028a2
|
@ -0,0 +1,220 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/AppConstants.jsm");
|
||||
Cu.import("resource://gre/modules/Preferences.jsm");
|
||||
|
||||
Cu.import("chrome://marionette/content/error.js");
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["assert"];
|
||||
|
||||
const isFennec = () => AppConstants.platform == "android";
|
||||
const isB2G = () => AppConstants.MOZ_B2G;
|
||||
const isFirefox = () => Services.appinfo.name == "Firefox";
|
||||
|
||||
/** Shorthands for common assertions made in Marionette. */
|
||||
this.assert = {};
|
||||
|
||||
/**
|
||||
* Asserts that the current browser is Firefox Desktop.
|
||||
*
|
||||
* @param {string=} msg
|
||||
* Custom error message.
|
||||
*
|
||||
* @throws {UnsupportedOperationError}
|
||||
* If current browser is not Firefox.
|
||||
*/
|
||||
assert.firefox = function(msg = "") {
|
||||
msg = msg || "Expected Firefox";
|
||||
assert.that(isFirefox, msg, UnsupportedOperationError)();
|
||||
};
|
||||
|
||||
/**
|
||||
* Asserts that the current browser is Fennec, or Firefox for Android.
|
||||
*
|
||||
* @param {string=} msg
|
||||
* Custom error message.
|
||||
*
|
||||
* @throws {UnsupportedOperationError}
|
||||
* If current browser is not Fennec.
|
||||
*/
|
||||
assert.fennec = function(msg = "") {
|
||||
msg = msg || "Expected Fennec";
|
||||
assert.that(isFennec, msg, UnsupportedOperationError)();
|
||||
};
|
||||
|
||||
/**
|
||||
* Asserts that the current browser is B2G.
|
||||
*
|
||||
* @param {string=} msg
|
||||
* Custom error message.
|
||||
*
|
||||
* @throws {UnsupportedOperationError}
|
||||
* If the current browser is not B2G.
|
||||
*/
|
||||
assert.b2g = function(msg = "") {
|
||||
msg = msg || "Expected B2G"
|
||||
assert.that(isB2G, msg, UnsupportedOperationError)();
|
||||
};
|
||||
|
||||
/**
|
||||
* Asserts that the current browser is a mobile browser, that is either
|
||||
* B2G or Fennec.
|
||||
*
|
||||
* @param {string=} msg
|
||||
* Custom error message.
|
||||
*
|
||||
* @throws {UnsupportedOperationError}
|
||||
* If the current browser is not B2G or Fennec.
|
||||
*/
|
||||
assert.mobile = function(msg = "") {
|
||||
msg = msg || "Expected Fennec or B2G";
|
||||
assert.that(() => isFennec() || isB2G(), msg, UnsupportedOperationError)();
|
||||
};
|
||||
|
||||
/**
|
||||
* Asserts that |obj| is defined.
|
||||
*
|
||||
* @param {?} obj
|
||||
* Value to test.
|
||||
* @param {string=} msg
|
||||
* Custom error message.
|
||||
*
|
||||
* @return {?}
|
||||
* |obj| is returned unaltered.
|
||||
*
|
||||
* @throws {InvalidArgumentError}
|
||||
* If |obj| is not defined.
|
||||
*/
|
||||
assert.defined = function(obj, msg = "") {
|
||||
msg = msg || error.pprint`Expected ${obj} to be defined`;
|
||||
return assert.that(o => typeof o != "undefined", msg)(obj);
|
||||
};
|
||||
|
||||
/**
|
||||
* Asserts that |obj| is an integer.
|
||||
*
|
||||
* @param {?} obj
|
||||
* Value to test.
|
||||
* @param {string=} msg
|
||||
* Custom error message.
|
||||
*
|
||||
* @return {number}
|
||||
* |obj| is returned unaltered.
|
||||
*
|
||||
* @throws {InvalidArgumentError}
|
||||
* If |obj| is not an integer.
|
||||
*/
|
||||
assert.integer = function(obj, msg = "") {
|
||||
msg = msg || error.pprint`Expected ${obj} to be an integer`;
|
||||
return assert.that(Number.isInteger, msg)(obj);
|
||||
};
|
||||
|
||||
/**
|
||||
* Asserts that |obj| is a positive integer.
|
||||
*
|
||||
* @param {?} obj
|
||||
* Value to test.
|
||||
* @param {string=} msg
|
||||
* Custom error message.
|
||||
*
|
||||
* @return {number}
|
||||
* |obj| is returned unaltered.
|
||||
*
|
||||
* @throws {InvalidArgumentError}
|
||||
* If |obj| is not a positive integer.
|
||||
*/
|
||||
assert.positiveInteger = function(obj, msg = "") {
|
||||
assert.integer(obj, msg);
|
||||
msg = msg || error.pprint`Expected ${obj} to be >= 0`;
|
||||
return assert.that(n => n >= 0, msg)(obj);
|
||||
};
|
||||
|
||||
/**
|
||||
* Asserts that |obj| is a boolean.
|
||||
*
|
||||
* @param {?} obj
|
||||
* Value to test.
|
||||
* @param {string=} msg
|
||||
* Custom error message.
|
||||
*
|
||||
* @return {boolean}
|
||||
* |obj| is returned unaltered.
|
||||
*
|
||||
* @throws {InvalidArgumentError}
|
||||
* If |obj| is not a boolean.
|
||||
*/
|
||||
assert.boolean = function(obj, msg = "") {
|
||||
msg = msg || error.pprint`Expected ${obj} to be boolean`;
|
||||
return assert.that(b => typeof b == "boolean", msg)(obj);
|
||||
};
|
||||
|
||||
/**
|
||||
* Asserts that |obj| is a string.
|
||||
*
|
||||
* @param {?} obj
|
||||
* Value to test.
|
||||
* @param {string=} msg
|
||||
* Custom error message.
|
||||
*
|
||||
* @return {string}
|
||||
* |obj| is returned unaltered.
|
||||
*
|
||||
* @throws {InvalidArgumentError}
|
||||
* If |obj| is not a string.
|
||||
*/
|
||||
assert.string = function(obj, msg = "") {
|
||||
msg = msg || error.pprint`Expected ${obj} to be a string`;
|
||||
return assert.that(s => typeof s == "string", msg)(obj);
|
||||
};
|
||||
|
||||
/**
|
||||
* Asserts that |obj| is an object.
|
||||
*
|
||||
* @param {?} obj
|
||||
* Value to test.
|
||||
* @param {string=} msg
|
||||
* Custom error message.
|
||||
*
|
||||
* @return {Object}
|
||||
* |obj| is returned unaltered.
|
||||
*
|
||||
* @throws {InvalidArgumentError}
|
||||
* If |obj| is not an object.
|
||||
*/
|
||||
assert.object = function(obj, msg = "") {
|
||||
msg = msg || error.pprint`Expected ${obj} to be an object`;
|
||||
return assert.that(o => typeof o == "object", msg)(obj);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a function that is used to assert the |predicate|.
|
||||
*
|
||||
* @param {function(?): boolean} predicate
|
||||
* Evaluated on calling the return value of this function. If its
|
||||
* return value of the inner function is false, |error| is thrown
|
||||
* with |message|.
|
||||
* @param {string=} message
|
||||
* Custom error message.
|
||||
* @param {Error=} error
|
||||
* Custom error type by its class.
|
||||
*
|
||||
* @return {function(?): ?}
|
||||
* Function that takes and returns the passed in value unaltered, and
|
||||
* which may throw |error| with |message| if |predicate| evaluates
|
||||
* to false.
|
||||
*/
|
||||
assert.that = function(
|
||||
predicate, message = "", error = InvalidArgumentError) {
|
||||
return obj => {
|
||||
if (!predicate(obj)) {
|
||||
throw new error(message);
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
};
|
|
@ -128,6 +128,32 @@ error.stringify = function(err) {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Pretty-print values passed to template strings.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* let input = {value: true};
|
||||
* error.pprint`Expected boolean, got ${input}`;
|
||||
* => "Expected boolean, got [object Object] {"value": true}"
|
||||
*/
|
||||
error.pprint = function(strings, ...values) {
|
||||
let res = [];
|
||||
for (let i = 0; i < strings.length; i++) {
|
||||
res.push(strings[i]);
|
||||
if (i < values.length) {
|
||||
let val = values[i];
|
||||
res.push(Object.prototype.toString.call(val));
|
||||
let s = JSON.stringify(val);
|
||||
if (s && s.length > 0) {
|
||||
res.push(" ");
|
||||
res.push(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
return res.join("");
|
||||
};
|
||||
|
||||
/**
|
||||
* Marshal a WebDriverError prototype to a JSON dictionary.
|
||||
*
|
||||
|
|
|
@ -27,6 +27,7 @@ marionette.jar:
|
|||
content/evaluate.js (evaluate.js)
|
||||
content/logging.js (logging.js)
|
||||
content/navigate.js (navigate.js)
|
||||
content/assert.js (assert.js)
|
||||
#ifdef ENABLE_TESTS
|
||||
content/test.xul (harness/marionette/chrome/test.xul)
|
||||
content/test2.xul (harness/marionette/chrome/test2.xul)
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {utils: Cu} = Components;
|
||||
|
||||
Cu.import("chrome://marionette/content/assert.js");
|
||||
Cu.import("chrome://marionette/content/error.js");
|
||||
|
||||
add_test(function test_platforms() {
|
||||
// at least one will fail
|
||||
let raised;
|
||||
for (let fn of [assert.firefox, assert.fennec, assert.b2g, assert.mobile]) {
|
||||
try {
|
||||
fn();
|
||||
} catch (e) {
|
||||
raised = e;
|
||||
}
|
||||
}
|
||||
ok(raised instanceof UnsupportedOperationError);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_defined() {
|
||||
assert.defined({});
|
||||
Assert.throws(() => assert.defined(undefined), InvalidArgumentError);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_integer() {
|
||||
assert.integer(1);
|
||||
assert.integer(0);
|
||||
assert.integer(-1);
|
||||
Assert.throws(() => assert.integer("foo"), InvalidArgumentError);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_positiveInteger() {
|
||||
assert.positiveInteger(1);
|
||||
assert.positiveInteger(0);
|
||||
Assert.throws(() => assert.positiveInteger(-1), InvalidArgumentError);
|
||||
Assert.throws(() => assert.positiveInteger("foo"), InvalidArgumentError);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_boolean() {
|
||||
assert.boolean(true);
|
||||
assert.boolean(false);
|
||||
Assert.throws(() => assert.boolean("false"), InvalidArgumentError);
|
||||
Assert.throws(() => assert.boolean(undefined), InvalidArgumentError);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_string() {
|
||||
assert.string("foo");
|
||||
assert.string(`bar`);
|
||||
Assert.throws(() => assert.string(42), InvalidArgumentError);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_object() {
|
||||
assert.object({});
|
||||
assert.object(new Object());
|
||||
Assert.throws(() => assert.object(42), InvalidArgumentError);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_that() {
|
||||
equal(1, assert.that(n => n + 1)(1));
|
||||
Assert.throws(() => assert.that(() => false)());
|
||||
Assert.throws(() => assert.that(val => val)(false));
|
||||
Assert.throws(() => assert.that(val => val, "foo", SessionNotCreatedError)(false),
|
||||
SessionNotCreatedError);
|
||||
|
||||
run_next_test();
|
||||
});
|
|
@ -8,6 +8,7 @@
|
|||
skip-if = appname == "thunderbird"
|
||||
|
||||
[test_action.js]
|
||||
[test_assert.js]
|
||||
[test_element.js]
|
||||
[test_error.js]
|
||||
[test_message.js]
|
||||
|
|
Загрузка…
Ссылка в новой задаче