statebus 6.2.3 → 6.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/client.js +2 -2
  2. package/extras/tests.js +60 -0
  3. package/package.json +9 -2
  4. package/server.js +4 -4
  5. package/statebus.js +39 -7
  6. package/extras/#test_save_delay.js# +0 -11
  7. package/extras/abort-test.html +0 -10
  8. package/extras/abort-test.js +0 -17
  9. package/extras/backups/db.2021-11-13 +0 -12
  10. package/extras/backups/db.2021-11-14 +0 -12
  11. package/extras/backups/db.2021-11-15 +0 -25
  12. package/extras/backups/db.2021-11-16 +0 -25
  13. package/extras/backups/db.2022-01-14 +0 -24
  14. package/extras/backups/db.2022-01-15 +0 -29
  15. package/extras/backups/db.2022-01-16 +0 -29
  16. package/extras/backups/db.2022-01-17 +0 -29
  17. package/extras/backups/db.2022-01-18 +0 -29
  18. package/extras/backups/db.2022-01-19 +0 -29
  19. package/extras/backups/db.2022-01-20 +0 -32
  20. package/extras/backups/db.2022-01-21 +0 -32
  21. package/extras/backups/db.2022-01-22 +0 -47
  22. package/extras/backups/db.2022-01-23 +0 -47
  23. package/extras/backups/db.2022-02-20 +0 -53
  24. package/extras/backups/db.2022-09-08 +0 -48
  25. package/extras/backups/db.2022-09-09 +0 -48
  26. package/extras/backups/db.2022-09-10 +0 -48
  27. package/extras/backups/db.2022-09-11 +0 -48
  28. package/extras/backups/db.2022-09-12 +0 -48
  29. package/extras/backups/db.2022-09-13 +0 -48
  30. package/extras/backups/db.2022-09-14 +0 -48
  31. package/extras/backups/pdb.2017-08-21 +0 -46
  32. package/extras/braid-client.html +0 -12
  33. package/extras/braid-client2.html +0 -9
  34. package/extras/braid-client3.html +0 -0
  35. package/extras/braid-server.js +0 -37
  36. package/extras/braid-server2.js +0 -35
  37. package/extras/chokitest.js +0 -142
  38. package/extras/clientless.js +0 -4
  39. package/extras/css.html +0 -4
  40. package/extras/ct.js +0 -24
  41. package/extras/ctests.js +0 -8
  42. package/extras/db +0 -48
  43. package/extras/ds.html +0 -8
  44. package/extras/ds.js +0 -17
  45. package/extras/email.html +0 -12
  46. package/extras/express-experiment.js +0 -15
  47. package/extras/f.js +0 -21
  48. package/extras/file-test.js +0 -12
  49. package/extras/flash.html +0 -8
  50. package/extras/flash.js +0 -7
  51. package/extras/fullnode-test.html +0 -4
  52. package/extras/fullnode-test.js +0 -26
  53. package/extras/hello-react/index.html +0 -24
  54. package/extras/hello-react.html +0 -4
  55. package/extras/hello.html +0 -4
  56. package/extras/k.js +0 -12
  57. package/extras/load-from-file.html +0 -4
  58. package/extras/multi-chat/1.html +0 -39
  59. package/extras/multicriteria +0 -52054
  60. package/extras/nested +0 -425965
  61. package/extras/new-react.html +0 -20
  62. package/extras/pdb +0 -46
  63. package/extras/perf.js +0 -68
  64. package/extras/perf2.js +0 -69
  65. package/extras/perf3.js +0 -14
  66. package/extras/pgt.js +0 -61
  67. package/extras/pointers-test.js +0 -17
  68. package/extras/pointers-test2.js +0 -83
  69. package/extras/ptest.js +0 -19
  70. package/extras/react-example.html +0 -32
  71. package/extras/react-example.jsx.html +0 -41
  72. package/extras/react.12.js +0 -18116
  73. package/extras/react.12.min.js +0 -16
  74. package/extras/react.15.min.js +0 -28
  75. package/extras/react.3.min.js +0 -19
  76. package/extras/remote-hello.html +0 -9
  77. package/extras/reset_pass.coffee +0 -101
  78. package/extras/reset_pass.html +0 -116
  79. package/extras/rocks-test.js +0 -6
  80. package/extras/s4.js +0 -2
  81. package/extras/sbdb +0 -4
  82. package/extras/slideboard +0 -4
  83. package/extras/smaller-file.js +0 -8
  84. package/extras/sqls-test.js +0 -6
  85. package/extras/stateb.us.coffee +0 -92
  86. package/extras/syncie.html +0 -31
  87. package/extras/syncie.js +0 -15
  88. package/extras/test2.js +0 -48
  89. package/extras/test_client.html +0 -8
  90. package/extras/test_client.js +0 -19
  91. package/extras/test_save_delay.js +0 -11
  92. package/extras/test_timeouts.js +0 -10
  93. package/extras/tests-val.js +0 -1572
  94. package/extras/tests.html +0 -5
  95. package/extras/uni.js +0 -7
  96. package/extras/usage_test.html +0 -3
  97. package/extras/usage_test.js +0 -32
  98. package/extras/vtest.js +0 -17
