Run in-app rails commands via fork+load where possible

While this avoids shell argument parsing, we still pass through
everything in our stack.
This commit is contained in:
Matthew Draper 2017-09-04 02:25:26 +09:30
parent 07bac9ef93
commit 802ce8a239
21 changed files with 339 additions and 289 deletions

View File

@ -45,7 +45,12 @@ namespace :test do
# We could run these in parallel, but pretty much all of the
# railties tests already run in parallel, so ¯\_(⊙︿⊙)_/¯
Process.waitpid fork { ARGV.clear; load file }
Process.waitpid fork {
ARGV.clear
Rake.application = nil
load file
}
unless $?.success?
failing_files << file

View File

@ -44,8 +44,7 @@ module ApplicationTests
test "assets are concatenated when debug is off and compile is off either if debug_assets param is provided" do
# config.assets.debug and config.assets.compile are false for production environment
ENV["RAILS_ENV"] = "production"
output = Dir.chdir(app_path) { `bin/rails assets:precompile --trace 2>&1` }
assert $?.success?, output
rails "assets:precompile", "--trace"
# Load app env
app "production"

View File

@ -22,7 +22,7 @@ module ApplicationTests
end
RUBY
list_tables = lambda { `bin/rails runner 'p ActiveRecord::Base.connection.tables'`.strip }
list_tables = lambda { rails("runner", "p ActiveRecord::Base.connection.tables").strip }
File.write("log/test.log", "zomg!")
assert_equal "[]", list_tables.call

View File

@ -31,7 +31,7 @@ module ApplicationTests
end
test "allow running plugin new generator inside Rails app directory" do
FileUtils.cd(rails_root) { `ruby bin/rails plugin new vendor/plugins/bukkits` }
rails "plugin", "new", "vendor/plugins/bukkits"
assert File.exist?(File.join(rails_root, "vendor/plugins/bukkits/test/dummy/config/application.rb"))
end
@ -167,7 +167,7 @@ module ApplicationTests
config.api_only = true
RUBY
FileUtils.cd(rails_root) { `bin/rails generate mailer notifier foo` }
rails "generate", "mailer", "notifier", "foo"
assert File.exist?(File.join(rails_root, "app/views/notifier_mailer/foo.text.erb"))
assert File.exist?(File.join(rails_root, "app/views/notifier_mailer/foo.html.erb"))
end
@ -190,10 +190,10 @@ module ApplicationTests
test "help does not show hidden namespaces" do
FileUtils.cd(rails_root) do
output = `bin/rails generate --help`
output = rails("generate", "--help")
assert_no_match "active_record:migration", output
output = `bin/rails destroy --help`
output = rails("destroy", "--help")
assert_no_match "active_record:migration", output
end
end

View File

@ -14,12 +14,12 @@ class HelpTest < ActiveSupport::TestCase
end
test "command works" do
output = Dir.chdir(app_path) { `bin/rails help` }
output = rails("help")
assert_match "The most common rails commands are", output
end
test "short-cut alias works" do
output = Dir.chdir(app_path) { `bin/rails -h` }
output = rails("-h")
assert_match "The most common rails commands are", output
end
end

View File

@ -215,20 +215,16 @@ module ApplicationTests
end
test "use schema cache dump" do
Dir.chdir(app_path) do
`rails generate model post title:string;
bin/rails db:migrate db:schema:cache:dump`
end
rails %w(generate model post title:string)
rails %w(db:migrate db:schema:cache:dump)
require "#{app_path}/config/environment"
ActiveRecord::Base.connection.drop_table("posts") # force drop posts table for test.
assert ActiveRecord::Base.connection.schema_cache.data_sources("posts")
end
test "expire schema cache dump" do
Dir.chdir(app_path) do
`rails generate model post title:string;
bin/rails db:migrate db:schema:cache:dump db:rollback`
end
rails %w(generate model post title:string)
rails %w(db:migrate db:schema:cache:dump db:rollback)
require "#{app_path}/config/environment"
assert !ActiveRecord::Base.connection.schema_cache.data_sources("posts")
end

View File

@ -15,7 +15,7 @@ module ApplicationTests
end
test "resets Action Mailer test deliveries" do
script("generate mailer BaseMailer welcome")
rails "generate", "mailer", "BaseMailer", "welcome"
app_file "test/integration/mailer_integration_test.rb", <<-RUBY
require 'test_helper'
@ -39,8 +39,7 @@ module ApplicationTests
end
RUBY
output = Dir.chdir(app_path) { `bin/rails test 2>&1` }
assert_equal 0, $?.to_i, output
output = rails("test")
assert_match(/0 failures, 0 errors/, output)
end
end
@ -67,8 +66,7 @@ module ApplicationTests
end
RUBY
output = Dir.chdir(app_path) { `bin/rails test 2>&1` }
assert_equal 0, $?.to_i, output
output = rails("test")
assert_match(/0 failures, 0 errors/, output)
end
end

View File

