Navigation Menu

Skip to content

Commit

Permalink
Bind i18n.t (#1682)
Browse files Browse the repository at this point in the history
* Fix spelling

* Allow using t as a free function

This facilitates using t via destructuring or as a callback.  Several people have run into this; see #1287.

* Use a fixed time zone for automated tests

This fixes some test failures in some time zones (such as Eastern US).

* Bind all functions, not just t

As discussed at #1681 and #1682.
  • Loading branch information
joshkel committed Nov 2, 2021
1 parent cd721b7 commit b428ec2
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 6 deletions.
4 changes: 4 additions & 0 deletions karma.conf.js
@@ -1,6 +1,10 @@
//const istanbul = require( 'browserify-istanbul' );

module.exports = function (karma) {
// Ensure consistent conversion of timestamps to date strings (has no effect
// on Windows)
process.env.TZ = 'UTC';

karma.set({
frameworks: ['mocha', 'chai', 'sinon', 'browserify'],

Expand Down
13 changes: 13 additions & 0 deletions src/i18next.js
Expand Up @@ -13,6 +13,17 @@ import { defer, isIE10 } from './utils.js';

function noop() { }

// Binds the member functions of the given class instance so that they can be
// destructured or used as callbacks.
function bindMemberFunctions(inst) {
const mems = Object.getOwnPropertyNames(Object.getPrototypeOf(inst))
mems.forEach((mem) => {
if (typeof inst[mem] === 'function') {
inst[mem] = inst[mem].bind(inst)
}
})
}

class I18n extends EventEmitter {
constructor(options = {}, callback) {
super();
Expand All @@ -25,6 +36,8 @@ class I18n extends EventEmitter {
this.logger = baseLogger;
this.modules = { external: [] };

bindMemberFunctions(this);

if (callback && !this.isInitialized && !options.isClone) {
// https://github.com/i18next/i18next/issues/879
if (!this.options.initImmediate) {
Expand Down
19 changes: 13 additions & 6 deletions test/i18next.spec.js
Expand Up @@ -17,7 +17,7 @@ describe('i18next', () => {
newInstance = i18next.createInstance({ bar: 'foo' });
});

it('it should not inherit options from inital i18next', () => {
it('it should not inherit options from initial i18next', () => {
expect(newInstance.options.foo).to.not.be.ok;
expect(newInstance.options.bar).to.equal('foo');
});
Expand All @@ -33,7 +33,7 @@ describe('i18next', () => {
newInstance = i18next.cloneInstance({ bar: 'foo' });
});

it('it should inherit options from inital i18next', () => {
it('it should inherit options from initial i18next', () => {
expect(newInstance.options.foo).to.equal('bar');
expect(newInstance.options.bar).to.equal('foo');
});
Expand Down Expand Up @@ -75,6 +75,13 @@ describe('i18next', () => {
});

describe('i18next - functions', () => {
describe('t', () => {
it('is usable as a free function', () => {
const { t } = i18next;
expect(t('key')).to.equal('key');
});
});

describe('getFixedT', () => {
it('it should have lng, ns on t', () => {
const t = i18next.getFixedT('de', 'common');
Expand All @@ -99,15 +106,15 @@ describe('i18next', () => {

describe('chained resource manipulation', () => {
describe('can add resources', () => {
it('it adds resouces by addResource', () => {
it('it adds resources by addResource', () => {
i18next
.addResource('de', 'translation', 'test', 'test')
.addResource('de', 'translation', 'nest.test', 'test_nest');
expect(i18next.getResource('de', 'translation', 'test')).to.equal('test');
expect(i18next.getResource('de', 'translation', 'nest.test')).to.equal('test_nest');
});

it('it adds resouces by addResources', () => {
it('it adds resources by addResources', () => {
i18next
.addResources('fr', 'translation', {
hi: 'salut',
Expand All @@ -120,7 +127,7 @@ describe('i18next', () => {
expect(i18next.getResource('fr', 'translation', 'hello')).to.equal('bonjour');
});

it('it adds resouces by addResourceBundle', () => {
it('it adds resources by addResourceBundle', () => {
i18next
.addResourceBundle('en.translation', { something1: 'deeper1' })
.addResourceBundle('en.translation', { something2: 'deeper2' });
Expand All @@ -131,7 +138,7 @@ describe('i18next', () => {
});

describe('can remove resources bundle', () => {
it('it removes resouces by removeResourceBundle', () => {
it('it removes resources by removeResourceBundle', () => {
i18next.removeResourceBundle('en', 'translation');
expect(i18next.getResourceBundle('en', 'translation')).to.be.not.ok;
});
Expand Down

0 comments on commit b428ec2

Please sign in to comment.