-
Notifications
You must be signed in to change notification settings - Fork 80
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: 🎸 make date,time and number formatters tree-shakeable
BREAKING CHANGE: Changes completely the API. Now, to format a number, date or time, the developer must explicitly import the formatter store: `import { time, date, number } from 'svelte-i18n'`
- Loading branch information
1 parent
858c25c
commit 6526245
Showing
6 changed files
with
265 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import { derived } from 'svelte/store' | ||
|
||
import { | ||
MessageFormatter, | ||
MessageObject, | ||
TimeFormatter, | ||
DateFormatter, | ||
NumberFormatter, | ||
} from '../types' | ||
import { lookup } from '../includes/lookup' | ||
import { hasLocaleQueue } from '../includes/loaderQueue' | ||
import { | ||
getMessageFormatter, | ||
getTimeFormatter, | ||
getDateFormatter, | ||
getNumberFormatter, | ||
} from '../includes/formatters' | ||
import { getOptions } from '../configs' | ||
|
||
import { $dictionary } from './dictionary' | ||
import { getCurrentLocale, getRelatedLocalesOf, $locale } from './locale' | ||
|
||
const formatMessage: MessageFormatter = (id, options = {}) => { | ||
if (typeof id === 'object') { | ||
options = id as MessageObject | ||
id = options.id | ||
} | ||
|
||
const { values, locale = getCurrentLocale(), default: defaultValue } = options | ||
|
||
if (locale == null) { | ||
throw new Error( | ||
'[svelte-i18n] Cannot format a message without first setting the initial locale.' | ||
) | ||
} | ||
|
||
const message = lookup(id, locale) | ||
|
||
if (!message) { | ||
if (getOptions().warnOnMissingMessages) { | ||
// istanbul ignore next | ||
console.warn( | ||
`[svelte-i18n] The message "${id}" was not found in "${getRelatedLocalesOf( | ||
locale | ||
).join('", "')}".${ | ||
hasLocaleQueue(getCurrentLocale()) | ||
? `\n\nNote: there are at least one loader still registered to this locale that wasn't executed.` | ||
: '' | ||
}` | ||
) | ||
} | ||
|
||
return defaultValue || id | ||
} | ||
|
||
if (!values) return message | ||
return getMessageFormatter(message, locale).format(values) | ||
} | ||
|
||
const formatTime: TimeFormatter = (t, options) => | ||
getTimeFormatter(options).format(t) | ||
|
||
const formatDate: DateFormatter = (d, options) => | ||
getDateFormatter(options).format(d) | ||
|
||
const formatNumber: NumberFormatter = (n, options) => | ||
getNumberFormatter(options).format(n) | ||
|
||
export const $format = derived([$locale, $dictionary], () => formatMessage) | ||
export const $formatTime = derived([$locale], () => formatTime) | ||
export const $formatDate = derived([$locale], () => formatDate) | ||
export const $formatNumber = derived([$locale], () => formatNumber) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
<<<<<<< HEAD:test/runtime/stores/format.test.ts | ||
import { Formatter } from '../../../src/runtime/types' | ||
import { $format } from '../../../src/runtime/stores/format' | ||
import { init } from '../../../src/runtime/configs' | ||
import { addMessages } from '../../../src/runtime/stores/dictionary' | ||
import { $locale } from '../../../src/runtime/stores/locale' | ||
======= | ||
import { get } from 'svelte/store' | ||
|
||
import { | ||
$format, | ||
$formatTime, | ||
$formatDate, | ||
$formatNumber, | ||
} from '../../../src/client/stores/formatters' | ||
import { init } from '../../../src/client/configs' | ||
import { addMessages } from '../../../src/client/stores/dictionary' | ||
import { $locale } from '../../../src/client/stores/locale' | ||
import { MessageFormatter } from '../../../src/client/types' | ||
import { | ||
TimeFormatter, | ||
DateFormatter, | ||
NumberFormatter, | ||
} from '../../../src/client/types/index' | ||
>>>>>>> feat: 🎸 make date,time and number formatters tree-shakeable:test/client/stores/formatters.test.ts | ||
|
||
let formatMessage: MessageFormatter | ||
let formatTime: TimeFormatter | ||
let formatDate: DateFormatter | ||
let formatNumber: NumberFormatter | ||
$locale.subscribe(() => { | ||
formatMessage = get($format) | ||
formatTime = get($formatTime) | ||
formatDate = get($formatDate) | ||
formatNumber = get($formatNumber) | ||
}) | ||
|
||
addMessages('en', require('../../fixtures/en.json')) | ||
addMessages('en-GB', require('../../fixtures/en-GB.json')) | ||
addMessages('pt', require('../../fixtures/pt.json')) | ||
addMessages('pt-BR', require('../../fixtures/pt-BR.json')) | ||
addMessages('pt-PT', require('../../fixtures/pt-PT.json')) | ||
|
||
beforeEach(() => { | ||
init({ fallbackLocale: 'en' }) | ||
}) | ||
|
||
test('formats a message by its id and the current locale', () => { | ||
expect(formatMessage({ id: 'form.field_1_name' })).toBe('Name') | ||
}) | ||
|
||
test('formats a message by its id and the a passed locale', () => { | ||
expect(formatMessage({ id: 'form.field_1_name', locale: 'pt' })).toBe('Nome') | ||
}) | ||
|
||
test('formats a message with interpolated values', () => { | ||
expect(formatMessage({ id: 'photos', values: { n: 0 } })).toBe( | ||
'You have no photos.' | ||
) | ||
expect(formatMessage({ id: 'photos', values: { n: 1 } })).toBe( | ||
'You have one photo.' | ||
) | ||
expect(formatMessage({ id: 'photos', values: { n: 21 } })).toBe( | ||
'You have 21 photos.' | ||
) | ||
}) | ||
|
||
test('accepts a message id as first argument', () => { | ||
expect(formatMessage('form.field_1_name')).toBe('Name') | ||
}) | ||
|
||
test('accepts a message id as first argument and formatting options as second', () => { | ||
expect(formatMessage('form.field_1_name', { locale: 'pt' })).toBe('Nome') | ||
}) | ||
|
||
test('throws if no locale is set', () => { | ||
$locale.set(null) | ||
expect(() => formatMessage('form.field_1_name')).toThrow( | ||
'[svelte-i18n] Cannot format a message without first setting the initial locale.' | ||
) | ||
}) | ||
|
||
test('uses a missing message default value', () => { | ||
expect(formatMessage('missing', { default: 'Missing Default' })).toBe( | ||
'Missing Default' | ||
) | ||
}) | ||
|
||
test('warn on missing messages', () => { | ||
const warn = global.console.warn | ||
global.console.warn = jest.fn() | ||
|
||
formatMessage('missing') | ||
|
||
expect(console.warn).toBeCalledWith( | ||
`[svelte-i18n] The message "missing" was not found in "en".` | ||
) | ||
|
||
global.console.warn = warn | ||
}) | ||
|
||
describe('format utilities', () => { | ||
test('time', () => { | ||
expect(formatTime(new Date(2019, 0, 1, 20, 37))).toBe('8:37 PM') | ||
}) | ||
test('date', () => { | ||
expect(formatDate(new Date(2019, 0, 1, 20, 37))).toBe('1/1/19') | ||
}) | ||
test('number', () => { | ||
expect(formatNumber(123123123)).toBe('123,123,123') | ||
}) | ||
}) |
Oops, something went wrong.