зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1363886 - Part 3: Check async callback arguments against schema r=kmag
MozReview-Commit-ID: E0yp9SdJrv6 --HG-- extra : rebase_source : d94e5269d73883d970aba0768d4727943e753cb2
This commit is contained in:
Родитель
d688cf9be3
Коммит
7ae4dbf848
|
@ -2108,6 +2108,7 @@ FunctionEntry = class FunctionEntry extends CallEntry {
|
|||
returns = {
|
||||
type: Schemas.parseSchema(schema.returns, path, ["optional", "name"]),
|
||||
optional: schema.returns.optional || false,
|
||||
name: "result",
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -2132,7 +2133,7 @@ FunctionEntry = class FunctionEntry extends CallEntry {
|
|||
this.hasAsyncCallback = type.hasAsyncCallback;
|
||||
}
|
||||
|
||||
checkValue({type, optional}, value, context) {
|
||||
checkValue({type, optional, name}, value, context) {
|
||||
if (optional && value == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -2143,7 +2144,14 @@ FunctionEntry = class FunctionEntry extends CallEntry {
|
|||
}
|
||||
const {error} = type.normalize(value, context);
|
||||
if (error) {
|
||||
this.throwError(context, `Type error for result value (${error})`);
|
||||
this.throwError(context, `Type error for ${name} value (${error})`);
|
||||
}
|
||||
}
|
||||
|
||||
checkCallback(args, context) {
|
||||
const callback = this.parameters[this.parameters.length - 1];
|
||||
for (const [i, param] of callback.type.parameters.entries()) {
|
||||
this.checkValue(param, args[i], context);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2165,7 +2173,21 @@ FunctionEntry = class FunctionEntry extends CallEntry {
|
|||
// and lastError values are reported immediately.
|
||||
callback = () => {};
|
||||
}
|
||||
return apiImpl.callAsyncFunction(actuals, callback);
|
||||
if (DEBUG && this.hasAsyncCallback && callback) {
|
||||
let original = callback;
|
||||
callback = (...args) => {
|
||||
this.checkCallback(args, context);
|
||||
original(...args);
|
||||
};
|
||||
}
|
||||
let result = apiImpl.callAsyncFunction(actuals, callback);
|
||||
if (DEBUG && this.hasAsyncCallback && !callback) {
|
||||
return result.then(result => {
|
||||
this.checkCallback([result], context);
|
||||
return result;
|
||||
});
|
||||
}
|
||||
return result;
|
||||
};
|
||||
} else if (!this.returns) {
|
||||
stub = (...args) => {
|
||||
|
|
|
@ -8,6 +8,14 @@ let {BaseContext, LocalAPIImplementation} = ExtensionCommon;
|
|||
let schemaJson = [
|
||||
{
|
||||
namespace: "testnamespace",
|
||||
types: [{
|
||||
id: "Widget",
|
||||
type: "object",
|
||||
properties: {
|
||||
size: {type: "integer"},
|
||||
colour: {type: "string", optional: true},
|
||||
},
|
||||
}],
|
||||
functions: [{
|
||||
name: "one_required",
|
||||
type: "function",
|
||||
|
@ -44,6 +52,18 @@ let schemaJson = [
|
|||
parameters: [],
|
||||
optional: true,
|
||||
}],
|
||||
}, {
|
||||
name: "async_result",
|
||||
type: "function",
|
||||
async: "callback",
|
||||
parameters: [{
|
||||
name: "callback",
|
||||
type: "function",
|
||||
parameters: [{
|
||||
name: "widget",
|
||||
$ref: "Widget",
|
||||
}],
|
||||
}],
|
||||
}],
|
||||
},
|
||||
];
|
||||
|
@ -147,6 +167,36 @@ add_task(async function testParameterValidation() {
|
|||
}
|
||||
});
|
||||
|
||||
add_task(async function testCheckAsyncResults() {
|
||||
await Schemas.load("data:," + JSON.stringify(schemaJson));
|
||||
|
||||
const complete = generateAPIs({}, {
|
||||
async_result: async () => ({size: 5, colour: "green"}),
|
||||
});
|
||||
|
||||
const optional = generateAPIs({}, {
|
||||
async_result: async () => ({size: 6}),
|
||||
});
|
||||
|
||||
const invalid = generateAPIs({}, {
|
||||
async_result: async () => ({}),
|
||||
});
|
||||
|
||||
deepEqual(await complete.async_result(), {size: 5, colour: "green"});
|
||||
|
||||
deepEqual(await optional.async_result(), {size: 6},
|
||||
"Missing optional properties is allowed");
|
||||
|
||||
if (AppConstants.DEBUG) {
|
||||
await Assert.rejects(invalid.async_result(),
|
||||
`Type error for widget value (Property "size" is required)`,
|
||||
"Should throw for invalid callback argument in DEBUG builds");
|
||||
} else {
|
||||
deepEqual(await invalid.async_result(), {},
|
||||
"Invalid callback argument doesn't throw in release builds");
|
||||
}
|
||||
});
|
||||
|
||||
add_task(async function testAsyncResults() {
|
||||
await Schemas.load("data:," + JSON.stringify(schemaJson));
|
||||
function runWithCallback(func) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче