pact 1.19.1 → 1.19.2

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
  SHA1:
3
- metadata.gz: 91a3bec55f1ec0ebd0ce051fc4b52613b8143bf2
4
- data.tar.gz: 978814b2a193198db83d41d68b5c55315ae839b5
3
+ metadata.gz: 5600e03dfa36e82f5046524a577d8d0b3fbfb65c
4
+ data.tar.gz: 806e61b3debf79d48dbdf7d6782f842b51d4e878
5
5
  SHA512:
6
- metadata.gz: a546703241a9770b086de20318f1eaa8d2223fc56800a446dcb6fd4466da28051778d08efc3c2ef0721064d1da4d22ef0bd953d96b51e813bb894ae96b2ba8b5
7
- data.tar.gz: 39237141c5ac6febcf2c4209a4d5d9a1bd610689e394d247d8ddccff67b05954d7ae36e1a324c32e2eb69cad93d4f0ec546e3305c408db70599f9e2547faabd5
6
+ metadata.gz: 716c814749febf3a308cf0fd4ceef616483f1ddc44cb5bd4e06d8abe6a8b2ea2c76046c87dd5db1f34e1c469cd71aeffa1a69aa9c1bfb245b7de726117f6b877
7
+ data.tar.gz: 71b3a60fab8ce4def9d6718ca78f806215c28e83b47ebdef2c8c4436536339d577e0b1ac754d3c2d274e1b135308acbfdad42bbe2cc1a8dba2f5b9e3cba17ffa
data/CHANGELOG.md CHANGED
@@ -1,3 +1,23 @@
1
+ <a name="v1.19.2"></a>
2
+ ### v1.19.2 (2017-11-16)
3
+
4
+
5
+ #### Features
6
+
7
+ * **publish test results**
8
+ * rename example to test in JSON ([cd2b79e](/../../commit/cd2b79e))
9
+ * remove ansi colours from error messages ([4416d04](/../../commit/4416d04))
10
+ * only publish for rspec 3 ([31192d0](/../../commit/31192d0))
11
+ * only publish verification results when all interactions have been run ([0c56752](/../../commit/0c56752))
12
+ * enable test results to be published to the pact broker in the verification results ([e0dad27](/../../commit/e0dad27))
13
+
14
+
15
+ #### Bug Fixes
16
+
17
+ * **verifications**
18
+ * tag provider version, not consumer version ([b347588](/../../commit/b347588))
19
+
20
+
1
21
  <a name="v1.19.1"></a>
2
22
  ### v1.19.1 (2017-10-31)
3
23
 
@@ -8,6 +8,7 @@ require 'pact/rspec'
8
8
  require 'pact/provider/pact_source'
9
9
  require 'pact/provider/help/write'
10
10
  require 'pact/provider/verification_results/publish_all'
11
+ require 'pact/provider/rspec/pact_broker_formatter'
11
12
 
12
13
  require_relative 'rspec'
13
14
 
@@ -61,6 +62,10 @@ module Pact
61
62
  config.output_stream = Pact.configuration.output_stream
62
63
  end
63
64
 
65
+ Pact::RSpec.with_rspec_3 do
66
+ ::RSpec.configuration.add_formatter Pact::Provider::RSpec::PactBrokerFormatter, StringIO.new
67
+ end
68
+
64
69
  if options[:format]
65
70
  ::RSpec.configuration.add_formatter options[:format]
66
71
  # Don't want to mess up the JSON parsing with messages to stdout, so send it to stderr
@@ -82,14 +87,12 @@ module Pact
82
87
  Pact.configuration.provider.app
83
88
  end
84
89
 
90
+ # For the Pact::Provider::RSpec::PactBrokerFormatter
91
+ Pact.provider_world.pact_sources = pact_sources
85
92
  jsons = pact_jsons
86
- sources = pact_sources
87
93
 
88
94
  config.after(:suite) do | suite |
89
95
  Pact::Provider::Help::Write.call(jsons)
