Add value-returning match expressions

This commit is contained in:
pavel 2026-08-27 17:56:13 +02:00
commit ab783c33ed
12 changed files with 384 additions and 14 deletions

View file

@ -77,3 +77,68 @@ fun main() { println(Status::PendingReservation) }`)
}
}
}
func TestGenerateExhaustiveMatchExpression(t *testing.T) {
prog, err := Parse(`package demo
enum AccountType { BASIC, SAVINGS }
fun interestRate(accountType: AccountType): Double {
return match (accountType) {
AccountType::BASIC -> 0.0
AccountType::SAVINGS -> 0.02
}
}`)
if err != nil {
t.Fatal(err)
}
out, err := GenerateGo(prog)
if err != nil {
t.Fatal(err)
}
for _, want := range []string{"func() float64", "case AccountTypeBASIC:", "return 0.0", "case AccountTypeSAVINGS:", "return 0.02", `panic("unreachable exhaustive match")`} {
if !strings.Contains(string(out), want) {
t.Fatalf("missing %q:\n%s", want, out)
}
}
}
func TestGeneratePayloadMatchExpression(t *testing.T) {
prog, err := Parse(`package demo
enum Outcome { Success(String), Failure(String) }
fun message(outcome: Outcome): String {
return match (outcome) {
Outcome::Success(value) -> value
Outcome::Failure(reason) -> reason
}
}`)
if err != nil {
t.Fatal(err)
}
out, err := GenerateGo(prog)
if err != nil {
t.Fatal(err)
}
for _, want := range []string{"switch gotlinMatch", "value := gotlinMatch", "return value", "return reason"} {
if !strings.Contains(string(out), want) {
t.Fatalf("missing %q:\n%s", want, out)
}
}
}
func TestRejectInvalidMatchExpression(t *testing.T) {
for _, test := range []struct {
source string
want string
}{
{`package demo enum State { On, Off } fun value(state: State): Int { return match (state) { State::On -> 1 } }`, "missing Off"},
{`package demo enum State { On, Off } fun value(state: State): Int { return match (state) { State::On -> 1 State::Off -> "off" } }`, "has type String, expected Int"},
} {
prog, err := Parse(test.source)
if err != nil {
t.Fatal(err)
}
_, err = GenerateGo(prog)
if err == nil || !strings.Contains(err.Error(), test.want) {
t.Fatalf("expected %q, got %v", test.want, err)
}
}
}