functional-ruby 0.7.0 → 0.7.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7ebc0dab7cc6ee079416729c8cc131bf239ca2bb
4
- data.tar.gz: 24b3193d7e6fef20addd8688ab372c104163edae
3
+ metadata.gz: 9bc4db6eba8d3f68f626e27415bb5e5b20e69fc3
4
+ data.tar.gz: fa353eb6d4d4fc0d2557e7340d2874d68159050d
5
5
  SHA512:
6
- metadata.gz: 65b487a457f8b8a4dcb3adfe98e8429ae0184656d3ddf6292c515c598f4cb6e610f8aca4185950626bf4e67cda95a77eb081031caf5f7ea95ccf3592df6c9d0a
7
- data.tar.gz: bbe8b613ee9ac7a4aa4ed6626a36a2bfc148e4ddc42ef5fd2f5be5703f74567beb15dd772d0b4e63156f6ca46accae1425dfdeac0a36d75a34a09aa4bceafc45
6
+ metadata.gz: 7d482b7d25a1066ef058ca13cc5e8b7b5b0d7e249a7356d4b7cb815288b18daff9c3f5fb789fdbe2ef4c47e0a3e26f9f3437b244bed244b69cbd16d72f415c2e
7
+ data.tar.gz: 693b09f4e460522ff1aad1db7098414138ec076d90674c0303f699c476cd2fc4b5f745c032508aa93559ea4ebbf37e2c4ebb509965a104e531b7b50d822b3e37
data/README.md CHANGED
@@ -120,7 +120,7 @@ Documentation: [Behavior](https://github.com/jdantonio/functional-ruby/blob/mast
120
120
  ```ruby
121
121
  require 'functional/behavior'
122
122
 
123
- behaviour_info(:gen_foo, foo: 0, bar: 1)
123
+ behaviour_info(:gen_foo, foo: 0, self_bar: 1)
124
124
 
125
125
  class Foo
126
126
  behavior(:gen_foo)
@@ -129,14 +129,15 @@ class Foo
129
129
  return 'foo/0'
130
130
  end
131
131
 
132
- def bar(one, &block)
132
+ def self.bar(one, &block)
133
133
  return 'bar/1'
134
134
  end
135
135
  end
136
136
 
137
137
  foo = Foo.new
138
138
 
139
- foo.behaves_as? :gen_foo #=> true
139
+ Foo.behaves_as? :gen_foo #=> true
140
+ foo.behaves_as?(:gen_foo) #=> true
140
141
  foo.behaves_as?(:bogus) #=> false
141
142
  'foo'.behaves_as? :gen_foo #=> false
142
143
  ```
@@ -38,15 +38,29 @@ module Kernel
38
38
 
39
39
  clazz.behaviors << name
40
40
 
41
+ if self.class == Module
42
+ (class << self; self; end).class_eval do
43
+ define_method(:included) do |base|
44
+ base.class_eval do
45
+ behavior(name)
46
+ end
47
+ end
48
+ end
49
+ end
50
+
41
51
  class << clazz
42
52
  def new(*args, &block)
43
- name = self.behaviors.first
44
53
  obj = super
45
- unless obj.behaves_as?(name)
46
- raise BehaviorError.new("undefined callback functions in #{self} (behavior '#{name}')")
47
- else
48
- return obj
54
+ self.ancestors.each do |clazz|
55
+ if clazz.respond_to?(:behaviors)
56
+ clazz.behaviors.each do |behavior|
57
+ unless obj.behaves_as?(behavior)
58
+ raise BehaviorError.new("undefined callback functions in #{self} (behavior '#{behavior}')")
59
+ end
60
+ end
61
+ end
49
62
  end
63
+ return obj
50
64
  end
51
65
  end
52
66
  end
@@ -79,9 +93,27 @@ class Object
79
93
  bi = $__behavior_info__[name]
80
94
  return false if bi.nil?
81
95
 
96
+ validator = proc do |obj, method, arity|
97
+ (obj.respond_to?(method) && arity == :any) || obj.method(method).arity == arity
98
+ end
99
+
100
+ if self.is_a?(Class) || self.is_a?(Module)
101
+ bi = bi.select{|method, arity| method.to_s =~ /^self_/ }
102
+ end
103
+
82
104
  bi.each do |method, arity|
83
105
  begin
84
- return false unless arity == :any || self.method(method).arity == arity
106
+ method = method.to_s
107
+ obj = self
108
+
109
+ if (self.is_a?(Class) || self.is_a?(Module)) && method =~ /^self_/
110
+ method = method.gsub(/^self_/, '')
111
+ elsif method =~ /^self_/
112
+ method = method.gsub(/^self_/, '')
113
+ obj = self.class
114
+ end
115
+
116
+ return false unless validator.call(obj, method, arity)
85
117
  rescue NameError
86
118
  return false
87
119
  end
@@ -1,6 +1,7 @@
1
1
  require 'pp'
2
2
  require 'stringio'
3
3
  require 'erb'
4
+ require 'rbconfig'
4
5
 
5
6
  Infinity = 1/0.0 unless defined?(Infinity)
6
7
  NaN = 0/0.0 unless defined?(NaN)
@@ -79,24 +80,28 @@ module Kernel
79
80
  # Sandbox the given operation at a high $SAFE level.
80
81
  #
81
82
  # @param args [Array] zero or more arguments to pass to the block
82
- # @param block [Proc] the block to isolate
83
83
  #
84
84
  # @return [Object] the result of the block operation
85
85
  def safe(*args)
86
86
  raise ArgumentError.new('no block given') unless block_given?
87
- result = nil
88
- t = Thread.new do
89
- $SAFE = 3
90
- result = yield(*args)
87
+ if RbConfig::CONFIG['ruby_install_name'] =~ /^ruby$/i
88
+ result = nil
89
+ t = Thread.new do
90
+ $SAFE = 3
91
+ result = yield(*args)
92
+ end
93
+ t.join
94
+ return result
95
+ else
96
+ return yield(*args)
91
97
  end
92
- t.join
93
- return result
94
98
  end
95
99
  module_function :safe
96
100
 
97
101
  # Open a file, read it, close the file, and return its contents.
98
102
  #
99
103
  # @param file [String] path to and name of the file to open
104
+ #
100
105
  # @return [String] file contents
101
106
  #
102
107
  # @see slurpee
@@ -110,6 +115,7 @@ module Kernel
110
115
  #
111
116
  # @param file [String] path to and name of the file to open
112
117
  # @param safe_level [Integer] when not nil, ERB will $SAFE set to this
118
+ #
113
119
  # @return [String] file contents
114
120
  #
115
121
  # @see slurpee
@@ -118,33 +124,36 @@ module Kernel
118
124
  end
119
125
  module_function :slurpee
120
126
 
121
- #############################################################################
122
-
123
- # @private
124
- def repl? # :nodoc:
125
- return ($0 == 'irb' || $0 == 'pry' || $0 == 'script/rails' || !!($0 =~ /bin\/bundle$/))
126
- end
127
- module_function :repl?
128
-
129
- # @private
130
- def timestamp # :nodoc:
131
- return Time.now.getutc.to_i
132
- end
133
-
134
- # @private
135
- def timer(*args) # :nodoc:
127
+ # Run the given block and time how long it takes in seconds. All arguments
128
+ # will be passed to the block. The function will return two values. The
129
+ # first value will be the duration of the timer in seconds. The second
130
+ # return value will be the result of the block.
131
+ #
132
+ # @param args [Array] zero or more arguments to pass to the block
133
+ #
134
+ # @return [Integer, Object] the duration of the operation in seconds and
135
+ # the result of the block operation
136
+ def timer(*args)
137
+ return 0,nil unless block_given?
136
138
  t1 = Time.now
137
139
  result = yield(*args)
138
140
  t2 = Time.now
139
- return (t2 - t1)
141
+ return (t2 - t1), result
140
142
  end
141
143
  module_function :timer
142
144
 
145
+ #############################################################################
146
+
143
147
  # @private
144
- def strftimer(seconds) # :nodoc:
145
- Time.at(seconds).gmtime.strftime('%R:%S.%L')
148
+ # @see http://cirw.in/blog/find-references
149
+ def object_counts # :nodoc:
150
+ counts = Hash.new{ 0 }
151
+ ObjectSpace.each_object do |obj|
152
+ counts[obj.class] += 1
153
+ end
154
+ return counts
146
155
  end
147
- module_function :strftimer
156
+ module_function :object_counts
148
157
 
149
158
  # @private
150
159
  # @see http://rhaseventh.blogspot.com/2008/07/ruby-and-rails-how-to-get-pp-pretty.html
@@ -157,4 +166,27 @@ module Kernel
157
166
  s.read
158
167
  end
159
168
  module_function :pp_s
169
+
170
+ # @private
171
+ def repl? # :nodoc:
172
+ return ($0 == 'irb' || $0 == 'pry' || $0 == 'script/rails' || !!($0 =~ /bin\/bundle$/))
173
+ end
174
+ module_function :repl?
175
+
176
+ # @private
177
+ def strftimer(seconds) # :nodoc:
178
+ Time.at(seconds).gmtime.strftime('%R:%S.%L')
179
+ end
180
+ module_function :strftimer
181
+
182
+ # @private
183
+ def timestamp # :nodoc:
184
+ return Time.now.getutc.to_i
185
+ end
186
+
187
+ def write_object_counts(name = 'ruby')
188
+ file = "#{name}_#{Time.now.to_i}.txt"
189
+ File.open(file, 'w') {|f| f.write(pp_s(object_counts)) }
190
+ end
191
+ module_function :write_object_counts
160
192
  end
@@ -1,3 +1,3 @@
1
1
  module Functional
2
- VERSION = '0.7.0'
2
+ VERSION = '0.7.1'
3
3
  end
data/md/behavior.md CHANGED
@@ -11,14 +11,10 @@ Forget to implement a required method and Ruby will let you know. See the exampl
11
11
 
12
12
  ## Usage
13
13
 
14
- The `behavior` functionality is not imported by default. It needs a separate `require` statement:
14
+ Require the gem
15
15
 
16
16
  ```ruby
17
- require 'functional/behavior'
18
-
19
- # -or-
20
-
21
- require 'functional/behaviour'
17
+ require 'functional'
22
18
  ```
23
19
 
24
20
  ### behavior_info
@@ -34,7 +30,6 @@ behaviour_info(:gen_foo, foo: 0, bar: 1, baz: 2)
34
30
  # -or (for the Java/C# crowd)
35
31
 
36
32
  interface(:gen_foo, foo: 0, bar: 1, baz: 2)
37
-
38
33
  ```
39
34
 
40
35
  Each function name can be listed only once and the arity must follow the rules of the
@@ -43,6 +38,12 @@ Though not explicitly documented, block arguments do not count toward a method's
43
38
  methods defined using this gem's `defn` function will always have an arity of -1,
44
39
  regardless of how many overloads are defined.
45
40
 
41
+ To specify class/module methods prepend the methid name with 'self_'
42
+
43
+ ```ruby
44
+ behaviour_info(:gen_foo, self_foo: 0, self_bar: 1, baz: 2)
45
+ ```
46
+
46
47
  ### behavior
47
48
 
48
49
  To enforce a behavior on a class simply call the `behavior` function within the class,
@@ -74,6 +75,45 @@ raise an exception when you try to create an object from the class:
74
75
  Baz.new #=> ArgumentError: undefined callback functions in Baz (behavior 'gen_foo')
75
76
  ```
76
77
 
78
+ A class may support multiple behaviors:
79
+
80
+ ```ruby
81
+ behavior_info(:gen_foo, foo: 0)
82
+ behavior_info(:gen_bar, bar: 1)
83
+
84
+ class FooBar
85
+ behavior(:gen_foo)
86
+ behavior(:gen_bar)
87
+ ...
88
+ end
89
+ ```
90
+
91
+ Inheritance and module inclusion are supported as well:
92
+
93
+ ```ruby
94
+ behavior_info(:gen_foo, foo: 0)
95
+ behavior_info(:gen_bar, bar: 0)
96
+
97
+ class Foo
98
+ behavior(:gen_foo)
99
+ def foo() nil; end
100
+ end
101
+
102
+ module Bar
103
+ behavior(:gen_bar)
104
+ def bar() nil; end
105
+ end
106
+
107
+ class FooBar < Foo
108
+ include Bar
109
+ end
110
+
111
+ foobar = FooBar.new
112
+
113
+ foobar.behaves_as?(:gen_foo) #=> true
114
+ foobar.behaves_as?(:gen_bar) #=> true
115
+ ```
116
+
77
117
  ### behaves_as?
78
118
 
79
119
  As an added bonus, Ruby [Object](http://ruby-doc.org/core-1.9.3/Object.html) will be
@@ -84,12 +124,12 @@ monkey-patched with a `behaves_as?` predicate method.
84
124
  A complete example:
85
125
 
86
126
  ```ruby
87
- behaviour_info(:gen_foo, foo: 0, bar: 1, baz: 2, boom: -1, bam: :any)
127
+ behaviour_info(:gen_foo, self_foo: 0, bar: 1, baz: 2, boom: -1, bam: :any)
88
128
 
89
129
  class Foo
90
130
  behavior(:gen_foo)
91
131
 
92
- def foo
132
+ def self.foo
93
133
  return 'foo/0'
94
134
  end
95
135
 
@@ -112,6 +152,7 @@ end
112
152
 
113
153
  foo = Foo.new
114
154
 
155
+ Foo.behaves_as? :gen_foo #=> true
115
156
  foo.behaves_as? :gen_foo #=> true
116
157
  foo.behaves_as?(:bogus) #=> false
117
158
  'foo'.behaves_as? :gen_foo #=> false
@@ -74,93 +74,166 @@ describe '-behavior' do
74
74
 
75
75
  context 'object creation' do
76
76
 
77
- it 'raises an exception when one or more function definitions are missing' do
78
- behavior_info(:gen_foo, foo: 0, bar: 1)
77
+ it 'checks all required behaviors' do
78
+ behavior_info(:gen_foo, foo: 0)
79
+ behavior_info(:gen_bar, bar: 1)
80
+
79
81
  clazz = Class.new {
80
82
  behavior(:gen_foo)
83
+ behavior(:gen_bar)
81
84
  def foo() nil; end
82
85
  }
86
+ lambda{ clazz.new }.should raise_error(BehaviorError)
83
87
 
84
- lambda {
85
- clazz.new
86
- }.should raise_error(BehaviorError)
87
- end
88
-
89
- it 'raises an exception when one or more functions do not have proper arity' do
90
- behavior_info(:gen_foo, foo: 0)
91
88
  clazz = Class.new {
92
89
  behavior(:gen_foo)
93
- def foo(broken) nil; end
90
+ behavior(:gen_bar)
91
+ def bar() nil; end
94
92
  }
93
+ lambda{ clazz.new }.should raise_error(BehaviorError)
95
94
 
96
- lambda {
97
- clazz.new
98
- }.should raise_error(BehaviorError)
99
- end
100
-
101
- it 'accepts any arity when function arity is set to :any' do
102
- behavior_info(:gen_foo, foo: :any)
103
95
  clazz = Class.new {
104
96
  behavior(:gen_foo)
105
- def foo(first) nil; end
97
+ behavior(:gen_bar)
106
98
  }
107
-
108
- lambda {
109
- clazz.new
110
- }.should_not raise_error
99
+ lambda{ clazz.new }.should raise_error(BehaviorError)
111
100
  end
112
101
 
113
- it 'creates the object when function definitions match' do
114
- behavior_info(:gen_foo, foo: 0, bar: 1)
115
- clazz = Class.new {
116
- behavior(:gen_foo)
117
- def foo() nil; end
118
- def bar(first) nil; end
119
- }
102
+ context 'instance methods' do
120
103
 
121
- lambda {
122
- clazz.new
123
- }.should_not raise_error
124
- end
125
- end
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
+ }
126
110
 
127
- context '#behaves_as?' do
111
+ lambda {
112
+ clazz.new
113
+ }.should raise_error(BehaviorError)
114
+ end
128
115
 
129
- it 'returns true when the behavior is fully suported' do
130
- behavior_info(:gen_foo, foo: 0, bar: 1, baz: 2)
131
- clazz = Class.new {
132
- def foo() nil; end
133
- def bar(first) nil; end
134
- def baz(first, second) nil; end
135
- }
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
+ }
136
122
 
137
- clazz.new.behaves_as?(:gen_foo).should be_true
138
- end
123
+ lambda {
124
+ clazz.new
125
+ }.should raise_error(BehaviorError)
126
+ end
139
127
 
140
- it 'accepts any arity when function arity is set to :any' do
141
- behavior_info(:gen_foo, foo: :any)
142
- clazz = Class.new {
143
- def foo(*args, &block) nil; end
144
- }
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
+ }
145
134
 
146
- clazz.new.behaves_as?(:gen_foo).should be_true
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
147
152
  end
148
153
 
149
- it 'returns false when the behavior is partially supported' do
150
- behavior_info(:gen_foo, foo: 0, bar: 1, baz: 2)
151
- clazz = Class.new {
152
- def foo() nil; end
153
- def bar(first) nil; end
154
- }
154
+ context 'class methods' do
155
155
 
156
- clazz.new.behaves_as?(:gen_foo).should be_false
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
157
204
  end
158
205
 
159
- it 'returns false when the behavior is not supported at all' do
160
- behavior_info(:gen_foo, foo: 0, bar: 1, baz: 2)
161
- clazz = Class.new { }
162
- clazz.new.behaves_as?(:gen_foo).should be_false
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
163
233
  end
234
+ end
235
+
236
+ context '#behaves_as?' do
164
237
 
165
238
  it 'returns false when the behavior does not exist' do
166
239
  clazz = Class.new { }
@@ -178,6 +251,87 @@ describe '-behavior' do
178
251
  clazz = Class.new { }
179
252
  clazz.new.behaves_as?('gen_foo').should be_true
180
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
181
335
  end
182
336
 
183
337
  context 'aliases' do
@@ -212,5 +366,4 @@ describe '-behavior' do
212
366
  clazz.new.behaves_as?(:gen_foo).should be_true
213
367
  end
214
368
  end
215
-
216
369
  end
@@ -1,5 +1,6 @@
1
1
  require 'spec_helper'
2
2
  require 'fakefs/safe'
3
+ require 'rbconfig'
3
4
 
4
5
  describe 'utilities' do
5
6
 
@@ -125,32 +126,34 @@ describe 'utilities' do
125
126
  end
126
127
  end
127
128
 
128
- context '#safe' do
129
+ if RbConfig::CONFIG['ruby_install_name'] =~ /^ruby$/i
130
+ context '#safe' do
129
131
 
130
- it 'allows safe operations' do
131
- lambda {
132
- safe{ 1 + 1 }
133
- }.should_not raise_error
134
- end
132
+ it 'allows safe operations' do
133
+ lambda {
134
+ safe{ 1 + 1 }
135
+ }.should_not raise_error
136
+ end
135
137
 
136
- it 'returns the value of the block when safe' do
137
- safe{ 1 + 1 }.should eq 2
138
- end
138
+ it 'returns the value of the block when safe' do
139
+ safe{ 1 + 1 }.should eq 2
140
+ end
139
141
 
140
- it 'passes all arguments to the block' do
141
- safe(1, 2, 3){|x, y, z| x + y + z }.should eq 6
142
- end
142
+ it 'passes all arguments to the block' do
143
+ safe(1, 2, 3){|x, y, z| x + y + z }.should eq 6
144
+ end
143
145
 
144
- it 'rejects unsafe operations on tainted objects' do
145
- lambda {
146
- safe{ Signal.trap('INT'.taint) }
147
- }.should raise_error(SecurityError)
148
- end
146
+ it 'rejects unsafe operations on tainted objects' do
147
+ lambda {
148
+ safe{ Signal.trap('INT'.taint) }
149
+ }.should raise_error(SecurityError)
150
+ end
149
151
 
150
- it 'rejects the use of #eval' do
151
- lambda {
152
- safe{ eval 'puts 1' }
153
- }.should raise_error(SecurityError)
152
+ it 'rejects the use of #eval' do
153
+ lambda {
154
+ safe{ eval 'puts 1' }
155
+ }.should raise_error(SecurityError)
156
+ end
154
157
  end
155
158
  end
156
159
 
@@ -234,4 +237,35 @@ describe 'utilities' do
234
237
  repl?.should be_false
235
238
  end
236
239
  end
240
+
241
+ context '#timer' do
242
+
243
+ it 'returns [0, nil] if no block is given' do
244
+ duration, result = timer()
245
+ duration.should eq 0
246
+ result.should be_nil
247
+ end
248
+
249
+ it 'yields to the block' do
250
+ @expected = false
251
+ duration, result = timer{ @expected = true }
252
+ @expected.should be_true
253
+ end
254
+
255
+ it 'passes all arguments to the block' do
256
+ @expected = nil
257
+ duration, result = timer(1,2,3){|a,b,c| @expected = [a,b,c]}
258
+ @expected.should eq [1,2,3]
259
+ end
260
+
261
+ it 'returns the duration as the first return value' do
262
+ duration, result = timer{ sleep(0.1) }
263
+ duration.should > 0
264
+ end
265
+
266
+ it 'returns the block result as the second return value' do
267
+ duration, result = timer{ 42 }
268
+ result.should eq 42
269
+ end
270
+ end
237
271
  end
data/spec/spec_helper.rb CHANGED
@@ -4,6 +4,7 @@ require 'functional'
4
4
  Dir[File.join(File.dirname(__FILE__), 'support/**/*.rb')].each { |f| require File.expand_path(f) }
5
5
 
6
6
  RSpec.configure do |config|
7
+ config.order = 'random'
7
8
 
8
9
  config.before(:suite) do
9
10
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: functional-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jerry D'Antonio
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-07-24 00:00:00.000000000 Z
11
+ date: 2013-08-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler