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.
- package/client.js +2 -2
- package/extras/tests.js +60 -0
- package/package.json +9 -2
- package/server.js +4 -4
- package/statebus.js +39 -7
- package/extras/#test_save_delay.js# +0 -11
- package/extras/abort-test.html +0 -10
- package/extras/abort-test.js +0 -17
- package/extras/backups/db.2021-11-13 +0 -12
- package/extras/backups/db.2021-11-14 +0 -12
- package/extras/backups/db.2021-11-15 +0 -25
- package/extras/backups/db.2021-11-16 +0 -25
- package/extras/backups/db.2022-01-14 +0 -24
- package/extras/backups/db.2022-01-15 +0 -29
- package/extras/backups/db.2022-01-16 +0 -29
- package/extras/backups/db.2022-01-17 +0 -29
- package/extras/backups/db.2022-01-18 +0 -29
- package/extras/backups/db.2022-01-19 +0 -29
- package/extras/backups/db.2022-01-20 +0 -32
- package/extras/backups/db.2022-01-21 +0 -32
- package/extras/backups/db.2022-01-22 +0 -47
- package/extras/backups/db.2022-01-23 +0 -47
- package/extras/backups/db.2022-02-20 +0 -53
- package/extras/backups/db.2022-09-08 +0 -48
- package/extras/backups/db.2022-09-09 +0 -48
- package/extras/backups/db.2022-09-10 +0 -48
- package/extras/backups/db.2022-09-11 +0 -48
- package/extras/backups/db.2022-09-12 +0 -48
- package/extras/backups/db.2022-09-13 +0 -48
- package/extras/backups/db.2022-09-14 +0 -48
- package/extras/backups/pdb.2017-08-21 +0 -46
- package/extras/braid-client.html +0 -12
- package/extras/braid-client2.html +0 -9
- package/extras/braid-client3.html +0 -0
- package/extras/braid-server.js +0 -37
- package/extras/braid-server2.js +0 -35
- package/extras/chokitest.js +0 -142
- package/extras/clientless.js +0 -4
- package/extras/css.html +0 -4
- package/extras/ct.js +0 -24
- package/extras/ctests.js +0 -8
- package/extras/db +0 -48
- package/extras/ds.html +0 -8
- package/extras/ds.js +0 -17
- package/extras/email.html +0 -12
- package/extras/express-experiment.js +0 -15
- package/extras/f.js +0 -21
- package/extras/file-test.js +0 -12
- package/extras/flash.html +0 -8
- package/extras/flash.js +0 -7
- package/extras/fullnode-test.html +0 -4
- package/extras/fullnode-test.js +0 -26
- package/extras/hello-react/index.html +0 -24
- package/extras/hello-react.html +0 -4
- package/extras/hello.html +0 -4
- package/extras/k.js +0 -12
- package/extras/load-from-file.html +0 -4
- package/extras/multi-chat/1.html +0 -39
- package/extras/multicriteria +0 -52054
- package/extras/nested +0 -425965
- package/extras/new-react.html +0 -20
- package/extras/pdb +0 -46
- package/extras/perf.js +0 -68
- package/extras/perf2.js +0 -69
- package/extras/perf3.js +0 -14
- package/extras/pgt.js +0 -61
- package/extras/pointers-test.js +0 -17
- package/extras/pointers-test2.js +0 -83
- package/extras/ptest.js +0 -19
- package/extras/react-example.html +0 -32
- package/extras/react-example.jsx.html +0 -41
- package/extras/react.12.js +0 -18116
- package/extras/react.12.min.js +0 -16
- package/extras/react.15.min.js +0 -28
- package/extras/react.3.min.js +0 -19
- package/extras/remote-hello.html +0 -9
- package/extras/reset_pass.coffee +0 -101
- package/extras/reset_pass.html +0 -116
- package/extras/rocks-test.js +0 -6
- package/extras/s4.js +0 -2
- package/extras/sbdb +0 -4
- package/extras/slideboard +0 -4
- package/extras/smaller-file.js +0 -8
- package/extras/sqls-test.js +0 -6
- package/extras/stateb.us.coffee +0 -92
- package/extras/syncie.html +0 -31
- package/extras/syncie.js +0 -15
- package/extras/test2.js +0 -48
- package/extras/test_client.html +0 -8
- package/extras/test_client.js +0 -19
- package/extras/test_save_delay.js +0 -11
- package/extras/test_timeouts.js +0 -10
- package/extras/tests-val.js +0 -1572
- package/extras/tests.html +0 -5
- package/extras/uni.js +0 -7
- package/extras/usage_test.html +0 -3
- package/extras/usage_test.js +0 -32
- package/extras/vtest.js +0 -17
package/extras/tests-val.js
DELETED
|
@@ -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()
|