canon 0.2.11 → 0.2.12
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/.rubocop_todo.yml +12 -22
- data/Rakefile +5 -2
- data/lib/canon/cache.rb +3 -1
- data/lib/canon/cli.rb +0 -3
- data/lib/canon/commands/diff_command.rb +0 -6
- data/lib/canon/commands/format_command.rb +0 -4
- data/lib/canon/commands.rb +9 -0
- data/lib/canon/comparison/child_realignment.rb +0 -2
- data/lib/canon/comparison/compare_profile.rb +30 -36
- data/lib/canon/comparison/comparison_result.rb +0 -2
- data/lib/canon/comparison/diff_node_builder.rb +353 -0
- data/lib/canon/comparison/dimensions/dimension.rb +51 -0
- data/lib/canon/comparison/dimensions/dimension_set.rb +49 -0
- data/lib/canon/comparison/dimensions/registry.rb +101 -60
- data/lib/canon/comparison/dimensions.rb +15 -46
- data/lib/canon/comparison/html_comparator.rb +18 -141
- data/lib/canon/comparison/html_compare_profile.rb +15 -18
- data/lib/canon/comparison/json_comparator.rb +4 -165
- data/lib/canon/comparison/json_parser.rb +0 -2
- data/lib/canon/comparison/markup_comparator.rb +14 -210
- data/lib/canon/comparison/match_options/base_resolver.rb +18 -29
- data/lib/canon/comparison/match_options/json_resolver.rb +4 -28
- data/lib/canon/comparison/match_options/xml_resolver.rb +4 -45
- data/lib/canon/comparison/match_options/yaml_resolver.rb +4 -30
- data/lib/canon/comparison/match_options.rb +13 -88
- data/lib/canon/comparison/pipeline.rb +269 -0
- data/lib/canon/comparison/profile_definition.rb +0 -2
- data/lib/canon/comparison/ruby_object_comparator.rb +1 -1
- data/lib/canon/comparison/strategies/match_strategy_factory.rb +9 -58
- data/lib/canon/comparison/strategies/semantic_tree_match_strategy.rb +4 -11
- data/lib/canon/comparison/strategies.rb +16 -0
- data/lib/canon/comparison/xml_comparator/attribute_comparator.rb +0 -3
- data/lib/canon/comparison/xml_comparator/attribute_filter.rb +0 -3
- data/lib/canon/comparison/xml_comparator/child_comparison.rb +0 -6
- data/lib/canon/comparison/xml_comparator/namespace_comparator.rb +1 -6
- data/lib/canon/comparison/xml_comparator/node_parser.rb +0 -4
- data/lib/canon/comparison/xml_comparator.rb +4 -492
- data/lib/canon/comparison/xml_comparator_helpers.rb +21 -0
- data/lib/canon/comparison/xml_node_comparison.rb +4 -119
- data/lib/canon/comparison/yaml_comparator.rb +0 -3
- data/lib/canon/comparison.rb +143 -266
- data/lib/canon/config/config_dsl.rb +159 -0
- data/lib/canon/config/env_provider.rb +0 -3
- data/lib/canon/config/env_schema.rb +48 -58
- data/lib/canon/config/profile_loader.rb +0 -1
- data/lib/canon/config.rb +116 -468
- data/lib/canon/diff/diff_block_builder.rb +0 -2
- data/lib/canon/diff/diff_classifier.rb +0 -5
- data/lib/canon/diff/diff_context.rb +0 -2
- data/lib/canon/diff/diff_context_builder.rb +0 -2
- data/lib/canon/diff/diff_line_builder.rb +0 -3
- data/lib/canon/diff/diff_node_enricher.rb +0 -4
- data/lib/canon/diff/diff_node_mapper.rb +0 -4
- data/lib/canon/diff/diff_report_builder.rb +0 -4
- data/lib/canon/diff/formatting_detector.rb +0 -1
- data/lib/canon/diff/node_serializer.rb +0 -7
- data/lib/canon/diff.rb +39 -0
- data/lib/canon/diff_formatter/by_line/base_formatter.rb +4 -17
- data/lib/canon/diff_formatter/by_line/html_formatter.rb +7 -19
- data/lib/canon/diff_formatter/by_line/json_formatter.rb +0 -3
- data/lib/canon/diff_formatter/by_line/simple_formatter.rb +0 -3
- data/lib/canon/diff_formatter/by_line/xml_formatter.rb +7 -26
- data/lib/canon/diff_formatter/by_line/yaml_formatter.rb +0 -3
- data/lib/canon/diff_formatter/by_object/base_formatter.rb +8 -15
- data/lib/canon/diff_formatter/by_object/json_formatter.rb +0 -2
- data/lib/canon/diff_formatter/by_object/xml_formatter.rb +0 -2
- data/lib/canon/diff_formatter/by_object/yaml_formatter.rb +0 -2
- data/lib/canon/diff_formatter/debug_output.rb +0 -2
- data/lib/canon/diff_formatter/diff_detail_formatter/dimension_formatter.rb +24 -58
- data/lib/canon/diff_formatter/diff_detail_formatter/location_extractor.rb +0 -2
- data/lib/canon/diff_formatter/diff_detail_formatter/node_utils.rb +1 -2
- data/lib/canon/diff_formatter/diff_detail_formatter/text_utils.rb +1 -7
- data/lib/canon/diff_formatter/diff_detail_formatter.rb +0 -7
- data/lib/canon/diff_formatter/diff_detail_formatter_helpers.rb +23 -0
- data/lib/canon/diff_formatter.rb +11 -9
- data/lib/canon/formatters/html4_formatter.rb +0 -2
- data/lib/canon/formatters/html5_formatter.rb +0 -2
- data/lib/canon/formatters/html_formatter.rb +0 -3
- data/lib/canon/formatters/json_formatter.rb +0 -1
- data/lib/canon/formatters/xml_formatter.rb +0 -4
- data/lib/canon/formatters/yaml_formatter.rb +0 -1
- data/lib/canon/formatters.rb +16 -0
- data/lib/canon/html/data_model.rb +0 -10
- data/lib/canon/html.rb +4 -3
- data/lib/canon/options/cli_generator.rb +0 -2
- data/lib/canon/options/registry.rb +0 -2
- data/lib/canon/options.rb +9 -0
- data/lib/canon/pretty_printer/html.rb +0 -1
- data/lib/canon/pretty_printer/xml_normalized.rb +0 -2
- data/lib/canon/pretty_printer.rb +12 -0
- data/lib/canon/tree_diff/adapters/html_adapter.rb +1 -1
- data/lib/canon/tree_diff/adapters.rb +14 -0
- data/lib/canon/tree_diff/core/attribute_comparator.rb +0 -6
- data/lib/canon/tree_diff/core/node_signature.rb +1 -1
- data/lib/canon/tree_diff/core/tree_node.rb +12 -5
- data/lib/canon/tree_diff/core.rb +17 -0
- data/lib/canon/tree_diff/matchers/hash_matcher.rb +0 -7
- data/lib/canon/tree_diff/matchers/similarity_matcher.rb +1 -5
- data/lib/canon/tree_diff/matchers/structural_propagator.rb +1 -5
- data/lib/canon/tree_diff/matchers.rb +15 -0
- data/lib/canon/tree_diff/operation_converter.rb +0 -8
- data/lib/canon/tree_diff/operation_converter_helpers/metadata_enricher.rb +2 -12
- data/lib/canon/tree_diff/operation_converter_helpers/post_processor.rb +13 -7
- data/lib/canon/tree_diff/operation_converter_helpers/reason_builder.rb +2 -2
- data/lib/canon/tree_diff/operation_converter_helpers/update_change_handler.rb +4 -6
- data/lib/canon/tree_diff/operation_converter_helpers.rb +18 -0
- data/lib/canon/tree_diff/operations/operation_detector.rb +2 -5
- data/lib/canon/tree_diff/operations.rb +13 -0
- data/lib/canon/tree_diff.rb +26 -27
- data/lib/canon/validators/base_validator.rb +0 -2
- data/lib/canon/validators/html_validator.rb +0 -1
- data/lib/canon/validators/json_validator.rb +0 -1
- data/lib/canon/validators/xml_validator.rb +0 -1
- data/lib/canon/validators/yaml_validator.rb +0 -1
- data/lib/canon/validators.rb +12 -0
- data/lib/canon/version.rb +1 -1
- data/lib/canon/xml/c14n.rb +0 -4
- data/lib/canon/xml/data_model.rb +0 -10
- data/lib/canon/xml/line_range_mapper.rb +0 -2
- data/lib/canon/xml/nodes/attribute_node.rb +0 -2
- data/lib/canon/xml/nodes/comment_node.rb +0 -2
- data/lib/canon/xml/nodes/element_node.rb +0 -2
- data/lib/canon/xml/nodes/namespace_node.rb +0 -2
- data/lib/canon/xml/nodes/processing_instruction_node.rb +0 -2
- data/lib/canon/xml/nodes/root_node.rb +0 -2
- data/lib/canon/xml/nodes/text_node.rb +0 -2
- data/lib/canon/xml/nodes.rb +19 -0
- data/lib/canon/xml/processor.rb +0 -5
- data/lib/canon/xml/sax_builder.rb +0 -7
- data/lib/canon/xml.rb +33 -0
- data/lib/canon/xml_backend.rb +50 -14
- data/lib/canon/xml_parsing.rb +4 -2
- data/lib/canon.rb +25 -15
- data/lib/tasks/performance.rake +0 -58
- data/lib/tasks/performance_comparator.rb +132 -65
- data/lib/tasks/performance_helpers.rb +4 -249
- data/lib/tasks/performance_report.rb +309 -0
- metadata +24 -11
- data/lib/canon/comparison/dimensions/attribute_order_dimension.rb +0 -64
- data/lib/canon/comparison/dimensions/attribute_presence_dimension.rb +0 -64
- data/lib/canon/comparison/dimensions/attribute_values_dimension.rb +0 -167
- data/lib/canon/comparison/dimensions/base_dimension.rb +0 -107
- data/lib/canon/comparison/dimensions/comments_dimension.rb +0 -117
- data/lib/canon/comparison/dimensions/element_position_dimension.rb +0 -86
- data/lib/canon/comparison/dimensions/structural_whitespace_dimension.rb +0 -115
- data/lib/canon/comparison/dimensions/text_content_dimension.rb +0 -102
- data/lib/canon/comparison/xml_comparator/diff_node_builder.rb +0 -300
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "node_inspector"
|
|
4
|
-
|
|
5
3
|
module Canon
|
|
6
4
|
module Comparison
|
|
7
5
|
# XML Node Comparison Utilities
|
|
@@ -78,18 +76,9 @@ differences)
|
|
|
78
76
|
differences)
|
|
79
77
|
end
|
|
80
78
|
|
|
81
|
-
# Filter children
|
|
82
|
-
#
|
|
83
|
-
# Removes nodes that should be excluded from comparison based on
|
|
84
|
-
# options like :ignore_nodes, :ignore_comments, etc.
|
|
85
|
-
#
|
|
86
|
-
# @param children [Array] Array of child nodes
|
|
87
|
-
# @param opts [Hash] Comparison options
|
|
88
|
-
# @return [Array] Filtered array of children
|
|
79
|
+
# Filter children — delegates to MarkupComparator.
|
|
89
80
|
def self.filter_children(children, opts)
|
|
90
|
-
children
|
|
91
|
-
node_excluded?(child, opts)
|
|
92
|
-
end
|
|
81
|
+
MarkupComparator.filter_children(children, opts)
|
|
93
82
|
end
|
|
94
83
|
|
|
95
84
|
# Build a side-specific opts copy that activates the pretty-print
|
|
@@ -193,70 +182,9 @@ diff_children, differences)
|
|
|
193
182
|
|
|
194
183
|
# Private helper methods
|
|
195
184
|
|
|
196
|
-
# Check if a node should be excluded
|
|
197
|
-
#
|
|
198
|
-
# @param node [Object] Node to check
|
|
199
|
-
# @param opts [Hash] Comparison options
|
|
200
|
-
# @return [Boolean] true if node should be excluded
|
|
185
|
+
# Check if a node should be excluded — delegates to MarkupComparator.
|
|
201
186
|
def self.node_excluded?(node, opts)
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
return true if opts[:ignore_nodes]&.include?(node)
|
|
205
|
-
return true if opts[:ignore_comments] && comment_node?(node)
|
|
206
|
-
return true if opts[:ignore_text_nodes] && text_node?(node)
|
|
207
|
-
|
|
208
|
-
# Check match options
|
|
209
|
-
match_opts = opts[:match_opts]
|
|
210
|
-
return false unless match_opts
|
|
211
|
-
|
|
212
|
-
# Filter comments based on match options and format
|
|
213
|
-
# HTML: Filter comments to avoid spurious differences from zip pairing
|
|
214
|
-
# BUT only when not in verbose mode (verbose needs differences recorded)
|
|
215
|
-
# XML: Don't filter comments (allow informative differences to be recorded)
|
|
216
|
-
if match_opts[:comments] == :ignore && comment_node?(node)
|
|
217
|
-
# In verbose mode, don't filter comments - we want to record the differences
|
|
218
|
-
return false if opts[:verbose]
|
|
219
|
-
|
|
220
|
-
# Only filter comments for HTML, not XML (when not verbose)
|
|
221
|
-
format = opts[:format] || match_opts[:format]
|
|
222
|
-
if %i[html html4 html5].include?(format)
|
|
223
|
-
return true
|
|
224
|
-
end
|
|
225
|
-
end
|
|
226
|
-
|
|
227
|
-
# Strip whitespace-only text nodes based on parent element configuration.
|
|
228
|
-
# Use preserve_whitespace_elements / strip_whitespace_elements to control.
|
|
229
|
-
# Blacklist (strip) > preserve > collapse > format defaults.
|
|
230
|
-
return false unless text_node?(node) && node.parent
|
|
231
|
-
return false unless MatchOptions.normalize_text(node_text(node)).empty?
|
|
232
|
-
|
|
233
|
-
# HTML-specific: NBSP (U+00A0) is never insignificant whitespace —
|
|
234
|
-
# it always renders as a visible non-breaking space.
|
|
235
|
-
format = opts[:format] || match_opts[:format]
|
|
236
|
-
if %i[html html4 html5].include?(format)
|
|
237
|
-
return false if WhitespaceSensitivity.contains_nbsp?(node_text(node))
|
|
238
|
-
|
|
239
|
-
# Whitespace between inline element siblings is semantically
|
|
240
|
-
# significant (renders as a visible gap) and must not be stripped.
|
|
241
|
-
return false if WhitespaceSensitivity.inline_whitespace_significant?(node)
|
|
242
|
-
end
|
|
243
|
-
|
|
244
|
-
return true unless WhitespaceSensitivity.whitespace_preserved?(
|
|
245
|
-
node.parent, match_opts
|
|
246
|
-
)
|
|
247
|
-
|
|
248
|
-
# When the pretty-print-side flag is active (set by opts_for_side in
|
|
249
|
-
# ChildComparison.compare), drop whitespace-only text nodes that start
|
|
250
|
-
# with "\n" inside :collapse elements — they are structural indentation
|
|
251
|
-
# from the pretty-printer, not content. Space-only nodes (no "\n") are
|
|
252
|
-
# real inline content and are kept for normalised comparison.
|
|
253
|
-
# :preserve elements are always left unchanged.
|
|
254
|
-
if match_opts[:_pretty_print_side_active]
|
|
255
|
-
ws_class = WhitespaceSensitivity.classify_text_node(node, opts)
|
|
256
|
-
return true if ws_class == :collapse && node_text(node).start_with?("\n")
|
|
257
|
-
end
|
|
258
|
-
|
|
259
|
-
false
|
|
187
|
+
MarkupComparator.node_excluded?(node, opts)
|
|
260
188
|
end
|
|
261
189
|
|
|
262
190
|
# Check if this is a comment vs non-comment comparison
|
|
@@ -337,9 +265,6 @@ diff_children, differences)
|
|
|
337
265
|
# Dispatch by Canon::Xml::Node type
|
|
338
266
|
def self.dispatch_canon_node_type(node1, node2, opts, child_opts,
|
|
339
267
|
diff_children, differences)
|
|
340
|
-
# Import XmlComparator to use its comparison methods
|
|
341
|
-
require_relative "xml_comparator"
|
|
342
|
-
|
|
343
268
|
case node1.node_type
|
|
344
269
|
when :root
|
|
345
270
|
XmlComparator.compare_children(node1, node2, opts, child_opts,
|
|
@@ -364,8 +289,6 @@ diff_children, differences)
|
|
|
364
289
|
# Dispatch by legacy Nokogiri/Moxml node type
|
|
365
290
|
def self.dispatch_legacy_node_type(node1, node2, opts, child_opts,
|
|
366
291
|
diff_children, differences)
|
|
367
|
-
require_relative "xml_comparator"
|
|
368
|
-
|
|
369
292
|
if Canon::XmlParsing.document?(node1)
|
|
370
293
|
XmlComparator.compare_document_nodes(node1, node2, opts, child_opts,
|
|
371
294
|
diff_children, differences)
|
|
@@ -401,47 +324,9 @@ diff_children, differences)
|
|
|
401
324
|
differences)
|
|
402
325
|
return unless opts[:verbose]
|
|
403
326
|
|
|
404
|
-
require_relative "xml_comparator"
|
|
405
327
|
XmlComparator.add_difference(node1, node2, diff1, diff2, dimension,
|
|
406
328
|
opts, differences)
|
|
407
329
|
end
|
|
408
|
-
|
|
409
|
-
# Serialize a Canon::Xml::Node to XML string
|
|
410
|
-
#
|
|
411
|
-
# This utility method handles serialization of different node types
|
|
412
|
-
# to their string representation for display and debugging purposes.
|
|
413
|
-
#
|
|
414
|
-
# @param node [Canon::Xml::Node, Object] Node to serialize
|
|
415
|
-
# @return [String] XML string representation
|
|
416
|
-
def self.serialize_node_to_xml(node)
|
|
417
|
-
case node
|
|
418
|
-
when Canon::Xml::Nodes::RootNode
|
|
419
|
-
# Serialize all children of root
|
|
420
|
-
node.children.map { |child| serialize_node_to_xml(child) }.join
|
|
421
|
-
when Canon::Xml::Nodes::ElementNode
|
|
422
|
-
# Serialize element with attributes and children
|
|
423
|
-
attrs = node.attribute_nodes.map do |a|
|
|
424
|
-
" #{a.name}=\"#{a.value}\""
|
|
425
|
-
end.join
|
|
426
|
-
children_xml = node.children.map do |c|
|
|
427
|
-
serialize_node_to_xml(c)
|
|
428
|
-
end.join
|
|
429
|
-
|
|
430
|
-
if children_xml.empty?
|
|
431
|
-
"<#{node.name}#{attrs}/>"
|
|
432
|
-
else
|
|
433
|
-
"<#{node.name}#{attrs}>#{children_xml}</#{node.name}>"
|
|
434
|
-
end
|
|
435
|
-
when Canon::Xml::Nodes::TextNode
|
|
436
|
-
node.value
|
|
437
|
-
when Canon::Xml::Nodes::CommentNode
|
|
438
|
-
"<!--#{node.value}-->"
|
|
439
|
-
when Canon::Xml::Nodes::ProcessingInstructionNode
|
|
440
|
-
"<?#{node.target} #{node.data}?>"
|
|
441
|
-
else
|
|
442
|
-
node.to_s
|
|
443
|
-
end
|
|
444
|
-
end
|
|
445
330
|
end
|
|
446
331
|
end
|
|
447
332
|
end
|