Files
sousa-gecko/devtools/server/tests/unit/test_protocol_simple.js
T
2018-06-01 12:36:09 +02:00

313 lines
8.9 KiB
JavaScript

/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Test simple requests using the protocol helpers.
*/
var protocol = require("devtools/shared/protocol");
var {Arg, Option, RetVal} = protocol;
var EventEmitter = require("devtools/shared/event-emitter");
function simpleHello() {
return {
from: "root",
applicationType: "xpcshell-tests",
traits: [],
};
}
const rootSpec = protocol.generateActorSpec({
typeName: "root",
events: {
"oneway": { a: Arg(0) },
"falsyOptions": {
zero: Option(0),
farce: Option(0)
}
},
methods: {
simpleReturn: {
response: { value: RetVal() },
},
promiseReturn: {
response: { value: RetVal("number") },
},
simpleArgs: {
request: {
firstArg: Arg(0),
secondArg: Arg(1),
},
response: RetVal()
},
optionArgs: {
request: {
option1: Option(0),
option2: Option(0)
},
response: RetVal()
},
optionalArgs: {
request: {
a: Arg(0),
b: Arg(1, "nullable:number")
},
response: {
value: RetVal("number")
},
},
arrayArgs: {
request: {
a: Arg(0, "array:number")
},
response: {
arrayReturn: RetVal("array:number")
},
},
nestedArrayArgs: {
request: { a: Arg(0, "array:array:number") },
response: { value: RetVal("array:array:number") },
},
renamedEcho: {
request: {
type: "echo",
a: Arg(0),
},
response: {
value: RetVal("string")
},
},
testOneWay: {
request: { a: Arg(0) },
oneway: true
},
emitFalsyOptions: {
oneway: true
}
}
});
var RootActor = protocol.ActorClassWithSpec(rootSpec, {
initialize: function(conn) {
protocol.Actor.prototype.initialize.call(this, conn);
// Root actor owns itself.
this.manage(this);
this.actorID = "root";
},
sayHello: simpleHello,
simpleReturn: function() {
return 1;
},
promiseReturn: function() {
return Promise.resolve(1);
},
simpleArgs: function(a, b) {
return { firstResponse: a + 1, secondResponse: b + 1 };
},
optionArgs: function(options) {
return { option1: options.option1, option2: options.option2 };
},
optionalArgs: function(a, b = 200) {
return b;
},
arrayArgs: function(a) {
return a;
},
nestedArrayArgs: function(a) {
return a;
},
/**
* Test that the 'type' part of the request packet works
* correctly when the type isn't the same as the method name
*/
renamedEcho: function(a) {
if (this.conn.currentPacket.type != "echo") {
return "goodbye";
}
return a;
},
testOneWay: function(a) {
// Emit to show that we got this message, because there won't be a response.
EventEmitter.emit(this, "oneway", a);
},
emitFalsyOptions: function() {
EventEmitter.emit(this, "falsyOptions", { zero: 0, farce: false });
}
});
var RootFront = protocol.FrontClassWithSpec(rootSpec, {
initialize: function(client) {
this.actorID = "root";
protocol.Front.prototype.initialize.call(this, client);
// Root owns itself.
this.manage(this);
}
});
function run_test() {
DebuggerServer.createRootActor = (conn => {
return RootActor(conn);
});
DebuggerServer.init();
Assert.throws(() => {
const badActor = protocol.ActorClassWithSpec({}, {
missing: protocol.preEvent("missing-event", function() {
})
});
void badActor;
}, /Actor specification must have a typeName member/);
protocol.types.getType("array:array:array:number");
protocol.types.getType("array:array:array:number");
Assert.throws(() => protocol.types.getType("unknown"),
/Unknown type:/, "Should throw for unknown type");
Assert.throws(() => protocol.types.getType("array:unknown"),
/Unknown type:/, "Should throw for unknown type");
Assert.throws(() => protocol.types.getType("unknown:number"),
/Unknown collection type:/, "Should throw for unknown collection type");
const trace = connectPipeTracing();
const client = new DebuggerClient(trace);
let rootClient;
client.connect().then(([applicationType, traits]) => {
trace.expectReceive({"from": "<actorid>",
"applicationType": "xpcshell-tests",
"traits": []});
Assert.equal(applicationType, "xpcshell-tests");
rootClient = RootFront(client);
rootClient.simpleReturn().then(ret => {
trace.expectSend({"type": "simpleReturn", "to": "<actorid>"});
trace.expectReceive({"value": 1, "from": "<actorid>"});
Assert.equal(ret, 1);
}).then(() => {
return rootClient.promiseReturn();
}).then(ret => {
trace.expectSend({"type": "promiseReturn", "to": "<actorid>"});
trace.expectReceive({"value": 1, "from": "<actorid>"});
Assert.equal(ret, 1);
}).then(() => {
Assert.throws(() => rootClient.simpleArgs(5),
/undefined passed where a value is required/,
"Should throw if simpleArgs is missing an argument.");
return rootClient.simpleArgs(5, 10);
}).then(ret => {
trace.expectSend({"type": "simpleArgs",
"firstArg": 5,
"secondArg": 10,
"to": "<actorid>"});
trace.expectReceive({"firstResponse": 6,
"secondResponse": 11,
"from": "<actorid>"});
Assert.equal(ret.firstResponse, 6);
Assert.equal(ret.secondResponse, 11);
}).then(() => {
return rootClient.optionArgs({
"option1": 5,
"option2": 10
});
}).then(ret => {
trace.expectSend({"type": "optionArgs",
"option1": 5,
"option2": 10,
"to": "<actorid>"});
trace.expectReceive({"option1": 5, "option2": 10, "from": "<actorid>"});
Assert.equal(ret.option1, 5);
Assert.equal(ret.option2, 10);
}).then(() => {
return rootClient.optionArgs({});
}).then(ret => {
trace.expectSend({"type": "optionArgs", "to": "<actorid>"});
trace.expectReceive({"from": "<actorid>"});
Assert.ok(typeof (ret.option1) === "undefined");
Assert.ok(typeof (ret.option2) === "undefined");
}).then(() => {
// Explicitly call an optional argument...
return rootClient.optionalArgs(5, 10);
}).then(ret => {
trace.expectSend({"type": "optionalArgs", "a": 5, "b": 10, "to": "<actorid>"});
trace.expectReceive({"value": 10, "from": "<actorid>"});
Assert.equal(ret, 10);
}).then(() => {
// Now don't pass the optional argument, expect the default.
return rootClient.optionalArgs(5);
}).then(ret => {
trace.expectSend({"type": "optionalArgs", "a": 5, "to": "<actorid>"});
trace.expectReceive({"value": 200, "from": "<actorid>"});
Assert.equal(ret, 200);
}).then(ret => {
return rootClient.arrayArgs([0, 1, 2, 3, 4, 5]);
}).then(ret => {
trace.expectSend({"type": "arrayArgs", "a": [0, 1, 2, 3, 4, 5], "to": "<actorid>"});
trace.expectReceive({"arrayReturn": [0, 1, 2, 3, 4, 5], "from": "<actorid>"});
Assert.equal(ret[0], 0);
Assert.equal(ret[5], 5);
}).then(() => {
return rootClient.arrayArgs([[5]]);
}).then(ret => {
trace.expectSend({"type": "arrayArgs", "a": [[5]], "to": "<actorid>"});
trace.expectReceive({"arrayReturn": [[5]], "from": "<actorid>"});
Assert.equal(ret[0][0], 5);
}).then(() => {
return rootClient.renamedEcho("hello");
}).then(str => {
trace.expectSend({"type": "echo", "a": "hello", "to": "<actorid>"});
trace.expectReceive({"value": "hello", "from": "<actorid>"});
Assert.equal(str, "hello");
const deferred = defer();
rootClient.on("oneway", (response) => {
trace.expectSend({"type": "testOneWay", "a": "hello", "to": "<actorid>"});
trace.expectReceive({"type": "oneway", "a": "hello", "from": "<actorid>"});
Assert.equal(response, "hello");
deferred.resolve();
});
Assert.ok(typeof (rootClient.testOneWay("hello")) === "undefined");
return deferred.promise;
}).then(() => {
const deferred = defer();
rootClient.on("falsyOptions", res => {
trace.expectSend({"type": "emitFalsyOptions", "to": "<actorid>"});
trace.expectReceive({"type": "falsyOptions",
"farce": false,
"zero": 0,
"from": "<actorid>"});
Assert.ok(res.zero === 0);
Assert.ok(res.farce === false);
deferred.resolve();
});
rootClient.emitFalsyOptions();
return deferred.promise;
}).then(() => {
client.close().then(() => {
do_test_finished();
});
}).catch(err => {
do_report_unexpected_exception(err, "Failure executing test");
});
});
do_test_pending();
}