1 | var assert = require('assert');
|
2 | var util = require('util');
|
3 | var zetta = require('../zetta');
|
4 | var MemRegistry = require('./fixture/mem_registry');
|
5 | var MemPeerRegistry = require('./fixture/mem_peer_registry');
|
6 |
|
7 | var Device = require('zetta-device');
|
8 | var HttpDevice = require('zetta-http-device');
|
9 | var Scout = require('zetta-scout');
|
10 | var ExampleDevice = require('./fixture/example_driver');
|
11 | var Query = require('calypso').Query;
|
12 |
|
13 | describe('Zetta', function() {
|
14 | var reg = null;
|
15 | var peerRegistry = null;
|
16 |
|
17 | beforeEach(function() {
|
18 | reg = new MemRegistry();
|
19 | peerRegistry = new MemPeerRegistry();
|
20 | });
|
21 |
|
22 | it('should be attached to the zetta as a function', function() {
|
23 | assert.equal(typeof zetta, 'function');
|
24 | });
|
25 |
|
26 | it('has the name set using the name() function.', function() {
|
27 | var z = zetta({ registry: reg, peerRegistry: peerRegistry }).name('local').silent();
|
28 | assert.equal(z._name, 'local');
|
29 | });
|
30 |
|
31 | it('should throw error if setting name to *', function() {
|
32 | assert.throws(function() {
|
33 | var z = zetta({ registry: reg, peerRegistry: peerRegistry }).name('*').silent();
|
34 | }, Error);
|
35 | });
|
36 |
|
37 | it('has the silent() function to suppress logging.', function() {
|
38 | var z = zetta({ registry: reg, peerRegistry: peerRegistry }).name('local').silent();
|
39 | });
|
40 |
|
41 | it('errors thrown in zetta apps should propagate.', function(done) {
|
42 | var d = require('domain').create();
|
43 | d.on('error', function(err) {
|
44 | assert.equal(err.message, '123');
|
45 | done();
|
46 | });
|
47 | d.run(function() {
|
48 | zetta()
|
49 | .silent()
|
50 | .use(ExampleDevice)
|
51 | .use(function(server) {
|
52 | var ledQuery = server.where({ type: 'testdriver' });
|
53 | server.observe(ledQuery, function(led) {
|
54 | throw new Error('123');
|
55 | })
|
56 | })
|
57 | .listen(0);
|
58 | });
|
59 | });
|
60 |
|
61 | it('has the logger() function to pass in custom logging.', function(done) {
|
62 | var z = zetta({ registry: reg, peerRegistry: peerRegistry });
|
63 | z.logger(function(log) {
|
64 | log.on('message', function(level, event, msg, data) {
|
65 | assert.equal(level, 'info');
|
66 | assert.equal(event, 'custom');
|
67 | assert.equal(msg, 'some message');
|
68 | assert.equal(data.data, 1);
|
69 | done();
|
70 | });
|
71 |
|
72 | z.log.info('custom', 'some message', {data: 1});
|
73 | });
|
74 | });
|
75 |
|
76 |
|
77 | it('will load an app with the load() function', function(done) {
|
78 | zetta({ registry: reg, peerRegistry: peerRegistry })
|
79 | .silent()
|
80 | .load(function(server) {
|
81 | assert.ok(server);
|
82 | done();
|
83 | })
|
84 | ._initApps(function(){});
|
85 | });
|
86 |
|
87 | it('will load an app with the use() function', function(done) {
|
88 | zetta({ registry: reg, peerRegistry: peerRegistry })
|
89 | .silent()
|
90 | .use(function(server) {
|
91 | assert.ok(server);
|
92 | done();
|
93 | })
|
94 | ._initApps(function(){});
|
95 | });
|
96 |
|
97 | it('will load an app with the use() function and additional arguments', function(done) {
|
98 | var app = function(server, opts) {
|
99 | assert.ok(server);
|
100 | assert.ok(opts);
|
101 | assert.equal(opts.foo, 1);
|
102 | done();
|
103 | }
|
104 |
|
105 | zetta({ registry: reg, peerRegistry: peerRegistry })
|
106 | .silent()
|
107 | .use(app, { foo: 1})
|
108 | ._initApps(function() {
|
109 |
|
110 | });
|
111 |
|
112 | });
|
113 |
|
114 | it('will load an app with the use() function and additional arguments', function(done) {
|
115 | var app = function(server, foo, bar) {
|
116 | assert.ok(server);
|
117 | assert.equal(foo, 1);
|
118 | assert.equal(bar, 2);
|
119 | done();
|
120 | }
|
121 |
|
122 | zetta({ registry: reg, peerRegistry: peerRegistry })
|
123 | .silent()
|
124 | .use(app, 1, 2)
|
125 | ._initApps(function() {
|
126 |
|
127 | });
|
128 |
|
129 | });
|
130 | it('will load a driver with the use() function', function() {
|
131 | var z = zetta({ registry: reg, peerRegistry: peerRegistry }).silent();
|
132 | function TestDriver() {
|
133 | Device.call(this);
|
134 | }
|
135 | util.inherits(TestDriver, Device);
|
136 |
|
137 | TestDriver.prototype.init = function() {};
|
138 |
|
139 | z.use(TestDriver);
|
140 | var s = z._scouts[0];
|
141 | assert.equal(s.server, z.runtime);
|
142 | });
|
143 |
|
144 | it('will load an HTTP driver with the use() function', function() {
|
145 | var z = zetta({ registry: reg, peerRegistry: peerRegistry }).silent();
|
146 | function TestDriver() {
|
147 | HttpDevice.call(this);
|
148 | }
|
149 | util.inherits(TestDriver, HttpDevice);
|
150 |
|
151 | TestDriver.prototype.init = function() {};
|
152 |
|
153 | z.use(TestDriver);
|
154 | var s = z._scouts[0];
|
155 | assert.equal(s.server, z.runtime);
|
156 | });
|
157 |
|
158 | it('will load a scout with the use() function', function() {
|
159 | var z = zetta({ registry: reg, peerRegistry: peerRegistry }).silent();
|
160 | function TestScout() {
|
161 | Scout.call(this);
|
162 | }
|
163 | util.inherits(TestScout, Scout);
|
164 | z.use(TestScout);
|
165 | assert.equal(z._scouts.length, 2);
|
166 | var s = z._scouts[0];
|
167 | assert.equal(s.server, z.runtime);
|
168 | });
|
169 |
|
170 | it('will set the what query is used for expose()', function() {
|
171 | var z = zetta({ registry: reg, peerRegistry: peerRegistry }).silent();
|
172 | z.expose('*');
|
173 |
|
174 | assert.ok(z._exposeQuery);
|
175 | });
|
176 |
|
177 | it('will call init on the server prototype to ensure everything is wired up correctly.', function(done) {
|
178 | function MockHttp(){}
|
179 | MockHttp.prototype.init = function() {
|
180 | done();
|
181 | };
|
182 | MockHttp.prototype.listen = function(port) {};
|
183 |
|
184 | var z = zetta({ registry: reg, peerRegistry: peerRegistry }).silent();
|
185 | z.httpServer = new MockHttp();
|
186 | z.listen(0);
|
187 |
|
188 | });
|
189 |
|
190 | it('will apply arguments to httpServer when listen() is called', function(done) {
|
191 | function MockHttp(){}
|
192 | MockHttp.prototype.init = function(){};
|
193 | MockHttp.prototype.listen = function(port) {
|
194 | assert.equal(port, 0);
|
195 | done();
|
196 | };
|
197 |
|
198 | var z = zetta({ registry: reg, peerRegistry: peerRegistry }).silent();
|
199 | z.httpServer = new MockHttp();
|
200 | z.listen(0);
|
201 |
|
202 | });
|
203 |
|
204 | it('will correctly apply the callback to httpServer when listen() is called', function(done) {
|
205 | function MockHttp(){}
|
206 | MockHttp.prototype.init = function(){};
|
207 | MockHttp.prototype.listen = function(port, cb) {
|
208 | assert.equal(port, 0);
|
209 | cb(null);
|
210 | };
|
211 |
|
212 | var z = zetta({ registry: reg, peerRegistry: peerRegistry }).silent();
|
213 | z.httpServer = new MockHttp();
|
214 | z.listen(0, function(err) {
|
215 | assert.ok(!err);
|
216 | done();
|
217 | });
|
218 | });
|
219 |
|
220 | it('should initialize device with proper properties set.', function(done) {
|
221 | var z = zetta({ registry: reg, peerRegistry: peerRegistry })
|
222 | .silent()
|
223 | .use(ExampleDevice, 1, 'a')
|
224 | ._run(function(err) {
|
225 | if (err) {
|
226 | return done(err);
|
227 | }
|
228 |
|
229 | var device = z.runtime._jsDevices[Object.keys(z.runtime._jsDevices)[0]];
|
230 | device.call('change', done);
|
231 | });
|
232 | });
|
233 |
|
234 | it('should initialize 3 devices with correct params when using multiple use', function(done) {
|
235 | var z = zetta({ registry: reg, peerRegistry: peerRegistry })
|
236 | .silent()
|
237 | .use(ExampleDevice, 1, 'a')
|
238 | .use(ExampleDevice, 2, 'b')
|
239 | .use(ExampleDevice, 3, 'c')
|
240 | ._run(function(err) {
|
241 | if (err) {
|
242 | return done(err);
|
243 | }
|
244 |
|
245 | var find = function(x, y) {
|
246 | return Object.keys(z.runtime._jsDevices).some(function(key){
|
247 | var device = z.runtime._jsDevices[key];
|
248 | return device._x === x && device._y === y;
|
249 | });
|
250 | };
|
251 |
|
252 | assert(find(1, 'a'));
|
253 | assert(find(2, 'b'));
|
254 | assert(find(3, 'c'));
|
255 |
|
256 | done();
|
257 | });
|
258 | });
|
259 |
|
260 |
|
261 |
|
262 | it('should provision 3 devices already in registry with correct params when using multiple use', function(done) {
|
263 | var z = zetta({ registry: reg, peerRegistry: peerRegistry })
|
264 | .silent()
|
265 | .use(ExampleDevice, 1, 'a')
|
266 | .use(ExampleDevice, 2, 'b')
|
267 | .use(ExampleDevice, 3, 'c')
|
268 | ._run(function(err) {
|
269 | if (err) {
|
270 | return done(err);
|
271 | }
|
272 |
|
273 | var find = function(x, y) {
|
274 | var id = null;
|
275 | Object.keys(z.runtime._jsDevices).some(function(key){
|
276 | var device = z.runtime._jsDevices[key];
|
277 | if (device._x === x && device._y === y) {
|
278 | id = device.id;
|
279 | return true;
|
280 | }
|
281 | });
|
282 |
|
283 | return id;
|
284 | };
|
285 |
|
286 | assert(find(1, 'a'));
|
287 | assert(find(2, 'b'));
|
288 | assert(find(3, 'c'));
|
289 |
|
290 | var z2 = zetta({ registry: reg, peerRegistry: peerRegistry })
|
291 | .silent()
|
292 | .use(ExampleDevice, 1, 'a')
|
293 | .use(ExampleDevice, 2, 'b')
|
294 | .use(ExampleDevice, 3, 'c')
|
295 | ._run(function(err) {
|
296 | if (err) {
|
297 | return done(err);
|
298 | }
|
299 |
|
300 | var find2 = function(id, x, y) {
|
301 | return Object.keys(z2.runtime._jsDevices).some(function(key){
|
302 | var device = z2.runtime._jsDevices[key];
|
303 | return device.id === id && device._x === x && device._y === y;
|
304 | });
|
305 | };
|
306 |
|
307 | assert(find2(find(1, 'a'), 1, 'a'));
|
308 | assert(find2(find(2, 'b'), 2, 'b'));
|
309 | assert(find2(find(3, 'c'), 3, 'c'));
|
310 | done();
|
311 | });
|
312 | });
|
313 | });
|
314 |
|
315 | it('should only call .init once on a device driver with .use(Device)', function(done) {
|
316 | var called = 0;
|
317 | var oldInit = ExampleDevice.prototype.init;
|
318 | ExampleDevice.prototype.init = function(config) {
|
319 | called++;
|
320 | return oldInit.call(this, config);
|
321 | };
|
322 |
|
323 | var app = zetta({ peerRegistry: peerRegistry, registry: reg });
|
324 | app.silent();
|
325 | app.use(ExampleDevice);
|
326 | app.listen(0);
|
327 | setTimeout(function() {
|
328 | ExampleDevice.prototype.init = oldInit;
|
329 | assert.equal(called, 1);
|
330 | done();
|
331 | }, 10);
|
332 | });
|
333 |
|
334 | describe('peering', function() {
|
335 | it('.link should add to peers', function(done){
|
336 | var app = zetta({ peerRegistry: peerRegistry, registry: reg });
|
337 | app.silent();
|
338 | app.link('http://example.com/');
|
339 | app._initPeers(app._peers, function(err) {
|
340 | setTimeout(function() {
|
341 | assert.equal(app._peerClients.length, 1);
|
342 | done();
|
343 | }, 100);
|
344 | });
|
345 | });
|
346 |
|
347 | it('.link should not add to peers', function(done){
|
348 |
|
349 | peerRegistry.db.put('1234567', JSON.stringify({id: '1234567', direction: 'initiator', url: 'http://example.com/', fromLink: true}), function(err){
|
350 | var app = zetta({ peerRegistry: peerRegistry, registry: reg });
|
351 | app.silent();
|
352 | app._initPeers(app._peers, function(err) {
|
353 | setTimeout(function() {
|
354 | assert.equal(app._peerClients.length, 0);
|
355 | done();
|
356 | }, 100);
|
357 | });
|
358 | });
|
359 | });
|
360 |
|
361 | it('will delete fromLink peers in the registry', function(done) {
|
362 | peerRegistry.db.put('1234567', JSON.stringify({ id:'1234567', direction: 'initiator', url: 'http://example.com/', fromLink: true}), function(err) {
|
363 | var app = zetta({ peerRegistry: peerRegistry, registry: reg });
|
364 | app._initPeers(app._peers, function(err) {
|
365 | setTimeout(function(){
|
366 | assert.equal(app._peerClients.length, 0);
|
367 | peerRegistry.find(Query.of('peers'), function(err, results) {
|
368 | assert.equal(results.length, 0);
|
369 | done();
|
370 | });
|
371 | }, 100);
|
372 | });
|
373 | });
|
374 |
|
375 | });
|
376 |
|
377 | it('will init API peers.', function(done){
|
378 |
|
379 | peerRegistry.db.put('1234567', JSON.stringify({id: '1234567', direction: 'initiator', url: 'http://example.com/'}), function(err){
|
380 | var app = zetta({ peerRegistry: peerRegistry, registry: reg });
|
381 | app.silent();
|
382 | app._initPeers(app._peers, function(err) {
|
383 | setTimeout(function() {
|
384 | assert.equal(app._peerClients.length, 1);
|
385 | done();
|
386 | }, 100);
|
387 | });
|
388 | });
|
389 | });
|
390 |
|
391 | });
|
392 |
|
393 | it('has the properties() function to add custom properties to the api.', function() {
|
394 | var z = zetta({ registry: reg, peerRegistry: peerRegistry });
|
395 | assert(typeof z.properties, 'function');
|
396 | z.properties({ test: 'abc' });
|
397 | });
|
398 |
|
399 | it('.getProperties() returns properties.', function() {
|
400 | var z = zetta({ registry: reg, peerRegistry: peerRegistry }).name('test');
|
401 | z.properties({ someKey: 123 });
|
402 | assert.deepEqual(z.getProperties(), { name: 'test', someKey: 123 });
|
403 | });
|
404 |
|
405 | });
|