@@ -1,1572 +0,0 @@
1
- bus = require('../statebus')()
2
- util = require('util')
3
- fs = require('fs')
4
- bus.label = 'bus'
5
- statelog_indent++
6
-
7
- // Include the test functions
8
- var {test, run_tests, log, assert, delay} = require('../statebus').testing
9
-
10
- // Make sure we have all the npm packages installed
11
- try {
12
- var reqs = 'sockjs chokidar websocket bcrypt-nodejs'.split(' ')
13
- for (var i=0; i<reqs.length; i++) require(reqs[i])
14
- } catch (e) {
15
- console.log(e)
16
- console.warn('#### Yo! You need to run "npm install sockjs chokidar websocket bcrypt-nodejs"')
17
- process.exit()
18
- }
19
-
20
-
21
- // Equality tests
22
- test(function equality (done) {
23
- var equality_tests = [
24
- [1, 1, true],
25
- [1, 3, false],
26
- [NaN, NaN, true],
27
- [NaN, undefined, false],
28
- [null, {}, false],
29
- [null, null, true],
30
- [[], [], true],
31
- [{}, [], false],
32
- [{}, {}, true],
33
- [[1], [], false],
34
- [[1], [1], true],
35
- [[1], [1, 1], false],
36
- [[{}], [{}], true],
37
- [{a:[]}, {a:[]}, true],
38
- [{a:[]}, {}, false],
39
- [[[[]]], [[[]]], true],
40
- [[[[]]], [[[[]]]], false],
41
- [[[{a:3,b:4}]], [[{b:4,a:3}]], true],
42
- [[[{a:3,b:4}]], [[{b:4,a:4}]], false],
43
- [function () {}, function () {}, false],
44
- [require, require, true],
45
- [require, function () {}, false],
46
- [{key:'f'}, {key:'f'}, true]
47
- ]
48
-
49
- for (var i=0; i<equality_tests.length; i++) {
50
- assert(bus.deep_equals(equality_tests[i][0],
51
- equality_tests[i][1])
52
- === equality_tests[i][2],
53
- 'Equality test failed forward', equality_tests[i])
54
-
55
- assert(bus.deep_equals(equality_tests[i][1],
56
- equality_tests[i][0])
57
- === equality_tests[i][2],
58
- 'Equality test failed backward', equality_tests[i])
59
- }
60
-
61
- done()
62
- })
63
-
64
- test(function validation (done) {
65
- var v_tests = [
66
- ['something', 'string', true],
67
- ['something', 'something', true],
68
- ['something', 3, false],
69
- [3, 3, true],
70
- [3, 'number', true],
71
- [3, 'string', false],
72
- [3, {}, false],
73
- [3, [], false],
74
- [{}, {}, true],
75
- [{}, {'key': 'string'}, false],
76
- [{}, {'?key': 'string'}, true],
77
- [{key: 3}, {'?key': 'string'}, false],
78
- [{key: '/foo'}, {key: 'string'}, true],
79
- [{a: 2, b: [], c: 'foo'}, {a: 'number', b: 'array', c: 'string'}, true],
80
- [{a: 2, b: [], c: 'foo', d: false}, {a: 'number', b: 'array', c: 'string'}, false],
81
- [{a: false}, {a: 'boolean'}, true],
82
- [{a: 1, b: 2}, {a: 1}, false],
83
- [{a: 1, b: 2}, {a: 1, '*':'*'}, true],
84
- [{a: 2, b: 2}, {a: 1, '*':'*'}, false]
85
- ]
86
-
87
- for (var i=0; i<v_tests.length; i++)
88
- assert(bus.validate(v_tests[i][0], v_tests[i][1]) === v_tests[i][2],
89
- 'Validation test failed', v_tests[i])
90
-
91
- done()
92
- })
93
-
94
- test(function applying_patches (done) {
95
- var tests = [
96
- ['0', '[0] = "1"', '1'],
97
- [['0'], '[0] = "1"', ['1']],
98
- [['0'], '[0] = [1]', [[1]]],
99
- ['', '[0:0] = "something"', 'something'],
100
- ['hello', '[-0:-0] = " there"', 'hello there'],
101
- [{}, '.foo = "bar"', {foo: 'bar'}],
102
- [{a:1}, '.a = true', {a: true}],
103
- [[1,2,3], '[1:1] = [4, 5, 6]', [1, 4, 5, 6, 2, 3]],
104
- [[1,2,3], '[-0:-0] = 0', [1, 2, 3, 0]],
105
- [[1,2,3], '[-1] = 0', [1, 2, 0]],
106
- [[1,2,3], '[-1:-0] = [0]', [1, 2, 0]],
107
- [[1,2,3], '[-1:-0] = [0, 0, 0]', [1, 2, 0, 0, 0]]
108
- ]
109
-
110
- for (var i=0; i<tests.length; i++) {
111
- var x = bus.apply_patch(tests[i][0], tests[i][1])
112
- assert(bus.deep_equals(x, tests[i][2]),
113
- `Patch applied wrong ${JSON.stringify(tests[i])} got ${x}`)
114
- }
115
- done()
116
- })
117
-
118
- test(function prune (done) {
119
- var boose = require('../statebus')()
120
- boose.set({key: 'nark', val: 333666})
121
- var a = {key: 'funny',
122
- b: {key: 'farty', booger: 3}}
123
- assert(!boose.prune(a).b.booger)
124
- var b = {key: 'farty',
125
- a: a,
126
- arr: [1, 3, a, {key: 'nark', ___: 999}]}
127
- done()
128
- })
129
-
130
- test(function auto_vars (done) {
131
- var n = require('../statebus')()
132
- n('r/*').to_get = function (rest, o) {return {rest: rest, o: o}}
133
- log(n.get('r/3'))
134
- assert(n.get('r/3').rest === '3')
135
- assert(n.get('r/3').o === undefined)
136
-
137
- n('v/*').to_get = function (vars, star) {return {vars: vars, rest: star}}
138
- log(n.get('v/[3,9 4]').rest)
139
- log(n.get('v/[3,9 4]').rest.match(/$Bad/))
140
- assert(n.get('v/[3,9 4]').rest === '[3,9 4]')
141
-
142
- log(n.get('v/[3,9 4]').vars)
143
- log(n.get('v/[3,9 4]').vars.match(/^Bad/))
144
- assert(n.get('v/[3,9 4]').vars.match(/^Bad/))
145
- assert(Array.isArray(n.get('v/[3,4]').vars))
146
-
147
- n('a/*').to_set = function (t, k, obj) {
148
- log('k:', k, 't:', t, 'o:', obj)
149
- assert(k === 'a/foo')
150
- assert(typeof obj === 'object')
151
- assert(obj.i >= 0 && obj.i <= 4)
152
- assert(Object.keys(obj).length === 2)
153
- assert(t.version)
154
- t.done()
155
- }
156
- for (var i=0; i<4; i++)
157
- n.set({key: 'a/foo', i:i})
158
-
159
- log('Forgetting things now')
160
- n('v/*').to_forget = function (vars, star) {log('(from auto_vars) forgot v/' + star)}
161
- n.forget('v/[3,9 4]')
162
- n.forget('v/[3,4]')
163
-
164
- done()
165
- })
166
-
167
- test(function serve_options (done) {
168
- var filename = 'test1.db', backups = 'test1.backups', certs = 'testcerts'
169
-
170
- // Remove old stuff if there
171
- try {
172
- // rm db
173
- fs.unlinkSync(filename)
174
-
175
- // rm -r backups
176
- fs.readdirSync(backups).forEach((f) => {
177
- fs.unlinkSync(backups + "/" + f);
178
- })
179
- fs.rmdirSync(backups)
180
-
181
- // // rm -r certs
182
- // fs.readdirSync(certs).forEach((f) => {
183
- // fs.unlinkSync(certs + "/" + f);
184
- // })
185
- // fs.rmdirSync(certs)
186
- } catch (e) {log(e)}
187
-
188
- var b = require('../statebus').serve({
189
- port: 31829,
190
- //file_store: false,
191
- file_store: {filename: filename, save_delay: 0, backup_dir: backups},
192
- certs: {private_key: certs+'/pk', certificate: certs+'/cert'},
193
- })
194
-
195
- b.set({key: 'foo', body: 'is this on disk?'})
196
- setTimeout(() => done(), 60)
197
- })
198
-
199
- test(function transactions (done) {
200
- var bus = require('../statebus')()
201
- bus.honk = 'statelog'
202
- bus.label = 'tranny'
203
-
204
- // Test to_get handlers with t.done()
205
- bus('foo1').to_get = function (t) {
206
- log('to_geting foo1')
207
- setTimeout(()=>{
208
- log('returning something for foo1')
209
- t.done({something: 'yeah'})
210
- }, 0)
211
- }
212
- var foo1 = bus.get('foo1')
213
- assert(!foo1.something)
214
- setTimeout(() => { log('test foo1'); assert(foo1.something === 'yeah') }, 10)
215
-
216
- // And return a value directly
217
- bus('foo2').to_get = (t) => { return {something: 'yeah'} }
218
- var foo2 = bus.get('foo2')
219
- setTimeout(() => { log('test foo2'); assert(foo2.something === 'yeah') }, 10)
220
-
221
-
222
- // Set up some rocks
223
- log('Set up some rocks')
224
- bus.set({key: 'rock1', a:1})
225
- bus.set({key: 'rock2', a:1})
226
- bus.set({key: 'softrock1', a:1})
227
- bus.set({key: 'softrock2', a:1})
228
-
229
- // Test to_set handlers with t.done(o), t.abort, 'done', 'abort'
230
- bus('rock1').to_set = (t) => {setTimeout(()=>{ t.abort() }, 0)}
231
- bus('rock2').to_set = ( ) => {return 'abort'}
232
- bus('softrock1').to_set = (t) => {setTimeout(()=>{ t.done() }, 0)}
233
- bus('softrock2').to_set = ( ) => {return 'done'}
234
-
235
- //bus.honk = true
236
- setTimeout(() => {
237
- log('Set some changes')
238
- bus.set({key: 'rock1', a:2})
239
- bus.set({key: 'rock2', a:2})
240
- bus.set({key: 'softrock1', a:2})
241
- bus.set({key: 'softrock2', a:2})
242
-
243
- setTimeout(() => {
244
- log('Check if the sets worked...')
245
- assert(bus.cache.rock1.a == 1)
246
- assert(bus.cache.rock2.a == 1)
247
- assert(bus.cache.softrock1.a == 2)
248
- assert(bus.cache.softrock2.a == 2)
249
-
250
- // Test the delete handlers with t.done(o), t.abort, 'done', 'abort'
251
- log("Now let's delete")
252
- bus('rock1').to_delete = (t) => {setTimeout(()=>{ t.abort() }, 0)}
253
- bus('rock2').to_delete = ( ) => {return 'abort'}
254
- bus('softrock1').to_delete = (t) => {setTimeout(()=>{ t.done() }, 0)}
255
- bus('softrock2').to_delete = ( ) => {return 'done'}
256
-
257
- log('Delete some rocks')
258
- bus.delete('rock1')
259
- bus.delete('rock2')
260
- bus.delete('softrock1')
261
- bus.delete('softrock2')
262
-
263
- setTimeout(() => {
264
- log("Test if the deletes worked")
265
- assert(bus.cache.rock1)
266
- assert(bus.cache.rock2)
267
- assert(!bus.cache.softrock1)
268
- assert(!bus.cache.softrock2)
269
- done()
270
- }, 10)
271
-
272
- }, 10)
273
- }, 20)
274
- })
275
-
276
- test(function url_translation (done) {
277
- var tests = [
278
- ['foo', 'foo'],
279
- [['a', 'b'], ['a', 'b']],
280
- [{key: 'a'}, {key: '/a'}],
281
- [{key: 'a', f: '3'}, {key: '/a', f: '3'}],
282
- [{a: {b: {key: 'a'}}}, {a: {b: {key: '/a'}}}],
283
- [{a: {b: {_key: ['a', 'b']}}}, {a: {b: {_key: ['/a', '/b']}}}],
284
- [{a: {b: {bombs_key: ['a', 1]}}}, {a: {b: {bombs_key: ['/a', 1]}}}],
285
- [{a: {b: {_key: ['a', {_key: 'b'}]}}}, {a: {b: {_key: ['/a', {_key: '/b'}]}}}],
286
- [{a: ['a', {_key: 'b'}]}, {a: ['a', {_key: '/b'}]}],
287
- ]
288
- for (var i=0; i<tests.length; i++) {
289
- log('Testing', i, JSON.stringify(tests[i][0]))
290
- var trans = bus.translate_keys(tests[i][0], function (k) {return '/' + k})
291
- assert(bus.deep_equals(trans, tests[i][1]),
292
- 'Bad translation: ' + JSON.stringify(trans))
293
- }
294
- done()
295
- })
296
-
297
- test(function basics (done) {
298
- bus('basic wait').to_get = function () {
299
- setTimeout(function () {bus.set.fire({key:'basic wait', a:1})},
300
- 30)
301
- }
302
-
303
- var count = 0
304
- bus(function () {
305
- var v = bus.get('basic wait')
306
- log('On round', count, 'we see', v)
307
- if (count == 0)
308
- assert(!v.a)
309
- if (count == 1) {
310
- assert(v.a)
311
- bus.forget()
312
- done()
313
- }
314
- count++
315
- })
316
- })
317
-
318
- // Multi-handlers
319
- test(function multiple_handlers1 (done) {
320
- var cuss = require('../statebus')()
321
- cuss('foo').to_get = () => {log('do nothing 1')}
322
- cuss('foo').to_get = () => {log('do nothing 2')}
323
- cuss('foo').to_get = () => (log('doing something'),{b: 3})
324
- cuss.get('foo', (o) => {
325
- log('Multi-handle got', o)
326
- cuss.forget()
327
- setTimeout(()=>{done()})
328
- })
329
- })
330
-
331
- test(function multiple_handlers2 (done) {
332
- var cuss = require('../statebus')()
333
- cuss('foo').to_set = (o) => {log('do nothing 1')}
334
- cuss('foo').to_set = (o) => {log('do nothing 2')}
335
- cuss('foo').to_set = (o) => {log('doin something'); cuss.set.fire(o)}
336
- //cuss('foo').to_set = (o) => {log('doin abortion'); cuss.set.abort(o)}
337
- cuss.set({key: 'foo', b: 55})
338
- log('over and out')
339
- setTimeout(()=>{done()})
340
- })
341
-
342
- // Callbacks are reactive
343
- test(function get_with_callback (done) {
344
- var count = 0
345
-
346
- function bbs() {
347
- return bus.bindings('bar', 'on_set').map(
348
- function (f){return bus.funk_name(f)})
349
- }
350
- function cb (o) {
351
- count++
352
- // log(bbs().length + ' bindings in cb before get')
353
- var bar = bus.get('bar')
354
- log('cb called', count, 'times', 'bar is', bar, 'foo is', o)
355
- // log(bbs().length + ' bindings in cb after get')
356
- }
357
-
358
- // log(bbs().length+ ' bindings to start')
359
-
360
- // Get a foo
361
- bus.get('foo', cb) // Call 1
362
-
363
- // Fire a foo
364
- setTimeout(function () {
365
- assert(count === 1, '1!=' + count)
366
- // log(bbs().length + ' bindings after first get')
367
-
368
- log('firing a new foo')
369
- // log(bbs().length + ' bindings')
370
- bus.set.fire({key: 'foo', count:count}) // Call 2
371
- }, 30)
372
-
373
- // Fire a bar, which the callback depends on
374
- setTimeout(function () {
375
- log('firing a new bar')
376
- // log(bbs().length+ ' bindings')
377
- assert(count === 2, '2!=' + count)
378
- bus.honk = true
379
- bus.set.fire({key: 'bar', count:count}) // Call 3
380
- log('fired the new bar')
381
- //log(bus.bindings('bar', 'on_set'))
382
- }, 50)
383
-
384
- // Done
385
- setTimeout(function () {
386
- assert(count === 2, '2!=' + count)
387
- bus.forget('foo', cb)
388
- //bus.forget('bar', cb)
389
- done()
390
- }, 100)
391
- })
392
-
393
- test(function get_once (done) {
394
- var calls = 0
395
- bus.get('get_once', function cb (o) {
396
- calls++
397
- log('Get_once called', calls)
398
- assert(calls < 2, 'Get-once called twice')
399
- bus.forget('get_once', cb)
400
- })
401
- bus.set.fire({key: 'get_once', _: 0})
402
- setTimeout(()=> { bus.set.fire({key: 'get_once', _: 1}) }, 10)
403
- setTimeout(()=> { bus.set.fire({key: 'get_once', _: 2}) }, 20)
404
- setTimeout(()=> { done() }, 30 )
405
- })
406
-
407
- test(function once (done) {
408
- bus('takeawhile').to_get = (t) => {
409
- setTimeout(_=> t.return({_: 3}), 150)
410
- }
411
- bus.once(_=> {
412
- var x = bus.get('takeawhile')
413
- var y = bus.get('changing')
414
- log('running the once func! loading is', bus.loading())
415
- assert(!bus.cache.certified)
416
- bus.set({key: 'whendone', certified: true})
417
- })
418
-
419
- delay(50, _=> assert(!bus.get('whendone').certified))
420
- delay(10, _=> bus.set({key: 'changing', _: 1}))
421
- delay(10, _=> bus.set({key: 'changing', _: 2}))
422
- delay(150, _=> assert(bus.get('whendone').certified))
423
- delay(10, _=> bus.set({key: 'changing', _: 3}))
424
- delay(10, _=> bus.set({key: 'changing', _: 4}))
425
- delay(30, _=> done())
426
- })
427
-
428
- // If there's an on_get handler, the callback doesn't return
429
- // until the handler fires a value
430
- test(function get_remote (done) {
431
- var count = 0
432
-
433
- // The moon responds in 30ms
434
- bus('moon').to_get =
435
- function (k) { setTimeout(function () {bus.set.fire({key:k})},30) }
436
- function cb (o) {
437
- count++
438
- var moon = bus.get('hey over there')
439
- log('cb called', count, 'times')
440
- }
441
-
442
- // Get a moon
443
- bus.get('moon', cb) // Doesn't call back yet
444
- assert(count === 0, '0!=' + count)
445
-
446
- // There should be a moonshot by now
447
- setTimeout(function () {
448
- assert(count === 1, '1!=' + count)
449
- bus.forget('moon', cb)
450
- done()
451
- }, 50)
452
- })
453
-
454
- // Multiple batched fires might trigger duplicate reactions
455
- test(function duplicate_fires (done) {
456
- var calls = new Set()
457
- var count = 0
458
- var dupes = []
459
- function cb (o) {
460
- count++
461
- if (calls.has(o.n)) dupes.push(o.n)
462
- calls.add(o.n)
463
- log('cb called', count, 'times with', calls)
464
- }
465
-
466
- // Get a foo
467
- bus.get('foo', cb) // Call 1
468
- assert(count === 1, '1!=' + count)
469
-
470
- // Fire a foo
471
- setTimeout(function () {
472
- log('Firing a few new foos')
473
- bus.set.fire({key: 'foo', n:0}) // Skipped
474
- bus.set.fire({key: 'foo', n:1}) // Skipped
475
- bus.set.fire({key: 'foo', n:2}) // Skipped
476
- bus.set.fire({key: 'foo', n:3}) // Call 2
477
- log("ok, now let's see what happens.")
478
- }, 30)
479
-
480
- // Done
481
- setTimeout(function () {
482
- assert(count === 2, '2!=' + count)
483
- assert(dupes.length === 0, 'CB got duplicate calls', dupes)
484
- log('Well, that went smoothly!')
485
- bus.forget('foo', cb)
486
- //bus.forget('bar', cb)
487
- done()
488
- }, 60)
489
- })
490
-
491
- // Identity fires shouldn't infinite loop
492
- test(function identity (done) {
493
- var key = 'kooder'
494
- var count = 0
495
- function fire () { bus.set.fire({key: 'kooder', count: count}) }
496
- bus(key).to_get = function () { setTimeout(fire, 10) }
497
- function cb() {
498
- count++
499
- log('cb called', count, 'times')
500
- bus.set.fire(bus.get('new'))
501
- }
502
- bus.get(key, cb)
503
-
504
- // Done
505
- setTimeout(function () {
506
- // Calls:
507
- // 1. Initial call
508
- // 2. First return from pending get
509
- assert(count === 1, 'cb called '+count+'!=1 times')
510
- bus.forget(key, cb)
511
- bus(key).to_get.delete(fire)
512
- done()
513
- }, 40)
514
- })
515
-
516
-
517
- // bus.forget() within a callback
518
- test(function forgetting (done) {
519
- var key = 'kooder'
520
- var count = 0
521
- function fire () { log('firing!'); bus.set.fire({key: key, count: count}) }
522
- bus(key).to_get = function () { setTimeout(fire, 10) }
523
-
524
- function cb (o) {
525
- count++
526
- log('cb2 called', count, 'times', 'on', o)
527
-
528
- if (count > 2) assert(false, 'cb2 too many calls')
529
- if (count > 1) {
530
- log('cb2 forgetting', key)
531
- bus.forget(key, cb)
532
- log('forgot.')
533
- }
534
- }
535
-
536
- bus.get(key, cb)
537
- setTimeout(fire, 70)
538
- setTimeout(fire, 80)
539
-
540
- // Done
541
- setTimeout(function () {
542
- assert(count === 2, "Count should be 2 but is", count)
543
- bus(key).to_get.delete(fire)
544
- done()
545
- }, 100)
546
- })
547
-
548
- // Can we return an object that getes another?
549
- test(function nested_get (done) {
550
- function outer () { return {inner: bus.get('inner') } }
551
- bus('outer').to_get = outer
552
- log('geting the outer wrapper')
553
- var obj = bus.get('outer')
554
- log('Ok, we geted:', obj)
555
- assert(obj.inner.key === 'inner')
556
- bus.set({key: 'inner', c: 1})
557
- assert(obj.inner.c === 1)
558
-
559
- log('vvv Grey line follows (cause outer geted inner) vvv')
560
-
561
- // Done
562
- setTimeout(function () {
563
- bus('outer').to_get.delete(outer)
564
- done()
565
- }, 10)
566
- })
567
-
568
- // Russian dolls
569
- test(function russian_doll_nesting (done) {
570
- var nothing = 3
571
- function big () { return {middle: bus.get('middle') } }
572
- function middle () { return {small: bus.get('small') } }
573
- function small () { return {nothing: nothing} }
574
- bus('big').to_get = big
575
- bus('middle').to_get = middle
576
- bus('small').to_get = small
577
-
578
- log('geting')
579
- var obj = bus.get('big')
580
- log('we got', obj)
581
-
582
- setTimeout(function () {
583
- bus.get('big', function (o) {
584
- nothing = 5
585
- log('About to update small')
586
- bus.set.fire({key: 'small', something: nothing})
587
- log('We did it.')
588
- })}, 10)
589
-
590
- setTimeout(function () {
591
- bus.get('big', function ruskie (o) {
592
- nothing = 50
593
- var small = bus.get('small')
594
- log()
595
- log('Second try. Small starts as', small)
596
- bus.set.fire({key: 'small', something: nothing})
597
- log('Now it is', bus.get('small'))
598
- })}, 15)
599
-
600
-
601
- // Done
602
- setTimeout(function () {
603
- bus('big').to_get.delete(big)
604
- bus('middle').to_get.delete(middle)
605
- bus('small').to_get.delete(small)
606
- done()
607
- }, 50)
608
- })
609
-
610
- test(function some_handlers_suicide (done) {
611
- // These handlers stop reacting after they successfully complete:
612
- //
613
- // .on_set
614
- // .to_set
615
- // .to_forget
616
- // .to_delete
617
- //
618
- // Ok, that's everyting except for a .to_get handler, which
619
- // runs until its key has been forget()ed.
620
-
621
- // XXX todo
622
- done()
623
- })
624
-
625
- test(function uncallback (done) {
626
- try {
627
- var chokidar = require('chokidar')
628
- } catch (e) {
629
- console.warn('#### Yo! You need to run "npm install chokidar"')
630
- process.exit()
631
- }
632
-
633
- var watchers = {}
634
- function read_file (filename, cb) {
635
- fs.readFile(filename, function (err, result) {
636
- if (err) throw err
637
- else cb(null, result + '')
638
- })
639
- }
640
-
641
- read_file = bus.uncallback(read_file, {
642
- start_watching: (args, dirty, del) => {
643
- var filename = args[0]
644
- assert(!(filename in watchers), 'WTF... the file ' + filename + ' is already being watched?')
645
- watchers[filename] = chokidar.watch(filename)
646
- watchers[filename].on('change', () => { bus.dirty(this.key) })
647
- },
648
- stop_watching: (json) => {
649
- filename = json[0]
650
- log('unwatching', filename)
651
- //watchers[filename].unwatch(filename)
652
- watchers[filename].close()
653
- delete watchers[filename]
654
- }})
655
-
656
- fs.writeFileSync('/tmp/blah', 'foo')
657
-
658
- bus.honk = 3
659
- var runs = 0
660
- bus(() => {
661
- runs++
662
- var result = read_file('/tmp/blah')
663
- log('read file as', JSON.stringify(result && result.substr(0,50)))
664
- //bus.forget(); return;
665
- if (bus.loading())
666
- log('Still loading!')
667
- else
668
- if (result == '1' || result == '2' || result == '3') {
669
- log('done. forgetting')
670
- bus.forget()
671
- }
672
-
673
- switch(runs) {
674
- case 1:
675
- console.assert(result == undefined); break
676
- case 2:
677
- console.assert(result == 'foo'); break
678
- case 3:
679
- case 4:
680
- console.assert(result == '1' || result == '2' || result == '3'); break;
681
- }
682
- })
683
-
684
- delay(10, () => {log('* MODIFY 1'); fs.writeFileSync('/tmp/blah', '1')})
685
- delay(200, () => {log('* MODIFY 2'); fs.writeFileSync('/tmp/blah', '2')})
686
- delay(200, () => {log('* MODIFY 3'); fs.writeFileSync('/tmp/blah', '3')})
687
-
688
- delay(200, () => {console.assert(runs < 4, 'There were', runs, 'runs'); done()})
689
- })
690
-
691
- test(function readfile (done) {
692
- var b = require('../statebus')(),
693
- count = 0
694
-
695
- fs.writeFileSync('/tmp/blah', '1')
696
- b(() => {
697
- var r = b.read_file('/tmp/blah')
698
- log('Got', r, 'at count', count)
699
- switch(count++) {
700
- case 0:
701
- console.assert(r === undefined); break
702
- case 1:
703
- console.assert(r === '1'); break
704
- case 2:
705
- console.assert(r === '2'); b.forget(); break
706
- case 3:
707
- console.assert(false); break
708
- }
709
- })
710
-
711
- delay(300, () => {log('* MODIFY 2'); fs.writeFileSync('/tmp/blah', '2')})
712
- delay(300, () => {log('* MODIFY 3'); fs.writeFileSync('/tmp/blah', '3')})
713
- delay(200, () => {done()})
714
- })
715
-
716
- test(function proxies (done) {
717
- var bus = require('../statebus')()
718
- db = bus.sb
719
- db.foo.a = 3
720
- assert(db.foo.a == 3)
721
- db.foo.a = [1,3,5, 'hello']
722
- db.foo.a.push({key: 'bar', 4:4})
723
-
724
- // Todo: make sure that push() and splice() etc. trigger updates to
725
- // state properly. They should trigger set() when they modify the
726
- // array, and not when they don't.
727
-
728
- log('Now foo is', db.foo)
729
- log('And bar is', db.bar)
730
-
731
- db.f = 3
732
- assert(bus.validate(bus.cache['f'], {key: 'f', val: 3}),
733
- bus.cache['f'], 'should be', {key: 'f', val: 3})
734
- assert(db.f === 3)
735
-
736
- db.g = [1,2,4,5]
737
- assert(bus.cache['g'].val.length = 4)
738
-
739
- done()
740
- })
741
-
742
- test(function proxies2 (done) {
743
- var bus = require('../statebus')()
744
- var state = bus.state
745
-
746
- assert(state.array === undefined)
747
- assert(state.bar === undefined)
748
-
749
- state.array = []
750
- log('array:', state.array)
751
- assert(state.array.length === 0)
752
- state.array[0] = 1
753
- log('array:', state.array)
754
- assert(state.array.length === 1)
755
- state.bar = {}
756
- log('bar:', state.bar)
757
- state.bar = {a: 1}
758
- log('bar:', state.bar)
759
- assert(state.bar.a === 1)
760
- state.bar.a = state.array
761
- log('bar:', state.bar)
762
- state.array[1] = 2
763
- log('array:', state.array)
764
- log('bar:', state.bar)
765
- assert(state.bar.a[1] === 2,
766
- "Array ref didn't link.\n\t"
767
- + JSON.stringify(bus.cache.bar) + '\n\t'
768
- + JSON.stringify(bus.cache.array))
769
-
770
- state.undefining = undefined
771
- assert(state.undefining === undefined)
772
- state.undefining = {a: undefined}
773
- log('state.undefining =', state.undefining)
774
- // assert(state.undefining.a === undefined)
775
- // TODO: fix https://github.com/invisible-college/statebus/issues/34
776
- state.undefining = {}
777
- assert(!('a' in state.undefining))
778
- state.undefining.a = undefined
779
- assert('a' in state.undefining)
780
- assert(state.undefining.a === undefined)
781
-
782
- state.b = {a: undefined}
783
- assert('a' in state.b)
784
- assert(state.b.a === undefined)
785
- delete state.b.a
786
- // TODO: https://github.com/invisible-college/statebus/issues/34
787
- assert(!('a' in state.b))
788
- assert(state.b.a === undefined)
789
-
790
- return done()
791
-
792
- /*
793
- Things I want to test:
794
-
795
- - Setting nested items
796
- - Escaping their fields
797
- - Calling get on them
798
- - Converting state[..] to keyed objects internally
799
- - has() potentially doing a get, or loading()
800
- - set() returning a proxy object
801
- - console output
802
- - node AND chrome
803
- - having nice colors and distinctions and shit
804
- */
805
-
806
- state.foo = 3
807
- // This should set into _
808
- console.assert(bus.validate(bus.cache.foo,
809
- {key: 'foo', val: 3}))
810
-
811
-
812
- state.foo = {a: 5}
813
- // This should set directly on it
814
- console.assert(bus.validate(bus.cache.foo,
815
- {key: 'foo', a: 5}))
816
- state.foo.b = 6
817
- console.assert(bus.validate(bus.cache.foo,
818
- {key: 'foo', b: 6}))
819
-
820
- state.bar = [3]
821
- state.foo = {a: 3, bar: state.bar}
822
-
823
- bus(() => {
824
- state.foo // foo triggers re-render
825
- state.foo.bar // bar triggers re-render
826
- state.foo.a // triggers re-render too
827
- })
828
-
829
- // Getting a linked item should do a get
830
- bus(() => {
831
- state.bar
832
- })
833
-
834
- // Getting a normal property should do a get
835
- })
836
-
837
- test(function only_one (done) {
838
- bus('only_one/*').to_get = function (k) {
839
- var id = k[k.length-1]
840
- return {selected: bus.get('selector').choice == id}
841
- }
842
-
843
- assert(!bus.get('only_one/1').selected)
844
- assert(!bus.get('only_one/2').selected)
845
- assert(!bus.get('only_one/3').selected)
846
-
847
- bus.set({key: 'selector', choice: 1})
848
-
849
- setTimeout(function () {
850
- assert( bus.get('only_one/1').selected)
851
- assert(!bus.get('only_one/2').selected)
852
- assert(!bus.get('only_one/3').selected)
853
-
854
- bus.set({key: 'selector', choice: 2})
855
- }, 10)
856
-
857
- setTimeout(function () {
858
- assert(!bus.get('only_one/1').selected)
859
- assert( bus.get('only_one/2').selected)
860
- assert(!bus.get('only_one/3').selected)
861
-
862
- bus.set({key: 'selector', choice: 3})
863
- }, 20)
864
-
865
- setTimeout(function () {
866
- assert(!bus.get('only_one/1').selected)
867
- assert(!bus.get('only_one/2').selected)
868
- assert( bus.get('only_one/3').selected)
869
- done()
870
- }, 30)
871
- })
872
-
873
- test(function set_can_trigger_toget (done) {
874
- // bus.honk = true
875
- bus('set_trigger_toget').to_get =
876
- function (k, old) {
877
- old.yes = Math.random()
878
- return old
879
- }
880
-
881
- var obj
882
- var triggered = 0
883
- bus(() => {
884
- log('Aight! Geting set_trigger_get')
885
- obj = bus.get('set_trigger_toget')
886
- if (bus.loading()) return
887
- triggered++
888
- log('Triggered', triggered, 'times', obj)
889
-
890
- // XXX todo: because of a bug in how to_get is handled, this triggers 4 times instead of 3
891
- assert(triggered <= 4)
892
- log('GGGGGGGGGGGG')
893
- })
894
-
895
- delay(30, () => { log('savin 1!'); obj.a = 1; bus.set(obj) })
896
- delay(30, () => { log('savin 2!'); obj.a = 2; bus.set(obj) })
897
- delay(30, done)
898
- })
899
-
900
- test(function rollback_setfire (done) {
901
- var count = 0
902
- var error = false
903
- var phase = 0
904
-
905
- function wait () { setTimeout(function () {
906
- assert(phase++ === 1)
907
- log('Firing wait')
908
- bus.set.fire({key: 'wait', count: count})
909
- }, 50) }
910
- bus('wait').to_get = wait
911
-
912
- // Initialize
913
- bus.set.fire({key: 'undo me', state: 'start'})
914
-
915
- // Now start the reactive function
916
- bus(function () {
917
- log('Reaction', ++count, 'starting with state',
918
- bus.get('undo me').state, 'and loading =', bus.loading())
919
-
920
- // Get something that we have to wait for
921
- var wait = bus.get('wait')
922
-
923
- // Set some middling state
924
- bus.set.fire({key: 'undo me', state: 'progressing'})
925
-
926
- if (count === 1 && !bus.loading()) {
927
- log('### Error! We should be loading!')
928
- error = true
929
- }
930
- log('Done with this reaction')
931
- })
932
-
933
- assert(!error)
934
-
935
- var state = bus.cache['undo me'].state
936
- log('After first reaction, the state is', state)
937
- assert(state === 'start', 'The state did not roll back.')
938
-
939
- // The state should still be "start" until 50ms
940
- setTimeout(function () {
941
- assert(bus.cache['undo me'].state === 'start')
942
- assert(phase++ === 0, phase)
943
- },
944
- 40)
945
-
946
- // The state should finally progress after 50ms
947
- setTimeout(function () {
948
- log('state is', bus.cache['undo me'].state)
949
- assert(bus.cache['undo me'].state === 'progressing')
950
- assert(phase++ === 2)
951
- },
952
- 60)
953
-
954
- setTimeout(function () {
955
- bus('wait').to_get.delete(wait)
956
- assert(phase === 3)
957
- done()
958
- }, 80)
959
- })
960
-
961
- test(function rollback_del (done) {
962
- bus('wait forever').to_get = function () {} // shooting blanks
963
- bus.set.fire({key: 'kill me', alive: true})
964
-
965
- // First do a del that will roll back
966
- bus(function () {
967
- log('Doing a rollback on', bus.cache['kill me'])
968
- bus.get('wait forever') // Never finishes loading
969
- bus.del('kill me') // Will roll back
970
- })
971
- assert(bus.cache['kill me'].alive === true)
972
-
973
- // Now a del that goes through
974
- bus(function () {
975
- log('Doing a real delete on', bus.cache['kill me'])
976
- bus.del('kill me') // Will not roll back
977
- })
978
- assert(!('kill me' in bus.cache))
979
- log('Now kill me is', bus.cache['kill me'])
980
- done()
981
- })
982
-
983
- test(function rollback_set (done) {
984
- var sets = []
985
- var all_done = false
986
- bus('candy').to_set = function (o) {sets.push(o); bus.set.fire(o)}
987
- bus.set.fire({key: 'candy', flavor: 'lemon'})
988
-
989
- log('Trying some rollbacks starting with', bus.cache['candy'])
990
-
991
- // First do a set that will roll back
992
- bus(function () { if (all_done) return;
993
- log('Doing a rollback on bananafied candy')
994
- bus.get('wait forever') // Never finishes loading
995
- bus.set({key:'candy', flavor: 'banana'}) // Will roll back
996
- log('...and the candy is', bus.cache['candy'])
997
- //forget('candy')
998
- })
999
- assert(bus.cache['candy'].flavor === 'lemon')
1000
- assert(sets.length === 0)
1001
-
1002
- // Try rolling back another style of set
1003
- bus(function () { if (all_done) return
1004
- log("Now we'll First we licoricize the", bus.cache['candy'])
1005
- bus.get('wait forever') // Never finishes loading
1006
- var candy = bus.get('candy')
1007
- candy.flavor = 'licorice'
1008
- log('...the candy has become', bus.cache['candy'])
1009
- bus.set(candy) // Will roll back
1010
- log('...and now it\'s rolled back to', bus.cache['candy'])
1011
- bus.forget('candy')
1012
- })
1013
- assert(bus.cache['candy'].flavor === 'lemon')
1014
- assert(sets.length === 0)
1015
-
1016
- // Now a set that goes through
1017
- bus(function () {
1018
- log('Doing a real set on', bus.cache['candy'])
1019
- bus.set({key:'candy', flavor: 'orangina'}) // Will go through
1020
- })
1021
- assert(bus.cache['candy'].flavor = 'orangina')
1022
- assert(sets.length === 1, 'Sets.length 1 != '+sets.length)
1023
-
1024
- log('Now candy is', bus.cache['candy'])
1025
- all_done = true
1026
- done()
1027
- })
1028
-
1029
- test(function rollback_abort (done) {
1030
- var bus = require('../statebus')()
1031
- bus('foo').to_set = (o, t) => {t.abort()}
1032
- bus(()=> {
1033
- var o = bus.get('foo')
1034
- o.bar = 3
1035
- bus.set(o)
1036
- })
1037
- setTimeout(() => {
1038
- assert(!bus.cache.foo.bar)
1039
- done()
1040
- }, 40)
1041
- })
1042
-
1043
- test(function loading_quirk (done) {
1044
- // Make sure a function that called loading() gets re-run even
1045
- // if the return from a get didn't actually change state
1046
-
1047
- // First define a delayed set.fire
1048
- bus('wait a sec').to_get = function (k) {
1049
- setTimeout(function () { bus.set.fire({key: k}) }, 50)
1050
- }
1051
-
1052
- // Now run the test
1053
- var loaded = false
1054
- var num_calls = 0
1055
- bus(function () {
1056
- num_calls++
1057
- log('called', num_calls, 'times')
1058
- bus.get('wait a sec')
1059
- loaded = !bus.loading()
1060
- })
1061
-
1062
- // Finish
1063
- setTimeout(function () {
1064
- assert(loaded, 'We never got loaded.')
1065
- assert(num_calls == 2,
1066
- 'We got called '+num_calls+'!=2 times')
1067
- done()
1068
- }, 100)
1069
- })
1070
-
1071
- test(function requires (done) {
1072
- try {
1073
- require.resolve('sockjs') // Will throw error if not found
1074
- require.resolve('websocket')
1075
- } catch (e) {
1076
- console.warn('#### Yo! You need to run "npm install sockjs websocket"')
1077
- process.exit()
1078
- }
1079
- log('Ok good, we have the goods.')
1080
- done()
1081
- })
1082
-
1083
- test(function default_route (done) {
1084
- var b1 = require('../statebus')()
1085
- var b2 = require('../statebus')()
1086
- b1.shadows(b2)
1087
- b2.set({key: 'foo', bar: 3})
1088
- console.assert(b1.get('foo').bar)
1089
- log(b1.get('foo'))
1090
- log(b2.get('foo'))
1091
- b1.delete('foo')
1092
- log(b1.get('foo'))
1093
- log(b2.get('foo'))
1094
- console.assert(!b1.get('foo').bar)
1095
- console.assert(!b2.get('foo').bar)
1096
- done()
1097
- })
1098
-
1099
- test(function setup_server (done) {
1100
- s = require('../statebus').serve({port: 3948, file_store: false})
1101
- s.label = 's'
1102
- log('Saving /far on server')
1103
- s.set({key: 'far', away:'is this'})
1104
-
1105
- c = require('../statebus')()
1106
- c.label = 'c'
1107
- c.ws_client('/*', 'statei://localhost:3948')
1108
-
1109
- // s.honk = true
1110
- // c.honk = true
1111
-
1112
- setTimeout(function () {
1113
- log('Geting /far on client')
1114
- var count = 0
1115
- c.get('/far', function (o) {
1116
- log('cb !!!!!!!!! --- ^_^')
1117
- c.get('/far')
1118
- if (o.away === 'is this') {
1119
- log('We got '+o.key+' from the server!')
1120
-
1121
- c.forget()
1122
- console.assert(count++ === 0, "Forget didn't work.")
1123
-
1124
- setTimeout(function () {done()})
1125
- }
1126
- })
1127
- }, 100)
1128
-
1129
- var matches = new Set()
1130
- for (var k in s.busses) {
1131
- log("Checking unique bus id", k, 'with name', s.busses[k].toString())
1132
- console.assert(!matches.has(k), 'duplicate bus id', k)
1133
- matches.add(k)
1134
- }
1135
- })
1136
-
1137
- test(function login (done) {
1138
- s.set({key: 'users',
1139
- all: [ { key: 'user/1',
1140
- name: 'mike',
1141
- email: 'toomim@gmail.com',
1142
- admin: true,
1143
- pass: '$2a$10$Ti7BgAZS8sB0Z62o2NKsIuCdmU3q9xP7jexVccTcG19Y8qpBpl/1y' }
1144
-
1145
- ,{ key: 'user/2',
1146
- name: 'j',
1147
- email: 'jtoomim@gmail.com',
1148
- admin: true,
1149
- pass: '$2a$10$Ti7BgAZS8sB0Z62o2NKsIuCdmU3q9xP7jexVccTcG19Y8qpBpl/1y' }
1150
-
1151
- ,{ key: 'user/3',
1152
- name: 'boo',
1153
- email: 'boo@gmail.com',
1154
- admin: false,
1155
- pass: '$2a$10$4UTjzf5OOGdkrCEsT.hO/.csKqf7u8mZ23ZT6stamBAWNV7u5WJuu' } ] })
1156
-
1157
- c(function () {
1158
- var u = c.get('/current_user')
1159
- if (u.logged_in) {
1160
- log('Yay! We are logged in as', u.user.name)
1161
- forget()
1162
- setTimeout(function () {done()})
1163
- } else
1164
- log("Ok... we aren't logged in yet. We be patient.")
1165
- })
1166
- // c.honk = user0.honk = true
1167
- var u = c.get('/current_user')
1168
- u.login_as = {name: 'mike', pass: 'yeah'}
1169
- log('Logging in')
1170
- c.set(u)
1171
- })
1172
-
1173
- test(function wrong_password (done) {
1174
- var u = c.get('/current_user')
1175
- assert(u.logged_in && u.user.name == 'mike')
1176
- u.login_as = {name: 'j', pass: 'nah'}
1177
- c.set(u)
1178
- setTimeout(function () {
1179
- assert(!u.login_as, 'Aborted login needs to abort')
1180
- log('Good, the login failed.')
1181
- done()
1182
- }, 300)
1183
- })
1184
-
1185
- test(function create_account (done) {
1186
- assert(c.get('/current_user').logged_in)
1187
- var count = 0
1188
- c(function () {
1189
- count++
1190
- var u = c.get('/current_user')
1191
-
1192
- log('Phase', count, '(logged '+(u.logged_in?'in)':'out)'))
1193
-
1194
- switch (count) {
1195
- case 1:
1196
- log('In 1 - Logging out')
1197
- assert(u.logged_in, '1 not logged in')
1198
- u.logout = true; c.set(u)
1199
- break
1200
- case 2: break
1201
- case 3:
1202
- // These are triggering a weird race condition bug, where the
1203
- // server sends a duplicate {user: {key: 'user/bob', name:
1204
- // 'bob', email: 'b@o.b'}, logged_in: true, key:
1205
- // 'current_user'} event, triggering a re-render at 7 before
1206
- // the logout has transpired.
1207
- // c.honk = true
1208
- // s.honk = true
1209
- log('In 3 - Creating bob, logging in as bob')
1210
- assert(!u.logged_in, '3 logged in')
1211
- u.create_account = {name: 'bob', email: 'b@o.b', pass: 'boob'}
1212
- c.set(u)
1213
-
1214
- // Note: I hope this done line isn't necessary in the future!
1215
- delete u.create_account
1216
-
1217
- u.login_as = {name: 'bob', pass: 'boob'}
1218
- c.set(u)
1219
- break
1220
- case 4: break
1221
- case 5:
1222
- log('In 5 - Logging out')
1223
- assert(u.logged_in)
1224
- assert(u.user.name === 'bob'
1225
- && u.user.email === 'b@o.b'
1226
- && u.user.pass === undefined
1227
- && u.user.key.match(/\/user\/.*/),
1228
- 'Bad user', u)
1229
- // Now let's log out
1230
- log('Almost done 5')
1231
- u.logout = true; c.set(u)
1232
- log('Done 5')
1233
- break
1234
- case 6: break
1235
- case 7:
1236
- log('In 7 - Logging back in as boob')
1237
- assert(!u.logged_in, '7. still logged in, as', u)
1238
- u.login_as = {name: 'bob', pass:'boob'}
1239
- c.set(u)
1240
- break
1241
- case 8: break
1242
- case 9:
1243
- log('In 9 - Forget and finish.')
1244
- assert(u.logged_in, '9 not logged in')
1245
- forget()
1246
- setTimeout(function () {done()})
1247
- break
1248
- default:
1249
- assert(false)
1250
- break
1251
- }
1252
- })
1253
- })
1254
-
1255
- function connections_helper (done, port, options) {
1256
- // Setup a server
1257
- var s = require('../statebus').serve({port: port,
1258
- file_store: false,
1259
- connections: options})
1260
- s.label = 's'
1261
-
1262
- // Connect two clients
1263
- var c1 = require('../statebus')()
1264
- c1.label = 'c1'
1265
- c1.ws_client('/*', 'statei://localhost:' + port)
1266
-
1267
- var c2 = require('../statebus')()
1268
- c2.label = 'c2'
1269
- c2.ws_client('/*', 'statei://localhost:' + port)
1270
-
1271
- // Load the basic connections
1272
- c1.c = c1.get('/connection')
1273
- c2.c = c2.get('/connection')
1274
- c1.all = c1.get('/connections')
1275
-
1276
- delay(50, _=> {
1277
- // Test
1278
- log('c1.c:', c1.c)
1279
- log('c2.c:', c2.c)
1280
- log('all:', c1.all)
1281
- assert(c1.c.id)
1282
- assert(c2.c.id)
1283
-
1284
- // Load the connections inside
1285
- c1.c1 = c1.get('/connection/' + c1.c.id)
1286
- c1.c2 = c1.get('/connection/' + c2.c.id)
1287
- c2.c1 = c2.get('/connection/' + c1.c.id)
1288
- c2.c2 = c2.get('/connection/' + c2.c.id)
1289
- })
1290
-
1291
- delay(50, _=> {
1292
- // Test
1293
- assert(c1.validate(c1.c1, {key: 'string', client: 'string', id: 'string'}))
1294
- log('c1.c1', JSON.stringify(c1.c1))
1295
- log('c2.c2', JSON.stringify(c2.c2))
1296
- assert(c1.c1.id === c1.c.id)
1297
- assert(c1.c2.id === c2.c.id)
1298
- assert(c2.c1.id === c1.c.id)
1299
- assert(c2.c2.id === c2.c.id)
1300
-
1301
- // Modify a connection
1302
- c1.c.foo = 'bar'; c1.set(c1.c)
1303
- c2.c2.fuzz = 'buzz'; c2.set(c2.c2)
1304
- })
1305
-
1306
- delay(50, _=> {
1307
- // Test
1308
- assert(c1.c.foo === 'bar')
1309
- assert(c1.c1.foo === 'bar')
1310
- assert(c2.c1.foo === 'bar')
1311
-
1312
- assert(c2.c.fuzz === 'buzz')
1313
- assert(c2.c2.fuzz === 'buzz')
1314
- assert(c1.c2.fuzz === 'buzz')
1315
-
1316
- // Modify someone else's connection
1317
- c1.c2.fuzz = 'fart'; c1.set(c1.c2)
1318
- c2.c1.free = 'willy'; c2.set(c2.c1)
1319
- })
1320
-
1321
- delay(50, _=> {
1322
- // Test
1323
- if (options.edit_others) {
1324
- assert(c1.c2.fuzz === 'fart')
1325
- assert(c2.c2.fuzz === 'fart')
1326
- assert(c1.c1.free === 'willy')
1327
- assert(c2.c1.free === 'willy')
1328
- } else {
1329
- assert(c1.c2.fuzz !== 'fart')
1330
- assert(c2.c2.fuzz !== 'fart')
1331
- assert(c1.c1.free !== 'willy')
1332
- assert(c2.c1.free !== 'willy')
1333
- }
1334
- })
1335
-
1336
- // Todo: test the inclusion of users
1337
-
1338
- delay(50, _=> done())
1339
- }
1340
-
1341
- test(function connections_1 (done) {
1342
- connections_helper(done, 3951, {include_users: true, edit_others: true})
1343
- })
1344
-
1345
- test(function connections_2 (done) {
1346
- connections_helper(done, 3952, {include_users: false, edit_others: false})
1347
- })
1348
-
1349
- test(function flashbacks (done) {
1350
- // We have an echo canceler. If you set state, it shouldn't send the
1351
- // same state back to you, but it should send it to everyone else. But if
1352
- // the state is changed in a to_set handler, it *should* send you
1353
- // changes.
1354
-
1355
- var port = 3873
1356
-
1357
- // Setup a server
1358
- var s = require('../statebus').serve({port: port, file_store: false})
1359
- s.label = 's'
1360
-
1361
- s('x').to_set = (o, t) => {
1362
- log('Saving x with', o)
1363
- o.x++ // Change the value of o.x a little
1364
- t.done(o)
1365
- }
1366
-
1367
- // Connect two clients
1368
- var c1 = require('../statebus')()
1369
- c1.label = 'c1'
1370
- c1.ws_client('*', 'statei://localhost:' + port)
1371
-
1372
- var c2 = require('../statebus')()
1373
- c2.label = 'c2'
1374
- c2.ws_client('*', 'statei://localhost:' + port)
1375
-
1376
- c1.x = c1.get('x')
1377
- c2.x = c2.get('x')
1378
-
1379
- // Change stuff
1380
- delay(50, _=> {
1381
- c1.x.x = 1
1382
- c1.set(c1.x)
1383
- })
1384
-
1385
- // Test stuff
1386
- delay(50, _=> {
1387
- assert(c2.x.x === 2, 'c2 didn\'t get it')
1388
- assert(c1.x.x === 2, 'c1 didn\'t get it')
1389
- log('complete!', c1.x, c2.x)
1390
- done()
1391
- })
1392
- })
1393
-
1394
- test(function email_read_permissions (done) {
1395
- var phase = -1
1396
- var u, user1, user2, user3
1397
- var tmp1
1398
-
1399
- var states = function () { return [
1400
- // Phase 0
1401
- [true,
1402
- function () {
1403
- log('Logging in as mike')
1404
- //s.honk=true
1405
- u.login_as = {name: 'mike', pass: 'yeah'}; c.set(u)
1406
- }],
1407
-
1408
- // Phase 1
1409
- // Logged in as mike
1410
- [(u.logged_in
1411
- && u.user.name === 'mike'
1412
- && u.user.key === '/user/1'
1413
-
1414
- // We can see our email
1415
- && u.user.email
1416
- && user1.email
1417
-
1418
- // We can't see other emails
1419
- && !user2.email
1420
- && !user3.email),
1421
-
1422
- function () {
1423
- !tmp1 && log('Logging in as j')
1424
- setTimeout(function () {
1425
- if (tmp1) return
1426
- tmp1 = true
1427
- log('Firing the actual j login')
1428
- //s.userbus.honk = true
1429
- u.login_as = {name: 'j', pass: 'yeah'}; c.set(u)
1430
- log('We just logged in as j. now user is:', u.user.name)
1431
- }, 10)
1432
- }],
1433
-
1434
- // Phase 2
1435
- // Logged in as j
1436
- [(u.logged_in
1437
- && u.user.name === 'j'
1438
- && u.user.key === '/user/2'
1439
-
1440
- // We can see j's email
1441
- && u.user.email
1442
- && user2.email
1443
-
1444
- // We can't see other emails
1445
- && !user1.email
1446
- && !user3.email),
1447
-
1448
- // That's all, Doc
1449
- function () { log("That's all, Doc."); setTimeout(function () {done()}) }]
1450
- ]}
1451
-
1452
- c('/current_user').on_set = function (o) {
1453
- //if (o.user && o.user.name === 'j') {
1454
- // log(s.userbus.deps('/current_user'))
1455
- // log(s.userbus.deps('/user/2'))
1456
- //}
1457
- }
1458
- c('/user/*').on_set = function (o) {
1459
- //log('-> Got new', o.key, o.email ? 'with email' : '')
1460
- }
1461
- c('/current_user').on_set = function (o) {
1462
- //log('-> Got new /current_user')
1463
- }
1464
- c(function loop () {
1465
- u = c.get('/current_user')
1466
- user1 = c.get('/user/1')
1467
- user2 = c.get('/user/2')
1468
- user3 = c.get('/user/3')
1469
- var st = states()
1470
-
1471
- if (phase===1)
1472
- log('\n\tcurr u:\t',u.user, '\n\t1:\t', user1,'\n\t2:\t', user2,'\n\t3:\t', user3)
1473
-
1474
- if (phase >= st.length) {
1475
- loop.forget()
1476
- return
1477
- }
1478
-
1479
- if (phase + 1 < st.length && st[phase + 1][0]) {
1480
- phase++
1481
- log()
1482
- log('## Shifting to phase', phase)
1483
- }
1484
-
1485
- //log('Phase', phase, 'logged_in:', u.logged_in && u.user.name)
1486
- st[phase][1]()
1487
- })
1488
- })
1489
-
1490
- test(function closet_space (done) {
1491
- var s = require('../statebus').serve({port: 3949,
1492
- file_store: false,
1493
- client: (c)=>{c.honk=true}})
1494
- s.label = 's'
1495
-
1496
- var c = require('../statebus')()
1497
- c.label = 'c'
1498
- c.ws_client('/*', 'statei://localhost:3949')
1499
-
1500
- // Make stuff as user A
1501
- var cu = c.get('/current_user')
1502
- c.set({key: '/current_user', create_account: {name: 'a', pass: 'a'}})
1503
- c.set({key: '/current_user', login_as: {name: 'a', pass: 'a'}})
1504
- var a_closet = c.get('/user/a/foo')
1505
- var a_private = c.get('/user/a/private/foo')
1506
-
1507
- delay(400, () => {
1508
- c.set({key: '/user/a/foo', val: 3})
1509
- c.set({key: '/user/a/private/foo', val: 4})
1510
- })
1511
-
1512
- // User A can see it
1513
- delay(450, ()=> {
1514
- log('1. Now curr user is', cu)
1515
- console.assert(cu.logged_in == true, 'not logged in')
1516
- log('closet is', a_closet)
1517
- console.assert(a_closet.val === 3, 'closet not right')
1518
- console.assert(a_private.val === 4, 'private not right')
1519
-
1520
- // Set up User B
1521
- c.set({key: '/current_user', create_account: {name: 'b', pass: 'b'}})
1522
- c.set({key: '/current_user', login_as: {name: 'b', pass: 'b'}})
1523
- })
1524
-
1525
- // User B can't see private stuff
1526
- delay(450, ()=> {
1527
- log('3. Now curr user is', cu)
1528
- log('closet is', {closet:a_closet, private:a_private})
1529
- console.assert(a_closet.val === 3, 'A\'s closet is not visible')
1530
- console.assert(a_private.val !== 4, 'damn can still see private')
1531
-
1532
- // User B tries editing the first closet
1533
- a_closet.val = 5; c.set(a_closet)
1534
- })
1535
-
1536
- // User B could not edit that
1537
- delay(350, ()=> {
1538
- console.assert(a_closet.val === 3, 'damn he could edit it')
1539
- })
1540
-
1541
- delay(50, ()=>done())
1542
- })
1543
-
1544
- test(function ambiguous_ordering (done) {
1545
- // Not fully implemented yet
1546
-
1547
- /*
1548
- Let's set within an on-set handler. Which will trigger
1549
- first... the dirty(), or the new set()? Hm, do we really
1550
- care?
1551
- */
1552
-
1553
- var user = 3
1554
- bus('user').to_get =
1555
- function (k) {
1556
- return {user: user}
1557
- }
1558
-
1559
- bus('user').to_set =
1560
- function (o) {
1561
- if (o.funny)
1562
- bus.set({key: 'user', user: 'funny'})
1563
-
1564
- user = o.user
1565
- bus.dirty('user')
1566
- }
1567
-
1568
- log("Eh, nevermind.")
1569
- done()
1570
- })
1571
-
1572
- run_tests()