pact 1.1.0.rc2 → 1.1.0.rc3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +0 -1
- data/CHANGELOG.md +46 -1
- data/Gemfile.lock +6 -4
- data/README.md +40 -186
- data/Rakefile +1 -1
- data/documentation/README.md +10 -0
- data/documentation/best-practices.md +33 -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/documentation/faq.md +36 -6
- data/documentation/provider-states.md +173 -0
- data/documentation/raq.md +4 -4
- data/documentation/terminology.md +2 -2
- data/example/animal-service/Gemfile.lock +6 -9
- data/example/animal-service/Rakefile +2 -0
- data/example/animal-service/db/animal_db.sqlite3 +0 -0
- data/example/animal-service/lib/animal_service/animal_repository.rb +1 -5
- data/example/animal-service/lib/animal_service/api.rb +1 -1
- data/example/animal-service/spec/service_consumers/pact_helper.rb +7 -10
- data/example/animal-service/spec/service_consumers/provider_states_for_zoo_app.rb +5 -1
- data/example/zoo-app/Gemfile.lock +6 -9
- data/example/zoo-app/Rakefile +5 -0
- data/example/zoo-app/doc/markdown/README.md +3 -0
- data/example/zoo-app/doc/markdown/Zoo App - Animal Service.md +75 -0
- data/example/zoo-app/lib/zoo_app/animal_service_client.rb +2 -2
- data/example/zoo-app/spec/pacts/zoo_app-animal_service.json +1 -1
- data/example/zoo-app/spec/service_providers/animal_service_client_spec.rb +29 -34
- data/example/zoo-app/spec/service_providers/pact_helper.rb +4 -0
- data/lib/pact/configuration.rb +49 -1
- data/lib/pact/consumer/configuration.rb +4 -172
- 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 +89 -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/mock_service/interaction_mismatch.rb +3 -3
- data/lib/pact/consumer/mock_service/interaction_post.rb +2 -2
- data/lib/pact/consumer/mock_service/interaction_replay.rb +3 -4
- data/lib/pact/consumer/mock_service/verification_get.rb +32 -13
- data/lib/pact/consumer/rspec.rb +2 -4
- data/lib/pact/consumer/spec_hooks.rb +3 -1
- data/lib/pact/consumer_contract/consumer_contract.rb +1 -1
- data/lib/pact/consumer_contract/interaction.rb +1 -1
- data/lib/pact/doc/doc_file.rb +40 -0
- data/lib/pact/doc/generate.rb +11 -0
- data/lib/pact/doc/generator.rb +81 -0
- data/lib/pact/doc/interaction_view_model.rb +113 -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/markdown/interactions_renderer.rb +56 -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 +150 -0
- data/lib/pact/matchers/difference.rb +5 -30
- 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 +3 -12
- data/lib/pact/matchers/{diff_decorator.rb → list_diff_formatter.rb} +28 -11
- data/lib/pact/matchers/matchers.rb +35 -39
- 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 +3 -13
- data/lib/pact/matchers/unexpected_key.rb +3 -12
- data/lib/pact/matchers/{plus_minus_diff_decorator.rb → unix_diff_formatter.rb} +22 -7
- data/lib/pact/provider/configuration.rb +5 -178
- 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 +54 -0
- data/lib/pact/provider/matchers.rb +21 -13
- data/lib/pact/provider/matchers/messages.rb +43 -0
- data/lib/pact/provider/pact_spec_runner.rb +8 -0
- data/lib/pact/provider/rspec.rb +1 -1
- data/lib/pact/provider/rspec/formatter.rb +9 -7
- data/lib/pact/{consumer_contract → shared}/active_support_support.rb +4 -0
- data/lib/pact/shared/jruby_support.rb +18 -0
- data/lib/pact/shared/key_not_found.rb +3 -16
- data/lib/pact/shared/request.rb +5 -5
- data/lib/pact/term.rb +2 -2
- data/lib/pact/version.rb +1 -1
- data/pact.gemspec +2 -2
- data/spec/integration/pact/provider_configuration_spec.rb +2 -1
- data/spec/lib/pact/configuration_spec.rb +73 -0
- data/spec/lib/pact/consumer/mock_service/interaction_mismatch_spec.rb +21 -3
- data/spec/lib/pact/consumer/mock_service/verification_get_spec.rb +134 -0
- data/spec/lib/pact/consumer/request_spec.rb +1 -1
- data/spec/lib/pact/consumer_contract/active_support_support_spec.rb +1 -1
- data/spec/lib/pact/doc/generator_spec.rb +69 -0
- data/spec/lib/pact/doc/interaction_view_model_spec.rb +112 -0
- data/spec/lib/pact/doc/markdown/index_renderer_spec.rb +29 -0
- data/spec/lib/pact/doc/markdown/interactions_renderer_spec.rb +29 -0
- data/spec/lib/pact/matchers/differ_spec.rb +214 -0
- data/spec/lib/pact/matchers/difference_spec.rb +2 -12
- data/spec/lib/pact/matchers/embedded_diff_formatter_spec.rb +77 -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 +38 -22
- 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/{plus_minus_diff_decorator_spec.rb → unix_diff_formatter_spec.rb} +35 -6
- 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 +92 -0
- data/spec/lib/pact/provider/configuration_spec.rb +7 -150
- data/spec/lib/pact/provider/matchers/messages_spec.rb +104 -0
- data/spec/lib/pact/provider/rspec/formatter_spec.rb +56 -0
- data/spec/lib/pact/shared/key_not_found_spec.rb +20 -0
- data/spec/lib/pact/shared/request_spec.rb +28 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/standalone/consumer_fail_test.rb +54 -0
- data/spec/standalone/consumer_pass_test.rb +50 -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/markdown_pact.json +48 -0
- data/spec/support/pact_helper.rb +2 -1
- data/spec/support/spec_support.rb +7 -0
- data/spec/support/test_app_fail.json +11 -2
- data/tasks/pact-test.rake +9 -0
- metadata +113 -20
- data/example/animal-service/db/animals_db.sqlite3 +0 -0
- data/lib/pact/consumer/rspec/full_example_description.rb +0 -28
- data/lib/pact/matchers/nested_json_diff_decorator.rb +0 -53
- data/spec/lib/pact/matchers/diff_decorator_spec.rb +0 -80
- data/spec/lib/pact/matchers/nested_json_diff_decorator_spec.rb +0 -48
@@ -24,27 +24,46 @@ module Pact
|
|
24
24
|
def respond env
|
25
25
|
if interaction_list.all_matched?
|
26
26
|
logger.info "Verifying - interactions matched for example \"#{example_description(env)}\""
|
27
|
-
[200, {}, ['Interactions matched']]
|
27
|
+
[200, {'Content-Type' => 'text/plain'}, ['Interactions matched']]
|
28
28
|
else
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
error_message
|
34
|
-
#{missing_interactions_summaries.join("\n ")}
|
35
|
-
Incorrect requests:
|
36
|
-
#{interaction_mismatches_summaries.join("\n ")}
|
37
|
-
Unexpected requests:
|
38
|
-
#{unexpected_requests_summaries.join("\n ")}"
|
39
|
-
logger.warn "Verifying - actual interactions do not match expected interactions for example \"#{example_description(env)}\". \n#{error_message}"
|
40
|
-
logger.warn error_message
|
41
|
-
[500, {}, ["Actual interactions do not match expected interactions for mock #{name}.\n#{error_message}\nSee #{log_description} for details."]]
|
30
|
+
error_message = FailureMessage.new(interaction_list).to_s
|
31
|
+
logger.warn "Verifying - actual interactions do not match expected interactions for example \"#{example_description(env)}\". \n#{error_message}"
|
32
|
+
logger.warn error_message
|
33
|
+
[500, {'Content-Type' => 'text/plain'}, ["Actual interactions do not match expected interactions for mock #{name}.\n\n#{error_message}See #{log_description} for details."]]
|
42
34
|
end
|
43
35
|
end
|
44
36
|
|
45
37
|
def example_description env
|
46
38
|
params_hash(env)['example_description']
|
47
39
|
end
|
40
|
+
|
41
|
+
class FailureMessage
|
42
|
+
|
43
|
+
def initialize interaction_list
|
44
|
+
@interaction_list = interaction_list
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_s
|
48
|
+
titles_and_summaries.collect do | title, summaries |
|
49
|
+
"#{title}:\n\t#{summaries.join("\n\t")}\n\n" if summaries.any?
|
50
|
+
end.compact.join
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
attr_reader :interaction_list
|
57
|
+
|
58
|
+
def titles_and_summaries
|
59
|
+
{
|
60
|
+
"Incorrect requests" => interaction_list.interaction_mismatches_summaries,
|
61
|
+
"Missing requests" => interaction_list.missing_interactions_summaries,
|
62
|
+
"Unexpected requests" => interaction_list.unexpected_requests_summaries,
|
63
|
+
}
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
48
67
|
end
|
49
68
|
end
|
50
69
|
end
|
data/lib/pact/consumer/rspec.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'pact/consumer'
|
2
2
|
require 'pact/consumer/spec_hooks'
|
3
|
-
require 'pact/consumer/rspec/full_example_description'
|
4
3
|
|
5
4
|
module Pact
|
6
5
|
module Consumer
|
@@ -12,7 +11,6 @@ end
|
|
12
11
|
|
13
12
|
hooks = Pact::Consumer::SpecHooks.new
|
14
13
|
|
15
|
-
|
16
14
|
RSpec.configure do |config|
|
17
15
|
config.include Pact::Consumer::RSpec, :pact => true
|
18
16
|
|
@@ -21,11 +19,11 @@ RSpec.configure do |config|
|
|
21
19
|
end
|
22
20
|
|
23
21
|
config.before :each, :pact => true do | example |
|
24
|
-
hooks.before_each
|
22
|
+
hooks.before_each example.example.full_description
|
25
23
|
end
|
26
24
|
|
27
25
|
config.after :each, :pact => true do | example |
|
28
|
-
hooks.after_each
|
26
|
+
hooks.after_each example.example.full_description
|
29
27
|
end
|
30
28
|
|
31
29
|
config.after :suite do
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'pact/doc/generate'
|
2
|
+
|
1
3
|
module Pact
|
2
4
|
module Consumer
|
3
5
|
class SpecHooks
|
@@ -22,7 +24,7 @@ module Pact
|
|
22
24
|
end
|
23
25
|
|
24
26
|
def after_suite
|
25
|
-
Pact.
|
27
|
+
Pact::Doc::Generate.call
|
26
28
|
Pact::Consumer::AppManager.instance.kill_all
|
27
29
|
Pact::Consumer::AppManager.instance.clear_all
|
28
30
|
end
|
@@ -3,6 +3,7 @@ require 'pact/something_like'
|
|
3
3
|
require 'pact/symbolize_keys'
|
4
4
|
require 'pact/term'
|
5
5
|
require 'pact/version'
|
6
|
+
require 'pact/shared/active_support_support'
|
6
7
|
require 'date'
|
7
8
|
require 'json/add/regexp'
|
8
9
|
require 'open-uri'
|
@@ -10,7 +11,6 @@ require_relative 'service_consumer'
|
|
10
11
|
require_relative 'service_provider'
|
11
12
|
require_relative 'interaction'
|
12
13
|
require_relative 'request'
|
13
|
-
require_relative 'active_support_support'
|
14
14
|
require_relative 'pact_file'
|
15
15
|
require_relative 'file_name'
|
16
16
|
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Pact
|
2
|
+
module Doc
|
3
|
+
|
4
|
+
class DocFile
|
5
|
+
|
6
|
+
def initialize consumer_contract, dir, interactions_renderer, file_extension
|
7
|
+
@dir = dir
|
8
|
+
@consumer_contract = consumer_contract
|
9
|
+
@interactions_renderer = interactions_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, :interactions_renderer, :file_extension
|
28
|
+
|
29
|
+
|
30
|
+
def path
|
31
|
+
File.join(dir, name)
|
32
|
+
end
|
33
|
+
|
34
|
+
def doc_file_contents
|
35
|
+
interactions_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
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'pact/doc/doc_file'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module Pact
|
5
|
+
module Doc
|
6
|
+
|
7
|
+
class Generator
|
8
|
+
|
9
|
+
def initialize pact_dir, doc_dir, options
|
10
|
+
@doc_dir = doc_dir
|
11
|
+
@pact_dir = pact_dir
|
12
|
+
@interactions_renderer = options[:interactions_renderer]
|
13
|
+
@doc_type = options[:doc_type]
|
14
|
+
@file_extension = options[:file_extension]
|
15
|
+
@index_renderer = options[:index_renderer]
|
16
|
+
@index_name = options[:index_name]
|
17
|
+
@after = options.fetch(:after, lambda{|pact_dir, target_dir, consumer_contracts| })
|
18
|
+
end
|
19
|
+
|
20
|
+
def call
|
21
|
+
ensure_target_dir_exists
|
22
|
+
write_index if consumer_contracts.any?
|
23
|
+
write_doc_files
|
24
|
+
perform_after_hook
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
attr_reader :doc_dir, :pact_dir, :interactions_renderer, :doc_type, :file_extension, :index_renderer, :after
|
30
|
+
|
31
|
+
def write_index
|
32
|
+
File.open(index_file_path, "w") { |io| io << index_file_contents }
|
33
|
+
end
|
34
|
+
|
35
|
+
def index_file_path
|
36
|
+
File.join(target_dir, "#{@index_name}#{file_extension}")
|
37
|
+
end
|
38
|
+
|
39
|
+
def index_file_contents
|
40
|
+
index_renderer.call(consumer_contracts.first.consumer.name, index_data)
|
41
|
+
end
|
42
|
+
|
43
|
+
def index_data
|
44
|
+
doc_files.each_with_object({}) do | doc_file, data |
|
45
|
+
data[doc_file.title] = doc_file.name
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def write_doc_files
|
50
|
+
doc_files.each(&:write)
|
51
|
+
end
|
52
|
+
|
53
|
+
def doc_files
|
54
|
+
consumer_contracts.collect do | consumer_contract |
|
55
|
+
DocFile.new(consumer_contract, target_dir, interactions_renderer, file_extension)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def consumer_contracts
|
60
|
+
@consumer_contracts ||= begin
|
61
|
+
Dir.glob("#{pact_dir}/**").collect do |file|
|
62
|
+
Pact::ConsumerContract.from_uri file
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def perform_after_hook
|
68
|
+
after.call(pact_dir, target_dir, consumer_contracts)
|
69
|
+
end
|
70
|
+
|
71
|
+
def ensure_target_dir_exists
|
72
|
+
FileUtils.mkdir_p target_dir
|
73
|
+
end
|
74
|
+
|
75
|
+
def target_dir
|
76
|
+
File.join(doc_dir, doc_type)
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'pact/shared/active_support_support'
|
2
|
+
|
3
|
+
module Pact
|
4
|
+
module Doc
|
5
|
+
class InteractionViewModel
|
6
|
+
|
7
|
+
include Pact::ActiveSupportSupport
|
8
|
+
|
9
|
+
def initialize interaction, consumer_contract
|
10
|
+
@interaction = interaction
|
11
|
+
@consumer_contract = consumer_contract
|
12
|
+
end
|
13
|
+
|
14
|
+
def id
|
15
|
+
@id ||= begin
|
16
|
+
if has_provider_state?
|
17
|
+
"#{description} given #{interaction.provider_state}"
|
18
|
+
else
|
19
|
+
interaction.description
|
20
|
+
end.gsub(/\s+/,'_')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def request_method
|
25
|
+
interaction.request.method.upcase
|
26
|
+
end
|
27
|
+
|
28
|
+
def request_path
|
29
|
+
interaction.request.path
|
30
|
+
end
|
31
|
+
|
32
|
+
def response_status
|
33
|
+
interaction.response['status']
|
34
|
+
end
|
35
|
+
|
36
|
+
def consumer_name
|
37
|
+
@consumer_contract.consumer.name
|
38
|
+
end
|
39
|
+
|
40
|
+
def provider_name
|
41
|
+
@consumer_contract.provider.name
|
42
|
+
end
|
43
|
+
|
44
|
+
def has_provider_state?
|
45
|
+
@interaction.provider_state && !@interaction.provider_state.empty?
|
46
|
+
end
|
47
|
+
|
48
|
+
def provider_state start_of_sentence = false
|
49
|
+
apply_capitals(@interaction.provider_state.strip, start_of_sentence)
|
50
|
+
end
|
51
|
+
|
52
|
+
def description start_of_sentence = false
|
53
|
+
apply_capitals(@interaction.description.strip, start_of_sentence)
|
54
|
+
end
|
55
|
+
|
56
|
+
def request
|
57
|
+
fix_json_formatting JSON.pretty_generate(clean_request)
|
58
|
+
end
|
59
|
+
|
60
|
+
def response
|
61
|
+
fix_json_formatting JSON.pretty_generate(clean_response)
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
attr_reader :interaction, :consumer_contract
|
67
|
+
|
68
|
+
def clean_request
|
69
|
+
ordered_clean_hash Reification.from_term(interaction.request).to_hash
|
70
|
+
end
|
71
|
+
|
72
|
+
def clean_response
|
73
|
+
ordered_clean_hash Reification.from_term(interaction.response)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Remove empty body and headers hashes from response, and empty headers from request,
|
77
|
+
# as an empty hash means "allow anything" - it's more intuitive and cleaner to just
|
78
|
+
# remove the empty hashes from display.
|
79
|
+
def ordered_clean_hash source
|
80
|
+
ordered_keys.each_with_object({}) do |key, target|
|
81
|
+
if source.key? key
|
82
|
+
target[key] = source[key] unless value_is_an_empty_hash_that_is_not_request_body(source[key], key)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def value_is_an_empty_hash_that_is_not_request_body value, key
|
88
|
+
value.is_a?(Hash) && value.empty? && key != :body
|
89
|
+
end
|
90
|
+
|
91
|
+
def ordered_keys
|
92
|
+
[:method, :path, :query, :headers, :body, "status", "headers","body"]
|
93
|
+
end
|
94
|
+
|
95
|
+
def remove_key_if_empty key, hash
|
96
|
+
hash.delete(key) if hash[key].is_a?(Hash) && hash[key].empty?
|
97
|
+
end
|
98
|
+
|
99
|
+
def apply_capitals string, start_of_sentence = false
|
100
|
+
start_of_sentence ? capitalize_first_letter(string) : lowercase_first_letter(string)
|
101
|
+
end
|
102
|
+
|
103
|
+
def capitalize_first_letter string
|
104
|
+
string[0].upcase + string[1..-1]
|
105
|
+
end
|
106
|
+
|
107
|
+
def lowercase_first_letter string
|
108
|
+
string[0].downcase + string[1..-1]
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'pact/doc/generator'
|
2
|
+
require 'pact/doc/markdown/interactions_renderer'
|
3
|
+
require 'pact/doc/markdown/index_renderer'
|
4
|
+
|
5
|
+
module Pact
|
6
|
+
module Doc
|
7
|
+
module Markdown
|
8
|
+
class Generator < Pact::Doc::Generator
|
9
|
+
|
10
|
+
def initialize pact_dir, doc_dir
|
11
|
+
super(pact_dir, doc_dir,
|
12
|
+
interactions_renderer: InteractionsRenderer,
|
13
|
+
doc_type: 'markdown',
|
14
|
+
file_extension: '.md',
|
15
|
+
index_renderer: IndexRenderer,
|
16
|
+
index_name: 'README')
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.call pact_dir, doc_dir
|
20
|
+
new(pact_dir, doc_dir).call
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Pact
|
2
|
+
module Doc
|
3
|
+
module Markdown
|
4
|
+
class IndexRenderer
|
5
|
+
|
6
|
+
attr_reader :consumer_name
|
7
|
+
attr_reader :docs # Hash of pact title => file_name
|
8
|
+
|
9
|
+
def initialize consumer_name, docs
|
10
|
+
@consumer_name = consumer_name
|
11
|
+
@docs = docs
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.call consumer_name, docs
|
15
|
+
new(consumer_name, docs).call
|
16
|
+
end
|
17
|
+
|
18
|
+
def call
|
19
|
+
title + "\n\n" + table_of_contents + "\n"
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def table_of_contents
|
25
|
+
docs.collect do | title, file_name |
|
26
|
+
item title, file_name
|
27
|
+
end.join("\n")
|
28
|
+
end
|
29
|
+
|
30
|
+
def title
|
31
|
+
"### Pacts for #{consumer_name}"
|
32
|
+
end
|
33
|
+
|
34
|
+
def item title, file_name
|
35
|
+
"* [#{title}](#{file_name})"
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|