pact-support 1.6.6 → 1.7.0.alpha.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|