rspec_api_documentation 4.8.0 → 4.9.0

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: fdd16f01648ad082b801d8fd30ebc1cd06e55fd8
4
- data.tar.gz: 51d343a6cf25688c651d1631ae060410cdb53b4b
3
+ metadata.gz: 16b47e6bedc1c86cc5e418233eca8b80d16b5628
4
+ data.tar.gz: e1da890616a2fa4cf6a8ff8c44eff5977abc32f6
5
5
  SHA512:
6
- metadata.gz: 6e2c63b4378da2efa410296c6133649210f4685ceb04a0ea612e91e690e69894099c220d83f01e9a5b5d77581bb2e0aa1c37b8e21b6bbda8e6440ad1411bafd4
7
- data.tar.gz: bb6622522c0dda680a95e7f56666d1266fb9dc793c38a02bd9e3cb3368b317859cff1360d33ac9e87d9953180f05e606eee1320096906084a63d77b1aaf88b59
6
+ metadata.gz: c16d4338f5d6e06f1c913a951c1370b31f2e6c85a6aef38a593d5fbd332226ad99c9fae76207e9bed5089500010a5b588a123e0354cdef25d057cbc0483a1933
7
+ data.tar.gz: 03ef3fbf5306d2951fa6f3b82f08e2679306069e791ef9bf5d30f58693dbb83528bb78009821cc4b26fb1da166c33620c1e5d327c9d91f8008bd45afa93eead4
@@ -57,6 +57,7 @@ module RspecApiDocumentation
57
57
  autoload :TextileExample
58
58
  autoload :MarkdownIndex
59
59
  autoload :MarkdownExample
60
+ autoload :SlateIndex
60
61
  autoload :SlateExample
61
62
  end
62
63
 
@@ -76,7 +76,7 @@ module RspecApiDocumentation
76
76
  def filter_headers(headers)
77
77
  if !@config_headers_to_filer.empty?
78
78
  headers.reject do |header|
79
- @config_headers_to_filer.include?(format_header(header))
79
+ @config_headers_to_filer.map(&:downcase).include?(format_header(header).downcase)
80
80
  end
81
81
  else
82
82
  headers
@@ -1,6 +1,7 @@
1
1
  require 'rspec/core/formatters/base_formatter'
2
2
  require 'rack/utils'
3
3
  require 'rack/test/utils'
4
+ require 'rspec_api_documentation/dsl/endpoint/params'
4
5
 
5
6
  module RspecApiDocumentation::DSL
6
7
  # DSL methods available inside the RSpec example.
@@ -63,11 +64,7 @@ module RspecApiDocumentation::DSL
63
64
  end
64
65
 
65
66
  def params
66
- parameters = example.metadata.fetch(:parameters, {}).inject({}) do |hash, param|
67
- set_param(hash, param)
68
- end
69
- parameters.deep_merge!(extra_params)
70
- parameters
67
+ Params.new(self, example, extra_params).call
71
68
  end
72
69
 
73
70
  def header(name, value)
@@ -99,22 +96,14 @@ module RspecApiDocumentation::DSL
99
96
  rspec_api_documentation_client.status
100
97
  end
101
98
 
102
- def in_path?(param)
103
- path_params.include?(param)
104
- end
105
-
106
- def path_params
107
- example.metadata[:route].scan(/:(\w+)/).flatten
108
- end
109
-
110
99
  def path
111
100
  example.metadata[:route].gsub(/:(\w+)/) do |match|
112
101
  if extra_params.keys.include?($1)
113
102
  delete_extra_param($1)
114
103
  elsif respond_to?($1)
115
- send($1)
104
+ escape send($1)
116
105
  else
117
- match
106
+ escape match
118
107
  end
119
108
  end
120
109
  end
@@ -146,26 +135,5 @@ module RspecApiDocumentation::DSL
146
135
  @extra_params.delete(key.to_sym) || @extra_params.delete(key.to_s)
147
136
  end
148
137
 
149
- def set_param(hash, param)
150
- key = param[:name]
151
-
152
- keys = [param[:scope], key].flatten.compact
153
- method_name = keys.join('_')
154
-
155
- return hash if in_path?(method_name)
156
-
157
- unless respond_to?(method_name)
158
- method_name = key
159
- return hash unless respond_to?(method_name)
160
- end
161
-
162
- hash.deep_merge(build_param_hash(keys, method_name))
163
- end
164
-
165
- def build_param_hash(keys, method_name)
166
- value = keys[1] ? build_param_hash(keys[1..-1], method_name) : send(method_name)
167
- { keys[0].to_s => value }
168
- end
169
-
170
138
  end
171
139
  end
@@ -0,0 +1,30 @@
1
+ require 'rspec_api_documentation/dsl/endpoint/set_param'
2
+
3
+ module RspecApiDocumentation
4
+ module DSL
5
+ module Endpoint
6
+ class Params
7
+ attr_reader :example_group, :example
8
+
9
+ def initialize(example_group, example, extra_params)
10
+ @example_group = example_group
11
+ @example = example
12
+ @extra_params = extra_params
13
+ end
14
+
15
+ def call
16
+ parameters = example.metadata.fetch(:parameters, {}).inject({}) do |hash, param|
17
+ SetParam.new(self, hash, param).call
18
+ end
19
+ parameters.deep_merge!(extra_params)
20
+ parameters
21
+ end
22
+
23
+ private
24
+
25
+ attr_reader :extra_params
26
+
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,62 @@
1
+ module RspecApiDocumentation
2
+ module DSL
3
+ module Endpoint
4
+ class SetParam
5
+ def initialize(parent, hash, param)
6
+ @parent = parent
7
+ @hash = hash
8
+ @param = param
9
+ end
10
+
11
+ def call
12
+ return hash if path_params.include?(path_name)
13
+ return hash unless method_name
14
+
15
+ hash.deep_merge build_param_hash(key_scope || [key])
16
+ end
17
+
18
+ private
19
+
20
+ attr_reader :parent, :hash, :param
21
+ delegate :example_group, :example, to: :parent
22
+
23
+ def key
24
+ @key ||= param[:name]
25
+ end
26
+
27
+ def key_scope
28
+ @key_scope ||= param[:scope] && Array(param[:scope]).dup.push(key)
29
+ end
30
+
31
+ def scoped_key
32
+ @scoped_key ||= key_scope && key_scope.join('_')
33
+ end
34
+
35
+ def custom_method_name
36
+ param[:method]
37
+ end
38
+
39
+ def path_name
40
+ scoped_key || key
41
+ end
42
+
43
+ def path_params
44
+ example.metadata[:route].scan(/:(\w+)/).flatten
45
+ end
46
+
47
+ def method_name
48
+ @method_name ||= begin
49
+ [custom_method_name, scoped_key, key].find do |name|
50
+ name && example_group.respond_to?(name)
51
+ end
52
+ end
53
+ end
54
+
55
+ def build_param_hash(keys)
56
+ value = keys[1] ? build_param_hash(keys[1..-1]) : example_group.send(method_name)
57
+ { keys[0].to_s => value }
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -50,6 +50,10 @@ module RspecApiDocumentation::DSL
50
50
  headers[name] = value
51
51
  end
52
52
 
53
+ def explanation(text)
54
+ safe_metadata(:resource_explanation, text)
55
+ end
56
+
53
57
  private
54
58
 
55
59
  def field_specification(name, *args)
@@ -42,6 +42,10 @@ module RspecApiDocumentation
42
42
  respond_to?(:response_fields) && response_fields.present?
43
43
  end
44
44
 
45
+ def resource_explanation
46
+ metadata[:resource_explanation] || nil
47
+ end
48
+
45
49
  def explanation
46
50
  metadata[:explanation] || nil
47
51
  end
@@ -63,7 +67,7 @@ module RspecApiDocumentation
63
67
  requests.each.with_index do |request_hash, index|
64
68
  next unless request_hash.key?(key)
65
69
  headers = request_hash[key]
66
- request_hash[key] = headers.select{ |key, _| headers_to_include.include?(key) }
70
+ request_hash[key] = headers.select{ |key, _| headers_to_include.map(&:downcase).include?(key.downcase) }
67
71
  requests[index] = request_hash
68
72
  end
69
73
  end
@@ -8,6 +8,14 @@ module RspecApiDocumentation
8
8
  self.template_name = "rspec_api_documentation/markdown_example"
9
9
  end
10
10
 
