lazy_api_doc 0.2.3 → 0.2.5

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: fa62cfe77df17307c22cb91c6a951e2820d1a4b5d9aa5abdcf2125048fe4442f
4
- data.tar.gz: f9429c504ec51bd374877f5a6c2406cbd0ce03353b771136f1f3dc41877a5cb6
3
+ metadata.gz: ef3ed91d230146fe8a9ec8848a38faaa15b74bbe9543cce9bbf9df31378b2364
4
+ data.tar.gz: 9a8d617d8e7ee944da9fe0d3044b38a95bc9a030be816565f6efe686ff90c84b
5
5
  SHA512:
6
- metadata.gz: '08af3aec20c0c6f7b9281f51845411a9f3875aec62577a6b0eb2f7a185ea4a7c49ad95fbc87d3ae434850ced028b14f5de2f9816bfd12babd938790bc443e553'
7
- data.tar.gz: a50c616f463aa585bb9afc963855e7149236a437fea129b225a204c3ee7687996d0e2d781821b358beb7473a97418fe8438f4a1eea09938dc36ba17b0cd5066f
6
+ metadata.gz: 6122f584b76193d5ce943208d67a8c3e80637acf3c78f78381629fc67b468ac337dc7ffb17cefcb1cefc7b4a18b2ab6a531113c3b138e99b2bc92c1a999d07bb
7
+ data.tar.gz: de1c56436fb2fca419cd0a2fa25a051cc08da77820dc4c9f8da9dfe5182d125275fc041254b721376b1432d0cb251fe6111c31c4a717a4391e924a84891c61c2
data/.gitignore CHANGED
@@ -10,3 +10,4 @@
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
12
  coverage
13
+ *.gem
data/.rubocop.yml CHANGED
@@ -1,10 +1,14 @@
1
1
  # Rubocop rules explanation:
2
2
  # https://github.com/rubocop-hq/rubocop/blob/master/config/default.yml
3
- #
4
- # Rubocop-Rspec rules explanation:
5
- # https://github.com/rubocop-hq/rubocop-rspec/blob/master/config/default.yml
6
3
 
7
- require: rubocop-rspec
4
+ AllCops:
5
+ DisplayCopNames: true
6
+ TargetRubyVersion: 2.3.0
7
+ NewCops: enable
8
+ SuggestExtensions: false
9
+ Exclude:
10
+ - bin/bundle
11
+ - spec
8
12
 
9
13
  Style/StringLiterals:
10
14
  Enabled: false
@@ -12,15 +16,13 @@ Style/StringLiterals:
12
16
  Style/FrozenStringLiteralComment:
13
17
  Enabled: false
14
18
 
15
- Metrics/LineLength:
16
- Exclude:
17
- - lazy_api_doc.gemspec
19
+ Layout/LineLength:
18
20
  Max: 120
19
21
 
20
22
  Style/ExpandPathArguments:
21
23
  Enabled: false
22
24
 
23
- Layout/AlignHash:
25
+ Layout/HashAlignment:
24
26
  Enabled: false
25
27
 
26
28
  Metrics/BlockLength:
@@ -34,12 +36,19 @@ Style/Documentation:
34
36
  Enabled: false
35
37
 
36
38
  Metrics/AbcSize:
37
- Max: 25
38
-
39
-
39
+ Max: 30
40
40
 
41
- RSpec/ExampleLength:
41
+ Style/WordArray:
42
42
  Enabled: false
43
43
 
44
- RSpec/DescribedClass:
44
+ Style/OpenStructUse:
45
45
  Enabled: false
46
+
47
+ Metrics/PerceivedComplexity:
48
+ Max: 10
49
+
50
+ Metrics/CyclomaticComplexity:
51
+ Max: 10
52
+
53
+ Metrics/ClassLength:
54
+ Max: 150
data/Gemfile.lock CHANGED
@@ -1,20 +1,22 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- lazy_api_doc (0.2.3)
4
+ lazy_api_doc (0.2.5)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
- ast (2.4.0)
9
+ ast (2.4.2)
10
10
  diff-lcs (1.3)
11
11
  docile (1.4.0)
