test(i18n): cover ParseLocale cases (#1293)

supperShen created

## What?

Adds table-driven tests for `ParseLocale` covering:

- plain, hyphenated, and underscored English locale inputs
- fallback behavior for an unregistered language
- invalid empty and malformed locale inputs

## Why?

`ParseLocale` is a small public i18n helper with no dedicated tests. The
new tests lock down locale normalization, fallback direction, and
invalid-input behavior before more locale work is added.

Fixes #1075

Change summary

i18n/locale_test.go | 89 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 89 insertions(+)

Detailed changes

i18n/locale_test.go 🔗

@@ -0,0 +1,89 @@
+package i18n
+
+import (
+	"errors"
+	"testing"
+
+	"golang.org/x/text/language"
+)
+
+func TestParseLocale(t *testing.T) {
+	RegisterLanguage(&Locale{
+		Tag:        language.Arabic,
+		Code:       "ar",
+		Name:       "Arabic",
+		NativeName: "Arabic",
+		Direction:  "rtl",
+		PluralFunc: ArabicPlural,
+	})
+
+	tests := []struct {
+		name          string
+		code          string
+		wantCode      string
+		wantDirection string
+		wantErr       error
+	}{
+		{
+			name:          "language code",
+			code:          "en",
+			wantCode:      "en",
+			wantDirection: "ltr",
+		},
+		{
+			name:          "hyphenated region",
+			code:          "en-US",
+			wantCode:      "en",
+			wantDirection: "ltr",
+		},
+		{
+			name:          "underscored region",
+			code:          "en_US",
+			wantCode:      "en",
+			wantDirection: "ltr",
+		},
+		{
+			name:          "unregistered language fallback",
+			code:          "eo",
+			wantCode:      "eo",
+			wantDirection: "ltr",
+		},
+		{
+			name:          "registered rtl language",
+			code:          "ar",
+			wantCode:      "ar",
+			wantDirection: "rtl",
+		},
+		{
+			name:    "empty code",
+			code:    "",
+			wantErr: ErrInvalidLocale,
+		},
+		{
+			name:    "malformed code",
+			code:    "@@@",
+			wantErr: ErrInvalidLocale,
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			locale, err := ParseLocale(tt.code)
+			if tt.wantErr != nil {
+				if !errors.Is(err, tt.wantErr) {
+					t.Fatalf("ParseLocale(%q) error = %v, want %v", tt.code, err, tt.wantErr)
+				}
+				return
+			}
+			if err != nil {
+				t.Fatalf("ParseLocale(%q) returned error: %v", tt.code, err)
+			}
+			if locale.Code != tt.wantCode {
+				t.Errorf("ParseLocale(%q).Code = %q, want %q", tt.code, locale.Code, tt.wantCode)
+			}
+			if locale.Direction != tt.wantDirection {
+				t.Errorf("ParseLocale(%q).Direction = %q, want %q", tt.code, locale.Direction, tt.wantDirection)
+			}
+		})
+	}
+}