зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1315872: Add browser.test.assertRejects and assertThrows. r=aswan
MozReview-Commit-ID: DKUlSVS2EvA --HG-- extra : rebase_source : f8e2b6cd1734fee55fa38ce8d5d683b174fe493f extra : histedit_source : 6c34cdab5ade5130d382983ecad8d4d56f49d27e
This commit is contained in:
Родитель
9c000b319d
Коммит
0ed479cc9c
|
@ -1037,7 +1037,12 @@ class ObjectType extends Type {
|
|||
// Parse "additionalProperties" schema.
|
||||
let additionalProperties = null;
|
||||
if (schema.additionalProperties) {
|
||||
additionalProperties = Schemas.parseSchema(schema.additionalProperties, path);
|
||||
let type = schema.additionalProperties;
|
||||
if (type === true) {
|
||||
type = {"type": "any"};
|
||||
}
|
||||
|
||||
additionalProperties = Schemas.parseSchema(type, path);
|
||||
}
|
||||
|
||||
return new this(schema, properties, additionalProperties, patternProperties, schema.isInstanceOf || null);
|
||||
|
@ -1386,7 +1391,7 @@ class FunctionType extends Type {
|
|||
this.checkSchemaProperties(schema, path, extraProperties);
|
||||
|
||||
let isAsync = !!schema.async;
|
||||
let isExpectingCallback = isAsync;
|
||||
let isExpectingCallback = typeof schema.async === "string";
|
||||
let parameters = null;
|
||||
if ("parameters" in schema) {
|
||||
parameters = [];
|
||||
|
@ -1412,9 +1417,10 @@ class FunctionType extends Type {
|
|||
|
||||
let hasAsyncCallback = false;
|
||||
if (isAsync) {
|
||||
if (parameters && parameters.length && parameters[parameters.length - 1].name == schema.async) {
|
||||
hasAsyncCallback = true;
|
||||
}
|
||||
hasAsyncCallback = (parameters &&
|
||||
parameters.length &&
|
||||
parameters[parameters.length - 1].name == schema.async);
|
||||
|
||||
if (schema.returns) {
|
||||
throw new Error("Internal error: Async functions must not have return values.");
|
||||
}
|
||||
|
@ -1955,7 +1961,11 @@ this.Schemas = {
|
|||
});
|
||||
|
||||
for (let json of this.schemaJSON.values()) {
|
||||
this.loadSchema(json);
|
||||
try {
|
||||
this.loadSchema(json);
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
}
|
||||
|
||||
return this.namespaces;
|
||||
|
|
|
@ -1,6 +1,80 @@
|
|||
"use strict";
|
||||
|
||||
function testApiFactory(context) {
|
||||
/**
|
||||
* Checks whether the given error matches the given expectations.
|
||||
*
|
||||
* @param {*} error
|
||||
* The error to check.
|
||||
* @param {string|RegExp|function|null} expectedError
|
||||
* The expectation to check against. If this parameter is:
|
||||
*
|
||||
* - a string, the error message must exactly equal the string.
|
||||
* - a regular expression, it must match the error message.
|
||||
* - a function, it is called with the error object and its
|
||||
* return value is returned.
|
||||
* - null, the function always returns true.
|
||||
* @param {BaseContext} context
|
||||
*
|
||||
* @returns {boolean}
|
||||
* True if the error matches the expected error.
|
||||
*/
|
||||
function errorMatches(error, expectedError, context) {
|
||||
if (expectedError === null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (typeof expectedError === "function") {
|
||||
return context.runSafeWithoutClone(expectedError, error);
|
||||
}
|
||||
|
||||
if (typeof error !== "object" || error == null ||
|
||||
typeof error.message !== "string") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeof expectedError === "string") {
|
||||
return error.message === expectedError;
|
||||
}
|
||||
|
||||
try {
|
||||
return expectedError.test(error.message);
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls .toSource() on the given value, but handles null, undefined,
|
||||
* and errors.
|
||||
*
|
||||
* @param {*} value
|
||||
* @returns {string}
|
||||
*/
|
||||
function toSource(value) {
|
||||
if (value === null) {
|
||||
return null;
|
||||
}
|
||||
if (value === undefined) {
|
||||
return null;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return JSON.stringify(value);
|
||||
}
|
||||
|
||||
try {
|
||||
return String(value.toSource());
|
||||
} catch (e) {
|
||||
return "<unknown>";
|
||||
}
|
||||
}
|
||||
|
||||
function makeTestAPI(context) {
|
||||
function assertTrue(...args) {
|
||||
context.childManager.callParentFunctionNoReturn("test.assertTrue", args);
|
||||
}
|
||||
|
||||
return {
|
||||
test: {
|
||||
// These functions accept arbitrary values. Convert the parameters to
|
||||
|
@ -40,9 +114,46 @@ function testApiFactory(context) {
|
|||
String(msg),
|
||||
]);
|
||||
},
|
||||
|
||||
assertRejects(promise, expectedError, msg) {
|
||||
// Wrap in a native promise for consistency.
|
||||
promise = Promise.resolve(promise);
|
||||
|
||||
if (msg) {
|
||||
msg = `: ${msg}`;
|
||||
}
|
||||
|
||||
return promise.then(result => {
|
||||
assertTrue(false, `Promise resolved, expected rejection${msg}`);
|
||||
}, error => {
|
||||
let errorMessage = toSource(error && error.message);
|
||||
|
||||
assertTrue(errorMatches(error, expectedError, context),
|
||||
`Promise rejected, expecting rejection to match ${toSource(expectedError)}, ` +
|
||||
`got ${errorMessage}${msg}`);
|
||||
});
|
||||
},
|
||||
|
||||
assertThrows(func, expectedError, msg) {
|
||||
if (msg) {
|
||||
msg = `: ${msg}`;
|
||||
}
|
||||
|
||||
try {
|
||||
func();
|
||||
|
||||
assertTrue(false, `Function did not throw, expected error${msg}`);
|
||||
} catch (error) {
|
||||
let errorMessage = toSource(error && error.message);
|
||||
|
||||
assertTrue(errorMatches(error, expectedError, context),
|
||||
`Promise rejected, expecting rejection to match ${toSource(expectedError)}` +
|
||||
`got ${errorMessage}${msg}`);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
extensions.registerSchemaAPI("test", "addon_child", testApiFactory);
|
||||
extensions.registerSchemaAPI("test", "content_child", testApiFactory);
|
||||
extensions.registerSchemaAPI("test", "addon_child", makeTestAPI);
|
||||
extensions.registerSchemaAPI("test", "content_child", makeTestAPI);
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ extensions.on("test-message", (type, extension, ...args) => {
|
|||
});
|
||||
/* eslint-enable mozilla/balanced-listeners */
|
||||
|
||||
function testApiFactory(context) {
|
||||
function makeTestAPI(context) {
|
||||
let {extension} = context;
|
||||
return {
|
||||
test: {
|
||||
|
@ -82,5 +82,5 @@ function testApiFactory(context) {
|
|||
},
|
||||
};
|
||||
}
|
||||
extensions.registerSchemaAPI("test", "addon_parent", testApiFactory);
|
||||
extensions.registerSchemaAPI("test", "content_parent", testApiFactory);
|
||||
extensions.registerSchemaAPI("test", "addon_parent", makeTestAPI);
|
||||
extensions.registerSchemaAPI("test", "content_parent", makeTestAPI);
|
||||
|
|
|
@ -126,19 +126,71 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"name": "assertThrows",
|
||||
"name": "assertRejects",
|
||||
"type": "function",
|
||||
"unsupported": true,
|
||||
"async": true,
|
||||
"parameters": [
|
||||
{"type": "function", "name": "fn"},
|
||||
{
|
||||
"type": "object",
|
||||
"name": "self",
|
||||
"additionalProperties": {"type": "any"},
|
||||
"name": "promise",
|
||||
"$ref": "Promise"
|
||||
},
|
||||
{
|
||||
"name": "expectedError",
|
||||
"$ref": "ExpectedError",
|
||||
"optional": true
|
||||
},
|
||||
{"type": "array", "items": {"type": "any"}, "name": "args", "optional": true},
|
||||
{"choices": [ {"type": "string"}, {"type": "object", "isInstanceOf": "RegExp"} ], "name": "message", "optional": true}
|
||||
{
|
||||
"name": "message",
|
||||
"type": "string",
|
||||
"optional": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "assertThrows",
|
||||
"type": "function",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "func",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"name": "expectedError",
|
||||
"$ref": "ExpectedError",
|
||||
"optional": true
|
||||
},
|
||||
{
|
||||
"name": "message",
|
||||
"type": "string",
|
||||
"optional": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"types": [
|
||||
{
|
||||
"id": "ExpectedError",
|
||||
"choices": [
|
||||
{"type": "string"},
|
||||
{"type": "object", "isInstanceOf": "RegExp", "additionalProperties": true},
|
||||
{"type": "function"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "Promise",
|
||||
"choices": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"then": {"type": "function"}
|
||||
},
|
||||
"additionalProperties": true
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"isInstanceOf": "Promise",
|
||||
"additionalProperties": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
|
|
|
@ -39,6 +39,8 @@ let expectedCommonApis = [
|
|||
// If you want to add a new powerful test API, please see bug 1287233.
|
||||
"test.assertEq",
|
||||
"test.assertFalse",
|
||||
"test.assertRejects",
|
||||
"test.assertThrows",
|
||||
"test.assertTrue",
|
||||
"test.fail",
|
||||
"test.log",
|
||||
|
|
Загрузка…
Ссылка в новой задаче