Class: SvgConform::ReportComparator

Inherits:
Object
  • Object
show all
Defined in:
lib/svg_conform/report_comparator.rb

Overview

Compares SvgConform validation reports with svgcheck reports and displays the differences in a formatted table

Instance Method Summary collapse

Constructor Details

#initialize(profile: :svg_1_2_rfc, reports_dir: "spec/fixtures/svgcheck_reports") ⇒ ReportComparator

Returns a new instance of ReportComparator.



10
11
12
13
14
# File 'lib/svg_conform/report_comparator.rb', line 10

def initialize(profile: :svg_1_2_rfc,
reports_dir: "spec/fixtures/svgcheck_reports")
  @profile = profile
  @reports_dir = reports_dir
end

Instance Method Details

#compare_all_test_filesObject

Compare all test files and generate a comprehensive report



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/svg_conform/report_comparator.rb', line 131

def compare_all_test_files
  puts "\n#{Paint['=' * 100, :cyan]}"
  puts Paint["šŸ” COMPREHENSIVE SVGCHECK COMPATIBILITY ANALYSIS", :magenta,
             :bold]
  puts Paint["=" * 100, :cyan]

  test_files = Dir.glob(File.join(@reports_dir,
                                  "*.svgcheck.yaml")).map do |report_file|
    File.basename(report_file, ".svgcheck.yaml")
  end

  results = []
  validator = SvgConform::Validator.new

  test_files.each do |filename|
    next if filename == "rfc.xml" # Skip non-SVG files

    begin
      # Load svgcheck report
      svgcheck_report_path = File.join(@reports_dir,
                                       "#{filename}.svgcheck.yaml")
      # Use the new external checker parser
      parser = SvgConform::ExternalCheckers::Svgcheck::Parser.new
      error_content = File.read(svgcheck_report_path)
      svgcheck_report = parser.parse(error_content, nil, filename: filename)

      # Generate SvgConform report
      svg_file_path = "svgcheck/svgcheck/Tests/#{filename}"
      if File.exist?(svg_file_path)
        svg_content = File.read(svg_file_path)
        validation_result = validator.validate(svg_content,
                                               profile: @profile)
        svg_conform_report = SvgConform::ConformanceReport.from_svg_conform_result(filename, validation_result,
                                                                                   profile: @profile, use_svgcheck_mapping: true)

        # Compare reports
        compare_reports(svg_conform_report, svgcheck_report, filename)

        # Track results
        results << {
          filename: filename,
          svg_conform_errors: svg_conform_report.errors.total_count,
          svgcheck_errors: svgcheck_report.errors.total_count,
          match: svg_conform_report.errors.total_count == svgcheck_report.errors.total_count,
        }
      else
        puts "\n⚠ SVG file not found: #{svg_file_path}"
      end
    rescue StandardError => e
      puts "\nāŒ Error processing #{filename}: #{e.message}"
    end
  end

  # Overall summary
  display_overall_summary(results)
end

#compare_reports(svg_conform_report, svgcheck_report, filename) ⇒ Object

Compare two reports and display the results in a table



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/svg_conform/report_comparator.rb', line 17

def compare_reports(svg_conform_report, svgcheck_report, filename)
  puts "\n#{Paint['=' * 80, :cyan]}"
  puts Paint["šŸ“Š REPORT COMPARISON: #{filename}", :blue, :bold]
  puts Paint["=" * 80, :cyan]

  # Summary table
  display_summary_table(svg_conform_report, svgcheck_report)

  # Error mapping table
  display_error_mapping_table(svg_conform_report, svgcheck_report)

  # Generate comparison result for requirement mapping
  result = generate_comparison_result(svg_conform_report, svgcheck_report,
                                      filename)

  # Display requirement-based mapping
  display_requirement_mapping(result)
end

#compare_single_file(filename) ⇒ Object

Compare a single file and return structured results



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/svg_conform/report_comparator.rb', line 37

def compare_single_file(filename)
  validator = SvgConform::Validator.new

  begin
    # Extract just the basename if a full path was provided
    basename = File.basename(filename)

    # Load svgcheck report
    svgcheck_report_path = File.join(@reports_dir,
                                     "#{basename}.svgcheck.yaml")
    return nil unless File.exist?(svgcheck_report_path)

    # Use the new external checker parser
    parser = SvgConform::ExternalCheckers::Svgcheck::Parser.new
    error_content = File.read(svgcheck_report_path)
    svgcheck_report = parser.parse(error_content, nil, filename: basename)

    # Generate SvgConform report - use the original filename for the SVG file path
    svg_file_path = filename.start_with?("svgcheck/") ? filename : "svgcheck/svgcheck/Tests/#{basename}"
    return nil unless File.exist?(svg_file_path)

    svg_content = File.read(svg_file_path)
    validation_result = validator.validate(svg_content, profile: @profile)
    svg_conform_report = SvgConform::ConformanceReport.from_svg_conform_result(basename, validation_result,
                                                                               profile: @profile, use_svgcheck_mapping: true)

    # Generate structured comparison result
    generate_comparison_result(svg_conform_report, svgcheck_report,
                               basename)
  rescue StandardError => e
    puts "āŒ Error processing #{filename}: #{e.message}"
    nil
  end
end

#display_single_file_result(result) ⇒ Object

Display single file comparison result using the table formatting



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/svg_conform/report_comparator.rb', line 73

def display_single_file_result(result)
  return unless result

  filename = result[:filename]

  puts "\n#{Paint['=' * 80, :cyan]}"
  puts Paint["šŸ“Š REPORT COMPARISON: #{filename}", :blue, :bold]
  puts Paint["=" * 80, :cyan]

  # Summary table
  headers = ["Metric", "SvgConform", "svgcheck", "Match?"]
  rows = [
    ["Valid", result[:svg_conform_valid], result[:svgcheck_valid],
     result[:valid_match] ? "āœ“" : "āœ—"],
    ["Total Errors", result[:svg_conform_errors], result[:svgcheck_errors],
     result[:errors_match] ? "āœ“" : "āœ—"],
    ["Error Types", result[:svg_conform_error_types], result[:svgcheck_error_types],
     result[:error_types_match] ? "āœ“" : "āœ—"],
  ]

  puts "\nSUMMARY:"
  render_gh_style_table(headers, rows)

  # Semantic error mapping table
  if result[:semantic_mapping]&.any?
    headers = ["Error Type", "SvgConform Count", "svgcheck Count", "Status"]
    rows = []

    result[:semantic_mapping].each do |error_type, counts|
      svg_count = counts[:svg_conform]
      svgcheck_count = counts[:svgcheck]
      status = if svg_count == svgcheck_count && svg_count.positive?
                 "āœ“ MATCH"
               elsif svg_count == svgcheck_count && svg_count.zero?
                 "āœ“ BOTH NONE"
               elsif svg_count > svgcheck_count
                 "⚠ MISMATCH"
               elsif svg_count < svgcheck_count
                 "⚠ MISMATCH"
               else
                 "? UNKNOWN"
               end

      rows << [error_type, svg_count, svgcheck_count, status]
    end

    # Determine overall coverage status
    coverage_status = determine_coverage_status(result[:semantic_mapping])

    puts "\nSEMANTIC ERROR MAPPING: #{coverage_status}"
    render_gh_style_table(headers, rows)
  end

  # Display requirement-based mapping
  display_requirement_mapping(result)
end