Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move Swagger types and warnings under /generator namespace #803

Merged
merged 4 commits into from
Jan 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions lib/apipie-rails.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,9 @@
require 'apipie/extractor'
require "apipie/version"
require "apipie/swagger_generator"
require "apipie/generator/generator"
require "apipie/generator/swagger/swagger"
require "apipie/generator/swagger/warning"
require "apipie/generator/swagger/warning_writer"
require "apipie/generator/swagger/type"
require "apipie/generator/swagger/type_extractor"
2 changes: 2 additions & 0 deletions lib/apipie/generator/generator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module Apipie::Generator
end
PanosCodes marked this conversation as resolved.
Show resolved Hide resolved
2 changes: 2 additions & 0 deletions lib/apipie/generator/swagger/swagger.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module Apipie::Generator::Swagger
end
16 changes: 16 additions & 0 deletions lib/apipie/generator/swagger/type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class Apipie::Generator::Swagger::Type
attr_reader :str_format

def initialize(type, str_format = nil)
@type = type
@str_format = str_format
end

def to_s
@type
end

def ==(other)
other.to_s == self.to_s
end
end
70 changes: 70 additions & 0 deletions lib/apipie/generator/swagger/type_extractor.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
class Apipie::Generator::Swagger::TypeExtractor
TYPES = {
numeric: 'number',
hash: 'object',
array: 'array',
enum: 'enum',

# see https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types
integer: Apipie::Generator::Swagger::Type.new('integer', 'int32'),
long: Apipie::Generator::Swagger::Type.new('integer', 'int64'),
number: Apipie::Generator::Swagger::Type.new('number'),
float: Apipie::Generator::Swagger::Type.new('number', 'float'),
double: Apipie::Generator::Swagger::Type.new('number', 'double'),
string: Apipie::Generator::Swagger::Type.new('string'),
byte: Apipie::Generator::Swagger::Type.new('string', 'byte'),
binary: Apipie::Generator::Swagger::Type.new('string', 'binary'),
boolean: Apipie::Generator::Swagger::Type.new('boolean'),
date: Apipie::Generator::Swagger::Type.new('string', 'date'),
dateTime: Apipie::Generator::Swagger::Type.new('string', 'date-time'),
password: Apipie::Generator::Swagger::Type.new('string', 'password')
}

# @param [Apipie::Validator::BaseValidator, ResponseDescriptionAdapter::PropDesc::Validator, nil] validator
def initialize(validator)
@validator = validator
end

# @param [Hash<Symbol, Apipie::Generator::Swagger::Warning>] warnings
def extract_with_warnings(warnings = {})
if boolean? && warnings[:boolean].present?
Apipie::Generator::Swagger::WarningWriter.instance.warn(warnings[:boolean])
end

extract
end

private

def extract
expected_type =
if string?
:string
elsif boolean?
:boolean
elsif enum?
:enum
else
@validator.expected_type.to_sym
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now that I am reading this properly.. maybe this was the original code... but I wonder why the if/elsif/elsif/else when @validator.expected_type.to_sym probably already return the right value for string, boolean, and enum ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What was confusing to me as well.
There are a couple of issues we handle here

ParamDescription's validator can be

  • nil
  • Apipie::Validator::BaseValidator
  • ResponseDescriptionAdapter::PropDesc::Validator

Updated Yard comment dc88775


In case of nil we want to default to string


Apipie::Validator::EnumValidator#expected_type returns string


ResponseDescriptionAdapter::PropDesc::Validator#expected_type can we whatever by if we give it values that are [true, false] we need to result into boolean.

end

TYPES[expected_type] || @validator.expected_type
end

def string?
@validator.blank?
end

def enum?
@validator.is_a?(Apipie::Validator::EnumValidator) ||
(@validator.respond_to?(:is_enum?) && @validator.is_enum?)
end

def boolean?
@_boolean ||= enum? && boolean_values?
end

def boolean_values?
@validator.values.to_set == Set.new([true, false])
end
end
77 changes: 77 additions & 0 deletions lib/apipie/generator/swagger/warning.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
class Apipie::Generator::Swagger::Warning
MISSING_METHOD_SUMMARY_CODE = 100
ADDED_MISSING_SLASH_CODE = 101
NO_RETURN_CODES_SPECIFIED_CODE = 102
HASH_WITHOUT_INTERNAL_TYPESPEC_CODE = 103
OPTIONAL_PARAM_IN_PATH_CODE = 104
OPTIONAL_WITHOUT_DEFAULT_VALUE_CODE = 105
PARAM_IGNORED_IN_FORM_DATA_CODE = 106
PATH_PARAM_NOT_DESCRIBED_CODE = 107
INFERRING_BOOLEAN_CODE = 108

