i18n.test.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import { Tracker } from 'meteor/tracker';
  2. import chai, { expect } from 'chai';
  3. import sinon from 'sinon';
  4. import { TAPi18n } from './tap';
  5. chai.use(require('sinon-chai'));
  6. chai.use(require('chai-as-promised'));
  7. describe('TAPi18n', () => {
  8. beforeEach(() => {
  9. sinon.stub(console, 'log');
  10. });
  11. afterEach(() => {
  12. sinon.restore();
  13. });
  14. if (Meteor.isClient) {
  15. it('extra languages are not loaded initially', () => {
  16. // Using function here to prevent Meteor from including the file
  17. // during building time
  18. function path(language) {
  19. return `./data/${language}.i18n.json`;
  20. }
  21. expect(() => require(path('de'))).to.throw('Cannot find module');
  22. });
  23. }
  24. describe('.init', () => {
  25. it('has default language translation loaded', async () => {
  26. sinon.spy(TAPi18n, 'loadLanguage');
  27. await TAPi18n.init();
  28. expect(TAPi18n.loadLanguage).to.be.calledWith('en');
  29. expect(TAPi18n.getLanguage()).to.be.equal('en');
  30. expect(TAPi18n.__('accept')).to.be.equal('Accept');
  31. });
  32. });
  33. describe('.getSupportedLanguages', () => {
  34. it('returns an array of objects with expected structure', () => {
  35. const languages = TAPi18n.getSupportedLanguages();
  36. expect(languages).to.be.an('array');
  37. for (const language of languages) {
  38. expect(language).to.have.keys('name', 'code', 'isoCode');
  39. }
  40. });
  41. });
  42. describe('.getLanguage', () => {
  43. it('is reactive', async () => {
  44. const tracked = [];
  45. Tracker.autorun(() => {
  46. tracked.push(TAPi18n.getLanguage());
  47. });
  48. expect(tracked).to.have.members(['en']);
  49. await TAPi18n.setLanguage('de');
  50. Tracker.flush();
  51. expect(tracked).to.have.members(['en', 'de']);
  52. });
  53. });
  54. describe('.loadLanguage', () => {
  55. beforeEach(() => {
  56. sinon.stub(TAPi18n.i18n, 'addResourceBundle');
  57. });
  58. it('actually loads the language data', async () => {
  59. await TAPi18n.loadLanguage('fr');
  60. expect(TAPi18n.i18n.addResourceBundle).to.be.calledOnceWith('fr');
  61. expect(TAPi18n.i18n.addResourceBundle.firstCall.args[2]).to.have.property('accept');
  62. });
  63. it('does nothing if language is missing', async () => {
  64. await expect(TAPi18n.loadLanguage('miss')).to.be.fulfilled;
  65. expect(TAPi18n.i18n.addResourceBundle).to.not.be.called;
  66. });
  67. });
  68. describe('.__', () => {
  69. beforeEach(async () => {
  70. await TAPi18n.init();
  71. TAPi18n.i18n.addResourceBundle('fr', 'translation', {
  72. 'simple': 'Hello',
  73. 'positional': 'Hello, %s! How is your %s?',
  74. 'named': 'Hello, __whom__! How is your __what__?',
  75. });
  76. TAPi18n.i18n.changeLanguage('fr');
  77. });
  78. it('works with simple keys', () => {
  79. const result = TAPi18n.__('simple');
  80. expect(result).to.be.equal('Hello');
  81. });
  82. it('works with simple keys and custom language', async () => {
  83. TAPi18n.i18n.addResourceBundle('de', 'translation', {
  84. 'simple': 'Hola',
  85. });
  86. const result = TAPi18n.__('simple', null, 'de');
  87. expect(result).to.be.equal('Hola');
  88. });
  89. it('works with positional parameters', () => {
  90. const result = TAPi18n.__('positional', {
  91. sprintf: ['Josh', 'life']
  92. });
  93. expect(result).to.be.equal('Hello, Josh! How is your life?');
  94. });
  95. it('works with named parameters', () => {
  96. const result = TAPi18n.__('named', {
  97. whom: 'Annie',
  98. what: 'job'
  99. });
  100. expect(result).to.be.equal('Hello, Annie! How is your job?');
  101. });
  102. });
  103. });