flatware 0.3.2 → 0.4.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/README.md +83 -39
- data/lib/flatware-cucumber.rb +1 -0
- data/lib/flatware-rspec.rb +1 -0
- data/lib/flatware.rb +2 -10
- data/lib/flatware/broadcaster.rb +15 -0
- data/lib/flatware/cli.rb +10 -34
- data/lib/flatware/cucumber.rb +37 -12
- data/lib/flatware/cucumber/checkpoint.rb +28 -0
- data/lib/flatware/cucumber/cli.rb +22 -0
- data/lib/flatware/cucumber/formatter.rb +36 -84
- data/lib/flatware/{formatters/cucumber → cucumber/formatters}/console.rb +5 -3
- data/lib/flatware/{formatters/cucumber → cucumber/formatters}/console/summary.rb +3 -3
- data/lib/flatware/cucumber/result.rb +27 -0
- data/lib/flatware/cucumber/scenario_result.rb +38 -0
- data/lib/flatware/cucumber/step_result.rb +30 -0
- data/lib/flatware/poller.rb +2 -2
- data/lib/flatware/rspec.rb +28 -0
- data/lib/flatware/rspec/checkpoint.rb +29 -0
- data/lib/flatware/rspec/cli.rb +16 -0
- data/lib/flatware/rspec/example_notification.rb +21 -0
- data/lib/flatware/rspec/examples_notification.rb +24 -0
- data/lib/flatware/rspec/formatter.rb +50 -0
- data/lib/flatware/rspec/formatters/console.rb +33 -0
- data/lib/flatware/rspec/summary.rb +40 -0
- data/lib/flatware/serialized_exception.rb +12 -8
- data/lib/flatware/sink.rb +43 -33
- data/lib/flatware/socket.rb +89 -25
- data/lib/flatware/version.rb +1 -1
- data/lib/flatware/worker.rb +16 -9
- metadata +27 -55
- data/lib/flatware/checkpoint.rb +0 -28
- data/lib/flatware/checkpoint_handler.rb +0 -45
- data/lib/flatware/dispatcher.rb +0 -31
- data/lib/flatware/fireable.rb +0 -34
- data/lib/flatware/formatters.rb +0 -27
- data/lib/flatware/formatters/cucumber/http.rb +0 -83
- data/lib/flatware/result.rb +0 -25
- data/lib/flatware/scenario_decorator.rb +0 -22
- data/lib/flatware/scenario_result.rb +0 -36
- data/lib/flatware/step_result.rb +0 -27
@@ -1,113 +1,65 @@
|
|
1
|
-
require '
|
2
|
-
require 'flatware/scenario_decorator'
|
1
|
+
require 'cucumber'
|
3
2
|
require 'flatware/sink'
|
4
3
|
require 'ostruct'
|
5
4
|
module Flatware
|
6
5
|
module Cucumber
|
7
6
|
class Formatter
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
@scenarios = []
|
12
|
-
@in_a_step = false
|
13
|
-
end
|
14
|
-
|
15
|
-
def after_features(*)
|
16
|
-
checkpoint = collector.checkpoint
|
17
|
-
scenarios.select(&:exception).map(&:file_colon_line).each do |file_colon_line|
|
18
|
-
scenario = checkpoint.scenarios.detect do |scenario|
|
19
|
-
scenario.file_colon_line == file_colon_line
|
20
|
-
end
|
21
|
-
scenario.failed_outside_step!(file_colon_line) if scenario
|
7
|
+
Checkpoint = Struct.new :steps, :scenarios do
|
8
|
+
def failures?
|
9
|
+
scenarios.any? &:failed?
|
22
10
|
end
|
23
|
-
Sink::client.checkpoint checkpoint
|
24
|
-
end
|
25
|
-
|
26
|
-
def after_step_result(_, _, _, status, *)
|
27
|
-
send_progress(status)
|
28
|
-
end
|
29
|
-
|
30
|
-
def table_cell_value(_, status)
|
31
|
-
send_progress(status) if status
|
32
11
|
end
|
33
12
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
send_progress(status)
|
13
|
+
Scenario = Struct.new :name, :file_colon_line, :status do
|
14
|
+
def failed?
|
15
|
+
status == :failed
|
38
16
|
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def respond_to?(x)
|
42
|
-
super
|
43
|
-
end
|
44
17
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
def after_outline_table(*)
|
50
|
-
@in_examples = false
|
18
|
+
def failed_outside_step?
|
19
|
+
false
|
20
|
+
end
|
51
21
|
end
|
52
22
|
|
53
|
-
def
|
54
|
-
|
23
|
+
def initialize(config)
|
24
|
+
config.on_event :after_test_case, &method(:on_after_test_case)
|
25
|
+
config.on_event :after_test_step, &method(:on_after_test_step)
|
26
|
+
config.on_event :finished_testing, &method(:on_finished_testing)
|
27
|
+
config.on_event :step_match, &method(:on_step_match)
|
28
|
+
reset
|
55
29
|
end
|
56
30
|
|
57
|
-
|
58
|
-
@in_a_step = ! @in_examples
|
59
|
-
end
|
31
|
+
private
|
60
32
|
|
61
|
-
def
|
62
|
-
|
33
|
+
def reset
|
34
|
+
@steps = []
|
35
|
+
@scenarios = []
|
36
|
+
@matched_steps = Set.new
|
63
37
|
end
|
64
38
|
|
65
|
-
|
66
|
-
@in_a_step = true
|
67
|
-
end
|
39
|
+
attr_reader :steps, :scenarios, :matched_steps
|
68
40
|
|
69
|
-
def
|
70
|
-
|
41
|
+
def on_after_test_case(event)
|
42
|
+
scenarios << Scenario.new(event.test_case.name, event.test_case.location.to_s, event.result.to_sym)
|
71
43
|
end
|
72
44
|
|
73
|
-
def
|
74
|
-
|
45
|
+
def on_step_match(event)
|
46
|
+
@matched_steps << event.step_match.location.to_s
|
75
47
|
end
|
76
48
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
49
|
+
def on_after_test_step(event)
|
50
|
+
if really_a_step?(event.test_step) or event.result.undefined?
|
51
|
+
steps << StepResult.new(event.result.to_sym, event.result.failed? && event.result.exception)
|
52
|
+
Sink::client.progress Result.new event.result.to_sym
|
53
|
+
end
|
82
54
|
end
|
83
55
|
|
84
|
-
def
|
85
|
-
Sink::client.
|
56
|
+
def on_finished_testing(*)
|
57
|
+
Sink::client.checkpoint Checkpoint.new steps, scenarios
|
58
|
+
reset
|
86
59
|
end
|
87
60
|
|
88
|
-
|
89
|
-
|
90
|
-
def initialize(step_mother)
|
91
|
-
@step_mother = step_mother
|
92
|
-
snapshot
|
93
|
-
end
|
94
|
-
|
95
|
-
def checkpoint
|
96
|
-
Checkpoint.new(step_mother.steps - @ran_steps, decorate_scenarios(step_mother.scenarios - @ran_scenarios)).tap do
|
97
|
-
snapshot
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
private
|
102
|
-
|
103
|
-
def snapshot
|
104
|
-
@ran_steps = step_mother.steps.dup
|
105
|
-
@ran_scenarios = step_mother.scenarios.dup
|
106
|
-
end
|
107
|
-
|
108
|
-
def decorate_scenarios(scenarios)
|
109
|
-
scenarios.map { |scenario| ScenarioDecorator.new(scenario) }
|
110
|
-
end
|
61
|
+
def really_a_step?(step)
|
62
|
+
matched_steps.include?(step.action_location.to_s)
|
111
63
|
end
|
112
64
|
end
|
113
65
|
end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require 'flatware/formatters/
|
1
|
+
require 'flatware/cucumber/formatters/console/summary'
|
2
2
|
require 'cucumber/formatter/console'
|
3
3
|
|
4
|
-
module Flatware::Formatters
|
4
|
+
module Flatware::Cucumber::Formatters
|
5
5
|
class Console
|
6
6
|
#for format_string
|
7
7
|
include ::Cucumber::Formatter::Console
|
@@ -26,7 +26,9 @@ module Flatware::Formatters::Cucumber
|
|
26
26
|
out.print format result.progress
|
27
27
|
end
|
28
28
|
|
29
|
-
def summarize(
|
29
|
+
def summarize(checkpoints)
|
30
|
+
steps = checkpoints.flat_map(&:steps)
|
31
|
+
scenarios = checkpoints.flat_map(&:scenarios)
|
30
32
|
Summary.new(steps, scenarios, out).summarize
|
31
33
|
end
|
32
34
|
|
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'cucumber/formatter/console'
|
2
|
-
require 'flatware/formatters/
|
3
|
-
require 'flatware/checkpoint'
|
2
|
+
require 'flatware/cucumber/formatters/console'
|
3
|
+
require 'flatware/cucumber/checkpoint'
|
4
4
|
|
5
|
-
module Flatware::Formatters
|
5
|
+
module Flatware::Cucumber::Formatters
|
6
6
|
class Console
|
7
7
|
class Summary
|
8
8
|
include ::Cucumber::Formatter::Console
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Flatware
|
2
|
+
module Cucumber
|
3
|
+
class Result
|
4
|
+
attr_reader :progress, :worker
|
5
|
+
|
6
|
+
def initialize(progress)
|
7
|
+
@progress = progress
|
8
|
+
@worker = ENV['TEST_ENV_NUMBER'].to_i
|
9
|
+
end
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def step(*args)
|
13
|
+
step = StepResult.new *args
|
14
|
+
new step.progress, [step]
|
15
|
+
end
|
16
|
+
|
17
|
+
def status(status)
|
18
|
+
new status
|
19
|
+
end
|
20
|
+
|
21
|
+
def background(status, exception)
|
22
|
+
new '', [StepResult.new(status, exception)]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'flatware/serialized_exception'
|
2
|
+
module Flatware
|
3
|
+
module Cucumber
|
4
|
+
class ScenarioResult
|
5
|
+
attr_reader :status, :file_colon_line, :name
|
6
|
+
def initialize(status, file_colon_line, name, e)
|
7
|
+
@status = status
|
8
|
+
@file_colon_line = file_colon_line
|
9
|
+
@name = name
|
10
|
+
@exception = SerializedException.new(e.class, e.message, e.backtrace) if e
|
11
|
+
@failed_outside_step = false
|
12
|
+
end
|
13
|
+
|
14
|
+
def passed?
|
15
|
+
status == :passed
|
16
|
+
end
|
17
|
+
|
18
|
+
def failed?
|
19
|
+
status == :failed
|
20
|
+
end
|
21
|
+
|
22
|
+
def failed_outside_step!(file_colon_line)
|
23
|
+
@failed_outside_step = file_colon_line
|
24
|
+
end
|
25
|
+
|
26
|
+
def failed_outside_step?
|
27
|
+
!!@failed_outside_step
|
28
|
+
end
|
29
|
+
|
30
|
+
def exception
|
31
|
+
@exception.tap do |e|
|
32
|
+
e.backtrace = e.backtrace.grep(Regexp.new(Dir.pwd)).map { |line| line[Dir.pwd.size..-1] }
|
33
|
+
e.backtrace = e.backtrace + [@failed_outside_step] if failed_outside_step?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'flatware/serialized_exception'
|
2
|
+
module Flatware
|
3
|
+
module Cucumber
|
4
|
+
class StepResult
|
5
|
+
attr_reader :status, :exception
|
6
|
+
|
7
|
+
def initialize(status, exception)
|
8
|
+
@status, @exception = status, (serialized(exception) if exception)
|
9
|
+
end
|
10
|
+
|
11
|
+
def passed?
|
12
|
+
status == :passed
|
13
|
+
end
|
14
|
+
|
15
|
+
def failed?
|
16
|
+
status == :failed
|
17
|
+
end
|
18
|
+
|
19
|
+
def progress
|
20
|
+
Cucumber::ProgressString.format(status)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
def serialized(e)
|
25
|
+
e.backtrace and e.backtrace.unshift e.backtrace.shift.sub(Dir.pwd, '.')
|
26
|
+
SerializedException.new(e.class, e.message, e.backtrace)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/flatware/poller.rb
CHANGED
@@ -21,14 +21,14 @@ module Flatware
|
|
21
21
|
def find_wrapped_socket
|
22
22
|
->(s) do
|
23
23
|
sockets.find do |socket|
|
24
|
-
socket.
|
24
|
+
socket.socket == s
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
29
|
def register_sockets
|
30
30
|
sockets.each do |socket|
|
31
|
-
zmq_poller.register_readable socket.
|
31
|
+
zmq_poller.register_readable socket.socket
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rspec/core'
|
2
|
+
require 'rspec/expectations'
|
3
|
+
require 'flatware/rspec/cli'
|
4
|
+
|
5
|
+
module Flatware
|
6
|
+
module RSpec
|
7
|
+
require 'flatware/rspec/formatters/console'
|
8
|
+
require 'flatware/rspec/formatter'
|
9
|
+
|
10
|
+
def self.extract_jobs_from_args(args, workers:)
|
11
|
+
|
12
|
+
options = ::RSpec::Core::ConfigurationOptions.new(args)
|
13
|
+
configuration = ::RSpec::Core::Configuration.new
|
14
|
+
def configuration.command() 'rspec' end
|
15
|
+
options.configure(configuration)
|
16
|
+
configuration.files_to_run.uniq.map do |file|
|
17
|
+
Job.new(file, args)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.run(job, options={})
|
22
|
+
runner = ::RSpec::Core::Runner
|
23
|
+
def runner.trap_interrupt() end
|
24
|
+
|
25
|
+
runner.run(%w[--format Flatware::RSpec::Formatter] + Array(job), $stderr, $stdout)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'flatware/rspec/examples_notification'
|
2
|
+
|
3
|
+
module Flatware
|
4
|
+
module RSpec
|
5
|
+
class Checkpoint
|
6
|
+
attr_reader :summary, :failures_notification
|
7
|
+
|
8
|
+
def initialize(summary, failures_notification)
|
9
|
+
@summary, @failures_notification = summary, ExamplesNotification.new(failures_notification.failure_notifications)
|
10
|
+
end
|
11
|
+
|
12
|
+
def +(other)
|
13
|
+
self.class.new summary + other.summary, failures_notification + other.failures_notification
|
14
|
+
end
|
15
|
+
|
16
|
+
def failures?
|
17
|
+
summary.failure_count > 0
|
18
|
+
end
|
19
|
+
|
20
|
+
def failure_notifications
|
21
|
+
failures_notification.failure_notifications
|
22
|
+
end
|
23
|
+
|
24
|
+
def fully_formatted_failed_examples(*args)
|
25
|
+
failures_notification.fully_formatted_failed_examples(*args)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'flatware/cli'
|
2
|
+
|
3
|
+
module Flatware
|
4
|
+
class CLI
|
5
|
+
worker_option
|
6
|
+
method_option 'dispatch-endpoint', type: :string, default: 'ipc://dispatch'
|
7
|
+
method_option 'sink-endpoint', type: :string, default: 'ipc://task'
|
8
|
+
desc "rspec [FLATWARE_OPTS]", "parallelizes rspec"
|
9
|
+
def rspec(*rspec_args)
|
10
|
+
jobs = RSpec.extract_jobs_from_args rspec_args, workers: workers
|
11
|
+
Flatware.verbose = options[:log]
|
12
|
+
Worker.spawn count: workers, runner: RSpec, dispatch: options['dispatch-endpoint'], sink: options['sink-endpoint']
|
13
|
+
start_sink jobs: jobs, workers: workers, formatter: Flatware::RSpec::Formatters::Console.new($stdout, $stderr)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rspec/core/formatters/console_codes'
|
2
|
+
|
3
|
+
module Flatware
|
4
|
+
module RSpec
|
5
|
+
class ExampleNotification
|
6
|
+
attr_reader :formatted
|
7
|
+
def initialize(notification)
|
8
|
+
@formatted = notification.fully_formatted '!', default_colorizer
|
9
|
+
end
|
10
|
+
|
11
|
+
def fully_formatted(i, _=nil)
|
12
|
+
formatted.sub '!', i.to_s
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
def default_colorizer
|
17
|
+
::RSpec::Core::Formatters::ConsoleCodes
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'flatware/rspec/example_notification'
|
2
|
+
module Flatware
|
3
|
+
module RSpec
|
4
|
+
class ExamplesNotification
|
5
|
+
attr_reader :failure_notifications
|
6
|
+
|
7
|
+
def initialize(failure_notifications)
|
8
|
+
@failure_notifications = failure_notifications.map(&ExampleNotification.method(:new))
|
9
|
+
end
|
10
|
+
|
11
|
+
def +(other)
|
12
|
+
self.class.new failure_notifications + other.failure_notifications
|
13
|
+
end
|
14
|
+
|
15
|
+
def fully_formatted_failed_examples(*)
|
16
|
+
formatted = "\n\nFailures:\n"
|
17
|
+
failure_notifications.each_with_index do |failure, index|
|
18
|
+
formatted << failure.fully_formatted(index.next)
|
19
|
+
end
|
20
|
+
formatted
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'flatware/rspec/checkpoint'
|
2
|
+
require 'flatware/rspec/summary'
|
3
|
+
require 'rspec/core/formatters/console_codes'
|
4
|
+
|
5
|
+
module Flatware
|
6
|
+
module RSpec
|
7
|
+
ProgressMessage = Struct.new(:progress)
|
8
|
+
|
9
|
+
class Formatter
|
10
|
+
attr_reader :summary, :output
|
11
|
+
|
12
|
+
def initialize(stdout)
|
13
|
+
@output = stdout
|
14
|
+
end
|
15
|
+
|
16
|
+
def example_passed(example)
|
17
|
+
send_progress :passed
|
18
|
+
end
|
19
|
+
|
20
|
+
def example_failed(example)
|
21
|
+
send_progress :failed
|
22
|
+
end
|
23
|
+
|
24
|
+
def example_pending(example)
|
25
|
+
send_progress :pending
|
26
|
+
end
|
27
|
+
|
28
|
+
def dump_summary(summary)
|
29
|
+
@summary = Summary.from_notification(summary)
|
30
|
+
end
|
31
|
+
|
32
|
+
def dump_failures(failure_notification)
|
33
|
+
@failure_notification = failure_notification
|
34
|
+
end
|
35
|
+
|
36
|
+
def close(*)
|
37
|
+
Sink::client.checkpoint Checkpoint.new(summary, @failure_notification)
|
38
|
+
@failure_notification = nil
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def send_progress(status)
|
44
|
+
Sink::client.progress ProgressMessage.new status
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
::RSpec::Core::Formatters.register Formatter, :example_passed, :example_failed, :example_pending, :dump_summary, :dump_failures, :close
|
49
|
+
end
|
50
|
+
end
|