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,14 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
require File.expand_path('../fixtures/classes', __FILE__)
|
3
|
+
require File.expand_path('../shared/key', __FILE__)
|
4
|
+
require File.expand_path('../shared/index', __FILE__)
|
5
|
+
|
6
|
+
describe "Hash#key?" do
|
7
|
+
it_behaves_like(:hash_key_p, :key?)
|
8
|
+
end
|
9
|
+
|
10
|
+
ruby_version_is "1.8.8" do
|
11
|
+
describe "Hash#key" do
|
12
|
+
it_behaves_like(:hash_index, :key)
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
require File.expand_path('../fixtures/classes', __FILE__)
|
3
|
+
|
4
|
+
describe "Hash#keys" do
|
5
|
+
|
6
|
+
ruby_version_is ""..."1.9" do
|
7
|
+
it "returns an array populated with keys" do
|
8
|
+
new_hash.keys.should == []
|
9
|
+
new_hash.keys.should be_kind_of(Array)
|
10
|
+
new_hash(5).keys.should == []
|
11
|
+
new_hash { 5 }.keys.should == []
|
12
|
+
new_hash(1 => 2, 2 => 4, 4 => 8).keys.sort.should == [1, 2, 4]
|
13
|
+
new_hash(1 => 2, 2 => 4, 4 => 8).keys.should be_kind_of(Array)
|
14
|
+
new_hash(nil => nil).keys.should == [nil]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
ruby_version_is "1.9" do
|
19
|
+
it "returns an array with the keys in the order they were inserted" do
|
20
|
+
new_hash.keys.should == []
|
21
|
+
new_hash.keys.should be_kind_of(Array)
|
22
|
+
new_hash(5).keys.should == []
|
23
|
+
new_hash { 5 }.keys.should == []
|
24
|
+
new_hash(1 => 2, 4 => 8, 2 => 4).keys.should == [1, 4, 2]
|
25
|
+
new_hash(1 => 2, 2 => 4, 4 => 8).keys.should be_kind_of(Array)
|
26
|
+
new_hash(nil => nil).keys.should == [nil]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
it "it uses the same order as #values" do
|
32
|
+
h = new_hash(1 => "1", 2 => "2", 3 => "3", 4 => "4")
|
33
|
+
|
34
|
+
values = h.values.to_a
|
35
|
+
h.size.times do |i|
|
36
|
+
h[h.keys[i]].should == values[i]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
require File.expand_path('../fixtures/classes', __FILE__)
|
3
|
+
require File.expand_path('../shared/iteration', __FILE__)
|
4
|
+
require File.expand_path('../shared/update', __FILE__)
|
5
|
+
|
6
|
+
describe "Hash#merge" do
|
7
|
+
it "returns a new hash by combining self with the contents of other" do
|
8
|
+
h = new_hash(1 => :a, 2 => :b, 3 => :c).merge(:a => 1, :c => 2)
|
9
|
+
h.should == new_hash(:c => 2, 1 => :a, 2 => :b, :a => 1, 3 => :c)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "sets any duplicate key to the value of block if passed a block" do
|
13
|
+
h1 = new_hash(:a => 2, :b => 1, :d => 5)
|
14
|
+
h2 = new_hash(:a => -2, :b => 4, :c => -3)
|
15
|
+
r = h1.merge(h2) { |k,x,y| nil }
|
16
|
+
r.should == new_hash(:a => nil, :b => nil, :c => -3, :d => 5)
|
17
|
+
|
18
|
+
r = h1.merge(h2) { |k,x,y| "#{k}:#{x+2*y}" }
|
19
|
+
r.should == new_hash(:a => "a:-2", :b => "b:9", :c => -3, :d => 5)
|
20
|
+
|
21
|
+
lambda {
|
22
|
+
h1.merge(h2) { |k, x, y| raise(IndexError) }
|
23
|
+
}.should raise_error(IndexError)
|
24
|
+
|
25
|
+
r = h1.merge(h1) { |k,x,y| :x }
|
26
|
+
r.should == new_hash(:a => :x, :b => :x, :d => :x)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "tries to convert the passed argument to a hash using #to_hash" do
|
30
|
+
obj = mock('{1=>2}')
|
31
|
+
obj.should_receive(:to_hash).and_return(new_hash(1 => 2).to_hash)
|
32
|
+
new_hash(3 => 4).merge(obj).should == new_hash(1 => 2, 3 => 4)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "does not call to_hash on hash subclasses" do
|
36
|
+
new_hash(3 => 4).merge(ToHashHash[1 => 2]).should == new_hash(1 => 2, 3 => 4)
|
37
|
+
end
|
38
|
+
|
39
|
+
=begin subclass
|
40
|
+
it "returns subclass instance for subclasses" do
|
41
|
+
MyHash[1 => 2, 3 => 4].merge(new_hash(1 => 2)).should be_kind_of(MyHash)
|
42
|
+
MyHash[].merge(new_hash(1 => 2)).should be_kind_of(MyHash)
|
43
|
+
|
44
|
+
new_hash(1 => 2, 3 => 4).merge(MyHash[1 => 2]).class.should == hash_class
|
45
|
+
new_hash.merge(MyHash[1 => 2]).class.should == hash_class
|
46
|
+
end
|
47
|
+
=end
|
48
|
+
|
49
|
+
it "processes entries with same order as each()" do
|
50
|
+
h = new_hash(1 => 2, 3 => 4, 5 => 6, "x" => nil, nil => 5, [] => [])
|
51
|
+
merge_pairs = []
|
52
|
+
each_pairs = []
|
53
|
+
h.each_pair { |k, v| each_pairs << [k, v] }
|
54
|
+
h.merge(h) { |k, v1, v2| merge_pairs << [k, v1] }
|
55
|
+
merge_pairs.should == each_pairs
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "Hash#merge!" do
|
61
|
+
it_behaves_like(:hash_update, :merge!)
|
62
|
+
|
63
|
+
it "does not raise an exception if changing the value of an existing key during iteration" do
|
64
|
+
hash = {1 => 2, 3 => 4, 5 => 6}
|
65
|
+
hash2 = {1 => :foo, 3 => :bar}
|
66
|
+
hash.each { hash.merge!(hash2) }
|
67
|
+
hash.should == {1 => :foo, 3 => :bar, 5 => 6}
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
ruby_version_is "1.9" do
|
4
|
+
describe "Hash#rassoc" do
|
5
|
+
before(:each) do
|
6
|
+
@h = {:apple => :green, :orange => :orange, :grape => :green, :banana => :yellow}
|
7
|
+
end
|
8
|
+
|
9
|
+
it "returns an Array if the argument is a value of the Hash" do
|
10
|
+
@h.rassoc(:green).should be_an_instance_of(Array)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "returns a 2-element Array if the argument is a value of the Hash" do
|
14
|
+
@h.rassoc(:orange).size.should == 2
|
15
|
+
end
|
16
|
+
|
17
|
+
it "sets the first element of the Array to the key of the located value" do
|
18
|
+
@h.rassoc(:yellow).first.should == :banana
|
19
|
+
end
|
20
|
+
|
21
|
+
it "sets the last element of the Array to the located value" do
|
22
|
+
@h.rassoc(:yellow).last.should == :yellow
|
23
|
+
end
|
24
|
+
|
25
|
+
it "only returns the first matching key-value pair" do
|
26
|
+
@h.rassoc(:green).should == [:apple, :green]
|
27
|
+
end
|
28
|
+
|
29
|
+
it "uses #== to compare the argument to the values" do
|
30
|
+
@h[:key] = 1.0
|
31
|
+
1.should == 1.0
|
32
|
+
@h.rassoc(1).should == [:key, 1.0]
|
33
|
+
end
|
34
|
+
|
35
|
+
it "returns nil if the argument is not a value of the Hash" do
|
36
|
+
@h.rassoc(:banana).should be_nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
require File.expand_path('../fixtures/classes', __FILE__)
|
3
|
+
require File.expand_path('../shared/iteration', __FILE__)
|
4
|
+
|
5
|
+
describe "Hash#reject" do
|
6
|
+
it "is equivalent to hsh.dup.delete_if" do
|
7
|
+
h = new_hash(:a => 'a', :b => 'b', :c => 'd')
|
8
|
+
h.reject { |k,v| k == 'd' }.should == (h.dup.delete_if { |k, v| k == 'd' })
|
9
|
+
|
10
|
+
all_args_reject = []
|
11
|
+
all_args_delete_if = []
|
12
|
+
h = new_hash(1 => 2, 3 => 4)
|
13
|
+
h.reject { |*args| all_args_reject << args }
|
14
|
+
h.delete_if { |*args| all_args_delete_if << args }
|
15
|
+
all_args_reject.should == all_args_delete_if
|
16
|
+
|
17
|
+
h = new_hash(1 => 2)
|
18
|
+
# dup doesn't copy singleton methods
|
19
|
+
def h.to_a() end
|
20
|
+
h.reject { false }.to_a.should == [[1, 2]]
|
21
|
+
end
|
22
|
+
|
23
|
+
=begin subclass
|
24
|
+
it "returns subclass instance for subclasses" do
|
25
|
+
MyHash[1 => 2, 3 => 4].reject { false }.should be_kind_of(MyHash)
|
26
|
+
MyHash[1 => 2, 3 => 4].reject { true }.should be_kind_of(MyHash)
|
27
|
+
end
|
28
|
+
=end
|
29
|
+
|
30
|
+
=begin taint
|
31
|
+
it "taints the resulting hash" do
|
32
|
+
h = new_hash(:a => 1).taint
|
33
|
+
h.reject {false}.tainted?.should == true
|
34
|
+
end
|
35
|
+
=end
|
36
|
+
|
37
|
+
it "processes entries with the same order as reject!" do
|
38
|
+
h = new_hash(:a => 1, :b => 2, :c => 3, :d => 4)
|
39
|
+
|
40
|
+
reject_pairs = []
|
41
|
+
reject_bang_pairs = []
|
42
|
+
h.dup.reject { |*pair| reject_pairs << pair }
|
43
|
+
h.reject! { |*pair| reject_bang_pairs << pair }
|
44
|
+
|
45
|
+
reject_pairs.should == reject_bang_pairs
|
46
|
+
end
|
47
|
+
|
48
|
+
it_behaves_like(:hash_iteration_no_block, :reject)
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "Hash#reject!" do
|
52
|
+
before(:each) do
|
53
|
+
@hsh = new_hash(1 => 2, 3 => 4, 5 => 6)
|
54
|
+
@empty = new_hash
|
55
|
+
end
|
56
|
+
|
57
|
+
it "is equivalent to delete_if if changes are made" do
|
58
|
+
new_hash(:a => 2).reject! { |k,v| v > 1 }.should ==
|
59
|
+
new_hash(:a => 2).delete_if { |k, v| v > 1 }
|
60
|
+
|
61
|
+
h = new_hash(1 => 2, 3 => 4)
|
62
|
+
all_args_reject = []
|
63
|
+
all_args_delete_if = []
|
64
|
+
h.dup.reject! { |*args| all_args_reject << args }
|
65
|
+
h.dup.delete_if { |*args| all_args_delete_if << args }
|
66
|
+
all_args_reject.should == all_args_delete_if
|
67
|
+
end
|
68
|
+
|
69
|
+
it "returns nil if no changes were made" do
|
70
|
+
new_hash(:a => 1).reject! { |k,v| v > 1 }.should == nil
|
71
|
+
end
|
72
|
+
|
73
|
+
it "processes entries with the same order as delete_if" do
|
74
|
+
h = new_hash(:a => 1, :b => 2, :c => 3, :d => 4)
|
75
|
+
|
76
|
+
reject_bang_pairs = []
|
77
|
+
delete_if_pairs = []
|
78
|
+
h.dup.reject! { |*pair| reject_bang_pairs << pair }
|
79
|
+
h.dup.delete_if { |*pair| delete_if_pairs << pair }
|
80
|
+
|
81
|
+
reject_bang_pairs.should == delete_if_pairs
|
82
|
+
end
|
83
|
+
|
84
|
+
=begin frozen
|
85
|
+
ruby_version_is ""..."1.9" do
|
86
|
+
it "raises a TypeError if called on a frozen instance" do
|
87
|
+
lambda { HashSpecs.frozen_hash.reject! { false } }.should raise_error(TypeError)
|
88
|
+
lambda { HashSpecs.empty_frozen_hash.reject! { true } }.should raise_error(TypeError)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
ruby_version_is "1.9" do
|
93
|
+
it "raises a RuntimeError if called on a frozen instance that is modified" do
|
94
|
+
lambda { HashSpecs.empty_frozen_hash.reject! { true } }.should raise_error(RuntimeError)
|
95
|
+
end
|
96
|
+
|
97
|
+
it "raises a RuntimeError if called on a frozen instance that would not be modified" do
|
98
|
+
lambda { HashSpecs.frozen_hash.reject! { false } }.should raise_error(RuntimeError)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
=end
|
102
|
+
|
103
|
+
ruby_version_is "" ... "1.8.7" do
|
104
|
+
it "raises a LocalJumpError when called on a non-empty hash without a block" do
|
105
|
+
lambda { @hsh.reject! }.should raise_error(LocalJumpError)
|
106
|
+
end
|
107
|
+
|
108
|
+
it "does not raise a LocalJumpError when called on an empty hash without a block" do
|
109
|
+
@empty.reject!.should == nil
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
ruby_version_is "1.8.7" do
|
114
|
+
it "returns an Enumerator when called on a non-empty hash without a block" do
|
115
|
+
@hsh.reject!.should be_an_instance_of(enumerator_class)
|
116
|
+
end
|
117
|
+
|
118
|
+
it "returns an Enumerator when called on an empty hash without a block" do
|
119
|
+
@empty.reject!.should be_an_instance_of(enumerator_class)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
require File.expand_path('../fixtures/classes', __FILE__)
|
3
|
+
require File.expand_path('../shared/iteration', __FILE__)
|
4
|
+
|
5
|
+
describe "Hash#select" do
|
6
|
+
before(:each) do
|
7
|
+
@hsh = new_hash(1 => 2, 3 => 4, 5 => 6)
|
8
|
+
@empty = new_hash
|
9
|
+
end
|
10
|
+
|
11
|
+
it "yields two arguments: key and value" do
|
12
|
+
all_args = []
|
13
|
+
new_hash(1 => 2, 3 => 4).select { |*args| all_args << args }
|
14
|
+
all_args.sort.should == [[1, 2], [3, 4]]
|
15
|
+
end
|
16
|
+
|
17
|
+
ruby_version_is ""..."1.9" do
|
18
|
+
it "returns an Array of entries for which block is true" do
|
19
|
+
a_pairs = new_hash('a' => 9, 'c' => 4, 'b' => 5, 'd' => 2).select { |k,v| v % 2 == 0 }
|
20
|
+
a_pairs.should be_an_instance_of(Array)
|
21
|
+
a_pairs.sort.should == [['c', 4], ['d', 2]]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
ruby_version_is "1.9" do
|
26
|
+
it "returns a Hash of entries for which block is true" do
|
27
|
+
a_pairs = new_hash('a' => 9, 'c' => 4, 'b' => 5, 'd' => 2).select { |k,v| v % 2 == 0 }
|
28
|
+
a_pairs.should be_an_instance_of(Hash)
|
29
|
+
a_pairs.sort.should == [['c', 4], ['d', 2]]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
it "processes entries with the same order as reject" do
|
34
|
+
h = new_hash(:a => 9, :c => 4, :b => 5, :d => 2)
|
35
|
+
|
36
|
+
select_pairs = []
|
37
|
+
reject_pairs = []
|
38
|
+
h.dup.select { |*pair| select_pairs << pair }
|
39
|
+
h.reject { |*pair| reject_pairs << pair }
|
40
|
+
|
41
|
+
select_pairs.should == reject_pairs
|
42
|
+
end
|
43
|
+
|
44
|
+
ruby_version_is "" ... "1.8.7" do
|
45
|
+
it "raises a LocalJumpError when called on a non-empty hash without a block" do
|
46
|
+
lambda { @hsh.select }.should raise_error(LocalJumpError)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "does not raise a LocalJumpError when called on an empty hash without a block" do
|
50
|
+
@empty.select.should == []
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
ruby_version_is "1.8.7" do
|
55
|
+
it "returns an Enumerator when called on a non-empty hash without a block" do
|
56
|
+
@hsh.select.should be_an_instance_of(enumerator_class)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "returns an Enumerator when called on an empty hash without a block" do
|
60
|
+
@empty.select.should be_an_instance_of(enumerator_class)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
ruby_version_is "1.9" do
|
67
|
+
describe "Hash#select!" do
|
68
|
+
before(:each) do
|
69
|
+
@hsh = new_hash(1 => 2, 3 => 4, 5 => 6)
|
70
|
+
@empty = new_hash
|
71
|
+
end
|
72
|
+
|
73
|
+
it "is equivalent to keep_if if changes are made" do
|
74
|
+
new_hash(:a => 2).select! { |k,v| v <= 1 }.should ==
|
75
|
+
new_hash(:a => 2).keep_if { |k, v| v <= 1 }
|
76
|
+
|
77
|
+
h = new_hash(1 => 2, 3 => 4)
|
78
|
+
all_args_select = []
|
79
|
+
all_args_keep_if = []
|
80
|
+
h.dup.select! { |*args| all_args_select << args }
|
81
|
+
h.dup.keep_if { |*args| all_args_keep_if << args }
|
82
|
+
all_args_select.should == all_args_keep_if
|
83
|
+
end
|
84
|
+
|
85
|
+
it "returns nil if no changes were made" do
|
86
|
+
new_hash(:a => 1).select! { |k,v| v <= 1 }.should == nil
|
87
|
+
end
|
88
|
+
=begin frozen
|
89
|
+
it "raises a RuntimeError if called on a frozen instance that is modified" do
|
90
|
+
lambda { HashSpecs.empty_frozen_hash.select! { false } }.should raise_error(RuntimeError)
|
91
|
+
end
|
92
|
+
|
93
|
+
it "raises a RuntimeError if called on a frozen instance that would not be modified" do
|
94
|
+
lambda { HashSpecs.frozen_hash.select! { true } }.should raise_error(RuntimeError)
|
95
|
+
end
|
96
|
+
=end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
shared_examples_for :hash_each do |method|
|
2
|
+
before { @method = method }
|
3
|
+
|
4
|
+
=begin self
|
5
|
+
it "returns self" do
|
6
|
+
h = new_hash(:a => 1, :b => 2, :c => 3, :d => 5)
|
7
|
+
h.send(@method) { |k,v| }.should equal(h)
|
8
|
+
end
|
9
|
+
=end
|
10
|
+
|
11
|
+
it "yields a [[key, value]] Array for each pair to a block expecting |*args|" do
|
12
|
+
all_args = []
|
13
|
+
new_hash(1 => 2, 3 => 4).send(@method) { |*args| all_args << args }
|
14
|
+
all_args.sort.should == [[[1, 2]], [[3, 4]]]
|
15
|
+
end
|
16
|
+
|
17
|
+
it "yields the key and value of each pair to a block expecting |key, value|" do
|
18
|
+
r = new_hash
|
19
|
+
h = new_hash(:a => 1, :b => 2, :c => 3, :d => 5)
|
20
|
+
h.send(@method) { |k,v| r[k.to_s] = v.to_s }
|
21
|
+
r.should == new_hash("a" => "1", "b" => "2", "c" => "3", "d" => "5")
|
22
|
+
end
|
23
|
+
|
24
|
+
it "yields the key only to a block expecting |key,|" do
|
25
|
+
ary = []
|
26
|
+
h = new_hash("a" => 1, "b" => 2, "c" => 3)
|
27
|
+
h.send(@method) { |k,| ary << k }
|
28
|
+
ary.sort.should == ["a", "b", "c"]
|
29
|
+
end
|
30
|
+
|
31
|
+
it "uses the same order as keys() and values()" do
|
32
|
+
h = new_hash(:a => 1, :b => 2, :c => 3, :d => 5)
|
33
|
+
keys = []
|
34
|
+
values = []
|
35
|
+
|
36
|
+
h.send(@method) do |k, v|
|
37
|
+
keys << k
|
38
|
+
values << v
|
39
|
+
end
|
40
|
+
|
41
|
+
keys.should == h.keys
|
42
|
+
values.should == h.values.to_a
|
43
|
+
end
|
44
|
+
|
45
|
+
# Confirming the argument-splatting works from child class for both k, v and [k, v]
|
46
|
+
it "properly expands (or not) child class's 'each'-yielded args" do
|
47
|
+
cls1 = Class.new(Hash) do
|
48
|
+
attr_accessor :k_v
|
49
|
+
def each
|
50
|
+
super do |k, v|
|
51
|
+
@k_v = [k, v]
|
52
|
+
yield k, v
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
cls2 = Class.new(Hash) do
|
58
|
+
attr_accessor :k_v
|
59
|
+
def each
|
60
|
+
super do |k, v|
|
61
|
+
@k_v = [k, v]
|
62
|
+
yield([k, v])
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
obj1 = cls1.new
|
68
|
+
obj1['a'] = 'b'
|
69
|
+
obj1.map {|k, v| [k, v]}.should == [['a', 'b']]
|
70
|
+
obj1.k_v.should == ['a', 'b']
|
71
|
+
|
72
|
+
obj2 = cls2.new
|
73
|
+
obj2['a'] = 'b'
|
74
|
+
obj2.map {|k, v| [k, v]}.should == [['a', 'b']]
|
75
|
+
obj2.k_v.should == ['a', 'b']
|
76
|
+
end
|
77
|
+
end
|