90
- Pact::RSpec.with_rspec_3 do
91
- Pact::Provider::VerificationResults::PublishAll.call(sources, ::RSpec.configuration.reporter.failed_examples)
92
- end
93
96
  end
94
97
 
95
98
  end
@@ -25,7 +25,7 @@ module Pact
25
25
  Pact.configuration.output_stream.puts "INFO: Filtering interactions by: #{options[:criteria]}" if options[:criteria] && options[:criteria].any?
26
26
  consumer_contract = Pact::ConsumerContract.from_json(pact_json)
27
27
  ::RSpec.describe "Verifying a pact between #{consumer_contract.consumer.name} and #{consumer_contract.provider.name}", pactfile_uri: pact_uri do
28
- honour_consumer_contract consumer_contract, options.merge(pact_json: pact_json)
28
+ honour_consumer_contract consumer_contract, options.merge(pact_json: pact_json, pact_uri: pact_uri)
29
29
  end
30
30
  end
31
31
 
@@ -61,19 +61,24 @@ module Pact
61
61
 
62
62
  def describe_interaction interaction, options
63
63
 
64
+ # pact_uri and pact_interaction are used by
65
+ # Pact::Provider::RSpec::PactBrokerFormatter
66
+
67
+ # pact_interaction_example_description is used by
68
+ # Pact::Provider::RSpec::Formatter and Pact::Provider::RSpec::Formatter2
69
+
70
+ # pact: verify is used to allow RSpec before and after hooks.
64
71
  metadata = {
65
72
  pact: :verify,
66
73
  pact_interaction: interaction,
67
74
  pact_interaction_example_description: interaction_description_for_rerun_command(interaction),
68
- pact_json: options[:pact_json]
75
+ pact_uri: options[:pact_uri]
69
76
  }
70
77
 
71
78
  describe description_for(interaction), metadata do
72
79
 
73
-
74
80
  describe "with #{interaction.request.method_and_path}" do
75
81
 
76
-
77
82
  interaction_context = InteractionContext.new
78
83
 
79
84
  before do | example |
@@ -0,0 +1,67 @@
1
+ require 'rspec/core/formatters'
2
+ require 'pact/provider/verification_results/publish_all'
3
+ require 'term/ansicolor'
4
+
5
+ module Pact
6
+ module Provider
7
+ module RSpec
8
+ class PactBrokerFormatter < ::RSpec::Core::Formatters::BaseFormatter
9
+ Pact::RSpec.with_rspec_3 do
10
+ ::RSpec::Core::Formatters.register self, :message, :dump_summary, :stop, :seed, :close
11
+ end
12
+
13
+ attr_reader :output_hash
14
+
15
+ def initialize(output)
16
+ super
17
+ @output_hash = {
18
+ :version => ::RSpec::Core::Version::STRING
19
+ }
20
+ end
21
+
22
+ def message(notification)
23
+ (@output_hash[:messages] ||= []) << notification.message
24
+ end
25
+
26
+ def dump_summary(summary)
27
+ end
28
+
29
+ def stop(notification)
30
+ @output_hash[:tests] = notification
31
+ .examples
32
+ .map { |example| format_example(example) }
33
+ end
34
+
35
+ def seed(notification)
36
+ return unless notification.seed_used?
37
+ @output_hash[:seed] = notification.seed
38
+ end
39
+
40
+ def close(_notification)
41
+ Pact::Provider::VerificationResults::PublishAll.call(Pact.provider_world.pact_sources, output_hash)
42
+ end
43
+
44
+ private
45
+
46
+ def format_example(example)
47
+ {
48
+ testDescription: example.description,
49
+ testFullDescription: example.full_description,
50
+ status: example.execution_result.status.to_s,
51
+ interactionProviderState: example.metadata[:pact_interaction].provider_state,
52
+ interactionDescription: example.metadata[:pact_interaction].description,
53
+ pact_uri: example.metadata[:pact_uri],
54
+ pact_interaction: example.metadata[:pact_interaction]
55
+ }.tap do |hash|
56
+ if example.exception
57
+ hash[:exception] = {
58
+ class: example.exception.class.name,
59
+ message: ::Term::ANSIColor.uncolor(example.exception.message)
60
+ }
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -4,38 +4,67 @@ module Pact
4
4
  module VerificationResults
5
5
  class Create
6
6
 
7
- def self.call pact_json, failed_examples
8
- new(pact_json, failed_examples).call
7
+ def self.call pact_source, test_results_hash
8
+ new(pact_source, test_results_hash).call
9
9
  end
10
10
 
11
- def initialize pact_json, failed_examples
12
- @pact_json = pact_json
13
- @failed_examples = failed_examples
11
+ def initialize pact_source, test_results_hash
12
+ @pact_source = pact_source
13
+ @test_results_hash = test_results_hash
14
14
  end
15
15
 
16
16
  def call
17
- VerificationResult.new(!any_failures?, Pact.configuration.provider.application_version)
17
+ VerificationResult.new(publishable?, !any_failures?, Pact.configuration.provider.application_version, test_results_hash_for_pact_uri)
18
18
  end
19
19
 
20
20
  private
21
21
 
22
- def pact_hash
23
- @pact_hash ||= json_load(pact_json)
22
+ def pact_uri
23
+ @pact_uri ||= pact_source.uri
24
24
  end
25
25
 
26
- def json_load json
27
- JSON.load(json, nil, { max_nesting: 50 })
26
+ def any_failures?
27
+ count_failures_for_pact_uri > 0
28
28
  end
29
29
 
30
- def count_failures_for_pact_json
31
- failed_examples.collect{ |e| e.metadata[:pact_json] == pact_json }.uniq.size
30
+ def publishable?
31
+ executed_interactions_count == all_interactions_count && all_interactions_count > 0
32
32
  end
33
33
 
34
- def any_failures?
35
- count_failures_for_pact_json > 0
34
+ def examples_for_pact_uri
35
+ @examples_for_pact_uri ||= test_results_hash[:tests].select{ |e| e[:pact_uri] == pact_uri }
36
+ end
37
+
38
+ def count_failures_for_pact_uri
39
+ examples_for_pact_uri.count{ |e| e[:status] != 'passed' }
40
+ end
41
+
42
+ def executed_interactions_count
43
+ examples_for_pact_uri
44
+ .collect { |e| e[:pact_interaction].object_id }
45
+ .uniq
46
+ .count
47
+ end
48
+
49
+ def all_interactions_count
50
+ pact_source.pact_hash['interactions'].count
51
+ end
52
+
53
+ def test_results_hash_for_pact_uri
54
+ {
55
+ tests: examples_for_pact_uri.collect{ |e| clean_example(e) },
56
+ summary: {
57
+ testCount: examples_for_pact_uri.size,
58
+ failureCount: count_failures_for_pact_uri
59
+ }
60
+ }
61
+ end
62
+
63
+ def clean_example(example)
64
+ example.reject{ |k, v| k == :pact_uri || k == :pact_interaction }
36
65
  end
37
66
 
38
- attr_reader :pact_json, :failed_examples
67
+ attr_reader :pact_source, :test_results_hash
39
68
  end
40
69
  end
41
70
  end
@@ -22,32 +22,50 @@ module Pact
22
22
  end
23
23
 
24
24
  def call
25
- if Pact.configuration.provider.publish_verification_results?
26
- if Pact.configuration.provider.tags.any?
27
- if tag_url('')
28
- tag_versions
29
- else
30
- Pact.configuration.error_stream.puts "WARN: Cannot tag provider version as there is no link named pb:tag-version in the pact JSON."
31
- end
32
- end
33
-
34
- if publication_url
35
- publish
36
- else
37
- Pact.configuration.error_stream.puts "WARN: Cannot publish verification for #{consumer_name} as there is no link named pb:publish-verification-results in the pact JSON. If you are using a pact broker, please upgrade to version 2.0.0 or later."
38
- end
25
+ if can_publish_verification_results?
26
+ tag_versions_if_configured
27
+ publish_verification_results
39
28
  end
