pact 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ ### 1.0.4 (unreleased)
2
+
3
+ ### 1.0.3 (5 September 2013)
4
+
5
+ * pact_helper.rb is located and loaded automatically if a support_file is not defined in a pact:verify task [Beth Skurrie]
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pact (1.0.2)
4
+ pact (1.0.3)
5
5
  awesome_print (~> 1.1.0)
6
6
  find_a_port (~> 1.0.1)
7
7
  hashie (~> 2.0)
@@ -24,6 +24,7 @@ GEM
24
24
  daemons (1.1.9)
25
25
  diff-lcs (1.2.4)
26
26
  eventmachine (1.0.3)
27
+ fakefs (0.4.2)
27
28
  find_a_port (1.0.1)
28
29
  geminabox-client (0.0.2)
29
30
  multipart-post
@@ -63,6 +64,7 @@ PLATFORMS
63
64
  ruby
64
65
 
65
66
  DEPENDENCIES
67
+ fakefs (~> 0.4)
66
68
  geminabox-client
67
69
  pact!
68
70
  pry
data/README.md CHANGED
@@ -117,6 +117,8 @@ end
117
117
 
118
118
  #### Configure your service provider rack app
119
119
 
120
+ Create a `pact_helper.rb` in your service provider project. The file must be called pact_helper.rb so the verification tasks can find it, however there is some flexibility in where it can be stored. The recommended place is `specs/service_providers/pact_helper.rb`.
121
+
120
122
  ```ruby
121
123
  Pact.service_provider "My Provider" do
122
124
  app { MyApp.new }
@@ -150,7 +152,8 @@ Note that these states have been defined only for the 'My Consumer' consumer by
150
152
 
151
153
  ```ruby
152
154
  # The consumer name here must match the name of the consumer configured in your consumer project
153
- # for it to use these states.
155
+ # for it to correctly find these provider states.
156
+ # Make sure the provider states are included in or required by your pact_helper.rb file.
154
157
 
155
158
  Pact.provider_states_for 'My Consumer' do
156
159
  provider_state "a thing exists" do
@@ -172,7 +175,7 @@ end
172
175
 
173
176
  ```
174
177
 
175
- If a state should be used for all consumers, the top level Pact.with_consumer can be skipped, and a global Pact.provider_state can be defined on its own.
178
+ If a state should be used for all consumers, the top level Pact.with_consumer can be skipped, and a global Pact.provider_state can be defined on its own.
176
179
 
177
180
  #### Create a rake task to verify that the service provider honours the pact
178
181
 
@@ -4,12 +4,21 @@ require 'rspec/core'
4
4
  require 'rspec/core/formatters/documentation_formatter'
5
5
  require_relative 'rspec'
6
6
 
7
+
7
8
  module Pact
8
9
  module Provider
9
10
  class PactSpecRunner
10
11
 
11
12
  extend Pact::Provider::RSpec::ClassMethods
12
13
 
14
+ PACT_HELPER_FILE_PATTERNS = [
15
+ "spec/**/*service*consumer*/pact_helper.rb",
16
+ "spec/**/*consumer*/pact_helper.rb",
17
+ "spec/**/pact_helper.rb",
18
+ "**/pact_helper.rb"]
19
+
20
+ NO_PACT_HELPER_FOUND_MSG = "Please create a pact_helper.rb file that can be found using one of the following patterns: #{PACT_HELPER_FILE_PATTERNS.join(", ")}"
21
+
13
22
  def self.run(spec_definitions, options = {})
14
23
  initialize_specs spec_definitions
15
24
  configure_rspec options
@@ -18,9 +27,24 @@ module Pact
18
27
 
19
28
  private
20
29
 
30
+ def self.require_pact_helper spec_definition
31
+ if spec_definition[:support_file]
32
+ require spec_definition[:support_file]
33
+ else
34
+ require pact_helper_file
35
+ end
36
+ end
37
+
38
+ def self.pact_helper_file
39
+ pact_helper_search_results = []
40
+ PACT_HELPER_FILE_PATTERNS.find { | pattern | (pact_helper_search_results.concat(Dir.glob(pattern))).any? }
41
+ raise NO_PACT_HELPER_FOUND_MSG if pact_helper_search_results.empty?
42
+ "#{Dir.pwd}/#{pact_helper_search_results[0]}"
43
+ end
44
+
21
45
  def self.initialize_specs spec_definitions
22
46
  spec_definitions.each do | spec_definition |
23
- require spec_definition[:support_file] if spec_definition[:support_file]
47
+ require_pact_helper spec_definition
24
48
  options = {consumer: spec_definition[:consumer], save_pactfile_to_tmp: true}
25
49
  honour_pactfile spec_definition[:uri], options
26
50
  end
@@ -80,7 +80,12 @@ module Pact
80
80
  def get_provider_state provider_state_name, consumer
81
81
  unless provider_state = ProviderState.get(provider_state_name, :for => consumer)
82
82
  extra = consumer ? " for consumer \"#{consumer}\"" : ""
83
- raise "Could not find a provider state defined for \"#{provider_state_name}\"#{extra}. Have you required the provider state file in your spec?"
83
+ error_msg = <<-eos
84
+ Could not find a provider state named \"#{provider_state_name}\"#{extra}.
85
+ Have you required the provider states file for this consumer in your pact_helper.rb?
86
+ Check the name in the Pact.provider_states_for definition is exactly \"#{consumer}\"
87
+ eos
88
+ raise error_msg
84
89
  end
85
90
  provider_state
86
91
  end
@@ -6,10 +6,8 @@ require_relative 'pact_task_helper'
6
6
  To create a rake pact:verify:<something> task
7
7
 
8
8
  Pact::VerificationTask.new(:head) do | pact |
9
- pact.uri 'http://master.cd.vpc.realestate.com.au/browse/BIQ-MAS/latestSuccessful/artifact/JOB2/Pacts/mas-contract_transaction_service.json',
10
- support_file: './spec/consumers/pact_helper'
11
- pact.uri 'http://master.cd.vpc.realestate.com.au/browse/BIQ-IMAGINARY-CONSUMER/latestSuccessful/artifact/JOB2/Pacts/imaginary_consumer-contract_transaction_service.json',
12
- support_file: './spec/consumers/pact_helper'
9
+ pact.uri 'http://master.cd.vpc.realestate.com.au/browse/BIQ-MAS/latestSuccessful/artifact/JOB2/Pacts/mas-contract_transaction_service.json'
10
+ pact.uri 'http://master.cd.vpc.realestate.com.au/browse/BIQ-IMAGINARY-CONSUMER/latestSuccessful/artifact/JOB2/Pacts/imaginary_consumer-contract_transaction_service.json'
13
11
  end
14
12
 
15
13
  The pact.uri may be a local file system path or a remote URL.
@@ -32,21 +30,27 @@ module Pact
32
30
  include PactTaskHelper
33
31
  def initialize(name)
34
32
  @pact_spec_config = []
35
-
33
+ @name = name
36
34
  yield self
37
-
38
- namespace :pact do
39
-
40
- desc "Verify provider against the consumer pacts for #{name}"
41
- task "verify:#{name}" do
42
- exit_status = Provider::PactSpecRunner.run(pact_spec_config)
43
- fail failure_message if exit_status != 0
44
- end
45
- end
35
+ define_rake_task
46
36
  end
47
37
 
48
- def uri(uri, options)
38
+ def uri(uri, options = {})
49
39
  @pact_spec_config << {uri: uri, support_file: options[:support_file]}
50
40
  end
41
+
42
+ private
43
+
44
+ attr_reader :name
45
+
46
+ def define_rake_task
47
+ namespace :pact do
48
+ desc "Verify provider against the consumer pacts for #{name}"
49
+ task "verify:#{name}" do
50
+ exit_status = Provider::PactSpecRunner.run(pact_spec_config)
51
+ fail failure_message if exit_status != 0
52
+ end
53
+ end
54
+ end
51
55
  end
52
56
  end
@@ -1,3 +1,3 @@
1
1
  module Pact
2
- VERSION = "1.0.2"
2
+ VERSION = "1.0.3"
3
3
  end
@@ -32,4 +32,5 @@ Gem::Specification.new do |gem|
32
32
  gem.add_development_dependency 'rake', '~> 10.0.3'
33
33
  gem.add_development_dependency 'webmock', '~> 1.9.3'
34
34
  gem.add_development_dependency 'pry'
35
+ gem.add_development_dependency 'fakefs', '~> 0.4'
35
36
  end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+ require 'pact/provider/pact_spec_runner'
3
+
4
+ module Pact::Provider
5
+ describe PactSpecRunner do
6
+ describe "pact_helper_file", :fakefs => true do
7
+
8
+ subject { PactSpecRunner.send(:pact_helper_file) }
9
+
10
+ def make_pactfile dir
11
+ FileUtils.mkdir_p ".#{dir}"
12
+ FileUtils.touch ".#{dir}/pact_helper.rb"
13
+ end
14
+
15
+ PACT_HELPER_FILE_DIRS = [
16
+ '/spec/blah/service-consumers',
17
+ '/spec/consumers',
18
+ '/spec/blah/service_consumers',
19
+ '/spec/serviceconsumers',
20
+ '/spec/consumer',
21
+ '/spec',
22
+ '/blah',
23
+ '/blah/consumer',
24
+ ''
25
+ ]
26
+
27
+ PACT_HELPER_FILE_DIRS.each do | dir |
28
+ context "the pact_helper is stored in #{dir}" do
29
+ it "finds the pact_helper" do
30
+ make_pactfile dir
31
+ expect(subject).to eq "#{Dir.pwd}#{dir}/pact_helper.rb"
32
+ end
33
+ end
34
+ end
35
+
36
+ context "when more than one pact_helper exists" do
37
+ it "returns the one that matches the most explict search pattern" do
38
+ make_pactfile '/spec/consumer'
39
+ FileUtils.touch 'pact_helper.rb'
40
+ expect(subject).to eq "#{Dir.pwd}/spec/consumer/pact_helper.rb"
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+ require 'pact/provider/test_methods'
3
+
4
+ module Pact::Provider
5
+ describe TestMethods do
6
+
7
+ class TestHelper
8
+ include TestMethods
9
+ end
10
+
11
+ subject { TestHelper.new }
12
+
13
+ describe "get_provider_state" do
14
+ it "raises a descriptive error if the provider state is not found" do
15
+ ProviderState.stub(:get).and_return(nil)
16
+ expect{ subject.send(:get_provider_state, 'some state', 'consumer') }.to raise_error /Could not find.*some state.*consumer.*/
17
+ end
18
+ end
19
+ end
20
+ end
@@ -4,31 +4,51 @@ require 'pact/verification_task'
4
4
  module Pact
5
5
  describe VerificationTask do
6
6
  before :all do
7
- @support_file = 'some_file.rb'
7
+ @support_file = '/custom/path/support_file.rb'
8
8
  @pact_uri = 'http://example.org/pact.json'
9
9
  @task_name = 'pact:verify:pact_rake_spec'
10
+ @task_name_with_explict_support_file = 'pact:verify:pact_rake_spec_with_explict_support_file'
10
11
  @consumer = 'some-consumer'
11
12
 
13
+ VerificationTask.new(:pact_rake_spec_with_explict_support_file) do | pact |
14
+ pact.uri @pact_uri, support_file: @support_file
15
+ end
16
+
12
17
  VerificationTask.new(:pact_rake_spec) do | pact |
13
- pact.uri @pact_uri, support_file: @support_file, consumer: @consumer
18
+ pact.uri @pact_uri
14
19
  end
15
20
  end
16
21
 
17
22
  describe '.initialize' do
18
-
19
- it 'creates the tasks' do
20
- Rake::Task.tasks.should include_task @task_name
23
+ context 'with an explict support_file' do
24
+ it 'creates the tasks' do
25
+ Rake::Task.tasks.should include_task @task_name
26
+ end
27
+ end
28
+ context 'with no explict support_file' do
29
+ it 'creates the tasks' do
30
+ Rake::Task.tasks.should include_task @task_name_with_explict_support_file
31
+ end
21
32
  end
22
-
23
33
  end
24
34
 
25
35
  describe 'execute' do
26
36
 
27
- let(:consumer_contract) { [ uri: @pact_uri, support_file: @support_file] }
37
+ let(:consumer_contract) { [ uri: @pact_uri, support_file: nil ] }
38
+
39
+ context "with no explict support file " do
40
+ it 'verifies the pacts using PactSpecRunner' do
41
+ Provider::PactSpecRunner.should_receive(:run).with(consumer_contract).and_return(0)
42
+ Rake::Task[@task_name].execute
43
+ end
44
+ end
28
45
 
29
- it 'verifies the pacts using PactSpecRunner' do
30
- Provider::PactSpecRunner.should_receive(:run).with(consumer_contract).and_return(0)
31
- Rake::Task[@task_name].execute
46
+ context "with an explict support_file" do
47
+ let(:consumer_contract) { [ uri: @pact_uri, support_file: @support_file] }
48
+ it 'verifies the pacts using PactSpecRunner' do
49
+ Provider::PactSpecRunner.should_receive(:run).with(consumer_contract).and_return(0)
50
+ Rake::Task[@task_name_with_explict_support_file].execute
51
+ end
32
52
  end
33
53
 
34
54
  context 'when all specs pass' do
@@ -1,6 +1,11 @@
1
+ require 'fakefs/spec_helpers'
1
2
  require 'rspec'
2
3
  require 'pact'
3
4
  require 'webmock/rspec'
4
5
  require_relative 'support/factories'
5
6
 
6
7
  WebMock.disable_net_connect!(allow_localhost: true)
8
+
9
+ RSpec.configure do | config |
10
+ config.include(FakeFS::SpecHelpers, :fakefs => true)
11
+ end
@@ -1,4 +1,5 @@
1
1
  require 'json'
2
+ # pact_helper for rake pact:tests
2
3
 
3
4
  module Pact
4
5
  module Test
@@ -8,10 +8,10 @@ namespace :pact do
8
8
  puts "Running task pact:tests"
9
9
  # Run these specs silently, otherwise expected failures will be written to stdout and look like unexpected failures.
10
10
 
11
- result = Pact::Provider::PactSpecRunner.run([{ uri: './spec/support/test_app_pass.json', support_file: './spec/support/pact_rake_support.rb', consumer: 'some-test-consumer' }], silent: silent)
11
+ result = Pact::Provider::PactSpecRunner.run([{ uri: './spec/support/test_app_pass.json' }], silent: silent)
12
12
  fail 'Expected pact to pass' unless (result == 0)
13
13
 
14
- result = Pact::Provider::PactSpecRunner.run([{ uri: './spec/support/test_app_fail.json', support_file: './spec/support/pact_rake_support.rb' }], silent: silent)
14
+ result = Pact::Provider::PactSpecRunner.run([{ uri: './spec/support/test_app_fail.json', support_file: './spec/support/pact_helper.rb' }], silent: silent)
15
15
  fail 'Expected pact to fail' if (result == 0)
16
16
 
17
17
  puts "Task pact:tests completed succesfully."
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.2
4
+ version: 1.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -223,6 +223,22 @@ dependencies:
223
223
  - - ! '>='
224
224
  - !ruby/object:Gem::Version
225
225
  version: '0'
226
+ - !ruby/object:Gem::Dependency
227
+ name: fakefs
228
+ requirement: !ruby/object:Gem::Requirement
229
+ none: false
230
+ requirements:
231
+ - - ~>
232
+ - !ruby/object:Gem::Version
233
+ version: '0.4'
234
+ type: :development
235
+ prerelease: false
236
+ version_requirements: !ruby/object:Gem::Requirement
237
+ none: false
238
+ requirements:
239
+ - - ~>
240
+ - !ruby/object:Gem::Version
241
+ version: '0.4'
226
242
  description: Define a pact between service consumers and providers
227
243
  email:
228
244
  - james.fraser@alumni.swinburne.edu
@@ -237,6 +253,7 @@ extra_rdoc_files: []
237
253
  files:
238
254
  - .gitignore
239
255
  - .rspec
256
+ - CHANGELOG.md
240
257
  - Gemfile
241
258
  - Gemfile.lock
242
259
  - LICENSE.txt
@@ -308,8 +325,10 @@ files:
308
325
  - spec/lib/pact/consumer_contract/interaction_spec.rb
309
326
  - spec/lib/pact/matchers/matchers_spec.rb
310
327
  - spec/lib/pact/provider/dsl_spec.rb
328
+ - spec/lib/pact/provider/pact_spec_runner_spec.rb
311
329
  - spec/lib/pact/provider/provider_state_spec.rb
312
330
  - spec/lib/pact/provider/rspec_spec.rb
331
+ - spec/lib/pact/provider/test_methods_spec.rb
313
332
  - spec/lib/pact/reification_spec.rb
314
333
  - spec/lib/pact/request_spec.rb
315
334
  - spec/lib/pact/term_spec.rb
@@ -319,7 +338,7 @@ files:
319
338
  - spec/support/a_consumer-a_provider.json
320
339
  - spec/support/consumer_contract_template.json
321
340
  - spec/support/factories.rb
322
- - spec/support/pact_rake_support.rb
341
+ - spec/support/pact_helper.rb
323
342
  - spec/support/test_app_fail.json
324
343
  - spec/support/test_app_pass.json
325
344
  - tasks/pact-test.rake
@@ -366,8 +385,10 @@ test_files:
366
385
  - spec/lib/pact/consumer_contract/interaction_spec.rb
367
386
  - spec/lib/pact/matchers/matchers_spec.rb
368
387
  - spec/lib/pact/provider/dsl_spec.rb
388
+ - spec/lib/pact/provider/pact_spec_runner_spec.rb
369
389
  - spec/lib/pact/provider/provider_state_spec.rb
370
390
  - spec/lib/pact/provider/rspec_spec.rb
391
+ - spec/lib/pact/provider/test_methods_spec.rb
371
392
  - spec/lib/pact/reification_spec.rb
372
393
  - spec/lib/pact/request_spec.rb
373
394
  - spec/lib/pact/term_spec.rb
@@ -377,6 +398,6 @@ test_files:
377
398
  - spec/support/a_consumer-a_provider.json
378
399
  - spec/support/consumer_contract_template.json
379
400
  - spec/support/factories.rb
380
- - spec/support/pact_rake_support.rb
401
+ - spec/support/pact_helper.rb
381
402
  - spec/support/test_app_fail.json
382
403
  - spec/support/test_app_pass.json