actionpack 1.13.1 → 1.13.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionpack might be problematic. Click here for more details.

@@ -288,11 +288,11 @@ module ActionController #:nodoc:
288
288
  end
289
289
 
290
290
  def [](key)
291
- data[key]
291
+ data[key.to_s]
292
292
  end
293
293
 
294
294
  def []=(key, value)
295
- data[key] = value
295
+ data[key.to_s] = value
296
296
  end
297
297
 
298
298
  def update
@@ -92,7 +92,6 @@ module HTML #:nodoc:
92
92
  # returns non +nil+. Returns the result of the #find call that succeeded.
93
93
  def find(conditions)
94
94
  conditions = validate_conditions(conditions)
95
-
96
95
  @children.each do |child|
97
96
  node = child.find(conditions)
98
97
  return node if node
@@ -152,7 +151,7 @@ module HTML #:nodoc:
152
151
 
153
152
  if scanner.skip(/!\[CDATA\[/)
154
153
  scanner.scan_until(/\]\]>/)
155
- return CDATA.new(parent, line, pos, scanner.pre_match)
154
+ return CDATA.new(parent, line, pos, scanner.pre_match.gsub(/<!\[CDATA\[/, ''))
156
155
  end
157
156
 
158
157
  closing = ( scanner.scan(/\//) ? :close : nil )
@@ -410,7 +409,6 @@ module HTML #:nodoc:
410
409
  # :child => /hello world/ }
411
410
  def match(conditions)
412
411
  conditions = validate_conditions(conditions)
413
-
414
412
  # check content of child nodes
415
413
  if conditions[:content]
416
414
  if children.empty?
@@ -2,7 +2,7 @@ module ActionPack #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 1
4
4
  MINOR = 13
5
- TINY = 1
5
+ TINY = 2
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -387,7 +387,7 @@ module ActionView
387
387
  options["name"] ||= tag_name_with_index(@auto_index)
388
388
  options["id"] ||= tag_id_with_index(@auto_index)
389
389
  else
390
- options["name"] ||= tag_name
390
+ options["name"] ||= tag_name + (options.has_key?('multiple') ? '[]' : '')
391
391
  options["id"] ||= tag_id
392
392
  end
393
393
  end
@@ -94,16 +94,16 @@ module ActionView
94
94
  end
95
95
 
96
96
  # Formats a +number+ with grouped thousands using +delimiter+. You
97
- # can customize the format in the +options+ hash.
98
- # * <tt>:delimiter</tt> - Sets the thousands delimiter, defaults to ","
99
- # * <tt>:separator</tt> - Sets the separator between the units, defaults to "."
97
+ # can customize the format using optional <em>delimiter</em> and <em>separator</em> parameters.
98
+ # * <tt>delimiter</tt> - Sets the thousands delimiter, defaults to ","
99
+ # * <tt>separator</tt> - Sets the separator between the units, defaults to "."
100
100
  #
101
101
  # number_with_delimiter(12345678) => 12,345,678
102
102
  # number_with_delimiter(12345678.05) => 12,345,678.05
103
- # number_with_delimiter(12345678, :delimiter => ".") => 12.345.678
103
+ # number_with_delimiter(12345678, ".") => 12.345.678
104
104
  def number_with_delimiter(number, delimiter=",", separator=".")
105
105
  begin
106
- parts = number.to_s.split(separator)
106
+ parts = number.to_s.split('.')
107
107
  parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}")
108
108
  parts.join separator
109
109
  rescue
@@ -354,26 +354,26 @@ module ActionView
354
354
  @_cycles = Hash.new unless defined?(@_cycles)
355
355
  @_cycles[name] = cycle_object
356
356
  end
357
-
357
+
358
358
  AUTO_LINK_RE = %r{
359
- ( # leading text
360
- <\w+.*?>| # leading HTML tag, or
361
- [^=!:'"/]| # leading punctuation, or
362
- ^ # beginning of line
359
+ ( # leading text
360
+ <\w+.*?>| # leading HTML tag, or
361
+ [^=!:'"/]| # leading punctuation, or
362
+ ^ # beginning of line
363
363
  )
364
364
  (
365
- (?:https?://)| # protocol spec, or
366
- (?:www\.) # www.*
365
+ (?:https?://)| # protocol spec, or
366
+ (?:www\.) # www.*
367
367
  )
368
368
  (
369
- [-\w]+ # subdomain or domain
370
- (?:\.[-\w]+)* # remaining subdomains or domain
371
- (?::\d+)? # port
372
- (?:/(?:[~\w%.;-]+)?)* # path
373
- (?:\?[\w%&=.;-]+)? # query string
374
- (?:\#\w*)? # trailing anchor
369
+ [-\w]+ # subdomain or domain
370
+ (?:\.[-\w]+)* # remaining subdomains or domain
371
+ (?::\d+)? # port
372
+ (?:/(?:(?:[~\w\+%-]|(?:[,.;:][^\s$]))+)?)* # path
373
+ (?:\?[\w\+%&=.;-]+)? # query string
374
+ (?:\#[\w\-]*)? # trailing anchor
375
375
  )
376
- ([[:punct:]]|\s|<|$) # trailing text
376
+ ([[:punct:]]|\s|<|$) # trailing text
377
377
  }x unless const_defined?(:AUTO_LINK_RE)
378
378
 
379
379
  # Turns all urls into clickable links. If a block is given, each url
@@ -13,7 +13,7 @@ unless defined?(ActionMailer)
13
13
  require 'action_mailer'
14
14
  rescue LoadError
15
15
  require 'rubygems'
16
- require_gem 'actionmailer'
16
+ gem 'actionmailer'
17
17
  end
18
18
  end
19
19
 
@@ -2,6 +2,7 @@ require File.dirname(__FILE__) + '/../abstract_unit'
2
2
 
3
3
  class ResourcesController < ActionController::Base
4
4
  def index() render :nothing => true end
5
+ alias_method :show, :index
5
6
  def rescue_action(e) raise e end
6
7
  end
7
8
 
@@ -9,6 +10,8 @@ class ThreadsController < ResourcesController; end
9
10
  class MessagesController < ResourcesController; end
10
11
  class CommentsController < ResourcesController; end
11
12
 
13
+ class AccountController < ResourcesController; end
14
+ class AdminController < ResourcesController; end
12
15
 
13
16
  class ResourcesTest < Test::Unit::TestCase
14
17
  def test_should_arrange_actions
@@ -24,6 +27,23 @@ class ResourcesTest < Test::Unit::TestCase
24
27
  assert_resource_methods [:new, :preview, :draft], resource, :new, :get
25
28
  end
26
29
 
30
+ def test_should_resource_controller_name_equal_resource_name_by_default
31
+ resource = ActionController::Resources::Resource.new(:messages, {})
32
+ assert_equal 'messages', resource.controller
33
+ end
34
+
35
+ def test_should_resource_controller_name_equal_controller_option
36
+ resource = ActionController::Resources::Resource.new(:messages, :controller => 'posts')
37
+ assert_equal 'posts', resource.controller
38
+ end
39
+
40
+ def test_should_all_singleton_paths_be_the_same
41
+ [ :path, :nesting_path_prefix, :member_path ].each do |method|
42
+ resource = ActionController::Resources::SingletonResource.new(:messages, :path_prefix => 'admin')
43
+ assert_equal 'admin/messages', resource.send(method)
44
+ end
45
+ end
46
+
27
47
  def test_default_restful_routes
28
48
  with_restful_routing :messages do
29
49
  assert_simply_restful_for :messages
@@ -113,7 +133,6 @@ class ResourcesTest < Test::Unit::TestCase
113
133
  end
114
134
  end
115
135
 
116
-
117
136
  def test_with_new_action
118
137
  with_restful_routing :messages, :new => { :preview => :post } do
119
138
  preview_options = {:action => 'preview'}
@@ -178,6 +197,121 @@ class ResourcesTest < Test::Unit::TestCase
178
197
  end
179
198
  end
180
199
 
200
+ def test_should_create_singleton_resource_routes
201
+ with_singleton_resources :account do
202
+ assert_singleton_restful_for :account
203
+ end
204
+ end
205
+
206
+ def test_should_create_multiple_singleton_resource_routes
207
+ with_singleton_resources :account, :admin do
208
+ assert_singleton_restful_for :account
209
+ assert_singleton_restful_for :admin
210
+ end
211
+ end
212
+
213
+ def test_should_create_nested_singleton_resource_routes
214
+ with_routing do |set|
215
+ set.draw do |map|
216
+ map.resource :admin do |admin|
217
+ admin.resource :account
218
+ end
219
+ end
220
+
221
+ assert_singleton_restful_for :admin
222
+ assert_singleton_restful_for :account, :path_prefix => 'admin/'
223
+ end
224
+ end
225
+
226
+ def test_singleton_resource_with_member_action
227
+ [:put, :post].each do |method|
228
+ with_singleton_resources :account, :member => { :reset => method } do
229
+ reset_options = {:action => 'reset'}
230
+ reset_path = "/account;reset"
231
+ assert_singleton_routes_for :account do |options|
232
+ assert_recognizes(options.merge(reset_options), :path => reset_path, :method => method)
233
+ end
234
+
235
+ assert_singleton_named_routes_for :account do |options|
236
+ assert_named_route reset_path, :reset_account_path, reset_options
237
+ end
238
+ end
239
+ end
240
+ end
241
+
242
+ def test_singleton_resource_with_two_member_actions_with_same_method
243
+ [:put, :post].each do |method|
244
+ with_singleton_resources :account, :member => { :reset => method, :disable => method } do
245
+ %w(reset disable).each do |action|
246
+ action_options = {:action => action}
247
+ action_path = "/account;#{action}"
248
+ assert_singleton_routes_for :account do |options|
249
+ assert_recognizes(options.merge(action_options), :path => action_path, :method => method)
250
+ end
251
+
252
+ assert_singleton_named_routes_for :account do |options|
253
+ assert_named_route action_path, "#{action}_account_path".to_sym, action_options
254
+ end
255
+ end
256
+ end
257
+ end
258
+ end
259
+
260
+ def test_should_nest_resources_in_singleton_resource
261
+ with_routing do |set|
262
+ set.draw do |map|
263
+ map.resource :account do |account|
264
+ account.resources :messages
265
+ end
266
+ end
267
+
268
+ assert_singleton_restful_for :account
269
+ assert_simply_restful_for :messages, :path_prefix => 'account/'
270
+ end
271
+ end
272
+
273
+ def test_should_nest_resources_in_singleton_resource_with_path_prefix
274
+ with_routing do |set|
275
+ set.draw do |map|
276
+ map.resource(:account, :path_prefix => ':site_id') do |account|
277
+ account.resources :messages
278
+ end
279
+ end
280
+
281
+ assert_singleton_restful_for :account, :path_prefix => '7/', :options => { :site_id => '7' }
282
+ assert_simply_restful_for :messages, :path_prefix => '7/account/', :options => { :site_id => '7' }
283
+ end
284
+ end
285
+
286
+ def test_should_nest_singleton_resource_in_resources
287
+ with_routing do |set|
288
+ set.draw do |map|
289
+ map.resources :threads do |thread|
290
+ thread.resource :admin
291
+ end
292
+ end
293
+
294
+ assert_simply_restful_for :threads
295
+ assert_singleton_restful_for :admin, :path_prefix => 'threads/5/', :options => { :thread_id => '5' }
296
+ end
297
+ end
298
+
299
+ def test_should_not_allow_delete_or_put_on_collection_path
300
+ controller_name = :messages
301
+ with_restful_routing controller_name do
302
+ options = { :controller => controller_name.to_s }
303
+ collection_path = "/#{controller_name}"
304
+
305
+ assert_raises(ActionController::RoutingError) do
306
+ assert_recognizes(options.merge(:action => 'update'), :path => collection_path, :method => :put)
307
+ end
308
+
309
+ assert_raises(ActionController::RoutingError) do
310
+ assert_recognizes(options.merge(:action => 'destroy'), :path => collection_path, :method => :delete)
311
+ end
312
+ end
313
+ end
314
+
181
315
  protected
182
316
  def with_restful_routing(*args)
183
317
  with_routing do |set|
@@ -185,6 +319,13 @@ class ResourcesTest < Test::Unit::TestCase
185
319
  yield
186
320
  end
187
321
  end
322
+
323
+ def with_singleton_resources(*args)
324
+ with_routing do |set|
325
+ set.draw { |map| map.resource(*args) }
326
+ yield
327
+ end
328
+ end
188
329
 
189
330
  # runs assert_restful_routes_for and assert_restful_named_routes for on the controller_name and options, without passing a block.
190
331
  def assert_simply_restful_for(controller_name, options = {})
@@ -192,33 +333,46 @@ class ResourcesTest < Test::Unit::TestCase
192
333
  assert_restful_named_routes_for controller_name, options
193
334
  end
194
335
 
336
+ def assert_singleton_restful_for(singleton_name, options = {})
337
+ assert_singleton_routes_for singleton_name, options
338
+ assert_singleton_named_routes_for singleton_name, options
339
+ end
340
+
195
341
  def assert_restful_routes_for(controller_name, options = {})
196
342
  (options[:options] ||= {})[:controller] = controller_name.to_s
197
343
 
198
- collection_path = "/#{options[:path_prefix]}#{controller_name}"
199
- member_path = "#{collection_path}/1"
200
- new_path = "#{collection_path}/new"
344
+ collection_path = "/#{options[:path_prefix]}#{controller_name}"
345
+ member_path = "#{collection_path}/1"
346
+ new_path = "#{collection_path}/new"
347
+ edit_member_path = "#{member_path};edit"
348
+ formatted_edit_member_path = "#{member_path}.xml;edit"
201
349
 
202
350
  with_options(options[:options]) do |controller|
203
351
  controller.assert_routing collection_path, :action => 'index'
204
- controller.assert_routing "#{collection_path}.xml" , :action => 'index', :format => 'xml'
205
352
  controller.assert_routing new_path, :action => 'new'
206
353
  controller.assert_routing member_path, :action => 'show', :id => '1'
207
- controller.assert_routing "#{member_path};edit", :action => 'edit', :id => '1'
354
+ controller.assert_routing edit_member_path, :action => 'edit', :id => '1'
355
+ controller.assert_routing "#{collection_path}.xml", :action => 'index', :format => 'xml'
356
+ controller.assert_routing "#{new_path}.xml", :action => 'new', :format => 'xml'
208
357
  controller.assert_routing "#{member_path}.xml", :action => 'show', :id => '1', :format => 'xml'
358
+ controller.assert_routing formatted_edit_member_path, :action => 'edit', :id => '1', :format => 'xml'
209
359
  end
210
360
 
211
- assert_recognizes(
212
- options[:options].merge(:action => 'create'),
213
- :path => collection_path, :method => :post)
214
-
215
- assert_recognizes(
216
- options[:options].merge(:action => 'update', :id => '1'),
217
- :path => member_path, :method => :put)
218
-
219
- assert_recognizes(
220
- options[:options].merge(:action => 'destroy', :id => '1'),
221
- :path => member_path, :method => :delete)
361
+ assert_recognizes(options[:options].merge(:action => 'index'), :path => collection_path, :method => :get)
362
+ assert_recognizes(options[:options].merge(:action => 'new'), :path => new_path, :method => :get)
363
+ assert_recognizes(options[:options].merge(:action => 'create'), :path => collection_path, :method => :post)
364
+ assert_recognizes(options[:options].merge(:action => 'show', :id => '1'), :path => member_path, :method => :get)
365
+ assert_recognizes(options[:options].merge(:action => 'edit', :id => '1'), :path => edit_member_path, :method => :get)
366
+ assert_recognizes(options[:options].merge(:action => 'update', :id => '1'), :path => member_path, :method => :put)
367
+ assert_recognizes(options[:options].merge(:action => 'destroy', :id => '1'), :path => member_path, :method => :delete)
368
+
369
+ assert_recognizes(options[:options].merge(:action => 'index', :format => 'xml'), :path => "#{collection_path}.xml", :method => :get)
370
+ assert_recognizes(options[:options].merge(:action => 'new', :format => 'xml'), :path => "#{new_path}.xml", :method => :get)
371
+ assert_recognizes(options[:options].merge(:action => 'create', :format => 'xml'), :path => "#{collection_path}.xml", :method => :post)
372
+ assert_recognizes(options[:options].merge(:action => 'show', :id => '1', :format => 'xml'), :path => "#{member_path}.xml", :method => :get)
373
+ assert_recognizes(options[:options].merge(:action => 'edit', :id => '1', :format => 'xml'), :path => formatted_edit_member_path, :method => :get)
374
+ assert_recognizes(options[:options].merge(:action => 'update', :id => '1', :format => 'xml'), :path => "#{member_path}.xml", :method => :put)
375
+ assert_recognizes(options[:options].merge(:action => 'destroy', :id => '1', :format => 'xml'), :path => "#{member_path}.xml", :method => :delete)
222
376
 
223
377
  yield options[:options] if block_given?
224
378
  end
@@ -240,15 +394,69 @@ class ResourcesTest < Test::Unit::TestCase
240
394
  full_prefix = "/#{options[:path_prefix]}#{controller_name}"
241
395
  name_prefix = options[:name_prefix]
242
396
 
243
- assert_named_route "#{full_prefix}", "#{name_prefix}#{controller_name}_path", options[:options]
244
- assert_named_route "#{full_prefix}.xml", "formatted_#{name_prefix}#{controller_name}_path", options[:options].merge(:format => 'xml')
245
- assert_named_route "#{full_prefix}/new", "#{name_prefix}new_#{singular_name}_path", options[:options]
246
- assert_named_route "#{full_prefix}/1", "#{name_prefix}#{singular_name}_path", options[:options].merge(:id => '1')
247
- assert_named_route "#{full_prefix}/1;edit", "#{name_prefix}edit_#{singular_name}_path", options[:options].merge(:id => '1')
248
- assert_named_route "#{full_prefix}/1.xml", "formatted_#{name_prefix}#{singular_name}_path", options[:options].merge(:format => 'xml', :id => '1')
397
+ assert_named_route "#{full_prefix}", "#{name_prefix}#{controller_name}_path", options[:options]
398
+ assert_named_route "#{full_prefix}/new", "#{name_prefix}new_#{singular_name}_path", options[:options]
399
+ assert_named_route "#{full_prefix}/1", "#{name_prefix}#{singular_name}_path", options[:options].merge(:id => '1')
400
+ assert_named_route "#{full_prefix}/1;edit", "#{name_prefix}edit_#{singular_name}_path", options[:options].merge(:id => '1')
401
+ assert_named_route "#{full_prefix}.xml", "formatted_#{name_prefix}#{controller_name}_path", options[:options].merge( :format => 'xml')
402
+ assert_named_route "#{full_prefix}/new.xml", "formatted_#{name_prefix}new_#{singular_name}_path", options[:options].merge( :format => 'xml')
403
+ assert_named_route "#{full_prefix}/1.xml", "formatted_#{name_prefix}#{singular_name}_path", options[:options].merge(:id => '1', :format => 'xml')
404
+ assert_named_route "#{full_prefix}/1.xml;edit", "formatted_#{name_prefix}edit_#{singular_name}_path", options[:options].merge(:id => '1', :format => 'xml')
405
+ yield options[:options] if block_given?
406
+ end
407
+
408
+ def assert_singleton_routes_for(singleton_name, options = {})
409
+ (options[:options] ||= {})[:controller] ||= singleton_name.to_s
410
+
411
+ full_path = "/#{options[:path_prefix]}#{singleton_name}"
412
+ new_path = "#{full_path}/new"
413
+ edit_path = "#{full_path};edit"
414
+ formatted_edit_path = "#{full_path}.xml;edit"
415
+
416
+ with_options options[:options] do |controller|
417
+ controller.assert_routing full_path, :action => 'show'
418
+ controller.assert_routing new_path, :action => 'new'
419
+ controller.assert_routing edit_path, :action => 'edit'
420
+ controller.assert_routing "#{full_path}.xml", :action => 'show', :format => 'xml'
421
+ controller.assert_routing "#{new_path}.xml", :action => 'new', :format => 'xml'
422
+ controller.assert_routing formatted_edit_path, :action => 'edit', :format => 'xml'
423
+ end
424
+
425
+ assert_recognizes(options[:options].merge(:action => 'show'), :path => full_path, :method => :get)
426
+ assert_recognizes(options[:options].merge(:action => 'new'), :path => new_path, :method => :get)
427
+ assert_recognizes(options[:options].merge(:action => 'edit'), :path => edit_path, :method => :get)
428
+ assert_recognizes(options[:options].merge(:action => 'create'), :path => full_path, :method => :post)
429
+ assert_recognizes(options[:options].merge(:action => 'update'), :path => full_path, :method => :put)
430
+ assert_recognizes(options[:options].merge(:action => 'destroy'), :path => full_path, :method => :delete)
431
+
432
+ assert_recognizes(options[:options].merge(:action => 'show', :format => 'xml'), :path => "#{full_path}.xml", :method => :get)
433
+ assert_recognizes(options[:options].merge(:action => 'new', :format => 'xml'), :path => "#{new_path}.xml", :method => :get)
434
+ assert_recognizes(options[:options].merge(:action => 'edit', :format => 'xml'), :path => formatted_edit_path, :method => :get)
435
+ assert_recognizes(options[:options].merge(:action => 'create', :format => 'xml'), :path => "#{full_path}.xml", :method => :post)
436
+ assert_recognizes(options[:options].merge(:action => 'update', :format => 'xml'), :path => "#{full_path}.xml", :method => :put)
437
+ assert_recognizes(options[:options].merge(:action => 'destroy', :format => 'xml'), :path => "#{full_path}.xml", :method => :delete)
438
+
249
439
  yield options[:options] if block_given?
250
440
  end
251
441
 
442
+ def assert_singleton_named_routes_for(singleton_name, options = {})
443
+ (options[:options] ||= {})[:controller] ||= singleton_name.to_s
444
+ @controller = "#{options[:options][:controller].camelize}Controller".constantize.new
445
+ @request = ActionController::TestRequest.new
446
+ @response = ActionController::TestResponse.new
447
+ get :show, options[:options]
448
+ options[:options].delete :action
449
+
450
+ full_path = "/#{options[:path_prefix]}#{singleton_name}"
451
+
452
+ assert_named_route "#{full_path}", "#{singleton_name}_path", options[:options]
453
+ assert_named_route "#{full_path}/new", "new_#{singleton_name}_path", options[:options]
454
+ assert_named_route "#{full_path};edit", "edit_#{singleton_name}_path", options[:options]
455
+ assert_named_route "#{full_path}.xml", "formatted_#{singleton_name}_path", options[:options].merge(:format => 'xml')
456
+ assert_named_route "#{full_path}/new.xml", "formatted_new_#{singleton_name}_path", options[:options].merge(:format => 'xml')
457
+ assert_named_route "#{full_path}.xml;edit", "formatted_edit_#{singleton_name}_path", options[:options].merge(:format => 'xml')
458
+ end
459
+
252
460
  def assert_named_route(expected, route, options)
253
461
  actual = @controller.send(route, options) rescue $!.class.name
254
462
  assert_equal expected, actual, "Error on route: #{route}(#{options.inspect})"