rspec_api_documentation 4.9.0 → 6.1.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 +4 -4
- data/lib/rspec_api_documentation/api_documentation.rb +2 -0
- data/lib/rspec_api_documentation/client_base.rb +8 -8
- data/lib/rspec_api_documentation/configuration.rb +12 -1
- data/lib/rspec_api_documentation/curl.rb +7 -2
- data/lib/rspec_api_documentation/dsl/endpoint/params.rb +19 -3
- data/lib/rspec_api_documentation/dsl/endpoint/set_param.rb +18 -5
- data/lib/rspec_api_documentation/dsl/endpoint.rb +44 -2
- data/lib/rspec_api_documentation/dsl/resource.rb +48 -1
- data/lib/rspec_api_documentation/dsl.rb +1 -1
- data/lib/rspec_api_documentation/example.rb +4 -0
- data/lib/rspec_api_documentation/open_api/contact.rb +9 -0
- data/lib/rspec_api_documentation/open_api/example.rb +7 -0
- data/lib/rspec_api_documentation/open_api/header.rb +12 -0
- data/lib/rspec_api_documentation/open_api/headers.rb +7 -0
- data/lib/rspec_api_documentation/open_api/helper.rb +29 -0
- data/lib/rspec_api_documentation/open_api/info.rb +12 -0
- data/lib/rspec_api_documentation/open_api/license.rb +8 -0
- data/lib/rspec_api_documentation/open_api/node.rb +112 -0
- data/lib/rspec_api_documentation/open_api/operation.rb +18 -0
- data/lib/rspec_api_documentation/open_api/parameter.rb +33 -0
- data/lib/rspec_api_documentation/open_api/path.rb +13 -0
- data/lib/rspec_api_documentation/open_api/paths.rb +7 -0
- data/lib/rspec_api_documentation/open_api/response.rb +10 -0
- data/lib/rspec_api_documentation/open_api/responses.rb +9 -0
- data/lib/rspec_api_documentation/open_api/root.rb +21 -0
- data/lib/rspec_api_documentation/open_api/schema.rb +15 -0
- data/lib/rspec_api_documentation/open_api/security_definitions.rb +7 -0
- data/lib/rspec_api_documentation/open_api/security_schema.rb +14 -0
- data/lib/rspec_api_documentation/open_api/tag.rb +9 -0
- data/lib/rspec_api_documentation/railtie.rb +1 -1
- data/lib/rspec_api_documentation/views/api_blueprint_example.rb +116 -0
- data/lib/rspec_api_documentation/views/api_blueprint_index.rb +105 -0
- data/lib/rspec_api_documentation/views/markdown_example.rb +1 -1
- data/lib/rspec_api_documentation/views/markup_example.rb +12 -3
- data/lib/rspec_api_documentation/views/markup_index.rb +2 -4
- data/lib/rspec_api_documentation/views/slate_index.rb +4 -0
- data/lib/rspec_api_documentation/writers/api_blueprint_writer.rb +29 -0
- data/lib/rspec_api_documentation/writers/combined_json_writer.rb +1 -1
- data/lib/rspec_api_documentation/writers/general_markup_writer.rb +20 -7
- data/lib/rspec_api_documentation/writers/json_iodocs_writer.rb +3 -2
- data/lib/rspec_api_documentation/writers/json_writer.rb +10 -6
- data/lib/rspec_api_documentation/writers/markdown_writer.rb +1 -1
- data/lib/rspec_api_documentation/writers/open_api_writer.rb +244 -0
- data/lib/rspec_api_documentation/writers/slate_writer.rb +2 -8
- data/lib/rspec_api_documentation.rb +29 -0
- data/templates/rspec_api_documentation/api_blueprint_index.mustache +80 -0
- data/templates/rspec_api_documentation/html_index.mustache +1 -1
- data/templates/rspec_api_documentation/markdown_example.mustache +4 -3
- data/templates/rspec_api_documentation/markdown_index.mustache +1 -0
- data/templates/rspec_api_documentation/slate_example.mustache +2 -2
- data/templates/rspec_api_documentation/slate_index.mustache +8 -0
- data/templates/rspec_api_documentation/textile_index.mustache +1 -0
- metadata +61 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8e1f18cb4e1bbf1939b21e8a4bdeb0ca17aae8f2
|
4
|
+
data.tar.gz: 98c99830570aad0754d38787cbe528cde8d795f5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 000471a180aa638ee4ac2852410f4202f210d3694118a0aafb0b31a7dde2d61baeb1e40fcc45cdfaf149962479de12390ee88096b338e7a6ad979436468ca83e
|
7
|
+
data.tar.gz: b2bb72596bdbe8896243c14b69a022e8c820e57fba621c45518ccea38b304c08b165d8b2e910644bbf96af256c989157950785654f91dd554b6a6a7042a85782
|
@@ -96,14 +96,14 @@ module RspecApiDocumentation
|
|
96
96
|
end
|
97
97
|
|
98
98
|
def clean_out_uploaded_data(params, request_body)
|
99
|
-
params.each do |
|
100
|
-
if value.
|
101
|
-
if value.has_key?(:tempfile)
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
99
|
+
params.each do |value|
|
100
|
+
if [Hash, Array].member? value.class
|
101
|
+
request_body = if value.respond_to?(:has_key?) && value.has_key?(:tempfile)
|
102
|
+
data = value[:tempfile].read
|
103
|
+
request_body.gsub(data, "[uploaded data]")
|
104
|
+
else
|
105
|
+
clean_out_uploaded_data(value, request_body)
|
106
|
+
end
|
107
107
|
end
|
108
108
|
end
|
109
109
|
request_body
|
@@ -51,6 +51,14 @@ module RspecApiDocumentation
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
+
add_setting :configurations_dir, :default => lambda { |config|
|
55
|
+
if defined?(Rails)
|
56
|
+
Rails.root.join('doc', 'configurations', 'api')
|
57
|
+
else
|
58
|
+
Pathname.new('doc/configurations/api')
|
59
|
+
end
|
60
|
+
}
|
61
|
+
|
54
62
|
add_setting :docs_dir, :default => lambda { |config|
|
55
63
|
if defined?(Rails)
|
56
64
|
Rails.root.join("doc", "api")
|
@@ -75,6 +83,7 @@ module RspecApiDocumentation
|
|
75
83
|
add_setting :curl_host, :default => nil
|
76
84
|
add_setting :keep_source_order, :default => false
|
77
85
|
add_setting :api_name, :default => "API Documentation"
|
86
|
+
add_setting :api_explanation, :default => nil
|
78
87
|
add_setting :io_docs_protocol, :default => "http"
|
79
88
|
add_setting :request_headers_to_include, :default => nil
|
80
89
|
add_setting :response_headers_to_include, :default => nil
|
@@ -109,7 +118,7 @@ module RspecApiDocumentation
|
|
109
118
|
# See RspecApiDocumentation::DSL::Endpoint#do_request
|
110
119
|
add_setting :response_body_formatter, default: Proc.new { |_, _|
|
111
120
|
Proc.new do |content_type, response_body|
|
112
|
-
if content_type =~ /application
|
121
|
+
if content_type =~ /application\/.*json/
|
113
122
|
JSON.pretty_generate(JSON.parse(response_body))
|
114
123
|
else
|
115
124
|
response_body
|
@@ -118,6 +127,8 @@ module RspecApiDocumentation
|
|
118
127
|
}
|
119
128
|
|
120
129
|
def client_method=(new_client_method)
|
130
|
+
return if new_client_method == client_method
|
131
|
+
|
121
132
|
RspecApiDocumentation::DSL::Resource.module_eval <<-RUBY
|
122
133
|
alias :#{new_client_method} #{client_method}
|
123
134
|
undef #{client_method}
|
@@ -16,7 +16,7 @@ module RspecApiDocumentation
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def get
|
19
|
-
"curl \"#{url}#{get_data}\" -X GET #{headers}"
|
19
|
+
"curl -g \"#{url}#{get_data}\" -X GET #{headers}"
|
20
20
|
end
|
21
21
|
|
22
22
|
def head
|
@@ -69,7 +69,12 @@ module RspecApiDocumentation
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def format_full_header(header, value)
|
72
|
-
formatted_value =
|
72
|
+
formatted_value = if value.is_a?(Numeric)
|
73
|
+
value
|
74
|
+
else
|
75
|
+
value ? value.gsub(/"/, "\\\"") : ''
|
76
|
+
end
|
77
|
+
|
73
78
|
"#{format_header(header)}: #{formatted_value}"
|
74
79
|
end
|
75
80
|
|
@@ -13,11 +13,27 @@ module RspecApiDocumentation
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def call
|
16
|
-
|
16
|
+
set_param = -> hash, param {
|
17
17
|
SetParam.new(self, hash, param).call
|
18
|
+
}
|
19
|
+
|
20
|
+
example.metadata.fetch(:parameters, {}).inject({}, &set_param)
|
21
|
+
.deep_merge(
|
22
|
+
example.metadata.fetch(:attributes, {}).inject({}, &set_param)
|
23
|
+
).deep_merge(extra_params)
|
24
|
+
end
|
25
|
+
|
26
|
+
def extended
|
27
|
+
example.metadata.fetch(:parameters, {}).map do |param|
|
28
|
+
p = Marshal.load(Marshal.dump(param))
|
29
|
+
p[:value] = SetParam.new(self, nil, p).value
|
30
|
+
unless p[:value]
|
31
|
+
cur = extra_params
|
32
|
+
[*p[:scope]].each { |scope| cur = cur && (cur[scope.to_sym] || cur[scope.to_s]) }
|
33
|
+
p[:value] = cur && (cur[p[:name].to_s] || cur[p[:name].to_sym])
|
34
|
+
end
|
35
|
+
p
|
18
36
|
end
|
19
|
-
parameters.deep_merge!(extra_params)
|
20
|
-
parameters
|
21
37
|
end
|
22
38
|
|
23
39
|
private
|
@@ -15,6 +15,10 @@ module RspecApiDocumentation
|
|
15
15
|
hash.deep_merge build_param_hash(key_scope || [key])
|
16
16
|
end
|
17
17
|
|
18
|
+
def value
|
19
|
+
example_group.send(method_name) if method_name
|
20
|
+
end
|
21
|
+
|
18
22
|
private
|
19
23
|
|
20
24
|
attr_reader :parent, :hash, :param
|
@@ -36,6 +40,10 @@ module RspecApiDocumentation
|
|
36
40
|
param[:method]
|
37
41
|
end
|
38
42
|
|
43
|
+
def set_value
|
44
|
+
param[:value]
|
45
|
+
end
|
46
|
+
|
39
47
|
def path_name
|
40
48
|
scoped_key || key
|
41
49
|
end
|
@@ -45,15 +53,20 @@ module RspecApiDocumentation
|
|
45
53
|
end
|
46
54
|
|
47
55
|
def method_name
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
56
|
+
if custom_method_name
|
57
|
+
custom_method_name if example_group.respond_to?(custom_method_name)
|
58
|
+
elsif scoped_key && example_group.respond_to?(scoped_key)
|
59
|
+
scoped_key
|
60
|
+
elsif key && example_group.respond_to?(key)
|
61
|
+
key
|
62
|
+
elsif key && set_value
|
63
|
+
key
|
52
64
|
end
|
53
65
|
end
|
54
66
|
|
55
67
|
def build_param_hash(keys)
|
56
|
-
value =
|
68
|
+
value = param[:value] if param.has_key?(:value)
|
69
|
+
value ||= keys[1] ? build_param_hash(keys[1..-1]) : example_group.send(method_name)
|
57
70
|
{ keys[0].to_s => value }
|
58
71
|
end
|
59
72
|
end
|
@@ -9,6 +9,8 @@ module RspecApiDocumentation::DSL
|
|
9
9
|
extend ActiveSupport::Concern
|
10
10
|
include Rack::Test::Utils
|
11
11
|
|
12
|
+
URL_PARAMS_REGEX = /[:\{](\w+)\}?/.freeze
|
13
|
+
|
12
14
|
delegate :response_headers, :response_status, :response_body, :to => :rspec_api_documentation_client
|
13
15
|
|
14
16
|
module ClassMethods
|
@@ -36,6 +38,9 @@ module RspecApiDocumentation::DSL
|
|
36
38
|
params_or_body = nil
|
37
39
|
path_or_query = path
|
38
40
|
|
41
|
+
extended_parameters
|
42
|
+
extract_route_parameters!
|
43
|
+
|
39
44
|
if http_method == :get && !query_string.blank?
|
40
45
|
path_or_query += "?#{query_string}"
|
41
46
|
else
|
@@ -72,6 +77,36 @@ module RspecApiDocumentation::DSL
|
|
72
77
|
example.metadata[:headers][name] = value
|
73
78
|
end
|
74
79
|
|
80
|
+
def authentication(type, value, opts = {})
|
81
|
+
name, new_opts =
|
82
|
+
case type
|
83
|
+
when :basic then ['Authorization', opts.merge(type: type)]
|
84
|
+
when :apiKey then [opts[:name], opts.merge(type: type, in: :header)]
|
85
|
+
else raise 'Not supported type for authentication'
|
86
|
+
end
|
87
|
+
header(name, value)
|
88
|
+
example.metadata[:authentications] ||= {}
|
89
|
+
example.metadata[:authentications][name] = new_opts
|
90
|
+
end
|
91
|
+
|
92
|
+
def extract_route_parameters!
|
93
|
+
example.metadata[:route].gsub(URL_PARAMS_REGEX) do |match|
|
94
|
+
value =
|
95
|
+
if extra_params.keys.include?($1)
|
96
|
+
extra_params[$1]
|
97
|
+
elsif respond_to?($1)
|
98
|
+
send($1)
|
99
|
+
else
|
100
|
+
match
|
101
|
+
end
|
102
|
+
extended_parameters << {name: match[1..-1], value: value, in: :path}
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def extended_parameters
|
107
|
+
example.metadata[:extended_parameters] ||= Params.new(self, example, extra_params).extended
|
108
|
+
end
|
109
|
+
|
75
110
|
def headers
|
76
111
|
return unless example.metadata[:headers]
|
77
112
|
example.metadata[:headers].inject({}) do |hash, (header, value)|
|
@@ -96,8 +131,16 @@ module RspecApiDocumentation::DSL
|
|
96
131
|
rspec_api_documentation_client.status
|
97
132
|
end
|
98
133
|
|
134
|
+
def in_path?(param)
|
135
|
+
path_params.include?(param)
|
136
|
+
end
|
137
|
+
|
138
|
+
def path_params
|
139
|
+
example.metadata[:route].scan(URL_PARAMS_REGEX).flatten
|
140
|
+
end
|
141
|
+
|
99
142
|
def path
|
100
|
-
example.metadata[:route].gsub(
|
143
|
+
example.metadata[:route].gsub(URL_PARAMS_REGEX) do |match|
|
101
144
|
if extra_params.keys.include?($1)
|
102
145
|
delete_extra_param($1)
|
103
146
|
elsif respond_to?($1)
|
@@ -134,6 +177,5 @@ module RspecApiDocumentation::DSL
|
|
134
177
|
def delete_extra_param(key)
|
135
178
|
@extra_params.delete(key.to_sym) || @extra_params.delete(key.to_s)
|
136
179
|
end
|
137
|
-
|
138
180
|
end
|
139
181
|
end
|
@@ -8,7 +8,12 @@ module RspecApiDocumentation::DSL
|
|
8
8
|
define_method method do |*args, &block|
|
9
9
|
options = args.extract_options!
|
10
10
|
options[:method] = method
|
11
|
-
|
11
|
+
if metadata[:route_uri]
|
12
|
+
options[:route] = metadata[:route_uri]
|
13
|
+
options[:action_name] = args.first
|
14
|
+
else
|
15
|
+
options[:route] = args.first
|
16
|
+
end
|
12
17
|
options[:api_doc_dsl] = :endpoint
|
13
18
|
args.push(options)
|
14
19
|
args[0] = "#{method.to_s.upcase} #{args[0]}"
|
@@ -38,10 +43,25 @@ module RspecApiDocumentation::DSL
|
|
38
43
|
context(*args, &block)
|
39
44
|
end
|
40
45
|
|
46
|
+
def route(*args, &block)
|
47
|
+
raise "You must define the route URI" if args[0].blank?
|
48
|
+
raise "You must define the route name" if args[1].blank?
|
49
|
+
options = args.extract_options!
|
50
|
+
options[:route_uri] = args[0].gsub(/\{.*\}/, "")
|
51
|
+
options[:route_optionals] = (optionals = args[0].match(/(\{.*\})/) and optionals[-1])
|
52
|
+
options[:route_name] = args[1]
|
53
|
+
args.push(options)
|
54
|
+
context(*args, &block)
|
55
|
+
end
|
56
|
+
|
41
57
|
def parameter(name, *args)
|
42
58
|
parameters.push(field_specification(name, *args))
|
43
59
|
end
|
44
60
|
|
61
|
+
def attribute(name, *args)
|
62
|
+
attributes.push(field_specification(name, *args))
|
63
|
+
end
|
64
|
+
|
45
65
|
def response_field(name, *args)
|
46
66
|
response_fields.push(field_specification(name, *args))
|
47
67
|
end
|
@@ -50,6 +70,25 @@ module RspecApiDocumentation::DSL
|
|
50
70
|
headers[name] = value
|
51
71
|
end
|
52
72
|
|
73
|
+
def authentication(type, value, opts = {})
|
74
|
+
name, new_opts =
|
75
|
+
case type
|
76
|
+
when :basic then ['Authorization', opts.merge(type: type)]
|
77
|
+
when :apiKey then [opts[:name], opts.merge(type: type, in: :header)]
|
78
|
+
else raise 'Not supported type for authentication'
|
79
|
+
end
|
80
|
+
header(name, value)
|
81
|
+
authentications[name] = new_opts
|
82
|
+
end
|
83
|
+
|
84
|
+
def route_summary(text)
|
85
|
+
safe_metadata(:route_summary, text)
|
86
|
+
end
|
87
|
+
|
88
|
+
def route_description(text)
|
89
|
+
safe_metadata(:route_description, text)
|
90
|
+
end
|
91
|
+
|
53
92
|
def explanation(text)
|
54
93
|
safe_metadata(:resource_explanation, text)
|
55
94
|
end
|
@@ -75,6 +114,10 @@ module RspecApiDocumentation::DSL
|
|
75
114
|
safe_metadata(:parameters, [])
|
76
115
|
end
|
77
116
|
|
117
|
+
def attributes
|
118
|
+
safe_metadata(:attributes, [])
|
119
|
+
end
|
120
|
+
|
78
121
|
def response_fields
|
79
122
|
safe_metadata(:response_fields, [])
|
80
123
|
end
|
@@ -83,6 +126,10 @@ module RspecApiDocumentation::DSL
|
|
83
126
|
safe_metadata(:headers, {})
|
84
127
|
end
|
85
128
|
|
129
|
+
def authentications
|
130
|
+
safe_metadata(:authentications, {})
|
131
|
+
end
|
132
|
+
|
86
133
|
def parameter_keys
|
87
134
|
parameters.map { |param| param[:name] }
|
88
135
|
end
|
@@ -21,7 +21,7 @@ module RspecApiDocumentation
|
|
21
21
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
22
22
|
options[:api_doc_dsl] = :resource
|
23
23
|
options[:resource_name] = args.first.to_s
|
24
|
-
options[:document]
|
24
|
+
options[:document] = :all unless options.key?(:document)
|
25
25
|
args.push(options)
|
26
26
|
describe(*args, &block)
|
27
27
|
end
|
@@ -38,6 +38,10 @@ module RspecApiDocumentation
|
|
38
38
|
respond_to?(:parameters) && parameters.present?
|
39
39
|
end
|
40
40
|
|
41
|
+
def has_attributes?
|
42
|
+
respond_to?(:attributes) && attributes.present?
|
43
|
+
end
|
44
|
+
|
41
45
|
def has_response_fields?
|
42
46
|
respond_to?(:response_fields) && response_fields.present?
|
43
47
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module RspecApiDocumentation
|
2
|
+
module OpenApi
|
3
|
+
class Header < Node
|
4
|
+
add_setting :description, :default => ''
|
5
|
+
add_setting :type, :required => true, :default => lambda { |header|
|
6
|
+
Helper.extract_type(header.public_send('x-example-value'))
|
7
|
+
}
|
8
|
+
add_setting :format
|
9
|
+
add_setting 'x-example-value'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module RspecApiDocumentation
|
2
|
+
module OpenApi
|
3
|
+
module Helper
|
4
|
+
module_function
|
5
|
+
|
6
|
+
def extract_type(value)
|
7
|
+
case value
|
8
|
+
when Rack::Test::UploadedFile then :file
|
9
|
+
when Array then :array
|
10
|
+
when Hash then :object
|
11
|
+
when TrueClass, FalseClass then :boolean
|
12
|
+
when Integer then :integer
|
13
|
+
when Float then :number
|
14
|
+
else :string
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def extract_items(value, opts = {})
|
19
|
+
result = {type: extract_type(value)}
|
20
|
+
if result[:type] == :array
|
21
|
+
result[:items] = extract_items(value[0], opts)
|
22
|
+
else
|
23
|
+
opts.each { |k, v| result[k] = v if v }
|
24
|
+
end
|
25
|
+
result
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module RspecApiDocumentation
|
2
|
+
module OpenApi
|
3
|
+
class Info < Node
|
4
|
+
add_setting :title, :default => 'OpenAPI Specification', :required => true
|
5
|
+
add_setting :description, :default => 'This is a sample server Petstore server.'
|
6
|
+
add_setting :termsOfService, :default => 'http://open-api.io/terms/'
|
7
|
+
add_setting :contact, :default => Contact.new, :schema => Contact
|
8
|
+
add_setting :license, :default => License.new, :schema => License
|
9
|
+
add_setting :version, :default => '1.0.0', :required => true
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
module RspecApiDocumentation
|
2
|
+
module OpenApi
|
3
|
+
class Node
|
4
|
+
# this is used to define class of incoming option attribute
|
5
|
+
# If +false+ then do not create new setting
|
6
|
+
# If +true+ then create new setting with raw passed value
|
7
|
+
# If RspecApiDocumentation::OpenApi::Node then create new setting and wrap it in this class
|
8
|
+
CHILD_CLASS = false
|
9
|
+
|
10
|
+
# This attribute allow us to hide some of children through configuration file
|
11
|
+
attr_accessor :hide
|
12
|
+
|
13
|
+
def self.add_setting(name, opts = {})
|
14
|
+
class_settings << name
|
15
|
+
|
16
|
+
define_method("#{name}_schema") { opts[:schema] || NilClass }
|
17
|
+
define_method("#{name}=") { |value| settings[name] = value }
|
18
|
+
define_method("#{name}") do
|
19
|
+
if settings.has_key?(name)
|
20
|
+
settings[name]
|
21
|
+
elsif !opts[:default].nil?
|
22
|
+
if opts[:default].respond_to?(:call)
|
23
|
+
opts[:default].call(self)
|
24
|
+
else
|
25
|
+
opts[:default]
|
26
|
+
end
|
27
|
+
elsif opts[:required]
|
28
|
+
raise "setting: #{name} required in #{self}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize(opts = {})
|
34
|
+
return unless opts
|
35
|
+
|
36
|
+
opts.each do |name, value|
|
37
|
+
if name.to_s == 'hide'
|
38
|
+
self.hide = value
|
39
|
+
elsif self.class::CHILD_CLASS
|
40
|
+
add_setting name, :value => self.class::CHILD_CLASS === true ? value : self.class::CHILD_CLASS.new(value)
|
41
|
+
elsif setting_exist?(name.to_sym)
|
42
|
+
schema = setting_schema(name)
|
43
|
+
converted =
|
44
|
+
case
|
45
|
+
when schema.is_a?(Array) && schema[0] <= Node then value.map { |v| v.is_a?(schema[0]) ? v : schema[0].new(v) }
|
46
|
+
when schema <= Node then value.is_a?(schema) ? value : schema.new(value)
|
47
|
+
else
|
48
|
+
value
|
49
|
+
end
|
50
|
+
assign_setting(name, converted)
|
51
|
+
else
|
52
|
+
public_send("#{name}=", value) if respond_to?("#{name}=")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def assign_setting(name, value); public_send("#{name}=", value) unless value.nil? end
|
58
|
+
def safe_assign_setting(name, value); assign_setting(name, value) unless settings.has_key?(name) end
|
59
|
+
def setting(name); public_send(name) end
|
60
|
+
def setting_schema(name); public_send("#{name}_schema") end
|
61
|
+
def setting_exist?(name); existing_settings.include?(name) end
|
62
|
+
def existing_settings; self.class.class_settings + instance_settings end
|
63
|
+
|
64
|
+
def add_setting(name, opts = {})
|
65
|
+
return false if setting_exist?(name)
|
66
|
+
|
67
|
+
instance_settings << name
|
68
|
+
|
69
|
+
settings[name] = opts[:value] if opts[:value]
|
70
|
+
|
71
|
+
define_singleton_method("#{name}_schema") { opts[:schema] || NilClass }
|
72
|
+
define_singleton_method("#{name}=") { |value| settings[name] = value }
|
73
|
+
define_singleton_method("#{name}") do
|
74
|
+
if settings.has_key?(name)
|
75
|
+
settings[name]
|
76
|
+
elsif !opts[:default].nil?
|
77
|
+
if opts[:default].respond_to?(:call)
|
78
|
+
opts[:default].call(self)
|
79
|
+
else
|
80
|
+
opts[:default]
|
81
|
+
end
|
82
|
+
elsif opts[:required]
|
83
|
+
raise "setting: #{name} required in #{self}"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def as_json
|
89
|
+
existing_settings.inject({}) do |hash, name|
|
90
|
+
value = setting(name)
|
91
|
+
case
|
92
|
+
when value.is_a?(Node)
|
93
|
+
hash[name] = value.as_json unless value.hide
|
94
|
+
when value.is_a?(Array) && value[0].is_a?(Node)
|
95
|
+
tmp = value.select { |v| !v.hide }.map { |v| v.as_json }
|
96
|
+
hash[name] = tmp unless tmp.empty?
|
97
|
+
else
|
98
|
+
hash[name] = value
|
99
|
+
end unless value.nil?
|
100
|
+
|
101
|
+
hash
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
def settings; @settings ||= {} end
|
108
|
+
def instance_settings; @instance_settings ||= [] end
|
109
|
+
def self.class_settings; @class_settings ||= [] end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module RspecApiDocumentation
|
2
|
+
module OpenApi
|
3
|
+
class Operation < Node
|
4
|
+
add_setting :tags, :default => []
|
5
|
+
add_setting :summary
|
6
|
+
add_setting :description, :default => ''
|
7
|
+
add_setting :externalDocs
|
8
|
+
add_setting :operationId
|
9
|
+
add_setting :consumes
|
10
|
+
add_setting :produces
|
11
|
+
add_setting :parameters, :default => [], :schema => [Parameter]
|
12
|
+
add_setting :responses, :required => true, :schema => Responses
|
13
|
+
add_setting :schemes
|
14
|
+
add_setting :deprecated, :default => false
|
15
|
+
add_setting :security
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module RspecApiDocumentation
|
2
|
+
module OpenApi
|
3
|
+
class Parameter < Node
|
4
|
+
# Required to write example values to description of parameter when option `with_example: true` is provided
|
5
|
+
attr_accessor :value
|
6
|
+
attr_accessor :with_example
|
7
|
+
|
8
|
+
add_setting :name, :required => true
|
9
|
+
add_setting :in, :required => true
|
10
|
+
add_setting :description, :default => ''
|
11
|
+
add_setting :required, :default => lambda { |parameter| parameter.in.to_s == 'path' ? true : false }
|
12
|
+
add_setting :schema
|
13
|
+
add_setting :type
|
14
|
+
add_setting :items
|
15
|
+
add_setting :default
|
16
|
+
add_setting :minimum
|
17
|
+
add_setting :maximum
|
18
|
+
add_setting :enum
|
19
|
+
|
20
|
+
def description_with_example
|
21
|
+
str = description_without_example.dup || ''
|
22
|
+
if with_example && value
|
23
|
+
str << "\n" unless str.empty?
|
24
|
+
str << "Eg, `#{value}`"
|
25
|
+
end
|
26
|
+
str
|
27
|
+
end
|
28
|
+
|
29
|
+
alias_method :description_without_example, :description
|
30
|
+
alias_method :description, :description_with_example
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module RspecApiDocumentation
|
2
|
+
module OpenApi
|
3
|
+
class Path < Node
|
4
|
+
add_setting :get, :schema => Operation
|
5
|
+
add_setting :put, :schema => Operation
|
6
|
+
add_setting :post, :schema => Operation
|
7
|
+
add_setting :delete, :schema => Operation
|
8
|
+
add_setting :options, :schema => Operation
|
9
|
+
add_setting :head, :schema => Operation
|
10
|
+
add_setting :patch, :schema => Operation
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module RspecApiDocumentation
|
2
|
+
module OpenApi
|
3
|
+
class Response < Node
|
4
|
+
add_setting :description, :required => true, :default => 'Successful operation'
|
5
|
+
add_setting :schema, :schema => Schema
|
6
|
+
add_setting :headers, :schema => Headers
|
7
|
+
add_setting :examples, :schema => Example
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|