pact-support 1.4.0 → 1.8.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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +143 -0
  3. data/lib/pact/configuration.rb +4 -0
  4. data/lib/pact/consumer_contract/consumer_contract.rb +19 -8
  5. data/lib/pact/consumer_contract/http_consumer_contract_parser.rb +37 -0
  6. data/lib/pact/consumer_contract/interaction.rb +57 -56
  7. data/lib/pact/consumer_contract/interaction_parser.rb +23 -0
  8. data/lib/pact/consumer_contract/interaction_v2_parser.rb +34 -0
  9. data/lib/pact/consumer_contract/interaction_v3_parser.rb +73 -0
  10. data/lib/pact/consumer_contract/pact_file.rb +24 -24
  11. data/lib/pact/consumer_contract/provider_state.rb +34 -0
  12. data/lib/pact/consumer_contract/query.rb +0 -2
  13. data/lib/pact/consumer_contract/query_hash.rb +6 -0
  14. data/lib/pact/consumer_contract/query_string.rb +2 -2
  15. data/lib/pact/consumer_contract/request.rb +1 -5
  16. data/lib/pact/consumer_contract/string_with_matching_rules.rb +17 -0
  17. data/lib/pact/matchers/multipart_form_diff_formatter.rb +41 -0
  18. data/lib/pact/matching_rules/merge.rb +43 -28
  19. data/lib/pact/matching_rules/v3/extract.rb +94 -0
  20. data/lib/pact/matching_rules/v3/merge.rb +135 -0
  21. data/lib/pact/matching_rules.rb +19 -6
  22. data/lib/pact/reification.rb +6 -3
  23. data/lib/pact/shared/multipart_form_differ.rb +14 -0
  24. data/lib/pact/specification_version.rb +18 -0
  25. data/lib/pact/support/version.rb +1 -1
  26. data/script/release.sh +1 -1
  27. data/spec/fixtures/multipart-form-diff.txt +9 -0
  28. data/spec/fixtures/not-a-pact.json +3 -0
  29. data/spec/fixtures/pact-http-v2.json +36 -0
  30. data/spec/fixtures/pact-http-v3.json +36 -0
  31. data/spec/integration/matching_rules_extract_and_merge_spec.rb +41 -4
  32. data/spec/lib/pact/consumer_contract/consumer_contract_spec.rb +54 -31
  33. data/spec/lib/pact/consumer_contract/http_consumer_contract_parser_spec.rb +25 -0
  34. data/spec/lib/pact/consumer_contract/interaction_parser_spec.rb +62 -0
  35. data/spec/lib/pact/consumer_contract/interaction_spec.rb +2 -26
  36. data/spec/lib/pact/consumer_contract/interaction_v2_parser_spec.rb +54 -0
  37. data/spec/lib/pact/consumer_contract/interaction_v3_parser_spec.rb +48 -0
  38. data/spec/lib/pact/consumer_contract/pact_file_spec.rb +9 -0
  39. data/spec/lib/pact/consumer_contract/query_hash_spec.rb +23 -0
  40. data/spec/lib/pact/matchers/multipart_form_diff_formatter_spec.rb +36 -0
  41. data/spec/lib/pact/matching_rules/merge_spec.rb +198 -110
  42. data/spec/lib/pact/matching_rules/v3/extract_spec.rb +238 -0
  43. data/spec/lib/pact/matching_rules/v3/merge_spec.rb +462 -0
  44. data/spec/lib/pact/matching_rules_spec.rb +82 -0
  45. data/spec/lib/pact/reification_spec.rb +18 -5
  46. data/spec/lib/pact/shared/multipart_form_differ_spec.rb +39 -0
  47. data/spec/support/factories.rb +5 -0
  48. data/tasks/spec.rake +0 -1
  49. metadata +40 -3
