1 |
|
2 |
|
3 | import * as assert from 'assert';
|
4 |
|
5 | import RpcProvider from '../src/RpcProvider';
|
6 |
|
7 | suite('RPC provider', function() {
|
8 |
|
9 | let local: RpcProvider,
|
10 | remote: RpcProvider,
|
11 | transferLocalToRemote: Array<any>,
|
12 | transferRemoteToLocal: Array<any>,
|
13 | errorLocal: Error,
|
14 | errorRemote: Error;
|
15 |
|
16 | setup(function() {
|
17 | local = new RpcProvider(
|
18 | (message, transfer) => (transferLocalToRemote = transfer, remote.dispatch(message)),
|
19 | 50
|
20 | );
|
21 |
|
22 | local.error.addHandler(err => errorLocal = err);
|
23 |
|
24 | remote = new RpcProvider(
|
25 | (message, transfer) => (transferRemoteToLocal = transfer, local.dispatch(message)),
|
26 | 50
|
27 | );
|
28 |
|
29 | remote.error.addHandler(err => errorRemote = err);
|
30 |
|
31 | transferLocalToRemote = transferRemoteToLocal = undefined;
|
32 | errorRemote = errorLocal = undefined
|
33 | });
|
34 |
|
35 | suite('signals', function() {
|
36 |
|
37 | test('Signals are propagated', function() {
|
38 | let x = -1;
|
39 |
|
40 | remote.registerSignalHandler('action', (value: number) => x = value);
|
41 |
|
42 | local.signal('action', 5);
|
43 |
|
44 | assert(!errorLocal);
|
45 | assert(!errorRemote);
|
46 | assert.strictEqual(x, 5);
|
47 | });
|
48 |
|
49 | test('Unregistered signals raise an error', function() {
|
50 | local.signal('action', 10);
|
51 |
|
52 | assert(errorLocal);
|
53 | assert(errorRemote);
|
54 | });
|
55 |
|
56 | test('Multiple signals do not interfere', function() {
|
57 | let x = -1, y = -1;
|
58 |
|
59 | remote.registerSignalHandler('setx', (value: number) => x = value);
|
60 | remote.registerSignalHandler('sety', (value: number) => y = value);
|
61 |
|
62 | local.signal('setx', 5);
|
63 | local.signal('sety', 6);
|
64 |
|
65 | assert(!errorLocal);
|
66 | assert(!errorRemote);
|
67 | assert.strictEqual(x, 5);
|
68 | assert.strictEqual(y, 6);
|
69 | });
|
70 |
|
71 | test('Multiple handlers can be bound to one signal', function() {
|
72 | let x = -1;
|
73 |
|
74 | remote.registerSignalHandler('action', (value: number) => x = value);
|
75 |
|
76 | local.signal('action', 1);
|
77 | local.signal('action', 2);
|
78 |
|
79 | assert(!errorLocal);
|
80 | assert(!errorRemote);
|
81 | assert.strictEqual(x, 2);
|
82 | });
|
83 |
|
84 | test('Handlers can be deregistered', function() {
|
85 | let x = -1;
|
86 |
|
87 | const handler = (value: number) => x = value;
|
88 |
|
89 | remote.registerSignalHandler('action', handler);
|
90 | remote.deregisterSignalHandler('action', handler);
|
91 |
|
92 | local.signal('action', 5);
|
93 |
|
94 | assert(!errorLocal);
|
95 | assert(!errorRemote);
|
96 | assert.strictEqual(x, -1);
|
97 | });
|
98 |
|
99 | test('Transfer is honored', function() {
|
100 | let x = -1;
|
101 | const transfer = [1, 2, 3];
|
102 |
|
103 | remote.registerSignalHandler('action', (value: number) => x = value);
|
104 |
|
105 | local.signal('action', 2, transfer);
|
106 |
|
107 | assert(!errorLocal);
|
108 | assert(!errorRemote);
|
109 | assert.strictEqual(x, 2);
|
110 | assert.strictEqual(transferLocalToRemote, transfer);
|
111 | assert(!transferRemoteToLocal);
|
112 | });
|
113 |
|
114 | });
|
115 |
|
116 | suite('RPC', function() {
|
117 |
|
118 | test('RPC handlers can return values', function() {
|
119 | remote.registerRpcHandler('action', () => 10);
|
120 |
|
121 | return local
|
122 | .rpc('action')
|
123 | .then(result => (
|
124 | assert.strictEqual(result, 10),
|
125 | assert(!errorLocal),
|
126 | assert(!errorRemote)
|
127 | ));
|
128 | });
|
129 |
|
130 | test('RPC handlers can return promises', function() {
|
131 | remote.registerRpcHandler('action', () => new Promise(r => setTimeout(() => r(10), 15)));
|
132 |
|
133 | return local
|
134 | .rpc('action')
|
135 | .then(result => (
|
136 | assert.strictEqual(result, 10),
|
137 | assert(!errorLocal),
|
138 | assert(!errorRemote)
|
139 | ));
|
140 | })
|
141 |
|
142 | test('Promise rejection is transferred', function() {
|
143 | remote.registerRpcHandler('action', () => new Promise((resolve, reject) => setTimeout(() => reject(10), 15)));
|
144 |
|
145 | return local
|
146 | .rpc('action')
|
147 | .then(
|
148 | () => Promise.reject('should have been rejected'),
|
149 | result => (
|
150 | assert.strictEqual(result, 10),
|
151 | assert(!errorLocal),
|
152 | assert(!errorRemote)
|
153 | )
|
154 | );
|
155 | });
|
156 |
|
157 | test('Invalid RPC calls are rejected', function() {
|
158 | return local
|
159 | .rpc('action')
|
160 | .then(
|
161 | () => Promise.reject('should have been rejected'),
|
162 | () => undefined
|
163 | );
|
164 | });
|
165 |
|
166 | test('Invalid RPC calls throw on both ends', function() {
|
167 | return local
|
168 | .rpc('action')
|
169 | .then(
|
170 | () => Promise.reject('should have been rejected'),
|
171 | () => undefined
|
172 | )
|
173 | .then(() => (
|
174 | assert(errorLocal),
|
175 | assert(errorRemote)
|
176 | ));
|
177 | });
|
178 |
|
179 | test('RPC calls time out', function() {
|
180 | remote.registerRpcHandler('action', () => new Promise(r => setTimeout(() => r(10), 100)));
|
181 |
|
182 | return local
|
183 | .rpc('action')
|
184 | .then(
|
185 | () => Promise.reject('should have been rejected'),
|
186 | () => (assert(errorLocal), new Promise(r => setTimeout(r, 100)))
|
187 | )
|
188 | .then(() => assert(errorRemote));
|
189 | });
|
190 |
|
191 | test('Multiple RPC handlers do not interfere', function() {
|
192 | remote.registerRpcHandler('a1', (value: number) => new Promise(r => setTimeout(() => r(value), 30)));
|
193 | remote.registerRpcHandler('a2', (value: number) => 2 * value);
|
194 |
|
195 | return Promise
|
196 | .all([
|
197 | local.rpc('a1', 10),
|
198 | local.rpc('a2', 20)
|
199 | ])
|
200 | .then(([r1, r2]) => (
|
201 | assert.strictEqual(r1, 10),
|
202 | assert.strictEqual(r2, 40),
|
203 | assert(!errorLocal),
|
204 | assert(!errorRemote)
|
205 | ));
|
206 | });
|
207 |
|
208 | test('RPC handler can be deregistered', function() {
|
209 | const handler = () => 10;
|
210 |
|
211 | remote.registerRpcHandler('action', handler);
|
212 | remote.deregisterRpcHandler('action', handler);
|
213 |
|
214 | return local
|
215 | .rpc('action')
|
216 | .then(
|
217 | () => Promise.reject('should have been rejected'),
|
218 | () => (
|
219 | assert(errorLocal),
|
220 | assert(errorRemote)
|
221 | )
|
222 | );
|
223 | });
|
224 |
|
225 | test('Transfer is honored', function() {
|
226 | const transfer = [1, 2, 3];
|
227 |
|
228 | remote.registerRpcHandler('action', () => 10);
|
229 |
|
230 | return local
|
231 | .rpc('action', undefined, transfer)
|
232 | .then(x => (
|
233 | assert.strictEqual(transferLocalToRemote, transfer),
|
234 | assert.strictEqual(x, 10),
|
235 | assert(!errorLocal),
|
236 | assert(!errorRemote)
|
237 | ));
|
238 | });
|
239 |
|
240 | });
|
241 |
|
242 | }); |
\ | No newline at end of file |