functional-ruby 0.7.1 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
data/md/utilities.md CHANGED
@@ -1,55 +1,55 @@
1
- # Utility Functions
2
-
3
- Convenience functions are not imported by default. They need a separate `require` statement:
4
-
5
- ```ruby
6
- require 'functional/utilities'
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
+ # Utility Functions
2
+
3
+ Convenience functions are not imported by default. They need a separate `require` statement:
4
+
5
+ ```ruby
6
+ require 'functional/utilities'
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,369 +1,464 @@
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
- context 'instance methods' do
103
-
104
- it 'raises an exception when one or more function definitions are missing' do
105
- behavior_info(:gen_foo, foo: 0, bar: 1)
106
- clazz = Class.new {
107
- behavior(:gen_foo)
108
- def foo() nil; end
109
- }
110
-
111
- lambda {
112
- clazz.new
113
- }.should raise_error(BehaviorError)
114
- end
115
-
116
- it 'raises an exception when one or more functions do not have proper arity' do
117
- behavior_info(:gen_foo, foo: 0)
118
- clazz = Class.new {
119
- behavior(:gen_foo)
120
- def foo(broken) nil; end
121
- }
122
-
123
- lambda {
124
- clazz.new
125
- }.should raise_error(BehaviorError)
126
- end
127
-
128
- it 'accepts any arity when function arity is set to :any' do
129
- behavior_info(:gen_foo, foo: :any)
130
- clazz = Class.new {
131
- behavior(:gen_foo)
132
- def foo(first) nil; end
133
- }
134
-
135
- lambda {
136
- clazz.new
137
- }.should_not raise_error
138
- end
139
-
140
- it 'creates the object when function definitions match' do
141
- behavior_info(:gen_foo, foo: 0, bar: 1)
142
- clazz = Class.new {
143
- behavior(:gen_foo)
144
- def foo() nil; end
145
- def bar(first) nil; end
146
- }
147
-
148
- lambda {
149
- clazz.new
150
- }.should_not raise_error
151
- end
152
- end
153
-
154
- context 'class methods' do
155
-
156
- it 'raises an exception when one or more function definitions are missing' do
157
- behavior_info(:gen_foo, self_foo: 0, self_bar: 1)
158
- clazz = Class.new {
159
- behavior(:gen_foo)
160
- def self.foo() nil; end
161
- }
162
-
163
- lambda {
164
- clazz.new
165
- }.should raise_error(BehaviorError)
166
- end
167
-
168
- it 'raises an exception when one or more functions do not have proper arity' do
169
- behavior_info(:gen_foo, self_foo: 0)
170
- clazz = Class.new {
171
- behavior(:gen_foo)
172
- def self.foo(broken) nil; end
173
- }
174
-
175
- lambda {
176
- clazz.new
177
- }.should raise_error(BehaviorError)
178
- end
179
-
180
- it 'accepts any arity when function arity is set to :any' do
181
- behavior_info(:gen_foo, self_foo: :any)
182
- clazz = Class.new {
183
- behavior(:gen_foo)
184
- def self.foo(first) nil; end
185
- }
186
-
187
- lambda {
188
- clazz.new
189
- }.should_not raise_error
190
- end
191
-
192
- it 'creates the object when function definitions match' do
193
- behavior_info(:gen_foo, self_foo: 0, self_bar: 1)
194
- clazz = Class.new {
195
- behavior(:gen_foo)
196
- def self.foo() nil; end
197
- def self.bar(first) nil; end
198
- }
199
-
200
- lambda {
201
- clazz.new
202
- }.should_not raise_error
203
- end
204
- end
205
-
206
- context 'inheritance' do
207
-
208
- it 'raises an exception if a superclass includes a behavior the subclass does not support' do
209
- behavior_info(:gen_foo, foo: 0)
210
- superclass = Class.new{
211
- behavior(:gen_foo)
212
- }
213
- subclass = Class.new(superclass)
214
-
215
- lambda {
216
- subclass.new
217
- }.should raise_error(BehaviorError)
218
- end
219
-
220
- it 'raises an exception if a module includes a behavior the containing class does not support' do
221
- behavior_info(:gen_foo, foo: 0)
222
- mod = Module.new{
223
- behavior(:gen_foo)
224
- }
225
- subclass = Class.new{
226
- include mod
227
- }
228
-
229
- lambda {
230
- subclass.new
231
- }.should raise_error(BehaviorError)
232
- end
233
- end
234
- end
235
-
236
- context '#behaves_as?' do
237
-
238
- it 'returns false when the behavior does not exist' do
239
- clazz = Class.new { }
240
- clazz.new.behaves_as?(:gen_foo).should be_false
241
- end
242
-
243
- it 'accepts behavior name as a symbol' do
244
- behavior_info(:gen_foo)
245
- clazz = Class.new { }
246
- clazz.new.behaves_as?(:gen_foo).should be_true
247
- end
248
-
249
- it 'accepts behavior name as a string' do
250
- behavior_info(:gen_foo)
251
- clazz = Class.new { }
252
- clazz.new.behaves_as?('gen_foo').should be_true
253
- end
254
-
255
- context 'Object' do
256
-
257
- it 'returns true when the behavior is fully suported' do
258
- behavior_info(:gen_foo, foo: 0, bar: 1, baz: 2)
259
- clazz = Class.new {
260
- def foo() nil; end
261
- def bar(first) nil; end
262
- def baz(first, second) nil; end
263
- }
264
-
265
- clazz.new.behaves_as?(:gen_foo).should be_true
266
- end
267
-
268
- it 'accepts any arity when function arity is set to :any' do
269
- behavior_info(:gen_foo, foo: :any)
270
- clazz = Class.new {
271
- def foo(*args, &block) nil; end
272
- }
273
-
274
- clazz.new.behaves_as?(:gen_foo).should be_true
275
- end
276
-
277
- it 'returns false when the behavior is partially supported' do
278
- behavior_info(:gen_foo, foo: 0, bar: 1, baz: 2)
279
- clazz = Class.new {
280
- def foo() nil; end
281
- def bar(first) nil; end
282
- }
283
-
284
- clazz.new.behaves_as?(:gen_foo).should be_false
285
- end
286
-
287
- it 'returns false when the behavior is not supported at all' do
288
- behavior_info(:gen_foo, foo: 0, bar: 1, baz: 2)
289
- clazz = Class.new { }
290
- clazz.new.behaves_as?(:gen_foo).should be_false
291
- end
292
- end
293
-
294
- context 'Class' do
295
-
296
- it 'returns true when the behavior is fully suported' do
297
- behavior_info(:gen_foo, self_foo: 0, self_bar: 1, baz: 2)
298
- clazz = Class.new {
299
- def self.foo() nil; end
300
- def self.bar(first) nil; end
301
- def baz(first, second) nil; end
302
- }
303
-
304
- clazz.behaves_as?(:gen_foo).should be_true
305
- clazz.new.behaves_as?(:gen_foo).should be_true
306
- end
307
-
308
- it 'accepts any arity when function arity is set to :any' do
309
- behavior_info(:gen_foo, self_foo: :any)
310
- clazz = Class.new {
311
- def self.foo(*args, &block) nil; end
312
- }
313
-
314
- clazz.behaves_as?(:gen_foo).should be_true
315
- clazz.new.behaves_as?(:gen_foo).should be_true
316
- end
317
-
318
- it 'returns false when the behavior is partially supported' do
319
- behavior_info(:gen_foo, self_foo: 0, bar: 1, self_baz: 2)
320
- clazz = Class.new {
321
- def self.foo() nil; end
322
- def self(first) nil; end
323
- }
324
-
325
- clazz.behaves_as?(:gen_foo).should be_false
326
- clazz.new.behaves_as?(:gen_foo).should be_false
327
- end
328
-
329
- it 'returns false when the behavior is not supported at all' do
330
- behavior_info(:gen_foo, self_foo: 0, self_bar: 1, self_baz: 2)
331
- clazz = Class.new { }
332
- clazz.new.behaves_as?(:gen_foo).should be_false
333
- end
334
- end
335
- end
336
-
337
- context 'aliases' do
338
-
339
- it 'aliases behaviour_info for behavior_info' do
340
- behaviour_info(:gen_foo)
341
- clazz = Class.new { }
342
- clazz.new.behaves_as?(:gen_foo).should be_true
343
- end
344
-
345
- it 'aliases interface for behavior_info' do
346
- interface(:gen_foo)
347
- clazz = Class.new { }
348
- clazz.new.behaves_as?(:gen_foo).should be_true
349
- end
350
-
351
- it 'aliases behaviour for behavior' do
352
- behavior_info(:gen_foo, foo: 0)
353
- clazz = Class.new {
354
- behaviour(:gen_foo)
355
- def foo() nil; end
356
- }
357
- clazz.new.behaves_as?(:gen_foo).should be_true
358
- end
359
-
360
- it 'aliases behaves_as for behavior' do
361
- behavior_info(:gen_foo, foo: 0)
362
- clazz = Class.new {
363
- behaves_as :gen_foo
364
- def foo() nil; end
365
- }
366
- clazz.new.behaves_as?(:gen_foo).should be_true
367
- end
368
- end
369
- end
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
+ context 'instance methods' do
103
+
104
+ it 'raises an exception when one or more function definitions are missing' do
105
+ behavior_info(:gen_foo, foo: 0, bar: 1)
106
+ clazz = Class.new {
107
+ behavior(:gen_foo)
108
+ def foo() nil; end
109
+ }
110
+
111
+ lambda {
112
+ clazz.new
113
+ }.should raise_error(BehaviorError)
114
+ end
115
+
116
+ it 'raises an exception when one or more functions do not have proper arity' do
117
+ behavior_info(:gen_foo, foo: 0)
118
+ clazz = Class.new {
119
+ behavior(:gen_foo)
120
+ def foo(broken) nil; end
121
+ }
122
+
123
+ lambda {
124
+ clazz.new
125
+ }.should raise_error(BehaviorError)
126
+ end
127
+
128
+ it 'accepts any arity when function arity is set to :any' do
129
+ behavior_info(:gen_foo, foo: :any)
130
+ clazz = Class.new {
131
+ behavior(:gen_foo)
132
+ def foo(first) nil; end
133
+ }
134
+
135
+ lambda {
136
+ clazz.new
137
+ }.should_not raise_error
138
+ end
139
+
140
+ it 'creates the object when function definitions match' do
141
+ behavior_info(:gen_foo, foo: 0, bar: 1)
142
+ clazz = Class.new {
143
+ behavior(:gen_foo)
144
+ def foo() nil; end
145
+ def bar(first) nil; end
146
+ }
147
+
148
+ lambda {
149
+ clazz.new
150
+ }.should_not raise_error
151
+ end
152
+ end
153
+
154
+ context 'class methods' do
155
+
156
+ it 'raises an exception when one or more function definitions are missing' do
157
+ behavior_info(:gen_foo, self_foo: 0, self_bar: 1)
158
+ clazz = Class.new {
159
+ behavior(:gen_foo)
160
+ def self.foo() nil; end
161
+ }
162
+
163
+ lambda {
164
+ clazz.new
165
+ }.should raise_error(BehaviorError)
166
+ end
167
+
168
+ it 'raises an exception when one or more functions do not have proper arity' do
169
+ behavior_info(:gen_foo, self_foo: 0)
170
+ clazz = Class.new {
171
+ behavior(:gen_foo)
172
+ def self.foo(broken) nil; end
173
+ }
174
+
175
+ lambda {
176
+ clazz.new
177
+ }.should raise_error(BehaviorError)
178
+ end
179
+
180
+ it 'accepts any arity when function arity is set to :any' do
181
+ behavior_info(:gen_foo, self_foo: :any)
182
+ clazz = Class.new {
183
+ behavior(:gen_foo)
184
+ def self.foo(first) nil; end
185
+ }
186
+
187
+ lambda {
188
+ clazz.new
189
+ }.should_not raise_error
190
+ end
191
+
192
+ it 'creates the object when function definitions match' do
193
+ behavior_info(:gen_foo, self_foo: 0, self_bar: 1)
194
+ clazz = Class.new {
195
+ behavior(:gen_foo)
196
+ def self.foo() nil; end
197
+ def self.bar(first) nil; end
198
+ }
199
+
200
+ lambda {
201
+ clazz.new
202
+ }.should_not raise_error
203
+ end
204
+ end
205
+
206
+ context 'inheritance' do
207
+
208
+ it 'raises an exception if a superclass includes a behavior the subclass does not support' do
209
+ behavior_info(:gen_foo, foo: 0)
210
+ superclass = Class.new{
211
+ behavior(:gen_foo)
212
+ }
213
+ subclass = Class.new(superclass)
214
+
215
+ lambda {
216
+ subclass.new
217
+ }.should raise_error(BehaviorError)
218
+ end
219
+
220
+ it 'raises an exception if a module includes a behavior the containing class does not support' do
221
+ behavior_info(:gen_foo, foo: 0)
222
+ mod = Module.new{
223
+ behavior(:gen_foo)
224
+ }
225
+ subclass = Class.new{
226
+ include mod
227
+ }
228
+
229
+ lambda {
230
+ subclass.new
231
+ }.should raise_error(BehaviorError)
232
+ end
233
+
234
+ it 'supports behaviors from multiple ancestors' do
235
+ behavior_info(:gen_foo, foo: 0)
236
+ behavior_info(:gen_bar, bar: 0)
237
+ behavior_info(:gen_baz, baz: 0)
238
+
239
+ rootclass = Class.new{ behavior(:gen_foo) }
240
+ superclass = Class.new(rootclass){ behavior(:gen_bar) }
241
+
242
+ subclass = Class.new(superclass){
243
+ behavior(:gen_baz)
244
+ def bar() nil; end
245
+ def baz() nil; end
246
+ }
247
+ lambda {
248
+ subclass.new
249
+ }.should raise_error(BehaviorError)
250
+
251
+ subclass = Class.new(superclass){
252
+ behavior(:gen_baz)
253
+ def foo() nil; end
254
+ def baz() nil; end
255
+ }
256
+ lambda {
257
+ subclass.new
258
+ }.should raise_error(BehaviorError)
259
+
260
+ subclass = Class.new(superclass){
261
+ behavior(:gen_baz)
262
+ def foo() nil; end
263
+ def bar() nil; end
264
+ }
265
+ lambda {
266
+ subclass.new
267
+ }.should raise_error(BehaviorError)
268
+
269
+ subclass = Class.new(superclass){
270
+ behavior(:gen_baz)
271
+ def foo() nil; end
272
+ def bar() nil; end
273
+ def baz() nil; end
274
+ }
275
+ lambda {
276
+ subclass.new
277
+ }.should_not raise_error
278
+ end
279
+
280
+ it 'supports multiple behaviors in an included module' do
281
+ behavior_info(:gen_foo, foo: 0)
282
+ behavior_info(:gen_bar, bar: 0)
283
+ behavior_info(:gen_baz, baz: 0)
284
+
285
+ mod = Module.new{
286
+ behavior(:gen_foo)
287
+ behavior(:gen_bar)
288
+ behavior(:gen_baz)
289
+ }
290
+
291
+ subclass = Class.new{
292
+ include mod
293
+ def bar() nil; end
294
+ def baz() nil; end
295
+ }
296
+ lambda {
297
+ subclass.new
298
+ }.should raise_error(BehaviorError)
299
+
300
+ subclass = Class.new{
301
+ include mod
302
+ def foo() nil; end
303
+ def baz() nil; end
304
+ }
305
+ lambda {
306
+ subclass.new
307
+ }.should raise_error(BehaviorError)
308
+
309
+ subclass = Class.new{
310
+ include mod
311
+ def foo() nil; end
312
+ def bar() nil; end
313
+ }
314
+ lambda {
315
+ subclass.new
316
+ }.should raise_error(BehaviorError)
317
+
318
+ subclass = Class.new{
319
+ include mod
320
+ def foo() nil; end
321
+ def bar() nil; end
322
+ def baz() nil; end
323
+ }
324
+ lambda {
325
+ subclass.new
326
+ }.should_not raise_error
327
+ end
328
+ end
329
+ end
330
+
331
+ context '#behaves_as?' do
332
+
333
+ it 'returns false when the behavior does not exist' do
334
+ clazz = Class.new { }
335
+ clazz.new.behaves_as?(:gen_foo).should be_false
336
+ end
337
+
338
+ it 'accepts behavior name as a symbol' do
339
+ behavior_info(:gen_foo)
340
+ clazz = Class.new { }
341
+ clazz.new.behaves_as?(:gen_foo).should be_true
342
+ end
343
+
344
+ it 'accepts behavior name as a string' do
345
+ behavior_info(:gen_foo)
346
+ clazz = Class.new { }
347
+ clazz.new.behaves_as?('gen_foo').should be_true
348
+ end
349
+
350
+ context 'Object' do
351
+
352
+ it 'returns true when the behavior is fully suported' do
353
+ behavior_info(:gen_foo, foo: 0, bar: 1, baz: 2)
354
+ clazz = Class.new {
355
+ def foo() nil; end
356
+ def bar(first) nil; end
357
+ def baz(first, second) nil; end
358
+ }
359
+
360
+ clazz.new.behaves_as?(:gen_foo).should be_true
361
+ end
362
+
363
+ it 'accepts any arity when function arity is set to :any' do
364
+ behavior_info(:gen_foo, foo: :any)
365
+ clazz = Class.new {
366
+ def foo(*args, &block) nil; end
367
+ }
368
+
369
+ clazz.new.behaves_as?(:gen_foo).should be_true
370
+ end
371
+
372
+ it 'returns false when the behavior is partially supported' 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
+ }
378
+
379
+ clazz.new.behaves_as?(:gen_foo).should be_false
380
+ end
381
+
382
+ it 'returns false when the behavior is not supported at all' do
383
+ behavior_info(:gen_foo, foo: 0, bar: 1, baz: 2)
384
+ clazz = Class.new { }
385
+ clazz.new.behaves_as?(:gen_foo).should be_false
386
+ end
387
+ end
388
+
389
+ context 'Class' do
390
+
391
+ it 'returns true when the behavior is fully suported' do
392
+ behavior_info(:gen_foo, self_foo: 0, self_bar: 1, baz: 2)
393
+ clazz = Class.new {
394
+ def self.foo() nil; end
395
+ def self.bar(first) nil; end
396
+ def baz(first, second) nil; end
397
+ }
398
+
399
+ clazz.behaves_as?(:gen_foo).should be_true
400
+ clazz.new.behaves_as?(:gen_foo).should be_true
401
+ end
402
+
403
+ it 'accepts any arity when function arity is set to :any' do
404
+ behavior_info(:gen_foo, self_foo: :any)
405
+ clazz = Class.new {
406
+ def self.foo(*args, &block) nil; end
407
+ }
408
+
409
+ clazz.behaves_as?(:gen_foo).should be_true
410
+ clazz.new.behaves_as?(:gen_foo).should be_true
411
+ end
412
+
413
+ it 'returns false when the behavior is partially supported' do
414
+ behavior_info(:gen_foo, self_foo: 0, bar: 1, self_baz: 2)
415
+ clazz = Class.new {
416
+ def self.foo() nil; end
417
+ def self(first) nil; end
418
+ }
419
+
420
+ clazz.behaves_as?(:gen_foo).should be_false
421
+ clazz.new.behaves_as?(:gen_foo).should be_false
422
+ end
423
+
424
+ it 'returns false when the behavior is not supported at all' do
425
+ behavior_info(:gen_foo, self_foo: 0, self_bar: 1, self_baz: 2)
426
+ clazz = Class.new { }
427
+ clazz.new.behaves_as?(:gen_foo).should be_false
428
+ end
429
+ end
430
+ end
431
+
432
+ context 'aliases' do
433
+
434
+ it 'aliases behaviour_info for behavior_info' do
435
+ behaviour_info(:gen_foo)
436
+ clazz = Class.new { }
437
+ clazz.new.behaves_as?(:gen_foo).should be_true
438
+ end
439
+
440
+ it 'aliases interface for behavior_info' do
441
+ interface(:gen_foo)
442
+ clazz = Class.new { }
443
+ clazz.new.behaves_as?(:gen_foo).should be_true
444
+ end
445
+
446
+ it 'aliases behaviour for behavior' do
447
+ behavior_info(:gen_foo, foo: 0)
448
+ clazz = Class.new {
449
+ behaviour(:gen_foo)
450
+ def foo() nil; end
451
+ }
452
+ clazz.new.behaves_as?(:gen_foo).should be_true
453
+ end
454
+
455
+ it 'aliases behaves_as for behavior' do
456
+ behavior_info(:gen_foo, foo: 0)
457
+ clazz = Class.new {
458
+ behaves_as :gen_foo
459
+ def foo() nil; end
460
+ }
461
+ clazz.new.behaves_as?(:gen_foo).should be_true
462
+ end
463
+ end
464
+ end