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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ad9d08da6cd0f2b5a4916c2f5c12f7749aed29c7
4
- data.tar.gz: 740000cf408626229d5cfd34d445dcf9856285fe
3
+ metadata.gz: 2bbba1bbc7c4a2bf0c9bf83c335bca49f3911b33
4
+ data.tar.gz: 074b3a5fbf4ea09514e9a58d6af2d42d22739942
5
5
  SHA512:
6
- metadata.gz: 618a7e49e43b611c6b7435f94bfe6bc5dba1162d33760a2e4c6643a8b088535354b7457d41e25e292573a87d3f6d126f3ea50f0a8005f4c3a80e7b8d480b0659
7
- data.tar.gz: 7ebdf91b188ca969ecd0cfaf5bb5d516714f3e2096956cfe07c7389020f678ee0d196c03f5aaa6fa6195adf9eed681ffe0c5aadd5585e61610749e9526e74b5e
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
 
@@ -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::Error.new("No consumer contract parser found for hash: #{hash}")
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/matching_rules'
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
- 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
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
- def match_criterion target, criterion
123
- target == criterion || (criterion.is_a?(Regexp) && criterion.match(target))
124
- end
47
+ def match_criterion target, criterion
48
+ target == criterion || (criterion.is_a?(Regexp) && criterion.match(target))
49
+ end
125
50
 
126
- def == other
127
- other.is_a?(Interaction) && to_hash == other.to_hash
128
- end
51
+ def == other
52
+ other.is_a?(Interaction) && to_hash == other.to_hash
53
+ end
129
54
 
130
- def eq? other
131
- self == other
132
- end
55
+ def eq? other
56
+ self == other
57
+ end
133
58
 
134
- def description_with_provider_state_quoted
135
- provider_state ? "\"#{description}\" given \"#{provider_state}\"" : "\"#{description}\""
136
- end
59
+ def description_with_provider_state_quoted
60
+ provider_state ? "\"#{description}\" given \"#{provider_state}\"" : "\"#{description}\""
61
+ end
137
62
 
138
- def request_modifies_resource_without_checking_response_body?
139
- request.modifies_resource? && response.body_allows_any_value?
140
- end
63
+ def request_modifies_resource_without_checking_response_body?
64
+ request.modifies_resource? && response.body_allows_any_value?
65
+ end
141
66
 
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
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
@@ -92,7 +92,7 @@ module Pact
92
92
 
93
93
  def handle_match_type object, path, rules
94
94
  log_used_rule(path, 'match', 'type')
95
- Pact::SomethingLike.new(object)
95
+ Pact::SomethingLike.new(recurse(object, path))
96
96
  end
97
97
 
98
98
  def handle_regex object, path, rules
@@ -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 @expected, @root_path
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, rule), new_matching_rules |
29
- new_matching_rules[JsonPath.new(path).to_s] = rule
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
- 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']
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
- log_ignored_rules(path, rules, {'match' => 'type'})
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
- log_ignored_rules(path, rules, {'match' => 'regex', 'regex' => rules['regex']})
97
- Pact::Term.new(generate: object, matcher: Regexp.new(rules['regex']))
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 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
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
- if dup_rules.any?
106
- $stderr.puts "WARN: Ignoring unsupported matching rules #{dup_rules} for path #{path}"
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
@@ -14,5 +14,5 @@ module Pact
14
14
  end
15
15
  end
16
16
 
17
- SpecificationVersion::NIL_VERSION = Pact::SpecificationVersion.new('')
17
+ SpecificationVersion::NIL_VERSION = Pact::SpecificationVersion.new('0')
18
18
  end
@@ -1,5 +1,5 @@
1
1
  module Pact
2
2
  module Support
3
- VERSION = "1.7.0.alpha.1"
3
+ VERSION = "1.7.0"
4
4
  end
5
5
  end
@@ -0,0 +1,9 @@
1
+
2
+
3
+ Description of differences
4
+ --------------------------------------
5
+ * Wrong header
6
+
7
+ @@ -1,2 +1,2 @@
8
+ -bar
9
+ +foo
@@ -0,0 +1,3 @@
1
+ {
2
+ "foo": "bar"
3
+ }
@@ -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
- xit "doesn't warn about the min size being ignored" do
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.alpha.1
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-07-14 00:00:00.000000000 Z
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: 1.3.1
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