mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
d163fcd620
Generators can create invalid migrations when passing an invalid field type. For example, when mixing up the name and type: bin/rails g model post string:title This will generate a field for post with a column named `string` of the type `title`, instead of a column named `title` of the type `string`. Running the migration will result in an error as the type `title` is not known to the database. Instead of generating invalid files, the generator should raise an error if the type is invalid. We validate the type by checking if it's a default migration types like: string, integer, datetime, but also references, and rich_text. If the type isn't a default type, we can ask the database connection if the type is valid. This uses the `valid_type?` method defined on each database adapter, which returns true if the adapter supports the column type. This method is also used by the SchemaDumper. Some gems like 'postgis' add custom types. The 'postgis' gem adds these types by overriding the `native_database_types` method. That method is used by `valid_type?` method on the database adapter, making this change compatible with 'postgis'.
190 lines
5.8 KiB
Ruby
190 lines
5.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "generators/generators_test_helper"
|
|
require "rails/generators/generated_attribute"
|
|
require "rails/generators/base"
|
|
|
|
class GeneratedAttributeTest < Rails::Generators::TestCase
|
|
include GeneratorsTestHelper
|
|
|
|
def setup
|
|
@old_belongs_to_required_by_default = Rails.application.config.active_record.belongs_to_required_by_default
|
|
Rails.application.config.active_record.belongs_to_required_by_default = true
|
|
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
|
|
end
|
|
|
|
def teardown
|
|
Rails.application.config.active_record.belongs_to_required_by_default = @old_belongs_to_required_by_default
|
|
end
|
|
|
|
def test_field_type_returns_number_field
|
|
assert_field_type :integer, :number_field
|
|
end
|
|
|
|
def test_field_type_returns_text_field
|
|
%w(float decimal string).each do |attribute_type|
|
|
assert_field_type attribute_type, :text_field
|
|
end
|
|
end
|
|
|
|
def test_field_type_returns_datetime_select
|
|
%w(datetime timestamp).each do |attribute_type|
|
|
assert_field_type attribute_type, :datetime_select
|
|
end
|
|
end
|
|
|
|
def test_field_type_returns_time_select
|
|
assert_field_type :time, :time_select
|
|
end
|
|
|
|
def test_field_type_returns_date_select
|
|
assert_field_type :date, :date_select
|
|
end
|
|
|
|
def test_field_type_returns_text_area
|
|
assert_field_type :text, :text_area
|
|
end
|
|
|
|
def test_field_type_returns_check_box
|
|
assert_field_type :boolean, :check_box
|
|
end
|
|
|
|
def test_field_type_returns_rich_text_area
|
|
assert_field_type :rich_text, :rich_text_area
|
|
end
|
|
|
|
def test_field_type_returns_file_field
|
|
%w(attachment attachments).each do |attribute_type|
|
|
assert_field_type attribute_type, :file_field
|
|
end
|
|
end
|
|
|
|
def test_field_type_with_unknown_type_raises_error
|
|
field_type = :unknown
|
|
e = assert_raise Rails::Generators::Error do
|
|
create_generated_attribute field_type
|
|
end
|
|
message = "Could not generate field 'test' with unknown type 'unknown'"
|
|
assert_match message, e.message
|
|
end
|
|
|
|
def test_default_value_is_integer
|
|
assert_field_default_value :integer, 1
|
|
end
|
|
|
|
def test_default_value_is_float
|
|
assert_field_default_value :float, 1.5
|
|
end
|
|
|
|
def test_default_value_is_decimal
|
|
assert_field_default_value :decimal, "9.99"
|
|
end
|
|
|
|
def test_default_value_is_datetime
|
|
%w(datetime timestamp time).each do |attribute_type|
|
|
assert_field_default_value attribute_type, Time.now.to_s(:db)
|
|
end
|
|
end
|
|
|
|
def test_default_value_is_date
|
|
assert_field_default_value :date, Date.today.to_s(:db)
|
|
end
|
|
|
|
def test_default_value_is_string
|
|
assert_field_default_value :string, "MyString"
|
|
end
|
|
|
|
def test_default_value_for_type
|
|
att = Rails::Generators::GeneratedAttribute.parse("type:string")
|
|
assert_equal("", att.default)
|
|
end
|
|
|
|
def test_default_value_is_text
|
|
assert_field_default_value :text, "MyText"
|
|
end
|
|
|
|
def test_default_value_is_boolean
|
|
assert_field_default_value :boolean, false
|
|
end
|
|
|
|
def test_default_value_is_nil
|
|
%w(references belongs_to rich_text attachment attachments).each do |attribute_type|
|
|
assert_field_default_value attribute_type, nil
|
|
end
|
|
end
|
|
|
|
def test_default_value_is_empty_string
|
|
%w(digest token).each do |attribute_type|
|
|
assert_field_default_value attribute_type, ""
|
|
end
|
|
end
|
|
|
|
def test_human_name
|
|
assert_equal(
|
|
"Full name",
|
|
create_generated_attribute(:string, "full_name").human_name
|
|
)
|
|
end
|
|
|
|
def test_reference_is_true
|
|
%w(references belongs_to).each do |attribute_type|
|
|
assert_predicate create_generated_attribute(attribute_type), :reference?
|
|
end
|
|
end
|
|
|
|
def test_reference_is_false
|
|
%w(string text float).each do |attribute_type|
|
|
assert_not_predicate create_generated_attribute(attribute_type), :reference?
|
|
end
|
|
end
|
|
|
|
def test_polymorphic_reference_is_true
|
|
%w(references belongs_to).each do |attribute_type|
|
|
assert_predicate create_generated_attribute("#{attribute_type}{polymorphic}"), :polymorphic?
|
|
end
|
|
end
|
|
|
|
def test_polymorphic_reference_is_false
|
|
%w(references belongs_to).each do |attribute_type|
|
|
assert_not_predicate create_generated_attribute(attribute_type), :polymorphic?
|
|
end
|
|
end
|
|
|
|
def test_blank_type_defaults_to_string
|
|
assert_equal :string, create_generated_attribute(nil, "title").type
|
|
assert_equal :string, create_generated_attribute("", "title").type
|
|
end
|
|
|
|
def test_handles_index_names_for_references
|
|
assert_equal "post", create_generated_attribute("string", "post").index_name
|
|
assert_equal "post_id", create_generated_attribute("references", "post").index_name
|
|
assert_equal "post_id", create_generated_attribute("belongs_to", "post").index_name
|
|
assert_equal ["post_id", "post_type"], create_generated_attribute("references{polymorphic}", "post").index_name
|
|
end
|
|
|
|
def test_handles_column_names_for_references
|
|
assert_equal "post", create_generated_attribute("string", "post").column_name
|
|
assert_equal "post_id", create_generated_attribute("references", "post").column_name
|
|
assert_equal "post_id", create_generated_attribute("belongs_to", "post").column_name
|
|
end
|
|
|
|
def test_parse_works_with_adapter_specific_types
|
|
att = Rails::Generators::GeneratedAttribute.parse("document:json")
|
|
assert_equal "document", att.name
|
|
assert_equal :json, att.type
|
|
end
|
|
|
|
def test_parse_required_attribute_with_index
|
|
att = Rails::Generators::GeneratedAttribute.parse("supplier:references:index")
|
|
assert_equal "supplier", att.name
|
|
assert_equal :references, att.type
|
|
assert_predicate att, :has_index?
|
|
assert_predicate att, :required?
|
|
end
|
|
|
|
def test_parse_required_attribute_with_index_false_when_belongs_to_required_by_default_global_config_is_false
|
|
Rails.application.config.active_record.belongs_to_required_by_default = false
|
|
att = Rails::Generators::GeneratedAttribute.parse("supplier:references:index")
|
|
assert_not_predicate att, :required?
|
|
end
|
|
end
|