dotpretty 0.8.1 → 0.9.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a657d16a0b5ccbe5f4b67eaeb09a70f349c9fe9dcfd8fe8021703963a66bc8c4
4
- data.tar.gz: 45b81b2f084da0490a76bb6f8247355dd7c5dfd8b709406923b48a545fbdd6ac
3
+ metadata.gz: c19f485b3423444380bc1288152ab158d27b1b3f0a80909d094e745ae24df8ec
4
+ data.tar.gz: ecea2dab730e241d3774d9ec13e9f216ae3b780c7d331e82791f25a0ead8579c
5
5
  SHA512:
6
- metadata.gz: e7283d15195d4f4d20b699ac605ffab981b5714f3c92808b3a019c1c15bfdb4cc9232c0e83f62d5f919d66da7b52b0f56b2cab76431a23df2f281c3fed34642b
7
- data.tar.gz: 9f2dcd67dd66a84c1a55dcdeaceb7605039e9fb8ec3d9e8c3a4619a115a694b482d830d548bf39a2b20342cbe3bef35a00d90dc593d94f3453b551488d33015d
6
+ metadata.gz: 39193f4dc7bc9566e5a87702610d70286cacbc9c1775aa6b58964a62cc21108db20fa4bb5ab73efbcb1fb5030e83dee6aead8aeaf5cb47374f8340a37479077e
7
+ data.tar.gz: 215b44b59aadcedd0a638701354124ebdd23a8c6cf3b22547ed4d98d57d82a1f95bf804862b752d3115efc844fa9da4c45e5fc566ff0a13187c630fb49c66c09
data/bin/dotpretty CHANGED
@@ -1,21 +1,18 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $: << File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
4
-
5
- require "dotpretty/color_palettes/bash"
6
- require "dotpretty/color_palettes/null"
7
- require "dotpretty/reporters/names"
3
+ require "dotpretty/options"
8
4
  require "dotpretty/runner"
5
+ require "dotpretty/reporters/names"
9
6
  require "dotpretty/version"
10
7
  require "optparse"
11
8
 
12
- options = {}
9
+ command_line_args = {}
13
10
  OptionParser.new do |opts|
14
11
 
15
12
  opts.banner = "Usage: dotnet test -v=normal Test.Project/ | dotnet [options]"
16
13
 
17
14
  opts.on("-c", "--color", "Enable color output") do |color|
18
- options[:color] = color
15
+ command_line_args[:color] = color
19
16
  end
20
17
 
21
18
  opts.on("-h", "--help", "Display this help") do
@@ -26,7 +23,7 @@ OptionParser.new do |opts|
26
23
  all_reporter_names = Dotpretty::Reporters::Names::ALL
27
24
  reporter_message = ["Set reporter. Defaults to basic", "Available reporters: #{all_reporter_names.join(", ")}"]
28
25
  opts.on("-rREPORTER", "--reporter=REPORTER", *reporter_message) do |reporter_name|
29
- options[:reporter_name] = reporter_name
26
+ command_line_args[:reporter_name] = reporter_name
30
27
  end
31
28
 
32
29
  if STDIN.tty?
@@ -37,11 +34,12 @@ OptionParser.new do |opts|
37
34
 
38
35
  end.parse!
39
36
 
