aboutsummaryrefslogtreecommitdiffstats
path: root/railties/test/application/test_test.rb
diff options
context:
space:
mode:
Diffstat (limited to 'railties/test/application/test_test.rb')
-rw-r--r--railties/test/application/test_test.rb345
1 files changed, 345 insertions, 0 deletions
diff --git a/railties/test/application/test_test.rb b/railties/test/application/test_test.rb
new file mode 100644
index 0000000000..fb43bebfbe
--- /dev/null
+++ b/railties/test/application/test_test.rb
@@ -0,0 +1,345 @@
+# frozen_string_literal: true
+
+require "isolation/abstract_unit"
+
+module ApplicationTests
+ class TestTest < ActiveSupport::TestCase
+ include ActiveSupport::Testing::Isolation
+
+ def setup
+ @old = ENV["PARALLEL_WORKERS"]
+ ENV["PARALLEL_WORKERS"] = "0"
+
+ build_app
+ end
+
+ def teardown
+ ENV["PARALLEL_WORKERS"] = @old
+
+ teardown_app
+ end
+
+ test "simple successful test" do
+ app_file "test/unit/foo_test.rb", <<-RUBY
+ require 'test_helper'
+
+ class FooTest < ActiveSupport::TestCase
+ def test_truth
+ assert true
+ end
+ end
+ RUBY
+
+ assert_successful_test_run "unit/foo_test.rb"
+ end
+
+ test "after_run" do
+ app_file "test/unit/foo_test.rb", <<-RUBY
+ require 'test_helper'
+
+ Minitest.after_run { puts "WORLD" }
+ Minitest.after_run { puts "HELLO" }
+
+ class FooTest < ActiveSupport::TestCase
+ def test_truth
+ assert true
+ end
+ end
+ RUBY
+
+ result = assert_successful_test_run "unit/foo_test.rb"
+ assert_equal ["HELLO", "WORLD"], result.scan(/HELLO|WORLD/) # only once and in correct order
+ end
+
+ test "simple failed test" do
+ app_file "test/unit/foo_test.rb", <<-RUBY
+ require 'test_helper'
+
+ class FooTest < ActiveSupport::TestCase
+ def test_truth
+ assert false
+ end
+ end
+ RUBY
+
+ assert_unsuccessful_run "unit/foo_test.rb", "Failure:\nFooTest#test_truth"
+ end
+
+ test "integration test" do
+ controller "posts", <<-RUBY
+ class PostsController < ActionController::Base
+ end
+ RUBY
+
+ app_file "app/views/posts/index.html.erb", <<-HTML
+ Posts#index
+ HTML
+
+ app_file "test/integration/posts_test.rb", <<-RUBY
+ require 'test_helper'
+
+ class PostsTest < ActionDispatch::IntegrationTest
+ def test_index
+ get '/posts'
+ assert_response :success
+ assert_includes @response.body, 'Posts#index'
+ end
+ end
+ RUBY
+
+ assert_successful_test_run "integration/posts_test.rb"
+ end
+
+ test "enable full backtraces on test failures" do
+ app_file "test/unit/failing_test.rb", <<-RUBY
+ require 'test_helper'
+
+ class FailingTest < ActiveSupport::TestCase
+ def test_failure
+ raise "fail"
+ end
+ end
+ RUBY
+
+ output = run_test_file("unit/failing_test.rb", env: { "BACKTRACE" => "1" })
+ assert_match %r{test/unit/failing_test\.rb}, output
+ assert_match %r{test/unit/failing_test\.rb:4}, output
+ end
+
+ test "ruby schema migrations" do
+ output = rails("generate", "model", "user", "name:string")
+ version = output.match(/(\d+)_create_users\.rb/)[1]
+
+ app_file "test/models/user_test.rb", <<-RUBY
+ require 'test_helper'
+
+ class UserTest < ActiveSupport::TestCase
+ test "user" do
+ User.create! name: "Jon"
+ end
+ end
+ RUBY
+ app_file "db/schema.rb", ""
+
+ assert_unsuccessful_run "models/user_test.rb", "Migrations are pending"
+
+ app_file "db/schema.rb", <<-RUBY
+ ActiveRecord::Schema.define(version: #{version}) do
+ create_table :users do |t|
+ t.string :name
+ end
+ end
+ RUBY
+
+ app_file "config/initializers/disable_maintain_test_schema.rb", <<-RUBY
+ Rails.application.config.active_record.maintain_test_schema = false
+ RUBY
+
+ assert_unsuccessful_run "models/user_test.rb", "Could not find table 'users'"
+
+ File.delete "#{app_path}/config/initializers/disable_maintain_test_schema.rb"
+
+ result = assert_successful_test_run("models/user_test.rb")
+ assert_not_includes result, "create_table(:users)"
+ end
+
+ test "sql structure migrations" do
+ output = rails("generate", "model", "user", "name:string")
+ version = output.match(/(\d+)_create_users\.rb/)[1]
+
+ app_file "test/models/user_test.rb", <<-RUBY
+ require 'test_helper'
+
+ class UserTest < ActiveSupport::TestCase
+ test "user" do
+ User.create! name: "Jon"
+ end
+ end
+ RUBY
+
+ app_file "db/structure.sql", ""
+ app_file "config/initializers/enable_sql_schema_format.rb", <<-RUBY
+ Rails.application.config.active_record.schema_format = :sql
+ RUBY
+
+ assert_unsuccessful_run "models/user_test.rb", "Migrations are pending"
+
+ app_file "db/structure.sql", <<-SQL
+ CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL);
+ CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version");
+ CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255));
+ INSERT INTO schema_migrations (version) VALUES ('#{version}');
+ SQL
+
+ app_file "config/initializers/disable_maintain_test_schema.rb", <<-RUBY
+ Rails.application.config.active_record.maintain_test_schema = false
+ RUBY
+
+ assert_unsuccessful_run "models/user_test.rb", "Could not find table 'users'"
+
+ File.delete "#{app_path}/config/initializers/disable_maintain_test_schema.rb"
+
+ assert_successful_test_run("models/user_test.rb")
+ end
+
+ test "sql structure migrations when adding column to existing table" do
+ 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
+ require 'test_helper'
+ class UserTest < ActiveSupport::TestCase
+ test "user" do
+ User.create! name: "Jon"
+ end
+ end
+ RUBY
+
+ app_file "config/initializers/enable_sql_schema_format.rb", <<-RUBY
+ Rails.application.config.active_record.schema_format = :sql
+ RUBY
+
+ app_file "db/structure.sql", <<-SQL
+ CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL);
+ CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version");
+ CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255));
+ INSERT INTO schema_migrations (version) VALUES ('#{version_1}');
+ SQL
+
+ assert_successful_test_run("models/user_test.rb")
+
+ 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
+ require 'test_helper'
+
+ class UserTest < ActiveSupport::TestCase
+ test "user" do
+ User.create! name: "Jon", email: "jon@doe.com"
+ end
+ end
+ RUBY
+
+ app_file "db/structure.sql", <<-SQL
+ CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL);
+ CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version");
+ CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255), "email" varchar(255));
+ INSERT INTO schema_migrations (version) VALUES ('#{version_1}');
+ INSERT INTO schema_migrations (version) VALUES ('#{version_2}');
+ SQL
+
+ assert_successful_test_run("models/user_test.rb")
+ end
+
+ # TODO: would be nice if we could detect the schema change automatically.
+ # 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 = rails("generate", "model", "user", "name:string")
+ version = output.match(/(\d+)_create_users\.rb/)[1]
+
+ app_file "test/models/user_test.rb", <<-RUBY
+ require 'test_helper'
+
+ class UserTest < ActiveSupport::TestCase
+ test "user" do
+ assert_equal ["id", "name"], User.columns_hash.keys
+ end
+ end
+ RUBY
+ app_file "db/schema.rb", <<-RUBY
+ ActiveRecord::Schema.define(version: #{version}) do
+ create_table :users do |t|
+ t.string :name
+ end
+ end
+ RUBY
+
+ assert_successful_test_run "models/user_test.rb"
+
+ # Simulate `db:rollback` + edit of the migration file + `db:migrate`
+ app_file "db/schema.rb", <<-RUBY
+ ActiveRecord::Schema.define(version: #{version}) do
+ create_table :users do |t|
+ t.string :name
+ t.integer :age
+ end
+ end
+ RUBY
+
+ assert_successful_test_run "models/user_test.rb"
+
+ rails "db:test:prepare"
+
+ assert_unsuccessful_run "models/user_test.rb", <<-ASSERTION
+Expected: ["id", "name"]
+ Actual: ["id", "name", "age"]
+ ASSERTION
+ end
+
+ test "hooks for plugins" do
+ output = rails("generate", "model", "user", "name:string")
+ version = output.match(/(\d+)_create_users\.rb/)[1]
+
+ app_file "lib/tasks/hooks.rake", <<-RUBY
+ task :before_hook do
+ has_user_table = ActiveRecord::Base.connection.table_exists?('users')
+ puts "before: " + has_user_table.to_s
+ end
+
+ task :after_hook do
+ has_user_table = ActiveRecord::Base.connection.table_exists?('users')
+ puts "after: " + has_user_table.to_s
+ end
+
+ Rake::Task["db:test:prepare"].enhance [:before_hook] do
+ Rake::Task[:after_hook].invoke
+ end
+ RUBY
+ app_file "test/models/user_test.rb", <<-RUBY
+ require 'test_helper'
+ class UserTest < ActiveSupport::TestCase
+ test "user" do
+ User.create! name: "Jon"
+ end
+ end
+ RUBY
+
+ # Simulate `db:migrate`
+ app_file "db/schema.rb", <<-RUBY
+ ActiveRecord::Schema.define(version: #{version}) do
+ create_table :users do |t|
+ t.string :name
+ end
+ end
+ RUBY
+
+ output = assert_successful_test_run "models/user_test.rb"
+ assert_includes output, "before: false\nafter: true"
+
+ # running tests again won't trigger a schema update
+ output = assert_successful_test_run "models/user_test.rb"
+ assert_not_includes output, "before:"
+ assert_not_includes output, "after:"
+ end
+
+ private
+ def assert_unsuccessful_run(name, message)
+ result = run_test_file(name)
+ assert_not_equal 0, $?.to_i
+ assert_includes result, message
+ result
+ end
+
+ def assert_successful_test_run(name)
+ result = run_test_file(name)
+ assert_equal 0, $?.to_i, result
+ result
+ end
+
+ def run_test_file(name, options = {})
+ rails "test", "#{app_path}/test/#{name}", allow_failure: true
+ end
+ end
+end