CODES = {
missing_method_summary: MISSING_METHOD_SUMMARY_CODE,
added_missing_slash: ADDED_MISSING_SLASH_CODE,
no_return_codes_specified: NO_RETURN_CODES_SPECIFIED_CODE,
hash_without_internal_typespec: HASH_WITHOUT_INTERNAL_TYPESPEC_CODE,
optional_param_in_path: OPTIONAL_PARAM_IN_PATH_CODE,
optional_without_default_value: OPTIONAL_WITHOUT_DEFAULT_VALUE_CODE,
param_ignored_in_form_data: PARAM_IGNORED_IN_FORM_DATA_CODE,
path_param_not_described_code: PATH_PARAM_NOT_DESCRIBED_CODE,
inferring_boolean: INFERRING_BOOLEAN_CODE
}

MESSAGES = {
MISSING_METHOD_SUMMARY_CODE => "Missing short description for method",
ADDED_MISSING_SLASH_CODE => "Added missing / at beginning of path: %{path}",
HASH_WITHOUT_INTERNAL_TYPESPEC_CODE => "The parameter :%{parameter} is a generic Hash without an internal type specification",
NO_RETURN_CODES_SPECIFIED_CODE => "No return codes ('errors') specified",
OPTIONAL_PARAM_IN_PATH_CODE => "The parameter :%{parameter} is 'in-path'. Ignoring 'not required' in DSL",
OPTIONAL_WITHOUT_DEFAULT_VALUE_CODE => "The parameter :%{parameter} is optional but default value is not specified (use :default_value => ...)",
PARAM_IGNORED_IN_FORM_DATA_CODE => "Ignoring param :%{parameter} -- cannot include Hash without fields in a formData specification",
PATH_PARAM_NOT_DESCRIBED_CODE => "The parameter :%{name} appears in the path %{path} but is not described",
INFERRING_BOOLEAN_CODE => "The parameter [%{parameter}] is Enum with [true, false] values. Inferring 'boolean'"
}

attr_reader :code

def initialize(code, info_message, method_id)
@code = code
@info_message = info_message
@method_id = method_id
end

def id
"#{@method_id}#{@code}#{@info_message}"
end

def warning_message
"WARNING (#{@code}): [#{@method_id}] -- #{@info_message}"
end

def warn
Warning.warn(warning_message)
end

def warn_through_writer
Apipie::Generator::Swagger::WarningWriter.instance.warn(self)
end

# @param [Integer] code
# @param [Hash] message_attributes
#
# @return [Apipie::Generator::Swagger::Warning]
def self.for_code(code, method_id, message_attributes = {})
if !CODES.values.include?(code)
raise ArgumentError, 'Unknown warning code'
end

info_message = if message_attributes.present?
self::MESSAGES[code] % message_attributes
else
self::MESSAGES[code]
end

Apipie::Generator::Swagger::Warning.new(code, info_message, method_id)
end
end
48 changes: 48 additions & 0 deletions lib/apipie/generator/swagger/warning_writer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
class Apipie::Generator::Swagger::WarningWriter
include Singleton

def initialize
@issued_warnings = []
end

# @param [Apipie::Generator::Swagger::Warning] warning
def warn(warning)
return if muted_warning?(warning)

warning.warn

@issued_warnings << warning.id
end

def issued_warnings?
@issued_warnings.count > 0
end

private

# @param [Apipie::Generator::Swagger::Warning] warning
#
# @return [TrueClass, FalseClass]
def muted_warning?(warning)
@issued_warnings.include?(warning.id) ||
suppressed_warning?(warning.code) ||
suppress_warnings?
end

# @param [Integer] warning_number
#
# @return [TrueClass, FalseClass]
def suppressed_warning?(warning_number)
suppress_warnings_config.is_a?(Array) && suppress_warnings_config.include?(warning_number)
end

# @return [TrueClass, FalseClass]
def suppress_warnings?
suppress_warnings_config == true
end

# @return [FalseClass, TrueClass, Array]
def suppress_warnings_config
Apipie.configuration.swagger_suppress_warnings
end
end
Loading