add unittest
This commit is contained in:
parent
d945c2092d
commit
a97452d494
119
packages/runtime/src/__tests__/formatter.test.ts
Normal file
119
packages/runtime/src/__tests__/formatter.test.ts
Normal file
@ -0,0 +1,119 @@
|
||||
import {test,vi,describe,expect,afterAll,beforeAll, beforeEach} from 'vitest'
|
||||
import { VoerkaI18nScope } from '../scope'
|
||||
import zhFormatters from '../formatters/zh';
|
||||
import enFormatters from '../formatters/en';
|
||||
import { VoerkaI18nManager } from '../manager';
|
||||
import { VoerkaI18nFormatterRegistry } from '../formatterRegistry';
|
||||
import { VoerkaI18nTranslate } from '../types';
|
||||
import { default as inlineFormatters } from '../formatters';
|
||||
import { InvalidLanguageError } from '../errors';
|
||||
import { createI18nScope, mergeFormattersConfigs } from './utils';
|
||||
import { messages,zhMessages,enMessages,formatters } from './utils/testData';
|
||||
|
||||
let scope:VoerkaI18nScope;
|
||||
|
||||
describe("格式化化配置与参数", () => {
|
||||
beforeAll(async ()=>{
|
||||
return new Promise((resolve)=>{
|
||||
scope = createI18nScope({
|
||||
ready:resolve
|
||||
})
|
||||
})
|
||||
})
|
||||
beforeEach(async ()=>{
|
||||
await scope.change("zh")
|
||||
})
|
||||
test("格式化器参数", async () => {
|
||||
expect(scope.formatters).toBeInstanceOf(VoerkaI18nFormatterRegistry)
|
||||
expect(scope.formatters.activeLanguage).toBe("zh")
|
||||
expect(scope.formatters.formatters).toEqual(formatters)
|
||||
expect(scope.formatters.types).toBe(zhFormatters.$types)
|
||||
})
|
||||
|
||||
test("查找格式化器", async () => {
|
||||
expect(scope.formatters.get("first")).toBe(formatters.zh.first)
|
||||
await scope.change("en")
|
||||
expect(scope.formatters.get("first")).toBe(formatters.en.first)
|
||||
})
|
||||
test("合并后的格式化器配置", async () => {
|
||||
let fallbackLanguage = scope.getLanguage(scope.activeLanguage)?.fallback
|
||||
const globalFormatters = inlineFormatters
|
||||
let scopeConfig = mergeFormattersConfigs([
|
||||
(fallbackLanguage! in globalFormatters) ? (globalFormatters as any)?.[fallbackLanguage!].$config:{},
|
||||
globalFormatters.zh.$config,
|
||||
(fallbackLanguage! in formatters) ? (formatters as any)?.[fallbackLanguage!]?.$config:{},
|
||||
formatters.zh.$config
|
||||
])
|
||||
expect(scope.formatters.config).toEqual(scopeConfig)
|
||||
//
|
||||
await scope.change("en")
|
||||
fallbackLanguage = scope.getLanguage(scope.activeLanguage)?.fallback
|
||||
scopeConfig = mergeFormattersConfigs([
|
||||
(fallbackLanguage! in globalFormatters) ? (globalFormatters as any)?.[fallbackLanguage!].$config:{},
|
||||
globalFormatters.en.$config,
|
||||
(fallbackLanguage! in formatters) ? (formatters as any)?.[fallbackLanguage!]?.$config:{},
|
||||
formatters.en.$config
|
||||
])
|
||||
expect(scope.formatters.config).toEqual(scopeConfig)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
describe('插值变量格式化器', () => {
|
||||
let t:VoerkaI18nTranslate
|
||||
|
||||
|
||||
beforeAll(() => {
|
||||
t = scope.t
|
||||
// 注册格式化器,注册为所有语言
|
||||
scope.registerFormatter("add", (value,args,config) => {
|
||||
return String(Number(value) + (Number(args.length==0 ? 1 : args[0])))
|
||||
});
|
||||
scope.formatters.updateConfig("zh",{
|
||||
bookname:{
|
||||
beginChar:"《",
|
||||
endChar:"》"
|
||||
}
|
||||
});
|
||||
scope.formatters.updateConfig("en",{
|
||||
bookname:{
|
||||
beginChar:"<",
|
||||
endChar:">"
|
||||
}
|
||||
});
|
||||
// 注册格式化器,注册为所有语言
|
||||
scope.registerFormatter("bookname", (value,args,config) => {
|
||||
let { beginChar = "<",endChar=">" } = Object.assign({},(config as any)?.bookname)
|
||||
if(args.length==1){
|
||||
beginChar = endChar = args[0]
|
||||
}else if(args.length>=2){
|
||||
beginChar = args[0]
|
||||
endChar = args[1]
|
||||
}
|
||||
return beginChar + value + endChar
|
||||
})
|
||||
})
|
||||
test('格式化器',async () => {
|
||||
expect(t("我的工资是每月{|add}元",1000)).toBe("我的工资是每月1001元")
|
||||
expect(t("我的工资是每月{|add()}元",1000)).toBe("我的工资是每月1001元")
|
||||
expect(t("我的工资是每月{|add(2)}元",1000)).toBe("我的工资是每月1002元")
|
||||
expect(t("我的工资是每月{|add|add()|add(2)}元",1000)).toBe("我的工资是每月1004元")
|
||||
})
|
||||
test('bookname式化器',async () => {
|
||||
expect(t("hello {|bookname}","tom")).toBe("hello 《tom》")
|
||||
expect(t("hello {|bookname('#')}","tom")).toBe("hello #tom#")
|
||||
expect(t("hello {|bookname('#','!')}","tom")).toBe("hello #tom!")
|
||||
expect(t("hello {|bookname|bookname|bookname}","tom")).toBe("hello 《《《tom》》》")
|
||||
await scope.change("en")
|
||||
expect(t("hello {|bookname}","tom")).toBe("hello <tom>")
|
||||
})
|
||||
|
||||
test('空值格式化器',async () => {
|
||||
expect(t("hello {|bookname|empty('空')}",undefined)).toBe("hello 《空》")
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe('内置格式化器', () => {
|
||||
|
||||
})
|
@ -1,166 +1,80 @@
|
||||
|
||||
|
||||
import {test,vi,describe,expect,afterAll,beforeAll, beforeEach} from 'vitest'
|
||||
import { VoerkaI18nScope } from '../scope'
|
||||
import zhFormatters from '../formatters/zh';
|
||||
import enFormatters from '../formatters/en';
|
||||
import { VoerkaI18nScope } from '../scope'
|
||||
import { VoerkaI18nManager } from '../manager';
|
||||
import { VoerkaI18nFormatterRegistry } from '../formatterRegistry';
|
||||
import { VoerkaI18nLanguageMessages, VoerkaI18nFormatterConfigs, VoerkaI18nTranslate } from '../types';
|
||||
import { deepMerge } from 'flex-tools/object/deepMerge';
|
||||
import { isPlainObject } from 'flex-tools/typecheck/isPlainObject';
|
||||
import { default as inlineFormatters } from '../formatters';
|
||||
import { VoerkaI18nTranslate } from '../types';
|
||||
import { InvalidLanguageError } from '../errors';
|
||||
|
||||
function mergeFormattersConfigs(configSources:any[]){
|
||||
return configSources.reduce((finalConfig, curConfig)=>{
|
||||
if(isPlainObject(curConfig)) deepMerge(finalConfig,curConfig,{newObject:false,array:'replace'})
|
||||
return finalConfig
|
||||
},{})
|
||||
}
|
||||
|
||||
const zhMessages:VoerkaI18nLanguageMessages = {
|
||||
$config:{
|
||||
add:{a:1},
|
||||
dec:{b:1}
|
||||
},
|
||||
"你好": "你好",
|
||||
"我叫{name},今年{age}岁": "我叫{name},今年{age}岁",
|
||||
"中国": "中国",
|
||||
"我有{}部车": ["我没有车","我有一部车","我有两部车","我有{}部车"] ,
|
||||
"我的工资是每月{}元":"我的工资是每月{}元"
|
||||
}
|
||||
const enMessages={
|
||||
"你好": "hello",
|
||||
"我叫{name},今年{age}岁": "My name is {name},Now {age} years old year",
|
||||
"中国": "china",
|
||||
"我有{}部车": ["I don't have car","I have a car","I have two cars","I have {} cars"],
|
||||
"我的工资是每月{}元":"My salary is {} yuan per month"
|
||||
}
|
||||
|
||||
const messages = {
|
||||
zh: zhMessages,
|
||||
en: enMessages
|
||||
}
|
||||
|
||||
const idMap={
|
||||
"你好":1,
|
||||
"你好,{name}":2,
|
||||
"中国":3,
|
||||
"我有{}部车":4
|
||||
}
|
||||
const languages = [
|
||||
{ name: "zh",default:true,active:true},
|
||||
{ name: "en"}
|
||||
]
|
||||
|
||||
Object.assign(zhFormatters.$config,{
|
||||
x:{x1:1,x2:2},
|
||||
y:{y1:1,y2:2}
|
||||
})
|
||||
Object.assign(enFormatters.$config,{
|
||||
x:{x1:11,x2:22},
|
||||
y:{y1:11,y2:22},
|
||||
z:{z1:11,z2:22}
|
||||
})
|
||||
|
||||
const formatters ={
|
||||
"*":{
|
||||
$config:{
|
||||
x:{g:1},
|
||||
y:{g:1},
|
||||
g:{g1:1,g2:2}
|
||||
}
|
||||
},
|
||||
zh:{
|
||||
$config:{},
|
||||
prefix:(value:any,args:any[],config?:VoerkaI18nFormatterConfigs)=>config?.chars+value,
|
||||
first:(value:any)=>'ZH'+value[0],
|
||||
},
|
||||
en:{
|
||||
$config:{},
|
||||
first:(value:any)=>'EN'+value[0],
|
||||
},
|
||||
jp:()=>{}
|
||||
}
|
||||
import { createI18nScope } from './utils';
|
||||
import { messages,zhMessages,enMessages } from './utils/testData';
|
||||
|
||||
let scope:VoerkaI18nScope;
|
||||
|
||||
|
||||
|
||||
describe("所有测试", () => {
|
||||
beforeAll(async ()=>{
|
||||
return new Promise((resolve)=>{
|
||||
scope = new VoerkaI18nScope({
|
||||
id: "test",
|
||||
languages,
|
||||
messages,
|
||||
formatters,
|
||||
callback:()=>{
|
||||
resolve()
|
||||
}
|
||||
scope = createI18nScope({
|
||||
ready:resolve
|
||||
})
|
||||
})
|
||||
})
|
||||
beforeEach(async ()=>{
|
||||
await scope.change("zh")
|
||||
})
|
||||
describe("VoerkaI18nScope", () => {
|
||||
test("成功创建实例", () => {
|
||||
expect(scope).toBeInstanceOf(VoerkaI18nScope)
|
||||
expect(scope.activeLanguage).toBe("zh")
|
||||
expect(scope.defaultLanguage).toBe("zh")
|
||||
expect(scope.messages).toEqual(messages)
|
||||
expect(scope.default).toEqual(zhMessages)
|
||||
expect(scope.current).toEqual(zhMessages)
|
||||
// 全局管理器
|
||||
expect(scope.global).toBeInstanceOf(VoerkaI18nManager)
|
||||
})
|
||||
test("切换语言", () => {
|
||||
return new Promise<void>((resolve)=>{
|
||||
scope.on((language:string) => {
|
||||
expect(language).toBe("en")
|
||||
expect(scope.activeLanguage).toBe("en")
|
||||
expect(scope.defaultLanguage).toBe("zh")
|
||||
expect(scope.messages).toEqual(messages)
|
||||
expect(scope.default).toEqual(zhMessages)
|
||||
expect(scope.current).toEqual(enMessages)
|
||||
resolve()
|
||||
})
|
||||
scope.change("en")
|
||||
})
|
||||
})
|
||||
|
||||
test("切换到不存在的语言", async () => {
|
||||
try{
|
||||
await scope.change("xn")
|
||||
}catch(e){
|
||||
expect(e).toBeInstanceOf(InvalidLanguageError)
|
||||
}
|
||||
})
|
||||
test("指定了默认信息加载器时,切换到不存在的语言时从远程加载", async () => {
|
||||
scope.global.registerDefaultLoader(async function(newLanguage:string,curScope){
|
||||
expect(newLanguage).toBe("de")
|
||||
expect(curScope).toBe(scope)
|
||||
return {
|
||||
hello:"[DE]hello"
|
||||
}
|
||||
test("成功创建实例", () => {
|
||||
expect(scope).toBeInstanceOf(VoerkaI18nScope)
|
||||
expect(scope.activeLanguage).toBe("zh")
|
||||
expect(scope.defaultLanguage).toBe("zh")
|
||||
expect(scope.messages).toEqual(messages)
|
||||
expect(scope.default).toEqual(zhMessages)
|
||||
expect(scope.current).toEqual(zhMessages)
|
||||
// 全局管理器
|
||||
expect(scope.global).toBeInstanceOf(VoerkaI18nManager)
|
||||
})
|
||||
test("切换语言", () => {
|
||||
return new Promise<void>((resolve)=>{
|
||||
scope.on((language:string) => {
|
||||
expect(language).toBe("en")
|
||||
expect(scope.activeLanguage).toBe("en")
|
||||
expect(scope.defaultLanguage).toBe("zh")
|
||||
expect(scope.messages).toEqual(messages)
|
||||
expect(scope.default).toEqual(zhMessages)
|
||||
expect(scope.current).toEqual(enMessages)
|
||||
resolve()
|
||||
})
|
||||
await scope.change("de")
|
||||
expect((scope.current as any)['hello']).toEqual("[DE]hello")
|
||||
})
|
||||
scope.change("en")
|
||||
})
|
||||
})
|
||||
|
||||
test("全局切换语言", () => {
|
||||
return new Promise<void>((resolve)=>{
|
||||
let event = 0
|
||||
scope.on((language:string) => {
|
||||
expect(language).toBe("en")
|
||||
expect(scope.activeLanguage).toBe("en")
|
||||
expect(scope.defaultLanguage).toBe("zh")
|
||||
expect(scope.messages).toEqual(messages)
|
||||
test("切换到不存在的语言", async () => {
|
||||
try{
|
||||
await scope.change("xn")
|
||||
}catch(e){
|
||||
expect(e).toBeInstanceOf(InvalidLanguageError)
|
||||
}
|
||||
})
|
||||
test("指定了默认信息加载器时,切换到不存在的语言时从远程加载", async () => {
|
||||
scope.global.registerDefaultLoader(async function(newLanguage:string,curScope){
|
||||
expect(newLanguage).toBe("de")
|
||||
expect(curScope).toBe(scope)
|
||||
return {
|
||||
hello:"[DE]hello"
|
||||
}
|
||||
})
|
||||
await scope.change("de")
|
||||
expect((scope.current as any)['hello']).toEqual("[DE]hello")
|
||||
})
|
||||
|
||||
test("全局切换语言", () => {
|
||||
return new Promise<void>((resolve)=>{
|
||||
let event = 0
|
||||
scope.on((language:string) => {
|
||||
expect(language).toBe("en")
|
||||
expect(scope.activeLanguage).toBe("en")
|
||||
expect(scope.defaultLanguage).toBe("zh")
|
||||
expect(scope.messages).toEqual(messages)
|
||||
expect(scope.default).toEqual(zhMessages)
|
||||
expect(scope.current).toEqual(enMessages)
|
||||
expect(scope.idMap).toEqual(idMap)
|
||||
event++
|
||||
if(event==2) resolve()
|
||||
})
|
||||
@ -173,155 +87,6 @@ describe("所有测试", () => {
|
||||
})
|
||||
VoerkaI18n.change("en")
|
||||
})
|
||||
})
|
||||
|
||||
test("多个Scope", async () => {
|
||||
let scope1 = new VoerkaI18nScope({
|
||||
languages,
|
||||
idMap: {},
|
||||
messages: {},
|
||||
formatters: {},
|
||||
})
|
||||
let scope2 = new VoerkaI18nScope({
|
||||
languages,
|
||||
idMap: {},
|
||||
messages: {},
|
||||
formatters: {},
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
})
|
||||
|
||||
|
||||
})
|
||||
describe("格式化化配置与参数", () => {
|
||||
|
||||
test("格式化器参数", async () => {
|
||||
expect(scope.formatters).toBeInstanceOf(VoerkaI18nFormatterRegistry)
|
||||
expect(scope.formatters.activeLanguage).toBe("zh")
|
||||
expect(scope.formatters.formatters).toEqual(formatters)
|
||||
expect(scope.formatters.types).toBe(zhFormatters.$types)
|
||||
})
|
||||
|
||||
test("查找格式化器", async () => {
|
||||
expect(scope.formatters.get("first")).toBe(formatters.zh.first)
|
||||
await scope.change("en")
|
||||
expect(scope.formatters.get("first")).toBe(formatters.en.first)
|
||||
})
|
||||
test("合并后的格式化器配置", async () => {
|
||||
let fallbackLanguage = scope.getLanguage(scope.activeLanguage)?.fallback
|
||||
const globalFormatters = inlineFormatters
|
||||
let scopeConfig = mergeFormattersConfigs([
|
||||
(fallbackLanguage! in globalFormatters) ? (globalFormatters as any)?.[fallbackLanguage!].$config:{},
|
||||
globalFormatters.zh.$config,
|
||||
(fallbackLanguage! in formatters) ? (formatters as any)?.[fallbackLanguage!]?.$config:{},
|
||||
formatters.zh.$config
|
||||
])
|
||||
expect(scope.formatters.config).toEqual(scopeConfig)
|
||||
//
|
||||
await scope.change("en")
|
||||
fallbackLanguage = scope.getLanguage(scope.activeLanguage)?.fallback
|
||||
scopeConfig = mergeFormattersConfigs([
|
||||
(fallbackLanguage! in globalFormatters) ? (globalFormatters as any)?.[fallbackLanguage!].$config:{},
|
||||
globalFormatters.en.$config,
|
||||
(fallbackLanguage! in formatters) ? (formatters as any)?.[fallbackLanguage!]?.$config:{},
|
||||
formatters.en.$config
|
||||
])
|
||||
expect(scope.formatters.config).toEqual(scopeConfig)
|
||||
})
|
||||
})
|
||||
|
||||
describe('翻译函数', () => {
|
||||
let t:VoerkaI18nTranslate
|
||||
beforeAll(() => {
|
||||
t = scope.t
|
||||
})
|
||||
test('基本翻译',async () => {
|
||||
expect(t("你好")).toBe("你好")
|
||||
expect(t("我叫{name},今年{age}岁","张三",12)).toBe("我叫张三,今年12岁")
|
||||
expect(t("我叫{name},今年{age}岁",["张三",12])).toBe("我叫张三,今年12岁")
|
||||
expect(t("我叫{name},今年{age}岁",{name:"张三",age:12})).toBe("我叫张三,今年12岁")
|
||||
await scope.change("en")
|
||||
expect(t("你好")).toBe("hello")
|
||||
expect(t("我叫{name},今年{age}岁","tom",12)).toBe("My name is tom,Now 12 years old year")
|
||||
expect(t("我叫{name},今年{age}岁",["tom",12])).toBe("My name is tom,Now 12 years old year")
|
||||
expect(t("我叫{name},今年{age}岁",{name:"tom",age:12})).toBe("My name is tom,Now 12 years old year")
|
||||
expect(t("中国")).toBe("china")
|
||||
})
|
||||
test('基本复数翻译',async () => {
|
||||
expect(t("我有{}部车",0)).toBe("我没有车")
|
||||
expect(t("我有{}部车",1)).toBe("我有一部车")
|
||||
expect(t("我有{}部车",2)).toBe("我有两部车")
|
||||
expect(t("我有{}部车",3)).toBe("我有3部车")
|
||||
expect(t("我有{}部车",100)).toBe("我有100部车")
|
||||
await scope.change("en")
|
||||
expect(t("我有{}部车",0)).toBe("I don't have car")
|
||||
expect(t("我有{}部车",1)).toBe("I have a car")
|
||||
expect(t("我有{}部车",2)).toBe("I have two cars")
|
||||
expect(t("我有{}部车",3)).toBe("I have 3 cars")
|
||||
expect(t("我有{}部车",100)).toBe("I have 100 cars")
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
describe('插值变量格式化器', () => {
|
||||
let t:VoerkaI18nTranslate
|
||||
|
||||
|
||||
beforeAll(() => {
|
||||
t = scope.t
|
||||
// 注册格式化器,注册为所有语言
|
||||
scope.registerFormatter("add", (value,args,config) => {
|
||||
return String(Number(value) + (Number(args.length==0 ? 1 : args[0])))
|
||||
});
|
||||
scope.formatters.updateConfig("zh",{
|
||||
bookname:{
|
||||
beginChar:"《",
|
||||
endChar:"》"
|
||||
}
|
||||
});
|
||||
scope.formatters.updateConfig("en",{
|
||||
bookname:{
|
||||
beginChar:"<",
|
||||
endChar:">"
|
||||
}
|
||||
});
|
||||
// 注册格式化器,注册为所有语言
|
||||
scope.registerFormatter("bookname", (value,args,config) => {
|
||||
let { beginChar = "<",endChar=">" } = Object.assign({},(config as any)?.bookname)
|
||||
if(args.length==1){
|
||||
beginChar = endChar = args[0]
|
||||
}else if(args.length>=2){
|
||||
beginChar = args[0]
|
||||
endChar = args[1]
|
||||
}
|
||||
return beginChar + value + endChar
|
||||
})
|
||||
})
|
||||
test('格式化器',async () => {
|
||||
expect(t("我的工资是每月{|add}元",1000)).toBe("我的工资是每月1001元")
|
||||
expect(t("我的工资是每月{|add()}元",1000)).toBe("我的工资是每月1001元")
|
||||
expect(t("我的工资是每月{|add(2)}元",1000)).toBe("我的工资是每月1002元")
|
||||
expect(t("我的工资是每月{|add|add()|add(2)}元",1000)).toBe("我的工资是每月1004元")
|
||||
})
|
||||
test('bookname式化器',async () => {
|
||||
expect(t("hello {|bookname}","tom")).toBe("hello 《tom》")
|
||||
expect(t("hello {|bookname('#')}","tom")).toBe("hello #tom#")
|
||||
expect(t("hello {|bookname('#','!')}","tom")).toBe("hello #tom!")
|
||||
expect(t("hello {|bookname|bookname|bookname}","tom")).toBe("hello 《《《tom》》》")
|
||||
await scope.change("en")
|
||||
expect(t("hello {|bookname}","tom")).toBe("hello <tom>")
|
||||
})
|
||||
|
||||
test('空值格式化器',async () => {
|
||||
expect(t("hello {|bookname|empty('空')}",undefined)).toBe("hello 《空》")
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe('内置格式化器', () => {
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
})
|
5
packages/runtime/src/__tests__/inlineFormatters.test.ts
Normal file
5
packages/runtime/src/__tests__/inlineFormatters.test.ts
Normal file
@ -0,0 +1,5 @@
|
||||
/**
|
||||
* 内置格式化器的测试
|
||||
*/
|
||||
|
||||
|
58
packages/runtime/src/__tests__/translate.test.ts
Normal file
58
packages/runtime/src/__tests__/translate.test.ts
Normal file
@ -0,0 +1,58 @@
|
||||
/**
|
||||
* 基本翻译功能
|
||||
*/
|
||||
|
||||
|
||||
|
||||
import {test,vi,describe,expect,afterAll,beforeAll, beforeEach} from 'vitest'
|
||||
import { VoerkaI18nScope } from '../scope'
|
||||
import { VoerkaI18nManager } from '../manager';
|
||||
import { VoerkaI18nTranslate } from '../types';
|
||||
import { InvalidLanguageError } from '../errors';
|
||||
import { createI18nScope } from './utils';
|
||||
import { messages,zhMessages,enMessages } from './utils/testData';
|
||||
|
||||
let scope:VoerkaI18nScope;
|
||||
let t:VoerkaI18nTranslate
|
||||
|
||||
describe("翻译函数", () => {
|
||||
beforeAll(async ()=>{
|
||||
return new Promise((resolve)=>{
|
||||
scope = createI18nScope({
|
||||
ready:resolve
|
||||
})
|
||||
})
|
||||
})
|
||||
beforeEach(async ()=>{
|
||||
await scope.change("zh")
|
||||
t = scope.t
|
||||
})
|
||||
|
||||
test('基本翻译',async () => {
|
||||
expect(t("你好")).toBe("你好")
|
||||
expect(t("我叫{name},今年{age}岁","张三",12)).toBe("我叫张三,今年12岁")
|
||||
expect(t("我叫{name},今年{age}岁",["张三",12])).toBe("我叫张三,今年12岁")
|
||||
expect(t("我叫{name},今年{age}岁",{name:"张三",age:12})).toBe("我叫张三,今年12岁")
|
||||
await scope.change("en")
|
||||
expect(t("你好")).toBe("hello")
|
||||
expect(t("我叫{name},今年{age}岁","tom",12)).toBe("My name is tom,Now 12 years old year")
|
||||
expect(t("我叫{name},今年{age}岁",["tom",12])).toBe("My name is tom,Now 12 years old year")
|
||||
expect(t("我叫{name},今年{age}岁",{name:"tom",age:12})).toBe("My name is tom,Now 12 years old year")
|
||||
expect(t("中国")).toBe("china")
|
||||
})
|
||||
test('基本复数翻译',async () => {
|
||||
expect(t("我有{}部车",0)).toBe("我没有车")
|
||||
expect(t("我有{}部车",1)).toBe("我有一部车")
|
||||
expect(t("我有{}部车",2)).toBe("我有两部车")
|
||||
expect(t("我有{}部车",3)).toBe("我有3部车")
|
||||
expect(t("我有{}部车",100)).toBe("我有100部车")
|
||||
await scope.change("en")
|
||||
expect(t("我有{}部车",0)).toBe("I don't have car")
|
||||
expect(t("我有{}部车",1)).toBe("I have a car")
|
||||
expect(t("我有{}部车",2)).toBe("I have two cars")
|
||||
expect(t("我有{}部车",3)).toBe("I have 3 cars")
|
||||
expect(t("我有{}部车",100)).toBe("I have 100 cars")
|
||||
})
|
||||
|
||||
|
||||
})
|
31
packages/runtime/src/__tests__/utils/index.ts
Normal file
31
packages/runtime/src/__tests__/utils/index.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import { VoerkaI18nScope } from '../../scope'
|
||||
import { deepMerge } from 'flex-tools/object/deepMerge';
|
||||
import { isPlainObject } from 'flex-tools/typecheck/isPlainObject';
|
||||
import { assignObject } from 'flex-tools/object/assignObject';
|
||||
import {languages, messages,formatters} from './testData'
|
||||
|
||||
|
||||
export function mergeFormattersConfigs(configSources:any[]){
|
||||
return configSources.reduce((finalConfig, curConfig)=>{
|
||||
if(isPlainObject(curConfig)) deepMerge(finalConfig,curConfig,{newObject:false,array:'replace'})
|
||||
return finalConfig
|
||||
},{})
|
||||
}
|
||||
|
||||
|
||||
export interface CreateI18nScopeOptions{
|
||||
id?:string,
|
||||
ready?:Function
|
||||
}
|
||||
export function createI18nScope(options?:CreateI18nScopeOptions){
|
||||
const {id,ready} = assignObject({
|
||||
id:"test",
|
||||
},options)
|
||||
return new VoerkaI18nScope({
|
||||
id,
|
||||
languages,
|
||||
messages,
|
||||
formatters,
|
||||
ready
|
||||
})
|
||||
}
|
71
packages/runtime/src/__tests__/utils/testData.ts
Normal file
71
packages/runtime/src/__tests__/utils/testData.ts
Normal file
@ -0,0 +1,71 @@
|
||||
|
||||
import zhFormatters from '../../formatters/zh';
|
||||
import enFormatters from '../../formatters/en';
|
||||
import { VoerkaI18nManager } from '../../manager';
|
||||
import { VoerkaI18nFormatterRegistry } from '../../formatterRegistry';
|
||||
import { VoerkaI18nLanguageMessages, VoerkaI18nFormatterConfigs, VoerkaI18nTranslate } from '../../types';
|
||||
|
||||
export const zhMessages:VoerkaI18nLanguageMessages = {
|
||||
$config:{
|
||||
add:{a:1},
|
||||
dec:{b:1}
|
||||
},
|
||||
"你好": "你好",
|
||||
"我叫{name},今年{age}岁": "我叫{name},今年{age}岁",
|
||||
"中国": "中国",
|
||||
"我有{}部车": ["我没有车","我有一部车","我有两部车","我有{}部车"] ,
|
||||
"我的工资是每月{}元":"我的工资是每月{}元"
|
||||
}
|
||||
export const enMessages={
|
||||
"你好": "hello",
|
||||
"我叫{name},今年{age}岁": "My name is {name},Now {age} years old year",
|
||||
"中国": "china",
|
||||
"我有{}部车": ["I don't have car","I have a car","I have two cars","I have {} cars"],
|
||||
"我的工资是每月{}元":"My salary is {} yuan per month"
|
||||
}
|
||||
|
||||
export const messages = {
|
||||
zh: zhMessages,
|
||||
en: enMessages
|
||||
}
|
||||
|
||||
export const idMap={
|
||||
"你好":1,
|
||||
"你好,{name}":2,
|
||||
"中国":3,
|
||||
"我有{}部车":4
|
||||
}
|
||||
export const languages = [
|
||||
{ name: "zh",default:true,active:true},
|
||||
{ name: "en"}
|
||||
]
|
||||
|
||||
Object.assign(zhFormatters.$config,{
|
||||
x:{x1:1,x2:2},
|
||||
y:{y1:1,y2:2}
|
||||
})
|
||||
Object.assign(enFormatters.$config,{
|
||||
x:{x1:11,x2:22},
|
||||
y:{y1:11,y2:22},
|
||||
z:{z1:11,z2:22}
|
||||
})
|
||||
|
||||
export const formatters ={
|
||||
"*":{
|
||||
$config:{
|
||||
x:{g:1},
|
||||
y:{g:1},
|
||||
g:{g1:1,g2:2}
|
||||
}
|
||||
},
|
||||
zh:{
|
||||
$config:{},
|
||||
prefix:(value:any,args:any[],config?:VoerkaI18nFormatterConfigs)=>config?.chars+value,
|
||||
first:(value:any)=>'ZH'+value[0],
|
||||
},
|
||||
en:{
|
||||
$config:{},
|
||||
first:(value:any)=>'EN'+value[0],
|
||||
},
|
||||
jp:()=>{}
|
||||
}
|
@ -17,7 +17,6 @@ import type {
|
||||
VoerkaI18nMessageLoader,
|
||||
} from "./types"
|
||||
import { VoerkaI18nFormatterRegistry } from './formatterRegistry';
|
||||
import { InvalidLanguageError } from "./errors"
|
||||
import { randomId } from "./utils"
|
||||
import { DefaultLanguageSettings, DefaultFallbackLanguage } from './consts';
|
||||
|
||||
@ -30,7 +29,7 @@ export interface VoerkaI18nScopeOptions {
|
||||
messages: VoerkaI18nLanguageMessagePack // 当前语言包
|
||||
idMap?: Voerkai18nIdMap // 消息id映射列表
|
||||
formatters: VoerkaI18nLanguageFormatters // 当前作用域的格式化函数列表{<lang>: {$types,$config,[格式化器名称]: () => {},[格式化器名称]: () => {}}}
|
||||
callback?:(e?:Error)=>void // 当注册到全局管理器后的回调函数
|
||||
ready?:(e?:Error)=>void // 当注册到全局管理器并切换到语言后的回调函数
|
||||
}
|
||||
|
||||
export class VoerkaI18nScope {
|
||||
@ -140,8 +139,8 @@ export class VoerkaI18nScope {
|
||||
* 当注册到Manager后,执行注册后的操作
|
||||
*/
|
||||
private onRegisterSuccess(){
|
||||
if(typeof(this.#options.callback)=='function'){
|
||||
this.#options.callback.call(this)
|
||||
if(typeof(this.#options.ready)=='function'){
|
||||
this.#options.ready.call(this)
|
||||
}
|
||||
// 从本地缓存中读取并合并补丁语言包
|
||||
this._mergePatchedMessages();
|
||||
@ -152,8 +151,8 @@ export class VoerkaI18nScope {
|
||||
* 当注册到Manager失败时,执行注册失败后的操作
|
||||
*/
|
||||
private onRegisterFail(e:any){
|
||||
if(typeof(this.#options.callback)=='function'){
|
||||
this.#options.callback.call(this,e)
|
||||
if(typeof(this.#options.ready)=='function'){
|
||||
this.#options.ready.call(this,e)
|
||||
}
|
||||
}
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user