diff options
Diffstat (limited to 'railties/test/generators')
20 files changed, 897 insertions, 230 deletions
diff --git a/railties/test/generators/actions_test.rb b/railties/test/generators/actions_test.rb index 0db40c1d32..c4b6441397 100644 --- a/railties/test/generators/actions_test.rb +++ b/railties/test/generators/actions_test.rb @@ -1,6 +1,7 @@ require 'generators/generators_test_helper' require 'rails/generators/rails/app/app_generator' require 'env_helpers' +require 'mocha/setup' # FIXME: stop using mocha class ActionsTest < Rails::Generators::TestCase include GeneratorsTestHelper @@ -41,13 +42,13 @@ class ActionsTest < Rails::Generators::TestCase def test_add_source_adds_source_to_gemfile run_generator action :add_source, 'http://gems.github.com' - assert_file 'Gemfile', /source "http:\/\/gems\.github\.com"/ + assert_file 'Gemfile', /source 'http:\/\/gems\.github\.com'/ end def test_gem_should_put_gem_dependency_in_gemfile run_generator action :gem, 'will-paginate' - assert_file 'Gemfile', /gem "will\-paginate"/ + assert_file 'Gemfile', /gem 'will\-paginate'/ end def test_gem_with_version_should_include_version_in_gemfile @@ -55,7 +56,7 @@ class ActionsTest < Rails::Generators::TestCase action :gem, 'rspec', '>=2.0.0.a5' - assert_file 'Gemfile', /gem "rspec", ">=2.0.0.a5"/ + assert_file 'Gemfile', /gem 'rspec', '>=2.0.0.a5'/ end def test_gem_should_insert_on_separate_lines @@ -66,8 +67,8 @@ class ActionsTest < Rails::Generators::TestCase action :gem, 'rspec' action :gem, 'rspec-rails' - assert_file 'Gemfile', /^gem "rspec"$/ - assert_file 'Gemfile', /^gem "rspec-rails"$/ + assert_file 'Gemfile', /^gem 'rspec'$/ + assert_file 'Gemfile', /^gem 'rspec-rails'$/ end def test_gem_should_include_options @@ -75,7 +76,25 @@ class ActionsTest < Rails::Generators::TestCase action :gem, 'rspec', github: 'dchelimsky/rspec', tag: '1.2.9.rc1' - assert_file 'Gemfile', /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_with_non_string_options + run_generator + + action :gem, 'rspec', require: false + action :gem, 'rspec-rails', group: [:development, :test] + + assert_file 'Gemfile', /^gem 'rspec', require: false$/ + assert_file 'Gemfile', /^gem 'rspec-rails', group: \[:development, :test\]$/ + end + + def test_gem_falls_back_to_inspect_if_string_contains_single_quote + run_generator + + action :gem, 'rspec', ">=2.0'0" + + assert_file 'Gemfile', /^gem 'rspec', ">=2\.0'0"$/ end def test_gem_group_should_wrap_gems_in_a_group @@ -89,7 +108,7 @@ class ActionsTest < Rails::Generators::TestCase gem 'fakeweb' end - assert_file 'Gemfile', /\ngroup :development, :test do\n gem "rspec-rails"\nend\n\ngroup :test do\n gem "fakeweb"\nend/ + assert_file 'Gemfile', /\ngroup :development, :test do\n gem 'rspec-rails'\nend\n\ngroup :test do\n gem 'fakeweb'\nend/ end def test_environment_should_include_data_in_environment_initializer_block @@ -110,7 +129,7 @@ class ActionsTest < Rails::Generators::TestCase run_generator action :environment do - '# This wont be added' + _ = '# This wont be added'# assignment to silence parse-time warning "unused literal ignored" '# This will be added' end @@ -234,7 +253,7 @@ class ActionsTest < Rails::Generators::TestCase protected def action(*args, &block) - silence(:stdout){ generator.send(*args, &block) } + capture(:stdout){ generator.send(*args, &block) } end end diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index 8246e76607..5d270555ed 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -1,6 +1,7 @@ require 'generators/generators_test_helper' require 'rails/generators/rails/app/app_generator' require 'generators/shared_generator_tests' +require 'mocha/setup' # FIXME: stop using mocha DEFAULT_APP_FILES = %w( .gitignore @@ -21,6 +22,7 @@ DEFAULT_APP_FILES = %w( bin/bundle bin/rails bin/rake + bin/setup config/environments config/initializers config/locales @@ -58,8 +60,8 @@ class AppGeneratorTest < Rails::Generators::TestCase def test_assets run_generator - assert_file("app/views/layouts/application.html.erb", /stylesheet_link_tag\s+"application", media: "all", "data-turbolinks-track" => true/) - assert_file("app/views/layouts/application.html.erb", /javascript_include_tag\s+"application", "data-turbolinks-track" => true/) + assert_file("app/views/layouts/application.html.erb", /stylesheet_link_tag\s+'application', media: 'all', 'data-turbolinks-track' => true/) + assert_file("app/views/layouts/application.html.erb", /javascript_include_tag\s+'application', 'data-turbolinks-track' => true/) assert_file("app/assets/stylesheets/application.css") assert_file("app/assets/javascripts/application.js") end @@ -119,7 +121,7 @@ class AppGeneratorTest < Rails::Generators::TestCase generator = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true }, destination_root: app_moved_root, shell: @shell generator.send(:app_const) - quietly { generator.send(:create_config_files) } + quietly { generator.send(:update_config_files) } assert_file "myapp_moved/config/environment.rb", /Rails\.application\.initialize!/ assert_file "myapp_moved/config/initializers/session_store.rb", /_myapp_session/ end @@ -134,10 +136,78 @@ class AppGeneratorTest < Rails::Generators::TestCase generator = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true }, destination_root: app_root, shell: @shell generator.send(:app_const) - quietly { generator.send(:create_config_files) } + quietly { generator.send(:update_config_files) } assert_file "myapp/config/initializers/session_store.rb", /_myapp_session/ end + def test_new_application_use_json_serialzier + run_generator + + assert_file("config/initializers/cookies_serializer.rb", /Rails\.application\.config\.action_dispatch\.cookies_serializer = :json/) + end + + def test_rails_update_keep_the_cookie_serializer_if_it_is_already_configured + app_root = File.join(destination_root, 'myapp') + run_generator [app_root] + + Rails.application.config.root = app_root + Rails.application.class.stubs(:name).returns("Myapp") + Rails.application.stubs(:is_a?).returns(Rails::Application) + + generator = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true }, destination_root: app_root, shell: @shell + generator.send(:app_const) + quietly { generator.send(:update_config_files) } + assert_file("#{app_root}/config/initializers/cookies_serializer.rb", /Rails\.application\.config\.action_dispatch\.cookies_serializer = :json/) + end + + def test_rails_update_does_not_create_callback_terminator_initializer + app_root = File.join(destination_root, 'myapp') + run_generator [app_root] + + FileUtils.rm("#{app_root}/config/initializers/callback_terminator.rb") + + Rails.application.config.root = app_root + Rails.application.class.stubs(:name).returns("Myapp") + Rails.application.stubs(:is_a?).returns(Rails::Application) + + generator = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true }, destination_root: app_root, shell: @shell + generator.send(:app_const) + quietly { generator.send(:update_config_files) } + assert_no_file "#{app_root}/config/initializers/callback_terminator.rb" + end + + def test_rails_update_does_not_remove_callback_terminator_initializer_if_already_present + app_root = File.join(destination_root, 'myapp') + run_generator [app_root] + + FileUtils.touch("#{app_root}/config/initializers/callback_terminator.rb") + + Rails.application.config.root = app_root + Rails.application.class.stubs(:name).returns("Myapp") + Rails.application.stubs(:is_a?).returns(Rails::Application) + + generator = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true }, destination_root: app_root, shell: @shell + generator.send(:app_const) + quietly { generator.send(:update_config_files) } + assert_file "#{app_root}/config/initializers/callback_terminator.rb" + end + + def test_rails_update_set_the_cookie_serializer_to_marchal_if_it_is_not_already_configured + app_root = File.join(destination_root, 'myapp') + run_generator [app_root] + + FileUtils.rm("#{app_root}/config/initializers/cookies_serializer.rb") + + Rails.application.config.root = app_root + Rails.application.class.stubs(:name).returns("Myapp") + Rails.application.stubs(:is_a?).returns(Rails::Application) + + generator = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true }, destination_root: app_root, shell: @shell + generator.send(:app_const) + quietly { generator.send(:update_config_files) } + assert_file("#{app_root}/config/initializers/cookies_serializer.rb", /Rails\.application\.config\.action_dispatch\.cookies_serializer = :marshal/) + end + def test_application_names_are_not_singularized run_generator [File.join(destination_root, "hats")] assert_file "hats/config/environment.rb", /Rails\.application\.initialize!/ @@ -156,87 +226,20 @@ class AppGeneratorTest < Rails::Generators::TestCase def test_config_database_is_added_by_default run_generator assert_file "config/database.yml", /sqlite3/ - unless defined?(JRUBY_VERSION) - assert_gem "sqlite3" - else + if defined?(JRUBY_VERSION) assert_gem "activerecord-jdbcsqlite3-adapter" - end - end - - def test_arbitrary_code - output = Tempfile.open('my_template') do |template| - template.puts 'puts "You are using Rails version #{Rails::VERSION::STRING}."' - template.close - run_generator([destination_root, "-m", template.path]) - end - assert_match 'You are using', output - end - - def test_add_gemfile_entry - Tempfile.open('my_template') do |template| - template.puts 'gemfile_entry "tenderlove"' - template.flush - template.close - run_generator([destination_root, "-n", template.path]) - assert_file "Gemfile", /tenderlove/ - end - end - - def test_add_skip_entry - Tempfile.open 'my_template' do |template| - template.puts 'add_gem_entry_filter { |gem| gem.name != "jbuilder" }' - template.close - - run_generator([destination_root, "-n", template.path]) - assert_file "Gemfile" do |contents| - assert_no_match 'jbuilder', contents - end - end - end - - def test_remove_gem - Tempfile.open 'my_template' do |template| - template.puts 'remove_gem "jbuilder"' - template.close - - run_generator([destination_root, "-n", template.path]) - assert_file "Gemfile" do |contents| - assert_no_match 'jbuilder', contents - end - end - end - - def test_skip_turbolinks_when_it_is_not_on_gemfile - Tempfile.open 'my_template' do |template| - template.puts 'add_gem_entry_filter { |gem| gem.name != "turbolinks" }' - template.flush - - run_generator([destination_root, "-n", template.path]) - assert_file "Gemfile" do |contents| - assert_no_match 'turbolinks', contents - end - - assert_file "app/views/layouts/application.html.erb" do |contents| - assert_no_match 'turbolinks', contents - end - - assert_file "app/views/layouts/application.html.erb" do |contents| - assert_no_match('data-turbolinks-track', contents) - end - - assert_file "app/assets/javascripts/application.js" do |contents| - assert_no_match 'turbolinks', contents - end + else + assert_gem "sqlite3" end end def test_config_another_database run_generator([destination_root, "-d", "mysql"]) assert_file "config/database.yml", /mysql/ - unless defined?(JRUBY_VERSION) - assert_gem "mysql2" - else + if defined?(JRUBY_VERSION) assert_gem "activerecord-jdbcmysql-adapter" + else + assert_gem "mysql2" end end @@ -248,10 +251,10 @@ class AppGeneratorTest < Rails::Generators::TestCase def test_config_postgresql_database run_generator([destination_root, "-d", "postgresql"]) assert_file "config/database.yml", /postgresql/ - unless defined?(JRUBY_VERSION) - assert_gem "pg" - else + if defined?(JRUBY_VERSION) assert_gem "activerecord-jdbcpostgresql-adapter" + else + assert_gem "pg" end end @@ -280,14 +283,28 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_gem "activerecord-jdbc-adapter" end - def test_config_jdbc_database_when_no_option_given - if defined?(JRUBY_VERSION) - run_generator([destination_root]) + if defined?(JRUBY_VERSION) + def test_config_jdbc_database_when_no_option_given + run_generator assert_file "config/database.yml", /sqlite3/ assert_gem "activerecord-jdbcsqlite3-adapter" end end + def test_generator_without_skips + run_generator + assert_file "config/application.rb", /\s+require\s+["']rails\/all["']/ + assert_file "config/environments/development.rb" do |content| + assert_match(/config\.action_mailer\.raise_delivery_errors = false/, content) + end + assert_file "config/environments/test.rb" do |content| + assert_match(/config\.action_mailer\.delivery_method = :test/, content) + end + assert_file "config/environments/production.rb" do |content| + assert_match(/# config\.action_mailer\.raise_delivery_errors = false/, content) + end + end + def test_generator_if_skip_active_record_is_given run_generator [destination_root, "--skip-active-record"] assert_no_file "config/database.yml" @@ -297,13 +314,23 @@ class AppGeneratorTest < Rails::Generators::TestCase end end - def test_generator_if_skip_action_view_is_given - run_generator [destination_root, "--skip-action-view"] - assert_file "config/application.rb", /#\s+require\s+["']action_view\/railtie["']/ + def test_generator_if_skip_action_mailer_is_given + run_generator [destination_root, "--skip-action-mailer"] + assert_file "config/application.rb", /#\s+require\s+["']action_mailer\/railtie["']/ + assert_file "config/environments/development.rb" do |content| + assert_no_match(/config\.action_mailer/, content) + end + assert_file "config/environments/test.rb" do |content| + assert_no_match(/config\.action_mailer/, content) + end + assert_file "config/environments/production.rb" do |content| + assert_no_match(/config\.action_mailer/, content) + end end def test_generator_if_skip_sprockets_is_given run_generator [destination_root, "--skip-sprockets"] + assert_no_file "config/initializers/assets.rb" assert_file "config/application.rb" do |content| assert_match(/#\s+require\s+["']sprockets\/railtie["']/, content) end @@ -319,23 +346,15 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_no_match(/config\.assets\.digest = true/, content) assert_no_match(/config\.assets\.js_compressor = :uglifier/, content) assert_no_match(/config\.assets\.css_compressor = :sass/, content) - assert_no_match(/config\.assets\.version = '1\.0'/, content) end end def test_inclusion_of_javascript_runtime - run_generator([destination_root]) + run_generator if defined?(JRUBY_VERSION) assert_gem "therubyrhino" else - assert_file "Gemfile", /# gem\s+["']therubyracer["']+, \s+platforms: :ruby$/ - end - end - - def test_inclusion_of_plateform_dependent_gems - run_generator([destination_root]) - if RUBY_ENGINE == 'rbx' - assert_gem 'rubysl' + assert_file "Gemfile", /# gem 'therubyracer', platforms: :ruby/ end end @@ -364,8 +383,8 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_no_file "vendor/assets/javascripts" assert_file "app/views/layouts/application.html.erb" do |contents| - assert_match(/stylesheet_link_tag\s+"application", media: "all" %>/, contents) - assert_no_match(/javascript_include_tag\s+"application" \%>/, contents) + assert_match(/stylesheet_link_tag\s+'application', media: 'all' %>/, contents) + assert_no_match(/javascript_include_tag\s+'application' \%>/, contents) end assert_file "Gemfile" do |content| @@ -376,17 +395,24 @@ class AppGeneratorTest < Rails::Generators::TestCase def test_inclusion_of_jbuilder run_generator - assert_file "Gemfile", /gem 'jbuilder'/ + assert_gem 'jbuilder' end - def test_inclusion_of_debugger + def test_inclusion_of_a_debugger run_generator - if defined?(JRUBY_VERSION) + if defined?(JRUBY_VERSION) || RUBY_ENGINE == "rbx" assert_file "Gemfile" do |content| - assert_no_match(/debugger/, content) + assert_no_match(/byebug/, content) end else - assert_file "Gemfile", /# gem 'debugger'/ + assert_gem 'byebug' + end + end + + def test_inclusion_of_method_source + run_generator + assert_file "Gemfile" do |content| + assert_gem 'method_source' end end @@ -428,10 +454,11 @@ class AppGeneratorTest < Rails::Generators::TestCase run_generator [destination_root, "--skip-test-unit", "--skip-active-record"] assert_file "config/application.rb", /#\s+require\s+["']rails\/test_unit\/railtie["']/ assert_file "config/application.rb", /#\s+require\s+["']active_record\/railtie["']/ + assert_file "config/application.rb", /\s+require\s+["']active_job\/railtie["']/ end def test_new_hash_style - run_generator [destination_root] + run_generator assert_file "config/initializers/session_store.rb" do |file| assert_match(/config.session_store :cookie_store, key: '_.+_session'/, file) end @@ -452,9 +479,32 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_file "foo bar/config/initializers/session_store.rb", /key: '_foo_bar/ end + def test_web_console + run_generator + assert_gem 'web-console' + end + + def test_web_console_with_dev_option + run_generator [destination_root, "--dev"] + + assert_file "Gemfile" do |content| + assert_match(/gem 'web-console',\s+github: "rails\/web-console"/, content) + assert_no_match(/gem 'web-console', '~> 2.0'/, content) + end + end + + def test_web_console_with_edge_option + run_generator [destination_root, "--edge"] + + assert_file "Gemfile" do |content| + assert_match(/gem 'web-console',\s+github: "rails\/web-console"/, content) + assert_no_match(/gem 'web-console', '~> 2.0'/, content) + end + end + def test_spring run_generator - assert_file "Gemfile", /gem 'spring', \s+group: :development/ + assert_gem 'spring' end def test_spring_binstubs @@ -482,13 +532,79 @@ class AppGeneratorTest < Rails::Generators::TestCase end end -protected + def test_generator_if_skip_turbolinks_is_given + run_generator [destination_root, "--skip-turbolinks"] + + assert_file "Gemfile" do |content| + assert_no_match(/turbolinks/, content) + end + assert_file "app/views/layouts/application.html.erb" do |content| + assert_no_match(/data-turbolinks-track/, content) + end + assert_file "app/assets/javascripts/application.js" do |content| + assert_no_match(/turbolinks/, content) + end + end + + def test_gitignore_when_sqlite3 + run_generator + + assert_file '.gitignore' do |content| + assert_match(/sqlite3/, content) + end + end + + def test_gitignore_when_no_active_record + run_generator [destination_root, '--skip-active-record'] + + assert_file '.gitignore' do |content| + assert_no_match(/sqlite/i, content) + end + end + + def test_gitignore_when_non_sqlite3_db + run_generator([destination_root, "-d", "mysql"]) + + assert_file '.gitignore' do |content| + assert_no_match(/sqlite/i, content) + end + end + + def test_psych_gem + run_generator + gem_regex = /gem 'psych',\s+'~> 2.0',\s+platforms: :rbx/ + + assert_file "Gemfile" do |content| + if defined?(Rubinius) + assert_match(gem_regex, content) + else + assert_no_match(gem_regex, content) + end + end + end + + def test_after_bundle_callback + path = 'http://example.org/rails_template' + template = %{ after_bundle { run 'echo ran after_bundle' } } + 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) + + bundler_first = sequence('bundle, binstubs, after_bundle') + generator.expects(:bundle_command).with('install').once.in_sequence(bundler_first) + generator.expects(:bundle_command).with('exec spring binstub --all').in_sequence(bundler_first) + generator.expects(:run).with('echo ran after_bundle').in_sequence(bundler_first) + + quietly { generator.invoke_all } + end + + protected def action(*args, &block) - silence(:stdout) { generator.send(*args, &block) } + capture(:stdout) { generator.send(*args, &block) } end def assert_gem(gem) - assert_file "Gemfile", /^gem\s+["']#{gem}["']$/ + assert_file "Gemfile", /^\s*gem\s+["']#{gem}["']$*/ end end diff --git a/railties/test/generators/argv_scrubber_test.rb b/railties/test/generators/argv_scrubber_test.rb index a94350cbd7..31e07bc8da 100644 --- a/railties/test/generators/argv_scrubber_test.rb +++ b/railties/test/generators/argv_scrubber_test.rb @@ -16,7 +16,7 @@ module Rails output = nil exit_code = nil scrubber.extend(Module.new { - define_method(:puts) { |str| output = str } + define_method(:puts) { |string| output = string } define_method(:exit) { |code| exit_code = code } }) scrubber.prepare! diff --git a/railties/test/generators/controller_generator_test.rb b/railties/test/generators/controller_generator_test.rb index 4b2f8539d0..a7d56dd352 100644 --- a/railties/test/generators/controller_generator_test.rb +++ b/railties/test/generators/controller_generator_test.rb @@ -28,13 +28,11 @@ class ControllerGeneratorTest < Rails::Generators::TestCase def test_invokes_helper run_generator assert_file "app/helpers/account_helper.rb" - assert_file "test/helpers/account_helper_test.rb" end def test_does_not_invoke_helper_if_required run_generator ["account", "--skip-helper"] assert_no_file "app/helpers/account_helper.rb" - assert_no_file "test/helpers/account_helper_test.rb" end def test_invokes_assets @@ -70,6 +68,13 @@ class ControllerGeneratorTest < Rails::Generators::TestCase assert_file "config/routes.rb", /get 'account\/foo'/, /get 'account\/bar'/ end + def test_skip_routes + run_generator ["account", "foo", "--skip-routes"] + assert_file "config/routes.rb" do |routes| + assert_no_match(/get 'account\/foo'/, routes) + end + end + def test_invokes_default_template_engine_even_with_no_action run_generator ["account"] assert_file "app/views/account" diff --git a/railties/test/generators/create_migration_test.rb b/railties/test/generators/create_migration_test.rb new file mode 100644 index 0000000000..e16a77479a --- /dev/null +++ b/railties/test/generators/create_migration_test.rb @@ -0,0 +1,134 @@ +require 'generators/generators_test_helper' +require 'rails/generators/rails/migration/migration_generator' + +class CreateMigrationTest < Rails::Generators::TestCase + include GeneratorsTestHelper + + class Migrator < Rails::Generators::MigrationGenerator + include Rails::Generators::Migration + + def self.next_migration_number(dirname) + current_migration_number(dirname) + 1 + end + end + + tests Migrator + + def default_destination_path + "db/migrate/create_articles.rb" + end + + def create_migration(destination_path = default_destination_path, config = {}, generator_options = {}, &block) + migration_name = File.basename(destination_path, '.rb') + generator([migration_name], generator_options) + generator.set_migration_assigns!(destination_path) + + dir, base = File.split(destination_path) + timestamped_destination_path = File.join(dir, ["%migration_number%", base].join('_')) + + @migration = Rails::Generators::Actions::CreateMigration.new(generator, timestamped_destination_path, block || "contents", config) + end + + def migration_exists!(*args) + @existing_migration = create_migration(*args) + invoke! + @generator = nil + end + + def invoke! + capture(:stdout) { @migration.invoke! } + end + + def revoke! + capture(:stdout) { @migration.revoke! } + end + + def test_invoke + create_migration + + assert_match(/create db\/migrate\/1_create_articles.rb\n/, invoke!) + assert_file @migration.destination + end + + def test_invoke_pretended + create_migration(default_destination_path, {}, { pretend: true }) + + assert_no_file @migration.destination + end + + def test_invoke_when_exists + migration_exists! + create_migration + + assert_equal @existing_migration.destination, @migration.existing_migration + end + + def test_invoke_when_exists_identical + migration_exists! + create_migration + + assert_match(/identical db\/migrate\/1_create_articles.rb\n/, invoke!) + assert @migration.identical? + end + + def test_invoke_when_exists_not_identical + migration_exists! + create_migration { "different content" } + + assert_raise(Rails::Generators::Error) { invoke! } + end + + def test_invoke_forced_when_exists_not_identical + dest = "db/migrate/migration.rb" + migration_exists!(dest) + create_migration(dest, force: true) { "different content" } + + stdout = invoke! + assert_match(/remove db\/migrate\/1_migration.rb\n/, stdout) + assert_match(/create db\/migrate\/2_migration.rb\n/, stdout) + assert_file @migration.destination + assert_no_file @existing_migration.destination + end + + def test_invoke_forced_pretended_when_exists_not_identical + migration_exists! + create_migration(default_destination_path, { force: true }, { pretend: true }) do + "different content" + end + + stdout = invoke! + assert_match(/remove db\/migrate\/1_create_articles.rb\n/, stdout) + assert_match(/create db\/migrate\/2_create_articles.rb\n/, stdout) + assert_no_file @migration.destination + end + + def test_invoke_skipped_when_exists_not_identical + migration_exists! + create_migration(default_destination_path, {}, { skip: true }) { "different content" } + + assert_match(/skip db\/migrate\/2_create_articles.rb\n/, invoke!) + assert_no_file @migration.destination + end + + def test_revoke + migration_exists! + create_migration + + assert_match(/remove db\/migrate\/1_create_articles.rb\n/, revoke!) + assert_no_file @existing_migration.destination + end + + def test_revoke_pretended + migration_exists! + create_migration(default_destination_path, {}, { pretend: true }) + + assert_match(/remove db\/migrate\/1_create_articles.rb\n/, revoke!) + assert_file @existing_migration.destination + end + + def test_revoke_when_no_exists + create_migration + + assert_match(/remove db\/migrate\/1_create_articles.rb\n/, revoke!) + end +end diff --git a/railties/test/generators/generated_attribute_test.rb b/railties/test/generators/generated_attribute_test.rb index c48bc20899..ee7c009305 100644 --- a/railties/test/generators/generated_attribute_test.rb +++ b/railties/test/generators/generated_attribute_test.rb @@ -141,4 +141,12 @@ class GeneratedAttributeTest < Rails::Generators::TestCase assert_equal "post_id", create_generated_attribute('references', 'post').column_name assert_equal "post_id", create_generated_attribute('belongs_to', 'post').column_name end + + def test_parse_required_attribute_with_index + att = Rails::Generators::GeneratedAttribute.parse("supplier:references{required}:index") + assert_equal "supplier", att.name + assert_equal :references, att.type + assert att.has_index? + assert att.required? + end end diff --git a/railties/test/generators/generator_test.rb b/railties/test/generators/generator_test.rb index 94d2c1bf50..7871399dd7 100644 --- a/railties/test/generators/generator_test.rb +++ b/railties/test/generators/generator_test.rb @@ -1,7 +1,6 @@ require 'active_support/test_case' require 'active_support/testing/autorun' require 'rails/generators/app_base' -require 'rails/generators/rails/app/app_generator' module Rails module Generators diff --git a/railties/test/generators/generators_test_helper.rb b/railties/test/generators/generators_test_helper.rb index 77ec2f1c0c..7c5183e6c8 100644 --- a/railties/test/generators/generators_test_helper.rb +++ b/railties/test/generators/generators_test_helper.rb @@ -7,7 +7,7 @@ module Rails class << self remove_possible_method :root def root - @root ||= File.expand_path(File.join(File.dirname(__FILE__), '..', 'fixtures')) + @root ||= Pathname.new(File.expand_path('../../fixtures', __FILE__)) end end end @@ -41,4 +41,22 @@ module GeneratorsTestHelper FileUtils.mkdir_p(destination) FileUtils.cp routes, destination end + + def quietly + silence_stream(STDOUT) do + silence_stream(STDERR) do + yield + end + end + end + + def silence_stream(stream) + old_stream = stream.dup + stream.reopen(IO::NULL) + stream.sync = true + yield + ensure + stream.reopen(old_stream) + old_stream.close + end end diff --git a/railties/test/generators/helper_generator_test.rb b/railties/test/generators/helper_generator_test.rb index 81d4fcb129..add04f21a4 100644 --- a/railties/test/generators/helper_generator_test.rb +++ b/railties/test/generators/helper_generator_test.rb @@ -13,26 +13,11 @@ class HelperGeneratorTest < Rails::Generators::TestCase assert_file "app/helpers/admin_helper.rb", /module AdminHelper/ end - def test_invokes_default_test_framework - run_generator - assert_file "test/helpers/admin_helper_test.rb", /class AdminHelperTest < ActionView::TestCase/ - end - - def test_logs_if_the_test_framework_cannot_be_found - content = run_generator ["admin", "--test-framework=rspec"] - assert_match(/rspec \[not found\]/, content) - end - def test_check_class_collision content = capture(:stderr){ run_generator ["object"] } assert_match(/The name 'ObjectHelper' is either already used in your application or reserved/, content) end - def test_check_class_collision_on_tests - content = capture(:stderr){ run_generator ["another_object"] } - assert_match(/The name 'AnotherObjectHelperTest' is either already used in your application or reserved/, content) - end - def test_namespaced_and_not_namespaced_helpers run_generator ["products"] diff --git a/railties/test/generators/job_generator_test.rb b/railties/test/generators/job_generator_test.rb new file mode 100644 index 0000000000..a9e0cea94f --- /dev/null +++ b/railties/test/generators/job_generator_test.rb @@ -0,0 +1,29 @@ +require 'generators/generators_test_helper' +require 'rails/generators/job/job_generator' + +class JobGeneratorTest < Rails::Generators::TestCase + include GeneratorsTestHelper + + def test_job_skeleton_is_created + run_generator ["refresh_counters"] + assert_file "app/jobs/refresh_counters_job.rb" do |job| + assert_match(/class RefreshCountersJob < ActiveJob::Base/, job) + end + end + + def test_job_queue_param + run_generator ["refresh_counters", "--queue", "important"] + assert_file "app/jobs/refresh_counters_job.rb" do |job| + assert_match(/class RefreshCountersJob < ActiveJob::Base/, job) + assert_match(/queue_as :important/, job) + end + end + + def test_job_namespace + run_generator ["admin/refresh_counters", "--queue", "admin"] + assert_file "app/jobs/admin/refresh_counters_job.rb" do |job| + assert_match(/class Admin::RefreshCountersJob < ActiveJob::Base/, job) + assert_match(/queue_as :admin/, job) + end + end +end diff --git a/railties/test/generators/mailer_generator_test.rb b/railties/test/generators/mailer_generator_test.rb index d209801f60..febd2fd12e 100644 --- a/railties/test/generators/mailer_generator_test.rb +++ b/railties/test/generators/mailer_generator_test.rb @@ -7,94 +7,114 @@ class MailerGeneratorTest < Rails::Generators::TestCase def test_mailer_skeleton_is_created run_generator - assert_file "app/mailers/notifier.rb" do |mailer| - assert_match(/class Notifier < ActionMailer::Base/, mailer) + assert_file "app/mailers/notifier_mailer.rb" do |mailer| + assert_match(/class NotifierMailer < ApplicationMailer/, mailer) + assert_no_match(/default from: "from@example.com"/, mailer) + assert_no_match(/layout :mailer_notifier/, mailer) + end + end + + def test_application_mailer_skeleton_is_created + run_generator + assert_file "app/mailers/application_mailer.rb" do |mailer| + assert_match(/class ApplicationMailer < ActionMailer::Base/, mailer) assert_match(/default from: "from@example.com"/, mailer) + assert_match(/layout 'mailer'/, mailer) end end def test_mailer_with_i18n_helper run_generator - assert_file "app/mailers/notifier.rb" do |mailer| - assert_match(/en\.notifier\.foo\.subject/, mailer) - assert_match(/en\.notifier\.bar\.subject/, mailer) + assert_file "app/mailers/notifier_mailer.rb" do |mailer| + assert_match(/en\.notifier_mailer\.foo\.subject/, mailer) + assert_match(/en\.notifier_mailer\.bar\.subject/, mailer) end end def test_check_class_collision - Object.send :const_set, :Notifier, Class.new + Object.send :const_set, :NotifierMailer, Class.new content = capture(:stderr){ run_generator } - assert_match(/The name 'Notifier' is either already used in your application or reserved/, content) + assert_match(/The name 'NotifierMailer' is either already used in your application or reserved/, content) ensure - Object.send :remove_const, :Notifier + Object.send :remove_const, :NotifierMailer end def test_invokes_default_test_framework run_generator - assert_file "test/mailers/notifier_test.rb" do |test| - assert_match(/class NotifierTest < ActionMailer::TestCase/, test) + assert_file "test/mailers/notifier_mailer_test.rb" do |test| + assert_match(/class NotifierMailerTest < ActionMailer::TestCase/, test) assert_match(/test "foo"/, test) assert_match(/test "bar"/, test) end - assert_file "test/mailers/previews/notifier_preview.rb" do |preview| + assert_file "test/mailers/previews/notifier_mailer_preview.rb" do |preview| assert_match(/\# Preview all emails at http:\/\/localhost\:3000\/rails\/mailers\/notifier/, preview) - assert_match(/class NotifierPreview < ActionMailer::Preview/, preview) + assert_match(/class NotifierMailerPreview < ActionMailer::Preview/, preview) assert_match(/\# Preview this email at http:\/\/localhost\:3000\/rails\/mailers\/notifier\/foo/, preview) assert_instance_method :foo, preview do |foo| - assert_match(/Notifier.foo/, foo) + assert_match(/NotifierMailer.foo/, foo) end assert_match(/\# Preview this email at http:\/\/localhost\:3000\/rails\/mailers\/notifier\/bar/, preview) assert_instance_method :bar, preview do |bar| - assert_match(/Notifier.bar/, bar) + assert_match(/NotifierMailer.bar/, bar) end end end def test_check_test_class_collision - Object.send :const_set, :NotifierTest, Class.new + Object.send :const_set, :NotifierMailerTest, Class.new content = capture(:stderr){ run_generator } - assert_match(/The name 'NotifierTest' is either already used in your application or reserved/, content) + assert_match(/The name 'NotifierMailerTest' is either already used in your application or reserved/, content) ensure - Object.send :remove_const, :NotifierTest + Object.send :remove_const, :NotifierMailerTest end def test_check_preview_class_collision - Object.send :const_set, :NotifierPreview, Class.new + Object.send :const_set, :NotifierMailerPreview, Class.new content = capture(:stderr){ run_generator } - assert_match(/The name 'NotifierPreview' is either already used in your application or reserved/, content) + assert_match(/The name 'NotifierMailerPreview' is either already used in your application or reserved/, content) ensure - Object.send :remove_const, :NotifierPreview + Object.send :remove_const, :NotifierMailerPreview end def test_invokes_default_text_template_engine run_generator assert_file "app/views/notifier/foo.text.erb" do |view| - assert_match(%r(app/views/notifier/foo\.text\.erb), view) + assert_match(%r(\sapp/views/notifier/foo\.text\.erb), view) assert_match(/<%= @greeting %>/, view) end assert_file "app/views/notifier/bar.text.erb" do |view| - assert_match(%r(app/views/notifier/bar\.text\.erb), view) + assert_match(%r(\sapp/views/notifier/bar\.text\.erb), view) assert_match(/<%= @greeting %>/, view) end + + assert_file "app/views/layouts/mailer.text.erb" do |view| + assert_match(/<%= yield %>/, view) + end end def test_invokes_default_html_template_engine run_generator assert_file "app/views/notifier/foo.html.erb" do |view| - assert_match(%r(app/views/notifier/foo\.html\.erb), view) + assert_match(%r(\sapp/views/notifier/foo\.html\.erb), view) assert_match(/<%= @greeting %>/, view) end assert_file "app/views/notifier/bar.html.erb" do |view| - assert_match(%r(app/views/notifier/bar\.html\.erb), view) + assert_match(%r(\sapp/views/notifier/bar\.html\.erb), view) assert_match(/<%= @greeting %>/, view) end + + assert_file "app/views/layouts/mailer.html.erb" do |view| + assert_match(%r{<html>\n <body>\n <%= yield %>\n </body>\n</html>}, view) + end end def test_invokes_default_template_engine_even_with_no_action run_generator ["notifier"] assert_file "app/views/notifier" + assert_file "app/views/layouts/mailer.text.erb" + assert_file "app/views/layouts/mailer.html.erb" end def test_logs_if_the_template_engine_cannot_be_found @@ -104,13 +124,13 @@ class MailerGeneratorTest < Rails::Generators::TestCase def test_mailer_with_namedspaced_mailer run_generator ["Farm::Animal", "moos"] - assert_file "app/mailers/farm/animal.rb" do |mailer| - assert_match(/class Farm::Animal < ActionMailer::Base/, mailer) - assert_match(/en\.farm\.animal\.moos\.subject/, mailer) + assert_file "app/mailers/farm/animal_mailer.rb" do |mailer| + assert_match(/class Farm::AnimalMailer < ApplicationMailer/, mailer) + assert_match(/en\.farm\.animal_mailer\.moos\.subject/, mailer) end - assert_file "test/mailers/previews/farm/animal_preview.rb" do |preview| + assert_file "test/mailers/previews/farm/animal_mailer_preview.rb" do |preview| assert_match(/\# Preview all emails at http:\/\/localhost\:3000\/rails\/mailers\/farm\/animal/, preview) - assert_match(/class Farm::AnimalPreview < ActionMailer::Preview/, preview) + assert_match(/class Farm::AnimalMailerPreview < ActionMailer::Preview/, preview) assert_match(/\# Preview this email at http:\/\/localhost\:3000\/rails\/mailers\/farm\/animal\/moos/, preview) end assert_file "app/views/farm/animal/moos.text.erb" @@ -120,7 +140,7 @@ class MailerGeneratorTest < Rails::Generators::TestCase def test_actions_are_turned_into_methods run_generator - assert_file "app/mailers/notifier.rb" do |mailer| + assert_file "app/mailers/notifier_mailer.rb" do |mailer| assert_instance_method :foo, mailer do |foo| assert_match(/mail to: "to@example.org"/, foo) assert_match(/@greeting = "Hi"/, foo) @@ -132,4 +152,26 @@ class MailerGeneratorTest < Rails::Generators::TestCase end end end + + def test_mailer_on_revoke + run_generator + run_generator ["notifier"], behavior: :revoke + + assert_no_file "app/mailers/notifier.rb" + assert_no_file "app/views/notifier/foo.text.erb" + assert_no_file "app/views/notifier/bar.text.erb" + assert_no_file "app/views/notifier/foo.html.erb" + assert_no_file "app/views/notifier/bar.html.erb" + + assert_file "app/mailers/application_mailer.rb" + assert_file "app/views/layouts/mailer.text.erb" + assert_file "app/views/layouts/mailer.html.erb" + end + + def test_mailer_suffix_is_not_duplicated + run_generator ["notifier_mailer"] + + assert_no_file "app/mailers/notifier_mailer_mailer.rb" + assert_file "app/mailers/notifier_mailer.rb" + end end diff --git a/railties/test/generators/migration_generator_test.rb b/railties/test/generators/migration_generator_test.rb index d876597944..57bc220558 100644 --- a/railties/test/generators/migration_generator_test.rb +++ b/railties/test/generators/migration_generator_test.rb @@ -85,6 +85,19 @@ class MigrationGeneratorTest < Rails::Generators::TestCase end end + def test_remove_migration_with_references_removes_foreign_keys + migration = "remove_references_from_books" + run_generator [migration, "author:belongs_to", "distributor:references{polymorphic}"] + + assert_migration "db/migrate/#{migration}.rb" do |content| + assert_method :change, content do |change| + assert_match(/remove_reference :books, :author,.*\sforeign_key: true/, change) + assert_match(/remove_reference :books, :distributor/, change) # sanity check + assert_no_match(/remove_reference :books, :distributor,.*\sforeign_key: true/, change) + 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"] @@ -159,6 +172,31 @@ class MigrationGeneratorTest < Rails::Generators::TestCase end end + def test_add_migration_with_required_references + migration = "add_references_to_books" + run_generator [migration, "author:belongs_to{required}", "distributor:references{polymorphic,required}"] + + assert_migration "db/migrate/#{migration}.rb" do |content| + assert_method :change, content do |change| + assert_match(/add_reference :books, :author, index: true, null: false/, change) + assert_match(/add_reference :books, :distributor, polymorphic: true, index: true, null: false/, change) + end + end + end + + def test_add_migration_with_references_adds_foreign_keys + 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 |change| + assert_match(/add_reference :books, :author,.*\sforeign_key: true/, change) + assert_match(/add_reference :books, :distributor/, change) # sanity check + assert_no_match(/add_reference :books, :distributor,.*\sforeign_key: true/, change) + end + end + end + def test_create_join_table_migration migration = "add_media_join_table" run_generator [migration, "artist_id", "musics:uniq"] @@ -193,8 +231,82 @@ class MigrationGeneratorTest < Rails::Generators::TestCase end end end - + def test_properly_identifies_usage_file assert generator_class.send(:usage_path) end + + def test_migration_with_singular_table_name + with_singular_table_name do + migration = "add_title_body_to_post" + run_generator [migration, 'title:string'] + assert_migration "db/migrate/#{migration}.rb" do |content| + assert_method :change, content do |change| + assert_match(/add_column :post, :title, :string/, change) + end + end + end + end + + def test_create_join_table_migration_with_singular_table_name + with_singular_table_name do + migration = "add_media_join_table" + run_generator [migration, "artist_id", "music:uniq"] + + assert_migration "db/migrate/#{migration}.rb" do |content| + assert_method :change, content do |change| + assert_match(/create_join_table :artist, :music/, change) + assert_match(/# t.index \[:artist_id, :music_id\]/, change) + assert_match(/ t.index \[:music_id, :artist_id\], unique: true/, change) + end + end + end + end + + def test_create_table_migration_with_singular_table_name + with_singular_table_name do + run_generator ["create_book", "title:string", "content:text"] + assert_migration "db/migrate/create_book.rb" do |content| + assert_method :change, content do |change| + assert_match(/create_table :book/, change) + assert_match(/ t\.string :title/, change) + assert_match(/ t\.text :content/, change) + end + end + end + end + + def test_create_table_migration_with_token_option + run_generator ["create_users", "token:token", "auth_token:token"] + assert_migration "db/migrate/create_users.rb" do |content| + assert_method :change, content do |change| + assert_match(/create_table :users/, change) + assert_match(/ t\.string :token/, change) + assert_match(/ t\.string :auth_token/, change) + assert_match(/add_index :users, :token, unique: true/, change) + assert_match(/add_index :users, :auth_token, unique: true/, change) + end + end + end + + def test_add_migration_with_token_option + migration = "add_token_to_users" + run_generator [migration, "auth_token:token"] + assert_migration "db/migrate/#{migration}.rb" do |content| + assert_method :change, content do |change| + assert_match(/add_column :users, :auth_token, :string/, change) + assert_match(/add_index :users, :auth_token, unique: true/, change) + end + end + end + + private + + def with_singular_table_name + old_state = ActiveRecord::Base.pluralize_table_names + ActiveRecord::Base.pluralize_table_names = false + yield + ensure + ActiveRecord::Base.pluralize_table_names = old_state + end end diff --git a/railties/test/generators/model_generator_test.rb b/railties/test/generators/model_generator_test.rb index 01ab77ee20..17a13fbf1f 100644 --- a/railties/test/generators/model_generator_test.rb +++ b/railties/test/generators/model_generator_test.rb @@ -1,5 +1,6 @@ require 'generators/generators_test_helper' require 'rails/generators/rails/model/model_generator' +require 'active_support/core_ext/string/strip' class ModelGeneratorTest < Rails::Generators::TestCase include GeneratorsTestHelper @@ -34,6 +35,13 @@ class ModelGeneratorTest < Rails::Generators::TestCase assert_no_migration "db/migrate/create_accounts.rb" end + def test_plural_names_are_singularized + content = run_generator ["accounts".freeze] + assert_file "app/models/account.rb", /class Account < ActiveRecord::Base/ + assert_file "test/models/account_test.rb", /class AccountTest/ + assert_match(/\[WARNING\] The model name 'accounts' was recognized as a plural, using the singular 'account' instead\. Override with --force-plural or setup custom inflection rules for this noun before running the generator\./, content) + end + def test_model_with_underscored_parent_option run_generator ["account", "--parent", "admin/account"] assert_file "app/models/account.rb", /class Account < Admin::Account/ @@ -279,18 +287,18 @@ class ModelGeneratorTest < Rails::Generators::TestCase def test_fixtures_use_the_references_ids run_generator ["LineItem", "product:references", "cart:belongs_to"] - assert_file "test/fixtures/line_items.yml", /product_id: \n cart_id: / + assert_file "test/fixtures/line_items.yml", /product: \n cart: / assert_generated_fixture("test/fixtures/line_items.yml", - {"one"=>{"product_id"=>nil, "cart_id"=>nil}, "two"=>{"product_id"=>nil, "cart_id"=>nil}}) + {"one"=>{"product"=>nil, "cart"=>nil}, "two"=>{"product"=>nil, "cart"=>nil}}) end def test_fixtures_use_the_references_ids_and_type run_generator ["LineItem", "product:references{polymorphic}", "cart:belongs_to"] - assert_file "test/fixtures/line_items.yml", /product_id: \n product_type: Product\n cart_id: / + assert_file "test/fixtures/line_items.yml", /product: \n product_type: Product\n cart: / assert_generated_fixture("test/fixtures/line_items.yml", - {"one"=>{"product_id"=>nil, "product_type"=>"Product", "cart_id"=>nil}, - "two"=>{"product_id"=>nil, "product_type"=>"Product", "cart_id"=>nil}}) + {"one"=>{"product"=>nil, "product_type"=>"Product", "cart"=>nil}, + "two"=>{"product"=>nil, "product_type"=>"Product", "cart"=>nil}}) end def test_fixtures_respect_reserved_yml_keywords @@ -356,6 +364,91 @@ class ModelGeneratorTest < Rails::Generators::TestCase end end + def test_required_belongs_to_adds_required_association + run_generator ["account", "supplier:references{required}"] + + expected_file = <<-FILE.strip_heredoc + class Account < ActiveRecord::Base + belongs_to :supplier, required: true + end + FILE + assert_file "app/models/account.rb", expected_file + end + + def test_required_polymorphic_belongs_to_generages_correct_model + run_generator ["account", "supplier:references{required,polymorphic}"] + + expected_file = <<-FILE.strip_heredoc + class Account < ActiveRecord::Base + belongs_to :supplier, polymorphic: true, required: true + end + FILE + assert_file "app/models/account.rb", expected_file + end + + def test_required_and_polymorphic_are_order_independent + run_generator ["account", "supplier:references{polymorphic.required}"] + + expected_file = <<-FILE.strip_heredoc + class Account < ActiveRecord::Base + belongs_to :supplier, polymorphic: true, required: true + end + FILE + assert_file "app/models/account.rb", expected_file + end + + def test_required_adds_null_false_to_column + run_generator ["account", "supplier:references{required}"] + + assert_migration "db/migrate/create_accounts.rb" do |m| + assert_method :change, m do |up| + assert_match(/t\.references :supplier,.*\snull: false/, up) + end + end + end + + def test_foreign_key_is_not_added_for_non_references + run_generator ["account", "supplier:string"] + + assert_migration "db/migrate/create_accounts.rb" do |m| + assert_method :change, m do |up| + assert_no_match(/foreign_key/, up) + end + end + end + + def test_foreign_key_is_added_for_references + run_generator ["account", "supplier:belongs_to", "user:references"] + + assert_migration "db/migrate/create_accounts.rb" do |m| + assert_method :change, m do |up| + assert_match(/t\.belongs_to :supplier,.*\sforeign_key: true/, up) + assert_match(/t\.references :user,.*\sforeign_key: true/, up) + end + end + end + + def test_foreign_key_is_skipped_for_polymorphic_references + run_generator ["account", "supplier:belongs_to{polymorphic}"] + + assert_migration "db/migrate/create_accounts.rb" do |m| + assert_method :change, m do |up| + assert_no_match(/foreign_key/, up) + end + end + end + + def test_token_option_adds_has_secure_token + run_generator ["user", "token:token", "auth_token:token"] + expected_file = <<-FILE.strip_heredoc + class User < ActiveRecord::Base + has_secure_token + has_secure_token :auth_token + end + FILE + assert_file "app/models/user.rb", expected_file + end + private def assert_generated_fixture(path, parsed_contents) fixture_file = File.new File.expand_path(path, destination_root) diff --git a/railties/test/generators/named_base_test.rb b/railties/test/generators/named_base_test.rb index ac5cfff229..4199e00b0d 100644 --- a/railties/test/generators/named_base_test.rb +++ b/railties/test/generators/named_base_test.rb @@ -1,5 +1,6 @@ require 'generators/generators_test_helper' require 'rails/generators/rails/scaffold_controller/scaffold_controller_generator' +require 'mocha/setup' # FIXME: stop using mocha # Mock out what we need from AR::Base. module ActiveRecord diff --git a/railties/test/generators/namespaced_generators_test.rb b/railties/test/generators/namespaced_generators_test.rb index d677c21f15..d0ea01dfb0 100644 --- a/railties/test/generators/namespaced_generators_test.rb +++ b/railties/test/generators/namespaced_generators_test.rb @@ -47,7 +47,6 @@ class NamespacedControllerGeneratorTest < NamespacedGeneratorTestCase def test_helper_is_also_namespaced run_generator assert_file "app/helpers/test_app/account_helper.rb", /module TestApp/, / module AccountHelper/ - assert_file "test/helpers/test_app/account_helper_test.rb", /module TestApp/, / class AccountHelperTest/ end def test_invokes_default_test_framework @@ -147,26 +146,26 @@ class NamespacedMailerGeneratorTest < NamespacedGeneratorTestCase def test_mailer_skeleton_is_created run_generator - assert_file "app/mailers/test_app/notifier.rb" do |mailer| + assert_file "app/mailers/test_app/notifier_mailer.rb" do |mailer| assert_match(/module TestApp/, mailer) - assert_match(/class Notifier < ActionMailer::Base/, mailer) - assert_match(/default from: "from@example.com"/, mailer) + assert_match(/class NotifierMailer < ApplicationMailer/, mailer) + assert_no_match(/default from: "from@example.com"/, mailer) end end def test_mailer_with_i18n_helper run_generator - assert_file "app/mailers/test_app/notifier.rb" do |mailer| - assert_match(/en\.notifier\.foo\.subject/, mailer) - assert_match(/en\.notifier\.bar\.subject/, mailer) + assert_file "app/mailers/test_app/notifier_mailer.rb" do |mailer| + assert_match(/en\.notifier_mailer\.foo\.subject/, mailer) + assert_match(/en\.notifier_mailer\.bar\.subject/, mailer) end end def test_invokes_default_test_framework run_generator - assert_file "test/mailers/test_app/notifier_test.rb" do |test| + assert_file "test/mailers/test_app/notifier_mailer_test.rb" do |test| assert_match(/module TestApp/, test) - assert_match(/class NotifierTest < ActionMailer::TestCase/, test) + assert_match(/class NotifierMailerTest < ActionMailer::TestCase/, test) assert_match(/test "foo"/, test) assert_match(/test "bar"/, test) end @@ -229,7 +228,6 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase # Helpers assert_file "app/helpers/test_app/product_lines_helper.rb" - assert_file "test/helpers/test_app/product_lines_helper_test.rb" # Stylesheets assert_file "app/assets/stylesheets/scaffold.css" @@ -260,7 +258,6 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase # Helpers assert_no_file "app/helpers/test_app/product_lines_helper.rb" - assert_no_file "test/helpers/test_app/product_lines_helper_test.rb" # Stylesheets (should not be removed) assert_file "app/assets/stylesheets/scaffold.css" @@ -297,7 +294,6 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase # Helpers assert_file "app/helpers/test_app/admin/roles_helper.rb" - assert_file "test/helpers/test_app/admin/roles_helper_test.rb" # Stylesheets assert_file "app/assets/stylesheets/scaffold.css" @@ -329,7 +325,6 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase # Helpers assert_no_file "app/helpers/test_app/admin/roles_helper.rb" - assert_no_file "test/helpers/test_app/admin/roles_helper_test.rb" # Stylesheets (should not be removed) assert_file "app/assets/stylesheets/scaffold.css" @@ -366,7 +361,6 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase # Helpers assert_file "app/helpers/test_app/admin/user/special/roles_helper.rb" - assert_file "test/helpers/test_app/admin/user/special/roles_helper_test.rb" # Stylesheets assert_file "app/assets/stylesheets/scaffold.css" @@ -397,7 +391,6 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase # Helpers assert_no_file "app/helpers/test_app/admin/user/special/roles_helper.rb" - assert_no_file "test/helpers/test_app/admin/user/special/roles_helper_test.rb" # Stylesheets (should not be removed) assert_file "app/assets/stylesheets/scaffold.css" diff --git a/railties/test/generators/plugin_generator_test.rb b/railties/test/generators/plugin_generator_test.rb index 932cd75bcb..318ea5b2cb 100644 --- a/railties/test/generators/plugin_generator_test.rb +++ b/railties/test/generators/plugin_generator_test.rb @@ -1,6 +1,7 @@ require 'generators/generators_test_helper' require 'rails/generators/rails/plugin/plugin_generator' require 'generators/shared_generator_tests' +require 'mocha/setup' # FIXME: stop using mocha DEFAULT_PLUGIN_FILES = %w( .gitignore @@ -53,7 +54,11 @@ class PluginGeneratorTest < Rails::Generators::TestCase run_generator assert_file "README.rdoc", /Bukkits/ assert_no_file "config/routes.rb" - assert_file "test/test_helper.rb" + assert_file "test/test_helper.rb" do |content| + assert_match(/require.+test\/dummy\/config\/environment/, content) + assert_match(/ActiveRecord::Migrator\.migrations_paths.+test\/dummy\/db\/migrate/, content) + assert_match(/Minitest\.backtrace_filter = Minitest::BacktraceFilter\.new/, content) + end assert_file "test/bukkits_test.rb", /assert_kind_of Module, Bukkits/ end @@ -64,14 +69,14 @@ class PluginGeneratorTest < Rails::Generators::TestCase assert_file "test/integration/navigation_test.rb", /ActionDispatch::IntegrationTest/ end - def test_inclusion_of_debugger + def test_inclusion_of_a_debugger run_generator [destination_root, '--full'] - if defined?(JRUBY_VERSION) + if defined?(JRUBY_VERSION) || RUBY_ENGINE == "rbx" assert_file "Gemfile" do |content| - assert_no_match(/debugger/, content) + assert_no_match(/byebug/, content) end else - assert_file "Gemfile", /# gem 'debugger'/ + assert_file "Gemfile", /# gem 'byebug'/ end end @@ -91,7 +96,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase end def test_generating_adds_dummy_app_without_javascript_and_assets_deps - run_generator [destination_root] + run_generator assert_file "test/dummy/app/assets/stylesheets/application.css" @@ -132,6 +137,20 @@ class PluginGeneratorTest < Rails::Generators::TestCase end end + def test_app_generator_without_skips + run_generator + assert_file "test/dummy/config/application.rb", /\s+require\s+["']rails\/all["']/ + assert_file "test/dummy/config/environments/development.rb" do |content| + assert_match(/config\.action_mailer\.raise_delivery_errors = false/, content) + end + assert_file "test/dummy/config/environments/test.rb" do |content| + assert_match(/config\.action_mailer\.delivery_method = :test/, content) + end + assert_file "test/dummy/config/environments/production.rb" do |content| + assert_match(/# config\.action_mailer\.raise_delivery_errors = false/, content) + 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["']/ @@ -145,6 +164,20 @@ class PluginGeneratorTest < Rails::Generators::TestCase end end + def test_action_mailer_is_removed_from_frameworks_if_skip_action_mailer_is_given + run_generator [destination_root, "--skip-action-mailer"] + assert_file "test/dummy/config/application.rb", /#\s+require\s+["']action_mailer\/railtie["']/ + assert_file "test/dummy/config/environments/development.rb" do |content| + assert_no_match(/config\.action_mailer/, content) + end + assert_file "test/dummy/config/environments/test.rb" do |content| + assert_no_match(/config\.action_mailer/, content) + end + assert_file "test/dummy/config/environments/production.rb" do |content| + assert_no_match(/config\.action_mailer/, content) + end + end + def test_ensure_that_database_option_is_passed_to_app_generator run_generator [destination_root, "--database", "postgresql"] assert_file "test/dummy/config/database.yml", /postgres/ @@ -156,7 +189,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase assert_match(/bukkits/, contents) end assert_match(/run bundle install/, result) - assert_match(/Using bukkits \(0\.0\.1\)/, 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 @@ -185,22 +218,22 @@ class PluginGeneratorTest < Rails::Generators::TestCase run_generator FileUtils.cd destination_root quietly { system 'bundle install' } - assert_match(/1 runs, 1 assertions, 0 failures, 0 errors/, `bundle exec rake test`) + assert_match(/1 runs, 1 assertions, 0 failures, 0 errors/, `bundle exec rake test 2>&1`) end def test_ensure_that_tests_works_in_full_mode run_generator [destination_root, "--full", "--skip_active_record"] FileUtils.cd destination_root quietly { system 'bundle install' } - assert_match(/1 runs, 1 assertions, 0 failures, 0 errors/, `bundle exec rake test`) + assert_match(/1 runs, 1 assertions, 0 failures, 0 errors/, `bundle exec rake test 2>&1`) end def test_ensure_that_migration_tasks_work_with_mountable_option run_generator [destination_root, "--mountable"] FileUtils.cd destination_root quietly { system 'bundle install' } - `bundle exec rake db:migrate` - assert_equal 0, $?.exitstatus + output = `bundle exec rake db:migrate 2>&1` + assert $?.success?, "Command failed: #{output}" end def test_creating_engine_in_full_mode @@ -238,6 +271,10 @@ class PluginGeneratorTest < Rails::Generators::TestCase assert_match(/stylesheet_link_tag\s+['"]bukkits\/application['"]/, contents) assert_match(/javascript_include_tag\s+['"]bukkits\/application['"]/, contents) end + assert_file "test/test_helper.rb" do |content| + assert_match(/ActiveRecord::Migrator\.migrations_paths.+\.\.\/test\/dummy\/db\/migrate/, content) + assert_match(/ActiveRecord::Migrator\.migrations_paths.+<<.+\.\.\/db\/migrate/, content) + end end def test_creating_gemspec @@ -266,6 +303,10 @@ class PluginGeneratorTest < Rails::Generators::TestCase assert_file "spec/dummy" assert_file "spec/dummy/config/application.rb" assert_no_file "test/dummy" + assert_file "test/test_helper.rb" do |content| + assert_match(/require.+spec\/dummy\/config\/environment/, content) + assert_match(/ActiveRecord::Migrator\.migrations_paths.+spec\/dummy\/db\/migrate/, content) + end end def test_creating_dummy_application_with_different_name @@ -273,6 +314,10 @@ class PluginGeneratorTest < Rails::Generators::TestCase assert_file "spec/fake" assert_file "spec/fake/config/application.rb" assert_no_file "test/dummy" + assert_file "test/test_helper.rb" do |content| + assert_match(/require.+spec\/fake\/config\/environment/, content) + assert_match(/ActiveRecord::Migrator\.migrations_paths.+spec\/fake\/db\/migrate/, content) + end end def test_creating_dummy_without_tests_but_with_dummy_path @@ -280,6 +325,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase assert_file "spec/dummy" assert_file "spec/dummy/config/application.rb" assert_no_file "test" + assert_no_file "test/test_helper.rb" assert_file '.gitignore' do |contents| assert_match(/spec\/dummy/, contents) end @@ -309,7 +355,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase assert_no_file "bukkits.gemspec" assert_file "Gemfile" do |contents| assert_no_match('gemspec', contents) - assert_match(/gem "rails", "~> #{Rails.version}"/, contents) + assert_match(/gem 'rails', '~> #{Rails.version}'/, contents) assert_match_sqlite3(contents) assert_no_match(/# gem "jquery-rails"/, contents) end @@ -320,7 +366,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase assert_no_file "bukkits.gemspec" assert_file "Gemfile" do |contents| assert_no_match('gemspec', contents) - assert_match(/gem "rails", "~> #{Rails.version}"/, contents) + assert_match(/gem 'rails', '~> #{Rails.version}'/, contents) assert_match_sqlite3(contents) end end @@ -331,7 +377,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase Object.const_set('APP_PATH', Rails.root) FileUtils.touch gemfile_path - run_generator [destination_root] + run_generator assert_file gemfile_path, /gem 'bukkits', path: 'tmp\/bukkits'/ ensure @@ -355,6 +401,52 @@ class PluginGeneratorTest < Rails::Generators::TestCase FileUtils.rm gemfile_path end + def test_generating_controller_inside_mountable_engine + run_generator [destination_root, "--mountable"] + + capture(:stdout) do + `#{destination_root}/bin/rails g controller admin/dashboard foo` + end + + assert_file "config/routes.rb" do |contents| + assert_match(/namespace :admin/, contents) + assert_no_match(/namespace :bukkit/, contents) + end + end + + def test_git_name_and_email_in_gemspec_file + name = `git config user.name`.chomp rescue "TODO: Write your name" + email = `git config user.email`.chomp rescue "TODO: Write your email address" + + run_generator + assert_file "bukkits.gemspec" do |contents| + assert_match name, contents + assert_match email, contents + end + end + + def test_git_name_in_license_file + name = `git config user.name`.chomp rescue "TODO: Write your name" + + run_generator + assert_file "MIT-LICENSE" do |contents| + assert_match name, contents + end + end + + def test_no_details_from_git_when_skip_git + name = "TODO: Write your name" + email = "TODO: Write your email address" + + run_generator [destination_root, '--skip-git'] + assert_file "MIT-LICENSE" do |contents| + assert_match name, contents + end + assert_file "bukkits.gemspec" do |contents| + assert_match name, contents + assert_match email, contents + end + end protected def action(*args, &block) @@ -366,10 +458,10 @@ protected end def assert_match_sqlite3(contents) - unless defined?(JRUBY_VERSION) - assert_match(/group :development do\n gem "sqlite3"\nend/, contents) + if defined?(JRUBY_VERSION) + assert_match(/group :development do\n gem 'activerecord-jdbcsqlite3-adapter'\nend/, contents) else - assert_match(/group :development do\n gem "activerecord-jdbcsqlite3-adapter"\nend/, contents) + assert_match(/group :development do\n gem 'sqlite3'\nend/, contents) end end end diff --git a/railties/test/generators/resource_generator_test.rb b/railties/test/generators/resource_generator_test.rb index 3d4e694361..581d80d60e 100644 --- a/railties/test/generators/resource_generator_test.rb +++ b/railties/test/generators/resource_generator_test.rb @@ -36,7 +36,6 @@ class ResourceGeneratorTest < Rails::Generators::TestCase assert_file "test/controllers/accounts_controller_test.rb", /class AccountsControllerTest < ActionController::TestCase/ assert_file "app/helpers/accounts_helper.rb", /module AccountsHelper/ - assert_file "test/helpers/accounts_helper_test.rb", /class AccountsHelperTest < ActionView::TestCase/ end def test_resource_controller_with_actions @@ -63,19 +62,19 @@ class ResourceGeneratorTest < Rails::Generators::TestCase content = run_generator ["accounts".freeze] assert_file "app/models/account.rb", /class Account < ActiveRecord::Base/ assert_file "test/models/account_test.rb", /class AccountTest/ - assert_match(/Plural version of the model detected, using singularized version. Override with --force-plural./, content) + assert_match(/\[WARNING\] The model name 'accounts' was recognized as a plural, using the singular 'account' instead\. Override with --force-plural or setup custom inflection rules for this noun before running the generator\./, content) end def test_plural_names_can_be_forced content = run_generator ["accounts", "--force-plural"] assert_file "app/models/accounts.rb", /class Accounts < ActiveRecord::Base/ assert_file "test/models/accounts_test.rb", /class AccountsTest/ - assert_no_match(/Plural version of the model detected/, content) + assert_no_match(/\[WARNING\]/, content) end def test_mass_nouns_do_not_throw_warnings content = run_generator ["sheep".freeze] - assert_no_match(/Plural version of the model detected/, content) + assert_no_match(/\[WARNING\]/, content) end def test_route_is_removed_on_revoke diff --git a/railties/test/generators/scaffold_controller_generator_test.rb b/railties/test/generators/scaffold_controller_generator_test.rb index 26e56a162c..ca972a3bdd 100644 --- a/railties/test/generators/scaffold_controller_generator_test.rb +++ b/railties/test/generators/scaffold_controller_generator_test.rb @@ -81,7 +81,6 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase def test_helper_are_invoked_with_a_pluralized_name run_generator assert_file "app/helpers/users_helper.rb", /module UsersHelper/ - assert_file "test/helpers/users_helper_test.rb", /class UsersHelperTest < ActionView::TestCase/ end def test_views_are_generated @@ -93,6 +92,14 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase assert_no_file "app/views/layouts/users.html.erb" end + def test_index_page_have_notice + run_generator + + %w(index show).each do |view| + assert_file "app/views/users/#{view}.html.erb", /notice/ + end + end + def test_functional_tests run_generator ["User", "name:string", "age:integer", "organization:references{polymorphic}"] @@ -118,7 +125,6 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase def test_skip_helper_if_required run_generator ["User", "name:string", "age:integer", "--no-helper"] assert_no_file "app/helpers/users_helper.rb" - assert_no_file "test/helpers/users_helper_test.rb" end def test_skip_layout_if_required @@ -160,13 +166,6 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase Unknown::Generators.send :remove_const, :ActiveModel end - def test_new_hash_style - run_generator - assert_file "app/controllers/users_controller.rb" do |content| - assert_match(/render action: 'new'/, content) - end - end - def test_model_name_option run_generator ["Admin::User", "--model-name=User"] assert_file "app/controllers/admin/users_controller.rb" do |content| diff --git a/railties/test/generators/scaffold_generator_test.rb b/railties/test/generators/scaffold_generator_test.rb index 524bbde2b7..3b545328b5 100644 --- a/railties/test/generators/scaffold_generator_test.rb +++ b/railties/test/generators/scaffold_generator_test.rb @@ -63,14 +63,23 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase end # Views - %w(index edit new show _form).each do |view| + assert_no_file "app/views/layouts/product_lines.html.erb" + + %w(index show).each do |view| assert_file "app/views/product_lines/#{view}.html.erb" end - assert_no_file "app/views/layouts/product_lines.html.erb" + + %w(edit new).each do |view| + assert_file "app/views/product_lines/#{view}.html.erb", /render 'form', product_line: @product_line/ + end + + assert_file "app/views/product_lines/_form.html.erb" do |test| + assert_match 'product_line', test + assert_no_match '@product_line', test + end # Helpers assert_file "app/helpers/product_lines_helper.rb" - assert_file "test/helpers/product_lines_helper_test.rb" # Assets assert_file "app/assets/stylesheets/scaffold.css" @@ -114,7 +123,6 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase # Helpers assert_no_file "app/helpers/product_lines_helper.rb" - assert_no_file "test/helpers/product_lines_helper_test.rb" # Assets assert_file "app/assets/stylesheets/scaffold.css", /:visited/ @@ -182,7 +190,6 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase # Helpers assert_file "app/helpers/admin/roles_helper.rb" - assert_file "test/helpers/admin/roles_helper_test.rb" # Assets assert_file "app/assets/stylesheets/scaffold.css", /:visited/ @@ -216,7 +223,6 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase # Helpers assert_no_file "app/helpers/admin/roles_helper.rb" - assert_no_file "test/helpers/admin/roles_helper_test.rb" # Assets assert_file "app/assets/stylesheets/scaffold.css" @@ -253,13 +259,27 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase assert_no_file "app/assets/stylesheets/posts.css" end - def test_scaffold_generator_no_assets_with_switch_resource_route_false + def test_scaffold_generator_with_switch_resource_route_false run_generator [ "posts", "--resource-route=false" ] assert_file "config/routes.rb" do |route| assert_no_match(/resources :posts$/, route) end end + def test_scaffold_generator_no_helper_with_switch_no_helper + output = run_generator [ "posts", "--no-helper" ] + + assert_no_match(/error/, output) + assert_no_file "app/helpers/posts_helper.rb" + end + + def test_scaffold_generator_no_helper_with_switch_helper_false + output = run_generator [ "posts", "--helper=false" ] + + assert_no_match(/error/, output) + assert_no_file "app/helpers/posts_helper.rb" + end + def test_scaffold_generator_no_stylesheets run_generator [ "posts", "--no-stylesheets" ] assert_no_file "app/assets/stylesheets/scaffold.css" diff --git a/railties/test/generators/shared_generator_tests.rb b/railties/test/generators/shared_generator_tests.rb index 8e198d5fe1..b998fef42e 100644 --- a/railties/test/generators/shared_generator_tests.rb +++ b/railties/test/generators/shared_generator_tests.rb @@ -78,9 +78,12 @@ module SharedGeneratorTests end def test_template_raises_an_error_with_invalid_path - content = capture(:stderr){ run_generator([destination_root, "-m", "non/existent/path"]) } - assert_match(/The template \[.*\] could not be loaded/, content) - assert_match(/non\/existent\/path/, content) + quietly do + content = capture(:stderr){ run_generator([destination_root, "-m", "non/existent/path"]) } + + assert_match(/The template \[.*\] could not be loaded/, content) + assert_match(/non\/existent\/path/, content) + end end def test_template_is_executed_when_supplied @@ -89,7 +92,7 @@ module SharedGeneratorTests 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 }) + quietly { assert_match(/It works!/, capture(:stdout) { generator.invoke_all }) } end def test_template_is_executed_when_supplied_an_https_path @@ -98,7 +101,7 @@ module SharedGeneratorTests 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 }) + quietly { assert_match(/It works!/, capture(:stdout) { generator.invoke_all }) } end def test_dev_option |