package lang import ( "strings" "testing" ) func TestGenerateGenericFunctionsAndClasses(t *testing.T) { program, err := Parse(`package demo data class Box(var value: T) { fun get(): T { return value } } fun identity(value: T): T { return value } fun wrap(value: T): Box { return Box(value) } fun main() { val inferred = identity(42) val explicit = identity("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" { t.Fatalf("generic class type = %s", got) } } func TestRejectInvalidGenericDeclarationsAndCalls(t *testing.T) { for _, test := range []struct{ source, message string }{ {`package demo fun identity(value: T): T { return value }`, "duplicate type parameter T"}, {`package demo fun identity(value: T): T { return value } fun main() { identity("x") }`, "expects 1 type arguments, got 2"}, {`package demo class Box(val value: T) { fun convert(): 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) } } }