webspicy 0.20.4 → 0.20.5
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 +4 -4
- data/bin/sandr +14 -0
- data/bin/search +2 -0
- data/bin/webspicy +2 -2
- data/lib/finitio/webspicy/shared.fio +10 -0
- data/lib/webspicy.rb +22 -53
- data/lib/webspicy/configuration.rb +2 -0
- data/lib/webspicy/configuration/scope.rb +2 -2
- data/lib/webspicy/configuration/single_url.rb +35 -25
- data/lib/webspicy/configuration/single_yml_file.rb +7 -2
- data/lib/webspicy/specification.rb +0 -55
- data/lib/webspicy/specification/service.rb +1 -5
- data/lib/webspicy/specification/test_case.rb +0 -49
- data/lib/webspicy/support/colorize.rb +1 -1
- data/lib/webspicy/tester.rb +1 -1
- data/lib/webspicy/tester/reporter/documentation.rb +4 -2
- data/lib/webspicy/version.rb +1 -1
- data/lib/webspicy/web.rb +46 -0
- data/lib/webspicy/{formaldoc.fio → web/formaldoc.fio} +5 -13
- data/lib/webspicy/web/specification.rb +68 -0
- data/lib/webspicy/web/specification/file_upload.rb +39 -0
- data/lib/webspicy/web/specification/service.rb +13 -0
- data/lib/webspicy/web/specification/test_case.rb +58 -0
- data/spec/unit/configuration/scope/test_expand_example.rb +11 -5
- data/spec/unit/specification/pre/test_global_request_headers.rb +3 -3
- data/spec/unit/specification/service/test_dress_params.rb +2 -2
- data/spec/unit/test_configuration.rb +1 -0
- data/spec/unit/web/specification/test_instantiate_url.rb +36 -0
- data/spec/unit/web/specification/test_url_placeholders.rb +23 -0
- metadata +21 -16
- data/lib/webspicy/specification/file_upload.rb +0 -37
- data/spec/blackbox/commandline.yml +0 -24
- data/spec/blackbox/fixtures/passing/config.rb +0 -9
- data/spec/blackbox/fixtures/passing/formaldef/get.yml +0 -30
- data/spec/unit/specification/test_instantiate_url.rb +0 -34
- data/spec/unit/specification/test_url_placeholders.rb +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cf642b32d3e6abe3f90e53c047b8e1e973910041133ba4626d9ba7c2cb5ba333
|
4
|
+
data.tar.gz: 95860fd2e93a11f5dcecf7e175371eee6378e073ee60e22ea266c44e69265d19
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8415d763e56aec8f101d7140974e1ce959da7b1b0cc405c81c64976481a49b3042b442779973fe1eac76e20d9283e8aa6abb1c1363021c7c79d8f70fae59b482
|
7
|
+
data.tar.gz: 8bdfbf03a2c792fb1d772ec2260227ec24b0bfc87f4df5bf70e0baf2376818ed580f43e41d6ef1b4c753e5bc3cc620dcae1479501baea2a5cc84d65ad7370394
|
data/bin/sandr
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'path'
|
3
|
+
|
4
|
+
def sandr(file)
|
5
|
+
file.write file.read.gsub(ARGV[0], ARGV[1])
|
6
|
+
end
|
7
|
+
|
8
|
+
Path.dir.parent.glob("lib/**/*.rb") do |file|
|
9
|
+
sandr(file)
|
10
|
+
end
|
11
|
+
|
12
|
+
Path.dir.parent.glob("spec/**/*.rb") do |file|
|
13
|
+
sandr(file)
|
14
|
+
end
|
data/bin/search
ADDED
data/bin/webspicy
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
#/
|
3
3
|
#/ Document & test web services as black-box operations.
|
4
|
-
#/ (c) Enspirit SRL. Distributed under MIT licence.
|
4
|
+
#/ Webspicy vVERSION, (c) Enspirit SRL. Distributed under MIT licence.
|
5
5
|
#/
|
6
6
|
#/ Usage: webspicy [options] URL # run default test againt url
|
7
7
|
#/ Usage: webspicy [options] path/to/config.rb # run whole test suite
|
@@ -28,7 +28,7 @@ require 'optparse'
|
|
28
28
|
|
29
29
|
def showhelp
|
30
30
|
file = __FILE__
|
31
|
-
exec "grep ^#/<'#{file}'|cut -c4
|
31
|
+
exec "grep ^#/<'#{file}'|cut -c4-|sed s/VERSION/#{Webspicy::VERSION}/g"
|
32
32
|
end
|
33
33
|
|
34
34
|
ARGV.options do |opts|
|
data/lib/webspicy.rb
CHANGED
@@ -7,7 +7,7 @@ require 'ostruct'
|
|
7
7
|
require 'yaml'
|
8
8
|
require 'rack/test'
|
9
9
|
require 'mustermann'
|
10
|
-
require '
|
10
|
+
require 'paint'
|
11
11
|
require 'securerandom'
|
12
12
|
require 'forwardable'
|
13
13
|
module Webspicy
|
@@ -21,22 +21,10 @@ module Webspicy
|
|
21
21
|
require 'webspicy/specification'
|
22
22
|
require 'webspicy/configuration'
|
23
23
|
require 'webspicy/tester'
|
24
|
-
require 'webspicy/web'
|
25
24
|
|
26
25
|
class Error < StandardError; end
|
27
26
|
class TimeoutError < Error; end
|
28
27
|
|
29
|
-
###
|
30
|
-
### Backward compatibility
|
31
|
-
###
|
32
|
-
Client = Tester::Client
|
33
|
-
HttpClient = Web::HttpClient
|
34
|
-
RackTestClient = Web::RackTestClient
|
35
|
-
Resource = Specification
|
36
|
-
FileUpload = Specification::FileUpload
|
37
|
-
Scope = Configuration::Scope
|
38
|
-
Checker = Tester::FileChecker
|
39
|
-
|
40
28
|
###
|
41
29
|
### About folders
|
42
30
|
###
|
@@ -49,10 +37,11 @@ module Webspicy
|
|
49
37
|
### About formal doc and specifications defined there
|
50
38
|
###
|
51
39
|
Finitio.stdlib_path(Path.dir/"finitio")
|
40
|
+
|
52
41
|
DEFAULT_SYSTEM = Finitio.system(<<~FIO)
|
53
42
|
@import webspicy/scalars
|
54
43
|
FIO
|
55
|
-
|
44
|
+
|
56
45
|
|
57
46
|
###
|
58
47
|
### Exceptions that we let pass during testing
|
@@ -66,45 +55,6 @@ module Webspicy
|
|
66
55
|
end
|
67
56
|
module_function :default_scope
|
68
57
|
|
69
|
-
def specification(raw, file = nil, scope = default_scope)
|
70
|
-
raw = YAML.load(raw) if raw.is_a?(String)
|
71
|
-
with_scope(scope) do
|
72
|
-
r = FORMALDOC["Specification"].dress(raw)
|
73
|
-
r.config = scope.config
|
74
|
-
r.located_at!(file) if file
|
75
|
-
r
|
76
|
-
end
|
77
|
-
rescue Finitio::Error => ex
|
78
|
-
handle_finitio_error(ex, scope)
|
79
|
-
end
|
80
|
-
module_function :specification
|
81
|
-
|
82
|
-
def service(raw, scope = default_scope)
|
83
|
-
with_scope(scope) do
|
84
|
-
FORMALDOC["Service"].dress(raw)
|
85
|
-
end
|
86
|
-
rescue Finitio::Error => ex
|
87
|
-
handle_finitio_error(ex)
|
88
|
-
end
|
89
|
-
module_function :service
|
90
|
-
|
91
|
-
def test_case(raw, scope = default_scope)
|
92
|
-
with_scope(scope) do
|
93
|
-
FORMALDOC["TestCase"].dress(raw)
|
94
|
-
end
|
95
|
-
rescue Finitio::Error => ex
|
96
|
-
handle_finitio_error(ex)
|
97
|
-
end
|
98
|
-
module_function :test_case
|
99
|
-
|
100
|
-
def handle_finitio_error(ex, scope)
|
101
|
-
# msg = "#{ex.message}:\n #{ex.root_cause.message}"
|
102
|
-
# msg = Support::Colorize.colorize_error(msg, scope.config)
|
103
|
-
# fatal(msg)
|
104
|
-
raise
|
105
|
-
end
|
106
|
-
module_function :handle_finitio_error
|
107
|
-
|
108
58
|
#
|
109
59
|
# Yields the block after having installed `scope` globally.
|
110
60
|
#
|
@@ -185,4 +135,23 @@ module Webspicy
|
|
185
135
|
end
|
186
136
|
module_function :fatal
|
187
137
|
|
138
|
+
require 'webspicy/web'
|
139
|
+
|
140
|
+
###
|
141
|
+
### Backward compatibility
|
142
|
+
###
|
143
|
+
Client = Tester::Client
|
144
|
+
HttpClient = Web::HttpClient
|
145
|
+
RackTestClient = Web::RackTestClient
|
146
|
+
Resource = Specification
|
147
|
+
FileUpload = Web::Specification::FileUpload
|
148
|
+
Scope = Configuration::Scope
|
149
|
+
Checker = Tester::FileChecker
|
150
|
+
|
151
|
+
[:specification, :service, :test_case].each do |meth|
|
152
|
+
define_method(meth) do |*args, &bl|
|
153
|
+
Webspicy::Web.send(meth, *args, &bl)
|
154
|
+
end
|
155
|
+
module_function(meth)
|
156
|
+
end
|
188
157
|
end
|
@@ -39,6 +39,7 @@ module Webspicy
|
|
39
39
|
:success => :green
|
40
40
|
}
|
41
41
|
@colorize = true
|
42
|
+
@factory = Webspicy::Web
|
42
43
|
@scope_factory = ->(config){ Scope.new(config) }
|
43
44
|
@client = Web::HttpClient
|
44
45
|
@reporter = default_reporter
|
@@ -109,6 +110,7 @@ module Webspicy
|
|
109
110
|
end
|
110
111
|
end
|
111
112
|
|
113
|
+
attr_accessor :factory
|
112
114
|
attr_accessor :scope_factory
|
113
115
|
|
114
116
|
def factor_scope
|
@@ -35,7 +35,7 @@ module Webspicy
|
|
35
35
|
def each_specification(apply_filter = true, &bl)
|
36
36
|
return enum_for(:each_specification, apply_filter) unless block_given?
|
37
37
|
each_specification_file(apply_filter) do |file, folder|
|
38
|
-
yield
|
38
|
+
yield config.factory.specification(file.load, file, self)
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
@@ -138,7 +138,7 @@ module Webspicy
|
|
138
138
|
return example unless service.default_example
|
139
139
|
h1 = service.default_example.to_info
|
140
140
|
h2 = example.to_info
|
141
|
-
ex =
|
141
|
+
ex = config.factory.test_case(merge_maps(h1, h2), self)
|
142
142
|
ex.bind(service, example.counterexample?)
|
143
143
|
end
|
144
144
|
|
@@ -10,37 +10,47 @@ module Webspicy
|
|
10
10
|
end
|
11
11
|
attr_reader :url
|
12
12
|
|
13
|
-
def
|
13
|
+
def each_specification_file(*args, &bl)
|
14
|
+
return enum_for(:each_specification_file) unless block_given?
|
15
|
+
yield Path.tempfile(["specification",".yml"]).tap{|f|
|
16
|
+
f.write(specification_src)
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
def each_specification(*args, &bl)
|
14
21
|
return enum_for(:each_specification) unless block_given?
|
15
|
-
|
22
|
+
yield config.factory.specification(specification_src, nil, self)
|
23
|
+
end
|
24
|
+
|
25
|
+
def specification_src
|
26
|
+
<<~YML.tap{|s| Webspicy.debug(s) }
|
16
27
|
---
|
17
|
-
|
18
|
-
|
28
|
+
description: |-
|
29
|
+
Getting #{url}
|
30
|
+
|
19
31
|
url: |-
|
20
32
|
#{url}
|
21
33
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
34
|
+
method: |-
|
35
|
+
GET
|
36
|
+
|
37
|
+
input_schema: |-
|
38
|
+
Any
|
39
|
+
|
40
|
+
output_schema: |-
|
41
|
+
Any
|
42
|
+
|
43
|
+
error_schema: |-
|
44
|
+
Any
|
45
|
+
|
46
|
+
examples:
|
47
|
+
|
48
|
+
- description: |-
|
49
|
+
it returns a 200
|
50
|
+
params: {}
|
51
|
+
expected:
|
52
|
+
status: 200
|
41
53
|
YML
|
42
|
-
Webspicy.debug(spec)
|
43
|
-
yield Webspicy.specification(spec, nil, self)
|
44
54
|
end
|
45
55
|
|
46
56
|
end # class SingleUrlScope
|
@@ -10,9 +10,14 @@ module Webspicy
|
|
10
10
|
end
|
11
11
|
attr_reader :file
|
12
12
|
|
13
|
-
def
|
13
|
+
def each_specification_file(*args, &bl)
|
14
|
+
return enum_for(:each_specification_file) unless block_given?
|
15
|
+
yield(file)
|
16
|
+
end
|
17
|
+
|
18
|
+
def each_specification(*args, &bl)
|
14
19
|
return enum_for(:each_specification) unless block_given?
|
15
|
-
yield
|
20
|
+
yield config.factory.specification(file.read, nil, self)
|
16
21
|
end
|
17
22
|
|
18
23
|
end # class SingleYmlFileScope
|
@@ -10,21 +10,6 @@ module Webspicy
|
|
10
10
|
attr_accessor :config
|
11
11
|
attr_reader :location
|
12
12
|
|
13
|
-
def self.info(raw)
|
14
|
-
new(raw)
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.singleservice(raw)
|
18
|
-
converted = {
|
19
|
-
name: raw[:name] || "Unamed specification",
|
20
|
-
url: raw[:url],
|
21
|
-
services: [
|
22
|
-
Webspicy.service(raw.reject{|k| k==:url or k==:name }, Webspicy.current_scope)
|
23
|
-
]
|
24
|
-
}
|
25
|
-
info(converted)
|
26
|
-
end
|
27
|
-
|
28
13
|
def located_at!(location)
|
29
14
|
@location = Path(location)
|
30
15
|
end
|
@@ -39,51 +24,12 @@ module Webspicy
|
|
39
24
|
@raw[:name]
|
40
25
|
end
|
41
26
|
|
42
|
-
def url
|
43
|
-
@raw[:url]
|
44
|
-
end
|
45
|
-
|
46
|
-
def url_pattern
|
47
|
-
@url_pattern ||= Mustermann.new(url, type: :template)
|
48
|
-
end
|
49
|
-
|
50
27
|
def services
|
51
28
|
@raw[:services] || []
|
52
29
|
end
|
53
30
|
|
54
|
-
def url_placeholders
|
55
|
-
url.scan(/\{([a-zA-Z]+(\.[a-zA-Z]+)*)\}/).map{|x| x.first }
|
56
|
-
end
|
57
|
-
|
58
|
-
def instantiate_url(params)
|
59
|
-
url, rest = self.url, params.dup
|
60
|
-
url_placeholders.each do |placeholder|
|
61
|
-
value, rest = extract_placeholder_value(rest, placeholder)
|
62
|
-
url = url.gsub("{#{placeholder}}", value.to_s)
|
63
|
-
end
|
64
|
-
[ url, rest ]
|
65
|
-
end
|
66
|
-
|
67
|
-
def to_singleservice
|
68
|
-
raise NotImplementedError
|
69
|
-
end
|
70
|
-
|
71
31
|
private
|
72
32
|
|
73
|
-
def extract_placeholder_value(params, placeholder, split = nil)
|
74
|
-
return extract_placeholder_value(params, placeholder, placeholder.split(".")) unless split
|
75
|
-
|
76
|
-
key = [ split.first, split.first.to_sym ].find{|k| params.has_key?(k) }
|
77
|
-
raise "Missing URL parameter `#{placeholder}`" unless key
|
78
|
-
|
79
|
-
if split.size == 1
|
80
|
-
[ params[key], params.dup.delete_if{|k| k == key } ]
|
81
|
-
else
|
82
|
-
value, rest = extract_placeholder_value(params[key], placeholder, split[1..-1])
|
83
|
-
[ value, params.merge(key => rest) ]
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
33
|
def bind_services
|
88
34
|
services.each do |s|
|
89
35
|
s.specification = self
|
@@ -99,4 +45,3 @@ require_relative 'specification/post'
|
|
99
45
|
require_relative 'specification/err'
|
100
46
|
require_relative 'specification/oldies'
|
101
47
|
require_relative 'specification/test_case'
|
102
|
-
require_relative 'specification/file_upload'
|
@@ -21,10 +21,6 @@ module Webspicy
|
|
21
21
|
specification.config
|
22
22
|
end
|
23
23
|
|
24
|
-
def method
|
25
|
-
@raw[:method]
|
26
|
-
end
|
27
|
-
|
28
24
|
def description
|
29
25
|
@raw[:description]
|
30
26
|
end
|
@@ -68,7 +64,7 @@ module Webspicy
|
|
68
64
|
def generated_counterexamples
|
69
65
|
preconditions.map{|pre|
|
70
66
|
pre.counterexamples(self).map{|tc|
|
71
|
-
tc =
|
67
|
+
tc = config.factory.test_case(tc, Webspicy.current_scope)
|
72
68
|
tc.bind(self, true)
|
73
69
|
}
|
74
70
|
}.flatten
|
@@ -43,10 +43,6 @@ module Webspicy
|
|
43
43
|
@raw[:seeds]
|
44
44
|
end
|
45
45
|
|
46
|
-
def headers
|
47
|
-
@raw[:headers] ||= {}
|
48
|
-
end
|
49
|
-
|
50
46
|
def metadata
|
51
47
|
@raw[:metadata] ||= {}
|
52
48
|
end
|
@@ -55,47 +51,10 @@ module Webspicy
|
|
55
51
|
@raw[:tags] ||= []
|
56
52
|
end
|
57
53
|
|
58
|
-
def dress_params
|
59
|
-
@raw.fetch(:dress_params){ true }
|
60
|
-
end
|
61
|
-
alias :dress_params? :dress_params
|
62
|
-
|
63
|
-
def params
|
64
|
-
@raw[:params] || {}
|
65
|
-
end
|
66
|
-
|
67
|
-
def body
|
68
|
-
@raw[:body]
|
69
|
-
end
|
70
|
-
|
71
|
-
def file_upload
|
72
|
-
@raw[:file_upload]
|
73
|
-
end
|
74
|
-
|
75
|
-
def located_file_upload
|
76
|
-
file_upload ? file_upload.locate(specification) : nil
|
77
|
-
end
|
78
|
-
|
79
54
|
def expected
|
80
55
|
@raw[:expected] || {}
|
81
56
|
end
|
82
57
|
|
83
|
-
def expected_content_type
|
84
|
-
expected[:content_type]
|
85
|
-
end
|
86
|
-
|
87
|
-
def expected_status
|
88
|
-
expected[:status]
|
89
|
-
end
|
90
|
-
|
91
|
-
def is_expected_status?(status)
|
92
|
-
expected_status === status
|
93
|
-
end
|
94
|
-
|
95
|
-
def has_expected_status?
|
96
|
-
not expected[:status].nil?
|
97
|
-
end
|
98
|
-
|
99
58
|
def expected_error
|
100
59
|
expected[:error]
|
101
60
|
end
|
@@ -104,14 +63,6 @@ module Webspicy
|
|
104
63
|
!expected_error.nil?
|
105
64
|
end
|
106
65
|
|
107
|
-
def expected_headers
|
108
|
-
expected[:headers] || {}
|
109
|
-
end
|
110
|
-
|
111
|
-
def has_expected_headers?
|
112
|
-
!expected_headers.empty?
|
113
|
-
end
|
114
|
-
|
115
66
|
def assert
|
116
67
|
@raw[:assert] || []
|
117
68
|
end
|
data/lib/webspicy/tester.rb
CHANGED
@@ -98,7 +98,7 @@ module Webspicy
|
|
98
98
|
def load_specification(spec_file)
|
99
99
|
@spec_file = spec_file
|
100
100
|
reporter.before_spec_file
|
101
|
-
|
101
|
+
config.factory.specification(spec_file.load, spec_file, scope)
|
102
102
|
rescue *PASSTHROUGH_EXCEPTIONS
|
103
103
|
raise
|
104
104
|
rescue Exception => e
|
@@ -7,8 +7,10 @@ module Webspicy
|
|
7
7
|
INDENT = " ".freeze
|
8
8
|
|
9
9
|
def spec_file_line(spec_file)
|
10
|
-
|
11
|
-
|
10
|
+
path = Path(spec_file).expand_path
|
11
|
+
path = path.relative_to(config.folder)
|
12
|
+
path = spec_file if path.to_s.start_with?(".")
|
13
|
+
colorize_section(">> #{path}", config)
|
12
14
|
end
|
13
15
|
|
14
16
|
def spec_file_error_line(spec_file, ex)
|
data/lib/webspicy/version.rb
CHANGED
data/lib/webspicy/web.rb
CHANGED
@@ -1,3 +1,49 @@
|
|
1
|
+
module Webspicy
|
2
|
+
module Web
|
3
|
+
|
4
|
+
require_relative 'web/specification'
|
5
|
+
|
6
|
+
FORMALDOC = Finitio.system(Path.dir/("web/formaldoc.fio"))
|
7
|
+
|
8
|
+
def specification(raw, file = nil, scope = Webspicy.default_scope)
|
9
|
+
raw = YAML.load(raw) if raw.is_a?(String)
|
10
|
+
Webspicy.with_scope(scope) do
|
11
|
+
r = FORMALDOC["Specification"].dress(raw)
|
12
|
+
r.config = scope.config
|
13
|
+
r.located_at!(file) if file
|
14
|
+
r
|
15
|
+
end
|
16
|
+
rescue Finitio::Error => ex
|
17
|
+
handle_finitio_error(ex)
|
18
|
+
end
|
19
|
+
module_function :specification
|
20
|
+
|
21
|
+
def service(raw, scope = Webspicy.default_scope)
|
22
|
+
Webspicy.with_scope(scope) do
|
23
|
+
FORMALDOC["Service"].dress(raw)
|
24
|
+
end
|
25
|
+
rescue Finitio::Error => ex
|
26
|
+
handle_finitio_error(ex)
|
27
|
+
end
|
28
|
+
module_function :service
|
29
|
+
|
30
|
+
def test_case(raw, scope = Webspicy.default_scope)
|
31
|
+
Webspicy.with_scope(scope) do
|
32
|
+
FORMALDOC["TestCase"].dress(raw)
|
33
|
+
end
|
34
|
+
rescue Finitio::Error => ex
|
35
|
+
handle_finitio_error(ex)
|
36
|
+
end
|
37
|
+
module_function :test_case
|
38
|
+
|
39
|
+
def handle_finitio_error(ex)
|
40
|
+
puts ex.root_cause.message
|
41
|
+
raise ex
|
42
|
+
end
|
43
|
+
module_function :handle_finitio_error
|
44
|
+
|
45
|
+
end # module Web
|
46
|
+
end # module Webspicy
|
1
47
|
require_relative 'web/client'
|
2
48
|
require_relative 'web/invocation'
|
3
49
|
require_relative 'web/mocker'
|
@@ -1,23 +1,17 @@
|
|
1
1
|
@import finitio/data
|
2
|
+
@import webspicy/shared
|
2
3
|
|
3
4
|
Method =
|
4
5
|
String( s | s =~ /^(GET|POST|POST_FORM|PUT|DELETE|PATCH|PUT|OPTIONS)$/ )
|
5
6
|
|
6
|
-
Tag = String( s | s.length > 0 )
|
7
|
-
|
8
|
-
Schema =
|
9
|
-
.Finitio::System <fio> String
|
10
|
-
\( s | ::Webspicy.schema(s) )
|
11
|
-
\( s | raise "Unsupported" )
|
12
|
-
|
13
7
|
FileUpload =
|
14
|
-
.Webspicy::FileUpload <info> {
|
8
|
+
.Webspicy::Web::Specification::FileUpload <info> {
|
15
9
|
path : String
|
16
10
|
content_type : String
|
17
11
|
param_name :? String
|
18
12
|
}
|
19
13
|
|
20
|
-
Specification = .Webspicy::Specification
|
14
|
+
Specification = .Webspicy::Web::Specification
|
21
15
|
<info> {
|
22
16
|
name: String
|
23
17
|
url: String
|
@@ -41,7 +35,7 @@ Specification = .Webspicy::Specification
|
|
41
35
|
}
|
42
36
|
|
43
37
|
Service =
|
44
|
-
.Webspicy::Specification::Service <info> {
|
38
|
+
.Webspicy::Web::Specification::Service <info> {
|
45
39
|
method : Method
|
46
40
|
description : String
|
47
41
|
preconditions :? [String]|String
|
@@ -57,7 +51,7 @@ Service =
|
|
57
51
|
}
|
58
52
|
|
59
53
|
TestCase =
|
60
|
-
.Webspicy::Specification::TestCase <info> {
|
54
|
+
.Webspicy::Web::Specification::TestCase <info> {
|
61
55
|
description :? String
|
62
56
|
dress_params :? Boolean
|
63
57
|
params :? Params
|
@@ -77,8 +71,6 @@ TestCase =
|
|
77
71
|
tags :? [Tag]
|
78
72
|
}
|
79
73
|
|
80
|
-
Params = .Array|.Hash
|
81
|
-
|
82
74
|
StatusRange = .Webspicy::Support::StatusRange
|
83
75
|
<int> Integer
|
84
76
|
<str> String(s | s =~ /^\dxx$/ )
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Webspicy
|
2
|
+
module Web
|
3
|
+
class Specification < Webspicy::Specification
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def info(raw)
|
7
|
+
new(raw)
|
8
|
+
end
|
9
|
+
|
10
|
+
def singleservice(raw)
|
11
|
+
converted = {
|
12
|
+
name: raw[:name] || "Unamed specification",
|
13
|
+
url: raw[:url],
|
14
|
+
services: [
|
15
|
+
Webspicy::Web.service(raw.reject{|k| k==:url or k==:name }, Webspicy.current_scope)
|
16
|
+
]
|
17
|
+
}
|
18
|
+
info(converted)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def url
|
23
|
+
@raw[:url]
|
24
|
+
end
|
25
|
+
|
26
|
+
def url_pattern
|
27
|
+
@url_pattern ||= Mustermann.new(url, type: :template)
|
28
|
+
end
|
29
|
+
|
30
|
+
def url_placeholders
|
31
|
+
url.scan(/\{([a-zA-Z]+(\.[a-zA-Z]+)*)\}/).map{|x| x.first }
|
32
|
+
end
|
33
|
+
|
34
|
+
def instantiate_url(params)
|
35
|
+
url, rest = self.url, params.dup
|
36
|
+
url_placeholders.each do |placeholder|
|
37
|
+
value, rest = extract_placeholder_value(rest, placeholder)
|
38
|
+
url = url.gsub("{#{placeholder}}", value.to_s)
|
39
|
+
end
|
40
|
+
[ url, rest ]
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_singleservice
|
44
|
+
raise NotImplementedError
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def extract_placeholder_value(params, placeholder, split = nil)
|
50
|
+
return extract_placeholder_value(params, placeholder, placeholder.split(".")) unless split
|
51
|
+
|
52
|
+
key = [ split.first, split.first.to_sym ].find{|k| params.has_key?(k) }
|
53
|
+
raise "Missing URL parameter `#{placeholder}`" unless key
|
54
|
+
|
55
|
+
if split.size == 1
|
56
|
+
[ params[key], params.dup.delete_if{|k| k == key } ]
|
57
|
+
else
|
58
|
+
value, rest = extract_placeholder_value(params[key], placeholder, split[1..-1])
|
59
|
+
[ value, params.merge(key => rest) ]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end # class Specification
|
64
|
+
end # module Web
|
65
|
+
end # module Webspicy
|
66
|
+
require_relative 'specification/service'
|
67
|
+
require_relative 'specification/test_case'
|
68
|
+
require_relative 'specification/file_upload'
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Webspicy
|
2
|
+
module Web
|
3
|
+
class Specification
|
4
|
+
class FileUpload
|
5
|
+
|
6
|
+
def initialize(raw)
|
7
|
+
@path = raw[:path]
|
8
|
+
@content_type = raw[:content_type]
|
9
|
+
@param_name = raw[:param_name] || "file"
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_reader :path, :content_type, :param_name
|
13
|
+
|
14
|
+
def self.info(raw)
|
15
|
+
new(raw)
|
16
|
+
end
|
17
|
+
|
18
|
+
def locate(specification)
|
19
|
+
FileUpload.new({
|
20
|
+
path: specification.locate(path),
|
21
|
+
content_type: content_type
|
22
|
+
})
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_info
|
26
|
+
{ path: path.to_s,
|
27
|
+
content_type: content_type,
|
28
|
+
param_name: param_name }
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_s
|
32
|
+
"FileUpload(#{to_info})"
|
33
|
+
end
|
34
|
+
alias :inspect :to_s
|
35
|
+
|
36
|
+
end # class FileUpload
|
37
|
+
end # class Specification
|
38
|
+
end # module Web
|
39
|
+
end # module Webspicy
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Webspicy
|
2
|
+
module Web
|
3
|
+
class Specification
|
4
|
+
class TestCase < Webspicy::Specification::TestCase
|
5
|
+
|
6
|
+
def headers
|
7
|
+
@raw[:headers] ||= {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def dress_params
|
11
|
+
@raw.fetch(:dress_params){ true }
|
12
|
+
end
|
13
|
+
alias :dress_params? :dress_params
|
14
|
+
|
15
|
+
def params
|
16
|
+
@raw[:params] || {}
|
17
|
+
end
|
18
|
+
|
19
|
+
def body
|
20
|
+
@raw[:body]
|
21
|
+
end
|
22
|
+
|
23
|
+
def file_upload
|
24
|
+
@raw[:file_upload]
|
25
|
+
end
|
26
|
+
|
27
|
+
def located_file_upload
|
28
|
+
file_upload ? file_upload.locate(specification) : nil
|
29
|
+
end
|
30
|
+
|
31
|
+
def expected_content_type
|
32
|
+
expected[:content_type]
|
33
|
+
end
|
34
|
+
|
35
|
+
def expected_status
|
36
|
+
expected[:status]
|
37
|
+
end
|
38
|
+
|
39
|
+
def is_expected_status?(status)
|
40
|
+
expected_status === status
|
41
|
+
end
|
42
|
+
|
43
|
+
def has_expected_status?
|
44
|
+
not expected[:status].nil?
|
45
|
+
end
|
46
|
+
|
47
|
+
def expected_headers
|
48
|
+
expected[:headers] || {}
|
49
|
+
end
|
50
|
+
|
51
|
+
def has_expected_headers?
|
52
|
+
!expected_headers.empty?
|
53
|
+
end
|
54
|
+
|
55
|
+
end # class TestCase
|
56
|
+
end # class Specification
|
57
|
+
end # module Web
|
58
|
+
end # module Webspicy
|
@@ -3,11 +3,17 @@ module Webspicy
|
|
3
3
|
class Configuration
|
4
4
|
describe Scope, "expand_example" do
|
5
5
|
|
6
|
-
|
6
|
+
let(:config){
|
7
|
+
Configuration.new(Path.dir)
|
8
|
+
}
|
9
|
+
|
10
|
+
subject{
|
11
|
+
Scope.new(config).send(:expand_example, service, example)
|
12
|
+
}
|
7
13
|
|
8
14
|
context 'when the service has no default example' do
|
9
15
|
let(:service) {
|
10
|
-
Webspicy.service({
|
16
|
+
Webspicy::Web.service({
|
11
17
|
method: "GET",
|
12
18
|
description: "Test service",
|
13
19
|
preconditions: "Foo",
|
@@ -18,7 +24,7 @@ module Webspicy
|
|
18
24
|
}
|
19
25
|
|
20
26
|
let(:example) {
|
21
|
-
Webspicy.test_case({
|
27
|
+
Webspicy::Web.test_case({
|
22
28
|
description: "Hello world"
|
23
29
|
})
|
24
30
|
}
|
@@ -30,7 +36,7 @@ module Webspicy
|
|
30
36
|
|
31
37
|
context 'when the service has a default example' do
|
32
38
|
let(:service) {
|
33
|
-
Webspicy.service({
|
39
|
+
Webspicy::Web.service({
|
34
40
|
method: "GET",
|
35
41
|
description: "Test service",
|
36
42
|
preconditions: "Foo",
|
@@ -44,7 +50,7 @@ module Webspicy
|
|
44
50
|
}
|
45
51
|
|
46
52
|
let(:example) {
|
47
|
-
Webspicy.test_case({
|
53
|
+
Webspicy::Web.test_case({
|
48
54
|
description: "Hello world",
|
49
55
|
expected: { content_type: "application/json" }
|
50
56
|
})
|
@@ -15,13 +15,13 @@ module Webspicy
|
|
15
15
|
|
16
16
|
describe "instrument" do
|
17
17
|
it 'injects the headers' do
|
18
|
-
tc = TestCase.new({})
|
18
|
+
tc = Web::Specification::TestCase.new({})
|
19
19
|
instrument(tc)
|
20
20
|
expect(tc.headers['Accept']).to eql("application/json")
|
21
21
|
end
|
22
22
|
|
23
23
|
it 'keeps original headers unchanged' do
|
24
|
-
tc = TestCase.new({
|
24
|
+
tc = Web::Specification::TestCase.new({
|
25
25
|
headers: {
|
26
26
|
'Content-Type' => 'text/plain'
|
27
27
|
}
|
@@ -32,7 +32,7 @@ module Webspicy
|
|
32
32
|
end
|
33
33
|
|
34
34
|
it 'has low precedence' do
|
35
|
-
tc = TestCase.new({
|
35
|
+
tc = Web::Specification::TestCase.new({
|
36
36
|
headers: {
|
37
37
|
'Accept' => 'text/plain'
|
38
38
|
}
|
@@ -4,7 +4,7 @@ module Webspicy
|
|
4
4
|
describe Service, "dress_params" do
|
5
5
|
|
6
6
|
it 'symbolizes keys' do
|
7
|
-
service = Webspicy.service({
|
7
|
+
service = Webspicy::Web.service({
|
8
8
|
method: "GET",
|
9
9
|
description: "Test service",
|
10
10
|
preconditions: "Foo",
|
@@ -17,7 +17,7 @@ module Webspicy
|
|
17
17
|
end
|
18
18
|
|
19
19
|
it 'supports an array' do
|
20
|
-
service = Webspicy.service({
|
20
|
+
service = Webspicy::Web.service({
|
21
21
|
method: "GET",
|
22
22
|
description: "Test service",
|
23
23
|
preconditions: "Foo",
|
@@ -36,6 +36,7 @@ module Webspicy
|
|
36
36
|
expect(c).to be_a(Configuration)
|
37
37
|
expect(c.folder).to eq(Path.pwd)
|
38
38
|
expect(c.each_scope.to_a.size).to eql(1)
|
39
|
+
expect(c.each_scope.to_a.first.each_specification_file.to_a.size).to eql(1)
|
39
40
|
expect(c.each_scope.to_a.first.each_specification.to_a.size).to eql(1)
|
40
41
|
end
|
41
42
|
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
module Webspicy
|
3
|
+
module Web
|
4
|
+
describe Specification, "instantiate_url" do
|
5
|
+
|
6
|
+
it 'does nothing when the url has no placeholder' do
|
7
|
+
r = Specification.new(url: "/test/a/url")
|
8
|
+
url, params = r.instantiate_url(foo: "bar")
|
9
|
+
expect(url).to eq("/test/a/url")
|
10
|
+
expect(params).to eq(foo: "bar")
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'instantiates placeholders and strips corresponding params' do
|
14
|
+
r = Specification.new(url: "/test/{foo}/url")
|
15
|
+
url, params = r.instantiate_url(foo: "bar", baz: "coz")
|
16
|
+
expect(url).to eq("/test/bar/url")
|
17
|
+
expect(params).to eq(baz: "coz")
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'instantiates placeholders and strips corresponding params even when multiple' do
|
21
|
+
r = Specification.new(url: "/test/{foo}/url/{bar}")
|
22
|
+
url, params = r.instantiate_url(foo: "bar", bar: "baz", baz: "coz")
|
23
|
+
expect(url).to eq("/test/bar/url/baz")
|
24
|
+
expect(params).to eq(baz: "coz")
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'supports placeholders corresponding to subentities' do
|
28
|
+
r = Specification.new(url: "/test/{foo.id}/url")
|
29
|
+
url, params = r.instantiate_url(foo: {id: "bar"}, baz: "coz")
|
30
|
+
expect(url).to eq("/test/bar/url")
|
31
|
+
expect(params).to eq(foo: {}, baz: "coz")
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
module Webspicy
|
3
|
+
module Web
|
4
|
+
describe Specification, "url_placeholders" do
|
5
|
+
|
6
|
+
it 'returns an empty array on none' do
|
7
|
+
r = Specification.new(url: "/test/a/url")
|
8
|
+
expect(r.url_placeholders).to eq([])
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'returns all placeholders' do
|
12
|
+
r = Specification.new(url: "/test/{foo}/url/{bar}")
|
13
|
+
expect(r.url_placeholders).to eq(["foo", "bar"])
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'returns all placeholders expr' do
|
17
|
+
r = Specification.new(url: "/test/{foo.id}/url/{bar}")
|
18
|
+
expect(r.url_placeholders).to eq(["foo.id", "bar"])
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: webspicy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.20.
|
4
|
+
version: 0.20.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bernard Lambeau
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-03-
|
11
|
+
date: 2021-03-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -171,19 +171,19 @@ dependencies:
|
|
171
171
|
- !ruby/object:Gem::Version
|
172
172
|
version: '0'
|
173
173
|
- !ruby/object:Gem::Dependency
|
174
|
-
name:
|
174
|
+
name: paint
|
175
175
|
requirement: !ruby/object:Gem::Requirement
|
176
176
|
requirements:
|
177
177
|
- - "~>"
|
178
178
|
- !ruby/object:Gem::Version
|
179
|
-
version:
|
179
|
+
version: '2.2'
|
180
180
|
type: :runtime
|
181
181
|
prerelease: false
|
182
182
|
version_requirements: !ruby/object:Gem::Requirement
|
183
183
|
requirements:
|
184
184
|
- - "~>"
|
185
185
|
- !ruby/object:Gem::Version
|
186
|
-
version:
|
186
|
+
version: '2.2'
|
187
187
|
- !ruby/object:Gem::Dependency
|
188
188
|
name: openapi3_parser
|
189
189
|
requirement: !ruby/object:Gem::Requirement
|
@@ -201,6 +201,8 @@ dependencies:
|
|
201
201
|
description: Webspicy helps testing web services as software operation black boxes
|
202
202
|
email: blambeau@gmail.com
|
203
203
|
executables:
|
204
|
+
- sandr
|
205
|
+
- search
|
204
206
|
- webspicy
|
205
207
|
extensions: []
|
206
208
|
extra_rdoc_files: []
|
@@ -208,22 +210,23 @@ files:
|
|
208
210
|
- Gemfile
|
209
211
|
- README.md
|
210
212
|
- Rakefile
|
213
|
+
- bin/sandr
|
214
|
+
- bin/search
|
211
215
|
- bin/webspicy
|
212
216
|
- doc/1-black-box-scene.md
|
213
217
|
- doc/2-black-box-testing.md
|
214
218
|
- doc/3-specification-importance.md
|
215
219
|
- doc/4-sequence-diagram.md
|
216
220
|
- lib/finitio/webspicy/scalars.fio
|
221
|
+
- lib/finitio/webspicy/shared.fio
|
217
222
|
- lib/webspicy.rb
|
218
223
|
- lib/webspicy/configuration.rb
|
219
224
|
- lib/webspicy/configuration/scope.rb
|
220
225
|
- lib/webspicy/configuration/single_url.rb
|
221
226
|
- lib/webspicy/configuration/single_yml_file.rb
|
222
|
-
- lib/webspicy/formaldoc.fio
|
223
227
|
- lib/webspicy/specification.rb
|
224
228
|
- lib/webspicy/specification/condition.rb
|
225
229
|
- lib/webspicy/specification/err.rb
|
226
|
-
- lib/webspicy/specification/file_upload.rb
|
227
230
|
- lib/webspicy/specification/oldies.rb
|
228
231
|
- lib/webspicy/specification/oldies/bridge.rb
|
229
232
|
- lib/webspicy/specification/oldies/errcondition.rb
|
@@ -279,14 +282,16 @@ files:
|
|
279
282
|
- lib/webspicy/web/client/http_client.rb
|
280
283
|
- lib/webspicy/web/client/rack_test_client.rb
|
281
284
|
- lib/webspicy/web/client/support.rb
|
285
|
+
- lib/webspicy/web/formaldoc.fio
|
282
286
|
- lib/webspicy/web/invocation.rb
|
283
287
|
- lib/webspicy/web/mocker.rb
|
284
288
|
- lib/webspicy/web/mocker/config.ru
|
285
289
|
- lib/webspicy/web/openapi.rb
|
286
290
|
- lib/webspicy/web/openapi/generator.rb
|
287
|
-
-
|
288
|
-
-
|
289
|
-
-
|
291
|
+
- lib/webspicy/web/specification.rb
|
292
|
+
- lib/webspicy/web/specification/file_upload.rb
|
293
|
+
- lib/webspicy/web/specification/service.rb
|
294
|
+
- lib/webspicy/web/specification/test_case.rb
|
290
295
|
- spec/spec_helper.rb
|
291
296
|
- spec/unit/configuration/config.rb
|
292
297
|
- spec/unit/configuration/scope/test_each_service.rb
|
@@ -297,8 +302,6 @@ files:
|
|
297
302
|
- spec/unit/specification/service/test_dress_params.rb
|
298
303
|
- spec/unit/specification/test_case/test_mutate.rb
|
299
304
|
- spec/unit/specification/test_condition.rb
|
300
|
-
- spec/unit/specification/test_instantiate_url.rb
|
301
|
-
- spec/unit/specification/test_url_placeholders.rb
|
302
305
|
- spec/unit/support/hooks/test_fire_after_each.rb
|
303
306
|
- spec/unit/support/hooks/test_fire_around.rb
|
304
307
|
- spec/unit/support/hooks/test_fire_before_each.rb
|
@@ -314,13 +317,15 @@ files:
|
|
314
317
|
- spec/unit/tester/test_assertions.rb
|
315
318
|
- spec/unit/web/mocker/test_mocker.rb
|
316
319
|
- spec/unit/web/openapi/test_generator.rb
|
320
|
+
- spec/unit/web/specification/test_instantiate_url.rb
|
321
|
+
- spec/unit/web/specification/test_url_placeholders.rb
|
317
322
|
- tasks/gem.rake
|
318
323
|
- tasks/test.rake
|
319
324
|
homepage: http://github.com/enspirit/webspicy
|
320
325
|
licenses:
|
321
326
|
- MIT
|
322
327
|
metadata: {}
|
323
|
-
post_install_message:
|
328
|
+
post_install_message:
|
324
329
|
rdoc_options: []
|
325
330
|
require_paths:
|
326
331
|
- lib
|
@@ -335,8 +340,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
335
340
|
- !ruby/object:Gem::Version
|
336
341
|
version: '0'
|
337
342
|
requirements: []
|
338
|
-
rubygems_version: 3.1
|
339
|
-
signing_key:
|
343
|
+
rubygems_version: 3.2.1
|
344
|
+
signing_key:
|
340
345
|
specification_version: 4
|
341
346
|
summary: Webspicy helps testing web services as software operation black boxes!
|
342
347
|
test_files: []
|
@@ -1,37 +0,0 @@
|
|
1
|
-
module Webspicy
|
2
|
-
class Specification
|
3
|
-
class FileUpload
|
4
|
-
|
5
|
-
def initialize(raw)
|
6
|
-
@path = raw[:path]
|
7
|
-
@content_type = raw[:content_type]
|
8
|
-
@param_name = raw[:param_name] || "file"
|
9
|
-
end
|
10
|
-
|
11
|
-
attr_reader :path, :content_type, :param_name
|
12
|
-
|
13
|
-
def self.info(raw)
|
14
|
-
new(raw)
|
15
|
-
end
|
16
|
-
|
17
|
-
def locate(specification)
|
18
|
-
FileUpload.new({
|
19
|
-
path: specification.locate(path),
|
20
|
-
content_type: content_type
|
21
|
-
})
|
22
|
-
end
|
23
|
-
|
24
|
-
def to_info
|
25
|
-
{ path: path.to_s,
|
26
|
-
content_type: content_type,
|
27
|
-
param_name: param_name }
|
28
|
-
end
|
29
|
-
|
30
|
-
def to_s
|
31
|
-
"FileUpload(#{to_info})"
|
32
|
-
end
|
33
|
-
alias :inspect :to_s
|
34
|
-
|
35
|
-
end # class FileUpload
|
36
|
-
end # class Specification
|
37
|
-
end # module Webspicy
|
@@ -1,24 +0,0 @@
|
|
1
|
-
---
|
2
|
-
command:
|
3
|
-
webspicy {options} {args}
|
4
|
-
|
5
|
-
examples:
|
6
|
-
|
7
|
-
- description: |-
|
8
|
-
when called on a passing path
|
9
|
-
args:
|
10
|
-
- ./fixtures/passing/config.rb
|
11
|
-
assert:
|
12
|
-
exit_code:
|
13
|
-
0
|
14
|
-
stdout: |-
|
15
|
-
GET /, when requested
|
16
|
-
v It has a 200 response status
|
17
|
-
v It has a `Content-Type: application/json` response header
|
18
|
-
v Its output meets the expected data schema
|
19
|
-
v Assert notEmpty
|
20
|
-
v Assert pathFD('', :hello => "World" )
|
21
|
-
|
22
|
-
|
23
|
-
1 spec file, 1 example, 0 counterexample
|
24
|
-
5 assertions, 0 error, 0 failure
|
@@ -1,30 +0,0 @@
|
|
1
|
-
---
|
2
|
-
url: |-
|
3
|
-
/
|
4
|
-
|
5
|
-
method: |-
|
6
|
-
GET
|
7
|
-
|
8
|
-
description: |-
|
9
|
-
Returns hello world
|
10
|
-
|
11
|
-
input_schema: |-
|
12
|
-
{ }
|
13
|
-
|
14
|
-
output_schema: |-
|
15
|
-
{ hello: String }
|
16
|
-
|
17
|
-
error_schema: |-
|
18
|
-
.
|
19
|
-
|
20
|
-
examples:
|
21
|
-
|
22
|
-
- description: |-
|
23
|
-
when requested
|
24
|
-
params: {}
|
25
|
-
expected:
|
26
|
-
content_type: application/json
|
27
|
-
status: 200
|
28
|
-
assert:
|
29
|
-
- notEmpty
|
30
|
-
- pathFD('', :hello => "World" )
|
@@ -1,34 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
module Webspicy
|
3
|
-
describe Specification, "instantiate_url" do
|
4
|
-
|
5
|
-
it 'does nothing when the url has no placeholder' do
|
6
|
-
r = Specification.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 = Specification.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
|
-
it 'instantiates placeholders and strips corresponding params even when multiple' do
|
20
|
-
r = Specification.new(url: "/test/{foo}/url/{bar}")
|
21
|
-
url, params = r.instantiate_url(foo: "bar", bar: "baz", baz: "coz")
|
22
|
-
expect(url).to eq("/test/bar/url/baz")
|
23
|
-
expect(params).to eq(baz: "coz")
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'supports placeholders corresponding to subentities' do
|
27
|
-
r = Specification.new(url: "/test/{foo.id}/url")
|
28
|
-
url, params = r.instantiate_url(foo: {id: "bar"}, baz: "coz")
|
29
|
-
expect(url).to eq("/test/bar/url")
|
30
|
-
expect(params).to eq(foo: {}, baz: "coz")
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|
34
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
module Webspicy
|
3
|
-
describe Specification, "url_placeholders" do
|
4
|
-
|
5
|
-
it 'returns an empty array on none' do
|
6
|
-
r = Specification.new(url: "/test/a/url")
|
7
|
-
expect(r.url_placeholders).to eq([])
|
8
|
-
end
|
9
|
-
|
10
|
-
it 'returns all placeholders' do
|
11
|
-
r = Specification.new(url: "/test/{foo}/url/{bar}")
|
12
|
-
expect(r.url_placeholders).to eq(["foo", "bar"])
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'returns all placeholders expr' do
|
16
|
-
r = Specification.new(url: "/test/{foo.id}/url/{bar}")
|
17
|
-
expect(r.url_placeholders).to eq(["foo.id", "bar"])
|
18
|
-
end
|
19
|
-
|
20
|
-
end
|
21
|
-
end
|