| // Copyright 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| define([ |
| "gin/test/expect", |
| "mojo/public/js/connection", |
| "mojo/public/js/core", |
| "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom", |
| "mojo/public/interfaces/bindings/tests/sample_service.mojom", |
| "mojo/public/js/threading", |
| "gc", |
| ], function(expect, |
| connection, |
| core, |
| sample_interfaces, |
| sample_service, |
| threading, |
| gc) { |
| testClientServer() |
| .then(testWriteToClosedPipe) |
| .then(testRequestResponse) |
| .then(function() { |
| this.result = "PASS"; |
| gc.collectGarbage(); // should not crash |
| threading.quit(); |
| }.bind(this)).catch(function(e) { |
| this.result = "FAIL: " + (e.stack || e); |
| threading.quit(); |
| }.bind(this)); |
| |
| function testClientServer() { |
| // ServiceImpl ------------------------------------------------------------ |
| |
| function ServiceImpl() { |
| } |
| |
| ServiceImpl.prototype = Object.create( |
| sample_service.Service.stubClass.prototype); |
| |
| ServiceImpl.prototype.frobinate = function(foo, baz, port) { |
| expect(foo.name).toBe("Example name"); |
| expect(baz).toBe(sample_service.Service.BazOptions.REGULAR); |
| expect(core.close(port)).toBe(core.RESULT_OK); |
| |
| return Promise.resolve({result: 42}); |
| }; |
| |
| var pipe = core.createMessagePipe(); |
| var anotherPipe = core.createMessagePipe(); |
| var sourcePipe = core.createMessagePipe(); |
| |
| var connection0 = new connection.Connection(pipe.handle0, ServiceImpl); |
| |
| var connection1 = new connection.Connection( |
| pipe.handle1, undefined, sample_service.Service.proxyClass); |
| |
| var foo = new sample_service.Foo(); |
| foo.bar = new sample_service.Bar(); |
| foo.name = "Example name"; |
| foo.source = sourcePipe.handle0; |
| var promise = connection1.remote.frobinate( |
| foo, sample_service.Service.BazOptions.REGULAR, anotherPipe.handle0) |
| .then(function(response) { |
| expect(response.result).toBe(42); |
| |
| connection0.close(); |
| connection1.close(); |
| |
| return Promise.resolve(); |
| }); |
| |
| // sourcePipe.handle1 hasn't been closed yet. |
| expect(core.close(sourcePipe.handle1)).toBe(core.RESULT_OK); |
| |
| // anotherPipe.handle1 hasn't been closed yet. |
| expect(core.close(anotherPipe.handle1)).toBe(core.RESULT_OK); |
| |
| return promise; |
| } |
| |
| function testWriteToClosedPipe() { |
| var pipe = core.createMessagePipe(); |
| var anotherPipe = core.createMessagePipe(); |
| |
| var connection1 = new connection.Connection( |
| pipe.handle1, function() {}, sample_service.Service.proxyClass); |
| |
| // Close the other end of the pipe. |
| core.close(pipe.handle0); |
| |
| // Not observed yet because we haven't pumped events yet. |
| expect(connection1.encounteredError()).toBeFalsy(); |
| |
| var promise = connection1.remote.frobinate( |
| null, sample_service.Service.BazOptions.REGULAR, anotherPipe.handle0) |
| .then(function(response) { |
| return Promise.reject("Unexpected response"); |
| }).catch(function(e) { |
| // We should observe the closed pipe. |
| expect(connection1.encounteredError()).toBeTruthy(); |
| return Promise.resolve(); |
| }); |
| |
| // Write failures are not reported. |
| expect(connection1.encounteredError()).toBeFalsy(); |
| |
| return promise; |
| } |
| |
| function testRequestResponse() { |
| // ProviderImpl ------------------------------------------------------------ |
| |
| function ProviderImpl() { |
| } |
| |
| ProviderImpl.prototype = |
| Object.create(sample_interfaces.Provider.stubClass.prototype); |
| |
| ProviderImpl.prototype.echoString = function(a) { |
| return Promise.resolve({a: a}); |
| }; |
| |
| ProviderImpl.prototype.echoStrings = function(a, b) { |
| return Promise.resolve({a: a, b: b}); |
| }; |
| |
| var pipe = core.createMessagePipe(); |
| |
| var connection0 = new connection.Connection(pipe.handle0, ProviderImpl); |
| |
| var connection1 = new connection.Connection( |
| pipe.handle1, undefined, sample_interfaces.Provider.proxyClass); |
| |
| var promise = connection1.remote.echoString("hello") |
| .then(function(response) { |
| expect(response.a).toBe("hello"); |
| return connection1.remote.echoStrings("hello", "world"); |
| }).then(function(response) { |
| expect(response.a).toBe("hello"); |
| expect(response.b).toBe("world"); |
| // Mock a read failure, expect it to fail. |
| core.readMessage = function() { |
| return { result: core.RESULT_UNKNOWN }; |
| }; |
| return connection1.remote.echoString("goodbye"); |
| }).then(function() { |
| throw Error("Expected echoString to fail."); |
| }, function(error) { |
| expect(error.message).toBe("Connection error: " + core.RESULT_UNKNOWN); |
| |
| return Promise.resolve(); |
| }); |
| |
| return promise; |
| } |
| }); |