72 lines
2.1 KiB
Go
72 lines
2.1 KiB
Go
package lang
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestGenerateGenericFunctionsAndClasses(t *testing.T) {
|
|
program, err := Parse(`package demo
|
|
data class Box<T>(var value: T) {
|
|
fun get(): T { return value }
|
|
}
|
|
fun identity<T>(value: T): T { return value }
|
|
fun wrap<T>(value: T): Box<T> { return Box(value) }
|
|
fun main() {
|
|
val inferred = identity(42)
|
|
val explicit = identity<String>("value")
|
|
val box = wrap("boxed")
|
|
println(box.get())
|
|
}`)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
output, err := GenerateGo(program)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
code := string(output)
|
|
for _, expected := range []string{
|
|
"type Box[T any] struct",
|
|
"func NewBox[T any](value T) *Box[T]",
|
|
"func (self *Box[T]) get() T",
|
|
"func identity[T any](value T) T",
|
|
"func wrap[T any](value T) *Box[T]",
|
|
"identity(42)",
|
|
`identity[string]("value")`,
|
|
`wrap("boxed")`,
|
|
} {
|
|
if !strings.Contains(code, expected) {
|
|
t.Fatalf("missing %q:\n%s", expected, code)
|
|
}
|
|
}
|
|
main := program.Functions[2]
|
|
inferred := main.Body[0].(VarDecl)
|
|
if got := ResolvedType(inferred.Value).String(); got != "Int" {
|
|
t.Fatalf("inferred generic type = %s", got)
|
|
}
|
|
box := main.Body[2].(VarDecl)
|
|
if got := ResolvedType(box.Value).String(); got != "Box<String>" {
|
|
t.Fatalf("generic class type = %s", got)
|
|
}
|
|
}
|
|
|
|
func TestRejectInvalidGenericDeclarationsAndCalls(t *testing.T) {
|
|
for _, test := range []struct{ source, message string }{
|
|
{`package demo fun identity<T, T>(value: T): T { return value }`, "duplicate type parameter T"},
|
|
{`package demo fun identity<T>(value: T): T { return value } fun main() { identity<String, Int>("x") }`, "expects 1 type arguments, got 2"},
|
|
{`package demo class Box<T>(val value: T) { fun convert<R>(): T { return value } }`, "generic methods are not supported"},
|
|
} {
|
|
program, err := Parse(test.source)
|
|
if err != nil {
|
|
if strings.Contains(err.Error(), test.message) {
|
|
continue
|
|
}
|
|
t.Fatalf("unexpected parse error: %v", err)
|
|
}
|
|
_, err = GenerateGo(program)
|
|
if err == nil || !strings.Contains(err.Error(), test.message) {
|
|
t.Fatalf("error = %v, want %q", err, test.message)
|
|
}
|
|
}
|
|
}
|