OSDN Git Service

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