pact 0.1.37 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. data/Gemfile.lock +6 -19
  2. data/example/zoo-app/Gemfile +1 -2
  3. data/example/zoo-app/Gemfile.lock +16 -13
  4. data/example/zoo-app/spec/pacts/zoo_app-animal_service.json +6 -6
  5. data/lib/pact/consumer/app_manager.rb +8 -28
  6. data/lib/pact/consumer/consumer_contract_builder.rb +65 -36
  7. data/lib/pact/consumer/dsl.rb +20 -10
  8. data/lib/pact/consumer/interaction_builder.rb +42 -0
  9. data/lib/pact/consumer/interactions_filter.rb +41 -0
  10. data/lib/pact/consumer/mock_service.rb +26 -19
  11. data/lib/pact/consumer/rspec.rb +2 -3
  12. data/lib/pact/consumer/server.rb +90 -0
  13. data/lib/pact/consumer.rb +6 -3
  14. data/lib/pact/consumer_contract/consumer_contract.rb +103 -0
  15. data/lib/pact/consumer_contract/interaction.rb +70 -0
  16. data/lib/pact/consumer_contract/service_consumer.rb +20 -0
  17. data/lib/pact/consumer_contract/service_provider.rb +20 -0
  18. data/lib/pact/consumer_contract.rb +1 -112
  19. data/lib/pact/{producer → provider}/dsl.rb +15 -4
  20. data/lib/pact/{producer → provider}/matchers.rb +0 -0
  21. data/lib/pact/{producer → provider}/pact_spec_runner.rb +2 -2
  22. data/lib/pact/{producer/producer_state.rb → provider/provider_state.rb} +13 -22
  23. data/lib/pact/provider/rspec.rb +128 -1
  24. data/lib/pact/{producer → provider}/test_methods.rb +12 -12
  25. data/lib/pact/{producer.rb → provider.rb} +0 -0
  26. data/lib/pact/verification_task.rb +4 -4
  27. data/lib/pact/version.rb +1 -1
  28. data/lib/pact.rb +1 -1
  29. data/pact.gemspec +1 -2
  30. data/scratchpad.txt +1 -1
  31. data/spec/features/consumption_spec.rb +15 -23
  32. data/spec/features/production_spec.rb +5 -5
  33. data/spec/features/{producer_states → provider_states}/zebras.rb +3 -3
  34. data/spec/integration/pact/consumer_configuration_spec.rb +3 -66
  35. data/spec/integration/pact/provider_configuration_spec.rb +1 -1
  36. data/spec/lib/pact/consumer/consumer_contract_builder_spec.rb +59 -15
  37. data/spec/lib/pact/consumer/dsl_spec.rb +4 -5
  38. data/spec/lib/pact/consumer/interaction_builder_spec.rb +91 -0
  39. data/spec/lib/pact/consumer/interactions_spec.rb +64 -0
  40. data/spec/lib/pact/consumer/mock_service_spec.rb +2 -6
  41. data/spec/lib/pact/consumer/service_consumer_spec.rb +1 -1
  42. data/spec/lib/pact/{consumer_contract_spec.rb → consumer_contract/consumer_contract_spec.rb} +72 -28
  43. data/spec/lib/pact/{consumer → consumer_contract}/interaction_spec.rb +49 -64
  44. data/spec/lib/pact/{producer/configuration_dsl_spec.rb → provider/dsl_spec.rb} +29 -28
  45. data/spec/lib/pact/{producer/producer_state_spec.rb → provider/provider_state_spec.rb} +17 -17
  46. data/spec/lib/pact/{producer → provider}/rspec_spec.rb +1 -1
  47. data/spec/lib/pact/verification_task_spec.rb +3 -3
  48. data/spec/spec_helper.rb +1 -0
  49. data/spec/support/a_consumer-a_producer.json +1 -1
  50. data/spec/support/a_consumer-a_provider.json +34 -0
  51. data/spec/support/consumer_contract_template.json +26 -0
  52. data/spec/support/factories.rb +78 -0
  53. data/spec/support/pact_rake_support.rb +1 -1
  54. data/spec/support/test_app_fail.json +1 -1
  55. data/spec/support/test_app_pass.json +1 -1
  56. data/tasks/pact-test.rake +3 -3
  57. metadata +38 -45
  58. data/lib/pact/consumer/configuration_dsl.rb +0 -73
  59. data/lib/pact/consumer/interaction.rb +0 -74
  60. data/lib/pact/consumer/run_condor.rb +0 -4
  61. data/lib/pact/consumer/run_mock_contract_service.rb +0 -13
  62. data/lib/pact/consumer/service_consumer.rb +0 -22
  63. data/lib/pact/consumer/service_producer.rb +0 -23
  64. data/lib/pact/producer/configuration_dsl.rb +0 -62
  65. data/lib/pact/producer/rspec.rb +0 -129
