swagger-docs 0.1.8 → 0.1.9
Sign up to get free protection for your applications and to get access to all the features.
- 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 Version](https://badge.fury.io/rb/swagger-docs.png)][gem]
|
6
|
+
[![Dependency Status](https://gemnasium.com/richhollis/swagger-docs.png?travis)][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����&|��
|