style: 💄 format tests

This commit is contained in:
Christian Kaisermann 2020-11-05 10:01:23 -03:00
parent cddd0c9182
commit 940aa65f8c
8 changed files with 389 additions and 375 deletions

View File

@ -6,5 +6,15 @@
}, },
"rules": { "rules": {
"@typescript-eslint/no-explicit-any": "off" "@typescript-eslint/no-explicit-any": "off"
} },
"overrides": [
{
"files": ["test/**/*"],
"rules": {
"global-require": "off",
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/no-require-imports": "off"
}
}
]
} }

View File

@ -29,8 +29,8 @@
"test": "jest", "test": "jest",
"test:ci": "jest --silent", "test:ci": "jest --silent",
"test:watch": "jest --verbose --watchAll", "test:watch": "jest --verbose --watchAll",
"lint": "eslint \"src/**/*.ts\"", "lint": "eslint \"{src,test}/**/*.ts\"",
"format": "prettier --loglevel silent --write \"src/**/*.ts\"", "format": "prettier --loglevel silent --write \"{src,test}/**/*.ts\"",
"release": " git add package.json && git commit -m \"chore(release): v$npm_package_version :tada:\"", "release": " git add package.json && git commit -m \"chore(release): v$npm_package_version :tada:\"",
"pretest": "npm run build", "pretest": "npm run build",
"prebuild": "yarn clean", "prebuild": "yarn clean",

View File

@ -1,46 +1,46 @@
import { get } from 'svelte/store' import { get } from 'svelte/store';
import { import {
init, init,
getOptions, getOptions,
defaultOptions, defaultOptions,
defaultFormats, defaultFormats,
} from '../../src/runtime/configs' } from '../../src/runtime/configs';
import { $locale } from '../../src/runtime/stores/locale' import { $locale } from '../../src/runtime/stores/locale';
beforeEach(() => { beforeEach(() => {
init(defaultOptions) init(defaultOptions);
}) });
test('inits the fallback locale', () => { test('inits the fallback locale', () => {
expect(getOptions().fallbackLocale).toBe(null) expect(getOptions().fallbackLocale).toBeNull();
init({ init({
fallbackLocale: 'en', fallbackLocale: 'en',
}) });
expect(getOptions().fallbackLocale).toBe('en') expect(getOptions().fallbackLocale).toBe('en');
}) });
test('inits the initial locale by string', () => { test('inits the initial locale by string', () => {
init({ init({
fallbackLocale: 'pt', fallbackLocale: 'pt',
initialLocale: 'en', initialLocale: 'en',
}) });
expect(getOptions().initialLocale).toBe('en') expect(getOptions().initialLocale).toBe('en');
expect(get($locale)).toBe('en') expect(get($locale)).toBe('en');
}) });
test('adds custom formats for time, date and number values', () => { test('adds custom formats for time, date and number values', () => {
const customFormats = require('../fixtures/formats.json') const customFormats = require('../fixtures/formats.json');
init({ init({
fallbackLocale: 'en', fallbackLocale: 'en',
formats: customFormats, formats: customFormats,
}) });
expect(getOptions().formats).toMatchObject(defaultFormats) expect(getOptions().formats).toMatchObject(defaultFormats);
expect(getOptions().formats).toMatchObject(customFormats) expect(getOptions().formats).toMatchObject(customFormats);
}) });
test('sets the minimum delay to set the loading store value', () => { test('sets the minimum delay to set the loading store value', () => {
init({ fallbackLocale: 'en', loadingDelay: 300 }) init({ fallbackLocale: 'en', loadingDelay: 300 });
expect(getOptions().loadingDelay).toBe(300) expect(getOptions().loadingDelay).toBe(300);
}) });

View File

