2018-03-23 20:17:05 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2018 DeineAgentur UG https://www.deineagentur.com. All rights reserved.
|
|
|
|
* Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
|
|
|
*/
|
|
|
|
|
2016-06-19 22:36:33 +00:00
|
|
|
package gotext
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
"path"
|
|
|
|
"testing"
|
2023-03-17 10:29:18 +00:00
|
|
|
"testing/fstest"
|
2016-06-19 22:36:33 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestLocale(t *testing.T) {
|
|
|
|
// Set PO content
|
2016-07-15 22:04:59 +00:00
|
|
|
str := `
|
2017-09-08 21:08:56 +00:00
|
|
|
msgid ""
|
|
|
|
msgstr ""
|
2016-07-15 22:04:59 +00:00
|
|
|
# Initial comment
|
|
|
|
# Headers below
|
|
|
|
"Language: en\n"
|
|
|
|
"Content-Type: text/plain; charset=UTF-8\n"
|
|
|
|
"Content-Transfer-Encoding: 8bit\n"
|
|
|
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
|
|
|
|
|
|
|
# Some comment
|
2016-06-19 22:36:33 +00:00
|
|
|
msgid "My text"
|
|
|
|
msgstr "Translated text"
|
|
|
|
|
|
|
|
# More comments
|
|
|
|
msgid "Another string"
|
|
|
|
msgstr ""
|
|
|
|
|
|
|
|
msgid "One with var: %s"
|
2016-06-23 14:41:38 +00:00
|
|
|
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"
|
2016-06-19 22:36:33 +00:00
|
|
|
|
2016-06-26 18:43:54 +00:00
|
|
|
msgid "This one has invalid syntax translations"
|
|
|
|
msgid_plural "Plural index"
|
|
|
|
msgstr[abc] "Wrong index"
|
|
|
|
msgstr[1 "Forgot to close brackets"
|
|
|
|
msgstr[0] "Badly formatted string'
|
|
|
|
|
|
|
|
msgctxt "Ctx"
|
|
|
|
msgid "One with var: %s"
|
|
|
|
msgid_plural "Several with vars: %s"
|
|
|
|
msgstr[0] "This one is the singular in a Ctx context: %s"
|
|
|
|
msgstr[1] "This one is the plural in a Ctx context: %s"
|
|
|
|
|
|
|
|
msgid "Some random"
|
2018-03-23 20:17:05 +00:00
|
|
|
msgstr "Some random Translation"
|
2016-06-26 18:43:54 +00:00
|
|
|
|
|
|
|
msgctxt "Ctx"
|
|
|
|
msgid "Some random in a context"
|
2018-03-23 20:17:05 +00:00
|
|
|
msgstr "Some random Translation in a context"
|
2016-06-26 18:43:54 +00:00
|
|
|
|
|
|
|
msgid "More"
|
2018-03-23 20:17:05 +00:00
|
|
|
msgstr "More Translation"
|
2016-06-26 18:43:54 +00:00
|
|
|
|
2017-05-29 09:36:18 +00:00
|
|
|
`
|
2016-06-19 22:36:33 +00:00
|
|
|
|
2023-03-17 10:29:18 +00:00
|
|
|
var locales []*Locale
|
|
|
|
{ // test os
|
|
|
|
// Create Locales directory with simplified language code
|
|
|
|
dirname := path.Join("/tmp", "en", "LC_MESSAGES")
|
|
|
|
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.Join(dirname, "my_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())
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create Locale with full language code
|
|
|
|
locales = append(locales, NewLocale("/tmp", "en_US"))
|
|
|
|
}
|
|
|
|
{ // test fs
|
|
|
|
fs := make(fstest.MapFS)
|
|
|
|
fs["en/LC_MESSAGES/my_domain.po"] = &fstest.MapFile{Data: []byte(str)}
|
|
|
|
locales = append(locales, NewLocaleFS("en_US", fs))
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, l := range locales {
|
|
|
|
// Force nil domain storage
|
|
|
|
l.Domains = nil
|
|
|
|
|
|
|
|
// Add domain
|
|
|
|
l.AddDomain("my_domain")
|
|
|
|
|
|
|
|
// Test translations
|
|
|
|
tr := l.GetD("my_domain", "My text")
|
|
|
|
if tr != translatedText {
|
|
|
|
t.Errorf("Expected '%s' but got '%s'", translatedText, tr)
|
|
|
|
}
|
|
|
|
|
|
|
|
v := "Variable"
|
|
|
|
tr = l.GetD("my_domain", "One with var: %s", v)
|
|
|
|
if tr != "This one is the singular: Variable" {
|
|
|
|
t.Errorf("Expected 'This one is the singular: Variable' but got '%s'", tr)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test plural
|
|
|
|
tr = l.GetND("my_domain", "One with var: %s", "Several with vars: %s", 7, v)
|
|
|
|
if tr != "This one is the plural: Variable" {
|
|
|
|
t.Errorf("Expected 'This one is the plural: Variable' but got '%s'", tr)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test context translations
|
|
|
|
tr = l.GetC("Some random in a context", "Ctx")
|
|
|
|
if tr != "Some random Translation in a context" {
|
|
|
|
t.Errorf("Expected 'Some random Translation in a context'. Got '%s'", tr)
|
|
|
|
}
|
|
|
|
|
|
|
|
v = "Test"
|
|
|
|
tr = l.GetNC("One with var: %s", "Several with vars: %s", 23, "Ctx", v)
|
|
|
|
if tr != "This one is the plural in a Ctx context: Test" {
|
|
|
|
t.Errorf("Expected 'This one is the plural in a Ctx context: Test'. Got '%s'", tr)
|
|
|
|
}
|
|
|
|
|
|
|
|
tr = l.GetDC("my_domain", "One with var: %s", "Ctx", v)
|
|
|
|
if tr != "This one is the singular in a Ctx context: Test" {
|
|
|
|
t.Errorf("Expected 'This one is the singular in a Ctx context: Test' but got '%s'", tr)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test plural
|
|
|
|
tr = l.GetNDC("my_domain", "One with var: %s", "Several with vars: %s", 3, "Ctx", v)
|
|
|
|
if tr != "This one is the plural in a Ctx context: Test" {
|
|
|
|
t.Errorf("Expected 'This one is the plural in a Ctx context: Test' but got '%s'", tr)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test last Translation
|
|
|
|
tr = l.GetD("my_domain", "More")
|
|
|
|
if tr != "More Translation" {
|
|
|
|
t.Errorf("Expected 'More Translation' but got '%s'", tr)
|
|
|
|
}
|
2016-08-08 14:36:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestLocaleFails(t *testing.T) {
|
|
|
|
// Set PO content
|
|
|
|
str := `
|
|
|
|
msgid ""
|
|
|
|
msgstr ""
|
|
|
|
# Initial comment
|
|
|
|
# Headers below
|
|
|
|
"Language: en\n"
|
|
|
|
"Content-Type: text/plain; charset=UTF-8\n"
|
|
|
|
"Content-Transfer-Encoding: 8bit\n"
|
|
|
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
|
|
|
|
|
|
|
# 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"
|
|
|
|
|
|
|
|
msgid "This one has invalid syntax translations"
|
|
|
|
msgid_plural "Plural index"
|
|
|
|
msgstr[abc] "Wrong index"
|
|
|
|
msgstr[1 "Forgot to close brackets"
|
|
|
|
msgstr[0] "Badly formatted string'
|
|
|
|
|
|
|
|
msgid "Invalid formatted id[] with no translations
|
|
|
|
|
|
|
|
msgctxt "Ctx"
|
|
|
|
msgid "One with var: %s"
|
|
|
|
msgid_plural "Several with vars: %s"
|
|
|
|
msgstr[0] "This one is the singular in a Ctx context: %s"
|
|
|
|
msgstr[1] "This one is the plural in a Ctx context: %s"
|
|
|
|
|
|
|
|
msgid "Some random"
|
2018-03-23 20:17:05 +00:00
|
|
|
msgstr "Some random Translation"
|
2016-08-08 14:36:05 +00:00
|
|
|
|
|
|
|
msgctxt "Ctx"
|
|
|
|
msgid "Some random in a context"
|
2018-03-23 20:17:05 +00:00
|
|
|
msgstr "Some random Translation in a context"
|
2016-08-08 14:36:05 +00:00
|
|
|
|
|
|
|
msgid "More"
|
2018-03-23 20:17:05 +00:00
|
|
|
msgstr "More Translation"
|
2016-08-08 14:36:05 +00:00
|
|
|
|
2017-05-29 09:36:18 +00:00
|
|
|
`
|
2016-08-08 14:36:05 +00:00
|
|
|
|
|
|
|
// Create Locales directory with simplified language code
|
|
|
|
dirname := path.Join("/tmp", "en", "LC_MESSAGES")
|
|
|
|
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.Join(dirname, "my_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())
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create Locale with full language code
|
|
|
|
l := NewLocale("/tmp", "en_US")
|
|
|
|
|
2023-05-07 23:23:20 +00:00
|
|
|
// Test language
|
|
|
|
language := l.GetLanguage()
|
|
|
|
if language != "en_US" {
|
|
|
|
t.Errorf("Expected 'en_US' but got '%s'", language)
|
|
|
|
}
|
|
|
|
|
2016-08-08 14:36:05 +00:00
|
|
|
// Force nil domain storage
|
2018-03-23 20:17:05 +00:00
|
|
|
l.Domains = nil
|
2016-08-08 14:36:05 +00:00
|
|
|
|
|
|
|
// Add domain
|
|
|
|
l.AddDomain("my_domain")
|
|
|
|
|
2018-03-23 20:17:05 +00:00
|
|
|
// Test non-existent "default" domain responses
|
|
|
|
tr := l.GetDomain()
|
|
|
|
if tr != "my_domain" {
|
|
|
|
t.Errorf("Expected 'my_domain' but got '%s'", tr)
|
|
|
|
}
|
|
|
|
|
2018-02-14 15:04:47 +00:00
|
|
|
// Set default domain to make it fail
|
2018-03-23 20:17:05 +00:00
|
|
|
l.SetDomain("default")
|
|
|
|
|
|
|
|
// Test non-existent "default" domain responses
|
|
|
|
tr = l.GetDomain()
|
|
|
|
if tr != "default" {
|
|
|
|
t.Errorf("Expected 'default' but got '%s'", tr)
|
|
|
|
}
|
2018-02-14 15:04:47 +00:00
|
|
|
|
2018-03-23 20:17:05 +00:00
|
|
|
// Test non-existent "default" domain responses
|
|
|
|
tr = l.Get("My text")
|
2016-06-26 14:54:28 +00:00
|
|
|
if tr != "My text" {
|
|
|
|
t.Errorf("Expected 'My text' but got '%s'", tr)
|
|
|
|
}
|
2016-06-26 15:15:08 +00:00
|
|
|
|
2016-08-08 14:36:05 +00:00
|
|
|
v := "Variable"
|
2016-06-26 14:54:28 +00:00
|
|
|
tr = l.GetN("One with var: %s", "Several with vars: %s", 2, v)
|
|
|
|
if tr != "Several with vars: Variable" {
|
|
|
|
t.Errorf("Expected 'Several with vars: Variable' but got '%s'", tr)
|
|
|
|
}
|
2016-06-26 18:43:54 +00:00
|
|
|
|
|
|
|
// Test inexistent translations
|
|
|
|
tr = l.Get("This is a test")
|
|
|
|
if tr != "This is a test" {
|
|
|
|
t.Errorf("Expected 'This is a test' but got '%s'", tr)
|
|
|
|
}
|
|
|
|
|
|
|
|
tr = l.GetN("This is a test", "This are tests", 1)
|
2019-10-21 17:43:48 +00:00
|
|
|
if tr != "This is a test" {
|
|
|
|
t.Errorf("Expected 'This is a test' but got '%s'", tr)
|
|
|
|
}
|
|
|
|
|
|
|
|
tr = l.GetN("This is a test", "This are tests", 7)
|
2016-06-26 18:43:54 +00:00
|
|
|
if tr != "This are tests" {
|
|
|
|
t.Errorf("Expected 'This are tests' but got '%s'", tr)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test syntax error parsed translations
|
|
|
|
tr = l.Get("This one has invalid syntax translations")
|
|
|
|
if tr != "This one has invalid syntax translations" {
|
|
|
|
t.Errorf("Expected 'This one has invalid syntax translations' but got '%s'", tr)
|
|
|
|
}
|
|
|
|
|
|
|
|
tr = l.GetN("This one has invalid syntax translations", "This are tests", 1)
|
2019-10-21 17:43:48 +00:00
|
|
|
if tr != "This one has invalid syntax translations" {
|
|
|
|
t.Errorf("Expected 'This one has invalid syntax translations' but got '%s'", tr)
|
|
|
|
}
|
|
|
|
tr = l.GetN("This one has invalid syntax translations", "This are tests", 2)
|
2016-06-26 18:43:54 +00:00
|
|
|
if tr != "This are tests" {
|
2019-10-21 17:43:48 +00:00
|
|
|
t.Errorf("Expected 'This are tests' but got '%s'", tr)
|
2016-06-26 18:43:54 +00:00
|
|
|
}
|
2018-03-23 20:17:05 +00:00
|
|
|
|
|
|
|
// Create Locale with full language code
|
|
|
|
l = NewLocale("/tmp", "golem")
|
|
|
|
|
2023-05-07 23:23:20 +00:00
|
|
|
// Test language
|
|
|
|
language = l.GetLanguage()
|
|
|
|
if language != "golem" {
|
|
|
|
t.Errorf("Expected 'golem' but got '%s'", language)
|
|
|
|
}
|
|
|
|
|
2018-03-23 20:17:05 +00:00
|
|
|
// Force nil domain storage
|
|
|
|
l.Domains = nil
|
|
|
|
|
|
|
|
// Add domain
|
|
|
|
l.SetDomain("my_domain")
|
|
|
|
|
|
|
|
// Test non-existent "default" domain responses
|
|
|
|
tr = l.GetDomain()
|
|
|
|
if tr != "my_domain" {
|
|
|
|
t.Errorf("Expected 'my_domain' but got '%s'", tr)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test syntax error parsed translations
|
|
|
|
tr = l.Get("This one has invalid syntax translations")
|
|
|
|
if tr != "This one has invalid syntax translations" {
|
|
|
|
t.Errorf("Expected 'This one has invalid syntax translations' but got '%s'", tr)
|
|
|
|
}
|
|
|
|
|
|
|
|
tr = l.GetN("This one has invalid syntax translations", "This are tests", 1)
|
2019-10-21 17:43:48 +00:00
|
|
|
if tr != "This one has invalid syntax translations" {
|
|
|
|
t.Errorf("Expected 'This one has invalid syntax translations' but got '%s'", tr)
|
|
|
|
}
|
|
|
|
tr = l.GetN("This one has invalid syntax translations", "This are tests", 111)
|
2018-03-23 20:17:05 +00:00
|
|
|
if tr != "This are tests" {
|
2019-10-21 17:43:48 +00:00
|
|
|
t.Errorf("Expected 'This are tests' but got '%s'", tr)
|
2018-03-23 20:17:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Create Locale with full language code
|
|
|
|
l = NewLocale("fixtures/", "fr_FR")
|
|
|
|
|
2023-05-07 23:23:20 +00:00
|
|
|
// Test language
|
|
|
|
language = l.GetLanguage()
|
|
|
|
if language != "fr_FR" {
|
|
|
|
t.Errorf("Expected 'fr_FR' but got '%s'", language)
|
|
|
|
}
|
|
|
|
|
2018-03-23 20:17:05 +00:00
|
|
|
// Force nil domain storage
|
|
|
|
l.Domains = nil
|
|
|
|
|
|
|
|
// Add domain
|
|
|
|
l.SetDomain("default")
|
|
|
|
|
|
|
|
// Test non-existent "default" domain responses
|
|
|
|
tr = l.GetDomain()
|
|
|
|
if tr != "default" {
|
|
|
|
t.Errorf("Expected 'my_domain' but got '%s'", tr)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test syntax error parsed translations
|
|
|
|
tr = l.Get("This one has invalid syntax translations")
|
|
|
|
if tr != "This one has invalid syntax translations" {
|
|
|
|
t.Errorf("Expected 'This one has invalid syntax translations' but got '%s'", tr)
|
|
|
|
}
|
|
|
|
|
|
|
|
tr = l.GetN("This one has invalid syntax translations", "This are tests", 1)
|
2019-10-21 17:43:48 +00:00
|
|
|
if tr != "This one has invalid syntax translations" {
|
|
|
|
t.Errorf("Expected 'This one has invalid syntax translations' but got '%s'", tr)
|
|
|
|
}
|
|
|
|
tr = l.GetN("This one has invalid syntax translations", "This are tests", 21)
|
2018-03-23 20:17:05 +00:00
|
|
|
if tr != "This are tests" {
|
2019-10-21 17:43:48 +00:00
|
|
|
t.Errorf("Expected 'This are tests' but got '%s'", tr)
|
2018-03-23 20:17:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Create Locale with full language code
|
|
|
|
l = NewLocale("fixtures/", "de_DE")
|
|
|
|
|
2023-05-07 23:23:20 +00:00
|
|
|
// Test language
|
|
|
|
language = l.GetLanguage()
|
|
|
|
if language != "de_DE" {
|
|
|
|
t.Errorf("Expected 'de_DE' but got '%s'", language)
|
|
|
|
}
|
|
|
|
|
2018-03-23 20:17:05 +00:00
|
|
|
// Force nil domain storage
|
|
|
|
l.Domains = nil
|
|
|
|
|
|
|
|
// Add domain
|
|
|
|
l.SetDomain("default")
|
|
|
|
|
|
|
|
// Test non-existent "default" domain responses
|
|
|
|
tr = l.GetDomain()
|
|
|
|
if tr != "default" {
|
|
|
|
t.Errorf("Expected 'my_domain' but got '%s'", tr)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test syntax error parsed translations
|
|
|
|
tr = l.Get("This one has invalid syntax translations")
|
|
|
|
if tr != "This one has invalid syntax translations" {
|
|
|
|
t.Errorf("Expected 'This one has invalid syntax translations' but got '%s'", tr)
|
|
|
|
}
|
|
|
|
|
|
|
|
tr = l.GetN("This one has invalid syntax translations", "This are tests", 1)
|
2019-10-21 17:43:48 +00:00
|
|
|
if tr != "This one has invalid syntax translations" {
|
|
|
|
t.Errorf("Expected 'This one has invalid syntax translations' but got '%s'", tr)
|
|
|
|
}
|
|
|
|
tr = l.GetN("This one has invalid syntax translations", "This are tests", 2)
|
2018-03-23 20:17:05 +00:00
|
|
|
if tr != "This are tests" {
|
2019-10-21 17:43:48 +00:00
|
|
|
t.Errorf("Expected 'This are tests' but got '%s'", tr)
|
2018-03-23 20:17:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Create Locale with full language code
|
|
|
|
l = NewLocale("fixtures/", "de_AT")
|
|
|
|
|
2023-05-07 23:23:20 +00:00
|
|
|
// Test language
|
|
|
|
language = l.GetLanguage()
|
|
|
|
if language != "de_AT" {
|
|
|
|
t.Errorf("Expected 'de_AT' but got '%s'", language)
|
|
|
|
}
|
|
|
|
|
2018-03-23 20:17:05 +00:00
|
|
|
// Force nil domain storage
|
|
|
|
l.Domains = nil
|
|
|
|
|
|
|
|
// Add domain
|
|
|
|
l.SetDomain("default")
|
|
|
|
|
|
|
|
// Test non-existent "default" domain responses
|
|
|
|
tr = l.GetDomain()
|
|
|
|
if tr != "default" {
|
|
|
|
t.Errorf("Expected 'my_domain' but got '%s'", tr)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test syntax error parsed translations
|
|
|
|
tr = l.Get("This one has invalid syntax translations")
|
|
|
|
if tr != "This one has invalid syntax translations" {
|
|
|
|
t.Errorf("Expected 'This one has invalid syntax translations' but got '%s'", tr)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test syntax error parsed translations
|
2018-07-05 14:37:25 +00:00
|
|
|
tr = l.GetNDC("mega", "This one has invalid syntax translations", "plural", 2, "ctx")
|
2018-03-23 20:17:05 +00:00
|
|
|
if tr != "plural" {
|
|
|
|
t.Errorf("Expected 'plural' but got '%s'", tr)
|
|
|
|
}
|
|
|
|
|
|
|
|
tr = l.GetN("This one has invalid syntax translations", "This are tests", 1)
|
2019-10-21 17:43:48 +00:00
|
|
|
if tr != "This one has invalid syntax translations" {
|
|
|
|
t.Errorf("Expected 'This one has invalid syntax translations' but got '%s'", tr)
|
|
|
|
}
|
|
|
|
tr = l.GetN("This one has invalid syntax translations", "This are tests", 14)
|
2018-03-23 20:17:05 +00:00
|
|
|
if tr != "This are tests" {
|
2019-10-21 17:43:48 +00:00
|
|
|
t.Errorf("Expected 'This are tests' but got '%s'", tr)
|
2018-03-23 20:17:05 +00:00
|
|
|
}
|
2016-06-19 22:36:33 +00:00
|
|
|
}
|
2016-06-24 20:45:12 +00:00
|
|
|
|
|
|
|
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"
|
|
|
|
|
2017-05-29 09:36:18 +00:00
|
|
|
`
|
2016-06-24 20:45:12 +00:00
|
|
|
|
2023-03-17 10:29:18 +00:00
|
|
|
var locales []*Locale
|
|
|
|
{ // test os
|
|
|
|
// Create Locales directory with simplified language code
|
|
|
|
dirname := path.Join("/tmp", "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.Join(dirname, "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
|
|
|
|
locales = append(locales, NewLocale("/tmp", "es"))
|
|
|
|
}
|
|
|
|
{ // test fs
|
|
|
|
fs := make(fstest.MapFS)
|
|
|
|
fs["es/LC_MESSAGES/race.po"] = &fstest.MapFile{Data: []byte(str)}
|
|
|
|
locales = append(locales, NewLocaleFS("es", fs))
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, l := range locales {
|
|
|
|
// 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) {
|
|
|
|
l.GetD("race", "My text")
|
|
|
|
done <- true
|
|
|
|
}(l, rc)
|
|
|
|
|
|
|
|
// Get translations at top level
|
2016-06-26 14:54:28 +00:00
|
|
|
l.GetD("race", "My text")
|
2016-06-24 20:45:12 +00:00
|
|
|
|
2023-03-17 10:29:18 +00:00
|
|
|
// Wait for goroutines to finish
|
|
|
|
<-ac
|
|
|
|
<-rc
|
|
|
|
}
|
2016-06-24 20:45:12 +00:00
|
|
|
}
|
2018-07-05 14:37:25 +00:00
|
|
|
|
|
|
|
func TestAddTranslator(t *testing.T) {
|
|
|
|
// Create po object
|
2020-09-10 20:02:24 +00:00
|
|
|
po := NewPo()
|
2018-07-05 14:37:25 +00:00
|
|
|
|
|
|
|
// Parse file
|
|
|
|
po.ParseFile("fixtures/en_US/default.po")
|
|
|
|
|
|
|
|
// Create Locale
|
|
|
|
l := NewLocale("", "en")
|
|
|
|
|
|
|
|
// Add PO Translator to Locale object
|
|
|
|
l.AddTranslator("default", po)
|
|
|
|
|
|
|
|
// Test translations
|
|
|
|
tr := l.Get("My text")
|
2020-09-10 20:02:24 +00:00
|
|
|
if tr != translatedText {
|
|
|
|
t.Errorf("Expected '%s' but got '%s'", translatedText, tr)
|
2018-07-05 14:37:25 +00:00
|
|
|
}
|
|
|
|
// Test translations
|
|
|
|
tr = l.Get("language")
|
|
|
|
if tr != "en_US" {
|
|
|
|
t.Errorf("Expected 'en_US' but got '%s'", tr)
|
|
|
|
}
|
|
|
|
}
|
2018-08-14 14:01:14 +00:00
|
|
|
|
2023-03-17 10:29:18 +00:00
|
|
|
func TestAddTranslatorFS(t *testing.T) {
|
|
|
|
fs := os.DirFS("fixtures")
|
|
|
|
// Create po object
|
|
|
|
po := NewPoFS(fs)
|
2020-04-19 19:50:56 +00:00
|
|
|
|
2023-03-17 10:29:18 +00:00
|
|
|
// Parse file
|
|
|
|
po.ParseFile("en_US/default.po")
|
2020-04-19 19:50:56 +00:00
|
|
|
|
2023-03-17 10:29:18 +00:00
|
|
|
// Create Locale
|
|
|
|
l := NewLocaleFS("en", fs)
|
2020-04-19 19:50:56 +00:00
|
|
|
|
2023-03-17 10:29:18 +00:00
|
|
|
// Add PO Translator to Locale object
|
|
|
|
l.AddTranslator("default", po)
|
2020-04-19 19:50:56 +00:00
|
|
|
|
2023-03-17 10:29:18 +00:00
|
|
|
// Test translations
|
|
|
|
tr := l.Get("My text")
|
|
|
|
if tr != translatedText {
|
|
|
|
t.Errorf("Expected '%s' but got '%s'", translatedText, tr)
|
2020-04-19 19:50:56 +00:00
|
|
|
}
|
2023-03-17 10:29:18 +00:00
|
|
|
// Test translations
|
|
|
|
tr = l.Get("language")
|
|
|
|
if tr != "en_US" {
|
|
|
|
t.Errorf("Expected 'en_US' but got '%s'", tr)
|
2020-04-19 19:50:56 +00:00
|
|
|
}
|
2023-03-17 10:29:18 +00:00
|
|
|
}
|
2020-04-19 19:50:56 +00:00
|
|
|
|
2023-03-17 10:29:18 +00:00
|
|
|
func TestArabicTranslation(t *testing.T) {
|
|
|
|
var locales []*Locale
|
|
|
|
{ // test os
|
|
|
|
// Create Locale
|
|
|
|
locales = append(locales, NewLocale("fixtures/", "ar"))
|
|
|
|
}
|
|
|
|
{ // test fs
|
|
|
|
locales = append(locales, NewLocaleFS("ar", os.DirFS("fixtures")))
|
|
|
|
}
|
|
|
|
for _, l := range locales {
|
|
|
|
|
|
|
|
// Add domain
|
|
|
|
l.AddDomain("categories")
|
|
|
|
|
|
|
|
// Plurals formula missing + Plural translation string missing
|
|
|
|
tr := l.GetD("categories", "Alcohol & Tobacco")
|
|
|
|
if tr != "الكحول والتبغ" {
|
|
|
|
t.Errorf("Expected to get 'الكحول والتبغ', but got '%s'", tr)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Plural translation string present without translations, should get the msgid_plural
|
|
|
|
tr = l.GetND("categories", "%d selected", "%d selected", 10)
|
|
|
|
if tr != "%d selected" {
|
|
|
|
t.Errorf("Expected to get '%%d selected', but got '%s'", tr)
|
|
|
|
}
|
|
|
|
|
|
|
|
//Plurals formula present + Plural translation string present and complete
|
|
|
|
tr = l.GetND("categories", "Load %d more document", "Load %d more documents", 0)
|
|
|
|
if tr != "حمّل %d مستندات إضافيّة" {
|
|
|
|
t.Errorf("Expected to get 'msgstr[0]', but got '%s'", tr)
|
|
|
|
}
|
|
|
|
|
|
|
|
tr = l.GetND("categories", "Load %d more document", "Load %d more documents", 1)
|
|
|
|
if tr != "حمّل مستند واحد إضافي" {
|
|
|
|
t.Errorf("Expected to get 'msgstr[1]', but got '%s'", tr)
|
|
|
|
}
|
|
|
|
|
|
|
|
tr = l.GetND("categories", "Load %d more document", "Load %d more documents", 2)
|
|
|
|
if tr != "حمّل مستندين إضافيين" {
|
|
|
|
t.Errorf("Expected to get 'msgstr[2]', but got '%s'", tr)
|
|
|
|
}
|
|
|
|
|
|
|
|
tr = l.GetND("categories", "Load %d more document", "Load %d more documents", 6)
|
|
|
|
if tr != "حمّل %d مستندات إضافيّة" {
|
|
|
|
t.Errorf("Expected to get 'msgstr[3]', but got '%s'", tr)
|
|
|
|
}
|
|
|
|
|
|
|
|
tr = l.GetND("categories", "Load %d more document", "Load %d more documents", 116)
|
|
|
|
if tr != "حمّل %d مستندا إضافيّا" {
|
|
|
|
t.Errorf("Expected to get 'msgstr[4]', but got '%s'", tr)
|
|
|
|
}
|
|
|
|
|
|
|
|
tr = l.GetND("categories", "Load %d more document", "Load %d more documents", 102)
|
|
|
|
if tr != "حمّل %d مستند إضافي" {
|
|
|
|
t.Errorf("Expected to get 'msgstr[5]', but got '%s'", tr)
|
|
|
|
}
|
2020-04-19 19:50:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestArabicMissingPluralForm(t *testing.T) {
|
2023-03-17 10:29:18 +00:00
|
|
|
var locales []*Locale
|
|
|
|
{ // test os
|
|
|
|
// Create Locale
|
|
|
|
locales = append(locales, NewLocale("fixtures/", "ar"))
|
|
|
|
}
|
|
|
|
{ // test fs
|
|
|
|
locales = append(locales, NewLocaleFS("ar", os.DirFS("fixtures")))
|
|
|
|
}
|
2020-04-19 19:50:56 +00:00
|
|
|
|
2023-03-17 10:29:18 +00:00
|
|
|
for _, l := range locales {
|
|
|
|
// Add domain
|
|
|
|
l.AddDomain("no_plural_header")
|
2020-04-19 19:50:56 +00:00
|
|
|
|
2023-03-17 10:29:18 +00:00
|
|
|
// Get translation
|
|
|
|
tr := l.GetD("no_plural_header", "Alcohol & Tobacco")
|
|
|
|
if tr != "الكحول والتبغ" {
|
|
|
|
t.Errorf("Expected to get 'الكحول والتبغ', but got '%s'", tr)
|
|
|
|
}
|
2020-04-19 19:50:56 +00:00
|
|
|
}
|
2018-08-14 14:01:14 +00:00
|
|
|
}
|
2023-03-17 10:29:18 +00:00
|
|
|
func TestLocale_GetTranslations(t *testing.T) {
|
|
|
|
var locales []*Locale
|
|
|
|
{ // test os
|
|
|
|
locales = append(locales, NewLocale("fixtures/", "en_US"))
|
2018-09-07 21:14:38 +00:00
|
|
|
}
|
2023-03-17 10:29:18 +00:00
|
|
|
{ // test fs
|
|
|
|
locales = append(locales, NewLocaleFS("en_US", os.DirFS("fixtures")))
|
2018-09-07 21:14:38 +00:00
|
|
|
}
|
2020-10-28 23:06:55 +00:00
|
|
|
|
2023-03-17 10:29:18 +00:00
|
|
|
for _, l := range locales {
|
|
|
|
l.AddDomain("default")
|
2020-10-28 23:06:55 +00:00
|
|
|
|
2023-03-17 10:29:18 +00:00
|
|
|
all := l.GetTranslations()
|
2020-10-28 23:06:55 +00:00
|
|
|
|
2023-03-17 10:29:18 +00:00
|
|
|
if len(all) < 5 {
|
|
|
|
t.Errorf("length of all translations is too few: %d", len(all))
|
|
|
|
}
|
2020-10-28 23:06:55 +00:00
|
|
|
|
2023-03-17 10:29:18 +00:00
|
|
|
const moreMsgID = "More"
|
|
|
|
more, ok := all[moreMsgID]
|
|
|
|
if !ok {
|
|
|
|
t.Error("missing expected translation")
|
|
|
|
}
|
|
|
|
if more.Get() != l.Get(moreMsgID) {
|
|
|
|
t.Errorf("translations of msgid %s do not match: \"%s\" != \"%s\"", moreMsgID, more.Get(), l.Get(moreMsgID))
|
|
|
|
}
|
2020-10-28 23:06:55 +00:00
|
|
|
}
|
|
|
|
}
|