protocol 0.8.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,22 @@
1
+ require 'protocol'
2
+
3
+ # Protocol version of the Comparable module, that actually checks, if #<=>
4
+ # was implemented by the including (conforming) class.
5
+ Comparing = Protocol do
6
+ # Compares _self_ with _other_ and returns -1, 0, or +1 depending on whether
7
+ # _self_ is less than, equal to, or greater than _other_.
8
+ def <=>(other) end
9
+
10
+ include Comparable
11
+ end
12
+
13
+ # Protocol version of the Enumerable module, that actually checks, if #each
14
+ # was implemented by the including (conforming) class.
15
+ Enumerating = Protocol do
16
+ # Iterate over each element of this Enumerating class and pass it to the
17
+ # _block_. Because protocol cannot determine if a block is expected from a
18
+ # C-function, I left it out of the specification for now.
19
+ understand :each
20
+
21
+ include Enumerable
22
+ end
data/make_doc.rb ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+ # vim: set et sw=2 ts=2:
3
+
4
+ require 'rbconfig'
5
+
6
+ bindir = Config::CONFIG['bindir']
7
+ $outdir = 'doc/'
8
+ puts "Creating documentation in '#$outdir'."
9
+ system "#{bindir}/ruby #{bindir}/rdoc -S -d --main=Protocol -o #$outdir lib/protocol.rb"
@@ -0,0 +1,620 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require 'protocol'
5
+
6
+ class TestProtocol < Test::Unit::TestCase
7
+ TestProtocol_foo = Protocol do
8
+ check_failure :none
9
+
10
+ understand :foo
11
+ end
12
+
13
+ TestProtocol_foo_fail = Protocol do
14
+ understand :foo
15
+ end
16
+
17
+ TestProtocol_bar = Protocol do
18
+ understand :bar
19
+ end
20
+
21
+ TestProtocol_foo_bar_1 = Protocol do
22
+ include TestProtocol_foo
23
+ understand :bar
24
+ end
25
+
26
+ TestProtocol_foo_bar_1_fail = Protocol do
27
+ include TestProtocol_foo
28
+ understand :bar
29
+ end
30
+
31
+ TestProtocol_foo_bar_2 = Protocol do
32
+ include TestProtocol_foo
33
+ include TestProtocol_bar
34
+ end
35
+
36
+ TestProtocol_foo_bar_2_fail = Protocol do
37
+ check_failure :error
38
+
39
+ include TestProtocol_foo
40
+ include TestProtocol_bar
41
+ end
42
+
43
+ TestProtocolArgs = Protocol do
44
+ understand :bar, 2
45
+ understand :baz, 3
46
+ understand :foo, -1
47
+ end
48
+
49
+ TestProtocolArgsOverwritten = Protocol do
50
+ include TestProtocolArgs
51
+
52
+ def bar(a, b, c)
53
+ end
54
+
55
+ def foo(a)
56
+ end
57
+ end
58
+
59
+ TestProtocolBlock = Protocol do
60
+ def foo(x, &block)
61
+ end
62
+ end
63
+
64
+ TestProtocolPartial = Protocol do
65
+ check_failure :none
66
+
67
+ implementation
68
+
69
+ def map(&block)
70
+ result = []
71
+ each { |x| result << block.call(x) }
72
+ result
73
+ end
74
+
75
+ specification
76
+
77
+ def each(&block) end
78
+ end
79
+
80
+ TestProtocolPartial_fail = Protocol do
81
+ check_failure :error
82
+
83
+ def each(&block) end
84
+
85
+ implementation
86
+
87
+ def map(&block)
88
+ result = []
89
+ each { |x| result << block.call(x) }
90
+ result
91
+ end
92
+ end
93
+
94
+ TestProtocolWrapMethodPassedFoo = Protocol do
95
+ def foo(foo, *rest) end
96
+ end
97
+
98
+ TestProtocolWrapMethodPassedBar = Protocol do
99
+ def bar() end
100
+ end
101
+
102
+ TestProtocolWrapMethod = Protocol do
103
+ def foo_bar(foo, bar)
104
+ TestProtocolWrapMethodPassedFoo =~ foo
105
+ TestProtocolWrapMethodPassedBar =~ bar
106
+ end
107
+ end
108
+
109
+ TestProtocolPostcondition = Protocol do
110
+ def foo_bar(foo, bar)
111
+ postcondition { foo + bar == result }
112
+ end
113
+
114
+ def foo_bars(foo, *bars)
115
+ postcondition { bars.unshift(foo) == result }
116
+ end
117
+ end
118
+
119
+ TestProtocolPrecondition = Protocol do
120
+ def foo_bar(foo, bar)
121
+ precondition { foo == 5 }
122
+ precondition { bar == 7 }
123
+ end
124
+ end
125
+
126
+ class MyClass
127
+ def one_with_block(foo, &block) end
128
+ end
129
+
130
+ TestProtocolInheritance = Protocol do
131
+ inherit MyClass, :one_with_block
132
+ end
133
+
134
+ TestProtocolInheritanceC = Protocol do
135
+ inherit ::Array, :each, true
136
+ end
137
+
138
+ def test_define_protocol
139
+ foo_protocol = Protocol do
140
+ understand :foo
141
+ understand :bar
142
+ end
143
+ assert_kind_of Protocol::ProtocolModule, foo_protocol
144
+ assert_raises(Protocol::SpecificationError) do
145
+ foo2_protocol = Protocol do
146
+ understand :foo
147
+ understand :foo
148
+ end
149
+ end
150
+ foo3_protocol = Protocol do
151
+ understand :foo, 1
152
+ understand :bar
153
+ end
154
+ assert_kind_of Protocol::ProtocolModule, foo3_protocol
155
+ assert_equal foo_protocol[:bar], foo3_protocol[:bar]
156
+ assert_not_same foo_protocol[:bar], foo3_protocol[:bar]
157
+ assert_not_equal foo_protocol[:foo], foo3_protocol[:foo]
158
+ assert_not_same foo_protocol[:foo], foo3_protocol[:foo]
159
+ assert foo_protocol.understand?(:foo)
160
+ assert foo_protocol.understand?(:bar)
161
+ assert !foo_protocol.understand?(:baz)
162
+ assert foo3_protocol.understand?(:foo)
163
+ assert foo3_protocol.understand?(:foo, 1)
164
+ assert foo3_protocol.understand?(:bar)
165
+ assert !foo3_protocol.understand?(:baz)
166
+ assert_equal [ foo3_protocol[:bar] ], foo3_protocol.grep(/^b/)
167
+ end
168
+
169
+ def test_simple_without_fail
170
+ c1 = Class.new do
171
+ def foo; end
172
+
173
+ conform_to TestProtocol_foo
174
+ end
175
+ assert c1.conform_to?(TestProtocol_foo)
176
+ assert c1.new.conform_to?(TestProtocol_foo)
177
+ assert !c1.conform_to?(TestProtocol_foo_bar_1)
178
+ assert !c1.new.conform_to?(TestProtocol_foo_bar_1)
179
+ assert !c1.conform_to?(TestProtocol_bar)
180
+ assert !c1.new.conform_to?(TestProtocol_bar)
181
+ assert_equal 2, TestProtocol_foo_bar_1.check_failures(Object).size
182
+ assert_equal 2, TestProtocol_foo_bar_1.check_failures(Object.new).size
183
+ assert_equal 1, TestProtocol_foo_bar_1.check_failures(c1).size
184
+ assert_equal 1, TestProtocol_foo_bar_1.check_failures(c1.new).size
185
+
186
+ c2 = Class.new do
187
+ conform_to TestProtocol_foo
188
+ end
189
+ assert !c2.conform_to?(TestProtocol_foo)
190
+ assert !c2.new.conform_to?(TestProtocol_foo)
191
+ assert !c2.conform_to?(TestProtocol_foo_bar_1)
192
+ assert !c2.new.conform_to?(TestProtocol_foo_bar_1)
193
+ assert !c2.conform_to?(TestProtocol_bar)
194
+ assert !c2.new.conform_to?(TestProtocol_bar)
195
+ end
196
+
197
+ def test_simple_with_fail
198
+ c1 = Class.new do
199
+ def foo; end
200
+
201
+ conform_to TestProtocol_foo_fail
202
+ end
203
+ assert c1.conform_to?(TestProtocol_foo_fail)
204
+ assert c1.new.conform_to?(TestProtocol_foo_fail)
205
+ assert !c1.conform_to?(TestProtocol_foo_bar_1)
206
+ assert !c1.new.conform_to?(TestProtocol_foo_bar_1)
207
+ assert !c1.conform_to?(TestProtocol_bar)
208
+ assert !c1.new.conform_to?(TestProtocol_bar)
209
+
210
+ begin
211
+ c2 = Class.new do
212
+ conform_to TestProtocol_foo_fail
213
+ end
214
+ assert(false)
215
+ rescue Protocol::CheckFailed
216
+ assert(true)
217
+ rescue
218
+ assert(false)
219
+ end
220
+ end
221
+
222
+ def test_inclusion1_with_fail
223
+ begin
224
+ c = Class.new do
225
+ def bar; end
226
+ conform_to TestProtocol_foo_bar_1_fail
227
+ end
228
+ assert(false)
229
+ rescue Protocol::CheckFailed
230
+ assert(true)
231
+ rescue
232
+ assert(false)
233
+ end
234
+ end
235
+
236
+ def test_inclusion2
237
+ c = Class.new do
238
+ def foo; end
239
+ def bar; end
240
+ conform_to TestProtocol_foo_bar_1
241
+ end
242
+ assert(true)
243
+ assert c.conform_to?(TestProtocol_foo_bar_1)
244
+ end
245
+
246
+ def test_inclusion3
247
+ c = Class.new do
248
+ def bar; end
249
+ conform_to TestProtocol_foo_bar_2
250
+ end
251
+ assert !c.conform_to?(TestProtocol_foo_bar_2)
252
+ assert(false)
253
+ rescue Protocol::CheckFailed
254
+ assert(true)
255
+ rescue
256
+ assert(false)
257
+ end
258
+
259
+ # Check argument arity
260
+
261
+ def test_arity1
262
+ c = Class.new do
263
+ def bar(x, y) x + y end
264
+ def foo(*x) x end
265
+ def baz(x, y, z) Math.sqrt(x * x + y * y + z * z) end
266
+
267
+ conform_to TestProtocolArgs
268
+ end
269
+ assert c.conform_to?(TestProtocolArgs)
270
+ assert c.new.conform_to?(TestProtocolArgs)
271
+ rescue
272
+ assert(false)
273
+ end
274
+
275
+ def test_arity2
276
+ c = Class.new do
277
+ def bar(x, y) x + y end
278
+ def baz(x, y, z) Math.sqrt(x * x + y * y + z * z) end
279
+ def foo(x) x end
280
+
281
+ conform_to TestProtocolArgs
282
+ end
283
+ assert(false)
284
+ rescue Protocol::CheckFailed
285
+ assert(true)
286
+ rescue
287
+ assert(false)
288
+ end
289
+
290
+ def test_arity3
291
+ c = Class.new do
292
+ def bar(x, y) x + y end
293
+ def baz(x, y, z) Math.sqrt(x * x + y * y + z * z) end
294
+ def foo(x) x end
295
+
296
+ conform_to TestProtocolArgs
297
+ end
298
+ rescue Protocol::CheckFailed
299
+ assert(true)
300
+ rescue
301
+ assert(false)
302
+ end
303
+
304
+ def test_block
305
+ begin
306
+ c1 = Class.new do
307
+ def foo(x) end
308
+
309
+ conform_to TestProtocolBlock
310
+ end
311
+ rescue Protocol::CheckFailed
312
+ assert(true)
313
+ rescue
314
+ assert(false)
315
+ end
316
+ c1b = Class.new do
317
+ def foo(x) end
318
+ end
319
+ assert !c1b.new.conform_to?(TestProtocolBlock)
320
+ begin
321
+ c2 = Class.new do
322
+ def foo(x, &block) block[x] end
323
+
324
+ conform_to TestProtocolBlock
325
+ end
326
+ assert(true)
327
+ rescue Protocol::CheckFailed
328
+ assert(false)
329
+ rescue
330
+ assert(false)
331
+ end
332
+ begin
333
+ c3 = Class.new do
334
+ def foo(x) yield x end
335
+
336
+ conform_to TestProtocolBlock
337
+ end
338
+ assert(true)
339
+ rescue Protocol::CheckFailed
340
+ assert(false)
341
+ rescue
342
+ assert(false)
343
+ end
344
+ obj = Object.new
345
+ assert !obj.conform_to?(TestProtocolBlock)
346
+ def obj.foo(x, &b) end
347
+ assert obj.conform_to?(TestProtocolBlock)
348
+ end
349
+
350
+ def test_partial_without_fail
351
+ c1 = Class.new do
352
+ def each(&block)
353
+ (1..3).each(&block)
354
+ self
355
+ end
356
+
357
+ conform_to TestProtocolPartial
358
+ end
359
+ obj = c1.new
360
+ assert c1.conform_to?(TestProtocolPartial)
361
+ assert obj.conform_to?(TestProtocolPartial)
362
+ assert_equal [ 1, 4, 9], obj.map { |x| x * x }
363
+ assert_equal obj, obj.each { |x| x * x }
364
+
365
+ c2 = Class.new do
366
+ conform_to TestProtocolPartial
367
+ end
368
+ assert !c2.conform_to?(TestProtocolPartial)
369
+ assert !c2.new.conform_to?(TestProtocolPartial)
370
+ assert_raises(NoMethodError) { c2.new.map { |x| x * x } }
371
+ assert_equal obj, obj.each { |x| x * x }
372
+ end
373
+
374
+ def test_partial_with_fail
375
+ c1 = Class.new do
376
+ def each(&block)
377
+ (1..3).each(&block)
378
+ self
379
+ end
380
+
381
+ conform_to TestProtocolPartial_fail
382
+ end
383
+ obj = c1.new
384
+ assert c1.conform_to?(TestProtocolPartial)
385
+ assert obj.conform_to?(TestProtocolPartial)
386
+ assert_equal [ 1, 4, 9], obj.map { |x| x * x }
387
+ assert_equal obj, obj.each { |x| x * x }
388
+
389
+ begin
390
+ c2 = Class.new do
391
+ conform_to TestProtocolPartial_fail
392
+ end
393
+ assert(false)
394
+ rescue Protocol::CheckFailed
395
+ assert(true)
396
+ rescue
397
+ assert(false)
398
+ end
399
+ end
400
+
401
+ def test_overwrite
402
+ c = Class.new do
403
+ def bar(x, y, z) x + y + z end
404
+ def baz(x, y, z) Math.sqrt(x * x + y * y + z * z) end
405
+ def foo(x) x end
406
+
407
+ conform_to TestProtocolArgsOverwritten
408
+ end
409
+ assert c.conform_to?(TestProtocolArgsOverwritten)
410
+ rescue Protocol::CheckFailed
411
+ assert(false)
412
+ rescue
413
+ assert(false)
414
+ end
415
+
416
+ def test_messages
417
+ assert_equal %w[bar baz foo], TestProtocolArgs.messages.map { |x| x.name }
418
+ assert_equal [2, 3, -1], TestProtocolArgs.messages.map { |x| x.arity }
419
+ assert_equal "TestProtocol::TestProtocolArgs#bar(2), TestProtocol::TestProtocolArgs#baz(3), TestProtocol::TestProtocolArgs#foo(-1)", TestProtocolArgs.to_s
420
+ assert_equal %w[bar baz foo], TestProtocolArgsOverwritten.messages.map { |x| x.name }
421
+ assert_equal [3, 3, 1], TestProtocolArgsOverwritten.messages.map { |x| x.arity }
422
+ assert_equal "TestProtocol::TestProtocolArgsOverwritten#bar(3), TestProtocol::TestProtocolArgs#baz(3), TestProtocol::TestProtocolArgsOverwritten#foo(1)", TestProtocolArgsOverwritten.to_s
423
+ end
424
+
425
+ def test_wrapped_method
426
+ begin
427
+ c1 = Class.new do
428
+ def foo(foo, *rest) foo end
429
+
430
+ conform_to TestProtocolWrapMethodPassedFoo
431
+ end
432
+ assert(true)
433
+ rescue Protocol::CheckFailed
434
+ assert(false)
435
+ rescue
436
+ assert(false)
437
+ end
438
+ begin
439
+ c2 = Class.new do
440
+ def bar() :bar end
441
+
442
+ conform_to TestProtocolWrapMethodPassedBar
443
+ end
444
+ assert(true)
445
+ rescue Protocol::CheckFailed
446
+ assert(false)
447
+ rescue
448
+ assert(false)
449
+ end
450
+ begin
451
+ c3 = Class.new do
452
+ def foo_bar(foo, bar)
453
+ [ foo.foo(:foo, :baz), bar.bar ]
454
+ end
455
+
456
+ conform_to TestProtocolWrapMethod
457
+ end
458
+ assert(true)
459
+ rescue Protocol::CheckFailed
460
+ assert(false)
461
+ rescue
462
+ assert(false)
463
+ end
464
+ begin
465
+ assert_equal [:foo, :bar], c3.new.foo_bar(c1.new, c2.new)
466
+ rescue Protocol::CheckFailed
467
+ assert(false)
468
+ rescue
469
+ assert(false)
470
+ end
471
+ begin
472
+ c3.new.foo_bar c1.new, c1.new
473
+ assert(false)
474
+ rescue Protocol::CheckFailed
475
+ assert(true)
476
+ rescue
477
+ assert(false)
478
+ end
479
+ end
480
+
481
+ def test_precondition
482
+ begin
483
+ c1 = Class.new do
484
+ def foo_bar(foo, bar)
485
+ foo + bar
486
+ end
487
+
488
+ conform_to TestProtocolPrecondition
489
+ end
490
+ assert(true)
491
+ rescue Protocol::CheckFailed
492
+ assert(false)
493
+ rescue
494
+ assert(false)
495
+ end
496
+ assert_equal 5 + 7, c1.new.foo_bar(5, 7)
497
+ assert_raises(Protocol::PreconditionCheckError) { c1.new.foo_bar(5, 8) }
498
+ end
499
+
500
+ def test_postcondition
501
+ begin
502
+ c1 = Class.new do
503
+ def foo_bar(foo, bar)
504
+ foo + bar
505
+ end
506
+
507
+ def foo_bars(foo, *bars)
508
+ bars.unshift foo
509
+ end
510
+
511
+ conform_to TestProtocolPostcondition
512
+ end
513
+ c2 = Class.new do
514
+ def foo_bar(foo, bar)
515
+ foo + bar + 1
516
+ end
517
+
518
+ def foo_bars(foo, *bars)
519
+ bars.unshift foo
520
+ end
521
+
522
+ conform_to TestProtocolPostcondition
523
+ end
524
+ assert(true)
525
+ rescue Protocol::CheckFailed
526
+ assert(false)
527
+ rescue
528
+ assert(false)
529
+ end
530
+ assert_equal [5, 7], c1.new.foo_bars(5, 7)
531
+ assert_equal 5 + 7, c1.new.foo_bar(5, 7)
532
+ assert_equal [5, 7], c2.new.foo_bars(5, 7)
533
+ assert_raises(Protocol::PostconditionCheckError) { c2.new.foo_bar(5, 7) }
534
+ o1 = Object.new
535
+ def o1.foo_bar(foo, bar)
536
+ foo + bar
537
+ end
538
+ def o1.foo_bars(foo, *bars)
539
+ bars.unshift foo
540
+ end
541
+ assert TestProtocolPostcondition =~ o1
542
+ assert_equal [5, 7], o1.foo_bars(5, 7)
543
+ assert_equal 5 + 7, o1.foo_bar(5, 7)
544
+ o2 = Object.new
545
+ def o2.foo_bar(foo, bar)
546
+ foo + bar + 1
547
+ end
548
+ def o2.foo_bars(foo, *bars)
549
+ bars.unshift foo
550
+ end
551
+ assert TestProtocolPostcondition =~ o2
552
+ assert_equal [5, 7], o2.foo_bars(5, 7)
553
+ assert_raises(Protocol::PostconditionCheckError) { o2.foo_bar(5, 7) }
554
+ end
555
+
556
+ def test_inheritance
557
+ begin
558
+ c1 = Class.new do
559
+ conform_to TestProtocolInheritance
560
+ end
561
+ rescue Protocol::CheckFailed
562
+ assert(true)
563
+ rescue
564
+ assert(false)
565
+ end
566
+ begin
567
+ c2 = Class.new do
568
+ def one_with_block() end
569
+ conform_to TestProtocolInheritance
570
+ end
571
+ rescue Protocol::CheckFailed
572
+ assert(true)
573
+ rescue
574
+ assert(false)
575
+ end
576
+ begin
577
+ c3 = Class.new do
578
+ def one_with_block(foo) end
579
+ conform_to TestProtocolInheritance
580
+ end
581
+ rescue Protocol::CheckFailed
582
+ assert(true)
583
+ rescue
584
+ assert(false)
585
+ end
586
+ begin
587
+ c4 = Class.new do
588
+ def one_with_block(foo, &block) end
589
+ conform_to TestProtocolInheritance
590
+ end
591
+ assert(true)
592
+ rescue Protocol::CheckFailed
593
+ assert(false)
594
+ rescue
595
+ assert(false)
596
+ end
597
+ begin
598
+ c5 = Class.new do
599
+ def each() end
600
+ conform_to TestProtocolInheritanceC
601
+ end
602
+ rescue Protocol::CheckFailed
603
+ assert(true)
604
+ rescue
605
+ assert(false)
606
+ end
607
+ begin
608
+ c6 = Class.new do
609
+ def each(&block) end
610
+ conform_to TestProtocolInheritanceC
611
+ end
612
+ assert(true)
613
+ rescue Protocol::CheckFailed
614
+ assert(false)
615
+ rescue
616
+ assert(false)
617
+ end
618
+ end
619
+ end
620
+ # vim: set et sw=2 ts=2: