diff --git a/modules/cabana/ml_nullable_test.go b/modules/cabana/ml_nullable_test.go index 401bc99..9f4a3f9 100644 --- a/modules/cabana/ml_nullable_test.go +++ b/modules/cabana/ml_nullable_test.go @@ -2,6 +2,7 @@ package cabana import ( "context" + "reflect" "strings" "testing" "testing/fstest" @@ -180,3 +181,74 @@ func TestMLNullablePointerHost(t *testing.T) { } }) } + +type nullableSlug string + +func (nullableSlug) String() string { return "decorated" } + +func TestHostScalarString(t *testing.T) { + var nilString *string + var nilBytes *[]byte + inner := new("x") + slug := nullableSlug("raw-slug") + cases := []struct { + name string + in any + want string + }{ + {"nil interface", nil, ""}, + {"nil *string", (*string)(nil), ""}, + {"nil *int", (*int)(nil), ""}, + {"**string to nil", &nilString, ""}, + {"nil *[]byte", nilBytes, ""}, + {"pointer to empty", new(""), ""}, + {"pointer to text", new("Opis"), "Opis"}, + {"**string to text", &inner, "x"}, + {"pointer to int", new(42), "42"}, + {"pointer to int64", new(int64(-7)), "-7"}, + {"pointer to uint", new(uint(9)), "9"}, + {"pointer to float64", new(1.5), "1.5"}, + {"pointer to bool", new(true), "true"}, + {"named string value", slug, "raw-slug"}, + {"pointer to named string", &slug, "raw-slug"}, + {"byte slice", []byte("abc"), "abc"}, + {"pointer to byte slice", new([]byte("abc")), "abc"}, + {"plain string", "plain", "plain"}, + {"plain int", 7, "7"}, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + got := hostScalarString(tc.in) + assertNoPointerLeak(t, tc.name, got) + if got != tc.want { + t.Fatalf("hostScalarString(%#v) = %q, want %q", tc.in, got, tc.want) + } + }) + } +} + +func TestMLHydrationPointerHost(t *testing.T) { + cc := mlCompiled(t) + cases := []struct { + name string + in any + want map[string]string + }{ + {"nil pointer", (*string)(nil), map[string]string{"en": "", "pl": ""}}, + {"pointer to empty", new(""), map[string]string{"en": "", "pl": ""}}, + {"pointer to text", new("Hello"), map[string]string{"en": "Hello", "pl": ""}}, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + writer := &recordingWriter{defaultLocale: "en", enabled: []string{"en", "pl"}} + data := map[string]any{"title": tc.in} + if err := hydrateMLRecord(context.Background(), nil, cc, writer, nil, data, "update"); err != nil { + t.Fatalf("hydrate: %v", err) + } + got := mlLocaleMap(t, tc.name, data, "title") + if !reflect.DeepEqual(got, tc.want) { + t.Fatalf("title = %#v, want %#v", got, tc.want) + } + }) + } +}