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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bf18b79ce15cb8436f59367c1ece509850b4f671
4
- data.tar.gz: cd5ee26cc156d613d0e1446a9a7744b112d421ef
3
+ metadata.gz: 9c266ba841a5bdacb059df2348ef839408bb1b8b
4
+ data.tar.gz: 85475fb831183dded5e7ed8b858e9c2df590350f
5
5
  SHA512:
6
- metadata.gz: a25491571a345ecdb99060f71b5ed468275901ce3b9099339eecd146a3ac300b883d96c465a7d64804ac687d58f1bf6843cbe353b1ff20f5fe6af53b71ec01b0
7
- data.tar.gz: ff752bfbb69eec66ada69efdeebf46c6e648a17f67345a7d8a8689bf69fbe15d918a7155270bdfeddb2c2356bc0f75f6bba8bea5d7530631f2e49d266ac6444d
6
+ metadata.gz: d5919f6cdf9462d5074db8e1749e4ef518dec92e08148de8f005ce518b7b0c90b0fefe40f638997cff400ca27f1b78af23b87b1944989503cf461c4987130509
7
+ data.tar.gz: 5511929b22b9b62174cacbe09ac160763337ccd600a2fb75b634445e29cbaba23ffce392fac3181ada7b38f7e6a3cb323e442533145277140faba98aeb768437
@@ -1 +1,2 @@
1
- �Z�;��9z1����_Q�%�� ����Sj3�8�1�5�DǢ\����D�Hm�ͳ���N4),zi�?} �ٟ��.�.�:�M&�ˣDYW��D�e���ΰA^��[MÀ����n��qW���' BO�d��UR� iF�� ��2� �����$����2-���3@(��� �Xmր�R�oJ����Bq�S50�*:C�B��L�҆ޮ6�8@�z]U�S���Ł>l���ryM����ZǕ�/D��
1
+ +�B�;=Ї0��-g�ӥ�x���޸�[}�`0yM��"���fxMZ-%9�^�vk S�Fb{7��
2
+ )'�|�>��U��f *��������C��j {�=O:���╬~a��ĩ`ۧo���w����URR��k�M6�4���8�x K�����u�;|��
data.tar.gz.sig CHANGED
@@ -1 +1,3 @@
1
- ���6^���y����R�]@H�`{)j���G����O���@���i�z! k�"c��qE����u���XYG����1-"�c���4�}���qL)�f�Fu�o�%x^H���$��R���؈g�e(��o� � �rd 0�x���x�� ��[>&1Yϟ�+凯
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��
@@ -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.
@@ -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
@@ -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
- Config.base_application.routes.routes.select{|i| i.defaults[:controller] == path}.each do |route|
128
- ret = get_route_path_apis(path, route, klass, settings, config)
129
- apis = apis + ret[:apis]
130
- models.merge!(ret[:models])
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.verb.source.to_s.delete('$'+'^').downcase.to_sym
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] = "#{path.camelize}##{action}"
177
+ nickname = operations[:nickname] = path_route_nickname(path, route)
152
178
 
153
- api_path = transform_spec_to_api_path(route.path.spec, settings[:controller_base_path], config[:api_extension_type])
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 = Config.base_application.routes.routes.map{|i| "#{i.defaults[:controller]}" }
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
 
@@ -9,7 +9,7 @@ module Swagger
9
9
  module ClassMethods
10
10
  private
11
11
 
12
- def swagger_api(action, &block)
12
+ def swagger_api(action, params = {}, &block)
13
13
  end
14
14
 
15
15
  def swagger_model(model_name, &block)
@@ -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
- private
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)
@@ -1,5 +1,5 @@
1
1
  module Swagger
2
2
  module Docs
3
- VERSION = "0.1.8"
3
+ VERSION = "0.1.9"
4
4
  end
5
5
  end
@@ -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$", "index", "api/v1/ignored", "/api/v1/ignored(.:format)"),
15
- stub_route("^GET$", "index", "api/v1/sample", "/api/v1/sample(.:format)"),
16
- stub_route("^GET$", "index", "api/v1/sample", "/api/v1/nested/:nested_id/sample(.:format)"),
17
- stub_route("^POST$", "create", "api/v1/sample", "/api/v1/sample(.:format)"),
18
- stub_route("^GET$", "show", "api/v1/sample", "/api/v1/sample/:id(.:format)"),
19
- stub_route("^PUT$", "update", "api/v1/sample", "/api/v1/sample/:id(.:format)"),
20
- stub_route("^DELETE$", "destroy", "api/v1/sample", "/api/v1/sample/:id(.:format)"),
21
- stub_route("^GET$", "new", "api/v1/sample", "/api/v1/sample/new(.:format)"), # no parameters for this method
22
- stub_route("^GET$", "index", "", "/api/v1/empty_path"), # intentional empty path should not cause any errors
23
- stub_route("^GET$", "ignored", "api/v1/sample", "/api/v1/ignored(.:format)") # an action without documentation should not cause any errors
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 7
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 1
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 1
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 1
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 7
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", :post) }
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 3
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", :post) }
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
@@ -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
@@ -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.8
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-06-23 00:00:00.000000000 Z
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: active_support
78
+ name: appraisal
79
79
  requirement: !ruby/object:Gem::Requirement
80
80
  requirements:
81
81
  - - "~>"
82
82
  - !ruby/object:Gem::Version
83
- version: '3'
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: appraisal
112
+ name: activesupport
93
113
  requirement: !ruby/object:Gem::Requirement
94
114
  requirements:
95
- - - "~>"
115
+ - - ">="
96
116
  - !ruby/object:Gem::Version
97
- version: '1'
98
- type: :development
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: '1'
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
- _T���գE3�y%}�h���!���X�t��kuH"ݒh0gS&%�X-A���,���4.�e�;��:�tY�Hz�6�1L�_=N���`��#����%�dmL�Y���>�\)��SF_Er2~��khCB���֯~�R���
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����&|��