grape-swagger 0.11.0 → 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +8 -1
  3. data/.rubocop.yml +3 -0
  4. data/.rubocop_todo.yml +14 -22
  5. data/.travis.yml +7 -4
  6. data/CHANGELOG.md +53 -26
  7. data/Gemfile +1 -1
  8. data/README.md +414 -327
  9. data/RELEASING.md +3 -4
  10. data/example/api/endpoints.rb +132 -0
  11. data/example/api/entities.rb +18 -0
  12. data/example/config.ru +36 -2
  13. data/example/example_requests.postman_collection +146 -0
  14. data/example/swagger-example.png +0 -0
  15. data/grape-swagger.gemspec +9 -6
  16. data/lib/grape-swagger.rb +69 -99
  17. data/lib/grape-swagger/doc_methods.rb +69 -544
  18. data/lib/grape-swagger/doc_methods/data_type.rb +77 -0
  19. data/lib/grape-swagger/doc_methods/extensions.rb +75 -0
  20. data/lib/grape-swagger/doc_methods/move_params.rb +153 -0
  21. data/lib/grape-swagger/doc_methods/operation_id.rb +27 -0
  22. data/lib/grape-swagger/doc_methods/optional_object.rb +15 -0
  23. data/lib/grape-swagger/doc_methods/parse_params.rb +113 -0
  24. data/lib/grape-swagger/doc_methods/path_string.rb +29 -0
  25. data/lib/grape-swagger/doc_methods/produces_consumes.rb +12 -0
  26. data/lib/grape-swagger/doc_methods/status_codes.rb +17 -0
  27. data/lib/grape-swagger/doc_methods/tag_name_description.rb +26 -0
  28. data/lib/grape-swagger/endpoint.rb +317 -0
  29. data/lib/grape-swagger/version.rb +1 -1
  30. data/spec/lib/data_type_spec.rb +57 -0
  31. data/spec/lib/endpoint_spec.rb +6 -0
  32. data/spec/lib/extensions_spec.rb +127 -0
  33. data/spec/lib/move_params_spec.rb +298 -0
  34. data/spec/lib/operation_id_spec.rb +24 -0
  35. data/spec/lib/optional_object_spec.rb +40 -0
  36. data/spec/lib/path_string_spec.rb +38 -0
  37. data/spec/lib/produces_consumes_spec.rb +98 -0
  38. data/spec/markdown/kramdown_adapter_spec.rb +2 -9
  39. data/spec/markdown/redcarpet_adapter_spec.rb +2 -16
  40. data/spec/spec_helper.rb +7 -13
  41. data/spec/support/api_swagger_v2_result.rb +204 -0
  42. data/spec/support/namespace_tags.rb +73 -0
  43. data/spec/support/the_api_entities.rb +52 -0
  44. data/spec/support/the_paths_definitions.rb +94 -0
  45. data/spec/swagger_v2/api_swagger_v2_definitions-models_spec.rb +32 -0
  46. data/spec/swagger_v2/api_swagger_v2_detail_spec.rb +151 -0
  47. data/spec/swagger_v2/api_swagger_v2_extensions_spec.rb +109 -0
  48. data/spec/swagger_v2/api_swagger_v2_format-content_type_spec.rb +124 -0
  49. data/spec/swagger_v2/api_swagger_v2_global_configuration_spec.rb +51 -0
  50. data/spec/swagger_v2/api_swagger_v2_headers_spec.rb +44 -0
  51. data/spec/swagger_v2/api_swagger_v2_hide_documentation_path_spec.rb +56 -0
  52. data/spec/swagger_v2/api_swagger_v2_mounted_spec.rb +146 -0
  53. data/spec/swagger_v2/api_swagger_v2_param_type_body_nested_spec.rb +197 -0
  54. data/spec/swagger_v2/api_swagger_v2_param_type_body_spec.rb +151 -0
  55. data/spec/swagger_v2/api_swagger_v2_param_type_spec.rb +217 -0
  56. data/spec/swagger_v2/api_swagger_v2_request_params_fix_spec.rb +64 -0
  57. data/spec/swagger_v2/api_swagger_v2_response_spec.rb +184 -0
  58. data/spec/swagger_v2/api_swagger_v2_spec.rb +207 -0
  59. data/spec/swagger_v2/api_swagger_v2_type-format_spec.rb +121 -0
  60. data/spec/{boolean_params_spec.rb → swagger_v2/boolean_params_spec.rb} +2 -2
  61. data/spec/{default_api_spec.rb → swagger_v2/default_api_spec.rb} +40 -36
  62. data/spec/swagger_v2/description_not_initialized.rb +39 -0
  63. data/spec/{float_api_spec.rb → swagger_v2/float_api_spec.rb} +2 -2
  64. data/spec/{form_params_spec.rb → swagger_v2/form_params_spec.rb} +9 -9
  65. data/spec/{grape-swagger_spec.rb → swagger_v2/grape-swagger_spec.rb} +0 -0
  66. data/spec/swagger_v2/hide_api_spec.rb +131 -0
  67. data/spec/swagger_v2/mounted_target_class_spec.rb +76 -0
  68. data/spec/swagger_v2/namespace_tags_prefix_spec.rb +84 -0
  69. data/spec/swagger_v2/namespace_tags_spec.rb +76 -0
  70. data/spec/{namespaced_api_spec.rb → swagger_v2/namespaced_api_spec.rb} +6 -26
  71. data/spec/{param_type_spec.rb → swagger_v2/param_type_spec.rb} +10 -8
  72. data/spec/{param_values_spec.rb → swagger_v2/param_values_spec.rb} +52 -22
  73. data/spec/swagger_v2/params_array_spec.rb +63 -0
  74. data/spec/swagger_v2/params_hash_spec.rb +65 -0
  75. data/spec/swagger_v2/params_nested_spec.rb +63 -0
  76. data/spec/{reference_entity.rb → swagger_v2/reference_entity.rb} +18 -23
  77. data/spec/swagger_v2/response_model_spec.rb +212 -0
  78. data/spec/swagger_v2/simple_mounted_api_spec.rb +264 -0
  79. metadata +175 -90
  80. data/example/api.rb +0 -66
  81. data/lib/grape-swagger/markdown.rb +0 -23
  82. data/spec/api_description_spec.rb +0 -43
  83. data/spec/api_global_models_spec.rb +0 -77
  84. data/spec/api_models_spec.rb +0 -364
  85. data/spec/api_paths_spec.rb +0 -128
  86. data/spec/api_root_spec.rb +0 -30
  87. data/spec/api_with_nil_types.rb +0 -50
  88. data/spec/api_with_path_versioning_spec.rb +0 -33
  89. data/spec/api_with_prefix_and_namespace_spec.rb +0 -32
  90. data/spec/api_with_standalone_namespace_spec.rb +0 -215
  91. data/spec/array_entity_spec.rb +0 -34
  92. data/spec/array_params_spec.rb +0 -85
  93. data/spec/grape-swagger_helper_spec.rb +0 -152
  94. data/spec/group_params_spec.rb +0 -31
  95. data/spec/hash_params_spec.rb +0 -30
  96. data/spec/hide_api_spec.rb +0 -124
  97. data/spec/i18n_spec.rb +0 -364
  98. data/spec/markdown/markdown_spec.rb +0 -27
  99. data/spec/mounted_target_class_spec.rb +0 -63
  100. data/spec/mutually_exclusive_spec.rb +0 -36
  101. data/spec/non_default_api_spec.rb +0 -733
  102. data/spec/response_model_spec.rb +0 -121
  103. data/spec/simple_mounted_api_spec.rb +0 -213
  104. data/spec/support/i18n_helper.rb +0 -8
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ describe GrapeSwagger::DocMethods::OptionalObject do
4
+ subject { described_class }
5
+
6
+ specify { expect(subject).to eql GrapeSwagger::DocMethods::OptionalObject }
7
+ specify { expect(subject).to respond_to :build }
8
+
9
+ describe 'build' do
10
+ let(:key) { :bar }
11
+ let(:request) { 'somes/request/string' }
12
+
13
+ describe 'no option given for key' do
14
+ let(:options) { {foo: 'foo' }}
15
+ specify do
16
+ expect(subject.build(key, options)).to be_nil
17
+ expect(subject.build(key, options, request)).to eql request
18
+ end
19
+ end
20
+
21
+ let(:value) { 'some optional value' }
22
+
23
+ describe 'option is a string' do
24
+ let(:options) { {bar: value }}
25
+ specify do
26
+ expect(subject.build(key, options)).to eql value
27
+ expect(subject.build(key, options, request)).to eql value
28
+ end
29
+ end
30
+
31
+ describe 'option is a proc' do
32
+ let(:options) { {bar: -> { value } }}
33
+ specify do
34
+ expect(subject.build(key, options)).to eql value
35
+ expect(subject.build(key, options, request)).to eql value
36
+ end
37
+ end
38
+ end
39
+
40
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe GrapeSwagger::DocMethods::PathString do
4
+ subject { described_class }
5
+
6
+ specify { expect(subject).to eql GrapeSwagger::DocMethods::PathString }
7
+ specify { expect(subject).to respond_to :build }
8
+
9
+ describe 'operation_id_object' do
10
+ describe 'version' do
11
+ describe 'defaults: not given, false' do
12
+ let(:options) {{ add_version: false }}
13
+
14
+ specify do
15
+ expect(subject.build('/thing(.json)', options)).to eql ['Thing', '/thing']
16
+ expect(subject.build('/thing/foo(.json)', options)).to eql ['Foo', '/thing/foo']
17
+ expect(subject.build('/thing(.:format)', options)).to eql ['Thing', '/thing']
18
+ expect(subject.build('/thing/foo(.:format)', options)).to eql ['Foo', '/thing/foo']
19
+ expect(subject.build('/thing/:id', options)).to eql ['Thing', '/thing/{id}']
20
+ expect(subject.build('/thing/foo/:id', options)).to eql ['Foo', '/thing/foo/{id}']
21
+ end
22
+ end
23
+
24
+ describe 'defaults: given, true' do
25
+ let(:options) {{ version: 'v1', add_version: true }}
26
+
27
+ specify do
28
+ expect(subject.build('/{version}/thing(.json)', options)).to eql ['Thing', '/v1/thing']
29
+ expect(subject.build('/{version}/thing/foo(.json)', options)).to eql ['Foo', '/v1/thing/foo']
30
+ expect(subject.build('/{version}/thing(.:format)', options)).to eql ['Thing', '/v1/thing']
31
+ expect(subject.build('/{version}/thing/foo(.:format)', options)).to eql ['Foo', '/v1/thing/foo']
32
+ expect(subject.build('/{version}/thing/:id', options)).to eql ['Thing', '/v1/thing/{id}']
33
+ expect(subject.build('/{version}/thing/foo/:id', options)).to eql ['Foo', '/v1/thing/foo/{id}']
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,98 @@
1
+ require 'spec_helper'
2
+
3
+ describe GrapeSwagger::DocMethods::ProducesConsumes do
4
+ describe ":json (default)" do
5
+ subject { described_class.call }
6
+
7
+ specify do
8
+ expect(subject).to eql( ['application/json'] )
9
+ end
10
+ end
11
+
12
+ describe "accept symbols of" do
13
+ describe "single" do
14
+ subject { described_class.call(:xml) }
15
+
16
+ specify do
17
+ expect(subject).to eql( ['application/xml'] )
18
+ end
19
+ end
20
+
21
+ describe "multiple" do
22
+ subject { described_class.call(:xml, :serializable_hash, :json, :binary, :txt) }
23
+
24
+ specify do
25
+ expect(subject).to eql( [
26
+ 'application/xml',
27
+ 'application/json',
28
+ 'application/octet-stream',
29
+ 'text/plain'
30
+ ] )
31
+ end
32
+ end
33
+ end
34
+
35
+ describe "accept mime_types of" do
36
+ describe "single" do
37
+ subject { described_class.call('application/xml') }
38
+
39
+ specify do
40
+ expect(subject).to eql( ['application/xml'] )
41
+ end
42
+ end
43
+
44
+ describe "multiple" do
45
+ subject { described_class.call(
46
+ 'application/xml',
47
+ 'application/json',
48
+ 'application/octet-stream',
49
+ 'text/plain'
50
+ ) }
51
+
52
+ specify do
53
+ expect(subject).to eql( [
54
+ 'application/xml',
55
+ 'application/json',
56
+ 'application/octet-stream',
57
+ 'text/plain'
58
+ ] )
59
+ end
60
+ end
61
+ end
62
+
63
+ describe "mix it up" do
64
+ subject { described_class.call(
65
+ :xml,
66
+ :serializable_hash,
67
+ 'application/json',
68
+ 'application/octet-stream',
69
+ :txt
70
+ ) }
71
+
72
+ specify do
73
+ expect(subject).to eql( [
74
+ 'application/xml',
75
+ 'application/json',
76
+ 'application/octet-stream',
77
+ 'text/plain'
78
+ ] )
79
+ end
80
+
81
+ subject { described_class.call( [
82
+ :xml,
83
+ :serializable_hash,
84
+ 'application/json',
85
+ 'application/octet-stream',
86
+ :txt
87
+ ] ) }
88
+
89
+ specify do
90
+ expect(subject).to eql( [
91
+ 'application/xml',
92
+ 'application/json',
93
+ 'application/octet-stream',
94
+ 'text/plain'
95
+ ] )
96
+ end
97
+ end
98
+ end
@@ -15,20 +15,13 @@ describe GrapeSwagger::Markdown::KramdownAdapter do
15
15
 
