webspicy 0.1.0.pre.rc1
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 +7 -0
- data/Gemfile +2 -0
- data/LICENSE.md +22 -0
- data/README.md +7 -0
- data/Rakefile +11 -0
- data/examples/restful/Gemfile +5 -0
- data/examples/restful/Gemfile.lock +69 -0
- data/examples/restful/Rakefile +21 -0
- data/examples/restful/app.rb +32 -0
- data/examples/restful/webspicy/schema.fio +4 -0
- data/examples/restful/webspicy/todo/getTodo.yml +52 -0
- data/examples/restful/webspicy/todo/getTodos.yml +39 -0
- data/lib/webspicy/checker.rb +26 -0
- data/lib/webspicy/client/http_client.rb +70 -0
- data/lib/webspicy/client.rb +20 -0
- data/lib/webspicy/configuration.rb +168 -0
- data/lib/webspicy/formaldoc.fio +47 -0
- data/lib/webspicy/resource/service/invocation.rb +158 -0
- data/lib/webspicy/resource/service/test_case.rb +74 -0
- data/lib/webspicy/resource/service.rb +49 -0
- data/lib/webspicy/resource.rb +43 -0
- data/lib/webspicy/scope.rb +113 -0
- data/lib/webspicy/tester/asserter.rb +94 -0
- data/lib/webspicy/tester/assertions.rb +103 -0
- data/lib/webspicy/tester.rb +96 -0
- data/lib/webspicy/version.rb +8 -0
- data/lib/webspicy.rb +112 -0
- data/spec/unit/resource/service/test_dress_params.rb +34 -0
- data/spec/unit/resource/test_instantiate_url.rb +20 -0
- data/spec/unit/resource/test_url_placeholders.rb +16 -0
- data/spec/unit/scope/test_each_resource.rb +59 -0
- data/spec/unit/scope/test_each_service.rb +51 -0
- data/spec/unit/scope/test_to_real_url.rb +75 -0
- data/spec/unit/spec_helper.rb +28 -0
- data/spec/unit/test_configuration.rb +84 -0
- data/spec/unit/tester/test_assertions.rb +108 -0
- data/tasks/test.rake +27 -0
- metadata +149 -0
@@ -0,0 +1,96 @@
|
|
1
|
+
module Webspicy
|
2
|
+
class Tester
|
3
|
+
|
4
|
+
def initialize(config)
|
5
|
+
@config = config
|
6
|
+
end
|
7
|
+
attr_reader :config
|
8
|
+
|
9
|
+
def call
|
10
|
+
Webspicy.with_scope_for(config) do |scope|
|
11
|
+
client = scope.get_client
|
12
|
+
scope.each_resource do |resource|
|
13
|
+
scope.each_service(resource) do |service|
|
14
|
+
RSpec.describe "#{service.method} `#{resource.url}`" do
|
15
|
+
scope.each_example(service) do |test_case|
|
16
|
+
describe test_case.description do
|
17
|
+
|
18
|
+
before(:each) do
|
19
|
+
client.before(test_case, service, resource)
|
20
|
+
end
|
21
|
+
|
22
|
+
subject do
|
23
|
+
client.call(test_case, service, resource)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'can be invoked successfuly' do
|
27
|
+
expect(subject.done?).to eq(true)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'meets the status and content type specification' do
|
31
|
+
expect(subject.expected_status_unmet).to(be_nil)
|
32
|
+
expect(subject.expected_content_type_unmet).to(be_nil)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'has the expected response headers' do
|
36
|
+
expect(subject.expected_headers_unmet).to(be_nil)
|
37
|
+
end if test_case.has_expected_headers?
|
38
|
+
|
39
|
+
it 'meets the output data schema' do
|
40
|
+
expect(subject.expected_schema_unmet).to(be_nil)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'meets all assertions' do
|
44
|
+
expect(subject.assertions_unmet).to(be_nil)
|
45
|
+
end if test_case.has_assertions?
|
46
|
+
|
47
|
+
end
|
48
|
+
end # service.examples
|
49
|
+
|
50
|
+
scope.each_counterexamples(service) do |test_case|
|
51
|
+
describe test_case.description do
|
52
|
+
|
53
|
+
before(:each) do
|
54
|
+
client.before(test_case, service, resource)
|
55
|
+
end
|
56
|
+
|
57
|
+
subject do
|
58
|
+
client.call(test_case, service, resource)
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'can be invoked successfuly' do
|
62
|
+
expect(subject.done?).to eq(true)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'meets the status and content type specification' do
|
66
|
+
expect(subject.expected_status_unmet).to(be_nil)
|
67
|
+
expect(subject.expected_content_type_unmet).to(be_nil)
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'has the expected response headers' do
|
71
|
+
expect(subject.expected_headers_unmet).to(be_nil)
|
72
|
+
end if test_case.has_expected_headers?
|
73
|
+
|
74
|
+
it 'meets the output data schema' do
|
75
|
+
expect(subject.expected_schema_unmet).to(be_nil)
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'meets all assertions' do
|
79
|
+
expect(subject.assertions_unmet).to(be_nil)
|
80
|
+
end if test_case.has_assertions?
|
81
|
+
|
82
|
+
it 'has expected error' do
|
83
|
+
expect(subject.expected_error_unmet).to(be_nil)
|
84
|
+
end if test_case.has_expected_error?
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
RSpec::Core::Runner.run config.rspec_options
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
end # class Tester
|
96
|
+
end # module Webspicy
|
data/lib/webspicy.rb
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'http'
|
2
|
+
require 'json'
|
3
|
+
require 'path'
|
4
|
+
require 'finitio'
|
5
|
+
require 'logger'
|
6
|
+
require 'ostruct'
|
7
|
+
require 'yaml'
|
8
|
+
require 'rspec'
|
9
|
+
module Webspicy
|
10
|
+
|
11
|
+
###
|
12
|
+
### Load library
|
13
|
+
###
|
14
|
+
|
15
|
+
require 'webspicy/configuration'
|
16
|
+
require 'webspicy/scope'
|
17
|
+
require 'webspicy/client'
|
18
|
+
require 'webspicy/client/http_client'
|
19
|
+
require 'webspicy/resource'
|
20
|
+
require 'webspicy/checker'
|
21
|
+
require 'webspicy/tester'
|
22
|
+
require 'webspicy/tester/assertions'
|
23
|
+
require 'webspicy/tester/asserter'
|
24
|
+
|
25
|
+
###
|
26
|
+
### About folders
|
27
|
+
###
|
28
|
+
|
29
|
+
ROOT_FOLDER = Path.backfind('.[Gemfile]')
|
30
|
+
|
31
|
+
EXAMPLES_FOLDER = ROOT_FOLDER/'examples'
|
32
|
+
|
33
|
+
###
|
34
|
+
### About formal doc and resources defined there
|
35
|
+
###
|
36
|
+
|
37
|
+
FORMALDOC = Finitio::DEFAULT_SYSTEM.parse (Path.dir/"webspicy/formaldoc.fio").read
|
38
|
+
|
39
|
+
def resource(raw, file = nil)
|
40
|
+
FORMALDOC["Resource"].dress(raw)
|
41
|
+
end
|
42
|
+
module_function :resource
|
43
|
+
|
44
|
+
def service(raw)
|
45
|
+
FORMALDOC["Service"].dress(raw)
|
46
|
+
end
|
47
|
+
module_function :service
|
48
|
+
|
49
|
+
def test_case(raw)
|
50
|
+
FORMALDOC["TestCase"].dress(raw)
|
51
|
+
end
|
52
|
+
module_function :test_case
|
53
|
+
|
54
|
+
#
|
55
|
+
# Yields a Scope instance for the configuration passed as parameter.
|
56
|
+
#
|
57
|
+
# This method makes sure that the scope will also be accessible for
|
58
|
+
# Finitio world schema parsing/dressing. Given that some global state
|
59
|
+
# is required (see "Schema" ADT, the dresser in particular, which calls
|
60
|
+
# `schema` later), the scope is put as a thread-local variable...
|
61
|
+
#
|
62
|
+
def with_scope_for(config)
|
63
|
+
scope = set_current_scope(Scope.new(config))
|
64
|
+
yield scope
|
65
|
+
set_current_scope(nil)
|
66
|
+
end
|
67
|
+
module_function :with_scope_for
|
68
|
+
|
69
|
+
#
|
70
|
+
# Sets the current scope.
|
71
|
+
#
|
72
|
+
# See `with_scope_for`
|
73
|
+
#
|
74
|
+
def set_current_scope(scope)
|
75
|
+
Thread.current[:webspicy_scope] = scope
|
76
|
+
end
|
77
|
+
module_function :set_current_scope
|
78
|
+
|
79
|
+
#
|
80
|
+
# Parses a webservice schema (typically input or output) in the context
|
81
|
+
# of the current scope previously installed using `with_scope_for`.
|
82
|
+
#
|
83
|
+
# If no scope has previously been installed, Finitio's default system
|
84
|
+
# is used instead of another schema.
|
85
|
+
#
|
86
|
+
def schema(fio)
|
87
|
+
if scope = Thread.current[:webspicy_scope]
|
88
|
+
scope.parse_schema(fio)
|
89
|
+
else
|
90
|
+
Finitio::DEFAULT_SYSTEM.parse(fio)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
module_function :schema
|
94
|
+
|
95
|
+
###
|
96
|
+
### Logging facade
|
97
|
+
###
|
98
|
+
|
99
|
+
LOGGER = ::Logger.new(STDOUT)
|
100
|
+
LOGGER.level = Logger.const_get(ENV['LOG_LEVEL'] || 'WARN')
|
101
|
+
|
102
|
+
def info(*args, &bl)
|
103
|
+
LOGGER && LOGGER.info(*args, &bl)
|
104
|
+
end
|
105
|
+
module_function :info
|
106
|
+
|
107
|
+
def debug(*args, &bl)
|
108
|
+
LOGGER && LOGGER.debug(*args, &bl)
|
109
|
+
end
|
110
|
+
module_function :debug
|
111
|
+
|
112
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Webspicy
|
3
|
+
class Resource
|
4
|
+
describe Service, "dress_params" do
|
5
|
+
|
6
|
+
it 'symbolizes keys' do
|
7
|
+
service = Webspicy.service({
|
8
|
+
method: "GET",
|
9
|
+
description: "Test service",
|
10
|
+
preconditions: "Foo",
|
11
|
+
input_schema: "{ id: Integer }",
|
12
|
+
output_schema: "{}",
|
13
|
+
error_schema: "{}"
|
14
|
+
})
|
15
|
+
params = service.dress_params("id" => 1247)
|
16
|
+
expect(params).to eq(id: 1247)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'supports an array' do
|
20
|
+
service = Webspicy.service({
|
21
|
+
method: "GET",
|
22
|
+
description: "Test service",
|
23
|
+
preconditions: "Foo",
|
24
|
+
input_schema: "[{ id: Integer }]",
|
25
|
+
output_schema: "{}",
|
26
|
+
error_schema: "{}"
|
27
|
+
})
|
28
|
+
params = service.dress_params([{"id" => 1247}])
|
29
|
+
expect(params).to eq([{id: 1247}])
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end # class Resource
|
34
|
+
end # module Webspicy
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
module Webspicy
|
3
|
+
describe Resource, "instantiate_url" do
|
4
|
+
|
5
|
+
it 'does nothing when the url has no placeholder' do
|
6
|
+
r = Resource.new(url: "/test/a/url")
|
7
|
+
url, params = r.instantiate_url(foo: "bar")
|
8
|
+
expect(url).to eq("/test/a/url")
|
9
|
+
expect(params).to eq(foo: "bar")
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'instantiates placeholders and strips corresponding params' do
|
13
|
+
r = Resource.new(url: "/test/{foo}/url")
|
14
|
+
url, params = r.instantiate_url(foo: "bar", baz: "coz")
|
15
|
+
expect(url).to eq("/test/bar/url")
|
16
|
+
expect(params).to eq(baz: "coz")
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
module Webspicy
|
3
|
+
describe Resource, "url_placeholders" do
|
4
|
+
|
5
|
+
it 'returns an empty array on none' do
|
6
|
+
r = Resource.new(url: "/test/a/url")
|
7
|
+
expect(r.url_placeholders).to eq([])
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'returns all placeholders' do
|
11
|
+
r = Resource.new(url: "/test/{foo}/url/{bar}")
|
12
|
+
expect(r.url_placeholders).to eq([:foo, :bar])
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Webspicy
|
3
|
+
describe Scope, 'each_resource' do
|
4
|
+
|
5
|
+
with_scope_management
|
6
|
+
|
7
|
+
let(:scope) {
|
8
|
+
Scope.new(configuration)
|
9
|
+
}
|
10
|
+
|
11
|
+
subject {
|
12
|
+
scope.each_resource.to_a
|
13
|
+
}
|
14
|
+
|
15
|
+
context 'without any filter' do
|
16
|
+
|
17
|
+
let(:configuration) {
|
18
|
+
Configuration.new{|c|
|
19
|
+
c.add_folder restful_folder
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
it 'returns all files' do
|
24
|
+
expect(subject.size).to eql(restful_folder.glob('**/*.yml').size)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'with a file filter as a proc' do
|
29
|
+
|
30
|
+
let(:configuration) {
|
31
|
+
Configuration.new{|c|
|
32
|
+
c.add_folder restful_folder
|
33
|
+
c.file_filter = ->(f) {
|
34
|
+
f.basename.to_s == "getTodo.yml"
|
35
|
+
}
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
it 'returns only that file' do
|
40
|
+
expect(subject.size).to eql(1)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'with a file filter as a Regex' do
|
45
|
+
|
46
|
+
let(:configuration) {
|
47
|
+
Configuration.new{|c|
|
48
|
+
c.add_folder restful_folder
|
49
|
+
c.file_filter = /getTodo.yml/
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
it 'returns only that file' do
|
54
|
+
expect(subject.size).to eql(1)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Webspicy
|
3
|
+
describe Scope, 'each_service' do
|
4
|
+
|
5
|
+
with_scope_management
|
6
|
+
|
7
|
+
let(:scope) {
|
8
|
+
Scope.new(configuration)
|
9
|
+
}
|
10
|
+
|
11
|
+
let(:resource) {
|
12
|
+
scope.each_resource.first
|
13
|
+
}
|
14
|
+
|
15
|
+
subject {
|
16
|
+
scope.each_service(resource).to_a
|
17
|
+
}
|
18
|
+
|
19
|
+
context 'without any filter' do
|
20
|
+
|
21
|
+
let(:configuration) {
|
22
|
+
Configuration.new{|c|
|
23
|
+
c.add_folder restful_folder
|
24
|
+
c.file_filter = /getTodo.yml/
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
it 'returns all services' do
|
29
|
+
expect(subject.size).to eql(1)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'with a service filter as a proc' do
|
34
|
+
|
35
|
+
let(:configuration) {
|
36
|
+
Configuration.new{|c|
|
37
|
+
c.add_folder restful_folder
|
38
|
+
c.file_filter = /getTodo.yml/
|
39
|
+
c.service_filter = ->(s) {
|
40
|
+
s.method == "POST"
|
41
|
+
}
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
it 'returns nothing' do
|
46
|
+
expect(subject.size).to eql(0)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Webspicy
|
3
|
+
describe Scope, 'to_real_url' do
|
4
|
+
|
5
|
+
let(:scope) {
|
6
|
+
Scope.new(configuration)
|
7
|
+
}
|
8
|
+
|
9
|
+
context 'when no host at all' do
|
10
|
+
|
11
|
+
let(:configuration) {
|
12
|
+
Configuration.new
|
13
|
+
}
|
14
|
+
|
15
|
+
it 'does nothing on absolute URLs already' do
|
16
|
+
url = 'http://127.0.0.1:4567/todo'
|
17
|
+
got = scope.to_real_url(url)
|
18
|
+
expect(got).to eql(url)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'fails on relative URLs' do
|
22
|
+
expect(->(){
|
23
|
+
scope.to_real_url("/todo")
|
24
|
+
}).to raise_error(/Unable to resolve `\/todo`/)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'with a static host' do
|
29
|
+
|
30
|
+
let(:configuration) {
|
31
|
+
Configuration.new do |c|
|
32
|
+
c.host = "http://127.0.0.1:4568"
|
33
|
+
end
|
34
|
+
}
|
35
|
+
|
36
|
+
it 'does nothing on absolute URLs already' do
|
37
|
+
url = 'http://127.0.0.1:4567/todo'
|
38
|
+
got = scope.to_real_url(url)
|
39
|
+
expect(got).to eql(url)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'resolves relative URLs as expected' do
|
43
|
+
url = '/todo'
|
44
|
+
got = scope.to_real_url(url)
|
45
|
+
expect(got).to eql("http://127.0.0.1:4568/todo")
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'with a dynamic host resolver' do
|
51
|
+
|
52
|
+
let(:configuration) {
|
53
|
+
Configuration.new do |c|
|
54
|
+
c.host = ->(url) {
|
55
|
+
"http://127.0.0.1:4568#{url}"
|
56
|
+
}
|
57
|
+
end
|
58
|
+
}
|
59
|
+
|
60
|
+
it 'resolves absolute URLs' do
|
61
|
+
url = 'http://127.0.0.1:4567/todo'
|
62
|
+
got = scope.to_real_url(url)
|
63
|
+
expect(got).to eql("http://127.0.0.1:4568#{url}")
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'resolves relative URLs as expected' do
|
67
|
+
url = '/todo'
|
68
|
+
got = scope.to_real_url(url)
|
69
|
+
expect(got).to eql("http://127.0.0.1:4568/todo")
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'webspicy'
|
3
|
+
|
4
|
+
module SpecHelper
|
5
|
+
|
6
|
+
def restful_folder
|
7
|
+
Webspicy::EXAMPLES_FOLDER/'restful/webspicy'
|
8
|
+
end
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
module ScopeManagement
|
13
|
+
|
14
|
+
def with_scope_management
|
15
|
+
before(:each) {
|
16
|
+
Webspicy.set_current_scope(scope)
|
17
|
+
}
|
18
|
+
after(:each) {
|
19
|
+
Webspicy.set_current_scope(nil)
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
RSpec.configure do |c|
|
26
|
+
c.include SpecHelper
|
27
|
+
c.extend ScopeManagement
|
28
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Webspicy
|
3
|
+
describe Configuration do
|
4
|
+
|
5
|
+
it 'yields itself at construction' do
|
6
|
+
seen = nil
|
7
|
+
Configuration.new do |c|
|
8
|
+
seen = c
|
9
|
+
end
|
10
|
+
expect(seen).to be_a(Configuration)
|
11
|
+
end
|
12
|
+
|
13
|
+
describe 'run_counterexamples' do
|
14
|
+
|
15
|
+
it 'is true by default' do
|
16
|
+
config = Configuration.new
|
17
|
+
expect(config.run_counterexamples?).to eql(true)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'implements backward compatibility with ROBUST env variable' do
|
21
|
+
ENV['ROBUST'] = 'no'
|
22
|
+
config = Configuration.new
|
23
|
+
expect(config.run_counterexamples?).to eql(false)
|
24
|
+
|
25
|
+
ENV['ROBUST'] = 'yes'
|
26
|
+
config = Configuration.new
|
27
|
+
expect(config.run_counterexamples?).to eql(true)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'ignores the environment is set explicitly' do
|
31
|
+
ENV['ROBUST'] = 'yes'
|
32
|
+
config = Configuration.new do |c|
|
33
|
+
c.run_counterexamples = false
|
34
|
+
end
|
35
|
+
expect(config.run_counterexamples?).to eql(false)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe 'file_filter' do
|
40
|
+
|
41
|
+
it 'is nil by default' do
|
42
|
+
config = Configuration.new
|
43
|
+
expect(config.file_filter).to be_nil
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'is implements backward compatibility with the RESOURCE env variable' do
|
47
|
+
ENV['RESOURCE'] = 'getTodo.yml'
|
48
|
+
config = Configuration.new
|
49
|
+
expect(config.file_filter).to be_a(Regexp)
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'ignores the environment is set explicitly' do
|
53
|
+
ENV['RESOURCE'] = 'getTodo.yml'
|
54
|
+
config = Configuration.new do |c|
|
55
|
+
c.file_filter = nil
|
56
|
+
end
|
57
|
+
expect(config.file_filter).to be_nil
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe 'service_filter' do
|
62
|
+
|
63
|
+
it 'is nil by default' do
|
64
|
+
config = Configuration.new
|
65
|
+
expect(config.service_filter).to be_nil
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'is implements backward compatibility with the RESOURCE env variable' do
|
69
|
+
ENV['METHOD'] = 'GET'
|
70
|
+
config = Configuration.new
|
71
|
+
expect(config.service_filter).to be_a(Proc)
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'ignores the environment is set explicitly' do
|
75
|
+
ENV['METHOD'] = 'POST'
|
76
|
+
config = Configuration.new do |c|
|
77
|
+
c.service_filter = nil
|
78
|
+
end
|
79
|
+
expect(config.service_filter).to be_nil
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Webspicy
|
4
|
+
class Tester
|
5
|
+
describe Assertions do
|
6
|
+
include Assertions
|
7
|
+
|
8
|
+
public :extract_path
|
9
|
+
|
10
|
+
it 'has an extract_path helper' do
|
11
|
+
target = { foo: "Hello", bar: { foo: "Hello" }, baz: [{ foo: "world" }] }
|
12
|
+
expect(extract_path(target)).to be(target)
|
13
|
+
expect(extract_path(target, nil)).to be(target)
|
14
|
+
expect(extract_path(target, '')).to be(target)
|
15
|
+
expect(extract_path(target, 'foo')).to eql("Hello")
|
16
|
+
expect(extract_path(target, 'bar/foo')).to eql("Hello")
|
17
|
+
expect(extract_path(target, 'baz/0')).to eql({ foo: "world" })
|
18
|
+
expect(extract_path(target, 'baz/0/foo')).to eql("world")
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'has an exists() assertion' do
|
22
|
+
expect(exists nil).to be(false)
|
23
|
+
expect(exists []).to be(true)
|
24
|
+
expect(exists [1]).to be(true)
|
25
|
+
expect(exists({ foo: [] }, 'foo')).to be(true)
|
26
|
+
expect(exists({ foo: {} }, 'foo')).to be(true)
|
27
|
+
expect(exists({ foo: {} }, 'foo/bar')).to be(false)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'has an notExists() assertion' do
|
31
|
+
expect(notExists nil).to be(true)
|
32
|
+
expect(notExists []).to be(false)
|
33
|
+
expect(notExists [1]).to be(false)
|
34
|
+
expect(notExists({ foo: [] }, 'foo')).to be(false)
|
35
|
+
expect(notExists({ foo: {} }, 'foo')).to be(false)
|
36
|
+
expect(notExists({ foo: {} }, 'foo/bar')).to be(true)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'has an empty() assertion' do
|
40
|
+
expect(empty []).to be(true)
|
41
|
+
expect(empty [1]).to be(false)
|
42
|
+
expect(empty({ foo: [] }, 'foo')).to be(true)
|
43
|
+
expect(empty({ foo: [1] }, 'foo')).to be(false)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'has a notEmpty() assertion' do
|
47
|
+
expect(notEmpty []).to be(false)
|
48
|
+
expect(notEmpty [1]).to be(true)
|
49
|
+
expect(notEmpty({ foo: [] }, 'foo')).to be(false)
|
50
|
+
expect(notEmpty({ foo: [1] }, 'foo')).to be(true)
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'has an size() assertion' do
|
54
|
+
expect(size [], 0).to be(true)
|
55
|
+
expect(size [], 1).to be(false)
|
56
|
+
expect(size [12], 1).to be(true)
|
57
|
+
expect(size({ foo: [] }, 'foo', 0)).to be(true)
|
58
|
+
expect(size({ foo: [] }, 'foo', 1)).to be(false)
|
59
|
+
expect(size({ foo: ['bar'] }, 'foo', 1)).to be(true)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'has an idIn assertion' do
|
63
|
+
expect(idIn [{id: 1}, {id: 2}], [1, 2]).to be(true)
|
64
|
+
expect(idIn [{id: 1}, {id: 2}], [2, 1]).to be(true)
|
65
|
+
expect(idIn [{id: 1}, {id: 2}], [1, 3]).to be(false)
|
66
|
+
expect(idIn [{id: 1}, {id: 2}], [1]).to be(false)
|
67
|
+
expect(idIn({ foo: [{id: 1}, {id: 2}] }, 'foo', [1, 2])).to be(true)
|
68
|
+
|
69
|
+
expect(idIn({id: 1}, [1])).to be(true)
|
70
|
+
expect(idIn({id: 1}, [2])).to be(false)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'has an idNotIn assertion' do
|
74
|
+
expect(idNotIn [{id: 1}, {id: 2}], [3]).to be(true)
|
75
|
+
expect(idNotIn [{id: 1}, {id: 2}], [3, 4]).to be(true)
|
76
|
+
expect(idNotIn [{id: 1}, {id: 2}], [1]).to be(false)
|
77
|
+
expect(idNotIn({ foo: [{id: 1}, {id: 2}] }, 'foo', [1])).to be(false)
|
78
|
+
expect(idNotIn({ foo: [{id: 1}, {id: 2}] }, 'foo', [3])).to be(true)
|
79
|
+
|
80
|
+
expect(idNotIn({id: 1}, [3])).to be(true)
|
81
|
+
expect(idNotIn({id: 1}, [1])).to be(false)
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'has an idFD assertion' do
|
85
|
+
target = { foo: [
|
86
|
+
{ id: 1, bar: "bar" },
|
87
|
+
{ id: 2, bar: "baz" }
|
88
|
+
] }
|
89
|
+
expect(idFD(target, 'foo', 1, bar: "bar")).to be(true)
|
90
|
+
expect(idFD(target, 'foo', 1, bar: "baz")).to be(false)
|
91
|
+
expect(idFD(target, 'foo', 1, baz: "boz")).to be(false)
|
92
|
+
|
93
|
+
target = { foo: { id: 1, bar: "bar" } }
|
94
|
+
expect(idFD(target, 'foo', 1, bar: "bar")).to be(true)
|
95
|
+
expect(idFD(target, 'foo', 1, bar: "baz")).to be(false)
|
96
|
+
expect(idFD(target, 'foo', 1, baz: "boz")).to be(false)
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'has an pathFD assertion' do
|
100
|
+
target = { foo: { bar: "baz"} }
|
101
|
+
expect(pathFD(target, 'foo', bar: "baz")).to be(true)
|
102
|
+
expect(pathFD(target, 'foo', bar: "boz")).to be(false)
|
103
|
+
expect(pathFD(target, 'foo', boz: "biz")).to be(false)
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
end # class Tester
|
108
|
+
end # module Webspicy
|