grape-swagger 0.7.2 → 0.8.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 +7 -0
- data/.gitignore +33 -0
- data/.rubocop.yml +36 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +3 -0
- data/CHANGELOG.md +90 -0
- data/CONTRIBUTING.md +126 -0
- data/Gemfile +1 -21
- data/LICENSE.txt +1 -1
- data/README.md +397 -0
- data/RELEASING.md +80 -0
- data/Rakefile +6 -23
- data/UPGRADING.md +47 -0
- data/grape-swagger.gemspec +26 -84
- data/lib/grape-swagger.rb +237 -111
- data/lib/grape-swagger/errors.rb +9 -0
- data/lib/grape-swagger/markdown.rb +23 -0
- data/lib/grape-swagger/markdown/kramdown_adapter.rb +37 -0
- data/lib/grape-swagger/markdown/redcarpet_adapter.rb +89 -0
- data/lib/grape-swagger/version.rb +3 -0
- data/spec/api_description_spec.rb +41 -0
- data/spec/api_global_models_spec.rb +76 -0
- data/spec/api_models_spec.rb +190 -93
- data/spec/default_api_spec.rb +31 -36
- data/spec/form_params_spec.rb +56 -53
- data/spec/grape-swagger_helper_spec.rb +88 -49
- data/spec/grape-swagger_spec.rb +7 -5
- data/spec/hide_api_spec.rb +58 -55
- data/spec/markdown/kramdown_adapter_spec.rb +38 -0
- data/spec/markdown/markdown_spec.rb +27 -0
- data/spec/markdown/redcarpet_adapter_spec.rb +81 -0
- data/spec/namespaced_api_spec.rb +47 -0
- data/spec/non_default_api_spec.rb +372 -222
- data/spec/response_model_spec.rb +80 -0
- data/spec/simple_mounted_api_spec.rb +113 -118
- data/spec/spec_helper.rb +0 -1
- data/spec/version_spec.rb +8 -0
- data/test/api.rb +62 -0
- data/test/config.ru +10 -2
- data/test/splines.png +0 -0
- metadata +145 -91
- data/.rvmrc +0 -48
- data/CHANGELOG.markdown +0 -55
- data/Gemfile.lock +0 -94
- data/README.markdown +0 -168
- data/VERSION +0 -1
- data/test/nested_api.rb +0 -30
@@ -0,0 +1,23 @@
|
|
1
|
+
module GrapeSwagger
|
2
|
+
class Markdown
|
3
|
+
attr_reader :adapter
|
4
|
+
|
5
|
+
###
|
6
|
+
# Initializes the markdown class with an adapter.
|
7
|
+
# The adapter needs to implement the method markdown which will be called by this interface class.
|
8
|
+
# The adapters are responsible of loading the required markdown dependencies and throw errors.
|
9
|
+
###
|
10
|
+
def initialize(adapter)
|
11
|
+
adapter = adapter.new if adapter.is_a?(Class)
|
12
|
+
fail(ArgumentError, "The configured markdown adapter should implement the method #{ :markdown }") unless adapter.respond_to? :markdown
|
13
|
+
@adapter = adapter
|
14
|
+
end
|
15
|
+
|
16
|
+
###
|
17
|
+
# Calls markdown to the configured adapter.
|
18
|
+
###
|
19
|
+
def as_markdown(text)
|
20
|
+
@adapter.markdown(text)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module GrapeSwagger
|
2
|
+
class Markdown
|
3
|
+
class KramdownAdapter
|
4
|
+
attr_reader :options
|
5
|
+
|
6
|
+
###
|
7
|
+
# Initializes the kramdown adapter with options.
|
8
|
+
# See kramdown documentation what options can be passed.
|
9
|
+
# Default it uses Github flavoured markup as input and won't use coderay as converter for syntax highlighting.
|
10
|
+
# config: an hash of configuration options to be passed to the kramdown.
|
11
|
+
# usage:
|
12
|
+
# Add the kramdown gem to your gemfile or run:
|
13
|
+
# $ (sudo) gem install kramdown
|
14
|
+
#
|
15
|
+
# Then pass a new instance of GrapeSwagger::Markdown::KramdownAdapter as markdown option.
|
16
|
+
###
|
17
|
+
def initialize(config = {})
|
18
|
+
require 'kramdown'
|
19
|
+
defaults = {
|
20
|
+
input: 'GFM',
|
21
|
+
enable_coderay: false
|
22
|
+
}
|
23
|
+
@options = defaults.merge(config)
|
24
|
+
rescue LoadError
|
25
|
+
raise GrapeSwagger::Errors::MarkdownDependencyMissingError, 'kramdown'
|
26
|
+
end
|
27
|
+
|
28
|
+
###
|
29
|
+
# marks down the given text to html format.
|
30
|
+
# text: The text to be formatted.
|
31
|
+
###
|
32
|
+
def markdown(text)
|
33
|
+
Kramdown::Document.new(text, @options).to_html
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module GrapeSwagger
|
2
|
+
class Markdown
|
3
|
+
class RedcarpetAdapter
|
4
|
+
module RenderWithoutSyntaxHighlighter
|
5
|
+
require 'cgi'
|
6
|
+
|
7
|
+
def block_code(code, language)
|
8
|
+
language ||= 'text'
|
9
|
+
"<div class=\"code_highlight\"><pre><code class=\"highlight #{language}\">#{CGI.escapeHTML(code)}</code></pre></div>"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_reader :extension_options
|
14
|
+
|
15
|
+
attr_reader :render_options
|
16
|
+
|
17
|
+
###
|
18
|
+
# Initializes the redcarpet adapter with markup options.
|
19
|
+
# See redcarpet documentation what options can be passed.
|
20
|
+
# Default it uses fenced_code_blocks, autolinks and rouge as syntax highlighter.
|
21
|
+
# To configure an highlighter add {highlighter: :value} to the extentions hash.
|
22
|
+
# Currently supported highlighters:
|
23
|
+
# :rouge
|
24
|
+
#
|
25
|
+
# extensions: an hash of configuration options to be passed to markdown.
|
26
|
+
# render_options: an hash of configuration options to be passed to renderer.
|
27
|
+
#
|
28
|
+
# usage:
|
29
|
+
# Add the redcarpet gem to your gemfile or run:
|
30
|
+
# $ (sudo) gem install redcarpet
|
31
|
+
# when you want to have rouge as syntax highlighter add rouge to the gemfile or run:
|
32
|
+
# $ (sudo) gem install rouge
|
33
|
+
#
|
34
|
+
# GrapeSwagger::Markdown::RedcarpetAdapter.new({highlighter: :none},{no_links: true}) # will use no syntax highlighter and won't render links.
|
35
|
+
###
|
36
|
+
def initialize(options = {})
|
37
|
+
require 'redcarpet'
|
38
|
+
extentions_defaults = {
|
39
|
+
fenced_code_blocks: true,
|
40
|
+
autolink: true
|
41
|
+
}
|
42
|
+
render_defaults = { highlighter: :rouge }
|
43
|
+
@extension_options = extentions_defaults.merge(options.fetch(:extensions, {}))
|
44
|
+
@render_options = render_defaults.merge(options.fetch(:render_options, {}))
|
45
|
+
@renderer = new_redcarpet_renderer(@render_options.delete(:highlighter)).new(@render_options)
|
46
|
+
@markdown = Redcarpet::Markdown.new(@renderer, @extension_options)
|
47
|
+
rescue LoadError
|
48
|
+
raise GrapeSwagger::Errors::MarkdownDependencyMissingError, 'redcarpet'
|
49
|
+
end
|
50
|
+
|
51
|
+
###
|
52
|
+
# Marks down the given text to html format.
|
53
|
+
###
|
54
|
+
def markdown(text)
|
55
|
+
@markdown.render(text)
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
###
|
61
|
+
# Creates a new redcarpet renderer based on the highlighter given.
|
62
|
+
#
|
63
|
+
# render_options: options passed to the renderer.
|
64
|
+
#
|
65
|
+
# usage:
|
66
|
+
# new_redcarpet_renderer(:rouge) # uses rouge as highlighter.
|
67
|
+
# new_redcarpet_renderer # no highlight plugin
|
68
|
+
###
|
69
|
+
def new_redcarpet_renderer(syntax_highlighter = nil)
|
70
|
+
case syntax_highlighter
|
71
|
+
when :rouge
|
72
|
+
begin
|
73
|
+
Class.new(Redcarpet::Render::HTML) do
|
74
|
+
require 'rouge'
|
75
|
+
require 'rouge/plugins/redcarpet'
|
76
|
+
include Rouge::Plugins::Redcarpet
|
77
|
+
end
|
78
|
+
rescue LoadError
|
79
|
+
raise GrapeSwagger::Errors::MarkdownDependencyMissingError, 'rouge'
|
80
|
+
end
|
81
|
+
else
|
82
|
+
Class.new(Redcarpet::Render::HTML) do
|
83
|
+
include RenderWithoutSyntaxHighlighter
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'API Description' do
|
4
|
+
context 'with no additional options' do
|
5
|
+
subject do
|
6
|
+
Class.new(Grape::API) do
|
7
|
+
add_swagger_documentation
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'describes the API with defaults' do
|
12
|
+
routes = subject.endpoints.first.routes
|
13
|
+
expect(routes.count).to eq 2
|
14
|
+
expect(routes.first.route_description).to eq 'Swagger compatible API description'
|
15
|
+
expect(routes.first.route_params).to eq({})
|
16
|
+
expect(routes.last.route_description).to eq 'Swagger compatible API description for specific API'
|
17
|
+
expect(routes.last.route_params).to eq('name' => { desc: 'Resource name of mounted API', type: 'string', required: true })
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'with additional options' do
|
22
|
+
subject do
|
23
|
+
Class.new(Grape::API) do
|
24
|
+
add_swagger_documentation \
|
25
|
+
api_documentation: { desc: 'First', params: { x: 1 }, xx: 11 },
|
26
|
+
specific_api_documentation: { desc: 'Second', params: { y: 42 }, yy: 4242 }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'describes the API with defaults' do
|
31
|
+
routes = subject.endpoints.first.routes
|
32
|
+
expect(routes.count).to eq 2
|
33
|
+
expect(routes.first.route_description).to eq 'First'
|
34
|
+
expect(routes.first.route_params).to eq(x: 1)
|
35
|
+
expect(routes.first.route_xx).to eq(11)
|
36
|
+
expect(routes.last.route_description).to eq 'Second'
|
37
|
+
expect(routes.last.route_params).to eq('name' => { desc: 'Resource name of mounted API', type: 'string', required: true }, y: 42)
|
38
|
+
expect(routes.last.route_yy).to eq(4242)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Global Models' do
|
4
|
+
|
5
|
+
before :all do
|
6
|
+
module Entities
|
7
|
+
module Some
|
8
|
+
class Thing < Grape::Entity
|
9
|
+
expose :text, documentation: { type: 'string', desc: 'Content of something.' }
|
10
|
+
end
|
11
|
+
|
12
|
+
class CombinedThing < Grape::Entity
|
13
|
+
expose :text, documentation: { type: 'string', desc: 'Content of something.' }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
subject do
|
20
|
+
Class.new(Grape::API) do
|
21
|
+
desc 'This gets thing.', params: Entities::Some::Thing.documentation
|
22
|
+
get '/thing' do
|
23
|
+
thing = OpenStruct.new text: 'thing'
|
24
|
+
present thing, with: Entities::Some::Thing
|
25
|
+
end
|
26
|
+
|
27
|
+
desc 'This gets combined thing.',
|
28
|
+
params: Entities::Some::CombinedThing.documentation,
|
29
|
+
entity: Entities::Some::CombinedThing
|
30
|
+
get '/combined_thing' do
|
31
|
+
thing = OpenStruct.new text: 'thing'
|
32
|
+
present thing, with: Entities::Some::CombinedThing
|
33
|
+
end
|
34
|
+
|
35
|
+
add_swagger_documentation models: [Entities::Some::Thing]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def app
|
40
|
+
subject
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'includes models specified' do
|
44
|
+
get '/swagger_doc/thing.json'
|
45
|
+
json = JSON.parse(last_response.body)
|
46
|
+
expect(json['models']).to eq(
|
47
|
+
'Some::Thing' => {
|
48
|
+
'id' => 'Some::Thing',
|
49
|
+
'properties' => {
|
50
|
+
'text' => { 'type' => 'string', 'description' => 'Content of something.' }
|
51
|
+
}
|
52
|
+
})
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'uses global models and route endpoint specific entities together' do
|
56
|
+
get '/swagger_doc/combined_thing.json'
|
57
|
+
json = JSON.parse(last_response.body)
|
58
|
+
|
59
|
+
expect(json['models']).to include(
|
60
|
+
'Some::Thing' => {
|
61
|
+
'id' => 'Some::Thing',
|
62
|
+
'properties' => {
|
63
|
+
'text' => { 'type' => 'string', 'description' => 'Content of something.' }
|
64
|
+
}
|
65
|
+
})
|
66
|
+
|
67
|
+
expect(json['models']).to include(
|
68
|
+
'Some::CombinedThing' => {
|
69
|
+
'id' => 'Some::CombinedThing',
|
70
|
+
'properties' => {
|
71
|
+
'text' => { 'type' => 'string', 'description' => 'Content of something.' }
|
72
|
+
}
|
73
|
+
})
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
data/spec/api_models_spec.rb
CHANGED
@@ -1,132 +1,229 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe 'API Models' do
|
4
4
|
|
5
5
|
before :all do
|
6
6
|
module Entities
|
7
7
|
class Something < Grape::Entity
|
8
|
-
expose :text, :
|
8
|
+
expose :text, documentation: { type: 'string', desc: 'Content of something.' }
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module Entities
|
13
|
+
class EnumValues < Grape::Entity
|
14
|
+
expose :gender, documentation: { type: 'string', desc: 'Content of something.', values: %w(Male Female) }
|
15
|
+
expose :number, documentation: { type: 'integer', desc: 'Content of something.', values: proc { [1, 2] } }
|
9
16
|
end
|
10
17
|
end
|
11
18
|
|
12
19
|
module Entities
|
13
20
|
module Some
|
14
21
|
class Thing < Grape::Entity
|
15
|
-
expose :text, :
|
22
|
+
expose :text, documentation: { type: 'string', desc: 'Content of something.' }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
module Entities
|
28
|
+
class ComposedOf < Grape::Entity
|
29
|
+
expose :part_text, documentation: { type: 'string', desc: 'Content of composedof.' }
|
30
|
+
end
|
31
|
+
|
32
|
+
class ComposedOfElse < Grape::Entity
|
33
|
+
def self.entity_name
|
34
|
+
'composed'
|
16
35
|
end
|
36
|
+
expose :part_text, documentation: { type: 'string', desc: 'Content of composedof else.' }
|
37
|
+
end
|
38
|
+
|
39
|
+
class SomeThingElse < Grape::Entity
|
40
|
+
expose :else_text, documentation: { type: 'string', desc: 'Content of something else.' }
|
41
|
+
expose :parts, using: Entities::ComposedOf, documentation: { type: 'ComposedOf',
|
42
|
+
is_array: true,
|
43
|
+
required: true }
|
44
|
+
|
45
|
+
expose :part, using: Entities::ComposedOfElse, documentation: { type: 'composes' }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
module Entities
|
50
|
+
class AliasedThing < Grape::Entity
|
51
|
+
expose :something, as: :post, using: Entities::Something, documentation: { type: 'Something', desc: 'Reference to something.' }
|
17
52
|
end
|
18
53
|
end
|
54
|
+
end
|
19
55
|
|
20
|
-
|
56
|
+
def app
|
57
|
+
Class.new(Grape::API) do
|
21
58
|
format :json
|
22
|
-
desc 'This gets something.',
|
23
|
-
|
24
|
-
}
|
59
|
+
desc 'This gets something.', entity: Entities::Something
|
60
|
+
|
25
61
|
get '/something' do
|
26
62
|
something = OpenStruct.new text: 'something'
|
27
63
|
present something, with: Entities::Something
|
28
64
|
end
|
29
65
|
|
30
|
-
desc 'This gets thing.',
|
31
|
-
|
32
|
-
}
|
33
|
-
get "/thing" do
|
66
|
+
desc 'This gets thing.', entity: Entities::Some::Thing
|
67
|
+
get '/thing' do
|
34
68
|
thing = OpenStruct.new text: 'thing'
|
35
69
|
present thing, with: Entities::Some::Thing
|
36
70
|
end
|
71
|
+
|
72
|
+
desc 'This gets somthing else.', entity: Entities::SomeThingElse
|
73
|
+
get '/somethingelse' do
|
74
|
+
part = OpenStruct.new part_text: 'part thing'
|
75
|
+
thing = OpenStruct.new else_text: 'else thing', parts: [part], part: part
|
76
|
+
|
77
|
+
present thing, with: Entities::SomeThingElse
|
78
|
+
end
|
79
|
+
|
80
|
+
desc 'This tests the enum values in params and documentation.', entity: Entities::EnumValues, params: Entities::EnumValues.documentation
|
81
|
+
get '/enum_description_in_entity' do
|
82
|
+
|
83
|
+
enum_value = OpenStruct.new gender: 'Male', number: 1
|
84
|
+
|
85
|
+
present enum_value, with: Entities::EnumValues
|
86
|
+
end
|
87
|
+
|
88
|
+
desc 'This gets an aliased thing.', entity: Entities::AliasedThing
|
89
|
+
get '/aliasedthing' do
|
90
|
+
something = OpenStruct.new(something: OpenStruct.new(text: 'something'))
|
91
|
+
present something, with: Entities::AliasedThing
|
92
|
+
end
|
93
|
+
|
37
94
|
add_swagger_documentation
|
38
95
|
end
|
39
96
|
end
|
40
97
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
98
|
+
context 'swagger_doc' do
|
99
|
+
subject do
|
100
|
+
get '/swagger_doc'
|
101
|
+
JSON.parse(last_response.body)
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'returns a swagger-compatible doc' do
|
105
|
+
expect(subject).to include(
|
106
|
+
'apiVersion' => '0.1',
|
107
|
+
'swaggerVersion' => '1.2',
|
108
|
+
'info' => {},
|
109
|
+
'produces' => ['application/json']
|
110
|
+
)
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'documents apis' do
|
114
|
+
expect(subject['apis']).to eq [
|
115
|
+
{ 'path' => '/something.{format}', 'description' => 'Operations about somethings' },
|
116
|
+
{ 'path' => '/thing.{format}', 'description' => 'Operations about things' },
|
117
|
+
{ 'path' => '/somethingelse.{format}', 'description' => 'Operations about somethingelses' },
|
118
|
+
{ 'path' => '/enum_description_in_entity.{format}', 'description' => 'Operations about enum_description_in_entities' },
|
119
|
+
{ 'path' => '/aliasedthing.{format}', 'description' => 'Operations about aliasedthings' },
|
120
|
+
{ 'path' => '/swagger_doc.{format}', 'description' => 'Operations about swagger_docs' }
|
56
121
|
]
|
57
|
-
|
122
|
+
end
|
58
123
|
end
|
59
124
|
|
60
|
-
it
|
125
|
+
it 'returns type' do
|
61
126
|
get '/swagger_doc/something.json'
|
62
|
-
JSON.parse(last_response.body)
|
63
|
-
|
64
|
-
"swaggerVersion" => "1.2",
|
65
|
-
"basePath" => "http://example.org",
|
66
|
-
"resourcePath" => "",
|
67
|
-
"apis" => [{
|
68
|
-
"path" => "/something.{format}",
|
69
|
-
"operations" => [{
|
70
|
-
"produces" => [
|
71
|
-
"application/json"
|
72
|
-
],
|
73
|
-
"notes" => "",
|
74
|
-
"type" => "Something",
|
75
|
-
"summary" => "This gets something.",
|
76
|
-
"nickname" => "GET-something---format-",
|
77
|
-
"httpMethod" => "GET",
|
78
|
-
"parameters" => []
|
79
|
-
}]
|
80
|
-
}],
|
81
|
-
"models" => {
|
82
|
-
"Something" => {
|
83
|
-
"id" => "Something",
|
84
|
-
"name" => "Something",
|
85
|
-
"properties" => {
|
86
|
-
"text" => {
|
87
|
-
"type" => "string",
|
88
|
-
"description" => "Content of something."
|
89
|
-
}
|
90
|
-
}
|
91
|
-
}
|
92
|
-
}
|
93
|
-
}
|
127
|
+
result = JSON.parse(last_response.body)
|
128
|
+
expect(result['apis'].first['operations'].first['type']).to eq 'Something'
|
94
129
|
end
|
95
130
|
|
96
|
-
it
|
131
|
+
it 'includes nested type' do
|
97
132
|
get '/swagger_doc/thing.json'
|
98
|
-
JSON.parse(last_response.body)
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
133
|
+
result = JSON.parse(last_response.body)
|
134
|
+
expect(result['apis'].first['operations'].first['type']).to eq 'Some::Thing'
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'includes entities which are only used as composition' do
|
138
|
+
get '/swagger_doc/somethingelse.json'
|
139
|
+
result = JSON.parse(last_response.body)
|
140
|
+
expect(result['apis']).to eq([{
|
141
|
+
'path' => '/somethingelse.{format}',
|
142
|
+
'operations' => [{
|
143
|
+
'notes' => '',
|
144
|
+
'type' => 'SomeThingElse',
|
145
|
+
'summary' => 'This gets somthing else.',
|
146
|
+
'nickname' => 'GET-somethingelse---format-',
|
147
|
+
'method' => 'GET',
|
148
|
+
'parameters' => []
|
149
|
+
}]
|
150
|
+
}])
|
151
|
+
|
152
|
+
expect(result['models']['SomeThingElse']).to include('id' => 'SomeThingElse',
|
153
|
+
'properties' => {
|
154
|
+
'else_text' => {
|
155
|
+
'type' => 'string',
|
156
|
+
'description' => 'Content of something else.'
|
157
|
+
},
|
158
|
+
'parts' => {
|
159
|
+
'type' => 'array',
|
160
|
+
'items' => { '$ref' => 'ComposedOf' }
|
161
|
+
},
|
162
|
+
'part' => { '$ref' => 'composes' }
|
163
|
+
},
|
164
|
+
'required' => ['parts']
|
165
|
+
|
166
|
+
)
|
167
|
+
|
168
|
+
expect(result['models']['ComposedOf']).to include(
|
169
|
+
'id' => 'ComposedOf',
|
170
|
+
'properties' => {
|
171
|
+
'part_text' => {
|
172
|
+
'type' => 'string',
|
173
|
+
'description' => 'Content of composedof.'
|
174
|
+
}
|
175
|
+
}
|
176
|
+
)
|
177
|
+
|
178
|
+
expect(result['models']['composed']).to include(
|
179
|
+
'id' => 'composed',
|
180
|
+
'properties' => {
|
181
|
+
'part_text' => {
|
182
|
+
'type' => 'string',
|
183
|
+
'description' => 'Content of composedof else.'
|
184
|
+
}
|
185
|
+
|
186
|
+
}
|
187
|
+
)
|
130
188
|
end
|
131
189
|
|
190
|
+
it 'includes enum values in params and documentation.' do
|
191
|
+
get '/swagger_doc/enum_description_in_entity.json'
|
192
|
+
result = JSON.parse(last_response.body)
|
193
|
+
expect(result['models']['EnumValues']).to eq(
|
194
|
+
'id' => 'EnumValues',
|
195
|
+
'properties' => {
|
196
|
+
'gender' => { 'type' => 'string', 'description' => 'Content of something.', 'enum' => %w(Male Female) },
|
197
|
+
'number' => { 'type' => 'integer', 'description' => 'Content of something.', 'enum' => [1, 2] }
|
198
|
+
}
|
199
|
+
)
|
200
|
+
|
201
|
+
expect(result['apis'][0]['operations'][0]).to include(
|
202
|
+
'parameters' =>
|
203
|
+
[
|
204
|
+
{ 'paramType' => 'query', 'name' => 'gender', 'description' => 'Content of something.', 'type' => 'string', 'required' => false, 'allowMultiple' => false, 'enum' => %w(Male Female) },
|
205
|
+
{ 'paramType' => 'query', 'name' => 'number', 'description' => 'Content of something.', 'type' => 'integer', 'required' => false, 'allowMultiple' => false, 'format' => 'int32', 'enum' => [1, 2] }
|
206
|
+
],
|
207
|
+
'type' => 'EnumValues'
|
208
|
+
)
|
209
|
+
|
210
|
+
end
|
211
|
+
|
212
|
+
it 'includes referenced models in those with aliased references.' do
|
213
|
+
get '/swagger_doc/aliasedthing.json'
|
214
|
+
result = JSON.parse(last_response.body)
|
215
|
+
expect(result['models']['AliasedThing']).to eq(
|
216
|
+
'id' => 'AliasedThing',
|
217
|
+
'properties' => {
|
218
|
+
'post' => { '$ref' => 'Something', 'description' => 'Reference to something.' }
|
219
|
+
}
|
220
|
+
)
|
221
|
+
|
222
|
+
expect(result['models']['Something']).to eq(
|
223
|
+
'id' => 'Something',
|
224
|
+
'properties' => {
|
225
|
+
'text' => { 'type' => 'string', 'description' => 'Content of something.' }
|
226
|
+
}
|
227
|
+
)
|
228
|
+
end
|
132
229
|
end
|