dotpretty 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/dotpretty +29 -1
- data/lib/dotpretty/aggregator.rb +105 -0
- data/lib/dotpretty/parser.rb +28 -41
- data/lib/dotpretty/reporters/basic.rb +43 -0
- data/lib/dotpretty/reporters/factory.rb +20 -0
- data/lib/dotpretty/reporters/json.rb +46 -0
- data/lib/dotpretty/reporters/names.rb +11 -0
- metadata +6 -2
- data/lib/dotpretty/reporter.rb +0 -42
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fdf29d364ee36b5ec7a9d54e2e80441d70a21a6b41bb89fb299f108081ba35bf
|
4
|
+
data.tar.gz: 16d74cfdcefa4ef0c16207998e1ece6e61ff5e4f46f24849a9915f3f2e34c1f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d855c3c5a208361dc345238e8b50d8bf1cb85e27632d6ad504a6728ff9af22b29e6f4a29ddcd6a7062f2af399768b6b739bfb53097ab4eaa85bbc4d665f1c55f
|
7
|
+
data.tar.gz: 8a64fd76daede11596684381c4fc1a1df6d2992a361c86c6ec9219e1d10ee20c1e1e201649672c7294587d38ba2731885fc013a45b76fad1d76f3b4c91a76a1e
|
data/bin/dotpretty
CHANGED
@@ -1,8 +1,36 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require "dotpretty/parser"
|
4
|
+
require "dotpretty/reporters/factory"
|
5
|
+
require "dotpretty/reporters/names"
|
6
|
+
require "optparse"
|
4
7
|
|
5
|
-
|
8
|
+
options = {}
|
9
|
+
OptionParser.new do |opts|
|
10
|
+
|
11
|
+
opts.banner = "Usage: dotnet test -v=normal Test.Project/ | dotnet [options]"
|
12
|
+
|
13
|
+
opts.on("-h", "--help", "Display this help") do
|
14
|
+
puts opts
|
15
|
+
exit
|
16
|
+
end
|
17
|
+
|
18
|
+
all_reporter_names = Dotpretty::Reporters::Names::ALL
|
19
|
+
reporter_message = ["Set reporter. Defaults to basic", "Available reporters: #{all_reporter_names.join(", ")}"]
|
20
|
+
opts.on("-rREPORTER", "--reporter=REPORTER", *reporter_message) do |reporter_name|
|
21
|
+
options[:reporter_name] = reporter_name
|
22
|
+
end
|
23
|
+
|
24
|
+
if STDIN.tty?
|
25
|
+
$stderr.puts opts.help
|
26
|
+
exit 1
|
27
|
+
end
|
28
|
+
|
29
|
+
end.parse!
|
30
|
+
|
31
|
+
|
32
|
+
reporter = Dotpretty::Reporters::Factory.build_reporter(options[:reporter_name], STDOUT)
|
33
|
+
parser = Dotpretty::Parser.new({ reporter: reporter })
|
6
34
|
|
7
35
|
STDIN.each_line do |line|
|
8
36
|
parser.parse_line(line)
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module Dotpretty
|
2
|
+
class Aggregator
|
3
|
+
|
4
|
+
BUILD_COMPLETED = /^Build completed/
|
5
|
+
TEST_FAILED = /^Failed/
|
6
|
+
TEST_PASSED = /^Passed/
|
7
|
+
TEST_SUMMARY = /^Total tests/
|
8
|
+
TESTS_STARTED = /^Starting test execution, please wait...$/
|
9
|
+
|
10
|
+
attr_accessor :state_machine
|
11
|
+
|
12
|
+
def initialize(reporter:)
|
13
|
+
self.reporter = reporter
|
14
|
+
end
|
15
|
+
|
16
|
+
def parse_line(input_line)
|
17
|
+
case state_machine.current_state_name
|
18
|
+
when :waiting
|
19
|
+
state_machine.trigger(:build_started)
|
20
|
+
when :build_in_progress
|
21
|
+
state_machine.trigger(:build_completed) if input_line.match(BUILD_COMPLETED)
|
22
|
+
when :ready_to_run_tests
|
23
|
+
state_machine.trigger(:tests_started) if input_line.match(TESTS_STARTED)
|
24
|
+
when :waiting_for_test_input
|
25
|
+
state_machine.trigger(:test_input_received, input_line)
|
26
|
+
when :waiting_for_failure_details
|
27
|
+
state_machine.trigger(:received_failure_details, input_line)
|
28
|
+
when :reading_failure_details
|
29
|
+
state_machine.trigger(:received_input_line, input_line)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def parse_test_input(input_line)
|
34
|
+
if input_line.match(TEST_PASSED)
|
35
|
+
match = input_line.match(/^Passed\s+(.+)$/)
|
36
|
+
state_machine.trigger(:test_passed, match[1])
|
37
|
+
elsif input_line.match(TEST_FAILED)
|
38
|
+
match = input_line.match(/^Failed\s+(.+)$/)
|
39
|
+
state_machine.trigger(:test_failed, match[1])
|
40
|
+
elsif input_line.match(TEST_SUMMARY)
|
41
|
+
state_machine.trigger(:tests_completed, input_line)
|
42
|
+
else
|
43
|
+
state_machine.trigger(:received_other_input)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def build_completed
|
48
|
+
reporter.build_completed
|
49
|
+
end
|
50
|
+
|
51
|
+
def build_started
|
52
|
+
reporter.build_started
|
53
|
+
end
|
54
|
+
|
55
|
+
def track_failure_details(details)
|
56
|
+
current_failing_test[:details] << details.rstrip if details.rstrip != ""
|
57
|
+
end
|
58
|
+
|
59
|
+
def show_test_summary(summary)
|
60
|
+
match = summary.match(/^Total tests: (\d+). Passed: (\d+). Failed: (\d+). Skipped: (\d+)./)
|
61
|
+
reporter.show_test_summary({
|
62
|
+
failedTests: match[3].to_i,
|
63
|
+
passedTests: match[2].to_i,
|
64
|
+
skippedTests: match[4].to_i,
|
65
|
+
totalTests: match[1].to_i
|
66
|
+
})
|
67
|
+
end
|
68
|
+
|
69
|
+
def report_failing_test(*args)
|
70
|
+
reporter.test_failed(current_failing_test)
|
71
|
+
end
|
72
|
+
|
73
|
+
def parse_failure_line(input_line)
|
74
|
+
if input_line.match(TEST_PASSED)
|
75
|
+
state_machine.trigger(:done_reading_failure, input_line)
|
76
|
+
elsif input_line.match(TEST_SUMMARY)
|
77
|
+
state_machine.trigger(:done_reading_failure, input_line)
|
78
|
+
elsif input_line.match(TEST_FAILED)
|
79
|
+
state_machine.trigger(:done_reading_failure, input_line)
|
80
|
+
else
|
81
|
+
state_machine.trigger(:received_failure_output, input_line)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def starting_tests
|
86
|
+
reporter.starting_tests
|
87
|
+
end
|
88
|
+
|
89
|
+
def reset_current_failing_test(test_name)
|
90
|
+
self.current_failing_test = {
|
91
|
+
details: [],
|
92
|
+
name: test_name
|
93
|
+
}
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_passed(test_name)
|
97
|
+
reporter.test_passed(test_name)
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
attr_accessor :current_failing_test, :reporter
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
data/lib/dotpretty/parser.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
|
-
require "dotpretty/
|
1
|
+
require "dotpretty/aggregator"
|
2
|
+
require "dotpretty/reporters/basic"
|
2
3
|
require "dotpretty/state_machine_builder"
|
3
4
|
|
4
5
|
module Dotpretty
|
5
6
|
class Parser
|
6
7
|
|
7
|
-
def initialize(
|
8
|
-
self.
|
9
|
-
self.state_machine = Dotpretty::StateMachineBuilder.build(
|
8
|
+
def initialize(reporter:)
|
9
|
+
self.aggregator = Dotpretty::Aggregator.new({ reporter: reporter })
|
10
|
+
self.state_machine = Dotpretty::StateMachineBuilder.build(aggregator) do
|
10
11
|
state :waiting do
|
11
12
|
transition :build_started, :build_in_progress, :build_started
|
12
13
|
end
|
@@ -14,56 +15,42 @@ module Dotpretty
|
|
14
15
|
transition :build_completed, :ready_to_run_tests, :build_completed
|
15
16
|
end
|
16
17
|
state :ready_to_run_tests do
|
17
|
-
transition :
|
18
|
+
transition :tests_started, :waiting_for_test_input, :starting_tests
|
18
19
|
end
|
19
|
-
state :
|
20
|
-
transition :
|
21
|
-
|
20
|
+
state :waiting_for_test_input do
|
21
|
+
transition :test_input_received, :parsing_test_input
|
22
|
+
end
|
23
|
+
state :parsing_test_input do
|
24
|
+
on_entry :parse_test_input
|
25
|
+
transition :received_other_input, :waiting_for_test_input
|
26
|
+
transition :test_failed, :waiting_for_failure_details, :reset_current_failing_test
|
27
|
+
transition :test_passed, :waiting_for_test_input, :test_passed
|
22
28
|
transition :tests_completed, :done, :show_test_summary
|
23
29
|
end
|
24
|
-
state :
|
25
|
-
transition :
|
26
|
-
|
30
|
+
state :waiting_for_failure_details do
|
31
|
+
transition :received_failure_details, :reading_failure_details
|
32
|
+
end
|
33
|
+
state :reading_failure_details do
|
34
|
+
on_entry :parse_failure_line
|
35
|
+
transition :done_reading_failure, :parsing_test_input, :report_failing_test
|
36
|
+
transition :received_failure_output, :waiting_for_failure_details, :track_failure_details
|
37
|
+
end
|
38
|
+
state :parsing_failure_line do
|
39
|
+
on_entry :parse_failure_line
|
40
|
+
transition :received_failure_output, :reading_failure_details, :track_failure_details
|
27
41
|
transition :tests_completed, :done, :show_test_summary
|
28
42
|
end
|
29
43
|
end
|
44
|
+
aggregator.state_machine = state_machine
|
30
45
|
end
|
31
46
|
|
32
47
|
def parse_line(input_line)
|
33
|
-
|
34
|
-
when :waiting
|
35
|
-
state_machine.trigger(:build_started)
|
36
|
-
when :build_in_progress
|
37
|
-
state_machine.trigger(:build_completed) if input_line.match(/^Build completed/)
|
38
|
-
when :ready_to_run_tests
|
39
|
-
if input_line.match(/^Starting test execution, please wait...$/)
|
40
|
-
state_machine.trigger(:starting_tests)
|
41
|
-
end
|
42
|
-
when :running_tests
|
43
|
-
if input_line.start_with?("Passed")
|
44
|
-
match = input_line.match(/^Passed\s+(.+)$/)
|
45
|
-
state_machine.trigger(:test_passed, match[1])
|
46
|
-
elsif input_line.start_with?("Failed")
|
47
|
-
match = input_line.match(/^Failed\s+(.+)$/)
|
48
|
-
state_machine.trigger(:test_failed, match[1])
|
49
|
-
elsif input_line.start_with?("Total tests")
|
50
|
-
state_machine.trigger(:tests_completed, input_line)
|
51
|
-
end
|
52
|
-
when :reading_test_failure
|
53
|
-
if input_line.start_with?("Passed")
|
54
|
-
match = input_line.match(/^Passed\s+(.+)$/)
|
55
|
-
state_machine.trigger(:test_passed, match[1])
|
56
|
-
elsif input_line.start_with?("Total tests")
|
57
|
-
state_machine.trigger(:tests_completed, input_line)
|
58
|
-
else
|
59
|
-
state_machine.trigger(:received_failure_output, input_line)
|
60
|
-
end
|
61
|
-
end
|
48
|
+
aggregator.parse_line(input_line)
|
62
49
|
end
|
63
50
|
|
64
51
|
private
|
65
52
|
|
66
|
-
attr_accessor :output, :state_machine
|
53
|
+
attr_accessor :aggregator, :output, :state_machine
|
67
54
|
|
68
55
|
end
|
69
56
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Dotpretty
|
2
|
+
module Reporters
|
3
|
+
class Basic
|
4
|
+
|
5
|
+
def initialize(output)
|
6
|
+
self.output = output
|
7
|
+
end
|
8
|
+
|
9
|
+
def build_started
|
10
|
+
output.puts("Build started")
|
11
|
+
end
|
12
|
+
|
13
|
+
def build_completed
|
14
|
+
output.puts("Build completed")
|
15
|
+
output.puts("")
|
16
|
+
end
|
17
|
+
|
18
|
+
def starting_tests
|
19
|
+
output.puts("Starting test execution...")
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_passed(test_name)
|
23
|
+
output.puts("Passed #{test_name}")
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_failed(failing_test)
|
27
|
+
output.puts("Failed #{failing_test[:name]}")
|
28
|
+
failing_test[:details].each do |line|
|
29
|
+
output.puts(line)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def show_test_summary(summary)
|
34
|
+
output.puts("\nTotal tests: #{summary[:totalTests]}. Passed: #{summary[:passedTests]}. Failed: #{summary[:failedTests]}. Skipped: #{summary[:skippedTests]}.\n")
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
attr_accessor :output
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "dotpretty/reporters/basic"
|
2
|
+
require "dotpretty/reporters/json"
|
3
|
+
require "dotpretty/reporters/names"
|
4
|
+
|
5
|
+
module Dotpretty
|
6
|
+
module Reporters
|
7
|
+
class Factory
|
8
|
+
|
9
|
+
def self.build_reporter(name, output)
|
10
|
+
case name
|
11
|
+
when Dotpretty::Reporters::Names::JSON
|
12
|
+
return Dotpretty::Reporters::Json.new(output)
|
13
|
+
else
|
14
|
+
return Dotpretty::Reporters::Basic.new({ output: output })
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require "json"
|
2
|
+
|
3
|
+
module Dotpretty
|
4
|
+
module Reporters
|
5
|
+
class Json
|
6
|
+
|
7
|
+
def initialize(output)
|
8
|
+
self.output = output
|
9
|
+
self.tests = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def build_started
|
13
|
+
end
|
14
|
+
|
15
|
+
def build_completed
|
16
|
+
end
|
17
|
+
|
18
|
+
def starting_tests
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_passed(test_name)
|
22
|
+
tests << {
|
23
|
+
name: test_name,
|
24
|
+
result: "passed"
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_failed(failing_test)
|
29
|
+
tests << failing_test.merge({
|
30
|
+
result: "failed"
|
31
|
+
})
|
32
|
+
end
|
33
|
+
|
34
|
+
def show_test_summary(summary)
|
35
|
+
output.puts({
|
36
|
+
tests: tests
|
37
|
+
}.to_json)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
attr_accessor :output, :tests
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dotpretty
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Meyer
|
@@ -19,8 +19,12 @@ extra_rdoc_files: []
|
|
19
19
|
files:
|
20
20
|
- bin/dotpretty
|
21
21
|
- lib/dotpretty.rb
|
22
|
+
- lib/dotpretty/aggregator.rb
|
22
23
|
- lib/dotpretty/parser.rb
|
23
|
-
- lib/dotpretty/
|
24
|
+
- lib/dotpretty/reporters/basic.rb
|
25
|
+
- lib/dotpretty/reporters/factory.rb
|
26
|
+
- lib/dotpretty/reporters/json.rb
|
27
|
+
- lib/dotpretty/reporters/names.rb
|
24
28
|
- lib/dotpretty/state_details.rb
|
25
29
|
- lib/dotpretty/state_machine.rb
|
26
30
|
- lib/dotpretty/state_machine_builder.rb
|
data/lib/dotpretty/reporter.rb
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
module Dotpretty
|
2
|
-
class Reporter
|
3
|
-
|
4
|
-
def initialize(output:)
|
5
|
-
self.output = output
|
6
|
-
end
|
7
|
-
|
8
|
-
def build_completed
|
9
|
-
output.puts("Build completed")
|
10
|
-
output.puts("")
|
11
|
-
end
|
12
|
-
|
13
|
-
def build_started
|
14
|
-
output.puts("Build started")
|
15
|
-
end
|
16
|
-
|
17
|
-
def show_failure_details(details)
|
18
|
-
output.puts("#{details}")
|
19
|
-
end
|
20
|
-
|
21
|
-
def show_test_summary(summary)
|
22
|
-
output.puts("\n#{summary}")
|
23
|
-
end
|
24
|
-
|
25
|
-
def starting_tests
|
26
|
-
output.puts("Starting test execution...")
|
27
|
-
end
|
28
|
-
|
29
|
-
def test_failed(test_name)
|
30
|
-
output.puts("Failed #{test_name}")
|
31
|
-
end
|
32
|
-
|
33
|
-
def test_passed(test_name)
|
34
|
-
output.puts("Passed #{test_name}")
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
attr_accessor :output
|
40
|
-
|
41
|
-
end
|
42
|
-
end
|