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,73 +0,0 @@
|
|
1
|
-
require_relative 'service_consumer'
|
2
|
-
require_relative 'consumer_contract_builders'
|
3
|
-
require_relative '../configuration'
|
4
|
-
|
5
|
-
module Pact
|
6
|
-
module Consumer
|
7
|
-
|
8
|
-
|
9
|
-
module Configuration
|
10
|
-
def add_producer_verification &block
|
11
|
-
producer_verifications << block
|
12
|
-
end
|
13
|
-
def producer_verifications
|
14
|
-
@producer_verifications ||= []
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
module ConfigurationDSL
|
19
|
-
|
20
|
-
def consumer &block
|
21
|
-
if block_given?
|
22
|
-
@consumer = ConsumerDSL.new(&block).create_service_consumer
|
23
|
-
elsif @consumer
|
24
|
-
@consumer
|
25
|
-
else
|
26
|
-
raise "Please configure a consumer before configuring producers"
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
alias_method :service_consumer, :consumer
|
31
|
-
|
32
|
-
class ConsumerDSL
|
33
|
-
|
34
|
-
def initialize &block
|
35
|
-
@app = nil
|
36
|
-
@port = nil
|
37
|
-
@name = nil
|
38
|
-
instance_eval(&block)
|
39
|
-
end
|
40
|
-
|
41
|
-
def validate
|
42
|
-
raise "Please provide a consumer name" unless @name
|
43
|
-
raise "Please provide a port for the consumer app" if @app && !@port
|
44
|
-
end
|
45
|
-
|
46
|
-
def name name
|
47
|
-
@name = name
|
48
|
-
end
|
49
|
-
|
50
|
-
def app app
|
51
|
-
@app = app
|
52
|
-
end
|
53
|
-
|
54
|
-
def port port
|
55
|
-
@port = port
|
56
|
-
end
|
57
|
-
|
58
|
-
def create_service_consumer
|
59
|
-
validate
|
60
|
-
register_consumer_app if @app
|
61
|
-
Pact::Consumer::ServiceConsumer.new name: @name
|
62
|
-
end
|
63
|
-
|
64
|
-
def register_consumer_app
|
65
|
-
Pact::Consumer::AppManager.instance.register @app, @port
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
Pact::Configuration.send(:include, Pact::Consumer::ConfigurationDSL)
|
73
|
-
Pact::Configuration.send(:include, Pact::Consumer::Configuration)
|
@@ -1,74 +0,0 @@
|
|
1
|
-
require 'net/http'
|
2
|
-
require 'pact/reification'
|
3
|
-
require 'pact/request'
|
4
|
-
#require 'json/add/core'
|
5
|
-
|
6
|
-
module Pact
|
7
|
-
module Consumer
|
8
|
-
|
9
|
-
class Interaction
|
10
|
-
|
11
|
-
attr_accessor :description, :request, :response, :producer_state
|
12
|
-
|
13
|
-
def initialize attributes
|
14
|
-
@description = attributes[:description]
|
15
|
-
@request = attributes[:request]
|
16
|
-
@response = attributes[:response]
|
17
|
-
@producer_state = attributes[:producer_state]
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.from_hash hash
|
21
|
-
new(:description => hash['description'],
|
22
|
-
:producer_state => hash['producer_state'],
|
23
|
-
:request => Pact::Request::Expected.from_hash(hash['request']),
|
24
|
-
:response => hash['response']
|
25
|
-
)
|
26
|
-
end
|
27
|
-
|
28
|
-
def as_json
|
29
|
-
{
|
30
|
-
:description => @description,
|
31
|
-
:request => @request.as_json,
|
32
|
-
:response => @response,
|
33
|
-
}.tap{ | hash | hash[:producer_state] = @producer_state if @producer_state }
|
34
|
-
end
|
35
|
-
|
36
|
-
def to_json(options = {})
|
37
|
-
as_json.to_json(options)
|
38
|
-
end
|
39
|
-
|
40
|
-
def as_json_for_mock_service
|
41
|
-
{:response => Reification.from_term(response), :request => @request.as_json_with_options, :description => description }.
|
42
|
-
tap{ | hash | hash[:producer_state] = @producer_state if @producer_state }
|
43
|
-
end
|
44
|
-
|
45
|
-
def to_json_for_mock_service
|
46
|
-
as_json_for_mock_service.to_json
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
class InteractionBuilder
|
51
|
-
|
52
|
-
attr_reader :interaction
|
53
|
-
|
54
|
-
def initialize(description, producer_state)
|
55
|
-
producer_state = producer_state.nil? ? nil : producer_state.to_s
|
56
|
-
@interaction = Interaction.new(:description => description, :producer_state => producer_state)
|
57
|
-
end
|
58
|
-
|
59
|
-
def with(request_details)
|
60
|
-
interaction.request = Request::Expected.from_hash(request_details)
|
61
|
-
self
|
62
|
-
end
|
63
|
-
|
64
|
-
def will_respond_with(response)
|
65
|
-
interaction.response = response
|
66
|
-
@callback.call interaction
|
67
|
-
end
|
68
|
-
|
69
|
-
def on_interaction_fully_defined &block
|
70
|
-
@callback = block
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'net/http'
|
2
|
-
require_relative 'spawn_app'
|
3
|
-
require_relative 'mock_service'
|
4
|
-
|
5
|
-
spawn_app MockService.new, 1234
|
6
|
-
|
7
|
-
RSpec.configure do |c|
|
8
|
-
c.before(:each, :type => :feature) do
|
9
|
-
http = Net::HTTP.new('localhost', 1234)
|
10
|
-
request = Net::HTTP::Delete.new('/interactions')
|
11
|
-
response = http.request(request)
|
12
|
-
end
|
13
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
module Pact
|
2
|
-
module Consumer
|
3
|
-
class ServiceConsumer
|
4
|
-
attr_accessor :name
|
5
|
-
def initialize options
|
6
|
-
@name = options[:name]
|
7
|
-
end
|
8
|
-
|
9
|
-
def to_s
|
10
|
-
name
|
11
|
-
end
|
12
|
-
|
13
|
-
def as_json options = {}
|
14
|
-
{name: name}
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.from_hash obj
|
18
|
-
ServiceConsumer.new(:name => obj['name'])
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
module Pact
|
2
|
-
module Consumer
|
3
|
-
# This is a crap name, it's really just a object for serializing to JSON
|
4
|
-
class ServiceProducer
|
5
|
-
attr_accessor :name
|
6
|
-
def initialize options
|
7
|
-
@name = options[:name] || '[producer name unknown - please update the pact gem in the consumer project to the latest version and regenerate the pacts]'
|
8
|
-
end
|
9
|
-
|
10
|
-
def to_s
|
11
|
-
name
|
12
|
-
end
|
13
|
-
|
14
|
-
def as_json options = {}
|
15
|
-
{name: name}
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.from_hash obj
|
19
|
-
ServiceProducer.new(:name => obj['name'])
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,62 +0,0 @@
|
|
1
|
-
require 'ostruct'
|
2
|
-
|
3
|
-
|
4
|
-
module Pact
|
5
|
-
module Producer
|
6
|
-
module ConfigurationDSL
|
7
|
-
|
8
|
-
def producer &block
|
9
|
-
@producer ||= nil
|
10
|
-
if block_given?
|
11
|
-
@producer = ProducerDSL.new(&block).create_producer_config
|
12
|
-
elsif @producer
|
13
|
-
@producer
|
14
|
-
else
|
15
|
-
raise "Please configure your producer. See the Producer section in the README for examples."
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
class ProducerConfig
|
20
|
-
attr_accessor :name
|
21
|
-
|
22
|
-
def initialize name, &app_block
|
23
|
-
@name = name
|
24
|
-
@app_block = app_block
|
25
|
-
end
|
26
|
-
|
27
|
-
def app
|
28
|
-
@app_block.call
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
class ProducerDSL
|
33
|
-
|
34
|
-
def initialize &block
|
35
|
-
@app = nil
|
36
|
-
@name = nil
|
37
|
-
instance_eval(&block)
|
38
|
-
end
|
39
|
-
|
40
|
-
def validate
|
41
|
-
raise "Please provide a name for the Producer" unless @name
|
42
|
-
raise "Please configure an app for the Producer" unless @app_block
|
43
|
-
end
|
44
|
-
|
45
|
-
def name name
|
46
|
-
@name = name
|
47
|
-
end
|
48
|
-
|
49
|
-
def app &block
|
50
|
-
@app_block = block
|
51
|
-
end
|
52
|
-
|
53
|
-
def create_producer_config
|
54
|
-
validate
|
55
|
-
ProducerConfig.new(@name, &@app_block)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
Pact::Configuration.send(:include, Pact::Producer::ConfigurationDSL)
|
data/lib/pact/producer/rspec.rb
DELETED
@@ -1,129 +0,0 @@
|
|
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_relative 'configuration_dsl'
|
7
|
-
require_relative 'dsl'
|
8
|
-
|
9
|
-
module Pact
|
10
|
-
module Producer
|
11
|
-
module RSpec
|
12
|
-
|
13
|
-
module InstanceMethods
|
14
|
-
def app
|
15
|
-
Pact.configuration.producer.app
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
module ClassMethods
|
20
|
-
|
21
|
-
include Pact::JsonWarning
|
22
|
-
|
23
|
-
def honour_pactfile pactfile_uri, options = {}
|
24
|
-
describe "Pact in #{pactfile_uri}" do
|
25
|
-
consumer_contract = Pact::ConsumerContract.from_json(read_pact_from(pactfile_uri, options))
|
26
|
-
honour_consumer_contract consumer_contract, options
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def honour_consumer_contract consumer_contract, options = {}
|
31
|
-
check_for_active_support_json
|
32
|
-
describe_consumer_contract consumer_contract, options.merge({:consumer => consumer_contract.consumer.name})
|
33
|
-
end
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
def describe_consumer_contract consumer_contract, options
|
38
|
-
consumer_contract.interactions.each do |interaction|
|
39
|
-
describe_interaction_with_producer_state interaction, options
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def describe_interaction_with_producer_state interaction, options
|
44
|
-
if interaction.producer_state
|
45
|
-
describe "Given #{interaction.producer_state}" do
|
46
|
-
describe_interaction interaction, options
|
47
|
-
end
|
48
|
-
else
|
49
|
-
describe_interaction interaction, options
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def describe_interaction interaction, options
|
54
|
-
|
55
|
-
describe description_for(interaction) do
|
56
|
-
|
57
|
-
before do
|
58
|
-
set_up_producer_state interaction.producer_state, options[:consumer]
|
59
|
-
replay_interaction interaction
|
60
|
-
end
|
61
|
-
|
62
|
-
after do
|
63
|
-
tear_down_producer_state interaction.producer_state, options[:consumer]
|
64
|
-
end
|
65
|
-
|
66
|
-
describe_response interaction.response
|
67
|
-
end
|
68
|
-
|
69
|
-
end
|
70
|
-
|
71
|
-
def describe_response response
|
72
|
-
describe "returns a response which" do
|
73
|
-
if response['status']
|
74
|
-
it "has status code #{response['status']}" do
|
75
|
-
expect(last_response.status).to eql response['status']
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
if response['headers']
|
80
|
-
describe "includes headers" do
|
81
|
-
response['headers'].each do |name, value|
|
82
|
-
it "\"#{name}\" with value \"#{value}\"" do
|
83
|
-
expect(last_response.headers[name]).to match_term value
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
if response['body']
|
90
|
-
it "has a matching body" do
|
91
|
-
logger.debug "Response body is #{last_response.body}"
|
92
|
-
expect(parse_entity_from_response(last_response)).to match_term response['body']
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
def description_for interaction
|
99
|
-
"#{interaction.description} to #{interaction.request.path}"
|
100
|
-
end
|
101
|
-
|
102
|
-
def read_pact_from uri, options = {}
|
103
|
-
pact = open(uri) { | file | file.read }
|
104
|
-
if options[:save_pactfile_to_tmp]
|
105
|
-
save_pactfile_to_tmp pact, File.basename(uri)
|
106
|
-
end
|
107
|
-
pact
|
108
|
-
rescue StandardError => e
|
109
|
-
$stderr.puts "Error reading file from #{uri}"
|
110
|
-
$stderr.puts "#{e.to_s} #{e.backtrace.join("\n")}"
|
111
|
-
raise e
|
112
|
-
end
|
113
|
-
|
114
|
-
def save_pactfile_to_tmp pact, name
|
115
|
-
FileUtils.mkdir_p Pact.configuration.tmp_dir
|
116
|
-
File.open(Pact.configuration.tmp_dir + "/#{name}", "w") { |file| file << pact}
|
117
|
-
end
|
118
|
-
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
RSpec.configure do |config|
|
125
|
-
config.extend Pact::Producer::RSpec::ClassMethods
|
126
|
-
config.include Pact::Producer::RSpec::InstanceMethods
|
127
|
-
config.include Pact::Producer::TestMethods
|
128
|
-
config.include Pact::Producer::TestMethods
|
129
|
-
end
|