functional-ruby 0.7.7 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +92 -152
  3. data/doc/memo.txt +192 -0
  4. data/doc/pattern_matching.txt +485 -0
  5. data/doc/protocol.txt +221 -0
  6. data/doc/record.txt +144 -0
  7. data/doc/thread_safety.txt +8 -0
  8. data/lib/functional.rb +48 -18
  9. data/lib/functional/abstract_struct.rb +161 -0
  10. data/lib/functional/delay.rb +117 -0
  11. data/lib/functional/either.rb +222 -0
  12. data/lib/functional/memo.rb +93 -0
  13. data/lib/functional/method_signature.rb +72 -0
  14. data/lib/functional/option.rb +209 -0
  15. data/lib/functional/pattern_matching.rb +117 -100
  16. data/lib/functional/protocol.rb +157 -0
  17. data/lib/functional/protocol_info.rb +193 -0
  18. data/lib/functional/record.rb +155 -0
  19. data/lib/functional/type_check.rb +112 -0
  20. data/lib/functional/union.rb +152 -0
  21. data/lib/functional/version.rb +3 -1
  22. data/spec/functional/abstract_struct_shared.rb +154 -0
  23. data/spec/functional/complex_pattern_matching_spec.rb +205 -0
  24. data/spec/functional/configuration_spec.rb +17 -0
  25. data/spec/functional/delay_spec.rb +147 -0
  26. data/spec/functional/either_spec.rb +237 -0
  27. data/spec/functional/memo_spec.rb +207 -0
  28. data/spec/functional/option_spec.rb +292 -0
  29. data/spec/functional/pattern_matching_spec.rb +279 -276
  30. data/spec/functional/protocol_info_spec.rb +444 -0
  31. data/spec/functional/protocol_spec.rb +274 -0
  32. data/spec/functional/record_spec.rb +175 -0
  33. data/spec/functional/type_check_spec.rb +103 -0
  34. data/spec/functional/union_spec.rb +110 -0
  35. data/spec/spec_helper.rb +6 -4
  36. metadata +55 -45
  37. data/lib/functional/behavior.rb +0 -138
  38. data/lib/functional/behaviour.rb +0 -2
  39. data/lib/functional/catalog.rb +0 -487
  40. data/lib/functional/collection.rb +0 -403
  41. data/lib/functional/inflect.rb +0 -127
  42. data/lib/functional/platform.rb +0 -120
  43. data/lib/functional/search.rb +0 -132
  44. data/lib/functional/sort.rb +0 -41
  45. data/lib/functional/utilities.rb +0 -189
  46. data/md/behavior.md +0 -188
  47. data/md/catalog.md +0 -32
  48. data/md/collection.md +0 -32
  49. data/md/inflect.md +0 -32
  50. data/md/pattern_matching.md +0 -512
  51. data/md/platform.md +0 -32
  52. data/md/search.md +0 -32
  53. data/md/sort.md +0 -32
  54. data/md/utilities.md +0 -55
  55. data/spec/functional/behavior_spec.rb +0 -528
  56. data/spec/functional/catalog_spec.rb +0 -1206
  57. data/spec/functional/collection_spec.rb +0 -752
  58. data/spec/functional/inflect_spec.rb +0 -85
  59. data/spec/functional/integration_spec.rb +0 -205
  60. data/spec/functional/platform_spec.rb +0 -501
  61. data/spec/functional/search_spec.rb +0 -187
  62. data/spec/functional/sort_spec.rb +0 -61
  63. data/spec/functional/utilities_spec.rb +0 -277
