gorillib 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. data/.gitignore +49 -0
  2. data/.rspec +2 -0
  3. data/CHANGELOG.textile +49 -0
  4. data/Gemfile +15 -0
  5. data/Gemfile.lock +36 -0
  6. data/README.textile +6 -1
  7. data/Rakefile +42 -9
  8. data/VERSION +1 -1
  9. data/gorillib.gemspec +110 -73
  10. data/lib/gorillib/array/deep_compact.rb +3 -12
  11. data/lib/gorillib/datetime/#flat.rb# +30 -0
  12. data/lib/gorillib/datetime/flat.rb +2 -10
  13. data/lib/gorillib/datetime/parse.rb +3 -1
  14. data/lib/gorillib/enumerable/sum.rb +37 -35
  15. data/lib/gorillib/hash/deep_compact.rb +3 -13
  16. data/lib/gorillib/logger/log.rb +1 -1
  17. data/lib/gorillib/numeric/clamp.rb +9 -0
  18. data/lib/gorillib/object/try.rb +10 -0
  19. data/lib/gorillib/object/try_dup.rb +44 -0
  20. data/lib/gorillib/string/human.rb +1 -3
  21. data/lib/gorillib/string/truncate.rb +2 -2
  22. data/spec/array/compact_blank_spec.rb +37 -0
  23. data/spec/array/extract_options_spec.rb +47 -0
  24. data/spec/datetime/flat_spec.rb +38 -0
  25. data/spec/datetime/parse_spec.rb +48 -0
  26. data/spec/enumerable/sum_spec.rb +56 -0
  27. data/spec/hash/compact_spec.rb +70 -0
  28. data/spec/hash/deep_compact_spec.rb +37 -0
  29. data/spec/hash/deep_merge_spec.rb +117 -0
  30. data/spec/hash/keys_spec.rb +111 -0
  31. data/spec/hash/reverse_merge_spec.rb +25 -0
  32. data/spec/hash/slice_spec.rb +43 -0
  33. data/spec/hash/zip_spec.rb +31 -0
  34. data/spec/logger/log_spec.rb +31 -0
  35. data/spec/metaprogramming/aliasing_spec.rb +177 -0
  36. data/spec/metaprogramming/cattr_accessor_spec.rb +41 -0
  37. data/spec/metaprogramming/class_attribute_spec.rb +75 -0
  38. data/spec/metaprogramming/delegation_spec.rb +166 -0
  39. data/spec/metaprogramming/mattr_accessor_spec.rb +44 -0
  40. data/spec/metaprogramming/singleton_class_spec.rb +9 -0
  41. data/spec/{numeric_spec.rb → numeric/clamp_spec.rb} +2 -2
  42. data/spec/object/blank_spec.rb +93 -0
  43. data/spec/object/try_dup_spec.rb +47 -0
  44. data/spec/object/try_spec.rb +20 -0
  45. data/spec/spec_helper.rb +13 -8
  46. data/spec/string/constantize_spec.rb +56 -0
  47. data/spec/string/human_spec.rb +66 -0
  48. data/spec/string/inflections_spec.rb +74 -0
  49. data/{test → spec}/string/inflector_test_cases.rb +0 -0
  50. data/spec/string/truncate_spec.rb +42 -0
  51. data/spec/support/kcode_test_helper.rb +16 -0
  52. metadata +209 -96
  53. data/.document +0 -5
  54. data/fiddle/hubahuba.rb +0 -62
  55. data/spec/blank_spec.rb +0 -86
  56. data/spec/deep_compact_spec.rb +0 -36
  57. data/spec/gorillib_spec.rb +0 -7
  58. data/spec/rcov.opts +0 -6
  59. data/spec/spec.opts +0 -4
  60. data/spec/spec_tasks.rake +0 -15
  61. data/test/abstract_unit.rb +0 -25
  62. data/test/array/compact_blank_test.rb +0 -33
  63. data/test/array/extract_options_test.rb +0 -39
  64. data/test/datetime/flat_test.rb +0 -0
  65. data/test/datetime/parse_test.rb +0 -0
  66. data/test/enumerable/sum_test.rb +0 -50
  67. data/test/hash/compact_test.rb +0 -38
  68. data/test/hash/deep_merge_test.rb +0 -30
  69. data/test/hash/keys_test.rb +0 -110
  70. data/test/hash/reverse_merge_test.rb +0 -20
  71. data/test/hash/slice_test.rb +0 -47
  72. data/test/hash/zip_test.rb +0 -0
  73. data/test/logger/log_test.rb +0 -0
  74. data/test/metaprogramming/aliasing_test.rb +0 -188
  75. data/test/metaprogramming/cattr_accessor_test.rb +0 -38
  76. data/test/metaprogramming/class_attribute_test.rb +0 -73
  77. data/test/metaprogramming/delegation_test.rb +0 -166
  78. data/test/metaprogramming/mattr_accessor_test.rb +0 -40
  79. data/test/metaprogramming/singleton_class_test.rb +0 -9
  80. data/test/object/blank_test.rb +0 -22
  81. data/test/string/constantize_test.rb +0 -30
  82. data/test/string/human_test.rb +0 -65
  83. data/test/string/inflections_test.rb +0 -57
  84. data/test/string/truncate_test.rb +0 -37