16
16
  expect(adapter.options).to eq(options)
17
17
  end
18
-
19
- it 'raises an GrapeSwagger::Errors::MarkdownDependencyMissingError if module can not be required' do
20
- pending
21
- expect_any_instance_of(Kernel).to receive(:require).with('kramdown').and_raise(LoadError)
22
-
23
- expect { GrapeSwagger::Markdown::KramdownAdapter.new }.to raise_error(GrapeSwagger::Errors::MarkdownDependencyMissingError, 'Missing required dependency: kramdown')
24
- end
25
18
  end
26
19
 
27
20
  context 'markdown' do
28
21
  it 'marks down with the configured options' do
29
- text = '# hello world #'
22
+ text = '# hello world'
30
23
  options = { input: 'GFM', enable_coderay: true, auto_ids: false, hard_wrap: true }
31
- expect(Kramdown::Document).to receive(:new).with(text, options).and_call_original
24
+ expect(GrapeSwagger::Markdown::KramdownAdapter).to receive(:new).with(options).and_call_original
32
25
 
33
26
  output = GrapeSwagger::Markdown::KramdownAdapter.new(options).markdown(text)
34
27
 
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe GrapeSwagger::Markdown::RedcarpetAdapter, unless: RUBY_PLATFORM.eql?('java') do
3
+ describe GrapeSwagger::Markdown::RedcarpetAdapter, unless: RUBY_PLATFORM.eql?('java') || RUBY_ENGINE.eql?('rbx') do
4
4
  context 'initialization' do
