Refactoring to make gocyclo happy
This commit is contained in:
124
locale_test.go
124
locale_test.go
@@ -106,12 +106,115 @@ msgstr "More translation"
|
|||||||
t.Errorf("Expected 'This one is the plural: Variable' but got '%s'", tr)
|
t.Errorf("Expected 'This one is the plural: Variable' but got '%s'", tr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test context translations
|
||||||
|
v = "Test"
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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"
|
||||||
|
msgstr "Some random translation"
|
||||||
|
|
||||||
|
msgctxt "Ctx"
|
||||||
|
msgid "Some random in a context"
|
||||||
|
msgstr "Some random translation in a context"
|
||||||
|
|
||||||
|
msgid "More"
|
||||||
|
msgstr "More translation"
|
||||||
|
|
||||||
|
`
|
||||||
|
|
||||||
|
// 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")
|
||||||
|
|
||||||
|
// Force nil domain storage
|
||||||
|
l.domains = nil
|
||||||
|
|
||||||
|
// Add domain
|
||||||
|
l.AddDomain("my_domain")
|
||||||
|
|
||||||
// Test non-existent "deafult" domain responses
|
// Test non-existent "deafult" domain responses
|
||||||
tr = l.Get("My text")
|
tr := l.Get("My text")
|
||||||
if tr != "My text" {
|
if tr != "My text" {
|
||||||
t.Errorf("Expected 'My text' but got '%s'", tr)
|
t.Errorf("Expected 'My text' but got '%s'", tr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v := "Variable"
|
||||||
tr = l.GetN("One with var: %s", "Several with vars: %s", 2, v)
|
tr = l.GetN("One with var: %s", "Several with vars: %s", 2, v)
|
||||||
if tr != "Several with vars: Variable" {
|
if tr != "Several with vars: Variable" {
|
||||||
t.Errorf("Expected 'Several with vars: Variable' but got '%s'", tr)
|
t.Errorf("Expected 'Several with vars: Variable' but got '%s'", tr)
|
||||||
@@ -138,25 +241,6 @@ msgstr "More translation"
|
|||||||
if tr != "This are tests" {
|
if tr != "This are tests" {
|
||||||
t.Errorf("Expected 'Plural index' but got '%s'", tr)
|
t.Errorf("Expected 'Plural index' but got '%s'", tr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test context translations
|
|
||||||
v = "Test"
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLocaleRace(t *testing.T) {
|
func TestLocaleRace(t *testing.T) {
|
||||||
|
|||||||
195
po.go
195
po.go
@@ -86,6 +86,10 @@ type Po struct {
|
|||||||
|
|
||||||
// Sync Mutex
|
// Sync Mutex
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
|
|
||||||
|
// Parsing buffers
|
||||||
|
trBuffer *translation
|
||||||
|
ctxBuffer string
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseFile tries to read the file by its provided path (f) and parse its content as a .po file.
|
// ParseFile tries to read the file by its provided path (f) and parse its content as a .po file.
|
||||||
@@ -125,89 +129,106 @@ func (po *Po) Parse(str string) {
|
|||||||
// Get lines
|
// Get lines
|
||||||
lines := strings.Split(str, "\n")
|
lines := strings.Split(str, "\n")
|
||||||
|
|
||||||
// Translation buffer
|
// Init buffer
|
||||||
tr := newTranslation()
|
po.trBuffer = newTranslation()
|
||||||
|
po.ctxBuffer = ""
|
||||||
// Context buffer
|
|
||||||
ctx := ""
|
|
||||||
|
|
||||||
for _, l := range lines {
|
for _, l := range lines {
|
||||||
// Trim spaces
|
// Trim spaces
|
||||||
l = strings.TrimSpace(l)
|
l = strings.TrimSpace(l)
|
||||||
|
|
||||||
// Skip empty lines
|
|
||||||
if l == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip invalid lines
|
// Skip invalid lines
|
||||||
if !strings.HasPrefix(l, "\"") && !strings.HasPrefix(l, "msgctxt") && !strings.HasPrefix(l, "msgid") && !strings.HasPrefix(l, "msgid_plural") && !strings.HasPrefix(l, "msgstr") {
|
if !po.isValidLine(l) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buffer context and continue
|
// Buffer context and continue
|
||||||
if strings.HasPrefix(l, "msgctxt") {
|
if strings.HasPrefix(l, "msgctxt") {
|
||||||
// Save current translation buffer.
|
po.parseContext(l)
|
||||||
// No context
|
|
||||||
if ctx == "" {
|
|
||||||
po.translations[tr.id] = tr
|
|
||||||
} else {
|
|
||||||
// Save context
|
|
||||||
if _, ok := po.contexts[ctx]; !ok {
|
|
||||||
po.contexts[ctx] = make(map[string]*translation)
|
|
||||||
}
|
|
||||||
po.contexts[ctx][tr.id] = tr
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flush buffer
|
|
||||||
tr = newTranslation()
|
|
||||||
ctx = ""
|
|
||||||
|
|
||||||
// Buffer context
|
|
||||||
ctx, _ = strconv.Unquote(strings.TrimSpace(strings.TrimPrefix(l, "msgctxt")))
|
|
||||||
|
|
||||||
// Loop
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buffer msgid and continue
|
// Buffer msgid and continue
|
||||||
if strings.HasPrefix(l, "msgid") && !strings.HasPrefix(l, "msgid_plural") {
|
if strings.HasPrefix(l, "msgid") && !strings.HasPrefix(l, "msgid_plural") {
|
||||||
// Save current translation buffer if not inside a context.
|
po.parseID(l)
|
||||||
if ctx == "" {
|
|
||||||
po.translations[tr.id] = tr
|
|
||||||
|
|
||||||
// Flush buffer
|
|
||||||
tr = newTranslation()
|
|
||||||
ctx = ""
|
|
||||||
} else if ctx != "" && tr.id != "" {
|
|
||||||
// Save current translation buffer inside a context
|
|
||||||
if _, ok := po.contexts[ctx]; !ok {
|
|
||||||
po.contexts[ctx] = make(map[string]*translation)
|
|
||||||
}
|
|
||||||
po.contexts[ctx][tr.id] = tr
|
|
||||||
|
|
||||||
// Flush buffer
|
|
||||||
tr = newTranslation()
|
|
||||||
ctx = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set id
|
|
||||||
tr.id, _ = strconv.Unquote(strings.TrimSpace(strings.TrimPrefix(l, "msgid")))
|
|
||||||
|
|
||||||
// Loop
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for plural form
|
// Check for plural form
|
||||||
if strings.HasPrefix(l, "msgid_plural") {
|
if strings.HasPrefix(l, "msgid_plural") {
|
||||||
tr.pluralID, _ = strconv.Unquote(strings.TrimSpace(strings.TrimPrefix(l, "msgid_plural")))
|
po.parsePluralID(l)
|
||||||
|
|
||||||
// Loop
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save translation
|
// Save translation
|
||||||
if strings.HasPrefix(l, "msgstr") {
|
if strings.HasPrefix(l, "msgstr") {
|
||||||
|
po.parseMessage(l)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Multi line strings and headers
|
||||||
|
if strings.HasPrefix(l, "\"") && strings.HasSuffix(l, "\"") {
|
||||||
|
po.parseString(l)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save last translation buffer.
|
||||||
|
po.saveBuffer()
|
||||||
|
|
||||||
|
// Parse headers
|
||||||
|
po.parseHeaders()
|
||||||
|
}
|
||||||
|
|
||||||
|
// saveBuffer takes the context and translation buffers
|
||||||
|
// and saves it on the translations collection
|
||||||
|
func (po *Po) saveBuffer() {
|
||||||
|
// If we have something to save...
|
||||||
|
if po.trBuffer.id != "" {
|
||||||
|
// With no context...
|
||||||
|
if po.ctxBuffer == "" {
|
||||||
|
po.translations[po.trBuffer.id] = po.trBuffer
|
||||||
|
} else {
|
||||||
|
// With context...
|
||||||
|
if _, ok := po.contexts[po.ctxBuffer]; !ok {
|
||||||
|
po.contexts[po.ctxBuffer] = make(map[string]*translation)
|
||||||
|
}
|
||||||
|
po.contexts[po.ctxBuffer][po.trBuffer.id] = po.trBuffer
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush buffer
|
||||||
|
po.trBuffer = newTranslation()
|
||||||
|
po.ctxBuffer = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseContext takes a line starting with "msgctxt",
|
||||||
|
// saves the current translation buffer and creates a new context.
|
||||||
|
func (po *Po) parseContext(l string) {
|
||||||
|
// Save current translation buffer.
|
||||||
|
po.saveBuffer()
|
||||||
|
|
||||||
|
// Buffer context
|
||||||
|
po.ctxBuffer, _ = strconv.Unquote(strings.TrimSpace(strings.TrimPrefix(l, "msgctxt")))
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseID takes a line starting with "msgid",
|
||||||
|
// saves the current translation and creates a new msgid buffer.
|
||||||
|
func (po *Po) parseID(l string) {
|
||||||
|
// Save current translation buffer.
|
||||||
|
po.saveBuffer()
|
||||||
|
|
||||||
|
// Set id
|
||||||
|
po.trBuffer.id, _ = strconv.Unquote(strings.TrimSpace(strings.TrimPrefix(l, "msgid")))
|
||||||
|
}
|
||||||
|
|
||||||
|
// parsePluralID saves the plural id buffer from a line starting with "msgid_plural"
|
||||||
|
func (po *Po) parsePluralID(l string) {
|
||||||
|
po.trBuffer.pluralID, _ = strconv.Unquote(strings.TrimSpace(strings.TrimPrefix(l, "msgid_plural")))
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseMessage takes a line starting with "msgstr" and saves it into the current buffer.
|
||||||
|
func (po *Po) parseMessage(l string) {
|
||||||
l = strings.TrimSpace(strings.TrimPrefix(l, "msgstr"))
|
l = strings.TrimSpace(strings.TrimPrefix(l, "msgstr"))
|
||||||
|
|
||||||
// Check for indexed translation forms
|
// Check for indexed translation forms
|
||||||
@@ -215,69 +236,69 @@ func (po *Po) Parse(str string) {
|
|||||||
idx := strings.Index(l, "]")
|
idx := strings.Index(l, "]")
|
||||||
if idx == -1 {
|
if idx == -1 {
|
||||||
// Skip wrong index formatting
|
// Skip wrong index formatting
|
||||||
continue
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse index
|
// Parse index
|
||||||
i, err := strconv.Atoi(l[1:idx])
|
i, err := strconv.Atoi(l[1:idx])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Skip wrong index formatting
|
// Skip wrong index formatting
|
||||||
continue
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse translation string
|
// Parse translation string
|
||||||
tr.trs[i], _ = strconv.Unquote(strings.TrimSpace(l[idx+1:]))
|
po.trBuffer.trs[i], _ = strconv.Unquote(strings.TrimSpace(l[idx+1:]))
|
||||||
|
|
||||||
// Loop
|
// Loop
|
||||||
continue
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save single translation form under 0 index
|
// Save single translation form under 0 index
|
||||||
tr.trs[0], _ = strconv.Unquote(l)
|
po.trBuffer.trs[0], _ = strconv.Unquote(l)
|
||||||
|
}
|
||||||
|
|
||||||
// Loop
|
// parseString takes a well formatted string without prefix
|
||||||
continue
|
// and creates headers or attach multi-line strings when corresponding
|
||||||
}
|
func (po *Po) parseString(l string) {
|
||||||
|
|
||||||
// Multi line strings and headers
|
|
||||||
if strings.HasPrefix(l, "\"") && strings.HasSuffix(l, "\"") {
|
|
||||||
// Check for multiline from previously set msgid
|
// Check for multiline from previously set msgid
|
||||||
if tr.id != "" {
|
if po.trBuffer.id != "" {
|
||||||
// Append to last translation found
|
// Append to last translation found
|
||||||
uq, _ := strconv.Unquote(l)
|
uq, _ := strconv.Unquote(l)
|
||||||
tr.trs[len(tr.trs)-1] += uq
|
po.trBuffer.trs[len(po.trBuffer.trs)-1] += uq
|
||||||
|
|
||||||
// Loop
|
return
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise is a header
|
// Otherwise is a header
|
||||||
h, err := strconv.Unquote(strings.TrimSpace(l))
|
h, err := strconv.Unquote(strings.TrimSpace(l))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
po.RawHeaders += h
|
po.RawHeaders += h
|
||||||
continue
|
}
|
||||||
}
|
|
||||||
|
// isValidLine checks for line prefixes to detect valid syntax.
|
||||||
|
func (po *Po) isValidLine(l string) bool {
|
||||||
|
// Skip empty lines
|
||||||
|
if l == "" {
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save last translation buffer.
|
// Check prefix
|
||||||
if tr.id != "" {
|
if !strings.HasPrefix(l, "\"") && !strings.HasPrefix(l, "msgctxt") && !strings.HasPrefix(l, "msgid") && !strings.HasPrefix(l, "msgid_plural") && !strings.HasPrefix(l, "msgstr") {
|
||||||
if ctx == "" {
|
return false
|
||||||
po.translations[tr.id] = tr
|
|
||||||
} else {
|
|
||||||
// Save context
|
|
||||||
if _, ok := po.contexts[ctx]; !ok {
|
|
||||||
po.contexts[ctx] = make(map[string]*translation)
|
|
||||||
}
|
|
||||||
po.contexts[ctx][tr.id] = tr
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse headers
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseHeaders retrieves data from previously parsed headers
|
||||||
|
func (po *Po) parseHeaders() {
|
||||||
|
// Make sure we end with 2 carriage returns.
|
||||||
po.RawHeaders += "\n\n"
|
po.RawHeaders += "\n\n"
|
||||||
|
|
||||||
|
// Read
|
||||||
reader := bufio.NewReader(strings.NewReader(po.RawHeaders))
|
reader := bufio.NewReader(strings.NewReader(po.RawHeaders))
|
||||||
tp := textproto.NewReader(reader)
|
tp := textproto.NewReader(reader)
|
||||||
|
|
||||||
|
|||||||
29
po_test.go
29
po_test.go
@@ -186,7 +186,7 @@ msgstr "Translated example"
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPluralForms(t *testing.T) {
|
func TestPluralFormsSingle(t *testing.T) {
|
||||||
// Single form
|
// Single form
|
||||||
str := `
|
str := `
|
||||||
"Plural-Forms: nplurals=1; plural=0;"
|
"Plural-Forms: nplurals=1; plural=0;"
|
||||||
@@ -227,10 +227,11 @@ msgstr[3] "Plural form 3"
|
|||||||
if n != 0 {
|
if n != 0 {
|
||||||
t.Errorf("Expected 0 for pluralForm(50), got %d", n)
|
t.Errorf("Expected 0 for pluralForm(50), got %d", n)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
func TestPluralForms2(t *testing.T) {
|
||||||
// 2 forms
|
// 2 forms
|
||||||
str = `
|
str := `
|
||||||
"Plural-Forms: nplurals=2; plural=n != 1;"
|
"Plural-Forms: nplurals=2; plural=n != 1;"
|
||||||
|
|
||||||
# Some comment
|
# Some comment
|
||||||
@@ -243,13 +244,13 @@ msgstr[3] "Plural form 3"
|
|||||||
`
|
`
|
||||||
|
|
||||||
// Create po object
|
// Create po object
|
||||||
po = new(Po)
|
po := new(Po)
|
||||||
|
|
||||||
// Parse
|
// Parse
|
||||||
po.Parse(str)
|
po.Parse(str)
|
||||||
|
|
||||||
// Check plural form
|
// Check plural form
|
||||||
n = po.pluralForm(0)
|
n := po.pluralForm(0)
|
||||||
if n != 1 {
|
if n != 1 {
|
||||||
t.Errorf("Expected 1 for pluralForm(0), got %d", n)
|
t.Errorf("Expected 1 for pluralForm(0), got %d", n)
|
||||||
}
|
}
|
||||||
@@ -265,10 +266,11 @@ msgstr[3] "Plural form 3"
|
|||||||
if n != 1 {
|
if n != 1 {
|
||||||
t.Errorf("Expected 1 for pluralForm(3), got %d", n)
|
t.Errorf("Expected 1 for pluralForm(3), got %d", n)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
func TestPluralForms3(t *testing.T) {
|
||||||
// 3 forms
|
// 3 forms
|
||||||
str = `
|
str := `
|
||||||
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2;"
|
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2;"
|
||||||
|
|
||||||
# Some comment
|
# Some comment
|
||||||
@@ -281,13 +283,13 @@ msgstr[3] "Plural form 3"
|
|||||||
`
|
`
|
||||||
|
|
||||||
// Create po object
|
// Create po object
|
||||||
po = new(Po)
|
po := new(Po)
|
||||||
|
|
||||||
// Parse
|
// Parse
|
||||||
po.Parse(str)
|
po.Parse(str)
|
||||||
|
|
||||||
// Check plural form
|
// Check plural form
|
||||||
n = po.pluralForm(0)
|
n := po.pluralForm(0)
|
||||||
if n != 2 {
|
if n != 2 {
|
||||||
t.Errorf("Expected 2 for pluralForm(0), got %d", n)
|
t.Errorf("Expected 2 for pluralForm(0), got %d", n)
|
||||||
}
|
}
|
||||||
@@ -311,10 +313,11 @@ msgstr[3] "Plural form 3"
|
|||||||
if n != 1 {
|
if n != 1 {
|
||||||
t.Errorf("Expected 1 for pluralForm(3), got %d", n)
|
t.Errorf("Expected 1 for pluralForm(3), got %d", n)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
func TestPluralFormsSpecial(t *testing.T) {
|
||||||
// 3 forms special
|
// 3 forms special
|
||||||
str = `
|
str := `
|
||||||
"Plural-Forms: nplurals=3;"
|
"Plural-Forms: nplurals=3;"
|
||||||
"plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"
|
"plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"
|
||||||
|
|
||||||
@@ -328,13 +331,13 @@ msgstr[3] "Plural form 3"
|
|||||||
`
|
`
|
||||||
|
|
||||||
// Create po object
|
// Create po object
|
||||||
po = new(Po)
|
po := new(Po)
|
||||||
|
|
||||||
// Parse
|
// Parse
|
||||||
po.Parse(str)
|
po.Parse(str)
|
||||||
|
|
||||||
// Check plural form
|
// Check plural form
|
||||||
n = po.pluralForm(1)
|
n := po.pluralForm(1)
|
||||||
if n != 0 {
|
if n != 0 {
|
||||||
t.Errorf("Expected 0 for pluralForm(1), got %d", n)
|
t.Errorf("Expected 0 for pluralForm(1), got %d", n)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user