bihash 1.2.0 → 2.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/.github/workflows/ci.yml +24 -0
- data/README.md +1 -2
- data/bihash.gemspec +8 -8
- data/bin/console +2 -2
- data/lib/bihash/unimplemented_methods.rb +17 -7
- data/lib/bihash/version.rb +1 -1
- data/lib/bihash.rb +101 -47
- data/spec/bihash_spec.rb +736 -296
- metadata +15 -32
- data/.travis.yml +0 -6
data/spec/bihash_spec.rb
CHANGED
|
@@ -2,244 +2,380 @@ require 'spec_helper'
|
|
|
2
2
|
|
|
3
3
|
describe Bihash do
|
|
4
4
|
it 'should be enumerable' do
|
|
5
|
-
Bihash.must_include Enumerable
|
|
5
|
+
_(Bihash).must_include Enumerable
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
Bihash::UNIMPLEMENTED_CLASS_METHODS.each do |method|
|
|
9
|
+
it "should report that it does not respond to ::#{method}" do
|
|
10
|
+
_(Bihash.respond_to?(method)).must_equal false
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "should raise NoMethodError if ::#{method} is called" do
|
|
14
|
+
error = _(-> { Bihash.send(method) }).must_raise NoMethodError
|
|
15
|
+
_(error.message).must_equal "Bihash::#{method} not implemented"
|
|
16
|
+
end
|
|
6
17
|
end
|
|
7
18
|
|
|
8
19
|
Bihash::UNIMPLEMENTED_METHODS.each do |method|
|
|
9
20
|
it "should report that it does not respond to ##{method}" do
|
|
10
|
-
Bihash.new.respond_to?(method).must_equal false
|
|
21
|
+
_(Bihash.new.respond_to?(method)).must_equal false
|
|
11
22
|
end
|
|
12
23
|
|
|
13
24
|
it "should raise NoMethodError if ##{method} is called" do
|
|
14
|
-
error = -> { Bihash.new.send(method) }.must_raise NoMethodError
|
|
15
|
-
error.message.must_equal "Bihash##{method} not implemented"
|
|
25
|
+
error = _(-> { Bihash.new.send(method) }).must_raise NoMethodError
|
|
26
|
+
_(error.message).must_equal "Bihash##{method} not implemented"
|
|
16
27
|
end
|
|
17
28
|
end
|
|
18
29
|
|
|
19
30
|
describe '::[]' do
|
|
20
31
|
it 'should be able to create an empty bihash' do
|
|
21
32
|
bh = Bihash[]
|
|
22
|
-
bh.must_be_instance_of Bihash
|
|
23
|
-
bh.must_be_empty
|
|
33
|
+
_(bh).must_be_instance_of Bihash
|
|
34
|
+
_(bh).must_be_empty
|
|
24
35
|
end
|
|
25
36
|
|
|
26
37
|
it 'should convert a hash to a bihash' do
|
|
27
38
|
bh = Bihash[:key => 'value']
|
|
28
|
-
bh.must_be_instance_of Bihash
|
|
29
|
-
bh[:key].must_equal 'value'
|
|
30
|
-
bh['value'].must_equal :key
|
|
39
|
+
_(bh).must_be_instance_of Bihash
|
|
40
|
+
_(bh[:key]).must_equal 'value'
|
|
41
|
+
_(bh['value']).must_equal :key
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it 'should not carry over the default value' do
|
|
45
|
+
h = Hash.new(404)
|
|
46
|
+
bh = Bihash[h]
|
|
47
|
+
_(bh.default).must_be_nil
|
|
48
|
+
_(bh[:not_a_key]).must_be_nil
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it 'should not carry over the default_proc' do
|
|
52
|
+
h = Hash.new { "#{_2} not found" }
|
|
53
|
+
bh = Bihash[h]
|
|
54
|
+
_(bh.default_proc).must_be_nil
|
|
55
|
+
_(bh[:not_a_key]).must_be_nil
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it 'should not carry over compare_by_identity' do
|
|
59
|
+
h = Hash.new.compare_by_identity
|
|
60
|
+
h[Array.new] = :array
|
|
61
|
+
bh = Bihash[h]
|
|
62
|
+
_(bh.compare_by_identity?).must_equal false
|
|
63
|
+
_(bh[Array.new]).must_equal :array
|
|
31
64
|
end
|
|
32
65
|
|
|
33
66
|
it 'should not accept a hash with duplicate values' do
|
|
34
|
-
-> { Bihash[:k1 => 'val', :k2 => 'val'] }.must_raise ArgumentError
|
|
67
|
+
_(-> { Bihash[:k1 => 'val', :k2 => 'val'] }).must_raise ArgumentError
|
|
35
68
|
end
|
|
36
69
|
|
|
37
70
|
it 'should not accept a hash that would result in ambiguous mappings' do
|
|
38
|
-
-> { Bihash[1, 2, 2, 3] }.must_raise ArgumentError
|
|
71
|
+
_(-> { Bihash[1, 2, 2, 3] }).must_raise ArgumentError
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it 'should not accept a hash that has ambiguous mappings that are ==' do
|
|
75
|
+
_(-> { Bihash[1, 1.0, 1.0, :anything]}).must_raise ArgumentError
|
|
39
76
|
end
|
|
40
77
|
|
|
41
78
|
it 'should accept a hash where a key equals its value' do
|
|
42
79
|
bh = Bihash[:key => :key]
|
|
43
|
-
bh.must_be_instance_of Bihash
|
|
44
|
-
bh[:key].must_equal :key
|
|
80
|
+
_(bh).must_be_instance_of Bihash
|
|
81
|
+
_(bh[:key]).must_equal :key
|
|
45
82
|
end
|
|
46
83
|
|
|
47
84
|
it 'should always return the value object if key-value pairs are equal' do
|
|
48
85
|
key, value = [], []
|
|
49
86
|
bh = Bihash[key => value]
|
|
50
|
-
bh.must_be_instance_of Bihash
|
|
51
|
-
bh[key].object_id.must_equal value.object_id
|
|
52
|
-
bh[value].object_id.must_equal value.object_id
|
|
87
|
+
_(bh).must_be_instance_of Bihash
|
|
88
|
+
_(bh[key].object_id).must_equal value.object_id
|
|
89
|
+
_(bh[value].object_id).must_equal value.object_id
|
|
53
90
|
end
|
|
54
91
|
|
|
55
92
|
it 'should accept an even number of arguments' do
|
|
56
93
|
bh = Bihash[:k1, 1, :k2, 2]
|
|
57
|
-
bh.must_be_instance_of Bihash
|
|
58
|
-
bh[:k1].must_equal 1
|
|
59
|
-
bh[:k2].must_equal 2
|
|
60
|
-
bh[1].must_equal :k1
|
|
61
|
-
bh[2].must_equal :k2
|
|
94
|
+
_(bh).must_be_instance_of Bihash
|
|
95
|
+
_(bh[:k1]).must_equal 1
|
|
96
|
+
_(bh[:k2]).must_equal 2
|
|
97
|
+
_(bh[1]).must_equal :k1
|
|
98
|
+
_(bh[2]).must_equal :k2
|
|
62
99
|
end
|
|
63
100
|
|
|
64
101
|
it 'should accept an array of key-value pairs packaged in arrays' do
|
|
65
102
|
array = [[:k1, 1], [:k2, 2]]
|
|
66
103
|
bh = Bihash[array]
|
|
67
|
-
bh.must_be_instance_of Bihash
|
|
68
|
-
bh[:k1].must_equal 1
|
|
69
|
-
bh[:k2].must_equal 2
|
|
70
|
-
bh[1].must_equal :k1
|
|
71
|
-
bh[2].must_equal :k2
|
|
104
|
+
_(bh).must_be_instance_of Bihash
|
|
105
|
+
_(bh[:k1]).must_equal 1
|
|
106
|
+
_(bh[:k2]).must_equal 2
|
|
107
|
+
_(bh[1]).must_equal :k1
|
|
108
|
+
_(bh[2]).must_equal :k2
|
|
72
109
|
end
|
|
73
110
|
end
|
|
74
111
|
|
|
75
112
|
describe '::new' do
|
|
76
113
|
it 'should create an empty bihash with a default of nil if no args' do
|
|
77
114
|
bh = Bihash.new
|
|
78
|
-
bh.must_be_instance_of Bihash
|
|
79
|
-
bh.must_be_empty
|
|
80
|
-
bh[:not_a_key].must_be_nil
|
|
115
|
+
_(bh).must_be_instance_of Bihash
|
|
116
|
+
_(bh).must_be_empty
|
|
117
|
+
_(bh[:not_a_key]).must_be_nil
|
|
81
118
|
end
|
|
82
119
|
|
|
83
120
|
it 'should create an empty bihash with a default if given an object arg' do
|
|
84
|
-
bh = Bihash.new('default')
|
|
85
|
-
bh.must_be_instance_of Bihash
|
|
86
|
-
bh.must_be_empty
|
|
87
|
-
bh[:not_a_key].must_equal 'default'
|
|
88
|
-
bh[:not_a_key]
|
|
89
|
-
bh[:still_not_a_key].must_equal '
|
|
121
|
+
bh = Bihash.new(['default'])
|
|
122
|
+
_(bh).must_be_instance_of Bihash
|
|
123
|
+
_(bh).must_be_empty
|
|
124
|
+
_(bh[:not_a_key]).must_equal ['default']
|
|
125
|
+
bh[:not_a_key] << 'pwned'
|
|
126
|
+
_(bh[:still_not_a_key]).must_equal ['default', 'pwned']
|
|
90
127
|
end
|
|
91
128
|
|
|
92
129
|
it 'should create an empty bihash with a default if given a block arg' do
|
|
93
|
-
bh = Bihash.new { '
|
|
94
|
-
bh.must_be_instance_of Bihash
|
|
95
|
-
bh.must_be_empty
|
|
96
|
-
bh[:not_a_key].must_equal '
|
|
97
|
-
bh[:not_a_key]
|
|
98
|
-
bh[:not_a_key].must_equal '
|
|
130
|
+
bh = Bihash.new { ['default'] }
|
|
131
|
+
_(bh).must_be_instance_of Bihash
|
|
132
|
+
_(bh).must_be_empty
|
|
133
|
+
_(bh[:not_a_key]).must_equal ['default']
|
|
134
|
+
bh[:not_a_key] << '(not) pwned'
|
|
135
|
+
_(bh[:not_a_key]).must_equal ['default']
|
|
99
136
|
end
|
|
100
137
|
|
|
101
138
|
it 'should allow assignment of new pairs if given a block arg' do
|
|
102
139
|
bh = Bihash.new { |bihash, key| bihash[key] = key.to_s }
|
|
103
|
-
bh[404].must_equal '404'
|
|
104
|
-
bh.size.must_equal 1
|
|
105
|
-
bh.must_include 404
|
|
106
|
-
bh.must_include '404'
|
|
140
|
+
_(bh[404]).must_equal '404'
|
|
141
|
+
_(bh.size).must_equal 1
|
|
142
|
+
_(bh).must_include 404
|
|
143
|
+
_(bh).must_include '404'
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
it 'should accept capacity as an optimization with and without defaults' do
|
|
147
|
+
bh1 = Bihash.new(capacity: 42)
|
|
148
|
+
_(bh1[:not_a_key]).must_be_nil
|
|
149
|
+
|
|
150
|
+
bh2 = Bihash.new(404, capacity: 42)
|
|
151
|
+
_(bh2[:not_a_key]).must_equal 404
|
|
152
|
+
|
|
153
|
+
bh3 = Bihash.new(capacity: 42) { "#{_2} not found" }
|
|
154
|
+
_(bh3[404]).must_equal '404 not found'
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
it 'should not accept arbitrary keyword arguments' do
|
|
158
|
+
_(-> { Bihash.new(keywords: true) }).must_raise ArgumentError
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
it 'should accept a default that is a hash' do
|
|
162
|
+
bh = Bihash.new({hash: true})
|
|
163
|
+
_(bh[:not_a_key]).must_equal({hash: true})
|
|
107
164
|
end
|
|
108
165
|
|
|
109
166
|
it 'should not accept both an object and a block' do
|
|
110
|
-
-> { Bihash.new('default 1') { 'default 2' } }.must_raise ArgumentError
|
|
167
|
+
_(-> { Bihash.new('default 1') { 'default 2' } }).must_raise ArgumentError
|
|
111
168
|
end
|
|
112
169
|
end
|
|
113
170
|
|
|
114
171
|
describe '::try_convert' do
|
|
172
|
+
it 'should return the bihash if given a bihash' do
|
|
173
|
+
original_bh = Bihash[:key => 'value']
|
|
174
|
+
returned_bh = Bihash.try_convert(original_bh)
|
|
175
|
+
_(original_bh.object_id).must_equal returned_bh.object_id
|
|
176
|
+
end
|
|
177
|
+
|
|
115
178
|
it 'should convert an object to a bihash if it responds to #to_hash' do
|
|
116
179
|
hash = {:k1 => 1, :k2 => 2}
|
|
117
180
|
bh = Bihash.try_convert(hash)
|
|
118
|
-
bh.must_be_instance_of Bihash
|
|
119
|
-
bh[:k1].must_equal 1
|
|
120
|
-
bh[:k2].must_equal 2
|
|
121
|
-
bh[1].must_equal :k1
|
|
122
|
-
bh[2].must_equal :k2
|
|
181
|
+
_(bh).must_be_instance_of Bihash
|
|
182
|
+
_(bh[:k1]).must_equal 1
|
|
183
|
+
_(bh[:k2]).must_equal 2
|
|
184
|
+
_(bh[1]).must_equal :k1
|
|
185
|
+
_(bh[2]).must_equal :k2
|
|
123
186
|
end
|
|
124
187
|
|
|
125
|
-
it 'should
|
|
126
|
-
|
|
127
|
-
Bihash.try_convert(bh).must_equal bh
|
|
188
|
+
it 'should return nil if the object does not respond to #to_hash' do
|
|
189
|
+
_(Bihash.try_convert(Object.new)).must_be_nil
|
|
128
190
|
end
|
|
129
191
|
|
|
130
|
-
it 'should
|
|
131
|
-
|
|
192
|
+
it 'should protect against mutations the original object' do
|
|
193
|
+
hash = {:k1 => 1, :k2 => 2}
|
|
194
|
+
bh = Bihash.try_convert(hash)
|
|
195
|
+
hash[:k3] = 3
|
|
196
|
+
_(bh).must_equal Bihash[:k1 => 1, :k2 => 2]
|
|
197
|
+
_(bh.include?(:k3)).must_equal false
|
|
198
|
+
_(bh.include?(3)).must_equal false
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
it 'should not carry over the default value' do
|
|
202
|
+
h = Hash.new(404)
|
|
203
|
+
bh = Bihash.try_convert(h)
|
|
204
|
+
_(bh.default).must_be_nil
|
|
205
|
+
_(bh[:not_a_key]).must_be_nil
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
it 'should not carry over the default_proc' do
|
|
209
|
+
h = Hash.new { "#{_2} not found" }
|
|
210
|
+
bh = Bihash.try_convert(h)
|
|
211
|
+
_(bh.default_proc).must_be_nil
|
|
212
|
+
_(bh[:not_a_key]).must_be_nil
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
it 'should not carry over compare_by_identity' do
|
|
216
|
+
h = Hash.new.compare_by_identity
|
|
217
|
+
h[Array.new] = :array
|
|
218
|
+
bh = Bihash.try_convert(h)
|
|
219
|
+
_(bh.compare_by_identity?).must_equal false
|
|
220
|
+
_(bh[Array.new]).must_equal :array
|
|
132
221
|
end
|
|
133
222
|
|
|
134
223
|
it 'should not accept a hash with duplicate values' do
|
|
135
|
-
-> { Bihash.try_convert(:k1 => 1, :k2 => 1) }.must_raise ArgumentError
|
|
224
|
+
_(-> { Bihash.try_convert(:k1 => 1, :k2 => 1) }).must_raise ArgumentError
|
|
136
225
|
end
|
|
137
226
|
end
|
|
138
227
|
|
|
139
228
|
describe '#<' do
|
|
140
229
|
it 'should raise an error if the right hand side is not a bihash' do
|
|
141
|
-
-> { Bihash[a: 1, b: 2] < {a: 1, b: 2, c: 3} }.must_raise TypeError
|
|
230
|
+
_(-> { Bihash[a: 1, b: 2] < {a: 1, b: 2, c: 3} }).must_raise TypeError
|
|
142
231
|
end
|
|
143
232
|
|
|
144
233
|
it 'should return true when the argument is a strict subset of self' do
|
|
145
|
-
(Bihash[a: 1, b: 2] < Bihash[a: 1, b: 2, c: 3]).must_equal true
|
|
234
|
+
_(Bihash[a: 1, b: 2] < Bihash[a: 1, b: 2, c: 3]).must_equal true
|
|
146
235
|
end
|
|
147
236
|
|
|
148
237
|
it 'should return false when the argument is equal to self' do
|
|
149
|
-
(Bihash[a: 1, b: 2] < Bihash[a: 1, b: 2]).must_equal false
|
|
238
|
+
_(Bihash[a: 1, b: 2] < Bihash[a: 1, b: 2]).must_equal false
|
|
150
239
|
end
|
|
151
240
|
|
|
152
241
|
it 'should return false when the argument is not a subset of self' do
|
|
153
|
-
(Bihash[a: 1, b: 2, c: 3] < Bihash[a: 1, b: 2]).must_equal false
|
|
242
|
+
_(Bihash[a: 1, b: 2, c: 3] < Bihash[a: 1, b: 2]).must_equal false
|
|
154
243
|
end
|
|
155
244
|
end
|
|
156
245
|
|
|
157
246
|
describe '#<=' do
|
|
158
247
|
it 'should raise an error if the right hand side is not a bihash' do
|
|
159
|
-
-> { Bihash[a: 1, b: 2] <= {a: 1, b: 2, c: 3} }.must_raise TypeError
|
|
248
|
+
_(-> { Bihash[a: 1, b: 2] <= {a: 1, b: 2, c: 3} }).must_raise TypeError
|
|
160
249
|
end
|
|
161
250
|
|
|
162
251
|
it 'should return true when the argument is a strict subset of self' do
|
|
163
|
-
(Bihash[a: 1, b: 2] <= Bihash[a: 1, b: 2, c: 3]).must_equal true
|
|
252
|
+
_(Bihash[a: 1, b: 2] <= Bihash[a: 1, b: 2, c: 3]).must_equal true
|
|
164
253
|
end
|
|
165
254
|
|
|
166
255
|
it 'should return true when the argument is equal to self' do
|
|
167
|
-
(Bihash[a: 1, b: 2] <= Bihash[a: 1, b: 2]).must_equal true
|
|
256
|
+
_(Bihash[a: 1, b: 2] <= Bihash[a: 1, b: 2]).must_equal true
|
|
168
257
|
end
|
|
169
258
|
|
|
170
259
|
it 'should return false when the argument is not a subset of self' do
|
|
171
|
-
(Bihash[a: 1, b: 2, c: 3] <= Bihash[a: 1, b: 2]).must_equal false
|
|
260
|
+
_(Bihash[a: 1, b: 2, c: 3] <= Bihash[a: 1, b: 2]).must_equal false
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
it 'should not treat == values as eql? when comparing pairs' do
|
|
264
|
+
bh1 = Bihash[1.to_i => 1.to_r, 1.to_f => 1.to_c]
|
|
265
|
+
bh2 = Bihash[1.to_i => 1.to_c, 1.to_f => 1.to_r]
|
|
266
|
+
_(bh1 <= bh2).must_equal false
|
|
172
267
|
end
|
|
173
268
|
end
|
|
174
269
|
|
|
175
270
|
describe '#==' do
|
|
176
271
|
it 'should return true when two bihashes have the same pairs' do
|
|
177
272
|
bh1, bh2 = Bihash[:k1 => 1, :k2 => 2], Bihash[2 => :k2, 1 => :k1]
|
|
178
|
-
(bh1 == bh2).must_equal true
|
|
273
|
+
_(bh1 == bh2).must_equal true
|
|
179
274
|
end
|
|
180
275
|
|
|
181
276
|
it 'should return false when two bihashes do not have the same pairs' do
|
|
182
277
|
bh1, bh2 = Bihash[:k1 => 1, :k2 => 2], Bihash[:k1 => 1, :k2 => 99]
|
|
183
|
-
(bh1 == bh2).must_equal false
|
|
278
|
+
_(bh1 == bh2).must_equal false
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
it 'should compare pairs using #eql? (since all values are also keys)' do
|
|
282
|
+
bh1 = Bihash[1.to_i => 1.to_r, 1.to_f => 1.to_c]
|
|
283
|
+
bh2 = Bihash[1.to_i => 1.to_c, 1.to_f => 1.to_r]
|
|
284
|
+
_(bh1 == bh2).must_equal false
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
describe 'when the bihashes differ on compare_by_identity' do
|
|
288
|
+
it 'should return true when both bihashes are empty' do
|
|
289
|
+
bh1 = Bihash[].compare_by_identity
|
|
290
|
+
bh2 = Bihash[]
|
|
291
|
+
_(bh1 == bh2).must_equal true
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
it 'should return false for non-empty bihashes' do
|
|
295
|
+
bh1 = Bihash[one: 1].compare_by_identity
|
|
296
|
+
bh2 = Bihash[one: 1]
|
|
297
|
+
_(bh1 == bh2).must_equal false
|
|
298
|
+
end
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
describe 'when compare_by_identity is set on both bihashes' do
|
|
302
|
+
it 'should return true when all pairs are equal?' do
|
|
303
|
+
i, r, f, c = 1.to_i, 1.to_r, 1.to_f, 1.to_c
|
|
304
|
+
bh1 = Bihash[i => r, f => c].compare_by_identity
|
|
305
|
+
bh2 = Bihash[i => r, f => c].compare_by_identity
|
|
306
|
+
_(bh1 == bh2).must_equal true
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
it 'should return false when all pairs are eql? but not equal?' do
|
|
310
|
+
bh1 = Bihash[1.to_i => 1.to_r, 1.to_f => 1.to_c].compare_by_identity
|
|
311
|
+
bh2 = Bihash[1.to_i => 1.to_r, 1.to_f => 1.to_c].compare_by_identity
|
|
312
|
+
_(bh1 == bh2).must_equal false
|
|
313
|
+
end
|
|
184
314
|
end
|
|
185
315
|
|
|
186
316
|
it 'should be aliased to #eql?' do
|
|
187
317
|
bh = Bihash.new
|
|
188
|
-
bh.method(:eql?).must_equal bh.method(:==)
|
|
318
|
+
_(bh.method(:eql?)).must_equal bh.method(:==)
|
|
189
319
|
end
|
|
190
320
|
end
|
|
191
321
|
|
|
192
322
|
describe '#>' do
|
|
193
323
|
it 'should raise an error if the right hand side is not a bihash' do
|
|
194
|
-
-> { Bihash[a: 1, b: 2] > {a: 1, b: 2, c: 3} }.must_raise TypeError
|
|
324
|
+
_(-> { Bihash[a: 1, b: 2] > {a: 1, b: 2, c: 3} }).must_raise TypeError
|
|
195
325
|
end
|
|
196
326
|
|
|
197
327
|
it 'should return true when the argument is a strict superset of self' do
|
|
198
|
-
(Bihash[a: 1, b: 2, c: 3] > Bihash[a: 1, b: 2]).must_equal true
|
|
328
|
+
_(Bihash[a: 1, b: 2, c: 3] > Bihash[a: 1, b: 2]).must_equal true
|
|
199
329
|
end
|
|
200
330
|
|
|
201
331
|
it 'should return false when the argument is equal to self' do
|
|
202
|
-
(Bihash[a: 1, b: 2] > Bihash[a: 1, b: 2]).must_equal false
|
|
332
|
+
_(Bihash[a: 1, b: 2] > Bihash[a: 1, b: 2]).must_equal false
|
|
203
333
|
end
|
|
204
334
|
|
|
205
335
|
it 'should return false when the argument is not a superset of self' do
|
|
206
|
-
(Bihash[a: 1, b: 2] > Bihash[a: 1, b: 2, c: 3]).must_equal false
|
|
336
|
+
_(Bihash[a: 1, b: 2] > Bihash[a: 1, b: 2, c: 3]).must_equal false
|
|
207
337
|
end
|
|
208
338
|
end
|
|
209
339
|
|
|
210
340
|
describe '#>=' do
|
|
211
341
|
it 'should raise an error if the right hand side is not a bihash' do
|
|
212
|
-
-> { Bihash[a: 1, b: 2] >= {a: 1, b: 2, c: 3} }.must_raise TypeError
|
|
342
|
+
_(-> { Bihash[a: 1, b: 2] >= {a: 1, b: 2, c: 3} }).must_raise TypeError
|
|
213
343
|
end
|
|
214
344
|
|
|
215
345
|
it 'should return true when the argument is a strict superset of self' do
|
|
216
|
-
(Bihash[a: 1, b: 2, c: 3] >= Bihash[a: 1, b: 2]).must_equal true
|
|
346
|
+
_(Bihash[a: 1, b: 2, c: 3] >= Bihash[a: 1, b: 2]).must_equal true
|
|
217
347
|
end
|
|
218
348
|
|
|
219
349
|
it 'should return true when the argument is equal to self' do
|
|
220
|
-
(Bihash[a: 1, b: 2] >= Bihash[a: 1, b: 2]).must_equal true
|
|
350
|
+
_(Bihash[a: 1, b: 2] >= Bihash[a: 1, b: 2]).must_equal true
|
|
221
351
|
end
|
|
222
352
|
|
|
223
353
|
it 'should return false when the argument is not a superset of self' do
|
|
224
|
-
(Bihash[a: 1, b: 2] >= Bihash[a: 1, b: 2, c: 3]).must_equal false
|
|
354
|
+
_(Bihash[a: 1, b: 2] >= Bihash[a: 1, b: 2, c: 3]).must_equal false
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
it 'should not treat == values as eql? when comparing pairs' do
|
|
358
|
+
bh1 = Bihash[1.to_i => 1.to_r, 1.to_f => 1.to_c]
|
|
359
|
+
bh2 = Bihash[1.to_i => 1.to_c, 1.to_f => 1.to_r]
|
|
360
|
+
_(bh1 >= bh2).must_equal false
|
|
225
361
|
end
|
|
226
362
|
end
|
|
227
363
|
|
|
228
364
|
describe '#[]' do
|
|
229
365
|
it 'should return the other pair' do
|
|
230
366
|
bh = Bihash[:key => 'value']
|
|
231
|
-
bh[:key].must_equal 'value'
|
|
232
|
-
bh['value'].must_equal :key
|
|
367
|
+
_(bh[:key]).must_equal 'value'
|
|
368
|
+
_(bh['value']).must_equal :key
|
|
233
369
|
end
|
|
234
370
|
|
|
235
371
|
it 'should return falsey values correctly' do
|
|
236
372
|
bh1 = Bihash[nil => false]
|
|
237
|
-
bh1[nil].must_equal false
|
|
238
|
-
bh1[false].must_be_nil
|
|
373
|
+
_(bh1[nil]).must_equal false
|
|
374
|
+
_(bh1[false]).must_be_nil
|
|
239
375
|
|
|
240
376
|
bh2 = Bihash[false => nil]
|
|
241
|
-
bh2[false].must_be_nil
|
|
242
|
-
bh2[nil].must_equal false
|
|
377
|
+
_(bh2[false]).must_be_nil
|
|
378
|
+
_(bh2[nil]).must_equal false
|
|
243
379
|
end
|
|
244
380
|
end
|
|
245
381
|
|
|
@@ -247,68 +383,125 @@ describe Bihash do
|
|
|
247
383
|
it 'should allow assignment of new pairs' do
|
|
248
384
|
bh = Bihash.new
|
|
249
385
|
bh[:key] = 'value'
|
|
250
|
-
bh[:key].must_equal 'value'
|
|
251
|
-
bh['value'].must_equal :key
|
|
386
|
+
_(bh[:key]).must_equal 'value'
|
|
387
|
+
_(bh['value']).must_equal :key
|
|
252
388
|
end
|
|
253
389
|
|
|
254
390
|
it 'should remove old pairs if old keys are re-assigned' do
|
|
255
391
|
bh = Bihash[1 => 'one', 2 => 'two']
|
|
256
392
|
bh[1] = 'uno'
|
|
257
|
-
bh[1].must_equal 'uno'
|
|
258
|
-
bh['uno'].must_equal 1
|
|
259
|
-
bh.wont_include 'one'
|
|
393
|
+
_(bh[1]).must_equal 'uno'
|
|
394
|
+
_(bh['uno']).must_equal 1
|
|
395
|
+
_(bh).wont_include 'one'
|
|
260
396
|
end
|
|
261
397
|
|
|
262
398
|
it 'should always return the value object if key-value pairs are equal' do
|
|
263
399
|
key, value = [], []
|
|
264
400
|
bh = Bihash.new
|
|
265
401
|
bh[key] = value
|
|
266
|
-
bh[key].object_id.must_equal value.object_id
|
|
267
|
-
bh[value].object_id.must_equal value.object_id
|
|
402
|
+
_(bh[key].object_id).must_equal value.object_id
|
|
403
|
+
_(bh[value].object_id).must_equal value.object_id
|
|
268
404
|
end
|
|
269
405
|
|
|
270
406
|
it 'should be aliased to #store' do
|
|
271
407
|
bh = Bihash.new
|
|
272
|
-
bh.method(:store).must_equal bh.method(:[]=)
|
|
408
|
+
_(bh.method(:store)).must_equal bh.method(:[]=)
|
|
273
409
|
bh.store(:key, 'value')
|
|
274
|
-
bh[:key].must_equal 'value'
|
|
275
|
-
bh['value'].must_equal :key
|
|
410
|
+
_(bh[:key]).must_equal 'value'
|
|
411
|
+
_(bh['value']).must_equal :key
|
|
276
412
|
end
|
|
277
413
|
|
|
278
|
-
it 'should raise
|
|
279
|
-
-> { Bihash.new.freeze[:key] = 'value' }.must_raise
|
|
414
|
+
it 'should raise FrozenError if called on a frozen bihash' do
|
|
415
|
+
_(-> { Bihash.new.freeze[:key] = 'value' }).must_raise FrozenError
|
|
280
416
|
end
|
|
281
417
|
end
|
|
282
418
|
|
|
283
419
|
describe '#assoc' do
|
|
284
420
|
it 'should return the pair if the argument is a key' do
|
|
285
421
|
bh = Bihash[:k1 => 'v1', :k2 => 'v2']
|
|
286
|
-
bh.assoc(:k1).must_equal [:k1, 'v1']
|
|
287
|
-
bh.assoc('v2').must_equal ['v2', :k2]
|
|
422
|
+
_(bh.assoc(:k1)).must_equal [:k1, 'v1']
|
|
423
|
+
_(bh.assoc('v2')).must_equal ['v2', :k2]
|
|
288
424
|
end
|
|
289
425
|
|
|
290
426
|
it 'should return nil if the argument is not a key' do
|
|
291
427
|
bh = Bihash.new(404)
|
|
292
|
-
bh.assoc(:not_a_key).must_be_nil
|
|
428
|
+
_(bh.assoc(:not_a_key)).must_be_nil
|
|
293
429
|
end
|
|
294
430
|
|
|
295
431
|
it 'should find the key using #==' do
|
|
296
432
|
bh = Bihash[[] => 'array']
|
|
297
433
|
bh['array'] << 'modified'
|
|
298
|
-
bh.assoc(['modified']).must_equal [['modified'], 'array']
|
|
299
|
-
bh.assoc([]).must_be_nil
|
|
434
|
+
_(bh.assoc(['modified'])).must_equal [['modified'], 'array']
|
|
435
|
+
_(bh.assoc([])).must_be_nil
|
|
436
|
+
end
|
|
437
|
+
end
|
|
438
|
+
|
|
439
|
+
describe '#compact' do
|
|
440
|
+
describe 'when any pairs contain a nil key' do
|
|
441
|
+
it 'should return a new bihash with any pairs containing nil removed' do
|
|
442
|
+
bh = Bihash[1 => :one, 2 => nil, 3 => :three]
|
|
443
|
+
_(bh.compact).must_equal Bihash[1 => :one, 3 => :three]
|
|
444
|
+
_(bh).must_equal Bihash[1 => :one, 2 => nil, 3 => :three]
|
|
445
|
+
end
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
describe 'no pairs contain a nil key' do
|
|
449
|
+
it 'should return a copy of the original bihash' do
|
|
450
|
+
bh = Bihash[1 => :one, 2 => :two, 3 => :three]
|
|
451
|
+
compacted_bh = bh.compact
|
|
452
|
+
_(compacted_bh).must_equal Bihash[1 => :one, 2=> :two, 3 => :three]
|
|
453
|
+
_(compacted_bh.object_id).wont_equal bh.object_id
|
|
454
|
+
end
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
it 'should return a new bihash with defaults copied' do
|
|
458
|
+
bh_default = Bihash.new(404)
|
|
459
|
+
_(bh_default.compact.default).must_equal 404
|
|
460
|
+
bh_default_proc = Bihash.new { "hello #{_2}" }
|
|
461
|
+
_(bh_default_proc.compact.default(:world)).must_equal "hello world"
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
it 'should return a new bihash with compare_by_identity copied' do
|
|
465
|
+
bh = Bihash[]
|
|
466
|
+
_(bh.compact.compare_by_identity?).must_equal false
|
|
467
|
+
bh.compare_by_identity
|
|
468
|
+
_(bh.compact.compare_by_identity?).must_equal true
|
|
469
|
+
end
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
describe '#compact!' do
|
|
473
|
+
it 'should delete any pairs containing nil' do
|
|
474
|
+
bh1 = Bihash[1 => :one, 2 => nil, 3 => :three]
|
|
475
|
+
bh1_id = bh1.object_id
|
|
476
|
+
_(bh1.compact!.object_id).must_equal bh1_id
|
|
477
|
+
_(bh1).must_equal Bihash[1 => :one, 3 => :three]
|
|
478
|
+
|
|
479
|
+
bh2 = Bihash[1 => :one, 2 => nil, 3 => :three]
|
|
480
|
+
bh2_id = bh2.object_id
|
|
481
|
+
_(bh2.compact!.object_id).must_equal bh2_id
|
|
482
|
+
_(bh2).must_equal Bihash[1 => :one, 3 => :three]
|
|
483
|
+
end
|
|
484
|
+
|
|
485
|
+
it 'should return nil if no changes were made to the bihash' do
|
|
486
|
+
bh = Bihash[1 => :one, 2 => :two, 3 => :three, 4 => :four]
|
|
487
|
+
_(bh.compact!).must_be_nil
|
|
488
|
+
_(bh).must_equal Bihash[1 => :one, 2 => :two, 3 => :three, 4 => :four]
|
|
489
|
+
end
|
|
490
|
+
|
|
491
|
+
it 'should raise FrozenError if called on a frozen bihash' do
|
|
492
|
+
_(-> { Bihash.new.freeze.compact! }).must_raise FrozenError
|
|
300
493
|
end
|
|
301
494
|
end
|
|
302
495
|
|
|
303
496
|
describe '#clear' do
|
|
304
497
|
it 'should remove all pairs and return the bihash' do
|
|
305
498
|
bh = Bihash[:key => 'value']
|
|
306
|
-
bh.clear.object_id.must_equal bh.object_id
|
|
307
|
-
bh.must_be_empty
|
|
499
|
+
_(bh.clear.object_id).must_equal bh.object_id
|
|
500
|
+
_(bh).must_be_empty
|
|
308
501
|
end
|
|
309
502
|
|
|
310
|
-
it 'should raise
|
|
311
|
-
-> { Bihash.new.freeze.clear }.must_raise
|
|
503
|
+
it 'should raise FrozenError if called on a frozen bihash' do
|
|
504
|
+
_(-> { Bihash.new.freeze.clear }).must_raise FrozenError
|
|
312
505
|
end
|
|
313
506
|
end
|
|
314
507
|
|
|
@@ -317,7 +510,30 @@ describe Bihash do
|
|
|
317
510
|
bh = Bihash[1 => :one]
|
|
318
511
|
clone = bh.clone
|
|
319
512
|
clone[2] = :two
|
|
320
|
-
bh[2].must_be_nil
|
|
513
|
+
_(bh[2]).must_be_nil
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
it 'should copy the default value' do
|
|
517
|
+
bh = Bihash.new(404)
|
|
518
|
+
clone = bh.clone
|
|
519
|
+
_(clone.default).must_equal 404
|
|
520
|
+
end
|
|
521
|
+
|
|
522
|
+
it 'should copy the default proc' do
|
|
523
|
+
bh = Bihash.new { |_,k| k.to_s }
|
|
524
|
+
clone = bh.clone
|
|
525
|
+
_(clone.default(:not_a_key)).must_equal 'not_a_key'
|
|
526
|
+
end
|
|
527
|
+
|
|
528
|
+
it 'should copy compare_by_identity' do
|
|
529
|
+
bh = Bihash[]
|
|
530
|
+
_(bh.clone.compare_by_identity?).must_equal false
|
|
531
|
+
bh.compare_by_identity
|
|
532
|
+
_(bh.clone.compare_by_identity?).must_equal true
|
|
533
|
+
end
|
|
534
|
+
|
|
535
|
+
it 'should copy the frozen state' do
|
|
536
|
+
_(Bihash.new.freeze.clone.frozen?).must_equal true
|
|
321
537
|
end
|
|
322
538
|
end
|
|
323
539
|
|
|
@@ -326,58 +542,76 @@ describe Bihash do
|
|
|
326
542
|
bh = Bihash.new.compare_by_identity
|
|
327
543
|
key1, key2 = 'key', 'value'
|
|
328
544
|
bh[key1] = key2
|
|
329
|
-
bh['key'].must_be_nil
|
|
330
|
-
bh['value'].must_be_nil
|
|
331
|
-
bh[key1].must_equal 'value'
|
|
332
|
-
bh[key2].must_equal 'key'
|
|
545
|
+
_(bh['key']).must_be_nil
|
|
546
|
+
_(bh['value']).must_be_nil
|
|
547
|
+
_(bh[key1]).must_equal 'value'
|
|
548
|
+
_(bh[key2]).must_equal 'key'
|
|
549
|
+
end
|
|
550
|
+
|
|
551
|
+
it 'should raise FrozenError if called on a frozen bihash' do
|
|
552
|
+
_(-> { Bihash.new.freeze.compare_by_identity }).must_raise FrozenError
|
|
333
553
|
end
|
|
334
554
|
|
|
335
|
-
it 'should raise
|
|
336
|
-
|
|
555
|
+
it 'should raise if called when key duplicated (equal?) outside pair' do
|
|
556
|
+
a, b, c, d = [:a], [:b], [:c], [:d]
|
|
557
|
+
bh = Bihash[a => b, c => d]
|
|
558
|
+
d.replace([:a])
|
|
559
|
+
bh[d] = :anything
|
|
560
|
+
_(-> { bh.compare_by_identity }).must_raise RuntimeError
|
|
337
561
|
end
|
|
338
562
|
end
|
|
339
563
|
|
|
340
564
|
describe '#compare_by_identity?' do
|
|
341
565
|
it 'should indicate whether bihash is comparing by identity' do
|
|
342
|
-
Bihash.new.compare_by_identity.compare_by_identity
|
|
343
|
-
Bihash.new.compare_by_identity
|
|
566
|
+
_(Bihash.new.compare_by_identity.compare_by_identity?).must_equal true
|
|
567
|
+
_(Bihash.new.compare_by_identity?).must_equal false
|
|
568
|
+
end
|
|
569
|
+
end
|
|
570
|
+
|
|
571
|
+
describe '#deconstruct_keys' do
|
|
572
|
+
it 'should enable pattern matching in the forward and reverse direction' do
|
|
573
|
+
bh = Bihash[left: :right]
|
|
574
|
+
bh in {left:}
|
|
575
|
+
_(left).must_equal :right
|
|
576
|
+
bh in {right:}
|
|
577
|
+
_(right).must_equal :left
|
|
344
578
|
end
|
|
345
579
|
end
|
|
346
580
|
|
|
347
581
|
describe '#default' do
|
|
348
582
|
it 'should not accept more than one argument' do
|
|
349
|
-
-> { Bihash.new.default(1,2) }.must_raise ArgumentError
|
|
583
|
+
_(-> { Bihash.new.default(1,2) }).must_raise ArgumentError
|
|
350
584
|
end
|
|
351
585
|
|
|
352
586
|
describe 'when there is not a default proc' do
|
|
353
587
|
it 'should return the default' do
|
|
354
588
|
bh1 = Bihash[:key => 'value']
|
|
355
|
-
bh1.default.must_be_nil
|
|
356
|
-
bh1.default(:not_a_key).must_be_nil
|
|
357
|
-
bh1.default(:key).must_be_nil
|
|
589
|
+
_(bh1.default).must_be_nil
|
|
590
|
+
_(bh1.default(:not_a_key)).must_be_nil
|
|
591
|
+
_(bh1.default(:key)).must_be_nil
|
|
358
592
|
|
|
359
593
|
bh2 = Bihash.new(404)
|
|
360
594
|
bh2[:key] = 'value'
|
|
361
|
-
bh2.default.must_equal 404
|
|
362
|
-
bh2.default(:not_a_key).must_equal 404
|
|
363
|
-
bh2.default(:key).must_equal 404
|
|
595
|
+
_(bh2.default).must_equal 404
|
|
596
|
+
_(bh2.default(:not_a_key)).must_equal 404
|
|
597
|
+
_(bh2.default(:key)).must_equal 404
|
|
364
598
|
end
|
|
365
599
|
end
|
|
366
600
|
|
|
367
601
|
describe 'when there is a default proc' do
|
|
368
602
|
it 'should return the default if called with no argument' do
|
|
369
|
-
Bihash.new { 'proc called' }.default.must_be_nil
|
|
603
|
+
_(Bihash.new { 'proc called' }.default).must_be_nil
|
|
370
604
|
end
|
|
371
605
|
|
|
372
606
|
it 'should call the default proc when called with an argument' do
|
|
373
607
|
bh = Bihash.new { |bihash, key| bihash[key] = key.to_s }
|
|
374
608
|
bh[:key] = 'value'
|
|
375
609
|
|
|
376
|
-
bh.default(:key).must_equal 'key'
|
|
377
|
-
bh[:key].must_equal 'key'
|
|
610
|
+
_(bh.default(:key)).must_equal 'key'
|
|
611
|
+
_(bh[:key]).must_equal 'key'
|
|
378
612
|
|
|
379
|
-
bh.default(404).must_equal '404'
|
|
380
|
-
bh[404].must_equal '404'
|
|
613
|
+
_(bh.default(404)).must_equal '404'
|
|
614
|
+
_(bh[404]).must_equal '404'
|
|
381
615
|
end
|
|
382
616
|
end
|
|
383
617
|
end
|
|
@@ -385,13 +619,13 @@ describe Bihash do
|
|
|
385
619
|
describe '#default=' do
|
|
386
620
|
it 'should set the default object' do
|
|
387
621
|
bh = Bihash.new { 'proc called' }
|
|
388
|
-
bh[:not_a_key].must_equal 'proc called'
|
|
389
|
-
(bh.default = 404).must_equal 404
|
|
390
|
-
bh[:not_a_key].must_equal 404
|
|
622
|
+
_(bh[:not_a_key]).must_equal 'proc called'
|
|
623
|
+
_(bh.default = 404).must_equal 404
|
|
624
|
+
_(bh[:not_a_key]).must_equal 404
|
|
391
625
|
end
|
|
392
626
|
|
|
393
|
-
it 'should raise
|
|
394
|
-
-> { Bihash.new.freeze.default = 404 }.must_raise
|
|
627
|
+
it 'should raise FrozenError if called on a frozen bihash' do
|
|
628
|
+
_(-> { Bihash.new.freeze.default = 404 }).must_raise FrozenError
|
|
395
629
|
end
|
|
396
630
|
end
|
|
397
631
|
|
|
@@ -401,68 +635,68 @@ describe Bihash do
|
|
|
401
635
|
prc = bh.default_proc
|
|
402
636
|
array = []
|
|
403
637
|
prc.call(array, 2)
|
|
404
|
-
array.must_equal [nil, nil, 2]
|
|
638
|
+
_(array).must_equal [nil, nil, 2]
|
|
405
639
|
end
|
|
406
640
|
|
|
407
641
|
it 'should return nil if there is no default proc' do
|
|
408
|
-
Bihash.new.default_proc.must_be_nil
|
|
409
|
-
Bihash.new(404).default_proc.must_be_nil
|
|
642
|
+
_(Bihash.new.default_proc).must_be_nil
|
|
643
|
+
_(Bihash.new(404).default_proc).must_be_nil
|
|
410
644
|
end
|
|
411
645
|
end
|
|
412
646
|
|
|
413
647
|
describe '#default_proc=' do
|
|
414
648
|
it 'should set the default proc' do
|
|
415
649
|
bh = Bihash.new(:default_object)
|
|
416
|
-
bh[:not_a_key].must_equal :default_object
|
|
417
|
-
(bh.default_proc = ->(bihash, key) { '404' }).must_be_instance_of Proc
|
|
418
|
-
bh[:not_a_key].must_equal '404'
|
|
650
|
+
_(bh[:not_a_key]).must_equal :default_object
|
|
651
|
+
_(bh.default_proc = ->(bihash, key) { '404' }).must_be_instance_of Proc
|
|
652
|
+
_(bh[:not_a_key]).must_equal '404'
|
|
419
653
|
end
|
|
420
654
|
|
|
421
655
|
it 'should set the default value to nil if argument is nil' do
|
|
422
656
|
bh = Bihash.new(:default_object)
|
|
423
|
-
bh[:not_a_key].must_equal :default_object
|
|
424
|
-
(bh.default_proc = nil).must_be_nil
|
|
425
|
-
bh[:not_a_key].must_be_nil
|
|
657
|
+
_(bh[:not_a_key]).must_equal :default_object
|
|
658
|
+
_(bh.default_proc = nil).must_be_nil
|
|
659
|
+
_(bh[:not_a_key]).must_be_nil
|
|
426
660
|
end
|
|
427
661
|
|
|
428
662
|
it 'should raise TypeError if not given a non-proc (except nil)' do
|
|
429
|
-
-> { Bihash.new.default_proc = :not_a_proc }.must_raise TypeError
|
|
663
|
+
_(-> { Bihash.new.default_proc = :not_a_proc }).must_raise TypeError
|
|
430
664
|
end
|
|
431
665
|
|
|
432
666
|
it 'should raise TypeError given a lambda without 2 args' do
|
|
433
|
-
-> { Bihash.new.default_proc = -> { '404' } }.must_raise TypeError
|
|
667
|
+
_(-> { Bihash.new.default_proc = -> { '404' } }).must_raise TypeError
|
|
434
668
|
end
|
|
435
669
|
|
|
436
|
-
it 'should raise
|
|
437
|
-
-> { Bihash[].freeze.default_proc = proc { '' } }.must_raise
|
|
670
|
+
it 'should raise FrozenError if called on a frozen bihash' do
|
|
671
|
+
_(-> { Bihash[].freeze.default_proc = proc { '' } }).must_raise FrozenError
|
|
438
672
|
end
|
|
439
673
|
end
|
|
440
674
|
|
|
441
675
|
describe '#delete' do
|
|
442
676
|
it 'should return the other key if the given key is found' do
|
|
443
|
-
Bihash[:key => 'value'].delete(:key).must_equal 'value'
|
|
444
|
-
Bihash[:key => 'value'].delete('value').must_equal :key
|
|
677
|
+
_(Bihash[:key => 'value'].delete(:key)).must_equal 'value'
|
|
678
|
+
_(Bihash[:key => 'value'].delete('value')).must_equal :key
|
|
445
679
|
end
|
|
446
680
|
|
|
447
681
|
it 'should remove both keys' do
|
|
448
682
|
bh1 = Bihash[:key => 'value']
|
|
449
683
|
bh1.delete(:key)
|
|
450
|
-
bh1.wont_include :key
|
|
451
|
-
bh1.wont_include 'value'
|
|
684
|
+
_(bh1).wont_include :key
|
|
685
|
+
_(bh1).wont_include 'value'
|
|
452
686
|
|
|
453
687
|
bh2 = Bihash[:key => 'value']
|
|
454
688
|
bh2.delete('value')
|
|
455
|
-
bh2.wont_include :key
|
|
456
|
-
bh2.wont_include 'value'
|
|
689
|
+
_(bh2).wont_include :key
|
|
690
|
+
_(bh2).wont_include 'value'
|
|
457
691
|
end
|
|
458
692
|
|
|
459
693
|
it 'should call the block (if given) when the key is not found' do
|
|
460
694
|
out = Bihash[:key => 'value'].delete(404) { |key| "#{key} not found" }
|
|
461
|
-
out.must_equal '404 not found'
|
|
695
|
+
_(out).must_equal '404 not found'
|
|
462
696
|
end
|
|
463
697
|
|
|
464
|
-
it 'should raise
|
|
465
|
-
-> { Bihash.new.freeze.delete(:key) }.must_raise
|
|
698
|
+
it 'should raise FrozenError if called on a frozen bihash' do
|
|
699
|
+
_(-> { Bihash.new.freeze.delete(:key) }).must_raise FrozenError
|
|
466
700
|
end
|
|
467
701
|
end
|
|
468
702
|
|
|
@@ -470,41 +704,64 @@ describe Bihash do
|
|
|
470
704
|
it 'should delete any pairs for which the block evaluates to true' do
|
|
471
705
|
bh = Bihash[1 => :one, 2 => :two, 3 => :three, 4 => :four]
|
|
472
706
|
bh_id = bh.object_id
|
|
473
|
-
bh.delete_if { |key1, key2| key1.even? }.object_id.must_equal bh_id
|
|
474
|
-
bh.must_equal Bihash[1 => :one, 3 => :three]
|
|
707
|
+
_(bh.delete_if { |key1, key2| key1.even? }.object_id).must_equal bh_id
|
|
708
|
+
_(bh).must_equal Bihash[1 => :one, 3 => :three]
|
|
475
709
|
end
|
|
476
710
|
|
|
477
|
-
it 'should raise
|
|
478
|
-
-> { Bihash.new.freeze.delete_if { false } }.must_raise
|
|
711
|
+
it 'should raise FrozenError if called on a frozen bihash with a block' do
|
|
712
|
+
_(-> { Bihash.new.freeze.delete_if { false } }).must_raise FrozenError
|
|
479
713
|
end
|
|
480
714
|
|
|
481
715
|
it 'should return an enumerator if not given a block' do
|
|
482
716
|
enum = Bihash[1 => :one, 2 => :two, 3 => :three, 4 => :four].delete_if
|
|
483
|
-
enum.must_be_instance_of Enumerator
|
|
484
|
-
enum.
|
|
717
|
+
_(enum).must_be_instance_of Enumerator
|
|
718
|
+
_(enum.size).must_equal 4
|
|
719
|
+
_(enum.each { |k1, k2| k1.even? }).must_equal Bihash[1 => :one, 3 => :three]
|
|
485
720
|
end
|
|
486
721
|
end
|
|
487
722
|
|
|
488
723
|
describe '#dig' do
|
|
489
724
|
it 'should traverse nested bihashes' do
|
|
490
725
|
bh = Bihash[foo: Bihash[bar: Bihash[baz: 4]]]
|
|
491
|
-
bh.dig(:foo, :bar, :baz).must_equal 4
|
|
492
|
-
bh.dig(:foo, :bar, 4).must_equal :baz
|
|
726
|
+
_(bh.dig(:foo, :bar, :baz)).must_equal 4
|
|
727
|
+
_(bh.dig(:foo, :bar, 4)).must_equal :baz
|
|
493
728
|
end
|
|
494
729
|
|
|
495
730
|
it 'should traverse nested hashes' do
|
|
496
731
|
bh = Bihash[foo: {bar: {baz: 4}}]
|
|
497
|
-
bh.dig(:foo, :bar, :baz).must_equal 4
|
|
732
|
+
_(bh.dig(:foo, :bar, :baz)).must_equal 4
|
|
498
733
|
end
|
|
499
734
|
|
|
500
735
|
it 'should traverse nested arrays' do
|
|
501
736
|
bh = Bihash[foo: [[4]]]
|
|
502
|
-
bh.dig(:foo, 0, 0).must_equal 4
|
|
737
|
+
_(bh.dig(:foo, 0, 0)).must_equal 4
|
|
503
738
|
end
|
|
504
739
|
|
|
505
740
|
it 'should return nil if any intermediate step is nil' do
|
|
506
741
|
bh = Bihash[foo: Bihash[bar: Bihash[baz: 4]]]
|
|
507
|
-
bh.dig(:foo, :bur, :boz).must_be_nil
|
|
742
|
+
_(bh.dig(:foo, :bur, :boz)).must_be_nil
|
|
743
|
+
end
|
|
744
|
+
|
|
745
|
+
describe 'when a key is not found' do
|
|
746
|
+
it 'should use the default value if present' do
|
|
747
|
+
bh = Bihash.new(404)
|
|
748
|
+
_(bh.dig(:not_a_key)).must_equal 404
|
|
749
|
+
end
|
|
750
|
+
|
|
751
|
+
it 'should use the default proc if present' do
|
|
752
|
+
bh = Bihash.new { "#{_2} not found" }
|
|
753
|
+
_(bh.dig(:not_a_key)).must_equal "not_a_key not found"
|
|
754
|
+
end
|
|
755
|
+
|
|
756
|
+
it 'should early return nil if the default is nil' do
|
|
757
|
+
bh = Bihash.new(nil)
|
|
758
|
+
_(bh.dig(:not_a_key, :dont_try_me)).must_be_nil
|
|
759
|
+
end
|
|
760
|
+
|
|
761
|
+
it 'should continue to dig on the default if it is not nil' do
|
|
762
|
+
bh = Bihash.new(Bihash[do_try_me: "it worked!"])
|
|
763
|
+
_(bh.dig(:not_a_key, :do_try_me)).must_equal "it worked!"
|
|
764
|
+
end
|
|
508
765
|
end
|
|
509
766
|
end
|
|
510
767
|
|
|
@@ -513,7 +770,30 @@ describe Bihash do
|
|
|
513
770
|
bh = Bihash[1 => :one]
|
|
514
771
|
dup = bh.dup
|
|
515
772
|
dup[2] = :two
|
|
516
|
-
bh[2].must_be_nil
|
|
773
|
+
_(bh[2]).must_be_nil
|
|
774
|
+
end
|
|
775
|
+
|
|
776
|
+
it 'should copy the default value' do
|
|
777
|
+
bh = Bihash.new(404)
|
|
778
|
+
dup = bh.dup
|
|
779
|
+
_(dup.default).must_equal 404
|
|
780
|
+
end
|
|
781
|
+
|
|
782
|
+
it 'should copy the default proc' do
|
|
783
|
+
bh = Bihash.new { |_,k| k.to_s }
|
|
784
|
+
dup = bh.dup
|
|
785
|
+
_(dup.default(:not_a_key)).must_equal 'not_a_key'
|
|
786
|
+
end
|
|
787
|
+
|
|
788
|
+
it 'should copy compare_by_identity' do
|
|
789
|
+
bh = Bihash[]
|
|
790
|
+
_(bh.dup.compare_by_identity?).must_equal false
|
|
791
|
+
bh.compare_by_identity
|
|
792
|
+
_(bh.dup.compare_by_identity?).must_equal true
|
|
793
|
+
end
|
|
794
|
+
|
|
795
|
+
it 'should not copy the frozen state' do
|
|
796
|
+
_(Bihash.new.freeze.dup.frozen?).must_equal false
|
|
517
797
|
end
|
|
518
798
|
end
|
|
519
799
|
|
|
@@ -521,120 +801,147 @@ describe Bihash do
|
|
|
521
801
|
it 'should iterate over each pair in the bihash' do
|
|
522
802
|
array = []
|
|
523
803
|
Bihash[:k1 => 'v1', :k2 => 'v2'].each { |pair| array << pair }
|
|
524
|
-
array.must_equal [[:k1, 'v1'], [:k2, 'v2']]
|
|
804
|
+
_(array).must_equal [[:k1, 'v1'], [:k2, 'v2']]
|
|
525
805
|
end
|
|
526
806
|
|
|
527
807
|
it 'should return the bihash if given a block' do
|
|
528
808
|
bh = Bihash.new
|
|
529
|
-
bh.each { |p| }.must_be_instance_of Bihash
|
|
530
|
-
bh.each { |p| }.object_id.must_equal bh.object_id
|
|
809
|
+
_(bh.each { |p| }).must_be_instance_of Bihash
|
|
810
|
+
_(bh.each { |p| }.object_id).must_equal bh.object_id
|
|
531
811
|
end
|
|
532
812
|
|
|
533
813
|
it 'should return an enumerator if not given a block' do
|
|
534
814
|
enum = Bihash[:k1 => 'v1', :k2 => 'v2'].each
|
|
535
|
-
enum.must_be_instance_of Enumerator
|
|
536
|
-
enum.
|
|
815
|
+
_(enum).must_be_instance_of Enumerator
|
|
816
|
+
_(enum.size).must_equal 2
|
|
817
|
+
_(enum.each { |pair| pair }).must_equal Bihash[:k1 => 'v1', :k2 => 'v2']
|
|
537
818
|
end
|
|
538
819
|
|
|
539
820
|
it 'should be aliased to #each_pair' do
|
|
540
821
|
bh = Bihash.new
|
|
541
|
-
bh.method(:each_pair).must_equal bh.method(:each)
|
|
822
|
+
_(bh.method(:each_pair)).must_equal bh.method(:each)
|
|
542
823
|
end
|
|
543
824
|
end
|
|
544
825
|
|
|
545
826
|
describe '#empty?' do
|
|
546
827
|
it 'should indicate if the bihash is empty' do
|
|
547
|
-
Bihash.new.empty
|
|
548
|
-
Bihash[:key => 'value'].empty
|
|
828
|
+
_(Bihash.new.empty?).must_equal true
|
|
829
|
+
_(Bihash[:key => 'value'].empty?).must_equal false
|
|
830
|
+
end
|
|
831
|
+
end
|
|
832
|
+
|
|
833
|
+
describe '#except' do
|
|
834
|
+
it 'should return a new bihash without the pairs that are in the args' do
|
|
835
|
+
bh = Bihash[1 => :one, 2 => :two, 3 => :three]
|
|
836
|
+
_(bh.except(1, :two, "nope")).must_equal Bihash[3 => :three]
|
|
837
|
+
_(bh).must_equal Bihash[1 => :one, 2 => :two, 3 => :three]
|
|
838
|
+
end
|
|
839
|
+
|
|
840
|
+
it 'should return a new bihash without defaults copied' do
|
|
841
|
+
bh_default = Bihash.new(404)
|
|
842
|
+
_(bh_default.except.default).must_be_nil
|
|
843
|
+
bh_default_proc = Bihash.new { 404 }
|
|
844
|
+
_(bh_default_proc.except.default_proc).must_be_nil
|
|
845
|
+
end
|
|
846
|
+
|
|
847
|
+
it 'should return a new bihash with compare_by_identity copied' do
|
|
848
|
+
bh = Bihash[]
|
|
849
|
+
_(bh.except.compare_by_identity?).must_equal false
|
|
850
|
+
bh.compare_by_identity
|
|
851
|
+
_(bh.except.compare_by_identity?).must_equal true
|
|
549
852
|
end
|
|
550
853
|
end
|
|
551
854
|
|
|
552
855
|
describe '#fetch' do
|
|
553
856
|
it 'should return the other pair' do
|
|
554
857
|
bh = Bihash[:key => 'value']
|
|
555
|
-
bh.fetch(:key).must_equal 'value'
|
|
556
|
-
bh.fetch('value').must_equal :key
|
|
858
|
+
_(bh.fetch(:key)).must_equal 'value'
|
|
859
|
+
_(bh.fetch('value')).must_equal :key
|
|
557
860
|
end
|
|
558
861
|
|
|
559
862
|
it 'should return falsey values correctly' do
|
|
560
863
|
bh1 = Bihash[nil => false]
|
|
561
|
-
bh1.fetch(nil).must_equal false
|
|
562
|
-
bh1.fetch(false).must_be_nil
|
|
864
|
+
_(bh1.fetch(nil)).must_equal false
|
|
865
|
+
_(bh1.fetch(false)).must_be_nil
|
|
563
866
|
|
|
564
867
|
bh2 = Bihash[false => nil]
|
|
565
|
-
bh2.fetch(false).must_be_nil
|
|
566
|
-
bh2.fetch(nil).must_equal false
|
|
868
|
+
_(bh2.fetch(false)).must_be_nil
|
|
869
|
+
_(bh2.fetch(nil)).must_equal false
|
|
567
870
|
end
|
|
568
871
|
|
|
569
872
|
describe 'when the key is not found' do
|
|
570
873
|
it 'should raise KeyError when not supplied any default' do
|
|
571
|
-
-> { Bihash[].fetch(:not_a_key) }.must_raise KeyError
|
|
874
|
+
_(-> { Bihash[].fetch(:not_a_key) }).must_raise KeyError
|
|
572
875
|
end
|
|
573
876
|
|
|
574
877
|
it 'should return the second arg when supplied with one' do
|
|
575
|
-
Bihash[].fetch(:not_a_key, :second_arg).must_equal :second_arg
|
|
878
|
+
_(Bihash[].fetch(:not_a_key, :second_arg)).must_equal :second_arg
|
|
576
879
|
end
|
|
577
880
|
|
|
578
881
|
it 'should call the block if supplied with one' do
|
|
579
|
-
Bihash[].fetch(404) { |k| "#{k} not found" }.must_equal '404 not found'
|
|
882
|
+
_(Bihash[].fetch(404) { |k| "#{k} not found" }).must_equal '404 not found'
|
|
580
883
|
end
|
|
581
884
|
end
|
|
582
885
|
end
|
|
583
886
|
|
|
584
887
|
describe '#fetch_values' do
|
|
585
888
|
it 'should return an array of values corresponding to the given keys' do
|
|
586
|
-
Bihash[1 => :one, 2 => :two].fetch_values(1, 2).must_equal [:one, :two]
|
|
587
|
-
Bihash[1 => :one, 2 => :two].fetch_values(:one, :two).must_equal [1, 2]
|
|
588
|
-
Bihash[1 => :one, 2 => :two].fetch_values(1, :two).must_equal [:one, 2]
|
|
589
|
-
end
|
|
590
|
-
|
|
591
|
-
it 'should raise a KeyError if any key is not found' do
|
|
592
|
-
-> { Bihash.new.fetch_values(404) }.must_raise KeyError
|
|
889
|
+
_(Bihash[1 => :one, 2 => :two].fetch_values(1, 2)).must_equal [:one, :two]
|
|
890
|
+
_(Bihash[1 => :one, 2 => :two].fetch_values(:one, :two)).must_equal [1, 2]
|
|
891
|
+
_(Bihash[1 => :one, 2 => :two].fetch_values(1, :two)).must_equal [:one, 2]
|
|
593
892
|
end
|
|
594
893
|
|
|
595
894
|
it 'should not duplicate entries if a key equals its value' do
|
|
596
|
-
Bihash[:key => :key].fetch_values(:key).must_equal [:key]
|
|
895
|
+
_(Bihash[:key => :key].fetch_values(:key)).must_equal [:key]
|
|
597
896
|
end
|
|
598
897
|
|
|
599
898
|
it 'should return an empty array with no args' do
|
|
600
|
-
Bihash[:key => 'value'].fetch_values.must_equal []
|
|
899
|
+
_(Bihash[:key => 'value'].fetch_values).must_equal []
|
|
900
|
+
end
|
|
901
|
+
|
|
902
|
+
it 'should raise a KeyError if any key is not found without a block' do
|
|
903
|
+
_(-> { Bihash.new.fetch_values(404) }).must_raise KeyError
|
|
904
|
+
end
|
|
905
|
+
|
|
906
|
+
it 'should yield missing keys to the block if one is given' do
|
|
907
|
+
_(Bihash[1 => :one, 2 => :two].fetch_values(1, :two, 'three') { |k| "#{k} is missing"}).must_equal [:one, 2, 'three is missing']
|
|
601
908
|
end
|
|
602
909
|
end
|
|
603
910
|
|
|
604
911
|
describe '#flatten' do
|
|
605
912
|
it 'should extract the pairs into an array' do
|
|
606
|
-
Bihash[:k1 => 'v1', :k2 => 'v2'].flatten.must_equal [:k1, 'v1', :k2, 'v2']
|
|
913
|
+
_(Bihash[:k1 => 'v1', :k2 => 'v2'].flatten).must_equal [:k1, 'v1', :k2, 'v2']
|
|
607
914
|
end
|
|
608
915
|
|
|
609
916
|
it 'should not flatten array keys if no argument is given' do
|
|
610
|
-
Bihash[:key => ['v1', 'v2']].flatten.must_equal [:key, ['v1', 'v2']]
|
|
917
|
+
_(Bihash[:key => ['v1', 'v2']].flatten).must_equal [:key, ['v1', 'v2']]
|
|
611
918
|
end
|
|
612
919
|
|
|
613
920
|
it 'should flatten to the level given as an argument' do
|
|
614
|
-
Bihash[:key => ['v1', 'v2']].flatten(2).must_equal [:key, 'v1', 'v2']
|
|
921
|
+
_(Bihash[:key => ['v1', 'v2']].flatten(2)).must_equal [:key, 'v1', 'v2']
|
|
615
922
|
end
|
|
616
923
|
end
|
|
617
924
|
|
|
618
925
|
describe '#hash' do
|
|
619
926
|
it 'should return the same hash code if two bihashes have the same pairs' do
|
|
620
927
|
bh1, bh2 = Bihash[:k1 => 1, :k2 => 2], Bihash[2 => :k2, 1 => :k1]
|
|
621
|
-
bh1.hash.must_equal bh2.hash
|
|
928
|
+
_(bh1.hash).must_equal bh2.hash
|
|
622
929
|
end
|
|
623
930
|
end
|
|
624
931
|
|
|
625
932
|
describe '#include?' do
|
|
626
933
|
it 'should indicate if the bihash contains the argument' do
|
|
627
934
|
bh = Bihash[:key => 'value']
|
|
628
|
-
bh.include?(:key).must_equal true
|
|
629
|
-
bh.include?('value').must_equal true
|
|
630
|
-
bh.include?(:not_a_key).must_equal false
|
|
935
|
+
_(bh.include?(:key)).must_equal true
|
|
936
|
+
_(bh.include?('value')).must_equal true
|
|
937
|
+
_(bh.include?(:not_a_key)).must_equal false
|
|
631
938
|
end
|
|
632
939
|
|
|
633
940
|
it 'should be aliased to #has_key?, #key?, and #member?' do
|
|
634
941
|
bh = Bihash.new
|
|
635
|
-
bh.method(:has_key?).must_equal bh.method(:include?)
|
|
636
|
-
bh.method(:key?).must_equal bh.method(:include?)
|
|
637
|
-
bh.method(:member?).must_equal bh.method(:include?)
|
|
942
|
+
_(bh.method(:has_key?)).must_equal bh.method(:include?)
|
|
943
|
+
_(bh.method(:key?)).must_equal bh.method(:include?)
|
|
944
|
+
_(bh.method(:member?)).must_equal bh.method(:include?)
|
|
638
945
|
end
|
|
639
946
|
end
|
|
640
947
|
|
|
@@ -642,39 +949,74 @@ describe Bihash do
|
|
|
642
949
|
it 'should retain any pairs for which the block evaluates to true' do
|
|
643
950
|
bh = Bihash[1 => :one, 2 => :two, 3 => :three, 4 => :four]
|
|
644
951
|
bh_id = bh.object_id
|
|
645
|
-
bh.keep_if { |key1, key2| key1.even? }.object_id.must_equal bh_id
|
|
646
|
-
bh.must_equal Bihash[2 => :two, 4 => :four]
|
|
952
|
+
_(bh.keep_if { |key1, key2| key1.even? }.object_id).must_equal bh_id
|
|
953
|
+
_(bh).must_equal Bihash[2 => :two, 4 => :four]
|
|
647
954
|
end
|
|
648
955
|
|
|
649
|
-
it 'should raise
|
|
650
|
-
-> { Bihash.new.freeze.keep_if { true } }.must_raise
|
|
956
|
+
it 'should raise FrozenError if called on a frozen bihash with a block' do
|
|
957
|
+
_(-> { Bihash.new.freeze.keep_if { true } }).must_raise FrozenError
|
|
651
958
|
end
|
|
652
959
|
|
|
653
960
|
it 'should return an enumerator if not given a block' do
|
|
654
961
|
enum = Bihash[1 => :one, 2 => :two, 3 => :three, 4 => :four].keep_if
|
|
655
|
-
enum.must_be_instance_of Enumerator
|
|
656
|
-
enum.
|
|
962
|
+
_(enum).must_be_instance_of Enumerator
|
|
963
|
+
_(enum.size).must_equal 4
|
|
964
|
+
_(enum.each { |k1, k2| k1.even? }).must_equal Bihash[2 => :two, 4 => :four]
|
|
657
965
|
end
|
|
658
966
|
end
|
|
659
967
|
|
|
660
968
|
describe '#length' do
|
|
661
969
|
it 'should return the number of pairs in the bihash' do
|
|
662
|
-
Bihash[1 => :one, 2 => :two].length.must_equal 2
|
|
970
|
+
_(Bihash[1 => :one, 2 => :two].length).must_equal 2
|
|
663
971
|
end
|
|
664
972
|
end
|
|
665
973
|
|
|
666
974
|
describe '#merge' do
|
|
667
|
-
it 'should merge bihashes, assigning each arg pair to a copy of
|
|
975
|
+
it 'should merge bihashes, assigning each arg pair to a copy of receiver' do
|
|
668
976
|
receiver = Bihash[:chips => :salsa, :milk => :cookies, :fish => :rice]
|
|
669
977
|
original_receiver = receiver.dup
|
|
670
978
|
argument = Bihash[:fish => :chips, :soup => :salad]
|
|
671
979
|
return_value = Bihash[:milk => :cookies, :fish => :chips, :soup => :salad]
|
|
672
|
-
receiver.merge(argument).must_equal return_value
|
|
673
|
-
receiver.must_equal original_receiver
|
|
980
|
+
_(receiver.merge(argument)).must_equal return_value
|
|
981
|
+
_(receiver).must_equal original_receiver
|
|
674
982
|
end
|
|
675
983
|
|
|
676
|
-
it 'should
|
|
677
|
-
|
|
984
|
+
it 'should accept multiple bihashes' do
|
|
985
|
+
receiver = Bihash[receiver: true]
|
|
986
|
+
original_receiver = receiver.dup
|
|
987
|
+
arg1 = Bihash[one: 1]
|
|
988
|
+
arg2 = Bihash[two: 2]
|
|
989
|
+
return_value = Bihash[receiver: true, one: 1, two: 2]
|
|
990
|
+
_(receiver.merge(arg1, arg2)).must_equal return_value
|
|
991
|
+
_(receiver).must_equal original_receiver
|
|
992
|
+
end
|
|
993
|
+
|
|
994
|
+
it 'should merge later bihashes over earlier ones' do
|
|
995
|
+
receiver = Bihash[a: 1]
|
|
996
|
+
original_receiver = receiver.dup
|
|
997
|
+
arg1 = Bihash[a: 2]
|
|
998
|
+
arg2 = Bihash[a: 3]
|
|
999
|
+
return_value = Bihash[a: 3]
|
|
1000
|
+
_(receiver.merge(arg1, arg2)).must_equal return_value
|
|
1001
|
+
_(receiver).must_equal original_receiver
|
|
1002
|
+
end
|
|
1003
|
+
|
|
1004
|
+
it 'should return a new bihash with defaults copied' do
|
|
1005
|
+
bh_default = Bihash.new(404)
|
|
1006
|
+
_(bh_default.merge.default).must_equal 404
|
|
1007
|
+
bh_default_proc = Bihash.new { "hello #{_2}" }
|
|
1008
|
+
_(bh_default_proc.merge.default(:world)).must_equal "hello world"
|
|
1009
|
+
end
|
|
1010
|
+
|
|
1011
|
+
it 'should return a new bihash with compare_by_identity copied' do
|
|
1012
|
+
bh = Bihash[]
|
|
1013
|
+
_(bh.merge.compare_by_identity?).must_equal false
|
|
1014
|
+
bh.compare_by_identity
|
|
1015
|
+
_(bh.merge.compare_by_identity?).must_equal true
|
|
1016
|
+
end
|
|
1017
|
+
|
|
1018
|
+
it 'should raise TypeError if any arg is not a bihash' do
|
|
1019
|
+
_(-> { Bihash.new.merge(Bihash[one: 1], Hash[two: 2]) }).must_raise TypeError
|
|
678
1020
|
end
|
|
679
1021
|
end
|
|
680
1022
|
|
|
@@ -683,21 +1025,39 @@ describe Bihash do
|
|
|
683
1025
|
receiver = Bihash[:chips => :salsa, :milk => :cookies, :fish => :rice]
|
|
684
1026
|
argument = Bihash[:fish => :chips, :soup => :salad]
|
|
685
1027
|
return_value = Bihash[:milk => :cookies, :fish => :chips, :soup => :salad]
|
|
686
|
-
receiver.merge!(argument).must_equal return_value
|
|
687
|
-
receiver.must_equal return_value
|
|
1028
|
+
_(receiver.merge!(argument)).must_equal return_value
|
|
1029
|
+
_(receiver).must_equal return_value
|
|
688
1030
|
end
|
|
689
1031
|
|
|
690
|
-
it 'should
|
|
691
|
-
|
|
1032
|
+
it 'should accept multiple bihashes' do
|
|
1033
|
+
receiver = Bihash[receiver: true]
|
|
1034
|
+
arg1 = Bihash[one: 1]
|
|
1035
|
+
arg2 = Bihash[two: 2]
|
|
1036
|
+
return_value = Bihash[receiver: true, one: 1, two: 2]
|
|
1037
|
+
_(receiver.merge!(arg1, arg2)).must_equal return_value
|
|
1038
|
+
_(receiver).must_equal return_value
|
|
692
1039
|
end
|
|
693
1040
|
|
|
694
|
-
it 'should
|
|
695
|
-
|
|
1041
|
+
it 'should merge later bihashes over earlier ones' do
|
|
1042
|
+
receiver = Bihash[a: 1]
|
|
1043
|
+
arg1 = Bihash[a: 2]
|
|
1044
|
+
arg2 = Bihash[a: 3]
|
|
1045
|
+
return_value = Bihash[a: 3]
|
|
1046
|
+
_(receiver.merge!(arg1, arg2)).must_equal return_value
|
|
1047
|
+
_(receiver).must_equal return_value
|
|
1048
|
+
end
|
|
1049
|
+
|
|
1050
|
+
it 'should raise TypeError if any arg is not a bihash' do
|
|
1051
|
+
_(-> { Bihash.new.merge!(Bihash[one: 1], Hash[two: 2]) }).must_raise TypeError
|
|
1052
|
+
end
|
|
1053
|
+
|
|
1054
|
+
it 'should raise FrozenError if called on a frozen bihash' do
|
|
1055
|
+
_(-> { Bihash.new.freeze.merge!(Bihash.new) }).must_raise FrozenError
|
|
696
1056
|
end
|
|
697
1057
|
|
|
698
1058
|
it 'should be aliased to #update' do
|
|
699
1059
|
bh = Bihash.new
|
|
700
|
-
bh.method(:update).must_equal bh.method(:merge!)
|
|
1060
|
+
_(bh.method(:update)).must_equal bh.method(:merge!)
|
|
701
1061
|
end
|
|
702
1062
|
end
|
|
703
1063
|
|
|
@@ -705,19 +1065,30 @@ describe Bihash do
|
|
|
705
1065
|
it 'should recompute all key hash values and return the bihash' do
|
|
706
1066
|
bh = Bihash[[] => :array]
|
|
707
1067
|
bh[:array] << 1
|
|
708
|
-
bh[[1]].must_be_nil
|
|
709
|
-
bh.rehash[[1]].must_equal :array
|
|
710
|
-
bh[[1]].must_equal :array
|
|
1068
|
+
_(bh[[1]]).must_be_nil
|
|
1069
|
+
_(bh.rehash[[1]]).must_equal :array
|
|
1070
|
+
_(bh[[1]]).must_equal :array
|
|
711
1071
|
end
|
|
712
1072
|
|
|
713
|
-
it 'should raise
|
|
714
|
-
-> { Bihash.new.freeze.rehash }.must_raise
|
|
1073
|
+
it 'should raise FrozenError if called on a frozen bihash' do
|
|
1074
|
+
_(-> { Bihash.new.freeze.rehash }).must_raise FrozenError
|
|
715
1075
|
end
|
|
716
1076
|
|
|
717
1077
|
it 'should raise RuntimeError if called when key duplicated outside pair' do
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
1078
|
+
a, b, c, d = [:a], [:b], [:c], [:d]
|
|
1079
|
+
bh = Bihash[a => b, c => d]
|
|
1080
|
+
d.replace([:a])
|
|
1081
|
+
_(-> { bh.rehash }).must_raise RuntimeError
|
|
1082
|
+
end
|
|
1083
|
+
|
|
1084
|
+
describe 'when #compare_by_identity is set' do
|
|
1085
|
+
it 'should not raise when there are keys that are eql? but not equal?' do
|
|
1086
|
+
bh = Bihash.new.compare_by_identity
|
|
1087
|
+
foo1, foo2 = "foo", "foo"
|
|
1088
|
+
bh[foo1] = 1
|
|
1089
|
+
bh[foo2] = "foo"
|
|
1090
|
+
bh.rehash
|
|
1091
|
+
end
|
|
721
1092
|
end
|
|
722
1093
|
end
|
|
723
1094
|
|
|
@@ -725,23 +1096,38 @@ describe Bihash do
|
|
|
725
1096
|
describe 'when some items are rejected' do
|
|
726
1097
|
it 'should return a bihash with items not rejected by the block' do
|
|
727
1098
|
bh = Bihash[1 => :one, 2 => :two, 3 => :three, 4 => :four]
|
|
728
|
-
bh.reject { |k1,k2| k1.even? }.must_equal Bihash[1 => :one, 3 => :three]
|
|
729
|
-
bh.must_equal Bihash[1 => :one, 2 => :two, 3 => :three, 4 => :four]
|
|
1099
|
+
_(bh.reject { |k1,k2| k1.even? }).must_equal Bihash[1 => :one, 3 => :three]
|
|
1100
|
+
_(bh).must_equal Bihash[1 => :one, 2 => :two, 3 => :three, 4 => :four]
|
|
730
1101
|
end
|
|
731
1102
|
end
|
|
732
1103
|
|
|
733
1104
|
describe 'when no items are rejected' do
|
|
734
1105
|
it 'should return a bihash with items not rejected by the block' do
|
|
735
1106
|
bh = Bihash[1 => :one, 3 => :three, 5 => :five, 7 => :seven]
|
|
736
|
-
bh.reject { |k1,k2| k1.even? }.must_equal bh
|
|
737
|
-
bh.must_equal bh
|
|
1107
|
+
_(bh.reject { |k1,k2| k1.even? }).must_equal bh
|
|
1108
|
+
_(bh).must_equal bh
|
|
738
1109
|
end
|
|
739
1110
|
end
|
|
740
1111
|
|
|
741
1112
|
it 'should return an enumerator if not given a block' do
|
|
742
1113
|
enum = Bihash[1 => :one, 2 => :two, 3 => :three, 4 => :four].reject
|
|
743
|
-
enum.must_be_instance_of Enumerator
|
|
744
|
-
enum.
|
|
1114
|
+
_(enum).must_be_instance_of Enumerator
|
|
1115
|
+
_(enum.size).must_equal 4
|
|
1116
|
+
_(enum.each { |k1,k2| k1.even? }).must_equal Bihash[1 => :one, 3 => :three]
|
|
1117
|
+
end
|
|
1118
|
+
|
|
1119
|
+
it 'should return a new bihash without defaults copied' do
|
|
1120
|
+
bh_default = Bihash.new(404)
|
|
1121
|
+
_(bh_default.reject { false }.default).must_be_nil
|
|
1122
|
+
bh_default_proc = Bihash.new { 404 }
|
|
1123
|
+
_(bh_default_proc.reject { false }.default_proc).must_be_nil
|
|
1124
|
+
end
|
|
1125
|
+
|
|
1126
|
+
it 'should return a new bihash with compare_by_identity copied' do
|
|
1127
|
+
bh = Bihash[]
|
|
1128
|
+
_(bh.reject { false }.compare_by_identity?).must_equal false
|
|
1129
|
+
bh.compare_by_identity
|
|
1130
|
+
_(bh.reject { false }.compare_by_identity?).must_equal true
|
|
745
1131
|
end
|
|
746
1132
|
end
|
|
747
1133
|
|
|
@@ -749,24 +1135,25 @@ describe Bihash do
|
|
|
749
1135
|
it 'should delete any pairs for which the block evaluates to true' do
|
|
750
1136
|
bh = Bihash[1 => :one, 2 => :two, 3 => :three, 4 => :four]
|
|
751
1137
|
bh_id = bh.object_id
|
|
752
|
-
bh.reject! { |key1, key2| key1.even? }.object_id.must_equal bh_id
|
|
753
|
-
bh.must_equal Bihash[1 => :one, 3 => :three]
|
|
1138
|
+
_(bh.reject! { |key1, key2| key1.even? }.object_id).must_equal bh_id
|
|
1139
|
+
_(bh).must_equal Bihash[1 => :one, 3 => :three]
|
|
754
1140
|
end
|
|
755
1141
|
|
|
756
1142
|
it 'should return nil if no changes were made to the bihash' do
|
|
757
1143
|
bh = Bihash[1 => :one, 2 => :two, 3 => :three, 4 => :four]
|
|
758
|
-
bh.reject! { |key1, key2| key1 > 5 }.must_be_nil
|
|
759
|
-
bh.must_equal Bihash[1 => :one, 2 => :two, 3 => :three, 4 => :four]
|
|
1144
|
+
_(bh.reject! { |key1, key2| key1 > 5 }).must_be_nil
|
|
1145
|
+
_(bh).must_equal Bihash[1 => :one, 2 => :two, 3 => :three, 4 => :four]
|
|
760
1146
|
end
|
|
761
1147
|
|
|
762
|
-
it 'should raise
|
|
763
|
-
-> { Bihash.new.freeze.reject! { false } }.must_raise
|
|
1148
|
+
it 'should raise FrozenError if called on a frozen bihash with a block' do
|
|
1149
|
+
_(-> { Bihash.new.freeze.reject! { false } }).must_raise FrozenError
|
|
764
1150
|
end
|
|
765
1151
|
|
|
766
1152
|
it 'should return an enumerator if not given a block' do
|
|
767
1153
|
enum = Bihash[1 => :one, 2 => :two, 3 => :three, 4 => :four].reject!
|
|
768
|
-
enum.must_be_instance_of Enumerator
|
|
769
|
-
enum.
|
|
1154
|
+
_(enum).must_be_instance_of Enumerator
|
|
1155
|
+
_(enum.size).must_equal 4
|
|
1156
|
+
_(enum.each { |k1, k2| k1.even? }).must_equal Bihash[1 => :one, 3 => :three]
|
|
770
1157
|
end
|
|
771
1158
|
end
|
|
772
1159
|
|
|
@@ -775,18 +1162,32 @@ describe Bihash do
|
|
|
775
1162
|
receiver = Bihash[]
|
|
776
1163
|
original_id = receiver.object_id
|
|
777
1164
|
arg = Bihash[:key => 'value']
|
|
778
|
-
receiver.replace(arg).must_equal Bihash[:key => 'value']
|
|
1165
|
+
_(receiver.replace(arg)).must_equal Bihash[:key => 'value']
|
|
779
1166
|
arg[:another_key] = 'another_value'
|
|
780
|
-
receiver.object_id.must_equal original_id
|
|
781
|
-
receiver.must_equal Bihash[:key => 'value']
|
|
1167
|
+
_(receiver.object_id).must_equal original_id
|
|
1168
|
+
_(receiver).must_equal Bihash[:key => 'value']
|
|
1169
|
+
end
|
|
1170
|
+
|
|
1171
|
+
it 'should copy the default value' do
|
|
1172
|
+
receiver = Bihash[]
|
|
1173
|
+
arg = Bihash.new(404)
|
|
1174
|
+
receiver.replace(arg)
|
|
1175
|
+
_(receiver.default).must_equal 404
|
|
1176
|
+
end
|
|
1177
|
+
|
|
1178
|
+
it 'should copy the default proc' do
|
|
1179
|
+
receiver = Bihash[]
|
|
1180
|
+
arg = Bihash.new { |_, key| key.to_s }
|
|
1181
|
+
receiver.replace(arg)
|
|
1182
|
+
_(receiver.default(:not_a_key)).must_equal 'not_a_key'
|
|
782
1183
|
end
|
|
783
1184
|
|
|
784
1185
|
it 'should raise TypeError if arg is not a bihash' do
|
|
785
|
-
-> { Bihash.new.replace({:key => 'value'}) }.must_raise TypeError
|
|
1186
|
+
_(-> { Bihash.new.replace({:key => 'value'}) }).must_raise TypeError
|
|
786
1187
|
end
|
|
787
1188
|
|
|
788
|
-
it 'should raise
|
|
789
|
-
-> { Bihash.new.freeze.replace(Bihash[:k, 'v']) }.must_raise
|
|
1189
|
+
it 'should raise FrozenError if called on a frozen bihash' do
|
|
1190
|
+
_(-> { Bihash.new.freeze.replace(Bihash[:k, 'v']) }).must_raise FrozenError
|
|
790
1191
|
end
|
|
791
1192
|
end
|
|
792
1193
|
|
|
@@ -794,28 +1195,43 @@ describe Bihash do
|
|
|
794
1195
|
describe 'when only some items are selected' do
|
|
795
1196
|
it 'should return a bihash with items selected by the block' do
|
|
796
1197
|
bh = Bihash[1 => :one, 2 => :two, 3 => :three, 4 => :four]
|
|
797
|
-
bh.select { |k1,k2| k1.even? }.must_equal Bihash[2 => :two, 4 => :four]
|
|
798
|
-
bh.must_equal Bihash[1 => :one, 2 => :two, 3 => :three, 4 => :four]
|
|
1198
|
+
_(bh.select { |k1,k2| k1.even? }).must_equal Bihash[2 => :two, 4 => :four]
|
|
1199
|
+
_(bh).must_equal Bihash[1 => :one, 2 => :two, 3 => :three, 4 => :four]
|
|
799
1200
|
end
|
|
800
1201
|
end
|
|
801
1202
|
|
|
802
1203
|
describe 'when all items are selected' do
|
|
803
1204
|
it 'should return a bihash with items selected by the block' do
|
|
804
1205
|
bh = Bihash[2 => :two, 4 => :four, 6 => :six, 8 => :eight]
|
|
805
|
-
bh.select { |k1,k2| k1.even? }.must_equal bh
|
|
806
|
-
bh.must_equal bh
|
|
1206
|
+
_(bh.select { |k1,k2| k1.even? }).must_equal bh
|
|
1207
|
+
_(bh).must_equal bh
|
|
807
1208
|
end
|
|
808
1209
|
end
|
|
809
1210
|
|
|
810
1211
|
it 'should return an enumerator if not given a block' do
|
|
811
1212
|
enum = Bihash[1 => :one, 2 => :two, 3 => :three, 4 => :four].select
|
|
812
|
-
enum.must_be_instance_of Enumerator
|
|
813
|
-
enum.
|
|
1213
|
+
_(enum).must_be_instance_of Enumerator
|
|
1214
|
+
_(enum.size).must_equal 4
|
|
1215
|
+
_(enum.each { |k1,k2| k1.even? }).must_equal Bihash[2 => :two, 4 => :four]
|
|
1216
|
+
end
|
|
1217
|
+
|
|
1218
|
+
it 'should return a new bihash without defaults copied' do
|
|
1219
|
+
bh_default = Bihash.new(404)
|
|
1220
|
+
_(bh_default.select { true }.default).must_be_nil
|
|
1221
|
+
bh_default_proc = Bihash.new { 404 }
|
|
1222
|
+
_(bh_default_proc.select { true }.default_proc).must_be_nil
|
|
1223
|
+
end
|
|
1224
|
+
|
|
1225
|
+
it 'should return a new bihash with compare_by_identity copied' do
|
|
1226
|
+
bh = Bihash[]
|
|
1227
|
+
_(bh.select { true }.compare_by_identity?).must_equal false
|
|
1228
|
+
bh.compare_by_identity
|
|
1229
|
+
_(bh.select { true }.compare_by_identity?).must_equal true
|
|
814
1230
|
end
|
|
815
1231
|
|
|
816
1232
|
it 'should be aliased to #filter' do
|
|
817
1233
|
bh = Bihash.new
|
|
818
|
-
bh.method(:filter).must_equal bh.method(:select)
|
|
1234
|
+
_(bh.method(:filter)).must_equal bh.method(:select)
|
|
819
1235
|
end
|
|
820
1236
|
end
|
|
821
1237
|
|
|
@@ -823,133 +1239,157 @@ describe Bihash do
|
|
|
823
1239
|
it 'should retain any pairs for which the block evaluates to true' do
|
|
824
1240
|
bh = Bihash[1 => :one, 2 => :two, 3 => :three, 4 => :four]
|
|
825
1241
|
bh_id = bh.object_id
|
|
826
|
-
bh.select! { |key1, key2| key1.even? }.object_id.must_equal bh_id
|
|
827
|
-
bh.must_equal Bihash[2 => :two, 4 => :four]
|
|
1242
|
+
_(bh.select! { |key1, key2| key1.even? }.object_id).must_equal bh_id
|
|
1243
|
+
_(bh).must_equal Bihash[2 => :two, 4 => :four]
|
|
828
1244
|
end
|
|
829
1245
|
|
|
830
1246
|
it 'should return nil if no changes were made to the bihash' do
|
|
831
1247
|
bh = Bihash[1 => :one, 2 => :two, 3 => :three, 4 => :four]
|
|
832
|
-
bh.select! { |key1, key2| key1 < 5 }.must_be_nil
|
|
833
|
-
bh.must_equal Bihash[1 => :one, 2 => :two, 3 => :three, 4 => :four]
|
|
1248
|
+
_(bh.select! { |key1, key2| key1 < 5 }).must_be_nil
|
|
1249
|
+
_(bh).must_equal Bihash[1 => :one, 2 => :two, 3 => :three, 4 => :four]
|
|
834
1250
|
end
|
|
835
1251
|
|
|
836
|
-
it 'should raise
|
|
837
|
-
-> { Bihash.new.freeze.select! { true } }.must_raise
|
|
1252
|
+
it 'should raise FrozenError if called on a frozen bihash with a block' do
|
|
1253
|
+
_(-> { Bihash.new.freeze.select! { true } }).must_raise FrozenError
|
|
838
1254
|
end
|
|
839
1255
|
|
|
840
1256
|
it 'should return an enumerator if not given a block' do
|
|
841
1257
|
enum = Bihash[1 => :one, 2 => :two, 3 => :three, 4 => :four].select!
|
|
842
|
-
enum.must_be_instance_of Enumerator
|
|
843
|
-
enum.
|
|
1258
|
+
_(enum).must_be_instance_of Enumerator
|
|
1259
|
+
_(enum.size).must_equal 4
|
|
1260
|
+
_(enum.each { |k1, k2| k1.even? }).must_equal Bihash[2 => :two, 4 => :four]
|
|
844
1261
|
end
|
|
845
1262
|
|
|
846
1263
|
it 'should be aliased to #filter!' do
|
|
847
1264
|
bh = Bihash.new
|
|
848
|
-
bh.method(:filter!).must_equal bh.method(:select!)
|
|
1265
|
+
_(bh.method(:filter!)).must_equal bh.method(:select!)
|
|
849
1266
|
end
|
|
850
1267
|
end
|
|
851
1268
|
|
|
852
1269
|
describe '#shift' do
|
|
853
1270
|
it 'should remove the oldest pair from the bihash and return it' do
|
|
854
1271
|
bh = Bihash[1 => :one, 2 => :two, 3 => :three]
|
|
855
|
-
bh.shift.must_equal [1, :one]
|
|
856
|
-
bh.must_equal Bihash[2 => :two, 3 => :three]
|
|
1272
|
+
_(bh.shift).must_equal [1, :one]
|
|
1273
|
+
_(bh).must_equal Bihash[2 => :two, 3 => :three]
|
|
857
1274
|
end
|
|
858
1275
|
|
|
859
|
-
it 'should return
|
|
860
|
-
Bihash.new.shift.must_be_nil
|
|
861
|
-
Bihash.new(404).shift.
|
|
862
|
-
Bihash.new { 'd3f4u17' }.shift.
|
|
1276
|
+
it 'should return nil if bihash is empty' do
|
|
1277
|
+
_(Bihash.new.shift).must_be_nil
|
|
1278
|
+
_(Bihash.new(404).shift).must_be_nil
|
|
1279
|
+
_(Bihash.new { 'd3f4u17' }.shift).must_be_nil
|
|
863
1280
|
end
|
|
864
1281
|
|
|
865
|
-
it 'should raise
|
|
866
|
-
-> { Bihash.new.freeze.shift }.must_raise
|
|
1282
|
+
it 'should raise FrozenError if called on a frozen bihash' do
|
|
1283
|
+
_(-> { Bihash.new.freeze.shift }).must_raise FrozenError
|
|
867
1284
|
end
|
|
868
1285
|
end
|
|
869
1286
|
|
|
870
1287
|
describe '#size' do
|
|
871
1288
|
it 'should return the number of pairs in the bihash' do
|
|
872
|
-
Bihash[1 => :one, 2 => :two].size.must_equal 2
|
|
1289
|
+
_(Bihash[1 => :one, 2 => :two].size).must_equal 2
|
|
873
1290
|
end
|
|
874
1291
|
end
|
|
875
1292
|
|
|
876
1293
|
describe '#slice' do
|
|
877
1294
|
it 'should return a new bihash with only the pairs that are in the args' do
|
|
878
1295
|
bh = Bihash[1 => :one, 2 => :two, 3 => :three]
|
|
879
|
-
bh.slice(1, :one, :two, "nope").must_equal Bihash[1 => :one, 2 => :two]
|
|
880
|
-
bh.must_equal Bihash[1 => :one, 2 => :two, 3 => :three]
|
|
1296
|
+
_(bh.slice(1, :one, :two, "nope")).must_equal Bihash[1 => :one, 2 => :two]
|
|
1297
|
+
_(bh).must_equal Bihash[1 => :one, 2 => :two, 3 => :three]
|
|
881
1298
|
end
|
|
882
1299
|
|
|
883
|
-
it 'should return a
|
|
884
|
-
|
|
885
|
-
|
|
1300
|
+
it 'should return a new bihash without defaults copied' do
|
|
1301
|
+
bh_default = Bihash.new(404)
|
|
1302
|
+
_(bh_default.slice.default).must_be_nil
|
|
1303
|
+
bh_default_proc = Bihash.new { 404 }
|
|
1304
|
+
_(bh_default_proc.slice.default_proc).must_be_nil
|
|
1305
|
+
end
|
|
1306
|
+
|
|
1307
|
+
it 'should return a new bihash with compare_by_identity copied' do
|
|
1308
|
+
bh = Bihash[]
|
|
1309
|
+
_(bh.slice.compare_by_identity?).must_equal false
|
|
1310
|
+
bh.compare_by_identity
|
|
1311
|
+
_(bh.slice.compare_by_identity?).must_equal true
|
|
886
1312
|
end
|
|
887
1313
|
end
|
|
888
1314
|
|
|
889
1315
|
describe '#to_h' do
|
|
890
|
-
it 'should return a copy of the forward hash' do
|
|
1316
|
+
it 'without a block, should return a copy of the forward hash' do
|
|
891
1317
|
bh = Bihash[:key1 => 'val1', :key2 => 'val2']
|
|
892
1318
|
h = bh.to_h
|
|
893
|
-
h.must_equal Hash[:key1 => 'val1', :key2 => 'val2']
|
|
1319
|
+
_(h).must_equal Hash[:key1 => 'val1', :key2 => 'val2']
|
|
894
1320
|
h.delete(:key1)
|
|
895
|
-
bh.must_include :key1
|
|
1321
|
+
_(bh).must_include :key1
|
|
896
1322
|
end
|
|
897
1323
|
|
|
898
|
-
it 'should
|
|
899
|
-
bh = Bihash
|
|
900
|
-
bh.
|
|
1324
|
+
it 'with a block, should transform pairs from the forward hash' do
|
|
1325
|
+
bh = Bihash[:key1 => 'val1', :key2 => 'val2']
|
|
1326
|
+
h = bh.to_h { |k,v| [k.to_s, v.to_sym] }
|
|
1327
|
+
_(h).must_equal Hash['key1' => :val1, 'key2' => :val2]
|
|
1328
|
+
_(bh).must_equal Bihash[:key1 => 'val1', :key2 => 'val2']
|
|
1329
|
+
end
|
|
1330
|
+
end
|
|
1331
|
+
|
|
1332
|
+
describe '#to_hash' do
|
|
1333
|
+
it 'should return a copy of the forward hash' do
|
|
1334
|
+
bh = Bihash[:key1 => 'val1', :key2 => 'val2']
|
|
1335
|
+
h = bh.to_hash
|
|
1336
|
+
_(h).must_equal Hash[:key1 => 'val1', :key2 => 'val2']
|
|
1337
|
+
h.delete(:key1)
|
|
1338
|
+
_(bh).must_include :key1
|
|
901
1339
|
end
|
|
902
1340
|
end
|
|
903
1341
|
|
|
904
1342
|
describe '#to_proc' do
|
|
905
1343
|
it 'should convert the bihash to a proc' do
|
|
906
|
-
Bihash[].to_proc.must_be_instance_of Proc
|
|
1344
|
+
_(Bihash[].to_proc).must_be_instance_of Proc
|
|
907
1345
|
end
|
|
908
1346
|
|
|
909
1347
|
it 'should call #[] on the bihash when the proc is called' do
|
|
910
|
-
Bihash[:key => 'value'].to_proc.call(:key).must_equal 'value'
|
|
1348
|
+
_(Bihash[:key => 'value'].to_proc.call(:key)).must_equal 'value'
|
|
911
1349
|
end
|
|
912
1350
|
end
|
|
913
1351
|
|
|
914
1352
|
describe '#to_s' do
|
|
915
1353
|
it 'should return a nice string representing the bihash' do
|
|
916
|
-
|
|
917
|
-
bh
|
|
1354
|
+
h = {:k1 => 'v1', :k2 => [:v2], :k3 => {:k4 => 'v4'}}
|
|
1355
|
+
bh = Bihash[h]
|
|
1356
|
+
keys_and_values_to_s = h.to_s.delete_prefix('{').delete_suffix('}')
|
|
1357
|
+
_(bh.to_s).must_equal "Bihash[#{keys_and_values_to_s}]"
|
|
918
1358
|
end
|
|
919
1359
|
|
|
920
1360
|
it 'should be aliased to #inspect' do
|
|
921
1361
|
bh = Bihash.new
|
|
922
|
-
bh.method(:inspect).must_equal bh.method(:to_s)
|
|
1362
|
+
_(bh.method(:inspect)).must_equal bh.method(:to_s)
|
|
923
1363
|
end
|
|
924
1364
|
end
|
|
925
1365
|
|
|
926
1366
|
describe '#values_at' do
|
|
927
1367
|
it 'should return an array of values corresponding to the given keys' do
|
|
928
|
-
Bihash[1 => :one, 2 => :two].values_at(1, 2).must_equal [:one, :two]
|
|
929
|
-
Bihash[1 => :one, 2 => :two].values_at(:one, :two).must_equal [1, 2]
|
|
930
|
-
Bihash[1 => :one, 2 => :two].values_at(1, :two).must_equal [:one, 2]
|
|
1368
|
+
_(Bihash[1 => :one, 2 => :two].values_at(1, 2)).must_equal [:one, :two]
|
|
1369
|
+
_(Bihash[1 => :one, 2 => :two].values_at(:one, :two)).must_equal [1, 2]
|
|
1370
|
+
_(Bihash[1 => :one, 2 => :two].values_at(1, :two)).must_equal [:one, 2]
|
|
931
1371
|
end
|
|
932
1372
|
|
|
933
1373
|
it 'should use the default if a given key is not found' do
|
|
934
1374
|
bh = Bihash.new(404)
|
|
935
1375
|
bh[1] = :one
|
|
936
1376
|
bh[2] = :two
|
|
937
|
-
bh.values_at(1, 2, 3).must_equal [:one, :two, 404]
|
|
938
|
-
bh.values_at(:one, :two, :three).must_equal [1, 2, 404]
|
|
1377
|
+
_(bh.values_at(1, 2, 3)).must_equal [:one, :two, 404]
|
|
1378
|
+
_(bh.values_at(:one, :two, :three)).must_equal [1, 2, 404]
|
|
939
1379
|
end
|
|
940
1380
|
|
|
941
1381
|
it 'should not duplicate entries if a key equals its value' do
|
|
942
|
-
Bihash[:key => :key].values_at(:key).must_equal [:key]
|
|
1382
|
+
_(Bihash[:key => :key].values_at(:key)).must_equal [:key]
|
|
943
1383
|
end
|
|
944
1384
|
|
|
945
1385
|
it 'should return an empty array with no args' do
|
|
946
|
-
Bihash[:key => 'value'].values_at.must_equal []
|
|
1386
|
+
_(Bihash[:key => 'value'].values_at).must_equal []
|
|
947
1387
|
end
|
|
948
1388
|
end
|
|
949
1389
|
|
|
950
1390
|
describe '#initialize' do
|
|
951
|
-
it 'should raise
|
|
952
|
-
-> { Bihash.new.freeze.send(:initialize) }.must_raise
|
|
1391
|
+
it 'should raise FrozenError if called on a frozen bihash' do
|
|
1392
|
+
_(-> { Bihash.new.freeze.send(:initialize) }).must_raise FrozenError
|
|
953
1393
|
end
|
|
954
1394
|
end
|
|
955
1395
|
end
|