Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
50cf0f07b7 | ||
|
|
d6f4cbb2d5 | ||
|
|
6e728a3df5 |
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
GNU gettext utilities for Go.
|
GNU gettext utilities for Go.
|
||||||
|
|
||||||
**Version: 0.9.0**
|
Version: [0.9.1](https://github.com/leonelquinteros/gotext/releases/tag/v0.9.1)
|
||||||
|
|
||||||
|
|
||||||
#Features
|
#Features
|
||||||
|
|||||||
@@ -63,3 +63,60 @@ msgstr[2] "And this is the second plural form: %s"
|
|||||||
t.Errorf("Expected 'And this is the second plural form: Variable' but got '%s'", tr)
|
t.Errorf("Expected 'And this is the second plural form: Variable' but got '%s'", tr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPackageRace(t *testing.T) {
|
||||||
|
// Set PO content
|
||||||
|
str := `# Some comment
|
||||||
|
msgid "My text"
|
||||||
|
msgstr "Translated text"
|
||||||
|
|
||||||
|
# More comments
|
||||||
|
msgid "Another string"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "One with var: %s"
|
||||||
|
msgid_plural "Several with vars: %s"
|
||||||
|
msgstr[0] "This one is the singular: %s"
|
||||||
|
msgstr[1] "This one is the plural: %s"
|
||||||
|
msgstr[2] "And this is the second plural form: %s"
|
||||||
|
|
||||||
|
`
|
||||||
|
|
||||||
|
// Create Locales directory on default location
|
||||||
|
dirname := path.Clean(library + string(os.PathSeparator) + "en_US")
|
||||||
|
err := os.MkdirAll(dirname, os.ModePerm)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Can't create test directory: %s", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write PO content to default domain file
|
||||||
|
filename := path.Clean(dirname + string(os.PathSeparator) + domain + ".po")
|
||||||
|
|
||||||
|
f, err := os.Create(filename)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Can't create test file: %s", err.Error())
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
_, err = f.WriteString(str)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Can't write to test file: %s", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init sync channels
|
||||||
|
c1 := make(chan bool)
|
||||||
|
c2 := make(chan bool)
|
||||||
|
|
||||||
|
// Test translations
|
||||||
|
go func(done chan bool) {
|
||||||
|
println(Get("My text"))
|
||||||
|
done <- true
|
||||||
|
}(c1)
|
||||||
|
|
||||||
|
go func(done chan bool) {
|
||||||
|
println(Get("My text"))
|
||||||
|
done <- true
|
||||||
|
}(c2)
|
||||||
|
|
||||||
|
println(Get("My text"))
|
||||||
|
}
|
||||||
|
|||||||
11
locale.go
11
locale.go
@@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -42,6 +43,9 @@ type Locale struct {
|
|||||||
|
|
||||||
// List of available domains for this locale.
|
// List of available domains for this locale.
|
||||||
domains map[string]*Po
|
domains map[string]*Po
|
||||||
|
|
||||||
|
// Sync Mutex
|
||||||
|
sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewLocale creates and initializes a new Locale object for a given language.
|
// NewLocale creates and initializes a new Locale object for a given language.
|
||||||
@@ -73,6 +77,9 @@ func (l *Locale) AddDomain(dom string) {
|
|||||||
po.ParseFile(filename)
|
po.ParseFile(filename)
|
||||||
|
|
||||||
// Save new domain
|
// Save new domain
|
||||||
|
l.Lock()
|
||||||
|
defer l.Unlock()
|
||||||
|
|
||||||
if l.domains == nil {
|
if l.domains == nil {
|
||||||
l.domains = make(map[string]*Po)
|
l.domains = make(map[string]*Po)
|
||||||
}
|
}
|
||||||
@@ -102,6 +109,10 @@ func (l *Locale) GetD(dom, str string, vars ...interface{}) string {
|
|||||||
// If n == 0, usually the singular form of the string is returned as defined in the PO file.
|
// If n == 0, usually the singular form of the string is returned as defined in the PO file.
|
||||||
// Supports optional parameters (vars... interface{}) to be inserted on the formatted string using the fmt.Printf syntax.
|
// Supports optional parameters (vars... interface{}) to be inserted on the formatted string using the fmt.Printf syntax.
|
||||||
func (l *Locale) GetND(dom, str, plural string, n int, vars ...interface{}) string {
|
func (l *Locale) GetND(dom, str, plural string, n int, vars ...interface{}) string {
|
||||||
|
// Sync read
|
||||||
|
l.RLock()
|
||||||
|
defer l.RUnlock()
|
||||||
|
|
||||||
if l.domains != nil {
|
if l.domains != nil {
|
||||||
if _, ok := l.domains[dom]; ok {
|
if _, ok := l.domains[dom]; ok {
|
||||||
if l.domains[dom] != nil {
|
if l.domains[dom] != nil {
|
||||||
|
|||||||
@@ -69,3 +69,69 @@ msgstr[2] "And this is the second plural form: %s"
|
|||||||
t.Errorf("Expected 'And this is the second plural form: Variable' but got '%s'", tr)
|
t.Errorf("Expected 'And this is the second plural form: Variable' but got '%s'", tr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLocaleRace(t *testing.T) {
|
||||||
|
// Set PO content
|
||||||
|
str := `# Some comment
|
||||||
|
msgid "My text"
|
||||||
|
msgstr "Translated text"
|
||||||
|
|
||||||
|
# More comments
|
||||||
|
msgid "Another string"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "One with var: %s"
|
||||||
|
msgid_plural "Several with vars: %s"
|
||||||
|
msgstr[0] "This one is the singular: %s"
|
||||||
|
msgstr[1] "This one is the plural: %s"
|
||||||
|
msgstr[2] "And this is the second plural form: %s"
|
||||||
|
|
||||||
|
`
|
||||||
|
|
||||||
|
// Create Locales directory with simplified language code
|
||||||
|
dirname := path.Clean("/tmp" + string(os.PathSeparator) + "es")
|
||||||
|
err := os.MkdirAll(dirname, os.ModePerm)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Can't create test directory: %s", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write PO content to file
|
||||||
|
filename := path.Clean(dirname + string(os.PathSeparator) + "race.po")
|
||||||
|
|
||||||
|
f, err := os.Create(filename)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Can't create test file: %s", err.Error())
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
_, err = f.WriteString(str)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Can't write to test file: %s", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create Locale with full language code
|
||||||
|
l := NewLocale("/tmp", "es")
|
||||||
|
|
||||||
|
// Init sync channels
|
||||||
|
ac := make(chan bool)
|
||||||
|
rc := make(chan bool)
|
||||||
|
|
||||||
|
// Add domain in goroutine
|
||||||
|
go func(l *Locale, done chan bool) {
|
||||||
|
l.AddDomain("race")
|
||||||
|
done <- true
|
||||||
|
}(l, ac)
|
||||||
|
|
||||||
|
// Get translations in goroutine
|
||||||
|
go func(l *Locale, done chan bool) {
|
||||||
|
println(l.GetD("race", "My text"))
|
||||||
|
done <- true
|
||||||
|
}(l, rc)
|
||||||
|
|
||||||
|
// Get translations at top level
|
||||||
|
println(l.GetD("race", "My text"))
|
||||||
|
|
||||||
|
// Wait for goroutines to finish
|
||||||
|
<-ac
|
||||||
|
<-rc
|
||||||
|
}
|
||||||
|
|||||||
8
po.go
8
po.go
@@ -186,6 +186,10 @@ func (po *Po) Parse(str string) {
|
|||||||
// Get retrieves the corresponding translation for the given string.
|
// Get retrieves the corresponding translation for the given string.
|
||||||
// Supports optional parameters (vars... interface{}) to be inserted on the formatted string using the fmt.Printf syntax.
|
// Supports optional parameters (vars... interface{}) to be inserted on the formatted string using the fmt.Printf syntax.
|
||||||
func (po *Po) Get(str string, vars ...interface{}) string {
|
func (po *Po) Get(str string, vars ...interface{}) string {
|
||||||
|
// Sync read
|
||||||
|
po.RLock()
|
||||||
|
defer po.RUnlock()
|
||||||
|
|
||||||
if po.translations != nil {
|
if po.translations != nil {
|
||||||
if _, ok := po.translations[str]; ok {
|
if _, ok := po.translations[str]; ok {
|
||||||
return fmt.Sprintf(po.translations[str].get(), vars...)
|
return fmt.Sprintf(po.translations[str].get(), vars...)
|
||||||
@@ -200,6 +204,10 @@ func (po *Po) Get(str string, vars ...interface{}) string {
|
|||||||
// If n == 0, usually the singular form of the string is returned as defined in the PO file.
|
// If n == 0, usually the singular form of the string is returned as defined in the PO file.
|
||||||
// Supports optional parameters (vars... interface{}) to be inserted on the formatted string using the fmt.Printf syntax.
|
// Supports optional parameters (vars... interface{}) to be inserted on the formatted string using the fmt.Printf syntax.
|
||||||
func (po *Po) GetN(str, plural string, n int, vars ...interface{}) string {
|
func (po *Po) GetN(str, plural string, n int, vars ...interface{}) string {
|
||||||
|
// Sync read
|
||||||
|
po.RLock()
|
||||||
|
defer po.RUnlock()
|
||||||
|
|
||||||
if po.translations != nil {
|
if po.translations != nil {
|
||||||
if _, ok := po.translations[str]; ok {
|
if _, ok := po.translations[str]; ok {
|
||||||
return fmt.Sprintf(po.translations[str].getN(n), vars...)
|
return fmt.Sprintf(po.translations[str].getN(n), vars...)
|
||||||
|
|||||||
45
po_test.go
45
po_test.go
@@ -59,3 +59,48 @@ msgstr[2] "And this is the second plural form: %s"
|
|||||||
t.Errorf("Expected 'And this is the second plural form: Variable' but got '%s'", tr)
|
t.Errorf("Expected 'And this is the second plural form: Variable' but got '%s'", tr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPoRace(t *testing.T) {
|
||||||
|
// Set PO content
|
||||||
|
str := `# Some comment
|
||||||
|
msgid "My text"
|
||||||
|
msgstr "Translated text"
|
||||||
|
|
||||||
|
# More comments
|
||||||
|
msgid "Another string"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "One with var: %s"
|
||||||
|
msgid_plural "Several with vars: %s"
|
||||||
|
msgstr[0] "This one is the singular: %s"
|
||||||
|
msgstr[1] "This one is the plural: %s"
|
||||||
|
msgstr[2] "And this is the second plural form: %s"
|
||||||
|
|
||||||
|
`
|
||||||
|
|
||||||
|
// Create Po object
|
||||||
|
po := new(Po)
|
||||||
|
|
||||||
|
// Create sync channels
|
||||||
|
pc := make(chan bool)
|
||||||
|
rc := make(chan bool)
|
||||||
|
|
||||||
|
// Parse po content in a goroutine
|
||||||
|
go func(po *Po, done chan bool) {
|
||||||
|
po.Parse(str)
|
||||||
|
done <- true
|
||||||
|
}(po, pc)
|
||||||
|
|
||||||
|
// Read some translation on a goroutine
|
||||||
|
go func(po *Po, done chan bool) {
|
||||||
|
println(po.Get("My text"))
|
||||||
|
done <- true
|
||||||
|
}(po, rc)
|
||||||
|
|
||||||
|
// Read something at top level
|
||||||
|
println(po.Get("My text"))
|
||||||
|
|
||||||
|
// Wait for goroutines to finish
|
||||||
|
<-pc
|
||||||
|
<-rc
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user