зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1506549 - Introduce API to listen for new child fronts of a given type. r=yulia
MozReview-Commit-ID: EKWTGhGo0VM Depends on D11624 Differential Revision: https://phabricator.services.mozilla.com/D11625 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
5eed35c08e
Коммит
78e2ca28f0
|
@ -0,0 +1,131 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Test Front.onFront method.
|
||||
*/
|
||||
|
||||
const protocol = require("devtools/shared/protocol");
|
||||
const {RetVal} = protocol;
|
||||
|
||||
const childSpec = protocol.generateActorSpec({
|
||||
typeName: "childActor",
|
||||
});
|
||||
|
||||
const ChildActor = protocol.ActorClassWithSpec(childSpec, {
|
||||
initialize(conn, id) {
|
||||
protocol.Actor.prototype.initialize.call(this, conn);
|
||||
this.childID = id;
|
||||
},
|
||||
|
||||
form: function(detail) {
|
||||
if (detail === "actorid") {
|
||||
return this.actorID;
|
||||
}
|
||||
return {
|
||||
actor: this.actorID,
|
||||
childID: this.childID,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
const rootSpec = protocol.generateActorSpec({
|
||||
typeName: "root",
|
||||
|
||||
methods: {
|
||||
createChild: {
|
||||
request: {},
|
||||
response: { actor: RetVal("childActor") },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const RootActor = protocol.ActorClassWithSpec(rootSpec, {
|
||||
typeName: "root",
|
||||
|
||||
initialize: function(conn) {
|
||||
protocol.Actor.prototype.initialize.call(this, conn);
|
||||
|
||||
this.actorID = "root";
|
||||
|
||||
// Root actor owns itself.
|
||||
this.manage(this);
|
||||
|
||||
this.sequence = 0;
|
||||
},
|
||||
|
||||
sayHello() {
|
||||
return {
|
||||
from: "root",
|
||||
applicationType: "xpcshell-tests",
|
||||
traits: [],
|
||||
};
|
||||
},
|
||||
|
||||
createChild() {
|
||||
return new ChildActor(this.conn, this.sequence++);
|
||||
},
|
||||
});
|
||||
|
||||
const ChildFront = protocol.FrontClassWithSpec(childSpec, {
|
||||
form(form, detail) {
|
||||
if (detail === "actorid") {
|
||||
return;
|
||||
}
|
||||
this.childID = form.childID;
|
||||
},
|
||||
});
|
||||
|
||||
const RootFront = protocol.FrontClassWithSpec(rootSpec, {
|
||||
initialize(client) {
|
||||
this.actorID = "root";
|
||||
protocol.Front.prototype.initialize.call(this, client);
|
||||
// Root owns itself.
|
||||
this.manage(this);
|
||||
},
|
||||
});
|
||||
|
||||
add_task(async function run_test() {
|
||||
DebuggerServer.createRootActor = RootActor;
|
||||
DebuggerServer.init();
|
||||
|
||||
const trace = connectPipeTracing();
|
||||
const client = new DebuggerClient(trace);
|
||||
await client.connect();
|
||||
|
||||
const rootFront = new RootFront(client);
|
||||
|
||||
const fronts = [];
|
||||
rootFront.onFront("childActor", front => {
|
||||
fronts.push(front);
|
||||
});
|
||||
|
||||
const firstChild = await rootFront.createChild();
|
||||
ok(firstChild instanceof ChildFront, "createChild returns a ChildFront instance");
|
||||
equal(firstChild.childID, 0, "First child has ID=0");
|
||||
|
||||
equal(fronts.length, 1,
|
||||
"onFront fires the callback, even if the front is created in the future");
|
||||
equal(fronts[0], firstChild,
|
||||
"onFront fires the callback with the right front instance");
|
||||
|
||||
const onFrontAfter = await new Promise(resolve => {
|
||||
rootFront.onFront("childActor", resolve);
|
||||
});
|
||||
equal(onFrontAfter, firstChild,
|
||||
"onFront fires the callback, even if the front is already created, " +
|
||||
" with the same front instance");
|
||||
|
||||
equal(fronts.length, 1,
|
||||
"There is still only one front reported from the first listener");
|
||||
|
||||
const secondChild = await rootFront.createChild();
|
||||
|
||||
equal(fronts.length, 2, "After a second call to createChild, two fronts are reported");
|
||||
equal(fronts[1], secondChild, "And the new front is the right instance");
|
||||
|
||||
trace.close();
|
||||
await client.close();
|
||||
});
|
|
@ -106,6 +106,7 @@ skip-if = coverage # bug 1336670
|
|||
[test_protocol_children.js]
|
||||
[test_protocol_formtype.js]
|
||||
[test_protocol_longstring.js]
|
||||
[test_protocol_onFront.js]
|
||||
[test_protocol_simple.js]
|
||||
[test_protocol_stack.js]
|
||||
[test_protocol_unregister.js]
|
||||
|
|
|
@ -1285,6 +1285,10 @@ var Front = function(conn = null, form = null, detail = null, context = null) {
|
|||
Pool.call(this, conn);
|
||||
this._requests = [];
|
||||
|
||||
// Front listener functions registered via `onFront` get notified
|
||||
// of new fronts via this dedicated EventEmitter object.
|
||||
this._frontListeners = new EventEmitter();
|
||||
|
||||
// protocol.js no longer uses this data in the constructor, only external
|
||||
// uses do. External usage of manually-constructed fronts will be
|
||||
// drastically reduced if we convert the root and target actors to
|
||||
|
@ -1314,6 +1318,7 @@ Front.prototype = extend(Pool.prototype, {
|
|||
}
|
||||
Pool.prototype.destroy.call(this);
|
||||
this.actorID = null;
|
||||
this._frontListeners = null;
|
||||
},
|
||||
|
||||
manage: function(front) {
|
||||
|
@ -1322,6 +1327,22 @@ Front.prototype = extend(Pool.prototype, {
|
|||
"Ensure server supports " + front.typeName + ".");
|
||||
}
|
||||
Pool.prototype.manage.call(this, front);
|
||||
|
||||
// Call listeners registered via `onFront` method
|
||||
this._frontListeners.emit(front.typeName, front);
|
||||
},
|
||||
|
||||
// Run callback on every front of this type that currently exists, and on every
|
||||
// instantiation of front type in the future.
|
||||
onFront(typeName, callback) {
|
||||
// First fire the callback on already instantiated fronts
|
||||
for (const front of this.poolChildren()) {
|
||||
if (front.typeName == typeName) {
|
||||
callback(front);
|
||||
}
|
||||
}
|
||||
// Then register the callback for fronts instantiated in the future
|
||||
this._frontListeners.on(typeName, callback);
|
||||
},
|
||||
|
||||
toString: function() {
|
||||
|
|
Загрузка…
Ссылка в новой задаче