package ident_test import ( "encoding" "encoding/base64" "fmt" "reflect" "testing" "git.gensokyo.uk/cofront/cof-spec/ident" ) // rTestCases describes multiple representation test cases. type rTestCases[V any, S interface { encoding.TextMarshaler encoding.TextUnmarshaler fmt.Stringer *V }] []struct { name string ident V want []byte err error } // checkRepresentation runs tests described by testCases. func (testCases rTestCases[V, S]) run(t *testing.T) { t.Helper() for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { t.Helper() t.Parallel() t.Run("decode", func(t *testing.T) { t.Helper() t.Parallel() var got V if err := S(&got).UnmarshalText(tc.want); !reflect.DeepEqual(err, tc.err) { t.Fatalf("UnmarshalText: error = %v, want %v", err, tc.err) } if tc.err != nil { return } if !reflect.DeepEqual(got, tc.ident) { t.Errorf("UnmarshalText: %#v, want %#v", got, tc.ident) } }) if tc.err != nil { return } t.Run("encode", func(t *testing.T) { t.Helper() t.Parallel() if got, err := S(&tc.ident).MarshalText(); err != nil { t.Fatalf("MarshalText: error = %v", err) } else if string(got) != string(tc.want) { raw, decodeErr := base64.URLEncoding.AppendDecode(nil, got) t.Logf("AppendDecode: %#v, error = %v", raw, decodeErr) t.Errorf("MarshalText: %#v, want %#v", got, tc.want) } if got := S(&tc.ident).String(); got != string(tc.want) { t.Errorf("String: %s, want %s", got, tc.want) } }) }) } } func TestErrors(t *testing.T) { t.Parallel() testCases := []struct { name string err error want string }{ {"UnexpectedSizeError", &ident.UnexpectedSizeError{ Data: make([]byte, 1<<10), Want: ident.EncodedSizeSystem, }, "got 1024 bytes for a 32-byte identifier"}, {"InvalidLabelLDH start", &ident.InvalidLabelError{ Data: []byte{'-'}, Label: 0xbad, Index: 0, Reason: ident.InvalidLabelLDH, }, "label 2989 starts with '-'"}, {"InvalidLabelLDH end", &ident.InvalidLabelError{ Data: []byte{0, '-'}, Label: 0xbad, Index: 1, Reason: ident.InvalidLabelLDH, }, "label 2989 ends with '-'"}, {"InvalidLabelLDH", &ident.InvalidLabelError{ Data: []byte{0}, Label: 0xbad, Index: 0, Reason: ident.InvalidLabelLDH, }, `label 2989 contains invalid byte '\x00' at index 0`}, {"InvalidLabelShort", &ident.InvalidLabelError{ Label: 0xf00d, Reason: ident.InvalidLabelShort, }, "label 61453 is empty"}, {"InvalidLabelLong", &ident.InvalidLabelError{ Label: 0xf00d, Reason: ident.InvalidLabelLong, }, "label 61453 is longer than 63 bytes"}, {"InvalidLabelError", &ident.InvalidLabelError{ Label: 0xcafe, Reason: 0xbadf00d, }, "invalid label 51966 at byte 0"}, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { t.Parallel() if got := tc.err.Error(); got != tc.want { t.Errorf("Error: %q, want %q", got, tc.want) } }) } }