5
5
  context 'initialization' do
6
6
  it 'uses fenced_code_blocks, auto_links and rouge as default.' do
@@ -30,19 +30,13 @@ describe GrapeSwagger::Markdown::RedcarpetAdapter, unless: RUBY_PLATFORM.eql?('j
30
30
  expect(adapter.extension_options).to eq(extensions)
31
31
  expect(adapter.render_options).to eq(no_links: true)
32
32
  end
33
-
34
- it 'raises an GrapeSwagger::Errors::MarkdownDependencyMissingError if module can not be required.' do
35
- expect_any_instance_of(Kernel).to receive(:require).with('redcarpet').and_raise(LoadError)
36
-
37
- expect { GrapeSwagger::Markdown::RedcarpetAdapter.new }.to raise_error(GrapeSwagger::Errors::MarkdownDependencyMissingError, 'Missing required dependency: redcarpet')
38
- end
39
33
  end
40
34
 
41
35
  context 'markdown' do
42
36
  it 'marks down with the configured options' do
43
37
  text = '# hello world #'
44
38
  extensions = { fenced_code_blocks: true, autolink: true }
45
- render_options = { highlighter: :none, no_links: true }
39
+ render_options = { highlighter: :none, no_links: true, highlighter: :none }
46
40
  expect_any_instance_of(Redcarpet::Markdown).to receive(:render).with(text).and_call_original
47
41
 
48
42
  output = GrapeSwagger::Markdown::RedcarpetAdapter.new(extensions: extensions, render_options: render_options).markdown(text)
@@ -60,14 +54,6 @@ describe GrapeSwagger::Markdown::RedcarpetAdapter, unless: RUBY_PLATFORM.eql?('j
60
54
  expect(renderer.superclass).to be(Redcarpet::Render::HTML)
61
55
  end
62
56
 
63
- it 'throws an error when rouge syntax highlighter cant be included' do
64
- adapter = GrapeSwagger::Markdown::RedcarpetAdapter.new
65
-
66
- expect_any_instance_of(Kernel).to receive(:require).with('rouge').and_raise(LoadError)
67
-
68
- expect { adapter.send(:new_redcarpet_renderer, :rouge) }.to raise_error(GrapeSwagger::Errors::MarkdownDependencyMissingError, 'Missing required dependency: rouge')
69
- end
70
-
71
57
  it 'returns a default syntax highlighter' do
72
58
  adapter = GrapeSwagger::Markdown::RedcarpetAdapter.new
73
59
  renderer = adapter.send(:new_redcarpet_renderer, :none)
data/spec/spec_helper.rb CHANGED
@@ -1,29 +1,23 @@
1
- $LOAD_PATH.unshift(File.dirname(__FILE__))
2
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'support'))
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+
3
+ Dir[File.join(Dir.getwd, 'spec/support/**/*.rb')].each { |f| require f }
4
4
 
