Skip to content

Commit

Permalink
Merge pull request #63 from OCTRI/i18next-promises
Browse files Browse the repository at this point in the history
Use promises returned by i18next methods instead of wrapping in a custom promise.
  • Loading branch information
heathharrelson authored Mar 14, 2019
2 parents d2aed24 + f702d89 commit ae103a5
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 87 deletions.
88 changes: 36 additions & 52 deletions addon/services/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { isBlank } from '@ember/utils';
import { assert } from '@ember/debug';
import {
resolve,
Promise as EmberPromise,
hash
} from 'rsvp';
import { computed } from '@ember/object';
Expand Down Expand Up @@ -44,9 +43,8 @@ const I18nService = Service.extend({
const lang = value;

if (this.get('isInitialized')) {
this._changeLocale(lang).then(lang => {
this.set('_locale', lang);
});
this._changeLocale(lang)
.then(lang => this.set('_locale', lang));
} else {
this.set('_locale', lang);
}
Expand All @@ -64,18 +62,17 @@ const I18nService = Service.extend({
initLibraryAsync() {
const i18next = this.get('i18next');

return this._runPreInitActions().then(() => {
return this._initLibrary();
}).then(() => {
return this._runPostInitActions();
}).then(() => {
this.set('_locale', i18next.language);
this.set('isInitialized', true);
return resolve();
}).catch(reason => {
// eslint-disable-next-line no-console
console.warn(`A promise in the i18next init chain rejected with reason: ${reason}`);
});
return this._runPreInitActions()
.then(() => this._initLibrary())
.then(() => this._runPostInitActions())
.then(() => {
this.set('_locale', i18next.language);
this.set('isInitialized', true);
return resolve();
}).catch(reason => {
// eslint-disable-next-line no-console
console.warn(`A promise in the i18next init chain rejected with reason: ${reason}`);
});
},

/**
Expand Down Expand Up @@ -158,16 +155,14 @@ const I18nService = Service.extend({
}

const oldLang = this._locale;
return this._runPreInitActions(lang).then(() => {
return this._setLng(lang);
}).then(() => {
return this._runPostInitActions(oldLang);
}).then(() => {
return resolve(lang);
}).catch(reason => {
// eslint-disable-next-line no-console
console.warn(`A promise in the locale change path rejected with reason: ${reason}`);
});
return this._runPreInitActions(lang)
.then(() => this._setLng(lang))
.then(() => this._runPostInitActions(oldLang))
.then(() => resolve(lang))
.catch(reason => {
// eslint-disable-next-line no-console
console.warn(`A promise in the locale change path rejected with reason: ${reason}`);
});
},

/**
Expand Down Expand Up @@ -277,36 +272,25 @@ const I18nService = Service.extend({
},

_initLibrary() {
return new EmberPromise((resolve, reject) => {
const i18next = this.get('i18next');
const options = config.i18nextOptions || {};

//
// TODO: Adding i18nextXHRBackend by default so that translation
// files can be loaded.
// How do we extend this so that other plugins can be added
// dynamically?
//
i18next
.use(i18nextXHRBackend)
.init(options, (err) => {
if (err) {
reject(err);
} else {
resolve(i18next);
}
});
});
const i18next = this.get('i18next');
const options = config.i18nextOptions || {};

//
// TODO: Adding i18nextXHRBackend by default so that translation
// files can be loaded.
// How do we extend this so that other plugins can be added
// dynamically?
//
return i18next
.use(i18nextXHRBackend)
.init(options)
.then(() => resolve(i18next));
},

_setLng(locale) {
const i18next = this.get('i18next');

return new EmberPromise(resolve => {
i18next.changeLanguage(locale, () => {
resolve(locale);
});
});
return i18next.changeLanguage(locale)
.then(() => resolve(locale));
},

_getActionCallHash(actions, lang) {
Expand Down
42 changes: 16 additions & 26 deletions tests/unit/services/i18n-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,16 @@ const mockI18next = {
return this;
},
init(options, cb) {
cb();
if (cb) {
cb();
}
return Promise.resolve();
},
changeLanguage(lng, cb) {
cb();
if (cb) {
cb();
}
return Promise.resolve();
}
};

Expand Down Expand Up @@ -43,7 +49,7 @@ module('service:i18n', function(hooks) {
'Throws if post-init action is not a function.');
});

test('initLibraryAsync triggers pre-init actions', function (assert) {
test('initLibraryAsync triggers pre-init actions', async function (assert) {
const service = this.owner.lookup('service:i18n');
service.set('i18next', mockI18next);

Expand All @@ -58,14 +64,11 @@ module('service:i18n', function(hooks) {

service.unregisterPreInitAction('removed-pre-init');

const done = assert.async();
assert.expect(1);
service.initLibraryAsync().then(() => {
done();
});
await service.initLibraryAsync();
});

test('initLibraryAsync triggers post-init actions', function (assert) {
test('initLibraryAsync triggers post-init actions', async function (assert) {
const service = this.owner.lookup('service:i18n');
service.set('i18next', mockI18next);

Expand All @@ -80,23 +83,18 @@ module('service:i18n', function(hooks) {

service.unregisterPostInitAction('removed-post-init');

const done = assert.async();
assert.expect(1);
service.initLibraryAsync().then(() => {
done();
});
await service.initLibraryAsync();
});

test('setting locale triggers pre-init actions', function (assert) {
test('setting locale triggers pre-init actions', async function (assert) {
const service = this.owner.factoryFor('service:i18n').create({
_locale: 'en',
isInitialized: true
});

service.set('i18next', mockI18next);

const done = assert.async();

service.registerPreInitAction('removed-pre-init', () => {
// should not get here
assert.ok(false, 'Setting locale should not trigger unregistered actions');
Expand All @@ -110,22 +108,17 @@ module('service:i18n', function(hooks) {
service.unregisterPreInitAction('removed-pre-init');

assert.expect(2);

service._changeLocale('th').then(() => {
done();
});
await service._changeLocale('th');
});

test('setting locale triggers post-init actions', function (assert) {
test('setting locale triggers post-init actions', async function (assert) {
const service = this.owner.factoryFor('service:i18n').create({
_locale: 'en',
isInitialized: true
});

service.set('i18next', mockI18next);

const done = assert.async();

service.registerPostInitAction('removed-post-init', () => {
// should not get here
assert.ok(false, 'Setting locale should not trigger unregistered actions');
Expand All @@ -139,9 +132,6 @@ module('service:i18n', function(hooks) {
service.unregisterPostInitAction('removed-post-init');

assert.expect(2);

service._changeLocale('th').then(() => {
done();
});
await service._changeLocale('th');
});
});
4 changes: 3 additions & 1 deletion tests/unit/utils/macro-test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { module, test } from 'qunit';
import { run } from '@ember/runloop';
import { setupTest } from 'ember-qunit';
import { settled } from '@ember/test-helpers';
import { translationMacro as t } from 'ember-i18next';
import EmberObject from '@ember/object';

Expand Down Expand Up @@ -35,9 +36,10 @@ module('Unit | Utils | translationMacro', function(hooks) {
assert.equal(this.object.get('tMacroWithInterpolation'), 'Clicks: 13');
});

test('defines a computed property that depends on the locale', function (assert) {
test('defines a computed property that depends on the locale', async function (assert) {
assert.equal(this.object.get('tMacroNoInterpolation'), 'text with no interpolations');
run(this.object, 'set', 'i18n.locale', 'th');
await settled();
assert.equal(this.object.get('tMacroNoInterpolation'), 'thai text with no interpolations');
});
});
25 changes: 17 additions & 8 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,13 @@
dependencies:
regenerator-runtime "^0.12.0"

"@babel/runtime@^7.3.1":
version "7.3.4"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.3.4.tgz#73d12ba819e365fcf7fd152aed56d6df97d21c83"
integrity sha512-IvfvnMdSaLBateu0jfsYIpZTxAc2cKEXEMiezGGN75QcBcecDUKd3PgLAncT0oOgxKy8dd8hrJKj9MfzgfZd6g==
dependencies:
regenerator-runtime "^0.12.0"

"@babel/template@^7.1.0", "@babel/template@^7.1.2", "@babel/template@^7.2.2":
version "7.2.2"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.2.2.tgz#005b3fdf0ed96e88041330379e0da9a708eb2907"
Expand Down Expand Up @@ -4551,15 +4558,17 @@ http-proxy@^1.13.1, http-proxy@^1.17.0:
follow-redirects "^1.0.0"
requires-port "^1.0.0"

i18next-xhr-backend@^1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/i18next-xhr-backend/-/i18next-xhr-backend-1.5.1.tgz#50282610780c6a696d880dfa7f4ac1d01e8c3ad5"
integrity sha512-9OLdC/9YxDvTFcgsH5t2BHCODHEotHCa6h7Ly0EUlUC7Y2GS09UeoHOGj3gWKQ3HCqXz8NlH4gOrK3NNc9vPuw==
i18next-xhr-backend@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/i18next-xhr-backend/-/i18next-xhr-backend-2.0.1.tgz#7af735ee1b0c6d4ce49fa5756591040a0fba6db7"
integrity sha512-CP0XPjJsTE4hY1rM1KXFYo63Ib61EBLEcTvMDyJwr0vs9p/UTuA3ENCmzSs9+ghZgWSjdOigc0oUERHaxctbsQ==

i18next@^11.10.0:
version "11.10.2"
resolved "https://registry.yarnpkg.com/i18next/-/i18next-11.10.2.tgz#e5f10346f6320ecf15595419926c25255381a56c"
integrity sha512-1rowdX8PqrvsdFhYb3v0A/LlIHLQL1HTa4ia29IzhvNAg2fesNV7R1jXibWLmLQdz3FfTB8RuqSqDEjIawXruA==
i18next@^15.0.7:
version "15.0.7"
resolved "https://registry.yarnpkg.com/i18next/-/i18next-15.0.7.tgz#2f61240c8b2b6656233217a8eee07a09a5707fea"
integrity sha512-KCSmTOE0nsku53cI0sSBY21ftXhsAfCjcNQBx54Y0AxcTxSs+v+qGFQ38ab+vi6F4NZEm8JupO36vlWoeF47cA==
dependencies:
"@babel/runtime" "^7.3.1"

[email protected]:
version "0.4.23"
Expand Down

0 comments on commit ae103a5

Please sign in to comment.