swagger-docs 0.0.2 → 0.0.3

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: 8288447cb546d04ee3e791e473f06351c1f9e702
4
- data.tar.gz: cf69d2574759663cdccb895d4c320c0b085fa0e4
3
+ metadata.gz: 93662e19d54d8714102ecfbd08e1ca88e360cd00
4
+ data.tar.gz: 646f03361ada42fc36e8369bc602e00307b86b0d
5
5
  SHA512:
6
- metadata.gz: 0cfdeb3b6ffc0c27f2306739d7831496c65c480efd54ad583923b5c0d1a5e6aa12643f55e59ffe4797e71b87f7d29fdba49c8f5d866f167906cc1e113f4be7a1
7
- data.tar.gz: aa89d0b6b9cac77cd1b9ab5e952b89ce3c85bed99fdc0933e891ba9bcf633180ffc72e6e1ba82e1dfbb197fdb261efafbdc66970f83dbfe474073894716aa6f2
6
+ metadata.gz: 868a3e56fc30ccee2ee8e636ab800d21398f4d5f4b0d8bf7867a302471e9c66841841a2332159f4e61a8311852b6bf9d437ff6135d685d60e6f04abedc0d2aad
7
+ data.tar.gz: 709e92e1acbee458adfd53facc2f2be17308f6dfca0bfd7a6213eceb232d447686e8aea79d16a7d4e3e4f2e8c874e1b8a23ed2e6e052f6980cfefe44acfa0008
checksums.yaml.gz.sig CHANGED
Binary file
data.tar.gz.sig CHANGED
Binary file
data/README.md CHANGED
@@ -38,14 +38,18 @@ Create an initializer in config/initializers (e.g. swagger_docs.rb) and define y
38
38
 
39
39
  ```
40
40
  Swagger::Docs::Config.register_apis({
41
- "1.0" => {:controller_base_path => "api/v1", :api_file_path => "public/api/v1/", :base_path => "http://api.somedomain.com"}
42
- })
41
+ "1.0" => {
42
+ :api_file_path => "public/api/v1/", # the output location where your .json files are written to
43
+ :base_path => "http://api.somedomain.com", # the URL base path to your API
44
+ :clean_directory => false # if you want to delete all .json files at each generation
45
+ }
46
+ )
43
47
  ```
44
48
 
45
49
  ### Documenting a controller
46
50
 
47
51
  ```
48
- class Api::V1::UsersController < ApiController
52
+ class Api::V1::UsersController < ApplicationController
49
53
 
50
54
  swagger_controller :users, "User Management"
51
55
 
@@ -101,7 +105,15 @@ end
101
105
  rake swagger:docs
102
106
  ```
103
107
 
104
- ### Swagger-ui JSON files should now be present in your api_file_path (e.g. ./public/api/v1)
108
+ Swagger-ui JSON files should now be present in your api_file_path (e.g. ./public/api/v1)
109
+
110
+ ### Sample
111
+
112
+ A sample Rails application where you can run the above rake command and view the output in swagger-ui can be found here:
113
+
114
+ https://github.com/richhollis/swagger-docs-sample
115
+
116
+ ### Output files
105
117
 
106
118
  api-docs.json output:
107
119
 
@@ -18,7 +18,7 @@ module Swagger
18
18
  end
19
19
 
20
20
  def get_api_path(spec)
21
- path_api = spec.to_s.gsub("(.:format)", "")
21
+ path_api = trim_leading_slash(spec.to_s.gsub("(.:format)", ""))
22
22
  parts_new = []
23
23
  path_api.split("/").each do |path_part|
24
24
  part = path_part
@@ -31,6 +31,22 @@ module Swagger
31
31
  path_api = parts_new*"/"
32
32
  end
33
33
 
34
+ def trim_leading_slash(str)
35
+ return str if !str
36
+ return str unless str[0] == '/'
37
+ str[1..-1]
38
+ end
39
+
40
+ def trim_trailing_slash(str)
41
+ return str if !str
42
+ return str unless str[-1] == '/'
43
+ str[0..-2]
44
+ end
45
+
46
+ def trim_slashes(str)
47
+ trim_leading_slash(trim_trailing_slash(str))
48
+ end
49
+
34
50
  def set_real_methods