@@ -1,40 +1,33 @@
1
1
  module Pact
2
- module Producer
2
+ module Provider
3
3
 
4
4
  module DSL
5
- def producer_state name, &block
6
- ProducerState.producer_state(name, &block).register
5
+ def provider_state name, &block
6
+ ProviderState.provider_state(name, &block).register
7
7
  end
8
8
 
9
- def with_consumer name, &block
10
- ProducerState.current_namespaces << name
9
+ def provider_states_for name, &block
10
+ ProviderState.current_namespaces << name
11
11
  instance_eval(&block)
12
- ProducerState.current_namespaces.pop
12
+ ProviderState.current_namespaces.pop
13
13
  end
14
-
15
- alias_method :provider_states_for, :with_consumer
16
- alias_method :provider_state, :producer_state
17
14
  end
18
15
 
19
- class ProducerState
16
+ class ProviderState
20
17
 
21
18
  attr_accessor :name
22
19
  attr_accessor :namespace
23
20
 
24
- def self.producer_state name, &block
25
- ProducerState.new(name, current_namespaces.join('.'), &block)
26
- end
27
-
28
21
  def self.provider_state name, &block
29
- producer_state name, &block
22
+ ProviderState.new(name, current_namespaces.join('.'), &block)
30
23
  end
31
24
 
32
- def self.register name, producer_state
33
- producer_states[name] = producer_state
25
+ def self.register name, provider_state
26
+ provider_states[name] = provider_state
34
27
  end
35
28
 
36
- def self.producer_states
37
- @@producer_states ||= {}
29
+ def self.provider_states
30
+ @@provider_states ||= {}
38
31
  end
39
32
 
40
33
  def self.current_namespaces
@@ -43,7 +36,7 @@ module Pact
43
36
 
44
37
  def self.get name, options = {}
45
38
  fullname = options[:for] ? "#{options[:for]}.#{name}" : name
46
- (producer_states[fullname] || producer_states[fullname.to_sym]) || producer_states[name]
39
+ (provider_states[fullname] || provider_states[fullname.to_sym]) || provider_states[name]
47
40
  end
48
41
 
49
42
  def register
@@ -84,5 +77,3 @@ module Pact
84
77
  end
85
78
  end
86
79
  end
87
-
88
- Pact.send(:extend, Pact::Producer::DSL)
@@ -1 +1,128 @@
1
- require 'pact/producer/rspec'
1
+ require 'open-uri'
2
+ require 'pact/consumer_contract'
3
+ require 'pact/json_warning'
4
+ require_relative 'matchers'
5
+ require_relative 'test_methods'
6
+ require 'pact/provider/dsl'
7
+
8
+ module Pact
9
+ module Provider
10
+ module RSpec
11
+
12
+ module InstanceMethods
13
+ def app
14
+ Pact.configuration.provider.app
15
+ end
16
+ end
17
+
18
+ module ClassMethods
19
+
20
+ include Pact::JsonWarning
21
+
22
+ def honour_pactfile pactfile_uri, options = {}
23
+ describe "Pact in #{pactfile_uri}" do
24
+ consumer_contract = Pact::ConsumerContract.from_json(read_pact_from(pactfile_uri, options))
25
+ honour_consumer_contract consumer_contract, options
26
+ end
27
+ end
28
+
29
+ def honour_consumer_contract consumer_contract, options = {}
30
+ check_for_active_support_json
31
+ describe_consumer_contract consumer_contract, options.merge({:consumer => consumer_contract.consumer.name})
32
+ end
33
+
34
+ private
35
+
36
+ def describe_consumer_contract consumer_contract, options
37
+ consumer_contract.interactions.each do |interaction|
38
+ describe_interaction_with_provider_state interaction, options
39
+ end
40
+ end
41
+
42
+ def describe_interaction_with_provider_state interaction, options
43
+ if interaction.provider_state
44
+ describe "Given #{interaction.provider_state}" do
45
+ describe_interaction interaction, options
46
+ end
47
+ else
48
+ describe_interaction interaction, options
49
+ end
50
+ end
51
+
52
+ def describe_interaction interaction, options
53
+
54
+ describe description_for(interaction) do
55
+
56
+ before do
57
+ set_up_provider_state interaction.provider_state, options[:consumer]
58
+ replay_interaction interaction
59
+ end
60
+
61
+ after do
62
+ tear_down_provider_state interaction.provider_state, options[:consumer]
63
+ end
64
+
65
+ describe_response interaction.response
66
+ end
67
+
68
+ end
69
+
70
+ def describe_response response
71
+ describe "returns a response which" do
72
+ if response['status']
73
+ it "has status code #{response['status']}" do
74
+ expect(last_response.status).to eql response['status']
75
+ end
76
+ end
77
+
78
+ if response['headers']
79
+ describe "includes headers" do
80
+ response['headers'].each do |name, value|
81
+ it "\"#{name}\" with value \"#{value}\"" do
82
+ expect(last_response.headers[name]).to match_term value
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ if response['body']
89
+ it "has a matching body" do
90
+ logger.debug "Response body is #{last_response.body}"
91
+ expect(parse_entity_from_response(last_response)).to match_term response['body']
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+ def description_for interaction
98
+ "#{interaction.description} to #{interaction.request.path}"
99
+ end
100
+
101
+ def read_pact_from uri, options = {}
102
+ pact = open(uri) { | file | file.read }
103
+ if options[:save_pactfile_to_tmp]
104
+ save_pactfile_to_tmp pact, File.basename(uri)
105
+ end
106
+ pact
107
+ rescue StandardError => e
108
+ $stderr.puts "Error reading file from #{uri}"
109
+ $stderr.puts "#{e.to_s} #{e.backtrace.join("\n")}"
110
+ raise e
111
+ end
112
+
113
+ def save_pactfile_to_tmp pact, name
114
+ FileUtils.mkdir_p Pact.configuration.tmp_dir
115
+ File.open(Pact.configuration.tmp_dir + "/#{name}", "w") { |file| file << pact}
116
+ end
117
+
118
+ end
119
+ end
120
+ end
121
+ end
122
+
123
+ RSpec.configure do |config|
124
+ config.extend Pact::Provider::RSpec::ClassMethods
125
+ config.include Pact::Provider::RSpec::InstanceMethods
126
+ config.include Pact::Provider::TestMethods
127
+ config.include Pact::Provider::TestMethods
128
+ end
@@ -1,10 +1,10 @@
1
1
  require 'pact/logging'
2
2
  require 'rack/test'
3
3
  require 'pact/reification'
4
- require 'pact/producer/producer_state'
4
+ require 'pact/provider/provider_state'
5
5
 
6
6
  module Pact
7
- module Producer
7
+ module Provider
8
8
  module TestMethods
9
9
 
10
10
  include Pact::Logging
@@ -19,15 +19,15 @@ module Pact
19
19
  end
20
20
  end
21
21
 
22
- def set_up_producer_state producer_state_name, consumer
23
- if producer_state_name
24
- get_producer_state(producer_state_name, consumer).set_up
22
+ def set_up_provider_state provider_state_name, consumer
23
+ if provider_state_name
24
+ get_provider_state(provider_state_name, consumer).set_up
25
25
  end
26
26
  end
27
27
 
28
- def tear_down_producer_state producer_state_name, consumer
29
- if producer_state_name
30
- get_producer_state(producer_state_name, consumer).tear_down
28
+ def tear_down_provider_state provider_state_name, consumer
29
+ if provider_state_name
30
+ get_provider_state(provider_state_name, consumer).tear_down
31
31
  end
32
32
  end
33
33
 
@@ -77,12 +77,12 @@ module Pact
77
77
  end
78
78
  end
79
79
 
80
- def get_producer_state producer_state_name, consumer
81
- unless producer_state = ProducerState.get(producer_state_name, :for => consumer)
80
+ def get_provider_state provider_state_name, consumer
81
+ unless provider_state = ProviderState.get(provider_state_name, :for => consumer)
82
82
  extra = consumer ? " for consumer \"#{consumer}\"" : ""
83
- raise "Could not find a producer state defined for \"#{producer_state_name}\"#{extra}. Have you required the producer state file in your spec?"
83
+ raise "Could not find a provider state defined for \"#{provider_state_name}\"#{extra}. Have you required the provider state file in your spec?"
84
84
  end
