mirror of
https://github.com/ditkrg/rswag.git
synced 2026-01-25 15:22:56 +00:00
Basic rubocops
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rswag/route_parser'
|
||||
require 'rails/generators'
|
||||
|
||||
module Rspec
|
||||
class SwaggerGenerator < ::Rails::Generators::NamedBase
|
||||
source_root File.expand_path('../templates', __FILE__)
|
||||
source_root File.expand_path('templates', __dir__)
|
||||
|
||||
def setup
|
||||
@routes = Rswag::RouteParser.new(controller_path).routes
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails/generators'
|
||||
|
||||
module Rswag
|
||||
module Specs
|
||||
|
||||
class InstallGenerator < Rails::Generators::Base
|
||||
source_root File.expand_path('../templates', __FILE__)
|
||||
source_root File.expand_path('templates', __dir__)
|
||||
|
||||
def add_swagger_helper
|
||||
template('swagger_helper.rb', 'spec/swagger_helper.rb')
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.configure do |config|
|
||||
@@ -25,7 +27,7 @@ RSpec.configure do |config|
|
||||
url: 'https://{defaultHost}',
|
||||
variables: {
|
||||
defaultHost: {
|
||||
default: 'www.example.com'
|
||||
default: 'www.example.com'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Rswag
|
||||
class RouteParser
|
||||
attr_reader :controller
|
||||
@@ -9,7 +11,7 @@ module Rswag
|
||||
def routes
|
||||
::Rails.application.routes.routes.select do |route|
|
||||
route.defaults[:controller] == controller
|
||||
end.reduce({}) do |tree, route|
|
||||
end.each_with_object({}) do |tree, route|
|
||||
path = path_from(route)
|
||||
verb = verb_from(route)
|
||||
tree[path] ||= { params: params_from(route), actions: {} }
|
||||
@@ -28,7 +30,7 @@ module Rswag
|
||||
|
||||
def verb_from(route)
|
||||
verb = route.verb
|
||||
if verb.kind_of? String
|
||||
if verb.is_a? String
|
||||
verb.downcase
|
||||
else
|
||||
verb.source.gsub(/[$^]/, '').downcase
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rspec/core'
|
||||
require 'rswag/specs/example_group_helpers'
|
||||
require 'rswag/specs/example_helpers'
|
||||
@@ -6,7 +8,6 @@ require 'rswag/specs/railtie' if defined?(Rails::Railtie)
|
||||
|
||||
module Rswag
|
||||
module Specs
|
||||
|
||||
# Extend RSpec with a swagger-based DSL
|
||||
::RSpec.configure do |c|
|
||||
c.add_setting :swagger_root
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
|
||||
module Rswag
|
||||
module Specs
|
||||
|
||||
class Configuration
|
||||
|
||||
def initialize(rspec_config)
|
||||
@rspec_config = rspec_config
|
||||
end
|
||||
@@ -14,6 +12,7 @@ module Rswag
|
||||
if @rspec_config.swagger_root.nil?
|
||||
raise ConfigurationError, 'No swagger_root provided. See swagger_helper.rb'
|
||||
end
|
||||
|
||||
@rspec_config.swagger_root
|
||||
end
|
||||
end
|
||||
@@ -23,6 +22,7 @@ module Rswag
|
||||
if @rspec_config.swagger_docs.nil? || @rspec_config.swagger_docs.empty?
|
||||
raise ConfigurationError, 'No swagger_docs defined. See swagger_helper.rb'
|
||||
end
|
||||
|
||||
@rspec_config.swagger_docs
|
||||
end
|
||||
end
|
||||
@@ -37,6 +37,7 @@ module Rswag
|
||||
@swagger_format ||= begin
|
||||
@rspec_config.swagger_format = :json if @rspec_config.swagger_format.nil? || @rspec_config.swagger_format.empty?
|
||||
raise ConfigurationError, "Unknown swagger_format '#{@rspec_config.swagger_format}'" unless [:json, :yaml].include?(@rspec_config.swagger_format)
|
||||
|
||||
@rspec_config.swagger_format
|
||||
end
|
||||
end
|
||||
@@ -44,6 +45,7 @@ module Rswag
|
||||
def get_swagger_doc(name)
|
||||
return swagger_docs.values.first if name.nil?
|
||||
raise ConfigurationError, "Unknown swagger_doc '#{name}'" unless swagger_docs[name]
|
||||
|
||||
swagger_docs[name]
|
||||
end
|
||||
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Rswag
|
||||
module Specs
|
||||
module ExampleGroupHelpers
|
||||
|
||||
def path(template, metadata={}, &block)
|
||||
def path(template, metadata = {}, &block)
|
||||
metadata[:path_item] = { template: template }
|
||||
describe(template, metadata, &block)
|
||||
end
|
||||
|
||||
[ :get, :post, :patch, :put, :delete, :head, :options, :trace ].each do |verb|
|
||||
[:get, :post, :patch, :put, :delete, :head, :options, :trace].each do |verb|
|
||||
define_method(verb) do |summary, &block|
|
||||
api_metadata = { operation: { verb: verb, summary: summary } }
|
||||
describe(verb, api_metadata, &block)
|
||||
end
|
||||
end
|
||||
|
||||
[ :operationId, :deprecated, :security ].each do |attr_name|
|
||||
[:operationId, :deprecated, :security].each do |attr_name|
|
||||
define_method(attr_name) do |value|
|
||||
metadata[:operation][attr_name] = value
|
||||
end
|
||||
@@ -23,13 +24,14 @@ module Rswag
|
||||
# NOTE: 'description' requires special treatment because ExampleGroup already
|
||||
# defines a method with that name. Provide an override that supports the existing
|
||||
# functionality while also setting the appropriate metadata if applicable
|
||||
def description(value=nil)
|
||||
def description(value = nil)
|
||||
return super() if value.nil?
|
||||
|
||||
metadata[:operation][:description] = value
|
||||
end
|
||||
|
||||
# These are array properties - note the splat operator
|
||||
[ :tags, :consumes, :produces, :schemes ].each do |attr_name|
|
||||
[:tags, :consumes, :produces, :schemes].each do |attr_name|
|
||||
define_method(attr_name) do |*value|
|
||||
metadata[:operation][attr_name] = value
|
||||
end
|
||||
@@ -125,13 +127,12 @@ module Rswag
|
||||
# end
|
||||
# end
|
||||
|
||||
|
||||
def parameter(attributes)
|
||||
if attributes[:in] && attributes[:in].to_sym == :path
|
||||
attributes[:required] = true
|
||||
end
|
||||
|
||||
if metadata.has_key?(:operation)
|
||||
if metadata.key?(:operation)
|
||||
metadata[:operation][:parameters] ||= []
|
||||
metadata[:operation][:parameters] << attributes
|
||||
else
|
||||
@@ -140,7 +141,7 @@ module Rswag
|
||||
end
|
||||
end
|
||||
|
||||
def response(code, description, metadata={}, &block)
|
||||
def response(code, description, metadata = {}, &block)
|
||||
metadata[:response] = { code: code, description: description }
|
||||
context(description, metadata, &block)
|
||||
end
|
||||
@@ -165,6 +166,7 @@ module Rswag
|
||||
# rspec-core ExampleGroup
|
||||
def examples(example = nil)
|
||||
return super() if example.nil?
|
||||
|
||||
metadata[:response][:examples] = example
|
||||
end
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ require 'json-schema'
|
||||
module Rswag
|
||||
module Specs
|
||||
class ExtendedSchema < JSON::Schema::Draft4
|
||||
|
||||
def initialize
|
||||
super
|
||||
@attributes['type'] = ExtendedTypeAttribute
|
||||
@@ -15,11 +14,11 @@ module Rswag
|
||||
end
|
||||
|
||||
class ExtendedTypeAttribute < JSON::Schema::TypeV4Attribute
|
||||
|
||||
def self.validate(current_schema, data, fragments, processor, validator, options={})
|
||||
def self.validate(current_schema, data, fragments, processor, validator, options = {})
|
||||
## OA3
|
||||
# return if data.nil? && (current_schema.schema['nullable'] == true || current_schema.schema['x-nullable'] == true)
|
||||
return if data.nil? && current_schema.schema['x-nullable'] == true
|
||||
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,9 +3,8 @@
|
||||
module Rswag
|
||||
module Specs
|
||||
class Railtie < ::Rails::Railtie
|
||||
|
||||
rake_tasks do
|
||||
load File.expand_path('../../../tasks/rswag-specs_tasks.rake', __FILE__)
|
||||
load File.expand_path('../../tasks/rswag-specs_tasks.rake', __dir__)
|
||||
end
|
||||
|
||||
generators do
|
||||
|
||||
@@ -8,7 +8,6 @@ require 'byebug'
|
||||
module Rswag
|
||||
module Specs
|
||||
class RequestFactory
|
||||
|
||||
def initialize(config = ::Rswag::Specs.config)
|
||||
@config = config
|
||||
end
|
||||
@@ -54,7 +53,7 @@ module Rswag
|
||||
if doc_version(swagger_doc).start_with?('2')
|
||||
(swagger_doc[:securityDefinitions] || {}).slice(*scheme_names).values
|
||||
else # Openapi3
|
||||
if swagger_doc.has_key?(:securityDefinitions)
|
||||
if swagger_doc.key?(:securityDefinitions)
|
||||
ActiveSupport::Deprecation.warn('Rswag::Specs: WARNING: securityDefinitions is replaced in OpenAPI3! Rename to components/securitySchemes (in swagger_helper.rb)')
|
||||
swagger_doc[:components] ||= { securitySchemes: swagger_doc[:securityDefinitions] }
|
||||
swagger_doc.delete(:securityDefinitions)
|
||||
@@ -67,8 +66,8 @@ module Rswag
|
||||
def resolve_parameter(ref, swagger_doc)
|
||||
key = key_version(ref, swagger_doc)
|
||||
definitions = definition_version(swagger_doc)
|
||||
|
||||
raise "Referenced parameter '#{ref}' must be defined" unless definitions && definitions[key]
|
||||
|
||||
definitions[key]
|
||||
end
|
||||
|
||||
@@ -89,7 +88,7 @@ module Rswag
|
||||
if doc_version(swagger_doc).start_with?('2')
|
||||
swagger_doc[:parameters]
|
||||
else # Openapi3
|
||||
if swagger_doc.has_key?(:parameters)
|
||||
if swagger_doc.key?(:parameters)
|
||||
ActiveSupport::Deprecation.warn('Rswag::Specs: WARNING: parameters is replaced in OpenAPI3! Rename to components/parameters (in swagger_helper.rb)')
|
||||
swagger_doc[:parameters]
|
||||
else
|
||||
@@ -106,21 +105,21 @@ module Rswag
|
||||
def add_path(request, metadata, swagger_doc, parameters, example)
|
||||
template = (swagger_doc[:basePath] || '') + metadata[:path_item][:template]
|
||||
|
||||
request[:path] = template.tap do |template|
|
||||
request[:path] = template.tap do |path_template|
|
||||
parameters.select { |p| p[:in] == :path }.each do |p|
|
||||
template.gsub!("{#{p[:name]}}", example.send(p[:name]).to_s)
|
||||
path_template.gsub!("{#{p[:name]}}", example.send(p[:name]).to_s)
|
||||
end
|
||||
|
||||
parameters.select { |p| p[:in] == :query }.each_with_index do |p, i|
|
||||
template.concat(i == 0 ? '?' : '&')
|
||||
template.concat(build_query_string_part(p, example.send(p[:name])))
|
||||
path_template.concat(i.zero? ? '?' : '&')
|
||||
path_template.concat(build_query_string_part(p, example.send(p[:name])))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def build_query_string_part(param, value)
|
||||
name = param[:name]
|
||||
return "#{name}=#{value.to_s}" unless param[:type].to_sym == :array
|
||||
return "#{name}=#{value}" unless param[:type].to_sym == :array
|
||||
|
||||
case param[:collectionFormat]
|
||||
when :ssv
|
||||
@@ -139,43 +138,43 @@ module Rswag
|
||||
def add_headers(request, metadata, swagger_doc, parameters, example)
|
||||
tuples = parameters
|
||||
.select { |p| p[:in] == :header }
|
||||
.map { |p| [ p[:name], example.send(p[:name]).to_s ] }
|
||||
.map { |p| [p[:name], example.send(p[:name]).to_s] }
|
||||
|
||||
# Accept header
|
||||
produces = metadata[:operation][:produces] || swagger_doc[:produces]
|
||||
if produces
|
||||
accept = example.respond_to?(:Accept) ? example.send(:Accept) : produces.first
|
||||
tuples << [ 'Accept', accept ]
|
||||
tuples << ['Accept', accept]
|
||||
end
|
||||
|
||||
# Content-Type header
|
||||
consumes = metadata[:operation][:consumes] || swagger_doc[:consumes]
|
||||
if consumes
|
||||
content_type = example.respond_to?(:'Content-Type') ? example.send(:'Content-Type') : consumes.first
|
||||
tuples << [ 'Content-Type', content_type ]
|
||||
tuples << ['Content-Type', content_type]
|
||||
end
|
||||
|
||||
# Rails test infrastructure requires rackified headers
|
||||
rackified_tuples = tuples.map do |pair|
|
||||
[
|
||||
case pair[0]
|
||||
when 'Accept' then 'HTTP_ACCEPT'
|
||||
when 'Content-Type' then 'CONTENT_TYPE'
|
||||
when 'Authorization' then 'HTTP_AUTHORIZATION'
|
||||
else pair[0]
|
||||
when 'Accept' then 'HTTP_ACCEPT'
|
||||
when 'Content-Type' then 'CONTENT_TYPE'
|
||||
when 'Authorization' then 'HTTP_AUTHORIZATION'
|
||||
else pair[0]
|
||||
end,
|
||||
pair[1]
|
||||
]
|
||||
end
|
||||
|
||||
request[:headers] = Hash[ rackified_tuples ]
|
||||
request[:headers] = Hash[rackified_tuples]
|
||||
end
|
||||
|
||||
def add_payload(request, parameters, example)
|
||||
content_type = request[:headers]['CONTENT_TYPE']
|
||||
return if content_type.nil?
|
||||
|
||||
if [ 'application/x-www-form-urlencoded', 'multipart/form-data' ].include?(content_type)
|
||||
if ['application/x-www-form-urlencoded', 'multipart/form-data'].include?(content_type)
|
||||
request[:payload] = build_form_payload(parameters, example)
|
||||
else
|
||||
request[:payload] = build_json_payload(parameters, example)
|
||||
@@ -189,7 +188,7 @@ module Rswag
|
||||
# PROS: simple to implement, CONS: serialization/deserialization is bypassed in test
|
||||
tuples = parameters
|
||||
.select { |p| p[:in] == :formData }
|
||||
.map { |p| [ p[:name], example.send(p[:name]) ] }
|
||||
.map { |p| [p[:name], example.send(p[:name])] }
|
||||
Hash[tuples]
|
||||
end
|
||||
|
||||
|
||||
@@ -69,12 +69,12 @@ module Rswag
|
||||
if version.start_with?('2')
|
||||
swagger_doc.slice(:definitions)
|
||||
else # Openapi3
|
||||
if swagger_doc.has_key?(:definitions)
|
||||
if swagger_doc.key?(:definitions)
|
||||
ActiveSupport::Deprecation.warn('Rswag::Specs: WARNING: definitions is replaced in OpenAPI3! Rename to components/schemas (in swagger_helper.rb)')
|
||||
return swagger_doc.slice(:definitions)
|
||||
swagger_doc.slice(:definitions)
|
||||
else
|
||||
components = swagger_doc[:components] || {}
|
||||
return { components: { schemas: components[:schemas] } }
|
||||
{ components: { schemas: components[:schemas] } }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,7 +6,6 @@ require 'swagger_helper'
|
||||
module Rswag
|
||||
module Specs
|
||||
class SwaggerFormatter
|
||||
|
||||
# NOTE: rspec 2.x support
|
||||
if RSPEC_VERSION > 2
|
||||
::RSpec::Core::Formatters.register self, :example_group_finished, :stop
|
||||
@@ -30,11 +29,11 @@ module Rswag
|
||||
# !metadata[:document] won't work, since nil means we should generate
|
||||
# docs.
|
||||
return if metadata[:document] == false
|
||||
return unless metadata.has_key?(:response)
|
||||
return unless metadata.key?(:response)
|
||||
|
||||
swagger_doc = @config.get_swagger_doc(metadata[:swagger_doc])
|
||||
|
||||
if !doc_version(swagger_doc).start_with?('2')
|
||||
unless doc_version(swagger_doc).start_with?('2')
|
||||
upgrade_request_type!(metadata)
|
||||
upgrade_servers!(swagger_doc)
|
||||
upgrade_oauth!(swagger_doc)
|
||||
@@ -43,7 +42,7 @@ module Rswag
|
||||
swagger_doc.deep_merge!(metadata_to_swagger(metadata))
|
||||
end
|
||||
|
||||
def stop(_notification=nil)
|
||||
def stop(_notification = nil)
|
||||
@config.swagger_docs.each do |url_path, doc|
|
||||
## OA3
|
||||
# # remove 2.0 parameters
|
||||
@@ -68,7 +67,7 @@ module Rswag
|
||||
|
||||
file_path = File.join(@config.swagger_root, url_path)
|
||||
dirname = File.dirname(file_path)
|
||||
FileUtils.mkdir_p dirname unless File.exists?(dirname)
|
||||
FileUtils.mkdir_p dirname unless File.exist?(dirname)
|
||||
|
||||
File.open(file_path, 'w') do |file|
|
||||
file.write(pretty_generate(doc))
|
||||
@@ -96,7 +95,7 @@ module Rswag
|
||||
|
||||
def metadata_to_swagger(metadata)
|
||||
response_code = metadata[:response][:code]
|
||||
response = metadata[:response].reject { |k,v| k == :code }
|
||||
response = metadata[:response].reject { |k, _v| k == :code }
|
||||
## OA3
|
||||
# content_type = metadata[:response][:content].present? ? metadata[:response][:content].keys.first : 'application/json'
|
||||
# # need to merge in to response
|
||||
@@ -111,12 +110,12 @@ module Rswag
|
||||
|
||||
verb = metadata[:operation][:verb]
|
||||
operation = metadata[:operation]
|
||||
.reject { |k,v| k == :verb }
|
||||
.reject { |k, _v| k == :verb }
|
||||
.merge(responses: { response_code => response })
|
||||
|
||||
path_template = metadata[:path_item][:template]
|
||||
path_item = metadata[:path_item]
|
||||
.reject { |k,v| k == :template }
|
||||
.reject { |k, _v| k == :template }
|
||||
.merge(verb => operation)
|
||||
|
||||
{ paths: { path_template => path_item } }
|
||||
@@ -141,31 +140,31 @@ module Rswag
|
||||
end
|
||||
|
||||
def upgrade_servers!(swagger_doc)
|
||||
if swagger_doc[:servers].nil? && swagger_doc.has_key?(:schemes)
|
||||
ActiveSupport::Deprecation.warn('Rswag::Specs: WARNING: schemes, host, and basePath are replaced in OpenAPI3! Rename to array of servers[{url}] (in swagger_helper.rb)')
|
||||
return unless swagger_doc[:servers].nil? && swagger_doc.key?(:schemes)
|
||||
|
||||
swagger_doc[:servers] = { urls: [] }
|
||||
swagger_doc[:schemes].each do |scheme|
|
||||
swagger_doc[:servers][:urls] << scheme + '://' + swagger_doc[:host] + swagger_doc[:basePath]
|
||||
end
|
||||
ActiveSupport::Deprecation.warn('Rswag::Specs: WARNING: schemes, host, and basePath are replaced in OpenAPI3! Rename to array of servers[{url}] (in swagger_helper.rb)')
|
||||
|
||||
swagger_doc.delete(:schemes)
|
||||
swagger_doc.delete(:host)
|
||||
swagger_doc.delete(:basePath)
|
||||
swagger_doc[:servers] = { urls: [] }
|
||||
swagger_doc[:schemes].each do |scheme|
|
||||
swagger_doc[:servers][:urls] << scheme + '://' + swagger_doc[:host] + swagger_doc[:basePath]
|
||||
end
|
||||
|
||||
swagger_doc.delete(:schemes)
|
||||
swagger_doc.delete(:host)
|
||||
swagger_doc.delete(:basePath)
|
||||
end
|
||||
|
||||
def upgrade_oauth!(swagger_doc)
|
||||
# find flow in securitySchemes (securityDefinitions will have been re-written)
|
||||
schemes = swagger_doc.dig(:components, :securitySchemes)
|
||||
if schemes && schemes.any?{ |_k, v| v.has_key?(:flow) }
|
||||
schemes.each do |name, v|
|
||||
if v.has_key?(:flow)
|
||||
ActiveSupport::Deprecation.warn("Rswag::Specs: WARNING: securityDefinitions flow is replaced in OpenAPI3! Rename to components/securitySchemes/#{name}/flows[] (in swagger_helper.rb)")
|
||||
flow = swagger_doc[:components][:securitySchemes][name].delete(:flow)
|
||||
swagger_doc[:components][:securitySchemes][name].merge!(flows: [flow])
|
||||
end
|
||||
end
|
||||
return unless schemes&.any? { |_k, v| v.key?(:flow) }
|
||||
|
||||
schemes.each do |name, v|
|
||||
next unless v.key?(:flow)
|
||||
|
||||
ActiveSupport::Deprecation.warn("Rswag::Specs: WARNING: securityDefinitions flow is replaced in OpenAPI3! Rename to components/securitySchemes/#{name}/flows[] (in swagger_helper.rb)")
|
||||
flow = swagger_doc[:components][:securitySchemes][name].delete(:flow)
|
||||
swagger_doc[:components][:securitySchemes][name].merge!(flows: [flow])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rspec/core/rake_task'
|
||||
|
||||
namespace :rswag do
|
||||
namespace :specs do
|
||||
|
||||
desc 'Generate Swagger JSON files from integration specs'
|
||||
RSpec::Core::RakeTask.new('swaggerize') do |t|
|
||||
t.pattern = ENV.fetch(
|
||||
@@ -12,12 +13,12 @@ namespace :rswag do
|
||||
|
||||
# NOTE: rspec 2.x support
|
||||
if Rswag::Specs::RSPEC_VERSION > 2 && Rswag::Specs.config.swagger_dry_run
|
||||
t.rspec_opts = [ '--format Rswag::Specs::SwaggerFormatter', '--dry-run', '--order defined' ]
|
||||
t.rspec_opts = ['--format Rswag::Specs::SwaggerFormatter', '--dry-run', '--order defined']
|
||||
else
|
||||
t.rspec_opts = [ '--format Rswag::Specs::SwaggerFormatter', '--order defined' ]
|
||||
t.rspec_opts = ['--format Rswag::Specs::SwaggerFormatter', '--order defined']
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
task :rswag => ['rswag:specs:swaggerize']
|
||||
task rswag: ['rswag:specs:swaggerize']
|
||||
|
||||
Reference in New Issue
Block a user