pact-support 0.0.1
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.
- checksums.yaml +15 -0
- data/.gitignore +29 -0
- data/.rspec +2 -0
- data/.travis.yml +8 -0
- data/CHANGELOG.md +4 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +80 -0
- data/LICENSE.txt +22 -0
- data/README.md +4 -0
- data/Rakefile +4 -0
- data/lib/pact/configuration.rb +164 -0
- data/lib/pact/consumer/request.rb +27 -0
- data/lib/pact/consumer_contract.rb +1 -0
- data/lib/pact/consumer_contract/consumer_contract.rb +114 -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 +73 -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/response.rb +51 -0
- data/lib/pact/consumer_contract/service_consumer.rb +28 -0
- data/lib/pact/consumer_contract/service_provider.rb +28 -0
- data/lib/pact/logging.rb +14 -0
- data/lib/pact/matchers.rb +1 -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 +139 -0
- 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/reification.rb +28 -0
- 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 +97 -0
- data/lib/pact/shared/text_differ.rb +14 -0
- data/lib/pact/something_like.rb +49 -0
- data/lib/pact/support.rb +9 -0
- data/lib/pact/support/version.rb +5 -0
- data/lib/pact/symbolize_keys.rb +12 -0
- data/lib/pact/term.rb +85 -0
- data/lib/tasks/pact.rake +29 -0
- data/pact-support.gemspec +35 -0
- data/spec/lib/pact/consumer/request_spec.rb +25 -0
- data/spec/lib/pact/consumer_contract/active_support_support_spec.rb +58 -0
- data/spec/lib/pact/consumer_contract/consumer_contract_spec.rb +141 -0
- data/spec/lib/pact/consumer_contract/headers_spec.rb +107 -0
- data/spec/lib/pact/consumer_contract/interaction_spec.rb +151 -0
- data/spec/lib/pact/consumer_contract/request_spec.rb +329 -0
- data/spec/lib/pact/consumer_contract/response_spec.rb +73 -0
- data/spec/lib/pact/matchers/differ_spec.rb +215 -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 +120 -0
- data/spec/lib/pact/matchers/matchers_spec.rb +500 -0
- 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/reification_spec.rb +67 -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 +196 -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/term_spec.rb +89 -0
- data/spec/spec_helper.rb +19 -0
- data/spec/support/a_consumer-a_producer.json +32 -0
- data/spec/support/a_consumer-a_provider.json +32 -0
- data/spec/support/active_support_if_configured.rb +6 -0
- data/spec/support/case-insensitive-response-header-matching.json +21 -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/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/term.json +48 -0
- data/spec/support/test_app_fail.json +61 -0
- data/spec/support/test_app_pass.json +38 -0
- data/spec/support/test_app_with_right_content_type_differ.json +23 -0
- data/tasks/spec.rake +6 -0
- metadata +401 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
!binary "U0hBMQ==":
|
|
3
|
+
metadata.gz: !binary |-
|
|
4
|
+
ZmE3YmExODMzYzc4ODljOWNiMjQ5NTZmMjFlYjUwYjBkZmZjNTY1Zg==
|
|
5
|
+
data.tar.gz: !binary |-
|
|
6
|
+
MGYzMWNkOTU5M2MxOWQwMzY2Mzg2NTI4YWMyNWM2ZTVhN2QxOTBlMA==
|
|
7
|
+
SHA512:
|
|
8
|
+
metadata.gz: !binary |-
|
|
9
|
+
NmM1ZjFlODEwNTlmNzM3ZTU2NjM1ZmJkOWI4OGQ0YjE4NjlkNDMwNThiZjI3
|
|
10
|
+
MDZhZDIzMDk4NTBmZDY2Y2EzZThjYjViMWVhM2FlNDVmMTVhNmY3YjU2NGM1
|
|
11
|
+
M2JlY2IzNzRkZDM4OGQ3NzhjOGIwYWE4YmI1YmE3N2Y2MmI0ZmM=
|
|
12
|
+
data.tar.gz: !binary |-
|
|
13
|
+
YjJiOGEwMmJmOGNmZjczMjY4MDU3ZDE2NzY3NmQ2NDMwZTVkN2FlYzA1MzZk
|
|
14
|
+
MmQ5MGMyNDdlNDg5YmE0MzA2N2M2ODg2ZDI3YzQ2MjI2NTI4Y2QxYWI5ZmE5
|
|
15
|
+
OTY2YTJlNWEzMGVmNzliYzI4ZmUwNzQ2MDFlM2M1OWQ0YmMwNGI=
|
data/.gitignore
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
*.gem
|
|
2
|
+
*.rbc
|
|
3
|
+
.bundle
|
|
4
|
+
.config
|
|
5
|
+
.yardoc
|
|
6
|
+
InstalledFiles
|
|
7
|
+
_yardoc
|
|
8
|
+
coverage
|
|
9
|
+
lib/bundler/man
|
|
10
|
+
pkg
|
|
11
|
+
rdoc
|
|
12
|
+
spec/reports
|
|
13
|
+
test/tmp
|
|
14
|
+
test/version_tmp
|
|
15
|
+
tmp
|
|
16
|
+
*.swp
|
|
17
|
+
.bin
|
|
18
|
+
tags
|
|
19
|
+
.rbenv-version
|
|
20
|
+
spec/pacts
|
|
21
|
+
.rvmrc
|
|
22
|
+
*.iml
|
|
23
|
+
.rakeTasks
|
|
24
|
+
*~
|
|
25
|
+
.ruby-gemset
|
|
26
|
+
.ruby-version
|
|
27
|
+
log
|
|
28
|
+
.idea
|
|
29
|
+
reports
|
data/.rspec
ADDED
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
pact-support (0.0.1)
|
|
5
|
+
awesome_print (~> 1.1)
|
|
6
|
+
find_a_port (~> 1.0.1)
|
|
7
|
+
json
|
|
8
|
+
rack-test (~> 0.6.2)
|
|
9
|
+
randexp (~> 0.1.7)
|
|
10
|
+
rspec (>= 2.14)
|
|
11
|
+
term-ansicolor (~> 1.0)
|
|
12
|
+
thor
|
|
13
|
+
|
|
14
|
+
GEM
|
|
15
|
+
remote: https://rubygems.org/
|
|
16
|
+
specs:
|
|
17
|
+
activesupport (4.1.1)
|
|
18
|
+
i18n (~> 0.6, >= 0.6.9)
|
|
19
|
+
json (~> 1.7, >= 1.7.7)
|
|
20
|
+
minitest (~> 5.1)
|
|
21
|
+
thread_safe (~> 0.1)
|
|
22
|
+
tzinfo (~> 1.1)
|
|
23
|
+
addressable (2.3.6)
|
|
24
|
+
awesome_print (1.2.0)
|
|
25
|
+
coderay (1.1.0)
|
|
26
|
+
crack (0.4.2)
|
|
27
|
+
safe_yaml (~> 1.0.0)
|
|
28
|
+
diff-lcs (1.2.5)
|
|
29
|
+
fakefs (0.5.2)
|
|
30
|
+
find_a_port (1.0.1)
|
|
31
|
+
hashie (2.1.1)
|
|
32
|
+
i18n (0.6.9)
|
|
33
|
+
json (1.8.1)
|
|
34
|
+
method_source (0.8.2)
|
|
35
|
+
minitest (5.3.4)
|
|
36
|
+
pry (0.10.0)
|
|
37
|
+
coderay (~> 1.1.0)
|
|
38
|
+
method_source (~> 0.8.1)
|
|
39
|
+
slop (~> 3.4)
|
|
40
|
+
rack (1.5.2)
|
|
41
|
+
rack-test (0.6.2)
|
|
42
|
+
rack (>= 1.0)
|
|
43
|
+
rake (10.0.4)
|
|
44
|
+
randexp (0.1.7)
|
|
45
|
+
rspec (3.1.0)
|
|
46
|
+
rspec-core (~> 3.1.0)
|
|
47
|
+
rspec-expectations (~> 3.1.0)
|
|
48
|
+
rspec-mocks (~> 3.1.0)
|
|
49
|
+
rspec-core (3.1.6)
|
|
50
|
+
rspec-support (~> 3.1.0)
|
|
51
|
+
rspec-expectations (3.1.2)
|
|
52
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
53
|
+
rspec-support (~> 3.1.0)
|
|
54
|
+
rspec-mocks (3.1.3)
|
|
55
|
+
rspec-support (~> 3.1.0)
|
|
56
|
+
rspec-support (3.1.2)
|
|
57
|
+
safe_yaml (1.0.3)
|
|
58
|
+
slop (3.5.0)
|
|
59
|
+
term-ansicolor (1.3.0)
|
|
60
|
+
tins (~> 1.0)
|
|
61
|
+
thor (0.19.1)
|
|
62
|
+
thread_safe (0.3.4)
|
|
63
|
+
tins (1.3.3)
|
|
64
|
+
tzinfo (1.2.1)
|
|
65
|
+
thread_safe (~> 0.1)
|
|
66
|
+
webmock (1.18.0)
|
|
67
|
+
addressable (>= 2.3.6)
|
|
68
|
+
crack (>= 0.3.2)
|
|
69
|
+
|
|
70
|
+
PLATFORMS
|
|
71
|
+
ruby
|
|
72
|
+
|
|
73
|
+
DEPENDENCIES
|
|
74
|
+
activesupport
|
|
75
|
+
fakefs (~> 0.4)
|
|
76
|
+
hashie (~> 2.0)
|
|
77
|
+
pact-support!
|
|
78
|
+
pry
|
|
79
|
+
rake (~> 10.0.3)
|
|
80
|
+
webmock (~> 1.18.0)
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2013 James Fraser, Sergei Matheson, Brent Snook, Ronald Holshausen, Beth Skurrie
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
data/Rakefile
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
require 'pact/matchers/embedded_diff_formatter'
|
|
2
|
+
require 'pact/matchers/unix_diff_formatter'
|
|
3
|
+
require 'pact/matchers/list_diff_formatter'
|
|
4
|
+
require 'pact/shared/json_differ'
|
|
5
|
+
require 'pact/shared/text_differ'
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
module Pact
|
|
9
|
+
|
|
10
|
+
class Configuration
|
|
11
|
+
|
|
12
|
+
DIFF_FORMATTERS = {
|
|
13
|
+
:embedded => Pact::Matchers::EmbeddedDiffFormatter,
|
|
14
|
+
:unix => Pact::Matchers::UnixDiffFormatter,
|
|
15
|
+
:list => Pact::Matchers::ListDiffFormatter
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class NilMatcher
|
|
20
|
+
def self.=~ other
|
|
21
|
+
other == nil ? 0 : nil
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
DIFF_FORMATTER_REGISTRATIONS = [
|
|
26
|
+
[/.*/, Pact::Matchers::UnixDiffFormatter],
|
|
27
|
+
[NilMatcher, Pact::Matchers::UnixDiffFormatter]
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
DIFFERS = [
|
|
31
|
+
[/json/, Pact::JsonDiffer],
|
|
32
|
+
[NilMatcher, Pact::TextDiffer],
|
|
33
|
+
[/.*/, Pact::TextDiffer]
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
DEFAULT_DIFFER = Pact::TextDiffer
|
|
38
|
+
|
|
39
|
+
attr_accessor :pact_dir
|
|
40
|
+
attr_accessor :log_dir
|
|
41
|
+
attr_accessor :tmp_dir
|
|
42
|
+
|
|
43
|
+
attr_writer :logger
|
|
44
|
+
|
|
45
|
+
attr_accessor :error_stream
|
|
46
|
+
attr_accessor :output_stream
|
|
47
|
+
|
|
48
|
+
def self.default_configuration
|
|
49
|
+
c = Configuration.new
|
|
50
|
+
c.pact_dir = File.expand_path('./spec/pacts')
|
|
51
|
+
c.tmp_dir = File.expand_path('./tmp/pacts')
|
|
52
|
+
c.log_dir = default_log_dir
|
|
53
|
+
|
|
54
|
+
c.output_stream = $stdout
|
|
55
|
+
c.error_stream = $stderr
|
|
56
|
+
|
|
57
|
+
c
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def initialize
|
|
61
|
+
@differ_registrations = []
|
|
62
|
+
@diff_formatter_registrations = []
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def logger
|
|
66
|
+
@logger ||= create_logger
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Should this be deprecated in favour of register_diff_formatter???
|
|
70
|
+
def diff_formatter= diff_formatter
|
|
71
|
+
register_diff_formatter /.*/, diff_formatter
|
|
72
|
+
register_diff_formatter nil, diff_formatter
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def register_diff_formatter content_type, diff_formatter
|
|
76
|
+
key = content_type_regexp_for content_type
|
|
77
|
+
@diff_formatter_registrations << [key, diff_formatter_for(diff_formatter)]
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def diff_formatter_for_content_type content_type
|
|
81
|
+
diff_formatter_registrations.find{ | registration | registration.first =~ content_type }.last
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def register_body_differ content_type, differ
|
|
85
|
+
key = content_type_regexp_for content_type
|
|
86
|
+
validate_differ differ
|
|
87
|
+
@differ_registrations << [key, differ]
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def body_differ_for_content_type content_type
|
|
91
|
+
differ_registrations.find{ | registration | registration.first =~ content_type }.last
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def log_path
|
|
95
|
+
log_dir + "/pact.log"
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
private
|
|
99
|
+
|
|
100
|
+
def diff_formatter_for input
|
|
101
|
+
if DIFF_FORMATTERS[input]
|
|
102
|
+
DIFF_FORMATTERS[input]
|
|
103
|
+
elsif input.respond_to?(:call)
|
|
104
|
+
input
|
|
105
|
+
else
|
|
106
|
+
raise "Pact diff_formatter needs to respond to call, or be in the preconfigured list: #{DIFF_FORMATTERS.keys}"
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def validate_differ differ
|
|
111
|
+
if !differ.respond_to?(:call)
|
|
112
|
+
raise "Pact.configuration.register_body_differ expects a differ that is a lamda or a class/object that responds to call."
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def content_type_regexp_for content_type
|
|
117
|
+
case content_type
|
|
118
|
+
when String then Regexp.new(/^#{Regexp.escape(content_type)}$/)
|
|
119
|
+
when Regexp then content_type
|
|
120
|
+
when nil then NilMatcher
|
|
121
|
+
else
|
|
122
|
+
raise "Invalid content type used to register a differ (#{content_type.inspect}). Please use a Regexp or a String."
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def differ_registrations
|
|
127
|
+
@differ_registrations + DIFFERS
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def diff_formatter_registrations
|
|
131
|
+
@diff_formatter_registrations + DIFF_FORMATTER_REGISTRATIONS
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def self.default_log_dir
|
|
135
|
+
File.expand_path("./log")
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
#Would love a better way of determining this! It sure won't work on windows.
|
|
139
|
+
def is_rake_running?
|
|
140
|
+
`ps -ef | grep rake | grep #{Process.ppid} | grep -v 'grep'`.size > 0
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def create_logger
|
|
144
|
+
FileUtils::mkdir_p log_dir
|
|
145
|
+
logger = Logger.new(log_path)
|
|
146
|
+
logger.level = Logger::DEBUG
|
|
147
|
+
logger
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def self.configuration
|
|
152
|
+
@configuration ||= Configuration.default_configuration
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def self.configure
|
|
156
|
+
yield configuration
|
|
157
|
+
FileUtils::mkdir_p configuration.tmp_dir
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def self.clear_configuration
|
|
161
|
+
@configuration = nil
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require 'pact/shared/request'
|
|
2
|
+
require 'pact/shared/key_not_found'
|
|
3
|
+
|
|
4
|
+
module Pact
|
|
5
|
+
module Consumer
|
|
6
|
+
module Request
|
|
7
|
+
class Actual < Pact::Request::Base
|
|
8
|
+
|
|
9
|
+
def self.from_hash(hash)
|
|
10
|
+
sym_hash = symbolize_keys hash
|
|
11
|
+
method = sym_hash.fetch(:method)
|
|
12
|
+
path = sym_hash.fetch(:path)
|
|
13
|
+
query = sym_hash.fetch(:query)
|
|
14
|
+
headers = sym_hash.fetch(:headers)
|
|
15
|
+
body = sym_hash.fetch(:body, nil)
|
|
16
|
+
new(method, path, headers, body, query)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
protected
|
|
20
|
+
|
|
21
|
+
def self.key_not_found
|
|
22
|
+
nil
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require 'pact/consumer_contract/consumer_contract'
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
require 'pact/logging'
|
|
2
|
+
require 'pact/something_like'
|
|
3
|
+
require 'pact/symbolize_keys'
|
|
4
|
+
require 'pact/term'
|
|
5
|
+
require 'pact/shared/active_support_support'
|
|
6
|
+
require 'date'
|
|
7
|
+
require 'json/add/regexp'
|
|
8
|
+
require 'open-uri'
|
|
9
|
+
require_relative 'service_consumer'
|
|
10
|
+
require_relative 'service_provider'
|
|
11
|
+
require_relative 'interaction'
|
|
12
|
+
require_relative 'request'
|
|
13
|
+
require_relative 'pact_file'
|
|
14
|
+
require_relative 'file_name'
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
module Pact
|
|
19
|
+
|
|
20
|
+
class ConsumerContract
|
|
21
|
+
|
|
22
|
+
include SymbolizeKeys
|
|
23
|
+
include Logging
|
|
24
|
+
include FileName
|
|
25
|
+
include ActiveSupportSupport
|
|
26
|
+
|
|
27
|
+
attr_accessor :interactions
|
|
28
|
+
attr_accessor :consumer
|
|
29
|
+
attr_accessor :provider
|
|
30
|
+
|
|
31
|
+
def initialize(attributes = {})
|
|
32
|
+
@interactions = attributes[:interactions] || []
|
|
33
|
+
@consumer = attributes[:consumer]
|
|
34
|
+
@provider = attributes[:provider]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def to_hash
|
|
38
|
+
{
|
|
39
|
+
provider: @provider.as_json,
|
|
40
|
+
consumer: @consumer.as_json,
|
|
41
|
+
interactions: @interactions.collect(&:as_json),
|
|
42
|
+
metadata: {
|
|
43
|
+
pactSpecificationVersion: "1.0.0"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def as_json(options = {})
|
|
49
|
+
fix_all_the_things to_hash
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def to_json(options = {})
|
|
53
|
+
as_json.to_json(options)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def self.from_hash(hash)
|
|
57
|
+
hash = symbolize_keys(hash)
|
|
58
|
+
new({
|
|
59
|
+
:interactions => hash[:interactions].collect { |hash| Interaction.from_hash(hash)},
|
|
60
|
+
:consumer => ServiceConsumer.from_hash(hash[:consumer]),
|
|
61
|
+
:provider => ServiceProvider.from_hash(hash[:provider])
|
|
62
|
+
})
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def self.from_json string
|
|
66
|
+
deserialised_object = JSON.load(maintain_backwards_compatiblity_with_producer_keys(string))
|
|
67
|
+
from_hash(deserialised_object)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def self.from_uri uri, options = {}
|
|
71
|
+
from_json(Pact::PactFile.read(uri, options))
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def self.maintain_backwards_compatiblity_with_producer_keys string
|
|
75
|
+
string.gsub('"producer":', '"provider":').gsub('"producer_state":', '"provider_state":')
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def find_interaction criteria
|
|
79
|
+
interactions = find_interactions criteria
|
|
80
|
+
if interactions.size == 0
|
|
81
|
+
raise "Could not find interaction matching #{criteria} in pact file between #{consumer.name} and #{provider.name}."
|
|
82
|
+
elsif interactions.size > 1
|
|
83
|
+
raise "Found more than 1 interaction matching #{criteria} in pact file between #{consumer.name} and #{provider.name}."
|
|
84
|
+
end
|
|
85
|
+
interactions.first
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def find_interactions criteria
|
|
89
|
+
interactions.select{ | interaction| interaction.matches_criteria?(criteria)}
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def each
|
|
93
|
+
interactions.each do | interaction |
|
|
94
|
+
yield interaction
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def pact_file_name
|
|
99
|
+
file_name consumer.name, provider.name
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def pactfile_path
|
|
103
|
+
raise 'You must first specify a consumer and service name' unless (consumer && consumer.name && provider && provider.name)
|
|
104
|
+
@pactfile_path ||= file_path consumer.name, provider.name
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def update_pactfile
|
|
108
|
+
logger.debug "Updating pact file for #{provider.name} at #{pactfile_path}"
|
|
109
|
+
File.open(pactfile_path, 'w') do |f|
|
|
110
|
+
f.write fix_json_formatting(JSON.pretty_generate(self))
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|