pact 1.3.3 → 1.4.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +16 -1
- data/Gemfile +5 -0
- data/Gemfile.lock +34 -13
- data/README.md +3 -2
- data/example/animal-service/lib/animal_service/api.rb +1 -0
- data/example/zoo-app/lib/zoo_app/animal_service_client.rb +0 -9
- data/example/zoo-app/lib/zoo_app/models/alligator.rb +2 -0
- data/lib/pact.rb +6 -5
- data/lib/pact/cli.rb +0 -26
- data/lib/pact/consumer/configuration.rb +0 -1
- data/lib/pact/consumer/configuration/configuration_extensions.rb +51 -0
- data/lib/pact/consumer/consumer_contract_builder.rb +1 -2
- data/lib/pact/consumer/interaction_builder.rb +2 -4
- data/lib/pact/doc/interaction_view_model.rb +9 -6
- data/lib/pact/doc/sort_interactions.rb +1 -1
- data/lib/pact/provider/rspec.rb +11 -9
- data/lib/pact/version.rb +1 -1
- data/pact.gemspec +5 -0
- data/spec/lib/pact/consumer/interaction_builder_spec.rb +4 -8
- data/spec/support/case-insensitive-response-header-matching.json +21 -0
- data/spec/support/case-insensitive-response-header-matching.rb +15 -0
- data/tasks/pact-test.rake +5 -0
- metadata +42 -122
- data/lib/pact/configuration.rb +0 -195
- data/lib/pact/consumer/app_manager.rb +0 -158
- data/lib/pact/consumer/interactions_filter.rb +0 -48
- data/lib/pact/consumer/mock_service.rb +0 -2
- data/lib/pact/consumer/mock_service/app.rb +0 -82
- data/lib/pact/consumer/mock_service/interaction_delete.rb +0 -33
- data/lib/pact/consumer/mock_service/interaction_list.rb +0 -76
- data/lib/pact/consumer/mock_service/interaction_mismatch.rb +0 -73
- data/lib/pact/consumer/mock_service/interaction_post.rb +0 -31
- data/lib/pact/consumer/mock_service/interaction_replay.rb +0 -139
- data/lib/pact/consumer/mock_service/log_get.rb +0 -28
- data/lib/pact/consumer/mock_service/missing_interactions_get.rb +0 -30
- data/lib/pact/consumer/mock_service/mock_service_administration_endpoint.rb +0 -31
- data/lib/pact/consumer/mock_service/pact_post.rb +0 -33
- data/lib/pact/consumer/mock_service/rack_request_helper.rb +0 -51
- data/lib/pact/consumer/mock_service/verification_get.rb +0 -68
- data/lib/pact/consumer/mock_service_client.rb +0 -65
- data/lib/pact/consumer/mock_service_interaction_expectation.rb +0 -37
- data/lib/pact/consumer/request.rb +0 -27
- data/lib/pact/consumer/server.rb +0 -90
- data/lib/pact/consumer_contract.rb +0 -1
- data/lib/pact/consumer_contract/consumer_contract.rb +0 -115
- data/lib/pact/consumer_contract/consumer_contract_writer.rb +0 -84
- data/lib/pact/consumer_contract/file_name.rb +0 -19
- data/lib/pact/consumer_contract/headers.rb +0 -51
- data/lib/pact/consumer_contract/interaction.rb +0 -67
- data/lib/pact/consumer_contract/pact_file.rb +0 -24
- data/lib/pact/consumer_contract/request.rb +0 -73
- data/lib/pact/consumer_contract/service_consumer.rb +0 -28
- data/lib/pact/consumer_contract/service_provider.rb +0 -28
- data/lib/pact/logging.rb +0 -14
- data/lib/pact/matchers.rb +0 -1
- data/lib/pact/matchers/actual_type.rb +0 -16
- data/lib/pact/matchers/base_difference.rb +0 -37
- data/lib/pact/matchers/differ.rb +0 -153
- data/lib/pact/matchers/difference.rb +0 -13
- data/lib/pact/matchers/difference_indicator.rb +0 -26
- data/lib/pact/matchers/embedded_diff_formatter.rb +0 -62
- data/lib/pact/matchers/expected_type.rb +0 -35
- data/lib/pact/matchers/index_not_found.rb +0 -15
- data/lib/pact/matchers/list_diff_formatter.rb +0 -101
- data/lib/pact/matchers/matchers.rb +0 -139
- data/lib/pact/matchers/no_diff_indicator.rb +0 -18
- data/lib/pact/matchers/regexp_difference.rb +0 -13
- data/lib/pact/matchers/type_difference.rb +0 -16
- data/lib/pact/matchers/unexpected_index.rb +0 -11
- data/lib/pact/matchers/unexpected_key.rb +0 -11
- data/lib/pact/matchers/unix_diff_formatter.rb +0 -114
- data/lib/pact/reification.rb +0 -28
- data/lib/pact/rspec.rb +0 -53
- data/lib/pact/shared/active_support_support.rb +0 -51
- data/lib/pact/shared/dsl.rb +0 -76
- data/lib/pact/shared/jruby_support.rb +0 -18
- data/lib/pact/shared/json_differ.rb +0 -15
- data/lib/pact/shared/key_not_found.rb +0 -15
- data/lib/pact/shared/null_expectation.rb +0 -31
- data/lib/pact/shared/request.rb +0 -80
- data/lib/pact/shared/text_differ.rb +0 -14
- data/lib/pact/something_like.rb +0 -49
- data/lib/pact/symbolize_keys.rb +0 -12
- data/lib/pact/term.rb +0 -85
- data/spec/lib/pact/consumer/request_spec.rb +0 -24
- data/spec/lib/pact/consumer_contract/active_support_support_spec.rb +0 -58
- data/spec/lib/pact/consumer_contract/consumer_contract_spec.rb +0 -180
- data/spec/lib/pact/consumer_contract/headers_spec.rb +0 -107
- data/spec/lib/pact/consumer_contract/interaction_spec.rb +0 -107
- data/spec/lib/pact/consumer_contract/request_spec.rb +0 -329
- data/spec/lib/pact/matchers/differ_spec.rb +0 -214
- data/spec/lib/pact/matchers/difference_spec.rb +0 -22
- data/spec/lib/pact/matchers/embedded_diff_formatter_spec.rb +0 -90
- data/spec/lib/pact/matchers/index_not_found_spec.rb +0 -21
- data/spec/lib/pact/matchers/list_diff_formatter_spec.rb +0 -114
- data/spec/lib/pact/matchers/matchers_spec.rb +0 -500
- data/spec/lib/pact/matchers/regexp_difference_spec.rb +0 -20
- data/spec/lib/pact/matchers/type_difference_spec.rb +0 -34
- data/spec/lib/pact/matchers/unexpected_index_spec.rb +0 -20
- data/spec/lib/pact/matchers/unexpected_key_spec.rb +0 -20
- data/spec/lib/pact/matchers/unix_diff_formatter_spec.rb +0 -216
- data/spec/lib/pact/reification_spec.rb +0 -67
- data/spec/lib/pact/shared/dsl_spec.rb +0 -86
- data/spec/lib/pact/shared/json_differ_spec.rb +0 -36
- data/spec/lib/pact/shared/key_not_found_spec.rb +0 -20
- data/spec/lib/pact/shared/request_spec.rb +0 -111
- data/spec/lib/pact/shared/text_differ_spec.rb +0 -54
- data/spec/lib/pact/something_like_spec.rb +0 -21
- data/spec/lib/pact/term_spec.rb +0 -89
- data/spec/support/dsl_spec_support.rb +0 -7
@@ -1,37 +0,0 @@
|
|
1
|
-
require 'pact/reification'
|
2
|
-
|
3
|
-
# Represents the Interaction in the form required by the MockService
|
4
|
-
# The json generated will be posted to the MockService to register the expectation
|
5
|
-
module Pact
|
6
|
-
module Consumer
|
7
|
-
class MockServiceInteractionExpectation
|
8
|
-
|
9
|
-
|
10
|
-
def initialize interaction
|
11
|
-
@interaction = interaction
|
12
|
-
end
|
13
|
-
|
14
|
-
def to_hash
|
15
|
-
hash = {:description => interaction.description}
|
16
|
-
hash[:provider_state] = interaction.provider_state if interaction.provider_state
|
17
|
-
options = interaction.request.options.empty? ? {} : { options: interaction.request.options}
|
18
|
-
hash[:request] = interaction.request.as_json.merge(options)
|
19
|
-
hash[:response] = interaction.response
|
20
|
-
hash
|
21
|
-
end
|
22
|
-
|
23
|
-
def as_json options = {}
|
24
|
-
to_hash
|
25
|
-
end
|
26
|
-
|
27
|
-
def to_json opts = {}
|
28
|
-
as_json.to_json(opts)
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
33
|
-
attr_reader :interaction
|
34
|
-
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
require 'pact/shared/request'
|
2
|
-
require 'pact/shared/key_not_found'
|
3
|
-
|
4
|
-
module Pact
|
5
|
-
module Consumer
|
6
|
-
module Request
|
7
|
-
class Actual < Pact::Request::Base
|
8
|
-
|
9
|
-
def self.from_hash(hash)
|
10
|
-
sym_hash = symbolize_keys hash
|
11
|
-
method = sym_hash.fetch(:method)
|
12
|
-
path = sym_hash.fetch(:path)
|
13
|
-
query = sym_hash.fetch(:query)
|
14
|
-
headers = sym_hash.fetch(:headers)
|
15
|
-
body = sym_hash.fetch(:body, nil)
|
16
|
-
new(method, path, headers, body, query)
|
17
|
-
end
|
18
|
-
|
19
|
-
protected
|
20
|
-
|
21
|
-
def self.key_not_found
|
22
|
-
nil
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
data/lib/pact/consumer/server.rb
DELETED
@@ -1,90 +0,0 @@
|
|
1
|
-
require 'uri'
|
2
|
-
require 'net/http'
|
3
|
-
require 'rack'
|
4
|
-
|
5
|
-
# Copied shamelessly from Capybara
|
6
|
-
module Pact
|
7
|
-
class Server
|
8
|
-
class Middleware
|
9
|
-
attr_accessor :error
|
10
|
-
|
11
|
-
def initialize(app)
|
12
|
-
@app = app
|
13
|
-
end
|
14
|
-
|
15
|
-
def call(env)
|
16
|
-
if env["PATH_INFO"] == "/__identify__"
|
17
|
-
[200, {}, [@app.object_id.to_s]]
|
18
|
-
else
|
19
|
-
begin
|
20
|
-
@app.call(env)
|
21
|
-
rescue StandardError => e
|
22
|
-
@error = e unless @error
|
23
|
-
raise e
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
class << self
|
30
|
-
def ports
|
31
|
-
@ports ||= {}
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
attr_reader :app, :port
|
36
|
-
|
37
|
-
def initialize(app, port)
|
38
|
-
@app = app
|
39
|
-
@middleware = Middleware.new(@app)
|
40
|
-
@server_thread = nil # supress warnings
|
41
|
-
@port = port
|
42
|
-
end
|
43
|
-
|
44
|
-
def reset_error!
|
45
|
-
@middleware.error = nil
|
46
|
-
end
|
47
|
-
|
48
|
-
def error
|
49
|
-
@middleware.error
|
50
|
-
end
|
51
|
-
|
52
|
-
def host
|
53
|
-
"localhost"
|
54
|
-
end
|
55
|
-
|
56
|
-
def responsive?
|
57
|
-
return false if @server_thread && @server_thread.join(0)
|
58
|
-
|
59
|
-
res = Net::HTTP.start(host, @port) { |http| http.get('/__identify__') }
|
60
|
-
|
61
|
-
if res.is_a?(Net::HTTPSuccess) or res.is_a?(Net::HTTPRedirection)
|
62
|
-
return res.body == @app.object_id.to_s
|
63
|
-
end
|
64
|
-
rescue SystemCallError
|
65
|
-
return false
|
66
|
-
end
|
67
|
-
|
68
|
-
def run_default_server(app, port)
|
69
|
-
require 'rack/handler/webrick'
|
70
|
-
Rack::Handler::WEBrick.run(app, :Port => port, :AccessLog => [], :Logger => WEBrick::Log::new(nil, 0))
|
71
|
-
end
|
72
|
-
|
73
|
-
def boot
|
74
|
-
unless responsive?
|
75
|
-
Pact::Server.ports[@app.object_id] = @port
|
76
|
-
|
77
|
-
@server_thread = Thread.new do
|
78
|
-
run_default_server(@middleware, @port)
|
79
|
-
end
|
80
|
-
|
81
|
-
Timeout.timeout(60) { @server_thread.join(0.1) until responsive? }
|
82
|
-
end
|
83
|
-
rescue Timeout::Error
|
84
|
-
raise "Rack application timed out during boot"
|
85
|
-
else
|
86
|
-
self
|
87
|
-
end
|
88
|
-
|
89
|
-
end
|
90
|
-
end
|
@@ -1 +0,0 @@
|
|
1
|
-
require 'pact/consumer_contract/consumer_contract'
|
@@ -1,115 +0,0 @@
|
|
1
|
-
require 'pact/logging'
|
2
|
-
require 'pact/something_like'
|
3
|
-
require 'pact/symbolize_keys'
|
4
|
-
require 'pact/term'
|
5
|
-
require 'pact/version'
|
6
|
-
require 'pact/shared/active_support_support'
|
7
|
-
require 'date'
|
8
|
-
require 'json/add/regexp'
|
9
|
-
require 'open-uri'
|
10
|
-
require_relative 'service_consumer'
|
11
|
-
require_relative 'service_provider'
|
12
|
-
require_relative 'interaction'
|
13
|
-
require_relative 'request'
|
14
|
-
require_relative 'pact_file'
|
15
|
-
require_relative 'file_name'
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
module Pact
|
20
|
-
|
21
|
-
class ConsumerContract
|
22
|
-
|
23
|
-
include SymbolizeKeys
|
24
|
-
include Logging
|
25
|
-
include FileName
|
26
|
-
include ActiveSupportSupport
|
27
|
-
|
28
|
-
attr_accessor :interactions
|
29
|
-
attr_accessor :consumer
|
30
|
-
attr_accessor :provider
|
31
|
-
|
32
|
-
def initialize(attributes = {})
|
33
|
-
@interactions = attributes[:interactions] || []
|
34
|
-
@consumer = attributes[:consumer]
|
35
|
-
@provider = attributes[:provider]
|
36
|
-
end
|
37
|
-
|
38
|
-
def to_hash
|
39
|
-
{
|
40
|
-
provider: @provider.as_json,
|
41
|
-
consumer: @consumer.as_json,
|
42
|
-
interactions: @interactions.collect(&:as_json),
|
43
|
-
metadata: {
|
44
|
-
pactSpecificationVersion: "1.0.0"
|
45
|
-
}
|
46
|
-
}
|
47
|
-
end
|
48
|
-
|
49
|
-
def as_json(options = {})
|
50
|
-
fix_all_the_things to_hash
|
51
|
-
end
|
52
|
-
|
53
|
-
def to_json(options = {})
|
54
|
-
as_json.to_json(options)
|
55
|
-
end
|
56
|
-
|
57
|
-
def self.from_hash(hash)
|
58
|
-
hash = symbolize_keys(hash)
|
59
|
-
new({
|
60
|
-
:interactions => hash[:interactions].collect { |hash| Interaction.from_hash(hash)},
|
61
|
-
:consumer => ServiceConsumer.from_hash(hash[:consumer]),
|
62
|
-
:provider => ServiceProvider.from_hash(hash[:provider])
|
63
|
-
})
|
64
|
-
end
|
65
|
-
|
66
|
-
def self.from_json string
|
67
|
-
deserialised_object = JSON.load(maintain_backwards_compatiblity_with_producer_keys(string))
|
68
|
-
from_hash(deserialised_object)
|
69
|
-
end
|
70
|
-
|
71
|
-
def self.from_uri uri, options = {}
|
72
|
-
from_json(Pact::PactFile.read(uri, options))
|
73
|
-
end
|
74
|
-
|
75
|
-
def self.maintain_backwards_compatiblity_with_producer_keys string
|
76
|
-
string.gsub('"producer":', '"provider":').gsub('"producer_state":', '"provider_state":')
|
77
|
-
end
|
78
|
-
|
79
|
-
def find_interaction criteria
|
80
|
-
interactions = find_interactions criteria
|
81
|
-
if interactions.size == 0
|
82
|
-
raise "Could not find interaction matching #{criteria} in pact file between #{consumer.name} and #{provider.name}."
|
83
|
-
elsif interactions.size > 1
|
84
|
-
raise "Found more than 1 interaction matching #{criteria} in pact file between #{consumer.name} and #{provider.name}."
|
85
|
-
end
|
86
|
-
interactions.first
|
87
|
-
end
|
88
|
-
|
89
|
-
def find_interactions criteria
|
90
|
-
interactions.select{ | interaction| interaction.matches_criteria?(criteria)}
|
91
|
-
end
|
92
|
-
|
93
|
-
def each
|
94
|
-
interactions.each do | interaction |
|
95
|
-
yield interaction
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
def pact_file_name
|
100
|
-
file_name consumer.name, provider.name
|
101
|
-
end
|
102
|
-
|
103
|
-
def pactfile_path
|
104
|
-
raise 'You must first specify a consumer and service name' unless (consumer && consumer.name && provider && provider.name)
|
105
|
-
@pactfile_path ||= file_path consumer.name, provider.name
|
106
|
-
end
|
107
|
-
|
108
|
-
def update_pactfile
|
109
|
-
logger.debug "Updating pact file for #{provider.name} at #{pactfile_path}"
|
110
|
-
File.open(pactfile_path, 'w') do |f|
|
111
|
-
f.write fix_json_formatting(JSON.pretty_generate(self))
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
@@ -1,84 +0,0 @@
|
|
1
|
-
require 'pact/consumer_contract'
|
2
|
-
require 'pact/consumer/interactions_filter'
|
3
|
-
require 'pact/consumer_contract/file_name'
|
4
|
-
|
5
|
-
module Pact
|
6
|
-
|
7
|
-
class ConsumerContractWriter
|
8
|
-
|
9
|
-
attr_reader :consumer_contract_details, :pactfile_write_mode, :interactions, :logger
|
10
|
-
|
11
|
-
def initialize consumer_contract_details, logger
|
12
|
-
@logger = logger
|
13
|
-
@consumer_contract_details = consumer_contract_details
|
14
|
-
@pactfile_write_mode = consumer_contract_details.fetch(:pactfile_write_mode, :overwrite).to_sym
|
15
|
-
@interactions = consumer_contract_details.fetch(:interactions)
|
16
|
-
end
|
17
|
-
|
18
|
-
def consumer_contract
|
19
|
-
@consumer_contract ||= Pact::ConsumerContract.new(
|
20
|
-
consumer: ServiceConsumer.new(name: consumer_contract_details[:consumer][:name]),
|
21
|
-
provider: ServiceProvider.new(name: consumer_contract_details[:provider][:name]),
|
22
|
-
interactions: interactions_for_new_consumer_contract)
|
23
|
-
end
|
24
|
-
|
25
|
-
def write
|
26
|
-
consumer_contract.update_pactfile
|
27
|
-
consumer_contract.to_json
|
28
|
-
end
|
29
|
-
|
30
|
-
def interactions_for_new_consumer_contract
|
31
|
-
if pactfile_write_mode == :update
|
32
|
-
merged_interactions = existing_interactions
|
33
|
-
filter = Consumer::UpdatableInteractionsFilter.new(merged_interactions)
|
34
|
-
interactions.each {|i| filter << i }
|
35
|
-
merged_interactions
|
36
|
-
else
|
37
|
-
interactions
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def existing_interactions
|
42
|
-
interactions = []
|
43
|
-
if pactfile_exists?
|
44
|
-
begin
|
45
|
-
interactions = existing_consumer_contract.interactions
|
46
|
-
info_and_puts "*****************************************************************************"
|
47
|
-
info_and_puts "Updating existing file .#{pactfile_path.gsub(Dir.pwd, '')} as config.pactfile_write_mode is :update"
|
48
|
-
info_and_puts "Only interactions defined in this test run will be updated."
|
49
|
-
info_and_puts "As interactions are identified by description and provider state, pleased note that if either of these have changed, the old interactions won't be removed from the pact file until the specs are next run with :pactfile_write_mode => :overwrite."
|
50
|
-
info_and_puts "*****************************************************************************"
|
51
|
-
rescue StandardError => e
|
52
|
-
warn_and_stderr "Could not load existing consumer contract from #{pactfile_path} due to #{e}"
|
53
|
-
logger.error e
|
54
|
-
logger.error e.backtrace
|
55
|
-
warn_and_stderr "Creating a new file."
|
56
|
-
end
|
57
|
-
end
|
58
|
-
interactions
|
59
|
-
end
|
60
|
-
|
61
|
-
def pactfile_exists?
|
62
|
-
File.exist?(pactfile_path)
|
63
|
-
end
|
64
|
-
|
65
|
-
def pactfile_path
|
66
|
-
Pact::FileName.file_path consumer_contract_details[:consumer][:name], consumer_contract_details[:provider][:name]
|
67
|
-
end
|
68
|
-
|
69
|
-
def existing_consumer_contract
|
70
|
-
Pact::ConsumerContract.from_uri(pactfile_path)
|
71
|
-
end
|
72
|
-
|
73
|
-
def warn_and_stderr msg
|
74
|
-
Pact.configuration.error_stream.puts msg
|
75
|
-
logger.warn msg
|
76
|
-
end
|
77
|
-
|
78
|
-
def info_and_puts msg
|
79
|
-
$stdout.puts msg
|
80
|
-
logger.info msg
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
module Pact
|
2
|
-
|
3
|
-
module FileName
|
4
|
-
|
5
|
-
extend self
|
6
|
-
|
7
|
-
def file_name consumer_name, provider_name
|
8
|
-
"#{filenamify(consumer_name)}-#{filenamify(provider_name)}.json"
|
9
|
-
end
|
10
|
-
|
11
|
-
def file_path consumer_name, provider_name, pact_dir = Pact.configuration.pact_dir
|
12
|
-
File.join(pact_dir, file_name(consumer_name, provider_name))
|
13
|
-
end
|
14
|
-
|
15
|
-
def filenamify name
|
16
|
-
name.downcase.gsub(/\s/, '_')
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
@@ -1,51 +0,0 @@
|
|
1
|
-
module Pact
|
2
|
-
|
3
|
-
class DuplicateHeaderError < StandardError; end
|
4
|
-
class InvalidHeaderNameTypeError < StandardError; end
|
5
|
-
|
6
|
-
class Headers < Hash
|
7
|
-
|
8
|
-
def initialize hash = {}
|
9
|
-
hash.each_pair do | key, value |
|
10
|
-
check_for_invalid key
|
11
|
-
self[find_matching_key(key)] = value
|
12
|
-
end
|
13
|
-
self.freeze
|
14
|
-
end
|
15
|
-
|
16
|
-
def [] key
|
17
|
-
super(find_matching_key(key))
|
18
|
-
end
|
19
|
-
|
20
|
-
def fetch *args, &block
|
21
|
-
args[0] = find_matching_key(args[0]) if args.first
|
22
|
-
super(*args, &block)
|
23
|
-
end
|
24
|
-
|
25
|
-
def key? key
|
26
|
-
super(find_matching_key(key))
|
27
|
-
end
|
28
|
-
|
29
|
-
alias_method :has_key?, :key?
|
30
|
-
alias_method :include?, :key?
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
def find_matching_key key
|
35
|
-
key = key.to_s
|
36
|
-
match = keys.find { |k| k.downcase == key.downcase }
|
37
|
-
match.nil? ? key : match
|
38
|
-
end
|
39
|
-
|
40
|
-
def check_for_invalid key
|
41
|
-
unless (String === key || Symbol === key)
|
42
|
-
raise InvalidHeaderNameTypeError.new "Header name (#{key}) must be a String or a Symbol."
|
43
|
-
end
|
44
|
-
if key? key
|
45
|
-
raise DuplicateHeaderError.new "Duplicate header found (#{find_matching_key(key)} and #{key}. Please use a comma separated single value when multiple headers with the same name are required."
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
end
|
50
|
-
|
51
|
-
end
|
@@ -1,67 +0,0 @@
|
|
1
|
-
require 'pact/consumer_contract/request'
|
2
|
-
require 'pact/symbolize_keys'
|
3
|
-
require 'pact/shared/active_support_support'
|
4
|
-
|
5
|
-
module Pact
|
6
|
-
class Interaction
|
7
|
-
include ActiveSupportSupport
|
8
|
-
include SymbolizeKeys
|
9
|
-
|
10
|
-
attr_accessor :description, :request, :response, :provider_state
|
11
|
-
|
12
|
-
def initialize attributes = {}
|
13
|
-
@description = attributes[:description]
|
14
|
-
@request = attributes[:request]
|
15
|
-
@response = attributes[:response]
|
16
|
-
@provider_state = attributes[:provider_state] || attributes[:providerState]
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.from_hash hash
|
20
|
-
request = Pact::Request::Expected.from_hash(hash['request'])
|
21
|
-
new(symbolize_keys(hash).merge({request: request}))
|
22
|
-
end
|
23
|
-
|
24
|
-
def to_hash
|
25
|
-
hash = { :description => @description }
|
26
|
-
hash[:provider_state] = @provider_state if @provider_state #Easier to read when provider state at top
|
27
|
-
hash.merge(:request => @request.as_json, :response => @response)
|
28
|
-
end
|
29
|
-
|
30
|
-
def as_json options = {}
|
31
|
-
fix_all_the_things to_hash
|
32
|
-
end
|
33
|
-
|
34
|
-
def to_json(options = {})
|
35
|
-
as_json.to_json(options)
|
36
|
-
end
|
37
|
-
|
38
|
-
def matches_criteria? criteria
|
39
|
-
criteria.each do | key, value |
|
40
|
-
unless match_criterion self.send(key.to_s), value
|
41
|
-
return false
|
42
|
-
end
|
43
|
-
end
|
44
|
-
true
|
45
|
-
end
|
46
|
-
|
47
|
-
def match_criterion target, criterion
|
48
|
-
target == criterion || (criterion.is_a?(Regexp) && criterion.match(target))
|
49
|
-
end
|
50
|
-
|
51
|
-
def == other
|
52
|
-
other.is_a?(Interaction) && as_json == other.as_json
|
53
|
-
end
|
54
|
-
|
55
|
-
def eq? other
|
56
|
-
self == other
|
57
|
-
end
|
58
|
-
|
59
|
-
def description_with_provider_state_quoted
|
60
|
-
provider_state ? "\"#{description}\" given \"#{provider_state}\"" : "\"#{description}\""
|
61
|
-
end
|
62
|
-
|
63
|
-
def to_s
|
64
|
-
JSON.pretty_generate(self)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|