functional-ruby 0.7.0 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
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