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,71 @@
|
|
|
1
|
+
require_relative 'pact_helper'
|
|
2
|
+
require 'zoo_app/animal_service_client'
|
|
3
|
+
|
|
4
|
+
module ZooApp
|
|
5
|
+
describe AnimalServiceClient, :pact => true do
|
|
6
|
+
|
|
7
|
+
before do
|
|
8
|
+
AnimalServiceClient.base_uri animal_service.mock_service_base_url
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
describe ".find_alligator_by_name" do
|
|
12
|
+
context "when an alligator by the given name exists" do
|
|
13
|
+
|
|
14
|
+
before do
|
|
15
|
+
animal_service.given("there is an alligator named Mary").
|
|
16
|
+
upon_receiving("a request for an alligator").with(
|
|
17
|
+
method: :get,
|
|
18
|
+
path: '/alligators/Mary',
|
|
19
|
+
headers: {'Accept' => 'application/json'} ).
|
|
20
|
+
will_respond_with(
|
|
21
|
+
status: 200,
|
|
22
|
+
headers: {'Content-Type' => 'application/json;charset=utf-8'},
|
|
23
|
+
body: {name: 'Mary'}
|
|
24
|
+
)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "returns the alligator" do
|
|
28
|
+
expect(AnimalServiceClient.find_alligator_by_name("Mary")).to eq ZooApp::Animals::Alligator.new(name: 'Mary')
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
context "when an alligator by the given name does not exist" do
|
|
34
|
+
|
|
35
|
+
before do
|
|
36
|
+
animal_service.given("there is not an alligator named Mary").
|
|
37
|
+
upon_receiving("a request for an alligator").with(
|
|
38
|
+
method: :get,
|
|
39
|
+
path: '/alligators/Mary',
|
|
40
|
+
headers: {'Accept' => 'application/json'} ).
|
|
41
|
+
will_respond_with(status: 404)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "returns nil" do
|
|
45
|
+
expect(AnimalServiceClient.find_alligator_by_name("Mary")).to be_nil
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
context "when an error occurs retrieving the alligator" do
|
|
51
|
+
|
|
52
|
+
before do
|
|
53
|
+
animal_service.given("an error occurs retrieving an alligator").
|
|
54
|
+
upon_receiving("a request for an alligator").with(
|
|
55
|
+
method: :get,
|
|
56
|
+
path: '/alligators/Mary',
|
|
57
|
+
headers: {'Accept' => 'application/json'}).
|
|
58
|
+
will_respond_with(
|
|
59
|
+
status: 500,
|
|
60
|
+
headers: { 'Content-Type' => 'application/json;charset=utf-8'},
|
|
61
|
+
body: {error: 'Argh!!!'})
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it "raises an error" do
|
|
65
|
+
expect{ AnimalServiceClient.find_alligator_by_name("Mary") }.to raise_error /Argh/
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require_relative '../spec_helper'
|
|
2
|
+
require 'pact/consumer/rspec'
|
|
3
|
+
|
|
4
|
+
Pact.configure do | config |
|
|
5
|
+
config.doc_generator = :markdown
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
Pact.service_consumer 'Zoo App' do
|
|
9
|
+
has_pact_with "Animal Service" do
|
|
10
|
+
mock_service :animal_service do
|
|
11
|
+
port 1234
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
data/lib/pact/cli.rb
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
require 'find_a_port'
|
|
2
|
+
require 'thor'
|
|
3
|
+
require 'thwait'
|
|
4
|
+
require 'pact/consumer'
|
|
5
|
+
require 'rack/handler/webrick'
|
|
6
|
+
|
|
7
|
+
module Pact
|
|
8
|
+
class CLI < Thor
|
|
9
|
+
|
|
10
|
+
desc 'verify', "Verify a pact"
|
|
11
|
+
method_option :pact_helper, aliases: "-h", desc: "Pact helper file", :required => true
|
|
12
|
+
method_option :pact_uri, aliases: "-p", desc: "Pact URI"
|
|
13
|
+
|
|
14
|
+
def verify
|
|
15
|
+
RunPactVerification.call(options)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
desc 'service', "Start a mock service"
|
|
19
|
+
method_option :port, aliases: "-p", desc: "Port on which to run the service"
|
|
20
|
+
method_option :log, aliases: "-l", desc: "File to which to log output"
|
|
21
|
+
method_option :quiet, aliases: "-q", desc: "If true, no admin messages will be shown"
|
|
22
|
+
|
|
23
|
+
def service
|
|
24
|
+
RunStandaloneMockService.call(options)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def log message
|
|
30
|
+
puts message unless options[:quiet]
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
class RunPactVerification
|
|
35
|
+
|
|
36
|
+
attr_reader :options
|
|
37
|
+
|
|
38
|
+
def initialize options
|
|
39
|
+
@options = options
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def self.call options
|
|
43
|
+
new(options).call
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def call
|
|
48
|
+
initialize_rspec
|
|
49
|
+
setup_load_path
|
|
50
|
+
load_pact_helper
|
|
51
|
+
run_specs
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
|
|
56
|
+
def initialize_rspec
|
|
57
|
+
# With RSpec3, if the pact_helper loads a library that adds its own formatter before we set one,
|
|
58
|
+
# we will get a ProgressFormatter too, and get little dots sprinkled throughout our output.
|
|
59
|
+
require 'pact/rspec'
|
|
60
|
+
::RSpec.configuration.add_formatter Pact::RSpec.formatter_class
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def setup_load_path
|
|
64
|
+
require 'pact/provider/pact_spec_runner'
|
|
65
|
+
lib = File.join(Dir.pwd, "lib") # Assume we are running from within the project root. RSpec is smarter about this.
|
|
66
|
+
spec = File.join(Dir.pwd, "spec")
|
|
67
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
68
|
+
$LOAD_PATH.unshift(spec) if Dir.exist?(spec) && !$LOAD_PATH.include?(spec)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def load_pact_helper
|
|
72
|
+
load options[:pact_helper]
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def run_specs
|
|
76
|
+
exit_code = if options[:pact_uri]
|
|
77
|
+
run_with_pact_uri
|
|
78
|
+
else
|
|
79
|
+
run_with_configured_pacts
|
|
80
|
+
end
|
|
81
|
+
exit 1 unless exit_code == 0
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def run_with_pact_uri
|
|
85
|
+
Pact::Provider::PactSpecRunner.new([{uri: options[:pact_uri]}], pact_spec_options).run
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def run_with_configured_pacts
|
|
89
|
+
pact_verifications = Pact.configuration.pact_verifications
|
|
90
|
+
verification_configs = pact_verifications.collect { | pact_verification | { :uri => pact_verification.uri }}
|
|
91
|
+
raise "Please configure a pact to verify" if verification_configs.empty?
|
|
92
|
+
Pact::Provider::PactSpecRunner.new(verification_configs, options).run
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def pact_spec_options
|
|
96
|
+
{criteria: SpecCriteria.call}
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
class RunStandaloneMockService
|
|
102
|
+
|
|
103
|
+
def self.call options
|
|
104
|
+
service_options = {}
|
|
105
|
+
if options[:log]
|
|
106
|
+
log = File.open(options[:log], 'w')
|
|
107
|
+
log.sync = true
|
|
108
|
+
service_options[:log_file] = log
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
port = options[:port] || FindAPort.available_port
|
|
112
|
+
mock_service = Consumer::MockService.new(service_options)
|
|
113
|
+
trap(:INT) { Rack::Handler::WEBrick.shutdown }
|
|
114
|
+
Rack::Handler::WEBrick.run(mock_service, :Port => port, :AccessLog => [])
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
class SpecCriteria
|
|
119
|
+
|
|
120
|
+
def self.call
|
|
121
|
+
criteria = {}
|
|
122
|
+
|
|
123
|
+
description = ENV["PACT_DESCRIPTION"]
|
|
124
|
+
criteria[:description] = Regexp.new(description) if description
|
|
125
|
+
|
|
126
|
+
provider_state = ENV["PACT_PROVIDER_STATE"]
|
|
127
|
+
if provider_state
|
|
128
|
+
if provider_state.length == 0
|
|
129
|
+
criteria[:provider_state] = nil #Allow PACT_PROVIDER_STATE="" to mean no provider state
|
|
130
|
+
else
|
|
131
|
+
criteria[:provider_state] = Regexp.new(provider_state)
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
criteria
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
data/lib/pact/configuration.rb
CHANGED
|
@@ -1,22 +1,186 @@
|
|
|
1
1
|
require 'ostruct'
|
|
2
2
|
require 'logger'
|
|
3
|
+
require 'pact/doc/markdown/generator'
|
|
4
|
+
require 'pact/matchers/unix_diff_formatter'
|
|
5
|
+
require 'pact/matchers/embedded_diff_formatter'
|
|
6
|
+
require 'pact/matchers/list_diff_formatter'
|
|
7
|
+
require 'pact/shared/json_differ'
|
|
8
|
+
require 'pact/shared/text_differ'
|
|
3
9
|
|
|
4
10
|
module Pact
|
|
5
11
|
|
|
6
12
|
class Configuration
|
|
13
|
+
|
|
14
|
+
DOC_GENERATORS = { markdown: Pact::Doc::Markdown::Generator }
|
|
15
|
+
|
|
16
|
+
DIFF_FORMATTERS = {
|
|
17
|
+
:embedded => Pact::Matchers::EmbeddedDiffFormatter,
|
|
18
|
+
:unix => Pact::Matchers::UnixDiffFormatter,
|
|
19
|
+
:list => Pact::Matchers::ListDiffFormatter
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class NilMatcher
|
|
24
|
+
def self.=~ other
|
|
25
|
+
other == nil ? 0 : nil
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
DIFF_FORMATTER_REGISTRATIONS = [
|
|
30
|
+
[/.*/, Pact::Matchers::UnixDiffFormatter],
|
|
31
|
+
[NilMatcher, Pact::Matchers::UnixDiffFormatter]
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
DIFFERS = [
|
|
35
|
+
[/json/, Pact::JsonDiffer],
|
|
36
|
+
[NilMatcher, Pact::TextDiffer],
|
|
37
|
+
[/.*/, Pact::TextDiffer]
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
DEFAULT_DIFFER = Pact::TextDiffer
|
|
42
|
+
|
|
7
43
|
attr_accessor :pact_dir
|
|
8
44
|
attr_accessor :log_dir
|
|
9
|
-
attr_accessor :
|
|
45
|
+
attr_accessor :doc_dir
|
|
46
|
+
attr_accessor :reports_dir
|
|
47
|
+
attr_writer :logger
|
|
10
48
|
attr_accessor :tmp_dir
|
|
11
|
-
|
|
49
|
+
attr_writer :pactfile_write_mode
|
|
50
|
+
|
|
51
|
+
attr_accessor :error_stream
|
|
52
|
+
attr_accessor :output_stream
|
|
53
|
+
|
|
54
|
+
def self.default_configuration
|
|
55
|
+
c = Configuration.new
|
|
56
|
+
c.pact_dir = File.expand_path('./spec/pacts')
|
|
57
|
+
c.tmp_dir = File.expand_path('./tmp/pacts')
|
|
58
|
+
c.log_dir = default_log_dir
|
|
59
|
+
c.pactfile_write_mode = :overwrite
|
|
60
|
+
c.reports_dir = File.expand_path('./reports/pacts')
|
|
61
|
+
c.doc_dir = File.expand_path("./doc/pacts")
|
|
62
|
+
c.output_stream = $stdout
|
|
63
|
+
c.error_stream = $stderr
|
|
64
|
+
c
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def initialize
|
|
68
|
+
@differ_registrations = []
|
|
69
|
+
@diff_formatter_registrations = []
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def logger
|
|
73
|
+
@logger ||= create_logger
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def doc_generator= doc_generator
|
|
77
|
+
doc_generators << begin
|
|
78
|
+
if DOC_GENERATORS[doc_generator]
|
|
79
|
+
DOC_GENERATORS[doc_generator]
|
|
80
|
+
elsif doc_generator.respond_to?(:call)
|
|
81
|
+
doc_generator
|
|
82
|
+
else
|
|
83
|
+
raise "Pact.configuration.doc_generator needs to respond to call, or be in the preconfigured list: #{DOC_GENERATORS.keys}"
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def doc_generators
|
|
89
|
+
@doc_generators ||= []
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Should this be deprecated in favour of register_diff_formatter???
|
|
93
|
+
def diff_formatter= diff_formatter
|
|
94
|
+
register_diff_formatter /.*/, diff_formatter
|
|
95
|
+
register_diff_formatter nil, diff_formatter
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def register_diff_formatter content_type, diff_formatter
|
|
99
|
+
key = content_type_regexp_for content_type
|
|
100
|
+
@diff_formatter_registrations << [key, diff_formatter_for(diff_formatter)]
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def diff_formatter_for_content_type content_type
|
|
104
|
+
diff_formatter_registrations.find{ | registration | registration.first =~ content_type }.last
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def register_body_differ content_type, differ
|
|
108
|
+
key = content_type_regexp_for content_type
|
|
109
|
+
validate_differ differ
|
|
110
|
+
@differ_registrations << [key, differ]
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def body_differ_for_content_type content_type
|
|
114
|
+
differ_registrations.find{ | registration | registration.first =~ content_type }.last
|
|
115
|
+
end
|
|
12
116
|
|
|
13
117
|
def log_path
|
|
14
|
-
log_dir + "/
|
|
118
|
+
log_dir + "/pact.log"
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def pactfile_write_mode
|
|
122
|
+
if @pactfile_write_mode == :smart
|
|
123
|
+
is_rake_running? ? :overwrite : :update
|
|
124
|
+
else
|
|
125
|
+
@pactfile_write_mode
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
private
|
|
130
|
+
|
|
131
|
+
def diff_formatter_for input
|
|
132
|
+
if DIFF_FORMATTERS[input]
|
|
133
|
+
DIFF_FORMATTERS[input]
|
|
134
|
+
elsif input.respond_to?(:call)
|
|
135
|
+
input
|
|
136
|
+
else
|
|
137
|
+
raise "Pact diff_formatter needs to respond to call, or be in the preconfigured list: #{DIFF_FORMATTERS.keys}"
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def validate_differ differ
|
|
142
|
+
if !differ.respond_to?(:call)
|
|
143
|
+
raise "Pact.configuration.register_body_differ expects a differ that is a lamda or a class/object that responds to call."
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def content_type_regexp_for content_type
|
|
148
|
+
case content_type
|
|
149
|
+
when String then Regexp.new(/^#{Regexp.escape(content_type)}$/)
|
|
150
|
+
when Regexp then content_type
|
|
151
|
+
when nil then NilMatcher
|
|
152
|
+
else
|
|
153
|
+
raise "Invalid content type used to register a differ (#{content_type.inspect}). Please use a Regexp or a String."
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def differ_registrations
|
|
158
|
+
@differ_registrations + DIFFERS
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def diff_formatter_registrations
|
|
162
|
+
@diff_formatter_registrations + DIFF_FORMATTER_REGISTRATIONS
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def self.default_log_dir
|
|
166
|
+
File.expand_path("./log")
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
#Would love a better way of determining this! It sure won't work on windows.
|
|
170
|
+
def is_rake_running?
|
|
171
|
+
`ps -ef | grep rake | grep #{Process.ppid} | grep -v 'grep'`.size > 0
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def create_logger
|
|
175
|
+
FileUtils::mkdir_p log_dir
|
|
176
|
+
logger = Logger.new(log_path)
|
|
177
|
+
logger.level = Logger::DEBUG
|
|
178
|
+
logger
|
|
15
179
|
end
|
|
16
180
|
end
|
|
17
181
|
|
|
18
182
|
def self.configuration
|
|
19
|
-
@configuration ||= default_configuration
|
|
183
|
+
@configuration ||= Configuration.default_configuration
|
|
20
184
|
end
|
|
21
185
|
|
|
22
186
|
def self.configure
|
|
@@ -25,30 +189,7 @@ module Pact
|
|
|
25
189
|
end
|
|
26
190
|
|
|
27
191
|
def self.clear_configuration
|
|
28
|
-
@configuration =
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
private
|
|
32
|
-
|
|
33
|
-
def self.default_configuration
|
|
34
|
-
c = Configuration.new
|
|
35
|
-
c.pact_dir = File.expand_path('./spec/pacts')
|
|
36
|
-
c.tmp_dir = File.expand_path('./tmp/pacts')
|
|
37
|
-
c.log_dir = default_log_dir
|
|
38
|
-
c.logger = default_logger c.log_path
|
|
39
|
-
c.pactfile_write_mode = defined?(Rake) ? :overwrite : :update
|
|
40
|
-
c
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def self.default_log_dir
|
|
44
|
-
File.expand_path("./log")
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def self.default_logger path
|
|
48
|
-
FileUtils::mkdir_p File.dirname(path)
|
|
49
|
-
logger = Logger.new(path)
|
|
50
|
-
logger.level = Logger::INFO
|
|
51
|
-
logger
|
|
192
|
+
@configuration = nil
|
|
52
193
|
end
|
|
53
194
|
|
|
54
195
|
end
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
require 'thwait'
|
|
2
|
-
require 'capybara'
|
|
3
2
|
|
|
4
3
|
require 'net/http'
|
|
5
4
|
require 'uri'
|
|
6
5
|
require 'find_a_port'
|
|
7
6
|
require 'pact/logging'
|
|
7
|
+
require 'pact/consumer/server'
|
|
8
|
+
require 'singleton'
|
|
8
9
|
|
|
9
10
|
module Pact
|
|
10
11
|
module Consumer
|
|
@@ -82,7 +83,7 @@ module Pact
|
|
|
82
83
|
lower_case_name.gsub('_service', '_mock_service')
|
|
83
84
|
else
|
|
84
85
|
lower_case_name + '_mock_service'
|
|
85
|
-
end
|
|
86
|
+
end
|
|
86
87
|
end
|
|
87
88
|
|
|
88
89
|
def app_registrations
|
|
@@ -110,9 +111,11 @@ module Pact
|
|
|
110
111
|
end
|
|
111
112
|
|
|
112
113
|
def kill
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
Process.
|
|
114
|
+
# TODO: need to work out how to kill
|
|
115
|
+
# logger.info "Killing #{self}"
|
|
116
|
+
# Process.kill(9, pid)
|
|
117
|
+
# Process.wait(pid)
|
|
118
|
+
# self.pid = nil
|
|
116
119
|
self.pid = nil
|
|
117
120
|
end
|
|
118
121
|
|
|
@@ -133,31 +136,9 @@ module Pact
|
|
|
133
136
|
end
|
|
134
137
|
|
|
135
138
|
def spawn
|
|
136
|
-
# following stolen from https://github.com/jwilger/kookaburra
|
|
137
139
|
logger.info "Starting app #{self}..."
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
Capybara.server_port = port
|
|
141
|
-
Capybara::Server.new(app).boot
|
|
142
|
-
|
|
143
|
-
# This ensures that this forked process keeps running, because the
|
|
144
|
-
# actual server is started in a thread by Capybara.
|
|
145
|
-
ThreadsWait.all_waits(Thread.list)
|
|
146
|
-
rescue Exception => e
|
|
147
|
-
logger.error "Error starting up #{self}"
|
|
148
|
-
$stderr.puts "Error starting up #{self}"
|
|
149
|
-
raise e
|
|
150
|
-
end
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
wait_until do
|
|
155
|
-
begin
|
|
156
|
-
Net::HTTP.get_response(URI.parse("http://localhost:#{port}/index.html"))
|
|
157
|
-
rescue Errno::ECONNREFUSED
|
|
158
|
-
false
|
|
159
|
-
end
|
|
160
|
-
end
|
|
140
|
+
Pact::Server.new(app, port).boot
|
|
141
|
+
self.pid = 'unknown'
|
|
161
142
|
logger.info "Started with pid #{pid}"
|
|
162
143
|
end
|
|
163
144
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module Pact
|
|
2
|
+
module Consumer
|
|
3
|
+
module Configuration
|
|
4
|
+
|
|
5
|
+
module ConfigurationExtensions
|
|
6
|
+
def add_provider_verification &block
|
|
7
|
+
provider_verifications << block
|
|
8
|
+
end
|
|
9
|
+
def provider_verifications
|
|
10
|
+
@provider_verifications ||= []
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
require 'pact/consumer/app_manager'
|
|
2
|
+
require 'pact/consumer/consumer_contract_builder'
|
|
3
|
+
require 'pact/consumer/consumer_contract_builders'
|
|
4
|
+
require 'pact/consumer/world'
|
|
5
|
+
|
|
6
|
+
module Pact
|
|
7
|
+
module Consumer
|
|
8
|
+
module Configuration
|
|
9
|
+
class MockService
|
|
10
|
+
|
|
11
|
+
extend Pact::DSL
|
|
12
|
+
|
|
13
|
+
attr_accessor :port, :standalone, :verify, :provider_name, :consumer_name
|
|
14
|
+
|
|
15
|
+
def initialize name, consumer_name, provider_name
|
|
16
|
+
@name = name
|
|
17
|
+
@consumer_name = consumer_name
|
|
18
|
+
@provider_name = provider_name
|
|
19
|
+
@port = nil
|
|
20
|
+
@standalone = false
|
|
21
|
+
@verify = true
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
dsl do
|
|
25
|
+
def port port
|
|
26
|
+
self.port = port
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def standalone standalone
|
|
30
|
+
self.standalone = standalone
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def verify verify
|
|
34
|
+
self.verify = verify
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def finalize
|
|
39
|
+
validate
|
|
40
|
+
register_mock_service
|
|
41
|
+
configure_consumer_contract_builder
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def register_mock_service
|
|
47
|
+
unless standalone
|
|
48
|
+
AppManager.instance.register_mock_service_for provider_name, "http://localhost:#{port}"
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def configure_consumer_contract_builder
|
|
53
|
+
consumer_contract_builder = create_consumer_contract_builder
|
|
54
|
+
create_consumer_contract_builders_method consumer_contract_builder
|
|
55
|
+
setup_verification(consumer_contract_builder) if verify
|
|
56
|
+
consumer_contract_builder
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def create_consumer_contract_builder
|
|
60
|
+
consumer_contract_builder_fields = {
|
|
61
|
+
:consumer_name => consumer_name,
|
|
62
|
+
:provider_name => provider_name,
|
|
63
|
+
:pactfile_write_mode => Pact.configuration.pactfile_write_mode,
|
|
64
|
+
:port => port
|
|
65
|
+
}
|
|
66
|
+
Pact::Consumer::ConsumerContractBuilder.new consumer_contract_builder_fields
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def setup_verification consumer_contract_builder
|
|
70
|
+
Pact.configuration.add_provider_verification do | example_description |
|
|
71
|
+
consumer_contract_builder.verify example_description
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# This makes the consumer_contract_builder available via a module method with the given identifier
|
|
76
|
+
# as the method name.
|
|
77
|
+
# I feel this should be defined somewhere else, but I'm not sure where
|
|
78
|
+
def create_consumer_contract_builders_method consumer_contract_builder
|
|
79
|
+
Pact::Consumer::ConsumerContractBuilders.send(:define_method, @name.to_sym) do
|
|
80
|
+
consumer_contract_builder
|
|
81
|
+
end
|
|
82
|
+
Pact.consumer_world.add_consumer_contract_builder consumer_contract_builder
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def validate
|
|
86
|
+
raise "Please provide a port for service #{name}" unless port
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require 'pact/shared/dsl'
|
|
2
|
+
|
|
3
|
+
module Pact
|
|
4
|
+
module Consumer
|
|
5
|
+
module Configuration
|
|
6
|
+
class ServiceConsumer
|
|
7
|
+
|
|
8
|
+
extend Pact::DSL
|
|
9
|
+
|
|
10
|
+
attr_accessor :app, :port, :name
|
|
11
|
+
|
|
12
|
+
def initialize name
|
|
13
|
+
@name = name
|
|
14
|
+
@app = nil
|
|
15
|
+
@port = nil
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
dsl do
|
|
19
|
+
def app app
|
|
20
|
+
self.app = app
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def port port
|
|
24
|
+
self.port = port
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def has_pact_with service_provider_name, &block
|
|
28
|
+
ServiceProvider.build(service_provider_name, name, &block)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def finalize
|
|
33
|
+
validate
|
|
34
|
+
register_consumer_app if @app
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def validate
|
|
40
|
+
raise "Please provide a consumer name" unless (name && !name.empty?)
|
|
41
|
+
raise "Please provide a port for the consumer app" if app && !port
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def register_consumer_app
|
|
46
|
+
Pact::Consumer::AppManager.instance.register app, port
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|