pact-support 1.0.1 → 1.1.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: 1250628a81126493c975c34bd21ac627275e578a
4
- data.tar.gz: 9f7e7f2609e0cc1f0ec03917b0bb35c70e3f36c5
3
+ metadata.gz: f84c7e04ee7c6d3b6a4608b95ec15979fde8c6d9
4
+ data.tar.gz: 2791aef2b37304e4c798ae5bd6c3549537728807
5
5
  SHA512:
6
- metadata.gz: 130b05570e62134204018f8cd5227ffa103b6e4b2d825464131c84e1a6dc24e7318768f3f9a2adc82a0a0cc3098901856390628aca30fd23a4db8283b02ae19c
7
- data.tar.gz: 5a48f981de6dfbbab2d1c0f6f4844f73591c8a0558944593911f92c5d0f57973b5d1fd5905d6186d1ba02e5cd0e64b6856d29800252bf2bc98050df56db6ba46
6
+ metadata.gz: 99b8273204ea956b052383e00f9601251348587911e29a47f04d25dd43d1c8a0e025aed2003f6d4842c5ac0e3e4475fba0498d24a565b84a74bdc0d4e1d27282
7
+ data.tar.gz: 3b658a185abf8011774c01a256ffa7559f81f81c7192bc46907a9f4ab8aeea8fa4114dc1d3bb890ec89a381b9ef84eac75393b420ab067a9129c0cf7e4b4152a
data/CHANGELOG.md CHANGED
@@ -1,6 +1,11 @@
1
1
  Do this to generate your change history
2
2
 
3
- git log --pretty=format:' * %h - %s (%an, %ad)' vX.Y.Z..HEAD
3
+ git log --pretty=format:' * %h - %s (%an, %ad)'
4
+
5
+ ### 1.1.0 (19 June 2017)
6
+ * 1659c54 - Add list of messages to diff output (Beth Skurrie, Mon Jun 19 09:39:08 2017 +1000)
7
+ * e18debc - Reify actual and expected when a type difference is encountered while doing exact matching (Beth Skurrie, Tue May 30 09:24:18 2017 +1000)
8
+ * 2ba49b6 - Updating matching rules extraction to use inheritance as per #34 (Beth Skurrie, Mon May 29 16:17:57 2017 +1000)
4
9
 
5
10
  ### 1.0.1 (11 May 2017)
6
11
  * e34374b - Extract rules for QueryHash and QueryString so we can include request matching rules in the pact. (Beth Skurrie, Thu May 11 09:11:19 2017 +1000)
@@ -162,8 +162,8 @@ module Pact
162
162
 
163
163
  def create_logger
164
164
  FileUtils::mkdir_p log_dir
165
- logger = Logger.new(log_path)
166
- logger.level = Logger::DEBUG
165
+ logger = ::Logger.new(log_path)
166
+ logger.level = ::Logger::DEBUG
167
167
  logger
168
168
  end
169
169
  end
@@ -5,11 +5,13 @@ module Pact
5
5
  module Matchers
6
6
  class BaseDifference
7
7
 
8
- attr_reader :expected, :actual
8
+ attr_reader :expected, :actual, :message
9
+ attr_writer :message
9
10
 
10
- def initialize expected, actual
11
+ def initialize expected, actual, message = nil
11
12
  @expected = expected
12
13
  @actual = actual
14
+ @message = message
13
15
  end
14
16
 
15
17
  def any?
@@ -51,8 +51,8 @@ module Pact
51
51
  end
52
52
  end
53
53
  #Handle the last remaining hunk
54
- output << matching_encoding(oldhunk.diff(format).to_s,output)
55
- output << matching_encoding("\n",output)
54
+ output << matching_encoding(oldhunk.diff(format).to_s, output)
55
+ output << matching_encoding("\n", output)
56
56
  color_diff output
57
57
  rescue Encoding::CompatibilityError
58
58
  if input_data_new.encoding != input_data_old.encoding
@@ -0,0 +1,71 @@
1
+ module Pact
2
+ module Matchers
3
+ class ExtractDiffMessages
4
+
5
+ attr_reader :diff
6
+
7
+ def initialize diff, options = {}
8
+ @diff = diff
9
+ end
10
+
11
+ def self.call diff, options = {}
12
+ new(diff, options).call
13
+ end
14
+
15
+ def to_hash
16
+ diff
17
+ end
18
+
19
+ def call
20
+ to_s
21
+ end
22
+
23
+ def to_s
24
+ diff_messages(diff).join("\n")
25
+ end
26
+
27
+ def diff_messages obj, path = [], messages = []
28
+ case obj
29
+ when Hash then handle_hash obj, path, messages
30
+ when Array then handle_array obj, path, messages
31
+ when BaseDifference then handle_difference obj, path, messages
32
+ when NoDiffAtIndex then nil
33
+ else
34
+ raise "Invalid diff, expected Hash, Array, NoDiffAtIndex or BaseDifference, found #{obj.class}"
35
+ end
36
+ messages
37
+ end
38
+
39
+ def handle_hash hash, path, messages
40
+ hash.each_pair do | key, value |
41
+ next_part = key =~ /\s/ ? key.inspect : key
42
+ diff_messages value, path + [".#{next_part}"], messages
43
+ end
44
+ end
45
+
46
+ def handle_array array, path, messages
47
+ array.each_with_index do | obj, index |
48
+ diff_messages obj, path + ["[#{index}]"], messages
49
+ end
50
+ end
51
+
52
+ def handle_difference difference, path, messages
53
+ if difference.message
54
+ message = "* #{difference.message}"
55
+ message = message.gsub("<path>", path_to_s(path))
56
+ message = message.gsub("<parent_path>", parent_path_to_s(path))
57
+ messages << message
58
+ end
59
+ end
60
+
61
+ def path_to_s path
62
+ "$" + path.join
63
+ end
64
+
65
+ def parent_path_to_s path
66
+ path_to_s(path[0..-2])
67
+ end
68
+
69
+ end
70
+ end
71
+ end
@@ -22,11 +22,11 @@ module Pact
22
22
  NO_DIFF = {}.freeze
23
23
 
24
24
  def diff expected, actual, opts = {}
25
- calculate_diff(Pact::Term.unpack_regexps(expected), actual, DEFAULT_OPTIONS.merge(opts))
25
+ calculate_diff(expected, actual, DEFAULT_OPTIONS.merge(opts))
26
26
  end
