rdl 2.1.0 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/.travis.yml +7 -6
- data/CHANGES.md +29 -0
- data/README.md +94 -26
- data/lib/rdl/boot.rb +82 -41
- data/lib/rdl/boot_rails.rb +5 -0
- data/lib/rdl/config.rb +9 -1
- data/lib/rdl/query.rb +2 -2
- data/lib/rdl/typecheck.rb +972 -225
- data/lib/rdl/types/annotated_arg.rb +8 -0
- data/lib/rdl/types/ast_node.rb +73 -0
- data/lib/rdl/types/bot.rb +8 -0
- data/lib/rdl/types/bound_arg.rb +63 -0
- data/lib/rdl/types/computed.rb +48 -0
- data/lib/rdl/types/dependent_arg.rb +9 -0
- data/lib/rdl/types/dynamic.rb +61 -0
- data/lib/rdl/types/finite_hash.rb +54 -9
- data/lib/rdl/types/generic.rb +33 -0
- data/lib/rdl/types/intersection.rb +8 -0
- data/lib/rdl/types/lexer.rex +6 -1
- data/lib/rdl/types/lexer.rex.rb +13 -1
- data/lib/rdl/types/method.rb +14 -0
- data/lib/rdl/types/nominal.rb +8 -0
- data/lib/rdl/types/non_null.rb +8 -0
- data/lib/rdl/types/optional.rb +8 -0
- data/lib/rdl/types/parser.racc +31 -5
- data/lib/rdl/types/parser.tab.rb +540 -302
- data/lib/rdl/types/rdl_types.rb +45 -0
- data/lib/rdl/types/singleton.rb +14 -1
- data/lib/rdl/types/string.rb +104 -0
- data/lib/rdl/types/structural.rb +8 -0
- data/lib/rdl/types/top.rb +8 -0
- data/lib/rdl/types/tuple.rb +32 -8
- data/lib/rdl/types/type.rb +54 -11
- data/lib/rdl/types/union.rb +41 -2
- data/lib/rdl/types/var.rb +10 -0
- data/lib/rdl/types/vararg.rb +8 -0
- data/lib/rdl/util.rb +13 -10
- data/lib/rdl/wrap.rb +271 -27
- data/lib/rdl_disable.rb +16 -2
- data/lib/types/active_record.rb +1 -0
- data/lib/types/core/array.rb +442 -23
- data/lib/types/core/basic_object.rb +3 -3
- data/lib/types/core/bigdecimal.rb +5 -0
- data/lib/types/core/class.rb +2 -0
- data/lib/types/core/dir.rb +3 -3
- data/lib/types/core/enumerable.rb +4 -4
- data/lib/types/core/enumerator.rb +1 -1
- data/lib/types/core/file.rb +4 -4
- data/lib/types/core/float.rb +203 -0
- data/lib/types/core/hash.rb +390 -15
- data/lib/types/core/integer.rb +223 -10
- data/lib/types/core/io.rb +2 -2
- data/lib/types/core/kernel.rb +8 -5
- data/lib/types/core/marshal.rb +3 -0
- data/lib/types/core/module.rb +3 -3
- data/lib/types/core/numeric.rb +0 -2
- data/lib/types/core/object.rb +5 -5
- data/lib/types/core/pathname.rb +2 -2
- data/lib/types/core/process.rb +1 -3
- data/lib/types/core/range.rb +1 -1
- data/lib/types/core/regexp.rb +2 -2
- data/lib/types/core/set.rb +1 -1
- data/lib/types/core/string.rb +408 -16
- data/lib/types/core/symbol.rb +3 -3
- data/lib/types/core/time.rb +1 -1
- data/lib/types/core/uri.rb +13 -13
- data/lib/types/rails/_helpers.rb +7 -1
- data/lib/types/rails/action_controller/mime_responds.rb +2 -0
- data/lib/types/rails/active_record/associations.rb +42 -30
- data/lib/types/rails/active_record/comp_types.rb +637 -0
- data/lib/types/rails/active_record/finder_methods.rb +1 -1
- data/lib/types/rails/active_record/model_schema.rb +28 -16
- data/lib/types/rails/active_record/relation.rb +5 -3
- data/lib/types/rails/active_record/sql-strings.rb +166 -0
- data/lib/types/rails/string.rb +1 -1
- data/lib/types/sequel.rb +1 -0
- data/lib/types/sequel/comp_types.rb +581 -0
- data/rdl.gemspec +5 -4
- data/test/test_alias.rb +4 -0
- data/test/test_array_types.rb +244 -0
- data/test/test_bound_types.rb +80 -0
- data/test/test_contract.rb +4 -0
- data/test/test_dsl.rb +5 -0
- data/test/test_dyn_comptype_checks.rb +206 -0
- data/test/test_generic.rb +21 -20
- data/test/test_hash_types.rb +322 -0
- data/test/test_intersection.rb +1 -0
- data/test/test_le.rb +29 -4
- data/test/test_member.rb +3 -1
- data/test/test_parser.rb +5 -0
- data/test/test_query.rb +1 -0
- data/test/test_rdl.rb +63 -28
- data/test/test_rdl_type.rb +4 -0
- data/test/test_string_types.rb +102 -0
- data/test/test_type_contract.rb +59 -37
- data/test/test_typecheck.rb +480 -75
- data/test/test_types.rb +17 -0
- data/test/test_wrap.rb +5 -0
- metadata +35 -5
- data/lib/types/rails/active_record/schema_types.rb +0 -51
data/test/test_generic.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'minitest/autorun'
|
2
2
|
$LOAD_PATH << File.dirname(__FILE__) + "/../lib"
|
3
3
|
require 'rdl'
|
4
|
+
RDL.reset
|
4
5
|
|
5
6
|
class TestGeneric < Minitest::Test
|
6
7
|
extend RDL::Annotate
|
@@ -8,8 +9,6 @@ class TestGeneric < Minitest::Test
|
|
8
9
|
# Make two classes that wrap Array and Hash, so we don't mess with their
|
9
10
|
# implementations in test case evaluation.
|
10
11
|
class A
|
11
|
-
extend RDL::Annotate
|
12
|
-
type_params [:t], :all?
|
13
12
|
def initialize(a); @a = a end
|
14
13
|
def all?(&blk)
|
15
14
|
@a.all?(&blk)
|
@@ -17,8 +16,6 @@ class TestGeneric < Minitest::Test
|
|
17
16
|
end
|
18
17
|
|
19
18
|
class H
|
20
|
-
extend RDL::Annotate
|
21
|
-
type_params [:k, :v], :all?
|
22
19
|
def initialize(h); @h = h end
|
23
20
|
def all?(&blk)
|
24
21
|
@h.all? { |x, y| blk.call(x, y) } # have to do extra wrap to avoid splat issues
|
@@ -28,9 +25,7 @@ class TestGeneric < Minitest::Test
|
|
28
25
|
class B
|
29
26
|
extend RDL::Annotate
|
30
27
|
# class for checking other variance annotations
|
31
|
-
|
32
|
-
type "(a) -> nil"
|
33
|
-
def m1(x)
|
28
|
+
def m1(x) # type annotation
|
34
29
|
nil
|
35
30
|
end
|
36
31
|
def m2(x) # no type annotation
|
@@ -38,7 +33,26 @@ class TestGeneric < Minitest::Test
|
|
38
33
|
end
|
39
34
|
end
|
40
35
|
|
36
|
+
class C
|
37
|
+
def m1() return self; end
|
38
|
+
def m2() return C.new; end
|
39
|
+
def m3() return Object.new; end
|
40
|
+
end
|
41
|
+
|
42
|
+
class D < C
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
|
41
47
|
def setup
|
48
|
+
RDL.reset
|
49
|
+
RDL.type_params A, [:t], :all?
|
50
|
+
RDL.type_params H, [:k, :v], :all?
|
51
|
+
RDL.type_params(B, [:a, :b], nil, variance: [:+, :-]) { |a, b| true }
|
52
|
+
RDL.type B, :m1, "(a) -> nil"
|
53
|
+
RDL.type C, :m1, "() -> self"
|
54
|
+
RDL.type C, :m2, "() -> self"
|
55
|
+
RDL.type C, :m3, "() -> self"
|
42
56
|
@ta = RDL::Type::NominalType.new "TestGeneric::A"
|
43
57
|
@th = RDL::Type::NominalType.new "TestGeneric::H"
|
44
58
|
@tas = RDL::Type::GenericType.new(@ta, RDL::Globals.types[:string])
|
@@ -111,19 +125,6 @@ class TestGeneric < Minitest::Test
|
|
111
125
|
assert (tbss <= ts5)
|
112
126
|
end
|
113
127
|
|
114
|
-
class C
|
115
|
-
extend RDL::Annotate
|
116
|
-
type "() -> self"
|
117
|
-
def m1() return self; end
|
118
|
-
type "() -> self"
|
119
|
-
def m2() return C.new; end
|
120
|
-
type "() -> self"
|
121
|
-
def m3() return Object.new; end
|
122
|
-
end
|
123
|
-
|
124
|
-
class D < C
|
125
|
-
end
|
126
|
-
|
127
128
|
def test_self_type
|
128
129
|
c = C.new
|
129
130
|
assert(c.m1)
|
@@ -0,0 +1,322 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
$LOAD_PATH << File.dirname(__FILE__) + "/../lib"
|
3
|
+
require 'rdl'
|
4
|
+
require 'types/core'
|
5
|
+
|
6
|
+
|
7
|
+
class TestHashTypes < Minitest::Test
|
8
|
+
extend RDL::Annotate
|
9
|
+
|
10
|
+
def setup
|
11
|
+
require 'types/core'
|
12
|
+
RDL.readd_comp_types
|
13
|
+
RDL.type_params :Hash, [:k, :v], :all? unless RDL::Globals.type_params["Hash"]
|
14
|
+
RDL.type_params :Array, [:t], :all? unless RDL::Globals.type_params["Array"]
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_hash_methods
|
18
|
+
self.class.class_eval {
|
19
|
+
type '({bar: Integer, baz: String}) -> String', typecheck: :now
|
20
|
+
def access_test1(x)
|
21
|
+
x[:baz]
|
22
|
+
end
|
23
|
+
|
24
|
+
type '({bar: Integer, baz: String}) -> {bar: Integer, baz: String}', typecheck: :now
|
25
|
+
def access_test2(x)
|
26
|
+
x[:baz]
|
27
|
+
x
|
28
|
+
end
|
29
|
+
|
30
|
+
type '(Symbol, {bar: Integer, baz: String}) -> String or Integer', typecheck: :now
|
31
|
+
def access_test3(y, x)
|
32
|
+
x[y]
|
33
|
+
end
|
34
|
+
|
35
|
+
type '(Hash) -> v', typecheck: :now
|
36
|
+
def access_test4(x)
|
37
|
+
x[:blah]
|
38
|
+
end
|
39
|
+
|
40
|
+
type '(Hash<Symbol, Integer or String>) -> Integer or String', typecheck: :now
|
41
|
+
def access_test5(x)
|
42
|
+
x[:baz]
|
43
|
+
end
|
44
|
+
|
45
|
+
type '({ foo: 1, Symbol: String }) -> 1 or String', typecheck: :now
|
46
|
+
def access_test6(x)
|
47
|
+
x[:blah]
|
48
|
+
end
|
49
|
+
|
50
|
+
type '({bar: Integer, baz: String}) -> Integer', typecheck: :access_fail1
|
51
|
+
def access_fail_test1(x)
|
52
|
+
x[:baz]
|
53
|
+
end
|
54
|
+
|
55
|
+
type '(Hash<Symbol, Integer or String>) -> Integer', typecheck: :access_fail2
|
56
|
+
def access_fail_test2(x)
|
57
|
+
x[:baz]
|
58
|
+
end
|
59
|
+
|
60
|
+
type '({ bar: 1, baz: 2 }) -> :bar', typecheck: :now
|
61
|
+
def key_test1(x)
|
62
|
+
x.key(1)
|
63
|
+
end
|
64
|
+
|
65
|
+
type '({ bar: Integer, baz: String }) -> Symbol', typecheck: :now
|
66
|
+
def key_test2(x)
|
67
|
+
x.key(1)
|
68
|
+
end
|
69
|
+
|
70
|
+
type '(Hash<Symbol, Integer>) -> Symbol', typecheck: :now
|
71
|
+
def key_test3(x)
|
72
|
+
x.key(1)
|
73
|
+
end
|
74
|
+
|
75
|
+
type '({ bar: Integer, baz: String }) -> { bar: Integer, baz: String, foo: Integer }', typecheck: :now
|
76
|
+
def merge_test1(x)
|
77
|
+
x.merge({ foo: 1 })
|
78
|
+
end
|
79
|
+
|
80
|
+
type '({ bar: Integer, baz: String }) -> { bar: String, baz: String }', typecheck: :now
|
81
|
+
def merge_test2(x)
|
82
|
+
x.merge({ bar: 'hi' })
|
83
|
+
end
|
84
|
+
|
85
|
+
type '(Hash<Integer, String>, { bar: Integer, baz: String }) -> Hash<Integer or Symbol, Integer or String>', typecheck: :now
|
86
|
+
def merge_test3(x, y)
|
87
|
+
x.merge(y)
|
88
|
+
end
|
89
|
+
|
90
|
+
type '(Hash<Integer, String>, { bar: Integer, baz: String }) -> Hash<Integer or Symbol, Integer or String>', typecheck: :now
|
91
|
+
def merge_test4(x, y)
|
92
|
+
y.merge(x)
|
93
|
+
end
|
94
|
+
|
95
|
+
type '(Hash<Integer, String>, Hash<Symbol, Integer>) -> Hash<Integer or Symbol, String or Integer>', typecheck: :now
|
96
|
+
def merge_test5(x, y)
|
97
|
+
x.merge(y)
|
98
|
+
end
|
99
|
+
|
100
|
+
type '(Hash<Integer, String>, Hash<Symbol, Integer>) -> Hash<Integer or Symbol, String or Integer>', typecheck: :now
|
101
|
+
def merge_test6(x, y)
|
102
|
+
y.merge(x)
|
103
|
+
end
|
104
|
+
|
105
|
+
type '(Hash, { bar: Integer, baz: String }) -> Hash', typecheck: :now
|
106
|
+
def merge_test7(x, y)
|
107
|
+
x.merge(y)
|
108
|
+
end
|
109
|
+
|
110
|
+
type '(Hash, { bar: Integer, baz: String }) -> Hash', typecheck: :now
|
111
|
+
def merge_test8(x, y)
|
112
|
+
y.merge(x)
|
113
|
+
end
|
114
|
+
|
115
|
+
type '(Hash, Hash<Integer, String>) -> Hash', typecheck: :now
|
116
|
+
def merge_test9(x, y)
|
117
|
+
x.merge(y)
|
118
|
+
end
|
119
|
+
|
120
|
+
type '(Hash, Hash<Integer, String>) -> Hash', typecheck: :now
|
121
|
+
def merge_test10(x, y)
|
122
|
+
y.merge(x)
|
123
|
+
end
|
124
|
+
|
125
|
+
type '({ bar: Integer, baz: String}) -> 2', typecheck: :now
|
126
|
+
def length_test1(x)
|
127
|
+
x.length
|
128
|
+
end
|
129
|
+
|
130
|
+
type '(Hash<Integer, String>) -> Integer', typecheck: :now
|
131
|
+
def length_test2(x)
|
132
|
+
x.length
|
133
|
+
end
|
134
|
+
|
135
|
+
type '({ hi: 1}) -> false', typecheck: :now
|
136
|
+
def empty_test1(x)
|
137
|
+
x.empty?
|
138
|
+
end
|
139
|
+
|
140
|
+
type '() -> true', typecheck: :now
|
141
|
+
def empty_test2()
|
142
|
+
x = {}
|
143
|
+
x.empty?
|
144
|
+
end
|
145
|
+
|
146
|
+
type '(Hash) -> %bool', typecheck: :now
|
147
|
+
def empty_test3(x)
|
148
|
+
x.empty?
|
149
|
+
end
|
150
|
+
|
151
|
+
type '(Hash<Symbol, String>) -> %bool', typecheck: :now
|
152
|
+
def empty_test4(x)
|
153
|
+
x.empty?
|
154
|
+
end
|
155
|
+
|
156
|
+
type '({ baz: Integer, 1 => 2 }) -> [:baz, 1]', typecheck: :now
|
157
|
+
def keys_test1(x)
|
158
|
+
x.keys
|
159
|
+
end
|
160
|
+
|
161
|
+
type '(Hash<Symbol, Integer>) -> Array<Symbol>', typecheck: :now
|
162
|
+
def keys_test2(x)
|
163
|
+
x.keys
|
164
|
+
end
|
165
|
+
|
166
|
+
|
167
|
+
type '({ foo: Integer }) -> { foo: Integer, bar: String }', typecheck: :now
|
168
|
+
def assign_test1(x)
|
169
|
+
x[:bar] = "2"
|
170
|
+
x
|
171
|
+
end
|
172
|
+
|
173
|
+
type '(Hash<Symbol, Integer>) -> Integer', typecheck: :now
|
174
|
+
def assign_test2(x)
|
175
|
+
x[:blah] = 42
|
176
|
+
x[:foo]
|
177
|
+
end
|
178
|
+
|
179
|
+
type '() -> Integer', typecheck: :now
|
180
|
+
def assign_test3()
|
181
|
+
x = {foo: 1, bar: 2, baz: 3}
|
182
|
+
x[:bar] = 3
|
183
|
+
end
|
184
|
+
|
185
|
+
type '({foo: Integer}) -> 42', typecheck: :now
|
186
|
+
def assign_test4(x)
|
187
|
+
x[:bar] = 42
|
188
|
+
x[:bar]
|
189
|
+
end
|
190
|
+
|
191
|
+
type '(Integer, { foo: String }) -> Hash<Symbol or Integer, String or Integer>', typecheck: :now
|
192
|
+
def assign_test5(i, x)
|
193
|
+
x[i] = i
|
194
|
+
x
|
195
|
+
end
|
196
|
+
|
197
|
+
type '({ foo: 1 }) -> { foo: 1 or 2 }', typecheck: :now
|
198
|
+
def assign_test6(x)
|
199
|
+
x[:foo] = 2
|
200
|
+
x
|
201
|
+
end
|
202
|
+
|
203
|
+
type :hash_callee, '({ foo: 1 or 2 }) -> %bool'
|
204
|
+
|
205
|
+
type '({ foo: 1 }) -> { foo: 1 or 2 }', typecheck: :now
|
206
|
+
def assign_test7(x)
|
207
|
+
hash_callee(x)
|
208
|
+
x[:foo] = 2
|
209
|
+
x
|
210
|
+
end
|
211
|
+
|
212
|
+
type '({ foo: 1 }) -> String', typecheck: :assign_fail1
|
213
|
+
def assign_fail_test1(x)
|
214
|
+
hash_callee(x)
|
215
|
+
x[:foo] = "2"
|
216
|
+
end
|
217
|
+
|
218
|
+
type '(Hash<Symbol, Integer>) -> %any', typecheck: :assign_fail2
|
219
|
+
def assign_fail_test2(x)
|
220
|
+
x[:blah] = 'hi'
|
221
|
+
end
|
222
|
+
|
223
|
+
type '(Hash<Symbol, Integer>) -> %any', typecheck: :assign_fail3
|
224
|
+
def assign_fail_test3(x)
|
225
|
+
x['string'] = 2
|
226
|
+
end
|
227
|
+
|
228
|
+
type '({ foo: 1, bar: String }) -> [:bar, String]', typecheck: :now
|
229
|
+
def assoc_test1(x)
|
230
|
+
x.assoc(:bar)
|
231
|
+
end
|
232
|
+
|
233
|
+
type '(Symbol, { foo: 1, bar: String }) -> [Symbol, Integer or String]', typecheck: :now
|
234
|
+
def assoc_test2(y, x)
|
235
|
+
x.assoc(y)
|
236
|
+
end
|
237
|
+
|
238
|
+
type '(Hash<Symbol, Integer>) -> [Symbol, Integer]'
|
239
|
+
def assoc_test3(x)
|
240
|
+
x.assoc(42)
|
241
|
+
end
|
242
|
+
|
243
|
+
type '({ foo: 1 }) -> true', typecheck: :now
|
244
|
+
def has_key_test1(x)
|
245
|
+
x.has_key?(:foo)
|
246
|
+
end
|
247
|
+
|
248
|
+
type '({ foo: 1 }) -> false', typecheck: :now
|
249
|
+
def has_key_test2(x)
|
250
|
+
x.has_key?(:bar)
|
251
|
+
end
|
252
|
+
|
253
|
+
type '(Symbol, { foo: 1 }) -> %bool', typecheck: :now
|
254
|
+
def has_key_test3(y, x)
|
255
|
+
x.has_key?(y)
|
256
|
+
end
|
257
|
+
|
258
|
+
type '(Symbol, Hash<Symbol, Integer>) -> %bool', typecheck: :now
|
259
|
+
def has_key_test4(y, x)
|
260
|
+
x.has_key?(y)
|
261
|
+
end
|
262
|
+
|
263
|
+
type '(String) -> { a: 1, b: String }', typecheck: :now
|
264
|
+
def create_test1(x)
|
265
|
+
Hash[:a, 1, :b, x]
|
266
|
+
end
|
267
|
+
|
268
|
+
type '() -> %any', typecheck: :create_fail1
|
269
|
+
def create_fail_test1
|
270
|
+
Hash[1, 2, 3]
|
271
|
+
end
|
272
|
+
|
273
|
+
type '({ foo: 1, bar: 2 }) -> 1', typecheck: :now
|
274
|
+
def delete_test1(x)
|
275
|
+
x.delete(:foo)
|
276
|
+
end
|
277
|
+
|
278
|
+
type '({ foo: 1, bar: 2 }) -> { foo: 1, bar: 2 }', typecheck: :now
|
279
|
+
def delete_test2(x)
|
280
|
+
x.delete(:foo)
|
281
|
+
x
|
282
|
+
end
|
283
|
+
|
284
|
+
type '(Symbol, {foo: 1, bar: 2}) -> 1 or 2', typecheck: :now
|
285
|
+
def delete_test3(s, x)
|
286
|
+
x.delete(s)
|
287
|
+
end
|
288
|
+
|
289
|
+
type '(Symbol, Hash<Symbol, Integer>) -> Integer', typecheck: :now
|
290
|
+
def delete_test4(s, x)
|
291
|
+
x.delete(s)
|
292
|
+
end
|
293
|
+
|
294
|
+
type '(Symbol, { foo: 1 }) -> Integer or String'
|
295
|
+
def delete_test5(s, x)
|
296
|
+
x.delete(s) { |i| "hi" }
|
297
|
+
end
|
298
|
+
|
299
|
+
type '({ foo: 1, bar: String, baz: Integer }) -> [1, String]', typecheck: :now
|
300
|
+
def values_at_test1(x)
|
301
|
+
x.values_at(:foo, :bar)
|
302
|
+
end
|
303
|
+
|
304
|
+
type '(Symbol, { foo: 1, bar: String, baz: Integer }) -> Array<Integer or String>', typecheck: :now
|
305
|
+
def values_at_test2(s, x)
|
306
|
+
x.values_at(:foo, s)
|
307
|
+
end
|
308
|
+
|
309
|
+
type '({ foo: 1, Symbol: String, baz: Integer }) -> Array<Integer or String>', typecheck: :now
|
310
|
+
def values_at_test3(x)
|
311
|
+
x.values_at(:foo, :blah)
|
312
|
+
end
|
313
|
+
}
|
314
|
+
assert_raises(RDL::Typecheck::StaticTypeError) { RDL.do_typecheck :access_fail1 }
|
315
|
+
assert_raises(RDL::Typecheck::StaticTypeError) { RDL.do_typecheck :access_fail2 }
|
316
|
+
assert_raises(RDL::Typecheck::StaticTypeError) { RDL.do_typecheck :assign_fail1 }
|
317
|
+
assert_raises(RDL::Typecheck::StaticTypeError) { RDL.do_typecheck :assign_fail2 }
|
318
|
+
assert_raises(RDL::Typecheck::StaticTypeError) { RDL.do_typecheck :assign_fail3 }
|
319
|
+
assert_raises(RDL::Typecheck::StaticTypeError) { RDL.do_typecheck :create_fail1 }
|
320
|
+
end
|
321
|
+
|
322
|
+
end
|
data/test/test_intersection.rb
CHANGED
data/test/test_le.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'minitest/autorun'
|
2
2
|
$LOAD_PATH << File.dirname(__FILE__) + "/../lib"
|
3
3
|
require 'rdl'
|
4
|
-
require 'types/core'
|
5
4
|
|
6
5
|
class TestLe < Minitest::Test
|
7
6
|
include RDL::Type
|
@@ -21,6 +20,7 @@ class TestLe < Minitest::Test
|
|
21
20
|
end
|
22
21
|
|
23
22
|
def setup
|
23
|
+
RDL.reset
|
24
24
|
@tbasicobject = NominalType.new "BasicObject"
|
25
25
|
@tsymfoo = SingletonType.new :foo
|
26
26
|
@ta = NominalType.new A
|
@@ -54,6 +54,24 @@ class TestLe < Minitest::Test
|
|
54
54
|
assert (@tsymfoo <= RDL::Globals.types[:top])
|
55
55
|
end
|
56
56
|
|
57
|
+
def test_dyn
|
58
|
+
assert (RDL::Globals.types[:dyn] <= RDL::Globals.types[:nil])
|
59
|
+
assert (RDL::Globals.types[:nil] <= RDL::Globals.types[:dyn])
|
60
|
+
assert (RDL::Globals.types[:dyn] <= RDL::Globals.types[:top])
|
61
|
+
assert (RDL::Globals.types[:top] <= RDL::Globals.types[:dyn])
|
62
|
+
assert (RDL::Globals.types[:dyn] <= RDL::Globals.types[:bot])
|
63
|
+
assert (RDL::Globals.types[:bot] <= RDL::Globals.types[:dyn])
|
64
|
+
assert (RDL::Globals.types[:dyn] <= RDL::Globals.types[:dyn])
|
65
|
+
assert (RDL::Globals.types[:dyn] <= RDL::Globals.types[:string])
|
66
|
+
assert (RDL::Globals.types[:string] <= RDL::Globals.types[:dyn])
|
67
|
+
assert (RDL::Globals.types[:dyn] <= RDL::Globals.types[:object])
|
68
|
+
assert (RDL::Globals.types[:object] <= RDL::Globals.types[:dyn])
|
69
|
+
assert (RDL::Globals.types[:dyn] <= @tbasicobject)
|
70
|
+
assert (@tbasicobject <= RDL::Globals.types[:dyn])
|
71
|
+
assert (RDL::Globals.types[:dyn] <= @tsymfoo)
|
72
|
+
assert (@tsymfoo <= RDL::Globals.types[:dyn])
|
73
|
+
end
|
74
|
+
|
57
75
|
def test_sym
|
58
76
|
assert (RDL::Globals.types[:symbol] <= RDL::Globals.types[:symbol])
|
59
77
|
assert (@tsymfoo <= @tsymfoo)
|
@@ -90,6 +108,8 @@ class TestLe < Minitest::Test
|
|
90
108
|
end
|
91
109
|
|
92
110
|
def test_tuple
|
111
|
+
RDL.type_params :Array, [:t], :all?
|
112
|
+
|
93
113
|
t1 = TupleType.new(RDL::Globals.types[:symbol], RDL::Globals.types[:string])
|
94
114
|
t2 = TupleType.new(RDL::Globals.types[:object], RDL::Globals.types[:object])
|
95
115
|
tarray = NominalType.new("Array")
|
@@ -131,6 +151,8 @@ class TestLe < Minitest::Test
|
|
131
151
|
end
|
132
152
|
|
133
153
|
def test_finite_hash
|
154
|
+
RDL.type_params :Hash, [:k, :v], :all?
|
155
|
+
|
134
156
|
t12 = tt "{a: 1, b: 2}"
|
135
157
|
tfs = tt "{a: Integer, b: Integer}"
|
136
158
|
too = tt "{a: Object, b: Object}"
|
@@ -248,18 +270,18 @@ class TestLe < Minitest::Test
|
|
248
270
|
end
|
249
271
|
|
250
272
|
class NomT
|
251
|
-
extend RDL::Annotate
|
252
|
-
type "() -> nil"
|
253
273
|
def m1()
|
254
274
|
nil
|
255
275
|
end
|
256
|
-
type "() -> nil"
|
257
276
|
def m2()
|
258
277
|
nil
|
259
278
|
end
|
260
279
|
end
|
261
280
|
|
262
281
|
def test_nominal_structural
|
282
|
+
RDL.type TestLe::NomT, :m1, "() -> nil", wrap: false
|
283
|
+
RDL.type TestLe::NomT, :m2, "() -> nil", wrap: false
|
284
|
+
|
263
285
|
tnom = NominalType.new(Nom)
|
264
286
|
tnomt = NominalType.new(NomT)
|
265
287
|
tma = MethodType.new([], nil, RDL::Globals.types[:nil])
|
@@ -279,6 +301,9 @@ class TestLe < Minitest::Test
|
|
279
301
|
end
|
280
302
|
|
281
303
|
def test_leq_inst
|
304
|
+
RDL.type_params :Array, [:t], :all?
|
305
|
+
RDL.type_params :Hash, [:k, :v], :all?
|
306
|
+
|
282
307
|
# when return of do_leq is false, ignore resulting inst, since that's very implementation dependent
|
283
308
|
assert_equal [true, {t: @ta}], do_leq(tt("t"), @ta, true)
|
284
309
|
assert_equal false, do_leq(tt("t"), @ta, false)[0]
|