tests.js 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746
  1. (function (Jed){
  2. describe("Property Checks", function () {
  3. it("should exist", function () {
  4. expect( Jed ).to.be.ok();
  5. });
  6. it("should have a context delimiter as per the gettext spec", function () {
  7. expect( Jed.context_delimiter ).to.be( "\u0004" );
  8. expect( Jed.context_delimiter ).to.be( String.fromCharCode( 4 ) );
  9. });
  10. });
  11. // Group tests that need similar data
  12. (function () {
  13. var locale_data = {
  14. "messages" : {
  15. "" : {
  16. "domain" : "messages",
  17. "lang" : "en",
  18. "plural-forms" : "nplurals=2; plural=(n != 1);"
  19. },
  20. "test" : ["test_translation_output"]
  21. }
  22. };
  23. var locale_data2 = {
  24. "some_domain" : {
  25. "" : {
  26. "domain" : "some_domain",
  27. "lang" : "en",
  28. "plural-forms" : "nplurals=2; plural=(n != 1);"
  29. },
  30. "test" : ["test_translation_output2"],
  31. "zero length translation" : [""]
  32. }
  33. };
  34. var locale_data3 = {
  35. "some_domain" : {
  36. "" : {
  37. "domain" : "some_domain",
  38. "lang" : "ar",
  39. "plural-forms" : "nplurals=6; plural=(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 ? 4 : 5);"
  40. },
  41. "test" : ["test_translation_output3"],
  42. "zero length translation" : [""]
  43. }
  44. };
  45. var i18n = new Jed({
  46. "domain" : "messages",
  47. "locale_data" : locale_data
  48. });
  49. var i18n_2 = new Jed({
  50. "domain" : "some_domain",
  51. "locale_data" : locale_data2
  52. });
  53. var i18n_3 = new Jed({
  54. "domain" : "some_domain",
  55. "locale_data" : locale_data3
  56. });
  57. // Standard shorthand function
  58. function _(msgid) {
  59. return i18n_2.gettext(msgid);
  60. }
  61. // Actual tests
  62. describe("Instantiation", function () {
  63. it("should exist", function () {
  64. expect( i18n ).to.be.ok();
  65. expect( i18n_2 ).to.be.ok();
  66. expect( i18n_3 ).to.be.ok();
  67. expect( _ ).to.be.ok();
  68. });
  69. });
  70. describe("Basic", function () {
  71. it("should translate a key that exists in the translation", function () {
  72. expect( i18n.gettext('test') ).to.be( 'test_translation_output' );
  73. });
  74. it("should just pass through strings that aren't translatable", function () {
  75. expect( i18n.gettext('missing') ).to.be( 'missing' );
  76. });
  77. it("should translate a key in a locale with plural-forms rules that don't assume n==1 will return 0", function () {
  78. expect(i18n_3.gettext('test')).to.be('test_translation_output3');
  79. });
  80. it("should allow you to wrap it as a shorthand function", function () {
  81. expect( _('test') ).to.be( 'test_translation_output2' );
  82. expect( _('missing') ).to.be( 'missing' );
  83. });
  84. it("should have identical output for wrapped and non-wrapped instances", function () {
  85. expect( _('test') ).to.be( i18n_2.gettext('test') );
  86. expect( _('missing') ).to.be( i18n_2.gettext('missing') );
  87. });
  88. it("should not allow you to use domains that don't exist", function () {
  89. function badCreate() {
  90. var x = new Jed({
  91. "domain" : "missing_domain",
  92. "locale_data" : locale_data
  93. });
  94. return x;
  95. }
  96. expect( badCreate ).to.throwException();
  97. });
  98. it("should just pass through translations that are empty strings", function () {
  99. expect( _('zero length translation') ).to.be('zero length translation' );
  100. });
  101. it("should call the callback function (if given) when a key is missing", function() {
  102. var callbackCalled;
  103. function missingKeyCallback(key) {
  104. callbackCalled = true;
  105. }
  106. callbackCalled = false;
  107. var jedWithCallback = new Jed({
  108. "missing_key_callback" : missingKeyCallback
  109. });
  110. jedWithCallback.gettext('missing key');
  111. expect(callbackCalled).to.be(true);
  112. callbackCalled = false;
  113. var jedWithoutCallback = new Jed({});
  114. jedWithoutCallback.gettext('missing key');
  115. expect(callbackCalled).to.be(false);
  116. });
  117. });
  118. })();
  119. (function () {
  120. var locale_data = {
  121. "messages_1": {
  122. "": {
  123. "domain": "messages_1",
  124. "lang": "en",
  125. "plural-forms": "nplurals=2; plural=(n != 1);"
  126. },
  127. "test": ["test_1"],
  128. "test singular": ["test_1 singular", "test_1 plural"],
  129. "context\u0004test": ["test_1 context"],
  130. "context\u0004test singular": ["test_1 context singular", "test_1 context plural"]
  131. },
  132. "messages_2": {
  133. "": {
  134. "domain": "messages_2",
  135. "lang": "en",
  136. "plural-forms": "nplurals=2; plural=(n != 1);"
  137. },
  138. "test": ["test_2"],
  139. "test singular": ["test_2 singular", "test_2 plural"],
  140. "context\u0004test": ["test_2 context"],
  141. "context\u0004test singular": ["test_2 context singular", "test_2 context plural"]
  142. }
  143. };
  144. describe("Domain", function () {
  145. var i18n1 = new Jed({
  146. domain : "messages_1",
  147. locale_data : locale_data
  148. });
  149. var i18n_2 = new Jed({
  150. domain : "messages_2",
  151. locale_data : locale_data
  152. });
  153. // No default domain
  154. var i18n_3 = new Jed({
  155. locale_data : locale_data
  156. });
  157. it("should use the correct domain when there are multiple", function () {
  158. expect( i18n1.gettext('test') ).to.be('test_1');
  159. expect( i18n_2.gettext('test') ).to.be('test_2');
  160. });
  161. it("should still pass through non-existent keys", function () {
  162. expect( i18n1.gettext('nope') ).to.be('nope');
  163. expect( i18n_2.gettext('nope again') ).to.be('nope again');
  164. });
  165. it("should reveal the current domain on any instance", function () {
  166. expect( i18n1.textdomain() ).to.be( 'messages_1' );
  167. expect( i18n_2.textdomain() ).to.be( 'messages_2' );
  168. });
  169. it("should use `messages` as the default domain if none given", function () {
  170. expect( i18n_3.textdomain() ).to.be('messages');
  171. });
  172. it("should allow on the fly domain switching", function () {
  173. // Switch these up
  174. i18n1.textdomain('messages_2');
  175. i18n_2.textdomain('messages_1');
  176. expect( i18n1.gettext('test') ).to.be('test_2');
  177. expect( i18n_2.gettext('test') ).to.be('test_1');
  178. expect( i18n1.textdomain() ).to.be( 'messages_2' );
  179. expect( i18n_2.textdomain() ).to.be( 'messages_1' );
  180. });
  181. describe("#dgettext", function () {
  182. it("should have the dgettext function", function () {
  183. expect( i18n_3.dgettext ).to.be.ok();
  184. });
  185. it("should allow you to call the domain on the fly", function () {
  186. expect( i18n_3.dgettext('messages_1', 'test') ).to.be('test_1');
  187. expect( i18n_3.dgettext('messages_2', 'test') ).to.be('test_2');
  188. });
  189. it("should pass through non-existent keys", function () {
  190. expect( i18n_3.dgettext('messages_1', 'nope') ).to.be('nope');
  191. expect( i18n_3.dgettext('messages_2', 'nope again') ).to.be('nope again');
  192. });
  193. });
  194. describe("#dcgettext", function () {
  195. var i18n_4 = new Jed({
  196. locale_data : locale_data
  197. });
  198. it("should have the dcgettext function", function () {
  199. expect( i18n_4.dcgettext ).to.be.ok();
  200. });
  201. it("should ignore categories altogether", function () {
  202. expect( i18n_4.dcgettext('messages_1', 'test', 'A_CATEGORY') ).to.be('test_1');
  203. });
  204. });
  205. });
  206. describe("Pluralization", function () {
  207. var locale_data1 = {
  208. "plural_test": {
  209. "": {
  210. "domain": "plural_test",
  211. "lang": "en",
  212. "plural-forms": "nplurals=2; plural=(n != 1);"
  213. },
  214. "test singular": ["test_1"],
  215. "test plural %1$d": ["test_1_singular %1$d", "test_1_plural %1$d"],
  216. "context\u0004test context": ["test_1context"],
  217. "test2": ["test_2"],
  218. "zero length translation": [""],
  219. "context\u0004test2": ["test_2context"],
  220. "Not translated plural": ["asdf", "asdf"], // this should never hit, since it's msgid2
  221. "context\u0004context plural %1$d": ["context_plural_1 singular %1$d", "context_plural_1 plural %1$d"]
  222. }
  223. };
  224. var locale_data2 = {
  225. "plural_test2": {
  226. "": {
  227. "domain": "plural_test2",
  228. "lang": "sl",
  229. // actual Slovenian pluralization rules
  230. "plural_forms": "nplurals=4; plural=(n==1 ? 0 : n%10==2 ? 1 : n%10==3 || n%10==4 ? 2 : 3);"
  231. },
  232. "Singular" : ["Numerus 0", "Numerus 1", "Numerus 2", "Numerus 3" ]
  233. }
  234. };
  235. var i18n = new Jed({
  236. domain: "plural_test",
  237. locale_data: locale_data1
  238. });
  239. var i18n_2 = new Jed({
  240. domain: "plural_test2",
  241. locale_data: locale_data2
  242. });
  243. describe("#ngettext", function () {
  244. it("should have a ngettext function", function () {
  245. expect( i18n.ngettext ).to.be.ok();
  246. });
  247. it("should choose the correct pluralization translation", function () {
  248. expect( i18n.ngettext('test plural %1$d', 'test plural %1$d', 1) ).to.be( 'test_1_singular %1$d' );
  249. expect( i18n.ngettext('test plural %1$d', 'test plural %1$d', 2) ).to.be( 'test_1_plural %1$d' );
  250. expect( i18n.ngettext('test plural %1$d', 'test plural %1$d', 0) ).to.be( 'test_1_plural %1$d' );
  251. });
  252. it("should still pass through on plurals", function () {
  253. expect(i18n.ngettext('Not translated', 'Not translated plural', 1) ).to.be( 'Not translated' );
  254. expect(i18n.ngettext('Not translated', 'Not translated plural', 2) ).to.be( 'Not translated plural' );
  255. expect(i18n.ngettext('Not translated', 'Not translated plural', 0) ).to.be( 'Not translated plural' );
  256. expect(i18n_2.ngettext('Not translated', 'Not translated plural', 3) ).to.be( 'Not translated plural' );
  257. });
  258. it("should be able to parse complex pluralization rules", function () {
  259. var strings = ['Singular', 'Plural'];
  260. for (var i=0; i<=40; i++) {
  261. var translation = i18n_2.ngettext(strings[0], strings[1], i);
  262. var plural = ((i == 1) ? 0 :
  263. (i % 10 == 2) ? 1 :
  264. (i % 10 == 3 || i % 10 == 4) ? 2 : 3);
  265. expect(translation).to.be( 'Numerus ' + plural );
  266. }
  267. });
  268. });
  269. var locale_data_multi = {
  270. "messages_3": {
  271. "": {
  272. "domain": "messages_3",
  273. "lang": "en",
  274. "plural-forms": "nplurals=2; plural=(n != 1);"
  275. },
  276. "test": ["test_1"],
  277. "test singular": ["test_1 singular", "test_1 plural"],
  278. "context\u0004test": ["test_1 context"],
  279. "context\u0004test singular": ["test_1 context singular", "test_1 context plural"]
  280. },
  281. "messages_4": {
  282. "": {
  283. "domain": "messages_4",
  284. "lang": "en",
  285. "plural-forms": "nplurals=2; plural=(n != 1);"
  286. },
  287. "test": ["test_2"],
  288. "test singular": ["test_2 singular", "test_2 plural"],
  289. "context\u0004test": ["test_2 context"],
  290. "context\u0004test singular": ["test_2 context singular", "test_2 context plural"]
  291. }
  292. };
  293. describe("#dngettext", function () {
  294. var i18n = new Jed({
  295. locale_data : locale_data_multi
  296. });
  297. it("should have a dngettext function", function () {
  298. expect( i18n.dngettext).to.be.ok();
  299. });
  300. it("should pluralize correctly, based on domain rules", function () {
  301. expect(i18n.dngettext('messages_3', 'test singular', 'test plural', 1)).to.be('test_1 singular');
  302. expect(i18n.dngettext('messages_3', 'test singular', 'test plural', 2)).to.be('test_1 plural');
  303. expect(i18n.dngettext('messages_3', 'test singular', 'test plural', 0)).to.be('test_1 plural');
  304. expect(i18n.dngettext('messages_4', 'test singular', 'test plural', 1)).to.be('test_2 singular');
  305. expect(i18n.dngettext('messages_4', 'test singular', 'test plural', 2)).to.be('test_2 plural');
  306. expect(i18n.dngettext('messages_4', 'test singular', 'test plural', 0)).to.be('test_2 plural');
  307. });
  308. it("should passthrough non-found keys regardless of pluralization addition", function (){
  309. expect(i18n.dngettext('messages_3', 'Not translated', 'Not translated plural', 1)).to.be('Not translated');
  310. expect(i18n.dngettext('messages_3', 'Not translated', 'Not translated plural', 2)).to.be('Not translated plural');
  311. expect(i18n.dngettext('messages_3', 'Not translated', 'Not translated plural', 0)).to.be('Not translated plural');
  312. expect(i18n.dngettext('messages_4', 'Not translated', 'Not translated plural', 1)).to.be('Not translated');
  313. expect(i18n.dngettext('messages_4', 'Not translated', 'Not translated plural', 2)).to.be('Not translated plural');
  314. expect(i18n.dngettext('messages_4', 'Not translated', 'Not translated plural', 0)).to.be('Not translated plural');
  315. });
  316. });
  317. describe("#dcngettext", function () {
  318. var i18n = new Jed({
  319. locale_data : locale_data_multi
  320. });
  321. it("should more or less ignore the category", function () {
  322. expect(i18n.dcngettext('messages_3', 'test singular', 'test plural', 1, 'LC_MESSAGES')).to.be('test_1 singular');
  323. expect(i18n.dcngettext('messages_3', 'test singular', 'test plural', 2, 'LC_MESSAGES')).to.be('test_1 plural');
  324. expect(i18n.dcngettext('messages_3', 'test singular', 'test plural', 0, 'LC_MESSAGES')).to.be('test_1 plural');
  325. expect(i18n.dcngettext('messages_4', 'test singular', 'test plural', 1, 'LC_MESSAGES')).to.be('test_2 singular');
  326. expect(i18n.dcngettext('messages_4', 'test singular', 'test plural', 2, 'LC_MESSAGES')).to.be('test_2 plural');
  327. expect(i18n.dcngettext('messages_4', 'test singular', 'test plural', 0, 'LC_MESSAGES')).to.be('test_2 plural');
  328. expect(i18n.dcngettext('messages_3', 'Not translated', 'Not translated plural', 1, 'LC_MESSAGES')).to.be('Not translated');
  329. expect(i18n.dcngettext('messages_3', 'Not translated', 'Not translated plural', 2, 'LC_MESSAGES')).to.be('Not translated plural');
  330. expect(i18n.dcngettext('messages_3', 'Not translated', 'Not translated plural', 0, 'LC_MESSAGES')).to.be('Not translated plural');
  331. expect(i18n.dcngettext('messages_4', 'Not translated', 'Not translated plural', 1, 'LC_MESSAGES')).to.be('Not translated');
  332. expect(i18n.dcngettext('messages_4', 'Not translated', 'Not translated plural', 2, 'LC_MESSAGES')).to.be('Not translated plural');
  333. expect(i18n.dcngettext('messages_4', 'Not translated', 'Not translated plural', 0, 'LC_MESSAGES')).to.be('Not translated plural');
  334. });
  335. });
  336. describe("#pgettext", function () {
  337. var locale_data_w_context = {
  338. "context_test": {
  339. "": {
  340. "domain": "context_test",
  341. "lang": "en",
  342. "plural-forms": "nplurals=2; plural=(n != 1);"
  343. },
  344. "test singular": ["test_1"],
  345. "test plural %1$d": ["test_1_singular %1$d", "test_1_plural %1$d"],
  346. "context\u0004test context": ["test_1context"],
  347. "test2": ["test_2"],
  348. "zero length translation": [""],
  349. "context\u0004test2": ["test_2context"],
  350. "context\u0004context plural %1$d": ["context_plural_1 singular %1$d", "context_plural_1 plural %1$d"]
  351. }
  352. };
  353. var i18n = new Jed({
  354. domain : "context_test",
  355. locale_data : locale_data_w_context
  356. });
  357. it("should expose the pgettext function", function () {
  358. expect( i18n.pgettext ).to.be.ok();
  359. });
  360. it("should accept a context and look up a new key using the context_glue", function () {
  361. expect( i18n.pgettext('context', 'test context') ).to.be( 'test_1context' );
  362. });
  363. it("should still pass through missing keys", function () {
  364. expect( i18n.pgettext('context', 'Not translated') ).to.be( 'Not translated' );
  365. });
  366. it("should make sure same msgid returns diff results w/ context when appropriate", function () {
  367. expect(i18n.gettext('test2')).to.be('test_2');
  368. expect(i18n.pgettext('context', 'test2')).to.be( 'test_2context' );
  369. });
  370. });
  371. describe("#dpgettext", function () {
  372. var i18n = new Jed({
  373. locale_data : locale_data_multi
  374. });
  375. it("should have a dpgettext function", function () {
  376. expect( i18n.dpgettext ).to.be.ok();
  377. });
  378. it("should use the domain and the context simultaneously", function () {
  379. expect(i18n.dpgettext('messages_3', 'context', 'test')).to.be('test_1 context');
  380. expect(i18n.dpgettext('messages_4', 'context', 'test')).to.be('test_2 context');
  381. });
  382. it("should pass through if either the domain, the key or the context isn't found", function () {
  383. expect(i18n.dpgettext('messages_3', 'context', 'Not translated')).to.be('Not translated');
  384. expect(i18n.dpgettext('messages_4', 'context', 'Not translated')).to.be('Not translated');
  385. });
  386. });
  387. describe("#dcpgettext", function () {
  388. var i18n = new Jed({
  389. locale_data : locale_data_multi
  390. });
  391. it("should have a dcpgettext function", function () {
  392. expect( i18n.dcpgettext ).to.be.ok();
  393. });
  394. it("should use the domain and the context simultaneously - ignore the category", function () {
  395. expect(i18n.dcpgettext('messages_3', 'context', 'test', 'LC_MESSAGES')).to.be('test_1 context');
  396. expect(i18n.dcpgettext('messages_4', 'context', 'test', 'LC_MESSAGES')).to.be('test_2 context');
  397. });
  398. it("should pass through if either the domain, the key or the context isn't found", function () {
  399. expect(i18n.dcpgettext('messages_3', 'context', 'Not translated', 'LC_MESSAGES')).to.be('Not translated');
  400. expect(i18n.dcpgettext('messages_4', 'context', 'Not translated', 'LC_MESSAGES')).to.be('Not translated');
  401. });
  402. });
  403. describe("#npgettext", function () {
  404. var locale_data_w_context = {
  405. "context_plural_test": {
  406. "": {
  407. "domain": "context_plural_test",
  408. "lang": "en",
  409. "plural-forms": "nplurals=2; plural=(n != 1);"
  410. },
  411. "test singular": ["test_1"],
  412. "test plural %1$d": ["test_1_singular %1$d", "test_1_plural %1$d"],
  413. "context\u0004test context": ["test_1context"],
  414. "test2": ["test_2"],
  415. "zero length translation": [""],
  416. "context\u0004test2": ["test_2context"],
  417. "context\u0004context plural %1$d": ["context_plural_1 singular %1$d", "context_plural_1 plural %1$d"]
  418. }
  419. };
  420. var i18n = new Jed({
  421. domain : "context_plural_test",
  422. locale_data : locale_data_w_context
  423. });
  424. it("should have a dcpgettext function", function () {
  425. expect( i18n.dcpgettext ).to.be.ok();
  426. });
  427. it("should handle plurals at the same time as contexts", function () {
  428. expect(i18n.npgettext('context', 'context plural %1$d', 'plural %1$d', 1)).to.be('context_plural_1 singular %1$d');
  429. expect(i18n.npgettext('context', 'context plural %1$d', 'plural %1$d', 2)).to.be('context_plural_1 plural %1$d');
  430. expect(i18n.npgettext('context', 'context plural %1$d', 'plural %1$d', 0)).to.be('context_plural_1 plural %1$d');
  431. });
  432. it("should just pass through on not-found cases", function () {
  433. expect(i18n.npgettext('context', 'Not translated', 'Not translated plural', 1)).to.be('Not translated');
  434. expect(i18n.npgettext('context', 'Not translated', 'Not translated plural', 2)).to.be('Not translated plural');
  435. expect(i18n.npgettext('context', 'Not translated', 'Not translated plural', 0)).to.be('Not translated plural');
  436. });
  437. });
  438. describe("#dnpgettext", function () {
  439. var i18n = new Jed({
  440. locale_data : locale_data_multi
  441. });
  442. it("should have a dnpgettext function", function () {
  443. expect( i18n.dnpgettext ).to.be.ok();
  444. });
  445. it("should be able to do a domain, context, and pluralization lookup all at once", function () {
  446. expect(i18n.dnpgettext('messages_3', 'context', 'test singular', 'test plural', 1)).to.be('test_1 context singular');
  447. expect(i18n.dnpgettext('messages_3', 'context', 'test singular', 'test plural', 2)).to.be('test_1 context plural');
  448. expect(i18n.dnpgettext('messages_3', 'context', 'test singular', 'test plural', 0)).to.be('test_1 context plural');
  449. expect(i18n.dnpgettext('messages_4', 'context', 'test singular', 'test plural', 1)).to.be('test_2 context singular');
  450. expect(i18n.dnpgettext('messages_4', 'context', 'test singular', 'test plural', 2)).to.be('test_2 context plural');
  451. expect(i18n.dnpgettext('messages_4', 'context', 'test singular', 'test plural', 0)).to.be('test_2 context plural');
  452. });
  453. it("should pass through if everything doesn't point towards a key", function () {
  454. expect(i18n.dnpgettext('messages_3', 'context', 'Not translated', 'Not translated plural', 1)).to.be('Not translated');
  455. expect(i18n.dnpgettext('messages_3', 'context', 'Not translated', 'Not translated plural', 2)).to.be('Not translated plural');
  456. expect(i18n.dnpgettext('messages_3', 'context', 'Not translated', 'Not translated plural', 0)).to.be('Not translated plural');
  457. expect(i18n.dnpgettext('messages_4', 'context', 'Not translated', 'Not translated plural', 1)).to.be('Not translated');
  458. expect(i18n.dnpgettext('messages_4', 'context', 'Not translated', 'Not translated plural', 2)).to.be('Not translated plural');
  459. expect(i18n.dnpgettext('messages_4', 'context', 'Not translated', 'Not translated plural', 0)).to.be('Not translated plural');
  460. });
  461. });
  462. describe("#dcnpgettext", function () {
  463. var i18n = new Jed({
  464. locale_data : locale_data_multi
  465. });
  466. it("should have a dcnpgettext function", function () {
  467. expect( i18n.dcnpgettext ).to.be.ok();
  468. });
  469. it("should be able to do a domain, context, and pluralization lookup all at once - ignore category", function () {
  470. expect(i18n.dcnpgettext('messages_3', 'context', 'test singular', 'test plural', 1, "LC_MESSAGES")).to.be('test_1 context singular');
  471. expect(i18n.dcnpgettext('messages_3', 'context', 'test singular', 'test plural', 2, "LC_MESSAGES")).to.be('test_1 context plural');
  472. expect(i18n.dcnpgettext('messages_3', 'context', 'test singular', 'test plural', 0, "LC_MESSAGES")).to.be('test_1 context plural');
  473. expect(i18n.dcnpgettext('messages_4', 'context', 'test singular', 'test plural', 1, "LC_MESSAGES")).to.be('test_2 context singular');
  474. expect(i18n.dcnpgettext('messages_4', 'context', 'test singular', 'test plural', 2, "LC_MESSAGES")).to.be('test_2 context plural');
  475. expect(i18n.dcnpgettext('messages_4', 'context', 'test singular', 'test plural', 0, "LC_MESSAGES")).to.be('test_2 context plural');
  476. });
  477. it("should pass through if everything doesn't point towards a key", function () {
  478. expect(i18n.dcnpgettext('messages_3', 'context', 'Not translated', 'Not translated plural', 1, "LC_MESSAGES")).to.be('Not translated');
  479. expect(i18n.dcnpgettext('messages_3', 'context', 'Not translated', 'Not translated plural', 2, "LC_MESSAGES")).to.be('Not translated plural');
  480. expect(i18n.dcnpgettext('messages_3', 'context', 'Not translated', 'Not translated plural', 0, "LC_MESSAGES")).to.be('Not translated plural');
  481. expect(i18n.dcnpgettext('messages_4', 'context', 'Not translated', 'Not translated plural', 1, "LC_MESSAGES")).to.be('Not translated');
  482. expect(i18n.dcnpgettext('messages_4', 'context', 'Not translated', 'Not translated plural', 2, "LC_MESSAGES")).to.be('Not translated plural');
  483. expect(i18n.dcnpgettext('messages_4', 'context', 'Not translated', 'Not translated plural', 0, "LC_MESSAGES")).to.be('Not translated plural');
  484. });
  485. });
  486. });
  487. describe("Plural Forms Parsing", function (){
  488. // This is the method from the original gettext.js that uses new Function
  489. function evalParse( plural_forms ) {
  490. var pf_re = new RegExp('^(\\s*nplurals\\s*=\\s*[0-9]+\\s*;\\s*plural\\s*=\\s*(?:\\s|[-\\?\\|&=!<>+*/%:;a-zA-Z0-9_\(\)])+)', 'm');
  491. if (pf_re.test(plural_forms)) {
  492. var pf = plural_forms;
  493. if (! /;\s*$/.test(pf)) pf = pf.concat(';');
  494. var code = 'var plural; var nplurals; '+pf+' return { "nplural" : nplurals, "plural" : (plural === true ? 1 : plural ? plural : 0) };';
  495. return (new Function("n", code));
  496. } else {
  497. throw new Error("Syntax error in language file. Plural-Forms header is invalid ["+plural_forms+"]");
  498. }
  499. }
  500. // http://translate.sourceforge.net/wiki/l10n/pluralforms
  501. it("should have the same result as doing an eval on the expression for all known plural-forms.", function (){
  502. var pfs = ["nplurals=2; plural=(n > 1)","nplurals=2; plural=(n != 1)","nplurals=6; plural= n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 ? 4 : 5;","nplurals=1; plural=0","nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)","nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2","nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2","nplurals=4; plural= (n==1) ? 0 : (n==2) ? 1 : (n != 8 && n != 11) ? 2 : 3","nplurals=2; plural=n > 1","nplurals=5; plural=n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n<11 ? 3 : 4","nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : (n > 2 && n < 20) ? 2 : 3","nplurals=2; plural= (n > 1)","nplurals=2; plural=(n%10!=1 || n%100==11)","nplurals=2; plural=n!=0","nplurals=2; plural=(n!=1)","nplurals=2; plural=(n!= 1)","nplurals=4; plural= (n==1) ? 0 : (n==2) ? 1 : (n == 3) ? 2 : 3","nplurals=2; plural=n>1;","nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2)","nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2)","nplurals=2; plural= n==1 || n%10==1 ? 0 : 1","nplurals=3; plural=(n==0 ? 0 : n==1 ? 1 : 2)","nplurals=4; plural=(n==1 ? 0 : n==0 || ( n%100>1 && n%100<11) ? 1 : (n%100>10 && n%100<20 ) ? 2 : 3)","nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)","nplurals=2; plural=(n!=1);","nplurals=3; plural=(n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < 20)) ? 1 : 2);","nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || n%100==4 ? 3 : 0)","nplurals=2; plural=n != 1","nplurals=2; plural=(n>1)","nplurals=1; plural=0;"],
  503. pf, pfc, pfe, pfi, i;
  504. for ( pfi = 0; pfi < pfs.length; pfi++ ) {
  505. pf = ""+pfs[ pfi ];
  506. for( i = 0; i < 106; i++ ){
  507. pfc = Jed.PF.compile( ""+pf )( i );
  508. pfe = evalParse( ""+pf )( i ).plural;
  509. if (pfc !== pfe) {
  510. throw new Error('expected ' + pfe + ' but got ' + pfc);
  511. }
  512. }
  513. }
  514. });
  515. });
  516. describe("Chainable API", function () {
  517. var locale_data_w_context = {
  518. "context_sprintf_test": {
  519. "": {
  520. "domain": "context_sprintf_test",
  521. "lang": "en",
  522. "plural-forms": "nplurals=2; plural=(n != 1);"
  523. },
  524. "test singular": ["test_1"],
  525. "test plural %1$d": ["test_1_singular %1$d", "test_1_plural %1$d"],
  526. "context\u0004test context": ["test_1context"],
  527. "test2": ["test_2"],
  528. "zero length translation": [""],
  529. "context\u0004test2": ["test_2context"],
  530. "context\u0004context plural %1$d": ["context_plural_1 singular %1$d", "context_plural_1 plural %1$d"]
  531. },
  532. "other_domain": {
  533. "": {
  534. "domain": "other_domain",
  535. "lang": "en",
  536. "plural-forms": "nplurals=2; plural=(n != 1);"
  537. },
  538. "test other_domain singular": ["other domain test 1"],
  539. "context\u0004context other plural %1$d": ["context_plural_1 singular %1$d", "context_plural_1 plural %1$d"]
  540. }
  541. };
  542. var i18n = new Jed({
  543. "locale_data" : locale_data_w_context,
  544. "domain": "context_sprintf_test"
  545. });
  546. it("should handle a simple gettext passthrough", function (){
  547. expect( i18n.translate('test singular').fetch() ).to.be('test_1');
  548. });
  549. it("should handle changing domains", function (){
  550. expect( i18n.translate('test other_domain singular').onDomain('other_domain').fetch() ).to.be('other domain test 1');
  551. });
  552. it("should allow you to add plural information in the chain.", function () {
  553. expect( i18n.translate("test plural %1$d").ifPlural(5, "dont matta").fetch() ).to.be( "test_1_plural %1$d" );
  554. });
  555. it("should take in a sprintf set of args (as array) on the plural lookup", function(){
  556. expect( i18n.translate("test plural %1$d").ifPlural(5, "dont matta").fetch([5]) ).to.be( "test_1_plural 5" );
  557. expect( i18n.translate("test plural %1$d %2$d").ifPlural(5, "dont matta %1$d %2$d").fetch([5, 6]) ).to.be( "dont matta 5 6" );
  558. expect( i18n.translate("test plural %1$d %2$d").ifPlural(1, "dont matta %1$d %2$d").fetch([1, 6]) ).to.be( "test plural 1 6" );
  559. });
  560. it("should take in a sprintf set of args (as args) on the plural lookup", function(){
  561. expect( i18n.translate("test plural %1$d %2$d").ifPlural(5, "dont matta %1$d %2$d").fetch(5, 6) ).to.be( "dont matta 5 6" );
  562. expect( i18n.translate("test plural %1$d %2$d").ifPlural(1, "dont matta %1$d %2$d").fetch(1, 6) ).to.be( "test plural 1 6" );
  563. });
  564. it("should handle context information.", function () {
  565. expect(i18n.translate('test context').withContext('context').fetch() ).to.be('test_1context');
  566. });
  567. it("should be able to do all at the same time.", function () {
  568. expect( i18n.translate("context other plural %1$d").withContext('context').onDomain('other_domain').ifPlural(5, "ignored %1$d").fetch(5) ).to.be( "context_plural_1 plural 5" );
  569. expect( i18n.translate("context other plural %1$d").withContext('context').onDomain('other_domain').ifPlural(1, "ignored %1$d").fetch(1) ).to.be( "context_plural_1 singular 1" );
  570. });
  571. });
  572. describe("Sprintf", function () {
  573. var locale_data_w_context = {
  574. "context_sprintf_test": {
  575. "": {
  576. "domain": "context_sprintf_test",
  577. "lang": "en",
  578. "plural-forms": "nplurals=2; plural=(n != 1);"
  579. },
  580. "test singular": ["test_1"],
  581. "test plural %1$d": ["test_1_singular %1$d", "test_1_plural %1$d"],
  582. "context\u0004test context": ["test_1context"],
  583. "test2": ["test_2"],
  584. "zero length translation": [""],
  585. "context\u0004test2": ["test_2context"],
  586. "context\u0004context plural %1$d": ["context_plural_1 singular %1$d", "context_plural_1 plural %1$d"]
  587. }
  588. };
  589. var i18n = new Jed({
  590. "locale_data" : locale_data_w_context,
  591. "domain": "context_sprintf_test"
  592. });
  593. it("should take multiple types of arrays as input", function () {
  594. var strings = {
  595. "blah" : "blah",
  596. "thing%1$sbob" : "thing[one]bob",
  597. "thing%1$s%2$sbob" : "thing[one][two]bob",
  598. "thing%1$sasdf%2$sasdf" : "thing[one]asdf[two]asdf",
  599. "%1$s%2$s%3$s" : "[one][two]",
  600. "tom%1$saDick" : "tom[one]aDick"
  601. };
  602. var args = ["[one]", "[two]"];
  603. for (var i in strings) {
  604. // test using new Array
  605. expect(Jed.sprintf(i, ["[one]","[two]"])).to.be(strings[i]);
  606. expect(i18n.sprintf(i, ["[one]","[two]"])).to.be(strings[i]);
  607. // test using predefined array
  608. expect(Jed.sprintf(i, args)).to.be(strings[i]);
  609. expect(i18n.sprintf(i, args)).to.be(strings[i]);
  610. }
  611. });
  612. it("should accept a single string instead of an array", function () {
  613. // test using scalar rather than array
  614. var strings = {
  615. "blah" : "blah",
  616. "" : "",
  617. "%%" : "%",
  618. "tom%%dick" : "tom%dick",
  619. "thing%1$sbob" : "thing[one]bob",
  620. "thing%1$s%2$sbob" : "thing[one]bob",
  621. "thing%1$sasdf%2$sasdf" : "thing[one]asdfasdf",
  622. "%1$s%2$s%3$s" : "[one]"
  623. };
  624. var arg = "[one]";
  625. for (var i in strings) {
  626. expect(Jed.sprintf(i, arg)).to.be(strings[i]);
  627. expect(i18n.sprintf(i, arg)).to.be(strings[i]);
  628. }
  629. });
  630. });
  631. })();
  632. })( Jed );