@@ -6,19 +6,9 @@ require 'gorillib/object/blank'
6
6
  class Hash
7
7
  def deep_compact!
8
8
  self.each do |key, val|
9
- case val
10
- when Hash
11
- val = val.deep_compact!
12
- self.delete(key) if val.blank?
13
- when Array
14
- val = val.deep_compact!
15
- self.delete(key) if val.blank?
16
- when String
17
- self.delete(key) if val.blank?
18
- when nil
19
- self.delete(key)
20
- end
9
+ val.deep_compact! if val.respond_to?(:deep_compact!)
10
+ self.delete(key) if val.blank?
21
11
  end
22
- self.blank? ? nil : self
12
+ self
23
13
  end
24
14
  end
@@ -5,7 +5,7 @@ require 'logger'
5
5
  #
6
6
  # define Log yourself to prevent its creation
7
7
  #
8
- ::Log = Logger.new(STDERR) unless defined?(::Log)
8
+ ::Log = Logger.new($stderr) unless defined?(::Log)
9
9
 
10
10
  def Log.dump *args
11
11
  debug args.map(&:inspect).join("\t")
@@ -1,4 +1,13 @@
1
1
  Numeric.class_eval do
2
+ #
3
+ # Coerce a number to lie between min and max.
4
+ #
5
+ # @example
6
+ # 5.clamp(6, 7) # => 6
7
+ # 5.clamp(6) # => 6
8
+ # 5.clamp(nil, 6) # => 5
9
+ # 5.clamp(nil, 4) # => 4
10
+ #
2
11
  def clamp min=nil, max=nil
3
12
  raise ArgumentError, "min must be <= max" if (min && max && (min > max))
4
13
  return min if min && (self < min)
@@ -0,0 +1,10 @@
1
+ class Object
2
+ # @person ? @person.name : nil
3
+ # vs
4
+ # @person.try(:name)
5
+ def try(method)
6
+ send method if respond_to? method
7
+ end
8
+
9
+ end
10
+
@@ -0,0 +1,44 @@
1
+ class Object
2
+ # Override this in a child if it cannot be dup'ed
3
+ #
4
+ # @return [Object]
5
+ def try_dup
6
+ self.dup
7
+ end
8
+ end
9
+
10
+ class TrueClass
11
+ def try_dup
12
+ self
13
+ end
14
+ end
15
+
16
+ class FalseClass
17
+ def try_dup
18
+ self
19
+ end
20
+ end
21
+
22
+ class Module
23
+ def try_dup
24
+ self
25
+ end
26
+ end
27
+
28
+ class NilClass
29
+ def try_dup
30
+ self
31
+ end
32
+ end
33
+
34
+ class Numeric
35
+ def try_dup
36
+ self
37
+ end
38
+ end
39
+
40
+ class Symbol
41
+ def try_dup
42
+ self
43
+ end
44
+ end
@@ -34,9 +34,7 @@ class Array
34
34
  default_words_connector = ", "
35
35
  default_two_words_connector = " and "
36
36
  default_last_word_connector = ", and "
37
-
38
- options.assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector, :locale)
39
- options.reverse_merge! :words_connector => default_words_connector, :two_words_connector => default_two_words_connector, :last_word_connector => default_last_word_connector
37
+ options = { :words_connector => default_words_connector, :two_words_connector => default_two_words_connector, :last_word_connector => default_last_word_connector }.merge(options)
40
38
 