40
29
  end
41
30
 
42
31
  private
43
32
 
33
+ def can_publish_verification_results?
34
+ return false unless Pact.configuration.provider.publish_verification_results?
35
+
36
+ if publication_url.nil?
37
+ Pact.configuration.error_stream.puts "WARN: Cannot publish verification for #{consumer_name} as there is no link named pb:publish-verification-results in the pact JSON. If you are using a pact broker, please upgrade to version 2.0.0 or later."
38
+ return false
39
+ end
40
+
41
+ if !verification_result.publishable?
42
+ Pact.configuration.error_stream.puts "WARN: Cannot publish verification for #{consumer_name} as not all interactions have been verified. Re-run the verification without the filter parameters or environment variables to publish the verification."
43
+ return false
44
+ end
45
+ true
46
+ end
47
+
44
48
  def publication_url
45
49
  @publication_url ||= pact_source.pact_hash.fetch('_links', {}).fetch('pb:publish-verification-results', {})['href']
46
50
  end
47
51
 
48
52
  def tag_url tag
49
- href = pact_source.pact_hash.fetch('_links', {}).fetch('pb:tag-version', {})['href']
50
- href ? href.gsub('{tag}', tag) : nil
53
+ # This is so dodgey, need to use proper HAL
54
+ if publication_url
55
+ u = URI(publication_url)
56
+ if match = publication_url.match(%r{/provider/([^/]+)})
57
+ provider_name = match[1]
58
+ base_url = "#{u.scheme}://#{u.host}:#{u.host == u.default_port ? '' : u.port}"
59
+ provider_application_version = Pact.configuration.provider.application_version
60
+ "#{base_url}/pacticipants/#{provider_name}/versions/#{provider_application_version}/tags/#{tag}"
61
+ end
62
+ end
63
+ end
64
+
65
+ def tag_versions_if_configured
66
+ if Pact.configuration.provider.tags.any?
67
+ tag_versions if tag_url('')
68
+ end
51
69
  end
52
70
 
53
71
  def tag_versions
@@ -71,9 +89,9 @@ module Pact
71
89
  end
72
90
  end
73
91
 
74
- def publish
92
+ def publish_verification_results
75
93
  uri = URI(publication_url)
76
- request = build_request('Post', uri, verification_result.to_json, "Publishing verification result #{verification_result.to_json} to")
94
+ request = build_request('Post', uri, verification_result.to_json, "Publishing verification result #{verification_result} to")
77
95
  response = nil
78
96
  begin
79
97
  options = {:use_ssl => uri.scheme == 'https'}
@@ -81,12 +99,17 @@ module Pact
81
99
  http.request request
82
100
  end
83
101
  rescue StandardError => e
84
- error_message = "Failed to publish verification result due to: #{e.class} #{e.message}"
102
+ error_message = "Failed to publish verification results due to: #{e.class} #{e.message}"
85
103
  raise PublicationError.new(error_message)
86
104
  end
87
105
 
88
- unless response.code.start_with?("2")
89
- raise PublicationError.new("Error returned from verification result publication #{response.code} #{response.body}")
106
+
107
+
108
+ if response.code.start_with?("2")
109
+ new_resource_url = JSON.parse(response.body)['_links']['self']['href']
110
+ $stdout.puts "INFO: Verification results published to #{new_resource_url}"
111
+ else
112
+ raise PublicationError.new("Error returned from verification results publication #{response.code} #{response.body}")
90
113
  end
91
114
  end
92
115
 
@@ -6,19 +6,18 @@ module Pact
6
6
  module VerificationResults
7
7
  class PublishAll
8
8
 
9
- def self.call pact_sources, rspec_summary
10
- new(pact_sources, rspec_summary).call
9
+ def self.call pact_sources, test_results_hash
10
+ new(pact_sources, test_results_hash).call
11
11
  end
