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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f49efdc481cac0f784e3c65cb68cdf854376a0df3b6082baef9a893469a27a6b
4
- data.tar.gz: 87d1b72bab6148ff502796e1c29d6bf786b08c3deeae45aa08f453dbaffaec63
3
+ metadata.gz: fdf29d364ee36b5ec7a9d54e2e80441d70a21a6b41bb89fb299f108081ba35bf
4
+ data.tar.gz: 16d74cfdcefa4ef0c16207998e1ece6e61ff5e4f46f24849a9915f3f2e34c1f0
5
5
  SHA512:
6
- metadata.gz: d262321031ccdc28a5e137697ecaed5bc168509de3e9ca4303ad672f072b35d8c857b3ddd1876fce04a51571e2568254e5928b300b1ec8a2524d5dc364b8f7d9
7
- data.tar.gz: f13f21aacfd75aca9f9f4970958f63868d3a4b5b13ac56b4ea9f9dd84ca7c5364343dc50310bbd01c65206c75ea7b7314d0363a1c042225ff4f65344e075371c
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
- parser = Dotpretty::Parser.new({ output: STDOUT })
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
@@ -1,12 +1,13 @@
1
- require "dotpretty/reporter"
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(output:)
8
- self.output = output
9
- self.state_machine = Dotpretty::StateMachineBuilder.build(Dotpretty::Reporter.new(output: output)) do
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 :starting_tests, :running_tests, :starting_tests
18
+ transition :tests_started, :waiting_for_test_input, :starting_tests
18
19
  end
19
- state :running_tests do
20
- transition :test_failed, :reading_test_failure, :test_failed
21
- transition :test_passed, :running_tests, :test_passed
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 :reading_test_failure do
25
- transition :test_passed, :running_tests, :test_passed
26
- transition :received_failure_output, :reading_test_failure, :show_failure_details
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
- case state_machine.current_state_name
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
@@ -0,0 +1,11 @@
1
+ module Dotpretty
2
+ module Reporters
3
+ class Names
4
+
5
+ BASIC = "basic"
6
+ JSON = "json"
7
+
8
+ ALL = [BASIC, JSON]
9
+ end
10
+ end
11
+ 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.1
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/reporter.rb
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
@@ -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