Commit b9846d60741788e84c889077d9b3b4786ba31042
1 parent
0088a8d8
Exists in
master
and in
28 other branches
ActionItem135: upgrading to rails 1.2.6; all tests pass
git-svn-id: https://svn.colivre.coop.br/svn/noosfero/trunk@1103 3f533792-8f58-4932-b0fe-aaf55b0a4547
Showing
127 changed files
with
2801 additions
and
565 deletions
Show diff stats
Too many changes.
To preserve performance only 100 of 127 files displayed.
vendor/rails/actionmailer/CHANGELOG
| 1 | +*1.3.6* (October 12th, 2007) | ||
| 2 | + | ||
| 3 | +* Depend on Action Pack 1.13.6 | ||
| 4 | + | ||
| 5 | +*1.3.5* (October 12th, 2007) | ||
| 6 | + | ||
| 7 | +* Depend on Action Pack 1.13.5 | ||
| 8 | + | ||
| 9 | + | ||
| 10 | +*1.3.4* (October 4th, 2007) | ||
| 11 | + | ||
| 12 | +* Depend on Action Pack 1.13.4 | ||
| 13 | + | ||
| 14 | + | ||
| 1 | *1.3.3* (March 12th, 2007) | 15 | *1.3.3* (March 12th, 2007) |
| 2 | 16 | ||
| 3 | * Depend on Action Pack 1.13.3 | 17 | * Depend on Action Pack 1.13.3 |
vendor/rails/actionmailer/Rakefile
| @@ -54,7 +54,7 @@ spec = Gem::Specification.new do |s| | @@ -54,7 +54,7 @@ spec = Gem::Specification.new do |s| | ||
| 54 | s.rubyforge_project = "actionmailer" | 54 | s.rubyforge_project = "actionmailer" |
| 55 | s.homepage = "http://www.rubyonrails.org" | 55 | s.homepage = "http://www.rubyonrails.org" |
| 56 | 56 | ||
| 57 | - s.add_dependency('actionpack', '= 1.13.3' + PKG_BUILD) | 57 | + s.add_dependency('actionpack', '= 1.13.6' + PKG_BUILD) |
| 58 | 58 | ||
| 59 | s.has_rdoc = true | 59 | s.has_rdoc = true |
| 60 | s.requirements << 'none' | 60 | s.requirements << 'none' |
vendor/rails/actionmailer/lib/action_mailer/version.rb
vendor/rails/actionpack/CHANGELOG
| 1 | +*1.13.6* (November 24th, 2007) | ||
| 2 | + | ||
| 3 | +* Correct Broken Fix for session_fixation attacks | ||
| 4 | + | ||
| 5 | +* Ensure that cookies handle array values correctly. Closes #9937 [queso] | ||
| 6 | + | ||
| 7 | +*1.13.5* (October 12th, 2007) | ||
| 8 | + | ||
| 9 | +* Backport: allow array and hash query parameters. Array route parameters are converted/to/a/path as before. #6765, #7047, #7462 [bgipsy, Jeremy McAnally, Dan Kubb, brendan, Diego Algorta Casamayou] | ||
| 10 | + | ||
| 11 | +* Fix in place editor's setter action with non-string fields. #7418 [Andreas] | ||
| 12 | + | ||
| 13 | + | ||
| 14 | +*1.13.4* (October 4th, 2007) | ||
| 15 | + | ||
| 16 | +* Only accept session ids from cookies, prevents session fixation attacks. [bradediger] | ||
| 17 | + | ||
| 18 | +* Change the resource seperator from ; to / change the generated routes to use the new-style named routes. e.g. new_group_user_path(@group) instead of group_new_user_path(@group). [pixeltrix] | ||
| 19 | + | ||
| 20 | +* Integration tests: introduce methods for other HTTP methods. #6353 [caboose] | ||
| 21 | + | ||
| 22 | +* Improve performance of action caching. Closes #8231 [skaes] | ||
| 23 | + | ||
| 24 | +* Fix errors with around_filters which do not yield, restore 1.1 behaviour with after filters. Closes #8891 [skaes] | ||
| 25 | + | ||
| 26 | + After filters will *no longer* be run if an around_filter fails to yield, users relying on | ||
| 27 | + this behaviour are advised to put the code in question after a yield statement in an around filter. | ||
| 28 | + | ||
| 29 | +* Allow you to delete cookies with options. Closes #3685 [josh, Chris Wanstrath] | ||
| 30 | + | ||
| 31 | +* Deprecate pagination. Install the classic_pagination plugin for forward compatibility, or move to the superior will_paginate plugin. #8157 [Mislav Marohnic] | ||
| 32 | + | ||
| 33 | +* Fix filtered parameter logging with nil parameter values. #8422 [choonkeat] | ||
| 34 | + | ||
| 35 | +* Integration tests: alias xhr to xml_http_request and add a request_method argument instead of always using POST. #7124 [Nik Wakelin, Francois Beausoleil, Wizard] | ||
| 36 | + | ||
| 37 | +* Document caches_action. #5419 [Jarkko Laine] | ||
| 38 | + | ||
| 39 | +* observe_form always sends the serialized form. #5271 [manfred, normelton@gmail.com] | ||
| 40 | + | ||
| 41 | +* Update UrlWriter to accept :anchor parameter. Closes #6771. [octopod] | ||
| 42 | + | ||
| 43 | +* Replace the current block/continuation filter chain handling by an implementation based on a simple loop. Closes #8226 [Stefan Kaes] | ||
| 44 | + | ||
| 45 | +* Return the string representation from an Xml Builder when rendering a partial. #5044 [tpope] | ||
| 46 | + | ||
| 47 | +* Cleaned up, corrected, and mildly expanded ActionPack documentation. Closes #7190 [jeremymcanally] | ||
| 48 | + | ||
| 49 | +* Small collection of ActionController documentation cleanups. Closes #7319 [jeremymcanally] | ||
| 50 | + | ||
| 51 | +* Performance: patch cgi/session/pstore to require digest/md5 once rather than per #initialize. #7583 [Stefan Kaes] | ||
| 52 | + | ||
| 53 | +* Deprecation: verification with :redirect_to => :named_route shouldn't be deprecated. #7525 [Justin French] | ||
| 54 | + | ||
| 55 | + | ||
| 1 | *1.13.3* (March 12th, 2007) | 56 | *1.13.3* (March 12th, 2007) |
| 2 | 57 | ||
| 3 | -* Apply [5709] to stable. | 58 | +* Fix a bug in Routing where a parameter taken from the path of the current request could not be used as a query parameter for the next. #6752 [Nicholas Seckar] |
| 4 | 59 | ||
| 5 | * session_enabled? works with session :off. #6680 [Catfish] | 60 | * session_enabled? works with session :off. #6680 [Catfish] |
| 6 | 61 | ||
| @@ -440,7 +495,7 @@ | @@ -440,7 +495,7 @@ | ||
| 440 | 495 | ||
| 441 | * Avoid naming collision among compiled view methods. [Jeremy Kemper] | 496 | * Avoid naming collision among compiled view methods. [Jeremy Kemper] |
| 442 | 497 | ||
| 443 | -* Fix CGI extensions when they expect string but get nil in Windows. Closes #5276 [mislav@nippur.irb.hr] | 498 | +* Fix CGI extensions when they expect string but get nil in Windows. Closes #5276 [Mislav Marohnic] |
| 444 | 499 | ||
| 445 | * Determine the correct template_root for deeply nested components. #2841 [s.brink@web.de] | 500 | * Determine the correct template_root for deeply nested components. #2841 [s.brink@web.de] |
| 446 | 501 |
vendor/rails/actionpack/Rakefile
| @@ -75,7 +75,7 @@ spec = Gem::Specification.new do |s| | @@ -75,7 +75,7 @@ spec = Gem::Specification.new do |s| | ||
| 75 | s.has_rdoc = true | 75 | s.has_rdoc = true |
| 76 | s.requirements << 'none' | 76 | s.requirements << 'none' |
| 77 | 77 | ||
| 78 | - s.add_dependency('activesupport', '= 1.4.2' + PKG_BUILD) | 78 | + s.add_dependency('activesupport', '= 1.4.4' + PKG_BUILD) |
| 79 | 79 | ||
| 80 | s.require_path = 'lib' | 80 | s.require_path = 'lib' |
| 81 | s.autorequire = 'action_controller' | 81 | s.autorequire = 'action_controller' |
vendor/rails/actionpack/examples/address_book_controller.cgi
vendor/rails/actionpack/examples/address_book_controller.fcgi
vendor/rails/actionpack/examples/address_book_controller.rbx
vendor/rails/actionpack/examples/benchmark_with_ar.fcgi
vendor/rails/actionpack/examples/blog_controller.cgi
vendor/rails/actionpack/examples/debate_controller.cgi
vendor/rails/actionpack/lib/action_controller/assertions/dom_assertions.rb
| 1 | module ActionController | 1 | module ActionController |
| 2 | module Assertions | 2 | module Assertions |
| 3 | module DomAssertions | 3 | module DomAssertions |
| 4 | - # test 2 html strings to be equivalent, i.e. identical up to reordering of attributes | 4 | + # Test two HTML strings for equivalency (e.g., identical up to reordering of attributes) |
| 5 | def assert_dom_equal(expected, actual, message="") | 5 | def assert_dom_equal(expected, actual, message="") |
| 6 | clean_backtrace do | 6 | clean_backtrace do |
| 7 | expected_dom = HTML::Document.new(expected).root | 7 | expected_dom = HTML::Document.new(expected).root |
| @@ -11,7 +11,7 @@ module ActionController | @@ -11,7 +11,7 @@ module ActionController | ||
| 11 | end | 11 | end |
| 12 | end | 12 | end |
| 13 | 13 | ||
| 14 | - # negated form of +assert_dom_equivalent+ | 14 | + # The negated form of +assert_dom_equivalent+. |
| 15 | def assert_dom_not_equal(expected, actual, message="") | 15 | def assert_dom_not_equal(expected, actual, message="") |
| 16 | clean_backtrace do | 16 | clean_backtrace do |
| 17 | expected_dom = HTML::Document.new(expected).root | 17 | expected_dom = HTML::Document.new(expected).root |
vendor/rails/actionpack/lib/action_controller/assertions/model_assertions.rb
| 1 | module ActionController | 1 | module ActionController |
| 2 | module Assertions | 2 | module Assertions |
| 3 | module ModelAssertions | 3 | module ModelAssertions |
| 4 | - # ensures that the passed record is valid by active record standards. returns the error messages if not | 4 | + # Ensures that the passed record is valid by ActiveRecord standards and returns any error messages if it is not. |
| 5 | def assert_valid(record) | 5 | def assert_valid(record) |
| 6 | clean_backtrace do | 6 | clean_backtrace do |
| 7 | assert record.valid?, record.errors.full_messages.join("\n") | 7 | assert record.valid?, record.errors.full_messages.join("\n") |
vendor/rails/actionpack/lib/action_controller/assertions/response_assertions.rb
| @@ -69,6 +69,7 @@ module ActionController | @@ -69,6 +69,7 @@ module ActionController | ||
| 69 | end | 69 | end |
| 70 | 70 | ||
| 71 | if value.respond_to?(:[]) && value['controller'] | 71 | if value.respond_to?(:[]) && value['controller'] |
| 72 | + value['controller'] = value['controller'].to_s | ||
| 72 | if key == :actual && value['controller'].first != '/' && !value['controller'].include?('/') | 73 | if key == :actual && value['controller'].first != '/' && !value['controller'].include?('/') |
| 73 | new_controller_path = ActionController::Routing.controller_relative_to(value['controller'], @controller.class.controller_path) | 74 | new_controller_path = ActionController::Routing.controller_relative_to(value['controller'], @controller.class.controller_path) |
| 74 | value['controller'] = new_controller_path if value['controller'] != new_controller_path && ActionController::Routing.possible_controllers.include?(new_controller_path) | 75 | value['controller'] = new_controller_path if value['controller'] != new_controller_path && ActionController::Routing.possible_controllers.include?(new_controller_path) |
| @@ -120,6 +121,7 @@ module ActionController | @@ -120,6 +121,7 @@ module ActionController | ||
| 120 | end | 121 | end |
| 121 | 122 | ||
| 122 | private | 123 | private |
| 124 | + # Recognizes the route for a given path. | ||
| 123 | def recognized_request_for(path, request_method = nil) | 125 | def recognized_request_for(path, request_method = nil) |
| 124 | path = "/#{path}" unless path.first == '/' | 126 | path = "/#{path}" unless path.first == '/' |
| 125 | 127 | ||
| @@ -132,6 +134,7 @@ module ActionController | @@ -132,6 +134,7 @@ module ActionController | ||
| 132 | request | 134 | request |
| 133 | end | 135 | end |
| 134 | 136 | ||
| 137 | + # Proxy to to_param if the object will respond to it. | ||
| 135 | def parameterize(value) | 138 | def parameterize(value) |
| 136 | value.respond_to?(:to_param) ? value.to_param : value | 139 | value.respond_to?(:to_param) ? value.to_param : value |
| 137 | end | 140 | end |
vendor/rails/actionpack/lib/action_controller/assertions/routing_assertions.rb
| @@ -82,6 +82,7 @@ module ActionController | @@ -82,6 +82,7 @@ module ActionController | ||
| 82 | end | 82 | end |
| 83 | 83 | ||
| 84 | private | 84 | private |
| 85 | + # Recognizes the route for a given path. | ||
| 85 | def recognized_request_for(path, request_method = nil) | 86 | def recognized_request_for(path, request_method = nil) |
| 86 | path = "/#{path}" unless path.first == '/' | 87 | path = "/#{path}" unless path.first == '/' |
| 87 | 88 |
vendor/rails/actionpack/lib/action_controller/assertions/selector_assertions.rb
| @@ -561,6 +561,8 @@ module ActionController | @@ -561,6 +561,8 @@ module ActionController | ||
| 561 | # RJS encodes double quotes and line breaks. | 561 | # RJS encodes double quotes and line breaks. |
| 562 | unescaped= rjs_string.gsub('\"', '"') | 562 | unescaped= rjs_string.gsub('\"', '"') |
| 563 | unescaped.gsub!('\n', "\n") | 563 | unescaped.gsub!('\n', "\n") |
| 564 | + unescaped.gsub!('\076', '>') | ||
| 565 | + unescaped.gsub!('\074', '<') | ||
| 564 | # RJS encodes non-ascii characters. | 566 | # RJS encodes non-ascii characters. |
| 565 | unescaped.gsub!(RJS_PATTERN_UNICODE_ESCAPED_CHAR) {|u| [$1.hex].pack('U*')} | 567 | unescaped.gsub!(RJS_PATTERN_UNICODE_ESCAPED_CHAR) {|u| [$1.hex].pack('U*')} |
| 566 | unescaped | 568 | unescaped |
vendor/rails/actionpack/lib/action_controller/base.rb
| @@ -292,6 +292,10 @@ module ActionController #:nodoc: | @@ -292,6 +292,10 @@ module ActionController #:nodoc: | ||
| 292 | # Turn on +ignore_missing_templates+ if you want to unit test actions without making the associated templates. | 292 | # Turn on +ignore_missing_templates+ if you want to unit test actions without making the associated templates. |
| 293 | cattr_accessor :ignore_missing_templates | 293 | cattr_accessor :ignore_missing_templates |
| 294 | 294 | ||
| 295 | + # Controls the resource action separator | ||
| 296 | + @@resource_action_separator = "/" | ||
| 297 | + cattr_accessor :resource_action_separator | ||
| 298 | + | ||
| 295 | # Holds the request object that's primarily used to get environment variables through access like | 299 | # Holds the request object that's primarily used to get environment variables through access like |
| 296 | # <tt>request.env["REQUEST_URI"]</tt>. | 300 | # <tt>request.env["REQUEST_URI"]</tt>. |
| 297 | attr_internal :request | 301 | attr_internal :request |
| @@ -393,7 +397,8 @@ module ActionController #:nodoc: | @@ -393,7 +397,8 @@ module ActionController #:nodoc: | ||
| 393 | elsif value.is_a?(Hash) | 397 | elsif value.is_a?(Hash) |
| 394 | filtered_parameters[key] = filter_parameters(value) | 398 | filtered_parameters[key] = filter_parameters(value) |
| 395 | elsif block_given? | 399 | elsif block_given? |
| 396 | - key, value = key.dup, value.dup | 400 | + key = key.dup |
| 401 | + value = value.dup if value | ||
| 397 | yield key, value | 402 | yield key, value |
| 398 | filtered_parameters[key] = value | 403 | filtered_parameters[key] = value |
| 399 | else | 404 | else |
| @@ -538,6 +543,7 @@ module ActionController #:nodoc: | @@ -538,6 +543,7 @@ module ActionController #:nodoc: | ||
| 538 | self.class.controller_path | 543 | self.class.controller_path |
| 539 | end | 544 | end |
| 540 | 545 | ||
| 546 | + # Test whether the session is enabled for this request. | ||
| 541 | def session_enabled? | 547 | def session_enabled? |
| 542 | request.session_options && request.session_options[:disabled] != false | 548 | request.session_options && request.session_options[:disabled] != false |
| 543 | end | 549 | end |
vendor/rails/actionpack/lib/action_controller/caching.rb
| 1 | require 'fileutils' | 1 | require 'fileutils' |
| 2 | require 'uri' | 2 | require 'uri' |
| 3 | +require 'set' | ||
| 3 | 4 | ||
| 4 | module ActionController #:nodoc: | 5 | module ActionController #:nodoc: |
| 5 | # Caching is a cheap way of speeding up slow applications by keeping the result of calculations, renderings, and database calls | 6 | # Caching is a cheap way of speeding up slow applications by keeping the result of calculations, renderings, and database calls |
| @@ -163,13 +164,24 @@ module ActionController #:nodoc: | @@ -163,13 +164,24 @@ module ActionController #:nodoc: | ||
| 163 | module Actions | 164 | module Actions |
| 164 | def self.included(base) #:nodoc: | 165 | def self.included(base) #:nodoc: |
| 165 | base.extend(ClassMethods) | 166 | base.extend(ClassMethods) |
| 166 | - base.send(:attr_accessor, :rendered_action_cache) | 167 | + base.class_eval do |
| 168 | + attr_accessor :rendered_action_cache, :action_cache_path | ||
| 169 | + alias_method_chain :protected_instance_variables, :action_caching | ||
| 170 | + end | ||
| 167 | end | 171 | end |
| 168 | 172 | ||
| 169 | - module ClassMethods #:nodoc: | 173 | + def protected_instance_variables_with_action_caching |
| 174 | + protected_instance_variables_without_action_caching + %w(@action_cache_path) | ||
| 175 | + end | ||
| 176 | + | ||
| 177 | + module ClassMethods | ||
| 178 | + # Declares that +actions+ should be cached. | ||
| 179 | + # See ActionController::Caching::Actions for details. | ||
| 170 | def caches_action(*actions) | 180 | def caches_action(*actions) |
| 171 | return unless perform_caching | 181 | return unless perform_caching |
| 172 | - around_filter(ActionCacheFilter.new(*actions)) | 182 | + action_cache_filter = ActionCacheFilter.new(*actions) |
| 183 | + before_filter action_cache_filter | ||
| 184 | + after_filter action_cache_filter | ||
| 173 | end | 185 | end |
| 174 | end | 186 | end |
| 175 | 187 | ||
| @@ -185,70 +197,59 @@ module ActionController #:nodoc: | @@ -185,70 +197,59 @@ module ActionController #:nodoc: | ||
| 185 | end | 197 | end |
| 186 | 198 | ||
| 187 | class ActionCacheFilter #:nodoc: | 199 | class ActionCacheFilter #:nodoc: |
| 188 | - def initialize(*actions, &block) | ||
| 189 | - @actions = actions | 200 | + def initialize(*actions) |
| 201 | + @actions = Set.new actions | ||
| 190 | end | 202 | end |
| 191 | 203 | ||
| 192 | def before(controller) | 204 | def before(controller) |
| 193 | - return unless @actions.include?(controller.action_name.intern) | ||
| 194 | - action_cache_path = ActionCachePath.new(controller) | ||
| 195 | - if cache = controller.read_fragment(action_cache_path.path) | 205 | + return unless @actions.include?(controller.action_name.to_sym) |
| 206 | + cache_path = ActionCachePath.new(controller, {}) | ||
| 207 | + if cache = controller.read_fragment(cache_path.path) | ||
| 196 | controller.rendered_action_cache = true | 208 | controller.rendered_action_cache = true |
| 197 | - set_content_type!(action_cache_path) | 209 | + set_content_type!(controller, cache_path.extension) |
| 198 | controller.send(:render_text, cache) | 210 | controller.send(:render_text, cache) |
| 199 | false | 211 | false |
| 212 | + else | ||
| 213 | + controller.action_cache_path = cache_path | ||
| 200 | end | 214 | end |
| 201 | end | 215 | end |
| 202 | 216 | ||
| 203 | def after(controller) | 217 | def after(controller) |
| 204 | - return if !@actions.include?(controller.action_name.intern) || controller.rendered_action_cache | ||
| 205 | - controller.write_fragment(ActionCachePath.path_for(controller), controller.response.body) | 218 | + return if !@actions.include?(controller.action_name.to_sym) || controller.rendered_action_cache |
| 219 | + controller.write_fragment(controller.action_cache_path.path, controller.response.body) | ||
| 206 | end | 220 | end |
| 207 | 221 | ||
| 208 | private | 222 | private |
| 209 | - | ||
| 210 | - def set_content_type!(action_cache_path) | ||
| 211 | - if extention = action_cache_path.extension | ||
| 212 | - content_type = Mime::EXTENSION_LOOKUP[extention] | ||
| 213 | - action_cache_path.controller.response.content_type = content_type.to_s | ||
| 214 | - end | 223 | + def set_content_type!(controller, extension) |
| 224 | + controller.response.content_type = Mime::EXTENSION_LOOKUP[extension].to_s if extension | ||
| 215 | end | 225 | end |
| 216 | 226 | ||
| 217 | end | 227 | end |
| 218 | 228 | ||
| 219 | class ActionCachePath | 229 | class ActionCachePath |
| 220 | - attr_reader :controller, :options | 230 | + attr_reader :path, :extension |
| 221 | 231 | ||
| 222 | class << self | 232 | class << self |
| 223 | - def path_for(*args, &block) | ||
| 224 | - new(*args).path | 233 | + def path_for(controller, options) |
| 234 | + new(controller, options).path | ||
| 225 | end | 235 | end |
| 226 | end | 236 | end |
| 227 | 237 | ||
| 228 | def initialize(controller, options = {}) | 238 | def initialize(controller, options = {}) |
| 229 | - @controller = controller | ||
| 230 | - @options = options | ||
| 231 | - end | ||
| 232 | - | ||
| 233 | - def path | ||
| 234 | - return @path if @path | ||
| 235 | - @path = controller.url_for(options).split('://').last | ||
| 236 | - normalize! | ||
| 237 | - add_extension! | ||
| 238 | - URI.unescape(@path) | ||
| 239 | - end | ||
| 240 | - | ||
| 241 | - def extension | ||
| 242 | - @extension ||= extract_extension(controller.request.path) | 239 | + @extension = extract_extension(controller.request.path) |
| 240 | + path = controller.url_for(options).split('://').last | ||
| 241 | + normalize!(path) | ||
| 242 | + add_extension!(path, @extension) | ||
| 243 | + @path = URI.unescape(path) | ||
| 243 | end | 244 | end |
| 244 | 245 | ||
| 245 | private | 246 | private |
| 246 | - def normalize! | ||
| 247 | - @path << 'index' if @path.last == '/' | 247 | + def normalize!(path) |
| 248 | + path << 'index' if path[-1] == ?/ | ||
| 248 | end | 249 | end |
| 249 | 250 | ||
| 250 | - def add_extension! | ||
| 251 | - @path << ".#{extension}" if extension | 251 | + def add_extension!(path, extension) |
| 252 | + path << ".#{extension}" if extension | ||
| 252 | end | 253 | end |
| 253 | 254 | ||
| 254 | def extract_extension(file_path) | 255 | def extract_extension(file_path) |
vendor/rails/actionpack/lib/action_controller/cgi_ext/pstore_performance_fix.rb
0 → 100644
| @@ -0,0 +1,30 @@ | @@ -0,0 +1,30 @@ | ||
| 1 | +# CGI::Session::PStore.initialize requires 'digest/md5' on every call. | ||
| 2 | +# This makes sense when spawning processes per request, but is | ||
| 3 | +# unnecessarily expensive when serving requests from a long-lived | ||
| 4 | +# process. | ||
| 5 | +require 'cgi/session' | ||
| 6 | +require 'cgi/session/pstore' | ||
| 7 | +require 'digest/md5' | ||
| 8 | + | ||
| 9 | +class CGI::Session::PStore #:nodoc: | ||
| 10 | + def initialize(session, option={}) | ||
| 11 | + dir = option['tmpdir'] || Dir::tmpdir | ||
| 12 | + prefix = option['prefix'] || '' | ||
| 13 | + id = session.session_id | ||
| 14 | + md5 = Digest::MD5.hexdigest(id)[0,16] | ||
| 15 | + path = dir+"/"+prefix+md5 | ||
| 16 | + path.untaint | ||
| 17 | + if File::exist?(path) | ||
| 18 | + @hash = nil | ||
| 19 | + else | ||
| 20 | + unless session.new_session | ||
| 21 | + raise CGI::Session::NoSession, "uninitialized session" | ||
| 22 | + end | ||
| 23 | + @hash = {} | ||
| 24 | + end | ||
| 25 | + @p = ::PStore.new(path) | ||
| 26 | + @p.transaction do |p| | ||
| 27 | + File.chmod(0600, p.path) | ||
| 28 | + end | ||
| 29 | + end | ||
| 30 | +end |
vendor/rails/actionpack/lib/action_controller/cgi_ext/raw_post_data_fix.rb
| @@ -65,7 +65,7 @@ class CGI #:nodoc: | @@ -65,7 +65,7 @@ class CGI #:nodoc: | ||
| 65 | if env_qs.blank? && !(uri = env_table['REQUEST_URI']).blank? | 65 | if env_qs.blank? && !(uri = env_table['REQUEST_URI']).blank? |
| 66 | uri.split('?', 2)[1] || '' | 66 | uri.split('?', 2)[1] || '' |
| 67 | else | 67 | else |
| 68 | - env_qs | 68 | + env_qs || '' |
| 69 | end | 69 | end |
| 70 | end | 70 | end |
| 71 | end | 71 | end |
vendor/rails/actionpack/lib/action_controller/cgi_process.rb
| @@ -2,6 +2,7 @@ require 'action_controller/cgi_ext/cgi_ext' | @@ -2,6 +2,7 @@ require 'action_controller/cgi_ext/cgi_ext' | ||
| 2 | require 'action_controller/cgi_ext/cookie_performance_fix' | 2 | require 'action_controller/cgi_ext/cookie_performance_fix' |
| 3 | require 'action_controller/cgi_ext/raw_post_data_fix' | 3 | require 'action_controller/cgi_ext/raw_post_data_fix' |
| 4 | require 'action_controller/cgi_ext/session_performance_fix' | 4 | require 'action_controller/cgi_ext/session_performance_fix' |
| 5 | +require 'action_controller/cgi_ext/pstore_performance_fix' | ||
| 5 | 6 | ||
| 6 | module ActionController #:nodoc: | 7 | module ActionController #:nodoc: |
| 7 | class Base | 8 | class Base |
| @@ -12,8 +13,8 @@ module ActionController #:nodoc: | @@ -12,8 +13,8 @@ module ActionController #:nodoc: | ||
| 12 | # (default). Additionally, there is CGI::Session::DRbStore and CGI::Session::ActiveRecordStore. Read more about these in | 13 | # (default). Additionally, there is CGI::Session::DRbStore and CGI::Session::ActiveRecordStore. Read more about these in |
| 13 | # lib/action_controller/session. | 14 | # lib/action_controller/session. |
| 14 | # * <tt>:session_key</tt> - the parameter name used for the session id. Defaults to '_session_id'. | 15 | # * <tt>:session_key</tt> - the parameter name used for the session id. Defaults to '_session_id'. |
| 15 | - # * <tt>:session_id</tt> - the session id to use. If not provided, then it is retrieved from the +session_key+ parameter | ||
| 16 | - # of the request, or automatically generated for a new session. | 16 | + # * <tt>:session_id</tt> - the session id to use. If not provided, then it is retrieved from the +session_key+ cookie, or |
| 17 | + # automatically generated for a new session. | ||
| 17 | # * <tt>:new_session</tt> - if true, force creation of a new session. If not set, a new session is only created if none currently | 18 | # * <tt>:new_session</tt> - if true, force creation of a new session. If not set, a new session is only created if none currently |
| 18 | # exists. If false, a new session is never created, and if none currently exists and the +session_id+ option is not set, | 19 | # exists. If false, a new session is never created, and if none currently exists and the +session_id+ option is not set, |
| 19 | # an ArgumentError is raised. | 20 | # an ArgumentError is raised. |
| @@ -23,6 +24,8 @@ module ActionController #:nodoc: | @@ -23,6 +24,8 @@ module ActionController #:nodoc: | ||
| 23 | # server. | 24 | # server. |
| 24 | # * <tt>:session_secure</tt> - if +true+, this session will only work over HTTPS. | 25 | # * <tt>:session_secure</tt> - if +true+, this session will only work over HTTPS. |
| 25 | # * <tt>:session_path</tt> - the path for which this session applies. Defaults to the directory of the CGI script. | 26 | # * <tt>:session_path</tt> - the path for which this session applies. Defaults to the directory of the CGI script. |
| 27 | + # * <tt>:cookie_only</tt> - if +true+ (the default), session IDs will only be accepted from cookies and not from | ||
| 28 | + # the query string or POST parameters. This protects against session fixation attacks. | ||
| 26 | def self.process_cgi(cgi = CGI.new, session_options = {}) | 29 | def self.process_cgi(cgi = CGI.new, session_options = {}) |
| 27 | new.process_cgi(cgi, session_options) | 30 | new.process_cgi(cgi, session_options) |
| 28 | end | 31 | end |
| @@ -34,11 +37,14 @@ module ActionController #:nodoc: | @@ -34,11 +37,14 @@ module ActionController #:nodoc: | ||
| 34 | 37 | ||
| 35 | class CgiRequest < AbstractRequest #:nodoc: | 38 | class CgiRequest < AbstractRequest #:nodoc: |
| 36 | attr_accessor :cgi, :session_options | 39 | attr_accessor :cgi, :session_options |
| 40 | + class SessionFixationAttempt < StandardError; end #:nodoc: | ||
| 37 | 41 | ||
| 38 | DEFAULT_SESSION_OPTIONS = { | 42 | DEFAULT_SESSION_OPTIONS = { |
| 39 | :database_manager => CGI::Session::PStore, | 43 | :database_manager => CGI::Session::PStore, |
| 40 | :prefix => "ruby_sess.", | 44 | :prefix => "ruby_sess.", |
| 41 | - :session_path => "/" | 45 | + :session_path => "/", |
| 46 | + :session_key => "_session_id", | ||
| 47 | + :cookie_only => true | ||
| 42 | } unless const_defined?(:DEFAULT_SESSION_OPTIONS) | 48 | } unless const_defined?(:DEFAULT_SESSION_OPTIONS) |
| 43 | 49 | ||
| 44 | def initialize(cgi, session_options = {}) | 50 | def initialize(cgi, session_options = {}) |
| @@ -48,6 +54,10 @@ module ActionController #:nodoc: | @@ -48,6 +54,10 @@ module ActionController #:nodoc: | ||
| 48 | super() | 54 | super() |
| 49 | end | 55 | end |
| 50 | 56 | ||
| 57 | + def cookie_only? | ||
| 58 | + session_options_with_string_keys['cookie_only'] | ||
| 59 | + end | ||
| 60 | + | ||
| 51 | def query_string | 61 | def query_string |
| 52 | if (qs = @cgi.query_string) && !qs.empty? | 62 | if (qs = @cgi.query_string) && !qs.empty? |
| 53 | qs | 63 | qs |
| @@ -108,6 +118,9 @@ module ActionController #:nodoc: | @@ -108,6 +118,9 @@ module ActionController #:nodoc: | ||
| 108 | @session = Hash.new | 118 | @session = Hash.new |
| 109 | else | 119 | else |
| 110 | stale_session_check! do | 120 | stale_session_check! do |
| 121 | + if cookie_only? && request_parameters[session_options_with_string_keys['session_key']] | ||
| 122 | + raise SessionFixationAttempt | ||
| 123 | + end | ||
| 111 | case value = session_options_with_string_keys['new_session'] | 124 | case value = session_options_with_string_keys['new_session'] |
| 112 | when true | 125 | when true |
| 113 | @session = new_session | 126 | @session = new_session |
vendor/rails/actionpack/lib/action_controller/cookies.rb
| @@ -47,7 +47,10 @@ module ActionController #:nodoc: | @@ -47,7 +47,10 @@ module ActionController #:nodoc: | ||
| 47 | # Returns the value of the cookie by +name+ -- or nil if no such cookie exists. You set new cookies using either the cookie method | 47 | # Returns the value of the cookie by +name+ -- or nil if no such cookie exists. You set new cookies using either the cookie method |
| 48 | # or cookies[]= (for simple name/value cookies without options). | 48 | # or cookies[]= (for simple name/value cookies without options). |
| 49 | def [](name) | 49 | def [](name) |
| 50 | - @cookies[name.to_s].value.first if @cookies[name.to_s] && @cookies[name.to_s].respond_to?(:value) | 50 | + cookie = @cookies[name.to_s] |
| 51 | + if cookie && cookie.respond_to?(:value) | ||
| 52 | + cookie.size > 1 ? cookie.value : cookie.value.to_s | ||
| 53 | + end | ||
| 51 | end | 54 | end |
| 52 | 55 | ||
| 53 | def []=(name, options) | 56 | def []=(name, options) |
| @@ -62,9 +65,11 @@ module ActionController #:nodoc: | @@ -62,9 +65,11 @@ module ActionController #:nodoc: | ||
| 62 | end | 65 | end |
| 63 | 66 | ||
| 64 | # Removes the cookie on the client machine by setting the value to an empty string | 67 | # Removes the cookie on the client machine by setting the value to an empty string |
| 65 | - # and setting its expiration date into the past | ||
| 66 | - def delete(name) | ||
| 67 | - set_cookie("name" => name.to_s, "value" => "", "expires" => Time.at(0)) | 68 | + # and setting its expiration date into the past. Like []=, you can pass in an options |
| 69 | + # hash to delete cookies with extra data such as a +path+. | ||
| 70 | + def delete(name, options = {}) | ||
| 71 | + options.stringify_keys! | ||
| 72 | + set_cookie(options.merge("name" => name.to_s, "value" => "", "expires" => Time.at(0))) | ||
| 68 | end | 73 | end |
| 69 | 74 | ||
| 70 | private | 75 | private |
vendor/rails/actionpack/lib/action_controller/filters.rb
| @@ -214,9 +214,10 @@ module ActionController #:nodoc: | @@ -214,9 +214,10 @@ module ActionController #:nodoc: | ||
| 214 | # == Filter Chain Halting | 214 | # == Filter Chain Halting |
| 215 | # | 215 | # |
| 216 | # <tt>before_filter</tt> and <tt>around_filter</tt> may halt the request | 216 | # <tt>before_filter</tt> and <tt>around_filter</tt> may halt the request |
| 217 | - # before controller action is run. This is useful, for example, to deny | 217 | + # before a controller action is run. This is useful, for example, to deny |
| 218 | # access to unauthenticated users or to redirect from http to https. | 218 | # access to unauthenticated users or to redirect from http to https. |
| 219 | # Simply return false from the filter or call render or redirect. | 219 | # Simply return false from the filter or call render or redirect. |
| 220 | + # After filters will not be executed if the filter chain is halted. | ||
| 220 | # | 221 | # |
| 221 | # Around filters halt the request unless the action block is called. | 222 | # Around filters halt the request unless the action block is called. |
| 222 | # Given these filters | 223 | # Given these filters |
| @@ -238,12 +239,12 @@ module ActionController #:nodoc: | @@ -238,12 +239,12 @@ module ActionController #:nodoc: | ||
| 238 | # . . / | 239 | # . . / |
| 239 | # . #around (code after yield) | 240 | # . #around (code after yield) |
| 240 | # . / | 241 | # . / |
| 241 | - # #after (actual filter code is run) | 242 | + # #after (actual filter code is run, unless the around filter does not yield) |
| 242 | # | 243 | # |
| 243 | - # If #around returns before yielding, only #after will be run. The #before | ||
| 244 | - # filter and controller action will not be run. If #before returns false, | ||
| 245 | - # the second half of #around and all of #after will still run but the | ||
| 246 | - # action will not. | 244 | + # If #around returns before yielding, #after will still not be run. The #before |
| 245 | + # filter and controller action will not be run. If #before returns false, | ||
| 246 | + # the second half of #around and will still run but #after and the | ||
| 247 | + # action will not. If #around does not yield, #after will not be run. | ||
| 247 | module ClassMethods | 248 | module ClassMethods |
| 248 | # The passed <tt>filters</tt> will be appended to the filter_chain and | 249 | # The passed <tt>filters</tt> will be appended to the filter_chain and |
| 249 | # will execute before the action on this controller is performed. | 250 | # will execute before the action on this controller is performed. |
| @@ -263,13 +264,13 @@ module ActionController #:nodoc: | @@ -263,13 +264,13 @@ module ActionController #:nodoc: | ||
| 263 | # The passed <tt>filters</tt> will be appended to the array of filters | 264 | # The passed <tt>filters</tt> will be appended to the array of filters |
| 264 | # that run _after_ actions on this controller are performed. | 265 | # that run _after_ actions on this controller are performed. |
| 265 | def append_after_filter(*filters, &block) | 266 | def append_after_filter(*filters, &block) |
| 266 | - prepend_filter_to_chain(filters, :after, &block) | 267 | + append_filter_to_chain(filters, :after, &block) |
| 267 | end | 268 | end |
| 268 | 269 | ||
| 269 | # The passed <tt>filters</tt> will be prepended to the array of filters | 270 | # The passed <tt>filters</tt> will be prepended to the array of filters |
| 270 | # that run _after_ actions on this controller are performed. | 271 | # that run _after_ actions on this controller are performed. |
| 271 | def prepend_after_filter(*filters, &block) | 272 | def prepend_after_filter(*filters, &block) |
| 272 | - append_filter_to_chain(filters, :after, &block) | 273 | + prepend_filter_to_chain(filters, :after, &block) |
| 273 | end | 274 | end |
| 274 | 275 | ||
| 275 | # Shorthand for append_after_filter since it's the most common. | 276 | # Shorthand for append_after_filter since it's the most common. |
| @@ -362,12 +363,12 @@ module ActionController #:nodoc: | @@ -362,12 +363,12 @@ module ActionController #:nodoc: | ||
| 362 | 363 | ||
| 363 | # Returns a mapping between filters and the actions that may run them. | 364 | # Returns a mapping between filters and the actions that may run them. |
| 364 | def included_actions #:nodoc: | 365 | def included_actions #:nodoc: |
| 365 | - read_inheritable_attribute("included_actions") || {} | 366 | + @included_actions ||= read_inheritable_attribute("included_actions") || {} |
| 366 | end | 367 | end |
| 367 | 368 | ||
| 368 | # Returns a mapping between filters and actions that may not run them. | 369 | # Returns a mapping between filters and actions that may not run them. |
| 369 | def excluded_actions #:nodoc: | 370 | def excluded_actions #:nodoc: |
| 370 | - read_inheritable_attribute("excluded_actions") || {} | 371 | + @excluded_actions ||= read_inheritable_attribute("excluded_actions") || {} |
| 371 | end | 372 | end |
| 372 | 373 | ||
| 373 | # Find a filter in the filter_chain where the filter method matches the _filter_ param | 374 | # Find a filter in the filter_chain where the filter method matches the _filter_ param |
| @@ -381,10 +382,11 @@ module ActionController #:nodoc: | @@ -381,10 +382,11 @@ module ActionController #:nodoc: | ||
| 381 | 382 | ||
| 382 | # Returns true if the filter is excluded from the given action | 383 | # Returns true if the filter is excluded from the given action |
| 383 | def filter_excluded_from_action?(filter,action) #:nodoc: | 384 | def filter_excluded_from_action?(filter,action) #:nodoc: |
| 384 | - if (ia = included_actions[filter]) && !ia.empty? | 385 | + case |
| 386 | + when ia = included_actions[filter] | ||
| 385 | !ia.include?(action) | 387 | !ia.include?(action) |
| 386 | - else | ||
| 387 | - (excluded_actions[filter] || []).include?(action) | 388 | + when ea = excluded_actions[filter] |
| 389 | + ea.include?(action) | ||
| 388 | end | 390 | end |
| 389 | end | 391 | end |
| 390 | 392 | ||
| @@ -397,20 +399,28 @@ module ActionController #:nodoc: | @@ -397,20 +399,28 @@ module ActionController #:nodoc: | ||
| 397 | @filter = filter | 399 | @filter = filter |
| 398 | end | 400 | end |
| 399 | 401 | ||
| 402 | + def type | ||
| 403 | + :around | ||
| 404 | + end | ||
| 405 | + | ||
| 400 | def before? | 406 | def before? |
| 401 | - false | 407 | + type == :before |
| 402 | end | 408 | end |
| 403 | 409 | ||
| 404 | def after? | 410 | def after? |
| 405 | - false | 411 | + type == :after |
| 406 | end | 412 | end |
| 407 | 413 | ||
| 408 | def around? | 414 | def around? |
| 409 | - true | 415 | + type == :around |
| 416 | + end | ||
| 417 | + | ||
| 418 | + def run(controller) | ||
| 419 | + raise ActionControllerError, 'No filter type: Nothing to do here.' | ||
| 410 | end | 420 | end |
| 411 | 421 | ||
| 412 | def call(controller, &block) | 422 | def call(controller, &block) |
| 413 | - raise(ActionControllerError, 'No filter type: Nothing to do here.') | 423 | + run(controller) |
| 414 | end | 424 | end |
| 415 | end | 425 | end |
| 416 | 426 | ||
| @@ -420,35 +430,38 @@ module ActionController #:nodoc: | @@ -420,35 +430,38 @@ module ActionController #:nodoc: | ||
| 420 | def filter | 430 | def filter |
| 421 | @filter.filter | 431 | @filter.filter |
| 422 | end | 432 | end |
| 423 | - | ||
| 424 | - def around? | ||
| 425 | - false | ||
| 426 | - end | ||
| 427 | end | 433 | end |
| 428 | 434 | ||
| 429 | class BeforeFilterProxy < FilterProxy #:nodoc: | 435 | class BeforeFilterProxy < FilterProxy #:nodoc: |
| 430 | - def before? | ||
| 431 | - true | 436 | + def type |
| 437 | + :before | ||
| 432 | end | 438 | end |
| 433 | 439 | ||
| 434 | - def call(controller, &block) | ||
| 435 | - if false == @filter.call(controller) # must only stop if equal to false. only filters returning false are halted. | ||
| 436 | - controller.halt_filter_chain(@filter, :returned_false) | ||
| 437 | - else | ||
| 438 | - yield | 440 | + def run(controller) |
| 441 | + # only filters returning false are halted. | ||
| 442 | + if false == @filter.call(controller) | ||
| 443 | + controller.send :halt_filter_chain, @filter, :returned_false | ||
| 439 | end | 444 | end |
| 440 | end | 445 | end |
| 446 | + | ||
| 447 | + def call(controller) | ||
| 448 | + yield unless run(controller) | ||
| 449 | + end | ||
| 441 | end | 450 | end |
| 442 | 451 | ||
| 443 | class AfterFilterProxy < FilterProxy #:nodoc: | 452 | class AfterFilterProxy < FilterProxy #:nodoc: |
| 444 | - def after? | ||
| 445 | - true | 453 | + def type |
| 454 | + :after | ||
| 446 | end | 455 | end |
| 447 | 456 | ||
| 448 | - def call(controller, &block) | ||
| 449 | - yield | 457 | + def run(controller) |
| 450 | @filter.call(controller) | 458 | @filter.call(controller) |
| 451 | end | 459 | end |
| 460 | + | ||
| 461 | + def call(controller) | ||
| 462 | + yield | ||
| 463 | + run(controller) | ||
| 464 | + end | ||
| 452 | end | 465 | end |
| 453 | 466 | ||
| 454 | class SymbolFilter < Filter #:nodoc: | 467 | class SymbolFilter < Filter #:nodoc: |
| @@ -485,29 +498,72 @@ module ActionController #:nodoc: | @@ -485,29 +498,72 @@ module ActionController #:nodoc: | ||
| 485 | end | 498 | end |
| 486 | end | 499 | end |
| 487 | 500 | ||
| 501 | + class ClassBeforeFilter < Filter #:nodoc: | ||
| 502 | + def call(controller, &block) | ||
| 503 | + @filter.before(controller) | ||
| 504 | + end | ||
| 505 | + end | ||
| 506 | + | ||
| 507 | + class ClassAfterFilter < Filter #:nodoc: | ||
| 508 | + def call(controller, &block) | ||
| 509 | + @filter.after(controller) | ||
| 510 | + end | ||
| 511 | + end | ||
| 512 | + | ||
| 488 | protected | 513 | protected |
| 489 | - def append_filter_to_chain(filters, position = :around, &block) | ||
| 490 | - write_inheritable_array('filter_chain', create_filters(filters, position, &block) ) | 514 | + def append_filter_to_chain(filters, filter_type = :around, &block) |
| 515 | + pos = find_filter_append_position(filters, filter_type) | ||
| 516 | + update_filter_chain(filters, filter_type, pos, &block) | ||
| 491 | end | 517 | end |
| 492 | 518 | ||
| 493 | - def prepend_filter_to_chain(filters, position = :around, &block) | ||
| 494 | - write_inheritable_attribute('filter_chain', create_filters(filters, position, &block) + filter_chain) | 519 | + def prepend_filter_to_chain(filters, filter_type = :around, &block) |
| 520 | + pos = find_filter_prepend_position(filters, filter_type) | ||
| 521 | + update_filter_chain(filters, filter_type, pos, &block) | ||
| 495 | end | 522 | end |
| 496 | 523 | ||
| 497 | - def create_filters(filters, position, &block) #:nodoc: | 524 | + def update_filter_chain(filters, filter_type, pos, &block) |
| 525 | + new_filters = create_filters(filters, filter_type, &block) | ||
| 526 | + new_chain = filter_chain.insert(pos, new_filters).flatten | ||
| 527 | + write_inheritable_attribute('filter_chain', new_chain) | ||
| 528 | + end | ||
| 529 | + | ||
| 530 | + def find_filter_append_position(filters, filter_type) | ||
| 531 | + # appending an after filter puts it at the end of the call chain | ||
| 532 | + # before and around filters go before the first after filter in the chain | ||
| 533 | + unless filter_type == :after | ||
| 534 | + filter_chain.each_with_index do |f,i| | ||
| 535 | + return i if f.after? | ||
| 536 | + end | ||
| 537 | + end | ||
| 538 | + return -1 | ||
| 539 | + end | ||
| 540 | + | ||
| 541 | + def find_filter_prepend_position(filters, filter_type) | ||
| 542 | + # prepending a before or around filter puts it at the front of the call chain | ||
| 543 | + # after filters go before the first after filter in the chain | ||
| 544 | + if filter_type == :after | ||
| 545 | + filter_chain.each_with_index do |f,i| | ||
| 546 | + return i if f.after? | ||
| 547 | + end | ||
| 548 | + return -1 | ||
| 549 | + end | ||
| 550 | + return 0 | ||
| 551 | + end | ||
| 552 | + | ||
| 553 | + def create_filters(filters, filter_type, &block) #:nodoc: | ||
| 498 | filters, conditions = extract_conditions(filters, &block) | 554 | filters, conditions = extract_conditions(filters, &block) |
| 499 | - filters.map! { |filter| find_or_create_filter(filter,position) } | 555 | + filters.map! { |filter| find_or_create_filter(filter, filter_type) } |
| 500 | update_conditions(filters, conditions) | 556 | update_conditions(filters, conditions) |
| 501 | filters | 557 | filters |
| 502 | end | 558 | end |
| 503 | 559 | ||
| 504 | - def find_or_create_filter(filter,position) | ||
| 505 | - if found_filter = find_filter(filter) { |f| f.send("#{position}?") } | 560 | + def find_or_create_filter(filter, filter_type) |
| 561 | + if found_filter = find_filter(filter) { |f| f.type == filter_type } | ||
| 506 | found_filter | 562 | found_filter |
| 507 | else | 563 | else |
| 508 | - f = class_for_filter(filter).new(filter) | 564 | + f = class_for_filter(filter, filter_type).new(filter) |
| 509 | # apply proxy to filter if necessary | 565 | # apply proxy to filter if necessary |
| 510 | - case position | 566 | + case filter_type |
| 511 | when :before | 567 | when :before |
| 512 | BeforeFilterProxy.new(f) | 568 | BeforeFilterProxy.new(f) |
| 513 | when :after | 569 | when :after |
| @@ -520,7 +576,7 @@ module ActionController #:nodoc: | @@ -520,7 +576,7 @@ module ActionController #:nodoc: | ||
| 520 | 576 | ||
| 521 | # The determination of the filter type was once done at run time. | 577 | # The determination of the filter type was once done at run time. |
| 522 | # This method is here to extract as much logic from the filter run time as possible | 578 | # This method is here to extract as much logic from the filter run time as possible |
| 523 | - def class_for_filter(filter) #:nodoc: | 579 | + def class_for_filter(filter, filter_type) #:nodoc: |
| 524 | case | 580 | case |
| 525 | when filter.is_a?(Symbol) | 581 | when filter.is_a?(Symbol) |
| 526 | SymbolFilter | 582 | SymbolFilter |
| @@ -534,8 +590,12 @@ module ActionController #:nodoc: | @@ -534,8 +590,12 @@ module ActionController #:nodoc: | ||
| 534 | end | 590 | end |
| 535 | when filter.respond_to?(:filter) | 591 | when filter.respond_to?(:filter) |
| 536 | ClassFilter | 592 | ClassFilter |
| 593 | + when filter.respond_to?(:before) && filter_type == :before | ||
| 594 | + ClassBeforeFilter | ||
| 595 | + when filter.respond_to?(:after) && filter_type == :after | ||
| 596 | + ClassAfterFilter | ||
| 537 | else | 597 | else |
| 538 | - raise(ActionControllerError, 'A filters must be a Symbol, Proc, Method, or object responding to filter.') | 598 | + raise(ActionControllerError, 'A filter must be a Symbol, Proc, Method, or object responding to filter, after or before.') |
| 539 | end | 599 | end |
| 540 | end | 600 | end |
| 541 | 601 | ||
| @@ -550,8 +610,8 @@ module ActionController #:nodoc: | @@ -550,8 +610,8 @@ module ActionController #:nodoc: | ||
| 550 | return if conditions.empty? | 610 | return if conditions.empty? |
| 551 | if conditions[:only] | 611 | if conditions[:only] |
| 552 | write_inheritable_hash('included_actions', condition_hash(filters, conditions[:only])) | 612 | write_inheritable_hash('included_actions', condition_hash(filters, conditions[:only])) |
| 553 | - else | ||
| 554 | - write_inheritable_hash('excluded_actions', condition_hash(filters, conditions[:except])) if conditions[:except] | 613 | + elsif conditions[:except] |
| 614 | + write_inheritable_hash('excluded_actions', condition_hash(filters, conditions[:except])) | ||
| 555 | end | 615 | end |
| 556 | end | 616 | end |
| 557 | 617 | ||
| @@ -576,9 +636,9 @@ module ActionController #:nodoc: | @@ -576,9 +636,9 @@ module ActionController #:nodoc: | ||
| 576 | 636 | ||
| 577 | def remove_actions_from_included_actions!(filters,*actions) | 637 | def remove_actions_from_included_actions!(filters,*actions) |
| 578 | actions = actions.flatten.map(&:to_s) | 638 | actions = actions.flatten.map(&:to_s) |
| 579 | - updated_hash = filters.inject(included_actions) do |hash,filter| | 639 | + updated_hash = filters.inject(read_inheritable_attribute('included_actions')||{}) do |hash,filter| |
| 580 | ia = (hash[filter] || []) - actions | 640 | ia = (hash[filter] || []) - actions |
| 581 | - ia.blank? ? hash.delete(filter) : hash[filter] = ia | 641 | + ia.empty? ? hash.delete(filter) : hash[filter] = ia |
| 582 | hash | 642 | hash |
| 583 | end | 643 | end |
| 584 | write_inheritable_attribute('included_actions', updated_hash) | 644 | write_inheritable_attribute('included_actions', updated_hash) |
| @@ -595,7 +655,9 @@ module ActionController #:nodoc: | @@ -595,7 +655,9 @@ module ActionController #:nodoc: | ||
| 595 | def proxy_before_and_after_filter(filter) #:nodoc: | 655 | def proxy_before_and_after_filter(filter) #:nodoc: |
| 596 | return filter unless filter_responds_to_before_and_after(filter) | 656 | return filter unless filter_responds_to_before_and_after(filter) |
| 597 | Proc.new do |controller, action| | 657 | Proc.new do |controller, action| |
| 598 | - unless filter.before(controller) == false | 658 | + if filter.before(controller) == false |
| 659 | + controller.send :halt_filter_chain, filter, :returned_false | ||
| 660 | + else | ||
| 599 | begin | 661 | begin |
| 600 | action.call | 662 | action.call |
| 601 | ensure | 663 | ensure |
| @@ -615,53 +677,90 @@ module ActionController #:nodoc: | @@ -615,53 +677,90 @@ module ActionController #:nodoc: | ||
| 615 | end | 677 | end |
| 616 | end | 678 | end |
| 617 | 679 | ||
| 618 | - def perform_action_with_filters | ||
| 619 | - call_filter(self.class.filter_chain, 0) | ||
| 620 | - end | 680 | + protected |
| 621 | 681 | ||
| 622 | def process_with_filters(request, response, method = :perform_action, *arguments) #:nodoc: | 682 | def process_with_filters(request, response, method = :perform_action, *arguments) #:nodoc: |
| 623 | @before_filter_chain_aborted = false | 683 | @before_filter_chain_aborted = false |
| 624 | process_without_filters(request, response, method, *arguments) | 684 | process_without_filters(request, response, method, *arguments) |
| 625 | end | 685 | end |
| 626 | 686 | ||
| 627 | - def filter_chain | ||
| 628 | - self.class.filter_chain | 687 | + def perform_action_with_filters |
| 688 | + call_filters(self.class.filter_chain, 0, 0) | ||
| 629 | end | 689 | end |
| 630 | 690 | ||
| 631 | - def call_filter(chain, index) | ||
| 632 | - return (performed? || perform_action_without_filters) if index >= chain.size | ||
| 633 | - filter = chain[index] | ||
| 634 | - return call_filter(chain, index.next) if self.class.filter_excluded_from_action?(filter,action_name) | 691 | + private |
| 635 | 692 | ||
| 636 | - halted = false | ||
| 637 | - filter.call(self) do | ||
| 638 | - halted = call_filter(chain, index.next) | 693 | + def call_filters(chain, index, nesting) |
| 694 | + index = run_before_filters(chain, index, nesting) | ||
| 695 | + aborted = @before_filter_chain_aborted | ||
| 696 | + perform_action_without_filters unless performed? || aborted | ||
| 697 | + return index if nesting != 0 || aborted | ||
| 698 | + run_after_filters(chain, index) | ||
| 699 | + end | ||
| 700 | + | ||
| 701 | + def skip_excluded_filters(chain, index) | ||
| 702 | + while (filter = chain[index]) && self.class.filter_excluded_from_action?(filter, action_name) | ||
| 703 | + index = index.next | ||
| 639 | end | 704 | end |
| 640 | - halt_filter_chain(filter.filter, :no_yield) if halted == false unless @before_filter_chain_aborted | ||
| 641 | - halted | 705 | + [filter, index] |
| 642 | end | 706 | end |
| 643 | 707 | ||
| 644 | - def halt_filter_chain(filter, reason) | ||
| 645 | - if logger | ||
| 646 | - case reason | ||
| 647 | - when :no_yield | ||
| 648 | - logger.info "Filter chain halted as [#{filter.inspect}] did not yield." | ||
| 649 | - when :returned_false | ||
| 650 | - logger.info "Filter chain halted as [#{filter.inspect}] returned false." | 708 | + def run_before_filters(chain, index, nesting) |
| 709 | + while chain[index] | ||
| 710 | + filter, index = skip_excluded_filters(chain, index) | ||
| 711 | + break unless filter # end of call chain reached | ||
| 712 | + case filter.type | ||
| 713 | + when :before | ||
| 714 | + filter.run(self) # invoke before filter | ||
| 715 | + index = index.next | ||
| 716 | + break if @before_filter_chain_aborted | ||
| 717 | + when :around | ||
| 718 | + yielded = false | ||
| 719 | + filter.call(self) do | ||
| 720 | + yielded = true | ||
| 721 | + # all remaining before and around filters will be run in this call | ||
| 722 | + index = call_filters(chain, index.next, nesting.next) | ||
| 723 | + end | ||
| 724 | + halt_filter_chain(filter, :did_not_yield) unless yielded | ||
| 725 | + break | ||
| 726 | + else | ||
| 727 | + break # no before or around filters left | ||
| 651 | end | 728 | end |
| 652 | end | 729 | end |
| 653 | - @before_filter_chain_aborted = true | ||
| 654 | - return false | 730 | + index |
| 655 | end | 731 | end |
| 656 | 732 | ||
| 657 | - private | ||
| 658 | - def process_cleanup_with_filters | ||
| 659 | - if @before_filter_chain_aborted | ||
| 660 | - close_session | 733 | + def run_after_filters(chain, index) |
| 734 | + seen_after_filter = false | ||
| 735 | + while chain[index] | ||
| 736 | + filter, index = skip_excluded_filters(chain, index) | ||
| 737 | + break unless filter # end of call chain reached | ||
| 738 | + case filter.type | ||
| 739 | + when :after | ||
| 740 | + seen_after_filter = true | ||
| 741 | + filter.run(self) # invoke after filter | ||
| 661 | else | 742 | else |
| 662 | - process_cleanup_without_filters | 743 | + # implementation error or someone has mucked with the filter chain |
| 744 | + raise ActionControllerError, "filter #{filter.inspect} was in the wrong place!" if seen_after_filter | ||
| 663 | end | 745 | end |
| 746 | + index = index.next | ||
| 747 | + end | ||
| 748 | + index.next | ||
| 749 | + end | ||
| 750 | + | ||
| 751 | + def halt_filter_chain(filter, reason) | ||
| 752 | + @before_filter_chain_aborted = true | ||
| 753 | + logger.info "Filter chain halted as [#{filter.inspect}] #{reason}." if logger | ||
| 754 | + false | ||
| 755 | + end | ||
| 756 | + | ||
| 757 | + def process_cleanup_with_filters | ||
| 758 | + if @before_filter_chain_aborted | ||
| 759 | + close_session | ||
| 760 | + else | ||
| 761 | + process_cleanup_without_filters | ||
| 664 | end | 762 | end |
| 763 | + end | ||
| 665 | end | 764 | end |
| 666 | end | 765 | end |
| 667 | end | 766 | end |
vendor/rails/actionpack/lib/action_controller/integration.rb
| @@ -67,7 +67,7 @@ module ActionController | @@ -67,7 +67,7 @@ module ActionController | ||
| 67 | @https = false | 67 | @https = false |
| 68 | @cookies = {} | 68 | @cookies = {} |
| 69 | @controller = @request = @response = nil | 69 | @controller = @request = @response = nil |
| 70 | - | 70 | + |
| 71 | self.host = "www.example.com" | 71 | self.host = "www.example.com" |
| 72 | self.remote_addr = "127.0.0.1" | 72 | self.remote_addr = "127.0.0.1" |
| 73 | self.accept = "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5" | 73 | self.accept = "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5" |
| @@ -89,7 +89,7 @@ module ActionController | @@ -89,7 +89,7 @@ module ActionController | ||
| 89 | # session.https! | 89 | # session.https! |
| 90 | # session.https!(false) | 90 | # session.https!(false) |
| 91 | def https!(flag=true) | 91 | def https!(flag=true) |
| 92 | - @https = flag | 92 | + @https = flag |
| 93 | end | 93 | end |
| 94 | 94 | ||
| 95 | # Return +true+ if the session is mimicing a secure HTTPS request. | 95 | # Return +true+ if the session is mimicing a secure HTTPS request. |
| @@ -143,10 +143,10 @@ module ActionController | @@ -143,10 +143,10 @@ module ActionController | ||
| 143 | # Performs a GET request with the given parameters. The parameters may | 143 | # Performs a GET request with the given parameters. The parameters may |
| 144 | # be +nil+, a Hash, or a string that is appropriately encoded | 144 | # be +nil+, a Hash, or a string that is appropriately encoded |
| 145 | # (application/x-www-form-urlencoded or multipart/form-data). The headers | 145 | # (application/x-www-form-urlencoded or multipart/form-data). The headers |
| 146 | - # should be a hash. The keys will automatically be upcased, with the | 146 | + # should be a hash. The keys will automatically be upcased, with the |
| 147 | # prefix 'HTTP_' added if needed. | 147 | # prefix 'HTTP_' added if needed. |
| 148 | # | 148 | # |
| 149 | - # You can also perform POST, PUT, DELETE, and HEAD requests with #post, | 149 | + # You can also perform POST, PUT, DELETE, and HEAD requests with #post, |
| 150 | # #put, #delete, and #head. | 150 | # #put, #delete, and #head. |
| 151 | def get(path, parameters=nil, headers=nil) | 151 | def get(path, parameters=nil, headers=nil) |
| 152 | process :get, path, parameters, headers | 152 | process :get, path, parameters, headers |
| @@ -161,31 +161,41 @@ module ActionController | @@ -161,31 +161,41 @@ module ActionController | ||
| 161 | def put(path, parameters=nil, headers=nil) | 161 | def put(path, parameters=nil, headers=nil) |
| 162 | process :put, path, parameters, headers | 162 | process :put, path, parameters, headers |
| 163 | end | 163 | end |
| 164 | - | 164 | + |
| 165 | # Performs a DELETE request with the given parameters. See get() for more details. | 165 | # Performs a DELETE request with the given parameters. See get() for more details. |
| 166 | def delete(path, parameters=nil, headers=nil) | 166 | def delete(path, parameters=nil, headers=nil) |
| 167 | process :delete, path, parameters, headers | 167 | process :delete, path, parameters, headers |
| 168 | end | 168 | end |
| 169 | - | 169 | + |
| 170 | # Performs a HEAD request with the given parameters. See get() for more details. | 170 | # Performs a HEAD request with the given parameters. See get() for more details. |
| 171 | def head(path, parameters=nil, headers=nil) | 171 | def head(path, parameters=nil, headers=nil) |
| 172 | process :head, path, parameters, headers | 172 | process :head, path, parameters, headers |
| 173 | end | 173 | end |
| 174 | 174 | ||
| 175 | - # Performs an XMLHttpRequest request with the given parameters, mimicing | ||
| 176 | - # the request environment created by the Prototype library. The parameters | ||
| 177 | - # may be +nil+, a Hash, or a string that is appropriately encoded | ||
| 178 | - # (application/x-www-form-urlencoded or multipart/form-data). The headers | ||
| 179 | - # should be a hash. The keys will automatically be upcased, with the | ||
| 180 | - # prefix 'HTTP_' added if needed. | ||
| 181 | - def xml_http_request(path, parameters=nil, headers=nil) | ||
| 182 | - headers = (headers || {}).merge( | ||
| 183 | - "X-Requested-With" => "XMLHttpRequest", | ||
| 184 | - "Accept" => "text/javascript, text/html, application/xml, text/xml, */*" | ||
| 185 | - ) | 175 | + # Performs an XMLHttpRequest request with the given parameters, mirroring |
| 176 | + # a request from the Prototype library. | ||
| 177 | + # | ||
| 178 | + # The request_method is :get, :post, :put, :delete or :head; the | ||
| 179 | + # parameters are +nil+, a hash, or a url-encoded or multipart string; | ||
| 180 | + # the headers are a hash. Keys are automatically upcased and prefixed | ||
| 181 | + # with 'HTTP_' if not already. | ||
| 182 | + # | ||
| 183 | + # This method used to omit the request_method parameter, assuming it | ||
| 184 | + # was :post. This was deprecated in Rails 1.2.4. Always pass the request | ||
| 185 | + # method as the first argument. | ||
| 186 | + def xml_http_request(request_method, path, parameters = nil, headers = nil) | ||
| 187 | + unless request_method.is_a?(Symbol) | ||
| 188 | + ActiveSupport::Deprecation.warn 'xml_http_request now takes the request_method (:get, :post, etc.) as the first argument. It used to assume :post, so add the :post argument to your existing method calls to silence this warning.' | ||
| 189 | + request_method, path, parameters, headers = :post, request_method, path, parameters | ||
| 190 | + end | ||
| 191 | + | ||
| 192 | + headers ||= {} | ||
| 193 | + headers['X-Requested-With'] = 'XMLHttpRequest' | ||
| 194 | + headers['Accept'] = 'text/javascript, text/html, application/xml, text/xml, */*' | ||
| 186 | 195 | ||
| 187 | - post(path, parameters, headers) | 196 | + process(request_method, path, parameters, headers) |
| 188 | end | 197 | end |
| 198 | + alias xhr :xml_http_request | ||
| 189 | 199 | ||
| 190 | # Returns the URL for the given options, according to the rules specified | 200 | # Returns the URL for the given options, according to the rules specified |
| 191 | # in the application's routes. | 201 | # in the application's routes. |
| @@ -292,7 +302,7 @@ module ActionController | @@ -292,7 +302,7 @@ module ActionController | ||
| 292 | @status = @status.to_i | 302 | @status = @status.to_i |
| 293 | end | 303 | end |
| 294 | 304 | ||
| 295 | - # Encode the cookies hash in a format suitable for passing to a | 305 | + # Encode the cookies hash in a format suitable for passing to a |
| 296 | # request. | 306 | # request. |
| 297 | def encode_cookies | 307 | def encode_cookies |
| 298 | cookies.inject("") do |string, (name, value)| | 308 | cookies.inject("") do |string, (name, value)| |
| @@ -450,7 +460,7 @@ module ActionController | @@ -450,7 +460,7 @@ module ActionController | ||
| 450 | # without any test methods. | 460 | # without any test methods. |
| 451 | def run(*args) #:nodoc: | 461 | def run(*args) #:nodoc: |
| 452 | return if @method_name == "default_test" | 462 | return if @method_name == "default_test" |
| 453 | - super | 463 | + super |
| 454 | end | 464 | end |
| 455 | 465 | ||
| 456 | # Because of how use_instantiated_fixtures and use_transactional_fixtures | 466 | # Because of how use_instantiated_fixtures and use_transactional_fixtures |
| @@ -490,7 +500,7 @@ module ActionController | @@ -490,7 +500,7 @@ module ActionController | ||
| 490 | @integration_session = open_session | 500 | @integration_session = open_session |
| 491 | end | 501 | end |
| 492 | 502 | ||
| 493 | - %w(get post cookies assigns xml_http_request).each do |method| | 503 | + %w(get post put head delete cookies assigns xml_http_request).each do |method| |
| 494 | define_method(method) do |*args| | 504 | define_method(method) do |*args| |
| 495 | reset! unless @integration_session | 505 | reset! unless @integration_session |
| 496 | # reset the html_document variable, but only for new get/post calls | 506 | # reset the html_document variable, but only for new get/post calls |
vendor/rails/actionpack/lib/action_controller/macros/in_place_editing.rb
| @@ -24,7 +24,7 @@ module ActionController | @@ -24,7 +24,7 @@ module ActionController | ||
| 24 | define_method("set_#{object}_#{attribute}") do | 24 | define_method("set_#{object}_#{attribute}") do |
| 25 | @item = object.to_s.camelize.constantize.find(params[:id]) | 25 | @item = object.to_s.camelize.constantize.find(params[:id]) |
| 26 | @item.update_attribute(attribute, params[:value]) | 26 | @item.update_attribute(attribute, params[:value]) |
| 27 | - render :text => @item.send(attribute) | 27 | + render :text => @item.send(attribute).to_s |
| 28 | end | 28 | end |
| 29 | end | 29 | end |
| 30 | end | 30 | end |
vendor/rails/actionpack/lib/action_controller/pagination.rb
| 1 | module ActionController | 1 | module ActionController |
| 2 | # === Action Pack pagination for Active Record collections | 2 | # === Action Pack pagination for Active Record collections |
| 3 | # | 3 | # |
| 4 | - # DEPRECATION WARNING: Pagination will be separated into its own plugin with Rails 2.0. | 4 | + # DEPRECATION WARNING: Pagination will be moved to a plugin in Rails 2.0. |
| 5 | + # Install the classic_pagination plugin for forward compatibility: | ||
| 6 | + # script/plugin install svn://errtheblog.com/svn/plugins/classic_pagination | ||
| 5 | # | 7 | # |
| 6 | # The Pagination module aids in the process of paging large collections of | 8 | # The Pagination module aids in the process of paging large collections of |
| 7 | # Active Record objects. It offers macro-style automatic fetching of your | 9 | # Active Record objects. It offers macro-style automatic fetching of your |
| @@ -130,6 +132,8 @@ module ActionController | @@ -130,6 +132,8 @@ module ActionController | ||
| 130 | paginator_and_collection_for(collection_id, options) | 132 | paginator_and_collection_for(collection_id, options) |
| 131 | end | 133 | end |
| 132 | 134 | ||
| 135 | + deprecate :paginate => 'Pagination is moving to a plugin in Rails 2.0: script/plugin install svn://errtheblog.com/svn/plugins/classic_pagination' | ||
| 136 | + | ||
| 133 | # These methods become class methods on any controller | 137 | # These methods become class methods on any controller |
| 134 | module ClassMethods | 138 | module ClassMethods |
| 135 | # Creates a +before_filter+ which automatically paginates an Active | 139 | # Creates a +before_filter+ which automatically paginates an Active |
| @@ -148,6 +152,8 @@ module ActionController | @@ -148,6 +152,8 @@ module ActionController | ||
| 148 | OPTIONS[self][collection_id] = options | 152 | OPTIONS[self][collection_id] = options |
| 149 | end | 153 | end |
| 150 | end | 154 | end |
| 155 | + | ||
| 156 | + deprecate :paginate => 'Pagination is moving to a plugin in Rails 2.0: script/plugin install svn://errtheblog.com/svn/plugins/classic_pagination' | ||
| 151 | end | 157 | end |
| 152 | 158 | ||
| 153 | def create_paginators_and_retrieve_collections #:nodoc: | 159 | def create_paginators_and_retrieve_collections #:nodoc: |
vendor/rails/actionpack/lib/action_controller/resources.rb
| @@ -2,48 +2,68 @@ module ActionController | @@ -2,48 +2,68 @@ module ActionController | ||
| 2 | module Resources | 2 | module Resources |
| 3 | class Resource #:nodoc: | 3 | class Resource #:nodoc: |
| 4 | attr_reader :collection_methods, :member_methods, :new_methods | 4 | attr_reader :collection_methods, :member_methods, :new_methods |
| 5 | - attr_reader :path_prefix, :name_prefix | 5 | + attr_reader :path_prefix, :new_name_prefix |
| 6 | attr_reader :plural, :singular | 6 | attr_reader :plural, :singular |
| 7 | attr_reader :options | 7 | attr_reader :options |
| 8 | 8 | ||
| 9 | def initialize(entities, options) | 9 | def initialize(entities, options) |
| 10 | @plural = entities | 10 | @plural = entities |
| 11 | @singular = options[:singular] || plural.to_s.singularize | 11 | @singular = options[:singular] || plural.to_s.singularize |
| 12 | - | 12 | + |
| 13 | @options = options | 13 | @options = options |
| 14 | 14 | ||
| 15 | arrange_actions | 15 | arrange_actions |
| 16 | add_default_actions | 16 | add_default_actions |
| 17 | set_prefixes | 17 | set_prefixes |
| 18 | end | 18 | end |
| 19 | - | 19 | + |
| 20 | def controller | 20 | def controller |
| 21 | @controller ||= (options[:controller] || plural).to_s | 21 | @controller ||= (options[:controller] || plural).to_s |
| 22 | end | 22 | end |
| 23 | - | 23 | + |
| 24 | def path | 24 | def path |
| 25 | @path ||= "#{path_prefix}/#{plural}" | 25 | @path ||= "#{path_prefix}/#{plural}" |
| 26 | end | 26 | end |
| 27 | - | 27 | + |
| 28 | def new_path | 28 | def new_path |
| 29 | @new_path ||= "#{path}/new" | 29 | @new_path ||= "#{path}/new" |
| 30 | end | 30 | end |
| 31 | - | 31 | + |
| 32 | def member_path | 32 | def member_path |
| 33 | @member_path ||= "#{path}/:id" | 33 | @member_path ||= "#{path}/:id" |
| 34 | end | 34 | end |
| 35 | - | 35 | + |
| 36 | def nesting_path_prefix | 36 | def nesting_path_prefix |
| 37 | @nesting_path_prefix ||= "#{path}/:#{singular}_id" | 37 | @nesting_path_prefix ||= "#{path}/:#{singular}_id" |
| 38 | end | 38 | end |
| 39 | - | 39 | + |
| 40 | + def deprecate_name_prefix? | ||
| 41 | + @name_prefix.blank? && !@new_name_prefix.blank? | ||
| 42 | + end | ||
| 43 | + | ||
| 44 | + def name_prefix | ||
| 45 | + deprecate_name_prefix? ? @new_name_prefix : @name_prefix | ||
| 46 | + end | ||
| 47 | + | ||
| 48 | + def old_name_prefix | ||
| 49 | + @name_prefix | ||
| 50 | + end | ||
| 51 | + | ||
| 52 | + def nesting_name_prefix | ||
| 53 | + "#{new_name_prefix}#{singular}_" | ||
| 54 | + end | ||
| 55 | + | ||
| 56 | + def action_separator | ||
| 57 | + @action_separator ||= Base.resource_action_separator | ||
| 58 | + end | ||
| 59 | + | ||
| 40 | protected | 60 | protected |
| 41 | def arrange_actions | 61 | def arrange_actions |
| 42 | @collection_methods = arrange_actions_by_methods(options.delete(:collection)) | 62 | @collection_methods = arrange_actions_by_methods(options.delete(:collection)) |
| 43 | @member_methods = arrange_actions_by_methods(options.delete(:member)) | 63 | @member_methods = arrange_actions_by_methods(options.delete(:member)) |
| 44 | @new_methods = arrange_actions_by_methods(options.delete(:new)) | 64 | @new_methods = arrange_actions_by_methods(options.delete(:new)) |
| 45 | end | 65 | end |
| 46 | - | 66 | + |
| 47 | def add_default_actions | 67 | def add_default_actions |
| 48 | add_default_action(member_methods, :get, :edit) | 68 | add_default_action(member_methods, :get, :edit) |
| 49 | add_default_action(new_methods, :get, :new) | 69 | add_default_action(new_methods, :get, :new) |
| @@ -52,6 +72,7 @@ module ActionController | @@ -52,6 +72,7 @@ module ActionController | ||
| 52 | def set_prefixes | 72 | def set_prefixes |
| 53 | @path_prefix = options.delete(:path_prefix) | 73 | @path_prefix = options.delete(:path_prefix) |
| 54 | @name_prefix = options.delete(:name_prefix) | 74 | @name_prefix = options.delete(:name_prefix) |
| 75 | + @new_name_prefix = options.delete(:new_name_prefix) | ||
| 55 | end | 76 | end |
| 56 | 77 | ||
| 57 | def arrange_actions_by_methods(actions) | 78 | def arrange_actions_by_methods(actions) |
| @@ -60,7 +81,7 @@ module ActionController | @@ -60,7 +81,7 @@ module ActionController | ||
| 60 | flipped_hash | 81 | flipped_hash |
| 61 | end | 82 | end |
| 62 | end | 83 | end |
| 63 | - | 84 | + |
| 64 | def add_default_action(collection, method, action) | 85 | def add_default_action(collection, method, action) |
| 65 | (collection[method] ||= []).unshift(action) | 86 | (collection[method] ||= []).unshift(action) |
| 66 | end | 87 | end |
| @@ -178,11 +199,11 @@ module ActionController | @@ -178,11 +199,11 @@ module ActionController | ||
| 178 | # | 199 | # |
| 179 | # The comment resources work the same, but must now include a value for :article_id. | 200 | # The comment resources work the same, but must now include a value for :article_id. |
| 180 | # | 201 | # |
| 181 | - # comments_url(@article) | ||
| 182 | - # comment_url(@article, @comment) | 202 | + # article_comments_url(@article) |
| 203 | + # article_comment_url(@article, @comment) | ||
| 183 | # | 204 | # |
| 184 | - # comments_url(:article_id => @article) | ||
| 185 | - # comment_url(:article_id => @article, :id => @comment) | 205 | + # article_comments_url(:article_id => @article) |
| 206 | + # article_comment_url(:article_id => @article, :id => @comment) | ||
| 186 | # | 207 | # |
| 187 | # * <tt>:name_prefix</tt> -- define a prefix for all generated routes, usually ending in an underscore. | 208 | # * <tt>:name_prefix</tt> -- define a prefix for all generated routes, usually ending in an underscore. |
| 188 | # Use this if you have named routes that may clash. | 209 | # Use this if you have named routes that may clash. |
| @@ -192,7 +213,7 @@ module ActionController | @@ -192,7 +213,7 @@ module ActionController | ||
| 192 | # | 213 | # |
| 193 | # * <tt>:collection</tt> -- add named routes for other actions that operate on the collection. | 214 | # * <tt>:collection</tt> -- add named routes for other actions that operate on the collection. |
| 194 | # Takes a hash of <tt>#{action} => #{method}</tt>, where method is <tt>:get</tt>/<tt>:post</tt>/<tt>:put</tt>/<tt>:delete</tt> | 215 | # Takes a hash of <tt>#{action} => #{method}</tt>, where method is <tt>:get</tt>/<tt>:post</tt>/<tt>:put</tt>/<tt>:delete</tt> |
| 195 | - # or <tt>:any</tt> if the method does not matter. These routes map to a URL like /messages;rss, with a route of rss_messages_url. | 216 | + # or <tt>:any</tt> if the method does not matter. These routes map to a URL like /messages/rss, with a route of rss_messages_url. |
| 196 | # * <tt>:member</tt> -- same as :collection, but for actions that operate on a specific member. | 217 | # * <tt>:member</tt> -- same as :collection, but for actions that operate on a specific member. |
| 197 | # * <tt>:new</tt> -- same as :collection, but for actions that operate on the new resource action. | 218 | # * <tt>:new</tt> -- same as :collection, but for actions that operate on the new resource action. |
| 198 | # | 219 | # |
| @@ -204,19 +225,19 @@ module ActionController | @@ -204,19 +225,19 @@ module ActionController | ||
| 204 | # # --> GET /thread/7/messages/1 | 225 | # # --> GET /thread/7/messages/1 |
| 205 | # | 226 | # |
| 206 | # map.resources :messages, :collection => { :rss => :get } | 227 | # map.resources :messages, :collection => { :rss => :get } |
| 207 | - # # --> GET /messages;rss (maps to the #rss action) | 228 | + # # --> GET /messages/rss (maps to the #rss action) |
| 208 | # # also adds a named route called "rss_messages" | 229 | # # also adds a named route called "rss_messages" |
| 209 | # | 230 | # |
| 210 | # map.resources :messages, :member => { :mark => :post } | 231 | # map.resources :messages, :member => { :mark => :post } |
| 211 | - # # --> POST /messages/1;mark (maps to the #mark action) | 232 | + # # --> POST /messages/1/mark (maps to the #mark action) |
| 212 | # # also adds a named route called "mark_message" | 233 | # # also adds a named route called "mark_message" |
| 213 | # | 234 | # |
| 214 | # map.resources :messages, :new => { :preview => :post } | 235 | # map.resources :messages, :new => { :preview => :post } |
| 215 | - # # --> POST /messages/new;preview (maps to the #preview action) | 236 | + # # --> POST /messages/new/preview (maps to the #preview action) |
| 216 | # # also adds a named route called "preview_new_message" | 237 | # # also adds a named route called "preview_new_message" |
| 217 | # | 238 | # |
| 218 | # map.resources :messages, :new => { :new => :any, :preview => :post } | 239 | # map.resources :messages, :new => { :new => :any, :preview => :post } |
| 219 | - # # --> POST /messages/new;preview (maps to the #preview action) | 240 | + # # --> POST /messages/new/preview (maps to the #preview action) |
| 220 | # # also adds a named route called "preview_new_message" | 241 | # # also adds a named route called "preview_new_message" |
| 221 | # # --> /messages/new can be invoked via any request method | 242 | # # --> /messages/new can be invoked via any request method |
| 222 | # | 243 | # |
| @@ -235,9 +256,10 @@ module ActionController | @@ -235,9 +256,10 @@ module ActionController | ||
| 235 | # /account profile. | 256 | # /account profile. |
| 236 | # | 257 | # |
| 237 | # See map.resources for general conventions. These are the main differences: | 258 | # See map.resources for general conventions. These are the main differences: |
| 238 | - # - a singular name is given to map.resource. The default controller name is taken from the singular name. | ||
| 239 | - # - To specify a custom plural name, use the :plural option. There is no :singular option | ||
| 240 | - # - No default index, new, or create routes are created for the singleton resource controller. | 259 | + # - A singular name is given to map.resource. The default controller name is taken from the singular name. |
| 260 | + # - There is no <tt>:collection</tt> option as there is only the singleton resource. | ||
| 261 | + # - There is no <tt>:singular</tt> option as the singular name is passed to map.resource. | ||
| 262 | + # - No default index route is created for the singleton resource controller. | ||
| 241 | # - When nesting singleton resources, only the singular name is used as the path prefix (example: 'account/messages/1') | 263 | # - When nesting singleton resources, only the singular name is used as the path prefix (example: 'account/messages/1') |
| 242 | # | 264 | # |
| 243 | # Example: | 265 | # Example: |
| @@ -300,7 +322,7 @@ module ActionController | @@ -300,7 +322,7 @@ module ActionController | ||
| 300 | map_member_actions(map, resource) | 322 | map_member_actions(map, resource) |
| 301 | 323 | ||
| 302 | if block_given? | 324 | if block_given? |
| 303 | - with_options(:path_prefix => resource.nesting_path_prefix, &block) | 325 | + with_options(:path_prefix => resource.nesting_path_prefix, :new_name_prefix => resource.nesting_name_prefix, &block) |
| 304 | end | 326 | end |
| 305 | end | 327 | end |
| 306 | end | 328 | end |
| @@ -315,7 +337,7 @@ module ActionController | @@ -315,7 +337,7 @@ module ActionController | ||
| 315 | map_member_actions(map, resource) | 337 | map_member_actions(map, resource) |
| 316 | 338 | ||
| 317 | if block_given? | 339 | if block_given? |
| 318 | - with_options(:path_prefix => resource.nesting_path_prefix, &block) | 340 | + with_options(:path_prefix => resource.nesting_path_prefix, :new_name_prefix => resource.nesting_name_prefix, &block) |
| 319 | end | 341 | end |
| 320 | end | 342 | end |
| 321 | end | 343 | end |
| @@ -324,8 +346,21 @@ module ActionController | @@ -324,8 +346,21 @@ module ActionController | ||
| 324 | resource.collection_methods.each do |method, actions| | 346 | resource.collection_methods.each do |method, actions| |
| 325 | actions.each do |action| | 347 | actions.each do |action| |
| 326 | action_options = action_options_for(action, resource, method) | 348 | action_options = action_options_for(action, resource, method) |
| 327 | - map.named_route("#{resource.name_prefix}#{action}_#{resource.plural}", "#{resource.path};#{action}", action_options) | ||
| 328 | - map.named_route("formatted_#{resource.name_prefix}#{action}_#{resource.plural}", "#{resource.path}.:format;#{action}", action_options) | 349 | + |
| 350 | + unless resource.old_name_prefix.blank? | ||
| 351 | + map.deprecated_named_route("#{action}_#{resource.name_prefix}#{resource.plural}", "#{resource.old_name_prefix}#{action}_#{resource.plural}") | ||
| 352 | + map.deprecated_named_route("formatted_#{action}_#{resource.name_prefix}#{resource.plural}", "formatted_#{resource.old_name_prefix}#{action}_#{resource.plural}") | ||
| 353 | + end | ||
| 354 | + | ||
| 355 | + if resource.deprecate_name_prefix? | ||
| 356 | + map.deprecated_named_route("#{action}_#{resource.name_prefix}#{resource.plural}", "#{action}_#{resource.plural}") | ||
| 357 | + map.deprecated_named_route("formatted_#{action}_#{resource.name_prefix}#{resource.plural}", "formatted_#{action}_#{resource.plural}") | ||
| 358 | + end | ||
| 359 | + | ||
| 360 | + map.named_route("#{action}_#{resource.name_prefix}#{resource.plural}", "#{resource.path}#{resource.action_separator}#{action}", action_options) | ||
| 361 | + map.connect("#{resource.path};#{action}", action_options) | ||
| 362 | + map.connect("#{resource.path}.:format;#{action}", action_options) | ||
| 363 | + map.named_route("formatted_#{action}_#{resource.name_prefix}#{resource.plural}", "#{resource.path}#{resource.action_separator}#{action}.:format", action_options) | ||
| 329 | end | 364 | end |
| 330 | end | 365 | end |
| 331 | end | 366 | end |
| @@ -335,6 +370,11 @@ module ActionController | @@ -335,6 +370,11 @@ module ActionController | ||
| 335 | map.named_route("#{resource.name_prefix}#{resource.plural}", resource.path, index_action_options) | 370 | map.named_route("#{resource.name_prefix}#{resource.plural}", resource.path, index_action_options) |
| 336 | map.named_route("formatted_#{resource.name_prefix}#{resource.plural}", "#{resource.path}.:format", index_action_options) | 371 | map.named_route("formatted_#{resource.name_prefix}#{resource.plural}", "#{resource.path}.:format", index_action_options) |
| 337 | 372 | ||
| 373 | + if resource.deprecate_name_prefix? | ||
| 374 | + map.deprecated_named_route("#{resource.name_prefix}#{resource.plural}", "#{resource.plural}") | ||
| 375 | + map.deprecated_named_route("formatted_#{resource.name_prefix}#{resource.plural}", "formatted_#{resource.plural}") | ||
| 376 | + end | ||
| 377 | + | ||
| 338 | create_action_options = action_options_for("create", resource) | 378 | create_action_options = action_options_for("create", resource) |
| 339 | map.connect(resource.path, create_action_options) | 379 | map.connect(resource.path, create_action_options) |
| 340 | map.connect("#{resource.path}.:format", create_action_options) | 380 | map.connect("#{resource.path}.:format", create_action_options) |
| @@ -351,11 +391,37 @@ module ActionController | @@ -351,11 +391,37 @@ module ActionController | ||
| 351 | actions.each do |action| | 391 | actions.each do |action| |
| 352 | action_options = action_options_for(action, resource, method) | 392 | action_options = action_options_for(action, resource, method) |
| 353 | if action == :new | 393 | if action == :new |
| 354 | - map.named_route("#{resource.name_prefix}new_#{resource.singular}", resource.new_path, action_options) | ||
| 355 | - map.named_route("formatted_#{resource.name_prefix}new_#{resource.singular}", "#{resource.new_path}.:format", action_options) | 394 | + |
| 395 | + unless resource.old_name_prefix.blank? | ||
| 396 | + map.deprecated_named_route("new_#{resource.name_prefix}#{resource.singular}", "#{resource.old_name_prefix}new_#{resource.singular}") | ||
| 397 | + map.deprecated_named_route("formatted_new_#{resource.name_prefix}#{resource.singular}", "formatted_#{resource.old_name_prefix}new_#{resource.singular}") | ||
| 398 | + end | ||
| 399 | + | ||
| 400 | + if resource.deprecate_name_prefix? | ||
| 401 | + map.deprecated_named_route("new_#{resource.name_prefix}#{resource.singular}", "new_#{resource.singular}") | ||
| 402 | + map.deprecated_named_route("formatted_new_#{resource.name_prefix}#{resource.singular}", "formatted_new_#{resource.singular}") | ||
| 403 | + end | ||
| 404 | + | ||
| 405 | + map.named_route("new_#{resource.name_prefix}#{resource.singular}", resource.new_path, action_options) | ||
| 406 | + map.named_route("formatted_new_#{resource.name_prefix}#{resource.singular}", "#{resource.new_path}.:format", action_options) | ||
| 407 | + | ||
| 356 | else | 408 | else |
| 357 | - map.named_route("#{resource.name_prefix}#{action}_new_#{resource.singular}", "#{resource.new_path};#{action}", action_options) | ||
| 358 | - map.named_route("formatted_#{resource.name_prefix}#{action}_new_#{resource.singular}", "#{resource.new_path}.:format;#{action}", action_options) | 409 | + |
| 410 | + unless resource.old_name_prefix.blank? | ||
| 411 | + map.deprecated_named_route("#{action}_new_#{resource.name_prefix}#{resource.singular}", "#{resource.old_name_prefix}#{action}_new_#{resource.singular}") | ||
| 412 | + map.deprecated_named_route("formatted_#{action}_new_#{resource.name_prefix}#{resource.singular}", "formatted_#{resource.old_name_prefix}#{action}_new_#{resource.singular}") | ||
| 413 | + end | ||
| 414 | + | ||
| 415 | + if resource.deprecate_name_prefix? | ||
| 416 | + map.deprecated_named_route("#{action}_new_#{resource.name_prefix}#{resource.singular}", "#{action}_new_#{resource.singular}") | ||
| 417 | + map.deprecated_named_route("formatted_#{action}_new_#{resource.name_prefix}#{resource.singular}", "formatted_#{action}_new_#{resource.singular}") | ||
| 418 | + end | ||
| 419 | + | ||
| 420 | + map.named_route("#{action}_new_#{resource.name_prefix}#{resource.singular}", "#{resource.new_path}#{resource.action_separator}#{action}", action_options) | ||
| 421 | + map.connect("#{resource.new_path};#{action}", action_options) | ||
| 422 | + map.connect("#{resource.new_path}.:format;#{action}", action_options) | ||
| 423 | + map.named_route("formatted_#{action}_new_#{resource.name_prefix}#{resource.singular}", "#{resource.new_path}#{resource.action_separator}#{action}.:format", action_options) | ||
| 424 | + | ||
| 359 | end | 425 | end |
| 360 | end | 426 | end |
| 361 | end | 427 | end |
| @@ -365,8 +431,22 @@ module ActionController | @@ -365,8 +431,22 @@ module ActionController | ||
| 365 | resource.member_methods.each do |method, actions| | 431 | resource.member_methods.each do |method, actions| |
| 366 | actions.each do |action| | 432 | actions.each do |action| |
| 367 | action_options = action_options_for(action, resource, method) | 433 | action_options = action_options_for(action, resource, method) |
| 368 | - map.named_route("#{resource.name_prefix}#{action}_#{resource.singular}", "#{resource.member_path};#{action}", action_options) | ||
| 369 | - map.named_route("formatted_#{resource.name_prefix}#{action}_#{resource.singular}", "#{resource.member_path}.:format;#{action}",action_options) | 434 | + |
| 435 | + unless resource.old_name_prefix.blank? | ||
| 436 | + map.deprecated_named_route("#{action}_#{resource.name_prefix}#{resource.singular}", "#{resource.old_name_prefix}#{action}_#{resource.singular}") | ||
| 437 | + map.deprecated_named_route("formatted_#{action}_#{resource.name_prefix}#{resource.singular}", "formatted_#{resource.old_name_prefix}#{action}_#{resource.singular}") | ||
| 438 | + end | ||
| 439 | + | ||
| 440 | + if resource.deprecate_name_prefix? | ||
| 441 | + map.deprecated_named_route("#{action}_#{resource.name_prefix}#{resource.singular}", "#{action}_#{resource.singular}") | ||
| 442 | + map.deprecated_named_route("formatted_#{action}_#{resource.name_prefix}#{resource.singular}", "formatted_#{action}_#{resource.singular}") | ||
| 443 | + end | ||
| 444 | + | ||
| 445 | + map.named_route("#{action}_#{resource.name_prefix}#{resource.singular}", "#{resource.member_path}#{resource.action_separator}#{action}", action_options) | ||
| 446 | + map.connect("#{resource.member_path};#{action}", action_options) | ||
| 447 | + map.connect("#{resource.member_path}.:format;#{action}", action_options) | ||
| 448 | + map.named_route("formatted_#{action}_#{resource.name_prefix}#{resource.singular}", "#{resource.member_path}#{resource.action_separator}#{action}.:format", action_options) | ||
| 449 | + | ||
| 370 | end | 450 | end |
| 371 | end | 451 | end |
| 372 | 452 | ||
| @@ -374,6 +454,11 @@ module ActionController | @@ -374,6 +454,11 @@ module ActionController | ||
| 374 | map.named_route("#{resource.name_prefix}#{resource.singular}", resource.member_path, show_action_options) | 454 | map.named_route("#{resource.name_prefix}#{resource.singular}", resource.member_path, show_action_options) |
| 375 | map.named_route("formatted_#{resource.name_prefix}#{resource.singular}", "#{resource.member_path}.:format", show_action_options) | 455 | map.named_route("formatted_#{resource.name_prefix}#{resource.singular}", "#{resource.member_path}.:format", show_action_options) |
| 376 | 456 | ||
| 457 | + if resource.deprecate_name_prefix? | ||
| 458 | + map.deprecated_named_route("#{resource.name_prefix}#{resource.singular}", "#{resource.singular}") | ||
| 459 | + map.deprecated_named_route("formatted_#{resource.name_prefix}#{resource.singular}", "formatted_#{resource.singular}") | ||
| 460 | + end | ||
| 461 | + | ||
| 377 | update_action_options = action_options_for("update", resource) | 462 | update_action_options = action_options_for("update", resource) |
| 378 | map.connect(resource.member_path, update_action_options) | 463 | map.connect(resource.member_path, update_action_options) |
| 379 | map.connect("#{resource.member_path}.:format", update_action_options) | 464 | map.connect("#{resource.member_path}.:format", update_action_options) |
vendor/rails/actionpack/lib/action_controller/routing.rb
| @@ -451,26 +451,17 @@ module ActionController | @@ -451,26 +451,17 @@ module ActionController | ||
| 451 | # is given (as an array), only the keys indicated will be used to build | 451 | # is given (as an array), only the keys indicated will be used to build |
| 452 | # the query string. The query string will correctly build array parameter | 452 | # the query string. The query string will correctly build array parameter |
| 453 | # values. | 453 | # values. |
| 454 | - def build_query_string(hash, only_keys=nil) | 454 | + def build_query_string(hash, only_keys = nil) |
| 455 | elements = [] | 455 | elements = [] |
| 456 | - | ||
| 457 | - only_keys ||= hash.keys | ||
| 458 | - | ||
| 459 | - only_keys.each do |key| | ||
| 460 | - value = hash[key] or next | ||
| 461 | - key = CGI.escape key.to_s | ||
| 462 | - if value.class == Array | ||
| 463 | - key << '[]' | ||
| 464 | - else | ||
| 465 | - value = [ value ] | ||
| 466 | - end | ||
| 467 | - value.each { |val| elements << "#{key}=#{CGI.escape(val.to_param.to_s)}" } | ||
| 468 | - end | ||
| 469 | 456 | ||
| 470 | - query_string = "?#{elements.join("&")}" unless elements.empty? | ||
| 471 | - query_string || "" | 457 | + (only_keys || hash.keys).each do |key| |
| 458 | + if value = hash[key] | ||
| 459 | + elements << value.to_query(key) | ||
| 460 | + end | ||
| 461 | + end | ||
| 462 | + elements.empty? ? '' : "?#{elements.sort * '&'}" | ||
| 472 | end | 463 | end |
| 473 | - | 464 | + |
| 474 | # Write the real recognition implementation and then resend the message. | 465 | # Write the real recognition implementation and then resend the message. |
| 475 | def recognize(path, environment={}) | 466 | def recognize(path, environment={}) |
| 476 | write_recognition | 467 | write_recognition |
| @@ -668,7 +659,7 @@ module ActionController | @@ -668,7 +659,7 @@ module ActionController | ||
| 668 | end | 659 | end |
| 669 | 660 | ||
| 670 | def extract_value | 661 | def extract_value |
| 671 | - "#{local_name} = hash[:#{key}] #{"|| #{default.inspect}" if default}" | 662 | + "#{local_name} = hash[:#{key}] && hash[:#{key}].to_param #{"|| #{default.inspect}" if default}" |
| 672 | end | 663 | end |
| 673 | def value_check | 664 | def value_check |
| 674 | if default # Then we know it won't be nil | 665 | if default # Then we know it won't be nil |
| @@ -989,6 +980,10 @@ module ActionController | @@ -989,6 +980,10 @@ module ActionController | ||
| 989 | def named_route(name, path, options = {}) | 980 | def named_route(name, path, options = {}) |
| 990 | @set.add_named_route(name, path, options) | 981 | @set.add_named_route(name, path, options) |
| 991 | end | 982 | end |
| 983 | + | ||
| 984 | + def deprecated_named_route(name, deprecated_name, options = {}) | ||
| 985 | + @set.add_deprecated_named_route(name, deprecated_name) | ||
| 986 | + end | ||
| 992 | 987 | ||
| 993 | # Added deprecation notice for anyone who already added a named route called "root". | 988 | # Added deprecation notice for anyone who already added a named route called "root". |
| 994 | # It'll be used as a shortcut for map.connect '' in Rails 2.0. | 989 | # It'll be used as a shortcut for map.connect '' in Rails 2.0. |
| @@ -1019,7 +1014,7 @@ module ActionController | @@ -1019,7 +1014,7 @@ module ActionController | ||
| 1019 | def clear! | 1014 | def clear! |
| 1020 | @routes = {} | 1015 | @routes = {} |
| 1021 | @helpers = [] | 1016 | @helpers = [] |
| 1022 | - | 1017 | + |
| 1023 | @module ||= Module.new | 1018 | @module ||= Module.new |
| 1024 | @module.instance_methods.each do |selector| | 1019 | @module.instance_methods.each do |selector| |
| 1025 | @module.send :remove_method, selector | 1020 | @module.send :remove_method, selector |
| @@ -1055,6 +1050,38 @@ module ActionController | @@ -1055,6 +1050,38 @@ module ActionController | ||
| 1055 | def install(destinations = [ActionController::Base, ActionView::Base]) | 1050 | def install(destinations = [ActionController::Base, ActionView::Base]) |
| 1056 | Array(destinations).each { |dest| dest.send :include, @module } | 1051 | Array(destinations).each { |dest| dest.send :include, @module } |
| 1057 | end | 1052 | end |
| 1053 | + | ||
| 1054 | + def define_deprecated_named_route_methods(name, deprecated_name) | ||
| 1055 | + | ||
| 1056 | + [:url, :path].each do |kind| | ||
| 1057 | + @module.send :module_eval, <<-end_eval # We use module_eval to avoid leaks | ||
| 1058 | + | ||
| 1059 | + def #{url_helper_name(deprecated_name, kind)}(*args) | ||
| 1060 | + | ||
| 1061 | + ActiveSupport::Deprecation.warn( | ||
| 1062 | + 'The named route "#{url_helper_name(deprecated_name, kind)}" uses a format that has been deprecated. ' + | ||
| 1063 | + 'You should use "#{url_helper_name(name, kind)}" instead.', caller | ||
| 1064 | + ) | ||
| 1065 | + | ||
| 1066 | + send :#{url_helper_name(name, kind)}, *args | ||
| 1067 | + | ||
| 1068 | + end | ||
| 1069 | + | ||
| 1070 | + def #{hash_access_name(deprecated_name, kind)}(*args) | ||
| 1071 | + | ||
| 1072 | + ActiveSupport::Deprecation.warn( | ||
| 1073 | + 'The named route "#{hash_access_name(deprecated_name, kind)}" uses a format that has been deprecated. ' + | ||
| 1074 | + 'You should use "#{hash_access_name(name, kind)}" instead.', caller | ||
| 1075 | + ) | ||
| 1076 | + | ||
| 1077 | + send :#{hash_access_name(name, kind)}, *args | ||
| 1078 | + | ||
| 1079 | + end | ||
| 1080 | + | ||
| 1081 | + end_eval | ||
| 1082 | + end | ||
| 1083 | + | ||
| 1084 | + end | ||
| 1058 | 1085 | ||
| 1059 | private | 1086 | private |
| 1060 | def url_helper_name(name, kind = :url) | 1087 | def url_helper_name(name, kind = :url) |
| @@ -1177,6 +1204,10 @@ module ActionController | @@ -1177,6 +1204,10 @@ module ActionController | ||
| 1177 | def add_named_route(name, path, options = {}) | 1204 | def add_named_route(name, path, options = {}) |
| 1178 | named_routes[name] = add_route(path, options) | 1205 | named_routes[name] = add_route(path, options) |
| 1179 | end | 1206 | end |
| 1207 | + | ||
| 1208 | + def add_deprecated_named_route(name, deprecated_name) | ||
| 1209 | + named_routes.define_deprecated_named_route_methods(name, deprecated_name) | ||
| 1210 | + end | ||
| 1180 | 1211 | ||
| 1181 | def options_as_params(options) | 1212 | def options_as_params(options) |
| 1182 | # If an explicit :controller was given, always make :action explicit | 1213 | # If an explicit :controller was given, always make :action explicit |
| @@ -1190,10 +1221,9 @@ module ActionController | @@ -1190,10 +1221,9 @@ module ActionController | ||
| 1190 | # | 1221 | # |
| 1191 | # great fun, eh? | 1222 | # great fun, eh? |
| 1192 | 1223 | ||
| 1193 | - options_as_params = options[:controller] ? { :action => "index" } : {} | ||
| 1194 | - options.each do |k, value| | ||
| 1195 | - options_as_params[k] = value.to_param | ||
| 1196 | - end | 1224 | + options_as_params = options.clone |
| 1225 | + options_as_params[:action] ||= 'index' if options[:controller] | ||
| 1226 | + options_as_params[:action] = options_as_params[:action].to_s if options_as_params[:action] | ||
| 1197 | options_as_params | 1227 | options_as_params |
| 1198 | end | 1228 | end |
| 1199 | 1229 | ||
| @@ -1224,6 +1254,9 @@ module ActionController | @@ -1224,6 +1254,9 @@ module ActionController | ||
| 1224 | options = options_as_params(options) | 1254 | options = options_as_params(options) |
| 1225 | expire_on = build_expiry(options, recall) | 1255 | expire_on = build_expiry(options, recall) |
| 1226 | 1256 | ||
| 1257 | + if options[:controller] | ||
| 1258 | + options[:controller] = options[:controller].to_s | ||
| 1259 | + end | ||
| 1227 | # if the controller has changed, make sure it changes relative to the | 1260 | # if the controller has changed, make sure it changes relative to the |
| 1228 | # current controller module, if any. In other words, if we're currently | 1261 | # current controller module, if any. In other words, if we're currently |
| 1229 | # on admin/get, and the new controller is 'set', the new controller | 1262 | # on admin/get, and the new controller is 'set', the new controller |
vendor/rails/actionpack/lib/action_controller/session/drb_server.rb
vendor/rails/actionpack/lib/action_controller/test_process.rb
| @@ -24,6 +24,7 @@ module ActionController #:nodoc: | @@ -24,6 +24,7 @@ module ActionController #:nodoc: | ||
| 24 | attr_accessor :cookies, :session_options | 24 | attr_accessor :cookies, :session_options |
| 25 | attr_accessor :query_parameters, :request_parameters, :path, :session, :env | 25 | attr_accessor :query_parameters, :request_parameters, :path, :session, :env |
| 26 | attr_accessor :host | 26 | attr_accessor :host |
| 27 | + attr_reader :request_uri_overridden | ||
| 27 | 28 | ||
| 28 | def initialize(query_parameters = nil, request_parameters = nil, session = nil) | 29 | def initialize(query_parameters = nil, request_parameters = nil, session = nil) |
| 29 | @query_parameters = query_parameters || {} | 30 | @query_parameters = query_parameters || {} |
| @@ -67,12 +68,14 @@ module ActionController #:nodoc: | @@ -67,12 +68,14 @@ module ActionController #:nodoc: | ||
| 67 | # Used to check AbstractRequest's request_uri functionality. | 68 | # Used to check AbstractRequest's request_uri functionality. |
| 68 | # Disables the use of @path and @request_uri so superclass can handle those. | 69 | # Disables the use of @path and @request_uri so superclass can handle those. |
| 69 | def set_REQUEST_URI(value) | 70 | def set_REQUEST_URI(value) |
| 71 | + @request_uri_overridden = true | ||
| 70 | @env["REQUEST_URI"] = value | 72 | @env["REQUEST_URI"] = value |
| 71 | @request_uri = nil | 73 | @request_uri = nil |
| 72 | @path = nil | 74 | @path = nil |
| 73 | end | 75 | end |
| 74 | 76 | ||
| 75 | def request_uri=(uri) | 77 | def request_uri=(uri) |
| 78 | + @env["REQUEST_URI"] = uri | ||
| 76 | @request_uri = uri | 79 | @request_uri = uri |
| 77 | @path = uri.split("?").first | 80 | @path = uri.split("?").first |
| 78 | end | 81 | end |
| @@ -426,12 +429,12 @@ module ActionController #:nodoc: | @@ -426,12 +429,12 @@ module ActionController #:nodoc: | ||
| 426 | end | 429 | end |
| 427 | 430 | ||
| 428 | def build_request_uri(action, parameters) | 431 | def build_request_uri(action, parameters) |
| 429 | - unless @request.env['REQUEST_URI'] | 432 | + unless @request.request_uri_overridden |
| 430 | options = @controller.send(:rewrite_options, parameters) | 433 | options = @controller.send(:rewrite_options, parameters) |
| 431 | options.update(:only_path => true, :action => action) | 434 | options.update(:only_path => true, :action => action) |
| 432 | 435 | ||
| 433 | url = ActionController::UrlRewriter.new(@request, parameters) | 436 | url = ActionController::UrlRewriter.new(@request, parameters) |
| 434 | - @request.set_REQUEST_URI(url.rewrite(options)) | 437 | + @request.request_uri = url.rewrite(options) |
| 435 | end | 438 | end |
| 436 | end | 439 | end |
| 437 | 440 |
vendor/rails/actionpack/lib/action_controller/url_rewriter.rb
| @@ -52,8 +52,9 @@ module ActionController | @@ -52,8 +52,9 @@ module ActionController | ||
| 52 | # Delete the unused options to prevent their appearance in the query string | 52 | # Delete the unused options to prevent their appearance in the query string |
| 53 | [:protocol, :host, :port].each { |k| options.delete k } | 53 | [:protocol, :host, :port].each { |k| options.delete k } |
| 54 | end | 54 | end |
| 55 | + anchor = "##{options.delete(:anchor)}" if options.key?(:anchor) | ||
| 55 | url << Routing::Routes.generate(options, {}) | 56 | url << Routing::Routes.generate(options, {}) |
| 56 | - return url | 57 | + return "#{url}#{anchor}" |
| 57 | end | 58 | end |
| 58 | 59 | ||
| 59 | end | 60 | end |
| @@ -76,6 +77,7 @@ module ActionController | @@ -76,6 +77,7 @@ module ActionController | ||
| 76 | alias_method :to_s, :to_str | 77 | alias_method :to_s, :to_str |
| 77 | 78 | ||
| 78 | private | 79 | private |
| 80 | + # Given a path and options, returns a rewritten URL string | ||
| 79 | def rewrite_url(path, options) | 81 | def rewrite_url(path, options) |
| 80 | rewritten_url = "" | 82 | rewritten_url = "" |
| 81 | unless options[:only_path] | 83 | unless options[:only_path] |
| @@ -91,6 +93,7 @@ module ActionController | @@ -91,6 +93,7 @@ module ActionController | ||
| 91 | rewritten_url | 93 | rewritten_url |
| 92 | end | 94 | end |
| 93 | 95 | ||
| 96 | + # Given a Hash of options, generates a route | ||
| 94 | def rewrite_path(options) | 97 | def rewrite_path(options) |
| 95 | options = options.symbolize_keys | 98 | options = options.symbolize_keys |
| 96 | options.update(options[:params].symbolize_keys) if options[:params] | 99 | options.update(options[:params].symbolize_keys) if options[:params] |
vendor/rails/actionpack/lib/action_controller/verification.rb
| @@ -95,6 +95,7 @@ module ActionController #:nodoc: | @@ -95,6 +95,7 @@ module ActionController #:nodoc: | ||
| 95 | response.headers.update(options[:add_headers]) if options[:add_headers] | 95 | response.headers.update(options[:add_headers]) if options[:add_headers] |
| 96 | unless performed? | 96 | unless performed? |
| 97 | render(options[:render]) if options[:render] | 97 | render(options[:render]) if options[:render] |
| 98 | + options[:redirect_to] = self.send(options[:redirect_to]) if options[:redirect_to].is_a? Symbol | ||
| 98 | redirect_to(options[:redirect_to]) if options[:redirect_to] | 99 | redirect_to(options[:redirect_to]) if options[:redirect_to] |
| 99 | end | 100 | end |
| 100 | return false | 101 | return false |
vendor/rails/actionpack/lib/action_pack/version.rb
| @@ -2,7 +2,7 @@ module ActionPack #:nodoc: | @@ -2,7 +2,7 @@ module ActionPack #:nodoc: | ||
| 2 | module VERSION #:nodoc: | 2 | module VERSION #:nodoc: |
| 3 | MAJOR = 1 | 3 | MAJOR = 1 |
| 4 | MINOR = 13 | 4 | MINOR = 13 |
| 5 | - TINY = 3 | 5 | + TINY = 6 |
| 6 | 6 | ||
| 7 | STRING = [MAJOR, MINOR, TINY].join('.') | 7 | STRING = [MAJOR, MINOR, TINY].join('.') |
| 8 | end | 8 | end |
vendor/rails/actionpack/lib/action_view/base.rb
| @@ -148,7 +148,7 @@ module ActionView #:nodoc: | @@ -148,7 +148,7 @@ module ActionView #:nodoc: | ||
| 148 | # | 148 | # |
| 149 | # This refreshes the sidebar, removes a person element and highlights the user list. | 149 | # This refreshes the sidebar, removes a person element and highlights the user list. |
| 150 | # | 150 | # |
| 151 | - # See the ActionView::Helpers::PrototypeHelper::JavaScriptGenerator documentation for more details. | 151 | + # See the ActionView::Helpers::PrototypeHelper::GeneratorMethods documentation for more details. |
| 152 | class Base | 152 | class Base |
| 153 | include ERB::Util | 153 | include ERB::Util |
| 154 | 154 | ||
| @@ -160,7 +160,7 @@ module ActionView #:nodoc: | @@ -160,7 +160,7 @@ module ActionView #:nodoc: | ||
| 160 | attr_internal *ActionController::Base::DEPRECATED_INSTANCE_VARIABLES | 160 | attr_internal *ActionController::Base::DEPRECATED_INSTANCE_VARIABLES |
| 161 | 161 | ||
| 162 | # Specify trim mode for the ERB compiler. Defaults to '-'. | 162 | # Specify trim mode for the ERB compiler. Defaults to '-'. |
| 163 | - # See ERB documentation for suitable values. | 163 | + # See ERb documentation for suitable values. |
| 164 | @@erb_trim_mode = '-' | 164 | @@erb_trim_mode = '-' |
| 165 | cattr_accessor :erb_trim_mode | 165 | cattr_accessor :erb_trim_mode |
| 166 | 166 | ||
| @@ -191,17 +191,17 @@ module ActionView #:nodoc: | @@ -191,17 +191,17 @@ module ActionView #:nodoc: | ||
| 191 | end | 191 | end |
| 192 | include CompiledTemplates | 192 | include CompiledTemplates |
| 193 | 193 | ||
| 194 | - # maps inline templates to their method names | 194 | + # Maps inline templates to their method names |
| 195 | @@method_names = {} | 195 | @@method_names = {} |
| 196 | - # map method names to their compile time | 196 | + # Map method names to their compile time |
| 197 | @@compile_time = {} | 197 | @@compile_time = {} |
| 198 | - # map method names to the names passed in local assigns so far | 198 | + # Map method names to the names passed in local assigns so far |
| 199 | @@template_args = {} | 199 | @@template_args = {} |
| 200 | - # count the number of inline templates | 200 | + # Count the number of inline templates |
| 201 | @@inline_template_count = 0 | 201 | @@inline_template_count = 0 |
| 202 | - # maps template paths without extension to their file extension returned by pick_template_extension. | ||
| 203 | - # if for a given path, path.ext1 and path.ext2 exist on the file system, the order of extensions | ||
| 204 | - # used by pick_template_extension determines whether ext1 or ext2 will be stored | 202 | + # Maps template paths without extension to their file extension returned by pick_template_extension. |
| 203 | + # If for a given path, path.ext1 and path.ext2 exist on the file system, the order of extensions | ||
| 204 | + # used by pick_template_extension determines whether ext1 or ext2 will be stored. | ||
| 205 | @@cached_template_extension = {} | 205 | @@cached_template_extension = {} |
| 206 | 206 | ||
| 207 | class ObjectWrapper < Struct.new(:value) #:nodoc: | 207 | class ObjectWrapper < Struct.new(:value) #:nodoc: |
| @@ -305,7 +305,6 @@ module ActionView #:nodoc: | @@ -305,7 +305,6 @@ module ActionView #:nodoc: | ||
| 305 | # Render the provided template with the given local assigns. If the template has not been rendered with the provided | 305 | # Render the provided template with the given local assigns. If the template has not been rendered with the provided |
| 306 | # local assigns yet, or if the template has been updated on disk, then the template will be compiled to a method. | 306 | # local assigns yet, or if the template has been updated on disk, then the template will be compiled to a method. |
| 307 | # | 307 | # |
| 308 | - | ||
| 309 | # Either, but not both, of template and file_path may be nil. If file_path is given, the template | 308 | # Either, but not both, of template and file_path may be nil. If file_path is given, the template |
| 310 | # will only be read if it has to be compiled. | 309 | # will only be read if it has to be compiled. |
| 311 | # | 310 | # |
| @@ -371,10 +370,12 @@ module ActionView #:nodoc: | @@ -371,10 +370,12 @@ module ActionView #:nodoc: | ||
| 371 | end | 370 | end |
| 372 | 371 | ||
| 373 | private | 372 | private |
| 373 | + # Builds a string holding the full path of the template including extension | ||
| 374 | def full_template_path(template_path, extension) | 374 | def full_template_path(template_path, extension) |
| 375 | "#{@base_path}/#{template_path}.#{extension}" | 375 | "#{@base_path}/#{template_path}.#{extension}" |
| 376 | end | 376 | end |
| 377 | 377 | ||
| 378 | + # Asserts the existence of a template. | ||
| 378 | def template_exists?(template_path, extension) | 379 | def template_exists?(template_path, extension) |
| 379 | file_path = full_template_path(template_path, extension) | 380 | file_path = full_template_path(template_path, extension) |
| 380 | @@method_names.has_key?(file_path) || FileTest.exists?(file_path) | 381 | @@method_names.has_key?(file_path) || FileTest.exists?(file_path) |
| @@ -389,6 +390,7 @@ module ActionView #:nodoc: | @@ -389,6 +390,7 @@ module ActionView #:nodoc: | ||
| 389 | @@cache_template_extensions && @@cached_template_extension[template_path] | 390 | @@cache_template_extensions && @@cached_template_extension[template_path] |
| 390 | end | 391 | end |
| 391 | 392 | ||
| 393 | + # Determines the template's file extension, such as rhtml, rxml, or rjs. | ||
| 392 | def find_template_extension_for(template_path) | 394 | def find_template_extension_for(template_path) |
| 393 | if match = delegate_template_exists?(template_path) | 395 | if match = delegate_template_exists?(template_path) |
| 394 | match.first.to_sym | 396 | match.first.to_sym |
| @@ -405,6 +407,7 @@ module ActionView #:nodoc: | @@ -405,6 +407,7 @@ module ActionView #:nodoc: | ||
| 405 | File.read(template_path) | 407 | File.read(template_path) |
| 406 | end | 408 | end |
| 407 | 409 | ||
| 410 | + # Evaluate the local assigns and pushes them to the view. | ||
| 408 | def evaluate_assigns | 411 | def evaluate_assigns |
| 409 | unless @assigns_added | 412 | unless @assigns_added |
| 410 | assign_variables_from_controller | 413 | assign_variables_from_controller |
| @@ -416,6 +419,7 @@ module ActionView #:nodoc: | @@ -416,6 +419,7 @@ module ActionView #:nodoc: | ||
| 416 | handler.new(self).render(template, local_assigns) | 419 | handler.new(self).render(template, local_assigns) |
| 417 | end | 420 | end |
| 418 | 421 | ||
| 422 | + # Assigns instance variables from the controller to the view. | ||
| 419 | def assign_variables_from_controller | 423 | def assign_variables_from_controller |
| 420 | @assigns.each { |key, value| instance_variable_set("@#{key}", value) } | 424 | @assigns.each { |key, value| instance_variable_set("@#{key}", value) } |
| 421 | end | 425 | end |
| @@ -427,10 +431,10 @@ module ActionView #:nodoc: | @@ -427,10 +431,10 @@ module ActionView #:nodoc: | ||
| 427 | ((args = @@template_args[render_symbol]) && local_assigns.all? { |k,_| args.has_key?(k) }) | 431 | ((args = @@template_args[render_symbol]) && local_assigns.all? { |k,_| args.has_key?(k) }) |
| 428 | end | 432 | end |
| 429 | 433 | ||
| 430 | - # Check whether compilation is necessary. | ||
| 431 | - # Compile if the inline template or file has not been compiled yet. | ||
| 432 | - # Or if local_assigns has a new key, which isn't supported by the compiled code yet. | ||
| 433 | - # Or if the file has changed on disk and checking file mods hasn't been disabled. | 434 | + # Method to check whether template compilation is necessary. |
| 435 | + # The template will be compiled if the inline template or file has not been compiled yet, | ||
| 436 | + # if local_assigns has a new key, which isn't supported by the compiled code yet, | ||
| 437 | + # or if the file has changed on disk and checking file mods hasn't been disabled. | ||
| 434 | def compile_template?(template, file_name, local_assigns) | 438 | def compile_template?(template, file_name, local_assigns) |
| 435 | method_key = file_name || template | 439 | method_key = file_name || template |
| 436 | render_symbol = @@method_names[method_key] | 440 | render_symbol = @@method_names[method_key] |
| @@ -445,14 +449,15 @@ module ActionView #:nodoc: | @@ -445,14 +449,15 @@ module ActionView #:nodoc: | ||
| 445 | end | 449 | end |
| 446 | end | 450 | end |
| 447 | 451 | ||
| 448 | - # Create source code for given template | 452 | + # Method to create the source code for a given template. |
| 449 | def create_template_source(extension, template, render_symbol, locals) | 453 | def create_template_source(extension, template, render_symbol, locals) |
| 450 | if template_requires_setup?(extension) | 454 | if template_requires_setup?(extension) |
| 451 | body = case extension.to_sym | 455 | body = case extension.to_sym |
| 452 | when :rxml | 456 | when :rxml |
| 453 | "controller.response.content_type ||= 'application/xml'\n" + | 457 | "controller.response.content_type ||= 'application/xml'\n" + |
| 454 | - "xml = Builder::XmlMarkup.new(:indent => 2)\n" + | ||
| 455 | - template | 458 | + "xml ||= Builder::XmlMarkup.new(:indent => 2)\n" + |
| 459 | + template + | ||
| 460 | + "\nxml.target!\n" | ||
| 456 | when :rjs | 461 | when :rjs |
| 457 | "controller.response.content_type ||= 'text/javascript'\n" + | 462 | "controller.response.content_type ||= 'text/javascript'\n" + |
| 458 | "update_page do |page|\n#{template}\nend" | 463 | "update_page do |page|\n#{template}\nend" |
| @@ -473,11 +478,11 @@ module ActionView #:nodoc: | @@ -473,11 +478,11 @@ module ActionView #:nodoc: | ||
| 473 | "def #{render_symbol}(local_assigns)\n#{locals_code}#{body}\nend" | 478 | "def #{render_symbol}(local_assigns)\n#{locals_code}#{body}\nend" |
| 474 | end | 479 | end |
| 475 | 480 | ||
| 476 | - def template_requires_setup?(extension) | 481 | + def template_requires_setup?(extension) #:nodoc: |
| 477 | templates_requiring_setup.include? extension.to_s | 482 | templates_requiring_setup.include? extension.to_s |
| 478 | end | 483 | end |
| 479 | 484 | ||
| 480 | - def templates_requiring_setup | 485 | + def templates_requiring_setup #:nodoc: |
| 481 | %w(rxml rjs) | 486 | %w(rxml rjs) |
| 482 | end | 487 | end |
| 483 | 488 | ||
| @@ -501,6 +506,7 @@ module ActionView #:nodoc: | @@ -501,6 +506,7 @@ module ActionView #:nodoc: | ||
| 501 | end | 506 | end |
| 502 | end | 507 | end |
| 503 | 508 | ||
| 509 | + # Compile and evaluate the template's code | ||
| 504 | def compile_template(extension, template, file_name, local_assigns) | 510 | def compile_template(extension, template, file_name, local_assigns) |
| 505 | render_symbol = assign_method_name(extension, template, file_name) | 511 | render_symbol = assign_method_name(extension, template, file_name) |
| 506 | render_source = create_template_source(extension, template, render_symbol, local_assigns.keys) | 512 | render_source = create_template_source(extension, template, render_symbol, local_assigns.keys) |
vendor/rails/actionpack/lib/action_view/compiled_templates.rb
| @@ -3,14 +3,14 @@ module ActionView | @@ -3,14 +3,14 @@ module ActionView | ||
| 3 | 3 | ||
| 4 | # CompiledTemplates modules hold methods that have been compiled. | 4 | # CompiledTemplates modules hold methods that have been compiled. |
| 5 | # Templates are compiled into these methods so that they do not need to be | 5 | # Templates are compiled into these methods so that they do not need to be |
| 6 | - # re-read and re-parsed each request. | 6 | + # read and parsed for each request. |
| 7 | # | 7 | # |
| 8 | # Each template may be compiled into one or more methods. Each method accepts a given | 8 | # Each template may be compiled into one or more methods. Each method accepts a given |
| 9 | # set of parameters which is used to implement local assigns passing. | 9 | # set of parameters which is used to implement local assigns passing. |
| 10 | # | 10 | # |
| 11 | # To use a compiled template module, create a new instance and include it into the class | 11 | # To use a compiled template module, create a new instance and include it into the class |
| 12 | # in which you want the template to be rendered. | 12 | # in which you want the template to be rendered. |
| 13 | - class CompiledTemplates < Module #:nodoc: | 13 | + class CompiledTemplates < Module |
| 14 | attr_reader :method_names | 14 | attr_reader :method_names |
| 15 | 15 | ||
| 16 | def initialize | 16 | def initialize |
vendor/rails/actionpack/lib/action_view/helpers/active_record_helper.rb
| @@ -13,17 +13,18 @@ module ActionView | @@ -13,17 +13,18 @@ module ActionView | ||
| 13 | # is a great of making the record quickly available for editing, but likely to prove lackluster for a complicated real-world form. | 13 | # is a great of making the record quickly available for editing, but likely to prove lackluster for a complicated real-world form. |
| 14 | # In that case, it's better to use the input method and the specialized form methods in link:classes/ActionView/Helpers/FormHelper.html | 14 | # In that case, it's better to use the input method and the specialized form methods in link:classes/ActionView/Helpers/FormHelper.html |
| 15 | module ActiveRecordHelper | 15 | module ActiveRecordHelper |
| 16 | - # Returns a default input tag for the type of object returned by the method. Example | ||
| 17 | - # (title is a VARCHAR column and holds "Hello World"): | 16 | + # Returns a default input tag for the type of object returned by the method. For example, let's say you have a model |
| 17 | + # that has an attribute +title+ of type VARCHAR column, and this instance holds "Hello World": | ||
| 18 | # input("post", "title") => | 18 | # input("post", "title") => |
| 19 | # <input id="post_title" name="post[title]" size="30" type="text" value="Hello World" /> | 19 | # <input id="post_title" name="post[title]" size="30" type="text" value="Hello World" /> |
| 20 | def input(record_name, method, options = {}) | 20 | def input(record_name, method, options = {}) |
| 21 | InstanceTag.new(record_name, method, self).to_tag(options) | 21 | InstanceTag.new(record_name, method, self).to_tag(options) |
| 22 | end | 22 | end |
| 23 | 23 | ||
| 24 | - # Returns an entire form with input tags and everything for a specified Active Record object. Example | ||
| 25 | - # (post is a new record that has a title using VARCHAR and a body using TEXT): | ||
| 26 | - # form("post") => | 24 | + # Returns an entire form with all needed input tags for a specified Active Record object. For example, let's say you |
| 25 | + # have a table model <tt>Post</tt> with attributes named <tt>title</tt> of type <tt>VARCHAR</tt> and <tt>body</tt> of type <tt>TEXT</tt>: | ||
| 26 | + # form("post") | ||
| 27 | + # That line would yield a form like the following: | ||
| 27 | # <form action='/post/create' method='post'> | 28 | # <form action='/post/create' method='post'> |
| 28 | # <p> | 29 | # <p> |
| 29 | # <label for="post_title">Title</label><br /> | 30 | # <label for="post_title">Title</label><br /> |
| @@ -32,14 +33,13 @@ module ActionView | @@ -32,14 +33,13 @@ module ActionView | ||
| 32 | # <p> | 33 | # <p> |
| 33 | # <label for="post_body">Body</label><br /> | 34 | # <label for="post_body">Body</label><br /> |
| 34 | # <textarea cols="40" id="post_body" name="post[body]" rows="20"> | 35 | # <textarea cols="40" id="post_body" name="post[body]" rows="20"> |
| 35 | - # Back to the hill and over it again! | ||
| 36 | # </textarea> | 36 | # </textarea> |
| 37 | # </p> | 37 | # </p> |
| 38 | # <input type='submit' value='Create' /> | 38 | # <input type='submit' value='Create' /> |
| 39 | # </form> | 39 | # </form> |
| 40 | # | 40 | # |
| 41 | # It's possible to specialize the form builder by using a different action name and by supplying another | 41 | # It's possible to specialize the form builder by using a different action name and by supplying another |
| 42 | - # block renderer. Example (entry is a new record that has a message attribute using VARCHAR): | 42 | + # block renderer. For example, let's say you have a model <tt>Entry</tt> with an attribute <tt>message</tt> of type <tt>VARCHAR</tt>: |
| 43 | # | 43 | # |
| 44 | # form("entry", :action => "sign", :input_block => | 44 | # form("entry", :action => "sign", :input_block => |
| 45 | # Proc.new { |record, column| "#{column.human_name}: #{input(record, column.name)}<br />" }) => | 45 | # Proc.new { |record, column| "#{column.human_name}: #{input(record, column.name)}<br />" }) => |
| @@ -74,16 +74,16 @@ module ActionView | @@ -74,16 +74,16 @@ module ActionView | ||
| 74 | content_tag('form', contents, :action => action, :method => 'post', :enctype => options[:multipart] ? 'multipart/form-data': nil) | 74 | content_tag('form', contents, :action => action, :method => 'post', :enctype => options[:multipart] ? 'multipart/form-data': nil) |
| 75 | end | 75 | end |
| 76 | 76 | ||
| 77 | - # Returns a string containing the error message attached to the +method+ on the +object+, if one exists. | ||
| 78 | - # This error message is wrapped in a DIV tag, which can be specialized to include both a +prepend_text+ and +append_text+ | ||
| 79 | - # to properly introduce the error and a +css_class+ to style it accordingly. Examples (post has an error message | ||
| 80 | - # "can't be empty" on the title attribute): | 77 | + # Returns a string containing the error message attached to the +method+ on the +object+ if one exists. |
| 78 | + # This error message is wrapped in a <tt>DIV</tt> tag, which can be extended to include a +prepend_text+ and/or +append_text+ | ||
| 79 | + # (to properly explain the error), and a +css_class+ to style it accordingly. As an example, let's say you have a model | ||
| 80 | + # +post+ that has an error message on the +title+ attribute: | ||
| 81 | # | 81 | # |
| 82 | # <%= error_message_on "post", "title" %> => | 82 | # <%= error_message_on "post", "title" %> => |
| 83 | # <div class="formError">can't be empty</div> | 83 | # <div class="formError">can't be empty</div> |
| 84 | # | 84 | # |
| 85 | - # <%= error_message_on "post", "title", "Title simply ", " (or it won't work)", "inputError" %> => | ||
| 86 | - # <div class="inputError">Title simply can't be empty (or it won't work)</div> | 85 | + # <%= error_message_on "post", "title", "Title simply ", " (or it won't work).", "inputError" %> => |
| 86 | + # <div class="inputError">Title simply can't be empty (or it won't work).</div> | ||
| 87 | def error_message_on(object, method, prepend_text = "", append_text = "", css_class = "formError") | 87 | def error_message_on(object, method, prepend_text = "", append_text = "", css_class = "formError") |
| 88 | if (obj = instance_variable_get("@#{object}")) && (errors = obj.errors.on(method)) | 88 | if (obj = instance_variable_get("@#{object}")) && (errors = obj.errors.on(method)) |
| 89 | content_tag("div", "#{prepend_text}#{errors.is_a?(Array) ? errors.first : errors}#{append_text}", :class => css_class) | 89 | content_tag("div", "#{prepend_text}#{errors.is_a?(Array) ? errors.first : errors}#{append_text}", :class => css_class) |
| @@ -92,11 +92,11 @@ module ActionView | @@ -92,11 +92,11 @@ module ActionView | ||
| 92 | end | 92 | end |
| 93 | end | 93 | end |
| 94 | 94 | ||
| 95 | - # Returns a string with a div containing all of the error messages for the objects located as instance variables by the names | 95 | + # Returns a string with a <tt>DIV</tt> containing all of the error messages for the objects located as instance variables by the names |
| 96 | # given. If more than one object is specified, the errors for the objects are displayed in the order that the object names are | 96 | # given. If more than one object is specified, the errors for the objects are displayed in the order that the object names are |
| 97 | # provided. | 97 | # provided. |
| 98 | # | 98 | # |
| 99 | - # This div can be tailored by the following options: | 99 | + # This <tt>DIV</tt> can be tailored by the following options: |
| 100 | # | 100 | # |
| 101 | # * <tt>header_tag</tt> - Used for the header of the error div (default: h2) | 101 | # * <tt>header_tag</tt> - Used for the header of the error div (default: h2) |
| 102 | # * <tt>id</tt> - The id of the error div (default: errorExplanation) | 102 | # * <tt>id</tt> - The id of the error div (default: errorExplanation) |
| @@ -105,12 +105,12 @@ module ActionView | @@ -105,12 +105,12 @@ module ActionView | ||
| 105 | # any text that you prefer. If <tt>object_name</tt> is not set, the name of | 105 | # any text that you prefer. If <tt>object_name</tt> is not set, the name of |
| 106 | # the first object will be used. | 106 | # the first object will be used. |
| 107 | # | 107 | # |
| 108 | - # Specifying one object: | 108 | + # To specify the display for one object, you simply provide its name as a parameter. For example, for the +User+ model: |
| 109 | # | 109 | # |
| 110 | # error_messages_for 'user' | 110 | # error_messages_for 'user' |
| 111 | # | 111 | # |
| 112 | - # Specifying more than one object (and using the name 'user' in the | ||
| 113 | - # header as the <tt>object_name</tt> instead of 'user_common'): | 112 | + # To specify more than one object, you simply list them; optionally, you can add an extra +object_name+ parameter, which |
| 113 | + # be the name in the header. | ||
| 114 | # | 114 | # |
| 115 | # error_messages_for 'user_common', 'user', :object_name => 'user' | 115 | # error_messages_for 'user_common', 'user', :object_name => 'user' |
| 116 | # | 116 | # |
vendor/rails/actionpack/lib/action_view/helpers/debug_helper.rb
| @@ -3,6 +3,16 @@ module ActionView | @@ -3,6 +3,16 @@ module ActionView | ||
| 3 | # Provides a set of methods for making it easier to locate problems. | 3 | # Provides a set of methods for making it easier to locate problems. |
| 4 | module DebugHelper | 4 | module DebugHelper |
| 5 | # Returns a <pre>-tag set with the +object+ dumped by YAML. Very readable way to inspect an object. | 5 | # Returns a <pre>-tag set with the +object+ dumped by YAML. Very readable way to inspect an object. |
| 6 | + # my_hash = {'first' => 1, 'second' => 'two', 'third' => [1,2,3]} | ||
| 7 | + # debug(my_hash) | ||
| 8 | + # => <pre class='debug_dump'>--- | ||
| 9 | + # first: 1 | ||
| 10 | + # second: two | ||
| 11 | + # third: | ||
| 12 | + # - 1 | ||
| 13 | + # - 2 | ||
| 14 | + # - 3 | ||
| 15 | + # </pre> | ||
| 6 | def debug(object) | 16 | def debug(object) |
| 7 | begin | 17 | begin |
| 8 | Marshal::dump(object) | 18 | Marshal::dump(object) |
vendor/rails/actionpack/lib/action_view/helpers/deprecated_helper.rb
| @@ -2,6 +2,9 @@ module ActionView | @@ -2,6 +2,9 @@ module ActionView | ||
| 2 | module Helpers | 2 | module Helpers |
| 3 | module PrototypeHelper | 3 | module PrototypeHelper |
| 4 | 4 | ||
| 5 | + # Method to execute an element update using Prototype. | ||
| 6 | + # DEPRECATION WARNING: This helper has been depercated; use RJS instead. | ||
| 7 | + # See ActionView::Helpers::PrototypeHelper::JavaScriptGenerator::GeneratorMethods for more information. | ||
| 5 | def update_element_function(element_id, options = {}, &block) | 8 | def update_element_function(element_id, options = {}, &block) |
| 6 | content = escape_javascript(options[:content] || '') | 9 | content = escape_javascript(options[:content] || '') |
| 7 | content = escape_javascript(capture(&block)) if block | 10 | content = escape_javascript(capture(&block)) if block |
vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb
| @@ -250,8 +250,10 @@ module ActionView | @@ -250,8 +250,10 @@ module ActionView | ||
| 250 | return function | 250 | return function |
| 251 | end | 251 | end |
| 252 | 252 | ||
| 253 | - # Observes the field with the DOM ID specified by +field_id+ and makes | ||
| 254 | - # an Ajax call when its contents have changed. | 253 | + # Observes the field with the DOM ID specified by +field_id+ and calls a |
| 254 | + # callback when its contents have changed. The default callback is an | ||
| 255 | + # Ajax call. By default the value of the observed field is sent as a | ||
| 256 | + # parameter with the Ajax call. | ||
| 255 | # | 257 | # |
| 256 | # Required +options+ are either of: | 258 | # Required +options+ are either of: |
| 257 | # <tt>:url</tt>:: +url_for+-style options for the action to call | 259 | # <tt>:url</tt>:: +url_for+-style options for the action to call |
| @@ -268,14 +270,24 @@ module ActionView | @@ -268,14 +270,24 @@ module ActionView | ||
| 268 | # <tt>:update</tt>:: Specifies the DOM ID of the element whose | 270 | # <tt>:update</tt>:: Specifies the DOM ID of the element whose |
| 269 | # innerHTML should be updated with the | 271 | # innerHTML should be updated with the |
| 270 | # XMLHttpRequest response text. | 272 | # XMLHttpRequest response text. |
| 271 | - # <tt>:with</tt>:: A JavaScript expression specifying the | ||
| 272 | - # parameters for the XMLHttpRequest. This defaults | ||
| 273 | - # to 'value', which in the evaluated context | ||
| 274 | - # refers to the new field value. If you specify a | ||
| 275 | - # string without a "=", it'll be extended to mean | ||
| 276 | - # the form key that the value should be assigned to. | ||
| 277 | - # So :with => "term" gives "'term'=value". If a "=" is | ||
| 278 | - # present, no extension will happen. | 273 | + # <tt>:with</tt>:: A JavaScript expression specifying the parameters |
| 274 | + # for the XMLHttpRequest. The default is to send the | ||
| 275 | + # key and value of the observed field. Any custom | ||
| 276 | + # expressions should return a valid URL query string. | ||
| 277 | + # The value of the field is stored in the JavaScript | ||
| 278 | + # variable +value+. | ||
| 279 | + # | ||
| 280 | + # Examples | ||
| 281 | + # | ||
| 282 | + # :with => "'my_custom_key=' + value" | ||
| 283 | + # :with => "'person[name]=' + prompt('New name')" | ||
| 284 | + # :with => "Form.Element.serialize('other-field')" | ||
| 285 | + # | ||
| 286 | + # Finally | ||
| 287 | + # :with => 'name' | ||
| 288 | + # is shorthand for | ||
| 289 | + # :with => "'name=' + value" | ||
| 290 | + # This essentially just changes the key of the parameter. | ||
| 279 | # <tt>:on</tt>:: Specifies which event handler to observe. By default, | 291 | # <tt>:on</tt>:: Specifies which event handler to observe. By default, |
| 280 | # it's set to "changed" for text fields and areas and | 292 | # it's set to "changed" for text fields and areas and |
| 281 | # "click" for radio buttons and checkboxes. With this, | 293 | # "click" for radio buttons and checkboxes. With this, |
| @@ -291,11 +303,15 @@ module ActionView | @@ -291,11 +303,15 @@ module ActionView | ||
| 291 | build_observer('Form.Element.EventObserver', field_id, options) | 303 | build_observer('Form.Element.EventObserver', field_id, options) |
| 292 | end | 304 | end |
| 293 | end | 305 | end |
| 294 | - | ||
| 295 | - # Like +observe_field+, but operates on an entire form identified by the | ||
| 296 | - # DOM ID +form_id+. +options+ are the same as +observe_field+, except | ||
| 297 | - # the default value of the <tt>:with</tt> option evaluates to the | ||
| 298 | - # serialized (request string) value of the form. | 306 | + |
| 307 | + # Observes the form with the DOM ID specified by +form_id+ and calls a | ||
| 308 | + # callback when its contents have changed. The default callback is an | ||
| 309 | + # Ajax call. By default all fields of the observed field are sent as | ||
| 310 | + # parameters with the Ajax call. | ||
| 311 | + # | ||
| 312 | + # The +options+ for +observe_form+ are the same as the options for | ||
| 313 | + # +observe_field+. The JavaScript variable +value+ available to the | ||
| 314 | + # <tt>:with</tt> option is set to the serialized form by default. | ||
| 299 | def observe_form(form_id, options = {}) | 315 | def observe_form(form_id, options = {}) |
| 300 | if options[:frequency] | 316 | if options[:frequency] |
| 301 | build_observer('Form.Observer', form_id, options) | 317 | build_observer('Form.Observer', form_id, options) |
| @@ -660,10 +676,10 @@ module ActionView | @@ -660,10 +676,10 @@ module ActionView | ||
| 660 | end | 676 | end |
| 661 | 677 | ||
| 662 | def build_observer(klass, name, options = {}) | 678 | def build_observer(klass, name, options = {}) |
| 663 | - if options[:with] && !options[:with].include?("=") | 679 | + if options[:with] && (options[:with] !~ /[=(.]/) |
| 664 | options[:with] = "'#{options[:with]}=' + value" | 680 | options[:with] = "'#{options[:with]}=' + value" |
| 665 | else | 681 | else |
| 666 | - options[:with] ||= 'value' if options[:update] | 682 | + options[:with] ||= 'value' unless options[:function] |
| 667 | end | 683 | end |
| 668 | 684 | ||
| 669 | callback = options[:function] || remote_function(options) | 685 | callback = options[:function] || remote_function(options) |
vendor/rails/actionpack/test/activerecord/pagination_test.rb
| @@ -5,6 +5,8 @@ class PaginationTest < ActiveRecordTestCase | @@ -5,6 +5,8 @@ class PaginationTest < ActiveRecordTestCase | ||
| 5 | 5 | ||
| 6 | class PaginationController < ActionController::Base | 6 | class PaginationController < ActionController::Base |
| 7 | self.template_root = "#{File.dirname(__FILE__)}/../fixtures/" | 7 | self.template_root = "#{File.dirname(__FILE__)}/../fixtures/" |
| 8 | + | ||
| 9 | + around_filter :silence_deprecation_warnings | ||
| 8 | 10 | ||
| 9 | def simple_paginate | 11 | def simple_paginate |
| 10 | @topic_pages, @topics = paginate(:topics) | 12 | @topic_pages, @topics = paginate(:topics) |
| @@ -67,6 +69,13 @@ class PaginationTest < ActiveRecordTestCase | @@ -67,6 +69,13 @@ class PaginationTest < ActiveRecordTestCase | ||
| 67 | :count => "d.id") | 69 | :count => "d.id") |
| 68 | render :nothing => true | 70 | render :nothing => true |
| 69 | end | 71 | end |
| 72 | + | ||
| 73 | + | ||
| 74 | + def silence_deprecation_warnings | ||
| 75 | + ActiveSupport::Deprecation.silence do | ||
| 76 | + yield | ||
| 77 | + end | ||
| 78 | + end | ||
| 70 | 79 | ||
| 71 | def rescue_errors(e) raise e end | 80 | def rescue_errors(e) raise e end |
| 72 | 81 |
vendor/rails/actionpack/test/controller/action_pack_assertions_test.rb
| @@ -19,6 +19,8 @@ class ActionPackAssertionsController < ActionController::Base | @@ -19,6 +19,8 @@ class ActionPackAssertionsController < ActionController::Base | ||
| 19 | 19 | ||
| 20 | def redirect_to_controller() redirect_to :controller => "elsewhere", :action => "flash_me"; end | 20 | def redirect_to_controller() redirect_to :controller => "elsewhere", :action => "flash_me"; end |
| 21 | 21 | ||
| 22 | + def redirect_to_controller_with_symbol() redirect_to :controller => :elsewhere, :action => :flash_me; end | ||
| 23 | + | ||
| 22 | def redirect_to_path() redirect_to '/some/path' end | 24 | def redirect_to_path() redirect_to '/some/path' end |
| 23 | 25 | ||
| 24 | def redirect_to_named_route() redirect_to route_one_url end | 26 | def redirect_to_named_route() redirect_to route_one_url end |
| @@ -555,6 +557,17 @@ class ActionPackAssertionsControllerTest < Test::Unit::TestCase | @@ -555,6 +557,17 @@ class ActionPackAssertionsControllerTest < Test::Unit::TestCase | ||
| 555 | assert_redirected_to 'http://test.host/some/path' | 557 | assert_redirected_to 'http://test.host/some/path' |
| 556 | end | 558 | end |
| 557 | 559 | ||
| 560 | + def test_assert_redirection_with_symbol | ||
| 561 | + process :redirect_to_controller_with_symbol | ||
| 562 | + assert_nothing_raised { | ||
| 563 | + assert_redirected_to :controller => "elsewhere", :action => "flash_me" | ||
| 564 | + } | ||
| 565 | + process :redirect_to_controller_with_symbol | ||
| 566 | + assert_nothing_raised { | ||
| 567 | + assert_redirected_to :controller => :elsewhere, :action => :flash_me | ||
| 568 | + } | ||
| 569 | + end | ||
| 570 | + | ||
| 558 | def test_redirected_to_with_nested_controller | 571 | def test_redirected_to_with_nested_controller |
| 559 | @controller = Admin::InnerModuleController.new | 572 | @controller = Admin::InnerModuleController.new |
| 560 | get :redirect_to_absolute_controller | 573 | get :redirect_to_absolute_controller |
vendor/rails/actionpack/test/controller/addresses_render_test.rb
| @@ -39,7 +39,10 @@ class AddressesTest < Test::Unit::TestCase | @@ -39,7 +39,10 @@ class AddressesTest < Test::Unit::TestCase | ||
| 39 | end | 39 | end |
| 40 | 40 | ||
| 41 | def test_list | 41 | def test_list |
| 42 | - get :list | 42 | + # because pagination is deprecated |
| 43 | + ActiveSupport::Deprecation.silence do | ||
| 44 | + get :list | ||
| 45 | + end | ||
| 43 | assert_equal "We only need to get this far!", @response.body.chomp | 46 | assert_equal "We only need to get this far!", @response.body.chomp |
| 44 | end | 47 | end |
| 45 | end | 48 | end |
vendor/rails/actionpack/test/controller/base_test.rb
| @@ -88,7 +88,7 @@ class ControllerInstanceTests < Test::Unit::TestCase | @@ -88,7 +88,7 @@ class ControllerInstanceTests < Test::Unit::TestCase | ||
| 88 | # Mocha adds methods to Object which are then included in the public_instance_methods | 88 | # Mocha adds methods to Object which are then included in the public_instance_methods |
| 89 | # This method hides those from the controller so the above tests won't know the difference | 89 | # This method hides those from the controller so the above tests won't know the difference |
| 90 | def hide_mocha_methods_from_controller(controller) | 90 | def hide_mocha_methods_from_controller(controller) |
| 91 | - mocha_methods = [:expects, :metaclass, :mocha, :mocha_inspect, :reset_mocha, :stubba_object, :stubba_method, :stubs, :verify] | 91 | + mocha_methods = [:expects, :metaclass, :mocha, :mocha_inspect, :reset_mocha, :stubba_object, :stubba_method, :stubs, :verify, :__is_a__, :__metaclass__] |
| 92 | controller.class.send(:hide_action, *mocha_methods) | 92 | controller.class.send(:hide_action, *mocha_methods) |
| 93 | end | 93 | end |
| 94 | 94 |
vendor/rails/actionpack/test/controller/caching_test.rb
| @@ -97,6 +97,7 @@ class ActionCachingTestController < ActionController::Base | @@ -97,6 +97,7 @@ class ActionCachingTestController < ActionController::Base | ||
| 97 | caches_action :index | 97 | caches_action :index |
| 98 | 98 | ||
| 99 | def index | 99 | def index |
| 100 | + sleep 0.01 | ||
| 100 | @cache_this = Time.now.to_f.to_s | 101 | @cache_this = Time.now.to_f.to_s |
| 101 | render :text => @cache_this | 102 | render :text => @cache_this |
| 102 | end | 103 | end |
| @@ -195,7 +196,7 @@ class ActionCacheTest < Test::Unit::TestCase | @@ -195,7 +196,7 @@ class ActionCacheTest < Test::Unit::TestCase | ||
| 195 | def test_xml_version_of_resource_is_treated_as_different_cache | 196 | def test_xml_version_of_resource_is_treated_as_different_cache |
| 196 | @mock_controller.mock_url_for = 'http://example.org/posts/' | 197 | @mock_controller.mock_url_for = 'http://example.org/posts/' |
| 197 | @mock_controller.mock_path = '/posts/index.xml' | 198 | @mock_controller.mock_path = '/posts/index.xml' |
| 198 | - path_object = @path_class.new(@mock_controller) | 199 | + path_object = @path_class.new(@mock_controller, {}) |
| 199 | assert_equal 'xml', path_object.extension | 200 | assert_equal 'xml', path_object.extension |
| 200 | assert_equal 'example.org/posts/index.xml', path_object.path | 201 | assert_equal 'example.org/posts/index.xml', path_object.path |
| 201 | end | 202 | end |
| @@ -204,7 +205,7 @@ class ActionCacheTest < Test::Unit::TestCase | @@ -204,7 +205,7 @@ class ActionCacheTest < Test::Unit::TestCase | ||
| 204 | @mock_controller.mock_url_for = 'http://example.org/' | 205 | @mock_controller.mock_url_for = 'http://example.org/' |
| 205 | @mock_controller.mock_path = '/' | 206 | @mock_controller.mock_path = '/' |
| 206 | 207 | ||
| 207 | - assert_equal 'example.org/index', @path_class.path_for(@mock_controller) | 208 | + assert_equal 'example.org/index', @path_class.path_for(@mock_controller, {}) |
| 208 | end | 209 | end |
| 209 | 210 | ||
| 210 | def test_file_extensions | 211 | def test_file_extensions |
vendor/rails/actionpack/test/controller/cookie_test.rb
| @@ -22,7 +22,7 @@ class CookieTest < Test::Unit::TestCase | @@ -22,7 +22,7 @@ class CookieTest < Test::Unit::TestCase | ||
| 22 | cookies["user_name"] = { "value" => "david", "expires" => Time.local(2005, 10, 10) } | 22 | cookies["user_name"] = { "value" => "david", "expires" => Time.local(2005, 10, 10) } |
| 23 | cookies["login"] = "XJ-122" | 23 | cookies["login"] = "XJ-122" |
| 24 | end | 24 | end |
| 25 | - | 25 | + |
| 26 | def access_frozen_cookies | 26 | def access_frozen_cookies |
| 27 | cookies["will"] = "work" | 27 | cookies["will"] = "work" |
| 28 | end | 28 | end |
| @@ -31,6 +31,11 @@ class CookieTest < Test::Unit::TestCase | @@ -31,6 +31,11 @@ class CookieTest < Test::Unit::TestCase | ||
| 31 | cookies.delete("user_name") | 31 | cookies.delete("user_name") |
| 32 | end | 32 | end |
| 33 | 33 | ||
| 34 | + def delete_cookie_with_path | ||
| 35 | + cookies.delete("user_name", :path => '/beaten') | ||
| 36 | + render_text "hello world" | ||
| 37 | + end | ||
| 38 | + | ||
| 34 | def rescue_action(e) | 39 | def rescue_action(e) |
| 35 | raise unless ActionController::MissingTemplate # No templates here, and we don't care about the output | 40 | raise unless ActionController::MissingTemplate # No templates here, and we don't care about the output |
| 36 | end | 41 | end |
| @@ -85,4 +90,18 @@ class CookieTest < Test::Unit::TestCase | @@ -85,4 +90,18 @@ class CookieTest < Test::Unit::TestCase | ||
| 85 | assert_equal "david", jar["user_name"] | 90 | assert_equal "david", jar["user_name"] |
| 86 | assert_equal nil, jar["something_else"] | 91 | assert_equal nil, jar["something_else"] |
| 87 | end | 92 | end |
| 93 | + | ||
| 94 | + def test_cookiejar_accessor_with_array_value | ||
| 95 | + a = %w{1 2 3} | ||
| 96 | + @request.cookies["pages"] = CGI::Cookie.new("name" => "pages", "value" => a, "expires" => Time.local(2025, 10, 10)) | ||
| 97 | + @controller.request = @request | ||
| 98 | + jar = ActionController::CookieJar.new(@controller) | ||
| 99 | + assert_equal a, jar["pages"] | ||
| 100 | + end | ||
| 101 | + | ||
| 102 | + def test_delete_cookie_with_path | ||
| 103 | + get :delete_cookie_with_path | ||
| 104 | + assert_equal "/beaten", @response.headers["cookie"].first.path | ||
| 105 | + assert_not_equal "/", @response.headers["cookie"].first.path | ||
| 106 | + end | ||
| 88 | end | 107 | end |
vendor/rails/actionpack/test/controller/deprecation/deprecated_base_methods_test.rb
| 1 | require File.dirname(__FILE__) + '/../../abstract_unit' | 1 | require File.dirname(__FILE__) + '/../../abstract_unit' |
| 2 | 2 | ||
| 3 | class DeprecatedBaseMethodsTest < Test::Unit::TestCase | 3 | class DeprecatedBaseMethodsTest < Test::Unit::TestCase |
| 4 | + # ActiveRecord model mock to test pagination deprecation | ||
| 5 | + class DummyModel | ||
| 6 | + def self.find(*args) [] end | ||
| 7 | + def self.count(*args) 0 end | ||
| 8 | + end | ||
| 9 | + | ||
| 4 | class Target < ActionController::Base | 10 | class Target < ActionController::Base |
| 5 | def deprecated_symbol_parameter_to_url_for | 11 | def deprecated_symbol_parameter_to_url_for |
| 6 | redirect_to(url_for(:home_url, "superstars")) | 12 | redirect_to(url_for(:home_url, "superstars")) |
| @@ -18,6 +24,11 @@ class DeprecatedBaseMethodsTest < Test::Unit::TestCase | @@ -18,6 +24,11 @@ class DeprecatedBaseMethodsTest < Test::Unit::TestCase | ||
| 18 | this_method_doesnt_exist | 24 | this_method_doesnt_exist |
| 19 | end | 25 | end |
| 20 | 26 | ||
| 27 | + def pagination | ||
| 28 | + paginate :dummy_models, :class_name => 'DeprecatedBaseMethodsTest::DummyModel' | ||
| 29 | + render :nothing => true | ||
| 30 | + end | ||
| 31 | + | ||
| 21 | def rescue_action(e) raise e end | 32 | def rescue_action(e) raise e end |
| 22 | end | 33 | end |
| 23 | 34 | ||
| @@ -27,6 +38,7 @@ class DeprecatedBaseMethodsTest < Test::Unit::TestCase | @@ -27,6 +38,7 @@ class DeprecatedBaseMethodsTest < Test::Unit::TestCase | ||
| 27 | @request = ActionController::TestRequest.new | 38 | @request = ActionController::TestRequest.new |
| 28 | @response = ActionController::TestResponse.new | 39 | @response = ActionController::TestResponse.new |
| 29 | @controller = Target.new | 40 | @controller = Target.new |
| 41 | + @controller.logger = Logger.new(nil) unless @controller.logger | ||
| 30 | end | 42 | end |
| 31 | 43 | ||
| 32 | def test_deprecated_symbol_parameter_to_url_for | 44 | def test_deprecated_symbol_parameter_to_url_for |
| @@ -57,4 +69,10 @@ class DeprecatedBaseMethodsTest < Test::Unit::TestCase | @@ -57,4 +69,10 @@ class DeprecatedBaseMethodsTest < Test::Unit::TestCase | ||
| 57 | error = Test::Unit::Error.new('testing ur doodz', e) | 69 | error = Test::Unit::Error.new('testing ur doodz', e) |
| 58 | assert_not_deprecated { error.message } | 70 | assert_not_deprecated { error.message } |
| 59 | end | 71 | end |
| 72 | + | ||
| 73 | + def test_pagination_deprecation | ||
| 74 | + assert_deprecated('svn://errtheblog.com/svn/plugins/classic_pagination') do | ||
| 75 | + get :pagination | ||
| 76 | + end | ||
| 77 | + end | ||
| 60 | end | 78 | end |
vendor/rails/actionpack/test/controller/filter_params_test.rb
| @@ -16,6 +16,7 @@ class FilterParamTest < Test::Unit::TestCase | @@ -16,6 +16,7 @@ class FilterParamTest < Test::Unit::TestCase | ||
| 16 | assert @controller.respond_to?(:filter_parameters) | 16 | assert @controller.respond_to?(:filter_parameters) |
| 17 | 17 | ||
| 18 | test_hashes = [[{},{},[]], | 18 | test_hashes = [[{},{},[]], |
| 19 | + [{'foo'=>nil},{'foo'=>nil},[]], | ||
| 19 | [{'foo'=>'bar'},{'foo'=>'bar'},[]], | 20 | [{'foo'=>'bar'},{'foo'=>'bar'},[]], |
| 20 | [{'foo'=>'bar'},{'foo'=>'bar'},%w'food'], | 21 | [{'foo'=>'bar'},{'foo'=>'bar'},%w'food'], |
| 21 | [{'foo'=>'bar'},{'foo'=>'[FILTERED]'},%w'foo'], | 22 | [{'foo'=>'bar'},{'foo'=>'[FILTERED]'},%w'foo'], |
vendor/rails/actionpack/test/controller/filters_test.rb
| @@ -14,7 +14,7 @@ class FilterTest < Test::Unit::TestCase | @@ -14,7 +14,7 @@ class FilterTest < Test::Unit::TestCase | ||
| 14 | @ran_filter ||= [] | 14 | @ran_filter ||= [] |
| 15 | @ran_filter << "ensure_login" | 15 | @ran_filter << "ensure_login" |
| 16 | end | 16 | end |
| 17 | - | 17 | + |
| 18 | def clean_up | 18 | def clean_up |
| 19 | @ran_after_filter ||= [] | 19 | @ran_after_filter ||= [] |
| 20 | @ran_after_filter << "clean_up" | 20 | @ran_after_filter << "clean_up" |
| @@ -62,7 +62,7 @@ class FilterTest < Test::Unit::TestCase | @@ -62,7 +62,7 @@ class FilterTest < Test::Unit::TestCase | ||
| 62 | render :inline => "something else" | 62 | render :inline => "something else" |
| 63 | end | 63 | end |
| 64 | end | 64 | end |
| 65 | - | 65 | + |
| 66 | class ConditionalFilterController < ActionController::Base | 66 | class ConditionalFilterController < ActionController::Base |
| 67 | def show | 67 | def show |
| 68 | render :inline => "ran action" | 68 | render :inline => "ran action" |
| @@ -86,7 +86,7 @@ class FilterTest < Test::Unit::TestCase | @@ -86,7 +86,7 @@ class FilterTest < Test::Unit::TestCase | ||
| 86 | @ran_filter ||= [] | 86 | @ran_filter ||= [] |
| 87 | @ran_filter << "clean_up_tmp" | 87 | @ran_filter << "clean_up_tmp" |
| 88 | end | 88 | end |
| 89 | - | 89 | + |
| 90 | def rescue_action(e) raise(e) end | 90 | def rescue_action(e) raise(e) end |
| 91 | end | 91 | end |
| 92 | 92 | ||
| @@ -94,7 +94,7 @@ class FilterTest < Test::Unit::TestCase | @@ -94,7 +94,7 @@ class FilterTest < Test::Unit::TestCase | ||
| 94 | before_filter :ensure_login, :except => [ :show_without_filter, :another_action ] | 94 | before_filter :ensure_login, :except => [ :show_without_filter, :another_action ] |
| 95 | end | 95 | end |
| 96 | 96 | ||
| 97 | - class OnlyConditionSymController < ConditionalFilterController | 97 | + class OnlyConditionSymController < ConditionalFilterController |
| 98 | before_filter :ensure_login, :only => :show | 98 | before_filter :ensure_login, :only => :show |
| 99 | end | 99 | end |
| 100 | 100 | ||
| @@ -104,10 +104,10 @@ class FilterTest < Test::Unit::TestCase | @@ -104,10 +104,10 @@ class FilterTest < Test::Unit::TestCase | ||
| 104 | 104 | ||
| 105 | class BeforeAndAfterConditionController < ConditionalFilterController | 105 | class BeforeAndAfterConditionController < ConditionalFilterController |
| 106 | before_filter :ensure_login, :only => :show | 106 | before_filter :ensure_login, :only => :show |
| 107 | - after_filter :clean_up_tmp, :only => :show | 107 | + after_filter :clean_up_tmp, :only => :show |
| 108 | end | 108 | end |
| 109 | - | ||
| 110 | - class OnlyConditionProcController < ConditionalFilterController | 109 | + |
| 110 | + class OnlyConditionProcController < ConditionalFilterController | ||
| 111 | before_filter(:only => :show) {|c| c.assigns["ran_proc_filter"] = true } | 111 | before_filter(:only => :show) {|c| c.assigns["ran_proc_filter"] = true } |
| 112 | end | 112 | end |
| 113 | 113 | ||
| @@ -131,6 +131,14 @@ class FilterTest < Test::Unit::TestCase | @@ -131,6 +131,14 @@ class FilterTest < Test::Unit::TestCase | ||
| 131 | before_filter(ConditionalClassFilter, :ensure_login, Proc.new {|c| c.assigns["ran_proc_filter1"] = true }, :except => :show_without_filter) { |c| c.assigns["ran_proc_filter2"] = true} | 131 | before_filter(ConditionalClassFilter, :ensure_login, Proc.new {|c| c.assigns["ran_proc_filter1"] = true }, :except => :show_without_filter) { |c| c.assigns["ran_proc_filter2"] = true} |
| 132 | end | 132 | end |
| 133 | 133 | ||
| 134 | + class EmptyFilterChainController < TestController | ||
| 135 | + self.filter_chain.clear | ||
| 136 | + def show | ||
| 137 | + @action_executed = true | ||
| 138 | + render :text => "yawp!" | ||
| 139 | + end | ||
| 140 | + end | ||
| 141 | + | ||
| 134 | class PrependingController < TestController | 142 | class PrependingController < TestController |
| 135 | prepend_before_filter :wonderful_life | 143 | prepend_before_filter :wonderful_life |
| 136 | # skip_before_filter :fire_flash | 144 | # skip_before_filter :fire_flash |
| @@ -145,7 +153,7 @@ class FilterTest < Test::Unit::TestCase | @@ -145,7 +153,7 @@ class FilterTest < Test::Unit::TestCase | ||
| 145 | class ConditionalSkippingController < TestController | 153 | class ConditionalSkippingController < TestController |
| 146 | skip_before_filter :ensure_login, :only => [ :login ] | 154 | skip_before_filter :ensure_login, :only => [ :login ] |
| 147 | skip_after_filter :clean_up, :only => [ :login ] | 155 | skip_after_filter :clean_up, :only => [ :login ] |
| 148 | - | 156 | + |
| 149 | before_filter :find_user, :only => [ :change_password ] | 157 | before_filter :find_user, :only => [ :change_password ] |
| 150 | 158 | ||
| 151 | def login | 159 | def login |
| @@ -155,7 +163,7 @@ class FilterTest < Test::Unit::TestCase | @@ -155,7 +163,7 @@ class FilterTest < Test::Unit::TestCase | ||
| 155 | def change_password | 163 | def change_password |
| 156 | render :inline => "ran action" | 164 | render :inline => "ran action" |
| 157 | end | 165 | end |
| 158 | - | 166 | + |
| 159 | protected | 167 | protected |
| 160 | def find_user | 168 | def find_user |
| 161 | @ran_filter ||= [] | 169 | @ran_filter ||= [] |
| @@ -166,15 +174,15 @@ class FilterTest < Test::Unit::TestCase | @@ -166,15 +174,15 @@ class FilterTest < Test::Unit::TestCase | ||
| 166 | class ConditionalParentOfConditionalSkippingController < ConditionalFilterController | 174 | class ConditionalParentOfConditionalSkippingController < ConditionalFilterController |
| 167 | before_filter :conditional_in_parent, :only => [:show, :another_action] | 175 | before_filter :conditional_in_parent, :only => [:show, :another_action] |
| 168 | after_filter :conditional_in_parent, :only => [:show, :another_action] | 176 | after_filter :conditional_in_parent, :only => [:show, :another_action] |
| 169 | - | 177 | + |
| 170 | private | 178 | private |
| 171 | - | 179 | + |
| 172 | def conditional_in_parent | 180 | def conditional_in_parent |
| 173 | @ran_filter ||= [] | 181 | @ran_filter ||= [] |
| 174 | @ran_filter << 'conditional_in_parent' | 182 | @ran_filter << 'conditional_in_parent' |
| 175 | end | 183 | end |
| 176 | end | 184 | end |
| 177 | - | 185 | + |
| 178 | class ChildOfConditionalParentController < ConditionalParentOfConditionalSkippingController | 186 | class ChildOfConditionalParentController < ConditionalParentOfConditionalSkippingController |
| 179 | skip_before_filter :conditional_in_parent, :only => :another_action | 187 | skip_before_filter :conditional_in_parent, :only => :another_action |
| 180 | skip_after_filter :conditional_in_parent, :only => :another_action | 188 | skip_after_filter :conditional_in_parent, :only => :another_action |
| @@ -197,7 +205,7 @@ class FilterTest < Test::Unit::TestCase | @@ -197,7 +205,7 @@ class FilterTest < Test::Unit::TestCase | ||
| 197 | controller.assigns["was_audited"] = true | 205 | controller.assigns["was_audited"] = true |
| 198 | end | 206 | end |
| 199 | end | 207 | end |
| 200 | - | 208 | + |
| 201 | class AroundFilter | 209 | class AroundFilter |
| 202 | def before(controller) | 210 | def before(controller) |
| 203 | @execution_log = "before" | 211 | @execution_log = "before" |
| @@ -209,7 +217,7 @@ class FilterTest < Test::Unit::TestCase | @@ -209,7 +217,7 @@ class FilterTest < Test::Unit::TestCase | ||
| 209 | controller.assigns["execution_log"] = @execution_log + " and after" | 217 | controller.assigns["execution_log"] = @execution_log + " and after" |
| 210 | controller.assigns["after_ran"] = true | 218 | controller.assigns["after_ran"] = true |
| 211 | controller.class.execution_log << " after aroundfilter " if controller.respond_to? :execution_log | 219 | controller.class.execution_log << " after aroundfilter " if controller.respond_to? :execution_log |
| 212 | - end | 220 | + end |
| 213 | end | 221 | end |
| 214 | 222 | ||
| 215 | class AppendedAroundFilter | 223 | class AppendedAroundFilter |
| @@ -219,12 +227,12 @@ class FilterTest < Test::Unit::TestCase | @@ -219,12 +227,12 @@ class FilterTest < Test::Unit::TestCase | ||
| 219 | 227 | ||
| 220 | def after(controller) | 228 | def after(controller) |
| 221 | controller.class.execution_log << " after appended aroundfilter " | 229 | controller.class.execution_log << " after appended aroundfilter " |
| 222 | - end | ||
| 223 | - end | ||
| 224 | - | 230 | + end |
| 231 | + end | ||
| 232 | + | ||
| 225 | class AuditController < ActionController::Base | 233 | class AuditController < ActionController::Base |
| 226 | before_filter(AuditFilter) | 234 | before_filter(AuditFilter) |
| 227 | - | 235 | + |
| 228 | def show | 236 | def show |
| 229 | render_text "hello" | 237 | render_text "hello" |
| 230 | end | 238 | end |
| @@ -234,6 +242,14 @@ class FilterTest < Test::Unit::TestCase | @@ -234,6 +242,14 @@ class FilterTest < Test::Unit::TestCase | ||
| 234 | around_filter AroundFilter.new | 242 | around_filter AroundFilter.new |
| 235 | end | 243 | end |
| 236 | 244 | ||
| 245 | + class BeforeAfterClassFilterController < PrependingController | ||
| 246 | + begin | ||
| 247 | + filter = AroundFilter.new | ||
| 248 | + before_filter filter | ||
| 249 | + after_filter filter | ||
| 250 | + end | ||
| 251 | + end | ||
| 252 | + | ||
| 237 | class MixedFilterController < PrependingController | 253 | class MixedFilterController < PrependingController |
| 238 | cattr_accessor :execution_log | 254 | cattr_accessor :execution_log |
| 239 | 255 | ||
| @@ -247,7 +263,7 @@ class FilterTest < Test::Unit::TestCase | @@ -247,7 +263,7 @@ class FilterTest < Test::Unit::TestCase | ||
| 247 | after_filter { |c| c.class.execution_log << " after procfilter " } | 263 | after_filter { |c| c.class.execution_log << " after procfilter " } |
| 248 | append_around_filter AppendedAroundFilter.new | 264 | append_around_filter AppendedAroundFilter.new |
| 249 | end | 265 | end |
| 250 | - | 266 | + |
| 251 | class MixedSpecializationController < ActionController::Base | 267 | class MixedSpecializationController < ActionController::Base |
| 252 | class OutOfOrder < StandardError; end | 268 | class OutOfOrder < StandardError; end |
| 253 | 269 | ||
| @@ -285,6 +301,101 @@ class FilterTest < Test::Unit::TestCase | @@ -285,6 +301,101 @@ class FilterTest < Test::Unit::TestCase | ||
| 285 | end | 301 | end |
| 286 | end | 302 | end |
| 287 | 303 | ||
| 304 | + class PrependingBeforeAndAfterController < ActionController::Base | ||
| 305 | + prepend_before_filter :before_all | ||
| 306 | + prepend_after_filter :after_all | ||
| 307 | + before_filter :between_before_all_and_after_all | ||
| 308 | + | ||
| 309 | + def before_all | ||
| 310 | + @ran_filter ||= [] | ||
| 311 | + @ran_filter << 'before_all' | ||
| 312 | + end | ||
| 313 | + | ||
| 314 | + def after_all | ||
| 315 | + @ran_filter ||= [] | ||
| 316 | + @ran_filter << 'after_all' | ||
| 317 | + end | ||
| 318 | + | ||
| 319 | + def between_before_all_and_after_all | ||
| 320 | + @ran_filter ||= [] | ||
| 321 | + @ran_filter << 'between_before_all_and_after_all' | ||
| 322 | + end | ||
| 323 | + def show | ||
| 324 | + render :text => 'hello' | ||
| 325 | + end | ||
| 326 | + end | ||
| 327 | + | ||
| 328 | + class NonYieldingAroundFilterController < ActionController::Base | ||
| 329 | + | ||
| 330 | + before_filter :filter_one | ||
| 331 | + around_filter :non_yielding_filter | ||
| 332 | + before_filter :filter_two | ||
| 333 | + after_filter :filter_three | ||
| 334 | + | ||
| 335 | + def index | ||
| 336 | + render :inline => "index" | ||
| 337 | + end | ||
| 338 | + | ||
| 339 | + #make sure the controller complains | ||
| 340 | + def rescue_action(e); raise e; end | ||
| 341 | + | ||
| 342 | + private | ||
| 343 | + | ||
| 344 | + def filter_one | ||
| 345 | + @filters ||= [] | ||
| 346 | + @filters << "filter_one" | ||
| 347 | + end | ||
| 348 | + | ||
| 349 | + def filter_two | ||
| 350 | + @filters << "filter_two" | ||
| 351 | + end | ||
| 352 | + | ||
| 353 | + def non_yielding_filter | ||
| 354 | + @filters << "zomg it didn't yield" | ||
| 355 | + @filter_return_value | ||
| 356 | + end | ||
| 357 | + | ||
| 358 | + def filter_three | ||
| 359 | + @filters << "filter_three" | ||
| 360 | + end | ||
| 361 | + | ||
| 362 | + end | ||
| 363 | + | ||
| 364 | + def test_non_yielding_around_filters_not_returning_false_do_not_raise | ||
| 365 | + controller = NonYieldingAroundFilterController.new | ||
| 366 | + controller.instance_variable_set "@filter_return_value", true | ||
| 367 | + assert_nothing_raised do | ||
| 368 | + test_process(controller, "index") | ||
| 369 | + end | ||
| 370 | + end | ||
| 371 | + | ||
| 372 | + def test_non_yielding_around_filters_returning_false_do_not_raise | ||
| 373 | + controller = NonYieldingAroundFilterController.new | ||
| 374 | + controller.instance_variable_set "@filter_return_value", false | ||
| 375 | + assert_nothing_raised do | ||
| 376 | + test_process(controller, "index") | ||
| 377 | + end | ||
| 378 | + end | ||
| 379 | + | ||
| 380 | + def test_after_filters_are_not_run_if_around_filter_returns_false | ||
| 381 | + controller = NonYieldingAroundFilterController.new | ||
| 382 | + controller.instance_variable_set "@filter_return_value", false | ||
| 383 | + test_process(controller, "index") | ||
| 384 | + assert_equal ["filter_one", "zomg it didn't yield"], controller.assigns['filters'] | ||
| 385 | + end | ||
| 386 | + | ||
| 387 | + def test_after_filters_are_not_run_if_around_filter_does_not_yield | ||
| 388 | + controller = NonYieldingAroundFilterController.new | ||
| 389 | + controller.instance_variable_set "@filter_return_value", true | ||
| 390 | + test_process(controller, "index") | ||
| 391 | + assert_equal ["filter_one", "zomg it didn't yield"], controller.assigns['filters'] | ||
| 392 | + end | ||
| 393 | + | ||
| 394 | + def test_empty_filter_chain | ||
| 395 | + assert_equal 0, EmptyFilterChainController.filter_chain.size | ||
| 396 | + assert test_process(EmptyFilterChainController).template.assigns['action_executed'] | ||
| 397 | + end | ||
| 398 | + | ||
| 288 | def test_added_filter_to_inheritance_graph | 399 | def test_added_filter_to_inheritance_graph |
| 289 | assert_equal [ :ensure_login ], TestController.before_filters | 400 | assert_equal [ :ensure_login ], TestController.before_filters |
| 290 | end | 401 | end |
| @@ -292,11 +403,11 @@ class FilterTest < Test::Unit::TestCase | @@ -292,11 +403,11 @@ class FilterTest < Test::Unit::TestCase | ||
| 292 | def test_base_class_in_isolation | 403 | def test_base_class_in_isolation |
| 293 | assert_equal [ ], ActionController::Base.before_filters | 404 | assert_equal [ ], ActionController::Base.before_filters |
| 294 | end | 405 | end |
| 295 | - | 406 | + |
| 296 | def test_prepending_filter | 407 | def test_prepending_filter |
| 297 | assert_equal [ :wonderful_life, :ensure_login ], PrependingController.before_filters | 408 | assert_equal [ :wonderful_life, :ensure_login ], PrependingController.before_filters |
| 298 | end | 409 | end |
| 299 | - | 410 | + |
| 300 | def test_running_filters | 411 | def test_running_filters |
| 301 | assert_equal %w( wonderful_life ensure_login ), test_process(PrependingController).template.assigns["ran_filter"] | 412 | assert_equal %w( wonderful_life ensure_login ), test_process(PrependingController).template.assigns["ran_filter"] |
| 302 | end | 413 | end |
| @@ -304,11 +415,11 @@ class FilterTest < Test::Unit::TestCase | @@ -304,11 +415,11 @@ class FilterTest < Test::Unit::TestCase | ||
| 304 | def test_running_filters_with_proc | 415 | def test_running_filters_with_proc |
| 305 | assert test_process(ProcController).template.assigns["ran_proc_filter"] | 416 | assert test_process(ProcController).template.assigns["ran_proc_filter"] |
| 306 | end | 417 | end |
| 307 | - | 418 | + |
| 308 | def test_running_filters_with_implicit_proc | 419 | def test_running_filters_with_implicit_proc |
| 309 | assert test_process(ImplicitProcController).template.assigns["ran_proc_filter"] | 420 | assert test_process(ImplicitProcController).template.assigns["ran_proc_filter"] |
| 310 | end | 421 | end |
| 311 | - | 422 | + |
| 312 | def test_running_filters_with_class | 423 | def test_running_filters_with_class |
| 313 | assert test_process(AuditController).template.assigns["was_audited"] | 424 | assert test_process(AuditController).template.assigns["was_audited"] |
| 314 | end | 425 | end |
| @@ -319,7 +430,7 @@ class FilterTest < Test::Unit::TestCase | @@ -319,7 +430,7 @@ class FilterTest < Test::Unit::TestCase | ||
| 319 | assert response.template.assigns["ran_class_filter"] | 430 | assert response.template.assigns["ran_class_filter"] |
| 320 | assert response.template.assigns["ran_proc_filter1"] | 431 | assert response.template.assigns["ran_proc_filter1"] |
| 321 | assert response.template.assigns["ran_proc_filter2"] | 432 | assert response.template.assigns["ran_proc_filter2"] |
| 322 | - | 433 | + |
| 323 | response = test_process(AnomolousYetValidConditionController, "show_without_filter") | 434 | response = test_process(AnomolousYetValidConditionController, "show_without_filter") |
| 324 | assert_equal nil, response.template.assigns["ran_filter"] | 435 | assert_equal nil, response.template.assigns["ran_filter"] |
| 325 | assert !response.template.assigns["ran_class_filter"] | 436 | assert !response.template.assigns["ran_class_filter"] |
| @@ -373,6 +484,12 @@ class FilterTest < Test::Unit::TestCase | @@ -373,6 +484,12 @@ class FilterTest < Test::Unit::TestCase | ||
| 373 | assert controller.template.assigns["after_ran"] | 484 | assert controller.template.assigns["after_ran"] |
| 374 | end | 485 | end |
| 375 | 486 | ||
| 487 | + def test_before_after_class_filter | ||
| 488 | + controller = test_process(BeforeAfterClassFilterController) | ||
| 489 | + assert controller.template.assigns["before_ran"] | ||
| 490 | + assert controller.template.assigns["after_ran"] | ||
| 491 | + end | ||
| 492 | + | ||
| 376 | def test_having_properties_in_around_filter | 493 | def test_having_properties_in_around_filter |
| 377 | controller = test_process(AroundFilterController) | 494 | controller = test_process(AroundFilterController) |
| 378 | assert_equal "before and after", controller.template.assigns["execution_log"] | 495 | assert_equal "before and after", controller.template.assigns["execution_log"] |
| @@ -381,10 +498,10 @@ class FilterTest < Test::Unit::TestCase | @@ -381,10 +498,10 @@ class FilterTest < Test::Unit::TestCase | ||
| 381 | def test_prepending_and_appending_around_filter | 498 | def test_prepending_and_appending_around_filter |
| 382 | controller = test_process(MixedFilterController) | 499 | controller = test_process(MixedFilterController) |
| 383 | assert_equal " before aroundfilter before procfilter before appended aroundfilter " + | 500 | assert_equal " before aroundfilter before procfilter before appended aroundfilter " + |
| 384 | - " after appended aroundfilter after aroundfilter after procfilter ", | 501 | + " after appended aroundfilter after aroundfilter after procfilter ", |
| 385 | MixedFilterController.execution_log | 502 | MixedFilterController.execution_log |
| 386 | end | 503 | end |
| 387 | - | 504 | + |
| 388 | def test_rendering_breaks_filtering_chain | 505 | def test_rendering_breaks_filtering_chain |
| 389 | response = test_process(RenderingController) | 506 | response = test_process(RenderingController) |
| 390 | assert_equal "something else", response.body | 507 | assert_equal "something else", response.body |
| @@ -412,6 +529,12 @@ class FilterTest < Test::Unit::TestCase | @@ -412,6 +529,12 @@ class FilterTest < Test::Unit::TestCase | ||
| 412 | end | 529 | end |
| 413 | end | 530 | end |
| 414 | 531 | ||
| 532 | + def test_running_prepended_before_and_after_filter | ||
| 533 | + assert_equal 3, PrependingBeforeAndAfterController.filter_chain.length | ||
| 534 | + response = test_process(PrependingBeforeAndAfterController) | ||
| 535 | + assert_equal %w( before_all between_before_all_and_after_all after_all ), response.template.assigns["ran_filter"] | ||
| 536 | + end | ||
| 537 | + | ||
| 415 | def test_conditional_skipping_of_filters | 538 | def test_conditional_skipping_of_filters |
| 416 | assert_nil test_process(ConditionalSkippingController, "login").template.assigns["ran_filter"] | 539 | assert_nil test_process(ConditionalSkippingController, "login").template.assigns["ran_filter"] |
| 417 | assert_equal %w( ensure_login find_user ), test_process(ConditionalSkippingController, "change_password").template.assigns["ran_filter"] | 540 | assert_equal %w( ensure_login find_user ), test_process(ConditionalSkippingController, "change_password").template.assigns["ran_filter"] |
vendor/rails/actionpack/test/controller/integration_test.rb
| @@ -11,7 +11,7 @@ require 'stubba' | @@ -11,7 +11,7 @@ require 'stubba' | ||
| 11 | module ActionController | 11 | module ActionController |
| 12 | module Integration | 12 | module Integration |
| 13 | class Session | 13 | class Session |
| 14 | - def process | 14 | + def process(*args) |
| 15 | end | 15 | end |
| 16 | 16 | ||
| 17 | def generic_url_rewriter | 17 | def generic_url_rewriter |
| @@ -56,8 +56,7 @@ class SessionTest < Test::Unit::TestCase | @@ -56,8 +56,7 @@ class SessionTest < Test::Unit::TestCase | ||
| 56 | 56 | ||
| 57 | @session.expects(:get).with(path,args) | 57 | @session.expects(:get).with(path,args) |
| 58 | 58 | ||
| 59 | - redirects = [true, true, false] | ||
| 60 | - @session.stubs(:redirect?).returns(lambda { redirects.shift }) | 59 | + @session.stubs(:redirect?).returns(true).then.returns(true).then.returns(false) |
| 61 | @session.expects(:follow_redirect!).times(2) | 60 | @session.expects(:follow_redirect!).times(2) |
| 62 | 61 | ||
| 63 | @session.stubs(:status).returns(200) | 62 | @session.stubs(:status).returns(200) |
| @@ -69,8 +68,7 @@ class SessionTest < Test::Unit::TestCase | @@ -69,8 +68,7 @@ class SessionTest < Test::Unit::TestCase | ||
| 69 | 68 | ||
| 70 | @session.expects(:post).with(path,args) | 69 | @session.expects(:post).with(path,args) |
| 71 | 70 | ||
| 72 | - redirects = [true, true, false] | ||
| 73 | - @session.stubs(:redirect?).returns(lambda { redirects.shift }) | 71 | + @session.stubs(:redirect?).returns(true).then.returns(true).then.returns(false) |
| 74 | @session.expects(:follow_redirect!).times(2) | 72 | @session.expects(:follow_redirect!).times(2) |
| 75 | 73 | ||
| 76 | @session.stubs(:status).returns(200) | 74 | @session.stubs(:status).returns(200) |
| @@ -134,15 +132,102 @@ class SessionTest < Test::Unit::TestCase | @@ -134,15 +132,102 @@ class SessionTest < Test::Unit::TestCase | ||
| 134 | @session.head(path,params,headers) | 132 | @session.head(path,params,headers) |
| 135 | end | 133 | end |
| 136 | 134 | ||
| 137 | - def test_xml_http_request | 135 | + def test_xml_http_request_deprecated_call |
| 138 | path = "/index"; params = "blah"; headers = {:location => 'blah'} | 136 | path = "/index"; params = "blah"; headers = {:location => 'blah'} |
| 139 | headers_after_xhr = headers.merge( | 137 | headers_after_xhr = headers.merge( |
| 140 | "X-Requested-With" => "XMLHttpRequest", | 138 | "X-Requested-With" => "XMLHttpRequest", |
| 141 | "Accept" => "text/javascript, text/html, application/xml, text/xml, */*" | 139 | "Accept" => "text/javascript, text/html, application/xml, text/xml, */*" |
| 142 | ) | 140 | ) |
| 143 | - @session.expects(:post).with(path,params,headers_after_xhr) | ||
| 144 | - @session.xml_http_request(path,params,headers) | 141 | + @session.expects(:process).with(:post,path,params,headers_after_xhr) |
| 142 | + assert_deprecated { @session.xml_http_request(path,params,headers) } | ||
| 145 | end | 143 | end |
| 144 | + | ||
| 145 | + def test_xml_http_request_get | ||
| 146 | + path = "/index"; params = "blah"; headers = {:location => 'blah'} | ||
| 147 | + headers_after_xhr = headers.merge( | ||
| 148 | + "X-Requested-With" => "XMLHttpRequest", | ||
| 149 | + "Accept" => "text/javascript, text/html, application/xml, text/xml, */*" | ||
| 150 | + ) | ||
| 151 | + @session.expects(:process).with(:get,path,params,headers_after_xhr) | ||
| 152 | + @session.xml_http_request(:get,path,params,headers) | ||
| 153 | + end | ||
| 154 | + | ||
| 155 | + def test_xml_http_request_post | ||
| 156 | + path = "/index"; params = "blah"; headers = {:location => 'blah'} | ||
| 157 | + headers_after_xhr = headers.merge( | ||
| 158 | + "X-Requested-With" => "XMLHttpRequest", | ||
| 159 | + "Accept" => "text/javascript, text/html, application/xml, text/xml, */*" | ||
| 160 | + ) | ||
| 161 | + @session.expects(:process).with(:post,path,params,headers_after_xhr) | ||
| 162 | + @session.xml_http_request(:post,path,params,headers) | ||
| 163 | + end | ||
| 164 | + | ||
| 165 | + def test_xml_http_request_put | ||
| 166 | + path = "/index"; params = "blah"; headers = {:location => 'blah'} | ||
| 167 | + headers_after_xhr = headers.merge( | ||
| 168 | + "X-Requested-With" => "XMLHttpRequest", | ||
| 169 | + "Accept" => "text/javascript, text/html, application/xml, text/xml, */*" | ||
| 170 | + ) | ||
| 171 | + @session.expects(:process).with(:put,path,params,headers_after_xhr) | ||
| 172 | + @session.xml_http_request(:put,path,params,headers) | ||
| 173 | + end | ||
| 174 | + | ||
| 175 | + def test_xml_http_request_delete | ||
| 176 | + path = "/index"; params = "blah"; headers = {:location => 'blah'} | ||
| 177 | + headers_after_xhr = headers.merge( | ||
| 178 | + "X-Requested-With" => "XMLHttpRequest", | ||
| 179 | + "Accept" => "text/javascript, text/html, application/xml, text/xml, */*" | ||
| 180 | + ) | ||
| 181 | + @session.expects(:process).with(:delete,path,params,headers_after_xhr) | ||
| 182 | + @session.xml_http_request(:delete,path,params,headers) | ||
| 183 | + end | ||
| 184 | + | ||
| 185 | + def test_xml_http_request_head | ||
| 186 | + path = "/index"; params = "blah"; headers = {:location => 'blah'} | ||
| 187 | + headers_after_xhr = headers.merge( | ||
| 188 | + "X-Requested-With" => "XMLHttpRequest", | ||
| 189 | + "Accept" => "text/javascript, text/html, application/xml, text/xml, */*" | ||
| 190 | + ) | ||
| 191 | + @session.expects(:process).with(:head,path,params,headers_after_xhr) | ||
| 192 | + @session.xml_http_request(:head,path,params,headers) | ||
| 193 | + end | ||
| 194 | +end | ||
| 195 | + | ||
| 196 | +class IntegrationTestTest < Test::Unit::TestCase | ||
| 197 | + | ||
| 198 | + def setup | ||
| 199 | + @test = ::ActionController::IntegrationTest.new(:default_test) | ||
| 200 | + @test.class.stubs(:fixture_table_names).returns([]) | ||
| 201 | + @session = @test.open_session | ||
| 202 | + end | ||
| 203 | + | ||
| 204 | + def test_opens_new_session | ||
| 205 | + @test.class.expects(:fixture_table_names).times(2).returns(['foo']) | ||
| 206 | + | ||
| 207 | + session1 = @test.open_session { |sess| } | ||
| 208 | + session2 = @test.open_session # implicit session | ||
| 209 | + | ||
| 210 | + assert_equal ::ActionController::Integration::Session, session1.class | ||
| 211 | + assert_equal ::ActionController::Integration::Session, session2.class | ||
| 212 | + assert_not_equal session1, session2 | ||
| 213 | + end | ||
| 214 | + | ||
| 215 | +end | ||
| 216 | + | ||
| 217 | +# Tests that integration tests don't call Controller test methods for processing. | ||
| 218 | +# Integration tests have their own setup and teardown. | ||
| 219 | +class IntegrationTestUsesCorrectClass < ActionController::IntegrationTest | ||
| 220 | + | ||
| 221 | + def self.fixture_table_names | ||
| 222 | + [] | ||
| 223 | + end | ||
| 224 | + | ||
| 225 | + def test_integration_methods_called | ||
| 226 | + %w( get post head put delete ).each do |verb| | ||
| 227 | + assert_nothing_raised("'#{verb}' should use integration test methods") { send(verb, '/') } | ||
| 228 | + end | ||
| 229 | + end | ||
| 230 | + | ||
| 146 | end | 231 | end |
| 147 | 232 | ||
| 148 | # TODO | 233 | # TODO |
vendor/rails/actionpack/test/controller/resources_test.rb
| @@ -10,8 +10,9 @@ class ThreadsController < ResourcesController; end | @@ -10,8 +10,9 @@ class ThreadsController < ResourcesController; end | ||
| 10 | class MessagesController < ResourcesController; end | 10 | class MessagesController < ResourcesController; end |
| 11 | class CommentsController < ResourcesController; end | 11 | class CommentsController < ResourcesController; end |
| 12 | 12 | ||
| 13 | -class AccountController < ResourcesController; end | ||
| 14 | -class AdminController < ResourcesController; end | 13 | +class AccountController < ResourcesController; end |
| 14 | +class AdminController < ResourcesController; end | ||
| 15 | +class ProductsController < ResourcesController; end | ||
| 15 | 16 | ||
| 16 | class ResourcesTest < Test::Unit::TestCase | 17 | class ResourcesTest < Test::Unit::TestCase |
| 17 | def test_should_arrange_actions | 18 | def test_should_arrange_actions |
| @@ -63,13 +64,13 @@ class ResourcesTest < Test::Unit::TestCase | @@ -63,13 +64,13 @@ class ResourcesTest < Test::Unit::TestCase | ||
| 63 | end | 64 | end |
| 64 | end | 65 | end |
| 65 | 66 | ||
| 66 | - def test_multile_with_path_prefix | 67 | + def test_multiple_with_path_prefix |
| 67 | with_restful_routing :messages, :comments, :path_prefix => '/thread/:thread_id' do | 68 | with_restful_routing :messages, :comments, :path_prefix => '/thread/:thread_id' do |
| 68 | assert_simply_restful_for :messages, :path_prefix => 'thread/5/', :options => { :thread_id => '5' } | 69 | assert_simply_restful_for :messages, :path_prefix => 'thread/5/', :options => { :thread_id => '5' } |
| 69 | assert_simply_restful_for :comments, :path_prefix => 'thread/5/', :options => { :thread_id => '5' } | 70 | assert_simply_restful_for :comments, :path_prefix => 'thread/5/', :options => { :thread_id => '5' } |
| 70 | end | 71 | end |
| 71 | end | 72 | end |
| 72 | - | 73 | + |
| 73 | def test_with_name_prefix | 74 | def test_with_name_prefix |
| 74 | with_restful_routing :messages, :name_prefix => 'post_' do | 75 | with_restful_routing :messages, :name_prefix => 'post_' do |
| 75 | assert_simply_restful_for :messages, :name_prefix => 'post_' | 76 | assert_simply_restful_for :messages, :name_prefix => 'post_' |
| @@ -78,7 +79,7 @@ class ResourcesTest < Test::Unit::TestCase | @@ -78,7 +79,7 @@ class ResourcesTest < Test::Unit::TestCase | ||
| 78 | 79 | ||
| 79 | def test_with_collection_action | 80 | def test_with_collection_action |
| 80 | rss_options = {:action => 'rss'} | 81 | rss_options = {:action => 'rss'} |
| 81 | - rss_path = "/messages;rss" | 82 | + rss_path = "/messages/rss" |
| 82 | actions = { 'a' => :put, 'b' => :post, 'c' => :delete } | 83 | actions = { 'a' => :put, 'b' => :post, 'c' => :delete } |
| 83 | 84 | ||
| 84 | with_restful_routing :messages, :collection => { :rss => :get }.merge(actions) do | 85 | with_restful_routing :messages, :collection => { :rss => :get }.merge(actions) do |
| @@ -86,14 +87,14 @@ class ResourcesTest < Test::Unit::TestCase | @@ -86,14 +87,14 @@ class ResourcesTest < Test::Unit::TestCase | ||
| 86 | assert_routing rss_path, options.merge(rss_options) | 87 | assert_routing rss_path, options.merge(rss_options) |
| 87 | 88 | ||
| 88 | actions.each do |action, method| | 89 | actions.each do |action, method| |
| 89 | - assert_recognizes(options.merge(:action => action), :path => "/messages;#{action}", :method => method) | 90 | + assert_recognizes(options.merge(:action => action), :path => "/messages/#{action}", :method => method) |
| 90 | end | 91 | end |
| 91 | end | 92 | end |
| 92 | 93 | ||
| 93 | assert_restful_named_routes_for :messages do |options| | 94 | assert_restful_named_routes_for :messages do |options| |
| 94 | assert_named_route rss_path, :rss_messages_path, rss_options | 95 | assert_named_route rss_path, :rss_messages_path, rss_options |
| 95 | actions.keys.each do |action| | 96 | actions.keys.each do |action| |
| 96 | - assert_named_route "/messages;#{action}", "#{action}_messages_path", :action => action | 97 | + assert_named_route "/messages/#{action}", "#{action}_messages_path", :action => action |
| 97 | end | 98 | end |
| 98 | end | 99 | end |
| 99 | end | 100 | end |
| @@ -103,7 +104,7 @@ class ResourcesTest < Test::Unit::TestCase | @@ -103,7 +104,7 @@ class ResourcesTest < Test::Unit::TestCase | ||
| 103 | [:put, :post].each do |method| | 104 | [:put, :post].each do |method| |
| 104 | with_restful_routing :messages, :member => { :mark => method } do | 105 | with_restful_routing :messages, :member => { :mark => method } do |
| 105 | mark_options = {:action => 'mark', :id => '1'} | 106 | mark_options = {:action => 'mark', :id => '1'} |
| 106 | - mark_path = "/messages/1;mark" | 107 | + mark_path = "/messages/1/mark" |
| 107 | assert_restful_routes_for :messages do |options| | 108 | assert_restful_routes_for :messages do |options| |
| 108 | assert_recognizes(options.merge(mark_options), :path => mark_path, :method => method) | 109 | assert_recognizes(options.merge(mark_options), :path => mark_path, :method => method) |
| 109 | end | 110 | end |
| @@ -120,7 +121,7 @@ class ResourcesTest < Test::Unit::TestCase | @@ -120,7 +121,7 @@ class ResourcesTest < Test::Unit::TestCase | ||
| 120 | with_restful_routing :messages, :member => { :mark => method, :unmark => method } do | 121 | with_restful_routing :messages, :member => { :mark => method, :unmark => method } do |
| 121 | %w(mark unmark).each do |action| | 122 | %w(mark unmark).each do |action| |
| 122 | action_options = {:action => action, :id => '1'} | 123 | action_options = {:action => action, :id => '1'} |
| 123 | - action_path = "/messages/1;#{action}" | 124 | + action_path = "/messages/1/#{action}" |
| 124 | assert_restful_routes_for :messages do |options| | 125 | assert_restful_routes_for :messages do |options| |
| 125 | assert_recognizes(options.merge(action_options), :path => action_path, :method => method) | 126 | assert_recognizes(options.merge(action_options), :path => action_path, :method => method) |
| 126 | end | 127 | end |
| @@ -136,7 +137,7 @@ class ResourcesTest < Test::Unit::TestCase | @@ -136,7 +137,7 @@ class ResourcesTest < Test::Unit::TestCase | ||
| 136 | def test_with_new_action | 137 | def test_with_new_action |
| 137 | with_restful_routing :messages, :new => { :preview => :post } do | 138 | with_restful_routing :messages, :new => { :preview => :post } do |
| 138 | preview_options = {:action => 'preview'} | 139 | preview_options = {:action => 'preview'} |
| 139 | - preview_path = "/messages/new;preview" | 140 | + preview_path = "/messages/new/preview" |
| 140 | assert_restful_routes_for :messages do |options| | 141 | assert_restful_routes_for :messages do |options| |
| 141 | assert_recognizes(options.merge(preview_options), :path => preview_path, :method => :post) | 142 | assert_recognizes(options.merge(preview_options), :path => preview_path, :method => :post) |
| 142 | end | 143 | end |
| @@ -178,9 +179,11 @@ class ResourcesTest < Test::Unit::TestCase | @@ -178,9 +179,11 @@ class ResourcesTest < Test::Unit::TestCase | ||
| 178 | assert_simply_restful_for :threads | 179 | assert_simply_restful_for :threads |
| 179 | assert_simply_restful_for :messages, | 180 | assert_simply_restful_for :messages, |
| 180 | :path_prefix => 'threads/1/', | 181 | :path_prefix => 'threads/1/', |
| 182 | + :name_prefix => 'thread_', | ||
| 181 | :options => { :thread_id => '1' } | 183 | :options => { :thread_id => '1' } |
| 182 | assert_simply_restful_for :comments, | 184 | assert_simply_restful_for :comments, |
| 183 | :path_prefix => 'threads/1/messages/2/', | 185 | :path_prefix => 'threads/1/messages/2/', |
| 186 | + :name_prefix => 'thread_message_', | ||
| 184 | :options => { :thread_id => '1', :message_id => '2' } | 187 | :options => { :thread_id => '1', :message_id => '2' } |
| 185 | end | 188 | end |
| 186 | end | 189 | end |
| @@ -217,9 +220,9 @@ class ResourcesTest < Test::Unit::TestCase | @@ -217,9 +220,9 @@ class ResourcesTest < Test::Unit::TestCase | ||
| 217 | admin.resource :account | 220 | admin.resource :account |
| 218 | end | 221 | end |
| 219 | end | 222 | end |
| 220 | - | 223 | + |
| 221 | assert_singleton_restful_for :admin | 224 | assert_singleton_restful_for :admin |
| 222 | - assert_singleton_restful_for :account, :path_prefix => 'admin/' | 225 | + assert_singleton_restful_for :account, :path_prefix => 'admin/', :name_prefix => 'admin_' |
| 223 | end | 226 | end |
| 224 | end | 227 | end |
| 225 | 228 | ||
| @@ -227,7 +230,7 @@ class ResourcesTest < Test::Unit::TestCase | @@ -227,7 +230,7 @@ class ResourcesTest < Test::Unit::TestCase | ||
| 227 | [:put, :post].each do |method| | 230 | [:put, :post].each do |method| |
| 228 | with_singleton_resources :account, :member => { :reset => method } do | 231 | with_singleton_resources :account, :member => { :reset => method } do |
| 229 | reset_options = {:action => 'reset'} | 232 | reset_options = {:action => 'reset'} |
| 230 | - reset_path = "/account;reset" | 233 | + reset_path = "/account/reset" |
| 231 | assert_singleton_routes_for :account do |options| | 234 | assert_singleton_routes_for :account do |options| |
| 232 | assert_recognizes(options.merge(reset_options), :path => reset_path, :method => method) | 235 | assert_recognizes(options.merge(reset_options), :path => reset_path, :method => method) |
| 233 | end | 236 | end |
| @@ -244,7 +247,7 @@ class ResourcesTest < Test::Unit::TestCase | @@ -244,7 +247,7 @@ class ResourcesTest < Test::Unit::TestCase | ||
| 244 | with_singleton_resources :account, :member => { :reset => method, :disable => method } do | 247 | with_singleton_resources :account, :member => { :reset => method, :disable => method } do |
| 245 | %w(reset disable).each do |action| | 248 | %w(reset disable).each do |action| |
| 246 | action_options = {:action => action} | 249 | action_options = {:action => action} |
| 247 | - action_path = "/account;#{action}" | 250 | + action_path = "/account/#{action}" |
| 248 | assert_singleton_routes_for :account do |options| | 251 | assert_singleton_routes_for :account do |options| |
| 249 | assert_recognizes(options.merge(action_options), :path => action_path, :method => method) | 252 | assert_recognizes(options.merge(action_options), :path => action_path, :method => method) |
| 250 | end | 253 | end |
| @@ -264,9 +267,9 @@ class ResourcesTest < Test::Unit::TestCase | @@ -264,9 +267,9 @@ class ResourcesTest < Test::Unit::TestCase | ||
| 264 | account.resources :messages | 267 | account.resources :messages |
| 265 | end | 268 | end |
| 266 | end | 269 | end |
| 267 | - | 270 | + |
| 268 | assert_singleton_restful_for :account | 271 | assert_singleton_restful_for :account |
| 269 | - assert_simply_restful_for :messages, :path_prefix => 'account/' | 272 | + assert_simply_restful_for :messages, :path_prefix => 'account/', :name_prefix => 'account_' |
| 270 | end | 273 | end |
| 271 | end | 274 | end |
| 272 | 275 | ||
| @@ -279,10 +282,10 @@ class ResourcesTest < Test::Unit::TestCase | @@ -279,10 +282,10 @@ class ResourcesTest < Test::Unit::TestCase | ||
| 279 | end | 282 | end |
| 280 | 283 | ||
| 281 | assert_singleton_restful_for :account, :path_prefix => '7/', :options => { :site_id => '7' } | 284 | 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' } | 285 | + assert_simply_restful_for :messages, :path_prefix => '7/account/', :name_prefix => 'account_', :options => { :site_id => '7' } |
| 283 | end | 286 | end |
| 284 | end | 287 | end |
| 285 | - | 288 | + |
| 286 | def test_should_nest_singleton_resource_in_resources | 289 | def test_should_nest_singleton_resource_in_resources |
| 287 | with_routing do |set| | 290 | with_routing do |set| |
| 288 | set.draw do |map| | 291 | set.draw do |map| |
| @@ -290,9 +293,9 @@ class ResourcesTest < Test::Unit::TestCase | @@ -290,9 +293,9 @@ class ResourcesTest < Test::Unit::TestCase | ||
| 290 | thread.resource :admin | 293 | thread.resource :admin |
| 291 | end | 294 | end |
| 292 | end | 295 | end |
| 293 | - | 296 | + |
| 294 | assert_simply_restful_for :threads | 297 | assert_simply_restful_for :threads |
| 295 | - assert_singleton_restful_for :admin, :path_prefix => 'threads/5/', :options => { :thread_id => '5' } | 298 | + assert_singleton_restful_for :admin, :path_prefix => 'threads/5/', :name_prefix => 'thread_', :options => { :thread_id => '5' } |
| 296 | end | 299 | end |
| 297 | end | 300 | end |
| 298 | 301 | ||
| @@ -312,6 +315,181 @@ class ResourcesTest < Test::Unit::TestCase | @@ -312,6 +315,181 @@ class ResourcesTest < Test::Unit::TestCase | ||
| 312 | end | 315 | end |
| 313 | end | 316 | end |
| 314 | 317 | ||
| 318 | + def test_resource_action_separator | ||
| 319 | + with_routing do |set| | ||
| 320 | + set.draw do |map| | ||
| 321 | + map.resources :messages, :collection => {:search => :get}, :new => {:preview => :any}, :name_prefix => 'thread_', :path_prefix => '/threads/:thread_id' | ||
| 322 | + map.resource :account, :member => {:login => :get}, :new => {:preview => :any}, :name_prefix => 'admin_', :path_prefix => '/admin' | ||
| 323 | + end | ||
| 324 | + | ||
| 325 | + action_separator = ActionController::Base.resource_action_separator | ||
| 326 | + | ||
| 327 | + assert_simply_restful_for :messages, :name_prefix => 'thread_', :path_prefix => 'threads/1/', :options => { :thread_id => '1' } | ||
| 328 | + assert_named_route "/threads/1/messages#{action_separator}search", "search_thread_messages_path", {} | ||
| 329 | + assert_named_route "/threads/1/messages/new", "new_thread_message_path", {} | ||
| 330 | + assert_named_route "/threads/1/messages/new#{action_separator}preview", "preview_new_thread_message_path", {} | ||
| 331 | + assert_singleton_restful_for :account, :name_prefix => 'admin_', :path_prefix => 'admin/' | ||
| 332 | + assert_named_route "/admin/account#{action_separator}login", "login_admin_account_path", {} | ||
| 333 | + assert_named_route "/admin/account/new", "new_admin_account_path", {} | ||
| 334 | + assert_named_route "/admin/account/new#{action_separator}preview", "preview_new_admin_account_path", {} | ||
| 335 | + end | ||
| 336 | + end | ||
| 337 | + | ||
| 338 | + def test_new_style_named_routes_for_resource | ||
| 339 | + with_routing do |set| | ||
| 340 | + set.draw do |map| | ||
| 341 | + map.resources :messages, :collection => {:search => :get}, :new => {:preview => :any}, :name_prefix => 'thread_', :path_prefix => '/threads/:thread_id' | ||
| 342 | + end | ||
| 343 | + assert_simply_restful_for :messages, :name_prefix => 'thread_', :path_prefix => 'threads/1/', :options => { :thread_id => '1' } | ||
| 344 | + assert_named_route "/threads/1/messages/search", "search_thread_messages_path", {} | ||
| 345 | + assert_named_route "/threads/1/messages/new", "new_thread_message_path", {} | ||
| 346 | + assert_named_route "/threads/1/messages/new/preview", "preview_new_thread_message_path", {} | ||
| 347 | + end | ||
| 348 | + end | ||
| 349 | + | ||
| 350 | + def test_new_style_named_routes_for_singleton_resource | ||
| 351 | + with_routing do |set| | ||
| 352 | + set.draw do |map| | ||
| 353 | + map.resource :account, :member => {:login => :get}, :new => {:preview => :any}, :name_prefix => 'admin_', :path_prefix => '/admin' | ||
| 354 | + end | ||
| 355 | + assert_singleton_restful_for :account, :name_prefix => 'admin_', :path_prefix => 'admin/' | ||
| 356 | + assert_named_route "/admin/account/login", "login_admin_account_path", {} | ||
| 357 | + assert_named_route "/admin/account/new", "new_admin_account_path", {} | ||
| 358 | + assert_named_route "/admin/account/new/preview", "preview_new_admin_account_path", {} | ||
| 359 | + end | ||
| 360 | + end | ||
| 361 | + | ||
| 362 | + def test_should_add_deprecated_named_routes_for_resource | ||
| 363 | + with_routing do |set| | ||
| 364 | + set.draw do |map| | ||
| 365 | + map.resources :messages, :collection => {:search => :get}, :new => {:preview => :any}, :name_prefix => 'thread_', :path_prefix => '/threads/:thread_id' | ||
| 366 | + end | ||
| 367 | + assert_simply_restful_for :messages, :name_prefix => 'thread_', :path_prefix => 'threads/1/', :options => { :thread_id => '1' } | ||
| 368 | + assert_deprecated do | ||
| 369 | + assert_named_route "/threads/1/messages/search", "thread_search_messages_path", {} | ||
| 370 | + assert_named_route "/threads/1/messages/new", "thread_new_message_path", {} | ||
| 371 | + assert_named_route "/threads/1/messages/new/preview", "thread_preview_new_message_path", {} | ||
| 372 | + end | ||
| 373 | + end | ||
| 374 | + end | ||
| 375 | + | ||
| 376 | + def test_should_add_deprecated_named_routes_for_singleton_resource | ||
| 377 | + with_routing do |set| | ||
| 378 | + set.draw do |map| | ||
| 379 | + map.resource :account, :member => {:login => :get}, :new => {:preview => :any}, :name_prefix => 'admin_', :path_prefix => '/admin' | ||
| 380 | + end | ||
| 381 | + assert_singleton_restful_for :account, :name_prefix => 'admin_', :path_prefix => 'admin/' | ||
| 382 | + assert_deprecated do | ||
| 383 | + assert_named_route "/admin/account/login", "admin_login_account_path", {} | ||
| 384 | + assert_named_route "/admin/account/new", "admin_new_account_path", {} | ||
| 385 | + assert_named_route "/admin/account/new/preview", "admin_preview_new_account_path", {} | ||
| 386 | + end | ||
| 387 | + end | ||
| 388 | + end | ||
| 389 | + | ||
| 390 | + def test_should_add_deprecated_named_routes_for_nested_resources | ||
| 391 | + with_routing do |set| | ||
| 392 | + set.draw do |map| | ||
| 393 | + map.resources :threads do |map| | ||
| 394 | + map.resources :messages do |map| | ||
| 395 | + map.resources :comments | ||
| 396 | + end | ||
| 397 | + end | ||
| 398 | + end | ||
| 399 | + | ||
| 400 | + assert_simply_restful_for :threads | ||
| 401 | + assert_simply_restful_for :messages, | ||
| 402 | + :path_prefix => 'threads/1/', | ||
| 403 | + :name_prefix => 'thread_', | ||
| 404 | + :options => { :thread_id => '1' } | ||
| 405 | + assert_simply_restful_for :comments, | ||
| 406 | + :path_prefix => 'threads/1/messages/2/', | ||
| 407 | + :name_prefix => 'thread_message_', | ||
| 408 | + :options => { :thread_id => '1', :message_id => '2' } | ||
| 409 | + | ||
| 410 | + assert_deprecated do | ||
| 411 | + assert_named_route "/threads/1/messages", "messages_path", {} | ||
| 412 | + assert_named_route "/threads/1/messages/1", "message_path", {:thread_id => '1', :id => '1'} | ||
| 413 | + assert_named_route "/threads/1/messages/new", "new_message_path", {:thread_id => '1'} | ||
| 414 | + assert_named_route "/threads/1/messages/1/edit", "edit_message_path", {:thread_id => '1', :id => '1'} | ||
| 415 | + end | ||
| 416 | + end | ||
| 417 | + end | ||
| 418 | + | ||
| 419 | + def test_should_add_deprecated_named_routes_for_nested_singleton_resources | ||
| 420 | + with_routing do |set| | ||
| 421 | + set.draw do |map| | ||
| 422 | + map.resource :admin do |admin| | ||
| 423 | + admin.resource :account | ||
| 424 | + end | ||
| 425 | + end | ||
| 426 | + | ||
| 427 | + assert_singleton_restful_for :admin | ||
| 428 | + assert_singleton_restful_for :account, :path_prefix => 'admin/', :name_prefix => 'admin_' | ||
| 429 | + | ||
| 430 | + assert_deprecated do | ||
| 431 | + assert_named_route "/admin/account", "account_path", {} | ||
| 432 | + assert_named_route "/admin/account/new", "new_account_path", {} | ||
| 433 | + assert_named_route "/admin/account/edit", "edit_account_path", {} | ||
| 434 | + end | ||
| 435 | + end | ||
| 436 | + end | ||
| 437 | + | ||
| 438 | + def test_should_add_deprecated_named_routes_for_nested_resources_in_singleton_resource | ||
| 439 | + with_routing do |set| | ||
| 440 | + set.draw do |map| | ||
| 441 | + map.resource :account do |account| | ||
| 442 | + account.resources :messages | ||
| 443 | + end | ||
| 444 | + end | ||
| 445 | + | ||
| 446 | + assert_singleton_restful_for :account | ||
| 447 | + assert_simply_restful_for :messages, :path_prefix => 'account/', :name_prefix => 'account_' | ||
| 448 | + | ||
| 449 | + assert_deprecated do | ||
| 450 | + assert_named_route "/account/messages", "messages_path", {} | ||
| 451 | + assert_named_route "/account/messages/1", "message_path", {:id => '1'} | ||
| 452 | + assert_named_route "/account/messages/new", "new_message_path", {} | ||
| 453 | + assert_named_route "/account/messages/1/edit", "edit_message_path", {:id => '1'} | ||
| 454 | + end | ||
| 455 | + end | ||
| 456 | + end | ||
| 457 | + | ||
| 458 | + def test_should_add_deprecated_named_routes_for_nested_singleton_resource_in_resources | ||
| 459 | + with_routing do |set| | ||
| 460 | + set.draw do |map| | ||
| 461 | + map.resources :threads do |thread| | ||
| 462 | + thread.resource :admin | ||
| 463 | + end | ||
| 464 | + end | ||
| 465 | + | ||
| 466 | + assert_simply_restful_for :threads | ||
| 467 | + assert_singleton_restful_for :admin, :path_prefix => 'threads/5/', :name_prefix => 'thread_', :options => { :thread_id => '5' } | ||
| 468 | + | ||
| 469 | + assert_deprecated do | ||
| 470 | + assert_named_route "/threads/5/admin", "admin_path", {} | ||
| 471 | + assert_named_route "/threads/5/admin/new", "new_admin_path", {} | ||
| 472 | + assert_named_route "/threads/5/admin/edit", "edit_admin_path", {} | ||
| 473 | + end | ||
| 474 | + end | ||
| 475 | + end | ||
| 476 | + | ||
| 477 | + def test_should_add_deprecated_formatted_routes | ||
| 478 | + with_routing do |set| | ||
| 479 | + set.draw do |map| | ||
| 480 | + map.resources :products, :collection => { :specials => :get }, :member => { :thumbnail => :get } | ||
| 481 | + map.resource :account, :member => { :icon => :get } | ||
| 482 | + end | ||
| 483 | + assert_restful_routes_for :products do |options| | ||
| 484 | + assert_recognizes options.merge({ :action => 'specials', :format => 'xml' }), :path => '/products.xml;specials', :method => :get | ||
| 485 | + assert_recognizes options.merge({ :action => 'thumbnail', :format => 'jpg', :id => '1' }), :path => '/products/1.jpg;thumbnail', :method => :get | ||
| 486 | + end | ||
| 487 | + assert_singleton_restful_for :account do |options| | ||
| 488 | + assert_recognizes options.merge({ :action => 'icon', :format => 'jpg' }), :path => '/account.jpg;icon', :method => :get | ||
| 489 | + end | ||
| 490 | + end | ||
| 491 | + end | ||
| 492 | + | ||
| 315 | protected | 493 | protected |
| 316 | def with_restful_routing(*args) | 494 | def with_restful_routing(*args) |
| 317 | with_routing do |set| | 495 | with_routing do |set| |
| @@ -319,7 +497,7 @@ class ResourcesTest < Test::Unit::TestCase | @@ -319,7 +497,7 @@ class ResourcesTest < Test::Unit::TestCase | ||
| 319 | yield | 497 | yield |
| 320 | end | 498 | end |
| 321 | end | 499 | end |
| 322 | - | 500 | + |
| 323 | def with_singleton_resources(*args) | 501 | def with_singleton_resources(*args) |
| 324 | with_routing do |set| | 502 | with_routing do |set| |
| 325 | set.draw { |map| map.resource(*args) } | 503 | set.draw { |map| map.resource(*args) } |
| @@ -344,8 +522,8 @@ class ResourcesTest < Test::Unit::TestCase | @@ -344,8 +522,8 @@ class ResourcesTest < Test::Unit::TestCase | ||
| 344 | collection_path = "/#{options[:path_prefix]}#{controller_name}" | 522 | collection_path = "/#{options[:path_prefix]}#{controller_name}" |
| 345 | member_path = "#{collection_path}/1" | 523 | member_path = "#{collection_path}/1" |
| 346 | new_path = "#{collection_path}/new" | 524 | new_path = "#{collection_path}/new" |
| 347 | - edit_member_path = "#{member_path};edit" | ||
| 348 | - formatted_edit_member_path = "#{member_path}.xml;edit" | 525 | + edit_member_path = "#{member_path}/edit" |
| 526 | + formatted_edit_member_path = "#{member_path}/edit.xml" | ||
| 349 | 527 | ||
| 350 | with_options(options[:options]) do |controller| | 528 | with_options(options[:options]) do |controller| |
| 351 | controller.assert_routing collection_path, :action => 'index' | 529 | controller.assert_routing collection_path, :action => 'index' |
| @@ -395,13 +573,13 @@ class ResourcesTest < Test::Unit::TestCase | @@ -395,13 +573,13 @@ class ResourcesTest < Test::Unit::TestCase | ||
| 395 | name_prefix = options[:name_prefix] | 573 | name_prefix = options[:name_prefix] |
| 396 | 574 | ||
| 397 | assert_named_route "#{full_prefix}", "#{name_prefix}#{controller_name}_path", options[:options] | 575 | 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] | 576 | + assert_named_route "#{full_prefix}/new", "new_#{name_prefix}#{singular_name}_path", options[:options] |
| 399 | assert_named_route "#{full_prefix}/1", "#{name_prefix}#{singular_name}_path", options[:options].merge(:id => '1') | 577 | 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') | 578 | + assert_named_route "#{full_prefix}/1/edit", "edit_#{name_prefix}#{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') | 579 | 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') | 580 | + assert_named_route "#{full_prefix}/new.xml", "formatted_new_#{name_prefix}#{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') | 581 | 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') | 582 | + assert_named_route "#{full_prefix}/1/edit.xml", "formatted_edit_#{name_prefix}#{singular_name}_path", options[:options].merge(:id => '1', :format => 'xml') |
| 405 | yield options[:options] if block_given? | 583 | yield options[:options] if block_given? |
| 406 | end | 584 | end |
| 407 | 585 | ||
| @@ -410,8 +588,8 @@ class ResourcesTest < Test::Unit::TestCase | @@ -410,8 +588,8 @@ class ResourcesTest < Test::Unit::TestCase | ||
| 410 | 588 | ||
| 411 | full_path = "/#{options[:path_prefix]}#{singleton_name}" | 589 | full_path = "/#{options[:path_prefix]}#{singleton_name}" |
| 412 | new_path = "#{full_path}/new" | 590 | new_path = "#{full_path}/new" |
| 413 | - edit_path = "#{full_path};edit" | ||
| 414 | - formatted_edit_path = "#{full_path}.xml;edit" | 591 | + edit_path = "#{full_path}/edit" |
| 592 | + formatted_edit_path = "#{full_path}/edit.xml" | ||
| 415 | 593 | ||
| 416 | with_options options[:options] do |controller| | 594 | with_options options[:options] do |controller| |
| 417 | controller.assert_routing full_path, :action => 'show' | 595 | controller.assert_routing full_path, :action => 'show' |
| @@ -448,13 +626,14 @@ class ResourcesTest < Test::Unit::TestCase | @@ -448,13 +626,14 @@ class ResourcesTest < Test::Unit::TestCase | ||
| 448 | options[:options].delete :action | 626 | options[:options].delete :action |
| 449 | 627 | ||
| 450 | full_path = "/#{options[:path_prefix]}#{singleton_name}" | 628 | 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') | 629 | + full_name = "#{options[:name_prefix]}#{singleton_name}" |
| 630 | + | ||
| 631 | + assert_named_route "#{full_path}", "#{full_name}_path", options[:options] | ||
| 632 | + assert_named_route "#{full_path}/new", "new_#{full_name}_path", options[:options] | ||
| 633 | + assert_named_route "#{full_path}/edit", "edit_#{full_name}_path", options[:options] | ||
| 634 | + assert_named_route "#{full_path}.xml", "formatted_#{full_name}_path", options[:options].merge(:format => 'xml') | ||
| 635 | + assert_named_route "#{full_path}/new.xml", "formatted_new_#{full_name}_path", options[:options].merge(:format => 'xml') | ||
| 636 | + assert_named_route "#{full_path}/edit.xml", "formatted_edit_#{full_name}_path", options[:options].merge(:format => 'xml') | ||
| 458 | end | 637 | end |
| 459 | 638 | ||
| 460 | def assert_named_route(expected, route, options) | 639 | def assert_named_route(expected, route, options) |
vendor/rails/actionpack/test/controller/routing_test.rb
| @@ -265,7 +265,7 @@ class LegacyRouteSetTests < Test::Unit::TestCase | @@ -265,7 +265,7 @@ class LegacyRouteSetTests < Test::Unit::TestCase | ||
| 265 | map.content '/content/:query', :controller => 'content', :action => 'show' | 265 | map.content '/content/:query', :controller => 'content', :action => 'show' |
| 266 | end | 266 | end |
| 267 | exception = assert_raise(ActionController::RoutingError) { rs.generate(:controller => 'content', :action => 'show', :use_route => "content") } | 267 | exception = assert_raise(ActionController::RoutingError) { rs.generate(:controller => 'content', :action => 'show', :use_route => "content") } |
| 268 | - expected_message = %[content_url failed to generate from {:action=>"show", :controller=>"content"} - you may have ambiguous routes, or you may need to supply additional parameters for this route. content_url has the following required parameters: ["content", :query] - are they all satisifed?] | 268 | + expected_message = "content_url failed to generate from #{{:action=>"show", :controller=>"content"}.inspect} - you may have ambiguous routes, or you may need to supply additional parameters for this route. content_url has the following required parameters: [\"content\", :query] - are they all satisifed?" |
| 269 | assert_equal expected_message, exception.message | 269 | assert_equal expected_message, exception.message |
| 270 | end | 270 | end |
| 271 | 271 | ||
| @@ -946,7 +946,7 @@ class RouteTest < Test::Unit::TestCase | @@ -946,7 +946,7 @@ class RouteTest < Test::Unit::TestCase | ||
| 946 | end | 946 | end |
| 947 | 947 | ||
| 948 | def test_expand_array_build_query_string | 948 | def test_expand_array_build_query_string |
| 949 | - assert_equal '?x[]=1&x[]=2', order_query_string(@route.build_query_string(:x => [1, 2])) | 949 | + assert_equal '?x%5B%5D=1&x%5B%5D=2', order_query_string(@route.build_query_string(:x => [1, 2])) |
| 950 | end | 950 | end |
| 951 | 951 | ||
| 952 | def test_escape_spaces_build_query_string_selected_keys | 952 | def test_escape_spaces_build_query_string_selected_keys |
vendor/rails/actionpack/test/controller/session_fixation_test.rb
0 → 100644
| @@ -0,0 +1,92 @@ | @@ -0,0 +1,92 @@ | ||
| 1 | +require File.dirname(__FILE__) + '/../abstract_unit' | ||
| 2 | + | ||
| 3 | +class SessionFixationTest < Test::Unit::TestCase | ||
| 4 | + class MockCGI < CGI #:nodoc: | ||
| 5 | + attr_accessor :stdoutput, :env_table | ||
| 6 | + | ||
| 7 | + def initialize(env, data = '') | ||
| 8 | + self.env_table = env | ||
| 9 | + self.stdoutput = StringIO.new | ||
| 10 | + super(StringIO.new(data)) | ||
| 11 | + end | ||
| 12 | + end | ||
| 13 | + | ||
| 14 | + class TestController < ActionController::Base | ||
| 15 | + session :session_key => '_myapp_session_id', :secret => 'secret', :except => :default_session_key | ||
| 16 | + session :cookie_only => false, :only => :allow_session_fixation | ||
| 17 | + | ||
| 18 | + def default_session_key | ||
| 19 | + render :text => "default_session_key" | ||
| 20 | + end | ||
| 21 | + | ||
| 22 | + def custom_session_key | ||
| 23 | + render :text => "custom_session_key: #{params[:id]}" | ||
| 24 | + end | ||
| 25 | + | ||
| 26 | + def allow_session_fixation | ||
| 27 | + render :text => "allow_session_fixation" | ||
| 28 | + end | ||
| 29 | + | ||
| 30 | + def rescue_action(e) raise end | ||
| 31 | + end | ||
| 32 | + | ||
| 33 | + def setup | ||
| 34 | + @controller = TestController.new | ||
| 35 | + end | ||
| 36 | + | ||
| 37 | + def test_should_be_able_to_make_a_successful_request | ||
| 38 | + cgi = mock_cgi_for_request_to(:custom_session_key, :id => 1) | ||
| 39 | + | ||
| 40 | + assert_nothing_raised do | ||
| 41 | + @controller.send(:process, mock_request(cgi), ActionController::CgiResponse.new(cgi)) | ||
| 42 | + end | ||
| 43 | + assert_equal 'custom_session_key: 1', @controller.response.body | ||
| 44 | + assert_not_nil @controller.session | ||
| 45 | + end | ||
| 46 | + | ||
| 47 | + def test_should_catch_session_fixation_attempt | ||
| 48 | + cgi = mock_cgi_for_request_to(:custom_session_key, :_myapp_session_id => 42) | ||
| 49 | + | ||
| 50 | + assert_raises ActionController::CgiRequest::SessionFixationAttempt do | ||
| 51 | + @controller.send(:process, mock_request(cgi), ActionController::CgiResponse.new(cgi)) | ||
| 52 | + end | ||
| 53 | + assert_nil @controller.session | ||
| 54 | + end | ||
| 55 | + | ||
| 56 | + def test_should_not_catch_session_fixation_attempt_when_cookie_only_setting_is_disabled | ||
| 57 | + cgi = mock_cgi_for_request_to(:allow_session_fixation, :_myapp_session_id => 42) | ||
| 58 | + | ||
| 59 | + assert_nothing_raised do | ||
| 60 | + @controller.send(:process, mock_request(cgi), ActionController::CgiResponse.new(cgi)) | ||
| 61 | + end | ||
| 62 | + assert !@controller.response.body.blank? | ||
| 63 | + assert_not_nil @controller.session | ||
| 64 | + end | ||
| 65 | + | ||
| 66 | + def test_should_catch_session_fixation_attempt_with_default_session_key | ||
| 67 | + ActionController::Base.session_store = :p_store # using the default session_key is not possible with cookie store | ||
| 68 | + cgi = mock_cgi_for_request_to(:default_session_key, :_session_id => 42) | ||
| 69 | + | ||
| 70 | + assert_raises ActionController::CgiRequest::SessionFixationAttempt do | ||
| 71 | + @controller.send(:process, mock_request(cgi) , ActionController::CgiResponse.new(cgi)) | ||
| 72 | + end | ||
| 73 | + assert @controller.response.body.blank? | ||
| 74 | + assert_nil @controller.session | ||
| 75 | + end | ||
| 76 | + | ||
| 77 | +private | ||
| 78 | + | ||
| 79 | + def mock_cgi_for_request_to(action, params = {}) | ||
| 80 | + MockCGI.new({ | ||
| 81 | + "REQUEST_METHOD" => "GET", | ||
| 82 | + "QUERY_STRING" => "action=#{action}&#{params.to_query}", | ||
| 83 | + "REQUEST_URI" => "/", | ||
| 84 | + "SERVER_PORT" => "80", | ||
| 85 | + "HTTP_HOST" => "testdomain.com" }, '') | ||
| 86 | + end | ||
| 87 | + | ||
| 88 | + def mock_request(cgi) | ||
| 89 | + ActionController::CgiRequest.new(cgi, {}) | ||
| 90 | + end | ||
| 91 | + | ||
| 92 | +end |
vendor/rails/actionpack/test/controller/test_test.rb
| @@ -482,6 +482,22 @@ HTML | @@ -482,6 +482,22 @@ HTML | ||
| 482 | end | 482 | end |
| 483 | end | 483 | end |
| 484 | 484 | ||
| 485 | + def test_request_uri_updates | ||
| 486 | + get :test_params | ||
| 487 | + uri = @request.request_uri | ||
| 488 | + assert_equal @request.env['REQUEST_URI'], uri | ||
| 489 | + | ||
| 490 | + get :test_uri | ||
| 491 | + assert_not_equal uri, @request.request_uri | ||
| 492 | + uri = @request.request_uri | ||
| 493 | + assert_equal @request.env['REQUEST_URI'], uri | ||
| 494 | + | ||
| 495 | + get :test_uri, :testing => true | ||
| 496 | + assert_not_equal uri, @request.request_uri | ||
| 497 | + uri = @request.request_uri | ||
| 498 | + assert_equal @request.env['REQUEST_URI'], uri | ||
| 499 | + end | ||
| 500 | + | ||
| 485 | protected | 501 | protected |
| 486 | def with_foo_routing | 502 | def with_foo_routing |
| 487 | with_routing do |set| | 503 | with_routing do |set| |
vendor/rails/actionpack/test/controller/url_rewriter_test.rb
| @@ -17,15 +17,12 @@ class UrlRewriterTests < Test::Unit::TestCase | @@ -17,15 +17,12 @@ class UrlRewriterTests < Test::Unit::TestCase | ||
| 17 | assert_match %r(/hi/hi/2$), u | 17 | assert_match %r(/hi/hi/2$), u |
| 18 | end | 18 | end |
| 19 | 19 | ||
| 20 | - | ||
| 21 | - private | ||
| 22 | - def split_query_string(str) | ||
| 23 | - [str[0].chr] + str[1..-1].split(/&/).sort | ||
| 24 | - end | ||
| 25 | - | ||
| 26 | - def assert_query_equal(q1, q2) | ||
| 27 | - assert_equal(split_query_string(q1), split_query_string(q2)) | ||
| 28 | - end | 20 | + def test_anchor |
| 21 | + assert_equal( | ||
| 22 | + 'http://test.host/c/a/i#anchor', | ||
| 23 | + @rewriter.rewrite(:controller => 'c', :action => 'a', :id => 'i', :anchor => 'anchor') | ||
| 24 | + ) | ||
| 25 | + end | ||
| 29 | end | 26 | end |
| 30 | 27 | ||
| 31 | class UrlWriterTests < Test::Unit::TestCase | 28 | class UrlWriterTests < Test::Unit::TestCase |
| @@ -75,6 +72,12 @@ class UrlWriterTests < Test::Unit::TestCase | @@ -75,6 +72,12 @@ class UrlWriterTests < Test::Unit::TestCase | ||
| 75 | W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => 'https') | 72 | W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => 'https') |
| 76 | ) | 73 | ) |
| 77 | end | 74 | end |
| 75 | + | ||
| 76 | + def test_anchor | ||
| 77 | + assert_equal('/c/a#anchor', | ||
| 78 | + W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :anchor => 'anchor') | ||
| 79 | + ) | ||
| 80 | + end | ||
| 78 | 81 | ||
| 79 | def test_named_route | 82 | def test_named_route |
| 80 | ActionController::Routing::Routes.draw do |map| | 83 | ActionController::Routing::Routes.draw do |map| |
| @@ -111,5 +114,58 @@ class UrlWriterTests < Test::Unit::TestCase | @@ -111,5 +114,58 @@ class UrlWriterTests < Test::Unit::TestCase | ||
| 111 | ensure | 114 | ensure |
| 112 | ActionController::Routing::Routes.load! | 115 | ActionController::Routing::Routes.load! |
| 113 | end | 116 | end |
| 114 | - | 117 | + |
| 118 | + def test_one_parameter | ||
| 119 | + assert_equal('/c/a?param=val', | ||
| 120 | + W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :param => 'val') | ||
| 121 | + ) | ||
| 122 | + end | ||
| 123 | + | ||
| 124 | + def test_two_parameters | ||
| 125 | + url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :p1 => 'X1', :p2 => 'Y2') | ||
| 126 | + params = extract_params(url) | ||
| 127 | + assert_equal params[0], { :p1 => 'X1' }.to_query | ||
| 128 | + assert_equal params[1], { :p2 => 'Y2' }.to_query | ||
| 129 | + end | ||
| 130 | + | ||
| 131 | + def test_hash_parameter | ||
| 132 | + url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :query => {:name => 'Bob', :category => 'prof'}) | ||
| 133 | + params = extract_params(url) | ||
| 134 | + assert_equal params[0], { 'query[category]' => 'prof' }.to_query | ||
| 135 | + assert_equal params[1], { 'query[name]' => 'Bob' }.to_query | ||
| 136 | + end | ||
| 137 | + | ||
| 138 | + def test_array_parameter | ||
| 139 | + url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :query => ['Bob', 'prof']) | ||
| 140 | + params = extract_params(url) | ||
| 141 | + assert_equal params[0], { 'query[]' => 'Bob' }.to_query | ||
| 142 | + assert_equal params[1], { 'query[]' => 'prof' }.to_query | ||
| 143 | + end | ||
| 144 | + | ||
| 145 | + def test_hash_recursive_parameters | ||
| 146 | + url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :query => {:person => {:name => 'Bob', :position => 'prof'}, :hobby => 'piercing'}) | ||
| 147 | + params = extract_params(url) | ||
| 148 | + assert_equal params[0], { 'query[hobby]' => 'piercing' }.to_query | ||
| 149 | + assert_equal params[1], { 'query[person][name]' => 'Bob' }.to_query | ||
| 150 | + assert_equal params[2], { 'query[person][position]' => 'prof' }.to_query | ||
| 151 | + end | ||
| 152 | + | ||
| 153 | + def test_hash_recursive_and_array_parameters | ||
| 154 | + url = W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :id => 101, :query => {:person => {:name => 'Bob', :position => ['prof', 'art director']}, :hobby => 'piercing'}) | ||
| 155 | + assert_match %r(^/c/a/101), url | ||
| 156 | + params = extract_params(url) | ||
| 157 | + assert_equal params[0], { 'query[hobby]' => 'piercing' }.to_query | ||
| 158 | + assert_equal params[1], { 'query[person][name]' => 'Bob' }.to_query | ||
| 159 | + assert_equal params[2], { 'query[person][position][]' => 'art director' }.to_query | ||
| 160 | + assert_equal params[3], { 'query[person][position][]' => 'prof' }.to_query | ||
| 161 | + end | ||
| 162 | + | ||
| 163 | + def test_path_generation_for_symbol_parameter_keys | ||
| 164 | + assert_generates("/image", :controller=> :image) | ||
| 165 | + end | ||
| 166 | + | ||
| 167 | + private | ||
| 168 | + def extract_params(url) | ||
| 169 | + url.split('?', 2).last.split('&') | ||
| 170 | + end | ||
| 115 | end | 171 | end |
vendor/rails/actionpack/test/controller/verification_test.rb
| @@ -34,9 +34,16 @@ class VerificationTest < Test::Unit::TestCase | @@ -34,9 +34,16 @@ class VerificationTest < Test::Unit::TestCase | ||
| 34 | 34 | ||
| 35 | verify :only => :must_be_post, :method => :post, :render => { :status => 405, :text => "Must be post" }, :add_headers => { "Allow" => "POST" } | 35 | verify :only => :must_be_post, :method => :post, :render => { :status => 405, :text => "Must be post" }, :add_headers => { "Allow" => "POST" } |
| 36 | 36 | ||
| 37 | + verify :only => :guarded_one_for_named_route_test, :params => "one", | ||
| 38 | + :redirect_to => :foo_url | ||
| 39 | + | ||
| 37 | def guarded_one | 40 | def guarded_one |
| 38 | render :text => "#{params[:one]}" | 41 | render :text => "#{params[:one]}" |
| 39 | end | 42 | end |
| 43 | + | ||
| 44 | + def guarded_one_for_named_route_test | ||
| 45 | + render :text => "#{params[:one]}" | ||
| 46 | + end | ||
| 40 | 47 | ||
| 41 | def guarded_with_flash | 48 | def guarded_with_flash |
| 42 | render :text => "#{params[:one]}" | 49 | render :text => "#{params[:one]}" |
| @@ -94,6 +101,14 @@ class VerificationTest < Test::Unit::TestCase | @@ -94,6 +101,14 @@ class VerificationTest < Test::Unit::TestCase | ||
| 94 | @controller = TestController.new | 101 | @controller = TestController.new |
| 95 | @request = ActionController::TestRequest.new | 102 | @request = ActionController::TestRequest.new |
| 96 | @response = ActionController::TestResponse.new | 103 | @response = ActionController::TestResponse.new |
| 104 | + ActionController::Routing::Routes.add_named_route :foo, '/foo', :controller => 'test', :action => 'foo' | ||
| 105 | + end | ||
| 106 | + | ||
| 107 | + def test_no_deprecation_warning_for_named_route | ||
| 108 | + assert_not_deprecated do | ||
| 109 | + get :guarded_one_for_named_route_test, :two => "not one" | ||
| 110 | + assert_redirected_to '/foo' | ||
| 111 | + end | ||
| 97 | end | 112 | end |
| 98 | 113 | ||
| 99 | def test_guarded_one_with_prereqs | 114 | def test_guarded_one_with_prereqs |
vendor/rails/actionpack/test/fixtures/test/hello_world.rxml
vendor/rails/actionpack/test/template/asset_tag_helper_test.rb
| @@ -165,7 +165,12 @@ class AssetTagHelperTest < Test::Unit::TestCase | @@ -165,7 +165,12 @@ class AssetTagHelperTest < Test::Unit::TestCase | ||
| 165 | 165 | ||
| 166 | def test_preset_empty_asset_id | 166 | def test_preset_empty_asset_id |
| 167 | Object.send(:const_set, :RAILS_ROOT, File.dirname(__FILE__) + "/../fixtures/") | 167 | Object.send(:const_set, :RAILS_ROOT, File.dirname(__FILE__) + "/../fixtures/") |
| 168 | + # on windows, setting ENV["XXX"] to "" makes ENV["XXX"] return nil | ||
| 169 | + if RUBY_PLATFORM =~ /win32/ | ||
| 170 | + ENV["RAILS_ASSET_ID"] = " " | ||
| 171 | + else | ||
| 168 | ENV["RAILS_ASSET_ID"] = "" | 172 | ENV["RAILS_ASSET_ID"] = "" |
| 173 | + end | ||
| 169 | assert_equal %(<img alt="Rails" src="/images/rails.png" />), image_tag("rails.png") | 174 | assert_equal %(<img alt="Rails" src="/images/rails.png" />), image_tag("rails.png") |
| 170 | end | 175 | end |
| 171 | 176 |
vendor/rails/actionpack/test/template/compiled_templates_test.rb
| @@ -71,7 +71,12 @@ class CompiledTemplateTests < Test::Unit::TestCase | @@ -71,7 +71,12 @@ class CompiledTemplateTests < Test::Unit::TestCase | ||
| 71 | end | 71 | end |
| 72 | 72 | ||
| 73 | def test_compile_time | 73 | def test_compile_time |
| 74 | - `echo '#{@a}' > #{@a}; echo '#{@b}' > #{@b}; ln -s #{@a} #{@s}` | 74 | + File.open(@a, "w"){|f| f.puts @a} |
| 75 | + File.open(@b, "w"){|f| f.puts @b} | ||
| 76 | + | ||
| 77 | + # windows doesn't support symlinks (even under cygwin) | ||
| 78 | + windows = (RUBY_PLATFORM =~ /win32/) | ||
| 79 | + `ln -s #{@a} #{@s}` unless windows | ||
| 75 | 80 | ||
| 76 | v = ActionView::Base.new | 81 | v = ActionView::Base.new |
| 77 | v.base_path = '.' | 82 | v.base_path = '.' |
| @@ -79,47 +84,54 @@ class CompiledTemplateTests < Test::Unit::TestCase | @@ -79,47 +84,54 @@ class CompiledTemplateTests < Test::Unit::TestCase | ||
| 79 | 84 | ||
| 80 | sleep 1 | 85 | sleep 1 |
| 81 | t = Time.now | 86 | t = Time.now |
| 87 | + sleep 1 | ||
| 88 | + | ||
| 82 | v.compile_and_render_template(:rhtml, '', @a) | 89 | v.compile_and_render_template(:rhtml, '', @a) |
| 83 | v.compile_and_render_template(:rhtml, '', @b) | 90 | v.compile_and_render_template(:rhtml, '', @b) |
| 84 | - v.compile_and_render_template(:rhtml, '', @s) | 91 | + v.compile_and_render_template(:rhtml, '', @s) unless windows |
| 92 | + | ||
| 85 | a_n = v.method_names[@a] | 93 | a_n = v.method_names[@a] |
| 86 | b_n = v.method_names[@b] | 94 | b_n = v.method_names[@b] |
| 87 | - s_n = v.method_names[@s] | 95 | + s_n = v.method_names[@s] unless windows |
| 96 | + ct_a = v.compile_time[a_n] | ||
| 97 | + ct_b = v.compile_time[b_n] | ||
| 98 | + ct_s = v.compile_time[s_n] unless windows | ||
| 88 | # all of the files have changed since last compile | 99 | # all of the files have changed since last compile |
| 89 | assert v.compile_time[a_n] > t | 100 | assert v.compile_time[a_n] > t |
| 90 | assert v.compile_time[b_n] > t | 101 | assert v.compile_time[b_n] > t |
| 91 | - assert v.compile_time[s_n] > t | 102 | + assert v.compile_time[s_n] > t unless windows |
| 92 | 103 | ||
| 93 | sleep 1 | 104 | sleep 1 |
| 94 | - t = Time.now | ||
| 95 | v.compile_and_render_template(:rhtml, '', @a) | 105 | v.compile_and_render_template(:rhtml, '', @a) |
| 96 | v.compile_and_render_template(:rhtml, '', @b) | 106 | v.compile_and_render_template(:rhtml, '', @b) |
| 97 | - v.compile_and_render_template(:rhtml, '', @s) | 107 | + v.compile_and_render_template(:rhtml, '', @s) unless windows |
| 98 | # none of the files have changed since last compile | 108 | # none of the files have changed since last compile |
| 99 | - assert v.compile_time[a_n] < t | ||
| 100 | - assert v.compile_time[b_n] < t | ||
| 101 | - assert v.compile_time[s_n] < t | 109 | + # so they should not have been recmpiled |
| 110 | + assert_equal ct_a, v.compile_time[a_n] | ||
| 111 | + assert_equal ct_b, v.compile_time[b_n] | ||
| 112 | + assert_equal ct_s, v.compile_time[s_n] unless windows | ||
| 102 | 113 | ||
| 103 | - `rm #{@s}; ln -s #{@b} #{@s}` | 114 | + `rm #{@s}; ln -s #{@b} #{@s}` unless windows |
| 104 | v.compile_and_render_template(:rhtml, '', @a) | 115 | v.compile_and_render_template(:rhtml, '', @a) |
| 105 | v.compile_and_render_template(:rhtml, '', @b) | 116 | v.compile_and_render_template(:rhtml, '', @b) |
| 106 | - v.compile_and_render_template(:rhtml, '', @s) | 117 | + v.compile_and_render_template(:rhtml, '', @s) unless windows |
| 107 | # the symlink has changed since last compile | 118 | # the symlink has changed since last compile |
| 108 | - assert v.compile_time[a_n] < t | ||
| 109 | - assert v.compile_time[b_n] < t | ||
| 110 | - assert v.compile_time[s_n] > t | 119 | + assert_equal ct_a, v.compile_time[a_n] |
| 120 | + assert_equal ct_b, v.compile_time[b_n] | ||
| 121 | + assert v.compile_time[s_n] > t unless windows | ||
| 111 | 122 | ||
| 112 | sleep 1 | 123 | sleep 1 |
| 113 | - `touch #{@b}` | 124 | + FileUtils.touch @b |
| 114 | t = Time.now | 125 | t = Time.now |
| 126 | + sleep 1 | ||
| 115 | v.compile_and_render_template(:rhtml, '', @a) | 127 | v.compile_and_render_template(:rhtml, '', @a) |
| 116 | v.compile_and_render_template(:rhtml, '', @b) | 128 | v.compile_and_render_template(:rhtml, '', @b) |
| 117 | - v.compile_and_render_template(:rhtml, '', @s) | 129 | + v.compile_and_render_template(:rhtml, '', @s) unless windows |
| 118 | # the file at the end of the symlink has changed since last compile | 130 | # the file at the end of the symlink has changed since last compile |
| 119 | # both the symlink and the file at the end of it should be recompiled | 131 | # both the symlink and the file at the end of it should be recompiled |
| 120 | assert v.compile_time[a_n] < t | 132 | assert v.compile_time[a_n] < t |
| 121 | assert v.compile_time[b_n] > t | 133 | assert v.compile_time[b_n] > t |
| 122 | - assert v.compile_time[s_n] > t | 134 | + assert v.compile_time[s_n] > t unless windows |
| 123 | end | 135 | end |
| 124 | end | 136 | end |
| 125 | 137 |
vendor/rails/actionpack/test/template/javascript_helper_test.rb
| @@ -36,14 +36,14 @@ class JavaScriptHelperTest < Test::Unit::TestCase | @@ -36,14 +36,14 @@ class JavaScriptHelperTest < Test::Unit::TestCase | ||
| 36 | html = link_to_function( "Greet me!" ) do |page| | 36 | html = link_to_function( "Greet me!" ) do |page| |
| 37 | page.replace_html 'header', "<h1>Greetings</h1>" | 37 | page.replace_html 'header', "<h1>Greetings</h1>" |
| 38 | end | 38 | end |
| 39 | - assert_dom_equal %(<a href="#" onclick="Element.update("header", "<h1>Greetings</h1>");; return false;">Greet me!</a>), html | 39 | + assert_dom_equal %q(<a href="#" onclick="Element.update("header", "\074h1\076Greetings\074/h1\076");; return false;">Greet me!</a>), html |
| 40 | end | 40 | end |
| 41 | 41 | ||
| 42 | def test_link_to_function_with_rjs_block_and_options | 42 | def test_link_to_function_with_rjs_block_and_options |
| 43 | html = link_to_function( "Greet me!", :class => "updater" ) do |page| | 43 | html = link_to_function( "Greet me!", :class => "updater" ) do |page| |
| 44 | page.replace_html 'header', "<h1>Greetings</h1>" | 44 | page.replace_html 'header', "<h1>Greetings</h1>" |
| 45 | end | 45 | end |
| 46 | - assert_dom_equal %(<a href="#" class="updater" onclick="Element.update("header", "<h1>Greetings</h1>");; return false;">Greet me!</a>), html | 46 | + assert_dom_equal %q(<a href="#" class="updater" onclick="Element.update("header", "\074h1\076Greetings\074/h1\076");; return false;">Greet me!</a>), html |
| 47 | end | 47 | end |
| 48 | 48 | ||
| 49 | def test_button_to_function | 49 | def test_button_to_function |
| @@ -55,13 +55,13 @@ class JavaScriptHelperTest < Test::Unit::TestCase | @@ -55,13 +55,13 @@ class JavaScriptHelperTest < Test::Unit::TestCase | ||
| 55 | html = button_to_function( "Greet me!" ) do |page| | 55 | html = button_to_function( "Greet me!" ) do |page| |
| 56 | page.replace_html 'header', "<h1>Greetings</h1>" | 56 | page.replace_html 'header', "<h1>Greetings</h1>" |
| 57 | end | 57 | end |
| 58 | - assert_dom_equal %(<input type="button" onclick="Element.update("header", "<h1>Greetings</h1>");;" value="Greet me!" />), html | 58 | + assert_dom_equal %q(<input type="button" onclick="Element.update("header", "\074h1\076Greetings\074/h1\076");;" value="Greet me!" />), html |
| 59 | end | 59 | end |
| 60 | 60 | ||
| 61 | def test_button_to_function_with_rjs_block_and_options | 61 | def test_button_to_function_with_rjs_block_and_options |
| 62 | html = button_to_function( "Greet me!", :class => "greeter" ) do |page| | 62 | html = button_to_function( "Greet me!", :class => "greeter" ) do |page| |
| 63 | page.replace_html 'header', "<h1>Greetings</h1>" | 63 | page.replace_html 'header', "<h1>Greetings</h1>" |
| 64 | end | 64 | end |
| 65 | - assert_dom_equal %(<input type="button" class="greeter" onclick="Element.update("header", "<h1>Greetings</h1>");;" value="Greet me!" />), html | 65 | + assert_dom_equal %q(<input type="button" class="greeter" onclick="Element.update("header", "\074h1\076Greetings\074/h1\076");;" value="Greet me!" />), html |
| 66 | end | 66 | end |
| 67 | end | 67 | end |
vendor/rails/actionpack/test/template/number_helper_test.rb
| @@ -22,7 +22,7 @@ class NumberHelperTest < Test::Unit::TestCase | @@ -22,7 +22,7 @@ class NumberHelperTest < Test::Unit::TestCase | ||
| 22 | def test_number_to_currency | 22 | def test_number_to_currency |
| 23 | assert_equal("$1,234,567,890.50", number_to_currency(1234567890.50)) | 23 | assert_equal("$1,234,567,890.50", number_to_currency(1234567890.50)) |
| 24 | assert_equal("$1,234,567,890.51", number_to_currency(1234567890.506)) | 24 | assert_equal("$1,234,567,890.51", number_to_currency(1234567890.506)) |
| 25 | - assert_equal("$1,234,567,890", number_to_currency(1234567890.50, {:precision => 0})) | 25 | + assert_equal("$1,234,567,891", number_to_currency(1234567890.51, {:precision => 0})) |
| 26 | assert_equal("$1,234,567,890.5", number_to_currency(1234567890.50, {:precision => 1})) | 26 | assert_equal("$1,234,567,890.5", number_to_currency(1234567890.50, {:precision => 1})) |
| 27 | assert_equal("£1234567890,50", number_to_currency(1234567890.50, {:unit => "£", :separator => ",", :delimiter => ""})) | 27 | assert_equal("£1234567890,50", number_to_currency(1234567890.50, {:unit => "£", :separator => ",", :delimiter => ""})) |
| 28 | assert_equal("$1,234,567,890.50", number_to_currency("1234567890.50")) | 28 | assert_equal("$1,234,567,890.50", number_to_currency("1234567890.50")) |
vendor/rails/actionpack/test/template/prototype_helper_test.rb
| @@ -125,7 +125,7 @@ class PrototypeHelperTest < Test::Unit::TestCase | @@ -125,7 +125,7 @@ class PrototypeHelperTest < Test::Unit::TestCase | ||
| 125 | end | 125 | end |
| 126 | 126 | ||
| 127 | def test_observe_field | 127 | def test_observe_field |
| 128 | - assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nnew Form.Element.Observer('glass', 300, function(element, value) {new Ajax.Request('http://www.example.com/reorder_if_empty', {asynchronous:true, evalScripts:true})})\n//]]>\n</script>), | 128 | + assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nnew Form.Element.Observer('glass', 300, function(element, value) {new Ajax.Request('http://www.example.com/reorder_if_empty', {asynchronous:true, evalScripts:true, parameters:value})})\n//]]>\n</script>), |
| 129 | observe_field("glass", :frequency => 5.minutes, :url => { :action => "reorder_if_empty" }) | 129 | observe_field("glass", :frequency => 5.minutes, :url => { :action => "reorder_if_empty" }) |
| 130 | end | 130 | end |
| 131 | 131 | ||
| @@ -135,7 +135,7 @@ class PrototypeHelperTest < Test::Unit::TestCase | @@ -135,7 +135,7 @@ class PrototypeHelperTest < Test::Unit::TestCase | ||
| 135 | end | 135 | end |
| 136 | 136 | ||
| 137 | def test_observe_form | 137 | def test_observe_form |
| 138 | - assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nnew Form.Observer('cart', 2, function(element, value) {new Ajax.Request('http://www.example.com/cart_changed', {asynchronous:true, evalScripts:true})})\n//]]>\n</script>), | 138 | + assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nnew Form.Observer('cart', 2, function(element, value) {new Ajax.Request('http://www.example.com/cart_changed', {asynchronous:true, evalScripts:true, parameters:value})})\n//]]>\n</script>), |
| 139 | observe_form("cart", :frequency => 2, :url => { :action => "cart_changed" }) | 139 | observe_form("cart", :frequency => 2, :url => { :action => "cart_changed" }) |
| 140 | end | 140 | end |
| 141 | 141 | ||
| @@ -170,23 +170,23 @@ class JavaScriptGeneratorTest < Test::Unit::TestCase | @@ -170,23 +170,23 @@ class JavaScriptGeneratorTest < Test::Unit::TestCase | ||
| 170 | end | 170 | end |
| 171 | 171 | ||
| 172 | def test_insert_html_with_string | 172 | def test_insert_html_with_string |
| 173 | - assert_equal 'new Insertion.Top("element", "<p>This is a test</p>");', | 173 | + assert_equal 'new Insertion.Top("element", "\074p\076This is a test\074/p\076");', |
| 174 | @generator.insert_html(:top, 'element', '<p>This is a test</p>') | 174 | @generator.insert_html(:top, 'element', '<p>This is a test</p>') |
| 175 | - assert_equal 'new Insertion.Bottom("element", "<p>This is a test</p>");', | 175 | + assert_equal 'new Insertion.Bottom("element", "\074p\076This is a test\074/p\076");', |
| 176 | @generator.insert_html(:bottom, 'element', '<p>This is a test</p>') | 176 | @generator.insert_html(:bottom, 'element', '<p>This is a test</p>') |
| 177 | - assert_equal 'new Insertion.Before("element", "<p>This is a test</p>");', | 177 | + assert_equal 'new Insertion.Before("element", "\074p\076This is a test\074/p\076");', |
| 178 | @generator.insert_html(:before, 'element', '<p>This is a test</p>') | 178 | @generator.insert_html(:before, 'element', '<p>This is a test</p>') |
| 179 | - assert_equal 'new Insertion.After("element", "<p>This is a test</p>");', | 179 | + assert_equal 'new Insertion.After("element", "\074p\076This is a test\074/p\076");', |
| 180 | @generator.insert_html(:after, 'element', '<p>This is a test</p>') | 180 | @generator.insert_html(:after, 'element', '<p>This is a test</p>') |
| 181 | end | 181 | end |
| 182 | 182 | ||
| 183 | def test_replace_html_with_string | 183 | def test_replace_html_with_string |
| 184 | - assert_equal 'Element.update("element", "<p>This is a test</p>");', | 184 | + assert_equal 'Element.update("element", "\074p\076This is a test\074/p\076");', |
| 185 | @generator.replace_html('element', '<p>This is a test</p>') | 185 | @generator.replace_html('element', '<p>This is a test</p>') |
| 186 | end | 186 | end |
| 187 | 187 | ||
| 188 | def test_replace_element_with_string | 188 | def test_replace_element_with_string |
| 189 | - assert_equal 'Element.replace("element", "<div id=\"element\"><p>This is a test</p></div>");', | 189 | + assert_equal 'Element.replace("element", "\074div id=\"element\"\076\074p\076This is a test\074/p\076\074/div\076");', |
| 190 | @generator.replace('element', '<div id="element"><p>This is a test</p></div>') | 190 | @generator.replace('element', '<div id="element"><p>This is a test</p></div>') |
| 191 | end | 191 | end |
| 192 | 192 | ||
| @@ -241,12 +241,12 @@ class JavaScriptGeneratorTest < Test::Unit::TestCase | @@ -241,12 +241,12 @@ class JavaScriptGeneratorTest < Test::Unit::TestCase | ||
| 241 | @generator.remove('foo', 'bar') | 241 | @generator.remove('foo', 'bar') |
| 242 | @generator.replace_html('baz', '<p>This is a test</p>') | 242 | @generator.replace_html('baz', '<p>This is a test</p>') |
| 243 | 243 | ||
| 244 | - assert_equal <<-EOS.chomp, @generator.to_s | ||
| 245 | -new Insertion.Top("element", "<p>This is a test</p>"); | ||
| 246 | -new Insertion.Bottom("element", "<p>This is a test</p>"); | 244 | + expected = %q(new Insertion.Top("element", "\074p\076This is a test\074/p\076"); |
| 245 | +new Insertion.Bottom("element", "\074p\076This is a test\074/p\076"); | ||
| 247 | ["foo", "bar"].each(Element.remove); | 246 | ["foo", "bar"].each(Element.remove); |
| 248 | -Element.update("baz", "<p>This is a test</p>"); | ||
| 249 | - EOS | 247 | +Element.update("baz", "\074p\076This is a test\074/p\076");) |
| 248 | + | ||
| 249 | + assert_equal expected, @generator.to_s | ||
| 250 | end | 250 | end |
| 251 | 251 | ||
| 252 | def test_element_access | 252 | def test_element_access |
vendor/rails/actionwebservice/CHANGELOG
| 1 | +*1.2.6* (November 24th, 2007) | ||
| 2 | + | ||
| 3 | +* Depend on Action Pack 1.13.6 | ||
| 4 | + | ||
| 5 | +* Depend on Active Record 1.15.6 | ||
| 6 | + | ||
| 7 | + | ||
| 8 | +*1.2.5* (October 12th, 2007) | ||
| 9 | + | ||
| 10 | +* Depend on Action Pack 1.13.5 | ||
| 11 | + | ||
| 12 | +* Depend on Active Record 1.15.5 | ||
| 13 | + | ||
| 14 | + | ||
| 15 | +*1.2.4* (October 4th, 2007) | ||
| 16 | + | ||
| 17 | +* Depend on Action Pack 1.13.4 | ||
| 18 | + | ||
| 19 | +* Depend on Active Record 1.15.4 | ||
| 20 | + | ||
| 21 | + | ||
| 1 | *1.2.3* (March 12th, 2007) | 22 | *1.2.3* (March 12th, 2007) |
| 2 | 23 | ||
| 3 | * Depend on Action Pack 1.13.3 | 24 | * Depend on Action Pack 1.13.3 |
vendor/rails/actionwebservice/Rakefile
| @@ -71,8 +71,8 @@ spec = Gem::Specification.new do |s| | @@ -71,8 +71,8 @@ spec = Gem::Specification.new do |s| | ||
| 71 | s.rubyforge_project = "aws" | 71 | s.rubyforge_project = "aws" |
| 72 | s.homepage = "http://www.rubyonrails.org" | 72 | s.homepage = "http://www.rubyonrails.org" |
| 73 | 73 | ||
| 74 | - s.add_dependency('actionpack', '= 1.13.3' + PKG_BUILD) | ||
| 75 | - s.add_dependency('activerecord', '= 1.15.3' + PKG_BUILD) | 74 | + s.add_dependency('actionpack', '= 1.13.6' + PKG_BUILD) |
| 75 | + s.add_dependency('activerecord', '= 1.15.6' + PKG_BUILD) | ||
| 76 | 76 | ||
| 77 | s.has_rdoc = true | 77 | s.has_rdoc = true |
| 78 | s.requirements << 'none' | 78 | s.requirements << 'none' |
vendor/rails/actionwebservice/lib/action_web_service/version.rb
| @@ -2,7 +2,7 @@ module ActionWebService | @@ -2,7 +2,7 @@ module ActionWebService | ||
| 2 | module VERSION #:nodoc: | 2 | module VERSION #:nodoc: |
| 3 | MAJOR = 1 | 3 | MAJOR = 1 |
| 4 | MINOR = 2 | 4 | MINOR = 2 |
| 5 | - TINY = 3 | 5 | + TINY = 6 |
| 6 | 6 | ||
| 7 | STRING = [MAJOR, MINOR, TINY].join('.') | 7 | STRING = [MAJOR, MINOR, TINY].join('.') |
| 8 | end | 8 | end |
vendor/rails/activerecord/CHANGELOG
| 1 | +*1.15.6* (November 24th, 2007) | ||
| 2 | + | ||
| 3 | +* Allow association redefinition in subclasses. #9346 [wildchild] | ||
| 4 | + | ||
| 5 | +* Fix has_many :through delete with custom foreign keys. #6466 [naffis] | ||
| 6 | + | ||
| 7 | +* Fix regression where the association would not construct new finder SQL on save causing bogus queries for "WHERE owner_id = NULL" even after owner was saved. #8713 [Bryan Helmkamp] | ||
| 8 | + | ||
| 9 | + | ||
| 10 | +*1.15.5* (October 12th, 2007) | ||
| 11 | + | ||
| 12 | +* Depend on Action Pack 1.4.4 | ||
| 13 | + | ||
| 14 | + | ||
| 15 | +*1.15.4* (October 4th, 2007) | ||
| 16 | + | ||
| 17 | +* Fix #count on a has_many :through association so that it recognizes the :uniq option. Closes #8801 [lifofifo] | ||
| 18 | + | ||
| 19 | +* Don't clobber includes passed to has_many.count [danger] | ||
| 20 | + | ||
| 21 | +* Make sure has_many uses :include when counting [danger] | ||
| 22 | + | ||
| 23 | +* Save associated records only if the association is already loaded. #8713 [blaine] | ||
| 24 | + | ||
| 25 | +* Changing the :default Date format doesn't break date quoting. #6312 [bshand, Elias] | ||
| 26 | + | ||
| 27 | +* Allow nil serialized attributes with a set class constraint. #7293 [sandofsky] | ||
| 28 | + | ||
| 29 | +* belongs_to assignment creates a new proxy rather than modifying its target in-place. #8412 [mmangino@elevatedrails.com] | ||
| 30 | + | ||
| 31 | +* Fix column type detection while loading fixtures. Closes #7987 [roderickvd] | ||
| 32 | + | ||
| 33 | +* Document deep eager includes. #6267 [Josh Susser, Dan Manges] | ||
| 34 | + | ||
| 35 | +* Oracle: extract column length for CHAR also. #7866 [ymendel] | ||
| 36 | + | ||
| 37 | +* Small additions and fixes for ActiveRecord documentation. Closes #7342 [jeremymcanally] | ||
| 38 | + | ||
| 39 | +* SQLite: binary escaping works with $KCODE='u'. #7862 [tsuka] | ||
| 40 | + | ||
| 41 | +* Improved cloning performance by relying less on exception raising #8159 [Blaine] | ||
| 42 | + | ||
| 43 | + | ||
| 1 | *1.15.3* (March 12th, 2007) | 44 | *1.15.3* (March 12th, 2007) |
| 2 | 45 | ||
| 3 | * Allow a polymorphic :source for has_many :through associations. Closes #7143 [protocool] | 46 | * Allow a polymorphic :source for has_many :through associations. Closes #7143 [protocool] |
vendor/rails/activerecord/Rakefile
| @@ -151,7 +151,7 @@ spec = Gem::Specification.new do |s| | @@ -151,7 +151,7 @@ spec = Gem::Specification.new do |s| | ||
| 151 | s.files = s.files + Dir.glob( "#{dir}/**/*" ).delete_if { |item| item.include?( "\.svn" ) } | 151 | s.files = s.files + Dir.glob( "#{dir}/**/*" ).delete_if { |item| item.include?( "\.svn" ) } |
| 152 | end | 152 | end |
| 153 | 153 | ||
| 154 | - s.add_dependency('activesupport', '= 1.4.2' + PKG_BUILD) | 154 | + s.add_dependency('activesupport', '= 1.4.4' + PKG_BUILD) |
| 155 | 155 | ||
| 156 | s.files.delete "test/fixtures/fixture_database.sqlite" | 156 | s.files.delete "test/fixtures/fixture_database.sqlite" |
| 157 | s.files.delete "test/fixtures/fixture_database_2.sqlite" | 157 | s.files.delete "test/fixtures/fixture_database_2.sqlite" |
vendor/rails/activerecord/lib/active_record/acts/list.rb
| @@ -63,7 +63,7 @@ module ActiveRecord | @@ -63,7 +63,7 @@ module ActiveRecord | ||
| 63 | 63 | ||
| 64 | #{scope_condition_method} | 64 | #{scope_condition_method} |
| 65 | 65 | ||
| 66 | - after_destroy :remove_from_list | 66 | + before_destroy :remove_from_list |
| 67 | before_create :add_to_list_bottom | 67 | before_create :add_to_list_bottom |
| 68 | EOV | 68 | EOV |
| 69 | end | 69 | end |
| @@ -74,6 +74,7 @@ module ActiveRecord | @@ -74,6 +74,7 @@ module ActiveRecord | ||
| 74 | # lower in the list of all chapters. Likewise, <tt>chapter.first?</tt> would return true if that chapter is | 74 | # lower in the list of all chapters. Likewise, <tt>chapter.first?</tt> would return true if that chapter is |
| 75 | # the first in the list of all chapters. | 75 | # the first in the list of all chapters. |
| 76 | module InstanceMethods | 76 | module InstanceMethods |
| 77 | + # Insert the item at the given position (defaults to the top position of 1). | ||
| 77 | def insert_at(position = 1) | 78 | def insert_at(position = 1) |
| 78 | insert_at_position(position) | 79 | insert_at_position(position) |
| 79 | end | 80 | end |
| @@ -118,8 +119,12 @@ module ActiveRecord | @@ -118,8 +119,12 @@ module ActiveRecord | ||
| 118 | end | 119 | end |
| 119 | end | 120 | end |
| 120 | 121 | ||
| 122 | + # Removes the item from the list. | ||
| 121 | def remove_from_list | 123 | def remove_from_list |
| 122 | - decrement_positions_on_lower_items if in_list? | 124 | + if in_list? |
| 125 | + decrement_positions_on_lower_items | ||
| 126 | + update_attribute position_column, nil | ||
| 127 | + end | ||
| 123 | end | 128 | end |
| 124 | 129 | ||
| 125 | # Increase the position of this item without adjusting the rest of the list. | 130 | # Increase the position of this item without adjusting the rest of the list. |
| @@ -162,6 +167,7 @@ module ActiveRecord | @@ -162,6 +167,7 @@ module ActiveRecord | ||
| 162 | ) | 167 | ) |
| 163 | end | 168 | end |
| 164 | 169 | ||
| 170 | + # Test if this record is in a list | ||
| 165 | def in_list? | 171 | def in_list? |
| 166 | !send(position_column).nil? | 172 | !send(position_column).nil? |
| 167 | end | 173 | end |
| @@ -178,21 +184,26 @@ module ActiveRecord | @@ -178,21 +184,26 @@ module ActiveRecord | ||
| 178 | # Overwrite this method to define the scope of the list changes | 184 | # Overwrite this method to define the scope of the list changes |
| 179 | def scope_condition() "1" end | 185 | def scope_condition() "1" end |
| 180 | 186 | ||
| 187 | + # Returns the bottom position number in the list. | ||
| 188 | + # bottom_position_in_list # => 2 | ||
| 181 | def bottom_position_in_list(except = nil) | 189 | def bottom_position_in_list(except = nil) |
| 182 | item = bottom_item(except) | 190 | item = bottom_item(except) |
| 183 | item ? item.send(position_column) : 0 | 191 | item ? item.send(position_column) : 0 |
| 184 | end | 192 | end |
| 185 | 193 | ||
| 194 | + # Returns the bottom item | ||
| 186 | def bottom_item(except = nil) | 195 | def bottom_item(except = nil) |
| 187 | conditions = scope_condition | 196 | conditions = scope_condition |
| 188 | conditions = "#{conditions} AND #{self.class.primary_key} != #{except.id}" if except | 197 | conditions = "#{conditions} AND #{self.class.primary_key} != #{except.id}" if except |
| 189 | acts_as_list_class.find(:first, :conditions => conditions, :order => "#{position_column} DESC") | 198 | acts_as_list_class.find(:first, :conditions => conditions, :order => "#{position_column} DESC") |
| 190 | end | 199 | end |
| 191 | 200 | ||
| 201 | + # Forces item to assume the bottom position in the list. | ||
| 192 | def assume_bottom_position | 202 | def assume_bottom_position |
| 193 | update_attribute(position_column, bottom_position_in_list(self).to_i + 1) | 203 | update_attribute(position_column, bottom_position_in_list(self).to_i + 1) |
| 194 | end | 204 | end |
| 195 | 205 | ||
| 206 | + # Forces item to assume the top position in the list. | ||
| 196 | def assume_top_position | 207 | def assume_top_position |
| 197 | update_attribute(position_column, 1) | 208 | update_attribute(position_column, 1) |
| 198 | end | 209 | end |
| @@ -227,6 +238,7 @@ module ActiveRecord | @@ -227,6 +238,7 @@ module ActiveRecord | ||
| 227 | ) | 238 | ) |
| 228 | end | 239 | end |
| 229 | 240 | ||
| 241 | + # Increments position (<tt>position_column</tt>) of all items in the list. | ||
| 230 | def increment_positions_on_all_items | 242 | def increment_positions_on_all_items |
| 231 | acts_as_list_class.update_all( | 243 | acts_as_list_class.update_all( |
| 232 | "#{position_column} = (#{position_column} + 1)", "#{scope_condition}" | 244 | "#{position_column} = (#{position_column} + 1)", "#{scope_condition}" |
vendor/rails/activerecord/lib/active_record/acts/tree.rb
| @@ -70,16 +70,23 @@ module ActiveRecord | @@ -70,16 +70,23 @@ module ActiveRecord | ||
| 70 | nodes | 70 | nodes |
| 71 | end | 71 | end |
| 72 | 72 | ||
| 73 | + # Returns the root node of the tree. | ||
| 73 | def root | 74 | def root |
| 74 | node = self | 75 | node = self |
| 75 | node = node.parent while node.parent | 76 | node = node.parent while node.parent |
| 76 | node | 77 | node |
| 77 | end | 78 | end |
| 78 | 79 | ||
| 80 | + # Returns all siblings of the current node. | ||
| 81 | + # | ||
| 82 | + # subchild1.siblings # => [subchild2] | ||
| 79 | def siblings | 83 | def siblings |
| 80 | self_and_siblings - [self] | 84 | self_and_siblings - [self] |
| 81 | end | 85 | end |
| 82 | 86 | ||
| 87 | + # Returns all siblings and a reference to the current node. | ||
| 88 | + # | ||
| 89 | + # subchild1.self_and_siblings # => [subchild1, subchild2] | ||
| 83 | def self_and_siblings | 90 | def self_and_siblings |
| 84 | parent ? parent.children : self.class.roots | 91 | parent ? parent.children : self.class.roots |
| 85 | end | 92 | end |
vendor/rails/activerecord/lib/active_record/associations.rb
| @@ -50,6 +50,12 @@ module ActiveRecord | @@ -50,6 +50,12 @@ module ActiveRecord | ||
| 50 | end | 50 | end |
| 51 | end | 51 | end |
| 52 | 52 | ||
| 53 | + class HasManyThroughCantDissociateNewRecords < ActiveRecordError #:nodoc: | ||
| 54 | + def initialize(owner, reflection) | ||
| 55 | + super("Cannot dissociate new records through '#{owner.class.name}##{reflection.name}' on '#{reflection.source_reflection.class_name rescue nil}##{reflection.source_reflection.name rescue nil}'. Both records must have an id in order to delete the has_many :through record associating them.") | ||
| 56 | + end | ||
| 57 | + end | ||
| 58 | + | ||
| 53 | class EagerLoadPolymorphicError < ActiveRecordError #:nodoc: | 59 | class EagerLoadPolymorphicError < ActiveRecordError #:nodoc: |
| 54 | def initialize(reflection) | 60 | def initialize(reflection) |
| 55 | super("Can not eagerly load the polymorphic association #{reflection.name.inspect}") | 61 | super("Can not eagerly load the polymorphic association #{reflection.name.inspect}") |
| @@ -352,7 +358,15 @@ module ActiveRecord | @@ -352,7 +358,15 @@ module ActiveRecord | ||
| 352 | # for post in Post.find(:all, :include => [ :author, :comments ]) | 358 | # for post in Post.find(:all, :include => [ :author, :comments ]) |
| 353 | # | 359 | # |
| 354 | # That'll add another join along the lines of: LEFT OUTER JOIN comments ON comments.post_id = posts.id. And we'll be down to 1 query. | 360 | # That'll add another join along the lines of: LEFT OUTER JOIN comments ON comments.post_id = posts.id. And we'll be down to 1 query. |
| 355 | - # But that shouldn't fool you to think that you can pull out huge amounts of data with no performance penalty just because you've reduced | 361 | + # |
| 362 | + # To include a deep hierarchy of associations, using a hash: | ||
| 363 | + # | ||
| 364 | + # for post in Post.find(:all, :include => [ :author, { :comments => { :author => :gravatar } } ]) | ||
| 365 | + # | ||
| 366 | + # That'll grab not only all the comments but all their authors and gravatar pictures. You can mix and match | ||
| 367 | + # symbols, arrays and hashes in any combination to describe the associations you want to load. | ||
| 368 | + # | ||
| 369 | + # All of this power shouldn't fool you into thinking that you can pull out huge amounts of data with no performance penalty just because you've reduced | ||
| 356 | # the number of queries. The database still needs to send all the data to Active Record and it still needs to be processed. So it's no | 370 | # the number of queries. The database still needs to send all the data to Active Record and it still needs to be processed. So it's no |
| 357 | # catch-all for performance problems, but it's a great way to cut down on the number of queries in a situation as the one described above. | 371 | # catch-all for performance problems, but it's a great way to cut down on the number of queries in a situation as the one described above. |
| 358 | # | 372 | # |
| @@ -734,6 +748,7 @@ module ActiveRecord | @@ -734,6 +748,7 @@ module ActiveRecord | ||
| 734 | deprecated_association_comparison_method(reflection.name, reflection.class_name) | 748 | deprecated_association_comparison_method(reflection.name, reflection.class_name) |
| 735 | end | 749 | end |
| 736 | 750 | ||
| 751 | + # Create the callbacks to update counter cache | ||
| 737 | if options[:counter_cache] | 752 | if options[:counter_cache] |
| 738 | cache_column = options[:counter_cache] == true ? | 753 | cache_column = options[:counter_cache] == true ? |
| 739 | "#{self.to_s.underscore.pluralize}_count" : | 754 | "#{self.to_s.underscore.pluralize}_count" : |
| @@ -853,7 +868,7 @@ module ActiveRecord | @@ -853,7 +868,7 @@ module ActiveRecord | ||
| 853 | # Don't use a before_destroy callback since users' before_destroy | 868 | # Don't use a before_destroy callback since users' before_destroy |
| 854 | # callbacks will be executed after the association is wiped out. | 869 | # callbacks will be executed after the association is wiped out. |
| 855 | old_method = "destroy_without_habtm_shim_for_#{reflection.name}" | 870 | old_method = "destroy_without_habtm_shim_for_#{reflection.name}" |
| 856 | - class_eval <<-end_eval | 871 | + class_eval <<-end_eval unless method_defined?(old_method) |
| 857 | alias_method :#{old_method}, :destroy_without_callbacks | 872 | alias_method :#{old_method}, :destroy_without_callbacks |
| 858 | def destroy_without_callbacks | 873 | def destroy_without_callbacks |
| 859 | #{reflection.name}.clear | 874 | #{reflection.name}.clear |
| @@ -871,6 +886,12 @@ module ActiveRecord | @@ -871,6 +886,12 @@ module ActiveRecord | ||
| 871 | end | 886 | end |
| 872 | 887 | ||
| 873 | private | 888 | private |
| 889 | + # Generate a join table name from two provided tables names. | ||
| 890 | + # The order of names in join name is determined by lexical precedence. | ||
| 891 | + # join_table_name("members", "clubs") | ||
| 892 | + # => "clubs_members" | ||
| 893 | + # join_table_name("members", "special_clubs") | ||
| 894 | + # => "members_special_clubs" | ||
| 874 | def join_table_name(first_table_name, second_table_name) | 895 | def join_table_name(first_table_name, second_table_name) |
| 875 | if first_table_name < second_table_name | 896 | if first_table_name < second_table_name |
| 876 | join_table = "#{first_table_name}_#{second_table_name}" | 897 | join_table = "#{first_table_name}_#{second_table_name}" |
| @@ -880,7 +901,7 @@ module ActiveRecord | @@ -880,7 +901,7 @@ module ActiveRecord | ||
| 880 | 901 | ||
| 881 | table_name_prefix + join_table + table_name_suffix | 902 | table_name_prefix + join_table + table_name_suffix |
| 882 | end | 903 | end |
| 883 | - | 904 | + |
| 884 | def association_accessor_methods(reflection, association_proxy_class) | 905 | def association_accessor_methods(reflection, association_proxy_class) |
| 885 | define_method(reflection.name) do |*params| | 906 | define_method(reflection.name) do |*params| |
| 886 | force_reload = params.first unless params.empty? | 907 | force_reload = params.first unless params.empty? |
| @@ -901,7 +922,7 @@ module ActiveRecord | @@ -901,7 +922,7 @@ module ActiveRecord | ||
| 901 | 922 | ||
| 902 | define_method("#{reflection.name}=") do |new_value| | 923 | define_method("#{reflection.name}=") do |new_value| |
| 903 | association = instance_variable_get("@#{reflection.name}") | 924 | association = instance_variable_get("@#{reflection.name}") |
| 904 | - if association.nil? | 925 | + if association.nil? || association.target != new_value |
| 905 | association = association_proxy_class.new(self, reflection) | 926 | association = association_proxy_class.new(self, reflection) |
| 906 | end | 927 | end |
| 907 | 928 | ||
| @@ -911,10 +932,7 @@ module ActiveRecord | @@ -911,10 +932,7 @@ module ActiveRecord | ||
| 911 | instance_variable_set("@#{reflection.name}", association) | 932 | instance_variable_set("@#{reflection.name}", association) |
| 912 | else | 933 | else |
| 913 | instance_variable_set("@#{reflection.name}", nil) | 934 | instance_variable_set("@#{reflection.name}", nil) |
| 914 | - return nil | ||
| 915 | end | 935 | end |
| 916 | - | ||
| 917 | - association | ||
| 918 | end | 936 | end |
| 919 | 937 | ||
| 920 | define_method("set_#{reflection.name}_target") do |target| | 938 | define_method("set_#{reflection.name}_target") do |target| |
| @@ -981,18 +999,21 @@ module ActiveRecord | @@ -981,18 +999,21 @@ module ActiveRecord | ||
| 981 | 999 | ||
| 982 | after_callback = <<-end_eval | 1000 | after_callback = <<-end_eval |
| 983 | association = instance_variable_get("@#{association_name}") | 1001 | association = instance_variable_get("@#{association_name}") |
| 984 | - | ||
| 985 | - if association.respond_to?(:loaded?) | ||
| 986 | - if @new_record_before_save | ||
| 987 | - records_to_save = association | ||
| 988 | - else | ||
| 989 | - records_to_save = association.select { |record| record.new_record? } | ||
| 990 | - end | ||
| 991 | - records_to_save.each { |record| association.send(:insert_record, record) } | ||
| 992 | - association.send(:construct_sql) # reconstruct the SQL queries now that we know the owner's id | 1002 | + |
| 1003 | + records_to_save = if @new_record_before_save | ||
| 1004 | + association | ||
| 1005 | + elsif association.respond_to?(:loaded?) && association.loaded? | ||
| 1006 | + association.select { |record| record.new_record? } | ||
| 1007 | + else | ||
| 1008 | + [] | ||
| 993 | end | 1009 | end |
| 1010 | + | ||
| 1011 | + records_to_save.each { |record| association.send(:insert_record, record) } unless records_to_save.blank? | ||
| 1012 | + | ||
| 1013 | + # reconstruct the SQL queries now that we know the owner's id | ||
| 1014 | + association.send(:construct_sql) if association.respond_to?(:construct_sql) | ||
| 994 | end_eval | 1015 | end_eval |
| 995 | - | 1016 | + |
| 996 | # Doesn't use after_save as that would save associations added in after_create/after_update twice | 1017 | # Doesn't use after_save as that would save associations added in after_create/after_update twice |
| 997 | after_create(after_callback) | 1018 | after_create(after_callback) |
| 998 | after_update(after_callback) | 1019 | after_update(after_callback) |
| @@ -1271,7 +1292,9 @@ module ActiveRecord | @@ -1271,7 +1292,9 @@ module ActiveRecord | ||
| 1271 | defined_callbacks = options[callback_name.to_sym] | 1292 | defined_callbacks = options[callback_name.to_sym] |
| 1272 | if options.has_key?(callback_name.to_sym) | 1293 | if options.has_key?(callback_name.to_sym) |
| 1273 | class_inheritable_reader full_callback_name.to_sym | 1294 | class_inheritable_reader full_callback_name.to_sym |
| 1274 | - write_inheritable_array(full_callback_name.to_sym, [defined_callbacks].flatten) | 1295 | + write_inheritable_attribute(full_callback_name.to_sym, [defined_callbacks].flatten) |
| 1296 | + else | ||
| 1297 | + write_inheritable_attribute(full_callback_name.to_sym, []) | ||
| 1275 | end | 1298 | end |
| 1276 | end | 1299 | end |
| 1277 | end | 1300 | end |
vendor/rails/activerecord/lib/active_record/associations/association_collection.rb
| @@ -91,7 +91,11 @@ module ActiveRecord | @@ -91,7 +91,11 @@ module ActiveRecord | ||
| 91 | attributes.collect { |attr| create(attr) } | 91 | attributes.collect { |attr| create(attr) } |
| 92 | else | 92 | else |
| 93 | record = build(attributes) | 93 | record = build(attributes) |
| 94 | - record.save unless @owner.new_record? | 94 | + if @owner.new_record? |
| 95 | + ActiveSupport::Deprecation.warn("Calling .create on a has_many association without saving its owner will not work in rails 2.0, you probably want .build instead") | ||
| 96 | + else | ||
| 97 | + record.save | ||
| 98 | + end | ||
| 95 | record | 99 | record |
| 96 | end | 100 | end |
| 97 | end | 101 | end |
vendor/rails/activerecord/lib/active_record/associations/has_many_association.rb
| @@ -50,7 +50,7 @@ module ActiveRecord | @@ -50,7 +50,7 @@ module ActiveRecord | ||
| 50 | options[:conditions] = options[:conditions].nil? ? | 50 | options[:conditions] = options[:conditions].nil? ? |
| 51 | @finder_sql : | 51 | @finder_sql : |
| 52 | @finder_sql + " AND (#{sanitize_sql(options[:conditions])})" | 52 | @finder_sql + " AND (#{sanitize_sql(options[:conditions])})" |
| 53 | - options[:include] = @reflection.options[:include] | 53 | + options[:include] ||= @reflection.options[:include] |
| 54 | 54 | ||
| 55 | @reflection.klass.count(column_name, options) | 55 | @reflection.klass.count(column_name, options) |
| 56 | end | 56 | end |
| @@ -138,7 +138,7 @@ module ActiveRecord | @@ -138,7 +138,7 @@ module ActiveRecord | ||
| 138 | elsif @reflection.options[:counter_sql] | 138 | elsif @reflection.options[:counter_sql] |
| 139 | @reflection.klass.count_by_sql(@counter_sql) | 139 | @reflection.klass.count_by_sql(@counter_sql) |
| 140 | else | 140 | else |
| 141 | - @reflection.klass.count(:conditions => @counter_sql) | 141 | + @reflection.klass.count(:conditions => @counter_sql, :include => @reflection.options[:include]) |
| 142 | end | 142 | end |
| 143 | 143 | ||
| 144 | @target = [] and loaded if count == 0 | 144 | @target = [] and loaded if count == 0 |
vendor/rails/activerecord/lib/active_record/associations/has_many_through_association.rb
| @@ -71,20 +71,26 @@ module ActiveRecord | @@ -71,20 +71,26 @@ module ActiveRecord | ||
| 71 | 71 | ||
| 72 | # Remove +records+ from this association. Does not destroy +records+. | 72 | # Remove +records+ from this association. Does not destroy +records+. |
| 73 | def delete(*records) | 73 | def delete(*records) |
| 74 | - records = flatten_deeper(records) | ||
| 75 | - records.each { |associate| raise_on_type_mismatch(associate) } | ||
| 76 | - records.reject! { |associate| @target.delete(associate) if associate.new_record? } | ||
| 77 | return if records.empty? | 74 | return if records.empty? |
| 78 | - | ||
| 79 | - @delete_join_finder ||= "find_all_by_#{@reflection.source_reflection.association_foreign_key}" | 75 | + records.each { |associate| raise_on_type_mismatch(associate) } |
| 76 | + | ||
| 80 | through = @reflection.through_reflection | 77 | through = @reflection.through_reflection |
| 81 | - through.klass.transaction do | ||
| 82 | - records.each do |associate| | ||
| 83 | - joins = @owner.send(through.name).send(@delete_join_finder, associate.id) | ||
| 84 | - @owner.send(through.name).delete(joins) | 78 | + raise ActiveRecord::HasManyThroughCantDissociateNewRecords.new(@owner, through) if @owner.new_record? |
| 79 | + | ||
| 80 | + load_target | ||
| 81 | + | ||
| 82 | + klass = through.klass | ||
| 83 | + klass.transaction do | ||
| 84 | + flatten_deeper(records).each do |associate| | ||
| 85 | + raise_on_type_mismatch(associate) | ||
| 86 | + raise ActiveRecord::HasManyThroughCantDissociateNewRecords.new(@owner, through) unless associate.respond_to?(:new_record?) && !associate.new_record? | ||
| 87 | + | ||
| 88 | + @owner.send(@reflection.through_reflection.name).proxy_target.delete(klass.delete_all(construct_join_attributes(associate))) | ||
| 85 | @target.delete(associate) | 89 | @target.delete(associate) |
| 86 | end | 90 | end |
| 87 | end | 91 | end |
| 92 | + | ||
| 93 | + self | ||
| 88 | end | 94 | end |
| 89 | 95 | ||
| 90 | def build(attrs = nil) | 96 | def build(attrs = nil) |
| @@ -101,6 +107,16 @@ module ActiveRecord | @@ -101,6 +107,16 @@ module ActiveRecord | ||
| 101 | def sum(*args, &block) | 107 | def sum(*args, &block) |
| 102 | calculate(:sum, *args, &block) | 108 | calculate(:sum, *args, &block) |
| 103 | end | 109 | end |
| 110 | + | ||
| 111 | + def count(*args) | ||
| 112 | + column_name, options = @reflection.klass.send(:construct_count_options_from_legacy_args, *args) | ||
| 113 | + if @reflection.options[:uniq] | ||
| 114 | + # This is needed becase 'SELECT count(DISTINCT *)..' is not valid sql statement. | ||
| 115 | + column_name = "#{@reflection.klass.table_name}.#{@reflection.klass.primary_key}" if column_name == :all | ||
| 116 | + options.merge!(:distinct => true) | ||
| 117 | + end | ||
| 118 | + @reflection.klass.send(:with_scope, construct_scope) { @reflection.klass.count(column_name, options) } | ||
| 119 | + end | ||
| 104 | 120 | ||
| 105 | protected | 121 | protected |
| 106 | def method_missing(method, *args, &block) | 122 | def method_missing(method, *args, &block) |
vendor/rails/activerecord/lib/active_record/base.rb
| @@ -575,7 +575,7 @@ module ActiveRecord #:nodoc: | @@ -575,7 +575,7 @@ module ActiveRecord #:nodoc: | ||
| 575 | 575 | ||
| 576 | # Specifies that the attribute by the name of +attr_name+ should be serialized before saving to the database and unserialized | 576 | # Specifies that the attribute by the name of +attr_name+ should be serialized before saving to the database and unserialized |
| 577 | # after loading from the database. The serialization is done through YAML. If +class_name+ is specified, the serialized | 577 | # after loading from the database. The serialization is done through YAML. If +class_name+ is specified, the serialized |
| 578 | - # object must be of that class on retrieval or +SerializationTypeMismatch+ will be raised. | 578 | + # object must be of that class on retrieval, or nil. Otherwise, +SerializationTypeMismatch+ will be raised. |
| 579 | def serialize(attr_name, class_name = Object) | 579 | def serialize(attr_name, class_name = Object) |
| 580 | serialized_attributes[attr_name.to_s] = class_name | 580 | serialized_attributes[attr_name.to_s] = class_name |
| 581 | end | 581 | end |
| @@ -1188,6 +1188,9 @@ module ActiveRecord #:nodoc: | @@ -1188,6 +1188,9 @@ module ActiveRecord #:nodoc: | ||
| 1188 | # | 1188 | # |
| 1189 | # It's even possible to use all the additional parameters to find. For example, the full interface for find_all_by_amount | 1189 | # It's even possible to use all the additional parameters to find. For example, the full interface for find_all_by_amount |
| 1190 | # is actually find_all_by_amount(amount, options). | 1190 | # is actually find_all_by_amount(amount, options). |
| 1191 | + # | ||
| 1192 | + # This also enables you to initialize a record if it is not found, such as find_or_initialize_by_amount(amount) | ||
| 1193 | + # or find_or_create_by_user_and_password(user, password). | ||
| 1191 | def method_missing(method_id, *arguments) | 1194 | def method_missing(method_id, *arguments) |
| 1192 | if match = /^find_(all_by|by)_([_a-zA-Z]\w*)$/.match(method_id.to_s) | 1195 | if match = /^find_(all_by|by)_([_a-zA-Z]\w*)$/.match(method_id.to_s) |
| 1193 | finder, deprecated_finder = determine_finder(match), determine_deprecated_finder(match) | 1196 | finder, deprecated_finder = determine_finder(match), determine_deprecated_finder(match) |
| @@ -1957,7 +1960,7 @@ module ActiveRecord #:nodoc: | @@ -1957,7 +1960,7 @@ module ActiveRecord #:nodoc: | ||
| 1957 | def unserialize_attribute(attr_name) | 1960 | def unserialize_attribute(attr_name) |
| 1958 | unserialized_object = object_from_yaml(@attributes[attr_name]) | 1961 | unserialized_object = object_from_yaml(@attributes[attr_name]) |
| 1959 | 1962 | ||
| 1960 | - if unserialized_object.is_a?(self.class.serialized_attributes[attr_name]) | 1963 | + if unserialized_object.is_a?(self.class.serialized_attributes[attr_name]) || unserialized_object.nil? |
| 1961 | @attributes[attr_name] = unserialized_object | 1964 | @attributes[attr_name] = unserialized_object |
| 1962 | else | 1965 | else |
| 1963 | raise SerializationTypeMismatch, | 1966 | raise SerializationTypeMismatch, |
| @@ -2156,7 +2159,13 @@ module ActiveRecord #:nodoc: | @@ -2156,7 +2159,13 @@ module ActiveRecord #:nodoc: | ||
| 2156 | 2159 | ||
| 2157 | def clone_attribute_value(reader_method, attribute_name) | 2160 | def clone_attribute_value(reader_method, attribute_name) |
| 2158 | value = send(reader_method, attribute_name) | 2161 | value = send(reader_method, attribute_name) |
| 2159 | - value.clone | 2162 | + |
| 2163 | + case value | ||
| 2164 | + when nil, Fixnum, true, false | ||
| 2165 | + value | ||
| 2166 | + else | ||
| 2167 | + value.clone | ||
| 2168 | + end | ||
| 2160 | rescue TypeError, NoMethodError | 2169 | rescue TypeError, NoMethodError |
| 2161 | value | 2170 | value |
| 2162 | end | 2171 | end |
vendor/rails/activerecord/lib/active_record/calculations.rb
| @@ -242,8 +242,8 @@ module ActiveRecord | @@ -242,8 +242,8 @@ module ActiveRecord | ||
| 242 | options.assert_valid_keys(CALCULATIONS_OPTIONS) | 242 | options.assert_valid_keys(CALCULATIONS_OPTIONS) |
| 243 | end | 243 | end |
| 244 | 244 | ||
| 245 | - # converts a given key to the value that the database adapter returns as | ||
| 246 | - # | 245 | + # Converts a given key to the value that the database adapter returns as |
| 246 | + # as a usable column name. | ||
| 247 | # users.id #=> users_id | 247 | # users.id #=> users_id |
| 248 | # sum(id) #=> sum_id | 248 | # sum(id) #=> sum_id |
| 249 | # count(distinct users.id) #=> count_distinct_users_id | 249 | # count(distinct users.id) #=> count_distinct_users_id |
vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
| @@ -24,7 +24,7 @@ module ActiveRecord | @@ -24,7 +24,7 @@ module ActiveRecord | ||
| 24 | when Float, Fixnum, Bignum then value.to_s | 24 | when Float, Fixnum, Bignum then value.to_s |
| 25 | # BigDecimals need to be output in a non-normalized form and quoted. | 25 | # BigDecimals need to be output in a non-normalized form and quoted. |
| 26 | when BigDecimal then value.to_s('F') | 26 | when BigDecimal then value.to_s('F') |
| 27 | - when Date then "'#{value.to_s}'" | 27 | + when Date then "'#{value.to_s(:db)}'" |
| 28 | when Time, DateTime then "'#{quoted_date(value)}'" | 28 | when Time, DateTime then "'#{quoted_date(value)}'" |
| 29 | else "'#{quote_string(value.to_yaml)}'" | 29 | else "'#{quote_string(value.to_yaml)}'" |
| 30 | end | 30 | end |
vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
| @@ -119,7 +119,7 @@ module ActiveRecord | @@ -119,7 +119,7 @@ module ActiveRecord | ||
| 119 | # | 119 | # |
| 120 | # * <tt>:host</tt> -- Defaults to localhost | 120 | # * <tt>:host</tt> -- Defaults to localhost |
| 121 | # * <tt>:port</tt> -- Defaults to 3306 | 121 | # * <tt>:port</tt> -- Defaults to 3306 |
| 122 | - # * <tt>:socket</tt> -- Defaults to /tmp/mysql.sock | 122 | + # * <tt>:socket</tt> -- Defaults to /var/run/mysqld/mysqld.sock |
| 123 | # * <tt>:username</tt> -- Defaults to root | 123 | # * <tt>:username</tt> -- Defaults to root |
| 124 | # * <tt>:password</tt> -- Defaults to nothing | 124 | # * <tt>:password</tt> -- Defaults to nothing |
| 125 | # * <tt>:database</tt> -- The name of the database. No default, must be provided. | 125 | # * <tt>:database</tt> -- The name of the database. No default, must be provided. |
vendor/rails/activerecord/lib/active_record/connection_adapters/oracle_adapter.rb
| @@ -320,6 +320,7 @@ begin | @@ -320,6 +320,7 @@ begin | ||
| 320 | decode(data_type, 'NUMBER', data_precision, | 320 | decode(data_type, 'NUMBER', data_precision, |
| 321 | 'FLOAT', data_precision, | 321 | 'FLOAT', data_precision, |
| 322 | 'VARCHAR2', data_length, | 322 | 'VARCHAR2', data_length, |
| 323 | + 'CHAR', data_length, | ||
| 323 | null) as limit, | 324 | null) as limit, |
| 324 | decode(data_type, 'NUMBER', data_scale, null) as scale | 325 | decode(data_type, 'NUMBER', data_scale, null) as scale |
| 325 | from all_tab_columns | 326 | from all_tab_columns |
vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
| @@ -68,7 +68,7 @@ module ActiveRecord | @@ -68,7 +68,7 @@ module ActiveRecord | ||
| 68 | class SQLiteColumn < Column #:nodoc: | 68 | class SQLiteColumn < Column #:nodoc: |
| 69 | class << self | 69 | class << self |
| 70 | def string_to_binary(value) | 70 | def string_to_binary(value) |
| 71 | - value.gsub(/\0|\%/) do |b| | 71 | + value.gsub(/\0|\%/n) do |b| |
| 72 | case b | 72 | case b |
| 73 | when "\0" then "%00" | 73 | when "\0" then "%00" |
| 74 | when "%" then "%25" | 74 | when "%" then "%25" |
| @@ -77,7 +77,7 @@ module ActiveRecord | @@ -77,7 +77,7 @@ module ActiveRecord | ||
| 77 | end | 77 | end |
| 78 | 78 | ||
| 79 | def binary_to_string(value) | 79 | def binary_to_string(value) |
| 80 | - value.gsub(/%00|%25/) do |b| | 80 | + value.gsub(/%00|%25/n) do |b| |
| 81 | case b | 81 | case b |
| 82 | when "%00" then "\0" | 82 | when "%00" then "\0" |
| 83 | when "%25" then "%" | 83 | when "%25" then "%" |
vendor/rails/activerecord/lib/active_record/deprecated_finders.rb
| 1 | module ActiveRecord | 1 | module ActiveRecord |
| 2 | class Base | 2 | class Base |
| 3 | class << self | 3 | class << self |
| 4 | - # This method is deprecated in favor of find with the :conditions option. | 4 | + # DEPRECATION NOTICE: This method is deprecated in favor of find with the :conditions option. |
| 5 | # | 5 | # |
| 6 | # Works like find, but the record matching +id+ must also meet the +conditions+. | 6 | # Works like find, but the record matching +id+ must also meet the +conditions+. |
| 7 | # +RecordNotFound+ is raised if no record can be found matching the +id+ or meeting the condition. | 7 | # +RecordNotFound+ is raised if no record can be found matching the +id+ or meeting the condition. |
| @@ -12,7 +12,7 @@ module ActiveRecord | @@ -12,7 +12,7 @@ module ActiveRecord | ||
| 12 | end | 12 | end |
| 13 | deprecate :find_on_conditions => "use find(ids, :conditions => conditions)" | 13 | deprecate :find_on_conditions => "use find(ids, :conditions => conditions)" |
| 14 | 14 | ||
| 15 | - # This method is deprecated in favor of find(:first, options). | 15 | + # DEPRECATION NOTICE: This method is deprecated in favor of find(:first, options). |
| 16 | # | 16 | # |
| 17 | # Returns the object for the first record responding to the conditions in +conditions+, | 17 | # Returns the object for the first record responding to the conditions in +conditions+, |
| 18 | # such as "group = 'master'". If more than one record is returned from the query, it's the first that'll | 18 | # such as "group = 'master'". If more than one record is returned from the query, it's the first that'll |
| @@ -24,7 +24,7 @@ module ActiveRecord | @@ -24,7 +24,7 @@ module ActiveRecord | ||
| 24 | end | 24 | end |
| 25 | deprecate :find_first => "use find(:first, ...)" | 25 | deprecate :find_first => "use find(:first, ...)" |
| 26 | 26 | ||
| 27 | - # This method is deprecated in favor of find(:all, options). | 27 | + # DEPRECATION NOTICE: This method is deprecated in favor of find(:all, options). |
| 28 | # | 28 | # |
| 29 | # Returns an array of all the objects that could be instantiated from the associated | 29 | # Returns an array of all the objects that could be instantiated from the associated |
| 30 | # table in the database. The +conditions+ can be used to narrow the selection of objects (WHERE-part), | 30 | # table in the database. The +conditions+ can be used to narrow the selection of objects (WHERE-part), |
vendor/rails/activerecord/lib/active_record/fixtures.rb
| @@ -412,7 +412,7 @@ class Fixture #:nodoc: | @@ -412,7 +412,7 @@ class Fixture #:nodoc: | ||
| 412 | klass = @class_name.constantize rescue nil | 412 | klass = @class_name.constantize rescue nil |
| 413 | 413 | ||
| 414 | list = @fixture.inject([]) do |fixtures, (key, value)| | 414 | list = @fixture.inject([]) do |fixtures, (key, value)| |
| 415 | - col = klass.columns_hash[key] if klass.kind_of?(ActiveRecord::Base) | 415 | + col = klass.columns_hash[key] if klass.respond_to?(:ancestors) && klass.ancestors.include?(ActiveRecord::Base) |
| 416 | fixtures << ActiveRecord::Base.connection.quote(value, col).gsub('[^\]\\n', "\n").gsub('[^\]\\r', "\r") | 416 | fixtures << ActiveRecord::Base.connection.quote(value, col).gsub('[^\]\\n', "\n").gsub('[^\]\\r', "\r") |
| 417 | end | 417 | end |
| 418 | list * ', ' | 418 | list * ', ' |
vendor/rails/activerecord/lib/active_record/timestamp.rb
| @@ -5,15 +5,6 @@ module ActiveRecord | @@ -5,15 +5,6 @@ module ActiveRecord | ||
| 5 | # Timestamping can be turned off by setting | 5 | # Timestamping can be turned off by setting |
| 6 | # <tt>ActiveRecord::Base.record_timestamps = false</tt> | 6 | # <tt>ActiveRecord::Base.record_timestamps = false</tt> |
| 7 | # | 7 | # |
| 8 | - # Keep in mind that, via inheritance, you can turn off timestamps on a per | ||
| 9 | - # model basis by setting <tt>record_timestamps</tt> to false in the desired | ||
| 10 | - # models. | ||
| 11 | - # | ||
| 12 | - # class Feed < ActiveRecord::Base | ||
| 13 | - # self.record_timestamps = false | ||
| 14 | - # # ... | ||
| 15 | - # end | ||
| 16 | - # | ||
| 17 | # Timestamps are in the local timezone by default but can use UTC by setting | 8 | # Timestamps are in the local timezone by default but can use UTC by setting |
| 18 | # <tt>ActiveRecord::Base.default_timezone = :utc</tt> | 9 | # <tt>ActiveRecord::Base.default_timezone = :utc</tt> |
| 19 | module Timestamp | 10 | module Timestamp |
vendor/rails/activerecord/lib/active_record/vendor/mysql.rb
| @@ -14,7 +14,7 @@ class Mysql | @@ -14,7 +14,7 @@ class Mysql | ||
| 14 | MAX_PACKET_LENGTH = 256*256*256-1 | 14 | MAX_PACKET_LENGTH = 256*256*256-1 |
| 15 | MAX_ALLOWED_PACKET = 1024*1024*1024 | 15 | MAX_ALLOWED_PACKET = 1024*1024*1024 |
| 16 | 16 | ||
| 17 | - MYSQL_UNIX_ADDR = "/tmp/mysql.sock" | 17 | + MYSQL_UNIX_ADDR = "/var/run/mysqld/mysqld.sock" |
| 18 | MYSQL_PORT = 3306 | 18 | MYSQL_PORT = 3306 |
| 19 | PROTOCOL_VERSION = 10 | 19 | PROTOCOL_VERSION = 10 |
| 20 | 20 |
vendor/rails/activerecord/lib/active_record/version.rb
vendor/rails/activerecord/test/aggregations_test.rb
| @@ -93,3 +93,21 @@ class AggregationsTest < Test::Unit::TestCase | @@ -93,3 +93,21 @@ class AggregationsTest < Test::Unit::TestCase | ||
| 93 | assert_raises(NoMethodError) { customers(:david).balance = nil } | 93 | assert_raises(NoMethodError) { customers(:david).balance = nil } |
| 94 | end | 94 | end |
| 95 | end | 95 | end |
| 96 | + | ||
| 97 | +class OverridingAggregationsTest < Test::Unit::TestCase | ||
| 98 | + class Name; end | ||
| 99 | + class DifferentName; end | ||
| 100 | + | ||
| 101 | + class Person < ActiveRecord::Base | ||
| 102 | + composed_of :composed_of, :mapping => %w(person_first_name first_name) | ||
| 103 | + end | ||
| 104 | + | ||
| 105 | + class DifferentPerson < Person | ||
| 106 | + composed_of :composed_of, :class_name => 'DifferentName', :mapping => %w(different_person_first_name first_name) | ||
| 107 | + end | ||
| 108 | + | ||
| 109 | + def test_composed_of_aggregation_redefinition_reflections_should_differ_and_not_inherited | ||
| 110 | + assert_not_equal Person.reflect_on_aggregation(:composed_of), | ||
| 111 | + DifferentPerson.reflect_on_aggregation(:composed_of) | ||
| 112 | + end | ||
| 113 | +end |
vendor/rails/activerecord/test/associations/eager_test.rb
| @@ -168,6 +168,12 @@ class EagerAssociationTest < Test::Unit::TestCase | @@ -168,6 +168,12 @@ class EagerAssociationTest < Test::Unit::TestCase | ||
| 168 | posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => "posts.title = 'magic forest'") | 168 | posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => "posts.title = 'magic forest'") |
| 169 | assert_equal 0, posts.size | 169 | assert_equal 0, posts.size |
| 170 | end | 170 | end |
| 171 | + | ||
| 172 | + def test_eager_count_performed_on_a_has_many_association_with_multi_table_conditional | ||
| 173 | + author = authors(:david) | ||
| 174 | + author_posts_without_comments = author.posts.select { |post| post.comments.blank? } | ||
| 175 | + assert_equal author_posts_without_comments.size, author.posts.count(:all, :include => :comments, :conditions => 'comments.id is null') | ||
| 176 | + end | ||
| 171 | 177 | ||
| 172 | def test_eager_with_has_and_belongs_to_many_and_limit | 178 | def test_eager_with_has_and_belongs_to_many_and_limit |
| 173 | posts = Post.find(:all, :include => :categories, :order => "posts.id", :limit => 3) | 179 | posts = Post.find(:all, :include => :categories, :order => "posts.id", :limit => 3) |
| @@ -271,6 +277,13 @@ class EagerAssociationTest < Test::Unit::TestCase | @@ -271,6 +277,13 @@ class EagerAssociationTest < Test::Unit::TestCase | ||
| 271 | assert_not_nil f.account | 277 | assert_not_nil f.account |
| 272 | assert_equal companies(:first_firm, :reload).account, f.account | 278 | assert_equal companies(:first_firm, :reload).account, f.account |
| 273 | end | 279 | end |
| 280 | + | ||
| 281 | + def test_eager_with_multi_table_conditional_properly_counts_the_records_when_using_size | ||
| 282 | + author = authors(:david) | ||
| 283 | + posts_with_no_comments = author.posts.select { |post| post.comments.blank? } | ||
| 284 | + assert_equal posts_with_no_comments.size, author.posts_with_no_comments.size | ||
| 285 | + assert_equal posts_with_no_comments, author.posts_with_no_comments | ||
| 286 | + end | ||
| 274 | 287 | ||
| 275 | def test_eager_with_invalid_association_reference | 288 | def test_eager_with_invalid_association_reference |
| 276 | assert_raises(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") { | 289 | assert_raises(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") { |
vendor/rails/activerecord/test/associations/join_model_test.rb
| @@ -8,10 +8,12 @@ require 'fixtures/category' | @@ -8,10 +8,12 @@ require 'fixtures/category' | ||
| 8 | require 'fixtures/categorization' | 8 | require 'fixtures/categorization' |
| 9 | require 'fixtures/vertex' | 9 | require 'fixtures/vertex' |
| 10 | require 'fixtures/edge' | 10 | require 'fixtures/edge' |
| 11 | +require 'fixtures/book' | ||
| 12 | +require 'fixtures/citation' | ||
| 11 | 13 | ||
| 12 | class AssociationsJoinModelTest < Test::Unit::TestCase | 14 | class AssociationsJoinModelTest < Test::Unit::TestCase |
| 13 | self.use_transactional_fixtures = false | 15 | self.use_transactional_fixtures = false |
| 14 | - fixtures :posts, :authors, :categories, :categorizations, :comments, :tags, :taggings, :author_favorites, :vertices | 16 | + fixtures :posts, :authors, :categories, :categorizations, :comments, :tags, :taggings, :author_favorites, :vertices, :books |
| 15 | 17 | ||
| 16 | def test_has_many | 18 | def test_has_many |
| 17 | assert authors(:david).categories.include?(categories(:general)) | 19 | assert authors(:david).categories.include?(categories(:general)) |
| @@ -29,7 +31,16 @@ class AssociationsJoinModelTest < Test::Unit::TestCase | @@ -29,7 +31,16 @@ class AssociationsJoinModelTest < Test::Unit::TestCase | ||
| 29 | assert_equal 2, authors(:mary).categorized_posts.size | 31 | assert_equal 2, authors(:mary).categorized_posts.size |
| 30 | assert_equal 1, authors(:mary).unique_categorized_posts.size | 32 | assert_equal 1, authors(:mary).unique_categorized_posts.size |
| 31 | end | 33 | end |
| 32 | - | 34 | + |
| 35 | + def test_has_many_uniq_through_count | ||
| 36 | + author = authors(:mary) | ||
| 37 | + assert !authors(:mary).unique_categorized_posts.loaded? | ||
| 38 | + assert_queries(1) { assert_equal 1, author.unique_categorized_posts.count } | ||
| 39 | + assert_queries(1) { assert_equal 1, author.unique_categorized_posts.count(:title, {}) } | ||
| 40 | + assert_queries(1) { assert_equal 0, author.unique_categorized_posts.count(:title, { :conditions => "title is NULL" }) } | ||
| 41 | + assert !authors(:mary).unique_categorized_posts.loaded? | ||
| 42 | + end | ||
| 43 | + | ||
| 33 | def test_polymorphic_has_many | 44 | def test_polymorphic_has_many |
| 34 | assert posts(:welcome).taggings.include?(taggings(:welcome_general)) | 45 | assert posts(:welcome).taggings.include?(taggings(:welcome_general)) |
| 35 | end | 46 | end |
| @@ -441,7 +452,21 @@ class AssociationsJoinModelTest < Test::Unit::TestCase | @@ -441,7 +452,21 @@ class AssociationsJoinModelTest < Test::Unit::TestCase | ||
| 441 | tags = posts(:thinking).tags | 452 | tags = posts(:thinking).tags |
| 442 | assert_equal tags, posts(:thinking).tags.push(tags(:general)) | 453 | assert_equal tags, posts(:thinking).tags.push(tags(:general)) |
| 443 | end | 454 | end |
| 444 | - | 455 | + |
| 456 | + def test_delete_associate_when_deleting_from_has_many_through_with_non_standard_id | ||
| 457 | + count = books(:awdr).references.count | ||
| 458 | + references_before = books(:awdr).references | ||
| 459 | + book = Book.create!(:name => 'Getting Real') | ||
| 460 | + book_awdr = books(:awdr) | ||
| 461 | + book_awdr.references << book | ||
| 462 | + assert_equal(count + 1, book_awdr.references(true).size) | ||
| 463 | + | ||
| 464 | + assert_nothing_raised { book_awdr.references.delete(book) } | ||
| 465 | + assert_equal(count, book_awdr.references.size) | ||
| 466 | + assert_equal(count, book_awdr.references(true).size) | ||
| 467 | + assert_equal(references_before.sort, book_awdr.references.sort) | ||
| 468 | + end | ||
| 469 | + | ||
| 445 | def test_delete_associate_when_deleting_from_has_many_through | 470 | def test_delete_associate_when_deleting_from_has_many_through |
| 446 | count = posts(:thinking).tags.count | 471 | count = posts(:thinking).tags.count |
| 447 | tags_before = posts(:thinking).tags | 472 | tags_before = posts(:thinking).tags |
vendor/rails/activerecord/test/associations_test.rb
| @@ -10,6 +10,8 @@ require 'fixtures/order' | @@ -10,6 +10,8 @@ require 'fixtures/order' | ||
| 10 | require 'fixtures/category' | 10 | require 'fixtures/category' |
| 11 | require 'fixtures/post' | 11 | require 'fixtures/post' |
| 12 | require 'fixtures/author' | 12 | require 'fixtures/author' |
| 13 | +require 'fixtures/person' | ||
| 14 | +require 'fixtures/reader' | ||
| 13 | 15 | ||
| 14 | 16 | ||
| 15 | class AssociationsTest < Test::Unit::TestCase | 17 | class AssociationsTest < Test::Unit::TestCase |
| @@ -21,6 +23,14 @@ class AssociationsTest < Test::Unit::TestCase | @@ -21,6 +23,14 @@ class AssociationsTest < Test::Unit::TestCase | ||
| 21 | Class.new(ActiveRecord::Base).has_many(:wheels, :name => 'wheels') | 23 | Class.new(ActiveRecord::Base).has_many(:wheels, :name => 'wheels') |
| 22 | end | 24 | end |
| 23 | end | 25 | end |
| 26 | + | ||
| 27 | + def test_should_construct_new_finder_sql_after_create | ||
| 28 | + person = Person.new | ||
| 29 | + assert_equal [], person.readers.find(:all) | ||
| 30 | + person.save! | ||
| 31 | + reader = Reader.create! :person => person, :post => Post.new(:title => "foo", :body => "bar") | ||
| 32 | + assert_equal [reader], person.readers.find(:all) | ||
| 33 | + end | ||
| 24 | 34 | ||
| 25 | def test_force_reload | 35 | def test_force_reload |
| 26 | firm = Firm.new("name" => "A New Firm, Inc") | 36 | firm = Firm.new("name" => "A New Firm, Inc") |
| @@ -67,8 +77,8 @@ class AssociationsTest < Test::Unit::TestCase | @@ -67,8 +77,8 @@ class AssociationsTest < Test::Unit::TestCase | ||
| 67 | end | 77 | end |
| 68 | 78 | ||
| 69 | class AssociationProxyTest < Test::Unit::TestCase | 79 | class AssociationProxyTest < Test::Unit::TestCase |
| 70 | - fixtures :authors, :posts | ||
| 71 | - | 80 | + fixtures :authors, :posts, :developers, :projects, :developers_projects |
| 81 | + | ||
| 72 | def test_proxy_accessors | 82 | def test_proxy_accessors |
| 73 | welcome = posts(:welcome) | 83 | welcome = posts(:welcome) |
| 74 | assert_equal welcome, welcome.author.proxy_owner | 84 | assert_equal welcome, welcome.author.proxy_owner |
| @@ -87,6 +97,19 @@ class AssociationProxyTest < Test::Unit::TestCase | @@ -87,6 +97,19 @@ class AssociationProxyTest < Test::Unit::TestCase | ||
| 87 | david.posts_with_extension.first # force load target | 97 | david.posts_with_extension.first # force load target |
| 88 | assert_equal david.posts_with_extension, david.posts_with_extension.testing_proxy_target | 98 | assert_equal david.posts_with_extension, david.posts_with_extension.testing_proxy_target |
| 89 | end | 99 | end |
| 100 | + | ||
| 101 | + def test_save_on_parent_does_not_load_target | ||
| 102 | + david = developers(:david) | ||
| 103 | + | ||
| 104 | + assert !david.projects.loaded? | ||
| 105 | + david.update_attribute(:created_at, Time.now) | ||
| 106 | + assert !david.projects.loaded? | ||
| 107 | + end | ||
| 108 | + | ||
| 109 | + def test_save_on_parent_saves_children | ||
| 110 | + developer = Developer.create :name => "Bryan", :salary => 50_000 | ||
| 111 | + assert_equal 1, developer.reload.audit_logs.size | ||
| 112 | + end | ||
| 90 | end | 113 | end |
| 91 | 114 | ||
| 92 | class HasOneAssociationsTest < Test::Unit::TestCase | 115 | class HasOneAssociationsTest < Test::Unit::TestCase |
| @@ -583,6 +606,13 @@ class HasManyAssociationsTest < Test::Unit::TestCase | @@ -583,6 +606,13 @@ class HasManyAssociationsTest < Test::Unit::TestCase | ||
| 583 | assert_equal 3, first_firm.plain_clients.size | 606 | assert_equal 3, first_firm.plain_clients.size |
| 584 | end | 607 | end |
| 585 | 608 | ||
| 609 | + def test_regular_create_on_has_many_when_parent_is_new_raises | ||
| 610 | + assert_deprecated(/.build instead/) do | ||
| 611 | + firm = Firm.new | ||
| 612 | + firm.plain_clients.create :name=>"Whoever" | ||
| 613 | + end | ||
| 614 | + end | ||
| 615 | + | ||
| 586 | def test_adding_a_mismatch_class | 616 | def test_adding_a_mismatch_class |
| 587 | assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << nil } | 617 | assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << nil } |
| 588 | assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << 1 } | 618 | assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << 1 } |
| @@ -1007,7 +1037,20 @@ class BelongsToAssociationsTest < Test::Unit::TestCase | @@ -1007,7 +1037,20 @@ class BelongsToAssociationsTest < Test::Unit::TestCase | ||
| 1007 | citibank.firm = apple | 1037 | citibank.firm = apple |
| 1008 | assert_equal apple.id, citibank.firm_id | 1038 | assert_equal apple.id, citibank.firm_id |
| 1009 | end | 1039 | end |
| 1010 | - | 1040 | + |
| 1041 | + def test_no_unexpected_aliasing | ||
| 1042 | + first_firm = companies(:first_firm) | ||
| 1043 | + another_firm = companies(:another_firm) | ||
| 1044 | + | ||
| 1045 | + citibank = Account.create("credit_limit" => 10) | ||
| 1046 | + citibank.firm = first_firm | ||
| 1047 | + original_proxy = citibank.firm | ||
| 1048 | + citibank.firm = another_firm | ||
| 1049 | + | ||
| 1050 | + assert_equal first_firm.object_id, original_proxy.object_id | ||
| 1051 | + assert_equal another_firm.object_id, citibank.firm.object_id | ||
| 1052 | + end | ||
| 1053 | + | ||
| 1011 | def test_creating_the_belonging_object | 1054 | def test_creating_the_belonging_object |
| 1012 | citibank = Account.create("credit_limit" => 10) | 1055 | citibank = Account.create("credit_limit" => 10) |
| 1013 | apple = citibank.create_firm("name" => "Apple") | 1056 | apple = citibank.create_firm("name" => "Apple") |
| @@ -1807,3 +1850,68 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase | @@ -1807,3 +1850,68 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase | ||
| 1807 | assert_equal %w(1 2), projects.scan(/\d/).sort | 1850 | assert_equal %w(1 2), projects.scan(/\d/).sort |
| 1808 | end | 1851 | end |
| 1809 | end | 1852 | end |
| 1853 | + | ||
| 1854 | + | ||
| 1855 | +class OverridingAssociationsTest < Test::Unit::TestCase | ||
| 1856 | + class Person < ActiveRecord::Base; end | ||
| 1857 | + class DifferentPerson < ActiveRecord::Base; end | ||
| 1858 | + | ||
| 1859 | + class PeopleList < ActiveRecord::Base | ||
| 1860 | + has_and_belongs_to_many :has_and_belongs_to_many, :before_add => :enlist | ||
| 1861 | + has_many :has_many, :before_add => :enlist | ||
| 1862 | + belongs_to :belongs_to | ||
| 1863 | + has_one :has_one | ||
| 1864 | + end | ||
| 1865 | + | ||
| 1866 | + class DifferentPeopleList < PeopleList | ||
| 1867 | + # Different association with the same name, callbacks should be omitted here. | ||
| 1868 | + has_and_belongs_to_many :has_and_belongs_to_many, :class_name => 'DifferentPerson' | ||
| 1869 | + has_many :has_many, :class_name => 'DifferentPerson' | ||
| 1870 | + belongs_to :belongs_to, :class_name => 'DifferentPerson', :foreign_key => 'belongs_to_id' | ||
| 1871 | + has_one :has_one, :class_name => 'DifferentPerson' | ||
| 1872 | + end | ||
| 1873 | + | ||
| 1874 | + def test_habtm_association_redefinition_callbacks_should_differ_and_not_inherited | ||
| 1875 | + # redeclared association on AR descendant should not inherit callbacks from superclass | ||
| 1876 | + callbacks = PeopleList.read_inheritable_attribute(:before_add_for_has_and_belongs_to_many) | ||
| 1877 | + assert_equal([:enlist], callbacks) | ||
| 1878 | + callbacks = DifferentPeopleList.read_inheritable_attribute(:before_add_for_has_and_belongs_to_many) | ||
| 1879 | + assert_equal([], callbacks) | ||
| 1880 | + end | ||
| 1881 | + | ||
| 1882 | + def test_has_many_association_redefinition_callbacks_should_differ_and_not_inherited | ||
| 1883 | + # redeclared association on AR descendant should not inherit callbacks from superclass | ||
| 1884 | + callbacks = PeopleList.read_inheritable_attribute(:before_add_for_has_many) | ||
| 1885 | + assert_equal([:enlist], callbacks) | ||
| 1886 | + callbacks = DifferentPeopleList.read_inheritable_attribute(:before_add_for_has_many) | ||
| 1887 | + assert_equal([], callbacks) | ||
| 1888 | + end | ||
| 1889 | + | ||
| 1890 | + def test_habtm_association_redefinition_reflections_should_differ_and_not_inherited | ||
| 1891 | + assert_not_equal( | ||
| 1892 | + PeopleList.reflect_on_association(:has_and_belongs_to_many), | ||
| 1893 | + DifferentPeopleList.reflect_on_association(:has_and_belongs_to_many) | ||
| 1894 | + ) | ||
| 1895 | + end | ||
| 1896 | + | ||
| 1897 | + def test_has_many_association_redefinition_reflections_should_differ_and_not_inherited | ||
| 1898 | + assert_not_equal( | ||
| 1899 | + PeopleList.reflect_on_association(:has_many), | ||
| 1900 | + DifferentPeopleList.reflect_on_association(:has_many) | ||
| 1901 | + ) | ||
| 1902 | + end | ||
| 1903 | + | ||
| 1904 | + def test_belongs_to_association_redefinition_reflections_should_differ_and_not_inherited | ||
| 1905 | + assert_not_equal( | ||
| 1906 | + PeopleList.reflect_on_association(:belongs_to), | ||
| 1907 | + DifferentPeopleList.reflect_on_association(:belongs_to) | ||
| 1908 | + ) | ||
| 1909 | + end | ||
| 1910 | + | ||
| 1911 | + def test_has_one_association_redefinition_reflections_should_differ_and_not_inherited | ||
| 1912 | + assert_not_equal( | ||
| 1913 | + PeopleList.reflect_on_association(:has_one), | ||
| 1914 | + DifferentPeopleList.reflect_on_association(:has_one) | ||
| 1915 | + ) | ||
| 1916 | + end | ||
| 1917 | +end |
vendor/rails/activerecord/test/base_test.rb
| @@ -1086,16 +1086,29 @@ class BasicsTest < Test::Unit::TestCase | @@ -1086,16 +1086,29 @@ class BasicsTest < Test::Unit::TestCase | ||
| 1086 | assert_equal(myobj, topic.content) | 1086 | assert_equal(myobj, topic.content) |
| 1087 | end | 1087 | end |
| 1088 | 1088 | ||
| 1089 | - def test_serialized_attribute_with_class_constraint | 1089 | + def test_nil_serialized_attribute_with_class_constraint |
| 1090 | myobj = MyObject.new('value1', 'value2') | 1090 | myobj = MyObject.new('value1', 'value2') |
| 1091 | - topic = Topic.create("content" => myobj) | ||
| 1092 | - Topic.serialize(:content, Hash) | 1091 | + topic = Topic.new |
| 1092 | + assert_nil topic.content | ||
| 1093 | + end | ||
| 1093 | 1094 | ||
| 1095 | + def test_should_raise_exception_on_serialized_attribute_with_type_mismatch | ||
| 1096 | + myobj = MyObject.new('value1', 'value2') | ||
| 1097 | + topic = Topic.new(:content => myobj) | ||
| 1098 | + assert topic.save | ||
| 1099 | + Topic.serialize(:content, Hash) | ||
| 1094 | assert_raise(ActiveRecord::SerializationTypeMismatch) { Topic.find(topic.id).content } | 1100 | assert_raise(ActiveRecord::SerializationTypeMismatch) { Topic.find(topic.id).content } |
| 1101 | + ensure | ||
| 1102 | + Topic.serialize(:content) | ||
| 1103 | + end | ||
| 1095 | 1104 | ||
| 1105 | + def test_serialized_attribute_with_class_constraint | ||
| 1096 | settings = { "color" => "blue" } | 1106 | settings = { "color" => "blue" } |
| 1097 | - Topic.find(topic.id).update_attribute("content", settings) | 1107 | + Topic.serialize(:content, Hash) |
| 1108 | + topic = Topic.new(:content => settings) | ||
| 1109 | + assert topic.save | ||
| 1098 | assert_equal(settings, Topic.find(topic.id).content) | 1110 | assert_equal(settings, Topic.find(topic.id).content) |
| 1111 | + ensure | ||
| 1099 | Topic.serialize(:content) | 1112 | Topic.serialize(:content) |
| 1100 | end | 1113 | end |
| 1101 | 1114 |
vendor/rails/activerecord/test/fixtures/author.rb
| @@ -25,6 +25,7 @@ class Author < ActiveRecord::Base | @@ -25,6 +25,7 @@ class Author < ActiveRecord::Base | ||
| 25 | 25 | ||
| 26 | has_many :hello_posts, :class_name => "Post", :conditions => "posts.body = 'hello'" | 26 | has_many :hello_posts, :class_name => "Post", :conditions => "posts.body = 'hello'" |
| 27 | has_many :hello_post_comments, :through => :hello_posts, :source => :comments | 27 | has_many :hello_post_comments, :through => :hello_posts, :source => :comments |
| 28 | + has_many :posts_with_no_comments, :class_name => 'Post', :conditions => 'comments.id is null', :include => :comments | ||
| 28 | 29 | ||
| 29 | has_many :other_posts, :class_name => "Post" | 30 | has_many :other_posts, :class_name => "Post" |
| 30 | has_many :posts_with_callbacks, :class_name => "Post", :before_add => :log_before_adding, | 31 | has_many :posts_with_callbacks, :class_name => "Post", :before_add => :log_before_adding, |
| @@ -0,0 +1,437 @@ | @@ -0,0 +1,437 @@ | ||
| 1 | +flowers: | ||
| 2 | + id: 1 | ||
| 3 | + data: !binary | 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 | ||
| 436 | + KKpVChRRRQAUUUUAFFFFABRRRQAUUUUAf//Z | ||
| 437 | + |
| @@ -0,0 +1,6 @@ | @@ -0,0 +1,6 @@ | ||
| 1 | +class Citation < ActiveRecord::Base | ||
| 2 | + belongs_to :reference_of, :class_name => "Book", :foreign_key => :book2_id | ||
| 3 | + | ||
| 4 | + belongs_to :book1, :class_name => "Book", :foreign_key => :book1_id | ||
| 5 | + belongs_to :book2, :class_name => "Book", :foreign_key => :book2_id | ||
| 6 | +end |
vendor/rails/activerecord/test/fixtures/db_definitions/schema.rb
| @@ -57,4 +57,18 @@ ActiveRecord::Schema.define do | @@ -57,4 +57,18 @@ ActiveRecord::Schema.define do | ||
| 57 | create_table :lock_without_defaults_cust, :force => true do |t| | 57 | create_table :lock_without_defaults_cust, :force => true do |t| |
| 58 | t.column :custom_lock_version, :integer | 58 | t.column :custom_lock_version, :integer |
| 59 | end | 59 | end |
| 60 | + | ||
| 61 | + create_table :audit_logs, :force => true do |t| | ||
| 62 | + t.column :message, :string, :null=>false | ||
| 63 | + t.column :developer_id, :integer, :null=>false | ||
| 64 | + end | ||
| 65 | + | ||
| 66 | + create_table :books, :force => true do |t| | ||
| 67 | + t.column :name, :string | ||
| 68 | + end | ||
| 69 | + | ||
| 70 | + create_table :citations, :force => true do |t| | ||
| 71 | + t.column :book1_id, :integer | ||
| 72 | + t.column :book2_id, :integer | ||
| 73 | + end | ||
| 60 | end | 74 | end |
vendor/rails/activerecord/test/fixtures/developer.rb
| @@ -31,8 +31,18 @@ class Developer < ActiveRecord::Base | @@ -31,8 +31,18 @@ class Developer < ActiveRecord::Base | ||
| 31 | 31 | ||
| 32 | has_and_belongs_to_many :special_projects, :join_table => 'developers_projects', :association_foreign_key => 'project_id' | 32 | has_and_belongs_to_many :special_projects, :join_table => 'developers_projects', :association_foreign_key => 'project_id' |
| 33 | 33 | ||
| 34 | + has_many :audit_logs | ||
| 35 | + | ||
| 34 | validates_inclusion_of :salary, :in => 50000..200000 | 36 | validates_inclusion_of :salary, :in => 50000..200000 |
| 35 | validates_length_of :name, :within => 3..20 | 37 | validates_length_of :name, :within => 3..20 |
| 38 | + | ||
| 39 | + before_create do |developer| | ||
| 40 | + developer.audit_logs.build :message => "Computer created" | ||
| 41 | + end | ||
| 42 | +end | ||
| 43 | + | ||
| 44 | +class AuditLog < ActiveRecord::Base | ||
| 45 | + belongs_to :developer | ||
| 36 | end | 46 | end |
| 37 | 47 | ||
| 38 | DeveloperSalary = Struct.new(:amount) | 48 | DeveloperSalary = Struct.new(:amount) |
vendor/rails/activerecord/test/fixtures_test.rb
| @@ -12,13 +12,15 @@ class FixturesTest < Test::Unit::TestCase | @@ -12,13 +12,15 @@ class FixturesTest < Test::Unit::TestCase | ||
| 12 | self.use_instantiated_fixtures = true | 12 | self.use_instantiated_fixtures = true |
| 13 | self.use_transactional_fixtures = false | 13 | self.use_transactional_fixtures = false |
| 14 | 14 | ||
| 15 | - fixtures :topics, :developers, :accounts, :tasks, :categories, :funny_jokes | 15 | + fixtures :topics, :developers, :accounts, :tasks, :categories, :funny_jokes, :binaries |
| 16 | 16 | ||
| 17 | - FIXTURES = %w( accounts companies customers | 17 | + FIXTURES = %w( accounts binaries companies customers |
| 18 | developers developers_projects entrants | 18 | developers developers_projects entrants |
| 19 | movies projects subscribers topics tasks ) | 19 | movies projects subscribers topics tasks ) |
| 20 | MATCH_ATTRIBUTE_NAME = /[a-zA-Z][-_\w]*/ | 20 | MATCH_ATTRIBUTE_NAME = /[a-zA-Z][-_\w]*/ |
| 21 | 21 | ||
| 22 | + BINARY_FIXTURE_PATH = File.dirname(__FILE__) + '/fixtures/flowers.jpg' | ||
| 23 | + | ||
| 22 | def test_clean_fixtures | 24 | def test_clean_fixtures |
| 23 | FIXTURES.each do |name| | 25 | FIXTURES.each do |name| |
| 24 | fixtures = nil | 26 | fixtures = nil |
| @@ -100,7 +102,6 @@ class FixturesTest < Test::Unit::TestCase | @@ -100,7 +102,6 @@ class FixturesTest < Test::Unit::TestCase | ||
| 100 | assert first | 102 | assert first |
| 101 | end | 103 | end |
| 102 | 104 | ||
| 103 | - | ||
| 104 | def test_bad_format | 105 | def test_bad_format |
| 105 | path = File.join(File.dirname(__FILE__), 'fixtures', 'bad_fixtures') | 106 | path = File.join(File.dirname(__FILE__), 'fixtures', 'bad_fixtures') |
| 106 | Dir.entries(path).each do |file| | 107 | Dir.entries(path).each do |file| |
| @@ -174,7 +175,6 @@ class FixturesTest < Test::Unit::TestCase | @@ -174,7 +175,6 @@ class FixturesTest < Test::Unit::TestCase | ||
| 174 | end | 175 | end |
| 175 | end | 176 | end |
| 176 | 177 | ||
| 177 | - | ||
| 178 | def test_yml_file_in_subdirectory | 178 | def test_yml_file_in_subdirectory |
| 179 | assert_equal(categories(:sub_special_1).name, "A special category in a subdir file") | 179 | assert_equal(categories(:sub_special_1).name, "A special category in a subdir file") |
| 180 | assert_equal(categories(:sub_special_1).class, SpecialCategory) | 180 | assert_equal(categories(:sub_special_1).class, SpecialCategory) |
| @@ -185,7 +185,11 @@ class FixturesTest < Test::Unit::TestCase | @@ -185,7 +185,11 @@ class FixturesTest < Test::Unit::TestCase | ||
| 185 | assert_equal(categories(:sub_special_3).class, SpecialCategory) | 185 | assert_equal(categories(:sub_special_3).class, SpecialCategory) |
| 186 | end | 186 | end |
| 187 | 187 | ||
| 188 | - | 188 | + def test_binary_in_fixtures |
| 189 | + assert_equal 1, @binaries.size | ||
| 190 | + data = File.read(BINARY_FIXTURE_PATH).freeze | ||
| 191 | + assert_equal data, @flowers.data | ||
| 192 | + end | ||
| 189 | end | 193 | end |
| 190 | 194 | ||
| 191 | if Account.connection.respond_to?(:reset_pk_sequence!) | 195 | if Account.connection.respond_to?(:reset_pk_sequence!) |
vendor/rails/activerecord/test/migration_test.rb
| @@ -170,7 +170,7 @@ if ActiveRecord::Base.connection.supports_migrations? | @@ -170,7 +170,7 @@ if ActiveRecord::Base.connection.supports_migrations? | ||
| 170 | # SQL Server and Sybase will not allow you to add a NOT NULL column | 170 | # SQL Server and Sybase will not allow you to add a NOT NULL column |
| 171 | # to a table without specifying a default value, so the | 171 | # to a table without specifying a default value, so the |
| 172 | # following test must be skipped | 172 | # following test must be skipped |
| 173 | - unless current_adapter?(:SQLServerAdapter, :SybaseAdapter) | 173 | + unless current_adapter?(:SQLServerAdapter, :SybaseAdapter, :SQLiteAdapter) |
| 174 | def test_add_column_not_null_without_default | 174 | def test_add_column_not_null_without_default |
| 175 | Person.connection.create_table :testings do |t| | 175 | Person.connection.create_table :testings do |t| |
| 176 | t.column :foo, :string | 176 | t.column :foo, :string |
| @@ -209,7 +209,7 @@ if ActiveRecord::Base.connection.supports_migrations? | @@ -209,7 +209,7 @@ if ActiveRecord::Base.connection.supports_migrations? | ||
| 209 | def test_native_decimal_insert_manual_vs_automatic | 209 | def test_native_decimal_insert_manual_vs_automatic |
| 210 | # SQLite3 always uses float in violation of SQL | 210 | # SQLite3 always uses float in violation of SQL |
| 211 | # 16 decimal places | 211 | # 16 decimal places |
| 212 | - correct_value = (current_adapter?(:SQLiteAdapter) ? '0.123456789012346E20' : '0012345678901234567890.0123456789').to_d | 212 | + correct_value = '0012345678901234567890.0123456789'.to_d |
| 213 | 213 | ||
| 214 | Person.delete_all | 214 | Person.delete_all |
| 215 | Person.connection.add_column "people", "wealth", :decimal, :precision => '30', :scale => '10' | 215 | Person.connection.add_column "people", "wealth", :decimal, :precision => '30', :scale => '10' |
| @@ -227,8 +227,9 @@ if ActiveRecord::Base.connection.supports_migrations? | @@ -227,8 +227,9 @@ if ActiveRecord::Base.connection.supports_migrations? | ||
| 227 | assert_kind_of BigDecimal, row.wealth | 227 | assert_kind_of BigDecimal, row.wealth |
| 228 | 228 | ||
| 229 | # If this assert fails, that means the SELECT is broken! | 229 | # If this assert fails, that means the SELECT is broken! |
| 230 | - assert_equal correct_value, row.wealth | ||
| 231 | - | 230 | + unless current_adapter?(:SQLite3Adapter) |
| 231 | + assert_equal correct_value, row.wealth | ||
| 232 | + end | ||
| 232 | # Reset to old state | 233 | # Reset to old state |
| 233 | Person.delete_all | 234 | Person.delete_all |
| 234 | 235 | ||
| @@ -240,8 +241,9 @@ if ActiveRecord::Base.connection.supports_migrations? | @@ -240,8 +241,9 @@ if ActiveRecord::Base.connection.supports_migrations? | ||
| 240 | assert_kind_of BigDecimal, row.wealth | 241 | assert_kind_of BigDecimal, row.wealth |
| 241 | 242 | ||
| 242 | # If these asserts fail, that means the INSERT (create function, or cast to SQL) is broken! | 243 | # If these asserts fail, that means the INSERT (create function, or cast to SQL) is broken! |
| 243 | - assert_equal correct_value, row.wealth | ||
| 244 | - | 244 | + unless current_adapter?(:SQLite3Adapter) |
| 245 | + assert_equal correct_value, row.wealth | ||
| 246 | + end | ||
| 245 | # Reset to old state | 247 | # Reset to old state |
| 246 | Person.connection.del_column "people", "wealth" rescue nil | 248 | Person.connection.del_column "people", "wealth" rescue nil |
| 247 | Person.reset_column_information | 249 | Person.reset_column_information |
| @@ -267,10 +269,7 @@ if ActiveRecord::Base.connection.supports_migrations? | @@ -267,10 +269,7 @@ if ActiveRecord::Base.connection.supports_migrations? | ||
| 267 | 269 | ||
| 268 | # Test for 30 significent digits (beyond the 16 of float), 10 of them | 270 | # Test for 30 significent digits (beyond the 16 of float), 10 of them |
| 269 | # after the decimal place. | 271 | # after the decimal place. |
| 270 | - if current_adapter?(:SQLiteAdapter) | ||
| 271 | - # SQLite3 uses float in violation of SQL. Test for 16 decimal places. | ||
| 272 | - assert_equal BigDecimal.new('0.123456789012346E20'), bob.wealth | ||
| 273 | - else | 272 | + unless current_adapter?(:SQLite3Adapter) |
| 274 | assert_equal BigDecimal.new("0012345678901234567890.0123456789"), bob.wealth | 273 | assert_equal BigDecimal.new("0012345678901234567890.0123456789"), bob.wealth |
| 275 | end | 274 | end |
| 276 | 275 |
vendor/rails/activerecord/test/mixin_test.rb
| @@ -211,6 +211,53 @@ class ListTest < Test::Unit::TestCase | @@ -211,6 +211,53 @@ class ListTest < Test::Unit::TestCase | ||
| 211 | assert_equal [new2, new1, new3], ListMixin.find(:all, :conditions => 'parent_id IS NULL', :order => 'pos') | 211 | assert_equal [new2, new1, new3], ListMixin.find(:all, :conditions => 'parent_id IS NULL', :order => 'pos') |
| 212 | end | 212 | end |
| 213 | 213 | ||
| 214 | + def test_remove_from_list_should_then_fail_in_list? | ||
| 215 | + assert_equal true, mixins(:list_1).in_list? | ||
| 216 | + mixins(:list_1).remove_from_list | ||
| 217 | + assert_equal false, mixins(:list_1).in_list? | ||
| 218 | + end | ||
| 219 | + | ||
| 220 | + def test_remove_from_list_should_set_position_to_nil | ||
| 221 | + assert_equal [mixins(:list_1), | ||
| 222 | + mixins(:list_2), | ||
| 223 | + mixins(:list_3), | ||
| 224 | + mixins(:list_4)], | ||
| 225 | + ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos') | ||
| 226 | + | ||
| 227 | + mixins(:list_2).remove_from_list | ||
| 228 | + | ||
| 229 | + assert_equal [mixins(:list_2, :reload), | ||
| 230 | + mixins(:list_1, :reload), | ||
| 231 | + mixins(:list_3, :reload), | ||
| 232 | + mixins(:list_4, :reload)], | ||
| 233 | + ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos') | ||
| 234 | + | ||
| 235 | + assert_equal 1, mixins(:list_1).pos | ||
| 236 | + assert_equal nil, mixins(:list_2).pos | ||
| 237 | + assert_equal 2, mixins(:list_3).pos | ||
| 238 | + assert_equal 3, mixins(:list_4).pos | ||
| 239 | + end | ||
| 240 | + | ||
| 241 | + def test_remove_before_destroy_does_not_shift_lower_items_twice | ||
| 242 | + assert_equal [mixins(:list_1), | ||
| 243 | + mixins(:list_2), | ||
| 244 | + mixins(:list_3), | ||
| 245 | + mixins(:list_4)], | ||
| 246 | + ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos') | ||
| 247 | + | ||
| 248 | + mixins(:list_2).remove_from_list | ||
| 249 | + mixins(:list_2).destroy | ||
| 250 | + | ||
| 251 | + assert_equal [mixins(:list_1, :reload), | ||
| 252 | + mixins(:list_3, :reload), | ||
| 253 | + mixins(:list_4, :reload)], | ||
| 254 | + ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos') | ||
| 255 | + | ||
| 256 | + assert_equal 1, mixins(:list_1).pos | ||
| 257 | + assert_equal 2, mixins(:list_3).pos | ||
| 258 | + assert_equal 3, mixins(:list_4).pos | ||
| 259 | + end | ||
| 260 | + | ||
| 214 | end | 261 | end |
| 215 | 262 | ||
| 216 | class TreeTest < Test::Unit::TestCase | 263 | class TreeTest < Test::Unit::TestCase |
vendor/rails/activerecord/test/validations_test.rb
| @@ -631,7 +631,7 @@ class ValidationsTest < Test::Unit::TestCase | @@ -631,7 +631,7 @@ class ValidationsTest < Test::Unit::TestCase | ||
| 631 | t = Topic.new('title' => 'noreplies', 'content' => 'whatever') | 631 | t = Topic.new('title' => 'noreplies', 'content' => 'whatever') |
| 632 | assert !t.save | 632 | assert !t.save |
| 633 | assert t.errors.on(:replies) | 633 | assert t.errors.on(:replies) |
| 634 | - t.replies.create('title' => 'areply', 'content' => 'whateveragain') | 634 | + t.replies.build('title' => 'areply', 'content' => 'whateveragain') |
| 635 | assert t.valid? | 635 | assert t.valid? |
| 636 | end | 636 | end |
| 637 | 637 | ||
| @@ -824,7 +824,7 @@ class ValidationsTest < Test::Unit::TestCase | @@ -824,7 +824,7 @@ class ValidationsTest < Test::Unit::TestCase | ||
| 824 | t = Topic.new('title' => 'あいうえお', 'content' => 'かきくけこ') | 824 | t = Topic.new('title' => 'あいうえお', 'content' => 'かきくけこ') |
| 825 | assert !t.save | 825 | assert !t.save |
| 826 | assert t.errors.on(:replies) | 826 | assert t.errors.on(:replies) |
| 827 | - t.replies.create('title' => 'あいうえお', 'content' => 'かきくけこ') | 827 | + t.replies.build('title' => 'あいうえお', 'content' => 'かきくけこ') |
| 828 | assert t.valid? | 828 | assert t.valid? |
| 829 | end | 829 | end |
| 830 | end | 830 | end |
vendor/rails/activesupport/CHANGELOG
| 1 | +*1.4.4* (October 12th, 2007) | ||
| 2 | + | ||
| 3 | +* Backport: allow array and hash query parameters. Array route parameters are converted/to/a/path as before. #6765, #7047, #7462 [bgipsy, Jeremy McAnally, Dan Kubb, brendan, Diego Algorta Casamayou] | ||
| 4 | + | ||
| 5 | + | ||
| 6 | +*1.4.3* (October 4th, 2007) | ||
| 7 | + | ||
| 8 | +* Demote Hash#to_xml to use XmlSimple#xml_in_string so it can't read files or stdin. #8453 [candlerb, Jeremy Kemper] | ||
| 9 | + | ||
| 10 | +* Document Object#blank?. #6491 [Chris Mear] | ||
| 11 | + | ||
| 12 | +* Update Dependencies to ignore constants inherited from ancestors. Closes #6951. [Nicholas Seckar] | ||
| 13 | + | ||
| 14 | +* Improved multibyte performance by relying less on exception raising #8159 [Blaine] | ||
| 15 | + | ||
| 16 | + | ||
| 1 | *1.4.2* (March 12th, 2007) | 17 | *1.4.2* (March 12th, 2007) |
| 2 | 18 | ||
| 3 | * Ruby 1.8.6 and 1.9 define private Time#to_date and #to_datetime; make them | 19 | * Ruby 1.8.6 and 1.9 define private Time#to_date and #to_datetime; make them |