def report
      @output = <<-TEMPLATE
<?xml version="1.0" encoding="UTF-8"?>
<testsuites>
  <testsuite name="#{File.basename(Dir.pwd)}" timestamp="#{DateTime.now}">
TEMPLATE

      # Group according to the errors.
      error_groups = {}
      @results.each do |file, errors|
        errors.each do |error|
          next unless error && error['code']

          error_groups[error['code']] ||= []
          error_groups[error['code']] << {
            file: file,
            line: error['line'],
            character: error['character'],
            message: error['reason']
          }
        end
      end

      # Combine all the errors and the tests for which we have messages. Combine both together.
      all_codes = error_groups.keys + TESTS.keys

      all_codes.each do |code|
        print_errors_for_code(code, error_groups.fetch(code, []))
      end

      @output <<= <<-TEMPLATE
  </testsuite>
</testsuites>
TEMPLATE

      output
    end
def report
      @output = <<-TEMPLATE
<?xml version="1.0" encoding="UTF-8"?>
<testsuites>
  <testsuite name="#{File.basename(Dir.pwd)}" timestamp="#{DateTime.now}">
TEMPLATE

      # Group according to the errors.
      error_groups = {}
      @results.each do |file, errors|
        errors.each do |error|
          next unless error && error['code']

          error_groups[error['code']] ||= []
          error_groups[error['code']] << {
            file: file,
            line: error['line'],
            character: error['character'],
            message: error['reason']
          }
        end
      end

      # Combine all the errors and the tests for which we have messages. Combine both together.
      all_codes = error_groups.keys + TESTS.keys

      all_codes.each do |code|
        print_errors_for_code(code, error_groups.fetch(code, []))
      end

      @output <<= <<-TEMPLATE
  </testsuite>
</testsuites>
TEMPLATE

      output
    end
Sets up the output string for the final report

 @param results [Hash] Key value pairs containing the filename and associated errors
 Loops through all the errors and generates the report

 @example
   foo/bar/baz.js: line 4, col 46, Bad operand.
   foo/bar/baz.js: line 39, col 7, Missing semicolon.

   2 errors

 @return [String] The default report