Backed out 2 changesets (bug 1473996) for failures in devtools/server/tests/unit/test_objectgrips-fn-apply.js on a CLOSED TREE

Backed out changeset dc601e6050f6 (bug 1473996)
Backed out changeset 9ba8a6f1857d (bug 1473996)
This commit is contained in:
Noemi Erli 2018-07-18 09:33:40 +03:00
Родитель 0de56634e3
Коммит a8bf2cbb53
6 изменённых файлов: 0 добавлений и 480 удалений

Просмотреть файл

@ -28,8 +28,6 @@ const {
isTypedArray,
} = require("devtools/server/actors/object/utils");
const propertyValueGettersMap = new WeakMap();
const proto = {
/**
* Creates an actor for the specified object.
@ -492,120 +490,6 @@ const proto = {
return { descriptor: this._propertyDescriptor(name) };
},
/**
* Handle a protocol request to provide the value of the object's
* specified property.
*
* Note: Since this will evaluate getters, it can trigger execution of
* content code and may cause side effects. This endpoint should only be used
* when you are confident that the side-effects will be safe, or the user
* is expecting the effects.
*
* @param {string} name
* The property we want the value of.
*/
propertyValue: function(name) {
if (!name) {
return this.throwError("missingParameter", "no property name was specified");
}
const value = this._getPropertyGetter()(this.obj, name);
return { value: this._buildCompletion(value) };
},
/**
* Rather than re-implement the logic for looking up the property of an
* object, this utility allows for easily generating a content function
* that can perform that lookup.
*/
_getPropertyGetter() {
const { global } = this.obj;
let getter = propertyValueGettersMap.get(global);
if (getter) {
return getter;
}
const debugeeGetter = global.executeInGlobal("((obj, key) => obj[key]);").return;
getter = (obj, key) => {
// eslint-disable-next-line no-useless-call
return debugeeGetter.call(undefined, obj, key);
};
propertyValueGettersMap.set(global, getter);
return getter;
},
/**
* Handle a protocol request to evaluate a function and provide the value of
* the result.
*
* Note: Since this will evaluate the function, it can trigger execution of
* content code and may cause side effects. This endpoint should only be used
* when you are confident that the side-effects will be safe, or the user
* is expecting the effects.
*
* @param {any} context
* The 'this' value to call the function with.
* @param {Array<any>} args
* The array of un-decoded actor objects, or primitives.
*/
apply: function(context, args) {
const debugeeContext = this._getValueFromGrip(context);
const debugeeArgs = args && args.map(this._getValueFromGrip, this);
if (!this.obj.callable) {
return this.throwError("notCallable", "debugee object is not callable");
}
const value = this.obj.apply(debugeeContext, debugeeArgs);
return { value: this._buildCompletion(value) };
},
_getValueFromGrip(grip) {
if (typeof grip !== "object" || !grip) {
return grip;
}
if (typeof grip.actor !== "string") {
return this.throwError("invalidGrip", "grip argument did not include actor ID");
}
const actor = this.conn.getActor(grip.actor);
if (!actor) {
return this.throwError("unknownActor", "grip actor did not match a known object");
}
return actor.obj;
},
/**
* Converts a Debugger API completion value record into an eqivalent
* object grip for use by the API.
*
* See https://developer.mozilla.org/en-US/docs/Tools/Debugger-API/Conventions#completion-values
* for more specifics on the expected behavior.
*/
_buildCompletion(value) {
let completionGrip = null;
// .apply result will be falsy if the script being executed is terminated
// via the "slow script" dialog.
if (value) {
completionGrip = {};
if ("return" in value) {
completionGrip.return = this.hooks.createValueGrip(value.return);
}
if ("throw" in value) {
completionGrip.throw = this.hooks.createValueGrip(value.throw);
}
}
return completionGrip;
},
/**
* Handle a protocol request to provide the display string for the object.
*/

Просмотреть файл

@ -1,142 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/* eslint-disable no-shadow, max-nested-callbacks */
"use strict";
async function run_test() {
try {
do_test_pending();
await run_test_with_server(DebuggerServer);
await run_test_with_server(WorkerDebuggerServer);
} finally {
do_test_finished();
}
}
async function run_test_with_server(server) {
initTestDebuggerServer(server);
const debuggee = addTestGlobal("test-grips", server);
debuggee.eval(`
function stopMe(arg1) {
debugger;
}
`);
const dbgClient = new DebuggerClient(server.connectPipe());
await dbgClient.connect();
const [,, threadClient] = await attachTestTabAndResume(dbgClient, "test-grips");
await test_object_grip(debuggee, threadClient);
await dbgClient.close();
}
async function test_object_grip(debuggee, threadClient) {
await assert_object_argument(
debuggee,
threadClient,
`
stopMe({
obj1: {},
obj2: {},
context(arg) {
return this === arg ? "correct context" : "wrong context";
},
sum(...parts) {
return parts.reduce((acc, v) => acc + v, 0);
},
error() {
throw "an error";
},
});
`,
async objClient => {
const obj1 = (await objClient.getPropertyValue("obj1")).value.return;
const obj2 = (await objClient.getPropertyValue("obj2")).value.return;
const context = threadClient.pauseGrip(
(await objClient.getPropertyValue("context")).value.return,
);
const sum = threadClient.pauseGrip(
(await objClient.getPropertyValue("sum")).value.return,
);
const error = threadClient.pauseGrip(
(await objClient.getPropertyValue("error")).value.return,
);
assert_response(await context.apply(obj1, [obj1]), {
return: "correct context",
});
assert_response(await context.apply(obj2, [obj2]), {
return: "correct context",
});
assert_response(await context.apply(obj1, [obj2]), {
return: "wrong context",
});
assert_response(await context.apply(obj2, [obj1]), {
return: "wrong context",
});
// eslint-disable-next-line no-useless-call
assert_response(await sum.apply(null, [1, 2, 3, 4, 5, 6, 7]), {
return: 1 + 2 + 3 + 4 + 5 + 6 + 7,
});
// eslint-disable-next-line no-useless-call
assert_response(await error.apply(null, []), {
throw: "an error",
});
},
);
}
function assert_object_argument(debuggee, threadClient, code, objectHandler) {
return new Promise((resolve, reject) => {
threadClient.addOneTimeListener("paused", function(event, packet) {
(async () => {
try {
const arg1 = packet.frame.arguments[0];
Assert.equal(arg1.class, "Object");
await objectHandler(threadClient.pauseGrip(arg1));
} finally {
await threadClient.resume();
}
})().then(resolve, reject);
});
// This synchronously blocks until 'threadClient.resume()' above runs
// because the 'paused' event runs everthing in a new event loop.
debuggee.eval(code);
});
}
function assert_response({ value }, expected) {
assert_completion(value, expected);
}
function assert_completion(value, expected) {
if (expected && "return" in expected) {
assert_value(value.return, expected.return);
}
if (expected && "throw" in expected) {
assert_value(value.throw, expected.throw);
}
if (!expected) {
assert_value(value, expected);
}
}
function assert_value(actual, expected) {
Assert.equal(typeof actual, typeof expected);
if (typeof expected === "object") {
// Note: We aren't using deepEqual here because we're only doing a cursory
// check of a few properties, not a full comparison of the result, since
// the full outputs includes stuff like preview info that we don't need.
for (const key of Object.keys(expected)) {
assert_value(actual[key], expected[key]);
}
} else {
Assert.equal(actual, expected);
}
}

Просмотреть файл

@ -1,171 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/* eslint-disable no-shadow, max-nested-callbacks */
"use strict";
async function run_test() {
try {
do_test_pending();
await run_test_with_server(DebuggerServer);
await run_test_with_server(WorkerDebuggerServer);
} finally {
do_test_finished();
}
}
async function run_test_with_server(server) {
initTestDebuggerServer(server);
const debuggee = addTestGlobal("test-grips", server);
debuggee.eval(`
function stopMe(arg1) {
debugger;
}
`);
const dbgClient = new DebuggerClient(server.connectPipe());
await dbgClient.connect();
const [,, threadClient] = await attachTestTabAndResume(dbgClient, "test-grips");
await test_object_grip(debuggee, threadClient);
await dbgClient.close();
}
async function test_object_grip(debuggee, threadClient) {
await assert_object_argument(
debuggee,
threadClient,
`
var obj = {
stringProp: "a value",
get stringNormal(){
return "a value";
},
get stringAbrupt() {
throw "a value";
},
get objectNormal() {
return { prop: 4 };
},
get objectAbrupt() {
throw { prop: 4 };
},
get context(){
return this === obj ? "correct context" : "wrong context";
},
method() {
return "a value";
},
};
stopMe(obj);
`,
async objClient => {
const expectedValues = {
stringProp: {
return: "a value",
},
stringNormal: {
return: "a value",
},
stringAbrupt: {
throw: "a value",
},
objectNormal: {
return: {
type: "object",
class: "Object",
ownPropertyLength: 1,
preview: {
kind: "Object",
ownProperties: {
prop: {
value: 4,
},
},
},
},
},
objectAbrupt: {
throw: {
type: "object",
class: "Object",
ownPropertyLength: 1,
preview: {
kind: "Object",
ownProperties: {
prop: {
value: 4,
},
},
},
},
},
context: {
return: "correct context",
},
method: {
return: {
type: "object",
class: "Function",
name: "method",
},
},
};
for (const [key, expected] of Object.entries(expectedValues)) {
const { value } = await objClient.getPropertyValue(key);
assert_completion(value, expected);
}
},
);
}
function assert_object_argument(debuggee, threadClient, code, objectHandler) {
return new Promise((resolve, reject) => {
threadClient.addOneTimeListener("paused", function(event, packet) {
(async () => {
try {
const arg1 = packet.frame.arguments[0];
Assert.equal(arg1.class, "Object");
await objectHandler(threadClient.pauseGrip(arg1));
} finally {
await threadClient.resume();
}
})().then(resolve, reject);
});
// This synchronously blocks until 'threadClient.resume()' above runs
// because the 'paused' event runs everthing in a new event loop.
debuggee.eval(code);
});
}
function assert_completion(value, expected) {
if (expected && "return" in expected) {
assert_value(value.return, expected.return);
}
if (expected && "throw" in expected) {
assert_value(value.throw, expected.throw);
}
if (!expected) {
assert_value(value, expected);
}
}
function assert_value(actual, expected) {
Assert.equal(typeof actual, typeof expected);
if (typeof expected === "object") {
// Note: We aren't using deepEqual here because we're only doing a cursory
// check of a few properties, not a full comparison of the result, since
// the full outputs includes stuff like preview info that we don't need.
for (const key of Object.keys(expected)) {
assert_value(actual[key], expected[key]);
}
} else {
Assert.equal(actual, expected);
}
}

Просмотреть файл

@ -177,8 +177,6 @@ reason = bug 1104838
[test_objectgrips-21.js]
[test_objectgrips-22.js]
[test_objectgrips-array-like-object.js]
[test_objectgrips-fn-apply.js]
[test_objectgrips-property-value.js]
[test_promise_state-01.js]
[test_promise_state-02.js]
[test_promise_state-03.js]

Просмотреть файл

@ -181,17 +181,6 @@ ObjectClient.prototype = {
name: arg(0)
}),
/**
* Request the value of the object's specified property.
*
* @param name string The name of the requested property.
* @param onResponse function Called with the request's response.
*/
getPropertyValue: DebuggerClient.requester({
type: "propertyValue",
name: arg(0)
}),
/**
* Request the prototype of the object.
*
@ -201,18 +190,6 @@ ObjectClient.prototype = {
type: "prototype"
}),
/**
* Request the value of the object's specified property.
*
* @param name string The name of the requested property.
* @param onResponse function Called with the request's response.
*/
apply: DebuggerClient.requester({
type: "apply",
this: arg(0),
arguments: arg(1),
}),
/**
* Request the display string of the object.
*

Просмотреть файл

@ -24,11 +24,6 @@ types.addDictType("object.descriptor", {
set: "nullable:json",
});
types.addDictType("object.completion", {
return: "nullable:json",
throw: "nullable:json"
});
types.addDictType("object.definitionSite", {
source: "source",
line: "number",
@ -50,14 +45,6 @@ types.addDictType("object.property", {
descriptor: "nullable:object.descriptor"
});
types.addDictType("object.propertyValue", {
value: "nullable:object.completion"
});
types.addDictType("object.apply", {
value: "nullable:object.completion"
});
types.addDictType("object.bindings", {
arguments: "array:json",
variables: "json",
@ -178,19 +165,6 @@ const objectSpec = generateActorSpec({
},
response: RetVal("object.property")
},
propertyValue: {
request: {
name: Arg(0, "string")
},
response: RetVal("object.propertyValue")
},
apply: {
request: {
this: Arg(0, "nullable:json"),
arguments: Arg(1, "nullable:array:json"),
},
response: RetVal("object.apply")
},
rejectionStack: {
request: {},
response: {