rspec-apidoc 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 70f813f8f9f45e4f454cd07147cc1ff8dc22496ddd99e22bccf098b6f513f732
4
- data.tar.gz: a817bac7f9c2f5bed38117de7634ae16520192f9f4a3864e685016d6f5e5d283
3
+ metadata.gz: 8700f45112bb1c1a6a8ca9770020b00c5e1887e673e4353b305ecc66f89f5d70
4
+ data.tar.gz: 9ce1fb0139b48f53dce57b0f51728ddcbf58546b64c99105437dc9b637bdf5ee
5
5
  SHA512:
6
- metadata.gz: c52748bb8d403685869114c402c36ee40ba0f1a3909871bc430cd753a4c74b626ad1d5f6252c5428d9ca628fe6757ae934ebbce923c9231e31205c77b989c722
7
- data.tar.gz: b2f2f1f893a876532f404ecd47598e986f805b888503055668ed7144f2f972a45ef4783fb12df76602107adbdce9b6ef05338bb1321fb3195d6fa7cb231e655c
6
+ metadata.gz: 617d0a747bb1977de943ec794fde2c4975bc5058d93c5e6cdd1ae88a8075e24c20db6b187b3d8fb59661961974555305c50ace0558662697103bb60c3feab20c
7
+ data.tar.gz: 0c82c4f051092f3517279e1c5d4ca0cd4e7eaae8471dfe81b8240bad3517d0d023965e129cf0fb169d6df5b372cd23d7fa8d8b4b88f695ccceef35a85b1bac2e
data/README.md CHANGED
@@ -47,12 +47,17 @@ RSpec.configure do |config|
47
47
 
48
48
  config.apidoc_title = 'YOUR.APP API Documentation'
49
49
  config.apidoc_description = \
50
- 'A longer intro to add before the examples: authtication, status codes...'
50
+ 'A longer intro to add before the examples: authentication, status codes...'
51
51
 
52
52
  config.apidoc_host = 'https://api.YOUR.APP'
53
53
  # Optionally specify the output file path.
54
54
  config.apidoc_output_filename = 'apidoc.html'
55
55
 
56
+ # Customize the authentication header
57
+ config.apidoc_auth_header = lambda do |headers|
58
+ '"Authorization: Bearer $AUTH_TOKEN"' if headers['Authorization']
59
+ end
60
+
56
61
  # You can add it to any example based on the metadata.
57
62
  config.after(:each, type: :request) do |example|
58
63
  RSpec::Apidoc.add(self, example)
@@ -90,10 +90,14 @@
90
90
  </div>
91
91
 
92
92
  <% examples.each do |controller, items| %>
93
- <% items.sort.each do |action, action_items| %>
93
+ <% items.sort.each_with_index do |(action, action_items), mindex| %>
94
94
  <% action_items.each_with_index do |item, index| %>
95
- <div class="example">
96
- <% if index == 0 %>
95
+ <div class="example" id="<%= controller %>-<%= action %>-<%= mindex + index %>">
96
+ <% if mindex == 0 %>
97
+ <%= item[:controller_comment] %>
98
+ <% end %>
99
+
100
+ <% if mindex == 0 && index == 0 %>
97
101
  <div class="example-doc" id="<%= controller %>-<%= action %>">
98
102
  <%= item[:action_comment] || ( item[:method] + ' ' + controller ) %>
99
103
  </div>
@@ -104,11 +108,20 @@
104
108
  <div class="request">
105
109
  <span>Request</span>
106
110
  <pre>
107
- $ curl '<%= host %><%= item[:path] %><%= ('?' + item[:query]) if item[:query] != '' %>' \
108
- -X <%= item[:method] %> \
109
- -H 'Content-Type: <%= item[:content_type] %>' <% if item[:request_body] != '' %> \
110
- @- &lt;&lt; EOF
111
+ $ curl -X <%= item[:method] %> '<%= host %><%= item[:path] %><%= ('?' + item[:query]) if item[:query] != '' %>' \
112
+ <%- if item[:auth_header] -%>
113
+ -H <%= item[:auth_header] %> <%- if item[:content_type] %>\<% end %>
114
+ <%- end -%>
115
+ <%- if item[:content_type] -%>
116
+ -H 'Content-Type: <%= item[:content_type] %>' <%- if item[:request_body] %>\<% end %>
117
+ <%- end -%>
118
+ <%- if item[:request_body] != '' -%>
119
+ -d - &lt;&lt; EOF
120
+ <% if item[:request_body].is_a?(String) -%>
121
+ <%=h item[:request_body] -%>
122
+ <% else %>
111
123
  <%=h JSON.pretty_generate(item[:request_body]) %>
