pact 1.0.39 → 1.1.0.rc1

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 (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