35
51
  ApplicationController.send(:include, Methods) # replace impotent methods with live ones
36
52
  end
@@ -38,33 +54,44 @@ module Swagger
38
54
  def write_docs(apis)
39
55
  results = {}
40
56
  set_real_methods
41
- Config.registered_apis.each do |api_version,config|
42
- results[api_version] = write_doc(api_version, config)
57
+ unless Config.registered_apis.empty?
58
+ Config.registered_apis.each do |api_version,config|
59
+ results[api_version] = write_doc(api_version, config)
60
+ end
61
+ else
62
+ config = {:api_file_path => "public/", :base_path => "/"}
63
+ puts "No swagger_docs config: Using default config #{config}"
64
+ results["1.0"] = write_doc("1.0", config)
43
65
  end
44
66
  results
45
67
  end
46
68
 
47
69
  def write_doc(api_version, config)
48
- base_path = config[:base_path]
49
- controller_base_path = config[:controller_base_path]
70
+ base_path = trim_trailing_slash(config[:base_path] || "")
71
+ controller_base_path = trim_leading_slash(config[:controller_base_path] || "")
50
72
  api_file_path = config[:api_file_path]
73
+ clean_directory = config[:clean_directory] || false
51
74
  results = {:processed => [], :skipped => []}
52
75
 
76
+ # create output paths
53
77
  FileUtils.mkdir_p(api_file_path) # recursively create out output path
54
- Dir.foreach(api_file_path) {|f| fn = File.join(api_file_path, f); File.delete(fn) if !File.directory?(fn)} # clean output path
78
+ Dir.foreach(api_file_path) {|f| fn = File.join(api_file_path, f); File.delete(fn) if !File.directory?(fn) and File.extname(fn) == '.json'} if clean_directory # clean output path
55
79
 
56
- header = { :api_version => api_version, :swagger_version => "1.2", :base_path => "#{base_path}/#{controller_base_path}"}
80
+ base_path += "/#{controller_base_path}" unless controller_base_path.empty?
81
+ header = { :api_version => api_version, :swagger_version => "1.2", :base_path => base_path + "/"}
57
82
  resources = header.merge({:apis => []})
58
83
 
59
84
  paths = Rails.application.routes.routes.map{|i| "#{i.defaults[:controller]}" }
60
85
  paths = paths.uniq.select{|i| i.start_with?(controller_base_path)}
61
86
  paths.each do |path|
87
+ next if path.empty?
62
88
  klass = "#{path.to_s.camelize}Controller".constantize
63
89
  if !klass.methods.include?(:swagger_config) or !klass.swagger_config[:controller]
64
90
  results[:skipped] << path
65
91
  next
66
92
  end
67
93
  apis = []
94
+ debased_path = path.gsub("#{controller_base_path}", "")
68
95
  Rails.application.routes.routes.select{|i| i.defaults[:controller] == path}.each do |route|
69
96
  action = route.defaults[:action]
70
97
  verb = route.verb.source.to_s.delete('$'+'^').downcase.to_sym
@@ -72,20 +99,20 @@ module Swagger
72
99
  operations = Hash[operations.map {|k, v| [k.to_s.gsub("@","").to_sym, v] }] # rename :@instance hash keys
73
100
  operations[:method] = verb
74
101
  operations[:nickname] = "#{path.camelize}##{action}"
75
- apis << {:path => get_api_path(route.path.spec).gsub("/#{controller_base_path}",""), :operations => [operations]}
102
+ apis << {:path => trim_slashes(get_api_path(trim_leading_slash(route.path.spec.to_s)).gsub("#{controller_base_path}","")), :operations => [operations]}
76
103
  end
77
- demod = "#{path.to_s.camelize}".demodulize.camelize.underscore
78
- resource = header.merge({:resource_path => "/#{demod}", :apis => apis})
104
+ demod = "#{debased_path.to_s.camelize}".demodulize.camelize.underscore
105
+ resource = header.merge({:resource_path => "#{demod}", :apis => apis})
79
106
  camelize_keys_deep!(resource)
