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,6 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "diff_line"
|
|
4
3
|
require "set"
|
|
5
4
|
|
|
6
5
|
module Canon
|
|
@@ -159,8 +158,6 @@ module Canon
|
|
|
159
158
|
# @param diff_lines [Array<DiffLine>] The diff lines to update
|
|
160
159
|
# @param lcs_diffs [Array<Diff::LCS::Change>] The LCS changes
|
|
161
160
|
def apply_block_formatting!(diff_lines, lcs_diffs)
|
|
162
|
-
require_relative "formatting_detector"
|
|
163
|
-
|
|
164
161
|
blocks = group_change_blocks(lcs_diffs)
|
|
165
162
|
|
|
166
163
|
blocks.each do |block|
|
|
@@ -265,7 +262,6 @@ module Canon
|
|
|
265
262
|
# @param line2 [String] Second line
|
|
266
263
|
# @return [Boolean] true if formatting-only difference
|
|
267
264
|
def formatting_only_line?(line1, line2)
|
|
268
|
-
require_relative "formatting_detector"
|
|
269
265
|
FormattingDetector.formatting_only?(line1, line2)
|
|
270
266
|
end
|
|
271
267
|
|
|
@@ -1,12 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "../xml/data_model"
|
|
4
|
-
require_relative "../xml/nodes/text_node"
|
|
5
|
-
require_relative "../xml/nodes/comment_node"
|
|
6
|
-
require_relative "../xml/nodes/element_node"
|
|
7
|
-
require_relative "../xml/nodes/processing_instruction_node"
|
|
8
|
-
require_relative "../xml/nodes/root_node"
|
|
9
|
-
|
|
10
3
|
module Canon
|
|
11
4
|
module Diff
|
|
12
5
|
# Serializes nodes from different parsing libraries into canonical strings
|
data/lib/canon/diff.rb
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Canon
|
|
4
|
+
# Diff representation and pipeline construction.
|
|
5
|
+
#
|
|
6
|
+
# This namespace holds the structural artifacts produced by the diff
|
|
7
|
+
# pipeline — DiffNode, DiffLine, DiffBlock, DiffContext, DiffReport —
|
|
8
|
+
# plus the builders that assemble them (DiffNodeMapper, DiffLineBuilder,
|
|
9
|
+
# DiffBlockBuilder, DiffContextBuilder, DiffReportBuilder) and the
|
|
10
|
+
# supporting services (PathBuilder, NodeSerializer, DiffClassifier,
|
|
11
|
+
# FormattingDetector, SourceLocator, TextDecomposer, DiffCharRange,
|
|
12
|
+
# DiffNodeEnricher, XmlSerializationFormatter).
|
|
13
|
+
#
|
|
14
|
+
# All children are autoloaded from this file — never `require_relative`
|
|
15
|
+
# them from sibling files. Reference the constant and let autoload
|
|
16
|
+
# resolve it on first use.
|
|
17
|
+
module Diff
|
|
18
|
+
autoload :DiffBlock, "canon/diff/diff_block"
|
|
19
|
+
autoload :DiffBlockBuilder, "canon/diff/diff_block_builder"
|
|
20
|
+
autoload :DiffCharRange, "canon/diff/diff_char_range"
|
|
21
|
+
autoload :DiffClassifier, "canon/diff/diff_classifier"
|
|
22
|
+
autoload :DiffContext, "canon/diff/diff_context"
|
|
23
|
+
autoload :DiffContextBuilder, "canon/diff/diff_context_builder"
|
|
24
|
+
autoload :DiffLine, "canon/diff/diff_line"
|
|
25
|
+
autoload :DiffLineBuilder, "canon/diff/diff_line_builder"
|
|
26
|
+
autoload :DiffNode, "canon/diff/diff_node"
|
|
27
|
+
autoload :DiffNodeEnricher, "canon/diff/diff_node_enricher"
|
|
28
|
+
autoload :DiffNodeMapper, "canon/diff/diff_node_mapper"
|
|
29
|
+
autoload :DiffReport, "canon/diff/diff_report"
|
|
30
|
+
autoload :DiffReportBuilder, "canon/diff/diff_report_builder"
|
|
31
|
+
autoload :FormattingDetector, "canon/diff/formatting_detector"
|
|
32
|
+
autoload :NodeSerializer, "canon/diff/node_serializer"
|
|
33
|
+
autoload :PathBuilder, "canon/diff/path_builder"
|
|
34
|
+
autoload :SourceLocator, "canon/diff/source_locator"
|
|
35
|
+
autoload :TextDecomposer, "canon/diff/text_decomposer"
|
|
36
|
+
autoload :XmlSerializationFormatter,
|
|
37
|
+
"canon/diff/xml_serialization_formatter"
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
require "diff/lcs" unless RUBY_ENGINE == "opal"
|
|
4
4
|
require "diff/lcs/hunk" unless RUBY_ENGINE == "opal"
|
|
5
|
-
require_relative "../debug_output"
|
|
6
|
-
require_relative "../theme"
|
|
7
5
|
|
|
8
6
|
module Canon
|
|
9
7
|
class DiffFormatter
|
|
@@ -22,10 +20,8 @@ module Canon
|
|
|
22
20
|
def self.for_format(format, **options)
|
|
23
21
|
case format
|
|
24
22
|
when :xml
|
|
25
|
-
require_relative "xml_formatter"
|
|
26
23
|
XmlFormatter.new(**options)
|
|
27
24
|
when :html, :html4, :html5
|
|
28
|
-
require_relative "html_formatter"
|
|
29
25
|
# Determine HTML version from format
|
|
30
26
|
version = case format
|
|
31
27
|
when :html5 then :html5
|
|
@@ -34,13 +30,10 @@ module Canon
|
|
|
34
30
|
end
|
|
35
31
|
HtmlFormatter.new(html_version: version, **options)
|
|
36
32
|
when :json
|
|
37
|
-
require_relative "json_formatter"
|
|
38
33
|
JsonFormatter.new(**options)
|
|
39
34
|
when :yaml
|
|
40
|
-
require_relative "yaml_formatter"
|
|
41
35
|
YamlFormatter.new(**options)
|
|
42
36
|
else
|
|
43
|
-
require_relative "simple_formatter"
|
|
44
37
|
SimpleFormatter.new(**options)
|
|
45
38
|
end
|
|
46
39
|
end
|
|
@@ -279,7 +272,7 @@ module Canon
|
|
|
279
272
|
|
|
280
273
|
differences.select do |diff|
|
|
281
274
|
# Handle both DiffNode objects and legacy Hash format
|
|
282
|
-
is_normative = if diff.
|
|
275
|
+
is_normative = if diff.is_a?(Canon::Diff::DiffNode)
|
|
283
276
|
diff.normative?
|
|
284
277
|
elsif diff.is_a?(Hash) && diff.key?(:normative)
|
|
285
278
|
diff[:normative]
|
|
@@ -394,8 +387,6 @@ module Canon
|
|
|
394
387
|
# @param diffs [Array] LCS diff array
|
|
395
388
|
# @return [Array<Canon::Diff::DiffBlock>] Array of diff blocks
|
|
396
389
|
def identify_diff_blocks(diffs)
|
|
397
|
-
require_relative "../../diff/diff_block"
|
|
398
|
-
|
|
399
390
|
blocks = []
|
|
400
391
|
current_start = nil
|
|
401
392
|
current_types = []
|
|
@@ -467,8 +458,6 @@ module Canon
|
|
|
467
458
|
# @return [Array<Canon::Diff::DiffContext>] Array of diff contexts
|
|
468
459
|
def expand_contexts_with_context_lines(contexts, context_lines,
|
|
469
460
|
total_lines)
|
|
470
|
-
require_relative "../../diff/diff_context"
|
|
471
|
-
|
|
472
461
|
contexts.map do |context|
|
|
473
462
|
first_block = context.first
|
|
474
463
|
last_block = context.last
|
|
@@ -736,10 +725,8 @@ module Canon
|
|
|
736
725
|
next unless match.status == :matched
|
|
737
726
|
|
|
738
727
|
[match.elem1, match.elem2].compact.each do |elem|
|
|
739
|
-
next unless elem.respond_to?(:children)
|
|
740
|
-
|
|
741
728
|
elem.children.each do |child|
|
|
742
|
-
children.add(child) if
|
|
729
|
+
children.add(child) if Canon::Comparison::NodeInspector.element_node?(child)
|
|
743
730
|
end
|
|
744
731
|
end
|
|
745
732
|
end
|
|
@@ -778,8 +765,8 @@ module Canon
|
|
|
778
765
|
return true if elements_with_semantic_diffs.include?(element)
|
|
779
766
|
|
|
780
767
|
# Check all descendants
|
|
781
|
-
if
|
|
782
|
-
|
|
768
|
+
if Canon::Comparison::NodeInspector.element_node?(element)
|
|
769
|
+
Canon::Comparison::NodeInspector.children(element).any? do |child|
|
|
783
770
|
has_semantic_diff_in_subtree?(child, elements_with_semantic_diffs)
|
|
784
771
|
end
|
|
785
772
|
else
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "base_formatter"
|
|
4
|
-
require_relative "../legend"
|
|
5
3
|
require "set"
|
|
6
4
|
|
|
7
5
|
module Canon
|
|
@@ -53,11 +51,6 @@ module Canon
|
|
|
53
51
|
return ""
|
|
54
52
|
end
|
|
55
53
|
|
|
56
|
-
require_relative "../../html/data_model"
|
|
57
|
-
require_relative "../../xml/element_matcher"
|
|
58
|
-
require_relative "../../xml/line_range_mapper"
|
|
59
|
-
require_relative "../../pretty_printer/html"
|
|
60
|
-
|
|
61
54
|
output = []
|
|
62
55
|
|
|
63
56
|
begin
|
|
@@ -107,7 +100,6 @@ module Canon
|
|
|
107
100
|
end
|
|
108
101
|
|
|
109
102
|
output << ""
|
|
110
|
-
require_relative "simple_formatter"
|
|
111
103
|
simple = SimpleFormatter.new(
|
|
112
104
|
use_color: @use_color,
|
|
113
105
|
context_lines: @context_lines,
|
|
@@ -122,9 +114,6 @@ module Canon
|
|
|
122
114
|
|
|
123
115
|
# Format using new DiffReportBuilder pipeline
|
|
124
116
|
def format_with_pipeline(doc1, doc2)
|
|
125
|
-
require_relative "../../diff/diff_node_mapper"
|
|
126
|
-
require_relative "../../diff/diff_report_builder"
|
|
127
|
-
|
|
128
117
|
# Layer 2: Map DiffNodes to DiffLines
|
|
129
118
|
diff_lines = Canon::Diff::DiffNodeMapper.map(@differences, doc1, doc2)
|
|
130
119
|
|
|
@@ -350,15 +339,14 @@ module Canon
|
|
|
350
339
|
|
|
351
340
|
# Second pass: skip children of elements with diffs
|
|
352
341
|
elements_with_diffs.each do |elem|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
end
|
|
360
|
-
current = current.respond_to?(:parent) ? current.parent : nil
|
|
342
|
+
current = Canon::Comparison::NodeInspector.parent(elem)
|
|
343
|
+
while current
|
|
344
|
+
if Canon::Comparison::NodeInspector.element_node?(current) &&
|
|
345
|
+
elements_with_diffs.include?(current)
|
|
346
|
+
elements_to_skip.add(elem)
|
|
347
|
+
break
|
|
361
348
|
end
|
|
349
|
+
current = Canon::Comparison::NodeInspector.parent(current)
|
|
362
350
|
end
|
|
363
351
|
end
|
|
364
352
|
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "base_formatter"
|
|
4
|
-
require_relative "../legend"
|
|
5
3
|
require "strscan"
|
|
6
4
|
|
|
7
5
|
module Canon
|
|
@@ -38,7 +36,6 @@ module Canon
|
|
|
38
36
|
output << colorize(
|
|
39
37
|
"Warning: JSON parsing failed (#{e.message}), using simple diff", :yellow
|
|
40
38
|
)
|
|
41
|
-
require_relative "simple_formatter"
|
|
42
39
|
simple = SimpleFormatter.new(
|
|
43
40
|
use_color: @use_color,
|
|
44
41
|
context_lines: @context_lines,
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "base_formatter"
|
|
4
|
-
require_relative "../legend"
|
|
5
|
-
require_relative "../../tree_diff/core/xml_entity_decoder"
|
|
6
3
|
require "set"
|
|
7
4
|
require "strscan"
|
|
8
5
|
|
|
@@ -44,10 +41,6 @@ module Canon
|
|
|
44
41
|
return ""
|
|
45
42
|
end
|
|
46
43
|
|
|
47
|
-
require_relative "../../diff/diff_node_enricher"
|
|
48
|
-
require_relative "../../diff/diff_line_builder"
|
|
49
|
-
require_relative "../../diff/diff_report_builder"
|
|
50
|
-
|
|
51
44
|
# Compute line number width BEFORE formatting
|
|
52
45
|
compute_line_num_width(doc1, doc2)
|
|
53
46
|
|
|
@@ -201,10 +194,6 @@ module Canon
|
|
|
201
194
|
return ""
|
|
202
195
|
end
|
|
203
196
|
|
|
204
|
-
require_relative "../../xml/data_model"
|
|
205
|
-
require_relative "../../xml/element_matcher"
|
|
206
|
-
require_relative "../../xml/line_range_mapper"
|
|
207
|
-
|
|
208
197
|
output = []
|
|
209
198
|
|
|
210
199
|
begin
|
|
@@ -247,7 +236,6 @@ module Canon
|
|
|
247
236
|
end
|
|
248
237
|
|
|
249
238
|
output << ""
|
|
250
|
-
require_relative "simple_formatter"
|
|
251
239
|
simple = SimpleFormatter.new(
|
|
252
240
|
use_color: @use_color,
|
|
253
241
|
context_lines: @context_lines,
|
|
@@ -622,15 +610,14 @@ module Canon
|
|
|
622
610
|
|
|
623
611
|
# Second pass: skip children of elements with diffs
|
|
624
612
|
elements_with_diffs.each do |elem|
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
end
|
|
632
|
-
current = current.respond_to?(:parent) ? current.parent : nil
|
|
613
|
+
current = Canon::Comparison::NodeInspector.parent(elem)
|
|
614
|
+
while current
|
|
615
|
+
if Canon::Comparison::NodeInspector.element_node?(current) &&
|
|
616
|
+
elements_with_diffs.include?(current)
|
|
617
|
+
elements_to_skip.add(elem)
|
|
618
|
+
break
|
|
633
619
|
end
|
|
620
|
+
current = Canon::Comparison::NodeInspector.parent(current)
|
|
634
621
|
end
|
|
635
622
|
end
|
|
636
623
|
|
|
@@ -721,8 +708,6 @@ module Canon
|
|
|
721
708
|
|
|
722
709
|
# Identify contiguous diff blocks
|
|
723
710
|
def identify_diff_blocks(diffs)
|
|
724
|
-
require_relative "../../diff/diff_block"
|
|
725
|
-
|
|
726
711
|
blocks = []
|
|
727
712
|
current_start = nil
|
|
728
713
|
current_types = []
|
|
@@ -784,8 +769,6 @@ module Canon
|
|
|
784
769
|
# Expand contexts with context lines
|
|
785
770
|
def expand_contexts_with_context_lines(contexts, context_lines,
|
|
786
771
|
total_lines)
|
|
787
|
-
require_relative "../../diff/diff_context"
|
|
788
|
-
|
|
789
772
|
contexts.map do |context|
|
|
790
773
|
first_block = context.first
|
|
791
774
|
last_block = context.last
|
|
@@ -803,8 +786,6 @@ module Canon
|
|
|
803
786
|
|
|
804
787
|
# Format a context
|
|
805
788
|
def format_context(context, diffs, base_line1, base_line2)
|
|
806
|
-
require_relative "../../diff/formatting_detector"
|
|
807
|
-
|
|
808
789
|
# Pre-compute block-level formatting for multi-line changes
|
|
809
790
|
formatting_indices = detect_block_formatting(context, diffs)
|
|
810
791
|
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "base_formatter"
|
|
4
|
-
require_relative "../legend"
|
|
5
3
|
require "strscan"
|
|
6
4
|
|
|
7
5
|
module Canon
|
|
@@ -37,7 +35,6 @@ module Canon
|
|
|
37
35
|
output << colorize(
|
|
38
36
|
"Warning: YAML parsing failed (#{e.message}), using simple diff", :yellow
|
|
39
37
|
)
|
|
40
|
-
require_relative "simple_formatter"
|
|
41
38
|
simple = SimpleFormatter.new(
|
|
42
39
|
use_color: @use_color,
|
|
43
40
|
context_lines: @context_lines,
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "set"
|
|
4
|
-
require_relative "../theme"
|
|
5
4
|
|
|
6
5
|
module Canon
|
|
7
6
|
class DiffFormatter
|
|
@@ -76,19 +75,16 @@ show_diffs: :all, theme: nil)
|
|
|
76
75
|
show_diffs: :all, theme: nil)
|
|
77
76
|
case format
|
|
78
77
|
when :xml, :html
|
|
79
|
-
require_relative "xml_formatter"
|
|
80
78
|
XmlFormatter.new(use_color: use_color,
|
|
81
79
|
visualization_map: visualization_map,
|
|
82
80
|
show_diffs: show_diffs,
|
|
83
81
|
theme: theme)
|
|
84
82
|
when :json
|
|
85
|
-
require_relative "json_formatter"
|
|
86
83
|
JsonFormatter.new(use_color: use_color,
|
|
87
84
|
visualization_map: visualization_map,
|
|
88
85
|
show_diffs: show_diffs,
|
|
89
86
|
theme: theme)
|
|
90
87
|
when :yaml
|
|
91
|
-
require_relative "yaml_formatter"
|
|
92
88
|
YamlFormatter.new(use_color: use_color,
|
|
93
89
|
visualization_map: visualization_map,
|
|
94
90
|
show_diffs: show_diffs,
|
|
@@ -221,23 +217,20 @@ show_diffs: :all, theme: nil)
|
|
|
221
217
|
current = node
|
|
222
218
|
visited = Set.new
|
|
223
219
|
|
|
224
|
-
while current
|
|
225
|
-
# Prevent infinite loops by tracking visited nodes
|
|
220
|
+
while current
|
|
226
221
|
break if visited.include?(current.object_id)
|
|
227
222
|
|
|
228
223
|
visited << current.object_id
|
|
229
224
|
|
|
230
|
-
|
|
225
|
+
break if Canon::Comparison::NodeInspector.document?(current) ||
|
|
226
|
+
Canon::Comparison::NodeInspector.document_fragment?(current)
|
|
227
|
+
|
|
228
|
+
name = Canon::Comparison::NodeInspector.name(current)
|
|
229
|
+
break if name.nil?
|
|
231
230
|
|
|
232
|
-
|
|
233
|
-
break if current.is_a?(Nokogiri::XML::Document) ||
|
|
234
|
-
current.is_a?(Nokogiri::HTML4::Document) ||
|
|
235
|
-
current.is_a?(Nokogiri::HTML5::Document) ||
|
|
236
|
-
current.is_a?(Nokogiri::XML::DocumentFragment) ||
|
|
237
|
-
current.is_a?(Nokogiri::HTML4::DocumentFragment) ||
|
|
238
|
-
current.is_a?(Nokogiri::HTML5::DocumentFragment)
|
|
231
|
+
parts.unshift(name) unless name.empty?
|
|
239
232
|
|
|
240
|
-
current =
|
|
233
|
+
current = Canon::Comparison::NodeInspector.parent(current)
|
|
241
234
|
end
|
|
242
235
|
|
|
243
236
|
parts.empty? ? diff_node.dimension.to_s : parts.join(".")
|
|
@@ -53,9 +53,6 @@ expand_difference: false)
|
|
|
53
53
|
# @param use_color [Boolean] Whether to use colors
|
|
54
54
|
# @return [Array] Tuple of [detail1, detail2, changes]
|
|
55
55
|
def self.format_namespace_uri_details(diff, use_color)
|
|
56
|
-
require_relative "color_helper"
|
|
57
|
-
require_relative "node_utils"
|
|
58
|
-
|
|
59
56
|
node1 = extract_node1(diff)
|
|
60
57
|
node2 = extract_node2(diff)
|
|
61
58
|
|
|
@@ -87,10 +84,6 @@ expand_difference: false)
|
|
|
87
84
|
# @param use_color [Boolean] Whether to use colors
|
|
88
85
|
# @return [Array] Tuple of [detail1, detail2, changes]
|
|
89
86
|
def self.format_namespace_declarations_details(diff, use_color)
|
|
90
|
-
require_relative "color_helper"
|
|
91
|
-
require_relative "node_utils"
|
|
92
|
-
require_relative "text_utils"
|
|
93
|
-
|
|
94
87
|
node1 = extract_node1(diff)
|
|
95
88
|
node2 = extract_node2(diff)
|
|
96
89
|
|
|
@@ -174,9 +167,6 @@ expand_difference: false)
|
|
|
174
167
|
# @param use_color [Boolean] Whether to use colors
|
|
175
168
|
# @return [Array] Tuple of [detail1, detail2, changes]
|
|
176
169
|
def self.format_element_structure_details(diff, use_color)
|
|
177
|
-
require_relative "color_helper"
|
|
178
|
-
require_relative "node_utils"
|
|
179
|
-
|
|
180
170
|
node1 = extract_node1(diff)
|
|
181
171
|
node2 = extract_node2(diff)
|
|
182
172
|
|
|
@@ -236,9 +226,6 @@ expand_difference: false)
|
|
|
236
226
|
# @param use_color [Boolean] Whether to use colors
|
|
237
227
|
# @return [Array] Tuple of [detail1, detail2, changes]
|
|
238
228
|
def self.format_attribute_presence_details(diff, use_color)
|
|
239
|
-
require_relative "color_helper"
|
|
240
|
-
require_relative "node_utils"
|
|
241
|
-
|
|
242
229
|
node1 = extract_node1(diff)
|
|
243
230
|
node2 = extract_node2(diff)
|
|
244
231
|
|
|
@@ -291,9 +278,6 @@ expand_difference: false)
|
|
|
291
278
|
# @param use_color [Boolean] Whether to use colors
|
|
292
279
|
# @return [Array] Tuple of [detail1, detail2, changes]
|
|
293
280
|
def self.format_attribute_values_details(diff, use_color)
|
|
294
|
-
require_relative "color_helper"
|
|
295
|
-
require_relative "node_utils"
|
|
296
|
-
|
|
297
281
|
node1 = extract_node1(diff)
|
|
298
282
|
node2 = extract_node2(diff)
|
|
299
283
|
|
|
@@ -330,9 +314,6 @@ expand_difference: false)
|
|
|
330
314
|
# @param use_color [Boolean] Whether to use colors
|
|
331
315
|
# @return [Array] Tuple of [detail1, detail2, changes]
|
|
332
316
|
def self.format_attribute_order_details(diff, use_color)
|
|
333
|
-
require_relative "color_helper"
|
|
334
|
-
require_relative "node_utils"
|
|
335
|
-
|
|
336
317
|
node1 = extract_node1(diff)
|
|
337
318
|
node2 = extract_node2(diff)
|
|
338
319
|
|
|
@@ -361,10 +342,6 @@ expand_difference: false)
|
|
|
361
342
|
# @param compact [Boolean] Whether to serialize element nodes as compact XML
|
|
362
343
|
# @return [Array] Tuple of [detail1, detail2, changes]
|
|
363
344
|
def self.format_text_content_details(diff, use_color, compact: false)
|
|
364
|
-
require_relative "color_helper"
|
|
365
|
-
require_relative "node_utils"
|
|
366
|
-
require_relative "text_utils"
|
|
367
|
-
|
|
368
345
|
node1 = extract_node1(diff)
|
|
369
346
|
node2 = extract_node2(diff)
|
|
370
347
|
|
|
@@ -465,10 +442,6 @@ expand_difference: false)
|
|
|
465
442
|
# @param use_color [Boolean] Whether to apply ANSI colours
|
|
466
443
|
# @return [Array<String>] Tuple of [detail1, detail2, changes]
|
|
467
444
|
def self.format_text_content_one_sided(node1, node2, use_color)
|
|
468
|
-
require_relative "color_helper"
|
|
469
|
-
require_relative "node_utils"
|
|
470
|
-
require_relative "text_utils"
|
|
471
|
-
|
|
472
445
|
present = node1 || node2
|
|
473
446
|
|
|
474
447
|
# Defensive: if a one-sided text-content diff carries an
|
|
@@ -515,10 +488,6 @@ expand_difference: false)
|
|
|
515
488
|
# @param use_color [Boolean] Whether to use colors
|
|
516
489
|
# @return [Array] Tuple of [detail1, detail2, changes]
|
|
517
490
|
def self.format_whitespace_adjacency_details(diff, use_color)
|
|
518
|
-
require_relative "color_helper"
|
|
519
|
-
require_relative "node_utils"
|
|
520
|
-
require_relative "text_utils"
|
|
521
|
-
|
|
522
491
|
node1 = extract_node1(diff)
|
|
523
492
|
node2 = extract_node2(diff)
|
|
524
493
|
|
|
@@ -568,10 +537,6 @@ expand_difference: false)
|
|
|
568
537
|
# @param use_color [Boolean] Whether to use colors
|
|
569
538
|
# @return [Array] Tuple of [detail1, detail2, changes]
|
|
570
539
|
def self.format_structural_whitespace_details(diff, use_color)
|
|
571
|
-
require_relative "color_helper"
|
|
572
|
-
require_relative "node_utils"
|
|
573
|
-
require_relative "text_utils"
|
|
574
|
-
|
|
575
540
|
node1 = extract_node1(diff)
|
|
576
541
|
node2 = extract_node2(diff)
|
|
577
542
|
|
|
@@ -594,9 +559,6 @@ expand_difference: false)
|
|
|
594
559
|
# @param use_color [Boolean] Whether to use colors
|
|
595
560
|
# @return [Array] Tuple of [detail1, detail2, changes]
|
|
596
561
|
def self.format_comments_details(diff, use_color)
|
|
597
|
-
require_relative "color_helper"
|
|
598
|
-
require_relative "node_utils"
|
|
599
|
-
|
|
600
562
|
node1 = extract_node1(diff)
|
|
601
563
|
node2 = extract_node2(diff)
|
|
602
564
|
|
|
@@ -619,8 +581,6 @@ expand_difference: false)
|
|
|
619
581
|
# @param use_color [Boolean] Whether to use colors
|
|
620
582
|
# @return [Array] Tuple of [detail1, detail2, changes]
|
|
621
583
|
def self.format_hash_diff_details(diff, use_color)
|
|
622
|
-
require_relative "color_helper"
|
|
623
|
-
|
|
624
584
|
detail1 = if diff.is_a?(Hash) && diff[:value1]
|
|
625
585
|
ColorHelper.colorize(format_json_value(diff[:value1]),
|
|
626
586
|
:red, use_color)
|
|
@@ -653,9 +613,6 @@ expand_difference: false)
|
|
|
653
613
|
# @param compact [Boolean] Whether to serialize element nodes as compact XML
|
|
654
614
|
# @return [Array] Tuple of [detail1, detail2, changes]
|
|
655
615
|
def self.format_fallback_details(diff, use_color, compact: false)
|
|
656
|
-
require_relative "color_helper"
|
|
657
|
-
require_relative "node_utils"
|
|
658
|
-
|
|
659
616
|
node1 = extract_node1(diff)
|
|
660
617
|
node2 = extract_node2(diff)
|
|
661
618
|
|
|
@@ -749,8 +706,7 @@ expand_difference: false)
|
|
|
749
706
|
|
|
750
707
|
declarations = {}
|
|
751
708
|
|
|
752
|
-
|
|
753
|
-
if node.respond_to?(:namespace_nodes)
|
|
709
|
+
if node.is_a?(Canon::Xml::Node)
|
|
754
710
|
node.namespace_nodes.each do |ns|
|
|
755
711
|
next if ns.prefix == "xml" && ns.uri == "http://www.w3.org/XML/1998/namespace"
|
|
756
712
|
|
|
@@ -760,30 +716,28 @@ expand_difference: false)
|
|
|
760
716
|
return declarations
|
|
761
717
|
end
|
|
762
718
|
|
|
763
|
-
# Handle Nokogiri/Moxml nodes (use attributes)
|
|
764
|
-
raw_attrs = node.
|
|
719
|
+
# Handle Nokogiri/Moxml nodes (use attribute_nodes or attributes).
|
|
720
|
+
raw_attrs = if node.is_a?(Nokogiri::XML::Node)
|
|
721
|
+
node.attribute_nodes
|
|
722
|
+
else
|
|
723
|
+
node.attributes
|
|
724
|
+
end
|
|
765
725
|
|
|
766
726
|
if raw_attrs.is_a?(Array)
|
|
767
727
|
raw_attrs.each do |attr|
|
|
768
|
-
name = attr.
|
|
769
|
-
value = attr.
|
|
728
|
+
name = attr.is_a?(Nokogiri::XML::Attr) ? attr.name : attr.to_s
|
|
729
|
+
value = attr.is_a?(Nokogiri::XML::Attr) ? attr.value : attr.to_s
|
|
770
730
|
|
|
771
731
|
if namespace_declaration?(name)
|
|
772
732
|
prefix = name == "xmlns" ? "" : name.split(":", 2)[1]
|
|
773
733
|
declarations[prefix] = value
|
|
774
734
|
end
|
|
775
735
|
end
|
|
776
|
-
elsif raw_attrs.
|
|
736
|
+
elsif raw_attrs.is_a?(Hash)
|
|
777
737
|
raw_attrs.each do |key, val|
|
|
778
|
-
name =
|
|
779
|
-
|
|
780
|
-
else
|
|
781
|
-
(key.respond_to?(:name) ? key.name : key.to_s)
|
|
782
|
-
end
|
|
783
|
-
value = if val.respond_to?(:value)
|
|
738
|
+
name = hash_key_to_name(key)
|
|
739
|
+
value = if val.is_a?(Nokogiri::XML::Attr)
|
|
784
740
|
val.value
|
|
785
|
-
elsif val.respond_to?(:content)
|
|
786
|
-
val.content
|
|
787
741
|
else
|
|
788
742
|
val.to_s
|
|
789
743
|
end
|
|
@@ -805,6 +759,18 @@ expand_difference: false)
|
|
|
805
759
|
def self.namespace_declaration?(name)
|
|
806
760
|
name == "xmlns" || name.to_s.start_with?("xmlns:")
|
|
807
761
|
end
|
|
762
|
+
|
|
763
|
+
# Coerce a hash key (from a backend-supplied attribute hash) into a
|
|
764
|
+
# plain String attribute name.
|
|
765
|
+
#
|
|
766
|
+
# @param key [String, Nokogiri::XML::Attr, Object]
|
|
767
|
+
# @return [String]
|
|
768
|
+
def self.hash_key_to_name(key)
|
|
769
|
+
return key if key.is_a?(String)
|
|
770
|
+
return key.name if key.is_a?(Nokogiri::XML::Attr)
|
|
771
|
+
|
|
772
|
+
key.to_s
|
|
773
|
+
end
|
|
808
774
|
end
|
|
809
775
|
end
|
|
810
776
|
end
|