Skip to content

Commit

Permalink
fix(i18n): stop forcing lng option (#259)
Browse files Browse the repository at this point in the history
stops forcing the lng option in favor of relativetime and uses the fallbackLng instead

Related issue #254
  • Loading branch information
zewa666 authored Feb 19, 2018
1 parent 81ebc72 commit 5692e30
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 105 deletions.
1 change: 1 addition & 0 deletions karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ module.exports = function(config) {

// list of files / patterns to load in the browser
files: [
'node_modules/babel-polyfill/browser.js',
{pattern: 'test/unit/fixtures/**/*.html', included: false},
// dont pre-load just serve if requested
{pattern: 'test/unit/fixtures/**/*.jpg', watched: false, included: false, served: true}
Expand Down
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@
"bugs": {
"url": "https://github.com/aurelia/i18n/issues"
},
"scripts": {},
"scripts": {
"precommit": "gulp lint",
"test": "karma start"
},
"license": "MIT",
"author": "Rob Eisenberg <rob@bluespire.com> (http://robeisenberg.com/)",
"main": "dist/commonjs/aurelia-i18n.js",
Expand Down Expand Up @@ -90,6 +93,7 @@
"babel-plugin-transform-es2015-modules-commonjs": "^6.11.5",
"babel-plugin-transform-es2015-modules-systemjs": "^6.11.6",
"babel-plugin-transform-flow-strip-types": "^6.8.0",
"babel-polyfill": "^6.26.0",
"babel-preset-es2015": "^6.9.0",
"babel-preset-es2015-loose": "^7.0.0",
"babel-preset-es2015-loose-native-modules": "^1.0.0",
Expand Down
3 changes: 0 additions & 3 deletions src/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,6 @@ export class I18N {
debug: false
};

if (options && !options.lng) {
throw new Error('You need to provide the lng option');
}

i18next.init(options || defaultOptions, (err, t) => {
//make sure attributes is an array in case a string was provided
Expand Down
17 changes: 13 additions & 4 deletions src/relativeTime.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {I18N} from './i18n';
import {translations} from './defaultTranslations/relative.time';
import {EventAggregator} from 'aurelia-event-aggregator';
import { I18N } from './i18n';
import { translations } from './defaultTranslations/relative.time';
import { EventAggregator } from 'aurelia-event-aggregator';

export class RelativeTime {
static inject() { return [I18N, EventAggregator]; }
Expand All @@ -18,8 +18,17 @@ export class RelativeTime {

setup(locales) {
let trans = translations.default || translations;
let key = locales && locales.newValue ? locales.newValue : this.service.getLocale();
let fallbackLng = this.service.i18next.fallbackLng;

let alternateFb = fallbackLng || this.service.i18next.options.fallbackLng;
if (Array.isArray(alternateFb) && alternateFb.length > 0) {
alternateFb = alternateFb[0];
}

let key = ((locales && locales.newValue)
? locales.newValue
: this.service.getLocale()) || alternateFb;

let index = 0;

if ((index = key.indexOf('-')) >= 0) { // eslint-disable-line no-cond-assign
Expand Down
198 changes: 101 additions & 97 deletions test/unit/relative.time.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,194 +10,198 @@ import { translations } from '../../src/defaultTranslations/relative.time';
import { bootstrapTestEnvironment } from './staging-helpers';

describe('testing relative time support', () => {
let sut;
let i18n;
let ea;

beforeEach(done => {
ea = new EventAggregator();
i18n = new I18N(ea, new BindingSignaler());
sut = new RelativeTime(i18n, ea);
i18n.setup({
async function arrange(options) {
const ea = new EventAggregator();
const i18n = new I18N(ea, new BindingSignaler());
const sut = new RelativeTime(i18n, ea);

await i18n.setup(Object.assign({
lng: 'en',
fallbackLng: 'en',
defaultNS: 'custom_default',
debug: false
}).then(() => done());
});
debug: false,
interpolation: {
prefix: '__',
suffix: '__'
}
}, options));

return { ea, i18n, sut };
}

it('should use the fallback language if no lng is provided', async () => {
const { sut } = await arrange({ lng: undefined });
let expectedDate = new Date();

it('should provide a custom error message if lng option is not provided', () => {
expect(() => i18n.setup({
lng: undefined,
fallbackLng: 'en',
defaultNS: 'custom_default',
debug: false
})).toThrow();
expect(sut.getRelativeTime(expectedDate)).toBe('just now');
});

it('should provide now unit', () => {
it('should provide now unit', async () => {
const { sut } = await arrange();
let expectedDate = new Date();

expect(sut.getRelativeTime(expectedDate)).toBe('just now');
});

describe('ago tests', () => {
it('should provide singular time unit', () => {
it('should provide singular time unit', async () => {
const { sut } = await arrange();
let expectedDate = new Date();

expectedDate.setHours(new Date().getHours() - 1);

expect(sut.getRelativeTime(expectedDate)).toBe('1 hour ago');
});

it('should provide plural time unit', () => {
it('should provide plural time unit', async () => {
const { sut } = await arrange();
let expectedDate = new Date();

expectedDate.setHours(new Date().getHours() - 2);

expect(sut.getRelativeTime(expectedDate)).toBe('2 hours ago');
});

it('should provide month ranges', () => {
it('should provide month ranges', async () => {
const { sut } = await arrange();
let expectedDate = new Date();

expectedDate.setMonth(new Date().getMonth() - 2);

expect(sut.getRelativeTime(expectedDate)).toBe('2 months ago');
});

it('should provide year ranges', () => {
it('should provide year ranges', async () => {
const { sut } = await arrange();
let expectedDate = new Date();

expectedDate.setFullYear(new Date().getFullYear() - 2);

expect(sut.getRelativeTime(expectedDate)).toBe('2 years ago');
});
});

describe('in tests', () => {
it('should provide singular time unit', () => {
it('should provide singular time unit', async () => {
const { sut } = await arrange();
let expectedDate = new Date();

expectedDate.setHours(new Date().getHours() + 1);

expect(sut.getRelativeTime(expectedDate)).toBe('in 1 hour');
});

it('should provide plural time unit', () => {
it('should provide plural time unit', async () => {
const { sut } = await arrange();
let expectedDate = new Date();

expectedDate.setHours(new Date().getHours() + 2);

expect(sut.getRelativeTime(expectedDate)).toBe('in 2 hours');
});

it('should provide month ranges', () => {
it('should provide month ranges', async () => {
const { sut } = await arrange();
let expectedDate = new Date();

expectedDate.setMonth(new Date().getMonth() + 2);

expect(sut.getRelativeTime(expectedDate)).toBe('in 2 months');
});

it('should provide year ranges', () => {
it('should provide year ranges', async () => {
const { sut } = await arrange();
let expectedDate = new Date();

expectedDate.setFullYear(new Date().getFullYear() + 2);

expect(sut.getRelativeTime(expectedDate)).toBe('in 2 years');
});
});

describe('test i18n support', () => {
it('should provide the translation in German', (done) => {
i18n.setLocale('de').then(() => {
let expectedDate = new Date();
expectedDate.setHours(new Date().getHours() + 2);
it('should provide the translation in German', async () => {
const { sut } = await arrange({ lng: 'de', fallbackLng: 'de' });

expect(sut.getRelativeTime(expectedDate)).toBe('in 2 Stunden');
done();
});
let expectedDate = new Date();
expectedDate.setHours(new Date().getHours() + 2);

expect(sut.getRelativeTime(expectedDate)).toBe('in 2 Stunden');
});

it('should provide the translation in English when the locale is not present', (done) => {
i18n.setLocale('notPresent').then(() => {
let expectedDate = new Date();
expectedDate.setHours(new Date().getHours() + 2);
it('should provide the translation in English when the locale is not present', async () => {
const { i18n, sut } = await arrange({ lng: 'en', fallbackLng: 'en' });

expect(sut.getRelativeTime(expectedDate)).toBe('in 2 hours');
done();
});
});
});
await i18n.setLocale('notPresent');

it('should try to find the language of the locale when the full locale is not found', (done) => {
expect(translations['nl-BE']).toBe(undefined); //If this fails, someone added translations for nl-BE
i18n.setLocale('nl-BE').then(() => {
let expectedDate = new Date();
expectedDate.setHours(new Date().getHours() + 2);

expect(sut.getRelativeTime(expectedDate)).toBe('in 2 uren');
done();
expect(sut.getRelativeTime(expectedDate)).toBe('in 2 hours');
});
});

it('should provide the translation for the full locale when available', (done) => {
translations['nl-XX'] = { translation: { 'hour_in_plural': 'in __count__ periods of an hourly length', 'hour_in': 'in __count__ uur' } };
i18n.setLocale('nl-XX').then(() => {
let expectedDate = new Date();
expectedDate.setHours(new Date().getHours() + 2);
it('should try to find the language of the locale when the full locale is not found', async () => {
const { i18n, sut } = await arrange({ lng: 'en', fallbackLng: 'en' });
expect(translations['nl-BE']).toBe(undefined); //If this fails, someone added translations for nl-BE

expect(sut.getRelativeTime(expectedDate)).toBe('in 2 periods of an hourly length');
done();
});
await i18n.setLocale('nl-BE');
let expectedDate = new Date();
expectedDate.setHours(new Date().getHours() + 2);

expect(sut.getRelativeTime(expectedDate)).toBe('in 2 uren');
});

it('should provide the translation for the base locale when a key is not found in the full locale', (done) => {
it('should provide the translation for the full locale when available', async () => {
const { i18n, sut } = await arrange({ lng: 'en', fallbackLng: 'en' });
translations['nl-XX'] = { translation: { 'hour_in_plural': 'in __count__ periods of an hourly length', 'hour_in': 'in __count__ uur' } };
i18n.setLocale('nl-XX').then(() => {
let expectedDate = new Date();
expectedDate.setMinutes(new Date().getMinutes() + 2);

expect(sut.getRelativeTime(expectedDate)).toBe('in 2 minuten');
done();
});
await i18n.setLocale('nl-XX');
let expectedDate = new Date();
expectedDate.setHours(new Date().getHours() + 2);

expect(sut.getRelativeTime(expectedDate)).toBe('in 2 periods of an hourly length');
});

it('should handle non-defined interpolation prefix and suffix', done => {
let customInterpolationSettings = new I18N(ea, new BindingSignaler());
it('should provide the translation for the base locale when a key is not found in the full locale', async () => {
const { i18n, sut } = await arrange({ lng: 'en', fallbackLng: 'en' });
translations['nl-XX'] = { translation: { 'hour_in_plural': 'in __count__ periods of an hourly length', 'hour_in': 'in __count__ uur' } };

await i18n.setLocale('nl-XX');
let expectedDate = new Date();
expectedDate.setMinutes(new Date().getMinutes() + 2);

customInterpolationSettings.setup({
expect(sut.getRelativeTime(expectedDate)).toBe('in 2 minuten');
});

it('should handle non-defined interpolation prefix and suffix', async () => {
const { sut } = await arrange({
lng: 'en',
getAsync: false,
sendMissing: false,
fallbackLng: 'en',
debug: false
}).then((instance) => {
instance.options.interpolation.prefix = undefined;
instance.options.interpolation.suffix = undefined;
let customSut = new RelativeTime(customInterpolationSettings, ea);
let expectedDate = new Date();
expectedDate.setHours(new Date().getHours() - 3);
interpolation: {
prefix: undefined,
suffix: undefined
}
});

expect(customSut.getRelativeTime(expectedDate)).toBe('3 hours ago');
let expectedDate = new Date();
expectedDate.setHours(new Date().getHours() - 3);

done();
});
expect(sut.getRelativeTime(expectedDate)).toBe('3 hours ago');
});

it('should respect interpolation settings', done => {
let customInterpolationSettings = new I18N(ea, new BindingSignaler());

customInterpolationSettings.setup({
it('should respect interpolation settings', async () => {
const { sut } = await arrange({
lng: 'en',
getAsync: false,
sendMissing: false,
fallbackLng: 'en',
debug: false
}).then((instance) => {
instance.options.interpolation.prefix = '${';
instance.options.interpolation.suffix = '}';
let customSut = new RelativeTime(customInterpolationSettings, ea);
let expectedDate = new Date();
expectedDate.setHours(new Date().getHours() - 1);

expect(customSut.getRelativeTime(expectedDate)).toBe('1 hour ago');

done();
interpolation: {
prefix: undefined,
suffix: undefined
}
});
let expectedDate = new Date();
expectedDate.setHours(new Date().getHours() - 1);

expect(sut.getRelativeTime(expectedDate)).toBe('1 hour ago');
});

it('should update relative time bindings using custom signal', done => {
Expand Down

0 comments on commit 5692e30

Please sign in to comment.