80
107
  # write controller resource file
81
- File.open("#{api_file_path}#{demod}.json", 'w') { |file| file.write(resource.to_json) }
108
+ File.open("#{api_file_path}/#{demod}.json", 'w') { |file| file.write(resource.to_json) }
82
109
  # append resource to resources array (for writing out at end)
83
- resources[:apis] << {path: "/#{demod}.{format}", description: klass.swagger_config[:description]}
110
+ resources[:apis] << {path: "#{trim_leading_slash(debased_path)}.{format}", description: klass.swagger_config[:description]}
84
111
  results[:processed] << path
85
112
  end
86
113
  # write master resource file
87
114
  camelize_keys_deep!(resources)
88
- File.open("#{api_file_path}api-docs.json", 'w') { |file| file.write(resources.to_json) }
115
+ File.open("#{api_file_path}/api-docs.json", 'w') { |file| file.write(resources.to_json) }
89
116
  results
90
117
  end
91
118
  end
@@ -1,5 +1,5 @@
1
1
  module Swagger
2
2
  module Docs
3
- VERSION = "0.0.2"
3
+ VERSION = "0.0.3"
4
4
  end
5
5
  end
@@ -5,6 +5,10 @@ describe Swagger::Docs::Generator do
5
5
  require "fixtures/controllers/application_controller"
6
6
  require "fixtures/controllers/ignored_controller"
7
7
 
8
+ def generate(config)
9
+ Swagger::Docs::Generator::write_docs(config)
10
+ end
11
+
8
12
  def stub_route(verb, action, controller, spec)