@ -4,195 +4,195 @@ import {
getTimeFormatter, getTimeFormatter,
getMessageFormatter, getMessageFormatter,
init, init,
locale locale,
} from '../../../src/runtime' } from '../../../src/runtime';
beforeEach(() => { beforeEach(() => {
init({ fallbackLocale: undefined }) init({ fallbackLocale: undefined });
}) });
describe('number formatter', () => { describe('number formatter', () => {
const number = 123123 const number = 123123;
test('throws if no locale is set', () => { it('throws if no locale is set', () => {
expect(() => getNumberFormatter().format(number)).toThrow( expect(() => getNumberFormatter().format(number)).toThrow(
'[svelte-i18n] A "locale" must be set to format numbers' '[svelte-i18n] A "locale" must be set to format numbers',
) );
}) });
test('formats a number according to the current locale', () => { it('formats a number according to the current locale', () => {
init({ fallbackLocale: 'en' }) init({ fallbackLocale: 'en' });
expect(getNumberFormatter().format(number)).toBe('123,123') expect(getNumberFormatter().format(number)).toBe('123,123');
}) });
test('formats a number according to a locale', () => { it('formats a number according to a locale', () => {
init({ fallbackLocale: 'en' }) init({ fallbackLocale: 'en' });
expect(getNumberFormatter({ locale: 'pt-BR' }).format(number)).toBe( expect(getNumberFormatter({ locale: 'pt-BR' }).format(number)).toBe(
'123.123' '123.123',
) );
}) });
test('formats a number with a custom format', () => { it('formats a number with a custom format', () => {
init({ init({
fallbackLocale: 'en', fallbackLocale: 'en',
formats: require('../../fixtures/formats.json'), formats: require('../../fixtures/formats.json'),
}) });
expect(getNumberFormatter({ format: 'brl' }).format(number)).toBe( expect(getNumberFormatter({ format: 'brl' }).format(number)).toBe(
'R$123,123.00' 'R$123,123.00',
) );
}) });
test('formats a number with inline options', () => { it('formats a number with inline options', () => {
init({ fallbackLocale: 'en' }) init({ fallbackLocale: 'en' });
expect( expect(
getNumberFormatter({ style: 'currency', currency: 'BRL' }).format(number) getNumberFormatter({ style: 'currency', currency: 'BRL' }).format(number),
).toBe('R$123,123.00') ).toBe('R$123,123.00');
}) });
test('formats a number according to the currently set locale', () => { it('formats a number according to the currently set locale', () => {
locale.set('en') locale.set('en');
expect(getNumberFormatter().format(number)).toBe('123,123') expect(getNumberFormatter().format(number)).toBe('123,123');
locale.set('nl') locale.set('nl');
expect(getNumberFormatter().format(number)).toBe('123.123') expect(getNumberFormatter().format(number)).toBe('123.123');
}) });
}) });
describe('date formatter', () => { describe('date formatter', () => {
const date = new Date(2019, 1, 1) const date = new Date(2019, 1, 1);
test('throws if no locale is set', () => { it('throws if no locale is set', () => {
expect(() => getDateFormatter().format(date)).toThrow( expect(() => getDateFormatter().format(date)).toThrow(
'[svelte-i18n] A "locale" must be set to format dates' '[svelte-i18n] A "locale" must be set to format dates',
) );
}) });
test('formats a date according to the current locale', () => { it('formats a date according to the current locale', () => {
init({ fallbackLocale: 'en' }) init({ fallbackLocale: 'en' });
expect(getDateFormatter().format(date)).toBe('2/1/19') expect(getDateFormatter().format(date)).toBe('2/1/19');
}) });
test('formats a date according to a locale', () => { it('formats a date according to a locale', () => {
expect(getDateFormatter({ locale: 'pt-BR' }).format(date)).toBe('01/02/19') expect(getDateFormatter({ locale: 'pt-BR' }).format(date)).toBe('01/02/19');
}) });
test('throws if passed a non-existing format', () => { it('throws if passed a non-existing format', () => {
init({ init({
fallbackLocale: 'en', fallbackLocale: 'en',
formats: require('../../fixtures/formats.json'), formats: require('../../fixtures/formats.json'),
}) });
expect(() => expect(() =>
getDateFormatter({ locale: 'pt-BR', format: 'foo' }).format(date) getDateFormatter({ locale: 'pt-BR', format: 'foo' }).format(date),
).toThrowError(`[svelte-i18n] Unknown "foo" date format.`) ).toThrowError(`[svelte-i18n] Unknown "foo" date format.`);
}) });
test('formats a date with a custom format', () => { it('formats a date with a custom format', () => {
init({ init({
fallbackLocale: 'en', fallbackLocale: 'en',
formats: require('../../fixtures/formats.json'), formats: require('../../fixtures/formats.json'),
}) });
expect(getDateFormatter({ format: 'customDate' }).format(date)).toBe( expect(getDateFormatter({ format: 'customDate' }).format(date)).toBe(
'2019 AD' '2019 AD',
) );
}) });
test('formats a date with inline options', () => { it('formats a date with inline options', () => {
init({ fallbackLocale: 'en' }) init({ fallbackLocale: 'en' });
expect( expect(
getDateFormatter({ year: 'numeric', era: 'short' }).format(date) getDateFormatter({ year: 'numeric', era: 'short' }).format(date),
).toBe('2019 AD') ).toBe('2019 AD');
}) });
test('formats a date according to the currently set locale', () => { it('formats a date according to the currently set locale', () => {
locale.set('en') locale.set('en');
expect(getDateFormatter().format(date)).toBe('2/1/19') expect(getDateFormatter().format(date)).toBe('2/1/19');
locale.set('nl') locale.set('nl');
expect(getDateFormatter().format(date)).toBe('1-2-19') expect(getDateFormatter().format(date)).toBe('1-2-19');
}) });
}) });
describe('time formatter', () => { describe('time formatter', () => {
const time = new Date(2019, 1, 1, 20, 37, 32) const time = new Date(2019, 1, 1, 20, 37, 32);
test('throws if no locale is set', () => { it('throws if no locale is set', () => {
expect(() => getTimeFormatter().format(time)).toThrow( expect(() => getTimeFormatter().format(time)).toThrow(
'[svelte-i18n] A "locale" must be set to format time' '[svelte-i18n] A "locale" must be set to format time',
) );
}) });
test('formats a time according to the current locale', () => { it('formats a time according to the current locale', () => {
init({ fallbackLocale: 'en' }) init({ fallbackLocale: 'en' });
expect(getTimeFormatter().format(time)).toBe('8:37 PM') expect(getTimeFormatter().format(time)).toBe('8:37 PM');
}) });
test('formats a time according to a locale', () => { it('formats a time according to a locale', () => {
expect(getTimeFormatter({ locale: 'pt-BR' }).format(time)).toBe('20:37') expect(getTimeFormatter({ locale: 'pt-BR' }).format(time)).toBe('20:37');
}) });
test('formats a time with a custom format', () => { it('formats a time with a custom format', () => {
init({ init({
fallbackLocale: 'en', fallbackLocale: 'en',
formats: require('../../fixtures/formats.json'), formats: require('../../fixtures/formats.json'),
}) });
expect(getTimeFormatter({ format: 'customTime' }).format(time)).toBe( expect(getTimeFormatter({ format: 'customTime' }).format(time)).toBe(
'08:37:32 PM' '08:37:32 PM',
) );
}) });
test('throws if passed a non-existing format', () => { it('throws if passed a non-existing format', () => {
init({ init({
fallbackLocale: 'en', fallbackLocale: 'en',
formats: require('../../fixtures/formats.json'), formats: require('../../fixtures/formats.json'),
}) });
expect(() => expect(() =>
getTimeFormatter({ locale: 'pt-BR', format: 'foo' }).format(time) getTimeFormatter({ locale: 'pt-BR', format: 'foo' }).format(time),
).toThrowError(`[svelte-i18n] Unknown "foo" time format.`) ).toThrowError(`[svelte-i18n] Unknown "foo" time format.`);
}) });
test('formats a time with inline options', () => { it('formats a time with inline options', () => {
init({ fallbackLocale: 'en' }) init({ fallbackLocale: 'en' });
expect( expect(
getTimeFormatter({ getTimeFormatter({
hour: '2-digit', hour: '2-digit',
minute: '2-digit', minute: '2-digit',
second: '2-digit', second: '2-digit',
}).format(time) }).format(time),
).toBe('08:37:32 PM') ).toBe('08:37:32 PM');
}) });
test('formats time according to the currently set locale', () => { it('formats time according to the currently set locale', () => {
locale.set('en') locale.set('en');
expect(getTimeFormatter().format(time)).toBe('8:37 PM') expect(getTimeFormatter().format(time)).toBe('8:37 PM');
locale.set('nl') locale.set('nl');
expect(getTimeFormatter().format(time)).toBe('20:37') expect(getTimeFormatter().format(time)).toBe('20:37');
}) });
}) });
describe('message formatter', () => { describe('message formatter', () => {
test('formats a message with interpolated values', () => { it('formats a message with interpolated values', () => {
expect( expect(
getMessageFormatter('Page: {current,number}/{max,number}', 'en').format({ getMessageFormatter('Page: {current,number}/{max,number}', 'en').format({
current: 2, current: 2,
max: 10, max: 10,
}) }),
).toBe('Page: 2/10') ).toBe('Page: 2/10');
}) });
test('formats number with custom formats', () => { it('formats number with custom formats', () => {
expect( expect(
getMessageFormatter('Number: {n, number, compactShort}', 'en').format({ getMessageFormatter('Number: {n, number, compactShort}', 'en').format({
n: 2000000, n: 2000000,
}) }),
).toBe('Number: 2M') ).toBe('Number: 2M');
}) });
}) });

