canon 0.2.1 → 0.2.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bfa3648b7c5308716c22fbdc377d875dc60d479eb0e376cfe347eb02a279d3d7
4
- data.tar.gz: 87024447cc6a13eaa8cb9d1edf91d360e35d2e6cb5a1f2b7035c067050fae24a
3
+ metadata.gz: f2d050730d102cb224140f806e5b56634cdb98a16206301b0773d310dec582b9
4
+ data.tar.gz: 0b3bbf793abcfc9c3dd96a8c935260f4cf3360c7ee326e65ef8f165c48421f77
5
5
  SHA512:
6
- metadata.gz: 6299802984ef5bab4c658c534105491f853c9d6cd297a5df49e5f8c83e0b36d1b01d140c1ea510002cf2916f3902035e764dcd589e4e01c5eec10c4ba76fda28
7
- data.tar.gz: 42e73a1c3f80942d7ad102187b8a19148eb8a4046539eabb45561a716711fa3a51ea228e7bc372b4f675f4777db9ad964ed6c4873c19a5be9dc375af8639d92d
6
+ metadata.gz: 69b187c69b2aee23b1c1763504a33b226347ccbaaaab92d228d2a70da7d1f94f7160fb84b67356001de7de4e51155cc856104344fa795da8573ccf5e27af0633
7
+ data.tar.gz: 687fb81fbf5cafd49e8b1818e3dc641c44f62cf0f5d387829916ab270bdd4b9fffa56278e61d09f6bdabec52da1640ad59baf3c8d472d6248d1e0fce38209227
@@ -253,6 +253,19 @@ result = Canon::Comparison.equivalent?(xml1, xml2)
253
253
  - Comment differences tracked but don't affect equivalence
254
254
  - Default for HTML (comments are presentational)
255
255
 
256
+ ==== Element Structure
257
+
258
+ `element_structure` is a derived dimension — produced by comparators when children
259
+ differ structurally (insertions, deletions, name changes). It is not a user-configurable
260
+ match dimension but follows the same normative rule as all general dimensions:
261
+
262
+ * **Default (no explicit behavior)** → Normative
263
+ - Structural differences (added/removed/renamed elements) affect equivalence
264
+
265
+ * **`:ignore` behavior** → Informative
266
+ - Structural differences tracked but don't affect equivalence
267
+ - Useful for content-only comparisons where wrapper elements don't matter
268
+
256
269
  .Example: Comment handling
257
270
  ====
258
271
  [source,ruby]
@@ -405,6 +418,8 @@ The classification system uses three main classes:
405
418
  - `normative_dimension?(dimension)` - Is this dimension normative?
406
419
  - `affects_equivalence?(dimension)` - Does this dimension affect equivalence?
407
420
  - `supports_formatting_detection?(dimension)` - Can this dimension have formatting-only diffs?
421
+ - Normative rules: `structural_whitespace` requires `:strict` for normative status;
422
+ all other dimensions are normative unless behavior is `:ignore`
408
423
 
409
424
  * **`DiffClassifier`** - Orchestrates classification using the above
410
425
  - First checks `XmlSerializationFormatter` for serialization formatting
@@ -51,12 +51,13 @@ module Canon
51
51
  #
52
52
  # This is used by DiffClassifier to determine the normative flag.
53
53
  #
54
+ # Normative rules by dimension:
55
+ # - structural_whitespace: only :strict is normative (:normalize and :ignore are informative)
56
+ # - all other dimensions: normative unless behavior is :ignore
57
+ #
54
58
  # @param dimension [Symbol] The match dimension to check
55
59
  # @return [Boolean] true if normative, false if informative
56
60
  def normative_dimension?(dimension)
57
- # Element structure changes are ALWAYS normative
58
- return true if dimension == :element_structure
59
-
60
61
  # Structural whitespace with :normalize or :ignore behavior is INFORMATIVE
61
62
  # Only :strict mode makes whitespace normative
62
63
  if dimension == :structural_whitespace
@@ -64,7 +65,7 @@ module Canon
64
65
  return behavior == :strict
65
66
  end
66
67
 
67
- # For other dimensions, if behavior affects equivalence, it's normative
68
+ # For all other dimensions, normative if behavior affects equivalence
68
69
  affects_equivalence?(dimension)
69
70
  end
70
71
 
@@ -306,7 +306,11 @@ module Canon
306
306
  end
307
307
 
308
308
  # Default reason - can be overridden in subclasses
309
- "#{diff1} vs #{diff2}"
309
+ if diff1 == Canon::Comparison::MISSING_NODE && diff2 == Canon::Comparison::MISSING_NODE
310
+ "element structure mismatch (children differ)"
311
+ else
312
+ "#{diff1} vs #{diff2}"
313
+ end
310
314
  end
311
315
 
312
316
  # Build a clear reason message for attribute presence differences
@@ -85,7 +85,11 @@ module Canon
85
85
  end
86
86
 
87
87
  # Default reason
88
- "#{diff1} vs #{diff2}"
88
+ if diff1 == Canon::Comparison::MISSING_NODE && diff2 == Canon::Comparison::MISSING_NODE
89
+ "element structure mismatch (children differ)"
90
+ else
91
+ "#{diff1} vs #{diff2}"
92
+ end
89
93
  end
90
94
 
91
95
  # Enrich DiffNode with canonical path, serialized content, and attributes
@@ -631,7 +631,11 @@ differences)
631
631
  return "Attribute order changed: [#{attrs1.join(', ')}] → [#{attrs2.join(', ')}]"
632
632
  end
633
633
 
634
- "#{diff1} vs #{diff2}"
634
+ if diff1 == Canon::Comparison::MISSING_NODE && diff2 == Canon::Comparison::MISSING_NODE
635
+ "element structure mismatch (children differ)"
636
+ else
637
+ "#{diff1} vs #{diff2}"
638
+ end
635
639
  end
636
640
 
637
641
  # Build a clear reason message for attribute value differences
data/lib/canon/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Canon
4
- VERSION = "0.2.1"
4
+ VERSION = "0.2.2"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: canon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-04-16 00:00:00.000000000 Z
11
+ date: 2026-04-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: diff-lcs