dictum 0.0.5 → 0.0.6
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/.rubocop.yml +1 -0
- data/Gemfile +4 -3
- data/README.md +19 -0
- data/TODO.md +1 -1
- data/dictum.gemspec +1 -1
- data/lib/dictum.rb +12 -3
- data/lib/dictum/constants.rb +3 -0
- data/lib/dictum/documenter.rb +19 -4
- data/lib/dictum/html_helpers.rb +24 -0
- data/lib/dictum/html_writer.rb +35 -5
- data/lib/dictum/markdown_writer.rb +16 -0
- data/lib/dictum/version.rb +1 -1
- data/lib/tasks/default_initializer +1 -0
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c7497e8af6c6c8ca44b6d22efcc8d35c2e7fdced
|
4
|
+
data.tar.gz: 4035ae72c64eeb23ba13ca9e6cceca97750f889f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ba691003c2487a7871b7a2ce6af0782bb1b8655a22adddbb25fe33eba196fb4d3dc8905b291cf6dfd12781fd3c1a57adc92d2161940582fbc276c099f347bdeb
|
7
|
+
data.tar.gz: 42c8d20e80ca2b825e87812d208800a0406f863d255cb4ddc4d3f1646cd131bb949f51846901d361c2b1be7369a1f20357c3b9c5d666f7863c4a6ea65363f32e
|
data/.rubocop.yml
CHANGED
data/Gemfile
CHANGED
@@ -3,9 +3,10 @@ source 'https://rubygems.org'
|
|
3
3
|
# Specify your gem's dependencies in crf.gemspec
|
4
4
|
gemspec
|
5
5
|
|
6
|
-
gem 'rake', '~>
|
7
|
-
gem 'json', '~>
|
6
|
+
gem 'rake', '~> 12.0'
|
7
|
+
gem 'json', '~> 2.0'
|
8
8
|
|
9
9
|
group :test do
|
10
|
-
gem '
|
10
|
+
gem 'simplecov'
|
11
|
+
gem 'codeclimate-test-reporter', '~> 1.0.0'
|
11
12
|
end
|
data/README.md
CHANGED
@@ -128,6 +128,25 @@ And voilà, Dictum will create a document like this in '/docs/Documentation' (se
|
|
128
128
|
"no_content"
|
129
129
|
```
|
130
130
|
|
131
|
+
# Error codes
|
132
|
+
|
133
|
+
Dictum supports the documentation of the custom error codes of your API. In order to do this you need to send an array of errors with a specific format, like the following:
|
134
|
+
|
135
|
+
```ruby
|
136
|
+
ERROR_CODES = [
|
137
|
+
{
|
138
|
+
code: 1234,
|
139
|
+
message: 'This is a short description of the error, usually what is returned in the body of the response.',
|
140
|
+
description: 'This is a larger and more detailed description of the error, usually you want to show this only in the documentation'
|
141
|
+
}
|
142
|
+
]
|
143
|
+
|
144
|
+
# spec_helper.rb
|
145
|
+
Dictum.error_codes(ERROR_CODES)
|
146
|
+
```
|
147
|
+
|
148
|
+
We recommend you to define your error codes in a module or class with useful methods like get(error_code) and get_all, [like this one](https://gist.github.com/alebian/1b925151b6a6acd3e4bb2ef4b5148324).
|
149
|
+
|
131
150
|
# Advanced usage
|
132
151
|
|
133
152
|
If you pay attention to the basic usage, you will notice that it is a lot of boilerplate if your API has a lot of endpoints, this is not DRY. Luckily you can work around it using some Rspec tricks:
|
data/TODO.md
CHANGED
data/dictum.gemspec
CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
20
|
spec.test_files = spec.files.grep(%r{^(test|spec)/})
|
21
21
|
|
22
|
-
spec.add_dependency 'nokogiri', '~> 1.
|
22
|
+
spec.add_dependency 'nokogiri', '~> 1.7'
|
23
23
|
|
24
24
|
spec.add_development_dependency 'bundler', '>= 1.3.0', '< 2.0'
|
25
25
|
spec.add_development_dependency 'rspec', '~> 3.4', '>= 3.4.0'
|
data/lib/dictum.rb
CHANGED
@@ -8,6 +8,8 @@ require 'tmpdir'
|
|
8
8
|
module Dictum
|
9
9
|
load 'tasks/dictum.rake' if defined?(Rails)
|
10
10
|
|
11
|
+
TEMPFILE_PATH = "#{Dir.tmpdir}/dictum_temp.json".freeze
|
12
|
+
|
11
13
|
@config = {
|
12
14
|
output_format: :markdown,
|
13
15
|
output_path: "#{Dir.tmpdir}/docs",
|
@@ -73,6 +75,14 @@ module Dictum
|
|
73
75
|
Documenter.instance.endpoint(arguments)
|
74
76
|
end
|
75
77
|
|
78
|
+
##
|
79
|
+
# Method used to add a new error code.
|
80
|
+
# @param codes_list is an array of hashes representing the code, message and description
|
81
|
+
#
|
82
|
+
def self.error_codes(codes_list)
|
83
|
+
codes_list.each { |error| Documenter.instance.error_code(error) }
|
84
|
+
end
|
85
|
+
|
76
86
|
##
|
77
87
|
# Method that will execute tests and then save the results in the selected format
|
78
88
|
#
|
@@ -88,13 +98,12 @@ module Dictum
|
|
88
98
|
def self.save_to_file
|
89
99
|
writer = nil
|
90
100
|
output_filename = "#{@config[:output_path]}/#{@config[:output_filename]}"
|
91
|
-
tempfile_path = Documenter.instance.tempfile_path
|
92
101
|
|
93
102
|
case @config[:output_format]
|
94
103
|
when :markdown
|
95
|
-
writer = MarkdownWriter.new(output_filename,
|
104
|
+
writer = MarkdownWriter.new(output_filename, TEMPFILE_PATH, @config)
|
96
105
|
when :html
|
97
|
-
writer = HtmlWriter.new(output_filename,
|
106
|
+
writer = HtmlWriter.new(output_filename, TEMPFILE_PATH, @config)
|
98
107
|
end
|
99
108
|
|
100
109
|
writer.write
|
data/lib/dictum/documenter.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'singleton'
|
2
2
|
require 'tmpdir'
|
3
|
+
require_relative 'constants'
|
3
4
|
|
4
5
|
module Dictum
|
5
6
|
##
|
@@ -7,13 +8,11 @@ module Dictum
|
|
7
8
|
#
|
8
9
|
class Documenter
|
9
10
|
include Singleton
|
10
|
-
|
11
11
|
attr_reader :data, :tempfile_path
|
12
|
-
TEMPFILE_NAME = 'dictum_temp.json'.freeze
|
13
12
|
|
14
13
|
def initialize
|
15
14
|
reset_data
|
16
|
-
@tempfile_path =
|
15
|
+
@tempfile_path = Dictum::TEMPFILE_PATH
|
17
16
|
end
|
18
17
|
|
19
18
|
def resource(arguments = {})
|
@@ -36,9 +35,21 @@ module Dictum
|
|
36
35
|
update_temp
|
37
36
|
end
|
38
37
|
|
38
|
+
def error_code(error = {})
|
39
|
+
return if error.nil? || !error.is_a?(Hash)
|
40
|
+
error_hash = {
|
41
|
+
code: error[:code] || Dictum::MISSING_MESSAGE,
|
42
|
+
message: error[:message] || '',
|
43
|
+
description: error[:description] || ''
|
44
|
+
}
|
45
|
+
error_codes << error_hash
|
46
|
+
update_temp
|
47
|
+
end
|
48
|
+
|
39
49
|
def reset_data
|
40
50
|
@data = {
|
41
|
-
resources: {}
|
51
|
+
resources: {},
|
52
|
+
error_codes: []
|
42
53
|
}
|
43
54
|
end
|
44
55
|
|
@@ -48,6 +59,10 @@ module Dictum
|
|
48
59
|
@data[:resources]
|
49
60
|
end
|
50
61
|
|
62
|
+
def error_codes
|
63
|
+
@data[:error_codes]
|
64
|
+
end
|
65
|
+
|
51
66
|
def update_temp
|
52
67
|
File.delete(tempfile_path) if File.exist?(tempfile_path)
|
53
68
|
file = File.open(tempfile_path, 'w+')
|
data/lib/dictum/html_helpers.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
module Dictum
|
2
|
+
# rubocop:disable ClassLength
|
2
3
|
class HtmlHelpers
|
3
4
|
BOOTSTRAP_JS = 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js'.freeze
|
4
5
|
BOOTSTRAP_CSS = 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css'.freeze
|
@@ -111,6 +112,29 @@ module Dictum
|
|
111
112
|
end
|
112
113
|
answer += ">#{content}</#{name}>"
|
113
114
|
end
|
115
|
+
|
116
|
+
def table(headers, rows)
|
117
|
+
return '' unless headers
|
118
|
+
answer = table_headers(headers)
|
119
|
+
answer += table_rows(rows)
|
120
|
+
tag('table', answer, class: 'table')
|
121
|
+
end
|
122
|
+
|
123
|
+
private
|
124
|
+
|
125
|
+
def table_headers(headers)
|
126
|
+
answer = ''
|
127
|
+
headers.each { |header| answer += tag('th', header) }
|
128
|
+
tag('tr', answer)
|
129
|
+
end
|
130
|
+
|
131
|
+
def table_rows(rows)
|
132
|
+
answer = ''
|
133
|
+
rows.each do |row|
|
134
|
+
answer += tag('tr', tag('td', row[0]) + tag('td', row[1]) + tag('td', row[2]))
|
135
|
+
end
|
136
|
+
answer
|
137
|
+
end
|
114
138
|
end
|
115
139
|
end
|
116
140
|
end
|
data/lib/dictum/html_writer.rb
CHANGED
@@ -3,7 +3,13 @@ require 'json'
|
|
3
3
|
require 'nokogiri'
|
4
4
|
|
5
5
|
module Dictum
|
6
|
+
# rubocop:disable ClassLength
|
6
7
|
class HtmlWriter
|
8
|
+
ERROR_CODE_URL = 'error_codes'.freeze
|
9
|
+
ERROR_CODE_TEXT = 'Error codes'.freeze
|
10
|
+
RESOURCES_TEXT = 'Resources'.freeze
|
11
|
+
BACK_TEXT = 'Back'.freeze
|
12
|
+
|
7
13
|
attr_reader :temp_path, :temp_json, :output_dir, :output_file, :header_title
|
8
14
|
|
9
15
|
def initialize(output_dir, temp_path, config)
|
@@ -28,10 +34,14 @@ module Dictum
|
|
28
34
|
index.close
|
29
35
|
end
|
30
36
|
|
37
|
+
# rubocop:disable LineLength
|
38
|
+
# rubocop:disable AbcSize
|
31
39
|
def write_index
|
32
40
|
html = HtmlHelpers.build do |b|
|
33
41
|
content = b.jumbotron(b.title(@config[:index_title], 'title'))
|
42
|
+
content += b.title(RESOURCES_TEXT)
|
34
43
|
content += b.unordered_list(resources.keys)
|
44
|
+
content += b.link("#{ERROR_CODE_URL}.html", b.subtitle(ERROR_CODE_TEXT)) unless error_codes.empty?
|
35
45
|
container = b.container(b.row(content))
|
36
46
|
b.html_header(header_title, container, @config[:inline_css])
|
37
47
|
end
|
@@ -42,18 +52,23 @@ module Dictum
|
|
42
52
|
resources.each do |resource_name, information|
|
43
53
|
write_page(resource_name, information)
|
44
54
|
end
|
55
|
+
write_error_codes_page unless error_codes.empty?
|
45
56
|
end
|
46
57
|
|
47
58
|
def resources
|
48
59
|
temp_json['resources']
|
49
60
|
end
|
50
61
|
|
62
|
+
def error_codes
|
63
|
+
temp_json['error_codes']
|
64
|
+
end
|
65
|
+
|
51
66
|
def write_page(resource_name, information)
|
52
67
|
html = HtmlHelpers.build do |b|
|
53
68
|
content = resource_header_and_endpoints(
|
54
69
|
resource_name, information['description'], information['endpoints'], b
|
55
70
|
)
|
56
|
-
container = b.container(b.row(content) + b.row(b.button(
|
71
|
+
container = b.container(b.row(content) + b.row(b.button(BACK_TEXT)))
|
57
72
|
b.html_header(header_title, container, @config[:inline_css])
|
58
73
|
end
|
59
74
|
write_to_file("#{output_dir}/#{resource_name.downcase}.html", html)
|
@@ -83,10 +98,7 @@ module Dictum
|
|
83
98
|
|
84
99
|
def write_response(endpoint, builder)
|
85
100
|
answer = builder.code_block('Status', endpoint['response_status'])
|
86
|
-
answer += write_codeblock(
|
87
|
-
'Response headers', endpoint['response_headers'], builder
|
88
|
-
) if endpoint['response_headers']
|
89
|
-
|
101
|
+
answer += write_codeblock('Response headers', endpoint['response_headers'], builder) if endpoint['response_headers']
|
90
102
|
if endpoint['response_body']
|
91
103
|
param = endpoint['response_body'] == 'no_content' ? {} : endpoint['response_body']
|
92
104
|
answer += write_codeblock('Response body', param, builder)
|
@@ -99,5 +111,23 @@ module Dictum
|
|
99
111
|
sanitized_json = json.empty? ? {} : json
|
100
112
|
builder.code_block(text, JSON.pretty_generate(sanitized_json))
|
101
113
|
end
|
114
|
+
|
115
|
+
def write_error_codes_page
|
116
|
+
html = HtmlHelpers.build do |b|
|
117
|
+
content = b.title(ERROR_CODE_TEXT, 'title')
|
118
|
+
content += b.table(error_code_table_header, error_codes_as_rows)
|
119
|
+
container = b.container(b.row(content) + b.row(b.button(BACK_TEXT)))
|
120
|
+
b.html_header(header_title, container, @config[:inline_css])
|
121
|
+
end
|
122
|
+
write_to_file("#{output_dir}/#{ERROR_CODE_URL}.html", html)
|
123
|
+
end
|
124
|
+
|
125
|
+
def error_code_table_header
|
126
|
+
%w(Code Description Message)
|
127
|
+
end
|
128
|
+
|
129
|
+
def error_codes_as_rows
|
130
|
+
error_codes.map { |a| [a['code'], a['description'], a['message']] }
|
131
|
+
end
|
102
132
|
end
|
103
133
|
end
|
@@ -16,6 +16,7 @@ module Dictum
|
|
16
16
|
@output_file = File.open(output_path, 'a+')
|
17
17
|
write_index
|
18
18
|
write_temp_path
|
19
|
+
write_error_codes
|
19
20
|
output_file.close
|
20
21
|
end
|
21
22
|
|
@@ -37,6 +38,17 @@ module Dictum
|
|
37
38
|
end
|
38
39
|
end
|
39
40
|
|
41
|
+
def write_error_codes
|
42
|
+
return if error_codes.empty?
|
43
|
+
output_file.puts "# Error codes"
|
44
|
+
output_file.puts "|Code|Message|Description|"
|
45
|
+
output_file.puts "|----|----|----|"
|
46
|
+
error_codes.each do |error|
|
47
|
+
output_file.puts "|#{error['code']}|#{error['message']}|#{error['description']}|"
|
48
|
+
end
|
49
|
+
output_file.puts "\n"
|
50
|
+
end
|
51
|
+
|
40
52
|
def write_endpoints(endpoints)
|
41
53
|
endpoints.each do |endpoint|
|
42
54
|
output_file.puts "## #{endpoint['http_verb']} #{endpoint['endpoint']}\n\n"
|
@@ -70,5 +82,9 @@ module Dictum
|
|
70
82
|
output_file.puts "\#\#\# #{subtitle}:"
|
71
83
|
output_file.puts "```json\n#{JSON.pretty_generate(sanitized_contents)}\n```\n\n"
|
72
84
|
end
|
85
|
+
|
86
|
+
def error_codes
|
87
|
+
temp_json['error_codes']
|
88
|
+
end
|
73
89
|
end
|
74
90
|
end
|
data/lib/dictum/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dictum
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alejandro Bezdjian
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-02-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
19
|
+
version: '1.7'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1.
|
26
|
+
version: '1.7'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -124,6 +124,7 @@ files:
|
|
124
124
|
- example.gif
|
125
125
|
- example.md
|
126
126
|
- lib/dictum.rb
|
127
|
+
- lib/dictum/constants.rb
|
127
128
|
- lib/dictum/documenter.rb
|
128
129
|
- lib/dictum/html_helpers.rb
|
129
130
|
- lib/dictum/html_writer.rb
|