dotpretty 0.0.1 → 0.1.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 +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
|