11
+ def parameters
12
+ super.map do |parameter|
13
+ parameter.merge({
14
+ :required => parameter[:required] ? 'true' : 'false',
15
+ })
16
+ end
17
+ end
18
+
11
19
  def extension
12
20
  EXTENSION
13
21
  end
@@ -23,7 +23,8 @@ module RspecApiDocumentation
23
23
  end
24
24
 
25
25
  def filename
26
- basename = description.downcase.gsub(/\s+/, '_').gsub(Pathname::SEPARATOR_PAT, '')
26
+ special_chars = /[<>:"\/\\|?*]/
27
+ basename = description.downcase.gsub(/\s+/, '_').gsub(special_chars, '')
27
28
  basename = Digest::MD5.new.update(description).to_s if basename.blank?
28
29
  "#{basename}.#{extension}"
29
30
  end
@@ -31,14 +32,15 @@ module RspecApiDocumentation
31
32
  def parameters
32
33
  super.each do |parameter|
33
34
  if parameter.has_key?(:scope)
34
- scope = Array(parameter[:scope]).each_with_index.map do |scope, index|
35
- if index == 0
36
- scope
37
- else
38
- "[#{scope}]"
39
- end
40
- end.join
41
- parameter[:scope] = scope
35
+ parameter[:scope] = format_scope(parameter[:scope])
36
+ end
37
+ end
38
+ end
39
+
40
+ def response_fields
41
+ super.each do |response_field|
42
+ if response_field.has_key?(:scope)
43
+ response_field[:scope] = format_scope(response_field[:scope])
42
44
  end
43
45
  end
44
46
  end
@@ -71,6 +73,16 @@ module RspecApiDocumentation
71
73
  "#{k}: #{v}"
72
74
  end.join("\n")
73
75
  end
76
+
77
+ def format_scope(unformatted_scope)
78
+ Array(unformatted_scope).each_with_index.map do |scope, index|
79
+ if index == 0
80
+ scope
81
+ else
82
+ "[#{scope}]"
83
+ end
84
+ end.join
85
+ end
74
86
  end
75
87
  end
76
88
  end
@@ -6,25 +6,11 @@ module RspecApiDocumentation
6
6
  self.template_name = "rspec_api_documentation/slate_example"
7
7
  end
8
8
 
9
- def curl_with_linebreaks
10
- requests.map {|request| request[:curl].lines }.flatten.map do |line|
11
- line.rstrip.gsub("\t", ' ').gsub(' ', '&nbsp;').gsub('\\', '&#92;')
12
- end.join "<br>"
13
- end
14
-
15
- def explanation_with_linebreaks
16
- explanation.gsub "\n", "<br>\n"
17
- end
18
-
19
- def write
20
- File.open(configuration.docs_dir.join("#{FILENAME}.#{extension}"), 'w+') do |file|
21
- file.write "# #{configuration.api_name}\n\n"
22
- index.examples.sort_by!(&:description) unless configuration.keep_source_order
23
-
24
- index.examples.each do |example|
25
- markup_example = markup_example_class.new(example, configuration)
26
- file.write markup_example.render
27
- end
9
+ def parameters
10
+ super.map do |parameter|
11
+ parameter.merge({
12
+ :required => parameter[:required] == 'true' ? true : false,
13
+ })
28
14
  end
29
15
  end
30
16
  end
@@ -0,0 +1,6 @@
1
+ module RspecApiDocumentation
2
+ module Views
3
+ class SlateIndex < MarkdownIndex
4
+ end
5
+ end
6
+ end
@@ -6,7 +6,7 @@ module RspecApiDocumentation
6
6
  def sections(examples, configuration)
7
7
  resources = examples.group_by(&:resource_name).inject([]) do |arr, (resource_name, examples)|
8
8
  ordered_examples = configuration.keep_source_order ? examples : examples.sort_by(&:description)
9
- arr.push(:resource_name => resource_name, :examples => ordered_examples)
9
+ arr.push(:resource_name => resource_name, :examples => ordered_examples, resource_explanation: examples.first.resource_explanation)
10
10
  end
11
11
  configuration.keep_source_order ? resources : resources.sort_by { |resource| resource[:resource_name] }
12
12
  end
@@ -47,6 +47,7 @@ module RspecApiDocumentation
47
47
  def section_hash(section)
48
48
  {
49
49
  :name => section[:resource_name],
50
+ :explanation => section[:resource_explanation],
50
51
  :examples => section[:examples].map { |example|
51
52
  {
52
53
  :description => example.description,
@@ -87,6 +88,7 @@ module RspecApiDocumentation
87
88
  def as_json(opts = nil)
88
89
  {
89
90
  :resource => resource_name,
91
+ :resource_explanation => resource_explanation,
90
92
  :http_method => http_method,
91
93
  :route => route,
92
94
  :description => description,
@@ -2,28 +2,50 @@ module RspecApiDocumentation
2
2
  module Writers
3
3
 
4
4
  class SlateWriter < MarkdownWriter
5
- FILENAME = '_generated_examples'
5
+ EXTENSION = 'html.md'
6
+ FILENAME = 'index'
6
7
 
7
8
  def self.clear_docs(docs_dir)
8
9
  FileUtils.mkdir_p(docs_dir)
9
10
  FileUtils.rm Dir[File.join docs_dir, "#{FILENAME}.*"]
10
11
  end
11
12
 
13
+ def markup_index_class
14
+ RspecApiDocumentation::Views::SlateIndex
15
+ end
16
+
12
17
  def markup_example_class
13
18
  RspecApiDocumentation::Views::SlateExample
14
19
  end
15
20
 
16
21
  def write
17
22
  File.open(configuration.docs_dir.join("#{FILENAME}.#{extension}"), 'w+') do |file|
18
- file.write "# #{configuration.api_name}\n\n"
19
- index.examples.sort_by!(&:description) unless configuration.keep_source_order
20
23
 
21
- index.examples.each do |example|
22
- markup_example = markup_example_class.new(example, configuration)
23
- file.write markup_example.render
24
+ file.write %Q{---\n}
25
+ file.write %Q{title: "#{configuration.api_name}"\n}
26
+ file.write %Q{language_tabs:\n}
27
+ file.write %Q{ - json: JSON\n}
28
+ file.write %Q{ - shell: cURL\n}
29
+ file.write %Q{---\n\n}
30
+
31
+ IndexHelper.sections(index.examples, @configuration).each do |section|
32
+
33
+ file.write "# #{section[:resource_name]}\n\n"
34
+ section[:examples].sort_by!(&:description) unless configuration.keep_source_order
35
+
36
+ section[:examples].each do |example|
37
+ markup_example = markup_example_class.new(example, configuration)
38
+ file.write markup_example.render
39
+ end
40
+
24
41
  end
42
+
25
43
  end
26
44
  end
45
+
46
+ def extension
47
+ EXTENSION
48
+ end
27
49
  end
28
50
  end
29
51
  end
@@ -10,6 +10,10 @@
10
10
  <body>
11
11
  <div class="container">
12
12
  <h1>{{resource_name}} API</h1>
13
+ {{# resource_explanation }}
14
+
15
+ <p class="explanation">{{{ resource_explanation }}}</p>
16
+ {{/ resource_explanation }}
13
17
 
14
18
  <div class="article">
15
19
  <h2>{{ description }}</h2>
@@ -14,6 +14,10 @@
14
14
  {{# sections }}
15
15
  <div class="article">
16
16
  <h2>{{ resource_name }}</h2>
17
+ {{# resource_explanation }}
18
+
19
+ <p class="explanation">{{{ resource_explanation }}}</p>
20
+ {{/ resource_explanation }}
17
21
 
18
22
  <ul>
19
23
  {{# examples }}
@@ -1,4 +1,8 @@
1
1
  # {{ resource_name }} API
2
+ {{# resource_explanation }}
3
+
4
+ {{{ resource_explanation }}}
5
+ {{/ resource_explanation }}
2
6
 
3
7
  ## {{ description }}
4
8
 
@@ -10,10 +14,11 @@
10
14
  {{# has_parameters? }}
11
15
 
12
16
  ### Parameters
13
- {{# parameters }}
14
17
 
15
- Name : {{ name }}{{# required }} *- required -*{{/ required }}
16
- Description : {{ description }}
18
+ | Name | Description | Required | Scope |
19
+ |------|-------------|----------|-------|
20
+ {{# parameters }}
21
+ | {{ name }} | {{ description }} | {{ required }} | {{ scope }} |
17
22
  {{/ parameters }}
18
23
 
19
24
  {{/ has_parameters? }}
@@ -2,6 +2,10 @@
2
2
 
3
3
  {{# sections }}
4
4
  ## {{ resource_name }}
5
+ {{# resource_explanation }}
6
+
7
+ {{{ resource_explanation }}}
8
+ {{/ resource_explanation }}
5
9
 
6
10
  {{# examples }}
7
11
  * [{{ description }}]({{ dirname }}/{{ filename }})
@@ -1,5 +1,9 @@
1
1
  ## {{ description }}
2
2
 
3
+ {{# explanation }}
4
+ {{{ explanation }}}
5
+ {{/ explanation }}
6
+
3
7
  ### Request
4
8
 
5
9
  #### Endpoint
@@ -13,11 +17,6 @@
13
17
 
14
18
  `{{ http_method }} {{ route }}`
15
19
 
16
- {{# explanation }}
17
-
18
- {{{ explanation_with_linebreaks }}}
19
- {{/ explanation }}
20
-
21
20
  #### Parameters
22
21
 
23
22
  {{# requests}}
@@ -78,9 +77,8 @@ None known.
78
77
  {{/ has_response_fields? }}
79
78
 
80
79
  {{# curl }}
81
-
82
- ### cURL
83
-
84
- <code>{{{ curl_with_linebreaks }}}</code>
80
+ ```shell
81
+ {{{ curl }}}
82
+ ```
85
83
  {{/ curl }}
86
84
  {{/ requests}}
@@ -1,4 +1,8 @@
1
1
  h1. {{ resource_name }} API
2
+ {{# resource_explanation }}
3
+
4
+ {{{ resource_explanation }}}
5
+ {{/ resource_explanation }}
2
6
 
3
7
  h2. {{ description }}
4
8
 
@@ -2,6 +2,10 @@ h1. {{ api_name }}
2
2
 
3
3
  {{# sections }}
4
4
  h2. {{ resource_name }}
5
+ {{# resource_explanation }}
6
+
7
+ {{{ resource_explanation }}}
8
+ {{/ resource_explanation }}
5
9
 
6
10
  {{# examples }}
7
11
  * "{{ description }}":{{ dirname }}/{{ filename }}
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec_api_documentation
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.8.0
4
+ version: 4.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Cahoon
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2016-05-25 00:00:00.000000000 Z
13
+ date: 2016-12-08 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rspec
@@ -19,9 +19,6 @@ dependencies:
19
19
  - - "~>"
20
20
  - !ruby/object:Gem::Version
21
21
  version: '3.0'
22
- - - ">="
23
- - !ruby/object:Gem::Version
24
- version: 3.0.0
25
22
  type: :runtime
26
23
  prerelease: false
27
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -29,9 +26,6 @@ dependencies:
29
26
  - - "~>"
30
27
  - !ruby/object:Gem::Version
31
28
  version: '3.0'
32
- - - ">="
33
- - !ruby/object:Gem::Version
34
- version: 3.0.0
35
29
  - !ruby/object:Gem::Dependency
36
30
  name: activesupport
37
31
  requirement: !ruby/object:Gem::Requirement
@@ -277,6 +271,8 @@ files:
277
271
  - lib/rspec_api_documentation/dsl.rb
278
272
  - lib/rspec_api_documentation/dsl/callback.rb
279
273
  - lib/rspec_api_documentation/dsl/endpoint.rb
274
+ - lib/rspec_api_documentation/dsl/endpoint/params.rb
275
+ - lib/rspec_api_documentation/dsl/endpoint/set_param.rb
280
276
  - lib/rspec_api_documentation/dsl/resource.rb
281
277
  - lib/rspec_api_documentation/example.rb
282
278
  - lib/rspec_api_documentation/headers.rb
@@ -293,6 +289,7 @@ files:
293
289
  - lib/rspec_api_documentation/views/markup_example.rb
294
290
  - lib/rspec_api_documentation/views/markup_index.rb
295
291
  - lib/rspec_api_documentation/views/slate_example.rb
292
+ - lib/rspec_api_documentation/views/slate_index.rb
296
293
  - lib/rspec_api_documentation/views/textile_example.rb
297
294
  - lib/rspec_api_documentation/views/textile_index.rb
298
295
  - lib/rspec_api_documentation/writers/append_json_writer.rb