hashdiff 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/README.md +4 -1
- data/changelog.md +4 -0
- data/lib/hashdiff/diff.rb +9 -8
- data/lib/hashdiff/patch.rb +6 -4
- data/lib/hashdiff/util.rb +4 -2
- data/lib/hashdiff/version.rb +1 -1
- data/spec/hashdiff/best_diff_spec.rb +9 -0
- data/spec/hashdiff/diff_spec.rb +8 -0
- data/spec/hashdiff/util_spec.rb +6 -0
- metadata +24 -9
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -25,7 +25,6 @@ HashDiff answers the question above in an opinionated approach:
|
|
25
25
|
* It compares Arrays using LCS(longest common subsequence) algorithm.
|
26
26
|
* It recoganize similar Hashes in Array using a similarity value(0 < similarity <= 1).
|
27
27
|
|
28
|
-
|
29
28
|
## Compatibility
|
30
29
|
|
31
30
|
HashDiff is tested against `1.9.2`, `1.9.3` and `ruby-head`. It should work on other versions as well.
|
@@ -86,6 +85,10 @@ unpatch example:
|
|
86
85
|
diff = HashDiff.diff(a, b) # diff two array is OK
|
87
86
|
HashDiff.unpatch!(b, diff).should == a
|
88
87
|
|
88
|
+
## Contributors
|
89
|
+
|
90
|
+
- @liufengyun
|
91
|
+
- @m-o-e
|
89
92
|
|
90
93
|
## License
|
91
94
|
|
data/changelog.md
CHANGED
data/lib/hashdiff/diff.rb
CHANGED
@@ -17,14 +17,14 @@ module HashDiff
|
|
17
17
|
# diff.should == [['-', 'x[0].c', 3], ['+', 'x[0].b', 2], ['-', 'x[1].y', 3], ['-', 'x[1]', {}]]
|
18
18
|
#
|
19
19
|
# @since 0.0.1
|
20
|
-
def self.best_diff(obj1, obj2)
|
21
|
-
diffs_1 = diff(obj1, obj2, "", 0.3)
|
20
|
+
def self.best_diff(obj1, obj2, delimiter='.')
|
21
|
+
diffs_1 = diff(obj1, obj2, "", 0.3, delimiter)
|
22
22
|
count_1 = count_diff diffs_1
|
23
23
|
|
24
|
-
diffs_2 = diff(obj1, obj2, "", 0.5)
|
24
|
+
diffs_2 = diff(obj1, obj2, "", 0.5, delimiter)
|
25
25
|
count_2 = count_diff diffs_2
|
26
26
|
|
27
|
-
diffs_3 = diff(obj1, obj2, "", 0.8)
|
27
|
+
diffs_3 = diff(obj1, obj2, "", 0.8, delimiter)
|
28
28
|
count_3 = count_diff diffs_3
|
29
29
|
|
30
30
|
count, diffs = count_1 < count_2 ? [count_1, diffs_1] : [count_2, diffs_2]
|
@@ -38,6 +38,7 @@ module HashDiff
|
|
38
38
|
# @param [float] similarity A value > 0 and <= 1.
|
39
39
|
# This parameter should be ignored in common usage.
|
40
40
|
# Similarity is only meaningful if there're similar objects in arrays. See {best_diff}.
|
41
|
+
# @param [String] delimiter Delimiter for returned property-string
|
41
42
|
#
|
42
43
|
# @return [Array] an array of changes.
|
43
44
|
# e.g. [[ '+', 'a.b', '45' ], [ '-', 'a.c', '5' ], [ '~', 'a.x', '45', '63']]
|
@@ -50,7 +51,7 @@ module HashDiff
|
|
50
51
|
# diff.should == [['-', 'b.b1', 1], ['-', 'b.b2', 2]]
|
51
52
|
#
|
52
53
|
# @since 0.0.1
|
53
|
-
def self.diff(obj1, obj2, prefix = "", similarity = 0.8)
|
54
|
+
def self.diff(obj1, obj2, prefix = "", similarity = 0.8, delimiter='.')
|
54
55
|
if obj1.nil? and obj2.nil?
|
55
56
|
return []
|
56
57
|
end
|
@@ -72,7 +73,7 @@ module HashDiff
|
|
72
73
|
changeset = diff_array(obj1, obj2, similarity) do |lcs|
|
73
74
|
# use a's index for similarity
|
74
75
|
lcs.each do |pair|
|
75
|
-
result.concat(diff(obj1[pair[0]], obj2[pair[1]], "#{prefix}[#{pair[0]}]", similarity))
|
76
|
+
result.concat(diff(obj1[pair[0]], obj2[pair[1]], "#{prefix}[#{pair[0]}]", similarity, delimiter))
|
76
77
|
end
|
77
78
|
end
|
78
79
|
|
@@ -84,7 +85,7 @@ module HashDiff
|
|
84
85
|
end
|
85
86
|
end
|
86
87
|
elsif obj1.is_a?(Hash)
|
87
|
-
prefix = prefix.empty? ? "" : "#{prefix}
|
88
|
+
prefix = prefix.empty? ? "" : "#{prefix}#{delimiter}"
|
88
89
|
|
89
90
|
deleted_keys = []
|
90
91
|
common_keys = []
|
@@ -101,7 +102,7 @@ module HashDiff
|
|
101
102
|
deleted_keys.each {|k| result << ['-', "#{prefix}#{k}", obj1[k]] }
|
102
103
|
|
103
104
|
# recursive comparison for common keys
|
104
|
-
common_keys.each {|k| result.concat(diff(obj1[k], obj2[k], "#{prefix}#{k}", similarity)) }
|
105
|
+
common_keys.each {|k| result.concat(diff(obj1[k], obj2[k], "#{prefix}#{k}", similarity, delimiter)) }
|
105
106
|
|
106
107
|
# added properties
|
107
108
|
obj2.each do |k, v|
|
data/lib/hashdiff/patch.rb
CHANGED
@@ -7,13 +7,14 @@ module HashDiff
|
|
7
7
|
#
|
8
8
|
# @param [Hash, Array] obj the object to be patchted, can be an Array of a Hash
|
9
9
|
# @param [Array] changes e.g. [[ '+', 'a.b', '45' ], [ '-', 'a.c', '5' ], [ '~', 'a.x', '45', '63']]
|
10
|
+
# @param [String] delimiter Property-string delimiter
|
10
11
|
#
|
11
12
|
# @return the object after patch
|
12
13
|
#
|
13
14
|
# @since 0.0.1
|
14
|
-
def self.patch!(obj, changes)
|
15
|
+
def self.patch!(obj, changes, delimiter='.')
|
15
16
|
changes.each do |change|
|
16
|
-
parts = decode_property_path(change[1])
|
17
|
+
parts = decode_property_path(change[1], delimiter)
|
17
18
|
last_part = parts.last
|
18
19
|
|
19
20
|
parent_node = node(obj, parts[0, parts.size-1])
|
@@ -42,13 +43,14 @@ module HashDiff
|
|
42
43
|
#
|
43
44
|
# @param [Hash, Array] obj the object to be unpatchted, can be an Array of a Hash
|
44
45
|
# @param [Array] changes e.g. [[ '+', 'a.b', '45' ], [ '-', 'a.c', '5' ], [ '~', 'a.x', '45', '63']]
|
46
|
+
# @param [String] delimiter Property-string delimiter
|
45
47
|
#
|
46
48
|
# @return the object after unpatch
|
47
49
|
#
|
48
50
|
# @since 0.0.1
|
49
|
-
def self.unpatch!(obj, changes)
|
51
|
+
def self.unpatch!(obj, changes, delimiter='.')
|
50
52
|
changes.reverse_each do |change|
|
51
|
-
parts = decode_property_path(change[1])
|
53
|
+
parts = decode_property_path(change[1], delimiter)
|
52
54
|
last_part = parts.last
|
53
55
|
|
54
56
|
parent_node = node(obj, parts[0, parts.size-1])
|
data/lib/hashdiff/util.rb
CHANGED
@@ -47,10 +47,12 @@ module HashDiff
|
|
47
47
|
# @private
|
48
48
|
#
|
49
49
|
# decode property path into an array
|
50
|
+
# @param [String] path Property-string
|
51
|
+
# @param [String] delimiter Property-string delimiter
|
50
52
|
#
|
51
53
|
# e.g. "a.b[3].c" => ['a', 'b', 3, 'c']
|
52
|
-
def self.decode_property_path(path)
|
53
|
-
parts = path.split(
|
54
|
+
def self.decode_property_path(path, delimiter='.')
|
55
|
+
parts = path.split(delimiter).collect do |part|
|
54
56
|
if part =~ /^(\w*)\[(\d+)\]$/
|
55
57
|
if $1.size > 0
|
56
58
|
[$1, $2.to_i]
|
data/lib/hashdiff/version.rb
CHANGED
@@ -9,6 +9,15 @@ describe HashDiff do
|
|
9
9
|
diff.should == [["-", "x[0].c", 3], ["+", "x[0].b", 2], ["-", "x[1]", {"y"=>3}]]
|
10
10
|
end
|
11
11
|
|
12
|
+
it "should use custom delimiter when provided" do
|
13
|
+
a = {'x' => [{'a' => 1, 'c' => 3, 'e' => 5}, {'y' => 3}]}
|
14
|
+
b = {'x' => [{'a' => 1, 'b' => 2, 'e' => 5}] }
|
15
|
+
|
16
|
+
diff = HashDiff.best_diff(a, b, "\t")
|
17
|
+
diff.should == [["-", "x[0]\tc", 3], ["+", "x[0]\tb", 2], ["-", "x[1]", {"y"=>3}]]
|
18
|
+
end
|
19
|
+
|
20
|
+
|
12
21
|
it "should be able to best diff array in hash" do
|
13
22
|
a = {"menu" => {
|
14
23
|
"id" => "file",
|
data/spec/hashdiff/diff_spec.rb
CHANGED
@@ -123,5 +123,13 @@ describe HashDiff do
|
|
123
123
|
diff.should == [["-", "[0].d", 4], ["-", "[1]", {"x"=>5, "y"=>6, "z"=>3}]]
|
124
124
|
end
|
125
125
|
|
126
|
+
it "should use custom delimiter when provided" do
|
127
|
+
a = [{'a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5}, {'x' => 5, 'y' => 6, 'z' => 3}, 3]
|
128
|
+
b = [{'a' => 1, 'b' => 2, 'c' => 3, 'e' => 5}, 3]
|
129
|
+
|
130
|
+
diff = HashDiff.diff(a, b, "", 0.8, "\t")
|
131
|
+
diff.should == [["-", "[0]\td", 4], ["-", "[1]", {"x"=>5, "y"=>6, "z"=>3}]]
|
132
|
+
end
|
133
|
+
|
126
134
|
end
|
127
135
|
|
data/spec/hashdiff/util_spec.rb
CHANGED
@@ -6,6 +6,12 @@ describe HashDiff do
|
|
6
6
|
decoded.should == ['a', 'b', 0, 'c', 'city', 5]
|
7
7
|
end
|
8
8
|
|
9
|
+
it "should be able to decode property path with custom delimiter" do
|
10
|
+
decoded = HashDiff.send(:decode_property_path, "a\tb[0]\tc\tcity[5]", "\t")
|
11
|
+
decoded.should == ['a', 'b', 0, 'c', 'city', 5]
|
12
|
+
end
|
13
|
+
|
14
|
+
|
9
15
|
it "should be able to tell similiar hash" do
|
10
16
|
a = {'a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5}
|
11
17
|
b = {'a' => 1, 'b' => 2, 'c' => 3, 'e' => 5}
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hashdiff
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-03-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,15 @@ dependencies:
|
|
21
21
|
version: '2.0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '2.0'
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: yard
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
35
|
- - ! '>='
|
@@ -32,10 +37,15 @@ dependencies:
|
|
32
37
|
version: '0'
|
33
38
|
type: :development
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
36
46
|
- !ruby/object:Gem::Dependency
|
37
47
|
name: bluecloth
|
38
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
39
49
|
none: false
|
40
50
|
requirements:
|
41
51
|
- - ! '>='
|
@@ -43,7 +53,12 @@ dependencies:
|
|
43
53
|
version: '0'
|
44
54
|
type: :development
|
45
55
|
prerelease: false
|
46
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
47
62
|
description: ! ' HashDiff is a diff lib to compute the smallest difference between
|
48
63
|
two hashes. '
|
49
64
|
email:
|
@@ -96,7 +111,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
96
111
|
version: '0'
|
97
112
|
requirements: []
|
98
113
|
rubyforge_project:
|
99
|
-
rubygems_version: 1.8.
|
114
|
+
rubygems_version: 1.8.24
|
100
115
|
signing_key:
|
101
116
|
specification_version: 3
|
102
117
|
summary: HashDiff is a diff lib to compute the smallest difference between two hashes.
|