diff options
Diffstat (limited to 'railties/test')
56 files changed, 2483 insertions, 1026 deletions
diff --git a/railties/test/abstract_unit.rb b/railties/test/abstract_unit.rb index 29ebdc6511..dfcf5aa27d 100644 --- a/railties/test/abstract_unit.rb +++ b/railties/test/abstract_unit.rb @@ -1,3 +1,5 @@ +ENV["RAILS_ENV"] ||= "test" + require File.expand_path("../../../load_paths", __FILE__) require 'stringio' diff --git a/railties/test/application/asset_debugging_test.rb b/railties/test/application/asset_debugging_test.rb index a2a7f184b8..ecacb34cb2 100644 --- a/railties/test/application/asset_debugging_test.rb +++ b/railties/test/application/asset_debugging_test.rb @@ -15,7 +15,7 @@ module ApplicationTests app_file "config/routes.rb", <<-RUBY AppTemplate::Application.routes.draw do - match '/posts', :to => "posts#index" + get '/posts', :to => "posts#index" end RUBY @@ -45,8 +45,8 @@ module ApplicationTests # the debug_assets params isn't used if compile is off get '/posts?debug_assets=true' - assert_match(/<script src="\/assets\/application-([0-z]+)\.js" type="text\/javascript"><\/script>/, last_response.body) - assert_no_match(/<script src="\/assets\/xmlhr-([0-z]+)\.js" type="text\/javascript"><\/script>/, last_response.body) + assert_match(/<script src="\/assets\/application-([0-z]+)\.js"><\/script>/, last_response.body) + assert_no_match(/<script src="\/assets\/xmlhr-([0-z]+)\.js"><\/script>/, last_response.body) end test "assets aren't concatened when compile is true is on and debug_assets params is true" do @@ -58,8 +58,8 @@ module ApplicationTests class ::PostsController < ActionController::Base ; end get '/posts?debug_assets=true' - assert_match(/<script src="\/assets\/application-([0-z]+)\.js\?body=1" type="text\/javascript"><\/script>/, last_response.body) - assert_match(/<script src="\/assets\/xmlhr-([0-z]+)\.js\?body=1" type="text\/javascript"><\/script>/, last_response.body) + assert_match(/<script src="\/assets\/application-([0-z]+)\.js\?body=1"><\/script>/, last_response.body) + assert_match(/<script src="\/assets\/xmlhr-([0-z]+)\.js\?body=1"><\/script>/, last_response.body) end end end diff --git a/railties/test/application/assets_test.rb b/railties/test/application/assets_test.rb index 1469c9af4d..c29fa4d95f 100644 --- a/railties/test/application/assets_test.rb +++ b/railties/test/application/assets_test.rb @@ -17,9 +17,21 @@ module ApplicationTests teardown_app end - def precompile! + def precompile!(env = nil) quietly do - Dir.chdir(app_path){ `bundle exec rake assets:precompile` } + precompile_task = 'bundle exec rake assets:precompile' + precompile_task += ' ' + env if env + out = Dir.chdir(app_path){ %x[ #{precompile_task} ] } + assert $?.exitstatus == 0, + "#{precompile_task} has failed: #{out}.\ + Probably you didn't install JavaScript runtime." + return out + end + end + + def clean_assets! + quietly do + assert Dir.chdir(app_path){ system('bundle exec rake assets:clean') } end end @@ -28,7 +40,7 @@ module ApplicationTests app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match '*path', :to => lambda { |env| [200, { "Content-Type" => "text/html" }, "Not an asset"] } + get '*path', :to => lambda { |env| [200, { "Content-Type" => "text/html" }, "Not an asset"] } end RUBY @@ -94,20 +106,28 @@ module ApplicationTests precompile! images_should_compile.each do |filename| - assert File.exists?("#{app_path}/public/assets/#{filename}") + assert_file_exists "#{app_path}/public/assets/#{filename}" end - assert File.exists?("#{app_path}/public/assets/application.js") - assert File.exists?("#{app_path}/public/assets/application.css") + assert_file_exists("#{app_path}/public/assets/application.js") + assert_file_exists("#{app_path}/public/assets/application.css") - assert !File.exists?("#{app_path}/public/assets/someapplication.js") - assert !File.exists?("#{app_path}/public/assets/someapplication.css") + assert_no_file_exists("#{app_path}/public/assets/someapplication.js") + assert_no_file_exists("#{app_path}/public/assets/someapplication.css") - assert !File.exists?("#{app_path}/public/assets/something.min.js") - assert !File.exists?("#{app_path}/public/assets/something.min.css") + assert_no_file_exists("#{app_path}/public/assets/something.min.js") + assert_no_file_exists("#{app_path}/public/assets/something.min.css") - assert !File.exists?("#{app_path}/public/assets/something.else.js") - assert !File.exists?("#{app_path}/public/assets/something.else.css") + assert_no_file_exists("#{app_path}/public/assets/something.else.js") + assert_no_file_exists("#{app_path}/public/assets/something.else.css") + end + + def assert_file_exists(filename) + assert File.exists?(filename), "missing #{filename}" + end + + def assert_no_file_exists(filename) + assert !File.exists?(filename), "#{filename} does exist" end test "asset pipeline should use a Sprockets::Index when config.assets.digest is true" do @@ -204,7 +224,7 @@ module ApplicationTests app_file "config/routes.rb", <<-RUBY AppTemplate::Application.routes.draw do - match '/posts', :to => "posts#index" + get '/posts', :to => "posts#index" end RUBY @@ -221,7 +241,7 @@ module ApplicationTests get '/posts' assert_match(/AssetNotPrecompiledError/, last_response.body) - assert_match(/app.js isn't precompiled/, last_response.body) + assert_match(/app.js isn't precompiled/, last_response.body) end test "assets raise AssetNotPrecompiledError when manifest file is present and requested file isn't precompiled if digest is disabled" do @@ -230,7 +250,7 @@ module ApplicationTests app_file "config/routes.rb", <<-RUBY AppTemplate::Application.routes.draw do - match '/posts', :to => "posts#index" + get '/posts', :to => "posts#index" end RUBY @@ -245,7 +265,7 @@ module ApplicationTests get '/posts' assert_match(/AssetNotPrecompiledError/, last_response.body) - assert_match(/app.js isn't precompiled/, last_response.body) + assert_match(/app.js isn't precompiled/, last_response.body) end test "precompile properly refers files referenced with asset_path and and run in the provided RAILS_ENV" do @@ -253,9 +273,8 @@ module ApplicationTests # digest is default in false, we must enable it for test environment add_to_env_config "test", "config.assets.digest = true" - quietly do - Dir.chdir(app_path){ `bundle exec rake assets:precompile RAILS_ENV=test` } - end + precompile!('RAILS_ENV=test') + file = Dir["#{app_path}/public/assets/application.css"].first assert_match(/\/assets\/rails\.png/, File.read(file)) file = Dir["#{app_path}/public/assets/application-*.css"].first @@ -285,9 +304,9 @@ module ApplicationTests add_to_config "config.assets.compile = true" ENV["RAILS_ENV"] = nil - quietly do - Dir.chdir(app_path){ `bundle exec rake assets:precompile RAILS_GROUPS=assets` } - end + + precompile!('RAILS_GROUPS=assets') + file = Dir["#{app_path}/public/assets/application-*.css"].first assert_match(/\/assets\/rails-([0-z]+)\.png/, File.read(file)) end @@ -310,9 +329,7 @@ module ApplicationTests app_file "public/assets/application.css", "a { color: green; }" app_file "public/assets/subdir/broken.png", "not really an image file" - quietly do - Dir.chdir(app_path){ `bundle exec rake assets:clean` } - end + clean_assets! files = Dir["#{app_path}/public/assets/**/*", "#{app_path}/tmp/cache/assets/*"] assert_equal 0, files.length, "Expected no assets, but found #{files.join(', ')}" @@ -334,7 +351,7 @@ module ApplicationTests app_file "config/routes.rb", <<-RUBY AppTemplate::Application.routes.draw do - match '/omg', :to => "omg#index" + get '/omg', :to => "omg#index" end RUBY @@ -382,8 +399,8 @@ module ApplicationTests # the debug_assets params isn't used if compile is off get '/posts?debug_assets=true' - assert_match(/<script src="\/assets\/application-([0-z]+)\.js" type="text\/javascript"><\/script>/, last_response.body) - assert_no_match(/<script src="\/assets\/xmlhr-([0-z]+)\.js" type="text\/javascript"><\/script>/, last_response.body) + assert_match(/<script src="\/assets\/application-([0-z]+)\.js"><\/script>/, last_response.body) + assert_no_match(/<script src="\/assets\/xmlhr-([0-z]+)\.js"><\/script>/, last_response.body) end test "assets aren't concatened when compile is true is on and debug_assets params is true" do @@ -397,8 +414,8 @@ module ApplicationTests class ::PostsController < ActionController::Base ; end get '/posts?debug_assets=true' - assert_match(/<script src="\/assets\/application-([0-z]+)\.js\?body=1" type="text\/javascript"><\/script>/, last_response.body) - assert_match(/<script src="\/assets\/xmlhr-([0-z]+)\.js\?body=1" type="text\/javascript"><\/script>/, last_response.body) + assert_match(/<script src="\/assets\/application-([0-z]+)\.js\?body=1"><\/script>/, last_response.body) + assert_match(/<script src="\/assets\/xmlhr-([0-z]+)\.js\?body=1"><\/script>/, last_response.body) end test "assets can access model information when precompiling" do @@ -440,9 +457,8 @@ module ApplicationTests add_to_config "config.assets.compile = true" add_to_config "config.assets.digest = true" - quietly do - Dir.chdir(app_path){ `bundle exec rake assets:clean assets:precompile` } - end + clean_assets! + precompile! files = Dir["#{app_path}/public/assets/application-*.js"] assert_equal 1, files.length, "Expected digested application.js asset to be generated, but none found" @@ -453,9 +469,8 @@ module ApplicationTests add_to_env_config "production", "config.assets.prefix = 'production_assets'" ENV["RAILS_ENV"] = nil - quietly do - Dir.chdir(app_path){ `bundle exec rake assets:clean` } - end + + clean_assets! files = Dir["#{app_path}/public/production_assets/application.js"] assert_equal 0, files.length, "Expected application.js asset to be removed, but still exists" @@ -513,7 +528,7 @@ module ApplicationTests app_file "config/routes.rb", <<-RUBY AppTemplate::Application.routes.draw do - match '/posts', :to => "posts#index" + get '/posts', :to => "posts#index" end RUBY end diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index 3dffd1c74c..039b08c723 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -41,16 +41,39 @@ module ApplicationTests FileUtils.rm_rf(new_app) if File.directory?(new_app) end + test "a renders exception on pending migration" do + add_to_config <<-RUBY + config.active_record.migration_error = :page_load + config.consider_all_requests_local = true + config.action_dispatch.show_exceptions = true + RUBY + + require "#{app_path}/config/environment" + ActiveRecord::Migrator.stubs(:needs_migration?).returns(true) + + get "/foo" + assert_equal 500, last_response.status + assert_match "ActiveRecord::PendingMigrationError", last_response.body + end + + test "multiple queue construction is possible" do + require 'rails' + require "#{app_path}/config/environment" + mail_queue = Rails.application.build_queue + image_processing_queue = Rails.application.build_queue + assert_not_equal mail_queue, image_processing_queue + end + test "Rails.groups returns available groups" do require "rails" Rails.env = "development" assert_equal [:default, "development"], Rails.groups - assert_equal [:default, "development", :assets], Rails.groups(:assets => [:development]) - assert_equal [:default, "development", :another, :assets], Rails.groups(:another, :assets => %w(development)) + assert_equal [:default, "development", :assets], Rails.groups(assets: [:development]) + assert_equal [:default, "development", :another, :assets], Rails.groups(:another, assets: %w(development)) Rails.env = "test" - assert_equal [:default, "test"], Rails.groups(:assets => [:development]) + assert_equal [:default, "test"], Rails.groups(assets: [:development]) ENV["RAILS_GROUPS"] = "javascripts,stylesheets" assert_equal [:default, "test", "javascripts", "stylesheets"], Rails.groups @@ -116,13 +139,19 @@ module ApplicationTests assert_instance_of Pathname, Rails.root end - test "marking the application as threadsafe sets the correct config variables" do + test "initialize an eager loaded, cache classes app" do add_to_config <<-RUBY - config.threadsafe! + config.eager_load = true + config.cache_classes = true RUBY require "#{app_path}/config/application" - assert AppTemplate::Application.config.allow_concurrency + assert AppTemplate::Application.initialize! + end + + test "application is always added to eager_load namespaces" do + require "#{app_path}/config/application" + assert AppTemplate::Application, AppTemplate::Application.config.eager_load_namespaces end test "asset_path defaults to nil for application" do @@ -130,10 +159,11 @@ module ApplicationTests assert_equal nil, AppTemplate::Application.config.asset_path end - test "the application can be marked as threadsafe when there are no frameworks" do + test "the application can be eager loaded even when there are no frameworks" do FileUtils.rm_rf("#{app_path}/config/environments") add_to_config <<-RUBY - config.threadsafe! + config.eager_load = true + config.cache_classes = true RUBY use_frameworks [] @@ -143,22 +173,6 @@ module ApplicationTests end end - test "frameworks are not preloaded by default" do - require "#{app_path}/config/environment" - - assert ActionController.autoload?(:RecordIdentifier) - end - - test "frameworks are preloaded with config.preload_frameworks is set" do - add_to_config <<-RUBY - config.preload_frameworks = true - RUBY - - require "#{app_path}/config/environment" - - assert !ActionController.autoload?(:RecordIdentifier) - end - test "filter_parameters should be able to set via config.filter_parameters" do add_to_config <<-RUBY config.filter_parameters += [ :foo, 'bar', lambda { |key, value| @@ -246,6 +260,55 @@ module ApplicationTests assert last_response.body =~ /csrf\-param/ end + test "default method for update can be changed" do + app_file 'app/models/post.rb', <<-RUBY + class Post + extend ActiveModel::Naming + def to_key; [1]; end + def persisted?; true; end + end + RUBY + + app_file 'app/controllers/posts_controller.rb', <<-RUBY + class PostsController < ApplicationController + def show + render :inline => "<%= begin; form_for(Post.new) {}; rescue => e; e.to_s; end %>" + end + + def update + render :text => "update" + end + end + RUBY + + add_to_config <<-RUBY + routes.prepend do + resources :posts + end + RUBY + + require "#{app_path}/config/environment" + + token = "cf50faa3fe97702ca1ae" + PostsController.any_instance.stubs(:form_authenticity_token).returns(token) + params = {:authenticity_token => token} + + get "/posts/1" + assert_match(/patch/, last_response.body) + + patch "/posts/1", params + assert_match(/update/, last_response.body) + + patch "/posts/1", params + assert_equal 200, last_response.status + + put "/posts/1", params + assert_match(/update/, last_response.body) + + put "/posts/1", params + assert_equal 200, last_response.status + end + test "request forgery token param can be changed" do make_basic_app do app.config.action_controller.request_forgery_protection_token = '_xsrf_token_here' @@ -302,9 +365,10 @@ module ApplicationTests require "#{app_path}/config/environment" - assert_equal ActiveModel::MassAssignmentSecurity::WhiteList, - ActiveRecord::Base.active_authorizers[:default].class - assert_equal [""], ActiveRecord::Base.active_authorizers[:default].to_a + klass = Class.new(ActiveRecord::Base) + + assert_equal ActiveModel::MassAssignmentSecurity::WhiteList, klass.active_authorizers[:default].class + assert_equal [], klass.active_authorizers[:default].to_a end test "registers interceptors with ActionMailer" do @@ -483,6 +547,12 @@ module ApplicationTests end RUBY + app_file 'app/controllers/application_controller.rb', <<-RUBY + class ApplicationController < ActionController::Base + protect_from_forgery with: :reset_session # as we are testing API here + end + RUBY + app_file 'app/controllers/posts_controller.rb', <<-RUBY class PostsController < ApplicationController def create @@ -539,5 +609,45 @@ module ApplicationTests make_basic_app assert app.config.colorize_logging end + + test "config.active_record.observers" do + add_to_config <<-RUBY + config.active_record.observers = :foo_observer + RUBY + + app_file 'app/models/foo.rb', <<-RUBY + class Foo < ActiveRecord::Base + end + RUBY + + app_file 'app/models/foo_observer.rb', <<-RUBY + class FooObserver < ActiveRecord::Observer + end + RUBY + + require "#{app_path}/config/environment" + + ActiveRecord::Base + assert defined?(FooObserver) + end + + test "config.session_store with :active_record_store with activerecord-session_store gem" do + begin + make_basic_app do |app| + ActionDispatch::Session::ActiveRecordStore = Class.new(ActionDispatch::Session::CookieStore) + app.config.session_store :active_record_store + end + ensure + ActionDispatch::Session.send :remove_const, :ActiveRecordStore + end + end + + test "config.session_store with :active_record_store without activerecord-session_store gem" do + assert_raise RuntimeError, /activerecord-session_store/ do + make_basic_app do |app| + app.config.session_store :active_record_store + end + end + end end end diff --git a/railties/test/application/generators_test.rb b/railties/test/application/generators_test.rb index bf58bb3f74..b80244f1d2 100644 --- a/railties/test/application/generators_test.rb +++ b/railties/test/application/generators_test.rb @@ -45,10 +45,10 @@ module ApplicationTests test "generators set rails options" do with_bare_config do |c| - c.generators.orm = :datamapper + c.generators.orm = :data_mapper c.generators.test_framework = :rspec c.generators.helper = false - expected = { :rails => { :orm => :datamapper, :test_framework => :rspec, :helper => false } } + expected = { :rails => { :orm => :data_mapper, :test_framework => :rspec, :helper => false } } assert_equal(expected, c.generators.options) end end @@ -64,7 +64,7 @@ module ApplicationTests test "generators aliases, options, templates and fallbacks on initialization" do add_to_config <<-RUBY config.generators.rails :aliases => { :test_framework => "-w" } - config.generators.orm :datamapper + config.generators.orm :data_mapper config.generators.test_framework :rspec config.generators.fallbacks[:shoulda] = :test_unit config.generators.templates << "some/where" @@ -95,15 +95,15 @@ module ApplicationTests test "generators with hashes for options and aliases" do with_bare_config do |c| c.generators do |g| - g.orm :datamapper, :migration => false + g.orm :data_mapper, :migration => false g.plugin :aliases => { :generator => "-g" }, :generator => true end expected = { - :rails => { :orm => :datamapper }, + :rails => { :orm => :data_mapper }, :plugin => { :generator => true }, - :datamapper => { :migration => false } + :data_mapper => { :migration => false } } assert_equal expected, c.generators.options @@ -114,12 +114,12 @@ module ApplicationTests test "generators with string and hash for options should generate symbol keys" do with_bare_config do |c| c.generators do |g| - g.orm 'datamapper', :migration => false + g.orm 'data_mapper', :migration => false end expected = { - :rails => { :orm => :datamapper }, - :datamapper => { :migration => false } + :rails => { :orm => :data_mapper }, + :data_mapper => { :migration => false } } assert_equal expected, c.generators.options diff --git a/railties/test/application/initializers/boot_test.rb b/railties/test/application/initializers/boot_test.rb index 04c46058cb..7eda15894e 100644 --- a/railties/test/application/initializers/boot_test.rb +++ b/railties/test/application/initializers/boot_test.rb @@ -1,7 +1,7 @@ require "isolation/abstract_unit" module ApplicationTests - class GemBooting < ActiveSupport::TestCase + class BootTest < ActiveSupport::TestCase include ActiveSupport::Testing::Isolation def setup diff --git a/railties/test/application/initializers/frameworks_test.rb b/railties/test/application/initializers/frameworks_test.rb index 8812685620..d3bbac811c 100644 --- a/railties/test/application/initializers/frameworks_test.rb +++ b/railties/test/application/initializers/frameworks_test.rb @@ -1,4 +1,5 @@ require "isolation/abstract_unit" +require 'set' module ApplicationTests class FrameworksTest < ActiveSupport::TestCase @@ -66,7 +67,7 @@ module ApplicationTests require "#{app_path}/config/environment" assert Foo.method_defined?(:foo_path) assert Foo.method_defined?(:main_app) - assert_equal ["notify"], Foo.action_methods + assert_equal Set.new(["notify"]), Foo.action_methods end test "allows to not load all helpers for controllers" do @@ -115,7 +116,7 @@ module ApplicationTests app_file "config/routes.rb", <<-RUBY AppTemplate::Application.routes.draw do - match "/:controller(/:action)" + get "/:controller(/:action)" end RUBY @@ -162,26 +163,6 @@ module ApplicationTests end # AR - test "database middleware doesn't initialize when session store is not active_record" do - add_to_config <<-RUBY - config.root = "#{app_path}" - config.session_store :cookie_store, { :key => "blahblahblah" } - RUBY - require "#{app_path}/config/environment" - - assert !Rails.application.config.middleware.include?(ActiveRecord::SessionStore) - end - - test "database middleware initializes when session store is active record" do - add_to_config "config.session_store :active_record_store" - - require "#{app_path}/config/environment" - - expects = [ActiveRecord::ConnectionAdapters::ConnectionManagement, ActiveRecord::QueryCache, ActiveRecord::SessionStore] - middleware = Rails.application.config.middleware.map { |m| m.klass } - assert_equal expects, middleware & expects - end - test "active_record extensions are applied to ActiveRecord" do add_to_config "config.active_record.table_name_prefix = 'tbl_'" require "#{app_path}/config/environment" @@ -193,5 +174,26 @@ module ApplicationTests require "#{app_path}/config/environment" assert_nil defined?(ActiveRecord::Base) end + + test "use schema cache dump" do + Dir.chdir(app_path) do + `rails generate model post title:string; + bundle exec rake db:migrate db:schema:cache:dump` + end + require "#{app_path}/config/environment" + ActiveRecord::Base.connection.drop_table("posts") # force drop posts table for test. + assert ActiveRecord::Base.connection.schema_cache.tables["posts"] + end + + test "expire schema cache dump" do + Dir.chdir(app_path) do + `rails generate model post title:string; + bundle exec rake db:migrate db:schema:cache:dump db:rollback` + end + silence_warnings { + require "#{app_path}/config/environment" + assert !ActiveRecord::Base.connection.schema_cache.tables["posts"] + } + end end end diff --git a/railties/test/application/initializers/hooks_test.rb b/railties/test/application/initializers/hooks_test.rb index 7b3e6844fd..b2cea0a8e1 100644 --- a/railties/test/application/initializers/hooks_test.rb +++ b/railties/test/application/initializers/hooks_test.rb @@ -1,7 +1,7 @@ require "isolation/abstract_unit" module ApplicationTests - class InitializersTest < ActiveSupport::TestCase + class HooksTest < ActiveSupport::TestCase include ActiveSupport::Testing::Isolation def setup @@ -20,11 +20,11 @@ module ApplicationTests assert $foo end - test "hooks block works correctly without cache classes (before_eager_load is not called)" do + test "hooks block works correctly without eager_load (before_eager_load is not called)" do add_to_config <<-RUBY $initialization_callbacks = [] config.root = "#{app_path}" - config.cache_classes = false + config.eager_load = false config.before_configuration { $initialization_callbacks << 1 } config.before_initialize { $initialization_callbacks << 2 } config.before_eager_load { Boom } @@ -35,11 +35,11 @@ module ApplicationTests assert_equal [1,2,3], $initialization_callbacks end - test "hooks block works correctly with cache classes" do + test "hooks block works correctly with eager_load" do add_to_config <<-RUBY $initialization_callbacks = [] config.root = "#{app_path}" - config.cache_classes = true + config.eager_load = true config.before_configuration { $initialization_callbacks << 1 } config.before_initialize { $initialization_callbacks << 2 } config.before_eager_load { $initialization_callbacks << 3 } diff --git a/railties/test/application/initializers/i18n_test.rb b/railties/test/application/initializers/i18n_test.rb index abb277dc1d..02d20bc150 100644 --- a/railties/test/application/initializers/i18n_test.rb +++ b/railties/test/application/initializers/i18n_test.rb @@ -85,7 +85,7 @@ en: app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match '/i18n', :to => lambda { |env| [200, {}, [Foo.instance_variable_get('@foo')]] } + get '/i18n', :to => lambda { |env| [200, {}, [Foo.instance_variable_get('@foo')]] } end RUBY @@ -109,7 +109,7 @@ en: app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match '/i18n', :to => lambda { |env| [200, {}, [I18n.t(:foo)]] } + get '/i18n', :to => lambda { |env| [200, {}, [I18n.t(:foo)]] } end RUBY diff --git a/railties/test/application/loading_test.rb b/railties/test/application/loading_test.rb index 5ad51f8476..e0286502f3 100644 --- a/railties/test/application/loading_test.rb +++ b/railties/test/application/loading_test.rb @@ -20,6 +20,7 @@ class LoadingTest < ActiveSupport::TestCase app_file "app/models/post.rb", <<-MODEL class Post < ActiveRecord::Base validates_acceptance_of :title, :accept => "omg" + attr_accessible :title end MODEL @@ -76,8 +77,8 @@ class LoadingTest < ActiveSupport::TestCase app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match '/load', :to => lambda { |env| [200, {}, Post.all] } - match '/unload', :to => lambda { |env| [200, {}, []] } + get '/load', :to => lambda { |env| [200, {}, Post.all] } + get '/unload', :to => lambda { |env| [200, {}, []] } end RUBY @@ -94,7 +95,7 @@ class LoadingTest < ActiveSupport::TestCase assert_equal [ActiveRecord::SchemaMigration], ActiveRecord::Base.descendants end - test "initialize_cant_be_called_twice" do + test "initialize cant be called twice" do require "#{app_path}/config/environment" assert_raise(RuntimeError) { ::AppTemplate::Application.initialize! } end @@ -106,7 +107,7 @@ class LoadingTest < ActiveSupport::TestCase app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match '/c', :to => lambda { |env| [200, {"Content-Type" => "text/plain"}, [User.counter.to_s]] } + get '/c', :to => lambda { |env| [200, {"Content-Type" => "text/plain"}, [User.counter.to_s]] } end RUBY @@ -145,7 +146,7 @@ class LoadingTest < ActiveSupport::TestCase app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match '/c', :to => lambda { |env| [200, {"Content-Type" => "text/plain"}, [User.counter.to_s]] } + get '/c', :to => lambda { |env| [200, {"Content-Type" => "text/plain"}, [User.counter.to_s]] } end RUBY @@ -181,7 +182,7 @@ class LoadingTest < ActiveSupport::TestCase app_file 'config/routes.rb', <<-RUBY $counter = 0 AppTemplate::Application.routes.draw do - match '/c', :to => lambda { |env| User; [200, {"Content-Type" => "text/plain"}, [$counter.to_s]] } + get '/c', :to => lambda { |env| User; [200, {"Content-Type" => "text/plain"}, [$counter.to_s]] } end RUBY @@ -212,8 +213,8 @@ class LoadingTest < ActiveSupport::TestCase app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match '/title', :to => lambda { |env| [200, {"Content-Type" => "text/plain"}, [Post.new.title]] } - match '/body', :to => lambda { |env| [200, {"Content-Type" => "text/plain"}, [Post.new.body]] } + get '/title', :to => lambda { |env| [200, {"Content-Type" => "text/plain"}, [Post.new.title]] } + get '/body', :to => lambda { |env| [200, {"Content-Type" => "text/plain"}, [Post.new.body]] } end RUBY @@ -255,6 +256,45 @@ class LoadingTest < ActiveSupport::TestCase assert_equal "BODY", last_response.body end + test "AC load hooks can be used with metal" do + app_file "app/controllers/omg_controller.rb", <<-RUBY + begin + class OmgController < ActionController::Metal + ActiveSupport.run_load_hooks(:action_controller, self) + def show + self.response_body = ["OK"] + end + end + rescue => e + puts "Error loading metal: \#{e.class} \#{e.message}" + end + RUBY + + app_file "config/routes.rb", <<-RUBY + AppTemplate::Application.routes.draw do + get "/:controller(/:action)" + end + RUBY + + require "#{rails_root}/config/environment" + + require 'rack/test' + extend Rack::Test::Methods + + get '/omg/show' + assert_equal 'OK', last_response.body + end + + def test_initialize_can_be_called_at_any_time + require "#{app_path}/config/application" + + assert !Rails.initialized? + assert !AppTemplate::Application.initialized? + Rails.initialize! + assert Rails.initialized? + assert AppTemplate::Application.initialized? + end + protected def setup_ar! diff --git a/railties/test/application/middleware/cache_test.rb b/railties/test/application/middleware/cache_test.rb index 561b020707..19d3f3a397 100644 --- a/railties/test/application/middleware/cache_test.rb +++ b/railties/test/application/middleware/cache_test.rb @@ -1,7 +1,7 @@ require 'isolation/abstract_unit' module ApplicationTests - class RoutingTest < ActiveSupport::TestCase + class CacheTest < ActiveSupport::TestCase include ActiveSupport::Testing::Isolation def setup @@ -46,7 +46,7 @@ module ApplicationTests app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match ':controller(/:action)' + get ':controller(/:action)' end RUBY end diff --git a/railties/test/application/middleware/exceptions_test.rb b/railties/test/application/middleware/exceptions_test.rb index a80898092d..42096cfec4 100644 --- a/railties/test/application/middleware/exceptions_test.rb +++ b/railties/test/application/middleware/exceptions_test.rb @@ -17,31 +17,32 @@ module ApplicationTests end test "show exceptions middleware filter backtrace before logging" do - my_middleware = Struct.new(:app) do - def call(env) - raise "Failure" + controller :foo, <<-RUBY + class FooController < ActionController::Base + def index + raise 'oops' + end end - end - - app.config.middleware.use my_middleware + RUBY - stringio = StringIO.new - Rails.logger = Logger.new(stringio) + get "/foo" + assert_equal 500, last_response.status - get "/" - assert_no_match(/action_dispatch/, stringio.string) + log = File.read(Rails.application.config.paths["log"].first) + assert_no_match(/action_dispatch/, log, log) + assert_match(/oops/, log, log) end test "renders active record exceptions as 404" do - my_middleware = Struct.new(:app) do - def call(env) - raise ActiveRecord::RecordNotFound + controller :foo, <<-RUBY + class FooController < ActionController::Base + def index + raise ActiveRecord::RecordNotFound + end end - end - - app.config.middleware.use my_middleware + RUBY - get "/" + get "/foo" assert_equal 404, last_response.status end @@ -87,9 +88,6 @@ module ApplicationTests end test "displays diagnostics message when exception raised in template that contains UTF-8" do - app.config.action_dispatch.show_exceptions = true - app.config.consider_all_requests_local = true - controller :foo, <<-RUBY class FooController < ActionController::Base def index @@ -97,18 +95,15 @@ module ApplicationTests end RUBY + app.config.action_dispatch.show_exceptions = true + app.config.consider_all_requests_local = true + app_file 'app/views/foo/index.html.erb', <<-ERB <% raise 'boooom' %> ✓測試テスト시험 ERB - app_file 'config/routes.rb', <<-RUBY - AppTemplate::Application.routes.draw do - match ':controller(/:action)' - end - RUBY - - post '/foo', :utf8 => '✓' + get '/foo', :utf8 => '✓' assert_match(/boooom/, last_response.body) assert_match(/測試テスト시험/, last_response.body) end diff --git a/railties/test/application/middleware/remote_ip_test.rb b/railties/test/application/middleware/remote_ip_test.rb index 066f0c1c84..9d97bae9ae 100644 --- a/railties/test/application/middleware/remote_ip_test.rb +++ b/railties/test/application/middleware/remote_ip_test.rb @@ -4,20 +4,6 @@ module ApplicationTests class RemoteIpTest < ActiveSupport::TestCase include ActiveSupport::Testing::Isolation - def setup - build_app - boot_rails - FileUtils.rm_rf "#{app_path}/config/environments" - end - - def teardown - teardown_app - end - - def app - @app ||= Rails.application - end - def remote_ip(env = {}) remote_ip = nil env = Rack::MockRequest.env_for("/").merge(env).merge!( diff --git a/railties/test/application/middleware/sendfile_test.rb b/railties/test/application/middleware/sendfile_test.rb index 0591386a87..eb791f5687 100644 --- a/railties/test/application/middleware/sendfile_test.rb +++ b/railties/test/application/middleware/sendfile_test.rb @@ -57,5 +57,18 @@ module ApplicationTests get "/" assert_equal File.expand_path(__FILE__), last_response.headers["X-Lighttpd-Send-File"] end + + test "files handled by ActionDispatch::Static are handled by Rack::Sendfile" do + make_basic_app do |app| + app.config.action_dispatch.x_sendfile_header = 'X-Sendfile' + app.config.serve_static_assets = true + app.paths["public"] = File.join(rails_root, "public") + end + + app_file "public/foo.txt", "foo" + + get "/foo.txt", "HTTP_X_SENDFILE_TYPE" => "X-Sendfile" + assert_equal File.join(rails_root, "public/foo.txt"), last_response.headers["X-Sendfile"] + end end end diff --git a/railties/test/application/middleware/session_test.rb b/railties/test/application/middleware/session_test.rb index f4e77ee244..07134cc935 100644 --- a/railties/test/application/middleware/session_test.rb +++ b/railties/test/application/middleware/session_test.rb @@ -26,5 +26,25 @@ module ApplicationTests require "#{app_path}/config/environment" assert app.config.session_options[:secure], "Expected session to be marked as secure" end + + test "session is not loaded if it's not used" do + make_basic_app + + class ::OmgController < ActionController::Base + def index + if params[:flash] + flash[:notice] = "notice" + end + + render :nothing => true + end + end + + get "/?flash=true" + get "/" + + assert last_request.env["HTTP_COOKIE"] + assert !last_response.headers["Set-Cookie"] + end end end diff --git a/railties/test/application/middleware_test.rb b/railties/test/application/middleware_test.rb index d0a550d2f0..3e096e99f2 100644 --- a/railties/test/application/middleware_test.rb +++ b/railties/test/application/middleware_test.rb @@ -1,6 +1,4 @@ require 'isolation/abstract_unit' -require 'stringio' -require 'rack/test' module ApplicationTests class MiddlewareTest < ActiveSupport::TestCase @@ -26,6 +24,7 @@ module ApplicationTests boot! assert_equal [ + "Rack::Sendfile", "ActionDispatch::Static", "Rack::Lock", "ActiveSupport::Cache::Strategy::LocalCache", @@ -36,7 +35,6 @@ module ApplicationTests "ActionDispatch::ShowExceptions", "ActionDispatch::DebugExceptions", "ActionDispatch::RemoteIp", - "Rack::Sendfile", "ActionDispatch::Reloader", "ActionDispatch::Callbacks", "ActiveRecord::ConnectionAdapters::ConnectionManagement", @@ -45,7 +43,7 @@ module ApplicationTests "ActionDispatch::Session::CookieStore", "ActionDispatch::Flash", "ActionDispatch::ParamsParser", - "ActionDispatch::Head", + "Rack::Head", "Rack::ConditionalGet", "Rack::ETag", "ActionDispatch::BestStandardsSupport" @@ -66,13 +64,13 @@ module ApplicationTests assert_equal "Rack::Cache", middleware.first end - test "Rack::SSL is present when force_ssl is set" do + test "ActionDispatch::SSL is present when force_ssl is set" do add_to_config "config.force_ssl = true" boot! - assert middleware.include?("Rack::SSL") + assert middleware.include?("ActionDispatch::SSL") end - test "Rack::SSL is configured with options when given" do + test "ActionDispatch::SSL is configured with options when given" do add_to_config "config.force_ssl = true" add_to_config "config.ssl_options = { :host => 'example.com' }" boot! @@ -85,11 +83,10 @@ module ApplicationTests boot! assert !middleware.include?("ActiveRecord::ConnectionAdapters::ConnectionManagement") assert !middleware.include?("ActiveRecord::QueryCache") - assert !middleware.include?("ActiveRecord::IdentityMap::Middleware") end - test "removes lock if allow concurrency is set" do - add_to_config "config.allow_concurrency = true" + test "removes lock if cache classes is set" do + add_to_config "config.cache_classes = true" boot! assert !middleware.include?("Rack::Lock") end @@ -143,18 +140,19 @@ module ApplicationTests assert_equal "Rack::Runtime", middleware.fourth end - test "identity map is inserted" do - add_to_config "config.active_record.identity_map = true" - boot! - assert middleware.include?("ActiveRecord::IdentityMap::Middleware") - end - test "insert middleware before" do add_to_config "config.middleware.insert_before ActionDispatch::Static, Rack::Config" boot! assert_equal "Rack::Config", middleware.first end + test "can't change middleware after it's built" do + boot! + assert_raise RuntimeError do + app.config.middleware.use Rack::Config + end + end + # ConditionalGet + Etag test "conditional get + etag middlewares handle http caching based on body" do make_basic_app @@ -186,7 +184,6 @@ module ApplicationTests assert_equal etag, last_response.headers["Etag"] get "/?nothing=true" - puts last_response.body assert_equal 200, last_response.status assert_equal "", last_response.body assert_equal "text/html; charset=utf-8", last_response.headers["Content-Type"] diff --git a/railties/test/application/queue_test.rb b/railties/test/application/queue_test.rb new file mode 100644 index 0000000000..c856089540 --- /dev/null +++ b/railties/test/application/queue_test.rb @@ -0,0 +1,189 @@ +require 'isolation/abstract_unit' + +module ApplicationTests + class QueueTest < ActiveSupport::TestCase + include ActiveSupport::Testing::Isolation + + def setup + build_app + boot_rails + end + + def teardown + teardown_app + end + + def app_const + @app_const ||= Class.new(Rails::Application) + end + + test "the queue is a TestQueue in test mode" do + app("test") + assert_kind_of Rails::Queueing::TestQueue, Rails.application.queue[:default] + assert_kind_of Rails::Queueing::TestQueue, Rails.queue[:default] + end + + test "the queue is a Queue in development mode" do + app("development") + assert_kind_of Rails::Queueing::Queue, Rails.application.queue[:default] + assert_kind_of Rails::Queueing::Queue, Rails.queue[:default] + end + + class ThreadTrackingJob + def initialize + @origin = Thread.current.object_id + end + + def run + @target = Thread.current.object_id + end + + def ran_in_different_thread? + @origin != @target + end + + def ran? + @target + end + end + + test "in development mode, an enqueued job will be processed in a separate thread" do + app("development") + + job = ThreadTrackingJob.new + Rails.queue.push job + sleep 0.1 + + assert job.ran?, "Expected job to be run" + assert job.ran_in_different_thread?, "Expected job to run in a different thread" + end + + test "in test mode, explicitly draining the queue will process it in a separate thread" do + app("test") + + Rails.queue.push ThreadTrackingJob.new + job = Rails.queue.jobs.last + Rails.queue.drain + + assert job.ran?, "Expected job to be run" + assert job.ran_in_different_thread?, "Expected job to run in a different thread" + end + + class IdentifiableJob + def initialize(id) + @id = id + end + + def ==(other) + other.same_id?(@id) + end + + def same_id?(other_id) + other_id == @id + end + + def run + end + end + + test "in test mode, the queue can be observed" do + app("test") + + jobs = (1..10).map do |id| + IdentifiableJob.new(id) + end + + jobs.each do |job| + Rails.queue.push job + end + + assert_equal jobs, Rails.queue.jobs + end + + test "in test mode, adding an unmarshallable job will raise an exception" do + app("test") + anonymous_class_instance = Struct.new(:run).new + assert_raises TypeError do + Rails.queue.push anonymous_class_instance + end + end + + test "attempting to marshal a queue will raise an exception" do + app("test") + assert_raises TypeError do + Marshal.dump Rails.queue + end + end + + test "attempting to add a reference to itself to the queue will raise an exception" do + app("test") + job = {reference: Rails.queue} + assert_raises TypeError do + Rails.queue.push job + end + end + + def setup_custom_queue + add_to_env_config "production", <<-RUBY + require "my_queue" + config.queue = MyQueue + RUBY + + app_file "lib/my_queue.rb", <<-RUBY + class MyQueue + def push(job) + job.run + end + end + RUBY + + app("production") + end + + test "a custom queue implementation can be provided" do + setup_custom_queue + + assert_kind_of MyQueue, Rails.queue[:default] + + job = Struct.new(:id, :ran) do + def run + self.ran = true + end + end + + job1 = job.new(1) + Rails.queue.push job1 + + assert_equal true, job1.ran + end + + test "a custom consumer implementation can be provided" do + add_to_env_config "production", <<-RUBY + require "my_queue_consumer" + config.queue_consumer = MyQueueConsumer + RUBY + + app_file "lib/my_queue_consumer.rb", <<-RUBY + class MyQueueConsumer < Rails::Queueing::ThreadedConsumer + attr_reader :started + + def start + @started = true + self + end + end + RUBY + + app("production") + + assert_kind_of MyQueueConsumer, Rails.application.queue_consumer + assert Rails.application.queue_consumer.started + end + + test "default consumer is not used with custom queue implementation" do + setup_custom_queue + + assert_nil Rails.application.queue_consumer + end + end +end diff --git a/railties/test/application/rack/logger_test.rb b/railties/test/application/rack/logger_test.rb index a77c6f472c..2f5bd3a764 100644 --- a/railties/test/application/rack/logger_test.rb +++ b/railties/test/application/rack/logger_test.rb @@ -5,6 +5,7 @@ require "rack/test" module ApplicationTests module RackTests class LoggerTest < ActiveSupport::TestCase + include ActiveSupport::Testing::Isolation include ActiveSupport::LogSubscriber::TestHelper include Rack::Test::Methods @@ -17,6 +18,7 @@ module ApplicationTests end def teardown + super teardown_app end @@ -24,12 +26,18 @@ module ApplicationTests @logs ||= @logger.logged(:info) end - test "logger logs proper HTTP verb and path" do + test "logger logs proper HTTP GET verb and path" do get "/blah" wait assert_match(/^Started GET "\/blah"/, logs[0]) end + test "logger logs proper HTTP HEAD verb and path" do + head "/blah" + wait + assert_match(/^Started HEAD "\/blah"/, logs[0]) + end + test "logger logs HTTP verb override" do post "/", {:_method => 'put'} wait diff --git a/railties/test/application/rake/migrations_test.rb b/railties/test/application/rake/migrations_test.rb index 301e516192..0a47fd014c 100644 --- a/railties/test/application/rake/migrations_test.rb +++ b/railties/test/application/rake/migrations_test.rb @@ -16,44 +16,45 @@ module ApplicationTests test 'running migrations with given scope' do Dir.chdir(app_path) do `rails generate model user username:string password:string` - end - app_file "db/migrate/01_a_migration.bukkits.rb", <<-MIGRATION - class AMigration < ActiveRecord::Migration - end - MIGRATION - output = Dir.chdir(app_path) { `rake db:migrate SCOPE=bukkits` } - assert_no_match(/create_table\(:users\)/, output) - assert_no_match(/CreateUsers/, output) - assert_no_match(/add_column\(:users, :email, :string\)/, output) + app_file "db/migrate/01_a_migration.bukkits.rb", <<-MIGRATION + class AMigration < ActiveRecord::Migration + end + MIGRATION + + output = `rake db:migrate SCOPE=bukkits` + assert_no_match(/create_table\(:users\)/, output) + assert_no_match(/CreateUsers/, output) + assert_no_match(/add_column\(:users, :email, :string\)/, output) - assert_match(/AMigration: migrated/, output) + assert_match(/AMigration: migrated/, output) - output = Dir.chdir(app_path) { `rake db:migrate SCOPE=bukkits VERSION=0` } - assert_no_match(/drop_table\(:users\)/, output) - assert_no_match(/CreateUsers/, output) - assert_no_match(/remove_column\(:users, :email\)/, output) + output = `rake db:migrate SCOPE=bukkits VERSION=0` + assert_no_match(/drop_table\(:users\)/, output) + assert_no_match(/CreateUsers/, output) + assert_no_match(/remove_column\(:users, :email\)/, output) - assert_match(/AMigration: reverted/, output) + assert_match(/AMigration: reverted/, output) + end end test 'model and migration generator with change syntax' do Dir.chdir(app_path) do - `rails generate model user username:string password:string` - `rails generate migration add_email_to_users email:string` + `rails generate model user username:string password:string; + rails generate migration add_email_to_users email:string` + + output = `rake db:migrate` + assert_match(/create_table\(:users\)/, output) + assert_match(/CreateUsers: migrated/, output) + assert_match(/add_column\(:users, :email, :string\)/, output) + assert_match(/AddEmailToUsers: migrated/, output) + + output = `rake db:rollback STEP=2` + assert_match(/drop_table\("users"\)/, output) + assert_match(/CreateUsers: reverted/, output) + assert_match(/remove_column\("users", :email\)/, output) + assert_match(/AddEmailToUsers: reverted/, output) end - - output = Dir.chdir(app_path){ `rake db:migrate` } - assert_match(/create_table\(:users\)/, output) - assert_match(/CreateUsers: migrated/, output) - assert_match(/add_column\(:users, :email, :string\)/, output) - assert_match(/AddEmailToUsers: migrated/, output) - - output = Dir.chdir(app_path){ `rake db:rollback STEP=2` } - assert_match(/drop_table\("users"\)/, output) - assert_match(/CreateUsers: reverted/, output) - assert_match(/remove_column\("users", :email\)/, output) - assert_match(/AddEmailToUsers: reverted/, output) end test 'migration status when schema migrations table is not present' do @@ -63,46 +64,94 @@ module ApplicationTests test 'test migration status' do Dir.chdir(app_path) do - `rails generate model user username:string password:string` - `rails generate migration add_email_to_users email:string` + `rails generate model user username:string password:string; + rails generate migration add_email_to_users email:string; + rake db:migrate` + + output = `rake db:migrate:status` + + assert_match(/up\s+\d{14}\s+Create users/, output) + assert_match(/up\s+\d{14}\s+Add email to users/, output) + + `rake db:rollback STEP=1` + output = `rake db:migrate:status` + + assert_match(/up\s+\d{14}\s+Create users/, output) + assert_match(/down\s+\d{14}\s+Add email to users/, output) end + end + + test 'migration status without timestamps' do + add_to_config('config.active_record.timestamped_migrations = false') + + Dir.chdir(app_path) do + `rails generate model user username:string password:string; + rails generate migration add_email_to_users email:string; + rake db:migrate` - Dir.chdir(app_path) { `rake db:migrate`} - output = Dir.chdir(app_path) { `rake db:migrate:status` } + output = `rake db:migrate:status` - assert_match(/up\s+\d{14}\s+Create users/, output) - assert_match(/up\s+\d{14}\s+Add email to users/, output) + assert_match(/up\s+\d{3,}\s+Create users/, output) + assert_match(/up\s+\d{3,}\s+Add email to users/, output) - Dir.chdir(app_path) { `rake db:rollback STEP=1` } - output = Dir.chdir(app_path) { `rake db:migrate:status` } + `rake db:rollback STEP=1` + output = `rake db:migrate:status` - assert_match(/up\s+\d{14}\s+Create users/, output) - assert_match(/down\s+\d{14}\s+Add email to users/, output) + assert_match(/up\s+\d{3,}\s+Create users/, output) + assert_match(/down\s+\d{3,}\s+Add email to users/, output) + end end test 'test migration status after rollback and redo' do Dir.chdir(app_path) do - `rails generate model user username:string password:string` - `rails generate migration add_email_to_users email:string` + `rails generate model user username:string password:string; + rails generate migration add_email_to_users email:string; + rake db:migrate` + + output = `rake db:migrate:status` + + assert_match(/up\s+\d{14}\s+Create users/, output) + assert_match(/up\s+\d{14}\s+Add email to users/, output) + + `rake db:rollback STEP=2` + output = `rake db:migrate:status` + + assert_match(/down\s+\d{14}\s+Create users/, output) + assert_match(/down\s+\d{14}\s+Add email to users/, output) + + `rake db:migrate:redo` + output = `rake db:migrate:status` + + assert_match(/up\s+\d{14}\s+Create users/, output) + assert_match(/up\s+\d{14}\s+Add email to users/, output) end + end + + test 'migration status after rollback and redo without timestamps' do + add_to_config('config.active_record.timestamped_migrations = false') - Dir.chdir(app_path) { `rake db:migrate` } - output = Dir.chdir(app_path) { `rake db:migrate:status` } + Dir.chdir(app_path) do + `rails generate model user username:string password:string; + rails generate migration add_email_to_users email:string; + rake db:migrate` + + output = `rake db:migrate:status` - assert_match(/up\s+\d{14}\s+Create users/, output) - assert_match(/up\s+\d{14}\s+Add email to users/, output) + assert_match(/up\s+\d{3,}\s+Create users/, output) + assert_match(/up\s+\d{3,}\s+Add email to users/, output) - Dir.chdir(app_path) { `rake db:rollback STEP=2` } - output = Dir.chdir(app_path) { `rake db:migrate:status` } + `rake db:rollback STEP=2` + output = `rake db:migrate:status` - assert_match(/down\s+\d{14}\s+Create users/, output) - assert_match(/down\s+\d{14}\s+Add email to users/, output) + assert_match(/down\s+\d{3,}\s+Create users/, output) + assert_match(/down\s+\d{3,}\s+Add email to users/, output) - Dir.chdir(app_path) { `rake db:migrate:redo` } - output = Dir.chdir(app_path) { `rake db:migrate:status` } + `rake db:migrate:redo` + output = `rake db:migrate:status` - assert_match(/up\s+\d{14}\s+Create users/, output) - assert_match(/up\s+\d{14}\s+Add email to users/, output) + assert_match(/up\s+\d{3,}\s+Create users/, output) + assert_match(/up\s+\d{3,}\s+Add email to users/, output) + end end end end diff --git a/railties/test/application/rake/notes_test.rb b/railties/test/application/rake/notes_test.rb index 4ab20afc47..27de75b63b 100644 --- a/railties/test/application/rake/notes_test.rb +++ b/railties/test/application/rake/notes_test.rb @@ -3,21 +3,27 @@ require "isolation/abstract_unit" module ApplicationTests module RakeTests class RakeNotesTest < ActiveSupport::TestCase - def setup + include ActiveSupport::Testing::Isolation + + def setup build_app require "rails/all" + super end def teardown + super teardown_app end - test 'notes' do - + test 'notes finds notes for certain file_types' do app_file "app/views/home/index.html.erb", "<% # TODO: note in erb %>" app_file "app/views/home/index.html.haml", "-# TODO: note in haml" app_file "app/views/home/index.html.slim", "/ TODO: note in slim" app_file "app/assets/javascripts/application.js.coffee", "# TODO: note in coffee" + app_file "app/assets/javascripts/application.js", "// TODO: note in js" + app_file "app/assets/stylesheets/application.css", "// TODO: note in css" + app_file "app/assets/stylesheets/application.css.scss", "// TODO: note in scss" app_file "app/controllers/application_controller.rb", 1000.times.map { "" }.join("\n") << "# TODO: note in ruby" boot_rails @@ -29,13 +35,53 @@ module ApplicationTests Dir.chdir(app_path) do output = `bundle exec rake notes` + lines = output.scan(/\[([0-9\s]+)\](\s)/) + + assert_match(/note in erb/, output) + assert_match(/note in haml/, output) + assert_match(/note in slim/, output) + assert_match(/note in ruby/, output) + assert_match(/note in coffee/, output) + assert_match(/note in js/, output) + assert_match(/note in css/, output) + assert_match(/note in scss/, output) + + assert_equal 8, lines.size + + lines.each do |line| + assert_equal 4, line[0].size + assert_equal ' ', line[1] + end + end + end + + test 'notes finds notes in default directories' do + app_file "app/controllers/some_controller.rb", "# TODO: note in app directory" + app_file "config/initializers/some_initializer.rb", "# TODO: note in config directory" + app_file "lib/some_file.rb", "# TODO: note in lib directory" + app_file "script/run_something.rb", "# TODO: note in script directory" + app_file "test/some_test.rb", 1000.times.map { "" }.join("\n") << "# TODO: note in test directory" + + app_file "some_other_dir/blah.rb", "# TODO: note in some_other directory" + + boot_rails + + require 'rake' + require 'rdoc/task' + require 'rake/testtask' + + Rails.application.load_tasks + + Dir.chdir(app_path) do + output = `bundle exec rake notes` lines = output.scan(/\[([0-9\s]+)\]/).flatten - assert_match /note in erb/, output - assert_match /note in haml/, output - assert_match /note in slim/, output - assert_match /note in ruby/, output - assert_match /note in coffee/, output + assert_match(/note in app directory/, output) + assert_match(/note in config directory/, output) + assert_match(/note in lib directory/, output) + assert_match(/note in script directory/, output) + assert_match(/note in test directory/, output) + assert_no_match(/note in some_other directory/, output) assert_equal 5, lines.size @@ -43,7 +89,43 @@ module ApplicationTests assert_equal 4, line_number.size end end + end + + test 'notes finds notes in custom directories' do + app_file "app/controllers/some_controller.rb", "# TODO: note in app directory" + app_file "config/initializers/some_initializer.rb", "# TODO: note in config directory" + app_file "lib/some_file.rb", "# TODO: note in lib directory" + app_file "script/run_something.rb", "# TODO: note in script directory" + app_file "test/some_test.rb", 1000.times.map { "" }.join("\n") << "# TODO: note in test directory" + + app_file "some_other_dir/blah.rb", "# TODO: note in some_other directory" + + boot_rails + + require 'rake' + require 'rdoc/task' + require 'rake/testtask' + + Rails.application.load_tasks + + Dir.chdir(app_path) do + output = `SOURCE_ANNOTATION_DIRECTORIES='some_other_dir' bundle exec rake notes` + lines = output.scan(/\[([0-9\s]+)\]/).flatten + + assert_match(/note in app directory/, output) + assert_match(/note in config directory/, output) + assert_match(/note in lib directory/, output) + assert_match(/note in script directory/, output) + assert_match(/note in test directory/, output) + + assert_match(/note in some_other directory/, output) + assert_equal 6, lines.size + + lines.each do |line_number| + assert_equal 4, line_number.size + end + end end private diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb index ff12b3e9fc..b05fe3aed5 100644 --- a/railties/test/application/rake_test.rb +++ b/railties/test/application/rake_test.rb @@ -55,6 +55,29 @@ module ApplicationTests assert_match "Doing something...", output end + def test_does_not_explode_when_accessing_a_model_with_eager_load + add_to_config <<-RUBY + config.eager_load = true + + rake_tasks do + task :do_nothing => :environment do + Hello.new.world + end + end + RUBY + + app_file "app/models/hello.rb", <<-RUBY + class Hello + def world + puts "Hello world" + end + end + RUBY + + output = Dir.chdir(app_path){ `rake do_nothing` } + assert_match "Hello world", output + end + def test_code_statistics_sanity assert_match "Code LOC: 5 Test LOC: 0 Code to Test Ratio: 1:0.0", Dir.chdir(app_path){ `rake stats` } @@ -107,9 +130,9 @@ module ApplicationTests def test_loading_specific_fixtures Dir.chdir(app_path) do - `rails generate model user username:string password:string` - `rails generate model product name:string` - `rake db:migrate` + `rails generate model user username:string password:string; + rails generate model product name:string; + rake db:migrate` end require "#{rails_root}/config/environment" @@ -122,21 +145,114 @@ module ApplicationTests assert_equal 0, ::AppTemplate::Application::User.count end + def test_loading_only_yml_fixtures + Dir.chdir(app_path) do + `rake db:migrate` + end + + app_file "test/fixtures/products.csv", "" + + require "#{rails_root}/config/environment" + errormsg = Dir.chdir(app_path) { `rake db:fixtures:load` } + assert $?.success?, errormsg + end + def test_scaffold_tests_pass_by_default - content = Dir.chdir(app_path) do - `rails generate scaffold user username:string password:string` - `bundle exec rake db:migrate db:test:clone test` + output = Dir.chdir(app_path) do + `rails generate scaffold user username:string password:string; + bundle exec rake db:migrate db:test:clone test` end - assert_match(/\d+ tests, \d+ assertions, 0 failures, 0 errors/, content) + assert_match(/7 tests, 13 assertions, 0 failures, 0 errors/, output) + assert_no_match(/Errors running/, output) + end + + def test_db_test_clone_when_using_sql_format + add_to_config "config.active_record.schema_format = :sql" + output = Dir.chdir(app_path) do + `rails generate scaffold user username:string; + bundle exec rake db:migrate db:test:clone 2>&1 --trace` + end + assert_match(/Execute db:test:clone_structure/, output) + end + + def test_db_test_prepare_when_using_sql_format + add_to_config "config.active_record.schema_format = :sql" + output = Dir.chdir(app_path) do + `rails generate scaffold user username:string; + bundle exec rake db:migrate db:test:prepare 2>&1 --trace` + end + assert_match(/Execute db:test:load_structure/, output) end def test_rake_dump_structure_should_respect_db_structure_env_variable Dir.chdir(app_path) do - `bundle exec rake db:migrate` # ensure we have a schema_migrations table to dump - `bundle exec rake db:structure:dump DB_STRUCTURE=db/my_structure.sql` + # ensure we have a schema_migrations table to dump + `bundle exec rake db:migrate db:structure:dump DB_STRUCTURE=db/my_structure.sql` end assert File.exists?(File.join(app_path, 'db', 'my_structure.sql')) end + + def test_rake_dump_structure_should_be_called_twice_when_migrate_redo + add_to_config "config.active_record.schema_format = :sql" + + output = Dir.chdir(app_path) do + `rails g model post title:string; + bundle exec rake db:migrate:redo 2>&1 --trace;` + end + + # expect only Invoke db:structure:dump (first_time) + assert_no_match(/^\*\* Invoke db:structure:dump\s+$/, output) + end + + def test_rake_dump_schema_cache + Dir.chdir(app_path) do + `rails generate model post title:string; + rails generate model product name:string; + bundle exec rake db:migrate db:schema:cache:dump` + end + assert File.exists?(File.join(app_path, 'db', 'schema_cache.dump')) + end + + def test_rake_clear_schema_cache + Dir.chdir(app_path) do + `bundle exec rake db:schema:cache:dump db:schema:cache:clear` + end + assert !File.exists?(File.join(app_path, 'db', 'schema_cache.dump')) + end + + def test_load_activerecord_base_when_we_use_observers + Dir.chdir(app_path) do + `bundle exec rails g model user; + bundle exec rake db:migrate; + bundle exec rails g observer user;` + + add_to_config "config.active_record.observers = :user_observer" + + assert_equal "0", `bundle exec rails r "puts User.count"`.strip + + app_file "lib/tasks/count_user.rake", <<-RUBY + namespace :user do + task :count => :environment do + puts User.count + end + end + RUBY + + assert_equal "0", `bundle exec rake user:count`.strip + end + end + + def test_copy_templates + Dir.chdir(app_path) do + `bundle exec rake rails:templates:copy` + %w(controller mailer scaffold).each do |dir| + assert File.exists?(File.join(app_path, 'lib', 'templates', 'erb', dir)) + end + %w(controller helper scaffold_controller assets).each do |dir| + assert File.exists?(File.join(app_path, 'lib', 'templates', 'rails', dir)) + end + end + end end end diff --git a/railties/test/application/route_inspect_test.rb b/railties/test/application/route_inspect_test.rb deleted file mode 100644 index 7c0a379112..0000000000 --- a/railties/test/application/route_inspect_test.rb +++ /dev/null @@ -1,162 +0,0 @@ -require 'minitest/autorun' -require 'rails/application/route_inspector' -require 'action_controller' -require 'rails/engine' - -module ApplicationTests - class RouteInspectTest < ActiveSupport::TestCase - def setup - @set = ActionDispatch::Routing::RouteSet.new - @inspector = Rails::Application::RouteInspector.new - app = ActiveSupport::OrderedOptions.new - app.config = ActiveSupport::OrderedOptions.new - app.config.assets = ActiveSupport::OrderedOptions.new - app.config.assets.prefix = '/sprockets' - Rails.stubs(:application).returns(app) - end - - def test_displaying_routes_for_engines - engine = Class.new(Rails::Engine) do - def self.to_s - "Blog::Engine" - end - end - engine.routes.draw do - get '/cart', :to => 'cart#show' - end - - @set.draw do - get '/custom/assets', :to => 'custom_assets#show' - mount engine => "/blog", :as => "blog" - end - - output = @inspector.format @set.routes - expected = [ - "custom_assets GET /custom/assets(.:format) custom_assets#show", - " blog /blog Blog::Engine", - "\nRoutes for Blog::Engine:", - "cart GET /cart(.:format) cart#show" - ] - assert_equal expected, output - end - - def test_cart_inspect - @set.draw do - get '/cart', :to => 'cart#show' - end - output = @inspector.format @set.routes - assert_equal ["cart GET /cart(.:format) cart#show"], output - end - - def test_inspect_shows_custom_assets - @set.draw do - get '/custom/assets', :to => 'custom_assets#show' - end - output = @inspector.format @set.routes - assert_equal ["custom_assets GET /custom/assets(.:format) custom_assets#show"], output - end - - def test_inspect_routes_shows_resources_route - @set.draw do - resources :articles - end - output = @inspector.format @set.routes - expected = [ - " articles GET /articles(.:format) articles#index", - " POST /articles(.:format) articles#create", - " new_article GET /articles/new(.:format) articles#new", - "edit_article GET /articles/:id/edit(.:format) articles#edit", - " article GET /articles/:id(.:format) articles#show", - " PUT /articles/:id(.:format) articles#update", - " DELETE /articles/:id(.:format) articles#destroy" ] - assert_equal expected, output - end - - def test_inspect_routes_shows_root_route - @set.draw do - root :to => 'pages#main' - end - output = @inspector.format @set.routes - assert_equal ["root / pages#main"], output - end - - def test_inspect_routes_shows_dynamic_action_route - @set.draw do - match 'api/:action' => 'api' - end - output = @inspector.format @set.routes - assert_equal [" /api/:action(.:format) api#:action"], output - end - - def test_inspect_routes_shows_controller_and_action_only_route - @set.draw do - match ':controller/:action' - end - output = @inspector.format @set.routes - assert_equal [" /:controller/:action(.:format) :controller#:action"], output - end - - def test_inspect_routes_shows_controller_and_action_route_with_constraints - @set.draw do - match ':controller(/:action(/:id))', :id => /\d+/ - end - output = @inspector.format @set.routes - assert_equal [" /:controller(/:action(/:id))(.:format) :controller#:action {:id=>/\\d+/}"], output - end - - def test_rake_routes_shows_route_with_defaults - @set.draw do - match 'photos/:id' => 'photos#show', :defaults => {:format => 'jpg'} - end - output = @inspector.format @set.routes - assert_equal [%Q[ /photos/:id(.:format) photos#show {:format=>"jpg"}]], output - end - - def test_rake_routes_shows_route_with_constraints - @set.draw do - match 'photos/:id' => 'photos#show', :id => /[A-Z]\d{5}/ - end - output = @inspector.format @set.routes - assert_equal [" /photos/:id(.:format) photos#show {:id=>/[A-Z]\\d{5}/}"], output - end - - class RackApp - def self.call(env) - end - end - - def test_rake_routes_shows_route_with_rack_app - @set.draw do - match 'foo/:id' => RackApp, :id => /[A-Z]\d{5}/ - end - output = @inspector.format @set.routes - assert_equal [" /foo/:id(.:format) #{RackApp.name} {:id=>/[A-Z]\\d{5}/}"], output - end - - def test_rake_routes_shows_route_with_rack_app_nested_with_dynamic_constraints - constraint = Class.new do - def to_s - "( my custom constraint )" - end - end - - @set.draw do - scope :constraint => constraint.new do - mount RackApp => '/foo' - end - end - - output = @inspector.format @set.routes - assert_equal [" /foo #{RackApp.name} {:constraint=>( my custom constraint )}"], output - end - - def test_rake_routes_dont_show_app_mounted_in_assets_prefix - @set.draw do - match '/sprockets' => RackApp - end - output = @inspector.format @set.routes - assert_no_match(/RackApp/, output.first) - assert_no_match(/\/sprockets/, output.first) - end - end -end diff --git a/railties/test/application/routing_test.rb b/railties/test/application/routing_test.rb index 28ce3beea9..396b1849d8 100644 --- a/railties/test/application/routing_test.rb +++ b/railties/test/application/routing_test.rb @@ -15,12 +15,24 @@ module ApplicationTests teardown_app end + test "rails/info/routes in development" do + app("development") + get "/rails/info/routes" + assert_equal 200, last_response.status + end + test "rails/info/properties in development" do app("development") get "/rails/info/properties" assert_equal 200, last_response.status end + test "rails/info/routes in production" do + app("production") + get "/rails/info/routes" + assert_equal 404, last_response.status + end + test "rails/info/properties in production" do app("production") get "/rails/info/properties" @@ -53,7 +65,7 @@ module ApplicationTests app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match ':controller(/:action)' + get ':controller(/:action)' end RUBY @@ -94,7 +106,7 @@ module ApplicationTests app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match ':controller(/:action)' + get ':controller(/:action)' end RUBY @@ -126,8 +138,8 @@ module ApplicationTests app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match 'admin/foo', :to => 'admin/foo#index' - match 'foo', :to => 'foo#index' + get 'admin/foo', :to => 'admin/foo#index' + get 'foo', :to => 'foo#index' end RUBY @@ -141,13 +153,13 @@ module ApplicationTests test "routes appending blocks" do app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match ':controller/:action' + get ':controller/:action' end RUBY add_to_config <<-R routes.append do - match '/win' => lambda { |e| [200, {'Content-Type'=>'text/plain'}, ['WIN']] } + get '/win' => lambda { |e| [200, {'Content-Type'=>'text/plain'}, ['WIN']] } end R @@ -158,7 +170,7 @@ module ApplicationTests app_file 'config/routes.rb', <<-R AppTemplate::Application.routes.draw do - match 'lol' => 'hello#index' + get 'lol' => 'hello#index' end R @@ -182,7 +194,7 @@ module ApplicationTests app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match 'foo', :to => 'foo#bar' + get 'foo', :to => 'foo#bar' end RUBY @@ -193,7 +205,7 @@ module ApplicationTests app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match 'foo', :to => 'foo#baz' + get 'foo', :to => 'foo#baz' end RUBY @@ -214,7 +226,7 @@ module ApplicationTests app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match 'foo', :to => ::InitializeRackApp + get 'foo', :to => ::InitializeRackApp end RUBY diff --git a/railties/test/application/runner_test.rb b/railties/test/application/runner_test.rb index e1d283a7fd..81ed5873a5 100644 --- a/railties/test/application/runner_test.rb +++ b/railties/test/application/runner_test.rb @@ -57,5 +57,15 @@ module ApplicationTests assert_match "script/program_name.rb", Dir.chdir(app_path) { `bundle exec rails runner "script/program_name.rb"` } end + + def test_with_hook + add_to_config <<-RUBY + runner do |app| + app.config.ran = true + end + RUBY + + assert_match "true", Dir.chdir(app_path) { `bundle exec rails runner "puts Rails.application.config.ran"` } + end end end diff --git a/railties/test/application/url_generation_test.rb b/railties/test/application/url_generation_test.rb index 85a8a15fcc..f7e60749a7 100644 --- a/railties/test/application/url_generation_test.rb +++ b/railties/test/application/url_generation_test.rb @@ -31,7 +31,7 @@ module ApplicationTests end MyApp.routes.draw do - match "/" => "omg#index", :as => :omg + get "/" => "omg#index", :as => :omg end require 'rack/test' diff --git a/railties/test/backtrace_cleaner_test.rb b/railties/test/backtrace_cleaner_test.rb index cbe7d35f6d..2dd74f8fd1 100644 --- a/railties/test/backtrace_cleaner_test.rb +++ b/railties/test/backtrace_cleaner_test.rb @@ -1,26 +1,24 @@ require 'abstract_unit' require 'rails/backtrace_cleaner' -if defined? Gem - class BacktraceCleanerVendorGemTest < ActiveSupport::TestCase - def setup - @cleaner = Rails::BacktraceCleaner.new - end +class BacktraceCleanerVendorGemTest < ActiveSupport::TestCase + def setup + @cleaner = Rails::BacktraceCleaner.new + end + + test "should format installed gems correctly" do + @backtrace = [ "#{Gem.path[0]}/gems/nosuchgem-1.2.3/lib/foo.rb" ] + @result = @cleaner.clean(@backtrace, :all) + assert_equal "nosuchgem (1.2.3) lib/foo.rb", @result[0] + end - test "should format installed gems correctly" do - @backtrace = [ "#{Gem.path[0]}/gems/nosuchgem-1.2.3/lib/foo.rb" ] + test "should format installed gems not in Gem.default_dir correctly" do + @target_dir = Gem.path.detect { |p| p != Gem.default_dir } + # skip this test if default_dir is the only directory on Gem.path + if @target_dir + @backtrace = [ "#{@target_dir}/gems/nosuchgem-1.2.3/lib/foo.rb" ] @result = @cleaner.clean(@backtrace, :all) assert_equal "nosuchgem (1.2.3) lib/foo.rb", @result[0] end - - test "should format installed gems not in Gem.default_dir correctly" do - @target_dir = Gem.path.detect { |p| p != Gem.default_dir } - # skip this test if default_dir is the only directory on Gem.path - if @target_dir - @backtrace = [ "#{@target_dir}/gems/nosuchgem-1.2.3/lib/foo.rb" ] - @result = @cleaner.clean(@backtrace, :all) - assert_equal "nosuchgem (1.2.3) lib/foo.rb", @result[0] - end - end end end diff --git a/railties/test/commands/console_test.rb b/railties/test/commands/console_test.rb new file mode 100644 index 0000000000..91ede1cb68 --- /dev/null +++ b/railties/test/commands/console_test.rb @@ -0,0 +1,137 @@ +require 'abstract_unit' +require 'rails/commands/console' + +class Rails::ConsoleTest < ActiveSupport::TestCase + class FakeConsole + def self.start; end + end + + def setup + end + + def test_sandbox_option + console = Rails::Console.new(app, parse_arguments(["--sandbox"])) + assert console.sandbox? + end + + def test_short_version_of_sandbox_option + console = Rails::Console.new(app, parse_arguments(["-s"])) + assert console.sandbox? + end + + def test_debugger_option + console = Rails::Console.new(app, parse_arguments(["--debugger"])) + assert console.debugger? + end + + def test_no_options + console = Rails::Console.new(app, parse_arguments([])) + assert !console.debugger? + assert !console.sandbox? + end + + def test_start + FakeConsole.expects(:start) + start + assert_match(/Loading \w+ environment \(Rails/, output) + end + + def test_start_with_debugger + rails_console = Rails::Console.new(app, parse_arguments(["--debugger"])) + rails_console.expects(:require_debugger).returns(nil) + + silence_stream(STDOUT) { rails_console.start } + end + + def test_start_with_sandbox + app.expects(:sandbox=).with(true) + FakeConsole.expects(:start) + + start ["--sandbox"] + + assert_match(/Loading \w+ environment in sandbox \(Rails/, output) + end + + def test_console_with_environment + start ["-e production"] + assert_match(/\sproduction\s/, output) + end + + def test_console_defaults_to_IRB + config = mock("config", :console => nil) + app = mock("app", :config => config) + app.expects(:load_console).returns(nil) + + assert_equal IRB, Rails::Console.new(app).console + end + + def test_default_environment_with_no_rails_env + with_rails_env nil do + start + assert_match /\sdevelopment\s/, output + end + end + + def test_default_environment_with_rails_env + with_rails_env 'special-production' do + start + assert_match /\sspecial-production\s/, output + end + end + + def test_e_option + start ['-e', 'special-production'] + assert_match /\sspecial-production\s/, output + end + + def test_environment_option + start ['--environment=special-production'] + assert_match /\sspecial-production\s/, output + end + + def test_rails_env_is_production_when_first_argument_is_p + start ['p'] + assert_match /\sproduction\s/, output + end + + def test_rails_env_is_test_when_first_argument_is_t + start ['t'] + assert_match /\stest\s/, output + end + + def test_rails_env_is_development_when_argument_is_d + start ['d'] + assert_match /\sdevelopment\s/, output + end + + private + + attr_reader :output + + def start(argv = []) + rails_console = Rails::Console.new(app, parse_arguments(argv)) + @output = output = capture(:stdout) { rails_console.start } + end + + def app + @app ||= begin + config = mock("config", :console => FakeConsole) + app = mock("app", :config => config) + app.stubs(:sandbox=).returns(nil) + app.expects(:load_console) + app + end + end + + def parse_arguments(args) + Rails::Console.parse_arguments(args) + end + + def with_rails_env(env) + original_rails_env = ENV['RAILS_ENV'] + ENV['RAILS_ENV'] = env + yield + ensure + ENV['RAILS_ENV'] = original_rails_env + end +end diff --git a/railties/test/commands/dbconsole_test.rb b/railties/test/commands/dbconsole_test.rb new file mode 100644 index 0000000000..d45bdaabf5 --- /dev/null +++ b/railties/test/commands/dbconsole_test.rb @@ -0,0 +1,185 @@ +require 'abstract_unit' +require 'rails/commands/dbconsole' + +class Rails::DBConsoleTest < ActiveSupport::TestCase + def teardown + %w[PGUSER PGHOST PGPORT PGPASSWORD].each{|key| ENV.delete(key)} + end + + def test_config + Rails::DBConsole.const_set(:APP_PATH, "erb") + + app_config({}) + capture_abort { Rails::DBConsole.new.config } + assert aborted + assert_match(/No database is configured for the environment '\w+'/, output) + + app_config(test: "with_init") + assert_equal Rails::DBConsole.new.config, "with_init" + + app_db_file("test:\n without_init") + assert_equal Rails::DBConsole.new.config, "without_init" + + app_db_file("test:\n <%= Rails.something_app_specific %>") + assert_equal Rails::DBConsole.new.config, "with_init" + + app_db_file("test:\n\ninvalid") + assert_equal Rails::DBConsole.new.config, "with_init" + end + + def test_env + assert_equal Rails::DBConsole.new.environment, "test" + + ENV['RAILS_ENV'] = nil + ENV['RACK_ENV'] = nil + + Rails.stubs(:respond_to?).with(:env).returns(false) + assert_equal Rails::DBConsole.new.environment, "development" + + ENV['RACK_ENV'] = "rack_env" + assert_equal Rails::DBConsole.new.environment, "rack_env" + + ENV['RAILS_ENV'] = "rails_env" + assert_equal Rails::DBConsole.new.environment, "rails_env" + ensure + ENV['RAILS_ENV'] = "test" + end + + def test_mysql + dbconsole.expects(:find_cmd_and_exec).with(%w[mysql mysql5], 'db') + start(adapter: 'mysql', database: 'db') + assert !aborted + end + + def test_mysql_full + dbconsole.expects(:find_cmd_and_exec).with(%w[mysql mysql5], '--host=locahost', '--port=1234', '--socket=socket', '--user=user', '--default-character-set=UTF-8', '-p', 'db') + start(adapter: 'mysql', database: 'db', host: 'locahost', port: 1234, socket: 'socket', username: 'user', password: 'qwerty', encoding: 'UTF-8') + assert !aborted + end + + def test_mysql_include_password + dbconsole.expects(:find_cmd_and_exec).with(%w[mysql mysql5], '--user=user', '--password=qwerty', 'db') + start({adapter: 'mysql', database: 'db', username: 'user', password: 'qwerty'}, ['-p']) + assert !aborted + end + + def test_postgresql + dbconsole.expects(:find_cmd_and_exec).with('psql', 'db') + start(adapter: 'postgresql', database: 'db') + assert !aborted + end + + def test_postgresql_full + dbconsole.expects(:find_cmd_and_exec).with('psql', 'db') + start(adapter: 'postgresql', database: 'db', username: 'user', password: 'q1w2e3', host: 'host', port: 5432) + assert !aborted + assert_equal 'user', ENV['PGUSER'] + assert_equal 'host', ENV['PGHOST'] + assert_equal '5432', ENV['PGPORT'] + assert_not_equal 'q1w2e3', ENV['PGPASSWORD'] + end + + def test_postgresql_include_password + dbconsole.expects(:find_cmd_and_exec).with('psql', 'db') + start({adapter: 'postgresql', database: 'db', username: 'user', password: 'q1w2e3'}, ['-p']) + assert !aborted + assert_equal 'user', ENV['PGUSER'] + assert_equal 'q1w2e3', ENV['PGPASSWORD'] + end + + def test_sqlite + dbconsole.expects(:find_cmd_and_exec).with('sqlite', 'db') + start(adapter: 'sqlite', database: 'db') + assert !aborted + end + + def test_sqlite3 + dbconsole.expects(:find_cmd_and_exec).with('sqlite3', Rails.root.join('db.sqlite3').to_s) + start(adapter: 'sqlite3', database: 'db.sqlite3') + assert !aborted + end + + def test_sqlite3_mode + dbconsole.expects(:find_cmd_and_exec).with('sqlite3', '-html', Rails.root.join('db.sqlite3').to_s) + start({adapter: 'sqlite3', database: 'db.sqlite3'}, ['--mode', 'html']) + assert !aborted + end + + def test_sqlite3_header + dbconsole.expects(:find_cmd_and_exec).with('sqlite3', '-header', Rails.root.join('db.sqlite3').to_s) + start({adapter: 'sqlite3', database: 'db.sqlite3'}, ['--header']) + end + + def test_sqlite3_db_absolute_path + dbconsole.expects(:find_cmd_and_exec).with('sqlite3', '/tmp/db.sqlite3') + start(adapter: 'sqlite3', database: '/tmp/db.sqlite3') + assert !aborted + end + + def test_oracle + dbconsole.expects(:find_cmd_and_exec).with('sqlplus', 'user@db') + start(adapter: 'oracle', database: 'db', username: 'user', password: 'secret') + assert !aborted + end + + def test_oracle_include_password + dbconsole.expects(:find_cmd_and_exec).with('sqlplus', 'user/secret@db') + start({adapter: 'oracle', database: 'db', username: 'user', password: 'secret'}, ['-p']) + assert !aborted + end + + def test_unknown_command_line_client + start(adapter: 'unknown', database: 'db') + assert aborted + assert_match(/Unknown command-line client for db/, output) + end + + def test_print_help_short + stdout = capture(:stdout) do + start({}, ['-h']) + end + assert aborted + assert_equal '', output + assert_match(/Usage:.*dbconsole/, stdout) + end + + def test_print_help_long + stdout = capture(:stdout) do + start({}, ['--help']) + end + assert aborted + assert_equal '', output + assert_match(/Usage:.*dbconsole/, stdout) + end + + private + attr_reader :aborted, :output + + def dbconsole + @dbconsole ||= Rails::DBConsole.new(nil) + end + + def start(config = {}, argv = []) + dbconsole.stubs(config: config.stringify_keys, arguments: argv) + capture_abort { dbconsole.start } + end + + def capture_abort + @aborted = false + @output = capture(:stderr) do + begin + yield + rescue SystemExit + @aborted = true + end + end + end + + def app_db_file(result) + IO.stubs(:read).with("config/database.yml").returns(result) + end + + def app_config(result) + Rails.application.config.stubs(:database_configuration).returns(result.stringify_keys) + end +end diff --git a/railties/test/commands/server_test.rb b/railties/test/commands/server_test.rb new file mode 100644 index 0000000000..4a3ea82e3d --- /dev/null +++ b/railties/test/commands/server_test.rb @@ -0,0 +1,26 @@ +require 'abstract_unit' +require 'rails/commands/server' + +class Rails::ServerTest < ActiveSupport::TestCase + + def test_environment_with_server_option + args = ["thin", "-e", "production"] + options = Rails::Server::Options.new.parse!(args) + assert_equal 'production', options[:environment] + assert_equal 'thin', options[:server] + end + + def test_environment_without_server_option + args = ["-e", "production"] + options = Rails::Server::Options.new.parse!(args) + assert_equal 'production', options[:environment] + assert_nil options[:server] + end + + def test_server_option_without_environment + args = ["thin"] + options = Rails::Server::Options.new.parse!(args) + assert_nil options[:environment] + assert_equal 'thin', options[:server] + end +end diff --git a/railties/test/configuration/middleware_stack_proxy_test.rb b/railties/test/configuration/middleware_stack_proxy_test.rb new file mode 100644 index 0000000000..5984c0b425 --- /dev/null +++ b/railties/test/configuration/middleware_stack_proxy_test.rb @@ -0,0 +1,59 @@ +require 'minitest/autorun' +require 'rails/configuration' +require 'active_support/test_case' + +module Rails + module Configuration + class MiddlewareStackProxyTest < ActiveSupport::TestCase + def setup + @stack = MiddlewareStackProxy.new + end + + def test_playback_insert_before + @stack.insert_before :foo + assert_playback :insert_before, :foo + end + + def test_playback_insert_after + @stack.insert_after :foo + assert_playback :insert_after, :foo + end + + def test_playback_swap + @stack.swap :foo + assert_playback :swap, :foo + end + + def test_playback_use + @stack.use :foo + assert_playback :use, :foo + end + + def test_playback_delete + @stack.delete :foo + assert_playback :delete, :foo + end + + def test_order + @stack.swap :foo + @stack.delete :foo + + mock = MiniTest::Mock.new + mock.expect :send, nil, [:swap, :foo] + mock.expect :send, nil, [:delete, :foo] + + @stack.merge_into mock + mock.verify + end + + private + + def assert_playback(msg_name, args) + mock = MiniTest::Mock.new + mock.expect :send, nil, [msg_name, args] + @stack.merge_into(mock) + mock.verify + end + end + end +end diff --git a/railties/test/engine_test.rb b/railties/test/engine_test.rb new file mode 100644 index 0000000000..addf49cdb6 --- /dev/null +++ b/railties/test/engine_test.rb @@ -0,0 +1,14 @@ +require 'abstract_unit' + +class EngineTest < ActiveSupport::TestCase + it "reports routes as available only if they're actually present" do + engine = Class.new(Rails::Engine) do + def initialize(*args) + @routes = nil + super + end + end + + assert !engine.routes? + end +end diff --git a/railties/test/generators/actions_test.rb b/railties/test/generators/actions_test.rb index a8c8fcd5b7..bc086c5986 100644 --- a/railties/test/generators/actions_test.rb +++ b/railties/test/generators/actions_test.rb @@ -67,6 +67,14 @@ class ActionsTest < Rails::Generators::TestCase assert_file 'Gemfile', /^gem "rspec-rails"$/ end + def test_gem_should_include_options + run_generator + + action :gem, 'rspec', github: 'dchelimsky/rspec', tag: '1.2.9.rc1' + + assert_file 'Gemfile', /gem "rspec", github: "dchelimsky\/rspec", tag: "1\.2\.9\.rc1"/ + end + def test_gem_group_should_wrap_gems_in_a_group run_generator diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index a3c24c392b..c294bfb238 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -83,6 +83,16 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_equal false, $?.success? end + def test_application_new_show_help_message_inside_existing_rails_directory + app_root = File.join(destination_root, 'myfirstapp') + run_generator [app_root] + output = Dir.chdir(app_root) do + `rails new --help` + end + assert_match(/rails new APP_PATH \[options\]/, output) + assert_equal true, $?.success? + end + def test_application_name_is_detected_if_it_exists_and_app_folder_renamed app_root = File.join(destination_root, "myapp") app_moved_root = File.join(destination_root, "myapp_moved") @@ -136,9 +146,9 @@ class AppGeneratorTest < Rails::Generators::TestCase run_generator assert_file "config/database.yml", /sqlite3/ unless defined?(JRUBY_VERSION) - assert_file "Gemfile", /^gem\s+["']sqlite3["']$/ + assert_gem "sqlite3" else - assert_file "Gemfile", /^gem\s+["']activerecord-jdbcsqlite3-adapter["']$/ + assert_gem "activerecord-jdbcsqlite3-adapter" end end @@ -146,9 +156,9 @@ class AppGeneratorTest < Rails::Generators::TestCase run_generator([destination_root, "-d", "mysql"]) assert_file "config/database.yml", /mysql/ unless defined?(JRUBY_VERSION) - assert_file "Gemfile", /^gem\s+["']mysql2["']$/ + assert_gem "mysql2" else - assert_file "Gemfile", /^gem\s+["']activerecord-jdbcmysql-adapter["']$/ + assert_gem "activerecord-jdbcmysql-adapter" end end @@ -156,45 +166,45 @@ class AppGeneratorTest < Rails::Generators::TestCase run_generator([destination_root, "-d", "postgresql"]) assert_file "config/database.yml", /postgresql/ unless defined?(JRUBY_VERSION) - assert_file "Gemfile", /^gem\s+["']pg["']$/ + assert_gem "pg" else - assert_file "Gemfile", /^gem\s+["']activerecord-jdbcpostgresql-adapter["']$/ + assert_gem "activerecord-jdbcpostgresql-adapter" end end def test_config_jdbcmysql_database run_generator([destination_root, "-d", "jdbcmysql"]) assert_file "config/database.yml", /mysql/ - assert_file "Gemfile", /^gem\s+["']activerecord-jdbcmysql-adapter["']$/ + assert_gem "activerecord-jdbcmysql-adapter" # TODO: When the JRuby guys merge jruby-openssl in # jruby this will be removed - assert_file "Gemfile", /^gem\s+["']jruby-openssl["']$/ if defined?(JRUBY_VERSION) + assert_gem "jruby-openssl" if defined?(JRUBY_VERSION) end def test_config_jdbcsqlite3_database run_generator([destination_root, "-d", "jdbcsqlite3"]) assert_file "config/database.yml", /sqlite3/ - assert_file "Gemfile", /^gem\s+["']activerecord-jdbcsqlite3-adapter["']$/ + assert_gem "activerecord-jdbcsqlite3-adapter" end def test_config_jdbcpostgresql_database run_generator([destination_root, "-d", "jdbcpostgresql"]) assert_file "config/database.yml", /postgresql/ - assert_file "Gemfile", /^gem\s+["']activerecord-jdbcpostgresql-adapter["']$/ + assert_gem "activerecord-jdbcpostgresql-adapter" end def test_config_jdbc_database run_generator([destination_root, "-d", "jdbc"]) assert_file "config/database.yml", /jdbc/ assert_file "config/database.yml", /mssql/ - assert_file "Gemfile", /^gem\s+["']activerecord-jdbc-adapter["']$/ + assert_gem "activerecord-jdbc-adapter" end def test_config_jdbc_database_when_no_option_given if defined?(JRUBY_VERSION) run_generator([destination_root]) assert_file "config/database.yml", /sqlite3/ - assert_file "Gemfile", /^gem\s+["']activerecord-jdbcsqlite3-adapter["']$/ + assert_gem "activerecord-jdbcsqlite3-adapter" end end @@ -202,7 +212,7 @@ class AppGeneratorTest < Rails::Generators::TestCase run_generator [destination_root, "--skip-active-record"] assert_no_file "config/database.yml" assert_file "config/application.rb", /#\s+require\s+["']active_record\/railtie["']/ - assert_file "config/application.rb", /#\s+config\.active_record\.dependent_restrict_raises = false/ + assert_file "config/application.rb", /#\s+config\.active_record\.whitelist_attributes = true/ assert_file "test/test_helper.rb" do |helper_content| assert_no_match(/fixtures :all/, helper_content) end @@ -212,7 +222,7 @@ class AppGeneratorTest < Rails::Generators::TestCase def test_generator_if_skip_sprockets_is_given run_generator [destination_root, "--skip-sprockets"] assert_file "config/application.rb" do |content| - assert_match(/#\s+require\s+["']sprockets\/railtie["']/, content) + assert_match(/#\s+require\s+["']sprockets\/rails\/railtie["']/, content) assert_no_match(/config\.assets\.enabled = true/, content) end assert_file "Gemfile" do |content| @@ -233,12 +243,19 @@ class AppGeneratorTest < Rails::Generators::TestCase def test_inclusion_of_javascript_runtime run_generator([destination_root]) if defined?(JRUBY_VERSION) - assert_file "Gemfile", /gem\s+["']therubyrhino["']$/ + assert_gem "therubyrhino" else - assert_file "Gemfile", /# gem\s+["']therubyracer["']$/ + assert_file "Gemfile", /# gem\s+["']therubyracer["']+, platforms: :ruby$/ end end + def test_generator_if_skip_index_html_is_given + run_generator [destination_root, "--skip-index-html"] + assert_no_file "public/index.html" + assert_no_file "app/assets/images/rails.png" + assert_file "app/assets/images/.gitkeep" + end + def test_creation_of_a_test_directory run_generator assert_file 'test' @@ -260,9 +277,7 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_match %r{^//= require jquery}, contents assert_match %r{^//= require jquery_ujs}, contents end - assert_file 'Gemfile' do |contents| - assert_match(/^gem 'jquery-rails'/, contents) - end + assert_gem "jquery-rails" end def test_other_javascript_libraries @@ -271,9 +286,7 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_match %r{^//= require prototype}, contents assert_match %r{^//= require prototype_ujs}, contents end - assert_file 'Gemfile' do |contents| - assert_match(/^gem 'prototype-rails'/, contents) - end + assert_gem "prototype-rails" end def test_javascript_is_skipped_if_required @@ -283,11 +296,9 @@ class AppGeneratorTest < Rails::Generators::TestCase end end - def test_inclusion_of_ruby_debug19 + def test_inclusion_of_debugger run_generator - assert_file "Gemfile" do |contents| - assert_match(/gem 'ruby-debug19', :require => 'ruby-debug'/, contents) - end + assert_file "Gemfile", /# gem 'debugger'/ end def test_template_from_dir_pwd @@ -301,7 +312,7 @@ class AppGeneratorTest < Rails::Generators::TestCase end def test_default_usage - File.expects(:exist?).returns(false) + Rails::Generators::AppGenerator.expects(:usage_path).returns(nil) assert_match(/Create rails files for app generator/, Rails::Generators::AppGenerator.desc) end @@ -350,9 +361,9 @@ class AppGeneratorTest < Rails::Generators::TestCase end end - def test_active_record_dependent_restrict_raises_is_present_application_config + def test_active_record_whitelist_attributes_is_present_application_config run_generator - assert_file "config/application.rb", /config\.active_record\.dependent_restrict_raises = false/ + assert_file "config/application.rb", /config\.active_record\.whitelist_attributes = true/ end def test_pretend_option @@ -366,6 +377,9 @@ protected silence(:stdout) { generator.send(*args, &block) } end + def assert_gem(gem) + assert_file "Gemfile", /^gem\s+["']#{gem}["']$/ + end end class CustomAppGeneratorTest < Rails::Generators::TestCase diff --git a/railties/test/generators/assets_generator_test.rb b/railties/test/generators/assets_generator_test.rb index d6338bd3da..a2b94f2e50 100644 --- a/railties/test/generators/assets_generator_test.rb +++ b/railties/test/generators/assets_generator_test.rb @@ -1,7 +1,6 @@ require 'generators/generators_test_helper' require 'rails/generators/rails/assets/assets_generator' -# FIXME: Silence the 'Could not find task "using_coffee?"' message in tests due to the public stub class AssetsGeneratorTest < Rails::Generators::TestCase include GeneratorsTestHelper arguments %w(posts) diff --git a/railties/test/generators/generated_attribute_test.rb b/railties/test/generators/generated_attribute_test.rb index 6e3fc84781..6ab1cd58c7 100644 --- a/railties/test/generators/generated_attribute_test.rb +++ b/railties/test/generators/generated_attribute_test.rb @@ -102,22 +102,28 @@ class GeneratedAttributeTest < Rails::Generators::TestCase def test_reference_is_true %w(references belongs_to).each do |attribute_type| - assert_equal( - true, - create_generated_attribute(attribute_type).reference? - ) + assert create_generated_attribute(attribute_type).reference? end end def test_reference_is_false %w(foo bar baz).each do |attribute_type| - assert_equal( - false, - create_generated_attribute(attribute_type).reference? - ) + assert !create_generated_attribute(attribute_type).reference? end end + def test_polymorphic_reference_is_true + %w(references belongs_to).each do |attribute_type| + assert create_generated_attribute("#{attribute_type}{polymorphic}").polymorphic? + end + end + + def test_polymorphic_reference_is_false + %w(foo bar baz).each do |attribute_type| + assert !create_generated_attribute("#{attribute_type}{polymorphic}").polymorphic? + end + end + def test_blank_type_defaults_to_string_raises_exception assert_equal :string, create_generated_attribute(nil, 'title').type assert_equal :string, create_generated_attribute("", 'title').type @@ -126,5 +132,6 @@ class GeneratedAttributeTest < Rails::Generators::TestCase def test_handles_index_names_for_references assert_equal "post", create_generated_attribute('string', 'post').index_name assert_equal "post_id", create_generated_attribute('references', 'post').index_name + assert_equal ["post_id", "post_type"], create_generated_attribute('references{polymorphic}', 'post').index_name end end diff --git a/railties/test/generators/migration_generator_test.rb b/railties/test/generators/migration_generator_test.rb index 4e08e5dae1..15e5a0b92b 100644 --- a/railties/test/generators/migration_generator_test.rb +++ b/railties/test/generators/migration_generator_test.rb @@ -28,6 +28,13 @@ class MigrationGeneratorTest < Rails::Generators::TestCase run_generator [migration] assert_migration "db/migrate/change_title_body_from_posts.rb", /class #{migration} < ActiveRecord::Migration/ end + + def test_migration_with_invalid_file_name + migration = "add_something:datetime" + assert_raise ActiveRecord::IllegalMigrationNameError do + run_generator [migration] + end + end def test_add_migration_with_attributes migration = "add_title_body_to_posts" @@ -41,6 +48,24 @@ class MigrationGeneratorTest < Rails::Generators::TestCase end end + def test_remove_migration_with_indexed_attribute + migration = "remove_title_body_from_posts" + run_generator [migration, "title:string:index", "body:text"] + + assert_migration "db/migrate/#{migration}.rb" do |content| + assert_method :up, content do |up| + assert_match(/remove_column :posts, :title/, up) + assert_match(/remove_column :posts, :body/, up) + end + + assert_method :down, content do |down| + assert_match(/add_column :posts, :title, :string/, down) + assert_match(/add_column :posts, :body, :text/, down) + assert_match(/add_index :posts, :title/, down) + end + end + end + def test_remove_migration_with_attributes migration = "remove_title_body_from_posts" run_generator [migration, "title:string", "body:text"] @@ -58,6 +83,23 @@ class MigrationGeneratorTest < Rails::Generators::TestCase end end + def test_remove_migration_with_references_options + migration = "remove_references_from_books" + run_generator [migration, "author:belongs_to", "distributor:references{polymorphic}"] + + assert_migration "db/migrate/#{migration}.rb" do |content| + assert_method :up, content do |up| + assert_match(/remove_reference :books, :author/, up) + assert_match(/remove_reference :books, :distributor, polymorphic: true/, up) + end + + assert_method :down, content do |down| + assert_match(/add_reference :books, :author, index: true/, down) + assert_match(/add_reference :books, :distributor, polymorphic: true, index: true/, down) + end + end + end + def test_add_migration_with_attributes_and_indices migration = "add_title_with_index_and_body_to_posts" run_generator [migration, "title:string:index", "body:text", "user_id:integer:uniq"] @@ -120,6 +162,31 @@ class MigrationGeneratorTest < Rails::Generators::TestCase end end + def test_add_migration_with_references_options + migration = "add_references_to_books" + run_generator [migration, "author:belongs_to", "distributor:references{polymorphic}"] + + assert_migration "db/migrate/#{migration}.rb" do |content| + assert_method :change, content do |up| + assert_match(/add_reference :books, :author, index: true/, up) + assert_match(/add_reference :books, :distributor, polymorphic: true, index: true/, up) + end + end + end + + def test_create_join_table_migration + migration = "add_media_join_table" + run_generator [migration, "artist_id", "musics:uniq"] + + assert_migration "db/migrate/#{migration}.rb" do |content| + assert_method :change, content do |up| + assert_match(/create_join_table :artists, :musics/, up) + assert_match(/# t.index \[:artist_id, :music_id\]/, up) + assert_match(/ t.index \[:music_id, :artist_id\], unique: true/, up) + end + end + end + def test_should_create_empty_migrations_if_name_not_start_with_add_or_remove migration = "create_books" run_generator [migration, "title:string", "content:text"] @@ -134,4 +201,8 @@ class MigrationGeneratorTest < Rails::Generators::TestCase end end end + + def test_properly_identifies_usage_file + assert generator_class.send(:usage_path) + end end diff --git a/railties/test/generators/model_generator_test.rb b/railties/test/generators/model_generator_test.rb index 156fa86eee..ec33bd7c6b 100644 --- a/railties/test/generators/model_generator_test.rb +++ b/railties/test/generators/model_generator_test.rb @@ -166,7 +166,7 @@ class ModelGeneratorTest < Rails::Generators::TestCase end def test_add_migration_with_attributes_index_declaration_and_attribute_options - run_generator ["product", "title:string{40}:index", "content:string{255}", "price:decimal{5,2}:index", "discount:decimal{5,2}:uniq"] + run_generator ["product", "title:string{40}:index", "content:string{255}", "price:decimal{5,2}:index", "discount:decimal{5,2}:uniq", "supplier:references{polymorphic}"] assert_migration "db/migrate/create_products.rb" do |content| assert_method :change, content do |up| @@ -174,6 +174,7 @@ class ModelGeneratorTest < Rails::Generators::TestCase assert_match(/t.string :title, limit: 40/, up) assert_match(/t.string :content, limit: 255/, up) assert_match(/t.decimal :price, precision: 5, scale: 2/, up) + assert_match(/t.references :supplier, polymorphic: true/, up) end assert_match(/add_index :products, :title/, content) assert_match(/add_index :products, :price/, content) @@ -193,15 +194,25 @@ class ModelGeneratorTest < Rails::Generators::TestCase end def test_model_with_references_attribute_generates_belongs_to_associations - run_generator ["product", "name:string", "supplier_id:references"] + run_generator ["product", "name:string", "supplier:references"] assert_file "app/models/product.rb", /belongs_to :supplier/ end def test_model_with_belongs_to_attribute_generates_belongs_to_associations - run_generator ["product", "name:string", "supplier_id:belongs_to"] + run_generator ["product", "name:string", "supplier:belongs_to"] assert_file "app/models/product.rb", /belongs_to :supplier/ end + def test_model_with_polymorphic_references_attribute_generates_belongs_to_associations + run_generator ["product", "name:string", "supplier:references{polymorphic}"] + assert_file "app/models/product.rb", /belongs_to :supplier, polymorphic: true/ + end + + def test_model_with_polymorphic_belongs_to_attribute_generates_belongs_to_associations + run_generator ["product", "name:string", "supplier:belongs_to{polymorphic}"] + assert_file "app/models/product.rb", /belongs_to :supplier, polymorphic: true/ + end + def test_migration_with_timestamps run_generator assert_migration "db/migrate/create_accounts.rb", /t.timestamps/ @@ -283,7 +294,7 @@ class ModelGeneratorTest < Rails::Generators::TestCase assert_migration "db/migrate/create_accounts.rb" do |m| assert_method :change, m do |up| - assert_match(/add_index/, up) + assert_match(/index: true/, up) end end end @@ -293,7 +304,7 @@ class ModelGeneratorTest < Rails::Generators::TestCase assert_migration "db/migrate/create_accounts.rb" do |m| assert_method :change, m do |up| - assert_match(/add_index/, up) + assert_match(/index: true/, up) end end end @@ -303,7 +314,7 @@ class ModelGeneratorTest < Rails::Generators::TestCase assert_migration "db/migrate/create_accounts.rb" do |m| assert_method :change, m do |up| - assert_no_match(/add_index/, up) + assert_no_match(/index: true/, up) end end end @@ -313,8 +324,18 @@ class ModelGeneratorTest < Rails::Generators::TestCase assert_migration "db/migrate/create_accounts.rb" do |m| assert_method :change, m do |up| - assert_no_match(/add_index/, up) + assert_no_match(/index: true/, up) end end end + + def test_attr_accessible_added_with_non_reference_attributes + run_generator + assert_file 'app/models/account.rb', /attr_accessible :age, :name/ + end + + def test_attr_accessible_added_with_comments_when_no_attributes_present + run_generator ["Account"] + assert_file 'app/models/account.rb', /# attr_accessible :title, :body/ + end end diff --git a/railties/test/generators/namespaced_generators_test.rb b/railties/test/generators/namespaced_generators_test.rb index 5c63b13dce..db2b8af217 100644 --- a/railties/test/generators/namespaced_generators_test.rb +++ b/railties/test/generators/namespaced_generators_test.rb @@ -20,8 +20,14 @@ class NamespacedControllerGeneratorTest < NamespacedGeneratorTestCase def test_namespaced_controller_skeleton_is_created run_generator - assert_file "app/controllers/test_app/account_controller.rb", /module TestApp/, / class AccountController < ApplicationController/ - assert_file "test/functional/test_app/account_controller_test.rb", /module TestApp/, / class AccountControllerTest/ + assert_file "app/controllers/test_app/account_controller.rb", + /require_dependency "test_app\/application_controller"/, + /module TestApp/, + / class AccountController < ApplicationController/ + + assert_file "test/functional/test_app/account_controller_test.rb", + /module TestApp/, + / class AccountControllerTest/ end def test_skipping_namespace @@ -32,7 +38,9 @@ class NamespacedControllerGeneratorTest < NamespacedGeneratorTestCase def test_namespaced_controller_with_additional_namespace run_generator ["admin/account"] - assert_file "app/controllers/test_app/admin/account_controller.rb", /module TestApp/, / class Admin::AccountController < ApplicationController/ + assert_file "app/controllers/test_app/admin/account_controller.rb", /module TestApp/, / class Admin::AccountController < ApplicationController/ do |contents| + assert_match %r(require_dependency "test_app/application_controller"), contents + end end def test_helpr_is_also_namespaced @@ -56,11 +64,20 @@ class NamespacedControllerGeneratorTest < NamespacedGeneratorTestCase run_generator assert_file "config/routes.rb", /get "account\/foo"/, /get "account\/bar"/ end -# + def test_invokes_default_template_engine_even_with_no_action run_generator ["account"] assert_file "app/views/test_app/account" end + + def test_namespaced_controller_dont_indent_blank_lines + run_generator + assert_file "app/controllers/test_app/account_controller.rb" do |content| + content.split("\n").each do |line| + assert_no_match(/^\s+$/, line, "Don't indent blank lines") + end + end + end end class NamespacedModelGeneratorTest < NamespacedGeneratorTestCase @@ -82,7 +99,7 @@ class NamespacedModelGeneratorTest < NamespacedGeneratorTestCase run_generator ["admin/account"] assert_file "app/models/test_app/admin.rb", /module TestApp/, /module Admin/ assert_file "app/models/test_app/admin.rb", /def self\.table_name_prefix/ - assert_file "app/models/test_app/admin.rb", /'admin_'/ + assert_file "app/models/test_app/admin.rb", /'test_app_admin_'/ assert_file "app/models/test_app/admin/account.rb", /module TestApp/, /class Admin::Account < ActiveRecord::Base/ end @@ -218,9 +235,10 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase end # Controller - assert_file "app/controllers/test_app/product_lines_controller.rb" do |content| - assert_match(/module TestApp\n class ProductLinesController < ApplicationController/, content) - end + assert_file "app/controllers/test_app/product_lines_controller.rb", + /require_dependency "test_app\/application_controller"/, + /module TestApp/, + /class ProductLinesController < ApplicationController/ assert_file "test/functional/test_app/product_lines_controller_test.rb", /module TestApp\n class ProductLinesControllerTest < ActionController::TestCase/ diff --git a/railties/test/generators/plugin_new_generator_test.rb b/railties/test/generators/plugin_new_generator_test.rb index 4bb5f04a79..bfb20dad2d 100644 --- a/railties/test/generators/plugin_new_generator_test.rb +++ b/railties/test/generators/plugin_new_generator_test.rb @@ -32,7 +32,7 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase content = capture(:stderr){ run_generator [File.join(destination_root, "things4.3")] } assert_equal "Invalid plugin name things4.3. Please give a name which use only alphabetic or numeric or \"_\" characters.\n", content - + content = capture(:stderr){ run_generator [File.join(destination_root, "43things")] } assert_equal "Invalid plugin name 43things. Please give a name which does not start with numbers.\n", content end @@ -58,6 +58,14 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase assert_file "test/integration/navigation_test.rb", /ActionDispatch::IntegrationTest/ end + def test_generating_test_files_in_full_mode_without_unit_test_files + run_generator [destination_root, "-T", "--full"] + + assert_no_directory "test/integration/" + assert_no_file "test" + assert_no_match(/APP_RAKEFILE/, File.read(File.join(destination_root, "Rakefile"))) + end + def test_ensure_that_plugin_options_are_not_passed_to_app_generator FileUtils.cd(Rails.root) assert_no_match(/It works from file!.*It works_from_file/, run_generator([destination_root, "-m", "lib/template.rb"])) @@ -82,6 +90,14 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase assert_file "bukkits.gemspec", /mysql/ end + def test_dont_generate_development_dependency + run_generator [destination_root, "--skip-active-record"] + + assert_file "bukkits.gemspec" do |contents| + assert_no_match(/s.add_development_dependency "sqlite3"/, contents) + end + end + def test_active_record_is_removed_from_frameworks_if_skip_active_record_is_given run_generator [destination_root, "--skip-active-record"] assert_file "test/dummy/config/application.rb", /#\s+require\s+["']active_record\/railtie["']/ @@ -99,7 +115,13 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase end def test_generation_runs_bundle_install_with_full_and_mountable - result = run_generator [destination_root, "--mountable", "--full"] + result = run_generator [destination_root, "--mountable", "--full", "--dev"] + assert_file "#{destination_root}/Gemfile.lock" do |contents| + assert_match(/bukkits/, contents) + end + assert_match(/run bundle install/, result) + assert_match(/Using bukkits \(0\.0\.1\)/, result) + assert_match(/Your bundle is complete/, result) assert_equal 1, result.scan("Your bundle is complete").size end @@ -211,7 +233,7 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase def test_creating_gemspec run_generator assert_file "bukkits.gemspec", /s.name\s+= "bukkits"/ - assert_file "bukkits.gemspec", /s.files = Dir\["\{app,config,db,lib\}\/\*\*\/\*"\]/ + assert_file "bukkits.gemspec", /s.files = Dir\["\{app,config,db,lib\}\/\*\*\/\*", "MIT-LICENSE", "Rakefile", "README\.rdoc"\]/ assert_file "bukkits.gemspec", /s.test_files = Dir\["test\/\*\*\/\*"\]/ assert_file "bukkits.gemspec", /s.version\s+ = Bukkits::VERSION/ end @@ -236,16 +258,26 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase assert_no_file "test/dummy" end + def test_creating_dummy_application_with_different_name + run_generator [destination_root, "--dummy_path", "spec/fake"] + assert_file "spec/fake" + assert_file "spec/fake/config/application.rb" + assert_no_file "test/dummy" + end + def test_creating_dummy_without_tests_but_with_dummy_path run_generator [destination_root, "--dummy_path", "spec/dummy", "--skip-test-unit"] assert_file "spec/dummy" assert_file "spec/dummy/config/application.rb" assert_no_file "test" + assert_file '.gitignore' do |contents| + assert_match(/spec\/dummy/, contents) + end end def test_ensure_that_gitignore_can_be_generated_from_a_template_for_dummy_path FileUtils.cd(Rails.root) - run_generator([destination_root, "--dummy_path", "spec/dummy" "--skip-test-unit"]) + run_generator([destination_root, "--dummy_path", "spec/dummy", "--skip-test-unit"]) assert_file ".gitignore" do |contents| assert_match(/spec\/dummy/, contents) end @@ -257,11 +289,40 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase assert_file "bukkits.gemspec" do |contents| assert_no_match(/s.test_files = Dir\["test\/\*\*\/\*"\]/, contents) end + assert_file '.gitignore' do |contents| + assert_no_match(/test\dummy/, contents) + end end def test_skipping_gemspec run_generator [destination_root, "--skip-gemspec"] assert_no_file "bukkits.gemspec" + assert_file "Gemfile" do |contents| + assert_no_match('gemspec', contents) + assert_match(/gem "rails", "~> #{Rails::VERSION::STRING}"/, contents) + assert_match(/group :development do\n gem "sqlite3"\nend/, contents) + assert_no_match(/# gem "jquery-rails"/, contents) + end + end + + def test_skipping_gemspec_in_full_mode + run_generator [destination_root, "--skip-gemspec", "--full"] + assert_no_file "bukkits.gemspec" + assert_file "Gemfile" do |contents| + assert_no_match('gemspec', contents) + assert_match(/gem "rails", "~> #{Rails::VERSION::STRING}"/, contents) + assert_match(/group :development do\n gem "sqlite3"\nend/, contents) + assert_match(/# gem "jquery-rails"/, contents) + assert_no_match(/# jquery-rails is used by the dummy application\ngem "jquery-rails"/, contents) + end + end + + def test_skipping_gemspec_in_full_mode_with_javascript_option + run_generator [destination_root, "--skip-gemspec", "--full", "--javascript=prototype"] + assert_file "Gemfile" do |contents| + assert_match(/# gem "prototype-rails"/, contents) + assert_match(/# jquery-rails is used by the dummy application\ngem "jquery-rails"/, contents) + end end def test_creating_plugin_in_app_directory_adds_gemfile_entry @@ -272,7 +333,7 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase run_generator [destination_root] - assert_file gemfile_path, /gem 'bukkits', :path => 'tmp\/bukkits'/ + assert_file gemfile_path, /gem 'bukkits', path: 'tmp\/bukkits'/ ensure Object.send(:remove_const, 'APP_PATH') FileUtils.rm gemfile_path @@ -287,7 +348,7 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase run_generator [destination_root, "--skip-gemfile-entry"] assert_file gemfile_path do |contents| - assert_no_match(/gem 'bukkits', :path => 'tmp\/bukkits'/, contents) + assert_no_match(/gem 'bukkits', path: 'tmp\/bukkits'/, contents) end ensure Object.send(:remove_const, 'APP_PATH') @@ -296,12 +357,10 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase protected - def action(*args, &block) silence(:stdout){ generator.send(*args, &block) } end -protected def default_files ::DEFAULT_PLUGIN_FILES end @@ -341,4 +400,3 @@ protected silence(:stdout){ generator.send(*args, &block) } end end - diff --git a/railties/test/generators/scaffold_controller_generator_test.rb b/railties/test/generators/scaffold_controller_generator_test.rb index 1382133d7b..1eea50b0d9 100644 --- a/railties/test/generators/scaffold_controller_generator_test.rb +++ b/railties/test/generators/scaffold_controller_generator_test.rb @@ -75,6 +75,19 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase assert_file "test/functional/users_controller_test.rb" do |content| assert_match(/class UsersControllerTest < ActionController::TestCase/, content) assert_match(/test "should get index"/, content) + assert_match(/post :create, user: \{ age: @user.age, name: @user.name \}/, content) + assert_match(/put :update, id: @user, user: \{ age: @user.age, name: @user.name \}/, content) + end + end + + def test_functional_tests_without_attributes + run_generator ["User"] + + assert_file "test/functional/users_controller_test.rb" do |content| + assert_match(/class UsersControllerTest < ActionController::TestCase/, content) + assert_match(/test "should get index"/, content) + assert_match(/post :create, user: \{ \}/, content) + assert_match(/put :update, id: @user, user: \{ \}/, content) end end diff --git a/railties/test/generators/scaffold_generator_test.rb b/railties/test/generators/scaffold_generator_test.rb index 2db8090621..9b456c64ef 100644 --- a/railties/test/generators/scaffold_generator_test.rb +++ b/railties/test/generators/scaffold_generator_test.rb @@ -14,10 +14,8 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase assert_file "app/models/product_line.rb", /class ProductLine < ActiveRecord::Base/ assert_file "test/unit/product_line_test.rb", /class ProductLineTest < ActiveSupport::TestCase/ assert_file "test/fixtures/product_lines.yml" - assert_migration "db/migrate/create_product_lines.rb", /belongs_to :product/ - assert_migration "db/migrate/create_product_lines.rb", /add_index :product_lines, :product_id/ - assert_migration "db/migrate/create_product_lines.rb", /references :user/ - assert_migration "db/migrate/create_product_lines.rb", /add_index :product_lines, :user_id/ + assert_migration "db/migrate/create_product_lines.rb", /belongs_to :product, index: true/ + assert_migration "db/migrate/create_product_lines.rb", /references :user, index: true/ # Route assert_file "config/routes.rb" do |route| @@ -62,8 +60,11 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase end end - assert_file "test/functional/product_lines_controller_test.rb", - /class ProductLinesControllerTest < ActionController::TestCase/ + assert_file "test/functional/product_lines_controller_test.rb" do |test| + assert_match(/class ProductLinesControllerTest < ActionController::TestCase/, test) + assert_match(/post :create, product_line: \{ title: @product_line.title \}/, test) + assert_match(/put :update, id: @product_line, product_line: \{ title: @product_line.title \}/, test) + end # Views %w( @@ -85,6 +86,17 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase assert_file "app/assets/stylesheets/product_lines.css" end + def test_functional_tests_without_attributes + run_generator ["product_line"] + + assert_file "test/functional/product_lines_controller_test.rb" do |content| + assert_match(/class ProductLinesControllerTest < ActionController::TestCase/, content) + assert_match(/test "should get index"/, content) + assert_match(/post :create, product_line: \{ \}/, content) + assert_match(/put :update, id: @product_line, product_line: \{ \}/, content) + end + end + def test_scaffold_on_revoke run_generator run_generator ["product_line"], :behavior => :revoke diff --git a/railties/test/generators/session_migration_generator_test.rb b/railties/test/generators/session_migration_generator_test.rb deleted file mode 100644 index b590047ff0..0000000000 --- a/railties/test/generators/session_migration_generator_test.rb +++ /dev/null @@ -1,27 +0,0 @@ -require 'generators/generators_test_helper' -require 'rails/generators/rails/session_migration/session_migration_generator' - -class SessionMigrationGeneratorTest < Rails::Generators::TestCase - include GeneratorsTestHelper - - def test_session_migration_with_default_name - run_generator - assert_migration "db/migrate/add_sessions_table.rb", /class AddSessionsTable < ActiveRecord::Migration/ - end - - def test_session_migration_with_given_name - run_generator ["create_session_table"] - assert_migration "db/migrate/create_session_table.rb", /class CreateSessionTable < ActiveRecord::Migration/ - end - - def test_session_migration_with_custom_table_name - ActiveRecord::SessionStore::Session.table_name = "custom_table_name" - run_generator - assert_migration "db/migrate/add_sessions_table.rb" do |migration| - assert_match(/class AddSessionsTable < ActiveRecord::Migration/, migration) - assert_match(/create_table :custom_table_name/, migration) - end - ensure - ActiveRecord::SessionStore::Session.table_name = "sessions" - end -end diff --git a/railties/test/generators/shared_generator_tests.rb b/railties/test/generators/shared_generator_tests.rb index 14a20eddb8..e78e67725d 100644 --- a/railties/test/generators/shared_generator_tests.rb +++ b/railties/test/generators/shared_generator_tests.rb @@ -91,21 +91,6 @@ module SharedGeneratorTests assert_match(/It works!/, capture(:stdout) { generator.invoke_all }) end - def test_template_raises_an_error_with_invalid_path - content = capture(:stderr){ run_generator([destination_root, "-m", "non/existant/path"]) } - assert_match(/The template \[.*\] could not be loaded/, content) - assert_match(/non\/existant\/path/, content) - end - - def test_template_is_executed_when_supplied - path = "http://gist.github.com/103208.txt" - template = %{ say "It works!" } - template.instance_eval "def read; self; end" # Make the string respond to read - - generator([destination_root], :template => path).expects(:open).with(path, 'Accept' => 'application/x-thor-template').returns(template) - assert_match(/It works!/, capture(:stdout) { generator.invoke_all }) - end - def test_template_is_executed_when_supplied_an_https_path path = "https://gist.github.com/103208.txt" template = %{ say "It works!" } @@ -119,13 +104,13 @@ module SharedGeneratorTests generator([destination_root], :dev => true).expects(:bundle_command).with('install').once quietly { generator.invoke_all } rails_path = File.expand_path('../../..', Rails.root) - assert_file 'Gemfile', /^gem\s+["']rails["'],\s+:path\s+=>\s+["']#{Regexp.escape(rails_path)}["']$/ + assert_file 'Gemfile', /^gem\s+["']rails["'],\s+path:\s+["']#{Regexp.escape(rails_path)}["']$/ end def test_edge_option generator([destination_root], :edge => true).expects(:bundle_command).with('install').once quietly { generator.invoke_all } - assert_file 'Gemfile', %r{^gem\s+["']rails["'],\s+:git\s+=>\s+["']#{Regexp.escape("https://github.com/rails/rails.git")}["']$} + assert_file 'Gemfile', %r{^gem\s+["']rails["'],\s+github:\s+["']#{Regexp.escape("rails/rails")}["']$} end def test_skip_gemfile diff --git a/railties/test/generators_test.rb b/railties/test/generators_test.rb index 60e7e57a91..027d8eb9b7 100644 --- a/railties/test/generators_test.rb +++ b/railties/test/generators_test.rb @@ -1,7 +1,6 @@ require 'generators/generators_test_helper' require 'rails/generators/rails/model/model_generator' require 'rails/generators/test_unit/model/model_generator' -require 'mocha' class GeneratorsTest < Rails::Generators::TestCase include GeneratorsTestHelper @@ -168,7 +167,7 @@ class GeneratorsTest < Rails::Generators::TestCase def test_developer_options_are_overwriten_by_user_options Rails::Generators.options[:with_options] = { :generate => false } - self.class.class_eval <<-end_eval + self.class.class_eval(<<-end_eval, __FILE__, __LINE__ + 1) class WithOptionsGenerator < Rails::Generators::Base class_option :generate, :default => true end @@ -186,7 +185,7 @@ class GeneratorsTest < Rails::Generators::TestCase mkdir_p(File.dirname(template)) File.open(template, 'w'){ |f| f.write "empty" } - output = capture(:stdout) do + capture(:stdout) do Rails::Generators.invoke :model, ["user"], :destination_root => destination_root end @@ -205,7 +204,7 @@ class GeneratorsTest < Rails::Generators::TestCase def test_usage_with_embedded_ruby require File.expand_path("fixtures/lib/generators/usage_template/usage_template_generator", File.dirname(__FILE__)) output = capture(:stdout) { Rails::Generators.invoke :usage_template, ['--help'] } - assert_match /:: 2 ::/, output + assert_match(/:: 2 ::/, output) end def test_hide_namespace diff --git a/railties/test/isolation/abstract_unit.rb b/railties/test/isolation/abstract_unit.rb index 4fb5e6a4eb..07a7faa3af 100644 --- a/railties/test/isolation/abstract_unit.rb +++ b/railties/test/isolation/abstract_unit.rb @@ -8,27 +8,27 @@ # Rails booted up. require 'fileutils' -require 'rubygems' +require 'bundler/setup' unless defined?(Bundler) require 'minitest/autorun' require 'active_support/test_case' -# TODO: Remove setting this magic constant RAILS_FRAMEWORK_ROOT = File.expand_path("#{File.dirname(__FILE__)}/../../..") # These files do not require any others and are needed # to run the tests -require "#{RAILS_FRAMEWORK_ROOT}/activesupport/lib/active_support/testing/isolation" -require "#{RAILS_FRAMEWORK_ROOT}/activesupport/lib/active_support/testing/declarative" -require "#{RAILS_FRAMEWORK_ROOT}/activesupport/lib/active_support/core_ext/kernel/reporting" +require "active_support/testing/isolation" +require "active_support/core_ext/kernel/reporting" +require 'tmpdir' module TestHelpers module Paths - module_function - - TMP_PATH = File.expand_path(File.join(File.dirname(__FILE__), *%w[.. .. tmp])) + def app_template_path + File.join Dir.tmpdir, 'app_template' + end def tmp_path(*args) - File.join(TMP_PATH, *args) + @tmp_path ||= File.realpath(Dir.mktmpdir) + File.join(@tmp_path, *args) end def app_path(*args) @@ -96,7 +96,7 @@ module TestHelpers ENV['RAILS_ENV'] = 'development' FileUtils.rm_rf(app_path) - FileUtils.cp_r(tmp_path('app_template'), app_path) + FileUtils.cp_r(app_template_path, app_path) # Delete the initializers unless requested unless options[:initializers] @@ -105,18 +105,25 @@ module TestHelpers end end - unless options[:gemfile] - File.delete"#{app_path}/Gemfile" + gemfile_path = "#{app_path}/Gemfile" + if options[:gemfile].blank? && File.exist?(gemfile_path) + File.delete gemfile_path end routes = File.read("#{app_path}/config/routes.rb") if routes =~ /(\n\s*end\s*)\Z/ File.open("#{app_path}/config/routes.rb", 'w') do |f| - f.puts $` + "\nmatch ':controller(/:action(/:id))(.:format)'\n" + $1 + f.puts $` + "\nmatch ':controller(/:action(/:id))(.:format)', :via => :all\n" + $1 end end - add_to_config 'config.secret_token = "3b7cd727ee24e8444053437c36cc66c4"; config.session_store :cookie_store, :key => "_myapp_session"; config.active_support.deprecation = :log' + add_to_config <<-RUBY + config.eager_load = false + config.secret_token = "3b7cd727ee24e8444053437c36cc66c4" + config.session_store :cookie_store, :key => "_myapp_session" + config.active_support.deprecation = :log + config.action_controller.allow_forgery_protection = false + RUBY end def teardown_app @@ -130,6 +137,7 @@ module TestHelpers require "action_controller/railtie" app = Class.new(Rails::Application) + app.config.eager_load = false app.config.secret_token = "3b7cd727ee24e8444053437c36cc66c4" app.config.session_store :cookie_store, :key => "_myapp_session" app.config.active_support.deprecation = :log @@ -138,7 +146,7 @@ module TestHelpers app.initialize! app.routes.draw do - match "/" => "omg#index" + get "/" => "omg#index" end require 'rack/test' @@ -156,7 +164,7 @@ module TestHelpers app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do - match ':controller(/:action)' + get ':controller(/:action)' end RUBY end @@ -244,10 +252,10 @@ module TestHelpers def use_frameworks(arr) to_remove = [:actionmailer, - :activemodel, - :activerecord, - :activeresource] - arr - remove_from_config "config.active_record.dependent_restrict_raises = false" if to_remove.include? :activerecord + :activerecord] - arr + if to_remove.include? :activerecord + remove_from_config "config.active_record.whitelist_attributes = true" + end $:.reject! {|path| path =~ %r'/(#{to_remove.join('|')})/' } end @@ -261,30 +269,22 @@ class ActiveSupport::TestCase include TestHelpers::Paths include TestHelpers::Rack include TestHelpers::Generation - extend ActiveSupport::Testing::Declarative end # Create a scope and build a fixture rails app Module.new do extend TestHelpers::Paths + # Build a rails app - if File.exist?(tmp_path) - FileUtils.rm_rf(tmp_path) - end - FileUtils.mkdir(tmp_path) + FileUtils.rm_rf(app_template_path) + FileUtils.mkdir(app_template_path) environment = File.expand_path('../../../../load_paths', __FILE__) - if File.exist?("#{environment}.rb") - require_environment = "-r #{environment}" - end + require_environment = "-r #{environment}" - `#{Gem.ruby} #{require_environment} #{RAILS_FRAMEWORK_ROOT}/railties/bin/rails new #{tmp_path('app_template')}` - File.open("#{tmp_path}/app_template/config/boot.rb", 'w') do |f| - if require_environment - f.puts "Dir.chdir('#{File.dirname(environment)}') do" - f.puts " require '#{environment}'" - f.puts "end" - end + `#{Gem.ruby} #{require_environment} #{RAILS_FRAMEWORK_ROOT}/railties/bin/rails new #{app_template_path} --skip-gemfile` + File.open("#{app_template_path}/config/boot.rb", 'w') do |f| + f.puts "require '#{environment}'" f.puts "require 'rails/all'" end end unless defined?(RAILS_ISOLATED_ENGINE) diff --git a/railties/test/paths_test.rb b/railties/test/paths_test.rb index c0f3887263..76ff3ec3e4 100644 --- a/railties/test/paths_test.rb +++ b/railties/test/paths_test.rb @@ -22,7 +22,7 @@ class PathsTest < ActiveSupport::TestCase root = Rails::Paths::Root.new(nil) root.add "app" root.path = "/root" - assert_equal ["app"], root["app"] + assert_equal ["app"], root["app"].to_ary assert_equal ["/root/app"], root["app"].to_a end @@ -91,10 +91,6 @@ class PathsTest < ActiveSupport::TestCase assert_equal ["/foo/bar/app2", "/foo/bar/app"], @root["app"].to_a end - test "the root can only have one physical path" do - assert_raise(RuntimeError) { Rails::Paths::Root.new(["/fiz", "/biz"]) } - end - test "it is possible to add a path that should be autoloaded only once" do @root.add "app", :with => "/app" @root["app"].autoload_once! @@ -202,6 +198,13 @@ class PathsTest < ActiveSupport::TestCase assert_equal "*.rb", @root["app"].glob end + test "it should be possible to replace a path and persist the original paths glob" do + @root.add "app", :glob => "*.rb" + @root["app"] = "app2" + assert_equal ["/foo/bar/app2"], @root["app"].to_a + assert_equal "*.rb", @root["app"].glob + end + test "a path can be added to the load path" do @root["app"] = "app" @root["app"].load_path! diff --git a/railties/test/queueing/container_test.rb b/railties/test/queueing/container_test.rb new file mode 100644 index 0000000000..69e59a3871 --- /dev/null +++ b/railties/test/queueing/container_test.rb @@ -0,0 +1,30 @@ +require 'abstract_unit' +require 'rails/queueing' + +module Rails + module Queueing + class ContainerTest < ActiveSupport::TestCase + def test_delegates_to_default + q = Queue.new + container = Container.new q + job = Object.new + + container.push job + assert_equal job, q.pop + end + + def test_access_default + q = Queue.new + container = Container.new q + assert_equal q, container[:default] + end + + def test_assign_queue + container = Container.new Object.new + q = Object.new + container[:foo] = q + assert_equal q, container[:foo] + end + end + end +end diff --git a/railties/test/queueing/test_queue_test.rb b/railties/test/queueing/test_queue_test.rb new file mode 100644 index 0000000000..2f0f507adb --- /dev/null +++ b/railties/test/queueing/test_queue_test.rb @@ -0,0 +1,102 @@ +require 'abstract_unit' +require 'rails/queueing' + +class TestQueueTest < ActiveSupport::TestCase + def setup + @queue = Rails::Queueing::TestQueue.new + end + + class ExceptionRaisingJob + def run + raise + end + end + + def test_drain_raises + @queue.push ExceptionRaisingJob.new + assert_raises(RuntimeError) { @queue.drain } + end + + def test_jobs + @queue.push 1 + @queue.push 2 + assert_equal [1,2], @queue.jobs + end + + class EquivalentJob + def initialize + @initial_id = self.object_id + end + + def run + end + + def ==(other) + other.same_initial_id?(@initial_id) + end + + def same_initial_id?(other_id) + other_id == @initial_id + end + end + + def test_contents + assert @queue.empty? + job = EquivalentJob.new + @queue.push job + refute @queue.empty? + assert_equal job, @queue.pop + end + + class ProcessingJob + def self.clear_processed + @processed = [] + end + + def self.processed + @processed + end + + def initialize(object) + @object = object + end + + def run + self.class.processed << @object + end + end + + def test_order + ProcessingJob.clear_processed + job1 = ProcessingJob.new(1) + job2 = ProcessingJob.new(2) + + @queue.push job1 + @queue.push job2 + @queue.drain + + assert_equal [1,2], ProcessingJob.processed + end + + class ThreadTrackingJob + attr_reader :thread_id + + def run + @thread_id = Thread.current.object_id + end + + def ran? + @thread_id + end + end + + def test_drain + @queue.push ThreadTrackingJob.new + job = @queue.jobs.last + @queue.drain + + assert @queue.empty? + assert job.ran?, "The job runs synchronously when the queue is drained" + assert_not_equal job.thread_id, Thread.current.object_id + end +end diff --git a/railties/test/queueing/threaded_consumer_test.rb b/railties/test/queueing/threaded_consumer_test.rb new file mode 100644 index 0000000000..c34a966d6e --- /dev/null +++ b/railties/test/queueing/threaded_consumer_test.rb @@ -0,0 +1,100 @@ +require 'abstract_unit' +require 'rails/queueing' + +class TestThreadConsumer < ActiveSupport::TestCase + class Job + attr_reader :id + def initialize(id, &block) + @id = id + @block = block + end + + def run + @block.call if @block + end + end + + def setup + @queue = Rails::Queueing::Queue.new + @consumer = Rails::Queueing::ThreadedConsumer.start(@queue) + end + + def teardown + @queue.push nil + end + + test "the jobs are executed" do + ran = false + + job = Job.new(1) do + ran = true + end + + @queue.push job + sleep 0.1 + assert_equal true, ran + end + + test "the jobs are not executed synchronously" do + ran = false + + job = Job.new(1) do + sleep 0.1 + ran = true + end + + @queue.push job + assert_equal false, ran + end + + test "shutting down the queue synchronously drains the jobs" do + ran = false + + job = Job.new(1) do + sleep 0.1 + ran = true + end + + @queue.push job + assert_equal false, ran + + @consumer.shutdown + + assert_equal true, ran + end + + test "log job that raises an exception" do + require "active_support/log_subscriber/test_helper" + logger = ActiveSupport::LogSubscriber::TestHelper::MockLogger.new + Rails.logger = logger + + job = Job.new(1) do + raise "RuntimeError: Error!" + end + + @queue.push job + sleep 0.1 + + assert_equal 1, logger.logged(:error).size + assert_match(/Job Error: RuntimeError: Error!/, logger.logged(:error).last) + end + + test "test overriding exception handling" do + @consumer.shutdown + @consumer = Class.new(Rails::Queueing::ThreadedConsumer) do + attr_reader :last_error + def handle_exception(e) + @last_error = e.message + end + end.start(@queue) + + job = Job.new(1) do + raise "RuntimeError: Error!" + end + + @queue.push job + sleep 0.1 + + assert_equal "RuntimeError: Error!", @consumer.last_error + end +end diff --git a/railties/test/rails_info_controller_test.rb b/railties/test/rails_info_controller_test.rb index 8a9363fb80..cfb32b7d35 100644 --- a/railties/test/rails_info_controller_test.rb +++ b/railties/test/rails_info_controller_test.rb @@ -11,30 +11,29 @@ class InfoControllerTest < ActionController::TestCase def setup Rails.application.routes.draw do - match '/rails/info/properties' => "rails/info#properties" + get '/rails/info/properties' => "rails/info#properties" + get '/rails/info/routes' => "rails/info#routes" end - @request.stubs(:local? => true) - @controller.stubs(:consider_all_requests_local? => false) + @controller.stubs(:local_request? => true) @routes = Rails.application.routes Rails::InfoController.send(:include, @routes.url_helpers) end test "info controller does not allow remote requests" do - @request.stubs(:local? => false) + @controller.stubs(:local_request? => false) get :properties assert_response :forbidden end test "info controller renders an error message when request was forbidden" do - @request.stubs(:local? => false) + @controller.stubs(:local_request? => false) get :properties assert_select 'p' end test "info controller allows requests when all requests are considered local" do - @request.stubs(:local? => false) - @controller.stubs(:consider_all_requests_local? => true) + @controller.stubs(:local_request? => true) get :properties assert_response :success end @@ -48,4 +47,10 @@ class InfoControllerTest < ActionController::TestCase get :properties assert_select 'table' end + + test "info controller renders with routes" do + get :routes + assert_select 'pre' + end + end diff --git a/railties/test/rails_info_test.rb b/railties/test/rails_info_test.rb index 1da66062aa..b9fb071d23 100644 --- a/railties/test/rails_info_test.rb +++ b/railties/test/rails_info_test.rb @@ -43,7 +43,7 @@ class InfoTest < ActiveSupport::TestCase def test_frameworks_exist Rails::Info.frameworks.each do |framework| - dir = File.dirname(__FILE__) + "/../../" + framework.gsub('_', '') + dir = File.dirname(__FILE__) + "/../../" + framework.delete('_') assert File.directory?(dir), "#{framework.classify} does not exist" end end diff --git a/railties/test/railties/engine_test.rb b/railties/test/railties/engine_test.rb index 5ed923a484..e52b3efdab 100644 --- a/railties/test/railties/engine_test.rb +++ b/railties/test/railties/engine_test.rb @@ -1,5 +1,4 @@ require "isolation/abstract_unit" -require "railties/shared_tests" require "stringio" require "rack/test" @@ -7,7 +6,6 @@ module RailtiesTest class EngineTest < ActiveSupport::TestCase include ActiveSupport::Testing::Isolation - include SharedTests include Rack::Test::Methods def setup @@ -29,6 +27,395 @@ module RailtiesTest teardown_app end + def boot_rails + super + require "#{app_path}/config/environment" + end + + test "serving sprocket's assets" do + @plugin.write "app/assets/javascripts/engine.js.erb", "<%= :alert %>();" + + boot_rails + require 'rack/test' + extend Rack::Test::Methods + + get "/assets/engine.js" + assert_match "alert()", last_response.body + end + + test "rake environment can be called in the engine" do + boot_rails + + @plugin.write "Rakefile", <<-RUBY + APP_RAKEFILE = '#{app_path}/Rakefile' + load 'rails/tasks/engine.rake' + task :foo => :environment do + puts "Task ran" + end + RUBY + + Dir.chdir(@plugin.path) do + output = `bundle exec rake foo` + assert_match "Task ran", output + end + end + + test "copying migrations" do + @plugin.write "db/migrate/1_create_users.rb", <<-RUBY + class CreateUsers < ActiveRecord::Migration + end + RUBY + + @plugin.write "db/migrate/2_add_last_name_to_users.rb", <<-RUBY + class AddLastNameToUsers < ActiveRecord::Migration + end + RUBY + + @plugin.write "db/migrate/3_create_sessions.rb", <<-RUBY + class CreateSessions < ActiveRecord::Migration + end + RUBY + + app_file "db/migrate/1_create_sessions.rb", <<-RUBY + class CreateSessions < ActiveRecord::Migration + def up + end + end + RUBY + + add_to_config "ActiveRecord::Base.timestamped_migrations = false" + + boot_rails + + Dir.chdir(app_path) do + output = `bundle exec rake bukkits:install:migrations` + + assert File.exists?("#{app_path}/db/migrate/2_create_users.bukkits.rb") + assert File.exists?("#{app_path}/db/migrate/3_add_last_name_to_users.bukkits.rb") + assert_match(/Copied migration 2_create_users.bukkits.rb from bukkits/, output) + assert_match(/Copied migration 3_add_last_name_to_users.bukkits.rb from bukkits/, output) + assert_match(/NOTE: Migration 3_create_sessions.rb from bukkits has been skipped/, output) + assert_equal 3, Dir["#{app_path}/db/migrate/*.rb"].length + + output = `bundle exec rake railties:install:migrations`.split("\n") + + assert_no_match(/2_create_users/, output.join("\n")) + + bukkits_migration_order = output.index(output.detect{|o| /NOTE: Migration 3_create_sessions.rb from bukkits has been skipped/ =~ o }) + assert_not_nil bukkits_migration_order, "Expected migration to be skipped" + + migrations_count = Dir["#{app_path}/db/migrate/*.rb"].length + output = `bundle exec rake railties:install:migrations` + + assert_equal migrations_count, Dir["#{app_path}/db/migrate/*.rb"].length + end + end + + test "mountable engine should copy migrations within engine_path" do + @plugin.write "lib/bukkits.rb", <<-RUBY + module Bukkits + class Engine < ::Rails::Engine + isolate_namespace Bukkits + end + end + RUBY + + @plugin.write "db/migrate/0_add_first_name_to_users.rb", <<-RUBY + class AddFirstNameToUsers < ActiveRecord::Migration + end + RUBY + + @plugin.write "Rakefile", <<-RUBY + APP_RAKEFILE = '#{app_path}/Rakefile' + load 'rails/tasks/engine.rake' + RUBY + + add_to_config "ActiveRecord::Base.timestamped_migrations = false" + + boot_rails + + Dir.chdir(@plugin.path) do + output = `bundle exec rake app:bukkits:install:migrations` + assert File.exists?("#{app_path}/db/migrate/0_add_first_name_to_users.bukkits.rb") + assert_match(/Copied migration 0_add_first_name_to_users.bukkits.rb from bukkits/, output) + assert_equal 1, Dir["#{app_path}/db/migrate/*.rb"].length + end + end + + test "no rake task without migrations" do + boot_rails + require 'rake' + require 'rdoc/task' + require 'rake/testtask' + Rails.application.load_tasks + assert !Rake::Task.task_defined?('bukkits:install:migrations') + end + + test "puts its lib directory on load path" do + boot_rails + require "another" + assert_equal "Another", Another.name + end + + test "puts its models directory on autoload path" do + @plugin.write "app/models/my_bukkit.rb", "class MyBukkit ; end" + boot_rails + assert_nothing_raised { MyBukkit } + end + + test "puts its controllers directory on autoload path" do + @plugin.write "app/controllers/bukkit_controller.rb", "class BukkitController ; end" + boot_rails + assert_nothing_raised { BukkitController } + end + + test "adds its views to view paths" do + @plugin.write "app/controllers/bukkit_controller.rb", <<-RUBY + class BukkitController < ActionController::Base + def index + end + end + RUBY + + @plugin.write "app/views/bukkit/index.html.erb", "Hello bukkits" + + boot_rails + + require "action_controller" + require "rack/mock" + response = BukkitController.action(:index).call(Rack::MockRequest.env_for("/")) + assert_equal "Hello bukkits\n", response[2].body + end + + test "adds its views to view paths with lower proriority than app ones" do + @plugin.write "app/controllers/bukkit_controller.rb", <<-RUBY + class BukkitController < ActionController::Base + def index + end + end + RUBY + + @plugin.write "app/views/bukkit/index.html.erb", "Hello bukkits" + app_file "app/views/bukkit/index.html.erb", "Hi bukkits" + + boot_rails + + require "action_controller" + require "rack/mock" + response = BukkitController.action(:index).call(Rack::MockRequest.env_for("/")) + assert_equal "Hi bukkits\n", response[2].body + end + + test "adds helpers to controller views" do + @plugin.write "app/controllers/bukkit_controller.rb", <<-RUBY + class BukkitController < ActionController::Base + def index + end + end + RUBY + + @plugin.write "app/helpers/bukkit_helper.rb", <<-RUBY + module BukkitHelper + def bukkits + "bukkits" + end + end + RUBY + + @plugin.write "app/views/bukkit/index.html.erb", "Hello <%= bukkits %>" + + boot_rails + + require "rack/mock" + response = BukkitController.action(:index).call(Rack::MockRequest.env_for("/")) + assert_equal "Hello bukkits\n", response[2].body + end + + test "autoload any path under app" do + @plugin.write "app/anything/foo.rb", <<-RUBY + module Foo; end + RUBY + boot_rails + assert Foo + end + + test "routes are added to router" do + @plugin.write "config/routes.rb", <<-RUBY + class Sprokkit + def self.call(env) + [200, {'Content-Type' => 'text/html'}, ["I am a Sprokkit"]] + end + end + + Rails.application.routes.draw do + get "/sprokkit", :to => Sprokkit + end + RUBY + + boot_rails + require 'rack/test' + extend Rack::Test::Methods + + get "/sprokkit" + assert_equal "I am a Sprokkit", last_response.body + end + + test "routes in engines have lower priority than application ones" do + controller "foo", <<-RUBY + class FooController < ActionController::Base + def index + render :text => "foo" + end + end + RUBY + + app_file "config/routes.rb", <<-RUBY + AppTemplate::Application.routes.draw do + get 'foo', :to => 'foo#index' + end + RUBY + + @plugin.write "app/controllers/bar_controller.rb", <<-RUBY + class BarController < ActionController::Base + def index + render :text => "bar" + end + end + RUBY + + @plugin.write "config/routes.rb", <<-RUBY + Rails.application.routes.draw do + get 'foo', :to => 'bar#index' + get 'bar', :to => 'bar#index' + end + RUBY + + boot_rails + require 'rack/test' + extend Rack::Test::Methods + + get '/foo' + assert_equal 'foo', last_response.body + + get '/bar' + assert_equal 'bar', last_response.body + end + + test "rake tasks lib tasks are loaded" do + $executed = false + @plugin.write "lib/tasks/foo.rake", <<-RUBY + task :foo do + $executed = true + end + RUBY + + boot_rails + require 'rake' + require 'rdoc/task' + require 'rake/testtask' + Rails.application.load_tasks + Rake::Task[:foo].invoke + assert $executed + end + + test "i18n files have lower priority than application ones" do + add_to_config <<-RUBY + config.i18n.load_path << "#{app_path}/app/locales/en.yml" + RUBY + + app_file 'app/locales/en.yml', <<-YAML +en: + bar: "1" +YAML + + app_file 'config/locales/en.yml', <<-YAML +en: + foo: "2" + bar: "2" +YAML + + @plugin.write 'config/locales/en.yml', <<-YAML +en: + foo: "3" +YAML + + boot_rails + + expected_locales = %W( + #{RAILS_FRAMEWORK_ROOT}/activesupport/lib/active_support/locale/en.yml + #{RAILS_FRAMEWORK_ROOT}/activemodel/lib/active_model/locale/en.yml + #{RAILS_FRAMEWORK_ROOT}/activerecord/lib/active_record/locale/en.yml + #{RAILS_FRAMEWORK_ROOT}/actionpack/lib/action_view/locale/en.yml + #{@plugin.path}/config/locales/en.yml + #{app_path}/config/locales/en.yml + #{app_path}/app/locales/en.yml + ).map { |path| File.expand_path(path) } + + actual_locales = I18n.load_path.map { |path| + File.expand_path(path) + } & expected_locales # remove locales external to Rails + + assert_equal expected_locales, actual_locales + + assert_equal "2", I18n.t(:foo) + assert_equal "1", I18n.t(:bar) + end + + test "namespaced controllers with namespaced routes" do + @plugin.write "config/routes.rb", <<-RUBY + Rails.application.routes.draw do + namespace :admin do + namespace :foo do + get "bar", :to => "bar#index" + end + end + end + RUBY + + @plugin.write "app/controllers/admin/foo/bar_controller.rb", <<-RUBY + class Admin::Foo::BarController < ApplicationController + def index + render :text => "Rendered from namespace" + end + end + RUBY + + boot_rails + require 'rack/test' + extend Rack::Test::Methods + + get "/admin/foo/bar" + assert_equal 200, last_response.status + assert_equal "Rendered from namespace", last_response.body + end + + test "initializers" do + $plugin_initializer = false + @plugin.write "config/initializers/foo.rb", <<-RUBY + $plugin_initializer = true + RUBY + + boot_rails + assert $plugin_initializer + end + + test "midleware referenced in configuration" do + @plugin.write "lib/bukkits.rb", <<-RUBY + class Bukkits + def initialize(app) + @app = app + end + + def call(env) + @app.call(env) + end + end + RUBY + + add_to_config "config.middleware.use \"Bukkits\"" + boot_rails + end + test "Rails::Engine itself does not respond to config" do boot_rails assert !Rails::Engine.respond_to?(:config) @@ -60,7 +447,6 @@ module RailtiesTest assert index < initializers.index { |i| i.name == :build_middleware_stack } end - class Upcaser def initialize(app) @app = app @@ -135,7 +521,7 @@ module RailtiesTest @plugin.write "config/routes.rb", <<-RUBY Bukkits::Engine.routes.draw do - match "/foo" => lambda { |env| [200, {'Content-Type' => 'text/html'}, ['foo']] } + get "/foo" => lambda { |env| [200, {'Content-Type' => 'text/html'}, ['foo']] } end RUBY @@ -151,10 +537,11 @@ module RailtiesTest assert_equal "foo", last_response.body end - test "it loads its environment file" do + test "it loads its environments file" do @plugin.write "lib/bukkits.rb", <<-RUBY module Bukkits class Engine < ::Rails::Engine + config.paths["config/environments"].push "config/environments/additional.rb" end end RUBY @@ -165,9 +552,16 @@ module RailtiesTest end RUBY + @plugin.write "config/environments/additional.rb", <<-RUBY + Bukkits::Engine.configure do + config.additional_environment_loaded = true + end + RUBY + boot_rails assert Bukkits::Engine.config.environment_loaded + assert Bukkits::Engine.config.additional_environment_loaded end test "it passes router in env" do @@ -214,18 +608,18 @@ module RailtiesTest app_file "config/routes.rb", <<-RUBY AppTemplate::Application.routes.draw do - match "/bar" => "bar#index", :as => "bar" + get "/bar" => "bar#index", :as => "bar" mount Bukkits::Engine => "/bukkits", :as => "bukkits" end RUBY @plugin.write "config/routes.rb", <<-RUBY Bukkits::Engine.routes.draw do - match "/foo" => "foo#index", :as => "foo" - match "/foo/show" => "foo#show" - match "/from_app" => "foo#from_app" - match "/routes_helpers_in_view" => "foo#routes_helpers_in_view" - match "/polymorphic_path_without_namespace" => "foo#polymorphic_path_without_namespace" + get "/foo" => "foo#index", :as => "foo" + get "/foo/show" => "foo#show" + get "/from_app" => "foo#from_app" + get "/routes_helpers_in_view" => "foo#routes_helpers_in_view" + get "/polymorphic_path_without_namespace" => "foo#polymorphic_path_without_namespace" resources :posts end RUBY @@ -382,7 +776,7 @@ module RailtiesTest @plugin.write "config/routes.rb", <<-RUBY Bukkits::Awesome::Engine.routes.draw do - match "/foo" => "foo#index" + get "/foo" => "foo#index" end RUBY @@ -476,8 +870,6 @@ module RailtiesTest boot_rails - require "#{rails_root}/config/environment" - get("/foo") assert_equal "foo", last_response.body @@ -490,7 +882,7 @@ module RailtiesTest module Bukkits class Engine < ::Rails::Engine config.generators do |g| - g.orm :datamapper + g.orm :data_mapper g.template_engine :haml g.test_framework :rspec end @@ -511,7 +903,6 @@ module RailtiesTest RUBY boot_rails - require "#{rails_root}/config/environment" app_generators = Rails.application.config.generators.options[:rails] assert_equal :mongoid , app_generators[:orm] @@ -519,7 +910,7 @@ module RailtiesTest assert_equal :test_unit, app_generators[:test_framework] generators = Bukkits::Engine.config.generators.options[:rails] - assert_equal :datamapper, generators[:orm] + assert_equal :data_mapper, generators[:orm] assert_equal :haml , generators[:template_engine] assert_equal :rspec , generators[:test_framework] end @@ -534,7 +925,6 @@ module RailtiesTest RUBY boot_rails - require "#{rails_root}/config/environment" generators = Bukkits::Engine.config.generators.options[:rails] assert_equal :active_record, generators[:orm] @@ -558,7 +948,6 @@ module RailtiesTest RUBY boot_rails - require "#{rails_root}/config/environment" assert_equal "foo", Bukkits.table_name_prefix end @@ -572,7 +961,6 @@ module RailtiesTest RUBY boot_rails - require "#{rails_root}/config/environment" assert_equal Bukkits::Engine.instance, Rails::Engine.find(@plugin.path) @@ -620,11 +1008,8 @@ module RailtiesTest add_to_config("config.action_dispatch.show_exceptions = false") boot_rails - require "#{rails_root}/config/environment" - methods = Bukkits::Engine.helpers.public_instance_methods.collect(&:to_s).sort - expected = ["bar", "baz"] - assert_equal expected, methods + assert_equal [:bar, :baz], Bukkits::Engine.helpers.public_instance_methods.sort end test "setting priority for engines with config.railties_order" do @@ -659,8 +1044,8 @@ module RailtiesTest app_file "config/routes.rb", <<-RUBY Rails.application.routes.draw do - match "/foo" => "main#foo" - match "/bar" => "main#bar" + get "/foo" => "main#foo" + get "/bar" => "main#bar" end RUBY @@ -699,7 +1084,6 @@ module RailtiesTest add_to_config("config.railties_order = [:all, :main_app, Blog::Engine]") boot_rails - require "#{rails_root}/config/environment" get("/foo") assert_equal "Bukkit's foo partial", last_response.body.strip @@ -712,6 +1096,10 @@ module RailtiesTest get("/assets/bar.js") assert_equal "// App's bar js\n;", last_response.body.strip + + # ensure that railties are not added twice + railties = Rails.application.send(:ordered_railties).map(&:class) + assert_equal railties, railties.uniq end test "railties_order adds :all with lowest priority if not given" do @@ -732,7 +1120,7 @@ module RailtiesTest app_file "config/routes.rb", <<-RUBY Rails.application.routes.draw do - match "/foo" => "main#foo" + get "/foo" => "main#foo" end RUBY @@ -747,12 +1135,112 @@ module RailtiesTest add_to_config("config.railties_order = [Bukkits::Engine]") boot_rails - require "#{rails_root}/config/environment" get("/foo") assert_equal "Bukkit's foo partial", last_response.body.strip end + test "engine can be properly mounted at root" do + add_to_config("config.action_dispatch.show_exceptions = false") + add_to_config("config.serve_static_assets = false") + + @plugin.write "lib/bukkits.rb", <<-RUBY + module Bukkits + class Engine < ::Rails::Engine + isolate_namespace ::Bukkits + end + end + RUBY + + @plugin.write "config/routes.rb", <<-RUBY + Bukkits::Engine.routes.draw do + root "foo#index" + end + RUBY + + @plugin.write "app/controllers/bukkits/foo_controller.rb", <<-RUBY + module Bukkits + class FooController < ActionController::Base + def index + text = <<-TEXT + script_name: \#{request.script_name} + fullpath: \#{request.fullpath} + path: \#{request.path} + TEXT + render :text => text + end + end + end + RUBY + + + app_file "config/routes.rb", <<-RUBY + Rails.application.routes.draw do + mount Bukkits::Engine => "/" + end + RUBY + + boot_rails + + expected = <<-TEXT + script_name: + fullpath: / + path: / + TEXT + + get("/") + assert_equal expected.split("\n").map(&:strip), + last_response.body.split("\n").map(&:strip) + end + + test "paths are properly generated when application is mounted at sub-path" do + @plugin.write "lib/bukkits.rb", <<-RUBY + module Bukkits + class Engine < ::Rails::Engine + isolate_namespace Bukkits + end + end + RUBY + + app_file "app/controllers/bar_controller.rb", <<-RUBY + class BarController < ApplicationController + def index + render :text => bukkits.bukkit_path + end + end + RUBY + + app_file "config/routes.rb", <<-RUBY + AppTemplate::Application.routes.draw do + get '/bar' => 'bar#index', :as => 'bar' + mount Bukkits::Engine => "/bukkits", :as => "bukkits" + end + RUBY + + @plugin.write "config/routes.rb", <<-RUBY + Bukkits::Engine.routes.draw do + get '/bukkit' => 'bukkit#index' + end + RUBY + + + @plugin.write "app/controllers/bukkits/bukkit_controller.rb", <<-RUBY + class Bukkits::BukkitController < ActionController::Base + def index + render :text => main_app.bar_path + end + end + RUBY + + boot_rails + + get("/bukkits/bukkit", {}, {'SCRIPT_NAME' => '/foo'}) + assert_equal '/foo/bar', last_response.body + + get("/bar", {}, {'SCRIPT_NAME' => '/foo'}) + assert_equal '/foo/bukkits/bukkit', last_response.body + end + private def app Rails.application diff --git a/railties/test/railties/generators_test.rb b/railties/test/railties/generators_test.rb index 6ebbabc0ff..c90b795d59 100644 --- a/railties/test/railties/generators_test.rb +++ b/railties/test/railties/generators_test.rb @@ -8,11 +8,13 @@ module RailtiesTests class GeneratorTest < Rails::Generators::TestCase include ActiveSupport::Testing::Isolation - TMP_PATH = File.expand_path(File.join(File.dirname(__FILE__), *%w[.. .. tmp])) - self.destination_root = File.join(TMP_PATH, "foo_bar") + def destination_root + tmp_path 'foo_bar' + end def tmp_path(*args) - File.join(TMP_PATH, *args) + @tmp_path ||= File.realpath(Dir.mktmpdir) + File.join(@tmp_path, *args) end def engine_path @@ -73,6 +75,18 @@ module RailtiesTests end end + def test_table_name_prefix_is_correctly_namespaced_when_engine_is_mountable + build_mountable_engine + Dir.chdir(engine_path) do + bundled_rails("g model namespaced/topic") + assert_file "app/models/foo_bar/namespaced.rb", /module FooBar\n module Namespaced/ do |content| + assert_class_method :table_name_prefix, content do |method_content| + assert_match(/'foo_bar_namespaced_'/, method_content) + end + end + end + end + def test_helpers_are_correctly_namespaced_when_engine_is_mountable build_mountable_engine Dir.chdir(engine_path) do diff --git a/railties/test/railties/mounted_engine_test.rb b/railties/test/railties/mounted_engine_test.rb index 2bb9df6b64..bd13c3aba3 100644 --- a/railties/test/railties/mounted_engine_test.rb +++ b/railties/test/railties/mounted_engine_test.rb @@ -18,13 +18,13 @@ module ApplicationTests AppTemplate::Application.routes.draw do mount Weblog::Engine, :at => '/', :as => 'weblog' resources :posts - match "/engine_route" => "application_generating#engine_route" - match "/engine_route_in_view" => "application_generating#engine_route_in_view" - match "/weblog_engine_route" => "application_generating#weblog_engine_route" - match "/weblog_engine_route_in_view" => "application_generating#weblog_engine_route_in_view" - match "/url_for_engine_route" => "application_generating#url_for_engine_route" - match "/polymorphic_route" => "application_generating#polymorphic_route" - match "/application_polymorphic_path" => "application_generating#application_polymorphic_path" + get "/engine_route" => "application_generating#engine_route" + get "/engine_route_in_view" => "application_generating#engine_route_in_view" + get "/weblog_engine_route" => "application_generating#weblog_engine_route" + get "/weblog_engine_route_in_view" => "application_generating#weblog_engine_route_in_view" + get "/url_for_engine_route" => "application_generating#url_for_engine_route" + get "/polymorphic_route" => "application_generating#polymorphic_route" + get "/application_polymorphic_path" => "application_generating#application_polymorphic_path" scope "/:user", :user => "anonymous" do mount Blog::Engine => "/blog" end @@ -42,7 +42,7 @@ module ApplicationTests @simple_plugin.write "config/routes.rb", <<-RUBY Weblog::Engine.routes.draw do - match '/weblog' => "weblogs#index", :as => 'weblogs' + get '/weblog' => "weblogs#index", :as => 'weblogs' end RUBY @@ -86,9 +86,9 @@ module ApplicationTests @plugin.write "config/routes.rb", <<-RUBY Blog::Engine.routes.draw do resources :posts - match '/generate_application_route', :to => 'posts#generate_application_route' - match '/application_route_in_view', :to => 'posts#application_route_in_view' - match '/engine_polymorphic_path', :to => 'posts#engine_polymorphic_path' + get '/generate_application_route', :to => 'posts#generate_application_route' + get '/application_route_in_view', :to => 'posts#application_route_in_view' + get '/engine_polymorphic_path', :to => 'posts#engine_polymorphic_path' end RUBY @@ -163,24 +163,14 @@ module ApplicationTests end end - def reset_script_name! - Rails.application.routes.default_url_options = {} - end - - def script_name(script_name) - Rails.application.routes.default_url_options = {:script_name => script_name} - end - test "routes generation in engine and application" do # test generating engine's route from engine get "/john/blog/posts" assert_equal "/john/blog/posts/1", last_response.body # test generating engine's route from engine with default_url_options - script_name "/foo" get "/john/blog/posts", {}, 'SCRIPT_NAME' => "/foo" assert_equal "/foo/john/blog/posts/1", last_response.body - reset_script_name! # test generating engine's route from application get "/engine_route" @@ -193,14 +183,11 @@ module ApplicationTests assert_equal "/john/blog/posts", last_response.body # test generating engine's route from application with default_url_options - script_name "/foo" get "/engine_route", {}, 'SCRIPT_NAME' => "/foo" assert_equal "/foo/anonymous/blog/posts", last_response.body - script_name "/foo" get "/url_for_engine_route", {}, 'SCRIPT_NAME' => "/foo" assert_equal "/foo/john/blog/posts", last_response.body - reset_script_name! # test generating application's route from engine get "/someone/blog/generate_application_route" @@ -210,10 +197,8 @@ module ApplicationTests assert_equal "/", last_response.body # test generating application's route from engine with default_url_options - script_name "/foo" get "/someone/blog/generate_application_route", {}, 'SCRIPT_NAME' => '/foo' assert_equal "/foo/", last_response.body - reset_script_name! # test polymorphic routes get "/polymorphic_route" diff --git a/railties/test/railties/railtie_test.rb b/railties/test/railties/railtie_test.rb index cd495320b5..c80b0f63af 100644 --- a/railties/test/railties/railtie_test.rb +++ b/railties/test/railties/railtie_test.rb @@ -163,6 +163,22 @@ module RailtiesTest assert $ran_block end + test "runner block is executed when MyApp.load_runner is called" do + $ran_block = false + + class MyTie < Rails::Railtie + runner do + $ran_block = true + end + end + + require "#{app_path}/config/environment" + + assert !$ran_block + AppTemplate::Application.load_runner + assert $ran_block + end + test "railtie can add initializers" do $ran_block = false diff --git a/railties/test/railties/shared_tests.rb b/railties/test/railties/shared_tests.rb deleted file mode 100644 index 3630a0937c..0000000000 --- a/railties/test/railties/shared_tests.rb +++ /dev/null @@ -1,367 +0,0 @@ -module RailtiesTest - # Holds tests shared between plugin and engines - module SharedTests - def boot_rails - super - require "#{app_path}/config/environment" - end - - def app - @app ||= Rails.application - end - - def test_serving_sprockets_assets - @plugin.write "app/assets/javascripts/engine.js.erb", "<%= :alert %>();" - - boot_rails - require 'rack/test' - extend Rack::Test::Methods - - get "/assets/engine.js" - assert_match "alert()", last_response.body - end - - def test_rake_environment_can_be_called_in_the_engine_or_plugin - boot_rails - - @plugin.write "Rakefile", <<-RUBY - APP_RAKEFILE = '#{app_path}/Rakefile' - load 'rails/tasks/engine.rake' - task :foo => :environment do - puts "Task ran" - end - RUBY - - Dir.chdir(@plugin.path) do - output = `bundle exec rake foo` - assert_match "Task ran", output - end - end - - def test_copying_migrations - @plugin.write "db/migrate/1_create_users.rb", <<-RUBY - class CreateUsers < ActiveRecord::Migration - end - RUBY - - @plugin.write "db/migrate/2_add_last_name_to_users.rb", <<-RUBY - class AddLastNameToUsers < ActiveRecord::Migration - end - RUBY - - @plugin.write "db/migrate/3_create_sessions.rb", <<-RUBY - class CreateSessions < ActiveRecord::Migration - end - RUBY - - app_file "db/migrate/1_create_sessions.rb", <<-RUBY - class CreateSessions < ActiveRecord::Migration - def up - end - end - RUBY - - add_to_config "ActiveRecord::Base.timestamped_migrations = false" - - boot_rails - railties = Rails.application.railties.all.map(&:railtie_name) - - Dir.chdir(app_path) do - output = `bundle exec rake bukkits:install:migrations` - - assert File.exists?("#{app_path}/db/migrate/2_create_users.bukkits.rb") - assert File.exists?("#{app_path}/db/migrate/3_add_last_name_to_users.bukkits.rb") - assert_match(/Copied migration 2_create_users.bukkits.rb from bukkits/, output) - assert_match(/Copied migration 3_add_last_name_to_users.bukkits.rb from bukkits/, output) - assert_match(/NOTE: Migration 3_create_sessions.rb from bukkits has been skipped/, output) - assert_equal 3, Dir["#{app_path}/db/migrate/*.rb"].length - - output = `bundle exec rake railties:install:migrations`.split("\n") - - assert_no_match(/2_create_users/, output.join("\n")) - - bukkits_migration_order = output.index(output.detect{|o| /NOTE: Migration 3_create_sessions.rb from bukkits has been skipped/ =~ o }) - assert_not_nil bukkits_migration_order, "Expected migration to be skipped" - - migrations_count = Dir["#{app_path}/db/migrate/*.rb"].length - output = `bundle exec rake railties:install:migrations` - - assert_equal migrations_count, Dir["#{app_path}/db/migrate/*.rb"].length - end - end - - def test_no_rake_task_without_migrations - boot_rails - require 'rake' - require 'rdoc/task' - require 'rake/testtask' - Rails.application.load_tasks - assert !Rake::Task.task_defined?('bukkits:install:migrations') - end - - def test_puts_its_lib_directory_on_load_path - boot_rails - require "another" - assert_equal "Another", Another.name - end - - def test_puts_its_models_directory_on_autoload_path - @plugin.write "app/models/my_bukkit.rb", "class MyBukkit ; end" - boot_rails - assert_nothing_raised { MyBukkit } - end - - def test_puts_its_controllers_directory_on_autoload_path - @plugin.write "app/controllers/bukkit_controller.rb", "class BukkitController ; end" - boot_rails - assert_nothing_raised { BukkitController } - end - - def test_adds_its_views_to_view_paths - @plugin.write "app/controllers/bukkit_controller.rb", <<-RUBY - class BukkitController < ActionController::Base - def index - end - end - RUBY - - @plugin.write "app/views/bukkit/index.html.erb", "Hello bukkits" - - boot_rails - - require "action_controller" - require "rack/mock" - response = BukkitController.action(:index).call(Rack::MockRequest.env_for("/")) - assert_equal "Hello bukkits\n", response[2].body - end - - def test_adds_its_views_to_view_paths_with_lower_proriority_than_app_ones - @plugin.write "app/controllers/bukkit_controller.rb", <<-RUBY - class BukkitController < ActionController::Base - def index - end - end - RUBY - - @plugin.write "app/views/bukkit/index.html.erb", "Hello bukkits" - app_file "app/views/bukkit/index.html.erb", "Hi bukkits" - - boot_rails - - require "action_controller" - require "rack/mock" - response = BukkitController.action(:index).call(Rack::MockRequest.env_for("/")) - assert_equal "Hi bukkits\n", response[2].body - end - - def test_adds_helpers_to_controller_views - @plugin.write "app/controllers/bukkit_controller.rb", <<-RUBY - class BukkitController < ActionController::Base - def index - end - end - RUBY - - @plugin.write "app/helpers/bukkit_helper.rb", <<-RUBY - module BukkitHelper - def bukkits - "bukkits" - end - end - RUBY - - @plugin.write "app/views/bukkit/index.html.erb", "Hello <%= bukkits %>" - - boot_rails - - require "rack/mock" - response = BukkitController.action(:index).call(Rack::MockRequest.env_for("/")) - assert_equal "Hello bukkits\n", response[2].body - end - - def test_autoload_any_path_under_app - @plugin.write "app/anything/foo.rb", <<-RUBY - module Foo; end - RUBY - boot_rails - assert Foo - end - - def test_routes_are_added_to_router - @plugin.write "config/routes.rb", <<-RUBY - class Sprokkit - def self.call(env) - [200, {'Content-Type' => 'text/html'}, ["I am a Sprokkit"]] - end - end - - Rails.application.routes.draw do - match "/sprokkit", :to => Sprokkit - end - RUBY - - boot_rails - require 'rack/test' - extend Rack::Test::Methods - - get "/sprokkit" - assert_equal "I am a Sprokkit", last_response.body - end - - def test_routes_in_plugins_have_lower_priority_than_application_ones - controller "foo", <<-RUBY - class FooController < ActionController::Base - def index - render :text => "foo" - end - end - RUBY - - app_file "config/routes.rb", <<-RUBY - AppTemplate::Application.routes.draw do - match 'foo', :to => 'foo#index' - end - RUBY - - @plugin.write "app/controllers/bar_controller.rb", <<-RUBY - class BarController < ActionController::Base - def index - render :text => "bar" - end - end - RUBY - - @plugin.write "config/routes.rb", <<-RUBY - Rails.application.routes.draw do - match 'foo', :to => 'bar#index' - match 'bar', :to => 'bar#index' - end - RUBY - - boot_rails - require 'rack/test' - extend Rack::Test::Methods - - get '/foo' - assert_equal 'foo', last_response.body - - get '/bar' - assert_equal 'bar', last_response.body - end - - def test_rake_tasks_lib_tasks_are_loaded - $executed = false - @plugin.write "lib/tasks/foo.rake", <<-RUBY - task :foo do - $executed = true - end - RUBY - - boot_rails - require 'rake' - require 'rdoc/task' - require 'rake/testtask' - Rails.application.load_tasks - Rake::Task[:foo].invoke - assert $executed - end - - def test_i18n_files_have_lower_priority_than_application_ones - add_to_config <<-RUBY - config.i18n.load_path << "#{app_path}/app/locales/en.yml" - RUBY - - app_file 'app/locales/en.yml', <<-YAML -en: - bar: "1" -YAML - - app_file 'config/locales/en.yml', <<-YAML -en: - foo: "2" - bar: "2" -YAML - - @plugin.write 'config/locales/en.yml', <<-YAML -en: - foo: "3" -YAML - - boot_rails - - expected_locales = %W( - #{RAILS_FRAMEWORK_ROOT}/activesupport/lib/active_support/locale/en.yml - #{RAILS_FRAMEWORK_ROOT}/activemodel/lib/active_model/locale/en.yml - #{RAILS_FRAMEWORK_ROOT}/activerecord/lib/active_record/locale/en.yml - #{RAILS_FRAMEWORK_ROOT}/actionpack/lib/action_view/locale/en.yml - #{@plugin.path}/config/locales/en.yml - #{app_path}/config/locales/en.yml - #{app_path}/app/locales/en.yml - ).map { |path| File.expand_path(path) } - - actual_locales = I18n.load_path.map { |path| - File.expand_path(path) - } & expected_locales # remove locales external to Rails - - assert_equal expected_locales, actual_locales - - assert_equal "2", I18n.t(:foo) - assert_equal "1", I18n.t(:bar) - end - - def test_namespaced_controllers_with_namespaced_routes - @plugin.write "config/routes.rb", <<-RUBY - Rails.application.routes.draw do - namespace :admin do - namespace :foo do - match "bar", :to => "bar#index" - end - end - end - RUBY - - @plugin.write "app/controllers/admin/foo/bar_controller.rb", <<-RUBY - class Admin::Foo::BarController < ApplicationController - def index - render :text => "Rendered from namespace" - end - end - RUBY - - boot_rails - require 'rack/test' - extend Rack::Test::Methods - - get "/admin/foo/bar" - assert_equal 200, last_response.status - assert_equal "Rendered from namespace", last_response.body - end - - def test_initializers - $plugin_initializer = false - @plugin.write "config/initializers/foo.rb", <<-RUBY - $plugin_initializer = true - RUBY - - boot_rails - assert $plugin_initializer - end - - def test_midleware_referenced_in_configuration - @plugin.write "lib/bukkits.rb", <<-RUBY - class Bukkits - def initialize(app) - @app = app - end - - def call(env) - @app.call(env) - end - end - RUBY - - add_to_config "config.middleware.use \"Bukkits\"" - boot_rails - end - end -end |