Class: Trainer::TestParser

Inherits:
Object
  • Object
show all
Defined in:
trainer/lib/trainer/test_parser.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path, config = {}) ⇒ TestParser

Returns a new instance of TestParser.



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
129
130
# File 'trainer/lib/trainer/test_parser.rb', line 100

def initialize(path, config = {})
  path = File.expand_path(path)
  UI.user_error!("File not found at path '#{path}'") unless File.exist?(path)

  if File.directory?(path) && path.end_with?(".xcresult")
    parse_xcresult(path, output_remove_retry_attempts: config[:output_remove_retry_attempts])
  else
    self.file_content = File.read(path)
    self.raw_json = Plist.parse_xml(self.file_content)

    return if self.raw_json["FormatVersion"].to_s.length.zero? # maybe that's a useless plist file

    ensure_file_valid!
    parse_content(config[:xcpretty_naming])
  end

  self.number_of_tests = 0
  self.number_of_failures = 0
  self.number_of_tests_excluding_retries = 0
  self.number_of_failures_excluding_retries = 0
  self.number_of_retries = 0
  self.number_of_skipped = 0
  self.data.each do |thing|
    self.number_of_tests += thing[:number_of_tests].to_i
    self.number_of_failures += thing[:number_of_failures].to_i
    self.number_of_tests_excluding_retries += thing[:number_of_tests_excluding_retries].to_i
    self.number_of_failures_excluding_retries += thing[:number_of_failures_excluding_retries].to_i
    self.number_of_retries += thing[:number_of_retries].to_i
    self.number_of_skipped += thing[:number_of_skipped].to_i
  end
end

Instance Attribute Details

#dataObject

Returns the value of attribute data.



11
12
13
# File 'trainer/lib/trainer/test_parser.rb', line 11

def data
  @data
end

#file_contentObject

Returns the value of attribute file_content.



13
14
15
# File 'trainer/lib/trainer/test_parser.rb', line 13

def file_content
  @file_content
end

#number_of_failuresObject

Returns the value of attribute number_of_failures.



18
19
20
# File 'trainer/lib/trainer/test_parser.rb', line 18

def number_of_failures
  @number_of_failures
end

#number_of_failures_excluding_retriesObject

Returns the value of attribute number_of_failures_excluding_retries.



20
21
22
# File 'trainer/lib/trainer/test_parser.rb', line 20

def number_of_failures_excluding_retries
  @number_of_failures_excluding_retries
end

#number_of_retriesObject

Returns the value of attribute number_of_retries.



21
22
23
# File 'trainer/lib/trainer/test_parser.rb', line 21

def number_of_retries
  @number_of_retries
end

#number_of_skippedObject

Returns the value of attribute number_of_skipped.



22
23
24
# File 'trainer/lib/trainer/test_parser.rb', line 22

def number_of_skipped
  @number_of_skipped
end

#number_of_testsObject

Returns the value of attribute number_of_tests.



17
18
19
# File 'trainer/lib/trainer/test_parser.rb', line 17

def number_of_tests
  @number_of_tests
end

#number_of_tests_excluding_retriesObject

Returns the value of attribute number_of_tests_excluding_retries.



19
20
21
# File 'trainer/lib/trainer/test_parser.rb', line 19

def number_of_tests_excluding_retries
  @number_of_tests_excluding_retries
end

#raw_jsonObject

Returns the value of attribute raw_json.



15
16
17
# File 'trainer/lib/trainer/test_parser.rb', line 15

def raw_json
  @raw_json
end

Class Method Details

.auto_convert(config) ⇒ Object

Returns a hash with the path being the key, and the value defining if the tests were successful



26
27
28
29
30
31
32
33
34
35
36
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
71
72
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
# File 'trainer/lib/trainer/test_parser.rb', line 26

def self.auto_convert(config)
  unless config[:silent]
    FastlaneCore::PrintTable.print_values(config: config,
                                           title: "Summary for trainer #{Fastlane::VERSION}")
  end

  containing_dir = config[:path]
  # Xcode < 10
  files = Dir["#{containing_dir}/**/Logs/Test/*TestSummaries.plist"]
  files += Dir["#{containing_dir}/Test/*TestSummaries.plist"]
  files += Dir["#{containing_dir}/*TestSummaries.plist"]
  # Xcode 10
  files += Dir["#{containing_dir}/**/Logs/Test/*.xcresult/TestSummaries.plist"]
  files += Dir["#{containing_dir}/Test/*.xcresult/TestSummaries.plist"]
  files += Dir["#{containing_dir}/*.xcresult/TestSummaries.plist"]
  files += Dir[containing_dir] if containing_dir.end_with?(".plist") # if it's the exact path to a plist file
  # Xcode 11
  files += Dir["#{containing_dir}/**/Logs/Test/*.xcresult"]
  files += Dir["#{containing_dir}/Test/*.xcresult"]
  files += Dir["#{containing_dir}/*.xcresult"]
  files << containing_dir if File.extname(containing_dir) == ".xcresult"

  if files.empty?
    UI.user_error!("No test result files found in directory '#{containing_dir}', make sure the file name ends with 'TestSummaries.plist' or '.xcresult'")
  end

  return_hash = {}
  files.each do |path|
    extension = config[:extension]
    output_filename = config[:output_filename]

    should_write_file = !extension.nil? || !output_filename.nil?

    if should_write_file
      if config[:output_directory]
        FileUtils.mkdir_p(config[:output_directory])
        # Remove .xcresult or .plist extension
        # Use custom file name ONLY if one file otherwise issues
        if files.size == 1 && output_filename
          filename = output_filename
        elsif path.end_with?(".xcresult")
          filename ||= File.basename(path).gsub(".xcresult", extension)
        else
          filename ||= File.basename(path).gsub(".plist", extension)
        end
        to_path = File.join(config[:output_directory], filename)
      else
        # Remove .xcresult or .plist extension
        if path.end_with?(".xcresult")
          to_path = path.gsub(".xcresult", extension)
        else
          to_path = path.gsub(".plist", extension)
        end
      end
    end

    tp = Trainer::TestParser.new(path, config)
    File.write(to_path, tp.to_junit) if should_write_file
    UI.success("Successfully generated '#{to_path}'") if should_write_file && !config[:silent]

    return_hash[path] = {
      to_path: to_path,
      successful: tp.tests_successful?,
      number_of_tests: tp.number_of_tests,
      number_of_failures: tp.number_of_failures,
      number_of_tests_excluding_retries: tp.number_of_tests_excluding_retries,
      number_of_failures_excluding_retries: tp.number_of_failures_excluding_retries,
      number_of_retries: tp.number_of_retries,
      number_of_skipped: tp.number_of_skipped
    }
  end
  return_hash
end

Instance Method Details

#tests_successful?Bool

Returns were all tests successful? Is false if at least one test failed.

Returns:

  • (Bool)

    were all tests successful? Is false if at least one test failed



138
139
140
# File 'trainer/lib/trainer/test_parser.rb', line 138

def tests_successful?
  self.data.collect { |a| a[:number_of_failures_excluding_retries] }.all?(&:zero?)
end

#to_junitObject

Returns the JUnit report as String



133
134
135
# File 'trainer/lib/trainer/test_parser.rb', line 133

def to_junit
  JunitGenerator.new(self.data).generate
end