guard-phpunit 0.1.3 → 0.1.4
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.
- data/CHANGELOG.md +37 -0
- data/LICENSE +19 -19
- data/README.md +106 -106
- data/lib/guard/phpunit.rb +112 -112
- data/lib/guard/phpunit/formatter.rb +64 -64
- data/lib/guard/phpunit/formatters/PHPUnit-Progress/PHPUnit/Extensions/Progress/ResultPrinter.php +498 -498
- data/lib/guard/phpunit/formatters/PHPUnit-Progress/README.markdown +44 -0
- data/lib/guard/phpunit/formatters/PHPUnit-Progress/Tests/_files/Number.php +78 -0
- data/lib/guard/phpunit/formatters/PHPUnit-Progress/Tests/_files/NumberTest.php +99 -0
- data/lib/guard/phpunit/formatters/PHPUnit-Progress/Tests/_files/emptyTest.php +6 -0
- data/lib/guard/phpunit/formatters/PHPUnit-Progress/Tests/printer_basic.phpt +22 -0
- data/lib/guard/phpunit/formatters/PHPUnit-Progress/Tests/printer_errors.phpt +27 -0
- data/lib/guard/phpunit/formatters/PHPUnit-Progress/Tests/printer_errors_variation.phpt +28 -0
- data/lib/guard/phpunit/formatters/PHPUnit-Progress/Tests/printer_failing.phpt +31 -0
- data/lib/guard/phpunit/formatters/PHPUnit-Progress/Tests/printer_failing_variation.phpt +32 -0
- data/lib/guard/phpunit/formatters/PHPUnit-Progress/Tests/printer_incomplete.phpt +19 -0
- data/lib/guard/phpunit/formatters/PHPUnit-Progress/Tests/printer_incomplete_variation.phpt +20 -0
- data/lib/guard/phpunit/formatters/PHPUnit-Progress/Tests/printer_passing.phpt +19 -0
- data/lib/guard/phpunit/formatters/PHPUnit-Progress/Tests/printer_passing_variation.phpt +20 -0
- data/lib/guard/phpunit/formatters/PHPUnit-Progress/Tests/printer_skipped.phpt +19 -0
- data/lib/guard/phpunit/formatters/PHPUnit-Progress/Tests/printer_skipped_variation.phpt +20 -0
- data/lib/guard/phpunit/formatters/PHPUnit-Progress/phpunit.xml +4 -0
- data/lib/guard/phpunit/formatters/PHPUnit-Progress/screenshot.png +0 -0
- data/lib/guard/phpunit/inspector.rb +54 -54
- data/lib/guard/phpunit/notifier.rb +68 -68
- data/lib/guard/phpunit/runner.rb +197 -194
- data/lib/guard/phpunit/templates/Guardfile +3 -3
- data/lib/guard/phpunit/version.rb +6 -6
- metadata +37 -3
@@ -1,64 +1,64 @@
|
|
1
|
-
module Guard
|
2
|
-
class PHPUnit
|
3
|
-
|
4
|
-
# The Guard::PHPUnit formatter parses the output
|
5
|
-
# of phpunit which gets printed by the progress
|
6
|
-
# printer.
|
7
|
-
#
|
8
|
-
module Formatter
|
9
|
-
class << self
|
10
|
-
|
11
|
-
# Parses the tests output.
|
12
|
-
#
|
13
|
-
# @param [String] text the output of phpunit.
|
14
|
-
# @return [Hash] the parsed results
|
15
|
-
#
|
16
|
-
def parse_output(text)
|
17
|
-
results = {
|
18
|
-
:tests => look_for_words_in('test', text),
|
19
|
-
:failures => look_for_words_in('failure', text),
|
20
|
-
:errors => look_for_words_in('error', text),
|
21
|
-
:pending => look_for_words_in(['skipped', 'incomplete'], text),
|
22
|
-
:duration => look_for_duration_in(text)
|
23
|
-
}
|
24
|
-
results.freeze
|
25
|
-
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
# Searches for a list of strings in the tests output
|
30
|
-
# and returns the total number assigned to these strings.
|
31
|
-
#
|
32
|
-
# @param [String, Array<String>] string_list the words
|
33
|
-
# @param [String] text the tests output
|
34
|
-
# @return [Integer] the total number assigned to the words
|
35
|
-
#
|
36
|
-
def look_for_words_in(strings_list, text)
|
37
|
-
count = 0
|
38
|
-
strings_list = Array(strings_list)
|
39
|
-
strings_list.each do |s|
|
40
|
-
text =~ %r{
|
41
|
-
(\d+) # count of what we are looking for
|
42
|
-
[ ] # then a space
|
43
|
-
#{s}s? # then the string
|
44
|
-
.* # then whatever
|
45
|
-
\Z # start looking at the end of the text
|
46
|
-
}x
|
47
|
-
count += $1.to_i unless $1.nil?
|
48
|
-
end
|
49
|
-
count
|
50
|
-
end
|
51
|
-
|
52
|
-
# Searches for the duration in the tests output
|
53
|
-
#
|
54
|
-
# @param [String] text the tests output
|
55
|
-
# @return [Integer] the duration
|
56
|
-
#
|
57
|
-
def look_for_duration_in(text)
|
58
|
-
text =~ %r{Finished in (\d)+ seconds?.*\Z}m
|
59
|
-
$1.nil? ? 0 : $1.to_i
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
1
|
+
module Guard
|
2
|
+
class PHPUnit
|
3
|
+
|
4
|
+
# The Guard::PHPUnit formatter parses the output
|
5
|
+
# of phpunit which gets printed by the progress
|
6
|
+
# printer.
|
7
|
+
#
|
8
|
+
module Formatter
|
9
|
+
class << self
|
10
|
+
|
11
|
+
# Parses the tests output.
|
12
|
+
#
|
13
|
+
# @param [String] text the output of phpunit.
|
14
|
+
# @return [Hash] the parsed results
|
15
|
+
#
|
16
|
+
def parse_output(text)
|
17
|
+
results = {
|
18
|
+
:tests => look_for_words_in('test', text),
|
19
|
+
:failures => look_for_words_in('failure', text),
|
20
|
+
:errors => look_for_words_in('error', text),
|
21
|
+
:pending => look_for_words_in(['skipped', 'incomplete'], text),
|
22
|
+
:duration => look_for_duration_in(text)
|
23
|
+
}
|
24
|
+
results.freeze
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
# Searches for a list of strings in the tests output
|
30
|
+
# and returns the total number assigned to these strings.
|
31
|
+
#
|
32
|
+
# @param [String, Array<String>] string_list the words
|
33
|
+
# @param [String] text the tests output
|
34
|
+
# @return [Integer] the total number assigned to the words
|
35
|
+
#
|
36
|
+
def look_for_words_in(strings_list, text)
|
37
|
+
count = 0
|
38
|
+
strings_list = Array(strings_list)
|
39
|
+
strings_list.each do |s|
|
40
|
+
text =~ %r{
|
41
|
+
(\d+) # count of what we are looking for
|
42
|
+
[ ] # then a space
|
43
|
+
#{s}s? # then the string
|
44
|
+
.* # then whatever
|
45
|
+
\Z # start looking at the end of the text
|
46
|
+
}x
|
47
|
+
count += $1.to_i unless $1.nil?
|
48
|
+
end
|
49
|
+
count
|
50
|
+
end
|
51
|
+
|
52
|
+
# Searches for the duration in the tests output
|
53
|
+
#
|
54
|
+
# @param [String] text the tests output
|
55
|
+
# @return [Integer] the duration
|
56
|
+
#
|
57
|
+
def look_for_duration_in(text)
|
58
|
+
text =~ %r{Finished in (\d)+ seconds?.*\Z}m
|
59
|
+
$1.nil? ? 0 : $1.to_i
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/guard/phpunit/formatters/PHPUnit-Progress/PHPUnit/Extensions/Progress/ResultPrinter.php
CHANGED
@@ -1,498 +1,498 @@
|
|
1
|
-
<?php
|
2
|
-
|
3
|
-
/**
|
4
|
-
* Prints tests' results in a similar way
|
5
|
-
* to rspec's progress formatter.
|
6
|
-
*
|
7
|
-
* @package PHPUnit
|
8
|
-
* @subpackage Progress
|
9
|
-
* @author Maher Sallam <maher@sallam.me>
|
10
|
-
* @copyright 2011 Maher Sallam <maher@sallam.me>
|
11
|
-
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
12
|
-
* @version 0.1
|
13
|
-
*/
|
14
|
-
class PHPUnit_Extensions_Progress_ResultPrinter extends PHPUnit_TextUI_ResultPrinter {
|
15
|
-
|
16
|
-
/**
|
17
|
-
* Constructor.
|
18
|
-
*
|
19
|
-
* @param mixed $out
|
20
|
-
* @param boolean $verbose
|
21
|
-
* @param boolean $colors
|
22
|
-
* @param boolean $debug
|
23
|
-
*/
|
24
|
-
public function __construct($out = NULL, $verbose = FALSE, $colors = FALSE, $debug = FALSE) {
|
25
|
-
|
26
|
-
// Start capturing output
|
27
|
-
ob_start();
|
28
|
-
|
29
|
-
$argv = $_SERVER['argv'];
|
30
|
-
$colors = in_array('--colors', $argv) || $colors;
|
31
|
-
$verbose = in_array('--verbose', $argv) || in_array('-v', $argv) || $verbose;
|
32
|
-
$debug = in_array('--debug', $argv) || $debug;
|
33
|
-
|
34
|
-
parent::__construct($out, $verbose, $colors, $debug);
|
35
|
-
}
|
36
|
-
|
37
|
-
/**
|
38
|
-
* @param PHPUnit_Framework_TestResult $result
|
39
|
-
*/
|
40
|
-
public function printResult(PHPUnit_Framework_TestResult $result)
|
41
|
-
{
|
42
|
-
print "\n";
|
43
|
-
|
44
|
-
if ($result->errorCount() > 0) {
|
45
|
-
$this->printErrors($result);
|
46
|
-
}
|
47
|
-
|
48
|
-
if ($result->failureCount() > 0) {
|
49
|
-
$this->printFailures($result);
|
50
|
-
}
|
51
|
-
|
52
|
-
if ($this->verbose) {
|
53
|
-
if ($result->deprecatedFeaturesCount() > 0) {
|
54
|
-
if ($result->failureCount() > 0) {
|
55
|
-
print "\n--\n\nDeprecated PHPUnit features are being used";
|
56
|
-
}
|
57
|
-
|
58
|
-
foreach ($result->deprecatedFeatures() as $deprecatedFeature) {
|
59
|
-
$this->write($deprecatedFeature . "\n\n");
|
60
|
-
}
|
61
|
-
}
|
62
|
-
|
63
|
-
if ($result->notImplementedCount() > 0) {
|
64
|
-
$this->printIncompletes($result);
|
65
|
-
}
|
66
|
-
|
67
|
-
if ($result->skippedCount() > 0) {
|
68
|
-
$this->printSkipped($result);
|
69
|
-
}
|
70
|
-
}
|
71
|
-
|
72
|
-
$this->printFooter($result);
|
73
|
-
}
|
74
|
-
|
75
|
-
/**
|
76
|
-
* @param array $defects
|
77
|
-
* @param integer $count
|
78
|
-
* @param string $type
|
79
|
-
*/
|
80
|
-
protected function printDefects(array $defects, $count, $type)
|
81
|
-
{
|
82
|
-
if ($count == 0) {
|
83
|
-
return;
|
84
|
-
}
|
85
|
-
|
86
|
-
$this->write("\n" . $type . ":\n");
|
87
|
-
|
88
|
-
$i = 1;
|
89
|
-
$failOrError = $type == 'Failures' || $type == 'Errors';
|
90
|
-
|
91
|
-
foreach ($defects as $defect) {
|
92
|
-
$this->printDefect($defect, $i++, $failOrError);
|
93
|
-
$this->write("\n");
|
94
|
-
}
|
95
|
-
}
|
96
|
-
|
97
|
-
/**
|
98
|
-
* @param PHPUnit_Framework_TestFailure $defect
|
99
|
-
* @param integer $count
|
100
|
-
* @param boolean $failOrError
|
101
|
-
*/
|
102
|
-
protected function printDefect(PHPUnit_Framework_TestFailure $defect, $count, $failOrError = true)
|
103
|
-
{
|
104
|
-
$this->printDefectHeader($defect, $count, $failOrError);
|
105
|
-
|
106
|
-
$padding = str_repeat(' ',
|
107
|
-
4 + ( $failOrError ? strlen((string)$count) : 0 )
|
108
|
-
);
|
109
|
-
|
110
|
-
$this->printDefectBody($defect, $count, $failOrError, $padding);
|
111
|
-
$this->printDefectTrace($defect, $padding);
|
112
|
-
}
|
113
|
-
|
114
|
-
/**
|
115
|
-
* @param PHPUnit_Framework_TestFailure $defect
|
116
|
-
* @param integer $count
|
117
|
-
* @param boolean $failOrError
|
118
|
-
*/
|
119
|
-
protected function printDefectHeader(PHPUnit_Framework_TestFailure $defect, $count, $failOrError = true)
|
120
|
-
{
|
121
|
-
$failedTest = $defect->failedTest();
|
122
|
-
|
123
|
-
if ($failedTest instanceof PHPUnit_Framework_SelfDescribing) {
|
124
|
-
$testName = $failedTest->toString();
|
125
|
-
} else {
|
126
|
-
$testName = get_class($failedTest);
|
127
|
-
}
|
128
|
-
|
129
|
-
if ( $failOrError ) {
|
130
|
-
$this->write(
|
131
|
-
sprintf(
|
132
|
-
"\n %d) %s",
|
133
|
-
|
134
|
-
$count,
|
135
|
-
$testName
|
136
|
-
)
|
137
|
-
);
|
138
|
-
} else {
|
139
|
-
$this->write(
|
140
|
-
sprintf( " %s", $this->yellow($testName) )
|
141
|
-
);
|
142
|
-
}
|
143
|
-
}
|
144
|
-
|
145
|
-
/**
|
146
|
-
* @param PHPUnit_Framework_TestFailure $defect
|
147
|
-
* @param integer $count
|
148
|
-
* @param boolean $failOrError
|
149
|
-
* @param string $padding
|
150
|
-
*/
|
151
|
-
protected function printDefectBody(PHPUnit_Framework_TestFailure $defect, $count, $failOrError, $padding)
|
152
|
-
{
|
153
|
-
$error = trim($defect->getExceptionAsString());
|
154
|
-
|
155
|
-
if ( !empty($error) ) {
|
156
|
-
$error = explode("\n", $error);
|
157
|
-
$error = "\n" . $padding . implode("\n " . $padding , $error);
|
158
|
-
|
159
|
-
$this->write( $failOrError ? $this->red($error) : $this->cyan($error) );
|
160
|
-
}
|
161
|
-
}
|
162
|
-
|
163
|
-
/**
|
164
|
-
* @param PHPUnit_Framework_TestFailure $defect
|
165
|
-
* @param string $padding
|
166
|
-
*/
|
167
|
-
protected function printDefectTrace(PHPUnit_Framework_TestFailure $defect, $padding = 0)
|
168
|
-
{
|
169
|
-
$trace = trim(
|
170
|
-
PHPUnit_Util_Filter::getFilteredStacktrace(
|
171
|
-
$defect->thrownException()
|
172
|
-
)
|
173
|
-
);
|
174
|
-
|
175
|
-
if ( ! empty($trace) ) {
|
176
|
-
$trace = explode("\n", $trace);
|
177
|
-
$trace = "\n" . $padding . '# ' . implode("\n${padding}# ", $trace);
|
178
|
-
|
179
|
-
$this->write($this->cyan($trace));
|
180
|
-
}
|
181
|
-
}
|
182
|
-
|
183
|
-
/**
|
184
|
-
* @param PHPUnit_Framework_TestResult $result
|
185
|
-
*/
|
186
|
-
protected function printErrors(PHPUnit_Framework_TestResult $result)
|
187
|
-
{
|
188
|
-
$this->printDefects(
|
189
|
-
$result->errors(),
|
190
|
-
$result->errorCount(),
|
191
|
-
'Errors'
|
192
|
-
);
|
193
|
-
}
|
194
|
-
|
195
|
-
/**
|
196
|
-
* @param PHPUnit_Framework_TestResult $result
|
197
|
-
*/
|
198
|
-
protected function printFailures(PHPUnit_Framework_TestResult $result)
|
199
|
-
{
|
200
|
-
$this->printDefects(
|
201
|
-
$result->failures(),
|
202
|
-
$result->failureCount(),
|
203
|
-
'Failures'
|
204
|
-
);
|
205
|
-
}
|
206
|
-
|
207
|
-
/**
|
208
|
-
* @param PHPUnit_Framework_TestResult $result
|
209
|
-
*/
|
210
|
-
protected function printIncompletes(PHPUnit_Framework_TestResult $result)
|
211
|
-
{
|
212
|
-
$this->printDefects(
|
213
|
-
$result->notImplemented(),
|
214
|
-
$result->notImplementedCount(),
|
215
|
-
'Incomplete tests'
|
216
|
-
);
|
217
|
-
}
|
218
|
-
|
219
|
-
/**
|
220
|
-
* @param PHPUnit_Framework_TestResult $result
|
221
|
-
* @since Method available since Release 3.0.0
|
222
|
-
*/
|
223
|
-
protected function printSkipped(PHPUnit_Framework_TestResult $result)
|
224
|
-
{
|
225
|
-
$this->printDefects(
|
226
|
-
$result->skipped(),
|
227
|
-
$result->skippedCount(),
|
228
|
-
'Skipped tests'
|
229
|
-
);
|
230
|
-
}
|
231
|
-
|
232
|
-
/**
|
233
|
-
* @param PHPUnit_Framework_TestResult $result
|
234
|
-
*/
|
235
|
-
protected function printFooter(PHPUnit_Framework_TestResult $result)
|
236
|
-
{
|
237
|
-
|
238
|
-
$this->write( sprintf("\nFinished in %s\n", PHP_Timer::timeSinceStartOfRequest()) );
|
239
|
-
|
240
|
-
$resultsCount = count($result);
|
241
|
-
|
242
|
-
$footer = sprintf("%d test%s, %d assertion%s",
|
243
|
-
$resultsCount,
|
244
|
-
$resultsCount == 1 ? '' : 's',
|
245
|
-
$this->numAssertions,
|
246
|
-
$this->numAssertions == 1 ? '' : 's'
|
247
|
-
);
|
248
|
-
|
249
|
-
if ( $result->wasSuccessful() &&
|
250
|
-
$result->allCompletlyImplemented() &&
|
251
|
-
$result->noneSkipped() )
|
252
|
-
{
|
253
|
-
$this->write($this->green($footer));
|
254
|
-
}
|
255
|
-
|
256
|
-
else if ( ( !$result->allCompletlyImplemented() || !$result->noneSkipped() )
|
257
|
-
&&
|
258
|
-
$result->wasSuccessful() )
|
259
|
-
{
|
260
|
-
|
261
|
-
$footer .= sprintf(
|
262
|
-
"%s%s",
|
263
|
-
|
264
|
-
$this->getCountString(
|
265
|
-
$result->notImplementedCount(), 'incomplete'
|
266
|
-
),
|
267
|
-
$this->getCountString(
|
268
|
-
$result->skippedCount(), 'skipped'
|
269
|
-
)
|
270
|
-
);
|
271
|
-
|
272
|
-
$this->write($this->yellow($footer));
|
273
|
-
|
274
|
-
}
|
275
|
-
|
276
|
-
else {
|
277
|
-
|
278
|
-
$footer .= sprintf(
|
279
|
-
"%s%s%s%s",
|
280
|
-
|
281
|
-
$this->getCountString($result->failureCount(), 'failures'),
|
282
|
-
$this->getCountString($result->errorCount(), 'errors'),
|
283
|
-
$this->getCountString(
|
284
|
-
$result->notImplementedCount(), 'incomplete'
|
285
|
-
),
|
286
|
-
$this->getCountString($result->skippedCount(), 'skipped')
|
287
|
-
);
|
288
|
-
|
289
|
-
$footer = preg_replace('/,$/', '', $footer);
|
290
|
-
|
291
|
-
$this->write($this->red($footer));
|
292
|
-
}
|
293
|
-
|
294
|
-
if ( ! $this->verbose &&
|
295
|
-
$result->deprecatedFeaturesCount() > 0 )
|
296
|
-
{
|
297
|
-
$message = sprintf(
|
298
|
-
"Warning: Deprecated PHPUnit features are being used %s times!\n".
|
299
|
-
"Use --verbose for more information.\n",
|
300
|
-
$result->deprecatedFeaturesCount()
|
301
|
-
);
|
302
|
-
|
303
|
-
if ($this->colors) {
|
304
|
-
$message = "\x1b[37;41m\x1b[2K" . $message .
|
305
|
-
"\x1b[0m";
|
306
|
-
}
|
307
|
-
|
308
|
-
$this->write("\n" . $message);
|
309
|
-
}
|
310
|
-
|
311
|
-
$this->writeNewLine();
|
312
|
-
}
|
313
|
-
|
314
|
-
/**
|
315
|
-
* @param integer $count
|
316
|
-
* @param string $name
|
317
|
-
* @return string
|
318
|
-
* @since Method available since Release 3.0.0
|
319
|
-
*/
|
320
|
-
protected function getCountString($count, $name)
|
321
|
-
{
|
322
|
-
$string = '';
|
323
|
-
|
324
|
-
if ($count > 0) {
|
325
|
-
$string = sprintf(
|
326
|
-
', %d %s',
|
327
|
-
|
328
|
-
$count,
|
329
|
-
$name
|
330
|
-
);
|
331
|
-
}
|
332
|
-
|
333
|
-
return $string;
|
334
|
-
}
|
335
|
-
|
336
|
-
/**
|
337
|
-
* An error occurred.
|
338
|
-
*
|
339
|
-
* @param PHPUnit_Framework_Test $test
|
340
|
-
* @param Exception $e
|
341
|
-
* @param float $time
|
342
|
-
*/
|
343
|
-
public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
|
344
|
-
{
|
345
|
-
$this->writeProgress($this->red('E'));
|
346
|
-
$this->lastTestFailed = TRUE;
|
347
|
-
}
|
348
|
-
|
349
|
-
/**
|
350
|
-
* A failure occurred.
|
351
|
-
*
|
352
|
-
* @param PHPUnit_Framework_Test $test
|
353
|
-
* @param PHPUnit_Framework_AssertionFailedError $e
|
354
|
-
* @param float $time
|
355
|
-
*/
|
356
|
-
public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
|
357
|
-
{
|
358
|
-
$this->writeProgress($this->red('F'));
|
359
|
-
$this->lastTestFailed = TRUE;
|
360
|
-
}
|
361
|
-
|
362
|
-
/**
|
363
|
-
* Incomplete test.
|
364
|
-
*
|
365
|
-
* @param PHPUnit_Framework_Test $test
|
366
|
-
* @param Exception $e
|
367
|
-
* @param float $time
|
368
|
-
*/
|
369
|
-
public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
|
370
|
-
{
|
371
|
-
$this->writeProgress($this->yellow('I'));
|
372
|
-
$this->lastTestFailed = TRUE;
|
373
|
-
}
|
374
|
-
|
375
|
-
/**
|
376
|
-
* Skipped test.
|
377
|
-
*
|
378
|
-
* @param PHPUnit_Framework_Test $test
|
379
|
-
* @param Exception $e
|
380
|
-
* @param float $time
|
381
|
-
* @since Method available since Release 3.0.0
|
382
|
-
*/
|
383
|
-
public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
|
384
|
-
{
|
385
|
-
$this->writeProgress($this->yellow('S'));
|
386
|
-
$this->lastTestFailed = TRUE;
|
387
|
-
}
|
388
|
-
|
389
|
-
/**
|
390
|
-
* A test ended.
|
391
|
-
*
|
392
|
-
* @param PHPUnit_Framework_Test $test
|
393
|
-
* @param float $time
|
394
|
-
*/
|
395
|
-
public function endTest(PHPUnit_Framework_Test $test, $time)
|
396
|
-
{
|
397
|
-
if (!$this->lastTestFailed) {
|
398
|
-
$this->writeProgress($this->green('.'));
|
399
|
-
}
|
400
|
-
|
401
|
-
if ($test instanceof PHPUnit_Framework_TestCase) {
|
402
|
-
$this->numAssertions += $test->getNumAssertions();
|
403
|
-
}
|
404
|
-
|
405
|
-
else if ($test instanceof PHPUnit_Extensions_PhptTestCase) {
|
406
|
-
$this->numAssertions++;
|
407
|
-
}
|
408
|
-
|
409
|
-
$this->lastTestFailed = FALSE;
|
410
|
-
|
411
|
-
if ($this->verbose && $test instanceof PHPUnit_Framework_TestCase) {
|
412
|
-
$this->write($test->getActualOutput());
|
413
|
-
}
|
414
|
-
|
415
|
-
}
|
416
|
-
|
417
|
-
/**
|
418
|
-
* @param string $progress
|
419
|
-
*/
|
420
|
-
protected function writeProgress($progress)
|
421
|
-
{
|
422
|
-
static $deletedHeader = false;
|
423
|
-
|
424
|
-
if ( ! $deletedHeader ) {
|
425
|
-
ob_clean();
|
426
|
-
$deletedHeader = true;
|
427
|
-
}
|
428
|
-
|
429
|
-
parent::writeProgress($progress);
|
430
|
-
}
|
431
|
-
|
432
|
-
/**
|
433
|
-
* Returns a colored string which can be used
|
434
|
-
* in the terminal.
|
435
|
-
*
|
436
|
-
* @param string $text
|
437
|
-
* @param integer $color_code
|
438
|
-
*/
|
439
|
-
protected function color($text, $color_code) {
|
440
|
-
return $this->colors ? "\033[${color_code}m" . $text . "\033[0m" : $text;
|
441
|
-
}
|
442
|
-
|
443
|
-
/**
|
444
|
-
* @param string $text
|
445
|
-
*/
|
446
|
-
protected function bold($text) {
|
447
|
-
return $this->color($text, "1");
|
448
|
-
}
|
449
|
-
|
450
|
-
/**
|
451
|
-
* @param string $text
|
452
|
-
*/
|
453
|
-
protected function red($text) {
|
454
|
-
return $this->color($text, "31");
|
455
|
-
}
|
456
|
-
|
457
|
-
/**
|
458
|
-
* @param string $text
|
459
|
-
*/
|
460
|
-
protected function green($text) {
|
461
|
-
return $this->color($text, "32");
|
462
|
-
}
|
463
|
-
|
464
|
-
/**
|
465
|
-
* @param string $text
|
466
|
-
*/
|
467
|
-
protected function yellow($text) {
|
468
|
-
return $this->color($text, "33");
|
469
|
-
}
|
470
|
-
|
471
|
-
/**
|
472
|
-
* @param string $text
|
473
|
-
*/
|
474
|
-
protected function blue($text) {
|
475
|
-
return $this->color($text, "34");
|
476
|
-
}
|
477
|
-
|
478
|
-
/**
|
479
|
-
* @param string $text
|
480
|
-
*/
|
481
|
-
protected function magenta($text) {
|
482
|
-
return $this->color($text, "35");
|
483
|
-
}
|
484
|
-
|
485
|
-
/**
|
486
|
-
* @param string $text
|
487
|
-
*/
|
488
|
-
protected function cyan($text) {
|
489
|
-
return $this->color($text, "36");
|
490
|
-
}
|
491
|
-
|
492
|
-
/**
|
493
|
-
* @param string $text
|
494
|
-
*/
|
495
|
-
protected function white($text) {
|
496
|
-
return $this->color($text, "37");
|
497
|
-
}
|
498
|
-
}
|
1
|
+
<?php
|
2
|
+
|
3
|
+
/**
|
4
|
+
* Prints tests' results in a similar way
|
5
|
+
* to rspec's progress formatter.
|
6
|
+
*
|
7
|
+
* @package PHPUnit
|
8
|
+
* @subpackage Progress
|
9
|
+
* @author Maher Sallam <maher@sallam.me>
|
10
|
+
* @copyright 2011 Maher Sallam <maher@sallam.me>
|
11
|
+
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
12
|
+
* @version 0.1
|
13
|
+
*/
|
14
|
+
class PHPUnit_Extensions_Progress_ResultPrinter extends PHPUnit_TextUI_ResultPrinter {
|
15
|
+
|
16
|
+
/**
|
17
|
+
* Constructor.
|
18
|
+
*
|
19
|
+
* @param mixed $out
|
20
|
+
* @param boolean $verbose
|
21
|
+
* @param boolean $colors
|
22
|
+
* @param boolean $debug
|
23
|
+
*/
|
24
|
+
public function __construct($out = NULL, $verbose = FALSE, $colors = FALSE, $debug = FALSE) {
|
25
|
+
|
26
|
+
// Start capturing output
|
27
|
+
ob_start();
|
28
|
+
|
29
|
+
$argv = $_SERVER['argv'];
|
30
|
+
$colors = in_array('--colors', $argv) || $colors;
|
31
|
+
$verbose = in_array('--verbose', $argv) || in_array('-v', $argv) || $verbose;
|
32
|
+
$debug = in_array('--debug', $argv) || $debug;
|
33
|
+
|
34
|
+
parent::__construct($out, $verbose, $colors, $debug);
|
35
|
+
}
|
36
|
+
|
37
|
+
/**
|
38
|
+
* @param PHPUnit_Framework_TestResult $result
|
39
|
+
*/
|
40
|
+
public function printResult(PHPUnit_Framework_TestResult $result)
|
41
|
+
{
|
42
|
+
print "\n";
|
43
|
+
|
44
|
+
if ($result->errorCount() > 0) {
|
45
|
+
$this->printErrors($result);
|
46
|
+
}
|
47
|
+
|
48
|
+
if ($result->failureCount() > 0) {
|
49
|
+
$this->printFailures($result);
|
50
|
+
}
|
51
|
+
|
52
|
+
if ($this->verbose) {
|
53
|
+
if ($result->deprecatedFeaturesCount() > 0) {
|
54
|
+
if ($result->failureCount() > 0) {
|
55
|
+
print "\n--\n\nDeprecated PHPUnit features are being used";
|
56
|
+
}
|
57
|
+
|
58
|
+
foreach ($result->deprecatedFeatures() as $deprecatedFeature) {
|
59
|
+
$this->write($deprecatedFeature . "\n\n");
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
if ($result->notImplementedCount() > 0) {
|
64
|
+
$this->printIncompletes($result);
|
65
|
+
}
|
66
|
+
|
67
|
+
if ($result->skippedCount() > 0) {
|
68
|
+
$this->printSkipped($result);
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
$this->printFooter($result);
|
73
|
+
}
|
74
|
+
|
75
|
+
/**
|
76
|
+
* @param array $defects
|
77
|
+
* @param integer $count
|
78
|
+
* @param string $type
|
79
|
+
*/
|
80
|
+
protected function printDefects(array $defects, $count, $type)
|
81
|
+
{
|
82
|
+
if ($count == 0) {
|
83
|
+
return;
|
84
|
+
}
|
85
|
+
|
86
|
+
$this->write("\n" . $type . ":\n");
|
87
|
+
|
88
|
+
$i = 1;
|
89
|
+
$failOrError = $type == 'Failures' || $type == 'Errors';
|
90
|
+
|
91
|
+
foreach ($defects as $defect) {
|
92
|
+
$this->printDefect($defect, $i++, $failOrError);
|
93
|
+
$this->write("\n");
|
94
|
+
}
|
95
|
+
}
|
96
|
+
|
97
|
+
/**
|
98
|
+
* @param PHPUnit_Framework_TestFailure $defect
|
99
|
+
* @param integer $count
|
100
|
+
* @param boolean $failOrError
|
101
|
+
*/
|
102
|
+
protected function printDefect(PHPUnit_Framework_TestFailure $defect, $count, $failOrError = true)
|
103
|
+
{
|
104
|
+
$this->printDefectHeader($defect, $count, $failOrError);
|
105
|
+
|
106
|
+
$padding = str_repeat(' ',
|
107
|
+
4 + ( $failOrError ? strlen((string)$count) : 0 )
|
108
|
+
);
|
109
|
+
|
110
|
+
$this->printDefectBody($defect, $count, $failOrError, $padding);
|
111
|
+
$this->printDefectTrace($defect, $padding);
|
112
|
+
}
|
113
|
+
|
114
|
+
/**
|
115
|
+
* @param PHPUnit_Framework_TestFailure $defect
|
116
|
+
* @param integer $count
|
117
|
+
* @param boolean $failOrError
|
118
|
+
*/
|
119
|
+
protected function printDefectHeader(PHPUnit_Framework_TestFailure $defect, $count, $failOrError = true)
|
120
|
+
{
|
121
|
+
$failedTest = $defect->failedTest();
|
122
|
+
|
123
|
+
if ($failedTest instanceof PHPUnit_Framework_SelfDescribing) {
|
124
|
+
$testName = $failedTest->toString();
|
125
|
+
} else {
|
126
|
+
$testName = get_class($failedTest);
|
127
|
+
}
|
128
|
+
|
129
|
+
if ( $failOrError ) {
|
130
|
+
$this->write(
|
131
|
+
sprintf(
|
132
|
+
"\n %d) %s",
|
133
|
+
|
134
|
+
$count,
|
135
|
+
$testName
|
136
|
+
)
|
137
|
+
);
|
138
|
+
} else {
|
139
|
+
$this->write(
|
140
|
+
sprintf( " %s", $this->yellow($testName) )
|
141
|
+
);
|
142
|
+
}
|
143
|
+
}
|
144
|
+
|
145
|
+
/**
|
146
|
+
* @param PHPUnit_Framework_TestFailure $defect
|
147
|
+
* @param integer $count
|
148
|
+
* @param boolean $failOrError
|
149
|
+
* @param string $padding
|
150
|
+
*/
|
151
|
+
protected function printDefectBody(PHPUnit_Framework_TestFailure $defect, $count, $failOrError, $padding)
|
152
|
+
{
|
153
|
+
$error = trim($defect->getExceptionAsString());
|
154
|
+
|
155
|
+
if ( !empty($error) ) {
|
156
|
+
$error = explode("\n", $error);
|
157
|
+
$error = "\n" . $padding . implode("\n " . $padding , $error);
|
158
|
+
|
159
|
+
$this->write( $failOrError ? $this->red($error) : $this->cyan($error) );
|
160
|
+
}
|
161
|
+
}
|
162
|
+
|
163
|
+
/**
|
164
|
+
* @param PHPUnit_Framework_TestFailure $defect
|
165
|
+
* @param string $padding
|
166
|
+
*/
|
167
|
+
protected function printDefectTrace(PHPUnit_Framework_TestFailure $defect, $padding = 0)
|
168
|
+
{
|
169
|
+
$trace = trim(
|
170
|
+
PHPUnit_Util_Filter::getFilteredStacktrace(
|
171
|
+
$defect->thrownException()
|
172
|
+
)
|
173
|
+
);
|
174
|
+
|
175
|
+
if ( ! empty($trace) ) {
|
176
|
+
$trace = explode("\n", $trace);
|
177
|
+
$trace = "\n" . $padding . '# ' . implode("\n${padding}# ", $trace);
|
178
|
+
|
179
|
+
$this->write($this->cyan($trace));
|
180
|
+
}
|
181
|
+
}
|
182
|
+
|
183
|
+
/**
|
184
|
+
* @param PHPUnit_Framework_TestResult $result
|
185
|
+
*/
|
186
|
+
protected function printErrors(PHPUnit_Framework_TestResult $result)
|
187
|
+
{
|
188
|
+
$this->printDefects(
|
189
|
+
$result->errors(),
|
190
|
+
$result->errorCount(),
|
191
|
+
'Errors'
|
192
|
+
);
|
193
|
+
}
|
194
|
+
|
195
|
+
/**
|
196
|
+
* @param PHPUnit_Framework_TestResult $result
|
197
|
+
*/
|
198
|
+
protected function printFailures(PHPUnit_Framework_TestResult $result)
|
199
|
+
{
|
200
|
+
$this->printDefects(
|
201
|
+
$result->failures(),
|
202
|
+
$result->failureCount(),
|
203
|
+
'Failures'
|
204
|
+
);
|
205
|
+
}
|
206
|
+
|
207
|
+
/**
|
208
|
+
* @param PHPUnit_Framework_TestResult $result
|
209
|
+
*/
|
210
|
+
protected function printIncompletes(PHPUnit_Framework_TestResult $result)
|
211
|
+
{
|
212
|
+
$this->printDefects(
|
213
|
+
$result->notImplemented(),
|
214
|
+
$result->notImplementedCount(),
|
215
|
+
'Incomplete tests'
|
216
|
+
);
|
217
|
+
}
|
218
|
+
|
219
|
+
/**
|
220
|
+
* @param PHPUnit_Framework_TestResult $result
|
221
|
+
* @since Method available since Release 3.0.0
|
222
|
+
*/
|
223
|
+
protected function printSkipped(PHPUnit_Framework_TestResult $result)
|
224
|
+
{
|
225
|
+
$this->printDefects(
|
226
|
+
$result->skipped(),
|
227
|
+
$result->skippedCount(),
|
228
|
+
'Skipped tests'
|
229
|
+
);
|
230
|
+
}
|
231
|
+
|
232
|
+
/**
|
233
|
+
* @param PHPUnit_Framework_TestResult $result
|
234
|
+
*/
|
235
|
+
protected function printFooter(PHPUnit_Framework_TestResult $result)
|
236
|
+
{
|
237
|
+
|
238
|
+
$this->write( sprintf("\nFinished in %s\n", PHP_Timer::timeSinceStartOfRequest()) );
|
239
|
+
|
240
|
+
$resultsCount = count($result);
|
241
|
+
|
242
|
+
$footer = sprintf("%d test%s, %d assertion%s",
|
243
|
+
$resultsCount,
|
244
|
+
$resultsCount == 1 ? '' : 's',
|
245
|
+
$this->numAssertions,
|
246
|
+
$this->numAssertions == 1 ? '' : 's'
|
247
|
+
);
|
248
|
+
|
249
|
+
if ( $result->wasSuccessful() &&
|
250
|
+
$result->allCompletlyImplemented() &&
|
251
|
+
$result->noneSkipped() )
|
252
|
+
{
|
253
|
+
$this->write($this->green($footer));
|
254
|
+
}
|
255
|
+
|
256
|
+
else if ( ( !$result->allCompletlyImplemented() || !$result->noneSkipped() )
|
257
|
+
&&
|
258
|
+
$result->wasSuccessful() )
|
259
|
+
{
|
260
|
+
|
261
|
+
$footer .= sprintf(
|
262
|
+
"%s%s",
|
263
|
+
|
264
|
+
$this->getCountString(
|
265
|
+
$result->notImplementedCount(), 'incomplete'
|
266
|
+
),
|
267
|
+
$this->getCountString(
|
268
|
+
$result->skippedCount(), 'skipped'
|
269
|
+
)
|
270
|
+
);
|
271
|
+
|
272
|
+
$this->write($this->yellow($footer));
|
273
|
+
|
274
|
+
}
|
275
|
+
|
276
|
+
else {
|
277
|
+
|
278
|
+
$footer .= sprintf(
|
279
|
+
"%s%s%s%s",
|
280
|
+
|
281
|
+
$this->getCountString($result->failureCount(), 'failures'),
|
282
|
+
$this->getCountString($result->errorCount(), 'errors'),
|
283
|
+
$this->getCountString(
|
284
|
+
$result->notImplementedCount(), 'incomplete'
|
285
|
+
),
|
286
|
+
$this->getCountString($result->skippedCount(), 'skipped')
|
287
|
+
);
|
288
|
+
|
289
|
+
$footer = preg_replace('/,$/', '', $footer);
|
290
|
+
|
291
|
+
$this->write($this->red($footer));
|
292
|
+
}
|
293
|
+
|
294
|
+
if ( ! $this->verbose &&
|
295
|
+
$result->deprecatedFeaturesCount() > 0 )
|
296
|
+
{
|
297
|
+
$message = sprintf(
|
298
|
+
"Warning: Deprecated PHPUnit features are being used %s times!\n".
|
299
|
+
"Use --verbose for more information.\n",
|
300
|
+
$result->deprecatedFeaturesCount()
|
301
|
+
);
|
302
|
+
|
303
|
+
if ($this->colors) {
|
304
|
+
$message = "\x1b[37;41m\x1b[2K" . $message .
|
305
|
+
"\x1b[0m";
|
306
|
+
}
|
307
|
+
|
308
|
+
$this->write("\n" . $message);
|
309
|
+
}
|
310
|
+
|
311
|
+
$this->writeNewLine();
|
312
|
+
}
|
313
|
+
|
314
|
+
/**
|
315
|
+
* @param integer $count
|
316
|
+
* @param string $name
|
317
|
+
* @return string
|
318
|
+
* @since Method available since Release 3.0.0
|
319
|
+
*/
|
320
|
+
protected function getCountString($count, $name)
|
321
|
+
{
|
322
|
+
$string = '';
|
323
|
+
|
324
|
+
if ($count > 0) {
|
325
|
+
$string = sprintf(
|
326
|
+
', %d %s',
|
327
|
+
|
328
|
+
$count,
|
329
|
+
$name
|
330
|
+
);
|
331
|
+
}
|
332
|
+
|
333
|
+
return $string;
|
334
|
+
}
|
335
|
+
|
336
|
+
/**
|
337
|
+
* An error occurred.
|
338
|
+
*
|
339
|
+
* @param PHPUnit_Framework_Test $test
|
340
|
+
* @param Exception $e
|
341
|
+
* @param float $time
|
342
|
+
*/
|
343
|
+
public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
|
344
|
+
{
|
345
|
+
$this->writeProgress($this->red('E'));
|
346
|
+
$this->lastTestFailed = TRUE;
|
347
|
+
}
|
348
|
+
|
349
|
+
/**
|
350
|
+
* A failure occurred.
|
351
|
+
*
|
352
|
+
* @param PHPUnit_Framework_Test $test
|
353
|
+
* @param PHPUnit_Framework_AssertionFailedError $e
|
354
|
+
* @param float $time
|
355
|
+
*/
|
356
|
+
public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
|
357
|
+
{
|
358
|
+
$this->writeProgress($this->red('F'));
|
359
|
+
$this->lastTestFailed = TRUE;
|
360
|
+
}
|
361
|
+
|
362
|
+
/**
|
363
|
+
* Incomplete test.
|
364
|
+
*
|
365
|
+
* @param PHPUnit_Framework_Test $test
|
366
|
+
* @param Exception $e
|
367
|
+
* @param float $time
|
368
|
+
*/
|
369
|
+
public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
|
370
|
+
{
|
371
|
+
$this->writeProgress($this->yellow('I'));
|
372
|
+
$this->lastTestFailed = TRUE;
|
373
|
+
}
|
374
|
+
|
375
|
+
/**
|
376
|
+
* Skipped test.
|
377
|
+
*
|
378
|
+
* @param PHPUnit_Framework_Test $test
|
379
|
+
* @param Exception $e
|
380
|
+
* @param float $time
|
381
|
+
* @since Method available since Release 3.0.0
|
382
|
+
*/
|
383
|
+
public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
|
384
|
+
{
|
385
|
+
$this->writeProgress($this->yellow('S'));
|
386
|
+
$this->lastTestFailed = TRUE;
|
387
|
+
}
|
388
|
+
|
389
|
+
/**
|
390
|
+
* A test ended.
|
391
|
+
*
|
392
|
+
* @param PHPUnit_Framework_Test $test
|
393
|
+
* @param float $time
|
394
|
+
*/
|
395
|
+
public function endTest(PHPUnit_Framework_Test $test, $time)
|
396
|
+
{
|
397
|
+
if (!$this->lastTestFailed) {
|
398
|
+
$this->writeProgress($this->green('.'));
|
399
|
+
}
|
400
|
+
|
401
|
+
if ($test instanceof PHPUnit_Framework_TestCase) {
|
402
|
+
$this->numAssertions += $test->getNumAssertions();
|
403
|
+
}
|
404
|
+
|
405
|
+
else if ($test instanceof PHPUnit_Extensions_PhptTestCase) {
|
406
|
+
$this->numAssertions++;
|
407
|
+
}
|
408
|
+
|
409
|
+
$this->lastTestFailed = FALSE;
|
410
|
+
|
411
|
+
if ($this->verbose && $test instanceof PHPUnit_Framework_TestCase) {
|
412
|
+
$this->write($test->getActualOutput());
|
413
|
+
}
|
414
|
+
|
415
|
+
}
|
416
|
+
|
417
|
+
/**
|
418
|
+
* @param string $progress
|
419
|
+
*/
|
420
|
+
protected function writeProgress($progress)
|
421
|
+
{
|
422
|
+
static $deletedHeader = false;
|
423
|
+
|
424
|
+
if ( ! $deletedHeader ) {
|
425
|
+
ob_clean();
|
426
|
+
$deletedHeader = true;
|
427
|
+
}
|
428
|
+
|
429
|
+
parent::writeProgress($progress);
|
430
|
+
}
|
431
|
+
|
432
|
+
/**
|
433
|
+
* Returns a colored string which can be used
|
434
|
+
* in the terminal.
|
435
|
+
*
|
436
|
+
* @param string $text
|
437
|
+
* @param integer $color_code
|
438
|
+
*/
|
439
|
+
protected function color($text, $color_code) {
|
440
|
+
return $this->colors ? "\033[${color_code}m" . $text . "\033[0m" : $text;
|
441
|
+
}
|
442
|
+
|
443
|
+
/**
|
444
|
+
* @param string $text
|
445
|
+
*/
|
446
|
+
protected function bold($text) {
|
447
|
+
return $this->color($text, "1");
|
448
|
+
}
|
449
|
+
|
450
|
+
/**
|
451
|
+
* @param string $text
|
452
|
+
*/
|
453
|
+
protected function red($text) {
|
454
|
+
return $this->color($text, "31");
|
455
|
+
}
|
456
|
+
|
457
|
+
/**
|
458
|
+
* @param string $text
|
459
|
+
*/
|
460
|
+
protected function green($text) {
|
461
|
+
return $this->color($text, "32");
|
462
|
+
}
|
463
|
+
|
464
|
+
/**
|
465
|
+
* @param string $text
|
466
|
+
*/
|
467
|
+
protected function yellow($text) {
|
468
|
+
return $this->color($text, "33");
|
469
|
+
}
|
470
|
+
|
471
|
+
/**
|
472
|
+
* @param string $text
|
473
|
+
*/
|
474
|
+
protected function blue($text) {
|
475
|
+
return $this->color($text, "34");
|
476
|
+
}
|
477
|
+
|
478
|
+
/**
|
479
|
+
* @param string $text
|
480
|
+
*/
|
481
|
+
protected function magenta($text) {
|
482
|
+
return $this->color($text, "35");
|
483
|
+
}
|
484
|
+
|
485
|
+
/**
|
486
|
+
* @param string $text
|
487
|
+
*/
|
488
|
+
protected function cyan($text) {
|
489
|
+
return $this->color($text, "36");
|
490
|
+
}
|
491
|
+
|
492
|
+
/**
|
493
|
+
* @param string $text
|
494
|
+
*/
|
495
|
+
protected function white($text) {
|
496
|
+
return $this->color($text, "37");
|
497
|
+
}
|
498
|
+
}
|