aboutsummaryrefslogtreecommitdiff
path: root/internal/i18n/gen_test.go
blob: 82dfd837b4c16e7a5314257382251a2a00422031 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package i18n

import (
	"os"
	"path/filepath"
	"reflect"
	"sort"
	"strings"
	"testing"
)

// quote wraps a value in double quotes when it has meaningful leading/trailing
// whitespace, so the INI reader's trim does not eat it.
func quote(s string) string {
	if s != strings.TrimSpace(s) {
		return `"` + s + `"`
	}
	return s
}

// marshalUI renders a UI table as an INI file, the inverse of applyUI. It is the
// generator for the embedded lang/<code>.ini files; the mapping is by reflection
// so adding a UI field needs no generator change.
func marshalUI(u UI) []byte {
	var b strings.Builder
	v := reflect.ValueOf(u)
	t := v.Type()
	for i := 0; i < t.NumField(); i++ {
		key := iniKey(t.Field(i).Name)
		fv := v.Field(i)
		switch fv.Kind() {
		case reflect.String:
			b.WriteString(key + " = " + quote(fv.String()) + "\n")
		case reflect.Map:
			ks := make([]string, 0, fv.Len())
			for _, k := range fv.MapKeys() {
				ks = append(ks, k.String())
			}
			sort.Strings(ks)
			for _, mk := range ks {
				b.WriteString(key + "." + mk + " = " + quote(fv.MapIndex(reflect.ValueOf(mk)).String()) + "\n")
			}
		case reflect.Array:
			parts := make([]string, fv.Len())
			for j := 0; j < fv.Len(); j++ {
				parts[j] = fv.Index(j).String()
			}
			b.WriteString(key + " = " + strings.Join(parts, ",") + "\n")
		}
	}
	return []byte(b.String())
}

// TestGenerateLangFiles (re)writes the embedded English and Polish chrome files
// from the Go golden tables. It is a generator, not an assertion: run it with
// LECTIO_GEN=1 after changing enUI/plUI to refresh lang/en.ini and lang/pl.ini.
func TestGenerateLangFiles(t *testing.T) {
	if os.Getenv("LECTIO_GEN") == "" {
		t.Skip("set LECTIO_GEN=1 to regenerate lang/*.ini from the Go tables")
	}
	if err := os.MkdirAll("lang", 0o755); err != nil {
		t.Fatal(err)
	}
	for code, u := range map[string]UI{"en": enUI, "pl": plUI} {
		if err := os.WriteFile(filepath.Join("lang", code+".ini"), marshalUI(u), 0o644); err != nil {
			t.Fatalf("write %s: %v", code, err)
		}
	}
}