lupocunit2junit 1.0

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.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/bin/lupocunit2junit +233 -0
  3. metadata +45 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 65a7e916bfc891a4bcdaeb8d483c3a3a53517a3a
4
+ data.tar.gz: b127291ca2a8ada6807ed4ad8e67eca9cec07e16
5
+ SHA512:
6
+ metadata.gz: 0b62b482060fa9a62226cfdd2a55add5e31c17c2fa7a2e03453ecc16a7817f41fae08a8ee50ebb1171d7bae79f796c25fc279b7a9627e320be8dd353eaa64eee
7
+ data.tar.gz: 863e44520c52b237ba7e02c967fff825745e456fec825b772e3e0a05efe96c20c935579e98478203fe8f10ad4b67c313648f170aa14e747a0b46f2f440e87260
@@ -0,0 +1,233 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # ocunit2junit.rb was written by Christian Hedin <christian.hedin@jayway.com>
4
+ # Version: 0.1 - 30/01 2010
5
+ # Usage:
6
+ # xcodebuild -yoursettings | ocunit2junit.rb
7
+ # All output is just passed through to stdout so you don't miss a thing!
8
+ # JUnit style XML-report are put in the folder specified below.
9
+ #
10
+ # Known problems:
11
+ # * "Errors" are not cought, only "warnings".
12
+ # * It's not possible to click links to failed test in Hudson
13
+ # * It's not possible to browse the source code in Hudson
14
+ #
15
+ # Acknowledgement:
16
+ # Big thanks to Steen Lehmann for prettifying this script.
17
+ ################################################################
18
+ # Edit these variables to match your system
19
+ #
20
+ #
21
+ # Where to put the XML-files from your unit tests
22
+ TEST_REPORTS_FOLDER = ENV.has_key?('TEST_REPORTS_FOLDER') ? ENV['TEST_REPORTS_FOLDER'] : "test-reports"
23
+ SUPPORT_KIWI = ENV.has_key?('SUPPORT_KIWI') ? ENV['SUPPORT_KIWI'] : true
24
+ #
25
+ #
26
+ # Don't edit below this line
27
+ ################################################################
28
+
29
+ require 'time'
30
+ require 'fileutils'
31
+ require 'socket'
32
+
33
+ class ReportParser
34
+
35
+ attr_reader :exit_code
36
+
37
+ def initialize(piped_input)
38
+ @piped_input = piped_input
39
+ @exit_code = 0
40
+
41
+ FileUtils.rm_rf(TEST_REPORTS_FOLDER)
42
+ FileUtils.mkdir_p(TEST_REPORTS_FOLDER)
43
+ parse_input
44
+ end
45
+
46
+ private
47
+
48
+ def parse_input
49
+ if @piped_input.respond_to?(:each)
50
+ line_enumerator = @piped_input.each
51
+ elsif @piped_input.respond_to?(:each_line)
52
+ line_enumerator = @piped_input.each_line
53
+ end
54
+
55
+ line_enumerator.each do |piped_row|
56
+ if piped_row.respond_to?("encode!")
57
+ temporary_encoding = (RUBY_VERSION == '1.9.2') ? 'UTF-8' : 'UTF-16'
58
+ piped_row.encode!(temporary_encoding, 'UTF-8', :invalid => :replace, :replace => '')
59
+ piped_row.encode!('UTF-8', temporary_encoding)
60
+ end
61
+ puts piped_row
62
+
63
+ description_results = piped_row.scan(/\s\'(.+)\'\s/)
64
+ if description_results && description_results[0] && description_results[0]
65
+ description = description_results[0][0]
66
+ end
67
+
68
+ case piped_row
69
+
70
+ when /Test Suite '(\S+)'.*started at\s+(.*)/
71
+ t = Time.parse($2.to_s)
72
+ handle_start_test_suite(t)
73
+ @last_description = nil
74
+ @current_suite = $1
75
+
76
+ when /Test Suite '(\S+)'.*finished at\s+(.*)./
77
+ t = Time.parse($2.to_s)
78
+ handle_end_test_suite($1,t)
79
+
80
+ when /Test Suite '(\S+)'.*passed at\s+(.*)./
81
+ t = Time.parse($2.to_s)
82
+ handle_end_test_suite($1,t)
83
+
84
+ when /Test Suite '(\S+)'.*failed at\s+(.*)./
85
+ t = Time.parse($2.to_s)
86
+ handle_end_test_suite($1,t)
87
+
88
+ when /Test Case '-\[\S+\s+(\S+)\]' started./
89
+ test_case = $1
90
+ @last_description = nil
91
+ @current_test = test_case
92
+
93
+ when /Test Case '-\[\S+\s+(\S+)\]' passed \((.*) seconds\)/
94
+ test_case = get_test_case_name($1, @last_description)
95
+ test_case_duration = $2.to_f
96
+ handle_test_passed(test_case,test_case_duration)
97
+
98
+ when /Restarting after unexpected exit or crash in (\S+)\//
99
+ error_message = "Crash encountered during the test!"
100
+ test_case = @current_test
101
+ test_suite = @current_suite
102
+ handle_test_error(test_suite,test_case,error_message, "Search the logs for error location!")
103
+ #no way to know the time elapsed in this case as XCUnit does not print it in the informational message.
104
+ handle_test_failed(test_case, 0.000)
105
+
106
+ #mark current suite as restarting.
107
+ @restarting_current_suite = true
108
+
109
+ when /(.*): error: -\[(\S+) (\S+)\] : (.*)/
110
+ error_location = $1
111
+ test_suite = $2
112
+ error_message = $4
113
+ test_case = get_test_case_name($3, description)
114
+ handle_test_error(test_suite,test_case,error_message,error_location)
115
+
116
+ when /Test Case '-\[\S+ (\S+)\]' failed \((\S+) seconds\)/
117
+ test_case = get_test_case_name($1, @last_description)
118
+ test_case_duration = $2.to_f
119
+ handle_test_failed(test_case,test_case_duration)
120
+
121
+ when /failed with exit code (\d+)/
122
+ @exit_code = $1.to_i
123
+
124
+ when
125
+ /BUILD FAILED/
126
+ @exit_code = -1;
127
+ end
128
+
129
+ if description
130
+ @last_description = description
131
+ end
132
+ end
133
+ end
134
+
135
+ def handle_start_test_suite(start_time)
136
+
137
+ #if we detected that XCUinit says it is being restarted because of an unexpected interruption. (i.e. a crash)
138
+ #In this case, we don't want to treat it as a "newly" encountered suite.
139
+ return if @restarting_current_suite
140
+
141
+ @total_failed_test_cases = 0
142
+ @total_passed_test_cases = 0
143
+ @tests_results = Hash.new # test_case -> duration
144
+ @errors = Hash.new # test_case -> error_msg
145
+ @ended_current_test_suite = false
146
+ @cur_start_time = start_time
147
+ end
148
+
149
+ def handle_end_test_suite(test_name,end_time)
150
+ unless @ended_current_test_suite
151
+ current_file = File.open("#{TEST_REPORTS_FOLDER}/TEST-#{test_name}.xml", 'w')
152
+ host_name = string_to_xml Socket.gethostname
153
+ test_name = string_to_xml test_name
154
+ test_duration = (end_time - @cur_start_time).to_s
155
+ total_tests = @total_failed_test_cases + @total_passed_test_cases
156
+ suite_info = '<testsuite errors="0" failures="'+@total_failed_test_cases.to_s+'" hostname="'+host_name+'" name="'+test_name+'" tests="'+total_tests.to_s+'" time="'+test_duration.to_s+'" timestamp="'+end_time.to_s+'">'
157
+ current_file << "<?xml version='1.0' encoding='UTF-8' ?>\n"
158
+ current_file << suite_info
159
+ @tests_results.each do |t|
160
+ test_case = string_to_xml t[0]
161
+ duration = @tests_results[test_case]
162
+ current_file << "<testcase classname='#{test_name}' name='#{test_case}' time='#{duration.to_s}'"
163
+ unless @errors[test_case].nil?
164
+ # uh oh we got a failure
165
+ puts "tests_errors[0]"
166
+ puts @errors[test_case][0]
167
+ puts "tests_errors[1]"
168
+ puts @errors[test_case][1]
169
+
170
+ message = string_to_xml @errors[test_case][0].to_s
171
+ location = string_to_xml @errors[test_case][1].to_s
172
+ current_file << ">\n"
173
+ current_file << "<failure message='#{message}' type='Failure'>#{location}</failure>\n"
174
+ current_file << "</testcase>\n"
175
+ else
176
+ current_file << " />\n"
177
+ end
178
+ end
179
+ current_file << "</testsuite>\n"
180
+ current_file.close
181
+ @ended_current_test_suite = true
182
+ @restarting_current_suite = false
183
+ end
184
+ end
185
+
186
+ def string_to_xml(s)
187
+ s.gsub(/&/, '&amp;').gsub(/'/, '&quot;').gsub(/</, '&lt;')
188
+ end
189
+
190
+ def handle_test_passed(test_case,test_case_duration)
191
+ @total_passed_test_cases += 1
192
+ @tests_results[test_case] = test_case_duration
193
+ end
194
+
195
+ def handle_test_error(test_suite,test_case,error_message,error_location)
196
+ # Only record the first error for a test_case
197
+ if @errors[test_case].nil?
198
+ @errors[test_case] = [ error_message, error_location ]
199
+ end
200
+ end
201
+
202
+ def handle_test_failed(test_case,test_case_duration)
203
+ @total_failed_test_cases +=1
204
+ @tests_results[test_case] = test_case_duration
205
+ end
206
+
207
+ def get_test_case_name(test_case, description)
208
+ # Kiwi 1.x
209
+ if SUPPORT_KIWI && test_case == "example" && description
210
+ description
211
+ # Kiwi 2.x
212
+ elsif SUPPORT_KIWI && test_case =~ /(.+_)+(Should.+)(_.+)*/
213
+ test_case.gsub(/([A-Z])([A-Z][a-z]+)/, ' \1 \2')
214
+ .gsub(/([A-Z][a-z]+)/, ' \1')
215
+ .gsub(/([A-Z][A-Z]+)/, ' \1')
216
+ .gsub(/([^A-Za-z ]+)/, ' \1')
217
+ .gsub(/\s+/, ' ')
218
+ .split(" _ ")[1..-1].join(", ")
219
+ .downcase.capitalize
220
+ else
221
+ test_case
222
+ end
223
+ end
224
+
225
+ end
226
+
227
+ #Main
228
+ #piped_input = File.open("tests_fail.txt") # for debugging this script
229
+ piped_input = ARGF.readlines
230
+
231
+ report = ReportParser.new(piped_input)
232
+
233
+ exit report.exit_code
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lupocunit2junit
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.0'
5
+ platform: ruby
6
+ authors:
7
+ - Christian HedinMichael Lupo
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-10-27 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: 'Simply pipe your xcodebuild output through ocunit2junit: xcodebuild
14
+ ... | lupocunit2junit.rb'
15
+ email:
16
+ executables:
17
+ - lupocunit2junit
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - bin/lupocunit2junit
22
+ homepage: https://github.com/mikelupo/LUPOCUnit2JUnit
23
+ licenses: []
24
+ metadata: {}
25
+ post_install_message:
26
+ rdoc_options: []
27
+ require_paths:
28
+ - lib
29
+ required_ruby_version: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ required_rubygems_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ requirements: []
40
+ rubyforge_project:
41
+ rubygems_version: 2.0.14.1
42
+ signing_key:
43
+ specification_version: 4
44
+ summary: A script that converts OCUnit (and Kiwi) output to JUnit style XML output.
45
+ test_files: []