easy_diff 0.0.7 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/README.rdoc +93 -7
- data/VERSION +1 -1
- data/lib/easy_diff/core.rb +47 -26
- data/spec/easy_diff_spec.rb +42 -160
- data/spec/test_data.yml +239 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YjI1YzlmNmU5NDk3YzBhMWVmNjIzMDI0YTc2NDM0ZDU0ZmFiZTM4Mg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MjhiNTJhNDBjZjRmMmYyMzkxNDY3YWI5YWFkODEwNWQ4ZTkyMWZkNg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YzU3NDkzYTRjN2E5OWZjZTNmYWQ2MGVjZjg2ZWJhZjk5NmVhMzYzMjRiYmM2
|
10
|
+
ZDM4YWRmNWM0MzUzOWY0ZTI2YmFkNzU0ZGZmNDA2OGFmMWQyOTdiOTQ1MzVl
|
11
|
+
ZTI3ZTlmMDdmZTFiY2E3NGFmODY4MDliNzFjMzEwNDZlMzkyOGU=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NTdjZDE4ZmUwNmQyZDczOGNjYTYzMzY4NDVhZmM2MzU4NzQ5YmE4MDYyZTYz
|
14
|
+
NjliMjg5MGVhZGMxM2QxNGJkMWQyOGNiNGVmMDJiNTYyNjVjYTQyMjQ3NTBm
|
15
|
+
M2Y5MGNkZjM4NWY2MWMzMDRhYTQ5OWIzMTU0ZjZiN2IxZDkzZjQ=
|
data/README.rdoc
CHANGED
@@ -1,19 +1,104 @@
|
|
1
1
|
= easy_diff
|
2
2
|
|
3
3
|
Easy Diff enhances the functionality of Hash, allowing recursive diff, merge, and unmerge of arbitrarily constructed hashes.
|
4
|
-
This is perfect for people who need to do diffs on not only plain text files but also data as Hash or JSON objects.
|
5
|
-
is included with diff and merge to more easily allow versioning of arbitrary data.
|
4
|
+
This is perfect for people who need to do diffs on not only plain text files but also data as Hash or JSON objects.
|
5
|
+
Unmerge is included with diff and merge to more easily allow versioning of arbitrary data.
|
6
|
+
|
7
|
+
There are a few caveats when using this gem:
|
8
|
+
* Unmerge should be used before merge to properly transform one hash into another. It will still work in most cases if you don't, but some edge cases will break.
|
9
|
+
* The order of elements within an array may be different when transforming one hash into another using unmerge and merge. There is currently no way to guarantee the order is untouched.
|
10
|
+
|
11
|
+
== Quick Start Example
|
12
|
+
|
13
|
+
old_data = {
|
14
|
+
:id => 1,
|
15
|
+
:name => "Foo",
|
16
|
+
:tags => [
|
17
|
+
"pretend",
|
18
|
+
"i",
|
19
|
+
"am",
|
20
|
+
"good",
|
21
|
+
"at",
|
22
|
+
"examples"
|
23
|
+
],
|
24
|
+
:config => {
|
25
|
+
:awesome => true,
|
26
|
+
:go_fast => false,
|
27
|
+
:actually_work => false
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
new_data = {
|
32
|
+
:id => 1,
|
33
|
+
:name => "Bar",
|
34
|
+
:description => "An awesome thingy I made."
|
35
|
+
:tags => [
|
36
|
+
"i",
|
37
|
+
"am",
|
38
|
+
"really",
|
39
|
+
"good"
|
40
|
+
]
|
41
|
+
:config => {
|
42
|
+
:awesome => true,
|
43
|
+
:go_fast => true,
|
44
|
+
:actually_work => true
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
# Diff the two hashes to get what was removed and what was added.
|
49
|
+
removed, added = old_data.easy_diff(new_data)
|
50
|
+
|
51
|
+
# removed will equal
|
52
|
+
# {
|
53
|
+
# :name => "Foo",
|
54
|
+
# :tags => [
|
55
|
+
# "pretend",
|
56
|
+
# "at",
|
57
|
+
# "examples"
|
58
|
+
# ],
|
59
|
+
# :config => {
|
60
|
+
# :go_fast => false,
|
61
|
+
# :actually_work => false
|
62
|
+
# }
|
63
|
+
# }
|
64
|
+
#
|
65
|
+
#
|
66
|
+
# added will equal
|
67
|
+
# {
|
68
|
+
# :name => "Bar",
|
69
|
+
# :description => "An awesome thingy I made.",
|
70
|
+
# :tags => [
|
71
|
+
# "really"
|
72
|
+
# ],
|
73
|
+
# :config => {
|
74
|
+
# :go_fast => true,
|
75
|
+
# :actually_work => true
|
76
|
+
# }
|
77
|
+
# }
|
78
|
+
|
79
|
+
# Now that we have the removed and added hashes, we can transform the old data into the new data or vice versa
|
80
|
+
transformed_old_data = old_data.easy_unmerge(added).easy_merge(removed)
|
81
|
+
transformed_new_data = new_data.easy_unmerge(removed).easy_merge(added)
|
82
|
+
|
83
|
+
# Let's see if there are any diffs between the transformed hashes and their respective counterparts
|
84
|
+
|
85
|
+
transformed_old_data.easy_diff(new_data)
|
86
|
+
# => [{}, {}] # Two empty hashes, indicating no diffs.
|
87
|
+
|
88
|
+
transformed_new_data.easy_diff(old_data)
|
89
|
+
# => [{}, {}] # Two empty hashes, indicating no diffs.
|
6
90
|
|
7
91
|
== Install
|
8
92
|
|
9
93
|
gem install easy_diff
|
10
94
|
|
11
|
-
==
|
95
|
+
== Methods
|
12
96
|
|
13
97
|
=== Hash#easy_diff
|
14
98
|
|
15
|
-
Takes another hash and recursively determines the differences between the
|
99
|
+
Takes another hash and recursively determines the differences between self and the other hash. This method returns two hashes.
|
16
100
|
The first contains what has to be removed from self to create the second hash. The second contains what has to be added.
|
101
|
+
When diffing arrays, the order of the arrays is ignored and only the contents are compared.
|
17
102
|
|
18
103
|
original = {
|
19
104
|
:tags => ['a', 'b', 'c'],
|
@@ -54,7 +139,7 @@ The first contains what has to be removed from self to create the second hash. T
|
|
54
139
|
|
55
140
|
=== Hash#easy_merge
|
56
141
|
|
57
|
-
Takes a hash and recursively merges it with self. Arrays are merged by
|
142
|
+
Takes a hash and recursively merges it with self. Arrays are merged by concatenation.
|
58
143
|
|
59
144
|
Using Hash#easy_merge! will modify self instead of returning a new hash.
|
60
145
|
|
@@ -90,8 +175,9 @@ Using Hash#easy_merge! will modify self instead of returning a new hash.
|
|
90
175
|
|
91
176
|
=== Hash#easy_unmerge
|
92
177
|
|
93
|
-
Takes a hash and recursively unmerges it with self.
|
94
|
-
|
178
|
+
Takes a hash and recursively unmerges it with self. Unmerging means it will remove all matching values from the hash.
|
179
|
+
Arrays will be unmerged by removing matching values in a non-greedy manner (i.e. [1, 1, 1] unmerged with [1] is [1, 1] instead of []).
|
180
|
+
|
95
181
|
Using Hash#easy_unmerge! will modify self instead of returning a new hash.
|
96
182
|
|
97
183
|
original = {
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
1.0.0
|
data/lib/easy_diff/core.rb
CHANGED
@@ -6,61 +6,63 @@ module EasyDiff
|
|
6
6
|
|
7
7
|
if original.nil?
|
8
8
|
added = modified.safe_dup
|
9
|
+
|
9
10
|
elsif modified.nil?
|
10
11
|
removed = original.safe_dup
|
12
|
+
|
11
13
|
elsif original.is_a?(Hash) && modified.is_a?(Hash)
|
12
14
|
removed = {}
|
13
15
|
added = {}
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
|
17
|
+
keys_in_common = original.keys & modified.keys
|
18
|
+
keys_removed = original.keys - modified.keys
|
19
|
+
keys_added = modified.keys - original.keys
|
20
|
+
|
19
21
|
keys_removed.each{ |key| removed[key] = original[key].safe_dup }
|
20
22
|
keys_added.each{ |key| added[key] = modified[key].safe_dup }
|
23
|
+
|
21
24
|
keys_in_common.each do |key|
|
22
25
|
r, a = easy_diff original[key], modified[key]
|
23
|
-
|
24
|
-
|
26
|
+
unless _blank?(r) && _blank?(a)
|
27
|
+
removed[key] = r
|
28
|
+
added[key] = a
|
29
|
+
end
|
25
30
|
end
|
31
|
+
|
26
32
|
elsif original.is_a?(Array) && modified.is_a?(Array)
|
27
|
-
removed = original
|
28
|
-
added = modified
|
33
|
+
removed = subtract_arrays(original, modified)
|
34
|
+
added = subtract_arrays(modified, original)
|
35
|
+
|
29
36
|
elsif original != modified
|
30
37
|
removed = original
|
31
38
|
added = modified
|
32
39
|
end
|
40
|
+
|
33
41
|
return removed, added
|
34
42
|
end
|
35
43
|
|
36
44
|
def self.easy_unmerge!(original, removed)
|
37
45
|
if original.is_a?(Hash) && removed.is_a?(Hash)
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
46
|
+
keys_in_common = original.keys & removed.keys
|
47
|
+
keys_in_common.each do |key|
|
48
|
+
if original[key] == removed[key]
|
49
|
+
original.delete(key)
|
50
|
+
else
|
51
|
+
easy_unmerge!(original[key], removed[key])
|
52
|
+
end
|
53
|
+
end
|
42
54
|
elsif original.is_a?(Array) && removed.is_a?(Array)
|
43
|
-
original
|
44
|
-
original.sort_by! { |item|
|
45
|
-
item.is_a?(Hash) ? item.sort : item
|
46
|
-
}
|
47
|
-
elsif original == removed
|
48
|
-
original = nil
|
55
|
+
subtract_arrays!(original, removed)
|
49
56
|
end
|
50
57
|
original
|
51
58
|
end
|
52
59
|
|
53
60
|
def self.easy_merge!(original, added)
|
54
|
-
if added.
|
55
|
-
return original
|
56
|
-
elsif original.is_a?(Hash) && added.is_a?(Hash)
|
61
|
+
if original.is_a?(Hash) && added.is_a?(Hash)
|
57
62
|
added_keys = added.keys
|
58
63
|
added_keys.each{ |key| original[key] = easy_merge!(original[key], added[key])}
|
59
64
|
elsif original.is_a?(Array) && added.is_a?(Array)
|
60
|
-
original
|
61
|
-
original.sort_by! { |item|
|
62
|
-
item.is_a?(Hash) ? item.sort : item
|
63
|
-
}
|
65
|
+
original += added
|
64
66
|
else
|
65
67
|
original = added.safe_dup
|
66
68
|
end
|
@@ -71,6 +73,7 @@ module EasyDiff
|
|
71
73
|
Marshal::load(Marshal.dump(original))
|
72
74
|
end
|
73
75
|
|
76
|
+
# Can't use regular empty? because that affects strings.
|
74
77
|
def self._blank?(obj)
|
75
78
|
if obj.is_a?(Hash) || obj.is_a?(Array)
|
76
79
|
obj.empty?
|
@@ -78,5 +81,23 @@ module EasyDiff
|
|
78
81
|
obj.nil?
|
79
82
|
end
|
80
83
|
end
|
84
|
+
|
85
|
+
# Regular array difference does not handle duplicate values in the way that is needed for this library.
|
86
|
+
# Examples:
|
87
|
+
# subtract_arrays([1, 1, 2, 3], [1, 2]) => [1, 3]
|
88
|
+
# subtract_arrays([3, 3, 3, 4], [3, 4, 5]) => [3, 3]
|
89
|
+
# Shamelessly stolen from http://stackoverflow.com/questions/3852755/ruby-array-subtraction-without-removing-items-more-than-once
|
90
|
+
def self.subtract_arrays! arr1, arr2
|
91
|
+
counts = arr2.inject(Hash.new(0)) { |h, v| h[v] += 1; h }
|
92
|
+
arr1.reject! { |e| counts[e] -= 1 unless counts[e].zero? }
|
93
|
+
end
|
94
|
+
|
95
|
+
# Non-destructive version of above method.
|
96
|
+
def self.subtract_arrays arr1, arr2
|
97
|
+
cloned_arr1 = easy_clone(arr1)
|
98
|
+
subtract_arrays!(cloned_arr1, arr2)
|
99
|
+
|
100
|
+
cloned_arr1
|
101
|
+
end
|
81
102
|
end
|
82
103
|
end
|
data/spec/easy_diff_spec.rb
CHANGED
@@ -1,180 +1,62 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) +
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
|
2
|
+
require 'yaml'
|
2
3
|
|
3
4
|
describe EasyDiff do
|
4
|
-
before :each do
|
5
|
-
@original = {
|
6
|
-
:tags => ['a', 'b', 'c'],
|
7
|
-
:pos => {:x => '1', :y => '2'},
|
8
|
-
:some_str => "bla",
|
9
|
-
:some_int => 1,
|
10
|
-
:some_bool => false,
|
11
|
-
:extra_removed => "bye"
|
12
|
-
}
|
13
5
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
:some_str => "bla",
|
18
|
-
:some_int => 2,
|
19
|
-
:some_bool => true,
|
20
|
-
:extra_added => "hi"
|
21
|
-
}
|
6
|
+
let(:no_diffs) do
|
7
|
+
[{},{}]
|
8
|
+
end
|
22
9
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
:some_int => 1,
|
27
|
-
:some_bool => false,
|
28
|
-
:extra_removed => "bye"
|
10
|
+
it "should do a deep clone" do
|
11
|
+
original = {
|
12
|
+
"pos" => {:x => 1, :y => 2}
|
29
13
|
}
|
30
14
|
|
31
|
-
|
32
|
-
|
33
|
-
:pos => {:x => '3'},
|
34
|
-
:some_int => 2,
|
35
|
-
:some_bool => true,
|
36
|
-
:extra_added => "hi"
|
37
|
-
}
|
38
|
-
end
|
39
|
-
it "should compute easy_diff" do
|
40
|
-
removed, added = @original.easy_diff @modified
|
41
|
-
removed.should == @removed
|
42
|
-
added.should == @added
|
43
|
-
end
|
15
|
+
cloned = original.easy_clone
|
16
|
+
cloned.should == original
|
44
17
|
|
45
|
-
|
46
|
-
|
47
|
-
unmerged.should == {
|
48
|
-
:tags => ['b', 'c'],
|
49
|
-
:pos => {:y => '2'},
|
50
|
-
:some_str => "bla"
|
51
|
-
}
|
18
|
+
cloned["pos"].delete(:x)
|
19
|
+
cloned.should_not == original
|
52
20
|
end
|
53
21
|
|
54
|
-
|
55
|
-
|
56
|
-
merged.should == {
|
57
|
-
:tags => ['a', 'b', 'c', 'd'],
|
58
|
-
:pos => {:x => '3', :y => '2'},
|
59
|
-
:some_str => "bla",
|
60
|
-
:some_int => 2,
|
61
|
-
:some_bool => true,
|
62
|
-
:extra_removed => "bye",
|
63
|
-
:extra_added => "hi"
|
64
|
-
}
|
65
|
-
@original.should == {
|
66
|
-
:tags => ['a', 'b', 'c'],
|
67
|
-
:pos => {:x => '1', :y => '2'},
|
68
|
-
:some_str => "bla",
|
69
|
-
:some_int => 1,
|
70
|
-
:some_bool => false,
|
71
|
-
:extra_removed => "bye"
|
72
|
-
}
|
73
|
-
end
|
22
|
+
# Tests that are dependent on the inputted data. Please edit or add
|
23
|
+
# to the test_data.yml file if you have data that breaks the gem.
|
74
24
|
|
75
|
-
|
76
|
-
|
77
|
-
unmerged = @modified.easy_unmerge added
|
78
|
-
original = unmerged.easy_merge removed
|
79
|
-
original.should == @original
|
80
|
-
end
|
25
|
+
test_data_file = File.expand_path(File.dirname(__FILE__) + "/test_data.yml")
|
26
|
+
test_data = YAML.load_file test_data_file
|
81
27
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
cloned.should == {
|
88
|
-
:tags => ['a', 'b', 'c', 'd'],
|
89
|
-
:pos => {:x => '2', :y => '2'},
|
90
|
-
:some_str => "bla",
|
91
|
-
:some_int => 1,
|
92
|
-
:some_bool => false,
|
93
|
-
:extra_removed => "bye"
|
94
|
-
}
|
95
|
-
@original.should == {
|
96
|
-
:tags => ['a', 'b', 'c'],
|
97
|
-
:pos => {:x => '1', :y => '2'},
|
98
|
-
:some_str => "bla",
|
99
|
-
:some_int => 1,
|
100
|
-
:some_bool => false,
|
101
|
-
:extra_removed => "bye"
|
102
|
-
}
|
103
|
-
end
|
28
|
+
test_data.each do |test_case|
|
29
|
+
describe "handling #{test_case["name"]}" do
|
30
|
+
let(:original) do
|
31
|
+
test_case["original"]
|
32
|
+
end
|
104
33
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
@removed.delete :pos
|
109
|
-
@removed.delete :tags
|
110
|
-
@added.delete :pos
|
111
|
-
@added.delete :tags
|
112
|
-
removed, added = @original.easy_diff @modified
|
113
|
-
removed.should == @removed
|
114
|
-
added.should == @added
|
115
|
-
end
|
34
|
+
let(:modified) do
|
35
|
+
test_case["modified"]
|
36
|
+
end
|
116
37
|
|
117
|
-
|
118
|
-
|
119
|
-
@modified[:empty_hash] = {}
|
120
|
-
@removed[:empty_array] = []
|
121
|
-
@added[:empty_hash] = {}
|
122
|
-
removed, added = @original.easy_diff @modified
|
123
|
-
removed.should == @removed
|
124
|
-
added.should == @added
|
125
|
-
end
|
38
|
+
it "should compute easy_diff correctly" do
|
39
|
+
removed, added = original.easy_diff modified
|
126
40
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
removed, added = original.easy_diff modified
|
131
|
-
removed.should == {:possibly_empty_string => ""}
|
132
|
-
added.should == {:possibly_empty_string => "not empty"}
|
133
|
-
end
|
41
|
+
removed.should == test_case["expected_removed"]
|
42
|
+
added.should == test_case["expected_added"]
|
43
|
+
end
|
134
44
|
|
135
|
-
|
136
|
-
|
137
|
-
{
|
138
|
-
"key" => [
|
139
|
-
{"c" => "1"},
|
140
|
-
{"a" => "2"},
|
141
|
-
{"a" => "1"},
|
142
|
-
]
|
143
|
-
}
|
144
|
-
end
|
45
|
+
it "should be able to progress original hash to modified hash with no computed diffs" do
|
46
|
+
removed, added = original.easy_diff modified
|
145
47
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
"key" => [
|
156
|
-
{"a" => "1"},
|
157
|
-
{"a" => "2"},
|
158
|
-
{"b" => "2"},
|
159
|
-
{"c" => "1"},
|
160
|
-
]
|
161
|
-
}
|
162
|
-
end
|
48
|
+
progressed = original.easy_unmerge(removed).easy_merge(added)
|
49
|
+
|
50
|
+
modified.easy_diff(progressed).should == no_diffs
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should be able to reverse modified hash to original hash with no computed diffs" do
|
54
|
+
removed, added = original.easy_diff modified
|
55
|
+
|
56
|
+
reversed = modified.easy_unmerge(added).easy_merge(removed)
|
163
57
|
|
164
|
-
|
165
|
-
|
166
|
-
"key" => [
|
167
|
-
{"a" => "2"},
|
168
|
-
]
|
169
|
-
}
|
170
|
-
|
171
|
-
unmerged = original.easy_unmerge to_unmerge
|
172
|
-
unmerged.should == {
|
173
|
-
"key" => [
|
174
|
-
{"a" => "1"},
|
175
|
-
{"c" => "1"},
|
176
|
-
]
|
177
|
-
}
|
58
|
+
original.easy_diff(reversed).should == no_diffs
|
59
|
+
end
|
178
60
|
end
|
179
61
|
end
|
180
62
|
end
|
data/spec/test_data.yml
ADDED
@@ -0,0 +1,239 @@
|
|
1
|
+
---
|
2
|
+
- # Basic test cases on nested Hashes and Arrays
|
3
|
+
name: "simple cases with nested Hashes and Arrays"
|
4
|
+
original:
|
5
|
+
tags:
|
6
|
+
- "a"
|
7
|
+
- "b"
|
8
|
+
- "c"
|
9
|
+
pos:
|
10
|
+
x: "1"
|
11
|
+
y: "2"
|
12
|
+
some_str: "bla"
|
13
|
+
some_int: 1
|
14
|
+
some_bool: false
|
15
|
+
extra_removed: "bye"
|
16
|
+
modified:
|
17
|
+
tags:
|
18
|
+
- "b"
|
19
|
+
- "c"
|
20
|
+
- "d"
|
21
|
+
pos:
|
22
|
+
x: "3"
|
23
|
+
y: "2"
|
24
|
+
some_str: "bla"
|
25
|
+
some_int: 2
|
26
|
+
some_bool: true
|
27
|
+
extra_added: "hi"
|
28
|
+
expected_removed:
|
29
|
+
tags:
|
30
|
+
- "a"
|
31
|
+
pos:
|
32
|
+
x: "1"
|
33
|
+
some_int: 1
|
34
|
+
some_bool: false
|
35
|
+
extra_removed: "bye"
|
36
|
+
expected_added:
|
37
|
+
tags:
|
38
|
+
- "d"
|
39
|
+
pos:
|
40
|
+
x: "3"
|
41
|
+
some_int: 2
|
42
|
+
some_bool: true
|
43
|
+
extra_added: "hi"
|
44
|
+
|
45
|
+
- # Test case where Arrays have duplicate values
|
46
|
+
name: "Arrays with duplicate values"
|
47
|
+
original:
|
48
|
+
key:
|
49
|
+
- 1
|
50
|
+
- 1
|
51
|
+
- 1
|
52
|
+
- 2
|
53
|
+
- 3
|
54
|
+
- 4
|
55
|
+
modified:
|
56
|
+
key:
|
57
|
+
- 1
|
58
|
+
- 3
|
59
|
+
- 4
|
60
|
+
- 4
|
61
|
+
expected_removed:
|
62
|
+
key:
|
63
|
+
- 1
|
64
|
+
- 1
|
65
|
+
- 2
|
66
|
+
expected_added:
|
67
|
+
key:
|
68
|
+
- 4
|
69
|
+
|
70
|
+
- # Test case where nil values of Hashes are expected to be preserved
|
71
|
+
name: "Hashes with nil values"
|
72
|
+
original:
|
73
|
+
old_nil: ~
|
74
|
+
new_nil: "foo"
|
75
|
+
still_nil: ~
|
76
|
+
removed_nil: ~
|
77
|
+
modified:
|
78
|
+
old_nil: "bar"
|
79
|
+
new_nil: ~
|
80
|
+
still_nil: ~
|
81
|
+
added_nil: ~
|
82
|
+
expected_removed:
|
83
|
+
old_nil: ~
|
84
|
+
new_nil: "foo"
|
85
|
+
removed_nil: ~
|
86
|
+
expected_added:
|
87
|
+
old_nil: "bar"
|
88
|
+
new_nil: ~
|
89
|
+
added_nil: ~
|
90
|
+
|
91
|
+
- # Test case where an empty Hash is compared to a Hash with one nil
|
92
|
+
# value in it.
|
93
|
+
name: "an empty Hash being compared to a Hash with a nil value"
|
94
|
+
original: {}
|
95
|
+
modified:
|
96
|
+
key: ~
|
97
|
+
expected_removed: {}
|
98
|
+
expected_added:
|
99
|
+
key: ~
|
100
|
+
|
101
|
+
- # Test case where nil values of Arrays are expected to be preserved
|
102
|
+
name: "Arrays with nil values"
|
103
|
+
original:
|
104
|
+
key:
|
105
|
+
- 5
|
106
|
+
- "hi"
|
107
|
+
modified:
|
108
|
+
key:
|
109
|
+
- 5
|
110
|
+
- "hi"
|
111
|
+
- ~
|
112
|
+
expected_removed:
|
113
|
+
key: []
|
114
|
+
expected_added:
|
115
|
+
key:
|
116
|
+
- ~
|
117
|
+
|
118
|
+
- # Test case where an empty Array is compared to an Array with one
|
119
|
+
# nil value in it.
|
120
|
+
name: "an empty Array being compared to an Array with a nil value"
|
121
|
+
original:
|
122
|
+
key: []
|
123
|
+
modified:
|
124
|
+
key:
|
125
|
+
- ~
|
126
|
+
expected_removed:
|
127
|
+
key: []
|
128
|
+
expected_added:
|
129
|
+
key:
|
130
|
+
- ~
|
131
|
+
|
132
|
+
- # Test case where nested Hashes and Arrays that are identical are
|
133
|
+
# expected to not show up as empty Hashes and Arrays in diffs.
|
134
|
+
name: "matching nested Hashes and Arrays"
|
135
|
+
original:
|
136
|
+
hash:
|
137
|
+
foo: "bar"
|
138
|
+
array:
|
139
|
+
- 1
|
140
|
+
- 2
|
141
|
+
- 3
|
142
|
+
extra: "apples"
|
143
|
+
modified:
|
144
|
+
hash:
|
145
|
+
foo: "bar"
|
146
|
+
array:
|
147
|
+
- 1
|
148
|
+
- 2
|
149
|
+
- 3
|
150
|
+
extra: "oranges"
|
151
|
+
expected_removed:
|
152
|
+
extra: "apples"
|
153
|
+
expected_added:
|
154
|
+
extra: "oranges"
|
155
|
+
|
156
|
+
- # Test case where empty Hashes and Arrays that are added or removed
|
157
|
+
# are expected to show up in diffs.
|
158
|
+
name: "empty Hashes and Arrays"
|
159
|
+
original:
|
160
|
+
foo: "bar"
|
161
|
+
modified:
|
162
|
+
empty_hash: {}
|
163
|
+
empty_array: []
|
164
|
+
foo: "bar"
|
165
|
+
expected_removed: {}
|
166
|
+
expected_added:
|
167
|
+
empty_hash: {}
|
168
|
+
empty_array: []
|
169
|
+
|
170
|
+
-
|
171
|
+
name: "empty Strings"
|
172
|
+
original:
|
173
|
+
possibly_empty_string: ""
|
174
|
+
modified:
|
175
|
+
possibly_empty_string: "not empty"
|
176
|
+
expected_removed:
|
177
|
+
possibly_empty_string: ""
|
178
|
+
expected_added:
|
179
|
+
possibly_empty_string: "not empty"
|
180
|
+
|
181
|
+
- # Test case where Arrays containing Hashes are expected to not
|
182
|
+
# cause an error.
|
183
|
+
name: "Arrays containing Hashes"
|
184
|
+
original:
|
185
|
+
key:
|
186
|
+
-
|
187
|
+
c: "1"
|
188
|
+
-
|
189
|
+
a: "2"
|
190
|
+
-
|
191
|
+
a: "1"
|
192
|
+
modified:
|
193
|
+
key:
|
194
|
+
-
|
195
|
+
c: "1"
|
196
|
+
-
|
197
|
+
b: "2"
|
198
|
+
-
|
199
|
+
a: "1"
|
200
|
+
expected_removed:
|
201
|
+
key:
|
202
|
+
-
|
203
|
+
a: "2"
|
204
|
+
expected_added:
|
205
|
+
key:
|
206
|
+
-
|
207
|
+
b: "2"
|
208
|
+
|
209
|
+
- # Test case where Arrays containing Hashes with nils are expected
|
210
|
+
# to not cause an error.
|
211
|
+
name: "Arrays containing Hashes with nils"
|
212
|
+
original:
|
213
|
+
key:
|
214
|
+
-
|
215
|
+
a: "1"
|
216
|
+
b: "2"
|
217
|
+
-
|
218
|
+
a: ~
|
219
|
+
c: "2"
|
220
|
+
-
|
221
|
+
e: "5"
|
222
|
+
modified:
|
223
|
+
key:
|
224
|
+
-
|
225
|
+
a: "1"
|
226
|
+
b: "2"
|
227
|
+
-
|
228
|
+
a: ~
|
229
|
+
c: "2"
|
230
|
+
-
|
231
|
+
d: "4"
|
232
|
+
expected_removed:
|
233
|
+
key:
|
234
|
+
-
|
235
|
+
e: "5"
|
236
|
+
expected_added:
|
237
|
+
key:
|
238
|
+
-
|
239
|
+
d: "4"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: easy_diff
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Abner Qian
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-01-
|
11
|
+
date: 2016-01-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -92,6 +92,7 @@ files:
|
|
92
92
|
- lib/easy_diff/safe_dup.rb
|
93
93
|
- spec/easy_diff_spec.rb
|
94
94
|
- spec/spec_helper.rb
|
95
|
+
- spec/test_data.yml
|
95
96
|
homepage: http://github.com/Blargel/easy_diff
|
96
97
|
licenses:
|
97
98
|
- MIT
|