Skip to content

Commit 27f2c00

Browse files
committed
Create a deep dupe method and use it for facts
1 parent 1c82b20 commit 27f2c00

File tree

3 files changed

+47
-5
lines changed

3 files changed

+47
-5
lines changed

lib/octocatalog-diff/facts.rb

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,9 @@ class Facts
1818
def initialize(options = {}, facts = nil)
1919
@node = options.fetch(:node, '')
2020
@timestamp = false
21-
@options = OctocatalogDiff::Util::Util.safe_dup(options)
21+
@options = options.dup
2222
if facts
23-
@facts = {}
24-
facts.each { |k, v| @facts[k] = OctocatalogDiff::Util::Util.safe_dup(v) }
23+
@facts = OctocatalogDiff::Util::Util.deep_dup(facts)
2524
else
2625
case options[:backend]
2726
when :json
@@ -33,8 +32,7 @@ def initialize(options = {}, facts = nil)
3332
else
3433
raise ArgumentError, 'Invalid fact source backend'
3534
end
36-
@facts = {}
37-
@orig_facts.each { |k, v| @facts[k] = OctocatalogDiff::Util::Util.safe_dup(v) }
35+
@facts = OctocatalogDiff::Util::Util.deep_dup(@orig_facts)
3836
end
3937
end
4038

lib/octocatalog-diff/util/util.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,29 @@ def self.object_is_any_of?(object, classes)
2020
# Utility Method!
2121
# `.dup` can't be called on certain objects (Fixnum for example). This
2222
# method returns the original object if it can't be duplicated.
23+
# @param object [?] Object to consider
24+
# @return [?] Duplicated object if possible, otherwise the original object
2325
def self.safe_dup(object)
2426
object.dup
2527
rescue TypeError
2628
object
2729
end
30+
31+
# Utility Method!
32+
# This does a "deep" duplication via recursion. Handles hashes and arrays.
33+
# @param object [?] Object to consider
34+
# @return [?] Duplicated object
35+
def self.deep_dup(object)
36+
if object.is_a?(Hash)
37+
result = {}
38+
object.each { |k, v| result[k] = deep_dup(v) }
39+
result
40+
elsif object.is_a?(Array)
41+
object.map { |ele| deep_dup(ele) }
42+
else
43+
safe_dup(object)
44+
end
45+
end
2846
end
2947
end
3048
end

spec/octocatalog-diff/tests/util/util_spec.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,30 @@
5858
expect(object.object_id).not_to eq(result.object_id)
5959
end
6060
end
61+
62+
describe '#deep_dup' do
63+
it 'should dupe a hash' do
64+
hash1 = { 'foo' => 'bar' }
65+
hash2 = { 'baz' => hash1 }
66+
hash3 = { 'xxx' => hash2 }
67+
result = described_class.deep_dup(hash3)
68+
expect(result['xxx']).to eq(hash2)
69+
expect(result['xxx'].object_id).not_to eq(hash2.object_id)
70+
end
71+
72+
it 'should dupe an array' do
73+
array1 = %w[foo bar baz]
74+
array2 = ['foo', array1, 'baz']
75+
array3 = ['foo', array2, 'baz']
76+
result = described_class.deep_dup(array3)
77+
expect(result[1]).to eq(array2)
78+
expect(result[1].object_id).not_to eq(array2.object_id)
79+
end
80+
81+
it 'should dupe a string' do
82+
obj = 'Hello there'
83+
result = described_class.deep_dup(obj)
84+
expect(result).to eq(obj)
85+
end
86+
end
6187
end

0 commit comments

Comments
 (0)