pact 1.52.0 → 1.55.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 +4 -4
- data/CHANGELOG.md +40 -0
- data/lib/pact/pact_broker/fetch_pact_uris_for_verification.rb +9 -6
- data/lib/pact/pact_broker/pact_selection_description.rb +0 -1
- data/lib/pact/provider/configuration/pact_verification_from_broker.rb +49 -7
- data/lib/pact/provider/pact_source.rb +4 -0
- data/lib/pact/provider/pact_spec_runner.rb +8 -11
- data/lib/pact/provider/rspec.rb +21 -13
- data/lib/pact/provider/rspec/calculate_exit_code.rb +18 -0
- data/lib/pact/provider/rspec/formatter_rspec_3.rb +69 -17
- data/lib/pact/provider/verification_results/publish.rb +1 -1
- data/lib/pact/provider/world.rb +1 -1
- data/lib/pact/tasks/verification_task.rb +6 -0
- data/lib/pact/utils/string.rb +35 -0
- data/lib/pact/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b5bc7edfd2afca203239799e173f2245076887f4d38df625bbaec1ddfc655fda
|
4
|
+
data.tar.gz: c71945880bf5878c9e712b67f5b87262b7f72444b1628c12dc8eaec725022653
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b8d062c28996f29d6424577b3514baa14510b546d3d914abd8d3d12ad2c626cef82a4dd6a7251b2d05fd3fa1c593e2d86862d3dac1b91c7e6757e9b7d7eaf9d7
|
7
|
+
data.tar.gz: 73feb7558cec7e7dc0b78469951c79a0313e0df86d7c85a677963a499c633b2e0d0877783f57ac2b141bb612cf0de8f9474eb5ccf5c8e7d5d2465d22ae16b73f
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,43 @@
|
|
1
|
+
<a name="v1.55.2"></a>
|
2
|
+
### v1.55.2 (2020-09-26)
|
3
|
+
|
4
|
+
#### Bug Fixes
|
5
|
+
|
6
|
+
* correctly calculate exit code when a mix of pending and non pending pacts are verified ([533faa1](/../../commit/533faa1))
|
7
|
+
|
8
|
+
<a name="v1.55.1"></a>
|
9
|
+
### v1.55.1 (2020-09-26)
|
10
|
+
|
11
|
+
#### Bug Fixes
|
12
|
+
|
13
|
+
* remove accidentally committed debug logging ([081423e](/../../commit/081423e))
|
14
|
+
|
15
|
+
<a name="v1.55.0"></a>
|
16
|
+
### v1.55.0 (2020-09-26)
|
17
|
+
|
18
|
+
#### Features
|
19
|
+
|
20
|
+
* add consumer_version_selectors to pact verification DSL, and convert consumer_version_tags to selectors ([39e6c4a](/../../commit/39e6c4a))
|
21
|
+
* allow verification task to set just a pact_helper without a URI ([303077d](/../../commit/303077d))
|
22
|
+
* split pending and failed rerun commands into separate sections ([f839391](/../../commit/f839391))
|
23
|
+
* update output during verification so the pact info shows before the describe blocks of the pact that is being verified ([15ec231](/../../commit/15ec231))
|
24
|
+
|
25
|
+
<a name="v1.54.0"></a>
|
26
|
+
### v1.54.0 (2020-09-12)
|
27
|
+
|
28
|
+
#### Features
|
29
|
+
|
30
|
+
* use pb relation in preference to beta relation when fetching pacts for verification ([7563fcf](/../../commit/7563fcf))
|
31
|
+
* allow include_wip_pacts_since to use a Date, DateTime or Time ([dd35366](/../../commit/dd35366))
|
32
|
+
* add support for include_wip_pacts_since ([f2247b8](/../../commit/f2247b8))
|
33
|
+
|
34
|
+
<a name="v1.53.0"></a>
|
35
|
+
### v1.53.0 (2020-09-11)
|
36
|
+
|
37
|
+
#### Features
|
38
|
+
|
39
|
+
* add support for the enable_pending flag ([16866f4](/../../commit/16866f4))
|
40
|
+
|
1
41
|
<a name="v1.52.0"></a>
|
2
42
|
### v1.52.0 (2020-09-10)
|
3
43
|
|
@@ -12,7 +12,8 @@ module Pact
|
|
12
12
|
include PactSelectionDescription
|
13
13
|
attr_reader :provider, :consumer_version_selectors, :provider_version_tags, :broker_base_url, :http_client_options, :http_client, :options
|
14
14
|
|
15
|
-
PACTS_FOR_VERIFICATION_RELATION = '
|
15
|
+
PACTS_FOR_VERIFICATION_RELATION = 'pb:provider-pacts-for-verification'.freeze
|
16
|
+
PACTS_FOR_VERIFICATION_RELATION_BETA = 'beta:provider-pacts-for-verification'.freeze
|
16
17
|
PACTS = 'pacts'.freeze
|
17
18
|
HREF = 'href'.freeze
|
18
19
|
LINKS = '_links'.freeze
|
@@ -22,7 +23,7 @@ module Pact
|
|
22
23
|
def initialize(provider, consumer_version_selectors, provider_version_tags, broker_base_url, http_client_options, options = {})
|
23
24
|
@provider = provider
|
24
25
|
@consumer_version_selectors = consumer_version_selectors || []
|
25
|
-
@provider_version_tags = provider_version_tags
|
26
|
+
@provider_version_tags = [*provider_version_tags]
|
26
27
|
@http_client_options = http_client_options
|
27
28
|
@broker_base_url = broker_base_url
|
28
29
|
@http_client = Pact::Hal::HttpClient.new(http_client_options)
|
@@ -34,13 +35,15 @@ module Pact
|
|
34
35
|
end
|
35
36
|
|
36
37
|
def call
|
37
|
-
if index.can?(PACTS_FOR_VERIFICATION_RELATION)
|
38
|
+
if index.can?(PACTS_FOR_VERIFICATION_RELATION) || index.can?(PACTS_FOR_VERIFICATION_RELATION_BETA)
|
38
39
|
log_message
|
39
40
|
pacts_for_verification
|
40
41
|
else
|
42
|
+
old_selectors = consumer_version_selectors.collect do | selector |
|
43
|
+
{ name: selector[:tag], all: !selector[:latest], fallback: selector[:fallbackTag]}
|
44
|
+
end
|
41
45
|
# Fall back to old method of fetching pacts
|
42
|
-
|
43
|
-
FetchPacts.call(provider, consumer_version_tags, broker_base_url, http_client_options)
|
46
|
+
FetchPacts.call(provider, old_selectors, broker_base_url, http_client_options)
|
44
47
|
end
|
45
48
|
end
|
46
49
|
|
@@ -63,7 +66,7 @@ module Pact
|
|
63
66
|
|
64
67
|
def pacts_for_verification_entity
|
65
68
|
index
|
66
|
-
._link(PACTS_FOR_VERIFICATION_RELATION)
|
69
|
+
._link(PACTS_FOR_VERIFICATION_RELATION, PACTS_FOR_VERIFICATION_RELATION_BETA)
|
67
70
|
.expand(provider: provider)
|
68
71
|
.post!(query)
|
69
72
|
end
|
@@ -7,7 +7,6 @@ module Pact
|
|
7
7
|
if consumer_version_selectors.any?
|
8
8
|
desc = consumer_version_selectors.collect do |selector|
|
9
9
|
all_or_latest = !selector[:latest] ? "all for tag" : "latest for tag"
|
10
|
-
# TODO support fallback
|
11
10
|
fallback = selector[:fallback] || selector[:fallbackTag]
|
12
11
|
name = fallback ? "#{selector[:tag]} (or #{fallback} if not found)" : selector[:tag]
|
13
12
|
"#{all_or_latest} #{name}"
|
@@ -2,6 +2,7 @@ require 'pact/shared/dsl'
|
|
2
2
|
require 'pact/provider/world'
|
3
3
|
require 'pact/pact_broker/fetch_pact_uris_for_verification'
|
4
4
|
require 'pact/errors'
|
5
|
+
require 'pact/utils/string'
|
5
6
|
|
6
7
|
module Pact
|
7
8
|
module Provider
|
@@ -14,12 +15,15 @@ module Pact
|
|
14
15
|
# in parent scope, it will clash with these ones,
|
15
16
|
# so put an underscore in front of the name to be safer.
|
16
17
|
|
17
|
-
attr_accessor :_provider_name, :_pact_broker_base_url, :_consumer_version_tags, :_provider_version_tags, :_basic_auth_options, :_verbose
|
18
|
+
attr_accessor :_provider_name, :_pact_broker_base_url, :_consumer_version_tags, :_provider_version_tags, :_basic_auth_options, :_enable_pending, :_include_wip_pacts_since, :_verbose, :_consumer_version_selectors
|
18
19
|
|
19
20
|
def initialize(provider_name, provider_version_tags)
|
20
21
|
@_provider_name = provider_name
|
21
22
|
@_provider_version_tags = provider_version_tags
|
22
23
|
@_consumer_version_tags = []
|
24
|
+
@_consumer_version_selectors = []
|
25
|
+
@_enable_pending = false
|
26
|
+
@_include_wip_pacts_since = nil
|
23
27
|
@_verbose = false
|
24
28
|
end
|
25
29
|
|
@@ -33,6 +37,22 @@ module Pact
|
|
33
37
|
self._consumer_version_tags = *consumer_version_tags
|
34
38
|
end
|
35
39
|
|
40
|
+
def consumer_version_selectors consumer_version_selectors
|
41
|
+
self._consumer_version_selectors = *consumer_version_selectors
|
42
|
+
end
|
43
|
+
|
44
|
+
def enable_pending enable_pending
|
45
|
+
self._enable_pending = enable_pending
|
46
|
+
end
|
47
|
+
|
48
|
+
def include_wip_pacts_since since
|
49
|
+
self._include_wip_pacts_since = if since.respond_to?(:xmlschema)
|
50
|
+
since.xmlschema
|
51
|
+
else
|
52
|
+
since
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
36
56
|
def verbose verbose
|
37
57
|
self._verbose = verbose
|
38
58
|
end
|
@@ -51,19 +71,41 @@ module Pact
|
|
51
71
|
consumer_version_selectors,
|
52
72
|
_provider_version_tags,
|
53
73
|
_pact_broker_base_url,
|
54
|
-
_basic_auth_options.merge(verbose: _verbose)
|
74
|
+
_basic_auth_options.merge(verbose: _verbose),
|
75
|
+
{ include_pending_status: _enable_pending, include_wip_pacts_since: _include_wip_pacts_since }
|
55
76
|
)
|
56
77
|
|
57
78
|
Pact.provider_world.add_pact_uri_source fetch_pacts
|
58
79
|
end
|
59
80
|
|
60
81
|
def consumer_version_selectors
|
61
|
-
|
82
|
+
convert_tags_to_selectors + convert_consumer_version_selectors
|
83
|
+
end
|
84
|
+
|
85
|
+
def convert_tags_to_selectors
|
62
86
|
_consumer_version_tags.collect do | tag |
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
87
|
+
if tag.is_a?(Hash)
|
88
|
+
{
|
89
|
+
tag: tag.fetch(:name),
|
90
|
+
latest: !tag[:all],
|
91
|
+
fallbackTag: tag[:fallback]
|
92
|
+
}
|
93
|
+
elsif tag.is_a?(String)
|
94
|
+
{
|
95
|
+
tag: tag,
|
96
|
+
latest: true
|
97
|
+
}
|
98
|
+
else
|
99
|
+
raise Pact::Error.new("The value supplied for consumer_version_tags must be a String or a Hash. Found #{tag.class}")
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def convert_consumer_version_selectors
|
105
|
+
_consumer_version_selectors.collect do | selector |
|
106
|
+
selector.each_with_object({}) do | (key, value), new_selector |
|
107
|
+
new_selector[Pact::Utils::String.camelcase(key.to_s).to_sym] = value
|
108
|
+
end
|
67
109
|
end
|
68
110
|
end
|
69
111
|
|
@@ -20,6 +20,10 @@ module Pact
|
|
20
20
|
@pact_hash ||= JSON.load(pact_json, nil, { max_nesting: 50 })
|
21
21
|
end
|
22
22
|
|
23
|
+
def pending?
|
24
|
+
uri.metadata[:pending]
|
25
|
+
end
|
26
|
+
|
23
27
|
def hal_entity
|
24
28
|
http_client_keys = [:username, :password, :token]
|
25
29
|
http_client_options = uri.options.reject{ |k, _| !http_client_keys.include?(k) }
|
@@ -11,6 +11,7 @@ require 'pact/provider/verification_results/publish_all'
|
|
11
11
|
require 'pact/provider/rspec/pact_broker_formatter'
|
12
12
|
require 'pact/provider/rspec/json_formatter'
|
13
13
|
require 'pact/provider/rspec'
|
14
|
+
require 'pact/provider/rspec/calculate_exit_code'
|
14
15
|
|
15
16
|
module Pact
|
16
17
|
module Provider
|
@@ -79,6 +80,7 @@ module Pact
|
|
79
80
|
executing_with_ruby = executing_with_ruby?
|
80
81
|
|
81
82
|
config.after(:suite) do | suite |
|
83
|
+
Pact.provider_world.failed_examples = suite.reporter.failed_examples
|
82
84
|
Pact::Provider::Help::Write.call(Pact.provider_world.pact_sources) if executing_with_ruby
|
83
85
|
end
|
84
86
|
end
|
@@ -90,7 +92,12 @@ module Pact
|
|
90
92
|
::RSpec::Core::CommandLine.new(NoConfigurationOptions.new)
|
91
93
|
.run(::RSpec.configuration.output_stream, ::RSpec.configuration.error_stream)
|
92
94
|
end
|
93
|
-
|
95
|
+
|
96
|
+
if options[:ignore_failures]
|
97
|
+
0
|
98
|
+
else
|
99
|
+
Pact::Provider::RSpec::CalculateExitCode.call(pact_sources, Pact.provider_world.failed_examples)
|
100
|
+
end
|
94
101
|
end
|
95
102
|
|
96
103
|
def rspec_runner_options
|
@@ -147,8 +154,6 @@ module Pact
|
|
147
154
|
end
|
148
155
|
|
149
156
|
::RSpec.configuration.full_backtrace = @options[:full_backtrace]
|
150
|
-
|
151
|
-
::RSpec.configuration.failure_color = :yellow if pending_mode?
|
152
157
|
end
|
153
158
|
|
154
159
|
def ordered_pact_json(pact_json)
|
@@ -159,20 +164,12 @@ module Pact
|
|
159
164
|
consumer_contract.to_json
|
160
165
|
end
|
161
166
|
|
162
|
-
def all_pacts_pending?
|
163
|
-
pact_urls.all?{ | pact_url| pact_url.metadata[:pending] }
|
164
|
-
end
|
165
|
-
|
166
167
|
def class_exists? name
|
167
168
|
Kernel.const_get name
|
168
169
|
rescue NameError
|
169
170
|
false
|
170
171
|
end
|
171
172
|
|
172
|
-
def pending_mode?
|
173
|
-
(all_pacts_pending? || options[:ignore_failures])
|
174
|
-
end
|
175
|
-
|
176
173
|
def executing_with_ruby?
|
177
174
|
ENV['PACT_EXECUTING_LANGUAGE'] == 'ruby'
|
178
175
|
end
|
data/lib/pact/provider/rspec.rb
CHANGED
@@ -24,28 +24,34 @@ module Pact
|
|
24
24
|
def honour_pactfile pact_source, pact_json, options
|
25
25
|
pact_uri = pact_source.uri
|
26
26
|
Pact.configuration.output_stream.puts "INFO: Reading pact at #{pact_uri}"
|
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
|
31
|
-
end
|
32
|
-
|
33
|
-
Pact.configuration.output_stream.puts "DEBUG: Filtering interactions by: #{options[:criteria]}" if options[:criteria] && options[:criteria].any?
|
34
27
|
consumer_contract = Pact::ConsumerContract.from_json(pact_json)
|
35
28
|
suffix = pact_uri.metadata[:pending] ? " [PENDING]": ""
|
29
|
+
|
36
30
|
::RSpec.describe "Verifying a pact between #{consumer_contract.consumer.name} and #{consumer_contract.provider.name}#{suffix}", pactfile_uri: pact_uri do
|
37
|
-
honour_consumer_contract consumer_contract, options.merge(
|
31
|
+
honour_consumer_contract consumer_contract, options.merge(
|
32
|
+
pact_json: pact_json,
|
33
|
+
pact_uri: pact_uri,
|
34
|
+
pact_source: pact_source,
|
35
|
+
consumer_contract: consumer_contract,
|
36
|
+
criteria: options[:criteria]
|
37
|
+
)
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
41
|
def honour_consumer_contract consumer_contract, options = {}
|
42
|
-
describe_consumer_contract consumer_contract, options.merge(consumer: consumer_contract.consumer.name)
|
42
|
+
describe_consumer_contract consumer_contract, options.merge(consumer: consumer_contract.consumer.name, pact_context: InteractionContext.new)
|
43
43
|
end
|
44
44
|
|
45
45
|
private
|
46
46
|
|
47
47
|
def describe_consumer_contract consumer_contract, options
|
48
|
-
consumer_interactions(consumer_contract, options).
|
48
|
+
consumer_interactions(consumer_contract, options).tap{ |interactions|
|
49
|
+
if interactions.empty?
|
50
|
+
# If there are no interactions, the documentation formatter never fires to print this out,
|
51
|
+
# so print it out here.
|
52
|
+
Pact.configuration.output_stream.puts "DEBUG: All interactions for #{options[:pact_uri]} have been filtered out by criteria: #{options[:criteria]}" if options[:criteria] && options[:criteria].any?
|
53
|
+
end
|
54
|
+
}.each do |interaction|
|
49
55
|
describe_interaction_with_provider_state interaction, options
|
50
56
|
end
|
51
57
|
end
|
@@ -54,7 +60,7 @@ module Pact
|
|
54
60
|
if options[:criteria].nil?
|
55
61
|
consumer_contract.interactions
|
56
62
|
else
|
57
|
-
consumer_contract.find_interactions
|
63
|
+
consumer_contract.find_interactions(options[:criteria])
|
58
64
|
end
|
59
65
|
end
|
60
66
|
|
@@ -83,13 +89,15 @@ module Pact
|
|
83
89
|
pact_interaction_example_description: interaction_description_for_rerun_command(interaction),
|
84
90
|
pact_uri: options[:pact_uri],
|
85
91
|
pact_source: options[:pact_source],
|
86
|
-
pact_ignore_failures: options[:
|
87
|
-
pact_consumer_contract: options[:consumer_contract]
|
92
|
+
pact_ignore_failures: options[:pact_source].pending? || options[:ignore_failures],
|
93
|
+
pact_consumer_contract: options[:consumer_contract],
|
94
|
+
pact_criteria: options[:criteria]
|
88
95
|
}
|
89
96
|
|
90
97
|
describe description_for(interaction), metadata do
|
91
98
|
|
92
99
|
interaction_context = InteractionContext.new
|
100
|
+
pact_context = options[:pact_context]
|
93
101
|
|
94
102
|
before do | example |
|
95
103
|
interaction_context.run_once :before do
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Pact
|
2
|
+
module Provider
|
3
|
+
module RSpec
|
4
|
+
module CalculateExitCode
|
5
|
+
def self.call(pact_sources, failed_examples)
|
6
|
+
any_non_pending_failures = pact_sources.any? do |pact_source|
|
7
|
+
if pact_source.pending?
|
8
|
+
nil
|
9
|
+
else
|
10
|
+
failed_examples.select { |e| e.metadata[:pact_source] == pact_source }.any?
|
11
|
+
end
|
12
|
+
end
|
13
|
+
any_non_pending_failures ? 1 : 0
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -24,6 +24,25 @@ module Pact
|
|
24
24
|
|
25
25
|
C = ::Term::ANSIColor
|
26
26
|
|
27
|
+
def example_group_started(notification)
|
28
|
+
if @group_level == 0
|
29
|
+
Pact.configuration.output_stream.puts
|
30
|
+
pact_uri = notification.group.metadata[:pactfile_uri]
|
31
|
+
::RSpec.configuration.failure_color = pact_uri.metadata[:pending] ? :yellow : :red
|
32
|
+
|
33
|
+
if pact_uri.metadata[:notices]
|
34
|
+
pact_uri.metadata[:notices].before_verification_notices_text.each do | text |
|
35
|
+
Pact.configuration.output_stream.puts("DEBUG: #{text}")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
criteria = notification.group.metadata[:pact_criteria]
|
40
|
+
Pact.configuration.output_stream.puts "DEBUG: Filtering interactions by: #{criteria}" if criteria && criteria.any?
|
41
|
+
end
|
42
|
+
super
|
43
|
+
end
|
44
|
+
|
45
|
+
|
27
46
|
def dump_summary(summary)
|
28
47
|
output.puts "\n" + colorized_totals_line(summary)
|
29
48
|
return if summary.failure_count == 0
|
@@ -35,28 +54,26 @@ module Pact
|
|
35
54
|
private
|
36
55
|
|
37
56
|
def interactions_count(summary)
|
38
|
-
summary.examples.collect{ |e| e
|
57
|
+
summary.examples.collect{ |e| interaction_unique_key(e) }.uniq.size
|
39
58
|
end
|
40
59
|
|
41
60
|
def failed_interactions_count(summary)
|
42
|
-
summary.
|
61
|
+
failed_interaction_examples(summary).size
|
43
62
|
end
|
44
63
|
|
45
|
-
def
|
46
|
-
summary.
|
64
|
+
def pending_interactions_count(summary)
|
65
|
+
pending_interaction_examples(summary).size
|
47
66
|
end
|
48
67
|
|
49
68
|
def failure_title summary
|
50
|
-
|
51
|
-
"#{failed_interactions_count(summary)} pending"
|
52
|
-
else
|
53
|
-
::RSpec::Core::Formatters::Helpers.pluralize(failed_interactions_count(summary), "failure")
|
54
|
-
end
|
69
|
+
::RSpec::Core::Formatters::Helpers.pluralize(failed_interactions_count(summary), "failure")
|
55
70
|
end
|
56
71
|
|
57
72
|
def totals_line summary
|
58
73
|
line = ::RSpec::Core::Formatters::Helpers.pluralize(interactions_count(summary), "interaction")
|
59
74
|
line << ", " << failure_title(summary)
|
75
|
+
pending_count = pending_interactions_count(summary)
|
76
|
+
line << ", " << "#{pending_count} pending" if pending_count > 0
|
60
77
|
line
|
61
78
|
end
|
62
79
|
|
@@ -69,13 +86,20 @@ module Pact
|
|
69
86
|
end
|
70
87
|
|
71
88
|
def print_rerun_commands summary
|
72
|
-
if
|
89
|
+
if pending_interactions_count(summary) > 0
|
90
|
+
set_rspec_failure_color(:yellow)
|
73
91
|
output.puts("\nPending interactions: (Failures listed here are expected and do not affect your suite's status)\n\n")
|
74
|
-
|
75
|
-
|
92
|
+
interaction_rerun_commands(pending_interaction_examples(summary)).each do | message |
|
93
|
+
output.puts(message)
|
94
|
+
end
|
95
|
+
set_rspec_failure_color(:red)
|
76
96
|
end
|
77
|
-
|
78
|
-
|
97
|
+
|
98
|
+
if failed_interactions_count(summary) > 0
|
99
|
+
output.puts("\nFailed interactions:\n\n")
|
100
|
+
interaction_rerun_commands(failed_interaction_examples(summary)).each do | message |
|
101
|
+
output.puts(message)
|
102
|
+
end
|
79
103
|
end
|
80
104
|
end
|
81
105
|
|
@@ -85,10 +109,34 @@ module Pact
|
|
85
109
|
end
|
86
110
|
end
|
87
111
|
|
88
|
-
def
|
89
|
-
summary.
|
112
|
+
def pending_interaction_examples(summary)
|
113
|
+
one_failed_example_per_interaction(summary).select do | example |
|
114
|
+
example.metadata[:pactfile_uri].metadata[:pending]
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def failed_interaction_examples(summary)
|
119
|
+
one_failed_example_per_interaction(summary).select do | example |
|
120
|
+
!example.metadata[:pactfile_uri].metadata[:pending]
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def one_failed_example_per_interaction(summary)
|
125
|
+
summary.failed_examples.group_by{| e| interaction_unique_key(e)}.values.collect(&:first)
|
126
|
+
end
|
127
|
+
|
128
|
+
def interaction_rerun_commands examples
|
129
|
+
examples.collect do |example|
|
90
130
|
interaction_rerun_command_for example
|
91
|
-
end.
|
131
|
+
end.compact
|
132
|
+
end
|
133
|
+
|
134
|
+
def interaction_unique_key(example)
|
135
|
+
# pending is just to make the counting easier, it isn't required for the unique key
|
136
|
+
{
|
137
|
+
pactfile_uri: example.metadata[:pactfile_uri],
|
138
|
+
index: example.metadata[:pact_interaction].index,
|
139
|
+
}
|
92
140
|
end
|
93
141
|
|
94
142
|
def interaction_rerun_command_for example
|
@@ -137,6 +185,10 @@ module Pact
|
|
137
185
|
def executing_with_ruby?
|
138
186
|
ENV['PACT_EXECUTING_LANGUAGE'] == 'ruby'
|
139
187
|
end
|
188
|
+
|
189
|
+
def set_rspec_failure_color color
|
190
|
+
::RSpec.configuration.failure_color = color
|
191
|
+
end
|
140
192
|
end
|
141
193
|
end
|
142
194
|
end
|
@@ -81,7 +81,7 @@ module Pact
|
|
81
81
|
Pact.configuration.output_stream.puts "INFO: Tagging version #{provider_application_version} of #{provider_name} as #{tag.inspect}"
|
82
82
|
tag_entity = tag_link.expand(version: provider_application_version, tag: tag).put
|
83
83
|
unless tag_entity.success?
|
84
|
-
raise PublicationError.new("Error returned from tagging request
|
84
|
+
raise PublicationError.new("Error returned from tagging request: status=#{tag_entity.response.code} body=#{tag_entity.response.body}")
|
85
85
|
end
|
86
86
|
end
|
87
87
|
end
|
data/lib/pact/provider/world.rb
CHANGED
@@ -31,6 +31,7 @@ module Pact
|
|
31
31
|
attr_reader :pact_spec_configs
|
32
32
|
attr_accessor :rspec_opts
|
33
33
|
attr_accessor :ignore_failures
|
34
|
+
attr_accessor :_pact_helper
|
34
35
|
|
35
36
|
def initialize(name)
|
36
37
|
@rspec_opts = nil
|
@@ -41,6 +42,10 @@ module Pact
|
|
41
42
|
rake_task
|
42
43
|
end
|
43
44
|
|
45
|
+
def pact_helper(pact_helper)
|
46
|
+
@pact_spec_configs << { pact_helper: pact_helper }
|
47
|
+
end
|
48
|
+
|
44
49
|
def uri(uri, options = {})
|
45
50
|
@pact_spec_configs << {uri: uri, pact_helper: options[:pact_helper]}
|
46
51
|
end
|
@@ -82,6 +87,7 @@ module Pact
|
|
82
87
|
Pact::TaskHelper.handle_verification_failure do
|
83
88
|
exit_statuses.count{ | status | status != 0 }
|
84
89
|
end
|
90
|
+
|
85
91
|
end
|
86
92
|
end
|
87
93
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# Can't use refinements because of Travelling Ruby
|
2
|
+
|
3
|
+
module Pact
|
4
|
+
module Utils
|
5
|
+
module String
|
6
|
+
|
7
|
+
extend self
|
8
|
+
|
9
|
+
# ripped from rubyworks/facets, thank you
|
10
|
+
def camelcase(string, *separators)
|
11
|
+
case separators.first
|
12
|
+
when Symbol, TrueClass, FalseClass, NilClass
|
13
|
+
first_letter = separators.shift
|
14
|
+
end
|
15
|
+
|
16
|
+
separators = ['_', '\s'] if separators.empty?
|
17
|
+
|
18
|
+
str = string.dup
|
19
|
+
|
20
|
+
separators.each do |s|
|
21
|
+
str = str.gsub(/(?:#{s}+)([a-z])/){ $1.upcase }
|
22
|
+
end
|
23
|
+
|
24
|
+
case first_letter
|
25
|
+
when :upper, true
|
26
|
+
str = str.gsub(/(\A|\s)([a-z])/){ $1 + $2.upcase }
|
27
|
+
when :lower, false
|
28
|
+
str = str.gsub(/(\A|\s)([A-Z])/){ $1 + $2.downcase }
|
29
|
+
end
|
30
|
+
|
31
|
+
str
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/pact/version.rb
CHANGED
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.55.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: 2020-09-
|
15
|
+
date: 2020-09-26 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: rspec
|
@@ -352,6 +352,7 @@ files:
|
|
352
352
|
- lib/pact/provider/request.rb
|
353
353
|
- lib/pact/provider/rspec.rb
|
354
354
|
- lib/pact/provider/rspec/backtrace_formatter.rb
|
355
|
+
- lib/pact/provider/rspec/calculate_exit_code.rb
|
355
356
|
- lib/pact/provider/rspec/custom_options_file
|
356
357
|
- lib/pact/provider/rspec/formatter_rspec_2.rb
|
357
358
|
- lib/pact/provider/rspec/formatter_rspec_3.rb
|
@@ -377,6 +378,7 @@ files:
|
|
377
378
|
- lib/pact/tasks/verification_task.rb
|
378
379
|
- lib/pact/templates/help.erb
|
379
380
|
- lib/pact/templates/provider_state.erb
|
381
|
+
- lib/pact/utils/string.rb
|
380
382
|
- lib/pact/version.rb
|
381
383
|
- lib/tasks/pact.rake
|
382
384
|
- pact.gemspec
|