dox 1.1.0 → 2.0.0
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.
- 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
|
-
|