pact 1.64.0 → 1.67.5
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 +130 -0
- data/lib/pact/cli/run_pact_verification.rb +0 -1
- data/lib/pact/consumer/consumer_contract_builder.rb +1 -1
- data/lib/pact/hal/http_client.rb +19 -1
- data/lib/pact/pact_broker/fetch_pact_uris_for_verification.rb +19 -8
- data/lib/pact/provider/configuration/message_provider_dsl.rb +4 -0
- data/lib/pact/provider/configuration/pact_verification_from_broker.rb +8 -2
- data/lib/pact/provider/help/console_text.rb +4 -8
- data/lib/pact/provider/help/prompt_text.rb +2 -4
- data/lib/pact/provider/matchers/messages.rb +3 -5
- data/lib/pact/provider/print_missing_provider_states.rb +3 -5
- data/lib/pact/provider/request.rb +25 -5
- data/lib/pact/provider/rspec/formatter_rspec_2.rb +1 -3
- data/lib/pact/provider/rspec/formatter_rspec_3.rb +1 -3
- data/lib/pact/provider/rspec/pact_broker_formatter.rb +2 -2
- data/lib/pact/provider/rspec.rb +5 -3
- data/lib/pact/provider/test_methods.rb +9 -3
- data/lib/pact/v2/configuration.rb +23 -0
- data/lib/pact/v2/consumer/grpc_interaction_builder.rb +194 -0
- data/lib/pact/v2/consumer/http_interaction_builder.rb +162 -0
- data/lib/pact/v2/consumer/interaction_contents.rb +62 -0
- data/lib/pact/v2/consumer/message_interaction_builder.rb +288 -0
- data/lib/pact/v2/consumer/mock_server.rb +108 -0
- data/lib/pact/v2/consumer/pact_config/base.rb +24 -0
- data/lib/pact/v2/consumer/pact_config/grpc.rb +26 -0
- data/lib/pact/v2/consumer/pact_config/http.rb +55 -0
- data/lib/pact/v2/consumer/pact_config/message.rb +17 -0
- data/lib/pact/v2/consumer/pact_config/plugin_async_message.rb +26 -0
- data/lib/pact/v2/consumer/pact_config/plugin_http.rb +26 -0
- data/lib/pact/v2/consumer/pact_config/plugin_sync_message.rb +26 -0
- data/lib/pact/v2/consumer/pact_config.rb +30 -0
- data/lib/pact/v2/consumer/plugin_async_message_interaction_builder.rb +171 -0
- data/lib/pact/v2/consumer/plugin_http_interaction_builder.rb +201 -0
- data/lib/pact/v2/consumer/plugin_sync_message_interaction_builder.rb +180 -0
- data/lib/pact/v2/consumer.rb +8 -0
- data/lib/pact/v2/generators/base.rb +287 -0
- data/lib/pact/v2/generators.rb +49 -0
- data/lib/pact/v2/matchers/base.rb +74 -0
- data/lib/pact/v2/matchers/v1/equality.rb +19 -0
- data/lib/pact/v2/matchers/v2/regex.rb +19 -0
- data/lib/pact/v2/matchers/v2/type.rb +17 -0
- data/lib/pact/v2/matchers/v3/boolean.rb +17 -0
- data/lib/pact/v2/matchers/v3/content_type.rb +32 -0
- data/lib/pact/v2/matchers/v3/date.rb +18 -0
- data/lib/pact/v2/matchers/v3/date_time.rb +18 -0
- data/lib/pact/v2/matchers/v3/decimal.rb +17 -0
- data/lib/pact/v2/matchers/v3/each.rb +42 -0
- data/lib/pact/v2/matchers/v3/include.rb +17 -0
- data/lib/pact/v2/matchers/v3/integer.rb +17 -0
- data/lib/pact/v2/matchers/v3/null.rb +16 -0
- data/lib/pact/v2/matchers/v3/number.rb +17 -0
- data/lib/pact/v2/matchers/v3/semver.rb +23 -0
- data/lib/pact/v2/matchers/v3/time.rb +18 -0
- data/lib/pact/v2/matchers/v3/values.rb +16 -0
- data/lib/pact/v2/matchers/v4/each_key.rb +26 -0
- data/lib/pact/v2/matchers/v4/each_key_value.rb +32 -0
- data/lib/pact/v2/matchers/v4/each_value.rb +33 -0
- data/lib/pact/v2/matchers/v4/not_empty.rb +24 -0
- data/lib/pact/v2/matchers/v4/status_code.rb +17 -0
- data/lib/pact/v2/matchers.rb +110 -0
- data/lib/pact/v2/native/blocking_verifier.rb +17 -0
- data/lib/pact/v2/native/logger.rb +25 -0
- data/lib/pact/v2/provider/async_message_verifier.rb +28 -0
- data/lib/pact/v2/provider/base_verifier.rb +242 -0
- data/lib/pact/v2/provider/grpc_verifier.rb +38 -0
- data/lib/pact/v2/provider/gruf_server.rb +75 -0
- data/lib/pact/v2/provider/http_server.rb +79 -0
- data/lib/pact/v2/provider/http_verifier.rb +43 -0
- data/lib/pact/v2/provider/message_provider_servlet.rb +79 -0
- data/lib/pact/v2/provider/mixed_verifier.rb +22 -0
- data/lib/pact/v2/provider/pact_broker_proxy.rb +66 -0
- data/lib/pact/v2/provider/pact_broker_proxy_runner.rb +80 -0
- data/lib/pact/v2/provider/pact_config/async.rb +29 -0
- data/lib/pact/v2/provider/pact_config/base.rb +103 -0
- data/lib/pact/v2/provider/pact_config/grpc.rb +26 -0
- data/lib/pact/v2/provider/pact_config/http.rb +27 -0
- data/lib/pact/v2/provider/pact_config/mixed.rb +40 -0
- data/lib/pact/v2/provider/pact_config.rb +26 -0
- data/lib/pact/v2/provider/provider_server_runner.rb +92 -0
- data/lib/pact/v2/provider/provider_state_configuration.rb +32 -0
- data/lib/pact/v2/provider/provider_state_servlet.rb +86 -0
- data/lib/pact/v2/provider.rb +8 -0
- data/lib/pact/v2/railtie.rb +13 -0
- data/lib/pact/v2/rspec/support/pact_consumer_helpers.rb +93 -0
- data/lib/pact/v2/rspec/support/pact_message_helpers.rb +42 -0
- data/lib/pact/v2/rspec/support/pact_provider_helpers.rb +129 -0
- data/lib/pact/v2/rspec/support/waterdrop/pact_waterdrop_client.rb +27 -0
- data/lib/pact/v2/rspec/support/webmock/webmock_helpers.rb +30 -0
- data/lib/pact/v2/rspec.rb +17 -0
- data/lib/pact/v2/tasks/pact.rake +13 -0
- data/lib/pact/v2.rb +71 -0
- data/lib/pact/version.rb +1 -1
- data/lib/pact.rb +6 -0
- data/lib/tasks/pact.rake +2 -2
- data/pact.gemspec +57 -9
- metadata +420 -69
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8be91a33981b95189c08f545d3746c76f2f2ad8642777f753cc3b414233986de
|
|
4
|
+
data.tar.gz: 1bc7d8a6e8a08c47b79e73f68e0caed9585a0eafb0bc316a4e589f2b3f9028a3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a73f8cf2aa2956f7e0c7ed2dc8ab35fefbf1b7a2b0ab88d21bb3936a4761ae60d2fd622c4f2a767f2b6e75837556aeb055011667def9a90b8fbe1f9df74bf0f9
|
|
7
|
+
data.tar.gz: e27d62a8822b43ded6ccd48b926c2833292617834c7c2b8dda45d93a26a769d1093909d87921f8c15962445d3ef2012b1df2d5417ed7a07259a4275862c9f4b9
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,133 @@
|
|
|
1
|
+
<a name="v1.67.5"></a>
|
|
2
|
+
### v1.67.5 (2026-02-13)
|
|
3
|
+
|
|
4
|
+
#### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* retry HTTP requests on 5xx status codes (502, 503, 504) ([2174a31](/../../commit/2174a31))
|
|
7
|
+
|
|
8
|
+
<a name="v1.67.4"></a>
|
|
9
|
+
### v1.67.4 (2026-02-09)
|
|
10
|
+
|
|
11
|
+
#### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* suppress v2 load warning in v1 mode ([4f7bab2](/../../commit/4f7bab2))
|
|
14
|
+
* pact-v2 verifier - pact_proxy_port was not honoured ([6a60bae](/../../commit/6a60bae))
|
|
15
|
+
|
|
16
|
+
<a name="v1.67.3"></a>
|
|
17
|
+
### v1.67.3 (2025-11-06)
|
|
18
|
+
|
|
19
|
+
#### Bug Fixes
|
|
20
|
+
|
|
21
|
+
* ensure message consumers with plugins cleanup processes ([8df23e6](/../../commit/8df23e6))
|
|
22
|
+
|
|
23
|
+
<a name="v1.67.2"></a>
|
|
24
|
+
### v1.67.2 (2025-10-22)
|
|
25
|
+
|
|
26
|
+
#### Bug Fixes
|
|
27
|
+
|
|
28
|
+
* **v2**
|
|
29
|
+
* allow configurable loggers in verifier ([9fad7fa](/../../commit/9fad7fa))
|
|
30
|
+
|
|
31
|
+
<a name="v1.67.1"></a>
|
|
32
|
+
### v1.67.1 (2025-10-22)
|
|
33
|
+
|
|
34
|
+
#### Bug Fixes
|
|
35
|
+
|
|
36
|
+
* **deps**
|
|
37
|
+
* make pact-ffi optional in v1 releases for pact-ruby-standalone consumption ([e3cd0d6](/../../commit/e3cd0d6))
|
|
38
|
+
|
|
39
|
+
<a name="v1.67.0"></a>
|
|
40
|
+
### v1.67.0 (2025-10-16)
|
|
41
|
+
|
|
42
|
+
#### Features
|
|
43
|
+
|
|
44
|
+
* add support for generate_from_provider_state ([4ff7812](/../../commit/4ff7812))
|
|
45
|
+
* add pact-ruby v2 generators ([4db935b](/../../commit/4db935b))
|
|
46
|
+
* add pact plugin consumer interfaces for http/async/sync messages ([ca19f86](/../../commit/ca19f86))
|
|
47
|
+
* add more matchers ([ccb82b9](/../../commit/ccb82b9))
|
|
48
|
+
* load pact/v2 into namespace ([4ac42ec](/../../commit/4ac42ec))
|
|
49
|
+
* add pact v2 interface ([4595015](/../../commit/4595015))
|
|
50
|
+
|
|
51
|
+
#### Bug Fixes
|
|
52
|
+
|
|
53
|
+
* ensure we always print mismatchs in consumer tests for better dx ([f9cb106](/../../commit/f9cb106))
|
|
54
|
+
* json load diff regression downstream, relax restrictions ([481eab9](/../../commit/481eab9))
|
|
55
|
+
|
|
56
|
+
<a name="v1.66.2"></a>
|
|
57
|
+
### v1.66.2 (2025-10-03)
|
|
58
|
+
|
|
59
|
+
#### Bug Fixes
|
|
60
|
+
|
|
61
|
+
* **spec**
|
|
62
|
+
* update rspec keyword vs arg changes https://github.com/rspec/rspec-mocks/pull/1473 ([c1c17fc](/../../commit/c1c17fc))
|
|
63
|
+
|
|
64
|
+
* correct generators import and update specs ([d025342](/../../commit/d025342))
|
|
65
|
+
* example/animal-service/Gemfile to reduce vulnerabilities ([4dfb3f5](/../../commit/4dfb3f5))
|
|
66
|
+
* example/animal-service/Gemfile to reduce vulnerabilities ([3d8fa31](/../../commit/3d8fa31))
|
|
67
|
+
* example/zoo-app/Gemfile to reduce vulnerabilities ([5ff8945](/../../commit/5ff8945))
|
|
68
|
+
|
|
69
|
+
<a name="v1.66.1"></a>
|
|
70
|
+
### v1.66.1 (2025-01-20)
|
|
71
|
+
|
|
72
|
+
#### Bug Fixes
|
|
73
|
+
|
|
74
|
+
* HTTP_HOST headers for sinatra 4.x ([173bfb7](/../../commit/173bfb7))
|
|
75
|
+
|
|
76
|
+
<a name="v1.66.0"></a>
|
|
77
|
+
### v1.66.0 (2024-11-29)
|
|
78
|
+
|
|
79
|
+
#### Features
|
|
80
|
+
|
|
81
|
+
* **generators**
|
|
82
|
+
* Add more generators as per spec ([f55adf1](/../../commit/f55adf1))
|
|
83
|
+
* Pass context and add ProviderState generator ([7a1cf3b](/../../commit/7a1cf3b))
|
|
84
|
+
|
|
85
|
+
#### Bug Fixes
|
|
86
|
+
|
|
87
|
+
* add HTTPS_HOST header if invoking a Sinatra app ([ed44189](/../../commit/ed44189))
|
|
88
|
+
* example/animal-service/Gemfile to reduce vulnerabilities ([981ebee](/../../commit/981ebee))
|
|
89
|
+
|
|
90
|
+
<a name="v1.65.3"></a>
|
|
91
|
+
### v1.65.3 (2024-10-23)
|
|
92
|
+
|
|
93
|
+
#### Bug Fixes
|
|
94
|
+
|
|
95
|
+
* **test**
|
|
96
|
+
* explicitly require ostruct as non stdlib in ruby 3.5.x ([c9a8525](/../../commit/c9a8525))
|
|
97
|
+
|
|
98
|
+
<a name="v1.65.2"></a>
|
|
99
|
+
### v1.65.2 (2024-09-26)
|
|
100
|
+
|
|
101
|
+
<a name="v1.65.1"></a>
|
|
102
|
+
### v1.65.1 (2024-08-08)
|
|
103
|
+
|
|
104
|
+
#### Bug Fixes
|
|
105
|
+
|
|
106
|
+
* set color codes even on dumb terms (prev behaviour) ([4f01bc9](/../../commit/4f01bc9))
|
|
107
|
+
* use .empty? in handling_no_pacts_found ([43bce74](/../../commit/43bce74))
|
|
108
|
+
|
|
109
|
+
<a name="v1.65.0"></a>
|
|
110
|
+
### v1.65.0 (2024-08-06)
|
|
111
|
+
|
|
112
|
+
#### Features
|
|
113
|
+
|
|
114
|
+
* support app_version_branch in MessageProviderDSL ([1653128](/../../commit/1653128))
|
|
115
|
+
* allow setting fail_if_no_pacts_found in honours_pacts_from_pact_broker ([f0f142e](/../../commit/f0f142e))
|
|
116
|
+
|
|
117
|
+
#### Bug Fixes
|
|
118
|
+
|
|
119
|
+
* handle case in no_pacts_found - undefined method empty? for nil ([0145d2d](/../../commit/0145d2d))
|
|
120
|
+
* remove unused ConsumerContractBuilder contract_details accessor ([fb5488e](/../../commit/fb5488e))
|
|
121
|
+
* example/animal-service/Gemfile to reduce vulnerabilities ([2bbefe2](/../../commit/2bbefe2))
|
|
122
|
+
* example/zoo-app/Gemfile to reduce vulnerabilities ([e10f914](/../../commit/e10f914))
|
|
123
|
+
* example/animal-service/Gemfile to reduce vulnerabilities ([7560918](/../../commit/7560918))
|
|
124
|
+
* example/zoo-app/Gemfile to reduce vulnerabilities ([b4cbe85](/../../commit/b4cbe85))
|
|
125
|
+
* example/animal-service/Gemfile to reduce vulnerabilities ([4028087](/../../commit/4028087))
|
|
126
|
+
* ConsumerContractBuilder exposing incorrect field ([c805c3e](/../../commit/c805c3e))
|
|
127
|
+
|
|
128
|
+
* **test**
|
|
129
|
+
* alias Rack/Rackup WEBrick handler in x509 test for backwards compat ([cc77498](/../../commit/cc77498))
|
|
130
|
+
|
|
1
131
|
<a name="v1.64.0"></a>
|
|
2
132
|
### v1.64.0 (2023-11-09)
|
|
3
133
|
|
data/lib/pact/hal/http_client.rb
CHANGED
|
@@ -6,6 +6,18 @@ require 'openssl'
|
|
|
6
6
|
|
|
7
7
|
module Pact
|
|
8
8
|
module Hal
|
|
9
|
+
class RetriableHttpStatusError < StandardError
|
|
10
|
+
RETRIABLE_STATUS_CODES = [502, 503, 504].freeze
|
|
11
|
+
|
|
12
|
+
attr_reader :status_code, :response_body
|
|
13
|
+
|
|
14
|
+
def initialize status_code, response_body
|
|
15
|
+
@status_code = status_code
|
|
16
|
+
@response_body = response_body
|
|
17
|
+
super("HTTP #{status_code} error: #{response_body}")
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
9
21
|
class HttpClient
|
|
10
22
|
attr_accessor :username, :password, :verbose, :token
|
|
11
23
|
|
|
@@ -65,9 +77,15 @@ module Pact
|
|
|
65
77
|
end
|
|
66
78
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
|
67
79
|
end
|
|
68
|
-
http.start do |http|
|
|
80
|
+
result = http.start do |http|
|
|
69
81
|
http.request request
|
|
70
82
|
end
|
|
83
|
+
|
|
84
|
+
# Raise error on specific 5xx status codes to trigger retry
|
|
85
|
+
status_code = result.code.to_i
|
|
86
|
+
raise RetriableHttpStatusError.new(status_code, result.body) if RetriableHttpStatusError::RETRIABLE_STATUS_CODES.include?(status_code)
|
|
87
|
+
|
|
88
|
+
result
|
|
71
89
|
end
|
|
72
90
|
Response.new(response)
|
|
73
91
|
end
|
|
@@ -39,15 +39,17 @@ module Pact
|
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
def call
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
42
|
+
handling_no_pacts_found do
|
|
43
|
+
if index.can?(PACTS_FOR_VERIFICATION_RELATION) || index.can?(PACTS_FOR_VERIFICATION_RELATION_BETA)
|
|
44
|
+
log_message
|
|
45
|
+
pacts_for_verification
|
|
46
|
+
else
|
|
47
|
+
old_selectors = consumer_version_selectors.collect do | selector |
|
|
48
|
+
{ name: selector[:tag], all: !selector[:latest], fallback: selector[:fallbackTag]}
|
|
49
|
+
end
|
|
50
|
+
# Fall back to old method of fetching pacts
|
|
51
|
+
FetchPacts.call(provider, old_selectors, broker_base_url, http_client_options)
|
|
48
52
|
end
|
|
49
|
-
# Fall back to old method of fetching pacts
|
|
50
|
-
FetchPacts.call(provider, old_selectors, broker_base_url, http_client_options)
|
|
51
53
|
end
|
|
52
54
|
end
|
|
53
55
|
|
|
@@ -96,6 +98,15 @@ module Pact
|
|
|
96
98
|
def log_message
|
|
97
99
|
Pact.configuration.output_stream.puts "INFO: #{pact_selection_description(provider, consumer_version_selectors, options, broker_base_url)}"
|
|
98
100
|
end
|
|
101
|
+
|
|
102
|
+
def handling_no_pacts_found
|
|
103
|
+
pacts_found = yield
|
|
104
|
+
raise "No pacts found to verify" if pacts_found.empty? && options[:fail_if_no_pacts_found] != false
|
|
105
|
+
if pacts_found.empty? && options[:fail_if_no_pacts_found] == false
|
|
106
|
+
Pact.configuration.output_stream.puts "WARN: No pacts found to verify & fail_if_no_pacts_found is set to false."
|
|
107
|
+
end
|
|
108
|
+
pacts_found
|
|
109
|
+
end
|
|
99
110
|
end
|
|
100
111
|
end
|
|
101
112
|
end
|
|
@@ -34,6 +34,10 @@ module Pact
|
|
|
34
34
|
self.tags = tags
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
+
def app_version_branch branch
|
|
38
|
+
self.branch = branch
|
|
39
|
+
end
|
|
40
|
+
|
|
37
41
|
def publish_verification_results publish_verification_results
|
|
38
42
|
self.publish_verification_results = publish_verification_results
|
|
39
43
|
Pact::RSpec.with_rspec_2 do
|
|
@@ -15,7 +15,7 @@ module Pact
|
|
|
15
15
|
# in parent scope, it will clash with these ones,
|
|
16
16
|
# so put an underscore in front of the name to be safer.
|
|
17
17
|
|
|
18
|
-
attr_accessor :_provider_name, :_pact_broker_base_url, :_consumer_version_tags, :_provider_version_branch, :_provider_version_tags, :_basic_auth_options, :_enable_pending, :_include_wip_pacts_since, :_verbose, :_consumer_version_selectors
|
|
18
|
+
attr_accessor :_provider_name, :_pact_broker_base_url, :_consumer_version_tags, :_provider_version_branch, :_provider_version_tags, :_basic_auth_options, :_enable_pending, :_include_wip_pacts_since, :_verbose, :_consumer_version_selectors, :_fail_if_no_pacts_found
|
|
19
19
|
|
|
20
20
|
def initialize(provider_name, provider_version_branch, provider_version_tags)
|
|
21
21
|
@_provider_name = provider_name
|
|
@@ -26,6 +26,7 @@ module Pact
|
|
|
26
26
|
@_enable_pending = false
|
|
27
27
|
@_include_wip_pacts_since = nil
|
|
28
28
|
@_verbose = false
|
|
29
|
+
@_fail_if_no_pacts_found = true # CLI defaults to false, unfortunately for consistency
|
|
29
30
|
end
|
|
30
31
|
|
|
31
32
|
dsl do
|
|
@@ -46,6 +47,11 @@ module Pact
|
|
|
46
47
|
self._enable_pending = enable_pending
|
|
47
48
|
end
|
|
48
49
|
|
|
50
|
+
# Underlying code defaults to true if not specified
|
|
51
|
+
def fail_if_no_pacts_found fail_if_no_pacts_found
|
|
52
|
+
self._fail_if_no_pacts_found = fail_if_no_pacts_found
|
|
53
|
+
end
|
|
54
|
+
|
|
49
55
|
def include_wip_pacts_since since
|
|
50
56
|
self._include_wip_pacts_since = if since.respond_to?(:xmlschema)
|
|
51
57
|
since.xmlschema
|
|
@@ -74,7 +80,7 @@ module Pact
|
|
|
74
80
|
_provider_version_tags,
|
|
75
81
|
_pact_broker_base_url,
|
|
76
82
|
_basic_auth_options.merge(verbose: _verbose),
|
|
77
|
-
{ include_pending_status: _enable_pending, include_wip_pacts_since: _include_wip_pacts_since }
|
|
83
|
+
{ include_pending_status: _enable_pending, include_wip_pacts_since: _include_wip_pacts_since, fail_if_no_pacts_found: _fail_if_no_pacts_found }
|
|
78
84
|
)
|
|
79
85
|
|
|
80
86
|
Pact.provider_world.add_pact_uri_source fetch_pacts
|
|
@@ -2,15 +2,13 @@ require 'pact/provider/help/content'
|
|
|
2
2
|
require 'fileutils'
|
|
3
3
|
require 'pact/consumer/configuration'
|
|
4
4
|
require 'pact/provider/help/write'
|
|
5
|
-
require '
|
|
5
|
+
require 'rainbow'
|
|
6
6
|
|
|
7
7
|
module Pact
|
|
8
8
|
module Provider
|
|
9
9
|
module Help
|
|
10
10
|
class ConsoleText
|
|
11
11
|
|
|
12
|
-
C = ::Term::ANSIColor
|
|
13
|
-
|
|
14
12
|
def self.call reports_dir = Pact.configuration.reports_dir, options = {color: true}
|
|
15
13
|
new(reports_dir || Pact.configuration.reports_dir, options).call
|
|
16
14
|
end
|
|
@@ -46,13 +44,11 @@ module Pact
|
|
|
46
44
|
end
|
|
47
45
|
|
|
48
46
|
def error_text_coloured
|
|
49
|
-
|
|
47
|
+
Rainbow(error_text_plain).red
|
|
50
48
|
end
|
|
51
49
|
|
|
52
50
|
class ColorizeMarkdown
|
|
53
51
|
|
|
54
|
-
C = ::Term::ANSIColor
|
|
55
|
-
|
|
56
52
|
def self.call markdown
|
|
57
53
|
markdown.split("\n").collect do | line |
|
|
58
54
|
if line.start_with?("# ")
|
|
@@ -66,11 +62,11 @@ module Pact
|
|
|
66
62
|
end
|
|
67
63
|
|
|
68
64
|
def self.yellow_underling string
|
|
69
|
-
|
|
65
|
+
Rainbow(string).yellow.underline
|
|
70
66
|
end
|
|
71
67
|
|
|
72
68
|
def self.green string
|
|
73
|
-
|
|
69
|
+
Rainbow(string).green
|
|
74
70
|
end
|
|
75
71
|
|
|
76
72
|
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
require 'pact/consumer/configuration'
|
|
2
|
-
require '
|
|
2
|
+
require 'rainbow'
|
|
3
3
|
require 'pathname'
|
|
4
4
|
|
|
5
5
|
module Pact
|
|
@@ -7,8 +7,6 @@ module Pact
|
|
|
7
7
|
module Help
|
|
8
8
|
class PromptText
|
|
9
9
|
|
|
10
|
-
C = ::Term::ANSIColor
|
|
11
|
-
|
|
12
10
|
def self.call reports_dir = Pact.configuration.reports_dir, options = {color: Pact.configuration.color_enabled}
|
|
13
11
|
new(reports_dir, options).call
|
|
14
12
|
end
|
|
@@ -31,7 +29,7 @@ module Pact
|
|
|
31
29
|
end
|
|
32
30
|
|
|
33
31
|
def prompt_text_colored
|
|
34
|
-
|
|
32
|
+
Rainbow(prompt_text_plain).yellow
|
|
35
33
|
end
|
|
36
34
|
|
|
37
35
|
def rake_args
|
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
require '
|
|
1
|
+
require 'rainbow'
|
|
2
2
|
require 'pact/term'
|
|
3
3
|
|
|
4
4
|
module Pact
|
|
5
5
|
module Matchers
|
|
6
6
|
module Messages
|
|
7
7
|
|
|
8
|
-
C = ::Term::ANSIColor
|
|
9
|
-
|
|
10
8
|
def match_term_failure_message diff, actual, diff_formatter, color_enabled
|
|
11
9
|
actual_string = String === actual ? actual : actual.to_json
|
|
12
|
-
maybe_coloured_string = color_enabled ?
|
|
10
|
+
maybe_coloured_string = color_enabled ? Rainbow(actual_string).white : actual_string
|
|
13
11
|
message = "Actual: #{maybe_coloured_string}\n\n"
|
|
14
12
|
formatted_diff = diff_formatter.call(diff)
|
|
15
13
|
message + colorize_if_enabled(formatted_diff, color_enabled)
|
|
@@ -40,7 +38,7 @@ module Pact
|
|
|
40
38
|
# RSpec wraps each line in the failure message with failure_color, turning it red.
|
|
41
39
|
# To ensure the lines in the diff that should be white, stay white, put an
|
|
42
40
|
# ANSI reset at the start of each line.
|
|
43
|
-
formatted_diff.split("\n").collect{ |line|
|
|
41
|
+
formatted_diff.split("\n").collect{ |line|"\e[0m#{line}" }.join("\n")
|
|
44
42
|
else
|
|
45
43
|
formatted_diff
|
|
46
44
|
end
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
require '
|
|
1
|
+
require 'rainbow'
|
|
2
2
|
|
|
3
3
|
module Pact
|
|
4
4
|
module Provider
|
|
5
5
|
class PrintMissingProviderStates
|
|
6
6
|
|
|
7
|
-
C = ::Term::ANSIColor
|
|
8
|
-
|
|
9
7
|
# Hash of consumer names to array of names of missing provider states
|
|
10
8
|
def self.call missing_provider_states, output
|
|
11
9
|
if missing_provider_states.any?
|
|
@@ -15,8 +13,8 @@ module Pact
|
|
|
15
13
|
|
|
16
14
|
def self.colorize string
|
|
17
15
|
lines = string.split("\n")
|
|
18
|
-
first_line =
|
|
19
|
-
other_lines =
|
|
16
|
+
first_line = Rainbow(lines[0]).cyan.underline
|
|
17
|
+
other_lines = Rainbow(lines[1..-1].join("\n")).cyan
|
|
20
18
|
first_line + "\n" + other_lines
|
|
21
19
|
end
|
|
22
20
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
require 'json'
|
|
2
2
|
require 'pact/reification'
|
|
3
3
|
require 'pact/shared/null_expectation'
|
|
4
|
+
require 'pact/generators'
|
|
4
5
|
|
|
5
6
|
module Pact
|
|
6
7
|
module Provider
|
|
@@ -10,8 +11,9 @@ module Pact
|
|
|
10
11
|
# See https://github.com/rack/rack/blob/e7d741c6282ca4cf4e01506f5681e6e6b14c0b32/SPEC#L87-89
|
|
11
12
|
NO_HTTP_PREFIX = ["CONTENT-TYPE", "CONTENT-LENGTH"]
|
|
12
13
|
|
|
13
|
-
def initialize expected_request
|
|
14
|
+
def initialize expected_request, state_params = nil
|
|
14
15
|
@expected_request = expected_request
|
|
16
|
+
@state_params = state_params
|
|
15
17
|
end
|
|
16
18
|
|
|
17
19
|
def method
|
|
@@ -19,7 +21,7 @@ module Pact
|
|
|
19
21
|
end
|
|
20
22
|
|
|
21
23
|
def path
|
|
22
|
-
expected_request.full_path
|
|
24
|
+
Pact::Generators.apply_generators(expected_request, "path", expected_request.full_path, @state_params)
|
|
23
25
|
end
|
|
24
26
|
|
|
25
27
|
def body
|
|
@@ -27,17 +29,22 @@ module Pact
|
|
|
27
29
|
when String then expected_request.body
|
|
28
30
|
when NullExpectation then ''
|
|
29
31
|
else
|
|
30
|
-
|
|
32
|
+
generated_body
|
|
31
33
|
end
|
|
32
34
|
end
|
|
33
35
|
|
|
34
36
|
def headers
|
|
35
37
|
request_headers = {}
|
|
38
|
+
# https://github.com/pact-foundation/pact-ruby/pull/327
|
|
39
|
+
request_headers.merge!('HOST' => 'localhost') if defined?(Sinatra)
|
|
36
40
|
return request_headers if expected_request.headers.is_a?(Pact::NullExpectation)
|
|
41
|
+
|
|
37
42
|
expected_request.headers.each do |key, value|
|
|
38
|
-
request_headers[
|
|
43
|
+
request_headers[key] = Pact::Reification.from_term(value)
|
|
39
44
|
end
|
|
40
|
-
|
|
45
|
+
|
|
46
|
+
request_headers = Pact::Generators.apply_generators(expected_request, "header", request_headers, @state_params)
|
|
47
|
+
request_headers.map{ |key,value| [rack_request_header_for(key), value]}.to_h
|
|
41
48
|
end
|
|
42
49
|
|
|
43
50
|
private
|
|
@@ -53,6 +60,19 @@ module Pact
|
|
|
53
60
|
end
|
|
54
61
|
end
|
|
55
62
|
|
|
63
|
+
def generated_body
|
|
64
|
+
result = Pact::Generators.apply_generators(expected_request, "body", reified_body, @state_params)
|
|
65
|
+
|
|
66
|
+
case result
|
|
67
|
+
when Hash
|
|
68
|
+
result.to_json
|
|
69
|
+
when String
|
|
70
|
+
result
|
|
71
|
+
else
|
|
72
|
+
raise "Expected body to be a String or Hash, but was #{result.class} with value #{result.inspect}"
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
56
76
|
def rack_request_header_for header
|
|
57
77
|
with_http_prefix(header.to_s.upcase).tr('-', '_')
|
|
58
78
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require 'pact/provider/print_missing_provider_states'
|
|
2
2
|
require 'rspec/core/formatters/documentation_formatter'
|
|
3
|
-
require '
|
|
3
|
+
require 'rainbow'
|
|
4
4
|
require 'pact/provider/help/prompt_text'
|
|
5
5
|
|
|
6
6
|
module Pact
|
|
@@ -13,8 +13,6 @@ module Pact
|
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
C = ::Term::ANSIColor
|
|
17
|
-
|
|
18
16
|
def dump_commands_to_rerun_failed_examples
|
|
19
17
|
return if failed_examples.empty?
|
|
20
18
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require 'pact/provider/print_missing_provider_states'
|
|
2
2
|
require 'rspec/core/formatters'
|
|
3
|
-
require '
|
|
3
|
+
require 'rainbow'
|
|
4
4
|
require 'pact/provider/help/prompt_text'
|
|
5
5
|
|
|
6
6
|
module Pact
|
|
@@ -22,8 +22,6 @@ module Pact
|
|
|
22
22
|
:example_passed, :example_pending, :example_failed
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
C = ::Term::ANSIColor
|
|
26
|
-
|
|
27
25
|
def example_group_started(notification)
|
|
28
26
|
# This is the metadata on the top level "Verifying a pact between X and Y" describe block
|
|
29
27
|
if @group_level == 0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require 'rspec/core/formatters'
|
|
2
2
|
require 'pact/provider/verification_results/publish_all'
|
|
3
|
-
require '
|
|
3
|
+
require 'rainbow'
|
|
4
4
|
require 'pact/matchers/extract_diff_messages'
|
|
5
5
|
|
|
6
6
|
module Pact
|
|
@@ -43,7 +43,7 @@ module Pact
|
|
|
43
43
|
if example.exception
|
|
44
44
|
hash[:exception] = {
|
|
45
45
|
class: example.exception.class.name,
|
|
46
|
-
message:
|
|
46
|
+
message: "\e[0m#{example.exception.message}"
|
|
47
47
|
}
|
|
48
48
|
end
|
|
49
49
|
|
data/lib/pact/provider/rspec.rb
CHANGED
|
@@ -25,6 +25,7 @@ module Pact
|
|
|
25
25
|
pact_uri = pact_source.uri
|
|
26
26
|
Pact.configuration.output_stream.puts "INFO: Reading pact at #{pact_uri}"
|
|
27
27
|
consumer_contract = Pact::ConsumerContract.from_json(pact_json)
|
|
28
|
+
|
|
28
29
|
suffix = pact_uri.metadata[:pending] ? " [PENDING]": ""
|
|
29
30
|
example_group_description = "Verifying a pact between #{consumer_contract.consumer.name} and #{consumer_contract.provider.name}#{suffix}"
|
|
30
31
|
example_group_metadata = { pactfile_uri: pact_uri, pact_criteria: options[:criteria] }
|
|
@@ -77,7 +78,6 @@ module Pact
|
|
|
77
78
|
end
|
|
78
79
|
|
|
79
80
|
def describe_interaction interaction, options
|
|
80
|
-
|
|
81
81
|
# pact_uri and pact_interaction are used by
|
|
82
82
|
# Pact::Provider::RSpec::PactBrokerFormatter
|
|
83
83
|
|
|
@@ -103,8 +103,9 @@ module Pact
|
|
|
103
103
|
before do | example |
|
|
104
104
|
interaction_context.run_once :before do
|
|
105
105
|
Pact.configuration.logger.info "Running example '#{Pact::RSpec.full_description(example)}'"
|
|
106
|
-
set_up_provider_states interaction.provider_states, options[:consumer]
|
|
107
|
-
|
|
106
|
+
provider_states_result = set_up_provider_states interaction.provider_states, options[:consumer]
|
|
107
|
+
state_params = provider_states_result[interaction.provider_state];
|
|
108
|
+
replay_interaction interaction, options[:request_customizer], state_params
|
|
108
109
|
interaction_context.last_response = last_response
|
|
109
110
|
end
|
|
110
111
|
end
|
|
@@ -129,6 +130,7 @@ module Pact
|
|
|
129
130
|
include Pact::RSpec::Matchers
|
|
130
131
|
extend Pact::Matchers::Messages
|
|
131
132
|
|
|
133
|
+
|
|
132
134
|
let(:expected_contents) { expected_response.body[:contents].as_json }
|
|
133
135
|
let(:response) { interaction_context.last_response }
|
|
134
136
|
let(:differ) { Pact.configuration.body_differ_for_content_type diff_content_type }
|
|
@@ -14,8 +14,8 @@ module Pact
|
|
|
14
14
|
include Pact::Logging
|
|
15
15
|
include Rack::Test::Methods
|
|
16
16
|
|
|
17
|
-
def replay_interaction interaction, request_customizer = nil
|
|
18
|
-
request = Request::Replayable.new(interaction.request)
|
|
17
|
+
def replay_interaction interaction, request_customizer = nil, state_params = nil
|
|
18
|
+
request = Request::Replayable.new(interaction.request, state_params)
|
|
19
19
|
request = request_customizer.call(request, interaction) if request_customizer
|
|
20
20
|
args = [request.path, request.body, request.headers]
|
|
21
21
|
|
|
@@ -42,11 +42,17 @@ module Pact
|
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
def set_up_provider_states provider_states, consumer, options = {}
|
|
45
|
+
provider_states_result = {};
|
|
45
46
|
# If there are no provider state, execute with an nil state to ensure global and base states are executed
|
|
46
47
|
Pact.configuration.provider_state_set_up.call(nil, consumer, options) if provider_states.nil? || provider_states.empty?
|
|
47
48
|
provider_states.each do | provider_state |
|
|
48
|
-
Pact.configuration.provider_state_set_up.call(provider_state.name, consumer, options.merge(params: provider_state.params))
|
|
49
|
+
result = Pact.configuration.provider_state_set_up.call(provider_state.name, consumer, options.merge(params: provider_state.params))
|
|
50
|
+
if result.is_a?(Hash)
|
|
51
|
+
provider_states_result[provider_state.name] = result
|
|
52
|
+
end
|
|
49
53
|
end
|
|
54
|
+
|
|
55
|
+
provider_states_result
|
|
50
56
|
end
|
|
51
57
|
|
|
52
58
|
def tear_down_provider_states provider_states, consumer, options = {}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pact
|
|
4
|
+
module V2
|
|
5
|
+
class Configuration
|
|
6
|
+
attr_reader :before_provider_state_proc, :after_provider_state_proc
|
|
7
|
+
|
|
8
|
+
class GlobalProviderConfigurationError < ::Pact::V2::Error; end
|
|
9
|
+
|
|
10
|
+
def before_provider_state_setup(&block)
|
|
11
|
+
raise GlobalProviderConfigurationError, "no block given" unless block
|
|
12
|
+
|
|
13
|
+
@before_provider_state_proc = block
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def after_provider_state_teardown(&block)
|
|
17
|
+
raise GlobalProviderConfigurationError, "no block given" unless block
|
|
18
|
+
|
|
19
|
+
@after_provider_state_proc = block
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|