functional-ruby 0.7.7 → 1.0.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.
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