pact 0.1.28 → 1.3.3
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/.gitignore +2 -1
- data/.ruby-version +1 -0
- data/.travis.yml +8 -0
- data/CHANGELOG.md +374 -0
- data/Gemfile +0 -1
- data/Gemfile.lock +58 -55
- data/README.md +214 -139
- data/Rakefile +4 -28
- data/bin/pact +2 -2
- data/config.ru +3 -0
- data/documentation/README.md +13 -0
- data/documentation/configuration.md +166 -0
- data/documentation/diff_formatter_embedded.png +0 -0
- data/documentation/diff_formatter_list.png +0 -0
- data/documentation/diff_formatter_unix.png +0 -0
- data/example/animal-service/Gemfile +14 -0
- data/example/animal-service/Gemfile.lock +69 -0
- data/example/animal-service/Rakefile +5 -0
- data/example/animal-service/config.ru +3 -0
- data/example/animal-service/db/animal_db.sqlite3 +0 -0
- data/example/animal-service/lib/animal_service/animal_repository.rb +12 -0
- data/example/animal-service/lib/animal_service/api.rb +28 -0
- data/example/animal-service/lib/animal_service/db.rb +5 -0
- data/example/animal-service/spec/service_consumers/pact_helper.rb +11 -0
- data/example/animal-service/spec/service_consumers/provider_states_for_zoo_app.rb +26 -0
- data/example/zoo-app/Gemfile +12 -0
- data/example/zoo-app/Gemfile.lock +63 -0
- data/example/zoo-app/Rakefile +5 -0
- data/example/zoo-app/doc/pacts/markdown/README.md +3 -0
- data/example/zoo-app/doc/pacts/markdown/Zoo App - Animal Service.md +75 -0
- data/example/zoo-app/lib/zoo_app/animal_service_client.rb +40 -0
- data/example/zoo-app/lib/zoo_app/models/alligator.rb +15 -0
- data/example/zoo-app/spec/pacts/zoo_app-animal_service.json +67 -0
- data/example/zoo-app/spec/service_providers/animal_service_client_spec.rb +71 -0
- data/example/zoo-app/spec/service_providers/pact_helper.rb +15 -0
- data/example/zoo-app/spec/spec_helper.rb +6 -0
- data/lib/pact/cli.rb +138 -0
- data/lib/pact/configuration.rb +169 -28
- data/lib/pact/consumer/app_manager.rb +10 -29
- data/lib/pact/consumer/configuration/configuration_extensions.rb +15 -0
- data/lib/pact/consumer/configuration/dsl.rb +12 -0
- data/lib/pact/consumer/configuration/mock_service.rb +91 -0
- data/lib/pact/consumer/configuration/service_consumer.rb +51 -0
- data/lib/pact/consumer/configuration/service_provider.rb +40 -0
- data/lib/pact/consumer/configuration.rb +11 -0
- data/lib/pact/consumer/consumer_contract_builder.rb +44 -47
- data/lib/pact/consumer/interaction_builder.rb +41 -0
- data/lib/pact/consumer/interactions_filter.rb +48 -0
- data/lib/pact/consumer/mock_service/app.rb +82 -0
- data/lib/pact/consumer/mock_service/interaction_delete.rb +33 -0
- data/lib/pact/consumer/mock_service/interaction_list.rb +76 -0
- data/lib/pact/consumer/mock_service/interaction_mismatch.rb +73 -0
- data/lib/pact/consumer/mock_service/interaction_post.rb +31 -0
- data/lib/pact/consumer/mock_service/interaction_replay.rb +139 -0
- data/lib/pact/consumer/mock_service/log_get.rb +28 -0
- data/lib/pact/consumer/mock_service/missing_interactions_get.rb +30 -0
- data/lib/pact/consumer/mock_service/mock_service_administration_endpoint.rb +31 -0
- data/lib/pact/consumer/mock_service/pact_post.rb +33 -0
- data/lib/pact/consumer/mock_service/rack_request_helper.rb +51 -0
- data/lib/pact/consumer/mock_service/verification_get.rb +68 -0
- data/lib/pact/consumer/mock_service.rb +1 -339
- data/lib/pact/consumer/mock_service_client.rb +65 -0
- data/lib/pact/consumer/mock_service_interaction_expectation.rb +37 -0
- data/lib/pact/consumer/request.rb +27 -0
- data/lib/pact/consumer/rspec.rb +9 -19
- data/lib/pact/consumer/server.rb +90 -0
- data/lib/pact/consumer/spec_hooks.rb +38 -0
- data/lib/pact/consumer/world.rb +37 -0
- data/lib/pact/consumer.rb +10 -7
- data/lib/pact/consumer_contract/consumer_contract.rb +115 -0
- data/lib/pact/consumer_contract/consumer_contract_writer.rb +84 -0
- data/lib/pact/consumer_contract/file_name.rb +19 -0
- data/lib/pact/consumer_contract/headers.rb +51 -0
- data/lib/pact/consumer_contract/interaction.rb +67 -0
- data/lib/pact/consumer_contract/pact_file.rb +24 -0
- data/lib/pact/consumer_contract/request.rb +73 -0
- data/lib/pact/consumer_contract/service_consumer.rb +28 -0
- data/lib/pact/consumer_contract/service_provider.rb +28 -0
- data/lib/pact/consumer_contract.rb +1 -110
- data/lib/pact/doc/doc_file.rb +40 -0
- data/lib/pact/doc/generate.rb +11 -0
- data/lib/pact/doc/generator.rb +82 -0
- data/lib/pact/doc/interaction_view_model.rb +114 -0
- data/lib/pact/doc/markdown/consumer_contract_renderer.rb +56 -0
- data/lib/pact/doc/markdown/generator.rb +26 -0
- data/lib/pact/doc/markdown/index_renderer.rb +41 -0
- data/lib/pact/doc/markdown/interaction.erb +14 -0
- data/lib/pact/doc/markdown/interaction_renderer.rb +38 -0
- data/lib/pact/doc/sort_interactions.rb +17 -0
- data/lib/pact/matchers/actual_type.rb +16 -0
- data/lib/pact/matchers/base_difference.rb +37 -0
- data/lib/pact/matchers/differ.rb +153 -0
- data/lib/pact/matchers/difference.rb +13 -0
- data/lib/pact/matchers/difference_indicator.rb +26 -0
- data/lib/pact/matchers/embedded_diff_formatter.rb +62 -0
- data/lib/pact/matchers/expected_type.rb +35 -0
- data/lib/pact/matchers/index_not_found.rb +15 -0
- data/lib/pact/matchers/list_diff_formatter.rb +101 -0
- data/lib/pact/matchers/matchers.rb +91 -37
- data/lib/pact/matchers/no_diff_indicator.rb +18 -0
- data/lib/pact/matchers/regexp_difference.rb +13 -0
- data/lib/pact/matchers/type_difference.rb +16 -0
- data/lib/pact/matchers/unexpected_index.rb +11 -0
- data/lib/pact/matchers/unexpected_key.rb +11 -0
- data/lib/pact/matchers/unix_diff_formatter.rb +114 -0
- data/lib/pact/project_root.rb +7 -0
- data/lib/pact/provider/configuration/configuration_extension.rb +58 -0
- data/lib/pact/provider/configuration/dsl.rb +13 -0
- data/lib/pact/provider/configuration/pact_verification.rb +46 -0
- data/lib/pact/provider/configuration/service_provider_config.rb +16 -0
- data/lib/pact/provider/configuration/service_provider_dsl.rb +59 -0
- data/lib/pact/provider/configuration.rb +7 -0
- data/lib/pact/provider/context.rb +0 -0
- data/lib/pact/provider/matchers/messages.rb +45 -0
- data/lib/pact/provider/pact_helper_locator.rb +22 -0
- data/lib/pact/provider/pact_spec_runner.rb +123 -0
- data/lib/pact/provider/pact_verification.rb +17 -0
- data/lib/pact/provider/print_missing_provider_states.rb +30 -0
- data/lib/pact/provider/request.rb +70 -0
- data/lib/pact/provider/rspec/backtrace_formatter.rb +43 -0
- data/lib/pact/provider/rspec/custom_options_file +0 -0
- data/lib/pact/provider/rspec/formatter_rspec_2.rb +65 -0
- data/lib/pact/provider/rspec/formatter_rspec_3.rb +96 -0
- data/lib/pact/provider/rspec/matchers.rb +97 -0
- data/lib/pact/provider/rspec.rb +181 -0
- data/lib/pact/provider/state/provider_state.rb +181 -0
- data/lib/pact/provider/state/provider_state_configured_modules.rb +13 -0
- data/lib/pact/provider/state/provider_state_manager.rb +42 -0
- data/lib/pact/provider/state/provider_state_proxy.rb +39 -0
- data/lib/pact/provider/test_methods.rb +47 -0
- data/lib/pact/provider/verification_report.rb +36 -0
- data/lib/pact/provider/world.rb +23 -0
- data/lib/pact/provider.rb +3 -0
- data/lib/pact/reification.rb +6 -4
- data/lib/pact/rspec.rb +53 -0
- data/lib/pact/shared/active_support_support.rb +51 -0
- data/lib/pact/shared/dsl.rb +76 -0
- data/lib/pact/shared/jruby_support.rb +18 -0
- data/lib/pact/shared/json_differ.rb +15 -0
- data/lib/pact/shared/key_not_found.rb +15 -0
- data/lib/pact/shared/null_expectation.rb +31 -0
- data/lib/pact/shared/request.rb +80 -0
- data/lib/pact/shared/text_differ.rb +14 -0
- data/lib/pact/something_like.rb +49 -0
- data/lib/pact/symbolize_keys.rb +12 -0
- data/lib/pact/tasks/task_helper.rb +36 -0
- data/lib/pact/tasks/verification_task.rb +87 -0
- data/lib/pact/tasks.rb +2 -0
- data/lib/pact/templates/provider_state.erb +14 -0
- data/lib/pact/term.rb +47 -2
- data/lib/pact/version.rb +1 -1
- data/lib/pact.rb +1 -1
- data/lib/tasks/pact.rake +25 -2
- data/pact.gemspec +13 -11
- data/{scratchpad.txt → scratchpad.rb} +18 -2
- data/spec/features/consumption_spec.rb +24 -56
- data/spec/features/production_spec.rb +19 -24
- data/spec/features/{producer_states → provider_states}/zebras.rb +3 -3
- data/spec/integration/consumer_spec.rb +212 -0
- data/spec/integration/pact/consumer_configuration_spec.rb +66 -0
- data/spec/integration/pact/provider_configuration_spec.rb +25 -0
- data/spec/lib/pact/cli_spec.rb +47 -0
- data/spec/lib/pact/configuration_spec.rb +269 -7
- data/spec/lib/pact/consumer/app_manager_spec.rb +3 -3
- data/spec/lib/pact/consumer/configuration_spec.rb +57 -0
- data/spec/lib/pact/consumer/consumer_contract_builder_spec.rb +52 -70
- 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/app_spec.rb +52 -0
- data/spec/lib/pact/consumer/mock_service/interaction_list_spec.rb +78 -0
- data/spec/lib/pact/consumer/mock_service/interaction_mismatch_spec.rb +70 -0
- data/spec/lib/pact/consumer/mock_service/interaction_replay_spec.rb +12 -0
- data/spec/lib/pact/consumer/mock_service/rack_request_helper_spec.rb +88 -0
- data/spec/lib/pact/consumer/mock_service/verification_get_spec.rb +142 -0
- data/spec/lib/pact/consumer/mock_service_client_spec.rb +88 -0
- data/spec/lib/pact/consumer/mock_service_interaction_expectation_spec.rb +54 -0
- data/spec/lib/pact/consumer/request_spec.rb +24 -0
- data/spec/lib/pact/consumer/service_consumer_spec.rb +1 -1
- data/spec/lib/pact/consumer_contract/active_support_support_spec.rb +58 -0
- data/spec/lib/pact/consumer_contract/consumer_contract_spec.rb +180 -0
- data/spec/lib/pact/consumer_contract/consumer_contract_writer_spec.rb +111 -0
- data/spec/lib/pact/consumer_contract/headers_spec.rb +107 -0
- data/spec/lib/pact/consumer_contract/interaction_spec.rb +107 -0
- data/spec/lib/pact/{request_spec.rb → consumer_contract/request_spec.rb} +80 -67
- data/spec/lib/pact/doc/generator_spec.rb +84 -0
- data/spec/lib/pact/doc/interaction_view_model_spec.rb +132 -0
- data/spec/lib/pact/doc/markdown/consumer_contract_renderer_spec.rb +29 -0
- data/spec/lib/pact/doc/markdown/index_renderer_spec.rb +29 -0
- data/spec/lib/pact/matchers/differ_spec.rb +214 -0
- data/spec/lib/pact/matchers/difference_spec.rb +22 -0
- data/spec/lib/pact/matchers/embedded_diff_formatter_spec.rb +90 -0
- data/spec/lib/pact/matchers/index_not_found_spec.rb +21 -0
- data/spec/lib/pact/matchers/list_diff_formatter_spec.rb +114 -0
- data/spec/lib/pact/matchers/matchers_spec.rb +400 -254
- data/spec/lib/pact/matchers/regexp_difference_spec.rb +20 -0
- data/spec/lib/pact/matchers/type_difference_spec.rb +34 -0
- data/spec/lib/pact/matchers/unexpected_index_spec.rb +20 -0
- data/spec/lib/pact/matchers/unexpected_key_spec.rb +20 -0
- data/spec/lib/pact/matchers/unix_diff_formatter_spec.rb +216 -0
- data/spec/lib/pact/provider/configuration/configuration_extension_spec.rb +30 -0
- data/spec/lib/pact/provider/configuration/pact_verification_spec.rb +43 -0
- data/spec/lib/pact/provider/configuration/service_provider_config_spec.rb +21 -0
- data/spec/lib/pact/provider/configuration/service_provider_dsl_spec.rb +108 -0
- data/spec/lib/pact/provider/configuration_spec.rb +50 -0
- data/spec/lib/pact/provider/matchers/messages_spec.rb +116 -0
- data/spec/lib/pact/provider/pact_helper_locator_spec.rb +54 -0
- data/spec/lib/pact/provider/print_missing_provider_states_spec.rb +19 -0
- data/spec/lib/pact/provider/request_spec.rb +78 -0
- data/spec/lib/pact/provider/rspec/formatter_rspec_2_spec.rb +68 -0
- data/spec/lib/pact/provider/rspec/formatter_rspec_3_spec.rb +72 -0
- data/spec/lib/pact/provider/rspec_spec.rb +55 -0
- data/spec/lib/pact/provider/state/provider_state_manager_spec.rb +89 -0
- data/spec/lib/pact/provider/state/provider_state_proxy_spec.rb +80 -0
- data/spec/lib/pact/provider/state/provider_state_spec.rb +213 -0
- data/spec/lib/pact/provider/world_spec.rb +41 -0
- data/spec/lib/pact/reification_spec.rb +24 -0
- data/spec/lib/pact/shared/dsl_spec.rb +86 -0
- data/spec/lib/pact/shared/json_differ_spec.rb +36 -0
- data/spec/lib/pact/shared/key_not_found_spec.rb +20 -0
- data/spec/lib/pact/shared/request_spec.rb +111 -0
- data/spec/lib/pact/shared/text_differ_spec.rb +54 -0
- data/spec/lib/pact/something_like_spec.rb +21 -0
- data/spec/lib/pact/tasks/task_helper_spec.rb +74 -0
- data/spec/lib/pact/tasks/verification_task_spec.rb +75 -0
- data/spec/lib/pact/term_spec.rb +57 -4
- data/spec/pact_specification/compliance-1.0.0.rb +47 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/standalone/consumer_fail_test.rb +55 -0
- data/spec/standalone/consumer_pass_test.rb +51 -0
- data/spec/support/a_consumer-a_producer.json +2 -4
- data/spec/support/a_consumer-a_provider.json +32 -0
- data/spec/support/active_support_if_configured.rb +6 -0
- data/spec/support/app_for_config_ru.rb +4 -0
- data/spec/support/consumer_contract_template.json +24 -0
- data/spec/support/dsl_spec_support.rb +7 -0
- data/spec/support/factories.rb +82 -0
- data/spec/support/generated_index.md +4 -0
- data/spec/support/generated_markdown.md +55 -0
- data/spec/support/interaction_view_model.json +63 -0
- data/spec/support/interaction_view_model_with_terms.json +50 -0
- data/spec/support/markdown_pact.json +48 -0
- data/spec/support/missing_provider_states_output.txt +25 -0
- data/spec/support/options.json +21 -0
- data/spec/support/options_app.rb +15 -0
- data/spec/support/pact_helper.rb +57 -0
- data/spec/support/shared_examples_for_request.rb +94 -0
- data/spec/support/spec_support.rb +20 -0
- data/spec/support/stubbing.json +22 -0
- data/spec/support/stubbing_using_allow.rb +29 -0
- data/spec/support/term.json +48 -0
- data/spec/support/test_app_fail.json +41 -2
- data/spec/support/test_app_pass.json +19 -2
- data/spec/support/test_app_with_right_content_type_differ.json +23 -0
- data/tasks/pact-test.rake +98 -8
- data/tasks/spec.rake +8 -0
- metadata +393 -95
- data/lib/pact/app.rb +0 -32
- data/lib/pact/consumer/configuration_dsl.rb +0 -71
- data/lib/pact/consumer/dsl.rb +0 -98
- data/lib/pact/consumer/interaction.rb +0 -70
- 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/json_warning.rb +0 -23
- data/lib/pact/producer/configuration_dsl.rb +0 -62
- data/lib/pact/producer/matchers.rb +0 -22
- data/lib/pact/producer/pact_spec_runner.rb +0 -57
- data/lib/pact/producer/producer_state.rb +0 -81
- data/lib/pact/producer/rspec.rb +0 -127
- data/lib/pact/producer/test_methods.rb +0 -89
- data/lib/pact/producer.rb +0 -1
- data/lib/pact/rake_task.rb +0 -64
- data/lib/pact/request.rb +0 -109
- data/lib/pact/verification_task.rb +0 -57
- data/spec/integration/pact/configuration_spec.rb +0 -65
- data/spec/lib/pact/consumer/dsl_spec.rb +0 -52
- data/spec/lib/pact/consumer/interaction_spec.rb +0 -108
- data/spec/lib/pact/consumer/mock_service_spec.rb +0 -147
- data/spec/lib/pact/consumer_contract_spec.rb +0 -125
- data/spec/lib/pact/producer/configuration_dsl_spec.rb +0 -101
- data/spec/lib/pact/producer/producer_state_spec.rb +0 -103
- data/spec/lib/pact/producer/rspec_spec.rb +0 -48
- data/spec/lib/pact/verification_task_spec.rb +0 -64
- data/spec/support/pact_rake_support.rb +0 -41
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
require 'pact/provider/configuration/pact_verification'
|
|
2
|
+
require 'pact/provider/configuration/service_provider_config'
|
|
3
|
+
|
|
4
|
+
module Pact
|
|
5
|
+
|
|
6
|
+
module Provider
|
|
7
|
+
|
|
8
|
+
module Configuration
|
|
9
|
+
|
|
10
|
+
class ServiceProviderDSL
|
|
11
|
+
|
|
12
|
+
extend Pact::DSL
|
|
13
|
+
|
|
14
|
+
attr_accessor :name, :app_block
|
|
15
|
+
|
|
16
|
+
CONFIG_RU_APP = lambda {
|
|
17
|
+
unless File.exist? Pact.configuration.config_ru_path
|
|
18
|
+
raise "Could not find config.ru file at #{Pact.configuration.config_ru_path} Please configure the service provider app or create a config.ru file in the root directory of the project. See https://github.com/realestate-com-au/pact/blob/master/documentation/verifying-pacts.md for more information."
|
|
19
|
+
end
|
|
20
|
+
Rack::Builder.parse_file(Pact.configuration.config_ru_path).first
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
def initialize name
|
|
24
|
+
@name = name
|
|
25
|
+
@app_block = CONFIG_RU_APP
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
dsl do
|
|
29
|
+
def app &block
|
|
30
|
+
self.app_block = block
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def honours_pact_with consumer_name, options = {}, &block
|
|
34
|
+
create_pact_verification consumer_name, options, &block
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def create_pact_verification consumer_name, options, &block
|
|
39
|
+
PactVerification.build(consumer_name, options, &block)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def finalize
|
|
43
|
+
validate
|
|
44
|
+
create_service_provider
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
def validate
|
|
50
|
+
raise "Please provide a name for the Provider" unless name && !name.strip.empty?
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def create_service_provider
|
|
54
|
+
Pact.configuration.provider = ServiceProviderConfig.new(&@app_block)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
require 'pact/provider/configuration/dsl'
|
|
2
|
+
require 'pact/provider/configuration/configuration_extension'
|
|
3
|
+
require 'pact/provider/state/provider_state'
|
|
4
|
+
|
|
5
|
+
Pact.send(:extend, Pact::Provider::DSL)
|
|
6
|
+
Pact.send(:extend, Pact::Provider::State::DSL)
|
|
7
|
+
Pact::Configuration.send(:include, Pact::Provider::Configuration::ConfigurationExtension)
|
|
File without changes
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require 'term/ansicolor'
|
|
2
|
+
require 'pact/term'
|
|
3
|
+
|
|
4
|
+
module Pact
|
|
5
|
+
module Matchers
|
|
6
|
+
module Messages
|
|
7
|
+
|
|
8
|
+
def match_term_failure_message diff, actual, diff_formatter, color_enabled
|
|
9
|
+
message = "Actual: #{(String === actual ? actual : actual.to_json)}\n\n"
|
|
10
|
+
formatted_diff = diff_formatter.call(diff)
|
|
11
|
+
message + colorize_if_enabled(formatted_diff, color_enabled)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def match_header_failure_message header_name, expected, actual
|
|
15
|
+
"Expected header \"#{header_name}\" to #{expected_desc(expected)}, but was #{actual_desc(actual)}"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def colorize_if_enabled formatted_diff, color_enabled
|
|
21
|
+
if color_enabled
|
|
22
|
+
# RSpec wraps each line in the failure message with failure_color, turning it red.
|
|
23
|
+
# To ensure the lines in the diff that should be white, stay white, put an
|
|
24
|
+
# ANSI reset at the start of each line.
|
|
25
|
+
formatted_diff.split("\n").collect{ |line| ::Term::ANSIColor.reset + line }.join("\n")
|
|
26
|
+
else
|
|
27
|
+
formatted_diff
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def expected_desc expected
|
|
32
|
+
case expected
|
|
33
|
+
when NilClass then "be nil"
|
|
34
|
+
else
|
|
35
|
+
"match #{expected.inspect}"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def actual_desc actual
|
|
40
|
+
actual.nil? ? 'nil' : '"' + actual + '"'
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Pact
|
|
2
|
+
module Provider
|
|
3
|
+
module PactHelperLocater
|
|
4
|
+
PACT_HELPER_FILE_PATTERNS = [
|
|
5
|
+
"spec/**/*service*consumer*/pact_helper.rb",
|
|
6
|
+
"spec/**/*consumer*/pact_helper.rb",
|
|
7
|
+
"spec/**/pact_helper.rb",
|
|
8
|
+
"**/pact_helper.rb"]
|
|
9
|
+
|
|
10
|
+
NO_PACT_HELPER_FOUND_MSG = "Please create a pact_helper.rb file that can be found using one of the following patterns: #{PACT_HELPER_FILE_PATTERNS.join(", ")}"
|
|
11
|
+
|
|
12
|
+
def self.pact_helper_path
|
|
13
|
+
pact_helper_search_results = []
|
|
14
|
+
PACT_HELPER_FILE_PATTERNS.find { | pattern | (pact_helper_search_results.concat(Dir.glob(pattern))).any? }
|
|
15
|
+
raise NO_PACT_HELPER_FOUND_MSG if pact_helper_search_results.empty?
|
|
16
|
+
File.join(Dir.pwd, pact_helper_search_results[0])
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
require 'open-uri'
|
|
2
|
+
require 'rspec'
|
|
3
|
+
require 'rspec/core'
|
|
4
|
+
require 'rspec/core/formatters/documentation_formatter'
|
|
5
|
+
require 'pact/provider/pact_helper_locator'
|
|
6
|
+
require 'pact/project_root'
|
|
7
|
+
require 'pact/rspec'
|
|
8
|
+
|
|
9
|
+
require_relative 'rspec'
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
module Pact
|
|
13
|
+
module Provider
|
|
14
|
+
class PactSpecRunner
|
|
15
|
+
|
|
16
|
+
include Pact::Provider::RSpec::ClassMethods
|
|
17
|
+
|
|
18
|
+
attr_reader :spec_definitions
|
|
19
|
+
attr_reader :options
|
|
20
|
+
attr_reader :output
|
|
21
|
+
|
|
22
|
+
def initialize spec_definitions, options = {}
|
|
23
|
+
@spec_definitions = spec_definitions
|
|
24
|
+
@options = options
|
|
25
|
+
@results = nil
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def run
|
|
29
|
+
begin
|
|
30
|
+
configure_rspec
|
|
31
|
+
initialize_specs
|
|
32
|
+
run_specs
|
|
33
|
+
ensure
|
|
34
|
+
::RSpec.reset
|
|
35
|
+
Pact.clear_provider_world
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def initialize_specs
|
|
42
|
+
spec_definitions.each do | spec_definition |
|
|
43
|
+
options = {
|
|
44
|
+
consumer: spec_definition[:consumer],
|
|
45
|
+
save_pactfile_to_tmp: true,
|
|
46
|
+
criteria: @options[:criteria]
|
|
47
|
+
}
|
|
48
|
+
honour_pactfile spec_definition[:uri], options
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def configure_rspec
|
|
53
|
+
monkey_patch_backtrace_formatter
|
|
54
|
+
|
|
55
|
+
config = ::RSpec.configuration
|
|
56
|
+
|
|
57
|
+
config.color = true
|
|
58
|
+
config.pattern = "pattern which doesn't match any files"
|
|
59
|
+
config.backtrace_inclusion_patterns = [Regexp.new(Dir.getwd), /pact.*main/]
|
|
60
|
+
|
|
61
|
+
config.extend Pact::Provider::RSpec::ClassMethods
|
|
62
|
+
config.include Pact::Provider::RSpec::InstanceMethods
|
|
63
|
+
config.include Pact::Provider::TestMethods
|
|
64
|
+
|
|
65
|
+
if options[:silent]
|
|
66
|
+
config.output_stream = StringIO.new
|
|
67
|
+
config.error_stream = StringIO.new
|
|
68
|
+
else
|
|
69
|
+
config.error_stream = Pact.configuration.error_stream
|
|
70
|
+
config.output_stream = Pact.configuration.output_stream
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Sometimes the formatter set in the cli.rb get set with an output of StringIO.. don't know why
|
|
74
|
+
formatter_class = Pact::RSpec.formatter_class
|
|
75
|
+
pact_formatter = ::RSpec.configuration.formatters.find {|f| f.class == formatter_class && f.output == ::RSpec.configuration.output_stream}
|
|
76
|
+
::RSpec.configuration.add_formatter formatter_class unless pact_formatter
|
|
77
|
+
|
|
78
|
+
config.before(:suite) do
|
|
79
|
+
# Preload app before suite so the classes loaded in memory are consistent for
|
|
80
|
+
# before :each and after :each hooks.
|
|
81
|
+
# Otherwise the app and all its dependencies are loaded between the first before :each
|
|
82
|
+
# and the first after :each, leading to inconsistent behaviour
|
|
83
|
+
# (eg. with database_cleaner transactions)
|
|
84
|
+
Pact.configuration.provider.app
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def run_specs
|
|
90
|
+
exit_code = if Pact::RSpec.runner_defined?
|
|
91
|
+
::RSpec::Core::Runner.run(rspec_runner_options)
|
|
92
|
+
else
|
|
93
|
+
::RSpec::Core::CommandLine.new(NoConfigurationOptions.new)
|
|
94
|
+
.run(::RSpec.configuration.output_stream, ::RSpec.configuration.error_stream)
|
|
95
|
+
end
|
|
96
|
+
exit_code
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def rspec_runner_options
|
|
100
|
+
["--options", Pact.project_root.join("lib/pact/provider/rspec/custom_options_file").to_s]
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def monkey_patch_backtrace_formatter
|
|
104
|
+
Pact::RSpec.with_rspec_3 do
|
|
105
|
+
require 'pact/provider/rspec/backtrace_formatter'
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def class_exists? name
|
|
110
|
+
Kernel.const_get name
|
|
111
|
+
rescue NameError
|
|
112
|
+
false
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
class NoConfigurationOptions
|
|
116
|
+
def method_missing(method, *args, &block)
|
|
117
|
+
# Do nothing!
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Pact::Provider
|
|
2
|
+
class PactVerification
|
|
3
|
+
attr_reader :consumer_name, :uri, :ref
|
|
4
|
+
def initialize consumer_name, uri, ref
|
|
5
|
+
@consumer_name = consumer_name
|
|
6
|
+
@uri = uri
|
|
7
|
+
@ref = ref
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def == other
|
|
11
|
+
other.is_a?(PactVerification) &&
|
|
12
|
+
consumer_name == other.consumer_name &&
|
|
13
|
+
uri == other.uri &&
|
|
14
|
+
ref == other.ref
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Pact
|
|
2
|
+
module Provider
|
|
3
|
+
class PrintMissingProviderStates
|
|
4
|
+
|
|
5
|
+
# Hash of consumer names to array of names of missing provider states
|
|
6
|
+
def self.call missing_provider_states, output
|
|
7
|
+
if missing_provider_states.any?
|
|
8
|
+
output.puts orangeify(text(missing_provider_states))
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.orangeify string
|
|
13
|
+
"\e[33m#{string}\e[m"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.text missing_provider_states
|
|
17
|
+
create_provider_states_for(missing_provider_states)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.create_provider_states_for consumers
|
|
21
|
+
ERB.new(template_string).result(binding)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.template_string
|
|
25
|
+
File.read(File.expand_path( '../../templates/provider_state.erb', __FILE__))
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
require 'pact/reification'
|
|
3
|
+
require 'pact/shared/null_expectation'
|
|
4
|
+
|
|
5
|
+
module Pact
|
|
6
|
+
module Provider
|
|
7
|
+
module Request
|
|
8
|
+
class Replayable
|
|
9
|
+
|
|
10
|
+
# See https://github.com/rack/rack/blob/e7d741c6282ca4cf4e01506f5681e6e6b14c0b32/SPEC#L87-89
|
|
11
|
+
NO_HTTP_PREFIX = ["CONTENT-TYPE", "CONTENT-LENGTH"]
|
|
12
|
+
|
|
13
|
+
def initialize expected_request
|
|
14
|
+
@expected_request = expected_request
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def method
|
|
18
|
+
expected_request.method
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def path
|
|
22
|
+
expected_request.full_path
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def body
|
|
26
|
+
case expected_request.body
|
|
27
|
+
when String then expected_request.body
|
|
28
|
+
when NullExpectation then ''
|
|
29
|
+
else
|
|
30
|
+
reified_body
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def headers
|
|
35
|
+
request_headers = {}
|
|
36
|
+
return request_headers if expected_request.headers.is_a?(Pact::NullExpectation)
|
|
37
|
+
expected_request.headers.each do |key, value|
|
|
38
|
+
request_headers[rack_request_header_for(key)] = value
|
|
39
|
+
end
|
|
40
|
+
request_headers
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
attr_reader :expected_request
|
|
45
|
+
|
|
46
|
+
def reified_body
|
|
47
|
+
rb = Pact::Reification.from_term(expected_request.body)
|
|
48
|
+
if rb.is_a?(String)
|
|
49
|
+
rb
|
|
50
|
+
else
|
|
51
|
+
JSON.dump(rb)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def rack_request_header_for header
|
|
56
|
+
with_http_prefix(header.to_s.upcase).gsub('-', '_')
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def rack_request_value_for value
|
|
60
|
+
Array(value).join("\n")
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def with_http_prefix header
|
|
64
|
+
NO_HTTP_PREFIX.include?(header) ? header : "HTTP_#{header}"
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module RSpec
|
|
2
|
+
module Core
|
|
3
|
+
|
|
4
|
+
# RSpec 3 has a hardwired @system_exclusion_patterns which removes everything matching /bin\//
|
|
5
|
+
# This causes *all* the backtrace lines to be cleaned, as rake pact:verify now shells out
|
|
6
|
+
# to the executable `pact verify ...`
|
|
7
|
+
# which then causes *all* the lines to be included as the BacktraceFormatter will
|
|
8
|
+
# include all lines of the backtrace if all lines were filtered out.
|
|
9
|
+
# This monkey patch only shows lines including bin/pact and removes the
|
|
10
|
+
# "show all lines if no lines would otherwise be shown" logic.
|
|
11
|
+
|
|
12
|
+
class BacktraceFormatter
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def format_backtrace(backtrace, options = {})
|
|
16
|
+
return backtrace if options[:full_backtrace]
|
|
17
|
+
backtrace.map { |l| backtrace_line(l) }.compact
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def backtrace_line(line)
|
|
21
|
+
relative_path(line) unless exclude?(line)
|
|
22
|
+
rescue SecurityError
|
|
23
|
+
nil
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def exclude?(line)
|
|
27
|
+
return false if @full_backtrace
|
|
28
|
+
relative_line = relative_path(line)
|
|
29
|
+
return true unless /bin\/pact/ =~ relative_line
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Copied from Metadata so a refactor can't break this overridden class
|
|
33
|
+
def relative_path(line)
|
|
34
|
+
line = line.sub(File.expand_path("."), ".")
|
|
35
|
+
line = line.sub(/\A([^:]+:\d+)$/, '\\1')
|
|
36
|
+
return nil if line == '-e:1'
|
|
37
|
+
line
|
|
38
|
+
rescue SecurityError
|
|
39
|
+
nil
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
File without changes
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
require 'pact/provider/print_missing_provider_states'
|
|
2
|
+
require 'rspec/core/formatters/documentation_formatter'
|
|
3
|
+
require 'term/ansicolor'
|
|
4
|
+
|
|
5
|
+
module Pact
|
|
6
|
+
module Provider
|
|
7
|
+
module RSpec
|
|
8
|
+
class Formatter2 < ::RSpec::Core::Formatters::DocumentationFormatter
|
|
9
|
+
|
|
10
|
+
C = ::Term::ANSIColor
|
|
11
|
+
|
|
12
|
+
def dump_commands_to_rerun_failed_examples
|
|
13
|
+
return if failed_examples.empty?
|
|
14
|
+
|
|
15
|
+
print_rerun_commands
|
|
16
|
+
print_failure_message
|
|
17
|
+
print_missing_provider_states
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def print_rerun_commands
|
|
24
|
+
output.puts("\n")
|
|
25
|
+
interaction_rerun_commands.each do | message |
|
|
26
|
+
output.puts(message)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def print_missing_provider_states
|
|
31
|
+
PrintMissingProviderStates.call Pact.provider_world.provider_states.missing_provider_states, output
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def interaction_rerun_commands
|
|
35
|
+
failed_examples.collect do |example|
|
|
36
|
+
interaction_rerun_command_for example
|
|
37
|
+
end.uniq
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def interaction_rerun_command_for example
|
|
41
|
+
provider_state = example.metadata[:pact_interaction].provider_state
|
|
42
|
+
description = example.metadata[:pact_interaction].description
|
|
43
|
+
pactfile_uri = example.metadata[:pactfile_uri]
|
|
44
|
+
example_description = example.metadata[:pact_interaction_example_description]
|
|
45
|
+
failure_color("rake pact:verify:at[#{pactfile_uri}] PACT_DESCRIPTION=\"#{description}\" PACT_PROVIDER_STATE=\"#{provider_state}\"") + " " + detail_color("# #{example_description}")
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def print_failure_message
|
|
49
|
+
output.puts failure_message
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def failure_message
|
|
53
|
+
"\n" + C.underline(C.yellow("For assistance debugging failures, please note:")) + "\n\n" +
|
|
54
|
+
"The pact files have been stored locally in the following temp directory:\n #{Pact.configuration.tmp_dir}\n\n" +
|
|
55
|
+
"The requests and responses are logged in the following log file:\n #{Pact.configuration.log_path}\n\n"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
require 'pact/provider/print_missing_provider_states'
|
|
2
|
+
require 'rspec/core/formatters'
|
|
3
|
+
require 'term/ansicolor'
|
|
4
|
+
|
|
5
|
+
module Pact
|
|
6
|
+
module Provider
|
|
7
|
+
module RSpec
|
|
8
|
+
class Formatter < ::RSpec::Core::Formatters::DocumentationFormatter
|
|
9
|
+
|
|
10
|
+
Pact::RSpec.with_rspec_3 do
|
|
11
|
+
::RSpec::Core::Formatters.register self, :example_group_started, :example_group_finished,
|
|
12
|
+
:example_passed, :example_pending, :example_failed
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
C = ::Term::ANSIColor
|
|
16
|
+
|
|
17
|
+
def dump_summary(summary)
|
|
18
|
+
output.puts "\n" + colorized_totals_line(summary)
|
|
19
|
+
return if summary.failure_count == 0
|
|
20
|
+
print_rerun_commands summary
|
|
21
|
+
print_failure_message
|
|
22
|
+
print_missing_provider_states
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def interactions_count(summary)
|
|
28
|
+
summary.examples.collect{ |e|e.metadata[:pact_interaction_example_description]}.uniq.size
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def failed_interactions_count(summary)
|
|
32
|
+
summary.failed_examples.collect{ |e|e.metadata[:pact_interaction_example_description]}.uniq.size
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def totals_line summary
|
|
36
|
+
line = ::RSpec::Core::Formatters::Helpers.pluralize(interactions_count(summary), "interaction")
|
|
37
|
+
line << ", " << ::RSpec::Core::Formatters::Helpers.pluralize(failed_interactions_count(summary), "failure")
|
|
38
|
+
line
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def colorized_totals_line(summary)
|
|
42
|
+
if summary.failure_count > 0
|
|
43
|
+
colorizer.wrap(totals_line(summary), ::RSpec.configuration.failure_color)
|
|
44
|
+
else
|
|
45
|
+
colorizer.wrap(totals_line(summary), ::RSpec.configuration.success_color)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def print_rerun_commands summary
|
|
50
|
+
output.puts("\nFailed interactions:\n\n")
|
|
51
|
+
interaction_rerun_commands(summary).each do | message |
|
|
52
|
+
output.puts(message)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def print_missing_provider_states
|
|
57
|
+
PrintMissingProviderStates.call Pact.provider_world.provider_states.missing_provider_states, output
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def interaction_rerun_commands summary
|
|
61
|
+
summary.failed_examples.collect do |example|
|
|
62
|
+
interaction_rerun_command_for example
|
|
63
|
+
end.uniq
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def interaction_rerun_command_for example
|
|
67
|
+
provider_state = example.metadata[:pact_interaction].provider_state
|
|
68
|
+
description = example.metadata[:pact_interaction].description
|
|
69
|
+
pactfile_uri = example.metadata[:pactfile_uri]
|
|
70
|
+
example_description = example.metadata[:pact_interaction_example_description]
|
|
71
|
+
colorizer.wrap("rake pact:verify:at[#{pactfile_uri}] PACT_DESCRIPTION=\"#{description}\" PACT_PROVIDER_STATE=\"#{provider_state}\" ", ::RSpec.configuration.failure_color) +
|
|
72
|
+
colorizer.wrap("# #{example_description}", ::RSpec.configuration.detail_color)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def print_failure_message
|
|
76
|
+
output.puts failure_message
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def failure_message
|
|
80
|
+
"\n" + C.underline(C.yellow("For assistance debugging failures, please note:")) + "\n\n" +
|
|
81
|
+
"The pact files have been stored locally in the following temp directory:\n #{Pact.configuration.tmp_dir}\n\n" +
|
|
82
|
+
"The requests and responses are logged in the following log file:\n #{Pact.configuration.log_path}\n\n"
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def colorizer
|
|
86
|
+
@colorizer ||= ::RSpec::Core::Formatters::ConsoleCodes
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
require 'rspec'
|
|
2
|
+
require 'pact/matchers'
|
|
3
|
+
require 'pact/provider/matchers/messages'
|
|
4
|
+
require 'pact/rspec'
|
|
5
|
+
require 'pact/shared/json_differ'
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
module Pact
|
|
9
|
+
module RSpec
|
|
10
|
+
module Matchers
|
|
11
|
+
|
|
12
|
+
module RSpec2Delegator
|
|
13
|
+
# For backwards compatiblity with rspec-2
|
|
14
|
+
def method_missing(method, *args, &block)
|
|
15
|
+
if method_name == :failure_message_for_should
|
|
16
|
+
failure_message method, *args, &block
|
|
17
|
+
else
|
|
18
|
+
super
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
class MatchTerm
|
|
24
|
+
|
|
25
|
+
include Pact::Matchers::Messages
|
|
26
|
+
include RSpec2Delegator
|
|
27
|
+
|
|
28
|
+
def initialize expected, differ, diff_formatter
|
|
29
|
+
@expected = expected
|
|
30
|
+
@differ = differ
|
|
31
|
+
@diff_formatter = diff_formatter
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def matches? actual
|
|
35
|
+
@actual = actual
|
|
36
|
+
(@difference = @differ.call(@expected, @actual)).empty?
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def failure_message
|
|
40
|
+
match_term_failure_message @difference, @actual, @diff_formatter, Pact::RSpec.color_enabled?
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def match_term expected, options
|
|
46
|
+
MatchTerm.new(expected, options.fetch(:with), options.fetch(:diff_formatter))
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
class MatchHeader
|
|
50
|
+
|
|
51
|
+
include Pact::Matchers
|
|
52
|
+
include Pact::Matchers::Messages
|
|
53
|
+
include RSpec2Delegator
|
|
54
|
+
|
|
55
|
+
def initialize header_name, expected
|
|
56
|
+
@header_name = header_name
|
|
57
|
+
@expected = expected
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def matches? actual
|
|
61
|
+
@actual = actual
|
|
62
|
+
diff(@expected, @actual).empty?
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def failure_message
|
|
66
|
+
match_header_failure_message @header_name, @expected, @actual
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def match_header header_name, expected
|
|
72
|
+
MatchHeader.new(header_name, expected)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
# RSpec::Matchers.define :match_header do |header_name, expected|
|
|
81
|
+
|
|
82
|
+
# include Pact::Matchers
|
|
83
|
+
# include Pact::Matchers::Messages
|
|
84
|
+
|
|
85
|
+
# match do |actual|
|
|
86
|
+
# diff(expected, actual).empty?
|
|
87
|
+
# end
|
|
88
|
+
|
|
89
|
+
# def failure_message_for_should(actual)
|
|
90
|
+
# match_header_failure_message header_name, expected, actual
|
|
91
|
+
# end
|
|
92
|
+
|
|
93
|
+
# # failure_message_for_should do | actual |
|
|
94
|
+
# # match_header_failure_message header_name, expected, actual
|
|
95
|
+
# # end
|
|
96
|
+
|
|
97
|
+
# end
|