swagcov 0.3.0 → 0.4.1

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: 5aaf6a7a919c70669dc24a129159b2ce961aa237495d57cfd1d94350bbad526f
4
- data.tar.gz: e312bf832ceca1bc66017b131c958ab9f70ea4efddc32fac9bda0fcb369d7696
3
+ metadata.gz: a9d919e84a0746826d0688b1624f11e8218c8e7ec9cfd4e7ae6457368672a275
4
+ data.tar.gz: ca13f5821ffc64ec599c4a171e6e15d019a6edbae43b3e765ef7d2fe101b0186
5
5
  SHA512:
6
- metadata.gz: 14de18f74737e418b16153aea8c9f107545b9445fc5956dd0617ddbae4a0ad78be83017d6df8f442724186d38fd44a47b8462d4dc7ce2590c2b7aae26aaff201
7
- data.tar.gz: b22dc442442935535df66b494d9f24f4475517eb36468208d24a3ad3b43f49202eb6ada1679efc1657804ea2e789b62b8dac030009ad1bf282fc9b6b3cfa1853
6
+ metadata.gz: b6e6ef15038466cbede2c5299bbffc4c72fafaccf61ea6a3771538f48ccf6102eb7a2458f8f195ee20146b01ed39534f2b46a1186cf7e41afb687d1242e3389a
7
+ data.tar.gz: 8a2eb6ade077b3f1d955d3053a35f3754560a87395df2a7f90177d69a94d061933db93c9fbb0afc170bd9ad2426bd49e0f4a08e6fc97b2db9a5192be589271f9
data/README.md CHANGED
@@ -26,7 +26,7 @@ Create a `.swagcov.yml` in root of your Rails application.
26
26
  ```yml
27
27
  docs:
28
28
  paths:
29
- - swagger/v1/swagger.yaml
29
+ - swagger.yaml
30
30
  ```
31
31
 
32
32
  - Add `only` routes (**optional**) :
@@ -49,7 +49,7 @@ Create a `.swagcov.yml` in root of your Rails application.
49
49
  ```yml
50
50
  docs:
51
51
  paths:
52
- - swagger/v1/swagger.yaml
52
+ - swagger.yaml
53
53
 
54
54
  routes:
55
55
  paths:
@@ -91,7 +91,7 @@ bundle exec rake swagcov
91
91
  ```yml
92
92
  docs:
93
93
  paths:
94
- - swagger/v1/swagger.yaml
94
+ - swagger.yaml
95
95
 
96
96
  routes:
97
97
  paths:
