vigia 0.1.4 → 0.2.0
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.
- 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
|