pacto 0.2.5 → 0.3.0.pre
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.
- data/.gitignore +3 -0
- data/.rspec +0 -2
- data/.rubocop-todo.yml +51 -0
- data/.rubocop.yml +1 -0
- data/.travis.yml +4 -2
- data/Guardfile +28 -14
- data/README.md +81 -51
- data/Rakefile +24 -11
- data/features/generation/generation.feature +25 -0
- data/features/journeys/validation.feature +74 -0
- data/features/support/env.rb +16 -0
- data/lib/pacto.rb +63 -34
- data/lib/pacto/contract.rb +25 -11
- data/lib/pacto/contract_factory.rb +13 -44
- data/lib/pacto/core/callback.rb +11 -0
- data/lib/pacto/core/configuration.rb +34 -0
- data/lib/pacto/core/contract_repository.rb +44 -0
- data/lib/pacto/erb_processor.rb +18 -0
- data/lib/pacto/exceptions/invalid_contract.rb +10 -1
- data/lib/pacto/extensions.rb +2 -2
- data/lib/pacto/generator.rb +75 -0
- data/lib/pacto/hash_merge_processor.rb +14 -0
- data/lib/pacto/hooks/erb_hook.rb +17 -0
- data/lib/pacto/logger.rb +42 -0
- data/lib/pacto/meta_schema.rb +17 -0
- data/lib/pacto/rake_task.rb +75 -12
- data/lib/pacto/request.rb +3 -4
- data/lib/pacto/response.rb +27 -19
- data/lib/pacto/server.rb +2 -0
- data/lib/pacto/server/dummy.rb +45 -0
- data/lib/pacto/server/playback_servlet.rb +21 -0
- data/lib/pacto/stubs/built_in.rb +57 -0
- data/lib/pacto/version.rb +1 -1
- data/pacto.gemspec +8 -2
- data/resources/contract_schema.json +216 -0
- data/spec/coveralls_helper.rb +10 -0
- data/spec/integration/data/strict_contract.json +33 -0
- data/spec/integration/data/templating_contract.json +25 -0
- data/spec/integration/e2e_spec.rb +40 -7
- data/spec/integration/templating_spec.rb +55 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/unit/data/simple_contract.json +22 -0
- data/spec/unit/hooks/erb_hook_spec.rb +51 -0
- data/spec/unit/pacto/configuration_spec.rb +51 -0
- data/spec/unit/pacto/contract_factory_spec.rb +4 -35
- data/spec/unit/pacto/contract_spec.rb +59 -31
- data/spec/unit/pacto/core/configuration_spec.rb +28 -0
- data/spec/unit/pacto/core/contract_repository_spec.rb +133 -0
- data/spec/unit/pacto/erb_processor_spec.rb +23 -0
- data/spec/unit/pacto/extensions_spec.rb +11 -11
- data/spec/unit/pacto/generator_spec.rb +142 -0
- data/spec/unit/pacto/hash_merge_processor_spec.rb +20 -0
- data/spec/unit/pacto/logger_spec.rb +44 -0
- data/spec/unit/pacto/meta_schema_spec.rb +70 -0
- data/spec/unit/pacto/pacto_spec.rb +32 -58
- data/spec/unit/pacto/request_spec.rb +83 -34
- data/spec/unit/pacto/response_adapter_spec.rb +9 -11
- data/spec/unit/pacto/response_spec.rb +68 -68
- data/spec/unit/pacto/server/playback_servlet_spec.rb +24 -0
- data/spec/unit/pacto/stubs/built_in_spec.rb +168 -0
- metadata +291 -147
- data/.rspec_integration +0 -4
- data/.rspec_unit +0 -4
- data/lib/pacto/file_pre_processor.rb +0 -12
- data/lib/pacto/instantiated_contract.rb +0 -62
- data/spec/integration/spec_helper.rb +0 -1
- data/spec/integration/utils/dummy_server.rb +0 -34
- data/spec/unit/pacto/file_pre_processor_spec.rb +0 -13
- data/spec/unit/pacto/instantiated_contract_spec.rb +0 -224
- data/spec/unit/spec_helper.rb +0 -5
data/.rspec_integration
DELETED
data/.rspec_unit
DELETED
@@ -1,62 +0,0 @@
|
|
1
|
-
module Pacto
|
2
|
-
class InstantiatedContract
|
3
|
-
attr_reader :response_body
|
4
|
-
|
5
|
-
def initialize(request, response)
|
6
|
-
@request = request
|
7
|
-
@response = response
|
8
|
-
@response_body = response.body
|
9
|
-
end
|
10
|
-
|
11
|
-
def request_path
|
12
|
-
@request.absolute_uri
|
13
|
-
end
|
14
|
-
|
15
|
-
def request_uri
|
16
|
-
@request.full_uri
|
17
|
-
end
|
18
|
-
|
19
|
-
def replace!(values)
|
20
|
-
if @response_body.respond_to?(:normalize_keys)
|
21
|
-
@response_body = @response_body.normalize_keys.deep_merge(values.normalize_keys)
|
22
|
-
else
|
23
|
-
@response_body = values
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def stub!
|
28
|
-
WebMock.stub_request(@request.method, "#{@request.host}#{@request.path}").
|
29
|
-
with(request_details).
|
30
|
-
to_return({
|
31
|
-
:status => @response.status,
|
32
|
-
:headers => @response.headers,
|
33
|
-
:body => format_body(@response_body)
|
34
|
-
})
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
def format_body(body)
|
40
|
-
if body.is_a?(Hash) or body.is_a?(Array)
|
41
|
-
body.to_json
|
42
|
-
else
|
43
|
-
body
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def request_details
|
48
|
-
details = {}
|
49
|
-
unless @request.params.empty?
|
50
|
-
details[webmock_params_key] = @request.params
|
51
|
-
end
|
52
|
-
unless @request.headers.empty?
|
53
|
-
details[:headers] = @request.headers
|
54
|
-
end
|
55
|
-
details
|
56
|
-
end
|
57
|
-
|
58
|
-
def webmock_params_key
|
59
|
-
@request.method == :get ? :query : :body
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
@@ -1 +0,0 @@
|
|
1
|
-
require_relative 'utils/dummy_server'
|
@@ -1,34 +0,0 @@
|
|
1
|
-
require 'webrick'
|
2
|
-
|
3
|
-
class Servlet < WEBrick::HTTPServlet::AbstractServlet
|
4
|
-
def initialize(server, json)
|
5
|
-
super(server)
|
6
|
-
@json = json
|
7
|
-
end
|
8
|
-
|
9
|
-
def do_GET(request, response)
|
10
|
-
response.status = 200
|
11
|
-
response['Content-Type'] = 'application/json'
|
12
|
-
response.body = @json
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
class DummyServer
|
17
|
-
def initialize port, path, response
|
18
|
-
@server = WEBrick::HTTPServer.new :Port => port,
|
19
|
-
:AccessLog => [],
|
20
|
-
:Logger => WEBrick::Log::new("/dev/null", 7)
|
21
|
-
@server.mount path, Servlet, response
|
22
|
-
end
|
23
|
-
|
24
|
-
def start
|
25
|
-
@pid = fork do
|
26
|
-
trap 'INT' do @server.shutdown end
|
27
|
-
@server.start
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def terminate
|
32
|
-
Process.kill('INT', @pid)
|
33
|
-
end
|
34
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
module Pacto
|
2
|
-
describe FilePreProcessor do
|
3
|
-
describe "#process" do
|
4
|
-
it "should return the result of ERB" do
|
5
|
-
subject.process("2 + 2 = <%= 2 + 2 %>").should == "2 + 2 = 4"
|
6
|
-
end
|
7
|
-
|
8
|
-
it "should not mess with pure JSONs" do
|
9
|
-
subject.process('{"property": ["one", "two, null"]}')
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
@@ -1,224 +0,0 @@
|
|
1
|
-
module Pacto
|
2
|
-
describe InstantiatedContract do
|
3
|
-
describe '#replace!' do
|
4
|
-
let(:body) { double('body') }
|
5
|
-
let(:response) { double(:body => body) }
|
6
|
-
let(:values) { double('values') }
|
7
|
-
|
8
|
-
context 'when response body is a hash' do
|
9
|
-
let(:normalized_values) { double('normalized values') }
|
10
|
-
let(:normalized_body) { double('normalized body') }
|
11
|
-
let(:merged_body) { double('merged body') }
|
12
|
-
|
13
|
-
it 'should normalize keys and deep merge response body with given values' do
|
14
|
-
values.should_receive(:normalize_keys).and_return(normalized_values)
|
15
|
-
response.body.should_receive(:normalize_keys).and_return(normalized_body)
|
16
|
-
normalized_body.should_receive(:deep_merge).with(normalized_values).and_return(merged_body)
|
17
|
-
|
18
|
-
instantiated_contract = described_class.new(nil, response)
|
19
|
-
instantiated_contract.replace!(values)
|
20
|
-
|
21
|
-
instantiated_contract.response_body.should == merged_body
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
context 'when response body is a string' do
|
26
|
-
let(:body) { 'foo' }
|
27
|
-
|
28
|
-
it 'should replace response body with given values' do
|
29
|
-
instantiated_contract = described_class.new(nil, response)
|
30
|
-
instantiated_contract.replace!(values)
|
31
|
-
instantiated_contract.response_body.should == values
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
context 'when response body is nil' do
|
36
|
-
let(:body) { nil }
|
37
|
-
|
38
|
-
it 'should replace response body with given values' do
|
39
|
-
instantiated_contract = described_class.new(nil, response)
|
40
|
-
instantiated_contract.replace!(values)
|
41
|
-
instantiated_contract.response_body.should == values
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
describe '#response_body' do
|
47
|
-
let(:response) { double(:body => double('body')) }
|
48
|
-
|
49
|
-
it "should return response body" do
|
50
|
-
described_class.new(nil, response).response_body.should == response.body
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
describe '#request_path' do
|
55
|
-
let(:request) { double('request', :absolute_uri => "http://dummy_link/hello_world") }
|
56
|
-
let(:response) { double('response', :body => double('body')) }
|
57
|
-
|
58
|
-
it "should return the request absolute uri" do
|
59
|
-
described_class.new(request, response).request_path.should == "http://dummy_link/hello_world"
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
describe '#request_uri' do
|
64
|
-
let(:request) { double('request', :full_uri => "http://dummy_link/hello_world?param=value#fragment") }
|
65
|
-
let(:response) { double('response', :body => double('body')) }
|
66
|
-
|
67
|
-
it "should return request full uri" do
|
68
|
-
described_class.new(request, response).request_uri.should == "http://dummy_link/hello_world?param=value#fragment"
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
describe '#stub!' do
|
73
|
-
let(:request) do
|
74
|
-
double({
|
75
|
-
:host => 'http://localhost',
|
76
|
-
:method => method,
|
77
|
-
:path => '/hello_world',
|
78
|
-
:headers => {'Accept' => 'application/json'},
|
79
|
-
:params => {'foo' => 'bar'}
|
80
|
-
})
|
81
|
-
end
|
82
|
-
|
83
|
-
let(:method) { :get }
|
84
|
-
|
85
|
-
let(:response) do
|
86
|
-
double({
|
87
|
-
:status => 200,
|
88
|
-
:headers => {},
|
89
|
-
:body => body
|
90
|
-
})
|
91
|
-
end
|
92
|
-
|
93
|
-
let(:body) do
|
94
|
-
{'message' => 'foo'}
|
95
|
-
end
|
96
|
-
|
97
|
-
let(:stubbed_request) { double('stubbed request') }
|
98
|
-
|
99
|
-
before do
|
100
|
-
WebMock.should_receive(:stub_request).
|
101
|
-
with(request.method, "#{request.host}#{request.path}").
|
102
|
-
and_return(stubbed_request)
|
103
|
-
|
104
|
-
stubbed_request.stub(:to_return).with({
|
105
|
-
:status => response.status,
|
106
|
-
:headers => response.headers,
|
107
|
-
:body => response.body.to_json
|
108
|
-
})
|
109
|
-
end
|
110
|
-
|
111
|
-
context 'when the response body is an object' do
|
112
|
-
let(:body) do
|
113
|
-
{'message' => 'foo'}
|
114
|
-
end
|
115
|
-
|
116
|
-
it 'should stub the response body with a json representation' do
|
117
|
-
stubbed_request.should_receive(:to_return).with({
|
118
|
-
:status => response.status,
|
119
|
-
:headers => response.headers,
|
120
|
-
:body => response.body.to_json
|
121
|
-
})
|
122
|
-
|
123
|
-
stubbed_request.stub(:with).and_return(stubbed_request)
|
124
|
-
|
125
|
-
described_class.new(request, response).stub!
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
context 'when the response body is an array' do
|
130
|
-
let(:body) do
|
131
|
-
[1, 2, 3]
|
132
|
-
end
|
133
|
-
|
134
|
-
it 'should stub the response body with a json representation' do
|
135
|
-
stubbed_request.should_receive(:to_return).with({
|
136
|
-
:status => response.status,
|
137
|
-
:headers => response.headers,
|
138
|
-
:body => response.body.to_json
|
139
|
-
})
|
140
|
-
|
141
|
-
stubbed_request.stub(:with).and_return(stubbed_request)
|
142
|
-
|
143
|
-
described_class.new(request, response).stub!
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
context 'when the response body is not an object or an array' do
|
148
|
-
let(:body) { nil }
|
149
|
-
|
150
|
-
it 'should stub the response body with the original body' do
|
151
|
-
stubbed_request.should_receive(:to_return).with({
|
152
|
-
:status => response.status,
|
153
|
-
:headers => response.headers,
|
154
|
-
:body => response.body
|
155
|
-
})
|
156
|
-
|
157
|
-
stubbed_request.stub(:with).and_return(stubbed_request)
|
158
|
-
|
159
|
-
described_class.new(request, response).stub!
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
context 'a GET request' do
|
164
|
-
let(:method) { :get }
|
165
|
-
|
166
|
-
it 'should use WebMock to stub the request' do
|
167
|
-
stubbed_request.should_receive(:with).
|
168
|
-
with({:headers => request.headers, :query => request.params}).
|
169
|
-
and_return(stubbed_request)
|
170
|
-
described_class.new(request, response).stub!
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
|
-
context 'a POST request' do
|
175
|
-
let(:method) { :post }
|
176
|
-
|
177
|
-
it 'should use WebMock to stub the request' do
|
178
|
-
stubbed_request.should_receive(:with).
|
179
|
-
with({:headers => request.headers, :body => request.params}).
|
180
|
-
and_return(stubbed_request)
|
181
|
-
described_class.new(request, response).stub!
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
context 'a request with no headers' do
|
186
|
-
let(:request) do
|
187
|
-
double({
|
188
|
-
:host => 'http://localhost',
|
189
|
-
:method => :get,
|
190
|
-
:path => '/hello_world',
|
191
|
-
:headers => {},
|
192
|
-
:params => {'foo' => 'bar'}
|
193
|
-
})
|
194
|
-
end
|
195
|
-
|
196
|
-
it 'should use WebMock to stub the request' do
|
197
|
-
stubbed_request.should_receive(:with).
|
198
|
-
with({:query => request.params}).
|
199
|
-
and_return(stubbed_request)
|
200
|
-
described_class.new(request, response).stub!
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
context 'a request with no params' do
|
205
|
-
let(:request) do
|
206
|
-
double({
|
207
|
-
:host => 'http://localhost',
|
208
|
-
:method => :get,
|
209
|
-
:path => '/hello_world',
|
210
|
-
:headers => {},
|
211
|
-
:params => {}
|
212
|
-
})
|
213
|
-
end
|
214
|
-
|
215
|
-
it 'should use WebMock to stub the request' do
|
216
|
-
stubbed_request.should_receive(:with).
|
217
|
-
with({}).
|
218
|
-
and_return(stubbed_request)
|
219
|
-
described_class.new(request, response).stub!
|
220
|
-
end
|
221
|
-
end
|
222
|
-
end
|
223
|
-
end
|
224
|
-
end
|