gotlin/internal/lang/nullability_test.go

67 lines
1.8 KiB
Go

package lang
import (
"strings"
"testing"
)
func TestSafeAccessAndNonNullAssertion(t *testing.T) {
prog, err := Parse(`package demo
data class User(var email: String)
fun safe(user: User?): String? { return user?.email }
fun required(user: User?): String { return user!!.email }`)
if err != nil {
t.Fatal(err)
}
out, err := GenerateGo(prog)
if err != nil {
t.Fatal(err)
}
for _, want := range []string{"if value == nil {", "return &result", "non-null assertion failed"} {
if !strings.Contains(string(out), want) {
t.Fatalf("missing %q:\n%s", want, out)
}
}
}
func TestRejectNullableDereference(t *testing.T) {
prog, err := Parse(`package demo
fun unsafe(user: User?): String { return user.email }`)
if err != nil {
t.Fatal(err)
}
_, err = GenerateGo(prog)
if err == nil || !strings.Contains(err.Error(), "requires ?. or !!") {
t.Fatalf("unexpected error: %v", err)
}
}
func TestRejectNullForNonNullableTypes(t *testing.T) {
for _, source := range []string{
`package demo data class User(var email: String) fun main() { val user: User = null }`,
`package demo data class User(var email: String) fun use(user: User) {} fun main() { use(null) }`,
`package demo fun name(): String { return null }`,
`package demo fun main() { val value = null }`,
} {
prog, err := Parse(source)
if err != nil {
t.Fatal(err)
}
if _, err = GenerateGo(prog); err == nil {
t.Fatalf("expected nullability error for %s", source)
}
}
}
func TestNullableSmartCasts(t *testing.T) {
prog, err := Parse(`package demo
data class User(var email: String)
fun guarded(user: User?): String { if (user == null) { return "missing" }; return user.email }
fun branched(user: User?): String { if (user != null) { return user.email } else { return "missing" } }`)
if err != nil {
t.Fatal(err)
}
if _, err = GenerateGo(prog); err != nil {
t.Fatal(err)
}
}