typescript-closure-tools
Version:
Command-line tools to convert closure-style JSDoc annotations to typescript, and to convert typescript sources to closure externs files
1,201 lines (933 loc) • 55.1 kB
text/typescript
/// <reference path="../sinon/sinon.d.ts" />
/// <reference path="../mocha/mocha.d.ts" />
/// <reference path="../expect.js/expect.js.d.ts" />
/// <reference path="../js-fixtures/fixtures.d.ts" />
/// <reference path="../jquery/jquery.d.ts" />
/// <reference path="i18next.d.ts" />
declare function done(): void;
describe('i18next', function () {
var i18n = $.i18n
, opts: I18nextOptions;
beforeEach(function () {
opts = {
lng: 'en-US',
load: 'all',
fallbackLng: 'dev',
preload: [],
lowerCaseLng: false,
ns: 'translation',
resGetPath: 'locales/__lng__/__ns__.json',
dynamicLoad: false,
useLocalStorage: false,
sendMissing: false,
getAsync: true,
returnObjectTrees: false,
debug: true,
selectorAttr: 'data-i18n',
postProcess: '',
interpolationPrefix: '__',
interpolationSuffix: '__'
};
});
describe('Initialisation', function () {
describe('with passed in resource set', function () {
var resStore = {
dev: { translation: { 'simple_dev': 'ok_from_dev' } },
en: { translation: { 'simple_en': 'ok_from_en' } },
'en-US': { translation: { 'simple_en-US': 'ok_from_en-US' } }
};
beforeEach(function (done) {
i18n.init($.extend(opts, { resStore: resStore }),
function (t) { done(); });
});
it('it should provide passed in resources for translation', function () {
expect(i18n.t('simple_en-US')).to.be('ok_from_en-US');
expect(i18n.t('simple_en')).to.be('ok_from_en');
expect(i18n.t('simple_dev')).to.be('ok_from_dev');
});
});
describe('loading from server', function () {
describe('with static route', function () {
beforeEach(function (done) {
i18n.init(opts, function (t) { done(); });
});
it('it should provide loaded resources for translation', function () {
expect(i18n.t('simple_en-US')).to.be('ok_from_en-US');
expect(i18n.t('simple_en')).to.be('ok_from_en');
expect(i18n.t('simple_dev')).to.be('ok_from_dev');
});
});
describe('with dynamic route', function () {
beforeEach(function (done) {
var res = {
dev: { translation: { 'simple_dev': 'ok_from_dev' } },
en: { translation: { 'simple_en': 'ok_from_en' } },
'en-US': { translation: { 'simple_en-US': 'ok_from_en-US' } }
};
var server = sinon.fakeServer.create();
server.autoRespond = true;
server.respondWith(<any[]>[200, { "Content-Type": "application/json" }, JSON.stringify(res)]);
i18n.init($.extend(opts, {
resGetPath: 'locales/resources.json?lng=__lng__&ns=__ns__',
dynamicLoad: true
}),
function (t) { server.restore(); done(); });
});
it('it should provide loaded resources for translation', function () {
expect(i18n.t('simple_en-US')).to.be('ok_from_en-US');
expect(i18n.t('simple_en')).to.be('ok_from_en');
expect(i18n.t('simple_dev')).to.be('ok_from_dev');
});
});
});
describe('advanced initialisation options', function () {
describe('setting load', function () {
describe('to current', function () {
var spy: any;
beforeEach(function (done) {
spy = sinon.spy(i18n.sync, '_fetchOne');
i18n.init($.extend(opts, {
load: 'current'
}),
function (t) { done(); });
});
afterEach(function () {
spy.restore();
});
it('it should load only current and fallback language', function () {
expect(spy.callCount).to.be(2); // en-US, en
});
it('it should provide loaded resources for translation', function () {
expect(i18n.t('simple_en-US')).to.be('ok_from_en-US');
expect(i18n.t('simple_en')).not.to.be('ok_from_en');
expect(i18n.t('simple_dev')).to.be('ok_from_dev');
});
});
describe('to unspecific', function () {
var spy: any;
beforeEach(function (done) {
spy = sinon.spy(i18n.sync, '_fetchOne');
i18n.init($.extend(opts, {
load: 'unspecific'
}),
function (t) { done(); });
});
afterEach(function () {
spy.restore();
});
it('it should load only unspecific and fallback language', function () {
expect(spy.callCount).to.be(2); // en-US, en
});
it('it should provide loaded resources for translation', function () {
expect(i18n.t('simple_en-US')).not.to.be('ok_from_en-US');
expect(i18n.t('simple_en')).to.be('ok_from_en');
expect(i18n.t('simple_dev')).to.be('ok_from_dev');
});
it('it should return unspecific language', function () {
expect(i18n.lng()).to.be('en');
});
});
});
describe('with fallback language set to false', function () {
var spy: any;
beforeEach(function (done) {
spy = sinon.spy(i18n.sync, '_fetchOne');
i18n.init($.extend(opts, {
fallbackLng: false
}),
function (t) { done(); });
});
afterEach(function () {
spy.restore();
});
it('it should load only specific and unspecific languages', function () {
expect(spy.callCount).to.be(2); // en-US, en
});
it('it should provide loaded resources for translation', function () {
expect(i18n.t('simple_en-US')).to.be('ok_from_en-US');
expect(i18n.t('simple_en')).to.be('ok_from_en');
expect(i18n.t('simple_dev')).not.to.be('ok_from_dev');
});
});
describe('preloading multiple languages', function () {
var spy: any;
beforeEach(function (done) {
spy = sinon.spy(i18n.sync, '_fetchOne');
i18n.init($.extend(opts, {
preload: ['fr', 'de-DE']
}),
function (t) { done(); });
});
afterEach(function () {
spy.restore();
});
it('it should load additional languages', function () {
expect(spy.callCount).to.be(6); // en-US, en, de-DE, de, fr, dev
});
describe('changing the language', function () {
beforeEach(function (done) {
spy.reset();
i18n.setLng('de-DE',
function (t) { done(); });
});
it('it should reload the preloaded languages', function () {
expect(spy.callCount).to.be(4); // de-DE, de, fr, dev
});
});
});
describe('with synchronous flag', function () {
beforeEach(function () {
i18n.init($.extend(opts, { getAsync: false }));
});
it('it should provide loaded resources for translation', function () {
expect(i18n.t('simple_en-US')).to.be('ok_from_en-US');
expect(i18n.t('simple_en')).to.be('ok_from_en');
expect(i18n.t('simple_dev')).to.be('ok_from_dev');
});
});
describe('with namespace', function () {
describe('with one namespace set', function () {
beforeEach(function (done) {
i18n.init($.extend(opts, { ns: 'ns.special' }),
function (t) { done(); });
});
it('it should provide loaded resources for translation', function () {
expect(i18n.t('simple_en-US')).to.be('ok_from_special_en-US');
expect(i18n.t('simple_en')).to.be('ok_from_special_en');
expect(i18n.t('simple_dev')).to.be('ok_from_special_dev');
});
});
describe('with more than one namespace set', function () {
beforeEach(function (done) {
i18n.init($.extend(opts, { ns: { namespaces: ['ns.common', 'ns.special'], defaultNs: 'ns.special' } }),
function (t) { done(); });
});
it('it should provide loaded resources for translation', function () {
// default ns
expect(i18n.t('simple_en-US')).to.be('ok_from_special_en-US');
expect(i18n.t('simple_en')).to.be('ok_from_special_en');
expect(i18n.t('simple_dev')).to.be('ok_from_special_dev');
// ns prefix
expect(i18n.t('ns.common:simple_en-US')).to.be('ok_from_common_en-US');
expect(i18n.t('ns.common:simple_en')).to.be('ok_from_common_en');
expect(i18n.t('ns.common:simple_dev')).to.be('ok_from_common_dev');
// ns in options
expect(i18n.t('simple_en-US', { ns: 'ns.common' })).to.be('ok_from_common_en-US');
expect(i18n.t('simple_en', { ns: 'ns.common' })).to.be('ok_from_common_en');
expect(i18n.t('simple_dev', { ns: 'ns.common' })).to.be('ok_from_common_dev');
});
});
describe('with reloading additional namespace', function () {
describe('without using localStorage', function () {
beforeEach(function (done) {
i18n.init(opts,
function (t) {
i18n.setDefaultNamespace('ns.special');
i18n.loadNamespaces(['ns.common', 'ns.special'], done);
});
});
it('it should provide loaded resources for translation', function () {
// default ns
expect(i18n.t('simple_en-US')).to.be('ok_from_special_en-US');
expect(i18n.t('simple_en')).to.be('ok_from_special_en');
expect(i18n.t('simple_dev')).to.be('ok_from_special_dev');
// ns prefix
expect(i18n.t('ns.common:simple_en-US')).to.be('ok_from_common_en-US');
expect(i18n.t('ns.common:simple_en')).to.be('ok_from_common_en');
expect(i18n.t('ns.common:simple_dev')).to.be('ok_from_common_dev');
// ns in options
expect(i18n.t('simple_en-US', { ns: 'ns.common' })).to.be('ok_from_common_en-US');
expect(i18n.t('simple_en', { ns: 'ns.common' })).to.be('ok_from_common_en');
expect(i18n.t('simple_dev', { ns: 'ns.common' })).to.be('ok_from_common_dev');
});
});
describe('with using localStorage', function () {
var spy: any;
before(function () {
window.localStorage.removeItem('res_en-US');
window.localStorage.removeItem('res_en');
window.localStorage.removeItem('res_dev');
});
beforeEach(function (done) {
spy = sinon.spy(i18n.sync, '_fetchOne');
i18n.init($.extend(opts, {
useLocalStorage: true
}), function (t) {
i18n.setDefaultNamespace('ns.special');
i18n.loadNamespaces(['ns.common', 'ns.special'], done);
});
});
afterEach(function () {
spy.restore();
});
it('it should load language', function () {
expect(spy.callCount).to.be(9); // en-US, en, de-DE, de, fr, dev * 3 namespaces (translate, common, special)
});
describe('on later reload of namespaces', function () {
beforeEach(function (done) {
spy.reset();
i18n.init($.extend(opts, {
useLocalStorage: true,
ns: 'translation'
}), function (t) {
i18n.setDefaultNamespace('ns.special');
i18n.loadNamespaces(['ns.common', 'ns.special'], done);
});
});
it('it should not reload language', function () {
expect(spy.callCount).to.be(0);
});
});
});
});
});
describe('using function provided in callback\'s argument', function () {
var cbT: any;
beforeEach(function (done) {
i18n.init(opts, function (t) { cbT = t; done(); });
});
it('it should provide loaded resources for translation', function () {
expect(cbT('simple_en-US')).to.be('ok_from_en-US');
expect(cbT('simple_en')).to.be('ok_from_en');
expect(cbT('simple_dev')).to.be('ok_from_dev');
});
});
describe('using localStorage', function () {
var spy: any;
before(function () {
window.localStorage.removeItem('res_en-US');
window.localStorage.removeItem('res_en');
window.localStorage.removeItem('res_dev');
});
beforeEach(function (done) {
spy = sinon.spy(i18n.sync, '_fetchOne');
i18n.init($.extend(opts, {
useLocalStorage: true
}), function (t) { done(); });
});
afterEach(function () {
spy.restore();
});
it('it should load language', function () {
expect(spy.callCount).to.be(3); // en-US, en, de-DE, de, fr, dev
});
describe('on later init', function () {
beforeEach(function (done) {
spy.reset();
i18n.init(function (t) { done(); });
});
it('it should not reload language', function () {
expect(spy.callCount).to.be(0); // de-DE, de, fr, dev
});
describe('on later init - after caching duration', function () {
beforeEach(function (done) {
spy.reset();
// exipred
var local = window.localStorage.getItem('res_en-US');
local = JSON.parse(local);
local.i18nStamp = 0;
window.localStorage.setItem('res_en-US', JSON.stringify(local));
i18n.init(function (t) { done(); });
});
it('it should reload language', function () {
expect(spy.callCount).to.be(1); // de-DE, de, fr, dev
});
});
});
});
describe('with lowercase flag', function () {
describe('default behaviour will uppercase specifc country part.', function () {
beforeEach(function () {
i18n.init($.extend(opts, {
lng: 'en-us',
resStore: {
'en-US': { translation: { 'simple_en-US': 'ok_from_en-US' } }
}
}, function (t: any) { done(); }));
});
it('it should translate the uppercased lng value', function () {
expect(i18n.t('simple_en-US')).to.be('ok_from_en-US');
});
it('it should get uppercased set language', function () {
expect(i18n.lng()).to.be('en-US');
});
});
describe('overridden behaviour will accept lowercased country part.', function () {
beforeEach(function () {
i18n.init($.extend(opts, {
lng: 'en-us',
lowerCaseLng: true,
resStore: {
'en-us': { translation: { 'simple_en-us': 'ok_from_en-us' } }
}
}, function (t: any) { done(); }));
});
it('it should translate the lowercase lng value', function () {
expect(i18n.t('simple_en-us')).to.be('ok_from_en-us');
});
it('it should get lowercased set language', function () {
expect(i18n.lng()).to.be('en-us');
});
});
});
});
});
describe('basic functionality', function () {
describe('setting language', function () {
beforeEach(function (done) {
i18n.init($.extend(opts, {
resStore: {
'en-US': { translation: { 'simpleTest': 'ok_from_en-US' } },
'de-DE': { translation: { 'simpleTest': 'ok_from_de-DE' } }
}
}), function (t) { done(); });
});
it('it should provide resources for set language', function (done) {
expect(i18n.t('simpleTest')).to.be('ok_from_en-US');
i18n.setLng('de-DE', function (t) {
expect(t('simpleTest')).to.be('ok_from_de-DE');
done();
});
});
});
describe('preloading multiple languages', function () {
var spy: any;
beforeEach(function (done) {
spy = sinon.spy(i18n.sync, '_fetchOne');
i18n.init(opts, function (t) { done(); });
});
afterEach(function () {
spy.restore();
});
it('it should preload resources for languages', function (done) {
spy.reset();
i18n.preload('de-DE', function (t) {
expect(spy.callCount).to.be(5); // en-US, en, de-DE, de, dev
done();
});
});
});
describe('postprocessing tranlation', function () {
describe('having a postprocessor', function () {
before(function () {
i18n.addPostProcessor('myProcessor', function (val, key, opts) {
return 'ok_from_postprocessor';
});
});
beforeEach(function (done) {
i18n.init($.extend(opts, {
resStore: {
'en-US': { translation: { 'simpleTest': 'ok_from_en-US' } },
'de-DE': { translation: { 'simpleTest': 'ok_from_de-DE' } }
}
}), function (t) { done(); });
});
it('it should postprocess the translation by passing in postProcess name to t function', function () {
expect(i18n.t('simpleTest', { postProcess: 'myProcessor' })).to.be('ok_from_postprocessor');
});
describe('or setting it as default on init', function () {
beforeEach(function (done) {
i18n.init($.extend(opts, {
resStore: {
'en-US': { translation: { 'simpleTest': 'ok_from_en-US' } },
'de-DE': { translation: { 'simpleTest': 'ok_from_de-DE' } }
},
postProcess: 'myProcessor'
}), function (t) { done(); });
});
it('it should postprocess the translation by default', function () {
expect(i18n.t('simpleTest')).to.be('ok_from_postprocessor');
});
});
});
});
describe('post missing resources', function () {
describe('to fallback', function () {
var server: any, stub: any;
beforeEach(function (done) {
server = sinon.fakeServer.create();
stub = sinon.stub(i18n.functions, "ajax");
server.respondWith(<any[]>[200, { "Content-Type": "text/html", "Content-Length": 2 }, "OK"]);
i18n.init($.extend(opts, {
sendMissing: true,
resStore: {
'en-US': { translation: {} },
'en': { translation: {} },
'dev': { translation: {} }
}
}), function (t) { done(); });
});
afterEach(function () {
server.restore();
stub.restore();
});
it('it should post missing resource to server', function () {
i18n.t('missing');
server.respond();
expect(stub.calledOnce).to.be(true);
});
});
describe('to all', function () {
var server: any, stub: any;
beforeEach(function (done) {
server = sinon.fakeServer.create();
stub = sinon.stub(i18n.functions, "ajax");
server.respondWith(<any[]>[200, { "Content-Type": "text/html", "Content-Length": 2 }, "OK"]);
i18n.init($.extend(opts, {
sendMissing: true,
sendMissingTo: 'all',
resStore: {
'en-US': { translation: {} },
'en': { translation: {} },
'dev': { translation: {} }
}
}), function (t) { done(); });
});
afterEach(function () {
server.restore();
stub.restore();
});
it('it should post missing resource for all lng to server', function () {
i18n.t('missing');
server.respond();
expect(stub.calledThrice).to.be(true);
});
});
});
});
describe('translation functionality', function () {
describe('key with empty string value as valid option', function () {
var resStore = {
dev: { translation: { empty: '' } },
en: { translation: {} },
'en-US': { translation: {} }
};
beforeEach(function (done) {
i18n.init($.extend(opts, { resStore: resStore }),
function (t) { done(); });
});
it('it should translate correctly', function () {
expect(i18n.t('empty')).to.be('');
});
});
describe('resource string as array', function () {
var resStore = {
dev: { translation: { testarray: ["title", "text"] } },
en: { translation: {} },
'en-US': { translation: {} }
};
beforeEach(function (done) {
i18n.init($.extend(opts, { resStore: resStore }),
function (t) { done(); });
});
it('it should translate nested value', function () {
expect(i18n.t('testarray')).to.be('title\ntext');
});
});
describe('accessing nested values', function () {
beforeEach(function (done) {
i18n.init(opts, function (t) { done(); });
});
it('it should return nested string', function () {
expect(i18n.t('test.simple_en-US')).to.be('ok_from_en-US');
});
it('it should not fail silently on accessing a objectTree', function () {
expect(i18n.t('test')).to.be('key \'translation:test (en-US)\' returned a object instead of string.');
});
describe('optional return an objectTree for UI components,...', function () {
describe('with init flag', function () {
var resStore = {
dev: { translation: {} },
en: { translation: {} },
'en-US': {
translation: {
test: { res: 'added __replace__' }
}
}
};
beforeEach(function (done) {
i18n.init($.extend(opts, {
returnObjectTrees: true,
resStore: resStore
}
), function (t) { done(); });
});
it('it should return objectTree applying options', function () {
expect(i18n.t('test', { replace: 'two' })).to.eql({ 'res': 'added two' });
});
});
describe('with flag in options', function () {
beforeEach(function (done) {
i18n.init($.extend(opts, { returnObjectTrees: false }),
function (t) { done(); });
});
it('it should return objectTree', function () {
expect(i18n.t('test', { returnObjectTrees: true })).to.eql({ 'simple_en-US': 'ok_from_en-US' });
});
});
});
});
describe('resource nesting', function () {
var resStore = {
dev: { translation: { nesting1: '1 $t(nesting2)' } },
en: { translation: { nesting2: '2 $t(nesting3)' } },
'en-US': { translation: { nesting3: '3' } }
};
beforeEach(function (done) {
i18n.init($.extend(opts, { resStore: resStore }),
function (t) { done(); });
});
it('it should translate nested value', function () {
expect(i18n.t('nesting1')).to.be('1 2 3');
});
it('it should apply nested value on defaultValue', function () {
expect(i18n.t('nesting_default', { defaultValue: '0 $t(nesting1)' })).to.be('0 1 2 3');
});
});
describe('interpolation - replacing values inside a string', function () {
describe('default i18next way', function () {
var resStore = {
dev: { translation: {} },
en: { translation: {} },
'en-US': {
translation: {
interpolationTest1: 'added __toAdd__',
interpolationTest2: 'added __toAdd__ __toAdd__ twice',
interpolationTest3: 'added __child.one__ __child.two__',
interpolationTest4: 'added __child.grandChild.three__'
}
}
};
beforeEach(function (done) {
i18n.init($.extend(opts, { resStore: resStore }),
function (t) { done(); });
});
it('it should replace passed in key/values', function () {
expect(i18n.t('interpolationTest1', { toAdd: 'something' })).to.be('added something');
expect(i18n.t('interpolationTest2', { toAdd: 'something' })).to.be('added something something twice');
expect(i18n.t('interpolationTest3', { child: { one: '1', two: '2' } })).to.be('added 1 2');
expect(i18n.t('interpolationTest4', { child: { grandChild: { three: '3' } } })).to.be('added 3');
});
it('it should replace passed in key/values on defaultValue', function () {
expect(i18n.t('interpolationTest5', { defaultValue: 'added __toAdd__', toAdd: 'something' })).to.be('added something');
});
});
describe('default i18next way - different prefix/suffix', function () {
var resStore = {
dev: { translation: {} },
en: { translation: {} },
'en-US': {
translation: {
interpolationTest1: 'added *toAdd*',
interpolationTest2: 'added *toAdd* *toAdd* twice',
interpolationTest3: 'added *child.one* *child.two*',
interpolationTest4: 'added *child.grandChild.three*'
}
}
};
beforeEach(function (done) {
i18n.init($.extend(opts, {
resStore: resStore,
interpolationPrefix: '*',
interpolationSuffix: '*'
}), function (t) { done(); });
});
it('it should replace passed in key/values', function () {
expect(i18n.t('interpolationTest1', { toAdd: 'something' })).to.be('added something');
expect(i18n.t('interpolationTest2', { toAdd: 'something' })).to.be('added something something twice');
expect(i18n.t('interpolationTest3', { child: { one: '1', two: '2' } })).to.be('added 1 2');
expect(i18n.t('interpolationTest4', { child: { grandChild: { three: '3' } } })).to.be('added 3');
});
it('it should replace passed in key/values on defaultValue', function () {
expect(i18n.t('interpolationTest5', { defaultValue: 'added *toAdd*', toAdd: 'something' })).to.be('added something');
});
});
describe('using sprintf', function () {
var resStore = {
dev: { translation: {} },
en: { translation: {} },
'en-US': {
translation: {
interpolationTest1: 'The first 4 letters of the english alphabet are: %s, %s, %s and %s',
interpolationTest2: 'Hello %(users[0].name)s, %(users[1].name)s and %(users[2].name)s'
}
}
};
beforeEach(function (done) {
i18n.init($.extend(opts, { resStore: resStore }),
function (t) { done(); });
});
it('it should replace passed in key/values', function () {
expect(i18n.t('interpolationTest1', { postProcess: 'sprintf', sprintf: ['a', 'b', 'c', 'd'] })).to.be('The first 4 letters of the english alphabet are: a, b, c and d');
expect(i18n.t('interpolationTest2', { postProcess: 'sprintf', sprintf: { users: [{ name: 'Dolly' }, { name: 'Molly' }, { name: 'Polly' }] } })).to.be('Hello Dolly, Molly and Polly');
});
});
});
describe('plural usage', function () {
describe('basic usage - singular and plural form', function () {
var resStore = {
dev: {
'ns.2': {
pluralTest: 'singular from ns.2',
pluralTest_plural: 'plural from ns.2',
pluralTestWithCount: '__count__ item from ns.2',
pluralTestWithCount_plural: '__count__ items from ns.2'
}
},
en: {},
'en-US': {
'ns.1': {
pluralTest: 'singular',
pluralTest_plural: 'plural',
pluralTestWithCount: '__count__ item',
pluralTestWithCount_plural: '__count__ items'
}
}
};
beforeEach(function (done) {
i18n.init($.extend(opts, {
resStore: resStore,
ns: { namespaces: ['ns.1', 'ns.2'], defaultNs: 'ns.1' }
}),
function (t) { done(); });
});
it('it should provide correct plural or singular form', function () {
expect(i18n.t('pluralTest', { count: 0 })).to.be('plural');
expect(i18n.t('pluralTest', { count: 1 })).to.be('singular');
expect(i18n.t('pluralTest', { count: 2 })).to.be('plural');
expect(i18n.t('pluralTest', { count: 7 })).to.be('plural');
expect(i18n.t('pluralTestWithCount', { count: 0 })).to.be('0 items');
expect(i18n.t('pluralTestWithCount', { count: 1 })).to.be('1 item');
expect(i18n.t('pluralTestWithCount', { count: 7 })).to.be('7 items');
});
it('it should provide correct plural or singular form for second namespace', function () {
expect(i18n.t('ns.2:pluralTest', { count: 0 })).to.be('plural from ns.2');
expect(i18n.t('ns.2:pluralTest', { count: 1 })).to.be('singular from ns.2');
expect(i18n.t('ns.2:pluralTest', { count: 2 })).to.be('plural from ns.2');
expect(i18n.t('ns.2:pluralTest', { count: 7 })).to.be('plural from ns.2');
expect(i18n.t('ns.2:pluralTestWithCount', { count: 1 })).to.be('1 item from ns.2');
expect(i18n.t('ns.2:pluralTestWithCount', { count: 7 })).to.be('7 items from ns.2');
});
});
describe('basic usage 2 - singular and plural form in french', function () {
var resStore = {
dev: {
'ns.2': {
pluralTest: 'singular from ns.2',
pluralTest_plural: 'plural from ns.2',
pluralTestWithCount: '__count__ item from ns.2',
pluralTestWithCount_plural: '__count__ items from ns.2'
}
},
en: {},
'fr': {
'ns.1': {
pluralTest: 'singular',
pluralTest_plural: 'plural',
pluralTestWithCount: '__count__ item',
pluralTestWithCount_plural: '__count__ items'
}
}
};
beforeEach(function (done) {
i18n.init($.extend(opts, {
lng: 'fr',
resStore: resStore,
ns: { namespaces: ['ns.1', 'ns.2'], defaultNs: 'ns.1' }
}),
function (t) { done(); });
});
it('it should provide correct plural or singular form', function () {
expect(i18n.t('pluralTest', { count: 0 })).to.be('singular');
expect(i18n.t('pluralTest', { count: 1 })).to.be('singular');
expect(i18n.t('pluralTest', { count: 2 })).to.be('plural');
expect(i18n.t('pluralTest', { count: 7 })).to.be('plural');
expect(i18n.t('pluralTestWithCount', { count: 0 })).to.be('0 item');
expect(i18n.t('pluralTestWithCount', { count: 1 })).to.be('1 item');
expect(i18n.t('pluralTestWithCount', { count: 7 })).to.be('7 items');
});
});
describe('extended usage - multiple plural forms - ar', function () {
var resStore = {
dev: { translation: {} },
ar: {
translation: {
key: 'singular',
key_plural_0: 'zero',
key_plural_2: 'two',
key_plural_3: 'few',
key_plural_11: 'many',
key_plural_100: 'plural'
}
},
'ar-??': { translation: {} }
};
beforeEach(function (done) {
i18n.init($.extend(opts, { lng: 'ar', resStore: resStore }),
function (t) { done(); });
});
it('it should provide correct plural forms', function () {
expect(i18n.t('key', { count: 0 })).to.be('zero');
expect(i18n.t('key', { count: 1 })).to.be('singular');
expect(i18n.t('key', { count: 2 })).to.be('two');
expect(i18n.t('key', { count: 3 })).to.be('few');
expect(i18n.t('key', { count: 4 })).to.be('few');
expect(i18n.t('key', { count: 104 })).to.be('few');
expect(i18n.t('key', { count: 11 })).to.be('many');
expect(i18n.t('key', { count: 99 })).to.be('many');
expect(i18n.t('key', { count: 199 })).to.be('many');
expect(i18n.t('key', { count: 100 })).to.be('plural');
});
});
describe('extended usage - multiple plural forms - ru', function () {
var resStore = {
dev: { translation: {} },
ru: {
translation: {
key: '1,21,31',
key_plural_2: '2,3,4',
key_plural_5: '0,5,6'
}
},
'ru-??': { translation: {} }
};
beforeEach(function (done) {
i18n.init($.extend(opts, { lng: 'ru', resStore: resStore }),
function (t) { done(); });
});
it('it should provide correct plural forms', function () {
expect(i18n.t('key', { count: 0 })).to.be('0,5,6');
expect(i18n.t('key', { count: 1 })).to.be('1,21,31');
expect(i18n.t('key', { count: 2 })).to.be('2,3,4');
expect(i18n.t('key', { count: 3 })).to.be('2,3,4');
expect(i18n.t('key', { count: 4 })).to.be('2,3,4');
expect(i18n.t('key', { count: 104 })).to.be('2,3,4');
expect(i18n.t('key', { count: 11 })).to.be('0,5,6');
expect(i18n.t('key', { count: 24 })).to.be('2,3,4');
expect(i18n.t('key', { count: 25 })).to.be('0,5,6');
expect(i18n.t('key', { count: 99 })).to.be('0,5,6');
expect(i18n.t('key', { count: 199 })).to.be('0,5,6');
expect(i18n.t('key', { count: 100 })).to.be('0,5,6');
});
});
});
describe('context usage', function () {
describe('basic usage', function () {
var resStore = {
dev: {
'ns.2': {
friend_context: 'A friend from ns2',
friend_context_male: 'A boyfriend from ns2',
friend_context_female: 'A girlfriend from ns2'
}
},
en: {
'ns.1': {
friend_context: 'A friend',
friend_context_male: 'A boyfriend',
friend_context_female: 'A girlfriend'
}
},
'en-US': { translation: {} }
};
beforeEach(function (done) {
i18n.init($.extend(opts, {
resStore: resStore,
ns: { namespaces: ['ns.1', 'ns.2'], defaultNs: 'ns.1' }
}),
function (t) { done(); });
});
it('it should provide correct context form', function () {
expect(i18n.t('friend_context')).to.be('A friend');
expect(i18n.t('friend_context', { context: '' })).to.be('A friend');
expect(i18n.t('friend_context', { context: 'male' })).to.be('A boyfriend');
expect(i18n.t('friend_context', { context: 'female' })).to.be('A girlfriend');
});
it('it should provide correct context form for second namespace', function () {
expect(i18n.t('ns.2:friend_context')).to.be('A friend from ns2');
expect(i18n.t('ns.2:friend_context', { context: '' })).to.be('A friend from ns2');
expect(i18n.t('ns.2:friend_context', { context: 'male' })).to.be('A boyfriend from ns2');
expect(i18n.t('ns.2:friend_context', { context: 'female' })).to.be('A girlfriend from ns2');
});
});
describe('extended usage - in combination with plurals', function () {
var resStore = {
dev: { translation: {} },
en: {
translation: {
friend_context: '__count__ friend',
friend_context_male: '__count__ boyfriend',
friend_context_female: '__count__ girlfriend',
friend_context_plural: '__count__ friends',
friend_context_male_plural: '__count__ boyfriends',
friend_context_female_plural: '__count__ girlfriends'
}
},
'en-US': { translation: {} }
};
beforeEach(function (done) {
i18n.init($.extend(opts, { resStore: resStore }),
function (t) { done(); });
});
it('it should provide correct context with plural forms', function () {
expect(i18n.t('friend_context', { count: 1 })).to.be('1 friend');
expect(i18n.t('friend_context', { context: '', count: 1 })).to.be('1 friend');
expect(i18n.t('friend_context', { context: 'male', count: 1 })).to.be('1 boyfriend');
expect(i18n.t('friend_context', { context: 'female', count: 1 })).to.be('1 girlfriend');
expect(i18n.t('friend_context', { count: 10 })).to.be('10 friends');
expect(i18n.t('friend_context', { context: '', count: 10 })).to.be('10 friends');
expect(i18n.t('friend_context', { context: 'male', count: 10 })).to.be('10 boyfriends');
expect(i18n.t('friend_context', { context: 'female', count: 10 })).to.be('10 girlfriends');
});
});
});
describe('with passed in languages different from set one', function () {
beforeEach(function (done) {
i18n.init($.extend(opts, {
preload: ['de-DE']
}),
function (t) { done(); });
});
it('it should provide translation for passed in language', function () {
expect(i18n.t('simple_de', { lng: 'de-DE' })).to.be('ok_from_de');
});
describe('with language not preloaded', function () {
it('it should provide translation for passed in language after loading file sync', function () {
expect(i18n.t('simple_fr', { lng: 'fr' })).to.be('ok_from_fr');
});
});
});
});
describe('jQuery integration / specials', function () {
describe('initialise - use deferrer instead of callback', function () {
describe('with passed in resource set', function () {
var resStore = {
dev: { translation: { 'simple_dev': 'ok_from_dev' } },
en: { translation: { 'simple_en': 'ok_from_en' } },
'en-US': { translation: { 'simple_en-US': 'ok_from_en-US' } }
};
beforeEach(function (done) {
i18n.init($.extend(opts, { resStore: resStore })).done(function (t: any) { done(); });
});
it('it should provide passed in resources for translation', function () {
expect($.t('simple_en-US')).to.be('ok_from_en-US');
expect($.t('simple_en')).to.be('ok_from_en');
expect($.t('simple_dev')).to.be('ok_from_dev');
});
});
describe('loading from server', function () {
beforeEach(function (done) {
i18n.init(opts).done(function () { done(); });
});
it('it should provide loaded resources for translation', function () {
expect($.t('simple_en-US')).to.be('ok_from_en-US');
expect($.t('simple_en')).to.be('ok_from_en');
expect($.t('simple_dev')).to.be('ok_from_dev');
});
});
});
describe('use translation function shortcut $.t', function () {
beforeEach(function (done) {
i18n.init(opts, function (t) { done(); });
});
it('it should provide translation via $.t', function ()