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
|
@@ -5,7 +5,7 @@ Could use:
|
|
|
5
5
|
eg
|
|
6
6
|
ex
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
my_provider.
|
|
9
9
|
given("a thing exists").
|
|
10
10
|
upon_receiving("a request for a thing").with({:method => 'get', :path => '/thing'})
|
|
11
11
|
will_respond_with({:body => {
|
|
@@ -29,8 +29,24 @@ Need a way to specify a literal empty hash, rather than a hash that matches anyt
|
|
|
29
29
|
{:something => actual({}) }
|
|
30
30
|
{:something => empty_hash }
|
|
31
31
|
|
|
32
|
-
Slightly unintuitive behaviour: {} matches any hash, but [] only matches an empty array (or does now we've changed the code). Should [] match any array? How do we then specify an empty array?
|
|
32
|
+
# Slightly unintuitive behaviour: {} matches any hash, but [] only matches an empty array (or does now we've changed the code). Should [] match any array? How do we then specify an empty array?
|
|
33
33
|
|
|
34
34
|
{:something => literal([]) }
|
|
35
35
|
{:something => actual([]) }
|
|
36
36
|
{:something => empty_array }
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
Pact.build do
|
|
40
|
+
{
|
|
41
|
+
status: 200,
|
|
42
|
+
headers: exactly({
|
|
43
|
+
|
|
44
|
+
}),
|
|
45
|
+
body: including({
|
|
46
|
+
age: literal('12'),
|
|
47
|
+
phoneNumber: example("0415 134 234", /\d{4} \d{3} \d{3}/),
|
|
48
|
+
favouriteColors:
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
end
|
|
@@ -1,30 +1,33 @@
|
|
|
1
1
|
require 'net/http'
|
|
2
2
|
require 'pact/consumer'
|
|
3
3
|
require 'pact/consumer/rspec'
|
|
4
|
-
|
|
4
|
+
load 'pact/consumer/world.rb'
|
|
5
5
|
|
|
6
6
|
describe "A service consumer side of a pact", :pact => true do
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
before do
|
|
9
9
|
Pact.clear_configuration
|
|
10
|
+
Pact.clear_consumer_world
|
|
11
|
+
end
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
end
|
|
13
|
+
describe "blah" do
|
|
14
|
+
describe "thing" do
|
|
15
|
+
|
|
16
|
+
it "goes a little something like this" do
|
|
16
17
|
|
|
17
|
-
Pact.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
Pact.service_consumer "Consumer" do
|
|
19
|
+
has_pact_with "Alice Service" do
|
|
20
|
+
mock_service :alice_service do
|
|
21
|
+
verify true
|
|
22
|
+
port 1234
|
|
23
|
+
end
|
|
21
24
|
end
|
|
22
|
-
end
|
|
23
25
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
has_pact_with "Bob" do
|
|
27
|
+
mock_service :bob_service do
|
|
28
|
+
verify false
|
|
29
|
+
port 4321
|
|
30
|
+
end
|
|
28
31
|
end
|
|
29
32
|
end
|
|
30
33
|
|
|
@@ -44,7 +47,7 @@ describe "A service consumer side of a pact", :pact => true do
|
|
|
44
47
|
method: :post,
|
|
45
48
|
path: '/donuts',
|
|
46
49
|
body: {
|
|
47
|
-
"name" => Pact::Term.new(matcher: /Bob
|
|
50
|
+
"name" => Pact::Term.new(matcher: /Bob/, generate: 'Bob')
|
|
48
51
|
},
|
|
49
52
|
headers: {'Accept' => 'text/plain', "Content-Type" => 'application/json'}
|
|
50
53
|
}).
|
|
@@ -61,7 +64,7 @@ describe "A service consumer side of a pact", :pact => true do
|
|
|
61
64
|
status: 200,
|
|
62
65
|
body: /deleted/
|
|
63
66
|
})
|
|
64
|
-
bob_service.
|
|
67
|
+
bob_service.
|
|
65
68
|
upon_receiving('an update alligators request').with({
|
|
66
69
|
method: :put,
|
|
67
70
|
path: '/alligators',
|
|
@@ -101,46 +104,11 @@ describe "A service consumer side of a pact", :pact => true do
|
|
|
101
104
|
|
|
102
105
|
expect(bob_post_response.code).to eql '200'
|
|
103
106
|
expect(bob_post_response.body).to eql([{"name" => "Roger", "age" => 20}].to_json)
|
|
104
|
-
expect{ bob_service.verify('goes a little something like this') }.to raise_error /do not match/
|
|
105
|
-
end
|
|
106
107
|
|
|
107
|
-
|
|
108
|
-
before do
|
|
109
|
-
Pact.clear_configuration
|
|
110
|
-
|
|
111
|
-
Pact.configure do | config |
|
|
112
|
-
config.consumer do
|
|
113
|
-
name "Consumer"
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
Pact.with_producer "Zebra Service" do
|
|
118
|
-
mock_service :zebra_service do
|
|
119
|
-
verify false
|
|
120
|
-
port 1235
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
it "goes like this" do
|
|
126
|
-
zebra_service.
|
|
127
|
-
given(:the_zebras_are_here).
|
|
128
|
-
upon_receiving("a retrieve Mallory request").with({
|
|
129
|
-
method: :get,
|
|
130
|
-
path: '/mallory',
|
|
131
|
-
headers: {'Accept' => 'text/html'}
|
|
132
|
-
}).
|
|
133
|
-
will_respond_with({
|
|
134
|
-
status: 200,
|
|
135
|
-
headers: { 'Content-Type' => 'text/html' },
|
|
136
|
-
body: Pact::Term.new(matcher: /Mallory/, generate: 'That is some good Mallory.')
|
|
137
|
-
})
|
|
138
|
-
|
|
139
|
-
interactions = Pact::ConsumerContract.from_json(File.read(zebra_service.consumer_contract.pactfile_path)).interactions
|
|
140
|
-
interactions.first.producer_state.should eq("the_zebras_are_here")
|
|
141
|
-
sleep 1
|
|
142
|
-
end
|
|
108
|
+
expect{ bob_service.verify('goes a little something like this') }.to raise_error /do not match/
|
|
143
109
|
end
|
|
144
110
|
|
|
145
111
|
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
146
114
|
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
require '
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'pact/provider/rspec'
|
|
2
3
|
require 'pact/consumer_contract'
|
|
3
|
-
require 'features/
|
|
4
|
+
require 'features/provider_states/zebras'
|
|
4
5
|
|
|
5
6
|
|
|
6
|
-
module Pact::
|
|
7
|
+
module Pact::Provider
|
|
7
8
|
|
|
8
9
|
describe "A service production side of a pact" do
|
|
9
10
|
|
|
@@ -40,6 +41,7 @@ module Pact::Producer
|
|
|
40
41
|
pact = Pact::ConsumerContract.from_json <<-EOS
|
|
41
42
|
{
|
|
42
43
|
"consumer" : { "name" : "a consumer"},
|
|
44
|
+
"provider" : { "name" : "a provider"},
|
|
43
45
|
"interactions" : [
|
|
44
46
|
{
|
|
45
47
|
"description": "donut creation request",
|
|
@@ -73,12 +75,9 @@ module Pact::Producer
|
|
|
73
75
|
}
|
|
74
76
|
EOS
|
|
75
77
|
|
|
76
|
-
before do
|
|
77
|
-
Pact.
|
|
78
|
-
|
|
79
|
-
name "My Producer"
|
|
80
|
-
app { ServiceUnderTest.new }
|
|
81
|
-
end
|
|
78
|
+
before :all do
|
|
79
|
+
Pact.service_provider "My Provider" do
|
|
80
|
+
app { ServiceUnderTest.new }
|
|
82
81
|
end
|
|
83
82
|
end
|
|
84
83
|
|
|
@@ -86,12 +85,13 @@ module Pact::Producer
|
|
|
86
85
|
|
|
87
86
|
end
|
|
88
87
|
|
|
89
|
-
describe "with a
|
|
88
|
+
describe "with a provider_state" do
|
|
90
89
|
|
|
91
90
|
context "that is a symbol" do
|
|
92
91
|
consumer_contract = Pact::ConsumerContract.from_json <<-EOS
|
|
93
92
|
{
|
|
94
93
|
"consumer" : { "name" : "the-wild-beast-store"},
|
|
94
|
+
"provider" : { "name" : "provider"},
|
|
95
95
|
"interactions" : [
|
|
96
96
|
{
|
|
97
97
|
"description": "donut creation request",
|
|
@@ -103,18 +103,15 @@ module Pact::Producer
|
|
|
103
103
|
"body": {"names": ["Jason", "Sarah"]},
|
|
104
104
|
"status": 200
|
|
105
105
|
},
|
|
106
|
-
"
|
|
106
|
+
"provider_state" : "the_zebras_are_here"
|
|
107
107
|
}
|
|
108
108
|
]
|
|
109
109
|
}
|
|
110
110
|
EOS
|
|
111
111
|
|
|
112
|
-
before do
|
|
113
|
-
Pact.
|
|
114
|
-
|
|
115
|
-
name "My Producer"
|
|
116
|
-
app { ServiceUnderTestWithFixture.new }
|
|
117
|
-
end
|
|
112
|
+
before :all do
|
|
113
|
+
Pact.service_provider "My Provider" do
|
|
114
|
+
app { ServiceUnderTestWithFixture.new }
|
|
118
115
|
end
|
|
119
116
|
end
|
|
120
117
|
|
|
@@ -126,6 +123,7 @@ module Pact::Producer
|
|
|
126
123
|
consumer_contract = Pact::ConsumerContract.from_json <<-EOS
|
|
127
124
|
{
|
|
128
125
|
"consumer" : { "name" : "some consumer"},
|
|
126
|
+
"provider" : { "name" : "provider"},
|
|
129
127
|
"interactions" : [
|
|
130
128
|
{
|
|
131
129
|
"description": "donut creation request",
|
|
@@ -137,18 +135,15 @@ module Pact::Producer
|
|
|
137
135
|
"body": {"names": ["Mark", "Gertrude"]},
|
|
138
136
|
"status": 200
|
|
139
137
|
},
|
|
140
|
-
"
|
|
138
|
+
"provider_state" : "some other zebras are here"
|
|
141
139
|
}
|
|
142
140
|
]
|
|
143
141
|
}
|
|
144
142
|
EOS
|
|
145
143
|
|
|
146
|
-
before do
|
|
147
|
-
Pact.
|
|
148
|
-
|
|
149
|
-
name "ServiceUnderTestWithFixture"
|
|
150
|
-
app { ServiceUnderTestWithFixture.new }
|
|
151
|
-
end
|
|
144
|
+
before :all do
|
|
145
|
+
Pact.service_provider "ServiceUnderTestWithFixture" do
|
|
146
|
+
app { ServiceUnderTestWithFixture.new }
|
|
152
147
|
end
|
|
153
148
|
end
|
|
154
149
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
require 'json'
|
|
2
2
|
require 'fileutils'
|
|
3
3
|
|
|
4
|
-
Pact.
|
|
4
|
+
Pact.provider_states_for 'the-wild-beast-store' do
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
provider_state :the_zebras_are_here do
|
|
7
7
|
set_up do
|
|
8
8
|
FileUtils.mkdir_p 'tmp'
|
|
9
9
|
some_data = [{'name' => 'Jason'},{'name' => 'Sarah'}]
|
|
@@ -16,7 +16,7 @@ Pact.with_consumer 'the-wild-beast-store' do
|
|
|
16
16
|
end
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
Pact.
|
|
19
|
+
Pact.provider_state "some other zebras are here" do
|
|
20
20
|
set_up do
|
|
21
21
|
some_data = [{'name' => 'Mark'},{'name' => 'Gertrude'}]
|
|
22
22
|
File.open("tmp/a_mock_database.json", "w") { |file| file << some_data.to_json }
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'net/http'
|
|
3
|
+
require 'pact/consumer'
|
|
4
|
+
require 'pact/consumer/rspec'
|
|
5
|
+
require 'faraday'
|
|
6
|
+
load 'pact/consumer/world.rb'
|
|
7
|
+
|
|
8
|
+
describe "A service consumer side of a pact", :pact => true do
|
|
9
|
+
|
|
10
|
+
context "with more than one matching interaction found" do
|
|
11
|
+
let(:expected_response) do
|
|
12
|
+
{"message"=>"Multiple interaction found for GET /path", "matching_interactions"=>[{"description"=>"a request", "request"=>{"method"=>"get", "path"=>"/path", "body"=>{"a"=>"some body"}, "headers"=>{"Content-Type"=>"application/json"}}}, {"description"=>"an identical request", "request"=>{"method"=>"get", "path"=>"/path", "body"=>{"a"=>"some body"}, "headers"=>{"Content-Type"=>"application/json"}}}]}
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "returns an error" do
|
|
16
|
+
Pact.clear_configuration
|
|
17
|
+
Pact.clear_consumer_world
|
|
18
|
+
|
|
19
|
+
Pact.service_consumer "Consumer" do
|
|
20
|
+
has_pact_with "Mary Service" do
|
|
21
|
+
mock_service :mary_service do
|
|
22
|
+
verify false
|
|
23
|
+
port 1237
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
mary_service
|
|
29
|
+
.given("something")
|
|
30
|
+
.upon_receiving("a request")
|
|
31
|
+
.with(method: 'get', path: '/path', body: {a: 'some body'}, headers: {'Content-Type' => 'application/json'})
|
|
32
|
+
.will_respond_with(status: 200)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
mary_service
|
|
36
|
+
.upon_receiving("an identical request")
|
|
37
|
+
.with(method: 'get', path: '/path', body: {a: 'some body'}, headers: {'Content-Type' => 'application/json'})
|
|
38
|
+
.will_respond_with(status: 200)
|
|
39
|
+
|
|
40
|
+
uri = URI('http://localhost:1237/path')
|
|
41
|
+
post_req = Net::HTTP::Get.new(uri.path)
|
|
42
|
+
post_req['Content-Type'] = "application/json"
|
|
43
|
+
post_req.body = {a: "some body"}.to_json
|
|
44
|
+
response = Net::HTTP.start(uri.hostname, uri.port) do |http|
|
|
45
|
+
http.request post_req
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
expect(JSON.load(response.body)).to eq expected_response
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
context "with no matching interaction found" do
|
|
54
|
+
|
|
55
|
+
let(:expected_response) do
|
|
56
|
+
{
|
|
57
|
+
"message"=>"No interaction found for GET /path",
|
|
58
|
+
"interaction_diffs"=>[{
|
|
59
|
+
"description" => "a request that will not be properly matched",
|
|
60
|
+
"provider_state" => "something",
|
|
61
|
+
"body"=>{
|
|
62
|
+
"a"=>{
|
|
63
|
+
"EXPECTED"=>"some body",
|
|
64
|
+
"ACTUAL"=>"not matching body"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}]
|
|
68
|
+
}
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "returns an error" do
|
|
72
|
+
Pact.clear_configuration
|
|
73
|
+
|
|
74
|
+
Pact.service_consumer "Consumer" do
|
|
75
|
+
has_pact_with "Mary Service" do
|
|
76
|
+
mock_service :mary_service do
|
|
77
|
+
verify false
|
|
78
|
+
port 1236
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
mary_service
|
|
84
|
+
.given("something")
|
|
85
|
+
.upon_receiving("a request that will not be properly matched")
|
|
86
|
+
.with(method: 'get', path: '/path', body: {a: 'some body'}, headers: {'Content-Type' => 'application/json'})
|
|
87
|
+
.will_respond_with(status: 200)
|
|
88
|
+
|
|
89
|
+
uri = URI('http://localhost:1236/path')
|
|
90
|
+
post_req = Net::HTTP::Get.new(uri.path)
|
|
91
|
+
post_req['Content-Type'] = "application/json"
|
|
92
|
+
post_req.body = {a: "not matching body"}.to_json
|
|
93
|
+
response = Net::HTTP.start(uri.hostname, uri.port) do |http|
|
|
94
|
+
http.request post_req
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
expect(JSON.load(response.body)).to eq expected_response
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
context "with a provider state" do
|
|
102
|
+
before do
|
|
103
|
+
Pact.clear_configuration
|
|
104
|
+
|
|
105
|
+
Pact.service_consumer "Consumer" do
|
|
106
|
+
has_pact_with "Zebra Service" do
|
|
107
|
+
mock_service :zebra_service do
|
|
108
|
+
verify false
|
|
109
|
+
port 1235
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
let(:body) { 'That is some good Mallory.' }
|
|
116
|
+
|
|
117
|
+
it "goes like this" do
|
|
118
|
+
zebra_service.
|
|
119
|
+
given(:the_zebras_are_here).
|
|
120
|
+
upon_receiving("a retrieve Mallory request").with({
|
|
121
|
+
method: :get,
|
|
122
|
+
path: '/mallory',
|
|
123
|
+
headers: {'Accept' => 'text/html'}
|
|
124
|
+
}).
|
|
125
|
+
will_respond_with({
|
|
126
|
+
status: 200,
|
|
127
|
+
headers: { 'Content-Type' => 'text/html' },
|
|
128
|
+
body: Pact::Term.new(matcher: /Mallory/, generate: body)
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
response = Faraday.get(zebra_service.mock_service_base_url + "/mallory", nil, {'Accept' => 'text/html'})
|
|
132
|
+
expect(response.body).to eq body
|
|
133
|
+
|
|
134
|
+
interactions = Pact::ConsumerContract.from_json(zebra_service.write_pact).interactions
|
|
135
|
+
expect(interactions.first.provider_state).to eq("the_zebras_are_here")
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
context "with multiple headers" do
|
|
140
|
+
before do
|
|
141
|
+
Pact.clear_configuration
|
|
142
|
+
Pact.service_consumer "Consumer" do
|
|
143
|
+
has_pact_with "Multi Headers Service" do
|
|
144
|
+
mock_service :multi_headers_service do
|
|
145
|
+
verify true
|
|
146
|
+
port 1240
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
multi_headers_service.
|
|
152
|
+
given("there are multiple headers").
|
|
153
|
+
upon_receiving("a request with multiple headers").
|
|
154
|
+
with(method: :get, path: '/something', headers: {'X-Something' => "1, 2"}).
|
|
155
|
+
will_respond_with(status: 200)
|
|
156
|
+
|
|
157
|
+
uri = URI('http://localhost:1240/something')
|
|
158
|
+
post_req = Net::HTTP::Get.new(uri.path)
|
|
159
|
+
post_req.add_field('X-Something', '1')
|
|
160
|
+
post_req.add_field('X-Something', '2')
|
|
161
|
+
response = Net::HTTP.start(uri.hostname, uri.port) do |http|
|
|
162
|
+
http.request post_req
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
it "handles multiple headers with the same name in a comma separated list" do
|
|
167
|
+
interactions = Pact::ConsumerContract.from_json(multi_headers_service.write_pact).interactions
|
|
168
|
+
expect(interactions.first.request.headers['X-Something']).to eq("1, 2")
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
context "with a async interaction with provider" do
|
|
174
|
+
before do
|
|
175
|
+
Pact.clear_configuration
|
|
176
|
+
|
|
177
|
+
Pact.service_consumer "Consumer" do
|
|
178
|
+
has_pact_with "Zebra Service" do
|
|
179
|
+
mock_service :zebra_service do
|
|
180
|
+
verify true
|
|
181
|
+
port 1239
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
it "goes like this" do
|
|
188
|
+
zebra_service.
|
|
189
|
+
given(:the_zebras_are_here).
|
|
190
|
+
upon_receiving("a retrieve Mallory request").
|
|
191
|
+
with({
|
|
192
|
+
method: :get,
|
|
193
|
+
path: '/mallory'
|
|
194
|
+
}).
|
|
195
|
+
will_respond_with({status: 200})
|
|
196
|
+
|
|
197
|
+
async_interaction { Net::HTTP.get_response(URI('http://localhost:1239/mallory'))}
|
|
198
|
+
|
|
199
|
+
zebra_service.wait_for_interactions wait_max_seconds: 1, poll_interval: 0.1
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def async_interaction
|
|
203
|
+
Thread.new do
|
|
204
|
+
sleep 0.2
|
|
205
|
+
yield
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
end
|
|
212
|
+
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'pact/configuration'
|
|
3
|
+
require 'pact/consumer/configuration'
|
|
4
|
+
|
|
5
|
+
describe "consumer side" do
|
|
6
|
+
describe "configure" do
|
|
7
|
+
|
|
8
|
+
class TestHelper
|
|
9
|
+
include Pact::Consumer::ConsumerContractBuilders
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
let(:application) { double("App")}
|
|
13
|
+
let(:world) { Pact::Consumer::World.new }
|
|
14
|
+
|
|
15
|
+
before do
|
|
16
|
+
Pact.clear_configuration
|
|
17
|
+
Pact::Consumer::AppManager.instance.clear_all
|
|
18
|
+
# Don't want processes actually spawning
|
|
19
|
+
allow_any_instance_of(Pact::Consumer::AppRegistration).to receive(:spawn)
|
|
20
|
+
allow(Pact).to receive(:consumer_world).and_return(world)
|
|
21
|
+
|
|
22
|
+
my_app = application
|
|
23
|
+
|
|
24
|
+
Pact.service_consumer "My Consumer" do
|
|
25
|
+
app my_app
|
|
26
|
+
port 1111
|
|
27
|
+
|
|
28
|
+
has_pact_with "My Service" do
|
|
29
|
+
mock_service :my_service do
|
|
30
|
+
port 1234
|
|
31
|
+
standalone true
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
has_pact_with "My Other Service" do
|
|
36
|
+
mock_service :my_other_service do
|
|
37
|
+
port 1235
|
|
38
|
+
standalone false
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
describe "providers" do
|
|
46
|
+
|
|
47
|
+
subject { TestHelper.new.my_service }
|
|
48
|
+
|
|
49
|
+
it "should have defined methods in MockServices for the providers" do
|
|
50
|
+
expect(subject).to be_instance_of(Pact::Consumer::ConsumerContractBuilder)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
context "when standalone is true" do
|
|
54
|
+
it "is not registerd with the AppManager" do
|
|
55
|
+
expect(Pact::Consumer::AppManager.instance.app_registered_on?(1234)).to eq false
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
context "when standalone is false" do
|
|
60
|
+
it "should register the MockServices on their given ports if they are not" do
|
|
61
|
+
expect(Pact::Consumer::AppManager.instance.app_registered_on?(1235)).to eq true
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'pact/provider/rspec'
|
|
3
|
+
|
|
4
|
+
describe "provider side" do
|
|
5
|
+
describe "configure" do
|
|
6
|
+
|
|
7
|
+
class TestHelper
|
|
8
|
+
include Pact::Provider::RSpec::InstanceMethods
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
let(:application) { double("App")}
|
|
12
|
+
|
|
13
|
+
before do
|
|
14
|
+
app_block = ->{ application }
|
|
15
|
+
Pact.service_provider "My Provider" do
|
|
16
|
+
app &app_block
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "makes the app available to the tests" do
|
|
21
|
+
expect(TestHelper.new.app).to be(application)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'pact/cli'
|
|
3
|
+
|
|
4
|
+
module Pact
|
|
5
|
+
describe SpecCriteria do
|
|
6
|
+
|
|
7
|
+
describe "#spec_criteria" do
|
|
8
|
+
|
|
9
|
+
let(:env_description) { "pact description set in ENV"}
|
|
10
|
+
let(:env_provider_state) { "provider state set in ENV"}
|
|
11
|
+
let(:env_criteria){ {:description=>/#{env_description}/, :provider_state=>/#{env_provider_state}/} }
|
|
12
|
+
|
|
13
|
+
let(:defaults) { {:description => default_description, :provider_state => default_provider_state} }
|
|
14
|
+
|
|
15
|
+
let(:subject) { Pact::App.new }
|
|
16
|
+
|
|
17
|
+
context "when ENV variables are defined" do
|
|
18
|
+
before do
|
|
19
|
+
allow(ENV).to receive(:[])
|
|
20
|
+
allow(ENV).to receive(:[]).with("PACT_DESCRIPTION").and_return(env_description)
|
|
21
|
+
allow(ENV).to receive(:[]).with("PACT_PROVIDER_STATE").and_return(env_provider_state)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "returns the env vars as regexes" do
|
|
25
|
+
expect(SpecCriteria.call).to eq(env_criteria)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
context "when ENV variables are not defined" do
|
|
30
|
+
it "returns an empty hash" do
|
|
31
|
+
expect(SpecCriteria.call).to eq({})
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
context "when provider state is an empty string" do
|
|
36
|
+
before do
|
|
37
|
+
allow(ENV).to receive(:[]).with(anything).and_return(nil)
|
|
38
|
+
allow(ENV).to receive(:[]).with("PACT_PROVIDER_STATE").and_return('')
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "returns a nil provider state so that it matches a nil provider state on the interaction" do
|
|
42
|
+
expect(SpecCriteria.call[:provider_state]).to be_nil
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|