canon 0.3.37 → 0.3.38
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 +4 -4
- data/lib/canon/comparison/ruby_object_comparator.rb +35 -11
- data/lib/canon/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dc55555287eb70fb4fc5201029aea89c2af55d8a9df26549d1d17b639a6de5de
|
|
4
|
+
data.tar.gz: 59ac3ba881495f29ee1355eda305da05d03d62a5611aa738404bf029f66d1721
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6b2d535b82b40ece128bea902b603b1b43c06c7bf4f40535f651e3b43c24674345de4e0c0767380fd6fc50d2986dc80ecf0e2c1b2d5286a7dd02524d65641920
|
|
7
|
+
data.tar.gz: '09af782d9c914502a54ca9b961448c89502bb20c3cffa93ec9268b7afc72099bcea2dcc2f7f8e36ccbf7fd6a6f8e3320ced5b7edfd67f7d70d0f5f95e7cf8d85'
|
|
@@ -29,9 +29,7 @@ module Canon
|
|
|
29
29
|
# difference exists (strict key_order compares insertion
|
|
30
30
|
# order, which keys == keys preserves). Most object pairs in
|
|
31
31
|
# similar documents hit this and skip the path-building walk.
|
|
32
|
-
|
|
33
|
-
return Comparison::EQUIVALENT
|
|
34
|
-
end
|
|
32
|
+
return Comparison::EQUIVALENT if deep_equal?(obj1, obj2)
|
|
35
33
|
|
|
36
34
|
case obj1
|
|
37
35
|
when Hash
|
|
@@ -68,8 +66,16 @@ module Canon
|
|
|
68
66
|
# Sort keys if order should be ignored (based on match options)
|
|
69
67
|
match_opts = opts[:match_opts]
|
|
70
68
|
if match_opts && match_opts[:key_order] != :strict
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
# Identical key arrays: one sort replaces two (the sorted
|
|
70
|
+
# forms are trivially equal, and the set algebra below
|
|
71
|
+
# degenerates — missing/extra empty, common = the sorted
|
|
72
|
+
# keys themselves).
|
|
73
|
+
if keys1 == keys2
|
|
74
|
+
keys1 = keys2 = keys1.sort_by(&:to_s)
|
|
75
|
+
else
|
|
76
|
+
keys1 = keys1.sort_by(&:to_s)
|
|
77
|
+
keys2 = keys2.sort_by(&:to_s)
|
|
78
|
+
end
|
|
73
79
|
elsif match_opts && match_opts[:key_order] == :strict
|
|
74
80
|
# Strict mode: key order matters
|
|
75
81
|
# Check if keys are in same order
|
|
@@ -85,8 +91,8 @@ module Canon
|
|
|
85
91
|
end
|
|
86
92
|
|
|
87
93
|
# Check for missing keys
|
|
88
|
-
missing_in_second = keys1 - keys2
|
|
89
|
-
missing_in_first = keys2 - keys1
|
|
94
|
+
missing_in_second = keys1 == keys2 ? EMPTY_KEYS : keys1 - keys2
|
|
95
|
+
missing_in_first = keys1 == keys2 ? EMPTY_KEYS : keys2 - keys1
|
|
90
96
|
|
|
91
97
|
missing_in_second.each do |key|
|
|
92
98
|
key_path = path.empty? ? key.to_s : "#{path}.#{key}"
|
|
@@ -102,13 +108,19 @@ module Canon
|
|
|
102
108
|
|
|
103
109
|
has_missing_keys = !missing_in_first.empty? || !missing_in_second.empty?
|
|
104
110
|
|
|
105
|
-
# Compare common keys
|
|
106
|
-
|
|
111
|
+
# Compare common keys. The path string is built lazily: deep-equal
|
|
112
|
+
# pairs (the overwhelming majority in similar documents) answer
|
|
113
|
+
# equivalent without ever needing it.
|
|
114
|
+
common_keys = keys1 == keys2 ? keys1 : keys1 & keys2
|
|
107
115
|
all_equivalent = true
|
|
108
116
|
common_keys.each do |key|
|
|
117
|
+
value1 = hash1[key]
|
|
118
|
+
value2 = hash2[key]
|
|
119
|
+
next if deep_equal?(value1, value2)
|
|
120
|
+
|
|
109
121
|
key_path = path.empty? ? key.to_s : "#{path}.#{key}"
|
|
110
|
-
result = compare_objects(
|
|
111
|
-
|
|
122
|
+
result = compare_objects(value1, value2, opts, differences,
|
|
123
|
+
key_path)
|
|
112
124
|
all_equivalent = false unless result == Comparison::EQUIVALENT
|
|
113
125
|
end
|
|
114
126
|
|
|
@@ -138,6 +150,8 @@ module Canon
|
|
|
138
150
|
all_equivalent = true
|
|
139
151
|
arr1.each_with_index do |elem1, index|
|
|
140
152
|
elem2 = arr2[index]
|
|
153
|
+
next if deep_equal?(elem1, elem2)
|
|
154
|
+
|
|
141
155
|
elem_path = "#{path}[#{index}]"
|
|
142
156
|
result = compare_objects(elem1, elem2, opts, differences,
|
|
143
157
|
elem_path)
|
|
@@ -166,6 +180,16 @@ module Canon
|
|
|
166
180
|
end
|
|
167
181
|
end
|
|
168
182
|
|
|
183
|
+
# Deep-equal with identical key order — compare_objects returns
|
|
184
|
+
# EQUIVALENT without consulting the path for such pairs, which
|
|
185
|
+
# is what makes lazy path construction in the hash/array walks
|
|
186
|
+
# behavior-identical.
|
|
187
|
+
def self.deep_equal?(obj1, obj2)
|
|
188
|
+
obj1 == obj2 && (!obj1.is_a?(Hash) || obj1.keys == obj2.keys)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
EMPTY_KEYS = [].freeze
|
|
192
|
+
|
|
169
193
|
# Add a Ruby object difference
|
|
170
194
|
#
|
|
171
195
|
# @param path [String] Path to the difference
|
data/lib/canon/version.rb
CHANGED