dox 0.0.1 → 0.0.2
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 +4 -4
- data/README.md +89 -4
- data/lib/dox.rb +31 -1
- data/lib/dox/config.rb +13 -0
- data/lib/dox/dsl/action.rb +35 -0
- data/lib/dox/dsl/attr_proxy.rb +12 -0
- data/lib/dox/dsl/documentation.rb +35 -0
- data/lib/dox/dsl/resource.rb +29 -0
- data/lib/dox/dsl/resource_group.rb +23 -0
- data/lib/dox/dsl/syntax.rb +33 -0
- data/lib/dox/entities/action.rb +18 -0
- data/lib/dox/entities/example.rb +52 -0
- data/lib/dox/entities/resource.rb +16 -0
- data/lib/dox/entities/resource_group.rb +15 -0
- data/lib/dox/formatter.rb +86 -0
- data/lib/dox/printers/action_printer.rb +31 -0
- data/lib/dox/printers/base_printer.rb +31 -0
- data/lib/dox/printers/document_printer.rb +29 -0
- data/lib/dox/printers/example_printer.rb +41 -0
- data/lib/dox/printers/resource_group_printer.rb +21 -0
- data/lib/dox/printers/resource_printer.rb +25 -0
- data/lib/dox/version.rb +1 -1
- metadata +20 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 77769eb7c66afabb92fdfd03814b9ba19fd4c532
|
4
|
+
data.tar.gz: 810167221ebe04073d1a33f5eecc6db0f9683589
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 47deb48ed84dbd87868adb2b360e77e3a7ecf3762e607a23e13af2024e262c8ab2b1f81a837efcca5fff386490a66f0c6b7d36100f00974738b4a3cb5380be7b
|
7
|
+
data.tar.gz: 10e5dd7824ded8945f169d9336cb0413d60121b6b4656332e43e5c860f452c073b8f9f32411dbf6cdfcb21799ba8b7f3c7add4de27979828c4c1597942267be2
|
data/README.md
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
# Dox
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
TODO: Delete this and the text above, and describe your gem
|
3
|
+
Dox formats the rspec output in the [api blueprint](https://apiblueprint.org/) format.
|
6
4
|
|
7
5
|
## Installation
|
8
6
|
|
@@ -22,7 +20,94 @@ Or install it yourself as:
|
|
22
20
|
|
23
21
|
## Usage
|
24
22
|
|
25
|
-
|
23
|
+
### Code example
|
24
|
+
|
25
|
+
Example documentation module for a resource:
|
26
|
+
|
27
|
+
``` ruby
|
28
|
+
module ApiDoc
|
29
|
+
module V1
|
30
|
+
module Bids
|
31
|
+
include Dox::DSL::Syntax
|
32
|
+
|
33
|
+
document :api do
|
34
|
+
group do
|
35
|
+
name 'Bids'
|
36
|
+
end
|
37
|
+
|
38
|
+
resource do
|
39
|
+
name 'Bids'
|
40
|
+
endpoint '/bids'
|
41
|
+
group 'Bids'
|
42
|
+
desc 'bid_resource.md'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
document :index do
|
47
|
+
action do
|
48
|
+
name 'Get bids'
|
49
|
+
verb 'GET'
|
50
|
+
path '/bids'
|
51
|
+
desc 'Returns list of user bids'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
document :create do
|
56
|
+
action do
|
57
|
+
name 'Post bids'
|
58
|
+
verb 'POST'
|
59
|
+
path '/bids'
|
60
|
+
desc 'Creates bid'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
```
|
67
|
+
Description can be included inline or relative path of a markdown file with the description (relative to configured folder for markdown descriptions).
|
68
|
+
|
69
|
+
Including the documentation module in a controller:
|
70
|
+
|
71
|
+
``` ruby
|
72
|
+
describe Api::V1::BidsController, type: :controller do
|
73
|
+
include ApiDoc::V1::Bids::Api
|
74
|
+
|
75
|
+
describe 'GET #index' do
|
76
|
+
include ApiDoc::V1::Bids::Index
|
77
|
+
|
78
|
+
it 'returns a list of bids' do
|
79
|
+
get :index
|
80
|
+
expect(response).to have_http_status(:ok)
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
85
|
+
```
|
86
|
+
|
87
|
+
### Configuration
|
88
|
+
|
89
|
+
You have to specify **root api file** and **descriptions folder**.
|
90
|
+
|
91
|
+
Root api file is a markdown file that will be included in the top of the documentation. It should contain title and some basic info about the api.
|
92
|
+
|
93
|
+
Descriptions folder is a fullpath of a folder that contains markdown files with descriptions which behave like partials and are included in the final concatenated markdown. Root api file should also be in this folder.
|
94
|
+
|
95
|
+
``` ruby
|
96
|
+
Dox.configure do |config|
|
97
|
+
config.root_api_file = 'api.md'
|
98
|
+
config.desc_folder_path = Rails.root.join('spec/support/api_doc/v1/markdown_descriptions')
|
99
|
+
end
|
100
|
+
```
|
101
|
+
|
102
|
+
### Generate HTML documentation
|
103
|
+
You have to install [aglio](https://www.npmjs.com/package/aglio).
|
104
|
+
|
105
|
+
Rake task for generating HTML:
|
106
|
+
|
107
|
+
``` ruby
|
108
|
+
`bundle exec rspec spec --tag apidoc -f Dox::Formatter --order defined --out spec/apispec.md`
|
109
|
+
`aglio --include-path / -i spec/apispec.md -o public/api/docs/index.html`
|
110
|
+
```
|
26
111
|
|
27
112
|
## Development
|
28
113
|
|
data/lib/dox.rb
CHANGED
@@ -1,5 +1,35 @@
|
|
1
|
+
require "rspec/rails"
|
1
2
|
require "dox/version"
|
3
|
+
require "dox/config"
|
4
|
+
require "dox/formatter"
|
5
|
+
require "dox/dsl/attr_proxy"
|
6
|
+
require "dox/dsl/action"
|
7
|
+
require "dox/dsl/resource"
|
8
|
+
require "dox/dsl/resource_group"
|
9
|
+
require "dox/dsl/documentation"
|
10
|
+
require "dox/dsl/syntax"
|
11
|
+
require "dox/entities/action"
|
12
|
+
require "dox/entities/example"
|
13
|
+
require "dox/entities/resource"
|
14
|
+
require "dox/entities/resource_group"
|
15
|
+
require "dox/printers/base_printer"
|
16
|
+
require "dox/printers/action_printer"
|
17
|
+
require "dox/printers/document_printer"
|
18
|
+
require "dox/printers/example_printer"
|
19
|
+
require "dox/printers/resource_group_printer"
|
20
|
+
require "dox/printers/resource_printer"
|
21
|
+
|
2
22
|
|
3
23
|
module Dox
|
4
|
-
|
24
|
+
class << self
|
25
|
+
attr_writer :config
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.configure
|
29
|
+
yield(config) if block_given?
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.config
|
33
|
+
@conifg ||= Dox::Config.new
|
34
|
+
end
|
5
35
|
end
|
data/lib/dox/config.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
module Dox
|
2
|
+
module DSL
|
3
|
+
class Action
|
4
|
+
include AttrProxy
|
5
|
+
|
6
|
+
attr_writer :name
|
7
|
+
attr_writer :verb
|
8
|
+
attr_writer :path
|
9
|
+
attr_writer :desc
|
10
|
+
attr_writer :params
|
11
|
+
|
12
|
+
def initialize(opts = {})
|
13
|
+
self.name = opts.fetch(:name, nil)
|
14
|
+
self.verb = opts.fetch(:verb, nil)
|
15
|
+
self.path = opts.fetch(:path, nil)
|
16
|
+
self.desc = opts.fetch(:desc, nil)
|
17
|
+
self.params = opts.fetch(:params, nil)
|
18
|
+
end
|
19
|
+
|
20
|
+
def param(signature)
|
21
|
+
params << signature
|
22
|
+
end
|
23
|
+
|
24
|
+
def config
|
25
|
+
Hash.new.tap do |config|
|
26
|
+
config[:action_name] = @name if @name
|
27
|
+
config[:action_verb] = @verb if @verb
|
28
|
+
config[:action_path] = @path if @path
|
29
|
+
config[:action_desc] = @desc if @desc
|
30
|
+
config[:action_params] = @params if @params
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Dox
|
2
|
+
module DSL
|
3
|
+
class Documentation
|
4
|
+
attr_accessor :subject
|
5
|
+
attr_accessor :_resource
|
6
|
+
attr_accessor :_action
|
7
|
+
attr_accessor :_group
|
8
|
+
|
9
|
+
def initialize(opts = {})
|
10
|
+
self.subject = opts.fetch :subject
|
11
|
+
end
|
12
|
+
|
13
|
+
def resource(name = nil, &block)
|
14
|
+
self._resource = Resource.new(name: name)
|
15
|
+
_resource.instance_eval(&block)
|
16
|
+
end
|
17
|
+
|
18
|
+
def action(name = nil, &block)
|
19
|
+
self._action = Action.new(name: name)
|
20
|
+
_action.instance_eval(&block)
|
21
|
+
end
|
22
|
+
|
23
|
+
def group(name = nil, &block)
|
24
|
+
self._group = ResourceGroup.new(name: name)
|
25
|
+
_group.instance_eval(&block)
|
26
|
+
end
|
27
|
+
|
28
|
+
def config
|
29
|
+
{}.merge(_resource ? _resource.config : {})
|
30
|
+
.merge(_action ? _action.config : {})
|
31
|
+
.merge(_group ? _group.config : {})
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Dox
|
2
|
+
module DSL
|
3
|
+
class Resource
|
4
|
+
include AttrProxy
|
5
|
+
|
6
|
+
attr_writer :name
|
7
|
+
attr_writer :group
|
8
|
+
attr_writer :desc
|
9
|
+
attr_writer :endpoint
|
10
|
+
|
11
|
+
def initialize(opts = {})
|
12
|
+
self.name = opts.fetch(:name, nil)
|
13
|
+
self.desc = opts.fetch(:desc, nil)
|
14
|
+
self.group = opts.fetch(:group, nil)
|
15
|
+
self.endpoint = opts.fetch(:endpoint, nil)
|
16
|
+
end
|
17
|
+
|
18
|
+
def config
|
19
|
+
{}.tap do |config|
|
20
|
+
config[:resource_name] = @name if @name
|
21
|
+
config[:resource_desc] = @desc if @desc
|
22
|
+
config[:resource_group_name] = @group if @group
|
23
|
+
config[:resource_endpoint] = @endpoint if @endpoint
|
24
|
+
config[:apidoc] = true
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Dox
|
2
|
+
module DSL
|
3
|
+
class ResourceGroup
|
4
|
+
include AttrProxy
|
5
|
+
|
6
|
+
attr_writer :name
|
7
|
+
attr_writer :desc
|
8
|
+
|
9
|
+
def initialize(opts = {})
|
10
|
+
self.name = opts.fetch(:name, nil)
|
11
|
+
self.desc = opts.fetch(:desc, nil)
|
12
|
+
end
|
13
|
+
|
14
|
+
def config
|
15
|
+
{}.tap do |config|
|
16
|
+
config[:resource_group_name] = @name if @name
|
17
|
+
config[:resource_group_desc] = @desc if @desc
|
18
|
+
config[:apidoc] = true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Dox
|
2
|
+
module DSL
|
3
|
+
module Syntax
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
class_methods do
|
7
|
+
def document(subject, &block)
|
8
|
+
documentation = _subjects[subject] = Documentation.new(subject: subject)
|
9
|
+
documentation.instance_eval(&block)
|
10
|
+
end
|
11
|
+
|
12
|
+
def const_missing(name)
|
13
|
+
documentation = _subjects[infer_subject(name)]
|
14
|
+
return super unless documentation
|
15
|
+
|
16
|
+
Module.new do
|
17
|
+
define_singleton_method :included do |base|
|
18
|
+
base.metadata.merge! documentation.config
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def infer_subject(name)
|
24
|
+
name.to_s.underscore.to_sym
|
25
|
+
end
|
26
|
+
|
27
|
+
def _subjects
|
28
|
+
@_subjects ||= {}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Dox
|
2
|
+
module Entities
|
3
|
+
class Action
|
4
|
+
|
5
|
+
attr_accessor :name, :desc, :verb, :path, :uri_params, :examples
|
6
|
+
|
7
|
+
def initialize(name, details)
|
8
|
+
@name = name
|
9
|
+
@desc = details[:action_desc]
|
10
|
+
@verb = details[:action_verb]
|
11
|
+
@path = details[:action_path]
|
12
|
+
@uri_params = details[:action_params]
|
13
|
+
@examples = []
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Dox
|
2
|
+
module Entities
|
3
|
+
class Example
|
4
|
+
|
5
|
+
attr_reader :desc, :request, :response
|
6
|
+
|
7
|
+
def initialize(details, request, response)
|
8
|
+
@desc = details[:description]
|
9
|
+
@request = request
|
10
|
+
@response = response
|
11
|
+
end
|
12
|
+
|
13
|
+
def request_parameters
|
14
|
+
request.parameters.except(*request.path_parameters.keys.map(&:to_s)).except(*request.query_parameters.keys.map(&:to_s))
|
15
|
+
end
|
16
|
+
|
17
|
+
def request_content_type
|
18
|
+
request.content_type
|
19
|
+
end
|
20
|
+
|
21
|
+
def request_identifier
|
22
|
+
fullpath
|
23
|
+
end
|
24
|
+
|
25
|
+
def response_status
|
26
|
+
response.status
|
27
|
+
end
|
28
|
+
|
29
|
+
def response_content_type
|
30
|
+
response.content_type
|
31
|
+
end
|
32
|
+
|
33
|
+
def response_body
|
34
|
+
response.body
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def path
|
40
|
+
request.path.sub(/\.json[^\?]*/, '')
|
41
|
+
end
|
42
|
+
|
43
|
+
def fullpath
|
44
|
+
if request.query_parameters.present?
|
45
|
+
URI::HTTP.build(path: path, query: request.query_parameters.to_query)
|
46
|
+
else
|
47
|
+
path
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Dox
|
2
|
+
module Entities
|
3
|
+
class Resource
|
4
|
+
|
5
|
+
attr_accessor :name, :desc, :endpoint, :actions
|
6
|
+
|
7
|
+
def initialize(name, details)
|
8
|
+
@name = name
|
9
|
+
@desc = details[:resource_desc]
|
10
|
+
@endpoint = details[:resource_endpoint]
|
11
|
+
@actions = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'rspec/core/formatters/base_formatter'
|
2
|
+
require 'pry'
|
3
|
+
|
4
|
+
module Dox
|
5
|
+
class Formatter < RSpec::Core::Formatters::BaseFormatter
|
6
|
+
|
7
|
+
RSpec::Core::Formatters.register self, :example_passed, :example_started, :stop
|
8
|
+
|
9
|
+
def initialize(output)
|
10
|
+
super
|
11
|
+
@passed_examples = {}
|
12
|
+
@group_level = 0
|
13
|
+
end
|
14
|
+
|
15
|
+
def example_started(notification)
|
16
|
+
@example_group_instance = notification.example.example_group_instance
|
17
|
+
end
|
18
|
+
|
19
|
+
def example_passed(passed)
|
20
|
+
@current_example_data = passed.example.metadata
|
21
|
+
if should_document_example?
|
22
|
+
move_example_to_passed
|
23
|
+
end
|
24
|
+
@example_group_instance = nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def stop(_notification)
|
28
|
+
printer.print(@passed_examples)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def load_or_save_group
|
34
|
+
group_name = @current_example_data[:resource_group_name]
|
35
|
+
group = @passed_examples[group_name]
|
36
|
+
|
37
|
+
if group
|
38
|
+
group.desc ||= @current_example_data[:resource_group_desc]
|
39
|
+
group
|
40
|
+
else
|
41
|
+
@passed_examples[group_name] = Entities::ResourceGroup.new(group_name, @current_example_data)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def load_or_save_resource_to_group(group)
|
46
|
+
resource_name = @current_example_data[:resource_name]
|
47
|
+
group.resources[resource_name] ||= Entities::Resource.new(resource_name, @current_example_data)
|
48
|
+
end
|
49
|
+
|
50
|
+
def load_or_save_action_to_resource(resource)
|
51
|
+
action_name = @current_example_data[:action_name]
|
52
|
+
resource.actions[action_name] ||= Entities::Action.new(action_name, @current_example_data)
|
53
|
+
end
|
54
|
+
|
55
|
+
def move_example_to_passed
|
56
|
+
group = load_or_save_group
|
57
|
+
resource = load_or_save_resource_to_group(group)
|
58
|
+
action = load_or_save_action_to_resource(resource)
|
59
|
+
action.examples << Entities::Example.new(@current_example_data, request, response)
|
60
|
+
end
|
61
|
+
|
62
|
+
def should_document_example?
|
63
|
+
@current_example_data[:apidoc] &&
|
64
|
+
!@current_example_data[:nodoc]
|
65
|
+
# error check
|
66
|
+
#&&
|
67
|
+
# @current_example_data[:resource_group] &&
|
68
|
+
# @current_example_data[:resource] &&
|
69
|
+
# @current_example_data[:action] &&
|
70
|
+
# !@current_example_data[:nodoc]
|
71
|
+
end
|
72
|
+
|
73
|
+
def request
|
74
|
+
@example_group_instance.request
|
75
|
+
end
|
76
|
+
|
77
|
+
def response
|
78
|
+
@example_group_instance.response
|
79
|
+
end
|
80
|
+
|
81
|
+
def printer
|
82
|
+
@printer ||= Printers::DocumentPrinter.new(output)
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Dox
|
2
|
+
module Printers
|
3
|
+
class ActionPrinter < BasePrinter
|
4
|
+
|
5
|
+
def print(action)
|
6
|
+
@output.puts "### #{action.name}\n\n#{print_desc(action.desc)}\n\n"
|
7
|
+
|
8
|
+
if action.uri_params.present?
|
9
|
+
@output.puts("+ Parameters\n#{formatted_params(action.uri_params)}")
|
10
|
+
end
|
11
|
+
|
12
|
+
action.examples.each do |example|
|
13
|
+
example_printer.print(example)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def example_printer
|
20
|
+
@example_printer ||= ExamplePrinter.new(@output)
|
21
|
+
end
|
22
|
+
|
23
|
+
def formatted_params(uri_params)
|
24
|
+
uri_params.map do |param, details|
|
25
|
+
" + #{CGI.escape(param.to_s)}: `#{CGI.escape(details[:value].to_s)}` (#{details[:type]}, #{details[:required]}) - #{details[:description]}"
|
26
|
+
end.flatten.join("\n")
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Dox
|
2
|
+
module Printers
|
3
|
+
class BasePrinter
|
4
|
+
|
5
|
+
attr_reader :descriptions_folder_path
|
6
|
+
|
7
|
+
def initialize(output)
|
8
|
+
@output = output
|
9
|
+
@descriptions_folder_path = Dox.config.desc_folder_path
|
10
|
+
end
|
11
|
+
|
12
|
+
def print
|
13
|
+
raise NotImplementedError
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def print_desc(desc)
|
19
|
+
return unless desc.present?
|
20
|
+
|
21
|
+
if desc.to_s =~ /.*\.md$/
|
22
|
+
path = descriptions_folder_path.join(desc).to_s
|
23
|
+
"<!-- include(#{path}) -->"
|
24
|
+
else
|
25
|
+
desc
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Dox
|
2
|
+
module Printers
|
3
|
+
class DocumentPrinter < BasePrinter
|
4
|
+
|
5
|
+
def print(passed_examples)
|
6
|
+
print_meta_info
|
7
|
+
|
8
|
+
passed_examples.sort.each do |_, resource_group|
|
9
|
+
group_printer.print(resource_group)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def group_printer
|
16
|
+
@group_printer ||= ResourceGroupPrinter.new(@output)
|
17
|
+
end
|
18
|
+
|
19
|
+
def print_meta_info
|
20
|
+
@output.puts(print_desc(api_desc_path))
|
21
|
+
end
|
22
|
+
|
23
|
+
def api_desc_path
|
24
|
+
Dox.config.root_api_file
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Dox
|
2
|
+
module Printers
|
3
|
+
class ExamplePrinter < BasePrinter
|
4
|
+
|
5
|
+
def print(example)
|
6
|
+
@output.puts "\n+ Request #{example.request_identifier} (#{example.request_content_type})"
|
7
|
+
|
8
|
+
if example.request_parameters.present?
|
9
|
+
@output.puts "\n#{indent_lines(8, pretty_json(example.request_parameters))}\n"
|
10
|
+
end
|
11
|
+
|
12
|
+
@output.puts "+ Response #{example.response_status} (#{example.response_content_type})"
|
13
|
+
|
14
|
+
if example.response_body.present?
|
15
|
+
@output.puts "\n#{indent_lines(8, pretty_json(safe_json_parse(example.response_body)))}\n"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def safe_json_parse(json_string)
|
22
|
+
json_string.length >= 2 ? JSON.parse(json_string) : nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def pretty_json(json_string)
|
26
|
+
if json_string.present?
|
27
|
+
JSON.pretty_generate(json_string)
|
28
|
+
else
|
29
|
+
''
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def indent_lines(number_of_spaces, string)
|
34
|
+
string
|
35
|
+
.split("\n")
|
36
|
+
.map { |a| a.prepend(' ' * number_of_spaces) }
|
37
|
+
.join("\n")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Dox
|
2
|
+
module Printers
|
3
|
+
class ResourceGroupPrinter < BasePrinter
|
4
|
+
|
5
|
+
def print(resource_group)
|
6
|
+
@output.puts "\n# Group #{resource_group.name}\n\n#{print_desc(resource_group.desc)}\n"
|
7
|
+
|
8
|
+
resource_group.resources.each do |_, resource|
|
9
|
+
resource_printer.print(resource)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def resource_printer
|
16
|
+
@resource_printer ||= ResourcePrinter.new(@output)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Dox
|
2
|
+
module Printers
|
3
|
+
class ResourcePrinter < BasePrinter
|
4
|
+
|
5
|
+
def print(resource)
|
6
|
+
if resource.endpoint.present?
|
7
|
+
@output.puts "\n## #{resource.name} [#{resource.endpoint}]\n\n#{print_desc(resource.desc)}\n"
|
8
|
+
else
|
9
|
+
@output.puts "## #{resource.name}"
|
10
|
+
end
|
11
|
+
|
12
|
+
resource.actions.each do |_, action|
|
13
|
+
action_printer.print(action)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def action_printer
|
20
|
+
@action_printer ||= ActionPrinter.new(@output)
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/dox/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dox
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Melita Kokot
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-06-
|
11
|
+
date: 2016-06-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -71,6 +71,24 @@ files:
|
|
71
71
|
- bin/setup
|
72
72
|
- dox.gemspec
|
73
73
|
- lib/dox.rb
|
74
|
+
- lib/dox/config.rb
|
75
|
+
- lib/dox/dsl/action.rb
|
76
|
+
- lib/dox/dsl/attr_proxy.rb
|
77
|
+
- lib/dox/dsl/documentation.rb
|
78
|
+
- lib/dox/dsl/resource.rb
|
79
|
+
- lib/dox/dsl/resource_group.rb
|
80
|
+
- lib/dox/dsl/syntax.rb
|
81
|
+
- lib/dox/entities/action.rb
|
82
|
+
- lib/dox/entities/example.rb
|
83
|
+
- lib/dox/entities/resource.rb
|
84
|
+
- lib/dox/entities/resource_group.rb
|
85
|
+
- lib/dox/formatter.rb
|
86
|
+
- lib/dox/printers/action_printer.rb
|
87
|
+
- lib/dox/printers/base_printer.rb
|
88
|
+
- lib/dox/printers/document_printer.rb
|
89
|
+
- lib/dox/printers/example_printer.rb
|
90
|
+
- lib/dox/printers/resource_group_printer.rb
|
91
|
+
- lib/dox/printers/resource_printer.rb
|
74
92
|
- lib/dox/version.rb
|
75
93
|
homepage: https://github.com/infinum/dox
|
76
94
|
licenses:
|
@@ -98,4 +116,3 @@ signing_key:
|
|
98
116
|
specification_version: 4
|
99
117
|
summary: Generates API documentation for rspec in api blueprint format.
|
100
118
|
test_files: []
|
101
|
-
has_rdoc:
|