pact 1.0.21 → 1.0.22

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@ Do this to generate your change history
2
2
 
3
3
  git log --date=relative --pretty=format:' * %h - %s (%an, %ad)'
4
4
 
5
+ ### 1.0.22 (25 November 2013)
6
+
7
+ * f742833 - Updating README (Beth Skurrie, 36 seconds ago)
8
+ * ec0d9e2 - Refactor config_ru lambda (Beth Skurrie, 8 minutes ago)
9
+ * 5cb5702 - Added code to use app in config.ru if non is specified as per https://github.com/uglyog/pact/issues/9 (Beth Skurrie, 10 minutes ago)
10
+
5
11
  ### 1.0.21 (25 November 2013)
6
12
 
7
13
  * f810795 - add jruby 2.0 to travis (Ronald Holshausen, 4 days ago)
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pact (1.0.21)
4
+ pact (1.0.22)
5
5
  awesome_print (~> 1.1.0)
6
6
  find_a_port (~> 1.0.1)
7
7
  json
data/README.md CHANGED
@@ -1,11 +1,10 @@
1
1
  # Pact
2
2
 
3
- Define a pact between service consumers and providers.
3
+ Define a pact between service consumers and providers, enabling "consumer driven contract" testing.
4
4
 
5
+ Pact provides an RSpec DSL for service consumers to define the requests they will make to a service provider and the responses they expect back. These expectations are used in the consumers specs to provide a mock service provider. The interactions are recorded, and played back in the service provider specs to ensure the service provider actually does provide the response the consumer expects.
5
6
 
6
- Pact provides an RSpec DSL for service consumers to define the request they will make to a service service provider and the response they expect back. This expectation is used in the consumers specs to provide a mock service provider, and is also played back in the service provider specs to ensure the service provider actually does provide the response the consumer expects.
7
-
8
- This allows you to test both sides of an integration point using fast unit tests.
7
+ This allows testing of both sides of an integration point using fast unit tests.
9
8
 
10
9
  This gem is inspired by the concept of "Consumer driven contracts". See http://martinfowler.com/articles/consumerDrivenContracts.html for more information.
11
10
 
@@ -15,9 +14,10 @@ Travis CI Status: [![travis-ci.org Build Status](https://travis-ci.org/uglyog/pa
15
14
  * A services is mocked using an actual process running on a specified port, so javascript clients can be tested as easily as backend clients.
16
15
  * "Provider states" (similar to fixtures) allow the same request to be made with a different expected response.
17
16
  * Consumers specify only the fields they are interested in, allowing a provider to return more fields without breaking the pact. This allows a provider to have a different pact with a different consumer, and know which fields each cares about in a given response.
18
- * Expected interactions are verified to have actually occurred.
19
- * A rake verification task allows a pact at any URI to be checked against a given service provider codebase.
20
- * Different versions of a consumer/provider pair can be easily tested against each other, allowing confidence when deploying new versions of each.
17
+ * Expected interactions are verified to have actually occurred in the consumer specs.
18
+ * The mocked responses are verified to be valid by replaying the interactions against the provider codebase.
19
+ * Rake verification tasks allow a pacts at one or more URIs to be checked against a given service provider codebase.
20
+ * Different versions of a consumer/provider pair can be easily tested against each other, allowing confidence when deploying new versions of each (see the pact_broker and pact_broker-client gems).
21
21
 
22
22
  ## Installation
23
23
 
@@ -154,15 +154,23 @@ Create your API class using the framework of your choice (e.g. Sinatra, Grape) -
154
154
  Create a `pact_helper.rb` in your service provider project. The file must be called pact_helper.rb, however there is some flexibility in where it can be stored. The recommended place is `specs/service_consumers/pact_helper.rb`.
155
155
 
156
156
  ```ruby
157
- require 'my_app' # Require the boot files for your app
157
+ require 'pact/provider/rspec'
158
+ # If you wish to use the same spec_helper file as your unit tests, require it here.
159
+ # Otherwise, you can set up a separate RSpec configuration in this file just for pact:verify.
160
+ require './spec_helper'
158
161
 
159
162
  Pact.service_provider "My Service Provider" do
163
+ # If you have a config.ru file, the app will be loaded from it automatically and you can skip the app config.
164
+ # Otherwise, set your rack app here as you would when using Rack::Test::Methods
165
+
160
166
  app { MyApp.new }
161
167
 
162
168
  honours_pact_with 'My Service Consumer' do
169
+
163
170
  # This example points to a local file, however, on a real project with a continuous
164
171
  # integration box, you would publish your pacts as artifacts,
165
172
  # and point the pact_uri to the pact published by the last successful build.
173
+
166
174
  pact_uri '../path-to-your-consumer-project/specs/pacts/my_consumer-my_provider.json'
167
175
  end
168
176
  end
@@ -306,33 +314,14 @@ Configure the pact_uri in the Pact.service_provider block with the pact artifact
306
314
 
307
315
  It should run with all your other tests. If an integration is broken, you want to know about it *before* you check in.
308
316
 
309
- #### Load your app from the config.ru file
310
-
311
- Your config.ru file may mount your app at a specified path. e.g.
312
-
313
- ```
314
- run Rack::URLMap.new( '/some-path' => MyServiceProvider::API )
315
- ```
316
-
317
- To avoid duplicating this code, and potentially letting your tests get out of sync with the config.ru file, you can parse the config.ru file and use the returned app in your service provider definition. e.g.
318
-
319
- ```
320
- def app_in_config_ru
321
- app, options = Rack::Builder.parse_file('config.ru')
322
- app
323
- end
324
-
325
- Pact.service_provider "My Service Provider" do
326
- app { app_in_config_ru }
327
- end
328
- ```
329
-
330
- Be aware that the Rack::Builder.parse_file seems to require files even if they have already been required, so make sure your boot files are idempotent.
331
-
332
317
  #### Use the real database
333
318
 
334
319
  Do not stub your database calls for pact:verify. This is the best time for you to test your database integration. If you stub your database calls, you are getting little more assurance that the real end-to-end will work than if you'd used a unit test. It's the appropriate time to incur the overhead of a database call.
335
320
 
321
+ ## Gotchas
322
+
323
+ * Be aware when using the app from the config.ru file is used (the default option) that the Rack::Builder.parse_file seems to require files even if they have already been required, so make sure your boot files are idempotent.
324
+
336
325
  ## Advanced
337
326
 
338
327
  ### Filtering the pact:verify specs
@@ -398,8 +387,6 @@ See https://www.relishapp.com/rspec/rspec-core/docs/hooks/filters for more infor
398
387
 
399
388
  Short term:
400
389
  - FIX EXAMPLE!!!
401
- - Make a pact-broker to store and return all the pacts, removing dependency on the CI box URLs.
402
- - Provide a better work around for ActiveSupport JSON rubygems hell.
403
390
 
404
391
  Long term:
405
392
  - Provide more flexible matching (eg the keys should match, and the classes of the values should match, but the values of each key do not need to be equal). This is to make the pact verification less brittle.
data/config.ru ADDED
@@ -0,0 +1,3 @@
1
+ require './spec/support/app_for_config_ru'
2
+
3
+ run AppForConfigRu
@@ -34,6 +34,14 @@ module Pact
34
34
  def pact_verifications
35
35
  @pact_verifications ||= []
36
36
  end
37
+
38
+ def config_ru_path
39
+ @config_ru_path ||= './config.ru'
40
+ end
41
+
42
+ def config_ru_path= config_ru_path
43
+ @config_ru_path = config_ru_path
44
+ end
37
45
  end
38
46
 
39
47
  Pact::Configuration.send(:include, ConfigurationExtension)
@@ -89,9 +97,11 @@ module Pact
89
97
 
90
98
  attr_accessor :name, :app_block
91
99
 
100
+ CONFIG_RU_APP = lambda { Rack::Builder.parse_file(Pact.configuration.config_ru_path).first }
101
+
92
102
  def initialize name
93
103
  @name = name
94
- @app_block = nil
104
+ @app_block = CONFIG_RU_APP
95
105
  end
96
106
 
97
107
  dsl do
@@ -117,7 +127,6 @@ module Pact
117
127
 
118
128
  def validate
119
129
  raise "Please provide a name for the Provider" unless name && !name.strip.empty?
120
- raise "Please configure an app for the Provider" unless app_block
121
130
  end
122
131
 
123
132
  def create_service_provider
data/lib/pact/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Pact
2
- VERSION = "1.0.21"
2
+ VERSION = "1.0.22"
3
3
  end
@@ -26,6 +26,16 @@ module Pact::Provider::Configuration
26
26
  expect{ Pact.configuration.provider }.to raise_error(/Please configure your provider/)
27
27
  end
28
28
  end
29
+
30
+ context "when a provider is configured without an app" do
31
+ before do
32
+ Pact.service_provider "Fred" do
33
+ end
34
+ end
35
+ it "uses the app from config.ru" do
36
+ expect( Pact.configuration.provider.app ).to be(AppForConfigRu)
37
+ end
38
+ end
29
39
  end
30
40
 
31
41
  describe PactVerification do
@@ -101,15 +111,6 @@ module Pact::Provider::Configuration
101
111
  expect{ subject.send(:validate)}.to raise_error("Please provide a name for the Provider")
102
112
  end
103
113
  end
104
- context "when no app is provided" do
105
- subject do
106
- ServiceProviderDSL.new 'Blah' do
107
- end
108
- end
109
- it "raises an error" do
110
- expect{ subject.send(:validate) }.to raise_error("Please configure an app for the Provider")
111
- end
112
- end
113
114
  end
114
115
 
115
116
  describe 'honours_pact_with' do
@@ -0,0 +1,4 @@
1
+ class AppForConfigRu
2
+ def call env
3
+ end
4
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pact
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.21
4
+ version: 1.0.22
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -279,6 +279,7 @@ files:
279
279
  - README.md
280
280
  - Rakefile
281
281
  - bin/pact
282
+ - config.ru
282
283
  - example/animal-service/Gemfile
283
284
  - example/animal-service/Gemfile.lock
284
285
  - example/animal-service/Rakefile
@@ -395,6 +396,7 @@ files:
395
396
  - spec/spec_helper.rb
396
397
  - spec/support/a_consumer-a_producer.json
397
398
  - spec/support/a_consumer-a_provider.json
399
+ - spec/support/app_for_config_ru.rb
398
400
  - spec/support/consumer_contract_template.json
399
401
  - spec/support/dsl_spec_support.rb
400
402
  - spec/support/factories.rb
@@ -419,7 +421,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
419
421
  version: '0'
420
422
  segments:
421
423
  - 0
422
- hash: -2335732393810580306
424
+ hash: 1182047425998304532
423
425
  required_rubygems_version: !ruby/object:Gem::Requirement
424
426
  none: false
425
427
  requirements:
@@ -428,7 +430,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
428
430
  version: '0'
429
431
  segments:
430
432
  - 0
431
- hash: -2335732393810580306
433
+ hash: 1182047425998304532
432
434
  requirements: []
433
435
  rubyforge_project:
434
436
  rubygems_version: 1.8.23
@@ -475,6 +477,7 @@ test_files:
475
477
  - spec/spec_helper.rb
476
478
  - spec/support/a_consumer-a_producer.json
477
479
  - spec/support/a_consumer-a_provider.json
480
+ - spec/support/app_for_config_ru.rb
478
481
  - spec/support/consumer_contract_template.json
479
482
  - spec/support/dsl_spec_support.rb
480
483
  - spec/support/factories.rb