gin 1.2.0 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.rdoc +9 -0
- data/lib/gin.rb +1 -1
- data/lib/gin/app.rb +7 -0
- data/lib/gin/controller.rb +44 -0
- data/lib/gin/request.rb +32 -6
- data/test/test_controller.rb +103 -0
- data/test/test_request.rb +49 -2
- metadata +3 -3
data/History.rdoc
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
=== 1.2.1 / 2014-03-12
|
2
|
+
|
3
|
+
* Minor Enhancements
|
4
|
+
* Controller.autocast_params to determine if/which params should be typecast
|
5
|
+
* Warn when sprockets isn't found and asset pipeline is enabled
|
6
|
+
|
7
|
+
* Bugfixes
|
8
|
+
* Fix for numeric and boolean param parsing
|
9
|
+
|
1
10
|
=== 1.2.0 / 2013-11-18
|
2
11
|
|
3
12
|
* Major Enhancements
|
data/lib/gin.rb
CHANGED
data/lib/gin/app.rb
CHANGED
@@ -1134,6 +1134,13 @@ class Gin::App
|
|
1134
1134
|
w.run
|
1135
1135
|
w.wait
|
1136
1136
|
end
|
1137
|
+
|
1138
|
+
rescue LoadError => e
|
1139
|
+
raise e unless e =~ /sprockets/
|
1140
|
+
logger << "\nWARNING: #{self.class} asset pipelining is enabled but the \
|
1141
|
+
sprockets gem wasn't found.\nIf you want asset pipelining turned off, add the \
|
1142
|
+
following to your #{self.class} definition:
|
1143
|
+
asset_pipeline false\n\n"
|
1137
1144
|
end
|
1138
1145
|
|
1139
1146
|
|
data/lib/gin/controller.rb
CHANGED
@@ -69,12 +69,14 @@ class Gin::Controller
|
|
69
69
|
|
70
70
|
def self.inherited subclass
|
71
71
|
subclass.setup
|
72
|
+
subclass.autocast_params self.autocast_params
|
72
73
|
super
|
73
74
|
end
|
74
75
|
|
75
76
|
|
76
77
|
def self.setup # :nodoc:
|
77
78
|
@layout = nil
|
79
|
+
@autocast_params = true
|
78
80
|
@ctrl_name = Gin.underscore(self.to_s).gsub(/_?controller_?/,'')
|
79
81
|
end
|
80
82
|
|
@@ -178,6 +180,47 @@ class Gin::Controller
|
|
178
180
|
end
|
179
181
|
|
180
182
|
|
183
|
+
##
|
184
|
+
# Define if params should be cast to autodetected types.
|
185
|
+
# This is an inherited attribute.
|
186
|
+
# * Passing a boolean turns auto-casting on or off for all params.
|
187
|
+
# * Passing a hash with :only or :except limits auto-casting to the
|
188
|
+
# given param names
|
189
|
+
# By default all params are cast to their autodetected types.
|
190
|
+
#
|
191
|
+
# autocast_params true # enabled for all params
|
192
|
+
# autocast_params false # disabled for all params
|
193
|
+
# autocast_params except: [:zip, :phone, :fax]
|
194
|
+
# autocast_params only: [:timestamp, :age]
|
195
|
+
#
|
196
|
+
# Params get cast as follows:
|
197
|
+
# * TrueClass true
|
198
|
+
# * FalseClass: false
|
199
|
+
# * Fixnum: 1234, -1234
|
200
|
+
# * Float: 1.123, -1.123
|
201
|
+
# * String: Everything else, including numbers that start with a 0
|
202
|
+
|
203
|
+
def self.autocast_params arg=nil
|
204
|
+
if Hash === arg && Hash === @autocast_params
|
205
|
+
arg.each do |k, v|
|
206
|
+
if @autocast_params[k]
|
207
|
+
@autocast_params[k] |= [*v]
|
208
|
+
else
|
209
|
+
@autocast_params[k] = [*v]
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
elsif arg == true || arg == false
|
214
|
+
@autocast_params = arg
|
215
|
+
|
216
|
+
elsif Hash === arg
|
217
|
+
@autocast_params = arg.dup
|
218
|
+
end
|
219
|
+
|
220
|
+
return @autocast_params
|
221
|
+
end
|
222
|
+
|
223
|
+
|
181
224
|
class_rproxy :controller_name, :actions
|
182
225
|
|
183
226
|
# The Gin::App instance used by the controller. The App instance is meant for
|
@@ -203,6 +246,7 @@ class Gin::Controller
|
|
203
246
|
@env = env
|
204
247
|
@request = Gin::Request.new env
|
205
248
|
@response = Gin::Response.new
|
249
|
+
@request.autocast_params = self.class.autocast_params
|
206
250
|
end
|
207
251
|
|
208
252
|
|
data/lib/gin/request.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
class Gin::Request < Rack::Request
|
2
2
|
include Gin::Constants
|
3
3
|
|
4
|
+
attr_accessor :autocast_params # :nodoc:
|
5
|
+
|
4
6
|
def initialize env
|
7
|
+
@params = nil
|
8
|
+
@params_processed = false
|
9
|
+
@autocast_params = true
|
5
10
|
super
|
6
|
-
self.params.update env[GIN_PATH_PARAMS] if env[GIN_PATH_PARAMS]
|
7
11
|
end
|
8
12
|
|
9
13
|
|
@@ -28,7 +32,12 @@ class Gin::Request < Rack::Request
|
|
28
32
|
|
29
33
|
|
30
34
|
def params
|
31
|
-
@params
|
35
|
+
return @params if @params_processed
|
36
|
+
@params = super
|
37
|
+
@params.update @env[GIN_PATH_PARAMS] if @env[GIN_PATH_PARAMS]
|
38
|
+
@params = process_params(@params)
|
39
|
+
@params_processed = true
|
40
|
+
@params
|
32
41
|
end
|
33
42
|
|
34
43
|
|
@@ -45,19 +54,23 @@ class Gin::Request < Rack::Request
|
|
45
54
|
|
46
55
|
private
|
47
56
|
|
48
|
-
M_BOOLEAN = /^true|false$/
|
49
|
-
M_FLOAT = /^-?([
|
50
|
-
M_INTEGER = /^-?([
|
57
|
+
M_BOOLEAN = /^(true|false)$/ #:nodoc:
|
58
|
+
M_FLOAT = /^-?([1-9]\d+|\d)\.\d+$/ #:nodoc:
|
59
|
+
M_INTEGER = /^-?([1-9]\d+|\d)$/ #:nodoc:
|
51
60
|
|
52
61
|
##
|
53
62
|
# Enable string or symbol key access to the nested params hash.
|
54
63
|
# Make String numbers into Numerics.
|
55
64
|
|
56
65
|
def process_params object
|
66
|
+
return object unless @autocast_params
|
67
|
+
|
57
68
|
case object
|
58
69
|
when Hash
|
59
70
|
new_hash = Gin::StrictHash.new
|
60
|
-
object.each
|
71
|
+
object.each do |key, value|
|
72
|
+
new_hash[key] = process_param?(key) ? process_params(value) : value
|
73
|
+
end
|
61
74
|
new_hash
|
62
75
|
when Array
|
63
76
|
object.map { |item| process_params(item) }
|
@@ -71,4 +84,17 @@ class Gin::Request < Rack::Request
|
|
71
84
|
object
|
72
85
|
end
|
73
86
|
end
|
87
|
+
|
88
|
+
|
89
|
+
def process_param? name
|
90
|
+
if Hash === @autocast_params
|
91
|
+
return false if @autocast_params[:except] &&
|
92
|
+
@autocast_params[:except].include?(name.to_sym)
|
93
|
+
|
94
|
+
return @autocast_params[:only].include?(name.to_sym) if
|
95
|
+
@autocast_params[:only]
|
96
|
+
end
|
97
|
+
|
98
|
+
!!@autocast_params
|
99
|
+
end
|
74
100
|
end
|
data/test/test_controller.rb
CHANGED
@@ -132,6 +132,109 @@ class ControllerTest < Test::Unit::TestCase
|
|
132
132
|
end
|
133
133
|
|
134
134
|
|
135
|
+
def test_autocast_params
|
136
|
+
rack_env['QUERY_STRING'] =
|
137
|
+
'id=456&foo=bar&bar=5&bool=true&nbool=truefalse&zip=01234&nint=m3&nflt=01.123&neg=-12&negf=-2.1'
|
138
|
+
|
139
|
+
klass = Class.new(AppController)
|
140
|
+
params = klass.new(@app, rack_env).params
|
141
|
+
|
142
|
+
assert_equal true, params['bool']
|
143
|
+
assert_equal 'truefalse', params['nbool']
|
144
|
+
assert_equal 'bar', params['foo']
|
145
|
+
assert_equal 5, params['bar']
|
146
|
+
assert_equal '01234', params['zip']
|
147
|
+
assert_equal 'm3', params['nint']
|
148
|
+
assert_equal '01.123', params['nflt']
|
149
|
+
assert_equal -12, params['neg']
|
150
|
+
assert_equal -2.1, params['negf']
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
def test_autocast_params_off
|
155
|
+
rack_env['QUERY_STRING'] =
|
156
|
+
'id=456&foo=bar&bar=5&bool=true&nbool=truefalse&zip=01234&nint=m3&nflt=01.123&neg=-12&negf=-2.1'
|
157
|
+
|
158
|
+
klass = Class.new(AppController)
|
159
|
+
klass.autocast_params false
|
160
|
+
params = klass.new(@app, rack_env).params
|
161
|
+
|
162
|
+
assert_equal 'true', params['bool']
|
163
|
+
assert_equal 'truefalse', params['nbool']
|
164
|
+
assert_equal 'bar', params['foo']
|
165
|
+
assert_equal '5', params['bar']
|
166
|
+
assert_equal '01234', params['zip']
|
167
|
+
assert_equal 'm3', params['nint']
|
168
|
+
assert_equal '01.123', params['nflt']
|
169
|
+
assert_equal '-12', params['neg']
|
170
|
+
assert_equal '-2.1', params['negf']
|
171
|
+
end
|
172
|
+
|
173
|
+
|
174
|
+
def test_autocast_params_only
|
175
|
+
rack_env['QUERY_STRING'] =
|
176
|
+
'foo=bar&bar=5&bool=true&nbool=truefalse&zip=01234&nint=m3&nflt=01.123&neg=-12&negf=-2.1'
|
177
|
+
|
178
|
+
klass = Class.new(AppController)
|
179
|
+
klass.autocast_params :only => [:bool, :bar, :zip]
|
180
|
+
params = klass.new(@app, rack_env).params
|
181
|
+
|
182
|
+
assert_equal true, params['bool']
|
183
|
+
assert_equal 'truefalse', params['nbool']
|
184
|
+
assert_equal 'bar', params['foo']
|
185
|
+
assert_equal 5, params['bar']
|
186
|
+
assert_equal '01234', params['zip']
|
187
|
+
assert_equal 'm3', params['nint']
|
188
|
+
assert_equal '01.123', params['nflt']
|
189
|
+
assert_equal '-12', params['neg']
|
190
|
+
assert_equal '-2.1', params['negf']
|
191
|
+
end
|
192
|
+
|
193
|
+
|
194
|
+
def test_autocast_params_except
|
195
|
+
rack_env['QUERY_STRING'] =
|
196
|
+
'id=456&foo=bar&bar=5&bool=true&nbool=truefalse&zip=01234&nint=m3&nflt=01.123&neg=-12&negf=-2.1'
|
197
|
+
|
198
|
+
klass = Class.new(AppController)
|
199
|
+
klass.autocast_params :except => [:bool, :bar, :zip]
|
200
|
+
params = klass.new(@app, rack_env).params
|
201
|
+
|
202
|
+
assert_equal 'true', params['bool']
|
203
|
+
assert_equal 'truefalse', params['nbool']
|
204
|
+
assert_equal 'bar', params['foo']
|
205
|
+
assert_equal '5', params['bar']
|
206
|
+
assert_equal '01234', params['zip']
|
207
|
+
assert_equal 'm3', params['nint']
|
208
|
+
assert_equal '01.123', params['nflt']
|
209
|
+
assert_equal -12, params['neg']
|
210
|
+
assert_equal -2.1, params['negf']
|
211
|
+
end
|
212
|
+
|
213
|
+
|
214
|
+
def test_autocast_params_inherit
|
215
|
+
rack_env['QUERY_STRING'] =
|
216
|
+
'foo=bar&bar=5&bool=true&nbool=truefalse&zip=01234&nint=m3&nflt=01.123&neg=-12&negf=-2.1'
|
217
|
+
|
218
|
+
klass = Class.new(AppController)
|
219
|
+
klass.autocast_params :only => [:bool, :bar, :zip]
|
220
|
+
|
221
|
+
subklass = Class.new(klass)
|
222
|
+
subklass.autocast_params :only => :neg
|
223
|
+
|
224
|
+
params = klass.new(@app, rack_env).params
|
225
|
+
|
226
|
+
assert_equal true, params['bool']
|
227
|
+
assert_equal 5, params['bar']
|
228
|
+
assert_equal '-12', params['neg']
|
229
|
+
|
230
|
+
params = subklass.new(@app, rack_env).params
|
231
|
+
|
232
|
+
assert_equal true, params['bool']
|
233
|
+
assert_equal 5, params['bar']
|
234
|
+
assert_equal -12, params['neg']
|
235
|
+
end
|
236
|
+
|
237
|
+
|
135
238
|
def test_class_layout
|
136
239
|
assert_equal :foo, BarController.layout
|
137
240
|
assert_equal :foo, AppController.layout
|
data/test/test_request.rb
CHANGED
@@ -7,8 +7,8 @@ class RequestTest < Test::Unit::TestCase
|
|
7
7
|
'HTTP_HOST' => 'example.com',
|
8
8
|
'rack.input' => '',
|
9
9
|
'QUERY_STRING' =>
|
10
|
-
'id=456&foo=bar&bar=5&bool=true&zip=01234&nflt=01.123&neg=-12&negf=-2.1',
|
11
|
-
'gin.path_query_hash' => {'id' => 123},
|
10
|
+
'id=456&foo=bar&bar=5&bool=true&nbool=truefalse&zip=01234&nint=m3&nflt=01.123&neg=-12&negf=-2.1',
|
11
|
+
'gin.path_query_hash' => {'id' => 123, 'age' => '22'},
|
12
12
|
}
|
13
13
|
@req = Gin::Request.new @env
|
14
14
|
end
|
@@ -16,9 +16,55 @@ class RequestTest < Test::Unit::TestCase
|
|
16
16
|
|
17
17
|
def test_query_hash_as_param
|
18
18
|
assert_equal 123, @req.params['id']
|
19
|
+
assert_equal 22, @req.params['age']
|
20
|
+
assert_equal true, @req.params['bool']
|
21
|
+
assert_equal 'truefalse', @req.params['nbool']
|
19
22
|
assert_equal 'bar', @req.params['foo']
|
20
23
|
assert_equal 5, @req.params['bar']
|
21
24
|
assert_equal '01234', @req.params['zip']
|
25
|
+
assert_equal 'm3', @req.params['nint']
|
26
|
+
assert_equal '01.123', @req.params['nflt']
|
27
|
+
assert_equal -12, @req.params['neg']
|
28
|
+
assert_equal -2.1, @req.params['negf']
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
def test_query_hash_as_param_w_autocast_off
|
33
|
+
@req.autocast_params = false
|
34
|
+
assert_equal '22', @req.params['age']
|
35
|
+
assert_equal 'true', @req.params['bool']
|
36
|
+
assert_equal 'bar', @req.params['foo']
|
37
|
+
assert_equal '5', @req.params['bar']
|
38
|
+
assert_equal '01234', @req.params['zip']
|
39
|
+
assert_equal 'm3', @req.params['nint']
|
40
|
+
assert_equal '01.123', @req.params['nflt']
|
41
|
+
assert_equal '-12', @req.params['neg']
|
42
|
+
assert_equal '-2.1', @req.params['negf']
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
def test_query_hash_as_param_w_autocast_only
|
47
|
+
@req.autocast_params = {:only => [:age, :bool, :zip]}
|
48
|
+
assert_equal 22, @req.params['age']
|
49
|
+
assert_equal true, @req.params['bool']
|
50
|
+
assert_equal 'bar', @req.params['foo']
|
51
|
+
assert_equal '5', @req.params['bar']
|
52
|
+
assert_equal '01234', @req.params['zip']
|
53
|
+
assert_equal 'm3', @req.params['nint']
|
54
|
+
assert_equal '01.123', @req.params['nflt']
|
55
|
+
assert_equal '-12', @req.params['neg']
|
56
|
+
assert_equal '-2.1', @req.params['negf']
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
def test_query_hash_as_param_w_autocast_except
|
61
|
+
@req.autocast_params = {:except => [:age, :bool, :zip]}
|
62
|
+
assert_equal '22', @req.params['age']
|
63
|
+
assert_equal 'true', @req.params['bool']
|
64
|
+
assert_equal 'bar', @req.params['foo']
|
65
|
+
assert_equal 5, @req.params['bar']
|
66
|
+
assert_equal '01234', @req.params['zip']
|
67
|
+
assert_equal 'm3', @req.params['nint']
|
22
68
|
assert_equal '01.123', @req.params['nflt']
|
23
69
|
assert_equal -12, @req.params['neg']
|
24
70
|
assert_equal -2.1, @req.params['negf']
|
@@ -74,6 +120,7 @@ class RequestTest < Test::Unit::TestCase
|
|
74
120
|
assert_equal false, @req.send(:process_params, "false")
|
75
121
|
assert_equal 1, @req.send(:process_params, "1")
|
76
122
|
assert_equal 1.1, @req.send(:process_params, "1.1")
|
123
|
+
assert_equal "w1", @req.send(:process_params, "w1")
|
77
124
|
assert_equal "not_true", @req.send(:process_params, "not_true")
|
78
125
|
|
79
126
|
ary = @req.send(:process_params, ["true", "1", "foo"])
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2014-03-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|
@@ -232,7 +232,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
232
232
|
version: '0'
|
233
233
|
segments:
|
234
234
|
- 0
|
235
|
-
hash: -
|
235
|
+
hash: -1291900085741485412
|
236
236
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
237
237
|
none: false
|
238
238
|
requirements:
|