40
- color_palette = options[:color] ? Dotpretty::ColorPalettes::Bash : Dotpretty::ColorPalettes::Null
41
- runner = Dotpretty::Runner.new({
42
- color_palette: color_palette,
37
+ options = Dotpretty::Options.build({
38
+ color: command_line_args.fetch(:color, false),
43
39
  output: STDOUT,
44
- reporter_name: options[:reporter_name]
40
+ reporter_name: command_line_args.fetch(:reporter_name, Dotpretty::Reporters::Names::BASIC)
45
41
  })
46
- STDIN.each_line { |line| runner.parse_line(line) }
42
+
43
+ runner = Dotpretty::Runner.new({ reporter: options.reporter })
44
+ STDIN.each_line { |line| runner.input_received(line) }
47
45
  runner.done_with_input
@@ -0,0 +1,26 @@
1
+ require "httparty"
2
+
3
+ module Dotpretty
4
+ module Http
5
+ class Client
6
+
7
+ def initialize(api_root:)
8
+ self.api_root = api_root
9
+ end
10
+
11
+ def post_json(route, data=nil)
12
+ HTTParty.post("#{api_root}#{route}", {
13
+ body: data.to_json,
14
+ headers: {
15
+ "Content-Type": "application/json"
16
+ }
17
+ })
18
+ end
19
+
20
+ private
21
+
22
+ attr_accessor :api_root
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,10 @@
1
+ module Dotpretty
2
+ module Http
3
+ class NullClient
4
+
5
+ def post_json(route, data=nil)
6
+ end
7
+
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,45 @@
1
+ require "dotpretty/color_palettes/bash"
2
+ require "dotpretty/color_palettes/null"
3
+ require "dotpretty/http/client"
4
+ require "dotpretty/http/null_client"
5
+ require "dotpretty/reporters/factory"
6
+
7
+ module Dotpretty
8
+ class Options
9
+
10
+ def self.build(command_line_args)
11
+ color_palette = command_line_args[:color] ? Dotpretty::ColorPalettes::Bash : Dotpretty::ColorPalettes::Null
12
+ http_client = Dotpretty::Http::Client.new({
13
+ api_root: "http://localhost:4567"
14
+ })
15
+ reporter_name = command_line_args.fetch(:reporter_name)
16
+ return Dotpretty::Options.new({
17
+ color_palette: color_palette,
18
+ http_client: http_client,
19
+ output: command_line_args.fetch(:output),
20
+ reporter_name: reporter_name
21
+ })
22
+ end
23
+
24
+ def initialize(color_palette:, http_client: Dotpretty::Http::NullClient.new, output:, reporter_name:)
25
+ self.color_palette = color_palette
26
+ self.http_client = http_client
27
+ self.output = output
28
+ self.reporter_name = reporter_name
29
+ end
30
+
31
+ def reporter
32
+ return Dotpretty::Reporters::Factory.build_reporter(reporter_name, {
33
+ color_palette: color_palette,
34
+ http_client: http_client,
35
+ output: output
36
+ })
37
+
38
+ end
39
+
40
+ private
41
+
42
+ attr_accessor :color_palette, :http_client, :output, :reporter_name
43
+
44
+ end
45
+ end
@@ -1,76 +1,173 @@
1
- require "dotpretty/aggregator"
2
- require "dotpretty/reporters/basic"
3
- require "dotpretty/state_machine/state_machine_builder"
4
-
5
1
  module Dotpretty
6
2
  class Parser
7
3
 
4
+ BUILD_STARTED = /^Build started/
5
+ BUILD_COMPLETED = /^Build completed/
6
+ BUILD_FAILED = /^Build FAILED.$/
7
+ TEST_FAILED = /^Failed/
8
+ TEST_PASSED = /^Passed/
9
+ TEST_SKIPPED = /^Skipped/
10
+ TEST_SUMMARY = /^Total tests/
11
+ TESTS_STARTED = /^Starting test execution, please wait...$/
12
+
13
+ attr_accessor :state_machine
14
+
8
15
  def initialize(reporter:)
9
- self.aggregator = Dotpretty::Aggregator.new({ reporter: reporter })
10
- self.state_machine = Dotpretty::StateMachine::StateMachineBuilder.build(aggregator) do
11
- state :waiting do
12
- transition :build_started, :build_in_progress, :build_started
13
- end
14
- state :build_in_progress do
15
- transition :received_build_input, :parsing_build_input
16
- end
17
- state :parsing_build_input do
18
- on_entry :parse_build_input
19
- transition :build_completed, :ready_to_run_tests, :build_completed
20
- transition :build_failed, :reading_build_failure_details, :reset_build_failure_details
21
- transition :received_build_input, :build_in_progress
22
- end
23
- state :reading_build_failure_details do
24
- transition :received_build_failure_details, :reading_build_failure_details, :track_build_failure_details
25
- transition :end_of_input, :done, :report_failing_build
26
- end
27
- state :ready_to_run_tests do
28
- transition :received_input_line, :determining_if_tests_started
29
- end
30
- state :determining_if_tests_started do
31
- on_entry :determine_if_tests_started
32
- transition :tests_started, :waiting_for_test_input, :starting_tests
33
- transition :tests_did_not_start, :ready_to_run_tests
34
- end
35
- state :waiting_for_test_input do
36
- transition :test_input_received, :parsing_test_input
37
- end
38
- state :parsing_test_input do
39
- on_entry :parse_test_input
40
- transition :received_other_input, :waiting_for_test_input
41
- transition :test_failed, :waiting_for_failure_details, :reset_current_failing_test
42
- transition :test_passed, :waiting_for_test_input, :test_passed
43
- transition :test_skipped, :waiting_for_test_input, :test_skipped
44
- transition :tests_completed, :done, :show_test_summary
45
- end
46
- state :waiting_for_failure_details do
47
- transition :received_failure_details, :reading_failure_details
48
- end
49
- state :reading_failure_details do
50
- on_entry :parse_failure_line
51
- transition :done_reading_failure, :parsing_test_input, :report_failing_test
52
- transition :received_failure_output, :waiting_for_failure_details, :track_failure_details
53
- end
54
- state :parsing_failure_line do
55
- on_entry :parse_failure_line
56
- transition :received_failure_output, :reading_failure_details, :track_failure_details
57
- transition :tests_completed, :done, :show_test_summary
58
- end
59
- end
60
- aggregator.state_machine = state_machine
16
+ self.raw_input_inlines = []
17
+ self.reporter = reporter
61
18
  end
62
19
 
63
20
  def parse_line(input_line)
64
- aggregator.parse_line(input_line)
21
+ raw_input_inlines << input_line
22
+ case state_machine.current_state_name
23
+ when :waiting_for_build_to_start
24
+ state_machine.trigger(:received_input_line, input_line)
25
+ when :build_in_progress
26
+ state_machine.trigger(:received_build_input, input_line)
27
+ when :reading_build_failure_details
28
+ state_machine.trigger(:received_build_failure_details, input_line)
29
+ when :ready_to_run_tests
30
+ state_machine.trigger(:received_input_line, input_line)
31
+ when :waiting_for_test_input
32
+ state_machine.trigger(:test_input_received, input_line)
33
+ when :waiting_for_failure_details
34
+ state_machine.trigger(:received_failure_details, input_line)
35
+ when :reading_failure_details
36
+ state_machine.trigger(:received_input_line, input_line)
37
+ end
38
+ end
39
+
40
+ def handle_end_of_input
41
+ case state_machine.current_state_name
42
+ when :waiting_for_build_to_start
43
+ state_machine.trigger(:build_failed_to_start)
44
+ else
45
+ state_machine.trigger(:end_of_input)
46
+ end
47
+ end
48
+
49
+ def parse_prebuild_input(input_line)
50
+ if input_line.match(BUILD_STARTED)
51
+ state_machine.trigger(:build_started)
52
+ else
53
+ state_machine.trigger(:build_did_not_start)
54
+ end
55
+ end
56
+
57
+ def build_failed_to_start
58
+ reporter.build_failed_to_start(raw_input_inlines)
59
+ end
60
+
61
+ def parse_build_input(input_line)
62
+ if input_line.match(BUILD_COMPLETED)
63
+ state_machine.trigger(:build_completed)
64
+ elsif input_line.match(BUILD_FAILED)
65
+ state_machine.trigger(:build_failed)
66
+ else
67
+ state_machine.trigger(:received_build_input)
68
+ end
69
+ end
70
+
71
+ def determine_if_tests_started(input_line)
72
+ if input_line.match(TESTS_STARTED)
73
+ state_machine.trigger(:tests_started)
74
+ else
75
+ state_machine.trigger(:tests_did_not_start)
76
+ end
77
+ end
78
+
79
+ def parse_test_input(input_line)
80
+ if input_line.match(TEST_PASSED)
81
+ match = input_line.match(/^Passed\s+(.+)$/)
82
+ state_machine.trigger(:test_passed, match[1])
83
+ elsif input_line.match(TEST_FAILED)
84
+ match = input_line.match(/^Failed\s+(.+)$/)
85
+ state_machine.trigger(:test_failed, match[1])
86
+ elsif input_line.match(TEST_SKIPPED)
87
+ match = input_line.match(/^Skipped\s+(.+)$/)
88
+ state_machine.trigger(:test_skipped, match[1])
89
+ elsif input_line.match(TEST_SUMMARY)
90
+ state_machine.trigger(:tests_completed, input_line)
91
+ else
92
+ state_machine.trigger(:received_other_input)
93
+ end
94
+ end
95
+
96
+ def build_completed
97
+ reporter.build_completed
98
+ end
99
+
100
+ def build_started
101
+ reporter.build_started
102
+ end
103
+
104
+ def reset_build_failure_details
105
+ self.build_failure_details = []
106
+ end
107
+
108
+ def track_build_failure_details(input_line)
109
+ build_failure_details << input_line
110
+ end
111
+
112
+ def report_failing_build
113
+ reporter.build_failed(build_failure_details)
114
+ end
115
+
116
+ def track_failure_details(details)
117
+ current_failing_test[:details] << details.rstrip if details.rstrip != ""
118
+ end
119
+
120
+ def show_test_summary(summary)
121
+ match = summary.match(/^Total tests: (\d+). Passed: (\d+). Failed: (\d+). Skipped: (\d+)./)
122
+ reporter.show_test_summary({
123
+ failedTests: match[3].to_i,
124
+ passedTests: match[2].to_i,
125
+ skippedTests: match[4].to_i,
126
+ totalTests: match[1].to_i
127
+ })
128
+ end
129
+
130
+ def report_failing_test(*_)
131
+ reporter.test_failed({
132
+ details: current_failing_test[:details],
133
+ name: current_failing_test[:name]
134
+ })
135
+ end
136
+
137
+ def parse_failure_line(input_line)
138
+ if input_line.match(TEST_PASSED)
139
+ state_machine.trigger(:done_reading_failure, input_line)
140
+ elsif input_line.match(TEST_SUMMARY)
141
+ state_machine.trigger(:done_reading_failure, input_line)
142
+ elsif input_line.match(TEST_FAILED)
143
+ state_machine.trigger(:done_reading_failure, input_line)
144
+ else
145
+ state_machine.trigger(:received_failure_output, input_line)
146
+ end
147
+ end
148
+
149
+ def starting_tests
150
+ reporter.starting_tests
151
+ end
152
+
153
+ def reset_current_failing_test(test_name)
154
+ self.current_failing_test = {
155
+ details: [],
156
+ name: test_name
157
+ }
158
+ end
159
+
160
+ def test_passed(name)
161
+ reporter.test_passed({ name: name })
65
162
  end
66
163
 
67
- def done_with_input
68
- state_machine.trigger(:end_of_input)
164
+ def test_skipped(name)
165
+ reporter.test_skipped({ name: name })
69
166
  end
70
167
 
71
168
  private
72
169
 
73
- attr_accessor :aggregator, :output, :state_machine
170
+ attr_accessor :build_failure_details, :current_failing_test, :raw_input_inlines, :reporter
74
171
 
75
172
  end
76
173
  end
@@ -14,6 +14,12 @@ module Dotpretty
14
14
  output.puts("Build started")
15
15
  end
16
16
 
17
+ def build_failed_to_start(raw_input_inlines)
18
+ raw_input_inlines.each do |raw_input_line|
19
+ output.puts(raw_input_line)
20
+ end
21
+ end
22
+
17
23
  def build_completed
18
24
  output.puts("Build completed")
19
25
  output.puts("")
@@ -30,17 +36,17 @@ module Dotpretty
30
36
  output.puts("Starting test execution...")
31
37
  end
32
38
 
33
- def test_passed(test_name)
34
- output.puts("#{green("Passed")} #{test_name}")
39
+ def test_passed(name:)
40
+ output.puts("#{green("Passed")} #{name}")
35
41
  end
36
42
 
37
- def test_skipped(test_name)
38
- output.puts("#{yellow("Skipped")} #{test_name}")
43
+ def test_skipped(name:)
44
+ output.puts("#{yellow("Skipped")} #{name}")
39
45
  end
40
46
 
41
- def test_failed(failing_test)
42
- output.puts("#{red("Failed")} #{failing_test[:name]}")
43
- failing_test[:details].each do |line|
47
+ def test_failed(name:, details:)
48
+ output.puts("#{red("Failed")} #{name}")
49
+ details.each do |line|
44
50
  output.puts(line)
45
51
  end
46
52
  end
@@ -0,0 +1,60 @@
1
+ module Dotpretty
2
+ module Reporters
3
+ class Browser
4
+
5
+ def initialize(http_client:)
6
+ self.http_client = http_client
7
+ end
8
+
9
+ def build_completed
10
+ end
11
+
12
+ def build_failed_to_start(raw_input_inlines)
13
+ end
14
+
15
+ def build_failed(failure_details)
16
+ end
17
+
18
+ def build_started
19
+ http_client.post_json("/build_started")
20
+ end
21
+
22
+ def show_test_summary(test_summary)
23
+ http_client.post_json("/update_results", {
24
+ tests: tests
25
+ })
26
+ end
27
+
28
+ def starting_tests
29
+ self.tests = []
30
+ end
31
+
32
+ def test_failed(name:, details:)
33
+ tests << {
34
+ details: details,
35
+ name: name,
36
+ result: "failed"
37
+ }
38
+ end
39
+
40
+ def test_passed(name:)
41
+ tests << {
42
+ name: name,
43
+ result: "passed"
44
+ }
45
+ end
46
+
47
+ def test_skipped(name:)
48
+ tests << {
49
+ name: name,
50
+ result: "skipped"
51
+ }
52
+ end
53
+
54
+ private
55
+
56
+ attr_accessor :http_client, :tests
57
+
58
+ end
59
+ end
60
+ end
@@ -1,5 +1,6 @@
1
1
  require "dotpretty/color_palettes/null"
2
2
  require "dotpretty/reporters/basic"
3
+ require "dotpretty/reporters/browser"
3
4
  require "dotpretty/reporters/json"
4
5
  require "dotpretty/reporters/names"
5
6
  require "dotpretty/reporters/progress"
@@ -10,6 +11,10 @@ module Dotpretty
10
11
 
11
12
  def self.build_reporter(name, options = {})
12
13
  case name
14
+ when Dotpretty::Reporters::Names::BROWSER
15
+ return Dotpretty::Reporters::Browser.new({
16
+ http_client: options.fetch(:http_client)
17
+ })
13
18
  when Dotpretty::Reporters::Names::JSON
14
19
  return Dotpretty::Reporters::Json.new(options.fetch(:output))
15
20
  when Dotpretty::Reporters::Names::PROGRESS
@@ -12,6 +12,9 @@ module Dotpretty
12
12
  def build_started
13
13
  end
14
14
 
15
+ def build_failed_to_start(raw_input_inlines)
16
+ end
17
+
15
18
  def build_completed
16
19
  end
17
20
 
@@ -21,24 +24,26 @@ module Dotpretty
21
24
  def starting_tests
22
25
  end
23
26
 
24
- def test_passed(test_name)
27
+ def test_passed(name:)
25
28
  tests << {
26
- name: test_name,
29
+ name: name,
27
30
  result: "passed"
28
31
  }
29
32
  end
30
33
 
31
- def test_skipped(test_name)
34
+ def test_skipped(name:)
32
35
  tests << {
33
- name: test_name,
36
+ name: name,
34
37
  result: "skipped"
35
38
  }
36
39
  end
37
40
 
38
- def test_failed(failing_test)
39
- tests << failing_test.merge({
41
+ def test_failed(name:, details:)
42
+ tests << {
43
+ details: details,
44
+ name: name,
40
45
  result: "failed"
41
- })
46
+ }
42
47
  end
43
48
 
44
49
  def show_test_summary(summary)
@@ -3,10 +3,12 @@ module Dotpretty
3
3
  class Names
4
4
 
5
5
  BASIC = "basic"
6
+ BROWSER = "browser"
6
7
  JSON = "json"
7
8
  PROGRESS = "progress"
8
9
 
9
- ALL = [ BASIC, JSON, PROGRESS ]
10
+ ALL = [ BASIC, BROWSER, JSON, PROGRESS ]
11
+
10
12
  end
11
13
  end
12
14
  end
@@ -15,6 +15,12 @@ module Dotpretty
15
15
  output.puts("")
16
16
  end
17
17
 
18
+ def build_failed_to_start(raw_input_inlines)
19
+ raw_input_inlines.each do |raw_input_line|
20
+ output.puts(raw_input_line)
21
+ end
22
+ end
23
+
18
24
  def build_started
19
25
  output.puts("Build started")
20
26
  end
@@ -38,17 +44,20 @@ module Dotpretty
38
44
  output.puts("Starting test execution")
39
45
  end
40
46
 
41
- def test_failed(failing_test)
42
- failing_tests << failing_test
47
+ def test_failed(name:, details:)
48
+ failing_tests << {
49
+ details: details,
50
+ name: name
51
+ }
43
52
  output.print(red("F"))
44
53
  end
45
54
 
46
- def test_passed(passing_test)
55
+ def test_passed(name:)
47
56
  output.print(green("."))
48
57
  end
49
58
 
50
- def test_skipped(test_name)
51
- skipped_test_names << test_name
59
+ def test_skipped(name:)
60
+ skipped_test_names << name
52
61
  output.print(yellow("*"))
53
62
  end
54
63
 
@@ -1,28 +1,82 @@
1
1
  require "dotpretty/parser"
2
- require "dotpretty/reporters/factory"
2
+ require "dotpretty/reporters/basic"
3
+ require "dotpretty/state_machine/state_machine_builder"
3
4
 
4
5
  module Dotpretty
5
6
  class Runner
6
7
 
7
- def initialize(color_palette:, output:, reporter_name:)
8
- reporter = Dotpretty::Reporters::Factory.build_reporter(reporter_name, {
9
- output: output,
10
- color_palette: color_palette
11
- })
8
+ def initialize(reporter:)
12
9
  self.parser = Dotpretty::Parser.new({ reporter: reporter })
10
+ self.state_machine = Dotpretty::StateMachine::StateMachineBuilder.build(parser) do
11
+ state :waiting_for_build_to_start do
12
+ transition :build_failed_to_start, :done, :build_failed_to_start
13
+ transition :received_input_line, :determining_if_build_started
14
+ end
15
+ state :determining_if_build_started do
16
+ on_entry :parse_prebuild_input
17
+ transition :build_started, :build_in_progress, :build_started
18
+ transition :build_did_not_start, :waiting_for_build_to_start
19
+ end
20
+ state :build_in_progress do
21
+ transition :received_build_input, :parsing_build_input
22
+ end
23
+ state :parsing_build_input do
24
+ on_entry :parse_build_input
25
+ transition :build_completed, :ready_to_run_tests, :build_completed
26
+ transition :build_failed, :reading_build_failure_details, :reset_build_failure_details
27
+ transition :received_build_input, :build_in_progress
28
+ end
29
+ state :reading_build_failure_details do
30
+ transition :received_build_failure_details, :reading_build_failure_details, :track_build_failure_details
31
+ transition :end_of_input, :done, :report_failing_build
32
+ end
33
+ state :ready_to_run_tests do
34
+ transition :received_input_line, :determining_if_tests_started
35
+ end
36
+ state :determining_if_tests_started do
37
+ on_entry :determine_if_tests_started
38
+ transition :tests_started, :waiting_for_test_input, :starting_tests
39
+ transition :tests_did_not_start, :ready_to_run_tests
40
+ end
41
+ state :waiting_for_test_input do
42
+ transition :test_input_received, :parsing_test_input
43
+ end
44
+ state :parsing_test_input do
45
+ on_entry :parse_test_input
46
+ transition :received_other_input, :waiting_for_test_input
47
+ transition :test_failed, :waiting_for_failure_details, :reset_current_failing_test
48
+ transition :test_passed, :waiting_for_test_input, :test_passed
49
+ transition :test_skipped, :waiting_for_test_input, :test_skipped
50
+ transition :tests_completed, :done, :show_test_summary
51
+ end
52
+ state :waiting_for_failure_details do
53
+ transition :received_failure_details, :reading_failure_details
54
+ end
55
+ state :reading_failure_details do
56
+ on_entry :parse_failure_line
57
+ transition :done_reading_failure, :parsing_test_input, :report_failing_test
58
+ transition :received_failure_output, :waiting_for_failure_details, :track_failure_details
59
+ end
60
+ state :parsing_failure_line do
61
+ on_entry :parse_failure_line
62
+ transition :received_failure_output, :reading_failure_details, :track_failure_details
63
+ transition :tests_completed, :done, :show_test_summary
64
+ end
65
+ end
66
+ parser.state_machine = state_machine
13
67
  end
14
68
 
15
- def parse_line(line)
16
- parser.parse_line(line)
69
+ def input_received(input_line)
70
+ parser.parse_line(input_line)
17
71
  end
18
72
 
19
73
  def done_with_input
20
- parser.done_with_input
74
+ parser.handle_end_of_input
21
75
  end
22
76
 
23
77
  private
24
78
 
25
- attr_accessor :parser
79
+ attr_accessor :parser, :output, :state_machine
26
80
 
27
81
  end
28
82
  end
@@ -1,3 +1,3 @@
1
1
  module Dotpretty
2
- VERSION = "0.8.1"
2
+ VERSION = "0.9.0"
3
3
  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.8.1
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Meyer
@@ -9,7 +9,21 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
  date: 2019-05-02 00:00:00.000000000 Z
12
- dependencies: []
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httparty
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.17'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.17'
13
27
  description: A gem to parse and improve the output of the dotnet command
14
28
  email:
15
29
  executables:
@@ -18,11 +32,14 @@ extensions: []
18
32
  extra_rdoc_files: []
19
33
  files:
20
34
  - bin/dotpretty
21
- - lib/dotpretty/aggregator.rb
22
35
  - lib/dotpretty/color_palettes/bash.rb
23
36
  - lib/dotpretty/color_palettes/null.rb
37
+ - lib/dotpretty/http/client.rb
38
+ - lib/dotpretty/http/null_client.rb
39
+ - lib/dotpretty/options.rb
24
40
  - lib/dotpretty/parser.rb
25
41
  - lib/dotpretty/reporters/basic.rb
42
+ - lib/dotpretty/reporters/browser.rb
26
43
  - lib/dotpretty/reporters/factory.rb
27
44
  - lib/dotpretty/reporters/json.rb
28
45
  - lib/dotpretty/reporters/names.rb
@@ -1,146 +0,0 @@
1
- module Dotpretty
2
- class Aggregator
3
-
4
- BUILD_COMPLETED = /^Build completed/
5
- BUILD_FAILED = /^Build FAILED.$/
6
- TEST_FAILED = /^Failed/
7
- TEST_PASSED = /^Passed/
8
- TEST_SKIPPED = /^Skipped/
9
- TEST_SUMMARY = /^Total tests/
10
- TESTS_STARTED = /^Starting test execution, please wait...$/
11
-
12
- attr_accessor :state_machine
13
-
14
- def initialize(reporter:)
15
- self.reporter = reporter
16
- end
17
-
18
- def parse_line(input_line)
19
- case state_machine.current_state_name
20
- when :waiting
21
- state_machine.trigger(:build_started)
22
- when :build_in_progress
23
- state_machine.trigger(:received_build_input, input_line)
24
- when :reading_build_failure_details
25
- state_machine.trigger(:received_build_failure_details, input_line)
26
- when :ready_to_run_tests
27
- state_machine.trigger(:received_input_line, input_line)
28
- when :waiting_for_test_input
29
- state_machine.trigger(:test_input_received, input_line)
30
- when :waiting_for_failure_details
31
- state_machine.trigger(:received_failure_details, input_line)
32
- when :reading_failure_details
33
- state_machine.trigger(:received_input_line, input_line)
34
- end
35
- end
36
-
37
- def parse_build_input(input_line)
38
- if input_line.match(BUILD_COMPLETED)
39
- state_machine.trigger(:build_completed)
40
- elsif input_line.match(BUILD_FAILED)
41
- state_machine.trigger(:build_failed)
42
- else
43
- state_machine.trigger(:received_build_input)
44
- end
45
- end
46
-
47
- def determine_if_tests_started(input_line)
48
- if input_line.match(TESTS_STARTED)
49
- state_machine.trigger(:tests_started)
50
- else
51
- state_machine.trigger(:tests_did_not_start)
52
- end
53
- end
54
-
55
- def parse_test_input(input_line)
56
- if input_line.match(TEST_PASSED)
57
- match = input_line.match(/^Passed\s+(.+)$/)
58
- state_machine.trigger(:test_passed, match[1])
59
- elsif input_line.match(TEST_FAILED)
60
- match = input_line.match(/^Failed\s+(.+)$/)
61
- state_machine.trigger(:test_failed, match[1])
62
- elsif input_line.match(TEST_SKIPPED)
63
- match = input_line.match(/^Skipped\s+(.+)$/)
64
- state_machine.trigger(:test_skipped, match[1])
65
- elsif input_line.match(TEST_SUMMARY)
66
- state_machine.trigger(:tests_completed, input_line)
67
- else
68
- state_machine.trigger(:received_other_input)
69
- end
70
- end
71
-
72
- def build_completed
73
- reporter.build_completed
74
- end
75
-
76
- def build_started
77
- reporter.build_started
78
- end
79
-
80
- def reset_build_failure_details
81
- self.build_failure_details = []
82
- end
83
-
84
- def track_build_failure_details(input_line)
85
- build_failure_details << input_line
86
- end
87
-
88
- def report_failing_build
89
- reporter.build_failed(build_failure_details)
90
- end
91
-
92
- def track_failure_details(details)
93
- current_failing_test[:details] << details.rstrip if details.rstrip != ""
94
- end
95
-
96
- def show_test_summary(summary)
97
- match = summary.match(/^Total tests: (\d+). Passed: (\d+). Failed: (\d+). Skipped: (\d+)./)
98
- reporter.show_test_summary({
99
- failedTests: match[3].to_i,
100
- passedTests: match[2].to_i,
101
- skippedTests: match[4].to_i,
102
- totalTests: match[1].to_i
103
- })
104
- end
105
-
106
- def report_failing_test(*args)
107
- reporter.test_failed(current_failing_test)
108
- end
109
-
110
- def parse_failure_line(input_line)
111
- if input_line.match(TEST_PASSED)
112
- state_machine.trigger(:done_reading_failure, input_line)
113
- elsif input_line.match(TEST_SUMMARY)
114
- state_machine.trigger(:done_reading_failure, input_line)
115
- elsif input_line.match(TEST_FAILED)
116
- state_machine.trigger(:done_reading_failure, input_line)
117
- else
118
- state_machine.trigger(:received_failure_output, input_line)
119
- end
120
- end
121
-
122
- def starting_tests
123
- reporter.starting_tests
124
- end
125
-
126
- def reset_current_failing_test(test_name)
127
- self.current_failing_test = {
128
- details: [],
129
- name: test_name
130
- }
131
- end
132
-
133
- def test_passed(test_name)
134
- reporter.test_passed(test_name)
135
- end
136
-
137
- def test_skipped(test_name)
138
- reporter.test_skipped(test_name)
139
- end
140
-
141
- private
142
-
143
- attr_accessor :build_failure_details, :current_failing_test, :reporter
144
-
145
- end
146
- end