tests: cleanup sum type tests (#6950)
parent
fa126b950a
commit
8e2b7fe3d6
|
@ -38,6 +38,51 @@ fn test_nested_if_smartcast() {
|
|||
}
|
||||
}
|
||||
|
||||
type Bar = string | Test
|
||||
type Xya = int | string
|
||||
|
||||
struct Test {
|
||||
x string
|
||||
xya Xya
|
||||
}
|
||||
|
||||
struct BarWrapper {
|
||||
y Bar
|
||||
}
|
||||
|
||||
fn test_nested_selector_smartcast() {
|
||||
f := BarWrapper{
|
||||
y: Bar(Test{
|
||||
x: 'Hi'
|
||||
xya: Xya(int(5))
|
||||
})
|
||||
}
|
||||
|
||||
if f.y is Test {
|
||||
z := f.y.x
|
||||
assert f.y.x == 'Hi'
|
||||
assert z == 'Hi'
|
||||
if f.y.xya is int {
|
||||
assert f.y.xya == 5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type Inner = int | string
|
||||
struct InnerStruct {
|
||||
x Inner
|
||||
}
|
||||
type Outer = string | InnerStruct
|
||||
|
||||
fn test_nested_if_is() {
|
||||
b := Outer(InnerStruct{Inner(0)})
|
||||
if b is InnerStruct {
|
||||
if b.x is int {
|
||||
assert b.x == 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct MutContainer {
|
||||
mut:
|
||||
abc Alphabet
|
||||
|
@ -122,3 +167,89 @@ fn test_mutability() {
|
|||
println('$cell.u')
|
||||
}
|
||||
}
|
||||
|
||||
type Expr = CallExpr | CTempVarExpr
|
||||
struct ExprWrapper {
|
||||
mut:
|
||||
expr Expr
|
||||
}
|
||||
struct CallExpr {
|
||||
y int
|
||||
x string
|
||||
}
|
||||
|
||||
struct CTempVarExpr {
|
||||
x string
|
||||
}
|
||||
|
||||
fn gen(_ Expr) CTempVarExpr {
|
||||
return CTempVarExpr{}
|
||||
}
|
||||
|
||||
fn test_reassign_from_function_with_parameter_selector() {
|
||||
mut f := ExprWrapper{Expr(CallExpr{})}
|
||||
if f.expr is CallExpr {
|
||||
f.expr = gen(f.expr)
|
||||
}
|
||||
}
|
||||
|
||||
type Node = Expr | string
|
||||
|
||||
fn test_nested_sumtype() {
|
||||
c := Node(Expr(CallExpr{y: 1}))
|
||||
if c is Expr {
|
||||
if c is CallExpr {
|
||||
assert c.y == 1
|
||||
}
|
||||
else {
|
||||
assert false
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert false
|
||||
}
|
||||
}
|
||||
|
||||
type Food = Milk | Eggs
|
||||
|
||||
struct FoodWrapper {
|
||||
mut:
|
||||
food Food
|
||||
}
|
||||
|
||||
struct Milk {
|
||||
mut:
|
||||
name string
|
||||
}
|
||||
|
||||
struct Eggs {
|
||||
mut:
|
||||
name string
|
||||
}
|
||||
|
||||
fn test_if_mut_selector() {
|
||||
mut f := FoodWrapper{Food(Milk{'test'})}
|
||||
if mut f.food is Milk {
|
||||
f.food.name = 'milk'
|
||||
assert f.food.name == 'milk'
|
||||
}
|
||||
}
|
||||
|
||||
struct NodeWrapper {
|
||||
node Node
|
||||
}
|
||||
|
||||
fn test_nested_sumtype_selector() {
|
||||
c := NodeWrapper{Node(Expr(CallExpr{y: 1}))}
|
||||
if c.node is Expr {
|
||||
if c.node is CallExpr {
|
||||
assert c.node.y == 1
|
||||
}
|
||||
else {
|
||||
assert false
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
type Node = Expr | string
|
||||
type Expr = IfExpr | IntegerLiteral
|
||||
|
||||
struct IntegerLiteral {}
|
||||
struct IfExpr {
|
||||
pos int
|
||||
}
|
||||
|
||||
struct NodeWrapper {
|
||||
node Node
|
||||
}
|
||||
|
||||
fn test_nested_sumtype_match_selector() {
|
||||
c := NodeWrapper{Node(Expr(IfExpr{pos: 1}))}
|
||||
match c.node {
|
||||
Expr {
|
||||
match c.node {
|
||||
IfExpr {
|
||||
assert c.node.pos == 1
|
||||
}
|
||||
else {
|
||||
assert false
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn test_nested_sumtype_match() {
|
||||
c := Node(Expr(IfExpr{pos: 1}))
|
||||
match c {
|
||||
Expr {
|
||||
match c {
|
||||
IfExpr {
|
||||
assert c.pos == 1
|
||||
}
|
||||
else {
|
||||
assert false
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Milk {
|
||||
mut:
|
||||
name string
|
||||
}
|
||||
|
||||
struct Eggs {
|
||||
mut:
|
||||
name string
|
||||
}
|
||||
|
||||
type Food = Milk | Eggs
|
||||
|
||||
struct FoodWrapper {
|
||||
mut:
|
||||
food Food
|
||||
}
|
||||
|
||||
fn test_match_mut() {
|
||||
mut f := Food(Milk{'test'})
|
||||
match mut f {
|
||||
Eggs {
|
||||
f.name = 'eggs'
|
||||
assert f.name == 'eggs'
|
||||
}
|
||||
Milk {
|
||||
f.name = 'milk'
|
||||
assert f.name == 'milk'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn test_match_mut_selector() {
|
||||
mut f := FoodWrapper{Food(Milk{'test'})}
|
||||
match mut f.food {
|
||||
Eggs {
|
||||
f.food.name = 'eggs'
|
||||
assert f.food.name == 'eggs'
|
||||
}
|
||||
Milk {
|
||||
f.food.name = 'milk'
|
||||
assert f.food.name == 'milk'
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,7 +10,6 @@ struct StructDecl {
|
|||
pos int
|
||||
}
|
||||
|
||||
|
||||
struct IfExpr {
|
||||
pos int
|
||||
}
|
||||
|
@ -19,49 +18,24 @@ struct IntegerLiteral {
|
|||
val string
|
||||
}
|
||||
|
||||
fn handle(e Expr) string {
|
||||
is_literal := e is IntegerLiteral
|
||||
assert is_literal
|
||||
assert !(e !is IntegerLiteral)
|
||||
if e is IntegerLiteral {
|
||||
println('int')
|
||||
}
|
||||
match e {
|
||||
IntegerLiteral {
|
||||
assert e.val == '12'
|
||||
return 'int'
|
||||
}
|
||||
IfExpr {
|
||||
return 'if'
|
||||
}
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
fn test_expr() {
|
||||
expr := IntegerLiteral{
|
||||
val: '12'
|
||||
}
|
||||
assert handle(expr) == 'int'
|
||||
// assert expr is IntegerLiteral // TODO
|
||||
}
|
||||
|
||||
fn test_assignment_and_push() {
|
||||
mut expr1 := Expr{}
|
||||
mut arr1 := []Expr{}
|
||||
expr := IntegerLiteral{
|
||||
val: '111'
|
||||
}
|
||||
arr1 << expr
|
||||
match arr1[0] {
|
||||
IntegerLiteral {
|
||||
arr1 << arr1[0]
|
||||
// should ref/dereference on assignent be made automatic?
|
||||
// currently it is done for return stmt and fn args
|
||||
expr1 = arr1[0]
|
||||
}
|
||||
else {}
|
||||
}
|
||||
fn test_sum_type_match() {
|
||||
// TODO: Remove these casts
|
||||
assert is_gt_simple('3', int(2))
|
||||
assert !is_gt_simple('3', int(5))
|
||||
assert is_gt_simple('3', f64(1.2))
|
||||
assert !is_gt_simple('3', f64(3.5))
|
||||
assert is_gt_nested('3', int(2))
|
||||
assert !is_gt_nested('3', int(5))
|
||||
assert is_gt_nested('3', f64(1.2))
|
||||
assert !is_gt_nested('3', f64(3.5))
|
||||
assert concat('3', int(2)) == '3(int)2'
|
||||
assert concat('3', int(5)) == '3(int)5'
|
||||
assert concat('3', f64(1.2)) == '3(float)1.2'
|
||||
assert concat('3', f64(3.5)) == '3(float)3.5'
|
||||
assert get_sum('3', int(2)) == 5.0
|
||||
assert get_sum('3', int(5)) == 8.0
|
||||
assert get_sum('3', f64(1.2)) == 4.2
|
||||
assert get_sum('3', f64(3.5)) == 6.5
|
||||
}
|
||||
|
||||
// Test moving structs between master/sub arrays
|
||||
|
@ -105,18 +79,121 @@ fn test_converting_down() {
|
|||
assert res[1].name == 'three'
|
||||
}
|
||||
|
||||
fn test_nested_sumtype() {
|
||||
c := Node(Expr(IfExpr{pos:1}))
|
||||
if c is Expr {
|
||||
if c is IfExpr {
|
||||
assert true
|
||||
|
||||
fn test_assignment_and_push() {
|
||||
mut expr1 := Expr{}
|
||||
mut arr1 := []Expr{}
|
||||
expr := IntegerLiteral{
|
||||
val: '111'
|
||||
}
|
||||
else {
|
||||
assert false
|
||||
arr1 << expr
|
||||
match arr1[0] {
|
||||
IntegerLiteral {
|
||||
arr1 << arr1[0]
|
||||
expr1 = arr1[0]
|
||||
}
|
||||
else {}
|
||||
}
|
||||
}
|
||||
|
||||
fn test_expr() {
|
||||
expr := IntegerLiteral{
|
||||
val: '12'
|
||||
}
|
||||
assert handle(expr) == 'int'
|
||||
// assert expr is IntegerLiteral // TODO
|
||||
}
|
||||
|
||||
struct Outer2 {
|
||||
e Expr
|
||||
}
|
||||
|
||||
fn test_zero_value_init() {
|
||||
// no c compiler error then it's successful
|
||||
_ := Outer2{}
|
||||
}
|
||||
|
||||
type Bar = string | Test
|
||||
type Xyz = int | string
|
||||
|
||||
struct Test {
|
||||
x string
|
||||
xyz Xyz
|
||||
}
|
||||
|
||||
fn test_assignment() {
|
||||
y := 5
|
||||
mut x := Xyz(y)
|
||||
x = 'test'
|
||||
|
||||
if x is string {
|
||||
x2 := x as string
|
||||
assert x2 == 'test'
|
||||
}
|
||||
}
|
||||
|
||||
struct Foo {
|
||||
y Bar
|
||||
}
|
||||
|
||||
fn test_as_cast() {
|
||||
f := Foo{
|
||||
y: Bar('test')
|
||||
}
|
||||
y := f.y as string
|
||||
assert y == 'test'
|
||||
}
|
||||
|
||||
fn test_typeof() {
|
||||
x := Expr(IfExpr{})
|
||||
assert typeof(x) == 'IfExpr'
|
||||
}
|
||||
|
||||
type Food = Milk | Eggs
|
||||
|
||||
struct FoodWrapper {
|
||||
mut:
|
||||
food Food
|
||||
}
|
||||
|
||||
struct Milk {
|
||||
mut:
|
||||
name string
|
||||
}
|
||||
|
||||
struct Eggs {
|
||||
mut:
|
||||
name string
|
||||
}
|
||||
|
||||
fn test_match_aggregate() {
|
||||
f := Food(Milk{'test'})
|
||||
match f {
|
||||
Milk, Eggs {
|
||||
assert f.name == 'test'
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert false
|
||||
}
|
||||
|
||||
fn test_if() {
|
||||
mut f := Food(Milk{'test'})
|
||||
if f is Milk {
|
||||
// only works without smartcast
|
||||
assert f is Milk
|
||||
}
|
||||
}
|
||||
|
||||
fn test_match() {
|
||||
mut f := Food(Milk{'test'})
|
||||
match f {
|
||||
Eggs {
|
||||
// only works without smartcast
|
||||
assert f is Eggs
|
||||
}
|
||||
Milk {
|
||||
// only works without smartcast
|
||||
assert f is Milk
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,15 +235,15 @@ fn test_int_cast_to_sumtype() {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: change definition once types other than any_int and any_float (int, f64, etc) are supported in sumtype
|
||||
type Number = any_int | any_float
|
||||
// TODO: change definition once types other than int and f64 (int, f64, etc) are supported in sumtype
|
||||
type Number = int | f64
|
||||
|
||||
fn is_gt_simple(val string, dst Number) bool {
|
||||
match dst {
|
||||
any_int {
|
||||
int {
|
||||
return val.int() > dst
|
||||
}
|
||||
any_float {
|
||||
f64 {
|
||||
return dst < val.f64()
|
||||
}
|
||||
}
|
||||
|
@ -175,9 +252,9 @@ fn is_gt_simple(val string, dst Number) bool {
|
|||
fn is_gt_nested(val string, dst Number) bool {
|
||||
dst2 := dst
|
||||
match dst {
|
||||
any_int {
|
||||
int {
|
||||
match dst2 {
|
||||
any_int {
|
||||
int {
|
||||
return val.int() > dst
|
||||
}
|
||||
// this branch should never been hit
|
||||
|
@ -186,9 +263,9 @@ fn is_gt_nested(val string, dst Number) bool {
|
|||
}
|
||||
}
|
||||
}
|
||||
any_float {
|
||||
f64 {
|
||||
match dst2 {
|
||||
any_float {
|
||||
f64 {
|
||||
return dst < val.f64()
|
||||
}
|
||||
// this branch should never been hit
|
||||
|
@ -202,12 +279,12 @@ fn is_gt_nested(val string, dst Number) bool {
|
|||
|
||||
fn concat(val string, dst Number) string {
|
||||
match dst {
|
||||
any_int {
|
||||
int {
|
||||
mut res := val + '(int)'
|
||||
res += dst.str()
|
||||
return res
|
||||
}
|
||||
any_float {
|
||||
f64 {
|
||||
mut res := val + '(float)'
|
||||
res += dst.str()
|
||||
return res
|
||||
|
@ -217,12 +294,12 @@ fn concat(val string, dst Number) string {
|
|||
|
||||
fn get_sum(val string, dst Number) f64 {
|
||||
match dst {
|
||||
any_int {
|
||||
int {
|
||||
mut res := val.int()
|
||||
res += dst
|
||||
return res
|
||||
}
|
||||
any_float {
|
||||
f64 {
|
||||
mut res := val.f64()
|
||||
res += dst
|
||||
return res
|
||||
|
@ -230,21 +307,22 @@ fn get_sum(val string, dst Number) f64 {
|
|||
}
|
||||
}
|
||||
|
||||
fn test_sum_type_match() {
|
||||
assert is_gt_simple('3', 2)
|
||||
assert !is_gt_simple('3', 5)
|
||||
assert is_gt_simple('3', 1.2)
|
||||
assert !is_gt_simple('3', 3.5)
|
||||
assert is_gt_nested('3', 2)
|
||||
assert !is_gt_nested('3', 5)
|
||||
assert is_gt_nested('3', 1.2)
|
||||
assert !is_gt_nested('3', 3.5)
|
||||
assert concat('3', 2) == '3(int)2'
|
||||
assert concat('3', 5) == '3(int)5'
|
||||
assert concat('3', 1.2) == '3(float)1.2'
|
||||
assert concat('3', 3.5) == '3(float)3.5'
|
||||
assert get_sum('3', 2) == 5.0
|
||||
assert get_sum('3', 5) == 8.0
|
||||
assert get_sum('3', 1.2) == 4.2
|
||||
assert get_sum('3', 3.5) == 6.5
|
||||
fn handle(e Expr) string {
|
||||
is_literal := e is IntegerLiteral
|
||||
assert is_literal
|
||||
assert !(e !is IntegerLiteral)
|
||||
if e is IntegerLiteral {
|
||||
assert typeof(e.val) == 'string'
|
||||
}
|
||||
match e {
|
||||
IntegerLiteral {
|
||||
assert e.val == '12'
|
||||
// assert e.val == '12' // TODO
|
||||
return 'int'
|
||||
}
|
||||
IfExpr {
|
||||
return 'if'
|
||||
}
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
|
|
@ -1,511 +0,0 @@
|
|||
type Expr = IfExpr | IntegerLiteral
|
||||
type Stmt = FnDecl | StructDecl
|
||||
type Node = Expr | Stmt
|
||||
|
||||
struct FnDecl {
|
||||
pos int
|
||||
}
|
||||
|
||||
struct StructDecl {
|
||||
pos int
|
||||
}
|
||||
|
||||
|
||||
struct IfExpr {
|
||||
pos int
|
||||
}
|
||||
|
||||
struct IntegerLiteral {
|
||||
val string
|
||||
}
|
||||
|
||||
fn handle(e Expr) string {
|
||||
is_literal := e is IntegerLiteral
|
||||
assert is_literal
|
||||
assert !(e !is IntegerLiteral)
|
||||
if e is IntegerLiteral {
|
||||
assert typeof(e.val) == 'string'
|
||||
}
|
||||
match e {
|
||||
IntegerLiteral {
|
||||
assert e.val == '12'
|
||||
// assert e.val == '12' // TODO
|
||||
return 'int'
|
||||
}
|
||||
IfExpr {
|
||||
return 'if'
|
||||
}
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
fn test_expr() {
|
||||
expr := IntegerLiteral{
|
||||
val: '12'
|
||||
}
|
||||
assert handle(expr) == 'int'
|
||||
// assert expr is IntegerLiteral // TODO
|
||||
}
|
||||
|
||||
fn test_assignment_and_push() {
|
||||
mut expr1 := Expr{}
|
||||
mut arr1 := []Expr{}
|
||||
expr := IntegerLiteral{
|
||||
val: '111'
|
||||
}
|
||||
arr1 << expr
|
||||
match arr1[0] {
|
||||
IntegerLiteral {
|
||||
arr1 << arr1[0]
|
||||
// should ref/dereference on assignent be made automatic?
|
||||
// currently it is done for return stmt and fn args
|
||||
expr1 = arr1[0]
|
||||
}
|
||||
else {}
|
||||
}
|
||||
}
|
||||
|
||||
// Test moving structs between master/sub arrays
|
||||
type Master = Sub1 | Sub2
|
||||
|
||||
struct Sub1 {
|
||||
mut:
|
||||
val int
|
||||
name string
|
||||
}
|
||||
|
||||
struct Sub2 {
|
||||
name string
|
||||
val int
|
||||
}
|
||||
|
||||
fn test_converting_down() {
|
||||
mut out := []Master{}
|
||||
out << Sub1{
|
||||
val: 1
|
||||
name: 'one'
|
||||
}
|
||||
out << Sub2{
|
||||
val: 2
|
||||
name: 'two'
|
||||
}
|
||||
out << Sub2{
|
||||
val: 3
|
||||
name: 'three'
|
||||
}
|
||||
mut res := []Sub2{cap: out.len}
|
||||
for d in out {
|
||||
match d {
|
||||
Sub2 { res << d }
|
||||
else {}
|
||||
}
|
||||
}
|
||||
assert res[0].val == 2
|
||||
assert res[0].name == 'two'
|
||||
assert res[1].val == 3
|
||||
assert res[1].name == 'three'
|
||||
}
|
||||
|
||||
struct NodeWrapper {
|
||||
node Node
|
||||
}
|
||||
|
||||
fn test_nested_sumtype_selector() {
|
||||
c := NodeWrapper{Node(Expr(IfExpr{pos: 1}))}
|
||||
if c.node is Expr {
|
||||
if c.node is IfExpr {
|
||||
assert c.node.pos == 1
|
||||
}
|
||||
else {
|
||||
assert false
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert false
|
||||
}
|
||||
}
|
||||
|
||||
fn test_nested_sumtype_match_selector() {
|
||||
c := NodeWrapper{Node(Expr(IfExpr{pos: 1}))}
|
||||
match c.node {
|
||||
Expr {
|
||||
match c.node {
|
||||
IfExpr {
|
||||
assert c.node.pos == 1
|
||||
}
|
||||
else {
|
||||
assert false
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn test_nested_sumtype() {
|
||||
c := Node(Expr(IfExpr{pos:1}))
|
||||
if c is Expr {
|
||||
if c is IfExpr {
|
||||
assert c.pos == 1
|
||||
}
|
||||
else {
|
||||
assert false
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert false
|
||||
}
|
||||
}
|
||||
|
||||
fn test_nested_sumtype_match() {
|
||||
c := Node(Expr(IfExpr{pos: 1}))
|
||||
match c {
|
||||
Expr {
|
||||
match c {
|
||||
IfExpr {
|
||||
assert c.pos == 1
|
||||
}
|
||||
else {
|
||||
assert false
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type Abc = int | string
|
||||
|
||||
fn test_string_cast_to_sumtype() {
|
||||
a := Abc('test')
|
||||
match a {
|
||||
int {
|
||||
assert false
|
||||
}
|
||||
string {
|
||||
assert true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn test_int_cast_to_sumtype() {
|
||||
// literal
|
||||
a := Abc(111)
|
||||
match a {
|
||||
int {
|
||||
assert true
|
||||
}
|
||||
string {
|
||||
assert false
|
||||
}
|
||||
}
|
||||
// var
|
||||
i := 111
|
||||
b := Abc(i)
|
||||
match b {
|
||||
int {
|
||||
assert true
|
||||
}
|
||||
string {
|
||||
assert false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: change definition once types other than int and f64 (int, f64, etc) are supported in sumtype
|
||||
type Number = int | f64
|
||||
|
||||
fn is_gt_simple(val string, dst Number) bool {
|
||||
match dst {
|
||||
int {
|
||||
return val.int() > dst
|
||||
}
|
||||
f64 {
|
||||
return dst < val.f64()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_gt_nested(val string, dst Number) bool {
|
||||
dst2 := dst
|
||||
match dst {
|
||||
int {
|
||||
match dst2 {
|
||||
int {
|
||||
return val.int() > dst
|
||||
}
|
||||
// this branch should never been hit
|
||||
else {
|
||||
return val.int() < dst
|
||||
}
|
||||
}
|
||||
}
|
||||
f64 {
|
||||
match dst2 {
|
||||
f64 {
|
||||
return dst < val.f64()
|
||||
}
|
||||
// this branch should never been hit
|
||||
else {
|
||||
return dst > val.f64()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn concat(val string, dst Number) string {
|
||||
match dst {
|
||||
int {
|
||||
mut res := val + '(int)'
|
||||
res += dst.str()
|
||||
return res
|
||||
}
|
||||
f64 {
|
||||
mut res := val + '(float)'
|
||||
res += dst.str()
|
||||
return res
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_sum(val string, dst Number) f64 {
|
||||
match dst {
|
||||
int {
|
||||
mut res := val.int()
|
||||
res += dst
|
||||
return res
|
||||
}
|
||||
f64 {
|
||||
mut res := val.f64()
|
||||
res += dst
|
||||
return res
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type Bar = string | Test
|
||||
type Xyz = int | string
|
||||
|
||||
struct Test {
|
||||
x string
|
||||
xyz Xyz
|
||||
}
|
||||
|
||||
struct Foo {
|
||||
y Bar
|
||||
}
|
||||
|
||||
fn test_nested_selector_smartcast() {
|
||||
f := Foo{
|
||||
y: Bar(Test{
|
||||
x: 'Hi'
|
||||
xyz: Xyz(5)
|
||||
})
|
||||
}
|
||||
|
||||
if f.y is Test {
|
||||
z := f.y.x
|
||||
assert f.y.x == 'Hi'
|
||||
assert z == 'Hi'
|
||||
if f.y.xyz is int {
|
||||
assert f.y.xyz == 5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn test_as_cast() {
|
||||
f := Foo{
|
||||
y: Bar('test')
|
||||
}
|
||||
y := f.y as string
|
||||
assert y == 'test'
|
||||
}
|
||||
|
||||
fn test_assignment() {
|
||||
y := 5
|
||||
mut x := Xyz(y)
|
||||
x = 'test'
|
||||
|
||||
if x is string {
|
||||
x2 := x as string
|
||||
assert x2 == 'test'
|
||||
}
|
||||
}
|
||||
|
||||
type Inner = int | string
|
||||
struct InnerStruct {
|
||||
x Inner
|
||||
}
|
||||
type Outer = string | InnerStruct
|
||||
|
||||
fn test_nested_if_is() {
|
||||
b := Outer(InnerStruct{Inner(0)})
|
||||
if b is InnerStruct {
|
||||
if b.x is int {
|
||||
assert b.x == 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type Expr3 = CallExpr | CTempVarExpr
|
||||
struct Expr3Wrapper {
|
||||
mut:
|
||||
expr Expr3
|
||||
}
|
||||
struct CallExpr {
|
||||
y int
|
||||
x string
|
||||
}
|
||||
|
||||
struct CTempVarExpr {
|
||||
x string
|
||||
}
|
||||
|
||||
fn gen(_ Expr3) CTempVarExpr {
|
||||
return CTempVarExpr{}
|
||||
}
|
||||
|
||||
fn test_reassign_from_function_with_parameter() {
|
||||
mut f := Expr3(CallExpr{})
|
||||
if f is CallExpr {
|
||||
f = gen(f)
|
||||
}
|
||||
}
|
||||
|
||||
fn test_reassign_from_function_with_parameter_selector() {
|
||||
mut f := Expr3Wrapper{Expr3(CallExpr{})}
|
||||
if f.expr is CallExpr {
|
||||
f.expr = gen(f.expr)
|
||||
}
|
||||
}
|
||||
|
||||
fn test_typeof() {
|
||||
x := Expr3(CTempVarExpr{})
|
||||
assert typeof(x) == 'CTempVarExpr'
|
||||
}
|
||||
|
||||
struct Outer2 {
|
||||
e Expr3
|
||||
}
|
||||
|
||||
fn test_zero_value_init() {
|
||||
// no c compiler error then it's successful
|
||||
_ := Outer2{}
|
||||
}
|
||||
|
||||
struct Milk {
|
||||
mut:
|
||||
name string
|
||||
}
|
||||
|
||||
struct Eggs {
|
||||
mut:
|
||||
name string
|
||||
}
|
||||
|
||||
type Food = Milk | Eggs
|
||||
|
||||
struct FoodWrapper {
|
||||
mut:
|
||||
food Food
|
||||
}
|
||||
|
||||
fn test_match_aggregate() {
|
||||
f := Food(Milk{'test'})
|
||||
match f {
|
||||
Milk, Eggs {
|
||||
assert f.name == 'test'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn test_match_mut() {
|
||||
mut f := Food(Milk{'test'})
|
||||
match mut f {
|
||||
Eggs {
|
||||
f.name = 'eggs'
|
||||
assert f.name == 'eggs'
|
||||
}
|
||||
Milk {
|
||||
f.name = 'milk'
|
||||
assert f.name == 'milk'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn test_match_not_mut() {
|
||||
mut f := Food(Milk{'test'})
|
||||
match f {
|
||||
Eggs {
|
||||
// only works without smartcast
|
||||
assert f is Eggs
|
||||
}
|
||||
Milk {
|
||||
// only works without smartcast
|
||||
assert f is Milk
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn test_if_mut() {
|
||||
mut f := Food(Milk{'test'})
|
||||
if mut f is Milk {
|
||||
f.name = 'milk'
|
||||
assert f.name == 'milk'
|
||||
}
|
||||
}
|
||||
|
||||
fn test_if_not_mut() {
|
||||
mut f := Food(Milk{'test'})
|
||||
if f is Milk {
|
||||
// only works without smartcast
|
||||
assert f is Milk
|
||||
}
|
||||
}
|
||||
|
||||
fn test_match_mut_selector() {
|
||||
mut f := FoodWrapper{Food(Milk{'test'})}
|
||||
match mut f.food {
|
||||
Eggs {
|
||||
f.food.name = 'eggs'
|
||||
assert f.food.name == 'eggs'
|
||||
}
|
||||
Milk {
|
||||
f.food.name = 'milk'
|
||||
assert f.food.name == 'milk'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn test_if_mut_selector() {
|
||||
mut f := FoodWrapper{Food(Milk{'test'})}
|
||||
if mut f.food is Milk {
|
||||
f.food.name = 'milk'
|
||||
assert f.food.name == 'milk'
|
||||
}
|
||||
}
|
||||
|
||||
fn test_sum_type_match() {
|
||||
// TODO: Remove these casts
|
||||
assert is_gt_simple('3', int(2))
|
||||
assert !is_gt_simple('3', int(5))
|
||||
assert is_gt_simple('3', f64(1.2))
|
||||
assert !is_gt_simple('3', f64(3.5))
|
||||
assert is_gt_nested('3', int(2))
|
||||
assert !is_gt_nested('3', int(5))
|
||||
assert is_gt_nested('3', f64(1.2))
|
||||
assert !is_gt_nested('3', f64(3.5))
|
||||
assert concat('3', int(2)) == '3(int)2'
|
||||
assert concat('3', int(5)) == '3(int)5'
|
||||
assert concat('3', f64(1.2)) == '3(float)1.2'
|
||||
assert concat('3', f64(3.5)) == '3(float)3.5'
|
||||
assert get_sum('3', int(2)) == 5.0
|
||||
assert get_sum('3', int(5)) == 8.0
|
||||
assert get_sum('3', f64(1.2)) == 4.2
|
||||
assert get_sum('3', f64(3.5)) == 6.5
|
||||
}
|
Loading…
Reference in New Issue