pact_broker 2.13.0 → 2.13.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/lib/pact/doc/README.md +5 -0
- data/lib/pact/doc/doc_file.rb +39 -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 +124 -0
- data/lib/pact/doc/markdown/consumer_contract_renderer.rb +68 -0
- data/lib/pact/doc/markdown/generator.rb +24 -0
- data/lib/pact/doc/markdown/index_renderer.rb +40 -0
- data/lib/pact/doc/markdown/interaction.erb +14 -0
- data/lib/pact/doc/markdown/interaction_renderer.rb +42 -0
- data/lib/pact/doc/sort_interactions.rb +15 -0
- data/lib/pact_broker/version.rb +1 -1
- data/pact_broker.gemspec +2 -2
- data/spec/lib/pact/doc/generator_spec.rb +80 -0
- data/spec/lib/pact/doc/interaction_view_model_spec.rb +186 -0
- data/spec/lib/pact/doc/markdown/consumer_contract_renderer_spec.rb +47 -0
- data/spec/lib/pact/doc/markdown/index_renderer_spec.rb +29 -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/markdown_pact_with_markdown_chars_in_names.json +11 -0
- data/spec/support/warning_silencer.rb +10 -0
- data/tasks/database/table_dependency_calculator.rb +3 -2
- metadata +43 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6493a06ed84ec11bd1c966faddbe3ddb2b948dc1
|
4
|
+
data.tar.gz: f2edee66e10d7ab2fbc8183ff3a685eca1fb20b6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0ddb05561ad94aeb5a3faef53dd0a96b7ca5550f312810f47e1640303298d3f6ef065e29b30d1b41a5928e46d6cba568bacf7c311c745d4f3af0d66d19cb3342
|
7
|
+
data.tar.gz: 905912e0bb8021d08d1d6f8f9ca9cc6d45cc3eafa0fd51dbbfb33ab8297627d3ad437472b5b3b2cf5de6ef5fdce736a14066591f8221a239c2ac56ad8e41483a
|
data/CHANGELOG.md
CHANGED
@@ -0,0 +1,5 @@
|
|
1
|
+
# Pact::Doc
|
2
|
+
|
3
|
+
The code in pact/doc has been copied from the pact gem to break the runtime dependency between the pact_broker and the pact gem, which requires the pact_mock-service, which requires webrick.
|
4
|
+
|
5
|
+
This was required as there is a vulnerability in webrick <= 1.3.1 that we don't want to include in the pact_broker gem, but webrick > 1.3.1 requires ruby 2.3.0, but we need ruby 2.2 for Travelling Ruby, which we use to package the Ruby codebase so it can be shared with implementations in other langauges.
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Pact
|
2
|
+
module Doc
|
3
|
+
class DocFile
|
4
|
+
|
5
|
+
def initialize consumer_contract, dir, consumer_contract_renderer, file_extension
|
6
|
+
@dir = dir
|
7
|
+
@consumer_contract = consumer_contract
|
8
|
+
@consumer_contract_renderer = consumer_contract_renderer
|
9
|
+
@file_extension = file_extension
|
10
|
+
end
|
11
|
+
|
12
|
+
def write
|
13
|
+
File.open(path, "w") { |io| io << doc_file_contents }
|
14
|
+
end
|
15
|
+
|
16
|
+
def title
|
17
|
+
consumer_contract.provider.name
|
18
|
+
end
|
19
|
+
|
20
|
+
def name
|
21
|
+
"#{consumer_contract.consumer.name} - #{consumer_contract.provider.name}#{file_extension}"
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
attr_reader :dir, :consumer_contract, :consumer_contract_renderer, :file_extension
|
27
|
+
|
28
|
+
|
29
|
+
def path
|
30
|
+
File.join(dir, name)
|
31
|
+
end
|
32
|
+
|
33
|
+
def doc_file_contents
|
34
|
+
consumer_contract_renderer.call(consumer_contract)
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
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,82 @@
|
|
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
|
+
@consumer_contract_renderer = options[:consumer_contract_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_and_is_clean
|
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, :consumer_contract_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, consumer_contract_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_and_is_clean
|
72
|
+
FileUtils.rm_rf target_dir
|
73
|
+
FileUtils.mkdir_p target_dir
|
74
|
+
end
|
75
|
+
|
76
|
+
def target_dir
|
77
|
+
File.join(doc_dir, doc_type)
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'pact/shared/active_support_support'
|
2
|
+
require 'pact/reification'
|
3
|
+
require 'cgi'
|
4
|
+
|
5
|
+
module Pact
|
6
|
+
module Doc
|
7
|
+
class InteractionViewModel
|
8
|
+
|
9
|
+
include Pact::ActiveSupportSupport
|
10
|
+
|
11
|
+
def initialize interaction, consumer_contract
|
12
|
+
@interaction = interaction
|
13
|
+
@consumer_contract = consumer_contract
|
14
|
+
end
|
15
|
+
|
16
|
+
def id
|
17
|
+
@id ||= begin
|
18
|
+
full_desc = if has_provider_state?
|
19
|
+
"#{description} given #{interaction.provider_state}"
|
20
|
+
else
|
21
|
+
description
|
22
|
+
end
|
23
|
+
CGI.escapeHTML(full_desc.gsub(/\s+/,'_'))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def request_method
|
28
|
+
interaction.request.method.upcase
|
29
|
+
end
|
30
|
+
|
31
|
+
def request_path
|
32
|
+
interaction.request.path
|
33
|
+
end
|
34
|
+
|
35
|
+
def response_status
|
36
|
+
interaction.response.status
|
37
|
+
end
|
38
|
+
|
39
|
+
def consumer_name
|
40
|
+
markdown_escape @consumer_contract.consumer.name
|
41
|
+
end
|
42
|
+
|
43
|
+
def provider_name
|
44
|
+
markdown_escape @consumer_contract.provider.name
|
45
|
+
end
|
46
|
+
|
47
|
+
def has_provider_state?
|
48
|
+
@interaction.provider_state && !@interaction.provider_state.empty?
|
49
|
+
end
|
50
|
+
|
51
|
+
def provider_state start_of_sentence = false
|
52
|
+
markdown_escape apply_capitals(@interaction.provider_state.strip, start_of_sentence)
|
53
|
+
end
|
54
|
+
|
55
|
+
def description start_of_sentence = false
|
56
|
+
return '' unless @interaction.description
|
57
|
+
markdown_escape apply_capitals(@interaction.description.strip, start_of_sentence)
|
58
|
+
end
|
59
|
+
|
60
|
+
def request
|
61
|
+
fix_json_formatting JSON.pretty_generate(clean_request)
|
62
|
+
end
|
63
|
+
|
64
|
+
def response
|
65
|
+
fix_json_formatting JSON.pretty_generate(clean_response)
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
attr_reader :interaction, :consumer_contract
|
71
|
+
|
72
|
+
def clean_request
|
73
|
+
reified_request = Reification.from_term(interaction.request)
|
74
|
+
ordered_clean_hash(reified_request).tap do | hash |
|
75
|
+
hash[:body] = reified_request[:body] if reified_request[:body]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def clean_response
|
80
|
+
ordered_clean_hash Reification.from_term(interaction.response)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Remove empty body and headers hashes from response, and empty headers from request,
|
84
|
+
# as an empty hash means "allow anything" - it's more intuitive and cleaner to just
|
85
|
+
# remove the empty hashes from display.
|
86
|
+
def ordered_clean_hash source
|
87
|
+
ordered_keys.each_with_object({}) do |key, target|
|
88
|
+
if source.key? key
|
89
|
+
target[key] = source[key] unless value_is_an_empty_hash(source[key])
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def value_is_an_empty_hash value
|
95
|
+
value.is_a?(Hash) && value.empty?
|
96
|
+
end
|
97
|
+
|
98
|
+
def ordered_keys
|
99
|
+
[:method, :path, :query, :status, :headers, :body]
|
100
|
+
end
|
101
|
+
|
102
|
+
def remove_key_if_empty key, hash
|
103
|
+
hash.delete(key) if hash[key].is_a?(Hash) && hash[key].empty?
|
104
|
+
end
|
105
|
+
|
106
|
+
def apply_capitals string, start_of_sentence = false
|
107
|
+
start_of_sentence ? capitalize_first_letter(string) : lowercase_first_letter(string)
|
108
|
+
end
|
109
|
+
|
110
|
+
def capitalize_first_letter string
|
111
|
+
string[0].upcase + string[1..-1]
|
112
|
+
end
|
113
|
+
|
114
|
+
def lowercase_first_letter string
|
115
|
+
string[0].downcase + string[1..-1]
|
116
|
+
end
|
117
|
+
|
118
|
+
def markdown_escape string
|
119
|
+
return nil unless string
|
120
|
+
string.gsub('*','\*').gsub('_','\_')
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'pact/doc/markdown/interaction_renderer'
|
2
|
+
require 'pact/doc/sort_interactions'
|
3
|
+
|
4
|
+
module Pact
|
5
|
+
module Doc
|
6
|
+
module Markdown
|
7
|
+
class ConsumerContractRenderer
|
8
|
+
|
9
|
+
def initialize consumer_contract
|
10
|
+
@consumer_contract = consumer_contract
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.call consumer_contract
|
14
|
+
new(consumer_contract).call
|
15
|
+
end
|
16
|
+
|
17
|
+
def call
|
18
|
+
title + summaries_title + summaries.join + interactions_title + full_interactions.join
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
attr_reader :consumer_contract
|
24
|
+
|
25
|
+
def title
|
26
|
+
"### A pact between #{consumer_name} and #{provider_name}\n\n"
|
27
|
+
end
|
28
|
+
|
29
|
+
def interaction_renderers
|
30
|
+
@interaction_renderers ||= sorted_interactions.collect{|interaction| InteractionRenderer.new interaction, @consumer_contract}
|
31
|
+
end
|
32
|
+
|
33
|
+
def summaries_title
|
34
|
+
"#### Requests from #{consumer_name} to #{provider_name}\n\n"
|
35
|
+
end
|
36
|
+
|
37
|
+
def interactions_title
|
38
|
+
"#### Interactions\n\n"
|
39
|
+
end
|
40
|
+
|
41
|
+
def summaries
|
42
|
+
interaction_renderers.collect(&:render_summary)
|
43
|
+
end
|
44
|
+
|
45
|
+
def full_interactions
|
46
|
+
interaction_renderers.collect(&:render_full_interaction)
|
47
|
+
end
|
48
|
+
|
49
|
+
def sorted_interactions
|
50
|
+
SortInteractions.call(consumer_contract.interactions)
|
51
|
+
end
|
52
|
+
|
53
|
+
def consumer_name
|
54
|
+
markdown_escape consumer_contract.consumer.name
|
55
|
+
end
|
56
|
+
|
57
|
+
def provider_name
|
58
|
+
markdown_escape consumer_contract.provider.name
|
59
|
+
end
|
60
|
+
|
61
|
+
def markdown_escape string
|
62
|
+
string.gsub('*','\*').gsub('_','\_')
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'pact/doc/generator'
|
2
|
+
require 'pact/doc/markdown/consumer_contract_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
|
+
def initialize pact_dir, doc_dir
|
10
|
+
super(pact_dir, doc_dir,
|
11
|
+
consumer_contract_renderer: ConsumerContractRenderer,
|
12
|
+
doc_type: 'markdown',
|
13
|
+
file_extension: '.md',
|
14
|
+
index_renderer: IndexRenderer,
|
15
|
+
index_name: 'README')
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.call pact_dir, doc_dir
|
19
|
+
new(pact_dir, doc_dir).call
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Pact
|
2
|
+
module Doc
|
3
|
+
module Markdown
|
4
|
+
class IndexRenderer
|
5
|
+
attr_reader :consumer_name
|
6
|
+
attr_reader :docs # Hash of pact title => file_name
|
7
|
+
|
8
|
+
def initialize consumer_name, docs
|
9
|
+
@consumer_name = consumer_name
|
10
|
+
@docs = docs
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.call consumer_name, docs
|
14
|
+
new(consumer_name, docs).call
|
15
|
+
end
|
16
|
+
|
17
|
+
def call
|
18
|
+
title + "\n\n" + table_of_contents + "\n"
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def table_of_contents
|
24
|
+
docs.collect do | title, file_name |
|
25
|
+
item title, file_name
|
26
|
+
end.join("\n")
|
27
|
+
end
|
28
|
+
|
29
|
+
def title
|
30
|
+
"### Pacts for #{consumer_name}"
|
31
|
+
end
|
32
|
+
|
33
|
+
def item title, file_name
|
34
|
+
"* [#{title}](#{file_name})"
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<a name="<%= interaction.id %>"></a>
|
2
|
+
<%= if interaction.has_provider_state?
|
3
|
+
"Given **#{interaction.provider_state}**, upon receiving"
|
4
|
+
else
|
5
|
+
"Upon receiving"
|
6
|
+
end
|
7
|
+
%> **<%= interaction.description %>** from <%= interaction.consumer_name %>, with
|
8
|
+
```json
|
9
|
+
<%= interaction.request %>
|
10
|
+
```
|
11
|
+
<%= interaction.provider_name %> will respond with:
|
12
|
+
```json
|
13
|
+
<%= interaction.response %>
|
14
|
+
```
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'pact/doc/interaction_view_model'
|
3
|
+
|
4
|
+
module Pact
|
5
|
+
module Doc
|
6
|
+
module Markdown
|
7
|
+
class InteractionRenderer
|
8
|
+
attr_reader :interaction
|
9
|
+
|
10
|
+
def initialize interaction, pact
|
11
|
+
@interaction = InteractionViewModel.new(interaction, pact)
|
12
|
+
end
|
13
|
+
|
14
|
+
def render_summary
|
15
|
+
suffix = interaction.has_provider_state? ? " given #{interaction.provider_state}" : ""
|
16
|
+
"* [#{interaction.description(true)}](##{interaction.id})#{suffix}\n\n"
|
17
|
+
end
|
18
|
+
|
19
|
+
def render_full_interaction
|
20
|
+
render('/interaction.erb')
|
21
|
+
end
|
22
|
+
|
23
|
+
def render template_file
|
24
|
+
ERB.new(template_string(template_file)).result(binding)
|
25
|
+
end
|
26
|
+
|
27
|
+
# The template file is written with only ASCII range characters, so we
|
28
|
+
# can read as UTF-8. But rendered strings must have same encoding as
|
29
|
+
# script encoding because it will joined to strings which are produced by
|
30
|
+
# string literal.
|
31
|
+
def template_string(template_file)
|
32
|
+
File.read(template_contents(template_file), external_encoding: Encoding::UTF_8).force_encoding(__ENCODING__)
|
33
|
+
end
|
34
|
+
|
35
|
+
def template_contents(template_file)
|
36
|
+
File.dirname(__FILE__) + template_file
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Pact
|
2
|
+
module Doc
|
3
|
+
class SortInteractions
|
4
|
+
def self.call interactions
|
5
|
+
interactions.sort{|a, b| sortable_id(a) <=> sortable_id(b)}
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def self.sortable_id interaction
|
11
|
+
"#{interaction.description.downcase} #{interaction.response.status} #{(interaction.provider_state || '').downcase}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/pact_broker/version.rb
CHANGED
data/pact_broker.gemspec
CHANGED
@@ -31,15 +31,15 @@ Gem::Specification.new do |gem|
|
|
31
31
|
gem.add_runtime_dependency 'semver2', '~> 3.4.2'
|
32
32
|
gem.add_runtime_dependency 'rack', '~>2.0'
|
33
33
|
gem.add_runtime_dependency 'redcarpet', '>=3.3.2', '~>3.3'
|
34
|
-
gem.add_runtime_dependency 'pact'
|
34
|
+
gem.add_runtime_dependency 'pact-support'
|
35
35
|
gem.add_runtime_dependency 'padrino-core', '~>0.14.1'
|
36
36
|
gem.add_runtime_dependency 'haml', '~>4.0'
|
37
37
|
gem.add_runtime_dependency 'sucker_punch', '~>2.0'
|
38
38
|
gem.add_runtime_dependency 'rack-protection', '~>2.0'
|
39
39
|
gem.add_runtime_dependency 'dry-types', '~> 0.10.3' # https://travis-ci.org/pact-foundation/pact_broker/jobs/249448621
|
40
40
|
gem.add_runtime_dependency 'table_print', '~> 1.5'
|
41
|
-
gem.add_runtime_dependency 'webrick', '~>1.3.0' # Webrick requires Ruby version >= 2.5.0dev. TODO remove dependency on Pact gem.
|
42
41
|
|
42
|
+
gem.add_development_dependency 'pact', '~>1.14'
|
43
43
|
gem.add_development_dependency 'bundler-audit', '~>0.4'
|
44
44
|
gem.add_development_dependency 'sqlite3', '~>1.3'
|
45
45
|
gem.add_development_dependency 'pry-byebug'
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'pact/doc/generator'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module Pact
|
5
|
+
module Doc
|
6
|
+
describe Generator do
|
7
|
+
|
8
|
+
let(:doc_dir) { './tmp/doc' }
|
9
|
+
let(:pact_dir) { './tmp/pacts' }
|
10
|
+
let(:file_name) { "Some Consumer - Some Provider#{file_extension}" }
|
11
|
+
let(:consumer_contract_renderer) { double("ConsumerContractRenderer", :call => doc_content) }
|
12
|
+
let(:doc_content) { "doc_content" }
|
13
|
+
let(:index_content) { "index_content" }
|
14
|
+
let(:expected_doc_path) { "#{doc_dir}/#{doc_type}/#{file_name}" }
|
15
|
+
let(:expected_index_path) { "#{doc_dir}/#{doc_type}/#{index_name}#{file_extension}" }
|
16
|
+
let(:doc_type) { 'markdown' }
|
17
|
+
let(:file_extension) { ".md" }
|
18
|
+
let(:actual_file_contents) { File.read(expected_doc_path) }
|
19
|
+
let(:actual_index_contents) { File.read(expected_index_path)}
|
20
|
+
let(:index_renderer) { double("IndexRenderer", :call => index_content)}
|
21
|
+
let(:index_name) { 'README' }
|
22
|
+
let(:after_hook) { double("hook", :call => nil)}
|
23
|
+
|
24
|
+
before do
|
25
|
+
FileUtils.rm_rf doc_dir
|
26
|
+
FileUtils.rm_rf pact_dir
|
27
|
+
FileUtils.mkdir_p doc_dir
|
28
|
+
FileUtils.mkdir_p pact_dir
|
29
|
+
FileUtils.cp './spec/support/markdown_pact.json', pact_dir
|
30
|
+
end
|
31
|
+
|
32
|
+
let(:options) { { consumer_contract_renderer: consumer_contract_renderer, doc_type: doc_type, file_extension: file_extension, index_renderer: index_renderer, index_name: index_name } }
|
33
|
+
|
34
|
+
subject { Generator.new(pact_dir, doc_dir, options) }
|
35
|
+
|
36
|
+
context "when there are existing files" do
|
37
|
+
let(:existing_doc_file_path) { File.join(doc_dir, doc_type, "leftover") }
|
38
|
+
|
39
|
+
before do
|
40
|
+
FileUtils.mkdir_p File.dirname(existing_doc_file_path)
|
41
|
+
FileUtils.touch existing_doc_file_path
|
42
|
+
end
|
43
|
+
|
44
|
+
it "clears the existing files" do
|
45
|
+
expect(File.exist?(existing_doc_file_path)).to be true
|
46
|
+
subject.call
|
47
|
+
expect(File.exist?(existing_doc_file_path)).to be false
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it "creates an index" do
|
52
|
+
expect(index_renderer).to receive(:call).with("Some Consumer", {"Some Provider"=>"Some Consumer - Some Provider.md"})
|
53
|
+
subject.call
|
54
|
+
expect(actual_index_contents).to eq(index_content)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "creates documentation" do
|
58
|
+
subject.call
|
59
|
+
expect(actual_file_contents).to eq(doc_content)
|
60
|
+
end
|
61
|
+
|
62
|
+
context "with an after hook specified" do
|
63
|
+
|
64
|
+
subject { Generator.new(pact_dir, doc_dir, options.merge(:after => after_hook)) }
|
65
|
+
|
66
|
+
it "executes the hook" do
|
67
|
+
expect(after_hook).to receive(:call).with(pact_dir, "#{doc_dir}/#{doc_type}", instance_of(Array))
|
68
|
+
subject.call
|
69
|
+
end
|
70
|
+
|
71
|
+
it "passes in the consumer_contracts" do
|
72
|
+
expect(after_hook).to receive(:call) do | _, _, consumer_contracts |
|
73
|
+
expect(consumer_contracts.first).to be_instance_of(Pact::ConsumerContract)
|
74
|
+
end
|
75
|
+
subject.call
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,186 @@
|
|
1
|
+
require 'pact/doc/interaction_view_model'
|
2
|
+
|
3
|
+
module Pact
|
4
|
+
module Doc
|
5
|
+
describe InteractionViewModel do
|
6
|
+
let(:consumer_contract) { Pact::ConsumerContract.from_uri './spec/support/interaction_view_model.json' }
|
7
|
+
let(:interaction_with_request_with_body_and_headers) { consumer_contract.find_interaction description: "a request with a body and headers" }
|
8
|
+
let(:interaction_with_request_without_body_and_headers) { consumer_contract.find_interaction description: "a request with an empty body and empty headers" }
|
9
|
+
let(:interaction_with_response_with_body_and_headers) { consumer_contract.find_interaction description: "a response with a body and headers" }
|
10
|
+
let(:interaction_with_response_without_body_and_headers) { consumer_contract.find_interaction description: "a response with an empty body and empty headers" }
|
11
|
+
let(:interaction) { consumer_contract.interactions.first }
|
12
|
+
|
13
|
+
subject { InteractionViewModel.new interaction, consumer_contract}
|
14
|
+
|
15
|
+
describe "id" do
|
16
|
+
context "with HTML characters in the description" do
|
17
|
+
before do
|
18
|
+
interaction.description = "an alligator with > 100 legs exists"
|
19
|
+
interaction.provider_state = "a thing exists"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "escapes the HTML characters" do
|
23
|
+
expect(subject.id).to eq "an_alligator_with_>_100_legs_exists_given_a_thing_exists"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "consumer_name" do
|
29
|
+
context "with markdown characters in the name" do
|
30
|
+
it "escapes the markdown characters" do
|
31
|
+
expect(subject.consumer_name).to eq "a\\*consumer"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "provider_name" do
|
37
|
+
context "with markdown characters in the name" do
|
38
|
+
it "escapes the markdown characters" do
|
39
|
+
expect(subject.provider_name).to eq "a\\_provider"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "request" do
|
45
|
+
let(:interaction) { interaction_with_request_with_body_and_headers }
|
46
|
+
|
47
|
+
it "includes the method" do
|
48
|
+
expect(subject.request).to include('"method"')
|
49
|
+
expect(subject.request).to include('"get"')
|
50
|
+
end
|
51
|
+
|
52
|
+
it "includes the body" do
|
53
|
+
expect(subject.request).to include('"body"')
|
54
|
+
expect(subject.request).to include('"a body"')
|
55
|
+
end
|
56
|
+
|
57
|
+
it "includes the headers" do
|
58
|
+
expect(subject.request).to include('"headers"')
|
59
|
+
expect(subject.request).to include('"a header"')
|
60
|
+
end
|
61
|
+
|
62
|
+
it "includes the query" do
|
63
|
+
expect(subject.request).to include('"query"')
|
64
|
+
expect(subject.request).to include('"some=thing"')
|
65
|
+
end
|
66
|
+
|
67
|
+
it "includes the path" do
|
68
|
+
expect(subject.request).to include('"path"')
|
69
|
+
expect(subject.request).to include('"/path"')
|
70
|
+
end
|
71
|
+
|
72
|
+
it "renders the keys in a meaningful order" do
|
73
|
+
expect(subject.request).to match /"method".*"path".*"query".*"headers".*"body"/m
|
74
|
+
end
|
75
|
+
|
76
|
+
context "when the body hash is empty" do
|
77
|
+
let(:interaction) { interaction_with_request_without_body_and_headers }
|
78
|
+
|
79
|
+
it "includes the body" do
|
80
|
+
expect(subject.request).to include("body")
|
81
|
+
end
|
82
|
+
end
|
83
|
+
context "when the headers hash is empty" do
|
84
|
+
let(:interaction) { interaction_with_request_without_body_and_headers }
|
85
|
+
|
86
|
+
it "does not include the headers" do
|
87
|
+
expect(subject.request).to_not include("headers")
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context "when a Pact::Term is present" do
|
92
|
+
let(:consumer_contract) { Pact::ConsumerContract.from_uri './spec/support/interaction_view_model_with_terms.json'}
|
93
|
+
let(:interaction) { consumer_contract.interactions.first }
|
94
|
+
|
95
|
+
it "uses the generated value" do
|
96
|
+
expect(subject.request).to_not include("Term")
|
97
|
+
expect(subject.request).to include("sunny")
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe "response" do
|
103
|
+
let(:interaction) { interaction_with_response_with_body_and_headers }
|
104
|
+
|
105
|
+
it "includes the status" do
|
106
|
+
expect(subject.response).to include('"status"')
|
107
|
+
end
|
108
|
+
|
109
|
+
it "includes the body" do
|
110
|
+
expect(subject.response).to include('"body"')
|
111
|
+
expect(subject.response).to include('"a body"')
|
112
|
+
end
|
113
|
+
it "includes the headers" do
|
114
|
+
expect(subject.response).to include('"headers"')
|
115
|
+
expect(subject.response).to include('"a header"')
|
116
|
+
end
|
117
|
+
|
118
|
+
it "renders the keys in a meaningful order" do
|
119
|
+
expect(subject.response).to match /"status".*"headers".*"body"/m
|
120
|
+
end
|
121
|
+
|
122
|
+
context "when the body hash is empty" do
|
123
|
+
let(:interaction) { interaction_with_response_without_body_and_headers }
|
124
|
+
|
125
|
+
it "does not include the body" do
|
126
|
+
expect(subject.response).to_not include("body")
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context "when the headers hash is empty" do
|
131
|
+
let(:interaction) { interaction_with_response_without_body_and_headers }
|
132
|
+
|
133
|
+
it "does not include the headers" do
|
134
|
+
expect(subject.response).to_not include("headers")
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context "when a Pact::Term is present" do
|
139
|
+
let(:consumer_contract) { Pact::ConsumerContract.from_uri './spec/support/interaction_view_model_with_terms.json'}
|
140
|
+
let(:interaction) { consumer_contract.interactions.first }
|
141
|
+
|
142
|
+
it "uses the generated value" do
|
143
|
+
expect(subject.response).to_not include("Term")
|
144
|
+
expect(subject.response).to include("rainy")
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
describe "description" do
|
150
|
+
context "with a nil description" do
|
151
|
+
let(:interaction) do
|
152
|
+
interaction_with_request_with_body_and_headers.description = nil
|
153
|
+
interaction_with_request_with_body_and_headers
|
154
|
+
end
|
155
|
+
|
156
|
+
it "does not blow up" do
|
157
|
+
expect(subject.description(true)).to eq ''
|
158
|
+
expect(subject.description(false)).to eq ''
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
context "with markdown characters in the name" do
|
163
|
+
let(:interaction) do
|
164
|
+
interaction_with_request_with_body_and_headers.description = 'a *description'
|
165
|
+
interaction_with_request_with_body_and_headers
|
166
|
+
end
|
167
|
+
it "escapes the markdown characters" do
|
168
|
+
expect(subject.description).to eq "a \\*description"
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
describe "provider_state" do
|
174
|
+
context "with markdown characters in the name" do
|
175
|
+
let(:interaction) do
|
176
|
+
interaction_with_request_with_body_and_headers.provider_state = 'a *provider state'
|
177
|
+
interaction_with_request_with_body_and_headers
|
178
|
+
end
|
179
|
+
it "escapes the markdown characters" do
|
180
|
+
expect(subject.provider_state).to eq "a \\*provider state"
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'pact/doc/markdown/consumer_contract_renderer'
|
3
|
+
require 'pact/support'
|
4
|
+
|
5
|
+
module Pact
|
6
|
+
module Doc
|
7
|
+
module Markdown
|
8
|
+
describe ConsumerContractRenderer do
|
9
|
+
|
10
|
+
subject { ConsumerContractRenderer.new(consumer_contract) }
|
11
|
+
let(:consumer_contract) { Pact::ConsumerContract.from_uri './spec/support/markdown_pact.json' }
|
12
|
+
|
13
|
+
let(:expected_output) { File.read("./spec/support/generated_markdown.md", external_encoding: Encoding::UTF_8) }
|
14
|
+
|
15
|
+
describe "#call" do
|
16
|
+
|
17
|
+
context "with markdown characters in the pacticipant names" do
|
18
|
+
let(:consumer_contract) { Pact::ConsumerContract.from_uri './spec/support/markdown_pact_with_markdown_chars_in_names.json' }
|
19
|
+
|
20
|
+
it "escapes the markdown characters" do
|
21
|
+
expect(subject.call).to include '### A pact between Some\*Consumer\*App and Some\_Provider\_App'
|
22
|
+
expect(subject.call).to include '#### Requests from Some\*Consumer\*App to Some\_Provider\_App'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "with ruby's default external encoding is not UTF-8" do
|
27
|
+
around do |example|
|
28
|
+
back = nil
|
29
|
+
WarningSilencer.enable { back, Encoding.default_external = Encoding.default_external, Encoding::ASCII_8BIT }
|
30
|
+
example.run
|
31
|
+
WarningSilencer.enable { Encoding.default_external = back }
|
32
|
+
end
|
33
|
+
|
34
|
+
it "renders the interactions" do
|
35
|
+
expect(subject.call).to eq(expected_output)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it "renders the interactions" do
|
40
|
+
expect(subject.call).to eq(expected_output)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'pact/doc/markdown/index_renderer'
|
3
|
+
|
4
|
+
module Pact
|
5
|
+
module Doc
|
6
|
+
module Markdown
|
7
|
+
describe IndexRenderer do
|
8
|
+
|
9
|
+
let(:consumer_name) { "Some Consumer" }
|
10
|
+
let(:docs) { {"Some Provider" => "Some Provider.md", "Some other provider" => "Some other provider.md"} }
|
11
|
+
let(:subject) { IndexRenderer.new(consumer_name, docs) }
|
12
|
+
let(:expected_content) { File.read('./spec/support/generated_index.md')}
|
13
|
+
|
14
|
+
describe "#call" do
|
15
|
+
it "renders the index" do
|
16
|
+
expect(subject.call).to eq expected_content
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe ".call" do
|
21
|
+
it "renders the index" do
|
22
|
+
expect(IndexRenderer.call(consumer_name, docs) ).to eq expected_content
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
### A pact between Some Consumer and Some Provider
|
2
|
+
|
3
|
+
#### Requests from Some Consumer to Some Provider
|
4
|
+
|
5
|
+
* [A request for alligators in Brüssel](#a_request_for_alligators_in_Brüssel_given_alligators_exist) given alligators exist
|
6
|
+
|
7
|
+
* [A request for polar bears](#a_request_for_polar_bears)
|
8
|
+
|
9
|
+
#### Interactions
|
10
|
+
|
11
|
+
<a name="a_request_for_alligators_in_Brüssel_given_alligators_exist"></a>
|
12
|
+
Given **alligators exist**, upon receiving **a request for alligators in Brüssel** from Some Consumer, with
|
13
|
+
```json
|
14
|
+
{
|
15
|
+
"method": "get",
|
16
|
+
"path": "/alligators"
|
17
|
+
}
|
18
|
+
```
|
19
|
+
Some Provider will respond with:
|
20
|
+
```json
|
21
|
+
{
|
22
|
+
"status": 200,
|
23
|
+
"headers": {
|
24
|
+
"Content-Type": "application/json"
|
25
|
+
},
|
26
|
+
"body": {
|
27
|
+
"alligators": [
|
28
|
+
{
|
29
|
+
"name": "Bob",
|
30
|
+
"phoneNumber": "12345678"
|
31
|
+
}
|
32
|
+
]
|
33
|
+
}
|
34
|
+
}
|
35
|
+
```
|
36
|
+
<a name="a_request_for_polar_bears"></a>
|
37
|
+
Upon receiving **a request for polar bears** from Some Consumer, with
|
38
|
+
```json
|
39
|
+
{
|
40
|
+
"method": "get",
|
41
|
+
"path": "/polar-bears"
|
42
|
+
}
|
43
|
+
```
|
44
|
+
Some Provider will respond with:
|
45
|
+
```json
|
46
|
+
{
|
47
|
+
"status": 404,
|
48
|
+
"headers": {
|
49
|
+
"Content-Type": "application/json"
|
50
|
+
},
|
51
|
+
"body": {
|
52
|
+
"message": "Sorry, due to climate change, the polar bears are currently unavailable."
|
53
|
+
}
|
54
|
+
}
|
55
|
+
```
|
@@ -0,0 +1,63 @@
|
|
1
|
+
{
|
2
|
+
"provider": {
|
3
|
+
"name": "a_provider"
|
4
|
+
},
|
5
|
+
"consumer": {
|
6
|
+
"name": "a*consumer"
|
7
|
+
},
|
8
|
+
"interactions": [
|
9
|
+
{
|
10
|
+
"description": "a request with a body and headers",
|
11
|
+
"request": {
|
12
|
+
"method": "get",
|
13
|
+
"path": "/path",
|
14
|
+
"query": "some=thing",
|
15
|
+
"headers": {
|
16
|
+
"key": "a header"
|
17
|
+
},
|
18
|
+
"body": {
|
19
|
+
"key": "a body"
|
20
|
+
}
|
21
|
+
},
|
22
|
+
"response": {}
|
23
|
+
},
|
24
|
+
{
|
25
|
+
"description": "a request with an empty body and empty headers",
|
26
|
+
"request": {
|
27
|
+
"method": "get",
|
28
|
+
"path": "/",
|
29
|
+
"headers": {},
|
30
|
+
"body": {}
|
31
|
+
},
|
32
|
+
"response": {}
|
33
|
+
},
|
34
|
+
{
|
35
|
+
"description": "a response with a body and headers",
|
36
|
+
"request": {
|
37
|
+
"method": "get",
|
38
|
+
"path": "/"
|
39
|
+
},
|
40
|
+
"response": {
|
41
|
+
"headers": {
|
42
|
+
"key": "a header"
|
43
|
+
},
|
44
|
+
"body": {
|
45
|
+
"key": "a body"
|
46
|
+
},
|
47
|
+
"status": 200
|
48
|
+
}
|
49
|
+
},
|
50
|
+
{
|
51
|
+
"description": "a response with an empty body and empty headers",
|
52
|
+
"request": {
|
53
|
+
"method": "get",
|
54
|
+
"path": "/"
|
55
|
+
},
|
56
|
+
"response": {
|
57
|
+
"status": 200,
|
58
|
+
"headers": {},
|
59
|
+
"body": {}
|
60
|
+
}
|
61
|
+
}
|
62
|
+
]
|
63
|
+
}
|
@@ -0,0 +1,50 @@
|
|
1
|
+
{
|
2
|
+
"provider": {
|
3
|
+
"name": "a provider"
|
4
|
+
},
|
5
|
+
"consumer": {
|
6
|
+
"name": "a consumer"
|
7
|
+
},
|
8
|
+
"interactions": [
|
9
|
+
{
|
10
|
+
"description": "an interaction with terms",
|
11
|
+
"request": {
|
12
|
+
"method": "post",
|
13
|
+
"path": "/path",
|
14
|
+
"query": "some=thing",
|
15
|
+
"headers": {
|
16
|
+
"key": "a header"
|
17
|
+
},
|
18
|
+
"body": {
|
19
|
+
"term": {
|
20
|
+
"json_class": "Pact::Term",
|
21
|
+
"data": {
|
22
|
+
"generate": "sunny",
|
23
|
+
"matcher": {
|
24
|
+
"json_class": "Regexp",
|
25
|
+
"o": 0,
|
26
|
+
"s": "sun"
|
27
|
+
}
|
28
|
+
}
|
29
|
+
}
|
30
|
+
}
|
31
|
+
},
|
32
|
+
"response": {
|
33
|
+
"status": 200,
|
34
|
+
"body": {
|
35
|
+
"term": {
|
36
|
+
"json_class": "Pact::Term",
|
37
|
+
"data": {
|
38
|
+
"generate": "rainy",
|
39
|
+
"matcher": {
|
40
|
+
"json_class": "Regexp",
|
41
|
+
"o": 0,
|
42
|
+
"s": "rain"
|
43
|
+
}
|
44
|
+
}
|
45
|
+
}
|
46
|
+
}
|
47
|
+
}
|
48
|
+
}
|
49
|
+
]
|
50
|
+
}
|
@@ -0,0 +1,48 @@
|
|
1
|
+
{
|
2
|
+
"provider": {
|
3
|
+
"name": "Some Provider"
|
4
|
+
},
|
5
|
+
"consumer": {
|
6
|
+
"name": "Some Consumer"
|
7
|
+
},
|
8
|
+
"interactions": [
|
9
|
+
{
|
10
|
+
"description": "a request for alligators in Brüssel",
|
11
|
+
"provider_state": "alligators exist",
|
12
|
+
"request": {
|
13
|
+
"method": "get",
|
14
|
+
"path": "/alligators"
|
15
|
+
},
|
16
|
+
"response": {
|
17
|
+
"headers" : {"Content-Type": "application/json"},
|
18
|
+
"status" : 200,
|
19
|
+
"body" : {
|
20
|
+
"alligators": [{
|
21
|
+
"name": "Bob",
|
22
|
+
"phoneNumber" : {
|
23
|
+
"json_class": "Pact::Term",
|
24
|
+
"data": {
|
25
|
+
"generate": "12345678",
|
26
|
+
"matcher": {"json_class":"Regexp","o":0,"s":"\\d+"}
|
27
|
+
}
|
28
|
+
}
|
29
|
+
}]
|
30
|
+
}
|
31
|
+
}
|
32
|
+
},{
|
33
|
+
"description": "a request for polar bears",
|
34
|
+
"provider_state": null,
|
35
|
+
"request": {
|
36
|
+
"method": "get",
|
37
|
+
"path": "/polar-bears"
|
38
|
+
},
|
39
|
+
"response": {
|
40
|
+
"headers" : {"Content-Type": "application/json"},
|
41
|
+
"status" : 404,
|
42
|
+
"body" : {
|
43
|
+
"message": "Sorry, due to climate change, the polar bears are currently unavailable."
|
44
|
+
}
|
45
|
+
}
|
46
|
+
}
|
47
|
+
]
|
48
|
+
}
|
@@ -20,8 +20,9 @@ module PactBroker
|
|
20
20
|
.collect{|it| @connection.foreign_key_list(it)
|
21
21
|
.collect{|fk| {from: it, to: fk[:table]} } }
|
22
22
|
.flatten
|
23
|
-
.uniq
|
24
|
-
|
23
|
+
.uniq
|
24
|
+
table_names = @connection.tables - [:schema_migrations, :schema_info]
|
25
|
+
check(table_names, dependencies, ordered_table_names)
|
25
26
|
ordered_table_names
|
26
27
|
end
|
27
28
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pact_broker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.13.
|
4
|
+
version: 2.13.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bethany Skurrie
|
@@ -165,19 +165,19 @@ dependencies:
|
|
165
165
|
- !ruby/object:Gem::Version
|
166
166
|
version: '3.3'
|
167
167
|
- !ruby/object:Gem::Dependency
|
168
|
-
name: pact
|
168
|
+
name: pact-support
|
169
169
|
requirement: !ruby/object:Gem::Requirement
|
170
170
|
requirements:
|
171
|
-
- - "
|
171
|
+
- - ">="
|
172
172
|
- !ruby/object:Gem::Version
|
173
|
-
version: '
|
173
|
+
version: '0'
|
174
174
|
type: :runtime
|
175
175
|
prerelease: false
|
176
176
|
version_requirements: !ruby/object:Gem::Requirement
|
177
177
|
requirements:
|
178
|
-
- - "
|
178
|
+
- - ">="
|
179
179
|
- !ruby/object:Gem::Version
|
180
|
-
version: '
|
180
|
+
version: '0'
|
181
181
|
- !ruby/object:Gem::Dependency
|
182
182
|
name: padrino-core
|
183
183
|
requirement: !ruby/object:Gem::Requirement
|
@@ -263,19 +263,19 @@ dependencies:
|
|
263
263
|
- !ruby/object:Gem::Version
|
264
264
|
version: '1.5'
|
265
265
|
- !ruby/object:Gem::Dependency
|
266
|
-
name:
|
266
|
+
name: pact
|
267
267
|
requirement: !ruby/object:Gem::Requirement
|
268
268
|
requirements:
|
269
269
|
- - "~>"
|
270
270
|
- !ruby/object:Gem::Version
|
271
|
-
version: 1.
|
272
|
-
type: :
|
271
|
+
version: '1.14'
|
272
|
+
type: :development
|
273
273
|
prerelease: false
|
274
274
|
version_requirements: !ruby/object:Gem::Requirement
|
275
275
|
requirements:
|
276
276
|
- - "~>"
|
277
277
|
- !ruby/object:Gem::Version
|
278
|
-
version: 1.
|
278
|
+
version: '1.14'
|
279
279
|
- !ruby/object:Gem::Dependency
|
280
280
|
name: bundler-audit
|
281
281
|
requirement: !ruby/object:Gem::Requirement
|
@@ -602,6 +602,17 @@ files:
|
|
602
602
|
- example/example_data.sql
|
603
603
|
- example/pact_broker_database.sqlite3
|
604
604
|
- lib/db.rb
|
605
|
+
- lib/pact/doc/README.md
|
606
|
+
- lib/pact/doc/doc_file.rb
|
607
|
+
- lib/pact/doc/generate.rb
|
608
|
+
- lib/pact/doc/generator.rb
|
609
|
+
- lib/pact/doc/interaction_view_model.rb
|
610
|
+
- lib/pact/doc/markdown/consumer_contract_renderer.rb
|
611
|
+
- lib/pact/doc/markdown/generator.rb
|
612
|
+
- lib/pact/doc/markdown/index_renderer.rb
|
613
|
+
- lib/pact/doc/markdown/interaction.erb
|
614
|
+
- lib/pact/doc/markdown/interaction_renderer.rb
|
615
|
+
- lib/pact/doc/sort_interactions.rb
|
605
616
|
- lib/pact_broker.rb
|
606
617
|
- lib/pact_broker/api.rb
|
607
618
|
- lib/pact_broker/api/contracts/pacticipant_name_contract.rb
|
@@ -919,6 +930,10 @@ files:
|
|
919
930
|
- spec/integration/endpoints/group_spec.rb
|
920
931
|
- spec/integration/ui/index_spec.rb
|
921
932
|
- spec/integration/webhooks/certificate_spec.rb
|
933
|
+
- spec/lib/pact/doc/generator_spec.rb
|
934
|
+
- spec/lib/pact/doc/interaction_view_model_spec.rb
|
935
|
+
- spec/lib/pact/doc/markdown/consumer_contract_renderer_spec.rb
|
936
|
+
- spec/lib/pact/doc/markdown/index_renderer_spec.rb
|
922
937
|
- spec/lib/pact_broker/api/contracts/put_pact_params_contract_spec.rb
|
923
938
|
- spec/lib/pact_broker/api/contracts/verification_contract_spec.rb
|
924
939
|
- spec/lib/pact_broker/api/contracts/webhook_contract_spec.rb
|
@@ -1040,12 +1055,19 @@ files:
|
|
1040
1055
|
- spec/spec_helper.rb
|
1041
1056
|
- spec/support/database_cleaner.rb
|
1042
1057
|
- spec/support/fixture_helpers.rb
|
1058
|
+
- spec/support/generated_index.md
|
1059
|
+
- spec/support/generated_markdown.md
|
1060
|
+
- spec/support/interaction_view_model.json
|
1061
|
+
- spec/support/interaction_view_model_with_terms.json
|
1062
|
+
- spec/support/markdown_pact.json
|
1063
|
+
- spec/support/markdown_pact_with_markdown_chars_in_names.json
|
1043
1064
|
- spec/support/migration_helpers.rb
|
1044
1065
|
- spec/support/rspec_match_hash.rb
|
1045
1066
|
- spec/support/rspec_matchers.rb
|
1046
1067
|
- spec/support/shared_examples_for_responses.rb
|
1047
1068
|
- spec/support/ssl_webhook_server.rb
|
1048
1069
|
- spec/support/test_data_builder.rb
|
1070
|
+
- spec/support/warning_silencer.rb
|
1049
1071
|
- tasks/database.rb
|
1050
1072
|
- tasks/database/table_dependency_calculator.rb
|
1051
1073
|
- tasks/db.rake
|
@@ -1170,6 +1192,10 @@ test_files:
|
|
1170
1192
|
- spec/integration/endpoints/group_spec.rb
|
1171
1193
|
- spec/integration/ui/index_spec.rb
|
1172
1194
|
- spec/integration/webhooks/certificate_spec.rb
|
1195
|
+
- spec/lib/pact/doc/generator_spec.rb
|
1196
|
+
- spec/lib/pact/doc/interaction_view_model_spec.rb
|
1197
|
+
- spec/lib/pact/doc/markdown/consumer_contract_renderer_spec.rb
|
1198
|
+
- spec/lib/pact/doc/markdown/index_renderer_spec.rb
|
1173
1199
|
- spec/lib/pact_broker/api/contracts/put_pact_params_contract_spec.rb
|
1174
1200
|
- spec/lib/pact_broker/api/contracts/verification_contract_spec.rb
|
1175
1201
|
- spec/lib/pact_broker/api/contracts/webhook_contract_spec.rb
|
@@ -1291,9 +1317,16 @@ test_files:
|
|
1291
1317
|
- spec/spec_helper.rb
|
1292
1318
|
- spec/support/database_cleaner.rb
|
1293
1319
|
- spec/support/fixture_helpers.rb
|
1320
|
+
- spec/support/generated_index.md
|
1321
|
+
- spec/support/generated_markdown.md
|
1322
|
+
- spec/support/interaction_view_model.json
|
1323
|
+
- spec/support/interaction_view_model_with_terms.json
|
1324
|
+
- spec/support/markdown_pact.json
|
1325
|
+
- spec/support/markdown_pact_with_markdown_chars_in_names.json
|
1294
1326
|
- spec/support/migration_helpers.rb
|
1295
1327
|
- spec/support/rspec_match_hash.rb
|
1296
1328
|
- spec/support/rspec_matchers.rb
|
1297
1329
|
- spec/support/shared_examples_for_responses.rb
|
1298
1330
|
- spec/support/ssl_webhook_server.rb
|
1299
1331
|
- spec/support/test_data_builder.rb
|
1332
|
+
- spec/support/warning_silencer.rb
|