e58616b975
Close #683.
271 lines
4.6 KiB
Go
271 lines
4.6 KiB
Go
package compiler_test
|
|
|
|
import (
|
|
"fmt"
|
|
"math/big"
|
|
"testing"
|
|
)
|
|
|
|
func TestSimpleFunctionCall(t *testing.T) {
|
|
src := `
|
|
package testcase
|
|
func Main() int {
|
|
x := 10
|
|
y := getSomeInteger()
|
|
return x + y
|
|
}
|
|
|
|
func getSomeInteger() int {
|
|
x := 10
|
|
return x
|
|
}
|
|
`
|
|
eval(t, src, big.NewInt(20))
|
|
}
|
|
|
|
func TestNotAssignedFunctionCall(t *testing.T) {
|
|
t.Run("Simple", func(t *testing.T) {
|
|
src := `package testcase
|
|
func Main() int {
|
|
getSomeInteger()
|
|
getSomeInteger()
|
|
return 0
|
|
}
|
|
|
|
func getSomeInteger() int {
|
|
return 0
|
|
}`
|
|
eval(t, src, big.NewInt(0))
|
|
})
|
|
t.Run("If", func(t *testing.T) {
|
|
src := `package testcase
|
|
func f() bool { return true }
|
|
func Main() int {
|
|
if f() {
|
|
return 42
|
|
}
|
|
return 0
|
|
}`
|
|
eval(t, src, big.NewInt(42))
|
|
})
|
|
t.Run("Switch", func(t *testing.T) {
|
|
src := `package testcase
|
|
func f() bool { return true }
|
|
func Main() int {
|
|
switch true {
|
|
case f():
|
|
return 42
|
|
default:
|
|
return 0
|
|
}
|
|
}`
|
|
eval(t, src, big.NewInt(42))
|
|
})
|
|
t.Run("Builtin", func(t *testing.T) {
|
|
src := `package foo
|
|
import "github.com/nspcc-dev/neo-go/pkg/interop/util"
|
|
func Main() int {
|
|
util.FromAddress("NPAsqZkx9WhNd4P72uhZxBhLinSuNkxfB8")
|
|
util.FromAddress("NPAsqZkx9WhNd4P72uhZxBhLinSuNkxfB8")
|
|
return 1
|
|
}`
|
|
eval(t, src, big.NewInt(1))
|
|
})
|
|
t.Run("Lambda", func(t *testing.T) {
|
|
src := `package foo
|
|
func Main() int {
|
|
f := func() (int, int) { return 1, 2 }
|
|
f()
|
|
f()
|
|
return 42
|
|
}`
|
|
eval(t, src, big.NewInt(42))
|
|
})
|
|
}
|
|
|
|
func TestMultipleFunctionCalls(t *testing.T) {
|
|
src := `
|
|
package testcase
|
|
func Main() int {
|
|
x := 10
|
|
y := getSomeInteger()
|
|
return x + y
|
|
}
|
|
|
|
func getSomeInteger() int {
|
|
x := 10
|
|
y := getSomeOtherInt()
|
|
return x + y
|
|
}
|
|
|
|
func getSomeOtherInt() int {
|
|
x := 8
|
|
return x
|
|
}
|
|
`
|
|
eval(t, src, big.NewInt(28))
|
|
}
|
|
|
|
func TestFunctionCallWithArgs(t *testing.T) {
|
|
src := `
|
|
package testcase
|
|
func Main() int {
|
|
x := 10
|
|
y := getSomeInteger(x)
|
|
return y
|
|
}
|
|
|
|
func getSomeInteger(x int) int {
|
|
y := 8
|
|
return x + y
|
|
}
|
|
`
|
|
eval(t, src, big.NewInt(18))
|
|
}
|
|
|
|
func TestFunctionCallWithInterfaceType(t *testing.T) {
|
|
src := `
|
|
package testcase
|
|
func Main() interface{} {
|
|
x := getSomeInteger(10)
|
|
return x
|
|
}
|
|
|
|
func getSomeInteger(x interface{}) interface{} {
|
|
return x
|
|
}
|
|
`
|
|
eval(t, src, big.NewInt(10))
|
|
}
|
|
|
|
func TestFunctionCallMultiArg(t *testing.T) {
|
|
src := `
|
|
package testcase
|
|
func Main() int {
|
|
x := addIntegers(2, 4)
|
|
return x
|
|
}
|
|
|
|
func addIntegers(x int, y int) int {
|
|
return x + y
|
|
}
|
|
`
|
|
eval(t, src, big.NewInt(6))
|
|
}
|
|
|
|
func TestFunctionWithVoidReturn(t *testing.T) {
|
|
src := `
|
|
package testcase
|
|
func Main() int {
|
|
x := 2
|
|
getSomeInteger()
|
|
y := 4
|
|
return x + y
|
|
}
|
|
|
|
func getSomeInteger() { %s }
|
|
`
|
|
t.Run("EmptyBody", func(t *testing.T) {
|
|
src := fmt.Sprintf(src, "")
|
|
eval(t, src, big.NewInt(6))
|
|
})
|
|
t.Run("SingleReturn", func(t *testing.T) {
|
|
src := fmt.Sprintf(src, "return")
|
|
eval(t, src, big.NewInt(6))
|
|
})
|
|
}
|
|
|
|
func TestFunctionWithVoidReturnBranch(t *testing.T) {
|
|
src := `
|
|
package testcase
|
|
func Main() int {
|
|
x := %t
|
|
f(x)
|
|
return 2
|
|
}
|
|
|
|
func f(x bool) {
|
|
if x {
|
|
return
|
|
}
|
|
}
|
|
`
|
|
t.Run("ReturnBranch", func(t *testing.T) {
|
|
src := fmt.Sprintf(src, true)
|
|
eval(t, src, big.NewInt(2))
|
|
})
|
|
t.Run("NoReturn", func(t *testing.T) {
|
|
src := fmt.Sprintf(src, false)
|
|
eval(t, src, big.NewInt(2))
|
|
})
|
|
}
|
|
|
|
func TestFunctionWithMultipleArgumentNames(t *testing.T) {
|
|
src := `package foo
|
|
func Main() int {
|
|
return add(1, 2)
|
|
}
|
|
func add(a, b int) int {
|
|
return a + b
|
|
}`
|
|
eval(t, src, big.NewInt(3))
|
|
}
|
|
|
|
func TestLocalsCount(t *testing.T) {
|
|
src := `package foo
|
|
func f(a, b, c int) int {
|
|
sum := a
|
|
for i := 0; i < c; i++ {
|
|
sum += b
|
|
}
|
|
return sum
|
|
}
|
|
func Main() int {
|
|
return f(1, 2, 3)
|
|
}`
|
|
eval(t, src, big.NewInt(7))
|
|
}
|
|
|
|
func TestVariadic(t *testing.T) {
|
|
srcTmpl := `package foo
|
|
func someFunc(a int, b ...int) int {
|
|
sum := a
|
|
for i := range b {
|
|
sum = sum - b[i]
|
|
}
|
|
return sum
|
|
}
|
|
func Main() int {
|
|
%s
|
|
return someFunc(10, %s)
|
|
}`
|
|
t.Run("Elements", func(t *testing.T) {
|
|
src := fmt.Sprintf(srcTmpl, "", "1, 2, 3")
|
|
eval(t, src, big.NewInt(4))
|
|
})
|
|
t.Run("Slice", func(t *testing.T) {
|
|
src := fmt.Sprintf(srcTmpl, "a := []int{1, 2, 3}", "a...")
|
|
eval(t, src, big.NewInt(4))
|
|
})
|
|
t.Run("Literal", func(t *testing.T) {
|
|
src := fmt.Sprintf(srcTmpl, "", "[]int{1, 2, 3}...")
|
|
eval(t, src, big.NewInt(4))
|
|
})
|
|
}
|
|
|
|
func TestVariadicMethod(t *testing.T) {
|
|
src := `package foo
|
|
type myInt int
|
|
func (x myInt) someFunc(a int, b ...int) int {
|
|
sum := int(x) + a
|
|
for i := range b {
|
|
sum = sum - b[i]
|
|
}
|
|
return sum
|
|
}
|
|
func Main() int {
|
|
x := myInt(38)
|
|
return x.someFunc(10, 1, 2, 3)
|
|
}`
|
|
eval(t, src, big.NewInt(42))
|
|
}
|