pact-support 1.7.0.alpha.1 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +35 -0
- data/lib/pact/configuration.rb +4 -0
- data/lib/pact/consumer_contract/consumer_contract.rb +5 -1
- data/lib/pact/consumer_contract/interaction.rb +56 -135
- data/lib/pact/consumer_contract/interaction_parser.rb +23 -0
- data/lib/pact/consumer_contract/interaction_v2_parser.rb +28 -0
- data/lib/pact/consumer_contract/interaction_v3_parser.rb +61 -0
- data/lib/pact/consumer_contract/pact_file.rb +2 -2
- data/lib/pact/consumer_contract/request.rb +1 -5
- data/lib/pact/matchers/multipart_form_diff_formatter.rb +41 -0
- data/lib/pact/matching_rules/merge.rb +1 -1
- data/lib/pact/matching_rules/v3/merge.rb +34 -18
- data/lib/pact/shared/multipart_form_differ.rb +14 -0
- data/lib/pact/specification_version.rb +1 -1
- data/lib/pact/support/version.rb +1 -1
- data/spec/fixtures/multipart-form-diff.txt +9 -0
- data/spec/fixtures/not-a-pact.json +3 -0
- data/spec/integration/matching_rules_extract_and_merge_spec.rb +41 -4
- data/spec/lib/pact/consumer_contract/consumer_contract_spec.rb +20 -0
- data/spec/lib/pact/consumer_contract/interaction_parser_spec.rb +62 -0
- data/spec/lib/pact/consumer_contract/interaction_spec.rb +0 -51
- data/spec/lib/pact/matchers/multipart_form_diff_formatter_spec.rb +36 -0
- data/spec/lib/pact/matching_rules/v3/merge_spec.rb +25 -3
- data/spec/lib/pact/shared/multipart_form_differ_spec.rb +39 -0
- metadata +19 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2bbba1bbc7c4a2bf0c9bf83c335bca49f3911b33
|
4
|
+
data.tar.gz: 074b3a5fbf4ea09514e9a58d6af2d42d22739942
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d15ba35784d2b6a93feeae4f77fd43f32ae2b07d3ece6b1b1a0367d9d05702a6a6dca9696e65287ba782c2ccfc495fc7fb3c8e8a34c57f525ddaf0702acdf6b2
|
7
|
+
data.tar.gz: 58ebf78d2b351442c2d3ac0ce8a2874949939acb51ca94b5aa7f0b261b1674da0ddd73db983e643267e9dd3b8c0117a80277090ac36690ff71ece9fbb694c118
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,38 @@
|
|
1
|
+
<a name="v1.7.0"></a>
|
2
|
+
### v1.7.0 (2018-08-07)
|
3
|
+
|
4
|
+
|
5
|
+
#### Features
|
6
|
+
|
7
|
+
* add support for multipart/form ([8ed4332](/../../commit/8ed4332))
|
8
|
+
|
9
|
+
|
10
|
+
<a name="v1.6.6"></a>
|
11
|
+
### v1.6.6 (2018-07-25)
|
12
|
+
|
13
|
+
|
14
|
+
#### Bug Fixes
|
15
|
+
|
16
|
+
* correctly handle an 'each like' inside a 'like' ([7dc76dc](/../../commit/7dc76dc))
|
17
|
+
|
18
|
+
|
19
|
+
<a name="v1.6.5"></a>
|
20
|
+
### v1.6.5 (2018-07-23)
|
21
|
+
|
22
|
+
|
23
|
+
#### Features
|
24
|
+
|
25
|
+
* use 0 as the nil pact specification version ([88e4750](/../../commit/88e4750))
|
26
|
+
* reify StringWithMatchingRules to a String ([a025dd3](/../../commit/a025dd3))
|
27
|
+
* parse String response and request bodies to StringWithMatchingRules to support pact-xml ([a9fbb58](/../../commit/a9fbb58))
|
28
|
+
* add custom contract parsers to front of pact parsers list so that customised parsers are tried first ([babc319](/../../commit/babc319))
|
29
|
+
|
30
|
+
|
31
|
+
#### Bug Fixes
|
32
|
+
|
33
|
+
* show a more helpful error when attempting to parse a URI that is not a pact ([a8ba1ed](/../../commit/a8ba1ed))
|
34
|
+
|
35
|
+
|
1
36
|
<a name="v1.6.4"></a>
|
2
37
|
### v1.6.4 (2018-07-14)
|
3
38
|
|
data/lib/pact/configuration.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
require 'pact/matchers/embedded_diff_formatter'
|
2
2
|
require 'pact/matchers/unix_diff_formatter'
|
3
3
|
require 'pact/matchers/list_diff_formatter'
|
4
|
+
require 'pact/matchers/multipart_form_diff_formatter'
|
4
5
|
require 'pact/shared/json_differ'
|
5
6
|
require 'pact/shared/text_differ'
|
6
7
|
require 'pact/shared/form_differ'
|
8
|
+
require 'pact/shared/multipart_form_differ'
|
7
9
|
|
8
10
|
|
9
11
|
module Pact
|
@@ -24,6 +26,7 @@ module Pact
|
|
24
26
|
end
|
25
27
|
|
26
28
|
DIFF_FORMATTER_REGISTRATIONS = [
|
29
|
+
[/multipart\/form-data/, Pact::Matchers::MultipartFormDiffFormatter],
|
27
30
|
[/.*/, Pact::Matchers::UnixDiffFormatter],
|
28
31
|
[NilMatcher, Pact::Matchers::UnixDiffFormatter]
|
29
32
|
]
|
@@ -31,6 +34,7 @@ module Pact
|
|
31
34
|
DIFFERS = [
|
32
35
|
[/json/, Pact::JsonDiffer],
|
33
36
|
[/application\/x\-www\-form\-urlencoded/, Pact::FormDiffer],
|
37
|
+
[/multipart\/form-data/, Pact::MultipartFormDiffer],
|
34
38
|
[NilMatcher, Pact::TextDiffer],
|
35
39
|
[/.*/, Pact::TextDiffer]
|
36
40
|
]
|
@@ -14,6 +14,8 @@ require 'pact/consumer_contract/http_consumer_contract_parser'
|
|
14
14
|
|
15
15
|
module Pact
|
16
16
|
|
17
|
+
class UnrecognizePactFormatError < ::Pact::Error; end
|
18
|
+
|
17
19
|
class ConsumerContract
|
18
20
|
|
19
21
|
include SymbolizeKeys
|
@@ -42,7 +44,7 @@ module Pact
|
|
42
44
|
parsers.each do | parser |
|
43
45
|
return parser.call(hash) if parser.can_parse?(hash)
|
44
46
|
end
|
45
|
-
raise Pact::
|
47
|
+
raise Pact::UnrecognizePactFormatError.new("This document does not use a recognised Pact format: #{hash}")
|
46
48
|
end
|
47
49
|
|
48
50
|
def self.from_json string
|
@@ -52,6 +54,8 @@ module Pact
|
|
52
54
|
|
53
55
|
def self.from_uri uri, options = {}
|
54
56
|
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.")
|
55
59
|
end
|
56
60
|
|
57
61
|
def self.maintain_backwards_compatiblity_with_producer_keys string
|
@@ -1,150 +1,71 @@
|
|
1
|
-
require 'pact/consumer_contract/request'
|
2
|
-
require 'pact/consumer_contract/response'
|
3
|
-
require 'pact/symbolize_keys'
|
4
1
|
require 'pact/shared/active_support_support'
|
5
|
-
require 'pact/
|
6
|
-
require 'pact/errors'
|
7
|
-
require 'pact/specification_version'
|
8
|
-
require 'pact/consumer_contract/string_with_matching_rules'
|
2
|
+
require 'pact/consumer_contract/interaction_parser'
|
9
3
|
|
10
4
|
module Pact
|
11
5
|
class Interaction
|
12
6
|
include ActiveSupportSupport
|
13
|
-
include SymbolizeKeys
|
14
7
|
|
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
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
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
|
8
|
+
attr_accessor :description, :request, :response, :provider_state
|
9
|
+
|
10
|
+
def initialize attributes = {}
|
11
|
+
@description = attributes[:description]
|
12
|
+
@request = attributes[:request]
|
13
|
+
@response = attributes[:response]
|
14
|
+
@provider_state = attributes[:provider_state] || attributes[:providerState]
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.from_hash hash, options = {}
|
18
|
+
InteractionParser.call(hash, options)
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_hash
|
22
|
+
{
|
23
|
+
description: description,
|
24
|
+
provider_state: provider_state,
|
25
|
+
request: request.to_hash,
|
26
|
+
response: response.to_hash
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
def http?
|
31
|
+
true
|
32
|
+
end
|
33
|
+
|
34
|
+
def validate!
|
35
|
+
raise Pact::InvalidInteractionError.new(self) unless description && request && response
|
36
|
+
end
|
37
|
+
|
38
|
+
def matches_criteria? criteria
|
39
|
+
criteria.each do | key, value |
|
40
|
+
unless match_criterion self.send(key.to_s), value
|
41
|
+
return false
|
118
42
|
end
|
119
|
-
true
|
120
43
|
end
|
44
|
+
true
|
45
|
+
end
|
121
46
|
|
122
|
-
|
123
|
-
|
124
|
-
|
47
|
+
def match_criterion target, criterion
|
48
|
+
target == criterion || (criterion.is_a?(Regexp) && criterion.match(target))
|
49
|
+
end
|
125
50
|
|
126
|
-
|
127
|
-
|
128
|
-
|
51
|
+
def == other
|
52
|
+
other.is_a?(Interaction) && to_hash == other.to_hash
|
53
|
+
end
|
129
54
|
|
130
|
-
|
131
|
-
|
132
|
-
|
55
|
+
def eq? other
|
56
|
+
self == other
|
57
|
+
end
|
133
58
|
|
134
|
-
|
135
|
-
|
136
|
-
|
59
|
+
def description_with_provider_state_quoted
|
60
|
+
provider_state ? "\"#{description}\" given \"#{provider_state}\"" : "\"#{description}\""
|
61
|
+
end
|
137
62
|
|
138
|
-
|
139
|
-
|
140
|
-
|
63
|
+
def request_modifies_resource_without_checking_response_body?
|
64
|
+
request.modifies_resource? && response.body_allows_any_value?
|
65
|
+
end
|
141
66
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
def self.is_xml? body
|
147
|
-
body.is_a?(String) && body.start_with?("<")
|
148
|
-
end
|
149
|
-
end
|
67
|
+
def to_s
|
68
|
+
to_hash.to_s
|
69
|
+
end
|
70
|
+
end
|
150
71
|
end
|
@@ -0,0 +1,23 @@
|
|
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
|
@@ -0,0 +1,28 @@
|
|
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
|
@@ -0,0 +1,61 @@
|
|
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
|
@@ -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]
|
@@ -2,9 +2,7 @@ require 'pact/shared/request'
|
|
2
2
|
require 'pact/shared/null_expectation'
|
3
3
|
|
4
4
|
module Pact
|
5
|
-
|
6
5
|
module Request
|
7
|
-
|
8
6
|
class Expected < Pact::Request::Base
|
9
7
|
|
10
8
|
DEFAULT_OPTIONS = {:allow_unexpected_keys => false}.freeze
|
@@ -80,8 +78,6 @@ module Pact
|
|
80
78
|
def body_differ
|
81
79
|
Pact.configuration.body_differ_for_content_type content_type
|
82
80
|
end
|
83
|
-
|
84
81
|
end
|
85
|
-
|
86
82
|
end
|
87
|
-
end
|
83
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'pact/matchers/unix_diff_formatter'
|
2
|
+
require 'pact/matchers/differ'
|
3
|
+
|
4
|
+
module Pact
|
5
|
+
module Matchers
|
6
|
+
class MultipartFormDiffFormatter
|
7
|
+
|
8
|
+
def initialize diff, options = {}
|
9
|
+
@options = options
|
10
|
+
@body_diff = diff[:body]
|
11
|
+
@non_body_diff = diff.reject{ |k, v| k == :body }
|
12
|
+
@colour = options.fetch(:colour, false)
|
13
|
+
@differ = Pact::Matchers::Differ.new(@colour)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.call diff, options = {}
|
17
|
+
new(diff, options).call
|
18
|
+
end
|
19
|
+
|
20
|
+
def call
|
21
|
+
Pact::Matchers::UnixDiffFormatter::MESSAGES_TITLE + "\n" + non_body_diff_string + "\n" + body_diff_string
|
22
|
+
end
|
23
|
+
|
24
|
+
def non_body_diff_string
|
25
|
+
if @non_body_diff.any?
|
26
|
+
Pact::Matchers::ExtractDiffMessages.call(@non_body_diff).collect{ | message| "* #{message}" }.join("\n")
|
27
|
+
else
|
28
|
+
""
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def body_diff_string
|
33
|
+
if @body_diff
|
34
|
+
@differ.diff_as_string(@body_diff.expected, @body_diff.actual)
|
35
|
+
else
|
36
|
+
""
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -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).tap { log_ignored_rules }
|
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, rules), new_matching_rules |
|
29
|
+
new_matching_rules[JsonPath.new(path).to_s] = Marshal.load(Marshal.dump(rules)) # simplest way to deep clone
|
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')
|
50
52
|
array_like_children_path = "#{path}[*]*"
|
51
|
-
|
52
|
-
|
53
|
-
min = @matching_rules[path] && @matching_rules[path]['matchers'] && @matching_rules[path]['matchers'].first && @matching_rules[path]['matchers'].first['min']
|
53
|
+
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.delete('match')
|
54
|
+
min = @matching_rules[path] && @matching_rules[path]['matchers'] && @matching_rules[path]['matchers'].first && @matching_rules[path]['matchers'].first.delete('min')
|
54
55
|
|
55
56
|
if min && (children_match_rule == 'type' || (children_match_rule.nil? && parent_match_rule == 'type'))
|
56
57
|
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,30 +82,46 @@ module Pact
|
|
82
82
|
elsif rules['regex']
|
83
83
|
handle_regex(object, path, rules)
|
84
84
|
else
|
85
|
-
log_ignored_rules(path, rules, {})
|
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
|
-
|
92
|
-
Pact::SomethingLike.new(object)
|
91
|
+
rules.delete('match')
|
92
|
+
Pact::SomethingLike.new(recurse(object, path))
|
93
93
|
end
|
94
94
|
|
95
95
|
def handle_regex object, path, rules
|
96
|
-
|
97
|
-
|
96
|
+
rules.delete('match')
|
97
|
+
regex = rules.delete('regex')
|
98
|
+
Pact::Term.new(generate: object, matcher: Regexp.new(regex))
|
98
99
|
end
|
99
100
|
|
100
|
-
def log_ignored_rules
|
101
|
-
|
102
|
-
|
103
|
-
|
101
|
+
def log_ignored_rules
|
102
|
+
@matching_rules.each do | jsonpath, rules_hash |
|
103
|
+
rules_array = rules_hash["matchers"]
|
104
|
+
((rules_array.length - 1)..0).each do | index |
|
105
|
+
rules_array.delete_at(index) if rules_array[index].empty?
|
106
|
+
end
|
104
107
|
end
|
105
|
-
|
106
|
-
|
108
|
+
|
109
|
+
if @matching_rules.any?
|
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
|
107
115
|
end
|
108
116
|
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
|
109
125
|
end
|
110
126
|
end
|
111
127
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'pact/shared/text_differ'
|
3
|
+
|
4
|
+
module Pact
|
5
|
+
class MultipartFormDiffer
|
6
|
+
def self.call expected, actual, options = {}
|
7
|
+
require 'pact/matchers' # avoid recursive loop between this file and pact/matchers
|
8
|
+
expected_boundary = expected.split.first
|
9
|
+
actual_boundary = actual.split.first
|
10
|
+
actual_with_hardcoded_boundary = actual.gsub(actual_boundary, expected_boundary)
|
11
|
+
TextDiffer.call(expected, actual_with_hardcoded_boundary, options)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/pact/support/version.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
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'
|
4
5
|
require 'pact/matching_rules/merge'
|
6
|
+
require 'pact/matching_rules/v3/merge'
|
5
7
|
require 'pact/reification'
|
6
8
|
|
7
9
|
describe "converting Pact::Term and Pact::SomethingLike to matching rules and back again" do
|
@@ -10,6 +12,9 @@ describe "converting Pact::Term and Pact::SomethingLike to matching rules and ba
|
|
10
12
|
let(:matching_rules) { Pact::MatchingRules::Extract.(expected) }
|
11
13
|
let(:recreated_expected) { Pact::MatchingRules::Merge.(example, matching_rules)}
|
12
14
|
|
15
|
+
let(:recreated_expected_v3) { Pact::MatchingRules::V3::Merge.(example, matching_rules_v3) }
|
16
|
+
let(:matching_rules_v3) { Pact::MatchingRules::V3::Extract.(expected) }
|
17
|
+
|
13
18
|
context "with a Pact::Term" do
|
14
19
|
let(:expected) do
|
15
20
|
{
|
@@ -21,9 +26,29 @@ describe "converting Pact::Term and Pact::SomethingLike to matching rules and ba
|
|
21
26
|
}
|
22
27
|
end
|
23
28
|
|
24
|
-
it "recreates the same object hierarchy" do
|
29
|
+
it "recreates the same object hierarchy with v2 matching" do
|
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
|
25
46
|
expect(recreated_expected).to eq expected
|
26
47
|
end
|
48
|
+
|
49
|
+
it "recreates the same object hierarchy with v3 matching" do
|
50
|
+
expect(recreated_expected_v3).to eq expected
|
51
|
+
end
|
27
52
|
end
|
28
53
|
|
29
54
|
context "with a Pact::SomethingLike" do
|
@@ -37,9 +62,13 @@ describe "converting Pact::Term and Pact::SomethingLike to matching rules and ba
|
|
37
62
|
}
|
38
63
|
end
|
39
64
|
|
40
|
-
it "recreates the same object hierarchy" do
|
65
|
+
it "recreates the same object hierarchy with v2 matching" do
|
41
66
|
expect(recreated_expected).to eq expected
|
42
67
|
end
|
68
|
+
|
69
|
+
it "recreates the same object hierarchy with v3 matching" do
|
70
|
+
expect(recreated_expected_v3).to eq expected
|
71
|
+
end
|
43
72
|
end
|
44
73
|
|
45
74
|
context "with a Pact::SomethingLike containing a Hash" do
|
@@ -61,9 +90,13 @@ describe "converting Pact::Term and Pact::SomethingLike to matching rules and ba
|
|
61
90
|
}
|
62
91
|
end
|
63
92
|
|
64
|
-
it "recreates the same object hierarchy" do
|
93
|
+
it "recreates the same object hierarchy with v2 matching" do
|
65
94
|
expect(recreated_expected).to eq expected
|
66
95
|
end
|
96
|
+
|
97
|
+
it "recreates the same object hierarchy with v3 matching" do
|
98
|
+
expect(recreated_expected_v3).to eq expected
|
99
|
+
end
|
67
100
|
end
|
68
101
|
|
69
102
|
context "with a Pact::SomethingLike containing an Array" do
|
@@ -83,8 +116,12 @@ describe "converting Pact::Term and Pact::SomethingLike to matching rules and ba
|
|
83
116
|
}
|
84
117
|
end
|
85
118
|
|
86
|
-
it "recreates the same object hierarchy" do
|
119
|
+
it "recreates the same object hierarchy with v2 matching" do
|
87
120
|
expect(recreated_expected).to eq expected
|
88
121
|
end
|
122
|
+
|
123
|
+
it "recreates the same object hierarchy with v3 matching" do
|
124
|
+
expect(recreated_expected_v3).to eq expected
|
125
|
+
end
|
89
126
|
end
|
90
127
|
end
|
@@ -3,6 +3,26 @@ 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
|
+
|
6
26
|
describe ".from_json" do
|
7
27
|
|
8
28
|
let(:loaded_pact) { ConsumerContract.from_json(string) }
|
@@ -0,0 +1,62 @@
|
|
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
|
@@ -52,58 +52,7 @@ 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
|
57
55
|
|
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
|
107
56
|
|
108
57
|
describe "request_modifies_resource_without_checking_response_body?" do
|
109
58
|
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'pact/matchers/multipart_form_diff_formatter'
|
2
|
+
|
3
|
+
module Pact
|
4
|
+
module Matchers
|
5
|
+
describe MultipartFormDiffFormatter do
|
6
|
+
describe ".call" do
|
7
|
+
subject { MultipartFormDiffFormatter.call(diff, options)}
|
8
|
+
|
9
|
+
let(:diff) do
|
10
|
+
{
|
11
|
+
headers: header_diff,
|
12
|
+
body: body_diff
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:header_diff) do
|
17
|
+
{
|
18
|
+
"Content-Type" => Difference.new("foo", "bar", "Wrong header")
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
let(:body_diff) do
|
23
|
+
Difference.new("foo", "bar", "A message")
|
24
|
+
end
|
25
|
+
|
26
|
+
let(:options) { {} }
|
27
|
+
|
28
|
+
let(:expected_output) { File.read("spec/fixtures/multipart-form-diff.txt")}
|
29
|
+
|
30
|
+
it "formats the diff" do
|
31
|
+
expect(subject).to eq expected_output
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -7,10 +7,16 @@ module Pact
|
|
7
7
|
subject { Merge.(expected, matching_rules) }
|
8
8
|
|
9
9
|
before do
|
10
|
-
allow($stderr).to receive(:puts)
|
10
|
+
allow($stderr).to receive(:puts) do | message |
|
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
|
11
13
|
end
|
12
14
|
|
13
15
|
describe "no recognised rules" do
|
16
|
+
before do
|
17
|
+
allow($stderr).to receive(:puts)
|
18
|
+
end
|
19
|
+
|
14
20
|
let(:expected) do
|
15
21
|
{
|
16
22
|
"_links" => {
|
@@ -65,6 +71,10 @@ module Pact
|
|
65
71
|
end
|
66
72
|
|
67
73
|
describe "type based matching" do
|
74
|
+
before do
|
75
|
+
allow($stderr).to receive(:puts)
|
76
|
+
end
|
77
|
+
|
68
78
|
let(:expected) do
|
69
79
|
{
|
70
80
|
"name" => "Mary"
|
@@ -88,11 +98,19 @@ module Pact
|
|
88
98
|
subject
|
89
99
|
end
|
90
100
|
|
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
|
91
106
|
end
|
92
107
|
|
93
108
|
describe "regular expressions" do
|
94
|
-
|
95
109
|
describe "in a hash" do
|
110
|
+
before do
|
111
|
+
allow($stderr).to receive(:puts)
|
112
|
+
end
|
113
|
+
|
96
114
|
let(:expected) do
|
97
115
|
{
|
98
116
|
"_links" => {
|
@@ -275,6 +293,10 @@ module Pact
|
|
275
293
|
end
|
276
294
|
|
277
295
|
describe "with an example array with more than one item" do
|
296
|
+
before do
|
297
|
+
allow($stderr).to receive(:puts)
|
298
|
+
end
|
299
|
+
|
278
300
|
let(:expected) do
|
279
301
|
{
|
280
302
|
|
@@ -292,7 +314,7 @@ module Pact
|
|
292
314
|
}
|
293
315
|
end
|
294
316
|
|
295
|
-
|
317
|
+
it "doesn't warn about the min size being ignored" do
|
296
318
|
expect(Pact.configuration.error_stream).to receive(:puts).once
|
297
319
|
subject
|
298
320
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'pact/shared/multipart_form_differ'
|
2
|
+
|
3
|
+
module Pact
|
4
|
+
describe MultipartFormDiffer do
|
5
|
+
|
6
|
+
describe ".call" do
|
7
|
+
|
8
|
+
let(:expected_body) do
|
9
|
+
"-------------RubyMultipartPost-1e4912957c7bb64de3c444568326663b\r\nContent-Disposition: form-data; name=\"file\"; filename=\"text.txt\"\r\nContent-Length: 14\r\nContent-Type: text/plain\r\nContent-Transfer-Encoding: binary\r\n\r\nThis is a file\r\n-------------RubyMultipartPost-1e4912957c7bb64de3c444568326663b--\r\n\r\n"
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:actual_body) do
|
13
|
+
"-------------RubyMultipartPost-1e4912957c7bb64de3c4445683266XXX\r\nContent-Disposition: form-data; name=\"file\"; filename=\"text.txt\"\r\nContent-Length: 14\r\nContent-Type: text/plain\r\nContent-Transfer-Encoding: binary\r\n\r\nThis is a file\r\n-------------RubyMultipartPost-1e4912957c7bb64de3c4445683266XXX--\r\n\r\n"
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:options) do
|
17
|
+
{}
|
18
|
+
end
|
19
|
+
|
20
|
+
subject { MultipartFormDiffer.call(expected_body, actual_body, options) }
|
21
|
+
|
22
|
+
context "when the bodies are the same apart from the boundary" do
|
23
|
+
it "returns an empty diff" do
|
24
|
+
expect(subject).to eq({})
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "when the bodies are not the same" do
|
29
|
+
let(:actual_body) do
|
30
|
+
"-------------RubyMultipartPost-1e4912957c7bb64de3c4445683266XXX\r\nContent-Disposition: form-data; name=\"file\"; filename=\"bar.txt\"\r\nContent-Length: 14\r\nContent-Type: text/plain\r\nContent-Transfer-Encoding: binary\r\n\r\nThis is a file\r\n-------------RubyMultipartPost-1e4912957c7bb64de3c4445683266XXX--\r\n\r\n"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "returns a text diff" do
|
34
|
+
expect(subject).to_not eq({})
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
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.7.0
|
4
|
+
version: 1.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Fraser
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2018-
|
15
|
+
date: 2018-08-06 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: randexp
|
@@ -270,6 +270,9 @@ 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
|
273
276
|
- lib/pact/consumer_contract/pact_file.rb
|
274
277
|
- lib/pact/consumer_contract/query.rb
|
275
278
|
- lib/pact/consumer_contract/query_hash.rb
|
@@ -294,6 +297,7 @@ files:
|
|
294
297
|
- lib/pact/matchers/index_not_found.rb
|
295
298
|
- lib/pact/matchers/list_diff_formatter.rb
|
296
299
|
- lib/pact/matchers/matchers.rb
|
300
|
+
- lib/pact/matchers/multipart_form_diff_formatter.rb
|
297
301
|
- lib/pact/matchers/no_diff_at_index.rb
|
298
302
|
- lib/pact/matchers/regexp_difference.rb
|
299
303
|
- lib/pact/matchers/type_difference.rb
|
@@ -314,6 +318,7 @@ files:
|
|
314
318
|
- lib/pact/shared/jruby_support.rb
|
315
319
|
- lib/pact/shared/json_differ.rb
|
316
320
|
- lib/pact/shared/key_not_found.rb
|
321
|
+
- lib/pact/shared/multipart_form_differ.rb
|
317
322
|
- lib/pact/shared/null_expectation.rb
|
318
323
|
- lib/pact/shared/request.rb
|
319
324
|
- lib/pact/shared/text_differ.rb
|
@@ -328,6 +333,8 @@ files:
|
|
328
333
|
- script/release.sh
|
329
334
|
- script/update-pact-specification-v2
|
330
335
|
- spec/fixtures/interaction-with-matching-rules.json
|
336
|
+
- spec/fixtures/multipart-form-diff.txt
|
337
|
+
- spec/fixtures/not-a-pact.json
|
331
338
|
- spec/fixtures/pact-http-v2.json
|
332
339
|
- spec/fixtures/pact-http-v3.json
|
333
340
|
- spec/integration/matching_rules_extract_and_merge_spec.rb
|
@@ -339,6 +346,7 @@ files:
|
|
339
346
|
- spec/lib/pact/consumer_contract/file_name_spec.rb
|
340
347
|
- spec/lib/pact/consumer_contract/headers_spec.rb
|
341
348
|
- spec/lib/pact/consumer_contract/http_consumer_contract_parser_spec.rb
|
349
|
+
- spec/lib/pact/consumer_contract/interaction_parser_spec.rb
|
342
350
|
- spec/lib/pact/consumer_contract/interaction_spec.rb
|
343
351
|
- spec/lib/pact/consumer_contract/pact_file_spec.rb
|
344
352
|
- spec/lib/pact/consumer_contract/query_hash_spec.rb
|
@@ -357,6 +365,7 @@ files:
|
|
357
365
|
- spec/lib/pact/matchers/matchers_messages_mismatched_value_spec.rb
|
358
366
|
- spec/lib/pact/matchers/matchers_messages_regexp_spec.rb
|
359
367
|
- spec/lib/pact/matchers/matchers_spec.rb
|
368
|
+
- spec/lib/pact/matchers/multipart_form_diff_formatter_spec.rb
|
360
369
|
- spec/lib/pact/matchers/no_diff_at_index_spec.rb
|
361
370
|
- spec/lib/pact/matchers/regexp_difference_spec.rb
|
362
371
|
- spec/lib/pact/matchers/type_difference_spec.rb
|
@@ -373,6 +382,7 @@ files:
|
|
373
382
|
- spec/lib/pact/shared/form_differ_spec.rb
|
374
383
|
- spec/lib/pact/shared/json_differ_spec.rb
|
375
384
|
- spec/lib/pact/shared/key_not_found_spec.rb
|
385
|
+
- spec/lib/pact/shared/multipart_form_differ_spec.rb
|
376
386
|
- spec/lib/pact/shared/request_spec.rb
|
377
387
|
- spec/lib/pact/shared/text_differ_spec.rb
|
378
388
|
- spec/lib/pact/something_like_spec.rb
|
@@ -420,9 +430,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
420
430
|
version: '2.0'
|
421
431
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
422
432
|
requirements:
|
423
|
-
- - "
|
433
|
+
- - ">="
|
424
434
|
- !ruby/object:Gem::Version
|
425
|
-
version:
|
435
|
+
version: '0'
|
426
436
|
requirements: []
|
427
437
|
rubyforge_project:
|
428
438
|
rubygems_version: 2.6.11
|
@@ -431,6 +441,8 @@ specification_version: 4
|
|
431
441
|
summary: Shared code for Pact gems
|
432
442
|
test_files:
|
433
443
|
- spec/fixtures/interaction-with-matching-rules.json
|
444
|
+
- spec/fixtures/multipart-form-diff.txt
|
445
|
+
- spec/fixtures/not-a-pact.json
|
434
446
|
- spec/fixtures/pact-http-v2.json
|
435
447
|
- spec/fixtures/pact-http-v3.json
|
436
448
|
- spec/integration/matching_rules_extract_and_merge_spec.rb
|
@@ -442,6 +454,7 @@ test_files:
|
|
442
454
|
- spec/lib/pact/consumer_contract/file_name_spec.rb
|
443
455
|
- spec/lib/pact/consumer_contract/headers_spec.rb
|
444
456
|
- spec/lib/pact/consumer_contract/http_consumer_contract_parser_spec.rb
|
457
|
+
- spec/lib/pact/consumer_contract/interaction_parser_spec.rb
|
445
458
|
- spec/lib/pact/consumer_contract/interaction_spec.rb
|
446
459
|
- spec/lib/pact/consumer_contract/pact_file_spec.rb
|
447
460
|
- spec/lib/pact/consumer_contract/query_hash_spec.rb
|
@@ -460,6 +473,7 @@ test_files:
|
|
460
473
|
- spec/lib/pact/matchers/matchers_messages_mismatched_value_spec.rb
|
461
474
|
- spec/lib/pact/matchers/matchers_messages_regexp_spec.rb
|
462
475
|
- spec/lib/pact/matchers/matchers_spec.rb
|
476
|
+
- spec/lib/pact/matchers/multipart_form_diff_formatter_spec.rb
|
463
477
|
- spec/lib/pact/matchers/no_diff_at_index_spec.rb
|
464
478
|
- spec/lib/pact/matchers/regexp_difference_spec.rb
|
465
479
|
- spec/lib/pact/matchers/type_difference_spec.rb
|
@@ -476,6 +490,7 @@ test_files:
|
|
476
490
|
- spec/lib/pact/shared/form_differ_spec.rb
|
477
491
|
- spec/lib/pact/shared/json_differ_spec.rb
|
478
492
|
- spec/lib/pact/shared/key_not_found_spec.rb
|
493
|
+
- spec/lib/pact/shared/multipart_form_differ_spec.rb
|
479
494
|
- spec/lib/pact/shared/request_spec.rb
|
480
495
|
- spec/lib/pact/shared/text_differ_spec.rb
|
481
496
|
- spec/lib/pact/something_like_spec.rb
|