12
- jaro_winkler (1.5.4)
13
- parallel (1.19.0)
14
- parser (2.6.5.0)
15
- ast (~> 2.4.0)
16
- rainbow (3.0.0)
12
+ json (2.6.3)
13
+ parallel (1.22.1)
14
+ parser (3.2.1.1)
15
+ ast (~> 2.4.1)
16
+ rainbow (3.1.1)
17
17
  rake (12.3.3)
18
+ regexp_parser (2.7.0)
19
+ rexml (3.2.5)
18
20
  rspec (3.9.0)
19
21
  rspec-core (~> 3.9.0)
20
22
  rspec-expectations (~> 3.9.0)
@@ -28,23 +30,28 @@ GEM
28
30
  diff-lcs (>= 1.2.0, < 2.0)
29
31
  rspec-support (~> 3.9.0)
30
32
  rspec-support (3.9.0)
31
- rubocop (0.76.0)
32
- jaro_winkler (~> 1.5.1)
33
+ rubocop (1.48.1)
34
+ json (~> 2.3)
33
35
  parallel (~> 1.10)
34
- parser (>= 2.6)
36
+ parser (>= 3.2.0.0)
35
37
  rainbow (>= 2.2.2, < 4.0)
38
+ regexp_parser (>= 1.8, < 3.0)
39
+ rexml (>= 3.2.5, < 4.0)
40
+ rubocop-ast (>= 1.26.0, < 2.0)
36
41
  ruby-progressbar (~> 1.7)
37
- unicode-display_width (>= 1.4.0, < 1.7)
42
+ unicode-display_width (>= 2.4.0, < 3.0)
43
+ rubocop-ast (1.27.0)
44
+ parser (>= 3.2.1.0)
38
45
  rubocop-rspec (1.38.1)
39
46
  rubocop (>= 0.68.1)
40
- ruby-progressbar (1.10.1)
47
+ ruby-progressbar (1.13.0)
41
48
  simplecov (0.21.2)
42
49
  docile (~> 1.1)
43
50
  simplecov-html (~> 0.11)
44
51
  simplecov_json_formatter (~> 0.1)
45
52
  simplecov-html (0.12.3)
46
53
  simplecov_json_formatter (0.1.3)
47
- unicode-display_width (1.6.0)
54
+ unicode-display_width (2.4.2)
48
55
 
49
56
  PLATFORMS
50
57
  ruby
data/lazy_api_doc.gemspec CHANGED
@@ -7,7 +7,9 @@ Gem::Specification.new do |spec|
7
7
  spec.email = ["biguban@gmail.com"]
8
8
 
9
9
  spec.summary = "Creates openapi v3 documentation based on rspec request tests"
10
- spec.description = "The gem collects all requests and responses from your request specs and generates documentationbased on it"
10
+ spec.description = <<~EODOC
11
+ The gem collects all requests and responses from your request specs and generates documentation based on it
12
+ EODOC
11
13
  spec.homepage = "https://github.com/bguban/lazy_api_doc"
12
14
  spec.license = "MIT"
13
15
  spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
@@ -26,4 +28,5 @@ Gem::Specification.new do |spec|
26
28
  spec.bindir = "exe"
27
29
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
30
  spec.require_paths = ["lib"]
31
+ spec.metadata['rubygems_mfa_required'] = 'true'
29
32
  end
@@ -14,9 +14,9 @@ module LazyApiDoc
14
14
  append_to_file '.gitignore' do
15
15
  <<~TXT
16
16
 
17
- # LazyApiDoc
18
- #{LazyApiDoc.path}/api.yml
19
- #{LazyApiDoc.path}/examples/*.json
17
+ # LazyApiDoc
18
+ #{LazyApiDoc.path}/api.yml
19
+ #{LazyApiDoc.path}/examples/*.json
20
20
  TXT
21
21
  end
22
22
 
@@ -2,6 +2,8 @@ require 'cgi'
2
2
 
3
3
  module LazyApiDoc
4
4
  class Generator
5
+ EXCLUDED_PARAMS = ["controller", "action", "format"].freeze
6
+
5
7
  attr_reader :examples
6
8
 
7
9
  def initialize
