lazy_api_doc 0.2.3 → 0.2.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
  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: