aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml3
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.lock18
-rw-r--r--actioncable/lib/action_cable/subscription_adapter/redis.rb2
-rw-r--r--activejob/test/support/integration/test_case_helpers.rb4
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb20
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb3
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb3
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb3
-rw-r--r--activerecord/lib/active_record/relation.rb3
-rw-r--r--activerecord/lib/active_record/schema_dumper.rb4
-rw-r--r--activerecord/test/cases/adapter_test.rb32
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb10
-rw-r--r--activerecord/test/cases/migration/column_attributes_test.rb20
-rw-r--r--activerecord/test/cases/persistence_test.rb36
-rw-r--r--activerecord/test/cases/relation/where_test.rb19
-rw-r--r--activerecord/test/cases/schema_dumper_test.rb25
-rw-r--r--activerecord/test/cases/timestamp_test.rb22
-rw-r--r--activestorage/.codeclimate.yml7
-rw-r--r--activestorage/test/models/blob_test.rb7
-rw-r--r--activestorage/test/test_helper.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/hash/deep_merge.rb18
-rw-r--r--activesupport/lib/active_support/lazy_load_hooks.rb6
-rw-r--r--activesupport/test/lazy_load_hooks_test.rb13
-rw-r--r--guides/source/active_record_validations.md2
-rw-r--r--guides/source/development_dependencies_install.md81
-rw-r--r--guides/source/upgrading_ruby_on_rails.md9
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/gitignore2
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb2
-rw-r--r--railties/test/generators/app_generator_test.rb119
-rw-r--r--railties/test/generators/plugin_generator_test.rb81
-rw-r--r--railties/test/generators/shared_generator_tests.rb114
33 files changed, 399 insertions, 295 deletions
diff --git a/.travis.yml b/.travis.yml
index 95a9099901..6c7380f050 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -114,7 +114,8 @@ notifications:
on_success: change
on_failure: always
channels:
- - "irc.freenode.org#rails-contrib"
+ # "irc.freenode.org#rails-contrib"
+ - secure: "QFKSOK7xQiWWqTzYfYm0XWoW7idzuxT57MBW9i9EASyRLEPuDwZEubKRP40Y7wPx7ylQd9lp6kJheeLnrDvvTjFbW3sWv9GDRl4WlOU8sG/Kv7MXAASXlDqzyJxxXTtzLeXz2iwY296kOBuKxKxl923eTvEGeocwH02QGo14LpQ="
campfire:
on_success: change
on_failure: always
diff --git a/Gemfile b/Gemfile
index 0b98dc1f75..412cc627b9 100644
--- a/Gemfile
+++ b/Gemfile
@@ -40,7 +40,7 @@ gem "rubocop", ">= 0.47", require: false
gem "rb-inotify", github: "matthewd/rb-inotify", branch: "close-handling", require: false
group :doc do
- gem "sdoc", "> 1.0.0.rc1", "< 2.0"
+ gem "sdoc", github: "robin850/sdoc", branch: "upgrade"
gem "redcarpet", "~> 3.2.3", platforms: :ruby
gem "w3c_validators"
gem "kindlerb", "~> 1.2.0"
diff --git a/Gemfile.lock b/Gemfile.lock
index 2096465a8b..516b4155c1 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -41,6 +41,14 @@ GIT
sprockets-rails (>= 2.0, < 4.0)
tilt (>= 1.1, < 3)
+GIT
+ remote: https://github.com/robin850/sdoc.git
+ revision: 0e340352f3ab2f196c8a8743f83c2ee286e4f71c
+ branch: upgrade
+ specs:
+ sdoc (1.0.0.rc2)
+ rdoc (~> 5.0)
+
PATH
remote: .
specs:
@@ -135,7 +143,7 @@ GEM
bcrypt (3.1.11-x86-mingw32)
beaneater (1.0.0)
benchmark-ips (2.7.2)
- blade (0.7.0)
+ blade (0.7.1)
activesupport (>= 3.0.0)
blade-qunit_adapter (~> 2.0.1)
coffee-script
@@ -145,7 +153,7 @@ GEM
faye
sprockets (>= 3.0)
thin (>= 1.6.0)
- thor (~> 0.19.1)
+ thor (>= 0.19.1)
useragent (~> 0.16.7)
blade-qunit_adapter (2.0.1)
blade-sauce_labs_plugin (0.7.2)
@@ -389,8 +397,6 @@ GEM
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
- sdoc (1.0.0.rc2)
- rdoc (~> 5.0)
selenium-webdriver (3.5.1)
childprocess (~> 0.5)
rubyzip (~> 1.0)
@@ -437,7 +443,7 @@ GEM
daemons (~> 1.0, >= 1.0.9)
eventmachine (~> 1.0, >= 1.0.4)
rack (>= 1, < 3)
- thor (0.19.4)
+ thor (0.20.0)
thread (0.1.7)
thread_safe (0.3.6)
tilt (2.0.8)
@@ -521,7 +527,7 @@ DEPENDENCIES
resque-scheduler
rubocop (>= 0.47)
sass-rails!
- sdoc (> 1.0.0.rc1, < 2.0)
+ sdoc!
sequel
sidekiq
sneakers
diff --git a/actioncable/lib/action_cable/subscription_adapter/redis.rb b/actioncable/lib/action_cable/subscription_adapter/redis.rb
index c64f55f5b7..facea944ff 100644
--- a/actioncable/lib/action_cable/subscription_adapter/redis.rb
+++ b/actioncable/lib/action_cable/subscription_adapter/redis.rb
@@ -10,7 +10,7 @@ module ActionCable
class Redis < Base # :nodoc:
prepend ChannelPrefix
- # Overwrite this factory method for redis connections if you want to use a different Redis library than Redis.
+ # Overwrite this factory method for Redis connections if you want to use a different Redis library than the redis gem.
# This is needed, for example, when using Makara proxies for distributed Redis.
cattr_accessor :redis_connector, default: ->(config) do
::Redis.new(config.slice(:url, :host, :port, :db, :password))
diff --git a/activejob/test/support/integration/test_case_helpers.rb b/activejob/test/support/integration/test_case_helpers.rb
index 9629876a6d..f02a32a38e 100644
--- a/activejob/test/support/integration/test_case_helpers.rb
+++ b/activejob/test/support/integration/test_case_helpers.rb
@@ -1,6 +1,5 @@
# frozen_string_literal: true
-require "active_support/core_ext/string/inflections"
require "support/integration/jobs_manager"
module TestCaseHelpers
@@ -30,8 +29,7 @@ module TestCaseHelpers
end
def adapter_is?(*adapter_class_symbols)
- adapter = ActiveJob::Base.queue_adapter.class.name.demodulize.chomp("Adapter").underscore
- adapter_class_symbols.map(&:to_s).include? adapter
+ adapter_class_symbols.map(&:to_s).include? ActiveJob::Base.queue_adapter_name
end
def wait_for_jobs_to_finish_for(seconds = 60)
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
index 5febb5a59f..4078345abf 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
@@ -10,6 +10,11 @@ module ActiveRecord
# Converts an arel AST to SQL
def to_sql(arel_or_sql_string, binds = [])
+ sql, _ = to_sql_and_binds(arel_or_sql_string, binds)
+ sql
+ end
+
+ def to_sql_and_binds(arel_or_sql_string, binds = []) # :nodoc:
if arel_or_sql_string.respond_to?(:ast)
unless binds.empty?
raise "Passing bind parameters with an arel AST is forbidden. " \
@@ -21,6 +26,7 @@ module ActiveRecord
[arel_or_sql_string.dup.freeze, binds]
end
end
+ private :to_sql_and_binds
# This is used in the StatementCache object. It returns an object that
# can be used to query the database repeatedly.
@@ -39,7 +45,7 @@ module ActiveRecord
# Returns an ActiveRecord::Result instance.
def select_all(arel, name = nil, binds = [], preparable: nil)
arel = arel_from_relation(arel)
- sql, binds = to_sql(arel, binds)
+ sql, binds = to_sql_and_binds(arel, binds)
if !prepared_statements || (arel.is_a?(String) && preparable.nil?)
preparable = false
else
@@ -138,22 +144,22 @@ module ActiveRecord
#
# If the next id was calculated in advance (as in Oracle), it should be
# passed in as +id_value+.
- def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil)
- sql, binds = to_sql(arel)
+ def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
+ sql, binds = to_sql_and_binds(arel, binds)
value = exec_insert(sql, name, binds, pk, sequence_name)
id_value || last_inserted_id(value)
end
alias create insert
# Executes the update statement and returns the number of rows affected.
- def update(arel, name = nil)
- sql, binds = to_sql(arel)
+ def update(arel, name = nil, binds = [])
+ sql, binds = to_sql_and_binds(arel, binds)
exec_update(sql, name, binds)
end
# Executes the delete statement and returns the number of rows affected.
- def delete(arel, name = nil)
- sql, binds = to_sql(arel)
+ def delete(arel, name = nil, binds = [])
+ sql, binds = to_sql_and_binds(arel, binds)
exec_delete(sql, name, binds)
end
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb b/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb
index 41d93c4322..25622e34c8 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb
@@ -95,7 +95,7 @@ module ActiveRecord
def select_all(arel, name = nil, binds = [], preparable: nil)
if @query_cache_enabled && !locked?(arel)
arel = arel_from_relation(arel)
- sql, binds = to_sql(arel, binds)
+ sql, binds = to_sql_and_binds(arel, binds)
cache_sql(sql, name, binds) { super(sql, name, binds, preparable: preparable) }
else
super
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
index 8a9c497918..5915f0db2d 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
@@ -177,8 +177,7 @@ module ActiveRecord
#++
def explain(arel, binds = [])
- sql, binds = to_sql(arel, binds)
- sql = "EXPLAIN #{sql}"
+ sql = "EXPLAIN #{to_sql(arel, binds)}"
start = Time.now
result = exec_query(sql, "EXPLAIN", binds)
elapsed = Time.now - start
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb b/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb
index 0dd4aac463..8db2a645af 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb
@@ -5,8 +5,7 @@ module ActiveRecord
module PostgreSQL
module DatabaseStatements
def explain(arel, binds = [])
- sql, binds = to_sql(arel, binds)
- sql = "EXPLAIN #{sql}"
+ sql = "EXPLAIN #{to_sql(arel, binds)}"
PostgreSQL::ExplainPrettyPrinter.new.pp(exec_query(sql, "EXPLAIN", binds))
end
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
index 8c12cb09bd..10e80179ac 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
@@ -203,8 +203,7 @@ module ActiveRecord
#++
def explain(arel, binds = [])
- sql, binds = to_sql(arel, binds)
- sql = "EXPLAIN QUERY PLAN #{sql}"
+ sql = "EXPLAIN QUERY PLAN #{to_sql(arel, binds)}"
SQLite3::ExplainPrettyPrinter.new.pp(exec_query(sql, "EXPLAIN", []))
end
diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb
index caabad6055..d319978930 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -571,8 +571,7 @@ module ActiveRecord
conn = klass.connection
conn.unprepared_statement {
- sql, _ = conn.to_sql(relation.arel)
- sql
+ conn.to_sql(relation.arel)
}
end
end
diff --git a/activerecord/lib/active_record/schema_dumper.rb b/activerecord/lib/active_record/schema_dumper.rb
index 27a1c89bd1..fd644225ca 100644
--- a/activerecord/lib/active_record/schema_dumper.rb
+++ b/activerecord/lib/active_record/schema_dumper.rb
@@ -243,7 +243,9 @@ HEADER
end
def remove_prefix_and_suffix(table)
- table.gsub(/^(#{@options[:table_name_prefix]})(.+)(#{@options[:table_name_suffix]})$/, "\\2")
+ prefix = Regexp.escape(@options[:table_name_prefix].to_s)
+ suffix = Regexp.escape(@options[:table_name_suffix].to_s)
+ table.sub(/\A#{prefix}(.+)#{suffix}\z/, "\\1")
end
def ignored?(table_name)
diff --git a/activerecord/test/cases/adapter_test.rb b/activerecord/test/cases/adapter_test.rb
index 6e04578576..d7551cd658 100644
--- a/activerecord/test/cases/adapter_test.rb
+++ b/activerecord/test/cases/adapter_test.rb
@@ -227,6 +227,38 @@ module ActiveRecord
result = @connection.select_all("SELECT * FROM posts WHERE id = #{Arel::Nodes::BindParam.new(nil).to_sql}", nil, [[nil, post.id]])
assert_equal expected.to_hash, result.to_hash
end
+
+ def test_insert_update_delete_with_legacy_binds
+ binds = [[nil, 1]]
+ bind_param = Arel::Nodes::BindParam.new(nil)
+
+ id = @connection.insert("INSERT INTO events(id) VALUES (#{bind_param.to_sql})", nil, nil, nil, nil, binds)
+ assert_equal 1, id
+
+ @connection.update("UPDATE events SET title = 'foo' WHERE id = #{bind_param.to_sql}", nil, binds)
+ result = @connection.select_all("SELECT * FROM events WHERE id = #{bind_param.to_sql}", nil, binds)
+ assert_equal({ "id" => 1, "title" => "foo" }, result.first)
+
+ @connection.delete("DELETE FROM events WHERE id = #{bind_param.to_sql}", nil, binds)
+ result = @connection.select_all("SELECT * FROM events WHERE id = #{bind_param.to_sql}", nil, binds)
+ assert_nil result.first
+ end
+
+ def test_insert_update_delete_with_binds
+ binds = [Relation::QueryAttribute.new("id", 1, Type.default_value)]
+ bind_param = Arel::Nodes::BindParam.new(nil)
+
+ id = @connection.insert("INSERT INTO events(id) VALUES (#{bind_param.to_sql})", nil, nil, nil, nil, binds)
+ assert_equal 1, id
+
+ @connection.update("UPDATE events SET title = 'foo' WHERE id = #{bind_param.to_sql}", nil, binds)
+ result = @connection.select_all("SELECT * FROM events WHERE id = #{bind_param.to_sql}", nil, binds)
+ assert_equal({ "id" => 1, "title" => "foo" }, result.first)
+
+ @connection.delete("DELETE FROM events WHERE id = #{bind_param.to_sql}", nil, binds)
+ result = @connection.select_all("SELECT * FROM events WHERE id = #{bind_param.to_sql}", nil, binds)
+ assert_nil result.first
+ end
end
def test_select_methods_passing_a_association_relation
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index 383c7314e1..6bd11a5d81 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -576,8 +576,16 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
end
def test_taking_with_a_number
+ klass = Class.new(Author) do
+ has_many :posts, -> { order(:id) }
+
+ def self.name
+ "Author"
+ end
+ end
+
# taking from unloaded Relation
- bob = Author.find(authors(:bob).id)
+ bob = klass.find(authors(:bob).id)
new_post = bob.posts.build
assert_not bob.posts.loaded?
assert_equal [posts(:misc_by_bob)], bob.posts.take(1)
diff --git a/activerecord/test/cases/migration/column_attributes_test.rb b/activerecord/test/cases/migration/column_attributes_test.rb
index 9200d32caf..be6dc2acb1 100644
--- a/activerecord/test/cases/migration/column_attributes_test.rb
+++ b/activerecord/test/cases/migration/column_attributes_test.rb
@@ -45,11 +45,11 @@ module ActiveRecord
assert_nil TestModel.columns_hash["description"].limit
end
- if current_adapter?(:Mysql2Adapter)
+ if current_adapter?(:Mysql2Adapter, :PostgreSQLAdapter)
def test_unabstracted_database_dependent_types
- add_column :test_models, :intelligence_quotient, :tinyint
+ add_column :test_models, :intelligence_quotient, :smallint
TestModel.reset_column_information
- assert_match(/tinyint/, TestModel.columns_hash["intelligence_quotient"].sql_type)
+ assert_match(/smallint/, TestModel.columns_hash["intelligence_quotient"].sql_type)
end
end
@@ -99,7 +99,21 @@ module ActiveRecord
assert_equal 7, wealth_column.scale
end
+ # Test SQLite3 adapter specifically for decimal types with precision and scale
+ # attributes, since these need to be maintained in schema but aren't actually
+ # used in SQLite3 itself
if current_adapter?(:SQLite3Adapter)
+ def test_change_column_with_new_precision_and_scale
+ connection.add_column "test_models", "wealth", :decimal, precision: 9, scale: 7
+
+ connection.change_column "test_models", "wealth", :decimal, precision: 12, scale: 8
+ TestModel.reset_column_information
+
+ wealth_column = TestModel.columns_hash["wealth"]
+ assert_equal 12, wealth_column.precision
+ assert_equal 8, wealth_column.scale
+ end
+
def test_change_column_preserve_other_column_precision_and_scale
connection.add_column "test_models", "last_name", :string
connection.add_column "test_models", "wealth", :decimal, precision: 9, scale: 7
diff --git a/activerecord/test/cases/persistence_test.rb b/activerecord/test/cases/persistence_test.rb
index c887f54560..170fd02b6f 100644
--- a/activerecord/test/cases/persistence_test.rb
+++ b/activerecord/test/cases/persistence_test.rb
@@ -78,6 +78,16 @@ class PersistenceTest < ActiveRecord::TestCase
assert_equal "2 updated", Topic.find(2).content
end
+ def test_class_level_update_is_affected_by_scoping
+ topic_data = { 1 => { "content" => "1 updated" }, 2 => { "content" => "2 updated" } }
+
+ assert_raise(ActiveRecord::RecordNotFound) do
+ Topic.where("1=0").scoping { Topic.update(topic_data.keys, topic_data.values) }
+ end
+ assert_not_equal "1 updated", Topic.find(1).content
+ assert_not_equal "2 updated", Topic.find(2).content
+ end
+
def test_delete_all
assert Topic.count > 0
@@ -912,13 +922,33 @@ class PersistenceTest < ActiveRecord::TestCase
assert_raise(ActiveRecord::RecordNotFound) { Reply.find(should_be_destroyed_reply.id) }
end
+ def test_class_level_destroy_is_affected_by_scoping
+ should_not_be_destroyed_reply = Reply.create("title" => "hello", "content" => "world")
+ Topic.find(1).replies << should_not_be_destroyed_reply
+
+ assert_raise(ActiveRecord::RecordNotFound) do
+ Topic.where("1=0").scoping { Topic.destroy(1) }
+ end
+ assert_nothing_raised { Topic.find(1) }
+ assert_nothing_raised { Reply.find(should_not_be_destroyed_reply.id) }
+ end
+
def test_class_level_delete
- should_be_destroyed_reply = Reply.create("title" => "hello", "content" => "world")
- Topic.find(1).replies << should_be_destroyed_reply
+ should_not_be_destroyed_reply = Reply.create("title" => "hello", "content" => "world")
+ Topic.find(1).replies << should_not_be_destroyed_reply
Topic.delete(1)
assert_raise(ActiveRecord::RecordNotFound) { Topic.find(1) }
- assert_nothing_raised { Reply.find(should_be_destroyed_reply.id) }
+ assert_nothing_raised { Reply.find(should_not_be_destroyed_reply.id) }
+ end
+
+ def test_class_level_delete_is_affected_by_scoping
+ should_not_be_destroyed_reply = Reply.create("title" => "hello", "content" => "world")
+ Topic.find(1).replies << should_not_be_destroyed_reply
+
+ Topic.where("1=0").scoping { Topic.delete(1) }
+ assert_nothing_raised { Topic.find(1) }
+ assert_nothing_raised { Reply.find(should_not_be_destroyed_reply.id) }
end
def test_create_with_custom_timestamps
diff --git a/activerecord/test/cases/relation/where_test.rb b/activerecord/test/cases/relation/where_test.rb
index 2fe2a67b1c..d95a54a2fe 100644
--- a/activerecord/test/cases/relation/where_test.rb
+++ b/activerecord/test/cases/relation/where_test.rb
@@ -109,6 +109,15 @@ module ActiveRecord
assert_equal expected.to_sql, actual.to_sql
end
+ def test_polymorphic_shallow_where_not
+ treasure = treasures(:sapphire)
+
+ expected = [price_estimates(:diamond), price_estimates(:honda)]
+ actual = PriceEstimate.where.not(estimate_of: treasure)
+
+ assert_equal expected.sort_by(&:id), actual.sort_by(&:id)
+ end
+
def test_polymorphic_nested_array_where
treasure = Treasure.new
treasure.id = 1
@@ -121,6 +130,16 @@ module ActiveRecord
assert_equal expected.to_sql, actual.to_sql
end
+ def test_polymorphic_nested_array_where_not
+ treasure = treasures(:diamond)
+ car = cars(:honda)
+
+ expected = [price_estimates(:sapphire_1), price_estimates(:sapphire_2)]
+ actual = PriceEstimate.where.not(estimate_of: [treasure, car])
+
+ assert_equal expected.sort_by(&:id), actual.sort_by(&:id)
+ end
+
def test_polymorphic_array_where_multiple_types
treasure_1 = treasures(:diamond)
treasure_2 = treasures(:sapphire)
diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb
index 01ec3e06ad..eb9b257da9 100644
--- a/activerecord/test/cases/schema_dumper_test.rb
+++ b/activerecord/test/cases/schema_dumper_test.rb
@@ -400,6 +400,31 @@ class SchemaDumperTest < ActiveRecord::TestCase
$stdout = original
end
+ def test_schema_dump_with_table_name_prefix_and_suffix_regexp_escape
+ original, $stdout = $stdout, StringIO.new
+ ActiveRecord::Base.table_name_prefix = "foo$"
+ ActiveRecord::Base.table_name_suffix = "$bar"
+
+ migration = CreateDogMigration.new
+ migration.migrate(:up)
+
+ output = perform_schema_dump
+ assert_no_match %r{create_table "foo\$.+\$bar"}, output
+ assert_no_match %r{add_index "foo\$.+\$bar"}, output
+ assert_no_match %r{create_table "schema_migrations"}, output
+ assert_no_match %r{create_table "ar_internal_metadata"}, output
+
+ if ActiveRecord::Base.connection.supports_foreign_keys?
+ assert_no_match %r{add_foreign_key "foo\$.+\$bar"}, output
+ assert_no_match %r{add_foreign_key "[^"]+", "foo\$.+\$bar"}, output
+ end
+ ensure
+ migration.migrate(:down)
+
+ ActiveRecord::Base.table_name_suffix = ActiveRecord::Base.table_name_prefix = ""
+ $stdout = original
+ end
+
def test_schema_dump_with_table_name_prefix_and_ignoring_tables
original, $stdout = $stdout, StringIO.new
diff --git a/activerecord/test/cases/timestamp_test.rb b/activerecord/test/cases/timestamp_test.rb
index ba0bc6c45d..5d3e2a175c 100644
--- a/activerecord/test/cases/timestamp_test.rb
+++ b/activerecord/test/cases/timestamp_test.rb
@@ -446,17 +446,6 @@ class TimestampTest < ActiveRecord::TestCase
toy = Toy.first
assert_equal ["created_at", "updated_at"], toy.send(:all_timestamp_attributes_in_model)
end
-
- def test_index_is_created_for_both_timestamps
- ActiveRecord::Base.connection.create_table(:foos, force: true) do |t|
- t.timestamps null: true, index: true
- end
-
- indexes = ActiveRecord::Base.connection.indexes("foos")
- assert_equal ["created_at", "updated_at"], indexes.flat_map(&:columns).sort
- ensure
- ActiveRecord::Base.connection.drop_table(:foos)
- end
end
class TimestampsWithoutTransactionTest < ActiveRecord::TestCase
@@ -475,4 +464,15 @@ class TimestampsWithoutTransactionTest < ActiveRecord::TestCase
assert_nil post.updated_at
end
end
+
+ def test_index_is_created_for_both_timestamps
+ ActiveRecord::Base.connection.create_table(:foos, force: true) do |t|
+ t.timestamps null: true, index: true
+ end
+
+ indexes = ActiveRecord::Base.connection.indexes("foos")
+ assert_equal ["created_at", "updated_at"], indexes.flat_map(&:columns).sort
+ ensure
+ ActiveRecord::Base.connection.drop_table(:foos)
+ end
end
diff --git a/activestorage/.codeclimate.yml b/activestorage/.codeclimate.yml
deleted file mode 100644
index 18f3dbb7b5..0000000000
--- a/activestorage/.codeclimate.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-engines:
- rubocop:
- enabled: true
-
-ratings:
- paths:
- - "**.rb"
diff --git a/activestorage/test/models/blob_test.rb b/activestorage/test/models/blob_test.rb
index 1c50d18994..99f2fb20b0 100644
--- a/activestorage/test/models/blob_test.rb
+++ b/activestorage/test/models/blob_test.rb
@@ -41,6 +41,13 @@ class ActiveStorage::BlobTest < ActiveSupport::TestCase
end
end
+ test "purge removes from external service" do
+ blob = create_blob
+
+ blob.purge
+ assert_not ActiveStorage::Blob.service.exist?(blob.key)
+ end
+
private
def expected_url_for(blob, disposition: :inline)
query_string = { content_type: blob.content_type, disposition: disposition }.to_param
diff --git a/activestorage/test/test_helper.rb b/activestorage/test/test_helper.rb
index 0bb3a925b8..2a969fa326 100644
--- a/activestorage/test/test_helper.rb
+++ b/activestorage/test/test_helper.rb
@@ -32,7 +32,7 @@ end
require "tmpdir"
ActiveStorage::Blob.service = ActiveStorage::Service::DiskService.new(root: Dir.mktmpdir("active_storage_tests"))
-ActiveStorage::Service.logger = ActiveSupport::Logger.new(STDOUT)
+ActiveStorage::Service.logger = ActiveSupport::Logger.new(nil)
ActiveStorage.verifier = ActiveSupport::MessageVerifier.new("Testing")
diff --git a/activesupport/lib/active_support/core_ext/hash/deep_merge.rb b/activesupport/lib/active_support/core_ext/hash/deep_merge.rb
index f92a2f1c2a..9bc50b7bc6 100644
--- a/activesupport/lib/active_support/core_ext/hash/deep_merge.rb
+++ b/activesupport/lib/active_support/core_ext/hash/deep_merge.rb
@@ -21,20 +21,14 @@ class Hash
# Same as +deep_merge+, but modifies +self+.
def deep_merge!(other_hash, &block)
- other_hash.each_pair do |current_key, other_value|
- this_value = self[current_key]
-
- self[current_key] = if this_value.is_a?(Hash) && other_value.is_a?(Hash)
- this_value.deep_merge(other_value, &block)
+ merge!(other_hash) do |key, this_val, other_val|
+ if this_val.is_a?(Hash) && other_val.is_a?(Hash)
+ this_val.deep_merge(other_val, &block)
+ elsif block_given?
+ block.call(key, this_val, other_val)
else
- if block_given? && key?(current_key)
- block.call(current_key, this_value, other_value)
- else
- other_value
- end
+ other_val
end
end
-
- self
end
end
diff --git a/activesupport/lib/active_support/lazy_load_hooks.rb b/activesupport/lib/active_support/lazy_load_hooks.rb
index c124416595..dc8080c469 100644
--- a/activesupport/lib/active_support/lazy_load_hooks.rb
+++ b/activesupport/lib/active_support/lazy_load_hooks.rb
@@ -40,7 +40,7 @@ module ActiveSupport
# * <tt>:run_once</tt> - Given +block+ will run only once.
def on_load(name, options = {}, &block)
@loaded[name].each do |base|
- execute_hook(base, options, block)
+ execute_hook(name, base, options, block)
end
@load_hooks[name] << [block, options]
@@ -49,7 +49,7 @@ module ActiveSupport
def run_load_hooks(name, base = Object)
@loaded[name] << base
@load_hooks[name].each do |hook, options|
- execute_hook(base, options, hook)
+ execute_hook(name, base, options, hook)
end
end
@@ -63,7 +63,7 @@ module ActiveSupport
end
end
- def execute_hook(base, options, block)
+ def execute_hook(name, base, options, block)
with_execution_control(name, block, options[:run_once]) do
if options[:yield]
block.call(base)
diff --git a/activesupport/test/lazy_load_hooks_test.rb b/activesupport/test/lazy_load_hooks_test.rb
index c161005100..721d44d0c1 100644
--- a/activesupport/test/lazy_load_hooks_test.rb
+++ b/activesupport/test/lazy_load_hooks_test.rb
@@ -22,14 +22,19 @@ class LazyLoadHooksTest < ActiveSupport::TestCase
def test_basic_hook_with_two_registrations_only_once
i = 0
- ActiveSupport.on_load(:basic_hook_with_two_once, run_once: true) do
+ block = proc { i += incr }
+ ActiveSupport.on_load(:basic_hook_with_two_once, run_once: true, &block)
+ ActiveSupport.on_load(:basic_hook_with_two_once) do
i += incr
end
- assert_equal 0, i
- ActiveSupport.run_load_hooks(:basic_hook_with_two_once, FakeContext.new(2))
+
+ ActiveSupport.on_load(:different_hook, run_once: true, &block)
+ ActiveSupport.run_load_hooks(:different_hook, FakeContext.new(2))
assert_equal 2, i
+ ActiveSupport.run_load_hooks(:basic_hook_with_two_once, FakeContext.new(2))
+ assert_equal 6, i
ActiveSupport.run_load_hooks(:basic_hook_with_two_once, FakeContext.new(5))
- assert_equal 2, i
+ assert_equal 11, i
end
def test_hook_registered_after_run
diff --git a/guides/source/active_record_validations.md b/guides/source/active_record_validations.md
index a086363cf1..e9157f3db1 100644
--- a/guides/source/active_record_validations.md
+++ b/guides/source/active_record_validations.md
@@ -892,7 +892,7 @@ Conditional Validation
Sometimes it will make sense to validate an object only when a given predicate
is satisfied. You can do that by using the `:if` and `:unless` options, which
-can take a symbol, a string, a `Proc` or an `Array`. You may use the `:if`
+can take a symbol, a `Proc` or an `Array`. You may use the `:if`
option when you want to specify when the validation **should** happen. If you
want to specify when the validation **should not** happen, then you may use the
`:unless` option.
diff --git a/guides/source/development_dependencies_install.md b/guides/source/development_dependencies_install.md
index c57efd6362..77b036b20f 100644
--- a/guides/source/development_dependencies_install.md
+++ b/guides/source/development_dependencies_install.md
@@ -21,24 +21,25 @@ The easiest and recommended way to get a development environment ready to hack i
The Hard Way
------------
-In case you can't use the Rails development box, see section below, these are the steps to manually build a development box for Ruby on Rails core development.
+In case you can't use the Rails development box, see the steps below to manually
+build a development box for Ruby on Rails core development.
### Install Git
-Ruby on Rails uses Git for source code control. The [Git homepage](http://git-scm.com/) has installation instructions. There are a variety of resources on the net that will help you get familiar with Git:
+Ruby on Rails uses Git for source code control. The [Git homepage](https://git-scm.com/) has installation instructions. There are a variety of resources on the net that will help you get familiar with Git:
-* [Try Git course](http://try.github.io/) is an interactive course that will teach you the basics.
-* The [official Documentation](http://git-scm.com/documentation) is pretty comprehensive and also contains some videos with the basics of Git.
+* [Try Git course](https://try.github.io/) is an interactive course that will teach you the basics.
+* The [official Documentation](https://git-scm.com/documentation) is pretty comprehensive and also contains some videos with the basics of Git.
* [Everyday Git](http://schacon.github.io/git/everyday.html) will teach you just enough about Git to get by.
-* [GitHub](http://help.github.com) offers links to a variety of Git resources.
-* [Pro Git](http://git-scm.com/book) is an entire book about Git with a Creative Commons license.
+* [GitHub](https://help.github.com/) offers links to a variety of Git resources.
+* [Pro Git](https://git-scm.com/book) is an entire book about Git with a Creative Commons license.
### Clone the Ruby on Rails Repository
Navigate to the folder where you want the Ruby on Rails source code (it will create its own `rails` subdirectory) and run:
```bash
-$ git clone git://github.com/rails/rails.git
+$ git clone https://github.com/rails/rails.git
$ cd rails
```
@@ -62,7 +63,7 @@ $ sudo apt-get install sqlite3 libsqlite3-dev
If you are on Fedora or CentOS, you're done with
```bash
-$ sudo yum install libsqlite3x libsqlite3x-devel
+$ sudo yum install libsqlite3x libsqlite3x-devel
```
If you are on Arch Linux, you will need to run:
@@ -96,7 +97,7 @@ This command will install all dependencies except the MySQL and PostgreSQL Ruby
NOTE: If you would like to run the tests that use memcached, you need to ensure that you have it installed and running.
-You can use [Homebrew](http://brew.sh/) to install memcached on OS X:
+You can use [Homebrew](https://brew.sh/) to install memcached on macOS:
```bash
$ brew install memcached
@@ -181,7 +182,7 @@ The Active Record test suite requires a custom config file: `activerecord/test/c
To be able to run the suite for MySQL and PostgreSQL we need their gems. Install
first the servers, their client libraries, and their development files.
-On OS X, you can run:
+On macOS, you can run:
```bash
$ brew install mysql
@@ -190,7 +191,7 @@ $ brew install postgresql
Follow the instructions given by Homebrew to start these.
-In Ubuntu just run:
+On Ubuntu, just run:
```bash
$ sudo apt-get install mysql-server libmysqlclient-dev
@@ -260,34 +261,34 @@ with your development account, on Linux or BSD, you just have to run:
$ sudo -u postgres createuser --superuser $USER
```
-and for OS X:
+and for macOS:
```bash
$ createuser --superuser $USER
```
-Then you need to create the test databases with
+Then, you need to create the test databases with:
```bash
$ cd activerecord
$ bundle exec rake db:postgresql:build
```
-It is possible to build databases for both PostgreSQL and MySQL with
+It is possible to build databases for both PostgreSQL and MySQL with:
```bash
$ cd activerecord
$ bundle exec rake db:create
```
-You can cleanup the databases using
+You can cleanup the databases using:
```bash
$ cd activerecord
$ bundle exec rake db:drop
```
-NOTE: Using the rake task to create the test databases ensures they have the correct character set and collation.
+NOTE: Using the Rake task to create the test databases ensures they have the correct character set and collation.
NOTE: You'll see the following warning (or localized warning) during activating HStore extension in PostgreSQL 9.1.x or earlier: "WARNING: => is deprecated as an operator".
@@ -299,11 +300,11 @@ Action Cable uses Redis as its default subscriptions adapter ([read more](action
#### Install Redis From Source
-Redis' documentation discourage installations with package managers as those are usually outdated. Installing from source and bringing the server up is straight forward and well documented on [Redis' documentation](http://redis.io/download#installation).
+Redis' documentation discourage installations with package managers as those are usually outdated. Installing from source and bringing the server up is straight forward and well documented on [Redis' documentation](https://redis.io/download#installation).
#### Install Redis From Package Manager
-On OS X, you can run:
+On macOS, you can run:
```bash
$ brew install redis
@@ -311,7 +312,7 @@ $ brew install redis
Follow the instructions given by Homebrew to start these.
-In Ubuntu just run:
+On Ubuntu, just run:
```bash
$ sudo apt-get install redis-server
@@ -323,7 +324,7 @@ On Fedora or CentOS (requires EPEL enabled), just run:
$ sudo yum install redis
```
-If you are running Arch Linux just run:
+If you are running Arch Linux, just run:
```bash
$ sudo pacman -S redis
@@ -335,3 +336,43 @@ FreeBSD users will have to run the following:
```bash
# portmaster databases/redis
```
+
+### Active Storage Setup
+
+When working on Active Storage, it is important to note that you need to
+install its JavaScript dependencies while working on that section of the
+codebase. In order to install these dependencies, it is necessary to
+have Yarn, a Node.js package manager, available on your system. A
+prerequisite for installing this package manager is that
+[Node.js](https://nodejs.org) is installed.
+
+
+On macOS, you can run:
+
+```bash
+brew install yarn
+```
+
+On Ubuntu, you can run:
+
+```bash
+curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
+echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
+
+sudo apt-get update && sudo apt-get install yarn
+```
+
+On Fedora or CentOS, just run:
+
+``bash
+sudo wget https://dl.yarnpkg.com/rpm/yarn.repo -O /etc/yum.repos.d/yarn.repo
+
+sudo yum install yarn
+```
+
+Finally, after installing Yarn, you will need to run the following
+command inside of the `activestorage` directory to install the dependencies:
+
+```bash
+yarn install
+```
diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md
index 49a0584d51..651b86275a 100644
--- a/guides/source/upgrading_ruby_on_rails.md
+++ b/guides/source/upgrading_ruby_on_rails.md
@@ -397,6 +397,15 @@ When using Ruby 2.4, you can preserve the timezone of the receiver when calling
ActiveSupport.to_time_preserves_timezone = false
+### Changes with JSON/JSONB serialization
+
+In Rails 5.0, how JSON/JSONB attributes are serialized and deserialized changed. Now, if
+you set a column equal to a `String`, Active Record will no longer turn that string
+into a `Hash`, and will instead only return the string. This is not limited to code
+interacting with models, but also affects `:default` column settings in `db/schema.rb`.
+It is recommended that you do not set columns equal to a `String`, but pass a `Hash`
+instead, which will be converted to and from a JSON string automatically.
+
Upgrading from Rails 4.1 to Rails 4.2
-------------------------------------
diff --git a/railties/lib/rails/generators/rails/plugin/templates/gitignore b/railties/lib/rails/generators/rails/plugin/templates/gitignore
index 8c7cad74ed..e15863d860 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/gitignore
+++ b/railties/lib/rails/generators/rails/plugin/templates/gitignore
@@ -2,8 +2,10 @@
log/*.log
pkg/
<% if with_dummy_app? -%>
+<% if sqlite3? -%>
<%= dummy_path %>/db/*.sqlite3
<%= dummy_path %>/db/*.sqlite3-journal
+<% end -%>
<%= dummy_path %>/log/*.log
<% unless options[:skip_yarn] -%>
<%= dummy_path %>/node_modules/
diff --git a/railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb b/railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb
index a0bab22764..2fa05a9146 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb
+++ b/railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb
@@ -17,6 +17,7 @@ Minitest.backtrace_filter = Minitest::BacktraceFilter.new
Rails::TestUnitReporter.executable = 'bin/test'
<% end -%>
+<% unless options[:skip_active_record] -%>
# Load fixtures from the engine
if ActiveSupport::TestCase.respond_to?(:fixture_path=)
ActiveSupport::TestCase.fixture_path = File.expand_path("fixtures", __dir__)
@@ -24,3 +25,4 @@ if ActiveSupport::TestCase.respond_to?(:fixture_path=)
ActiveSupport::TestCase.file_fixture_path = ActiveSupport::TestCase.fixture_path + "/files"
ActiveSupport::TestCase.fixtures :all
end
+<% end -%>
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index b50b9364d0..f64ebf5f1f 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -381,31 +381,6 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
end
- def test_generator_without_skips
- run_generator
- assert_file "config/application.rb", /\s+require\s+["']rails\/all["']/
- assert_file "config/environments/development.rb" do |content|
- assert_match(/config\.action_mailer\.raise_delivery_errors = false/, content)
- end
- assert_file "config/environments/test.rb" do |content|
- assert_match(/config\.action_mailer\.delivery_method = :test/, content)
- end
- assert_file "config/environments/production.rb" do |content|
- assert_match(/# config\.action_mailer\.raise_delivery_errors = false/, content)
- assert_match(/^ config\.read_encrypted_secrets = true/, content)
- end
- end
-
- def test_default_frameworks_are_required_when_others_are_removed
- run_generator [destination_root, "--skip-active-record", "--skip-action-mailer", "--skip-action-cable", "--skip-sprockets", "--skip-test"]
- assert_file "config/application.rb", /require\s+["']rails["']/
- assert_file "config/application.rb", /require\s+["']active_model\/railtie["']/
- assert_file "config/application.rb", /require\s+["']active_job\/railtie["']/
- assert_file "config/application.rb", /require\s+["']action_controller\/railtie["']/
- assert_file "config/application.rb", /require\s+["']action_view\/railtie["']/
- assert_file "config/application.rb", /require\s+["']active_storage\/engine["']/
- end
-
def test_generator_defaults_to_puma_version
run_generator [destination_root]
assert_gem "puma", "'~> 3.7'"
@@ -419,39 +394,6 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
end
- def test_generator_if_skip_active_record_is_given
- run_generator [destination_root, "--skip-active-record"]
- assert_no_directory "db/"
- assert_no_file "config/database.yml"
- assert_no_file "app/models/application_record.rb"
- assert_file "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 "bin/setup" do |setup_content|
- assert_no_match(/db:setup/, setup_content)
- end
- assert_file "bin/update" do |update_content|
- assert_no_match(/db:migrate/, update_content)
- end
- end
-
- def test_generator_if_skip_action_mailer_is_given
- run_generator [destination_root, "--skip-action-mailer"]
- assert_file "config/application.rb", /#\s+require\s+["']action_mailer\/railtie["']/
- assert_file "config/environments/development.rb" do |content|
- assert_no_match(/config\.action_mailer/, content)
- end
- assert_file "config/environments/test.rb" do |content|
- assert_no_match(/config\.action_mailer/, content)
- end
- assert_file "config/environments/production.rb" do |content|
- assert_no_match(/config\.action_mailer/, content)
- end
- assert_no_directory "app/mailers"
- assert_no_directory "test/mailers"
- end
-
def test_generator_has_assets_gems
run_generator
@@ -459,43 +401,6 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_gem "uglifier"
end
- def test_generator_if_skip_sprockets_is_given
- run_generator [destination_root, "--skip-sprockets"]
-
- assert_no_file "config/initializers/assets.rb"
-
- assert_file "config/application.rb", /#\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 "config/environments/development.rb" do |content|
- assert_no_match(/config\.assets\.debug/, content)
- end
-
- assert_file "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_if_skip_action_cable_is_given
- run_generator [destination_root, "--skip-action-cable"]
- assert_file "config/application.rb", /#\s+require\s+["']action_cable\/engine["']/
- assert_no_file "config/cable.yml"
- assert_no_file "app/assets/javascripts/cable.js"
- assert_no_directory "app/assets/javascripts/channels"
- assert_no_directory "app/channels"
- assert_file "Gemfile" do |content|
- assert_no_match(/redis/, content)
- end
- end
-
def test_action_cable_redis_gems
run_generator
assert_file "Gemfile", /^# gem 'redis'/
@@ -770,30 +675,6 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
end
- def test_gitignore_when_sqlite3
- run_generator
-
- assert_file ".gitignore" do |content|
- assert_match(/sqlite3/, content)
- end
- end
-
- def test_gitignore_when_no_active_record
- run_generator [destination_root, "--skip-active-record"]
-
- assert_file ".gitignore" do |content|
- assert_no_match(/sqlite/i, content)
- end
- end
-
- def test_gitignore_when_non_sqlite3_db
- run_generator([destination_root, "-d", "mysql"])
-
- assert_file ".gitignore" do |content|
- assert_no_match(/sqlite/i, content)
- end
- end
-
def test_inclusion_of_ruby_version
run_generator
diff --git a/railties/test/generators/plugin_generator_test.rb b/railties/test/generators/plugin_generator_test.rb
index e94b1ac8fe..38130ceb68 100644
--- a/railties/test/generators/plugin_generator_test.rb
+++ b/railties/test/generators/plugin_generator_test.rb
@@ -129,31 +129,6 @@ class PluginGeneratorTest < Rails::Generators::TestCase
end
end
- def test_generating_adds_dummy_app_without_sprockets
- run_generator [destination_root, "--skip-sprockets"]
-
- assert_no_file "test/dummy/config/initializers/assets.rb"
-
- assert_file "test/dummy/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 "test/dummy/config/environments/development.rb" do |content|
- assert_no_match(/config\.assets\.debug/, content)
- end
-
- assert_file "test/dummy/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_generating_adds_dummy_app_rake_tasks_without_unit_test_files
run_generator [destination_root, "-T", "--mountable", "--dummy-path", "my_dummy_app"]
assert_file "Rakefile", /APP_RAKEFILE/
@@ -202,69 +177,13 @@ class PluginGeneratorTest < Rails::Generators::TestCase
end
end
- def test_app_generator_without_skips
- run_generator
- assert_file "test/dummy/config/application.rb", /\s+require\s+["']rails\/all["']/
- assert_file "test/dummy/config/environments/development.rb" do |content|
- assert_match(/config\.action_mailer\.raise_delivery_errors = false/, content)
- end
- assert_file "test/dummy/config/environments/test.rb" do |content|
- assert_match(/config\.action_mailer\.delivery_method = :test/, content)
- end
- assert_file "test/dummy/config/environments/production.rb" do |content|
- assert_match(/# config\.action_mailer\.raise_delivery_errors = false/, content)
- assert_match(/^ config\.read_encrypted_secrets = true/, content)
- end
- end
-
- def test_default_frameworks_are_required_when_others_are_removed
- run_generator [destination_root, "--skip-active-record", "--skip-action-mailer", "--skip-action-cable", "--skip-sprockets"]
- assert_file "test/dummy/config/application.rb", /require\s+["']rails["']/
- assert_file "test/dummy/config/application.rb", /require\s+["']active_model\/railtie["']/
- assert_file "test/dummy/config/application.rb", /require\s+["']active_job\/railtie["']/
- assert_file "test/dummy/config/application.rb", /require\s+["']action_controller\/railtie["']/
- assert_file "test/dummy/config/application.rb", /require\s+["']action_view\/railtie["']/
- 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_file "test/test_helper.rb" do |contents|
assert_no_match(/ActiveRecord/, contents)
end
end
- def test_action_mailer_is_removed_from_frameworks_if_skip_action_mailer_is_given
- run_generator [destination_root, "--skip-action-mailer"]
- assert_file "test/dummy/config/application.rb", /#\s+require\s+["']action_mailer\/railtie["']/
- assert_file "test/dummy/config/environments/development.rb" do |content|
- assert_no_match(/config\.action_mailer/, content)
- end
- assert_file "test/dummy/config/environments/test.rb" do |content|
- assert_no_match(/config\.action_mailer/, content)
- end
- assert_file "test/dummy/config/environments/production.rb" do |content|
- assert_no_match(/config\.action_mailer/, content)
- end
- assert_no_directory "test/dummy/app/mailers"
- end
-
- def test_action_cable_is_removed_from_frameworks_if_skip_action_cable_is_given
- run_generator [destination_root, "--skip-action-cable"]
- assert_file "test/dummy/config/application.rb", /#\s+require\s+["']action_cable\/engine["']/
- assert_no_file "test/dummy/config/cable.yml"
- assert_no_file "test/dummy/app/assets/javascripts/cable.js"
- assert_no_directory "test/dummy/app/channels"
- assert_file "Gemfile" do |content|
- assert_no_match(/redis/, content)
- end
- end
-
def test_ensure_that_database_option_is_passed_to_app_generator
run_generator [destination_root, "--database", "postgresql"]
assert_file "test/dummy/config/database.yml", /postgres/
diff --git a/railties/test/generators/shared_generator_tests.rb b/railties/test/generators/shared_generator_tests.rb
index 6c0775b50e..56c9b37e1b 100644
--- a/railties/test/generators/shared_generator_tests.rb
+++ b/railties/test/generators/shared_generator_tests.rb
@@ -128,6 +128,120 @@ module SharedGeneratorTests
assert_no_file("app/models/concerns/.keep")
end
+ def test_default_frameworks_are_required_when_others_are_removed
+ run_generator [destination_root, "--skip-active-record", "--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+["']action_controller\/railtie["']/
+ assert_file "#{application_path}/config/application.rb", /require\s+["']action_view\/railtie["']/
+ assert_file "#{application_path}/config/application.rb", /require\s+["']active_storage\/engine["']/
+ 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)
+ assert_match(/^ config\.read_encrypted_secrets = 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_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/