View File

@ -3,69 +3,69 @@ import {
flush, flush,
registerLocaleLoader, registerLocaleLoader,
resetQueues, resetQueues,
} from '../../../src/runtime/includes/loaderQueue' } from '../../../src/runtime/includes/loaderQueue';
import { getMessageFromDictionary } from '../../../src/runtime/stores/dictionary' import { getMessageFromDictionary } from '../../../src/runtime/stores/dictionary';
beforeEach(() => { beforeEach(() => {
resetQueues() resetQueues();
}) });
const loader = (content: any) => () => new Promise(res => res(content)) const loader = (content: any) => () => new Promise((res) => res(content));
test('registers a locale loader', () => { test('registers a locale loader', () => {
expect(hasLocaleQueue('pt-BR')).toBe(false) expect(hasLocaleQueue('pt-BR')).toBe(false);
registerLocaleLoader('pt-BR', loader({ message: 'Mensagem' })) registerLocaleLoader('pt-BR', loader({ message: 'Mensagem' }));
expect(hasLocaleQueue('pt-BR')).toBe(true) expect(hasLocaleQueue('pt-BR')).toBe(true);
}) });
test('checks if exist queues of locale and its fallbacks', () => { test('checks if exist queues of locale and its fallbacks', () => {
registerLocaleLoader('en', loader({ field: 'Name' })) registerLocaleLoader('en', loader({ field: 'Name' }));
expect(hasLocaleQueue('en-US')).toBe(true) expect(hasLocaleQueue('en-US')).toBe(true);
}) });
test("does nothing if there's no queue for a locale", () => { test("does nothing if there's no queue for a locale", () => {
expect(flush('foo')).toBe(undefined) expect(flush('foo')).toBeUndefined();
}) });
test('flushes the queue of a locale and its fallbacks and merge the result with the dictionary', async () => { test('flushes the queue of a locale and its fallbacks and merge the result with the dictionary', async () => {
registerLocaleLoader('en', loader({ field: 'Name' })) registerLocaleLoader('en', loader({ field: 'Name' }));
registerLocaleLoader('en-US', loader({ field_2: 'Lastname' })) registerLocaleLoader('en-US', loader({ field_2: 'Lastname' }));
await flush('en-US') await flush('en-US');
expect(getMessageFromDictionary('en', 'field')).toBe('Name') expect(getMessageFromDictionary('en', 'field')).toBe('Name');
expect(getMessageFromDictionary('en-US', 'field_2')).toBe('Lastname') expect(getMessageFromDictionary('en-US', 'field_2')).toBe('Lastname');
expect(hasLocaleQueue('en')).toBe(false) expect(hasLocaleQueue('en')).toBe(false);
expect(hasLocaleQueue('en-US')).toBe(false) expect(hasLocaleQueue('en-US')).toBe(false);
}) });
test('consecutive flushes return the same promise', async () => { test('consecutive flushes return the same promise', async () => {
registerLocaleLoader('en', async () => ({})) registerLocaleLoader('en', async () => ({}));
const flushA = flush('en') const flushA = flush('en');
const flushB = flush('en') const flushB = flush('en');
const flushC = flush('en') const flushC = flush('en');
expect(flushB).toStrictEqual(flushA) expect(flushB).toStrictEqual(flushA);
expect(flushC).toStrictEqual(flushA) expect(flushC).toStrictEqual(flushA);
}) });
test('waits for loaders added while already flushing', async () => { test('waits for loaders added while already flushing', async () => {
registerLocaleLoader( registerLocaleLoader(
'en', 'en',
() => new Promise(res => setTimeout(() => res({ foo: 'foo' }), 300)) () => new Promise((res) => setTimeout(() => res({ foo: 'foo' }), 300)),
) );
const flushPromise = flush('en') const flushPromise = flush('en');
registerLocaleLoader( registerLocaleLoader(
'en', 'en',
() => new Promise(res => setTimeout(() => res({ bar: 'bar' }))) () => new Promise((res) => setTimeout(() => res({ bar: 'bar' }))),
) );
await flushPromise await flushPromise;
expect(getMessageFromDictionary('en', 'foo')).toBe('foo') expect(getMessageFromDictionary('en', 'foo')).toBe('foo');
expect(getMessageFromDictionary('en', 'bar')).toBe('bar') expect(getMessageFromDictionary('en', 'bar')).toBe('bar');
}) });

