openapi_first 3.4.3 → 4.0.0
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 +4 -4
- data/CHANGELOG.md +66 -0
- data/README.md +95 -42
- data/lib/openapi_first/builder.rb +85 -50
- data/lib/openapi_first/child_configuration.rb +0 -2
- data/lib/openapi_first/configuration.rb +0 -23
- data/lib/openapi_first/definition.rb +35 -2
- data/lib/openapi_first/failure.rb +5 -1
- data/lib/openapi_first/middlewares/request_validation.rb +1 -1
- data/lib/openapi_first/middlewares/response_validation.rb +1 -1
- data/lib/openapi_first/parameter/converter/array_converter.rb +42 -0
- data/lib/openapi_first/parameter/converter/object_converter.rb +60 -0
- data/lib/openapi_first/parameter/converter.rb +69 -0
- data/lib/openapi_first/parameter/unpackers.rb +132 -0
- data/lib/openapi_first/parameter.rb +70 -0
- data/lib/openapi_first/parameter_content_parsers.rb +55 -0
- data/lib/openapi_first/parameters_parser.rb +23 -0
- data/lib/openapi_first/query_string_parser.rb +93 -0
- data/lib/openapi_first/ref_resolver.rb +56 -3
- data/lib/openapi_first/request.rb +11 -10
- data/lib/openapi_first/request_body_parsers.rb +11 -7
- data/lib/openapi_first/request_headers.rb +27 -0
- data/lib/openapi_first/request_validator.rb +4 -1
- data/lib/openapi_first/response_header.rb +9 -0
- data/lib/openapi_first/response_parser.rb +3 -10
- data/lib/openapi_first/router.rb +27 -12
- data/lib/openapi_first/schema/hash.rb +0 -1
- data/lib/openapi_first/sinatra.rb +217 -0
- data/lib/openapi_first/test/configuration.rb +0 -34
- data/lib/openapi_first/test/coverage/html_reporter/context.rb +24 -17
- data/lib/openapi_first/test/coverage/html_reporter.css +214 -67
- data/lib/openapi_first/test/coverage/html_reporter.html.erb +39 -11
- data/lib/openapi_first/test/coverage/html_reporter.rb +11 -1
- data/lib/openapi_first/test/coverage/plan.rb +30 -10
- data/lib/openapi_first/test/coverage/request_task.rb +7 -2
- data/lib/openapi_first/test/coverage/response_task.rb +6 -1
- data/lib/openapi_first/test/coverage/route_task.rb +23 -1
- data/lib/openapi_first/test/coverage/skipped_summary.rb +22 -0
- data/lib/openapi_first/test/coverage/terminal_reporter.rb +23 -11
- data/lib/openapi_first/test/coverage.rb +9 -3
- data/lib/openapi_first/test.rb +69 -11
- data/lib/openapi_first/validators/multipart_request_body.rb +57 -0
- data/lib/openapi_first/validators/request_body.rb +20 -7
- data/lib/openapi_first/validators/request_parameters.rb +5 -4
- data/lib/openapi_first/version.rb +1 -1
- metadata +15 -23
- data/lib/openapi_first/header.rb +0 -9
|
@@ -5,17 +5,14 @@ module OpenapiFirst
|
|
|
5
5
|
module Coverage
|
|
6
6
|
# Reports coverage to a logger using ANSI-coloured lines.
|
|
7
7
|
class TerminalReporter
|
|
8
|
+
include SkippedSummary
|
|
9
|
+
|
|
8
10
|
def initialize(verbose: false, focused: true, logger: Test.logger)
|
|
9
11
|
@verbose = verbose
|
|
10
12
|
@focused = focused && !verbose
|
|
11
13
|
@logger = logger
|
|
12
14
|
end
|
|
13
15
|
|
|
14
|
-
def format(coverage_result)
|
|
15
|
-
logger.warn 'DEPRECATION WARNING: TerminalReporter#format is deprecated, use #report instead.'
|
|
16
|
-
report(coverage_result)
|
|
17
|
-
end
|
|
18
|
-
|
|
19
16
|
def report(coverage_result)
|
|
20
17
|
coverage = coverage_result.coverage
|
|
21
18
|
if coverage.zero?
|
|
@@ -23,13 +20,14 @@ module OpenapiFirst
|
|
|
23
20
|
'Make sure to observe your application using OpenapiFirst::Test.'
|
|
24
21
|
end
|
|
25
22
|
coverage_result.plans.each { |plan| format_plan(plan) } if coverage.positive?
|
|
23
|
+
log_skipped_summary(coverage_result)
|
|
26
24
|
end
|
|
27
25
|
|
|
28
26
|
private attr_reader :out, :verbose, :focused, :logger
|
|
29
27
|
|
|
30
28
|
private
|
|
31
29
|
|
|
32
|
-
def format_plan(plan)
|
|
30
|
+
def format_plan(plan)
|
|
33
31
|
logger.info "API validation coverage for #{plan.api_identifier}: #{plan.coverage}%"
|
|
34
32
|
return if plan.done? && !verbose
|
|
35
33
|
|
|
@@ -37,9 +35,7 @@ module OpenapiFirst
|
|
|
37
35
|
focused_route = requested_routes_count <= 1 && focused
|
|
38
36
|
|
|
39
37
|
plan.routes.each do |route|
|
|
40
|
-
next
|
|
41
|
-
|
|
42
|
-
next if route.requests.none?(&:requested?) && focused_route
|
|
38
|
+
next unless report_route?(route, focused_route)
|
|
43
39
|
|
|
44
40
|
format_requests(route.requests)
|
|
45
41
|
|
|
@@ -47,9 +43,19 @@ module OpenapiFirst
|
|
|
47
43
|
end
|
|
48
44
|
end
|
|
49
45
|
|
|
46
|
+
def report_route?(route, focused_route)
|
|
47
|
+
return verbose if route.skipped?
|
|
48
|
+
return false if route.finished? && !verbose
|
|
49
|
+
return false if focused_route && route.requests.none?(&:requested?)
|
|
50
|
+
|
|
51
|
+
true
|
|
52
|
+
end
|
|
53
|
+
|
|
50
54
|
def format_requests(requests)
|
|
51
55
|
requests.each do |request|
|
|
52
|
-
if request.
|
|
56
|
+
if request.skipped?
|
|
57
|
+
log_skipped "⚠ #{request_label(request)} – Skipped!" if verbose
|
|
58
|
+
elsif request.finished?
|
|
53
59
|
log_success "✓ #{request_label(request)}"
|
|
54
60
|
else
|
|
55
61
|
log_error "❌ #{request_label(request)} – #{explain_unfinished_request(request)}"
|
|
@@ -59,7 +65,9 @@ module OpenapiFirst
|
|
|
59
65
|
|
|
60
66
|
def format_responses(responses)
|
|
61
67
|
responses.each do |response|
|
|
62
|
-
if response.
|
|
68
|
+
if response.skipped?
|
|
69
|
+
log_skipped " #{response_label(response)} – Skipped!" if verbose
|
|
70
|
+
elsif response.finished?
|
|
63
71
|
log_success " ✓ #{response_label(response)}" if verbose
|
|
64
72
|
else
|
|
65
73
|
log_error " ❌ #{response_label(response)} – #{explain_unfinished_response(response)}"
|
|
@@ -98,6 +106,10 @@ module OpenapiFirst
|
|
|
98
106
|
logger.info "\e[32m#{msg}\e[0m"
|
|
99
107
|
end
|
|
100
108
|
|
|
109
|
+
def log_skipped(msg)
|
|
110
|
+
logger.info "\e[33m#{msg}\e[0m"
|
|
111
|
+
end
|
|
112
|
+
|
|
101
113
|
def log_error(msg)
|
|
102
114
|
logger.error "\e[31m#{msg}\e[0m"
|
|
103
115
|
end
|
|
@@ -4,6 +4,7 @@ require_relative 'coverage/plan'
|
|
|
4
4
|
require_relative 'coverage/tracker'
|
|
5
5
|
require_relative 'coverage/covered_request'
|
|
6
6
|
require_relative 'coverage/covered_response'
|
|
7
|
+
require_relative 'coverage/skipped_summary'
|
|
7
8
|
require 'drb'
|
|
8
9
|
|
|
9
10
|
module OpenapiFirst
|
|
@@ -15,10 +16,15 @@ module OpenapiFirst
|
|
|
15
16
|
autoload :TerminalReporter, 'openapi_first/test/coverage/terminal_reporter'
|
|
16
17
|
autoload :HtmlReporter, 'openapi_first/test/coverage/html_reporter'
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
Result = Data.define(:plans, :coverage) do
|
|
20
|
+
def skipped_requests_count
|
|
21
|
+
plans.sum(&:skipped_requests_count)
|
|
22
|
+
end
|
|
20
23
|
|
|
21
|
-
|
|
24
|
+
def skipped_responses_count
|
|
25
|
+
plans.sum(&:skipped_responses_count)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
22
28
|
|
|
23
29
|
class << self
|
|
24
30
|
def start(skip_response: nil, skip_route: nil)
|
data/lib/openapi_first/test.rb
CHANGED
|
@@ -5,7 +5,64 @@ require_relative 'test/configuration'
|
|
|
5
5
|
require_relative 'registry'
|
|
6
6
|
|
|
7
7
|
module OpenapiFirst
|
|
8
|
-
# Test integration
|
|
8
|
+
# Test integration for contract testing. Use this to validate requests/responses against a
|
|
9
|
+
# registered OAD while your test suite runs, and tracks which parts of the API
|
|
10
|
+
# description have been exercised.
|
|
11
|
+
#
|
|
12
|
+
# @example Basic setup (e.g. in spec_helper.rb)
|
|
13
|
+
# require 'openapi_first'
|
|
14
|
+
# OpenapiFirst::Test.setup
|
|
15
|
+
#
|
|
16
|
+
# {.setup} prepares coverage tracking and OAD registration. To actually validate the
|
|
17
|
+
# requests/responses that happen during your tests, you also have to observe your
|
|
18
|
+
# application, i.e. wrap it with silent request/response validation. There are three ways
|
|
19
|
+
# to do this:
|
|
20
|
+
#
|
|
21
|
+
# 1. Include {Methods}, which adds an `app` method wrapping your rack app for rack-test.
|
|
22
|
+
# This is the easiest option if you don't already define `app` yourself:
|
|
23
|
+
# RSpec.configure do |config|
|
|
24
|
+
# config.include OpenapiFirst::Test::Methods[MyApp], type: :request
|
|
25
|
+
# end
|
|
26
|
+
# 2. Call {.observe} to inject validation directly into an app class or instance
|
|
27
|
+
# , if you can't rely on rack-test's `app` method:
|
|
28
|
+
# OpenapiFirst::Test.observe(Rails.application)
|
|
29
|
+
# 3. Call {.app} to wrap an app instance yourself, e.g. if you already define your own
|
|
30
|
+
# `app` method and only want to wrap what it returns:
|
|
31
|
+
# def app
|
|
32
|
+
# OpenapiFirst::Test.app(MyApp.new)
|
|
33
|
+
# end
|
|
34
|
+
#
|
|
35
|
+
# @example Configure via the block passed to .setup
|
|
36
|
+
# OpenapiFirst::Test.setup do |test|
|
|
37
|
+
# test.register('openapi/openapi.yaml')
|
|
38
|
+
#
|
|
39
|
+
# # Ignore certain request/response errors instead of raising them
|
|
40
|
+
# test.ignore_request_error do |validated_request|
|
|
41
|
+
# validated_request.path.start_with?('/legacy') && validated_request.unknown?
|
|
42
|
+
# end
|
|
43
|
+
# test.ignore_response_error do |validated_response, rack_request|
|
|
44
|
+
# validated_response.error.type == :response_status_not_found
|
|
45
|
+
# end
|
|
46
|
+
#
|
|
47
|
+
# # Response status codes that are okay to leave uncovered (default: 401, 404, 500)
|
|
48
|
+
# test.ignored_unknown_status << 403
|
|
49
|
+
# test.ignore_unknown_response_status = true # or: ignore all unknown status codes
|
|
50
|
+
#
|
|
51
|
+
# # Don't raise when a request doesn't match the API description at all
|
|
52
|
+
# test.ignore_unknown_requests = true
|
|
53
|
+
#
|
|
54
|
+
# # Exclude parts of the API description from coverage tracking
|
|
55
|
+
# test.skip_response_coverage { |response_definition| response_definition.status == '5XX' }
|
|
56
|
+
# test.skip_coverage { |path, request_method| path == '/internal' && request_method == 'GET' }
|
|
57
|
+
#
|
|
58
|
+
# # Require minimm of 95% coverage of the API description (default: 100)
|
|
59
|
+
# test.minimum_coverage = 95
|
|
60
|
+
#
|
|
61
|
+
# # Report coverage always (default), only warn, or not at all: true / :warn / false
|
|
62
|
+
# test.report_coverage = :warn
|
|
63
|
+
# end
|
|
64
|
+
#
|
|
65
|
+
# See {OpenapiFirst::Test::Configuration} for the full list of options.
|
|
9
66
|
module Test # rubocop:disable Metrics/ModuleLength
|
|
10
67
|
autoload :Coverage, 'openapi_first/test/coverage'
|
|
11
68
|
autoload :Methods, 'openapi_first/test/methods'
|
|
@@ -58,7 +115,7 @@ module OpenapiFirst
|
|
|
58
115
|
'Please register your API description via ' \
|
|
59
116
|
"`OpenapiFirst.register('myopenapi.yaml)` or " \
|
|
60
117
|
'in a block passed to `OpenapiFirst::Test.setup` like this: ' \
|
|
61
|
-
"`OpenapiFirst::Test.setup { |test| test.register('myopenapi.yaml') }` "
|
|
118
|
+
"`OpenapiFirst::Test.setup { |test| test.register('myopenapi.yaml') }` "
|
|
62
119
|
|
|
63
120
|
end
|
|
64
121
|
|
|
@@ -83,22 +140,23 @@ module OpenapiFirst
|
|
|
83
140
|
return unless configuration.report_coverage == true
|
|
84
141
|
|
|
85
142
|
coverage = Coverage.result.coverage
|
|
86
|
-
|
|
143
|
+
minimum_coverage = configuration.minimum_coverage
|
|
87
144
|
|
|
88
|
-
|
|
145
|
+
if coverage < minimum_coverage
|
|
146
|
+
logger.error "API Coverage fails with exit 2, because not all described requests and responses have been tested (#{coverage.round(4)}% covered)." # rubocop:disable Layout/LineLength
|
|
89
147
|
|
|
90
|
-
|
|
148
|
+
exit 2
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
return unless coverage - minimum_coverage >= 1.0
|
|
152
|
+
|
|
153
|
+
logger.warn "API Coverage (#{coverage.round(4)}%) is higher than the configured minimum_coverage (#{minimum_coverage}%). You should probably increase minimum_coverage to #{coverage.round(4)}." # rubocop:disable Layout/LineLength
|
|
91
154
|
end
|
|
92
155
|
|
|
93
156
|
# Print the coverage report
|
|
94
157
|
# @param reporter A reporter class to render the report.
|
|
95
|
-
# @param formatter @deprecated Alias for `reporter:`.
|
|
96
158
|
# @return [IO] An output where to puts the report.
|
|
97
|
-
def self.report_coverage(reporter: Coverage::TerminalReporter,
|
|
98
|
-
if formatter
|
|
99
|
-
warn 'DEPRECATION WARNING: Test.report_coverage(formatter:) is deprecated, use reporter: instead.'
|
|
100
|
-
reporter = formatter
|
|
101
|
-
end
|
|
159
|
+
def self.report_coverage(reporter: Coverage::TerminalReporter, **)
|
|
102
160
|
reporter.new(**).report(Coverage.result)
|
|
103
161
|
end
|
|
104
162
|
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../schema/validation_result'
|
|
4
|
+
|
|
5
|
+
module OpenapiFirst
|
|
6
|
+
module Validators
|
|
7
|
+
class MultipartRequestBody
|
|
8
|
+
FILE_UPLOAD_PLACEHOLDER = String.new('', encoding: Encoding::BINARY).freeze
|
|
9
|
+
|
|
10
|
+
def initialize(content_schema:)
|
|
11
|
+
@schema = content_schema
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def call(parsed_request)
|
|
15
|
+
body = parsed_request.body
|
|
16
|
+
return if body.nil?
|
|
17
|
+
|
|
18
|
+
uploads = collect_file_uploads(body)
|
|
19
|
+
uploads.each_key { write_at(body, _1, FILE_UPLOAD_PLACEHOLDER) }
|
|
20
|
+
begin
|
|
21
|
+
validate(body)
|
|
22
|
+
ensure
|
|
23
|
+
uploads.each { |path, upload| write_at(body, path, upload) }
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def validate(body)
|
|
30
|
+
validation = Schema::ValidationResult.new(
|
|
31
|
+
@schema.validate(body, access_mode: 'write')
|
|
32
|
+
)
|
|
33
|
+
Failure.new(:invalid_body, errors: validation.errors) if validation.error?
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def collect_file_uploads(value, path = [], result = {})
|
|
37
|
+
case value
|
|
38
|
+
when ::Hash
|
|
39
|
+
if value.key?(:tempfile)
|
|
40
|
+
result[path] = value unless path.empty?
|
|
41
|
+
else
|
|
42
|
+
value.each { |key, item| collect_file_uploads(item, path + [key], result) }
|
|
43
|
+
end
|
|
44
|
+
when ::Array
|
|
45
|
+
value.each_with_index { |item, index| collect_file_uploads(item, path + [index], result) }
|
|
46
|
+
end
|
|
47
|
+
result
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def write_at(root, path, value)
|
|
51
|
+
*parents, key = path
|
|
52
|
+
container = parents.empty? ? root : root.dig(*parents)
|
|
53
|
+
container[key] = value if container
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -1,20 +1,33 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative 'multipart_request_body'
|
|
4
|
+
|
|
3
5
|
module OpenapiFirst
|
|
4
6
|
module Validators
|
|
5
7
|
class RequestBody
|
|
6
|
-
|
|
8
|
+
MULTIPART = %r{\Amultipart/}i
|
|
9
|
+
private_constant :MULTIPART
|
|
10
|
+
|
|
11
|
+
REQUIREMENT = lambda do |parsed_request|
|
|
12
|
+
Failure.new(:invalid_body, message: 'Request body must not be empty') if parsed_request.body.nil?
|
|
13
|
+
end
|
|
14
|
+
private_constant :REQUIREMENT
|
|
15
|
+
|
|
16
|
+
def self.for(content_schema:, required_request_body:, content_type:)
|
|
17
|
+
validators = []
|
|
18
|
+
validators << REQUIREMENT if required_request_body
|
|
19
|
+
klass = MULTIPART.match?(content_type.to_s) ? MultipartRequestBody : self
|
|
20
|
+
validators << klass.new(content_schema:)
|
|
21
|
+
validators
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def initialize(content_schema:)
|
|
7
25
|
@schema = content_schema
|
|
8
|
-
@required = required_request_body
|
|
9
26
|
end
|
|
10
27
|
|
|
11
28
|
def call(parsed_request)
|
|
12
29
|
body = parsed_request.body
|
|
13
|
-
if body.nil?
|
|
14
|
-
return Failure.new(:invalid_body, message: 'Request body must not be empty') if @required
|
|
15
|
-
|
|
16
|
-
return
|
|
17
|
-
end
|
|
30
|
+
return if body.nil?
|
|
18
31
|
|
|
19
32
|
validation = Schema::ValidationResult.new(
|
|
20
33
|
@schema.validate(body, access_mode: 'write')
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
module OpenapiFirst
|
|
4
4
|
module Validators
|
|
5
|
+
# @visibility private
|
|
5
6
|
module RequestParameters
|
|
6
|
-
|
|
7
|
+
Headers = Data.define(:schema) do
|
|
7
8
|
def call(parsed_request)
|
|
8
9
|
validation = schema.validate(parsed_request.headers)
|
|
9
10
|
Failure.new(:invalid_header, errors: validation.errors) if validation.error?
|
|
@@ -24,7 +25,7 @@ module OpenapiFirst
|
|
|
24
25
|
end
|
|
25
26
|
end
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
Cookies = Data.define(:schema) do
|
|
28
29
|
def call(parsed_request)
|
|
29
30
|
validation = schema.validate(parsed_request.cookies)
|
|
30
31
|
Failure.new(:invalid_cookie, errors: validation.errors) if validation.error?
|
|
@@ -34,8 +35,8 @@ module OpenapiFirst
|
|
|
34
35
|
VALIDATORS = {
|
|
35
36
|
path_schema: Path,
|
|
36
37
|
query_schema: Query,
|
|
37
|
-
header_schema:
|
|
38
|
-
cookie_schema:
|
|
38
|
+
header_schema: Headers,
|
|
39
|
+
cookie_schema: Cookies
|
|
39
40
|
}.freeze
|
|
40
41
|
|
|
41
42
|
def self.for(args)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: openapi_first
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 4.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andreas Haller
|
|
@@ -57,26 +57,6 @@ dependencies:
|
|
|
57
57
|
- - "<"
|
|
58
58
|
- !ruby/object:Gem::Version
|
|
59
59
|
version: '3.0'
|
|
60
|
-
- !ruby/object:Gem::Dependency
|
|
61
|
-
name: openapi_parameters
|
|
62
|
-
requirement: !ruby/object:Gem::Requirement
|
|
63
|
-
requirements:
|
|
64
|
-
- - ">="
|
|
65
|
-
- !ruby/object:Gem::Version
|
|
66
|
-
version: 0.12.0
|
|
67
|
-
- - "<"
|
|
68
|
-
- !ruby/object:Gem::Version
|
|
69
|
-
version: '2.0'
|
|
70
|
-
type: :runtime
|
|
71
|
-
prerelease: false
|
|
72
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
73
|
-
requirements:
|
|
74
|
-
- - ">="
|
|
75
|
-
- !ruby/object:Gem::Version
|
|
76
|
-
version: 0.12.0
|
|
77
|
-
- - "<"
|
|
78
|
-
- !ruby/object:Gem::Version
|
|
79
|
-
version: '2.0'
|
|
80
60
|
- !ruby/object:Gem::Dependency
|
|
81
61
|
name: rack
|
|
82
62
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -117,20 +97,29 @@ files:
|
|
|
117
97
|
- lib/openapi_first/errors.rb
|
|
118
98
|
- lib/openapi_first/failure.rb
|
|
119
99
|
- lib/openapi_first/file_loader.rb
|
|
120
|
-
- lib/openapi_first/header.rb
|
|
121
100
|
- lib/openapi_first/json.rb
|
|
122
101
|
- lib/openapi_first/middlewares/request_validation.rb
|
|
123
102
|
- lib/openapi_first/middlewares/response_validation.rb
|
|
103
|
+
- lib/openapi_first/parameter.rb
|
|
104
|
+
- lib/openapi_first/parameter/converter.rb
|
|
105
|
+
- lib/openapi_first/parameter/converter/array_converter.rb
|
|
106
|
+
- lib/openapi_first/parameter/converter/object_converter.rb
|
|
107
|
+
- lib/openapi_first/parameter/unpackers.rb
|
|
108
|
+
- lib/openapi_first/parameter_content_parsers.rb
|
|
109
|
+
- lib/openapi_first/parameters_parser.rb
|
|
124
110
|
- lib/openapi_first/parsed_request.rb
|
|
125
111
|
- lib/openapi_first/plugins.rb
|
|
126
112
|
- lib/openapi_first/plugins/x_public.rb
|
|
113
|
+
- lib/openapi_first/query_string_parser.rb
|
|
127
114
|
- lib/openapi_first/ref_resolver.rb
|
|
128
115
|
- lib/openapi_first/registry.rb
|
|
129
116
|
- lib/openapi_first/request.rb
|
|
130
117
|
- lib/openapi_first/request_body_parsers.rb
|
|
118
|
+
- lib/openapi_first/request_headers.rb
|
|
131
119
|
- lib/openapi_first/request_validator.rb
|
|
132
120
|
- lib/openapi_first/response.rb
|
|
133
121
|
- lib/openapi_first/response_body_parsers.rb
|
|
122
|
+
- lib/openapi_first/response_header.rb
|
|
134
123
|
- lib/openapi_first/response_parser.rb
|
|
135
124
|
- lib/openapi_first/response_validator.rb
|
|
136
125
|
- lib/openapi_first/router.rb
|
|
@@ -140,6 +129,7 @@ files:
|
|
|
140
129
|
- lib/openapi_first/schema/hash.rb
|
|
141
130
|
- lib/openapi_first/schema/validation_error.rb
|
|
142
131
|
- lib/openapi_first/schema/validation_result.rb
|
|
132
|
+
- lib/openapi_first/sinatra.rb
|
|
143
133
|
- lib/openapi_first/test.rb
|
|
144
134
|
- lib/openapi_first/test/app.rb
|
|
145
135
|
- lib/openapi_first/test/callable.rb
|
|
@@ -155,6 +145,7 @@ files:
|
|
|
155
145
|
- lib/openapi_first/test/coverage/request_task.rb
|
|
156
146
|
- lib/openapi_first/test/coverage/response_task.rb
|
|
157
147
|
- lib/openapi_first/test/coverage/route_task.rb
|
|
148
|
+
- lib/openapi_first/test/coverage/skipped_summary.rb
|
|
158
149
|
- lib/openapi_first/test/coverage/terminal_reporter.rb
|
|
159
150
|
- lib/openapi_first/test/coverage/tracker.rb
|
|
160
151
|
- lib/openapi_first/test/logger.rb
|
|
@@ -165,6 +156,7 @@ files:
|
|
|
165
156
|
- lib/openapi_first/test/plain_helpers.rb
|
|
166
157
|
- lib/openapi_first/validated_request.rb
|
|
167
158
|
- lib/openapi_first/validated_response.rb
|
|
159
|
+
- lib/openapi_first/validators/multipart_request_body.rb
|
|
168
160
|
- lib/openapi_first/validators/request_body.rb
|
|
169
161
|
- lib/openapi_first/validators/request_parameters.rb
|
|
170
162
|
- lib/openapi_first/validators/response_body.rb
|
|
@@ -193,7 +185,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
193
185
|
- !ruby/object:Gem::Version
|
|
194
186
|
version: '0'
|
|
195
187
|
requirements: []
|
|
196
|
-
rubygems_version: 4.0.
|
|
188
|
+
rubygems_version: 4.0.16
|
|
197
189
|
specification_version: 4
|
|
198
190
|
summary: OpenAPI based request validation, response validation, contract-testing and
|
|
199
191
|
coverage
|