blob: b75e58c331be39bde2f6b9c63b1815aa939e08a6 [file] [log] [blame]
Bram Moolenaar00b28d62022-12-08 15:32:33 +00001" Test Vim9 classes
2
3source check.vim
4import './vim9.vim' as v9
5
6def Test_class_basic()
7 var lines =<< trim END
8 class NotWorking
9 endclass
10 END
11 v9.CheckScriptFailure(lines, 'E1316:')
12
13 lines =<< trim END
14 vim9script
15 class notWorking
16 endclass
17 END
18 v9.CheckScriptFailure(lines, 'E1314:')
19
20 lines =<< trim END
21 vim9script
22 class Not@working
23 endclass
24 END
25 v9.CheckScriptFailure(lines, 'E1315:')
26
27 lines =<< trim END
28 vim9script
29 abstract noclass Something
30 endclass
31 END
32 v9.CheckScriptFailure(lines, 'E475:')
33
34 lines =<< trim END
35 vim9script
36 abstract classy Something
37 endclass
38 END
39 v9.CheckScriptFailure(lines, 'E475:')
40
41 lines =<< trim END
42 vim9script
43 class Something
44 endcl
45 END
46 v9.CheckScriptFailure(lines, 'E1065:')
47
48 lines =<< trim END
49 vim9script
50 class Something
51 endclass school's out
52 END
53 v9.CheckScriptFailure(lines, 'E488:')
54
55 lines =<< trim END
56 vim9script
57 class Something
58 endclass | echo 'done'
59 END
60 v9.CheckScriptFailure(lines, 'E488:')
61
62 lines =<< trim END
63 vim9script
64 class Something
65 this
66 endclass
67 END
68 v9.CheckScriptFailure(lines, 'E1317:')
69
70 lines =<< trim END
71 vim9script
72 class Something
73 this.
74 endclass
75 END
76 v9.CheckScriptFailure(lines, 'E1317:')
77
78 lines =<< trim END
79 vim9script
80 class Something
81 this .count
82 endclass
83 END
84 v9.CheckScriptFailure(lines, 'E1317:')
85
86 lines =<< trim END
87 vim9script
88 class Something
89 this. count
90 endclass
91 END
92 v9.CheckScriptFailure(lines, 'E1317:')
93
94 lines =<< trim END
95 vim9script
96 class Something
97 this.count: number
98 that.count
99 endclass
100 END
101 v9.CheckScriptFailure(lines, 'E1318: Not a valid command in a class: that.count')
102
103 lines =<< trim END
104 vim9script
105 class Something
106 this.count
107 endclass
108 END
109 v9.CheckScriptFailure(lines, 'E1022:')
110
111 lines =<< trim END
112 vim9script
113 class Something
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000114 def new()
115 this.state = 0
116 enddef
117 endclass
118 var obj = Something.new()
119 END
120 v9.CheckScriptFailure(lines, 'E1089:')
121
122 lines =<< trim END
123 vim9script
124 class Something
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000125 this.count : number
126 endclass
127 END
128 v9.CheckScriptFailure(lines, 'E1059:')
129
130 lines =<< trim END
131 vim9script
132 class Something
133 this.count:number
134 endclass
135 END
136 v9.CheckScriptFailure(lines, 'E1069:')
137
138 lines =<< trim END
139 vim9script
140
141 class TextPosition
142 this.lnum: number
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000143 this.col: number
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000144
Bram Moolenaar418b5472022-12-20 13:38:22 +0000145 # make a nicely formatted string
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000146 def ToString(): string
147 return $'({this.lnum}, {this.col})'
148 enddef
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000149 endclass
150
Bram Moolenaard28d7b92022-12-08 20:42:00 +0000151 # use the automatically generated new() method
152 var pos = TextPosition.new(2, 12)
153 assert_equal(2, pos.lnum)
154 assert_equal(12, pos.col)
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000155
156 # call an object method
157 assert_equal('(2, 12)', pos.ToString())
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000158 END
159 v9.CheckScriptSuccess(lines)
160enddef
161
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000162def Test_class_member_initializer()
163 var lines =<< trim END
164 vim9script
165
166 class TextPosition
167 this.lnum: number = 1
168 this.col: number = 1
169
Bram Moolenaar418b5472022-12-20 13:38:22 +0000170 # constructor with only the line number
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000171 def new(lnum: number)
172 this.lnum = lnum
173 enddef
174 endclass
175
176 var pos = TextPosition.new(3)
177 assert_equal(3, pos.lnum)
178 assert_equal(1, pos.col)
179
180 var instr = execute('disassemble TextPosition.new')
181 assert_match('new\_s*' ..
Bram Moolenaar3ea8a1b2022-12-10 19:03:51 +0000182 '0 NEW TextPosition size \d\+\_s*' ..
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000183 '\d PUSHNR 1\_s*' ..
184 '\d STORE_THIS 0\_s*' ..
185 '\d PUSHNR 1\_s*' ..
186 '\d STORE_THIS 1\_s*' ..
187 'this.lnum = lnum\_s*' ..
188 '\d LOAD arg\[-1]\_s*' ..
189 '\d PUSHNR 0\_s*' ..
190 '\d LOAD $0\_s*' ..
191 '\d\+ STOREINDEX object\_s*' ..
192 '\d\+ RETURN object.*',
193 instr)
194 END
195 v9.CheckScriptSuccess(lines)
196enddef
197
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000198def Test_class_default_new()
199 var lines =<< trim END
200 vim9script
201
202 class TextPosition
203 this.lnum: number = 1
204 this.col: number = 1
205 endclass
206
207 var pos = TextPosition.new()
208 assert_equal(1, pos.lnum)
209 assert_equal(1, pos.col)
210
211 pos = TextPosition.new(v:none, v:none)
212 assert_equal(1, pos.lnum)
213 assert_equal(1, pos.col)
214
215 pos = TextPosition.new(3, 22)
216 assert_equal(3, pos.lnum)
217 assert_equal(22, pos.col)
218
219 pos = TextPosition.new(v:none, 33)
220 assert_equal(1, pos.lnum)
221 assert_equal(33, pos.col)
222 END
223 v9.CheckScriptSuccess(lines)
224
225 lines =<< trim END
226 vim9script
227 class Person
228 this.name: string
229 this.age: number = 42
230 this.education: string = "unknown"
231
232 def new(this.name, this.age = v:none, this.education = v:none)
233 enddef
234 endclass
235
236 var piet = Person.new("Piet")
237 assert_equal("Piet", piet.name)
238 assert_equal(42, piet.age)
239 assert_equal("unknown", piet.education)
240
241 var chris = Person.new("Chris", 4, "none")
242 assert_equal("Chris", chris.name)
243 assert_equal(4, chris.age)
244 assert_equal("none", chris.education)
245 END
246 v9.CheckScriptSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +0000247
248 lines =<< trim END
249 vim9script
250 class Person
251 this.name: string
252 this.age: number = 42
253 this.education: string = "unknown"
254
255 def new(this.name, this.age = v:none, this.education = v:none)
256 enddef
257 endclass
258
259 var missing = Person.new()
260 END
261 v9.CheckScriptFailure(lines, 'E119:')
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000262enddef
263
Bram Moolenaar74e12742022-12-13 21:14:28 +0000264def Test_class_object_member_inits()
265 var lines =<< trim END
266 vim9script
267 class TextPosition
268 this.lnum: number
269 this.col = 1
270 this.addcol: number = 2
271 endclass
272
273 var pos = TextPosition.new()
274 assert_equal(0, pos.lnum)
275 assert_equal(1, pos.col)
276 assert_equal(2, pos.addcol)
277 END
278 v9.CheckScriptSuccess(lines)
279
280 lines =<< trim END
281 vim9script
282 class TextPosition
283 this.lnum
284 this.col = 1
285 endclass
286 END
287 v9.CheckScriptFailure(lines, 'E1022:')
288
289 lines =<< trim END
290 vim9script
291 class TextPosition
292 this.lnum = v:none
293 this.col = 1
294 endclass
295 END
296 v9.CheckScriptFailure(lines, 'E1330:')
297enddef
298
Bram Moolenaar3d473ee2022-12-14 20:59:32 +0000299def Test_class_object_member_access()
300 var lines =<< trim END
301 vim9script
302 class Triple
303 this._one = 1
304 this.two = 2
305 public this.three = 3
306
307 def GetOne(): number
308 return this._one
309 enddef
310 endclass
311
312 var trip = Triple.new()
313 assert_equal(1, trip.GetOne())
314 assert_equal(2, trip.two)
315 assert_equal(3, trip.three)
316 assert_fails('echo trip._one', 'E1333')
317
318 assert_fails('trip._one = 11', 'E1333')
319 assert_fails('trip.two = 22', 'E1335')
320 trip.three = 33
321 assert_equal(33, trip.three)
Bram Moolenaard505d172022-12-18 21:42:55 +0000322
323 assert_fails('trip.four = 4', 'E1334')
324 END
325 v9.CheckScriptSuccess(lines)
Bram Moolenaar590162c2022-12-24 21:24:06 +0000326
327 lines =<< trim END
328 vim9script
329
330 class MyCar
331 this.make: string
332
333 def new(make_arg: string)
334 this.make = make_arg
335 enddef
336
337 def GetMake(): string
338 return $"make = {this.make}"
339 enddef
340 endclass
341
342 var c = MyCar.new("abc")
343 assert_equal('make = abc', c.GetMake())
344
345 c = MyCar.new("def")
346 assert_equal('make = def', c.GetMake())
347
348 var c2 = MyCar.new("123")
349 assert_equal('make = 123', c2.GetMake())
350 END
351 v9.CheckScriptSuccess(lines)
Bram Moolenaar6ef54712022-12-25 19:31:36 +0000352
353 lines =<< trim END
354 vim9script
355
356 class MyCar
357 this.make: string
358
359 def new(make_arg: string)
360 this.make = make_arg
361 enddef
362 endclass
363
364 var c = MyCar.new("abc")
365 var c = MyCar.new("def")
366 END
367 v9.CheckScriptFailure(lines, 'E1041:')
Bram Moolenaard505d172022-12-18 21:42:55 +0000368enddef
369
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +0000370def Test_class_object_compare()
371 var class_lines =<< trim END
372 vim9script
373 class Item
374 this.nr = 0
375 this.name = 'xx'
376 endclass
377 END
378
379 # used at the script level and in a compiled function
380 var test_lines =<< trim END
381 var i1 = Item.new()
382 assert_equal(i1, i1)
383 assert_true(i1 is i1)
384 var i2 = Item.new()
385 assert_equal(i1, i2)
386 assert_false(i1 is i2)
387 var i3 = Item.new(0, 'xx')
388 assert_equal(i1, i3)
389
390 var io1 = Item.new(1, 'xx')
391 assert_notequal(i1, io1)
392 var io2 = Item.new(0, 'yy')
393 assert_notequal(i1, io2)
394 END
395
396 v9.CheckScriptSuccess(class_lines + test_lines)
397 # TODO: this does not work yet
398 #v9.CheckScriptSuccess(
399 # class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()'])
400
401 for op in ['>', '>=', '<', '<=', '=~', '!~']
402 var op_lines = [
403 'var i1 = Item.new()',
404 'var i2 = Item.new()',
405 'echo i1 ' .. op .. ' i2',
406 ]
407 v9.CheckScriptFailure(class_lines + op_lines, 'E1153: Invalid operation for object')
408 # TODO: this does not work yet
409 #v9.CheckScriptFailure(class_lines
410 # + ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E99:')
411 endfor
412enddef
413
Bram Moolenaar6acf7572023-01-01 19:53:30 +0000414def Test_class_member()
415 # check access rules
Bram Moolenaard505d172022-12-18 21:42:55 +0000416 var lines =<< trim END
417 vim9script
418 class TextPos
419 this.lnum = 1
420 this.col = 1
421 static counter = 0
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +0000422 static _secret = 7
423 public static anybody = 42
Bram Moolenaard505d172022-12-18 21:42:55 +0000424
Bram Moolenaar6bafdd42023-01-01 12:58:33 +0000425 static def AddToCounter(nr: number)
Bram Moolenaard505d172022-12-18 21:42:55 +0000426 counter += nr
427 enddef
428 endclass
429
430 assert_equal(0, TextPos.counter)
431 TextPos.AddToCounter(3)
432 assert_equal(3, TextPos.counter)
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000433 assert_fails('echo TextPos.noSuchMember', 'E1338:')
Bram Moolenaard505d172022-12-18 21:42:55 +0000434
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000435 assert_fails('TextPos.noSuchMember = 2', 'E1337:')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +0000436 assert_fails('TextPos.counter = 5', 'E1335:')
437 assert_fails('TextPos.counter += 5', 'E1335:')
438
439 assert_fails('echo TextPos._secret', 'E1333:')
440 assert_fails('TextPos._secret = 8', 'E1333:')
441
442 assert_equal(42, TextPos.anybody)
443 TextPos.anybody = 12
444 assert_equal(12, TextPos.anybody)
445 TextPos.anybody += 5
446 assert_equal(17, TextPos.anybody)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +0000447 END
448 v9.CheckScriptSuccess(lines)
Bram Moolenaar6acf7572023-01-01 19:53:30 +0000449
450 # check shadowing
451 lines =<< trim END
452 vim9script
453
454 class Some
455 static count = 0
456 def Method(count: number)
457 echo count
458 enddef
459 endclass
460
461 var s = Some.new()
462 s.Method(7)
463 END
464 v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: count')
465
466 lines =<< trim END
467 vim9script
468
469 class Some
470 static count = 0
471 def Method(arg: number)
472 var count = 3
473 echo arg count
474 enddef
475 endclass
476
477 var s = Some.new()
478 s.Method(7)
479 END
480 v9.CheckScriptFailure(lines, 'E1341: Variable already declared in the class: count')
Bram Moolenaar3d473ee2022-12-14 20:59:32 +0000481enddef
482
Bram Moolenaar6bafdd42023-01-01 12:58:33 +0000483def Test_class_function()
484 var lines =<< trim END
485 vim9script
486 class Value
487 this.value = 0
488 static objects = 0
489
490 def new(v: number)
491 this.value = v
492 ++objects
493 enddef
494
495 static def GetCount(): number
496 return objects
497 enddef
498 endclass
499
500 assert_equal(0, Value.GetCount())
501 var v1 = Value.new(2)
502 assert_equal(1, Value.GetCount())
503 var v2 = Value.new(7)
504 assert_equal(2, Value.GetCount())
505 END
506 v9.CheckScriptSuccess(lines)
507enddef
508
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +0000509def Test_class_object_to_string()
510 var lines =<< trim END
511 vim9script
512 class TextPosition
513 this.lnum = 1
514 this.col = 22
515 endclass
516
517 assert_equal("class TextPosition", string(TextPosition))
518
519 var pos = TextPosition.new()
520 assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
521 END
522 v9.CheckScriptSuccess(lines)
523enddef
Bram Moolenaar74e12742022-12-13 21:14:28 +0000524
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000525
526" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker