Skip to content

Commit

Permalink
Add fuubar as formatting option
Browse files Browse the repository at this point in the history
  • Loading branch information
tomasdundacek committed Oct 16, 2024
1 parent 4ba7b77 commit 462ad7b
Show file tree
Hide file tree
Showing 9 changed files with 155 additions and 14 deletions.
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.4']
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
4 changes: 3 additions & 1 deletion 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,7 +18,8 @@ class CLI
def rspec(*rspec_args)
jobs = RSpec.extract_jobs_from_args rspec_args, workers: workers

formatter = Flatware::RSpec::Formatters::Console.new(
formatter_klass = "Flatware::RSpec::Formatters::#{options[:formatter].capitalize}".constantize
formatter = formatter_klass.new(
::RSpec.configuration.output_stream,
deprecation_stream: ::RSpec.configuration.deprecation_stream
)
Expand Down
31 changes: 21 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,29 @@ 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

def marshaled_start_notification(notification)
Flatware::RSpec::Marshalable::StartNotification.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 > 0
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

0 comments on commit 462ad7b

Please sign in to comment.