OLD | NEW |
| (Empty) |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // Mock out the support module to avoid depending on the message loop. | |
6 define("mojo/bindings/js/support", function() { | |
7 var waitingCallbacks = []; | |
8 | |
9 function WaitCookie(id) { | |
10 this.id = id; | |
11 } | |
12 | |
13 function asyncWait(handle, flags, callback) { | |
14 var id = waitingCallbacks.length; | |
15 waitingCallbacks.push(callback); | |
16 return new WaitCookie(id); | |
17 } | |
18 | |
19 function cancelWait(cookie) { | |
20 waitingCallbacks[cookie.id] = null; | |
21 } | |
22 | |
23 function numberOfWaitingCallbacks() { | |
24 var count = 0; | |
25 for (var i = 0; i < waitingCallbacks.length; ++i) { | |
26 if (waitingCallbacks[i]) | |
27 ++count; | |
28 } | |
29 return count; | |
30 } | |
31 | |
32 function pumpOnce(result) { | |
33 var callbacks = waitingCallbacks; | |
34 waitingCallbacks = []; | |
35 for (var i = 0; i < callbacks.length; ++i) { | |
36 if (callbacks[i]) | |
37 callbacks[i](result); | |
38 } | |
39 } | |
40 | |
41 var exports = {}; | |
42 exports.asyncWait = asyncWait; | |
43 exports.cancelWait = cancelWait; | |
44 exports.numberOfWaitingCallbacks = numberOfWaitingCallbacks; | |
45 exports.pumpOnce = pumpOnce; | |
46 return exports; | |
47 }); | |
48 | |
49 define([ | |
50 "gin/test/expect", | |
51 "mojo/bindings/js/support", | |
52 "mojo/bindings/js/core", | |
53 "mojo/public/bindings/js/connection", | |
54 "mojo/public/bindings/tests/sample_interfaces.mojom", | |
55 "mojo/public/bindings/tests/sample_service.mojom", | |
56 ], function(expect, | |
57 mockSupport, | |
58 core, | |
59 connection, | |
60 sample_interfaces, | |
61 sample_service) { | |
62 testClientServer(); | |
63 testWriteToClosedPipe(); | |
64 testRequestResponse(); | |
65 this.result = "PASS"; | |
66 | |
67 function testClientServer() { | |
68 var receivedFrobinate = false; | |
69 var receivedDidFrobinate = false; | |
70 | |
71 // ServiceImpl ------------------------------------------------------------- | |
72 | |
73 function ServiceImpl(peer) { | |
74 this.peer = peer; | |
75 } | |
76 | |
77 ServiceImpl.prototype = Object.create(sample_service.ServiceStub.prototype); | |
78 | |
79 ServiceImpl.prototype.frobinate = function(foo, baz, port) { | |
80 receivedFrobinate = true; | |
81 | |
82 expect(foo.name).toBe("Example name"); | |
83 expect(baz).toBeTruthy(); | |
84 expect(core.close(port)).toBe(core.RESULT_OK); | |
85 | |
86 this.peer.didFrobinate(42); | |
87 }; | |
88 | |
89 // ServiceImpl ------------------------------------------------------------- | |
90 | |
91 function ServiceClientImpl(peer) { | |
92 this.peer = peer; | |
93 } | |
94 | |
95 ServiceClientImpl.prototype = | |
96 Object.create(sample_service.ServiceClientStub.prototype); | |
97 | |
98 ServiceClientImpl.prototype.didFrobinate = function(result) { | |
99 receivedDidFrobinate = true; | |
100 | |
101 expect(result).toBe(42); | |
102 }; | |
103 | |
104 var pipe = core.createMessagePipe(); | |
105 var anotherPipe = core.createMessagePipe(); | |
106 var sourcePipe = core.createMessagePipe(); | |
107 | |
108 var connection0 = new connection.Connection( | |
109 pipe.handle0, ServiceImpl, sample_service.ServiceClientProxy); | |
110 | |
111 var connection1 = new connection.Connection( | |
112 pipe.handle1, ServiceClientImpl, sample_service.ServiceProxy); | |
113 | |
114 var foo = new sample_service.Foo(); | |
115 foo.bar = new sample_service.Bar(); | |
116 foo.name = "Example name"; | |
117 foo.source = sourcePipe.handle0; | |
118 connection1.remote.frobinate(foo, true, anotherPipe.handle0); | |
119 | |
120 mockSupport.pumpOnce(core.RESULT_OK); | |
121 | |
122 expect(receivedFrobinate).toBeTruthy(); | |
123 expect(receivedDidFrobinate).toBeTruthy(); | |
124 | |
125 connection0.close(); | |
126 connection1.close(); | |
127 | |
128 expect(mockSupport.numberOfWaitingCallbacks()).toBe(0); | |
129 | |
130 // sourcePipe.handle0 was closed automatically when sent over IPC. | |
131 expect(core.close(sourcePipe.handle0)).toBe(core.RESULT_INVALID_ARGUMENT); | |
132 // sourcePipe.handle1 hasn't been closed yet. | |
133 expect(core.close(sourcePipe.handle1)).toBe(core.RESULT_OK); | |
134 | |
135 // anotherPipe.handle0 was closed automatically when sent over IPC. | |
136 expect(core.close(anotherPipe.handle0)).toBe(core.RESULT_INVALID_ARGUMENT); | |
137 // anotherPipe.handle1 hasn't been closed yet. | |
138 expect(core.close(anotherPipe.handle1)).toBe(core.RESULT_OK); | |
139 | |
140 // The Connection object is responsible for closing these handles. | |
141 expect(core.close(pipe.handle0)).toBe(core.RESULT_INVALID_ARGUMENT); | |
142 expect(core.close(pipe.handle1)).toBe(core.RESULT_INVALID_ARGUMENT); | |
143 } | |
144 | |
145 function testWriteToClosedPipe() { | |
146 var pipe = core.createMessagePipe(); | |
147 | |
148 var connection1 = new connection.Connection( | |
149 pipe.handle1, function() {}, sample_service.ServiceProxy); | |
150 | |
151 // Close the other end of the pipe. | |
152 core.close(pipe.handle0); | |
153 | |
154 // Not observed yet because we haven't pumped events yet. | |
155 expect(connection1.encounteredError()).toBeFalsy(); | |
156 | |
157 var foo = new sample_service.Foo(); | |
158 foo.bar = new sample_service.Bar(); | |
159 // TODO(darin): crbug.com/357043: pass null in place of |foo| here. | |
160 connection1.remote.frobinate(foo, true, core.kInvalidHandle); | |
161 | |
162 // Write failures are not reported. | |
163 expect(connection1.encounteredError()).toBeFalsy(); | |
164 | |
165 // Pump events, and then we should start observing the closed pipe. | |
166 mockSupport.pumpOnce(core.RESULT_OK); | |
167 | |
168 expect(connection1.encounteredError()).toBeTruthy(); | |
169 | |
170 connection1.close(); | |
171 } | |
172 | |
173 function testRequestResponse() { | |
174 | |
175 // ProviderImpl ------------------------------------------------------------ | |
176 | |
177 function ProviderImpl(peer) { | |
178 this.peer = peer; | |
179 } | |
180 | |
181 ProviderImpl.prototype = | |
182 Object.create(sample_interfaces.ProviderStub.prototype); | |
183 | |
184 ProviderImpl.prototype.echoString = function(a, callback) { | |
185 callback(a); | |
186 }; | |
187 | |
188 ProviderImpl.prototype.echoStrings = function(a, b, callback) { | |
189 callback(a, b); | |
190 }; | |
191 | |
192 // ProviderClientImpl ------------------------------------------------------ | |
193 | |
194 function ProviderClientImpl(peer) { | |
195 this.peer = peer; | |
196 } | |
197 | |
198 ProviderClientImpl.prototype = | |
199 Object.create(sample_interfaces.ProviderClientStub.prototype); | |
200 | |
201 ProviderClientImpl.prototype.didFrobinate = function(result) { | |
202 receivedDidFrobinate = true; | |
203 | |
204 expect(result).toBe(42); | |
205 }; | |
206 | |
207 var pipe = core.createMessagePipe(); | |
208 | |
209 var connection0 = new connection.Connection( | |
210 pipe.handle0, ProviderImpl, sample_interfaces.ProviderClientProxy); | |
211 | |
212 var connection1 = new connection.Connection( | |
213 pipe.handle1, ProviderClientImpl, sample_interfaces.ProviderProxy); | |
214 | |
215 var echoedString; | |
216 | |
217 // echoString | |
218 | |
219 connection1.remote.echoString("hello", function(a) { | |
220 echoedString = a; | |
221 }); | |
222 | |
223 mockSupport.pumpOnce(core.RESULT_OK); | |
224 | |
225 expect(echoedString).toBe("hello"); | |
226 | |
227 // echoStrings | |
228 | |
229 connection1.remote.echoStrings("hello", "world", function(a, b) { | |
230 echoedString = a + " " + b; | |
231 }); | |
232 | |
233 mockSupport.pumpOnce(core.RESULT_OK); | |
234 | |
235 expect(echoedString).toBe("hello world"); | |
236 } | |
237 }); | |
OLD | NEW |