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.
- checksums.yaml +4 -4
- data/README.md +92 -152
- data/doc/memo.txt +192 -0
- data/doc/pattern_matching.txt +485 -0
- data/doc/protocol.txt +221 -0
- data/doc/record.txt +144 -0
- data/doc/thread_safety.txt +8 -0
- data/lib/functional.rb +48 -18
- data/lib/functional/abstract_struct.rb +161 -0
- data/lib/functional/delay.rb +117 -0
- data/lib/functional/either.rb +222 -0
- data/lib/functional/memo.rb +93 -0
- data/lib/functional/method_signature.rb +72 -0
- data/lib/functional/option.rb +209 -0
- data/lib/functional/pattern_matching.rb +117 -100
- data/lib/functional/protocol.rb +157 -0
- data/lib/functional/protocol_info.rb +193 -0
- data/lib/functional/record.rb +155 -0
- data/lib/functional/type_check.rb +112 -0
- data/lib/functional/union.rb +152 -0
- data/lib/functional/version.rb +3 -1
- data/spec/functional/abstract_struct_shared.rb +154 -0
- data/spec/functional/complex_pattern_matching_spec.rb +205 -0
- data/spec/functional/configuration_spec.rb +17 -0
- data/spec/functional/delay_spec.rb +147 -0
- data/spec/functional/either_spec.rb +237 -0
- data/spec/functional/memo_spec.rb +207 -0
- data/spec/functional/option_spec.rb +292 -0
- data/spec/functional/pattern_matching_spec.rb +279 -276
- data/spec/functional/protocol_info_spec.rb +444 -0
- data/spec/functional/protocol_spec.rb +274 -0
- data/spec/functional/record_spec.rb +175 -0
- data/spec/functional/type_check_spec.rb +103 -0
- data/spec/functional/union_spec.rb +110 -0
- data/spec/spec_helper.rb +6 -4
- metadata +55 -45
- data/lib/functional/behavior.rb +0 -138
- data/lib/functional/behaviour.rb +0 -2
- data/lib/functional/catalog.rb +0 -487
- data/lib/functional/collection.rb +0 -403
- data/lib/functional/inflect.rb +0 -127
- data/lib/functional/platform.rb +0 -120
- data/lib/functional/search.rb +0 -132
- data/lib/functional/sort.rb +0 -41
- data/lib/functional/utilities.rb +0 -189
- data/md/behavior.md +0 -188
- data/md/catalog.md +0 -32
- data/md/collection.md +0 -32
- data/md/inflect.md +0 -32
- data/md/pattern_matching.md +0 -512
- data/md/platform.md +0 -32
- data/md/search.md +0 -32
- data/md/sort.md +0 -32
- data/md/utilities.md +0 -55
- data/spec/functional/behavior_spec.rb +0 -528
- data/spec/functional/catalog_spec.rb +0 -1206
- data/spec/functional/collection_spec.rb +0 -752
- data/spec/functional/inflect_spec.rb +0 -85
- data/spec/functional/integration_spec.rb +0 -205
- data/spec/functional/platform_spec.rb +0 -501
- data/spec/functional/search_spec.rb +0 -187
- data/spec/functional/sort_spec.rb +0 -61
- data/spec/functional/utilities_spec.rb +0 -277
@@ -1,187 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Functional
|
4
|
-
|
5
|
-
describe Search do
|
6
|
-
|
7
|
-
context '#linear_search' do
|
8
|
-
|
9
|
-
let(:sample) do
|
10
|
-
[3, 5, 6, 7, 8, 11, 15, 21, 22, 28, 30, 32, 33, 34, 40].freeze
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'returns nil for a nil sample' do
|
14
|
-
Search.linear_search(nil, 1).should be_nil
|
15
|
-
end
|
16
|
-
|
17
|
-
it 'returns nil for an empty sample' do
|
18
|
-
Search.linear_search([].freeze, 1).should be_nil
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'returns the index of the item when found' do
|
22
|
-
index = Search.linear_search(sample, 11)
|
23
|
-
index.should eq 5
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'returns the index of the item when using a block' do
|
27
|
-
sample = [
|
28
|
-
{:count => 11},
|
29
|
-
{:count => 12},
|
30
|
-
{:count => 13},
|
31
|
-
{:count => 14},
|
32
|
-
{:count => 16},
|
33
|
-
{:count => 17},
|
34
|
-
{:count => 18},
|
35
|
-
{:count => 19},
|
36
|
-
{:count => 20},
|
37
|
-
{:count => 21}
|
38
|
-
].freeze
|
39
|
-
|
40
|
-
index = Search.linear_search(sample, 14){|item| item[:count]}
|
41
|
-
index.should eq 3
|
42
|
-
end
|
43
|
-
|
44
|
-
it 'returns nil when not found' do
|
45
|
-
index = Search.linear_search(sample, 13)
|
46
|
-
index.should be_nil
|
47
|
-
end
|
48
|
-
|
49
|
-
it 'supports an :imin option for an alternate low index' do
|
50
|
-
index = Search.linear_search(sample, 11, :imin => 3)
|
51
|
-
index.should eq 5
|
52
|
-
|
53
|
-
index = Search.linear_search(sample, 11, :imin => 10)
|
54
|
-
index.should be_nil
|
55
|
-
end
|
56
|
-
|
57
|
-
it 'supports an :imax option for an alternate high index' do
|
58
|
-
index = Search.linear_search(sample, 11, :imax => 10)
|
59
|
-
index.should eq 5
|
60
|
-
|
61
|
-
index = Search.linear_search(sample, 11, :imax => 4)
|
62
|
-
index.should be_nil
|
63
|
-
end
|
64
|
-
|
65
|
-
it 'behaves consistently when :imin equals :imax' do
|
66
|
-
index = Search.linear_search(sample, 3, :imin => 5, :imax => 5)
|
67
|
-
index.should be_nil
|
68
|
-
|
69
|
-
index = Search.linear_search(sample, 11, :imin => 5, :imax => 5)
|
70
|
-
index.should eq 5
|
71
|
-
|
72
|
-
index = Search.linear_search(sample, 30, :imin => 5, :imax => 5)
|
73
|
-
index.should be_nil
|
74
|
-
end
|
75
|
-
|
76
|
-
it 'sets :imin to zero (0) when given a negative number' do
|
77
|
-
index = Search.linear_search(sample, 11, :imin => -1)
|
78
|
-
index.should eq 5
|
79
|
-
end
|
80
|
-
|
81
|
-
it 'sets :imax to the uppermost index when :imax is out of range' do
|
82
|
-
index = Search.linear_search(sample, 11, :imax => 100)
|
83
|
-
index.should eq 5
|
84
|
-
end
|
85
|
-
|
86
|
-
it 'returns nil when :imin is greater than :imax' do
|
87
|
-
index = Search.linear_search(sample, 1, :imin => 10, :imax => 5)
|
88
|
-
index.should be_nil
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
context '#binary_search' do
|
93
|
-
|
94
|
-
let(:sample) do
|
95
|
-
[3, 5, 6, 7, 8, 11, 15, 21, 22, 28, 30, 32, 33, 34, 40].freeze
|
96
|
-
end
|
97
|
-
|
98
|
-
it 'returns nil for a nil sample' do
|
99
|
-
Search.binary_search(nil, 1).should be_nil
|
100
|
-
end
|
101
|
-
|
102
|
-
it 'returns nil for an empty sample' do
|
103
|
-
Search.binary_search([].freeze, 1).should be_nil
|
104
|
-
end
|
105
|
-
|
106
|
-
it 'returns the index of the item when found as [index, index]' do
|
107
|
-
index = Search.binary_search(sample, 11)
|
108
|
-
index.should eq [5, 5]
|
109
|
-
end
|
110
|
-
|
111
|
-
it 'returns the index of the item when using a block' do
|
112
|
-
sample = [
|
113
|
-
{:count => 11},
|
114
|
-
{:count => 12},
|
115
|
-
{:count => 13},
|
116
|
-
{:count => 14},
|
117
|
-
{:count => 16},
|
118
|
-
{:count => 17},
|
119
|
-
{:count => 18},
|
120
|
-
{:count => 19},
|
121
|
-
{:count => 20},
|
122
|
-
{:count => 21}
|
123
|
-
].freeze
|
124
|
-
|
125
|
-
index = Search.binary_search(sample, 14){|item| item[:count]}
|
126
|
-
index.should eq [3, 3]
|
127
|
-
end
|
128
|
-
|
129
|
-
it 'returns the indexes above and below when not found - below, above' do
|
130
|
-
index = Search.binary_search(sample, 13)
|
131
|
-
index.should eq [5, 6]
|
132
|
-
end
|
133
|
-
|
134
|
-
it 'returns nil and the low index when the item is out of range on the low end - [nil, low]' do
|
135
|
-
index = Search.binary_search(sample, 1)
|
136
|
-
index.should eq [nil, 0]
|
137
|
-
end
|
138
|
-
|
139
|
-
it 'returns the high index and nil when the item is out of range on the high end - [high, nil]' do
|
140
|
-
index = Search.binary_search(sample, 41)
|
141
|
-
index.should eq [14, nil]
|
142
|
-
end
|
143
|
-
|
144
|
-
it 'supports an :imin option for an alternate low index' do
|
145
|
-
index = Search.binary_search(sample, 11, :imin => 3)
|
146
|
-
index.should eq [5, 5]
|
147
|
-
|
148
|
-
index = Search.binary_search(sample, 11, :imin => 10)
|
149
|
-
index.should eq [nil, 10]
|
150
|
-
end
|
151
|
-
|
152
|
-
it 'supports an :imax option for an alternate high index' do
|
153
|
-
index = Search.binary_search(sample, 11, :imax => 10)
|
154
|
-
index.should eq [5, 5]
|
155
|
-
|
156
|
-
index = Search.binary_search(sample, 11, :imax => 4)
|
157
|
-
index.should eq [4, nil]
|
158
|
-
end
|
159
|
-
|
160
|
-
it 'behaves consistently when :imin equals :imax' do
|
161
|
-
index = Search.binary_search(sample, 3, :imin => 5, :imax => 5)
|
162
|
-
index.should eq [nil, 5]
|
163
|
-
|
164
|
-
index = Search.binary_search(sample, 11, :imin => 5, :imax => 5)
|
165
|
-
index.should eq [5, 5]
|
166
|
-
|
167
|
-
index = Search.binary_search(sample, 30, :imin => 5, :imax => 5)
|
168
|
-
index.should eq [5, nil]
|
169
|
-
end
|
170
|
-
|
171
|
-
it 'sets :imin to zero (0) when given a negative number' do
|
172
|
-
index = Search.binary_search(sample, 1, :imin => -1)
|
173
|
-
index.should eq [nil, 0]
|
174
|
-
end
|
175
|
-
|
176
|
-
it 'sets :imax to the uppermost index when :imax is out of range' do
|
177
|
-
index = Search.binary_search(sample, 41, :imax => 100)
|
178
|
-
index.should eq [14, nil]
|
179
|
-
end
|
180
|
-
|
181
|
-
it 'returns nil when :imin is greater than :imax' do
|
182
|
-
index = Search.binary_search(sample, 1, :imin => 10, :imax => 5)
|
183
|
-
index.should be_nil
|
184
|
-
end
|
185
|
-
end
|
186
|
-
end
|
187
|
-
end
|
@@ -1,61 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Functional
|
4
|
-
|
5
|
-
describe Sort do
|
6
|
-
|
7
|
-
context '#insertion_sort!' do
|
8
|
-
|
9
|
-
it 'returns nil for a nil sample' do
|
10
|
-
Sort.insertion_sort!(nil).should be_nil
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'returns the sample when the sample is empty' do
|
14
|
-
Sort.insertion_sort!([]).should be_empty
|
15
|
-
end
|
16
|
-
|
17
|
-
it 'returns the sample when the sample has one element' do
|
18
|
-
Sort.insertion_sort!([100]).should eq [100]
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'sorts an unsorted collection' do
|
22
|
-
sample = [31, 37, 26, 30, 2, 30, 1, 33, 5, 14, 11, 13, 17, 35, 4]
|
23
|
-
count = sample.count
|
24
|
-
sorted = Sort.insertion_sort!(sample)
|
25
|
-
Functional.ascending?(sorted).should be_true
|
26
|
-
sorted.count.should eq count
|
27
|
-
end
|
28
|
-
|
29
|
-
it 'does not modify an unsorted collection' do
|
30
|
-
sample = [1, 2, 4, 5, 11, 13, 14, 17, 26, 30, 30, 31, 33, 35, 37]
|
31
|
-
control = sample.dup
|
32
|
-
sorted = Sort.insertion_sort!(sample)
|
33
|
-
sorted.should eq control
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'it sorts a collection with a block' do
|
37
|
-
sample = [
|
38
|
-
{:count => 31},
|
39
|
-
{:count => 37},
|
40
|
-
{:count => 26},
|
41
|
-
{:count => 30},
|
42
|
-
{:count => 2},
|
43
|
-
{:count => 30},
|
44
|
-
{:count => 1}
|
45
|
-
]
|
46
|
-
|
47
|
-
count = sample.count
|
48
|
-
sorted = Sort.insertion_sort!(sample){|item| item[:count]}
|
49
|
-
Functional.ascending?(sorted){|item| item[:count]}.should be_true
|
50
|
-
sorted.count.should eq count
|
51
|
-
end
|
52
|
-
|
53
|
-
it 'performs the sort in place' do
|
54
|
-
lambda {
|
55
|
-
sample = [31, 37, 26, 30, 2, 30, 1, 33, 5, 14, 11, 13, 17, 35, 4].freeze
|
56
|
-
Sort.insertion_sort!(sample)
|
57
|
-
}.should raise_error
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
@@ -1,277 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'fakefs/safe'
|
3
|
-
require 'rbconfig'
|
4
|
-
|
5
|
-
describe 'utilities' do
|
6
|
-
|
7
|
-
context '#delta' do
|
8
|
-
|
9
|
-
it 'computes the delta of two positive values' do
|
10
|
-
delta(10.5, 5.0).should be_within(0.01).of(5.5)
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'computes the delta of two negative values' do
|
14
|
-
delta(-10.5, -5.0).should be_within(0.01).of(5.5)
|
15
|
-
end
|
16
|
-
|
17
|
-
it 'computes the delta of a positive and negative value' do
|
18
|
-
delta(10.5, -5.0).should be_within(0.01).of(15.5)
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'computes the delta of two positive values with a block' do
|
22
|
-
v1 = {:count => 10.5}
|
23
|
-
v2 = {:count => 5.0}
|
24
|
-
delta(v1, v2){|x| x[:count]}.should be_within(0.01).of(5.5)
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'computes the delta of two negative values with a block' do
|
28
|
-
v1 = {:count => -10.5}
|
29
|
-
v2 = {:count => -5.0}
|
30
|
-
delta(v1, v2){|x| x[:count]}.should be_within(0.01).of(5.5)
|
31
|
-
end
|
32
|
-
|
33
|
-
it 'computes the delta of a positive and negative value with a block' do
|
34
|
-
v1 = {:count => 10.5}
|
35
|
-
v2 = {:count => -5.0}
|
36
|
-
delta(v1, v2){|x| x[:count]}.should be_within(0.01).of(15.5)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
context '#repeatedly' do
|
41
|
-
|
42
|
-
it 'returns an empty array when requested times is zero' do
|
43
|
-
expected = repeatedly(0){ 1 }
|
44
|
-
expected.should be_empty
|
45
|
-
end
|
46
|
-
|
47
|
-
it 'returns an array with all nil values when no block is given' do
|
48
|
-
expected = repeatedly(10)
|
49
|
-
expected.length.should eq 10
|
50
|
-
expected.each do |elem|
|
51
|
-
elem.should be_nil
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
it 'iterates the requested number of times and puts the results into an array' do
|
56
|
-
expected = repeatedly(10){ 5 }
|
57
|
-
expected.length.should eq 10
|
58
|
-
expected.each do |elem|
|
59
|
-
elem.should eq 5
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
it 'passes the initial value to the first iteration' do
|
64
|
-
@expected = nil
|
65
|
-
repeatedly(1,100){|previous| @expected = previous }
|
66
|
-
@expected.should eq 100
|
67
|
-
end
|
68
|
-
|
69
|
-
it 'passes the result of each iteration to the next iteration' do
|
70
|
-
expected = repeatedly(10, 1){|previous| previous * 2 }
|
71
|
-
expected.should eq [2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
context '#retro' do
|
76
|
-
|
77
|
-
it 'does not run the block if requested times is zero' do
|
78
|
-
@expected = true
|
79
|
-
retro(0){ @expected = false }
|
80
|
-
@expected.should be_true
|
81
|
-
end
|
82
|
-
|
83
|
-
it 'passes all arguments to the block' do
|
84
|
-
@expected = nil
|
85
|
-
retro(1, ?a, ?b, ?c){|*args| @expected = args }
|
86
|
-
@expected.should eq [?a, ?b, ?c]
|
87
|
-
end
|
88
|
-
|
89
|
-
it 'calls the block once if the first pass is successful' do
|
90
|
-
@expected = 0
|
91
|
-
retro(5){ @expected += 1 }
|
92
|
-
@expected.should eq 1
|
93
|
-
end
|
94
|
-
|
95
|
-
it 'calls the block more than once if the first pass fails' do
|
96
|
-
@expected = 0
|
97
|
-
retro(5) do
|
98
|
-
@expected += 1
|
99
|
-
raise StandardError if @expected < 3
|
100
|
-
end
|
101
|
-
@expected.should eq 3
|
102
|
-
end
|
103
|
-
|
104
|
-
it 'calls the block no more than the requested number of times' do
|
105
|
-
@expected = 0
|
106
|
-
retro(5) do
|
107
|
-
@expected += 1
|
108
|
-
raise StandardError
|
109
|
-
end
|
110
|
-
@expected.should eq 5
|
111
|
-
end
|
112
|
-
|
113
|
-
it 'returns true if any attempt succeeds' do
|
114
|
-
expected = retro(1){ nil }
|
115
|
-
expected.should be_true
|
116
|
-
end
|
117
|
-
|
118
|
-
it 'returns false if all attempts fail' do
|
119
|
-
expected = retro(1){ raise StandardError }
|
120
|
-
expected.should be_false
|
121
|
-
end
|
122
|
-
|
123
|
-
it 'returns false if no block is given' do
|
124
|
-
expected = retro(10)
|
125
|
-
expected.should eq false
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
if RbConfig::CONFIG['ruby_install_name'] =~ /^ruby$/i
|
130
|
-
context '#safe' do
|
131
|
-
|
132
|
-
it 'allows safe operations' do
|
133
|
-
lambda {
|
134
|
-
safe{ 1 + 1 }
|
135
|
-
}.should_not raise_error
|
136
|
-
end
|
137
|
-
|
138
|
-
it 'returns the value of the block when safe' do
|
139
|
-
safe{ 1 + 1 }.should eq 2
|
140
|
-
end
|
141
|
-
|
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
|
145
|
-
|
146
|
-
it 'rejects unsafe operations on tainted objects' do
|
147
|
-
lambda {
|
148
|
-
safe{ Signal.trap('INT'.taint) }
|
149
|
-
}.should raise_error(SecurityError)
|
150
|
-
end
|
151
|
-
|
152
|
-
it 'rejects the use of #eval' do
|
153
|
-
lambda {
|
154
|
-
safe{ eval 'puts 1' }
|
155
|
-
}.should raise_error(SecurityError)
|
156
|
-
end
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
context '#slurp' do
|
161
|
-
|
162
|
-
unless Functional::PLATFORM.rbx?
|
163
|
-
|
164
|
-
before(:all) { FakeFS.activate! }
|
165
|
-
after(:all) { FakeFS.deactivate! }
|
166
|
-
|
167
|
-
let!(:path){ 'slurp.txt' }
|
168
|
-
let!(:text){ 'Hello, world!' }
|
169
|
-
|
170
|
-
it 'returns the contents of the file' do
|
171
|
-
File.open(path, 'w+') {|f| f.write(text) }
|
172
|
-
slurp(path).should eq text
|
173
|
-
end
|
174
|
-
|
175
|
-
it 'raises an exception when the file does not exist' do
|
176
|
-
lambda {
|
177
|
-
slurp('path/does/not/exist')
|
178
|
-
}.should raise_error(Errno::ENOENT)
|
179
|
-
end
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
context '#slurpee' do
|
184
|
-
|
185
|
-
unless Functional::PLATFORM.rbx?
|
186
|
-
|
187
|
-
before(:all) { FakeFS.activate! }
|
188
|
-
after(:all) { FakeFS.deactivate! }
|
189
|
-
|
190
|
-
let!(:path){ 'slurp.txt' }
|
191
|
-
let!(:text){ 'You are number 6.' }
|
192
|
-
let!(:erb) { 'You are number <%= 2 * 3 %>.' }
|
193
|
-
|
194
|
-
it 'returns the processed contents of the file' do
|
195
|
-
File.open(path, 'w+') {|f| f.write(erb) }
|
196
|
-
slurpee(path).should eq text
|
197
|
-
end
|
198
|
-
|
199
|
-
it 'raises an exception when the file does not exist' do
|
200
|
-
lambda {
|
201
|
-
slurpee('path/does/not/exist')
|
202
|
-
}.should raise_error(Errno::ENOENT)
|
203
|
-
end
|
204
|
-
end
|
205
|
-
end
|
206
|
-
|
207
|
-
context '#repl?' do
|
208
|
-
|
209
|
-
before(:each) do
|
210
|
-
@dollar_zero = $0
|
211
|
-
end
|
212
|
-
|
213
|
-
after(:each) do
|
214
|
-
$0 = @dollar_zero
|
215
|
-
end
|
216
|
-
|
217
|
-
def set_dollar_zero(val)
|
218
|
-
$0 = val
|
219
|
-
end
|
220
|
-
|
221
|
-
it 'recognizes IRB' do
|
222
|
-
set_dollar_zero('irb')
|
223
|
-
repl?.should be_true
|
224
|
-
end
|
225
|
-
|
226
|
-
it 'recognizes Pry' do
|
227
|
-
set_dollar_zero('pry')
|
228
|
-
repl?.should be_true
|
229
|
-
end
|
230
|
-
|
231
|
-
it 'recognizes Rails Console' do
|
232
|
-
set_dollar_zero('script/rails')
|
233
|
-
repl?.should be_true
|
234
|
-
end
|
235
|
-
|
236
|
-
it 'recognizes Bundle Console' do
|
237
|
-
set_dollar_zero('bin/bundle')
|
238
|
-
repl?.should be_true
|
239
|
-
end
|
240
|
-
|
241
|
-
it 'returns false when not in a REPL' do
|
242
|
-
set_dollar_zero(__FILE__)
|
243
|
-
repl?.should be_false
|
244
|
-
end
|
245
|
-
end
|
246
|
-
|
247
|
-
context '#timer' do
|
248
|
-
|
249
|
-
it 'returns [0, nil] if no block is given' do
|
250
|
-
duration, result = timer()
|
251
|
-
duration.should eq 0
|
252
|
-
result.should be_nil
|
253
|
-
end
|
254
|
-
|
255
|
-
it 'yields to the block' do
|
256
|
-
@expected = false
|
257
|
-
duration, result = timer{ @expected = true }
|
258
|
-
@expected.should be_true
|
259
|
-
end
|
260
|
-
|
261
|
-
it 'passes all arguments to the block' do
|
262
|
-
@expected = nil
|
263
|
-
duration, result = timer(1,2,3){|a,b,c| @expected = [a,b,c]}
|
264
|
-
@expected.should eq [1,2,3]
|
265
|
-
end
|
266
|
-
|
267
|
-
it 'returns the duration as the first return value' do
|
268
|
-
duration, result = timer{ sleep(0.1) }
|
269
|
-
duration.should > 0
|
270
|
-
end
|
271
|
-
|
272
|
-
it 'returns the block result as the second return value' do
|
273
|
-
duration, result = timer{ 42 }
|
274
|
-
result.should eq 42
|
275
|
-
end
|
276
|
-
end
|
277
|
-
end
|