pact-support 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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