1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
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 = String.new
mapping = TypeMap.new
mapping.register_type(/varchar/i, string)
assert_equal mapping.lookup('varchar(20)'), string
end
def test_aliasing_types
string = String.new
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 = String.new
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
|