Skip to content

Commit

Permalink
Support non-string enum validators ...
Browse files Browse the repository at this point in the history
... both for custom validators and self-describing properties.

Before:

```ruby
expect(pm_schema).to have_field(:num_tails, 'number', {:description => "Number of tails", :enum => [0, 1]})
# => expected param 'num_tails' to have type 'number' (got 'string')

expect_param_def("get", "/users/by_department_number", "department", "type", "integer")
# =>        expected: "integer"
# =>            got: "string"
```

After:

tests pass.

This PR also adds support for subclassing of validators.
  • Loading branch information
jaynetics committed Oct 21, 2024
1 parent eeef4de commit 9f5d68c
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 5 deletions.
4 changes: 2 additions & 2 deletions lib/apipie/generator/swagger/param_description/type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ def array_items_type(items_type)

def for_enum_type
{
type: 'string',
enum: @param_description.validator.values
type: validator.expected_type,
enum: validator.values
}
end

Expand Down
5 changes: 4 additions & 1 deletion lib/apipie/validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,11 @@ def inspect
end

def self.inherited(subclass)
BaseValidator.validators.unshift(subclass)
end

def self.validators
@validators ||= []
@validators.insert 0, subclass
end

# find the right validator for given options
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ def self.describe_own_properties
Apipie::prop(:weight, 'number', {:description => "Weight in pounds" }),
Apipie::prop(:height, 'number', {:description => "Height in inches" }),
Apipie::prop(:num_legs, 'number', {:description => "Number of legs", :required => false }),
Apipie::prop(:num_tails, 'number', {:description => "Number of tails", :values => [0, 1] }),
Apipie::additional_properties(false)
])
]
Expand Down
6 changes: 6 additions & 0 deletions spec/dummy/app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,12 @@ def get_by_department
render :plain => 'nothing to see here'
end

api :GET, '/users/by_department_number', 'show users from a specific department by department number'
param :department, [1, 2, 3], default_value: 1, type: 'integer'
def get_by_department_number
render :plain => 'nothing to see here'
end

api :GET, '/users/in_departments', 'show users from specific departments'
param :departments, Array, in: %w[finance operations sales marketing HR], default_value: ['sales']
def get_in_departments
Expand Down
13 changes: 13 additions & 0 deletions spec/lib/apipie/validator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,17 @@
expect(validator.description).to eq('Must be one of: <code>first</code>, <code>second &amp; third</code>.')
end
end

describe 'subclassing BaseValidator' do
it 'adds the new validator to the list of validators' do
subclass = Class.new(Apipie::Validator::BaseValidator)
expect(Apipie::Validator::BaseValidator.validators).to include(subclass)
end

it 'adds the new validator to the list of validators recursively' do
subclass = Class.new(Apipie::Validator::BaseValidator)
subsubclass = Class.new(subclass)
expect(Apipie::Validator::BaseValidator.validators).to include(subsubclass)
end
end
end
8 changes: 7 additions & 1 deletion spec/lib/swagger/rake_swagger_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ def expect_response_params_def(http_method, path, response_code, param_name, fie
expect_param_def("get", "/users/by_department", "department", "enum",
%w[finance operations sales marketing HR])

expect_param_def("get", "/users/by_department_number", "department", "type", "integer")
expect_param_def("get", "/users/by_department_number", "department", "enum", [1, 2, 3])

expect_tags_def("get", "/twitter_example/{id}/followers", %w[twitter_example following index search])
expect_response_params_def("get", "/pets/{id}/as_properties", 200, "pet_name", "example", "mypet")
end
Expand Down Expand Up @@ -135,12 +138,15 @@ def expect_response_params_def(http_method, path, response_code, param_name, fie
expect_param_def("get", "/users/by_department", "department", "enum",
%w[finance operations sales marketing HR])

expect_param_def("get", "/users/by_department_number", "department", "type", "integer")
expect_param_def("get", "/users/by_department_number", "department", "enum", [1, 2, 3])

expect_param_def("get", "/users/in_departments", "departments", "in", "query")
expect_array_param_def("get", "/users/in_departments", "departments",
%w[finance operations sales marketing HR])

expect_tags_def("get", "/twitter_example/{id}/followers", %w[twitter_example following index search])

expect_response_params_def("get", "/pets/{id}/as_properties", 200, "pet_name", "example", "mypet")
end

it "generates a valid swagger file" do
Expand Down
3 changes: 2 additions & 1 deletion spec/lib/swagger/swagger_dsl_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ def have_field?(field, expected_name, breadcrumb)

expect(returns_obj).to match_field_structure([:pet_name,
:animal_type,
{:pet_measurements => [:weight, :height, :num_legs]}
{:pet_measurements => [:weight, :height, :num_legs, :num_tails]}
])
end

Expand All @@ -587,6 +587,7 @@ def have_field?(field, expected_name, breadcrumb)
expect(pm_schema).to have_field(:weight, 'number', {:description => "Weight in pounds"})
expect(pm_schema).to have_field(:height, 'number', {:description => "Height in inches"})
expect(pm_schema).to have_field(:num_legs, 'number', {:description => "Number of legs", :required => false})
expect(pm_schema).to have_field(:num_tails, 'number', {:description => "Number of tails", :enum => [0, 1]})
end
end

Expand Down
14 changes: 14 additions & 0 deletions spec/support/custom_typed_enum_validator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class CustomTypedEnumValidator < Apipie::Validator::EnumValidator
attr_accessor :expected_type

def initialize(param_description, enum, type)
super(param_description, enum)
self.expected_type = type
end

def self.build(param_description, argument, options, block)
if argument.is_a?(Array) && options.to_h[:type]
new(param_description, argument, options[:type])
end
end
end

0 comments on commit 9f5d68c

Please sign in to comment.