27
27
 
28
28
  def type_diff expected, actual, opts = {}
29
- calculate_diff Pact::Term.unpack_regexps(expected), actual, DEFAULT_OPTIONS.merge(opts).merge(type: true)
29
+ calculate_diff expected, actual, DEFAULT_OPTIONS.merge(opts).merge(type: true)
30
30
  end
31
31
 
32
32
  private
@@ -39,17 +39,42 @@ module Pact
39
39
  when Regexp then regexp_diff(expected, actual, options)
40
40
  when Pact::SomethingLike then calculate_diff(expected.contents, actual, options.merge(:type => true))
41
41
  when Pact::ArrayLike then array_like_diff(expected, actual, options)
42
+ when Pact::Term then term_diff(expected, actual, options)
42
43
  else object_diff(expected, actual, options)
43
44
  end
44
45
  end
45
46
 
46
47
  alias_method :structure_diff, :type_diff # Backwards compatibility
47
48
 
49
+ def term_diff term, actual, options
50
+ if actual.is_a?(String)
51
+ actual_term_diff term, actual, options
52
+ else
53
+ RegexpDifference.new term.matcher, Pact::Reification.from_term(actual), "Expected a String matching #{term.matcher.inspect} (like #{term.generate.inspect}) but got #{class_name_with_value_in_brackets(actual)} at <path>"
54
+ end
55
+ end
56
+
57
+ def actual_term_diff term, actual, options
58
+ if term.matcher.match(actual)
59
+ NO_DIFF
60
+ else
61
+ RegexpDifference.new term.matcher, Pact::Reification.from_term(actual), "Expected a String matching #{term.matcher.inspect} (like #{term.generate.inspect}) but got #{actual.inspect} at <path>"
62
+ end
63
+ end
64
+
48
65
  def regexp_diff regexp, actual, options
49
- if actual.is_a?(String) && regexp.match(actual)
66
+ if actual.is_a?(String)
67
+ actual_regexp_diff regexp, actual, options
68
+ else
69
+ RegexpDifference.new regexp, Pact::Reification.from_term(actual), "Expected a String matching #{regexp.inspect} but got #{class_name_with_value_in_brackets(actual)} at <path>"
70
+ end
71
+ end
72
+
73
+ def actual_regexp_diff regexp, actual, options
74
+ if regexp.match(actual)
50
75
  NO_DIFF
51
76
  else
52
- RegexpDifference.new regexp, actual
77
+ RegexpDifference.new regexp, Pact::Reification.from_term(actual), "Expected a String matching #{regexp.inspect} but got #{short_description(actual)} at <path>"
53
78
  end
54
79
  end
55
80
 
@@ -57,7 +82,7 @@ module Pact
57
82
  if actual.is_a? Array
58
83
  actual_array_diff expected, actual, options
59
84
  else
60
- Difference.new expected, actual
85
+ Difference.new Pact::Reification.from_term(expected), Pact::Reification.from_term(actual), type_difference_message(expected, actual)
61
86
  end
62
87
  end
63
88
 
@@ -84,7 +109,7 @@ module Pact
84
109
  expected_array = expected_size.times.collect{ Pact::Term.unpack_regexps(array_like.contents) }
85
110
  actual_array_diff expected_array, actual, options.merge(:type => true)
86
111
  else
87
- Difference.new array_like.generate, actual
112
+ Difference.new array_like.generate, Pact::Reification.from_term(actual), type_difference_message(expected, actual)
88
113
  end
89
114
  end
90
115
 
@@ -92,24 +117,33 @@ module Pact
92
117
  if actual.is_a? Hash
93
118
  actual_hash_diff expected, actual, options
94
119
  else
95
- Difference.new expected, actual
120
+ Difference.new Pact::Reification.from_term(expected), Pact::Reification.from_term(actual), type_difference_message(expected, actual)
96
121
  end
97
122
  end
98
123
 
99
124
  def actual_hash_diff expected, actual, options
100
- hash_diff = expected.each_with_object({}) do |(key, value), difference|
101
- diff_at_key = calculate_diff(value, actual.fetch(key, Pact::KeyNotFound.new), options)
125
+ hash_diff = expected.each_with_object({}) do |(key, expected_value), difference|
126
+ diff_at_key = calculate_diff_at_key(key, expected_value, actual, difference, options)
102
127
  difference[key] = diff_at_key if diff_at_key.any?
103
128
  end
104
129
  hash_diff.merge(check_for_unexpected_keys(expected, actual, options))
105
130
  end
106
131
 
132
+ def calculate_diff_at_key key, expected_value, actual, difference, options
133
+ actual_value = actual.fetch(key, Pact::KeyNotFound.new)
134
+ diff_at_key = calculate_diff(expected_value, actual_value, options)
135
+ if actual_value.is_a?(Pact::KeyNotFound)
136
+ diff_at_key.message = key_not_found_message(key, actual)
137
+ end
138
+ diff_at_key
139
+ end
140
+
107
141
  def check_for_unexpected_keys expected, actual, options
108
142
  if options[:allow_unexpected_keys]
109
143
  NO_DIFF
110
144
  else
111
145
  (actual.keys - expected.keys).each_with_object({}) do | key, running_diff |
112
- running_diff[key] = Difference.new(UnexpectedKey.new, actual[key])
146
+ running_diff[key] = Difference.new(UnexpectedKey.new, actual[key], "Did not expect the key \"#{key}\" to exist at <parent_path>")
113
147
  end
114
148
  end
115
149
  end
@@ -124,7 +158,7 @@ module Pact
124
158
 
125
159
  def exact_value_diff expected, actual, options
126
160
  if expected != actual
127
- Difference.new expected, actual
161
+ Difference.new expected, actual, value_difference_message(expected, actual, options)
128
162
  else
129
163
  NO_DIFF
130
164
  end
@@ -134,7 +168,7 @@ module Pact
134
168
  if types_match? expected, actual
135
169
  NO_DIFF
136
170
  else
137
- TypeDifference.new type_diff_expected_display(expected), type_diff_actual_display(actual)
171
+ TypeDifference.new type_diff_expected_display(expected), type_diff_actual_display(actual), type_difference_message(expected, actual)
138
172
  end
139
173
  end
