diff options
Diffstat (limited to 'railties/test/generators')
-rw-r--r-- | railties/test/generators/actions_test.rb | 67 | ||||
-rw-r--r-- | railties/test/generators/app_generator_test.rb | 214 | ||||
-rw-r--r-- | railties/test/generators/generated_attribute_test.rb | 12 | ||||
-rw-r--r-- | railties/test/generators/generator_generator_test.rb | 39 | ||||
-rw-r--r-- | railties/test/generators/generators_test_helper.rb | 4 | ||||
-rw-r--r-- | railties/test/generators/mailer_generator_test.rb | 9 | ||||
-rw-r--r-- | railties/test/generators/migration_generator_test.rb | 15 | ||||
-rw-r--r-- | railties/test/generators/model_generator_test.rb | 82 | ||||
-rw-r--r-- | railties/test/generators/named_base_test.rb | 5 | ||||
-rw-r--r-- | railties/test/generators/namespaced_generators_test.rb | 357 | ||||
-rw-r--r-- | railties/test/generators/plugin_generator_test.rb | 18 | ||||
-rw-r--r-- | railties/test/generators/plugin_new_generator_test.rb | 229 | ||||
-rw-r--r-- | railties/test/generators/resource_generator_test.rb | 5 | ||||
-rw-r--r-- | railties/test/generators/scaffold_generator_test.rb | 73 | ||||
-rw-r--r-- | railties/test/generators/shared_generator_tests.rb | 195 |
15 files changed, 1091 insertions, 233 deletions
diff --git a/railties/test/generators/actions_test.rb b/railties/test/generators/actions_test.rb index 0472ca73a8..68d4c17623 100644 --- a/railties/test/generators/actions_test.rb +++ b/railties/test/generators/actions_test.rb @@ -7,11 +7,16 @@ class ActionsTest < Rails::Generators::TestCase arguments [destination_root] def setup + Rails.application = TestApp::Application super @git_plugin_uri = 'git://github.com/technoweenie/restful-authentication.git' @svn_plugin_uri = 'svn://svnhub.com/technoweenie/restful-authentication/trunk' end + def teardown + Rails.application = TestApp::Application.instance + end + def test_invoke_other_generator_with_shortcut action :invoke, 'model', ['my_model'] assert_file 'app/models/my_model.rb', /MyModel/ @@ -79,37 +84,6 @@ class ActionsTest < Rails::Generators::TestCase assert_file 'Gemfile', /gem "will\-paginate"/ end - def test_gem_with_options_should_include_all_options_in_gemfile - run_generator - - assert_deprecated do - action :gem, 'mislav-will-paginate', :lib => 'will-paginate', :source => 'http://gems.github.com' - end - - assert_deprecated do - action :gem, 'thoughtbot-factory_girl', :require_as => 'factory_girl', :source => 'http://gems.github.com' - end - - assert_file 'Gemfile', /gem "mislav\-will\-paginate", :require => "will\-paginate"/ - assert_file 'Gemfile', /source "http:\/\/gems\.github\.com"/ - assert_file 'Gemfile', /gem "thoughtbot-factory_girl", :require => "factory_girl"/ - end - - def test_gem_with_env_should_include_all_dependencies_in_gemfile - run_generator - - assert_deprecated do - action :gem, 'rspec', :env => %w(development test) - end - - assert_deprecated do - action :gem, 'rspec-rails', :only => %w(development test) - end - - assert_file 'Gemfile', /gem "rspec", :group => \["development", "test"\]/ - assert_file 'Gemfile', /gem "rspec-rails", :group => \["development", "test"\]/ - end - def test_gem_with_version_should_include_version_in_gemfile run_generator @@ -204,12 +178,6 @@ class ActionsTest < Rails::Generators::TestCase action :capify! end - def test_freeze_is_deprecated - assert_deprecated do - action :freeze! - end - end - def test_route_should_add_data_to_the_routes_block_in_config_routes run_generator route_command = "route '/login', :controller => 'sessions', :action => 'new'" @@ -223,6 +191,31 @@ class ActionsTest < Rails::Generators::TestCase assert_match(/Welcome to Rails/, action(:readme, "README")) end + def test_readme_with_quiet + generator(default_arguments, :quiet => true) + run_generator + Rails::Generators::AppGenerator.expects(:source_root).times(2).returns(destination_root) + assert_no_match(/Welcome to Rails/, action(:readme, "README")) + end + + def test_log + assert_equal("YES\n", action(:log, "YES")) + end + + def test_log_with_status + assert_equal(" yes YES\n", action(:log, :yes, "YES")) + end + + def test_log_with_quiet + generator(default_arguments, :quiet => true) + assert_equal("", action(:log, "YES")) + end + + def test_log_with_status_with_quiet + generator(default_arguments, :quiet => true) + assert_equal("", action(:log, :yes, "YES")) + end + protected def action(*args, &block) diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index 08cfb585f9..018c2fa6bf 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -1,6 +1,7 @@ require 'abstract_unit' require 'generators/generators_test_helper' require 'rails/generators/rails/app/app_generator' +require 'generators/shared_generator_tests.rb' DEFAULT_APP_FILES = %w( .gitignore @@ -40,28 +41,10 @@ DEFAULT_APP_FILES = %w( class AppGeneratorTest < Rails::Generators::TestCase include GeneratorsTestHelper arguments [destination_root] + include SharedGeneratorTests - def setup - super - Rails::Generators::AppGenerator.instance_variable_set('@desc', nil) - @bundle_command = File.basename(Thor::Util.ruby_command).sub(/ruby/, 'bundle') - end - - def teardown - super - Rails::Generators::AppGenerator.instance_variable_set('@desc', nil) - end - - def test_application_skeleton_is_created - run_generator - - DEFAULT_APP_FILES.each{ |path| assert_file path } - end - - def test_application_generate_pretend - run_generator ["testapp", "--pretend"] - - DEFAULT_APP_FILES.each{ |path| assert_no_file path } + def default_files + ::DEFAULT_APP_FILES end def test_application_controller_and_layout_files @@ -70,42 +53,34 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_no_file "public/stylesheets/application.css" end - def test_options_before_application_name_raises_an_error - content = capture(:stderr){ run_generator(["--skip-active-record", destination_root]) } - assert_equal "Options should be given after the application name. For details run: rails --help\n", content - end - - def test_name_collision_raises_an_error - reserved_words = %w[application destroy plugin runner test] - reserved_words.each do |reserved| - content = capture(:stderr){ run_generator [File.join(destination_root, reserved)] } - assert_equal "Invalid application name #{reserved}. Please give a name which does not match one of the reserved rails words.\n", content - end - end - - def test_invalid_database_option_raises_an_error - content = capture(:stderr){ run_generator([destination_root, "-d", "unknown"]) } - assert_match /Invalid value for \-\-database option/, content - end - def test_invalid_application_name_raises_an_error content = capture(:stderr){ run_generator [File.join(destination_root, "43-things")] } assert_equal "Invalid application name 43-things. Please give a name which does not start with numbers.\n", content end - def test_application_name_raises_an_error_if_name_already_used_constant - %w{ String Hash Class Module Set Symbol }.each do |ruby_class| - content = capture(:stderr){ run_generator [File.join(destination_root, ruby_class)] } - assert_equal "Invalid application name #{ruby_class}, constant #{ruby_class} is already in use. Please choose another application name.\n", content - end - end - def test_invalid_application_name_is_fixed run_generator [File.join(destination_root, "things-43")] assert_file "things-43/config/environment.rb", /Things43::Application\.initialize!/ assert_file "things-43/config/application.rb", /^module Things43$/ end + def test_application_new_exits_with_non_zero_code_on_invalid_application_name + # TODO: Suppress the output of this (it's because of a Thor::Error) + `rails new test` + assert_equal false, $?.success? + end + + def test_application_new_exits_with_message_and_non_zero_code_when_generating_inside_existing_rails_directory + app_root = File.join(destination_root, 'myfirstapp') + run_generator [app_root] + output = nil + Dir.chdir(app_root) do + output = `rails new mysecondapp` + end + assert_equal "Can't initialize a new Rails application within the directory of another, please change to a non-Rails directory first.\nType 'rails' for help.\n", output + assert_equal false, $?.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") @@ -118,16 +93,26 @@ class AppGeneratorTest < Rails::Generators::TestCase FileUtils.mv(app_root, app_moved_root) - # forces the shell to automatically overwrite all files - Thor::Base.shell.send(:attr_accessor, :always_force) - shell = Thor::Base.shell.new - shell.send(:always_force=, true) - generator = Rails::Generators::AppGenerator.new ["rails"], { :with_dispatchers => true }, - :destination_root => app_moved_root, :shell => shell + :destination_root => app_moved_root, :shell => @shell generator.send(:app_const) silence(:stdout){ generator.send(:create_config_files) } assert_file "myapp_moved/config/environment.rb", /Myapp::Application\.initialize!/ + assert_file "myapp_moved/config/initializers/session_store.rb", /_myapp_session/ + end + + def test_rails_update_generates_correct_session_key + 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) + silence(:stdout){ generator.send(:create_config_files) } + assert_file "myapp/config/initializers/session_store.rb", /_myapp_session/ end def test_application_names_are_not_singularized @@ -138,18 +123,22 @@ class AppGeneratorTest < Rails::Generators::TestCase def test_config_database_is_added_by_default run_generator assert_file "config/database.yml", /sqlite3/ - assert_file "Gemfile", /^gem\s+["']sqlite3-ruby["'],\s+:require\s+=>\s+["']sqlite3["']$/ + assert_file "Gemfile", /^gem\s+["']sqlite3["']$/ end def test_config_another_database run_generator([destination_root, "-d", "mysql"]) assert_file "config/database.yml", /mysql/ - assert_file "Gemfile", /^gem\s+["']mysql["']$/ + assert_file "Gemfile", /^gem\s+["']mysql2["']$/ end - def test_config_database_is_not_added_if_skip_active_record_is_given + def test_generator_if_skip_active_record_is_given run_generator [destination_root, "--skip-active-record"] assert_no_file "config/database.yml" + assert_file "test/test_helper.rb" do |helper_content| + assert_no_match /fixtures :all/, helper_content + end + assert_file "test/performance/browsing_test.rb" end def test_active_record_is_removed_from_frameworks_if_skip_active_record_is_given @@ -163,26 +152,37 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_file "public/javascripts/application.js" assert_file "public/javascripts/prototype.js" assert_file "public/javascripts/rails.js" + assert_file "public/javascripts/controls.js" + assert_file "public/javascripts/dragdrop.js" + assert_file "public/javascripts/effects.js" assert_file "test" end - def test_prototype_and_test_unit_are_skipped_if_required - run_generator [destination_root, "--skip-prototype", "--skip-test-unit"] + def test_javascript_is_skipped_if_required + run_generator [destination_root, "--skip-javascript"] assert_file "config/application.rb", /^\s+config\.action_view\.javascript_expansions\[:defaults\]\s+=\s+%w\(\)/ assert_file "public/javascripts/application.js" assert_no_file "public/javascripts/prototype.js" assert_no_file "public/javascripts/rails.js" - assert_no_file "test" end - def test_shebang_is_added_to_rails_file - run_generator [destination_root, "--ruby", "foo/bar/baz"] - assert_file "script/rails", /#!foo\/bar\/baz/ + def test_config_prototype_javascript_library + run_generator [destination_root, "-j", "prototype"] + assert_file "config/application.rb", /#\s+config\.action_view\.javascript_expansions\[:defaults\]\s+=\s+%w\(jquery rails\)/ + assert_file "public/javascripts/application.js" + assert_file "public/javascripts/prototype.js" + assert_file "public/javascripts/controls.js" + assert_file "public/javascripts/dragdrop.js" + assert_file "public/javascripts/effects.js" + assert_file "public/javascripts/rails.js", /prototype/ end - def test_shebang_when_is_the_same_as_default_use_env - run_generator [destination_root, "--ruby", Thor::Util.ruby_command] - assert_file "script/rails", /#!\/usr\/bin\/env/ + def test_config_jquery_javascript_library + run_generator [destination_root, "-j", "jquery"] + assert_file "config/application.rb", /^\s+config\.action_view\.javascript_expansions\[:defaults\]\s+=\s+%w\(jquery rails\)/ + assert_file "public/javascripts/application.js" + assert_file "public/javascripts/jquery.js" + assert_file "public/javascripts/rails.js", /jQuery/ end def test_template_from_dir_pwd @@ -190,21 +190,6 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_match /It works from file!/, run_generator([destination_root, "-m", "lib/template.rb"]) 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!/, silence(:stdout){ generator.invoke_all } - end - def test_usage_read_from_file File.expects(:read).returns("USAGE FROM FILE") assert_equal "USAGE FROM FILE", Rails::Generators::AppGenerator.desc @@ -224,17 +209,11 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_file 'lib/test_file.rb', 'heres test data' end - def test_dev_option - generator([destination_root], :dev => true).expects(:run).with("#{@bundle_command} install") - silence(:stdout){ generator.invoke_all } - rails_path = File.expand_path('../../..', Rails.root) - assert_file 'Gemfile', /^gem\s+["']rails["'],\s+:path\s+=>\s+["']#{Regexp.escape(rails_path)}["']$/ - end - - def test_edge_option - generator([destination_root], :edge => true).expects(:run).with("#{@bundle_command} install") - silence(:stdout){ generator.invoke_all } - assert_file 'Gemfile', /^gem\s+["']rails["'],\s+:git\s+=>\s+["']#{Regexp.escape("git://github.com/rails/rails.git")}["']$/ + def test_test_unit_is_removed_from_frameworks_if_skip_test_unit_is_given + run_generator [destination_root, "--skip-test-unit"] + assert_file "config/application.rb" do |file| + assert_match /config.generators.test_framework = false/, file + end end protected @@ -250,60 +229,21 @@ class CustomAppGeneratorTest < Rails::Generators::TestCase tests Rails::Generators::AppGenerator arguments [destination_root] + include SharedCustomGeneratorTests - def setup - super - Rails::Generators::AppGenerator.instance_variable_set('@desc', nil) - @bundle_command = File.basename(Thor::Util.ruby_command).sub(/ruby/, 'bundle') - end - - def teardown - super - Rails::Generators::AppGenerator.instance_variable_set('@desc', nil) - Object.class_eval { remove_const :AppBuilder if const_defined?(:AppBuilder) } - end - - def test_builder_option_with_empty_app_builder - FileUtils.cd(Rails.root) - run_generator([destination_root, "-b", "#{Rails.root}/lib/empty_builder.rb"]) - DEFAULT_APP_FILES.each{ |path| assert_no_file path } - end - - def test_builder_option_with_simple_app_builder - FileUtils.cd(Rails.root) - run_generator([destination_root, "-b", "#{Rails.root}/lib/simple_builder.rb"]) - (DEFAULT_APP_FILES - ['config.ru']).each{ |path| assert_no_file path } - assert_file "config.ru", %[run proc { |env| [200, { "Content-Type" => "text/html" }, ["Hello World"]] }] - end - - def test_builder_option_with_relative_path - here = File.expand_path(File.dirname(__FILE__)) - FileUtils.cd(here) - run_generator([destination_root, "-b", "../fixtures/lib/simple_builder.rb"]) - (DEFAULT_APP_FILES - ['config.ru']).each{ |path| assert_no_file path } - assert_file "config.ru", %[run proc { |env| [200, { "Content-Type" => "text/html" }, ["Hello World"]] }] +protected + def default_files + ::DEFAULT_APP_FILES end - def test_builder_option_with_tweak_app_builder - FileUtils.cd(Rails.root) - run_generator([destination_root, "-b", "#{Rails.root}/lib/tweak_builder.rb"]) - DEFAULT_APP_FILES.each{ |path| assert_file path } - assert_file "config.ru", %[run proc { |env| [200, { "Content-Type" => "text/html" }, ["Hello World"]] }] + def builders_dir + "app_builders" end - def test_builder_option_with_http - path = "http://gist.github.com/103208.txt" - template = "class AppBuilder; end" - template.instance_eval "def read; self; end" # Make the string respond to read - - generator([destination_root], :builder => path).expects(:open).with(path, 'Accept' => 'application/x-thor-template').returns(template) - capture(:stdout) { generator.invoke_all } - - DEFAULT_APP_FILES.each{ |path| assert_no_file path } + def builder_class + :AppBuilder end -protected - def action(*args, &block) silence(:stdout){ generator.send(*args, &block) } end diff --git a/railties/test/generators/generated_attribute_test.rb b/railties/test/generators/generated_attribute_test.rb index de7e4de2a6..064546a3f3 100644 --- a/railties/test/generators/generated_attribute_test.rb +++ b/railties/test/generators/generated_attribute_test.rb @@ -108,4 +108,16 @@ class GeneratedAttributeTest < Rails::Generators::TestCase ) end end + + def test_nil_type_raises_exception + assert_raise Thor::Error do + create_generated_attribute(nil, 'title') + end + end + + def test_missing_type_raises_exception + assert_raise Thor::Error do + create_generated_attribute('', 'title') + end + end end diff --git a/railties/test/generators/generator_generator_test.rb b/railties/test/generators/generator_generator_test.rb index 26f975a191..f4c975fc18 100644 --- a/railties/test/generators/generator_generator_test.rb +++ b/railties/test/generators/generator_generator_test.rb @@ -17,4 +17,43 @@ class GeneratorGeneratorTest < Rails::Generators::TestCase assert_file "lib/generators/awesome/awesome_generator.rb", /class AwesomeGenerator < Rails::Generators::NamedBase/ end + + def test_namespaced_generator_skeleton + run_generator ["rails/awesome"] + + %w( + lib/generators/rails/awesome + lib/generators/rails/awesome/USAGE + lib/generators/rails/awesome/templates + ).each{ |path| assert_file path } + + assert_file "lib/generators/rails/awesome/awesome_generator.rb", + /class Rails::AwesomeGenerator < Rails::Generators::NamedBase/ + end + + def test_generator_skeleton_is_created_without_file_name_namespace + run_generator ["awesome", "--namespace", "false"] + + %w( + lib/generators/ + lib/generators/USAGE + lib/generators/templates + ).each{ |path| assert_file path } + + assert_file "lib/generators/awesome_generator.rb", + /class AwesomeGenerator < Rails::Generators::NamedBase/ + end + + def test_namespaced_generator_skeleton_without_file_name_namespace + run_generator ["rails/awesome", "--namespace", "false"] + + %w( + lib/generators/rails + lib/generators/rails/USAGE + lib/generators/rails/templates + ).each{ |path| assert_file path } + + assert_file "lib/generators/rails/awesome_generator.rb", + /class Rails::AwesomeGenerator < Rails::Generators::NamedBase/ + end end diff --git a/railties/test/generators/generators_test_helper.rb b/railties/test/generators/generators_test_helper.rb index 4a5a9b2932..1b9a8fd8a7 100644 --- a/railties/test/generators/generators_test_helper.rb +++ b/railties/test/generators/generators_test_helper.rb @@ -34,6 +34,6 @@ module GeneratorsTestHelper routes = File.expand_path("../../../lib/rails/generators/rails/app/templates/config/routes.rb", __FILE__) destination = File.join(destination_root, "config") FileUtils.mkdir_p(destination) - FileUtils.cp File.expand_path(routes), destination + FileUtils.cp routes, destination end -end
\ No newline at end of file +end diff --git a/railties/test/generators/mailer_generator_test.rb b/railties/test/generators/mailer_generator_test.rb index 450dec7716..f4fdc46328 100644 --- a/railties/test/generators/mailer_generator_test.rb +++ b/railties/test/generators/mailer_generator_test.rb @@ -59,6 +59,15 @@ class MailerGeneratorTest < Rails::Generators::TestCase assert_match /haml \[not found\]/, content end + 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 + end + assert_file "app/views/farm/animal/moos.text.erb" + end + def test_actions_are_turned_into_methods run_generator diff --git a/railties/test/generators/migration_generator_test.rb b/railties/test/generators/migration_generator_test.rb index f9d1e42d24..6eecfc8e2e 100644 --- a/railties/test/generators/migration_generator_test.rb +++ b/railties/test/generators/migration_generator_test.rb @@ -34,15 +34,10 @@ class MigrationGeneratorTest < Rails::Generators::TestCase run_generator [migration, "title:string", "body:text"] assert_migration "db/migrate/#{migration}.rb" do |content| - assert_class_method :up, content do |up| + assert_method :change, content do |up| assert_match /add_column :posts, :title, :string/, up assert_match /add_column :posts, :body, :text/, up end - - assert_class_method :down, content do |down| - assert_match /remove_column :posts, :title/, down - assert_match /remove_column :posts, :body/, down - end end end @@ -51,12 +46,12 @@ class MigrationGeneratorTest < Rails::Generators::TestCase run_generator [migration, "title:string", "body:text"] assert_migration "db/migrate/#{migration}.rb" do |content| - assert_class_method :up, content do |up| + assert_method :up, content do |up| assert_match /remove_column :posts, :title/, up assert_match /remove_column :posts, :body/, up end - assert_class_method :down, content do |down| + assert_method :down, content do |down| assert_match /add_column :posts, :title, :string/, down assert_match /add_column :posts, :body, :text/, down end @@ -68,11 +63,11 @@ class MigrationGeneratorTest < Rails::Generators::TestCase run_generator [migration, "title:string", "content:text"] assert_migration "db/migrate/#{migration}.rb" do |content| - assert_class_method :up, content do |up| + assert_method :up, content do |up| assert_match /^\s*$/, up end - assert_class_method :down, content do |down| + assert_method :down, content do |down| assert_match /^\s*$/, down end end diff --git a/railties/test/generators/model_generator_test.rb b/railties/test/generators/model_generator_test.rb index ef415a4fed..3d773b4134 100644 --- a/railties/test/generators/model_generator_test.rb +++ b/railties/test/generators/model_generator_test.rb @@ -11,6 +11,12 @@ class ModelGeneratorTest < Rails::Generators::TestCase assert_match /TestUnit options:/, content end + def test_model_with_missing_attribute_type + content = capture(:stderr) { run_generator ["post", "title:string", "body"] } + assert_match /Missing type for attribute 'body'/, content + assert_match /Example: 'body:string' where string is the type/, content + end + def test_invokes_default_orm run_generator assert_file "app/models/account.rb", /class Account < ActiveRecord::Base/ @@ -93,15 +99,11 @@ class ModelGeneratorTest < Rails::Generators::TestCase run_generator ["product", "name:string", "supplier_id:integer"] assert_migration "db/migrate/create_products.rb" do |m| - assert_class_method :up, m do |up| + assert_method :change, m do |up| assert_match /create_table :products/, up assert_match /t\.string :name/, up assert_match /t\.integer :supplier_id/, up end - - assert_class_method :down, m do |down| - assert_match /drop_table :products/, down - end end end @@ -135,16 +137,28 @@ class ModelGeneratorTest < Rails::Generators::TestCase run_generator ["account", "--no-timestamps"] assert_migration "db/migrate/create_accounts.rb" do |m| - assert_class_method :up, m do |up| + assert_method :change, m do |up| assert_no_match /t.timestamps/, up end end end - def test_migration_already_exists_error_message + def test_migration_is_skipped_with_skip_option + run_generator + output = run_generator ["Account", "--skip"] + assert_match %r{skip\s+db/migrate/\d+_create_accounts.rb}, output + end + + def test_migration_is_ignored_as_identical_with_skip_option + run_generator ["Account"] + output = run_generator ["Account", "--skip"] + assert_match %r{identical\s+db/migrate/\d+_create_accounts.rb}, output + end + + def test_migration_is_skipped_on_skip_behavior run_generator - error = capture(:stderr){ run_generator ["Account"], :behavior => :skip } - assert_match /Another migration is already named create_accounts/, error + output = run_generator ["Account"], :behavior => :skip + assert_match %r{skip\s+db/migrate/\d+_create_accounts.rb}, output end def test_migration_error_is_not_shown_on_revoke @@ -159,6 +173,15 @@ class ModelGeneratorTest < Rails::Generators::TestCase assert_no_migration "db/migrate/create_accounts.rb" end + def test_existing_migration_is_removed_on_force + run_generator + old_migration = Dir["#{destination_root}/db/migrate/*_create_accounts.rb"].first + error = capture(:stderr) { run_generator ["Account", "--force"] } + assert_no_match /Another migration is already named create_accounts/, error + assert_no_file old_migration + assert_migration 'db/migrate/create_accounts.rb' + end + def test_invokes_default_test_framework run_generator assert_file "test/unit/account_test.rb", /class AccountTest < ActiveSupport::TestCase/ @@ -180,4 +203,45 @@ class ModelGeneratorTest < Rails::Generators::TestCase content = capture(:stderr){ run_generator ["object"] } assert_match /The name 'Object' is either already used in your application or reserved/, content end + + def test_index_is_added_for_belongs_to_association + run_generator ["account", "supplier:belongs_to"] + + assert_migration "db/migrate/create_accounts.rb" do |m| + assert_method :change, m do |up| + assert_match /add_index/, up + end + end + end + + def test_index_is_added_for_references_association + run_generator ["account", "supplier:references"] + + assert_migration "db/migrate/create_accounts.rb" do |m| + assert_method :change, m do |up| + assert_match /add_index/, up + end + end + end + + def test_index_is_skipped_for_belongs_to_association + run_generator ["account", "supplier:belongs_to", "--no-indexes"] + + assert_migration "db/migrate/create_accounts.rb" do |m| + assert_method :change, m do |up| + assert_no_match /add_index/, up + end + end + end + + def test_index_is_skipped_for_references_association + run_generator ["account", "supplier:references", "--no-indexes"] + + assert_migration "db/migrate/create_accounts.rb" do |m| + assert_method :change, m do |up| + assert_no_match /add_index/, up + end + end + end + end diff --git a/railties/test/generators/named_base_test.rb b/railties/test/generators/named_base_test.rb index 1badae0713..f23701e99e 100644 --- a/railties/test/generators/named_base_test.rb +++ b/railties/test/generators/named_base_test.rb @@ -98,6 +98,11 @@ class NamedBaseTest < Rails::Generators::TestCase assert_name g, 'posts', :index_helper end + def test_index_helper_to_pluralize_once + g = generator ['Stadium'] + assert_name g, 'stadia', :index_helper + end + def test_index_helper_with_uncountable g = generator ['Sheep'] assert_name g, 'sheep_index', :index_helper diff --git a/railties/test/generators/namespaced_generators_test.rb b/railties/test/generators/namespaced_generators_test.rb new file mode 100644 index 0000000000..d61a02d32f --- /dev/null +++ b/railties/test/generators/namespaced_generators_test.rb @@ -0,0 +1,357 @@ +require 'generators/generators_test_helper' +require 'rails/generators/rails/controller/controller_generator' +require 'rails/generators/rails/model/model_generator' +require 'rails/generators/rails/observer/observer_generator' +require 'rails/generators/mailer/mailer_generator' +require 'rails/generators/rails/scaffold/scaffold_generator' + +class NamespacedGeneratorTestCase < Rails::Generators::TestCase + def setup + TestApp::Application.isolate_namespace(TestApp) + end + + def teardown + if TestApp.respond_to?(:_railtie) + TestApp.singleton_class.send(:undef_method, :_railtie) + TestApp.singleton_class.send(:undef_method, :table_name_prefix) + TestApp::Application.isolated = false + end + end +end + +class NamespacedControllerGeneratorTest < NamespacedGeneratorTestCase + include GeneratorsTestHelper + arguments %w(Account foo bar) + tests Rails::Generators::ControllerGenerator + + setup :copy_routes + + 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/ + end + + def test_skipping_namespace + run_generator ["Account", "--skip-namespace"] + assert_file "app/controllers/account_controller.rb", /class AccountController < ApplicationController/ + assert_file "app/helpers/account_helper.rb", /module AccountHelper/ + end + + 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/ + end + + def test_helpr_is_also_namespaced + run_generator + assert_file "app/helpers/test_app/account_helper.rb", /module TestApp/, / module AccountHelper/ + assert_file "test/unit/helpers/test_app/account_helper_test.rb", /module TestApp/, / class AccountHelperTest/ + end + + def test_invokes_default_test_framework + run_generator + assert_file "test/functional/test_app/account_controller_test.rb" + end + + def test_invokes_default_template_engine + run_generator + assert_file "app/views/test_app/account/foo.html.erb", %r(app/views/test_app/account/foo\.html\.erb) + assert_file "app/views/test_app/account/bar.html.erb", %r(app/views/test_app/account/bar\.html\.erb) + end + + def test_routes_should_not_be_namespaced + 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 +end + +class NamespacedModelGeneratorTest < NamespacedGeneratorTestCase + include GeneratorsTestHelper + arguments %w(Account name:string age:integer) + tests Rails::Generators::ModelGenerator + + def test_module_file_is_not_created + run_generator + assert_no_file "app/models/test_app.rb" + end + + def test_adds_namespace_to_model + run_generator + assert_file "app/models/test_app/account.rb", /module TestApp/, / class Account < ActiveRecord::Base/ + end + + def test_model_with_namespace + 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/account.rb", /module TestApp/, /class Admin::Account < ActiveRecord::Base/ + end + + def test_migration + run_generator + assert_migration "db/migrate/create_test_app_accounts.rb", /create_table :test_app_accounts/, /class CreateTestAppAccounts < ActiveRecord::Migration/ + end + + def test_migration_with_namespace + run_generator ["Gallery::Image"] + assert_migration "db/migrate/create_test_app_gallery_images", /class CreateTestAppGalleryImages < ActiveRecord::Migration/ + assert_no_migration "db/migrate/create_test_app_images" + end + + def test_migration_with_nested_namespace + run_generator ["Admin::Gallery::Image"] + assert_no_migration "db/migrate/create_images" + assert_no_migration "db/migrate/create_gallery_images" + assert_migration "db/migrate/create_test_app_admin_gallery_images", /class CreateTestAppAdminGalleryImages < ActiveRecord::Migration/ + assert_migration "db/migrate/create_test_app_admin_gallery_images", /create_table :test_app_admin_gallery_images/ + end + + def test_migration_with_nested_namespace_without_pluralization + ActiveRecord::Base.pluralize_table_names = false + run_generator ["Admin::Gallery::Image"] + assert_no_migration "db/migrate/create_images" + assert_no_migration "db/migrate/create_gallery_images" + assert_no_migration "db/migrate/create_test_app_admin_gallery_images" + assert_migration "db/migrate/create_test_app_admin_gallery_image", /class CreateTestAppAdminGalleryImage < ActiveRecord::Migration/ + assert_migration "db/migrate/create_test_app_admin_gallery_image", /create_table :test_app_admin_gallery_image/ + ensure + ActiveRecord::Base.pluralize_table_names = true + end + + def test_invokes_default_test_framework + run_generator + assert_file "test/unit/test_app/account_test.rb", /module TestApp/, /class AccountTest < ActiveSupport::TestCase/ + assert_file "test/fixtures/test_app/accounts.yml", /name: MyString/, /age: 1/ + end +end + +class NamespacedObserverGeneratorTest < NamespacedGeneratorTestCase + include GeneratorsTestHelper + arguments %w(account) + tests Rails::Generators::ObserverGenerator + + def test_invokes_default_orm + run_generator + assert_file "app/models/test_app/account_observer.rb", /module TestApp/, / class AccountObserver < ActiveRecord::Observer/ + end + + def test_invokes_default_orm_with_class_path + run_generator ["admin/account"] + assert_file "app/models/test_app/admin/account_observer.rb", /module TestApp/, / class Admin::AccountObserver < ActiveRecord::Observer/ + end + + def test_invokes_default_test_framework + run_generator + assert_file "test/unit/test_app/account_observer_test.rb", /module TestApp/, / class AccountObserverTest < ActiveSupport::TestCase/ + end +end + +class NamespacedMailerGeneratorTest < NamespacedGeneratorTestCase + include GeneratorsTestHelper + arguments %w(notifier foo bar) + tests Rails::Generators::MailerGenerator + + def test_mailer_skeleton_is_created + run_generator + assert_file "app/mailers/test_app/notifier.rb" do |mailer| + assert_match /module TestApp/, mailer + assert_match /class Notifier < ActionMailer::Base/, mailer + assert_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 + end + end + + def test_invokes_default_test_framework + run_generator + assert_file "test/functional/test_app/notifier_test.rb" do |test| + assert_match /module TestApp/, test + assert_match /class NotifierTest < ActionMailer::TestCase/, test + assert_match /test "foo"/, test + assert_match /test "bar"/, test + end + end + + def test_invokes_default_template_engine + run_generator + assert_file "app/views/test_app/notifier/foo.text.erb" do |view| + assert_match %r(app/views/test_app/notifier/foo\.text\.erb), view + assert_match /<%= @greeting %>/, view + end + + assert_file "app/views/test_app/notifier/bar.text.erb" do |view| + assert_match %r(app/views/test_app/notifier/bar\.text\.erb), view + assert_match /<%= @greeting %>/, view + end + end + + def test_invokes_default_template_engine_even_with_no_action + run_generator ["notifier"] + assert_file "app/views/test_app/notifier" + end +end + +class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase + include GeneratorsTestHelper + arguments %w(product_line title:string price:integer) + tests Rails::Generators::ScaffoldGenerator + + setup :copy_routes + + def test_scaffold_on_invoke + run_generator + + # Model + assert_file "app/models/test_app/product_line.rb", /module TestApp\n class ProductLine < ActiveRecord::Base/ + assert_file "test/unit/test_app/product_line_test.rb", /module TestApp\n class ProductLineTest < ActiveSupport::TestCase/ + assert_file "test/fixtures/test_app/product_lines.yml" + assert_migration "db/migrate/create_test_app_product_lines.rb" + + # Route + assert_file "config/routes.rb" do |route| + assert_match(/resources :product_lines$/, route) + 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 "test/functional/test_app/product_lines_controller_test.rb", + /module TestApp\n class ProductLinesControllerTest < ActionController::TestCase/ + + # Views + %w( + index + edit + new + show + _form + ).each { |view| assert_file "app/views/test_app/product_lines/#{view}.html.erb" } + assert_no_file "app/views/layouts/test_app/product_lines.html.erb" + + # Helpers + assert_file "app/helpers/test_app/product_lines_helper.rb" + assert_file "test/unit/helpers/test_app/product_lines_helper_test.rb" + + # Stylesheets + assert_file "public/stylesheets/scaffold.css" + end + + def test_scaffold_on_revoke + run_generator + run_generator ["product_line"], :behavior => :revoke + + # Model + assert_no_file "app/models/test_app/product_line.rb" + assert_no_file "test/unit/test_app/product_line_test.rb" + assert_no_file "test/fixtures/test_app/product_lines.yml" + assert_no_migration "db/migrate/create_test_app_product_lines.rb" + + # Route + assert_file "config/routes.rb" do |route| + assert_no_match(/resources :product_lines$/, route) + end + + # Controller + assert_no_file "app/controllers/test_app/product_lines_controller.rb" + assert_no_file "test/functional/test_app/product_lines_controller_test.rb" + + # Views + assert_no_file "app/views/test_app/product_lines" + assert_no_file "app/views/test_app/layouts/product_lines.html.erb" + + # Helpers + assert_no_file "app/helpers/test_app/product_lines_helper.rb" + assert_no_file "test/unit/helpers/test_app/product_lines_helper_test.rb" + + # Stylesheets (should not be removed) + assert_file "public/stylesheets/scaffold.css" + end + + def test_scaffold_with_namespace_on_invoke + run_generator [ "admin/role", "name:string", "description:string" ] + + # Model + assert_file "app/models/test_app/admin.rb", /module TestApp\n module Admin/ + assert_file "app/models/test_app/admin/role.rb", /module TestApp\n class Admin::Role < ActiveRecord::Base/ + assert_file "test/unit/test_app/admin/role_test.rb", /module TestApp\n class Admin::RoleTest < ActiveSupport::TestCase/ + assert_file "test/fixtures/test_app/admin/roles.yml" + assert_migration "db/migrate/create_test_app_admin_roles.rb" + + # Route + assert_file "config/routes.rb" do |route| + assert_match(/namespace :admin do resources :roles end$/, route) + end + + # Controller + assert_file "app/controllers/test_app/admin/roles_controller.rb" do |content| + assert_match(/module TestApp\n class Admin::RolesController < ApplicationController/, content) + end + + assert_file "test/functional/test_app/admin/roles_controller_test.rb", + /module TestApp\n class Admin::RolesControllerTest < ActionController::TestCase/ + + # Views + %w( + index + edit + new + show + _form + ).each { |view| assert_file "app/views/test_app/admin/roles/#{view}.html.erb" } + assert_no_file "app/views/layouts/admin/roles.html.erb" + + # Helpers + assert_file "app/helpers/test_app/admin/roles_helper.rb" + assert_file "test/unit/helpers/test_app/admin/roles_helper_test.rb" + + # Stylesheets + assert_file "public/stylesheets/scaffold.css" + end + + def test_scaffold_with_namespace_on_revoke + run_generator [ "admin/role", "name:string", "description:string" ] + run_generator [ "admin/role" ], :behavior => :revoke + + # Model + assert_file "app/models/test_app/admin.rb" # ( should not be remove ) + assert_no_file "app/models/test_app/admin/role.rb" + assert_no_file "test/unit/test_app/admin/role_test.rb" + assert_no_file "test/fixtures/test_app/admin/roles.yml" + assert_no_migration "db/migrate/create_test_app_admin_roles.rb" + + # Route + assert_file "config/routes.rb" do |route| + assert_no_match(/namespace :admin do resources :roles end$/, route) + end + + # Controller + assert_no_file "app/controllers/test_app/admin/roles_controller.rb" + assert_no_file "test/functional/test_app/admin/roles_controller_test.rb" + + # Views + assert_no_file "app/views/test_app/admin/roles" + assert_no_file "app/views/layouts/test_app/admin/roles.html.erb" + + # Helpers + assert_no_file "app/helpers/test_app/admin/roles_helper.rb" + assert_no_file "test/unit/helpers/test_app/admin/roles_helper_test.rb" + + # Stylesheets (should not be removed) + assert_file "public/stylesheets/scaffold.css" + end +end diff --git a/railties/test/generators/plugin_generator_test.rb b/railties/test/generators/plugin_generator_test.rb index c1f646f7c1..e6686a6af4 100644 --- a/railties/test/generators/plugin_generator_test.rb +++ b/railties/test/generators/plugin_generator_test.rb @@ -6,7 +6,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase arguments %w(plugin_fu) def test_plugin_skeleton_is_created - run_generator + silence(:stderr) { run_generator } year = Date.today.year %w( @@ -36,30 +36,36 @@ class PluginGeneratorTest < Rails::Generators::TestCase end def test_invokes_default_test_framework - run_generator + silence(:stderr) { run_generator } assert_file "vendor/plugins/plugin_fu/test/plugin_fu_test.rb", /class PluginFuTest < ActiveSupport::TestCase/ assert_file "vendor/plugins/plugin_fu/test/test_helper.rb" end def test_logs_if_the_test_framework_cannot_be_found - content = run_generator ["plugin_fu", "--test-framework=rspec"] + content = nil + silence(:stderr) { content = run_generator ["plugin_fu", "--test-framework=rspec"] } assert_match /rspec \[not found\]/, content end def test_creates_tasks_if_required - run_generator ["plugin_fu", "--tasks"] + silence(:stderr) { run_generator ["plugin_fu", "--tasks"] } assert_file "vendor/plugins/plugin_fu/lib/tasks/plugin_fu_tasks.rake" end def test_creates_generator_if_required - run_generator ["plugin_fu", "--generator"] + silence(:stderr) { run_generator ["plugin_fu", "--generator"] } assert_file "vendor/plugins/plugin_fu/lib/generators/templates" assert_file "vendor/plugins/plugin_fu/lib/generators/plugin_fu_generator.rb", /class PluginFuGenerator < Rails::Generators::NamedBase/ end def test_plugin_generator_on_revoke - run_generator + silence(:stderr) { run_generator } run_generator ["plugin_fu"], :behavior => :revoke end + + def test_deprecation + output = capture(:stderr) { run_generator } + assert_match /Plugin generator is deprecated, please use 'rails plugin new' command to generate plugin structure./, output + end end diff --git a/railties/test/generators/plugin_new_generator_test.rb b/railties/test/generators/plugin_new_generator_test.rb new file mode 100644 index 0000000000..3c11c8dbaf --- /dev/null +++ b/railties/test/generators/plugin_new_generator_test.rb @@ -0,0 +1,229 @@ +require 'abstract_unit' +require 'generators/generators_test_helper' +require 'rails/generators/rails/plugin_new/plugin_new_generator' +require 'generators/shared_generator_tests.rb' + +DEFAULT_PLUGIN_FILES = %w( + .gitignore + Gemfile + Rakefile + bukkits.gemspec + MIT-LICENSE + lib + lib/bukkits.rb + lib/tasks/bukkits_tasks.rake + script/rails + test/bukkits_test.rb + test/test_helper.rb + test/dummy +) + +class PluginNewGeneratorTest < Rails::Generators::TestCase + include GeneratorsTestHelper + destination File.join(Rails.root, "tmp/bukkits") + arguments [destination_root] + include SharedGeneratorTests + + def default_files + ::DEFAULT_PLUGIN_FILES + end + + def test_invalid_plugin_name_raises_an_error + content = capture(:stderr){ run_generator [File.join(destination_root, "43-things")] } + assert_equal "Invalid plugin name 43-things. Please give a name which does not start with numbers.\n", content + end + + def test_invalid_plugin_name_is_fixed + run_generator [File.join(destination_root, "things-43")] + assert_file "things-43/lib/things-43.rb", /module Things43/ + end + + def test_generating_without_options + run_generator + assert_file "README.rdoc", /Bukkits/ + assert_no_file "config/routes.rb" + assert_file "test/test_helper.rb" + assert_file "test/bukkits_test.rb", /assert_kind_of Module, Bukkits/ + end + + def test_generating_test_files_in_full_mode + run_generator [destination_root, "--full"] + assert_directory "test/integration/" + + assert_file "test/integration/navigation_test.rb", /ActionDispatch::IntegrationTest/ + 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"])) + end + + def test_ensure_that_test_dummy_can_be_generated_from_a_template + FileUtils.cd(Rails.root) + run_generator([destination_root, "-m", "lib/create_test_dummy_template.rb", "--skip-test-unit"]) + assert_file "spec/dummy" + assert_no_file "test" + end + + def test_database_entry_is_assed_by_default_in_full_mode + run_generator([destination_root, "--full"]) + assert_file "test/dummy/config/database.yml", /sqlite/ + assert_file "Gemfile", /^gem\s+["']sqlite3["']$/ + end + + def test_config_another_database + run_generator([destination_root, "-d", "mysql", "--full"]) + assert_file "test/dummy/config/database.yml", /mysql/ + assert_file "Gemfile", /^gem\s+["']mysql2["']$/ + 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["']/ + end + + def test_ensure_that_skip_active_record_option_is_passed_to_app_generator + run_generator [destination_root, "--skip_active_record"] + assert_no_file "test/dummy/config/database.yml" + assert_no_match(/ActiveRecord/, File.read(File.join(destination_root, "test/test_helper.rb"))) + 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/ + end + + def test_skipping_javascripts_without_mountable_option + run_generator + assert_no_file "public/javascripts/prototype.js" + assert_no_file "public/javascripts/rails.js" + assert_no_file "public/javascripts/controls.js" + assert_no_file "public/javascripts/dragdrop.js" + assert_no_file "public/javascripts/dragdrop.js" + assert_no_file "public/javascripts/application.js" + end + + def test_javascripts_generation + run_generator [destination_root, "--mountable"] + assert_file "public/javascripts/rails.js" + assert_file "public/javascripts/prototype.js" + assert_file "public/javascripts/controls.js" + assert_file "public/javascripts/dragdrop.js" + assert_file "public/javascripts/dragdrop.js" + assert_file "public/javascripts/application.js" + end + + def test_skip_javascripts + run_generator [destination_root, "--skip-javascript", "--mountable"] + assert_no_file "public/javascripts/prototype.js" + assert_no_file "public/javascripts/rails.js" + assert_no_file "public/javascripts/controls.js" + assert_no_file "public/javascripts/dragdrop.js" + assert_no_file "public/javascripts/dragdrop.js" + end + + def test_ensure_that_javascript_option_is_passed_to_app_generator + run_generator [destination_root, "--javascript", "jquery"] + assert_file "test/dummy/public/javascripts/jquery.js" + end + + def test_ensure_that_skip_javascript_option_is_passed_to_app_generator + run_generator [destination_root, "--skip_javascript"] + assert_no_file "test/dummy/public/javascripts/prototype.js" + end + + def test_template_from_dir_pwd + FileUtils.cd(Rails.root) + assert_match(/It works from file!/, run_generator([destination_root, "-m", "lib/template.rb"])) + end + + def test_ensure_that_tests_works + run_generator + FileUtils.cd destination_root + `bundle install` + assert_match(/1 tests, 1 assertions, 0 failures, 0 errors/, `bundle exec rake test`) + end + + def test_ensure_that_tests_works_in_full_mode + run_generator [destination_root, "--full", "--skip_active_record"] + FileUtils.cd destination_root + `bundle install` + assert_match(/2 tests, 2 assertions, 0 failures, 0 errors/, `bundle exec rake test`) + end + + def test_creating_engine_in_full_mode + run_generator [destination_root, "--full"] + assert_file "config/routes.rb", /Rails.application.routes.draw do/ + assert_file "lib/bukkits/engine.rb", /module Bukkits\n class Engine < Rails::Engine\n end\nend/ + assert_file "lib/bukkits.rb", /require "bukkits\/engine"/ + end + + def test_being_quiet_while_creating_dummy_application + assert_no_match(/create\s+config\/application.rb/, run_generator) + end + + def test_create_mountable_application_with_mountable_option + run_generator [destination_root, "--mountable"] + assert_file "config/routes.rb", /Bukkits::Engine.routes.draw do/ + assert_file "lib/bukkits/engine.rb", /isolate_namespace Bukkits/ + assert_file "test/dummy/config/routes.rb", /mount Bukkits::Engine => "\/bukkits"/ + assert_file "app/controllers/bukkits/application_controller.rb", /module Bukkits\n class ApplicationController < ActionController::Base/ + assert_file "app/helpers/bukkits/application_helper.rb", /module Bukkits\n module ApplicationHelper/ + assert_file "app/views/layouts/bukkits/application.html.erb", /<title>Bukkits<\/title>/ + end + + def test_passing_dummy_path_as_a_parameter + run_generator [destination_root, "--dummy_path", "spec/dummy"] + assert_file "spec/dummy" + assert_file "spec/dummy/config/application.rb" + assert_no_file "test/dummy" + end + + def test_skipping_gemspec + run_generator [destination_root, "--skip-gemspec"] + assert_no_file "bukkits.gemspec" + end + +protected + + def action(*args, &block) + silence(:stdout){ generator.send(*args, &block) } + end + +end + +class CustomPluginGeneratorTest < Rails::Generators::TestCase + include GeneratorsTestHelper + tests Rails::Generators::PluginNewGenerator + + destination File.join(Rails.root, "tmp/bukkits") + arguments [destination_root] + include SharedCustomGeneratorTests + + def test_overriding_test_framework + FileUtils.cd(destination_root) + run_generator([destination_root, "-b", "#{Rails.root}/lib/plugin_builders/spec_builder.rb"]) + assert_file 'spec/spec_helper.rb' + assert_file 'spec/dummy' + assert_file 'Rakefile', /task :default => :spec/ + assert_file 'Rakefile', /# spec tasks in rakefile/ + assert_file 'script/rails', %r{spec/dummy} + end + +protected + def default_files + ::DEFAULT_PLUGIN_FILES + end + + def builder_class + :PluginBuilder + end + + def builders_dir + "plugin_builders" + end + + def action(*args, &block) + silence(:stdout){ generator.send(*args, &block) } + end +end diff --git a/railties/test/generators/resource_generator_test.rb b/railties/test/generators/resource_generator_test.rb index 55d5bd6f83..71b3619351 100644 --- a/railties/test/generators/resource_generator_test.rb +++ b/railties/test/generators/resource_generator_test.rb @@ -73,6 +73,11 @@ class ResourceGeneratorTest < Rails::Generators::TestCase assert_no_match /Plural version of the model detected/, 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 + end + def test_route_is_removed_on_revoke run_generator run_generator ["account"], :behavior => :revoke diff --git a/railties/test/generators/scaffold_generator_test.rb b/railties/test/generators/scaffold_generator_test.rb index f12445ae35..df787f61ba 100644 --- a/railties/test/generators/scaffold_generator_test.rb +++ b/railties/test/generators/scaffold_generator_test.rb @@ -3,7 +3,7 @@ require 'rails/generators/rails/scaffold/scaffold_generator' class ScaffoldGeneratorTest < Rails::Generators::TestCase include GeneratorsTestHelper - arguments %w(product_line title:string price:integer) + arguments %w(product_line title:string product:belongs_to user:references) setup :copy_routes @@ -14,48 +14,51 @@ 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" + 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/ # Route assert_file "config/routes.rb" do |route| - assert_match /resources :product_lines$/, route + assert_match(/resources :product_lines$/, route) end # Controller assert_file "app/controllers/product_lines_controller.rb" do |content| - assert_match /class ProductLinesController < ApplicationController/, content + assert_match(/class ProductLinesController < ApplicationController/, content) assert_instance_method :index, content do |m| - assert_match /@product_lines = ProductLine\.all/, m + assert_match(/@product_lines = ProductLine\.all/, m) end assert_instance_method :show, content do |m| - assert_match /@product_line = ProductLine\.find\(params\[:id\]\)/, m + assert_match(/@product_line = ProductLine\.find\(params\[:id\]\)/, m) end assert_instance_method :new, content do |m| - assert_match /@product_line = ProductLine\.new/, m + assert_match(/@product_line = ProductLine\.new/, m) end assert_instance_method :edit, content do |m| - assert_match /@product_line = ProductLine\.find\(params\[:id\]\)/, m + assert_match(/@product_line = ProductLine\.find\(params\[:id\]\)/, m) end assert_instance_method :create, content do |m| - assert_match /@product_line = ProductLine\.new\(params\[:product_line\]\)/, m - assert_match /@product_line\.save/, m - assert_match /@product_line\.errors/, m + assert_match(/@product_line = ProductLine\.new\(params\[:product_line\]\)/, m) + assert_match(/@product_line\.save/, m) + assert_match(/@product_line\.errors/, m) end assert_instance_method :update, content do |m| - assert_match /@product_line = ProductLine\.find\(params\[:id\]\)/, m - assert_match /@product_line\.update_attributes\(params\[:product_line\]\)/, m - assert_match /@product_line\.errors/, m + assert_match(/@product_line = ProductLine\.find\(params\[:id\]\)/, m) + assert_match(/@product_line\.update_attributes\(params\[:product_line\]\)/, m) + assert_match(/@product_line\.errors/, m) end assert_instance_method :destroy, content do |m| - assert_match /@product_line = ProductLine\.find\(params\[:id\]\)/, m - assert_match /@product_line\.destroy/, m + assert_match(/@product_line = ProductLine\.find\(params\[:id\]\)/, m) + assert_match(/@product_line\.destroy/, m) end end @@ -92,7 +95,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase # Route assert_file "config/routes.rb" do |route| - assert_no_match /resources :product_lines$/, route + assert_no_match(/resources :product_lines$/, route) end # Controller @@ -123,44 +126,44 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase # Route assert_file "config/routes.rb" do |route| - assert_match /namespace :admin do resources :roles end$/, route + assert_match(/namespace :admin do resources :roles end$/, route) end # Controller assert_file "app/controllers/admin/roles_controller.rb" do |content| - assert_match /class Admin::RolesController < ApplicationController/, content + assert_match(/class Admin::RolesController < ApplicationController/, content) assert_instance_method :index, content do |m| - assert_match /@admin_roles = Admin::Role\.all/, m + assert_match(/@admin_roles = Admin::Role\.all/, m) end assert_instance_method :show, content do |m| - assert_match /@admin_role = Admin::Role\.find\(params\[:id\]\)/, m + assert_match(/@admin_role = Admin::Role\.find\(params\[:id\]\)/, m) end assert_instance_method :new, content do |m| - assert_match /@admin_role = Admin::Role\.new/, m + assert_match(/@admin_role = Admin::Role\.new/, m) end assert_instance_method :edit, content do |m| - assert_match /@admin_role = Admin::Role\.find\(params\[:id\]\)/, m + assert_match(/@admin_role = Admin::Role\.find\(params\[:id\]\)/, m) end assert_instance_method :create, content do |m| - assert_match /@admin_role = Admin::Role\.new\(params\[:admin_role\]\)/, m - assert_match /@admin_role\.save/, m - assert_match /@admin_role\.errors/, m + assert_match(/@admin_role = Admin::Role\.new\(params\[:admin_role\]\)/, m) + assert_match(/@admin_role\.save/, m) + assert_match(/@admin_role\.errors/, m) end assert_instance_method :update, content do |m| - assert_match /@admin_role = Admin::Role\.find\(params\[:id\]\)/, m - assert_match /@admin_role\.update_attributes\(params\[:admin_role\]\)/, m - assert_match /@admin_role\.errors/, m + assert_match(/@admin_role = Admin::Role\.find\(params\[:id\]\)/, m) + assert_match(/@admin_role\.update_attributes\(params\[:admin_role\]\)/, m) + assert_match(/@admin_role\.errors/, m) end assert_instance_method :destroy, content do |m| - assert_match /@admin_role = Admin::Role\.find\(params\[:id\]\)/, m - assert_match /@admin_role\.destroy/, m + assert_match(/@admin_role = Admin::Role\.find\(params\[:id\]\)/, m) + assert_match(/@admin_role\.destroy/, m) end end @@ -198,7 +201,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase # Route assert_file "config/routes.rb" do |route| - assert_no_match /namespace :admin do resources :roles end$/, route + assert_no_match(/namespace :admin do resources :roles end$/, route) end # Controller @@ -231,4 +234,10 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase assert_file "config/routes.rb", /\.routes\.draw do\s*\|map\|\s*$/ end + + def test_scaffold_generator_outputs_error_message_on_missing_attribute_type + content = capture(:stderr) { run_generator ["post", "title:string", "body"]} + assert_match(/Missing type for attribute 'body'/, content) + assert_match(/Example: 'body:string' where string is the type/, content) + end end diff --git a/railties/test/generators/shared_generator_tests.rb b/railties/test/generators/shared_generator_tests.rb new file mode 100644 index 0000000000..c9c5d2fad2 --- /dev/null +++ b/railties/test/generators/shared_generator_tests.rb @@ -0,0 +1,195 @@ +module SharedGeneratorTests + def setup + Rails.application = TestApp::Application + super + Rails::Generators::AppGenerator.instance_variable_set('@desc', nil) + @bundle_command = File.basename(Thor::Util.ruby_command).sub(/ruby/, 'bundle') + + Kernel::silence_warnings do + Thor::Base.shell.send(:attr_accessor, :always_force) + @shell = Thor::Base.shell.new + @shell.send(:always_force=, true) + end + end + + def teardown + super + Rails::Generators::AppGenerator.instance_variable_set('@desc', nil) + Rails.application = TestApp::Application.instance + end + + def test_skeleton_is_created + run_generator + + default_files.each{ |path| assert_file path } + end + + def test_plugin_new_generate_pretend + run_generator ["testapp", "--pretend"] + default_files.each{ |path| assert_no_file File.join("testapp",path) } + end + + def test_invalid_database_option_raises_an_error + content = capture(:stderr){ run_generator([destination_root, "-d", "unknown"]) } + assert_match(/Invalid value for \-\-database option/, content) + end + + def test_test_unit_is_skipped_if_required + run_generator [destination_root, "--skip-test-unit"] + assert_no_file "test" + end + + def test_options_before_application_name_raises_an_error + content = capture(:stderr){ run_generator(["--pretend", destination_root]) } + assert_match(/Options should be given after the \w+ name. For details run: rails( plugin)? --help\n/, content) + end + + def test_name_collision_raises_an_error + reserved_words = %w[application destroy plugin runner test] + reserved_words.each do |reserved| + content = capture(:stderr){ run_generator [File.join(destination_root, reserved)] } + assert_match(/Invalid \w+ name #{reserved}. Please give a name which does not match one of the reserved rails words.\n/, content) + end + end + + def test_name_raises_an_error_if_name_already_used_constant + %w{ String Hash Class Module Set Symbol }.each do |ruby_class| + content = capture(:stderr){ run_generator [File.join(destination_root, ruby_class)] } + assert_match(/Invalid \w+ name #{ruby_class}, constant #{ruby_class} is already in use. Please choose another \w+ name.\n/, content) + end + end + + def test_shebang_is_added_to_rails_file + run_generator [destination_root, "--ruby", "foo/bar/baz"] + assert_file "script/rails", /#!foo\/bar\/baz/ + end + + def test_shebang_when_is_the_same_as_default_use_env + run_generator [destination_root, "--ruby", Thor::Util.ruby_command] + assert_file "script/rails", /#!\/usr\/bin\/env/ + 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!/, silence(:stdout){ generator.invoke_all }) + end + + def test_dev_option + generator([destination_root], :dev => true).expects(:run).with("#{@bundle_command} install") + silence(:stdout){ generator.invoke_all } + rails_path = File.expand_path('../../..', Rails.root) + assert_file 'Gemfile', /^gem\s+["']rails["'],\s+:path\s+=>\s+["']#{Regexp.escape(rails_path)}["']$/ + end + + def test_edge_option + generator([destination_root], :edge => true).expects(:run).with("#{@bundle_command} install") + silence(:stdout){ generator.invoke_all } + assert_file 'Gemfile', %r{^gem\s+["']rails["'],\s+:git\s+=>\s+["']#{Regexp.escape("git://github.com/rails/rails.git")}["']$} + 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!/, silence(: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!" } + 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!/, silence(:stdout){ generator.invoke_all }) + end + + def test_dev_option + generator([destination_root], :dev => true).expects(:run).with("#{@bundle_command} install") + silence(:stdout){ generator.invoke_all } + rails_path = File.expand_path('../../..', Rails.root) + assert_file 'Gemfile', /^gem\s+["']rails["'],\s+:path\s+=>\s+["']#{Regexp.escape(rails_path)}["']$/ + end + + def test_edge_option + generator([destination_root], :edge => true).expects(:run).with("#{@bundle_command} install") + silence(:stdout){ generator.invoke_all } + assert_file 'Gemfile', %r{^gem\s+["']rails["'],\s+:git\s+=>\s+["']#{Regexp.escape("git://github.com/rails/rails.git")}["']$} + end +end + +module SharedCustomGeneratorTests + def setup + Rails.application = TestApp::Application + super + Rails::Generators::AppGenerator.instance_variable_set('@desc', nil) + @bundle_command = File.basename(Thor::Util.ruby_command).sub(/ruby/, 'bundle') + end + + def teardown + super + Rails::Generators::AppGenerator.instance_variable_set('@desc', nil) + Object.class_eval do + remove_const :AppBuilder if const_defined?(:AppBuilder) + remove_const :PluginBuilder if const_defined?(:PluginBuilder) + end + Rails.application = TestApp::Application.instance + end + + def test_builder_option_with_empty_app_builder + FileUtils.cd(destination_root) + run_generator([destination_root, "-b", "#{Rails.root}/lib/#{builders_dir}/empty_builder.rb"]) + default_files.each{ |path| assert_no_file path } + end + + def test_builder_option_with_simple_plugin_builder + FileUtils.cd(destination_root) + run_generator([destination_root, "-b", "#{Rails.root}/lib/#{builders_dir}/simple_builder.rb"]) + (default_files - ['.gitignore']).each{ |path| assert_no_file path } + assert_file ".gitignore", "foobar" + end + + def test_builder_option_with_relative_path + here = File.expand_path(File.dirname(__FILE__)) + FileUtils.cd(here) + run_generator([destination_root, "-b", "../fixtures/lib/#{builders_dir}/simple_builder.rb"]) + FileUtils.cd(destination_root) + (default_files - ['.gitignore']).each{ |path| assert_no_file path } + assert_file ".gitignore", "foobar" + end + + def test_builder_option_with_tweak_plugin_builder + FileUtils.cd(destination_root) + run_generator([destination_root, "-b", "#{Rails.root}/lib/#{builders_dir}/tweak_builder.rb"]) + default_files.each{ |path| assert_file path } + assert_file ".gitignore", "foobar" + end + + def test_builder_option_with_http + path = "http://gist.github.com/103208.txt" + template = "class #{builder_class}; end" + template.instance_eval "def read; self; end" # Make the string respond to read + + generator([destination_root], :builder => path).expects(:open).with(path, 'Accept' => 'application/x-thor-template').returns(template) + capture(:stdout) { generator.invoke_all } + + default_files.each{ |path| assert_no_file(path) } + end +end |