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,31 +0,0 @@
|
|
1
|
-
require 'pact/consumer/mock_service/mock_service_administration_endpoint'
|
2
|
-
|
3
|
-
module Pact
|
4
|
-
module Consumer
|
5
|
-
class InteractionPost < MockServiceAdministrationEndpoint
|
6
|
-
|
7
|
-
attr_accessor :interaction_list
|
8
|
-
|
9
|
-
def initialize name, logger, interaction_list
|
10
|
-
super name, logger
|
11
|
-
@interaction_list = interaction_list
|
12
|
-
end
|
13
|
-
|
14
|
-
def request_path
|
15
|
-
'/interactions'
|
16
|
-
end
|
17
|
-
|
18
|
-
def request_method
|
19
|
-
'POST'
|
20
|
-
end
|
21
|
-
|
22
|
-
def respond env
|
23
|
-
interaction = Interaction.from_hash(JSON.load(env['rack.input'].string))
|
24
|
-
interaction_list.add interaction
|
25
|
-
logger.info "Registered expected interaction #{interaction.request.method_and_path}"
|
26
|
-
logger.debug JSON.pretty_generate JSON.parse(interaction.to_json)
|
27
|
-
[200, {}, ['Added interaction']]
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,139 +0,0 @@
|
|
1
|
-
require 'pact/matchers'
|
2
|
-
require 'pact/consumer/mock_service/rack_request_helper'
|
3
|
-
require 'pact/consumer/mock_service/interaction_mismatch'
|
4
|
-
require 'pact/consumer_contract'
|
5
|
-
require 'pact/consumer/interactions_filter'
|
6
|
-
|
7
|
-
module Pact
|
8
|
-
module Consumer
|
9
|
-
|
10
|
-
class InteractionReplay
|
11
|
-
include Pact::Matchers
|
12
|
-
include RackRequestHelper
|
13
|
-
|
14
|
-
attr_accessor :name, :logger, :interaction_list, :interactions
|
15
|
-
|
16
|
-
def initialize name, logger, interaction_list, interactions
|
17
|
-
@name = name
|
18
|
-
@logger = logger
|
19
|
-
@interaction_list = interaction_list
|
20
|
-
@interactions = DistinctInteractionsFilter.new(interactions)
|
21
|
-
end
|
22
|
-
|
23
|
-
def match? env
|
24
|
-
true # default handler
|
25
|
-
end
|
26
|
-
|
27
|
-
def respond env
|
28
|
-
find_response request_as_hash_from(env)
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
33
|
-
def add_verified_interaction interaction
|
34
|
-
interactions << interaction
|
35
|
-
end
|
36
|
-
|
37
|
-
def find_response request_hash
|
38
|
-
actual_request = Request::Actual.from_hash(request_hash)
|
39
|
-
logger.info "Received request #{actual_request.method_and_path}"
|
40
|
-
logger.debug pretty_generate actual_request
|
41
|
-
candidate_interactions = interaction_list.find_candidate_interactions actual_request
|
42
|
-
matching_interactions = find_matching_interactions actual_request, from: candidate_interactions
|
43
|
-
|
44
|
-
case matching_interactions.size
|
45
|
-
when 0 then handle_unrecognised_request actual_request, candidate_interactions
|
46
|
-
when 1 then handle_matched_interaction matching_interactions.first
|
47
|
-
else
|
48
|
-
handle_more_than_one_matching_interaction actual_request, matching_interactions
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def find_matching_interactions actual_request, opts
|
53
|
-
candidate_interactions = opts.fetch(:from)
|
54
|
-
candidate_interactions.select do | candidate_interaction |
|
55
|
-
candidate_interaction.request.matches? actual_request
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def handle_matched_interaction interaction
|
60
|
-
interaction_list.register_matched interaction
|
61
|
-
add_verified_interaction interaction
|
62
|
-
response = response_from(interaction.response)
|
63
|
-
logger.info "Found matching response for #{interaction.request.method_and_path}"
|
64
|
-
logger.debug pretty_generate(interaction.response)
|
65
|
-
response
|
66
|
-
end
|
67
|
-
|
68
|
-
def multiple_interactions_found_response actual_request, matching_interactions
|
69
|
-
response = {
|
70
|
-
message: "Multiple interaction found for #{actual_request.method_and_path}",
|
71
|
-
matching_interactions: matching_interactions.collect{ | interaction | request_summary_for(interaction) }
|
72
|
-
}
|
73
|
-
[500, {'Content-Type' => 'application/json'}, [response.to_json]]
|
74
|
-
end
|
75
|
-
|
76
|
-
def handle_more_than_one_matching_interaction actual_request, matching_interactions
|
77
|
-
logger.error "Multiple interactions found for #{actual_request.method_and_path}:"
|
78
|
-
matching_interactions.each do | interaction |
|
79
|
-
logger.debug pretty_generate(interaction)
|
80
|
-
end
|
81
|
-
multiple_interactions_found_response actual_request, matching_interactions
|
82
|
-
end
|
83
|
-
|
84
|
-
def interaction_mismatch actual_request, candidate_interactions
|
85
|
-
InteractionMismatch.new(candidate_interactions, actual_request)
|
86
|
-
end
|
87
|
-
|
88
|
-
def request_summary_for interaction
|
89
|
-
summary = {:description => interaction.description}
|
90
|
-
summary[:provider_state] if interaction.provider_state
|
91
|
-
summary[:request] = interaction.request
|
92
|
-
summary
|
93
|
-
end
|
94
|
-
|
95
|
-
def unrecognised_request_response interaction_mismatch
|
96
|
-
response = {
|
97
|
-
message: "No interaction found for #{interaction_mismatch.actual_request.method_and_path}",
|
98
|
-
interaction_diffs: interaction_mismatch.to_hash
|
99
|
-
}
|
100
|
-
[500, {'Content-Type' => 'application/json'}, [response.to_json]]
|
101
|
-
end
|
102
|
-
|
103
|
-
def log_unrecognised_request_and_interaction_diff interaction_mismatch
|
104
|
-
logger.error "No matching interaction found on #{name} for #{interaction_mismatch.actual_request.method_and_path}"
|
105
|
-
logger.error 'Interaction diffs for that route:'
|
106
|
-
logger.error(interaction_mismatch.to_s)
|
107
|
-
end
|
108
|
-
|
109
|
-
def handle_unrecognised_request actual_request, candidate_interactions
|
110
|
-
interaction_mismatch = interaction_mismatch(actual_request, candidate_interactions)
|
111
|
-
if candidate_interactions.any?
|
112
|
-
interaction_list.register_interaction_mismatch interaction_mismatch
|
113
|
-
else
|
114
|
-
interaction_list.register_unexpected_request actual_request
|
115
|
-
end
|
116
|
-
log_unrecognised_request_and_interaction_diff interaction_mismatch
|
117
|
-
unrecognised_request_response interaction_mismatch
|
118
|
-
end
|
119
|
-
|
120
|
-
def response_from response
|
121
|
-
[response['status'], (response['headers'] || {}).to_hash, [render_body(Pact::Reification.from_term(response['body']))]]
|
122
|
-
end
|
123
|
-
|
124
|
-
def render_body body
|
125
|
-
return '' unless body
|
126
|
-
body.kind_of?(String) ? body.force_encoding('utf-8') : body.to_json
|
127
|
-
end
|
128
|
-
|
129
|
-
def logger_info_ap msg
|
130
|
-
logger.info msg
|
131
|
-
end
|
132
|
-
|
133
|
-
#Doesn't seem to reliably pretty generate unless we go to JSON and back again :(
|
134
|
-
def pretty_generate object
|
135
|
-
JSON.pretty_generate(JSON.parse(object.to_json))
|
136
|
-
end
|
137
|
-
end
|
138
|
-
end
|
139
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
require 'pact/consumer/mock_service/mock_service_administration_endpoint'
|
2
|
-
|
3
|
-
module Pact
|
4
|
-
module Consumer
|
5
|
-
class LogGet < MockServiceAdministrationEndpoint
|
6
|
-
|
7
|
-
include RackRequestHelper
|
8
|
-
|
9
|
-
def request_path
|
10
|
-
'/log'
|
11
|
-
end
|
12
|
-
|
13
|
-
def request_method
|
14
|
-
'GET'
|
15
|
-
end
|
16
|
-
|
17
|
-
|
18
|
-
def respond env
|
19
|
-
logger.info "Debug message from client - #{message(env)}"
|
20
|
-
[200, {}, []]
|
21
|
-
end
|
22
|
-
|
23
|
-
def message env
|
24
|
-
params_hash(env)['msg']
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
require 'pact/consumer/mock_service/mock_service_administration_endpoint'
|
2
|
-
|
3
|
-
module Pact
|
4
|
-
module Consumer
|
5
|
-
|
6
|
-
class MissingInteractionsGet < MockServiceAdministrationEndpoint
|
7
|
-
include RackRequestHelper
|
8
|
-
|
9
|
-
def initialize name, logger, interaction_list
|
10
|
-
super name, logger
|
11
|
-
@interaction_list = interaction_list
|
12
|
-
end
|
13
|
-
|
14
|
-
def request_path
|
15
|
-
'/interactions/missing'
|
16
|
-
end
|
17
|
-
|
18
|
-
def request_method
|
19
|
-
'GET'
|
20
|
-
end
|
21
|
-
|
22
|
-
def respond env
|
23
|
-
number_of_missing_interactions = @interaction_list.missing_interactions.size
|
24
|
-
logger.info "Number of missing interactions for mock \"#{name}\" = #{number_of_missing_interactions}"
|
25
|
-
[200, {}, [{size: number_of_missing_interactions}.to_json]]
|
26
|
-
end
|
27
|
-
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
require 'pact/consumer/mock_service/rack_request_helper'
|
2
|
-
module Pact
|
3
|
-
module Consumer
|
4
|
-
class MockServiceAdministrationEndpoint
|
5
|
-
|
6
|
-
attr_accessor :logger, :name
|
7
|
-
|
8
|
-
def initialize name, logger
|
9
|
-
@name = name
|
10
|
-
@logger = logger
|
11
|
-
end
|
12
|
-
|
13
|
-
include RackRequestHelper
|
14
|
-
|
15
|
-
def match? env
|
16
|
-
headers_from(env)['X-Pact-Mock-Service'] &&
|
17
|
-
env['REQUEST_PATH'] == request_path &&
|
18
|
-
env['REQUEST_METHOD'] == request_method
|
19
|
-
end
|
20
|
-
|
21
|
-
def request_path
|
22
|
-
raise NotImplementedError
|
23
|
-
end
|
24
|
-
|
25
|
-
def request_method
|
26
|
-
raise NotImplementedError
|
27
|
-
end
|
28
|
-
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
require 'pact/consumer/mock_service/mock_service_administration_endpoint'
|
2
|
-
require 'pact/consumer_contract/consumer_contract_writer'
|
3
|
-
|
4
|
-
module Pact
|
5
|
-
module Consumer
|
6
|
-
class PactPost < MockServiceAdministrationEndpoint
|
7
|
-
|
8
|
-
attr_accessor :consumer_contract, :interactions
|
9
|
-
|
10
|
-
def initialize name, logger, interactions
|
11
|
-
super name, logger
|
12
|
-
@interactions = interactions
|
13
|
-
end
|
14
|
-
|
15
|
-
def request_path
|
16
|
-
'/pact'
|
17
|
-
end
|
18
|
-
|
19
|
-
def request_method
|
20
|
-
'POST'
|
21
|
-
end
|
22
|
-
|
23
|
-
def respond env
|
24
|
-
consumer_contract_details = JSON.parse(env['rack.input'].string, symbolize_names: true)
|
25
|
-
logger.info "Writing pact with details #{consumer_contract_details}"
|
26
|
-
consumer_contract_writer = ConsumerContractWriter.new(consumer_contract_details.merge(interactions: interactions), logger)
|
27
|
-
json = consumer_contract_writer.write
|
28
|
-
|
29
|
-
[200, {'Content-Type' =>'application/json'}, [json]]
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
@@ -1,51 +0,0 @@
|
|
1
|
-
module Pact
|
2
|
-
module Consumer
|
3
|
-
|
4
|
-
module RackRequestHelper
|
5
|
-
REQUEST_KEYS = {
|
6
|
-
'REQUEST_METHOD' => :method,
|
7
|
-
'PATH_INFO' => :path,
|
8
|
-
'QUERY_STRING' => :query,
|
9
|
-
'rack.input' => :body
|
10
|
-
}
|
11
|
-
|
12
|
-
def params_hash env
|
13
|
-
env["QUERY_STRING"].split("&").collect{| param| param.split("=")}.inject({}){|params, param| params[param.first] = URI.decode(param.last); params }
|
14
|
-
end
|
15
|
-
|
16
|
-
def request_as_hash_from env
|
17
|
-
request = env.inject({}) do |memo, (k, v)|
|
18
|
-
request_key = REQUEST_KEYS[k]
|
19
|
-
memo[request_key] = v if request_key
|
20
|
-
memo
|
21
|
-
end
|
22
|
-
|
23
|
-
request[:headers] = headers_from env
|
24
|
-
body_string = request[:body].read
|
25
|
-
|
26
|
-
if body_string.empty?
|
27
|
-
request.delete :body
|
28
|
-
else
|
29
|
-
body_is_json = request[:headers]['Content-Type'] =~ /json/
|
30
|
-
request[:body] = body_is_json ? JSON.parse(body_string) : body_string
|
31
|
-
end
|
32
|
-
request[:method] = request[:method].downcase
|
33
|
-
request
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
def headers_from env
|
39
|
-
headers = env.reject{ |key, value| !(key.start_with?("HTTP") || key == 'CONTENT_TYPE' || key == 'CONTENT_LENGTH')}
|
40
|
-
headers.inject({}) do | hash, header |
|
41
|
-
hash[standardise_header(header.first)] = header.last
|
42
|
-
hash
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def standardise_header header
|
47
|
-
header.gsub(/^HTTP_/, '').split("_").collect{|word| word[0] + word[1..-1].downcase}.join("-")
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
@@ -1,68 +0,0 @@
|
|
1
|
-
require 'pact/consumer/mock_service/mock_service_administration_endpoint'
|
2
|
-
|
3
|
-
module Pact
|
4
|
-
module Consumer
|
5
|
-
class VerificationGet < MockServiceAdministrationEndpoint
|
6
|
-
|
7
|
-
include RackRequestHelper
|
8
|
-
attr_accessor :interaction_list, :log_description
|
9
|
-
|
10
|
-
def initialize name, logger, interaction_list, log_description
|
11
|
-
super name, logger
|
12
|
-
@interaction_list = interaction_list
|
13
|
-
@log_description = log_description
|
14
|
-
end
|
15
|
-
|
16
|
-
def request_path
|
17
|
-
'/interactions/verification'
|
18
|
-
end
|
19
|
-
|
20
|
-
def request_method
|
21
|
-
'GET'
|
22
|
-
end
|
23
|
-
|
24
|
-
def respond env
|
25
|
-
if interaction_list.all_matched?
|
26
|
-
logger.info "Verifying - interactions matched for example \"#{example_description(env)}\""
|
27
|
-
[200, {'Content-Type' => 'text/plain'}, ['Interactions matched']]
|
28
|
-
else
|
29
|
-
error_message = FailureMessage.new(interaction_list).to_s
|
30
|
-
logger.warn "Verifying - actual interactions do not match expected interactions for example \"#{example_description(env)}\". \n#{error_message}"
|
31
|
-
logger.warn error_message
|
32
|
-
[500, {'Content-Type' => 'text/plain'}, ["Actual interactions do not match expected interactions for mock #{name}.\n\n#{error_message}See #{log_description} for details."]]
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def example_description env
|
37
|
-
params_hash(env)['example_description']
|
38
|
-
end
|
39
|
-
|
40
|
-
class FailureMessage
|
41
|
-
|
42
|
-
def initialize interaction_list
|
43
|
-
@interaction_list = interaction_list
|
44
|
-
end
|
45
|
-
|
46
|
-
def to_s
|
47
|
-
titles_and_summaries.collect do | title, summaries |
|
48
|
-
"#{title}:\n\t#{summaries.join("\n\t")}\n\n" if summaries.any?
|
49
|
-
end.compact.join
|
50
|
-
|
51
|
-
end
|
52
|
-
|
53
|
-
private
|
54
|
-
|
55
|
-
attr_reader :interaction_list
|
56
|
-
|
57
|
-
def titles_and_summaries
|
58
|
-
{
|
59
|
-
"Incorrect requests" => interaction_list.interaction_mismatches_summaries,
|
60
|
-
"Missing requests" => interaction_list.missing_interactions_summaries,
|
61
|
-
"Unexpected requests" => interaction_list.unexpected_requests_summaries,
|
62
|
-
}
|
63
|
-
end
|
64
|
-
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
@@ -1,65 +0,0 @@
|
|
1
|
-
require 'net/http'
|
2
|
-
require 'pact/consumer/mock_service_interaction_expectation'
|
3
|
-
|
4
|
-
module Pact
|
5
|
-
module Consumer
|
6
|
-
class MockServiceClient
|
7
|
-
|
8
|
-
MOCK_SERVICE_ADMINISTRATON_HEADERS = {'X-Pact-Mock-Service' => 'true'}
|
9
|
-
|
10
|
-
def initialize port
|
11
|
-
@http = Net::HTTP.new('localhost', port)
|
12
|
-
end
|
13
|
-
|
14
|
-
def verify example_description
|
15
|
-
response = http.request_get("/interactions/verification?example_description=#{URI.encode(example_description)}", MOCK_SERVICE_ADMINISTRATON_HEADERS)
|
16
|
-
raise "\e[31m#{response.body}\e[m" unless response.is_a? Net::HTTPSuccess
|
17
|
-
end
|
18
|
-
|
19
|
-
def log msg
|
20
|
-
http.request_get("/log?msg=#{URI.encode(msg)}", MOCK_SERVICE_ADMINISTRATON_HEADERS)
|
21
|
-
end
|
22
|
-
|
23
|
-
def wait_for_interactions wait_max_seconds, poll_interval
|
24
|
-
wait_until_true(wait_max_seconds, poll_interval) do
|
25
|
-
response = http.request_get("/interactions/missing", MOCK_SERVICE_ADMINISTRATON_HEADERS)
|
26
|
-
JSON.parse(response.body)['size'] == 0
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def clear_interactions example_description
|
31
|
-
http.delete("/interactions?example_description=#{URI.encode(example_description)}", MOCK_SERVICE_ADMINISTRATON_HEADERS)
|
32
|
-
end
|
33
|
-
|
34
|
-
def add_expected_interaction interaction
|
35
|
-
response = http.request_post('/interactions', MockServiceInteractionExpectation.new(interaction).to_json, MOCK_SERVICE_ADMINISTRATON_HEADERS.merge("Content-Type" => "application/json"))
|
36
|
-
raise "\e[31m#{response.body}\e[m" unless response.is_a? Net::HTTPSuccess
|
37
|
-
end
|
38
|
-
|
39
|
-
def self.clear_interactions port, example_description
|
40
|
-
Net::HTTP.new("localhost", port).delete("/interactions?example_description=#{URI.encode(example_description)}", MOCK_SERVICE_ADMINISTRATON_HEADERS)
|
41
|
-
end
|
42
|
-
|
43
|
-
def write_pact pacticipant_details
|
44
|
-
response = http.request_post("/pact", pacticipant_details.to_json, MOCK_SERVICE_ADMINISTRATON_HEADERS.merge("Content-Type" => "application/json"))
|
45
|
-
raise "\e[31m#{response.body}\e[m" unless response.is_a? Net::HTTPSuccess
|
46
|
-
response.body
|
47
|
-
end
|
48
|
-
|
49
|
-
private
|
50
|
-
|
51
|
-
attr_reader :http
|
52
|
-
|
53
|
-
#todo: in need a better home (where can we move it?)
|
54
|
-
def wait_until_true timeout=3, interval=0.1
|
55
|
-
time_limit = Time.now + timeout
|
56
|
-
loop do
|
57
|
-
result = yield
|
58
|
-
return if result || Time.now >= time_limit
|
59
|
-
sleep interval
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|