@@ -1,32 +0,0 @@
1
- # Platform
2
-
3
- TBD...
4
-
5
- ## Copyright
6
-
7
- *Functional Ruby* is Copyright © 2013 [Jerry D'Antonio](https://twitter.com/jerrydantonio).
8
- It is free software and may be redistributed under the terms specified in the LICENSE file.
9
-
10
- ## License
11
-
12
- Released under the MIT license.
13
-
14
- http://www.opensource.org/licenses/mit-license.php
15
-
16
- > Permission is hereby granted, free of charge, to any person obtaining a copy
17
- > of this software and associated documentation files (the "Software"), to deal
18
- > in the Software without restriction, including without limitation the rights
19
- > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
20
- > copies of the Software, and to permit persons to whom the Software is
21
- > furnished to do so, subject to the following conditions:
22
- >
23
- > The above copyright notice and this permission notice shall be included in
24
- > all copies or substantial portions of the Software.
25
- >
26
- > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27
- > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28
- > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29
- > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30
- > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31
- > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
32
- > THE SOFTWARE.
@@ -1,32 +0,0 @@
1
- # Search
2
-
3
- TBD...
4
-
5
- ## Copyright
6
-
7
- *Functional Ruby* is Copyright © 2013 [Jerry D'Antonio](https://twitter.com/jerrydantonio).
8
- It is free software and may be redistributed under the terms specified in the LICENSE file.
9
-
10
- ## License
11
-
12
- Released under the MIT license.
13
-
14
- http://www.opensource.org/licenses/mit-license.php
15
-
16
- > Permission is hereby granted, free of charge, to any person obtaining a copy
17
- > of this software and associated documentation files (the "Software"), to deal
18
- > in the Software without restriction, including without limitation the rights
19
- > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
20
- > copies of the Software, and to permit persons to whom the Software is
21
- > furnished to do so, subject to the following conditions:
22
- >
23
- > The above copyright notice and this permission notice shall be included in
24
- > all copies or substantial portions of the Software.
25
- >
26
- > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27
- > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28
- > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29
- > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30
- > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31
- > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
32
- > THE SOFTWARE.
data/md/sort.md DELETED
@@ -1,32 +0,0 @@
1
- # Sort
2
-
3
- TBD...
4
-
5
- ## Copyright
6
-
7
- *Functional Ruby* is Copyright © 2013 [Jerry D'Antonio](https://twitter.com/jerrydantonio).
8
- It is free software and may be redistributed under the terms specified in the LICENSE file.
9
-
10
- ## License
11
-
12
- Released under the MIT license.
13
-
14
- http://www.opensource.org/licenses/mit-license.php
15
-
16
- > Permission is hereby granted, free of charge, to any person obtaining a copy
17
- > of this software and associated documentation files (the "Software"), to deal
18
- > in the Software without restriction, including without limitation the rights
19
- > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
20
- > copies of the Software, and to permit persons to whom the Software is
21
- > furnished to do so, subject to the following conditions:
22
- >
23
- > The above copyright notice and this permission notice shall be included in
24
- > all copies or substantial portions of the Software.
25
- >
26
- > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27
- > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28
- > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29
- > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30
- > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31
- > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
32
- > THE SOFTWARE.
@@ -1,55 +0,0 @@
1
- # Utility Functions
2
-
3
- Start by requiring the Functional Ruby gem:
4
-
5
- ```ruby
6
- require 'functional'
7
- ```
8
-
9
- This gives you access to a few constants and functions:
10
-
11
- ```ruby
12
- Infinity #=> Infinity
13
- NaN #=> NaN
14
-
15
- repl? #=> true when called under irb, pry, bundle console, or rails console
16
-
17
- safe(1, 2){|a, b| a + b} #=> 3
18
- safe{ eval 'puts "Hello World!"' } #=> SecurityError: Insecure operation
19
-
20
- pp_s [1,2,3,4] #=> "[1, 2, 3, 4]\n" props to Rha7
21
-
22
- delta(-1, 1) #=> 2
23
- delta({count: -1}, {count: 1}){|item| item[:count]} #=> 2
24
-
25
- repeatedly(10, 1){|previous| previous * 2 } #=> [2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
26
- ```
27
-
28
- ## Copyright
29
-
30
- *Functional Ruby* is Copyright © 2013 [Jerry D'Antonio](https://twitter.com/jerrydantonio).
31
- It is free software and may be redistributed under the terms specified in the LICENSE file.
32
-
33
- ## License
34
-
35
- Released under the MIT license.
36
-
37
- http://www.opensource.org/licenses/mit-license.php
38
-
39
- > Permission is hereby granted, free of charge, to any person obtaining a copy
40
- > of this software and associated documentation files (the "Software"), to deal
41
- > in the Software without restriction, including without limitation the rights
42
- > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
43
- > copies of the Software, and to permit persons to whom the Software is
44
- > furnished to do so, subject to the following conditions:
45
- >
46
- > The above copyright notice and this permission notice shall be included in
47
- > all copies or substantial portions of the Software.
48
- >
49
- > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
50
- > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
51
- > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
52
- > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
53
- > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
54
- > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
55
- > THE SOFTWARE.
@@ -1,528 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe '-behavior' do
4
-
5
- before(:each) do
6
- @__behavior_info__ = $__behavior_info__
7
- $__behavior_info__ = {}
8
- end
9
-
10
- after(:each) do
11
- $__behavior_info__ = @__behavior_info__
12
- end
13
-
14
- context 'behavior_info/2' do
15
-
16
- it 'accepts a symbol name' do
17
- behavior_info(:gen_foo, foo: 0)
18
- $__behavior_info__.keys.first.should eq :gen_foo
19
- end
20
-
21
- it 'accepts a string name' do
22
- behavior_info('gen_foo', foo: 0)
23
- $__behavior_info__.keys.first.should eq :gen_foo
24
- end
25
-
26
- it 'accepts zero function names' do
27
- behavior_info(:gen_foo)
28
- $__behavior_info__.keys.first.should eq :gen_foo
29
- end
30
-
31
- it 'accepts symbols for function names' do
32
- behavior_info(:gen_foo, foo: 0)
33
- $__behavior_info__.values.first.should == {foo: 0}
34
- end
35
-
36
- it 'accepts strings as function names' do
37
- behavior_info(:gen_foo, 'foo' => 0)
38
- $__behavior_info__.values.first.should == {foo: 0}
39
- end
40
-
41
- it 'accepts numeric arity values' do
42
- behavior_info(:gen_foo, foo: 0)
43
- $__behavior_info__.values.first.should == {foo: 0}
44
- end
45
-
46
- it 'accepts :any as an arity value' do
47
- behavior_info(:gen_foo, foo: :any)
48
- $__behavior_info__.values.first.should == {foo: :any}
49
- end
50
- end
51
-
52
- context 'behavior/1' do
53
-
54
- it 'raises an exception if the behavior has not been defined' do
55
- lambda {
56
- Class.new{
57
- behavior(:gen_foo)
58
- }
59
- }.should raise_error(BehaviorError)
60
- end
61
-
62
- it 'can be called multiple times for one class' do
63
- behavior_info(:gen_foo, foo: 0)
64
- behavior_info(:gen_bar, bar: 0)
65
-
66
- lambda {
67
- Class.new{
68
- behavior(:gen_foo)
69
- behavior(:gen_bar)
70
- }
71
- }.should_not raise_error
72
- end
73
- end
74
-
75
- context 'object creation' do
76
-
77
- it 'checks all required behaviors' do
78
- behavior_info(:gen_foo, foo: 0)
79
- behavior_info(:gen_bar, bar: 1)
80
-
81
- clazz = Class.new {
82
- behavior(:gen_foo)
83
- behavior(:gen_bar)
84
- def foo() nil; end
85
- }
86
- lambda{ clazz.new }.should raise_error(BehaviorError)
87
-
88
- clazz = Class.new {
89
- behavior(:gen_foo)
90
- behavior(:gen_bar)
91
- def bar() nil; end
92
- }
93
- lambda{ clazz.new }.should raise_error(BehaviorError)
94
-
95
- clazz = Class.new {
96
- behavior(:gen_foo)
97
- behavior(:gen_bar)
98
- }
99
- lambda{ clazz.new }.should raise_error(BehaviorError)
100
- end
101
-
102
- it 'allows constructor check to be permanently disabled when gem loaded' do
103
-
104
- @original_config = $ENABLE_BEHAVIOR_CHECK_ON_CONSTRUCTION
105
-
106
- behavior_info(:gen_foo, foo: 0)
107
-
108
- $ENABLE_BEHAVIOR_CHECK_ON_CONSTRUCTION = true
109
- load(File.join(File.dirname(__FILE__), '../../', 'lib/functional/behavior.rb'))
110
- clazz = Class.new { behavior(:gen_foo) }
111
- expect { clazz.new }.to raise_error(BehaviorError)
112
-
113
- $ENABLE_BEHAVIOR_CHECK_ON_CONSTRUCTION = false
114
- load(File.join(File.dirname(__FILE__), '../../', 'lib/functional/behavior.rb'))
115
- clazz = Class.new { behavior(:gen_foo) }
116
- expect { clazz.new }.not_to raise_error()
117
-
118
- $ENABLE_BEHAVIOR_CHECK_ON_CONSTRUCTION = @original_config
119
- load(File.join(File.dirname(__FILE__), '../../', 'lib/functional/behavior.rb'))
120
- end
121
-
122
- context 'instance methods' do
123
-
124
- it 'raises an exception when one or more function definitions are missing' do
125
- behavior_info(:gen_foo, foo: 0, bar: 1)
126
- clazz = Class.new {
127
- behavior(:gen_foo)
128
- def foo() nil; end
129
- }
130
-
131
- lambda {
132
- clazz.new
133
- }.should raise_error(BehaviorError)
134
- end
135
-
136
- it 'raises an exception when one or more functions do not have proper arity' do
137
- behavior_info(:gen_foo, foo: 0)
138
- clazz = Class.new {
139
- behavior(:gen_foo)
140
- def foo(broken) nil; end
141
- }
142
-
143
- lambda {
144
- clazz.new
145
- }.should raise_error(BehaviorError)
146
- end
147
-
148
- it 'accepts any arity when function arity is set to :any' do
149
- behavior_info(:gen_foo, foo: :any)
150
- clazz = Class.new {
151
- behavior(:gen_foo)
152
- def foo(first) nil; end
153
- }
154
-
155
- lambda {
156
- clazz.new
157
- }.should_not raise_error
158
- end
159
-
160
- it 'creates the object when function definitions match' do
161
- behavior_info(:gen_foo, foo: 0, bar: 1)
162
- clazz = Class.new {
163
- behavior(:gen_foo)
164
- def foo() nil; end
165
- def bar(first) nil; end
166
- }
167
-
168
- lambda {
169
- clazz.new
170
- }.should_not raise_error
171
- end
172
- end
173
-
174
- context 'class methods' do
175
-
176
- it 'raises an exception when one or more function definitions are missing' do
177
- behavior_info(:gen_foo, self_foo: 0, self_bar: 1)
178
- clazz = Class.new {
179
- behavior(:gen_foo)
180
- def self.foo() nil; end
181
- }
182
-
183
- lambda {
184
- clazz.new
185
- }.should raise_error(BehaviorError)
186
- end
187
-
188
- it 'raises an exception when one or more functions do not have proper arity' do
189
- behavior_info(:gen_foo, self_foo: 0)
190
- clazz = Class.new {
191
- behavior(:gen_foo)
192
- def self.foo(broken) nil; end
193
- }
194
-
195
- lambda {
196
- clazz.new
197
- }.should raise_error(BehaviorError)
198
- end
199
-
200
- it 'accepts any arity when function arity is set to :any' do
201
- behavior_info(:gen_foo, self_foo: :any)
202
- clazz = Class.new {
203
- behavior(:gen_foo)
204
- def self.foo(first) nil; end
205
- }
206
-
207
- lambda {
208
- clazz.new
209
- }.should_not raise_error
210
- end
211
-
212
- it 'creates the object when function definitions match' do
213
- behavior_info(:gen_foo, self_foo: 0, self_bar: 1)
214
- clazz = Class.new {
215
- behavior(:gen_foo)
216
- def self.foo() nil; end
217
- def self.bar(first) nil; end
218
- }
219
-
220
- lambda {
221
- clazz.new
222
- }.should_not raise_error
223
- end
224
- end
225
-
226
- context 'inheritance' do
227
-
228
- it 'raises an exception if a superclass includes a behavior the subclass does not support' do
229
- behavior_info(:gen_foo, foo: 0)
230
- superclass = Class.new{
231
- behavior(:gen_foo)
232
- }
233
- subclass = Class.new(superclass)
234
-
235
- lambda {
236
- subclass.new
237
- }.should raise_error(BehaviorError)
238
- end
239
-
240
- it 'raises an exception if a module includes a behavior the containing class does not support' do
241
- behavior_info(:gen_foo, foo: 0)
242
- mod = Module.new{
243
- behavior(:gen_foo)
244
- }
245
- subclass = Class.new{
246
- include mod
247
- }
248
-
249
- lambda {
250
- subclass.new
251
- }.should raise_error(BehaviorError)
252
- end
253
-
254
- it 'supports behaviors from multiple ancestors' do
255
- behavior_info(:gen_foo, foo: 0)
256
- behavior_info(:gen_bar, bar: 0)
257
- behavior_info(:gen_baz, baz: 0)
258
-
259
- rootclass = Class.new{ behavior(:gen_foo) }
260
- superclass = Class.new(rootclass){ behavior(:gen_bar) }
261
-
262
- subclass = Class.new(superclass){
263
- behavior(:gen_baz)
264
- def bar() nil; end
265
- def baz() nil; end
266
- }
267
- lambda {
268
- subclass.new
269
- }.should raise_error(BehaviorError)
270
-
271
- subclass = Class.new(superclass){
272
- behavior(:gen_baz)
273
- def foo() nil; end
274
- def baz() nil; end
275
- }
276
- lambda {
277
- subclass.new
278
- }.should raise_error(BehaviorError)
279
-
280
- subclass = Class.new(superclass){
281
- behavior(:gen_baz)
282
- def foo() nil; end
283
- def bar() nil; end
284
- }
285
- lambda {
286
- subclass.new
287
- }.should raise_error(BehaviorError)
288
-
289
- subclass = Class.new(superclass){
290
- behavior(:gen_baz)
291
- def foo() nil; end
292
- def bar() nil; end
293
- def baz() nil; end
294
- }
295
- lambda {
296
- subclass.new
297
- }.should_not raise_error
298
- end
299
-
300
- it 'supports multiple behaviors in an included module' do
301
- behavior_info(:gen_foo, foo: 0)
302
- behavior_info(:gen_bar, bar: 0)
303
- behavior_info(:gen_baz, baz: 0)
304
-
305
- mod = Module.new{
306
- behavior(:gen_foo)
307
- behavior(:gen_bar)
308
- behavior(:gen_baz)
309
- }
310
-
311
- subclass = Class.new{
312
- include mod
313
- def bar() nil; end
314
- def baz() nil; end
315
- }
316
- lambda {
317
- subclass.new
318
- }.should raise_error(BehaviorError)
319
-
320
- subclass = Class.new{
321
- include mod
322
- def foo() nil; end
323
- def baz() nil; end
324
- }
325
- lambda {
326
- subclass.new
327
- }.should raise_error(BehaviorError)
328
-
329
- subclass = Class.new{
330
- include mod
331
- def foo() nil; end
332
- def bar() nil; end
333
- }
334
- lambda {
335
- subclass.new
336
- }.should raise_error(BehaviorError)
337
-
338
- subclass = Class.new{
339
- include mod
340
- def foo() nil; end
341
- def bar() nil; end
342
- def baz() nil; end
343
- }
344
- lambda {
345
- subclass.new
346
- }.should_not raise_error
347
- end
348
- end
349
- end
350
-
351
- context '#behaves_as?' do
352
-
353
- it 'returns false when the behavior does not exist' do
354
- clazz = Class.new { }
355
- clazz.new.behaves_as?(:gen_foo).should be_false
356
- end
357
-
358
- it 'accepts behavior name as a symbol' do
359
- behavior_info(:gen_foo)
360
- clazz = Class.new { }
361
- clazz.new.behaves_as?(:gen_foo).should be_true
362
- end
363
-
364
- it 'accepts behavior name as a string' do
365
- behavior_info(:gen_foo)
366
- clazz = Class.new { }
367
- clazz.new.behaves_as?('gen_foo').should be_true
368
- end
369
-
370
- context 'Object' do
371
-
372
- it 'returns true when the behavior is fully suported' do
373
- behavior_info(:gen_foo, foo: 0, bar: 1, baz: 2)
374
- clazz = Class.new {
375
- def foo() nil; end
376
- def bar(first) nil; end
377
- def baz(first, second) nil; end
378
- }
379
-
380
- clazz.new.behaves_as?(:gen_foo).should be_true
381
- end
382
-
383
- it 'accepts any arity when function arity is set to :any' do
384
- behavior_info(:gen_foo, foo: :any)
385
- clazz = Class.new {
386
- def foo(*args, &block) nil; end
387
- }
388
-
389
- clazz.new.behaves_as?(:gen_foo).should be_true
390
- end
391
-
392
- it 'returns false when the behavior is partially supported' do
393
- behavior_info(:gen_foo, foo: 0, bar: 1, baz: 2)
394
- clazz = Class.new {
395
- def foo() nil; end
396
- def bar(first) nil; end
397
- }
398
-
399
- clazz.new.behaves_as?(:gen_foo).should be_false
400
- end
401
-
402
- it 'returns false when the behavior is not supported at all' do
403
- behavior_info(:gen_foo, foo: 0, bar: 1, baz: 2)
404
- clazz = Class.new { }
405
- clazz.new.behaves_as?(:gen_foo).should be_false
406
- end
407
-
408
- it 'raises an exception on failure when abend is true' do
409
- behavior_info(:gen_foo, foo: 0)
410
- behavior_info(:gen_bar, self_bar: 1)
411
- behavior_info(:gen_baz, baz: :any)
412
- clazz = Class.new { }
413
-
414
- lambda {
415
- clazz.new.behaves_as?(:gen_foo, true)
416
- }.should raise_error(BehaviorError)
417
-
418
- lambda {
419
- clazz.new.behaves_as?(:gen_bar, true)
420
- }.should raise_error(BehaviorError)
421
-
422
- lambda {
423
- clazz.new.behaves_as?(:gen_baz, true)
424
- }.should raise_error(BehaviorError)
425
- end
426
-
427
- it 'exception includes the name and arity of the first missing function' do
428
- behavior_info(:gen_foo, foo: 0)
429
- behavior_info(:gen_bar, self_bar: 1)
430
- behavior_info(:gen_baz, baz: :any)
431
- clazz = Class.new { }
432
-
433
- begin
434
- clazz.new.behaves_as?(:gen_foo, true)
435
- rescue BehaviorError => ex
436
- ex.message.should =~ /foo\/0/
437
- end
438
-
439
- begin
440
- clazz.new.behaves_as?(:gen_bar, true)
441
- rescue BehaviorError => ex
442
- ex.message.should =~ /#self\.bar\/1/
443
- end
444
-
445
- begin
446
- clazz.new.behaves_as?(:gen_baz, true)
447
- rescue BehaviorError => ex
448
- ex.message.should =~ /#baz\/:any/
449
- end
450
- end
451
- end
452
-
453
- context 'Class' do
454
-
455
- it 'returns true when the behavior is fully suported' do
456
- behavior_info(:gen_foo, self_foo: 0, self_bar: 1, baz: 2)
457
- clazz = Class.new {
458
- def self.foo() nil; end
459
- def self.bar(first) nil; end
460
- def baz(first, second) nil; end
461
- }
462
-
463
- clazz.behaves_as?(:gen_foo).should be_true
464
- clazz.new.behaves_as?(:gen_foo).should be_true
465
- end
466
-
467
- it 'accepts any arity when function arity is set to :any' do
468
- behavior_info(:gen_foo, self_foo: :any)
469
- clazz = Class.new {
470
- def self.foo(*args, &block) nil; end
471
- }
472
-
473
- clazz.behaves_as?(:gen_foo).should be_true
474
- clazz.new.behaves_as?(:gen_foo).should be_true
475
- end
476
-
477
- it 'returns false when the behavior is partially supported' do
478
- behavior_info(:gen_foo, self_foo: 0, bar: 1, self_baz: 2)
479
- clazz = Class.new {
480
- def self.foo() nil; end
481
- def self(first) nil; end
482
- }
483
-
484
- clazz.behaves_as?(:gen_foo).should be_false
485
- clazz.new.behaves_as?(:gen_foo).should be_false
486
- end
487
-
488
- it 'returns false when the behavior is not supported at all' do
489
- behavior_info(:gen_foo, self_foo: 0, self_bar: 1, self_baz: 2)
490
- clazz = Class.new { }
491
- clazz.new.behaves_as?(:gen_foo).should be_false
492
- end
493
- end
494
- end
495
-
496
- context 'aliases' do
497
-
498
- it 'aliases behaviour_info for behavior_info' do
499
- behaviour_info(:gen_foo)
500
- clazz = Class.new { }
501
- clazz.new.behaves_as?(:gen_foo).should be_true
502
- end
503
-
504
- it 'aliases interface for behavior_info' do
505
- interface(:gen_foo)
506
- clazz = Class.new { }
507
- clazz.new.behaves_as?(:gen_foo).should be_true
508
- end
509
-
510
- it 'aliases behaviour for behavior' do
511
- behavior_info(:gen_foo, foo: 0)
512
- clazz = Class.new {
513
- behaviour(:gen_foo)
514
- def foo() nil; end
515
- }
516
- clazz.new.behaves_as?(:gen_foo).should be_true
517
- end
518
-
519
- it 'aliases behaves_as for behavior' do
520
- behavior_info(:gen_foo, foo: 0)
521
- clazz = Class.new {
522
- behaves_as :gen_foo
523
- def foo() nil; end
524
- }
525
- clazz.new.behaves_as?(:gen_foo).should be_true
526
- end
527
- end
528
- end