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