rspec_api_documentation 4.9.0 → 6.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|