mirror of
https://github.com/retailcrm/mg-transport-core.git
synced 2024-11-22 13:16:04 +03:00
helper for easy translations check in transports
This commit is contained in:
parent
41e873016f
commit
87b694bc08
114
core/translations_extractor.go
Normal file
114
core/translations_extractor.go
Normal file
@ -0,0 +1,114 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/gobuffalo/packr/v2"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// TranslationsExtractor is a tool to load raw translations data from files or from box.
|
||||
// It is feasible to be used in tests in order to check translation files correctness.
|
||||
// The easiest way to check correctness is to check keys in translations.
|
||||
// TranslationsExtractor IS NOT supposed to check correctness of translations - it's just an extractor.
|
||||
// Translations can be checked manually, or via external library like https://github.com/google/go-cmp
|
||||
type TranslationsExtractor struct {
|
||||
fileNameTemplate string
|
||||
TranslationsBox *packr.Box
|
||||
TranslationsPath string
|
||||
}
|
||||
|
||||
// TranslationsExtractor constructor. Use "translate.{}.yml" as template if your translations are named like "translate.en.yml"
|
||||
func NewTranslationsExtractor(fileNameTemplate string) *TranslationsExtractor {
|
||||
return &TranslationsExtractor{fileNameTemplate: fileNameTemplate}
|
||||
}
|
||||
|
||||
// unmarshalToMap returns map with unmarshaled data or error
|
||||
func (t *TranslationsExtractor) unmarshalToMap(in []byte) (map[string]interface{}, error) {
|
||||
var dataMap map[string]interface{}
|
||||
|
||||
if err := yaml.Unmarshal(in, &dataMap); err == nil {
|
||||
return dataMap, nil
|
||||
} else {
|
||||
return dataMap, err
|
||||
}
|
||||
}
|
||||
|
||||
// loadYAMLBox loads YAML from box
|
||||
func (t *TranslationsExtractor) loadYAMLBox(fileName string) (map[string]interface{}, error) {
|
||||
var dataMap map[string]interface{}
|
||||
|
||||
if data, err := t.TranslationsBox.Find(fileName); err == nil {
|
||||
return t.unmarshalToMap(data)
|
||||
} else {
|
||||
return dataMap, err
|
||||
}
|
||||
}
|
||||
|
||||
// loadYAMLFile loads YAML from file
|
||||
func (t *TranslationsExtractor) loadYAMLFile(fileName string) (map[string]interface{}, error) {
|
||||
var dataMap map[string]interface{}
|
||||
|
||||
if info, err := os.Stat(fileName); err == nil {
|
||||
if !info.IsDir() {
|
||||
if path, err := filepath.Abs(fileName); err == nil {
|
||||
if source, err := ioutil.ReadFile(path); err == nil {
|
||||
return t.unmarshalToMap(source)
|
||||
} else {
|
||||
return dataMap, err
|
||||
}
|
||||
} else {
|
||||
return dataMap, err
|
||||
}
|
||||
} else {
|
||||
return dataMap, errors.New("directory provided instead of file")
|
||||
}
|
||||
} else {
|
||||
return dataMap, err
|
||||
}
|
||||
}
|
||||
|
||||
// loadYAML loads YAML from filesystem or from packr box - depends on what was configured. Can return error.
|
||||
func (t *TranslationsExtractor) loadYAML(fileName string) (map[string]interface{}, error) {
|
||||
if t.TranslationsBox != nil {
|
||||
return t.loadYAMLBox(fileName)
|
||||
} else if t.TranslationsPath != "" {
|
||||
return t.loadYAMLFile(fileName)
|
||||
} else {
|
||||
return map[string]interface{}{}, errors.New("nor box nor translations directory was provided")
|
||||
}
|
||||
}
|
||||
|
||||
// GetMapKeys returns sorted map keys from map[string]interface{} - useful to check keys in several translation files
|
||||
func (t *TranslationsExtractor) GetMapKeys(data map[string]interface{}) []string {
|
||||
keys := make([]string, len(data))
|
||||
|
||||
i := 0
|
||||
for k := range data {
|
||||
keys[i] = k
|
||||
i++
|
||||
}
|
||||
|
||||
sort.Strings(keys)
|
||||
|
||||
return keys
|
||||
}
|
||||
|
||||
// LoadLocale returns translation file data with provided locale
|
||||
func (t *TranslationsExtractor) LoadLocale(locale string) (map[string]interface{}, error) {
|
||||
return t.loadYAML(strings.Replace(t.fileNameTemplate, "{}", locale, 1))
|
||||
}
|
||||
|
||||
// LoadLocaleKeys returns only sorted keys from translation file
|
||||
func (t *TranslationsExtractor) LoadLocaleKeys(locale string) ([]string, error) {
|
||||
if data, err := t.LoadLocale(locale); err == nil {
|
||||
return t.GetMapKeys(data), nil
|
||||
} else {
|
||||
return []string{}, err
|
||||
}
|
||||
}
|
60
core/translations_extractor_test.go
Normal file
60
core/translations_extractor_test.go
Normal file
@ -0,0 +1,60 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"reflect"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
type TranslationsExtractorTest struct {
|
||||
suite.Suite
|
||||
extractor *TranslationsExtractor
|
||||
}
|
||||
|
||||
func (t *TranslationsExtractorTest) SetupSuite() {
|
||||
translation := map[string]string{
|
||||
"test": "first",
|
||||
"another": "second",
|
||||
}
|
||||
data, _ := yaml.Marshal(translation)
|
||||
errWrite := ioutil.WriteFile("/tmp/translate.en.yml", data, os.ModePerm)
|
||||
require.NoError(t.T(), errWrite)
|
||||
|
||||
t.extractor = NewTranslationsExtractor("translate.{}.yml")
|
||||
t.extractor.TranslationsPath = "/tmp"
|
||||
}
|
||||
|
||||
func (t *TranslationsExtractorTest) Test_LoadLocale() {
|
||||
data, err := t.extractor.LoadLocale("en")
|
||||
require.NoError(t.T(), err)
|
||||
assert.Contains(t.T(), data, "test")
|
||||
}
|
||||
|
||||
func (t *TranslationsExtractorTest) Test_GetMapKeys() {
|
||||
testMap := map[string]interface{}{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 3,
|
||||
}
|
||||
keys := []string{"a", "b", "c"}
|
||||
mapKeys := t.extractor.GetMapKeys(testMap)
|
||||
|
||||
assert.True(t.T(), reflect.DeepEqual(keys, mapKeys))
|
||||
}
|
||||
|
||||
func (t *TranslationsExtractorTest) Test_unmarshalToMap() {
|
||||
translation := map[string]string{
|
||||
"test": "first",
|
||||
"another": "second",
|
||||
}
|
||||
data, _ := yaml.Marshal(translation)
|
||||
mapData, err := t.extractor.unmarshalToMap(data)
|
||||
require.NoError(t.T(), err)
|
||||
|
||||
assert.True(t.T(), reflect.DeepEqual(translation, mapData))
|
||||
}
|
Loading…
Reference in New Issue
Block a user