fraggel 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,33 @@
1
+ module Fraggel
2
+
3
+ module Encoder
4
+
5
+ class UnknownType < StandardError ; end
6
+
7
+ def encode(value)
8
+ case value
9
+ when nil
10
+ "$-1\r\n"
11
+ when true
12
+ encode(1)
13
+ when false
14
+ encode(0)
15
+ when Integer
16
+ ":%d\r\n" % [value]
17
+ when String
18
+ "$%d\r\n%s\r\n" % [value.length, value]
19
+ when Array
20
+ mapped = value.map {|x| encode(x) }
21
+ "*%d\r\n%s" % [mapped.length, mapped]
22
+ when StandardError, Exception
23
+ "-ERR: %s\r\n" % [value.message]
24
+ when Symbol
25
+ "+%s\r\n" % [value]
26
+ else
27
+ raise UnknownType, value
28
+ end
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -0,0 +1,46 @@
1
+ module Fraggel
2
+
3
+ class Responder
4
+
5
+ def initialize(&blk)
6
+ @receiver = blk
7
+ end
8
+
9
+ def receive_event(name, value)
10
+ @cs ||= lambda {|x|
11
+ @receiver.call(x)
12
+ @cs = nil
13
+ }
14
+
15
+ case name
16
+ when :array
17
+ @cs = array!(value, [], &@cs)
18
+ when :value
19
+ @cs.call(value)
20
+ when :error
21
+ @cs.call(StandardError.new(value))
22
+ when :status
23
+ # I'm not sure if this is a good idea. Symbols are not garbage
24
+ # collected. If there server sends and arbitrary number of status
25
+ # messages, this could get ugly. I'm not sure that's a problem yet.
26
+ @cs.call(value.to_sym)
27
+ else
28
+ fail "Unknown Type #{name.inspect}"
29
+ end
30
+ end
31
+
32
+ def array!(c, a, &blk)
33
+ lambda {|x|
34
+ a << x
35
+ if c == a.length
36
+ @cs = blk
37
+ blk.call(a)
38
+ else
39
+ array!(c, a, &blk)
40
+ end
41
+ }
42
+ end
43
+
44
+ end
45
+
46
+ end
@@ -0,0 +1,124 @@
1
+ require 'fraggel'
2
+
3
+ class FraggelDecoderTest < Test::Unit::TestCase
4
+
5
+ attr_reader :log
6
+ attr_reader :parser
7
+
8
+ def setup
9
+ @log = []
10
+ @parser = Fraggel::Decoder.new do |name, value|
11
+ @log << [name, value]
12
+ end
13
+ end
14
+
15
+ def test_blank_line
16
+ parser.receive_data("\r\n")
17
+ parser.receive_data("\r")
18
+ parser.receive_data("\n")
19
+
20
+ assert_equal [], log
21
+ end
22
+
23
+ def test_blank_poison
24
+ assert_raise(Fraggel::Decoder::Poisioned) do
25
+ parser.receive_data("\n")
26
+ end
27
+ end
28
+
29
+ def test_read_integer
30
+ ":123".each_char do |c|
31
+ parser.receive_data(c)
32
+ end
33
+ assert_equal [], log
34
+
35
+ parser.receive_data("\r")
36
+ assert_equal [], log
37
+
38
+ parser.receive_data("\n")
39
+ assert_equal [[:value, 123]], log
40
+ end
41
+
42
+ def test_read_poisoned_integer
43
+ parser.receive_data(":1")
44
+ assert_raise(Fraggel::Decoder::Poisioned) do
45
+ parser.receive_data("X")
46
+ end
47
+ end
48
+
49
+ def test_read_string
50
+ "$4\r\nping".each_char do |c|
51
+ parser.receive_data(c)
52
+ end
53
+ assert_equal [], log
54
+
55
+ parser.receive_data("\r")
56
+ assert_equal [], log
57
+
58
+ parser.receive_data("\n")
59
+ assert_equal [[:value, "ping"]], log
60
+ end
61
+
62
+ def test_read_poisoned_string
63
+ parser.receive_data("$1")
64
+ assert_raise(Fraggel::Decoder::Poisioned) do
65
+ parser.receive_data("X")
66
+ end
67
+ end
68
+
69
+ def test_read_true
70
+ "+OK".each_char do |c|
71
+ parser.receive_data(c)
72
+ end
73
+ assert_equal [], log
74
+
75
+ parser.receive_data("\r")
76
+ assert_equal [], log
77
+
78
+ parser.receive_data("\n")
79
+ assert_equal [[:status, "OK"]], log
80
+ end
81
+
82
+ def test_read_false
83
+ "-ERR".each_char do |c|
84
+ parser.receive_data(c)
85
+ end
86
+ assert_equal [], log
87
+
88
+ parser.receive_data("\r")
89
+ assert_equal [], log
90
+
91
+ parser.receive_data("\n")
92
+ assert_equal [[:error, "ERR"]], log
93
+ end
94
+
95
+ def test_read_array
96
+ "*1".each_char do |c|
97
+ parser.receive_data(c)
98
+ end
99
+ assert_equal [], log
100
+
101
+ parser.receive_data("\r")
102
+ assert_equal [], log
103
+
104
+ parser.receive_data("\n")
105
+ assert_equal [[:array, 1]], log
106
+ end
107
+
108
+ def test_all_types_together
109
+ "*2\r\n:1\r\n$3\r\nfoo\r\n+OK\r\n-ERR\r\n".each_char do |c|
110
+ parser.receive_data(c)
111
+ end
112
+
113
+ expected = [
114
+ [:array, 2],
115
+ [:value, 1],
116
+ [:value, "foo"],
117
+ [:status, "OK"],
118
+ [:error, "ERR"]
119
+ ]
120
+
121
+ assert_equal expected, log
122
+ end
123
+
124
+ end
@@ -0,0 +1,49 @@
1
+ require 'fraggel'
2
+
3
+ class FraggelEncoderTest < Test::Unit::TestCase
4
+
5
+ include Fraggel::Encoder
6
+
7
+ def test_blank_line
8
+ assert_equal "$-1\r\n", encode(nil)
9
+ end
10
+
11
+ def test_integer
12
+ assert_equal ":123\r\n", encode(123)
13
+ end
14
+
15
+ def test_string
16
+ assert_equal "$3\r\nfoo\r\n", encode("foo")
17
+ end
18
+
19
+ def test_error
20
+ assert_equal "-ERR: test\r\n", encode(StandardError.new("test"))
21
+ end
22
+
23
+ def test_exception
24
+ assert_equal "-ERR: test\r\n", encode(Exception.new("test"))
25
+ end
26
+
27
+ def test_true
28
+ assert_equal ":1\r\n", encode(true)
29
+ end
30
+
31
+ def test_false
32
+ assert_equal ":0\r\n", encode(false)
33
+ end
34
+
35
+ def test_array
36
+ assert_equal "*1\r\n$3\r\nfoo\r\n", encode(["foo"])
37
+ end
38
+
39
+ def test_status
40
+ assert_equal "+OK\r\n", encode(:OK)
41
+ end
42
+
43
+ def test_unknown
44
+ assert_raise Fraggel::Encoder::UnknownType do
45
+ encode Class
46
+ end
47
+ end
48
+
49
+ end
@@ -0,0 +1,91 @@
1
+ require 'fraggel/responder'
2
+
3
+ class FraggelResponderTest < Test::Unit::TestCase
4
+
5
+ attr_reader :responder
6
+ attr_reader :log
7
+
8
+ def setup
9
+ @log = []
10
+ @responder = Fraggel::Responder.new do |x|
11
+ @log << x
12
+ end
13
+ end
14
+
15
+ def test_integer
16
+ responder.receive_event(:value, 1)
17
+ assert_equal [1], log
18
+ end
19
+
20
+ def test_string
21
+ responder.receive_event(:value, "foo")
22
+ assert_equal ["foo"], log
23
+ end
24
+
25
+ def test_error
26
+ responder.receive_event(:error, "ERR: test")
27
+ # TODO: Find a better way to assert this
28
+ assert_equal 1, log.length
29
+ assert_equal StandardError, log[0].class
30
+ assert_equal "ERR: test", log[0].message
31
+ end
32
+
33
+ def test_status
34
+ responder.receive_event(:status, "OK")
35
+ assert_equal [:OK], log
36
+ end
37
+
38
+ def test_array
39
+ responder.receive_event(:array, 1)
40
+ responder.receive_event(:value, 2)
41
+ assert_equal [[2]], log
42
+ end
43
+
44
+ def test_nested_arrays
45
+ responder.receive_event(:array, 1)
46
+ responder.receive_event(:array, 2)
47
+ responder.receive_event(:value, 2)
48
+ responder.receive_event(:array, 1)
49
+ responder.receive_event(:value, "foo")
50
+ assert_equal [[[2, ["foo"]]]], log
51
+ end
52
+
53
+ def test_deep_nested_array
54
+ # Arrays are indented for clarity
55
+ responder.receive_event(:value, 1)
56
+ responder.receive_event(:array, 3)
57
+ responder.receive_event(:value, "a")
58
+ responder.receive_event(:array, 1)
59
+ responder.receive_event(:value, "b")
60
+ responder.receive_event(:value, "c")
61
+ responder.receive_event(:value, 2)
62
+
63
+
64
+ assert_equal [1, ["a", ["b"], "c"], 2], log
65
+ end
66
+
67
+ def test_real
68
+ responder.receive_event(:array, 3)
69
+ responder.receive_event(:value, 1)
70
+ responder.receive_event(:value, 1)
71
+ responder.receive_event(:array, 3)
72
+ responder.receive_event(:value, "/test/a")
73
+ responder.receive_event(:value, "1")
74
+ responder.receive_event(:value, "99")
75
+
76
+ responder.receive_event(:array, 3)
77
+ responder.receive_event(:value, 1)
78
+ responder.receive_event(:value, 1)
79
+ responder.receive_event(:array, 3)
80
+ responder.receive_event(:value, "/test/b")
81
+ responder.receive_event(:value, "2")
82
+ responder.receive_event(:value, "123")
83
+
84
+ assert_equal [
85
+ [1, 1, ["/test/a", "1", "99"]],
86
+ [1, 1, ["/test/b", "2", "123"]]
87
+ ], log
88
+ end
89
+
90
+
91
+ end
@@ -0,0 +1,522 @@
1
+ require 'fraggel'
2
+
3
+ class FraggelTest < Test::Unit::TestCase
4
+ include Fraggel::Encoder
5
+
6
+ attr_reader :client, :response
7
+
8
+ class FakeFraggel
9
+ include Fraggel
10
+
11
+ attr_reader :sent, :called
12
+
13
+ ## Expose @callbacks for tests
14
+ attr_reader :callbacks
15
+
16
+ def initialize
17
+ @sent = ""
18
+ @called = []
19
+ end
20
+
21
+ def call(*args)
22
+ @called << args
23
+ super(*args)
24
+ end
25
+
26
+ def send_data(data)
27
+ @sent << data
28
+ end
29
+ end
30
+
31
+ def setup
32
+ @response = []
33
+ @client = FakeFraggel.new
34
+
35
+ # Fake a successful connection
36
+ @client.post_init
37
+ end
38
+
39
+ def respond(response)
40
+ client.receive_data(encode(response))
41
+ end
42
+
43
+
44
+ ##
45
+ # call
46
+ #
47
+ def test_call_sends_data
48
+ client.call :TEST do
49
+ # Do nothing
50
+ end
51
+
52
+ assert_equal encode([1, "TEST"]), client.sent
53
+ end
54
+
55
+ def test_call_calls_callback
56
+ opid = client.call :TEST do |x|
57
+ @response = x
58
+ end
59
+
60
+ respond [opid, Fraggel::Valid, :CALLED]
61
+
62
+ # Make sure the callback is called
63
+ assert_equal :CALLED, response
64
+ end
65
+
66
+ def test_call_holds_undone_callback
67
+ callback = Proc.new do |x|
68
+ # Do nothing
69
+ end
70
+
71
+ opid = client.call :TEST, &callback
72
+
73
+ respond [opid, Fraggel::Valid, :CALLED]
74
+
75
+ # Make sure the callback is held
76
+ assert_equal callback, client.callbacks[opid]
77
+ end
78
+
79
+ def test_done
80
+ @response = []
81
+ opid = client.call :TEST do |err|
82
+ @response << err
83
+ end
84
+
85
+ respond [opid, Fraggel::Done]
86
+
87
+ assert_equal [:done], response
88
+ assert_nil client.callbacks[opid]
89
+ end
90
+
91
+ def test_valid_and_done
92
+ @response = []
93
+ opid = client.call :TEST do |err|
94
+ @response << err
95
+ end
96
+
97
+ respond [opid, Fraggel::Valid | Fraggel::Done]
98
+
99
+ assert_equal [nil, :done], response
100
+ assert_nil client.callbacks[opid]
101
+ end
102
+
103
+ ##
104
+ # GET
105
+ #
106
+ def test_get_call
107
+ client.get("/ping") {}
108
+ client.get("/ping", 123) {}
109
+ expected = [
110
+ [:GET, ["/ping", 0]],
111
+ [:GET, ["/ping", 123]],
112
+ ]
113
+ assert_equal expected, client.called
114
+ end
115
+
116
+ def test_get_entry
117
+ opid = client.get "/ping" do |body, cas, err|
118
+ @response = [body, cas, err]
119
+ end
120
+
121
+ respond [opid, Fraggel::Valid | Fraggel::Done, [["pong"], "99"]]
122
+ body, cas, err = response
123
+
124
+ assert_nil err
125
+ assert_equal ["pong"], body
126
+ assert_equal "99", cas
127
+ assert ! cas.dir?
128
+ end
129
+
130
+ def test_get_error
131
+ opid = client.get "/ping" do |body, cas, err|
132
+ @response = [body, cas, err]
133
+ end
134
+
135
+ respond [opid, Fraggel::Valid, StandardError.new("test")]
136
+ body, cas, err = response
137
+
138
+ assert_nil body
139
+ assert_nil cas
140
+ assert_equal StandardError, err.class
141
+ assert_equal "ERR: test", err.message
142
+ end
143
+
144
+ def test_get_directory
145
+ opid = client.get "/letters" do |body, cas, err|
146
+ @response = [body, cas, err]
147
+ end
148
+
149
+ entries = ["a", "b", "c"]
150
+ respond [opid, Fraggel::Valid | Fraggel::Done, [entries, Fraggel::Dir]]
151
+ body, cas, err = response
152
+
153
+ assert_nil err
154
+ assert_equal entries, body
155
+ assert_equal Fraggel::Dir, cas
156
+ assert cas.dir?
157
+ end
158
+
159
+ ##
160
+ # SET
161
+ #
162
+ def test_set_call
163
+ client.set("/foo", "bar", "99") {}
164
+ client.set("/foo", "bar", :missing) {}
165
+ client.set("/foo", "bar", :clobber) {}
166
+ expected = [
167
+ [:SET, ["/foo", "bar", "99"]],
168
+ [:SET, ["/foo", "bar", "0"]],
169
+ [:SET, ["/foo", "bar", ""]]
170
+ ]
171
+ assert_equal expected, client.called
172
+ end
173
+
174
+ def test_set
175
+ opid = client.set "/letters/a", "1", "99" do |cas, err|
176
+ @response = [cas, err]
177
+ end
178
+
179
+ respond [opid, Fraggel::Valid | Fraggel::Done, "99"]
180
+ cas, err = response
181
+
182
+ # Check err and body
183
+ assert_nil err
184
+ assert_equal "99", cas
185
+ assert ! cas.dir?
186
+ end
187
+
188
+ def test_set_error
189
+ opid = client.set "/letters/a", "1", "99" do |cas, err|
190
+ @response = [cas, err]
191
+ end
192
+
193
+ respond [opid, Fraggel::Valid | Fraggel::Done, StandardError.new("cas mismatch")]
194
+ cas, err = response
195
+
196
+ assert_equal StandardError, err.class
197
+ assert_equal "ERR: cas mismatch", err.message
198
+ assert_nil cas
199
+ end
200
+
201
+ ##
202
+ # SETT
203
+ #
204
+ def test_sett_call
205
+ client.sett("/foo", 100, "99") {}
206
+ client.sett("/foo", 100, :missing) {}
207
+ client.sett("/foo", 100, :clobber) {}
208
+ expected = [
209
+ [:SETT, ["/foo", 100, "99"]],
210
+ [:SETT, ["/foo", 100, "0"]],
211
+ [:SETT, ["/foo", 100, ""]]
212
+ ]
213
+ assert_equal expected, client.called
214
+ end
215
+
216
+ def test_sett
217
+ opid = client.sett "/timer/a", 100, "99" do |t, cas, err|
218
+ @response = [t, cas, err]
219
+ end
220
+
221
+ respond [opid, Fraggel::Valid | Fraggel::Done, [1000, "99"]]
222
+ t, cas, err = response
223
+
224
+ assert_nil err
225
+ assert_equal 1000, t
226
+ assert_equal "99", cas
227
+ assert ! cas.dir?
228
+ end
229
+
230
+ def test_sett_error
231
+ opid = client.sett "/timer/a", 100, "99" do |t, cas, err|
232
+ @response = [t, cas, err]
233
+ end
234
+
235
+ respond [opid, Fraggel::Valid | Fraggel::Done, StandardError.new("test")]
236
+ t, cas, err = response
237
+
238
+ assert_equal StandardError, err.class
239
+ assert_equal "ERR: test", err.message
240
+ assert_nil t
241
+ assert_nil cas
242
+ end
243
+
244
+ ##
245
+ # CLOSE
246
+ #
247
+ def test_close_call
248
+ client.close(99) {}
249
+ expected = [
250
+ [:CLOSE, 99]
251
+ ]
252
+ assert_equal expected, client.called
253
+ end
254
+
255
+ def test_close
256
+ opid = client.close 99 do |err|
257
+ @response = err
258
+ end
259
+
260
+ respond [opid, Fraggel::Valid | Fraggel::Done, :OK]
261
+ assert_nil response
262
+ end
263
+
264
+ def test_close_error
265
+ opid = client.close 99 do |err|
266
+ @response = err
267
+ end
268
+
269
+ respond [opid, Fraggel::Valid | Fraggel::Done, StandardError.new("test")]
270
+ assert_equal StandardError, response.class
271
+ assert_equal "ERR: test", response.message
272
+ end
273
+
274
+ ##
275
+ # DEL
276
+ #
277
+ def test_del_call
278
+ client.del("/foo", "68") {}
279
+ expected = [
280
+ [:DEL, ["/foo", "68"]]
281
+ ]
282
+ assert_equal expected, client.called
283
+ end
284
+
285
+ def test_del
286
+ opid = client.del "/foo", "68" do |err|
287
+ @response = err
288
+ end
289
+
290
+ respond [opid, Fraggel::Valid | Fraggel::Done, :OK]
291
+ assert_nil response
292
+ end
293
+
294
+ def test_del_error
295
+ opid = client.del "/foo", "123" do |err|
296
+ @response = err
297
+ end
298
+
299
+ respond [opid, Fraggel::Valid | Fraggel::Done, StandardError.new("test")]
300
+ assert_equal StandardError, response.class
301
+ assert_equal "ERR: test", response.message
302
+ end
303
+
304
+ ##
305
+ # NOOP
306
+ #
307
+ def test_noop_call
308
+ client.noop() {}
309
+ expected = [
310
+ [:NOOP]
311
+ ]
312
+ assert_equal expected, client.called
313
+ end
314
+
315
+ def test_noop
316
+ opid = client.noop do |err|
317
+ @response = err
318
+ end
319
+
320
+ respond [opid, Fraggel::Valid | Fraggel::Done, :OK]
321
+ assert_nil response
322
+ end
323
+
324
+ def test_noop_error
325
+ opid = client.noop do |err|
326
+ @response = err
327
+ end
328
+
329
+ respond [opid, Fraggel::Valid | Fraggel::Done, StandardError.new("test")]
330
+ assert_equal StandardError, response.class
331
+ assert_equal "ERR: test", response.message
332
+ end
333
+
334
+ ##
335
+ # SNAP
336
+ #
337
+ def test_snap_call
338
+ client.snap() {}
339
+ expected = [
340
+ [:SNAP]
341
+ ]
342
+ assert_equal expected, client.called
343
+ end
344
+
345
+ def test_snap
346
+ opid = client.snap do |sid, err|
347
+ @response = [sid, err]
348
+ end
349
+
350
+ respond [opid, Fraggel::Valid | Fraggel::Done, 123]
351
+ sid, err = response
352
+
353
+ assert_nil err
354
+ assert_equal 123, sid
355
+ end
356
+
357
+ def test_snap_error
358
+ opid = client.snap do |sid, err|
359
+ @response = [sid, err]
360
+ end
361
+
362
+ respond [opid, Fraggel::Valid | Fraggel::Done, StandardError.new("test")]
363
+ sid, err = response
364
+
365
+ assert_equal StandardError, err.class
366
+ assert_equal "ERR: test", err.message
367
+ assert_nil sid
368
+ end
369
+
370
+ ##
371
+ # DELSNAP
372
+ #
373
+ def test_delsnap_call
374
+ client.delsnap() {}
375
+ expected = [
376
+ [:DELSNAP]
377
+ ]
378
+ assert_equal expected, client.called
379
+ end
380
+
381
+ def test_delsnap
382
+ opid = client.delsnap do |err|
383
+ @response = err
384
+ end
385
+
386
+ respond [opid, Fraggel::Valid | Fraggel::Done, 123]
387
+ sid, err = response
388
+
389
+ assert_nil err
390
+ end
391
+
392
+ def test_delsnap_error
393
+ opid = client.delsnap do |err|
394
+ @response = err
395
+ end
396
+
397
+ respond [opid, Fraggel::Valid | Fraggel::Done, StandardError.new("test")]
398
+ sid, err = response
399
+
400
+ assert_equal StandardError, err.class
401
+ assert_equal "ERR: test", err.message
402
+ end
403
+
404
+ ##
405
+ # WALK
406
+ #
407
+ def test_walk_call
408
+ client.walk("/test/**") {}
409
+ client.walk("/test/*", 123) {}
410
+ expected = [
411
+ [:WALK, ["/test/**", 0]],
412
+ [:WALK, ["/test/*", 123]],
413
+ ]
414
+ assert_equal expected, client.called
415
+ end
416
+
417
+ def test_walk
418
+ opid = client.walk "/test/**" do |path, body, cas, err|
419
+ @response = [path, body, cas, err]
420
+ end
421
+
422
+ respond [opid, Fraggel::Valid, ["/test/a", "1", "99"]]
423
+ path, body, cas, err = response
424
+
425
+ assert_nil err
426
+ assert_equal "/test/a", path
427
+ assert_equal "1", body
428
+ assert_equal "99", cas
429
+ assert ! cas.dir?
430
+
431
+ respond [opid, Fraggel::Valid, ["/test/b", "2", "123"]]
432
+ path, body, cas, err = response
433
+
434
+ assert_nil err
435
+ assert_equal "/test/b", path
436
+ assert_equal "2", body
437
+ assert_equal "123", cas
438
+ assert ! cas.dir?
439
+
440
+ respond [opid, Fraggel::Done]
441
+ path, body, cas, err = response
442
+
443
+ assert_equal :done, err
444
+ assert_nil path
445
+ assert_nil body
446
+ assert_nil cas
447
+ end
448
+
449
+ def test_walk_error
450
+ opid = client.walk "/test/**" do |path, body, cas, err|
451
+ @response = [path, body, cas, err]
452
+ end
453
+
454
+ respond [opid, Fraggel::Valid, StandardError.new("test")]
455
+ path, body, cas, err = response
456
+
457
+ assert_equal StandardError, err.class
458
+ assert_equal "ERR: test", err.message
459
+ assert_nil path
460
+ assert_nil body
461
+ assert_nil cas
462
+ end
463
+
464
+ ##
465
+ # WATCH
466
+ #
467
+ def test_watch_call
468
+ client.watch("/test/**") {}
469
+ expected = [
470
+ [:WATCH, "/test/**"],
471
+ ]
472
+ assert_equal expected, client.called
473
+ end
474
+
475
+ def test_watch
476
+ opid = client.watch "/test/**" do |path, body, cas, err|
477
+ @response = [path, body, cas, err]
478
+ end
479
+
480
+ respond [opid, Fraggel::Valid, ["/test/a", "1", "99"]]
481
+ path, body, cas, err = response
482
+
483
+ assert_nil err
484
+ assert_equal "/test/a", path
485
+ assert_equal "1", body
486
+ assert_equal "99", cas
487
+ assert ! cas.dir?
488
+
489
+ respond [opid, Fraggel::Valid, ["/test/b", "2", "123"]]
490
+ path, body, cas, err = response
491
+
492
+ assert_nil err
493
+ assert_equal "/test/b", path
494
+ assert_equal "2", body
495
+ assert_equal "123", cas
496
+ assert ! cas.dir?
497
+
498
+ respond [opid, Fraggel::Done]
499
+ path, body, cas, err = response
500
+
501
+ assert_equal :done, err
502
+ assert_nil path
503
+ assert_nil body
504
+ assert_nil cas
505
+ end
506
+
507
+ def test_watch_error
508
+ opid = client.watch "/test/**" do |path, body, cas, err|
509
+ @response = [path, body, cas, err]
510
+ end
511
+
512
+ respond [opid, Fraggel::Valid, StandardError.new("test")]
513
+ path, body, cas, err = response
514
+
515
+ assert_equal StandardError, err.class
516
+ assert_equal "ERR: test", err.message
517
+ assert_nil path
518
+ assert_nil body
519
+ assert_nil cas
520
+ end
521
+
522
+ end