fraggel 0.1.0

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.
@@ -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