41
39
  case length
42
40
  when 0
@@ -16,13 +16,13 @@ class String
16
16
  # # => "And they f... (continued)"
17
17
  def truncate(length, options = {})
18
18
  text = self.dup
19
- chars = text.respond_to?(:mb_chars) ? text.mb_chars : text.chars
19
+ chars = text.respond_to?(:mb_chars) ? text.mb_chars : text
20
20
  omission = options[:omission] || "..."
21
21
  omission_len = omission.respond_to?(:mb_chars) ? omission.mb_chars.length : omission.length
22
22
  length_with_room_for_omission = length - omission_len
23
23
 
24
24
  if (separator = options[:separator])
25
- separator_chars = separator.respond_to?(:mb_chars) ? separator.to_s.mb_chars : separator.to_s.chars
25
+ separator_chars = separator.respond_to?(:mb_chars) ? separator.to_s.mb_chars : separator.to_s
26
26
  stop = chars.rindex(separator_chars, length_with_room_for_omission) || length_with_room_for_omission
27
27
  else
28
28
  stop = length_with_room_for_omission
@@ -0,0 +1,37 @@
1
+ require File.dirname(__FILE__)+'/../spec_helper'
2
+ require 'gorillib/array/compact_blank'
3
+
4
+ describe Array do
5
+
6
+ describe '#compact_blank' do
7
+ it 'with empty' do
8
+ [ [nil], [nil, false, {}, ""] ].each do |arr|
9
+ arr.compact_blank.should == []
10
+ arr.length.should_not == 0
11
+ end
12
+ end
13
+
14
+ it 'with full' do
15
+ [ [nil, 1, nil, 2], [nil, 1, false, 2, {}, ""] ].each do |arr|
16
+ arr.compact_blank.should == [1, 2]
17
+ end
18
+ end
19
+ end
20
+
21
+ describe '#compact_blank!' do
22
+ it 'with empty' do
23
+ [].compact_blank!.should == []
24
+ [ [nil], [nil, false, {}, ""] ].each do |arr|
25
+ arr.compact_blank!.should == []
26
+ arr.length.should == 0
27
+ end
28
+ end
29
+
30
+ it 'with full' do
31
+ [ [nil, 1, nil, 2], [nil, 1, false, 2, {}, ""] ].each do |arr|
32
+ arr.compact_blank!.should == [1, 2]
33
+ end
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,47 @@
1
+ require File.dirname(__FILE__)+'/../spec_helper'
2
+ require 'gorillib/array/extract_options'
3
+
4
+ class HashSubclass < Hash
5
+ end
6
+
7
+ class ExtractableHashSubclass < Hash
8
+ def extractable_options?
9
+ true
10
+ end
11
+ end
12
+
13
+ describe Array do
14
+ describe '#extract_options!' do
15
+ it 'pulls empty hash from empty array' do
16
+ [].extract_options!.should == {}
17
+ end
18
+ it 'pulls empty hash from array with no hash' do
19
+ [1].extract_options!.should == {}
20
+ end
21
+ it 'pulls hash from array with only that hash' do
22
+ [{:a=>:b}].extract_options!.should == {:a=>:b}
23
+ end
24
+ it 'pulls hash from end of array' do
25
+ [1, {:a=>:b}].extract_options!.should == {:a=>:b}
26
+ end
27
+
28
+ it 'does not extract hash subclasses' do
29
+ hash = HashSubclass.new
30
+ hash[:foo] = 1
31
+ array = [hash]
32
+ options = array.extract_options!
33
+ options.should == {}
34
+ array.should == [hash]
35
+ end
36
+
37
+ it 'does extract extractable subclass' do
38
+ hash = ExtractableHashSubclass.new
39
+ hash[:foo] = 1
40
+ array = [hash]
41
+ options = array.extract_options!
42
+ options.should == {:foo => 1}
43
+ array.should == []
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1,38 @@
1
+ require File.dirname(__FILE__)+'/../spec_helper'
2
+ require 'gorillib/datetime/flat'
3
+ require 'gorillib/datetime/parse'
4
+
5
+ describe Time do
6
+ describe '#to_flat' do
7
+ before do
8
+ @time_utc = Time.parse("2011-02-03T04:05:06 UTC")
9
+ @time_cst = Time.parse("2011-02-02T22:05:06-06:00")
10
+ @time_flat = "20110203040506"
11
+ end
12
+
13
+ it 'converts times to UTC' do
14
+ @time_utc.to_flat.should == @time_flat
15
+ @time_cst.to_flat.should == @time_flat
16
+ end
17
+
18
+ it 'round-trips' do
19
+ Time.parse_safely(@time_flat).to_flat.should == @time_flat
20
+ Time.parse_safely(@time_utc.to_flat).should == @time_utc
21
+ end
22
+
23
+ end
24
+ end
25
+
26
+ describe Date do
27
+ describe '#to_flat' do
28
+ before do
29
+ @date = Date.new(2011, 2, 3)
30
+ @date_flat = "20110203"
31
+ end
32
+
33
+ it 'converts dates' do
34
+ @date.to_flat.should == @date_flat
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,48 @@
1
+ require File.dirname(__FILE__)+'/../spec_helper'
2
+ require 'gorillib/datetime/flat'
3
+ require 'gorillib/datetime/parse'
4
+
5
+ describe DateTime do
6
+ describe '#parse_safely' do
7
+ before do
8
+ @time_utc = Time.parse("2011-02-03T04:05:06 UTC")
9
+ @time_cst = Time.parse("2011-02-02T22:05:06-06:00")
10
+ @time_flat = "20110203040506"
11
+ @time_iso_utc = "2011-02-03T04:05:06+00:00"
12
+ @time_iso_cst = "2011-02-02T22:05:06-06:00"
13
+ end
14
+
15
+ it 'with a Time, passes it through.' do
16
+ Time.parse_safely(@time_utc).should == @time_utc
17
+ Time.parse_safely(@time_cst).should == @time_cst
18
+ end
19
+
20
+ it 'with a Time, converts to UTC.' do
21
+ Time.parse_safely(@time_utc).utc_offset.should == 0
22
+ Time.parse_safely(@time_cst).utc_offset.should == 0
23
+ end
24
+
25
+ it 'with a flat time, converts to UTC Time instance' do
26
+ Time.parse_safely(@time_flat).should == @time_utc
27
+ Time.parse_safely(@time_flat).utc_offset.should == 0
28
+ end
29
+
30
+ it 'with a flat time and Z, converts to UTC Time instance' do
31
+ Time.parse_safely(@time_flat+'Z').should == @time_utc
32
+ Time.parse_safely(@time_flat+'Z').utc_offset.should == 0
33
+ end
34
+
35
+ it 'parses a regular time string, converting to UTC' do
36
+ Time.parse_safely(@time_iso_utc).should == @time_utc
37
+ Time.parse_safely(@time_iso_utc).utc_offset.should == 0
38
+ Time.parse_safely(@time_iso_cst).should == @time_utc
39
+ Time.parse_safely(@time_iso_cst).utc_offset.should == 0
40
+ end
41
+
42
+ it 'round-trips' do
43
+ Time.parse_safely(@time_flat).to_flat.should == @time_flat
44
+ Time.parse_safely(@time_utc.to_flat).should == @time_utc
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,56 @@
1
+ require File.dirname(__FILE__)+'/../spec_helper'
2
+ require 'gorillib/enumerable/sum'
3
+
4
+ Payment = Struct.new(:price)
5
+ class SummablePayment < Payment
6
+ def +(p) self.class.new(price + p.price) end
7
+ end
8
+
9
+ describe Enumerable do
10
+ describe '#sum' do
11
+ it 'sums lists of numbers to a number' do
12
+ [5, 15, 10].sum .should == 30
13
+ [5, 15, 10].sum{|i| i }.should == 30
14
+ end
15
+
16
+ it 'sums list of strings to a string' do
17
+
18
+ %w(a b c).sum .should == 'abc'
19
+ %w(a b c).sum{|i| i }.should == 'abc'
20
+ end
21
+
22
+ it 'sums list of objects with a &:method' do
23
+ payments = [ Payment.new(5), Payment.new(15), Payment.new(10) ]
24
+ payments.sum(&:price) .should == 30
25
+ payments.sum { |p| p.price * 2 }.should == 60
26
+ end
27
+
28
+ it 'sums object with a synthetic "+" method' do
29
+ payments = [ SummablePayment.new(5), SummablePayment.new(15) ]
30
+ payments.sum .should == SummablePayment.new(20)
31
+ payments.sum{|p| p }.should == SummablePayment.new(20)
32
+ end
33
+
34
+ it 'handles nil sums' do
35
+ lambda{ [5, 15, nil].sum }.should raise_error(TypeError)
36
+
37
+ payments = [ Payment.new(5), Payment.new(15), Payment.new(10), Payment.new(nil) ]
38
+ lambda{ payments.sum(&:price) }.should raise_error(TypeError)
39
+ payments.sum{|p| p.price.to_i * 2 }.should == 60
40
+ end
41
+
42
+ it 'handles empty sums' do
43
+ [].sum .should == 0
44
+ [].sum{|i| i }.should == 0
45
+ [].sum(Payment.new(0)).should == Payment.new(0)
46
+ end
47
+
48
+ it 'behaves the same on ranges' do
49
+ (1..4).sum{|i| i * 2 }.should == 20
50
+ (1..4).sum .should == 10
51
+ (1..4.5).sum .should == 10
52
+ (1...4).sum .should == 6
53
+ ('a'..'c').sum .should == 'abc'
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,70 @@
1
+ require File.dirname(__FILE__)+'/../spec_helper'
2
+ require 'gorillib/hash/compact'
3
+
4
+ describe Hash do
5
+ describe '#compact' do
6
+ it 'scrubs nil' do
7
+ hsh = { 1 => nil }
8
+ hsh.compact.should == {}
9
+ hsh.length.should == 1
10
+ end
11
+
12
+ it 'does not scrub false, {} or ""' do
13
+ hsh = { 1 => nil, 2 => false, 3 => {}, 4 => "" }
14
+ hsh.compact.should == { 2 => false, 3 => {}, 4 => "" }
15
+ hsh.length.should == 4
16
+ end
17
+
18
+ it 'with values' do
19
+ { 1 => nil, nil => 2 }.compact.should == { nil => 2 }
20
+ { 1 => nil, 2 => :val_2, 3 => {}, 4 => :val_4}.compact.should == { 2 => :val_2, 3 => {}, 4 => :val_4 }
21
+ end
22
+ end
23
+
24
+ describe '#compact!' do
25
+ it 'scrubs nil' do
26
+ hsh = { 1 => nil }
27
+ hsh.compact!.should == {}
28
+ hsh.length.should == 0
29
+ end
30
+
31
+ it 'does not scrub false, {} or ""' do
32
+ hsh = { 1 => nil, 2 => false, 3 => {}, 4 => "" }
33
+ hsh.compact!.should == { 2 => false, 3 => {}, 4 => "" }
34
+ hsh.length.should == 3
35
+ end
36
+
37
+ it 'with values' do
38
+ { 1 => nil, nil => 2 }.compact!.should == { nil => 2 }
39
+ { 1 => nil, 2 => :val_2, 3 => {}, 4 => :val_4}.compact!.should == { 2 => :val_2, 3 => {}, 4 => :val_4 }
40
+ end
41
+ end
42
+
43
+ describe '#compact_blank' do
44
+ it 'when empty' do
45
+ [ { 1 => nil}, { 1 => nil, 2 => false, 3 => {}, 4 => ""} ].each do |hsh|
46
+ hsh.compact_blank.should == {}
47
+ hsh.length.should_not == 0
48
+ end
49
+ end
50
+
51
+ it 'with values' do
52
+ { 1 => nil, nil => 2 }.compact_blank.should == { nil => 2 }
53
+ { 1 => nil, 2 => :val_2, 3 => {}, 4 => :val_4}.compact_blank.should == { 2 => :val_2, 4 => :val_4 }
54
+ end
55
+ end
56
+
57
+ describe '#compact_blank!' do
58
+ it 'when empty' do
59
+ [ { 1 => nil}, { 1 => nil, 2 => false, 3 => {}, 4 => ""} ].each do |hsh|
60
+ hsh.compact_blank!.should == {}
61
+ hsh.length.should == 0
62
+ end
63
+ end
64
+
65
+ it 'with values' do
66
+ { 1 => nil, nil => 2 }.compact_blank!.should == { nil => 2 }
67
+ { 1 => nil, 2 => :val_2, 3 => {}, 4 => :val_4}.compact_blank!.should == { 2 => :val_2, 4 => :val_4 }
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,37 @@
1
+ require File.dirname(__FILE__)+'/../spec_helper'
2
+ require 'gorillib/hash/deep_compact'
3
+ require 'gorillib/array/deep_compact'
4
+
5
+ describe Hash do
6
+ describe 'array/deep_compact and hash/deep_compact' do
7
+ it "should respond to the method deep_compact!" do
8
+ { }.should respond_to :deep_compact!
9
+ end
10
+
11
+ it "should return nil if all values evaluate as blank" do
12
+ { :a => nil, :b => "", :c => [], :d => {} }.deep_compact!.should == {}
13
+ end
14
+
15
+ it "should return a hash with all blank values removed recursively" do
16
+ @test_hash = {:e=>["", nil, [], {}, "foo", { :a=> [nil, {}, { :c=> ["","",[]] } ], :b => nil }]}
17
+ @test_hash.deep_compact!.should == {:e=>["foo"]}
18
+ end
19
+ end
20
+ end
21
+
22
+ describe Array do
23
+ describe 'array/deep_compact and hash/deep_compact' do
24
+ it "should respond to the method deep_compact!" do
25
+ [ ].should respond_to :deep_compact!
26
+ end
27
+
28
+ it "should return nil if all values evaluate as blank" do
29
+ [nil, '', { }, []].deep_compact!.should == []
30
+ end
31
+
32
+ it "should return a hash with all blank values removed recursively" do
33
+ @test_arr = ["", nil, [], {}, "foo", { :a=> [nil, {}, { :c=> ["","",[]] } ], :b => nil }]
34
+ @test_arr.deep_compact!.should == ["foo"]
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,117 @@
1
+ require File.dirname(__FILE__)+'/../spec_helper'
2
+ require 'gorillib/hash/deep_merge'
3
+
4
+ describe Hash do
5
+ describe '#deep_merge' do
6
+ before do
7
+ @hash_1 =
8
+ { :a => 1, :b => "b", :c => { :val => "val", :arr => ['hi'], :hsh => { :d1 => "d1" } } }
9
+ end
10
+
11
+ it 'merges, replacing values on the left' do
12
+ @hash_1.deep_merge(
13
+ { :a => 1, :c => { :val => 2, } }).should ==
14
+ { :a => 1, :b => "b", :c => { :val => 2, :arr => ['hi'], :hsh => { :d1 => "d1" } } }
15
+ @hash_1.should ==
16
+ { :a => 1, :b => "b", :c => { :val => "val", :arr => ['hi'], :hsh => { :d1 => "d1" } } }
17
+ end
18
+
19
+ it 'merges, merging hashes where they meet' do
20
+ @hash_1.deep_merge(
21
+ { :a => 1, :c => { :val => 2, :hsh => { :d2 => "d2" } } }).should ==
22
+ { :a => 1, :b => "b", :c => { :val => 2, :arr => ['hi'], :hsh => { :d1 => "d1", :d2 => "d2" } } }
23
+ @hash_1.should ==
24
+ { :a => 1, :b => "b", :c => { :val => "val", :arr => ['hi'], :hsh => { :d1 => "d1" } } }
25
+ end
26
+
27
+ it 'merges, replacing hash on left with value on right' do
28
+ @hash_1.deep_merge(
29
+ { :a => 1, :c => { :hsh => :val } }).should ==
30
+ { :a => 1, :b => "b", :c => { :val => "val", :arr => ['hi'], :hsh => :val } }
31
+ @hash_1.should ==
32
+ { :a => 1, :b => "b", :c => { :val => "val", :arr => ['hi'], :hsh => { :d1 => "d1" } } }
33
+ end
34
+
35
+ it 'merges, replacing val on left with hash on right' do
36
+ @hash_1.deep_merge(
37
+ { :a => 1, :c => { :val => {}, } }).should ==
38
+ { :a => 1, :b => "b", :c => { :val => {}, :arr => ['hi'], :hsh => { :d1 => "d1" } } }
39
+ @hash_1.should ==
40
+ { :a => 1, :b => "b", :c => { :val => "val", :arr => ['hi'], :hsh => { :d1 => "d1" } } }
41
+ end
42
+
43
+ it 'merges, replacing array on left with array on right without merging' do
44
+ @hash_1.deep_merge(
45
+ { :a => 1, :c => { :arr => ['whatevs'] } }).should ==
46
+ { :a => 1, :b => "b", :c => { :val => "val", :arr => ['whatevs'], :hsh => { :d1 => "d1" } } }
47
+ @hash_1.should ==
48
+ { :a => 1, :b => "b", :c => { :val => "val", :arr => ['hi'], :hsh => { :d1 => "d1" } } }
49
+ end
50
+ end
51
+
52
+ describe '#deep_merge!' do
53
+ before do
54
+ @hash_1 = {
55
+ :a => 1, :b => "b", :c => { :val => "val", :arr => ['hi'], :hsh => { :d1 => "d1" } } }
56
+ end
57
+
58
+ it 'merges, replacing values on the left' do
59
+ @hash_1.deep_merge!(
60
+ { :a => 1, :c => { :val => 2, } }).should ==
61
+ { :a => 1, :b => "b", :c => { :val => 2, :arr => ['hi'], :hsh => { :d1 => "d1" } } }
62
+ @hash_1.should ==
63
+ { :a => 1, :b => "b", :c => { :val => 2, :arr => ['hi'], :hsh => { :d1 => "d1" } } }
64
+ end
65
+
66
+ it 'merges, merging hashes where they meet' do
67
+ @hash_1.deep_merge!(
68
+ { :a => 1, :c => { :val => 2, :hsh => { :d2 => "d2" } } }).should ==
69
+ { :a => 1, :b => "b", :c => { :val => 2, :arr => ['hi'], :hsh => { :d1 => "d1", :d2 => "d2" } } }
70
+ @hash_1.should ==
71
+ { :a => 1, :b => "b", :c => { :val => 2, :arr => ['hi'], :hsh => { :d1 => "d1", :d2 => "d2" } } }
72
+ end
73
+
74
+ it 'merges, replacing hash on left with value on right' do
75
+ @hash_1.deep_merge!(
76
+ { :a => 1, :c => { :hsh => :val } }).should ==
77
+ { :a => 1, :b => "b", :c => { :val => "val", :arr => ['hi'], :hsh => :val } }
78
+ @hash_1.should ==
79
+ { :a => 1, :b => "b", :c => { :val => "val", :arr => ['hi'], :hsh => :val } }
80
+ end
81
+
82
+ it 'merges, replacing val on left with hash on right' do
83
+ @hash_1.deep_merge!(
84
+ { :a => 1, :c => { :val => {}, } }).should ==
85
+ { :a => 1, :b => "b", :c => { :val => {}, :arr => ['hi'], :hsh => { :d1 => "d1" } } }
86
+ @hash_1.should ==
87
+ { :a => 1, :b => "b", :c => { :val => {}, :arr => ['hi'], :hsh => { :d1 => "d1" } } }
88
+ end
89
+
90
+ it 'merges, replacing array on left with array on right without merging' do
91
+ @hash_1.deep_merge!(
92
+ { :a => 1, :c => { :arr => ['whatevs'] } }).should ==
93
+ { :a => 1, :b => "b", :c => { :val => "val", :arr => ['whatevs'], :hsh => { :d1 => "d1" } } }
94
+ @hash_1.should ==
95
+ { :a => 1, :b => "b", :c => { :val => "val", :arr => ['whatevs'], :hsh => { :d1 => "d1" } } }
96
+ end
97
+ end
98
+
99
+
100
+
101
+ describe '#deep_dup' do
102
+ # def test_deep_dup
103
+ # hash = { :a => { :b => 'b' } }
104
+ # dup = hash.deep_dup
105
+ # dup[:a][:c] = 'c'
106
+ # assert_equal nil, hash[:a][:c]
107
+ # assert_equal 'c', dup[:a][:c]
108
+ # end
109
+ #
110
+ # def test_deep_dup_initialize
111
+ # zero_hash = Hash.new 0
112
+ # hash = { :a => zero_hash }
113
+ # dup = hash.deep_dup
114
+ # assert_equal 0, dup[:a][44]
115
+ # end
116
+ end
117
+ end