go-i18n/time_test.go
Claude 32a55f5d35
test(i18n): add tests for 8 uncovered files, coverage 69.9% -> 86.6%
Add dedicated test files for compose.go, context.go, debug.go, hooks.go,
i18n.go, localise.go, time.go, and transform.go. Uses testify
assert/require with table-driven tests and Good/Bad/Ugly naming.

Key coverage improvements:
- transform.go: toInt/toInt64/toFloat64 18.8% -> 100%
- time.go: TimeAgo/FormatAgo 0% -> 100%/87.5%
- compose.go: newTemplateData/SetFormality/IsInformal 0% -> 100%
- context.go: all functions now 100%
- debug.go: package-level SetDebug 0% -> 100%
- hooks.go: RegisterLocales 0% -> 100%
- i18n.go: T/Raw/N/SetMode/AddHandler/PrependHandler all covered

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 02:09:08 +00:00

132 lines
3 KiB
Go

package i18n
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// --- TimeAgo ---
func TestTimeAgo_Good(t *testing.T) {
svc, err := New()
require.NoError(t, err)
SetDefault(svc)
tests := []struct {
name string
duration time.Duration
contains string
}{
{"just_now", 5 * time.Second, "just now"},
{"minutes_ago", 5 * time.Minute, "5 minutes ago"},
{"hours_ago", 3 * time.Hour, "3 hours ago"},
{"days_ago", 2 * 24 * time.Hour, "2 days ago"},
{"weeks_ago", 3 * 7 * 24 * time.Hour, "3 weeks ago"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := TimeAgo(time.Now().Add(-tt.duration))
assert.Contains(t, got, tt.contains)
})
}
}
func TestTimeAgo_Good_EdgeCases(t *testing.T) {
svc, err := New()
require.NoError(t, err)
SetDefault(svc)
// Just under 1 minute
got := TimeAgo(time.Now().Add(-59 * time.Second))
assert.Contains(t, got, "just now")
// Exactly 1 minute
got = TimeAgo(time.Now().Add(-60 * time.Second))
assert.Contains(t, got, "minute")
// Just under 1 hour
got = TimeAgo(time.Now().Add(-59 * time.Minute))
assert.Contains(t, got, "minutes ago")
// Just under 1 day
got = TimeAgo(time.Now().Add(-23 * time.Hour))
assert.Contains(t, got, "hours ago")
// Just under 1 week
got = TimeAgo(time.Now().Add(-6 * 24 * time.Hour))
assert.Contains(t, got, "days ago")
}
func TestTimeAgo_Good_SingleUnits(t *testing.T) {
svc, err := New()
require.NoError(t, err)
SetDefault(svc)
// 1 minute ago
got := TimeAgo(time.Now().Add(-1 * time.Minute))
assert.Contains(t, got, "1 minute ago")
// 1 hour ago
got = TimeAgo(time.Now().Add(-1 * time.Hour))
assert.Contains(t, got, "1 hour ago")
// 1 day ago
got = TimeAgo(time.Now().Add(-24 * time.Hour))
assert.Contains(t, got, "1 day ago")
// 1 week ago
got = TimeAgo(time.Now().Add(-7 * 24 * time.Hour))
assert.Contains(t, got, "1 week ago")
}
// --- FormatAgo ---
func TestFormatAgo_Good(t *testing.T) {
svc, err := New()
require.NoError(t, err)
SetDefault(svc)
tests := []struct {
name string
count int
unit string
want string
}{
{"1_second", 1, "second", "1 second ago"},
{"5_seconds", 5, "second", "5 seconds ago"},
{"1_minute", 1, "minute", "1 minute ago"},
{"30_minutes", 30, "minute", "30 minutes ago"},
{"1_hour", 1, "hour", "1 hour ago"},
{"12_hours", 12, "hour", "12 hours ago"},
{"1_day", 1, "day", "1 day ago"},
{"7_days", 7, "day", "7 days ago"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := FormatAgo(tt.count, tt.unit)
assert.Equal(t, tt.want, got)
})
}
}
func TestFormatAgo_Bad_UnknownUnit(t *testing.T) {
svc, err := New()
require.NoError(t, err)
SetDefault(svc)
// Unknown unit should fallback to programmatic format
got := FormatAgo(5, "fortnight")
assert.Equal(t, "5 fortnights ago", got)
}
func TestFormatAgo_Good_SingularUnit(t *testing.T) {
svc, err := New()
require.NoError(t, err)
SetDefault(svc)
got := FormatAgo(1, "fortnight")
assert.Equal(t, "1 fortnight ago", got)
}