140
174
 
@@ -154,6 +188,67 @@ module Pact
154
188
  object == true || object == false
155
189
  end
156
190
 
191
+ def has_children? object
192
+ object.is_a?(Hash) || object.is_a?(Array)
193
+ end
194
+
195
+ def value_difference_message expected, actual, options = {}
196
+ case expected
197
+ when Pact::UnexpectedIndex
198
+ "Actual array is too long and should not contain #{short_description(actual)} at <path>"
199
+ else
200
+ case actual
201
+ when Pact::IndexNotFound
202
+ "Actual array is too short and should have contained #{short_description(expected)} at <path>"
203
+ else
204
+ "Expected #{short_description(expected)} but got #{short_description(actual)} at <path>"
205
+ end
206
+ end
207
+ end
208
+
209
+ def type_difference_message expected, actual
210
+ case actual
211
+ when Pact::IndexNotFound
212
+ "Actual array is too short and should have contained #{short_description(expected)} at <path>"
213
+ else
214
+ expected_desc = class_name_with_value_in_brackets(expected)
215
+ expected_desc.gsub!("(", "(like ")
216
+ actual_desc = class_name_with_value_in_brackets(actual)
217
+ message = "Expected #{expected_desc} but got #{actual_desc} at <path>"
218
+ end
219
+ end
220
+
221
+ def class_name_with_value_in_brackets object
222
+ object_desc = has_children?(object) && object.inspect.length < 100 ? "" : " (#{object.inspect})"
223
+ object_desc = if object.nil?
224
+ "nil"
225
+ else
226
+ "#{class_description(object)}#{object_desc}"
227
+ end
228
+ end
229
+
230
+ def key_not_found_message key, actual
231
+ hint = actual.any? ? "(keys present are: #{actual.keys.join(", ")})" : "in empty Hash"
232
+ "Could not find key \"#{key}\" #{hint} at <parent_path>"
233
+ end
234
+
235
+ def short_description object
236
+ return "nil" if object.nil?
237
+ case object
238
+ when Hash then "a Hash"
239
+ when Array then "an Array"
240
+ else object.inspect
241
+ end
242
+ end
157
243
 
244
+ def class_description object
245
+ return "nil" if object.nil?
246
+ clazz = object.class
247
+ case clazz.name[0]
248
+ when /[AEIOU]/ then "an #{clazz}"
249
+ else
250
+ "a #{clazz}"
251
+ end
252
+ end
158
253
  end
159
254
  end
@@ -1,5 +1,6 @@
1
1
  require 'pact/shared/jruby_support'
2
2
  require 'pact/matchers/differ'
3
+ require 'pact/matchers/extract_messages'
3
4
 
4
5
  module Pact
5
6
  module Matchers
@@ -8,15 +9,20 @@ module Pact
8
9
 
9
10
  include JRubySupport
10
11
 
12
+ MESSAGES_TITLE = "\n\nDescription of differences\n--------------------------------------"
13
+
11
14
  def initialize diff, options = {}
12
15
  @diff = diff
13
16
  @colour = options.fetch(:colour, false)
17
+ @actual = options.fetch(:actual, {})
14
18
  @include_explanation = options.fetch(:include_explanation, true)
15
19
  @differ = Pact::Matchers::Differ.new(@colour)
20
+ @messages = Pact::Matchers::ExtractDiffMessages.call(diff)
16
21
  end
17
22
 
18
- def self.call diff, options = {colour: Pact.configuration.color_enabled}
19
- new(diff, options).call
23
+ def self.call diff, options = {}
24
+ default_options = {colour: Pact.configuration.color_enabled}
25
+ new(diff, default_options.merge(options)).call
20
26
  end
21
27
 
22
28
  def call
@@ -24,11 +30,15 @@ module Pact
24
30
  end
25
31
 
26
32
  def to_s
33
+
27
34
  expected = generate_string(diff, :expected)
28
35
  actual = generate_string(diff, :actual)
29
- suffix = @include_explanation ? "\n" + key : ''
30
- string_diff = remove_comma_from_end_of_arrays(@differ.diff_as_string(actual, expected).lstrip)
31
- string_diff + suffix
36
+ suffix = @include_explanation ? key + "\n" : ''
37
+ messages = @include_explanation ? "#{MESSAGES_TITLE}\n#{@messages}\n" : ''
38
+ string_diff = @differ.diff_as_string(actual, expected).lstrip
39
+ string_diff = remove_first_line(string_diff)
40
+ string_diff = remove_comma_from_end_of_arrays(string_diff)
41
+ suffix + string_diff + messages
32
42
  end
33
43
 
34
44
  private
@@ -91,11 +101,22 @@ module Pact
91
101
  end
92
102
 
93
103
  def key
94
- "Key: " + @differ.red("-") + @differ.red(" means \"expected, but was not found\". \n") +
95
- @differ.green(" +") + @differ.green(" means \"actual, should not be found\". \n") +
96
- " Values where the expected matches the actual are not shown.\n"
104
+ "Diff\n--------------------------------------\n" +
105
+ "Key: " + @differ.red("-") + @differ.red(" is expected \n") +
106
+ @differ.green(" +") + @differ.green(" is actual \n") +
107
+ "Matching keys and values are not shown\n"
97
108
  end
98
109
 
110
+ def remove_first_line string_diff
111
+ lines = string_diff.split("\n")
112
+ if lines[0] =~ /@@/
113
+ lines[1..-1].join("\n")
114
+ else
115
+ string_diff
116
+ end
117
+ end
118
+
119
+
99
120
  def add_comma_to_end_of_arrays string
100
121
  string.gsub(/(\n\s*\])/, ',\1')
101
122
  end
@@ -33,8 +33,6 @@ module Pact
33
33
  when Pact::Term then record_regex_rule object, path
34
34
  when Pact::QueryString then recurse(object.query, path, match_type)
35
35
  when Pact::QueryHash then recurse_hash(object.query, path, match_type)
36
- else
37
- record_match_type_rule path, match_type
38
36
  end
39
37
  end
40
38
 
@@ -51,6 +49,7 @@ module Pact
51
49
  end
52
50
 
53
51
  def handle_something_like something_like, path, match_type
52
+ record_match_type_rule path, "type"
54
53
  recurse something_like.contents, path, "type"
55
54
  end
