comparison src/testdir/test_vim9_enum.vim @ 34676:5b25ec43f208 v9.1.0219

patch 9.1.0219: Vim9: No enum support Commit: https://github.com/vim/vim/commit/3164cf8f12f14b725b918e3170bb0a9085af8298 Author: Yegappan Lakshmanan <yegappan@yahoo.com> Date: Thu Mar 28 10:36:42 2024 +0100 patch 9.1.0219: Vim9: No enum support Problem: No enum support Solution: Implement enums for Vim9 script (Yegappan Lakshmanan) closes: #14224 Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
author Christian Brabandt <cb@256bit.org>
date Thu, 28 Mar 2024 10:45:06 +0100
parents
children ad86d59d7510
comparison
equal deleted inserted replaced
34675:42bca55140ec 34676:5b25ec43f208
1 " Test Vim9 enums
2
3 source check.vim
4 import './vim9.vim' as v9
5
6 " Test for parsing an enum definition
7 def Test_enum_parse()
8 # enum supported only in a Vim9 script
9 var lines =<< trim END
10 enum Foo
11 endenum
12 END
13 v9.CheckSourceFailure(lines, 'E1414: Enum can only be defined in Vim9 script', 1)
14
15 # First character in an enum name should be capitalized.
16 lines =<< trim END
17 vim9script
18 enum foo
19 endenum
20 END
21 v9.CheckSourceFailure(lines, 'E1415: Enum name must start with an uppercase letter: foo', 2)
22
23 # Only alphanumeric characters are supported in an enum name
24 lines =<< trim END
25 vim9script
26 enum Foo@bar
27 endenum
28 END
29 v9.CheckSourceFailure(lines, 'E1315: White space required after name: Foo@bar', 2)
30
31 # Unsupported keyword (instead of enum)
32 lines =<< trim END
33 vim9script
34 noenum Something
35 endenum
36 END
37 v9.CheckSourceFailure(lines, 'E492: Not an editor command: noenum Something', 2)
38
39 # Only the complete word "enum" should be recognized
40 lines =<< trim END
41 vim9script
42 enums Something
43 endenum
44 END
45 v9.CheckSourceFailure(lines, 'E492: Not an editor command: enums Something', 2)
46
47 # The complete "endenum" should be specified.
48 lines =<< trim END
49 vim9script
50 enum Something
51 enden
52 END
53 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: enden', 3)
54
55 # Only the complete word "endenum" should be recognized
56 lines =<< trim END
57 vim9script
58 enum Something
59 endenums
60 END
61 v9.CheckSourceFailure(lines, 'E1420: Missing :endenum', 4)
62
63 # all lower case should be used for "enum"
64 lines =<< trim END
65 vim9script
66 Enum Something
67 endenum
68 END
69 v9.CheckSourceFailure(lines, 'E492: Not an editor command: Enum Something', 2)
70
71 # all lower case should be used for "endenum"
72 lines =<< trim END
73 vim9script
74 enum Something
75 Endenum
76 END
77 v9.CheckSourceFailure(lines, 'E1420: Missing :endenum', 4)
78
79 # Additional words after "endenum"
80 lines =<< trim END
81 vim9script
82 enum Something
83 endenum school's out
84 END
85 v9.CheckSourceFailure(lines, "E488: Trailing characters: school's out", 3)
86
87 # Additional commands after "endenum"
88 lines =<< trim END
89 vim9script
90 enum Something
91 endenum | echo 'done'
92 END
93 v9.CheckSourceFailure(lines, "E488: Trailing characters: | echo 'done'", 3)
94
95 # Try to define enum in a single command
96 lines =<< trim END
97 vim9script
98 enum Something | endenum
99 END
100 v9.CheckSourceFailure(lines, 'E1420: Missing :endenum', 3)
101
102 # Try to define an enum with the same name as an existing variable
103 lines =<< trim END
104 vim9script
105 var Something: list<number> = [1]
106 enum Something
107 endenum
108 END
109 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "Something"', 3)
110
111 # Unsupported special character following enum name
112 lines =<< trim END
113 vim9script
114 enum Foo
115 first,
116 second : 20
117 endenum
118 END
119 v9.CheckSourceFailure(lines, 'E1123: Missing comma before argument: : 20', 4)
120
121 # Try initializing an enum item with a number
122 lines =<< trim END
123 vim9script
124 enum Foo
125 first,
126 second = 2
127 endenum
128 END
129 v9.CheckSourceFailure(lines, 'E1123: Missing comma before argument: = 2', 4)
130
131 # Try initializing an enum item with a String
132 lines =<< trim END
133 vim9script
134 enum Foo
135 first,
136 second = 'second'
137 endenum
138 defcompile
139 END
140 v9.CheckSourceFailure(lines, "E1123: Missing comma before argument: = 'second'", 4)
141
142 # Try initializing an enum item with a List
143 lines =<< trim END
144 vim9script
145 enum Foo
146 first,
147 second = []
148 endenum
149 END
150 v9.CheckSourceFailure(lines, 'E1123: Missing comma before argument: = []', 4)
151
152 # Use a colon after name
153 lines =<< trim END
154 vim9script
155 enum Foo
156
157 # first
158 first:
159 second
160 endenum
161 END
162 v9.CheckSourceFailure(lines, 'E1123: Missing comma before argument: :', 5)
163
164 # Use a '=='
165 lines =<< trim END
166 vim9script
167 enum Foo
168 first == 1
169 endenum
170 defcompile
171 END
172 v9.CheckSourceFailure(lines, 'E1123: Missing comma before argument: == 1', 3)
173
174 # Missing comma after an enum item
175 lines =<< trim END
176 vim9script
177 enum Planet
178 mercury
179 venus
180 endenum
181 END
182 v9.CheckSourceFailure(lines, 'E1419: Not a valid command in an Enum: venus', 4)
183
184 # Comma at the beginning of an item
185 lines =<< trim END
186 vim9script
187 enum Planet
188 mercury
189 ,venus
190 endenum
191 END
192 v9.CheckSourceFailure(lines, 'E1419: Not a valid command in an Enum: ,venus', 4)
193 # Space before comma
194 lines =<< trim END
195 vim9script
196 enum Planet
197 mercury ,
198 venus
199 endenum
200 END
201 v9.CheckSourceFailure(lines, "E1068: No white space allowed before ','", 3)
202
203 # No space after comma
204 lines =<< trim END
205 vim9script
206 enum Planet
207 mercury,venus
208 endenum
209 END
210 v9.CheckSourceFailure(lines, "E1069: White space required after ',': mercury,venus", 3)
211
212 # no comma between items in the same line
213 lines =<< trim END
214 vim9script
215 enum Planet
216 mercury venus earth
217 endenum
218 defcompile
219 END
220 v9.CheckSourceFailure(lines, 'E1123: Missing comma before argument: venus earth', 3)
221
222 # No space after an item and comment between items
223 lines =<< trim END
224 vim9script
225 enum Planet
226 mercury
227
228 # Venus
229 venus
230 endenum
231 END
232 v9.CheckSourceFailure(lines, 'E1419: Not a valid command in an Enum: venus', 6)
233
234 # Comma is supported for the last item
235 lines =<< trim END
236 vim9script
237 enum Planet
238 mercury,
239 venus,
240 endenum
241 var p: Planet
242 p = Planet.mercury
243 p = Planet.venus
244 END
245 v9.CheckSourceSuccess(lines)
246
247 # invalid enum value declaration
248 lines =<< trim END
249 vim9script
250 enum Fruit
251 Apple,
252 $%@
253 endenum
254 defcompile
255 END
256 v9.CheckSourceFailure(lines, 'E1418: Invalid enum value declaration: $%@', 4)
257
258 # Duplicate enum value
259 lines =<< trim END
260 vim9script
261 enum A
262 Foo,
263 Bar,
264 Foo
265 endenum
266 END
267 v9.CheckSourceFailure(lines, 'E1428: Duplicate enum value: Foo', 5)
268
269 # Duplicate enum value in the same line
270 lines =<< trim END
271 vim9script
272 enum A
273 Foo, Bar, Foo,
274 Bar
275 endenum
276 END
277 v9.CheckSourceFailure(lines, 'E1428: Duplicate enum value: Foo', 3)
278
279 # Try extending a class when defining an enum
280 lines =<< trim END
281 vim9script
282 class Foo
283 endclass
284 enum Bar extends Foo
285 endenum
286 END
287 v9.CheckSourceFailure(lines, 'E1416: Enum cannot extend a class or enum', 4)
288
289 # Try extending an enum
290 lines =<< trim END
291 vim9script
292 enum Foo
293 endenum
294 enum Bar extends Foo
295 endenum
296 END
297 v9.CheckSourceFailure(lines, 'E1416: Enum cannot extend a class or enum', 4)
298
299 # Try extending an enum using a class
300 lines =<< trim END
301 vim9script
302 enum Foo
303 endenum
304 class Bar extends Foo
305 endclass
306 END
307 v9.CheckSourceFailure(lines, 'E1354: Cannot extend Foo', 5)
308
309 # Try implementing an enum using a class
310 lines =<< trim END
311 vim9script
312 enum Foo
313 endenum
314 class Bar implements Foo
315 endclass
316 END
317 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: Foo', 5)
318
319 # abstract method is not supported in an enum
320 lines =<< trim END
321 vim9script
322 enum Foo
323 Apple
324 abstract def Bar()
325 endenum
326 END
327 v9.CheckSourceFailure(lines, 'E1417: Abstract cannot be used in an Enum', 4)
328
329 # Define an enum without any enum values but only with an object variable
330 lines =<< trim END
331 vim9script
332 enum Foo
333 final n: number = 10
334 endenum
335 END
336 v9.CheckSourceFailure(lines, 'E1123: Missing comma before argument: n: number = 10', 3)
337 enddef
338
339 def Test_basic_enum()
340 # Declare a simple enum
341 var lines =<< trim END
342 vim9script
343 enum Foo
344 apple,
345 orange
346 endenum
347 var a: Foo = Foo.apple
348 var b: Foo = Foo.orange
349 assert_equal(a, Foo.apple)
350 assert_equal(b, Foo.orange)
351 END
352 v9.CheckSourceSuccess(lines)
353
354 # Multiple enums in a single line
355 lines =<< trim END
356 vim9script
357 enum Foo
358 apple, orange
359 endenum
360 assert_equal('enum<Foo>', typename(Foo.apple))
361 assert_equal('enum<Foo>', typename(Foo.orange))
362 END
363 v9.CheckSourceSuccess(lines)
364
365 # Comments and empty lines are supported between enum items
366 lines =<< trim END
367 vim9script
368 enum Foo
369 # Apple
370 apple,
371
372 # Orange
373 orange
374 endenum
375 def Fn()
376 var a: Foo = Foo.apple
377 var b: Foo = Foo.orange
378 assert_equal(a, Foo.apple)
379 assert_equal(b, Foo.orange)
380 enddef
381 END
382 v9.CheckSourceSuccess(lines)
383
384 # Try using a non-existing enum value
385 lines =<< trim END
386 vim9script
387 enum Foo
388 apple,
389 orange
390 endenum
391 var a: Foo = Foo.pear
392 END
393 v9.CheckSourceFailure(lines, 'E1422: Enum value "pear" not found in enum "Foo"', 6)
394
395 # Enum function argument
396 lines =<< trim END
397 vim9script
398 enum Foo
399 apple,
400 orange
401 endenum
402 def Fn(a: Foo): Foo
403 return a
404 enddef
405 assert_equal(Foo.apple, Fn(Foo.apple))
406 END
407 v9.CheckSourceSuccess(lines)
408
409 # Enum function argument
410 lines =<< trim END
411 vim9script
412 enum Foo
413 apple,
414 orange
415 endenum
416 def Fn(a: Foo): Foo
417 return a
418 enddef
419 Fn({})
420 END
421 v9.CheckSourceFailure(lines, 'E1013: Argument 1: type mismatch, expected enum<Foo> but got dict<any>', 9)
422
423 # Returning an enum in a function returning number
424 lines =<< trim END
425 vim9script
426 enum Foo
427 apple,
428 orange
429 endenum
430 def Fn(): number
431 return Foo.orange
432 enddef
433 Fn()
434 END
435 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got enum<Foo>', 1)
436
437 # Returning a number in a function returning enum
438 lines =<< trim END
439 vim9script
440 enum Foo
441 apple,
442 orange
443 endenum
444 def Fn(): Foo
445 return 20
446 enddef
447 Fn()
448 END
449 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected enum<Foo> but got number', 1)
450
451 # Use a List of enums
452 lines =<< trim END
453 vim9script
454 enum Planet
455 Mercury,
456 Venus,
457 Earth
458 endenum
459 var l1: list<Planet> = [Planet.Mercury, Planet.Venus]
460 assert_equal(Planet.Venus, l1[1])
461 def Fn()
462 var l2: list<Planet> = [Planet.Mercury, Planet.Venus]
463 assert_equal(Planet.Venus, l2[1])
464 enddef
465 END
466 v9.CheckSourceSuccess(lines)
467
468 # Try using an enum as a value
469 lines =<< trim END
470 vim9script
471 enum Fruit
472 Apple,
473 Orange
474 endenum
475 var a = Fruit
476 END
477 v9.CheckSourceFailure(lines, 'E1421: Enum "Fruit" cannot be used as a value', 6)
478 enddef
479
480 " Test for type() and typename() of an enum
481 def Test_enum_type()
482 var lines =<< trim END
483 vim9script
484 enum Fruit
485 Apple,
486 Orange
487 endenum
488 assert_equal('enum<Fruit>', typename(Fruit))
489 assert_equal('enum<Fruit>', typename(Fruit.Apple))
490 assert_equal(v:t_enum, type(Fruit))
491 assert_equal(v:t_enumvalue, type(Fruit.Apple))
492 assert_equal(15, type(Fruit))
493 assert_equal(16, type(Fruit.Apple))
494 END
495 v9.CheckSourceSuccess(lines)
496
497 # Assign an enum to a variable with any type
498 lines =<< trim END
499 vim9script
500 enum Fruit
501 Apple,
502 Orange
503 endenum
504 var a = Fruit.Apple
505 var b: any = Fruit.Orange
506 assert_equal('enum<Fruit>', typename(a))
507 assert_equal('enum<Fruit>', typename(b))
508 END
509 v9.CheckSourceSuccess(lines)
510 enddef
511
512 " Try modifying an enum or an enum item
513 def Test_enum_modify()
514 # Try assigning an unsupported value to an enum
515 var lines =<< trim END
516 vim9script
517 enum Foo
518 apple
519 endenum
520 var a: Foo = 30
521 END
522 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected enum<Foo> but got number', 5)
523
524 # Try assigning an unsupported value to an enum in a function
525 lines =<< trim END
526 vim9script
527 enum Foo
528 apple
529 endenum
530 def Fn()
531 var a: Foo = 30
532 enddef
533 defcompile
534 END
535 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected enum<Foo> but got number', 1)
536
537 # Try assigning a number to an enum
538 lines =<< trim END
539 vim9script
540 enum Foo
541 apple,
542 orange
543 endenum
544 Foo = 10
545 END
546 v9.CheckSourceFailure(lines, 'E1421: Enum "Foo" cannot be used as a value', 6)
547
548 # Try assigning a number to an enum in a function
549 lines =<< trim END
550 vim9script
551 enum Foo
552 apple
553 endenum
554 def Fn()
555 Foo = 10
556 enddef
557 defcompile
558 END
559 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected enum<Foo> but got number', 1)
560
561 # Try assigning a number to an enum value
562 lines =<< trim END
563 vim9script
564 enum Foo
565 apple
566 endenum
567 Foo.apple = 20
568 END
569 v9.CheckSourceFailure(lines, 'E1423: Enum value "Foo.apple" cannot be modified', 5)
570
571 # Try assigning a number to an enum value in a function
572 lines =<< trim END
573 vim9script
574 enum Foo
575 apple
576 endenum
577 def Fn()
578 Foo.apple = 20
579 enddef
580 defcompile
581 END
582 v9.CheckSourceFailure(lines, 'E1423: Enum value "Foo.apple" cannot be modified', 1)
583
584 # Try assigning one enum to another
585 lines =<< trim END
586 vim9script
587 enum Foo
588 endenum
589 enum Bar
590 endenum
591 Foo = Bar
592 END
593 v9.CheckSourceFailure(lines, 'E1421: Enum "Bar" cannot be used as a value', 6)
594
595 # Try assigning one enum to another in a function
596 lines =<< trim END
597 vim9script
598 enum Foo
599 endenum
600 enum Bar
601 endenum
602 def Fn()
603 Foo = Bar
604 enddef
605 defcompile
606 END
607 v9.CheckSourceFailure(lines, 'E1421: Enum "Bar" cannot be used as a value', 1)
608
609 # Try assigning one enum item to another enum item
610 lines =<< trim END
611 vim9script
612 enum Foo
613 Apple
614 endenum
615 enum Bar
616 Orange
617 endenum
618 Foo.Apple = Bar.Orange
619 END
620 v9.CheckSourceFailure(lines, 'E1423: Enum value "Foo.Apple" cannot be modified', 8)
621
622 # Try assigning one enum item to another enum item in a function
623 lines =<< trim END
624 vim9script
625 enum Foo
626 Apple
627 endenum
628 enum Bar
629 Orange
630 endenum
631 def Fn()
632 Foo.Apple = Bar.Orange
633 enddef
634 defcompile
635 END
636 v9.CheckSourceFailure(lines, 'E1423: Enum value "Foo.Apple" cannot be modified', 1)
637 enddef
638
639 " Test for using enum in an expression
640 def Test_enum_expr()
641 var lines =<< trim END
642 vim9script
643 enum Color
644 Red, Blue, Green
645 endenum
646 var a: number = 1 + Color
647 END
648 v9.CheckSourceFailure(lines, 'E1421: Enum "Color" cannot be used as a value', 5)
649
650 lines =<< trim END
651 vim9script
652 enum Color
653 Red, Blue, Green
654 endenum
655 var a: number = 1 + Color.Red
656 END
657 v9.CheckSourceFailure(lines, 'E1424: Using an Enum "Color" as a Number', 5)
658
659 lines =<< trim END
660 vim9script
661 enum Color
662 Red, Blue, Green
663 endenum
664 var s: string = "abc" .. Color
665 END
666 v9.CheckSourceFailure(lines, 'E1421: Enum "Color" cannot be used as a value', 5)
667
668 lines =<< trim END
669 vim9script
670 enum Color
671 Red, Blue, Green
672 endenum
673 var s: string = "abc" .. Color.Red
674 END
675 v9.CheckSourceFailure(lines, 'E1425: Using an Enum "Color" as a String', 5)
676 enddef
677
678 " Using an enum in a lambda function
679 def Test_enum_lambda()
680 var lines =<< trim END
681 vim9script
682 enum Planet
683 Mercury,
684 Venus,
685 Earth,
686 endenum
687 var Fn = (p: Planet): Planet => p
688 for [idx, v] in items([Planet.Mercury, Planet.Venus, Planet.Earth])
689 assert_equal(idx, Fn(v).ordinal)
690 endfor
691 END
692 v9.CheckSourceSuccess(lines)
693 enddef
694
695 " Comparison using enums
696 def Test_enum_compare()
697 var lines =<< trim END
698 vim9script
699 enum Planet
700 Mercury,
701 Venus,
702 Earth,
703 endenum
704 enum Fruit
705 Apple,
706 Orange
707 endenum
708
709 var p: Planet = Planet.Venus
710 var f: Fruit = Fruit.Orange
711 assert_equal(true, p == Planet.Venus)
712 assert_equal(false, p == Planet.Earth)
713 assert_equal(false, p == f)
714 assert_equal(true, Planet.Mercury == Planet.Mercury)
715 assert_equal(true, Planet.Venus != Planet.Earth)
716 assert_equal(true, Planet.Mercury != Fruit.Apple)
717
718 def Fn1()
719 var p2: Planet = Planet.Venus
720 var f2: Fruit = Fruit.Orange
721 assert_equal(true, p2 == Planet.Venus)
722 assert_equal(false, p2 == Planet.Earth)
723 assert_equal(false, p2 == f2)
724 enddef
725 Fn1()
726
727 # comparison using "is" and "isnot"
728 assert_equal(true, p is Planet.Venus)
729 assert_equal(true, p isnot Planet.Earth)
730 assert_equal(false, p is Fruit.Orange)
731 assert_equal(true, p isnot Fruit.Orange)
732 def Fn2(arg: Planet)
733 assert_equal(true, arg is Planet.Venus)
734 assert_equal(true, arg isnot Planet.Earth)
735 assert_equal(false, arg is Fruit.Orange)
736 assert_equal(true, arg isnot Fruit.Orange)
737 enddef
738 Fn2(p)
739
740 class A
741 endclass
742 var o: A = A.new()
743 assert_equal(false, p == o)
744 END
745 v9.CheckSourceSuccess(lines)
746 enddef
747
748 " Test for using an enum as a default argument to a function
749 def Test_enum_default_arg()
750 var lines =<< trim END
751 vim9script
752 enum Day
753 Monday, Tuesday, Wednesday
754 endenum
755 def Fn(d: Day = Day.Tuesday): Day
756 return d
757 enddef
758 assert_equal(Day.Tuesday, Fn())
759 assert_equal(Day.Wednesday, Fn(Day.Wednesday))
760 END
761 v9.CheckSourceSuccess(lines)
762 enddef
763
764 " Test for enum garbage collection
765 func Test_enum_garbagecollect()
766 let lines =<< trim END
767 vim9script
768 enum Car
769 Honda, Ford, Tesla
770 endenum
771 assert_equal(1, Car.Ford.ordinal)
772 call test_garbagecollect_now()
773 assert_equal(1, Car.Ford.ordinal)
774 var c: Car = Car.Tesla
775 assert_equal(2, c.ordinal)
776 call test_garbagecollect_now()
777 assert_equal(2, c.ordinal)
778 END
779 call v9.CheckSourceSuccess(lines)
780
781 " garbage collection with a variable of type any
782 let lines =<< trim END
783 vim9script
784 enum Car
785 Honda, Ford, Tesla
786 endenum
787 call test_garbagecollect_now()
788 var c: any = Car.Tesla
789 call test_garbagecollect_now()
790 assert_equal(Car.Tesla, c)
791 END
792 call v9.CheckSourceSuccess(lines)
793
794 " garbage collection with function arguments and return types
795 let lines =<< trim END
796 vim9script
797 enum Car
798 Honda, Ford, Tesla
799 endenum
800 def Fn(a: Car): Car
801 assert_equal(Car.Ford, a)
802 return Car.Tesla
803 enddef
804 call test_garbagecollect_now()
805 var b: Car = Car.Ford
806 call test_garbagecollect_now()
807 assert_equal(Car.Tesla, Fn(b))
808 call test_garbagecollect_now()
809 END
810 call v9.CheckSourceSuccess(lines)
811 endfunc
812
813 " Test for the enum values class variable
814 def Test_enum_values()
815 var lines =<< trim END
816 vim9script
817 enum Car
818 Honda, Ford, Tesla
819 endenum
820 var l: list<Car> = Car.values
821 assert_equal(Car.Ford, l[1])
822 END
823 v9.CheckSourceSuccess(lines)
824
825 # empty enum
826 lines =<< trim END
827 vim9script
828 enum Car
829 endenum
830 assert_equal([], Car.values)
831 END
832 v9.CheckSourceSuccess(lines)
833
834 # single value
835 lines =<< trim END
836 vim9script
837 enum Car
838 Honda
839 endenum
840 assert_equal([Car.Honda], Car.values)
841 END
842 v9.CheckSourceSuccess(lines)
843
844 lines =<< trim END
845 vim9script
846 enum A
847 Red,
848 Blue
849 static def GetValues(): list<A>
850 return values
851 enddef
852 endenum
853 assert_equal([A.Red, A.Blue], A.GetValues())
854 END
855 v9.CheckSourceSuccess(lines)
856
857 # Other class variables in an enum should not be added to 'values'
858 lines =<< trim END
859 vim9script
860 enum LogLevel
861 Error, Warn
862 static const x: number = 22
863 endenum
864 assert_equal([LogLevel.Error, LogLevel.Warn], LogLevel.values)
865 END
866 v9.CheckSourceSuccess(lines)
867
868 # Other class variable of enum type should not be added to 'values'
869 lines =<< trim END
870 vim9script
871 enum LogLevel
872 Error, Warn
873 static const x: LogLevel = LogLevel.Warn
874 endenum
875 assert_equal([LogLevel.Error, LogLevel.Warn], LogLevel.values)
876 END
877 v9.CheckSourceSuccess(lines)
878 enddef
879
880 " Test comments in enums
881 def Test_enum_comments()
882 var lines =<< trim END
883 vim9script
884 enum Car # cars
885 # before enum
886 Honda, # honda
887 # before enum
888 Ford # ford
889 endenum
890 assert_equal(1, Car.Ford.ordinal)
891 END
892 v9.CheckSourceSuccess(lines)
893
894 # Test for using an unsupported comment
895 lines =<< trim END
896 vim9script
897 enum Car
898 Honda,
899 Ford,
900 #{
901 endenum
902 defcompile
903 END
904 v9.CheckSourceFailure(lines, 'E1170: Cannot use #{ to start a comment', 4)
905 enddef
906
907 " Test string() with enums
908 def Test_enum_string()
909 var lines =<< trim END
910 vim9script
911 enum Car
912 Honda,
913 Ford
914 endenum
915 assert_equal("enum Car", string(Car))
916 assert_equal("Car.Honda", string(Car.Honda))
917 END
918 v9.CheckSourceSuccess(lines)
919 enddef
920
921 " Test for importing an enum
922 def Test_enum_import()
923 var lines =<< trim END
924 vim9script
925 export enum Star
926 Gemini,
927 Orion,
928 Pisces
929 endenum
930 END
931 writefile(lines, 'Xenumexport.vim', 'D')
932
933 lines =<< trim END
934 vim9script
935 import './Xenumexport.vim' as mod
936
937 var s1: mod.Star = mod.Star.Orion
938 assert_equal(true, s1 == mod.Star.Orion)
939 assert_equal(2, mod.Star.Pisces.ordinal)
940 var l1: list<mod.Star> = mod.Star.values
941 assert_equal("Star.Orion", string(l1[1]))
942 assert_equal(s1, l1[1])
943
944 def Fn()
945 var s2: mod.Star = mod.Star.Orion
946 assert_equal(true, s2 == mod.Star.Orion)
947 assert_equal(2, mod.Star.Pisces.ordinal)
948 var l2: list<mod.Star> = mod.Star.values
949 assert_equal("Star.Orion", string(l2[1]))
950 assert_equal(s2, l2[1])
951 enddef
952 Fn()
953 END
954 v9.CheckScriptSuccess(lines)
955 enddef
956
957 " Test for using test_refcount() with enum
958 def Test_enum_refcount()
959 var lines =<< trim END
960 vim9script
961 enum Foo
962 endenum
963 assert_equal(1, test_refcount(Foo))
964
965 enum Star
966 Gemini,
967 Orion,
968 endenum
969 assert_equal(3, test_refcount(Star))
970 assert_equal(2, test_refcount(Star.Gemini))
971 assert_equal(2, test_refcount(Star.Orion))
972
973 var s: Star
974 assert_equal(3, test_refcount(Star))
975 assert_equal(-1, test_refcount(s))
976 s = Star.Orion
977 assert_equal(3, test_refcount(Star))
978 assert_equal(3, test_refcount(s))
979 assert_equal(2, test_refcount(Star.Gemini))
980 var t = s
981 assert_equal(3, test_refcount(Star))
982 assert_equal(4, test_refcount(s))
983 assert_equal(4, test_refcount(Star.Orion))
984 END
985 v9.CheckSourceSuccess(lines)
986 enddef
987
988 " Test for defining an enum with additional object variables and methods
989 def Test_enum_enhanced()
990 var lines =<< trim END
991 vim9script
992 enum Vehicle
993 car(4, 5, 400),
994 bus(6, 50, 800),
995 bicycle(2, 1, 0)
996
997 final tires: number
998 final passengers: number
999 final carbonPerKilometer: number
1000
1001 def new(t: number, p: number, cpk: number)
1002 this.tires = t
1003 this.passengers = p
1004 this.carbonPerKilometer = cpk
1005 enddef
1006
1007 def CarbonFootprint(): float
1008 return round(this.carbonPerKilometer / this.passengers)
1009 enddef
1010
1011 def IsTwoWheeled(): bool
1012 return this == Vehicle.bicycle
1013 enddef
1014
1015 def CompareTo(other: Vehicle): float
1016 return this.CarbonFootprint() - other.CarbonFootprint()
1017 enddef
1018 endenum
1019
1020 var v: Vehicle = Vehicle.bus
1021 assert_equal([6, 50, 800], [v.tires, v.passengers, v.carbonPerKilometer])
1022 assert_equal(true, Vehicle.bicycle.IsTwoWheeled())
1023 assert_equal(false, Vehicle.car.IsTwoWheeled())
1024 assert_equal(16.0, Vehicle.bus.CarbonFootprint())
1025 END
1026 v9.CheckSourceSuccess(lines)
1027 enddef
1028
1029 " Test for the enum value 'name' variable
1030 def Test_enum_name()
1031 # Check the names of enum values
1032 var lines =<< trim END
1033 vim9script
1034 enum Planet
1035 Mercury,
1036 Venus,
1037 Earth
1038 endenum
1039 assert_equal('Mercury', Planet.Mercury.name)
1040 assert_equal('Venus', Planet.Venus.name)
1041 assert_equal('Earth', Planet.Earth.name)
1042 assert_equal('string', typename(Planet.Earth.name))
1043 END
1044 v9.CheckSourceSuccess(lines)
1045
1046 # Check the name of enum items in the constructor
1047 lines =<< trim END
1048 vim9script
1049 enum Planet
1050 Mercury("Mercury"),
1051 Venus("Venus"),
1052 Earth("Earth")
1053
1054 def new(s: string)
1055 assert_equal(s, this.name)
1056 enddef
1057 endenum
1058 defcompile
1059 END
1060 v9.CheckSourceSuccess(lines)
1061
1062 # Try assigning to the name of an enum
1063 lines =<< trim END
1064 vim9script
1065 enum Fruit
1066 Apple
1067 endenum
1068 Fruit.Apple.name = 'foo'
1069 END
1070 v9.CheckSourceFailure(lines, 'E1335: Variable "name" in class "Fruit" is not writable', 5)
1071
1072 # Try assigning to the name of an enum in a function
1073 lines =<< trim END
1074 vim9script
1075 enum Fruit
1076 Apple
1077 endenum
1078 def Fn()
1079 Fruit.Apple.name = 'bar'
1080 enddef
1081 defcompile
1082 END
1083 v9.CheckSourceFailure(lines, 'E1423: Enum value "Fruit.name" cannot be modified', 1)
1084
1085 # Try to overwrite an enum value name in the enum constructor
1086 lines =<< trim END
1087 vim9script
1088 enum Planet
1089 Mercury,
1090 Venus
1091
1092 def new()
1093 this.name = 'foo'
1094 enddef
1095 endenum
1096 END
1097 v9.CheckSourceFailure(lines, 'E1427: Enum "Planet" name cannot be modified', 1)
1098
1099 # Try to declare an object variable named 'name'
1100 lines =<< trim END
1101 vim9script
1102 enum Planet
1103 Mercury
1104 var name: string
1105 endenum
1106 END
1107 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: name', 4)
1108 enddef
1109
1110 " Test for the enum value 'ordinal' variable
1111 def Test_enum_ordinal()
1112 # Check the ordinal values of enum items
1113 var lines =<< trim END
1114 vim9script
1115 enum Planet
1116 Mercury,
1117 Venus,
1118 Earth
1119 endenum
1120 assert_equal(0, Planet.Mercury.ordinal)
1121 assert_equal(1, Planet.Venus.ordinal)
1122 assert_equal(2, Planet.Earth.ordinal)
1123 assert_equal('number', typename(Planet.Earth.ordinal))
1124 END
1125 v9.CheckSourceSuccess(lines)
1126
1127 # Check the ordinal value of enum items in the constructor
1128 lines =<< trim END
1129 vim9script
1130 enum Planet
1131 Mercury(0),
1132 Venus(1),
1133 Earth(2)
1134
1135 def new(v: number)
1136 assert_equal(v, this.ordinal)
1137 enddef
1138 endenum
1139 defcompile
1140 END
1141 v9.CheckSourceSuccess(lines)
1142
1143 # Try assigning to the ordinal value of an enum
1144 lines =<< trim END
1145 vim9script
1146 enum Fruit
1147 Apple
1148 endenum
1149 Fruit.Apple.ordinal = 20
1150 END
1151 v9.CheckSourceFailure(lines, 'E1335: Variable "ordinal" in class "Fruit" is not writable', 5)
1152
1153 # Try assigning to the ordinal value of an enum in a function
1154 lines =<< trim END
1155 vim9script
1156 enum Fruit
1157 Apple
1158 endenum
1159 def Fn()
1160 Fruit.Apple.ordinal = 20
1161 enddef
1162 defcompile
1163 END
1164 v9.CheckSourceFailure(lines, 'E1423: Enum value "Fruit.ordinal" cannot be modified', 1)
1165
1166 # Try to overwrite an enum value ordinal in the enum constructor
1167 lines =<< trim END
1168 vim9script
1169 enum Planet
1170 Mercury,
1171 Venus
1172
1173 def new()
1174 this.ordinal = 20
1175 enddef
1176 endenum
1177 END
1178 v9.CheckSourceFailure(lines, 'E1426: Enum "Planet" ordinal value cannot be modified', 1)
1179
1180 # Try to declare an object variable named 'ordinal'
1181 lines =<< trim END
1182 vim9script
1183 enum Planet
1184 Mercury
1185 var ordinal: number
1186 endenum
1187 END
1188 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: ordinal', 4)
1189 enddef
1190
1191 " Test for trying to create a new enum object using the constructor
1192 def Test_enum_invoke_constructor()
1193 var lines =<< trim END
1194 vim9script
1195 enum Foo
1196 endenum
1197 var f: Foo = Foo.new()
1198 END
1199 v9.CheckSourceFailure(lines, 'E1325: Method "new" not found in class "Foo"', 4)
1200
1201 lines =<< trim END
1202 vim9script
1203 enum Fruit
1204 Apple,
1205 Orange
1206 endenum
1207 var f: Fruit = Fruit.new()
1208 END
1209 v9.CheckSourceFailure(lines, 'E1325: Method "new" not found in class "Fruit"', 6)
1210
1211 lines =<< trim END
1212 vim9script
1213 enum Fruit
1214 Apple,
1215 Orange
1216 def newFruit()
1217 enddef
1218 endenum
1219 var f: Fruit = Fruit.newFruit()
1220 END
1221 v9.CheckSourceFailure(lines, 'E1325: Method "newFruit" not found in class "Fruit"', 8)
1222
1223 lines =<< trim END
1224 vim9script
1225 enum Fruit
1226 Apple,
1227 Orange
1228 endenum
1229 def Fn()
1230 var f: Fruit = Fruit.new()
1231 enddef
1232 Fn()
1233 END
1234 v9.CheckSourceFailure(lines, 'E1325: Method "new" not found in class "Fruit"', 1)
1235
1236 # error in the enum constructor
1237 lines =<< trim END
1238 vim9script
1239 enum Planet
1240 earth
1241 def new()
1242 x = 123
1243 enddef
1244 endenum
1245 END
1246 v9.CheckSourceFailureList(lines, ['E1100:', 'E1100:'], 1)
1247 enddef
1248
1249 " Test for checking "this" in an enum constructor
1250 def Test_enum_this_in_constructor()
1251 var lines =<< trim END
1252 vim9script
1253 enum A
1254 Red("A.Red"),
1255 Blue("A.Blue"),
1256 Green("A.Green")
1257
1258 def new(s: string)
1259 assert_equal(s, string(this))
1260 enddef
1261 endenum
1262 defcompile
1263 END
1264 v9.CheckSourceSuccess(lines)
1265 enddef
1266
1267 " Test for using member variables in an enum object
1268 def Test_enum_object_variable()
1269 var lines =<< trim END
1270 vim9script
1271 enum Planet
1272 Jupiter(95),
1273 Saturn(146)
1274
1275 var moons: number
1276 endenum
1277 assert_equal(95, Planet.Jupiter.moons)
1278 assert_equal(146, Planet.Saturn.moons)
1279 END
1280 v9.CheckSourceSuccess(lines)
1281
1282 # Use a final object variable
1283 lines =<< trim END
1284 vim9script
1285 enum Planet
1286 Jupiter(95),
1287 Saturn(146)
1288
1289 final moons: number
1290 def new(n: number)
1291 this.moons = n
1292 enddef
1293 endenum
1294 assert_equal(95, Planet.Jupiter.moons)
1295 assert_equal(146, Planet.Saturn.moons)
1296 END
1297 v9.CheckSourceSuccess(lines)
1298
1299 # Use a const object variable
1300 lines =<< trim END
1301 vim9script
1302 enum Planet
1303 Mars(false),
1304 Jupiter(true)
1305
1306 const has_ring: bool
1307 def new(r: bool)
1308 this.has_ring = r
1309 enddef
1310 endenum
1311 assert_equal(false, Planet.Mars.has_ring)
1312 assert_equal(true, Planet.Jupiter.has_ring)
1313 END
1314 v9.CheckSourceSuccess(lines)
1315
1316 # Use a regular object variable
1317 lines =<< trim END
1318 vim9script
1319 enum Fruit
1320 Apple,
1321 Orange
1322
1323 final farm: string = 'SunValley'
1324 endenum
1325 assert_equal('SunValley', Fruit.Apple.farm)
1326 assert_equal('SunValley', Fruit.Apple.farm)
1327 END
1328 v9.CheckSourceSuccess(lines)
1329
1330 # Invoke the default constructor with an object variable
1331 lines =<< trim END
1332 vim9script
1333 enum Fruit
1334 Apple('foo'),
1335 Orange('bar')
1336
1337 final t: string
1338 endenum
1339 assert_equal('foo', Fruit.Apple.t)
1340 assert_equal('bar', Fruit.Orange.t)
1341 END
1342 v9.CheckSourceSuccess(lines)
1343
1344 # Invoke the default constructor with an argument but without the object
1345 # variable
1346 lines =<< trim END
1347 vim9script
1348 enum Fruit
1349 Apple,
1350 Orange('bar')
1351 endenum
1352 defcompile
1353 END
1354 v9.CheckSourceFailure(lines, 'E118: Too many arguments for function: new', 5)
1355
1356 # Define a default constructor with an argument, but don't pass it in when
1357 # defining the enum value
1358 lines =<< trim END
1359 vim9script
1360 enum Fruit
1361 Apple(5),
1362 Orange
1363
1364 def new(t: number)
1365 enddef
1366 endenum
1367 defcompile
1368 END
1369 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: new', 8)
1370 enddef
1371
1372 " Test for using a custom constructor with an enum
1373 def Test_enum_custom_constructor()
1374 # space before "("
1375 var lines =<< trim END
1376 vim9script
1377 enum Fruit
1378 Apple(10),
1379 Orange (20)
1380
1381 def new(t: number)
1382 enddef
1383 endenum
1384 defcompile
1385 END
1386 v9.CheckSourceFailure(lines, "E1068: No white space allowed before '(': Orange (20)", 4)
1387
1388 # no closing ")"
1389 lines =<< trim END
1390 vim9script
1391 enum Fruit
1392 Apple(10),
1393 Orange (20
1394
1395 def new(t: number)
1396 enddef
1397 endenum
1398 defcompile
1399 END
1400 v9.CheckSourceFailure(lines, "E1068: No white space allowed before '(': Orange (20", 4)
1401
1402 # Specify constructor arguments split across multiple lines
1403 lines =<< trim END
1404 vim9script
1405 enum Fruit
1406 Apple(10,
1407 'foo'), Orange(20,
1408 'bar'),
1409 Pear(30,
1410 'baz'), Mango(40,
1411 'qux')
1412
1413 final n: number
1414 final s: string
1415 def new(t: number, str: string)
1416 this.n = t
1417 this.s = str
1418 enddef
1419 endenum
1420 defcompile
1421 assert_equal([10, 'foo'], [Fruit.Apple.n, Fruit.Apple.s])
1422 assert_equal([20, 'bar'], [Fruit.Orange.n, Fruit.Orange.s])
1423 assert_equal([30, 'baz'], [Fruit.Pear.n, Fruit.Pear.s])
1424 assert_equal([40, 'qux'], [Fruit.Mango.n, Fruit.Mango.s])
1425 END
1426 v9.CheckSourceSuccess(lines)
1427
1428 # specify multiple enums with constructor arguments in a single line
1429 lines =<< trim END
1430 vim9script
1431 enum Fruit
1432 Apple(10, 'foo'), Orange(20, 'bar'), Pear(30, 'baz'), Mango(40, 'qux')
1433 const n: number
1434 const s: string
1435 endenum
1436 defcompile
1437 assert_equal([10, 'foo'], [Fruit.Apple.n, Fruit.Apple.s])
1438 assert_equal([20, 'bar'], [Fruit.Orange.n, Fruit.Orange.s])
1439 assert_equal([30, 'baz'], [Fruit.Pear.n, Fruit.Pear.s])
1440 assert_equal([40, 'qux'], [Fruit.Mango.n, Fruit.Mango.s])
1441 END
1442 v9.CheckSourceSuccess(lines)
1443 enddef
1444
1445 " Test for using class variables in an enum class
1446 def Test_enum_class_variable()
1447 var lines =<< trim END
1448 vim9script
1449 enum Fruit
1450 Apple,
1451 Orange
1452
1453 static var farm: string = 'SunValley'
1454 endenum
1455 assert_equal('SunValley', Fruit.farm)
1456 END
1457 v9.CheckSourceSuccess(lines)
1458 enddef
1459
1460 " Test for converting an enum value to a string and then back to an enum value
1461 def Test_enum_eval()
1462 var lines =<< trim END
1463 vim9script
1464 enum Color
1465 Red,
1466 Blue
1467 endenum
1468 var s: string = string(Color.Blue)
1469 var e = eval(s)
1470 assert_equal(Color.Blue, e)
1471 assert_equal(1, e.ordinal)
1472 END
1473 v9.CheckSourceSuccess(lines)
1474 enddef
1475
1476 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker