neo-go/pkg/compiler/function_call_test.go

272 lines
4.6 KiB
Go
Raw Normal View History

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) {
2020-06-27 07:39:30 +00:00
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 {
2020-06-27 07:39:30 +00:00
%s
return someFunc(10, %s)
}`
2020-06-27 07:39:30 +00:00
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))
}