9
13
  double("route", :verb => double("verb", :source => verb),
10
14
  :defaults => {:action => action, :controller => controller},
@@ -14,67 +18,38 @@ describe Swagger::Docs::Generator do
14
18
 
15
19
  before(:each) do
16
20
  FileUtils.rm_rf(TMP_DIR)
17
- routes = [
18
- stub_route("^GET$", "index", "api/v1/ignored", "/api/v1/ignored(.:format)"),
19
- stub_route("^GET$", "index", "api/v1/sample", "/api/v1/sample(.:format)"),
20
- stub_route("^POST$", "create", "api/v1/sample", "/api/v1/sample(.:format)"),
21
- stub_route("^GET$", "show", "api/v1/sample", "/api/v1/sample/:id(.:format)"),
22
- stub_route("^PUT$", "update", "api/v1/sample", "/api/v1/sample/:id(.:format)"),
23
- stub_route("^DELETE$", "destroy", "api/v1/sample", "/api/v1/sample/:id(.:format)")
24
- ]
25
- @config = Swagger::Docs::Config.register_apis({
26
- "1.0" => {:controller_base_path => "api/v1", :api_file_path => "#{TMP_DIR}api/v1/", :base_path => "http://api.no.where"}
27
- })
28
- Rails.stub_chain(:application, :routes, :routes).and_return(routes)
29
- Swagger::Docs::Generator.set_real_methods
30
- require "fixtures/controllers/sample_controller"
31
21
  end
32
22
 
33
- context "test suite initialization" do
34
- it "the resources file does not exist" do
35
- expect(File.exists?(FILE_RESOURCES)).to be_false
36
- end
37
- it "the resource file does not exist" do
38
- expect(File.exists?(FILE_RESOURCE)).to be_false
39
- end
40
- end
23
+ let(:routes) {[
24
+ stub_route("^GET$", "index", "api/v1/ignored", "/api/v1/ignored(.:format)"),
25
+ stub_route("^GET$", "index", "api/v1/sample", "/api/v1/sample(.:format)"),
26
+ stub_route("^POST$", "create", "api/v1/sample", "/api/v1/sample(.:format)"),
27
+ stub_route("^GET$", "show", "api/v1/sample", "/api/v1/sample/:id(.:format)"),
28
+ stub_route("^PUT$", "update", "api/v1/sample", "/api/v1/sample/:id(.:format)"),
29
+ stub_route("^DELETE$", "destroy", "api/v1/sample", "/api/v1/sample/:id(.:format)")
30
+ ]}
41
31
 
42
- describe "#write_docs" do
43
- let(:generate) { Swagger::Docs::Generator::write_docs(@config) }
32
+ context "without controller base path" do
33
+ let(:config) { Swagger::Docs::Config.register_apis({
34
+ "1.0" => {:api_file_path => "#{TMP_DIR}api/v1/", :base_path => "http://api.no.where"}
35
+ })}
44
36
  before(:each) do
45
- generate
46
- end
47
- it "writes the resources file" do
48
- expect(File.exists?(FILE_RESOURCES)).to be_true
49
- end
50
- it "writes the resource file" do
51
- expect(File.exists?(FILE_RESOURCE)).to be_true
52
- end
53
- it "returns results hash" do
54
- results = generate
55
- expect(results["1.0"][:processed].count).to eq 1
56
- expect(results["1.0"][:skipped].count).to eq 1
37
+ Rails.stub_chain(:application, :routes, :routes).and_return(routes)
38
+ Swagger::Docs::Generator.set_real_methods
39
+ require "fixtures/controllers/sample_controller"
40
+ generate(config)
57
41
  end
58
42
  context "resources files" do
59
43
  let(:resources) { File.read(FILE_RESOURCES)}
60
44
  let(:response) { JSON.parse(resources) }
61
- it "writes version correctly" do
62
- expect(response["apiVersion"]).to eq "1.0"
63
- end
64
- it "writes swaggerVersion correctly" do
65
- expect(response["swaggerVersion"]).to eq "1.2"
66
- end
67
45
  it "writes basePath correctly" do
68
- expect(response["basePath"]).to eq "http://api.no.where/api/v1"
46
+ expect(response["basePath"]).to eq "http://api.no.where/"
69
47
  end
70
48
  it "writes apis correctly" do
71
49
  expect(response["apis"].count).to eq 1
72
50
  end
73
51
  it "writes api path correctly" do
74
- expect(response["apis"][0]["path"]).to eq "/sample.{format}"
75
- end
76
- it "writes api description correctly" do
77
- expect(response["apis"][0]["description"]).to eq "User Management"
52
+ expect(response["apis"][0]["path"]).to eq "api/v1/sample.{format}"
78
53
  end
79
54
  end
80
55
  context "resource file" do
@@ -82,20 +57,12 @@ describe Swagger::Docs::Generator do
82
57
  let(:response) { JSON.parse(resource) }
83
58
  let(:first) { response["apis"].first }
84
59
  let(:operations) { first["operations"] }
85
- let(:params) { operations.first["parameters"] }
86
- let(:response_msgs) { operations.first["responseMessages"] }
87
60
  # {"apiVersion":"1.0","swaggerVersion":"1.2","basePath":"/api/v1","resourcePath":"/sample"
88
- it "writes version correctly" do
89
- expect(response["apiVersion"]).to eq "1.0"
90
- end
91
- it "writes swaggerVersion correctly" do
92
- expect(response["swaggerVersion"]).to eq "1.2"
93
- end
94
61
  it "writes basePath correctly" do
95
- expect(response["basePath"]).to eq "http://api.no.where/api/v1"
62
+ expect(response["basePath"]).to eq "http://api.no.where/"
96
63
  end
97
64
  it "writes resourcePath correctly" do
98
- expect(response["resourcePath"]).to eq "/sample"
65
+ expect(response["resourcePath"]).to eq "sample"
99
66
  end
100
67
  it "writes out expected api count" do
101
68
  expect(response["apis"].count).to eq 5
@@ -104,48 +71,153 @@ describe Swagger::Docs::Generator do
104
71
  #"apis":[{"path":" /sample","operations":[{"summary":"Fetches all User items"
105
72
  #,"method":"get","nickname":"Api::V1::Sample#index"}]
106
73
  it "writes path correctly" do
107
- expect(first["path"]).to eq "/sample"
74
+ expect(first["path"]).to eq "api/v1/sample"
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ context "with controller base path" do
81
+ let(:config) { Swagger::Docs::Config.register_apis({
82
+ "1.0" => {:controller_base_path => "api/v1", :api_file_path => "#{TMP_DIR}api/v1/", :base_path => "http://api.no.where"}
83
+ })}
84
+ before(:each) do
85
+ Rails.stub_chain(:application, :routes, :routes).and_return(routes)
86
+ Swagger::Docs::Generator.set_real_methods
87
+ require "fixtures/controllers/sample_controller"
88
+ end
89
+
90
+ context "test suite initialization" do
91
+ it "the resources file does not exist" do
92
+ expect(File.exists?(FILE_RESOURCES)).to be_false
93
+ end
94
+ it "the resource file does not exist" do
95
+ expect(File.exists?(FILE_RESOURCE)).to be_false
96
+ end
97
+ end
98
+
99
+ describe "#write_docs" do
100
+ before(:each) do
101
+ generate(config)
102
+ end
103
+ it "cleans json files in directory when set" do
104
+ file_to_delete = "#{TMP_DIR}api/v1/delete_me.json"
105
+ File.open(file_to_delete, 'w') {|f| f.write("{}") }
106
+ expect(File.exists?(file_to_delete)).to be_true
107
+ config["1.0"][:clean_directory] = true
108
+ generate(config)
109
+ expect(File.exists?(file_to_delete)).to be_false
110
+ end
111
+ it "keeps non json files in directory when cleaning" do
112
+ file_to_keep = "#{TMP_DIR}api/v1/keep_me"
113
+ File.open(file_to_keep, 'w') {|f| f.write("{}") }
114
+ config["1.0"][:clean_directory] = true
115
+ generate(config)
116
+ expect(File.exists?(file_to_keep)).to be_true
117
+ end
118
+ it "writes the resources file" do
119
+ expect(File.exists?(FILE_RESOURCES)).to be_true
120
+ end
121
+ it "writes the resource file" do
122
+ expect(File.exists?(FILE_RESOURCE)).to be_true
123
+ end
124
+ it "returns results hash" do
125
+ results = generate(config)
126
+ expect(results["1.0"][:processed].count).to eq 1
127
+ expect(results["1.0"][:skipped].count).to eq 1
128
+ end
129
+ context "resources files" do
130
+ let(:resources) { File.read(FILE_RESOURCES)}
131
+ let(:response) { JSON.parse(resources) }
132
+ it "writes version correctly" do
133
+ expect(response["apiVersion"]).to eq "1.0"
108
134
  end
109
- it "writes summary correctly" do
110
- expect(operations.first["summary"]).to eq "Fetches all User items"
135
+ it "writes swaggerVersion correctly" do
136
+ expect(response["swaggerVersion"]).to eq "1.2"
111
137
  end
112
- it "writes method correctly" do
113
- expect(operations.first["method"]).to eq "get"
138
+ it "writes basePath correctly" do
139
+ expect(response["basePath"]).to eq "http://api.no.where/api/v1/"
114
140
  end
115
- it "writes nickname correctly" do
116
- expect(operations.first["nickname"]).to eq "Api::V1::Sample#index"
141
+ it "writes apis correctly" do
142
+ expect(response["apis"].count).to eq 1
117
143
  end
118
- #"parameters":[{"paramType":"query","name":"page","type":"integer","description":"Page number","required":false}]
119
- context "parameters" do
120
- it "has correct count" do
121
- expect(params.count).to eq 1
122
- end
123
- it "writes paramType correctly" do
124
- expect(params.first["paramType"]).to eq "query"
125
- end
126
- it "writes name correctly" do
127
- expect(params.first["name"]).to eq "page"
128
- end
129
- it "writes type correctly" do
130
- expect(params.first["type"]).to eq "integer"
144
+ it "writes api path correctly" do
145
+ expect(response["apis"][0]["path"]).to eq "sample.{format}"
146
+ end
147
+ it "writes api description correctly" do
148
+ expect(response["apis"][0]["description"]).to eq "User Management"
149
+ end
150
+ end
151
+ context "resource file" do
152
+ let(:resource) { File.read(FILE_RESOURCE)}
153
+ let(:response) { JSON.parse(resource) }
154
+ let(:first) { response["apis"].first }
155
+ let(:operations) { first["operations"] }
156
+ let(:params) { operations.first["parameters"] }
157
+ let(:response_msgs) { operations.first["responseMessages"] }
158
+ # {"apiVersion":"1.0","swaggerVersion":"1.2","basePath":"/api/v1","resourcePath":"/sample"
159
+ it "writes version correctly" do
160
+ expect(response["apiVersion"]).to eq "1.0"
161
+ end
162
+ it "writes swaggerVersion correctly" do
163
+ expect(response["swaggerVersion"]).to eq "1.2"
164
+ end
165
+ it "writes basePath correctly" do
166
+ expect(response["basePath"]).to eq "http://api.no.where/api/v1/"
167
+ end
168
+ it "writes resourcePath correctly" do
169
+ expect(response["resourcePath"]).to eq "sample"
170
+ end
171
+ it "writes out expected api count" do
172
+ expect(response["apis"].count).to eq 5
173
+ end
174
+ context "first api" do
175
+ #"apis":[{"path":" /sample","operations":[{"summary":"Fetches all User items"
176
+ #,"method":"get","nickname":"Api::V1::Sample#index"}]
177
+ it "writes path correctly" do
178
+ expect(first["path"]).to eq "sample"
131
179
  end
132
- it "writes description correctly" do
133
- expect(params.first["description"]).to eq "Page number"
180
+ it "writes summary correctly" do
181
+ expect(operations.first["summary"]).to eq "Fetches all User items"
134
182
  end
135
- it "writes required correctly" do
136
- expect(params.first["required"]).to be_false
183
+ it "writes method correctly" do
184
+ expect(operations.first["method"]).to eq "get"
137
185
  end
138
- end
139
- #"responseMessages":[{"code":401,"message":"Unauthorized"},{"code":406,"message":"Not Acceptable"},{"code":416,"message":"Requested Range Not Satisfiable"}]
140
- context "response messages" do
141
- it "has correct count" do
142
- expect(response_msgs.count).to eq 3
186
+ it "writes nickname correctly" do
187
+ expect(operations.first["nickname"]).to eq "Api::V1::Sample#index"
143
188
  end
144
- it "writes code correctly" do
145
- expect(response_msgs.first["code"]).to eq 401
189
+ #"parameters":[{"paramType":"query","name":"page","type":"integer","description":"Page number","required":false}]
190
+ context "parameters" do
191
+ it "has correct count" do
192
+ expect(params.count).to eq 1
193
+ end
194
+ it "writes paramType correctly" do
195
+ expect(params.first["paramType"]).to eq "query"
196
+ end
197
+ it "writes name correctly" do
198
+ expect(params.first["name"]).to eq "page"
199
+ end
200
+ it "writes type correctly" do
201
+ expect(params.first["type"]).to eq "integer"
202
+ end
203
+ it "writes description correctly" do
204
+ expect(params.first["description"]).to eq "Page number"
205
+ end
206
+ it "writes required correctly" do
207
+ expect(params.first["required"]).to be_false
208
+ end
146
209
  end
147
- it "writes message correctly" do
148
- expect(response_msgs.first["message"]).to eq "Unauthorized"
210
+ #"responseMessages":[{"code":401,"message":"Unauthorized"},{"code":406,"message":"Not Acceptable"},{"code":416,"message":"Requested Range Not Satisfiable"}]
211
+ context "response messages" do
212
+ it "has correct count" do
213
+ expect(response_msgs.count).to eq 3
214
+ end
215
+ it "writes code correctly" do
216
+ expect(response_msgs.first["code"]).to eq 401
217
+ end
218
+ it "writes message correctly" do
219
+ expect(response_msgs.first["message"]).to eq "Unauthorized"
220
+ end
149
221
  end
150
222
  end
151
223
  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.0.2
4
+ version: 0.0.3
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: 2013-10-22 00:00:00.000000000 Z
33
+ date: 2013-11-04 00:00:00.000000000 Z
34
34
  dependencies:
35
35
  - !ruby/object:Gem::Dependency
36
36
  name: bundler
metadata.gz.sig CHANGED
Binary file