blob: 5d540fa30607e9c1c65b07703291a79969bfc746 [file] [log] [blame]
<!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>