pact-support 1.7.0.alpha.1 → 1.7.0
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 +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
|