pacto 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|