124
+ <%- end %>
112
125
  EOF
113
126
  <% end %>
114
127
  </pre>
@@ -116,9 +129,14 @@ EOF
116
129
  <div class="response">
117
130
  <span>Response</span>
118
131
  <pre>
119
- &lt; Content-Type: <%= item[:response_content_type] %>
132
+ &lt; Content-Type: <%= item[:response_content_type] -%>
120
133
  &lt; Status: <%= item[:status] %>
121
- <%=h JSON.pretty_generate(item[:response_body]) %>
134
+
135
+ <% if item[:response_body].is_a?(String) -%>
136
+ <%=h item[:response_body] -%>
137
+ <% else %>
138
+ <%=h JSON.pretty_generate(item[:response_body]) -%>
139
+ <%- end -%>
122
140
  </pre>
123
141
  </div>
124
142
  </div>
@@ -135,6 +153,9 @@ EOF
135
153
  </div>
136
154
  <div class="footer">
137
155
  &copy; <%= Date.current.year %> <%= title %>
156
+ <p>
157
+ <small>Latest update at <%= DateTime.current.to_s %></small>
158
+ </p>
138
159
  </div>
139
160
  </body>
140
161
  </html>
data/lib/rspec/apidoc.rb CHANGED
@@ -13,6 +13,7 @@ module RSpec
13
13
  config.add_setting(:apidoc_title)
14
14
  config.add_setting(:apidoc_description)
15
15
  config.add_setting(:apidoc_host)
16
+ config.add_setting(:apidoc_auth_header, default: ->(headers) {})
16
17
  config.add_setting(
17
18
  :apidoc_template_path,
18
19
  default: File.expand_path('apidoc/static/template.html.erb', __dir__)
@@ -65,6 +66,14 @@ module RSpec
65
66
  RSpec.configuration.apidoc_host
66
67
  end
67
68
 
69
+ # Returns the API authentication header callback result
70
+ #
71
+ # @param headers [ActionDispatch::Http::Headers] object
72
+ # @return [Object]
73
+ def self.auth_header(headers)
74
+ RSpec.configuration.apidoc_auth_header.call(headers)
75
+ end
76
+
68
77
  # Returns the collected examples, sorted
69
78
  #
70
79
  # @return [Array] a list of [Hash] items
@@ -82,15 +91,22 @@ module RSpec
82
91
  response_body = parse_json_safely(spec.response.body)
83
92
 
84
93
  if spec.request.controller_instance
85
- action_comment = spec.request.controller_class.instance_method(
86
- spec.request.controller_instance.action_name
87
- ).comment
94
+ action_name = spec.request.controller_instance.action_name
95
+ action_method = spec.request.controller_instance.method(action_name)
88
96
  # Remove any `@param` or `@return` lines
89
- action_comment = action_comment.delete('#').gsub(/@.*$/, '').strip
97
+ action_comment = action_method.comment
98
+ .gsub(/^#(\s+)?$/, "\n").gsub(/^#(\s+)?/, '').gsub(/^@.*$/, '')
90
99
  controller_class = spec.request.controller_class
91
- action_name = spec.request.controller_instance.action_name
100
+ controller_comment = nil
101
+
102
+ if action_method.respond_to?(:class_comment)
103
+ controller_comment = action_method.class_comment.gsub(
104
+ /.*frozen_string_literal:.*/, ''
105
+ ).gsub(/^#(\s+)?$/, "\n").gsub(/^#(\s+)?/, '').gsub(/^@.*$/, '')
106
+ end
92
107
  else
93
108
  action_comment = nil
109
+ controller_comment = nil
94
110
  controller_class = spec.request.path
95
111
  action_name = spec.request.method
96
112
  end
@@ -99,10 +115,12 @@ module RSpec
99
115
  description: example.metadata[:full_description],
100
116
 
101
117
  controller_class: controller_class,
118
+ controller_comment: controller_comment,
102
119
  action_name: action_name,
103
120
  action_comment: action_comment,
104
121
 
105
122
  content_type: spec.request.content_type,
123
+ auth_header: auth_header(spec.request.headers),
106
124
  method: spec.request.method,
107
125
  path: spec.request.path,
108
126
  query: spec.request.query_parameters.to_param,
@@ -145,7 +163,7 @@ module RSpec
145
163
  def close(_notification)
146
164
  return if examples.empty?
147
165
 
148
- erb = ERB.new(File.read(template_path))
166
+ erb = ERB.new(File.read(template_path), trim_mode: '-')
149
167
  File.write(output_filename, erb.result(self.binding))
150
168
  end
151
169
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-apidoc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stas Suscov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-02 00:00:00.000000000 Z
11
+ date: 2021-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: method_source