pact 1.46.1 → 1.53.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/CHANGELOG.md +105 -0
- data/lib/pact/cli/run_pact_verification.rb +3 -1
- data/lib/pact/cli/spec_criteria.rb +3 -0
- data/lib/pact/cli.rb +5 -0
- data/lib/pact/consumer/consumer_contract_builder.rb +4 -0
- data/lib/pact/consumer/interaction_builder.rb +6 -0
- data/lib/pact/hal/http_client.rb +2 -0
- data/lib/pact/pact_broker/fetch_pact_uris_for_verification.rb +9 -15
- data/lib/pact/pact_broker/notices.rb +34 -0
- data/lib/pact/pact_broker/pact_selection_description.rb +24 -0
- data/lib/pact/provider/configuration/message_provider_dsl.rb +27 -0
- data/lib/pact/provider/configuration/pact_verification_from_broker.rb +8 -2
- data/lib/pact/provider/pact_source.rb +1 -1
- data/lib/pact/provider/pact_spec_runner.rb +1 -1
- data/lib/pact/provider/pact_uri.rb +2 -2
- data/lib/pact/provider/rspec/formatter_rspec_3.rb +20 -5
- data/lib/pact/provider/rspec/json_formatter.rb +25 -11
- data/lib/pact/provider/rspec.rb +11 -5
- data/lib/pact/provider/test_methods.rb +8 -2
- data/lib/pact/provider/verification_results/publish.rb +3 -0
- data/lib/pact/provider/verification_results/publish_all.rb +14 -1
- data/lib/pact/provider/verification_results/verification_result.rb +1 -4
- data/lib/pact/tasks/task_helper.rb +6 -1
- data/lib/pact/version.rb +1 -1
- data/pact.gemspec +3 -2
- metadata +29 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 36cdbcc7291013248a5b691e8dec77f7153fd3c5c75d664e5da651943a8673dc
|
|
4
|
+
data.tar.gz: 0a75d19524d85f5623f6f8f9b042b1e481f551a5784cb2c48e86633f2d3d7329
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: faa46bb073cdacca555022ee518d15e13182f286f1b6d75f309f7f5d6d6692674c046ced1d3b8598d10772b7dc25d3157aa556d6ac47453753dc90607ed8575b
|
|
7
|
+
data.tar.gz: 360a99577f6925e21ab6ce0949bca79a3309c1a16e7dbd21ae72fe20b7c46a87eca0f422d810061d2adc594141b76ca4be831eeb8859aff29eca00fe9227f78e
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,108 @@
|
|
|
1
|
+
<a name="v1.53.0"></a>
|
|
2
|
+
### v1.53.0 (2020-09-11)
|
|
3
|
+
|
|
4
|
+
#### Features
|
|
5
|
+
|
|
6
|
+
* add support for the enable_pending flag ([16866f4](/../../commit/16866f4))
|
|
7
|
+
|
|
8
|
+
<a name="v1.52.0"></a>
|
|
9
|
+
### v1.52.0 (2020-09-10)
|
|
10
|
+
|
|
11
|
+
#### Features
|
|
12
|
+
|
|
13
|
+
* support webdav http methods ([fa1d712](/../../commit/fa1d712))
|
|
14
|
+
|
|
15
|
+
<a name="v1.51.1"></a>
|
|
16
|
+
### v1.51.1 (2020-08-12)
|
|
17
|
+
|
|
18
|
+
#### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* update thor dependency (#218) ([bf3ce69](/../../commit/bf3ce69))
|
|
21
|
+
* bump rake dependency per CVE-2020-8130 (#219) ([09feaa6](/../../commit/09feaa6))
|
|
22
|
+
|
|
23
|
+
<a name="v1.51.0"></a>
|
|
24
|
+
### v1.51.0 (2020-06-24)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
#### Features
|
|
28
|
+
|
|
29
|
+
* allow individual interactions to be re-run by setting PACT_BROKER_INTERACTION_ID ([a586d80](/../../commit/a586d80))
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
<a name="v1.50.1"></a>
|
|
33
|
+
### v1.50.1 (2020-06-15)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
#### Bug Fixes
|
|
37
|
+
|
|
38
|
+
* fix integration with pact-message-ruby (#216) ([d2da13e](/../../commit/d2da13e))
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
<a name="v1.50.0"></a>
|
|
42
|
+
### v1.50.0 (2020-04-25)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
#### Features
|
|
46
|
+
|
|
47
|
+
* Set expected interactions on mock service but without writing them to pact file (#210) ([14f5327](/../../commit/14f5327))
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
<a name="v1.49.3"></a>
|
|
51
|
+
### v1.49.3 (2020-04-22)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
#### Bug Fixes
|
|
55
|
+
|
|
56
|
+
* pact selection verification options logging ([9ff59f4](/../../commit/9ff59f4))
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
<a name="v1.49.2"></a>
|
|
60
|
+
### v1.49.2 (2020-04-08)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
#### Bug Fixes
|
|
64
|
+
|
|
65
|
+
* json parser error for top level JSON values ([dafbc35](/../../commit/dafbc35))
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
<a name="v1.49.1"></a>
|
|
69
|
+
### v1.49.1 (2020-03-21)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
#### Bug Fixes
|
|
73
|
+
|
|
74
|
+
* ensure diff is included in the json output ([0bd9753](/../../commit/0bd9753))
|
|
75
|
+
* ensure the presence of basic auth credentials does not cause an error when displaying the path of a pact on the local filesystem ([f6a0b4d](/../../commit/f6a0b4d))
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
<a name="v1.49.0"></a>
|
|
79
|
+
### v1.49.0 (2020-02-18)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
#### Features
|
|
83
|
+
|
|
84
|
+
* use environment variables PACT_BROKER_USERNAME and PACT_BROKER_PASSWORD when verifying a pact by URL, if the environment variables are present ([308f25d](/../../commit/308f25d))
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
<a name="v1.48.0"></a>
|
|
88
|
+
### v1.48.0 (2020-02-13)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
#### Features
|
|
92
|
+
|
|
93
|
+
* use certificates from SSL_CERT_FILE and SSL_CERT_DIR environment variables in HTTP connections ([164912b](/../../commit/164912b))
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
<a name="v1.47.0"></a>
|
|
97
|
+
### v1.47.0 (2020-02-08)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
#### Features
|
|
101
|
+
|
|
102
|
+
* update json formatter output ([376e47a](/../../commit/376e47a))
|
|
103
|
+
* add pact metadata to json formatter ([6c6ddb8](/../../commit/6c6ddb8))
|
|
104
|
+
|
|
105
|
+
|
|
1
106
|
<a name="v1.46.1"></a>
|
|
2
107
|
### v1.46.1 (2020-01-22)
|
|
3
108
|
|
|
@@ -56,9 +56,11 @@ module Pact
|
|
|
56
56
|
|
|
57
57
|
def run_with_pact_url_string
|
|
58
58
|
pact_repository_uri_options = {}
|
|
59
|
+
pact_repository_uri_options[:username] = ENV['PACT_BROKER_USERNAME'] if ENV['PACT_BROKER_USERNAME']
|
|
60
|
+
pact_repository_uri_options[:password] = ENV['PACT_BROKER_PASSWORD'] if ENV['PACT_BROKER_PASSWORD']
|
|
61
|
+
pact_repository_uri_options[:token] = ENV['PACT_BROKER_TOKEN']
|
|
59
62
|
pact_repository_uri_options[:username] = options[:pact_broker_username] if options[:pact_broker_username]
|
|
60
63
|
pact_repository_uri_options[:password] = options[:pact_broker_password] if options[:pact_broker_password]
|
|
61
|
-
pact_repository_uri_options[:token] = ENV['PACT_BROKER_TOKEN']
|
|
62
64
|
pact_uri = ::Pact::Provider::PactURI.new(options[:pact_uri], pact_repository_uri_options)
|
|
63
65
|
Pact::Provider::PactSpecRunner.new([pact_uri], pact_spec_options).run
|
|
64
66
|
end
|
|
@@ -6,8 +6,11 @@ module Pact
|
|
|
6
6
|
criteria = {}
|
|
7
7
|
|
|
8
8
|
criteria[:description] = Regexp.new(options[:description]) if options[:description]
|
|
9
|
+
criteria[:_id] = options[:pact_broker_interaction_id] if options[:pact_broker_interaction_id]
|
|
10
|
+
criteria[:index] = options[:interaction_index] if options[:interaction_index]
|
|
9
11
|
|
|
10
12
|
provider_state = options[:provider_state]
|
|
13
|
+
|
|
11
14
|
if provider_state
|
|
12
15
|
if provider_state.length == 0
|
|
13
16
|
criteria[:provider_state] = nil #Allow PACT_PROVIDER_STATE="" to mean no provider state
|
data/lib/pact/cli.rb
CHANGED
|
@@ -4,6 +4,9 @@ require 'pact/provider/configuration'
|
|
|
4
4
|
|
|
5
5
|
module Pact
|
|
6
6
|
class CLI < Thor
|
|
7
|
+
def self.exit_on_failure? # Thor 1.0 deprecation guard
|
|
8
|
+
false
|
|
9
|
+
end
|
|
7
10
|
|
|
8
11
|
desc 'verify', "Verify a pact"
|
|
9
12
|
method_option :pact_helper, aliases: "-h", desc: "Pact helper file", :required => true
|
|
@@ -18,6 +21,8 @@ module Pact
|
|
|
18
21
|
default: Pact.configuration.interactions_replay_order
|
|
19
22
|
method_option :description, aliases: "-d", desc: "Interaction description filter"
|
|
20
23
|
method_option :provider_state, aliases: "-s", desc: "Provider state filter"
|
|
24
|
+
method_option :interaction_index, type: :numeric, desc: "Index filter"
|
|
25
|
+
method_option :pact_broker_interaction_id, desc: "Pact Broker interaction ID filter"
|
|
21
26
|
method_option :format, aliases: "-f", banner: "FORMATTER", desc: "RSpec formatter. Defaults to custom Pact formatter. [j]son may also be used."
|
|
22
27
|
method_option :out, aliases: "-o", banner: "FILE", desc: "Write output to a file instead of $stdout."
|
|
23
28
|
|
|
@@ -25,6 +25,10 @@ module Pact
|
|
|
25
25
|
@mock_service_base_url = "http://#{attributes[:host]}:#{attributes[:port]}"
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
+
def without_writing_to_pact
|
|
29
|
+
interaction_builder.without_writing_to_pact
|
|
30
|
+
end
|
|
31
|
+
|
|
28
32
|
def given(provider_state)
|
|
29
33
|
interaction_builder.given(provider_state)
|
|
30
34
|
end
|
|
@@ -13,6 +13,12 @@ module Pact
|
|
|
13
13
|
@callback = block
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
+
def without_writing_to_pact
|
|
17
|
+
interaction.metadata ||= {}
|
|
18
|
+
interaction.metadata[:write_to_pact] = false
|
|
19
|
+
self
|
|
20
|
+
end
|
|
21
|
+
|
|
16
22
|
def upon_receiving description
|
|
17
23
|
@interaction.description = description
|
|
18
24
|
self
|
data/lib/pact/hal/http_client.rb
CHANGED
|
@@ -50,6 +50,8 @@ module Pact
|
|
|
50
50
|
http = Net::HTTP.new(uri.host, uri.port, :ENV)
|
|
51
51
|
http.set_debug_output(output_stream) if verbose
|
|
52
52
|
http.use_ssl = (uri.scheme == 'https')
|
|
53
|
+
http.ca_file = ENV['SSL_CERT_FILE'] if ENV['SSL_CERT_FILE'] && ENV['SSL_CERT_FILE'] != ''
|
|
54
|
+
http.ca_path = ENV['SSL_CERT_DIR'] if ENV['SSL_CERT_DIR'] && ENV['SSL_CERT_DIR'] != ''
|
|
53
55
|
http.start do |http|
|
|
54
56
|
http.request request
|
|
55
57
|
end
|
|
@@ -3,10 +3,13 @@ require 'pact/hal/http_client'
|
|
|
3
3
|
require 'pact/provider/pact_uri'
|
|
4
4
|
require 'pact/errors'
|
|
5
5
|
require 'pact/pact_broker/fetch_pacts'
|
|
6
|
+
require 'pact/pact_broker/notices'
|
|
7
|
+
require 'pact/pact_broker/pact_selection_description'
|
|
6
8
|
|
|
7
9
|
module Pact
|
|
8
10
|
module PactBroker
|
|
9
11
|
class FetchPactURIsForVerification
|
|
12
|
+
include PactSelectionDescription
|
|
10
13
|
attr_reader :provider, :consumer_version_selectors, :provider_version_tags, :broker_base_url, :http_client_options, :http_client, :options
|
|
11
14
|
|
|
12
15
|
PACTS_FOR_VERIFICATION_RELATION = 'beta:provider-pacts-for-verification'.freeze
|
|
@@ -19,7 +22,7 @@ module Pact
|
|
|
19
22
|
def initialize(provider, consumer_version_selectors, provider_version_tags, broker_base_url, http_client_options, options = {})
|
|
20
23
|
@provider = provider
|
|
21
24
|
@consumer_version_selectors = consumer_version_selectors || []
|
|
22
|
-
@provider_version_tags = provider_version_tags
|
|
25
|
+
@provider_version_tags = [*provider_version_tags]
|
|
23
26
|
@http_client_options = http_client_options
|
|
24
27
|
@broker_base_url = broker_base_url
|
|
25
28
|
@http_client = Pact::Hal::HttpClient.new(http_client_options)
|
|
@@ -51,7 +54,8 @@ module Pact
|
|
|
51
54
|
pacts_for_verification_entity.response.body[EMBEDDED][PACTS].collect do | pact |
|
|
52
55
|
metadata = {
|
|
53
56
|
pending: pact["verificationProperties"]["pending"],
|
|
54
|
-
notices: extract_notices(pact)
|
|
57
|
+
notices: extract_notices(pact),
|
|
58
|
+
short_description: pact["shortDescription"]
|
|
55
59
|
}
|
|
56
60
|
Pact::Provider::PactURI.new(pact[LINKS][SELF][HREF], http_client_options, metadata)
|
|
57
61
|
end
|
|
@@ -69,11 +73,12 @@ module Pact
|
|
|
69
73
|
q["includePendingStatus"] = true if options[:include_pending_status]
|
|
70
74
|
q["consumerVersionSelectors"] = consumer_version_selectors if consumer_version_selectors.any?
|
|
71
75
|
q["providerVersionTags"] = provider_version_tags if provider_version_tags.any?
|
|
76
|
+
q["includeWipPactsSince"] = options[:include_wip_pacts_since] if options[:include_wip_pacts_since]
|
|
72
77
|
q
|
|
73
78
|
end
|
|
74
79
|
|
|
75
80
|
def extract_notices(pact)
|
|
76
|
-
(pact["verificationProperties"]["notices"] || []).collect{ |notice| symbolize_keys(notice) }
|
|
81
|
+
Notices.new((pact["verificationProperties"]["notices"] || []).collect{ |notice| symbolize_keys(notice) })
|
|
77
82
|
end
|
|
78
83
|
|
|
79
84
|
def symbolize_keys(hash)
|
|
@@ -81,18 +86,7 @@ module Pact
|
|
|
81
86
|
end
|
|
82
87
|
|
|
83
88
|
def log_message
|
|
84
|
-
|
|
85
|
-
message = "INFO: Fetching #{latest}pacts for #{provider} from #{broker_base_url}"
|
|
86
|
-
if consumer_version_selectors.any?
|
|
87
|
-
desc = consumer_version_selectors.collect do |selector|
|
|
88
|
-
all_or_latest = selector[:all] ? "all" : "latest"
|
|
89
|
-
# TODO support fallback
|
|
90
|
-
name = selector[:fallback] ? "#{selector[:tag]} (or #{selector[:fallback]} if not found)" : selector[:tag]
|
|
91
|
-
"#{all_or_latest} #{name}"
|
|
92
|
-
end.join(", ")
|
|
93
|
-
message << " for tags: #{desc}"
|
|
94
|
-
end
|
|
95
|
-
Pact.configuration.output_stream.puts message
|
|
89
|
+
Pact.configuration.output_stream.puts "INFO: #{pact_selection_description(provider, consumer_version_selectors, options, broker_base_url)}"
|
|
96
90
|
end
|
|
97
91
|
end
|
|
98
92
|
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module Pact
|
|
2
|
+
module PactBroker
|
|
3
|
+
class Notices < Array
|
|
4
|
+
def before_verification_notices
|
|
5
|
+
select { | notice | notice[:when].nil? || notice[:when].start_with?('before_verification') }
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def before_verification_notices_text
|
|
9
|
+
before_verification_notices.collect{ | notice | notice[:text] }
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def after_verification_notices(success, published)
|
|
13
|
+
select { | notice | notice[:when] == "after_verification:success_#{success}_published_#{published}" || notice[:when] == "after_verification" }
|
|
14
|
+
.collect do | notice |
|
|
15
|
+
notice.merge(:when => simplify_notice_when(notice[:when]))
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def after_verification_notices_text(success, published)
|
|
20
|
+
after_verification_notices(success, published).collect{ | notice | notice[:text] }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def all_notices(success, published)
|
|
24
|
+
before_verification_notices + after_verification_notices(success, published)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def simplify_notice_when(when_key)
|
|
30
|
+
when_key.split(":").first
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Pact
|
|
2
|
+
module PactBroker
|
|
3
|
+
module PactSelectionDescription
|
|
4
|
+
def pact_selection_description(provider, consumer_version_selectors, options, broker_base_url)
|
|
5
|
+
latest = consumer_version_selectors.any? ? "" : "latest "
|
|
6
|
+
message = "Fetching pacts for #{provider} from #{broker_base_url} with the selection criteria: "
|
|
7
|
+
if consumer_version_selectors.any?
|
|
8
|
+
desc = consumer_version_selectors.collect do |selector|
|
|
9
|
+
all_or_latest = !selector[:latest] ? "all for tag" : "latest for tag"
|
|
10
|
+
# TODO support fallback
|
|
11
|
+
fallback = selector[:fallback] || selector[:fallbackTag]
|
|
12
|
+
name = fallback ? "#{selector[:tag]} (or #{fallback} if not found)" : selector[:tag]
|
|
13
|
+
"#{all_or_latest} #{name}"
|
|
14
|
+
end.join(", ")
|
|
15
|
+
if options[:include_wip_pacts_since]
|
|
16
|
+
desc = "#{desc}, work in progress pacts created after #{options[:include_wip_pacts_since]}"
|
|
17
|
+
end
|
|
18
|
+
message << "#{desc}"
|
|
19
|
+
end
|
|
20
|
+
message
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -22,6 +22,33 @@ module Pact
|
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
dsl do
|
|
25
|
+
def app &block
|
|
26
|
+
self.app_block = block
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def app_version application_version
|
|
30
|
+
self.application_version = application_version
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def app_version_tags tags
|
|
34
|
+
self.tags = tags
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def publish_verification_results publish_verification_results
|
|
38
|
+
self.publish_verification_results = publish_verification_results
|
|
39
|
+
Pact::RSpec.with_rspec_2 do
|
|
40
|
+
Pact.configuration.error_stream.puts "WARN: Publishing of verification results is currently not supported with rspec 2. If you would like this functionality, please feel free to submit a PR!"
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def honours_pact_with consumer_name, options = {}, &block
|
|
45
|
+
create_pact_verification consumer_name, options, &block
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def honours_pacts_from_pact_broker &block
|
|
49
|
+
create_pact_verification_from_broker &block
|
|
50
|
+
end
|
|
51
|
+
|
|
25
52
|
def builder &block
|
|
26
53
|
self.app_block = lambda { RackToMessageAdapter.new(block) }
|
|
27
54
|
end
|
|
@@ -14,12 +14,13 @@ module Pact
|
|
|
14
14
|
# in parent scope, it will clash with these ones,
|
|
15
15
|
# so put an underscore in front of the name to be safer.
|
|
16
16
|
|
|
17
|
-
attr_accessor :_provider_name, :_pact_broker_base_url, :_consumer_version_tags, :_provider_version_tags, :_basic_auth_options, :_verbose
|
|
17
|
+
attr_accessor :_provider_name, :_pact_broker_base_url, :_consumer_version_tags, :_provider_version_tags, :_basic_auth_options, :_enable_pending, :_verbose
|
|
18
18
|
|
|
19
19
|
def initialize(provider_name, provider_version_tags)
|
|
20
20
|
@_provider_name = provider_name
|
|
21
21
|
@_provider_version_tags = provider_version_tags
|
|
22
22
|
@_consumer_version_tags = []
|
|
23
|
+
@_enable_pending = false
|
|
23
24
|
@_verbose = false
|
|
24
25
|
end
|
|
25
26
|
|
|
@@ -33,6 +34,10 @@ module Pact
|
|
|
33
34
|
self._consumer_version_tags = *consumer_version_tags
|
|
34
35
|
end
|
|
35
36
|
|
|
37
|
+
def enable_pending enable_pending
|
|
38
|
+
self._enable_pending = enable_pending
|
|
39
|
+
end
|
|
40
|
+
|
|
36
41
|
def verbose verbose
|
|
37
42
|
self._verbose = verbose
|
|
38
43
|
end
|
|
@@ -51,7 +56,8 @@ module Pact
|
|
|
51
56
|
consumer_version_selectors,
|
|
52
57
|
_provider_version_tags,
|
|
53
58
|
_pact_broker_base_url,
|
|
54
|
-
_basic_auth_options.merge(verbose: _verbose)
|
|
59
|
+
_basic_auth_options.merge(verbose: _verbose),
|
|
60
|
+
{ include_pending_status: _enable_pending }
|
|
55
61
|
)
|
|
56
62
|
|
|
57
63
|
Pact.provider_world.add_pact_uri_source fetch_pacts
|
|
@@ -122,7 +122,7 @@ module Pact
|
|
|
122
122
|
ignore_failures: options[:ignore_failures],
|
|
123
123
|
request_customizer: options[:request_customizer]
|
|
124
124
|
}
|
|
125
|
-
honour_pactfile pact_source
|
|
125
|
+
honour_pactfile pact_source, ordered_pact_json(pact_source.pact_json), spec_options
|
|
126
126
|
end
|
|
127
127
|
end
|
|
128
128
|
|
|
@@ -93,17 +93,32 @@ module Pact
|
|
|
93
93
|
|
|
94
94
|
def interaction_rerun_command_for example
|
|
95
95
|
example_description = example.metadata[:pact_interaction_example_description]
|
|
96
|
-
|
|
96
|
+
|
|
97
|
+
_id = example.metadata[:pact_interaction]._id
|
|
98
|
+
index = example.metadata[:pact_interaction].index
|
|
99
|
+
provider_state = example.metadata[:pact_interaction].provider_state
|
|
100
|
+
description = example.metadata[:pact_interaction].description
|
|
101
|
+
pactfile_uri = example.metadata[:pactfile_uri]
|
|
102
|
+
|
|
103
|
+
if _id && ENV['PACT_INTERACTION_RERUN_COMMAND_FOR_BROKER']
|
|
104
|
+
cmd = String.new(ENV['PACT_INTERACTION_RERUN_COMMAND_FOR_BROKER'])
|
|
105
|
+
cmd.gsub!("<PACT_URI>", example.metadata[:pactfile_uri].to_s)
|
|
106
|
+
cmd.gsub!("<PACT_BROKER_INTERACTION_ID>", "#{_id}")
|
|
107
|
+
colorizer.wrap("#{cmd} ", ::RSpec.configuration.failure_color) + colorizer.wrap("# #{example_description}", ::RSpec.configuration.detail_color)
|
|
108
|
+
elsif ENV['PACT_INTERACTION_RERUN_COMMAND']
|
|
97
109
|
cmd = String.new(ENV['PACT_INTERACTION_RERUN_COMMAND'])
|
|
98
|
-
provider_state = example.metadata[:pact_interaction].provider_state
|
|
99
|
-
description = example.metadata[:pact_interaction].description
|
|
100
|
-
pactfile_uri = example.metadata[:pactfile_uri]
|
|
101
110
|
cmd.gsub!("<PACT_URI>", pactfile_uri.to_s)
|
|
102
111
|
cmd.gsub!("<PACT_DESCRIPTION>", description)
|
|
103
112
|
cmd.gsub!("<PACT_PROVIDER_STATE>", "#{provider_state}")
|
|
113
|
+
cmd.gsub!("<PACT_INTERACTION_INDEX>", "#{index}")
|
|
104
114
|
colorizer.wrap("#{cmd} ", ::RSpec.configuration.failure_color) + colorizer.wrap("# #{example_description}", ::RSpec.configuration.detail_color)
|
|
105
115
|
else
|
|
106
|
-
|
|
116
|
+
message = if _id
|
|
117
|
+
"* #{example_description} (to re-run just this interaction, set environment variable PACT_BROKER_INTERACTION_ID=\"#{_id}\")"
|
|
118
|
+
else
|
|
119
|
+
"* #{example_description} (to re-run just this interaction, set environment variables PACT_DESCRIPTION=\"#{description}\" PACT_PROVIDER_STATE=\"#{provider_state}\")"
|
|
120
|
+
end
|
|
121
|
+
colorizer.wrap(message, ::RSpec.configuration.failure_color)
|
|
107
122
|
end
|
|
108
123
|
end
|
|
109
124
|
|
|
@@ -8,19 +8,21 @@ module Pact
|
|
|
8
8
|
|
|
9
9
|
def dump_summary(summary)
|
|
10
10
|
super(create_custom_summary(summary))
|
|
11
|
-
output_hash[:summary][:
|
|
11
|
+
output_hash[:summary][:pacts] = pacts(summary)
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def format_example(example)
|
|
15
15
|
{
|
|
16
16
|
:id => example.id,
|
|
17
|
+
:interaction_index => example.metadata[:pact_interaction].index,
|
|
17
18
|
:description => example.description,
|
|
18
19
|
:full_description => example.full_description,
|
|
19
20
|
:status => calculate_status(example),
|
|
20
21
|
:file_path => example.metadata[:file_path],
|
|
21
22
|
:line_number => example.metadata[:line_number],
|
|
22
23
|
:run_time => example.execution_result.run_time,
|
|
23
|
-
:mismatches => extract_differences(example)
|
|
24
|
+
:mismatches => extract_differences(example),
|
|
25
|
+
:pact_url => example.metadata[:pact_uri].uri
|
|
24
26
|
}
|
|
25
27
|
end
|
|
26
28
|
|
|
@@ -28,13 +30,15 @@ module Pact
|
|
|
28
30
|
output_hash[:examples] = notification.examples.map do |example|
|
|
29
31
|
format_example(example).tap do |hash|
|
|
30
32
|
e = example.exception
|
|
31
|
-
|
|
32
|
-
if e && ! e.is_a?(::RSpec::Expectations::ExpectationNotMetError)
|
|
33
|
+
if e
|
|
33
34
|
hash[:exception] = {
|
|
34
|
-
:
|
|
35
|
-
:
|
|
36
|
-
:backtrace => e.backtrace,
|
|
35
|
+
class: e.class.name,
|
|
36
|
+
message: e.message,
|
|
37
37
|
}
|
|
38
|
+
# No point providing a backtrace for a mismatch, too much noise
|
|
39
|
+
if !e.is_a?(::RSpec::Expectations::ExpectationNotMetError)
|
|
40
|
+
hash[:exception][:backtrace]
|
|
41
|
+
end
|
|
38
42
|
end
|
|
39
43
|
end
|
|
40
44
|
end
|
|
@@ -54,12 +58,22 @@ module Pact
|
|
|
54
58
|
# If the JSON formatter is used by someone else and they have multiple pacts, all the notices
|
|
55
59
|
# for the pacts will be mushed together in one collection, so it will be hard to know which notice
|
|
56
60
|
# belongs to which pact.
|
|
57
|
-
def
|
|
58
|
-
|
|
61
|
+
def pacts(summary)
|
|
62
|
+
unique_pact_metadatas(summary).collect do | example_metadata |
|
|
63
|
+
pact_uri = example_metadata[:pact_uri]
|
|
64
|
+
notices = (pact_uri.metadata[:notices] && pact_uri.metadata[:notices].before_verification_notices) || []
|
|
65
|
+
{
|
|
66
|
+
notices: notices,
|
|
67
|
+
url: pact_uri.uri,
|
|
68
|
+
consumer_name: example_metadata[:pact_consumer_contract].consumer.name,
|
|
69
|
+
provider_name: example_metadata[:pact_consumer_contract].provider.name,
|
|
70
|
+
short_description: pact_uri.metadata[:short_description]
|
|
71
|
+
}
|
|
72
|
+
end
|
|
59
73
|
end
|
|
60
74
|
|
|
61
|
-
def
|
|
62
|
-
summary.examples.collect(&:metadata).
|
|
75
|
+
def unique_pact_metadatas(summary)
|
|
76
|
+
summary.examples.collect(&:metadata).group_by{ | metadata | metadata[:pact_uri].uri }.values.collect(&:first)
|
|
63
77
|
end
|
|
64
78
|
|
|
65
79
|
def create_custom_summary(summary)
|
data/lib/pact/provider/rspec.rb
CHANGED
|
@@ -21,16 +21,20 @@ module Pact
|
|
|
21
21
|
|
|
22
22
|
include ::RSpec::Core::DSL
|
|
23
23
|
|
|
24
|
-
def honour_pactfile
|
|
24
|
+
def honour_pactfile pact_source, pact_json, options
|
|
25
|
+
pact_uri = pact_source.uri
|
|
25
26
|
Pact.configuration.output_stream.puts "INFO: Reading pact at #{pact_uri}"
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
if pact_uri.metadata[:notices]
|
|
28
|
+
pact_uri.metadata[:notices].before_verification_notices_text.each do | text |
|
|
29
|
+
Pact.configuration.output_stream.puts("DEBUG: #{text}")
|
|
30
|
+
end
|
|
28
31
|
end
|
|
32
|
+
|
|
29
33
|
Pact.configuration.output_stream.puts "DEBUG: Filtering interactions by: #{options[:criteria]}" if options[:criteria] && options[:criteria].any?
|
|
30
34
|
consumer_contract = Pact::ConsumerContract.from_json(pact_json)
|
|
31
35
|
suffix = pact_uri.metadata[:pending] ? " [PENDING]": ""
|
|
32
36
|
::RSpec.describe "Verifying a pact between #{consumer_contract.consumer.name} and #{consumer_contract.provider.name}#{suffix}", pactfile_uri: pact_uri do
|
|
33
|
-
honour_consumer_contract consumer_contract, options.merge(pact_json: pact_json, pact_uri: pact_uri)
|
|
37
|
+
honour_consumer_contract consumer_contract, options.merge(pact_json: pact_json, pact_uri: pact_uri, pact_source: pact_source, consumer_contract: consumer_contract)
|
|
34
38
|
end
|
|
35
39
|
end
|
|
36
40
|
|
|
@@ -78,7 +82,9 @@ module Pact
|
|
|
78
82
|
pact_interaction: interaction,
|
|
79
83
|
pact_interaction_example_description: interaction_description_for_rerun_command(interaction),
|
|
80
84
|
pact_uri: options[:pact_uri],
|
|
81
|
-
|
|
85
|
+
pact_source: options[:pact_source],
|
|
86
|
+
pact_ignore_failures: options[:pact_uri].metadata[:pending] || options[:ignore_failures],
|
|
87
|
+
pact_consumer_contract: options[:consumer_contract]
|
|
82
88
|
}
|
|
83
89
|
|
|
84
90
|
describe description_for(interaction), metadata do
|
|
@@ -21,7 +21,11 @@ module Pact
|
|
|
21
21
|
|
|
22
22
|
logger.info "Sending #{request.method.upcase} request to path: \"#{request.path}\" with headers: #{request.headers}, see debug logs for body"
|
|
23
23
|
logger.debug "body :#{request.body}"
|
|
24
|
-
response = self.
|
|
24
|
+
response = if self.respond_to?(:custom_request)
|
|
25
|
+
self.custom_request(request.method.upcase, *args)
|
|
26
|
+
else
|
|
27
|
+
self.send(request.method.downcase, *args)
|
|
28
|
+
end
|
|
25
29
|
logger.info "Received response with status: #{response.status}, headers: #{response.headers}, see debug logs for body"
|
|
26
30
|
logger.debug "body: #{response.body}"
|
|
27
31
|
end
|
|
@@ -29,7 +33,9 @@ module Pact
|
|
|
29
33
|
def parse_body_from_response rack_response
|
|
30
34
|
case rack_response.headers['Content-Type']
|
|
31
35
|
when /json/
|
|
32
|
-
|
|
36
|
+
# For https://github.com/pact-foundation/pact-net/issues/237
|
|
37
|
+
# Only required for the pact-ruby-standalone ¯\_(ツ)_/¯
|
|
38
|
+
JSON.load("[#{rack_response.body}]").first
|
|
33
39
|
else
|
|
34
40
|
rack_response.body
|
|
35
41
|
end
|
|
@@ -17,7 +17,12 @@ module Pact
|
|
|
17
17
|
|
|
18
18
|
def call
|
|
19
19
|
verification_results.collect do | (pact_source, verification_result) |
|
|
20
|
-
|
|
20
|
+
published = false
|
|
21
|
+
begin
|
|
22
|
+
published = Publish.call(pact_source, verification_result)
|
|
23
|
+
ensure
|
|
24
|
+
print_after_verification_notices(pact_source, verification_result, published)
|
|
25
|
+
end
|
|
21
26
|
end
|
|
22
27
|
end
|
|
23
28
|
|
|
@@ -29,6 +34,14 @@ module Pact
|
|
|
29
34
|
end
|
|
30
35
|
end
|
|
31
36
|
|
|
37
|
+
def print_after_verification_notices(pact_source, verification_result, published)
|
|
38
|
+
if pact_source.uri.metadata[:notices]
|
|
39
|
+
pact_source.uri.metadata[:notices].after_verification_notices_text(verification_result.success, published).each do | text |
|
|
40
|
+
Pact.configuration.output_stream.puts "DEBUG: #{text}"
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
32
45
|
attr_reader :pact_sources, :test_results_hash
|
|
33
46
|
end
|
|
34
47
|
end
|
|
@@ -4,6 +4,7 @@ module Pact
|
|
|
4
4
|
module Provider
|
|
5
5
|
module VerificationResults
|
|
6
6
|
class VerificationResult
|
|
7
|
+
attr_reader :success, :provider_application_version, :test_results_hash
|
|
7
8
|
|
|
8
9
|
def initialize publishable, success, provider_application_version, test_results_hash
|
|
9
10
|
@publishable = publishable
|
|
@@ -31,10 +32,6 @@ module Pact
|
|
|
31
32
|
def to_s
|
|
32
33
|
"[success: #{success}, providerApplicationVersion: #{provider_application_version}]"
|
|
33
34
|
end
|
|
34
|
-
|
|
35
|
-
private
|
|
36
|
-
|
|
37
|
-
attr_reader :success, :provider_application_version, :test_results_hash
|
|
38
35
|
end
|
|
39
36
|
end
|
|
40
37
|
end
|
|
@@ -7,6 +7,7 @@ module Pact
|
|
|
7
7
|
module TaskHelper
|
|
8
8
|
|
|
9
9
|
PACT_INTERACTION_RERUN_COMMAND = "bundle exec rake pact:verify:at[<PACT_URI>] PACT_DESCRIPTION=\"<PACT_DESCRIPTION>\" PACT_PROVIDER_STATE=\"<PACT_PROVIDER_STATE>\""
|
|
10
|
+
PACT_INTERACTION_RERUN_COMMAND_FOR_BROKER = "bundle exec rake pact:verify:at[<PACT_URI>] PACT_BROKER_INTERACTION_ID=\"<PACT_BROKER_INTERACTION_ID>\""
|
|
10
11
|
|
|
11
12
|
extend self
|
|
12
13
|
|
|
@@ -34,6 +35,8 @@ module Pact
|
|
|
34
35
|
command_parts << "--backtrace" if ENV['BACKTRACE'] == 'true'
|
|
35
36
|
command_parts << "--description #{Shellwords.escape(ENV['PACT_DESCRIPTION'])}" if ENV['PACT_DESCRIPTION']
|
|
36
37
|
command_parts << "--provider-state #{Shellwords.escape(ENV['PACT_PROVIDER_STATE'])}" if ENV['PACT_PROVIDER_STATE']
|
|
38
|
+
command_parts << "--pact-broker-interaction-id #{Shellwords.escape(ENV['PACT_BROKER_INTERACTION_ID'])}" if ENV['PACT_BROKER_INTERACTION_ID']
|
|
39
|
+
command_parts << "--interaction-index #{Shellwords.escape(ENV['PACT_INTERACTION_INDEX'])}" if ENV['PACT_INTERACTION_INDEX']
|
|
37
40
|
command_parts.flatten.join(" ")
|
|
38
41
|
end
|
|
39
42
|
|
|
@@ -41,7 +44,9 @@ module Pact
|
|
|
41
44
|
Pact.configuration.output_stream.puts command
|
|
42
45
|
temporarily_set_env_var 'PACT_EXECUTING_LANGUAGE', 'ruby' do
|
|
43
46
|
temporarily_set_env_var 'PACT_INTERACTION_RERUN_COMMAND', PACT_INTERACTION_RERUN_COMMAND do
|
|
44
|
-
|
|
47
|
+
temporarily_set_env_var 'PACT_INTERACTION_RERUN_COMMAND_FOR_BROKER', PACT_INTERACTION_RERUN_COMMAND_FOR_BROKER do
|
|
48
|
+
exit_status = system(command) ? 0 : 1
|
|
49
|
+
end
|
|
45
50
|
end
|
|
46
51
|
end
|
|
47
52
|
end
|
data/lib/pact/version.rb
CHANGED
data/pact.gemspec
CHANGED
|
@@ -28,14 +28,14 @@ Gem::Specification.new do |gem|
|
|
|
28
28
|
|
|
29
29
|
gem.add_runtime_dependency 'rspec', '~> 3.0'
|
|
30
30
|
gem.add_runtime_dependency 'rack-test', '>= 0.6.3', '< 2.0.0'
|
|
31
|
-
gem.add_runtime_dependency 'thor', '
|
|
31
|
+
gem.add_runtime_dependency 'thor', '>= 0.20', '< 2.0'
|
|
32
32
|
gem.add_runtime_dependency 'webrick', '~> 1.3'
|
|
33
33
|
gem.add_runtime_dependency 'term-ansicolor', '~> 1.0'
|
|
34
34
|
|
|
35
35
|
gem.add_runtime_dependency 'pact-support', '~> 1.9'
|
|
36
36
|
gem.add_runtime_dependency 'pact-mock_service', '~> 3.0', '>= 3.3.1'
|
|
37
37
|
|
|
38
|
-
gem.add_development_dependency 'rake', '~>
|
|
38
|
+
gem.add_development_dependency 'rake', '~> 13.0'
|
|
39
39
|
gem.add_development_dependency 'webmock', '~> 3.0'
|
|
40
40
|
gem.add_development_dependency 'fakefs', '0.5' # 0.6.0 blows up
|
|
41
41
|
gem.add_development_dependency 'hashie', '~> 2.0'
|
|
@@ -44,4 +44,5 @@ Gem::Specification.new do |gem|
|
|
|
44
44
|
gem.add_development_dependency 'conventional-changelog', '~> 1.3'
|
|
45
45
|
gem.add_development_dependency 'bump', '~> 0.5'
|
|
46
46
|
gem.add_development_dependency 'pact-message', '~> 0.6'
|
|
47
|
+
gem.add_development_dependency 'rspec-its', '~> 1.3'
|
|
47
48
|
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.
|
|
4
|
+
version: 1.53.0
|
|
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: 2020-
|
|
15
|
+
date: 2020-09-11 00:00:00.000000000 Z
|
|
16
16
|
dependencies:
|
|
17
17
|
- !ruby/object:Gem::Dependency
|
|
18
18
|
name: rspec
|
|
@@ -52,16 +52,22 @@ dependencies:
|
|
|
52
52
|
name: thor
|
|
53
53
|
requirement: !ruby/object:Gem::Requirement
|
|
54
54
|
requirements:
|
|
55
|
-
- - "
|
|
55
|
+
- - ">="
|
|
56
56
|
- !ruby/object:Gem::Version
|
|
57
57
|
version: '0.20'
|
|
58
|
+
- - "<"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '2.0'
|
|
58
61
|
type: :runtime
|
|
59
62
|
prerelease: false
|
|
60
63
|
version_requirements: !ruby/object:Gem::Requirement
|
|
61
64
|
requirements:
|
|
62
|
-
- - "
|
|
65
|
+
- - ">="
|
|
63
66
|
- !ruby/object:Gem::Version
|
|
64
67
|
version: '0.20'
|
|
68
|
+
- - "<"
|
|
69
|
+
- !ruby/object:Gem::Version
|
|
70
|
+
version: '2.0'
|
|
65
71
|
- !ruby/object:Gem::Dependency
|
|
66
72
|
name: webrick
|
|
67
73
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -130,14 +136,14 @@ dependencies:
|
|
|
130
136
|
requirements:
|
|
131
137
|
- - "~>"
|
|
132
138
|
- !ruby/object:Gem::Version
|
|
133
|
-
version: '
|
|
139
|
+
version: '13.0'
|
|
134
140
|
type: :development
|
|
135
141
|
prerelease: false
|
|
136
142
|
version_requirements: !ruby/object:Gem::Requirement
|
|
137
143
|
requirements:
|
|
138
144
|
- - "~>"
|
|
139
145
|
- !ruby/object:Gem::Version
|
|
140
|
-
version: '
|
|
146
|
+
version: '13.0'
|
|
141
147
|
- !ruby/object:Gem::Dependency
|
|
142
148
|
name: webmock
|
|
143
149
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -250,6 +256,20 @@ dependencies:
|
|
|
250
256
|
- - "~>"
|
|
251
257
|
- !ruby/object:Gem::Version
|
|
252
258
|
version: '0.6'
|
|
259
|
+
- !ruby/object:Gem::Dependency
|
|
260
|
+
name: rspec-its
|
|
261
|
+
requirement: !ruby/object:Gem::Requirement
|
|
262
|
+
requirements:
|
|
263
|
+
- - "~>"
|
|
264
|
+
- !ruby/object:Gem::Version
|
|
265
|
+
version: '1.3'
|
|
266
|
+
type: :development
|
|
267
|
+
prerelease: false
|
|
268
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
269
|
+
requirements:
|
|
270
|
+
- - "~>"
|
|
271
|
+
- !ruby/object:Gem::Version
|
|
272
|
+
version: '1.3'
|
|
253
273
|
description: Enables consumer driven contract testing, providing a mock service and
|
|
254
274
|
DSL for the consumer project, and interaction playback and verification for the
|
|
255
275
|
service provider project.
|
|
@@ -304,6 +324,8 @@ files:
|
|
|
304
324
|
- lib/pact/pact_broker.rb
|
|
305
325
|
- lib/pact/pact_broker/fetch_pact_uris_for_verification.rb
|
|
306
326
|
- lib/pact/pact_broker/fetch_pacts.rb
|
|
327
|
+
- lib/pact/pact_broker/notices.rb
|
|
328
|
+
- lib/pact/pact_broker/pact_selection_description.rb
|
|
307
329
|
- lib/pact/project_root.rb
|
|
308
330
|
- lib/pact/provider.rb
|
|
309
331
|
- lib/pact/provider/configuration.rb
|
|
@@ -381,8 +403,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
381
403
|
- !ruby/object:Gem::Version
|
|
382
404
|
version: '0'
|
|
383
405
|
requirements: []
|
|
384
|
-
|
|
385
|
-
rubygems_version: 2.7.7
|
|
406
|
+
rubygems_version: 3.1.4
|
|
386
407
|
signing_key:
|
|
387
408
|
specification_version: 4
|
|
388
409
|
summary: Enables consumer driven contract testing, providing a mock service and DSL
|