Skip to content

Commit

Permalink
feat: support pending pacts in json formatter
Browse files Browse the repository at this point in the history
  • Loading branch information
bethesque committed Jan 20, 2020
1 parent e8d4a55 commit 2c0d20d
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/pact/provider/pact_spec_runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

require_relative 'rspec'

require 'pact/provider/rspec/json_formatter'

module Pact
module Provider
Expand Down
86 changes: 86 additions & 0 deletions lib/pact/provider/rspec/json_formatter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
require 'rspec/core/formatters/json_formatter'

module Pact
module Provider
module RSpec
class JsonFormatter < ::RSpec::Core::Formatters::JsonFormatter
::RSpec::Core::Formatters.register self, :message, :dump_summary, :dump_profile, :stop, :seed, :close

def dump_summary(summary)
super(create_custom_summary(summary))
output_hash[:summary][:notices] = pact_broker_notices(summary)
end

def format_example(example)
{
:id => example.id,
:description => example.description,
:full_description => example.full_description,
:status => calculate_status(example),
:file_path => example.metadata[:file_path],
:line_number => example.metadata[:line_number],
:run_time => example.execution_result.run_time,
:mismatches => extract_differences(example)
}
end

def stop(notification)
output_hash[:examples] = notification.examples.map do |example|
format_example(example).tap do |hash|
e = example.exception
# No point providing a backtrace for a mismatch, too much noise
if e && ! e.is_a?(::RSpec::Expectations::ExpectationNotMetError)
hash[:exception] = {
:class => e.class.name,
:message => e.message,
:backtrace => e.backtrace,
}
end
end
end
end

def calculate_status(example)
if example.execution_result.status == :failed && example.metadata[:pact_ignore_failures]
'pending'
else
example.execution_result.status.to_s
end
end

# There will most likely be only one pact associated with this RSpec execution, because
# the most likely user of this formatter is the Go implementation that parses the JSON
# and builds Go tests from them.
# If the JSON formatter is used by someone else and they have multiple pacts, all the notices
# for the pacts will be mushed together in one collection, so it will be hard to know which notice
# belongs to which pact.
def pact_broker_notices(summary)
pact_uris(summary).collect{ |pact_uri| pact_uri.metadata[:notices] }.compact.flatten
end

def pact_uris(summary)
summary.examples.collect(&:metadata).collect{ |metadata| metadata[:pact_uri] }.uniq
end

def create_custom_summary(summary)
::RSpec::Core::Notifications::SummaryNotification.new(
summary.duration,
summary.examples,
summary.examples.select{ | example | example.execution_result.status == :failed && !example.metadata[:pact_ignore_failures] },
summary.examples.select{ | example | example.execution_result.status == :failed && example.metadata[:pact_ignore_failures] },
summary.load_time,
summary.errors_outside_of_examples_count
)
end

def extract_differences(example)
if example.metadata[:pact_diff]
Pact::Matchers::ExtractDiffMessages.call(example.metadata[:pact_diff]).to_a
else
[]
end
end
end
end
end
end

0 comments on commit 2c0d20d

Please sign in to comment.