diff --git a/hooks_test.go b/hooks_test.go index d6c78b0..7727fb6 100644 --- a/hooks_test.go +++ b/hooks_test.go @@ -1,6 +1,7 @@ package i18n import ( + "sync" "testing" "testing/fstest" @@ -72,6 +73,43 @@ func TestRegisterLocales_Good_AfterLocalesLoaded(t *testing.T) { assert.Equal(t, "arrived late", got) } +func TestInit_LoadsRegisteredLocales(t *testing.T) { + // Save and restore global service state. + registeredLocalesMu.Lock() + savedLocales := registeredLocales + savedLoaded := localesLoaded + registeredLocales = nil + localesLoaded = false + registeredLocalesMu.Unlock() + + defaultOnce = sync.Once{} + defaultService.Store(nil) + + defer func() { + registeredLocalesMu.Lock() + registeredLocales = savedLocales + localesLoaded = savedLoaded + registeredLocalesMu.Unlock() + defaultService.Store(nil) + defaultOnce = sync.Once{} + }() + + fs := fstest.MapFS{ + "locales/en.json": &fstest.MapFile{ + Data: []byte(`{"init.registered": "loaded on init"}`), + }, + } + RegisterLocales(fs, "locales") + + require.NoError(t, Init()) + + svc := Default() + require.NotNil(t, svc) + + got := svc.T("init.registered") + assert.Equal(t, "loaded on init", got) +} + func TestLoadRegisteredLocales_Good(t *testing.T) { svc, err := New() require.NoError(t, err) diff --git a/service.go b/service.go index b06714a..20a33bd 100644 --- a/service.go +++ b/service.go @@ -136,9 +136,15 @@ func Init() error { } svc, err := New() if err == nil { + // Register and load any locales queued before initialisation. + loadRegisteredLocales(svc) // CAS prevents overwriting a concurrent SetDefault call that // raced between the Load check above and this store. - defaultService.CompareAndSwap(nil, svc) + if !defaultService.CompareAndSwap(nil, svc) { + // If a concurrent caller already installed a service, load + // registered locales into that active default service instead. + loadRegisteredLocales(defaultService.Load()) + } } defaultErr = err })