typed.rb 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +26 -0
  3. data/bin/typed.rb +110 -0
  4. data/lib/typed/language.rb +131 -0
  5. data/lib/typed/model/tm_abs.rb +104 -0
  6. data/lib/typed/model/tm_array_literal.rb +25 -0
  7. data/lib/typed/model/tm_boolean.rb +15 -0
  8. data/lib/typed/model/tm_boolean_operator.rb +34 -0
  9. data/lib/typed/model/tm_break.rb +24 -0
  10. data/lib/typed/model/tm_case_when.rb +38 -0
  11. data/lib/typed/model/tm_class.rb +63 -0
  12. data/lib/typed/model/tm_const.rb +29 -0
  13. data/lib/typed/model/tm_defined.rb +19 -0
  14. data/lib/typed/model/tm_error.rb +16 -0
  15. data/lib/typed/model/tm_float.rb +15 -0
  16. data/lib/typed/model/tm_for.rb +42 -0
  17. data/lib/typed/model/tm_fun.rb +165 -0
  18. data/lib/typed/model/tm_global_var.rb +22 -0
  19. data/lib/typed/model/tm_global_var_assignment.rb +20 -0
  20. data/lib/typed/model/tm_hash_literal.rb +32 -0
  21. data/lib/typed/model/tm_if_else.rb +24 -0
  22. data/lib/typed/model/tm_instance_var.rb +23 -0
  23. data/lib/typed/model/tm_instance_var_assignment.rb +32 -0
  24. data/lib/typed/model/tm_int.rb +15 -0
  25. data/lib/typed/model/tm_local_var_asgn.rb +35 -0
  26. data/lib/typed/model/tm_mass_asgn.rb +60 -0
  27. data/lib/typed/model/tm_mlhs.rb +87 -0
  28. data/lib/typed/model/tm_module.rb +51 -0
  29. data/lib/typed/model/tm_next.rb +24 -0
  30. data/lib/typed/model/tm_nil.rb +14 -0
  31. data/lib/typed/model/tm_range_literal.rb +30 -0
  32. data/lib/typed/model/tm_regexp.rb +27 -0
  33. data/lib/typed/model/tm_rescue.rb +27 -0
  34. data/lib/typed/model/tm_return.rb +24 -0
  35. data/lib/typed/model/tm_s_class.rb +30 -0
  36. data/lib/typed/model/tm_self.rb +22 -0
  37. data/lib/typed/model/tm_send.rb +300 -0
  38. data/lib/typed/model/tm_sequencing.rb +53 -0
  39. data/lib/typed/model/tm_string.rb +15 -0
  40. data/lib/typed/model/tm_string_interpolation.rb +21 -0
  41. data/lib/typed/model/tm_super.rb +27 -0
  42. data/lib/typed/model/tm_symbol.rb +15 -0
  43. data/lib/typed/model/tm_symbol_interpolation.rb +21 -0
  44. data/lib/typed/model/tm_try.rb +29 -0
  45. data/lib/typed/model/tm_var.rb +28 -0
  46. data/lib/typed/model/tm_while.rb +43 -0
  47. data/lib/typed/model.rb +48 -0
  48. data/lib/typed/prelude.rb +939 -0
  49. data/lib/typed/prelude_existential_registry.bin +0 -0
  50. data/lib/typed/prelude_generic_registry.bin +0 -0
  51. data/lib/typed/prelude_registry.bin +0 -0
  52. data/lib/typed/runtime/ast_parser.rb +589 -0
  53. data/lib/typed/runtime/method_signature_processor.rb +72 -0
  54. data/lib/typed/runtime/normalization/validations.rb +47 -0
  55. data/lib/typed/runtime/normalization.rb +196 -0
  56. data/lib/typed/runtime/parser_context.rb +36 -0
  57. data/lib/typed/runtime/type_parser.rb +215 -0
  58. data/lib/typed/runtime/type_registry.rb +170 -0
  59. data/lib/typed/runtime/type_signature_processor.rb +34 -0
  60. data/lib/typed/runtime.rb +33 -0
  61. data/lib/typed/type_signature/parser.rb +240 -0
  62. data/lib/typed/types/polymorphism/existential_type_variable.rb +13 -0
  63. data/lib/typed/types/polymorphism/generic_comparisons.rb +134 -0
  64. data/lib/typed/types/polymorphism/generic_variables.rb +24 -0
  65. data/lib/typed/types/polymorphism/type_variable.rb +138 -0
  66. data/lib/typed/types/polymorphism/type_variable_register.rb +298 -0
  67. data/lib/typed/types/polymorphism/unification.rb +579 -0
  68. data/lib/typed/types/ty_boolean.rb +15 -0
  69. data/lib/typed/types/ty_dynamic.rb +39 -0
  70. data/lib/typed/types/ty_either.rb +168 -0
  71. data/lib/typed/types/ty_error.rb +18 -0
  72. data/lib/typed/types/ty_existential_type.rb +22 -0
  73. data/lib/typed/types/ty_function.rb +144 -0
  74. data/lib/typed/types/ty_generic_function.rb +115 -0
  75. data/lib/typed/types/ty_generic_object.rb +180 -0
  76. data/lib/typed/types/ty_generic_singleton_object.rb +238 -0
  77. data/lib/typed/types/ty_object.rb +256 -0
  78. data/lib/typed/types/ty_singleton_object.rb +78 -0
  79. data/lib/typed/types/ty_stack_jump.rb +44 -0
  80. data/lib/typed/types/ty_top_level_object.rb +38 -0
  81. data/lib/typed/types.rb +60 -0
  82. data/lib/typed/typing_context.rb +206 -0
  83. data/lib/typed/version.rb +3 -0
  84. data/lib/typed.rb +161 -0
  85. data/spec/lib/ast_parser_spec.rb +101 -0
  86. data/spec/lib/examples/animals.rb +44 -0
  87. data/spec/lib/examples/counter.rb +16 -0
  88. data/spec/lib/examples/if.rb +31 -0
  89. data/spec/lib/language_spec.rb +36 -0
  90. data/spec/lib/model/tm_abs_spec.rb +66 -0
  91. data/spec/lib/model/tm_array_literal_spec.rb +36 -0
  92. data/spec/lib/model/tm_case_when_spec.rb +39 -0
  93. data/spec/lib/model/tm_class_spec.rb +67 -0
  94. data/spec/lib/model/tm_defined_spec.rb +10 -0
  95. data/spec/lib/model/tm_for_spec.rb +150 -0
  96. data/spec/lib/model/tm_fun_spec.rb +11 -0
  97. data/spec/lib/model/tm_hash_literal_spec.rb +40 -0
  98. data/spec/lib/model/tm_mass_asgn_spec.rb +104 -0
  99. data/spec/lib/model/tm_module_spec.rb +42 -0
  100. data/spec/lib/model/tm_regexp_spec.rb +9 -0
  101. data/spec/lib/model/tm_return_spec.rb +47 -0
  102. data/spec/lib/model/tm_s_class_spec.rb +27 -0
  103. data/spec/lib/model/tm_self_spec.rb +19 -0
  104. data/spec/lib/model/tm_string_interpolation_spec.rb +10 -0
  105. data/spec/lib/model/tm_symbol_interpolation_spec.rb +10 -0
  106. data/spec/lib/model/tm_symbol_spec.rb +9 -0
  107. data/spec/lib/model/tm_while_spec.rb +141 -0
  108. data/spec/lib/polymorphism/type_variable_spec.rb +14 -0
  109. data/spec/lib/polymorphism/unification_spec.rb +328 -0
  110. data/spec/lib/prelude/array_spec.rb +263 -0
  111. data/spec/lib/prelude/class_spec.rb +12 -0
  112. data/spec/lib/prelude/enumerable_spec.rb +278 -0
  113. data/spec/lib/prelude/enumerator_spec.rb +101 -0
  114. data/spec/lib/prelude/hash_spec.rb +361 -0
  115. data/spec/lib/prelude/kernel_spec.rb +23 -0
  116. data/spec/lib/prelude/object_spec.rb +22 -0
  117. data/spec/lib/prelude/pair_spec.rb +16 -0
  118. data/spec/lib/prelude/showable_spec.rb +31 -0
  119. data/spec/lib/prelude/string_spec.rb +98 -0
  120. data/spec/lib/runtime/normalization_spec.rb +29 -0
  121. data/spec/lib/runtime/validations_spec.rb +56 -0
  122. data/spec/lib/runtime_spec.rb +503 -0
  123. data/spec/lib/type_signature/parser_spec.rb +239 -0
  124. data/spec/lib/types/comparisons_spec.rb +35 -0
  125. data/spec/lib/types/polymorphism/generic_comparisons_spec.rb +492 -0
  126. data/spec/lib/types/polymorphism/type_variable_register_spec.rb +128 -0
  127. data/spec/lib/types/ty_dynamic_spec.rb +103 -0
  128. data/spec/lib/types/ty_either_spec.rb +288 -0
  129. data/spec/lib/types/ty_error_spec.rb +18 -0
  130. data/spec/lib/types/ty_generic_object_spec.rb +78 -0
  131. data/spec/lib/types/ty_generic_singleton_object_spec.rb +288 -0
  132. data/spec/lib/types/typing_context_spec.rb +86 -0
  133. data/spec/lib/types_spec.rb +174 -0
  134. data/spec/lib/typing/boolean_asgn_spec.rb +134 -0
  135. data/spec/lib/typing/break_spec.rb +79 -0
  136. data/spec/lib/typing/generics_spec.rb +191 -0
  137. data/spec/lib/typing/instance_vars_spec.rb +103 -0
  138. data/spec/lib/typing/next_spec.rb +29 -0
  139. data/spec/lib/typing/op_asgn_spec.rb +104 -0
  140. data/spec/lib/typing/overriden_methods_spec.rb +31 -0
  141. data/spec/lib/typing/subtyping_spec.rb +112 -0
  142. data/spec/lib/typing/tm_boolean_operator_spec.rb +100 -0
  143. data/spec/lib/typing/tm_boolean_spec.rb +61 -0
  144. data/spec/lib/typing/tm_const_spec.rb +28 -0
  145. data/spec/lib/typing/tm_defined_spec.rb +12 -0
  146. data/spec/lib/typing/tm_fun_spec.rb +347 -0
  147. data/spec/lib/typing/tm_global_var_spec.rb +33 -0
  148. data/spec/lib/typing/tm_if_else_spec.rb +104 -0
  149. data/spec/lib/typing/tm_ignore_spec.rb +24 -0
  150. data/spec/lib/typing/tm_instance_vars_spec.rb +117 -0
  151. data/spec/lib/typing/tm_local_var_asgn_spec.rb +134 -0
  152. data/spec/lib/typing/tm_mlhs_spec.rb +164 -0
  153. data/spec/lib/typing/tm_module_spec.rb +89 -0
  154. data/spec/lib/typing/tm_raise_spec.rb +31 -0
  155. data/spec/lib/typing/tm_range_literal_spec.rb +25 -0
  156. data/spec/lib/typing/tm_regexp_spec.rb +14 -0
  157. data/spec/lib/typing/tm_return_spec.rb +45 -0
  158. data/spec/lib/typing/tm_send_casting_spec.rb +26 -0
  159. data/spec/lib/typing/tm_send_class_methods_spec.rb +42 -0
  160. data/spec/lib/typing/tm_send_generic_apply_spec.rb +103 -0
  161. data/spec/lib/typing/tm_send_generic_methods_spec.rb +77 -0
  162. data/spec/lib/typing/tm_send_initialize_spec.rb +68 -0
  163. data/spec/lib/typing/tm_send_lambda_spec.rb +135 -0
  164. data/spec/lib/typing/tm_send_spec.rb +217 -0
  165. data/spec/lib/typing/tm_send_yield_block_spec.rb +308 -0
  166. data/spec/lib/typing/tm_sequencing_spec.rb +174 -0
  167. data/spec/lib/typing/tm_string_interpolation_spec.rb +19 -0
  168. data/spec/lib/typing/tm_super_spec.rb +63 -0
  169. data/spec/lib/typing/tm_symbol_interpolation_spec.rb +19 -0
  170. data/spec/lib/typing/tm_symbol_spec.rb +14 -0
  171. data/spec/lib/typing/tm_try_spec.rb +73 -0
  172. data/spec/spec_helper.rb +140 -0
  173. metadata +216 -0
