pact-support 1.6.6 → 1.7.0.alpha.1
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 +0 -26
- data/lib/pact/consumer_contract/consumer_contract.rb +1 -5
- data/lib/pact/consumer_contract/interaction.rb +135 -56
- data/lib/pact/consumer_contract/pact_file.rb +2 -2
- data/lib/pact/matching_rules/merge.rb +1 -1
- data/lib/pact/matching_rules/v3/merge.rb +18 -34
- data/lib/pact/specification_version.rb +1 -1
- data/lib/pact/support/version.rb +1 -1
- data/spec/integration/matching_rules_extract_and_merge_spec.rb +4 -41
- data/spec/lib/pact/consumer_contract/consumer_contract_spec.rb +0 -20
- data/spec/lib/pact/consumer_contract/interaction_spec.rb +51 -0
- data/spec/lib/pact/matching_rules/v3/merge_spec.rb +3 -25
- metadata +4 -11
- data/lib/pact/consumer_contract/interaction_parser.rb +0 -23
- data/lib/pact/consumer_contract/interaction_v2_parser.rb +0 -28
- data/lib/pact/consumer_contract/interaction_v3_parser.rb +0 -61
- data/spec/fixtures/not-a-pact.json +0 -3
- data/spec/lib/pact/consumer_contract/interaction_parser_spec.rb +0 -62
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ad9d08da6cd0f2b5a4916c2f5c12f7749aed29c7
|
4
|
+
data.tar.gz: 740000cf408626229d5cfd34d445dcf9856285fe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 618a7e49e43b611c6b7435f94bfe6bc5dba1162d33760a2e4c6643a8b088535354b7457d41e25e292573a87d3f6d126f3ea50f0a8005f4c3a80e7b8d480b0659
|
7
|
+
data.tar.gz: 7ebdf91b188ca969ecd0cfaf5bb5d516714f3e2096956cfe07c7389020f678ee0d196c03f5aaa6fa6195adf9eed681ffe0c5aadd5585e61610749e9526e74b5e
|
data/CHANGELOG.md
CHANGED
@@ -1,29 +1,3 @@
|
|
1
|
-
<a name="v1.6.6"></a>
|
2
|
-
### v1.6.6 (2018-07-25)
|
3
|
-
|
4
|
-
|
5
|
-
#### Bug Fixes
|
6
|
-
|
7
|
-
* correctly handle an 'each like' inside a 'like' ([7dc76dc](/../../commit/7dc76dc))
|
8
|
-
|
9
|
-
|
10
|
-
<a name="v1.6.5"></a>
|
11
|
-
### v1.6.5 (2018-07-23)
|
12
|
-
|
13
|
-
|
14
|
-
#### Features
|
15
|
-
|
16
|
-
* use 0 as the nil pact specification version ([88e4750](/../../commit/88e4750))
|
17
|
-
* reify StringWithMatchingRules to a String ([a025dd3](/../../commit/a025dd3))
|
18
|
-
* parse String response and request bodies to StringWithMatchingRules to support pact-xml ([a9fbb58](/../../commit/a9fbb58))
|
19
|
-
* add custom contract parsers to front of pact parsers list so that customised parsers are tried first ([babc319](/../../commit/babc319))
|
20
|
-
|
21
|
-
|
22
|
-
#### Bug Fixes
|
23
|
-
|
24
|
-
* show a more helpful error when attempting to parse a URI that is not a pact ([a8ba1ed](/../../commit/a8ba1ed))
|
25
|
-
|
26
|
-
|
27
1
|
<a name="v1.6.4"></a>
|
28
2
|
### v1.6.4 (2018-07-14)
|
29
3
|
|
@@ -14,8 +14,6 @@ require 'pact/consumer_contract/http_consumer_contract_parser'
|
|
14
14
|
|
15
15
|
module Pact
|
16
16
|
|
17
|
-
class UnrecognizePactFormatError < ::Pact::Error; end
|
18
|
-
|
19
17
|
class ConsumerContract
|
20
18
|
|
21
19
|
include SymbolizeKeys
|
@@ -44,7 +42,7 @@ module Pact
|
|
44
42
|
parsers.each do | parser |
|
45
43
|
return parser.call(hash) if parser.can_parse?(hash)
|
46
44
|
end
|
47
|
-
raise Pact::
|
45
|
+
raise Pact::Error.new("No consumer contract parser found for hash: #{hash}")
|
48
46
|
end
|
49
47
|
|
50
48
|
def self.from_json string
|
@@ -54,8 +52,6 @@ module Pact
|
|
54
52
|
|
55
53
|
def self.from_uri uri, options = {}
|
56
54
|
from_json(Pact::PactFile.read(uri, options))
|
57
|
-
rescue UnrecognizePactFormatError
|
58
|
-
raise Pact::UnrecognizePactFormatError.new("This document does not use a recognised Pact format. Please check that #{uri} is a valid pact file.")
|
59
55
|
end
|
60
56
|
|
61
57
|
def self.maintain_backwards_compatiblity_with_producer_keys string
|
@@ -1,71 +1,150 @@
|
|
1
|
+
require 'pact/consumer_contract/request'
|
2
|
+
require 'pact/consumer_contract/response'
|
3
|
+
require 'pact/symbolize_keys'
|
1
4
|
require 'pact/shared/active_support_support'
|
2
|
-
require 'pact/
|
5
|
+
require 'pact/matching_rules'
|
6
|
+
require 'pact/errors'
|
7
|
+
require 'pact/specification_version'
|
8
|
+
require 'pact/consumer_contract/string_with_matching_rules'
|
3
9
|
|
4
10
|
module Pact
|
5
11
|
class Interaction
|
6
12
|
include ActiveSupportSupport
|
13
|
+
include SymbolizeKeys
|
7
14
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
15
|
+
attr_accessor :description, :request, :response, :provider_state
|
16
|
+
|
17
|
+
def initialize attributes = {}
|
18
|
+
@description = attributes[:description]
|
19
|
+
@request = attributes[:request]
|
20
|
+
@response = attributes[:response]
|
21
|
+
@provider_state = attributes[:provider_state] || attributes[:providerState]
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.from_hash hash, options = {}
|
25
|
+
pact_specification_version = options[:pact_specification_version] || Pact::SpecificationVersion::NIL_VERSION
|
26
|
+
case pact_specification_version.major
|
27
|
+
when nil, 0, 1, 2 then parse_v2_interaction(hash, pact_specification_version: pact_specification_version)
|
28
|
+
else parse_v3_interaction(hash, pact_specification_version: pact_specification_version)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.parse_v2_interaction hash, options
|
33
|
+
request = parse_v2_request(hash['request'], options)
|
34
|
+
response = parse_v2_response(hash['response'], options)
|
35
|
+
new(symbolize_keys(hash).merge(request: request, response: response))
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.parse_v3_interaction hash, options
|
39
|
+
request = parse_v3_request(hash['request'], options)
|
40
|
+
response = parse_v3_response(hash['response'], options)
|
41
|
+
new(symbolize_keys(hash).merge(request: request, response: response))
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.parse_v2_request request_hash, options
|
45
|
+
request_hash = Pact::MatchingRules.merge(request_hash, request_hash['matchingRules'], options)
|
46
|
+
Pact::Request::Expected.from_hash(request_hash)
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.parse_v2_response response_hash, options
|
50
|
+
response_hash = Pact::MatchingRules.merge(response_hash, response_hash['matchingRules'], options)
|
51
|
+
Pact::Response.from_hash(response_hash)
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.parse_v3_request request_hash, options
|
55
|
+
request_matching_rules = request_hash['matchingRules'] || {}
|
56
|
+
if request_hash['body'].is_a?(String)
|
57
|
+
parse_request_with_string_body(request_hash, request_matching_rules['body'] || {}, options)
|
58
|
+
else
|
59
|
+
parse_v3_request_with_non_string_body(request_hash, request_matching_rules, options)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.parse_request_with_string_body request_hash, request_matching_rules, options
|
64
|
+
string_with_matching_rules = StringWithMatchingRules.new(request_hash['body'], options[:pact_specification_version], request_matching_rules)
|
65
|
+
Pact::Request::Expected.from_hash(request_hash.merge('body' => string_with_matching_rules))
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.parse_v3_response response_hash, options
|
69
|
+
response_matching_rules = response_hash['matchingRules'] || {}
|
70
|
+
if response_hash['body'].is_a?(String)
|
71
|
+
parse_response_with_string_body(response_hash, response_matching_rules['body'] || {}, options)
|
72
|
+
else
|
73
|
+
parse_v3_response_with_non_string_body(response_hash, response_matching_rules, options)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.parse_response_with_string_body response_hash, response_matching_rules, options
|
78
|
+
string_with_matching_rules = StringWithMatchingRules.new(response_hash['body'], options[:pact_specification_version], response_matching_rules)
|
79
|
+
Pact::Response.from_hash(response_hash.merge('body' => string_with_matching_rules))
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.parse_v3_request_with_non_string_body request_hash, request_matching_rules, options
|
83
|
+
request_hash = request_hash.keys.each_with_object({}) do | key, new_hash |
|
84
|
+
new_hash[key] = Pact::MatchingRules.merge(request_hash[key], request_matching_rules[key], options)
|
85
|
+
end
|
86
|
+
Pact::Request::Expected.from_hash(request_hash)
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.parse_v3_response_with_non_string_body response_hash, response_matching_rules, options
|
90
|
+
response_hash = response_hash.keys.each_with_object({}) do | key, new_hash |
|
91
|
+
new_hash[key] = Pact::MatchingRules.merge(response_hash[key], response_matching_rules[key], options)
|
92
|
+
end
|
93
|
+
Pact::Response.from_hash(response_hash)
|
94
|
+
end
|
95
|
+
|
96
|
+
def to_hash
|
97
|
+
{
|
98
|
+
description: description,
|
99
|
+
provider_state: provider_state,
|
100
|
+
request: request.to_hash,
|
101
|
+
response: response.to_hash
|
102
|
+
}
|
103
|
+
end
|
104
|
+
|
105
|
+
def http?
|
106
|
+
true
|
107
|
+
end
|
108
|
+
|
109
|
+
def validate!
|
110
|
+
raise Pact::InvalidInteractionError.new(self) unless description && request && response
|
111
|
+
end
|
112
|
+
|
113
|
+
def matches_criteria? criteria
|
114
|
+
criteria.each do | key, value |
|
115
|
+
unless match_criterion self.send(key.to_s), value
|
116
|
+
return false
|
117
|
+
end
|
42
118
|
end
|
119
|
+
true
|
43
120
|
end
|
44
|
-
true
|
45
|
-
end
|
46
121
|
|
47
|
-
|
48
|
-
|
49
|
-
|
122
|
+
def match_criterion target, criterion
|
123
|
+
target == criterion || (criterion.is_a?(Regexp) && criterion.match(target))
|
124
|
+
end
|
50
125
|
|
51
|
-
|
52
|
-
|
53
|
-
|
126
|
+
def == other
|
127
|
+
other.is_a?(Interaction) && to_hash == other.to_hash
|
128
|
+
end
|
54
129
|
|
55
|
-
|
56
|
-
|
57
|
-
|
130
|
+
def eq? other
|
131
|
+
self == other
|
132
|
+
end
|
58
133
|
|
59
|
-
|
60
|
-
|
61
|
-
|
134
|
+
def description_with_provider_state_quoted
|
135
|
+
provider_state ? "\"#{description}\" given \"#{provider_state}\"" : "\"#{description}\""
|
136
|
+
end
|
62
137
|
|
63
|
-
|
64
|
-
|
65
|
-
|
138
|
+
def request_modifies_resource_without_checking_response_body?
|
139
|
+
request.modifies_resource? && response.body_allows_any_value?
|
140
|
+
end
|
66
141
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
142
|
+
def to_s
|
143
|
+
to_hash.to_s
|
144
|
+
end
|
145
|
+
|
146
|
+
def self.is_xml? body
|
147
|
+
body.is_a?(String) && body.start_with?("<")
|
148
|
+
end
|
149
|
+
end
|
71
150
|
end
|
@@ -40,7 +40,7 @@ module Pact
|
|
40
40
|
end
|
41
41
|
|
42
42
|
private
|
43
|
-
|
43
|
+
|
44
44
|
def local? uri
|
45
45
|
!uri.start_with?("http://", "https://")
|
46
46
|
end
|
@@ -74,7 +74,7 @@ module Pact
|
|
74
74
|
end
|
75
75
|
end
|
76
76
|
end
|
77
|
-
|
77
|
+
|
78
78
|
def get_remote(uri, options)
|
79
79
|
request = Net::HTTP::Get.new(uri)
|
80
80
|
request.basic_auth(options[:username], options[:password]) if options[:username]
|
@@ -18,15 +18,15 @@ module Pact
|
|
18
18
|
|
19
19
|
def call
|
20
20
|
return @expected if @matching_rules.nil? || @matching_rules.empty?
|
21
|
-
recurse
|
21
|
+
recurse @expected, @root_path
|
22
22
|
end
|
23
23
|
|
24
24
|
private
|
25
25
|
|
26
26
|
def standardise_paths matching_rules
|
27
27
|
return matching_rules if matching_rules.nil? || matching_rules.empty?
|
28
|
-
matching_rules.each_with_object({}) do | (path,
|
29
|
-
new_matching_rules[JsonPath.new(path).to_s] =
|
28
|
+
matching_rules.each_with_object({}) do | (path, rule), new_matching_rules |
|
29
|
+
new_matching_rules[JsonPath.new(path).to_s] = rule
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
@@ -47,14 +47,14 @@ module Pact
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def recurse_array array, path
|
50
|
-
|
51
|
-
parent_match_rule = @matching_rules[path] && @matching_rules[path]['matchers'] && @matching_rules[path]['matchers'].first && @matching_rules[path]['matchers'].first.delete('match')
|
52
50
|
array_like_children_path = "#{path}[*]*"
|
53
|
-
|
54
|
-
|
51
|
+
parent_match_rule = @matching_rules[path] && @matching_rules[path]['matchers'] && @matching_rules[path]['matchers'].first && @matching_rules[path]['matchers'].first['match']
|
52
|
+
children_match_rule = @matching_rules[array_like_children_path] && @matching_rules[array_like_children_path]['matchers'] && @matching_rules[array_like_children_path]['matchers'].first && @matching_rules[array_like_children_path]['matchers'].first['match']
|
53
|
+
min = @matching_rules[path] && @matching_rules[path]['matchers'] && @matching_rules[path]['matchers'].first && @matching_rules[path]['matchers'].first['min']
|
55
54
|
|
56
55
|
if min && (children_match_rule == 'type' || (children_match_rule.nil? && parent_match_rule == 'type'))
|
57
56
|
warn_when_not_one_example_item(array, path)
|
57
|
+
# log_ignored_rules(path, @matching_rules[path], {'min' => min})
|
58
58
|
Pact::ArrayLike.new(recurse(array.first, "#{path}[*]"), min: min)
|
59
59
|
else
|
60
60
|
new_array = []
|
@@ -82,46 +82,30 @@ module Pact
|
|
82
82
|
elsif rules['regex']
|
83
83
|
handle_regex(object, path, rules)
|
84
84
|
else
|
85
|
-
|
85
|
+
log_ignored_rules(path, rules, {})
|
86
86
|
object
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
90
|
def handle_match_type object, path, rules
|
91
|
-
rules
|
92
|
-
Pact::SomethingLike.new(
|
91
|
+
log_ignored_rules(path, rules, {'match' => 'type'})
|
92
|
+
Pact::SomethingLike.new(object)
|
93
93
|
end
|
94
94
|
|
95
95
|
def handle_regex object, path, rules
|
96
|
-
rules
|
97
|
-
|
98
|
-
Pact::Term.new(generate: object, matcher: Regexp.new(regex))
|
96
|
+
log_ignored_rules(path, rules, {'match' => 'regex', 'regex' => rules['regex']})
|
97
|
+
Pact::Term.new(generate: object, matcher: Regexp.new(rules['regex']))
|
99
98
|
end
|
100
99
|
|
101
|
-
def log_ignored_rules
|
102
|
-
|
103
|
-
|
104
|
-
(
|
105
|
-
rules_array.delete_at(index) if rules_array[index].empty?
|
106
|
-
end
|
100
|
+
def log_ignored_rules path, rules, used_rules
|
101
|
+
dup_rules = rules.dup
|
102
|
+
used_rules.each_pair do | used_key, used_value |
|
103
|
+
dup_rules.delete(used_key) if dup_rules[used_key] == used_value
|
107
104
|
end
|
108
|
-
|
109
|
-
|
110
|
-
@matching_rules.each do | path, rules_hash |
|
111
|
-
rules_hash.each do | key, value |
|
112
|
-
$stderr.puts "WARN: Ignoring unsupported #{key} #{value} for path #{path}" if value.any?
|
113
|
-
end
|
114
|
-
end
|
105
|
+
if dup_rules.any?
|
106
|
+
$stderr.puts "WARN: Ignoring unsupported matching rules #{dup_rules} for path #{path}"
|
115
107
|
end
|
116
108
|
end
|
117
|
-
|
118
|
-
def find_rule(path, key)
|
119
|
-
@matching_rules[path] && @matching_rules[path][key]
|
120
|
-
end
|
121
|
-
|
122
|
-
def log_used_rule path, key, value
|
123
|
-
@used_rules << [path, key, value]
|
124
|
-
end
|
125
109
|
end
|
126
110
|
end
|
127
111
|
end
|
data/lib/pact/support/version.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
require 'pact/term'
|
2
2
|
require 'pact/something_like'
|
3
3
|
require 'pact/matching_rules/extract'
|
4
|
-
require 'pact/matching_rules/v3/extract'
|
5
4
|
require 'pact/matching_rules/merge'
|
6
|
-
require 'pact/matching_rules/v3/merge'
|
7
5
|
require 'pact/reification'
|
8
6
|
|
9
7
|
describe "converting Pact::Term and Pact::SomethingLike to matching rules and back again" do
|
@@ -12,9 +10,6 @@ describe "converting Pact::Term and Pact::SomethingLike to matching rules and ba
|
|
12
10
|
let(:matching_rules) { Pact::MatchingRules::Extract.(expected) }
|
13
11
|
let(:recreated_expected) { Pact::MatchingRules::Merge.(example, matching_rules)}
|
14
12
|
|
15
|
-
let(:recreated_expected_v3) { Pact::MatchingRules::V3::Merge.(example, matching_rules_v3) }
|
16
|
-
let(:matching_rules_v3) { Pact::MatchingRules::V3::Extract.(expected) }
|
17
|
-
|
18
13
|
context "with a Pact::Term" do
|
19
14
|
let(:expected) do
|
20
15
|
{
|
@@ -26,29 +21,9 @@ describe "converting Pact::Term and Pact::SomethingLike to matching rules and ba
|
|
26
21
|
}
|
27
22
|
end
|
28
23
|
|
29
|
-
it "recreates the same object hierarchy
|
30
|
-
expect(recreated_expected).to eq expected
|
31
|
-
end
|
32
|
-
|
33
|
-
it "recreates the same object hierarchy with v3 matching" do
|
34
|
-
expect(recreated_expected_v3).to eq expected
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
context "with a Pact::SomethingLike containing a Pact::ArrayLike" do
|
39
|
-
let(:expected) do
|
40
|
-
{
|
41
|
-
body: Pact::SomethingLike.new(children: Pact::ArrayLike.new("foo", min: 2))
|
42
|
-
}
|
43
|
-
end
|
44
|
-
|
45
|
-
it "recreates the same object hierarchy with v2 matching" do
|
24
|
+
it "recreates the same object hierarchy" do
|
46
25
|
expect(recreated_expected).to eq expected
|
47
26
|
end
|
48
|
-
|
49
|
-
it "recreates the same object hierarchy with v3 matching" do
|
50
|
-
expect(recreated_expected_v3).to eq expected
|
51
|
-
end
|
52
27
|
end
|
53
28
|
|
54
29
|
context "with a Pact::SomethingLike" do
|
@@ -62,13 +37,9 @@ describe "converting Pact::Term and Pact::SomethingLike to matching rules and ba
|
|
62
37
|
}
|
63
38
|
end
|
64
39
|
|
65
|
-
it "recreates the same object hierarchy
|
40
|
+
it "recreates the same object hierarchy" do
|
66
41
|
expect(recreated_expected).to eq expected
|
67
42
|
end
|
68
|
-
|
69
|
-
it "recreates the same object hierarchy with v3 matching" do
|
70
|
-
expect(recreated_expected_v3).to eq expected
|
71
|
-
end
|
72
43
|
end
|
73
44
|
|
74
45
|
context "with a Pact::SomethingLike containing a Hash" do
|
@@ -90,13 +61,9 @@ describe "converting Pact::Term and Pact::SomethingLike to matching rules and ba
|
|
90
61
|
}
|
91
62
|
end
|
92
63
|
|
93
|
-
it "recreates the same object hierarchy
|
64
|
+
it "recreates the same object hierarchy" do
|
94
65
|
expect(recreated_expected).to eq expected
|
95
66
|
end
|
96
|
-
|
97
|
-
it "recreates the same object hierarchy with v3 matching" do
|
98
|
-
expect(recreated_expected_v3).to eq expected
|
99
|
-
end
|
100
67
|
end
|
101
68
|
|
102
69
|
context "with a Pact::SomethingLike containing an Array" do
|
@@ -116,12 +83,8 @@ describe "converting Pact::Term and Pact::SomethingLike to matching rules and ba
|
|
116
83
|
}
|
117
84
|
end
|
118
85
|
|
119
|
-
it "recreates the same object hierarchy
|
86
|
+
it "recreates the same object hierarchy" do
|
120
87
|
expect(recreated_expected).to eq expected
|
121
88
|
end
|
122
|
-
|
123
|
-
it "recreates the same object hierarchy with v3 matching" do
|
124
|
-
expect(recreated_expected_v3).to eq expected
|
125
|
-
end
|
126
89
|
end
|
127
90
|
end
|
@@ -3,26 +3,6 @@ require 'pact/consumer_contract'
|
|
3
3
|
|
4
4
|
module Pact
|
5
5
|
describe ConsumerContract do
|
6
|
-
describe "from_uri" do
|
7
|
-
context "when the URL does not point to a valid pact" do
|
8
|
-
subject { ConsumerContract.from_uri('spec/fixtures/not-a-pact.json') }
|
9
|
-
|
10
|
-
it "raises a helpful error" do
|
11
|
-
expect { subject }.to raise_error UnrecognizePactFormatError, /Please check that spec/
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
describe "from_hash" do
|
17
|
-
context "when the hash is not a valid pact" do
|
18
|
-
subject { ConsumerContract.from_hash({'foo' => 'bar'}) }
|
19
|
-
|
20
|
-
it "raises a helpful error" do
|
21
|
-
expect { subject }.to raise_error UnrecognizePactFormatError, 'This document does not use a recognised Pact format: {"foo"=>"bar"}'
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
6
|
describe ".from_json" do
|
27
7
|
|
28
8
|
let(:loaded_pact) { ConsumerContract.from_json(string) }
|
@@ -52,7 +52,58 @@ module Pact
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
+
describe "from_hash" do
|
56
|
+
context "when providerState has been used instead of provider_state" do
|
55
57
|
|
58
|
+
subject { Interaction.from_hash('response' => response, 'request' => request, 'providerState' => 'some state') }
|
59
|
+
|
60
|
+
it "recognises the provider state" do
|
61
|
+
expect(subject.provider_state).to eq 'some state'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context "when there are matching rules" do
|
66
|
+
let(:hash) { load_json_fixture 'interaction-with-matching-rules.json' }
|
67
|
+
|
68
|
+
subject { Interaction.from_hash hash, pact_specification_version: Pact::SpecificationVersion.new("2") }
|
69
|
+
|
70
|
+
it "merges the rules with the example for the request" do
|
71
|
+
expect(subject.request.body['name']).to be_instance_of(Pact::Term)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "merges the rules with the example for the response" do
|
75
|
+
expect(subject.response.body['_links']['self']['href']).to be_instance_of(Pact::Term)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "when the request body is a String" do
|
80
|
+
let(:hash) { { 'request' => request, 'response' => response } }
|
81
|
+
subject { Interaction.from_hash hash, pact_specification_version: Pact::SpecificationVersion.new("3") }
|
82
|
+
|
83
|
+
let(:request) { { 'method' => 'get', 'path' => 'path' , 'body' => "<xml></xml>", 'matchingRules' => {"body" => {"foo" => "bar"} } } }
|
84
|
+
|
85
|
+
it "returns an interaction with an StringWithMatchingRules in the request" do
|
86
|
+
expect(subject.request.body).to be_a(Pact::StringWithMatchingRules)
|
87
|
+
expect(subject.request.body).to eq "<xml></xml>"
|
88
|
+
expect(subject.request.body.matching_rules).to eq "foo" => "bar"
|
89
|
+
expect(subject.request.body.pact_specification_version).to eq Pact::SpecificationVersion.new("3")
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context "when the response body is a String" do
|
94
|
+
let(:hash) { { 'request' => request, 'response' => response } }
|
95
|
+
subject { Interaction.from_hash hash, pact_specification_version: Pact::SpecificationVersion.new("3") }
|
96
|
+
|
97
|
+
let(:response) { { 'status' => '200', 'body' => "<xml></xml>", 'matchingRules' => {"body" => {"foo" => "bar"} } } }
|
98
|
+
|
99
|
+
it "returns an interaction with an StringWithMatchingRules in the response" do
|
100
|
+
expect(subject.response.body).to be_a(Pact::StringWithMatchingRules)
|
101
|
+
expect(subject.response.body).to eq "<xml></xml>"
|
102
|
+
expect(subject.response.body.matching_rules).to eq "foo" => "bar"
|
103
|
+
expect(subject.response.body.pact_specification_version).to eq Pact::SpecificationVersion.new("3")
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
56
107
|
|
57
108
|
describe "request_modifies_resource_without_checking_response_body?" do
|
58
109
|
|
@@ -7,16 +7,10 @@ module Pact
|
|
7
7
|
subject { Merge.(expected, matching_rules) }
|
8
8
|
|
9
9
|
before do
|
10
|
-
allow($stderr).to receive(:puts)
|
11
|
-
raise "Was not expecting stderr to receive #{message.inspect} in this spec. This may be because of a missed rule deletion in Merge."
|
12
|
-
end
|
10
|
+
allow($stderr).to receive(:puts)
|
13
11
|
end
|
14
12
|
|
15
13
|
describe "no recognised rules" do
|
16
|
-
before do
|
17
|
-
allow($stderr).to receive(:puts)
|
18
|
-
end
|
19
|
-
|
20
14
|
let(:expected) do
|
21
15
|
{
|
22
16
|
"_links" => {
|
@@ -71,10 +65,6 @@ module Pact
|
|
71
65
|
end
|
72
66
|
|
73
67
|
describe "type based matching" do
|
74
|
-
before do
|
75
|
-
allow($stderr).to receive(:puts)
|
76
|
-
end
|
77
|
-
|
78
68
|
let(:expected) do
|
79
69
|
{
|
80
70
|
"name" => "Mary"
|
@@ -98,19 +88,11 @@ module Pact
|
|
98
88
|
subject
|
99
89
|
end
|
100
90
|
|
101
|
-
it "does not alter the passed in rules hash" do
|
102
|
-
original_matching_rules = JSON.parse(matching_rules.to_json)
|
103
|
-
subject
|
104
|
-
expect(matching_rules).to eq original_matching_rules
|
105
|
-
end
|
106
91
|
end
|
107
92
|
|
108
93
|
describe "regular expressions" do
|
109
|
-
describe "in a hash" do
|
110
|
-
before do
|
111
|
-
allow($stderr).to receive(:puts)
|
112
|
-
end
|
113
94
|
|
95
|
+
describe "in a hash" do
|
114
96
|
let(:expected) do
|
115
97
|
{
|
116
98
|
"_links" => {
|
@@ -293,10 +275,6 @@ module Pact
|
|
293
275
|
end
|
294
276
|
|
295
277
|
describe "with an example array with more than one item" do
|
296
|
-
before do
|
297
|
-
allow($stderr).to receive(:puts)
|
298
|
-
end
|
299
|
-
|
300
278
|
let(:expected) do
|
301
279
|
{
|
302
280
|
|
@@ -314,7 +292,7 @@ module Pact
|
|
314
292
|
}
|
315
293
|
end
|
316
294
|
|
317
|
-
|
295
|
+
xit "doesn't warn about the min size being ignored" do
|
318
296
|
expect(Pact.configuration.error_stream).to receive(:puts).once
|
319
297
|
subject
|
320
298
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pact-support
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.7.0.alpha.1
|
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: 2018-07-
|
15
|
+
date: 2018-07-14 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: randexp
|
@@ -270,9 +270,6 @@ files:
|
|
270
270
|
- lib/pact/consumer_contract/headers.rb
|
271
271
|
- lib/pact/consumer_contract/http_consumer_contract_parser.rb
|
272
272
|
- lib/pact/consumer_contract/interaction.rb
|
273
|
-
- lib/pact/consumer_contract/interaction_parser.rb
|
274
|
-
- lib/pact/consumer_contract/interaction_v2_parser.rb
|
275
|
-
- lib/pact/consumer_contract/interaction_v3_parser.rb
|
276
273
|
- lib/pact/consumer_contract/pact_file.rb
|
277
274
|
- lib/pact/consumer_contract/query.rb
|
278
275
|
- lib/pact/consumer_contract/query_hash.rb
|
@@ -331,7 +328,6 @@ files:
|
|
331
328
|
- script/release.sh
|
332
329
|
- script/update-pact-specification-v2
|
333
330
|
- spec/fixtures/interaction-with-matching-rules.json
|
334
|
-
- spec/fixtures/not-a-pact.json
|
335
331
|
- spec/fixtures/pact-http-v2.json
|
336
332
|
- spec/fixtures/pact-http-v3.json
|
337
333
|
- spec/integration/matching_rules_extract_and_merge_spec.rb
|
@@ -343,7 +339,6 @@ files:
|
|
343
339
|
- spec/lib/pact/consumer_contract/file_name_spec.rb
|
344
340
|
- spec/lib/pact/consumer_contract/headers_spec.rb
|
345
341
|
- spec/lib/pact/consumer_contract/http_consumer_contract_parser_spec.rb
|
346
|
-
- spec/lib/pact/consumer_contract/interaction_parser_spec.rb
|
347
342
|
- spec/lib/pact/consumer_contract/interaction_spec.rb
|
348
343
|
- spec/lib/pact/consumer_contract/pact_file_spec.rb
|
349
344
|
- spec/lib/pact/consumer_contract/query_hash_spec.rb
|
@@ -425,9 +420,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
425
420
|
version: '2.0'
|
426
421
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
427
422
|
requirements:
|
428
|
-
- - "
|
423
|
+
- - ">"
|
429
424
|
- !ruby/object:Gem::Version
|
430
|
-
version:
|
425
|
+
version: 1.3.1
|
431
426
|
requirements: []
|
432
427
|
rubyforge_project:
|
433
428
|
rubygems_version: 2.6.11
|
@@ -436,7 +431,6 @@ specification_version: 4
|
|
436
431
|
summary: Shared code for Pact gems
|
437
432
|
test_files:
|
438
433
|
- spec/fixtures/interaction-with-matching-rules.json
|
439
|
-
- spec/fixtures/not-a-pact.json
|
440
434
|
- spec/fixtures/pact-http-v2.json
|
441
435
|
- spec/fixtures/pact-http-v3.json
|
442
436
|
- spec/integration/matching_rules_extract_and_merge_spec.rb
|
@@ -448,7 +442,6 @@ test_files:
|
|
448
442
|
- spec/lib/pact/consumer_contract/file_name_spec.rb
|
449
443
|
- spec/lib/pact/consumer_contract/headers_spec.rb
|
450
444
|
- spec/lib/pact/consumer_contract/http_consumer_contract_parser_spec.rb
|
451
|
-
- spec/lib/pact/consumer_contract/interaction_parser_spec.rb
|
452
445
|
- spec/lib/pact/consumer_contract/interaction_spec.rb
|
453
446
|
- spec/lib/pact/consumer_contract/pact_file_spec.rb
|
454
447
|
- spec/lib/pact/consumer_contract/query_hash_spec.rb
|
@@ -1,23 +0,0 @@
|
|
1
|
-
require 'pact/specification_version'
|
2
|
-
require 'pact/consumer_contract/interaction_v2_parser'
|
3
|
-
require 'pact/consumer_contract/interaction_v3_parser'
|
4
|
-
|
5
|
-
module Pact
|
6
|
-
class InteractionParser
|
7
|
-
def self.call hash, options = {}
|
8
|
-
pact_specification_version = options[:pact_specification_version] || Pact::SpecificationVersion::NIL_VERSION
|
9
|
-
case pact_specification_version.major
|
10
|
-
when nil, 0, 1, 2 then parse_v2_interaction(hash, pact_specification_version: pact_specification_version)
|
11
|
-
else parse_v3_interaction(hash, pact_specification_version: pact_specification_version)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
def self.parse_v2_interaction hash, options
|
16
|
-
InteractionV2Parser.call(hash, options)
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.parse_v3_interaction hash, options
|
20
|
-
InteractionV3Parser.call(hash, options)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
require 'pact/consumer_contract/request'
|
2
|
-
require 'pact/consumer_contract/response'
|
3
|
-
require 'pact/symbolize_keys'
|
4
|
-
require 'pact/matching_rules'
|
5
|
-
require 'pact/errors'
|
6
|
-
|
7
|
-
module Pact
|
8
|
-
class InteractionV2Parser
|
9
|
-
|
10
|
-
include SymbolizeKeys
|
11
|
-
|
12
|
-
def self.call hash, options
|
13
|
-
request = parse_request(hash['request'], options)
|
14
|
-
response = parse_response(hash['response'], options)
|
15
|
-
Interaction.new(symbolize_keys(hash).merge(request: request, response: response))
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.parse_request request_hash, options
|
19
|
-
request_hash = Pact::MatchingRules.merge(request_hash, request_hash['matchingRules'], options)
|
20
|
-
Pact::Request::Expected.from_hash(request_hash)
|
21
|
-
end
|
22
|
-
|
23
|
-
def self.parse_response response_hash, options
|
24
|
-
response_hash = Pact::MatchingRules.merge(response_hash, response_hash['matchingRules'], options)
|
25
|
-
Pact::Response.from_hash(response_hash)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
@@ -1,61 +0,0 @@
|
|
1
|
-
require 'pact/consumer_contract/request'
|
2
|
-
require 'pact/consumer_contract/response'
|
3
|
-
require 'pact/symbolize_keys'
|
4
|
-
require 'pact/matching_rules'
|
5
|
-
require 'pact/errors'
|
6
|
-
require 'pact/consumer_contract/string_with_matching_rules'
|
7
|
-
|
8
|
-
module Pact
|
9
|
-
class InteractionV3Parser
|
10
|
-
|
11
|
-
include SymbolizeKeys
|
12
|
-
|
13
|
-
def self.call hash, options
|
14
|
-
request = parse_request(hash['request'], options)
|
15
|
-
response = parse_response(hash['response'], options)
|
16
|
-
Interaction.new(symbolize_keys(hash).merge(request: request, response: response))
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.parse_request request_hash, options
|
20
|
-
request_matching_rules = request_hash['matchingRules'] || {}
|
21
|
-
if request_hash['body'].is_a?(String)
|
22
|
-
parse_request_with_string_body(request_hash, request_matching_rules['body'] || {}, options)
|
23
|
-
else
|
24
|
-
parse_request_with_non_string_body(request_hash, request_matching_rules, options)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def self.parse_response response_hash, options
|
29
|
-
response_matching_rules = response_hash['matchingRules'] || {}
|
30
|
-
if response_hash['body'].is_a?(String)
|
31
|
-
parse_response_with_string_body(response_hash, response_matching_rules['body'] || {}, options)
|
32
|
-
else
|
33
|
-
parse_response_with_non_string_body(response_hash, response_matching_rules, options)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def self.parse_request_with_non_string_body request_hash, request_matching_rules, options
|
38
|
-
request_hash = request_hash.keys.each_with_object({}) do | key, new_hash |
|
39
|
-
new_hash[key] = Pact::MatchingRules.merge(request_hash[key], request_matching_rules[key], options)
|
40
|
-
end
|
41
|
-
Pact::Request::Expected.from_hash(request_hash)
|
42
|
-
end
|
43
|
-
|
44
|
-
def self.parse_response_with_non_string_body response_hash, response_matching_rules, options
|
45
|
-
response_hash = response_hash.keys.each_with_object({}) do | key, new_hash |
|
46
|
-
new_hash[key] = Pact::MatchingRules.merge(response_hash[key], response_matching_rules[key], options)
|
47
|
-
end
|
48
|
-
Pact::Response.from_hash(response_hash)
|
49
|
-
end
|
50
|
-
|
51
|
-
def self.parse_request_with_string_body request_hash, request_matching_rules, options
|
52
|
-
string_with_matching_rules = StringWithMatchingRules.new(request_hash['body'], options[:pact_specification_version], request_matching_rules)
|
53
|
-
Pact::Request::Expected.from_hash(request_hash.merge('body' => string_with_matching_rules))
|
54
|
-
end
|
55
|
-
|
56
|
-
def self.parse_response_with_string_body response_hash, response_matching_rules, options
|
57
|
-
string_with_matching_rules = StringWithMatchingRules.new(response_hash['body'], options[:pact_specification_version], response_matching_rules)
|
58
|
-
Pact::Response.from_hash(response_hash.merge('body' => string_with_matching_rules))
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
@@ -1,62 +0,0 @@
|
|
1
|
-
require 'pact/consumer_contract/interaction_parser'
|
2
|
-
|
3
|
-
module Pact
|
4
|
-
describe InteractionParser do
|
5
|
-
describe ".call" do
|
6
|
-
|
7
|
-
let(:request) { {method: 'get', path: 'path'} }
|
8
|
-
let(:response) { {} }
|
9
|
-
|
10
|
-
context "when providerState has been used instead of provider_state" do
|
11
|
-
|
12
|
-
subject { InteractionParser.call('response' => response, 'request' => request, 'providerState' => 'some state') }
|
13
|
-
|
14
|
-
it "recognises the provider state" do
|
15
|
-
expect(subject.provider_state).to eq 'some state'
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
context "when there are matching rules" do
|
20
|
-
let(:hash) { load_json_fixture 'interaction-with-matching-rules.json' }
|
21
|
-
|
22
|
-
subject { InteractionParser.call(hash, pact_specification_version: Pact::SpecificationVersion.new("2")) }
|
23
|
-
|
24
|
-
it "merges the rules with the example for the request" do
|
25
|
-
expect(subject.request.body['name']).to be_instance_of(Pact::Term)
|
26
|
-
end
|
27
|
-
|
28
|
-
it "merges the rules with the example for the response" do
|
29
|
-
expect(subject.response.body['_links']['self']['href']).to be_instance_of(Pact::Term)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
context "when the request body is a String" do
|
34
|
-
let(:hash) { { 'request' => request, 'response' => response } }
|
35
|
-
subject { InteractionParser.call(hash, pact_specification_version: Pact::SpecificationVersion.new("3")) }
|
36
|
-
|
37
|
-
let(:request) { { 'method' => 'get', 'path' => 'path' , 'body' => "<xml></xml>", 'matchingRules' => {"body" => {"foo" => "bar"} } } }
|
38
|
-
|
39
|
-
it "returns an interaction with an StringWithMatchingRules in the request" do
|
40
|
-
expect(subject.request.body).to be_a(Pact::StringWithMatchingRules)
|
41
|
-
expect(subject.request.body).to eq "<xml></xml>"
|
42
|
-
expect(subject.request.body.matching_rules).to eq "foo" => "bar"
|
43
|
-
expect(subject.request.body.pact_specification_version).to eq Pact::SpecificationVersion.new("3")
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
context "when the response body is a String" do
|
48
|
-
let(:hash) { { 'request' => request, 'response' => response } }
|
49
|
-
subject { InteractionParser.call(hash, pact_specification_version: Pact::SpecificationVersion.new("3")) }
|
50
|
-
|
51
|
-
let(:response) { { 'status' => '200', 'body' => "<xml></xml>", 'matchingRules' => {"body" => {"foo" => "bar"} } } }
|
52
|
-
|
53
|
-
it "returns an interaction with an StringWithMatchingRules in the response" do
|
54
|
-
expect(subject.response.body).to be_a(Pact::StringWithMatchingRules)
|
55
|
-
expect(subject.response.body).to eq "<xml></xml>"
|
56
|
-
expect(subject.response.body.matching_rules).to eq "foo" => "bar"
|
57
|
-
expect(subject.response.body.pact_specification_version).to eq Pact::SpecificationVersion.new("3")
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|