fspl/analyzer/control-flow_test.go

238 lines
3.6 KiB
Go

package analyzer
import "testing"
func TestMatch (test *testing.T) {
testString (test,
`
U: (| Int F64)
[matchToInt u:U]:Int = match u
| u:Int u
| u:F64 [~Int u]
`)
}
func TestMatchReturn (test *testing.T) {
testString (test,
`
U: (| Int F64)
[isInt u:U]:Bool = {
match u | u:Int [return true]
false
}
`)
}
func TestMatchReturnValueUsed (test *testing.T) {
testString (test,
`
U: (| Int F64)
[isInt u:U]:Bool = match u
| u:Int [return true]
| u:F64 false
`)
}
func TestMatchDefault (test *testing.T) {
testString (test,
`
U: (| Int F64)
[isInt u:U]:Bool = match u
| u:Int [return true]
* false
`)
}
func TestMatchUnionUnderComplete (test *testing.T) {
testString (test,
`
U: (| Int F64 UInt)
[print str:String]
[matchToInt u:U] = match u
| u:Int [print 'Int']
| u:F64 [print 'F64']
`)
}
func TestMatchErrUnionOverComplete (test *testing.T) {
testStringErr (test,
"UInt is not included within U", 5, 6,
`
U: (| Int F64)
[matchToInt u:U]:Int = match u
| u:Int u
| u:UInt [~Int u]
| u:F64 [~Int u]
`)
}
func TestMatchErrNotUnion (test *testing.T) {
testStringErr (test,
"type U is not a union", 3, 30,
`
U: Int
[matchToInt u:U]:Int = match u
| u:Int u
| u:F64 [~Int u]
`)
}
func TestMatchErrUnionUnderComplete (test *testing.T) {
testStringErr (test,
"match does not cover all types within U", 3, 24,
`
U: (| Int F64 UInt)
[matchToInt u:U]:Int = match u
| u:Int u
| u:F64 [~Int u]
`)
}
func TestMatchErrDuplicate (test *testing.T) {
testStringErr (test,
"Int already listed in match at stream0.fspl:4:6", 6, 6,
`
U: (| Int F64 UInt)
[matchToInt u:U]:Int = match u
| u:Int u
| u:F64 [~Int u]
| u:Int u
`)
}
func TestSwitch (test *testing.T) {
testString (test,
`
[f x:Int]:Int = switch x
| 0 5
| 1 4
| 2 3
* 0
`)
}
func TestSwitchReturn (test *testing.T) {
testString (test,
`
[is5 x:Int]:Bool = {
switch x | 5 [return true]
false
}
`)
}
func TestSwitchReturnValueUsed (test *testing.T) {
testString (test,
`
[is5 x:Int]:Bool = switch x
| 5 [return true]
* false
`)
}
func TestSwitchErrBadLiteral (test *testing.T) {
testStringErr (test,
"cannot use array literal as Int", 4, 4,
`
[f x:Int]:Int = switch x
| 0 5
| (1) 4
| 2 3
* 0
`)
}
func TestSwitchErrNotConstant (test *testing.T) {
testStringErr (test,
"y cannot represent a constant integer", 7, 4,
`
[f x:Int]:Int = {
y:Int = 1
switch x
| 0 5
| y 4
| 2 3
* 0
}
`)
}
func TestSwitchErrDuplicate (test *testing.T) {
testStringErr (test,
"65 already listed in match at stream0.fspl:6:2", 7, 4,
`
[f x:I8]:Int = switch x
| 0 5
| 1 4
| 2 3
| 65 2
| 'A' 1
* 0
`)
}
func TestIfElseReturnValueUsed (test *testing.T) {
testString (test,
`
[is5 x:Int]:Bool = if [= x 5]
then true
else [return false]
`)
}
func TestIfElseBreakValueUsed (test *testing.T) {
testString (test,
`
[f x:Int]: Int = loop {
y:Int = if [= x 5]
then [break 0]
else x
}
`)
}
func TestFor (test *testing.T) {
testString (test,
`
[f str:String] = for c:Byte in str { }
[g str:String] = for i:Index c:Byte in str { }
`)}
func TestForBreak (test *testing.T) {
testString (test,
`
[f str:String]:Byte = for c:Byte in str [break c]
`)}
func TestForBreakBadType (test *testing.T) {
testStringErr (test,
"expected Byte", 2, 56,
`
[f str:String]:Byte = for i:Index c:Byte in str [break i]
`)}
func TestForErrBadIndex (test *testing.T) {
testStringErr (test,
"expected Index", 2, 22,
`
[f str:String] = for i:Int c:Byte in str { }
`)}
func TestForErrBadOver (test *testing.T) {
testStringErr (test,
"cannot use U8 as Int", 2, 31,
`
[f str:String] = for c:Int in str { }
`)}
func TestForErrDeclarationScoped (test *testing.T) {
testStringErr (test,
"no variable named c", 4, 2,
`
[f str:String] = {
for c:Byte in str { }
c = 'a'
}
`)}