i18n: Add dummy language for checking translation keys (#5785)
This commit is contained in:
parent
cea08caea3
commit
42eed7dbea
5 changed files with 123 additions and 2 deletions
66
modules/translation/i18n/dummy.go
Normal file
66
modules/translation/i18n/dummy.go
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
// Copyright 2024 The Forgejo Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package i18n
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"html/template"
|
||||||
|
"reflect"
|
||||||
|
"slices"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type KeyLocale struct{}
|
||||||
|
|
||||||
|
var _ Locale = (*KeyLocale)(nil)
|
||||||
|
|
||||||
|
// HasKey implements Locale.
|
||||||
|
func (k *KeyLocale) HasKey(trKey string) bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// TrHTML implements Locale.
|
||||||
|
func (k *KeyLocale) TrHTML(trKey string, trArgs ...any) template.HTML {
|
||||||
|
args := slices.Clone(trArgs)
|
||||||
|
for i, v := range args {
|
||||||
|
switch v := v.(type) {
|
||||||
|
case nil, bool, int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, template.HTML:
|
||||||
|
// for most basic types (including template.HTML which is safe), just do nothing and use it
|
||||||
|
case string:
|
||||||
|
args[i] = template.HTMLEscapeString(v)
|
||||||
|
case fmt.Stringer:
|
||||||
|
args[i] = template.HTMLEscapeString(v.String())
|
||||||
|
default:
|
||||||
|
args[i] = template.HTMLEscapeString(fmt.Sprint(v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return template.HTML(k.TrString(trKey, args...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TrString implements Locale.
|
||||||
|
func (k *KeyLocale) TrString(trKey string, trArgs ...any) string {
|
||||||
|
return FormatDummy(trKey, trArgs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func FormatDummy(trKey string, args ...any) string {
|
||||||
|
if len(args) == 0 {
|
||||||
|
return fmt.Sprintf("(%s)", trKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmtArgs := make([]any, 0, len(args)+1)
|
||||||
|
fmtArgs = append(fmtArgs, trKey)
|
||||||
|
for _, arg := range args {
|
||||||
|
val := reflect.ValueOf(arg)
|
||||||
|
if val.Kind() == reflect.Slice {
|
||||||
|
for i := 0; i < val.Len(); i++ {
|
||||||
|
fmtArgs = append(fmtArgs, val.Index(i).Interface())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmtArgs = append(fmtArgs, arg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template := fmt.Sprintf("(%%s: %s)", strings.Join(slices.Repeat([]string{"%v"}, len(fmtArgs)-1), ", "))
|
||||||
|
return fmt.Sprintf(template, fmtArgs...)
|
||||||
|
}
|
19
modules/translation/i18n/dummy_test.go
Normal file
19
modules/translation/i18n/dummy_test.go
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// Copyright 2024 The Forgejo Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package i18n_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/translation/i18n"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFormatDummy(t *testing.T) {
|
||||||
|
assert.Equal(t, "(admin.config.git_max_diff_lines)", i18n.FormatDummy("admin.config.git_max_diff_lines"))
|
||||||
|
assert.Equal(t, "(dashboard)", i18n.FormatDummy("dashboard"))
|
||||||
|
assert.Equal(t, "(branch.create_branch: main)", i18n.FormatDummy("branch.create_branch", "main"))
|
||||||
|
assert.Equal(t, "(test.test: a, 1, true)", i18n.FormatDummy("test.test", "a", 1, true))
|
||||||
|
}
|
|
@ -160,6 +160,16 @@ func NewLocale(lang string) Locale {
|
||||||
defer lock.RUnlock()
|
defer lock.RUnlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if lang == "dummy" {
|
||||||
|
l := &locale{
|
||||||
|
Locale: &i18n.KeyLocale{},
|
||||||
|
Lang: lang,
|
||||||
|
LangName: lang,
|
||||||
|
msgPrinter: message.NewPrinter(language.English),
|
||||||
|
}
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
langName := "unknown"
|
langName := "unknown"
|
||||||
if l, ok := allLangMap[lang]; ok {
|
if l, ok := allLangMap[lang]; ok {
|
||||||
langName = l.Name
|
langName = l.Name
|
||||||
|
|
|
@ -26,8 +26,10 @@ func Locale(resp http.ResponseWriter, req *http.Request) translation.Locale {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if lang == "dummy" {
|
||||||
|
changeLang = false
|
||||||
|
} else if lang != "" && !i18n.DefaultLocales.HasLang(lang) {
|
||||||
// Check again in case someone changes the supported language list.
|
// Check again in case someone changes the supported language list.
|
||||||
if lang != "" && !i18n.DefaultLocales.HasLang(lang) {
|
|
||||||
lang = ""
|
lang = ""
|
||||||
changeLang = false
|
changeLang = false
|
||||||
}
|
}
|
||||||
|
|
24
tests/integration/dummy_lang_test.go
Normal file
24
tests/integration/dummy_lang_test.go
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// Copyright 2024 The Forgejo Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/tests"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestKeyLocale(t *testing.T) {
|
||||||
|
defer tests.PrepareTestEnv(t)()
|
||||||
|
|
||||||
|
req := NewRequest(t, "GET", "/user2/repo1/issues?lang=dummy")
|
||||||
|
resp := MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||||
|
newButton := htmlDoc.doc.Find(".list-header-issues > .issue-list-new")
|
||||||
|
assert.Equal(t, "(repo.issues.new)", newButton.Text())
|
||||||
|
}
|
Loading…
Reference in a new issue