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/apps/js/bindings/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 callbacks[i](result); 37 } 38 39 var exports = {}; 40 exports.asyncWait = asyncWait; 41 exports.cancelWait = cancelWait; 42 exports.numberOfWaitingCallbacks = numberOfWaitingCallbacks; 43 exports.pumpOnce = pumpOnce; 44 return exports; 45 }); 46 47 define([ 48 "gin/test/expect", 49 "mojo/apps/js/bindings/support", 50 "mojo/apps/js/bindings/core", 51 "mojo/apps/js/bindings/connector", 52 "mojom/sample_service", 53 ], function(expect, mockSupport, core, connector, sample) { 54 55 var receivedFrobinate = false; 56 var receivedDidFrobinate = false; 57 58 // ServiceImpl -------------------------------------------------------------- 59 60 function ServiceImpl(peer) { 61 this.peer = peer; 62 } 63 64 ServiceImpl.prototype = Object.create(sample.ServiceStub.prototype); 65 66 ServiceImpl.prototype.frobinate = function(foo, baz, port) { 67 receivedFrobinate = true; 68 69 expect(foo.name).toBe("Example name"); 70 expect(baz).toBeTruthy(); 71 expect(core.close(port)).toBe(core.RESULT_OK); 72 73 this.peer.didFrobinate(42); 74 }; 75 76 // ServiceImpl -------------------------------------------------------------- 77 78 function ServiceClientImpl(peer) { 79 this.peer = peer; 80 } 81 82 ServiceClientImpl.prototype = 83 Object.create(sample.ServiceClientStub.prototype); 84 85 ServiceClientImpl.prototype.didFrobinate = function(result) { 86 receivedDidFrobinate = true; 87 88 expect(result).toBe(42); 89 }; 90 91 var pipe = core.createMessagePipe(); 92 var anotherPipe = core.createMessagePipe(); 93 var sourcePipe = core.createMessagePipe(); 94 95 var connection0 = new connector.Connection( 96 pipe.handle0, ServiceImpl, sample.ServiceClientProxy); 97 98 var connection1 = new connector.Connection( 99 pipe.handle1, ServiceClientImpl, sample.ServiceProxy); 100 101 var foo = new sample.Foo(); 102 foo.bar = new sample.Bar(); 103 foo.name = "Example name"; 104 foo.source = sourcePipe.handle0; 105 connection1.remote.frobinate(foo, true, anotherPipe.handle0); 106 107 mockSupport.pumpOnce(core.RESULT_OK); 108 109 expect(receivedFrobinate).toBeTruthy(); 110 expect(receivedDidFrobinate).toBeTruthy(); 111 112 connection0.close(); 113 connection1.close(); 114 115 expect(mockSupport.numberOfWaitingCallbacks()).toBe(0); 116 117 // sourcePipe.handle0 was closed automatically when sent over IPC. 118 expect(core.close(sourcePipe.handle0)).toBe(core.RESULT_INVALID_ARGUMENT); 119 // sourcePipe.handle1 hasn't been closed yet. 120 expect(core.close(sourcePipe.handle1)).toBe(core.RESULT_OK); 121 122 // anotherPipe.handle0 was closed automatically when sent over IPC. 123 expect(core.close(anotherPipe.handle0)).toBe(core.RESULT_INVALID_ARGUMENT); 124 // anotherPipe.handle1 hasn't been closed yet. 125 expect(core.close(anotherPipe.handle1)).toBe(core.RESULT_OK); 126 127 // The Connection object is responsible for closing these handles. 128 expect(core.close(pipe.handle0)).toBe(core.RESULT_INVALID_ARGUMENT); 129 expect(core.close(pipe.handle1)).toBe(core.RESULT_INVALID_ARGUMENT); 130 131 this.result = "PASS"; 132 }); 133