From 7cb156454433e7566f499d34af55e44e3d8b2ea5 Mon Sep 17 00:00:00 2001 From: White Rabbit <2667887+artyomb@users.noreply.github.com> Date: Tue, 5 Sep 2023 14:14:59 +0300 Subject: [PATCH 1/8] Allow range be Float --- lib/grape-swagger/doc_methods/parse_params.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/grape-swagger/doc_methods/parse_params.rb b/lib/grape-swagger/doc_methods/parse_params.rb index 3e12889d..0e1ed223 100644 --- a/lib/grape-swagger/doc_methods/parse_params.rb +++ b/lib/grape-swagger/doc_methods/parse_params.rb @@ -193,7 +193,7 @@ def parse_enum_or_range_values(values) when Proc parse_enum_or_range_values(values.call) if values.parameters.empty? when Range - parse_range_values(values) if values.first.is_a?(Integer) + parse_range_values(values) if values.first.is_a?(Integer) || values.first.is_a?(Float) when Array { enum: values } else From 960e37a01539fb997c2c735212c74e54f5b34cca Mon Sep 17 00:00:00 2001 From: Andrey Subbota Date: Sun, 8 Nov 2026 14:03:10 +0100 Subject: [PATCH 2/8] Cover Float ranges in specs and changelog The Float range support documents minimum and maximum, which an existing spec still asserted as absent. Update it, add a unit test for the Float case and record the change. --- CHANGELOG.md | 1 + spec/lib/parse_params_spec.rb | 7 +++++++ spec/swagger_v2/param_values_spec.rb | 6 ++++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ce50eda..59142da2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ #### Fixes +* [#905](https://github.com/ruby-grape/grape-swagger/pull/905): Allow Float ranges in `values` to set `minimum` and `maximum` - [@artyomb](https://github.com/artyomb). * [#1016](https://github.com/ruby-grape/grape-swagger/pull/1016): Hide the nested parameters of a Hash parameter marked `documentation: { hidden: true }`, and pass the resolved `token_owner` to parameter-level `hidden:` procs like route-level ones (raising `TokenOwnerNotFound` if the configured method is missing) - [@numbata](https://github.com/numbata). * [#1013](https://github.com/ruby-grape/grape-swagger/pull/1013): Fix array `default` values being placed inside `items` instead of on the array parameter or property, and emit an empty array `default` - [@numbata](https://github.com/numbata). * [#1012](https://github.com/ruby-grape/grape-swagger/pull/1012): Keep the Danger PR check running in CI by pinning `git` below 6 - [@numbata](https://github.com/numbata). diff --git a/spec/lib/parse_params_spec.rb b/spec/lib/parse_params_spec.rb index 51e82f71..8f209a2d 100644 --- a/spec/lib/parse_params_spec.rb +++ b/spec/lib/parse_params_spec.rb @@ -37,6 +37,13 @@ end end + describe 'first Float' do + specify do + parsed_range = subject.send(:parse_enum_or_range_values, -5.0..5.0) + expect(parsed_range).to eql(minimum: -5.0, maximum: 5.0) + end + end + describe 'first String' do specify do parsed_range = subject.send(:parse_enum_or_range_values, 'a'..'z') diff --git a/spec/swagger_v2/param_values_spec.rb b/spec/swagger_v2/param_values_spec.rb index 0220a9e7..ee44fa26 100644 --- a/spec/swagger_v2/param_values_spec.rb +++ b/spec/swagger_v2/param_values_spec.rb @@ -167,13 +167,15 @@ def first_parameter_info(request) context 'Range values' do subject(:range_float) { first_parameter_info('range_float') } - it 'has float range values as string' do + it 'has float range values as minimum and maximum' do expect(range_float).to eq [{ 'in' => 'formData', 'name' => 'float', 'type' => 'number', 'required' => true, - 'format' => 'float' + 'format' => 'float', + 'minimum' => -5.0, + 'maximum' => 5.0 }] end end From 2b666d4ed2e7173ecf3b8ce875d6279e9f9b07f7 Mon Sep 17 00:00:00 2001 From: Andrey Subbota Date: Sun, 8 Nov 2026 14:03:15 +0100 Subject: [PATCH 3/8] Match changelog entry style --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59142da2..5b313a0f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ #### Fixes -* [#905](https://github.com/ruby-grape/grape-swagger/pull/905): Allow Float ranges in `values` to set `minimum` and `maximum` - [@artyomb](https://github.com/artyomb). +* [#905](https://github.com/ruby-grape/grape-swagger/pull/905): Allow Float ranges in `values` to set `minimum` and `maximum` - [@artyomb](https://github.com/artyomb) * [#1016](https://github.com/ruby-grape/grape-swagger/pull/1016): Hide the nested parameters of a Hash parameter marked `documentation: { hidden: true }`, and pass the resolved `token_owner` to parameter-level `hidden:` procs like route-level ones (raising `TokenOwnerNotFound` if the configured method is missing) - [@numbata](https://github.com/numbata). * [#1013](https://github.com/ruby-grape/grape-swagger/pull/1013): Fix array `default` values being placed inside `items` instead of on the array parameter or property, and emit an empty array `default` - [@numbata](https://github.com/numbata). * [#1012](https://github.com/ruby-grape/grape-swagger/pull/1012): Keep the Danger PR check running in CI by pinning `git` below 6 - [@numbata](https://github.com/numbata). From 08f4890d578361b70b735b908d02dd298c58018f Mon Sep 17 00:00:00 2001 From: Andrey Subbota Date: Sun, 8 Nov 2026 14:09:22 +0100 Subject: [PATCH 4/8] End the changelog entry with a period --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b313a0f..59142da2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ #### Fixes -* [#905](https://github.com/ruby-grape/grape-swagger/pull/905): Allow Float ranges in `values` to set `minimum` and `maximum` - [@artyomb](https://github.com/artyomb) +* [#905](https://github.com/ruby-grape/grape-swagger/pull/905): Allow Float ranges in `values` to set `minimum` and `maximum` - [@artyomb](https://github.com/artyomb). * [#1016](https://github.com/ruby-grape/grape-swagger/pull/1016): Hide the nested parameters of a Hash parameter marked `documentation: { hidden: true }`, and pass the resolved `token_owner` to parameter-level `hidden:` procs like route-level ones (raising `TokenOwnerNotFound` if the configured method is missing) - [@numbata](https://github.com/numbata). * [#1013](https://github.com/ruby-grape/grape-swagger/pull/1013): Fix array `default` values being placed inside `items` instead of on the array parameter or property, and emit an empty array `default` - [@numbata](https://github.com/numbata). * [#1012](https://github.com/ruby-grape/grape-swagger/pull/1012): Keep the Danger PR check running in CI by pinning `git` below 6 - [@numbata](https://github.com/numbata). From 2e645b4fc8e464c2a972a75e69a7b037bedbf91b Mon Sep 17 00:00:00 2001 From: Andrey Subbota Date: Tue, 10 Nov 2026 15:38:35 +0100 Subject: [PATCH 5/8] Skip bounds that cannot be rendered as JSON numbers A Float range with an infinite bound, such as 1.0..Float::INFINITY, put Infinity into the parameter and made /swagger_doc fail to serialize. Only finite numeric bounds are emitted now. Beginless ranges no longer raise, and BigDecimal ranges, which map to a Swagger double, are documented as floats. --- CHANGELOG.md | 2 +- lib/grape-swagger/doc_methods/parse_params.rb | 12 +++++-- spec/lib/parse_params_spec.rb | 35 +++++++++++++++++++ spec/swagger_v2/param_values_spec.rb | 25 +++++++++++++ 4 files changed, 71 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59142da2..0bab3faf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ #### Fixes -* [#905](https://github.com/ruby-grape/grape-swagger/pull/905): Allow Float ranges in `values` to set `minimum` and `maximum` - [@artyomb](https://github.com/artyomb). +* [#905](https://github.com/ruby-grape/grape-swagger/pull/905): Allow Float, BigDecimal and beginless ranges in `values` to set `minimum` and `maximum`, and skip infinite bounds that cannot be serialized to JSON - [@artyomb](https://github.com/artyomb). * [#1016](https://github.com/ruby-grape/grape-swagger/pull/1016): Hide the nested parameters of a Hash parameter marked `documentation: { hidden: true }`, and pass the resolved `token_owner` to parameter-level `hidden:` procs like route-level ones (raising `TokenOwnerNotFound` if the configured method is missing) - [@numbata](https://github.com/numbata). * [#1013](https://github.com/ruby-grape/grape-swagger/pull/1013): Fix array `default` values being placed inside `items` instead of on the array parameter or property, and emit an empty array `default` - [@numbata](https://github.com/numbata). * [#1012](https://github.com/ruby-grape/grape-swagger/pull/1012): Keep the Danger PR check running in CI by pinning `git` below 6 - [@numbata](https://github.com/numbata). diff --git a/lib/grape-swagger/doc_methods/parse_params.rb b/lib/grape-swagger/doc_methods/parse_params.rb index 0e1ed223..e2398f1e 100644 --- a/lib/grape-swagger/doc_methods/parse_params.rb +++ b/lib/grape-swagger/doc_methods/parse_params.rb @@ -193,7 +193,7 @@ def parse_enum_or_range_values(values) when Proc parse_enum_or_range_values(values.call) if values.parameters.empty? when Range - parse_range_values(values) if values.first.is_a?(Integer) || values.first.is_a?(Float) + parse_range_values(values) if (values.begin || values.end).is_a?(Numeric) when Array { enum: values } else @@ -202,7 +202,15 @@ def parse_enum_or_range_values(values) end def parse_range_values(values) - { minimum: values.begin, maximum: values.end }.compact + { minimum: range_bound(values.begin), maximum: range_bound(values.end) }.compact + end + + # Only finite numbers are valid JSON; BigDecimal and Rational are emitted as Float. + def range_bound(bound) + return unless bound.is_a?(Numeric) + + bound = bound.to_f unless bound.is_a?(Integer) || bound.is_a?(Float) + bound if bound.finite? end end end diff --git a/spec/lib/parse_params_spec.rb b/spec/lib/parse_params_spec.rb index 8f209a2d..0e2c9fbe 100644 --- a/spec/lib/parse_params_spec.rb +++ b/spec/lib/parse_params_spec.rb @@ -44,6 +44,41 @@ end end + describe 'with an infinite end' do + specify do + expect(subject.send(:parse_enum_or_range_values, 1.0..Float::INFINITY)).to eql(minimum: 1.0) + expect(subject.send(:parse_enum_or_range_values, 1..Float::INFINITY)).to eql(minimum: 1) + end + end + + describe 'with an infinite begin' do + specify do + parsed_range = subject.send(:parse_enum_or_range_values, -Float::INFINITY..5.0) + expect(parsed_range).to eql(maximum: 5.0) + end + end + + describe 'beginless' do + specify do + expect(subject.send(:parse_enum_or_range_values, ..5.0)).to eql(maximum: 5.0) + expect(subject.send(:parse_enum_or_range_values, ..5)).to eql(maximum: 5) + end + end + + describe 'endless Float' do + specify do + parsed_range = subject.send(:parse_enum_or_range_values, 1.5..) + expect(parsed_range).to eql(minimum: 1.5) + end + end + + describe 'BigDecimal' do + specify do + parsed_range = subject.send(:parse_enum_or_range_values, BigDecimal('1')..BigDecimal('2')) + expect(parsed_range).to eql(minimum: 1.0, maximum: 2.0) + end + end + describe 'first String' do specify do parsed_range = subject.send(:parse_enum_or_range_values, 'a'..'z') diff --git a/spec/swagger_v2/param_values_spec.rb b/spec/swagger_v2/param_values_spec.rb index ee44fa26..683bff74 100644 --- a/spec/swagger_v2/param_values_spec.rb +++ b/spec/swagger_v2/param_values_spec.rb @@ -139,6 +139,16 @@ def app { message: 'hi' } end + desc 'range_infinite_float' do + consumes ['application/x-www-form-urlencoded'] + end + params do + requires :float, type: Float, values: 1.0..Float::INFINITY + end + post :range_infinite_float do + { message: 'hi' } + end + add_swagger_documentation end end @@ -179,4 +189,19 @@ def first_parameter_info(request) }] end end + + context 'Range values with an infinite end' do + subject(:range_infinite_float) { first_parameter_info('range_infinite_float') } + + it 'has only the finite bound as minimum' do + expect(range_infinite_float).to eq [{ + 'in' => 'formData', + 'name' => 'float', + 'type' => 'number', + 'required' => true, + 'format' => 'float', + 'minimum' => 1.0 + }] + end + end end From 94db668692f6f910c24830d498e1c30490adc893 Mon Sep 17 00:00:00 2001 From: Andrey Subbota Date: Tue, 10 Nov 2026 19:46:05 +0100 Subject: [PATCH 6/8] Document exclusive range ends and ignore non-real bounds An exclusive range such as 1.0...5.0 was documented with an inclusive maximum, so the excluded end looked valid. It now also sets exclusiveMaximum, which survives in body definitions. A range with a Complex bound no longer aborts Swagger generation. --- lib/grape-swagger/doc_methods/move_params.rb | 4 +- lib/grape-swagger/doc_methods/parse_params.rb | 12 ++++-- spec/lib/parse_params_spec.rb | 21 ++++++++++ spec/swagger_v2/param_values_spec.rb | 38 +++++++++++++++++++ 4 files changed, 70 insertions(+), 5 deletions(-) diff --git a/lib/grape-swagger/doc_methods/move_params.rb b/lib/grape-swagger/doc_methods/move_params.rb index fd1823e1..e92d647e 100644 --- a/lib/grape-swagger/doc_methods/move_params.rb +++ b/lib/grape-swagger/doc_methods/move_params.rb @@ -178,8 +178,8 @@ def parse_model(ref) end def property_keys - %i[type format description minimum maximum items enum default additional_properties additionalProperties - example minLength maxLength minProperties maxProperties] + %i[type format description minimum maximum exclusiveMaximum items enum default additional_properties + additionalProperties example minLength maxLength minProperties maxProperties] end def array_schema_keys diff --git a/lib/grape-swagger/doc_methods/parse_params.rb b/lib/grape-swagger/doc_methods/parse_params.rb index e2398f1e..e54dc585 100644 --- a/lib/grape-swagger/doc_methods/parse_params.rb +++ b/lib/grape-swagger/doc_methods/parse_params.rb @@ -193,7 +193,7 @@ def parse_enum_or_range_values(values) when Proc parse_enum_or_range_values(values.call) if values.parameters.empty? when Range - parse_range_values(values) if (values.begin || values.end).is_a?(Numeric) + parse_range_values(values) if real_number?(values.begin || values.end) when Array { enum: values } else @@ -202,12 +202,18 @@ def parse_enum_or_range_values(values) end def parse_range_values(values) - { minimum: range_bound(values.begin), maximum: range_bound(values.end) }.compact + range = { minimum: range_bound(values.begin), maximum: range_bound(values.end) }.compact + range[:exclusiveMaximum] = true if values.exclude_end? && range.key?(:maximum) + range + end + + def real_number?(bound) + bound.is_a?(Numeric) && bound.real? end # Only finite numbers are valid JSON; BigDecimal and Rational are emitted as Float. def range_bound(bound) - return unless bound.is_a?(Numeric) + return unless real_number?(bound) bound = bound.to_f unless bound.is_a?(Integer) || bound.is_a?(Float) bound if bound.finite? diff --git a/spec/lib/parse_params_spec.rb b/spec/lib/parse_params_spec.rb index 0e2c9fbe..4f399df7 100644 --- a/spec/lib/parse_params_spec.rb +++ b/spec/lib/parse_params_spec.rb @@ -79,6 +79,27 @@ end end + describe 'with an exclusive end' do + specify do + expect(subject.send(:parse_enum_or_range_values, 1...5)) + .to eql(minimum: 1, maximum: 5, exclusiveMaximum: true) + expect(subject.send(:parse_enum_or_range_values, 0.0...1.0)) + .to eql(minimum: 0.0, maximum: 1.0, exclusiveMaximum: true) + end + + it 'does not flag an endless or infinite end' do + expect(subject.send(:parse_enum_or_range_values, 1...)).to eql(minimum: 1) + expect(subject.send(:parse_enum_or_range_values, 1.0...Float::INFINITY)).to eql(minimum: 1.0) + end + end + + describe 'with Complex bounds' do + specify do + expect(subject.send(:parse_enum_or_range_values, ..Complex(1, 2))).to be_nil + expect(subject.send(:parse_enum_or_range_values, Complex(1, 2)..)).to be_nil + end + end + describe 'first String' do specify do parsed_range = subject.send(:parse_enum_or_range_values, 'a'..'z') diff --git a/spec/swagger_v2/param_values_spec.rb b/spec/swagger_v2/param_values_spec.rb index 683bff74..3c3607e2 100644 --- a/spec/swagger_v2/param_values_spec.rb +++ b/spec/swagger_v2/param_values_spec.rb @@ -149,6 +149,27 @@ def app { message: 'hi' } end + desc 'range_exclusive_float' do + consumes ['application/x-www-form-urlencoded'] + end + params do + requires :float, type: Float, values: 0.0...1.0 + end + post :range_exclusive_float do + { message: 'hi' } + end + + desc 'range_exclusive_body' do + consumes ['application/json'] + end + params do + requires :float, type: Float, values: 0.0...1.0 + requires :list, type: Array[Integer], values: 1...5 + end + post :range_exclusive_body do + { message: 'hi' } + end + add_swagger_documentation end end @@ -190,6 +211,23 @@ def first_parameter_info(request) end end + context 'Range values with an exclusive end' do + subject(:range_exclusive_float) { first_parameter_info('range_exclusive_float') } + + it 'flags the maximum as exclusive' do + expect(range_exclusive_float.first).to include('minimum' => 0.0, 'maximum' => 1.0, 'exclusiveMaximum' => true) + end + end + + context 'Range values with an exclusive end in a body definition' do + it 'keeps exclusiveMaximum on properties and array items' do + get '/swagger_doc/range_exclusive_body' + props = JSON.parse(last_response.body)['definitions']['postRangeExclusiveBody']['properties'] + expect(props['float']).to include('maximum' => 1.0, 'exclusiveMaximum' => true) + expect(props['list']['items']).to include('minimum' => 1, 'maximum' => 5, 'exclusiveMaximum' => true) + end + end + context 'Range values with an infinite end' do subject(:range_infinite_float) { first_parameter_info('range_infinite_float') } From 5ad1271a40617b91d293d417278119443a6f940c Mon Sep 17 00:00:00 2001 From: Andrey Subbota Date: Tue, 10 Nov 2026 20:53:16 +0100 Subject: [PATCH 7/8] Keep whole BigDecimal and Rational range bounds exact Range bounds that are not Integer or Float were always rounded through Float, so a whole BigDecimal such as 9007199254740993 lost precision and 1 was documented as 1.0. Whole values now stay Integers; only fractional ones become Floats. Specs also cover Rational, NaN bounds, and exclusiveMaximum on the items of a query array. --- lib/grape-swagger/doc_methods/parse_params.rb | 8 +++--- spec/lib/parse_params_spec.rb | 28 +++++++++++++++++-- spec/swagger_v2/param_values_spec.rb | 18 ++++++++++++ 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/lib/grape-swagger/doc_methods/parse_params.rb b/lib/grape-swagger/doc_methods/parse_params.rb index e54dc585..22908da7 100644 --- a/lib/grape-swagger/doc_methods/parse_params.rb +++ b/lib/grape-swagger/doc_methods/parse_params.rb @@ -211,12 +211,12 @@ def real_number?(bound) bound.is_a?(Numeric) && bound.real? end - # Only finite numbers are valid JSON; BigDecimal and Rational are emitted as Float. + # Only finite numbers are valid JSON; BigDecimal and Rational are emitted as Integer when whole, else Float. def range_bound(bound) - return unless real_number?(bound) + return unless real_number?(bound) && bound.finite? + return bound if bound.is_a?(Integer) || bound.is_a?(Float) - bound = bound.to_f unless bound.is_a?(Integer) || bound.is_a?(Float) - bound if bound.finite? + bound.to_i == bound ? bound.to_i : bound.to_f end end end diff --git a/spec/lib/parse_params_spec.rb b/spec/lib/parse_params_spec.rb index 4f399df7..d8e8ae51 100644 --- a/spec/lib/parse_params_spec.rb +++ b/spec/lib/parse_params_spec.rb @@ -74,8 +74,32 @@ describe 'BigDecimal' do specify do - parsed_range = subject.send(:parse_enum_or_range_values, BigDecimal('1')..BigDecimal('2')) - expect(parsed_range).to eql(minimum: 1.0, maximum: 2.0) + parsed_range = subject.send(:parse_enum_or_range_values, BigDecimal('1')..BigDecimal('2.5')) + expect(parsed_range).to eql(minimum: 1, maximum: 2.5) + end + + it 'keeps whole values beyond Float precision exact' do + parsed_range = subject.send(:parse_enum_or_range_values, BigDecimal('9007199254740993')..) + expect(parsed_range).to eql(minimum: 9_007_199_254_740_993) + end + + it 'skips NaN and infinite bounds' do + expect(subject.send(:parse_enum_or_range_values, ..BigDecimal('NaN'))).to eql({}) + expect(subject.send(:parse_enum_or_range_values, BigDecimal('-Infinity')..BigDecimal('3'))).to eql(maximum: 3) + end + end + + describe 'Rational' do + specify do + parsed_range = subject.send(:parse_enum_or_range_values, 1r..3/2r) + expect(parsed_range).to eql(minimum: 1, maximum: 1.5) + end + end + + describe 'Float NaN' do + specify do + parsed_range = subject.send(:parse_enum_or_range_values, Float::NAN..) + expect(parsed_range).to eql({}) end end diff --git a/spec/swagger_v2/param_values_spec.rb b/spec/swagger_v2/param_values_spec.rb index 3c3607e2..b4a7b109 100644 --- a/spec/swagger_v2/param_values_spec.rb +++ b/spec/swagger_v2/param_values_spec.rb @@ -170,6 +170,16 @@ def app { message: 'hi' } end + desc 'range_exclusive_query_array' do + consumes ['application/json'] + end + params do + requires :list, type: Array[Integer], values: 1...5 + end + get :range_exclusive_query_array do + { message: 'hi' } + end + add_swagger_documentation end end @@ -219,6 +229,14 @@ def first_parameter_info(request) end end + context 'Range values with an exclusive end in a query array' do + it 'keeps exclusiveMaximum on the array items' do + get '/swagger_doc/range_exclusive_query_array' + parameters = JSON.parse(last_response.body)['paths']['/range_exclusive_query_array']['get']['parameters'] + expect(parameters.first['items']).to include('minimum' => 1, 'maximum' => 5, 'exclusiveMaximum' => true) + end + end + context 'Range values with an exclusive end in a body definition' do it 'keeps exclusiveMaximum on properties and array items' do get '/swagger_doc/range_exclusive_body' From dda14e71240b7ba5881a08150db5079ca0724703 Mon Sep 17 00:00:00 2001 From: Andrey Subbota Date: Thu, 12 Nov 2026 00:21:48 +0100 Subject: [PATCH 8/8] Check every range bound before documenting it A range with a real start and a non-real end, such as 1..Complex(2, 0), was documented with only its start because the check looked at a single bound. Checking all bounds drops the whole range instead, matching how non-real bounds are already handled. --- lib/grape-swagger/doc_methods/parse_params.rb | 7 ++++++- spec/lib/parse_params_spec.rb | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/grape-swagger/doc_methods/parse_params.rb b/lib/grape-swagger/doc_methods/parse_params.rb index 22908da7..4350a482 100644 --- a/lib/grape-swagger/doc_methods/parse_params.rb +++ b/lib/grape-swagger/doc_methods/parse_params.rb @@ -193,7 +193,7 @@ def parse_enum_or_range_values(values) when Proc parse_enum_or_range_values(values.call) if values.parameters.empty? when Range - parse_range_values(values) if real_number?(values.begin || values.end) + parse_range_values(values) if range_bounds_real?(values) when Array { enum: values } else @@ -207,6 +207,11 @@ def parse_range_values(values) range end + def range_bounds_real?(values) + bounds = [values.begin, values.end].compact + bounds.any? && bounds.all? { |bound| real_number?(bound) } + end + def real_number?(bound) bound.is_a?(Numeric) && bound.real? end diff --git a/spec/lib/parse_params_spec.rb b/spec/lib/parse_params_spec.rb index d8e8ae51..4a4ac205 100644 --- a/spec/lib/parse_params_spec.rb +++ b/spec/lib/parse_params_spec.rb @@ -121,6 +121,7 @@ specify do expect(subject.send(:parse_enum_or_range_values, ..Complex(1, 2))).to be_nil expect(subject.send(:parse_enum_or_range_values, Complex(1, 2)..)).to be_nil + expect(subject.send(:parse_enum_or_range_values, 1..Complex(2, 0))).to be_nil end end