fix(i18n): preserve structured missing-key args
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
a1a7b2d6fe
commit
be1cf9bba8
2 changed files with 84 additions and 6 deletions
|
|
@ -208,6 +208,55 @@ func TestOnMissingKey_Good(t *testing.T) {
|
|||
assert.Equal(t, "hooks_test.go", filepath.Base(captured.CallerFile))
|
||||
}
|
||||
|
||||
func TestOnMissingKey_Good_SubjectArgs(t *testing.T) {
|
||||
svc, err := New()
|
||||
require.NoError(t, err)
|
||||
prev := Default()
|
||||
SetDefault(svc)
|
||||
t.Cleanup(func() {
|
||||
SetDefault(prev)
|
||||
})
|
||||
svc.SetMode(ModeCollect)
|
||||
|
||||
var captured MissingKey
|
||||
OnMissingKey(func(m MissingKey) {
|
||||
captured = m
|
||||
})
|
||||
|
||||
_ = T("missing.subject.key", S("file", "config.yaml").Count(3).In("workspace").Formal())
|
||||
|
||||
assert.Equal(t, "missing.subject.key", captured.Key)
|
||||
assert.Equal(t, "config.yaml", captured.Args["Subject"])
|
||||
assert.Equal(t, "file", captured.Args["Noun"])
|
||||
assert.Equal(t, 3, captured.Args["Count"])
|
||||
assert.Equal(t, "workspace", captured.Args["Location"])
|
||||
assert.Equal(t, FormalityFormal, captured.Args["Formality"])
|
||||
}
|
||||
|
||||
func TestOnMissingKey_Good_TranslationContextArgs(t *testing.T) {
|
||||
svc, err := New()
|
||||
require.NoError(t, err)
|
||||
prev := Default()
|
||||
SetDefault(svc)
|
||||
t.Cleanup(func() {
|
||||
SetDefault(prev)
|
||||
})
|
||||
svc.SetMode(ModeCollect)
|
||||
|
||||
var captured MissingKey
|
||||
OnMissingKey(func(m MissingKey) {
|
||||
captured = m
|
||||
})
|
||||
|
||||
_ = T("missing.context.key", C("navigation").WithGender("feminine").In("workspace").Formal())
|
||||
|
||||
assert.Equal(t, "missing.context.key", captured.Key)
|
||||
assert.Equal(t, "navigation", captured.Args["Context"])
|
||||
assert.Equal(t, "feminine", captured.Args["Gender"])
|
||||
assert.Equal(t, "workspace", captured.Args["Location"])
|
||||
assert.Equal(t, FormalityFormal, captured.Args["Formality"])
|
||||
}
|
||||
|
||||
func TestDispatchMissingKey_Good_NoHandler(t *testing.T) {
|
||||
// Store nil handler (using correct type)
|
||||
missingKeyHandler.Store(MissingKeyHandler(nil))
|
||||
|
|
|
|||
41
service.go
41
service.go
|
|
@ -545,12 +545,7 @@ func (s *Service) handleMissingKey(key string, args []any) string {
|
|||
case ModeStrict:
|
||||
panic(core.Sprintf("i18n: missing translation key %q", key))
|
||||
case ModeCollect:
|
||||
var argsMap map[string]any
|
||||
if len(args) > 0 {
|
||||
if m, ok := args[0].(map[string]any); ok {
|
||||
argsMap = m
|
||||
}
|
||||
}
|
||||
argsMap := missingKeyArgs(args)
|
||||
dispatchMissingKey(key, argsMap)
|
||||
return "[" + key + "]"
|
||||
default:
|
||||
|
|
@ -558,6 +553,40 @@ func (s *Service) handleMissingKey(key string, args []any) string {
|
|||
}
|
||||
}
|
||||
|
||||
func missingKeyArgs(args []any) map[string]any {
|
||||
if len(args) == 0 {
|
||||
return nil
|
||||
}
|
||||
switch v := args[0].(type) {
|
||||
case map[string]any:
|
||||
return v
|
||||
case *TranslationContext:
|
||||
return missingKeyContextArgs(v)
|
||||
case *Subject:
|
||||
return missingKeySubjectArgs(v)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func missingKeyContextArgs(ctx *TranslationContext) map[string]any {
|
||||
if ctx == nil {
|
||||
return nil
|
||||
}
|
||||
data := templateDataForRendering(ctx)
|
||||
result, _ := data.(map[string]any)
|
||||
return result
|
||||
}
|
||||
|
||||
func missingKeySubjectArgs(subj *Subject) map[string]any {
|
||||
if subj == nil {
|
||||
return nil
|
||||
}
|
||||
data := templateDataForRendering(subj)
|
||||
result, _ := data.(map[string]any)
|
||||
return result
|
||||
}
|
||||
|
||||
// Raw translates without i18n.* namespace magic.
|
||||
func (s *Service) Raw(messageID string, args ...any) string {
|
||||
s.mu.RLock()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue