pact 0.1.37 → 1.0.0

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