5
5
  require 'grape'
6
6
  require 'grape-swagger'
7
7
  require 'grape-entity'
8
8
 
9
- require 'rubygems'
10
- require 'bundler'
11
-
12
- require 'json'
13
-
14
9
  Bundler.setup :default, :test
15
10
 
11
+ require 'rack'
16
12
  require 'rack/test'
17
13
 
18
- require 'i18n_helper'
19
-
20
14
  RSpec.configure do |config|
21
15
  require 'rspec/expectations'
22
- require 'rspec/support'
23
-
24
16
  config.include RSpec::Matchers
25
17
  config.mock_with :rspec
26
18
  config.include Rack::Test::Methods
27
19
  config.raise_errors_for_deprecations!
28
- config.include I18nHelper
20
+
21
+ config.order = 'random'
22
+ config.seed = 40834
29
23
  end
@@ -0,0 +1,204 @@
1
+ RSpec.shared_context "swagger example" do
2
+
3
+ before :all do
4
+ module Entities
5
+ class Something < Grape::Entity
6
+ expose :id, documentation: { type: Integer, desc: 'Identity of Something' }
7
+ expose :text, documentation: { type: String, desc: 'Content of something.' }
8
+ expose :links, documentation: { type: 'link', is_array: true }
9
+ expose :others, documentation: { type: 'text', is_array: false }
10
+ end
11
+
12
+ class EnumValues < Grape::Entity
13
+ expose :gender, documentation: { type: 'string', desc: 'Content of something.', values: %w(Male Female) }
14
+ expose :number, documentation: { type: 'integer', desc: 'Content of something.', values: [1, 2] }
15
+ end
16
+
17
+
18
+ class AliasedThing < Grape::Entity
19
+ expose :something, as: :post, using: Entities::Something, documentation: { type: 'Something', desc: 'Reference to something.' }
20
+ end
21
+
22
+ class FourthLevel < Grape::Entity
23
+ expose :text, documentation: { type: 'string' }
24
+ end
25
+
26
+ class ThirdLevel < Grape::Entity
27
+ expose :parts, using: Entities::FourthLevel, documentation: { type: 'FourthLevel' }
28
+ end
29
+
30
+ class SecondLevel < Grape::Entity
31
+ expose :parts, using: Entities::ThirdLevel, documentation: { type: 'ThirdLevel' }
32
+ end
33
+
34
+ class FirstLevel < Grape::Entity
35
+ expose :parts, using: Entities::SecondLevel, documentation: { type: 'SecondLevel' }
36
+ end
37
+
38
+ class QueryInputElement < Grape::Entity
39
+ expose :key, documentation: {
40
+ type: String, desc: 'Name of parameter', required: true }
41
+ expose :value, documentation: {
42
+ type: String, desc: 'Value of parameter', required: true }
43
+ end
44
+
45
+ class QueryInput < Grape::Entity
46
+ expose :elements, using: Entities::QueryInputElement, documentation: {
47
+ type: 'QueryInputElement',
48
+ desc: 'Set of configuration',
49
+ param_type: 'body',
50
+ is_array: true,
51
+ required: true
52
+ }
53
+ end
54
+
55
+ class ApiError < Grape::Entity
56
+ expose :code, documentation: { type: Integer, desc: 'status code' }
57
+ expose :message, documentation: { type: String, desc: 'error message' }
58
+ end
59
+ end
60
+ end
61
+
62
+ let(:swagger_json) do
63
+ {
64
+ "info"=>{
65
+ "title"=>"The API title to be displayed on the API homepage.",
66
+ "description"=>"A description of the API.",
67
+ "termsOfServiceUrl"=>"www.The-URL-of-the-terms-and-service.com",
68
+ "contact"=>{"name"=>"Contact name", "email"=>"Contact@email.com", "url"=>"Contact URL"},
69
+ "license"=>{"name"=>"The name of the license.", "url"=>"www.The-URL-of-the-license.org"},
70
+ "version"=>"v1"
71
+ },
72
+ "swagger"=>"2.0",
73
+ "produces"=>["application/json"],
74
+ "host"=>"example.org",
75
+ "basePath"=>"/api",
76
+ "tags"=>[
77
+ {"name"=>"other_thing", "description"=>"Operations about other_things"},
78
+ {"name"=>"thing", "description"=>"Operations about things"},
79
+ {"name"=>"thing2", "description"=>"Operations about thing2s"},
80
+ {"name"=>"dummy", "description"=>"Operations about dummies"}
81
+ ],
82
+ "schemes"=>["https", "http"],
83
+ "paths"=>{
84
+ "/v3/other_thing/{elements}"=>{
85
+ "get"=>{
86
+ "description"=>"nested route inside namespace",
87
+ "produces"=>["application/json"],
88
+ "parameters"=>[{"in"=>"body", "name"=>"elements", "description"=>"Set of configuration", "type"=>"array", "items"=>{"type"=>"string"}, "required"=>true}],
89
+ "responses"=>{"200"=>{"description"=>"nested route inside namespace", "schema"=>{"$ref"=>"#/definitions/QueryInput"}}},
90
+ "tags"=>["other_thing"],
91
+ "operationId"=>"getV3OtherThingElements",
92
+ "x-amazon-apigateway-auth"=>{"type"=>"none"},
93
+ "x-amazon-apigateway-integration"=>{"type"=>"aws", "uri"=>"foo_bar_uri", "httpMethod"=>"get"}
94
+ }
95
+ },
96
+ "/thing"=>{
97
+ "get"=>{
98
+ "description"=>"This gets Things.",
99
+ "produces"=>["application/json"],
100
+ "parameters"=>[
101
+ {"in"=>"query", "name"=>"id", "description"=>"Identity of Something", "type"=>"integer", "format"=>"int32", "required"=>false},
102
+ {"in"=>"query", "name"=>"text", "description"=>"Content of something.", "type"=>"string", "required"=>false},
103
+ {"in"=>"formData", "name"=>"links", "description"=>nil, "type"=>"array", "items"=>{"type"=>"link"}, "required"=>false},
104
+ {"in"=>"query", "name"=>"others", "description"=>nil, "type"=>"text", "required"=>false}
105
+ ],
106
+ "responses"=>{"200"=>{"description"=>"This gets Things.", "schema"=>{"$ref"=>"#/definitions/Thing"}}, "401"=>{"description"=>"Unauthorized", "schema"=>{"$ref"=>"#/definitions/ApiError"}}},
107
+ "tags"=>["thing"],
108
+ "operationId"=>"getThing"
109
+ },
110
+ "post"=>{
111
+ "description"=>"This creates Thing.",
112
+ "produces"=>["application/json"],
113
+ "consumes"=>["application/json"],
114
+ "parameters"=>[
115
+ {"in"=>"formData", "name"=>"text", "description"=>"Content of something.", "type"=>"string", "required"=>true},
116
+ {"in"=>"formData", "name"=>"links", "description"=>nil, "type"=>"array", "items"=>{"type"=>"string"}, "required"=>true}
117
+ ],
118
+ "responses"=>{"201"=>{"description"=>"This creates Thing.", "schema"=>{"$ref"=>"#/definitions/Something"}}, "422"=>{"description"=>"Unprocessible Entity"}},
119
+ "tags"=>["thing"],
120
+ "operationId"=>"postThing"
121
+ }
122
+ },
123
+ "/thing/{id}"=>{
124
+ "get"=>{
125
+ "description"=>"This gets Thing.",
126
+ "produces"=>["application/json"],
127
+ "parameters"=>[{"in"=>"path", "name"=>"id", "description"=>nil, "type"=>"integer", "format"=>"int32", "required"=>true}],
128
+ "responses"=>{"200"=>{"description"=>"getting a single thing", "schema"=>{"$ref"=>"#/definitions/Thing"}}, "401"=>{"description"=>"Unauthorized"}},
129
+ "tags"=>["thing"],
130
+ "operationId"=>"getThingId"
131
+ },
132
+ "put"=>{
133
+ "description"=>"This updates Thing.",
134
+ "produces"=>["application/json"],
135
+ "consumes"=>["application/json"],
136
+ "parameters"=>[
137
+ {"in"=>"path", "name"=>"id", "description"=>nil, "type"=>"integer", "format"=>"int32", "required"=>true},
138
+ {"in"=>"formData", "name"=>"text", "description"=>"Content of something.", "type"=>"string", "required"=>false},
139
+ {"in"=>"formData", "name"=>"links", "description"=>nil, "type"=>"array", "items"=>{"type"=>"string"}, "required"=>false}
140
+ ],
141
+ "responses"=>{"200"=>{"description"=>"This updates Thing.", "schema"=>{"$ref"=>"#/definitions/Something"}}},
142
+ "tags"=>["thing"],
143
+ "operationId"=>"putThingId"
144
+ },
145
+ "delete"=>{
146
+ "description"=>"This deletes Thing.",
147
+ "produces"=>["application/json"],
148
+ "parameters"=>[{"in"=>"path", "name"=>"id", "description"=>nil, "type"=>"integer", "format"=>"int32", "required"=>true}],
149
+ "responses"=>{"200"=>{"description"=>"This deletes Thing.", "schema"=>{"$ref"=>"#/definitions/Something"}}},
150
+ "tags"=>["thing"],
151
+ "operationId"=>"deleteThingId"
152
+ }
153
+ },
154
+ "/thing2"=>{
155
+ "get"=>{
156
+ "description"=>"This gets Things.",
157
+ "produces"=>["application/json"],
158
+ "responses"=>{"200"=>{"description"=>"get Horses", "schema"=>{"$ref"=>"#/definitions/Something"}}, "401"=>{"description"=>"HorsesOutError", "schema"=>{"$ref"=>"#/definitions/ApiError"}}},
159
+ "tags"=>["thing2"],
160
+ "operationId"=>"getThing2"
161
+ }
162
+ },
163
+ "/dummy/{id}"=>{
164
+ "delete"=>{
165
+ "description"=>"dummy route.",
166
+ "produces"=>["application/json"],
167
+ "parameters"=>[{"in"=>"path", "name"=>"id", "description"=>nil, "type"=>"integer", "format"=>"int32", "required"=>true}],
168
+ "responses"=>{"204"=>{"description"=>"dummy route."}, "401"=>{"description"=>"Unauthorized"}},
169
+ "tags"=>["dummy"],
170
+ "operationId"=>"deleteDummyId"
171
+ }
172
+ }
173
+ },
174
+ "definitions"=>{
175
+ "QueryInput"=>{
176
+ "type"=>"object",
177
+ "properties"=>{"elements"=>{"type"=>"array", "items"=>{"$ref"=>"#/definitions/QueryInputElement"}}},
178
+ "description"=>"nested route inside namespace"},
179
+ "QueryInputElement"=>{
180
+ "type"=>"object",
181
+ "properties"=>{"key"=>{"type"=>"string"}, "value"=>{"type"=>"string"}}},
182
+ "Thing"=>{
183
+ "type"=>"object",
184
+ "properties"=>{"id"=>{"type"=>"integer", "format"=>"int32"}, "text"=>{"type"=>"string"}, "links"=>{"type"=>"link"}, "others"=>{"type"=>"text"}},
185
+ "description"=>"This gets Thing."},
186
+ "ApiError"=>{
187
+ "type"=>"object",
188
+ "properties"=>{"code"=>{"type"=>"integer", "format"=>"int32"}, "message"=>{"type"=>"string"}},
189
+ "description"=>"This gets Things."},
190
+ "Something"=>{
191
+ "type"=>"object",
192
+ "properties"=>{"id"=>{"type"=>"integer", "format"=>"int32"}, "text"=>{"type"=>"string"}, "links"=>{"type"=>"link"}, "others"=>{"type"=>"text"}},
193
+ "description"=>"This gets Things."
194
+ }
195
+ }
196
+ }
197
+ end
198
+
199
+ let(:http_verbs) { %w[get post put delete]}
200
+ end
201
+
202
+ def mounted_paths
203
+ %w[ /thing /other_thing /dummy ]
204
+ end