apidoc 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +1 -0
- data/Gemfile.lock +2 -0
- data/VERSION +1 -1
- data/apidoc.gemspec +8 -2
- data/examples/burritos_api.html +30 -17
- data/examples/burritos_api.rb +13 -2
- data/examples/tacos_api.html +22 -21
- data/examples/tacos_api.rb +5 -5
- data/ftags +8 -0
- data/lib/apidoc.rb +49 -52
- data/spec/apidoc_spec.rb +16 -320
- data/spec/before_and_after_spec.rb +203 -0
- data/spec/html_writer_spec.rb +113 -0
- data/spec/support/test_apps.rb +34 -0
- data/templates/layout.mustache +14 -15
- data/templates/resource.mustache +1 -1
- metadata +37 -23
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -9,6 +9,7 @@ GEM
|
|
9
9
|
rake
|
10
10
|
rdoc
|
11
11
|
json (1.7.3)
|
12
|
+
kramdown (0.13.5)
|
12
13
|
mustache (0.99.4)
|
13
14
|
rack (1.4.0)
|
14
15
|
rack-protection (1.2.0)
|
@@ -40,6 +41,7 @@ DEPENDENCIES
|
|
40
41
|
bundler (~> 1.0.0)
|
41
42
|
jeweler (~> 1.8.3)
|
42
43
|
json
|
44
|
+
kramdown
|
43
45
|
mustache
|
44
46
|
rack-test
|
45
47
|
rdoc (~> 3.12)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.3
|
data/apidoc.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "apidoc"
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["T.J. VanSlyke"]
|
12
|
-
s.date = "2012-06-
|
12
|
+
s.date = "2012-06-05"
|
13
13
|
s.description = "Minimalist API documentation generator for Rack applications."
|
14
14
|
s.email = "tj@turing.com"
|
15
15
|
s.executables = ["apidoc"]
|
@@ -36,7 +36,10 @@ Gem::Specification.new do |s|
|
|
36
36
|
"ftags",
|
37
37
|
"lib/apidoc.rb",
|
38
38
|
"spec/apidoc_spec.rb",
|
39
|
+
"spec/before_and_after_spec.rb",
|
40
|
+
"spec/html_writer_spec.rb",
|
39
41
|
"spec/spec_helper.rb",
|
42
|
+
"spec/support/test_apps.rb",
|
40
43
|
"templates/apidoc_helper.rb",
|
41
44
|
"templates/layout.mustache",
|
42
45
|
"templates/resource.mustache"
|
@@ -55,6 +58,7 @@ Gem::Specification.new do |s|
|
|
55
58
|
s.add_runtime_dependency(%q<mustache>, [">= 0"])
|
56
59
|
s.add_runtime_dependency(%q<rack-test>, [">= 0"])
|
57
60
|
s.add_runtime_dependency(%q<mustache>, [">= 0"])
|
61
|
+
s.add_runtime_dependency(%q<kramdown>, [">= 0"])
|
58
62
|
s.add_development_dependency(%q<rspec>, ["~> 2.8.0"])
|
59
63
|
s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
|
60
64
|
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
@@ -66,6 +70,7 @@ Gem::Specification.new do |s|
|
|
66
70
|
s.add_dependency(%q<mustache>, [">= 0"])
|
67
71
|
s.add_dependency(%q<rack-test>, [">= 0"])
|
68
72
|
s.add_dependency(%q<mustache>, [">= 0"])
|
73
|
+
s.add_dependency(%q<kramdown>, [">= 0"])
|
69
74
|
s.add_dependency(%q<rspec>, ["~> 2.8.0"])
|
70
75
|
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
71
76
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
@@ -78,6 +83,7 @@ Gem::Specification.new do |s|
|
|
78
83
|
s.add_dependency(%q<mustache>, [">= 0"])
|
79
84
|
s.add_dependency(%q<rack-test>, [">= 0"])
|
80
85
|
s.add_dependency(%q<mustache>, [">= 0"])
|
86
|
+
s.add_dependency(%q<kramdown>, [">= 0"])
|
81
87
|
s.add_dependency(%q<rspec>, ["~> 2.8.0"])
|
82
88
|
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
83
89
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
data/examples/burritos_api.html
CHANGED
@@ -108,21 +108,20 @@
|
|
108
108
|
font-size: 1em;
|
109
109
|
}
|
110
110
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
}
|
111
|
+
.api-resource .desc {
|
112
|
+
margin: 1em 0;
|
113
|
+
color:
|
114
|
+
#333;
|
115
|
+
display: block;
|
116
|
+
font-family: Helvetica, sans-serif;
|
117
|
+
font-size: 13px;
|
118
|
+
font-weight: 100;
|
119
|
+
height: 17px;
|
120
|
+
line-height: 17px;
|
121
|
+
text-shadow:
|
122
|
+
rgba(255, 255, 255, 0.597656) 0px 1px 0px;
|
123
|
+
vertical-align: baseline;
|
124
|
+
}
|
126
125
|
.api-resource .params,
|
127
126
|
.api-resource .response {
|
128
127
|
font-family: Monaco, fixed;
|
@@ -159,7 +158,8 @@
|
|
159
158
|
<div class="api-resource">
|
160
159
|
<div class="method">GET</div>
|
161
160
|
<div class="path">/burritos.json</div>
|
162
|
-
<div class="desc">Get all burritos
|
161
|
+
<div class="desc"><p>Get all burritos. <em>Note:</em> When requesting all burritos, please give the commissary ample time to prepare your order. Fattie.</p>
|
162
|
+
</div>
|
163
163
|
<div class="params"></div>
|
164
164
|
<div class="response">[
|
165
165
|
{
|
@@ -173,7 +173,8 @@
|
|
173
173
|
<div class="api-resource">
|
174
174
|
<div class="method">POST</div>
|
175
175
|
<div class="path">/burritos.json</div>
|
176
|
-
<div class="desc">Make a new delicious burrito</
|
176
|
+
<div class="desc"><p>Make a new delicious burrito</p>
|
177
|
+
</div>
|
177
178
|
<div class="params">{
|
178
179
|
"meat": "beef",
|
179
180
|
"lettuce": true
|
@@ -182,6 +183,18 @@
|
|
182
183
|
"meat": "beef",
|
183
184
|
"lettuce": true
|
184
185
|
}</div>
|
186
|
+
</div>
|
187
|
+
<div class="api-resource">
|
188
|
+
<div class="method">GET</div>
|
189
|
+
<div class="path">/burritos/:id.json</div>
|
190
|
+
<div class="desc"><p>Get a burrito by its ID</p>
|
191
|
+
</div>
|
192
|
+
<div class="params">{
|
193
|
+
}</div>
|
194
|
+
<div class="response">{
|
195
|
+
"meat": "beef",
|
196
|
+
"id": "123"
|
197
|
+
}</div>
|
185
198
|
</div>
|
186
199
|
|
187
200
|
</div>
|
data/examples/burritos_api.rb
CHANGED
@@ -13,6 +13,10 @@ class BurritoApp < Sinatra::Base
|
|
13
13
|
request.body
|
14
14
|
end
|
15
15
|
|
16
|
+
get '/burritos/:id.json' do
|
17
|
+
JSON.generate({ meat: 'beef', id: params['id'] })
|
18
|
+
end
|
19
|
+
|
16
20
|
end
|
17
21
|
|
18
22
|
doc = ApiDoc.new BurritoApp do
|
@@ -21,13 +25,20 @@ doc = ApiDoc.new BurritoApp do
|
|
21
25
|
content_type :json
|
22
26
|
|
23
27
|
get '/burritos.json' do
|
24
|
-
desc
|
28
|
+
desc %{Get all burritos. *Note:* When requesting all burritos, please give the commissary ample time to prepare your order. Fattie.}
|
25
29
|
end
|
26
30
|
|
27
31
|
post '/burritos.json' do
|
28
32
|
desc "Make a new delicious burrito"
|
29
33
|
params do
|
30
|
-
|
34
|
+
{ meat: 'beef', lettuce: true }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
get '/burritos/:id.json' do
|
39
|
+
desc "Get a burrito by its ID"
|
40
|
+
params do
|
41
|
+
{ id: 123 }
|
31
42
|
end
|
32
43
|
end
|
33
44
|
|
data/examples/tacos_api.html
CHANGED
@@ -108,21 +108,20 @@
|
|
108
108
|
font-size: 1em;
|
109
109
|
}
|
110
110
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
}
|
111
|
+
.api-resource .desc {
|
112
|
+
margin: 1em 0;
|
113
|
+
color:
|
114
|
+
#333;
|
115
|
+
display: block;
|
116
|
+
font-family: Helvetica, sans-serif;
|
117
|
+
font-size: 13px;
|
118
|
+
font-weight: 100;
|
119
|
+
height: 17px;
|
120
|
+
line-height: 17px;
|
121
|
+
text-shadow:
|
122
|
+
rgba(255, 255, 255, 0.597656) 0px 1px 0px;
|
123
|
+
vertical-align: baseline;
|
124
|
+
}
|
126
125
|
.api-resource .params,
|
127
126
|
.api-resource .response {
|
128
127
|
font-family: Monaco, fixed;
|
@@ -158,17 +157,19 @@
|
|
158
157
|
<div class="name"></div>
|
159
158
|
<div class="api-resource">
|
160
159
|
<div class="method">GET</div>
|
161
|
-
<div class="path">/tacos
|
162
|
-
<div class="desc">Get all tacos</
|
160
|
+
<div class="path">/tacos</div>
|
161
|
+
<div class="desc"><p>Get all tacos</p>
|
162
|
+
</div>
|
163
163
|
<div class="params"></div>
|
164
164
|
<div class="response">[{"meat":"chicken"}]</div>
|
165
165
|
</div>
|
166
166
|
<div class="api-resource">
|
167
167
|
<div class="method">POST</div>
|
168
|
-
<div class="path">/tacos
|
169
|
-
<div class="desc">Make a new delicious taco</
|
170
|
-
|
171
|
-
<div class="
|
168
|
+
<div class="path">/tacos</div>
|
169
|
+
<div class="desc"><p>Make a new delicious taco</p>
|
170
|
+
</div>
|
171
|
+
<div class="params">{:meat=>"beef", :lettuce=>true}</div>
|
172
|
+
<div class="response">meat=beef&lettuce=true</div>
|
172
173
|
</div>
|
173
174
|
|
174
175
|
</div>
|
data/examples/tacos_api.rb
CHANGED
@@ -5,11 +5,11 @@ require 'sinatra/base'
|
|
5
5
|
|
6
6
|
class TacoApp < Sinatra::Base
|
7
7
|
|
8
|
-
get '/tacos
|
8
|
+
get '/tacos' do
|
9
9
|
JSON.generate [ { meat: 'chicken' } ]
|
10
10
|
end
|
11
11
|
|
12
|
-
post '/tacos
|
12
|
+
post '/tacos' do
|
13
13
|
request.body
|
14
14
|
end
|
15
15
|
|
@@ -17,14 +17,14 @@ end
|
|
17
17
|
|
18
18
|
doc = ApiDoc.new TacoApp do
|
19
19
|
|
20
|
-
get '/tacos
|
20
|
+
get '/tacos' do
|
21
21
|
desc "Get all tacos"
|
22
22
|
end
|
23
23
|
|
24
|
-
post '/tacos
|
24
|
+
post '/tacos' do
|
25
25
|
desc "Make a new delicious taco"
|
26
26
|
params do
|
27
|
-
|
27
|
+
{ meat: 'beef', lettuce: true }
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
data/ftags
CHANGED
@@ -11,13 +11,21 @@ Gemfile.lock ./Gemfile.lock /^/;" r
|
|
11
11
|
LICENSE.txt ./LICENSE.txt /^/;" r
|
12
12
|
README.rdoc ./README.rdoc /^/;" r
|
13
13
|
Rakefile ./Rakefile /^/;" r
|
14
|
+
VERSION ./VERSION /^/;" r
|
14
15
|
apidoc ./bin/apidoc /^/;" r
|
16
|
+
apidoc-0.1.2.gem ./pkg/apidoc-0.1.2.gem /^/;" r
|
17
|
+
apidoc.gemspec ./apidoc.gemspec /^/;" r
|
15
18
|
apidoc.rb ./lib/apidoc.rb /^/;" r
|
16
19
|
apidoc_helper.rb ./templates/apidoc_helper.rb /^/;" r
|
17
20
|
apidoc_spec.rb ./spec/apidoc_spec.rb /^/;" r
|
18
21
|
authentication.rb ./examples/authentication.rb /^/;" r
|
22
|
+
before_and_after_spec.rb ./spec/before_and_after_spec.rb /^/;" r
|
23
|
+
burritos_api.html ./examples/burritos_api.html /^/;" r
|
24
|
+
burritos_api.rb ./examples/burritos_api.rb /^/;" r
|
19
25
|
config ./.bundle/config /^/;" r
|
20
26
|
ftags ./ftags /^/;" r
|
21
27
|
layout.mustache ./templates/layout.mustache /^/;" r
|
22
28
|
resource.mustache ./templates/resource.mustache /^/;" r
|
23
29
|
spec_helper.rb ./spec/spec_helper.rb /^/;" r
|
30
|
+
tacos_api.html ./examples/tacos_api.html /^/;" r
|
31
|
+
tacos_api.rb ./examples/tacos_api.rb /^/;" r
|
data/lib/apidoc.rb
CHANGED
@@ -2,6 +2,7 @@ require 'rack/test'
|
|
2
2
|
require 'thor'
|
3
3
|
require 'mustache'
|
4
4
|
require 'json'
|
5
|
+
require 'kramdown'
|
5
6
|
|
6
7
|
module ApiDoc
|
7
8
|
VERSION = "0.1.0"
|
@@ -99,6 +100,8 @@ module ApiDoc
|
|
99
100
|
end
|
100
101
|
|
101
102
|
def write(stream)
|
103
|
+
@runner.run
|
104
|
+
|
102
105
|
stream.write(
|
103
106
|
Mustache.to_html(File.read(File.dirname(__FILE__) + '/../templates/layout.mustache'), {
|
104
107
|
content: @runner.resources.map {|r| resource_html(r) }.join
|
@@ -109,39 +112,15 @@ module ApiDoc
|
|
109
112
|
end
|
110
113
|
|
111
114
|
def resource_html(resource)
|
112
|
-
resource.run
|
113
|
-
|
114
115
|
Mustache.to_html(File.read(File.dirname(__FILE__) + '/../templates/resource.mustache'), {
|
115
116
|
method: resource.method,
|
116
117
|
path: resource.path,
|
117
|
-
desc: resource.desc,
|
118
|
-
params: formatted_params
|
119
|
-
response: formatted_response
|
118
|
+
desc: Kramdown::Document.new(resource.desc).to_html,
|
119
|
+
params: resource.formatted_params,
|
120
|
+
response: resource.formatted_response
|
120
121
|
})
|
121
122
|
end
|
122
123
|
|
123
|
-
def formatted_params(resource)
|
124
|
-
return '' unless resource.params
|
125
|
-
return resource.params unless resource.accept
|
126
|
-
|
127
|
-
case resource.accept.intern
|
128
|
-
when :json
|
129
|
-
JSON.pretty_generate(JSON.parse(resource.params))
|
130
|
-
else
|
131
|
-
resource.params
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
def formatted_response(resource)
|
136
|
-
return resource.response_body unless resource.content_type
|
137
|
-
|
138
|
-
case resource.content_type.intern
|
139
|
-
when :json
|
140
|
-
JSON.pretty_generate(JSON.parse(resource.response_body))
|
141
|
-
else
|
142
|
-
resource.response_body
|
143
|
-
end
|
144
|
-
end
|
145
124
|
end
|
146
125
|
|
147
126
|
class Resource
|
@@ -205,22 +184,60 @@ module ApiDoc
|
|
205
184
|
def run
|
206
185
|
@before_blocks.each {|block| instance_eval &block }
|
207
186
|
@params = @params.call if @params.is_a?(Proc)
|
208
|
-
@response = make_request
|
187
|
+
@response = make_request
|
209
188
|
@after_blocks.each {|block| instance_eval &block }
|
210
189
|
end
|
211
190
|
|
191
|
+
def filtered_params
|
192
|
+
params.reject {|k, v| path_captures.include?(k) or path_captures.include?(k.to_s)}
|
193
|
+
end
|
194
|
+
|
195
|
+
def formatted_params
|
196
|
+
return '' unless params
|
197
|
+
return filtered_params unless accept
|
198
|
+
|
199
|
+
case accept.intern
|
200
|
+
when :json
|
201
|
+
JSON.pretty_generate(filtered_params)
|
202
|
+
else
|
203
|
+
filtered_params
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
def formatted_response
|
208
|
+
return response_body unless content_type
|
209
|
+
|
210
|
+
case content_type.intern
|
211
|
+
when :json
|
212
|
+
JSON.pretty_generate(JSON.parse(response_body))
|
213
|
+
else
|
214
|
+
response_body
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
212
218
|
def response_body
|
213
219
|
@response.body
|
214
220
|
end
|
215
221
|
|
216
|
-
|
222
|
+
PATH_CAPTURE_REGEXP = /:[^\.\/]+/
|
217
223
|
|
218
|
-
|
224
|
+
def path_captures
|
225
|
+
@path.match(PATH_CAPTURE_REGEXP).to_a.map {|m| m.gsub(':', '').intern }
|
226
|
+
end
|
219
227
|
|
220
|
-
def
|
221
|
-
|
228
|
+
def interpolated_path
|
229
|
+
@path.gsub(PATH_CAPTURE_REGEXP) do |match|
|
230
|
+
params[match.gsub(':', '').intern]
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
def make_request
|
235
|
+
self.send(@method.downcase.intern, interpolated_path, formatted_params)
|
222
236
|
end
|
223
237
|
|
238
|
+
end
|
239
|
+
|
240
|
+
class PostResource < Resource
|
224
241
|
def initialize(runner, path, &block)
|
225
242
|
super runner, path, &block
|
226
243
|
@method = 'POST'
|
@@ -228,11 +245,6 @@ module ApiDoc
|
|
228
245
|
end
|
229
246
|
|
230
247
|
class GetResource < Resource
|
231
|
-
|
232
|
-
def make_request(path, params)
|
233
|
-
get path, params
|
234
|
-
end
|
235
|
-
|
236
248
|
def initialize(runner, path, &block)
|
237
249
|
super runner, path, &block
|
238
250
|
@method = 'GET'
|
@@ -240,11 +252,6 @@ module ApiDoc
|
|
240
252
|
end
|
241
253
|
|
242
254
|
class PutResource < Resource
|
243
|
-
|
244
|
-
def make_request(path, params)
|
245
|
-
put path, params
|
246
|
-
end
|
247
|
-
|
248
255
|
def initialize(runner, path, &block)
|
249
256
|
super runner, path, &block
|
250
257
|
@method = 'PUT'
|
@@ -252,11 +259,6 @@ module ApiDoc
|
|
252
259
|
end
|
253
260
|
|
254
261
|
class DeleteResource < Resource
|
255
|
-
|
256
|
-
def make_request(path, params)
|
257
|
-
delete path, params
|
258
|
-
end
|
259
|
-
|
260
262
|
def initialize(runner, path, &block)
|
261
263
|
super runner, path, &block
|
262
264
|
@method = 'DELETE'
|
@@ -264,11 +266,6 @@ module ApiDoc
|
|
264
266
|
end
|
265
267
|
|
266
268
|
class OptionsResource < Resource
|
267
|
-
|
268
|
-
def make_request(path, params)
|
269
|
-
options path, params
|
270
|
-
end
|
271
|
-
|
272
269
|
def initialize(runner, path, &block)
|
273
270
|
super runner, path, &block
|
274
271
|
@method = 'OPTIONS'
|