jactive_support 1.0.2
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.
- data/.gitignore +4 -0
- data/.rvmrc +63 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +20 -0
- data/Rakefile +45 -0
- data/jactive_support.gemspec +24 -0
- data/lib/jactive_support.rb +6 -0
- data/lib/jactive_support/constantize.rb +19 -0
- data/lib/jactive_support/core_ext.rb +4 -0
- data/lib/jactive_support/core_ext/enum.rb +43 -0
- data/lib/jactive_support/core_ext/hash.rb +2 -0
- data/lib/jactive_support/core_ext/hash/assert_valid_params.rb +19 -0
- data/lib/jactive_support/core_ext/hash/with_keys_values.rb +9 -0
- data/lib/jactive_support/core_ext/locale.rb +28 -0
- data/lib/jactive_support/core_ext/module.rb +9 -0
- data/lib/jactive_support/core_ext/numeric.rb +7 -0
- data/lib/jactive_support/core_ext/ordering.rb +17 -0
- data/lib/jactive_support/core_ext/to_java.rb +9 -0
- data/lib/jactive_support/core_ext/to_java_date.rb +25 -0
- data/lib/jactive_support/core_ext/to_java_list.rb +11 -0
- data/lib/jactive_support/core_ext/to_java_map.rb +11 -0
- data/lib/jactive_support/java_ext.rb +4 -0
- data/lib/jactive_support/java_ext/date.rb +37 -0
- data/lib/jactive_support/java_ext/date/calculations.rb +43 -0
- data/lib/jactive_support/java_ext/date/conversions.rb +135 -0
- data/lib/jactive_support/java_ext/enum.rb +19 -0
- data/lib/jactive_support/java_ext/iterable.rb +74 -0
- data/lib/jactive_support/java_ext/iterator.rb +8 -0
- data/lib/jactive_support/java_ext/list.rb +65 -0
- data/lib/jactive_support/java_ext/list_iterator.rb +8 -0
- data/lib/jactive_support/java_ext/locale.rb +32 -0
- data/lib/jactive_support/java_ext/map.rb +6 -0
- data/lib/jactive_support/java_ext/map/constructor.rb +35 -0
- data/lib/jactive_support/java_ext/map/hash.rb +166 -0
- data/lib/jactive_support/java_ext/number.rb +91 -0
- data/lib/jactive_support/java_ext/sql_date.rb +7 -0
- data/lib/jactive_support/java_ext/sql_date/conversions.rb +33 -0
- data/lib/jactive_support/json.rb +1 -0
- data/lib/jactive_support/json/encoders/collection.rb +12 -0
- data/lib/jactive_support/json/encoders/locale.rb +6 -0
- data/lib/jactive_support/json/encoders/map.rb +55 -0
- data/lib/jactive_support/json/encoding.rb +5 -0
- data/lib/jactive_support/rescuable.rb +62 -0
- data/lib/jactive_support/version.rb +3 -0
- data/spec/constantize_spec.rb +57 -0
- data/spec/core_ext/hash_spec.rb +34 -0
- data/spec/core_ext/module_spec.rb +19 -0
- data/spec/core_ext/ordering_spec.rb +12 -0
- data/spec/enum_spec.rb +67 -0
- data/spec/java_ext/iterable/clear_spec.rb +56 -0
- data/spec/java_ext/iterable/delete_if_spec.rb +71 -0
- data/spec/java_ext/iterable/empty_spec.rb +10 -0
- data/spec/java_ext/iterable/reject_spec.rb +76 -0
- data/spec/java_ext/iterable/shared/enumeratorize.rb +12 -0
- data/spec/java_ext/iterable/shared/fixtures.rb +90 -0
- data/spec/java_ext/iterable/shift_spec.rb +160 -0
- data/spec/java_ext/list/clear_spec.rb +56 -0
- data/spec/java_ext/list/collect_spec.rb +11 -0
- data/spec/java_ext/list/last_spec.rb +87 -0
- data/spec/java_ext/list/map_spec.rb +11 -0
- data/spec/java_ext/list/push_spec.rb +44 -0
- data/spec/java_ext/list/shared/collect.rb +133 -0
- data/spec/java_ext/list/shared/fixtures.rb +34 -0
- data/spec/java_ext/map/assoc_spec.rb +43 -0
- data/spec/java_ext/map/clear_spec.rb +49 -0
- data/spec/java_ext/map/clone_spec.rb +13 -0
- data/spec/java_ext/map/compare_by_identity_spec.rb +111 -0
- data/spec/java_ext/map/constructor_spec.rb +54 -0
- data/spec/java_ext/map/delete_if_spec.rb +54 -0
- data/spec/java_ext/map/delete_spec.rb +38 -0
- data/spec/java_ext/map/each_key_spec.rb +29 -0
- data/spec/java_ext/map/each_pair_spec.rb +38 -0
- data/spec/java_ext/map/each_spec.rb +9 -0
- data/spec/java_ext/map/each_value_spec.rb +28 -0
- data/spec/java_ext/map/element_reference_spec.rb +119 -0
- data/spec/java_ext/map/element_set_spec.rb +7 -0
- data/spec/java_ext/map/empty_spec.rb +15 -0
- data/spec/java_ext/map/eql_spec.rb +19 -0
- data/spec/java_ext/map/equal_value_spec.rb +18 -0
- data/spec/java_ext/map/fetch_spec.rb +35 -0
- data/spec/java_ext/map/fixtures/classes.rb +36 -0
- data/spec/java_ext/map/flatten_spec.rb +64 -0
- data/spec/java_ext/map/has_key_spec.rb +8 -0
- data/spec/java_ext/map/has_value_spec.rb +8 -0
- data/spec/java_ext/map/hash_spec.rb +53 -0
- data/spec/java_ext/map/include_spec.rb +7 -0
- data/spec/java_ext/map/index_spec.rb +7 -0
- data/spec/java_ext/map/indexes_spec.rb +9 -0
- data/spec/java_ext/map/indices_spec.rb +9 -0
- data/spec/java_ext/map/initialize_copy_spec.rb +13 -0
- data/spec/java_ext/map/initialize_spec.rb +64 -0
- data/spec/java_ext/map/inspect_spec.rb +9 -0
- data/spec/java_ext/map/invert_spec.rb +27 -0
- data/spec/java_ext/map/keep_if_spec.rb +33 -0
- data/spec/java_ext/map/key_spec.rb +14 -0
- data/spec/java_ext/map/keys_spec.rb +39 -0
- data/spec/java_ext/map/length_spec.rb +7 -0
- data/spec/java_ext/map/member_spec.rb +7 -0
- data/spec/java_ext/map/merge_spec.rb +69 -0
- data/spec/java_ext/map/rassoc_spec.rb +39 -0
- data/spec/java_ext/map/reject_spec.rb +123 -0
- data/spec/java_ext/map/replace_spec.rb +7 -0
- data/spec/java_ext/map/select_spec.rb +98 -0
- data/spec/java_ext/map/shared/each.rb +77 -0
- data/spec/java_ext/map/shared/eql.rb +224 -0
- data/spec/java_ext/map/shared/equal.rb +94 -0
- data/spec/java_ext/map/shared/index.rb +29 -0
- data/spec/java_ext/map/shared/iteration.rb +28 -0
- data/spec/java_ext/map/shared/key.rb +43 -0
- data/spec/java_ext/map/shared/length.rb +12 -0
- data/spec/java_ext/map/shared/replace.rb +82 -0
- data/spec/java_ext/map/shared/store.rb +68 -0
- data/spec/java_ext/map/shared/to_s.rb +68 -0
- data/spec/java_ext/map/shared/update.rb +95 -0
- data/spec/java_ext/map/shared/value.rb +16 -0
- data/spec/java_ext/map/shared/values_at.rb +12 -0
- data/spec/java_ext/map/shift_spec.rb +44 -0
- data/spec/java_ext/map/size_spec.rb +7 -0
- data/spec/java_ext/map/sort_spec.rb +17 -0
- data/spec/java_ext/map/store_spec.rb +7 -0
- data/spec/java_ext/map/to_a_spec.rb +29 -0
- data/spec/java_ext/map/to_hash_spec.rb +11 -0
- data/spec/java_ext/map/to_s_spec.rb +20 -0
- data/spec/java_ext/map/try_convert_spec.rb +32 -0
- data/spec/java_ext/map/update_spec.rb +7 -0
- data/spec/java_ext/map/value_spec.rb +8 -0
- data/spec/java_ext/map/values_at_spec.rb +7 -0
- data/spec/java_ext/map/values_spec.rb +10 -0
- data/spec/locale_spec.rb +77 -0
- data/spec/shared/fixtures.rb +7 -0
- data/spec/shared/version.rb +123 -0
- data/spec/spec_helper.rb +50 -0
- metadata +332 -0
@@ -0,0 +1,224 @@
|
|
1
|
+
shared_examples_for :hash_eql do |method|
|
2
|
+
before { @method = method }
|
3
|
+
|
4
|
+
it "does not compare values when keys don't match" do
|
5
|
+
value = mock('x')
|
6
|
+
value.should_not_receive(:==)
|
7
|
+
value.should_not_receive(:eql?)
|
8
|
+
new_hash(1 => value).send(@method, new_hash(2 => value)).should be_false
|
9
|
+
end
|
10
|
+
|
11
|
+
it "returns false when the numbers of keys differ without comparing any elements" do
|
12
|
+
obj = mock('x')
|
13
|
+
h = new_hash(obj => obj)
|
14
|
+
|
15
|
+
obj.should_not_receive(:==)
|
16
|
+
obj.should_not_receive(:eql?)
|
17
|
+
|
18
|
+
new_hash.send(@method, h).should be_false
|
19
|
+
h.send(@method, new_hash).should be_false
|
20
|
+
end
|
21
|
+
|
22
|
+
it "first compares keys via hash" do
|
23
|
+
x = mock('x')
|
24
|
+
x.should_receive(:hash).any_number_of_times.and_return(0)
|
25
|
+
y = mock('y')
|
26
|
+
y.should_receive(:hash).any_number_of_times.and_return(0)
|
27
|
+
|
28
|
+
new_hash(x => 1).send(@method, new_hash(y => 1)).should be_false
|
29
|
+
end
|
30
|
+
|
31
|
+
it "does not compare keys with different hash codes via eql?" do
|
32
|
+
x = mock('x')
|
33
|
+
y = mock('y')
|
34
|
+
x.should_not_receive(:eql?)
|
35
|
+
y.should_not_receive(:eql?)
|
36
|
+
|
37
|
+
x.should_receive(:hash).any_number_of_times.and_return(0)
|
38
|
+
y.should_receive(:hash).any_number_of_times.and_return(1)
|
39
|
+
|
40
|
+
new_hash(x => 1).send(@method, new_hash(y => 1)).should be_false
|
41
|
+
end
|
42
|
+
|
43
|
+
it "computes equality for recursive hashes" do
|
44
|
+
h = new_hash
|
45
|
+
h[:a] = h
|
46
|
+
h.send(@method, h[:a]).should be_true
|
47
|
+
(h == h[:a]).should be_true
|
48
|
+
end
|
49
|
+
|
50
|
+
it "doesn't call to_hash on objects" do
|
51
|
+
mock_hash = mock("fake hash")
|
52
|
+
def mock_hash.to_hash() new_hash end
|
53
|
+
new_hash.send(@method, mock_hash).should be_false
|
54
|
+
end
|
55
|
+
|
56
|
+
ruby_bug "redmine #2448", "1.9.1" do
|
57
|
+
it "computes equality for complex recursive hashes" do
|
58
|
+
a, b = {}, {}
|
59
|
+
a.merge! :self => a, :other => b
|
60
|
+
b.merge! :self => b, :other => a
|
61
|
+
a.send(@method, b).should be_true # they both have the same structure!
|
62
|
+
|
63
|
+
c = {}
|
64
|
+
c.merge! :other => c, :self => c
|
65
|
+
c.send(@method, a).should be_true # subtle, but they both have the same structure!
|
66
|
+
a[:delta] = c[:delta] = a
|
67
|
+
c.send(@method, a).should be_false # not quite the same structure, as a[:other][:delta] = nil
|
68
|
+
c[:delta] = 42
|
69
|
+
c.send(@method, a).should be_false
|
70
|
+
a[:delta] = 42
|
71
|
+
c.send(@method, a).should be_false
|
72
|
+
b[:delta] = 42
|
73
|
+
c.send(@method, a).should be_true
|
74
|
+
end
|
75
|
+
|
76
|
+
it "computes equality for recursive hashes & arrays" do
|
77
|
+
x, y, z = [], [], []
|
78
|
+
a, b, c = {:foo => x, :bar => 42}, {:foo => y, :bar => 42}, {:foo => z, :bar => 42}
|
79
|
+
x << a
|
80
|
+
y << c
|
81
|
+
z << b
|
82
|
+
b.send(@method, c).should be_true # they clearly have the same structure!
|
83
|
+
y.send(@method, z).should be_true
|
84
|
+
a.send(@method, b).should be_true # subtle, but they both have the same structure!
|
85
|
+
x.send(@method, y).should be_true
|
86
|
+
y << x
|
87
|
+
y.send(@method, z).should be_false
|
88
|
+
z << x
|
89
|
+
y.send(@method, z).should be_true
|
90
|
+
|
91
|
+
a[:foo], a[:bar] = a[:bar], a[:foo]
|
92
|
+
a.send(@method, b).should be_false
|
93
|
+
b[:bar] = b[:foo]
|
94
|
+
b.send(@method, c).should be_false
|
95
|
+
end
|
96
|
+
end # ruby_bug
|
97
|
+
end
|
98
|
+
|
99
|
+
# All these tests are true for ==, and for eql? when Ruby >= 1.8.7
|
100
|
+
shared_examples_for :hash_eql_additional do |method|
|
101
|
+
before { @method = method }
|
102
|
+
|
103
|
+
it "compares values when keys match" do
|
104
|
+
x = mock('x')
|
105
|
+
y = mock('y')
|
106
|
+
def x.==(o) false end
|
107
|
+
def y.==(o) false end
|
108
|
+
def x.eql?(o) false end
|
109
|
+
def y.eql?(o) false end
|
110
|
+
new_hash(1 => x).send(@method, new_hash(1 => y)).should be_false
|
111
|
+
|
112
|
+
x = mock('x')
|
113
|
+
y = mock('y')
|
114
|
+
def x.==(o) true end
|
115
|
+
def y.==(o) true end
|
116
|
+
def x.eql?(o) true end
|
117
|
+
def y.eql?(o) true end
|
118
|
+
new_hash(1 => x).send(@method, new_hash(1 => y)).should be_true
|
119
|
+
end
|
120
|
+
|
121
|
+
it "compares keys with eql? semantics" do
|
122
|
+
new_hash(1.0 => "x").send(@method, new_hash(1.0 => "x")).should be_true
|
123
|
+
new_hash(1.0 => "x").send(@method, new_hash(1.0 => "x")).should be_true
|
124
|
+
new_hash(1 => "x").send(@method, new_hash(1.0 => "x")).should be_false
|
125
|
+
new_hash(1.0 => "x").send(@method, new_hash(1 => "x")).should be_false
|
126
|
+
end
|
127
|
+
|
128
|
+
it "returns true iff other Hash has the same number of keys and each key-value pair matches" do
|
129
|
+
a = new_hash(:a => 5)
|
130
|
+
b = new_hash
|
131
|
+
a.send(@method, b).should be_false
|
132
|
+
|
133
|
+
b[:a] = 5
|
134
|
+
a.send(@method, b).should be_true
|
135
|
+
|
136
|
+
c = new_hash("a" => 5)
|
137
|
+
a.send(@method, c).should be_false
|
138
|
+
end
|
139
|
+
|
140
|
+
it "does not call to_hash on hash subclasses" do
|
141
|
+
new_hash(5 => 6).send(@method, ToHashHash[5 => 6]).should be_true
|
142
|
+
end
|
143
|
+
|
144
|
+
it "ignores hash class differences" do
|
145
|
+
h = new_hash(1 => 2, 3 => 4)
|
146
|
+
MyHash[h].send(@method, h).should be_true
|
147
|
+
MyHash[h].send(@method, MyHash[h]).should be_true
|
148
|
+
h.send(@method, MyHash[h]).should be_true
|
149
|
+
end
|
150
|
+
|
151
|
+
=begin eql
|
152
|
+
# Why isn't this true of eql? too ?
|
153
|
+
it "compares keys with matching hash codes via eql?" do
|
154
|
+
# Can't use should_receive because it uses hash and eql? internally
|
155
|
+
a = Array.new(2) do
|
156
|
+
obj = mock('0')
|
157
|
+
|
158
|
+
def obj.hash()
|
159
|
+
return 0
|
160
|
+
end
|
161
|
+
# It's undefined whether the impl does a[0].eql?(a[1]) or
|
162
|
+
# a[1].eql?(a[0]) so we taint both.
|
163
|
+
def obj.equals(o)
|
164
|
+
return true if self == o
|
165
|
+
taint
|
166
|
+
o.taint
|
167
|
+
false
|
168
|
+
end
|
169
|
+
|
170
|
+
obj
|
171
|
+
end
|
172
|
+
|
173
|
+
new_hash(a[0] => 1).send(@method, new_hash(a[1] => 1)).should be_false
|
174
|
+
a[0].tainted?.should be_true
|
175
|
+
a[1].tainted?.should be_true
|
176
|
+
|
177
|
+
a = Array.new(2) do
|
178
|
+
obj = mock('0')
|
179
|
+
|
180
|
+
def obj.hash()
|
181
|
+
# It's undefined whether the impl does a[0].send(@method, a[1]) or
|
182
|
+
# a[1].send(@method, a[0]) so we taint both.
|
183
|
+
def self.equals(o) taint; o.taint; true; end
|
184
|
+
return 0
|
185
|
+
end
|
186
|
+
|
187
|
+
obj
|
188
|
+
end
|
189
|
+
|
190
|
+
new_hash(a[0] => 1).send(@method, new_hash(a[1] => 1)).should be_true
|
191
|
+
a[0].tainted?.should be_true
|
192
|
+
a[1].tainted?.should be_true
|
193
|
+
end
|
194
|
+
|
195
|
+
# The specs above all pass in 1.8.6p287 for Hash#== but not Hash#eql
|
196
|
+
# except this one, which does not pass for Hash#==.
|
197
|
+
ruby_version_is "1.8.7" do
|
198
|
+
it "compares the values in self to values in other hash" do
|
199
|
+
l_val = mock("left")
|
200
|
+
r_val = mock("right")
|
201
|
+
|
202
|
+
l_val.should_receive(:equals).with(r_val).and_return(true)
|
203
|
+
|
204
|
+
new_hash(1 => l_val).eql?(new_hash(1 => r_val)).should be_true
|
205
|
+
end
|
206
|
+
end
|
207
|
+
=end
|
208
|
+
end
|
209
|
+
|
210
|
+
shared_examples_for :hash_eql_additional_more do |method|
|
211
|
+
before { @method = method }
|
212
|
+
|
213
|
+
it "returns true if other Hash has the same number of keys and each key-value pair matches, even though the default-value are not same" do
|
214
|
+
new_hash(5).send(@method, new_hash(1)).should be_true
|
215
|
+
new_hash {|h, k| 1}.send(@method, new_hash {}).should be_true
|
216
|
+
new_hash {|h, k| 1}.send(@method, new_hash(2)).should be_true
|
217
|
+
|
218
|
+
d = new_hash {|h, k| 1}
|
219
|
+
e = new_hash {}
|
220
|
+
d[1] = 2
|
221
|
+
e[1] = 2
|
222
|
+
d.send(@method, e).should be_true
|
223
|
+
end
|
224
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
shared_examples_for :hash_equal do |method|
|
2
|
+
before { @method = method }
|
3
|
+
|
4
|
+
it "does not compare values when keys don't match" do
|
5
|
+
value = mock('x')
|
6
|
+
value.should_not_receive(:==)
|
7
|
+
value.should_not_receive(:eql?)
|
8
|
+
new_hash(1 => value).send(@method, new_hash(2 => value)).should be_false
|
9
|
+
end
|
10
|
+
|
11
|
+
it "returns false when the numbers of keys differ without comparing any elements" do
|
12
|
+
obj = mock('x')
|
13
|
+
h = new_hash(obj => obj)
|
14
|
+
|
15
|
+
obj.should_not_receive(:==)
|
16
|
+
obj.should_not_receive(:eql?)
|
17
|
+
|
18
|
+
new_hash.send(@method, h).should be_false
|
19
|
+
h.send(@method, new_hash).should be_false
|
20
|
+
end
|
21
|
+
|
22
|
+
it "first compares keys via hash" do
|
23
|
+
x = mock('x')
|
24
|
+
x.should_receive(:hash).and_return(0)
|
25
|
+
y = mock('y')
|
26
|
+
y.should_receive(:hash).and_return(0)
|
27
|
+
|
28
|
+
new_hash(x => 1).send(@method, new_hash(y => 1)).should be_false
|
29
|
+
end
|
30
|
+
|
31
|
+
it "does not compare keys with different hash codes via eql?" do
|
32
|
+
x = mock('x')
|
33
|
+
y = mock('y')
|
34
|
+
x.should_not_receive(:eql?)
|
35
|
+
y.should_not_receive(:eql?)
|
36
|
+
|
37
|
+
x.should_receive(:hash).and_return(0)
|
38
|
+
y.should_receive(:hash).and_return(1)
|
39
|
+
|
40
|
+
def x.hash() 0 end
|
41
|
+
def y.hash() 1 end
|
42
|
+
|
43
|
+
new_hash(x => 1).send(@method, new_hash(y => 1)).should be_false
|
44
|
+
end
|
45
|
+
|
46
|
+
it "computes equality for recursive hashes" do
|
47
|
+
h = new_hash
|
48
|
+
h[:a] = h
|
49
|
+
h.send(@method, h[:a]).should be_true
|
50
|
+
(h == h[:a]).should be_true
|
51
|
+
end
|
52
|
+
|
53
|
+
ruby_bug "redmine #2448", "1.9.1" do
|
54
|
+
it "computes equality for complex recursive hashes" do
|
55
|
+
a, b = {}, {}
|
56
|
+
a.merge! :self => a, :other => b
|
57
|
+
b.merge! :self => b, :other => a
|
58
|
+
a.send(@method, b).should be_true # they both have the same structure!
|
59
|
+
|
60
|
+
c = {}
|
61
|
+
c.merge! :other => c, :self => c
|
62
|
+
c.send(@method, a).should be_true # subtle, but they both have the same structure!
|
63
|
+
a[:delta] = c[:delta] = a
|
64
|
+
c.send(@method, a).should be_false # not quite the same structure, as a[:other][:delta] = nil
|
65
|
+
c[:delta] = 42
|
66
|
+
c.send(@method, a).should be_false
|
67
|
+
a[:delta] = 42
|
68
|
+
c.send(@method, a).should be_false
|
69
|
+
b[:delta] = 42
|
70
|
+
c.send(@method, a).should be_true
|
71
|
+
end
|
72
|
+
|
73
|
+
it "computes equality for recursive hashes & arrays" do
|
74
|
+
x, y, z = [], [], []
|
75
|
+
a, b, c = {:foo => x, :bar => 42}, {:foo => y, :bar => 42}, {:foo => z, :bar => 42}
|
76
|
+
x << a
|
77
|
+
y << c
|
78
|
+
z << b
|
79
|
+
b.send(@method, c).should be_true # they clearly have the same structure!
|
80
|
+
y.send(@method, z).should be_true
|
81
|
+
a.send(@method, b).should be_true # subtle, but they both have the same structure!
|
82
|
+
x.send(@method, y).should be_true
|
83
|
+
y << x
|
84
|
+
y.send(@method, z).should be_false
|
85
|
+
z << x
|
86
|
+
y.send(@method, z).should be_true
|
87
|
+
|
88
|
+
a[:foo], a[:bar] = a[:bar], a[:foo]
|
89
|
+
a.send(@method, b).should be_false
|
90
|
+
b[:bar] = b[:foo]
|
91
|
+
b.send(@method, c).should be_false
|
92
|
+
end
|
93
|
+
end # ruby_bug
|
94
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.expand_path('../../../../spec_helper', __FILE__)
|
2
|
+
require File.expand_path('../../fixtures/classes', __FILE__)
|
3
|
+
|
4
|
+
shared_examples_for :hash_index do |method|
|
5
|
+
before { @method = method }
|
6
|
+
|
7
|
+
it "returns the corresponding key for value" do
|
8
|
+
new_hash(2 => 'a', 1 => 'b').send(@method, 'b').should == 1
|
9
|
+
end
|
10
|
+
|
11
|
+
it "returns nil if the value is not found" do
|
12
|
+
new_hash(:a => -1, :b => 3.14, :c => 2.718).send(@method, 1).should be_nil
|
13
|
+
end
|
14
|
+
|
15
|
+
it "doesn't return default value if the value is not found" do
|
16
|
+
new_hash(5).send(@method, 5).should be_nil
|
17
|
+
end
|
18
|
+
|
19
|
+
it "compares values using ==" do
|
20
|
+
new_hash(1 => 0).send(@method, 0.0).should == 1
|
21
|
+
new_hash(1 => 0.0).send(@method, 0).should == 1
|
22
|
+
|
23
|
+
needle = mock('needle')
|
24
|
+
inhash = mock('inhash')
|
25
|
+
inhash.should_receive(:==).with(needle).and_return(true)
|
26
|
+
|
27
|
+
new_hash(1 => inhash).send(@method, needle).should == 1
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
shared_examples_for :hash_iteration_no_block do |method|
|
2
|
+
before { @method = method }
|
3
|
+
|
4
|
+
before(:each) do
|
5
|
+
@hsh = new_hash(1 => 2, 3 => 4, 5 => 6)
|
6
|
+
@empty = new_hash
|
7
|
+
end
|
8
|
+
|
9
|
+
ruby_version_is "" ... "1.8.7" do
|
10
|
+
it "raises a LocalJumpError when called on a non-empty hash without a block" do
|
11
|
+
lambda { @hsh.send(@method) }.should raise_error(LocalJumpError)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "does not raise a LocalJumpError when called on an empty hash without a block" do
|
15
|
+
@empty.send(@method).should == @empty
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
ruby_version_is "1.8.7" do
|
20
|
+
it "returns an Enumerator if called on a non-empty hash without a block" do
|
21
|
+
@hsh.send(@method).should be_an_instance_of(enumerator_class)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "returns an Enumerator if called on an empty hash without a block" do
|
25
|
+
@empty.send(@method).should be_an_instance_of(enumerator_class)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
shared_examples_for :hash_key_p do |method|
|
2
|
+
before { @method = method }
|
3
|
+
|
4
|
+
it "returns true if argument is a key" do
|
5
|
+
h = new_hash(:a => 1, :b => 2, :c => 3, 4 => 0)
|
6
|
+
h.send(@method, :a).should == true
|
7
|
+
h.send(@method, :b).should == true
|
8
|
+
h.send(@method, 'b').should == false
|
9
|
+
h.send(@method, 2).should == false
|
10
|
+
h.send(@method, 4).should == true
|
11
|
+
h.send(@method, 4.0).should == false
|
12
|
+
end
|
13
|
+
|
14
|
+
=begin nil
|
15
|
+
it "returns true if the key's matching value was nil" do
|
16
|
+
new_hash(:xyz => nil).send(@method, :xyz).should == true
|
17
|
+
end
|
18
|
+
=end
|
19
|
+
|
20
|
+
it "returns true if the key's matching value was false" do
|
21
|
+
new_hash(:xyz => false).send(@method, :xyz).should == true
|
22
|
+
end
|
23
|
+
|
24
|
+
=begin nil
|
25
|
+
it "returns true if the key is nil" do
|
26
|
+
new_hash(nil => 'b').send(@method, nil).should == true
|
27
|
+
new_hash(nil => nil).send(@method, nil).should == true
|
28
|
+
end
|
29
|
+
=end
|
30
|
+
|
31
|
+
=begin hashCode equals
|
32
|
+
it "compares keys with the same #hashCode value via #equals" do
|
33
|
+
x = mock('x')
|
34
|
+
x.stub!(:hashCode).and_return(42)
|
35
|
+
|
36
|
+
y = mock('y')
|
37
|
+
y.stub!(:hashCode).and_return(42)
|
38
|
+
y.should_receive(:equals).and_return(false)
|
39
|
+
|
40
|
+
new_hash(x => nil).send(@method, y).should == false
|
41
|
+
end
|
42
|
+
=end
|
43
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
shared_examples_for :hash_length do |method|
|
2
|
+
before { @method = method }
|
3
|
+
|
4
|
+
it "returns the number of entries" do
|
5
|
+
new_hash(:a => 1, :b => 'c').send(@method).should == 2
|
6
|
+
new_hash(:a => 1, :b => 2, :a => 2).send(@method).should == 2
|
7
|
+
new_hash(:a => 1, :b => 1, :c => 1).send(@method).should == 3
|
8
|
+
new_hash().send(@method).should == 0
|
9
|
+
new_hash(5).send(@method).should == 0
|
10
|
+
new_hash { 5 }.send(@method).should == 0
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
shared_examples_for :hash_replace do |method|
|
2
|
+
before { @method = method }
|
3
|
+
|
4
|
+
=begin self
|
5
|
+
it "returns self" do
|
6
|
+
h = new_hash(:a => 1, :b => 2)
|
7
|
+
h.send(@method, :c => -1, :d => -2).should equal(h)
|
8
|
+
end
|
9
|
+
=end
|
10
|
+
|
11
|
+
it "replaces the contents of self with other" do
|
12
|
+
h = new_hash(:a => 1, :b => 2)
|
13
|
+
h.send(@method, :c => -1, :d => -2)
|
14
|
+
h.should == new_hash(:c => -1, :d => -2)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "tries to convert the passed argument to a hash using #to_hash" do
|
18
|
+
obj = mock('{1=>2,3=>4}')
|
19
|
+
obj.should_receive(:to_hash).and_return(new_hash(1 => 2, 3 => 4).to_hash)
|
20
|
+
|
21
|
+
h = new_hash
|
22
|
+
h.send(@method, obj)
|
23
|
+
h.should == new_hash(1 => 2, 3 => 4)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "calls to_hash on hash subclasses" do
|
27
|
+
h = new_hash
|
28
|
+
h.send(@method, ToHashHash[1 => 2])
|
29
|
+
h.should == new_hash(1 => 2)
|
30
|
+
end
|
31
|
+
|
32
|
+
=begin default
|
33
|
+
it "does not transfer default values" do
|
34
|
+
hash_a = new_hash
|
35
|
+
hash_b = new_hash 5
|
36
|
+
hash_a.send(@method, hash_b)
|
37
|
+
hash_a.default.should == 5
|
38
|
+
|
39
|
+
hash_a = new_hash
|
40
|
+
hash_b = new_hash { |h, k| k * 2 }
|
41
|
+
hash_a.send(@method, hash_b)
|
42
|
+
hash_a.default(5).should == 10
|
43
|
+
|
44
|
+
hash_a = new_hash { |h, k| k * 5 }
|
45
|
+
hash_b = new_hash(lambda { raise "Should not invoke lambda" })
|
46
|
+
hash_a.send(@method, hash_b)
|
47
|
+
hash_a.default.should == hash_b.default
|
48
|
+
end
|
49
|
+
=end
|
50
|
+
|
51
|
+
=begin frozen
|
52
|
+
ruby_version_is ""..."1.9" do
|
53
|
+
it "raises a RuntimeError if called on a frozen instance that is modified" do
|
54
|
+
lambda do
|
55
|
+
HashSpecs.frozen_hash.send(@method, HashSpecs.empty_frozen_hash)
|
56
|
+
end.should raise_error(TypeError)
|
57
|
+
end
|
58
|
+
|
59
|
+
ruby_bug "#1571, [ruby-core:23714]", "1.8.8" do
|
60
|
+
it "raises a RuntimeError if called on a frozen instance that would not be modified" do
|
61
|
+
lambda do
|
62
|
+
HashSpecs.frozen_hash.send(@method, HashSpecs.frozen_hash)
|
63
|
+
end.should raise_error(TypeError)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
ruby_version_is "1.9" do
|
69
|
+
it "raises a RuntimeError if called on a frozen instance that is modified" do
|
70
|
+
lambda do
|
71
|
+
HashSpecs.frozen_hash.send(@method, HashSpecs.frozen_hash)
|
72
|
+
end.should raise_error(RuntimeError)
|
73
|
+
end
|
74
|
+
|
75
|
+
it "raises a RuntimeError if called on a frozen instance that would not be modified" do
|
76
|
+
lambda do
|
77
|
+
HashSpecs.frozen_hash.send(@method, HashSpecs.empty_frozen_hash)
|
78
|
+
end.should raise_error(RuntimeError)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
=end
|
82
|
+
end
|