UNPKG

7.52 kBPlain TextView Raw
1/// <reference path="../typings/index.d.ts"/>
2
3import * as assert from 'assert';
4
5import RpcProvider from '../src/RpcProvider';
6
7suite('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