//nolint:testpackage // white-box tests exercise unexported internals package mfer import ( "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) // TestValidatePathMessagesVerbatim pins the exact rendered text of every // ValidatePath rejection. // // These strings are user-visible and are assembled by wrapping static // sentinels mid-sentence, which makes them easy to reword by accident // while refactoring for errors.Is matchability. Changing one is a // deliberate change, not a refactoring side effect. func TestValidatePathMessagesVerbatim(t *testing.T) { t.Parallel() for _, tc := range []struct { name string path string want string is error }{ { name: "empty", path: "", want: "path cannot be empty", is: errPathEmpty, }, { name: "not utf8", path: "a\xffb", want: `path "a\xffb" is not valid UTF-8`, is: errPathNotUTF8, }, { name: "backslash", path: `a\b`, want: `path "a\\b" contains backslash; ` + "use forward slashes only", is: errPathBackslash, }, { name: "absolute", path: "/a/b", want: `path "/a/b" is absolute; must be relative`, is: errPathAbsolute, }, { name: "empty segment", path: "a//b", want: `path "a//b" contains empty segment`, is: errPathEmptySegment, }, { name: "dotdot segment", path: "a/../b", want: `path "a/../b" contains '..' segment`, is: errPathDotDot, }, } { t.Run(tc.name, func(t *testing.T) { t.Parallel() err := ValidatePath(tc.path) require.Error(t, err) assert.Equal(t, tc.want, err.Error()) require.ErrorIs(t, err, tc.is) }) } } // TestSerializeInternalErrorMessagesVerbatim pins the two distinct // "internal error" messages, which differ between generate and // generateOuter and have always done so. func TestSerializeInternalErrorMessagesVerbatim(t *testing.T) { t.Parallel() m := &manifest{} require.EqualError(t, m.generate(), "internal error: pbInner not set") require.EqualError(t, m.generateOuter(), "internal error") }