@@ -0,0 +1,361 @@
1
+ require_relative '../../spec_helper'
2
+
3
+ describe Hash do
4
+ let(:language) { TypedRb::Language.new }
5
+
6
+ describe '#initialize' do
7
+ it 'type checks / -> Hash[S][T]' do
8
+ result = language.check('Hash.(String,Integer).new')
9
+ expect(result.to_s).to eq('Hash[String][Integer]')
10
+ end
11
+
12
+ it 'type checks / -> Hash[S][T] with a literal type annotation' do
13
+ result = language.check("Hash.('[String][Integer]').new")
14
+ expect(result.to_s).to eq('Hash[String][Integer]')
15
+ end
16
+
17
+ it 'type checks / -> [T] -> Hash[S][T]' do
18
+ result = language.check("Hash.(String,Integer).new(1)")
19
+ expect(result.to_s).to eq('Hash[String][Integer]')
20
+
21
+ expect {
22
+ language.check("Hash.(String,Integer).new('string')")
23
+ }.to raise_error(TypedRb::Types::UncomparableTypes)
24
+ end
25
+
26
+ it 'type checks / &(Hash[S][T] -> [S] -> unit) -> Hash[S][T]' do
27
+ result = language.check("Hash.(String,Integer).new { |acc,k| acc[k] = 0 }")
28
+ expect(result.to_s).to eq('Hash[String][Integer]')
29
+
30
+ expect {
31
+ language.check("Hash.(String,Integer).new { |acc,k| acc[k] = 'string'}")
32
+ }.to raise_error(TypedRb::Types::UncomparableTypes)
33
+ end
34
+ end
35
+
36
+ describe '#any?' do
37
+ it 'type checks / &(T -> S -> Boolean) -> Boolean' do
38
+ code = <<__CODE
39
+
40
+ ts "#randomBool / String -> Integer -> Boolean"
41
+ def randomBool(s,i); true; end
42
+
43
+ Hash.(String,Integer).new.any? { |s,t| randomBool(s,t) }
44
+ __CODE
45
+
46
+ result = language.check(code)
47
+ expect(result.to_s).to eq('Boolean')
48
+
49
+ expect {
50
+ code = <<__CODE
51
+
52
+ ts "#randomBool / String -> Integer -> Boolean"
53
+ def randomBool(s,i); true; end
54
+
55
+ Hash.(String,Integer).new.any? { |s,t| randomBool(t,s) }
56
+ __CODE
57
+
58
+ language.check("Hash.(String,Integer).new { |acc,k| acc[k] = 'string'}")
59
+ }.to raise_error(TypedRb::Types::UncomparableTypes)
60
+ end
61
+ end
62
+
63
+ describe '#assoc' do
64
+ it 'type checks / [S] -> Pair[S][T]' do
65
+ code = <<__CODE
66
+ h = Hash.(String,Integer).new
67
+ h['key'] = 0
68
+ result = h.assoc('key')
69
+ result.second
70
+ __CODE
71
+
72
+ result = language.check(code)
73
+ expect(result.to_s).to eq('Integer')
74
+
75
+ expect {
76
+ code = <<__CODE
77
+ Hash.(String,Integer).new.assoc(2)
78
+ __CODE
79
+
80
+ language.check("Hash.(String,Integer).new { |acc,k| acc[k] = 'string'}")
81
+ }.to raise_error(TypedRb::Types::UncomparableTypes)
82
+ end
83
+ end
84
+
85
+ # describe '#default_proc' do
86
+ # xit 'type checks / -> (Hash[S][T] -> [S] -> [T])' do
87
+ # code = 'Hash.(String,Integer).new.default_proc'
88
+ # #result = language.check(code)
89
+ # end
90
+ # end
91
+
92
+ describe '#delete' do
93
+ it 'type checks / [S] -> [T]' do
94
+ code = <<__CODE
95
+ Hash.(String,Integer).new.delete('str')
96
+ __CODE
97
+ result = language.check(code)
98
+ expect(result.ruby_type).to eq(Integer)
99
+
100
+ expect {
101
+ language.check('Hash.(String,Integer).new.delete(1)')
102
+ }.to raise_error(TypedRb::Types::UncomparableTypes)
103
+ end
104
+
105
+ it 'type checks / [S] -> &([S] -> [T]) -> [T]' do
106
+ code = <<__CODE
107
+ Hash.(String,Integer).new.delete('str') { |k| 0 }
108
+ __CODE
109
+ result = language.check(code)
110
+ expect(result.ruby_type).to eq(Integer)
111
+
112
+ expect {
113
+ code = <<__CODE
114
+ Hash.(String,Integer).new.delete('str') { |k| k }
115
+ __CODE
116
+ language.check(code)
117
+ }.to raise_error(TypedRb::Types::UncomparableTypes)
118
+ end
119
+ end
120
+
121
+ describe '#delete_if' do
122
+ it 'type checks / [S] -> &([S] -> [T] -> Boolean) -> [T]' do
123
+ code = <<__CODE
124
+ ts '#str_int_bool / String -> Integer -> Boolean'
125
+ def str_int_bool(s,i); true; end
126
+ Hash.(String,Integer).new.delete_if { |k,v| str_int_bool(k,v) }
127
+ __CODE
128
+ result = language.check(code)
129
+ expect(result.to_s).to eq('Hash[String][Integer]')
130
+
131
+ expect {
132
+ code = <<__CODE
133
+ ts '#str_int_bool / String -> Integer -> Boolean'
134
+ def str_int_bool(s,i); true; end
135
+ Hash.(String,Integer).new.delete_if { |k,v| str_int_bool(v,k) }
136
+ __CODE
137
+
138
+ language.check(code)
139
+ }.to raise_error(TypedRb::Types::UncomparableTypes)
140
+ end
141
+ end
142
+
143
+ describe '#each' do
144
+ it 'type checks / &([S] -> [T] -> unit) -> Hash[S][T]' do
145
+ code = <<__CODE
146
+ ts '#str_int_bool / String -> Integer -> Boolean'
147
+ def str_int_bool(s,i); true; end
148
+
149
+ Hash.(String,Integer).new.each { |s,t| str_int_bool(s,t) }
150
+ __CODE
151
+
152
+ result = language.check(code)
153
+ expect(result.to_s).to eq('Hash[String][Integer]')
154
+
155
+
156
+ code = <<__CODE
157
+ ts '#str_int_bool / String -> Integer -> Boolean'
158
+ def str_int_bool(s,i); true; end
159
+
160
+ Hash.(String,Integer).new.each { |(s,t)| str_int_bool(s,t) }
161
+ __CODE
162
+
163
+ result = language.check(code)
164
+ expect(result.to_s).to eq('Hash[String][Integer]')
165
+
166
+ expect {
167
+ code = <<__CODE
168
+ ts '#str_int_bool / String -> Integer -> Boolean'
169
+ def str_int_bool(s,i); true; end
170
+ Hash.(String,Integer).new.delete_if { |k,v| str_int_bool(v,v) }
171
+ __CODE
172
+
173
+ language.check(code)
174
+ }.to raise_error(TypedRb::Types::UncomparableTypes)
175
+
176
+ expect {
177
+ code = <<__CODE
178
+ ts '#str_int_bool / String -> Integer -> Boolean'
179
+ def str_int_bool(s,i); true; end
180
+ Hash.(String,Integer).new.delete_if { |(k,v)| str_int_bool(v,v) }
181
+ __CODE
182
+
183
+ language.check(code)
184
+ }.to raise_error(TypedRb::Types::UncomparableTypes)
185
+ end
186
+ end
187
+
188
+ describe '#each_key' do
189
+ it 'type checks / -> Enumerator' do
190
+ result = language.check('Hash.(String,Integer).new.each_key')
191
+ expect(result.ruby_type).to eq(Enumerator)
192
+ end
193
+
194
+ it 'type checks / &([S] -> unit) -> Hash[S][T]' do
195
+ code = <<__CODE
196
+ ts '#str_bool / String -> Boolean'
197
+ def str_bool(s); true; end
198
+
199
+ Hash.(String,Integer).new.each_key { |s| str_bool(s,t) }
200
+ __CODE
201
+
202
+ result = language.check(code)
203
+ expect(result.to_s).to eq('Hash[String][Integer]')
204
+
205
+ expect {
206
+ code = <<__CODE
207
+ ts '#int_bool / Integer -> Boolean'
208
+ def int_bool(s); true; end
209
+
210
+ Hash.(String,Integer).new.each_key { |s| int_bool(s) }
211
+ __CODE
212
+
213
+ language.check(code)
214
+ }.to raise_error(TypedRb::Types::UncomparableTypes)
215
+ end
216
+ end
217
+
218
+ describe '#eql?' do
219
+ it 'type checks / Hash[?][?] -> Boolean' do
220
+ result = language.check('Hash.(String,Integer).new.eql?(Hash.(String,String).new)')
221
+ expect(result.to_s).to eq('Boolean')
222
+
223
+ result = language.check('Hash.(String,Integer).new.eql?(Array.(String).new)')
224
+ expect(result.to_s).to eq('Boolean')
225
+ end
226
+ end
227
+
228
+ describe '#fetch' do
229
+ it 'type checks / [S] -> &([S] -> [T]) -> [T]' do
230
+
231
+ code = <<__CODE
232
+ h = Hash.(String,Integer).new
233
+ h['str'] = 0
234
+ h.fetch('str')
235
+ __CODE
236
+ result = language.check(code)
237
+ expect(result.ruby_type).to eq(Integer)
238
+
239
+ code = <<__CODE
240
+ ts '#str / String -> unit'
241
+ def str(k); end
242
+
243
+ h = Hash.(String,Integer).new
244
+ h['str'] = 0
245
+ h.fetch('str') { |k| str(k) }
246
+ __CODE
247
+ result = language.check(code)
248
+ expect(result.ruby_type).to eq(Integer)
249
+
250
+ expect {
251
+ code = <<__CODE
252
+ h = Hash.(String,Integer).new
253
+ h['str'] = 0
254
+ begin
255
+ h.fetch(0)
256
+ rescue; end
257
+ __CODE
258
+ language.check(code)
259
+ }.to raise_error(TypedRb::Types::UncomparableTypes)
260
+
261
+ expect {
262
+ code = <<__CODE
263
+ ts '#intf / Integer -> unit'
264
+ def intf(k); end
265
+
266
+ h = Hash.(String,Integer).new
267
+ h['str'] = 0
268
+ h.fetch('str') { |k| intf(k) }
269
+ __CODE
270
+ language.check(code)
271
+ }.to raise_error(TypedRb::Types::UncomparableTypes)
272
+ end
273
+
274
+ it 'type checks / [S] -> [T] -> [T]' do
275
+ result = language.check('Hash.(String,Integer).new.fetch("str",0)')
276
+ expect(result.ruby_type).to eq(Integer)
277
+
278
+ expect {
279
+ language.check('Hash.(String,Integer).new.fetch("str","default")')
280
+ }.to raise_error(TypedRb::Types::UncomparableTypes)
281
+ end
282
+ end
283
+
284
+ describe '#invert' do
285
+ it 'type checks / -> Hash[T][S]' do
286
+ result = language.check('Hash.(String,Integer).new.invert')
287
+ expect(result.to_s).to eq('Hash[Integer][String]')
288
+ end
289
+ end
290
+
291
+ describe '#merge' do
292
+ it 'type checks / Hash[S][T] -> Hash[S][T]' do
293
+ result = language.check('a = Hash.(String,Integer).new; Hash.(String,Integer).new.merge(a)')
294
+ expect(result.to_s).to eq('Hash[String][Integer]')
295
+
296
+ expect {
297
+ language.check('a = Hash.(Integer,Integer).new; Hash.(String,Integer).new.merge(a)')
298
+ }.to raise_error(TypedRb::Types::UncomparableTypes)
299
+ end
300
+
301
+ context 'with a given block' do
302
+ it 'type checks / Hash[S][T] -> &([S] -> [T] -> [T] -> [S]) -> Hash[S][T]' do
303
+ code = <<__CODE
304
+ ts '#str_int_int_fn / String -> Integer -> Integer -> Integer'
305
+ def str_int_int_fn(k,v1,v2); v1 + v2; end
306
+
307
+ a = Hash.(String,Integer).new
308
+ Hash.(String,Integer).new.merge(a) { |k,v1,v2| str_int_int_fn(k, v1, v2) }
309
+ __CODE
310
+ result = language.check(code)
311
+ expect(result.to_s).to eq('Hash[String][Integer]')
312
+
313
+ expect {
314
+ code = <<__CODE
315
+ ts '#str_str_int_fn / String -> String -> Integer -> Integer'
316
+ def str_str_int_fn(k,v1,v2); 0; end
317
+
318
+ a = Hash.(String,Integer).new
319
+ Hash.(String,Integer).new.merge(a) { |k,v1,v2| str_str_int_fn(k, v1, v2) }
320
+ __CODE
321
+ language.check(code)
322
+ }.to raise_error(TypedRb::Types::UncomparableTypes)
323
+ end
324
+ end
325
+ end
326
+
327
+ describe '#rassoc' do
328
+ it 'type checks / [T] -> Pair[S][T]' do
329
+ result = language.check('Hash.(String,Integer).new.rassoc(2)')
330
+ expect(result.to_s).to eq('Pair[String][Integer]')
331
+ end
332
+ end
333
+
334
+ describe '#shift' do
335
+ it 'type checks / -> Pair[S][T]' do
336
+ result = language.check('Hash.(String,Integer).new.shift')
337
+ expect(result.to_s).to eq('Pair[String][Integer]')
338
+ end
339
+ end
340
+
341
+ describe '#to_a' do
342
+ it 'type checks / -> Array[Pair[S][T]]' do
343
+ result = language.check('Hash.(String,Integer).new.to_a')
344
+ expect(result.to_s).to eq('Array[Pair[String][Integer]]')
345
+ end
346
+ end
347
+
348
+ describe '#values' do
349
+ it 'type checks / -> Array[S]' do
350
+ result = language.check('Hash.(String,Integer).new.values')
351
+ expect(result.to_s).to eq('Array[Integer]')
352
+ end
353
+ end
354
+
355
+ describe '#values_at' do
356
+ it 'type checks / -> Array[S]' do
357
+ result = language.check('Hash.(String,Integer).new.values_at("a","b","d")')
358
+ expect(result.to_s).to eq('Array[Integer]')
359
+ end
360
+ end
361
+ end
@@ -0,0 +1,23 @@
1
+ require_relative '../../spec_helper'
2
+
3
+ describe Kernel do
4
+ let(:language) { TypedRb::Language.new }
5
+
6
+ describe '#Array[E]' do
7
+ it 'type checks / Range[E] -> Array[E]' do
8
+ result = language.check('Array(Range.(Integer).new(0, 10))')
9
+ expect(result.ruby_type).to eq(Array)
10
+ expect(result.type_vars.first.bound.ruby_type).to eq(Integer)
11
+ end
12
+ end
13
+
14
+ describe '#rand' do
15
+ it 'type checks #rand[E < Numeric] / [E] -> [E]' do
16
+ result = language.check('rand(2.0)')
17
+ expect(result.ruby_type).to eq(Float)
18
+
19
+ result = language.check('rand(1)')
20
+ expect(result.ruby_type).to eq(Integer)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,22 @@
1
+ require_relative '../../spec_helper'
2
+
3
+ describe Object do
4
+ let(:language) { TypedRb::Language.new }
5
+
6
+ describe '#instance_variable_defined' do
7
+ it 'type checks / Showable -> Boolean' do
8
+ result = language.check('Object.new.instance_variable_defined?("@a")')
9
+ expect(result.ruby_type).to eq(TrueClass)
10
+
11
+ result = language.check('Object.new.instance_variable_defined?(:@a)')
12
+ expect(result.ruby_type).to eq(TrueClass)
13
+ end
14
+ end
15
+
16
+ describe '#instance_of?' do
17
+ it 'type checks / Class -> Boolean' do
18
+ result = language.check('Object.new.instance_of?(Object)')
19
+ expect(result.ruby_type).to eq(TrueClass)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,16 @@
1
+ require_relative '../../spec_helper'
2
+ require_relative '../../../lib/typed/prelude'
3
+
4
+ describe Pair do
5
+ let(:language) { TypedRb::Language.new }
6
+
7
+ describe '#instance_variable_defined' do
8
+ it 'type checks / Showable -> Boolean' do
9
+ result = language.check('Pair.of(1,"foo").second')
10
+ expect(result.ruby_type).to eq(String)
11
+
12
+ result = language.check('Pair.of(1,"foo").first')
13
+ expect(result.ruby_type).to eq(Integer)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,31 @@
1
+ require_relative '../../spec_helper'
2
+
3
+ describe Object do
4
+ let(:language) { TypedRb::Language.new }
5
+
6
+ describe 'Strings' do
7
+ it 'is a Showable' do
8
+ code = <<__CODE
9
+ ts '#st1 / Showable -> Showable'
10
+ def st1(s); s; end
11
+
12
+ st1('hey')
13
+ __CODE
14
+ result = language.check(code)
15
+ expect(result.ruby_type).to eq(Showable)
16
+ end
17
+ end
18
+
19
+ describe 'Symbols' do
20
+ it 'is a Showable' do
21
+ code = <<__CODE
22
+ ts '#st1 / Showable -> Showable'
23
+ def st1(s); s; end
24
+
25
+ st1(:hey)
26
+ __CODE
27
+ result = language.check(code)
28
+ expect(result.ruby_type).to eq(Showable)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,98 @@
1
+ require_relative '../../spec_helper'
2
+
3
+ describe String do
4
+ let(:language) { TypedRb::Language.new }
5
+
6
+ describe '#each_line' do
7
+ describe '/ &(String -> unit) -> String' do
8
+ it 'type checks , positive case' do
9
+ code = <<__CODE
10
+ ts '#str_fn / String -> unit'
11
+ def str_fn(s); end
12
+
13
+ "".each_line{ |s| str_fn(s) }
14
+ __CODE
15
+ result = language.check(code)
16
+ expect(result.to_s).to eq('String')
17
+ end
18
+
19
+ it 'type checks / &(String -> unit) -> String, negative case' do
20
+ code = <<__CODE
21
+ ts '#int_fn / Integer -> unit'
22
+ def int_fn(i); end
23
+
24
+ "".each_line{ |s| int_fn(s) }
25
+ __CODE
26
+ expect {
27
+ language.check(code)
28
+ }.to raise_error(TypedRb::Types::UncomparableTypes)
29
+ end
30
+ end
31
+
32
+ describe '-> Enumerator[String]' do
33
+ it 'type checks' do
34
+ result = language.check('"".each_line')
35
+ expect(result.to_s).to eq('Enumerator[String]')
36
+ end
37
+ end
38
+
39
+ describe '/ String -> &(String -> unit) -> String' do
40
+ it 'type checks , positive case' do
41
+ code = <<__CODE
42
+ ts '#str_fn / String -> unit'
43
+ def str_fn(s); end
44
+
45
+ "".each_line(''){ |s| str_fn(s) }
46
+ __CODE
47
+ result = language.check(code)
48
+ expect(result.to_s).to eq('String')
49
+ end
50
+
51
+ it 'type checks / &(String -> unit) -> String, negative case' do
52
+ code = <<__CODE
53
+ ts '#int_fn / Integer -> unit'
54
+ def int_fn(i); end
55
+
56
+ "".each_line(''){ |s| int_fn(s) }
57
+ __CODE
58
+ expect {
59
+ language.check(code)
60
+ }.to raise_error(TypedRb::Types::UncomparableTypes)
61
+ end
62
+ end
63
+
64
+ describe 'String -> Enumerator[String]' do
65
+ it 'type checks' do
66
+ result = language.check('"".each_line("")')
67
+ expect(result.to_s).to eq('Enumerator[String]')
68
+ end
69
+ end
70
+ end
71
+
72
+ describe '#scan' do
73
+ describe 'Regexp -> &(String... -> unit) -> String' do
74
+ it 'type checks, positive case' do
75
+ code = <<__CODE
76
+ ts '#str_array_fn / Array[String] -> unit'
77
+ def str_array_fn(ss); end
78
+
79
+ "".scan(/\n/) { |ss| str_array_fn(ss) }
80
+ __CODE
81
+ result = language.check(code)
82
+ expect(result.to_s).to eq('String')
83
+ end
84
+
85
+ it 'type checks, negative case' do
86
+ code = <<__CODE
87
+ ts '#int_array_fn / Array[Integer] -> unit'
88
+ def int_array_fn(is); end
89
+
90
+ "".scan(/\n/) { |ss| int_array_fn(ss) }
91
+ __CODE
92
+ expect {
93
+ language.check(code)
94
+ }.to raise_error(TypedRb::Types::UncomparableTypes)
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,29 @@
1
+ require_relative '../../spec_helper'
2
+
3
+ describe TypedRb::Runtime::Normalization do
4
+ let(:language) { TypedRb::Language.new }
5
+ it 'normalizes generic types with super types annotations' do
6
+ code = <<__END
7
+ ts 'type TestPair[S][T] super Array[Object]'
8
+ class TestPair < Array
9
+ ts '#first / -> [S]'
10
+ end
11
+ TestPair
12
+ __END
13
+ result = language.check(code)
14
+ expect(result.ruby_type).to eq(TestPair)
15
+ expect(result.super_type.ruby_type).to eq(Array)
16
+ expect(result.super_type.type_vars.first.bound.ruby_type).to eq(Object)
17
+ end
18
+
19
+ it 'raises an exception if the super type is not a super class of the current type' do
20
+ code = <<__END
21
+ ts 'type TestPair2[S][T] super Array[Object]'
22
+ class TestPair2
23
+ end
24
+ __END
25
+ expect {
26
+ language.check(code)
27
+ }.to raise_error(StandardError)
28
+ end
29
+ end
@@ -0,0 +1,56 @@
1
+ require_relative '../../spec_helper'
2
+
3
+ describe TypedRb::Runtime::Normalization::Validations do
4
+
5
+ let(:language) { TypedRb::Language.new }
6
+
7
+ include described_class
8
+
9
+ describe '#validate_signature' do
10
+ it 'is valid if the type is a variable' do
11
+ expect {
12
+ validate_signature(:class_variable, nil)
13
+ }.to_not raise_error
14
+ expect {
15
+ validate_signature(:instance_variable, nil)
16
+ }.to_not raise_error
17
+ expect {
18
+ validate_signature(:invalid, nil)
19
+ }.to raise_error(::TypedRb::Types::TypeParsingError)
20
+ end
21
+ end
22
+
23
+ describe '#validate_signatures' do
24
+ it 'raises an exception if there is a duplicated arity' do
25
+ code = <<__END
26
+ class TA
27
+ ts '#x / Integer -> Integer -> Integer'
28
+ ts '#x / String -> String -> String'
29
+ def x(a,b); a + b; end
30
+ end
31
+ __END
32
+ expect {
33
+ language.check(code)
34
+ }.to raise_error(::TypedRb::Types::TypeParsingError)
35
+ end
36
+ end
37
+
38
+ describe '#validate_method' do
39
+ it 'fails if the class method info passed does not include the method validated' do
40
+ expect {
41
+ validate_method({instance_methods: []}, :class, :test, :instance)
42
+ }.to raise_error(::TypedRb::Types::TypeParsingError)
43
+ expect {
44
+ validate_method({all_methods: []}, :class, :test, :class)
45
+ }.to raise_error(::TypedRb::Types::TypeParsingError)
46
+ end
47
+ end
48
+
49
+ describe '#validate_function_signature' do
50
+ it 'fails if a hash is passed' do
51
+ expect {
52
+ validate_function_signature(nil, nil, {}, nil)
53
+ }.to raise_error(::TypedRb::Types::TypeParsingError)
54
+ end
55
+ end
56
+ end