package lang import ( "strings" "testing" ) func TestGenerateStructuredCoroutines(t *testing.T) { prog, err := Parse(`package demo suspend fun load(): Int { delay(1); return 42 } fun main() { runBlocking { coroutineScope { launch { delay(1) } val result = async { return load() } println(result.await()) } } }`) if err != nil { t.Fatal(err) } out, err := GenerateGo(prog) if err != nil { t.Fatal(err) } for _, want := range []string{"func load(gotlinScope *GotlinCoroutineScope) int", "gotlinScope.Delay(1)", "gotlinScope.Launch", "gotlinAsync[int]", "load(gotlinScope)", ".await()", "gotlinRunBlocking"} { if !strings.Contains(string(out), want) { t.Fatalf("missing %q:\n%s", want, out) } } } func TestSuspendFunctionRequiresScope(t *testing.T) { prog, err := Parse(`package demo suspend fun load(): Int { return 1 } fun main() { println(load()) }`) if err != nil { t.Fatal(err) } _, err = GenerateGo(prog) if err == nil || !strings.Contains(err.Error(), "requires a coroutine scope") { t.Fatalf("unexpected error: %v", err) } } func TestWorkerAndBareGoAreRemoved(t *testing.T) { for _, source := range []string{`package demo worker Counter { var count = 0 }`, `package demo fun main() { go println("x") }`} { if _, err := Parse(source); err == nil { t.Fatalf("deprecated concurrency syntax parsed: %s", source) } } } func TestRunBlockingCancelsAndJoinsChildrenOnPanic(t *testing.T) { prog, err := Parse(`package demo fun main() { runBlocking { launch { delay(1) }; panic("failed") } }`) if err != nil { t.Fatal(err) } out, err := GenerateGo(prog) if err != nil { t.Fatal(err) } for _, want := range []string{"scope.cancel()", "scope.workers.Wait()", "panic(value)", "gotlinRunBlocking"} { if !strings.Contains(string(out), want) { t.Fatalf("missing %q:\n%s", want, out) } } }