@@ -21,11 +23,10 @@ module LazyApiDoc
21
23
  def result
22
24
  result = {}
23
25
  @examples.map { |example| OpenStruct.new(example) }.sort_by(&:source_location)
24
- .group_by { |ex| [ex.controller, ex.action] }
25
- .each do |_, examples|
26
- first = examples.first
27
- route = ::LazyApiDoc::RouteParser.new(first.controller, first.action, first.verb).route
26
+ .group_by { |example| ::LazyApiDoc::RouteParser.find_by(example) }
27
+ .each do |route, examples|
28
28
  next if route.nil? # TODO: think about adding such cases to log
29
+ first = examples.first
29
30
 
30
31
  doc_path = route['doc_path']
31
32
  result[doc_path] ||= {}
@@ -36,28 +37,25 @@ module LazyApiDoc
36
37
 
37
38
  private
38
39
 
39
- def example_group(example, examples, route) # rubocop:disable Metrics/AbcSize
40
+ def example_group(example, examples, route)
40
41
  {
41
42
  example['verb'].downcase => {
42
43
  "tags" => [example.controller || 'Ungrouped'],
43
44
  "description" => example["description"].capitalize,
44
45
  "summary" => example.action,
45
- "parameters" => path_params(route, examples) + query_params(examples),
46
+ "parameters" => path_params(route, examples) + query_params(route, examples),
46
47
  "requestBody" => body_params(route, examples),
47
- "responses" => examples.group_by { |ex| ex.response['code'] }.map do |code, variants|
48
- [
49
- code,
50
- {
51
- "description" => variants.first["description"].capitalize,
48
+ "responses" => examples.group_by { |ex| ex.response['code'] }.transform_values do |variants|
49
+ {
50
+ "description" => variants.first["description"].capitalize,
52
51
  "content" => {
53
52
  example.response['content_type'] => {
54
53
  "schema" => ::LazyApiDoc::VariantsParser.new(variants.map { |v| parse_body(v.response) }).result
55
54
  }
56
55
  }
57
- }
58
- ]
59
- end.to_h # rubocop:disable Style/MultilineBlockChain
60
- }.reject { |_, v| v.nil? }
56
+ }
57
+ end
58
+ }.compact
61
59
  }
62
60
  end
63
61
 
@@ -83,12 +81,19 @@ module LazyApiDoc
83
81
  end
84
82
  end
85
83
 
86
- def query_params(examples)
84
+ def query_params(route, examples)
87
85
  query_variants = examples.map do |example|
88
86
  _path, query = example.request['full_path'].split('?')
89
- next {} unless query
90
87
 
91
- CGI.parse(query).map { |k, v| [k.gsub('[]', ''), k.match?('\[\]') ? v : v.first] }.to_h
88
+ params = if query
89
+ CGI.parse(query).to_h { |k, v| [k.gsub('[]', ''), k.match?('\[\]') ? v : v.first] }
90
+ else
91
+ {}
92
+ end
93
+ if %w[GET HEAD].include?(example['verb'])
94
+ params.merge!(example.params.except(*EXCLUDED_PARAMS, *route['path_params'], *route['defaults'].keys))
95
+ end
96
+ params
92
97
  end
93
98
 
94
99
  parsed = ::LazyApiDoc::VariantsParser.new(query_variants).result
@@ -104,9 +109,9 @@ module LazyApiDoc
104
109
 
105
110
  def body_params(route, examples)
106
111
  first = examples.first
107
- return unless %w[POST PATCH].include?(first['verb'])
112
+ return unless %w[POST PATCH PUT DELETE].include?(first['verb'])
108
113
 
