pact 1.0.39 → 1.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/CHANGELOG.md +1 -17
  2. data/Gemfile.lock +2 -2
  3. data/README.md +18 -27
  4. data/bethtest.rb +30 -0
  5. data/documentation/faq.md +6 -36
  6. data/lib/pact/configuration.rb +0 -4
  7. data/lib/pact/consumer/consumer_contract_builder.rb +1 -1
  8. data/lib/pact/consumer_contract/active_support_support.rb +0 -4
  9. data/lib/pact/matchers/diff_decorator.rb +1 -1
  10. data/lib/pact/matchers/index_not_found.rb +12 -3
  11. data/lib/pact/matchers/matchers.rb +2 -1
  12. data/lib/pact/matchers/nested_json_diff_decorator.rb +48 -0
  13. data/lib/pact/matchers/plus_minus_diff_decorator.rb +92 -0
  14. data/lib/pact/matchers/unexpected_index.rb +13 -3
  15. data/lib/pact/matchers/unexpected_key.rb +12 -3
  16. data/lib/pact/provider/configuration.rb +31 -0
  17. data/lib/pact/provider/matchers.rb +4 -4
  18. data/lib/pact/provider/pact_spec_runner.rb +28 -35
  19. data/lib/pact/provider/print_missing_provider_states.rb +2 -2
  20. data/lib/pact/provider/rspec.rb +7 -16
  21. data/lib/pact/provider/world.rb +0 -6
  22. data/lib/pact/shared/key_not_found.rb +16 -3
  23. data/lib/pact/tasks/task_helper.rb +18 -15
  24. data/lib/pact/templates/provider_state.erb +1 -0
  25. data/lib/pact/version.rb +1 -1
  26. data/spec/lib/pact/matchers/matchers_spec.rb +9 -0
  27. data/spec/lib/pact/matchers/nested_json_diff_decorator_spec.rb +48 -0
  28. data/spec/lib/pact/matchers/plus_minus_diff_decorator_spec.rb +186 -0
  29. data/spec/lib/pact/provider/configuration_spec.rb +131 -102
  30. data/spec/lib/pact/verification_task_spec.rb +10 -0
  31. data/spec/support/pact_helper.rb +2 -5
  32. data/spec/support/stubbing.json +1 -1
  33. data/spec/support/test_app_fail.json +2 -29
  34. data/spec/support/test_app_pass.json +4 -4
  35. data/tasks/pact-test.rake +0 -8
  36. metadata +13 -22
  37. data/lib/pact/matchers/difference_indicator.rb +0 -26
  38. data/lib/pact/provider/rspec/formatter.rb +0 -63
  39. data/lib/pact/provider/rspec/silent_json_formatter.rb +0 -18
  40. data/spec/lib/pact/matchers/index_not_found_spec.rb +0 -21
  41. data/spec/lib/pact/matchers/unexpected_index_spec.rb +0 -20
  42. data/spec/lib/pact/matchers/unexpected_key_spec.rb +0 -20
  43. data/spec/lib/pact/shared/key_not_found_spec.rb +0 -20
  44. data/spec/lib/pact/tasks/task_helper_spec.rb +0 -80
