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
data/lib/pact/consumer.rb
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
require 'pact/consumer_contract'
|
|
2
|
+
require 'pact/consumer/configuration'
|
|
3
|
+
require 'pact/consumer/consumer_contract_builder'
|
|
4
|
+
require 'pact/consumer/consumer_contract_builders'
|
|
5
|
+
require 'pact/consumer/interaction_builder'
|
|
6
|
+
require 'pact/consumer/mock_service'
|
|
7
|
+
require 'pact/consumer/mock_service_client'
|
|
8
|
+
require 'pact/consumer/app_manager'
|
|
9
|
+
require 'pact/term'
|
|
10
|
+
require 'pact/something_like'
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
require 'pact/logging'
|
|
2
|
+
require 'pact/something_like'
|
|
3
|
+
require 'pact/symbolize_keys'
|
|
4
|
+
require 'pact/term'
|
|
5
|
+
require 'pact/version'
|
|
6
|
+
require 'pact/shared/active_support_support'
|
|
7
|
+
require 'date'
|
|
8
|
+
require 'json/add/regexp'
|
|
9
|
+
require 'open-uri'
|
|
10
|
+
require_relative 'service_consumer'
|
|
11
|
+
require_relative 'service_provider'
|
|
12
|
+
require_relative 'interaction'
|
|
13
|
+
require_relative 'request'
|
|
14
|
+
require_relative 'pact_file'
|
|
15
|
+
require_relative 'file_name'
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
module Pact
|
|
20
|
+
|
|
21
|
+
class ConsumerContract
|
|
22
|
+
|
|
23
|
+
include SymbolizeKeys
|
|
24
|
+
include Logging
|
|
25
|
+
include FileName
|
|
26
|
+
include ActiveSupportSupport
|
|
27
|
+
|
|
28
|
+
attr_accessor :interactions
|
|
29
|
+
attr_accessor :consumer
|
|
30
|
+
attr_accessor :provider
|
|
31
|
+
|
|
32
|
+
def initialize(attributes = {})
|
|
33
|
+
@interactions = attributes[:interactions] || []
|
|
34
|
+
@consumer = attributes[:consumer]
|
|
35
|
+
@provider = attributes[:provider]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def to_hash
|
|
39
|
+
{
|
|
40
|
+
provider: @provider.as_json,
|
|
41
|
+
consumer: @consumer.as_json,
|
|
42
|
+
interactions: @interactions.collect(&:as_json),
|
|
43
|
+
metadata: {
|
|
44
|
+
pactSpecificationVersion: "1.0.0"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def as_json(options = {})
|
|
50
|
+
fix_all_the_things to_hash
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def to_json(options = {})
|
|
54
|
+
as_json.to_json(options)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def self.from_hash(hash)
|
|
58
|
+
hash = symbolize_keys(hash)
|
|
59
|
+
new({
|
|
60
|
+
:interactions => hash[:interactions].collect { |hash| Interaction.from_hash(hash)},
|
|
61
|
+
:consumer => ServiceConsumer.from_hash(hash[:consumer]),
|
|
62
|
+
:provider => ServiceProvider.from_hash(hash[:provider])
|
|
63
|
+
})
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def self.from_json string
|
|
67
|
+
deserialised_object = JSON.load(maintain_backwards_compatiblity_with_producer_keys(string))
|
|
68
|
+
from_hash(deserialised_object)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def self.from_uri uri, options = {}
|
|
72
|
+
from_json(Pact::PactFile.read(uri, options))
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def self.maintain_backwards_compatiblity_with_producer_keys string
|
|
76
|
+
string.gsub('"producer":', '"provider":').gsub('"producer_state":', '"provider_state":')
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def find_interaction criteria
|
|
80
|
+
interactions = find_interactions criteria
|
|
81
|
+
if interactions.size == 0
|
|
82
|
+
raise "Could not find interaction matching #{criteria} in pact file between #{consumer.name} and #{provider.name}."
|
|
83
|
+
elsif interactions.size > 1
|
|
84
|
+
raise "Found more than 1 interaction matching #{criteria} in pact file between #{consumer.name} and #{provider.name}."
|
|
85
|
+
end
|
|
86
|
+
interactions.first
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def find_interactions criteria
|
|
90
|
+
interactions.select{ | interaction| interaction.matches_criteria?(criteria)}
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def each
|
|
94
|
+
interactions.each do | interaction |
|
|
95
|
+
yield interaction
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def pact_file_name
|
|
100
|
+
file_name consumer.name, provider.name
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def pactfile_path
|
|
104
|
+
raise 'You must first specify a consumer and service name' unless (consumer && consumer.name && provider && provider.name)
|
|
105
|
+
@pactfile_path ||= file_path consumer.name, provider.name
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def update_pactfile
|
|
109
|
+
logger.debug "Updating pact file for #{provider.name} at #{pactfile_path}"
|
|
110
|
+
File.open(pactfile_path, 'w') do |f|
|
|
111
|
+
f.write fix_json_formatting(JSON.pretty_generate(self))
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
require 'pact/consumer_contract'
|
|
2
|
+
require 'pact/consumer/interactions_filter'
|
|
3
|
+
require 'pact/consumer_contract/file_name'
|
|
4
|
+
|
|
5
|
+
module Pact
|
|
6
|
+
|
|
7
|
+
class ConsumerContractWriter
|
|
8
|
+
|
|
9
|
+
attr_reader :consumer_contract_details, :pactfile_write_mode, :interactions, :logger
|
|
10
|
+
|
|
11
|
+
def initialize consumer_contract_details, logger
|
|
12
|
+
@logger = logger
|
|
13
|
+
@consumer_contract_details = consumer_contract_details
|
|
14
|
+
@pactfile_write_mode = consumer_contract_details.fetch(:pactfile_write_mode, :overwrite).to_sym
|
|
15
|
+
@interactions = consumer_contract_details.fetch(:interactions)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def consumer_contract
|
|
19
|
+
@consumer_contract ||= Pact::ConsumerContract.new(
|
|
20
|
+
consumer: ServiceConsumer.new(name: consumer_contract_details[:consumer][:name]),
|
|
21
|
+
provider: ServiceProvider.new(name: consumer_contract_details[:provider][:name]),
|
|
22
|
+
interactions: interactions_for_new_consumer_contract)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def write
|
|
26
|
+
consumer_contract.update_pactfile
|
|
27
|
+
consumer_contract.to_json
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def interactions_for_new_consumer_contract
|
|
31
|
+
if pactfile_write_mode == :update
|
|
32
|
+
merged_interactions = existing_interactions
|
|
33
|
+
filter = Consumer::UpdatableInteractionsFilter.new(merged_interactions)
|
|
34
|
+
interactions.each {|i| filter << i }
|
|
35
|
+
merged_interactions
|
|
36
|
+
else
|
|
37
|
+
interactions
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def existing_interactions
|
|
42
|
+
interactions = []
|
|
43
|
+
if pactfile_exists?
|
|
44
|
+
begin
|
|
45
|
+
interactions = existing_consumer_contract.interactions
|
|
46
|
+
info_and_puts "*****************************************************************************"
|
|
47
|
+
info_and_puts "Updating existing file .#{pactfile_path.gsub(Dir.pwd, '')} as config.pactfile_write_mode is :update"
|
|
48
|
+
info_and_puts "Only interactions defined in this test run will be updated."
|
|
49
|
+
info_and_puts "As interactions are identified by description and provider state, pleased note that if either of these have changed, the old interactions won't be removed from the pact file until the specs are next run with :pactfile_write_mode => :overwrite."
|
|
50
|
+
info_and_puts "*****************************************************************************"
|
|
51
|
+
rescue StandardError => e
|
|
52
|
+
warn_and_stderr "Could not load existing consumer contract from #{pactfile_path} due to #{e}"
|
|
53
|
+
logger.error e
|
|
54
|
+
logger.error e.backtrace
|
|
55
|
+
warn_and_stderr "Creating a new file."
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
interactions
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def pactfile_exists?
|
|
62
|
+
File.exist?(pactfile_path)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def pactfile_path
|
|
66
|
+
Pact::FileName.file_path consumer_contract_details[:consumer][:name], consumer_contract_details[:provider][:name]
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def existing_consumer_contract
|
|
70
|
+
Pact::ConsumerContract.from_uri(pactfile_path)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def warn_and_stderr msg
|
|
74
|
+
Pact.configuration.error_stream.puts msg
|
|
75
|
+
logger.warn msg
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def info_and_puts msg
|
|
79
|
+
$stdout.puts msg
|
|
80
|
+
logger.info msg
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Pact
|
|
2
|
+
|
|
3
|
+
module FileName
|
|
4
|
+
|
|
5
|
+
extend self
|
|
6
|
+
|
|
7
|
+
def file_name consumer_name, provider_name
|
|
8
|
+
"#{filenamify(consumer_name)}-#{filenamify(provider_name)}.json"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def file_path consumer_name, provider_name, pact_dir = Pact.configuration.pact_dir
|
|
12
|
+
File.join(pact_dir, file_name(consumer_name, provider_name))
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def filenamify name
|
|
16
|
+
name.downcase.gsub(/\s/, '_')
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module Pact
|
|
2
|
+
|
|
3
|
+
class DuplicateHeaderError < StandardError; end
|
|
4
|
+
class InvalidHeaderNameTypeError < StandardError; end
|
|
5
|
+
|
|
6
|
+
class Headers < Hash
|
|
7
|
+
|
|
8
|
+
def initialize hash = {}
|
|
9
|
+
hash.each_pair do | key, value |
|
|
10
|
+
check_for_invalid key
|
|
11
|
+
self[find_matching_key(key)] = value
|
|
12
|
+
end
|
|
13
|
+
self.freeze
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def [] key
|
|
17
|
+
super(find_matching_key(key))
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def fetch *args, &block
|
|
21
|
+
args[0] = find_matching_key(args[0]) if args.first
|
|
22
|
+
super(*args, &block)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def key? key
|
|
26
|
+
super(find_matching_key(key))
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
alias_method :has_key?, :key?
|
|
30
|
+
alias_method :include?, :key?
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def find_matching_key key
|
|
35
|
+
key = key.to_s
|
|
36
|
+
match = keys.find { |k| k.downcase == key.downcase }
|
|
37
|
+
match.nil? ? key : match
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def check_for_invalid key
|
|
41
|
+
unless (String === key || Symbol === key)
|
|
42
|
+
raise InvalidHeaderNameTypeError.new "Header name (#{key}) must be a String or a Symbol."
|
|
43
|
+
end
|
|
44
|
+
if key? key
|
|
45
|
+
raise DuplicateHeaderError.new "Duplicate header found (#{find_matching_key(key)} and #{key}. Please use a comma separated single value when multiple headers with the same name are required."
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
require 'pact/consumer_contract/request'
|
|
2
|
+
require 'pact/symbolize_keys'
|
|
3
|
+
require 'pact/shared/active_support_support'
|
|
4
|
+
|
|
5
|
+
module Pact
|
|
6
|
+
class Interaction
|
|
7
|
+
include ActiveSupportSupport
|
|
8
|
+
include SymbolizeKeys
|
|
9
|
+
|
|
10
|
+
attr_accessor :description, :request, :response, :provider_state
|
|
11
|
+
|
|
12
|
+
def initialize attributes = {}
|
|
13
|
+
@description = attributes[:description]
|
|
14
|
+
@request = attributes[:request]
|
|
15
|
+
@response = attributes[:response]
|
|
16
|
+
@provider_state = attributes[:provider_state] || attributes[:providerState]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.from_hash hash
|
|
20
|
+
request = Pact::Request::Expected.from_hash(hash['request'])
|
|
21
|
+
new(symbolize_keys(hash).merge({request: request}))
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def to_hash
|
|
25
|
+
hash = { :description => @description }
|
|
26
|
+
hash[:provider_state] = @provider_state if @provider_state #Easier to read when provider state at top
|
|
27
|
+
hash.merge(:request => @request.as_json, :response => @response)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def as_json options = {}
|
|
31
|
+
fix_all_the_things to_hash
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def to_json(options = {})
|
|
35
|
+
as_json.to_json(options)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def matches_criteria? criteria
|
|
39
|
+
criteria.each do | key, value |
|
|
40
|
+
unless match_criterion self.send(key.to_s), value
|
|
41
|
+
return false
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
true
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def match_criterion target, criterion
|
|
48
|
+
target == criterion || (criterion.is_a?(Regexp) && criterion.match(target))
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def == other
|
|
52
|
+
other.is_a?(Interaction) && as_json == other.as_json
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def eq? other
|
|
56
|
+
self == other
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def description_with_provider_state_quoted
|
|
60
|
+
provider_state ? "\"#{description}\" given \"#{provider_state}\"" : "\"#{description}\""
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def to_s
|
|
64
|
+
JSON.pretty_generate(self)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Pact
|
|
2
|
+
|
|
3
|
+
module PactFile
|
|
4
|
+
|
|
5
|
+
extend self
|
|
6
|
+
|
|
7
|
+
def read uri, options = {}
|
|
8
|
+
pact = open(uri.to_s) { | file | file.read }
|
|
9
|
+
if options[:save_pactfile_to_tmp]
|
|
10
|
+
save_pactfile_to_tmp pact, ::File.basename(uri.to_s)
|
|
11
|
+
end
|
|
12
|
+
pact
|
|
13
|
+
rescue StandardError => e
|
|
14
|
+
$stderr.puts "Error reading file from #{uri}"
|
|
15
|
+
$stderr.puts "#{e.to_s} #{e.backtrace.join("\n")}"
|
|
16
|
+
raise e
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def save_pactfile_to_tmp pact, name
|
|
20
|
+
::FileUtils.mkdir_p Pact.configuration.tmp_dir
|
|
21
|
+
::File.open(Pact.configuration.tmp_dir + "/#{name}", "w") { |file| file << pact}
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
require 'pact/shared/request'
|
|
2
|
+
require 'pact/shared/null_expectation'
|
|
3
|
+
|
|
4
|
+
module Pact
|
|
5
|
+
|
|
6
|
+
module Request
|
|
7
|
+
|
|
8
|
+
class Expected < Pact::Request::Base
|
|
9
|
+
|
|
10
|
+
DEFAULT_OPTIONS = {:allow_unexpected_keys => false}.freeze
|
|
11
|
+
attr_accessor :options #Temporary hack
|
|
12
|
+
|
|
13
|
+
def self.from_hash(hash)
|
|
14
|
+
sym_hash = symbolize_keys hash
|
|
15
|
+
method = sym_hash.fetch(:method)
|
|
16
|
+
path = sym_hash.fetch(:path)
|
|
17
|
+
query = sym_hash.fetch(:query, key_not_found)
|
|
18
|
+
headers = sym_hash.fetch(:headers, key_not_found)
|
|
19
|
+
body = sym_hash.fetch(:body, key_not_found)
|
|
20
|
+
options = sym_hash.fetch(:options, {})
|
|
21
|
+
new(method, path, headers, body, query, options)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def initialize(method, path, headers, body, query, options = {})
|
|
25
|
+
super(method, path, headers, body, query)
|
|
26
|
+
@options = options
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def matches?(actual_request)
|
|
30
|
+
difference(actual_request).empty?
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def matches_route? actual_request
|
|
34
|
+
diff({:method => method, :path => path}, {:method => actual_request.method, :path => actual_request.path}).empty?
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def difference(actual_request)
|
|
38
|
+
request_diff = diff(to_hash_without_body, actual_request.to_hash_without_body)
|
|
39
|
+
unless body.is_a? NullExpectation
|
|
40
|
+
request_diff.merge(body_difference(actual_request.body))
|
|
41
|
+
else
|
|
42
|
+
request_diff
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
protected
|
|
47
|
+
|
|
48
|
+
def self.key_not_found
|
|
49
|
+
Pact::NullExpectation.new
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
# Options is a dirty hack to allow Condor to send extra keys in the request,
|
|
55
|
+
# as it's too much work to set up an exactly matching expectation.
|
|
56
|
+
# Need to implement a proper matching strategy and remove this.
|
|
57
|
+
# Do not rely on it!
|
|
58
|
+
def runtime_options
|
|
59
|
+
DEFAULT_OPTIONS.merge(symbolize_keys(options))
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def body_difference(actual_body)
|
|
63
|
+
body_differ.call({:body => body}, {body: actual_body}, allow_unexpected_keys: runtime_options[:allow_unexpected_keys_in_body])
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def body_differ
|
|
67
|
+
Pact.configuration.body_differ_for_content_type content_type
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'pact/symbolize_keys'
|
|
2
|
+
|
|
3
|
+
module Pact
|
|
4
|
+
class ServiceConsumer
|
|
5
|
+
include SymbolizeKeys
|
|
6
|
+
|
|
7
|
+
attr_accessor :name
|
|
8
|
+
def initialize options
|
|
9
|
+
@name = options[:name]
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def to_s
|
|
13
|
+
name
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def to_hash
|
|
17
|
+
{name: name}
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def as_json options = {}
|
|
21
|
+
to_hash
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.from_hash hash
|
|
25
|
+
new(symbolize_keys(hash))
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'pact/symbolize_keys'
|
|
2
|
+
|
|
3
|
+
module Pact
|
|
4
|
+
class ServiceProvider
|
|
5
|
+
include SymbolizeKeys
|
|
6
|
+
|
|
7
|
+
attr_accessor :name
|
|
8
|
+
def initialize options
|
|
9
|
+
@name = options[:name] || '[provider name unknown - please update the pact gem in the consumer project to the latest version and regenerate the pacts]'
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def to_s
|
|
13
|
+
name
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def to_hash
|
|
17
|
+
{name: name}
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def as_json options = {}
|
|
21
|
+
to_hash
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.from_hash hash
|
|
25
|
+
new(symbolize_keys(hash))
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -1,110 +1 @@
|
|
|
1
|
-
require 'pact/
|
|
2
|
-
require 'pact/consumer/service_producer'
|
|
3
|
-
require 'pact/consumer/interaction'
|
|
4
|
-
require 'pact/logging'
|
|
5
|
-
require 'pact/json_warning'
|
|
6
|
-
require 'date'
|
|
7
|
-
|
|
8
|
-
module Pact
|
|
9
|
-
class ConsumerContract
|
|
10
|
-
|
|
11
|
-
include Pact::Logging
|
|
12
|
-
include Pact::JsonWarning
|
|
13
|
-
|
|
14
|
-
attr_accessor :interactions
|
|
15
|
-
attr_accessor :consumer
|
|
16
|
-
attr_accessor :producer
|
|
17
|
-
|
|
18
|
-
def initialize(attributes = {})
|
|
19
|
-
@interactions = attributes[:interactions] || []
|
|
20
|
-
@consumer = attributes[:consumer]
|
|
21
|
-
@producer = attributes[:producer]
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def as_json(options = {})
|
|
25
|
-
{
|
|
26
|
-
producer: @producer.as_json,
|
|
27
|
-
consumer: @consumer.as_json,
|
|
28
|
-
interactions: @interactions.collect(&:as_json),
|
|
29
|
-
metadata: {
|
|
30
|
-
pact_gem: {
|
|
31
|
-
version: Pact::VERSION
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def to_json(options = {})
|
|
38
|
-
as_json(options).to_json(options)
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def self.from_hash(obj)
|
|
42
|
-
new({
|
|
43
|
-
:interactions => obj['interactions'].collect { |hash| Pact::Consumer::Interaction.from_hash(hash)},
|
|
44
|
-
:consumer => Pact::Consumer::ServiceConsumer.from_hash(obj['consumer']),
|
|
45
|
-
:producer => Pact::Consumer::ServiceProducer.from_hash(obj['producer'] || {})
|
|
46
|
-
})
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def self.from_json string
|
|
50
|
-
deserialised_object = JSON.load(string)
|
|
51
|
-
from_hash(deserialised_object)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def find_interaction criteria
|
|
55
|
-
interactions = find_interactions criteria
|
|
56
|
-
if interactions.size == 0
|
|
57
|
-
raise "Could not find interaction matching #{criteria} in pact file between #{consumer.name} and #{producer.name}."
|
|
58
|
-
elsif interactions.size > 1
|
|
59
|
-
raise "Found more than 1 interaction matching #{criteria} in pact file between #{consumer.name} and #{producer.name}."
|
|
60
|
-
end
|
|
61
|
-
interactions.first
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def find_interactions criteria
|
|
65
|
-
interactions.select{ | interaction| match_criteria? interaction, criteria}
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def each
|
|
69
|
-
interactions.each do | interaction |
|
|
70
|
-
yield interaction
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def match_criteria? interaction, criteria
|
|
75
|
-
criteria.each do | key, value |
|
|
76
|
-
unless match_criterion interaction[key.to_s], value
|
|
77
|
-
return false
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
true
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def match_criterion target, criterion
|
|
84
|
-
target == criterion || (criterion.is_a?(Regexp) && criterion.match(target))
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def pact_file_name
|
|
88
|
-
"#{filenamify(consumer.name)}-#{filenamify(producer.name)}.json"
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
def pactfile_path
|
|
92
|
-
raise 'You must first specify a consumer and service name' unless (consumer && consumer.name && producer && producer.name)
|
|
93
|
-
@pactfile_path ||= File.join(Pact.configuration.pact_dir, pact_file_name)
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
def update_pactfile
|
|
97
|
-
logger.debug "Updating pact file for #{producer.name} at #{pactfile_path}"
|
|
98
|
-
check_for_active_support_json
|
|
99
|
-
File.open(pactfile_path, 'w') do |f|
|
|
100
|
-
f.write JSON.pretty_generate(self)
|
|
101
|
-
end
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
private
|
|
105
|
-
|
|
106
|
-
def filenamify name
|
|
107
|
-
name.downcase.gsub(/\s/, '_')
|
|
108
|
-
end
|
|
109
|
-
end
|
|
110
|
-
end
|
|
1
|
+
require 'pact/consumer_contract/consumer_contract'
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Pact
|
|
2
|
+
module Doc
|
|
3
|
+
|
|
4
|
+
class DocFile
|
|
5
|
+
|
|
6
|
+
def initialize consumer_contract, dir, consumer_contract_renderer, file_extension
|
|
7
|
+
@dir = dir
|
|
8
|
+
@consumer_contract = consumer_contract
|
|
9
|
+
@consumer_contract_renderer = consumer_contract_renderer
|
|
10
|
+
@file_extension = file_extension
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def write
|
|
14
|
+
File.open(path, "w") { |io| io << doc_file_contents }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def title
|
|
18
|
+
consumer_contract.provider.name
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def name
|
|
22
|
+
"#{consumer_contract.consumer.name} - #{consumer_contract.provider.name}#{file_extension}"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
attr_reader :dir, :consumer_contract, :consumer_contract_renderer, :file_extension
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def path
|
|
31
|
+
File.join(dir, name)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def doc_file_contents
|
|
35
|
+
consumer_contract_renderer.call(consumer_contract)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module Pact
|
|
2
|
+
module Doc
|
|
3
|
+
class Generate
|
|
4
|
+
|
|
5
|
+
def self.call pact_dir = Pact.configuration.pact_dir, doc_dir = Pact.configuration.doc_dir, doc_generators = Pact.configuration.doc_generators
|
|
6
|
+
doc_generators.each{| doc_generator| doc_generator.call pact_dir, doc_dir }
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|