@@ -0,0 +1,462 @@
1
+ require 'pact/matching_rules/v3/merge'
2
+
3
+ module Pact
4
+ module MatchingRules
5
+ module V3
6
+ describe Merge do
7
+ subject { Merge.(expected, matching_rules) }
8
+
9
+ before do
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
13
+ end
14
+
15
+ describe "no recognised rules" do
16
+ before do
17
+ allow($stderr).to receive(:puts)
18
+ end
19
+
20
+ let(:expected) do
21
+ {
22
+ "_links" => {
23
+ "self" => {
24
+ "href" => "http://localhost:1234/thing"
25
+ }
26
+ }
27
+ }
28
+ end
29
+
30
+ let(:matching_rules) do
31
+ {
32
+ "$._links.self.href" => {
33
+ "matchers" => [{ "type" => "unknown" }]
34
+ }
35
+ }
36
+ end
37
+
38
+ it "returns the object at that path unaltered" do
39
+ expect(subject["_links"]["self"]["href"]).to eq "http://localhost:1234/thing"
40
+ end
41
+
42
+ it "it logs the rules it has ignored" do
43
+ expect($stderr).to receive(:puts) do | message |
44
+ expect(message).to include("WARN")
45
+ expect(message).to include("type")
46
+ expect(message).to include("unknown")
47
+ expect(message).to include("$['_links']")
48
+ end
49
+ subject
50
+ end
51
+
52
+ end
53
+
54
+ describe "with nil rules" do
55
+ let(:expected) do
56
+ {
57
+ "_links" => {
58
+ "self" => {
59
+ "href" => "http://localhost:1234/thing"
60
+ }
61
+ }
62
+ }
63
+ end
64
+
65
+ let(:matching_rules) { nil }
66
+
67
+ it "returns the example unaltered" do
68
+ expect(subject["_links"]["self"]["href"]).to eq "http://localhost:1234/thing"
69
+ end
70
+
71
+ end
72
+
73
+ describe "type based matching" do
74
+ before do
75
+ allow($stderr).to receive(:puts)
76
+ end
77
+
78
+ let(:expected) do
79
+ {
80
+ "name" => "Mary"
81
+ }
82
+ end
83
+
84
+ let(:matching_rules) do
85
+ {
86
+ "$.name" => {
87
+ "matchers" => [{ "match" => "type", "ignored" => "matchingrule" }]
88
+ }
89
+ }
90
+ end
91
+
92
+ it "creates a SomethingLike at the appropriate path" do
93
+ expect(subject['name']).to be_instance_of(Pact::SomethingLike)
94
+ end
95
+
96
+ it "it logs the rules it has ignored" do
97
+ expect($stderr).to receive(:puts).once.with(/ignored.*matchingrule/)
98
+ subject
99
+ end
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
106
+ end
107
+
108
+ describe "when a Pact.like is nested inside a Pact.each_like which is nested inside a Pact.like" do
109
+ let(:original_definition) do
110
+ Pact.like('foos' => Pact.each_like(Pact.like('name' => "foo1")))
111
+ end
112
+
113
+ let(:expected) do
114
+ Pact::Reification.from_term(original_definition)
115
+ end
116
+
117
+ let(:matching_rules) do
118
+ Extract.call(original_definition)
119
+ end
120
+
121
+ it "creates a Pact::SomethingLike containing a Pact::ArrayLike containing a Pact::SomethingLike" do
122
+ expect(subject.to_hash).to eq original_definition.to_hash
123
+ end
124
+ end
125
+
126
+ describe "when a Pact.array_like is the top level object" do
127
+ let(:original_definition) do
128
+ Pact.each_like('foos')
129
+ end
130
+
131
+ let(:expected) do
132
+ Pact::Reification.from_term(original_definition)
133
+ end
134
+
135
+ let(:matching_rules) do
136
+ Extract.call(original_definition)
137
+ end
138
+
139
+ it "creates a Pact::ArrayLike" do
140
+ expect(subject.to_hash).to eq original_definition.to_hash
141
+ end
142
+ end
143
+
144
+ describe "when a Pact.like containing an array is the top level object" do
145
+ let(:original_definition) do
146
+ Pact.like(['foos'])
147
+ end
148
+
149
+ let(:expected) do
150
+ Pact::Reification.from_term(original_definition).tap { |it| puts it }
151
+ end
152
+
153
+ let(:matching_rules) do
154
+ Extract.call(original_definition).tap { |it| puts it }
155
+ end
156
+
157
+ it "creates a Pact::SomethingLike" do
158
+ expect(subject).to be_a(Pact::SomethingLike)
159
+ expect(subject.to_hash).to eq original_definition.to_hash
160
+ end
161
+ end
162
+
163
+ describe "regular expressions" do
164
+ describe "in a hash" do
165
+ before do
166
+ allow($stderr).to receive(:puts)
167
+ end
168
+
169
+ let(:expected) do
170
+ {
171
+ "_links" => {
172
+ "self" => {
173
+ "href" => "http://localhost:1234/thing"
174
+ }
175
+ }
176
+ }
177
+ end
178
+
179
+ let(:matching_rules) do
180
+ {
181
+ "$._links.self.href" => {
182
+ "matchers" => [{ "regex" => "http:\\/\\/.*\\/thing", "match" => "regex", "ignored" => "somerule" }]
183
+ }
184
+ }
185
+ end
186
+
187
+ it "creates a Pact::Term at the appropriate path" do
188
+ expect(subject["_links"]["self"]["href"]).to be_instance_of(Pact::Term)
189
+ expect(subject["_links"]["self"]["href"].generate).to eq "http://localhost:1234/thing"
190
+ expect(subject["_links"]["self"]["href"].matcher.inspect).to eq "/http:\\/\\/.*\\/thing/"
191
+ end
192
+
193
+ it "it logs the rules it has ignored" do
194
+ expect($stderr).to receive(:puts) do | message |
195
+ expect(message).to match /ignored.*"somerule"/
196
+ expect(message).to_not match /regex/
197
+ expect(message).to_not match /"match"/
198
+ end
199
+ subject
200
+ end
201
+ end
202
+
203
+ describe "with an array" do
204
+
205
+ let(:expected) do
206
+ {
207
+ "_links" => {
208
+ "self" => [{
209
+ "href" => "http://localhost:1234/thing"
210
+ }]
211
+ }
212
+ }
213
+ end
214
+
215
+ let(:matching_rules) do
216
+ {
217
+ "$._links.self[0].href" => {
218
+ "matchers" => [{ "regex" => "http:\\/\\/.*\\/thing" }]
219
+ }
220
+ }
221
+ end
222
+
223
+ it "creates a Pact::Term at the appropriate path" do
224
+ expect(subject["_links"]["self"][0]["href"]).to be_instance_of(Pact::Term)
225
+ expect(subject["_links"]["self"][0]["href"].generate).to eq "http://localhost:1234/thing"
226
+ expect(subject["_links"]["self"][0]["href"].matcher.inspect).to eq "/http:\\/\\/.*\\/thing/"
227
+ end
228
+ end
229
+
230
+ describe "with an ArrayLike containing a Term" do
231
+ let(:expected) do
232
+ ["foo"]
233
+ end
234
+
235
+ let(:matching_rules) do
236
+ {
237
+ "$" => {"matchers" => [{"min" => 1}]},
238
+ "$[*].*" => {"matchers" => [{"match" => "type"}]},
239
+ "$[*]" => {"matchers" => [{"match" => "regex", "regex"=>"f"}]}
240
+ }
241
+ end
242
+
243
+ it "it creates an ArrayLike with a Pact::Term as the contents" do
244
+ expect(subject).to be_a(Pact::ArrayLike)
245
+ expect(subject.contents).to be_a(Pact::Term)
246
+ end
247
+ end
248
+ end
249
+
250
+ describe "with an array where all elements should match by type and the rule is specified on the parent element and there is no min specified" do
251
+ let(:expected) do
252
+ {
253
+ 'alligators' => [{'name' => 'Mary'}]
254
+ }
255
+ end
256
+
257
+ let(:matching_rules) do
258
+ {
259
+ "$.alligators" => {
260
+ "matchers" => [{ 'match' => 'type' }]
261
+ }
262
+ }
263
+ end
264
+
265
+ it "creates a Pact::SomethingLike at the appropriate path" do
266
+ expect(subject["alligators"]).to be_instance_of(Pact::SomethingLike)
267
+ expect(subject["alligators"].contents).to eq ['name' => 'Mary']
268
+ end
269
+ end
270
+
271
+ describe "with an array where all elements should match by type and the rule is specified on the child elements" do
272
+ let(:expected) do
273
+ {
274
+ 'alligators' => [{'name' => 'Mary'}]
275
+ }
276
+ end
277
+
278
+ let(:matching_rules) do
279
+ {
280
+ "$.alligators" => {
281
+ "matchers" => [{ 'min' => 2}]
282
+ },
283
+ "$.alligators[*].*" => {
284
+ "matchers" => [{ 'match' => 'type'}]
285
+ }
286
+ }
287
+ end
288
+ it "creates a Pact::ArrayLike at the appropriate path" do
289
+ expect(subject["alligators"]).to be_instance_of(Pact::ArrayLike)
290
+ expect(subject["alligators"].contents).to eq 'name' => 'Mary'
291
+ expect(subject["alligators"].min).to eq 2
292
+ end
293
+ end
294
+
295
+ describe "with an array where all elements should match by type and the rule is specified on both the parent element and the child elements" do
296
+ let(:expected) do
297
+ {
298
+ 'alligators' => [{'name' => 'Mary'}]
299
+ }
300
+ end
301
+
302
+ let(:matching_rules) do
303
+ {
304
+ "$.alligators" => {
305
+ "matchers" => [{ 'min' => 2, 'match' => 'type' }]
306
+ },
307
+ "$.alligators[*].*" => {
308
+ "matchers" => [{ 'match' => 'type' }]
309
+ }
310
+ }
311
+ end
312
+
313
+ it "creates a Pact::ArrayLike at the appropriate path" do
314
+ expect(subject["alligators"]).to be_instance_of(Pact::SomethingLike)
315
+ expect(subject["alligators"].contents).to be_instance_of(Pact::ArrayLike)
316
+ expect(subject["alligators"].contents.contents).to eq 'name' => 'Mary'
317
+ expect(subject["alligators"].contents.min).to eq 2
318
+ end
319
+ end
320
+
321
+ describe "with an array where all elements should match by type and there is only a match:type on the parent element" do
322
+ let(:expected) do
323
+ {
324
+ 'alligators' => [{'name' => 'Mary'}]
325
+ }
326
+ end
327
+
328
+ let(:matching_rules) do
329
+ {
330
+ "$.alligators" => { 'matchers' => [{'min' => 2, 'match' => 'type'}] },
331
+ }
332
+ end
333
+
334
+ it "creates a Pact::ArrayLike at the appropriate path" do
335
+ expect(subject["alligators"]).to be_instance_of(Pact::ArrayLike)
336
+ expect(subject["alligators"].contents).to eq 'name' => 'Mary'
337
+ expect(subject["alligators"].min).to eq 2
338
+ end
339
+ end
340
+
341
+ describe "with an array where all elements should match by type nested inside another array where all elements should match by type" do
342
+ let(:expected) do
343
+ {
344
+
345
+ 'alligators' => [
346
+ {
347
+ 'name' => 'Mary',
348
+ 'children' => [
349
+ 'age' => 9
350
+ ]
351
+ }
352
+ ]
353
+
354
+ }
355
+ end
356
+
357
+ let(:matching_rules) do
358
+ {
359
+ "$.alligators" => { "matchers" => [{ 'min' => 2, 'match' => 'type' }] },
360
+ "$.alligators[*].children" => { "matchers" => [{ 'min' => 1, 'match' => 'type' }]},
361
+ }
362
+ end
363
+
364
+ it "creates a Pact::ArrayLike at the appropriate path" do
365
+ expect(subject["alligators"].contents['children']).to be_instance_of(Pact::ArrayLike)
366
+ expect(subject["alligators"].contents['children'].contents).to eq 'age' => 9
367
+ expect(subject["alligators"].contents['children'].min).to eq 1
368
+ end
369
+ end
370
+
371
+ describe "with an example array with more than one item" do
372
+ before do
373
+ allow($stderr).to receive(:puts)
374
+ end
375
+
376
+ let(:expected) do
377
+ {
378
+
379
+ 'alligators' => [
380
+ {'name' => 'Mary'},
381
+ {'name' => 'Joe'}
382
+ ]
383
+
384
+ }
385
+ end
386
+
387
+ let(:matching_rules) do
388
+ {
389
+ "$.alligators" => { "matchers" => [{'min' => 2, 'match' => 'type'}] }
390
+ }
391
+ end
392
+
393
+ it "doesn't warn about the min size being ignored" do
394
+ expect(Pact.configuration.error_stream).to receive(:puts).once
395
+ subject
396
+ end
397
+
398
+ it "warns that the other items will be ignored" do
399
+ allow(Pact.configuration.error_stream).to receive(:puts)
400
+ expect(Pact.configuration.error_stream).to receive(:puts).with(/WARN: Only the first item/)
401
+ subject
402
+ end
403
+ end
404
+
405
+ describe "using bracket notation for a Hash" do
406
+ let(:expected) do
407
+ {
408
+ "name" => "Mary"
409
+ }
410
+ end
411
+
412
+ let(:matching_rules) do
413
+ {
414
+ "$['name']" => { "matchers" => [{"match" => "type"}] }
415
+ }
416
+ end
417
+
418
+ it "applies the rule" do
419
+ expect(subject['name']).to be_instance_of(Pact::SomethingLike)
420
+ end
421
+ end
422
+
423
+ describe "with a dot in the path" do
424
+ let(:expected) do
425
+ {
426
+ "first.name" => "Mary"
427
+ }
428
+ end
429
+
430
+ let(:matching_rules) do
431
+ {
432
+ "$['first.name']" => { "matchers" => [{ "match" => "type" }] }
433
+ }
434
+ end
435
+
436
+ it "applies the rule" do
437
+ expect(subject['first.name']).to be_instance_of(Pact::SomethingLike)
438
+ end
439
+ end
440
+
441
+ describe "with an @ in the path" do
442
+ let(:expected) do
443
+ {
444
+ "@name" => "Mary"
445
+ }
446
+ end
447
+
448
+ let(:matching_rules) do
449
+ {
450
+ "$['@name']" => { "matchers" => [ { "match" => "type" }] }
451
+ }
452
+ end
453
+
454
+ it "applies the rule" do
455
+ expect(subject['@name']).to be_instance_of(Pact::SomethingLike)
456
+ end
457
+ end
458
+
459
+ end
460
+ end
461
+ end
462
+ end
@@ -0,0 +1,82 @@
1
+ require 'pact/matching_rules'
2
+
3
+ module Pact
4
+ module MatchingRules
5
+ describe ".merge" do
6
+ before do
7
+ allow(V3::Merge).to receive(:call)
8
+ allow(Merge).to receive(:call)
9
+ allow(Pact.configuration.error_stream).to receive(:puts)
10
+ end
11
+
12
+ let(:object) { double('object') }
13
+ let(:rules) { double('rules') }
14
+ let(:options) { { pact_specification_version: Pact::SpecificationVersion.new(pact_specification_version) } }
15
+
16
+ subject { MatchingRules.merge(object, rules, options)}
17
+
18
+ context "when the pact_specification_version is nil" do
19
+ let(:options) { { pact_specification_version: nil } }
20
+
21
+ it "calls Merge" do
22
+ expect(Merge).to receive(:call)
23
+ subject
24
+ end
25
+ end
26
+
27
+ context "when the pact_specification_version starts with '1.'" do
28
+ let(:pact_specification_version) { "1.0" }
29
+
30
+ it "calls Merge" do
31
+ expect(Merge).to receive(:call)
32
+ subject
33
+ end
34
+ end
35
+
36
+ context "when the pact_specification_version is with '1'" do
37
+ let(:pact_specification_version) { "1" }
38
+
39
+ it "calls Merge" do
40
+ expect(Merge).to receive(:call)
41
+ subject
42
+ end
43
+ end
44
+
45
+ context "when the pact_specification_version starts with '2.'" do
46
+ let(:pact_specification_version) { "2.0" }
47
+
48
+ it "calls Merge" do
49
+ expect(Merge).to receive(:call)
50
+ subject
51
+ end
52
+ end
53
+
54
+ context "when the pact_specification_version starts with '3.'" do
55
+ let(:pact_specification_version) { "3.0" }
56
+
57
+ it "calls V3::Merge" do
58
+ expect(V3::Merge).to receive(:call)
59
+ subject
60
+ end
61
+ end
62
+
63
+ context "when the pact_specification_version starts with '4.'" do
64
+ let(:pact_specification_version) { "4.0" }
65
+
66
+ it "calls V3::Merge" do
67
+ expect(V3::Merge).to receive(:call)
68
+ subject
69
+ end
70
+ end
71
+
72
+ context "when the pact_specification_version is with '11'" do
73
+ let(:pact_specification_version) { "11" }
74
+
75
+ it "calls V3::Merge" do
76
+ expect(V3::Merge).to receive(:call)
77
+ subject
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -122,10 +122,9 @@ module Pact
122
122
  end
123
123
 
124
124
  context "when Hash Query with UTF-8 string" do
125
-
126
125
  subject { Reification.from_term(query)}
127
126
 
128
- let(:query) { QueryHash.new( {param: 'ILove', extra: '寿司'})}
127
+ let(:query) { QueryHash.new(param: 'ILove', extra: '寿司') }
129
128
 
130
129
  it "returns the hash with escaping UTF-8 string" do
131
130
  expect(subject).to eq("param=ILove&extra=%E5%AF%BF%E5%8F%B8")
@@ -133,7 +132,6 @@ module Pact
133
132
  end
134
133
 
135
134
  context "when Hash Query with embeded terms" do
136
-
137
135
  subject { Reification.from_term(query)}
138
136
 
139
137
  let(:query) { QueryHash.new( {param: 'hello', extra: Pact::Term.new(generate: "wonderworld", matcher: /\w+world/)})}
@@ -141,10 +139,9 @@ module Pact
141
139
  it "returns the hash in the natural order, and fills in Terms appropriately" do
142
140
  expect(subject).to eq("param=hello&extra=wonderworld")
143
141
  end
144
-
145
142
  end
146
- context "when Hash Query with Arrays and multiple params with the same name" do
147
143
 
144
+ context "when Hash Query with Arrays and multiple params with the same name" do
148
145
  subject { Reification.from_term(query)}
