guard-phpunit2 0.2.6 → 0.2.7
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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/guard/phpunit/formatters/PHPUnit-Progress/PHPUnit/Extensions/Progress/ResultPrinter.php +1 -1
- data/lib/guard/phpunit2/logreader.rb +114 -0
- data/lib/guard/phpunit2/realtime_runner.rb +54 -0
- data/lib/guard/phpunit2/runner.rb +26 -9
- data/lib/guard/phpunit2/version.rb +1 -1
- data/lib/guard/phpunit2.rb +10 -3
- data/spec/fixtures/failureSampleTest.php +11 -0
- data/spec/fixtures/mixedSampleTest.php +23 -0
- data/spec/fixtures/passingSampleTest.php +11 -0
- data/spec/fixtures/results/failing-json.txt +53 -0
- data/spec/fixtures/results/mixed-json.txt +110 -0
- data/spec/fixtures/results/multiple-test-cases-json.txt +319 -0
- data/spec/fixtures/results/passing-json.txt +35 -0
- data/spec/fixtures/results/skipped_and_incomplete-json.txt +77 -0
- data/spec/fixtures/skippedSampleTest.php +15 -0
- data/spec/guard/phpunit2/logreader_spec.rb +62 -0
- data/spec/guard/phpunit2/realtime_runner_spec.rb +167 -0
- data/spec/guard/phpunit2_spec.rb +29 -1
- data.tar.gz.sig +0 -0
- metadata +37 -14
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 81d31e2b034295210e186676f0192edf353604e4
|
4
|
+
data.tar.gz: 6b5f8d0593d418fc6ab4a3789fd6238ab18ac3c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd75f1a8826faff16feebdd4f98bcb3e9434a31c7f691685ff59dcaa5640f01394c495ffb5b9546ffd8d65166effd1f5a030278d993a5279c3bdadcca0ae9fe9
|
7
|
+
data.tar.gz: dcf12bb176c68eb33dece74c8713b8688b1b77aa3273a808adfcb68d527e60ef0693c8bdd2728865994e16d333c5b1b9027b3f83623fbf276226f9dc6e635b8b
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'json'
|
2
|
+
module Guard
|
3
|
+
class PHPUnit2
|
4
|
+
module LogReader
|
5
|
+
class << self
|
6
|
+
|
7
|
+
# Parses the output of --log-json
|
8
|
+
#
|
9
|
+
# @param [String] the file's contents
|
10
|
+
# @return [Hash] with the following properties:
|
11
|
+
# :tests => number of tests executed
|
12
|
+
# :failures => number of tests failing because of an assertion
|
13
|
+
# not being met
|
14
|
+
# :errors => number of tests failing because of an error (like
|
15
|
+
# an Exception)
|
16
|
+
# :pending => number of tests skipped or incomplete
|
17
|
+
# :duration => length of test with units
|
18
|
+
def parse_output(output)
|
19
|
+
log = JSON.parse(clean_output(output))
|
20
|
+
|
21
|
+
tests = 0
|
22
|
+
passes = 0
|
23
|
+
errors = 0
|
24
|
+
failures = 0
|
25
|
+
skips = 0
|
26
|
+
duration = 0
|
27
|
+
|
28
|
+
tests = log.first['tests'] unless log.empty?
|
29
|
+
log.each do |event|
|
30
|
+
passes += 1 if passed_test?(event)
|
31
|
+
failures += 1 if failed_test?(event)
|
32
|
+
skips += 1 if skipped_test?(event)
|
33
|
+
errors += 1 if error_test?(event)
|
34
|
+
|
35
|
+
duration += event['time'] if event['time']
|
36
|
+
end
|
37
|
+
|
38
|
+
{
|
39
|
+
:tests => tests,
|
40
|
+
:failures => failures,
|
41
|
+
:errors => errors,
|
42
|
+
:pending => skips,
|
43
|
+
:duration => calculate_duration(duration)
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
# PHPUnit writes out the JSON log as a series of JSON objects
|
50
|
+
# It is not serializable all as one object. We need to
|
51
|
+
# turn it into an array and add commas between subsequent objects
|
52
|
+
#
|
53
|
+
# @param [String] json log output from PPHUnit
|
54
|
+
# @return [String] properly-formed JSON string
|
55
|
+
def clean_output(output)
|
56
|
+
"[#{output.gsub(/^}{/, '},{')}]"
|
57
|
+
end
|
58
|
+
|
59
|
+
# Turns a float duration into a array of integer seconds and the
|
60
|
+
# string 'seconds'
|
61
|
+
#
|
62
|
+
# This is the format expected by Guard
|
63
|
+
#
|
64
|
+
# @param [Float] duration in fractions of a second
|
65
|
+
# @return [Fixnum, String]
|
66
|
+
def calculate_duration(duration)
|
67
|
+
[duration.to_i, 'seconds']
|
68
|
+
end
|
69
|
+
|
70
|
+
# Determines if a PHPUnit event represents a skipped test
|
71
|
+
#
|
72
|
+
# Skipped and Incomplete tests are considered skipped
|
73
|
+
# @param [Hash] json object for a single PHPUnit event
|
74
|
+
# @return [Boolean]
|
75
|
+
def skipped_test?(event)
|
76
|
+
return false unless event['event'] == 'test' && event['status'] == 'error'
|
77
|
+
|
78
|
+
!!event['message'].match(/Skipped|Incomplete/i)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Determine if a PHPUnit event represents a test that errored out
|
82
|
+
#
|
83
|
+
# Errored tests are those that failed because of an error, for example
|
84
|
+
# an exception. Assertion failures are not considered errors
|
85
|
+
#
|
86
|
+
# @param [Hash] json object for a single event
|
87
|
+
# @return [Boolean]
|
88
|
+
def error_test?(event)
|
89
|
+
return false unless event['event'] == 'test' && event['status'] == 'error'
|
90
|
+
|
91
|
+
!skipped_test?(event)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Determine if a PHPUnit event represents a test that passed
|
95
|
+
#
|
96
|
+
# @param [Hash] json object for a single event
|
97
|
+
# @return [Boolean]
|
98
|
+
def passed_test?(event)
|
99
|
+
event['event'] == 'test' && event['status'] == 'pass'
|
100
|
+
end
|
101
|
+
|
102
|
+
# Determine if a PHPUnit event represents a test that failed because an
|
103
|
+
# assertion was not met.
|
104
|
+
#
|
105
|
+
# @param [Hash] JSON object for a single event
|
106
|
+
# @return [Boolean]
|
107
|
+
def failed_test?(event)
|
108
|
+
event['event'] == 'test' && event['status'] == 'fail'
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'tmpdir'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module Guard
|
5
|
+
class PHPUnit2
|
6
|
+
|
7
|
+
# The Guard::PHPUnit runner handles running the tests, displaying
|
8
|
+
# their output and notifying the user about the results.
|
9
|
+
#
|
10
|
+
class RealtimeRunner < Runner
|
11
|
+
|
12
|
+
def self.run(paths, options)
|
13
|
+
self.new.run(paths, options)
|
14
|
+
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
|
18
|
+
def parse_output(log)
|
19
|
+
LogReader.parse_output(log)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Generates the phpunit command for the tests paths.
|
23
|
+
#
|
24
|
+
# @param (see #run)
|
25
|
+
# @param (see #run)
|
26
|
+
# @see #run_tests
|
27
|
+
#
|
28
|
+
def phpunit_command(path, options, logfile)
|
29
|
+
super(path, options) do |cmd_parts|
|
30
|
+
cmd_parts << "--log-json #{logfile}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Executes a system command but does not return the output
|
35
|
+
#
|
36
|
+
# @param [String] command the command to be run
|
37
|
+
#
|
38
|
+
def execute_command(command)
|
39
|
+
system(command)
|
40
|
+
end
|
41
|
+
|
42
|
+
def execute_phpunit(tests_folder, options)
|
43
|
+
log_file = Tempfile.new "guard-phpunit2"
|
44
|
+
execute_command(phpunit_command(tests_folder, options, log_file.path))
|
45
|
+
|
46
|
+
log = log_file.read
|
47
|
+
log_file.close
|
48
|
+
log_file.unlink
|
49
|
+
|
50
|
+
log
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -7,8 +7,11 @@ module Guard
|
|
7
7
|
# The Guard::PHPUnit runner handles running the tests, displaying
|
8
8
|
# their output and notifying the user about the results.
|
9
9
|
#
|
10
|
-
|
11
|
-
|
10
|
+
class Runner
|
11
|
+
|
12
|
+
def self.run(paths, options)
|
13
|
+
self.new.run(paths, options)
|
14
|
+
end
|
12
15
|
|
13
16
|
# The exittcode phpunit returns when the tests contain failures
|
14
17
|
#
|
@@ -38,7 +41,7 @@ module Guard
|
|
38
41
|
run_tests(paths, options)
|
39
42
|
end
|
40
43
|
|
41
|
-
|
44
|
+
protected
|
42
45
|
|
43
46
|
# Checks that phpunit is installed on the user's
|
44
47
|
# machine.
|
@@ -67,15 +70,13 @@ module Guard
|
|
67
70
|
|
68
71
|
if paths.length == 1
|
69
72
|
tests_path = paths.first
|
70
|
-
output =
|
73
|
+
output = execute_phpunit(tests_path, options)
|
71
74
|
else
|
72
75
|
create_tests_folder_for(paths) do |tests_folder|
|
73
|
-
output =
|
76
|
+
output = execute_phpunit(tests_folder, options)
|
74
77
|
end
|
75
78
|
end
|
76
79
|
|
77
|
-
# print the output to the terminal
|
78
|
-
puts output
|
79
80
|
|
80
81
|
# return false in case the system call fails with no status!
|
81
82
|
return false if $?.nil?
|
@@ -108,10 +109,15 @@ module Guard
|
|
108
109
|
# @param (see #run)
|
109
110
|
#
|
110
111
|
def notify_results(output, options)
|
111
|
-
results =
|
112
|
+
results = parse_output(output)
|
112
113
|
Notifier.notify_results(results)
|
113
114
|
end
|
114
115
|
|
116
|
+
# Parses the output into the hash Guard expects
|
117
|
+
def parse_output(output)
|
118
|
+
Formatter.parse_output(output)
|
119
|
+
end
|
120
|
+
|
115
121
|
# Displays a notification about failing to run the tests
|
116
122
|
#
|
117
123
|
# @param (see #run)
|
@@ -184,9 +190,14 @@ module Guard
|
|
184
190
|
cmd_parts << command
|
185
191
|
cmd_parts << "--include-path #{formatter_path}"
|
186
192
|
cmd_parts << "--printer PHPUnit_Extensions_Progress_ResultPrinter"
|
193
|
+
|
194
|
+
# Allow callers to inject some parts if needed
|
195
|
+
yield cmd_parts if block_given?
|
196
|
+
|
187
197
|
cmd_parts << options[:cli] if options[:cli]
|
188
198
|
cmd_parts << path
|
189
199
|
|
200
|
+
|
190
201
|
cmd_parts.join(' ')
|
191
202
|
end
|
192
203
|
|
@@ -198,7 +209,13 @@ module Guard
|
|
198
209
|
def execute_command(command)
|
199
210
|
%x{#{command}}
|
200
211
|
end
|
201
|
-
|
212
|
+
|
213
|
+
def execute_phpunit(tests_folder, options)
|
214
|
+
output = execute_command phpunit_command(tests_folder, options)
|
215
|
+
puts output
|
216
|
+
|
217
|
+
output
|
218
|
+
end
|
202
219
|
end
|
203
220
|
end
|
204
221
|
end
|
data/lib/guard/phpunit2.rb
CHANGED
@@ -13,6 +13,8 @@ module Guard
|
|
13
13
|
autoload :Formatter, 'guard/phpunit2/formatter'
|
14
14
|
autoload :Notifier, 'guard/phpunit2/notifier'
|
15
15
|
autoload :Runner, 'guard/phpunit2/runner'
|
16
|
+
autoload :LogReader, 'guard/phpunit2/logreader'
|
17
|
+
autoload :RealtimeRunner, 'guard/phpunit2/realtime_runner'
|
16
18
|
|
17
19
|
DEFAULT_OPTIONS = {
|
18
20
|
:all_on_start => true,
|
@@ -20,7 +22,8 @@ module Guard
|
|
20
22
|
:keep_failed => true,
|
21
23
|
:cli => nil,
|
22
24
|
:tests_path => Dir.pwd,
|
23
|
-
:notification => true
|
25
|
+
:notification => true,
|
26
|
+
:realtime => false
|
24
27
|
}
|
25
28
|
|
26
29
|
# Initialize Guard::PHPUnit.
|
@@ -57,7 +60,7 @@ module Guard
|
|
57
60
|
# @raise (see #start)
|
58
61
|
#
|
59
62
|
def run_all
|
60
|
-
success =
|
63
|
+
success = runner.run(options[:tests_path], options.merge(
|
61
64
|
:message => 'Running all tests'
|
62
65
|
))
|
63
66
|
|
@@ -72,7 +75,7 @@ module Guard
|
|
72
75
|
#
|
73
76
|
def run_on_changes(paths)
|
74
77
|
paths = Inspector.clean(paths + @failed_paths)
|
75
|
-
success =
|
78
|
+
success = runner.run(paths, options)
|
76
79
|
|
77
80
|
update_failed_paths(success, paths)
|
78
81
|
run_all_after_pass(success)
|
@@ -81,6 +84,10 @@ module Guard
|
|
81
84
|
|
82
85
|
private
|
83
86
|
|
87
|
+
def runner
|
88
|
+
options[:realtime] ? RealtimeRunner : Runner
|
89
|
+
end
|
90
|
+
|
84
91
|
# Adds or removes path to the failed_paths bassed
|
85
92
|
# on the tests result.
|
86
93
|
#
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<?php
|
2
|
+
|
3
|
+
class Mixed extends PHPUnit_Framework_TestCase {
|
4
|
+
public function testPass() {
|
5
|
+
$this->assertTrue(true);
|
6
|
+
}
|
7
|
+
|
8
|
+
public function testFail() {
|
9
|
+
$this->assertTrue(false);
|
10
|
+
}
|
11
|
+
|
12
|
+
public function testError() {
|
13
|
+
throw new Exception("Broked!");
|
14
|
+
}
|
15
|
+
|
16
|
+
public function testSkipped() {
|
17
|
+
$this->markTestSkipped();
|
18
|
+
}
|
19
|
+
|
20
|
+
public function testIncomplete() {
|
21
|
+
$this->markTestIncomplete();
|
22
|
+
}
|
23
|
+
}
|
@@ -0,0 +1,53 @@
|
|
1
|
+
{
|
2
|
+
"event": "suiteStart",
|
3
|
+
"suite": "Fail2",
|
4
|
+
"tests": 2
|
5
|
+
}{
|
6
|
+
"event": "testStart",
|
7
|
+
"suite": "Fail2",
|
8
|
+
"test": "Fail2::testTrueIsTrue"
|
9
|
+
}{
|
10
|
+
"event": "test",
|
11
|
+
"suite": "Fail2",
|
12
|
+
"test": "Fail2::testTrueIsTrue",
|
13
|
+
"status": "fail",
|
14
|
+
"time": 0.0018670558929443,
|
15
|
+
"trace": [
|
16
|
+
{
|
17
|
+
"file": "\/Users\/mburke\/personal\/guard-phpunit2\/spec\/fixtures\/fail2.php",
|
18
|
+
"line": 5,
|
19
|
+
"function": "assertTrue",
|
20
|
+
"class": "PHPUnit_Framework_Assert",
|
21
|
+
"type": "::",
|
22
|
+
"args": [
|
23
|
+
false
|
24
|
+
]
|
25
|
+
}
|
26
|
+
],
|
27
|
+
"message": "Failed asserting that false is true.",
|
28
|
+
"output": ""
|
29
|
+
}{
|
30
|
+
"event": "testStart",
|
31
|
+
"suite": "Fail2",
|
32
|
+
"test": "Fail2::testFalseIsFalse"
|
33
|
+
}{
|
34
|
+
"event": "test",
|
35
|
+
"suite": "Fail2",
|
36
|
+
"test": "Fail2::testFalseIsFalse",
|
37
|
+
"status": "fail",
|
38
|
+
"time": 0.00041508674621582,
|
39
|
+
"trace": [
|
40
|
+
{
|
41
|
+
"file": "\/Users\/mburke\/personal\/guard-phpunit2\/spec\/fixtures\/fail2.php",
|
42
|
+
"line": 9,
|
43
|
+
"function": "assertFalse",
|
44
|
+
"class": "PHPUnit_Framework_Assert",
|
45
|
+
"type": "::",
|
46
|
+
"args": [
|
47
|
+
true
|
48
|
+
]
|
49
|
+
}
|
50
|
+
],
|
51
|
+
"message": "Failed asserting that true is false.",
|
52
|
+
"output": ""
|
53
|
+
}
|
@@ -0,0 +1,110 @@
|
|
1
|
+
{
|
2
|
+
"event": "suiteStart",
|
3
|
+
"suite": "Mixed",
|
4
|
+
"tests": 5
|
5
|
+
}{
|
6
|
+
"event": "testStart",
|
7
|
+
"suite": "Mixed",
|
8
|
+
"test": "Mixed::testPass"
|
9
|
+
}{
|
10
|
+
"event": "test",
|
11
|
+
"suite": "Mixed",
|
12
|
+
"test": "Mixed::testPass",
|
13
|
+
"status": "pass",
|
14
|
+
"time": 0.0012249946594238,
|
15
|
+
"trace": [
|
16
|
+
|
17
|
+
],
|
18
|
+
"message": "",
|
19
|
+
"output": ""
|
20
|
+
}{
|
21
|
+
"event": "testStart",
|
22
|
+
"suite": "Mixed",
|
23
|
+
"test": "Mixed::testFail"
|
24
|
+
}{
|
25
|
+
"event": "test",
|
26
|
+
"suite": "Mixed",
|
27
|
+
"test": "Mixed::testFail",
|
28
|
+
"status": "fail",
|
29
|
+
"time": 0.00089907646179199,
|
30
|
+
"trace": [
|
31
|
+
{
|
32
|
+
"file": "\/Users\/mburke\/personal\/guard-phpunit2\/spec\/fixtures\/mixed.php",
|
33
|
+
"line": 9,
|
34
|
+
"function": "assertTrue",
|
35
|
+
"class": "PHPUnit_Framework_Assert",
|
36
|
+
"type": "::",
|
37
|
+
"args": [
|
38
|
+
false
|
39
|
+
]
|
40
|
+
}
|
41
|
+
],
|
42
|
+
"message": "Failed asserting that false is true.",
|
43
|
+
"output": ""
|
44
|
+
}{
|
45
|
+
"event": "testStart",
|
46
|
+
"suite": "Mixed",
|
47
|
+
"test": "Mixed::testError"
|
48
|
+
}{
|
49
|
+
"event": "test",
|
50
|
+
"suite": "Mixed",
|
51
|
+
"test": "Mixed::testError",
|
52
|
+
"status": "error",
|
53
|
+
"time": 0.0003211498260498,
|
54
|
+
"trace": [
|
55
|
+
{
|
56
|
+
"file": "\/Users\/mburke\/personal\/guard-phpunit2\/spec\/fixtures\/mixed.php",
|
57
|
+
"line": 13
|
58
|
+
}
|
59
|
+
],
|
60
|
+
"message": "Broked!",
|
61
|
+
"output": ""
|
62
|
+
}{
|
63
|
+
"event": "testStart",
|
64
|
+
"suite": "Mixed",
|
65
|
+
"test": "Mixed::testSkipped"
|
66
|
+
}{
|
67
|
+
"event": "test",
|
68
|
+
"suite": "Mixed",
|
69
|
+
"test": "Mixed::testSkipped",
|
70
|
+
"status": "error",
|
71
|
+
"time": 0.0005791187286377,
|
72
|
+
"trace": [
|
73
|
+
{
|
74
|
+
"file": "\/Users\/mburke\/personal\/guard-phpunit2\/spec\/fixtures\/mixed.php",
|
75
|
+
"line": 17,
|
76
|
+
"function": "markTestSkipped",
|
77
|
+
"class": "PHPUnit_Framework_Assert",
|
78
|
+
"type": "::",
|
79
|
+
"args": [
|
80
|
+
|
81
|
+
]
|
82
|
+
}
|
83
|
+
],
|
84
|
+
"message": "Skipped Test: ",
|
85
|
+
"output": ""
|
86
|
+
}{
|
87
|
+
"event": "testStart",
|
88
|
+
"suite": "Mixed",
|
89
|
+
"test": "Mixed::testIncomplete"
|
90
|
+
}{
|
91
|
+
"event": "test",
|
92
|
+
"suite": "Mixed",
|
93
|
+
"test": "Mixed::testIncomplete",
|
94
|
+
"status": "error",
|
95
|
+
"time": 0.00052285194396973,
|
96
|
+
"trace": [
|
97
|
+
{
|
98
|
+
"file": "\/Users\/mburke\/personal\/guard-phpunit2\/spec\/fixtures\/mixed.php",
|
99
|
+
"line": 21,
|
100
|
+
"function": "markTestIncomplete",
|
101
|
+
"class": "PHPUnit_Framework_Assert",
|
102
|
+
"type": "::",
|
103
|
+
"args": [
|
104
|
+
|
105
|
+
]
|
106
|
+
}
|
107
|
+
],
|
108
|
+
"message": "Incomplete Test: ",
|
109
|
+
"output": ""
|
110
|
+
}
|