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