1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00
rails--rails/railties/test/generators/shared_generator_tests.rb

365 lines
13 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
#
# Tests, setup, and teardown common to the application and plugin generator suites.
#
module SharedGeneratorTests
def setup
Rails.application = TestApp::Application
super
Rails::Generators::AppGenerator.instance_variable_set("@desc", nil)
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 application_path
destination_root
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_files_are_skipped_if_required
run_generator [destination_root, "--skip-test"]
assert_no_file "test"
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: application, destroy, plugin, runner, test\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", "--full"]
assert_file "bin/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, "--full"]
assert_file "bin/rails", /#!\/usr\/bin\/env/
end
def test_template_raises_an_error_with_invalid_path
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_an_https_path
path = "https://gist.github.com/josevalim/103208/raw/"
template = %{ say "It works!" }.dup
template.instance_eval "def read; self; end" # Make the string respond to read
check_open = -> *args do
assert_equal [ path, "Accept" => "application/x-thor-template" ], args
template
end
generator([destination_root], template: path).stub(:open, check_open, template) do
quietly { assert_match(/It works!/, capture(:stdout) { generator.invoke_all }) }
end
end
def test_skip_gemfile
assert_not_called(generator([destination_root], skip_gemfile: true), :bundle_command) do
quietly { generator.invoke_all }
assert_no_file "Gemfile"
end
end
def test_skip_git
run_generator [destination_root, "--skip-git", "--full"]
assert_no_file(".gitignore")
assert_no_directory(".git")
end
def test_skip_keeps
run_generator [destination_root, "--skip-keeps", "--full"]
assert_file ".gitignore" do |content|
assert_no_match(/\.keep/, content)
end
assert_no_file("app/models/concerns/.keep")
end
def test_default_frameworks_are_required_when_others_are_removed
`rails new` runs `rails active_storage:install` Omit `rails activestorage:install` for jdbcmysql, jdbc and shebang tests AppGeneratorTest#test_config_jdbcmysql_database rails aborted! LoadError: Could not load 'active_record/connection_adapters/mysql_adapter'. Make sure that the adapter in config/database.yml is valid. If you use an adapter other than 'mysql2', 'postgresql' or 'sqlite3' add the necessary adapter gem to the Gemfile. (compressed) bin/rails:4:in `<main>' Tasks: TOP => activestorage:install => environment (See full trace by running task with --trace) AppGeneratorTest#test_config_jdbc_database rails aborted! LoadError: Could not load 'active_record/connection_adapters/jdbc_adapter'. Make sure that the adapter in config/database.yml is valid. If you use an adapter other than 'mysql2', 'postgresql' or 'sqlite3' add the necessary adapter gem to the Gemfile. (compressed) bin/rails:4:in `<main>' Tasks: TOP => activestorage:install => environment (See full trace by running task with --trace) AppGeneratorTest#test_shebang_is_added_to_rails_file /home/ubuntu/.rbenv/versions/2.4.1/bin/ruby: no Ruby script found in input (LoadError) Prevent PendingMigrationError in tests * Run `bin/rails db:migrate RAILS_ENV=test` in test_cases before start tests to prevent PendingMigrationError * FileUtils.rm_r("db/migrate") * --skip-active-storage Fix failed tests in `railties/test/railties/engine_test.rb` Related to #30111 Imporve `SharedGeneratorTests#test_default_frameworks_are_required_when_others_are_removed` - Explicitly skip active_storage - Ensure that skipped frameworks are commented - Ensure that default frameworks are not commented Fix error `Errno::ENOSPC: No space left on device - sendfile` Since `rails new` runs `rails active_storage:install` that boots an app. Since adding Bootsnap 0312a5c67e35b960e33677b5358c539f1047e4e1 during booting an app, it creates the cache: 264K tmp/cache/bootsnap-load-path-cache 27M tmp/cache/bootsnap-compile-cache * teardown_app must remove app
2017-08-07 00:31:14 -04:00
run_generator [
destination_root,
"--skip-active-record",
"--skip-active-storage",
"--skip-action-mailer",
"--skip-action-cable",
"--skip-sprockets"
]
assert_file "#{application_path}/config/application.rb", /^require\s+["']rails["']/
assert_file "#{application_path}/config/application.rb", /^require\s+["']active_model\/railtie["']/
assert_file "#{application_path}/config/application.rb", /^require\s+["']active_job\/railtie["']/
assert_file "#{application_path}/config/application.rb", /^# require\s+["']active_record\/railtie["']/
assert_file "#{application_path}/config/application.rb", /^# require\s+["']active_storage\/engine["']/
assert_file "#{application_path}/config/application.rb", /^require\s+["']action_controller\/railtie["']/
assert_file "#{application_path}/config/application.rb", /^# require\s+["']action_mailer\/railtie["']/
assert_file "#{application_path}/config/application.rb", /^require\s+["']action_view\/railtie["']/
assert_file "#{application_path}/config/application.rb", /^# require\s+["']action_cable\/engine["']/
assert_file "#{application_path}/config/application.rb", /^# require\s+["']sprockets\/railtie["']/
assert_file "#{application_path}/config/application.rb", /^require\s+["']rails\/test_unit\/railtie["']/
end
def test_generator_without_skips
run_generator
assert_file "#{application_path}/config/application.rb", /\s+require\s+["']rails\/all["']/
assert_file "#{application_path}/config/environments/development.rb" do |content|
assert_match(/config\.action_mailer\.raise_delivery_errors = false/, content)
end
assert_file "#{application_path}/config/environments/test.rb" do |content|
assert_match(/config\.action_mailer\.delivery_method = :test/, content)
end
assert_file "#{application_path}/config/environments/production.rb" do |content|
assert_match(/# config\.action_mailer\.raise_delivery_errors = false/, content)
Add credentials using a generic EncryptedConfiguration class (#30067) * WIP: Add credentials using a generic EncryptedConfiguration class This is sketch code so far. * Flesh out EncryptedConfiguration and test it * Better name * Add command and generator for credentials * Use the Pathnames * Extract EncryptedFile from EncryptedConfiguration and add serializers * Test EncryptedFile * Extract serializer validation * Stress the point about losing comments * Allow encrypted configuration to be read without parsing for display * Use credentials by default and base them on the master key * Derive secret_key_base in test/dev, source it from credentials in other envs And document the usage. * Document the new credentials setup * Stop generating the secrets.yml file now that we have credentials * Document what we should have instead Still need to make it happen, tho. * [ci skip] Keep wording to `key base`; prefer defaults. Usually we say we change defaults, not "spec" out a release. Can't use backticks in our sdoc generated documentation either. * Abstract away OpenSSL; prefer MessageEncryptor. * Spare needless new when raising. * Encrypted file test shouldn't depend on subclass. * [ci skip] Some woordings. * Ditch serializer future coding. * I said flip it. Flip it good. * [ci skip] Move require_master_key to the real production.rb. * Add require_master_key to abort the boot process. In case the master key is required in a certain environment we should inspect that the key is there and abort if it isn't. * Print missing key message and exit immediately. Spares us a lengthy backtrace and prevents further execution. I've verified the behavior in a test app, but couldn't figure the test out as loading the app just exits immediately with: ``` /Users/kasperhansen/Documents/code/rails/activesupport/lib/active_support/testing/isolation.rb:23:in `load': marshal data too short (ArgumentError) from /Users/kasperhansen/Documents/code/rails/activesupport/lib/active_support/testing/isolation.rb:23:in `run' from /Users/kasperhansen/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/minitest-5.10.2/lib/minitest.rb:830:in `run_one_method' from /Users/kasperhansen/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/minitest-5.10.2/lib/minitest/parallel.rb:32:in `block (2 levels) in start' ``` It's likely we need to capture and prevent the exit somehow. Kernel.stub(:exit) didn't work. Leaving it for tomorrow. * Fix require_master_key config test. Loading the app would trigger the `exit 1` per require_master_key's semantics, which then aborted the test. Fork and wait for the child process to finish, then inspect the exit status. Also check we aborted because of a missing master key, so something else didn't just abort the boot. Much <3 to @tenderlove for the tip. * Support reading/writing configs via methods. * Skip needless deep symbolizing. * Remove save; test config reader elsewhere. * Move secret_key_base check to when we're reading it. Otherwise we'll abort too soon since we don't assign the secret_key_base to secrets anymore. * Add missing string literal comments; require unneeded yaml require. * ya ya ya, rubocop. * Add master_key/credentials after bundle. Then we can reuse the existing message on `rails new bc4`. It'll look like: ``` Using web-console 3.5.1 from https://github.com/rails/web-console.git (at master@ce985eb) Using rails 5.2.0.alpha from source at `/Users/kasperhansen/Documents/code/rails` Using sass-rails 5.0.6 Bundle complete! 16 Gemfile dependencies, 72 gems now installed. Use `bundle info [gemname]` to see where a bundled gem is installed. Adding config/master.key to store the master encryption key: 97070158c44b4675b876373a6bc9d5a0 Save this in a password manager your team can access. If you lose the key, no one, including you, can access anything encrypted with it. create config/master.key ``` And that'll be executed even if `--skip-bundle` was passed. * Ensure test app has secret_key_base. * Assign secret_key_base to app or omit. * Merge noise * Split options for dynamic delegation into its own method and use deep symbols to make it work * Update error to point to credentials instead * Appease Rubocop * Validate secret_key_base when reading it. Instead of relying on the validation in key_generator move that into secret_key_base itself. * Fix generator and secrets test. Manually add config.read_encrypted_secrets since it's not there by default anymore. Move mentions of config/secrets.yml to config/credentials.yml.enc. * Remove files I have no idea how they got here. * [ci skip] swap secrets for credentials. * [ci skip] And now, changelogs are coming.
2017-09-11 14:21:20 -04:00
assert_match(/^ # config\.require_master_key = true/, 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_non_sqlite3_db
run_generator([destination_root, "-d", "mysql"])
assert_file ".gitignore" do |content|
assert_no_match(/sqlite/i, content)
end
end
def test_generator_if_skip_active_record_is_given
run_generator [destination_root, "--skip-active-record"]
assert_no_directory "#{application_path}/db/"
assert_no_file "#{application_path}/config/database.yml"
assert_no_file "#{application_path}/app/models/application_record.rb"
assert_file "#{application_path}/config/application.rb", /#\s+require\s+["']active_record\/railtie["']/
assert_file "test/test_helper.rb" do |helper_content|
assert_no_match(/fixtures :all/, helper_content)
end
assert_file "#{application_path}/bin/setup" do |setup_content|
assert_no_match(/db:setup/, setup_content)
end
assert_file "#{application_path}/bin/update" do |update_content|
assert_no_match(/db:migrate/, update_content)
end
assert_file ".gitignore" do |content|
assert_no_match(/sqlite/i, content)
end
end
def test_generator_for_active_storage
run_generator
assert_file "#{application_path}/app/assets/javascripts/application.js" do |content|
assert_match(/^\/\/= require activestorage/, content)
end
assert_file "#{application_path}/config/environments/development.rb" do |content|
assert_match(/config\.active_storage/, content)
end
assert_file "#{application_path}/config/environments/production.rb" do |content|
assert_match(/config\.active_storage/, content)
end
assert_file "#{application_path}/config/environments/test.rb" do |content|
assert_match(/config\.active_storage/, content)
end
assert_file "#{application_path}/config/storage.yml"
assert_directory "#{application_path}/storage"
assert_directory "#{application_path}/tmp/storage"
assert_file ".gitignore" do |content|
assert_match(/\/storage\//, content)
end
end
def test_generator_if_skip_active_storage_is_given
run_generator [destination_root, "--skip-active-storage"]
assert_file "#{application_path}/config/application.rb", /#\s+require\s+["']active_storage\/engine["']/
assert_file "#{application_path}/app/assets/javascripts/application.js" do |content|
assert_no_match(/^\/\/= require activestorage/, content)
end
assert_file "#{application_path}/config/environments/development.rb" do |content|
assert_no_match(/config\.active_storage/, content)
end
assert_file "#{application_path}/config/environments/production.rb" do |content|
assert_no_match(/config\.active_storage/, content)
end
assert_file "#{application_path}/config/environments/test.rb" do |content|
assert_no_match(/config\.active_storage/, content)
end
assert_no_file "#{application_path}/config/storage.yml"
assert_no_directory "#{application_path}/db/migrate"
assert_no_directory "#{application_path}/storage"
assert_no_directory "#{application_path}/tmp/storage"
assert_file ".gitignore" do |content|
assert_no_match(/\/storage\//, content)
end
end
def test_generator_does_not_generate_active_storage_contents_if_skip_active_record_is_given
run_generator [destination_root, "--skip-active-record"]
assert_file "#{application_path}/config/application.rb", /#\s+require\s+["']active_storage\/engine["']/
assert_file "#{application_path}/app/assets/javascripts/application.js" do |content|
assert_no_match(/^\/\/= require activestorage/, content)
end
assert_file "#{application_path}/config/environments/development.rb" do |content|
assert_no_match(/config\.active_storage/, content)
end
assert_file "#{application_path}/config/environments/production.rb" do |content|
assert_no_match(/config\.active_storage/, content)
end
assert_file "#{application_path}/config/environments/test.rb" do |content|
assert_no_match(/config\.active_storage/, content)
end
assert_no_file "#{application_path}/config/storage.yml"
assert_no_directory "#{application_path}/db/migrate"
assert_no_directory "#{application_path}/storage"
assert_no_directory "#{application_path}/tmp/storage"
assert_file ".gitignore" do |content|
assert_no_match(/\/storage\//, content)
end
end
def test_generator_if_skip_action_mailer_is_given
run_generator [destination_root, "--skip-action-mailer"]
assert_file "#{application_path}/config/application.rb", /#\s+require\s+["']action_mailer\/railtie["']/
assert_file "#{application_path}/config/environments/development.rb" do |content|
assert_no_match(/config\.action_mailer/, content)
end
assert_file "#{application_path}/config/environments/test.rb" do |content|
assert_no_match(/config\.action_mailer/, content)
end
assert_file "#{application_path}/config/environments/production.rb" do |content|
assert_no_match(/config\.action_mailer/, content)
end
assert_no_directory "#{application_path}/app/mailers"
assert_no_directory "#{application_path}/test/mailers"
end
def test_generator_if_skip_action_cable_is_given
run_generator [destination_root, "--skip-action-cable"]
assert_file "#{application_path}/config/application.rb", /#\s+require\s+["']action_cable\/engine["']/
assert_no_file "#{application_path}/config/cable.yml"
assert_no_file "#{application_path}/app/assets/javascripts/cable.js"
assert_no_directory "#{application_path}/app/assets/javascripts/channels"
assert_no_directory "#{application_path}/app/channels"
assert_file "Gemfile" do |content|
assert_no_match(/redis/, content)
end
end
def test_generator_if_skip_sprockets_is_given
run_generator [destination_root, "--skip-sprockets"]
assert_no_file "#{application_path}/config/initializers/assets.rb"
assert_file "#{application_path}/config/application.rb", /#\s+require\s+["']sprockets\/railtie["']/
assert_file "Gemfile" do |content|
assert_no_match(/sass-rails/, content)
assert_no_match(/uglifier/, content)
assert_no_match(/coffee-rails/, content)
end
assert_file "#{application_path}/config/environments/development.rb" do |content|
assert_no_match(/config\.assets\.debug/, content)
end
assert_file "#{application_path}/config/environments/production.rb" do |content|
assert_no_match(/config\.assets\.digest/, content)
assert_no_match(/config\.assets\.js_compressor/, content)
assert_no_match(/config\.assets\.css_compressor/, content)
assert_no_match(/config\.assets\.compile/, content)
end
end
def test_generator_for_yarn
run_generator
assert_file "#{application_path}/package.json", /dependencies/
assert_file "#{application_path}/config/initializers/assets.rb", /node_modules/
assert_file ".gitignore" do |content|
assert_match(/node_modules/, content)
assert_match(/yarn-error\.log/, content)
end
end
def test_generator_for_yarn_skipped
run_generator([destination_root, "--skip-yarn"])
assert_no_file "#{application_path}/package.json"
assert_no_file "#{application_path}/bin/yarn"
assert_file "#{application_path}/config/initializers/assets.rb" do |content|
assert_no_match(/node_modules/, content)
end
assert_file ".gitignore" do |content|
assert_no_match(/node_modules/, content)
assert_no_match(/yarn-error\.log/, content)
end
end
end