1 package ut
2
3 import (
4 "fmt"
5 "testing"
6
7 "github.com/go-playground/locales"
8 "github.com/go-playground/locales/en"
9 "github.com/go-playground/locales/en_CA"
10 "github.com/go-playground/locales/nl"
11 )
12
13
14
15
16
17
18
19
20
21
22
23
24 func TestBasicTranslation(t *testing.T) {
25
26 e := en.New()
27 uni := New(e, e)
28 en, found := uni.GetTranslator("en")
29 if !found {
30 t.Fatalf("Expected '%t' Got '%t'", true, found)
31 }
32
33 translations := []struct {
34 key interface{}
35 trans string
36 expected error
37 expectedError bool
38 override bool
39 }{
40 {
41 key: "test_trans",
42 trans: "Welcome {0}",
43 expected: nil,
44 },
45 {
46 key: -1,
47 trans: "Welcome {0}",
48 expected: nil,
49 },
50 {
51 key: "test_trans2",
52 trans: "{0} to the {1}.",
53 expected: nil,
54 },
55 {
56 key: "test_trans3",
57 trans: "Welcome {0} to the {1}",
58 expected: nil,
59 },
60 {
61 key: "test_trans4",
62 trans: "{0}{1}",
63 expected: nil,
64 },
65 {
66 key: "test_trans",
67 trans: "{0}{1}",
68 expected: &ErrConflictingTranslation{locale: en.Locale(), key: "test_trans", text: "{0}{1}"},
69 expectedError: true,
70 },
71 {
72 key: -1,
73 trans: "{0}{1}",
74 expected: &ErrConflictingTranslation{locale: en.Locale(), key: -1, text: "{0}{1}"},
75 expectedError: true,
76 },
77 {
78 key: "test_trans",
79 trans: "Welcome {0} to the {1}.",
80 expected: nil,
81 override: true,
82 },
83 }
84
85 for _, tt := range translations {
86
87 err := en.Add(tt.key, tt.trans, tt.override)
88 if err != tt.expected {
89 if !tt.expectedError {
90 t.Errorf("Expected '%s' Got '%s'", tt.expected, err)
91 } else {
92 if err.Error() != tt.expected.Error() {
93 t.Errorf("Expected '%s' Got '%s'", tt.expected.Error(), err.Error())
94 }
95 }
96 }
97 }
98
99 tests := []struct {
100 key interface{}
101 params []string
102 expected string
103 expectedError bool
104 }{
105 {
106 key: "test_trans",
107 params: []string{"Joeybloggs", "The Test"},
108 expected: "Welcome Joeybloggs to the The Test.",
109 },
110 {
111 key: "test_trans2",
112 params: []string{"Joeybloggs", "The Test"},
113 expected: "Joeybloggs to the The Test.",
114 },
115 {
116 key: "test_trans3",
117 params: []string{"Joeybloggs", "The Test"},
118 expected: "Welcome Joeybloggs to the The Test",
119 },
120 {
121 key: "test_trans4",
122 params: []string{"Joeybloggs", "The Test"},
123 expected: "JoeybloggsThe Test",
124 },
125
126 {
127 key: "non-existant-key",
128 params: []string{"Joeybloggs", "The Test"},
129 expected: "",
130 expectedError: true,
131 },
132 }
133
134 for _, tt := range tests {
135 s, err := en.T(tt.key, tt.params...)
136 if s != tt.expected {
137 if !tt.expectedError && err != ErrUnknowTranslation {
138 t.Errorf("Expected '%s' Got '%s'", tt.expected, s)
139 }
140 }
141 }
142 }
143
144 func TestCardinalTranslation(t *testing.T) {
145
146 e := en.New()
147 uni := New(e, e)
148 en, found := uni.GetTranslator("en")
149 if !found {
150 t.Fatalf("Expected '%t' Got '%t'", true, found)
151 }
152
153 translations := []struct {
154 key interface{}
155 trans string
156 rule locales.PluralRule
157 expected error
158 expectedError bool
159 override bool
160 }{
161
162 {
163 key: "cardinal_test",
164 trans: "You have a day left.",
165 rule: locales.PluralRuleOne,
166 expected: &ErrCardinalTranslation{text: fmt.Sprintf("error: parameter '%s' not found, may want to use 'Add' instead of 'AddCardinal'. locale: '%s' key: '%v' text: '%s'", paramZero, en.Locale(), "cardinal_test", "You have a day left.")},
167 expectedError: true,
168 },
169
170 {
171 key: "cardinal_test",
172 trans: "You have a day left few.",
173 rule: locales.PluralRuleFew,
174 expected: &ErrCardinalTranslation{text: fmt.Sprintf("error: cardinal plural rule '%s' does not exist for locale '%s' key: '%s' text: '%s'", locales.PluralRuleFew, en.Locale(), "cardinal_test", "You have a day left few.")},
175 expectedError: true,
176 },
177 {
178 key: "cardinal_test",
179 trans: "You have {0} day",
180 rule: locales.PluralRuleOne,
181 expected: nil,
182 },
183 {
184 key: "cardinal_test",
185 trans: "You have {0} days left.",
186 rule: locales.PluralRuleOther,
187 expected: nil,
188 },
189 {
190 key: "cardinal_test",
191 trans: "You have {0} days left.",
192 rule: locales.PluralRuleOther,
193 expected: &ErrConflictingTranslation{locale: en.Locale(), key: "cardinal_test", rule: locales.PluralRuleOther, text: "You have {0} days left."},
194 expectedError: true,
195 },
196 {
197 key: "cardinal_test",
198 trans: "You have {0} day left.",
199 rule: locales.PluralRuleOne,
200 expected: nil,
201 override: true,
202 },
203 }
204
205 for _, tt := range translations {
206
207 err := en.AddCardinal(tt.key, tt.trans, tt.rule, tt.override)
208 if err != tt.expected {
209 if !tt.expectedError || err.Error() != tt.expected.Error() {
210 t.Errorf("Expected '<nil>' Got '%s'", err)
211 }
212 }
213 }
214
215 tests := []struct {
216 key interface{}
217 num float64
218 digits uint64
219 param string
220 expected string
221 expectedError bool
222 }{
223 {
224 key: "cardinal_test",
225 num: 1,
226 digits: 0,
227 param: string(en.FmtNumber(1, 0)),
228 expected: "You have 1 day left.",
229 },
230
231 {
232 key: "non-existant",
233 num: 1,
234 digits: 0,
235 param: string(en.FmtNumber(1, 0)),
236 expected: "",
237 expectedError: true,
238 },
239 }
240
241 for _, tt := range tests {
242
243 s, err := en.C(tt.key, tt.num, tt.digits, tt.param)
244 if err != nil {
245 if !tt.expectedError && err != ErrUnknowTranslation {
246 t.Errorf("Expected '<nil>' Got '%s'", err)
247 }
248 }
249
250 if s != tt.expected {
251 t.Errorf("Expected '%s' Got '%s'", tt.expected, s)
252 }
253 }
254 }
255
256 func TestOrdinalTranslation(t *testing.T) {
257
258 e := en.New()
259 uni := New(e, e)
260 en, found := uni.GetTranslator("en")
261 if !found {
262 t.Fatalf("Expected '%t' Got '%t'", true, found)
263 }
264
265 translations := []struct {
266 key interface{}
267 trans string
268 rule locales.PluralRule
269 expected error
270 expectedError bool
271 override bool
272 }{
273
274 {
275 key: "day",
276 trans: "st",
277 rule: locales.PluralRuleOne,
278 expected: &ErrOrdinalTranslation{text: fmt.Sprintf("error: parameter '%s' not found, may want to use 'Add' instead of 'AddOrdinal'. locale: '%s' key: '%v' text: '%s'", paramZero, en.Locale(), "day", "st")},
279 expectedError: true,
280 },
281
282 {
283 key: "day",
284 trans: "st",
285 rule: locales.PluralRuleMany,
286 expected: &ErrOrdinalTranslation{text: fmt.Sprintf("error: ordinal plural rule '%s' does not exist for locale '%s' key: '%s' text: '%s'", locales.PluralRuleMany, en.Locale(), "day", "st")},
287 expectedError: true,
288 },
289 {
290 key: "day",
291 trans: "{0}st",
292 rule: locales.PluralRuleOne,
293 expected: nil,
294 },
295 {
296 key: "day",
297 trans: "{0}nd",
298 rule: locales.PluralRuleTwo,
299 expected: nil,
300 },
301 {
302 key: "day",
303 trans: "{0}rd",
304 rule: locales.PluralRuleFew,
305 expected: nil,
306 },
307 {
308 key: "day",
309 trans: "{0}th",
310 rule: locales.PluralRuleOther,
311 expected: nil,
312 },
313
314 {
315 key: "day",
316 trans: "{0}th",
317 rule: locales.PluralRuleOther,
318 expected: &ErrConflictingTranslation{locale: en.Locale(), key: "day", rule: locales.PluralRuleOther, text: "{0}th"},
319 expectedError: true,
320 },
321 {
322 key: "day",
323 trans: "{0}st",
324 rule: locales.PluralRuleOne,
325 expected: nil,
326 override: true,
327 },
328 }
329
330 for _, tt := range translations {
331
332 err := en.AddOrdinal(tt.key, tt.trans, tt.rule, tt.override)
333 if err != tt.expected {
334 if !tt.expectedError || err.Error() != tt.expected.Error() {
335 t.Errorf("Expected '<nil>' Got '%s'", err)
336 }
337 }
338 }
339
340 tests := []struct {
341 key interface{}
342 num float64
343 digits uint64
344 param string
345 expected string
346 expectedError bool
347 }{
348 {
349 key: "day",
350 num: 1,
351 digits: 0,
352 param: string(en.FmtNumber(1, 0)),
353 expected: "1st",
354 },
355 {
356 key: "day",
357 num: 2,
358 digits: 0,
359 param: string(en.FmtNumber(2, 0)),
360 expected: "2nd",
361 },
362 {
363 key: "day",
364 num: 3,
365 digits: 0,
366 param: string(en.FmtNumber(3, 0)),
367 expected: "3rd",
368 },
369 {
370 key: "day",
371 num: 4,
372 digits: 0,
373 param: string(en.FmtNumber(4, 0)),
374 expected: "4th",
375 },
376 {
377 key: "day",
378 num: 10258.43,
379 digits: 0,
380 param: string(en.FmtNumber(10258.43, 0)),
381 expected: "10,258th",
382 },
383
384 {
385 key: "d-day",
386 num: 10258.43,
387 digits: 0,
388 param: string(en.FmtNumber(10258.43, 0)),
389 expected: "",
390 expectedError: true,
391 },
392 }
393
394 for _, tt := range tests {
395
396 s, err := en.O(tt.key, tt.num, tt.digits, tt.param)
397 if err != nil {
398 if !tt.expectedError && err != ErrUnknowTranslation {
399 t.Errorf("Expected '<nil>' Got '%s'", err)
400 }
401 }
402
403 if s != tt.expected {
404 t.Errorf("Expected '%s' Got '%s'", tt.expected, s)
405 }
406 }
407 }
408
409 func TestRangeTranslation(t *testing.T) {
410
411 n := nl.New()
412 uni := New(n, n)
413
414
415 nl, found := uni.GetTranslator("nl")
416 if !found {
417 t.Fatalf("Expected '%t' Got '%t'", true, found)
418 }
419
420 translations := []struct {
421 key interface{}
422 trans string
423 rule locales.PluralRule
424 expected error
425 expectedError bool
426 override bool
427 }{
428
429 {
430 key: "day",
431 trans: "er -{1} dag vertrokken",
432 rule: locales.PluralRuleOne,
433 expected: &ErrRangeTranslation{text: fmt.Sprintf("error: parameter '%s' not found, are you sure you're adding a Range Translation? locale: '%s' key: '%s' text: '%s'", paramZero, nl.Locale(), "day", "er -{1} dag vertrokken")},
434 expectedError: true,
435 },
436
437 {
438 key: "day",
439 trans: "er {0}- dag vertrokken",
440 rule: locales.PluralRuleMany,
441 expected: &ErrRangeTranslation{text: fmt.Sprintf("error: range plural rule '%s' does not exist for locale '%s' key: '%s' text: '%s'", locales.PluralRuleMany, nl.Locale(), "day", "er {0}- dag vertrokken")},
442 expectedError: true,
443 },
444
445 {
446 key: "day",
447 trans: "er {0}- dag vertrokken",
448 rule: locales.PluralRuleOne,
449 expected: &ErrRangeTranslation{text: fmt.Sprintf("error: parameter '%s' not found, a Range Translation requires two parameters. locale: '%s' key: '%s' text: '%s'", paramOne, nl.Locale(), "day", "er {0}- dag vertrokken")},
450 expectedError: true,
451 },
452 {
453 key: "day",
454 trans: "er {0}-{1} dag",
455 rule: locales.PluralRuleOne,
456 expected: nil,
457 },
458 {
459 key: "day",
460 trans: "er zijn {0}-{1} dagen over",
461 rule: locales.PluralRuleOther,
462 expected: nil,
463 },
464
465 {
466 key: "day",
467 trans: "er zijn {0}-{1} dagen over",
468 rule: locales.PluralRuleOther,
469 expected: &ErrConflictingTranslation{locale: nl.Locale(), key: "day", rule: locales.PluralRuleOther, text: "er zijn {0}-{1} dagen over"},
470 expectedError: true,
471 },
472 {
473 key: "day",
474 trans: "er {0}-{1} dag vertrokken",
475 rule: locales.PluralRuleOne,
476 expected: nil,
477 override: true,
478 },
479 }
480
481 for _, tt := range translations {
482
483 err := nl.AddRange(tt.key, tt.trans, tt.rule, tt.override)
484 if err != tt.expected {
485 if !tt.expectedError || err.Error() != tt.expected.Error() {
486 t.Errorf("Expected '%#v' Got '%s'", tt.expected, err)
487 }
488 }
489 }
490
491 tests := []struct {
492 key interface{}
493 num1 float64
494 digits1 uint64
495 num2 float64
496 digits2 uint64
497 param1 string
498 param2 string
499 expected string
500 expectedError bool
501 }{
502 {
503 key: "day",
504 num1: 1,
505 digits1: 0,
506 num2: 2,
507 digits2: 0,
508 param1: string(nl.FmtNumber(1, 0)),
509 param2: string(nl.FmtNumber(2, 0)),
510 expected: "er zijn 1-2 dagen over",
511 },
512 {
513 key: "day",
514 num1: 0,
515 digits1: 0,
516 num2: 1,
517 digits2: 0,
518 param1: string(nl.FmtNumber(0, 0)),
519 param2: string(nl.FmtNumber(1, 0)),
520 expected: "er 0-1 dag vertrokken",
521 },
522 {
523 key: "day",
524 num1: 0,
525 digits1: 0,
526 num2: 2,
527 digits2: 0,
528 param1: string(nl.FmtNumber(0, 0)),
529 param2: string(nl.FmtNumber(2, 0)),
530 expected: "er zijn 0-2 dagen over",
531 },
532
533 {
534 key: "d-day",
535 num1: 0,
536 digits1: 0,
537 num2: 2,
538 digits2: 0,
539 param1: string(nl.FmtNumber(0, 0)),
540 param2: string(nl.FmtNumber(2, 0)),
541 expected: "",
542 expectedError: true,
543 },
544 }
545
546 for _, tt := range tests {
547
548 s, err := nl.R(tt.key, tt.num1, tt.digits1, tt.num2, tt.digits2, tt.param1, tt.param2)
549 if err != nil {
550 if !tt.expectedError && err != ErrUnknowTranslation {
551 t.Errorf("Expected '<nil>' Got '%s'", err)
552 }
553 }
554
555 if s != tt.expected {
556 t.Errorf("Expected '%s' Got '%s'", tt.expected, s)
557 }
558 }
559 }
560
561 func TestFallbackTranslator(t *testing.T) {
562
563 e := en.New()
564 uni := New(e, e)
565 en, found := uni.GetTranslator("en")
566 if !found {
567 t.Fatalf("Expected '%t' Got '%t'", true, found)
568 }
569
570 if en.Locale() != "en" {
571 t.Errorf("Expected '%s' Got '%s'", "en", en.Locale())
572 }
573
574 fallback, _ := uni.GetTranslator("nl")
575 if fallback.Locale() != "en" {
576 t.Errorf("Expected '%s' Got '%s'", "en", fallback.Locale())
577 }
578
579 en, _ = uni.FindTranslator("nl", "en")
580 if en.Locale() != "en" {
581 t.Errorf("Expected '%s' Got '%s'", "en", en.Locale())
582 }
583
584 fallback, _ = uni.FindTranslator("nl")
585 if fallback.Locale() != "en" {
586 t.Errorf("Expected '%s' Got '%s'", "en", fallback.Locale())
587 }
588 }
589
590 func TestAddTranslator(t *testing.T) {
591
592 e := en.New()
593 n := nl.New()
594 uni := New(e, n)
595
596 tests := []struct {
597 trans locales.Translator
598 expected error
599 expectedError bool
600 override bool
601 }{
602 {
603 trans: en_CA.New(),
604 expected: nil,
605 override: false,
606 },
607 {
608 trans: n,
609 expected: &ErrExistingTranslator{locale: n.Locale()},
610 expectedError: true,
611 override: false,
612 },
613 {
614 trans: e,
615 expected: &ErrExistingTranslator{locale: e.Locale()},
616 expectedError: true,
617 override: false,
618 },
619 {
620 trans: e,
621 expected: nil,
622 override: true,
623 },
624 }
625
626 for _, tt := range tests {
627
628 err := uni.AddTranslator(tt.trans, tt.override)
629 if err != tt.expected {
630 if !tt.expectedError || err.Error() != tt.expected.Error() {
631 t.Errorf("Expected '%s' Got '%s'", tt.expected, err)
632 }
633 }
634 }
635 }
636
637 func TestVerifyTranslations(t *testing.T) {
638
639 n := nl.New()
640
641 uni := New(n, n)
642
643 loc, _ := uni.GetTranslator("nl")
644 if loc.Locale() != "nl" {
645 t.Errorf("Expected '%s' Got '%s'", "nl", loc.Locale())
646 }
647
648
649
650 err := loc.AddCardinal("day", "je {0} dag hebben verlaten", locales.PluralRuleOne, false)
651 if err != nil {
652 t.Fatalf("Expected '<nil>' Got '%s'", err)
653 }
654
655
656 expected := &ErrMissingPluralTranslation{locale: loc.Locale(), translationType: "plural", rule: locales.PluralRuleOther, key: "day"}
657 err = loc.VerifyTranslations()
658 if err == nil || err.Error() != expected.Error() {
659 t.Errorf("Expected '%s' Got '%s'", expected, err)
660 }
661
662
663 err = loc.AddCardinal("day", "je {0} dagen hebben verlaten", locales.PluralRuleOther, false)
664 if err != nil {
665 t.Fatalf("Expected '<nil>' Got '%s'", err)
666 }
667
668 err = loc.VerifyTranslations()
669 if err != nil {
670 t.Fatalf("Expected '<nil>' Got '%s'", err)
671 }
672
673
674 err = loc.AddRange("day", "je {0}-{1} dagen hebben verlaten", locales.PluralRuleOther, false)
675 if err != nil {
676 t.Fatalf("Expected '<nil>' Got '%s'", err)
677 }
678
679
680 expected = &ErrMissingPluralTranslation{locale: loc.Locale(), translationType: "range", rule: locales.PluralRuleOne, key: "day"}
681 err = loc.VerifyTranslations()
682 if err == nil || err.Error() != expected.Error() {
683 t.Errorf("Expected '%s' Got '%s'", expected, err)
684 }
685
686
687 err = loc.AddRange("day", "je {0}-{1} dag hebben verlaten", locales.PluralRuleOne, false)
688 if err != nil {
689 t.Fatalf("Expected '<nil>' Got '%s'", err)
690 }
691
692 err = loc.VerifyTranslations()
693 if err != nil {
694 t.Fatalf("Expected '<nil>' Got '%s'", err)
695 }
696
697
698
699 err = uni.AddTranslator(en.New(), false)
700 if err != nil {
701 t.Fatalf("Expected '<nil>' Got '%s'", err)
702 }
703
704 loc, _ = uni.GetTranslator("en")
705 if loc.Locale() != "en" {
706 t.Errorf("Expected '%s' Got '%s'", "en", loc.Locale())
707 }
708
709
710
711 err = loc.AddOrdinal("day", "{0}st", locales.PluralRuleOne, false)
712 if err != nil {
713 t.Fatalf("Expected '<nil>' Got '%s'", err)
714 }
715
716 err = loc.AddOrdinal("day", "{0}rd", locales.PluralRuleFew, false)
717 if err != nil {
718 t.Fatalf("Expected '<nil>' Got '%s'", err)
719 }
720
721 err = loc.AddOrdinal("day", "{0}th", locales.PluralRuleOther, false)
722 if err != nil {
723 t.Fatalf("Expected '<nil>' Got '%s'", err)
724 }
725
726
727 expected = &ErrMissingPluralTranslation{locale: loc.Locale(), translationType: "ordinal", rule: locales.PluralRuleTwo, key: "day"}
728 err = loc.VerifyTranslations()
729 if err == nil || err.Error() != expected.Error() {
730 t.Errorf("Expected '%s' Got '%s'", expected, err)
731 }
732
733
734
735 err = loc.AddOrdinal("day", "{0}nd", locales.PluralRuleTwo, false)
736 if err != nil {
737 t.Fatalf("Expected '<nil>' Got '%s'", err)
738 }
739
740 err = loc.VerifyTranslations()
741 if err != nil {
742 t.Fatalf("Expected '<nil>' Got '%s'", err)
743 }
744 }
745
746 func TestVerifyTranslationsWithNonStringKeys(t *testing.T) {
747
748 n := nl.New()
749
750 uni := New(n, n)
751
752 loc, _ := uni.GetTranslator("nl")
753 if loc.Locale() != "nl" {
754 t.Errorf("Expected '%s' Got '%s'", "nl", loc.Locale())
755 }
756
757
758
759 err := loc.AddCardinal(-1, "je {0} dag hebben verlaten", locales.PluralRuleOne, false)
760 if err != nil {
761 t.Fatalf("Expected '<nil>' Got '%s'", err)
762 }
763
764
765 expected := &ErrMissingPluralTranslation{locale: loc.Locale(), translationType: "plural", rule: locales.PluralRuleOther, key: -1}
766 err = loc.VerifyTranslations()
767 if err == nil || err.Error() != expected.Error() {
768 t.Errorf("Expected '%s' Got '%s'", expected, err)
769 }
770 }
771
772 func TestGetFallback(t *testing.T) {
773
774
775 n := nl.New()
776 e := en.New()
777
778 uni := New(e, n)
779
780 trans := uni.GetFallback()
781
782 expected := "en"
783
784 if trans.Locale() != expected {
785 t.Errorf("Expected '%s' Got '%s'", expected, trans.Locale())
786 }
787 }
788
789 func TestVerifyUTTranslations(t *testing.T) {
790
791 e := en.New()
792 uni := New(e, e)
793 en, found := uni.GetTranslator("en")
794 if !found {
795 t.Fatalf("Expected '%t' Got '%t'", true, found)
796 }
797
798 translations := []struct {
799 key interface{}
800 trans string
801 rule locales.PluralRule
802 expected error
803 expectedError bool
804 override bool
805 }{
806 {
807 key: "day",
808 trans: "{0}st",
809 rule: locales.PluralRuleOne,
810 expected: nil,
811 },
812 {
813 key: "day",
814 trans: "{0}nd",
815 rule: locales.PluralRuleTwo,
816 expected: nil,
817 },
818 {
819 key: "day",
820 trans: "{0}rd",
821 rule: locales.PluralRuleFew,
822 expected: nil,
823 },
824
825
826
827
828
829
830
831 }
832
833 for _, tt := range translations {
834
835 err := en.AddOrdinal(tt.key, tt.trans, tt.rule, tt.override)
836 if err != tt.expected {
837 if !tt.expectedError || err.Error() != tt.expected.Error() {
838 t.Errorf("Expected '<nil>' Got '%s'", err)
839 }
840 }
841 }
842
843 expected := "error: missing 'ordinal' plural rule 'Other' for translation with key 'day' and locale 'en'"
844 err := uni.VerifyTranslations()
845 if err == nil || err.Error() != expected {
846 t.Fatalf("Expected '%s' Got '%s'", expected, err)
847 }
848
849 err = en.AddOrdinal("day", "{0}th", locales.PluralRuleOther, false)
850 if err != nil {
851 t.Fatalf("Expected '%v' Got '%s'", nil, err)
852 }
853
854 err = uni.VerifyTranslations()
855 if err != nil {
856 t.Fatalf("Expected '%v' Got '%s'", nil, err)
857 }
858 }
859
View as plain text