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.
- data/Gemfile.lock +6 -19
- data/example/zoo-app/Gemfile +1 -2
- data/example/zoo-app/Gemfile.lock +16 -13
- data/example/zoo-app/spec/pacts/zoo_app-animal_service.json +6 -6
- data/lib/pact/consumer/app_manager.rb +8 -28
- data/lib/pact/consumer/consumer_contract_builder.rb +65 -36
- data/lib/pact/consumer/dsl.rb +20 -10
- data/lib/pact/consumer/interaction_builder.rb +42 -0
- data/lib/pact/consumer/interactions_filter.rb +41 -0
- data/lib/pact/consumer/mock_service.rb +26 -19
- data/lib/pact/consumer/rspec.rb +2 -3
- data/lib/pact/consumer/server.rb +90 -0
- data/lib/pact/consumer.rb +6 -3
- data/lib/pact/consumer_contract/consumer_contract.rb +103 -0
- data/lib/pact/consumer_contract/interaction.rb +70 -0
- data/lib/pact/consumer_contract/service_consumer.rb +20 -0
- data/lib/pact/consumer_contract/service_provider.rb +20 -0
- data/lib/pact/consumer_contract.rb +1 -112
- data/lib/pact/{producer → provider}/dsl.rb +15 -4
- data/lib/pact/{producer → provider}/matchers.rb +0 -0
- data/lib/pact/{producer → provider}/pact_spec_runner.rb +2 -2
- data/lib/pact/{producer/producer_state.rb → provider/provider_state.rb} +13 -22
- data/lib/pact/provider/rspec.rb +128 -1
- data/lib/pact/{producer → provider}/test_methods.rb +12 -12
- data/lib/pact/{producer.rb → provider.rb} +0 -0
- data/lib/pact/verification_task.rb +4 -4
- data/lib/pact/version.rb +1 -1
- data/lib/pact.rb +1 -1
- data/pact.gemspec +1 -2
- data/scratchpad.txt +1 -1
- data/spec/features/consumption_spec.rb +15 -23
- data/spec/features/production_spec.rb +5 -5
- data/spec/features/{producer_states → provider_states}/zebras.rb +3 -3
- data/spec/integration/pact/consumer_configuration_spec.rb +3 -66
- data/spec/integration/pact/provider_configuration_spec.rb +1 -1
- data/spec/lib/pact/consumer/consumer_contract_builder_spec.rb +59 -15
- data/spec/lib/pact/consumer/dsl_spec.rb +4 -5
- data/spec/lib/pact/consumer/interaction_builder_spec.rb +91 -0
- data/spec/lib/pact/consumer/interactions_spec.rb +64 -0
- data/spec/lib/pact/consumer/mock_service_spec.rb +2 -6
- data/spec/lib/pact/consumer/service_consumer_spec.rb +1 -1
- data/spec/lib/pact/{consumer_contract_spec.rb → consumer_contract/consumer_contract_spec.rb} +72 -28
- data/spec/lib/pact/{consumer → consumer_contract}/interaction_spec.rb +49 -64
- data/spec/lib/pact/{producer/configuration_dsl_spec.rb → provider/dsl_spec.rb} +29 -28
- data/spec/lib/pact/{producer/producer_state_spec.rb → provider/provider_state_spec.rb} +17 -17
- data/spec/lib/pact/{producer → provider}/rspec_spec.rb +1 -1
- data/spec/lib/pact/verification_task_spec.rb +3 -3
- data/spec/spec_helper.rb +1 -0
- data/spec/support/a_consumer-a_producer.json +1 -1
- data/spec/support/a_consumer-a_provider.json +34 -0
- data/spec/support/consumer_contract_template.json +26 -0
- data/spec/support/factories.rb +78 -0
- data/spec/support/pact_rake_support.rb +1 -1
- data/spec/support/test_app_fail.json +1 -1
- data/spec/support/test_app_pass.json +1 -1
- data/tasks/pact-test.rake +3 -3
- metadata +38 -45
- data/lib/pact/consumer/configuration_dsl.rb +0 -73
- data/lib/pact/consumer/interaction.rb +0 -74
- data/lib/pact/consumer/run_condor.rb +0 -4
- data/lib/pact/consumer/run_mock_contract_service.rb +0 -13
- data/lib/pact/consumer/service_consumer.rb +0 -22
- data/lib/pact/consumer/service_producer.rb +0 -23
- data/lib/pact/producer/configuration_dsl.rb +0 -62
- data/lib/pact/producer/rspec.rb +0 -129
@@ -1,40 +1,33 @@
|
|
1
1
|
module Pact
|
2
|
-
module
|
2
|
+
module Provider
|
3
3
|
|
4
4
|
module DSL
|
5
|
-
def
|
6
|
-
|
5
|
+
def provider_state name, &block
|
6
|
+
ProviderState.provider_state(name, &block).register
|
7
7
|
end
|
8
8
|
|
9
|
-
def
|
10
|
-
|
9
|
+
def provider_states_for name, &block
|
10
|
+
ProviderState.current_namespaces << name
|
11
11
|
instance_eval(&block)
|
12
|
-
|
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
|
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
|
-
|
22
|
+
ProviderState.new(name, current_namespaces.join('.'), &block)
|
30
23
|
end
|
31
24
|
|
32
|
-
def self.register name,
|
33
|
-
|
25
|
+
def self.register name, provider_state
|
26
|
+
provider_states[name] = provider_state
|
34
27
|
end
|
35
28
|
|
36
|
-
def self.
|
37
|
-
@@
|
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
|
-
(
|
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)
|
data/lib/pact/provider/rspec.rb
CHANGED
@@ -1 +1,128 @@
|
|
1
|
-
require '
|
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/
|
4
|
+
require 'pact/provider/provider_state'
|
5
5
|
|
6
6
|
module Pact
|
7
|
-
module
|
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
|
23
|
-
if
|
24
|
-
|
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
|
29
|
-
if
|
30
|
-
|
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
|
81
|
-
unless
|
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
|
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
|
-
|
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/
|
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
|
36
|
+
desc "Verify provider against the consumer pacts for #{name}"
|
37
37
|
task "verify:#{name}" do
|
38
|
-
exit_status =
|
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
|
-
"
|
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
data/lib/pact.rb
CHANGED
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
|
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
@@ -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
|
102
|
+
context "with a provider state" do
|
103
103
|
before do
|
104
104
|
Pact.clear_configuration
|
105
105
|
|
106
|
-
Pact.
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
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.
|
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
|
136
|
+
context "with a async interaction with provider" do
|
141
137
|
before do
|
142
138
|
Pact.clear_configuration
|
143
139
|
|
144
|
-
Pact.
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
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/
|
3
|
+
require 'features/provider_states/zebras'
|
4
4
|
|
5
5
|
|
6
|
-
module Pact::
|
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
|
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
|
-
"
|
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
|
-
"
|
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.
|
4
|
+
Pact.provider_states_for 'the-wild-beast-store' do
|
5
5
|
|
6
|
-
|
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.
|
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::
|
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 "
|
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
|
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
|
@@ -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
|
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(:
|
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
|
-
:
|
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 "
|
39
|
-
expect(consumer_contract_builder.consumer_contract.interactions
|
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', :
|
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::
|
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
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
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
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
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
|