56
55
 
@@ -1,5 +1,5 @@
1
1
  module Pact
2
2
  module Support
3
- VERSION = "1.0.1"
3
+ VERSION = "1.1.0"
4
4
  end
5
5
  end
data/pact-support.gemspec CHANGED
@@ -31,7 +31,7 @@ Gem::Specification.new do |gem|
31
31
  gem.add_development_dependency 'rake', '~> 10.0.3'
32
32
  gem.add_development_dependency 'webmock', '~> 2.0.0'
33
33
  gem.add_development_dependency 'pry'
34
- gem.add_development_dependency 'fakefs', '~> 0.4'
34
+ gem.add_development_dependency 'fakefs', '0.5.2' #0.5.3+ breaks everything
35
35
  gem.add_development_dependency 'hashie', '~> 2.0'
36
36
  gem.add_development_dependency 'activesupport'
37
37
  gem.add_development_dependency 'appraisal'
@@ -61,13 +61,9 @@ describe "converting Pact::Term and Pact::SomethingLike to matching rules and ba
61
61
  }
62
62
  end
63
63
 
64
- it "recreates the same object hierarchy", pending: 'Waiting for Pact JVM to implement nested type matching' do
64
+ it "recreates the same object hierarchy" do
65
65
  expect(recreated_expected).to eq expected
66
66
  end
67
-
68
- it "recreates a similar object hierarchy that does the same thing" do
69
- expect(recreated_expected).to eq similar
70
- end
71
67
  end
72
68
 
73
69
  context "with a Pact::SomethingLike containing an Array" do
@@ -87,12 +83,8 @@ describe "converting Pact::Term and Pact::SomethingLike to matching rules and ba
87
83
  }
88
84
  end
89
85
 
90
- it "recreates the same object hierarchy", pending: 'Waiting for Pact JVM to implement nested type matching' do
86
+ it "recreates the same object hierarchy" do
91
87
  expect(recreated_expected).to eq expected
92
88
  end
93
-
94
- it "recreates a similar object hierarchy that does the same thing" do
95
- expect(recreated_expected).to eq similar
96
- end
97
89
  end
98
90
  end
