xcpretty-security-patched 0.3.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.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/.hound.yml +2 -0
- data/.kick +17 -0
- data/.rubocop.yml +239 -0
- data/.travis.yml +12 -0
- data/CHANGELOG.md +269 -0
- data/CONTRIBUTING.md +64 -0
- data/Gemfile +9 -0
- data/LICENSE.txt +61 -0
- data/README.md +95 -0
- data/Rakefile +18 -0
- data/assets/report.html.erb +173 -0
- data/bin/xcpretty +90 -0
- data/features/assets/RACCommandSpec_enabled_signal_should_send_YES_while_executing_is_YES.png +0 -0
- data/features/assets/apple_raw.png +0 -0
- data/features/custom_formatter.feature +15 -0
- data/features/custom_reporter.feature +29 -0
- data/features/fixtures/xcodebuild.log +5963 -0
- data/features/html_report.feature +54 -0
- data/features/json_compilation_database_report.feature +33 -0
- data/features/junit_report.feature +49 -0
- data/features/knock_format.feature +11 -0
- data/features/simple_format.feature +238 -0
- data/features/steps/custom_reporter_steps.rb +16 -0
- data/features/steps/formatting_steps.rb +386 -0
- data/features/steps/html_steps.rb +32 -0
- data/features/steps/json_steps.rb +45 -0
- data/features/steps/junit_steps.rb +39 -0
- data/features/steps/report_steps.rb +27 -0
- data/features/steps/xcpretty_steps.rb +31 -0
- data/features/support/env.rb +123 -0
- data/features/tap_format.feature +31 -0
- data/features/test_format.feature +49 -0
- data/features/xcpretty.feature +14 -0
- data/lib/xcpretty/ansi.rb +72 -0
- data/lib/xcpretty/formatters/formatter.rb +200 -0
- data/lib/xcpretty/formatters/knock.rb +35 -0
- data/lib/xcpretty/formatters/rspec.rb +33 -0
- data/lib/xcpretty/formatters/simple.rb +200 -0
- data/lib/xcpretty/formatters/tap.rb +40 -0
- data/lib/xcpretty/parser.rb +596 -0
- data/lib/xcpretty/printer.rb +28 -0
- data/lib/xcpretty/reporters/html.rb +93 -0
- data/lib/xcpretty/reporters/json_compilation_database.rb +51 -0
- data/lib/xcpretty/reporters/junit.rb +102 -0
- data/lib/xcpretty/reporters/reporter.rb +62 -0
- data/lib/xcpretty/snippet.rb +38 -0
- data/lib/xcpretty/syntax.rb +58 -0
- data/lib/xcpretty/term.rb +14 -0
- data/lib/xcpretty/version.rb +4 -0
- data/lib/xcpretty.rb +38 -0
- data/spec/fixtures/NSStringTests.m +64 -0
- data/spec/fixtures/constants.rb +707 -0
- data/spec/fixtures/custom_formatter.rb +18 -0
- data/spec/fixtures/custom_reporter.rb +30 -0
- data/spec/fixtures/oneliner.m +1 -0
- data/spec/fixtures/raw_kiwi_compilation_fail.txt +24 -0
- data/spec/fixtures/raw_kiwi_fail.txt +1896 -0
- data/spec/fixtures/raw_specta_fail.txt +3110 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/support/matchers/colors.rb +21 -0
- data/spec/xcpretty/ansi_spec.rb +47 -0
- data/spec/xcpretty/formatters/formatter_spec.rb +151 -0
- data/spec/xcpretty/formatters/rspec_spec.rb +56 -0
- data/spec/xcpretty/formatters/simple_spec.rb +178 -0
- data/spec/xcpretty/parser_spec.rb +636 -0
- data/spec/xcpretty/printer_spec.rb +55 -0
- data/spec/xcpretty/reporters/junit_spec.rb +20 -0
- data/spec/xcpretty/reporters/reporter_spec.rb +40 -0
- data/spec/xcpretty/snippet_spec.rb +46 -0
- data/spec/xcpretty/syntax_spec.rb +39 -0
- data/spec/xcpretty/term_spec.rb +26 -0
- data/xcpretty.gemspec +37 -0
- metadata +250 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
Feature: Showing Test Anything Protocol-compatible test output
|
2
|
+
|
3
|
+
Scenario: Showing failed tests
|
4
|
+
Given I have a failing test in my suite
|
5
|
+
When I pipe to xcpretty with "--tap"
|
6
|
+
Then I should see text beginning with "not ok 1"
|
7
|
+
|
8
|
+
Scenario: Showing passing tests
|
9
|
+
Given I have a passing test in my suite
|
10
|
+
When I pipe to xcpretty with "--tap"
|
11
|
+
Then I should see text beginning with "ok 1"
|
12
|
+
|
13
|
+
Scenario: Showing pending tests
|
14
|
+
Given I have a pending test in my suite
|
15
|
+
When I pipe to xcpretty with "--tap"
|
16
|
+
Then I should see text containing " # TODO" and beginning with "not ok 1"
|
17
|
+
|
18
|
+
Scenario: Showing how many tests completed
|
19
|
+
Given I have a pending test in my suite
|
20
|
+
And I have a passing test in my suite
|
21
|
+
And I have a failing test in my suite
|
22
|
+
And the test suite has finished
|
23
|
+
When I pipe to xcpretty with "--tap"
|
24
|
+
Then I should see text matching "1..3"
|
25
|
+
|
26
|
+
Scenario: Showing a running test counter
|
27
|
+
Given I have a passing test in my suite
|
28
|
+
And I have a failing test in my suite
|
29
|
+
When I pipe to xcpretty with "--tap"
|
30
|
+
Then I should see text beginning with "ok 1"
|
31
|
+
And I should see text beginning with "not ok 2"
|
@@ -0,0 +1,49 @@
|
|
1
|
+
Feature: Showing RSpec-style test output
|
2
|
+
|
3
|
+
Scenario: Showing failed tests
|
4
|
+
Given I have a failing test in my suite
|
5
|
+
When I pipe to xcpretty with "--test --no-color"
|
6
|
+
Then I should see a failed test icon
|
7
|
+
|
8
|
+
Scenario: Showing passing tests
|
9
|
+
Given I have a passing test in my suite
|
10
|
+
When I pipe to xcpretty with "--test --no-color"
|
11
|
+
Then I should see a passing test icon in ASCII
|
12
|
+
|
13
|
+
Scenario: Showing pending tests
|
14
|
+
Given I have a pending test in my suite
|
15
|
+
When I pipe to xcpretty with "--test --no-color"
|
16
|
+
Then I should see a pending test icon in ASCII
|
17
|
+
|
18
|
+
Scenario: Showing measuring tests
|
19
|
+
Given I have a measuring test in my suite
|
20
|
+
When I pipe to xcpretty with "--test --no-color"
|
21
|
+
Then I should see a measuring test icon in ASCII
|
22
|
+
|
23
|
+
Scenario: Showing some tests failed with color
|
24
|
+
Given I have a failing test in my suite
|
25
|
+
And the test suite has finished
|
26
|
+
When I pipe to xcpretty with "--test --color"
|
27
|
+
Then I should see a red failed test icon
|
28
|
+
And I should see the path of a failed test
|
29
|
+
And the final execution message should be red
|
30
|
+
|
31
|
+
Scenario: Showing passing tests with color
|
32
|
+
Given I have a passing test in my suite
|
33
|
+
When I pipe to xcpretty with "--test --color"
|
34
|
+
Then I should see a green passing test icon
|
35
|
+
|
36
|
+
Scenario: Showing pending tests with color
|
37
|
+
Given I have a pending test in my suite
|
38
|
+
When I pipe to xcpretty with "--test --color"
|
39
|
+
Then I should see a yellow pending test icon
|
40
|
+
|
41
|
+
Scenario: Showing measuring tests with color
|
42
|
+
Given I have a measuring test in my suite
|
43
|
+
When I pipe to xcpretty with "--test --color"
|
44
|
+
Then I should see a yellow measuring test icon
|
45
|
+
|
46
|
+
Scenario: Showing that all tests passed with color
|
47
|
+
Given all of my tests will pass in my suite
|
48
|
+
When I pipe to xcpretty with "--test --color"
|
49
|
+
Then the final execution message should be green
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Feature: CLI behavior
|
2
|
+
|
3
|
+
Scenario: Starting xcpretty without any flags
|
4
|
+
When I run xcpretty
|
5
|
+
Then I should see the help banner
|
6
|
+
|
7
|
+
Scenario: Starting xcpretty with version
|
8
|
+
When I run xcpretty with -v
|
9
|
+
Then I should see the xcpretty version
|
10
|
+
|
11
|
+
Scenario: Performance
|
12
|
+
When I run xcpretty over a big file
|
13
|
+
Then the performance should be way faster than running cat
|
14
|
+
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module XCPretty
|
2
|
+
module ANSI
|
3
|
+
|
4
|
+
attr_accessor :colorize
|
5
|
+
|
6
|
+
FORMATTED_MATCHER = %r{\e\[(\d+)[;]?(\d+)?m(.*)\e\[0m}
|
7
|
+
|
8
|
+
EFFECT = {
|
9
|
+
reset: '0',
|
10
|
+
bold: '1',
|
11
|
+
underline: '4'
|
12
|
+
}
|
13
|
+
|
14
|
+
COLORS = {
|
15
|
+
black: '30',
|
16
|
+
red: '31',
|
17
|
+
green: '32',
|
18
|
+
yellow: '33',
|
19
|
+
blue: '34',
|
20
|
+
cyan: '36',
|
21
|
+
white: '37',
|
22
|
+
plain: '39'
|
23
|
+
}
|
24
|
+
|
25
|
+
def colorize?
|
26
|
+
!!@colorize
|
27
|
+
end
|
28
|
+
|
29
|
+
def white(text)
|
30
|
+
ansi_parse(text, :plain, :bold)
|
31
|
+
end
|
32
|
+
|
33
|
+
def red(text)
|
34
|
+
ansi_parse(text, :red)
|
35
|
+
end
|
36
|
+
|
37
|
+
def green(text)
|
38
|
+
ansi_parse(text, :green, :bold)
|
39
|
+
end
|
40
|
+
|
41
|
+
def cyan(text)
|
42
|
+
ansi_parse(text, :cyan)
|
43
|
+
end
|
44
|
+
|
45
|
+
def yellow(text)
|
46
|
+
ansi_parse(text, :yellow)
|
47
|
+
end
|
48
|
+
|
49
|
+
def applied_effects(text)
|
50
|
+
effects = []
|
51
|
+
if text =~ FORMATTED_MATCHER
|
52
|
+
colors = COLORS.invert[$1]
|
53
|
+
effect = EFFECT.invert[$2]
|
54
|
+
effects << colors if colors
|
55
|
+
effects << effect if effect
|
56
|
+
end
|
57
|
+
effects
|
58
|
+
end
|
59
|
+
|
60
|
+
def strip(text)
|
61
|
+
text =~ FORMATTED_MATCHER ? $3 : text
|
62
|
+
end
|
63
|
+
|
64
|
+
def ansi_parse(text, color, effect=nil)
|
65
|
+
return text unless colorize?
|
66
|
+
colors_code = COLORS[color] || ''
|
67
|
+
effect_code = EFFECT[effect] ? ';' + EFFECT[effect] : ''
|
68
|
+
"\e[#{colors_code}#{effect_code}m#{text}\e[#{EFFECT[:reset]}m"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
@@ -0,0 +1,200 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'xcpretty/ansi'
|
3
|
+
require 'xcpretty/parser'
|
4
|
+
|
5
|
+
module XCPretty
|
6
|
+
|
7
|
+
# Making a new formatter is easy.
|
8
|
+
# Just make a subclass of Formatter, and override any of these methods.
|
9
|
+
module FormatMethods
|
10
|
+
EMPTY = ''.freeze
|
11
|
+
|
12
|
+
def format_analyze(file_name, file_path); EMPTY; end
|
13
|
+
def format_build_target(target, project, configuration); EMPTY; end
|
14
|
+
def format_aggregate_target(target, project, configuration); EMPTY; end
|
15
|
+
def format_analyze_target(target, project, configuration); EMPTY; end
|
16
|
+
def format_check_dependencies; EMPTY; end
|
17
|
+
def format_clean(project, target, configuration); EMPTY; end
|
18
|
+
def format_clean_target(target, project, configuration); EMPTY; end
|
19
|
+
def format_clean_remove; EMPTY; end
|
20
|
+
def format_compile(file_name, file_path); EMPTY; end
|
21
|
+
def format_compile_command(compiler_command, file_path); EMPTY; end
|
22
|
+
def format_compile_storyboard(file_name, file_path); EMPTY; end
|
23
|
+
def format_compile_xib(file_name, file_path); EMPTY; end
|
24
|
+
def format_copy_header_file(source, target); EMPTY; end
|
25
|
+
def format_copy_plist_file(source, target); EMPTY; end
|
26
|
+
def format_copy_strings_file(file_name); EMPTY; end
|
27
|
+
def format_cpresource(file); EMPTY; end
|
28
|
+
def format_generate_dsym(dsym); EMPTY; end
|
29
|
+
def format_linking(file, build_variant, arch); EMPTY; end
|
30
|
+
def format_libtool(library); EMPTY; end
|
31
|
+
def format_passing_test(suite, test, time); EMPTY; end
|
32
|
+
def format_pending_test(suite, test); EMPTY; end
|
33
|
+
def format_measuring_test(suite, test, time); EMPTY; end
|
34
|
+
def format_failing_test(suite, test, reason, file_path); EMPTY; end
|
35
|
+
def format_process_pch(file); EMPTY; end
|
36
|
+
def format_process_pch_command(file_path); EMPTY; end
|
37
|
+
def format_phase_success(phase_name); EMPTY; end
|
38
|
+
def format_phase_script_execution(script_name); EMPTY; end
|
39
|
+
def format_process_info_plist(file_name, file_path); EMPTY; end
|
40
|
+
def format_codesign(file); EMPTY; end
|
41
|
+
def format_preprocess(file); EMPTY; end
|
42
|
+
def format_pbxcp(file); EMPTY; end
|
43
|
+
def format_shell_command(command, arguments); EMPTY; end
|
44
|
+
def format_test_run_started(name); EMPTY; end
|
45
|
+
def format_test_run_finished(name, time); EMPTY; end
|
46
|
+
def format_test_suite_started(name); EMPTY; end
|
47
|
+
def format_test_summary(message, failures_per_suite); EMPTY; end
|
48
|
+
def format_touch(file_path, file_name); EMPTY; end
|
49
|
+
def format_tiffutil(file); EMPTY; end
|
50
|
+
def format_write_file(file); EMPTY; end
|
51
|
+
def format_write_auxiliary_files; EMPTY; end
|
52
|
+
def format_other(text) EMPTY; end
|
53
|
+
|
54
|
+
# COMPILER / LINKER ERRORS AND WARNINGS
|
55
|
+
def format_compile_error(file_name, file_path, reason,
|
56
|
+
line, cursor); EMPTY; end
|
57
|
+
def format_error(message); EMPTY; end
|
58
|
+
def format_file_missing_error(error, file_path); EMPTY; end
|
59
|
+
def format_ld_warning(message); EMPTY; end
|
60
|
+
def format_undefined_symbols(message, symbol, reference); EMPTY; end
|
61
|
+
def format_duplicate_symbols(message, file_paths); EMPTY; end
|
62
|
+
def format_warning(message); message; end
|
63
|
+
|
64
|
+
# TODO: see how we can unify format_error and format_compile_error,
|
65
|
+
# the same for warnings
|
66
|
+
def format_compile_warning(file_name, file_path, reason,
|
67
|
+
line, cursor); EMPTY; end
|
68
|
+
end
|
69
|
+
|
70
|
+
class Formatter
|
71
|
+
|
72
|
+
include ANSI
|
73
|
+
include FormatMethods
|
74
|
+
|
75
|
+
attr_reader :parser
|
76
|
+
|
77
|
+
def initialize(use_unicode, colorize)
|
78
|
+
@use_unicode = use_unicode
|
79
|
+
@colorize = colorize
|
80
|
+
@parser = Parser.new(self)
|
81
|
+
end
|
82
|
+
|
83
|
+
def finish
|
84
|
+
end
|
85
|
+
|
86
|
+
# Override if you want to catch something specific with your regex
|
87
|
+
def pretty_format(text)
|
88
|
+
parser.parse(text)
|
89
|
+
end
|
90
|
+
|
91
|
+
# If you want to print inline, override #optional_newline with ''
|
92
|
+
def optional_newline
|
93
|
+
"\n"
|
94
|
+
end
|
95
|
+
|
96
|
+
def use_unicode?
|
97
|
+
!!@use_unicode
|
98
|
+
end
|
99
|
+
|
100
|
+
# Will be printed by default. Override with '' if you don't want summary
|
101
|
+
def format_test_summary(executed_message, failures_per_suite)
|
102
|
+
failures = format_failures(failures_per_suite)
|
103
|
+
if failures.empty?
|
104
|
+
final_message = green(executed_message)
|
105
|
+
else
|
106
|
+
final_message = red(executed_message)
|
107
|
+
end
|
108
|
+
|
109
|
+
text = [failures, final_message].join("\n\n\n").strip
|
110
|
+
"\n\n#{text}"
|
111
|
+
end
|
112
|
+
|
113
|
+
ERROR = '❌ '
|
114
|
+
ASCII_ERROR = '[x]'
|
115
|
+
|
116
|
+
WARNING = '⚠️ '
|
117
|
+
ASCII_WARNING = '[!]'
|
118
|
+
|
119
|
+
def format_error(message)
|
120
|
+
"\n#{red(error_symbol + " " + message)}\n\n"
|
121
|
+
end
|
122
|
+
|
123
|
+
def format_compile_error(file, file_path, reason, line, cursor)
|
124
|
+
"\n#{red(error_symbol + " ")}#{file_path}: #{red(reason)}\n\n" \
|
125
|
+
"#{line}\n#{cyan(cursor)}\n\n"
|
126
|
+
end
|
127
|
+
|
128
|
+
def format_file_missing_error(reason, file_path)
|
129
|
+
"\n#{red(error_symbol + " " + reason)} #{file_path}\n\n"
|
130
|
+
end
|
131
|
+
|
132
|
+
def format_compile_warning(file, file_path, reason, line, cursor)
|
133
|
+
"\n#{yellow(warning_symbol + ' ')}#{file_path}: #{yellow(reason)}\n\n" \
|
134
|
+
"#{line}\n#{cyan(cursor)}\n\n"
|
135
|
+
end
|
136
|
+
|
137
|
+
def format_ld_warning(reason)
|
138
|
+
"#{yellow(warning_symbol + ' ' + reason)}"
|
139
|
+
end
|
140
|
+
|
141
|
+
def format_undefined_symbols(message, symbol, reference)
|
142
|
+
"\n#{red(error_symbol + " " + message)}\n" \
|
143
|
+
"> Symbol: #{symbol}\n" \
|
144
|
+
"> Referenced from: #{reference}\n\n"
|
145
|
+
end
|
146
|
+
|
147
|
+
def format_duplicate_symbols(message, file_paths)
|
148
|
+
"\n#{red(error_symbol + " " + message)}\n" \
|
149
|
+
"> #{file_paths.map { |path| path.split('/').last }.join("\n> ")}\n"
|
150
|
+
end
|
151
|
+
|
152
|
+
def format_will_not_be_code_signed(message)
|
153
|
+
"#{yellow(warning_symbol + " " + message)}"
|
154
|
+
end
|
155
|
+
|
156
|
+
def format_other(text)
|
157
|
+
""
|
158
|
+
end
|
159
|
+
|
160
|
+
|
161
|
+
private
|
162
|
+
|
163
|
+
def format_failures(failures_per_suite)
|
164
|
+
failures_per_suite.map do |suite, failures|
|
165
|
+
formatted_failures = failures.map do |failure|
|
166
|
+
format_failure(failure)
|
167
|
+
end.join("\n\n")
|
168
|
+
|
169
|
+
"\n#{suite}\n#{formatted_failures}"
|
170
|
+
end.join("\n")
|
171
|
+
end
|
172
|
+
|
173
|
+
def format_failure(f)
|
174
|
+
snippet = Snippet.from_filepath(f[:file_path])
|
175
|
+
output = " #{f[:test_case]}, #{red(f[:reason])}"
|
176
|
+
output += "\n #{cyan(f[:file_path])}"
|
177
|
+
return output if snippet.contents.empty?
|
178
|
+
|
179
|
+
output += "\n ```\n"
|
180
|
+
if @colorize
|
181
|
+
output += Syntax.highlight(snippet)
|
182
|
+
else
|
183
|
+
output += snippet.contents
|
184
|
+
end
|
185
|
+
|
186
|
+
output += " ```"
|
187
|
+
output
|
188
|
+
end
|
189
|
+
|
190
|
+
def error_symbol
|
191
|
+
use_unicode? ? ERROR : ASCII_ERROR
|
192
|
+
end
|
193
|
+
|
194
|
+
def warning_symbol
|
195
|
+
use_unicode? ? WARNING : ASCII_WARNING
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module XCPretty
|
2
|
+
|
3
|
+
class Knock < Formatter
|
4
|
+
|
5
|
+
FAIL = 'not ok'
|
6
|
+
PASS = 'ok'
|
7
|
+
|
8
|
+
def format_passing_test(suite, test_case, time)
|
9
|
+
"#{PASS} - #{test_case}"
|
10
|
+
end
|
11
|
+
|
12
|
+
def format_failing_test(test_suite, test_case, reason, file)
|
13
|
+
"#{FAIL} - #{test_case}: FAILED" +
|
14
|
+
format_failure_diagnostics(test_suite, test_case, reason, file)
|
15
|
+
end
|
16
|
+
|
17
|
+
def format_test_summary(executed_message, failures_per_suite)
|
18
|
+
''
|
19
|
+
end
|
20
|
+
|
21
|
+
def format_failure_diagnostics(test_suite, test_case, reason, file)
|
22
|
+
format_diagnostics(reason) +
|
23
|
+
format_diagnostics(" #{file}: #{test_suite} - #{test_case}")
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def format_diagnostics(text)
|
29
|
+
"\n# #{text}"
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module XCPretty
|
2
|
+
|
3
|
+
class RSpec < Formatter
|
4
|
+
|
5
|
+
FAIL = "F"
|
6
|
+
PASS = "."
|
7
|
+
PENDING = "P"
|
8
|
+
MEASURING = 'T'
|
9
|
+
|
10
|
+
def optional_newline
|
11
|
+
''
|
12
|
+
end
|
13
|
+
|
14
|
+
def format_passing_test(suite, test_case, time)
|
15
|
+
green(PASS)
|
16
|
+
end
|
17
|
+
|
18
|
+
def format_failing_test(test_suite, test_case, reason, file)
|
19
|
+
red(FAIL)
|
20
|
+
end
|
21
|
+
|
22
|
+
def format_pending_test(suite, test_case)
|
23
|
+
yellow(PENDING)
|
24
|
+
end
|
25
|
+
|
26
|
+
def format_measuring_test(suite, test_case, time)
|
27
|
+
yellow(MEASURING)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
@@ -0,0 +1,200 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'shellwords'
|
3
|
+
|
4
|
+
module XCPretty
|
5
|
+
|
6
|
+
class Simple < Formatter
|
7
|
+
|
8
|
+
PASS = "✓"
|
9
|
+
FAIL = "✗"
|
10
|
+
PENDING = "⧖"
|
11
|
+
COMPLETION = "▸"
|
12
|
+
MEASURE = '◷'
|
13
|
+
|
14
|
+
ASCII_PASS = "."
|
15
|
+
ASCII_FAIL = "x"
|
16
|
+
ASCII_PENDING = "P"
|
17
|
+
ASCII_COMPLETION = ">"
|
18
|
+
ASCII_MEASURE = 'T'
|
19
|
+
|
20
|
+
INDENT = " "
|
21
|
+
|
22
|
+
def format_analyze(file_name, file_path)
|
23
|
+
format("Analyzing", file_name)
|
24
|
+
end
|
25
|
+
|
26
|
+
def format_build_target(target, project, configuration)
|
27
|
+
format("Building", "#{project}/#{target} [#{configuration}]")
|
28
|
+
end
|
29
|
+
|
30
|
+
def format_aggregate_target(target, project, configuration)
|
31
|
+
format("Aggregate", "#{project}/#{target} [#{configuration}]")
|
32
|
+
end
|
33
|
+
|
34
|
+
def format_analyze_target(target, project, configuration)
|
35
|
+
format("Analyzing", "#{project}/#{target} [#{configuration}]")
|
36
|
+
end
|
37
|
+
|
38
|
+
def format_clean_target(target, project, configuration)
|
39
|
+
format("Cleaning", "#{project}/#{target} [#{configuration}]")
|
40
|
+
end
|
41
|
+
|
42
|
+
def format_compile(file_name, file_path)
|
43
|
+
format("Compiling", file_name)
|
44
|
+
end
|
45
|
+
|
46
|
+
def format_compile_xib(file_name, file_path)
|
47
|
+
format("Compiling", file_name)
|
48
|
+
end
|
49
|
+
|
50
|
+
def format_compile_storyboard(file_name, file_path)
|
51
|
+
format("Compiling", file_name)
|
52
|
+
end
|
53
|
+
|
54
|
+
def format_copy_header_file(source, target)
|
55
|
+
format("Copying", File.basename(source))
|
56
|
+
end
|
57
|
+
|
58
|
+
def format_copy_plist_file(source, target)
|
59
|
+
format("Copying", File.basename(source))
|
60
|
+
end
|
61
|
+
|
62
|
+
def format_copy_strings_file(file)
|
63
|
+
format("Copying", file)
|
64
|
+
end
|
65
|
+
|
66
|
+
def format_cpresource(resource)
|
67
|
+
format("Copying", resource)
|
68
|
+
end
|
69
|
+
|
70
|
+
def format_generate_dsym(dsym)
|
71
|
+
format("Generating '#{dsym}'")
|
72
|
+
end
|
73
|
+
|
74
|
+
def format_libtool(library)
|
75
|
+
format("Building library", library)
|
76
|
+
end
|
77
|
+
|
78
|
+
def format_linking(target, build_variants, arch)
|
79
|
+
format("Linking", target)
|
80
|
+
end
|
81
|
+
|
82
|
+
def format_failing_test(suite, test_case, reason, file)
|
83
|
+
INDENT + format_test("#{test_case}, #{reason}", :fail)
|
84
|
+
end
|
85
|
+
|
86
|
+
def format_passing_test(suite, test_case, time)
|
87
|
+
INDENT + format_test("#{test_case} (#{colored_time(time)} seconds)",
|
88
|
+
:pass)
|
89
|
+
end
|
90
|
+
|
91
|
+
def format_pending_test(suite, test_case)
|
92
|
+
INDENT + format_test("#{test_case} [PENDING]", :pending)
|
93
|
+
end
|
94
|
+
|
95
|
+
def format_measuring_test(suite, test_case, time)
|
96
|
+
INDENT + format_test(
|
97
|
+
"#{test_case} measured (#{colored_time(time)} seconds)", :measure
|
98
|
+
)
|
99
|
+
end
|
100
|
+
|
101
|
+
def format_phase_success(phase_name)
|
102
|
+
format(phase_name.capitalize, "Succeeded")
|
103
|
+
end
|
104
|
+
|
105
|
+
def format_phase_script_execution(script_name)
|
106
|
+
format("Running script", "'#{script_name}'")
|
107
|
+
end
|
108
|
+
|
109
|
+
def format_process_info_plist(file_name, file_path)
|
110
|
+
format("Processing", file_name)
|
111
|
+
end
|
112
|
+
|
113
|
+
def format_process_pch(file)
|
114
|
+
format("Precompiling", file)
|
115
|
+
end
|
116
|
+
|
117
|
+
def format_codesign(file)
|
118
|
+
format("Signing", file)
|
119
|
+
end
|
120
|
+
|
121
|
+
def format_preprocess(file)
|
122
|
+
format("Preprocessing", file)
|
123
|
+
end
|
124
|
+
|
125
|
+
def format_pbxcp(file)
|
126
|
+
format("Copying", file)
|
127
|
+
end
|
128
|
+
|
129
|
+
def format_test_run_started(name)
|
130
|
+
heading("Test Suite", name, "started")
|
131
|
+
end
|
132
|
+
|
133
|
+
def format_test_suite_started(name)
|
134
|
+
heading("", name, "")
|
135
|
+
end
|
136
|
+
|
137
|
+
def format_touch(file_path, file_name)
|
138
|
+
format("Touching", file_name)
|
139
|
+
end
|
140
|
+
|
141
|
+
def format_tiffutil(file_name)
|
142
|
+
format("Validating", file_name)
|
143
|
+
end
|
144
|
+
|
145
|
+
def format_warning(message)
|
146
|
+
INDENT + yellow(message)
|
147
|
+
end
|
148
|
+
|
149
|
+
def format_check_dependencies
|
150
|
+
format('Check Dependencies')
|
151
|
+
end
|
152
|
+
|
153
|
+
private
|
154
|
+
|
155
|
+
def heading(prefix, text, description)
|
156
|
+
[prefix, white(text), description].join(" ").strip
|
157
|
+
end
|
158
|
+
|
159
|
+
def format(command, argument_text="", success=true)
|
160
|
+
symbol = status_symbol(success ? :completion : :fail)
|
161
|
+
[symbol, white(command), argument_text].join(" ").strip
|
162
|
+
end
|
163
|
+
|
164
|
+
def format_test(test_case, status)
|
165
|
+
[status_symbol(status), test_case].join(" ").strip
|
166
|
+
end
|
167
|
+
|
168
|
+
def status_symbol(status)
|
169
|
+
case status
|
170
|
+
when :pass
|
171
|
+
green(use_unicode? ? PASS : ASCII_PASS)
|
172
|
+
when :fail
|
173
|
+
red(use_unicode? ? FAIL : ASCII_FAIL)
|
174
|
+
when :pending
|
175
|
+
yellow(use_unicode? ? PENDING : ASCII_PENDING)
|
176
|
+
when :error
|
177
|
+
red(use_unicode? ? ERROR : ASCII_ERROR)
|
178
|
+
when :completion
|
179
|
+
yellow(use_unicode? ? COMPLETION : ASCII_COMPLETION)
|
180
|
+
when :measure
|
181
|
+
yellow(use_unicode? ? MEASURE : ASCII_MEASURE)
|
182
|
+
else
|
183
|
+
""
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def colored_time(time)
|
188
|
+
case time.to_f
|
189
|
+
when 0..0.025
|
190
|
+
time
|
191
|
+
when 0.026..0.100
|
192
|
+
yellow(time)
|
193
|
+
else
|
194
|
+
red(time)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module XCPretty
|
2
|
+
|
3
|
+
class TestAnything < Knock
|
4
|
+
|
5
|
+
attr_reader :counter
|
6
|
+
|
7
|
+
def initialize(unicode, color)
|
8
|
+
super
|
9
|
+
@counter = 0
|
10
|
+
end
|
11
|
+
|
12
|
+
def format_passing_test(suite, test_case, time)
|
13
|
+
increment_counter
|
14
|
+
"#{PASS} #{counter} - #{test_case}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def format_failing_test(test_suite, test_case, reason, file)
|
18
|
+
increment_counter
|
19
|
+
"#{FAIL} #{counter} - #{test_case}" +
|
20
|
+
format_failure_diagnostics(test_suite, test_case, reason, file)
|
21
|
+
end
|
22
|
+
|
23
|
+
def format_pending_test(test_suite, test_case)
|
24
|
+
increment_counter
|
25
|
+
"#{FAIL} #{counter} - #{test_case} # TODO Not written yet"
|
26
|
+
end
|
27
|
+
|
28
|
+
def format_test_summary(executed_message, failures_per_suite)
|
29
|
+
counter > 0 ? "1..#{counter}" : ''
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def increment_counter
|
35
|
+
@counter += 1
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|