cat / 012
clone

a spreadsheet for the terminal: lotus 1-2-3 looks, google sheets keys and formulas, one go binary

cat/module-path
012 / internal / formula / locale_test.go
locale_test.go 3.3K
1package formula23import (4 "fmt"5 "testing"67 "src.rest/cat/012/internal/locale"8)910func mustLocale(t *testing.T, tag string) *locale.Locale {11 t.Helper()12 l, ok := locale.Lookup(tag)13 if !ok {14 t.Fatalf("no locale %s", tag)15 }16 return l17}1819// TestFormulaLocaleRoundTrip types formulas in each locale, stores them20// canonically, parses them, and prints them back in the locale.21func TestFormulaLocaleRoundTrip(t *testing.T) {22 cases := []struct{ tag, typed, stored string }{23 {"de-DE", "=ROUND(1,5; 0)", "=ROUND(1.5, 0)"},24 {"de-DE", "=SUM(A1:A3;0,25)*2", "=SUM(A1:A3,0.25)*2"},25 {"de-DE", `=IF(A1>1,5;"a,b;c";'Q3; x'!B2)`, `=IF(A1>1.5,"a,b;c",'Q3; x'!B2)`},26 {"de-DE", "=SUM({1\\2,5;3\\4})", "=SUM({1,2.5;3,4})"},27 {"de-DE", "=1,5E-3+,5", "=1.5E-3+.5"},28 {"de-DE", "=SUM(Sheet2!A1..B3;Tax.Rate)", "=SUM(Sheet2!A1..B3,Tax.Rate)"},29 {"fr-FR", "=SUM(1,25; 2)", "=SUM(1.25, 2)"},30 {"pt-BR", "=IF(A1;1,5;2,5)", "=IF(A1,1.5,2.5)"},31 {"en-GB", "=ROUND(1.5, 0)", "=ROUND(1.5, 0)"},32 {"ja-JP", "={1,2;3,4}", "={1,2;3,4}"},33 {"en-US", "=ROUND(1.5, 0)", "=ROUND(1.5, 0)"},34 }35 for _, c := range cases {36 l := mustLocale(t, c.tag)37 stored := Delocalize(c.typed, l)38 if stored != c.stored {39 t.Errorf("%s: %q stored as %q, want %q", c.tag, c.typed, stored, c.stored)40 continue41 }42 if len(stored) != len(c.typed) {43 t.Errorf("%s: %q changed length", c.tag, c.typed)44 }45 if back := Localize(stored, l); back != c.typed {46 t.Errorf("%s: %q shown as %q, want %q", c.tag, stored, back, c.typed)47 }48 n, err := Parse(stored, testFuncs)49 if err != nil {50 t.Errorf("%s: %q: %v", c.tag, stored, err)51 continue52 }53 // The printer's canonical text, localized, reads back the same.54 printed := Localize(Text(n), l)55 n2, err := Parse(Delocalize(printed, l), testFuncs)56 if err != nil || Text(n2) != Text(n) {57 t.Errorf("%s: printed %q reads back as %v %v", c.tag, printed, n2, err)58 }59 }60}6162// TestLocalizePartial translates formulas still being typed.63func TestLocalizePartial(t *testing.T) {64 de := mustLocale(t, "de-DE")65 for typed, want := range map[string]string{66 "=SUM(1,5;": "=SUM(1.5,",67 `=IF(A1;"x;`: `=IF(A1,"x;`,68 "={1\\": "={1,",69 "=ROUND(": "=ROUND(",70 } {71 if got := Delocalize(typed, de); got != want {72 t.Errorf("%q = %q, want %q", typed, got, want)73 }74 }75}7677// TestLocalizeError checks parse errors name what was typed in the78// locale: its separators and the text at the error.79func TestLocalizeError(t *testing.T) {80 de := mustLocale(t, "de-DE")81 for typed, want := range map[string]string{82 "=SUM(1;2 3)": "Expected ; or ) in SUM",83 "=1;5": "Unexpected ;",84 "={1\\2 3}": "Expected \\ ; or } in an array",85 "=SUM(1;2": "Expected ; or ) in SUM",86 } {87 stored := Delocalize(typed, de)88 _, err := Parse(stored, testFuncs)89 if err == nil {90 t.Errorf("%q parsed", typed)91 continue92 }93 got := LocalizeError(err, de)94 if got.Error() != want {95 t.Errorf("%q: %q, want %q", typed, got, want)96 }97 pe, ok := got.(*ParseError)98 if !ok || pe.Pos != err.(*ParseError).Pos {99 t.Errorf("%q: %T lost the position", typed, got)100 }101 wrapped := LocalizeError(fmt.Errorf("Formula: %w", err), de)102 if wrapped.Error() != "Formula: "+want {103 t.Errorf("%q wrapped: %q", typed, wrapped)104 }105 }106 en := mustLocale(t, "en-US")107 _, err := Parse("=SUM(1,2 3)", testFuncs)108 if got := LocalizeError(err, en); got != err {109 t.Errorf("en-US changed %v", got)110 }111}