diff options
34 files changed, 284 insertions, 181 deletions
diff --git a/actionmailer/test/abstract_unit.rb b/actionmailer/test/abstract_unit.rb index 51de03c4ce..a646cbd581 100644 --- a/actionmailer/test/abstract_unit.rb +++ b/actionmailer/test/abstract_unit.rb @@ -31,15 +31,15 @@ I18n.enforce_available_locales = false FIXTURE_LOAD_PATH = File.expand_path("fixtures", File.dirname(__FILE__)) ActionMailer::Base.view_paths = FIXTURE_LOAD_PATH -# Skips the current run on Rubinius using Minitest::Assertions#skip -def rubinius_skip(message = "") - skip message if RUBY_ENGINE == "rbx" -end -# Skips the current run on JRuby using Minitest::Assertions#skip -def jruby_skip(message = "") - skip message if defined?(JRUBY_VERSION) -end - class ActiveSupport::TestCase include ActiveSupport::Testing::MethodCallAssertions + + # Skips the current run on Rubinius using Minitest::Assertions#skip + private def rubinius_skip(message = "") + skip message if RUBY_ENGINE == "rbx" + end + # Skips the current run on JRuby using Minitest::Assertions#skip + private def jruby_skip(message = "") + skip message if defined?(JRUBY_VERSION) + end end diff --git a/actionpack/lib/action_controller/metal/strong_parameters.rb b/actionpack/lib/action_controller/metal/strong_parameters.rb index 6e8df02fb9..d304dcf468 100644 --- a/actionpack/lib/action_controller/metal/strong_parameters.rb +++ b/actionpack/lib/action_controller/metal/strong_parameters.rb @@ -398,8 +398,7 @@ module ActionController unpermitted_parameters!(params) if self.class.action_on_unpermitted_parameters - params.permitted = true - params + params.permit! end # Returns a parameter for the given +key+. If not found, @@ -818,7 +817,6 @@ module ActionController # Filter this one out. end end - sanitized.permitted = true end end diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 83652bd34c..8d9f70e3c6 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -1,6 +1,7 @@ require "active_support/core_ext/hash/slice" require "active_support/core_ext/enumerable" require "active_support/core_ext/array/extract_options" +require "active_support/core_ext/regexp" require "action_dispatch/routing/redirection" require "action_dispatch/routing/endpoint" diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index 7c113426a5..459b0d6c54 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -354,15 +354,6 @@ class CommentsController < ResourcesController; end class AccountsController < ResourcesController; end class ImagesController < ResourcesController; end -# Skips the current run on Rubinius using Minitest::Assertions#skip -def rubinius_skip(message = "") - skip message if RUBY_ENGINE == "rbx" -end -# Skips the current run on JRuby using Minitest::Assertions#skip -def jruby_skip(message = "") - skip message if defined?(JRUBY_VERSION) -end - require "active_support/testing/method_call_assertions" class ForkingExecutor @@ -438,4 +429,13 @@ end class ActiveSupport::TestCase include ActiveSupport::Testing::MethodCallAssertions + + # Skips the current run on Rubinius using Minitest::Assertions#skip + private def rubinius_skip(message = "") + skip message if RUBY_ENGINE == "rbx" + end + # Skips the current run on JRuby using Minitest::Assertions#skip + private def jruby_skip(message = "") + skip message if defined?(JRUBY_VERSION) + end end diff --git a/actionpack/test/controller/parameters/nested_parameters_permit_test.rb b/actionpack/test/controller/parameters/nested_parameters_permit_test.rb index 5f86901e30..138d83726c 100644 --- a/actionpack/test/controller/parameters/nested_parameters_permit_test.rb +++ b/actionpack/test/controller/parameters/nested_parameters_permit_test.rb @@ -140,6 +140,11 @@ class NestedParametersPermitTest < ActiveSupport::TestCase assert_equal "William Shakespeare", permitted[:book][:authors_attributes]["0"][:name] assert_equal "Unattributed Assistant", permitted[:book][:authors_attributes]["1"][:name] + assert_equal( + {"book"=>{"authors_attributes"=>{"0"=>{"name"=>"William Shakespeare"}, "1"=>{"name"=>"Unattributed Assistant"}, "2"=>{}}}}, + permitted.to_h + ) + assert_filtered_out permitted[:book][:authors_attributes]["0"], :age_of_death end diff --git a/actionpack/test/controller/parameters/parameters_permit_test.rb b/actionpack/test/controller/parameters/parameters_permit_test.rb index b62a3d6d7b..82d7530e9f 100644 --- a/actionpack/test/controller/parameters/parameters_permit_test.rb +++ b/actionpack/test/controller/parameters/parameters_permit_test.rb @@ -187,11 +187,6 @@ class ParametersPermitTest < ActiveSupport::TestCase permitted = params.permit(:username, preferences: {}, hacked: {}) - assert permitted.permitted? - assert permitted[:preferences].permitted? - assert permitted[:preferences][:font].permitted? - assert permitted[:preferences][:dubious].all?(&:permitted?) - assert_equal "fxn", permitted[:username] assert_equal "Marazul", permitted[:preferences][:scheme] assert_equal "Source Code Pro", permitted[:preferences][:font][:name] diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index 0c0f18f200..3a0a0a8bde 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -313,7 +313,6 @@ class ExpiresInRenderTest < ActionController::TestCase end def test_permitted_dynamic_render_file_hash - skip "FIXME: this test passes on 4-2-stable but not master. Why?" assert File.exist?(File.join(File.dirname(__FILE__), "../../test/abstract_unit.rb")) response = get :dynamic_render_permit, params: { id: { file: '../\\../test/abstract_unit.rb' } } assert_equal File.read(File.join(File.dirname(__FILE__), "../../test/abstract_unit.rb")), diff --git a/actionview/lib/action_view/helpers/sanitize_helper.rb b/actionview/lib/action_view/helpers/sanitize_helper.rb index 3d6ff598ee..1e9b813d3d 100644 --- a/actionview/lib/action_view/helpers/sanitize_helper.rb +++ b/actionview/lib/action_view/helpers/sanitize_helper.rb @@ -45,17 +45,15 @@ module ActionView # Providing a custom Rails::Html scrubber: # # class CommentScrubber < Rails::Html::PermitScrubber - # def allowed_node?(node) - # !%w(form script comment blockquote).include?(node.name) + # def initialize + # super + # self.tags = %w( form script comment blockquote ) + # self.attributes = %w( style ) # end # # def skip_node?(node) # node.text? # end - # - # def scrub_attribute?(name) - # name == 'style' - # end # end # # <%= sanitize @comment.body, scrubber: CommentScrubber.new %> diff --git a/actionview/lib/action_view/rendering.rb b/actionview/lib/action_view/rendering.rb index 0e72316eb7..cf18562c45 100644 --- a/actionview/lib/action_view/rendering.rb +++ b/actionview/lib/action_view/rendering.rb @@ -124,7 +124,11 @@ module ActionView key = action.include?(?/) ? :template : :action options[key] = action else - options[:partial] = action + if action.respond_to?(:permitted?) && action.permitted? + options = action + else + options[:partial] = action + end end options diff --git a/actionview/test/abstract_unit.rb b/actionview/test/abstract_unit.rb index fbdaa07fb0..dde66a7ba0 100644 --- a/actionview/test/abstract_unit.rb +++ b/actionview/test/abstract_unit.rb @@ -271,15 +271,15 @@ module ActionDispatch end end -# Skips the current run on Rubinius using Minitest::Assertions#skip -def rubinius_skip(message = "") - skip message if RUBY_ENGINE == "rbx" -end -# Skips the current run on JRuby using Minitest::Assertions#skip -def jruby_skip(message = "") - skip message if defined?(JRUBY_VERSION) -end - class ActiveSupport::TestCase include ActiveSupport::Testing::MethodCallAssertions + + # Skips the current run on Rubinius using Minitest::Assertions#skip + private def rubinius_skip(message = "") + skip message if RUBY_ENGINE == "rbx" + end + # Skips the current run on JRuby using Minitest::Assertions#skip + private def jruby_skip(message = "") + skip message if defined?(JRUBY_VERSION) + end end diff --git a/activejob/lib/active_job/test_helper.rb b/activejob/lib/active_job/test_helper.rb index d01795f0c5..2182427375 100644 --- a/activejob/lib/active_job/test_helper.rb +++ b/activejob/lib/active_job/test_helper.rb @@ -284,7 +284,7 @@ module ActiveJob # def test_perform_enqueued_jobs_with_only # perform_enqueued_jobs(only: MyJob) do # MyJob.perform_later(1, 2, 3) # will be performed - # HelloJob.perform_later(1, 2, 3) # will not be perfomed + # HelloJob.perform_later(1, 2, 3) # will not be performed # end # assert_performed_jobs 1 # end diff --git a/activemodel/test/cases/errors_test.rb b/activemodel/test/cases/errors_test.rb index e6ba06301d..0872084cf5 100644 --- a/activemodel/test/cases/errors_test.rb +++ b/activemodel/test/cases/errors_test.rb @@ -1,4 +1,5 @@ require "cases/helper" +require "active_support/core_ext/string/strip" require "yaml" class ErrorsTest < ActiveModel::TestCase diff --git a/activemodel/test/cases/helper.rb b/activemodel/test/cases/helper.rb index 4e9f43ad86..40dfb8e589 100644 --- a/activemodel/test/cases/helper.rb +++ b/activemodel/test/cases/helper.rb @@ -9,15 +9,15 @@ I18n.enforce_available_locales = false require "active_support/testing/autorun" require "active_support/testing/method_call_assertions" -# Skips the current run on Rubinius using Minitest::Assertions#skip -def rubinius_skip(message = "") - skip message if RUBY_ENGINE == "rbx" -end -# Skips the current run on JRuby using Minitest::Assertions#skip -def jruby_skip(message = "") - skip message if defined?(JRUBY_VERSION) -end - class ActiveModel::TestCase include ActiveSupport::Testing::MethodCallAssertions + + # Skips the current run on Rubinius using Minitest::Assertions#skip + private def rubinius_skip(message = "") + skip message if RUBY_ENGINE == "rbx" + end + # Skips the current run on JRuby using Minitest::Assertions#skip + private def jruby_skip(message = "") + skip message if defined?(JRUBY_VERSION) + end end diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 5bba673dee..3438c04245 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,7 @@ +* Raise `ActiveRecord::InvalidForeignKey` when a foreign key constraint fails on Sqlite3. + + *Ryuta Kamizono* + * Add the touch option to ActiveRecord#increment! and decrement! *Hiroaki Izu* diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_creation.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_creation.rb index 322684672f..807df2184a 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_creation.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_creation.rb @@ -15,9 +15,9 @@ module ActiveRecord end delegate :quote_column_name, :quote_table_name, :quote_default_expression, :type_to_sql, - :options_include_default?, :supports_indexes_in_create?, :supports_foreign_keys?, :foreign_key_options, to: :@conn + :options_include_default?, :supports_indexes_in_create?, :supports_foreign_keys_in_create?, :foreign_key_options, to: :@conn private :quote_column_name, :quote_table_name, :quote_default_expression, :type_to_sql, - :options_include_default?, :supports_indexes_in_create?, :supports_foreign_keys?, :foreign_key_options + :options_include_default?, :supports_indexes_in_create?, :supports_foreign_keys_in_create?, :foreign_key_options private @@ -49,7 +49,7 @@ module ActiveRecord statements.concat(o.indexes.map { |column_name, options| index_in_create(o.name, column_name, options) }) end - if supports_foreign_keys? + if supports_foreign_keys_in_create? statements.concat(o.foreign_keys.map { |to_table, options| foreign_key_in_create(o.name, to_table, options) }) end diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb index cf2269bf12..348396de72 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb @@ -310,6 +310,12 @@ module ActiveRecord false end + # Does this adapter support creating foreign key constraints + # in the same statement as creating the table? + def supports_foreign_keys_in_create? + supports_foreign_keys? + end + # Does this adapter support views? def supports_views? false diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb index ec44d020c2..ca6de37a6b 100644 --- a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb @@ -95,6 +95,8 @@ module ActiveRecord @active = nil @statements = StatementPool.new(self.class.type_cast_config_to_integer(config[:statement_limit])) + + configure_connection end def supports_ddl_transactions? @@ -128,6 +130,10 @@ module ActiveRecord true end + def supports_foreign_keys_in_create? + sqlite_version >= "3.6.19" + end + def supports_views? true end @@ -185,6 +191,19 @@ module ActiveRecord true end + # REFERENTIAL INTEGRITY ==================================== + + def disable_referential_integrity # :nodoc: + old = select_value("PRAGMA foreign_keys") + + begin + execute("PRAGMA foreign_keys = OFF") + yield + ensure + execute("PRAGMA foreign_keys = #{old}") + end + end + #-- # DATABASE STATEMENTS ====================================== #++ @@ -424,6 +443,19 @@ module ActiveRecord rename_column_indexes(table_name, column.name, new_column_name) end + def foreign_keys(table_name) + fk_info = select_all("PRAGMA foreign_key_list(#{quote(table_name)})", "SCHEMA") + fk_info.map do |row| + options = { + column: row["from"], + primary_key: row["to"], + on_delete: extract_foreign_key_action(row["on_delete"]), + on_update: extract_foreign_key_action(row["on_update"]) + } + ForeignKeyDefinition.new(table_name, row["table"], options) + end + end + private def table_structure(table_name) @@ -525,6 +557,8 @@ module ActiveRecord RecordNotUnique.new(message) when /.* may not be NULL/, /NOT NULL constraint failed: .*/ NotNullViolation.new(message) + when /FOREIGN KEY constraint failed/i + InvalidForeignKey.new(message) else super end @@ -574,6 +608,18 @@ module ActiveRecord def create_table_definition(*args) SQLite3::TableDefinition.new(*args) end + + def extract_foreign_key_action(specifier) + case specifier + when "CASCADE"; :cascade + when "SET NULL"; :nullify + when "RESTRICT"; :restrict + end + end + + def configure_connection + execute("PRAGMA foreign_keys = ON", "SCHEMA") + end end end end diff --git a/activerecord/test/cases/adapter_test.rb b/activerecord/test/cases/adapter_test.rb index 11fcbfadb1..a2b7d53205 100644 --- a/activerecord/test/cases/adapter_test.rb +++ b/activerecord/test/cases/adapter_test.rb @@ -184,34 +184,6 @@ module ActiveRecord end unless current_adapter?(:SQLite3Adapter) - def test_foreign_key_violations_are_translated_to_specific_exception - error = assert_raises(ActiveRecord::InvalidForeignKey) do - # Oracle adapter uses prefetched primary key values from sequence and passes them to connection adapter insert method - if @connection.prefetch_primary_key? - id_value = @connection.next_sequence_value(@connection.default_sequence_name("fk_test_has_fk", "id")) - @connection.execute "INSERT INTO fk_test_has_fk (id, fk_id) VALUES (#{id_value},0)" - else - @connection.execute "INSERT INTO fk_test_has_fk (fk_id) VALUES (0)" - end - end - - assert_not_nil error.cause - end - - def test_foreign_key_violations_are_translated_to_specific_exception_with_validate_false - klass_has_fk = Class.new(ActiveRecord::Base) do - self.table_name = "fk_test_has_fk" - end - - error = assert_raises(ActiveRecord::InvalidForeignKey) do - has_fk = klass_has_fk.new - has_fk.fk_id = 1231231231 - has_fk.save(validate: false) - end - - assert_not_nil error.cause - end - def test_value_limit_violations_are_translated_to_specific_exception error = assert_raises(ActiveRecord::ValueTooLong) do Event.create(title: "abcdefgh") @@ -229,23 +201,6 @@ module ActiveRecord end end - def test_disable_referential_integrity - assert_nothing_raised do - @connection.disable_referential_integrity do - # Oracle adapter uses prefetched primary key values from sequence and passes them to connection adapter insert method - if @connection.prefetch_primary_key? - id_value = @connection.next_sequence_value(@connection.default_sequence_name("fk_test_has_fk", "id")) - @connection.execute "INSERT INTO fk_test_has_fk (id, fk_id) VALUES (#{id_value},0)" - else - @connection.execute "INSERT INTO fk_test_has_fk (fk_id) VALUES (0)" - end - # should delete created record as otherwise disable_referential_integrity will try to enable constraints after executed block - # and will fail (at least on Oracle) - @connection.execute "DELETE FROM fk_test_has_fk" - end - end - end - def test_select_all_always_return_activerecord_result result = @connection.select_all "SELECT * FROM posts" assert result.is_a?(ActiveRecord::Result) @@ -289,6 +244,59 @@ module ActiveRecord end end + class AdapterForeignKeyTest < ActiveRecord::TestCase + self.use_transactional_tests = false + + def setup + @connection = ActiveRecord::Base.connection + end + + def test_foreign_key_violations_are_translated_to_specific_exception_with_validate_false + klass_has_fk = Class.new(ActiveRecord::Base) do + self.table_name = "fk_test_has_fk" + end + + error = assert_raises(ActiveRecord::InvalidForeignKey) do + has_fk = klass_has_fk.new + has_fk.fk_id = 1231231231 + has_fk.save(validate: false) + end + + assert_not_nil error.cause + end + + def test_foreign_key_violations_are_translated_to_specific_exception + error = assert_raises(ActiveRecord::InvalidForeignKey) do + insert_into_fk_test_has_fk + end + + assert_not_nil error.cause + end + + def test_disable_referential_integrity + assert_nothing_raised do + @connection.disable_referential_integrity do + insert_into_fk_test_has_fk + # should delete created record as otherwise disable_referential_integrity will try to enable constraints + # after executed block and will fail (at least on Oracle) + @connection.execute "DELETE FROM fk_test_has_fk" + end + end + end + + private + + def insert_into_fk_test_has_fk + # Oracle adapter uses prefetched primary key values from sequence and passes them to connection adapter insert method + if @connection.prefetch_primary_key? + id_value = @connection.next_sequence_value(@connection.default_sequence_name("fk_test_has_fk", "id")) + @connection.execute "INSERT INTO fk_test_has_fk (id,fk_id) VALUES (#{id_value},0)" + else + @connection.execute "INSERT INTO fk_test_has_fk (fk_id) VALUES (0)" + end + end + end + class AdapterTestWithoutTransaction < ActiveRecord::TestCase self.use_transactional_tests = false diff --git a/activerecord/test/cases/date_time_precision_test.rb b/activerecord/test/cases/date_time_precision_test.rb index a1c3c5af9c..e4a2f9ee17 100644 --- a/activerecord/test/cases/date_time_precision_test.rb +++ b/activerecord/test/cases/date_time_precision_test.rb @@ -73,7 +73,7 @@ if subsecond_precision_supported? assert_match %r{t\.datetime\s+"updated_at",\s+precision: 6,\s+null: false$}, output end - if current_adapter?(:PostgreSQLAdapter) + if current_adapter?(:PostgreSQLAdapter, :SQLServerAdapter) def test_datetime_precision_with_zero_should_be_dumped @connection.create_table(:foos, force: true) do |t| t.timestamps precision: 0 diff --git a/activerecord/test/cases/migration/foreign_key_test.rb b/activerecord/test/cases/migration/foreign_key_test.rb index 9be6667aa1..96e775a58b 100644 --- a/activerecord/test/cases/migration/foreign_key_test.rb +++ b/activerecord/test/cases/migration/foreign_key_test.rb @@ -2,6 +2,26 @@ require "cases/helper" require "support/ddl_helper" require "support/schema_dumping_helper" +if ActiveRecord::Base.connection.supports_foreign_keys_in_create? + module ActiveRecord + class Migration + class ForeignKeyInCreateTest < ActiveRecord::TestCase + def test_foreign_keys + foreign_keys = ActiveRecord::Base.connection.foreign_keys("fk_test_has_fk") + assert_equal 1, foreign_keys.size + + fk = foreign_keys.first + assert_equal "fk_test_has_fk", fk.from_table + assert_equal "fk_test_has_pk", fk.to_table + assert_equal "fk_id", fk.column + assert_equal "pk_id", fk.primary_key + assert_equal "fk_name", fk.name unless current_adapter?(:SQLite3Adapter) + end + end + end + end +end + if ActiveRecord::Base.connection.supports_foreign_keys? module ActiveRecord class Migration @@ -29,10 +49,8 @@ if ActiveRecord::Base.connection.supports_foreign_keys? end teardown do - if defined?(@connection) - @connection.drop_table "astronauts", if_exists: true - @connection.drop_table "rockets", if_exists: true - end + @connection.drop_table "astronauts", if_exists: true + @connection.drop_table "rockets", if_exists: true end def test_foreign_keys @@ -305,9 +323,11 @@ else @connection.remove_foreign_key :clubs, :categories end - def test_foreign_keys_should_raise_not_implemented - assert_raises NotImplementedError do - @connection.foreign_keys("clubs") + unless current_adapter?(:SQLite3Adapter) + def test_foreign_keys_should_raise_not_implemented + assert_raises NotImplementedError do + @connection.foreign_keys("clubs") + end end end end diff --git a/activerecord/test/cases/migration/references_foreign_key_test.rb b/activerecord/test/cases/migration/references_foreign_key_test.rb index 4957ab8b3d..560adcbfed 100644 --- a/activerecord/test/cases/migration/references_foreign_key_test.rb +++ b/activerecord/test/cases/migration/references_foreign_key_test.rb @@ -1,9 +1,9 @@ require "cases/helper" -if ActiveRecord::Base.connection.supports_foreign_keys? +if ActiveRecord::Base.connection.supports_foreign_keys_in_create? module ActiveRecord class Migration - class ReferencesForeignKeyTest < ActiveRecord::TestCase + class ReferencesForeignKeyInCreateTest < ActiveRecord::TestCase setup do @connection = ActiveRecord::Base.connection @connection.create_table(:testing_parents, force: true) @@ -61,6 +61,24 @@ if ActiveRecord::Base.connection.supports_foreign_keys? assert_equal([["testings", "testing_parents", "parent_id"]], fks.map { |fk| [fk.from_table, fk.to_table, fk.column] }) end + end + end + end +end + +if ActiveRecord::Base.connection.supports_foreign_keys? + module ActiveRecord + class Migration + class ReferencesForeignKeyTest < ActiveRecord::TestCase + setup do + @connection = ActiveRecord::Base.connection + @connection.create_table(:testing_parents, force: true) + end + + teardown do + @connection.drop_table "testings", if_exists: true + @connection.drop_table "testing_parents", if_exists: true + end test "foreign keys cannot be added to polymorphic relations when creating the table" do @connection.create_table :testings do |t| diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb index bea78d2a95..34c5f356b8 100644 --- a/activerecord/test/cases/schema_dumper_test.rb +++ b/activerecord/test/cases/schema_dumper_test.rb @@ -343,7 +343,7 @@ class SchemaDumperTest < ActiveRecord::TestCase t.column :name, :string t.column :owner_id, :bigint t.index [:name] - t.foreign_key :dog_owners, column: "owner_id" if supports_foreign_keys? + t.foreign_key :dog_owners, column: "owner_id" end end def down diff --git a/activerecord/test/cases/time_precision_test.rb b/activerecord/test/cases/time_precision_test.rb index 03f6c234e8..09c585167e 100644 --- a/activerecord/test/cases/time_precision_test.rb +++ b/activerecord/test/cases/time_precision_test.rb @@ -68,7 +68,7 @@ if subsecond_precision_supported? assert_match %r{t\.time\s+"finish",\s+precision: 6$}, output end - if current_adapter?(:PostgreSQLAdapter) + if current_adapter?(:PostgreSQLAdapter, :SQLServerAdapter) def test_time_precision_with_zero_should_be_dumped @connection.create_table(:foos, force: true) do |t| t.time :start, precision: 0 diff --git a/activerecord/test/cases/view_test.rb b/activerecord/test/cases/view_test.rb index d055968a56..07288568e8 100644 --- a/activerecord/test/cases/view_test.rb +++ b/activerecord/test/cases/view_test.rb @@ -154,7 +154,7 @@ if ActiveRecord::Base.connection.supports_views? end # sqlite dose not support CREATE, INSERT, and DELETE for VIEW - if current_adapter?(:Mysql2Adapter, :PostgreSQLAdapter) + if current_adapter?(:Mysql2Adapter, :PostgreSQLAdapter, :SQLServerAdapter) class UpdateableViewTest < ActiveRecord::TestCase self.use_transactional_tests = false fixtures :books @@ -200,7 +200,7 @@ if ActiveRecord::Base.connection.supports_views? end end end - end # end of `if current_adapter?(:Mysql2Adapter, :PostgreSQLAdapter)` + end # end of `if current_adapter?(:Mysql2Adapter, :PostgreSQLAdapter, :SQLServerAdapter)` end # end of `if ActiveRecord::Base.connection.supports_views?` if ActiveRecord::Base.connection.respond_to?(:supports_materialized_views?) && diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index ba6f5de894..b38b9661b3 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -1005,16 +1005,14 @@ ActiveRecord::Schema.define do create_table :records, force: true do |t| end - if supports_foreign_keys? - # fk_test_has_fk should be before fk_test_has_pk - create_table :fk_test_has_fk, force: true do |t| - t.bigint :fk_id, null: false + disable_referential_integrity do + create_table :fk_test_has_pk, primary_key: "pk_id", force: :cascade do |t| end - create_table :fk_test_has_pk, force: true, primary_key: "pk_id" do |t| + create_table :fk_test_has_fk, force: true do |t| + t.references :fk, null: false + t.foreign_key :fk_test_has_pk, column: "fk_id", name: "fk_name", primary_key: "pk_id" end - - add_foreign_key :fk_test_has_fk, :fk_test_has_pk, column: "fk_id", name: "fk_name", primary_key: "pk_id" end create_table :overloaded_types, force: true do |t| diff --git a/activerecord/test/schema/sqlite_specific_schema.rb b/activerecord/test/schema/sqlite_specific_schema.rb deleted file mode 100644 index cc7c36fe2b..0000000000 --- a/activerecord/test/schema/sqlite_specific_schema.rb +++ /dev/null @@ -1,18 +0,0 @@ -ActiveRecord::Schema.define do - execute "DROP TABLE fk_test_has_fk" rescue nil - execute "DROP TABLE fk_test_has_pk" rescue nil - execute <<_SQL - CREATE TABLE 'fk_test_has_pk' ( - 'pk_id' INTEGER NOT NULL PRIMARY KEY - ); -_SQL - - execute <<_SQL - CREATE TABLE 'fk_test_has_fk' ( - 'id' INTEGER NOT NULL PRIMARY KEY, - 'fk_id' INTEGER NOT NULL, - - FOREIGN KEY ('fk_id') REFERENCES 'fk_test_has_pk'('pk_id') - ); -_SQL -end diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md index 0bb6b2466c..5207194fba 100644 --- a/activesupport/CHANGELOG.md +++ b/activesupport/CHANGELOG.md @@ -1,3 +1,8 @@ +* Changed `ActiveSupport::Inflector#transliterate` to raise `ArgumentError` when it receives + anything except a string. + + *Kevin McPhillips* + * Fixed bugs that `StringInquirer#respond_to_missing?` and `ArrayInquirer#respond_to_missing?` do not fallback to `super`. diff --git a/activesupport/lib/active_support/core_ext/load_error.rb b/activesupport/lib/active_support/core_ext/load_error.rb index 029d6dd449..d273487010 100644 --- a/activesupport/lib/active_support/core_ext/load_error.rb +++ b/activesupport/lib/active_support/core_ext/load_error.rb @@ -6,18 +6,6 @@ class LoadError /^cannot load such file -- (.+)$/i, ] - unless method_defined?(:path) - # Returns the path which was unable to be loaded. - def path - @path ||= begin - REGEXPS.find do |regex| - message =~ regex - end - $1 - end - end - end - # Returns true if the given path name (except perhaps for the ".rb" # extension) is the missing file which caused the exception to be raised. def is_missing?(location) diff --git a/activesupport/lib/active_support/core_ext/string/output_safety.rb b/activesupport/lib/active_support/core_ext/string/output_safety.rb index 227c34b032..94ce3f6a61 100644 --- a/activesupport/lib/active_support/core_ext/string/output_safety.rb +++ b/activesupport/lib/active_support/core_ext/string/output_safety.rb @@ -152,18 +152,16 @@ module ActiveSupport #:nodoc: def [](*args) if args.size < 2 super - else - if html_safe? - new_safe_buffer = super - - if new_safe_buffer - new_safe_buffer.instance_variable_set :@html_safe, true - end + elsif html_safe? + new_safe_buffer = super - new_safe_buffer - else - to_str[*args] + if new_safe_buffer + new_safe_buffer.instance_variable_set :@html_safe, true end + + new_safe_buffer + else + to_str[*args] end end diff --git a/activesupport/lib/active_support/inflector/transliterate.rb b/activesupport/lib/active_support/inflector/transliterate.rb index 3e78986e8e..de6dd2720b 100644 --- a/activesupport/lib/active_support/inflector/transliterate.rb +++ b/activesupport/lib/active_support/inflector/transliterate.rb @@ -57,6 +57,8 @@ module ActiveSupport # transliterate('Jürgen') # # => "Juergen" def transliterate(string, replacement = "?".freeze) + raise ArgumentError, "Can only transliterate strings. Received #{string.class.name}" unless string.is_a?(String) + I18n.transliterate(ActiveSupport::Multibyte::Unicode.normalize( ActiveSupport::Multibyte::Unicode.tidy_bytes(string), :c), replacement: replacement) diff --git a/activesupport/test/abstract_unit.rb b/activesupport/test/abstract_unit.rb index 6b9daf0fe2..c4f34c0abf 100644 --- a/activesupport/test/abstract_unit.rb +++ b/activesupport/test/abstract_unit.rb @@ -24,16 +24,16 @@ ActiveSupport.to_time_preserves_timezone = ENV["PRESERVE_TIMEZONES"] == "1" # Disable available locale checks to avoid warnings running the test suite. I18n.enforce_available_locales = false -# Skips the current run on Rubinius using Minitest::Assertions#skip -def rubinius_skip(message = "") - skip message if RUBY_ENGINE == "rbx" -end - -# Skips the current run on JRuby using Minitest::Assertions#skip -def jruby_skip(message = "") - skip message if defined?(JRUBY_VERSION) -end - class ActiveSupport::TestCase include ActiveSupport::Testing::MethodCallAssertions + + # Skips the current run on Rubinius using Minitest::Assertions#skip + private def rubinius_skip(message = "") + skip message if RUBY_ENGINE == "rbx" + end + + # Skips the current run on JRuby using Minitest::Assertions#skip + private def jruby_skip(message = "") + skip message if defined?(JRUBY_VERSION) + end end diff --git a/activesupport/test/transliterate_test.rb b/activesupport/test/transliterate_test.rb index 040ddd25fc..466b69bcef 100644 --- a/activesupport/test/transliterate_test.rb +++ b/activesupport/test/transliterate_test.rb @@ -31,4 +31,22 @@ class TransliterateTest < ActiveSupport::TestCase def test_transliterate_should_allow_a_custom_replacement_char assert_equal "a*b", ActiveSupport::Inflector.transliterate("a索b", "*") end + + def test_transliterate_handles_empty_string + assert_equal "", ActiveSupport::Inflector.transliterate("") + end + + def test_transliterate_handles_nil + exception = assert_raises ArgumentError do + ActiveSupport::Inflector.transliterate(nil) + end + assert_equal "Can only transliterate strings. Received NilClass", exception.message + end + + def test_transliterate_handles_unknown_object + exception = assert_raises ArgumentError do + ActiveSupport::Inflector.transliterate(Object.new) + end + assert_equal "Can only transliterate strings. Received Object", exception.message + end end diff --git a/railties/lib/rails/tasks/yarn.rake b/railties/lib/rails/tasks/yarn.rake new file mode 100644 index 0000000000..bb99d38fde --- /dev/null +++ b/railties/lib/rails/tasks/yarn.rake @@ -0,0 +1,9 @@ +namespace :yarn do + desc "Install all JavaScript dependencies as specified via Yarn" + task :install do + system('./bin/yarn install') + end +end + +# Run Yarn prior to Sprockets assets precompilation, so dependencies are available for use. +Rake::Task['assets:precompile'].enhance [ 'yarn:install' ] diff --git a/railties/test/abstract_unit.rb b/railties/test/abstract_unit.rb index fd1e1b9662..e4b2d0457d 100644 --- a/railties/test/abstract_unit.rb +++ b/railties/test/abstract_unit.rb @@ -17,15 +17,15 @@ module TestApp end end -# Skips the current run on Rubinius using Minitest::Assertions#skip -def rubinius_skip(message = "") - skip message if RUBY_ENGINE == "rbx" -end -# Skips the current run on JRuby using Minitest::Assertions#skip -def jruby_skip(message = "") - skip message if defined?(JRUBY_VERSION) -end - class ActiveSupport::TestCase include ActiveSupport::Testing::Stream + + # Skips the current run on Rubinius using Minitest::Assertions#skip + private def rubinius_skip(message = "") + skip message if RUBY_ENGINE == "rbx" + end + # Skips the current run on JRuby using Minitest::Assertions#skip + private def jruby_skip(message = "") + skip message if defined?(JRUBY_VERSION) + end end |