xcpretty-security-patched 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/README.md
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
![logo](http://i.imgur.com/i2fElxx.png)
|
2
|
+
|
3
|
+
__`xcpretty` is a fast and flexible formatter for `xcodebuild`__.<br/>
|
4
|
+
It does one thing, and it should do it well.
|
5
|
+
|
6
|
+
[![Gem version](http://img.shields.io/gem/v/xcpretty.svg)](http://rubygems.org/gems/xcpretty)
|
7
|
+
[![Build Status](https://travis-ci.org/supermarin/xcpretty.svg?branch=master)](https://travis-ci.org/supermarin/xcpretty)
|
8
|
+
[![Code Climate](http://img.shields.io/codeclimate/github/supermarin/xcpretty.svg)](https://codeclimate.com/github/supermarin/xcpretty)
|
9
|
+
[![Reviewed by Hound](https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg)](https://houndci.com)
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
``` bash
|
13
|
+
$ gem install xcpretty
|
14
|
+
```
|
15
|
+
|
16
|
+
## Usage
|
17
|
+
``` bash
|
18
|
+
$ xcodebuild [flags] | xcpretty
|
19
|
+
```
|
20
|
+
`xcpretty` is designed to be piped with `xcodebuild` and thus keeping 100%
|
21
|
+
compatibility with it. It's even a bit faster than `xcodebuild` itself, since
|
22
|
+
it saves your terminal some prints.
|
23
|
+
|
24
|
+
__Important:__ If you're running `xcpretty` on a CI like Travis or Jenkins, you
|
25
|
+
may want to exit with same status code as `xcodebuild`.
|
26
|
+
CI systems usually use status codes to determine if the build has failed.
|
27
|
+
|
28
|
+
``` bash
|
29
|
+
$ set -o pipefail && xcodebuild [flags] | xcpretty
|
30
|
+
#
|
31
|
+
# OR
|
32
|
+
#
|
33
|
+
$ xcodebuild [flags] | xcpretty && exit ${PIPESTATUS[0]}
|
34
|
+
```
|
35
|
+
|
36
|
+
## Raw xcodebuild output
|
37
|
+
You might want to use `xcpretty` together with `tee` to store the raw log in a
|
38
|
+
file, and get the pretty output in the terminal. This might be useful if you
|
39
|
+
want to inspect a failure in detail and aren't able to tell from the pretty
|
40
|
+
output.
|
41
|
+
|
42
|
+
Here's a way of doing it:
|
43
|
+
``` bash
|
44
|
+
$ xcodebuild [flags] | tee xcodebuild.log | xcpretty
|
45
|
+
```
|
46
|
+
|
47
|
+
## Formats
|
48
|
+
|
49
|
+
- `--simple`, `-s` (default)
|
50
|
+
![xcpretty --simple](http://i.imgur.com/LdmozBS.gif)
|
51
|
+
|
52
|
+
- `--test`, `-t` (RSpec style)
|
53
|
+
![xcpretty alpha](http://i.imgur.com/VeTQQub.gif)
|
54
|
+
- `--tap` ([Test Anything Protocol](http://testanything.org)-compatible output)
|
55
|
+
- `--knock`, `-k` (a [simplified version](https://github.com/chneukirchen/knock) of the Test Anything Protocol)
|
56
|
+
|
57
|
+
## ANSI / UTF-8
|
58
|
+
|
59
|
+
- `--[no-]color`: Show build icons in color. (you can add it to `--simple` or `--test` format).
|
60
|
+
Defaults to auto-detecting color availability.
|
61
|
+
- `--[no-]utf`: Use unicode characters in build output or only ASCII.
|
62
|
+
Defaults to auto-detecting the current locale.
|
63
|
+
|
64
|
+
## Reporters
|
65
|
+
|
66
|
+
- `--report junit`, `-r junit`: Creates a JUnit-style XML report at `build/reports/junit.xml`, compatible with Jenkins and TeamCity CI.
|
67
|
+
|
68
|
+
- `--report html`, `-r html`: Creates a simple HTML report at `build/reports/tests.html`.
|
69
|
+
![xcpretty html](http://i.imgur.com/0Rnux3v.gif)
|
70
|
+
|
71
|
+
- `--report json-compilation-database`, `-r json-compilation-database`: Creates a [JSON compilation database](http://clang.llvm.org/docs/JSONCompilationDatabase.html) at `build/reports/compilation_db.json`. This is a format to replay single compilations independently of the build system.
|
72
|
+
|
73
|
+
Writing a report to a custom path can be specified using `--output PATH`.
|
74
|
+
|
75
|
+
## Extensions
|
76
|
+
|
77
|
+
`xcpretty` supports custom formatters through the use of the
|
78
|
+
`--formatter` flag, which takes a path to a file as an argument. The
|
79
|
+
file must contain a Ruby subclass of `XCPretty::Formatter`, and
|
80
|
+
return that class at the end of the file. The class
|
81
|
+
can override the `format_*` methods to hook into output parsing
|
82
|
+
events.
|
83
|
+
|
84
|
+
### Known extensions
|
85
|
+
|
86
|
+
* [xcpretty-travis-formatter](https://github.com/kattrali/xcpretty-travis-formatter): support for cleaner output in TravisCI using code folding
|
87
|
+
|
88
|
+
The recommended format is a gem containing the formatter and named
|
89
|
+
with an `xcpretty-` prefix, for easier discovery.
|
90
|
+
|
91
|
+
|
92
|
+
## Team
|
93
|
+
|
94
|
+
- [Marin Usalj](http://github.com/supermarin) http://supermar.in
|
95
|
+
- [Delisa Mason](http://github.com/kattrali) http://delisa.me
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
|
3
|
+
task :kick do
|
4
|
+
sh 'bundle exec kicker -r ruby'
|
5
|
+
end
|
6
|
+
|
7
|
+
task :spec do
|
8
|
+
sh 'bundle exec rspec --color --format=doc'
|
9
|
+
end
|
10
|
+
|
11
|
+
task :cucumber do
|
12
|
+
sh 'bundle exec cucumber'
|
13
|
+
end
|
14
|
+
|
15
|
+
task :lint do
|
16
|
+
sh 'bundle exec rubocop'
|
17
|
+
end
|
18
|
+
|
@@ -0,0 +1,173 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8" />
|
5
|
+
<title>Test Results | xcpretty</title>
|
6
|
+
<style type="text/css">
|
7
|
+
body { font-family:Avenir Next, Helvetica Neue, sans-serif; color: #4A4A4A; background-color: #F0F3FB; margin:0;}
|
8
|
+
h1 { font-weight: normal; font-size: 24px; margin: 10px 0 0 0;}
|
9
|
+
h3 { font-weight: normal; margin: 2px; font-size: 1.1em;}
|
10
|
+
header { position: fixed;width: 100%;background: rgba(249, 254, 255, 0.9);margin: 0;padding: 10px;}
|
11
|
+
header:before, header:after { content:""; display:table;}
|
12
|
+
header:after { clear:both;}
|
13
|
+
a:link { color: #A1D761;}
|
14
|
+
footer { clear: both;position: relative;z-index: 10;height: 40px;margin-top: -10px; margin-left:30px; font-size:12px;}
|
15
|
+
table { width:100%; border-collapse: collapse;}
|
16
|
+
tr td:first-child { width:7%}
|
17
|
+
.left { float: left; margin-left:30px;}
|
18
|
+
.right { float: right; margin-right: 40px; margin-top: 0; margin-bottom:0;}
|
19
|
+
.test-suite { margin: 0 0 30px 0;}
|
20
|
+
.test-suite > .heading { font-family:Menlo, Monaco, monospace; font-weight: bold; border-color: #A1D761; background-color: #B8E986; border-width: 1px;}
|
21
|
+
.test-suite.failing > .heading { border-color: #C84F5E; background-color: #E58591;}
|
22
|
+
.test-suite > .heading > .title { margin-top: 4px; margin-left: 10px;}
|
23
|
+
.tests { overflow: scroll;margin: 0 30px 0 60px;}
|
24
|
+
.test, .test-suite > .heading { height: 30px; overflow: hidden; margin: 0 30px;}
|
25
|
+
.test, .test-suite > .heading { border-width: 1px; border-collapse: collapse; border-style: solid; }
|
26
|
+
.test { margin-left: 30px; border-top:none;}
|
27
|
+
.test.failing { border-color: #C84F5E; background-color: #F4DDE0;}
|
28
|
+
.test.passing { border-color: #A1D761;}
|
29
|
+
.test.failing { background-color: #E7A1AA;}
|
30
|
+
.test.passing { background-color: #CAF59F;}
|
31
|
+
.test.failing.odd { background-color: #EEC7CC;}
|
32
|
+
.test.passing.odd { background-color: #E5FBCF;}
|
33
|
+
.details.failing { background-color: #F4DDE0; border: 1px solid #C84F5E;}
|
34
|
+
.details.passing { background-color: #E5F4DC; border: 1px solid #A1D761;}
|
35
|
+
.test .test-detail:last-child { padding-bottom: 8px;}
|
36
|
+
.test .title { float: left; font-size: 0.9em; margin-top: 8px; font-family: Menlo, Monaco, monospace;}
|
37
|
+
.test .time { float: left;margin: 4px 10px 0 20px;}
|
38
|
+
.test-detail { font-family:Menlo, Monaco, monospace; font-size: 0.9em; margin: 5px 0 5px 0px;}
|
39
|
+
.screenshots { height: auto; overflow: hidden; padding: 4px 4px 0 4px; background-color: #B8E986; border: #A1D761; border-width: 0 1px; border-style: solid; }
|
40
|
+
.screenshots.failing { border-color: #C84F5E; background-color: #E58591; }
|
41
|
+
.screenshot { max-height: 60px; float: left; transition: max-height 0.2s; margin: 0 4px 4px 0 }
|
42
|
+
.screenshot.selected { max-height: 568px; }
|
43
|
+
#test-suites { display: inline-block; width: 100%;margin-top:100px;}
|
44
|
+
#segment-bar { margin-top: 10px;margin-left: 14px;float:right;}
|
45
|
+
#segment-bar a:first-child { border-radius: 9px 0 0 9px; border-right: none;}
|
46
|
+
#segment-bar a:last-child { border-radius: 0 9px 9px 0; border-left: none;}
|
47
|
+
#segment-bar > a { color: #565656; border: 2px solid #7B7B7B; width: 80px; font-weight: bold; display:inline-block;text-align:center; font-weight: normal;}
|
48
|
+
#segment-bar > a.selected { background-color: #979797; color: #F0F3FB;}
|
49
|
+
#counters { float: left;margin: 10px;text-align: right;}
|
50
|
+
#counters h2 { font-size: 16px; font-family: Avenir, sans-serif; font-weight: lighter; display:inline;}
|
51
|
+
#counters .number { font-size: 20px;}
|
52
|
+
#fail-count { color: #D0021B; margin-left:10px;}
|
53
|
+
@media (max-width: 640px) {
|
54
|
+
h1, #counters, #segment-bar { margin: 5px auto; text-align:center;}
|
55
|
+
header, #segment-bar { width: 100%; position: relative; background:none;}
|
56
|
+
.left, .right { float:none; margin:0;}
|
57
|
+
#test-suites { margin-top: 0;}
|
58
|
+
#counters { float:none;}
|
59
|
+
}
|
60
|
+
</style>
|
61
|
+
<script type="text/javascript">
|
62
|
+
var hide = function(element) { element.style.display = 'none';}
|
63
|
+
var show = function(element) { element.style.display = '';}
|
64
|
+
var isHidden = function(element) { return element.style.display == 'none';}
|
65
|
+
var isSelected = function(element) { return element.classList.contains("selected");}
|
66
|
+
var deselect = function(element) { return element.classList.remove("selected");}
|
67
|
+
var select = function(element) { return element.classList.add("selected");}
|
68
|
+
var toggle = function(element) { isHidden(element) ? show(element) : hide(element);};
|
69
|
+
var toggleTests = function(heading) { toggle(heading.parentNode.children[1]);};
|
70
|
+
var toggleDetails = function(detailClass) {
|
71
|
+
var details = document.querySelectorAll('.' + detailClass);
|
72
|
+
for (var i = details.length - 1; i >= 0; i--) { toggle(details[i]);};
|
73
|
+
};
|
74
|
+
var hideAll = function(collection) {
|
75
|
+
for (var i = collection.length - 1; i >= 0; i--) { hide(collection[i]); };
|
76
|
+
}
|
77
|
+
var showAll = function(collection) {
|
78
|
+
for (var i = collection.length - 1; i >= 0; i--) { show(collection[i]); };
|
79
|
+
}
|
80
|
+
var selectSegment = function(segment) {
|
81
|
+
if (isSelected(segment)) return;
|
82
|
+
var segments = document.querySelectorAll('#segment-bar > a');
|
83
|
+
for (var i = segments.length - 1; i >= 0; i--) { deselect(segments[i]);};
|
84
|
+
select(segment);
|
85
|
+
if (segment.id == "all-segment") {
|
86
|
+
showAll(document.querySelectorAll('.test-suite'));
|
87
|
+
showAll(document.querySelectorAll('.test'));
|
88
|
+
} else if (segment.id == "failing-segment") {
|
89
|
+
hideAll(document.querySelectorAll('.test.passing'));
|
90
|
+
showAll(document.querySelectorAll('.test.failing'));
|
91
|
+
hideAll(document.querySelectorAll('.test-suite.passing'));
|
92
|
+
showAll(document.querySelectorAll('.test-suite.failing'));
|
93
|
+
} else if (segment.id == "passing-segment") {
|
94
|
+
hideAll(document.querySelectorAll('.test.failing'));
|
95
|
+
showAll(document.querySelectorAll('.test.passing'));
|
96
|
+
hideAll(document.querySelectorAll('.test-suite.failing'));
|
97
|
+
showAll(document.querySelectorAll('.test-suite.passing'));
|
98
|
+
}
|
99
|
+
}
|
100
|
+
var toggleScreenshot = function(suiteName, index) {
|
101
|
+
var screenshot = document.getElementById("screenshot-" + suiteName + "-" + index);
|
102
|
+
isSelected(screenshot) ? deselect(screenshot) : select(screenshot);
|
103
|
+
}
|
104
|
+
</script>
|
105
|
+
</head>
|
106
|
+
<body>
|
107
|
+
<header>
|
108
|
+
<section class="left">
|
109
|
+
<h1>Test Results</h1>
|
110
|
+
</section>
|
111
|
+
<section class="right">
|
112
|
+
<section id="counters">
|
113
|
+
<h2 id="test-count"><span class="number"><%= test_count %></span> tests</h2>
|
114
|
+
<% if fail_count > 0 %>
|
115
|
+
<h2 id="fail-count"><span class="number"><%= fail_count %></span> failures</h2>
|
116
|
+
<% end %>
|
117
|
+
</section>
|
118
|
+
<section id="segment-bar">
|
119
|
+
<a id="all-segment" onclick="selectSegment(this);" class="selected">All</a><a id="failing-segment" onclick="selectSegment(this);">Failing</a><a id="passing-segment" onclick="selectSegment(this);">Passing</a>
|
120
|
+
</section>
|
121
|
+
</section>
|
122
|
+
</header>
|
123
|
+
<section id="test-suites">
|
124
|
+
<% test_suites.each do |name, info| %>
|
125
|
+
<% next unless info[:tests].size > 0 %>
|
126
|
+
<section class="test-suite <%= info[:failing] ? 'failing' : 'passing'%>" id="<%= name %>">
|
127
|
+
<section class="heading" onclick="toggleTests(this);">
|
128
|
+
<h3 class="title"><%= name %></h3>
|
129
|
+
</section>
|
130
|
+
<section class="tests">
|
131
|
+
<table>
|
132
|
+
<% info[:tests].each_with_index do |test, index| %>
|
133
|
+
<% detail_class = test[:name].gsub(/\s/,'') %>
|
134
|
+
<tr class="test <%= test[:failing] ? 'failing' : 'passing'%> <%= index % 2 != 0 ? 'odd' :''%>" onclick="toggleDetails('<%= detail_class %>');">
|
135
|
+
<td>
|
136
|
+
<% if test[:time] %>
|
137
|
+
<h3 class="time"><%= test[:time] %>s</h3>
|
138
|
+
<% end %>
|
139
|
+
</td>
|
140
|
+
<td><h3 class="title"><%= test[:name] %></h3></td>
|
141
|
+
</tr>
|
142
|
+
<% if test[:reason] || test[:snippet] || !test[:screenshots].empty? %>
|
143
|
+
<tr class="details <%= test[:failing] ? 'failing' : 'passing'%> <%= detail_class %>">
|
144
|
+
<td></td>
|
145
|
+
<td>
|
146
|
+
<% if test[:reason] %>
|
147
|
+
<section class="test-detail reason"><%= test[:reason] %></section>
|
148
|
+
<% end %>
|
149
|
+
<% if test[:snippet] %>
|
150
|
+
<section class="test-detail snippet"><%= test[:snippet] %></section>
|
151
|
+
<section class="test-detail"><%= test[:file] %></section>
|
152
|
+
<% end %>
|
153
|
+
<% if !test[:screenshots].empty? %>
|
154
|
+
<section class="test-detail">
|
155
|
+
<% test[:screenshots].each_with_index do |screenshot, idx| %>
|
156
|
+
<a href="javascript:toggleScreenshot('<%=test[:name] %>', <%=index %>)">
|
157
|
+
<img class="screenshot" id="screenshot-<%=test[:name] %>-<%=index %>" src="<%=screenshot %>" />
|
158
|
+
</a>
|
159
|
+
<% end %>
|
160
|
+
</section>
|
161
|
+
<% end %>
|
162
|
+
</td>
|
163
|
+
</tr>
|
164
|
+
<% end %>
|
165
|
+
<% end %>
|
166
|
+
</table>
|
167
|
+
</section>
|
168
|
+
</section>
|
169
|
+
<% end %>
|
170
|
+
</section>
|
171
|
+
<footer>Report generated with <a href="https://github.com/supermarin/xcpretty">xcpretty</a></footer>
|
172
|
+
</body>
|
173
|
+
</html>
|
data/bin/xcpretty
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
if RUBY_VERSION < '2.0.0'
|
4
|
+
abort "error: XCPretty requires Ruby 2.0.0 or higher."
|
5
|
+
end
|
6
|
+
|
7
|
+
if $PROGRAM_NAME == __FILE__
|
8
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
9
|
+
end
|
10
|
+
require 'xcpretty'
|
11
|
+
require 'optparse'
|
12
|
+
|
13
|
+
report_options = []
|
14
|
+
report_classes = []
|
15
|
+
report_formats = {
|
16
|
+
"junit" => XCPretty::JUnit,
|
17
|
+
"html" => XCPretty::HTML,
|
18
|
+
"json-compilation-database" => XCPretty::JSONCompilationDatabase
|
19
|
+
}
|
20
|
+
|
21
|
+
printer_opts = {
|
22
|
+
unicode: XCPretty::Term.unicode?,
|
23
|
+
colorize: XCPretty::Term.color?,
|
24
|
+
formatter: XCPretty::Simple
|
25
|
+
}
|
26
|
+
|
27
|
+
OptionParser.new do |opts|
|
28
|
+
opts.banner = "Usage: xcodebuild [options] | xcpretty"
|
29
|
+
opts.on('-t', '--test', 'Use RSpec style output') do
|
30
|
+
printer_opts[:formatter] = XCPretty::RSpec
|
31
|
+
end
|
32
|
+
opts.on('-s', '--simple', 'Use simple output (default)') do
|
33
|
+
printer_opts[:formatter] = XCPretty::Simple
|
34
|
+
end
|
35
|
+
opts.on('-k', '--knock', 'Use knock output') do
|
36
|
+
printer_opts[:formatter] = XCPretty::Knock
|
37
|
+
end
|
38
|
+
opts.on('--tap', 'Use TAP output') do
|
39
|
+
printer_opts[:formatter] = XCPretty::TestAnything
|
40
|
+
end
|
41
|
+
opts.on('-f', '--formatter PATH', 'Use formatter returned from evaluating the specified Ruby file') do |path|
|
42
|
+
printer_opts[:formatter] = XCPretty.load_custom_class(path)
|
43
|
+
end
|
44
|
+
opts.on('-c', '--[no-]color', 'Use colorized output. Default is auto') do |value|
|
45
|
+
printer_opts[:colorize] = value
|
46
|
+
end
|
47
|
+
opts.on('--[no-]utf', 'Use unicode characters in output. Default is auto.') do |value|
|
48
|
+
printer_opts[:unicode] = value
|
49
|
+
end
|
50
|
+
opts.on("-r", "--report FORMAT or PATH", "Run FORMAT or PATH reporter",
|
51
|
+
" Choices: #{report_formats.keys.join(', ')}") do |format|
|
52
|
+
if report_formats.key?(format)
|
53
|
+
report_classes << report_formats[format]
|
54
|
+
else
|
55
|
+
report_classes << XCPretty.load_custom_class(format)
|
56
|
+
end
|
57
|
+
report_options << {}
|
58
|
+
end
|
59
|
+
opts.on('-o', '--output PATH', 'Write report output to PATH') do |path|
|
60
|
+
unless opts = report_options.last
|
61
|
+
XCPretty.exit_with_error('Expected report format to be specified before output path')
|
62
|
+
end
|
63
|
+
opts[:path] = path
|
64
|
+
end
|
65
|
+
opts.on('--screenshots', 'Collect screenshots in the HTML report') do
|
66
|
+
unless opts = report_options.last
|
67
|
+
XCPretty.exit_with_error('Expected screenshot argument to be specified after report format')
|
68
|
+
end
|
69
|
+
opts[:screenshots] = true
|
70
|
+
end
|
71
|
+
opts.on_tail('-h', '--help', 'Show this message') { puts opts; exit }
|
72
|
+
opts.on_tail("-v", "--version", "Show version") { puts XCPretty::VERSION; exit }
|
73
|
+
opts.parse!
|
74
|
+
|
75
|
+
if STDIN.tty?
|
76
|
+
XCPretty.exit_with_error(opts.help)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
printer = XCPretty::Printer.new(printer_opts)
|
81
|
+
reporters = report_classes.compact.each_with_index.map { |k, i| k.new(report_options[i]) }
|
82
|
+
|
83
|
+
STDIN.each_line do |line|
|
84
|
+
printer.pretty_print(line)
|
85
|
+
reporters.each { |r| r.handle(line) }
|
86
|
+
end
|
87
|
+
|
88
|
+
printer.finish
|
89
|
+
reporters.each(&:finish)
|
90
|
+
|
Binary file
|
Binary file
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Feature: Loading an arbitrary Ruby file as a formatter
|
2
|
+
|
3
|
+
Scenario: The file loaded does not contain a Ruby class
|
4
|
+
When I pipe to xcpretty with "--formatter /bin/bash"
|
5
|
+
Then the exit status code should be 1
|
6
|
+
|
7
|
+
Scenario: The file loaded contains a Ruby class
|
8
|
+
Given I have a file to compile
|
9
|
+
When I pipe to xcpretty with a custom formatter
|
10
|
+
Then the exit status code should be 0
|
11
|
+
|
12
|
+
Scenario: Showing output using a custom formatter
|
13
|
+
Given I have a file to compile
|
14
|
+
When I pipe to xcpretty with a custom formatter
|
15
|
+
Then I should see a custom compilation message
|
@@ -0,0 +1,29 @@
|
|
1
|
+
Feature: Loading an arbitrary Ruby file as a reporter
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given the tests have started running
|
5
|
+
|
6
|
+
Scenario: The file loaded does not contain a Ruby class
|
7
|
+
When I pipe to xcpretty with "-r /bin/bash"
|
8
|
+
Then the exit status code should be 1
|
9
|
+
|
10
|
+
Scenario: The file loaded contains a Ruby class
|
11
|
+
Given I have a file to compile
|
12
|
+
When I pipe to xcpretty with a custom reporter
|
13
|
+
Then the exit status code should be 0
|
14
|
+
|
15
|
+
Scenario: Showing failed tests
|
16
|
+
Given I have a failing test in my suite
|
17
|
+
When I pipe to xcpretty with a custom reporter
|
18
|
+
Then I should see a failed test in my custom report
|
19
|
+
And the custom failure counter should show 1 test
|
20
|
+
|
21
|
+
Scenario: Showing passing tests
|
22
|
+
Given I have a passing test in my suite
|
23
|
+
When I pipe to xcpretty with a custom reporter
|
24
|
+
Then I should see a passing test in my custom report
|
25
|
+
|
26
|
+
Scenario: Showing pending tests
|
27
|
+
Given I have a pending test in my suite
|
28
|
+
When I pipe to xcpretty with a custom reporter
|
29
|
+
Then I should see a pending test in my custom report
|