blob: de26259d49fe0f3a99df1729983bd3f0e14111e5 [file] [log] [blame]
" Test Vim9 enums
source check.vim
import './vim9.vim' as v9
" Test for parsing an enum definition
def Test_enum_parse()
# enum supported only in a Vim9 script
var lines =<< trim END
enum Foo
endenum
END
v9.CheckSourceFailure(lines, 'E1414: Enum can only be defined in Vim9 script', 1)
# First character in an enum name should be capitalized.
lines =<< trim END
vim9script
enum foo
endenum
END
v9.CheckSourceFailure(lines, 'E1415: Enum name must start with an uppercase letter: foo', 2)
# Only alphanumeric characters are supported in an enum name
lines =<< trim END
vim9script
enum Foo@bar
endenum
END
v9.CheckSourceFailure(lines, 'E1315: White space required after name: Foo@bar', 2)
# Unsupported keyword (instead of enum)
lines =<< trim END
vim9script
noenum Something
endenum
END
v9.CheckSourceFailure(lines, 'E492: Not an editor command: noenum Something', 2)
# Only the complete word "enum" should be recognized
lines =<< trim END
vim9script
enums Something
endenum
END
v9.CheckSourceFailure(lines, 'E492: Not an editor command: enums Something', 2)
# The complete "enum" should be specified.
lines =<< trim END
vim9script
enu Something
endenum
END
v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: enu', 2)
# The complete "endenum" should be specified.
lines =<< trim END
vim9script
enum Something
enden
END
v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: enden', 3)
# Only the complete word "endenum" should be recognized
lines =<< trim END
vim9script
enum Something
endenums
END
v9.CheckSourceFailure(lines, 'E1420: Missing :endenum', 4)
# all lower case should be used for "enum"
lines =<< trim END
vim9script
Enum Something
endenum
END
v9.CheckSourceFailure(lines, 'E492: Not an editor command: Enum Something', 2)
# all lower case should be used for "endenum"
lines =<< trim END
vim9script
enum Something
Endenum
END
v9.CheckSourceFailure(lines, 'E1420: Missing :endenum', 4)
# Additional words after "endenum"
lines =<< trim END
vim9script
enum Something
endenum school's out
END
v9.CheckSourceFailure(lines, "E488: Trailing characters: school's out", 3)
# Additional commands after "endenum"
lines =<< trim END
vim9script
enum Something
endenum | echo 'done'
END
v9.CheckSourceFailure(lines, "E488: Trailing characters: | echo 'done'", 3)
# Try to define enum in a single command
lines =<< trim END
vim9script
enum Something | endenum
END
v9.CheckSourceFailure(lines, 'E488: Trailing characters: | endenum', 2)
# another command follows the enum name
lines =<< trim END
vim9script
enum Something | var x = 10
Foo
endenum
END
v9.CheckSourceFailure(lines, 'E488: Trailing characters: | var x = 10', 2)
# Try to define an enum with the same name as an existing variable
lines =<< trim END
vim9script
var Something: list<number> = [1]
enum Something
endenum
END
v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "Something"', 3)
# Unsupported special character following enum name
lines =<< trim END
vim9script
enum Foo
first,
second : 20
endenum
END
v9.CheckSourceFailure(lines, 'E1123: Missing comma before argument: : 20', 4)
# Try initializing an enum item with a number
lines =<< trim END
vim9script
enum Foo
first,
second = 2
endenum
END
v9.CheckSourceFailure(lines, 'E1123: Missing comma before argument: = 2', 4)
# Try initializing an enum item with a String
lines =<< trim END
vim9script
enum Foo
first,
second = 'second'
endenum
defcompile
END
v9.CheckSourceFailure(lines, "E1123: Missing comma before argument: = 'second'", 4)
# Try initializing an enum item with a List
lines =<< trim END
vim9script
enum Foo
first,
second = []
endenum
END
v9.CheckSourceFailure(lines, 'E1123: Missing comma before argument: = []', 4)
# Use a colon after name
lines =<< trim END
vim9script
enum Foo
# first
first:
second
endenum
END
v9.CheckSourceFailure(lines, 'E1123: Missing comma before argument: :', 5)
# Use a '=='
lines =<< trim END
vim9script
enum Foo
first == 1
endenum
defcompile
END
v9.CheckSourceFailure(lines, 'E1123: Missing comma before argument: == 1', 3)
# Missing comma after an enum item
lines =<< trim END
vim9script
enum Planet
mercury
venus
endenum
END
v9.CheckSourceFailure(lines, 'E1419: Not a valid command in an Enum: venus', 4)
# Comma at the beginning of an item
lines =<< trim END
vim9script
enum Planet
mercury
,venus
endenum
END
v9.CheckSourceFailure(lines, 'E1419: Not a valid command in an Enum: ,venus', 4)
# Space before comma
lines =<< trim END
vim9script
enum Planet
mercury ,
venus
endenum
END
v9.CheckSourceFailure(lines, "E1068: No white space allowed before ','", 3)
# No space after comma
lines =<< trim END
vim9script
enum Planet
mercury,venus
endenum
END
v9.CheckSourceFailure(lines, "E1069: White space required after ',': mercury,venus", 3)
# no comma between items in the same line
lines =<< trim END
vim9script
enum Planet
mercury venus earth
endenum
defcompile
END
v9.CheckSourceFailure(lines, 'E1123: Missing comma before argument: venus earth', 3)
# No space after an item and comment between items
lines =<< trim END
vim9script
enum Planet
mercury
# Venus
venus
endenum
END
v9.CheckSourceFailure(lines, 'E1419: Not a valid command in an Enum: venus', 6)
# Comma is supported for the last item
lines =<< trim END
vim9script
enum Planet
mercury,
venus,
endenum
var p: Planet
p = Planet.mercury
p = Planet.venus
END
v9.CheckSourceSuccess(lines)
# invalid enum value declaration
lines =<< trim END
vim9script
enum Fruit
Apple,
$%@
endenum
defcompile
END
v9.CheckSourceFailure(lines, 'E1418: Invalid enum value declaration: $%@', 4)
# Duplicate enum value
lines =<< trim END
vim9script
enum A
Foo,
Bar,
Foo
endenum
END
v9.CheckSourceFailure(lines, 'E1428: Duplicate enum value: Foo', 5)
# Duplicate enum value in the same line
lines =<< trim END
vim9script
enum A
Foo, Bar, Foo,
Bar
endenum
END
v9.CheckSourceFailure(lines, 'E1428: Duplicate enum value: Foo', 3)
# Try extending a class when defining an enum
lines =<< trim END
vim9script
class Foo
endclass
enum Bar extends Foo
endenum
END
v9.CheckSourceFailure(lines, 'E1416: Enum cannot extend a class or enum', 4)
# Try extending an enum
lines =<< trim END
vim9script
enum Foo
endenum
enum Bar extends Foo
endenum
END
v9.CheckSourceFailure(lines, 'E1416: Enum cannot extend a class or enum', 4)
# Try extending an enum using a class
lines =<< trim END
vim9script
enum Foo
endenum
class Bar extends Foo
endclass
END
v9.CheckSourceFailure(lines, 'E1354: Cannot extend Foo', 5)
# Try implementing an enum using a class
lines =<< trim END
vim9script
enum Foo
endenum
class Bar implements Foo
endclass
END
v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: Foo', 5)
# abstract method is not supported in an enum
lines =<< trim END
vim9script
enum Foo
Apple
abstract def Bar()
endenum
END
v9.CheckSourceFailure(lines, 'E1417: Abstract cannot be used in an Enum', 4)
# Define an enum without any enum values but only with an object variable
lines =<< trim END
vim9script
enum Foo
final n: number = 10
endenum
END
v9.CheckSourceFailure(lines, 'E1123: Missing comma before argument: n: number = 10', 3)
enddef
def Test_basic_enum()
# Declare a simple enum
var lines =<< trim END
vim9script
enum Foo
apple,
orange
endenum
var a: Foo = Foo.apple
var b: Foo = Foo.orange
assert_equal(a, Foo.apple)
assert_equal(b, Foo.orange)
END
v9.CheckSourceSuccess(lines)
# Multiple enums in a single line
lines =<< trim END
vim9script
enum Foo
apple, orange
endenum
assert_equal('enum<Foo>', typename(Foo.apple))
assert_equal('enum<Foo>', typename(Foo.orange))
END
v9.CheckSourceSuccess(lines)
# Comments and empty lines are supported between enum items
lines =<< trim END
vim9script
enum Foo
# Apple
apple,
# Orange
orange
endenum
def Fn()
var a: Foo = Foo.apple
var b: Foo = Foo.orange
assert_equal(a, Foo.apple)
assert_equal(b, Foo.orange)
enddef
END
v9.CheckSourceSuccess(lines)
# Try using a non-existing enum value
lines =<< trim END
vim9script
enum Foo
apple,
orange
endenum
var a: Foo = Foo.pear
END
v9.CheckSourceFailure(lines, 'E1422: Enum value "pear" not found in enum "Foo"', 6)
# Enum function argument
lines =<< trim END
vim9script
enum Foo
apple,
orange
endenum
def Fn(a: Foo): Foo
return a
enddef
assert_equal(Foo.apple, Fn(Foo.apple))
END
v9.CheckSourceSuccess(lines)
# Enum function argument
lines =<< trim END
vim9script
enum Foo
apple,
orange
endenum
def Fn(a: Foo): Foo
return a
enddef
Fn({})
END
v9.CheckSourceFailure(lines, 'E1013: Argument 1: type mismatch, expected enum<Foo> but got dict<any>', 9)
# Returning an enum in a function returning number
lines =<< trim END
vim9script
enum Foo
apple,
orange
endenum
def Fn(): number
return Foo.orange
enddef
Fn()
END
v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got enum<Foo>', 1)
# Returning a number in a function returning enum
lines =<< trim END
vim9script
enum Foo
apple,
orange
endenum
def Fn(): Foo
return 20
enddef
Fn()
END
v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected enum<Foo> but got number', 1)
# Use a List of enums
lines =<< trim END
vim9script
enum Planet
Mercury,
Venus,
Earth
endenum
var l1: list<Planet> = [Planet.Mercury, Planet.Venus]
assert_equal(Planet.Venus, l1[1])
def Fn()
var l2: list<Planet> = [Planet.Mercury, Planet.Venus]
assert_equal(Planet.Venus, l2[1])
enddef
END
v9.CheckSourceSuccess(lines)
# Try using an enum as a value
lines =<< trim END
vim9script
enum Fruit
Apple,
Orange
endenum
var a = Fruit
END
v9.CheckSourceFailure(lines, 'E1421: Enum "Fruit" cannot be used as a value', 6)
enddef
" Test for type() and typename() of an enum
def Test_enum_type()
var lines =<< trim END
vim9script
enum Fruit
Apple,
Orange
endenum
assert_equal('enum<Fruit>', typename(Fruit))
assert_equal('enum<Fruit>', typename(Fruit.Apple))
assert_equal(v:t_enum, type(Fruit))
assert_equal(v:t_enumvalue, type(Fruit.Apple))
assert_equal(15, type(Fruit))
assert_equal(16, type(Fruit.Apple))
END
v9.CheckSourceSuccess(lines)
# Assign an enum to a variable with any type
lines =<< trim END
vim9script
enum Fruit
Apple,
Orange
endenum
var a = Fruit.Apple
var b: any = Fruit.Orange
assert_equal('enum<Fruit>', typename(a))
assert_equal('enum<Fruit>', typename(b))
END
v9.CheckSourceSuccess(lines)
enddef
" Try modifying an enum or an enum item
def Test_enum_modify()
# Try assigning an unsupported value to an enum
var lines =<< trim END
vim9script
enum Foo
apple
endenum
var a: Foo = 30
END
v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected enum<Foo> but got number', 5)
# Try assigning an unsupported value to an enum in a function
lines =<< trim END
vim9script
enum Foo
apple
endenum
def Fn()
var a: Foo = 30
enddef
defcompile
END
v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected enum<Foo> but got number', 1)
# Try assigning a number to an enum
lines =<< trim END
vim9script
enum Foo
apple,
orange
endenum
Foo = 10
END
v9.CheckSourceFailure(lines, 'E1421: Enum "Foo" cannot be used as a value', 6)
# Try assigning a number to an enum in a function
lines =<< trim END
vim9script
enum Foo
apple
endenum
def Fn()
Foo = 10
enddef
defcompile
END
v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected enum<Foo> but got number', 1)
# Try assigning a number to an enum value
lines =<< trim END
vim9script
enum Foo
apple
endenum
Foo.apple = 20
END
v9.CheckSourceFailure(lines, 'E1423: Enum value "Foo.apple" cannot be modified', 5)
# Try assigning a number to an enum value in a function
lines =<< trim END
vim9script
enum Foo
apple
endenum
def Fn()
Foo.apple = 20
enddef
defcompile
END
v9.CheckSourceFailure(lines, 'E1423: Enum value "Foo.apple" cannot be modified', 1)
# Try assigning one enum to another
lines =<< trim END
vim9script
enum Foo
endenum
enum Bar
endenum
Foo = Bar
END
v9.CheckSourceFailure(lines, 'E1421: Enum "Bar" cannot be used as a value', 6)
# Try assigning one enum to another in a function
lines =<< trim END
vim9script
enum Foo
endenum
enum Bar
endenum
def Fn()
Foo = Bar
enddef
defcompile
END
v9.CheckSourceFailure(lines, 'E1421: Enum "Bar" cannot be used as a value', 1)
# Try assigning one enum item to another enum item
lines =<< trim END
vim9script
enum Foo
Apple
endenum
enum Bar
Orange
endenum
Foo.Apple = Bar.Orange
END
v9.CheckSourceFailure(lines, 'E1423: Enum value "Foo.Apple" cannot be modified', 8)
# Try assigning one enum item to another enum item in a function
lines =<< trim END
vim9script
enum Foo
Apple
endenum
enum Bar
Orange
endenum
def Fn()
Foo.Apple = Bar.Orange
enddef
defcompile
END
v9.CheckSourceFailure(lines, 'E1423: Enum value "Foo.Apple" cannot be modified', 1)
enddef
" Test for using enum in an expression
def Test_enum_expr()
var lines =<< trim END
vim9script
enum Color
Red, Blue, Green
endenum
var a: number = 1 + Color
END
v9.CheckSourceFailure(lines, 'E1421: Enum "Color" cannot be used as a value', 5)
lines =<< trim END
vim9script
enum Color
Red, Blue, Green
endenum
var a: number = 1 + Color.Red
END
v9.CheckSourceFailure(lines, 'E1424: Using an Enum "Color" as a Number', 5)
lines =<< trim END
vim9script
enum Color
Red, Blue, Green
endenum
var s: string = "abc" .. Color
END
v9.CheckSourceFailure(lines, 'E1421: Enum "Color" cannot be used as a value', 5)
lines =<< trim END
vim9script
enum Color
Red, Blue, Green
endenum
var s: string = "abc" .. Color.Red
END
v9.CheckSourceFailure(lines, 'E1425: Using an Enum "Color" as a String', 5)
enddef
" Using an enum in a lambda function
def Test_enum_lambda()
var lines =<< trim END
vim9script
enum Planet
Mercury,
Venus,
Earth,
endenum
var Fn = (p: Planet): Planet => p
for [idx, v] in items([Planet.Mercury, Planet.Venus, Planet.Earth])
assert_equal(idx, Fn(v).ordinal)
endfor
END
v9.CheckSourceSuccess(lines)
enddef
" Comparison using enums
def Test_enum_compare()
var lines =<< trim END
vim9script
enum Planet
Mercury,
Venus,
Earth,
endenum
enum Fruit
Apple,
Orange
endenum
var p: Planet = Planet.Venus
var f: Fruit = Fruit.Orange
assert_equal(true, p == Planet.Venus)
assert_equal(false, p == Planet.Earth)
assert_equal(false, p == f)
assert_equal(true, Planet.Mercury == Planet.Mercury)
assert_equal(true, Planet.Venus != Planet.Earth)
assert_equal(true, Planet.Mercury != Fruit.Apple)
def Fn1()
var p2: Planet = Planet.Venus
var f2: Fruit = Fruit.Orange
assert_equal(true, p2 == Planet.Venus)
assert_equal(false, p2 == Planet.Earth)
assert_equal(false, p2 == f2)
enddef
Fn1()
# comparison using "is" and "isnot"
assert_equal(true, p is Planet.Venus)
assert_equal(true, p isnot Planet.Earth)
assert_equal(false, p is Fruit.Orange)
assert_equal(true, p isnot Fruit.Orange)
def Fn2(arg: Planet)
assert_equal(true, arg is Planet.Venus)
assert_equal(true, arg isnot Planet.Earth)
assert_equal(false, arg is Fruit.Orange)
assert_equal(true, arg isnot Fruit.Orange)
enddef
Fn2(p)
class A
endclass
var o: A = A.new()
assert_equal(false, p == o)
END
v9.CheckSourceSuccess(lines)
enddef
" Test for using an enum as a default argument to a function
def Test_enum_default_arg()
var lines =<< trim END
vim9script
enum Day
Monday, Tuesday, Wednesday
endenum
def Fn(d: Day = Day.Tuesday): Day
return d
enddef
assert_equal(Day.Tuesday, Fn())
assert_equal(Day.Wednesday, Fn(Day.Wednesday))
END
v9.CheckSourceSuccess(lines)
enddef
" Test for enum garbage collection
func Test_enum_garbagecollect()
let lines =<< trim END
vim9script
enum Car
Honda, Ford, Tesla
endenum
assert_equal(1, Car.Ford.ordinal)
call test_garbagecollect_now()
assert_equal(1, Car.Ford.ordinal)
var c: Car = Car.Tesla
assert_equal(2, c.ordinal)
call test_garbagecollect_now()
assert_equal(2, c.ordinal)
END
call v9.CheckSourceSuccess(lines)
" garbage collection with a variable of type any
let lines =<< trim END
vim9script
enum Car
Honda, Ford, Tesla
endenum
call test_garbagecollect_now()
var c: any = Car.Tesla
call test_garbagecollect_now()
assert_equal(Car.Tesla, c)
END
call v9.CheckSourceSuccess(lines)
" garbage collection with function arguments and return types
let lines =<< trim END
vim9script
enum Car
Honda, Ford, Tesla
endenum
def Fn(a: Car): Car
assert_equal(Car.Ford, a)
return Car.Tesla
enddef
call test_garbagecollect_now()
var b: Car = Car.Ford
call test_garbagecollect_now()
assert_equal(Car.Tesla, Fn(b))
call test_garbagecollect_now()
END
call v9.CheckSourceSuccess(lines)
endfunc
" Test for the enum values class variable
def Test_enum_values()
var lines =<< trim END
vim9script
enum Car
Honda, Ford, Tesla
endenum
var l: list<Car> = Car.values
assert_equal(Car.Ford, l[1])
END
v9.CheckSourceSuccess(lines)
# empty enum
lines =<< trim END
vim9script
enum Car
endenum
assert_equal([], Car.values)
END
v9.CheckSourceSuccess(lines)
# single value
lines =<< trim END
vim9script
enum Car
Honda
endenum
assert_equal([Car.Honda], Car.values)
END
v9.CheckSourceSuccess(lines)
lines =<< trim END
vim9script
enum A
Red,
Blue
static def GetValues(): list<A>
return values
enddef
endenum
assert_equal([A.Red, A.Blue], A.GetValues())
END
v9.CheckSourceSuccess(lines)
# Other class variables in an enum should not be added to 'values'
lines =<< trim END
vim9script
enum LogLevel
Error, Warn
static const x: number = 22
endenum
assert_equal([LogLevel.Error, LogLevel.Warn], LogLevel.values)
END
v9.CheckSourceSuccess(lines)
# Other class variable of enum type should not be added to 'values'
lines =<< trim END
vim9script
enum LogLevel
Error, Warn
static const x: LogLevel = LogLevel.Warn
endenum
assert_equal([LogLevel.Error, LogLevel.Warn], LogLevel.values)
END
v9.CheckSourceSuccess(lines)
enddef
" Test comments in enums
def Test_enum_comments()
var lines =<< trim END
vim9script
enum Car # cars
# before enum
Honda, # honda
# before enum
Ford # ford
endenum
assert_equal(1, Car.Ford.ordinal)
END
v9.CheckSourceSuccess(lines)
lines =<< trim END
vim9script
enum Car # cars
# before enum
Honda(), # honda
# before enum
Ford() # ford
endenum
assert_equal(1, Car.Ford.ordinal)
END
v9.CheckSourceSuccess(lines)
# Test for using an unsupported comment
lines =<< trim END
vim9script
enum Car
Honda,
Ford,
#{
endenum
defcompile
END
v9.CheckSourceFailure(lines, 'E1170: Cannot use #{ to start a comment', 4)
enddef
" Test trailing whitespace after enum values
def Test_enum_whitespace()
var lines =<< trim END
vim9script
enum Car
Honda,
Ford
endenum
defcompile
END
v9.CheckSourceSuccess(lines)
lines =<< trim END
vim9script
enum Car
Honda(),
Ford()
endenum
defcompile
END
v9.CheckSourceSuccess(lines)
enddef
" Test string() with enums
def Test_enum_string()
var lines =<< trim END
vim9script
enum Car
Honda,
Ford
endenum
assert_equal("enum Car", string(Car))
assert_equal("enum Car.Honda {name: 'Honda', ordinal: 0}", string(Car.Honda))
END
v9.CheckSourceSuccess(lines)
# customized string function
lines =<< trim END
vim9script
enum Dir
North,
South
def string(): string
return $'Dir.{this.name}'
enddef
endenum
assert_equal('Dir.North', string(Dir.North))
assert_equal('Dir.South', string(Dir.South))
END
v9.CheckSourceSuccess(lines)
enddef
" Test for importing an enum
def Test_enum_import()
var lines =<< trim END
vim9script
export enum Star
Gemini,
Orion,
Pisces
endenum
END
writefile(lines, 'Xenumexport.vim', 'D')
lines =<< trim END
vim9script
import './Xenumexport.vim' as mod
var s1: mod.Star = mod.Star.Orion
assert_equal(true, s1 == mod.Star.Orion)
assert_equal(2, mod.Star.Pisces.ordinal)
var l1: list<mod.Star> = mod.Star.values
assert_equal("enum Star.Orion {name: 'Orion', ordinal: 1}", string(l1[1]))
assert_equal(s1, l1[1])
def Fn()
var s2: mod.Star = mod.Star.Orion
assert_equal(true, s2 == mod.Star.Orion)
assert_equal(2, mod.Star.Pisces.ordinal)
var l2: list<mod.Star> = mod.Star.values
assert_equal("enum Star.Orion {name: 'Orion', ordinal: 1}", string(l2[1]))
assert_equal(s2, l2[1])
enddef
Fn()
END
v9.CheckScriptSuccess(lines)
enddef
" Test for using test_refcount() with enum
def Test_enum_refcount()
var lines =<< trim END
vim9script
enum Foo
endenum
assert_equal(1, test_refcount(Foo))
enum Star
Gemini,
Orion
endenum
assert_equal(3, test_refcount(Star))
assert_equal(2, test_refcount(Star.Gemini))
assert_equal(2, test_refcount(Star.Orion))
var s: Star
assert_equal(3, test_refcount(Star))
assert_equal(-1, test_refcount(s))
s = Star.Orion
assert_equal(3, test_refcount(Star))
assert_equal(3, test_refcount(s))
assert_equal(2, test_refcount(Star.Gemini))
var t = s
assert_equal(3, test_refcount(Star))
assert_equal(4, test_refcount(s))
assert_equal(4, test_refcount(Star.Orion))
END
v9.CheckSourceSuccess(lines)
enddef
" Test for defining an enum with additional object variables and methods
def Test_enum_enhanced()
var lines =<< trim END
vim9script
enum Vehicle
car(4, 5, 400),
bus(6, 50, 800),
bicycle(2, 1, 0)
final tires: number
final passengers: number
final carbonPerKilometer: number
def new(t: number, p: number, cpk: number)
this.tires = t
this.passengers = p
this.carbonPerKilometer = cpk
enddef
def CarbonFootprint(): float
return round(this.carbonPerKilometer / this.passengers)
enddef
def IsTwoWheeled(): bool
return this == Vehicle.bicycle
enddef
def CompareTo(other: Vehicle): float
return this.CarbonFootprint() - other.CarbonFootprint()
enddef
endenum
var v: Vehicle = Vehicle.bus
assert_equal([6, 50, 800], [v.tires, v.passengers, v.carbonPerKilometer])
assert_equal(true, Vehicle.bicycle.IsTwoWheeled())
assert_equal(false, Vehicle.car.IsTwoWheeled())
assert_equal(16.0, Vehicle.bus.CarbonFootprint())
END
v9.CheckSourceSuccess(lines)
enddef
" Test for the enum value 'name' variable
def Test_enum_name()
# Check the names of enum values
var lines =<< trim END
vim9script
enum Planet
Mercury,
Venus,
Earth
endenum
assert_equal('Mercury', Planet.Mercury.name)
assert_equal('Venus', Planet.Venus.name)
assert_equal('Earth', Planet.Earth.name)
assert_equal('string', typename(Planet.Earth.name))
END
v9.CheckSourceSuccess(lines)
# Check the name of enum items in the constructor
lines =<< trim END
vim9script
enum Planet
Mercury("Mercury"),
Venus("Venus"),
Earth("Earth")
def new(s: string)
assert_equal(s, this.name)
enddef
endenum
defcompile
END
v9.CheckSourceSuccess(lines)
# Try assigning to the name of an enum
lines =<< trim END
vim9script
enum Fruit
Apple
endenum
Fruit.Apple.name = 'foo'
END
v9.CheckSourceFailure(lines, 'E1335: Variable "name" in class "Fruit" is not writable', 5)
# Try assigning to the name of an enum in a function
lines =<< trim END
vim9script
enum Fruit
Apple
endenum
def Fn()
Fruit.Apple.name = 'bar'
enddef
defcompile
END
v9.CheckSourceFailure(lines, 'E1423: Enum value "Fruit.name" cannot be modified', 1)
# Try to overwrite an enum value name in the enum constructor
lines =<< trim END
vim9script
enum Planet
Mercury,
Venus
def new()
this.name = 'foo'
enddef
endenum
END
v9.CheckSourceFailure(lines, 'E1427: Enum "Planet" name cannot be modified', 1)
# Try to declare an object variable named 'name'
lines =<< trim END
vim9script
enum Planet
Mercury
var name: string
endenum
END
v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: name', 4)
enddef
" Test for the enum value 'ordinal' variable
def Test_enum_ordinal()
# Check the ordinal values of enum items
var lines =<< trim END
vim9script
enum Planet
Mercury,
Venus,
Earth
endenum
assert_equal(0, Planet.Mercury.ordinal)
assert_equal(1, Planet.Venus.ordinal)
assert_equal(2, Planet.Earth.ordinal)
assert_equal('number', typename(Planet.Earth.ordinal))
END
v9.CheckSourceSuccess(lines)
# Check the ordinal value of enum items in the constructor
lines =<< trim END
vim9script
enum Planet
Mercury(0),
Venus(1),
Earth(2)
def new(v: number)
assert_equal(v, this.ordinal)
enddef
endenum
defcompile
END
v9.CheckSourceSuccess(lines)
# Try assigning to the ordinal value of an enum
lines =<< trim END
vim9script
enum Fruit
Apple
endenum
Fruit.Apple.ordinal = 20
END
v9.CheckSourceFailure(lines, 'E1335: Variable "ordinal" in class "Fruit" is not writable', 5)
# Try assigning to the ordinal value of an enum in a function
lines =<< trim END
vim9script
enum Fruit
Apple
endenum
def Fn()
Fruit.Apple.ordinal = 20
enddef
defcompile
END
v9.CheckSourceFailure(lines, 'E1423: Enum value "Fruit.ordinal" cannot be modified', 1)
# Try to overwrite an enum value ordinal in the enum constructor
lines =<< trim END
vim9script
enum Planet
Mercury,
Venus
def new()
this.ordinal = 20
enddef
endenum
END
v9.CheckSourceFailure(lines, 'E1426: Enum "Planet" ordinal value cannot be modified', 1)
# Try to declare an object variable named 'ordinal'
lines =<< trim END
vim9script
enum Planet
Mercury
var ordinal: number
endenum
END
v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: ordinal', 4)
enddef
" Test for trying to create a new enum object using the constructor
def Test_enum_invoke_constructor()
var lines =<< trim END
vim9script
enum Foo
endenum
var f: Foo = Foo.new()
END
v9.CheckSourceFailure(lines, 'E1325: Method "new" not found in class "Foo"', 4)
lines =<< trim END
vim9script
enum Fruit
Apple,
Orange
endenum
var f: Fruit = Fruit.new()
END
v9.CheckSourceFailure(lines, 'E1325: Method "new" not found in class "Fruit"', 6)
lines =<< trim END
vim9script
enum Fruit
Apple,
Orange
def newFruit()
enddef
endenum
var f: Fruit = Fruit.newFruit()
END
v9.CheckSourceFailure(lines, 'E1325: Method "newFruit" not found in class "Fruit"', 8)
lines =<< trim END
vim9script
enum Fruit
Apple,
Orange
endenum
def Fn()
var f: Fruit = Fruit.new()
enddef
Fn()
END
v9.CheckSourceFailure(lines, 'E1325: Method "new" not found in class "Fruit"', 1)
# error in the enum constructor
lines =<< trim END
vim9script
enum Planet
earth
def new()
x = 123
enddef
endenum
END
v9.CheckSourceFailureList(lines, ['E1100:', 'E1100:'], 1)
enddef
" Test for checking "this" in an enum constructor
def Test_enum_this_in_constructor()
var lines =<< trim END
vim9script
enum A
Red("enum A.Red {name: 'Red', ordinal: 0}"),
Blue("enum A.Blue {name: 'Blue', ordinal: 1}"),
Green("enum A.Green {name: 'Green', ordinal: 2}")
def new(s: string)
assert_equal(s, string(this))
enddef
endenum
defcompile
END
v9.CheckSourceSuccess(lines)
enddef
" Test for using member variables in an enum object
def Test_enum_object_variable()
var lines =<< trim END
vim9script
enum Planet
Jupiter(95),
Saturn(146)
var moons: number
endenum
assert_equal(95, Planet.Jupiter.moons)
assert_equal(146, Planet.Saturn.moons)
END
v9.CheckSourceSuccess(lines)
# Use a final object variable
lines =<< trim END
vim9script
enum Planet
Jupiter(95),
Saturn(146)
final moons: number
def new(n: number)
this.moons = n
enddef
endenum
assert_equal(95, Planet.Jupiter.moons)
assert_equal(146, Planet.Saturn.moons)
END
v9.CheckSourceSuccess(lines)
# Use a const object variable
lines =<< trim END
vim9script
enum Planet
Mars(false),
Jupiter(true)
const has_ring: bool
def new(r: bool)
this.has_ring = r
enddef
endenum
assert_equal(false, Planet.Mars.has_ring)
assert_equal(true, Planet.Jupiter.has_ring)
END
v9.CheckSourceSuccess(lines)
# Use a regular object variable
lines =<< trim END
vim9script
enum Fruit
Apple,
Orange
final farm: string = 'SunValley'
endenum
assert_equal('SunValley', Fruit.Apple.farm)
assert_equal('SunValley', Fruit.Apple.farm)
END
v9.CheckSourceSuccess(lines)
# Invoke the default constructor with an object variable
lines =<< trim END
vim9script
enum Fruit
Apple('foo'),
Orange('bar')
final t: string
endenum
assert_equal('foo', Fruit.Apple.t)
assert_equal('bar', Fruit.Orange.t)
END
v9.CheckSourceSuccess(lines)
# Invoke the default constructor with an argument but without the object
# variable
lines =<< trim END
vim9script
enum Fruit
Apple,
Orange('bar')
endenum
defcompile
END
v9.CheckSourceFailure(lines, 'E118: Too many arguments for function: new', 5)
# Define a default constructor with an argument, but don't pass it in when
# defining the enum value
lines =<< trim END
vim9script
enum Fruit
Apple(5),
Orange
def new(t: number)
enddef
endenum
defcompile
END
v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: new', 8)
enddef
" Test for using a custom constructor with an enum
def Test_enum_custom_constructor()
# space before "("
var lines =<< trim END
vim9script
enum Fruit
Apple(10),
Orange (20)
def new(t: number)
enddef
endenum
defcompile
END
v9.CheckSourceFailure(lines, "E1068: No white space allowed before '(': Orange (20)", 4)
# no closing ")"
lines =<< trim END
vim9script
enum Fruit
Apple(10),
Orange (20
def new(t: number)
enddef
endenum
defcompile
END
v9.CheckSourceFailure(lines, "E1068: No white space allowed before '(': Orange (20", 4)
# Specify constructor arguments split across multiple lines
lines =<< trim END
vim9script
enum Fruit
Apple(10,
'foo'), Orange(20,
'bar'),
Pear(30,
'baz'), Mango(40,
'qux')
final n: number
final s: string
def new(t: number, str: string)
this.n = t
this.s = str
enddef
endenum
defcompile
assert_equal([10, 'foo'], [Fruit.Apple.n, Fruit.Apple.s])
assert_equal([20, 'bar'], [Fruit.Orange.n, Fruit.Orange.s])
assert_equal([30, 'baz'], [Fruit.Pear.n, Fruit.Pear.s])
assert_equal([40, 'qux'], [Fruit.Mango.n, Fruit.Mango.s])
END
v9.CheckSourceSuccess(lines)
# specify multiple enums with constructor arguments in a single line
lines =<< trim END
vim9script
enum Fruit
Apple(10, 'foo'), Orange(20, 'bar'), Pear(30, 'baz'), Mango(40, 'qux')
const n: number
const s: string
endenum
defcompile
assert_equal([10, 'foo'], [Fruit.Apple.n, Fruit.Apple.s])
assert_equal([20, 'bar'], [Fruit.Orange.n, Fruit.Orange.s])
assert_equal([30, 'baz'], [Fruit.Pear.n, Fruit.Pear.s])
assert_equal([40, 'qux'], [Fruit.Mango.n, Fruit.Mango.s])
END
v9.CheckSourceSuccess(lines)
enddef
" Test for using class variables in an enum class
def Test_enum_class_variable()
var lines =<< trim END
vim9script
enum Fruit
Apple,
Orange
static var farm: string = 'SunValley'
endenum
assert_equal('SunValley', Fruit.farm)
END
v9.CheckSourceSuccess(lines)
enddef
" Test for converting a string to an enum value
def Test_enum_eval()
var lines =<< trim END
vim9script
enum Color
Red,
Blue
endenum
var e = eval('Color.Blue')
assert_equal(Color.Blue, e)
assert_equal(1, e.ordinal)
assert_fails("eval('Color.Green')", 'E1422: Enum value "Green" not found in enum "Color"')
assert_fails("var x = eval('Color')", 'E1421: Enum "Color" cannot be used as a value')
END
v9.CheckSourceSuccess(lines)
enddef
" Test for using "values" in an enum class variable
def Test_use_enum_values_in_class_variable()
var lines =<< trim END
vim9script
enum Dir
North, South
static const dirs: list<Dir> = Dir.values
endenum
assert_equal([Dir.North, Dir.South], Dir.dirs)
END
v9.CheckSourceSuccess(lines)
enddef
" Test for using lambda block in enums
def Test_lambda_block_in_enum()
# This used to crash Vim
var lines =<< trim END
vim9script
enum IdEnum1
ID1
const Id: func(number): number = (num: number): number => {
# Return a ID
return num / 2
}
endenum
assert_equal(5, IdEnum1.ID1.Id(10))
END
v9.CheckScriptSuccess(lines)
# This used to crash Vim
lines =<< trim END
vim9script
enum IdEnum2
ID1
static const Id: func(number): number = (num: number): number => {
# Return a ID
return num + 2
}
endenum
assert_equal(12, IdEnum2.Id(10))
END
v9.CheckScriptSuccess(lines)
enddef
" Echo an enum
def Test_enum_echo()
var lines =<< trim END
vim9script
enum Demo
one('tahi'),
two('rua'),
three('toru')
var alias: string
endenum
assert_equal('enum Demo.one {name: one, ordinal: 0, alias: tahi}', execute('echo Demo.one')->split("\n")[0])
END
v9.CheckScriptSuccess(lines)
enddef
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker