feat(html): add cloneable context data helpers
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
9a90819aaf
commit
c56924d95c
2 changed files with 75 additions and 0 deletions
28
context.go
28
context.go
|
|
@ -21,6 +21,23 @@ type Context struct {
|
|||
service Translator
|
||||
}
|
||||
|
||||
// Clone returns a shallow copy of the context with an independent Data map.
|
||||
// Example: next := ctx.Clone().SetData("theme", "dark").
|
||||
func (ctx *Context) Clone() *Context {
|
||||
if ctx == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
clone := *ctx
|
||||
if ctx.Data != nil {
|
||||
clone.Data = make(map[string]any, len(ctx.Data))
|
||||
for key, value := range ctx.Data {
|
||||
clone.Data[key] = value
|
||||
}
|
||||
}
|
||||
return &clone
|
||||
}
|
||||
|
||||
func applyLocaleToService(svc Translator, locale string) {
|
||||
if svc == nil || locale == "" {
|
||||
return
|
||||
|
|
@ -127,6 +144,17 @@ func (ctx *Context) SetData(key string, value any) *Context {
|
|||
return ctx
|
||||
}
|
||||
|
||||
// WithData returns a cloned context with one additional data value set.
|
||||
// Example: next := ctx.WithData("theme", "dark").
|
||||
func (ctx *Context) WithData(key string, value any) *Context {
|
||||
clone := ctx.Clone()
|
||||
if clone == nil {
|
||||
return nil
|
||||
}
|
||||
clone.SetData(key, value)
|
||||
return clone
|
||||
}
|
||||
|
||||
// SetLocale updates the context locale and reapplies it to the active
|
||||
// translator.
|
||||
// Example: ctx.SetLocale("en-US").
|
||||
|
|
|
|||
|
|
@ -134,6 +134,53 @@ func TestContext_SetData_InitialisesNilMap(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestContext_CloneCopiesDataWithoutSharingMap(t *testing.T) {
|
||||
svc := &localeTranslator{}
|
||||
ctx := NewContextWithService(svc, "en-GB")
|
||||
ctx.SetIdentity("user-123")
|
||||
ctx.SetData("theme", "dark")
|
||||
|
||||
clone := ctx.Clone()
|
||||
|
||||
if clone == ctx {
|
||||
t.Fatal("Clone should return a distinct context instance")
|
||||
}
|
||||
if clone.service != ctx.service {
|
||||
t.Fatal("Clone should preserve the active translator")
|
||||
}
|
||||
if clone.Locale != ctx.Locale {
|
||||
t.Fatalf("Clone should preserve locale, got %q want %q", clone.Locale, ctx.Locale)
|
||||
}
|
||||
if clone.Identity != ctx.Identity {
|
||||
t.Fatalf("Clone should preserve identity, got %q want %q", clone.Identity, ctx.Identity)
|
||||
}
|
||||
|
||||
clone.SetData("theme", "light")
|
||||
if got := ctx.Data["theme"]; got != "dark" {
|
||||
t.Fatalf("Clone should not share Data map with original, got %v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestContext_WithDataReturnsClonedContext(t *testing.T) {
|
||||
ctx := NewContext()
|
||||
ctx.SetData("theme", "dark")
|
||||
|
||||
next := ctx.WithData("locale", "fr-FR")
|
||||
|
||||
if next == ctx {
|
||||
t.Fatal("WithData should return a cloned context")
|
||||
}
|
||||
if got := ctx.Data["locale"]; got != nil {
|
||||
t.Fatalf("WithData should not mutate the original context, got %v", got)
|
||||
}
|
||||
if got := next.Data["locale"]; got != "fr-FR" {
|
||||
t.Fatalf("WithData should set the requested value on the clone, got %v", got)
|
||||
}
|
||||
if got := next.Data["theme"]; got != "dark" {
|
||||
t.Fatalf("WithData should preserve existing data on the clone, got %v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestContext_Setters_NilReceiver(t *testing.T) {
|
||||
var ctx *Context
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue