pact-support 0.2.1 → 0.3.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.
@@ -1,5 +1,5 @@
1
1
  module Pact
2
2
  module Support
3
- VERSION = "0.2.1"
3
+ VERSION = "0.3.0"
4
4
  end
5
5
  end
data/lib/pact/term.rb CHANGED
@@ -27,7 +27,7 @@ module Pact
27
27
  @matcher = attributes[:matcher]
28
28
  raise "Please specify a matcher for the Term" unless @matcher != nil
29
29
  raise "Please specify a value to generate for the Term" unless @generate != nil
30
- raise "Value to generate \"#{@generate}\" does not match regular expression #{@matcher}" unless @generate =~ @matcher
30
+ raise "Value to generate \"#{@generate}\" does not match regular expression #{@matcher.inspect}" unless @generate =~ @matcher
31
31
  end
32
32
 
33
33
  def to_hash
@@ -0,0 +1,27 @@
1
+ {
2
+ "description": "a request to make something",
3
+ "providerState" : null,
4
+ "request" : {
5
+ "method" : "POST",
6
+ "path" : "/something",
7
+ "body": {
8
+ "name": "Mary"
9
+ },
10
+ "requestMatchingRules": {
11
+ "$.body.name" : {"regex" : ".+"}
12
+ }
13
+ },
14
+ "response" : {
15
+ "status" : 200,
16
+ "body" : {
17
+ "_links" : {
18
+ "self" : {
19
+ "href" : "http://localhost:1234/things/1"
20
+ }
21
+ }
22
+ },
23
+ "responseMatchingRules" : {
24
+ "$.body._links.self.href": {"regex": "http:\\/\\/.*\\/\\d+"}
25
+ }
26
+ }
27
+ }
@@ -0,0 +1,98 @@
1
+ require 'pact/term'
2
+ require 'pact/something_like'
3
+ require 'pact/matching_rules/extract'
4
+ require 'pact/matching_rules/merge'
5
+ require 'pact/reification'
6
+
7
+ describe "converting Pact::Term and Pact::SomethingLike to matching rules and back again" do
8
+
9
+ let(:example) { Pact::Reification.from_term expected }
10
+ let(:matching_rules) { Pact::MatchingRules::Extract.(expected) }
11
+ let(:recreated_expected) { Pact::MatchingRules::Merge.(example, matching_rules)}
12
+
13
+ context "with a Pact::Term" do
14
+ let(:expected) do
15
+ {
16
+ body: {
17
+ alligator: {
18
+ name: Pact::Term.new(generate: 'Mary', matcher: /M/)
19
+ }
20
+ }
21
+ }
22
+ end
23
+
24
+ it "recreates the same object hierarchy" do
25
+ expect(recreated_expected).to eq expected
26
+ end
27
+ end
28
+
29
+ context "with a Pact::SomethingLike" do
30
+ let(:expected) do
31
+ {
32
+ body: {
33
+ alligator: {
34
+ name: Pact::SomethingLike.new("Mary")
35
+ }
36
+ }
37
+ }
38
+ end
39
+
40
+ it "recreates the same object hierarchy" do
41
+ expect(recreated_expected).to eq expected
42
+ end
43
+ end
44
+
45
+ context "with a Pact::SomethingLike containing a Hash" do
46
+ let(:expected) do
47
+ {
48
+ body: {
49
+ alligator: Pact::SomethingLike.new(name: 'Mary')
50
+ }
51
+ }
52
+ end
53
+
54
+ let(:similar) do
55
+ {
56
+ body: {
57
+ alligator: {
58
+ name: Pact::SomethingLike.new('Mary')
59
+ }
60
+ }
61
+ }
62
+ end
63
+
64
+ it "recreates the same object hierarchy", pending: 'Waiting for Pact JVM to implement nested type matching' do
65
+ expect(recreated_expected).to eq expected
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
+ end
72
+
73
+ context "with a Pact::SomethingLike containing an Array" do
74
+ let(:expected) do
75
+ {
76
+ body: {
77
+ alligators: Pact::SomethingLike.new(["Mary", "Betty"])
78
+ }
79
+ }
80
+ end
81
+
82
+ let(:similar) do
83
+ {
84
+ body: {
85
+ alligators: [Pact::SomethingLike.new("Mary"), Pact::SomethingLike.new("Betty")]
86
+ }
87
+ }
88
+ end
89
+
90
+ it "recreates the same object hierarchy", pending: 'Waiting for Pact JVM to implement nested type matching' do
91
+ expect(recreated_expected).to eq expected
92
+ 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
+ end
98
+ end
@@ -61,6 +61,20 @@ module Pact
61
61
  expect(subject.provider_state).to eq 'some state'
62
62
  end
63
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 }
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
64
78
  end
65
79
 
66
80
  describe "request_modifies_resource_without_checking_response_body?" do
@@ -80,7 +80,7 @@ EOS
80
80
  end
81
81
 
82
82
  context "when there is a missing index" do
83
- let(:diff) { [NoDiffIndicator.new, Difference.new(1, IndexNotFound.new )]}
83
+ let(:diff) { [NoDiffAtIndex.new, Difference.new(1, IndexNotFound.new )]}
84
84
  it "includes the expected value" do
85
85
  expect(subject).to match(/Missing.*1/m)
86
86
  end
@@ -91,7 +91,7 @@ EOS
91
91
  end
92
92
 
93
93
  context "when there is an unexpected index" do
94
- let(:diff) { [NoDiffIndicator.new, Difference.new(UnexpectedIndex.new, 2), Difference.new(UnexpectedIndex.new, "b")]}
94
+ let(:diff) { [NoDiffAtIndex.new, Difference.new(UnexpectedIndex.new, 2), Difference.new(UnexpectedIndex.new, "b")]}
95
95
  it "includes the unexpected value" do
96
96
  expect(subject).to include("Array contained unexpected item:")
97
97
  end
@@ -143,10 +143,11 @@ module Pact::Matchers
143
143
  let(:expected) { [{name: 'Fred'}, {name: 'Mary'}] }
144
144
  context "when an item with differing class values is found" do
145
145
  let(:actual) { [{name: 'Fred'}, {name: 1}] }
146
- let(:difference) { [
147
- Pact::Matchers::NO_DIFF_INDICATOR,
148
- {:name =>
149
- TypeDifference.new(Pact::ExpectedType.new("Mary"), Pact::ActualType.new(1))
146
+ let(:difference) {
147
+ [
148
+ NoDiffAtIndex.new,
149
+ {
150
+ :name => TypeDifference.new(Pact::ExpectedType.new("Mary"), Pact::ActualType.new(1))
150
151
  }
151
152
  ]
152
153
  }
@@ -214,7 +215,7 @@ module Pact::Matchers
214
215
  context "when expected is longer than the actual" do
215
216
  subject { [1,2,3] }
216
217
  let(:actual) { [1,2]}
217
- let(:difference) { [Pact::Matchers::NO_DIFF_INDICATOR, Pact::Matchers::NO_DIFF_INDICATOR, Difference.new(3, Pact::IndexNotFound.new)] }
218
+ let(:difference) { [NoDiffAtIndex.new, NoDiffAtIndex.new, Difference.new(3, Pact::IndexNotFound.new)] }
218
219
  it 'returns the diff' do
219
220
  expect(diff(subject, actual)).to eq(difference)
220
221
  end
@@ -223,7 +224,7 @@ module Pact::Matchers
223
224
  context "when the different index is in the middle of an array" do
224
225
  subject { [1,2,3] }
225
226
  let(:actual) { [1,7,3]}
226
- let(:difference) { [Pact::Matchers::NO_DIFF_INDICATOR, Difference.new(2, 7), Pact::Matchers::NO_DIFF_INDICATOR] }
227
+ let(:difference) { [NoDiffAtIndex.new, Difference.new(2, 7), NoDiffAtIndex.new] }
227
228
  it 'returns the diff' do
228
229
  expect(diff(subject, actual)).to eq(difference)
229
230
  end
@@ -232,7 +233,7 @@ module Pact::Matchers
232
233
  context "when actual array is longer than the expected" do
233
234
  subject { [1] }
234
235
  let(:actual) { [1,2]}
235
- let(:difference) { [Pact::Matchers::NO_DIFF_INDICATOR, Difference.new(Pact::UnexpectedIndex.new, 2)] }
236
+ let(:difference) { [NoDiffAtIndex.new, Difference.new(Pact::UnexpectedIndex.new, 2)] }
236
237
  it 'returns the diff' do
237
238
  expect(diff(subject, actual)).to eq(difference)
238
239
  end
@@ -478,7 +479,7 @@ module Pact::Matchers
478
479
  context "when two different arrays are found" do
479
480
  subject { [4,5,6] }
480
481
  let(:actual) { [4,6,7] }
481
- let(:difference) { [Pact::Matchers::NO_DIFF_INDICATOR, Difference.new(5, 6), Difference.new(6, 7)] }
482
+ let(:difference) { [NoDiffAtIndex.new, Difference.new(5, 6), Difference.new(6, 7)] }
482
483
 
483
484
  it 'includes this in the diff' do
484
485
  expect(diff(subject, actual)).to eq(difference)
@@ -0,0 +1,15 @@
1
+ require 'pact/matchers/no_diff_at_index'
2
+
3
+ module Pact
4
+ module Matchers
5
+ describe NoDiffAtIndex do
6
+
7
+ describe "#to_json" do
8
+ it "returns a json string" do
9
+ expect(NoDiffAtIndex.new.to_json).to eq '"<no difference at this index>"'
10
+ end
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -61,19 +61,19 @@ EOF
61
61
  end
62
62
 
63
63
  context "with an incorrect value in an array" do
64
- let(:diff) { [NoDiffIndicator.new, Difference.new({name: 'Mary'}, "Joe"), NoDiffIndicator.new] }
64
+ let(:diff) { [NoDiffAtIndex.new, Difference.new({name: 'Mary'}, "Joe"), NoDiffAtIndex.new] }
65
65
 
66
66
  it "displays '+' next to the incorrect values and '-' next to the missing ones" do
67
- expect(subject).to match /no difference here!/
67
+ expect(subject).to include "... ,"
68
68
  expect(subject).to match /\-.*{/
69
69
  expect(subject).to match /\-.*}/
70
70
  expect(subject).to match /\-.*Mary/
71
71
  expect(subject).to match /\+.*Joe/
72
- expect(subject).to match /no.*Mary.*Joe.*no/m
72
+ expect(subject).to match /\.\.\..*Mary.*Joe.*\.\.\./m
73
73
  end
74
74
 
75
75
  it "doesn't display the no difference indicator as a change" do
76
- expect(subject).to match(/^\s+"no difference here!",$/)
76
+ expect(subject).to match(/^\s+... ,$/)
77
77
  end
78
78
 
79
79
  it "generates the right number of lines, even with ActiveSupport loaded" do
@@ -147,7 +147,7 @@ EOF
147
147
  end
148
148
 
149
149
  context "with a missing index" do
150
- let(:diff) { [NoDiffIndicator.new, Difference.new({name: 'Mary'}, IndexNotFound.new)] }
150
+ let(:diff) { [NoDiffAtIndex.new, Difference.new({name: 'Mary'}, IndexNotFound.new)] }
151
151
 
152
152
  it "displays '-' next to the missing items" do
153
153
  expect(subject).to match /\-.*Mary/
@@ -160,13 +160,14 @@ 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 8 + key_lines_count
163
+ expect(line_count).to eq 7 + key_lines_count
164
164
  end
165
165
 
166
166
  end
167
167
 
168
168
  context "with an unexpected index" do
169
- let(:diff) { [NoDiffIndicator.new, Difference.new(UnexpectedIndex.new, {name: 'Mary'})] }
169
+ let(:diff) { [NoDiffAtIndex.new, Difference.new(UnexpectedIndex.new, {name: 'Mary'})] }
170
+ let(:diff) { { some_array: [NoDiffAtIndex.new, Difference.new(UnexpectedIndex.new, {name: 'Mary'})]} }
170
171
 
171
172
  it "displays '+' next to the unexpected item" do
172
173
  expect(subject).to match /\+.*{/
@@ -175,10 +176,10 @@ EOF
175
176
  expect(subject).to match /\+.*Mary/
176
177
  end
177
178
 
178
- xit "doesn't mark the 'no difference' as a change" do
179
- expect(subject).to match /#{NoDiffIndicator.new.to_s},/
180
- expect(subject).to_not match /\-.*#{NoDiffIndicator.new.to_s}/
181
- expect(subject).to_not match /\+.*#{NoDiffIndicator.new.to_s}/
179
+ it "doesn't mark the 'no difference' as a change" do
180
+ expect(subject).to include "... ,"
181
+ expect(subject).to_not match /\-.*\.\.\./
182
+ expect(subject).to_not match /\+.*\.\.\./
182
183
  end
183
184
 
184
185
  it "does not display the UnexpectedIndex" do
@@ -186,13 +187,13 @@ EOF
186
187
  end
187
188
 
188
189
  it "generates the right number of lines, even with ActiveSupport loaded" do
189
- expect(line_count).to eq 8 + key_lines_count
190
+ expect(line_count).to eq 9 + key_lines_count
190
191
  end
191
192
 
192
193
  end
193
194
 
194
195
  context "with 2 unexpected indexes" do
195
- let(:diff) { [NoDiffIndicator.new, Difference.new(UnexpectedIndex.new, {name: 'Mary'}), Difference.new(UnexpectedIndex.new, {name: 'Joe'})] }
196
+ let(:diff) { [NoDiffAtIndex.new, Difference.new(UnexpectedIndex.new, {name: 'Mary'}), Difference.new(UnexpectedIndex.new, {name: 'Joe'})] }
196
197
 
197
198
  it "displays '+' next to the unexpected item" do
198
199
  expect(subject).to match /\+.*Mary/
@@ -204,7 +205,7 @@ EOF
204
205
  end
205
206
 
206
207
  it "generates the right number of lines, even with ActiveSupport loaded" do
207
- expect(line_count).to eq 11 + key_lines_count
208
+ expect(line_count).to eq 10 + key_lines_count
208
209
  end
209
210
 
210
211
  end
@@ -0,0 +1,105 @@
1
+ require 'pact/matching_rules/extract'
2
+ require 'pact/something_like'
3
+ require 'pact/term'
4
+
5
+ module Pact
6
+ module MatchingRules
7
+ describe Extract do
8
+
9
+ describe ".call" do
10
+
11
+ subject { Extract.call(matchable) }
12
+
13
+ context "with a Pact::SomethingLike" do
14
+ let(:matchable) do
15
+ {
16
+ body: Pact::SomethingLike.new(foo: 'bar', alligator: { name: 'Mary' })
17
+ }
18
+ end
19
+
20
+ let(:rules) do
21
+ {
22
+ "$.body.foo" => {"match" => "type"},
23
+ "$.body.alligator.name" => {"match" => "type"},
24
+ }
25
+ end
26
+
27
+
28
+ it "creates a rule that matches by type" do
29
+ expect(subject).to eq rules
30
+ end
31
+ end
32
+
33
+ context "with a Pact::Term" do
34
+ let(:matchable) do
35
+ {
36
+ body: {
37
+ alligator: {
38
+ name: Pact::Term.new(generate: 'Mary', matcher: /.*a/)
39
+ }
40
+ }
41
+ }
42
+ end
43
+
44
+ let(:rules) do
45
+ {
46
+ "$.body.alligator.name" => {"match" => "regex", "regex" => ".*a"}
47
+ }
48
+ end
49
+
50
+
51
+ it "creates a rule that matches by regex" do
52
+ expect(subject).to eq rules
53
+ end
54
+ end
55
+
56
+ context "with a Pact::SomethingLike containing a Term" do
57
+ let(:matchable) do
58
+ {
59
+ body: Pact::SomethingLike.new(
60
+ foo: 'bar',
61
+ alligator: { name: Pact::Term.new(generate: 'Mary', matcher: /.*a/) }
62
+ )
63
+ }
64
+ end
65
+
66
+ let(:rules) do
67
+ {
68
+ "$.body.foo" => {"match" => "type"},
69
+ "$.body.alligator.name" => {"match" => "regex", "regex"=>".*a"},
70
+ }
71
+ end
72
+
73
+
74
+ it "the match:regex overrides the match:type" do
75
+ expect(subject).to eq rules
76
+ end
77
+ end
78
+
79
+ context "with a Pact::SomethingLike containing an array" do
80
+ let(:matchable) do
81
+ {
82
+ body: Pact::SomethingLike.new(
83
+ alligators: [
84
+ {name: 'Mary'},
85
+ {name: 'Betty'}
86
+ ]
87
+ )
88
+ }
89
+ end
90
+
91
+ let(:rules) do
92
+ {
93
+ "$.body.alligators[0].name" => {"match" => "type"},
94
+ "$.body.alligators[1].name" => {"match" => "type"}
95
+ }
96
+ end
97
+
98
+ it "lists a rule for each item" do
99
+ expect(subject).to eq rules
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end