dox 1.1.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.rubocop.yml +6 -3
- data/.ruby-version +1 -1
- data/.travis.yml +7 -11
- data/CHANGES.md +29 -0
- data/Gemfile +1 -1
- data/README.md +112 -117
- data/Rakefile +3 -3
- data/bin/console +3 -3
- data/dox.gemspec +15 -14
- data/lib/dox.rb +14 -1
- data/lib/dox/config.rb +39 -5
- data/lib/dox/dsl/action.rb +10 -4
- data/lib/dox/dsl/documentation.rb +4 -0
- data/lib/dox/dsl/resource.rb +0 -2
- data/lib/dox/dsl/syntax.rb +1 -0
- data/lib/dox/entities/action.rb +33 -13
- data/lib/dox/entities/example.rb +33 -3
- data/lib/dox/entities/resource.rb +4 -6
- data/lib/dox/entities/resource_group.rb +2 -3
- data/lib/dox/formatter.rb +10 -11
- data/lib/dox/formatters/base.rb +19 -0
- data/lib/dox/formatters/json.rb +14 -0
- data/lib/dox/formatters/multipart.rb +23 -0
- data/lib/dox/formatters/plain.rb +13 -0
- data/lib/dox/formatters/xml.rb +14 -0
- data/lib/dox/printers/action_printer.rb +18 -27
- data/lib/dox/printers/base_printer.rb +36 -17
- data/lib/dox/printers/document_printer.rb +37 -7
- data/lib/dox/printers/example_request_printer.rb +69 -0
- data/lib/dox/printers/example_response_printer.rb +86 -0
- data/lib/dox/printers/resource_group_printer.rb +7 -7
- data/lib/dox/printers/resource_printer.rb +12 -7
- data/lib/dox/util/http.rb +64 -0
- data/lib/dox/version.rb +1 -1
- metadata +93 -32
- data/lib/dox/printers/example_printer.rb +0 -132
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c4cb190cdb908fc6f132913d43624c470ab3f495f8875fdf9b8fb311f7d9dc15
|
4
|
+
data.tar.gz: cd95ecb21307695857b2164834703c1cc2fcee8f2675721054fdde257f6b4fbf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3c6f7b2b5497fca67e55b06fa037b0c677c4d6ec552fc117674f25b46bbb30aed430bf3290e951a2fa66b32a8280629953f341f8a3c62e76308be4145855ac0d
|
7
|
+
data.tar.gz: e8204b56a371f816da95cd240f52f04d30f6d46346111fb35ea393337c07ebdd9a3abe04190e52014613ec411efcaafcd31d2aeb094759a7b8fcf4e551b0708e
|
data/.rubocop.yml
CHANGED
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.5.5
|
data/.travis.yml
CHANGED
@@ -1,20 +1,16 @@
|
|
1
1
|
language: ruby
|
2
|
-
before_install: gem install bundler -v 1.
|
2
|
+
# before_install: gem install bundler -v 1.17.3
|
3
3
|
|
4
4
|
matrix:
|
5
5
|
include:
|
6
|
-
- rvm: 2.0.0
|
7
|
-
env: "RAILS_VERSION=4.0.0"
|
8
|
-
- rvm: 2.1.2
|
9
|
-
env: "RAILS_VERSION=4.1.0"
|
10
|
-
- rvm: 2.2.0
|
11
|
-
env: "RAILS_VERSION=4.2.0"
|
12
|
-
- rvm: 2.2.2
|
13
|
-
env: "RAILS_VERSION=5.0.0"
|
14
|
-
- rvm: 2.3.0
|
15
|
-
env: "RAILS_VERSION=5.0.0"
|
16
6
|
- rvm: 2.4.0
|
17
7
|
env: "RAILS_VERSION=5.0.0"
|
8
|
+
- rvm: 2.5.0
|
9
|
+
env: "RAILS_VERSION=5.0.0"
|
10
|
+
- rvm: 2.6.0
|
11
|
+
env: "RAILS_VERSION=6.0.0"
|
12
|
+
- rvm: 2.7.0
|
13
|
+
env: "RAILS_VERSION=6.0.0"
|
18
14
|
|
19
15
|
addons:
|
20
16
|
code_climate:
|
data/CHANGES.md
CHANGED
@@ -1,5 +1,34 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## Version 2.0.0
|
4
|
+
|
5
|
+
Released on August 8, 2020
|
6
|
+
|
7
|
+
Change:
|
8
|
+
- BREAKING CHANGE The API description format changed from API-blueprint to OpenAPI.
|
9
|
+
- BREAKING CHANGE Base structure is now defined in .json format
|
10
|
+
- BREAKING CHANGE Output is written to a .json file
|
11
|
+
- BREAKING CHANGE Html is rendered with Redoc instead of Aglio
|
12
|
+
- Renamed `Dox.config.desc_folder_path` -> `Dox.config.descriptions_location`
|
13
|
+
- Depricated `Dox.config.header_file_path`
|
14
|
+
- Removed `endpoint` method from document resource block
|
15
|
+
|
16
|
+
New:
|
17
|
+
- Added `Dox.config.title`
|
18
|
+
- Added `Dox.config.header_description`
|
19
|
+
- Added `Dox.config.version`
|
20
|
+
|
21
|
+
## Version 1.2.0
|
22
|
+
|
23
|
+
Released on November 27, 2019
|
24
|
+
|
25
|
+
New:
|
26
|
+
- Support Multipart payload with pretty formatting (based on `content-type` header)
|
27
|
+
|
28
|
+
Fix:
|
29
|
+
- Explicit passing of an empty hash for `params` in actions now works as expected
|
30
|
+
|
31
|
+
|
3
32
|
## Version 1.1.0
|
4
33
|
|
5
34
|
Released on February 19, 2018
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -4,13 +4,9 @@
|
|
4
4
|
|
5
5
|
# Dox
|
6
6
|
|
7
|
-
Automate your documentation writing
|
7
|
+
Automate your documentation writing process! Dox generates API documentation from Rspec controller/request specs in a Rails application. It formats the tests output in the [OpenApi](https://www.openapis.org/) format. Use the ReDoc renderer for generating and displaying the documentation as HTML.
|
8
8
|
|
9
|
-
Here's a [demo app](https://github.com/infinum/dox-demo)
|
10
|
-
|
11
|
-
- [Dox demo - Apiary](http://docs.doxdemo.apiary.io/#reference/books/books)
|
12
|
-
- [Dox demo - Aglio](https://infinum.github.io/dox-demo/aglio)
|
13
|
-
- [Dox demo - Snowboard](https://infinum.github.io/dox-demo/snowboard)
|
9
|
+
Here's a [demo app](https://github.com/infinum/dox-demo).
|
14
10
|
|
15
11
|
|
16
12
|
## Installation
|
@@ -44,39 +40,33 @@ $ gem install dox
|
|
44
40
|
require 'dox'
|
45
41
|
```
|
46
42
|
|
47
|
-
and configure rspec with this:
|
48
|
-
|
49
|
-
``` ruby
|
50
|
-
RSpec.configure do |config|
|
51
|
-
config.after(:each, :dox) do |example|
|
52
|
-
example.metadata[:request] = request
|
53
|
-
example.metadata[:response] = response
|
54
|
-
end
|
55
|
-
end
|
56
|
-
```
|
57
|
-
|
58
43
|
### Configure it
|
59
|
-
Set these
|
44
|
+
Set these optional options in the rails_helper:
|
60
45
|
|
61
46
|
| Option | Value | Description |
|
62
47
|
| -- | -- | -- |
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
|
70
|
-
|
|
48
|
+
| descriptions_location | Pathname instance or fullpath string | Folder containing markdown descriptions of resources. |
|
49
|
+
| schema_request_folder_path | Pathname instance or fullpath string | Folder with request schemas of resources. |
|
50
|
+
| schema_response_folder_path | Pathname instance or fullpath string | Folder with response schemas of resources. |
|
51
|
+
| schema_response_fail_file_path | Pathname instance or fullpath string | Json file that contains the default schema of a failed response. |
|
52
|
+
| openapi_version | string | Openapi version (default: '3.0.0' ) |
|
53
|
+
| api_version | string | Api Version (default: '1.0') |
|
54
|
+
| title | string | Documentation title (default: 'API Documentation') |
|
55
|
+
| header_description | Pathname instance or string | Description (header) of the documentation (default: ''). If pathname ends with `.md`, the file is looked in `descriptions_location` folder |
|
71
56
|
| headers_whitelist | Array of headers (strings) | Requests and responses will by default list only `Content-Type` header. To list other http headers, you must whitelist them.|
|
72
57
|
|
73
58
|
Example:
|
74
59
|
|
75
60
|
``` ruby
|
76
61
|
Dox.configure do |config|
|
77
|
-
config.
|
78
|
-
config.
|
62
|
+
config.descriptions_location = Rails.root.join('spec/docs/v1/descriptions')
|
63
|
+
config.schema_request_folder_path = Rails.root.join('spec/docs/v1/schemas')
|
64
|
+
config.schema_response_folder_path = Rails.root.join('spec/support/v1/schemas')
|
65
|
+
config.schema_response_fail_file_path = Rails.root.join('spec/support/v1/schemas/error.json')
|
79
66
|
config.headers_whitelist = ['Accept', 'X-Auth-Token']
|
67
|
+
config.title = 'API'
|
68
|
+
config.api_version = '2.0'
|
69
|
+
config.header_description = 'api_description.md'
|
80
70
|
end
|
81
71
|
```
|
82
72
|
|
@@ -93,8 +83,8 @@ module Docs
|
|
93
83
|
# define common resource data for each action
|
94
84
|
document :api do
|
95
85
|
resource 'Bids' do
|
96
|
-
endpoint '/bids'
|
97
86
|
group 'Bids'
|
87
|
+
desc 'bids.md'
|
98
88
|
end
|
99
89
|
end
|
100
90
|
|
@@ -138,34 +128,41 @@ And [generate the documentation](#generate-documentation).
|
|
138
128
|
|
139
129
|
### Advanced options
|
140
130
|
|
141
|
-
Before running into any more details, here's roughly how
|
142
|
-
|
143
|
-
-
|
144
|
-
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
-
|
150
|
-
|
151
|
-
|
152
|
-
-
|
153
|
-
|
154
|
-
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
131
|
+
Before running into any more details, here's roughly how the generated OpenApi document is structured:
|
132
|
+
|
133
|
+
- openapi
|
134
|
+
- info
|
135
|
+
- paths
|
136
|
+
- action 1
|
137
|
+
- tag1
|
138
|
+
- example 1
|
139
|
+
- example 2
|
140
|
+
- action 2
|
141
|
+
- tag2
|
142
|
+
- example 3
|
143
|
+
- x-tagGroups
|
144
|
+
- tags1
|
145
|
+
- tag 1
|
146
|
+
- tag 2
|
147
|
+
- tags2
|
148
|
+
- tag 3
|
149
|
+
- tag 4
|
150
|
+
- tags
|
151
|
+
- tag1
|
152
|
+
- tag2
|
153
|
+
|
154
|
+
|
155
|
+
OpenApi and info are defined in a json file as mentioned before. Examples are concrete test examples (you can have multiple examples for both happy and fail paths). They are completely automatically generated from the request/response objects.
|
160
156
|
And you can customize the following in the descriptors:
|
161
157
|
|
162
|
-
-
|
163
|
-
- resource
|
158
|
+
- x-tagGroup (**resourceGroup**)
|
159
|
+
- tag (**resource**)
|
164
160
|
- action
|
161
|
+
- example
|
165
162
|
|
166
|
-
####
|
163
|
+
#### ResourceGroup
|
167
164
|
|
168
|
-
|
165
|
+
ResourceGroup contains related resources and is defined with:
|
169
166
|
- **name** (required)
|
170
167
|
- desc (optional, inline string or relative filepath)
|
171
168
|
|
@@ -183,7 +180,6 @@ You can omit defining the resource group, if you don't have any description for
|
|
183
180
|
#### Resource
|
184
181
|
Resource contains actions and is defined with:
|
185
182
|
- **name** (required)
|
186
|
-
- **endpoint** (required)
|
187
183
|
- **group** (required; to associate it with the related group)
|
188
184
|
- desc (optional; inline string or relative filepath)
|
189
185
|
|
@@ -191,14 +187,13 @@ Example:
|
|
191
187
|
``` ruby
|
192
188
|
document :bids do
|
193
189
|
resource 'Bids' do
|
194
|
-
endpoint '/bids'
|
195
190
|
group 'Bids'
|
196
191
|
desc 'bids/bids.md'
|
197
192
|
end
|
198
193
|
end
|
199
194
|
```
|
200
195
|
|
201
|
-
Usually you'll want to define
|
196
|
+
Usually you'll want to define resourceGroup and resource together, so you don't have to include 2 modules with common data per spec file:
|
202
197
|
|
203
198
|
``` ruby
|
204
199
|
document :bids_common do
|
@@ -207,7 +202,6 @@ document :bids_common do
|
|
207
202
|
end
|
208
203
|
|
209
204
|
resource 'Bids' do
|
210
|
-
endpoint '/bids'
|
211
205
|
group 'Bids'
|
212
206
|
desc 'bids/bids.md'
|
213
207
|
end
|
@@ -215,12 +209,16 @@ end
|
|
215
209
|
```
|
216
210
|
|
217
211
|
#### Action
|
218
|
-
Action is defined with:
|
212
|
+
Action contains examples and is defined with:
|
219
213
|
- **name** (required)
|
220
214
|
- path* (optional)
|
221
215
|
- verb* (optional)
|
222
|
-
- params
|
216
|
+
- params (optional; _depricated_)
|
217
|
+
- query_params (optional; [more info](https://swagger.io/docs/specification/describing-parameters/#query-parameters))
|
223
218
|
- desc (optional; inline string or relative filepath)
|
219
|
+
- request_schema (optional; inline string or relative filepath)
|
220
|
+
- response_schema_success (optional; inline string or relative filepath)
|
221
|
+
- response_schema_fail (optional; inline string or relative filepath)
|
224
222
|
|
225
223
|
\* these optional attributes are guessed (if not defined) from the request object of the test example and you can override them.
|
226
224
|
|
@@ -228,13 +226,37 @@ Example:
|
|
228
226
|
|
229
227
|
``` ruby
|
230
228
|
show_params = { id: { type: :number, required: :required, value: 1, description: 'bid id' } }
|
229
|
+
query_params = [ {
|
230
|
+
"in": "query",
|
231
|
+
"name": "filter",
|
232
|
+
"required": false,
|
233
|
+
"style": "deepObject",
|
234
|
+
"explode": true,
|
235
|
+
"schema": {
|
236
|
+
"type": "object",
|
237
|
+
"required": ["updated_at_gt"],
|
238
|
+
"example": {
|
239
|
+
"updated_at_gt": "2018-02-03 10:30:00"
|
240
|
+
},
|
241
|
+
"properties": {
|
242
|
+
"updated_at_gt": {
|
243
|
+
"type": "string",
|
244
|
+
"title": "date"
|
245
|
+
}
|
246
|
+
}
|
247
|
+
}
|
248
|
+
]
|
231
249
|
|
232
250
|
document :action do
|
233
251
|
action 'Get bid' do
|
234
252
|
path '/bids/{id}'
|
235
253
|
verb 'GET'
|
236
254
|
params show_params
|
255
|
+
query_params query_params
|
237
256
|
desc 'Some description for get bid action'
|
257
|
+
request_schema 'namespace/bids'
|
258
|
+
response_schema_success 'namespace/bids_s'
|
259
|
+
response_schema_fail 'namespace/bids_f'
|
238
260
|
end
|
239
261
|
end
|
240
262
|
```
|
@@ -242,89 +264,63 @@ end
|
|
242
264
|
### Generate documentation
|
243
265
|
Documentation is generated in 2 steps:
|
244
266
|
|
245
|
-
1. generate
|
246
|
-
```bundle exec rspec
|
267
|
+
1. generate OpenApi json file:
|
268
|
+
```bundle exec rspec --tag apidoc -f Dox::Formatter --order defined --tag dox --out spec/api_doc/v1/schemas/docs.json```
|
247
269
|
|
248
|
-
2. render HTML with
|
249
|
-
```
|
270
|
+
2. render HTML with Redoc:
|
271
|
+
```redoc-cli bundle -o public/api/docs/v2/docs.html spec/api_doc/v1/schemas/docs.json```
|
250
272
|
|
251
273
|
|
252
274
|
#### Use rake tasks
|
253
275
|
It's recommendable to write a few rake tasks to make things easier. Here's an example:
|
254
276
|
|
255
277
|
```ruby
|
256
|
-
namespace :
|
257
|
-
|
258
|
-
desc 'Generate API documentation markdown'
|
259
|
-
task :md do
|
260
|
-
require 'rspec/core/rake_task'
|
261
|
-
|
262
|
-
RSpec::Core::RakeTask.new(:api_spec) do |t|
|
263
|
-
t.pattern = 'spec/controllers/api/v1/'
|
264
|
-
t.rspec_opts = "-f Dox::Formatter --order defined --tag dox --out public/api/docs/v1/apispec.md"
|
265
|
-
end
|
278
|
+
namespace :dox do
|
279
|
+
desc 'Generate API documentation markdown'
|
266
280
|
|
267
|
-
|
268
|
-
|
281
|
+
task :json, [:version, :docs_path, :host] => :environment do |_, args|
|
282
|
+
require 'rspec/core/rake_task'
|
283
|
+
version = args[:version] || :v1
|
269
284
|
|
270
|
-
|
271
|
-
|
285
|
+
RSpec::Core::RakeTask.new(:api_spec) do |t|
|
286
|
+
t.pattern = "spec/requests/api/#{version}"
|
287
|
+
t.rspec_opts =
|
288
|
+
"-f Dox::Formatter --tag dox --order defined --out spec/docs/#{version}/apispec.json"
|
272
289
|
end
|
273
290
|
|
274
|
-
|
275
|
-
|
276
|
-
end
|
291
|
+
Rake::Task['api_spec'].invoke
|
292
|
+
end
|
277
293
|
|
278
|
-
|
279
|
-
|
280
|
-
|
294
|
+
task :html, [:version, :docs_path, :host] => :json do |_, args|
|
295
|
+
version = args[:version] || :v1
|
296
|
+
docs_path = args[:docs_path] || "api/#{version}/docs"
|
297
|
+
|
298
|
+
`yarn run redoc-cli bundle -o public/#{docs_path}/index.html spec/docs/#{version}/apispec.json`
|
299
|
+
end
|
300
|
+
|
301
|
+
task :open, [:version, :docs_path, :host] => :html do |_, args|
|
302
|
+
version = args[:version] || :v1
|
303
|
+
docs_path = args[:docs_path] || "api/#{version}/docs"
|
304
|
+
|
305
|
+
`open public/#{docs_path}/index.html`
|
281
306
|
end
|
282
307
|
end
|
283
308
|
```
|
284
309
|
|
285
310
|
#### Renderers
|
286
|
-
You can render the HTML yourself with
|
287
|
-
|
288
|
-
- [Aglio](https://github.com/danielgtaylor/aglio)
|
289
|
-
- [Snowboard](https://github.com/subosito/snowboard)
|
290
|
-
|
291
|
-
Both support multiple themes and template customization.
|
292
|
-
|
293
|
-
Or you can just take your generated markdown and host your documentation on [Apiary.io](https://apiary.io).
|
311
|
+
You can render the HTML yourself with ReDoc:
|
294
312
|
|
313
|
+
- [Redoc](https://github.com/Redocly/redoc)
|
295
314
|
|
296
315
|
### Common issues
|
297
316
|
|
298
317
|
You might experience some strange issues when generating the documentation. Here are a few examples of what we've encountered so far.
|
299
318
|
|
300
|
-
####
|
301
|
-
Rails wraps JSON parameters on all requests by default, which results with documented requests looking like this:
|
302
|
-
|
303
|
-
```
|
304
|
-
+ Request get pokemons
|
305
|
-
{
|
306
|
-
"pokemon": {}
|
307
|
-
}
|
308
|
-
```
|
309
|
-
|
310
|
-
To disable wrapping parameters with a resource name, turn off this feature in `config/initializers/wrap_parameters.rb`:
|
311
|
-
|
312
|
-
``` ruby
|
313
|
-
# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
|
314
|
-
ActiveSupport.on_load(:action_controller) do
|
315
|
-
wrap_parameters format: []
|
316
|
-
end
|
317
|
-
```
|
318
|
-
|
319
|
-
#### Rendering warnings with Aglio
|
320
|
-
You might get the following warnings when rendering HTML with Aglio:
|
321
|
-
|
322
|
-
* `no headers specified (warning code 3)`
|
323
|
-
* `empty request message-body (warning code 6)`
|
324
|
-
|
325
|
-
This usually happens on GET requests examples when there are no headers. To solve this issue, add at least one header to the tests' requests, like `Accept: application/json`.
|
319
|
+
#### Uninitialized constant errors
|
326
320
|
|
321
|
+
There seems to be a problem with **rspec-rails** versions 3.7 and later not automatically requiring the project's rails_helper.rb when run with the `--format` flag.
|
327
322
|
|
323
|
+
To fix this issue, generate your documentation with `--require rails_helper`:
|
328
324
|
## Development
|
329
325
|
|
330
326
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -344,4 +340,3 @@ Dox is maintained and sponsored by [Infinum](https://infinum.co).
|
|
344
340
|
## License
|
345
341
|
|
346
342
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
347
|
-
|