109
- variants = examples.map { |example| example.params.except("controller", "action", "format", *route['path_params']) }
114
+ variants = examples.map { |example| example.params.except(*EXCLUDED_PARAMS, *route['path_params'], *route['defaults'].keys) }
110
115
  {
111
116
  'content' => {
112
117
  first.content_type => {
@@ -1,15 +1,9 @@
1
1
  module LazyApiDoc
2
2
  class RouteParser
3
- attr_reader :controller, :action, :verb
4
-
5
- def initialize(controller, action, verb)
6
- @controller = controller
7
- @action = action
8
- @verb = verb
9
- end
10
-
11
- def route
12
- self.class.routes.find { |r| r['action'] == action && r['controller'] == controller && r['verb'].include?(verb) }
3
+ def self.find_by(example)
4
+ r = routes.find do |r|
5
+ r['verb'].include?(example.verb) && example.params.slice(*r['defaults'].keys) == r['defaults']
6
+ end
13
7
  end
14
8
 
15
9
  def self.routes
@@ -20,13 +14,13 @@ module LazyApiDoc
20
14
 
21
15
  def self.format(route)
22
16
  route = ActionDispatch::Routing::RouteWrapper.new(route)
23
-
24
17
  {
25
18
  'doc_path' => route.path.gsub("(.:format)", "").gsub(/(:\w+)/, '{\1}').delete(":"),
26
19
  'path_params' => route.path.gsub("(.:format)", "").scan(/:\w+/).map { |p| p.delete(":") },
27
20
  'controller' => route.controller,
28
21
  'action' => route.action,
29
- 'verb' => route.verb.split('|')
22
+ 'verb' => route.verb.split('|'),
23
+ 'defaults' => route.defaults.transform_keys(&:to_s)
30
24
  }
31
25
  end
32
26
  end
@@ -15,6 +15,7 @@ module LazyApiDoc
15
15
  variants.delete(OPTIONAL)
16
16
  case variant
17
17
  when Array
18
+ variant = variants.find(&:any?) || variants.first
18
19
  parse_array(variant, variants)
19
20
  when Hash
20
21
  parse_hash(variants)
@@ -69,13 +70,13 @@ module LazyApiDoc
69
70
  def parse_hash(variants)
70
71
  result = types_template(variants)
71
72
  variant = variants.select { |v| v.is_a?(Hash) }.reverse_each
72
- .each_with_object({}) { |v, res| res.merge!(v) }
73
- result["properties"] = variant.map do |key, val|
73
+ .with_object({}) { |v, res| res.merge!(v) }
74
+ result["properties"] = variant.to_h do |key, val|
74
75
  [
75
76
  key.to_s,
76
77
  parse(val, variants.select { |v| v.is_a?(Hash) }.map { |v| v.fetch(key, OPTIONAL) })
77
78
  ]
78
- end.to_h
79
+ end
79
80
  result["required"] = variant.keys.select { |key| variants.select { |v| v.is_a?(Hash) }.all? { |v| v.key?(key) } }
80
81
  result
81
82
  end
@@ -1,3 +1,3 @@
1
1
  module LazyApiDoc
2
- VERSION = "0.2.3".freeze
2
+ VERSION = "0.2.5".freeze
3
3
  end
data/lib/lazy_api_doc.rb CHANGED
@@ -80,7 +80,7 @@ module LazyApiDoc
80
80
  end
81
81
 
82
82
  def save_examples(process_name)
83
- FileUtils.mkdir("#{path}/examples") unless File.exist?("#{path}/examples")
83
+ FileUtils.mkdir_p("#{path}/examples")
84
84
  File.write(
85
85
  "#{path}/examples/#{process_name}_#{ENV['TEST_ENV_NUMBER'] || SecureRandom.uuid}.json",
86
86
  {
metadata CHANGED
@@ -1,17 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lazy_api_doc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bogdan Guban
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-06-04 00:00:00.000000000 Z
11
+ date: 2023-04-18 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: The gem collects all requests and responses from your request specs and
14
- generates documentationbased on it
13
+ description: 'The gem collects all requests and responses from your request specs
14
+ and generates documentation based on it
15
+
16
+ '
15
17
  email:
16
18
  - biguban@gmail.com
17
19
  executables: []
@@ -55,6 +57,7 @@ metadata:
55
57
  homepage_uri: https://github.com/bguban/lazy_api_doc
56
58
  source_code_uri: https://github.com/bguban/lazy_api_doc
57
59
  changelog_uri: https://github.com/bguban/lazy_api_doc
60
+ rubygems_mfa_required: 'true'
58
61
  post_install_message:
59
62
  rdoc_options: []
60
63
  require_paths: