Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fuubar as formatting option #101

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions flatware-rspec.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Gem::Specification.new do |s|
s.required_ruby_version = ['>= 2.6', '< 3.5']
s.require_paths = ['lib']
s.add_dependency %(flatware), Flatware::VERSION
s.add_dependency %(fuubar), '>= 2.5'
s.add_dependency %(rspec), '>= 3.6'
# s.metadata['rubygems_mfa_required'] = 'true'
end
1 change: 1 addition & 0 deletions lib/flatware/broadcaster.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class Broadcaster
started
summarize
summarize_remaining
worker_ready
].freeze

attr_reader :formatters
Expand Down
8 changes: 8 additions & 0 deletions lib/flatware/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ def self.worker_option
desc: 'Print debug messages to $stderr'
)

class_option(
:formatter,
aliases: '-f',
type: :string,
desc: 'Formatter to use',
default: :console
)

worker_option
desc 'fan [COMMAND]', 'executes the given job on all of the workers'
def fan(*command)
Expand Down
19 changes: 14 additions & 5 deletions lib/flatware/rspec/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require 'flatware/cli'
require 'flatware/rspec'
require 'flatware/rspec/formatters/console'
require 'flatware/rspec/formatters/fuubar'

module Flatware
# rspec thor command
Expand All @@ -17,14 +18,22 @@ class CLI
def rspec(*rspec_args)
jobs = RSpec.extract_jobs_from_args rspec_args, workers: workers

formatter = Flatware::RSpec::Formatters::Console.new(
::RSpec.configuration.output_stream,
deprecation_stream: ::RSpec.configuration.deprecation_stream
)

Flatware.verbose = options[:log]
Worker.spawn count: workers, runner: RSpec, sink: options['sink-endpoint']
start_sink(jobs: jobs, workers: workers, formatter: formatter)
end

private

def formatter
@formatter ||= begin
formatter_klass = Flatware::RSpec::Formatters.const_get(options[:formatter].capitalize)

formatter_klass.new(
::RSpec.configuration.output_stream,
deprecation_stream: ::RSpec.configuration.deprecation_stream
)
end
end
end
end
27 changes: 17 additions & 10 deletions lib/flatware/rspec/formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

module Flatware
module RSpec
ProgressMessage = Struct.new(:progress)

class Formatter
extend Forwardable

Expand All @@ -17,16 +15,20 @@ def initialize(stdout)
@output = stdout
end

def example_passed(_example)
send_progress :passed
def start(notification)
Sink.client.worker_ready notification
end

def example_passed(notification)
send_progress marshaled_progress_notification(notification)
end

def example_failed(_example)
send_progress :failed
def example_failed(notification)
send_progress marshaled_progress_notification(notification)
end

def example_pending(_example)
send_progress :pending
def example_pending(notification)
send_progress marshaled_progress_notification(notification)
end

def message(message)
Expand All @@ -40,20 +42,25 @@ def close(*)

private

def send_progress(status)
Sink.client.progress ProgressMessage.new status
def send_progress(notification)
Sink.client.progress notification
end

def checkpoint
@checkpoint ||= Checkpoint.new
end

def marshaled_progress_notification(notification)
Flatware::RSpec::Marshalable::ExampleNotification.from_rspec(notification)
end

::RSpec::Core::Formatters.register(
self,
*Checkpoint::EVENTS,
:example_passed,
:example_failed,
:example_pending,
:start,
:message,
:close
)
Expand Down
6 changes: 3 additions & 3 deletions lib/flatware/rspec/formatters/console.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def initialize(out, deprecation_stream: StringIO.new)
end

def progress(result)
progress_formatter.public_send(message_for(result), nil)
progress_formatter.public_send(message_for(result), result)
end

def message(message)
Expand Down Expand Up @@ -75,12 +75,12 @@ def colorizer
::RSpec::Core::Formatters::ConsoleCodes
end

def message_for(result)
def message_for(notification)
{
passed: :example_passed,
failed: :example_failed,
pending: :example_pending
}.fetch result.progress
}.fetch notification.example.execution_result.status
end
end
end
Expand Down
96 changes: 96 additions & 0 deletions lib/flatware/rspec/formatters/fuubar.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
require 'fuubar'

module Flatware
module RSpec
module Formatters
class Fuubar
attr_reader :progress_formatter, :out, :deprecation_stream

def initialize(out, deprecation_stream: StringIO.new)
@out = out
@deprecation_stream = deprecation_stream
::RSpec.configuration.backtrace_exclusion_patterns += [%r{/lib/flatware/worker}, %r{/lib/flatware/rspec}]
@progress_formatter = ::Fuubar.new(out)
end

def worker_ready(notification)
if progress_formatter.progress.total.positive?
progress_formatter.progress.total += notification.count
else
progress_formatter.start(notification)
end
end

def progress(result)
progress_formatter.public_send(message_for(result), result)
end

def message(message)
out.puts(message.message)
end

def summarize(checkpoints)
return if checkpoints.empty?

result = checkpoints.reduce :+

progress_formatter.dump_pending(result) if result.pending_examples.any?
progress_formatter.dump_failures(result)
dump_deprecations(result.deprecations)
dump_profile(result.profile) if result.profile
progress_formatter.dump_summary(result.summary)
end

def summarize_remaining(remaining)
out.puts(colorizer.wrap(<<~MESSAGE, :detail))

The following specs weren't run:

#{spec_list(remaining)}

MESSAGE
end

private

def dump_deprecations(deprecations)
formatter = ::RSpec::Core::Formatters::DeprecationFormatter.new(
deprecation_stream,
out
)

deprecations.each(&formatter.method(:deprecation))
formatter.deprecation_summary(nil)
end

def dump_profile(profile)
::RSpec::Core::Formatters::ProfileFormatter.new(out).dump_profile(profile)
end

def spec_list(remaining)
remaining
.flat_map(&:id).sort.each_with_index
.map do |example, index|
format(
'%<index>4d) %<example>s',
index: index.next,
example: example
)
end.join("\n")
end

def colorizer
::RSpec::Core::Formatters::ConsoleCodes
end

def message_for(notification)
{
passed: :example_passed,
failed: :example_failed,
pending: :example_pending
}.fetch notification.example.execution_result.status
end
end
end
end
end
1 change: 1 addition & 0 deletions lib/flatware/rspec/marshalable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module RSpec
module Marshalable
require 'flatware/rspec/marshalable/deprecation_notification'
require 'flatware/rspec/marshalable/examples_notification'
require 'flatware/rspec/marshalable/example_notification'
require 'flatware/rspec/marshalable/profile_notification'
require 'flatware/rspec/marshalable/summary_notification'

Expand Down
21 changes: 21 additions & 0 deletions lib/flatware/rspec/marshalable/example_notification.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
require 'rspec/core'
require 'flatware/rspec/marshalable/example'

module Flatware
module RSpec
module Marshalable
class ExampleNotification < ::RSpec::Core::Notifications::ExampleNotification
def self.from_rspec(rspec_notification)
new(Example.new(rspec_notification.example))
end

def fully_formatted(failure_number, colorizer = ::RSpec::Core::Formatters::ConsoleCodes)
return if example.execution_result.status != :failed

@exception_presenter ||= ::RSpec::Core::Formatters::ExceptionPresenter::Factory.new(example).build
@exception_presenter.fully_formatted(failure_number, colorizer)
end
end
end
end
end
18 changes: 15 additions & 3 deletions spec/flatware/rspec/formatter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,25 @@
context 'when example_passed' do
it "sends a 'passed' progress message to the sink client" do
formatter = described_class.new StringIO.new
example = double 'Example'
example = double 'Example', full_description: 'example description',
location: 'here',
location_rerun_argument: 'here[1]',
metadata: {},
execution_result: double(
'Execution result',
status: :passed,
exception: nil,
finished_at: Time.now,
run_time: 0.1,
started_at: Time.now - 0.1
)
notification = double 'Notification', example: example
client = double 'Client', progress: true
Flatware::Sink.client = client
formatter.example_passed example
formatter.example_passed notification

expect(client).to have_received(:progress).with anything do |message|
expect(message.progress).to eq :passed
expect(message.example.execution_result.status).to eq :passed
true
end
end
Expand Down
Loading