View File

@ -1,73 +1,75 @@
import { defineMessages, waitLocale, register, init } from '../../src/runtime' import { defineMessages, waitLocale, register, init } from '../../src/runtime';
import { $locale } from '../../src/runtime/stores/locale' import { $locale } from '../../src/runtime/stores/locale';
import { hasLocaleQueue } from '../../src/runtime/includes/loaderQueue' import { hasLocaleQueue } from '../../src/runtime/includes/loaderQueue';
import { import {
getLocaleDictionary, getLocaleDictionary,
$dictionary, $dictionary,
} from '../../src/runtime/stores/dictionary' } from '../../src/runtime/stores/dictionary';
import { $format } from '../../src/runtime/stores/formatters' import { $format } from '../../src/runtime/stores/formatters';
test('defineMessages returns the identity of its first argument', () => { test('defineMessages returns the identity of its first argument', () => {
const obj = {} const obj = {};
expect(obj).toBe(defineMessages(obj))
}) expect(obj).toBe(defineMessages(obj));
});
describe('waiting for a locale to load', () => { describe('waiting for a locale to load', () => {
beforeEach(() => { beforeEach(() => {
$dictionary.set({}) $dictionary.set({});
$locale.set(undefined) $locale.set(undefined);
}) });
test('should wait for a locale queue to be flushed', async () => { it('should wait for a locale queue to be flushed', async () => {
register('en', () => Promise.resolve({ foo: 'foo' })) register('en', () => Promise.resolve({ foo: 'foo' }));
$locale.set('en') $locale.set('en');
await waitLocale('en') await waitLocale('en');
expect(hasLocaleQueue('en')).toBe(false) expect(hasLocaleQueue('en')).toBe(false);
expect(getLocaleDictionary('en')).toMatchObject({ foo: 'foo' }) expect(getLocaleDictionary('en')).toMatchObject({ foo: 'foo' });
}) });
test('should wait for the current locale queue to be flushed', async () => { it('should wait for the current locale queue to be flushed', async () => {
register('en', () => Promise.resolve({ foo: 'foo' })) register('en', () => Promise.resolve({ foo: 'foo' }));
init({ fallbackLocale: 'pt', initialLocale: 'en' }) init({ fallbackLocale: 'pt', initialLocale: 'en' });
await waitLocale() await waitLocale();
expect(hasLocaleQueue('en')).toBe(false) expect(hasLocaleQueue('en')).toBe(false);
expect(getLocaleDictionary('en')).toMatchObject({ foo: 'foo' }) expect(getLocaleDictionary('en')).toMatchObject({ foo: 'foo' });
}) });
test('should wait for the fallback locale queue to be flushed if initial not set', async () => { it('should wait for the fallback locale queue to be flushed if initial not set', async () => {
register('pt', () => Promise.resolve({ foo: 'foo' })) register('pt', () => Promise.resolve({ foo: 'foo' }));
init({ fallbackLocale: 'pt' }) init({ fallbackLocale: 'pt' });
await waitLocale() await waitLocale();
expect(hasLocaleQueue('pt')).toBe(false) expect(hasLocaleQueue('pt')).toBe(false);
expect(getLocaleDictionary('pt')).toMatchObject({ foo: 'foo' }) expect(getLocaleDictionary('pt')).toMatchObject({ foo: 'foo' });
}) });
}) });
describe('format updates', () => { describe('format updates', () => {
beforeEach(() => { beforeEach(() => {
init({ fallbackLocale: 'en' }) init({ fallbackLocale: 'en' });
}) });
test('format store is updated when locale changes', () => { it('format store is updated when locale changes', () => {
const fn = jest.fn() const fn = jest.fn();
const cancel = $format.subscribe(fn) const cancel = $format.subscribe(fn);
$locale.set('pt') $locale.set('pt');
expect(fn).toHaveBeenCalledTimes(2) expect(fn).toHaveBeenCalledTimes(2);
cancel() cancel();
}) });
test('format store is updated when dictionary changes', () => { it('format store is updated when dictionary changes', () => {
const fn = jest.fn() const fn = jest.fn();
const cancel = $format.subscribe(fn) const cancel = $format.subscribe(fn);
$dictionary.set({})
expect(fn).toHaveBeenCalledTimes(2) $dictionary.set({});
cancel() expect(fn).toHaveBeenCalledTimes(2);
}) cancel();
}) });
});