85
- producer_state
85
+ provider_state
86
86
  end
87
87
  end
88
88
  end
File without changes
@@ -1,5 +1,5 @@
1
1
  require 'rake/tasklib'
2
- require 'pact/producer/pact_spec_runner'
2
+ require 'pact/provider/pact_spec_runner'
3
3
 
4
4
  =begin
5
5
  To create a rake pact:verify:<something> task
@@ -33,15 +33,15 @@ module Pact
33
33
  yield self
34
34
 
35
35
  namespace :pact do
36
- desc "Verify producer against the consumer pacts for #{name}"
36
+ desc "Verify provider against the consumer pacts for #{name}"
37
37
  task "verify:#{name}" do
38
- exit_status = Producer::PactSpecRunner.run(pact_spec_config)
38
+ exit_status = Provider::PactSpecRunner.run(pact_spec_config)
39
39
  fail failure_message if exit_status != 0
40
40
  end
41
41
 
42
42
  def failure_message
43
43
  "\n* * * * * * * * * * * * * * * * * * *\n" +
44
- "Producer did not honour pact file.\nSee\n * #{Pact.configuration.log_path}\n * #{Pact.configuration.tmp_dir}\nfor logs and pact files." +
44
+ "Provider did not honour pact file.\nSee\n * #{Pact.configuration.log_path}\n * #{Pact.configuration.tmp_dir}\nfor logs and pact files." +
45
45
  "\n* * * * * * * * * * * * * * * * * * *\n\n"
46
46
  end
47
47
  end
data/lib/pact/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Pact
2
- VERSION = "0.1.37"
2
+ VERSION = "1.0.0"
3
3
  end
data/lib/pact.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require_relative 'pact/version'
2
2
  require_relative 'pact/configuration'
3
3
  require_relative 'pact/consumer'
4
- require_relative 'pact/producer'
4
+ require_relative 'pact/provider'
5
5
  require_relative 'pact/consumer_contract'
data/pact.gemspec CHANGED
@@ -19,12 +19,11 @@ Gem::Specification.new do |gem|
19
19
  gem.license = 'MIT'
20
20
 
21
21
  gem.add_runtime_dependency 'randexp', '~> 0.1.7'
22
- gem.add_runtime_dependency 'hashie', '~> 2.0.5'
22
+ gem.add_runtime_dependency 'hashie', '~> 2.0'
23
23
  gem.add_runtime_dependency 'rspec', '~> 2.12'
24
24
  gem.add_runtime_dependency 'find_a_port', '~> 1.0.1'
25
25
  gem.add_runtime_dependency 'rack-test', '~> 0.6.2'
26
26
  gem.add_runtime_dependency 'awesome_print', '~> 1.1.0'
27
- gem.add_runtime_dependency 'capybara', '~> 2.1.0'
28
27
  gem.add_runtime_dependency 'thor'
29
28
  gem.add_runtime_dependency 'thin'
30
29
  gem.add_runtime_dependency 'json' #Not locking down a version because buncher gem requires 1.6, while other projects use 1.7.
data/scratchpad.txt CHANGED
@@ -5,7 +5,7 @@ Could use:
5
5
  eg
6
6
  ex
7
7
 
8
- my_producer.
8
+ my_provider.
9
9
  given("a thing exists").
10
10
  upon_receiving("a request for a thing").with({:method => 'get', :path => '/thing'})