@@ -0,0 +1,78 @@
1
+ require 'pact/matchers/extract_messages'
2
+
3
+ module Pact
4
+ module Matchers
5
+ describe ExtractDiffMessages do
6
+
7
+ subject { ExtractDiffMessages.call(diff) }
8
+
9
+ context "<path> with a diff in a Hash" do
10
+ let(:diff) { {a: Difference.new(nil, nil, "There was a difference at <path>") } }
11
+
12
+ it { is_expected.to eq "* There was a difference at $.a" }
13
+ end
14
+
15
+ context "<parent_path> with a diff in a Hash" do
16
+ let(:diff) { {a: Difference.new(nil, nil, "There was a difference at <parent_path>") } }
17
+
18
+ it { is_expected.to eq "* There was a difference at $" }
19
+ end
20
+
21
+ context "<path> with a diff in a nested Hash" do
22
+ let(:diff) { {a: {b: Difference.new(nil, nil, "There was a difference at <path>")}} }
23
+
24
+ it { is_expected.to eq "* There was a difference at $.a.b" }
25
+ end
26
+
27
+ context "<parent_path> with a diff in a nested Hash" do
28
+ let(:diff) { {a: {b: Difference.new(nil, nil, "There was a difference at <parent_path>")}} }
29
+
30
+ it { is_expected.to eq "* There was a difference at $.a" }
31
+ end
32
+
33
+ context "<path> with a diff in an Array" do
34
+ let(:diff) { [NoDiffAtIndex.new, Difference.new(nil, nil, "There was a difference at <path>")] }
35
+
36
+ it { is_expected.to eq "* There was a difference at $[1]" }
37
+ end
38
+
39
+ context "<parent_path> with a diff in an Array" do
40
+ let(:diff) { [NoDiffAtIndex.new, Difference.new(nil, nil, "There was a difference at <parent_path>")] }
41
+
42
+ it { is_expected.to eq "* There was a difference at $" }
43
+ end
44
+
45
+ context "<path> with a diff in a nested Array" do
46
+ let(:diff) { [NoDiffAtIndex.new,[NoDiffAtIndex.new, Difference.new(nil, nil, "There was a difference at <path>")]] }
47
+
48
+ it { is_expected.to eq "* There was a difference at $[1][1]" }
49
+ end
50
+
51
+ context "<parent_path> with a diff in a nested Array" do
52
+ let(:diff) { [NoDiffAtIndex.new,[NoDiffAtIndex.new, Difference.new(nil, nil, "There was a difference at <parent_path>")]] }
53
+
54
+ it { is_expected.to eq "* There was a difference at $[1]" }
55
+ end
56
+
57
+ context "when there is a space in the key" do
58
+ let(:diff) do
59
+ {"Foo Bar" => Difference.new(nil, nil, "There was a difference at <path>")}
60
+ end
61
+
62
+ it { is_expected.to eq "* There was a difference at $.\"Foo Bar\"" }
63
+ end
64
+
65
+ context "with two differences" do
66
+ let(:diff) do
67
+ {
68
+ a: Difference.new(nil, nil, "There was a difference at <path>"),
69
+ b: Difference.new(nil, nil, "There was a difference at <path>")
70
+ }
71
+ end
72
+
73
+ it { is_expected.to eq "* There was a difference at $.a\n* There was a difference at $.b" }
74
+ end
75
+
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,134 @@
1
+ require 'spec_helper'
2
+ require 'pact/matchers'
3
+ require 'pact/consumer_contract/headers'
4
+
5
+ module Pact::Matchers
6
+
7
+ describe Pact::Matchers do
8
+ include Pact::Matchers
9
+
10
+ describe "diff" do
11
+ STRING = "foo"
12
+ INT = 1
13
+ FLOAT = 1.0
14
+ HASH = {foo: "bar"}
15
+ ARRAY = ["foo"]
16
+
17
+ context "with a Hash" do
18
+
19
+ context "with a missing key when the actual is an empty Hash" do
20
+ let(:expected) { {thing: "foo"} }
21
+ let(:actual) { {} }
22
+ let(:difference) { diff(expected, actual) }
23
+
24
+ it "returns a message" do
25
+ expect(difference[:thing].message).to eq "Could not find key \"thing\" in empty Hash at <parent_path>"
26
+ end
27
+ end
28
+
29
+ context "with a missing key when the actual is a populated Hash" do
30
+ let(:expected) { {thing: "foo"} }
31
+ let(:actual) { {a_thing: "foo", other_thing: "foo"} }
32
+ let(:difference) { diff(expected, actual) }
33
+
34
+ it "returns a message" do
35
+ expect(difference[:thing].message).to eq "Could not find key \"thing\" (keys present are: a_thing, other_thing) at <parent_path>"
36
+ end
37
+ end
38
+
39
+ context "with an unexpected key" do
40
+ let(:expected) { {thing: "foo"} }
41
+ let(:actual) { {thing: "foo", another_thing: "foo"} }
42
+ let(:difference) { diff(expected, actual, {allow_unexpected_keys: false}) }
43
+
44
+ it "returns a message" do
45
+ expect(difference[:another_thing].message).to eq "Did not expect the key \"another_thing\" to exist at <parent_path>"
46
+ end
47
+ end
48
+ end
49
+
50
+ context "with an Array" do
51
+
52
+ context "with not enough Integer items" do
53
+ let(:expected) { {thing: [1, 2]} }
54
+ let(:actual) { {thing: [1]} }
55
+ let(:difference) { diff(expected, actual) }
56
+
57
+ it "returns a message" do
58
+ expect(difference[:thing][1].message).to eq "Actual array is too short and should have contained 2 at <path>"
59
+ end
60
+ end
61
+
62
+ context "with not enough String items" do
63
+ let(:expected) { {thing: [1, STRING]} }
64
+ let(:actual) { {thing: [1]} }
65
+ let(:difference) { diff(expected, actual) }
66
+
67
+ it "returns a message" do
68
+ expect(difference[:thing][1].message).to eq "Actual array is too short and should have contained \"foo\" at <path>"
69
+ end
70
+ end
71
+
72
+ context "with not enough Hash items" do
73
+ let(:expected) { {thing: [1, HASH]} }
74
+ let(:actual) { {thing: [1]} }
75
+ let(:difference) { diff(expected, actual) }
76
+
77
+ it "returns a message" do
78
+ expect(difference[:thing][1].message).to eq "Actual array is too short and should have contained a Hash at <path>"
79
+ end
80
+ end
81
+
82
+ context "with not enough Array items" do
83
+ let(:expected) { {thing: [1, ARRAY]} }
84
+ let(:actual) { {thing: [1]} }
85
+ let(:difference) { diff(expected, actual) }
86
+
87
+ it "returns a message" do
88
+ expect(difference[:thing][1].message).to eq "Actual array is too short and should have contained an Array at <path>"
89
+ end
90
+ end
91
+
92
+ context "with an extra item that is an Integer" do
93
+ let(:expected) { {thing: [1]} }
94
+ let(:actual) { {thing: [1, 2]} }
95
+ let(:difference) { diff(expected, actual) }
96
+
97
+ it "returns a message" do
98
+ expect(difference[:thing][1].message).to eq "Actual array is too long and should not contain 2 at <path>"
99
+ end
100
+ end
101
+
102
+ context "with an extra item that is a String" do
103
+ let(:expected) { {thing: [1]} }
104
+ let(:actual) { {thing: [1, "foo"]} }
105
+ let(:difference) { diff(expected, actual) }
106
+
107
+ it "returns a message" do
108
+ expect(difference[:thing][1].message).to eq "Actual array is too long and should not contain \"foo\" at <path>"
109
+ end
110
+ end
111
+
112
+ context "with an extra item that is a Hash" do
113
+ let(:expected) { {thing: [1]} }
114
+ let(:actual) { {thing: [1, HASH]} }
115
+ let(:difference) { diff(expected, actual) }
116
+
117
+ it "returns a message" do
118
+ expect(difference[:thing][1].message).to eq "Actual array is too long and should not contain a Hash at <path>"
119
+ end
120
+ end
121
+
122
+ context "with an extra item that is an Array" do
123
+ let(:expected) { {thing: [1]} }
124
+ let(:actual) { {thing: [1, ARRAY]} }
125
+ let(:difference) { diff(expected, actual) }
126
+
127
+ it "returns a message" do
128
+ expect(difference[:thing][1].message).to eq "Actual array is too long and should not contain an Array at <path>"
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+ require 'pact/matchers'
3
+ require 'pact/consumer_contract/headers'
4
+
5
+ module Pact::Matchers
6
+
7
+ describe Pact::Matchers do
8
+ include Pact::Matchers
9
+
10
+ describe "diff" do
11
+ STRING = "foo"
12
+ INT = 1
13
+ FLOAT = 1.0
14
+ HASH = {foo: "bar"}
15
+ ARRAY = ["foo"]
16
+
17
+ COMBINATIONS = [
18
+ [STRING, "bar", "Expected \"foo\" but got \"bar\" at <path>"],
19
+ [STRING, nil, "Expected \"foo\" but got nil at <path>"],
20
+ [STRING, INT, "Expected \"foo\" but got 1 at <path>"],
21
+ [STRING, FLOAT, "Expected \"foo\" but got 1.0 at <path>"],
22
+ [STRING, HASH, "Expected \"foo\" but got a Hash at <path>"],
23
+ [STRING, ARRAY, "Expected \"foo\" but got an Array at <path>"],
24
+ [Pact.like(STRING), "bar", nil],
25
+ [Pact.like(STRING), nil, "Expected a String (like \"foo\") but got nil at <path>"],
26
+ [Pact.like(STRING), INT, "Expected a String (like \"foo\") but got a Fixnum (1) at <path>"],
27
+ [Pact.like(STRING), FLOAT, "Expected a String (like \"foo\") but got a Float (1.0) at <path>"],
28
+ [Pact.like(STRING), HASH, "Expected a String (like \"foo\") but got a Hash at <path>"],
29
+ [Pact.like(STRING), ARRAY, "Expected a String (like \"foo\") but got an Array at <path>"],
30
+ [INT, 2, "Expected 1 but got 2 at <path>"],
31
+ [INT, nil, "Expected 1 but got nil at <path>"],
32
+ [INT, STRING, "Expected 1 but got \"foo\" at <path>"],
33
+ [INT, FLOAT, "Expected 1 but got \"foo\" at <path>", {pending: true}],
34
+ [INT, HASH, "Expected 1 but got a Hash at <path>"],
35
+ [INT, ARRAY, "Expected 1 but got an Array at <path>"],
36
+ [Pact.like(INT), 2, nil],
37
+ [Pact.like(INT), nil, "Expected a Fixnum (like 1) but got nil at <path>"],
38
+ [Pact.like(INT), STRING, "Expected a Fixnum (like 1) but got a String (\"foo\") at <path>"],
39
+ [Pact.like(INT), FLOAT, "Expected a Fixnum (like 1) but got a Float (1.0) at <path>"],
40
+ [Pact.like(INT), HASH, "Expected a Fixnum (like 1) but got a Hash at <path>"],
41
+ [Pact.like(INT), ARRAY, "Expected a Fixnum (like 1) but got an Array at <path>"],
42
+ [HASH, HASH, nil],
43
+ [HASH, nil, "Expected a Hash but got nil at <path>"],
44
+ [HASH, STRING, "Expected a Hash but got a String (\"foo\") at <path>"],
45
+ [HASH, INT, "Expected a Hash but got a Fixnum (1) at <path>"],
46
+ [HASH, FLOAT, "Expected a Hash but got a Float (1.0) at <path>"],
47
+ [HASH, ARRAY, "Expected a Hash but got an Array at <path>"],
48
+ [Pact.like(HASH), STRING, "Expected a Hash but got a String (\"foo\") at <path>"],
49
+ [ARRAY, ARRAY, nil],
50
+ [ARRAY, nil, "Expected an Array but got nil at <path>"],
51
+ [ARRAY, STRING, "Expected an Array but got a String (\"foo\") at <path>"],
52
+ [ARRAY, INT, "Expected an Array but got a Fixnum (1) at <path>"],
53
+ [ARRAY, FLOAT, "Expected an Array but got a Float (1.0) at <path>"],
54
+ [ARRAY, HASH, "Expected an Array but got a Hash at <path>"]
55
+ ]
56
+
57
+ COMBINATIONS.each do | expected, actual, expected_message, options |
58
+ context "when expected is #{expected.inspect} and actual is #{actual.inspect}", options || {} do
59
+ let(:difference) { diff({thing: expected}, {thing: actual}) }
60
+ let(:message) { difference[:thing] ? difference[:thing].message : nil }
61
+
62
+ it "returns the message '#{expected_message}'" do
63
+ expect(message).to eq expected_message
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,101 @@
1
+ require 'spec_helper'
2
+ require 'pact/matchers'
3
+ require 'pact/consumer_contract/headers'
4
+
5
+ module Pact::Matchers
6
+
7
+ describe Pact::Matchers do
8
+ include Pact::Matchers
9
+
10
+ describe "diff" do
11
+ STRING = "foo"
12
+ INT = 1
13
+ FLOAT = 1.0
14
+ HASH = {foo: "bar"}
15
+ ARRAY = ["foo"]
16
+
17
+
18
+ let(:term) { Pact.term(/foo/, "food") }
19
+ let(:regexp) { /foo/ }
20
+ let(:actual) { "drink" }
21
+ let(:difference) { diff({thing: expected}, {thing: actual}) }
22
+
23
+ context "with a Pact::Term" do
24
+ let(:expected) { term }
25
+
26
+ context "when the Pact::Term does not match" do
27
+ it "returns a message" do
28
+ expect(difference[:thing].message).to eq "Expected a String matching /foo/ (like \"food\") but got \"drink\" at <path>"
29
+ end
30
+ end
31
+
32
+ context "when the actual is a Fixnum" do
33
+ let(:actual) { INT }
34
+ it "returns a message" do
35
+ expect(difference[:thing].message).to eq "Expected a String matching /foo/ (like \"food\") but got a Fixnum (1) at <path>"
36
+ end
37
+ end
38
+
39
+ context "when the actual is Hash" do
40
+ let(:actual) { HASH }
41
+ it "returns a message" do
42
+ expect(difference[:thing].message).to eq "Expected a String matching /foo/ (like \"food\") but got a Hash at <path>"
43
+ end
44
+ end
45
+
46
+ context "when the actual is a Fixnum" do
47
+ let(:actual) { INT }
48
+ it "returns a message" do
49
+ expect(difference[:thing].message).to eq "Expected a String matching /foo/ (like \"food\") but got a Fixnum (1) at <path>"
50
+ end
51
+ end
52
+
53
+ context "when the actual is nil" do
54
+ let(:actual) { nil }
55
+ it "returns a message" do
56
+ expect(difference[:thing].message).to eq "Expected a String matching /foo/ (like \"food\") but got nil at <path>"
57
+ end
58
+ end
59
+ end
60
+
61
+ context "with a Regexp" do
62
+
63
+ let(:expected) { regexp }
64
+
65
+ context "when the Pact::Term does not match" do
66
+ it "returns a message" do
67
+ expect(difference[:thing].message).to eq "Expected a String matching /foo/ but got \"drink\" at <path>"
68
+ end
69
+ end
70
+
71
+ context "when the actual is a Fixnum" do
72
+ let(:actual) { INT }
73
+ it "returns a message" do
74
+ expect(difference[:thing].message).to eq "Expected a String matching /foo/ but got a Fixnum (1) at <path>"
75
+ end
76
+ end
77
+
78
+ context "when the actual is Hash" do
79
+ let(:actual) { HASH }
80
+ it "returns a message" do
81
+ expect(difference[:thing].message).to eq "Expected a String matching /foo/ but got a Hash at <path>"
82
+ end
83
+ end
84
+
85
+ context "when the actual is a Fixnum" do
86
+ let(:actual) { INT }
87
+ it "returns a message" do
88
+ expect(difference[:thing].message).to eq "Expected a String matching /foo/ but got a Fixnum (1) at <path>"
89
+ end
90
+ end
91
+
92
+ context "when the actual is nil" do
93
+ let(:actual) { nil }
94
+ it "returns a message" do
95
+ expect(difference[:thing].message).to eq "Expected a String matching /foo/ but got nil at <path>"
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
@@ -45,7 +45,7 @@ module Pact::Matchers
45
45
 
