vigia 0.1.4 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/Gemfile +3 -0
- data/README.md +1 -1
- data/lib/vigia.rb +29 -8
- data/lib/vigia/adapters/raml.rb +111 -0
- data/lib/vigia/config.rb +4 -6
- data/lib/vigia/parameters.rb +1 -1
- data/lib/vigia/rspec.rb +2 -5
- data/lib/vigia/sail/examples/default.rb +28 -16
- data/lib/vigia/sail/group.rb +12 -0
- data/lib/vigia/sail/group_instance.rb +1 -1
- data/lib/vigia/sail/rspec_object.rb +8 -0
- data/lib/vigia/url.rb +2 -4
- data/lib/vigia/version.rb +1 -1
- metadata +22 -7
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
NDYwMThkZDk2ZDI3NDFhYzc5ZWUyNzQ4NzA0NmRjMjgyNmFjZGM4Nw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MDk2NWU5YTkyMTg0NzE2YzFiNmRlMDY2Yzg3NmNkMDU1NmFiNmJkOQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZjA0N2FmOTg2ODRiN2Y1Y2FiMzEwYzcyNDBkNGMwNzQ2ZWNhZmMwZjc4OWZl
|
10
|
+
MDNiYzU3MDE0MTQxMzNkNWFjNWY3NzhiYWQyNWVhZDhiMzllZDMzMDY3MWQ1
|
11
|
+
MzM0ZjJjNTgxYWU4ZWU5ODZlZTExYzFlZDdjZDFlZWYzYzQxODY=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
OWMyMDQyZTViMWNkZTMzZmM5OGRlM2E1OTk2MmUwYTI5ZGY0MjEwMzM1NTZj
|
14
|
+
NTQ1YjgxMTVmMTBiODk2YTM1YWUxNDIzNDRlNDNmMTljM2QwYWNlOWMwOTE2
|
15
|
+
NTc1YTVhZDcwMDMzNzM2NTI4MGY3YWI2OWYyYjIyZjgzODcxZjA=
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -9,7 +9,7 @@ Vigia
|
|
9
9
|
|
10
10
|
<img src="http://singularities.org/vigia.png" width="96" height="96" class="right" alt="Vigia logo" />
|
11
11
|
|
12
|
-
Vigia is a gem to perform integration tests using RSpec and a compatible adapter (See [Adapters](https://github.com/lonelyplanet/vigia/wiki/Adapters)). The adapter creates the structure of the test (groups and context) and sets up all the variables (See [Context variables](https://github.com/lonelyplanet/vigia/wiki/Context-variables)) used to perform the http request.
|
12
|
+
Vigia is a gem to perform integration tests on an API server using RSpec and a compatible adapter (See [Adapters](https://github.com/lonelyplanet/vigia/wiki/Adapters)). The adapter creates the structure of the test (groups and context) and sets up all the variables (See [Context variables](https://github.com/lonelyplanet/vigia/wiki/Context-variables)) used to perform the http request.
|
13
13
|
|
14
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](https://github.com/lonelyplanet/vigia/wiki/Expectations---Examples) and [Custom Shared Examples](https://github.com/lonelyplanet/vigia/wiki/Shared-examples))
|
15
15
|
|
data/lib/vigia.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
require 'redsnow'
|
4
|
+
require 'raml'
|
4
5
|
require 'rspec'
|
5
6
|
require 'rest_client'
|
6
7
|
require 'addressable/template'
|
7
8
|
|
8
9
|
require_relative 'vigia/adapter'
|
9
10
|
require_relative 'vigia/adapters/blueprint'
|
11
|
+
require_relative 'vigia/adapters/raml'
|
10
12
|
require_relative 'vigia/config'
|
11
13
|
require_relative 'vigia/hooks'
|
12
14
|
require_relative 'vigia/formatter'
|
@@ -17,6 +19,7 @@ require_relative 'vigia/parameters'
|
|
17
19
|
require_relative 'vigia/rspec'
|
18
20
|
require_relative 'vigia/sail/rspec_object'
|
19
21
|
require_relative 'vigia/sail/example'
|
22
|
+
require_relative 'vigia/sail/examples/default'
|
20
23
|
require_relative 'vigia/sail/context'
|
21
24
|
require_relative 'vigia/sail/group'
|
22
25
|
require_relative 'vigia/sail/group_instance'
|
@@ -25,21 +28,39 @@ require_relative 'vigia/version'
|
|
25
28
|
|
26
29
|
module Vigia
|
27
30
|
class << self
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
+
|
32
|
+
attr_reader :config
|
33
|
+
|
31
34
|
def configure
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
+
reset!
|
36
|
+
@config = Vigia::Config.new.tap do |_config|
|
37
|
+
yield _config
|
38
|
+
load_default_examples if _config.load_default_examples
|
39
|
+
end
|
35
40
|
end
|
41
|
+
|
36
42
|
def spec_folder
|
37
43
|
File.join(__dir__, 'vigia', 'spec')
|
38
44
|
end
|
45
|
+
|
39
46
|
def rspec!
|
47
|
+
ensure_config
|
40
48
|
Vigia::Rspec.new.run!
|
41
49
|
end
|
50
|
+
|
51
|
+
def reset!
|
52
|
+
[ Vigia::Sail::Context, Vigia::Sail::Example, Vigia::Sail::Group ].map(&:clean!)
|
53
|
+
@config = nil
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def load_default_examples
|
59
|
+
Vigia::Sail::Examples::Default.load!
|
60
|
+
end
|
61
|
+
|
62
|
+
def ensure_config
|
63
|
+
(config && config.validate!) || raise('Invalid config')
|
64
|
+
end
|
42
65
|
end
|
43
66
|
end
|
44
|
-
|
45
|
-
require_relative 'vigia/sail/examples/default'
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module Vigia
|
2
|
+
module Adapters
|
3
|
+
class Raml < Vigia::Adapter
|
4
|
+
|
5
|
+
attr_reader :raml
|
6
|
+
|
7
|
+
setup_adapter do
|
8
|
+
|
9
|
+
after_initialize do
|
10
|
+
@raml = ::Raml::parse_file(source_file)
|
11
|
+
end
|
12
|
+
|
13
|
+
group :resource,
|
14
|
+
primary: true,
|
15
|
+
children: [ :method ],
|
16
|
+
describes: -> { adapter.raml.resources.values },
|
17
|
+
description: -> { "Resource: #{ resource.name }" },
|
18
|
+
recursion: -> { resources.values }
|
19
|
+
|
20
|
+
group :method,
|
21
|
+
children: [ :response ],
|
22
|
+
describes: -> { resource.methods.values },
|
23
|
+
description: -> { "Method: #{ method.name }" }
|
24
|
+
|
25
|
+
group :response,
|
26
|
+
children: [ :body ],
|
27
|
+
describes: -> { method.responses.values },
|
28
|
+
description: -> { "Response: #{ response.name }" }
|
29
|
+
|
30
|
+
group :body,
|
31
|
+
contexts: [ :default ],
|
32
|
+
describes: -> { response.bodies.values },
|
33
|
+
description: -> { "Content type: #{ body.name }" }
|
34
|
+
|
35
|
+
context :default,
|
36
|
+
http_client_options: {
|
37
|
+
method: -> { method.name },
|
38
|
+
uri_template: -> { adapter.resource_uri_template(method) },
|
39
|
+
parameters: -> { adapter.parameters_for(method) },
|
40
|
+
headers: -> { adapter.request_headers(body) },
|
41
|
+
payload: -> { adapter.payload_for(method, body) if adapter.with_payload?(method.name) }
|
42
|
+
},
|
43
|
+
expectations: {
|
44
|
+
code: -> { response.name.to_i },
|
45
|
+
headers: -> { adapter.expected_headers(body) },
|
46
|
+
body: -> { body.schema.value }
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
def resource_uri_template(method)
|
51
|
+
uri_template = method.parent.resource_path
|
52
|
+
uri_template += query_parameters(method)
|
53
|
+
end
|
54
|
+
|
55
|
+
def parameters_for(method)
|
56
|
+
format_parameters(method.query_parameters) + format_parameters(method.parent.uri_parameters)
|
57
|
+
end
|
58
|
+
|
59
|
+
def request_headers(body)
|
60
|
+
method = body.parent.parent
|
61
|
+
compile_headers(method.headers).tap do |headers|
|
62
|
+
return unless with_payload?(method.name)
|
63
|
+
return if request_body_for(method, body).name == '*/*'
|
64
|
+
headers.merge!(content_type: request_body_for(method, body).name)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def expected_headers(body)
|
69
|
+
compile_headers(body.parent.headers).tap do |headers|
|
70
|
+
# Dont add content_type header if response is 204 (nil response)
|
71
|
+
headers.merge!(content_type: body.media_type) unless body.parent.name == 204 or headers.key?(:content_type)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def payload_for(method, body)
|
76
|
+
return unless with_payload?(method.name)
|
77
|
+
request_body_for(method, body).schema.value
|
78
|
+
end
|
79
|
+
|
80
|
+
def with_payload?(method_name)
|
81
|
+
[ :post, :put, :patch ].include?(method_name.to_s.downcase.to_sym)
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def format_parameters(raml_hash)
|
87
|
+
raml_hash.values.each_with_object([]) do |parameter, array|
|
88
|
+
array << { name: parameter.name, value: parameter.example, required: !parameter.optional }
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def compile_headers(headers)
|
93
|
+
headers.each_with_object({}) do |(key, header), hash|
|
94
|
+
raise "Required header #{ key } does not have an example value" if header.example.nil? && !header.optional
|
95
|
+
hash.merge!(key.to_s.gsub('-', '_').downcase.to_sym => header.example)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def request_body_for(method, response_body)
|
100
|
+
body = response_body.name == '*/*' ? method.bodies.values.first : method.bodies[response_body.name]
|
101
|
+
body ||raise("An example body cannot be found for method #{ method.name } #{ method.parent.resource_path }")
|
102
|
+
end
|
103
|
+
|
104
|
+
def query_parameters(method)
|
105
|
+
method.apply_traits if method.traits.any? # Does this belong here RAML?
|
106
|
+
return '' if method.query_parameters.empty?
|
107
|
+
"{?#{ method.query_parameters.keys.join(',') }}"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
data/lib/vigia/config.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
module Vigia
|
2
2
|
class Config
|
3
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, :internal_hosts
|
4
|
+
attr_accessor :adapter, :hooks, :rspec_config_block, :stderr, :stdout, :internal_hosts, :load_default_examples
|
5
5
|
|
6
6
|
def initialize
|
7
7
|
@host = nil
|
8
8
|
@source_file = nil
|
9
9
|
@rspec_config_block = nil
|
10
|
+
@load_default_examples = true
|
10
11
|
@internal_hosts = []
|
11
12
|
@headers = {}
|
12
13
|
@custom_examples_paths = []
|
@@ -18,13 +19,10 @@ module Vigia
|
|
18
19
|
@http_client_class = Vigia::HttpClient::RestClient
|
19
20
|
end
|
20
21
|
|
21
|
-
def apply
|
22
|
-
validate!
|
23
|
-
end
|
24
|
-
|
25
22
|
def validate!
|
26
|
-
raise("You need to provide an source") unless source_file
|
27
23
|
raise("You have to provide a host value in config or in the Apib") unless host
|
24
|
+
|
25
|
+
true
|
28
26
|
end
|
29
27
|
|
30
28
|
def add_custom_examples_on(filter, name)
|
data/lib/vigia/parameters.rb
CHANGED
data/lib/vigia/rspec.rb
CHANGED
@@ -1,10 +1,6 @@
|
|
1
1
|
module Vigia
|
2
2
|
class Rspec
|
3
3
|
class << self
|
4
|
-
def adapter
|
5
|
-
@@adapter
|
6
|
-
end
|
7
|
-
|
8
4
|
def include_shared_folders
|
9
5
|
require_custom_examples
|
10
6
|
require "#{ __dir__ }/spec/support/utils"
|
@@ -35,6 +31,7 @@ module Vigia
|
|
35
31
|
|
36
32
|
def set_global_memoizers(rspec)
|
37
33
|
instance = adapter
|
34
|
+
self.class.define_singleton_method(:adapter) { instance }
|
38
35
|
rspec.let(:client) { Vigia.config.http_client_class.new(http_client_options) }
|
39
36
|
rspec.let(:result) { client.run }
|
40
37
|
rspec.let(:result!) { client.run! }
|
@@ -42,7 +39,7 @@ module Vigia
|
|
42
39
|
end
|
43
40
|
|
44
41
|
def adapter
|
45
|
-
|
42
|
+
@adapter ||= Vigia.config.adapter.instance
|
46
43
|
end
|
47
44
|
|
48
45
|
private
|
@@ -1,17 +1,29 @@
|
|
1
|
-
Vigia
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
expect(expectations.code.member?(result.code)).to be true
|
7
|
-
else
|
8
|
-
expect(result.code).to be(expectations.code)
|
9
|
-
end
|
10
|
-
}
|
11
|
-
)
|
1
|
+
module Vigia
|
2
|
+
module Sail
|
3
|
+
module Examples
|
4
|
+
module Default
|
5
|
+
module_function
|
12
6
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
7
|
+
def load!
|
8
|
+
Vigia::Sail::Example.register(
|
9
|
+
:code_match,
|
10
|
+
description: 'has the expected HTTP code',
|
11
|
+
expectation: -> {
|
12
|
+
if expectations.code.is_a?(Range)
|
13
|
+
expect(expectations.code.member?(result.code)).to be true
|
14
|
+
else
|
15
|
+
expect(result.code).to be(expectations.code)
|
16
|
+
end
|
17
|
+
}
|
18
|
+
)
|
19
|
+
|
20
|
+
Vigia::Sail::Example.register(
|
21
|
+
:include_headers,
|
22
|
+
description: 'includes the expected headers',
|
23
|
+
expectation: -> { expect(result.headers).to include(expectations.headers) }
|
24
|
+
)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/vigia/sail/group.rb
CHANGED
@@ -15,6 +15,8 @@ module Vigia
|
|
15
15
|
rspec.describe group_instance do
|
16
16
|
let(group_instance.group.name) { group_instance.described_object }
|
17
17
|
|
18
|
+
group_instance.group.include_recursion(group_instance.described_object, self)
|
19
|
+
|
18
20
|
group_instance.run(self)
|
19
21
|
end
|
20
22
|
end
|
@@ -32,6 +34,16 @@ module Vigia
|
|
32
34
|
contextual_object(option_name: :describes) || []
|
33
35
|
end
|
34
36
|
|
37
|
+
def include_recursion(object, rspec_context)
|
38
|
+
describes = contextual_object(option_name: :recursion, context: object) || []
|
39
|
+
return if describes.empty?
|
40
|
+
|
41
|
+
self.clone.tap do |recursive_group|
|
42
|
+
recursive_group.options[:describes] = describes
|
43
|
+
recursive_group.instance_variable_set('@rspec', rspec_context)
|
44
|
+
end.run
|
45
|
+
end
|
46
|
+
|
35
47
|
def create_group_instance(object, index)
|
36
48
|
instance_name = "#{ name }#{ index }"
|
37
49
|
Vigia::Sail::GroupInstance.new(instance_name, options, rspec).tap do |instance|
|
data/lib/vigia/url.rb
CHANGED
@@ -17,10 +17,8 @@ module Vigia
|
|
17
17
|
|
18
18
|
attr_reader :uri_template
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
def initialize(apib_uri_template)
|
23
|
-
@uri_template = Addressable::Template.new(apib_uri_template)
|
20
|
+
def initialize(template)
|
21
|
+
@uri_template = Addressable::Template.new(template)
|
24
22
|
end
|
25
23
|
|
26
24
|
def expand(parameters)
|
data/lib/vigia/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vigia
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Tapiador
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-03
|
12
|
+
date: 2015-05-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -81,6 +81,20 @@ dependencies:
|
|
81
81
|
- - ! '>='
|
82
82
|
- !ruby/object:Gem::Version
|
83
83
|
version: '0'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: raml_ruby
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ! '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
type: :runtime
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ! '>='
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
84
98
|
- !ruby/object:Gem::Dependency
|
85
99
|
name: bundler
|
86
100
|
requirement: !ruby/object:Gem::Requirement
|
@@ -191,22 +205,23 @@ files:
|
|
191
205
|
- Gemfile
|
192
206
|
- lib/vigia/adapter.rb
|
193
207
|
- lib/vigia/adapters/blueprint.rb
|
194
|
-
- lib/vigia/
|
208
|
+
- lib/vigia/adapters/raml.rb
|
195
209
|
- lib/vigia/formatter.rb
|
196
210
|
- lib/vigia/hooks.rb
|
197
211
|
- lib/vigia/http_client/options.rb
|
198
212
|
- lib/vigia/http_client/requests.rb
|
199
213
|
- lib/vigia/http_client/rest_client.rb
|
200
|
-
- lib/vigia/parameters.rb
|
201
|
-
- lib/vigia/rspec.rb
|
202
|
-
- lib/vigia/sail/context.rb
|
203
214
|
- lib/vigia/sail/example.rb
|
204
215
|
- lib/vigia/sail/examples/default.rb
|
216
|
+
- lib/vigia/sail/context.rb
|
205
217
|
- lib/vigia/sail/group.rb
|
206
218
|
- lib/vigia/sail/group_instance.rb
|
207
219
|
- lib/vigia/sail/rspec_object.rb
|
208
|
-
- lib/vigia/spec/api_spec.rb
|
209
220
|
- lib/vigia/spec/support/utils.rb
|
221
|
+
- lib/vigia/spec/api_spec.rb
|
222
|
+
- lib/vigia/rspec.rb
|
223
|
+
- lib/vigia/config.rb
|
224
|
+
- lib/vigia/parameters.rb
|
210
225
|
- lib/vigia/url.rb
|
211
226
|
- lib/vigia/version.rb
|
212
227
|
- lib/vigia.rb
|