View File

@ -1,104 +1,106 @@
import { get } from 'svelte/store' import { get } from 'svelte/store';
import { import {
$format, $format,
$formatTime, $formatTime,
$formatDate, $formatDate,
$formatNumber, $formatNumber,
} from '../../../src/runtime/stores/formatters' } from '../../../src/runtime/stores/formatters';
import { init } from '../../../src/runtime/configs' import { init } from '../../../src/runtime/configs';
import { addMessages } from '../../../src/runtime/stores/dictionary' import { addMessages } from '../../../src/runtime/stores/dictionary';
import { $locale } from '../../../src/runtime/stores/locale' import { $locale } from '../../../src/runtime/stores/locale';
import { import {
MessageFormatter, MessageFormatter,
TimeFormatter, TimeFormatter,
DateFormatter, DateFormatter,
NumberFormatter, NumberFormatter,
} from '../../../src/runtime/types' } from '../../../src/runtime/types';
let formatMessage: MessageFormatter;
let formatTime: TimeFormatter;
let formatDate: DateFormatter;
let formatNumber: NumberFormatter;
let formatMessage: MessageFormatter
let formatTime: TimeFormatter
let formatDate: DateFormatter
let formatNumber: NumberFormatter
$locale.subscribe(() => { $locale.subscribe(() => {
formatMessage = get($format) formatMessage = get($format);
formatTime = get($formatTime) formatTime = get($formatTime);
formatDate = get($formatDate) formatDate = get($formatDate);
formatNumber = get($formatNumber) formatNumber = get($formatNumber);
}) });
addMessages('en', require('../../fixtures/en.json')) addMessages('en', require('../../fixtures/en.json'));
addMessages('en-GB', require('../../fixtures/en-GB.json')) addMessages('en-GB', require('../../fixtures/en-GB.json'));
addMessages('pt', require('../../fixtures/pt.json')) addMessages('pt', require('../../fixtures/pt.json'));
addMessages('pt-BR', require('../../fixtures/pt-BR.json')) addMessages('pt-BR', require('../../fixtures/pt-BR.json'));
addMessages('pt-PT', require('../../fixtures/pt-PT.json')) addMessages('pt-PT', require('../../fixtures/pt-PT.json'));
beforeEach(() => { beforeEach(() => {
init({ fallbackLocale: 'en' }) init({ fallbackLocale: 'en' });
}) });
test('formats a message by its id and the current locale', () => { test('formats a message by its id and the current locale', () => {
expect(formatMessage({ id: 'form.field_1_name' })).toBe('Name') expect(formatMessage({ id: 'form.field_1_name' })).toBe('Name');
}) });
test('formats a message by its id and the a passed locale', () => { test('formats a message by its id and the a passed locale', () => {
expect(formatMessage({ id: 'form.field_1_name', locale: 'pt' })).toBe('Nome') expect(formatMessage({ id: 'form.field_1_name', locale: 'pt' })).toBe('Nome');
}) });
test('formats a message with interpolated values', () => { test('formats a message with interpolated values', () => {
expect(formatMessage({ id: 'photos', values: { n: 0 } })).toBe( expect(formatMessage({ id: 'photos', values: { n: 0 } })).toBe(
'You have no photos.' 'You have no photos.',
) );
expect(formatMessage({ id: 'photos', values: { n: 1 } })).toBe( expect(formatMessage({ id: 'photos', values: { n: 1 } })).toBe(
'You have one photo.' 'You have one photo.',
) );
expect(formatMessage({ id: 'photos', values: { n: 21 } })).toBe( expect(formatMessage({ id: 'photos', values: { n: 21 } })).toBe(
'You have 21 photos.' 'You have 21 photos.',
) );
}) });
test('accepts a message id as first argument', () => { test('accepts a message id as first argument', () => {
expect(formatMessage('form.field_1_name')).toBe('Name') expect(formatMessage('form.field_1_name')).toBe('Name');
}) });
test('accepts a message id as first argument and formatting options as second', () => { test('accepts a message id as first argument and formatting options as second', () => {
expect(formatMessage('form.field_1_name', { locale: 'pt' })).toBe('Nome') expect(formatMessage('form.field_1_name', { locale: 'pt' })).toBe('Nome');
}) });
test('throws if no locale is set', () => { test('throws if no locale is set', () => {
$locale.set(null) $locale.set(null);
expect(() => formatMessage('form.field_1_name')).toThrow( expect(() => formatMessage('form.field_1_name')).toThrow(
'[svelte-i18n] Cannot format a message without first setting the initial locale.' '[svelte-i18n] Cannot format a message without first setting the initial locale.',
) );
}) });
test('uses a missing message default value', () => { test('uses a missing message default value', () => {
expect(formatMessage('missing', { default: 'Missing Default' })).toBe( expect(formatMessage('missing', { default: 'Missing Default' })).toBe(
'Missing Default' 'Missing Default',
) );
}) });
test('warn on missing messages', () => { test('warn on missing messages', () => {
const warn = global.console.warn const { warn } = global.console;
global.console.warn = jest.fn()
formatMessage('missing') jest.spyOn(global.console, 'warn').mockImplementation();
formatMessage('missing');
expect(console.warn).toBeCalledWith( expect(console.warn).toBeCalledWith(
`[svelte-i18n] The message "missing" was not found in "en".` `[svelte-i18n] The message "missing" was not found in "en".`,
) );
global.console.warn = warn global.console.warn = warn;
}) });
describe('format utilities', () => { describe('format utilities', () => {
test('time', () => { it('time', () => {
expect(formatTime(new Date(2019, 0, 1, 20, 37))).toBe('8:37 PM') expect(formatTime(new Date(2019, 0, 1, 20, 37))).toBe('8:37 PM');
}) });
test('date', () => { it('date', () => {
expect(formatDate(new Date(2019, 0, 1, 20, 37))).toBe('1/1/19') expect(formatDate(new Date(2019, 0, 1, 20, 37))).toBe('1/1/19');
}) });
test('number', () => { it('number', () => {
expect(formatNumber(123123123)).toBe('123,123,123') expect(formatNumber(123123123)).toBe('123,123,123');
}) });
}) });

View File

@ -1,6 +1,6 @@
import { get } from 'svelte/store' import { get } from 'svelte/store';
import { lookup } from '../../../src/runtime/includes/lookup' import { lookup } from '../../../src/runtime/includes/lookup';
import { import {
isFallbackLocaleOf, isFallbackLocaleOf,
getFallbackOf, getFallbackOf,
@ -8,162 +8,162 @@ import {
getCurrentLocale, getCurrentLocale,
$locale, $locale,
isRelatedLocale, isRelatedLocale,
} from '../../../src/runtime/stores/locale' } from '../../../src/runtime/stores/locale';
import { getOptions, init } from '../../../src/runtime/configs' import { getOptions, init } from '../../../src/runtime/configs';
import { register, isLoading } from '../../../src/runtime' import { register, isLoading } from '../../../src/runtime';
import { hasLocaleQueue } from '../../../src/runtime/includes/loaderQueue' import { hasLocaleQueue } from '../../../src/runtime/includes/loaderQueue';
beforeEach(() => { beforeEach(() => {
init({ fallbackLocale: undefined }) init({ fallbackLocale: undefined });
$locale.set(undefined) $locale.set(undefined);
}) });
test('sets and gets the fallback locale', () => { test('sets and gets the fallback locale', () => {
init({ fallbackLocale: 'en' }) init({ fallbackLocale: 'en' });
expect(getOptions().fallbackLocale).toBe('en') expect(getOptions().fallbackLocale).toBe('en');
}) });
test('checks if a locale is a fallback locale of another locale', () => { test('checks if a locale is a fallback locale of another locale', () => {
expect(isFallbackLocaleOf('en', 'en-US')).toBe(true) expect(isFallbackLocaleOf('en', 'en-US')).toBe(true);
expect(isFallbackLocaleOf('en', 'en')).toBe(false) expect(isFallbackLocaleOf('en', 'en')).toBe(false);
expect(isFallbackLocaleOf('it', 'en-US')).toBe(false) expect(isFallbackLocaleOf('it', 'en-US')).toBe(false);
}) });
test('checks if a locale is a fallback locale of another locale', () => { test('checks if a locale is a related locale of another locale', () => {
expect(isRelatedLocale('en', 'en-US')).toBe(true) expect(isRelatedLocale('en', 'en-US')).toBe(true);
expect(isRelatedLocale('pt-BR', 'pt')).toBe(true) expect(isRelatedLocale('pt-BR', 'pt')).toBe(true);
expect(isRelatedLocale('en', 'en')).toBe(true) expect(isRelatedLocale('en', 'en')).toBe(true);
expect(isRelatedLocale('en', 'it-IT')).toBe(false) expect(isRelatedLocale('en', 'it-IT')).toBe(false);
expect(isRelatedLocale('en-US', 'it')).toBe(false) expect(isRelatedLocale('en-US', 'it')).toBe(false);
}) });
test('gets the next fallback locale of a locale', () => { test('gets the next fallback locale of a locale', () => {
expect(getFallbackOf('az-Cyrl-AZ')).toBe('az-Cyrl') expect(getFallbackOf('az-Cyrl-AZ')).toBe('az-Cyrl');
expect(getFallbackOf('en-US')).toBe('en') expect(getFallbackOf('en-US')).toBe('en');
expect(getFallbackOf('en')).toBe(null) expect(getFallbackOf('en')).toBeNull();
}) });
test('gets the global fallback locale if set', () => { test('gets the global fallback locale if set', () => {
init({ fallbackLocale: 'en' }) init({ fallbackLocale: 'en' });
expect(getFallbackOf('it')).toBe('en') expect(getFallbackOf('it')).toBe('en');
}) });
test('should not get the global fallback as the fallback of itself', () => { test('should not get the global fallback as the fallback of itself', () => {
init({ fallbackLocale: 'en' }) init({ fallbackLocale: 'en' });
expect(getFallbackOf('en')).toBe(null) expect(getFallbackOf('en')).toBeNull();
}) });
test('if global fallback locale has a fallback, it should return it', () => { test('if global fallback locale has a fallback, it should return it', () => {
init({ fallbackLocale: 'en-US' }) init({ fallbackLocale: 'en-US' });
expect(getFallbackOf('en-US')).toBe('en') expect(getFallbackOf('en-US')).toBe('en');
}) });
test('gets all fallback locales of a locale', () => { test('gets all fallback locales of a locale', () => {
expect(getRelatedLocalesOf('en-US')).toEqual(['en', 'en-US']) expect(getRelatedLocalesOf('en-US')).toEqual(['en', 'en-US']);
expect(getRelatedLocalesOf('en-US')).toEqual(['en', 'en-US']) expect(getRelatedLocalesOf('en-US')).toEqual(['en', 'en-US']);
expect(getRelatedLocalesOf('az-Cyrl-AZ')).toEqual([ expect(getRelatedLocalesOf('az-Cyrl-AZ')).toEqual([
'az', 'az',
'az-Cyrl', 'az-Cyrl',
'az-Cyrl-AZ', 'az-Cyrl-AZ',
]) ]);
}) });
test('gets all fallback locales of a locale including the global fallback locale', () => { test('gets all fallback locales of a locale including the global fallback locale', () => {
init({ fallbackLocale: 'pt' }) init({ fallbackLocale: 'pt' });
expect(getRelatedLocalesOf('en-US')).toEqual(['en', 'en-US', 'pt']) expect(getRelatedLocalesOf('en-US')).toEqual(['en', 'en-US', 'pt']);
expect(getRelatedLocalesOf('en-US')).toEqual(['en', 'en-US', 'pt']) expect(getRelatedLocalesOf('en-US')).toEqual(['en', 'en-US', 'pt']);
expect(getRelatedLocalesOf('az-Cyrl-AZ')).toEqual([ expect(getRelatedLocalesOf('az-Cyrl-AZ')).toEqual([
'az', 'az',
'az-Cyrl', 'az-Cyrl',
'az-Cyrl-AZ', 'az-Cyrl-AZ',
'pt', 'pt',
]) ]);
}) });
test('gets all fallback locales of a locale including the global fallback locale and its fallbacks', () => { test('gets all fallback locales of a locale including the global fallback locale and its fallbacks', () => {
init({ fallbackLocale: 'pt-BR' }) init({ fallbackLocale: 'pt-BR' });
expect(getRelatedLocalesOf('en-US')).toEqual(['en', 'en-US', 'pt', 'pt-BR']) expect(getRelatedLocalesOf('en-US')).toEqual(['en', 'en-US', 'pt', 'pt-BR']);
expect(getRelatedLocalesOf('en-US')).toEqual(['en', 'en-US', 'pt', 'pt-BR']) expect(getRelatedLocalesOf('en-US')).toEqual(['en', 'en-US', 'pt', 'pt-BR']);
expect(getRelatedLocalesOf('az-Cyrl-AZ')).toEqual([ expect(getRelatedLocalesOf('az-Cyrl-AZ')).toEqual([
'az', 'az',
'az-Cyrl', 'az-Cyrl',
'az-Cyrl-AZ', 'az-Cyrl-AZ',
'pt', 'pt',
'pt-BR', 'pt-BR',
]) ]);
}) });
test("don't list fallback locale twice", () => { test("don't list fallback locale twice", () => {
init({ fallbackLocale: 'pt-BR' }) init({ fallbackLocale: 'pt-BR' });
expect(getRelatedLocalesOf('pt-BR')).toEqual(['pt', 'pt-BR']) expect(getRelatedLocalesOf('pt-BR')).toEqual(['pt', 'pt-BR']);
expect(getRelatedLocalesOf('pt')).toEqual(['pt']) expect(getRelatedLocalesOf('pt')).toEqual(['pt']);
}) });
test('gets the current locale', () => { test('gets the current locale', () => {
expect(getCurrentLocale()).toBe(undefined) expect(getCurrentLocale()).toBeUndefined();
$locale.set('es-ES') $locale.set('es-ES');
expect(getCurrentLocale()).toBe('es-ES') expect(getCurrentLocale()).toBe('es-ES');
}) });
test('if no initial locale is set, set the locale to the fallback', () => { test('if no initial locale is set, set the locale to the fallback', () => {
init({ fallbackLocale: 'pt' }) init({ fallbackLocale: 'pt' });
expect(get($locale)).toBe('pt') expect(get($locale)).toBe('pt');
expect(getOptions().fallbackLocale).toBe('pt') expect(getOptions().fallbackLocale).toBe('pt');
}) });
test('if no initial locale was found, set to the fallback locale', () => { test('if no initial locale was found, set to the fallback locale', () => {
init({ init({
fallbackLocale: 'en', fallbackLocale: 'en',
initialLocale: null, initialLocale: null,
}) });
expect(get($locale)).toBe('en') expect(get($locale)).toBe('en');
expect(getOptions().fallbackLocale).toBe('en') expect(getOptions().fallbackLocale).toBe('en');
}) });
test('should flush the queue of the locale when changing the store value', async () => { test('should flush the queue of the locale when changing the store value', async () => {
register( register(
'en', 'en',
() => new Promise(res => setTimeout(() => res({ foo: 'Foo' }), 50)) () => new Promise((res) => setTimeout(() => res({ foo: 'Foo' }), 50)),
) );
expect(hasLocaleQueue('en')).toBe(true) expect(hasLocaleQueue('en')).toBe(true);
await $locale.set('en') await $locale.set('en');
expect(hasLocaleQueue('en')).toBe(false) expect(hasLocaleQueue('en')).toBe(false);
expect(lookup('foo', 'en')).toBe('Foo') expect(lookup('foo', 'en')).toBe('Foo');
}) });
test('if no locale is set, ignore the loading delay', async () => { test('if no locale is set, ignore the loading delay', async () => {
register( register(
'en', 'en',
() => new Promise(res => setTimeout(() => res({ foo: 'Foo' }), 50)) () => new Promise((res) => setTimeout(() => res({ foo: 'Foo' }), 50)),
) );
const promise = $locale.set('en') const promise = $locale.set('en');
expect(get(isLoading)).toBe(true) expect(get(isLoading)).toBe(true);
await promise await promise;
expect(get(isLoading)).toBe(false) expect(get(isLoading)).toBe(false);
}) });
test("if a locale is set, don't ignore the loading delay", async () => { test("if a locale is set, don't ignore the loading delay", async () => {
register( register(
'en', 'en',
() => new Promise(res => setTimeout(() => res({ foo: 'Foo' }), 50)) () => new Promise((res) => setTimeout(() => res({ foo: 'Foo' }), 50)),
) );
register( register(
'pt', 'pt',
() => new Promise(res => setTimeout(() => res({ foo: 'Foo' }), 50)) () => new Promise((res) => setTimeout(() => res({ foo: 'Foo' }), 50)),
) );
await $locale.set('en') await $locale.set('en');
const promise = $locale.set('pt') const promise = $locale.set('pt');
expect(get(isLoading)).toBe(false) expect(get(isLoading)).toBe(false);
await promise await promise;
expect(get(isLoading)).toBe(false) expect(get(isLoading)).toBe(false);
}) });