46
46
  context 'when the actual is something like the expected' do
47
47
  let(:expected) { Pact::SomethingLike.new( { a: 1 } ) }
48
- let(:actual) { { a: 2} }
48
+ let(:actual) { { a: 2 } }
49
49
 
50
50
  it 'returns an empty diff' do
51
51
  expect(diff(expected, actual)).to eq({})
@@ -53,6 +53,15 @@ module Pact::Matchers
53
53
 
54
54
  end
55
55
 
56
+ context 'when the there is a mismatch of a parent, and a child contains a SomethingLike' do
57
+ let(:expected) { {thing: {foo: Pact::SomethingLike.new(1)}} }
58
+ let(:actual) { {thing: [Pact::SomethingLike.new(1)]} }
59
+ let(:difference) { {thing: Difference.new({foo: 1}, [1]) } }
60
+
61
+ it "reifies the children" do
62
+ expect(diff(expected, actual)).to eq difference
63
+ end
64
+ end
56
65
  end
57
66
 
58
67
  describe 'option {allow_unexpected_keys: false}' do
@@ -125,14 +134,14 @@ module Pact::Matchers
125
134
  end
126
135
  context "and a hash is found" do
127
136
  let(:actual) { {a: {b: 1}} }
128
- let(:difference) { {:a=>TypeDifference.new(Pact::ExpectedType.new(1), Pact::ActualType.new({:b=>1})) } }
137
+ let(:difference) { {a: TypeDifference.new(Pact::ExpectedType.new(1), Pact::ActualType.new({:b=>1})) } }
129
138
  it "returns the diff" do
