hashdiff_sym 0.3.1
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.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rspec +1 -0
- data/.travis.yml +7 -0
- data/.yardopts +1 -0
- data/Gemfile +6 -0
- data/LICENSE +19 -0
- data/README.md +22 -0
- data/Rakefile +13 -0
- data/changelog.md +48 -0
- data/hashdiff_sym.gemspec +25 -0
- data/lib/hashdiff_sym/diff.rb +220 -0
- data/lib/hashdiff_sym/lcs.rb +69 -0
- data/lib/hashdiff_sym/patch.rb +84 -0
- data/lib/hashdiff_sym/util.rb +147 -0
- data/lib/hashdiff_sym/version.rb +3 -0
- data/lib/hashdiff_sym.rb +5 -0
- data/spec/hashdiff_sym/best_diff_spec.rb +65 -0
- data/spec/hashdiff_sym/diff_array_spec.rb +60 -0
- data/spec/hashdiff_sym/diff_spec.rb +263 -0
- data/spec/hashdiff_sym/lcs_spec.rb +75 -0
- data/spec/hashdiff_sym/patch_spec.rb +154 -0
- data/spec/hashdiff_sym/util_spec.rb +78 -0
- data/spec/spec_helper.rb +13 -0
- metadata +112 -0
@@ -0,0 +1,154 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe HashDiffSym do
|
4
|
+
it "it should be able to patch key addition" do
|
5
|
+
a = {"a"=>3, "c"=>11, "d"=>45, "e"=>100, "f"=>200}
|
6
|
+
b = {"a"=>3, "c"=>11, "d"=>45, "e"=>100, "f"=>200, "g"=>300}
|
7
|
+
diff = HashDiffSym.diff(a, b)
|
8
|
+
|
9
|
+
HashDiffSym.patch!(a, diff).should == b
|
10
|
+
|
11
|
+
a = {"a"=>3, "c"=>11, "d"=>45, "e"=>100, "f"=>200}
|
12
|
+
b = {"a"=>3, "c"=>11, "d"=>45, "e"=>100, "f"=>200, "g"=>300}
|
13
|
+
HashDiffSym.unpatch!(b, diff).should == a
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should be able to patch value type changes" do
|
17
|
+
a = {"a" => 3}
|
18
|
+
b = {"a" => {"a1" => 1, "a2" => 2}}
|
19
|
+
diff = HashDiffSym.diff(a, b)
|
20
|
+
|
21
|
+
HashDiffSym.patch!(a, diff).should == b
|
22
|
+
|
23
|
+
a = {"a" => 3}
|
24
|
+
b = {"a" => {"a1" => 1, "a2" => 2}}
|
25
|
+
HashDiffSym.unpatch!(b, diff).should == a
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should be able to patch value array <=> []" do
|
29
|
+
a = {"a" => 1, "b" => [1, 2]}
|
30
|
+
b = {"a" => 1, "b" => []}
|
31
|
+
diff = HashDiffSym.diff(a, b)
|
32
|
+
|
33
|
+
HashDiffSym.patch!(a, diff).should == b
|
34
|
+
|
35
|
+
a = {"a" => 1, "b" => [1, 2]}
|
36
|
+
b = {"a" => 1, "b" => []}
|
37
|
+
HashDiffSym.unpatch!(b, diff).should == a
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should be able to patch value array <=> nil" do
|
41
|
+
a = {"a" => 1, "b" => [1, 2]}
|
42
|
+
b = {"a" => 1, "b" => nil}
|
43
|
+
diff = HashDiffSym.diff(a, b)
|
44
|
+
|
45
|
+
HashDiffSym.patch!(a, diff).should == b
|
46
|
+
|
47
|
+
a = {"a" => 1, "b" => [1, 2]}
|
48
|
+
b = {"a" => 1, "b" => nil}
|
49
|
+
HashDiffSym.unpatch!(b, diff).should == a
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should be able to patch array value removal" do
|
53
|
+
a = {"a" => 1, "b" => [1, 2]}
|
54
|
+
b = {"a" => 1}
|
55
|
+
diff = HashDiffSym.diff(a, b)
|
56
|
+
|
57
|
+
HashDiffSym.patch!(a, diff).should == b
|
58
|
+
|
59
|
+
a = {"a" => 1, "b" => [1, 2]}
|
60
|
+
b = {"a" => 1}
|
61
|
+
HashDiffSym.unpatch!(b, diff).should == a
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should be able to patch array under hash key with non-word characters" do
|
65
|
+
a = {"a" => 1, "b-b" => [1, 2]}
|
66
|
+
b = {"a" => 1, "b-b" => [2, 1]}
|
67
|
+
diff = HashDiffSym.diff(a, b)
|
68
|
+
|
69
|
+
HashDiffSym.patch!(a, diff).should == b
|
70
|
+
|
71
|
+
a = {"a" => 1, "b-b" => [1, 2]}
|
72
|
+
b = {"a" => 1, "b-b" => [2, 1]}
|
73
|
+
HashDiffSym.unpatch!(b, diff).should == a
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should be able to patch hash value removal" do
|
77
|
+
a = {"a" => 1, "b" => {"b1" => 1, "b2" =>2}}
|
78
|
+
b = {"a" => 1}
|
79
|
+
diff = HashDiffSym.diff(a, b)
|
80
|
+
|
81
|
+
HashDiffSym.patch!(a, diff).should == b
|
82
|
+
|
83
|
+
a = {"a" => 1, "b" => {"b1" => 1, "b2" =>2}}
|
84
|
+
b = {"a" => 1}
|
85
|
+
HashDiffSym.unpatch!(b, diff).should == a
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should be able to patch value hash <=> {}" do
|
89
|
+
a = {"a" => 1, "b" => {"b1" => 1, "b2" =>2}}
|
90
|
+
b = {"a" => 1, "b" => {}}
|
91
|
+
diff = HashDiffSym.diff(a, b)
|
92
|
+
|
93
|
+
HashDiffSym.patch!(a, diff).should == b
|
94
|
+
|
95
|
+
a = {"a" => 1, "b" => {"b1" => 1, "b2" =>2}}
|
96
|
+
b = {"a" => 1, "b" => {}}
|
97
|
+
HashDiffSym.unpatch!(b, diff).should == a
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should be able to patch value hash <=> nil" do
|
101
|
+
a = {"a" => 1, "b" => {"b1" => 1, "b2" =>2}}
|
102
|
+
b = {"a" => 1, "b" => nil}
|
103
|
+
diff = HashDiffSym.diff(a, b)
|
104
|
+
|
105
|
+
HashDiffSym.patch!(a, diff).should == b
|
106
|
+
|
107
|
+
a = {"a" => 1, "b" => {"b1" => 1, "b2" =>2}}
|
108
|
+
b = {"a" => 1, "b" => nil}
|
109
|
+
HashDiffSym.unpatch!(b, diff).should == a
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should be able to patch value nil removal" do
|
113
|
+
a = {"a" => 1, "b" => nil}
|
114
|
+
b = {"a" => 1}
|
115
|
+
diff = HashDiffSym.diff(a, b)
|
116
|
+
|
117
|
+
HashDiffSym.patch!(a, diff).should == b
|
118
|
+
|
119
|
+
a = {"a" => 1, "b" => nil}
|
120
|
+
b = {"a" => 1}
|
121
|
+
HashDiffSym.unpatch!(b, diff).should == a
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should be able to patch similar objects between arrays" do
|
125
|
+
a = [{'a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5}, 3]
|
126
|
+
b = [1, {'a' => 1, 'b' => 2, 'c' => 3, 'e' => 5}]
|
127
|
+
|
128
|
+
diff = HashDiffSym.diff(a, b)
|
129
|
+
HashDiffSym.patch!(a, diff).should == b
|
130
|
+
|
131
|
+
a = [{'a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5}, 3]
|
132
|
+
b = [1, {'a' => 1, 'b' => 2, 'c' => 3, 'e' => 5}]
|
133
|
+
HashDiffSym.unpatch!(b, diff).should == a
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should be able to patch similar & equal objects between arrays" do
|
137
|
+
a = [{'a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5}, {'x' => 5, 'y' => 6, 'z' => 3}, 1]
|
138
|
+
b = [1, {'a' => 1, 'b' => 2, 'c' => 3, 'e' => 5}]
|
139
|
+
|
140
|
+
diff = HashDiffSym.diff(a, b)
|
141
|
+
HashDiffSym.patch!(a, diff).should == b
|
142
|
+
|
143
|
+
a = [{'a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5}, {'x' => 5, 'y' => 6, 'z' => 3}, 1]
|
144
|
+
b = [1, {'a' => 1, 'b' => 2, 'c' => 3, 'e' => 5}]
|
145
|
+
HashDiffSym.unpatch!(b, diff).should == a
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should patch hashes with symbols correctly" do
|
149
|
+
a = {a: 3}
|
150
|
+
b = {a: {a1: 1, a2: 2}}
|
151
|
+
diff = HashDiffSym.diff(a, b)
|
152
|
+
HashDiffSym.patch!(a, diff).should == b
|
153
|
+
end
|
154
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe HashDiffSym do
|
4
|
+
it "should be able to decode property path" do
|
5
|
+
decoded = HashDiffSym.send(:decode_property_path, "a.b[0].c.city[5]")
|
6
|
+
decoded.should == ['a', 'b', 0, 'c', 'city', 5]
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should be able to decode property path with custom delimiter" do
|
10
|
+
decoded = HashDiffSym.send(:decode_property_path, "a\tb[0]\tc\tcity[5]", "\t")
|
11
|
+
decoded.should == ['a', 'b', 0, 'c', 'city', 5]
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should be able to tell similiar hash" do
|
15
|
+
a = {'a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5}
|
16
|
+
b = {'a' => 1, 'b' => 2, 'c' => 3, 'e' => 5}
|
17
|
+
HashDiffSym.similar?(a, b).should be_truthy
|
18
|
+
HashDiffSym.similar?(a, b, :similarity => 1).should be_falsey
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should be able to tell similiar hash with values within tolerance" do
|
22
|
+
a = {'a' => 1.5, 'b' => 2.25, 'c' => 3, 'd' => 4, 'e' => 5}
|
23
|
+
b = {'a' => 1.503, 'b' => 2.22, 'c' => 3, 'e' => 5}
|
24
|
+
HashDiffSym.similar?(a, b, :numeric_tolerance => 0.05).should be_truthy
|
25
|
+
HashDiffSym.similar?(a, b).should be_falsey
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should be able to tell numbers and strings" do
|
29
|
+
HashDiffSym.similar?(1, 2).should be_falsey
|
30
|
+
HashDiffSym.similar?("a", "b").should be_falsey
|
31
|
+
HashDiffSym.similar?("a", [1, 2, 3]).should be_falsey
|
32
|
+
HashDiffSym.similar?(1, {'a' => 1, 'b' => 2, 'c' => 3, 'e' => 5}).should be_falsey
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should be able to tell true when similarity == 0.5" do
|
36
|
+
a = {"value" => "New1", "onclick" => "CreateNewDoc()"}
|
37
|
+
b = {"value" => "New", "onclick" => "CreateNewDoc()"}
|
38
|
+
|
39
|
+
HashDiffSym.similar?(a, b, :similarity => 0.5).should be_truthy
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should be able to tell false when similarity == 0.5" do
|
43
|
+
a = {"value" => "New1", "onclick" => "open()"}
|
44
|
+
b = {"value" => "New", "onclick" => "CreateNewDoc()"}
|
45
|
+
|
46
|
+
HashDiffSym.similar?(a, b, :similarity => 0.5).should be_falsey
|
47
|
+
end
|
48
|
+
|
49
|
+
describe '.compare_values' do
|
50
|
+
it "should compare numeric values exactly when no tolerance" do
|
51
|
+
expect(HashDiffSym.compare_values(10.004, 10.003)).to be_falsey
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should allow tolerance with numeric values" do
|
55
|
+
expect(HashDiffSym.compare_values(10.004, 10.003, :numeric_tolerance => 0.01)).to be_truthy
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should compare other objects with or without tolerance" do
|
59
|
+
expect(HashDiffSym.compare_values('hats', 'ninjas')).to be_falsey
|
60
|
+
expect(HashDiffSym.compare_values('hats', 'ninjas', :numeric_tolerance => 0.01)).to be_falsey
|
61
|
+
expect(HashDiffSym.compare_values('horse', 'horse')).to be_truthy
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should compare strings exactly by default' do
|
65
|
+
expect(HashDiffSym.compare_values(' horse', 'horse')).to be_falsey
|
66
|
+
expect(HashDiffSym.compare_values('horse', 'Horse')).to be_falsey
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should strip strings before comparing when requested' do
|
70
|
+
expect(HashDiffSym.compare_values(' horse', 'horse', :strip => true)).to be_truthy
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should ignore string case when requested" do
|
74
|
+
expect(HashDiffSym.compare_values('horse', 'Horse', :case_insensitive => true)).to be_truthy
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'rspec'
|
5
|
+
require 'rspec/autorun'
|
6
|
+
|
7
|
+
require 'hashdiff_sym'
|
8
|
+
|
9
|
+
RSpec.configure do |config|
|
10
|
+
config.mock_framework = :rspec
|
11
|
+
|
12
|
+
config.include RSpec::Matchers
|
13
|
+
end
|
metadata
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hashdiff_sym
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Liu Fengyun
|
8
|
+
- Alexander Morozov
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2016-08-02 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '2.0'
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '2.0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: yard
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: bluecloth
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
description: " HashDiffSym is a diff lib to compute the smallest difference between
|
57
|
+
two hashes. "
|
58
|
+
email:
|
59
|
+
- ntcomp12@gmail.com
|
60
|
+
executables: []
|
61
|
+
extensions: []
|
62
|
+
extra_rdoc_files: []
|
63
|
+
files:
|
64
|
+
- ".gitignore"
|
65
|
+
- ".rspec"
|
66
|
+
- ".travis.yml"
|
67
|
+
- ".yardopts"
|
68
|
+
- Gemfile
|
69
|
+
- LICENSE
|
70
|
+
- README.md
|
71
|
+
- Rakefile
|
72
|
+
- changelog.md
|
73
|
+
- hashdiff_sym.gemspec
|
74
|
+
- lib/hashdiff_sym.rb
|
75
|
+
- lib/hashdiff_sym/diff.rb
|
76
|
+
- lib/hashdiff_sym/lcs.rb
|
77
|
+
- lib/hashdiff_sym/patch.rb
|
78
|
+
- lib/hashdiff_sym/util.rb
|
79
|
+
- lib/hashdiff_sym/version.rb
|
80
|
+
- spec/hashdiff_sym/best_diff_spec.rb
|
81
|
+
- spec/hashdiff_sym/diff_array_spec.rb
|
82
|
+
- spec/hashdiff_sym/diff_spec.rb
|
83
|
+
- spec/hashdiff_sym/lcs_spec.rb
|
84
|
+
- spec/hashdiff_sym/patch_spec.rb
|
85
|
+
- spec/hashdiff_sym/util_spec.rb
|
86
|
+
- spec/spec_helper.rb
|
87
|
+
homepage: https://github.com/kengho/hashdiff_sym
|
88
|
+
licenses:
|
89
|
+
- MIT
|
90
|
+
metadata: {}
|
91
|
+
post_install_message:
|
92
|
+
rdoc_options: []
|
93
|
+
require_paths:
|
94
|
+
- lib
|
95
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: 1.8.7
|
100
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
requirements: []
|
106
|
+
rubyforge_project:
|
107
|
+
rubygems_version: 2.6.6
|
108
|
+
signing_key:
|
109
|
+
specification_version: 4
|
110
|
+
summary: HashDiffSym is a diff lib to compute the smallest difference between two
|
111
|
+
hashes.
|
112
|
+
test_files: []
|