12
12
 
13
- def initialize pact_sources, rspec_summary
13
+ def initialize pact_sources, test_results_hash
14
14
  @pact_sources = pact_sources
15
- @rspec_summary = rspec_summary
15
+ @test_results_hash = test_results_hash
16
16
  end
17
17
 
18
- # TODO do not publish unless all interactions have been run
19
18
  def call
20
- verification_results.collect do | pair |
21
- Publish.call(pair.first, pair.last)
19
+ verification_results.collect do | (pact_source, verification_result) |
20
+ Publish.call(pact_source, verification_result)
22
21
  end
23
22
  end
24
23
 
@@ -26,11 +25,11 @@ module Pact
26
25
 
27
26
  def verification_results
28
27
  pact_sources.collect do | pact_source |
29
- [pact_source, Create.call(pact_source.pact_json, rspec_summary)]
28
+ [pact_source, Create.call(pact_source, test_results_hash)]
30
29
  end
31
30
  end
32
31
 
33
- attr_reader :pact_sources, :rspec_summary
32
+ attr_reader :pact_sources, :test_results_hash
34
33
  end
35
34
  end
36
35
  end
@@ -1,11 +1,19 @@
1
+ require 'json'
2
+
1
3
  module Pact
2
4
  module Provider
3
5
  module VerificationResults
4
6
  class VerificationResult
5
7
 
6
- def initialize success, provider_application_version
8
+ def initialize publishable, success, provider_application_version, test_results_hash
9
+ @publishable = publishable
7
10
  @success = success
8
11
  @provider_application_version = provider_application_version
12
+ @test_results_hash = test_results_hash
13
+ end
14
+
15
+ def publishable?
16
+ @publishable
9
17
  end
10
18
 
11
19
  def provider_application_version_set?
@@ -15,13 +23,18 @@ module Pact
15
23
  def to_json
16
24
  {
17
25
  success: success,
18
- providerApplicationVersion: provider_application_version
26
+ providerApplicationVersion: provider_application_version,
27
+ #testResults: test_results_hash # not yet
19
28
  }.to_json
20
29
  end
21
30
 
31
+ def to_s
32
+ "[success: #{success}, providerApplicationVersion: #{provider_application_version}]"
33
+ end
34
+
22
35
  private
23
36
 
24
- attr_reader :success, :provider_application_version
37
+ attr_reader :success, :provider_application_version, :test_results_hash
25
38
  end
26
39
  end
27
40
  end
@@ -14,6 +14,8 @@ module Pact
14
14
  module Provider
15
15
  class World
16
16
 
17
+ attr_accessor :pact_sources
18
+
17
19
  def provider_states
18
20
  @provider_states_proxy ||= Pact::Provider::State::ProviderStateProxy.new
19
21
  end
@@ -29,7 +31,6 @@ module Pact
29
31
  def pact_urls
30
32
  pact_verifications.collect(&:uri)
31
33
  end
32
-
33
34
  end
34
35
  end
35
36
  end
data/lib/pact/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  # Remember to bump pact-provider-proxy when this changes major version
2
2
  module Pact
3
- VERSION = "1.19.1"
3
+ VERSION = "1.19.2"
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pact
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.19.1
4
+ version: 1.19.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Fraser
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2017-10-31 00:00:00.000000000 Z
15
+ date: 2017-11-16 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: randexp
@@ -366,6 +366,7 @@ files:
366
366
  - lib/pact/provider/rspec/formatter_rspec_2.rb
367
367
  - lib/pact/provider/rspec/formatter_rspec_3.rb
368
368
  - lib/pact/provider/rspec/matchers.rb
369
+ - lib/pact/provider/rspec/pact_broker_formatter.rb
369
370
  - lib/pact/provider/state/provider_state.rb
370
371
  - lib/pact/provider/state/provider_state_configured_modules.rb
371
372
  - lib/pact/provider/state/provider_state_manager.rb