vigia 0.0.9 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +13 -5
- data/README.md +191 -58
- data/Rakefile +13 -2
- data/lib/vigia/adapter.rb +63 -0
- data/lib/vigia/adapters/blueprint.rb +105 -0
- data/lib/vigia/config.rb +27 -16
- data/lib/vigia/http_client/options.rb +30 -0
- data/lib/vigia/http_client/requests.rb +10 -0
- data/lib/vigia/http_client/rest_client.rb +35 -13
- data/lib/vigia/parameters.rb +20 -9
- data/lib/vigia/rspec.rb +31 -14
- data/lib/vigia/sail/context.rb +67 -0
- data/lib/vigia/sail/example.rb +65 -0
- data/lib/vigia/sail/group.rb +47 -0
- data/lib/vigia/sail/group_instance.rb +24 -0
- data/lib/vigia/sail/rspec_object.rb +73 -0
- data/lib/vigia/spec/api_spec.rb +1 -25
- data/lib/vigia/spec/support/utils.rb +1 -14
- data/lib/vigia/url.rb +4 -20
- data/lib/vigia/version.rb +1 -1
- data/lib/vigia.rb +11 -5
- metadata +59 -41
- data/lib/vigia/blueprint.rb +0 -14
- data/lib/vigia/example.rb +0 -92
- data/lib/vigia/headers.rb +0 -48
- data/lib/vigia/spec/support/shared_examples/apib_example.rb +0 -33
- data/lib/vigia/spec/support/shared_examples/skip_example.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NzQzNmJmYjk4OTkzYjZmZDc0ZGQ3N2I4MTZiYjUyYmZhOTNkODExZQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ZDI3MTQ4ZWYxNDY5MjIzMjA2MGM3OWVkN2EwNzA0NDU0NDhjODY5MQ==
|
5
7
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ZGI4ZWY0MjAxZGM5YzRmYjdhYTE0MTc0NTg0NmRjZTI1ZTE3NDBjMWQ0YmE2
|
10
|
+
YmZmY2FhMWJhZTkzMDQ5NDU5N2U5MmE0ODAwNjhhYzk5MWRjODVmNjI0NmM0
|
11
|
+
NmY3ZDliMjRlNDMyOGJiZGJiMmU0NDhlNzRkNDJkMWFjMmQwYmY=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MzdkMDE5NjMzYmI5MGJmODY3MWQ1YWQwMDRjZDhhOWIwNzAxMWUxODVmMzQ5
|
14
|
+
M2ExMmVkMDI3Y2MwYzg2MWRiYWI3YTAyZDY2ZTFjMjliZTgyYmEyNmNlMmIy
|
15
|
+
MTlhM2I2NTc4NzM5OTY2Yzc0ZGY5ZDUyNjk1YTQ4NjVmZGY2NTU=
|
data/README.md
CHANGED
@@ -7,11 +7,11 @@ Vigia
|
|
7
7
|
|
8
8
|
# What is it?
|
9
9
|
|
10
|
-
|
11
|
-
[Api Blueprint](https://github.com/apiaryio/api-blueprint/blob/master/API%20Blueprint%20Specification.md) definition file. It uses [RedSnow](https://github.com/apiaryio/redsnow) to parse the Api Blueprint file and [RestClient](https://github.com/rest-client/rest-client) as http client to perform the requests.
|
10
|
+
<img src="http://singularities.org/vigia.png" width="96" height="96" class="right" alt="Vigia logo" />
|
12
11
|
|
13
|
-
Vigia
|
12
|
+
Vigia is a gem to perform integration tests using RSpec and a compatible adapter (See [Adapters](#adapters)). The adapter creates the structure of the test (groups and context) and sets up all the variables (See [Context variables](#context-variables)) used to perform the http request.
|
14
13
|
|
14
|
+
These results and expectations objects can be used to run examples that will compare the expected value with the server response value. Vigia allows to use a variety of different ways to execute these comparisons (See [Vigia Examples](#vigia-examples) and [Custom Shared Examples](#custom-shared-examples))
|
15
15
|
|
16
16
|
# Installation
|
17
17
|
|
@@ -27,70 +27,229 @@ end
|
|
27
27
|
|
28
28
|
Run bundle install
|
29
29
|
|
30
|
-
```
|
30
|
+
```bash
|
31
31
|
$ bundle install
|
32
32
|
```
|
33
33
|
|
34
|
-
Vigia can
|
34
|
+
Now, Vigia can be used inside your application.
|
35
35
|
|
36
36
|
# Getting started
|
37
37
|
|
38
|
-
|
38
|
+
This example shows an easy way to start a rails server and perform you apibs test.
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
# Your lib/tasks/vigia.rake
|
42
|
+
namespace :spec do
|
43
|
+
desc 'Run Vigia tests'
|
44
|
+
task :vigia => :environment do
|
45
|
+
|
46
|
+
# start rails server by the easiest way
|
47
|
+
system("bundle exec rails s -e #{ Rails.env } -d")
|
48
|
+
# give some time to the server
|
49
|
+
sleep 10
|
50
|
+
|
51
|
+
Vigia.configure do |config|
|
52
|
+
config.source_file = "#{ Rails.root }/apibs/my_api.apib"
|
53
|
+
config.host = 'http://localhost:3000'
|
54
|
+
end
|
55
|
+
|
56
|
+
Vigia.rspec!
|
57
|
+
end
|
58
|
+
end
|
59
|
+
```
|
60
|
+
|
61
|
+
## Configuration
|
62
|
+
|
63
|
+
Vigia tries to be flexible enough in case that you need to run custom operations during the tests.
|
39
64
|
|
40
65
|
```ruby
|
41
66
|
|
42
67
|
Vigia.configure do |config|
|
43
68
|
|
44
|
-
# Define
|
45
|
-
config.
|
69
|
+
# Define your source file. For example, within a Rails app
|
70
|
+
config.source_file = "#{ Rails.root }/apibs/my_api.apib"
|
46
71
|
|
47
72
|
# Define the host address where the request will be performed.
|
48
73
|
config.host = 'http://localhost:3000'
|
49
74
|
|
50
|
-
# Include
|
51
|
-
config.
|
75
|
+
# Include a collection of custom headers in all the requests.
|
76
|
+
config.headers = { authorization: 'Bearer <your hash here>' }
|
52
77
|
|
53
|
-
#
|
54
|
-
config.
|
78
|
+
# Reset rspec_config and set up documentation formatter
|
79
|
+
config.rspec_config do |rspec_config|
|
80
|
+
rspec_config.reset
|
81
|
+
rspec_config.formatter = RSpec::Core::Formatters::DocumentationFormatter
|
82
|
+
end
|
55
83
|
|
56
|
-
#
|
57
|
-
config.
|
84
|
+
# Attach a before_context hook to set up the database using Databasecleaner
|
85
|
+
config.before_context do
|
86
|
+
DatabaseCleaner.start
|
87
|
+
end
|
58
88
|
|
89
|
+
# Set a timer on the primary group and raise an exception if the
|
90
|
+
# described group takes more than 5 seconds to run
|
91
|
+
config.before_group do
|
92
|
+
let!(:group_started_at) { Time.now } if described_class.options[:primary]
|
93
|
+
end
|
94
|
+
|
95
|
+
config.after_group do
|
96
|
+
if described_class.options[:primary]
|
97
|
+
it 'has taken less than 5 seconds to run this example' do
|
98
|
+
expect(Time.now.to_i - group_started_at.to_i).to be < 5
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
59
102
|
end
|
60
103
|
|
104
|
+
Vigia.rspec!
|
105
|
+
|
61
106
|
```
|
107
|
+
For more information about config, see the `Vigia::Config` class.
|
108
|
+
|
109
|
+
## Adapters
|
62
110
|
|
63
|
-
|
111
|
+
By default, Vigia uses `Vigia::Adapters::Blueprint` adapter. This adapter takes an Api Blueprint compatible file and parses it using [RedSnow](https://github.com/apiaryio/redsnow). Then, it builds up the test structure accordingly.
|
64
112
|
|
65
|
-
|
113
|
+
If needed, Vigia can be configured to use a custom adapter. To do so, you just need to specify the adapter class inside the vigia configuration block:
|
66
114
|
|
67
115
|
```ruby
|
68
|
-
|
116
|
+
Vigia.configure do |config|
|
117
|
+
config.adapter = MyBlogAdapter
|
118
|
+
end
|
119
|
+
```
|
69
120
|
|
70
|
-
|
121
|
+
Then, insde your adapter class, you can use the `setup_adater` method to define the groups and contexts that the adapter will provide:
|
71
122
|
|
72
|
-
|
73
|
-
task :vigia => :environment do
|
123
|
+
```ruby
|
74
124
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
125
|
+
# Post
|
126
|
+
class MyBlogAdapter < Vigia::Adapter
|
127
|
+
setup_adapter do
|
128
|
+
group :resource,
|
129
|
+
primary: true,
|
130
|
+
contexts: [ :default ]
|
131
|
+
describes: [ :post, :pages ]
|
132
|
+
|
133
|
+
context :default,
|
134
|
+
http_client_options: {
|
135
|
+
url: -> { "/#{ resource }" },
|
136
|
+
method: :get
|
137
|
+
},
|
138
|
+
expectations: {
|
139
|
+
code: 200,
|
140
|
+
headers: {},
|
141
|
+
body: -> { adapter.body_for(resource) }
|
142
|
+
}
|
143
|
+
end
|
79
144
|
|
80
|
-
|
81
|
-
|
82
|
-
|
145
|
+
def body_for(resource)
|
146
|
+
case resource
|
147
|
+
when :post
|
148
|
+
# Your post index expected body
|
149
|
+
when :pages
|
150
|
+
# Your pages index expected body
|
151
|
+
else
|
152
|
+
'Unknown resource. WTH!'
|
83
153
|
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
```
|
84
157
|
|
85
|
-
|
158
|
+
When vigia starts, it fetchs the first group defined as primary. For each group, Vigia will loop on each element of the describes option (`:post, :page` in this example), and will set a rspec memoized object named as the group (`let(:resource) { :post }`). Then, it will run the children (if any) and the contexts in this group, setting up the `http_client_options` and `expectations` memoized objects per context.
|
159
|
+
|
160
|
+
See `Vigia::Adapters::Blueprint` class for more information about configuring and setting up an adapter.
|
161
|
+
|
162
|
+
## Context Variables
|
163
|
+
|
164
|
+
Vigia tries to be consistent with the way the RSpec are normally written. It creates the describe groups and context based on the adapter configuration and set up all the variables for the examples by using RSpec memoized objects.
|
86
165
|
|
166
|
+
```ruby
|
167
|
+
|
168
|
+
# With an adapter `ExampleAdapter` with this config
|
169
|
+
#
|
170
|
+
# group :resource,
|
171
|
+
# describes: [ :posts, :pages ],
|
172
|
+
# children: [ :action ]
|
173
|
+
#
|
174
|
+
# group :action
|
175
|
+
# describes: [ :get, :post ],
|
176
|
+
# context: [ :default ]
|
177
|
+
#
|
178
|
+
# context :default,
|
179
|
+
# http_client_options: {
|
180
|
+
# method: -> { action.to_s.upcase }
|
181
|
+
# url: -> { adapter.url_for(resource) }" }
|
182
|
+
# headers: :headers
|
183
|
+
# expectations:
|
184
|
+
# code: :code
|
185
|
+
# headers: {}
|
186
|
+
# body: -> { Body.for(resource} }
|
187
|
+
#
|
188
|
+
# Vigia will generate this RSpec code
|
189
|
+
|
190
|
+
describe Vigia::RSpec do
|
191
|
+
let(:adapter) { ExampleAdapter.instance }
|
192
|
+
let(:client) { Vigia.config.http_client_class.new(http_options) }
|
193
|
+
let(:result) { client.run }
|
194
|
+
|
195
|
+
# the loop starts...
|
196
|
+
describe 'posts' do
|
197
|
+
let(:resource) { :posts }
|
198
|
+
|
199
|
+
describe 'action' do
|
200
|
+
let(:action) { :get }
|
201
|
+
|
202
|
+
context 'default' do
|
203
|
+
let(:http_client_options) { Vigia::HttpClient::Options.new(context_options) }
|
204
|
+
let(:expectations) { Vigia::HttpClient::ExpectedRequest.new(expectations) }
|
205
|
+
|
206
|
+
# EXAMPLES RUN HERE!
|
207
|
+
end
|
208
|
+
# NEXT ACTION
|
209
|
+
end
|
210
|
+
# NEXT RESOURCE
|
87
211
|
end
|
88
212
|
end
|
89
213
|
```
|
90
214
|
|
91
|
-
|
215
|
+
Also, It is important to mention that it is in this context where the adapter configuration will be executed. In the previous example, we configured the http_client option as follows:
|
216
|
+
|
217
|
+
```ruby
|
218
|
+
# http_client_options: {
|
219
|
+
# method: -> { action.to_s.upcase }
|
220
|
+
# url: -> { adapter.url_for(resource) }" }
|
221
|
+
# headers: :headers
|
222
|
+
```
|
223
|
+
|
224
|
+
The option `method` is a lambda object. This object will be executed inside the RSpec memoized objects context. It is the same as doing:
|
225
|
+
|
226
|
+
```ruby
|
227
|
+
# it has access to all context/group memoized objects
|
228
|
+
let(:method) { action.to_s.upcase }
|
229
|
+
```
|
230
|
+
|
231
|
+
You can also use the adapter like in option `url`, since it has been defined as a memoized object by Vigia::RSpec.
|
232
|
+
|
233
|
+
Lastly, you can specify a symbol as the option value. In this case, the adapter will be the reciever of this method.
|
234
|
+
|
235
|
+
## Vigia Examples
|
92
236
|
|
93
|
-
|
237
|
+
The first way to include examples on vigia is using `register`. Option `disabled_if` can be used to prevent the example for being executed on different situations. `contexts` limits the example to the listed contexts.
|
238
|
+
|
239
|
+
```ruby
|
240
|
+
|
241
|
+
# On your config file, spec_helper, etc.
|
242
|
+
Vigia::Sail::Example.register(
|
243
|
+
:my_custom_body_validator,
|
244
|
+
expectation: -> { expect { MyValidator(result.body) }.not.to raise_error } },
|
245
|
+
contexts: [ :my_context ], # default: :default
|
246
|
+
disable_if: -> { ! result.headers[:content_type].include?('my_validator_mime') }
|
247
|
+
)
|
248
|
+
```
|
249
|
+
|
250
|
+
## Custom shared examples
|
251
|
+
|
252
|
+
Vigia allows to include custom shared rspec examples in the test using some options in the config
|
94
253
|
|
95
254
|
```ruby
|
96
255
|
|
@@ -100,13 +259,8 @@ Vigia.configure do |config|
|
|
100
259
|
|
101
260
|
# Define the custom examples you want to include in your test
|
102
261
|
|
103
|
-
# To the example in all your
|
262
|
+
# To the example in all your requests use `:all` symbol
|
104
263
|
config.add_custom_examples_on(:all, 'my custom examples')
|
105
|
-
|
106
|
-
# You can specify the name of an action or a resource. Only the requests which belong to that
|
107
|
-
# resource or action will run these shared examples
|
108
|
-
config.add_custom_examples_on('Create an Image', 'create image examples')
|
109
|
-
|
110
264
|
end
|
111
265
|
```
|
112
266
|
|
@@ -117,29 +271,8 @@ Then, create your Rspec shared example and name the examples accordingly
|
|
117
271
|
|
118
272
|
shared_examples 'my custom examples' do |vigia_example, response|
|
119
273
|
it 'is a valid json response' do
|
120
|
-
expect { JSON.parse(result
|
274
|
+
expect { JSON.parse(result.body) }.not_to raise_error
|
121
275
|
end
|
122
276
|
end
|
123
277
|
|
124
|
-
shared_examples 'create image examples' do |vigia_example, response|
|
125
|
-
before do
|
126
|
-
@json_result = JSON.parse(result[:body])
|
127
|
-
@json_expectation = JSON.parse(expectations[:body])
|
128
|
-
end
|
129
|
-
|
130
|
-
it 'has the expected link to the image' do |vigia_example, response|
|
131
|
-
expect(@json_result['image']['link']).to eql(@json_expectation['image']['link'])
|
132
|
-
end
|
133
|
-
end
|
134
278
|
```
|
135
|
-
|
136
|
-
# ToDo
|
137
|
-
|
138
|
-
- [ ] Vigia::Example defines each Api Blueprint transactional example, but each example can have several responses (200, 404, etc.). Think a better way to handle this instead of passing the response variable across methods.
|
139
|
-
|
140
|
-
- [ ] Spike: Do we need to set RSpec specific options? (Vigia::Rspec)
|
141
|
-
|
142
|
-
- [ ] Parse http client exceptions properly. (done?)
|
143
|
-
|
144
|
-
- [ ] Support custom http client through config. (low priority)
|
145
|
-
|
data/Rakefile
CHANGED
@@ -1,7 +1,18 @@
|
|
1
1
|
require 'bundler/gem_tasks'
|
2
2
|
require 'rspec/core/rake_task'
|
3
|
+
require 'cucumber/rake/task'
|
4
|
+
|
5
|
+
Cucumber::Rake::Task.new(:cucumber) do |t|
|
6
|
+
t.cucumber_opts = '--tags ~@wip'
|
7
|
+
end
|
3
8
|
|
4
9
|
RSpec::Core::RakeTask.new(:spec)
|
5
10
|
|
6
|
-
|
7
|
-
task :
|
11
|
+
desc 'Clear tmp folders'
|
12
|
+
task :clobber do
|
13
|
+
FileUtils.rm_rf(File.join(__dir__, 'coverage'))
|
14
|
+
end
|
15
|
+
|
16
|
+
# Not sure why simplecov is preventing cucumber for being run after spec
|
17
|
+
# when running rake default
|
18
|
+
task :default => [ :spec, :cucumber ]
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Vigia
|
2
|
+
class Adapter
|
3
|
+
|
4
|
+
attr_accessor :source_file, :structure
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def setup_adapter(&block)
|
8
|
+
raise 'You have to call config_adapter with a block' unless block_given?
|
9
|
+
@template = block
|
10
|
+
end
|
11
|
+
|
12
|
+
def template
|
13
|
+
@template
|
14
|
+
end
|
15
|
+
|
16
|
+
def instance
|
17
|
+
new.tap do |object|
|
18
|
+
object.source_file = Vigia.config.source_file
|
19
|
+
object.structure = Structure.generate(object, @template)
|
20
|
+
object
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Structure
|
26
|
+
class << self
|
27
|
+
def generate(adapter, structure)
|
28
|
+
instance = new(adapter, structure)
|
29
|
+
instance.preload
|
30
|
+
instance
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
attr_reader :adapter, :groups, :contexts, :template
|
35
|
+
|
36
|
+
def initialize(adapter, template)
|
37
|
+
@adapter = adapter
|
38
|
+
@template = template
|
39
|
+
@groups = {}
|
40
|
+
@contexts = {}
|
41
|
+
end
|
42
|
+
|
43
|
+
def preload
|
44
|
+
instance_exec(&template)
|
45
|
+
|
46
|
+
Vigia::Sail::Group.collection = groups
|
47
|
+
Vigia::Sail::Context.collection = contexts
|
48
|
+
end
|
49
|
+
|
50
|
+
def after_initialize(&block)
|
51
|
+
adapter.instance_exec(&block)
|
52
|
+
end
|
53
|
+
|
54
|
+
def group(name, options = {})
|
55
|
+
@groups.merge!(name => options)
|
56
|
+
end
|
57
|
+
|
58
|
+
def context(name, options = {})
|
59
|
+
@contexts.merge!(name => options)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module Vigia
|
2
|
+
module Adapters
|
3
|
+
class Blueprint < Vigia::Adapter
|
4
|
+
|
5
|
+
attr_reader :apib
|
6
|
+
|
7
|
+
setup_adapter do
|
8
|
+
|
9
|
+
after_initialize do
|
10
|
+
@apib_parsed = RedSnow::parse(File.read(source_file))
|
11
|
+
@apib = @apib_parsed.ast
|
12
|
+
end
|
13
|
+
|
14
|
+
group :resource_group,
|
15
|
+
primary: true,
|
16
|
+
children: [ :resource ],
|
17
|
+
describes: -> { adapter.apib.resource_groups },
|
18
|
+
description: -> { "Resource Group: #{ resource_group.name }" }
|
19
|
+
|
20
|
+
group :resource,
|
21
|
+
children: [ :action ],
|
22
|
+
describes: -> { resource_group.resources },
|
23
|
+
description: -> { "Resource: #{ resource.name }" }
|
24
|
+
|
25
|
+
group :action,
|
26
|
+
children: [ :transactional_example ],
|
27
|
+
describes: -> { resource.actions },
|
28
|
+
description: -> { action.method }
|
29
|
+
|
30
|
+
group :transactional_example,
|
31
|
+
children: [ :response ],
|
32
|
+
describes: -> { action.examples },
|
33
|
+
description: -> { "Example ##{ parent_object.examples.index(transactional_example) }" }
|
34
|
+
|
35
|
+
group :response,
|
36
|
+
contexts: [ :default ],
|
37
|
+
describes: -> { transactional_example.responses },
|
38
|
+
description: -> { "Running Response #{ response.name }" }
|
39
|
+
|
40
|
+
context :default,
|
41
|
+
http_client_options: {
|
42
|
+
headers: -> { adapter.headers_for(resource, action, transactional_example, response) },
|
43
|
+
method: -> { action.method },
|
44
|
+
uri_template: -> { resource.uri_template },
|
45
|
+
parameters: -> { adapter.parameters_for(resource, action) },
|
46
|
+
payload: -> { adapter.payload_for(transactional_example, response) if adapter.with_payload?(action) }
|
47
|
+
},
|
48
|
+
expectations: {
|
49
|
+
code: -> { response.name.to_i },
|
50
|
+
headers: -> { adapter.headers_for(resource, action, transactional_example, response, include_payload = false) },
|
51
|
+
body: -> { response.body }
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
def headers_for(resource, action, transactional_example, response, include_payload = true)
|
56
|
+
headers = headers_for_response(resource, response)
|
57
|
+
headers += headers_for_payload(transactional_example, response) if with_payload?(action) && include_payload
|
58
|
+
compile_headers(headers)
|
59
|
+
end
|
60
|
+
|
61
|
+
def parameters_for(resource, action)
|
62
|
+
(resource.parameters.collection + action.parameters.collection).each_with_object([]) do |parameter, collection|
|
63
|
+
collection << { name: parameter.name, value: parameter.example_value, required: (parameter.use == :required) }
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def with_payload?(action)
|
68
|
+
%w(POST PUT PATCH).include? action.method
|
69
|
+
end
|
70
|
+
|
71
|
+
def payload_for(transactional_example, response)
|
72
|
+
payload = get_payload(transactional_example, response)
|
73
|
+
payload.body
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def compile_headers(headers)
|
79
|
+
headers.inject({}) do |hash, header|
|
80
|
+
normalize_header_name = header[:name].gsub('-', '_').downcase.to_sym
|
81
|
+
hash.merge!(normalize_header_name => header[:value])
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def headers_for_response(resource, response)
|
86
|
+
collection = []
|
87
|
+
collection << [*resource.model.headers.collection]
|
88
|
+
collection << [*response.headers.collection]
|
89
|
+
collection.flatten
|
90
|
+
end
|
91
|
+
|
92
|
+
def headers_for_payload(transactional_example, response)
|
93
|
+
payload = get_payload(transactional_example, response)
|
94
|
+
[ *payload.headers.collection ].flatten
|
95
|
+
end
|
96
|
+
|
97
|
+
def get_payload(transactional_example, response)
|
98
|
+
index = transactional_example.responses.index(response)
|
99
|
+
transactional_example.requests.fetch(index)
|
100
|
+
rescue => e
|
101
|
+
raise "Unable to load payload for response #{ response.name }"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
data/lib/vigia/config.rb
CHANGED
@@ -1,18 +1,28 @@
|
|
1
1
|
module Vigia
|
2
2
|
class Config
|
3
|
-
attr_accessor :
|
3
|
+
attr_accessor :source_file, :host, :custom_examples_paths, :custom_examples, :headers, :http_client_class
|
4
|
+
attr_accessor :adapter, :hooks, :rspec_config_block, :stderr, :stdout
|
4
5
|
|
5
6
|
def initialize
|
6
7
|
@host = nil
|
7
|
-
@
|
8
|
+
@source_file = nil
|
9
|
+
@rspec_config_block = nil
|
8
10
|
@headers = {}
|
9
11
|
@custom_examples_paths = []
|
10
12
|
@custom_examples = []
|
13
|
+
@hooks = []
|
14
|
+
@stderr = $stderr
|
15
|
+
@stdout = $stdout
|
16
|
+
@adapter = Vigia::Adapters::Blueprint
|
11
17
|
@http_client_class = Vigia::HttpClient::RestClient
|
12
18
|
end
|
13
19
|
|
20
|
+
def apply
|
21
|
+
validate!
|
22
|
+
end
|
23
|
+
|
14
24
|
def validate!
|
15
|
-
raise("You need to provide an
|
25
|
+
raise("You need to provide an source") unless source_file
|
16
26
|
raise("You have to provide a host value in config or in the Apib") unless host
|
17
27
|
end
|
18
28
|
|
@@ -20,27 +30,28 @@ module Vigia
|
|
20
30
|
@custom_examples << { filter: filter, name: name }
|
21
31
|
end
|
22
32
|
|
23
|
-
def
|
24
|
-
@
|
33
|
+
def rspec_config(&block)
|
34
|
+
@rspec_config_block = block
|
25
35
|
end
|
26
36
|
|
27
|
-
def
|
28
|
-
|
29
|
-
collection << custom_example[:name] if eligible_example?(specpaib_example, custom_example[:filter])
|
30
|
-
collection
|
31
|
-
end
|
37
|
+
def before_group(&block)
|
38
|
+
store_hook(Vigia::Sail::GroupInstance, :before, block)
|
32
39
|
end
|
33
40
|
|
34
|
-
def
|
35
|
-
|
41
|
+
def after_group(&block)
|
42
|
+
store_hook(Vigia::Sail::GroupInstance, :after, block)
|
36
43
|
end
|
37
44
|
|
38
|
-
|
45
|
+
def before_context(&block)
|
46
|
+
store_hook(Vigia::Sail::Context, :before, block)
|
47
|
+
end
|
39
48
|
|
40
|
-
def
|
41
|
-
|
49
|
+
def after_context(&block)
|
50
|
+
store_hook(Vigia::Sail::Context, :after, block)
|
51
|
+
end
|
42
52
|
|
43
|
-
|
53
|
+
def store_hook(rspec_class, filter, block)
|
54
|
+
@hooks << { rspec_class: rspec_class, filter: filter, block: block }
|
44
55
|
end
|
45
56
|
end
|
46
57
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Vigia
|
2
|
+
module HttpClient
|
3
|
+
class Options < OpenStruct
|
4
|
+
class << self
|
5
|
+
def build(context, in_let_context)
|
6
|
+
instance = new
|
7
|
+
instance.context = context
|
8
|
+
instance.options.each do |name, value|
|
9
|
+
instance[name] = context.contextual_object(object: value, context: in_let_context)
|
10
|
+
end
|
11
|
+
instance.use_uri_template if instance.uri_template
|
12
|
+
instance.include_config_headers if Vigia.config.headers.any?
|
13
|
+
instance
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def options
|
18
|
+
context.options[:http_client_options] || {}
|
19
|
+
end
|
20
|
+
|
21
|
+
def use_uri_template
|
22
|
+
self.url = Vigia::Url.new(uri_template).expand(parameters)
|
23
|
+
end
|
24
|
+
|
25
|
+
def include_config_headers
|
26
|
+
self.headers.merge!(Vigia.config.headers)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|