@@ -136,15 +136,15 @@ bundle exec rspec spec --exclude-pattern spec/sandbox_**/**/*_spec.rb
136
136
  - Ensure you have access to publish on [rubygems](https://rubygems.org/gems/swagcov).
137
137
  - Update [CHANGELOG](https://github.com/smridge/swagcov/blob/main/CHANGELOG.md).
138
138
  - Update [`VERSION`](https://github.com/smridge/swagcov/blob/main/lib/swagcov/version.rb).
139
- - Commit changes to `main` branch locally.
139
+ - Run `bundle update` for each sandbox application to reflect new swagcov version in each `Gemfile.lock`
140
+ - Open a Pull Request to ensure all specs pass, then merge to `main`.
141
+ - Checkout the latest `main` on your machine.
140
142
  - Run: `rake release`
141
143
  - This command builds the gem, creates a tag and publishes to rubygems, see [bundler docs](https://bundler.io/guides/creating_gem.html#releasing-the-gem).
142
144
 
143
145
  ## TODO
144
- - Create Rails 7 / Ruby 3.1 Sandbox
145
146
  - Add autogeneration of ignore paths
146
147
  - Add `CONTRIBUTING.md`
147
- - Add GitHub Action for linting
148
148
 
149
149
  ## Credit
150
150
  To [@lonelyelk](https://github.com/lonelyelk) for initial development!
@@ -31,8 +31,10 @@ module Swagcov
31
31
  attr_reader :dotfile
32
32
 
33
33
  def collect_coverage
34
+ openapi_files = ::Swagcov::OpenapiFiles.new(filepaths: dotfile.doc_paths)
35
+
34
36
  @routes.each do |route|
35
- path = route.path.spec.to_s.sub(/\(\.:format\)$/, "")
37
+ path = route.path.spec.to_s.chomp("(.:format)")
36
38
 
37
39
  next if third_party_route?(route, path)
38
40
 
@@ -45,30 +47,16 @@ module Swagcov
45
47
  next if dotfile.only_path_mismatch?(path)
46
48
 
47
49
  @total += 1
48
- regex = Regexp.new("^#{path.gsub(%r{:[^/]+}, '\\{[^/]+\\}')}(\\.[^/]+)?$")
49
- matching_keys = docs_paths.keys.grep(regex)
50
50
 
51
- if (doc = docs_paths.dig(matching_keys.first, route.verb.downcase))
51
+ if (response_keys = openapi_files.find_response_keys(path: path, route_verb: route.verb))
52
52
  @covered += 1
53
- @routes_covered << { verb: route.verb, path: path, status: doc["responses"].keys.map(&:to_s).sort.join(" ") }
53
+ @routes_covered << { verb: route.verb, path: path, status: response_keys.join(" ") }
54
54
  else
55
55
  @routes_not_covered << { verb: route.verb, path: path, status: "none" }
56
56
  end
57
57
  end
58
58
  end
59
59
 
60
- def docs_paths
61
- @docs_paths ||= Dir.glob(dotfile.doc_paths).reduce({}) do |acc, docspath|
62
- acc.merge(load_yaml(docspath))
63
- end
64
- end
65
-
66
- def load_yaml docspath
67
- YAML.load_file(docspath)["paths"]
68
- rescue Psych::SyntaxError
69
- raise BadConfigurationError, "Malinformed openapi file (#{docspath})"
70
- end
71
-
72
60
  def third_party_route? route, path
73
61
  # https://github.com/rails/rails/blob/48f3c3e201b57a4832314b2c957a3b303e89bfea/actionpack/lib/action_dispatch/routing/inspector.rb#L105-L107
74
62
  # Skips route paths like ["/rails/info/properties", "/rails/info", "/rails/mailers"]
@@ -87,13 +75,22 @@ module Swagcov
87
75
  routes.each do |route|
88
76
  $stdout.puts(
89
77
  format(
90
- "%<verb>10s %<path>-90s %<status>s",
78
+ "%<verb>10s %<path>-#{min_width(:path) + 1}s %<status>s",
91
79
  { verb: route[:verb], path: route[:path], status: route[:status].send(status_color) }
92
80
  )
93
81
  )
94
82
  end
95
83
  end
96
84
 
85
+ def min_width key
86
+ strings =
87
+ @routes_covered.map { |hash| hash[key] } +
88
+ @routes_ignored.map { |hash| hash[key] } +
89
+ @routes_not_covered.map { |hash| hash[key] }
90
+
91
+ strings.max_by(&:length).size
92
+ end
93
+
97
94
  def final_output
98
95
  $stdout.puts
99
96
  $stdout.puts(
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Swagcov
4
+ class OpenapiFiles
5
+ def initialize filepaths:
6
+ @filepaths = filepaths
7
+ @openapi_paths = load_yamls
8
+ end
9
+
10
+ def find_response_keys path:, route_verb:
11
+ # replace :id with {id}
12
+ regex = Regexp.new("^#{path.gsub(%r{:[^/]+}, '\\{[^/]+\\}')}?$")
13
+
14
+ matching_paths_key = @openapi_paths.keys.grep(regex).first
15
+ matching_request_method_key = @openapi_paths.dig(matching_paths_key, route_verb.downcase)
16
+
17
+ matching_request_method_key["responses"].keys.map(&:to_s).sort if matching_request_method_key
18
+ end
19
+
20
+ private
21
+
22
+ def load_yamls
23
+ Dir.glob(@filepaths).reduce({}) do |hash, filepath|
24
+ hash.merge(load_yaml(filepath))
25
+ end
26
+ end
27
+
28
+ def load_yaml filepath
29
+ YAML.load_file(filepath)["paths"]
30
+ rescue Psych::SyntaxError
31
+ raise BadConfigurationError, "Malinformed openapi file (#{filepath})"
32
+ end
33
+ end
34
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Swagcov
4
- VERSION = "0.3.0"
4
+ VERSION = "0.4.1"
5
5
  end
data/lib/swagcov.rb CHANGED
@@ -6,6 +6,7 @@ if defined?(Rails)
6
6
  require "swagcov/railtie"
7
7
  require "swagcov/dotfile"
8
8
  require "swagcov/coverage"
9
+ require "swagcov/openapi_files"
9
10
  end
10
11
 
11
12
  require "swagcov/core_ext/string"
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: swagcov
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sarah Ridge
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2022-02-21 00:00:00.000000000 Z
10
+ date: 2025-03-18 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: rails
@@ -24,77 +23,6 @@ dependencies:
24
23
  - - ">="
25
24
  - !ruby/object:Gem::Version
26
25
  version: '5'
27
- - !ruby/object:Gem::Dependency
28
- name: pry-byebug
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: rspec
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: rubocop
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: rubocop-performance
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: rubocop-rspec
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- description:
98
26
  email:
99
27
  - sarahmarie@hey.com
100
28
  executables: []
@@ -108,6 +36,7 @@ files:
108
36
  - lib/swagcov/core_ext/string.rb
109
37
  - lib/swagcov/coverage.rb
110
38
  - lib/swagcov/dotfile.rb
39
+ - lib/swagcov/openapi_files.rb
111
40
  - lib/swagcov/railtie.rb
112
41
  - lib/swagcov/version.rb
113
42
  - lib/tasks/swagcove.rake
@@ -120,7 +49,6 @@ metadata:
120
49
  source_code_uri: https://github.com/smridge/swagcov
121
50
  changelog_uri: https://github.com/smridge/swagcov/blob/main/CHANGELOG.md
122
51
  rubygems_mfa_required: 'true'
123
- post_install_message:
124
52
  rdoc_options: []
125
53
  require_paths:
126
54
  - lib
@@ -135,8 +63,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
135
63
  - !ruby/object:Gem::Version
136
64
  version: '0'
137
65
  requirements: []
138
- rubygems_version: 3.2.32
139
- signing_key:
66
+ rubygems_version: 3.6.6
140
67
  specification_version: 4
141
- summary: Open API docs coverage for Rails Routes
68
+ summary: OpenAPI documentation coverage for Rails Routes
142
69
  test_files: []