# frozen_string_literal: true require "cases/helper" module ActiveRecord module Type class TypeMapTest < ActiveRecord::TestCase def test_default_type mapping = TypeMap.new assert_kind_of Value, mapping.lookup(:undefined) end def test_registering_types boolean = Boolean.new mapping = TypeMap.new mapping.register_type(/boolean/i, boolean) assert_equal mapping.lookup("boolean"), boolean end def test_overriding_registered_types time = Time.new timestamp = DateTime.new mapping = TypeMap.new mapping.register_type(/time/i, time) mapping.register_type(/time/i, timestamp) assert_equal mapping.lookup("time"), timestamp end def test_fuzzy_lookup string = +"" mapping = TypeMap.new mapping.register_type(/varchar/i, string) assert_equal mapping.lookup("varchar(20)"), string end def test_aliasing_types string = +"" mapping = TypeMap.new mapping.register_type(/string/i, string) mapping.alias_type(/varchar/i, "string") assert_equal mapping.lookup("varchar"), string end def test_changing_type_changes_aliases time = Time.new timestamp = DateTime.new mapping = TypeMap.new mapping.register_type(/timestamp/i, time) mapping.alias_type(/datetime/i, "timestamp") mapping.register_type(/timestamp/i, timestamp) assert_equal mapping.lookup("datetime"), timestamp end def test_aliases_keep_metadata mapping = TypeMap.new mapping.register_type(/decimal/i) { |sql_type| sql_type } mapping.alias_type(/number/i, "decimal") assert_equal mapping.lookup("number(20)"), "decimal(20)" assert_equal mapping.lookup("number"), "decimal" end def test_register_proc string = +"" binary = Binary.new mapping = TypeMap.new mapping.register_type(/varchar/i) do |type| if type.include?("(") string else binary end end assert_equal mapping.lookup("varchar(20)"), string assert_equal mapping.lookup("varchar"), binary end def test_additional_lookup_args mapping = TypeMap.new mapping.register_type(/varchar/i) do |type, limit| if limit > 255 "text" else "string" end end mapping.alias_type(/string/i, "varchar") assert_equal mapping.lookup("varchar", 200), "string" assert_equal mapping.lookup("varchar", 400), "text" assert_equal mapping.lookup("string", 400), "text" end def test_requires_value_or_block mapping = TypeMap.new assert_raises(ArgumentError) do mapping.register_type(/only key/i) end end def test_lookup_non_strings mapping = HashLookupTypeMap.new mapping.register_type(1, "string") mapping.register_type(2, "int") mapping.alias_type(3, 1) assert_equal mapping.lookup(1), "string" assert_equal mapping.lookup(2), "int" assert_equal mapping.lookup(3), "string" assert_kind_of Type::Value, mapping.lookup(4) end def test_fetch mapping = TypeMap.new mapping.register_type(1, "string") assert_equal "string", mapping.fetch(1) { "int" } assert_equal "int", mapping.fetch(2) { "int" } end def test_fetch_yields_args mapping = TypeMap.new assert_equal "foo-1-2-3", mapping.fetch("foo", 1, 2, 3) { |*args| args.join("-") } assert_equal "bar-1-2-3", mapping.fetch("bar", 1, 2, 3) { |*args| args.join("-") } end def test_fetch_memoizes mapping = TypeMap.new looked_up = false mapping.register_type(1) do fail if looked_up looked_up = true "string" end assert_equal "string", mapping.fetch(1) assert_equal "string", mapping.fetch(1) end def test_fetch_memoizes_on_args mapping = TypeMap.new mapping.register_type("foo") { |*args| args.join("-") } assert_equal "foo-1-2-3", mapping.fetch("foo", 1, 2, 3) { |*args| args.join("-") } assert_equal "foo-2-3-4", mapping.fetch("foo", 2, 3, 4) { |*args| args.join("-") } end def test_register_clears_cache mapping = TypeMap.new mapping.register_type(1, "string") mapping.lookup(1) mapping.register_type(1, "int") assert_equal "int", mapping.lookup(1) end end end end