86 lines
2.2 KiB
Go
86 lines
2.2 KiB
Go
package lang
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestExpressionBodiedFunctionInfersReturnType(t *testing.T) {
|
|
program, err := Parse(`package demo
|
|
fun twice(value: Int) = value * 2
|
|
fun text() = "value"`)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
output, err := GenerateGo(program)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, expected := range []string{"func twice(value int) int", "return value * 2", "func text() string", `return "value"`} {
|
|
if !strings.Contains(string(output), expected) {
|
|
t.Fatalf("missing %q:\n%s", expected, output)
|
|
}
|
|
}
|
|
if got := ResolvedType(program.Functions[0].ExpressionBody).String(); got != "Int" {
|
|
t.Fatalf("return type = %s", got)
|
|
}
|
|
}
|
|
|
|
func TestExpressionBodyInferenceReachesFixedPoint(t *testing.T) {
|
|
program, err := Parse(`package demo
|
|
fun first() = second()
|
|
fun second() = third()
|
|
fun third() = 42`)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
semantic, err := Analyze(program)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, name := range []string{"first", "second", "third"} {
|
|
symbol, _ := semantic.Global.Lookup(name)
|
|
if got := symbol.Type.(FunctionType).Result.String(); got != "Int" {
|
|
t.Fatalf("%s result = %s", name, got)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestWithContextExpressionBodyEstablishesBoundary(t *testing.T) {
|
|
program, err := Parse(`package demo
|
|
import http net.http
|
|
import exec os.exec
|
|
fun work() { exec.commandContext("date") }
|
|
fun handle(request: *http.Request) = withContext(request.context()) {
|
|
work()
|
|
}`)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
semantic, err := Analyze(program)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !semantic.FunctionEffects["work"].Has(CoroutineEffect) {
|
|
t.Fatal("work should require ambient context")
|
|
}
|
|
if semantic.FunctionEffects["handle"].Has(CoroutineEffect) {
|
|
t.Fatal("withContext should be an effect boundary")
|
|
}
|
|
output, err := GenerateGo(program)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
code := string(output)
|
|
for _, expected := range []string{
|
|
"func work(gotlinScope *GotlinCoroutineScope)",
|
|
`exec.CommandContext(gotlinScope.Context(), "date")`,
|
|
"func handle(request *http.Request)",
|
|
"gotlinRunWithContext(request.Context()",
|
|
"work(gotlinScope)",
|
|
} {
|
|
if !strings.Contains(code, expected) {
|
|
t.Fatalf("missing %q:\n%s", expected, code)
|
|
}
|
|
}
|
|
}
|