130
139
  expect(type_diff(expected, actual)).to eq difference
131
140
  end
132
141
  end
133
142
  context "and an array is found" do
134
143
  let(:actual) { {a: [1] } }
135
- let(:difference) { {:a=>TypeDifference.new(Pact::ExpectedType.new(1), Pact::ActualType.new([1]))}}
144
+ let(:difference) { {a: TypeDifference.new(Pact::ExpectedType.new(1), Pact::ActualType.new([1]))}}
136
145
  it "returns the diff" do
137
146
  expect(type_diff(expected, actual)).to eq difference
138
147
  end
@@ -147,7 +156,7 @@ module Pact::Matchers
147
156
  [
148
157
  NoDiffAtIndex.new,
149
158
  {
150
- :name => TypeDifference.new(Pact::ExpectedType.new("Mary"), Pact::ActualType.new(1))
159
+ name: TypeDifference.new(Pact::ExpectedType.new("Mary"), Pact::ActualType.new(1))
151
160
  }
152
161
  ]
153
162
  }
@@ -162,7 +171,7 @@ module Pact::Matchers
162
171
  let(:expected) { {a: nil} }
163
172
  context "and a string is found" do
164
173
  let(:actual) { {a: 'a string'} }
165
- let(:difference) { {:a=>TypeDifference.new(Pact::ExpectedType.new(nil), Pact::ActualType.new("a string")) } }
174
+ let(:difference) { {a: TypeDifference.new(Pact::ExpectedType.new(nil), Pact::ActualType.new("a string")) } }
166
175
  it "returns the diff" do
167
176
  expect(type_diff(expected, actual)).to eq difference
168
177
  end
@@ -184,8 +193,8 @@ module Pact::Matchers
184
193
  let(:expected) { {a: {b: Pact::Term.new(:matcher => /p/, :generate => 'apple')}} }
185
194
  context "and a non matching value is found" do
186
195
  let(:actual) { {a: nil} }
187
- let(:difference) { {a: Difference.new({b: /p/}, nil)} }
188
- it "returns the diff with the regexp unpacked" do
196
+ let(:difference) { {a: Difference.new({b: "apple"}, nil)} }
197
+ it "returns the diff with the term reified" do
189
198
  expect(type_diff(expected, actual)).to eq difference
190
199
  end
191
200
  end
@@ -264,6 +273,17 @@ module Pact::Matchers
264
273
  expect(diff(subject, actual)).to eq(difference)
265
274
  end
266
275
  end
276
+
277
+ context "when the actual value is an array, and both expected and actual contain SomethingLike" do
278
+ subject { {a: {foo: Pact.like("b")}} }
279
+ let(:actual) { {a: [Pact.like(1)] } }
280
+ let(:difference) { {a: Difference.new({foo: "b"}, [1]) } }
281
+
282
+ it "should return the diff with the reified likes" do
283
+ expect(diff(subject, actual)).to eq(difference)
284
+ end
285
+ end
286
+
267
287
  context "when the actual value is an hash" do
268
288
  let(:actual) { {b: 'c'} }
269
289
  let(:difference) { { a: Difference.new("b",Pact::KeyNotFound.new)} }
@@ -9,7 +9,7 @@ module Pact
9
9
 
10
10
  describe ".call" do
11
11
 
12
- let(:key_lines_count) { 4 }
12
+ let(:key_lines_count) { 9 }
13
13
  let(:colour) { false }
14
14
  subject { UnixDiffFormatter.call(diff, {colour: colour}) }
15
15
 
@@ -55,7 +55,7 @@ EOF
55
55
  end
56
56
 
57
57
  it "generates the right number of lines, even with ActiveSupport loaded" do
58
- expect(line_count).to eq 9 + key_lines_count
58
+ expect(line_count).to eq 8 + key_lines_count
59
59
  end
60
60
 
61
61
  end
@@ -77,7 +77,7 @@ EOF
77
77
  end
78
78
 
79
79
  it "generates the right number of lines, even with ActiveSupport loaded" do
80
- expect(line_count).to eq 9 + key_lines_count
80
+ expect(line_count).to eq 8 + key_lines_count
81
81
  end
82
82
 
83
83
  end
@@ -99,7 +99,7 @@ EOF
99
99
  end
100
100
 
101
101
  it "generates the right number of lines, even with ActiveSupport loaded" do
102
- expect(line_count).to eq 5 + key_lines_count
102
+ expect(line_count).to eq 4 + key_lines_count
103
103
  end
104
104
 
105
105
  end
@@ -121,7 +121,7 @@ EOF
121
121
  end
122
122
 
123
123
  it "generates the right number of lines, even with ActiveSupport loaded" do
124
- expect(line_count).to eq 8 + key_lines_count
124
+ expect(line_count).to eq 7 + key_lines_count
125
125
  end
126
126
  end
127
127
 
@@ -141,7 +141,7 @@ EOF
141
141
  end
