|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
3 |
|
4 /** |
|
5 * Test simple requests using the protocol helpers. |
|
6 */ |
|
7 |
|
8 let protocol = devtools.require("devtools/server/protocol"); |
|
9 let {method, Arg, Option, RetVal} = protocol; |
|
10 let events = devtools.require("sdk/event/core"); |
|
11 |
|
12 function simpleHello() { |
|
13 return { |
|
14 from: "root", |
|
15 applicationType: "xpcshell-tests", |
|
16 traits: [], |
|
17 } |
|
18 } |
|
19 |
|
20 let RootActor = protocol.ActorClass({ |
|
21 typeName: "root", |
|
22 initialize: function(conn) { |
|
23 protocol.Actor.prototype.initialize.call(this, conn); |
|
24 // Root actor owns itself. |
|
25 this.manage(this); |
|
26 this.actorID = "root"; |
|
27 }, |
|
28 |
|
29 sayHello: simpleHello, |
|
30 |
|
31 simpleReturn: method(function() { |
|
32 return 1; |
|
33 }, { |
|
34 response: { value: RetVal() }, |
|
35 }), |
|
36 |
|
37 promiseReturn: method(function() { |
|
38 return promise.resolve(1); |
|
39 }, { |
|
40 response: { value: RetVal("number") }, |
|
41 }), |
|
42 |
|
43 simpleArgs: method(function(a, b) { |
|
44 return { firstResponse: a + 1, secondResponse: b + 1 }; |
|
45 }, { |
|
46 request: { |
|
47 firstArg: Arg(0), |
|
48 secondArg: Arg(1), |
|
49 }, |
|
50 response: RetVal() |
|
51 }), |
|
52 |
|
53 nestedArgs: method(function(a, b, c) { |
|
54 return { a: a, b: b, c: c }; |
|
55 }, { |
|
56 request: { |
|
57 firstArg: Arg(0), |
|
58 nest: { |
|
59 secondArg: Arg(1), |
|
60 nest: { |
|
61 thirdArg: Arg(2) |
|
62 } |
|
63 } |
|
64 }, |
|
65 response: RetVal() |
|
66 }), |
|
67 |
|
68 optionArgs: method(function(options) { |
|
69 return { option1: options.option1, option2: options.option2 }; |
|
70 }, { |
|
71 request: { |
|
72 option1: Option(0), |
|
73 option2: Option(0) |
|
74 }, |
|
75 response: RetVal() |
|
76 }), |
|
77 |
|
78 optionalArgs: method(function(a, b=200) { |
|
79 return b; |
|
80 }, { |
|
81 request: { |
|
82 a: Arg(0), |
|
83 b: Arg(1, "nullable:number") |
|
84 }, |
|
85 response: { |
|
86 value: RetVal("number") |
|
87 }, |
|
88 }), |
|
89 |
|
90 arrayArgs: method(function(a) { |
|
91 return a; |
|
92 }, { |
|
93 request: { |
|
94 a: Arg(0, "array:number") |
|
95 }, |
|
96 response: { |
|
97 arrayReturn: RetVal("array:number") |
|
98 }, |
|
99 }), |
|
100 |
|
101 nestedArrayArgs: method(function(a) { |
|
102 return a; |
|
103 }, { |
|
104 request: { a: Arg(0, "array:array:number") }, |
|
105 response: { value: RetVal("array:array:number") }, |
|
106 }), |
|
107 |
|
108 /** |
|
109 * Test that the 'type' part of the request packet works |
|
110 * correctly when the type isn't the same as the method name |
|
111 */ |
|
112 renamedEcho: method(function(a) { |
|
113 if (this.conn.currentPacket.type != "echo") { |
|
114 return "goodbye"; |
|
115 } |
|
116 return a; |
|
117 }, { |
|
118 request: { |
|
119 type: "echo", |
|
120 a: Arg(0), |
|
121 }, |
|
122 response: { |
|
123 value: RetVal("string") |
|
124 }, |
|
125 }), |
|
126 |
|
127 testOneWay: method(function(a) { |
|
128 // Emit to show that we got this message, because there won't be a response. |
|
129 events.emit(this, "oneway", a); |
|
130 }, { |
|
131 request: { a: Arg(0) }, |
|
132 oneway: true |
|
133 }), |
|
134 |
|
135 events: { |
|
136 "oneway": { a: Arg(0) } |
|
137 } |
|
138 }); |
|
139 |
|
140 let RootFront = protocol.FrontClass(RootActor, { |
|
141 initialize: function(client) { |
|
142 this.actorID = "root"; |
|
143 protocol.Front.prototype.initialize.call(this, client); |
|
144 // Root owns itself. |
|
145 this.manage(this); |
|
146 } |
|
147 }); |
|
148 |
|
149 function run_test() |
|
150 { |
|
151 DebuggerServer.createRootActor = (conn => { |
|
152 return RootActor(conn); |
|
153 }); |
|
154 DebuggerServer.init(() => true); |
|
155 |
|
156 check_except(() => { |
|
157 let badActor = ActorClass({ |
|
158 missing: preEvent("missing-event", function() { |
|
159 }) |
|
160 }) |
|
161 }); |
|
162 |
|
163 protocol.types.getType("array:array:array:number"); |
|
164 protocol.types.getType("array:array:array:number"); |
|
165 |
|
166 check_except(() => protocol.types.getType("unknown")); |
|
167 check_except(() => protocol.types.getType("array:unknown")); |
|
168 check_except(() => protocol.types.getType("unknown:number")); |
|
169 let trace = connectPipeTracing(); |
|
170 let client = new DebuggerClient(trace); |
|
171 let rootClient; |
|
172 |
|
173 client.connect((applicationType, traits) => { |
|
174 trace.expectReceive({"from":"<actorid>","applicationType":"xpcshell-tests","traits":[]}); |
|
175 do_check_eq(applicationType, "xpcshell-tests"); |
|
176 |
|
177 rootClient = RootFront(client); |
|
178 |
|
179 rootClient.simpleReturn().then(ret => { |
|
180 trace.expectSend({"type":"simpleReturn","to":"<actorid>"}); |
|
181 trace.expectReceive({"value":1,"from":"<actorid>"}); |
|
182 do_check_eq(ret, 1); |
|
183 }).then(() => { |
|
184 return rootClient.promiseReturn(); |
|
185 }).then(ret => { |
|
186 trace.expectSend({"type":"promiseReturn","to":"<actorid>"}); |
|
187 trace.expectReceive({"value":1,"from":"<actorid>"}); |
|
188 do_check_eq(ret, 1); |
|
189 }).then(() => { |
|
190 // Missing argument should throw an exception |
|
191 check_except(() => { |
|
192 rootClient.simpleArgs(5); |
|
193 }); |
|
194 |
|
195 return rootClient.simpleArgs(5, 10) |
|
196 }).then(ret => { |
|
197 trace.expectSend({"type":"simpleArgs","firstArg":5,"secondArg":10,"to":"<actorid>"}); |
|
198 trace.expectReceive({"firstResponse":6,"secondResponse":11,"from":"<actorid>"}); |
|
199 do_check_eq(ret.firstResponse, 6); |
|
200 do_check_eq(ret.secondResponse, 11); |
|
201 }).then(() => { |
|
202 return rootClient.nestedArgs(1, 2, 3); |
|
203 }).then(ret => { |
|
204 trace.expectSend({"type":"nestedArgs","firstArg":1,"nest":{"secondArg":2,"nest":{"thirdArg":3}},"to":"<actorid>"}); |
|
205 trace.expectReceive({"a":1,"b":2,"c":3,"from":"<actorid>"}); |
|
206 do_check_eq(ret.a, 1); |
|
207 do_check_eq(ret.b, 2); |
|
208 do_check_eq(ret.c, 3); |
|
209 }).then(() => { |
|
210 return rootClient.optionArgs({ |
|
211 "option1": 5, |
|
212 "option2": 10 |
|
213 }); |
|
214 }).then(ret => { |
|
215 trace.expectSend({"type":"optionArgs","option1":5,"option2":10,"to":"<actorid>"}); |
|
216 trace.expectReceive({"option1":5,"option2":10,"from":"<actorid>"}); |
|
217 do_check_eq(ret.option1, 5); |
|
218 do_check_eq(ret.option2, 10); |
|
219 }).then(() => { |
|
220 return rootClient.optionArgs({}); |
|
221 }).then(ret => { |
|
222 trace.expectSend({"type":"optionArgs","to":"<actorid>"}); |
|
223 trace.expectReceive({"from":"<actorid>"}); |
|
224 do_check_true(typeof(ret.option1) === "undefined"); |
|
225 do_check_true(typeof(ret.option2) === "undefined"); |
|
226 }).then(ret => { |
|
227 // Explicitly call an optional argument... |
|
228 return rootClient.optionalArgs(5, 10); |
|
229 }).then(ret => { |
|
230 trace.expectSend({"type":"optionalArgs","a":5,"b":10,"to":"<actorid>"}); |
|
231 trace.expectReceive({"value":10,"from":"<actorid>"}); |
|
232 do_check_eq(ret, 10); |
|
233 }).then(() => { |
|
234 // Now don't pass the optional argument, expect the default. |
|
235 return rootClient.optionalArgs(5); |
|
236 }).then(ret => { |
|
237 trace.expectSend({"type":"optionalArgs","a":5,"to":"<actorid>"}); |
|
238 trace.expectReceive({"value":200,"from":"<actorid>"}); |
|
239 do_check_eq(ret, 200); |
|
240 }).then(ret => { |
|
241 return rootClient.arrayArgs([0, 1, 2, 3, 4, 5]); |
|
242 }).then(ret => { |
|
243 trace.expectSend({"type":"arrayArgs","a":[0,1,2,3,4,5],"to":"<actorid>"}); |
|
244 trace.expectReceive({"arrayReturn":[0,1,2,3,4,5],"from":"<actorid>"}); |
|
245 do_check_eq(ret[0], 0); |
|
246 do_check_eq(ret[5], 5); |
|
247 }).then(() => { |
|
248 return rootClient.arrayArgs([[5]]); |
|
249 }).then(ret => { |
|
250 trace.expectSend({"type":"arrayArgs","a":[[5]],"to":"<actorid>"}); |
|
251 trace.expectReceive({"arrayReturn":[[5]],"from":"<actorid>"}); |
|
252 do_check_eq(ret[0][0], 5); |
|
253 }).then(() => { |
|
254 return rootClient.renamedEcho("hello"); |
|
255 }).then(str => { |
|
256 trace.expectSend({"type":"echo","a":"hello","to":"<actorid>"}); |
|
257 trace.expectReceive({"value":"hello","from":"<actorid>"}); |
|
258 |
|
259 do_check_eq(str, "hello"); |
|
260 |
|
261 let deferred = promise.defer(); |
|
262 rootClient.on("oneway", (response) => { |
|
263 trace.expectSend({"type":"testOneWay","a":"hello","to":"<actorid>"}); |
|
264 trace.expectReceive({"type":"oneway","a":"hello","from":"<actorid>"}); |
|
265 |
|
266 do_check_eq(response, "hello"); |
|
267 deferred.resolve(); |
|
268 }); |
|
269 do_check_true(typeof(rootClient.testOneWay("hello")) === "undefined"); |
|
270 return deferred.promise; |
|
271 }).then(() => { |
|
272 client.close(() => { |
|
273 do_test_finished(); |
|
274 }); |
|
275 }).then(null, err => { |
|
276 do_report_unexpected_exception(err, "Failure executing test"); |
|
277 }); |
|
278 }); |
|
279 do_test_pending(); |
|
280 } |