swagger-docs 0.1.8 → 0.1.9
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
- checksums.yaml.gz.sig +2 -1
- data.tar.gz.sig +3 -1
- data/CHANGELOG.md +15 -0
- data/README.md +51 -3
- data/lib/swagger/docs/config.rb +5 -1
- data/lib/swagger/docs/dsl.rb +7 -3
- data/lib/swagger/docs/generator.rb +40 -13
- data/lib/swagger/docs/impotent_methods.rb +1 -1
- data/lib/swagger/docs/methods.rb +6 -6
- data/lib/swagger/docs/version.rb +1 -1
- data/spec/fixtures/controllers/nested_controller.rb +18 -0
- data/spec/fixtures/controllers/sample_controller.rb +3 -6
- data/spec/lib/swagger/docs/api_declaration_file_spec.rb +4 -2
- data/spec/lib/swagger/docs/config_spec.rb +8 -0
- data/spec/lib/swagger/docs/dsl_spec.rb +15 -0
- data/spec/lib/swagger/docs/generator_spec.rb +79 -32
- data/spec/lib/swagger/docs/methods.rb +15 -0
- data/spec/spec_helper.rb +9 -0
- data/swagger-docs.gemspec +3 -1
- metadata +42 -10
- metadata.gz.sig +4 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9c266ba841a5bdacb059df2348ef839408bb1b8b
|
4
|
+
data.tar.gz: 85475fb831183dded5e7ed8b858e9c2df590350f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d5919f6cdf9462d5074db8e1749e4ef518dec92e08148de8f005ce518b7b0c90b0fefe40f638997cff400ca27f1b78af23b87b1944989503cf461c4987130509
|
7
|
+
data.tar.gz: 5511929b22b9b62174cacbe09ac160763337ccd600a2fb75b634445e29cbaba23ffce392fac3181ada7b38f7e6a3cb323e442533145277140faba98aeb768437
|
checksums.yaml.gz.sig
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
|
1
|
+
+�B�;=Ї0��-g�ӥ�x����[}�`0yM��"���f�xMZ-%9�^�vk S�Fb{�7��
|
2
|
+
)'�|�>��U��f *��������C��j {�=O:���╬~a��ĩ`ۧo���w����URR��k�M6�4���8�xK�����u�;|��
|
data.tar.gz.sig
CHANGED
@@ -1 +1,3 @@
|
|
1
|
-
|
1
|
+
��n��Ҵ~)8��!@zs��7p��XZ� ����-���Ws7���3ۘ��۲��
|
2
|
+
`�:�Վ"���Z�1p �;.`K�v+#O����ۢl��Q�,M!�P�O��S�.�w���(�Q�"`���@8����>��k��|v+i��^C�_�>��&�c;$�uϮ?����
|
3
|
+
�"�b��>{ _]D<���cQ���$�?������|�Q�DoK���l��
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
## 0.1.10
|
2
|
+
|
3
|
+
(next release - not released yet)
|
4
|
+
|
5
|
+
## 0.1.9
|
6
|
+
|
7
|
+
- Adding support for multiple engines #65
|
8
|
+
- Add ability for swagger_api to accept parameters (e.g. consumes, produces)
|
9
|
+
- Update dependencies #64
|
10
|
+
- Address issue with routing verbs where some verbs do not have a route.verb.source attribute only route.verb #58
|
11
|
+
- Add ability to set custom attributes (like info block) on api-docs file #67
|
12
|
+
- Ensure API endpoint/nickname (e.g. "Api::V1::Some#update") is only written out once per resource file. Addresses PATCH, POST duplication issue #70
|
13
|
+
- Add "consumes" dsl method #74
|
14
|
+
- Expose API version on transform_path for easier “No Server Integrations” #79
|
15
|
+
|
1
16
|
## 0.1.8
|
2
17
|
|
3
18
|
- Fix issue with gem build open-ended dependency warnings in gemspec
|
data/README.md
CHANGED
@@ -2,6 +2,15 @@
|
|
2
2
|
|
3
3
|
Generates swagger-ui json files for rails apps with APIs. You add the swagger DSL to your controller classes and then run one rake task to generate the json files.
|
4
4
|
|
5
|
+
[][gem]
|
6
|
+
[][gemnasium]
|
7
|
+
|
8
|
+
[gem]: https://rubygems.org/gems/swagger-docs
|
9
|
+
[travis]: http://travis-ci.org/richhollis/swagger-docs
|
10
|
+
[gemnasium]: https://gemnasium.com/richhollis/swagger-docs
|
11
|
+
[coveralls]: https://coveralls.io/r/richhollis/swagger-docs
|
12
|
+
|
13
|
+
|
5
14
|
Here is an extract of the DSL from a user controller API class:
|
6
15
|
|
7
16
|
```ruby
|
@@ -47,7 +56,18 @@ Swagger::Docs::Config.register_apis({
|
|
47
56
|
# the URL base path to your API
|
48
57
|
:base_path => "http://api.somedomain.com",
|
49
58
|
# if you want to delete all .json files at each generation
|
50
|
-
:clean_directory => false
|
59
|
+
:clean_directory => false,
|
60
|
+
# add custom attributes to api-docs
|
61
|
+
:attributes => {
|
62
|
+
:info => {
|
63
|
+
"title" => "Swagger Sample App",
|
64
|
+
"description" => "This is a sample description.",
|
65
|
+
"termsOfServiceUrl" => "http://helloreverb.com/terms/",
|
66
|
+
"contact" => "apiteam@wordnik.com",
|
67
|
+
"license" => "Apache 2.0",
|
68
|
+
"licenseUrl" => "http://www.apache.org/licenses/LICENSE-2.0.html"
|
69
|
+
}
|
70
|
+
}
|
51
71
|
}
|
52
72
|
})
|
53
73
|
```
|
@@ -132,6 +152,7 @@ class Api::V1::UsersController < ApplicationController
|
|
132
152
|
swagger_api :show do
|
133
153
|
summary "Fetches a single User item"
|
134
154
|
param :path, :id, :integer, :optional, "User Id"
|
155
|
+
response :success, "Success", :User
|
135
156
|
response :unauthorized
|
136
157
|
response :not_acceptable
|
137
158
|
response :not_found
|
@@ -288,6 +309,25 @@ class Swagger::Docs::Config
|
|
288
309
|
end
|
289
310
|
```
|
290
311
|
|
312
|
+
If you want swagger to find controllers in `Rails.application` and/or multiple
|
313
|
+
engines you can override `base_application` to return an array.
|
314
|
+
|
315
|
+
```ruby
|
316
|
+
class Swagger::Docs::Config
|
317
|
+
def self.base_application; [Rails.application, Api::Engine, SomeOther::Engine] end
|
318
|
+
end
|
319
|
+
```
|
320
|
+
|
321
|
+
Or, if you prefer you can override `base_applications` for this purpose. The plural
|
322
|
+
`base_applications` takes precedence over `base_application` and MUST return an
|
323
|
+
array.
|
324
|
+
|
325
|
+
```ruby
|
326
|
+
class Swagger::Docs::Config
|
327
|
+
def self.base_applications; [Rails.application, Api::Engine, SomeOther::Engine] end
|
328
|
+
end
|
329
|
+
```
|
330
|
+
|
291
331
|
#### Transforming the `path` variable
|
292
332
|
|
293
333
|
Swagger allows a distinction between the API documentation server and the hosted API
|
@@ -296,8 +336,8 @@ class method in your initializer:
|
|
296
336
|
|
297
337
|
```ruby
|
298
338
|
class Swagger::Docs::Config
|
299
|
-
def self.transform_path(path)
|
300
|
-
"http://example.com/api-docs/#{path}"
|
339
|
+
def self.transform_path(path, api_version)
|
340
|
+
"http://example.com/api-docs/#{api_version}/#{path}"
|
301
341
|
end
|
302
342
|
end
|
303
343
|
```
|
@@ -616,6 +656,14 @@ users.json output:
|
|
616
656
|
|
617
657
|
Thanks to jdar, fotinakis, stevschmid, ldnunes, aaronrenner and all of our contributors for making swagger-docs even better.
|
618
658
|
|
659
|
+
## Related Projects
|
660
|
+
|
661
|
+
**[@fotinakis](https://github.com/fotinakis/)** has created Swagger::Blocks - a DSL for pure Ruby code blocks: [swagger-blocks](https://github.com/fotinakis/swagger-blocks/)
|
662
|
+
|
663
|
+
## More About Me
|
664
|
+
|
665
|
+
[Rich Hollis](http://richhollis.co.uk)
|
666
|
+
|
619
667
|
## Contributing
|
620
668
|
|
621
669
|
When raising a Pull Request please ensure that you have provided good test coverage for the request you are making.
|
data/lib/swagger/docs/config.rb
CHANGED
@@ -12,6 +12,10 @@ module Swagger
|
|
12
12
|
@@base_api_controller = controller
|
13
13
|
end
|
14
14
|
|
15
|
+
def base_applications
|
16
|
+
Array(base_application)
|
17
|
+
end
|
18
|
+
|
15
19
|
def base_application
|
16
20
|
Rails.application
|
17
21
|
end
|
@@ -25,7 +29,7 @@ module Swagger
|
|
25
29
|
@versions ||= {}
|
26
30
|
end
|
27
31
|
|
28
|
-
def transform_path(path)
|
32
|
+
def transform_path(path, api_version)
|
29
33
|
# This is only for overriding, so don't perform any path transformations by default.
|
30
34
|
path
|
31
35
|
end
|
data/lib/swagger/docs/dsl.rb
CHANGED
@@ -16,7 +16,7 @@ module Swagger
|
|
16
16
|
def summary(text)
|
17
17
|
@summary = text
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
def notes(text)
|
21
21
|
@notes = text
|
22
22
|
end
|
@@ -29,6 +29,10 @@ module Swagger
|
|
29
29
|
@type = type
|
30
30
|
end
|
31
31
|
|
32
|
+
def consumes(mime_types)
|
33
|
+
@consumes = mime_types
|
34
|
+
end
|
35
|
+
|
32
36
|
def nickname(nickname)
|
33
37
|
@nickname = nickname
|
34
38
|
end
|
@@ -55,9 +59,9 @@ module Swagger
|
|
55
59
|
def response(status, text = nil, model = nil)
|
56
60
|
if status.is_a? Symbol
|
57
61
|
status_code = Rack::Utils.status_code(status)
|
58
|
-
response_messages << {:code => status_code, :message => text || status.to_s.titleize}
|
62
|
+
response_messages << {:code => status_code, :responseModel => model, :message => text || status.to_s.titleize}
|
59
63
|
else
|
60
|
-
response_messages << {:code => status, :message => text}
|
64
|
+
response_messages << {:code => status, :responseModel => model, :message => text}
|
61
65
|
end
|
62
66
|
response_messages.sort_by!{|i| i[:code]}
|
63
67
|
end
|
@@ -28,7 +28,10 @@ module Swagger
|
|
28
28
|
clean_output_paths(settings[:api_file_path]) if config[:clean_directory] || false
|
29
29
|
root = result[:root]
|
30
30
|
resources = root.delete 'resources'
|
31
|
+
root.merge!(config[:attributes] || {}) # merge custom user attributes like info
|
32
|
+
# write the api-docs file
|
31
33
|
write_to_file("#{settings[:api_file_path]}/api-docs.json", root, config)
|
34
|
+
# write the individual resource files
|
32
35
|
resources.each do |resource|
|
33
36
|
resource_file_path = resource.delete 'resourceFilePath'
|
34
37
|
write_to_file(File.join(settings[:api_file_path], "#{resource_file_path}.json"), resource, config)
|
@@ -54,7 +57,7 @@ module Swagger
|
|
54
57
|
end
|
55
58
|
|
56
59
|
def generate_doc(api_version, settings, config)
|
57
|
-
root = { "apiVersion" => api_version, "swaggerVersion" => "1.2", "basePath" => settings[:base_path] + "/", :apis => []}
|
60
|
+
root = { "apiVersion" => api_version, "swaggerVersion" => "1.2", "basePath" => settings[:base_path] + "/", :apis => [] }
|
58
61
|
results = {:processed => [], :skipped => []}
|
59
62
|
resources = []
|
60
63
|
|
@@ -65,7 +68,7 @@ module Swagger
|
|
65
68
|
resources << generate_resource(ret[:path], ret[:apis], ret[:models], settings, root, config)
|
66
69
|
debased_path = get_debased_path(ret[:path], settings[:controller_base_path])
|
67
70
|
resource_api = {
|
68
|
-
path: "#{Config.transform_path(trim_leading_slash(debased_path))}.{format}",
|
71
|
+
path: "#{Config.transform_path(trim_leading_slash(debased_path), api_version)}.{format}",
|
69
72
|
description: ret[:klass].swagger_config[:description]
|
70
73
|
}
|
71
74
|
root[:apis] << resource_api
|
@@ -123,15 +126,34 @@ module Swagger
|
|
123
126
|
klass = "#{path.to_s.camelize}Controller".constantize rescue nil
|
124
127
|
return {action: :skipped, path: path, reason: :klass_not_present} if !klass
|
125
128
|
return {action: :skipped, path: path, reason: :not_swagger_resource} if !klass.methods.include?(:swagger_config) or !klass.swagger_config[:controller]
|
126
|
-
apis, models = [], {}
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
129
|
+
apis, models, defined_nicknames = [], {}, []
|
130
|
+
routes.select{|i| i.defaults[:controller] == path}.each do |route|
|
131
|
+
unless nickname_defined?(defined_nicknames, path, route) # only add once for each route once e.g. PATCH, PUT
|
132
|
+
ret = get_route_path_apis(path, route, klass, settings, config)
|
133
|
+
apis = apis + ret[:apis]
|
134
|
+
models.merge!(ret[:models])
|
135
|
+
defined_nicknames << ret[:nickname] if ret[:nickname].present?
|
136
|
+
end
|
131
137
|
end
|
132
138
|
{action: :processed, path: path, apis: apis, models: models, klass: klass}
|
133
139
|
end
|
134
140
|
|
141
|
+
def route_verb(route)
|
142
|
+
if defined?(route.verb.source) then route.verb.source.to_s.delete('$'+'^') else route.verb end.downcase.to_sym
|
143
|
+
end
|
144
|
+
|
145
|
+
def path_route_nickname(path, route)
|
146
|
+
action = route.defaults[:action]
|
147
|
+
"#{path.camelize}##{action}"
|
148
|
+
end
|
149
|
+
|
150
|
+
def nickname_defined?(defined_nicknames, path, route)
|
151
|
+
verb = route_verb(route)
|
152
|
+
target_nickname = path_route_nickname(path, route)
|
153
|
+
defined_nicknames.each{|nickname| return true if nickname == target_nickname }
|
154
|
+
false
|
155
|
+
end
|
156
|
+
|
135
157
|
def generate_resource(path, apis, models, settings, root, config)
|
136
158
|
metadata = ApiDeclarationFileMetadata.new(root["apiVersion"], path, root["basePath"],
|
137
159
|
settings[:controller_base_path],
|
@@ -141,22 +163,27 @@ module Swagger
|
|
141
163
|
declaration.generate_resource
|
142
164
|
end
|
143
165
|
|
166
|
+
def routes
|
167
|
+
Config.base_applications.map{|app| app.routes.routes.to_a }.flatten
|
168
|
+
end
|
169
|
+
|
144
170
|
def get_route_path_apis(path, route, klass, settings, config)
|
145
171
|
models, apis = {}, []
|
146
172
|
action = route.defaults[:action]
|
147
|
-
verb = route
|
148
|
-
return {apis: apis, models: models} if !operations = klass.swagger_actions[action.to_sym]
|
173
|
+
verb = route_verb(route)
|
174
|
+
return {apis: apis, models: models, nickname: nil} if !operations = klass.swagger_actions[action.to_sym]
|
149
175
|
operations = Hash[operations.map {|k, v| [k.to_s.gsub("@","").to_sym, v.respond_to?(:deep_dup) ? v.deep_dup : v.dup] }] # rename :@instance hash keys
|
150
176
|
operations[:method] = verb
|
151
|
-
operations[:nickname] =
|
177
|
+
nickname = operations[:nickname] = path_route_nickname(path, route)
|
152
178
|
|
153
|
-
|
179
|
+
route_path = if defined?(route.path.spec) then route.path.spec else route.path end
|
180
|
+
api_path = transform_spec_to_api_path(route_path, settings[:controller_base_path], config[:api_extension_type])
|
154
181
|
operations[:parameters] = filter_path_params(api_path, operations[:parameters]) if operations[:parameters]
|
155
182
|
|
156
183
|
apis << {:path => api_path, :operations => [operations]}
|
157
184
|
models = get_klass_models(klass)
|
158
185
|
|
159
|
-
{apis: apis, models: models}
|
186
|
+
{apis: apis, models: models, nickname: nickname}
|
160
187
|
end
|
161
188
|
|
162
189
|
def get_klass_models(klass)
|
@@ -187,7 +214,7 @@ module Swagger
|
|
187
214
|
end
|
188
215
|
|
189
216
|
def get_route_paths(controller_base_path)
|
190
|
-
paths =
|
217
|
+
paths = routes.map{|i| "#{i.defaults[:controller]}" }
|
191
218
|
paths.uniq.select{|i| i.start_with?(controller_base_path)}
|
192
219
|
end
|
193
220
|
|
data/lib/swagger/docs/methods.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require "active_support/core_ext/hash/deep_merge"
|
1
2
|
module Swagger
|
2
3
|
module Docs
|
3
4
|
module Methods
|
@@ -6,17 +7,18 @@ module Swagger
|
|
6
7
|
end
|
7
8
|
|
8
9
|
module ClassMethods
|
9
|
-
def swagger_controller(controller, description)
|
10
|
+
def swagger_controller(controller, description, params = {})
|
10
11
|
swagger_config[:controller] = controller
|
11
12
|
swagger_config[:description] = description
|
12
13
|
end
|
13
14
|
|
14
15
|
def swagger_actions
|
15
16
|
swagger_dsl = {}
|
16
|
-
Array(@swagger_dsl).each do |action, controller, block|
|
17
|
+
Array(@swagger_dsl).each do |action, params, controller, block|
|
17
18
|
dsl = SwaggerDSL.call(action, controller, &block)
|
18
19
|
swagger_dsl[action] ||= {}
|
19
20
|
swagger_dsl[action].deep_merge!(dsl) { |key, old, new| Array(old) + Array(new) }
|
21
|
+
swagger_dsl[action].deep_merge!(params) # merge in user api parameters
|
20
22
|
end
|
21
23
|
swagger_dsl
|
22
24
|
end
|
@@ -34,11 +36,9 @@ module Swagger
|
|
34
36
|
@swagger_config ||= {}
|
35
37
|
end
|
36
38
|
|
37
|
-
|
38
|
-
|
39
|
-
def swagger_api(action, &block)
|
39
|
+
def swagger_api(action, params = {}, &block)
|
40
40
|
@swagger_dsl ||= []
|
41
|
-
@swagger_dsl << [action, self, block]
|
41
|
+
@swagger_dsl << [action, params, self, block]
|
42
42
|
end
|
43
43
|
|
44
44
|
def swagger_model(model_name, &block)
|
data/lib/swagger/docs/version.rb
CHANGED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Api
|
2
|
+
module V1
|
3
|
+
class SuperclassController < ApplicationController
|
4
|
+
end
|
5
|
+
class NestedController < SuperclassController
|
6
|
+
swagger_controller :nested, "User Management"
|
7
|
+
|
8
|
+
swagger_api :index do
|
9
|
+
summary "Fetches all User items"
|
10
|
+
param :query, :page, :integer, :optional, "Page number"
|
11
|
+
param :path, :nested_id, :integer, :optional, "Team Id"
|
12
|
+
response :unauthorized
|
13
|
+
response :not_acceptable, "The request you made is not acceptable"
|
14
|
+
response :requested_range_not_satisfiable
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -9,14 +9,9 @@ module Api
|
|
9
9
|
summary "Fetches all User items"
|
10
10
|
param :query, :page, :integer, :optional, "Page number"
|
11
11
|
param :path, :nested_id, :integer, :optional, "Team Id"
|
12
|
+
response :success, "Some text", :Tag
|
12
13
|
response :unauthorized
|
13
|
-
end
|
14
|
-
|
15
|
-
swagger_api :index do
|
16
14
|
response :not_acceptable, "The request you made is not acceptable"
|
17
|
-
end
|
18
|
-
|
19
|
-
swagger_api :index do
|
20
15
|
response :requested_range_not_satisfiable
|
21
16
|
end
|
22
17
|
|
@@ -30,10 +25,12 @@ module Api
|
|
30
25
|
|
31
26
|
swagger_api :create do
|
32
27
|
summary "Creates a new User"
|
28
|
+
consumes [ "application/json", "text/xml" ]
|
33
29
|
param :form, :first_name, :string, :required, "First name"
|
34
30
|
param :form, :last_name, :string, :required, "Last name"
|
35
31
|
param :form, :email, :string, :required, "Email address"
|
36
32
|
param_list :form, :role, :string, :required, "Role", [ "admin", "superadmin", "user" ]
|
33
|
+
param :body, :body, :json, :required, 'JSON formatted body'
|
37
34
|
response :unauthorized
|
38
35
|
response :not_acceptable
|
39
36
|
end
|
@@ -22,7 +22,8 @@ describe Swagger::Docs::ApiDeclarationFile do
|
|
22
22
|
],
|
23
23
|
:notes=>"Only the given fields are updated.",
|
24
24
|
:method=>:put,
|
25
|
-
:nickname=>"Api::V1::Sample#update"
|
25
|
+
:nickname=>"Api::V1::Sample#update",
|
26
|
+
:consumes=>["application/json", "text/xml"]
|
26
27
|
}
|
27
28
|
]
|
28
29
|
}
|
@@ -187,7 +188,8 @@ describe Swagger::Docs::ApiDeclarationFile do
|
|
187
188
|
],
|
188
189
|
"notes"=>"Only the given fields are updated.",
|
189
190
|
"method"=>:put,
|
190
|
-
"nickname"=>"Api::V1::Sample#update"
|
191
|
+
"nickname"=>"Api::V1::Sample#update",
|
192
|
+
"consumes"=>["application/json", "text/xml"]
|
191
193
|
}
|
192
194
|
]
|
193
195
|
}
|
@@ -28,4 +28,12 @@ describe Swagger::Docs::Config do
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
+
describe "::base_applications" do
|
32
|
+
before(:each) { allow( subject ).to receive(:base_application).and_return(:app) }
|
33
|
+
it "defaults to Rails.application an an Array" do
|
34
|
+
expect(subject.base_applications).to eq [:app]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
|
31
39
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Swagger::Docs::SwaggerDSL do
|
4
|
+
|
5
|
+
subject { described_class.new() }
|
6
|
+
|
7
|
+
describe "#response" do
|
8
|
+
it "adds code, responseModel and message to response_messages" do
|
9
|
+
subject.response(:success, "Some sample text", "Tag")
|
10
|
+
expect(subject.response_messages).to eq([{:code=>500, :responseModel=>"Tag", :message=>"Some sample text"}])
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
@@ -11,21 +11,23 @@ describe Swagger::Docs::Generator do
|
|
11
11
|
end
|
12
12
|
|
13
13
|
let(:routes) {[
|
14
|
-
stub_route("^GET$",
|
15
|
-
stub_route("^GET$",
|
16
|
-
|
17
|
-
stub_route("^
|
18
|
-
stub_route("^
|
19
|
-
stub_route("^
|
20
|
-
stub_route("^
|
21
|
-
stub_route("^
|
22
|
-
stub_route("^GET$",
|
23
|
-
stub_route("^GET$",
|
14
|
+
stub_route( "^GET$", "index", "api/v1/ignored", "/api/v1/ignored(.:format)"),
|
15
|
+
stub_route( "^GET$", "index", "api/v1/sample", "/api/v1/sample(.:format)"),
|
16
|
+
stub_string_verb_route("GET", "index", "api/v1/nested", "/api/v1/nested/:nested_id/nested_sample(.:format)"),
|
17
|
+
stub_route( "^PATCH$", "create", "api/v1/sample", "/api/v1/sample(.:format)"),
|
18
|
+
stub_route( "^PUT$", "create", "api/v1/sample", "/api/v1/sample(.:format)"), # intentional duplicate of above route to ensure PATCH is used
|
19
|
+
stub_route( "^GET$", "show", "api/v1/sample", "/api/v1/sample/:id(.:format)"),
|
20
|
+
stub_route( "^PUT$", "update", "api/v1/sample", "/api/v1/sample/:id(.:format)"),
|
21
|
+
stub_route( "^DELETE$", "destroy", "api/v1/sample", "/api/v1/sample/:id(.:format)"),
|
22
|
+
stub_route( "^GET$", "new", "api/v1/sample", "/api/v1/sample/new(.:format)"), # no parameters for this method
|
23
|
+
stub_route( "^GET$", "index", "", "/api/v1/empty_path"), # intentional empty path should not cause any errors
|
24
|
+
stub_route( "^GET$", "ignored", "api/v1/sample", "/api/v1/ignored(.:format)") # an action without documentation should not cause any errors
|
24
25
|
]}
|
25
26
|
|
26
27
|
let(:tmp_dir) { Pathname.new('/tmp/swagger-docs/') }
|
27
28
|
let(:file_resources) { tmp_dir + 'api-docs.json' }
|
28
29
|
let(:file_resource) { tmp_dir + 'api/v1/sample.json' }
|
30
|
+
let(:file_resource_nested) { tmp_dir + 'nested.json' }
|
29
31
|
|
30
32
|
context "without controller base path" do
|
31
33
|
let(:config) {
|
@@ -65,7 +67,7 @@ describe Swagger::Docs::Generator do
|
|
65
67
|
expect(response["resourcePath"]).to eq "sample"
|
66
68
|
end
|
67
69
|
it "writes out expected api count" do
|
68
|
-
expect(response["apis"].count).to eq
|
70
|
+
expect(response["apis"].count).to eq 6
|
69
71
|
end
|
70
72
|
context "first api" do
|
71
73
|
#"apis":[{"path":" /sample","operations":[{"summary":"Fetches all User items"
|
@@ -79,13 +81,25 @@ describe Swagger::Docs::Generator do
|
|
79
81
|
|
80
82
|
context "with controller base path" do
|
81
83
|
let(:config) { Swagger::Docs::Config.register_apis({
|
82
|
-
DEFAULT_VER => {:controller_base_path => "api/v1", :api_file_path => "#{tmp_dir}", :base_path => "http://api.no.where"
|
84
|
+
DEFAULT_VER => {:controller_base_path => "api/v1", :api_file_path => "#{tmp_dir}", :base_path => "http://api.no.where",
|
85
|
+
:attributes => {
|
86
|
+
:info => {
|
87
|
+
"title" => "Swagger Sample App",
|
88
|
+
"description" => "This is a sample description.",
|
89
|
+
"termsOfServiceUrl" => "http://helloreverb.com/terms/",
|
90
|
+
"contact" => "apiteam@wordnik.com",
|
91
|
+
"license" => "Apache 2.0",
|
92
|
+
"licenseUrl" => "http://www.apache.org/licenses/LICENSE-2.0.html"
|
93
|
+
}
|
94
|
+
}
|
95
|
+
}
|
83
96
|
})}
|
84
97
|
let(:file_resource) { tmp_dir + 'sample.json' }
|
85
98
|
before(:each) do
|
86
99
|
allow(Rails).to receive_message_chain(:application, :routes, :routes).and_return(routes)
|
87
100
|
Swagger::Docs::Generator.set_real_methods
|
88
101
|
require "fixtures/controllers/sample_controller"
|
102
|
+
require "fixtures/controllers/nested_controller"
|
89
103
|
end
|
90
104
|
|
91
105
|
context "test suite initialization" do
|
@@ -104,12 +118,31 @@ describe Swagger::Docs::Generator do
|
|
104
118
|
end
|
105
119
|
it "generates using default config" do
|
106
120
|
results = generate({})
|
107
|
-
expect(results[DEFAULT_VER][:processed].count).to eq
|
121
|
+
expect(results[DEFAULT_VER][:processed].count).to eq 2
|
108
122
|
end
|
109
123
|
end
|
110
124
|
before(:each) do
|
111
125
|
generate(config)
|
112
126
|
end
|
127
|
+
context "api-docs resources file" do
|
128
|
+
it "writes the file" do
|
129
|
+
expect(file_resources).to exist
|
130
|
+
end
|
131
|
+
context "custom user attributes" do
|
132
|
+
let(:parsed_resources) {
|
133
|
+
JSON.parse(File.read file_resources)
|
134
|
+
}
|
135
|
+
it "it has info hash" do
|
136
|
+
expect(parsed_resources.keys).to include("info")
|
137
|
+
end
|
138
|
+
it "has title field" do
|
139
|
+
expect(parsed_resources["info"]["title"]).to eq "Swagger Sample App"
|
140
|
+
end
|
141
|
+
it "has description field" do
|
142
|
+
expect(parsed_resources["info"]["description"]).to eq "This is a sample description."
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
113
146
|
it "cleans json files in directory when set" do
|
114
147
|
file_to_delete = Pathname.new(File.join(config['1.0'][:api_file_path], 'delete_me.json'))
|
115
148
|
File.open(file_to_delete, 'w') {|f| f.write("{}") }
|
@@ -125,15 +158,12 @@ describe Swagger::Docs::Generator do
|
|
125
158
|
generate(config)
|
126
159
|
expect(file_to_keep).to exist
|
127
160
|
end
|
128
|
-
it "writes the resources file" do
|
129
|
-
expect(file_resources).to exist
|
130
|
-
end
|
131
161
|
it "writes the resource file" do
|
132
162
|
expect(file_resource).to exist
|
133
163
|
end
|
134
164
|
it "returns results hash" do
|
135
165
|
results = generate(config)
|
136
|
-
expect(results[DEFAULT_VER][:processed].count).to eq
|
166
|
+
expect(results[DEFAULT_VER][:processed].count).to eq 2
|
137
167
|
expect(results[DEFAULT_VER][:skipped].count).to eq 1
|
138
168
|
end
|
139
169
|
it "writes pretty json files when set" do
|
@@ -155,7 +185,7 @@ describe Swagger::Docs::Generator do
|
|
155
185
|
expect(response["basePath"]).to eq "http://api.no.where/api/v1/"
|
156
186
|
end
|
157
187
|
it "writes apis correctly" do
|
158
|
-
expect(response["apis"].count).to eq
|
188
|
+
expect(response["apis"].count).to eq 2
|
159
189
|
end
|
160
190
|
it "writes api path correctly" do
|
161
191
|
expect(response["apis"][0]["path"]).to eq "sample.{format}"
|
@@ -164,7 +194,23 @@ describe Swagger::Docs::Generator do
|
|
164
194
|
expect(response["apis"][0]["description"]).to eq "User Management"
|
165
195
|
end
|
166
196
|
end
|
167
|
-
context "resource file" do
|
197
|
+
context "nested resource file" do
|
198
|
+
let(:resource) { file_resource_nested.read }
|
199
|
+
let(:response) { JSON.parse(resource) }
|
200
|
+
let(:apis) { response["apis"] }
|
201
|
+
context "apis" do
|
202
|
+
context "show" do
|
203
|
+
let(:api) { get_api_operation(apis, "nested/{nested_id}/nested_sample", :get) }
|
204
|
+
let(:operations) { get_api_operations(apis, "nested/{nested_id}/nested_sample") }
|
205
|
+
context "parameters" do
|
206
|
+
it "has correct count" do
|
207
|
+
expect(api["parameters"].count).to eq 2
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
context "sample resource file" do
|
168
214
|
let(:resource) { file_resource.read }
|
169
215
|
let(:response) { JSON.parse(resource) }
|
170
216
|
let(:apis) { response["apis"] }
|
@@ -182,7 +228,7 @@ describe Swagger::Docs::Generator do
|
|
182
228
|
expect(response["resourcePath"]).to eq "sample"
|
183
229
|
end
|
184
230
|
it "writes out expected api count" do
|
185
|
-
expect(response["apis"].count).to eq
|
231
|
+
expect(response["apis"].count).to eq 6
|
186
232
|
end
|
187
233
|
describe "context dependent documentation" do
|
188
234
|
after(:each) do
|
@@ -226,6 +272,9 @@ describe Swagger::Docs::Generator do
|
|
226
272
|
it "writes nickname correctly" do
|
227
273
|
expect(operations.first["nickname"]).to eq "Api::V1::Sample#index"
|
228
274
|
end
|
275
|
+
it "writes responseModel attribute" do
|
276
|
+
expect(api["responseMessages"].find{|m| m["responseModel"] == "Tag"}).to_not be_nil
|
277
|
+
end
|
229
278
|
#"parameters"=>[
|
230
279
|
# {"paramType"=>"query", "name"=>"page", "type"=>"integer", "description"=>"Page number", "required"=>false},
|
231
280
|
# {"paramType"=>"path", "name"=>"nested_id", "type"=>"integer", "description"=>"Team Id", "required"=>false}], "responseMessages"=>[{"code"=>401, "message"=>"Unauthorized"}, {"code"=>406, "message"=>"The request you made is not acceptable"}, {"code"=>416, "message"=>"Requested Range Not Satisfiable"}], "method"=>"get", "nickname"=>"Api::V1::Sample#index"}
|
@@ -252,7 +301,7 @@ describe Swagger::Docs::Generator do
|
|
252
301
|
end
|
253
302
|
end
|
254
303
|
context "list parameter" do
|
255
|
-
let(:api) { get_api_operation(apis, "sample", :
|
304
|
+
let(:api) { get_api_operation(apis, "sample", :patch) }
|
256
305
|
let(:params) {api["parameters"] }
|
257
306
|
it "writes description correctly" do
|
258
307
|
expect(params[3]["description"]).to eq "Role"
|
@@ -262,7 +311,7 @@ describe Swagger::Docs::Generator do
|
|
262
311
|
context "response messages" do
|
263
312
|
let(:response_msgs) { operations.first["responseMessages"] }
|
264
313
|
it "has correct count" do
|
265
|
-
expect(response_msgs.count).to eq
|
314
|
+
expect(response_msgs.count).to eq 4
|
266
315
|
end
|
267
316
|
it "writes code correctly" do
|
268
317
|
expect(response_msgs.first["code"]).to eq 401
|
@@ -275,20 +324,18 @@ describe Swagger::Docs::Generator do
|
|
275
324
|
end
|
276
325
|
end
|
277
326
|
end
|
278
|
-
context "show" do
|
279
|
-
let(:api) { get_api_operation(apis, "nested/{nested_id}/sample", :get) }
|
280
|
-
let(:operations) { get_api_operations(apis, "nested/{nested_id}/sample") }
|
281
|
-
context "parameters" do
|
282
|
-
it "has correct count" do
|
283
|
-
expect(api["parameters"].count).to eq 2
|
284
|
-
end
|
285
|
-
end
|
286
|
-
end
|
287
327
|
context "create" do
|
288
|
-
let(:api) { get_api_operation(apis, "sample", :
|
328
|
+
let(:api) { get_api_operation(apis, "sample", :patch) }
|
289
329
|
it "writes list parameter values correctly" do
|
290
330
|
expected_param = {"valueType"=>"LIST", "values"=>["admin", "superadmin", "user"]}
|
331
|
+
expected_body = {"paramType"=>"body", "name"=>"body", "type"=>"json", "description"=>"JSON formatted body", "required"=>true}
|
332
|
+
expected_consumes = ["application/json", "text/xml"]
|
291
333
|
expect(get_api_parameter(api, "role")["allowableValues"]).to eq expected_param
|
334
|
+
expect(get_api_parameter(api, "body")).to eq expected_body
|
335
|
+
expect(api["consumes"]).to eq ["application/json", "text/xml"]
|
336
|
+
end
|
337
|
+
it "doesn't write out route put method" do
|
338
|
+
expect(get_api_operation(apis, "sample", :put)).to be_nil
|
292
339
|
end
|
293
340
|
end
|
294
341
|
context "update" do
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Swagger::Docs::Methods do
|
4
|
+
|
5
|
+
describe "#swagger_actions" do
|
6
|
+
it "merges additional configuration parameters into dsl" do
|
7
|
+
methods = Object.new
|
8
|
+
methods.extend(Swagger::Docs::Methods::ClassMethods)
|
9
|
+
methods.swagger_api("test", {produces: [ "application/json" ], consumes: [ "multipart/form-data" ]}) do
|
10
|
+
end
|
11
|
+
expect(methods.swagger_actions()).to eq({"test"=>{:produces=>["application/json"], :consumes=>["multipart/form-data"]}})
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -21,6 +21,13 @@ def generate(config)
|
|
21
21
|
Swagger::Docs::Generator::write_docs(config)
|
22
22
|
end
|
23
23
|
|
24
|
+
def stub_string_verb_route(verb, action, controller, spec)
|
25
|
+
double("route", :verb => verb,
|
26
|
+
:defaults => {:action => action, :controller => controller},
|
27
|
+
:path => spec
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
24
31
|
def stub_route(verb, action, controller, spec)
|
25
32
|
double("route", :verb => double("verb", :source => verb),
|
26
33
|
:defaults => {:action => action, :controller => controller},
|
@@ -40,8 +47,10 @@ end
|
|
40
47
|
def get_api_operation(apis, path, method)
|
41
48
|
operations = get_api_operations(apis, path)
|
42
49
|
operations.each{|operation| return operation if operation["method"] == method.to_s}
|
50
|
+
nil
|
43
51
|
end
|
44
52
|
|
45
53
|
def get_api_parameter(api, name)
|
46
54
|
api["parameters"].each{|param| return param if param["name"] == name}
|
55
|
+
nil
|
47
56
|
end
|
data/swagger-docs.gemspec
CHANGED
@@ -25,6 +25,8 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_development_dependency "bundler", "~> 1.3"
|
26
26
|
spec.add_development_dependency "rake", "~> 10"
|
27
27
|
spec.add_development_dependency "rspec", "~> 3"
|
28
|
-
spec.add_development_dependency "active_support", "~> 3"
|
29
28
|
spec.add_development_dependency "appraisal", "~> 1"
|
29
|
+
|
30
|
+
spec.add_runtime_dependency "rails", ">= 3","< 5"
|
31
|
+
spec.add_runtime_dependency "activesupport", ">= 3","< 5"
|
30
32
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: swagger-docs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rich Hollis
|
@@ -30,7 +30,7 @@ cert_chain:
|
|
30
30
|
RYcsqDfanYBx7QcftOnbeQq7/Ep7Zx+W9+Ph3TiJLMLdAr7bLkgN1SjvrjTL5mQR
|
31
31
|
FuQtYvE4LKiUQpG7vLTRB78dQBlSj9fnv2OM9w==
|
32
32
|
-----END CERTIFICATE-----
|
33
|
-
date: 2014-
|
33
|
+
date: 2014-09-10 00:00:00.000000000 Z
|
34
34
|
dependencies:
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
36
|
name: bundler
|
@@ -75,33 +75,59 @@ dependencies:
|
|
75
75
|
- !ruby/object:Gem::Version
|
76
76
|
version: '3'
|
77
77
|
- !ruby/object:Gem::Dependency
|
78
|
-
name:
|
78
|
+
name: appraisal
|
79
79
|
requirement: !ruby/object:Gem::Requirement
|
80
80
|
requirements:
|
81
81
|
- - "~>"
|
82
82
|
- !ruby/object:Gem::Version
|
83
|
-
version: '
|
83
|
+
version: '1'
|
84
84
|
type: :development
|
85
85
|
prerelease: false
|
86
86
|
version_requirements: !ruby/object:Gem::Requirement
|
87
87
|
requirements:
|
88
88
|
- - "~>"
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '1'
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: rails
|
93
|
+
requirement: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
89
96
|
- !ruby/object:Gem::Version
|
90
97
|
version: '3'
|
98
|
+
- - "<"
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '5'
|
101
|
+
type: :runtime
|
102
|
+
prerelease: false
|
103
|
+
version_requirements: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '3'
|
108
|
+
- - "<"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '5'
|
91
111
|
- !ruby/object:Gem::Dependency
|
92
|
-
name:
|
112
|
+
name: activesupport
|
93
113
|
requirement: !ruby/object:Gem::Requirement
|
94
114
|
requirements:
|
95
|
-
- - "
|
115
|
+
- - ">="
|
96
116
|
- !ruby/object:Gem::Version
|
97
|
-
version: '
|
98
|
-
|
117
|
+
version: '3'
|
118
|
+
- - "<"
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '5'
|
121
|
+
type: :runtime
|
99
122
|
prerelease: false
|
100
123
|
version_requirements: !ruby/object:Gem::Requirement
|
101
124
|
requirements:
|
102
|
-
- - "
|
125
|
+
- - ">="
|
103
126
|
- !ruby/object:Gem::Version
|
104
|
-
version: '
|
127
|
+
version: '3'
|
128
|
+
- - "<"
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '5'
|
105
131
|
description: Generates json files for rails apps to use with swagger-ui
|
106
132
|
email:
|
107
133
|
- richhollis@gmail.com
|
@@ -130,11 +156,14 @@ files:
|
|
130
156
|
- lib/tasks/swagger.rake
|
131
157
|
- spec/fixtures/controllers/application_controller.rb
|
132
158
|
- spec/fixtures/controllers/ignored_controller.rb
|
159
|
+
- spec/fixtures/controllers/nested_controller.rb
|
133
160
|
- spec/fixtures/controllers/sample_controller.rb
|
134
161
|
- spec/lib/swagger/docs/api_declaration_file_metadata_spec.rb
|
135
162
|
- spec/lib/swagger/docs/api_declaration_file_spec.rb
|
136
163
|
- spec/lib/swagger/docs/config_spec.rb
|
164
|
+
- spec/lib/swagger/docs/dsl_spec.rb
|
137
165
|
- spec/lib/swagger/docs/generator_spec.rb
|
166
|
+
- spec/lib/swagger/docs/methods.rb
|
138
167
|
- spec/spec_helper.rb
|
139
168
|
- swagger-docs.gemspec
|
140
169
|
homepage: https://github.com/richhollis/swagger-docs
|
@@ -165,9 +194,12 @@ summary: Generates swagger-ui json files for rails apps with APIs. You add the s
|
|
165
194
|
test_files:
|
166
195
|
- spec/fixtures/controllers/application_controller.rb
|
167
196
|
- spec/fixtures/controllers/ignored_controller.rb
|
197
|
+
- spec/fixtures/controllers/nested_controller.rb
|
168
198
|
- spec/fixtures/controllers/sample_controller.rb
|
169
199
|
- spec/lib/swagger/docs/api_declaration_file_metadata_spec.rb
|
170
200
|
- spec/lib/swagger/docs/api_declaration_file_spec.rb
|
171
201
|
- spec/lib/swagger/docs/config_spec.rb
|
202
|
+
- spec/lib/swagger/docs/dsl_spec.rb
|
172
203
|
- spec/lib/swagger/docs/generator_spec.rb
|
204
|
+
- spec/lib/swagger/docs/methods.rb
|
173
205
|
- spec/spec_helper.rb
|
metadata.gz.sig
CHANGED
@@ -1 +1,4 @@
|
|
1
|
-
�
|
1
|
+
Y�(
|
2
|
+
Q�~屗2(0P�ރY��V�E������H��$"��^���/�Zޱ�dVW9���[�K~Q�hs=/�Hrp�I)'I�R.�r�7<�Wc����(�<n:��?w������D��ҤV�w�]p��G��'3���)�|cn|�7�)���ǂA�nE+נ�-J�H$4q��*�����
|
3
|
+
q]�No�� �u�whC:_����5�l�Q�k��>
|
4
|
+
P!.��GA�c����u;+���Rrp����&|��
|