@ -9,45 +9,45 @@ const Ananab = -1
@@ -9,45 +9,45 @@ const Ananab = -1
@testset " EnumX " begin
# Basic
@enumx Fruit Apple Banana
# Basic
@enumx Fruit Apple Banana
@test Fruit isa Module
@test Set ( names ( Fruit ) ) == Set ( [ :Fruit ] )
@test_broken Set ( names ( Fruit ; all = true ) ) == Set ( [ :Fruit , :Apple , :Banana , :T ] )
@test issubset ( Set ( [ :Fruit , :Apple , :Banana , :T ] ) , Set ( names ( Fruit ; all = true ) ) )
@test Fruit . T <: EnumX . Enum { Int32 } <: Base . Enum { Int32 }
@test ! @isdefined ( Apple )
@test ! @isdefined ( Banana )
@test Fruit isa Module
@test Set ( names ( Fruit ) ) == Set ( [ :Fruit ] )
@test_broken Set ( names ( Fruit ; all = true ) ) == Set ( [ :Fruit , :Apple , :Banana , :T ] )
@test issubset ( Set ( [ :Fruit , :Apple , :Banana , :T ] ) , Set ( names ( Fruit ; all = true ) ) )
@test Fruit . T <: EnumX . Enum { Int32 } <: Base . Enum { Int32 }
@test ! @isdefined ( Apple )
@test ! @isdefined ( Banana )
@test Fruit . Apple isa EnumX . Enum
@test Fruit . Apple isa Base . Enum
@test Fruit . Banana isa EnumX . Enum
@test Fruit . Banana isa Base . Enum
@test Fruit . Apple isa EnumX . Enum
@test Fruit . Apple isa Base . Enum
@test Fruit . Banana isa EnumX . Enum
@test Fruit . Banana isa Base . Enum
@test instances ( Fruit . T ) === ( Fruit . Apple , Fruit . Banana )
@test Base . Enums . namemap ( Fruit . T ) == Dict { Int32 , Symbol } ( 0 => :Apple , 1 => :Banana )
@test Base . Enums . basetype ( Fruit . T ) == Int32
@test instances ( Fruit . T ) === ( Fruit . Apple , Fruit . Banana )
@test Base . Enums . namemap ( Fruit . T ) == Dict { Int32 , Symbol } ( 0 => :Apple , 1 => :Banana )
@test Base . Enums . basetype ( Fruit . T ) == Int32
@test Symbol ( Fruit . Apple ) === :Apple
@test Symbol ( Fruit . Banana ) === :Banana
@test Symbol ( Fruit . Apple ) === :Apple
@test Symbol ( Fruit . Banana ) === :Banana
@test Integer ( Fruit . Apple ) === Int32 ( 0 )
@test Int ( Fruit . Apple ) === Int ( 0 )
@test Integer ( Fruit . Banana ) === Int32 ( 1 )
@test Int ( Fruit . Banana ) === Int ( 1 )
@test Integer ( Fruit . Apple ) === Int32 ( 0 )
@test Int ( Fruit . Apple ) === Int ( 0 )
@test Integer ( Fruit . Banana ) === Int32 ( 1 )
@test Int ( Fruit . Banana ) === Int ( 1 )
@test Fruit . Apple === Fruit . Apple
@test Fruit . Banana === Fruit . Banana
@test Fruit . Apple === Fruit . Apple
@test Fruit . Banana === Fruit . Banana
@test Fruit . T ( Int32 ( 0 ) ) === Fruit . T ( 0 ) === Fruit . Apple
@test Fruit . T ( Int32 ( 1 ) ) === Fruit . T ( 1 ) === Fruit . Banana
@test_throws ArgumentError ( " invalid value for Enum Fruit: 123. " ) Fruit . T ( Int32 ( 123 ) )
@test_throws ArgumentError ( " invalid value for Enum Fruit: 123. " ) Fruit . T ( 123 )
@test Fruit . T ( Int32 ( 0 ) ) === Fruit . T ( 0 ) === Fruit . Apple
@test Fruit . T ( Int32 ( 1 ) ) === Fruit . T ( 1 ) === Fruit . Banana
@test_throws ArgumentError ( " invalid value for Enum Fruit: 123. " ) Fruit . T ( Int32 ( 123 ) )
@test_throws ArgumentError ( " invalid value for Enum Fruit: 123. " ) Fruit . T ( 123 )
@test Fruit . Apple < Fruit . Banana
@test Fruit . Apple < Fruit . Banana
let io = IOBuffer ( )
let io = IOBuffer ( )
write ( io , Fruit . Apple )
seekstart ( io )
@test read ( io , Fruit . T ) === Fruit . Apple
@ -59,9 +59,9 @@ let io = IOBuffer()
@@ -59,9 +59,9 @@ let io = IOBuffer()
write ( io , Int32 ( 123 ) )
seekstart ( io )
@test_throws ArgumentError ( " invalid value for Enum Fruit: 123. " ) read ( io , Fruit . T )
end
end
let io = IOBuffer ( )
let io = IOBuffer ( )
show ( io , " text/plain " , Fruit . T )
str = String ( take! ( io ) )
@test str == " Enum type Fruit.T <: Enum{Int32} with 2 instances: \n Fruit.Apple = 0 \n Fruit.Banana = 1 "
@ -77,20 +77,20 @@ let io = IOBuffer()
@@ -77,20 +77,20 @@ let io = IOBuffer()
show ( io , " text/plain " , EnumX . Enum { Int32 } )
str = String ( take! ( io ) )
@test str == " EnumX.Enum{Int32} "
end
end
# Base type specification
@enumx Fruit8 :: Int8 Apple
@test Fruit8 . T <: EnumX . Enum { Int8 } <: Base . Enum { Int8 }
@test Base . Enums . basetype ( Fruit8 . T ) === Int8
@test Integer ( Fruit8 . Apple ) === Int8 ( 0 )
# Base type specification
@enumx Fruit8 :: Int8 Apple
@test Fruit8 . T <: EnumX . Enum { Int8 } <: Base . Enum { Int8 }
@test Base . Enums . basetype ( Fruit8 . T ) === Int8
@test Integer ( Fruit8 . Apple ) === Int8 ( 0 )
@enumx FruitU8 :: UInt8 Apple Banana # no overflow even if first is typemin(T)
@test Base . Enums . basetype ( FruitU8 . T ) === UInt8
@test FruitU8 . Apple === FruitU8 . T ( 0 )
@enumx FruitU8 :: UInt8 Apple Banana # no overflow even if first is typemin(T)
@test Base . Enums . basetype ( FruitU8 . T ) === UInt8
@test FruitU8 . Apple === FruitU8 . T ( 0 )
let io = IOBuffer ( )
let io = IOBuffer ( )
show ( io , " text/plain " , FruitU8 . T )
str = String ( take! ( io ) )
@test str == " Enum type FruitU8.T <: Enum{UInt8} with 2 instances: \n FruitU8.Apple = 0x00 \n FruitU8.Banana = 0x01 "
@ -100,111 +100,111 @@ let io = IOBuffer()
@@ -100,111 +100,111 @@ let io = IOBuffer()
show ( io , " text/plain " , FruitU8 . Banana )
str = String ( take! ( io ) )
@test str == " FruitU8.Banana = 0x01 "
end
end
@enumx Fruit16 :: T16 Apple
@test Fruit16 . T <: EnumX . Enum { Int16 } <: Base . Enum { Int16 }
@test Base . Enums . basetype ( Fruit16 . T ) === Int16
@test Integer ( Fruit16 . Apple ) === Int16 ( 0 )
@enumx Fruit16 :: T16 Apple
@test Fruit16 . T <: EnumX . Enum { Int16 } <: Base . Enum { Int16 }
@test Base . Enums . basetype ( Fruit16 . T ) === Int16
@test Integer ( Fruit16 . Apple ) === Int16 ( 0 )
@enumx Fruit64 :: getInt64 ( ) Apple
@test Fruit64 . T <: EnumX . Enum { Int64 } <: Base . Enum { Int64 }
@test Base . Enums . basetype ( Fruit64 . T ) === Int64
@test Integer ( Fruit64 . Apple ) == Int64 ( 0 )
@enumx Fruit64 :: getInt64 ( ) Apple
@test Fruit64 . T <: EnumX . Enum { Int64 } <: Base . Enum { Int64 }
@test Base . Enums . basetype ( Fruit64 . T ) === Int64
@test Integer ( Fruit64 . Apple ) == Int64 ( 0 )
try
try
@macroexpand @enumx ( Fr + uit ) Apple
error ( )
catch err
catch err
err isa LoadError && ( err = err . error )
@test err isa ArgumentError
@test err . msg == " invalid EnumX.@enumx type specification: Fr + uit. "
end
end
# Block syntax
@enumx FruitBlock begin
# Block syntax
@enumx FruitBlock begin
Apple
Banana
end
@test FruitBlock . T <: EnumX . Enum { Int32 } <: Base . Enum { Int32 }
@test FruitBlock . Apple === FruitBlock . T ( 0 )
@test FruitBlock . Banana === FruitBlock . T ( 1 )
end
@test FruitBlock . T <: EnumX . Enum { Int32 } <: Base . Enum { Int32 }
@test FruitBlock . Apple === FruitBlock . T ( 0 )
@test FruitBlock . Banana === FruitBlock . T ( 1 )
@enumx FruitBlock8 :: Int8 begin
@enumx FruitBlock8 :: Int8 begin
Apple
Banana
end
@test FruitBlock8 . T <: EnumX . Enum { Int8 } <: Base . Enum { Int8 }
@test FruitBlock8 . Apple === FruitBlock8 . T ( 0 )
@test FruitBlock8 . Banana === FruitBlock8 . T ( 1 )
end
@test FruitBlock8 . T <: EnumX . Enum { Int8 } <: Base . Enum { Int8 }
@test FruitBlock8 . Apple === FruitBlock8 . T ( 0 )
@test FruitBlock8 . Banana === FruitBlock8 . T ( 1 )
# Custom values
@enumx FruitValues Apple = 1 Banana = ( 1 + 2 ) Orange
@test FruitValues . Apple === FruitValues . T ( 1 )
@test FruitValues . Banana === FruitValues . T ( 3 )
@test FruitValues . Orange === FruitValues . T ( 4 )
# Custom values
@enumx FruitValues Apple = 1 Banana = ( 1 + 2 ) Orange
@test FruitValues . Apple === FruitValues . T ( 1 )
@test FruitValues . Banana === FruitValues . T ( 3 )
@test FruitValues . Orange === FruitValues . T ( 4 )
@enumx FruitValues8 :: Int8 Apple = - 1 Banana = ( 1 + 2 ) Orange
@test FruitValues8 . Apple === FruitValues8 . T ( - 1 )
@test FruitValues8 . Banana === FruitValues8 . T ( 3 )
@test FruitValues8 . Orange === FruitValues8 . T ( 4 )
@enumx FruitValues8 :: Int8 Apple = - 1 Banana = ( 1 + 2 ) Orange
@test FruitValues8 . Apple === FruitValues8 . T ( - 1 )
@test FruitValues8 . Banana === FruitValues8 . T ( 3 )
@test FruitValues8 . Orange === FruitValues8 . T ( 4 )
@enumx FruitValuesBlock begin
@enumx FruitValuesBlock begin
Apple = sum ( ( 1 , 2 , 3 ) )
Banana
end
@test FruitValuesBlock . Apple === FruitValuesBlock . T ( 6 )
@test FruitValuesBlock . Banana === FruitValuesBlock . T ( 7 )
end
@test FruitValuesBlock . Apple === FruitValuesBlock . T ( 6 )
@test FruitValuesBlock . Banana === FruitValuesBlock . T ( 7 )
try
@macroexpand @enumx Fruit :: Int8 Apple = typemax ( Int8 ) Banana
try
@macroexpand @enumx Fruit :: Int8 Apple = typemax ( Int8 ) Banana
error ( )
catch err
catch err
err isa LoadError && ( err = err . error )
@test err isa ArgumentError
@test err . msg == " value overflow for Enum Fruit: Fruit.Banana = -128. "
end
try
@macroexpand @enumx Fruit :: Int8 Apple = " apple "
end
try
@macroexpand @enumx Fruit :: Int8 Apple = " apple "
error ( )
catch err
catch err
err isa LoadError && ( err = err . error )
@test err isa ArgumentError
@test err . msg == " invalid value for Enum Fruit{Int8}: Fruit.Apple = \" apple \" . "
end
try
@macroexpand @enumx Fruit :: Int8 Apple = 128
end
try
@macroexpand @enumx Fruit :: Int8 Apple = 128
error ( )
catch err
catch err
err isa LoadError && ( err = err . error )
@test err isa ArgumentError
@test err . msg == " invalid value for Enum Fruit{Int8}: Fruit.Apple = 128. "
end
try
end
try
@macroexpand @enumx Fruit :: Int8 Apple ( )
error ( )
catch err
catch err
err isa LoadError && ( err = err . error )
@test err isa ArgumentError
@test err . msg == " invalid EnumX.@enumx entry: Apple() "
end
try
end
try
@macroexpand @enumx Fruit Apple Apple
error ( )
catch err
catch err
err isa LoadError && ( err = err . error )
@test err isa ArgumentError
@test err . msg == " duplicate name for Enum Fruit: Fruit.Apple = 1, name already used for Fruit.Apple = 0. "
end
end
# Duplicate values
@enumx FruitDup Apple = 0 Banana = 0
@test FruitDup . Apple === FruitDup . Banana === FruitDup . T ( 0 )
# Duplicate values
@enumx FruitDup Apple = 0 Banana = 0
@test FruitDup . Apple === FruitDup . Banana === FruitDup . T ( 0 )
let io = IOBuffer ( )
let io = IOBuffer ( )
show ( io , " text/plain " , FruitDup . T )
str = String ( take! ( io ) )
@test str == " Enum type FruitDup.T <: Enum{Int32} with 2 instances: \n FruitDup.Apple = 0 \n FruitDup.Banana = 0 "
@ -214,70 +214,70 @@ let io = IOBuffer()
@@ -214,70 +214,70 @@ let io = IOBuffer()
show ( io , " text/plain " , FruitDup . Banana )
str = String ( take! ( io ) )
@test str == " FruitDup.Apple = FruitDup.Banana = 0 "
end
end
# Initialize with previous instance name
@enumx FruitPrev Elppa Banana = Elppa Orange = Ananab
@test FruitPrev . Elppa === FruitPrev . Banana === FruitPrev . T ( 0 )
@test FruitPrev . Orange === FruitPrev . T ( - 1 )
# Initialize with previous instance name
@enumx FruitPrev Elppa Banana = Elppa Orange = Ananab
@test FruitPrev . Elppa === FruitPrev . Banana === FruitPrev . T ( 0 )
@test FruitPrev . Orange === FruitPrev . T ( - 1 )
# Custom typename
@enumx T = Typ FruitT Apple Banana
@test isdefined ( FruitT , :Typ )
@test ! isdefined ( FruitT , :T )
@test FruitT . Typ <: EnumX . Enum
@test FruitT . Apple === FruitT . Typ ( 0 )
# Custom typename
@enumx T = Typ FruitT Apple Banana
@test isdefined ( FruitT , :Typ )
@test ! isdefined ( FruitT , :T )
@test FruitT . Typ <: EnumX . Enum
@test FruitT . Apple === FruitT . Typ ( 0 )
let io = IOBuffer ( )
let io = IOBuffer ( )
show ( io , " text/plain " , FruitT . Typ )
str = String ( take! ( io ) )
@test str == " Enum type FruitT.Typ <: Enum{Int32} with 2 instances: \n FruitT.Apple = 0 \n FruitT.Banana = 1 "
end
end
# Custom typename with quoted symbol
@enumx T = :Typ FruitST Apple Banana
@test isdefined ( FruitST , :Typ )
@test ! isdefined ( FruitST , :T )
@test FruitST . Typ <: EnumX . Enum
@test FruitST . Apple === FruitST . Typ ( 0 )
# Custom typename with quoted symbol
@enumx T = :Typ FruitST Apple Banana
@test isdefined ( FruitST , :Typ )
@test ! isdefined ( FruitST , :T )
@test FruitST . Typ <: EnumX . Enum
@test FruitST . Apple === FruitST . Typ ( 0 )
try
@macroexpand @enumx T = Apple Fruit Apple
try
@macroexpand @enumx T = Apple Fruit Apple
error ( )
catch err
catch err
err isa LoadError && ( err = err . error )
@test err isa ArgumentError
@test err . msg == " instance name Fruit.Apple reserved for the Enum typename. "
end
end
# Empty enum
@enumx FruitEmpty
@test instances ( FruitEmpty . T ) == ( )
let io = IOBuffer ( )
# Empty enum
@enumx FruitEmpty
@test instances ( FruitEmpty . T ) == ( )
let io = IOBuffer ( )
show ( io , " text/plain " , FruitEmpty . T )
str = String ( take! ( io ) )
@test str == " Enum type FruitEmpty.T <: Enum{Int32} with 0 instances "
end
end
@enumx T = Typ FruitEmptyT
@test instances ( FruitEmptyT . Typ ) == ( )
@enumx T = Typ FruitEmptyT
@test instances ( FruitEmptyT . Typ ) == ( )
# Showing invalid instances
@enumx Invalid A
let io = IOBuffer ( )
# Showing invalid instances
@enumx Invalid A
let io = IOBuffer ( )
invalid = Base . bitcast ( Invalid . T , Int32 ( 1 ) )
show ( io , " text/plain " , invalid )
str = String ( take! ( io ) )
@test str == " Invalid.#invalid# = 1 "
end
end
# Documented type (module) and instances
begin
# Documented type (module) and instances
begin
"""
Documentation for FruitDoc
"""
@ -294,38 +294,38 @@ begin
@@ -294,38 +294,38 @@ begin
@eval const LINENUMBER = $ ( @__LINE__ )
@eval const FILENAME = $ ( @__FILE__ )
@eval const MODULE = $ ( @__MODULE__ )
end
end
function get_doc_metadata ( mod , s )
function get_doc_metadata ( mod , s )
Base . Docs . meta ( mod ) [ Base . Docs . Binding ( mod , s ) ] . docs [ Union { } ] . data
end
@test FruitDoc . Apple === FruitDoc . T ( 0 )
@test FruitDoc . Banana === FruitDoc . T ( 2 )
@test FruitDoc . Orange === FruitDoc . T ( 0 )
mod_doc = @doc ( FruitDoc )
@test sprint ( show , mod_doc ) == " Documentation for FruitDoc \n "
mod_doc_data = get_doc_metadata ( FruitDoc , :FruitDoc )
@test mod_doc_data [ :linenumber ] == LINENUMBER - 13
@test mod_doc_data [ :path ] == FILENAME
@test mod_doc_data [ :module ] == MODULE
apple_doc = @doc ( FruitDoc . Apple )
@test sprint ( show , apple_doc ) == " Apple documentation. \n "
apple_doc_data = get_doc_metadata ( FruitDoc , :Apple )
@test apple_doc_data [ :linenumber ] == LINENUMBER - 9
@test apple_doc_data [ :path ] == FILENAME
@test apple_doc_data [ :module ] == FruitDoc
banana_doc = @doc ( FruitDoc . Banana )
@test sprint ( show , banana_doc ) == " Banana documentation on multiple lines. \n "
banana_doc_data = get_doc_metadata ( FruitDoc , :Banana )
@test banana_doc_data [ :linenumber ] == LINENUMBER - 7
@test banana_doc_data [ :path ] == FILENAME
@test banana_doc_data [ :module ] == FruitDoc
orange_doc = @doc ( FruitDoc . Orange )
@test startswith ( sprint ( show , orange_doc ) , " No documentation found " )
end
@test FruitDoc . Apple === FruitDoc . T ( 0 )
@test FruitDoc . Banana === FruitDoc . T ( 2 )
@test FruitDoc . Orange === FruitDoc . T ( 0 )
mod_doc = @doc ( FruitDoc )
@test sprint ( show , mod_doc ) == " Documentation for FruitDoc \n "
mod_doc_data = get_doc_metadata ( FruitDoc , :FruitDoc )
@test mod_doc_data [ :linenumber ] == LINENUMBER - 13
@test mod_doc_data [ :path ] == FILENAME
@test mod_doc_data [ :module ] == MODULE
apple_doc = @doc ( FruitDoc . Apple )
@test sprint ( show , apple_doc ) == " Apple documentation. \n "
apple_doc_data = get_doc_metadata ( FruitDoc , :Apple )
@test apple_doc_data [ :linenumber ] == LINENUMBER - 9
@test apple_doc_data [ :path ] == FILENAME
@test apple_doc_data [ :module ] == FruitDoc
banana_doc = @doc ( FruitDoc . Banana )
@test sprint ( show , banana_doc ) == " Banana documentation on multiple lines. \n "
banana_doc_data = get_doc_metadata ( FruitDoc , :Banana )
@test banana_doc_data [ :linenumber ] == LINENUMBER - 7
@test banana_doc_data [ :path ] == FILENAME
@test banana_doc_data [ :module ] == FruitDoc
orange_doc = @doc ( FruitDoc . Orange )
@test startswith ( sprint ( show , orange_doc ) , " No documentation found " )
end # testset