dictum 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 217d2599c6e42803dae17c91e5f912b62c9c1c69
4
- data.tar.gz: 67ea4dea1683a6d22bfcb6a83ad6bc39b981a235
3
+ metadata.gz: 1abfdfd254c6440dd20d29a1f76339d413512ee5
4
+ data.tar.gz: 01f93d8ee750b724a6c93e4a9beabab729cadfbe
5
5
  SHA512:
6
- metadata.gz: d0d2f490887e718e421ead994f06fb3dd5603465aceb15773ed673ed63a49997ba77d18a52eda092cef8dbed17efb884508b179e78ae7a6508d90ecd66c9508c
7
- data.tar.gz: 749835247251aa4c2e79d273d50ae6e47f1de9b79ee8e78d18febdfa46477a79868465d219bc91001b2011ef65806d5ef2ed4c326c97b62a453abbe6cb232b06
6
+ metadata.gz: 43e9db9a4c534ffb44e4a648fff63f44a5c38565e716708dc2beff30d8cd6b31046f487f8769ccf1ebd89d74aff15145e4b51b861f5ad9847a001955c784b621
7
+ data.tar.gz: 96012528a2372d4bc8879367c4f64462e2209b6e9138f6ee7f5d40969910a1706e269a3e39a1d6973cdee088b6c2b4ab9c8d9c206473cb7066b6ae9af21fe591
@@ -11,3 +11,6 @@ LineLength:
11
11
 
12
12
  FrozenStringLiteralComment:
13
13
  Enabled: false
14
+
15
+ Metrics/AbcSize:
16
+ Max: 15.3
@@ -1,6 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.9.3
4
3
  - 2.0.0
5
4
  - 2.1
6
5
  - 2.2
data/README.md CHANGED
@@ -25,7 +25,11 @@ Or install it yourself as:
25
25
 
26
26
  ## Basic usage
27
27
 
28
- First you need to set a configuration file inside /config/initializers/dictum.rb
28
+ First run:
29
+
30
+ $ bundle exec rake dictum:configure [PATH_TO_HELPER_FILE]
31
+
32
+ This will create a basic Rspec configuration in 'spec/support/spec_helper.rb' or in PATH_TO_HELPER_FILE. Also it will create a configuration file inside /config/initializers/dictum.rb
29
33
 
30
34
  ```ruby
31
35
  # /config/initializers/dictum.rb
@@ -34,6 +38,7 @@ Dictum.configure do |config|
34
38
  config.root_path = Rails.root
35
39
  config.output_filename = 'Documentation'
36
40
  config.output_format = :markdown
41
+ config.index_title = 'My Documentation Title'
37
42
  end
38
43
  ```
39
44
 
@@ -78,9 +83,9 @@ Then execute:
78
83
 
79
84
  $ bundle exec rake dictum:document
80
85
 
81
- And voilà, Dictum will create a document like this in '/docs/Documentation':
86
+ And voilà, Dictum will create a document like this in '/docs/Documentation' (see [example.md](https://github.com/Wolox/dictum/blob/master/example.md)):
82
87
 
83
- # Index
88
+ # My Documentation Title
84
89
  - MyResource
85
90
 
86
91
  # MyResource
@@ -125,20 +130,14 @@ And voilà, Dictum will create a document like this in '/docs/Documentation':
125
130
 
126
131
  # Advanced usage
127
132
 
128
- If you pay attention to the basic usage, you will notice that much code is needed if your API has a lot of endpoints, this is not DRY and adds unnecesary boilerplate. Luckily you can work around it using some Rspec tricks:
133
+ 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:
129
134
 
130
135
  ```ruby
131
- # spec/controllers/my_resource_controller_spec.rb
132
- require 'rails_helper'
133
-
134
- describe V1::MyResourceController do
135
- Dictum.resource(
136
- name: 'MyResource',
137
- description: 'This is MyResource description.'
138
- )
139
-
140
- after(:each) do |test|
136
+ # spec/rails_helper.rb
137
+ RSpec.configure do |config|
138
+ config.after(:each) do |test|
141
139
  if test.metadata[:dictum]
140
+ Dictum.endpoint(
142
141
  Dictum.endpoint(
143
142
  resource: test.metadata[:described_class].to_s.gsub('V1::', '').gsub('Controller', ''),
144
143
  endpoint: request.fullpath,
@@ -152,35 +151,14 @@ describe V1::MyResourceController do
152
151
  response_headers: response.headers,
153
152
  response_status: response.status,
154
153
  response_body: response_body
155
- end
156
- end
157
-
158
- describe '#some_method' do
159
- context 'some context for my resource' do
160
- it 'returns status ok', dictum: true, dictum_description: 'Some description of the endpoint.' do
161
- get :index
162
- expect(response_status).to eq(200)
163
- end
164
- end
165
- end
166
- end
167
- ```
168
-
169
- This is much better, but it is not DRYed enough because you would have to repeat the after(:each) declaration on every controller spec you have, so you can still improve it a bit more:
170
-
171
- ```ruby
172
- # spec/rails_helper.rb
173
- RSpec.configure do |config|
174
- config.after(:each) do |test|
175
- if test.metadata[:dictum]
176
- Dictum.endpoint(
177
- # All the parameters that you want
178
154
  )
179
155
  end
180
156
  end
181
157
  end
182
158
  ```
183
159
 
160
+ A file similar (and more complete) to that one is created when you run the rake dictum:configure task.
161
+
184
162
  ```ruby
185
163
  # spec/controllers/my_resource_controller_spec.rb
186
164
  require 'rails_helper'
@@ -202,6 +180,8 @@ describe V1::MyResourceController do
202
180
  end
203
181
  ```
204
182
 
183
+ This is how your controller test should look now, much better.
184
+
205
185
  # Dynamic HTML documentation
206
186
 
207
187
  So far so good, but your team needs to read the documentation everytime you update it, and sending the documentation file to them doesn't seem too practical. Instead you can use the HTML version of Dictum and generate static views with the content. Here is a very basic example of what you can do to generate the views and routes dynamycally:
@@ -213,6 +193,9 @@ Dictum.configure do |config|
213
193
  config.root_path = Rails.root
214
194
  config.output_filename = 'docs'
215
195
  config.output_format = :html
196
+ config.index_title = 'My documentation title'
197
+ config.header_title = 'API doc'
198
+ config.inline_css = File.read(Rails.root.join('app', 'assets', 'stylesheets', 'documentation.css'))
216
199
  end
217
200
  ```
218
201
 
@@ -234,6 +217,14 @@ end
234
217
 
235
218
  Of course you will need to have a controller for this, in this case one named 'docs_controller.rb'. And finally go to 'http://localhost:3000/docs/index.html'
236
219
 
220
+ This is an HTML example:
221
+
222
+ <p align="center">
223
+ <img src="https://raw.githubusercontent.com/Wolox/dictum/master/example.gif">
224
+ </p>
225
+
226
+ You can customize the HTML using css like this [example](https://raw.githubusercontent.com/Wolox/dictum/master/example.css).
227
+
237
228
  ## Contributing
238
229
 
239
230
  1. Fork it
@@ -19,10 +19,10 @@ 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 'htmlbeautifier', '~> 1.1', '>= 1.1.1'
22
+ spec.add_dependency 'nokogiri', '~> 1.6'
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'
26
26
  spec.add_development_dependency 'byebug', '~> 8.0', '>= 8.0.0' if RUBY_VERSION >= '2.0.0'
27
- spec.add_development_dependency 'rubocop', '~> 0.38', '>= 0.38.2'
27
+ spec.add_development_dependency 'rubocop', '~> 0.40', '>= 0.40.0'
28
28
  end
@@ -0,0 +1,84 @@
1
+ body {
2
+ background-color: white;
3
+ }
4
+
5
+ ul {
6
+ list-style-type: disc;
7
+ }
8
+
9
+ a {
10
+ color: blue;
11
+ font-family: sans-serif;
12
+ font-weight: bold;
13
+ }
14
+
15
+ .jumbotron {
16
+ background-color: grey;
17
+ }
18
+
19
+ pre {
20
+ background-color: grey;
21
+ }
22
+
23
+ .jumbotron > h1{
24
+ color: black;
25
+ font-family: sans-serif;
26
+ font-weight: bold;
27
+ text-transform: uppercase;
28
+ font-size: 50px;
29
+ }
30
+
31
+ h1 {
32
+ color: black;
33
+ font-family: sans-serif;
34
+ font-weight: bold;
35
+ text-transform: uppercase;
36
+ font-size: 40px;
37
+ }
38
+
39
+ p {
40
+ color: black;
41
+ font-family: sans-serif;
42
+ }
43
+
44
+ h3 {
45
+ color: black;
46
+ font-family: sans-serif;
47
+ font-weight: bold;
48
+ font-size: 30px;
49
+ }
50
+
51
+ h4 {
52
+ color: grey;
53
+ font-family: sans-serif;
54
+ font-weight: bold;
55
+ text-transform: uppercase;
56
+ font-size: 20px;
57
+ }
58
+
59
+ .dictum-button {
60
+ background-color: white;
61
+ border-color: black;
62
+ color: black;
63
+ margin-right: 10px;
64
+ }
65
+
66
+ .dictum-button > p {
67
+ font-family: sans-serif;
68
+ text-transform: uppercase;
69
+ display: inline;
70
+ }
71
+
72
+ .dictum-button:hover {
73
+ background-color: transparent;
74
+ border-color: blue;
75
+ color: blue;
76
+ }
77
+
78
+ span.lit, span.kwd {
79
+ color: green;
80
+ }
81
+
82
+ span.pun, span.str {
83
+ color: black;
84
+ }
Binary file
@@ -0,0 +1,42 @@
1
+ # Index
2
+ - MyResource
3
+
4
+ # MyResource
5
+ This is MyResource description.
6
+
7
+ ## POST /api/v1/my_resource
8
+
9
+ ### Description:
10
+ Some description of the endpoint.
11
+
12
+ ### Request headers:
13
+ ```json
14
+ {
15
+ "AUTHORIZATION" : "user_token",
16
+ "Content-Type" : "application/json",
17
+ "Accept" : "application/json"
18
+ }
19
+ ```
20
+
21
+ ### Path parameters:
22
+ ```json
23
+ { "id": 1, "page": 1 }
24
+ ```
25
+
26
+ ### Body parameters:
27
+ ```json
28
+ { "some": "parameter" }
29
+ ```
30
+
31
+ ### Response headers:
32
+ ```json
33
+ { "some_header": "some_header_value" }
34
+ ```
35
+
36
+ ### Response status:
37
+ 200
38
+
39
+ ### Response body:
40
+ ```json
41
+ "no_content"
42
+ ```
@@ -13,7 +13,10 @@ module Dictum
13
13
  output_path: "#{Dir.tmpdir}/docs",
14
14
  root_path: Dir.tmpdir,
15
15
  test_suite: :rspec,
16
- output_filename: 'Documentation'
16
+ output_filename: 'Documentation',
17
+ index_title: 'Index',
18
+ header_title: 'Dictum',
19
+ inline_css: nil
17
20
  }
18
21
 
19
22
  def self.configure
@@ -40,6 +43,18 @@ module Dictum
40
43
  @config[:output_filename] = file
41
44
  end
42
45
 
46
+ def self.index_title=(title)
47
+ @config[:index_title] = title
48
+ end
49
+
50
+ def self.header_title=(title)
51
+ @config[:header_title] = title
52
+ end
53
+
54
+ def self.inline_css=(style)
55
+ @config[:inline_css] = style
56
+ end
57
+
43
58
  def self.config
44
59
  @config
45
60
  end
@@ -63,7 +78,7 @@ module Dictum
63
78
  #
64
79
  def self.document
65
80
  Dir.mkdir(@config[:output_path]) unless Dir.exist?(@config[:output_path])
66
- Documenter.instance.reset_resources
81
+ Documenter.instance.reset_data
67
82
 
68
83
  system "bundle exec rspec #{@config[:root_path]}" if @config[:test_suite] == :rspec
69
84
 
@@ -77,9 +92,9 @@ module Dictum
77
92
 
78
93
  case @config[:output_format]
79
94
  when :markdown
80
- writer = MarkdownWriter.new(output_filename, tempfile_path)
95
+ writer = MarkdownWriter.new(output_filename, tempfile_path, @config)
81
96
  when :html
82
- writer = HtmlWriter.new(output_filename, tempfile_path, 'Dictum')
97
+ writer = HtmlWriter.new(output_filename, tempfile_path, @config)
83
98
  end
84
99
 
85
100
  writer.write
@@ -8,21 +8,22 @@ module Dictum
8
8
  class Documenter
9
9
  include Singleton
10
10
 
11
- attr_reader :resources, :tempfile_path
11
+ attr_reader :data, :tempfile_path
12
12
  TEMPFILE_NAME = 'dictum_temp.json'.freeze
13
13
 
14
14
  def initialize
15
- @resources = {}
15
+ reset_data
16
16
  @tempfile_path = "#{Dir.tmpdir}/#{TEMPFILE_NAME}"
17
17
  end
18
18
 
19
19
  def resource(arguments = {})
20
20
  return if arguments.nil?
21
21
  name = arguments[:name]
22
+ description = arguments[:description]
22
23
  return if name.nil?
23
- @resources[name] ||= {}
24
- @resources[name][:description] = arguments[:description] if arguments[:description]
25
- @resources[name][:endpoints] ||= []
24
+ resources[name] ||= {}
25
+ resources[name][:description] = description if description
26
+ resources[name][:endpoints] ||= []
26
27
  update_temp
27
28
  end
28
29
 
@@ -30,21 +31,27 @@ module Dictum
30
31
  resource = arguments[:resource]
31
32
  endpoint = arguments[:endpoint]
32
33
  return if resource.nil? || endpoint.nil?
33
- resource(name: arguments[:resource]) unless @resources.key? arguments[:resource]
34
- @resources[resource][:endpoints] << arguments_hash(arguments)
34
+ resource(name: resource) unless resources.key? resource
35
+ resources[resource][:endpoints] << arguments_hash(arguments)
35
36
  update_temp
36
37
  end
37
38
 
38
- def reset_resources
39
- @resources = {}
39
+ def reset_data
40
+ @data = {
41
+ resources: {}
42
+ }
40
43
  end
41
44
 
42
45
  private
43
46
 
47
+ def resources
48
+ @data[:resources]
49
+ end
50
+
44
51
  def update_temp
45
52
  File.delete(tempfile_path) if File.exist?(tempfile_path)
46
53
  file = File.open(tempfile_path, 'w+')
47
- file.write(JSON.generate(@resources))
54
+ file.write(JSON.generate(@data))
48
55
  file.close
49
56
  end
50
57
 
@@ -10,23 +10,19 @@ module Dictum
10
10
  yield self
11
11
  end
12
12
 
13
- def html_header(title, body_content)
14
- "<!DOCTYPE html>\n<html>\n<head>\n<title>#{title}</title>\n#{external_css(BOOTSTRAP_CSS)}"\
15
- "\n<style>\n#{page_css}\n</style>\n</head>\n<body>\n#{body_content}" \
16
- "#{script(JQUERY)}\n#{script(BOOTSTRAP_JS)}\n#{script(PRETTIFY)}\n</body>\n</html>"
13
+ def html_header(title, body_content, inline_css = nil)
14
+ "<!DOCTYPE html><html><head><title>#{title}</title>#{external_css(BOOTSTRAP_CSS)}"\
15
+ "#{inline_css(inline_css)}</head><body>#{body_content}" \
16
+ "#{script(JQUERY)}#{script(BOOTSTRAP_JS)}#{script(PRETTIFY)}</body></html>"
17
17
  end
18
18
 
19
19
  def container(content)
20
- tag('div', "\n#{content}\n", class: 'container-fluid')
20
+ tag('div', content.to_s, class: 'container-fluid')
21
21
  end
22
22
 
23
23
  def row(content)
24
- internal_div = tag('div', "\n#{content}\n", class: 'col-md-8 col-md-offset-2')
25
- tag('div', "\n#{internal_div}", class: 'row')
26
- end
27
-
28
- def page_css
29
- ''
24
+ internal_div = tag('div', content.to_s, class: 'col-md-8 col-md-offset-2')
25
+ tag('div', internal_div.to_s, class: 'row')
30
26
  end
31
27
 
32
28
  def script(script_path)
@@ -36,48 +32,59 @@ module Dictum
36
32
 
37
33
  def external_css(css_path)
38
34
  return '' unless css_path
39
- "<link rel='stylesheet' href='#{css_path}' />\n"
35
+ "<link rel='stylesheet' href='#{css_path}' />"
36
+ end
37
+
38
+ def inline_css(style)
39
+ return '' unless style
40
+ "<style>#{style}</style>"
40
41
  end
41
42
 
42
43
  def unordered_list(elements)
43
- return "<ul>\n</ul>\n" unless elements
44
- answer = "<ul>\n"
44
+ return '<ul></ul>' unless elements
45
+ answer = '<ul>'
45
46
  elements.each do |element|
46
- answer += "<li><a href='#{element.downcase}.html'>#{element}</a></li>\n"
47
+ answer += list_item(link("#{element.downcase}.html", element))
47
48
  end
48
- answer += "</ul>\n"
49
+ answer += '</ul>'
50
+ end
51
+
52
+ def list_item(content)
53
+ tag('li', content)
49
54
  end
50
55
 
51
56
  def link(href, content)
52
- tag('a', content, href: href)
57
+ tag('a', content, href: './' + href)
53
58
  end
54
59
 
55
60
  def title(text, html_class = nil)
56
- return "<h1>#{text}</h1>\n" unless html_class
61
+ return "<h1>#{text}</h1>" unless html_class
57
62
  tag('h1', text, class: html_class)
58
63
  end
59
64
 
60
65
  def subtitle(text, html_class = nil)
61
- return "<h3>#{text}</h3>\n" unless html_class
66
+ return "<h3>#{text}</h3>" unless html_class
62
67
  tag('h3', text, class: html_class)
63
68
  end
64
69
 
65
70
  def sub_subtitle(text, html_class = nil)
66
- return "<h4>#{text}</h4>\n" unless html_class
71
+ return "<h4>#{text}</h4>" unless html_class
67
72
  tag('h4', text, class: html_class)
68
73
  end
69
74
 
70
75
  def paragraph(text, html_class = nil)
71
- return "<p>#{text}</p>\n" unless html_class
76
+ return "<p>#{text}</p>" unless html_class
72
77
  tag('p', text, class: html_class)
73
78
  end
74
79
 
75
- def button(text, glyphicon = nil)
76
- span = tag('span', text, class: "glyphicon #{glyphicon}", 'aria-hidden' => 'true')
77
- button = tag('button', "\n#{span}", 'type' => 'button',
78
- 'class' => 'btn btn-primary back',
79
- 'aria-label' => 'Left Align')
80
- tag('a', "\n#{button}", href: 'index.html')
80
+ def button(text, glyphicon = 'glyphicon-menu-left')
81
+ span = tag('span', nil, class: "glyphicon #{glyphicon}", 'aria-hidden' => 'true')
82
+ paragraph = paragraph(text)
83
+ button_content = span.to_s + paragraph.to_s
84
+ button = tag('button', button_content, 'type' => 'button',
85
+ 'class' => 'btn btn-primary back dictum-button',
86
+ 'aria-label' => 'Left Align')
87
+ tag('a', button.to_s, href: 'index.html')
81
88
  end
82
89
 
83
90
  def code_block(title, json)
@@ -91,14 +98,18 @@ module Dictum
91
98
  tag('pre', json, class: 'prettyprint')
92
99
  end
93
100
 
101
+ def jumbotron(content)
102
+ return '' unless content
103
+ tag('div', content, class: 'jumbotron')
104
+ end
105
+
94
106
  def tag(name, content, attributes = {})
95
107
  return '' unless name
96
108
  answer = "<#{name}"
97
109
  attributes.each do |key, value|
98
110
  answer += " #{key}='#{value}'"
99
111
  end
100
- answer += ">#{content}"
101
- answer += "</#{name}>\n"
112
+ answer += ">#{content}</#{name}>"
102
113
  end
103
114
  end
104
115
  end
@@ -1,16 +1,17 @@
1
1
  require_relative 'html_helpers'
2
2
  require 'json'
3
- require 'htmlbeautifier'
3
+ require 'nokogiri'
4
4
 
5
5
  module Dictum
6
6
  class HtmlWriter
7
- attr_reader :temp_path, :temp_json, :output_dir, :output_file, :output_title
7
+ attr_reader :temp_path, :temp_json, :output_dir, :output_file, :header_title
8
8
 
9
- def initialize(output_dir, temp_path, output_title)
9
+ def initialize(output_dir, temp_path, config)
10
10
  @output_dir = output_dir
11
11
  @temp_path = temp_path
12
12
  @temp_json = JSON.parse(File.read(temp_path))
13
- @output_title = output_title
13
+ @config = config
14
+ @header_title = config[:header_title]
14
15
  end
15
16
 
16
17
  def write
@@ -23,33 +24,37 @@ module Dictum
23
24
 
24
25
  def write_to_file(file_path, content)
25
26
  index = File.open(file_path, 'w+')
26
- index.puts(HtmlBeautifier.beautify(content))
27
+ index.puts(Nokogiri::HTML(content).to_html)
27
28
  index.close
28
29
  end
29
30
 
30
31
  def write_index
31
32
  html = HtmlHelpers.build do |b|
32
- content = "<div class='jumbotron'>\n#{HtmlHelpers.title('Index', 'title')}\n</div>\n"
33
- content += b.unordered_list(temp_json.keys)
33
+ content = b.jumbotron(b.title(@config[:index_title], 'title'))
34
+ content += b.unordered_list(resources.keys)
34
35
  container = b.container(b.row(content))
35
- b.html_header(output_title, container)
36
+ b.html_header(header_title, container, @config[:inline_css])
36
37
  end
37
38
  write_to_file("#{output_dir}/index.html", html)
38
39
  end
39
40
 
40
41
  def write_pages
41
- temp_json.each do |resource_name, information|
42
+ resources.each do |resource_name, information|
42
43
  write_page(resource_name, information)
43
44
  end
44
45
  end
45
46
 
47
+ def resources
48
+ temp_json['resources']
49
+ end
50
+
46
51
  def write_page(resource_name, information)
47
52
  html = HtmlHelpers.build do |b|
48
53
  content = resource_header_and_endpoints(
49
54
  resource_name, information['description'], information['endpoints'], b
50
55
  )
51
- container = b.container(b.row(content) + b.row(b.button('Back', 'glyphicon-menu-left')))
52
- b.html_header(output_title, container)
56
+ container = b.container(b.row(content) + b.row(b.button('Back')))
57
+ b.html_header(header_title, container, @config[:inline_css])
53
58
  end
54
59
  write_to_file("#{output_dir}/#{resource_name.downcase}.html", html)
55
60
  end
@@ -83,7 +88,7 @@ module Dictum
83
88
  ) if endpoint['response_headers']
84
89
 
85
90
  if endpoint['response_body']
86
- param = (endpoint['response_body'] == 'no_content') ? {} : endpoint['response_body']
91
+ param = endpoint['response_body'] == 'no_content' ? {} : endpoint['response_body']
87
92
  answer += write_codeblock('Response body', param, builder)
88
93
  end
89
94
  answer
@@ -91,7 +96,8 @@ module Dictum
91
96
 
92
97
  def write_codeblock(text, json, builder)
93
98
  return unless text && json && builder
94
- builder.code_block(text, JSON.pretty_generate(json))
99
+ sanitized_json = json.empty? ? {} : json
100
+ builder.code_block(text, JSON.pretty_generate(sanitized_json))
95
101
  end
96
102
  end
97
103
  end
@@ -4,11 +4,12 @@ module Dictum
4
4
  class MarkdownWriter
5
5
  attr_reader :temp_path, :temp_json, :output_path, :output_file
6
6
 
7
- def initialize(output_path, temp_path)
7
+ def initialize(output_path, temp_path, config)
8
8
  @output_path = "#{output_path}.md"
9
9
  File.delete(output_path) if File.exist?(output_path)
10
10
  @temp_path = temp_path
11
11
  @temp_json = JSON.parse(File.read(temp_path))
12
+ @config = config
12
13
  end
13
14
 
14
15
  def write
@@ -21,15 +22,15 @@ module Dictum
21
22
  private
22
23
 
23
24
  def write_index
24
- output_file.puts '# Index'
25
- @temp_json.each do |resource_name, _information|
25
+ output_file.puts "# #{@config[:index_title]}"
26
+ @temp_json['resources'].each do |resource_name, _information|
26
27
  output_file.puts "- #{resource_name}"
27
28
  end
28
29
  output_file.puts "\n"
29
30
  end
30
31
 
31
32
  def write_temp_path
32
- @temp_json.each do |resource_name, information|
33
+ @temp_json['resources'].each do |resource_name, information|
33
34
  output_file.puts "# #{resource_name}"
34
35
  output_file.puts "#{information['description']}\n\n"
35
36
  write_endpoints(information['endpoints'])
@@ -65,8 +66,9 @@ module Dictum
65
66
 
66
67
  def print_subsubtitle_json(subtitle, contents)
67
68
  return unless subtitle && contents
69
+ sanitized_contents = contents.empty? ? {} : contents
68
70
  output_file.puts "\#\#\# #{subtitle}:"
69
- output_file.puts "```json\n#{JSON.pretty_generate(contents)}\n```\n\n"
71
+ output_file.puts "```json\n#{JSON.pretty_generate(sanitized_contents)}\n```\n\n"
70
72
  end
71
73
  end
72
74
  end
@@ -1,3 +1,3 @@
1
1
  module Dictum
2
- VERSION = '0.0.4'.freeze
2
+ VERSION = '0.0.5'.freeze
3
3
  end
@@ -0,0 +1,19 @@
1
+
2
+ RSpec.configure do |config|
3
+ config.after(:each) do |test|
4
+ if test.metadata[:dictum]
5
+ Dictum.endpoint(
6
+ resource: test.metadata[:described_class].to_s.gsub('V1::', '').gsub('Controller', ''),
7
+ endpoint: request.fullpath,
8
+ http_verb: request.env['REQUEST_METHOD'],
9
+ description: test.metadata[:dictum_description],
10
+ request_headers: test.metadata[:dictum_no_auth] ? DEFAULT_REQUEST_HEADERS.except('AUTHORIZATION') : DEFAULT_REQUEST_HEADERS,
11
+ request_path_parameters: request.env['action_dispatch.request.path_parameters'].except(:controller, :action),
12
+ request_body_parameters: request.env['action_dispatch.request.parameters'].except('controller', 'action'),
13
+ response_headers: response.headers['Location'] ? { 'Location' => response.headers['Location'] } : nil,
14
+ response_status: response.status,
15
+ response_body: response_body
16
+ )
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,6 @@
1
+ Dictum.configure do |config|
2
+ config.output_path = Rails.root.join('docs')
3
+ config.root_path = Rails.root
4
+ config.output_filename = 'Documentation'
5
+ config.output_format = :markdown
6
+ end
@@ -1,8 +1,29 @@
1
1
  require 'rake'
2
2
 
3
3
  namespace :dictum do
4
+ GEM_DIR = Gem::Specification.find_by_name('dictum').gem_dir
5
+ DEFAULT_CONFIG_PATH = GEM_DIR + '/lib/tasks/default_configuration'
6
+ DEFAULT_INITIALIZER = GEM_DIR + '/lib/tasks/default_initializer'
7
+
4
8
  desc 'Starts the documenting process'
5
9
  task document: :environment do
6
10
  system 'bundle exec rails runner -e test Dictum.document'
7
11
  end
12
+
13
+ desc 'Installs the basic configuration in the file specified or in spec/support/spec_helper.rb'
14
+ task configure: :environment do
15
+ configuration_file_path = ARGV[1] || 'spec/support/spec_helper.rb'
16
+ initializer_file_path = Rails.root.join('config', 'initializers', 'dictum.rb')
17
+
18
+ default_config = File.read(DEFAULT_CONFIG_PATH)
19
+ default_initializer = File.read(DEFAULT_INITIALIZER)
20
+
21
+ File.open(configuration_file_path, 'a+') do |file|
22
+ file.puts(default_config)
23
+ end
24
+
25
+ File.open(initializer_file_path, 'a+') do |file|
26
+ file.puts(default_initializer)
27
+ end
28
+ end
8
29
  end
metadata CHANGED
@@ -1,35 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dictum
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alejandro Bezdjian
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-25 00:00:00.000000000 Z
11
+ date: 2016-09-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: htmlbeautifier
14
+ name: nokogiri
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.1'
20
- - - ">="
21
- - !ruby/object:Gem::Version
22
- version: 1.1.1
19
+ version: '1.6'
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
24
  - - "~>"
28
25
  - !ruby/object:Gem::Version
29
- version: '1.1'
30
- - - ">="
31
- - !ruby/object:Gem::Version
32
- version: 1.1.1
26
+ version: '1.6'
33
27
  - !ruby/object:Gem::Dependency
34
28
  name: bundler
35
29
  requirement: !ruby/object:Gem::Requirement
@@ -96,20 +90,20 @@ dependencies:
96
90
  requirements:
97
91
  - - "~>"
98
92
  - !ruby/object:Gem::Version
99
- version: '0.38'
93
+ version: '0.40'
100
94
  - - ">="
101
95
  - !ruby/object:Gem::Version
102
- version: 0.38.2
96
+ version: 0.40.0
103
97
  type: :development
104
98
  prerelease: false
105
99
  version_requirements: !ruby/object:Gem::Requirement
106
100
  requirements:
107
101
  - - "~>"
108
102
  - !ruby/object:Gem::Version
109
- version: '0.38'
103
+ version: '0.40'
110
104
  - - ">="
111
105
  - !ruby/object:Gem::Version
112
- version: 0.38.2
106
+ version: 0.40.0
113
107
  description: Create automatic documentation of your API endpoints through your tests.
114
108
  email: alebezdjian@gmail.com
115
109
  executables: []
@@ -126,12 +120,17 @@ files:
126
120
  - Rakefile
127
121
  - TODO.md
128
122
  - dictum.gemspec
123
+ - example.css
124
+ - example.gif
125
+ - example.md
129
126
  - lib/dictum.rb
130
127
  - lib/dictum/documenter.rb
131
128
  - lib/dictum/html_helpers.rb
132
129
  - lib/dictum/html_writer.rb
133
130
  - lib/dictum/markdown_writer.rb
134
131
  - lib/dictum/version.rb
132
+ - lib/tasks/default_configuration
133
+ - lib/tasks/default_initializer
135
134
  - lib/tasks/dictum.rake
136
135
  homepage: https://github.com/Wolox/dictum
137
136
  licenses:
@@ -158,4 +157,3 @@ signing_key:
158
157
  specification_version: 4
159
158
  summary: Document your APIs.
160
159
  test_files: []
161
- has_rdoc: