pacto 0.3.0 → 0.3.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 +4 -4
- data/.gitignore +1 -2
- data/CHANGELOG +12 -0
- data/CONTRIBUTING.md +6 -0
- data/Gemfile +6 -1
- data/README.md +5 -1
- data/Rakefile +36 -1
- data/features/generate/generation.feature +51 -0
- data/lib/pacto/contract.rb +1 -1
- data/lib/pacto/core/configuration.rb +1 -1
- data/lib/pacto/core/validation_registry.rb +1 -6
- data/lib/pacto/erb_processor.rb +2 -1
- data/lib/pacto/generator.rb +7 -0
- data/lib/pacto/logger.rb +42 -36
- data/lib/pacto/stubs/webmock_helper.rb +2 -4
- data/lib/pacto/validation.rb +1 -4
- data/lib/pacto/validators/body_validator.rb +13 -5
- data/lib/pacto/validators/request_body_validator.rb +5 -2
- data/lib/pacto/validators/response_body_validator.rb +5 -2
- data/lib/pacto/version.rb +1 -1
- data/pacto.gemspec +20 -15
- data/spec/integration/data/simple_contract.json +1 -1
- data/spec/integration/rspec_spec.rb +14 -5
- data/spec/pacto/server/dummy.rb +3 -1
- data/spec/unit/pacto/configuration_spec.rb +1 -1
- data/spec/unit/pacto/contract_validator_spec.rb +6 -6
- data/spec/unit/pacto/erb_processor_spec.rb +1 -1
- data/spec/unit/pacto/generator_spec.rb +40 -11
- data/spec/unit/pacto/logger_spec.rb +42 -40
- data/spec/unit/pacto/stubs/webmock_adapter_spec.rb +3 -2
- data/spec/unit/pacto/validators/body_validator_spec.rb +25 -12
- metadata +49 -50
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 18ae0d545ae833247f073b842eb80cae0bfe15bd
|
4
|
+
data.tar.gz: 7bbc42514d8b1efecaa5dd650d042f4135ead5da
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b3518a69c9f3d65f241f23ed2879349b6016f9411c2991e2bbed85a63ad0091959aedb5d829f7111f14c47a4596a158bf5b3294e8e8c8a951c45f63629cd374a
|
7
|
+
data.tar.gz: 22d00ac297683e0233c7d002891f5a5f26e133dbc8f7590a3431b567b48200ddd5c0fc02750f9eb17dcd077480a8fe15a9846c8d885f84c51595c1c3cc290fbb
|
data/.gitignore
CHANGED
data/CHANGELOG
ADDED
data/CONTRIBUTING.md
CHANGED
@@ -77,6 +77,12 @@ tasks:
|
|
77
77
|
- Integration tests (`bundle exec rake integration`).
|
78
78
|
- User journey tests (`bundle exec rake journey`).
|
79
79
|
|
80
|
+
It is also possible run specific tests:
|
81
|
+
|
82
|
+
- Unit tests (`bundle exec rspec spec/unit/[file_path]`
|
83
|
+
- Integration tests (`bundle exec rspec spec/integration/[file_path]`)
|
84
|
+
- User journey tests (`bundle exec cucumber features/[file_path] -r features/support/env.rb`)
|
85
|
+
|
80
86
|
### Checking that all is green
|
81
87
|
|
82
88
|
To know that both tests and static analysis is working fine you just have to
|
data/Gemfile
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
3
|
# Specify your gem's dependencies in pacto.gemspec
|
4
|
-
gemspec
|
4
|
+
gemspec :name => 'pacto'
|
5
|
+
|
6
|
+
Dir['pacto-*.gemspec'].each do |gemspec|
|
7
|
+
plugin = gemspec.scan(/pacto-(.*)\.gemspec/).flatten.first
|
8
|
+
gemspec(:name => "pacto-#{plugin}", :development_group => plugin)
|
9
|
+
end
|
5
10
|
|
6
11
|
# This is only used by Relish tests. Putting it here let's travis
|
7
12
|
# pre-install so we can speed up the test with `bundle install --local`,
|
data/README.md
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
**If you're viewing this at https://github.com/thoughtworks/pacto,
|
8
8
|
you're reading the documentation for the master branch.
|
9
9
|
[View documentation for the latest release
|
10
|
-
(0.
|
10
|
+
(0.3.0).](https://github.com/thoughtworks/pacto/tree/v0.3.0)**
|
11
11
|
|
12
12
|
# Pacto
|
13
13
|
|
@@ -44,6 +44,8 @@ Pacto can provide a [**contract writer**](#generating) that tries to strike a ba
|
|
44
44
|
|
45
45
|
## Usage
|
46
46
|
|
47
|
+
**See also: http://thoughtworks.github.io/pacto/usage/**
|
48
|
+
|
47
49
|
Pacto can perform three activities: generating, validating, or stubbing services. You can do each of these activities against either live or stubbed services.
|
48
50
|
|
49
51
|
### Configuration
|
@@ -122,6 +124,8 @@ contracts.stub_all(request_id: 14, name: "Marcos")
|
|
122
124
|
|
123
125
|
## Pacto Server (non-Ruby usage)
|
124
126
|
|
127
|
+
**See also: http://thoughtworks.github.io/pacto/patterns/polyglot/**
|
128
|
+
|
125
129
|
It is really easy to embed Pacto inside a small server. We haven't bundled a server inside of Pacto, but check out [pacto-demo](https://github.com/thoughtworks/pacto-demo) to see how easily you can expose Pacto via server.
|
126
130
|
|
127
131
|
That demo lets you easily run a server in several modes:
|
data/Rakefile
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'bundler/gem_tasks'
|
2
1
|
require 'rspec/core/rake_task'
|
3
2
|
require 'pacto/rake_task'
|
4
3
|
require 'cucumber'
|
@@ -27,3 +26,39 @@ RSpec::Core::RakeTask.new(:integration) do |t|
|
|
27
26
|
end
|
28
27
|
|
29
28
|
task :default => [:unit, :integration, :journeys, :rubocop, 'coveralls:push']
|
29
|
+
|
30
|
+
desc 'Build gems into the pkg directory'
|
31
|
+
task :build do
|
32
|
+
FileUtils.rm_rf('pkg')
|
33
|
+
Dir['*.gemspec'].each do |gemspec|
|
34
|
+
system "gem build #{gemspec}"
|
35
|
+
end
|
36
|
+
FileUtils.mkdir_p('pkg')
|
37
|
+
FileUtils.mv(Dir['*.gem'], 'pkg')
|
38
|
+
end
|
39
|
+
|
40
|
+
desc 'Tags version, pushes to remote, and pushes gems'
|
41
|
+
task :release => :build do
|
42
|
+
sh 'git', 'tag', '-m', changelog, "v#{Pacto::VERSION}"
|
43
|
+
sh 'git push origin master'
|
44
|
+
sh "git push origin v#{Pacto::VERSION}"
|
45
|
+
sh 'ls pkg/*.gem | xargs -n 1 gem push'
|
46
|
+
end
|
47
|
+
|
48
|
+
task :changelog do
|
49
|
+
changelog
|
50
|
+
end
|
51
|
+
|
52
|
+
def changelog
|
53
|
+
changelog = File.read('CHANGELOG').split("\n\n\n", 2).first
|
54
|
+
confirm "Does the CHANGELOG look correct? ", changelog
|
55
|
+
end
|
56
|
+
|
57
|
+
def confirm(question, data)
|
58
|
+
puts "Please confirm..."
|
59
|
+
puts data
|
60
|
+
print question
|
61
|
+
abort "Aborted" unless $stdin.gets.strip == 'y'
|
62
|
+
puts "Confirmed"
|
63
|
+
data
|
64
|
+
end
|
@@ -26,3 +26,54 @@ Feature: Contract Generation
|
|
26
26
|
}
|
27
27
|
}
|
28
28
|
"""
|
29
|
+
|
30
|
+
Scenario: Generating a contract using the rake task
|
31
|
+
Given a directory named "contracts"
|
32
|
+
When I successfully run `bundle exec rake pacto:generate['tmp/aruba/requests','tmp/aruba/contracts','http://localhost:8000']`
|
33
|
+
Then the output should contain "Successfully generated all contracts"
|
34
|
+
|
35
|
+
Scenario: Generating a contract programmatically
|
36
|
+
Given a file named "generate.rb" with:
|
37
|
+
"""ruby
|
38
|
+
require 'pacto'
|
39
|
+
|
40
|
+
WebMock.allow_net_connect!
|
41
|
+
generator = Pacto::Generator.new
|
42
|
+
contract = generator.generate('requests/my_contract.json', 'http://localhost:8000')
|
43
|
+
puts contract
|
44
|
+
"""
|
45
|
+
When I successfully run `bundle exec ruby generate.rb`
|
46
|
+
Then the output should contain exactly:
|
47
|
+
"""json
|
48
|
+
{
|
49
|
+
"request": {
|
50
|
+
"headers": {
|
51
|
+
"Accept": "application/json"
|
52
|
+
},
|
53
|
+
"method": "get",
|
54
|
+
"params": {
|
55
|
+
},
|
56
|
+
"path": "/hello"
|
57
|
+
},
|
58
|
+
"response": {
|
59
|
+
"headers": {
|
60
|
+
"Content-Type": "application/json",
|
61
|
+
"Vary": "Accept"
|
62
|
+
},
|
63
|
+
"status": 200,
|
64
|
+
"body": {
|
65
|
+
"$schema": "http://json-schema.org/draft-03/schema#",
|
66
|
+
"description": "Generated from requests/my_contract.json with shasum 210fa3b144ef2db8d1c160c4d9e8d8bf738ed851",
|
67
|
+
"type": "object",
|
68
|
+
"required": true,
|
69
|
+
"properties": {
|
70
|
+
"message": {
|
71
|
+
"type": "string",
|
72
|
+
"required": true
|
73
|
+
}
|
74
|
+
}
|
75
|
+
}
|
76
|
+
}
|
77
|
+
}
|
78
|
+
|
79
|
+
"""
|
data/lib/pacto/contract.rb
CHANGED
@@ -5,7 +5,7 @@ module Pacto
|
|
5
5
|
def initialize(request, response, file, name = nil, request_pattern_provider = RequestPattern)
|
6
6
|
@request = request
|
7
7
|
@response = response
|
8
|
-
@file = file.to_s
|
8
|
+
@file = Addressable::URI.convert_path(file.to_s).to_s
|
9
9
|
@name = name || @file
|
10
10
|
@request_pattern = request_pattern_provider.for(request)
|
11
11
|
@values = {}
|
@@ -8,7 +8,7 @@ module Pacto
|
|
8
8
|
@provider = Stubs::WebMockAdapter.new
|
9
9
|
@strict_matchers = true
|
10
10
|
@contracts_path = nil
|
11
|
-
@logger = Logger.instance
|
11
|
+
@logger = Logger::SimpleLogger.instance
|
12
12
|
define_logger_level
|
13
13
|
@hook = Hook.new {}
|
14
14
|
@generator_options = { :schema_version => 'draft3' }
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module Pacto
|
2
2
|
class ValidationRegistry
|
3
3
|
include Singleton
|
4
|
+
include Logger
|
4
5
|
attr_reader :validations
|
5
6
|
|
6
7
|
def initialize
|
@@ -35,11 +36,5 @@ module Pacto
|
|
35
36
|
!validation.successful?
|
36
37
|
end
|
37
38
|
end
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
def logger
|
42
|
-
@logger ||= Logger.instance
|
43
|
-
end
|
44
39
|
end
|
45
40
|
end
|
data/lib/pacto/erb_processor.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
module Pacto
|
2
2
|
class ERBProcessor
|
3
|
+
include Logger
|
3
4
|
def process(contract, values = {})
|
4
5
|
erb = ERB.new(contract)
|
5
6
|
erb_result = erb.result hash_binding(values)
|
6
|
-
|
7
|
+
logger.debug "Processed contract: #{erb_result.inspect}"
|
7
8
|
erb_result
|
8
9
|
end
|
9
10
|
|
data/lib/pacto/generator.rb
CHANGED
@@ -14,6 +14,13 @@ module Pacto
|
|
14
14
|
@filters = filters
|
15
15
|
end
|
16
16
|
|
17
|
+
def generate(request_file, host)
|
18
|
+
contract = Pacto.load_contract request_file, host
|
19
|
+
request = contract.request
|
20
|
+
response = contract.request.execute
|
21
|
+
save(request_file, request, response)
|
22
|
+
end
|
23
|
+
|
17
24
|
def save(source, request, response)
|
18
25
|
contract = generate_contract source, request, response
|
19
26
|
pretty_contract = MultiJson.encode(contract, :pretty => true)
|
data/lib/pacto/logger.rb
CHANGED
@@ -1,44 +1,50 @@
|
|
1
1
|
require 'forwardable'
|
2
2
|
|
3
3
|
module Pacto
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
def_delegators :@log, :debug, :info, :warn, :error, :fatal
|
9
|
-
|
10
|
-
def initialize
|
11
|
-
log ::Logger.new STDOUT
|
12
|
-
end
|
13
|
-
|
14
|
-
def log(log)
|
15
|
-
@log = log
|
16
|
-
@log.level = default_level
|
17
|
-
@log.progname = 'Pacto'
|
18
|
-
end
|
19
|
-
|
20
|
-
def level=(level)
|
21
|
-
@log.level = log_levels.fetch(level, default_level)
|
22
|
-
end
|
23
|
-
|
24
|
-
def level
|
25
|
-
log_levels.key @log.level
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
def default_level
|
31
|
-
::Logger::ERROR
|
4
|
+
module Logger
|
5
|
+
def logger
|
6
|
+
Pacto.configuration.logger
|
32
7
|
end
|
33
8
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
9
|
+
class SimpleLogger
|
10
|
+
include Singleton
|
11
|
+
extend Forwardable
|
12
|
+
|
13
|
+
def_delegators :@log, :debug, :info, :warn, :error, :fatal
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
log ::Logger.new STDOUT
|
17
|
+
end
|
18
|
+
|
19
|
+
def log(log)
|
20
|
+
@log = log
|
21
|
+
@log.level = default_level
|
22
|
+
@log.progname = 'Pacto'
|
23
|
+
end
|
24
|
+
|
25
|
+
def level=(level)
|
26
|
+
@log.level = log_levels.fetch(level, default_level)
|
27
|
+
end
|
28
|
+
|
29
|
+
def level
|
30
|
+
log_levels.key @log.level
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def default_level
|
36
|
+
::Logger::ERROR
|
37
|
+
end
|
38
|
+
|
39
|
+
def log_levels
|
40
|
+
{
|
41
|
+
debug: ::Logger::DEBUG,
|
42
|
+
info: ::Logger::INFO,
|
43
|
+
warn: ::Logger::WARN,
|
44
|
+
error: ::Logger::ERROR,
|
45
|
+
fatal: ::Logger::FATAL
|
46
|
+
}
|
47
|
+
end
|
42
48
|
end
|
43
49
|
end
|
44
50
|
end
|
@@ -2,6 +2,8 @@ module Pacto
|
|
2
2
|
module Stubs
|
3
3
|
class WebMockHelper
|
4
4
|
class << self
|
5
|
+
include Logger
|
6
|
+
|
5
7
|
def validate(request_signature, response)
|
6
8
|
pacto_response = webmock_to_pacto_response(response)
|
7
9
|
contract = Pacto.contracts_for(request_signature).first
|
@@ -43,10 +45,6 @@ module Pacto
|
|
43
45
|
File.join(Pacto.configuration.contracts_path, uri.host, File.dirname(uri.path), basename)
|
44
46
|
end
|
45
47
|
|
46
|
-
def logger
|
47
|
-
@logger ||= Logger.instance
|
48
|
-
end
|
49
|
-
|
50
48
|
def webmock_to_pacto_request(webmock_request)
|
51
49
|
uri = webmock_request.uri
|
52
50
|
Faraday::Request.create webmock_request.method do |req|
|
data/lib/pacto/validation.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
module Pacto
|
2
2
|
class Validation
|
3
|
+
include Logger
|
3
4
|
attr_reader :request, :response, :contract, :results
|
4
5
|
|
5
6
|
def initialize(request, response, contract)
|
@@ -45,10 +46,6 @@ module Pacto
|
|
45
46
|
|
46
47
|
private
|
47
48
|
|
48
|
-
def logger
|
49
|
-
@logger ||= Logger.instance
|
50
|
-
end
|
51
|
-
|
52
49
|
def validate
|
53
50
|
logger.debug("Validating #{@request}, #{@response} against #{@contract}")
|
54
51
|
@results = contract.validate_consumer(@request, @response)
|
@@ -5,17 +5,24 @@ module Pacto
|
|
5
5
|
fail 'section name should be provided by subclass'
|
6
6
|
end
|
7
7
|
|
8
|
-
def self.
|
8
|
+
def self.subschema(contract)
|
9
|
+
fail 'override to return the proper subschema the contract'
|
10
|
+
end
|
11
|
+
|
12
|
+
# FIXME: https://github.com/thoughtworks/pacto/issues/10#issuecomment-31281238
|
13
|
+
# rubocop:disable MethodLenth
|
14
|
+
def self.validate(contract, body)
|
15
|
+
schema = subschema(contract)
|
9
16
|
if schema
|
17
|
+
schema['id'] = contract.file unless schema.key? 'id'
|
10
18
|
if schema['type'] && schema['type'] == 'string'
|
11
19
|
validate_as_pure_string schema, body.body
|
12
20
|
else
|
13
|
-
|
21
|
+
validate_as_json(schema, body)
|
14
22
|
end
|
15
|
-
|
16
|
-
[]
|
17
|
-
end
|
23
|
+
end || []
|
18
24
|
end
|
25
|
+
# rubocop:enable MethodLenth
|
19
26
|
|
20
27
|
private
|
21
28
|
|
@@ -34,6 +41,7 @@ module Pacto
|
|
34
41
|
end
|
35
42
|
|
36
43
|
def self.validate_as_json(schema, body)
|
44
|
+
body = body.body if body.respond_to? :body
|
37
45
|
JSON::Validator.fully_validate(schema, body, :version => :draft3)
|
38
46
|
end
|
39
47
|
end
|
@@ -9,11 +9,14 @@ module Pacto
|
|
9
9
|
'request'
|
10
10
|
end
|
11
11
|
|
12
|
+
def self.subschema(contract)
|
13
|
+
contract.request.schema
|
14
|
+
end
|
15
|
+
|
12
16
|
def call(env)
|
13
17
|
if env[:validation_results].empty? # skip body validation if we already have other errors
|
14
|
-
expected_body = env[:contract].request.schema
|
15
18
|
actual_body = env[:actual_request]
|
16
|
-
errors = self.class.validate(
|
19
|
+
errors = self.class.validate(env[:contract], actual_body)
|
17
20
|
env[:validation_results].concat errors.compact
|
18
21
|
end
|
19
22
|
@app.call env
|
@@ -9,11 +9,14 @@ module Pacto
|
|
9
9
|
'response'
|
10
10
|
end
|
11
11
|
|
12
|
+
def self.subschema(contract)
|
13
|
+
contract.response.schema
|
14
|
+
end
|
15
|
+
|
12
16
|
def call(env)
|
13
17
|
if env[:validation_results].empty? # skip body validation if we already have other errors
|
14
|
-
expected_body = env[:contract].response.schema
|
15
18
|
actual_body = env[:actual_response]
|
16
|
-
errors = self.class.validate(
|
19
|
+
errors = self.class.validate(env[:contract], actual_body)
|
17
20
|
env[:validation_results].concat errors.compact
|
18
21
|
end
|
19
22
|
@app.call env
|
data/lib/pacto/version.rb
CHANGED
data/pacto.gemspec
CHANGED
@@ -3,6 +3,10 @@ lib = File.expand_path('../lib', __FILE__)
|
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
4
|
require 'pacto/version'
|
5
5
|
|
6
|
+
plugin_files = Dir['pacto-*.gemspec'].map do |gemspec|
|
7
|
+
eval(File.read(gemspec)).files # rubocop:disable Eval
|
8
|
+
end.flatten.uniq
|
9
|
+
|
6
10
|
Gem::Specification.new do |gem|
|
7
11
|
gem.name = 'pacto'
|
8
12
|
gem.version = Pacto::VERSION
|
@@ -13,7 +17,7 @@ Gem::Specification.new do |gem|
|
|
13
17
|
gem.homepage = 'http://thoughtworks.github.io/pacto/'
|
14
18
|
gem.license = 'MIT'
|
15
19
|
|
16
|
-
gem.files = `git ls-files`.split($/) # rubocop:disable SpecialGlobalVars
|
20
|
+
gem.files = `git ls-files`.split($/) - plugin_files # rubocop:disable SpecialGlobalVars
|
17
21
|
gem.executables = gem.files.grep(/^bin\//).map { |f| File.basename(f) }
|
18
22
|
gem.test_files = gem.files.grep(/^(test|spec|features)\//)
|
19
23
|
gem.require_paths = ['lib']
|
@@ -22,24 +26,25 @@ Gem::Specification.new do |gem|
|
|
22
26
|
gem.add_dependency 'middleware', '~> 0.1'
|
23
27
|
gem.add_dependency 'multi_json', '~> 1.8'
|
24
28
|
gem.add_dependency 'json-schema', '~> 2.0'
|
25
|
-
gem.add_dependency 'json-generator', '>= 0.0.5'
|
29
|
+
gem.add_dependency 'json-generator', '~> 0.0', '>= 0.0.5'
|
26
30
|
gem.add_dependency 'hash-deep-merge', '~> 0.1'
|
27
31
|
gem.add_dependency 'faraday', '~> 0.9'
|
28
32
|
gem.add_dependency 'addressable', '~> 2.3'
|
29
|
-
gem.add_dependency 'json-schema-generator', '>= 0.0.7'
|
33
|
+
gem.add_dependency 'json-schema-generator', '~> 0.0', '>= 0.0.7'
|
30
34
|
gem.add_dependency 'term-ansicolor', '~> 1.3'
|
31
35
|
|
32
|
-
gem.add_development_dependency 'coveralls'
|
33
|
-
gem.add_development_dependency 'rake'
|
34
|
-
gem.add_development_dependency 'rake-notes'
|
36
|
+
gem.add_development_dependency 'coveralls', '~> 0'
|
37
|
+
gem.add_development_dependency 'rake', '~> 10.0'
|
38
|
+
gem.add_development_dependency 'rake-notes', '~> 0'
|
35
39
|
gem.add_development_dependency 'rspec', '~> 2.14'
|
36
|
-
gem.add_development_dependency 'should_not'
|
37
|
-
gem.add_development_dependency 'aruba'
|
38
|
-
|
39
|
-
gem.add_development_dependency '
|
40
|
-
gem.add_development_dependency '
|
41
|
-
gem.add_development_dependency '
|
42
|
-
gem.add_development_dependency 'guard-
|
43
|
-
gem.add_development_dependency '
|
44
|
-
gem.add_development_dependency '
|
40
|
+
gem.add_development_dependency 'should_not', '~> 1.0'
|
41
|
+
gem.add_development_dependency 'aruba', '~> 0'
|
42
|
+
# Only required to push documentation, and not easily installed on Windows
|
43
|
+
# gem.add_development_dependency 'relish'
|
44
|
+
gem.add_development_dependency 'guard-rspec', '~> 4.2'
|
45
|
+
gem.add_development_dependency 'rubocop', '~> 0.16'
|
46
|
+
gem.add_development_dependency 'guard-rubocop', '~> 1.0'
|
47
|
+
gem.add_development_dependency 'guard-cucumber', '~> 1.4'
|
48
|
+
gem.add_development_dependency 'rb-fsevent', '~> 0' if RUBY_PLATFORM =~ /darwin/i
|
49
|
+
gem.add_development_dependency 'terminal-notifier-guard', '~> 1.5' if RUBY_PLATFORM =~ /darwin/i
|
45
50
|
end
|
@@ -25,6 +25,13 @@ describe 'pacto/rspec' do
|
|
25
25
|
MultiJson.load(response.body)
|
26
26
|
end
|
27
27
|
|
28
|
+
def play_bad_response
|
29
|
+
contracts.stub_all(:device_id => 1.5)
|
30
|
+
Faraday.get('http://dummyprovider.com/strict') do |req|
|
31
|
+
req.headers = {'Accept' => 'application/json' }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
28
35
|
context 'successful validations' do
|
29
36
|
let(:contracts) do
|
30
37
|
Pacto.load_contracts 'spec/integration/data/', 'http://dummyprovider.com'
|
@@ -82,13 +89,15 @@ describe 'pacto/rspec' do
|
|
82
89
|
end
|
83
90
|
|
84
91
|
it 'displays Contract validation problems' do
|
85
|
-
|
86
|
-
Faraday.get('http://dummyprovider.com/strict') do |req|
|
87
|
-
req.headers = {'Accept' => 'application/json' }
|
88
|
-
end
|
92
|
+
play_bad_response
|
89
93
|
expect_to_raise(/validation errors were found:/) { expect(Pacto).to have_validated(:get, 'http://dummyprovider.com/strict') }
|
90
|
-
|
91
94
|
expect_to_raise(/but the following issues were found:/) { expect(Pacto).to_not have_failed_validations }
|
92
95
|
end
|
96
|
+
|
97
|
+
it 'displays the Contract file' do
|
98
|
+
play_bad_response
|
99
|
+
schema_file_uri = Addressable::URI.convert_path(File.absolute_path strict_contract_path).to_s
|
100
|
+
expect_to_raise(/in schema #{schema_file_uri}/) { expect(Pacto).to have_validated(:get, 'http://dummyprovider.com/strict') }
|
101
|
+
end
|
93
102
|
end
|
94
103
|
end
|
data/spec/pacto/server/dummy.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'webrick'
|
2
2
|
require 'forwardable'
|
3
|
+
require 'tempfile'
|
3
4
|
|
4
5
|
module Pacto
|
5
6
|
module Server
|
@@ -21,10 +22,11 @@ module Pacto
|
|
21
22
|
|
22
23
|
class Dummy
|
23
24
|
def initialize(port, path, response)
|
25
|
+
log_file = File.exists?('/dev/null') ? '/dev/null' : Tempfile.new('log') # So tests run on Windows
|
24
26
|
params = {
|
25
27
|
:Port => port,
|
26
28
|
:AccessLog => [],
|
27
|
-
:Logger => WEBrick::Log.new(
|
29
|
+
:Logger => WEBrick::Log.new(log_file, 7)
|
28
30
|
}
|
29
31
|
@server = WEBrick::HTTPServer.new params
|
30
32
|
@server.mount path, Servlet, response
|
@@ -42,13 +42,13 @@ module Pacto
|
|
42
42
|
|
43
43
|
describe '.validate' do
|
44
44
|
before do
|
45
|
-
allow(Pacto::Validators::RequestBodyValidator).to receive(:validate).with(
|
46
|
-
allow(Pacto::Validators::ResponseBodyValidator).to receive(:validate).with(
|
45
|
+
allow(Pacto::Validators::RequestBodyValidator).to receive(:validate).with(contract, actual_request).and_return([])
|
46
|
+
allow(Pacto::Validators::ResponseBodyValidator).to receive(:validate).with(contract, actual_response).and_return([])
|
47
47
|
end
|
48
48
|
|
49
49
|
context 'default validator stack' do
|
50
50
|
it 'calls the RequestBodyValidator' do
|
51
|
-
expect(Pacto::Validators::RequestBodyValidator).to receive(:validate).with(
|
51
|
+
expect(Pacto::Validators::RequestBodyValidator).to receive(:validate).with(contract, actual_request).and_return(validation_errors)
|
52
52
|
expect(ContractValidator.validate contract, actual_request, actual_response, opts).to eq(validation_errors)
|
53
53
|
end
|
54
54
|
|
@@ -63,7 +63,7 @@ module Pacto
|
|
63
63
|
end
|
64
64
|
|
65
65
|
it 'calls the ResponseBodyValidator' do
|
66
|
-
expect(Pacto::Validators::ResponseBodyValidator).to receive(:validate).with(
|
66
|
+
expect(Pacto::Validators::ResponseBodyValidator).to receive(:validate).with(contract, actual_response).and_return(validation_errors)
|
67
67
|
expect(ContractValidator.validate contract, actual_request, actual_response, opts).to eq(validation_errors)
|
68
68
|
end
|
69
69
|
end
|
@@ -73,10 +73,10 @@ module Pacto
|
|
73
73
|
# JSON::Validator.should_receive(:fully_validate).
|
74
74
|
# with(definition['body'], fake_response.body, :version => :draft3).
|
75
75
|
# and_return([])
|
76
|
-
expect(Pacto::Validators::RequestBodyValidator).to receive(:validate).with(
|
76
|
+
expect(Pacto::Validators::RequestBodyValidator).to receive(:validate).with(contract, actual_request).and_return([])
|
77
77
|
expect(Pacto::Validators::ResponseStatusValidator).to receive(:validate).with(expected_response.status, actual_response.status).and_return([])
|
78
78
|
expect(Pacto::Validators::ResponseHeaderValidator).to receive(:validate).with(expected_response.headers, actual_response.headers).and_return([])
|
79
|
-
expect(Pacto::Validators::ResponseBodyValidator).to receive(:validate).with(
|
79
|
+
expect(Pacto::Validators::ResponseBodyValidator).to receive(:validate).with(contract, actual_response).and_return([])
|
80
80
|
expect(ContractValidator.validate contract, actual_request, actual_response, opts).to be_empty
|
81
81
|
end
|
82
82
|
end
|
@@ -11,7 +11,7 @@ module Pacto
|
|
11
11
|
end
|
12
12
|
|
13
13
|
it 'logs the erb processed' do
|
14
|
-
|
14
|
+
Pacto.configuration.logger.should_receive(:debug).with("Processed contract: \"#{result}\"")
|
15
15
|
processor.process erb
|
16
16
|
end
|
17
17
|
|
@@ -3,19 +3,20 @@ module Pacto
|
|
3
3
|
let(:record_host) do
|
4
4
|
'http://example.com'
|
5
5
|
end
|
6
|
-
|
7
6
|
let(:request) do
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
7
|
+
Pacto::RequestClause.new(record_host,
|
8
|
+
'method' => 'GET',
|
9
|
+
'path' => '/abcd',
|
10
|
+
'headers' => {
|
11
|
+
'Content-Length' => [1234],
|
12
|
+
'Via' => ['Some Proxy'],
|
13
|
+
'User-Agent' => ['rspec']
|
14
|
+
},
|
15
|
+
'params' => {
|
16
|
+
'apikey' => "<%= ENV['MY_API_KEY'] %>"
|
17
|
+
}
|
18
|
+
)
|
17
19
|
end
|
18
|
-
|
19
20
|
let(:response_adapter) do
|
20
21
|
Faraday::Response.new(
|
21
22
|
:status => 200,
|
@@ -43,6 +44,34 @@ module Pacto
|
|
43
44
|
MultiJson.encode(obj, :pretty => true).gsub(/^$\n/, '')
|
44
45
|
end
|
45
46
|
|
47
|
+
describe '#generate' do
|
48
|
+
let(:request_contract) do
|
49
|
+
double(
|
50
|
+
:request => request
|
51
|
+
)
|
52
|
+
end
|
53
|
+
let(:generated_contract) { double('generated contract') }
|
54
|
+
before do
|
55
|
+
Pacto.should_receive(:load_contract).with(request_file, record_host).and_return request_contract
|
56
|
+
request.should_receive(:execute).and_return response_adapter
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'parses the request' do
|
60
|
+
generator.should_receive(:save).with(request_file, request, anything)
|
61
|
+
generator.generate request_file, record_host
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'fetches a response' do
|
65
|
+
generator.should_receive(:save).with(request_file, anything, response_adapter)
|
66
|
+
generator.generate request_file, record_host
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'saves the result' do
|
70
|
+
generator.should_receive(:save).with(request_file, request, response_adapter).and_return generated_contract
|
71
|
+
expect(generator.generate request_file, record_host).to eq(generated_contract)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
46
75
|
describe '#save' do
|
47
76
|
before do
|
48
77
|
filters.should_receive(:filter_request_headers).with(request, response_adapter).and_return filtered_request_headers
|
@@ -1,44 +1,46 @@
|
|
1
1
|
module Pacto
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
2
|
+
module Logger
|
3
|
+
describe SimpleLogger do
|
4
|
+
before do
|
5
|
+
logger.log logger_lib
|
6
|
+
end
|
7
|
+
|
8
|
+
subject(:logger) { described_class.instance }
|
9
|
+
let(:logger_lib) { ::Logger.new(StringIO.new) }
|
10
|
+
|
11
|
+
it 'delegates debug to the logger lib' do
|
12
|
+
logger_lib.should_receive(:debug)
|
13
|
+
logger.debug
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'delegates info to the logger lib' do
|
17
|
+
logger_lib.should_receive(:info)
|
18
|
+
logger.info
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'delegates warn to the logger lib' do
|
22
|
+
logger_lib.should_receive(:warn)
|
23
|
+
logger.warn
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'delegates error to the logger lib' do
|
27
|
+
logger_lib.should_receive(:error)
|
28
|
+
logger.error
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'delegates fatal to the logger lib' do
|
32
|
+
logger_lib.should_receive(:error)
|
33
|
+
logger.error
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'has the default log level as error' do
|
37
|
+
expect(logger.level).to eq :error
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'provides access to the log level' do
|
41
|
+
logger.level = :info
|
42
|
+
expect(logger.level).to eq :info
|
43
|
+
end
|
42
44
|
end
|
43
45
|
end
|
44
46
|
end
|
@@ -39,7 +39,7 @@ module Pacto
|
|
39
39
|
stubbed_request.stub(:to_return).with(
|
40
40
|
:status => response.status,
|
41
41
|
:headers => response.headers,
|
42
|
-
:body => response.body.to_json
|
42
|
+
:body => response.body.to_json
|
43
43
|
)
|
44
44
|
stubbed_request.stub(:request_pattern).and_return request_pattern
|
45
45
|
end
|
@@ -50,7 +50,8 @@ module Pacto
|
|
50
50
|
expect(block.parameters).to have(2).items
|
51
51
|
end
|
52
52
|
|
53
|
-
WebMockAdapter.new
|
53
|
+
# WebMockAdapter.new
|
54
|
+
Pacto.configuration.provider # this way the rpec after block doesn't create a second instance
|
54
55
|
end
|
55
56
|
end
|
56
57
|
|
@@ -2,23 +2,36 @@ module Pacto
|
|
2
2
|
module Validators
|
3
3
|
describe BodyValidator do
|
4
4
|
class MyBodyValidator < BodyValidator
|
5
|
-
|
6
|
-
|
5
|
+
class << self
|
6
|
+
attr_writer :subschema
|
7
|
+
|
8
|
+
def section_name
|
9
|
+
'my_section'
|
10
|
+
end
|
11
|
+
|
12
|
+
def subschema(contract)
|
13
|
+
@subschema
|
14
|
+
end
|
7
15
|
end
|
8
16
|
end
|
9
17
|
|
10
18
|
subject(:validator) { MyBodyValidator }
|
11
19
|
let(:string_required) { true }
|
20
|
+
let(:contract) { double('contract', :file => 'file:///a.json') }
|
12
21
|
let(:body) { 'a simple string' }
|
13
22
|
let(:fake_interaction) { double(:fake_interaction, body: body) }
|
14
23
|
|
24
|
+
before(:each) do
|
25
|
+
MyBodyValidator.subschema = schema
|
26
|
+
end
|
27
|
+
|
15
28
|
describe '#validate' do
|
16
29
|
context 'when schema is not specified' do
|
17
30
|
let(:schema) { nil }
|
18
31
|
|
19
32
|
it 'gives no errors without validating body' do
|
20
33
|
JSON::Validator.should_not_receive(:fully_validate)
|
21
|
-
expect(validator.validate(
|
34
|
+
expect(validator.validate(contract, fake_interaction)).to be_empty
|
22
35
|
end
|
23
36
|
end
|
24
37
|
|
@@ -31,17 +44,17 @@ module Pacto
|
|
31
44
|
# FIXME: This seems like a design flaw. We're partially reproducing json-schema behavior
|
32
45
|
# instead of finding a way to use it.
|
33
46
|
JSON::Validator.should_not_receive(:fully_validate)
|
34
|
-
validator.validate(
|
47
|
+
validator.validate(contract, fake_interaction)
|
35
48
|
end
|
36
49
|
|
37
50
|
context 'if required' do
|
38
51
|
it 'does not return an error when body is a string' do
|
39
|
-
expect(validator.validate(
|
52
|
+
expect(validator.validate(contract, fake_interaction)).to be_empty
|
40
53
|
end
|
41
54
|
|
42
55
|
it 'returns an error when body is nil' do
|
43
56
|
expect(fake_interaction).to receive(:body).and_return nil
|
44
|
-
expect(validator.validate(
|
57
|
+
expect(validator.validate(contract, fake_interaction).size).to eq 1
|
45
58
|
end
|
46
59
|
end
|
47
60
|
|
@@ -49,12 +62,12 @@ module Pacto
|
|
49
62
|
let(:string_required) { false }
|
50
63
|
|
51
64
|
it 'does not return an error when body is a string' do
|
52
|
-
expect(validator.validate(
|
65
|
+
expect(validator.validate(contract, fake_interaction)).to be_empty
|
53
66
|
end
|
54
67
|
|
55
68
|
it 'does not return an error when body is nil' do
|
56
69
|
expect(fake_interaction).to receive(:body).and_return nil
|
57
|
-
expect(validator.validate(
|
70
|
+
expect(validator.validate(contract, fake_interaction)).to be_empty
|
58
71
|
end
|
59
72
|
end
|
60
73
|
|
@@ -67,7 +80,7 @@ module Pacto
|
|
67
80
|
let(:body) { 'abc' } # This matches the pattern /a.c/
|
68
81
|
|
69
82
|
it 'does not return an error' do
|
70
|
-
expect(validator.validate(
|
83
|
+
expect(validator.validate(contract, fake_interaction)).to be_empty
|
71
84
|
end
|
72
85
|
end
|
73
86
|
|
@@ -75,7 +88,7 @@ module Pacto
|
|
75
88
|
let(:body) { 'acb' } # This does not matches the pattern /a.c/
|
76
89
|
|
77
90
|
it 'returns an error' do
|
78
|
-
expect(validator.validate(
|
91
|
+
expect(validator.validate(contract, fake_interaction).size).to eq 1
|
79
92
|
end
|
80
93
|
end
|
81
94
|
end
|
@@ -87,7 +100,7 @@ module Pacto
|
|
87
100
|
context 'when body matches' do
|
88
101
|
it 'does not return any errors' do
|
89
102
|
expect(JSON::Validator).to receive(:fully_validate).and_return([])
|
90
|
-
expect(validator.validate(
|
103
|
+
expect(validator.validate(contract, fake_interaction)).to be_empty
|
91
104
|
end
|
92
105
|
end
|
93
106
|
|
@@ -95,7 +108,7 @@ module Pacto
|
|
95
108
|
it 'returns a list of errors' do
|
96
109
|
errors = double 'some errors'
|
97
110
|
expect(JSON::Validator).to receive(:fully_validate).and_return(errors)
|
98
|
-
expect(validator.validate(
|
111
|
+
expect(validator.validate(contract, fake_interaction)).to eq(errors)
|
99
112
|
end
|
100
113
|
end
|
101
114
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pacto
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ThoughtWorks & Abril
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-03-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: webmock
|
@@ -70,6 +70,9 @@ dependencies:
|
|
70
70
|
name: json-generator
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.0'
|
73
76
|
- - ">="
|
74
77
|
- !ruby/object:Gem::Version
|
75
78
|
version: 0.0.5
|
@@ -77,6 +80,9 @@ dependencies:
|
|
77
80
|
prerelease: false
|
78
81
|
version_requirements: !ruby/object:Gem::Requirement
|
79
82
|
requirements:
|
83
|
+
- - "~>"
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0.0'
|
80
86
|
- - ">="
|
81
87
|
- !ruby/object:Gem::Version
|
82
88
|
version: 0.0.5
|
@@ -126,6 +132,9 @@ dependencies:
|
|
126
132
|
name: json-schema-generator
|
127
133
|
requirement: !ruby/object:Gem::Requirement
|
128
134
|
requirements:
|
135
|
+
- - "~>"
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0.0'
|
129
138
|
- - ">="
|
130
139
|
- !ruby/object:Gem::Version
|
131
140
|
version: 0.0.7
|
@@ -133,6 +142,9 @@ dependencies:
|
|
133
142
|
prerelease: false
|
134
143
|
version_requirements: !ruby/object:Gem::Requirement
|
135
144
|
requirements:
|
145
|
+
- - "~>"
|
146
|
+
- !ruby/object:Gem::Version
|
147
|
+
version: '0.0'
|
136
148
|
- - ">="
|
137
149
|
- !ruby/object:Gem::Version
|
138
150
|
version: 0.0.7
|
@@ -154,42 +166,42 @@ dependencies:
|
|
154
166
|
name: coveralls
|
155
167
|
requirement: !ruby/object:Gem::Requirement
|
156
168
|
requirements:
|
157
|
-
- - "
|
169
|
+
- - "~>"
|
158
170
|
- !ruby/object:Gem::Version
|
159
171
|
version: '0'
|
160
172
|
type: :development
|
161
173
|
prerelease: false
|
162
174
|
version_requirements: !ruby/object:Gem::Requirement
|
163
175
|
requirements:
|
164
|
-
- - "
|
176
|
+
- - "~>"
|
165
177
|
- !ruby/object:Gem::Version
|
166
178
|
version: '0'
|
167
179
|
- !ruby/object:Gem::Dependency
|
168
180
|
name: rake
|
169
181
|
requirement: !ruby/object:Gem::Requirement
|
170
182
|
requirements:
|
171
|
-
- - "
|
183
|
+
- - "~>"
|
172
184
|
- !ruby/object:Gem::Version
|
173
|
-
version: '0'
|
185
|
+
version: '10.0'
|
174
186
|
type: :development
|
175
187
|
prerelease: false
|
176
188
|
version_requirements: !ruby/object:Gem::Requirement
|
177
189
|
requirements:
|
178
|
-
- - "
|
190
|
+
- - "~>"
|
179
191
|
- !ruby/object:Gem::Version
|
180
|
-
version: '0'
|
192
|
+
version: '10.0'
|
181
193
|
- !ruby/object:Gem::Dependency
|
182
194
|
name: rake-notes
|
183
195
|
requirement: !ruby/object:Gem::Requirement
|
184
196
|
requirements:
|
185
|
-
- - "
|
197
|
+
- - "~>"
|
186
198
|
- !ruby/object:Gem::Version
|
187
199
|
version: '0'
|
188
200
|
type: :development
|
189
201
|
prerelease: false
|
190
202
|
version_requirements: !ruby/object:Gem::Requirement
|
191
203
|
requirements:
|
192
|
-
- - "
|
204
|
+
- - "~>"
|
193
205
|
- !ruby/object:Gem::Version
|
194
206
|
version: '0'
|
195
207
|
- !ruby/object:Gem::Dependency
|
@@ -210,128 +222,114 @@ dependencies:
|
|
210
222
|
name: should_not
|
211
223
|
requirement: !ruby/object:Gem::Requirement
|
212
224
|
requirements:
|
213
|
-
- - "
|
225
|
+
- - "~>"
|
214
226
|
- !ruby/object:Gem::Version
|
215
|
-
version: '0'
|
227
|
+
version: '1.0'
|
216
228
|
type: :development
|
217
229
|
prerelease: false
|
218
230
|
version_requirements: !ruby/object:Gem::Requirement
|
219
231
|
requirements:
|
220
|
-
- - "
|
232
|
+
- - "~>"
|
221
233
|
- !ruby/object:Gem::Version
|
222
|
-
version: '0'
|
234
|
+
version: '1.0'
|
223
235
|
- !ruby/object:Gem::Dependency
|
224
236
|
name: aruba
|
225
237
|
requirement: !ruby/object:Gem::Requirement
|
226
238
|
requirements:
|
227
|
-
- - "
|
228
|
-
- !ruby/object:Gem::Version
|
229
|
-
version: '0'
|
230
|
-
type: :development
|
231
|
-
prerelease: false
|
232
|
-
version_requirements: !ruby/object:Gem::Requirement
|
233
|
-
requirements:
|
234
|
-
- - ">="
|
235
|
-
- !ruby/object:Gem::Version
|
236
|
-
version: '0'
|
237
|
-
- !ruby/object:Gem::Dependency
|
238
|
-
name: relish
|
239
|
-
requirement: !ruby/object:Gem::Requirement
|
240
|
-
requirements:
|
241
|
-
- - ">="
|
239
|
+
- - "~>"
|
242
240
|
- !ruby/object:Gem::Version
|
243
241
|
version: '0'
|
244
242
|
type: :development
|
245
243
|
prerelease: false
|
246
244
|
version_requirements: !ruby/object:Gem::Requirement
|
247
245
|
requirements:
|
248
|
-
- - "
|
246
|
+
- - "~>"
|
249
247
|
- !ruby/object:Gem::Version
|
250
248
|
version: '0'
|
251
249
|
- !ruby/object:Gem::Dependency
|
252
250
|
name: guard-rspec
|
253
251
|
requirement: !ruby/object:Gem::Requirement
|
254
252
|
requirements:
|
255
|
-
- - "
|
253
|
+
- - "~>"
|
256
254
|
- !ruby/object:Gem::Version
|
257
|
-
version: '
|
255
|
+
version: '4.2'
|
258
256
|
type: :development
|
259
257
|
prerelease: false
|
260
258
|
version_requirements: !ruby/object:Gem::Requirement
|
261
259
|
requirements:
|
262
|
-
- - "
|
260
|
+
- - "~>"
|
263
261
|
- !ruby/object:Gem::Version
|
264
|
-
version: '
|
262
|
+
version: '4.2'
|
265
263
|
- !ruby/object:Gem::Dependency
|
266
264
|
name: rubocop
|
267
265
|
requirement: !ruby/object:Gem::Requirement
|
268
266
|
requirements:
|
269
267
|
- - "~>"
|
270
268
|
- !ruby/object:Gem::Version
|
271
|
-
version: 0.16
|
269
|
+
version: '0.16'
|
272
270
|
type: :development
|
273
271
|
prerelease: false
|
274
272
|
version_requirements: !ruby/object:Gem::Requirement
|
275
273
|
requirements:
|
276
274
|
- - "~>"
|
277
275
|
- !ruby/object:Gem::Version
|
278
|
-
version: 0.16
|
276
|
+
version: '0.16'
|
279
277
|
- !ruby/object:Gem::Dependency
|
280
278
|
name: guard-rubocop
|
281
279
|
requirement: !ruby/object:Gem::Requirement
|
282
280
|
requirements:
|
283
|
-
- - "
|
281
|
+
- - "~>"
|
284
282
|
- !ruby/object:Gem::Version
|
285
|
-
version: '0'
|
283
|
+
version: '1.0'
|
286
284
|
type: :development
|
287
285
|
prerelease: false
|
288
286
|
version_requirements: !ruby/object:Gem::Requirement
|
289
287
|
requirements:
|
290
|
-
- - "
|
288
|
+
- - "~>"
|
291
289
|
- !ruby/object:Gem::Version
|
292
|
-
version: '0'
|
290
|
+
version: '1.0'
|
293
291
|
- !ruby/object:Gem::Dependency
|
294
292
|
name: guard-cucumber
|
295
293
|
requirement: !ruby/object:Gem::Requirement
|
296
294
|
requirements:
|
297
|
-
- - "
|
295
|
+
- - "~>"
|
298
296
|
- !ruby/object:Gem::Version
|
299
|
-
version: '
|
297
|
+
version: '1.4'
|
300
298
|
type: :development
|
301
299
|
prerelease: false
|
302
300
|
version_requirements: !ruby/object:Gem::Requirement
|
303
301
|
requirements:
|
304
|
-
- - "
|
302
|
+
- - "~>"
|
305
303
|
- !ruby/object:Gem::Version
|
306
|
-
version: '
|
304
|
+
version: '1.4'
|
307
305
|
- !ruby/object:Gem::Dependency
|
308
306
|
name: rb-fsevent
|
309
307
|
requirement: !ruby/object:Gem::Requirement
|
310
308
|
requirements:
|
311
|
-
- - "
|
309
|
+
- - "~>"
|
312
310
|
- !ruby/object:Gem::Version
|
313
311
|
version: '0'
|
314
312
|
type: :development
|
315
313
|
prerelease: false
|
316
314
|
version_requirements: !ruby/object:Gem::Requirement
|
317
315
|
requirements:
|
318
|
-
- - "
|
316
|
+
- - "~>"
|
319
317
|
- !ruby/object:Gem::Version
|
320
318
|
version: '0'
|
321
319
|
- !ruby/object:Gem::Dependency
|
322
320
|
name: terminal-notifier-guard
|
323
321
|
requirement: !ruby/object:Gem::Requirement
|
324
322
|
requirements:
|
325
|
-
- - "
|
323
|
+
- - "~>"
|
326
324
|
- !ruby/object:Gem::Version
|
327
|
-
version: '
|
325
|
+
version: '1.5'
|
328
326
|
type: :development
|
329
327
|
prerelease: false
|
330
328
|
version_requirements: !ruby/object:Gem::Requirement
|
331
329
|
requirements:
|
332
|
-
- - "
|
330
|
+
- - "~>"
|
333
331
|
- !ruby/object:Gem::Version
|
334
|
-
version: '
|
332
|
+
version: '1.5'
|
335
333
|
description: Pacto is a judge that arbitrates contract disputes between a service
|
336
334
|
provider and one or more consumers. In other words, it is a framework for Integration
|
337
335
|
Contract Testing, and helps guide service evolution patterns like Consumer-Driven
|
@@ -349,6 +347,7 @@ files:
|
|
349
347
|
- ".ruby-gemset"
|
350
348
|
- ".ruby-version"
|
351
349
|
- ".travis.yml"
|
350
|
+
- CHANGELOG
|
352
351
|
- CONTRIBUTING.md
|
353
352
|
- Gemfile
|
354
353
|
- Guardfile
|