sinatra-param 1.3.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +29 -8
- data/coverage/index.html +319 -151
- data/lib/sinatra/param.rb +43 -15
- data/lib/sinatra/param/version.rb +1 -1
- data/sinatra-param-1.3.1.gem +0 -0
- data/spec/dummy/app.rb +28 -4
- data/spec/parameter_exclusivity_spec.rb +6 -6
- data/spec/parameter_inclusivity_spec.rb +30 -0
- data/spec/parameter_raise_spec.rb +8 -1
- data/spec/parameter_transformations_spec.rb +1 -1
- data/spec/parameter_type_coercion_spec.rb +5 -5
- data/spec/parameter_validations_spec.rb +13 -13
- metadata +5 -2
data/lib/sinatra/param.rb
CHANGED
@@ -27,7 +27,8 @@ module Sinatra
|
|
27
27
|
raise exception
|
28
28
|
end
|
29
29
|
|
30
|
-
error =
|
30
|
+
error = exception.to_s
|
31
|
+
|
31
32
|
if content_type and content_type.match(mime_type(:json))
|
32
33
|
error = {message: error, errors: {name => exception.message}}.to_json
|
33
34
|
end
|
@@ -50,7 +51,30 @@ module Sinatra
|
|
50
51
|
raise exception
|
51
52
|
end
|
52
53
|
|
53
|
-
error = "
|
54
|
+
error = "Invalid parameters [#{names.join(', ')}]"
|
55
|
+
if content_type and content_type.match(mime_type(:json))
|
56
|
+
error = {message: error, errors: {names => exception.message}}.to_json
|
57
|
+
end
|
58
|
+
|
59
|
+
halt 400, error
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def any_of(*args)
|
64
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
65
|
+
names = args.collect(&:to_s)
|
66
|
+
|
67
|
+
return unless names.length >= 2
|
68
|
+
|
69
|
+
begin
|
70
|
+
validate_any_of!(params, names, options)
|
71
|
+
rescue InvalidParameterError => exception
|
72
|
+
if options[:raise] or (settings.raise_sinatra_param_exceptions rescue false)
|
73
|
+
exception.param, exception.options = names, options
|
74
|
+
raise exception
|
75
|
+
end
|
76
|
+
|
77
|
+
error = "Invalid parameters [#{names.join(', ')}]"
|
54
78
|
if content_type and content_type.match(mime_type(:json))
|
55
79
|
error = {message: error, errors: {names => exception.message}}.to_json
|
56
80
|
end
|
@@ -87,13 +111,13 @@ module Sinatra
|
|
87
111
|
raise InvalidParameterError, "Parameter is required" if value && param.nil?
|
88
112
|
when :blank
|
89
113
|
raise InvalidParameterError, "Parameter cannot be blank" if !value && case param
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
114
|
+
when String
|
115
|
+
!(/\S/ === param)
|
116
|
+
when Array, Hash
|
117
|
+
param.empty?
|
118
|
+
else
|
119
|
+
param.nil?
|
120
|
+
end
|
97
121
|
when :format
|
98
122
|
raise InvalidParameterError, "Parameter must be a string if using the format validation" unless param.kind_of?(String)
|
99
123
|
raise InvalidParameterError, "Parameter must match format #{value}" unless param =~ value
|
@@ -101,11 +125,11 @@ module Sinatra
|
|
101
125
|
raise InvalidParameterError, "Parameter must be #{value}" unless param === value
|
102
126
|
when :in, :within, :range
|
103
127
|
raise InvalidParameterError, "Parameter must be within #{value}" unless param.nil? || case value
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
128
|
+
when Range
|
129
|
+
value.include?(param)
|
130
|
+
else
|
131
|
+
Array(value).include?(param)
|
132
|
+
end
|
109
133
|
when :min
|
110
134
|
raise InvalidParameterError, "Parameter cannot be less than #{value}" unless param.nil? || value <= param
|
111
135
|
when :max
|
@@ -119,7 +143,11 @@ module Sinatra
|
|
119
143
|
end
|
120
144
|
|
121
145
|
def validate_one_of!(params, names, options)
|
122
|
-
raise InvalidParameterError, "
|
146
|
+
raise InvalidParameterError, "Only one of [#{names.join(', ')}] is allowed" if names.count{|name| present?(params[name])} > 1
|
147
|
+
end
|
148
|
+
|
149
|
+
def validate_any_of!(params, names, options)
|
150
|
+
raise InvalidParameterError, "One of parameters [#{names.join(', ')}] is required" if names.count{|name| present?(params[name])} < 1
|
123
151
|
end
|
124
152
|
|
125
153
|
# ActiveSupport #present? and #blank? without patching Object
|
Binary file
|
data/spec/dummy/app.rb
CHANGED
@@ -185,7 +185,7 @@ class App < Sinatra::Base
|
|
185
185
|
params.to_json
|
186
186
|
end
|
187
187
|
|
188
|
-
get '/
|
188
|
+
get '/one_of/1' do
|
189
189
|
param :a, String
|
190
190
|
param :b, String
|
191
191
|
param :c, String
|
@@ -197,7 +197,7 @@ class App < Sinatra::Base
|
|
197
197
|
}.to_json
|
198
198
|
end
|
199
199
|
|
200
|
-
get '/
|
200
|
+
get '/one_of/2' do
|
201
201
|
param :a, String
|
202
202
|
param :b, String
|
203
203
|
param :c, String
|
@@ -209,7 +209,7 @@ class App < Sinatra::Base
|
|
209
209
|
}.to_json
|
210
210
|
end
|
211
211
|
|
212
|
-
get '/
|
212
|
+
get '/one_of/3' do
|
213
213
|
param :a, String
|
214
214
|
param :b, String
|
215
215
|
param :c, String
|
@@ -221,12 +221,24 @@ class App < Sinatra::Base
|
|
221
221
|
}.to_json
|
222
222
|
end
|
223
223
|
|
224
|
+
get '/any_of' do
|
225
|
+
param :a, String
|
226
|
+
param :b, String
|
227
|
+
param :c, String
|
228
|
+
|
229
|
+
any_of :a, :b, :c
|
230
|
+
|
231
|
+
{
|
232
|
+
message: 'OK'
|
233
|
+
}.to_json
|
234
|
+
end
|
235
|
+
|
224
236
|
get '/raise/validation/required' do
|
225
237
|
param :arg, String, required: true, raise: true
|
226
238
|
params.to_json
|
227
239
|
end
|
228
240
|
|
229
|
-
get '/raise/
|
241
|
+
get '/raise/one_of/3' do
|
230
242
|
param :a, String
|
231
243
|
param :b, String
|
232
244
|
param :c, String
|
@@ -237,4 +249,16 @@ class App < Sinatra::Base
|
|
237
249
|
message: 'OK'
|
238
250
|
}.to_json
|
239
251
|
end
|
252
|
+
|
253
|
+
get '/raise/any_of' do
|
254
|
+
param :a, String
|
255
|
+
param :b, String
|
256
|
+
param :c, String
|
257
|
+
|
258
|
+
any_of :a, :b, :c, raise: true
|
259
|
+
|
260
|
+
{
|
261
|
+
message: 'OK'
|
262
|
+
}.to_json
|
263
|
+
end
|
240
264
|
end
|
@@ -10,9 +10,9 @@ describe 'Parameter Sets' do
|
|
10
10
|
]
|
11
11
|
|
12
12
|
params.each do |param|
|
13
|
-
get('/
|
13
|
+
get('/one_of/3', param) do |response|
|
14
14
|
expect(response.status).to eql 400
|
15
|
-
expect(JSON.parse(response.body)['message']).to match(
|
15
|
+
expect(JSON.parse(response.body)['message']).to match(/^Invalid parameters/)
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
@@ -20,9 +20,9 @@ describe 'Parameter Sets' do
|
|
20
20
|
it 'returns 400 on requests that contain more than one mutually exclusive parameter' do
|
21
21
|
params = {a: 1, b: 2}
|
22
22
|
|
23
|
-
get('/
|
23
|
+
get('/one_of/2', params) do |response|
|
24
24
|
expect(response.status).to eql 400
|
25
|
-
expect(JSON.parse(response.body)['message']).to match(
|
25
|
+
expect(JSON.parse(response.body)['message']).to match(/^Invalid parameters/)
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
@@ -35,7 +35,7 @@ describe 'Parameter Sets' do
|
|
35
35
|
|
36
36
|
(1..3).each do |n|
|
37
37
|
params.each do |param|
|
38
|
-
get("/
|
38
|
+
get("/one_of/#{n}", param) do |response|
|
39
39
|
expect(response.status).to eql 200
|
40
40
|
expect(JSON.parse(response.body)['message']).to match(/OK/)
|
41
41
|
end
|
@@ -45,7 +45,7 @@ describe 'Parameter Sets' do
|
|
45
45
|
|
46
46
|
it 'returns successfully for requests that have no parameter' do
|
47
47
|
(1..3).each do |n|
|
48
|
-
get("/
|
48
|
+
get("/one_of/#{n}") do |response|
|
49
49
|
expect(response.status).to eql 200
|
50
50
|
expect(JSON.parse(response.body)['message']).to match(/OK/)
|
51
51
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Parameter Sets' do
|
4
|
+
describe 'any_of' do
|
5
|
+
it 'returns 400 on requests that contain fewer than one required parameter' do
|
6
|
+
get('/any_of', {}) do |response|
|
7
|
+
expect(response.status).to eql 400
|
8
|
+
expect(JSON.parse(response.body)['message']).to match(/Invalid parameters/)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'returns successfully for requests that have at least one parameter' do
|
13
|
+
params = [
|
14
|
+
{a: 1},
|
15
|
+
{b: 2},
|
16
|
+
{c: 3},
|
17
|
+
{a: 1, b: 2},
|
18
|
+
{b: 2, c: 3},
|
19
|
+
{a: 1, b: 2, c: 3}
|
20
|
+
]
|
21
|
+
|
22
|
+
params.each do |param|
|
23
|
+
get("/any_of", param) do |response|
|
24
|
+
expect(response.status).to eql 200
|
25
|
+
expect(JSON.parse(response.body)['message']).to match(/OK/)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -12,7 +12,14 @@ describe 'Exception' do
|
|
12
12
|
it 'should raise error when more than one parameter is specified' do
|
13
13
|
params = {a: 1, b: 2, c: 3}
|
14
14
|
expect {
|
15
|
-
get('/raise/
|
15
|
+
get('/raise/one_of/3', params)
|
16
|
+
}.to raise_error
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should raise error when no parameters are specified' do
|
20
|
+
params = {}
|
21
|
+
expect {
|
22
|
+
get('/raise/any_of', params)
|
16
23
|
}.to raise_error
|
17
24
|
end
|
18
25
|
end
|
@@ -35,7 +35,7 @@ describe 'Parameter Transformations' do
|
|
35
35
|
it 'skips transformations when the value is nil' do
|
36
36
|
get('/transform/required') do |response|
|
37
37
|
expect(response.status).to eql 400
|
38
|
-
expect(JSON.parse(response.body)['message']).to eq(
|
38
|
+
expect(JSON.parse(response.body)['message']).to eq("Parameter is required")
|
39
39
|
end
|
40
40
|
end
|
41
41
|
end
|
@@ -21,7 +21,7 @@ describe 'Parameter Types' do
|
|
21
21
|
it 'returns 400 on requests when integer is invalid' do
|
22
22
|
get('/coerce/integer', arg: '123abc') do |response|
|
23
23
|
expect(response.status).to eql 400
|
24
|
-
expect(JSON.parse(response.body)['message']).to eq('
|
24
|
+
expect(JSON.parse(response.body)['message']).to eq("'123abc' is not a valid Integer")
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
@@ -37,7 +37,7 @@ describe 'Parameter Types' do
|
|
37
37
|
it 'returns 400 on requests when float is invalid' do
|
38
38
|
get('/coerce/float', arg: '123abc') do |response|
|
39
39
|
expect(response.status).to eql 400
|
40
|
-
expect(JSON.parse(response.body)['message']).to eq('
|
40
|
+
expect(JSON.parse(response.body)['message']).to eq("'123abc' is not a valid Float")
|
41
41
|
end
|
42
42
|
end
|
43
43
|
end
|
@@ -53,7 +53,7 @@ describe 'Parameter Types' do
|
|
53
53
|
it 'returns 400 on requests when time is invalid' do
|
54
54
|
get('/coerce/time', arg: '123abc') do |response|
|
55
55
|
expect(response.status).to eql 400
|
56
|
-
expect(JSON.parse(response.body)['message']).to eq('
|
56
|
+
expect(JSON.parse(response.body)['message']).to eq("'123abc' is not a valid Time")
|
57
57
|
end
|
58
58
|
end
|
59
59
|
end
|
@@ -69,7 +69,7 @@ describe 'Parameter Types' do
|
|
69
69
|
it 'returns 400 on requests when date is invalid' do
|
70
70
|
get('/coerce/date', arg: 'abc') do |response|
|
71
71
|
expect(response.status).to eql 400
|
72
|
-
expect(JSON.parse(response.body)['message']).to eq('
|
72
|
+
expect(JSON.parse(response.body)['message']).to eq("'abc' is not a valid Date")
|
73
73
|
end
|
74
74
|
end
|
75
75
|
end
|
@@ -85,7 +85,7 @@ describe 'Parameter Types' do
|
|
85
85
|
it 'returns 400 on requests when datetime is invalid' do
|
86
86
|
get('/coerce/datetime', arg: 'abc') do |response|
|
87
87
|
expect(response.status).to eql 400
|
88
|
-
expect(JSON.parse(response.body)['message']).to eq('
|
88
|
+
expect(JSON.parse(response.body)['message']).to eq("'abc' is not a valid DateTime")
|
89
89
|
end
|
90
90
|
end
|
91
91
|
end
|
@@ -5,7 +5,7 @@ describe 'Parameter Validations' do
|
|
5
5
|
it 'returns 400 on requests without required fields' do
|
6
6
|
get('/validation/required') do |response|
|
7
7
|
expect(response.status).to eq(400)
|
8
|
-
expect(JSON.parse(response.body)['message']).to eq(
|
8
|
+
expect(JSON.parse(response.body)['message']).to eq("Parameter is required")
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
@@ -20,28 +20,28 @@ describe 'Parameter Validations' do
|
|
20
20
|
it 'returns 400 on requests when string is blank' do
|
21
21
|
get('/validation/blank/string', arg: '') do |response|
|
22
22
|
expect(response.status).to eq(400)
|
23
|
-
expect(JSON.parse(response.body)['message']).to eq(
|
23
|
+
expect(JSON.parse(response.body)['message']).to eq("Parameter cannot be blank")
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
27
|
it 'returns 400 on requests when array is blank' do
|
28
28
|
get('/validation/blank/array', arg: '') do |response|
|
29
29
|
expect(response.status).to eq(400)
|
30
|
-
expect(JSON.parse(response.body)['message']).to eq(
|
30
|
+
expect(JSON.parse(response.body)['message']).to eq("Parameter cannot be blank")
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
34
|
it 'returns 400 on requests when hash is blank' do
|
35
35
|
get('/validation/blank/hash', arg: '') do |response|
|
36
36
|
expect(response.status).to eq(400)
|
37
|
-
expect(JSON.parse(response.body)['message']).to eq(
|
37
|
+
expect(JSON.parse(response.body)['message']).to eq("Parameter cannot be blank")
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
41
|
it 'returns 400 on requests when hash is blank' do
|
42
42
|
get('/validation/blank/other', arg: '') do |response|
|
43
43
|
expect(response.status).to eq(400)
|
44
|
-
expect(JSON.parse(response.body)['message']).to eq(
|
44
|
+
expect(JSON.parse(response.body)['message']).to eq("Parameter cannot be blank")
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
@@ -76,7 +76,7 @@ describe 'Parameter Validations' do
|
|
76
76
|
it 'returns 400 on requests when value is other than defined' do
|
77
77
|
get('/validation/is', arg: 'bar') do |response|
|
78
78
|
expect(response.status).to eq(400)
|
79
|
-
expect(JSON.parse(response.body)['message']).to eq(
|
79
|
+
expect(JSON.parse(response.body)['message']).to eq("Parameter must be foo")
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
@@ -91,7 +91,7 @@ describe 'Parameter Validations' do
|
|
91
91
|
it 'returns 400 on requests with a value not in the set' do
|
92
92
|
get('/validation/in', arg: 'MISC') do |response|
|
93
93
|
expect(response.status).to eq(400)
|
94
|
-
expect(JSON.parse(response.body)['message']).to eq(
|
94
|
+
expect(JSON.parse(response.body)['message']).to eq("Parameter must be within [\"ASC\", \"DESC\"]")
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
@@ -106,7 +106,7 @@ describe 'Parameter Validations' do
|
|
106
106
|
it 'returns 400 on requests with a value outside the range' do
|
107
107
|
get('/validation/within', arg: 20) do |response|
|
108
108
|
expect(response.status).to eq(400)
|
109
|
-
expect(JSON.parse(response.body)['message']).to eq(
|
109
|
+
expect(JSON.parse(response.body)['message']).to eq("Parameter must be within 1..10")
|
110
110
|
end
|
111
111
|
end
|
112
112
|
|
@@ -121,7 +121,7 @@ describe 'Parameter Validations' do
|
|
121
121
|
it 'returns 400 on requests with a value outside the range' do
|
122
122
|
get('/validation/range', arg: 20) do |response|
|
123
123
|
expect(response.status).to eq(400)
|
124
|
-
expect(JSON.parse(response.body)['message']).to eq(
|
124
|
+
expect(JSON.parse(response.body)['message']).to eq("Parameter must be within 1..10")
|
125
125
|
end
|
126
126
|
end
|
127
127
|
|
@@ -136,7 +136,7 @@ describe 'Parameter Validations' do
|
|
136
136
|
it 'returns 400 on requests with a value smaller than min' do
|
137
137
|
get('/validation/min', arg: 5) do |response|
|
138
138
|
expect(response.status).to eq(400)
|
139
|
-
expect(JSON.parse(response.body)['message']).to eq(
|
139
|
+
expect(JSON.parse(response.body)['message']).to eq("Parameter cannot be less than 12")
|
140
140
|
end
|
141
141
|
end
|
142
142
|
|
@@ -151,7 +151,7 @@ describe 'Parameter Validations' do
|
|
151
151
|
it 'returns 400 on requests with a value larger than max' do
|
152
152
|
get('/validation/max', arg: 100) do |response|
|
153
153
|
expect(response.status).to eq(400)
|
154
|
-
expect(JSON.parse(response.body)['message']).to eq(
|
154
|
+
expect(JSON.parse(response.body)['message']).to eq("Parameter cannot be greater than 20")
|
155
155
|
end
|
156
156
|
end
|
157
157
|
|
@@ -166,7 +166,7 @@ describe 'Parameter Validations' do
|
|
166
166
|
it 'returns 400 on requests with a string shorter than min_length' do
|
167
167
|
get('/validation/min_length', arg: 'hi') do |response|
|
168
168
|
expect(response.status).to eq(400)
|
169
|
-
expect(JSON.parse(response.body)['message']).to eq(
|
169
|
+
expect(JSON.parse(response.body)['message']).to eq("Parameter cannot have length less than 5")
|
170
170
|
end
|
171
171
|
end
|
172
172
|
|
@@ -181,7 +181,7 @@ describe 'Parameter Validations' do
|
|
181
181
|
it 'returns 400 on requests with a string longer than max_length' do
|
182
182
|
get('/validation/max_length', arg: 'reallylongstringlongerthanmax') do |response|
|
183
183
|
expect(response.status).to eq(400)
|
184
|
-
expect(JSON.parse(response.body)['message']).to eq(
|
184
|
+
expect(JSON.parse(response.body)['message']).to eq("Parameter cannot have length greater than 10")
|
185
185
|
end
|
186
186
|
end
|
187
187
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sinatra-param
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mattt Thompson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-04-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sinatra
|
@@ -141,9 +141,11 @@ files:
|
|
141
141
|
- ./Rakefile
|
142
142
|
- ./README.md
|
143
143
|
- ./sinatra-param-1.3.0.gem
|
144
|
+
- ./sinatra-param-1.3.1.gem
|
144
145
|
- ./sinatra-param.gemspec
|
145
146
|
- spec/dummy/app.rb
|
146
147
|
- spec/parameter_exclusivity_spec.rb
|
148
|
+
- spec/parameter_inclusivity_spec.rb
|
147
149
|
- spec/parameter_raise_spec.rb
|
148
150
|
- spec/parameter_spec.rb
|
149
151
|
- spec/parameter_transformations_spec.rb
|
@@ -177,6 +179,7 @@ summary: Parameter Validation & Type Coercion for Sinatra.
|
|
177
179
|
test_files:
|
178
180
|
- spec/dummy/app.rb
|
179
181
|
- spec/parameter_exclusivity_spec.rb
|
182
|
+
- spec/parameter_inclusivity_spec.rb
|
180
183
|
- spec/parameter_raise_spec.rb
|
181
184
|
- spec/parameter_spec.rb
|
182
185
|
- spec/parameter_transformations_spec.rb
|