Skip to content

Commit aeb40a7

Browse files
blakenumbata
authored andcommitted
Fix edge cases with ranges, floats and strings
1 parent 54de96d commit aeb40a7

File tree

2 files changed

+180
-2
lines changed

2 files changed

+180
-2
lines changed

lib/grape-swagger/openapi_3/doc_methods/parse_params.rb

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,17 @@ def parse_enum_or_range_values(values)
110110
when Proc
111111
parse_enum_or_range_values(values.call) if values.parameters.empty?
112112
when Range
113-
parse_range_values(values) if values.first.is_a?(Integer)
113+
if values.first.is_a?(Numeric)
114+
parse_range_values(values)
115+
else
116+
{ enum: values.to_a }
117+
end
114118
else
115-
{ enum: values } if values
119+
if values.respond_to? :each
120+
{ enum: values }
121+
else
122+
{ enum: [values] }
123+
end
116124
end
117125
end
118126

spec/openapi_3/param_values_spec.rb

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
# frozen_string_literal: true
2+
3+
require 'spec_helper'
4+
# require 'grape_version'
5+
6+
describe 'Convert values to enum or Range' do
7+
def app
8+
Class.new(Grape::API) do
9+
format :json
10+
11+
params do
12+
requires :letter, type: String, values: %w[a b c]
13+
end
14+
post :plain_array do
15+
end
16+
17+
params do
18+
requires :letter, type: String, values: proc { %w[d e f] }
19+
end
20+
post :array_in_proc do
21+
end
22+
23+
params do
24+
requires :letter, type: String, values: 'a'..'z'
25+
end
26+
post :range_letter do
27+
end
28+
29+
params do
30+
requires :integer, type: Integer, values: -5..5
31+
end
32+
post :range_integer do
33+
end
34+
35+
add_swagger_documentation openapi_version: '3.0'
36+
end
37+
end
38+
39+
def first_parameter_info(request)
40+
get "/swagger_doc/#{request}"
41+
expect(last_response.status).to eq 200
42+
body = JSON.parse last_response.body
43+
body['paths']["/#{request}"]['post']['requestBody']['content']['application/x-www-form-urlencoded']['schema']
44+
end
45+
46+
context 'Plain array values' do
47+
subject(:plain_array) { first_parameter_info('plain_array') }
48+
it 'has values as array in enum' do
49+
expect(plain_array).to eq(
50+
'properties' => {
51+
'letter' => {
52+
'enum' => %w[a b c],
53+
'type' => 'string'
54+
}
55+
},
56+
'required' => ['letter'],
57+
'type' => 'object'
58+
)
59+
end
60+
end
61+
62+
context 'Array in proc values' do
63+
subject(:array_in_proc) { first_parameter_info('array_in_proc') }
64+
65+
it 'has proc returned values as array in enum' do
66+
expect(array_in_proc).to eq(
67+
'properties' => {
68+
'letter' => {
69+
'enum' => %w[d e f],
70+
'type' => 'string'
71+
}
72+
}, 'required' => ['letter'],
73+
'type' => 'object'
74+
)
75+
end
76+
end
77+
78+
context 'Range values' do
79+
subject(:range_letter) { first_parameter_info('range_letter') }
80+
81+
it 'has letter range values' do
82+
expect(range_letter).to eq(
83+
'properties' => {
84+
'letter' => { 'enum' => %w[a b c d e f g h i j k l m n o p q r s t u v w x y z], 'type' => 'string' }
85+
},
86+
'required' => ['letter'],
87+
'type' => 'object'
88+
)
89+
end
90+
91+
subject(:range_integer) { first_parameter_info('range_integer') }
92+
93+
it 'has integer range values' do
94+
expect(range_integer).to eq(
95+
'properties' => {
96+
'integer' => {
97+
'format' => 'int32',
98+
'maximum' => 5,
99+
'minimum' => -5,
100+
'type' => 'integer'
101+
}
102+
},
103+
'required' => ['integer'],
104+
'type' => 'object'
105+
)
106+
end
107+
end
108+
end
109+
110+
describe 'Convert values to enum for float range and not arrays inside a proc', if: GrapeVersion.satisfy?('>= 0.11.0') do
111+
def app
112+
Class.new(Grape::API) do
113+
format :json
114+
115+
params do
116+
requires :letter, type: String, values: proc { 'string' }
117+
end
118+
post :non_array_in_proc do
119+
end
120+
121+
params do
122+
requires :float, type: Float, values: -5.0..5.0
123+
end
124+
post :range_float do
125+
end
126+
127+
add_swagger_documentation openapi_version: '3.0'
128+
end
129+
end
130+
131+
def first_parameter_info(request)
132+
get "/swagger_doc/#{request}"
133+
expect(last_response.status).to eq 200
134+
body = JSON.parse last_response.body
135+
body['paths']["/#{request}"]['post']['requestBody']['content']['application/x-www-form-urlencoded']['schema']
136+
end
137+
138+
context 'Non array in proc values' do
139+
subject(:non_array_in_proc) { first_parameter_info('non_array_in_proc') }
140+
141+
it 'has proc returned value as string in enum' do
142+
expect(non_array_in_proc).to eq(
143+
'properties' => {
144+
'letter' => {
145+
'enum' => ['string'],
146+
'type' => 'string'
147+
}
148+
},
149+
'required' => ['letter'],
150+
'type' => 'object'
151+
)
152+
end
153+
end
154+
155+
context 'Range values' do
156+
subject(:range_float) { first_parameter_info('range_float') }
157+
158+
it 'has float range values as string' do
159+
expect(range_float).to eq(
160+
'properties' => {
161+
'float' => {
162+
'format' => 'float', 'maximum' => 5.0, 'minimum' => -5.0, 'type' => 'number'
163+
}
164+
},
165+
'required' => ['float'],
166+
'type' => 'object'
167+
)
168+
end
169+
end
170+
end

0 commit comments

Comments
 (0)