| <!DOCTYPE html> |
| <script src="../resources/testharness.js"></script> |
| <script src="../resources/testharnessreport.js"></script> |
| <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings_lite.js"></script> |
| <script src="file:///gen/content/test/data/lite_js_test.mojom-lite.js"></script> |
| <script> |
| 'use strict'; |
| |
| const kTestMessage = 'hello there'; |
| const kTestNumbers = [0, 1, 1, 2, 3, 5, 8, 13, 21]; |
| |
| class TargetImpl { |
| constructor() { |
| this.numPokes = 0; |
| this.target = new liteJsTest.mojom.TestMessageTarget(this); |
| } |
| |
| poke() { this.numPokes++; } |
| ping() { return Promise.resolve(); } |
| repeat(message, numbers) { return {message: message, numbers: numbers}; } |
| flatten(values) {} |
| flattenUnions(unions) {} |
| requestSubinterface(request, client) {} |
| } |
| |
| promise_test(() => { |
| let impl = new TargetImpl; |
| let proxy = impl.target.createProxy(); |
| proxy.poke(); |
| return proxy.ping().then(() => { |
| assert_equals(impl.numPokes, 1); |
| }); |
| }, 'messages with replies return Promises that resolve on reply received'); |
| |
| promise_test(() => { |
| let impl = new TargetImpl; |
| let proxy = impl.target.createProxy(); |
| return proxy.repeat(kTestMessage, kTestNumbers) |
| .then(reply => { |
| assert_equals(reply.message, kTestMessage); |
| assert_array_equals(reply.numbers, kTestNumbers); |
| }); |
| }, 'implementations can reply with multiple reply arguments'); |
| |
| promise_test(async (t) => { |
| const impl = new TargetImpl; |
| const proxy = impl.target.createProxy(); |
| |
| await proxy.ping(); |
| proxy.$.close(); |
| |
| await promise_rejects(t, new Error(), proxy.ping()); |
| }, 'after the pipe is closed all future calls should fail'); |
| |
| promise_test(async (t) => { |
| const impl = new TargetImpl; |
| const proxy = impl.target.createProxy(); |
| |
| // None of these promises should successfully resolve because we are |
| // immediately closing the pipe. |
| const promises = [] |
| for (let i = 0; i < 10; i++) { |
| promises.push(proxy.ping()); |
| } |
| |
| proxy.$.close(); |
| |
| for (const promise of promises) { |
| await promise_rejects(t, new Error(), promise); |
| } |
| }, 'closing the pipe drops any pending messages'); |
| |
| promise_test(() => { |
| let impl = new TargetImpl; |
| |
| // Intercept any browser-bound request for TestMessageTarget and bind it |
| // instead to the local |impl| object. |
| let interceptor = new MojoInterfaceInterceptor( |
| liteJsTest.mojom.TestMessageTarget.$interfaceName); |
| interceptor.oninterfacerequest = e => { |
| impl.target.bindHandle(e.handle); |
| } |
| interceptor.start(); |
| |
| let proxy = liteJsTest.mojom.TestMessageTarget.getProxy(); |
| proxy.poke(); |
| return proxy.ping().then(() => { |
| assert_equals(impl.numPokes, 1); |
| }); |
| }, 'getProxy() attempts to send requests to the frame host'); |
| |
| promise_test(() => { |
| let router = new liteJsTest.mojom.TestMessageTargetCallbackRouter; |
| let proxy = router.createProxy(); |
| return new Promise(resolve => { |
| router.poke.addListener(resolve); |
| proxy.poke(); |
| }); |
| }, 'basic generated CallbackRouter behavior works as intended'); |
| |
| promise_test(() => { |
| let router = new liteJsTest.mojom.TestMessageTargetCallbackRouter; |
| let proxy = router.createProxy(); |
| let numPokes = 0; |
| router.poke.addListener(() => ++numPokes); |
| router.ping.addListener(() => Promise.resolve()); |
| proxy.poke(); |
| return proxy.ping().then(() => assert_equals(numPokes, 1)); |
| }, 'CallbackRouter listeners can reply to messages'); |
| |
| promise_test(() => { |
| let router = new liteJsTest.mojom.TestMessageTargetCallbackRouter; |
| let proxy = router.createProxy(); |
| router.repeat.addListener( |
| (message, numbers) => ({message: message, numbers: numbers})); |
| return proxy.repeat(kTestMessage, kTestNumbers) |
| .then(reply => { |
| assert_equals(reply.message, kTestMessage); |
| assert_array_equals(reply.numbers, kTestNumbers); |
| }); |
| }, 'CallbackRouter listeners can reply with multiple reply arguments'); |
| |
| promise_test(() => { |
| let targetRouter = new liteJsTest.mojom.TestMessageTargetCallbackRouter; |
| let targetProxy = targetRouter.createProxy(); |
| let subinterfaceRouter = new liteJsTest.mojom.SubinterfaceCallbackRouter; |
| targetRouter.requestSubinterface.addListener((request, client) => { |
| let values = []; |
| subinterfaceRouter.bindHandle(request.handle); |
| subinterfaceRouter.push.addListener(value => values.push(value)); |
| subinterfaceRouter.flush.addListener(() => { |
| client.didFlush(values); |
| values = []; |
| }); |
| }); |
| |
| let clientRouter = new liteJsTest.mojom.SubinterfaceClientCallbackRouter; |
| let subinterfaceProxy = new liteJsTest.mojom.SubinterfaceProxy; |
| targetProxy.requestSubinterface( |
| subinterfaceProxy.$.createRequest(), clientRouter.createProxy()); |
| return new Promise(resolve => { |
| clientRouter.didFlush.addListener(values => { |
| assert_array_equals(values, kTestNumbers); |
| resolve(); |
| }); |
| |
| kTestNumbers.forEach(n => subinterfaceProxy.push(n)); |
| subinterfaceProxy.flush(); |
| }); |
| }, 'can send and receive interface requests and proxies'); |
| |
| promise_test(() => { |
| const targetRouter = new liteJsTest.mojom.TestMessageTargetCallbackRouter; |
| const targetProxy = targetRouter.createProxy(); |
| targetRouter.flatten.addListener(values => ({values: values.map(v => v.x)})); |
| return targetProxy.flatten([{x: 1}, {x: 2}, {x: 3}]).then(reply => { |
| assert_array_equals(reply.values, [1, 2, 3]); |
| }); |
| }, 'regression test for complex array serialization'); |
| |
| promise_test(() => { |
| const targetRouter = new liteJsTest.mojom.TestMessageTargetCallbackRouter; |
| const targetProxy = targetRouter.createProxy(); |
| targetRouter.flattenUnions.addListener(unions => { |
| return {x: unions.filter(u => u.x !== undefined).map(u => u.x), |
| s: unions.filter(u => u.s !== undefined).map(u => u.s.x)}; |
| }); |
| |
| return targetProxy.flattenUnions( |
| [{x: 1}, {x: 2}, {s: {x: 3}}, {s: {x: 4}}, {x: 5}, {s: {x: 6}}]) |
| .then(reply => { |
| assert_array_equals(reply.x, [1, 2, 5]); |
| assert_array_equals(reply.s, [3, 4, 6]); |
| }); |
| }, 'can serialize and deserialize unions'); |
| |
| promise_test(() => { |
| let impl = new TargetImpl; |
| let proxy = impl.target.createProxy(); |
| |
| // Poke a bunch of times. These should never race with the assertion below, |
| // because the |flushForTesting| request/response is ordered against other |
| // messages on |proxy|. |
| const kNumPokes = 100; |
| for (let i = 0; i < kNumPokes; ++i) |
| proxy.poke(); |
| return proxy.$.flushForTesting().then(() => { |
| assert_equals(impl.numPokes, kNumPokes); |
| }); |
| }, 'can use generated flushForTesting API for synchronization in tests'); |
| </script> |