149
146
 
150
147
  let(:query) { QueryHash.new( {param: 'hello', double: [Pact::Term.new(generate: "wonder", matcher: /\w+/), 'world'], simple: 'bye'})}
@@ -152,8 +149,24 @@ module Pact
152
149
  it "returns the hash in the natural order, and fills in Terms appropriately" do
153
150
  expect(subject).to eq("param=hello&double=wonder&double=world&simple=bye")
154
151
  end
152
+ end
155
153
 
154
+ context "when Hash Query with an ArrayLike" do
155
+ subject { Reification.from_term(query)}
156
+
157
+ let(:query) { QueryHash.new(param: Pact.each_like("1", min: 2)) }
158
+
159
+ it "turns the hash into a string with the right number of params" do
160
+ expect(subject).to eq("param=1&param=1")
161
+ end
156
162
  end
157
163
 
164
+ context "with a StringWithMatchingRules" do
165
+ subject { Reification.from_term(StringWithMatchingRules.new("foo", Pact::SpecificationVersion.new("3"), {}))}
166
+
167
+ it "returns a String" do
168
+ expect(subject.class).to be String
169
+ end
170
+ end
158
171
  end
159
172
  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
@@ -40,6 +40,11 @@ class InteractionFactory
40
40
  'body' => {a: 'response body'}
41
41
  }
42
42
  }
43
+
44
+ if hash.key?(:provider_states) || hash.key?('provider_states')
45
+ defaults.delete('provider_state')
46
+ end
47
+
43
48
  Pact::Interaction.from_hash(stringify_keys(deep_merge(defaults, stringify_keys(hash))))
44
49
  end
45
50
  end
data/tasks/spec.rake CHANGED
@@ -12,4 +12,3 @@ task :spec_with_active_support => [:set_active_support_on] do
12
12
  end
13
13
 
14
14
  task :default => [:spec, :spec_with_active_support]
15
-