grape 0.3.0 → 0.7.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.
Potentially problematic release.
This version of grape might be problematic. Click here for more details.
- checksums.yaml +15 -0
- data/.gitignore +8 -0
- data/.rubocop.yml +70 -0
- data/.travis.yml +7 -6
- data/CHANGELOG.md +134 -4
- data/CONTRIBUTING.md +118 -0
- data/Gemfile +5 -2
- data/README.md +551 -116
- data/RELEASING.md +105 -0
- data/Rakefile +29 -8
- data/UPGRADING.md +124 -0
- data/grape.gemspec +3 -3
- data/lib/grape/api.rb +207 -88
- data/lib/grape/cookies.rb +4 -8
- data/lib/grape/endpoint.rb +198 -144
- data/lib/grape/error_formatter/base.rb +5 -7
- data/lib/grape/error_formatter/json.rb +3 -5
- data/lib/grape/error_formatter/txt.rb +1 -3
- data/lib/grape/error_formatter/xml.rb +4 -6
- data/lib/grape/exceptions/base.rb +9 -9
- data/lib/grape/exceptions/incompatible_option_values.rb +10 -0
- data/lib/grape/exceptions/invalid_formatter.rb +1 -4
- data/lib/grape/exceptions/invalid_versioner_option.rb +1 -5
- data/lib/grape/exceptions/invalid_with_option_for_represent.rb +1 -6
- data/lib/grape/exceptions/missing_mime_type.rb +1 -5
- data/lib/grape/exceptions/missing_option.rb +1 -4
- data/lib/grape/exceptions/missing_vendor_option.rb +1 -4
- data/lib/grape/exceptions/unknown_options.rb +1 -5
- data/lib/grape/exceptions/unknown_validator.rb +1 -3
- data/lib/grape/exceptions/validation.rb +13 -3
- data/lib/grape/exceptions/validation_errors.rb +43 -0
- data/lib/grape/formatter/base.rb +5 -7
- data/lib/grape/formatter/json.rb +0 -3
- data/lib/grape/formatter/serializable_hash.rb +15 -15
- data/lib/grape/formatter/txt.rb +0 -2
- data/lib/grape/formatter/xml.rb +0 -2
- data/lib/grape/http/request.rb +26 -0
- data/lib/grape/locale/en.yml +8 -5
- data/lib/grape/middleware/auth/base.rb +30 -0
- data/lib/grape/middleware/auth/basic.rb +3 -20
- data/lib/grape/middleware/auth/digest.rb +2 -19
- data/lib/grape/middleware/auth/oauth2.rb +31 -24
- data/lib/grape/middleware/base.rb +7 -7
- data/lib/grape/middleware/error.rb +36 -22
- data/lib/grape/middleware/filter.rb +3 -3
- data/lib/grape/middleware/formatter.rb +99 -61
- data/lib/grape/middleware/globals.rb +13 -0
- data/lib/grape/middleware/versioner/accept_version_header.rb +67 -0
- data/lib/grape/middleware/versioner/header.rb +22 -16
- data/lib/grape/middleware/versioner/param.rb +9 -11
- data/lib/grape/middleware/versioner/path.rb +10 -13
- data/lib/grape/middleware/versioner.rb +3 -1
- data/lib/grape/namespace.rb +23 -0
- data/lib/grape/parser/base.rb +3 -5
- data/lib/grape/parser/json.rb +0 -2
- data/lib/grape/parser/xml.rb +0 -2
- data/lib/grape/path.rb +70 -0
- data/lib/grape/route.rb +10 -6
- data/lib/grape/util/content_types.rb +2 -1
- data/lib/grape/util/deep_merge.rb +5 -5
- data/lib/grape/util/hash_stack.rb +13 -2
- data/lib/grape/validations/coerce.rb +11 -10
- data/lib/grape/validations/default.rb +25 -0
- data/lib/grape/validations/presence.rb +7 -3
- data/lib/grape/validations/regexp.rb +2 -5
- data/lib/grape/validations/values.rb +17 -0
- data/lib/grape/validations.rb +161 -54
- data/lib/grape/version.rb +1 -1
- data/lib/grape.rb +19 -4
- data/spec/grape/api_spec.rb +897 -268
- data/spec/grape/endpoint_spec.rb +283 -66
- data/spec/grape/entity_spec.rb +132 -29
- data/spec/grape/exceptions/missing_mime_type_spec.rb +3 -9
- data/spec/grape/exceptions/validation_errors_spec.rb +19 -0
- data/spec/grape/middleware/auth/basic_spec.rb +8 -8
- data/spec/grape/middleware/auth/digest_spec.rb +5 -5
- data/spec/grape/middleware/auth/oauth2_spec.rb +81 -36
- data/spec/grape/middleware/base_spec.rb +8 -13
- data/spec/grape/middleware/error_spec.rb +13 -17
- data/spec/grape/middleware/exception_spec.rb +47 -27
- data/spec/grape/middleware/formatter_spec.rb +103 -41
- data/spec/grape/middleware/versioner/accept_version_header_spec.rb +121 -0
- data/spec/grape/middleware/versioner/header_spec.rb +76 -51
- data/spec/grape/middleware/versioner/param_spec.rb +18 -18
- data/spec/grape/middleware/versioner/path_spec.rb +6 -6
- data/spec/grape/middleware/versioner_spec.rb +5 -2
- data/spec/grape/path_spec.rb +229 -0
- data/spec/grape/util/hash_stack_spec.rb +31 -32
- data/spec/grape/validations/coerce_spec.rb +116 -51
- data/spec/grape/validations/default_spec.rb +123 -0
- data/spec/grape/validations/presence_spec.rb +42 -44
- data/spec/grape/validations/regexp_spec.rb +9 -9
- data/spec/grape/validations/values_spec.rb +138 -0
- data/spec/grape/validations/zh-CN.yml +4 -3
- data/spec/grape/validations_spec.rb +681 -48
- data/spec/shared/versioning_examples.rb +22 -6
- data/spec/spec_helper.rb +3 -2
- data/spec/support/basic_auth_encode_helpers.rb +0 -1
- data/spec/support/content_type_helpers.rb +11 -0
- data/spec/support/versioned_helpers.rb +13 -5
- metadata +34 -84
@@ -1,12 +1,11 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Grape::Util::HashStack do
|
4
|
-
let(:klass){ Grape::Util::HashStack }
|
5
4
|
|
6
5
|
describe '#get' do
|
7
6
|
it 'finds the first available key' do
|
8
7
|
subject[:abc] = 123
|
9
|
-
subject.push(:
|
8
|
+
subject.push(abc: 345)
|
10
9
|
subject.get(:abc).should == 345
|
11
10
|
end
|
12
11
|
|
@@ -26,105 +25,105 @@ describe Grape::Util::HashStack do
|
|
26
25
|
describe '#imbue' do
|
27
26
|
it 'pushes a new value onto the end of an array' do
|
28
27
|
subject[:abc] = []
|
29
|
-
subject.imbue
|
30
|
-
subject.imbue
|
28
|
+
subject.imbue :abc, [123]
|
29
|
+
subject.imbue :abc, [456]
|
31
30
|
subject[:abc].should == [123, 456]
|
32
31
|
end
|
33
32
|
|
34
33
|
it 'merges a hash that is passed' do
|
35
|
-
subject[:abc] = {:
|
36
|
-
subject.imbue
|
37
|
-
subject[:abc].should == {:
|
34
|
+
subject[:abc] = { foo: 'bar' }
|
35
|
+
subject.imbue :abc, baz: 'wich'
|
36
|
+
subject[:abc].should == { foo: 'bar', baz: 'wich' }
|
38
37
|
end
|
39
38
|
|
40
39
|
it 'sets the value if not a hash or array' do
|
41
|
-
subject.imbue
|
40
|
+
subject.imbue :abc, 123
|
42
41
|
subject[:abc].should == 123
|
43
42
|
end
|
44
43
|
|
45
44
|
it 'is able to imbue an array without explicit setting' do
|
46
|
-
subject.imbue
|
47
|
-
subject.imbue
|
48
|
-
subject[:arr].should == [1,2]
|
45
|
+
subject.imbue :arr, [1]
|
46
|
+
subject.imbue :arr, [2]
|
47
|
+
subject[:arr].should == [1, 2]
|
49
48
|
end
|
50
49
|
|
51
50
|
it 'is able to imbue a hash without explicit setting' do
|
52
|
-
subject.imbue
|
53
|
-
subject.imbue
|
54
|
-
subject[:hash].should == {:
|
51
|
+
subject.imbue :hash, foo: 'bar'
|
52
|
+
subject.imbue :hash, baz: 'wich'
|
53
|
+
subject[:hash].should == { foo: 'bar', baz: 'wich' }
|
55
54
|
end
|
56
55
|
end
|
57
56
|
|
58
57
|
describe '#push' do
|
59
58
|
it 'returns a HashStack' do
|
60
|
-
subject.push(
|
59
|
+
subject.push(Grape::Util::HashStack.new).should be_kind_of(Grape::Util::HashStack)
|
61
60
|
end
|
62
61
|
|
63
62
|
it 'places the passed value on the top of the stack' do
|
64
|
-
subject.push(:
|
65
|
-
subject.stack.should == [{}, {:
|
63
|
+
subject.push(abc: 123)
|
64
|
+
subject.stack.should == [{}, { abc: 123 }]
|
66
65
|
end
|
67
66
|
|
68
67
|
it 'pushes an empty hash by default' do
|
69
68
|
subject[:abc] = 123
|
70
69
|
subject.push
|
71
|
-
subject.stack.should == [{:
|
70
|
+
subject.stack.should == [{ abc: 123 }, {}]
|
72
71
|
end
|
73
72
|
end
|
74
73
|
|
75
74
|
describe '#pop' do
|
76
75
|
it 'removes and return the top frame' do
|
77
|
-
subject.push(:
|
78
|
-
subject.pop.should == {:
|
76
|
+
subject.push(abc: 123)
|
77
|
+
subject.pop.should == { abc: 123 }
|
79
78
|
subject.stack.size.should == 1
|
80
79
|
end
|
81
80
|
end
|
82
81
|
|
83
82
|
describe '#peek' do
|
84
83
|
it 'returns the top frame without removing it' do
|
85
|
-
subject.push(:
|
86
|
-
subject.peek.should == {:
|
84
|
+
subject.push(abc: 123)
|
85
|
+
subject.peek.should == { abc: 123 }
|
87
86
|
subject.stack.size.should == 2
|
88
87
|
end
|
89
88
|
end
|
90
89
|
|
91
90
|
describe '#prepend' do
|
92
91
|
it 'returns a HashStack' do
|
93
|
-
subject.prepend(
|
92
|
+
subject.prepend(Grape::Util::HashStack.new).should be_kind_of(Grape::Util::HashStack)
|
94
93
|
end
|
95
94
|
|
96
95
|
it "prepends a HashStack's stack onto its own stack" do
|
97
|
-
other =
|
98
|
-
subject.prepend(other).stack.should == [{}, {:
|
96
|
+
other = Grape::Util::HashStack.new.push(abc: 123)
|
97
|
+
subject.prepend(other).stack.should == [{}, { abc: 123 }, {}]
|
99
98
|
end
|
100
99
|
end
|
101
100
|
|
102
101
|
describe '#concat' do
|
103
102
|
it 'returns a HashStack' do
|
104
|
-
subject.concat(
|
103
|
+
subject.concat(Grape::Util::HashStack.new).should be_kind_of(Grape::Util::HashStack)
|
105
104
|
end
|
106
105
|
|
107
106
|
it "appends a HashStack's stack onto its own stack" do
|
108
|
-
other =
|
109
|
-
subject.concat(other).stack.should == [{}, {}, {:
|
107
|
+
other = Grape::Util::HashStack.new.push(abc: 123)
|
108
|
+
subject.concat(other).stack.should == [{}, {}, { abc: 123 }]
|
110
109
|
end
|
111
110
|
end
|
112
111
|
|
113
112
|
describe '#update' do
|
114
113
|
it 'merges! into the top frame' do
|
115
|
-
subject.update(:
|
116
|
-
subject.stack.should == [{:
|
114
|
+
subject.update(abc: 123)
|
115
|
+
subject.stack.should == [{ abc: 123 }]
|
117
116
|
end
|
118
117
|
|
119
118
|
it 'returns a HashStack' do
|
120
|
-
subject.update(:
|
119
|
+
subject.update(abc: 123).should be_kind_of(Grape::Util::HashStack)
|
121
120
|
end
|
122
121
|
end
|
123
122
|
|
124
123
|
describe '#clone' do
|
125
124
|
it 'performs a deep copy' do
|
126
125
|
subject[:abc] = 123
|
127
|
-
subject.push :
|
126
|
+
subject.push def: 234
|
128
127
|
clone = subject.clone
|
129
128
|
clone[:def] = 345
|
130
129
|
subject[:def].should == 234
|
@@ -2,45 +2,84 @@
|
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
4
|
describe Grape::Validations::CoerceValidator do
|
5
|
-
subject
|
6
|
-
|
5
|
+
subject do
|
6
|
+
Class.new(Grape::API)
|
7
|
+
end
|
8
|
+
|
9
|
+
def app
|
10
|
+
subject
|
11
|
+
end
|
7
12
|
|
8
13
|
describe 'coerce' do
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
14
|
+
|
15
|
+
context "i18n" do
|
16
|
+
|
17
|
+
after :each do
|
18
|
+
I18n.locale = :en
|
19
|
+
end
|
20
|
+
|
21
|
+
it "i18n error on malformed input" do
|
22
|
+
I18n.load_path << File.expand_path('../zh-CN.yml', __FILE__)
|
23
|
+
I18n.reload!
|
24
|
+
I18n.locale = 'zh-CN'.to_sym
|
25
|
+
subject.params do
|
26
|
+
requires :age, type: Integer
|
27
|
+
end
|
28
|
+
subject.get '/single' do
|
29
|
+
'int works'
|
30
|
+
end
|
31
|
+
|
32
|
+
get '/single', age: '43a'
|
33
|
+
last_response.status.should == 400
|
34
|
+
last_response.body.should == '年龄格式不正确'
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'gives an english fallback error when default locale message is blank' do
|
38
|
+
I18n.locale = 'pt-BR'.to_sym
|
39
|
+
subject.params do
|
40
|
+
requires :age, type: Integer
|
41
|
+
end
|
42
|
+
subject.get '/single' do
|
43
|
+
'int works'
|
44
|
+
end
|
45
|
+
|
46
|
+
get '/single', age: '43a'
|
47
|
+
last_response.status.should == 400
|
48
|
+
last_response.body.should == 'age is invalid'
|
49
|
+
end
|
20
50
|
|
21
51
|
end
|
52
|
+
|
22
53
|
it 'error on malformed input' do
|
23
|
-
subject.params
|
24
|
-
|
54
|
+
subject.params do
|
55
|
+
requires :int, type: Integer
|
56
|
+
end
|
57
|
+
subject.get '/single' do
|
58
|
+
'int works'
|
59
|
+
end
|
25
60
|
|
26
|
-
get '/single', :
|
61
|
+
get '/single', int: '43a'
|
27
62
|
last_response.status.should == 400
|
28
|
-
last_response.body.should == '
|
63
|
+
last_response.body.should == 'int is invalid'
|
29
64
|
|
30
|
-
get '/single', :
|
65
|
+
get '/single', int: '43'
|
31
66
|
last_response.status.should == 200
|
32
67
|
last_response.body.should == 'int works'
|
33
68
|
end
|
34
69
|
|
35
70
|
it 'error on malformed input (Array)' do
|
36
|
-
subject.params
|
37
|
-
|
71
|
+
subject.params do
|
72
|
+
requires :ids, type: Array[Integer]
|
73
|
+
end
|
74
|
+
subject.get '/array' do
|
75
|
+
'array int works'
|
76
|
+
end
|
38
77
|
|
39
|
-
get 'array',
|
78
|
+
get 'array', ids: ['1', '2', 'az']
|
40
79
|
last_response.status.should == 400
|
41
|
-
last_response.body.should == '
|
80
|
+
last_response.body.should == 'ids is invalid'
|
42
81
|
|
43
|
-
get 'array',
|
82
|
+
get 'array', ids: ['1', '2', '890']
|
44
83
|
last_response.status.should == 200
|
45
84
|
last_response.body.should == 'array int works'
|
46
85
|
end
|
@@ -48,21 +87,25 @@ describe Grape::Validations::CoerceValidator do
|
|
48
87
|
context 'complex objects' do
|
49
88
|
module CoerceValidatorSpec
|
50
89
|
class User
|
51
|
-
include Virtus
|
90
|
+
include Virtus.model
|
52
91
|
attribute :id, Integer
|
53
92
|
attribute :name, String
|
54
93
|
end
|
55
94
|
end
|
56
95
|
|
57
96
|
it 'error on malformed input for complex objects' do
|
58
|
-
subject.params
|
59
|
-
|
97
|
+
subject.params do
|
98
|
+
requires :user, type: CoerceValidatorSpec::User
|
99
|
+
end
|
100
|
+
subject.get '/user' do
|
101
|
+
'complex works'
|
102
|
+
end
|
60
103
|
|
61
|
-
get '/user', :
|
104
|
+
get '/user', user: "32"
|
62
105
|
last_response.status.should == 400
|
63
|
-
last_response.body.should == '
|
106
|
+
last_response.body.should == 'user is invalid'
|
64
107
|
|
65
|
-
get '/user', :
|
108
|
+
get '/user', user: { id: 32, name: 'Bob' }
|
66
109
|
last_response.status.should == 200
|
67
110
|
last_response.body.should == 'complex works'
|
68
111
|
end
|
@@ -70,71 +113,93 @@ describe Grape::Validations::CoerceValidator do
|
|
70
113
|
|
71
114
|
context 'coerces' do
|
72
115
|
it 'Integer' do
|
73
|
-
subject.params
|
74
|
-
|
116
|
+
subject.params do
|
117
|
+
requires :int, coerce: Integer
|
118
|
+
end
|
119
|
+
subject.get '/int' do
|
120
|
+
params[:int].class
|
121
|
+
end
|
75
122
|
|
76
|
-
get '/int',
|
123
|
+
get '/int', int: "45"
|
77
124
|
last_response.status.should == 200
|
78
125
|
last_response.body.should == 'Fixnum'
|
79
126
|
end
|
80
127
|
|
81
128
|
it 'Array of Integers' do
|
82
|
-
subject.params
|
83
|
-
|
129
|
+
subject.params do
|
130
|
+
requires :arry, coerce: Array[Integer]
|
131
|
+
end
|
132
|
+
subject.get '/array' do
|
133
|
+
params[:arry][0].class
|
134
|
+
end
|
84
135
|
|
85
|
-
get '/array',
|
136
|
+
get '/array', arry: ['1', '2', '3']
|
86
137
|
last_response.status.should == 200
|
87
138
|
last_response.body.should == 'Fixnum'
|
88
139
|
end
|
89
140
|
|
90
141
|
it 'Array of Bools' do
|
91
|
-
subject.params
|
92
|
-
|
142
|
+
subject.params do
|
143
|
+
requires :arry, coerce: Array[Virtus::Attribute::Boolean]
|
144
|
+
end
|
145
|
+
subject.get '/array' do
|
146
|
+
params[:arry][0].class
|
147
|
+
end
|
93
148
|
|
94
|
-
get 'array',
|
149
|
+
get 'array', arry: [1, 0]
|
95
150
|
last_response.status.should == 200
|
96
151
|
last_response.body.should == 'TrueClass'
|
97
152
|
end
|
98
153
|
|
99
154
|
it 'Bool' do
|
100
|
-
subject.params
|
101
|
-
|
155
|
+
subject.params do
|
156
|
+
requires :bool, coerce: Virtus::Attribute::Boolean
|
157
|
+
end
|
158
|
+
subject.get '/bool' do
|
159
|
+
params[:bool].class
|
160
|
+
end
|
102
161
|
|
103
|
-
get '/bool',
|
162
|
+
get '/bool', bool: 1
|
104
163
|
last_response.status.should == 200
|
105
164
|
last_response.body.should == 'TrueClass'
|
106
165
|
|
107
|
-
get '/bool',
|
166
|
+
get '/bool', bool: 0
|
108
167
|
last_response.status.should == 200
|
109
168
|
last_response.body.should == 'FalseClass'
|
110
169
|
|
111
|
-
get '/bool',
|
170
|
+
get '/bool', bool: 'false'
|
112
171
|
last_response.status.should == 200
|
113
172
|
last_response.body.should == 'FalseClass'
|
114
173
|
|
115
|
-
get '/bool',
|
174
|
+
get '/bool', bool: 'true'
|
116
175
|
last_response.status.should == 200
|
117
176
|
last_response.body.should == 'TrueClass'
|
118
177
|
end
|
119
178
|
|
120
179
|
it 'file' do
|
121
|
-
subject.params
|
122
|
-
|
180
|
+
subject.params do
|
181
|
+
requires :file, coerce: Rack::Multipart::UploadedFile
|
182
|
+
end
|
183
|
+
subject.post '/upload' do
|
184
|
+
params[:file].filename
|
185
|
+
end
|
123
186
|
|
124
|
-
post '/upload',
|
187
|
+
post '/upload', file: Rack::Test::UploadedFile.new(__FILE__)
|
125
188
|
last_response.status.should == 201
|
126
189
|
last_response.body.should == File.basename(__FILE__).to_s
|
127
190
|
end
|
128
191
|
|
129
192
|
it 'Nests integers' do
|
130
193
|
subject.params do
|
131
|
-
|
132
|
-
requires :int, :
|
194
|
+
requires :integers, type: Hash do
|
195
|
+
requires :int, coerce: Integer
|
133
196
|
end
|
134
197
|
end
|
135
|
-
subject.get '/int' do
|
198
|
+
subject.get '/int' do
|
199
|
+
params[:integers][:int].class
|
200
|
+
end
|
136
201
|
|
137
|
-
get '/int',
|
202
|
+
get '/int', integers: { int: "45" }
|
138
203
|
last_response.status.should == 200
|
139
204
|
last_response.body.should == 'Fixnum'
|
140
205
|
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Grape::Validations::DefaultValidator do
|
4
|
+
|
5
|
+
module ValidationsSpec
|
6
|
+
module DefaultValidatorSpec
|
7
|
+
class API < Grape::API
|
8
|
+
default_format :json
|
9
|
+
|
10
|
+
params do
|
11
|
+
optional :id
|
12
|
+
optional :type, default: 'default-type'
|
13
|
+
end
|
14
|
+
get '/' do
|
15
|
+
{ id: params[:id], type: params[:type] }
|
16
|
+
end
|
17
|
+
|
18
|
+
params do
|
19
|
+
optional :type1, default: 'default-type1'
|
20
|
+
optional :type2, default: 'default-type2'
|
21
|
+
end
|
22
|
+
get '/user' do
|
23
|
+
{ type1: params[:type1], type2: params[:type2] }
|
24
|
+
end
|
25
|
+
|
26
|
+
params do
|
27
|
+
requires :id
|
28
|
+
optional :type1, default: 'default-type1'
|
29
|
+
optional :type2, default: 'default-type2'
|
30
|
+
end
|
31
|
+
|
32
|
+
get '/message' do
|
33
|
+
{ id: params[:id], type1: params[:type1], type2: params[:type2] }
|
34
|
+
end
|
35
|
+
|
36
|
+
params do
|
37
|
+
optional :random, default: -> { Random.rand }
|
38
|
+
optional :not_random, default: Random.rand
|
39
|
+
end
|
40
|
+
get '/numbers' do
|
41
|
+
{ random_number: params[:random], non_random_number: params[:non_random_number] }
|
42
|
+
end
|
43
|
+
|
44
|
+
params do
|
45
|
+
# NOTE: The :foo parameter could be made required with json body
|
46
|
+
# params, and then an empty hash would be valid. With query parameters
|
47
|
+
# it must be optional if it isn't provided at all, as otherwise
|
48
|
+
# the validaton for the Hash itself fails because there is no such
|
49
|
+
# thing as an empty hash.
|
50
|
+
optional :foo, type: Hash do
|
51
|
+
optional :bar, default: 'foo-bar'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
get '/group' do
|
55
|
+
{ foo_bar: params[:foo][:bar] }
|
56
|
+
end
|
57
|
+
|
58
|
+
params do
|
59
|
+
optional :array, type: Array do
|
60
|
+
requires :name
|
61
|
+
optional :with_default, default: 'default'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
get '/array' do
|
65
|
+
{ array: params[:array] }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def app
|
72
|
+
ValidationsSpec::DefaultValidatorSpec::API
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'set default value for optional param' do
|
76
|
+
get("/")
|
77
|
+
last_response.status.should == 200
|
78
|
+
last_response.body.should == { id: nil, type: 'default-type' }.to_json
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'set default values for optional params' do
|
82
|
+
get("/user")
|
83
|
+
last_response.status.should == 200
|
84
|
+
last_response.body.should == { type1: 'default-type1', type2: 'default-type2' }.to_json
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'set default values for missing params in the request' do
|
88
|
+
get("/user?type2=value2")
|
89
|
+
last_response.status.should == 200
|
90
|
+
last_response.body.should == { type1: 'default-type1', type2: 'value2' }.to_json
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'set default values for optional params and allow to use required fields in the same time' do
|
94
|
+
get("/message?id=1")
|
95
|
+
last_response.status.should == 200
|
96
|
+
last_response.body.should == { id: '1', type1: 'default-type1', type2: 'default-type2' }.to_json
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'sets lambda based defaults at the time of call' do
|
100
|
+
get("/numbers")
|
101
|
+
last_response.status.should == 200
|
102
|
+
before = JSON.parse(last_response.body)
|
103
|
+
get("/numbers")
|
104
|
+
last_response.status.should == 200
|
105
|
+
after = JSON.parse(last_response.body)
|
106
|
+
|
107
|
+
before['non_random_number'].should == after['non_random_number']
|
108
|
+
before['random_number'].should_not == after['random_number']
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'set default values for optional grouped params' do
|
112
|
+
get('/group')
|
113
|
+
last_response.status.should == 200
|
114
|
+
last_response.body.should == { foo_bar: 'foo-bar' }.to_json
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'sets default values for grouped arrays' do
|
118
|
+
get('/array?array[][name]=name&array[][name]=name2&array[][with_default]=bar2')
|
119
|
+
last_response.status.should == 200
|
120
|
+
last_response.body.should == { array: [{ name: "name", with_default: "default" }, { name: "name2", with_default: "bar2" }] }.to_json
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|