@@ -0,0 +1,186 @@
1
+ require 'spec_helper'
2
+ require 'pact/matchers/plus_minus_diff_decorator'
3
+
4
+ module Pact
5
+ module Matchers
6
+ describe PlusMinusDiffDecorator do
7
+
8
+ describe "#to_s" do
9
+
10
+ subject { PlusMinusDiffDecorator.new(diff).to_s }
11
+
12
+ let(:line_count) { subject.split("\n").size }
13
+
14
+ context "with class based matching" do
15
+ xit "displays nicely"
16
+ end
17
+
18
+ context "with an incorrect value in a hash" do
19
+ let(:diff) { {thing: {alligator: Difference.new({name: 'Mary'}, "Joe" )}} }
20
+
21
+ it "displays '+' next to the unexpected value, and '-' next to the missing one" do
22
+ expect(subject).to match /alligator/
23
+ expect(subject).to match /\-.*Mary/
24
+ expect(subject).to match /\+.*Joe/
25
+ end
26
+
27
+ it "generates the right number of lines, even with ActiveSupport loaded" do
28
+ expect(line_count).to eq 10
29
+ end
30
+
31
+ end
32
+
33
+ context "with an incorrect value in an array" do
34
+ let(:diff) { [NoDiffIndicator.new, Difference.new({name: 'Mary'}, "Joe"), NoDiffIndicator.new] }
35
+
36
+ it "displays '+' next to the incorrect values and '-' next to the missing ones" do
37
+ expect(subject).to match /no difference here!/
38
+ expect(subject).to match /\-.*{/
39
+ expect(subject).to match /\-.*}/
40
+ expect(subject).to match /\-.*Mary/
41
+ expect(subject).to match /\+.*Joe/
42
+ expect(subject).to match /no.*Mary.*Joe.*no/m
43
+ end
44
+
45
+ it "doesn't display the no difference indicator as a change" do
46
+ expect(subject).to match(/^\s+no difference here!,$/)
47
+ end
48
+
49
+ it "generates the right number of lines, even with ActiveSupport loaded" do
50
+ expect(line_count).to eq 10
51
+ end
52
+
53
+ end
54
+
55
+ context "with a regular expression that was not matched" do
56
+ let(:regexp) { %r{http://.*/thing/1234} }
57
+ let(:diff) { {thing: Difference.new(regexp, "pear")} }
58
+
59
+ it "displays the regular expression" do
60
+ expect(subject).to include(regexp.inspect)
61
+ expect(subject).to include(regexp.inspect)
62
+ expect(subject).to match /\-.*thing/
63
+ expect(subject).to match /\+.*pear/
64
+ end
65
+
66
+ it "does not put quotes around the regular expression" do
67
+ expect(subject).to match /\/$/
68
+ expect(subject).to match /: \//
69
+ end
70
+
71
+ it "generates the right number of lines, even with ActiveSupport loaded" do
72
+ expect(line_count).to eq 6
73
+ end
74
+
75
+ end
76
+
77
+ context "with a missing key" do
78
+
79
+ let(:diff) { {thing: {alligator: Difference.new({name: 'Mary'}, KeyNotFound.new )}} }
80
+
81
+ it "it displays '-' next to the missing key and its value" do
82
+ expect(subject).to match /\-.*{/
83
+ expect(subject).to match /\-.*}/
84
+ expect(subject).to match /\-.*alligator/
85
+ expect(subject).to match /\-.*name/
86
+ expect(subject).to match /\-.*Mary/
87
+ end
88
+
89
+ it "does not display the missing key in the actual output" do
90
+ expect(subject).to_not match /\+.*alligator/
91
+ end
92
+
93
+ it "generates the right number of lines, even with ActiveSupport loaded" do
94
+ expect(line_count).to eq 9
95
+ end
96
+ end
97
+
98
+ context "with an unexpected key" do
99
+ let(:diff) { {thing: {alligator: Difference.new(UnexpectedKey.new, {name: 'Mary'} )}} }
100
+
101
+ it "displays '+' next to the unexpected key and its value" do
102
+ expect(subject).to match /\+.*name/
103
+ expect(subject).to match /\+.*Mary/
104
+ expect(subject).to match /\+.*alligator/
105
+ expect(subject).to match /\+.*}/
106
+ expect(subject).to match /\+.*{/
107
+ end
108
+
109
+ it "does not display the unexpected key in the expected output" do
110
+ expect(subject).to_not match /\-.*alligator/
111
+ end
112
+
113
+ it "generates the right number of lines, even with ActiveSupport loaded" do
114
+ expect(line_count).to eq 9
115
+ end
116
+
117
+ end
118
+
119
+ context "with a missing index" do
120
+ let(:diff) { [NoDiffIndicator.new, Difference.new({name: 'Mary'}, IndexNotFound.new)] }
121
+
122
+ it "displays '-' next to the missing items" do
123
+ expect(subject).to match /\-.*Mary/
124
+ expect(subject).to match /\-.*{/
125
+ expect(subject).to match /\-.*}/
126
+ end
127
+
128
+ it "does not display IndexNotFound" do
129
+ expect(subject).to_not match /#{IndexNotFound.new.to_s}/
130
+ end
131
+
132
+ it "generates the right number of lines, even with ActiveSupport loaded" do
133
+ expect(line_count).to eq 9
134
+ end
135
+
136
+ end
137
+
138
+ context "with an unexpected index" do
139
+ let(:diff) { [NoDiffIndicator.new, Difference.new(UnexpectedIndex.new, {name: 'Mary'})] }
140
+
141
+ it "displays '+' next to the unexpected item" do
142
+ expect(subject).to match /\+.*{/
143
+ expect(subject).to match /\+.*}/
144
+ expect(subject).to match /\+.*name/
145
+ expect(subject).to match /\+.*Mary/
146
+ end
147
+
148
+ xit "doesn't mark the 'no difference' as a change" do
149
+ expect(subject).to match /#{NoDiffIndicator.new.to_s},/
150
+ expect(subject).to_not match /\-.*#{NoDiffIndicator.new.to_s}/
151
+ expect(subject).to_not match /\+.*#{NoDiffIndicator.new.to_s}/
152
+ end
153
+
154
+ it "does not display the UnexpectedIndex" do
155
+ expect(subject).to_not match UnexpectedIndex.new.to_s
156
+ end
157
+
158
+ it "generates the right number of lines, even with ActiveSupport loaded" do
159
+ expect(line_count).to eq 9
160
+ end
161
+
162
+ end
163
+
164
+ context "with 2 unexpected indexes" do
165
+ let(:diff) { [NoDiffIndicator.new, Difference.new(UnexpectedIndex.new, {name: 'Mary'}), Difference.new(UnexpectedIndex.new, {name: 'Joe'})] }
166
+
167
+ it "displays '+' next to the unexpected item" do
168
+ expect(subject).to match /\+.*Mary/
169
+ expect(subject).to match /\+.*Joe/
170
+ end
171
+
172
+ it "does not display the UnexpectedIndex" do
173
+ expect(subject).to_not match UnexpectedIndex.new.to_s
174
+ end
175
+
176
+ it "generates the right number of lines, even with ActiveSupport loaded" do
177
+ expect(line_count).to eq 12
178
+ end
179
+
180
+ end
181
+
182
+ end
183
+
184
+ end
185
+ end
186
+ end
@@ -3,162 +3,191 @@ require 'pact/provider/configuration'
3
3
 
4
4
  module Pact::Provider::Configuration
5
5
 
6
- describe "service_provider" do
6
+ describe ConfigurationExtension do
7
7
 
8
8
  before do
9
9
  Pact.clear_configuration
10
10
  end
11
11
 
12
- let(:mock_config) { MockConfig.new }
13
- context "when a provider is configured" do
14
- before do
15
- Pact.service_provider "Fred" do
16
- app { "An app" }
17
- end
18
- end
19
- it "should allow configuration of the test app" do
20
- expect(Pact.configuration.provider.app).to eql "An app"
21
- end
22
- end
12
+ describe "diff_formatter_class" do
23
13
 
24
- context "when a provider is not configured" do
25
- it "raises an error" do
26
- expect{ Pact.configuration.provider }.to raise_error(/Please configure your provider/)
14
+ it "returns the Pact::Matchers::NestedJsonDiffDecorator by default" do
15
+ expect(Pact.configuration.diff_formatter_class).to eq(Pact::Matchers::NestedJsonDiffDecorator)
27
16
  end
28
- end
29
17
 
30
- context "when a provider is configured without an app" do
31
- before do
32
- Pact.service_provider "Fred" do
18
+ context "when plus_and_minus formatter is configured" do
19
+ it "returns the Pact::Matchers::PlusMinusDiffDecorator" do
20
+ Pact.configuration.diff_format = :plus_and_minus
21
+ expect(Pact.configuration.diff_formatter_class).to eq(Pact::Matchers::PlusMinusDiffDecorator)
33
22
  end
34
23
  end
35
- it "uses the app from config.ru" do
36
- expect( Pact.configuration.provider.app ).to be(AppForConfigRu)
37
- end
24
+
38
25
  end
39
- end
40
26
 
41
- describe PactVerification do
27
+ describe "service_provider" do
42
28
 
43
- describe 'create_verification' do
44
- let(:url) {'http://some/uri'}
45
- let(:consumer_name) {'some consumer'}
46
- let(:ref) {:prod}
47
- let(:options) { {:ref => :prod} }
48
- context "with valid values" do
49
- subject do
50
- uri = url
51
- PactVerification.build(consumer_name, options) do
52
- pact_uri uri
53
- end
54
- end
55
29
 
56
- it "creates a Verification" do
57
- Pact::Provider::PactVerification.should_receive(:new).with(consumer_name, url, ref)
58
- subject
59
- end
30
+ it "allows configuration of colour_enabled" do
31
+ Pact.configuration.color_enabled = false
32
+ expect(Pact.configuration.color_enabled).to be_false
60
33
  end
61
34
 
62
- context "with a nil uri" do
63
- subject do
64
- PactVerification.build(consumer_name, options) do
65
- pact_uri nil
35
+ it "sets color_enabled to be true by default" do
36
+ expect(Pact.configuration.color_enabled).to be_true
37
+ end
38
+
39
+ context "when a provider is configured" do
40
+ before do
41
+ Pact.service_provider "Fred" do
42
+ app { "An app" }
66
43
  end
67
44
  end
68
-
69
- it "raises a validation error" do
70
- expect{ subject }.to raise_error /Please provide a pact_uri/
45
+ it "should allow configuration of the test app" do
46
+ expect(Pact.configuration.provider.app).to eql "An app"
71
47
  end
72
48
  end
73
- end
74
- end
75
49
 
76
- describe ServiceProviderDSL do
77
-
78
- describe "initialize" do
50
+ context "when a provider is not configured" do
51
+ it "raises an error" do
52
+ expect{ Pact.configuration.provider }.to raise_error(/Please configure your provider/)
53
+ end
54
+ end
79
55
 
80
- context "with an object instead of a block" do
81
- subject do
82
- ServiceProviderDSL.build 'name' do
83
- app 'blah'
56
+ context "when a provider is configured without an app" do
57
+ before do
58
+ Pact.service_provider "Fred" do
84
59
  end
85
60
  end
86
- it "raises an error" do
87
- expect{ subject }.to raise_error /wrong number of arguments/
61
+ it "uses the app from config.ru" do
62
+ expect( Pact.configuration.provider.app ).to be(AppForConfigRu)
88
63
  end
89
64
  end
90
65
 
91
66
  end
92
67
 
93
- describe "validate" do
94
- context "when no name is provided" do
95
- subject do
96
- ServiceProviderDSL.new ' ' do
97
- app { Object.new }
68
+ describe PactVerification do
69
+
70
+ describe 'create_verification' do
71
+ let(:url) {'http://some/uri'}
72
+ let(:consumer_name) {'some consumer'}
73
+ let(:ref) {:prod}
74
+ let(:options) { {:ref => :prod} }
75
+ context "with valid values" do
76
+ subject do
77
+ uri = url
78
+ PactVerification.build(consumer_name, options) do
79
+ pact_uri uri
80
+ end
98
81
  end
99
- end
100
- it "raises an error" do
101
- expect{ subject.send(:validate)}.to raise_error("Please provide a name for the Provider")
102
- end
103
- end
104
- context "when nil name is provided" do
105
- subject do
106
- ServiceProviderDSL.new nil do
107
- app { Object.new }
82
+
83
+ it "creates a Verification" do
84
+ Pact::Provider::PactVerification.should_receive(:new).with(consumer_name, url, ref)
85
+ subject
108
86
  end
109
87
  end
110
- it "raises an error" do
111
- expect{ subject.send(:validate)}.to raise_error("Please provide a name for the Provider")
88
+
89
+ context "with a nil uri" do
90
+ subject do
91
+ PactVerification.build(consumer_name, options) do
92
+ pact_uri nil
93
+ end
94
+ end
95
+
96
+ it "raises a validation error" do
97
+ expect{ subject }.to raise_error /Please provide a pact_uri/
98
+ end
112
99
  end
113
100
  end
114
101
  end
115
102
 
116
- describe 'honours_pact_with' do
117
- before do
118
- Pact.clear_configuration
103
+ describe ServiceProviderDSL do
104
+
105
+ describe "initialize" do
106
+
107
+ context "with an object instead of a block" do
108
+ subject do
109
+ ServiceProviderDSL.build 'name' do
110
+ app 'blah'
111
+ end
112
+ end
113
+ it "raises an error" do
114
+ expect{ subject }.to raise_error /wrong number of arguments/
115
+ end
116
+ end
117
+
119
118
  end
120
119
 
121
- context "with no optional params" do
122
- subject do
123
- ServiceProviderDSL.build 'some-provider' do
124
- app {}
125
- honours_pact_with 'some-consumer' do
126
- pact_uri 'blah'
120
+ describe "validate" do
121
+ context "when no name is provided" do
122
+ subject do
123
+ ServiceProviderDSL.new ' ' do
124
+ app { Object.new }
127
125
  end
128
126
  end
127
+ it "raises an error" do
128
+ expect{ subject.send(:validate)}.to raise_error("Please provide a name for the Provider")
129
+ end
129
130
  end
130
- it 'adds a verification to the Pact.configuration' do
131
- subject
132
- expect(Pact.configuration.pact_verifications.first).to eq(Pact::Provider::PactVerification.new('some-consumer', 'blah', :head))
131
+ context "when nil name is provided" do
132
+ subject do
133
+ ServiceProviderDSL.new nil do
134
+ app { Object.new }
135
+ end
136
+ end
137
+ it "raises an error" do
138
+ expect{ subject.send(:validate)}.to raise_error("Please provide a name for the Provider")
139
+ end
133
140
  end
134
141
  end
135
142
 
136
- context "with all params specified" do
137
- subject do
138
- ServiceProviderDSL.build 'some-provider' do
139
- app {}
140
- honours_pact_with 'some-consumer', :ref => :prod do
141
- pact_uri 'blah'
143
+ describe 'honours_pact_with' do
144
+ before do
145
+ Pact.clear_configuration
146
+ end
147
+
148
+ context "with no optional params" do
149
+ subject do
150
+ ServiceProviderDSL.build 'some-provider' do
151
+ app {}
152
+ honours_pact_with 'some-consumer' do
153
+ pact_uri 'blah'
154
+ end
142
155
  end
143
156
  end
157
+ it 'adds a verification to the Pact.configuration' do
158
+ subject
159
+ expect(Pact.configuration.pact_verifications.first).to eq(Pact::Provider::PactVerification.new('some-consumer', 'blah', :head))
160
+ end
144
161
  end
145
- it 'adds a verification to the Pact.configuration' do
146
- subject
147
- expect(Pact.configuration.pact_verifications.first).to eq(Pact::Provider::PactVerification.new('some-consumer', 'blah', :prod))
162
+
163
+ context "with all params specified" do
164
+ subject do
165
+ ServiceProviderDSL.build 'some-provider' do
166
+ app {}
167
+ honours_pact_with 'some-consumer', :ref => :prod do
168
+ pact_uri 'blah'
169
+ end
170
+ end
171
+ end
172
+ it 'adds a verification to the Pact.configuration' do
173
+ subject
174
+ expect(Pact.configuration.pact_verifications.first).to eq(Pact::Provider::PactVerification.new('some-consumer', 'blah', :prod))
175
+ end
176
+
148
177
  end
149
178
 
150
179
  end
151
-
152
180
  end
153
- end
154
181
 
155
- describe ServiceProviderConfig do
156
- describe "app" do
157
- subject { ServiceProviderConfig.new { Object.new } }
158
- it "should execute the app_block each time" do
159
- expect(subject.app.object_id).to_not equal(subject.app.object_id)
182
+ describe ServiceProviderConfig do
183
+ describe "app" do
184
+ subject { ServiceProviderConfig.new { Object.new } }
185
+ it "should execute the app_block each time" do
186
+ expect(subject.app.object_id).to_not equal(subject.app.object_id)
187
+ end
160
188
  end
161
189
  end
162
190
  end
163
191
 
192
+
164
193
  end