diff options
19 files changed, 187 insertions, 36 deletions
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index b0f7d0bc11..9d320ddb8d 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -101,11 +101,11 @@ For example if you have this route: - map '*pages' => 'pages#show' + match '*pages' => 'pages#show' by requesting '/foo/bar.json', your `params[:pages]` will be equals to "foo/bar" with the request format of JSON. If you want the old 3.0.x behavior back, you could supply `:format => false` like this: - map '*pages' => 'pages#show', :format => false + match '*pages' => 'pages#show', :format => false * Added Base.http_basic_authenticate_with to do simple http basic authentication with a single class method call [DHH] diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec index 642fbcb8e6..88d892eb16 100644 --- a/actionpack/actionpack.gemspec +++ b/actionpack/actionpack.gemspec @@ -21,7 +21,7 @@ Gem::Specification.new do |s| s.add_dependency('rack-cache', '~> 1.0.2') s.add_dependency('builder', '~> 3.0.0') s.add_dependency('i18n', '~> 0.6') - s.add_dependency('rack', '~> 1.3.0') + s.add_dependency('rack', '~> 1.3.1') s.add_dependency('rack-test', '~> 0.6.0') s.add_dependency('rack-mount', '~> 0.8.1') s.add_dependency('sprockets', '= 2.0.0.beta.10') diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 65895590bf..8d071b2061 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -659,13 +659,13 @@ module ActionDispatch # # This generates the following routes: # - # admin_posts GET /admin/posts(.:format) {:action=>"index", :controller=>"admin/posts"} - # admin_posts POST /admin/posts(.:format) {:action=>"create", :controller=>"admin/posts"} - # new_admin_post GET /admin/posts/new(.:format) {:action=>"new", :controller=>"admin/posts"} - # edit_admin_post GET /admin/posts/:id/edit(.:format) {:action=>"edit", :controller=>"admin/posts"} - # admin_post GET /admin/posts/:id(.:format) {:action=>"show", :controller=>"admin/posts"} - # admin_post PUT /admin/posts/:id(.:format) {:action=>"update", :controller=>"admin/posts"} - # admin_post DELETE /admin/posts/:id(.:format) {:action=>"destroy", :controller=>"admin/posts"} + # admin_posts GET /admin/posts(.:format) admin/posts#index + # admin_posts POST /admin/posts(.:format) admin/posts#create + # new_admin_post GET /admin/posts/new(.:format) admin/posts#new + # edit_admin_post GET /admin/posts/:id/edit(.:format) admin/posts#edit + # admin_post GET /admin/posts/:id(.:format) admin/posts#show + # admin_post PUT /admin/posts/:id(.:format) admin/posts#update + # admin_post DELETE /admin/posts/:id(.:format) admin/posts#destroy # # === Options # diff --git a/actionpack/lib/sprockets/assets.rake b/actionpack/lib/sprockets/assets.rake index 0236350576..b2c282c158 100644 --- a/actionpack/lib/sprockets/assets.rake +++ b/actionpack/lib/sprockets/assets.rake @@ -17,10 +17,6 @@ namespace :assets do task :clean => :environment do assets = Rails.application.config.assets public_asset_path = Rails.public_path + assets.prefix - file_list = FileList.new("#{public_asset_path}/**/*") - file_list.each do |file| - rm_rf file - rm_rf "#{file}.gz" - end + rm_rf public_asset_path, :secure => true end end diff --git a/actionpack/test/dispatch/test_request_test.rb b/actionpack/test/dispatch/test_request_test.rb index aa115608ef..4ee1d61146 100644 --- a/actionpack/test/dispatch/test_request_test.rb +++ b/actionpack/test/dispatch/test_request_test.rb @@ -40,6 +40,11 @@ class TestRequestTest < ActiveSupport::TestCase req.cookie_jar["login"] = "XJ-122" assert_cookies({"user_name" => "david", "login" => "XJ-122"}, req.cookie_jar) + assert_nothing_raised do + req.cookie_jar["login"] = nil + assert_cookies({"user_name" => "david", "login" => nil}, req.cookie_jar) + end + req.cookie_jar.delete(:login) assert_cookies({"user_name" => "david"}, req.cookie_jar) diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index eb4a16ecf5..deff1c65ef 100644 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -1638,7 +1638,8 @@ MSG when new_record? "#{self.class.model_name.cache_key}/new" when timestamp = self[:updated_at] - "#{self.class.model_name.cache_key}/#{id}-#{timestamp.to_s(:number)}" + timestamp = timestamp.utc.to_s(:number) + "#{self.class.model_name.cache_key}/#{id}-#{timestamp}" else "#{self.class.model_name.cache_key}/#{id}" end diff --git a/activerecord/lib/active_record/relation/batches.rb b/activerecord/lib/active_record/relation/batches.rb index 46ab67d1cf..ec1176e3dd 100644 --- a/activerecord/lib/active_record/relation/batches.rb +++ b/activerecord/lib/active_record/relation/batches.rb @@ -66,11 +66,14 @@ module ActiveRecord records = relation.where(table[primary_key].gteq(start)).all while records.any? + records_size = records.size + primary_key_offset = records.last.id + yield records - break if records.size < batch_size + break if records_size < batch_size - if primary_key_offset = records.last.id + if primary_key_offset records = relation.where(table[primary_key].gt(primary_key_offset)).to_a else raise "Primary key not included in the custom select clause" diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index 9feb7b010f..8144f7075d 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -488,11 +488,11 @@ class BasicsTest < ActiveRecord::TestCase def test_hashing assert_equal [ Topic.find(1) ], [ Topic.find(2).topic ] & [ Topic.find(1) ] end - + def test_comparison topic_1 = Topic.create! topic_2 = Topic.create! - + assert_equal [topic_2, topic_1].sort, [topic_1, topic_2] end @@ -1835,4 +1835,29 @@ class BasicsTest < ActiveRecord::TestCase def test_attribtue_names_on_abstract_class assert_equal [], AbstractCompany.attribute_names end + + def test_cache_key_for_existing_record_is_not_timezone_dependent + ActiveRecord::Base.time_zone_aware_attributes = true + + Time.zone = "UTC" + utc_key = Developer.first.cache_key + + Time.zone = "EST" + est_key = Developer.first.cache_key + + assert_equal utc_key, est_key + ensure + ActiveRecord::Base.time_zone_aware_attributes = false + end + + def test_cache_key_format_for_existing_record_with_updated_at + dev = Developer.first + assert_equal "developers/#{dev.id}-#{dev.updated_at.utc.to_s(:number)}", dev.cache_key + end + + def test_cache_key_format_for_existing_record_with_nil_updated_at + dev = Developer.first + dev.update_attribute(:updated_at, nil) + assert_match /\/#{dev.id}$/, dev.cache_key + end end diff --git a/activerecord/test/cases/batches_test.rb b/activerecord/test/cases/batches_test.rb index 50ddf6c757..a35baee4ed 100644 --- a/activerecord/test/cases/batches_test.rb +++ b/activerecord/test/cases/batches_test.rb @@ -100,4 +100,20 @@ class EachTest < ActiveRecord::TestCase end end end + + def test_find_in_batches_should_not_use_records_after_yielding_them_in_case_original_array_is_modified + not_a_post = "not a post" + not_a_post.stubs(:id).raises(StandardError, "not_a_post had #id called on it") + + assert_nothing_raised do + Post.find_in_batches(:batch_size => 1) do |batch| + assert_kind_of Array, batch + assert_kind_of Post, batch.first + + batch.map! { not_a_post } + end + end + + end + end diff --git a/activerecord/test/fixtures/pirates.yml b/activerecord/test/fixtures/pirates.yml index a47d894249..abb91101da 100644 --- a/activerecord/test/fixtures/pirates.yml +++ b/activerecord/test/fixtures/pirates.yml @@ -5,5 +5,5 @@ blackbeard: redbeard: catchphrase: "Avast!" parrot: louis - created_on: <%= 2.weeks.ago.utc.to_s(:db) %> - updated_on: <%= 2.weeks.ago.utc.to_s(:db) %> + created_on: <%= 2.weeks.ago.to_s(:db) %> + updated_on: <%= 2.weeks.ago.to_s(:db) %> diff --git a/activesupport/lib/active_support/core_ext/object/blank.rb b/activesupport/lib/active_support/core_ext/object/blank.rb index 8221dc4abe..d060ac04d8 100644 --- a/activesupport/lib/active_support/core_ext/object/blank.rb +++ b/activesupport/lib/active_support/core_ext/object/blank.rb @@ -1,3 +1,5 @@ +# encoding: utf-8 + class Object # An object is blank if it's false, empty, or a whitespace string. # For example, "", " ", +nil+, [], and {} are all blank. @@ -86,14 +88,18 @@ class Hash end class String + # 0x3000: fullwidth whitespace + NON_WHITESPACE_REGEXP = %r![^\s#{[0x3000].pack("U")}]! + # A string is blank if it's empty or contains whitespaces only: # # "".blank? # => true # " ".blank? # => true + # " ".blank? # => true # " something here ".blank? # => false # def blank? - self !~ /\S/ + self !~ NON_WHITESPACE_REGEXP end end diff --git a/activesupport/test/core_ext/blank_test.rb b/activesupport/test/core_ext/blank_test.rb index 97c6b213ba..a2cf298905 100644 --- a/activesupport/test/core_ext/blank_test.rb +++ b/activesupport/test/core_ext/blank_test.rb @@ -1,8 +1,10 @@ +# encoding: utf-8 + require 'abstract_unit' require 'active_support/core_ext/object/blank' class BlankTest < Test::Unit::TestCase - BLANK = [ EmptyTrue.new, nil, false, '', ' ', " \n\t \r ", [], {} ] + BLANK = [ EmptyTrue.new, nil, false, '', ' ', " \n\t \r ", ' ', [], {} ] NOT = [ EmptyFalse.new, Object.new, true, 0, 1, 'a', [nil], { nil => 0 } ] def test_blank diff --git a/railties/guides/source/routing.textile b/railties/guides/source/routing.textile index 1cbc5c8f6e..6a729d9641 100644 --- a/railties/guides/source/routing.textile +++ b/railties/guides/source/routing.textile @@ -823,10 +823,10 @@ If you want a complete list of all of the available routes in your application, For example, here's a small section of the +rake routes+ output for a RESTful route: <pre> - users GET /users {:controller=>"users", :action=>"index"} -formatted_users GET /users.:format {:controller=>"users", :action=>"index"} - POST /users {:controller=>"users", :action=>"create"} - POST /users.:format {:controller=>"users", :action=>"create"} + users GET /users(.:format) users#index + POST /users(.:format) users#create + new_user GET /users/new(.:format) users#new +edit_user GET /users/:id/edit(.:format) users#edit </pre> You may restrict the listing to the routes that map to a particular controller setting the +CONTROLLER+ environment variable: diff --git a/railties/lib/rails/generators/rails/app/templates/config/application.rb b/railties/lib/rails/generators/rails/app/templates/config/application.rb index 500693a568..7687b1beac 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/application.rb +++ b/railties/lib/rails/generators/rails/app/templates/config/application.rb @@ -47,9 +47,9 @@ module <%= app_const_base %> # Configure sensitive parameters which will be filtered from the log file. config.filter_parameters += [:password] - <% unless options.skip_sprockets? %> +<% unless options.skip_sprockets? -%> # Enable the asset pipeline config.assets.enabled = true - <% end %> +<% end -%> end end diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec b/railties/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec index 56b06829d8..eb1a1e5054 100644 --- a/railties/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec +++ b/railties/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec @@ -4,7 +4,7 @@ Gem::Specification.new do |s| s.name = "<%= name %>" s.summary = "Insert <%= camelized %> summary." s.description = "Insert <%= camelized %> description." - s.files = Dir["{app,config,lib}/**/*"] + ["MIT-LICENSE", "Rakefile", "README.rdoc"] + s.files = Dir["{app,config,db,lib}/**/*"] + ["MIT-LICENSE", "Rakefile", "README.rdoc"] <% unless options.skip_test_unit? -%> s.test_files = Dir["test/**/*"] <% end -%> diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/Rakefile b/railties/lib/rails/generators/rails/plugin_new/templates/Rakefile index b28a842731..731f98047e 100755 --- a/railties/lib/rails/generators/rails/plugin_new/templates/Rakefile +++ b/railties/lib/rails/generators/rails/plugin_new/templates/Rakefile @@ -24,3 +24,8 @@ end APP_RAKEFILE = File.expand_path("../<%= dummy_path -%>/Rakefile", __FILE__) load 'rails/tasks/engine.rake' <% end %> + +<% unless options[:skip_gemspec] -%> + +Bundler::GemHelper.install_tasks +<% end %> diff --git a/railties/lib/rails/tasks/routes.rake b/railties/lib/rails/tasks/routes.rake index a0c953967c..0c26bcf790 100644 --- a/railties/lib/rails/tasks/routes.rake +++ b/railties/lib/rails/tasks/routes.rake @@ -10,8 +10,16 @@ task :routes => :environment do routes = all_routes.collect do |route| reqs = route.requirements.dup - reqs[:to] = route.app unless route.app.class.name.to_s =~ /^ActionDispatch::Routing/ - reqs = reqs.empty? ? "" : reqs.inspect + rack_app = route.app unless route.app.class.name.to_s =~ /^ActionDispatch::Routing/ + + endpoint = rack_app ? rack_app.inspect : "#{reqs[:controller]}##{reqs[:action]}" + constraints = reqs.except(:controller, :action) + + reqs = endpoint == '#' ? '' : endpoint + + unless constraints.empty? + reqs = reqs.empty? ? constraints.inspect : "#{reqs} #{constraints.inspect}" + end {:name => route.name.to_s, :verb => route.verb.to_s, :path => route.path, :reqs => reqs} end diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb index 7671c129e9..cc65a674c9 100644 --- a/railties/test/application/rake_test.rb +++ b/railties/test/application/rake_test.rb @@ -91,7 +91,7 @@ module ApplicationTests get '/cart', :to => 'cart#show' end RUBY - assert_match 'cart GET /cart(.:format)', Dir.chdir(app_path){ `rake routes` } + assert_equal "cart GET /cart(.:format) cart#show\n", Dir.chdir(app_path){ `rake routes` } end def test_rake_routes_shows_custom_assets @@ -100,7 +100,91 @@ module ApplicationTests get '/custom/assets', :to => 'custom_assets#show' end RUBY - assert_match 'custom_assets GET /custom/assets(.:format)', Dir.chdir(app_path){ `rake routes` } + assert_equal "custom_assets GET /custom/assets(.:format) custom_assets#show\n", + Dir.chdir(app_path){ `rake routes` } + end + + def test_rake_routes_shows_resources_route + app_file "config/routes.rb", <<-RUBY + AppTemplate::Application.routes.draw do + resources :articles + end + RUBY + expected = + " articles GET /articles(.:format) articles#index\n" << + " POST /articles(.:format) articles#create\n" << + " new_article GET /articles/new(.:format) articles#new\n" << + "edit_article GET /articles/:id/edit(.:format) articles#edit\n" << + " article GET /articles/:id(.:format) articles#show\n" << + " PUT /articles/:id(.:format) articles#update\n" << + " DELETE /articles/:id(.:format) articles#destroy\n" + assert_equal expected, Dir.chdir(app_path){ `rake routes` } + end + + def test_rake_routes_shows_root_route + app_file "config/routes.rb", <<-RUBY + AppTemplate::Application.routes.draw do + root :to => 'pages#main' + end + RUBY + assert_equal "root / pages#main\n", Dir.chdir(app_path){ `rake routes` } + end + + def test_rake_routes_shows_controller_and_action_only_route + app_file "config/routes.rb", <<-RUBY + AppTemplate::Application.routes.draw do + match ':controller/:action' + end + RUBY + assert_equal " /:controller/:action(.:format) \n", Dir.chdir(app_path){ `rake routes` } + end + + def test_rake_routes_shows_controller_and_action_route_with_constraints + app_file "config/routes.rb", <<-RUBY + AppTemplate::Application.routes.draw do + match ':controller(/:action(/:id))', :id => /\\d+/ + end + RUBY + assert_equal " /:controller(/:action(/:id))(.:format) {:id=>/\\d+/}\n", Dir.chdir(app_path){ `rake routes` } + end + + def test_rake_routes_shows_route_with_defaults + app_file "config/routes.rb", <<-RUBY + AppTemplate::Application.routes.draw do + match 'photos/:id' => 'photos#show', :defaults => {:format => 'jpg'} + end + RUBY + assert_equal %Q[ /photos/:id(.:format) photos#show {:format=>"jpg"}\n], Dir.chdir(app_path){ `rake routes` } + end + + def test_rake_routes_shows_route_with_constraints + app_file "config/routes.rb", <<-RUBY + AppTemplate::Application.routes.draw do + match 'photos/:id' => 'photos#show', :id => /[A-Z]\\d{5}/ + end + RUBY + assert_equal " /photos/:id(.:format) photos#show {:id=>/[A-Z]\\d{5}/}\n", Dir.chdir(app_path){ `rake routes` } + end + + def test_rake_routes_shows_route_with_rack_app + app_file "lib/rack_app.rb", <<-RUBY + class RackApp + class << self + def call(env) + end + end + end + RUBY + + app_file "config/routes.rb", <<-RUBY + require 'rack_app' + + AppTemplate::Application.routes.draw do + match 'foo/:id' => RackApp, :id => /[A-Z]\\d{5}/ + end + RUBY + + assert_equal " /foo/:id(.:format) RackApp {:id=>/[A-Z]\\d{5}/}\n", Dir.chdir(app_path){ `rake routes` } end def test_logger_is_flushed_when_exiting_production_rake_tasks diff --git a/railties/test/generators/plugin_new_generator_test.rb b/railties/test/generators/plugin_new_generator_test.rb index 4bd77ff7e3..0ccb2ae9da 100644 --- a/railties/test/generators/plugin_new_generator_test.rb +++ b/railties/test/generators/plugin_new_generator_test.rb @@ -206,7 +206,7 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase def test_creating_gemspec run_generator assert_file "bukkits.gemspec", /s.name = "bukkits"/ - assert_file "bukkits.gemspec", /s.files = Dir\["\{app,config,lib\}\/\*\*\/\*"\]/ + assert_file "bukkits.gemspec", /s.files = Dir\["\{app,config,db,lib\}\/\*\*\/\*"\]/ assert_file "bukkits.gemspec", /s.test_files = Dir\["test\/\*\*\/\*"\]/ assert_file "bukkits.gemspec", /s.version = "0.0.1"/ end |