pacto 0.3.0.pre → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/.rubocop-todo.yml +0 -27
- data/.rubocop.yml +9 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +4 -5
- data/CONTRIBUTING.md +112 -0
- data/Gemfile +5 -0
- data/Guardfile +18 -13
- data/README.md +157 -101
- data/Rakefile +3 -3
- data/features/configuration/strict_matchers.feature +97 -0
- data/features/evolve/README.md +11 -0
- data/features/evolve/existing_services.feature +82 -0
- data/features/generate/README.md +5 -0
- data/features/generate/generation.feature +28 -0
- data/features/steps/pacto_steps.rb +75 -0
- data/features/stub/README.md +2 -0
- data/features/stub/templates.feature +46 -0
- data/features/support/env.rb +11 -5
- data/features/validate/README.md +1 -0
- data/features/validate/body_only.feature +85 -0
- data/features/{journeys/validation.feature → validate/meta_validation.feature} +41 -24
- data/features/validate/validation.feature +36 -0
- data/lib/pacto.rb +61 -33
- data/lib/pacto/contract.rb +18 -15
- data/lib/pacto/contract_factory.rb +14 -11
- data/lib/pacto/contract_files.rb +17 -0
- data/lib/pacto/contract_list.rb +17 -0
- data/lib/pacto/contract_validator.rb +29 -0
- data/lib/pacto/core/configuration.rb +19 -17
- data/lib/pacto/core/contract_registry.rb +43 -0
- data/lib/pacto/core/{callback.rb → hook.rb} +3 -3
- data/lib/pacto/core/modes.rb +33 -0
- data/lib/pacto/core/validation_registry.rb +45 -0
- data/lib/pacto/erb_processor.rb +0 -1
- data/lib/pacto/extensions.rb +18 -4
- data/lib/pacto/generator.rb +34 -49
- data/lib/pacto/generator/filters.rb +41 -0
- data/lib/pacto/hooks/erb_hook.rb +4 -3
- data/lib/pacto/logger.rb +4 -2
- data/lib/pacto/meta_schema.rb +4 -2
- data/lib/pacto/rake_task.rb +28 -25
- data/lib/pacto/request_clause.rb +43 -0
- data/lib/pacto/request_pattern.rb +8 -0
- data/lib/pacto/response_clause.rb +15 -0
- data/lib/pacto/rspec.rb +102 -0
- data/lib/pacto/stubs/uri_pattern.rb +23 -0
- data/lib/pacto/stubs/webmock_adapter.rb +69 -0
- data/lib/pacto/stubs/webmock_helper.rb +71 -0
- data/lib/pacto/ui.rb +7 -0
- data/lib/pacto/uri.rb +9 -0
- data/lib/pacto/validation.rb +57 -0
- data/lib/pacto/validators/body_validator.rb +41 -0
- data/lib/pacto/validators/request_body_validator.rb +23 -0
- data/lib/pacto/validators/response_body_validator.rb +23 -0
- data/lib/pacto/validators/response_header_validator.rb +49 -0
- data/lib/pacto/validators/response_status_validator.rb +24 -0
- data/lib/pacto/version.rb +1 -1
- data/pacto.gemspec +33 -29
- data/resources/contract_schema.json +8 -176
- data/resources/draft-03.json +174 -0
- data/spec/integration/data/strict_contract.json +2 -2
- data/spec/integration/e2e_spec.rb +22 -31
- data/spec/integration/rspec_spec.rb +94 -0
- data/spec/integration/templating_spec.rb +9 -12
- data/{lib → spec}/pacto/server.rb +0 -0
- data/{lib → spec}/pacto/server/dummy.rb +11 -8
- data/{lib → spec}/pacto/server/playback_servlet.rb +1 -1
- data/spec/spec_helper.rb +2 -0
- data/spec/unit/hooks/erb_hook_spec.rb +15 -15
- data/spec/unit/pacto/configuration_spec.rb +2 -10
- data/spec/unit/pacto/contract_factory_spec.rb +16 -13
- data/spec/unit/pacto/contract_files_spec.rb +42 -0
- data/spec/unit/pacto/contract_list_spec.rb +35 -0
- data/spec/unit/pacto/contract_spec.rb +43 -44
- data/spec/unit/pacto/contract_validator_spec.rb +85 -0
- data/spec/unit/pacto/core/configuration_spec.rb +4 -11
- data/spec/unit/pacto/core/contract_registry_spec.rb +119 -0
- data/spec/unit/pacto/core/modes_spec.rb +18 -0
- data/spec/unit/pacto/core/validation_registry_spec.rb +76 -0
- data/spec/unit/pacto/core/validation_spec.rb +60 -0
- data/spec/unit/pacto/extensions_spec.rb +14 -23
- data/spec/unit/pacto/generator/filters_spec.rb +99 -0
- data/spec/unit/pacto/generator_spec.rb +34 -73
- data/spec/unit/pacto/meta_schema_spec.rb +46 -6
- data/spec/unit/pacto/pacto_spec.rb +17 -15
- data/spec/unit/pacto/{request_spec.rb → request_clause_spec.rb} +32 -44
- data/spec/unit/pacto/request_pattern_spec.rb +22 -0
- data/spec/unit/pacto/response_clause_spec.rb +54 -0
- data/spec/unit/pacto/stubs/uri_pattern_spec.rb +28 -0
- data/spec/unit/pacto/stubs/webmock_adapter_spec.rb +205 -0
- data/spec/unit/pacto/stubs/webmock_helper_spec.rb +20 -0
- data/spec/unit/pacto/uri_spec.rb +20 -0
- data/spec/unit/pacto/validators/body_validator_spec.rb +105 -0
- data/spec/unit/pacto/validators/response_header_validator_spec.rb +94 -0
- data/spec/unit/pacto/validators/response_status_validator_spec.rb +20 -0
- metadata +230 -146
- data/features/generation/generation.feature +0 -25
- data/lib/pacto/core/contract_repository.rb +0 -44
- data/lib/pacto/hash_merge_processor.rb +0 -14
- data/lib/pacto/request.rb +0 -57
- data/lib/pacto/response.rb +0 -63
- data/lib/pacto/response_adapter.rb +0 -24
- data/lib/pacto/stubs/built_in.rb +0 -57
- data/spec/unit/pacto/core/contract_repository_spec.rb +0 -133
- data/spec/unit/pacto/hash_merge_processor_spec.rb +0 -20
- data/spec/unit/pacto/response_adapter_spec.rb +0 -25
- data/spec/unit/pacto/response_spec.rb +0 -201
- data/spec/unit/pacto/stubs/built_in_spec.rb +0 -168
@@ -0,0 +1,60 @@
|
|
1
|
+
module Pacto
|
2
|
+
describe Validation do
|
3
|
+
let(:request) { double('request') }
|
4
|
+
let(:response) { double('response') }
|
5
|
+
let(:contract) { double('contract') }
|
6
|
+
let(:validation_results) { double('validation_results') }
|
7
|
+
|
8
|
+
before(:each) do
|
9
|
+
allow(contract).to receive(:validate_consumer)
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'stores the request, response and contract' do
|
13
|
+
validation = Pacto::Validation.new request, response, contract
|
14
|
+
expect(validation.request).to eq request
|
15
|
+
expect(validation.response).to eq response
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'generates and stores the results' do
|
19
|
+
expect(contract).to receive(:validate_consumer).with(request, response).and_return(validation_results)
|
20
|
+
validation = Pacto::Validation.new request, response, contract
|
21
|
+
expect(validation.results).to eq validation_results
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#successful?' do
|
25
|
+
subject(:validation) do
|
26
|
+
Pacto::Validation.new request, response, contract
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'returns true if there were no validation errors' do
|
30
|
+
expect(validation.successful?).to be_true
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'returns false if there were validation errors' do
|
34
|
+
expect(validation.successful?).to be_true
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#against_contract?' do
|
39
|
+
it 'returns nil if there was no contract' do
|
40
|
+
validation = Pacto::Validation.new request, response, nil
|
41
|
+
expect(validation.against_contract? 'a').to be_nil
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'returns the contract with an exact string name match' do
|
45
|
+
allow(contract).to receive(:file).and_return('foo')
|
46
|
+
validation = Pacto::Validation.new request, response, contract
|
47
|
+
expect(validation.against_contract? 'foo').to eq(contract)
|
48
|
+
expect(validation.against_contract? 'bar').to be_nil
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'returns the contract if there is a regex match' do
|
52
|
+
allow(contract).to receive(:file).and_return 'foobar'
|
53
|
+
validation = Pacto::Validation.new request, response, contract
|
54
|
+
expect(validation.against_contract?(/foo/)).to eq(contract)
|
55
|
+
expect(validation.against_contract?(/bar/)).to eq(contract)
|
56
|
+
expect(validation.against_contract?(/baz/)).to be_nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -1,32 +1,23 @@
|
|
1
1
|
module Pacto
|
2
2
|
module Extensions
|
3
3
|
describe HashSubsetOf do
|
4
|
-
describe '#
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
context 'when the other hash is a subset' do
|
12
|
-
it 'returns true' do
|
13
|
-
expect({:a => 'a'}).to be_subset_of({:a => 'a', :b => 'b'})
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
context 'when the other hash is not a subset' do
|
18
|
-
it 'returns false' do
|
19
|
-
expect({:a => 'a'}.subset_of?({:a => 'b'})).to be_false
|
20
|
-
end
|
4
|
+
describe '#normalize_keys' do
|
5
|
+
it 'turns keys into downcased strings' do
|
6
|
+
expect({:A => 'a'}.normalize_keys).to eq('a' => 'a')
|
7
|
+
expect({:a => 'a'}.normalize_keys).to eq('a' => 'a')
|
8
|
+
expect({'A' => 'a'}.normalize_keys).to eq('a' => 'a')
|
9
|
+
expect({'a' => 'a'}.normalize_keys).to eq('a' => 'a')
|
21
10
|
end
|
22
11
|
end
|
23
12
|
|
24
|
-
describe '#
|
25
|
-
it '
|
26
|
-
expect(
|
27
|
-
expect(
|
28
|
-
expect(
|
29
|
-
expect(
|
13
|
+
describe '#normalize_header_keys' do
|
14
|
+
it 'matches headers to the style in the RFC documentation' do
|
15
|
+
expect(Pacto::Extensions.normalize_header_keys(:'user-agent' => 'a')).to eq('User-Agent' => 'a') # rubocop:disable SymbolName
|
16
|
+
expect(Pacto::Extensions.normalize_header_keys(:user_agent => 'a')).to eq('User-Agent' => 'a')
|
17
|
+
expect(Pacto::Extensions.normalize_header_keys('User-Agent' => 'a')).to eq('User-Agent' => 'a')
|
18
|
+
expect(Pacto::Extensions.normalize_header_keys('user-agent' => 'a')).to eq('User-Agent' => 'a')
|
19
|
+
expect(Pacto::Extensions.normalize_header_keys('user_agent' => 'a')).to eq('User-Agent' => 'a')
|
20
|
+
expect(Pacto::Extensions.normalize_header_keys('USER_AGENT' => 'a')).to eq('User-Agent' => 'a')
|
30
21
|
end
|
31
22
|
end
|
32
23
|
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module Pacto
|
2
|
+
class Generator
|
3
|
+
describe Filters do
|
4
|
+
let(:record_host) do
|
5
|
+
'http://example.com'
|
6
|
+
end
|
7
|
+
let(:request) do
|
8
|
+
RequestClause.new(
|
9
|
+
record_host,
|
10
|
+
'method' => 'GET',
|
11
|
+
'path' => '/abcd',
|
12
|
+
'headers' => {
|
13
|
+
'Server' => ['example.com'],
|
14
|
+
'Connection' => ['Close'],
|
15
|
+
'Content-Length' => [1234],
|
16
|
+
'Via' => ['Some Proxy'],
|
17
|
+
'User-Agent' => ['rspec']
|
18
|
+
},
|
19
|
+
'params' => {
|
20
|
+
'apikey' => "<%= ENV['MY_API_KEY'] %>"
|
21
|
+
}
|
22
|
+
)
|
23
|
+
end
|
24
|
+
let(:varies) { ['User-Agent'] }
|
25
|
+
let(:response) do
|
26
|
+
Faraday::Response.new(
|
27
|
+
:status => 200,
|
28
|
+
:response_headers => {
|
29
|
+
'Date' => Time.now.rfc2822,
|
30
|
+
'Last-Modified' => Time.now.rfc2822,
|
31
|
+
'ETag' => 'abc123',
|
32
|
+
'Server' => ['Fake Server'],
|
33
|
+
'Content-Type' => ['application/json'],
|
34
|
+
'Vary' => varies
|
35
|
+
},
|
36
|
+
:body => double('dummy body')
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#filter_request_headers' do
|
41
|
+
subject(:filtered_request_headers) { described_class.new.filter_request_headers(request, response).keys.map(&:downcase) }
|
42
|
+
it 'keeps important request headers' do
|
43
|
+
expect(filtered_request_headers).to include 'user-agent'
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'filters informational request headers' do
|
47
|
+
expect(filtered_request_headers).not_to include 'via'
|
48
|
+
expect(filtered_request_headers).not_to include 'date'
|
49
|
+
expect(filtered_request_headers).not_to include 'server'
|
50
|
+
expect(filtered_request_headers).not_to include 'content-length'
|
51
|
+
expect(filtered_request_headers).not_to include 'connection'
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'multiple Vary elements' do
|
55
|
+
context 'as a single string' do
|
56
|
+
let(:varies) do
|
57
|
+
['User-Agent,Via']
|
58
|
+
end
|
59
|
+
it 'keeps each header' do
|
60
|
+
expect(filtered_request_headers).to include 'user-agent'
|
61
|
+
expect(filtered_request_headers).to include 'via'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
context 'as multiple items' do
|
65
|
+
let(:varies) do
|
66
|
+
%w{User-Agent Via}
|
67
|
+
end
|
68
|
+
it 'keeps each header' do
|
69
|
+
expect(filtered_request_headers).to include 'user-agent'
|
70
|
+
expect(filtered_request_headers).to include 'via'
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe '#filter_response_headers' do
|
77
|
+
subject(:filtered_response_headers) { described_class.new.filter_response_headers(request, response).keys.map(&:downcase) }
|
78
|
+
it 'keeps important response headers' do
|
79
|
+
expect(filtered_response_headers).to include 'content-type'
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'filters connection control headers' do
|
83
|
+
expect(filtered_response_headers).not_to include 'content-length'
|
84
|
+
expect(filtered_response_headers).not_to include 'via'
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'filters freshness headers' do
|
88
|
+
expect(filtered_response_headers).not_to include 'date'
|
89
|
+
expect(filtered_response_headers).not_to include 'last-modified'
|
90
|
+
expect(filtered_response_headers).not_to include 'eTag'
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'filters x-* headers' do
|
94
|
+
expect(filtered_response_headers).not_to include 'x-men'
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -1,73 +1,53 @@
|
|
1
1
|
module Pacto
|
2
2
|
describe Generator do
|
3
|
-
let(:record_host)
|
3
|
+
let(:record_host) do
|
4
4
|
'http://example.com'
|
5
|
-
|
5
|
+
end
|
6
|
+
|
6
7
|
let(:request) do
|
7
|
-
|
8
|
-
|
9
|
-
'
|
10
|
-
|
8
|
+
Faraday::Request.create :get do |req|
|
9
|
+
req.path = '/abcd'
|
10
|
+
req.params = { 'apikey' => "<%= ENV['MY_API_KEY'] %>" }
|
11
|
+
req.headers = {
|
11
12
|
'Content-Length' => [1234],
|
12
13
|
'Via' => ['Some Proxy'],
|
13
14
|
'User-Agent' => ['rspec']
|
14
|
-
}
|
15
|
-
|
16
|
-
})
|
15
|
+
}
|
16
|
+
end
|
17
17
|
end
|
18
|
+
|
18
19
|
let(:response_adapter) do
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
'
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
})
|
20
|
+
Faraday::Response.new(
|
21
|
+
:status => 200,
|
22
|
+
:response_headers => {
|
23
|
+
'Date' => [Time.now],
|
24
|
+
'Server' => ['Fake Server'],
|
25
|
+
'Content-Type' => ['application/json'],
|
26
|
+
'Vary' => ['User-Agent']
|
27
|
+
},
|
28
|
+
:body => 'dummy body' # body is just a string
|
29
29
|
)
|
30
30
|
end
|
31
|
+
let(:filtered_request_headers) { double('filtered_response_headers') }
|
32
|
+
let(:filtered_response_headers) { double('filtered_response_headers') }
|
31
33
|
let(:response_body_schema) { '{"message": "dummy generated schema"}' }
|
32
34
|
let(:version) { 'draft3' }
|
33
35
|
let(:schema_generator) { double('schema_generator') }
|
34
36
|
let(:validator) { double('validator') }
|
37
|
+
let(:filters) { double :filters }
|
35
38
|
let(:request_file) { 'request.json' }
|
36
|
-
let(:
|
39
|
+
let(:options) { Pacto.configuration.generator_options }
|
40
|
+
let(:generator) { described_class.new version, schema_generator, validator, options, filters }
|
37
41
|
|
38
|
-
def pretty
|
42
|
+
def pretty(obj)
|
39
43
|
MultiJson.encode(obj, :pretty => true).gsub(/^$\n/, '')
|
40
44
|
end
|
41
45
|
|
42
|
-
describe '#
|
43
|
-
let(:request_contract) {
|
44
|
-
double({
|
45
|
-
:request => request,
|
46
|
-
})
|
47
|
-
}
|
48
|
-
let(:generated_contract) { double('generated contract') }
|
46
|
+
describe '#save' do
|
49
47
|
before do
|
50
|
-
|
51
|
-
|
52
|
-
end
|
53
|
-
|
54
|
-
it 'parses the request' do
|
55
|
-
generator.should_receive(:save).with(request_file, request, anything)
|
56
|
-
generator.generate request_file, record_host
|
57
|
-
end
|
58
|
-
|
59
|
-
it 'fetches a response' do
|
60
|
-
generator.should_receive(:save).with(request_file, anything, response_adapter)
|
61
|
-
generator.generate request_file, record_host
|
62
|
-
end
|
63
|
-
|
64
|
-
it 'saves the result' do
|
65
|
-
generator.should_receive(:save).with(request_file, request, response_adapter).and_return generated_contract
|
66
|
-
expect(generator.generate request_file, record_host).to eq(generated_contract)
|
48
|
+
filters.should_receive(:filter_request_headers).with(request, response_adapter).and_return filtered_request_headers
|
49
|
+
filters.should_receive(:filter_response_headers).with(request, response_adapter).and_return filtered_response_headers
|
67
50
|
end
|
68
|
-
end
|
69
|
-
|
70
|
-
describe '#save' do
|
71
51
|
context 'invalid schema' do
|
72
52
|
it 'raises an error if schema generation fails' do
|
73
53
|
JSON::SchemaGenerator.should_receive(:generate).and_raise ArgumentError.new('Could not generate schema')
|
@@ -82,11 +62,11 @@ module Pacto
|
|
82
62
|
end
|
83
63
|
|
84
64
|
context 'valid schema' do
|
85
|
-
let(:raw_contract)
|
86
|
-
JSON::SchemaGenerator.should_receive(:generate).with(request_file, response_adapter.body,
|
65
|
+
let(:raw_contract) do
|
66
|
+
JSON::SchemaGenerator.should_receive(:generate).with(request_file, response_adapter.body, Pacto.configuration.generator_options).and_return response_body_schema
|
87
67
|
validator.should_receive(:validate).and_return true
|
88
68
|
generator.save request_file, request, response_adapter
|
89
|
-
|
69
|
+
end
|
90
70
|
subject(:generated_contract) { JSON.parse raw_contract }
|
91
71
|
|
92
72
|
it 'sets the body to the generated json-schema' do
|
@@ -99,17 +79,9 @@ module Pacto
|
|
99
79
|
expect(generated_request['path']).to eq(request.path)
|
100
80
|
end
|
101
81
|
|
102
|
-
it '
|
103
|
-
|
104
|
-
expect(
|
105
|
-
end
|
106
|
-
|
107
|
-
it 'filters informational request headers' do
|
108
|
-
saved_headers = subject['request']['headers']
|
109
|
-
expect(saved_headers).not_to include 'Date'
|
110
|
-
expect(saved_headers).not_to include 'Server'
|
111
|
-
expect(saved_headers).not_to include 'Content-Length'
|
112
|
-
expect(saved_headers).not_to include 'Connection'
|
82
|
+
it 'preserves ERB in the request params' do
|
83
|
+
generated_request = subject['request']
|
84
|
+
expect(generated_request['params']['apikey']).to eq("<%= ENV['MY_API_KEY'] %>")
|
113
85
|
end
|
114
86
|
|
115
87
|
it 'normalizes the request method' do
|
@@ -122,17 +94,6 @@ module Pacto
|
|
122
94
|
expect(generated_response['status']).to eq(response_adapter.status)
|
123
95
|
end
|
124
96
|
|
125
|
-
it 'keeps important response headers' do
|
126
|
-
saved_headers = subject['response']['headers']
|
127
|
-
expect(saved_headers.keys).to include 'Content-Type'
|
128
|
-
end
|
129
|
-
|
130
|
-
it 'filters informational response headers' do
|
131
|
-
saved_headers = subject['response']['headers']
|
132
|
-
expect(saved_headers).not_to include 'Content-Length'
|
133
|
-
expect(saved_headers).not_to include 'Via'
|
134
|
-
end
|
135
|
-
|
136
97
|
it 'generates pretty JSON' do
|
137
98
|
expect(raw_contract).to eq(pretty(subject))
|
138
99
|
end
|
@@ -31,7 +31,7 @@ module Pacto
|
|
31
31
|
EOF
|
32
32
|
end
|
33
33
|
|
34
|
-
let(:
|
34
|
+
let(:partial_contract) do
|
35
35
|
<<-EOF
|
36
36
|
{
|
37
37
|
"request": {
|
@@ -47,22 +47,62 @@ module Pacto
|
|
47
47
|
EOF
|
48
48
|
end
|
49
49
|
|
50
|
+
let(:invalid_contract) do
|
51
|
+
<<-EOF
|
52
|
+
{
|
53
|
+
"request": {
|
54
|
+
"method": "GET",
|
55
|
+
"path": "/hello_world",
|
56
|
+
"headers": {
|
57
|
+
"Accept": "application/json"
|
58
|
+
},
|
59
|
+
"params": {}
|
60
|
+
},
|
61
|
+
|
62
|
+
"response": {
|
63
|
+
"status": 200,
|
64
|
+
"headers": {
|
65
|
+
"Content-Type": "application/json"
|
66
|
+
},
|
67
|
+
"body": {
|
68
|
+
"description": "A simple response",
|
69
|
+
"required": {},
|
70
|
+
"type": "object",
|
71
|
+
"properties": {
|
72
|
+
"message": {
|
73
|
+
"type": "string"
|
74
|
+
}
|
75
|
+
}
|
76
|
+
}
|
77
|
+
}
|
78
|
+
}
|
79
|
+
EOF
|
80
|
+
end
|
81
|
+
|
50
82
|
subject(:schema) { MetaSchema.new }
|
51
83
|
|
52
84
|
describe 'when validating a contract against the master schema' do
|
53
85
|
context 'with a valid contract structure' do
|
54
86
|
it 'does not raise any exceptions' do
|
55
|
-
expect
|
87
|
+
expect do
|
56
88
|
schema.validate(valid_contract)
|
57
|
-
|
89
|
+
end.to_not raise_error(Exception)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'with an partial contract structure' do
|
94
|
+
it 'raises InvalidContract exception' do
|
95
|
+
expect do
|
96
|
+
schema.validate(invalid_contract)
|
97
|
+
end.to raise_error(InvalidContract)
|
58
98
|
end
|
59
99
|
end
|
60
100
|
|
61
|
-
context 'with an invalid contract
|
101
|
+
context 'with an invalid contract' do
|
62
102
|
it 'raises InvalidContract exception' do
|
63
|
-
expect
|
103
|
+
expect do
|
64
104
|
schema.validate(invalid_contract)
|
65
|
-
|
105
|
+
end.to raise_error(InvalidContract)
|
66
106
|
end
|
67
107
|
end
|
68
108
|
end
|
@@ -1,5 +1,6 @@
|
|
1
|
-
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
|
+
describe Pacto do
|
3
4
|
around(:each) do |example|
|
4
5
|
$stdout = StringIO.new
|
5
6
|
example.run
|
@@ -19,7 +20,7 @@ describe Pacto do
|
|
19
20
|
it 'displays a success message and return true' do
|
20
21
|
mock_validation []
|
21
22
|
success = Pacto.validate_contract 'my_contract.json'
|
22
|
-
expect(output).to eq '
|
23
|
+
expect(output).to eq 'Validating my_contract.json'
|
23
24
|
expect(success).to be_true
|
24
25
|
end
|
25
26
|
end
|
@@ -28,7 +29,7 @@ describe Pacto do
|
|
28
29
|
it 'displays one error messages and return false' do
|
29
30
|
mock_validation ['Error 1']
|
30
31
|
success = Pacto.validate_contract 'my_contract.json'
|
31
|
-
expect(output).to match
|
32
|
+
expect(output).to match(/error/)
|
32
33
|
expect(success).to be_false
|
33
34
|
end
|
34
35
|
|
@@ -40,21 +41,22 @@ describe Pacto do
|
|
40
41
|
end
|
41
42
|
end
|
42
43
|
|
43
|
-
describe '
|
44
|
-
let(:
|
45
|
-
let(:host)
|
46
|
-
let(:
|
47
|
-
let(:
|
44
|
+
describe 'loading contracts' do
|
45
|
+
let(:contracts_path) { 'path/to/dir' }
|
46
|
+
let(:host) { 'localhost' }
|
47
|
+
let(:contract1) { double }
|
48
|
+
let(:contract2) { double }
|
49
|
+
let(:factory) { double(:factory) }
|
48
50
|
|
49
|
-
|
50
|
-
Pacto::ContractFactory.
|
51
|
-
described_class.build_from_file(path, host, file_pre_processor)
|
51
|
+
before do
|
52
|
+
allow(Pacto::ContractFactory).to receive(:new).and_return(factory)
|
52
53
|
end
|
53
54
|
|
54
|
-
it '
|
55
|
-
Pacto::
|
56
|
-
|
55
|
+
it 'instantiates a contract list' do
|
56
|
+
allow(Pacto::ContractFiles).to receive(:for).with(contracts_path).and_return { %w{file1 file2} }
|
57
|
+
allow(factory).to receive(:build).with(%w{file1 file2}, host).and_return { [contract1, contract2] }
|
58
|
+
expect(Pacto::ContractList).to receive(:new).with([contract1, contract2])
|
59
|
+
Pacto.load_contracts(contracts_path, host)
|
57
60
|
end
|
58
61
|
end
|
59
|
-
|
60
62
|
end
|