142
142
 
143
143
  it "generates the right number of lines, even with ActiveSupport loaded" do
144
- expect(line_count).to eq 8 + key_lines_count
144
+ expect(line_count).to eq 7 + key_lines_count
145
145
  end
146
146
 
147
147
  end
@@ -160,7 +160,7 @@ EOF
160
160
  end
161
161
 
162
162
  it "generates the right number of lines, even with ActiveSupport loaded" do
163
- expect(line_count).to eq 7 + key_lines_count
163
+ expect(line_count).to eq 6 + key_lines_count
164
164
  end
165
165
 
166
166
  end
@@ -187,7 +187,7 @@ EOF
187
187
  end
188
188
 
189
189
  it "generates the right number of lines, even with ActiveSupport loaded" do
190
- expect(line_count).to eq 9 + key_lines_count
190
+ expect(line_count).to eq 8 + key_lines_count
191
191
  end
192
192
 
193
193
  end
@@ -205,7 +205,7 @@ EOF
205
205
  end
206
206
 
207
207
  it "generates the right number of lines, even with ActiveSupport loaded" do
208
- expect(line_count).to eq 10 + key_lines_count
208
+ expect(line_count).to eq 9 + key_lines_count
209
209
  end
210
210
 
211
211
  end
@@ -20,8 +20,7 @@ module Pact
20
20
 
21
21
  let(:rules) do
22
22
  {
23
- "$.body.foo" => {"match" => "type"},
24
- "$.body.alligator.name" => {"match" => "type"}
23
+ "$.body" => {"match" => "type"}
25
24
  }
26
25
  end
27
26
 
@@ -64,7 +63,7 @@ module Pact
64
63
 
65
64
  let(:rules) do
66
65
  {
67
- "$.body.foo" => {"match" => "type"},
66
+ "$.body" => {"match" => "type"},
68
67
  "$.body.alligator.name" => {"match" => "regex", "regex"=>".*a"},
69
68
  }
70
69
  end
@@ -88,8 +87,7 @@ module Pact
88
87
 
89
88
  let(:rules) do
90
89
  {
91
- "$.body.alligators[0].name" => {"match" => "type"},
92
- "$.body.alligators[1].name" => {"match" => "type"}
90
+ "$.body" => {"match" => "type"}
93
91
  }
94
92
  end
95
93
 
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.0.1
4
+ version: 1.1.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: 2017-05-10 00:00:00.000000000 Z
15
+ date: 2017-06-18 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: randexp
@@ -172,16 +172,16 @@ dependencies:
172
172
  name: fakefs
173
173
  requirement: !ruby/object:Gem::Requirement
174
174
  requirements:
175
- - - "~>"
175
+ - - '='
176
176
  - !ruby/object:Gem::Version
177
- version: '0.4'
177
+ version: 0.5.2
178
178
  type: :development
179
179
  prerelease: false
180
180
  version_requirements: !ruby/object:Gem::Requirement
181
181
  requirements:
182
- - - "~>"
182
+ - - '='
183
183
  - !ruby/object:Gem::Version
184
- version: '0.4'
184
+ version: 0.5.2
185
185
  - !ruby/object:Gem::Dependency
186
186
  name: hashie
187
187
  requirement: !ruby/object:Gem::Requirement
@@ -274,6 +274,7 @@ files:
274
274
  - lib/pact/matchers/difference_indicator.rb
275
275
  - lib/pact/matchers/embedded_diff_formatter.rb
276
276
  - lib/pact/matchers/expected_type.rb
277
+ - lib/pact/matchers/extract_messages.rb
277
278
  - lib/pact/matchers/index_not_found.rb
278
279
  - lib/pact/matchers/list_diff_formatter.rb
279
280
  - lib/pact/matchers/matchers.rb
@@ -324,9 +325,13 @@ files:
324
325
  - spec/lib/pact/matchers/differ_spec.rb
325
326
  - spec/lib/pact/matchers/difference_spec.rb
326
327
  - spec/lib/pact/matchers/embedded_diff_formatter_spec.rb
328
+ - spec/lib/pact/matchers/extract_messages_spec.rb
327
329
  - spec/lib/pact/matchers/index_not_found_spec.rb
328
330
  - spec/lib/pact/matchers/list_diff_formatter_spec.rb
329
331
  - spec/lib/pact/matchers/matchers_array_like_spec.rb
332
+ - spec/lib/pact/matchers/matchers_messages_hash_and_array_spec.rb
333
+ - spec/lib/pact/matchers/matchers_messages_mismatched_value_spec.rb
334
+ - spec/lib/pact/matchers/matchers_messages_regexp_spec.rb
330
335
  - spec/lib/pact/matchers/matchers_spec.rb
331
336
  - spec/lib/pact/matchers/no_diff_at_index_spec.rb
332
337
  - spec/lib/pact/matchers/regexp_difference_spec.rb
@@ -391,7 +396,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
391
396
  version: '0'
392
397
  requirements: []
393
398
  rubyforge_project:
394
- rubygems_version: 2.4.5
399
+ rubygems_version: 2.6.11
395
400
  signing_key:
396
401
  specification_version: 4
397
402
  summary: Shared code for Pact gems
@@ -414,9 +419,13 @@ test_files:
414
419
  - spec/lib/pact/matchers/differ_spec.rb
415
420
  - spec/lib/pact/matchers/difference_spec.rb
416
421
  - spec/lib/pact/matchers/embedded_diff_formatter_spec.rb
422
+ - spec/lib/pact/matchers/extract_messages_spec.rb
417
423
  - spec/lib/pact/matchers/index_not_found_spec.rb
418
424
  - spec/lib/pact/matchers/list_diff_formatter_spec.rb
419
425
  - spec/lib/pact/matchers/matchers_array_like_spec.rb
426
+ - spec/lib/pact/matchers/matchers_messages_hash_and_array_spec.rb
427
+ - spec/lib/pact/matchers/matchers_messages_mismatched_value_spec.rb
428
+ - spec/lib/pact/matchers/matchers_messages_regexp_spec.rb
420
429
  - spec/lib/pact/matchers/matchers_spec.rb
421
430
  - spec/lib/pact/matchers/no_diff_at_index_spec.rb
422
431
  - spec/lib/pact/matchers/regexp_difference_spec.rb