@ -28,11 +28,11 @@ module ApplicationTests
def db_create_and_drop(expected_database)
Dir.chdir(app_path) do
output = `bin/rails db:create`
output = rails("db:create")
assert_match(/Created database/, output)
assert File.exist?(expected_database)
assert_equal expected_database, ActiveRecord::Base.connection_config[:database]
output = `bin/rails db:drop`
output = rails("db:drop")
assert_match(/Dropped database/, output)
assert !File.exist?(expected_database)
end
@ -52,17 +52,16 @@ module ApplicationTests
def with_database_existing
Dir.chdir(app_path) do
set_database_url
`bin/rails db:create`
rails "db:create"
yield
`bin/rails db:drop`
rails "db:drop"
end
end
test "db:create failure because database exists" do
with_database_existing do
output = `bin/rails db:create 2>&1`
output = rails("db:create")
assert_match(/already exists/, output)
assert_equal 0, $?.exitstatus
end
end
@ -77,7 +76,7 @@ module ApplicationTests
test "db:create failure because bad permissions" do
with_bad_permissions do
output = `bin/rails db:create 2>&1`
output = rails("db:create", allow_failure: true)
assert_match(/Couldn't create database/, output)
assert_equal 1, $?.exitstatus
end
@ -85,16 +84,15 @@ module ApplicationTests
test "db:drop failure because database does not exist" do
Dir.chdir(app_path) do
output = `bin/rails db:drop:_unsafe --trace 2>&1`
output = rails("db:drop:_unsafe", "--trace")
assert_match(/does not exist/, output)
assert_equal 0, $?.exitstatus
end
end
test "db:drop failure because bad permissions" do
with_database_existing do
with_bad_permissions do
output = `bin/rails db:drop 2>&1`
output = rails("db:drop", allow_failure: true)
assert_match(/Couldn't drop/, output)
assert_equal 1, $?.exitstatus
end
@ -103,9 +101,9 @@ module ApplicationTests
def db_migrate_and_status(expected_database)
Dir.chdir(app_path) do
`bin/rails generate model book title:string;
bin/rails db:migrate`
output = `bin/rails db:migrate:status`
rails "generate", "model", "book", "title:string"
rails "db:migrate"
output = rails("db:migrate:status")
assert_match(%r{database:\s+\S*#{Regexp.escape(expected_database)}}, output)
assert_match(/up\s+\d{14}\s+Create books/, output)
end
@ -124,8 +122,8 @@ module ApplicationTests
def db_schema_dump
Dir.chdir(app_path) do
`bin/rails generate model book title:string;
bin/rails db:migrate db:schema:dump`
rails "generate", "model", "book", "title:string"
rails "db:migrate", "db:schema:dump"
schema_dump = File.read("db/schema.rb")
assert_match(/create_table \"books\"/, schema_dump)
end
@ -142,8 +140,8 @@ module ApplicationTests
def db_fixtures_load(expected_database)
Dir.chdir(app_path) do
`bin/rails generate model book title:string;
bin/rails db:migrate db:fixtures:load`
rails "generate", "model", "book", "title:string"
rails "db:migrate", "db:fixtures:load"
assert_match expected_database, ActiveRecord::Base.connection_config[:database]
require "#{app_path}/app/models/book"
assert_equal 2, Book.count
@ -164,8 +162,8 @@ module ApplicationTests
test "db:fixtures:load with namespaced fixture" do
require "#{app_path}/config/environment"
Dir.chdir(app_path) do
`bin/rails generate model admin::book title:string;
bin/rails db:migrate db:fixtures:load`
rails "generate", "model", "admin::book", "title:string"
rails "db:migrate", "db:fixtures:load"
require "#{app_path}/app/models/admin/book"
assert_equal 2, Admin::Book.count
end
@ -173,11 +171,11 @@ module ApplicationTests
def db_structure_dump_and_load(expected_database)
Dir.chdir(app_path) do
`bin/rails generate model book title:string;
bin/rails db:migrate db:structure:dump`
rails "generate", "model", "book", "title:string"
rails "db:migrate", "db:structure:dump"
structure_dump = File.read("db/structure.sql")
assert_match(/CREATE TABLE (?:IF NOT EXISTS )?\"books\"/, structure_dump)
`bin/rails environment db:drop db:structure:load`
rails "environment", "db:drop", "db:structure:load"
assert_match expected_database, ActiveRecord::Base.connection_config[:database]
require "#{app_path}/app/models/book"
#if structure is not loaded correctly, exception would be raised
@ -197,20 +195,18 @@ module ApplicationTests
end
test "db:structure:dump does not dump schema information when no migrations are used" do
Dir.chdir(app_path) do
# create table without migrations
`bin/rails runner 'ActiveRecord::Base.connection.create_table(:posts) {|t| t.string :title }'`
# create table without migrations
rails "runner", "ActiveRecord::Base.connection.create_table(:posts) {|t| t.string :title }"
stderr_output = capture(:stderr) { `bin/rails db:structure:dump` }
assert_empty stderr_output
structure_dump = File.read("db/structure.sql")
assert_match(/CREATE TABLE (?:IF NOT EXISTS )?\"posts\"/, structure_dump)
end
stderr_output = capture(:stderr) { rails("db:structure:dump", stderr: true, allow_failure: true) }
assert_empty stderr_output
structure_dump = File.read("#{app_path}/db/structure.sql")
assert_match(/CREATE TABLE (?:IF NOT EXISTS )?\"posts\"/, structure_dump)
end
test "db:schema:load and db:structure:load do not purge the existing database" do
Dir.chdir(app_path) do
`bin/rails runner 'ActiveRecord::Base.connection.create_table(:posts) {|t| t.string :title }'`
rails "runner", "ActiveRecord::Base.connection.create_table(:posts) {|t| t.string :title }"
app_file "db/schema.rb", <<-RUBY
ActiveRecord::Schema.define(version: 20140423102712) do
@ -218,17 +214,17 @@ module ApplicationTests
end
RUBY
list_tables = lambda { `bin/rails runner 'p ActiveRecord::Base.connection.tables'`.strip }
list_tables = lambda { rails("runner", "p ActiveRecord::Base.connection.tables").strip }
assert_equal '["posts"]', list_tables[]
`bin/rails db:schema:load`
rails "db:schema:load"
assert_equal '["posts", "comments", "schema_migrations", "ar_internal_metadata"]', list_tables[]
app_file "db/structure.sql", <<-SQL
CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255));
SQL
`bin/rails db:structure:load`
rails "db:structure:load"
assert_equal '["posts", "comments", "schema_migrations", "ar_internal_metadata", "users"]', list_tables[]
end
end
@ -251,27 +247,25 @@ module ApplicationTests
end
RUBY
`bin/rails db:schema:load`
rails "db:schema:load"
tables = `bin/rails runner 'p ActiveRecord::Base.connection.tables'`.strip
tables = rails("runner", "p ActiveRecord::Base.connection.tables").strip
assert_match(/"geese"/, tables)
columns = `bin/rails runner 'p ActiveRecord::Base.connection.columns("geese").map(&:name)'`.strip
columns = rails("runner", "p ActiveRecord::Base.connection.columns('geese').map(&:name)").strip
assert_equal columns, '["gooseid", "name"]'
end
end
test "db:schema:load fails if schema.rb doesn't exist yet" do
Dir.chdir(app_path) do
stderr_output = capture(:stderr) { `bin/rails db:schema:load` }
assert_match(/Run `rails db:migrate` to create it/, stderr_output)
end
stderr_output = capture(:stderr) { rails("db:schema:load", stderr: true, allow_failure: true) }
assert_match(/Run `rails db:migrate` to create it/, stderr_output)
end
def db_test_load_structure
Dir.chdir(app_path) do
`bin/rails generate model book title:string;
bin/rails db:migrate db:structure:dump db:test:load_structure`
rails "generate", "model", "book", "title:string"
rails "db:migrate", "db:structure:dump", "db:test:load_structure"
ActiveRecord::Base.configurations = Rails.application.config.database_configuration
ActiveRecord::Base.establish_connection :test
require "#{app_path}/app/models/book"
@ -307,7 +301,7 @@ module ApplicationTests
RUBY
Dir.chdir(app_path) do
database_path = `bin/rails db:setup`
database_path = rails("db:setup")
assert_equal "development.sqlite3", File.basename(database_path.strip)
end
ensure

View File

@ -17,7 +17,7 @@ module ApplicationTests
test "dev:cache creates file and outputs message" do
Dir.chdir(app_path) do
output = `rails dev:cache`
output = rails("dev:cache")
assert File.exist?("tmp/caching-dev.txt")
assert_match(/Development mode is now being cached/, output)
end
@ -25,8 +25,8 @@ module ApplicationTests
test "dev:cache deletes file and outputs message" do
Dir.chdir(app_path) do
`rails dev:cache` # Create caching file.
output = `rails dev:cache` # Delete caching file.
rails "dev:cache" # Create caching file.
output = rails("dev:cache") # Delete caching file.
assert_not File.exist?("tmp/caching-dev.txt")
assert_match(/Development mode is no longer being cached/, output)
end
@ -34,12 +34,12 @@ module ApplicationTests
test "dev:cache touches tmp/restart.txt" do
Dir.chdir(app_path) do
`rails dev:cache`
rails "dev:cache"
assert File.exist?("tmp/restart.txt")
prev_mtime = File.mtime("tmp/restart.txt")
sleep(1)
`rails dev:cache`
rails "dev:cache"
curr_mtime = File.mtime("tmp/restart.txt")
assert_not_equal prev_mtime, curr_mtime
end

View File

@ -23,7 +23,7 @@ module ApplicationTests
File.write("log/test.log", "test")
File.write("log/dummy.log", "dummy")
`rails log:clear`
rails "log:clear"
assert_equal 0, File.size("log/test.log")
assert_equal 0, File.size("log/staging.log")

View File

@ -16,21 +16,21 @@ module ApplicationTests
test "running migrations with given scope" do
Dir.chdir(app_path) do
`bin/rails generate model user username:string password:string`
rails "generate", "model", "user", "username:string", "password:string"
app_file "db/migrate/01_a_migration.bukkits.rb", <<-MIGRATION
class AMigration < ActiveRecord::Migration::Current
end
MIGRATION
output = `bin/rails db:migrate SCOPE=bukkits`
output = rails("db:migrate", "SCOPE=bukkits")
assert_no_match(/create_table\(:users\)/, output)
assert_no_match(/CreateUsers/, output)
assert_no_match(/add_column\(:users, :email, :string\)/, output)
assert_match(/AMigration: migrated/, output)
output = `bin/rails db:migrate SCOPE=bukkits VERSION=0`
output = rails("db:migrate", "SCOPE=bukkits", "VERSION=0")
assert_no_match(/drop_table\(:users\)/, output)
assert_no_match(/CreateUsers/, output)
assert_no_match(/remove_column\(:users, :email\)/, output)
@ -41,38 +41,38 @@ module ApplicationTests
test "migration with empty version" do
Dir.chdir(app_path) do
output = `bin/rails db:migrate VERSION= 2>&1`
output = rails("db:migrate", "VERSION=", allow_failure: true)
assert_match(/Empty VERSION provided/, output)
output = `bin/rails db:migrate:redo VERSION= 2>&1`
output = rails("db:migrate:redo", "VERSION=", allow_failure: true)
assert_match(/Empty VERSION provided/, output)
output = `bin/rails db:migrate:up VERSION= 2>&1`
output = rails("db:migrate:up", "VERSION=", allow_failure: true)
assert_match(/VERSION is required/, output)
output = `bin/rails db:migrate:up 2>&1`
output = rails("db:migrate:up", allow_failure: true)
assert_match(/VERSION is required/, output)
output = `bin/rails db:migrate:down VERSION= 2>&1`
output = rails("db:migrate:down", "VERSION=", allow_failure: true)
assert_match(/VERSION is required - To go down one migration, use db:rollback/, output)
output = `bin/rails db:migrate:down 2>&1`
output = rails("db:migrate:down", allow_failure: true)
assert_match(/VERSION is required - To go down one migration, use db:rollback/, output)
end
end
test "model and migration generator with change syntax" do
Dir.chdir(app_path) do
`bin/rails generate model user username:string password:string;
bin/rails generate migration add_email_to_users email:string`
rails "generate", "model", "user", "username:string", "password:string"
rails "generate", "migration", "add_email_to_users", "email:string"
output = `bin/rails db:migrate`
output = rails("db:migrate")
assert_match(/create_table\(:users\)/, output)
assert_match(/CreateUsers: migrated/, output)
assert_match(/add_column\(:users, :email, :string\)/, output)
assert_match(/AddEmailToUsers: migrated/, output)
output = `bin/rails db:rollback STEP=2`
output = rails("db:rollback", "STEP=2")
assert_match(/drop_table\(:users\)/, output)
assert_match(/CreateUsers: reverted/, output)
assert_match(/remove_column\(:users, :email, :string\)/, output)
@ -81,23 +81,23 @@ module ApplicationTests
end
test "migration status when schema migrations table is not present" do
output = Dir.chdir(app_path) { `bin/rails db:migrate:status 2>&1` }
output = rails("db:migrate:status", allow_failure: true)
assert_equal "Schema migrations table does not exist yet.\n", output
end
test "migration status" do
Dir.chdir(app_path) do
`bin/rails generate model user username:string password:string;
bin/rails generate migration add_email_to_users email:string;
bin/rails db:migrate`
rails "generate", "model", "user", "username:string", "password:string"
rails "generate", "migration", "add_email_to_users", "email:string"
rails "db:migrate"
output = `bin/rails db:migrate:status`
output = rails("db:migrate:status")
assert_match(/up\s+\d{14}\s+Create users/, output)
assert_match(/up\s+\d{14}\s+Add email to users/, output)
`bin/rails db:rollback STEP=1`
output = `bin/rails db:migrate:status`
rails "db:rollback", "STEP=1"
output = rails("db:migrate:status")
assert_match(/up\s+\d{14}\s+Create users/, output)
assert_match(/down\s+\d{14}\s+Add email to users/, output)
@ -108,17 +108,17 @@ module ApplicationTests
add_to_config("config.active_record.timestamped_migrations = false")
Dir.chdir(app_path) do
`bin/rails generate model user username:string password:string;
bin/rails generate migration add_email_to_users email:string;
bin/rails db:migrate`
rails "generate", "model", "user", "username:string", "password:string"
rails "generate", "migration", "add_email_to_users", "email:string"
rails "db:migrate"
output = `bin/rails db:migrate:status`
output = rails("db:migrate:status")
assert_match(/up\s+\d{3,}\s+Create users/, output)
assert_match(/up\s+\d{3,}\s+Add email to users/, output)
`bin/rails db:rollback STEP=1`
output = `bin/rails db:migrate:status`
rails "db:rollback", "STEP=1"
output = rails("db:migrate:status")
assert_match(/up\s+\d{3,}\s+Create users/, output)
assert_match(/down\s+\d{3,}\s+Add email to users/, output)
@ -127,23 +127,23 @@ module ApplicationTests
test "migration status after rollback and redo" do
Dir.chdir(app_path) do
`bin/rails generate model user username:string password:string;
bin/rails generate migration add_email_to_users email:string;
bin/rails db:migrate`
rails "generate", "model", "user", "username:string", "password:string"
rails "generate", "migration", "add_email_to_users", "email:string"
rails "db:migrate"
output = `bin/rails db:migrate:status`
output = rails("db:migrate:status")
assert_match(/up\s+\d{14}\s+Create users/, output)
assert_match(/up\s+\d{14}\s+Add email to users/, output)
`bin/rails db:rollback STEP=2`
output = `bin/rails db:migrate:status`
rails "db:rollback", "STEP=2"
output = rails("db:migrate:status")
assert_match(/down\s+\d{14}\s+Create users/, output)
assert_match(/down\s+\d{14}\s+Add email to users/, output)
`bin/rails db:migrate:redo`
output = `bin/rails db:migrate:status`
rails "db:migrate:redo"
output = rails("db:migrate:status")
assert_match(/up\s+\d{14}\s+Create users/, output)
assert_match(/up\s+\d{14}\s+Add email to users/, output)
@ -152,23 +152,23 @@ module ApplicationTests
test "migration status after rollback and forward" do
Dir.chdir(app_path) do
`bin/rails generate model user username:string password:string;
bin/rails generate migration add_email_to_users email:string;
bin/rails db:migrate`
rails "generate", "model", "user", "username:string", "password:string"
rails "generate", "migration", "add_email_to_users", "email:string"
rails "db:migrate"
output = `bin/rails db:migrate:status`
output = rails("db:migrate:status")
assert_match(/up\s+\d{14}\s+Create users/, output)
assert_match(/up\s+\d{14}\s+Add email to users/, output)
`bin/rails db:rollback STEP=2`
output = `bin/rails db:migrate:status`
rails "db:rollback", "STEP=2"
output = rails("db:migrate:status")
assert_match(/down\s+\d{14}\s+Create users/, output)
assert_match(/down\s+\d{14}\s+Add email to users/, output)
`bin/rails db:forward STEP=2`
output = `bin/rails db:migrate:status`
rails "db:forward", "STEP=2"
output = rails("db:migrate:status")
assert_match(/up\s+\d{14}\s+Create users/, output)
assert_match(/up\s+\d{14}\s+Add email to users/, output)
@ -177,30 +177,30 @@ module ApplicationTests
test "raise error on any move when current migration does not exist" do
Dir.chdir(app_path) do
`bin/rails generate model user username:string password:string;
bin/rails generate migration add_email_to_users email:string;
bin/rails db:migrate
rm db/migrate/*email*.rb`
rails "generate", "model", "user", "username:string", "password:string"
rails "generate", "migration", "add_email_to_users", "email:string"
rails "db:migrate"
`rm db/migrate/*email*.rb`
output = `bin/rails db:migrate:status`
output = rails("db:migrate:status")
assert_match(/up\s+\d{14}\s+Create users/, output)
assert_match(/up\s+\d{14}\s+\** NO FILE \**/, output)
output = `bin/rails db:rollback 2>&1`
output = rails("db:rollback", allow_failure: true)
assert_match(/rails aborted!/, output)
assert_match(/ActiveRecord::UnknownMigrationVersionError:/, output)
assert_match(/No migration with version number\s\d{14}\./, output)
output = `bin/rails db:migrate:status`
output = rails("db:migrate:status")
assert_match(/up\s+\d{14}\s+Create users/, output)
assert_match(/up\s+\d{14}\s+\** NO FILE \**/, output)
output = `bin/rails db:forward 2>&1`
output = rails("db:forward", allow_failure: true)
assert_match(/rails aborted!/, output)
assert_match(/ActiveRecord::UnknownMigrationVersionError:/, output)
assert_match(/No migration with version number\s\d{14}\./, output)
output = `bin/rails db:migrate:status`
output = rails("db:migrate:status")
assert_match(/up\s+\d{14}\s+Create users/, output)
assert_match(/up\s+\d{14}\s+\** NO FILE \**/, output)
end
@ -210,23 +210,23 @@ module ApplicationTests
add_to_config("config.active_record.timestamped_migrations = false")
Dir.chdir(app_path) do
`bin/rails generate model user username:string password:string;
bin/rails generate migration add_email_to_users email:string;
bin/rails db:migrate`
rails "generate", "model", "user", "username:string", "password:string"
rails "generate", "migration", "add_email_to_users", "email:string"
rails "db:migrate"
output = `bin/rails db:migrate:status`
output = rails("db:migrate:status")
assert_match(/up\s+\d{3,}\s+Create users/, output)
assert_match(/up\s+\d{3,}\s+Add email to users/, output)
`bin/rails db:rollback STEP=2`
output = `bin/rails db:migrate:status`
rails "db:rollback", "STEP=2"
output = rails("db:migrate:status")
assert_match(/down\s+\d{3,}\s+Create users/, output)
assert_match(/down\s+\d{3,}\s+Add email to users/, output)
`bin/rails db:migrate:redo`
output = `bin/rails db:migrate:status`
rails "db:migrate:redo"
output = rails("db:migrate:status")
assert_match(/up\s+\d{3,}\s+Create users/, output)
assert_match(/up\s+\d{3,}\s+Add email to users/, output)
@ -246,9 +246,9 @@ module ApplicationTests
end
MIGRATION
`bin/rails db:migrate`
rails "db:migrate"
output = `bin/rails db:migrate:status`
output = rails("db:migrate:status")
assert_match(/up\s+001\s+One migration/, output)
assert_match(/up\s+002\s+Two migration/, output)
@ -259,19 +259,19 @@ module ApplicationTests
add_to_config("config.active_record.dump_schema_after_migration = false")
Dir.chdir(app_path) do
`bin/rails generate model book title:string`
output = `bin/rails generate model author name:string`
rails "generate", "model", "book", "title:string"
output = rails("generate", "model", "author", "name:string")
version = output =~ %r{[^/]+db/migrate/(\d+)_create_authors\.rb} && $1
`bin/rails db:migrate db:rollback db:forward db:migrate:up db:migrate:down VERSION=#{version}`
rails "db:migrate", "db:rollback", "db:forward", "db:migrate:up", "db:migrate:down", "VERSION=#{version}"
assert !File.exist?("db/schema.rb"), "should not dump schema when configured not to"
end
add_to_config("config.active_record.dump_schema_after_migration = true")
Dir.chdir(app_path) do
`bin/rails generate model reviews book_id:integer`
`bin/rails db:migrate`
rails "generate", "model", "reviews", "book_id:integer"
rails "db:migrate"
structure_dump = File.read("db/schema.rb")
assert_match(/create_table "reviews"/, structure_dump)
@ -280,8 +280,8 @@ module ApplicationTests
test "default schema generation after migration" do
Dir.chdir(app_path) do
`bin/rails generate model book title:string;
bin/rails db:migrate`
rails "generate", "model", "book", "title:string"
rails "db:migrate"
structure_dump = File.read("db/schema.rb")
assert_match(/create_table "books"/, structure_dump)
@ -290,12 +290,12 @@ module ApplicationTests
test "migration status migrated file is deleted" do
Dir.chdir(app_path) do
`bin/rails generate model user username:string password:string;
bin/rails generate migration add_email_to_users email:string;
bin/rails db:migrate
rm db/migrate/*email*.rb`
rails "generate", "model", "user", "username:string", "password:string"
rails "generate", "migration", "add_email_to_users", "email:string"
rails "db:migrate"
`rm db/migrate/*email*.rb`
output = `bin/rails db:migrate:status`
output = rails("db:migrate:status")
assert_match(/up\s+\d{14}\s+Create users/, output)
assert_match(/up\s+\d{14}\s+\** NO FILE \**/, output)

View File

@ -17,12 +17,12 @@ module ApplicationTests
test "rails restart touches tmp/restart.txt" do
Dir.chdir(app_path) do
`bin/rails restart`
rails "restart"
assert File.exist?("tmp/restart.txt")
prev_mtime = File.mtime("tmp/restart.txt")
sleep(1)
`bin/rails restart`
rails "restart"
curr_mtime = File.mtime("tmp/restart.txt")
assert_not_equal prev_mtime, curr_mtime
end
@ -31,7 +31,7 @@ module ApplicationTests
test "rails restart should work even if tmp folder does not exist" do
Dir.chdir(app_path) do
FileUtils.remove_dir("tmp")
`bin/rails restart`
rails "restart"
assert File.exist?("tmp/restart.txt")
end
end

View File

@ -26,7 +26,7 @@ module ApplicationTests
FileUtils.mkdir_p("tmp/screenshots")
FileUtils.touch("tmp/screenshots/fail.png")
`rails tmp:clear`
rails "tmp:clear"
assert_not File.exist?("tmp/cache/cache_file")
assert_not File.exist?("tmp/sockets/socket_file")
@ -36,9 +36,7 @@ module ApplicationTests
test "tmp:clear should work if folder missing" do
FileUtils.remove_dir("#{app_path}/tmp")
errormsg = Dir.chdir(app_path) { `bin/rails tmp:clear` }
assert_predicate $?, :success?
assert_empty errormsg
rails "tmp:clear"
end
end
end

View File

@ -1,11 +1,12 @@
# frozen_string_literal: true
require "isolation/abstract_unit"
require "env_helpers"
require "active_support/core_ext/string/strip"
module ApplicationTests
class RakeTest < ActiveSupport::TestCase
include ActiveSupport::Testing::Isolation
include ActiveSupport::Testing::Isolation, EnvHelpers
def setup
build_app
@ -26,20 +27,20 @@ module ApplicationTests
end
test "task is protected when previous migration was production" do
Dir.chdir(app_path) do
output = `bin/rails generate model product name:string;
env RAILS_ENV=production bin/rails db:create db:migrate;
env RAILS_ENV=production bin/rails db:test:prepare test 2>&1`
with_rails_env "production" do
rails "generate", "model", "product", "name:string"
rails "db:create", "db:migrate"
output = rails("db:test:prepare", allow_failure: true)
assert_match(/ActiveRecord::ProtectedEnvironmentError/, output)
end
end
def test_not_protected_when_previous_migration_was_not_production
Dir.chdir(app_path) do
output = `bin/rails generate model product name:string;
env RAILS_ENV=test bin/rails db:create db:migrate;
env RAILS_ENV=test bin/rails db:test:prepare test 2>&1`
with_rails_env "test" do
rails "generate", "model", "product", "name:string"
rails "db:create", "db:migrate"
output = Dir.chdir(app_path) { rails("db:test:prepare", "test") }
refute_match(/ActiveRecord::ProtectedEnvironmentError/, output)
end
@ -56,7 +57,7 @@ module ApplicationTests
Rails.application.initialize!
RUBY
assert_match("SuperMiddleware", Dir.chdir(app_path) { `bin/rails middleware` })
assert_match("SuperMiddleware", rails("middleware"))
end
def test_initializers_are_executed_in_rake_tasks
@ -71,7 +72,7 @@ module ApplicationTests
end
RUBY
output = Dir.chdir(app_path) { `bin/rails do_nothing` }
output = rails("do_nothing")
assert_match "Doing something...", output
end
@ -92,7 +93,7 @@ module ApplicationTests
end
RUBY
output = Dir.chdir(app_path) { `bin/rails do_nothing` }
output = rails("do_nothing")
assert_match "Hello world", output
end
@ -120,7 +121,7 @@ module ApplicationTests
def test_code_statistics_sanity
assert_match "Code LOC: 25 Test LOC: 0 Code to Test Ratio: 1:0.0",
Dir.chdir(app_path) { `bin/rails stats` }
rails("stats")
end
def test_rails_routes_calls_the_route_inspector
@ -130,7 +131,7 @@ module ApplicationTests
end
RUBY
output = Dir.chdir(app_path) { `bin/rails routes` }
output = rails("routes")
assert_equal <<-MESSAGE.strip_heredoc, output
Prefix Verb URI Pattern Controller#Action
cart GET /cart(.:format) cart#show
@ -158,7 +159,7 @@ module ApplicationTests
" DELETE /post(.:format) posts#destroy",
" POST /post(.:format) posts#create\n"].join("\n")
output = Dir.chdir(app_path) { `bin/rails routes -c PostController` }
output = rails("routes", "-c", "PostController")
assert_equal expected_output, output
end
@ -171,7 +172,7 @@ module ApplicationTests
end
RUBY
output = Dir.chdir(app_path) { `bin/rails routes -g show` }
output = rails("routes", "-g", "show", allow_failure: true)
assert_equal <<-MESSAGE.strip_heredoc, output
Prefix Verb URI Pattern Controller#Action
cart GET /cart(.:format) cart#show
@ -180,14 +181,14 @@ module ApplicationTests
rails_disk_service GET /rails/active_storage/disk/:encoded_key/*filename(.:format) active_storage/disk#show
MESSAGE
output = Dir.chdir(app_path) { `bin/rails routes -g POST` }
output = rails("routes", "-g", "POST")
assert_equal <<-MESSAGE.strip_heredoc, output
Prefix Verb URI Pattern Controller#Action
POST /cart(.:format) cart#create
rails_direct_uploads POST /rails/active_storage/direct_uploads(.:format) active_storage/direct_uploads#create
MESSAGE
output = Dir.chdir(app_path) { `bin/rails routes -g basketballs` }
output = rails("routes", "-g", "basketballs")
assert_equal " Prefix Verb URI Pattern Controller#Action\n" \
"basketballs GET /basketballs(.:format) basketball#index\n", output
end
@ -200,13 +201,13 @@ module ApplicationTests
end
RUBY
output = Dir.chdir(app_path) { `bin/rails routes -c cart` }
output = rails("routes", "-c", "cart")
assert_equal "Prefix Verb URI Pattern Controller#Action\n cart GET /cart(.:format) cart#show\n", output
output = Dir.chdir(app_path) { `bin/rails routes -c Cart` }
output = rails("routes", "-c", "Cart")
assert_equal "Prefix Verb URI Pattern Controller#Action\n cart GET /cart(.:format) cart#show\n", output
output = Dir.chdir(app_path) { `bin/rails routes -c CartController` }
output = rails("routes", "-c", "CartController")
assert_equal "Prefix Verb URI Pattern Controller#Action\n cart GET /cart(.:format) cart#show\n", output
end
@ -227,10 +228,10 @@ module ApplicationTests
" DELETE /admin/post(.:format) admin/posts#destroy",
" POST /admin/post(.:format) admin/posts#create\n"].join("\n")
output = Dir.chdir(app_path) { `bin/rails routes -c Admin::PostController` }
output = rails("routes", "-c", "Admin::PostController")
assert_equal expected_output, output
output = Dir.chdir(app_path) { `bin/rails routes -c PostController` }
output = rails("routes", "-c", "PostController")
assert_equal expected_output, output
end
@ -240,7 +241,7 @@ module ApplicationTests
end
RUBY
assert_equal <<-MESSAGE.strip_heredoc, Dir.chdir(app_path) { `bin/rails routes` }
assert_equal <<-MESSAGE.strip_heredoc, rails("routes")
Prefix Verb URI Pattern Controller#Action
rails_service_blob GET /rails/active_storage/blobs/:signed_id/*filename(.:format) active_storage/blobs#show
rails_blob_variation GET /rails/active_storage/variants/:signed_blob_id/:variation_key/*filename(.:format) active_storage/variants#show
@ -279,43 +280,37 @@ module ApplicationTests
end
RUBY
output = Dir.chdir(app_path) { `bin/rails log_something RAILS_ENV=production && cat log/production.log` }
assert_match "Sample log message", output
rails "log_something", "RAILS_ENV=production"
assert_match "Sample log message", File.read("#{app_path}/log/production.log")
end
def test_loading_specific_fixtures
Dir.chdir(app_path) do
`bin/rails generate model user username:string password:string;
bin/rails generate model product name:string;
bin/rails db:migrate`
end
rails "generate", "model", "user", "username:string", "password:string"
rails "generate", "model", "product", "name:string"
rails "db:migrate"
require "#{rails_root}/config/environment"
# loading a specific fixture
errormsg = Dir.chdir(app_path) { `bin/rails db:fixtures:load FIXTURES=products` }
assert $?.success?, errormsg
rails "db:fixtures:load", "FIXTURES=products"
assert_equal 2, ::AppTemplate::Application::Product.count
assert_equal 0, ::AppTemplate::Application::User.count
end
def test_loading_only_yml_fixtures
Dir.chdir(app_path) do
`bin/rails db:migrate`
end
rails "db:migrate"
app_file "test/fixtures/products.csv", ""
require "#{rails_root}/config/environment"
errormsg = Dir.chdir(app_path) { `bin/rails db:fixtures:load` }
assert $?.success?, errormsg
rails "db:fixtures:load"
end
def test_scaffold_tests_pass_by_default
rails "generate", "scaffold", "user", "username:string", "password:string"
output = Dir.chdir(app_path) do
`bin/rails generate scaffold user username:string password:string;
RAILS_ENV=test bin/rails db:migrate test`
`RAILS_ENV=test bin/rails db:migrate test`
end
assert_match(/7 runs, 9 assertions, 0 failures, 0 errors/, output)
@ -332,9 +327,9 @@ module ApplicationTests
end
RUBY
rails "generate", "scaffold", "user", "username:string", "password:string"
output = Dir.chdir(app_path) do
`bin/rails generate scaffold user username:string password:string;
RAILS_ENV=test bin/rails db:migrate test`
`RAILS_ENV=test bin/rails db:migrate test`
end
assert_match(/5 runs, 7 assertions, 0 failures, 0 errors/, output)
@ -342,11 +337,11 @@ module ApplicationTests
end
def test_scaffold_with_references_columns_tests_pass_by_default
rails "generate", "model", "Product"
rails "generate", "model", "Cart"
rails "generate", "scaffold", "LineItems", "product:references", "cart:belongs_to"
output = Dir.chdir(app_path) do
`bin/rails generate model Product;
bin/rails generate model Cart;
bin/rails generate scaffold LineItems product:references cart:belongs_to;
RAILS_ENV=test bin/rails db:migrate test`
`RAILS_ENV=test bin/rails db:migrate test`
end
assert_match(/7 runs, 9 assertions, 0 failures, 0 errors/, output)
@ -355,53 +350,45 @@ module ApplicationTests
def test_db_test_prepare_when_using_sql_format
add_to_config "config.active_record.schema_format = :sql"
output = Dir.chdir(app_path) do
`bin/rails generate scaffold user username:string;
bin/rails db:migrate;
bin/rails db:test:prepare 2>&1 --trace`
rails "generate", "scaffold", "user", "username:string"
rails "db:migrate"
output = with_rails_env("test") do
rails "db:test:prepare", "--trace"
end
assert_match(/Execute db:test:load_structure/, output)
end
def test_rake_dump_structure_should_respect_db_structure_env_variable
Dir.chdir(app_path) do
# ensure we have a schema_migrations table to dump
`bin/rails db:migrate db:structure:dump SCHEMA=db/my_structure.sql`
end
# ensure we have a schema_migrations table to dump
rails "db:migrate", "db:structure:dump", "SCHEMA=db/my_structure.sql"
assert File.exist?(File.join(app_path, "db", "my_structure.sql"))
end
def test_rake_dump_structure_should_be_called_twice_when_migrate_redo
add_to_config "config.active_record.schema_format = :sql"
output = Dir.chdir(app_path) do
`bin/rails g model post title:string;
bin/rails db:migrate:redo 2>&1 --trace;`
end
rails "g", "model", "post", "title:string"
output = rails("db:migrate:redo", "--trace")
# expect only Invoke db:structure:dump (first_time)
assert_no_match(/^\*\* Invoke db:structure:dump\s+$/, output)
end
def test_rake_dump_schema_cache
Dir.chdir(app_path) do
`bin/rails generate model post title:string;
bin/rails generate model product name:string;
bin/rails db:migrate db:schema:cache:dump`
end
rails "generate", "model", "post", "title:string"
rails "generate", "model", "product", "name:string"
rails "db:migrate", "db:schema:cache:dump"
assert File.exist?(File.join(app_path, "db", "schema_cache.yml"))
end
def test_rake_clear_schema_cache
Dir.chdir(app_path) do
`bin/rails db:schema:cache:dump db:schema:cache:clear`
end
rails "db:schema:cache:dump", "db:schema:cache:clear"
assert !File.exist?(File.join(app_path, "db", "schema_cache.yml"))
end
def test_copy_templates
Dir.chdir(app_path) do
`bin/rails app:templates:copy`
rails "app:templates:copy"
%w(controller mailer scaffold).each do |dir|
assert File.exist?(File.join(app_path, "lib", "templates", "erb", dir))
end
@ -415,10 +402,7 @@ module ApplicationTests
app_file "config/initializers/dummy.rb", "puts 'Hello, World!'"
app_file "template.rb", ""
output = Dir.chdir(app_path) do
`bin/rails app:template LOCATION=template.rb`
end
output = rails("app:template", "LOCATION=template.rb")
assert_match(/Hello, World!/, output)
end
end

View File

@ -26,22 +26,19 @@ module ApplicationTests
end
def test_should_include_runner_in_shebang_line_in_help_without_option
assert_match "/rails runner", Dir.chdir(app_path) { `bin/rails runner` }
assert_match "/rails runner", rails("runner", allow_failure: true)
end
def test_should_include_runner_in_shebang_line_in_help
assert_match "/rails runner", Dir.chdir(app_path) { `bin/rails runner --help` }
assert_match "/rails runner", rails("runner", "--help")
end
def test_should_run_ruby_statement
assert_match "42", Dir.chdir(app_path) { `bin/rails runner "puts User.count"` }
assert_match "42", rails("runner", "puts User.count")
end
def test_should_set_argv_when_running_code
output = Dir.chdir(app_path) {
# Both long and short args, at start and end of ARGV
`bin/rails runner "puts ARGV.join(',')" --foo a1 -b a2 a3 --moo`
}
output = rails("runner", "puts ARGV.join(',')", "--foo", "a1", "-b", "a2", "a3", "--moo")
assert_equal "--foo,a1,-b,a2,a3,--moo", output.chomp
end
@ -50,7 +47,7 @@ module ApplicationTests
puts User.count
SCRIPT
assert_match "42", Dir.chdir(app_path) { `bin/rails runner "bin/count_users.rb"` }
assert_match "42", rails("runner", "bin/count_users.rb")
end
def test_no_minitest_loaded_in_production_mode
@ -67,7 +64,7 @@ module ApplicationTests
puts $0
SCRIPT
assert_match "bin/dollar0.rb", Dir.chdir(app_path) { `bin/rails runner "bin/dollar0.rb"` }
assert_match "bin/dollar0.rb", rails("runner", "bin/dollar0.rb")
end
def test_should_set_dollar_program_name_to_file
@ -75,7 +72,7 @@ module ApplicationTests
puts $PROGRAM_NAME
SCRIPT
assert_match "bin/program_name.rb", Dir.chdir(app_path) { `bin/rails runner "bin/program_name.rb"` }
assert_match "bin/program_name.rb", rails("runner", "bin/program_name.rb")
end
def test_passes_extra_args_to_file
@ -83,7 +80,7 @@ module ApplicationTests
p ARGV
SCRIPT
assert_match %w( a b ).to_s, Dir.chdir(app_path) { `bin/rails runner "bin/program_name.rb" a b` }
assert_match %w( a b ).to_s, rails("runner", "bin/program_name.rb", "a", "b")
end
def test_should_run_stdin
@ -101,34 +98,34 @@ module ApplicationTests
end
RUBY
assert_match "true", Dir.chdir(app_path) { `bin/rails runner "puts Rails.application.config.ran"` }
assert_match "true", rails("runner", "puts Rails.application.config.ran")
end
def test_default_environment
assert_match "development", Dir.chdir(app_path) { `bin/rails runner "puts Rails.env"` }
assert_match "development", rails("runner", "puts Rails.env")
end
def test_runner_detects_syntax_errors
output = Dir.chdir(app_path) { `bin/rails runner "puts 'hello world" 2>&1` }
output = rails("runner", "puts 'hello world", allow_failure: true)
assert_not $?.success?
assert_match "unterminated string meets end of file", output
end
def test_runner_detects_bad_script_name
output = Dir.chdir(app_path) { `bin/rails runner "iuiqwiourowe" 2>&1` }
output = rails("runner", "iuiqwiourowe", allow_failure: true)
assert_not $?.success?
assert_match "undefined local variable or method `iuiqwiourowe' for", output
end
def test_environment_with_rails_env
with_rails_env "production" do
assert_match "production", Dir.chdir(app_path) { `bin/rails runner "puts Rails.env"` }
assert_match "production", rails("runner", "puts Rails.env")
end
end
def test_environment_with_rack_env
with_rack_env "production" do
assert_match "production", Dir.chdir(app_path) { `bin/rails runner "puts Rails.env"` }
assert_match "production", rails("runner", "puts Rails.env")
end
end
end

View File

@ -59,7 +59,7 @@ module ApplicationTests
def; end
RUBY
error = capture(:stderr) { run_test_command("test/models/error_test.rb") }
error = capture(:stderr) { run_test_command("test/models/error_test.rb", stderr: true) }
assert_match "syntax error", error
end
@ -91,13 +91,11 @@ module ApplicationTests
create_test_file :unit, "baz_unit"
create_test_file :controllers, "foobar_controller"
Dir.chdir(app_path) do
`bin/rails test:units`.tap do |output|
assert_match "FooTest", output
assert_match "BarHelperTest", output
assert_match "BazUnitTest", output
assert_match "3 runs, 3 assertions, 0 failures", output
end
rails("test:units").tap do |output|
assert_match "FooTest", output
assert_match "BarHelperTest", output
assert_match "BazUnitTest", output
assert_match "3 runs, 3 assertions, 0 failures", output
end
end
@ -140,13 +138,11 @@ module ApplicationTests
create_test_file :functional, "baz_functional"
create_test_file :models, "foo"
Dir.chdir(app_path) do
`bin/rails test:functionals`.tap do |output|
assert_match "FooMailerTest", output
assert_match "BarControllerTest", output
assert_match "BazFunctionalTest", output
assert_match "3 runs, 3 assertions, 0 failures", output
end
rails("test:functionals").tap do |output|
assert_match "FooMailerTest", output
assert_match "BarControllerTest", output
assert_match "BazFunctionalTest", output
assert_match "3 runs, 3 assertions, 0 failures", output
end
end
@ -524,11 +520,11 @@ module ApplicationTests
create_test_file :models, "post", pass: false
assert_match(/Interrupt/,
capture(:stderr) { run_test_command("test/models/post_test.rb --fail-fast") })
capture(:stderr) { run_test_command("test/models/post_test.rb --fail-fast", stderr: true) })
end
def test_raise_error_when_specified_file_does_not_exist
error = capture(:stderr) { run_test_command("test/not_exists.rb") }
error = capture(:stderr) { run_test_command("test/not_exists.rb", stderr: true) }
assert_match(%r{cannot load such file.+test/not_exists\.rb}, error)
end
@ -554,14 +550,16 @@ module ApplicationTests
def test_rails_db_create_all_restores_db_connection
create_test_file :models, "account"
output = Dir.chdir(app_path) { `bin/rails db:create:all db:migrate && echo ".tables" | rails dbconsole` }
rails "db:create:all", "db:migrate"
output = Dir.chdir(app_path) { `echo ".tables" | rails dbconsole` }
assert_match "ar_internal_metadata", output, "tables should be dumped"
end
def test_rails_db_create_all_restores_db_connection_after_drop
create_test_file :models, "account"
Dir.chdir(app_path) { `bin/rails db:create:all` } # create all to avoid warnings
output = Dir.chdir(app_path) { `bin/rails db:drop:all db:create:all db:migrate && echo ".tables" | rails dbconsole` }
rails "db:create:all" # create all to avoid warnings
rails "db:drop:all", "db:create:all", "db:migrate"
output = Dir.chdir(app_path) { `echo ".tables" | rails dbconsole` }
assert_match "ar_internal_metadata", output, "tables should be dumped"
end
@ -601,7 +599,7 @@ module ApplicationTests
end
RUBY
assert_match(/warning: assigned but unused variable/,
capture(:stderr) { run_test_command("test/models/warnings_test.rb -w") })
capture(:stderr) { run_test_command("test/models/warnings_test.rb -w", stderr: true) })
end
def test_reset_sessions_before_rollback_on_system_tests
@ -679,12 +677,12 @@ module ApplicationTests
end
private
def run_test_command(arguments = "test/unit/test_test.rb")
Dir.chdir(app_path) { `bin/rails t #{arguments}` }
def run_test_command(arguments = "test/unit/test_test.rb", **opts)
rails "t", *Shellwords.split(arguments), allow_failure: true, **opts
end
def create_model_with_fixture
script "generate model user name:string"
rails "generate", "model", "user", "name:string"
app_file "test/fixtures/users.yml", <<-YAML.strip_heredoc
vampire:
@ -755,17 +753,17 @@ module ApplicationTests
end
def create_scaffold
script "generate scaffold user name:string"
Dir.chdir(app_path) { File.exist?("app/models/user.rb") }
rails "generate", "scaffold", "user", "name:string"
assert File.exist?("#{app_path}/app/models/user.rb")
run_migration
end
def create_controller
script "generate controller admin/dashboard index"
rails "generate", "controller", "admin/dashboard", "index"
end
def run_migration
Dir.chdir(app_path) { `bin/rails db:migrate` }
rails "db:migrate"
end
end
end

View File

@ -102,7 +102,7 @@ module ApplicationTests
end
test "ruby schema migrations" do
output = script("generate model user name:string")
output = rails("generate", "model", "user", "name:string")
version = output.match(/(\d+)_create_users\.rb/)[1]
app_file "test/models/user_test.rb", <<-RUBY
@ -139,7 +139,7 @@ module ApplicationTests
end
test "sql structure migrations" do
output = script("generate model user name:string")
output = rails("generate", "model", "user", "name:string")
version = output.match(/(\d+)_create_users\.rb/)[1]
app_file "test/models/user_test.rb", <<-RUBY
@ -178,7 +178,7 @@ module ApplicationTests
end
test "sql structure migrations when adding column to existing table" do
output_1 = script("generate model user name:string")
output_1 = rails("generate", "model", "user", "name:string")
version_1 = output_1.match(/(\d+)_create_users\.rb/)[1]
app_file "test/models/user_test.rb", <<-RUBY
@ -203,7 +203,7 @@ module ApplicationTests
assert_successful_test_run("models/user_test.rb")
output_2 = script("generate migration add_email_to_users")
output_2 = rails("generate", "migration", "add_email_to_users")
version_2 = output_2.match(/(\d+)_add_email_to_users\.rb/)[1]
app_file "test/models/user_test.rb", <<-RUBY
@ -231,7 +231,7 @@ module ApplicationTests
# For now, the user has to synchronize the schema manually.
# This test-case serves as a reminder for this use-case.
test "manually synchronize test schema after rollback" do
output = script("generate model user name:string")
output = rails("generate", "model", "user", "name:string")
version = output.match(/(\d+)_create_users\.rb/)[1]
app_file "test/models/user_test.rb", <<-RUBY
@ -265,7 +265,7 @@ module ApplicationTests
assert_successful_test_run "models/user_test.rb"
Dir.chdir(app_path) { `bin/rails db:test:prepare` }
rails "db:test:prepare"
assert_unsuccessful_run "models/user_test.rb", <<-ASSERTION
Expected: ["id", "name"]
@ -274,7 +274,7 @@ Expected: ["id", "name"]
end
test "hooks for plugins" do
output = script("generate model user name:string")
output = rails("generate", "model", "user", "name:string")
version = output.match(/(\d+)_create_users\.rb/)[1]
app_file "lib/tasks/hooks.rake", <<-RUBY
@ -334,7 +334,7 @@ Expected: ["id", "name"]
end
def run_test_file(name, options = {})
Dir.chdir(app_path) { `bin/rails test "#{app_path}/test/#{name}" 2>&1` }
rails "test", "#{app_path}/test/#{name}", allow_failure: true
end
end
end

View File

@ -15,12 +15,12 @@ class VersionTest < ActiveSupport::TestCase
end
test "command works" do
output = Dir.chdir(app_path) { `bin/rails version` }
output = rails("version")
assert_equal "Rails #{Rails.gem_version}\n", output
end
test "short-cut alias works" do
output = Dir.chdir(app_path) { `bin/rails -v` }
output = rails("-v")
assert_equal "Rails #{Rails.gem_version}\n", output
end
end

View File

@ -1,11 +1,12 @@
# frozen_string_literal: true
require "isolation/abstract_unit"
require "env_helpers"
require "rails/command"
require "rails/commands/secrets/secrets_command"
class Rails::Command::SecretsCommandTest < ActiveSupport::TestCase
include ActiveSupport::Testing::Isolation
include ActiveSupport::Testing::Isolation, EnvHelpers
def setup
build_app
@ -36,14 +37,16 @@ class Rails::Command::SecretsCommandTest < ActiveSupport::TestCase
private
def run_edit_command(editor: "cat")
Dir.chdir(app_path) { `EDITOR="#{editor}" bin/rails secrets:edit` }
switch_env("EDITOR", editor) do
rails "secrets:edit"
end
end
def run_show_command
Dir.chdir(app_path) { `bin/rails secrets:show` }
rails "secrets:show"
end
def run_setup_command
Dir.chdir(app_path) { `bin/rails secrets:setup` }
rails "secrets:setup"
end
end

View File

@ -236,10 +236,88 @@ module TestHelpers
end
end
def script(script)
Dir.chdir(app_path) do
`#{Gem.ruby} #{app_path}/bin/rails #{script}`
# Invoke a bin/rails command inside the app
#
# allow_failures:: true to return normally if the command exits with
# a non-zero status. By default, this method will raise.
# stderr:: true to pass STDERR output straight to the "real" STDERR.
# By default, the STDERR and STDOUT of the process will be
# combined in the returned string.
# fork:: false to not use fork even when it's available. By default,
# when possible, the command is executed in a fork of the current
# process, avoiding the need to load core Rails libraries anew.
def rails(*args, allow_failure: false, stderr: false, fork: true)
args = args.flatten
command = "bin/rails #{Shellwords.join args}#{' 2>&1' unless stderr}"
# Don't fork if the environment has disabled it
fork = false if ENV["NO_FORK"]
# Don't fork if the runtime isn't able to
fork = false if !Process.respond_to?(:fork)
# Don't fork if we're re-invoking minitest
fork = false if args.first == "t" || args.grep(/\Atest(:|\z)/).any?
if fork
out_read, out_write = IO.pipe
if stderr
err_read, err_write = IO.pipe
else
err_write = out_write
end
pid = fork do
out_read.close
err_read.close if err_read
$stdin.reopen(File::NULL, "r")
$stdout.reopen(out_write)
$stderr.reopen(err_write)
at_exit do
case $!
when SystemExit
exit! $!.status
when nil
exit! 0
else
err_write.puts "#{$!.class}: #{$!}"
exit! 1
end
end
Rails.instance_variable_set :@_env, nil
$-v = $-w = false
Dir.chdir app_path unless Dir.pwd == app_path
ARGV.replace(args)
load "./bin/rails"
exit! 0
end
out_write.close
if err_read
err_write.close
$stderr.write err_read.read
end
output = out_read.read
Process.waitpid pid
else
output = `cd #{app_path}; #{command}`
end
raise "rails command failed (#{$?.exitstatus}): #{command}\n#{output}" unless allow_failure || $?.success?
output
end
def add_to_top_of_config(str)

View File

@ -108,7 +108,7 @@ class Rails::SecretsTest < ActiveSupport::TestCase
config.dereferenced_secret = Rails.application.secrets.some_secret
end_of_config
assert_equal "yeah yeah\n", `bin/rails runner -e production "puts Rails.application.config.dereferenced_secret"`
assert_equal "yeah yeah\n", rails("runner", "-e", "production", "puts Rails.application.config.dereferenced_secret", fork: false)
end
end
@ -141,7 +141,7 @@ class Rails::SecretsTest < ActiveSupport::TestCase
assert_match(/production:\n\s*api_key: 00112233445566778899aabbccddeeff…\n/, File.read(tmp_path))
end
assert_equal "00112233445566778899aabbccddeeff…\n", `bin/rails runner -e production "puts Rails.application.secrets.api_key"`
assert_equal "00112233445566778899aabbccddeeff…\n", rails("runner", "-e", "production", "puts Rails.application.secrets.api_key", fork: false)
end
end
@ -158,7 +158,7 @@ class Rails::SecretsTest < ActiveSupport::TestCase
assert_equal(secrets.dup.force_encoding(Encoding::ASCII_8BIT), IO.binread(tmp_path))
end
assert_equal "00112233445566778899aabbccddeeff…\n", `bin/rails runner -e production "puts Rails.application.secrets.api_key"`
assert_equal "00112233445566778899aabbccddeeff…\n", rails("runner", "-e", "production", "puts Rails.application.secrets.api_key", fork: false)
end
end