Match-id-417ad546618f89732bb60368a0b25e5f7f547b20
This commit is contained in:
commit
9fbaf33e17
|
@ -4,7 +4,7 @@
|
|||
"description": "",
|
||||
"main": "build/intl.umd.js",
|
||||
"type": "commonjs",
|
||||
"types": "build/@types/index.d.ts",
|
||||
"types": "build/index.d.ts",
|
||||
"scripts": {
|
||||
"demo-serve": "webpack serve --mode=development",
|
||||
"rollup-build": "rollup --config rollup.config.js",
|
||||
|
|
|
@ -17,8 +17,9 @@ import EventDispatcher from '../utils/eventListener';
|
|||
import DateTimeFormatter from "../format/fomatters/DateTimeFormatter";
|
||||
import NumberFormatter from "../format/fomatters/NumberFormatter";
|
||||
import { getFormatMessage } from '../format/getFormatMessage';
|
||||
import { I18nProps, MessageDescriptor, MessageOptions } from '../types/interfaces';
|
||||
import {I18nCache, I18nProps, MessageDescriptor, MessageOptions} from '../types/interfaces';
|
||||
import { Locale, Locales, Messages, AllLocaleConfig, AllMessages, LocaleConfig, Error, Events } from '../types/types';
|
||||
import creatI18nCache from "../format/cache/cache";
|
||||
|
||||
export class I18n extends EventDispatcher<Events> {
|
||||
public locale: Locale;
|
||||
|
@ -26,7 +27,7 @@ export class I18n extends EventDispatcher<Events> {
|
|||
private readonly _localeConfig: AllLocaleConfig;
|
||||
private readonly allMessages: AllMessages;
|
||||
public readonly error?: Error;
|
||||
public readonly useMemorize?: boolean;
|
||||
public readonly cache?: I18nCache;
|
||||
|
||||
constructor(props: I18nProps) {
|
||||
super();
|
||||
|
@ -48,6 +49,8 @@ export class I18n extends EventDispatcher<Events> {
|
|||
this.formatMessage = this.formatMessage.bind(this);
|
||||
this.formatDate = this.formatDate.bind(this);
|
||||
this.formatNumber = this.formatNumber.bind(this);
|
||||
|
||||
this.cache = props.cache ?? creatI18nCache();
|
||||
}
|
||||
|
||||
get messages(): string | Messages | AllMessages {
|
||||
|
@ -115,18 +118,18 @@ export class I18n extends EventDispatcher<Events> {
|
|||
formatMessage(
|
||||
id: MessageDescriptor | string,
|
||||
values: Object | undefined = {},
|
||||
{ message, context, formatOptions, useMemorize}: MessageOptions = {},
|
||||
{ message, context, formatOptions}: MessageOptions = {},
|
||||
) {
|
||||
return getFormatMessage(this, id, values, { message, context, formatOptions, useMemorize});
|
||||
return getFormatMessage(this, id, values, { message, context, formatOptions});
|
||||
}
|
||||
|
||||
formatDate(value: string | Date, formatOptions?: Intl.DateTimeFormatOptions): string {
|
||||
const dateTimeFormatter = new DateTimeFormatter(this.locale || this.locales, formatOptions, this.useMemorize);
|
||||
const dateTimeFormatter = new DateTimeFormatter(this.locale || this.locales, formatOptions, this.cache);
|
||||
return dateTimeFormatter.dateTimeFormat(value);
|
||||
}
|
||||
|
||||
formatNumber(value: number, formatOptions?: Intl.NumberFormatOptions): string {
|
||||
const numberFormatter = new NumberFormatter(this.locale || this.locales, formatOptions, this.useMemorize);
|
||||
const numberFormatter = new NumberFormatter(this.locale || this.locales, formatOptions, this.cache);
|
||||
return numberFormatter.numberFormat(value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,8 +12,7 @@
|
|||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
import Inula, { useRef, useState, useEffect, useMemo, Component } from 'inulajs';
|
||||
import utils from '../../utils/utils';
|
||||
import Inula, { useRef, useState, useEffect, useMemo } from 'inulajs';
|
||||
import { InjectProvider } from './InjectI18n';
|
||||
import I18n, { createI18nInstance } from '../I18n';
|
||||
import { I18nProviderProps } from '../../types/types';
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
*/
|
||||
import { configProps, I18nCache } from '../types/interfaces';
|
||||
import I18n, { createI18nInstance } from './I18n';
|
||||
import creatI18nCache from '../format/cache/cache';
|
||||
|
||||
/**
|
||||
* createI18n hook函数,用于创建国际化i8n实例,以进行相关的数据操作
|
||||
|
@ -22,9 +23,9 @@ import I18n, { createI18nInstance } from './I18n';
|
|||
export const createI18n = (config: configProps, cache?: I18nCache): I18n => {
|
||||
const { locale, defaultLocale, messages } = config;
|
||||
return createI18nInstance({
|
||||
locale: locale || defaultLocale || 'en',
|
||||
locale: locale || defaultLocale || 'zh',
|
||||
messages: messages,
|
||||
useMemorize: !!cache,
|
||||
cache: cache ?? creatI18nCache(),
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
import { UNICODE_REG } from '../constants';
|
||||
import { CompiledMessage, Locale, LocaleConfig, Locales } from '../types/types';
|
||||
import generateFormatters from './generateFormatters';
|
||||
import { FormatOptions } from '../types/interfaces';
|
||||
import {FormatOptions, I18nCache} from '../types/interfaces';
|
||||
import {createIntlCache} from "../../index";
|
||||
|
||||
/**
|
||||
* 获取翻译结果
|
||||
|
@ -26,14 +27,14 @@ class Translation {
|
|||
private readonly locale: Locale;
|
||||
private readonly locales: Locales;
|
||||
private readonly localeConfig: Record<string, any>;
|
||||
private readonly useMemorize?: boolean;
|
||||
private readonly cache: I18nCache;
|
||||
|
||||
constructor(compiledMessage, locale, locales, localeConfig, memorize?) {
|
||||
constructor(compiledMessage, locale, locales, localeConfig, cache?) {
|
||||
this.compiledMessage = compiledMessage;
|
||||
this.locale = locale;
|
||||
this.locales = locales;
|
||||
this.localeConfig = localeConfig;
|
||||
this.useMemorize = memorize ?? true;
|
||||
this.cache = cache ?? createIntlCache;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -47,12 +48,11 @@ class Translation {
|
|||
values: object,
|
||||
formatOptions: FormatOptions,
|
||||
localeConfig: LocaleConfig,
|
||||
useMemorize?: boolean
|
||||
) => {
|
||||
const textFormatter = (name: string, type: string, format: any) => {
|
||||
const formatters = generateFormatters(locale, locales, localeConfig, formatOptions);
|
||||
const formatters = generateFormatters(locale, locales, localeConfig, formatOptions, this.cache);
|
||||
const value = values[name];
|
||||
const formatter = formatters[type](value, format, useMemorize);
|
||||
const formatter = formatters[type](value, format);
|
||||
|
||||
let message;
|
||||
if (typeof formatter === 'function') {
|
||||
|
@ -73,7 +73,6 @@ class Translation {
|
|||
values,
|
||||
formatOptions,
|
||||
this.localeConfig,
|
||||
this.useMemorize
|
||||
);
|
||||
// 通过递归方法formatCore进行格式化处理
|
||||
const result = this.formatMessage(this.compiledMessage, textFormatter);
|
||||
|
|
|
@ -22,7 +22,6 @@ function creatI18nCache(): I18nCache {
|
|||
dateTimeFormat: {},
|
||||
numberFormat: {},
|
||||
plurals: {},
|
||||
messages: {},
|
||||
select: {},
|
||||
octothorpe: {},
|
||||
};
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
import creatI18nCache from '../cache/cache';
|
||||
import utils from '../../utils/utils';
|
||||
import { DatePool, Locales } from '../../types/types';
|
||||
import {I18nCache} from "../../types/interfaces";
|
||||
|
||||
/**
|
||||
* 时间格式化
|
||||
|
@ -23,17 +24,13 @@ import { DatePool, Locales } from '../../types/types';
|
|||
class DateTimeFormatter {
|
||||
private readonly locales: Locales;
|
||||
private readonly formatOptions: Intl.DateTimeFormatOptions;
|
||||
|
||||
// 是否进行存储
|
||||
private readonly useMemorize: boolean;
|
||||
|
||||
// 创建一个缓存对象,用于存储DateTimeFormat的对象
|
||||
private cache = creatI18nCache().dateTimeFormat;
|
||||
private readonly cache?: I18nCache;
|
||||
|
||||
constructor(locales: Locales, formatOptions?: Intl.DateTimeFormatOptions, useMemorize?: boolean) {
|
||||
constructor(locales: Locales, formatOptions?: Intl.DateTimeFormatOptions, cache?: I18nCache) {
|
||||
this.locales = locales;
|
||||
this.formatOptions = formatOptions ?? {};
|
||||
this.useMemorize = useMemorize ?? true;
|
||||
this.cache = cache ?? creatI18nCache();
|
||||
}
|
||||
|
||||
dateTimeFormat(value: DatePool, formatOptions?: Intl.DateTimeFormatOptions): string {
|
||||
|
@ -45,16 +42,16 @@ class DateTimeFormatter {
|
|||
}
|
||||
|
||||
// 如果启用了记忆化且已经有对应的数字格式化器缓存,则直接返回缓存中的格式化结果。否则创建新的格式化数据,并进行缓存
|
||||
if (this.useMemorize) {
|
||||
if (this.cache?.dateTimeFormat) {
|
||||
// 造缓存的key,key包含区域设置和日期时间格式选项
|
||||
const cacheKey = utils.generateKey<Intl.DateTimeFormatOptions>(this.locales, options);
|
||||
|
||||
if (this.cache[cacheKey]) {
|
||||
return this.cache[cacheKey].format(value);
|
||||
if (this.cache.dateTimeFormat[cacheKey]) {
|
||||
return this.cache.dateTimeFormat[cacheKey].format(value);
|
||||
}
|
||||
|
||||
// 查询缓存中的key, 若无key则创建新key
|
||||
this.cache[cacheKey] = formatter;
|
||||
this.cache.dateTimeFormat[cacheKey] = formatter;
|
||||
return formatter.format(value);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
import creatI18nCache from '../cache/cache';
|
||||
import { Locales } from '../../types/types';
|
||||
import utils from '../../utils/utils';
|
||||
import {I18nCache} from "../../types/interfaces";
|
||||
|
||||
/**
|
||||
* 数字格式化
|
||||
|
@ -23,13 +24,12 @@ import utils from '../../utils/utils';
|
|||
class NumberFormatter {
|
||||
private readonly locales: Locales;
|
||||
private readonly formatOption?: Intl.NumberFormatOptions;
|
||||
private readonly useMemorize?: boolean;
|
||||
private cache = creatI18nCache().numberFormat; // 创建一个缓存对象,用于缓存已经创建的数字格式化器
|
||||
private cache?: I18nCache; // 创建一个缓存对象,用于缓存已经创建的数字格式化器
|
||||
|
||||
constructor(locales: Locales, formatOption?: Intl.NumberFormatOptions, useMemorize?: boolean) {
|
||||
constructor(locales: Locales, formatOption?: Intl.NumberFormatOptions, cache?: I18nCache) {
|
||||
this.locales = locales;
|
||||
this.formatOption = formatOption ?? {};
|
||||
this.useMemorize = useMemorize ?? true;
|
||||
this.cache = cache ?? creatI18nCache();
|
||||
}
|
||||
|
||||
numberFormat(value: number, formatOption?: Intl.NumberFormatOptions): string {
|
||||
|
@ -37,15 +37,15 @@ class NumberFormatter {
|
|||
const formatter = new Intl.NumberFormat(this.locales, options);
|
||||
|
||||
// 如果启用了记忆化且已经有对应的数字格式化器缓存,则直接返回缓存中的格式化结果。否则创建新的格式化数据,并进行缓存
|
||||
if (this.useMemorize) {
|
||||
if (this.cache?.numberFormat) {
|
||||
// 造缓存的key,key包含区域设置数字格式选项
|
||||
const cacheKey = utils.generateKey<Intl.NumberFormatOptions>(this.locales, options);
|
||||
|
||||
if (this.cache[cacheKey]) {
|
||||
return this.cache[cacheKey].format(value);
|
||||
if (this.cache.numberFormat[cacheKey]) {
|
||||
return this.cache.numberFormat[cacheKey].format(value);
|
||||
}
|
||||
|
||||
this.cache[cacheKey] = formatter;
|
||||
this.cache.numberFormat[cacheKey] = formatter;
|
||||
return formatter.format(value);
|
||||
}
|
||||
return formatter.format(value);
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
import utils from '../../utils/utils';
|
||||
import NumberFormatter from './NumberFormatter';
|
||||
import { Locale, Locales } from '../../types/types';
|
||||
import {I18nCache} from "../../types/interfaces";
|
||||
import {createIntlCache} from "../../../index";
|
||||
|
||||
/**
|
||||
* 复数格式化
|
||||
|
@ -25,15 +27,14 @@ class PluralFormatter {
|
|||
private readonly locales: Locales;
|
||||
private readonly value: number;
|
||||
private readonly message: any;
|
||||
private readonly useMemorize: boolean;
|
||||
private octothorpe: Record<string, any> = {};
|
||||
private readonly cache: I18nCache;
|
||||
|
||||
constructor(locale, locales, value, message, useMemorize?) {
|
||||
constructor(locale, locales, value, message, cache?) {
|
||||
this.locale = locale;
|
||||
this.locales = locales;
|
||||
this.value = value;
|
||||
this.message = message;
|
||||
this.useMemorize = useMemorize ?? true;
|
||||
this.cache = cache ?? createIntlCache();
|
||||
}
|
||||
|
||||
// 将 message中的“#”替换为指定数字value,并返回新的字符串或者字符串数组
|
||||
|
@ -44,17 +45,17 @@ class PluralFormatter {
|
|||
const numberFormatter = new NumberFormatter(this.locales);
|
||||
const valueStr = numberFormatter.numberFormat(this.value);
|
||||
|
||||
if (this.useMemorize) {
|
||||
if (this.cache.octothorpe) {
|
||||
// 创建key,用于唯一标识
|
||||
const cacheKey = utils.generateKey<Intl.NumberFormatOptions>(this.locale, this.message);
|
||||
|
||||
// 如果key存在,则使用缓存中的替代
|
||||
if (this.octothorpe[cacheKey]) {
|
||||
return messages.map(msg => (typeof msg === 'string' ? msg.replace('#', this.octothorpe[cacheKey]) : msg));
|
||||
if (this.cache.octothorpe[cacheKey]) {
|
||||
return messages.map(msg => (typeof msg === 'string' ? msg.replace('#', this.cache.octothorpe[cacheKey]) : msg));
|
||||
}
|
||||
|
||||
// 如果不存在,则进行缓存
|
||||
this.octothorpe[cacheKey] = valueStr;
|
||||
this.cache.octothorpe[cacheKey] = valueStr;
|
||||
}
|
||||
|
||||
return messages.map(msg => (typeof msg === 'string' ? msg.replace('#', valueStr) : msg));
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
import utils from '../../utils/utils';
|
||||
import { Locale } from '../../types/types';
|
||||
import {I18nCache} from "../../types/interfaces";
|
||||
|
||||
/**
|
||||
* 规则选择器
|
||||
|
@ -23,24 +24,25 @@ import { Locale } from '../../types/types';
|
|||
*/
|
||||
class SelectFormatter {
|
||||
private readonly locale: Locale;
|
||||
private selectCache = {};
|
||||
private readonly cache: I18nCache;
|
||||
|
||||
constructor(locale) {
|
||||
constructor(locale, cache) {
|
||||
this.locale = locale;
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
getRule(value, rules, useMemorize?) {
|
||||
if (useMemorize) {
|
||||
getRule(value, rules) {
|
||||
if (this.cache.select) {
|
||||
// 创建key,用于唯一标识
|
||||
const cacheKey = utils.generateKey<Intl.NumberFormatOptions>(this.locale, rules);
|
||||
|
||||
// 如果key存在,则使用缓存中的替代
|
||||
if (this.selectCache[cacheKey]) {
|
||||
return this.selectCache[cacheKey][value] || this.selectCache[cacheKey].other;
|
||||
if (this.cache.select[cacheKey]) {
|
||||
return this.cache.select[cacheKey][value] || this.cache.select[cacheKey].other;
|
||||
}
|
||||
|
||||
// 如果不存在,则进行缓存
|
||||
this.selectCache[cacheKey] = rules;
|
||||
this.cache.select[cacheKey] = rules;
|
||||
}
|
||||
|
||||
return rules[value] || rules.other;
|
||||
|
|
|
@ -18,7 +18,8 @@ import NumberFormatter from './fomatters/NumberFormatter';
|
|||
import { DatePool, Locale, Locales, SelectPool } from '../types/types';
|
||||
import PluralFormatter from './fomatters/PluralFormatter';
|
||||
import SelectFormatter from './fomatters/SelectFormatter';
|
||||
import { FormatOptions, IntlMessageFormat } from '../types/interfaces';
|
||||
import {FormatOptions, I18nCache, IntlMessageFormat} from '../types/interfaces';
|
||||
import cache from "./cache/cache";
|
||||
|
||||
/**
|
||||
* 默认格式化接口
|
||||
|
@ -27,7 +28,8 @@ const generateFormatters = (
|
|||
locale: Locale | Locales,
|
||||
locales: Locales,
|
||||
localeConfig: Record<string, any> = { plurals: undefined },
|
||||
formatOptions: FormatOptions = {} // 自定义格式对象
|
||||
formatOptions: FormatOptions = {}, // 自定义格式对象
|
||||
cache: I18nCache
|
||||
): IntlMessageFormat => {
|
||||
locale = locales || locale;
|
||||
const { plurals } = localeConfig;
|
||||
|
@ -45,13 +47,13 @@ const generateFormatters = (
|
|||
|
||||
return {
|
||||
// 复数规则
|
||||
plural: (value: number, { offset = 0, ...rules }, useMemorize?) => {
|
||||
plural: (value: number, { offset = 0, ...rules }) => {
|
||||
const pluralFormatter = new PluralFormatter(
|
||||
locale,
|
||||
locales,
|
||||
value - offset,
|
||||
rules[value] || rules[(plurals as any)?.(value - offset)] || rules.other,
|
||||
useMemorize
|
||||
cache
|
||||
);
|
||||
return pluralFormatter.replaceSymbol.bind(pluralFormatter);
|
||||
},
|
||||
|
@ -63,14 +65,14 @@ const generateFormatters = (
|
|||
},
|
||||
|
||||
// 选择规则,如果规则对象中包含与该值相对应的属性,则返回该属性的值;否则,返回 "other" 属性的值。
|
||||
select: (value: SelectPool, formatRules, useMemorize?) => {
|
||||
const selectFormatter = new SelectFormatter(locale);
|
||||
return selectFormatter.getRule(value, formatRules, useMemorize);
|
||||
select: (value: SelectPool, formatRules) => {
|
||||
const selectFormatter = new SelectFormatter(locale, cache);
|
||||
return selectFormatter.getRule(value, formatRules);
|
||||
},
|
||||
|
||||
// 用于将数字格式化为字符串,接受一个数字和一个格式化规则。它会根据规则返回格式化后的字符串。
|
||||
numberFormat: (value: number, formatOption, useMemorize) => {
|
||||
return new NumberFormatter(locales, getStyleOption(formatOption), useMemorize).numberFormat(value);
|
||||
numberFormat: (value: number, formatOption) => {
|
||||
return new NumberFormatter(locales, getStyleOption(formatOption), cache).numberFormat(value);
|
||||
},
|
||||
|
||||
// 用于将日期格式化为字符串,接受一个日期对象和一个格式化规则。它会根据规则返回格式化后的字符串。
|
||||
|
@ -83,8 +85,8 @@ const generateFormatters = (
|
|||
* @param formatOption { year: 'numeric', month: 'long', day: 'numeric' }
|
||||
* @param useMemorize
|
||||
*/
|
||||
dateTimeFormat: (value: DatePool, formatOption, useMemorize) => {
|
||||
return new DateTimeFormatter(locales, getStyleOption(formatOption), useMemorize).dateTimeFormat(
|
||||
dateTimeFormat: (value: DatePool, formatOption) => {
|
||||
return new DateTimeFormatter(locales, getStyleOption(formatOption), cache).dateTimeFormat(
|
||||
value,
|
||||
formatOption
|
||||
);
|
||||
|
|
|
@ -18,6 +18,7 @@ import Translation from './Translation';
|
|||
import I18n from '../core/I18n';
|
||||
import { MessageDescriptor, MessageOptions } from '../types/interfaces';
|
||||
import { CompiledMessage } from '../types/types';
|
||||
import creatI18nCache from "./cache/cache";
|
||||
|
||||
export function getFormatMessage(
|
||||
i18n: I18n,
|
||||
|
@ -25,8 +26,8 @@ export function getFormatMessage(
|
|||
values: Object | undefined = {},
|
||||
options: MessageOptions = {}
|
||||
) {
|
||||
let { message, context, formatOptions, useMemorize } = options;
|
||||
const memorize = useMemorize ?? i18n.useMemorize;
|
||||
let { message, context, formatOptions } = options;
|
||||
const cache = i18n.cache ?? creatI18nCache();
|
||||
if (typeof id !== 'string') {
|
||||
values = values || id.defaultValues;
|
||||
message = id.message || id.defaultMessage;
|
||||
|
@ -59,6 +60,6 @@ export function getFormatMessage(
|
|||
// 对解析的messages进行parse解析,并输出解析后的Token
|
||||
compliedMessage = typeof compliedMessage === 'string' ? utils.compile(compliedMessage) : compliedMessage;
|
||||
|
||||
const translation = new Translation(compliedMessage, i18n.locale, i18n.locales, i18n.localeConfig, memorize);
|
||||
const translation = new Translation(compliedMessage, i18n.locale, i18n.locales, i18n.localeConfig, cache);
|
||||
return translation.translate(values, formatOptions);
|
||||
}
|
||||
|
|
|
@ -46,7 +46,6 @@ export interface MessageOptions {
|
|||
message?: string;
|
||||
context?: string;
|
||||
formatOptions?: FormatOptions;
|
||||
useMemorize?: boolean;
|
||||
}
|
||||
|
||||
// I18n类的缓存定义
|
||||
|
@ -54,8 +53,7 @@ export interface I18nCache {
|
|||
dateTimeFormat: Record<string, Intl.DateTimeFormat>;
|
||||
numberFormat: Record<string, Intl.NumberFormat>;
|
||||
plurals: Record<string, Intl.PluralRules>;
|
||||
messages: Record<string, IntlMessageFormat>;
|
||||
select: Record<string, object>;
|
||||
select: Record<string, any>;
|
||||
octothorpe: Record<string, any>;
|
||||
}
|
||||
|
||||
|
@ -65,7 +63,7 @@ export interface I18nProps {
|
|||
locales?: Locales;
|
||||
messages?: AllMessages;
|
||||
localeConfig?: AllLocaleConfig;
|
||||
useMemorize?: boolean;
|
||||
cache?: I18nCache;
|
||||
error?: Error;
|
||||
}
|
||||
|
||||
|
@ -91,23 +89,41 @@ export interface configProps {
|
|||
defaultLocale?: string;
|
||||
RenderOnLocaleChange?: boolean;
|
||||
children?: any;
|
||||
uesMemorize?: boolean;
|
||||
onWarn?: Error;
|
||||
}
|
||||
|
||||
export interface IntlMessageFormat extends configProps, MessageOptions {
|
||||
plural: (
|
||||
value: number,
|
||||
{ offset, ...rules }: { [x: string]: any; offset?: number },
|
||||
useMemorize?: boolean
|
||||
{
|
||||
offset,
|
||||
...rules
|
||||
}: {
|
||||
[x: string]: any;
|
||||
offset?: number | undefined;
|
||||
}
|
||||
) => (ctx: any) => any[];
|
||||
selectordinal: (
|
||||
value: number,
|
||||
{ offset, ...rules }: { [x: string]: any; offset?: number },
|
||||
useMemorize?: boolean
|
||||
{
|
||||
offset,
|
||||
...rules
|
||||
}: {
|
||||
[x: string]: any;
|
||||
offset?: number | undefined;
|
||||
}
|
||||
) => (ctx: any) => any[];
|
||||
select: (value: SelectPool, formatRules: any, useMemorize?: boolean) => any;
|
||||
numberFormat: (value: number, formatOption: any, useMemorize: boolean) => string;
|
||||
dateTimeFormat: (value: DatePool, formatOption: any, useMemorize: boolean) => string;
|
||||
select: (value: SelectPool, formatRules: any) => any;
|
||||
numberFormat: (value: number, formatOption: any) => string;
|
||||
/**
|
||||
* eg: { year: 'numeric', month: 'long', day: 'numeric' } 是一个用于指定DateTimeFormatter如何将日期对象转换为字符串的参数。
|
||||
* \year: 'numeric' 表示年份的表示方式是数字形式(比如2023)。
|
||||
* month: 'long' 表示月份的表示方式是全名(比如January)。
|
||||
* day: 'numeric' 表示日期的表示方式是数字形式(比如1号)。
|
||||
* @param value
|
||||
* @param formatOption { year: 'numeric', month: 'long', day: 'numeric' }
|
||||
*/
|
||||
dateTimeFormat: (value: DatePool, formatOption: any) => string;
|
||||
undefined: (value: any) => any;
|
||||
}
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ describe('I18n', () => {
|
|||
locale: 'en',
|
||||
messages: {
|
||||
en: messages,
|
||||
fr:{}
|
||||
fr: {},
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -13,40 +13,37 @@
|
|||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
import * as React from 'react'
|
||||
import {render} from '@testing-library/react'
|
||||
import {IntlProvider, useIntl} from "../../../index";
|
||||
import * as React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import { IntlProvider, useIntl } from '../../../index';
|
||||
|
||||
const FunctionComponent = ({ spy }: { spy?: Function }) => {
|
||||
const {i18n} = useIntl()
|
||||
spy!(i18n.locale)
|
||||
return null
|
||||
}
|
||||
const { i18n } = useIntl();
|
||||
spy!(i18n.locale);
|
||||
return null;
|
||||
};
|
||||
|
||||
const FC = () => {
|
||||
const i18n = useIntl()
|
||||
return i18n.formatNumber(10000, {style: 'currency', currency: 'USD'}) as any
|
||||
}
|
||||
const i18n = useIntl();
|
||||
return i18n.formatNumber(10000, { style: 'currency', currency: 'USD' }) as any;
|
||||
};
|
||||
|
||||
describe('useIntl() hooks', () => {
|
||||
it('throws when <IntlProvider> is missing from ancestry', () => {
|
||||
// So it doesn't spam the console
|
||||
jest.spyOn(console, 'error').mockImplementation(() => {
|
||||
})
|
||||
expect(() => render(<FunctionComponent/>)).toThrow(
|
||||
'I18n object is not found!'
|
||||
)
|
||||
})
|
||||
jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
expect(() => render(<FunctionComponent />)).toThrow('I18n object is not found!');
|
||||
});
|
||||
|
||||
it('hooks onto the intl context', () => {
|
||||
const spy = jest.fn()
|
||||
const spy = jest.fn();
|
||||
render(
|
||||
<IntlProvider locale="en">
|
||||
<FunctionComponent spy={spy} />
|
||||
</IntlProvider>
|
||||
)
|
||||
expect(spy).toHaveBeenCalledWith('en')
|
||||
})
|
||||
);
|
||||
expect(spy).toHaveBeenCalledWith('en');
|
||||
});
|
||||
|
||||
it('should work when switching locale on provider', () => {
|
||||
const { rerender, getByTestId } = render(
|
||||
|
@ -55,24 +52,24 @@ describe('useIntl() hooks', () => {
|
|||
<FC />
|
||||
</span>
|
||||
</IntlProvider>
|
||||
)
|
||||
expect(getByTestId('comp')).toMatchSnapshot()
|
||||
);
|
||||
expect(getByTestId('comp')).toMatchSnapshot();
|
||||
rerender(
|
||||
<IntlProvider locale="es">
|
||||
<span data-testid="comp">
|
||||
<FC />
|
||||
</span>
|
||||
</IntlProvider>
|
||||
)
|
||||
expect(getByTestId('comp')).toMatchSnapshot()
|
||||
);
|
||||
expect(getByTestId('comp')).toMatchSnapshot();
|
||||
rerender(
|
||||
<IntlProvider locale="en">
|
||||
<span data-testid="comp">
|
||||
<FC />
|
||||
</span>
|
||||
</IntlProvider>
|
||||
)
|
||||
);
|
||||
|
||||
expect(getByTestId('comp')).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
expect(getByTestId('comp')).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
*/
|
||||
|
||||
import Translation from '../../src/format/Translation';
|
||||
import {createIntlCache} from "../../index";
|
||||
|
||||
describe('Translation', () => {
|
||||
let translation;
|
||||
|
@ -23,8 +24,7 @@ describe('Translation', () => {
|
|||
const locale = 'en';
|
||||
const locales = {};
|
||||
const localeConfig = {};
|
||||
const useMemorize = true;
|
||||
translation = new Translation(compiledMessage, locale, locales, localeConfig, useMemorize);
|
||||
translation = new Translation(compiledMessage, locale, locales, localeConfig, createIntlCache());
|
||||
});
|
||||
describe('formatMessage', () => {
|
||||
it('should return the message if it is not an array', () => {
|
||||
|
|
|
@ -21,7 +21,6 @@ describe('creatI18nCache', () => {
|
|||
expect(intlCache).toEqual({
|
||||
dateTimeFormat: {},
|
||||
numberFormat: {},
|
||||
messages: {},
|
||||
plurals: {},
|
||||
select: {},
|
||||
octothorpe: {},
|
||||
|
|
|
@ -43,7 +43,6 @@ describe('compile', function () {
|
|||
|
||||
it('should compile message with variable', function () {
|
||||
const cache = utils.compile('Hey {name}!');
|
||||
console.log(cache)
|
||||
expect(new Translation(cache, 'en', [], {}).translate({})).toEqual('Hey {name}!');
|
||||
});
|
||||
|
||||
|
@ -58,7 +57,6 @@ describe('compile', function () {
|
|||
expect(translate({ value: 1 })).toEqual('1 Book');
|
||||
expect(translate({ value: 2 })).toEqual('2 Books');
|
||||
|
||||
|
||||
const translatePlurals = prepare('{value, plural, offset:1 =0 {No Books} one {# Book} other {# Books}}');
|
||||
|
||||
expect(translatePlurals({ value: 0 })).toEqual('No Books');
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
*/
|
||||
|
||||
import { DateTimeFormatter } from '../../../index';
|
||||
import creatI18nCache from "../../../src/format/cache/cache";
|
||||
|
||||
describe('DateTimeFormatter', () => {
|
||||
const date = new Date('2023-04-03T12:34:56Z');
|
||||
|
@ -25,7 +26,7 @@ describe('DateTimeFormatter', () => {
|
|||
const firstRunResult = firstRunt1 - firstRunt0;
|
||||
|
||||
const seconddRunt0 = performance.now();
|
||||
const dateTimeFormatter2 = new DateTimeFormatter('es', {}, false);
|
||||
const dateTimeFormatter2 = new DateTimeFormatter('es', {});
|
||||
dateTimeFormatter2.dateTimeFormat(new Date());
|
||||
const seconddRunt1 = performance.now();
|
||||
const secondRunResult = seconddRunt1 - seconddRunt0;
|
||||
|
@ -62,8 +63,8 @@ describe('DateTimeFormatter', () => {
|
|||
|
||||
it('should not memoize formatter instances when memoize is false', () => {
|
||||
const spy = jest.spyOn(Intl, 'DateTimeFormat');
|
||||
const formatter1 = new DateTimeFormatter('en-US', { month: 'short' }, false);
|
||||
const formatter2 = new DateTimeFormatter('en-US', { month: 'short' }, false);
|
||||
const formatter1 = new DateTimeFormatter('en-US', { month: 'short' });
|
||||
const formatter2 = new DateTimeFormatter('en-US', { month: 'short' });
|
||||
formatter1.dateTimeFormat(date);
|
||||
formatter2.dateTimeFormat(date);
|
||||
expect(spy).toHaveBeenCalledTimes(5);
|
||||
|
@ -91,7 +92,7 @@ describe('DateTimeFormatter', () => {
|
|||
});
|
||||
|
||||
it('should format using memorized formatter when useMemorize is true', () => {
|
||||
const formatter = new DateTimeFormatter('en-US',{"year":'numeric'}, true);
|
||||
const formatter = new DateTimeFormatter('en-US',{"year":'numeric'}, creatI18nCache());
|
||||
const date = new Date(2023, 0, 1);
|
||||
const formatted1 = formatter.dateTimeFormat(date);
|
||||
const formatted2 = formatter.dateTimeFormat(date);
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
*/
|
||||
|
||||
import { NumberFormatter } from '../../../index';
|
||||
import creatI18nCache from "../../../src/format/cache/cache";
|
||||
|
||||
describe('NumberFormatter', () => {
|
||||
it('number formatter is memoized', async () => {
|
||||
|
@ -24,7 +25,7 @@ describe('NumberFormatter', () => {
|
|||
const firstRunResult = firstRunt1 - firstRunt0;
|
||||
|
||||
const seconddRunt0 = performance.now();
|
||||
const numberFormatter = new NumberFormatter('es', {}, false);
|
||||
const numberFormatter = new NumberFormatter('es', {});
|
||||
numberFormatter.numberFormat(10000);
|
||||
const secondRunt1 = performance.now();
|
||||
const secondRunResult = secondRunt1 - seconddRunt0;
|
||||
|
@ -82,7 +83,7 @@ describe('NumberFormatter', () => {
|
|||
});
|
||||
|
||||
it('should format using memorized formatter when useMemorize is true', () => {
|
||||
const formatter = new NumberFormatter('en-US', undefined, true);
|
||||
const formatter = new NumberFormatter('en-US', undefined, creatI18nCache());
|
||||
const number = 12345.6789;
|
||||
const formatted1 = formatter.numberFormat(number);
|
||||
const formatted2 = formatter.numberFormat(number);
|
||||
|
@ -90,7 +91,7 @@ describe('NumberFormatter', () => {
|
|||
});
|
||||
|
||||
it('should create a new formatter when useMemorize is false', () => {
|
||||
const formatter = new NumberFormatter('en-US', undefined, false);
|
||||
const formatter = new NumberFormatter('en-US', undefined);
|
||||
const number = 12345.6789;
|
||||
const formatted1 = formatter.numberFormat(number);
|
||||
const formatted2 = formatter.numberFormat(number);
|
||||
|
|
|
@ -61,7 +61,7 @@ describe('ruleUtils test', () => {
|
|||
|
||||
expect(() => {
|
||||
ruleUtils.getReg(input);
|
||||
}).toThrowError('Signs Prohibited');
|
||||
}).toThrowError('prohibition sign');
|
||||
});
|
||||
|
||||
it('should throw an error when input regular expression object has forbidden flags', () => {
|
||||
|
|
Loading…
Reference in New Issue