Skip to content

Commit dd00931

Browse files
committed
Add Test::Configuration#skip_coverage to skip test coverage for specific paths + request methods and all responses
1 parent 9c8aeca commit dd00931

7 files changed

Lines changed: 58 additions & 13 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
## 2.10.0
66

7+
- Add Test::Configuration#skip_coverage to skip test coverage for specific paths + request methods and all responses
78
- Deprecate setting minimum_coverage value. Use skip_response_coverage, ignored_unknown_status to configure coverage instead.
89
- Update openapi_parameters to make parsing array query parameters more consistent.
910
Now parsing empty array query parameter like `ids=&` or `ids&` both result in an empty array value (`[]`) instead of `nil` or `""`.

README.md

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,24 +70,49 @@ Here is how to set it up:
7070
end
7171
```
7272
- Or inject a Module to wrap (prepend) the `call` method of your Rack app Class.
73-
73+
7474
NOTE: This is still work in progress. It works with basic Sinatra apps, but does not work with Hanami or Rails out of the box, yet. PRs welcome 🤗
75-
75+
7676
```ruby
7777
OpenapiFirst::Test.observe(MyApplication)
7878
```
7979
3. Run your tests. The Coverage feature will tell you about missing or invalid requests/responses.
8080

8181
(✷1): It does not matter what method of openapi_first you use to validate requests/responses. Instead of using `OpenapiFirstTest.app` to wrap your application, you could also use the [middlewares](#rack-middlewares) or [test assertion method](#test-assertions), but you would have to do that for all requests/responses defined in your API description to make coverage work.
8282

83-
OpenapiFirst' request validation raises an error when a request is not defined. You can deactivate this during testing:
83+
### Configure test coverage
84+
85+
OpenapiFirst::Test raises an error when a request is not defined. You can deactivate this with:
8486

8587
```ruby
8688
OpenapiFirst::Test.setup do |test|
89+
# …
8790
test.ignore_unknown_requests = true
8891
end
8992
```
9093

94+
Exclude certain _responses_ from coverage with `skip_coverage`:
95+
96+
```ruby
97+
OpenapiFirst::Test.setup do |test|
98+
# …
99+
test.skip_response_coverage do |response_definition|
100+
response_definition.status == '5XX'
101+
end
102+
end
103+
```
104+
105+
Skip coverage for a request and all responses alltogether of a route with `skip_coverage`:
106+
107+
```ruby
108+
OpenapiFirst::Test.setup do |test|
109+
# …
110+
test.skip_coverage do |path, request_method|
111+
path == '/bookings/{bookingId}' && requests_method == 'DELETE'
112+
end
113+
end
114+
```
115+
91116
## Rack Middlewares
92117

93118
### Request validation

lib/openapi_first/test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def self.setup
4141

4242
configuration.registry.each { |name, oad| register(oad, as: name) }
4343
configuration.apps.each { |name, app| observe(app, api: name) }
44-
Coverage.start(skip_response: configuration.skip_response_coverage)
44+
Coverage.start(skip_response: configuration.skip_response_coverage, skip_route: configuration.skip_coverage)
4545

4646
if definitions.empty?
4747
raise NotRegisteredError,

lib/openapi_first/test/configuration.rb

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ def initialize
99
@coverage_formatter = Coverage::TerminalFormatter
1010
@coverage_formatter_options = {}
1111
@skip_response_coverage = nil
12+
@skip_coverage = nil
1213
@response_raise_error = true
1314
@ignored_unknown_status = [404]
1415
@report_coverage = true
@@ -44,7 +45,7 @@ def report_coverage=(value)
4445
@report_coverage = value
4546
end
4647

47-
# @deprecated Use skip_response_coverage, ignored_unknown_status to configure coverage
48+
# @deprecated Use skip_response_coverage, ignored_unknown_status or skip_coverage to configure coverage
4849
def minimum_coverage=(value)
4950
warn 'OpenapiFirst::Test::Configuration#minimum_coverage= is deprecated. ' \
5051
'Use skip_response_coverage, ignored_unknown_status to configure coverage instead.'
@@ -56,6 +57,12 @@ def skip_response_coverage(&block)
5657

5758
@skip_response_coverage = block
5859
end
60+
61+
def skip_coverage(&block)
62+
return @skip_coverage unless block_given?
63+
64+
@skip_coverage = block
65+
end
5966
end
6067
end
6168
end

lib/openapi_first/test/coverage.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ class << self
1919

2020
def install = Test.install
2121

22-
def start(skip_response: nil)
22+
def start(skip_response: nil, skip_route: nil)
2323
@current_run = Test.definitions.values.to_h do |oad|
24-
plan = Plan.for(oad, skip_response:)
24+
plan = Plan.for(oad, skip_response:, skip_route:)
2525
[oad.key, plan]
2626
end
2727
end

lib/openapi_first/test/coverage/plan.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ module Coverage
1212
class Plan
1313
class UnknownRequestError < StandardError; end
1414

15-
def self.for(oad, skip_response: nil)
15+
def self.for(oad, skip_response: nil, skip_route: nil)
1616
plan = new(definition_key: oad.key, filepath: oad.filepath)
17-
oad.routes.each do |route|
17+
routes = oad.routes
18+
routes = routes.reject { |route| skip_route[route.path, route.request_method] } if skip_route
19+
routes.each do |route|
1820
responses = skip_response ? route.responses.reject(&skip_response) : route.responses
1921
plan.add_route request_method: route.request_method,
2022
path: route.path,

spec/test_spec.rb

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,12 +141,22 @@ def call(_env)
141141
expect(described_class::Coverage.plans.first.tasks.count).to eq(2)
142142
end
143143

144-
it 'can skip_response_coverage' do
144+
it 'can skip_coverage for whole routes' do
145145
described_class.setup do |test|
146-
test.register('./examples/openapi.yaml')
147-
test.skip_response_coverage { |res| res.status == '401' }
146+
test.register('./spec/data/petstore.yaml')
147+
test.skip_coverage { |path, request_method| path == '/pets' && request_method == 'POST' }
148148
end
149-
expect(described_class::Coverage.plans.first.tasks.count).to eq(2)
149+
route_tasks = described_class::Coverage.plans.first.routes
150+
expect(route_tasks.map { |route| [route.path, route.request_method] }).to eq([['/pets', 'GET'], ['/pets/{petId}', 'GET']])
151+
end
152+
153+
it 'can skip_coverage for paths' do
154+
described_class.setup do |test|
155+
test.register('./spec/data/petstore.yaml')
156+
test.skip_coverage { |path| path == '/pets' }
157+
end
158+
route_tasks = described_class::Coverage.plans.first.routes
159+
expect(route_tasks.map { |route| [route.path, route.request_method] }).to eq([['/pets/{petId}', 'GET']])
150160
end
151161

152162
it 'raises an error if no block is given' do

0 commit comments

Comments
 (0)