1 | process.env.NODE_ENV = 'test'
|
2 |
|
3 | path = require 'path'
|
4 | assert = require 'assert'
|
5 | async = require 'async'
|
6 | LindaClient = require(path.resolve()).Client
|
7 | TestServer = require './server'
|
8 |
|
9 | port = process.env.PORT-0 || 13000
|
10 |
|
11 |
|
12 | server = new TestServer().listen(port)
|
13 | setTimeout ->
|
14 | server.close()
|
15 | , 10000
|
16 |
|
17 |
|
18 | create_client = ->
|
19 | socket = require('socket.io-client').connect("http://localhost:#{port}")
|
20 | return new LindaClient().connect(socket)
|
21 |
|
22 |
|
23 | describe 'instance of LindaClient', ->
|
24 |
|
25 | it 'should have method "connect"', ->
|
26 | assert.equal typeof new LindaClient()['connect'], 'function'
|
27 |
|
28 | it 'should have property "io"', ->
|
29 | assert.ok create_client().hasOwnProperty('io')
|
30 |
|
31 | it 'should have socket.io connection', (done) ->
|
32 | linda = create_client()
|
33 | ts = linda.tuplespace('chat')
|
34 |
|
35 | linda.io.on 'connect', ->
|
36 | assert.ok
|
37 | done()
|
38 |
|
39 | it 'should have method "tuplespace"', ->
|
40 | assert.equal typeof new LindaClient()['tuplespace'], 'function'
|
41 |
|
42 |
|
43 | describe 'method "tuplespace"', ->
|
44 |
|
45 | it 'should have property "name"', ->
|
46 | ts = create_client().tuplespace('test')
|
47 | assert.equal ts.name, 'test'
|
48 |
|
49 | it 'should have method "create_callback_id"', ->
|
50 | ts = create_client().tuplespace('test')
|
51 | assert.equal typeof ts['create_callback_id'], 'function'
|
52 |
|
53 | it 'should have method "create_watch_callback_id"', ->
|
54 | ts = create_client().tuplespace('test')
|
55 | assert.equal typeof ts['create_watch_callback_id'], 'function'
|
56 |
|
57 | it 'should have method "write"', ->
|
58 | ts = create_client().tuplespace('test')
|
59 | assert.equal typeof ts['write'], 'function'
|
60 |
|
61 | it 'should have method "read"', ->
|
62 | ts = create_client().tuplespace('test')
|
63 | assert.equal typeof ts['read'], 'function'
|
64 |
|
65 | it 'should have method "take"', ->
|
66 | ts = create_client().tuplespace('test')
|
67 | assert.equal typeof ts['take'], 'function'
|
68 |
|
69 | it 'should have method "watch"', ->
|
70 | ts = create_client().tuplespace('test')
|
71 | assert.equal typeof ts['watch'], 'function'
|
72 |
|
73 | it 'should have method "cancel"', ->
|
74 | ts = create_client().tuplespace('test')
|
75 | assert.equal typeof ts['cancel'], 'function'
|
76 |
|
77 | describe 'method "write"', ->
|
78 |
|
79 | it 'should write Tuple', (done) ->
|
80 | linda = create_client()
|
81 | ts = linda.tuplespace('write')
|
82 |
|
83 | msg = "hello world #{new Date()}"
|
84 |
|
85 | assert.equal server.linda.tuplespace('write').size, 0
|
86 | linda.tuplespace('write').write {type: "chat", message: msg}
|
87 | server.linda.tuplespace('write').read {type: "chat"}, (err, tuple) ->
|
88 | assert.deepEqual tuple.data, {type: "chat", message: msg}
|
89 | assert.equal server.linda.tuplespace('write').size, 1
|
90 | done()
|
91 |
|
92 | it 'should have "expire" option', (done) ->
|
93 | @timeout(5000)
|
94 | linda = create_client()
|
95 | ts = linda.tuplespace('write_expire')
|
96 | server_ts = server.linda.tuplespace('write_expire')
|
97 |
|
98 | ts.write {foo: "bar"}, {expire: 2}
|
99 | ts.read {foo: "bar"}, (err, tuple) ->
|
100 | assert.deepEqual tuple.data, {foo: "bar"}
|
101 | assert.equal server_ts.size, 1
|
102 | setTimeout ->
|
103 | server_ts.check_expire()
|
104 | assert.equal server_ts.size, 0
|
105 | done()
|
106 | , 3000
|
107 |
|
108 |
|
109 | describe 'method "watch"', ->
|
110 |
|
111 | it 'should return cancel_id', ->
|
112 | cid = create_client().tuplespace('watch_cancel').watch {}, ->
|
113 | assert.ok cid > 0
|
114 |
|
115 | it 'should return matched Tuple', (done) ->
|
116 | writer = create_client()
|
117 | watcher = create_client()
|
118 | val_a = Math.random()
|
119 | val_b = Math.random()
|
120 |
|
121 | count = 0
|
122 | watcher.tuplespace('watch').watch {sensor: "light"}, (err, tuple) ->
|
123 | count += 1
|
124 | switch count
|
125 | when 1
|
126 | assert.deepEqual tuple.data, {sensor: "light", value: val_a}
|
127 | when 2
|
128 | assert.deepEqual tuple.data, {sensor: "light", value: val_b}
|
129 | done()
|
130 |
|
131 | writer.tuplespace('watch').write {sensor: "foo", value: 20}
|
132 | writer.tuplespace('watch').write {sensor: "light", value: val_a}
|
133 | writer.tuplespace('watch').write {name: "shokai", age: 29}
|
134 | writer.tuplespace('watch').write {sensor: "light", value: val_b}
|
135 |
|
136 |
|
137 | it 'should not return Tuple if canceled', (done) ->
|
138 | linda = create_client()
|
139 | ts = linda.tuplespace('watch_cancel_test')
|
140 | cid = null
|
141 | async.parallel [
|
142 | (async_done) ->
|
143 | cid_ = ts.watch {a:1}, (err, tuple) ->
|
144 | assert.deepEqual tuple.data, {a:1, b:2}
|
145 | async_done(null, cid_)
|
146 | (async_done) ->
|
147 | cid = ts.watch {}, (err, tuple) ->
|
148 | assert.equal err, "cancel"
|
149 | async_done(null, cid)
|
150 | ], (err, callback_ids) ->
|
151 | assert.notEqual callback_ids[0], callback_ids[1]
|
152 | assert.equal server_ts.callbacks.length, 1
|
153 | done()
|
154 |
|
155 | server_ts = server.linda.tuplespace('watch_cancel_test')
|
156 | assert.equal server_ts.callbacks.length, 0
|
157 | ts.cancel cid
|
158 | ts.write {a:1, b:2}
|
159 |
|
160 | it 'should use same callback_id for same Tuple watch', (done) ->
|
161 | linda = create_client()
|
162 | ts = linda.tuplespace('watch_callback_id')
|
163 | server_ts = server.linda.tuplespace('watch_callback_id')
|
164 | assert.equal server_ts.callbacks.length, 0
|
165 |
|
166 | async.parallel [
|
167 | (async_done) ->
|
168 | cid = ts.watch {sensor: "light"}, (err, tuple) ->
|
169 | assert.deepEqual tuple.data, {sensor: "light", value: 8}
|
170 | async_done(null, cid)
|
171 | (async_done) ->
|
172 |
|
173 | cid = ts.watch {sensor: "light"}, (err, tuple) ->
|
174 | assert.deepEqual tuple.data, {sensor: "light", value: 8}
|
175 | async_done(null, cid)
|
176 | (async_done) ->
|
177 | cid = ts.watch {sensor: "temperature"}, (err, tuple) ->
|
178 | assert.deepEqual tuple.data, {sensor: "temperature", value: 19}
|
179 | async_done(null, cid)
|
180 | ], (err, callback_ids) ->
|
181 | assert.equal callback_ids[0], callback_ids[1]
|
182 | assert.notEqual callback_ids[0], callback_ids[2]
|
183 | assert.equal server_ts.callbacks.length, 2
|
184 | done()
|
185 |
|
186 | ts.write {sensor: "light", value: 8}
|
187 | ts.write {sensor: "temperature", value: 19}
|
188 |
|
189 |
|
190 | describe 'method "read"', ->
|
191 |
|
192 | it 'should return cancel_id', ->
|
193 | cid = create_client().tuplespace('read_cancel').read {}, ->
|
194 | assert.ok cid > 0
|
195 |
|
196 | it 'should return matched Tuple', (done) ->
|
197 | reader = create_client()
|
198 | writer = create_client()
|
199 |
|
200 | msg = "hello world #{new Date}"
|
201 | writer.tuplespace('read').write {type: "chat", message: msg}
|
202 | async.parallel [
|
203 | (async_done) ->
|
204 | reader.tuplespace('read').read {type: "chat"}, (err, tuple) ->
|
205 | assert.deepEqual tuple.data, {type: "chat", message: msg}
|
206 | async_done()
|
207 | (async_done) ->
|
208 | reader.tuplespace('read').read {type: "foobar"}, (err, tuple) ->
|
209 | assert.ok false
|
210 | async_done()
|
211 | setTimeout ->
|
212 | assert.ok
|
213 | async_done()
|
214 | , 500
|
215 | ], (err, results) ->
|
216 | assert.equal server.linda.tuplespace('read').size, 1
|
217 | assert.equal server.linda.tuplespace('read').callbacks.length, 1
|
218 | done()
|
219 |
|
220 |
|
221 | it 'should wait if Tuple not found', (done) ->
|
222 | reader = create_client()
|
223 | writer = create_client()
|
224 |
|
225 | msg = "hello world #{new Date}"
|
226 | reader.tuplespace('read_callback').read {type: "chat"}, (err, tuple) ->
|
227 | assert.deepEqual tuple.data, {type: "chat", message: msg}
|
228 | done()
|
229 |
|
230 | writer.tuplespace('read_callback').write {type: "chat", message: msg}
|
231 |
|
232 | it 'should not return Tuple if canceled', (done) ->
|
233 | linda = create_client()
|
234 | ts = linda.tuplespace('read_cancel_test')
|
235 | cid = null
|
236 | async.parallel [
|
237 | (async_done) ->
|
238 | cid_ = ts.read {a:1}, (err, tuple) ->
|
239 | assert.deepEqual tuple.data, {a:1, b:2}
|
240 | async_done(null, cid_)
|
241 | (async_done) ->
|
242 | cid = ts.read {}, (err, tuple) ->
|
243 | assert.equal err, "cancel"
|
244 | async_done(null, cid)
|
245 | ], (err, callback_ids) ->
|
246 | assert.notEqual callback_ids[0], callback_ids[1]
|
247 | assert.equal server_ts.callbacks.length, 0
|
248 | done()
|
249 |
|
250 | server_ts = server.linda.tuplespace('read_cancel_test')
|
251 | assert.equal server_ts.callbacks.length, 0
|
252 | ts.cancel cid
|
253 | ts.write {a:1, b:2}
|
254 |
|
255 |
|
256 | describe 'method "take"', ->
|
257 |
|
258 | it 'should return cancel_id', ->
|
259 | cid = create_client().tuplespace('take_cancel').take {}, ->
|
260 | assert.ok cid > 0
|
261 |
|
262 | it 'should return matched Tuple and delete', (done) ->
|
263 | taker = create_client()
|
264 | writer = create_client()
|
265 |
|
266 | msg = "hello world #{new Date}"
|
267 | writer.tuplespace('take').write {type: "chat", message: msg}
|
268 | async.parallel [
|
269 | (async_done) ->
|
270 | taker.tuplespace('take').take {type: "chat"}, (err, tuple) ->
|
271 | assert.deepEqual tuple.data, {type: "chat", message: msg}
|
272 | async_done()
|
273 | (async_done) ->
|
274 | taker.tuplespace('take').take {type: "foobar"}, (err, tuple) ->
|
275 | assert.ok false
|
276 | async_done()
|
277 | setTimeout ->
|
278 | assert.ok
|
279 | async_done()
|
280 | , 500
|
281 | ], (err, results) ->
|
282 | assert.equal server.linda.tuplespace('take').size, 0
|
283 | assert.equal server.linda.tuplespace('take').callbacks.length, 1
|
284 | done()
|
285 |
|
286 |
|
287 | it 'should wait if Tuple not found', (done) ->
|
288 | taker = create_client()
|
289 | writer = create_client()
|
290 |
|
291 | msg = "hello world #{new Date}"
|
292 | taker.tuplespace('take_callback').read {type: "chat"}, (err, tuple) ->
|
293 | assert.deepEqual tuple.data, {type: "chat", message: msg}
|
294 | done()
|
295 |
|
296 | writer.tuplespace('take_callback').write {type: "chat", message: msg}
|
297 |
|
298 | it 'should not return Tuple if canceled', (done) ->
|
299 | linda = create_client()
|
300 | ts = linda.tuplespace('take_cancel_test')
|
301 | cid = null
|
302 | async.parallel [
|
303 | (async_done) ->
|
304 | cid_ = ts.take {a:1}, (err, tuple) ->
|
305 | assert.deepEqual tuple.data, {a:1, b:2}
|
306 | async_done(null, cid_)
|
307 | (async_done) ->
|
308 | cid = ts.take {}, (err, tuple) ->
|
309 | assert.equal err, "cancel"
|
310 | async_done(null, cid)
|
311 | ], (err, callback_ids) ->
|
312 | assert.notEqual callback_ids[0], callback_ids[1]
|
313 | assert.equal server_ts.callbacks.length, 0
|
314 | done()
|
315 |
|
316 | server_ts = server.linda.tuplespace('take_cancel_test')
|
317 | assert.equal server_ts.callbacks.length, 0
|
318 | ts.cancel cid
|
319 | ts.write {a:1, b:2}
|
320 |
|
321 | describe 'returned Tuple', ->
|
322 |
|
323 | it 'should have remote-address in "from" property', (done) ->
|
324 | linda = create_client()
|
325 | ts = linda.tuplespace('tuple_from')
|
326 | async.parallel [
|
327 | (async_done) ->
|
328 | ts.read {a:1}, (err, tuple) ->
|
329 | assert.ok tuple.from?.match(/^\d+\.\d+\.\d+\.\d+$/)
|
330 | async_done(null)
|
331 | (async_done) ->
|
332 | ts.watch {a:1}, (err, tuple) ->
|
333 | assert.ok tuple.from?.match(/^\d+\.\d+\.\d+\.\d+$/)
|
334 | async_done(null)
|
335 | (async_done) ->
|
336 | ts.take {a:1}, (err, tuple) ->
|
337 | assert.ok tuple.from?.match(/^\d+\.\d+\.\d+\.\d+$/)
|
338 | async_done(null)
|
339 | ], (err) ->
|
340 | done()
|
341 |
|
342 | ts.write {a:1, b:2}
|