11
11
  will_respond_with({:body => {
@@ -99,20 +99,16 @@ describe "A service consumer side of a pact", :pact => true do
99
99
  expect{ bob_service.verify('goes a little something like this') }.to raise_error /do not match/
100
100
  end
101
101
 
102
- context "with a producer state" do
102
+ context "with a provider state" do
103
103
  before do
104
104
  Pact.clear_configuration
105
105
 
106
- Pact.configure do | config |
107
- config.service_consumer do
108
- name "Consumer"
109
- end
110
- end
111
-
112
- Pact.with_service_provider "Zebra Service" do
113
- mock_service :zebra_service do
114
- verify false
115
- port 1235
106
+ Pact.service_consumer "Consumer" do
107
+ has_pact_with "Zebra Service" do
108
+ mock_service :zebra_service do
109
+ verify false
110
+ port 1235
111
+ end
116
112
  end
117
113
  end
118
114
  end
@@ -132,25 +128,21 @@ describe "A service consumer side of a pact", :pact => true do
132
128
  })
133
129
 
134
130
  interactions = Pact::ConsumerContract.from_json(File.read(zebra_service.consumer_contract.pactfile_path)).interactions
135
- interactions.first.producer_state.should eq("the_zebras_are_here")
131
+ interactions.first.provider_state.should eq("the_zebras_are_here")
136
132
  sleep 1
137
133
  end
138
134
  end
139
135
 
140
- context "with a async interaction with producer" do
136
+ context "with a async interaction with provider" do
141
137
  before do
142
138
  Pact.clear_configuration
143
139
 
144
- Pact.configure do | config |
145
- config.service_consumer do
146
- name "Consumer"
147
- end
148
- end
149
-
150
- Pact.with_service_provider "Zebra Service" do
151
- mock_service :zebra_service do
152
- verify true
153
- port 1239
140
+ Pact.service_consumer "Consumer" do | config |
141
+ has_pact_with "Zebra Service" do
142
+ mock_service :zebra_service do
143
+ verify true
144
+ port 1239
145
+ end
154
146
  end
155
147
  end
156
148
  end
@@ -1,9 +1,9 @@
1
1
  require 'pact/provider/rspec'
2
2
  require 'pact/consumer_contract'
3
- require 'features/producer_states/zebras'
3
+ require 'features/provider_states/zebras'
4
4
 
5
5
 
6
- module Pact::Producer
6
+ module Pact::Provider
7
7
 
8
8
  describe "A service production side of a pact" do
9
9
 
@@ -83,7 +83,7 @@ module Pact::Producer
83
83
 
84
84
  end
85
85
 
86
- describe "with a producer_state" do
86
+ describe "with a provider_state" do
87
87
 
88
88
  context "that is a symbol" do
89
89
  consumer_contract = Pact::ConsumerContract.from_json <<-EOS
@@ -100,7 +100,7 @@ module Pact::Producer
100
100
  "body": {"names": ["Jason", "Sarah"]},
101
101
  "status": 200
102
102
  },
103
- "producer_state" : "the_zebras_are_here"
103
+ "provider_state" : "the_zebras_are_here"
104
104
  }
105
105
  ]
106
106
  }
@@ -131,7 +131,7 @@ module Pact::Producer
131
131
  "body": {"names": ["Mark", "Gertrude"]},
132
132
  "status": 200
133
133
  },
134
- "producer_state" : "some other zebras are here"
134
+ "provider_state" : "some other zebras are here"
135
135
  }
136
136
  ]
137
137
  }
@@ -1,9 +1,9 @@
1
1
  require 'json'
2
2
  require 'fileutils'
3
3
 
4
- Pact.with_consumer 'the-wild-beast-store' do
4
+ Pact.provider_states_for 'the-wild-beast-store' do
5
5
 
6
- producer_state :the_zebras_are_here do
6
+ provider_state :the_zebras_are_here do
7
7
  set_up do
8
8
  FileUtils.mkdir_p 'tmp'
9
9
  some_data = [{'name' => 'Jason'},{'name' => 'Sarah'}]
@@ -16,7 +16,7 @@ Pact.with_consumer 'the-wild-beast-store' do
16
16
  end
17
17
  end
18
18
 
19
- Pact.producer_state "some other zebras are here" do
19
+ Pact.provider_state "some other zebras are here" do
20
20
  set_up do
21
21
  some_data = [{'name' => 'Mark'},{'name' => 'Gertrude'}]
22
22
  File.open("tmp/a_mock_database.json", "w") { |file| file << some_data.to_json }
@@ -1,8 +1,6 @@
1
1
  require 'spec_helper'
2
2
  require 'pact/configuration'
3
3
  require 'pact/consumer/dsl'
4
- require 'pact/consumer/configuration_dsl'
5
- require 'pact/producer/configuration_dsl'
6
4
 
7
5
  describe "consumer side" do
8
6
  describe "configure" do
@@ -47,7 +45,7 @@ describe "consumer side" do
47
45
  subject { TestHelper.new.my_service.consumer_contract.consumer }
48
46
 
49
47
  it "should be configured" do
50
- expect(subject).to be_instance_of Pact::Consumer::ServiceConsumer
48
+ expect(subject).to be_instance_of Pact::ServiceConsumer
51
49
  end
52
50
 
53
51
  it "should have the right name" do
@@ -59,11 +57,11 @@ describe "consumer side" do
59
57
  end
60
58
  end
61
59
 
62
- describe "producers" do
60
+ describe "providers" do
63
61
 
64
62
  subject { TestHelper.new.my_service }
65
63
 
66
- it "should have defined methods in MockServices for the producers" do
64
+ it "should have defined methods in MockServices for the providers" do
67
65
  subject.should be_instance_of Pact::Consumer::ConsumerContractBuilder
68
66
  end
69
67
 
@@ -80,65 +78,4 @@ describe "consumer side" do
80
78
  end
81
79
  end
82
80
  end
83
-
84
-
85
- describe "deprecated configure" do
86
-
87
- before do
88
- Pact.clear_configuration
89
- Pact::Consumer::AppManager.instance.clear_all
90
-
91
- Pact.configure do | config |
92
- config.service_consumer do
93
- name "My Consumer"
94
- end
95
- end
96
-
97
- Pact.with_service_provider "My Service" do
98
- mock_service :my_service do
99
- port 1234
100
- standalone true
101
- end
102
- end
103
-
104
- Pact.with_service_provider "My Other Service" do
105
- mock_service :my_other_service do
106
- port 1235
107
- standalone false
108
- end
109
- end
110
- end
111
-
112
- describe "configuration" do
113
- it "should return the same configuration object each time" do
114
- expect(Pact.configuration).to equal(Pact.configuration)
115
- end
116
- end
117
-
118
- describe "deprecated consumer" do
119
- it "should be configured" do
120
- Pact.configuration.consumer.name.should eq "My Consumer"
121
- end
122
- end
123
-
124
- describe "producers" do
125
- include Pact::Consumer::ConsumerContractBuilders
126
-
127
- it "should have defined methods in MockServices for the producers" do
128
- my_service.should be_instance_of Pact::Consumer::ConsumerContractBuilder
129
- end
130
-
131
- context "when standalone is true" do
132
- it "is not registerd with the AppManager" do
133
- Pact::Consumer::AppManager.instance.app_registered_on?(1234).should be_false
134
- end
135
- end
136
-
137
- context "when standalone is false" do
138
- it "should register the MockServices on their given ports if they are not" do
139
- Pact::Consumer::AppManager.instance.app_registered_on?(1235).should be_true
140
- end
141
- end
142
- end
143
- end
144
81
  end
@@ -5,7 +5,7 @@ describe "provider side" do
5
5
  describe "configure" do
6
6
 
7
7
  class TestHelper
8
- include Pact::Producer::RSpec::InstanceMethods
8
+ include Pact::Provider::RSpec::InstanceMethods
9
9
  end
10
10
 
11
11
  let(:application) { double("App")}
@@ -7,23 +7,26 @@ module Pact
7
7
  describe ConsumerContractBuilder do
8
8
 
9
9
  describe "initialize" do
10
+ SUPPORT_PACT_FILE = './spec/support/a_consumer-a_provider.json'
10
11
  before do
11
12
  Pact.clear_configuration
12
13
  Pact.configuration.stub(:pact_dir).and_return(File.expand_path(tmp_pact_dir))
13
14
  FileUtils.rm_rf tmp_pact_dir
14
15
  FileUtils.mkdir_p tmp_pact_dir
15
- FileUtils.cp './spec/support/a_consumer-a_producer.json', "#{tmp_pact_dir}/a_consumer-a_producer.json"
16
+ FileUtils.cp SUPPORT_PACT_FILE, "#{tmp_pact_dir}/a_consumer-a_provider.json"
16
17
  end
17
18
 
19
+ let(:expected_interactions) { ConsumerContract.from_json(File.read(SUPPORT_PACT_FILE)).interactions }
20
+
18
21
  let(:tmp_pact_dir) {"./tmp/pacts"}
19
22
 
20
23
  let(:consumer_name) { 'a consumer' }
21
- let(:producer_name) { 'a producer' }
24
+ let(:provider_name) { 'a provider' }
22
25
  let(:consumer_contract_builder) {
23
26
  Pact::Consumer::ConsumerContractBuilder.new(
24
27
  :pactfile_write_mode => pactfile_write_mode,
25
28
  :consumer_name => consumer_name,
26
- :producer_name => producer_name,
29
+ :provider_name => provider_name,
27
30
  :port => 1234)}
28
31
 
29
32
  context "when overwriting pact" do
@@ -31,20 +34,51 @@ module Pact
31
34
  it "it overwrites the existing pact file" do
32
35
  expect(consumer_contract_builder.consumer_contract.interactions).to eq []
33
36
  end
37
+
38
+ it "uses an DistinctInteractionsFilter to handle new interactions" do
39
+ Pact::Consumer::DistinctInteractionsFilter.should_receive(:new).with([])
40
+ consumer_contract_builder
41
+ end
34
42
  end
35
43
 
36
44
  context "when updating pact" do
37
45
  let(:pactfile_write_mode) {:update}
38
- it "updates the existing pact file" do
39
- expect(consumer_contract_builder.consumer_contract.interactions.size).to eq 2
46
+ it "loads the interactions from the existing pact file" do
47
+ expect(consumer_contract_builder.consumer_contract.interactions).to eq expected_interactions
48
+ end
49
+
50
+ it "uses an UpdatableInteractionsFilter to handle new interactions" do
51
+ Pact::Consumer::UpdatableInteractionsFilter.should_receive(:new).with(expected_interactions)
52
+ consumer_contract_builder
40
53
  end
41
54
  end
55
+
56
+ context "when an error occurs deserializing the existing pactfile" do
57
+ let(:pactfile_write_mode) {:update}
58
+ let(:error) { RuntimeError.new('some error')}
59
+ let(:line1) { /Could not load existing consumer contract from .* due to some error/ }
60
+ let(:line2) {'Creating a new file.'}
61
+ before do
62
+ ConsumerContract.stub(:from_json).and_raise(error)
63
+ $stderr.should_receive(:puts).with(line1)
64
+ $stderr.should_receive(:puts).with(line2)
65
+ Pact.configuration.logger.should_receive(:warn).with(line1)
66
+ Pact.configuration.logger.should_receive(:warn).with(line2)
67
+ end
68
+ it "logs the error" do
69
+ consumer_contract_builder
70
+ end
71
+
72
+ it "continues with a new file" do
73
+ expect(consumer_contract_builder.consumer_contract.interactions).to eq []
74
+ end
75
+ end
42
76
  end
43
77
 
44
78
  describe "handle_interaction_fully_defined" do
45
79
 
46
80
  subject {
47
- Pact::Consumer::ConsumerContractBuilder.new({:consumer_name => 'blah', :producer_name => 'blah', :port => 2222})
81
+ Pact::Consumer::ConsumerContractBuilder.new({:consumer_name => 'blah', :provider_name => 'blah', :port => 2222})
48
82
  }
49
83
 
50
84
  let(:interaction_hash) {
@@ -66,21 +100,31 @@ module Pact
66
100
 
67
101
  let(:interaction_json) { interaction.to_json_for_mock_service }
68
102
 
69
- let(:interaction) { Pact::Consumer::Interaction.from_hash(JSON.parse(interaction_hash.to_json)) }
103
+ let(:interaction) { Pact::Interaction.from_hash(JSON.parse(interaction_hash.to_json)) }
70
104
 
71
105
  before do
72
106
  stub_request(:post, 'localhost:2222/interactions')
73
107
  end
74
108
 
75
- it "posts the interaction with generated response to the mock service" do
76
- subject.handle_interaction_fully_defined interaction
77
- WebMock.should have_requested(:post, 'localhost:2222/interactions').with(body: interaction_json)
78
- end
109
+ it "posts the interaction with generated response to the mock service" do
110
+ subject.handle_interaction_fully_defined interaction
111
+ WebMock.should have_requested(:post, 'localhost:2222/interactions').with(body: interaction_json)
112
+ end
113
+
114
+ it "adds the interaction to the consumer contract" do
115
+ subject.handle_interaction_fully_defined interaction
116
+ expect(subject.consumer_contract.interactions).to eq [interaction]
117
+ end
118
+
119
+ it "updates the provider's pactfile" do
120
+ subject.consumer_contract.should_receive(:update_pactfile)
121
+ subject.handle_interaction_fully_defined interaction
122
+ end
79
123
 
80
- it "updates the Producer's Pactfile" do
81
- subject.consumer_contract.should_receive(:update_pactfile)
82
- subject.handle_interaction_fully_defined interaction
83
- end
124
+ it "resets the interaction_builder to nil" do
125
+ subject.should_receive(:interaction_builder=).with(nil)
126
+ subject.handle_interaction_fully_defined interaction
127
+ end
84
128
  end
85
129
  end
86
130
  end