translator_test.go 20 KB

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