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('内置格式化器', () => {
|
||||||
|
|
||||||
|
})
|
@ -2,110 +2,25 @@
|
|||||||
|
|
||||||
import {test,vi,describe,expect,afterAll,beforeAll, beforeEach} from 'vitest'
|
import {test,vi,describe,expect,afterAll,beforeAll, beforeEach} from 'vitest'
|
||||||
import { VoerkaI18nScope } from '../scope'
|
import { VoerkaI18nScope } from '../scope'
|
||||||
import zhFormatters from '../formatters/zh';
|
|
||||||
import enFormatters from '../formatters/en';
|
|
||||||
import { VoerkaI18nManager } from '../manager';
|
import { VoerkaI18nManager } from '../manager';
|
||||||
import { VoerkaI18nFormatterRegistry } from '../formatterRegistry';
|
import { VoerkaI18nTranslate } from '../types';
|
||||||
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 { InvalidLanguageError } from '../errors';
|
import { InvalidLanguageError } from '../errors';
|
||||||
|
import { createI18nScope } from './utils';
|
||||||
function mergeFormattersConfigs(configSources:any[]){
|
import { messages,zhMessages,enMessages } from './utils/testData';
|
||||||
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:()=>{}
|
|
||||||
}
|
|
||||||
|
|
||||||
let scope:VoerkaI18nScope;
|
let scope:VoerkaI18nScope;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
describe("所有测试", () => {
|
describe("所有测试", () => {
|
||||||
beforeAll(async ()=>{
|
beforeAll(async ()=>{
|
||||||
return new Promise((resolve)=>{
|
return new Promise((resolve)=>{
|
||||||
scope = new VoerkaI18nScope({
|
scope = createI18nScope({
|
||||||
id: "test",
|
ready:resolve
|
||||||
languages,
|
|
||||||
messages,
|
|
||||||
formatters,
|
|
||||||
callback:()=>{
|
|
||||||
resolve()
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
beforeEach(async ()=>{
|
beforeEach(async ()=>{
|
||||||
await scope.change("zh")
|
await scope.change("zh")
|
||||||
})
|
})
|
||||||
describe("VoerkaI18nScope", () => {
|
|
||||||
test("成功创建实例", () => {
|
test("成功创建实例", () => {
|
||||||
expect(scope).toBeInstanceOf(VoerkaI18nScope)
|
expect(scope).toBeInstanceOf(VoerkaI18nScope)
|
||||||
expect(scope.activeLanguage).toBe("zh")
|
expect(scope.activeLanguage).toBe("zh")
|
||||||
@ -160,7 +75,6 @@ describe("所有测试", () => {
|
|||||||
expect(scope.messages).toEqual(messages)
|
expect(scope.messages).toEqual(messages)
|
||||||
expect(scope.default).toEqual(zhMessages)
|
expect(scope.default).toEqual(zhMessages)
|
||||||
expect(scope.current).toEqual(enMessages)
|
expect(scope.current).toEqual(enMessages)
|
||||||
expect(scope.idMap).toEqual(idMap)
|
|
||||||
event++
|
event++
|
||||||
if(event==2) resolve()
|
if(event==2) resolve()
|
||||||
})
|
})
|
||||||
@ -175,153 +89,4 @@ describe("所有测试", () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
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,
|
VoerkaI18nMessageLoader,
|
||||||
} from "./types"
|
} from "./types"
|
||||||
import { VoerkaI18nFormatterRegistry } from './formatterRegistry';
|
import { VoerkaI18nFormatterRegistry } from './formatterRegistry';
|
||||||
import { InvalidLanguageError } from "./errors"
|
|
||||||
import { randomId } from "./utils"
|
import { randomId } from "./utils"
|
||||||
import { DefaultLanguageSettings, DefaultFallbackLanguage } from './consts';
|
import { DefaultLanguageSettings, DefaultFallbackLanguage } from './consts';
|
||||||
|
|
||||||
@ -30,7 +29,7 @@ export interface VoerkaI18nScopeOptions {
|
|||||||
messages: VoerkaI18nLanguageMessagePack // 当前语言包
|
messages: VoerkaI18nLanguageMessagePack // 当前语言包
|
||||||
idMap?: Voerkai18nIdMap // 消息id映射列表
|
idMap?: Voerkai18nIdMap // 消息id映射列表
|
||||||
formatters: VoerkaI18nLanguageFormatters // 当前作用域的格式化函数列表{<lang>: {$types,$config,[格式化器名称]: () => {},[格式化器名称]: () => {}}}
|
formatters: VoerkaI18nLanguageFormatters // 当前作用域的格式化函数列表{<lang>: {$types,$config,[格式化器名称]: () => {},[格式化器名称]: () => {}}}
|
||||||
callback?:(e?:Error)=>void // 当注册到全局管理器后的回调函数
|
ready?:(e?:Error)=>void // 当注册到全局管理器并切换到语言后的回调函数
|
||||||
}
|
}
|
||||||
|
|
||||||
export class VoerkaI18nScope {
|
export class VoerkaI18nScope {
|
||||||
@ -140,8 +139,8 @@ export class VoerkaI18nScope {
|
|||||||
* 当注册到Manager后,执行注册后的操作
|
* 当注册到Manager后,执行注册后的操作
|
||||||
*/
|
*/
|
||||||
private onRegisterSuccess(){
|
private onRegisterSuccess(){
|
||||||
if(typeof(this.#options.callback)=='function'){
|
if(typeof(this.#options.ready)=='function'){
|
||||||
this.#options.callback.call(this)
|
this.#options.ready.call(this)
|
||||||
}
|
}
|
||||||
// 从本地缓存中读取并合并补丁语言包
|
// 从本地缓存中读取并合并补丁语言包
|
||||||
this._mergePatchedMessages();
|
this._mergePatchedMessages();
|
||||||
@ -152,8 +151,8 @@ export class VoerkaI18nScope {
|
|||||||
* 当注册到Manager失败时,执行注册失败后的操作
|
* 当注册到Manager失败时,执行注册失败后的操作
|
||||||
*/
|
*/
|
||||||
private onRegisterFail(e:any){
|
private onRegisterFail(e:any){
|
||||||
if(typeof(this.#options.callback)=='function'){
|
if(typeof(this.#options.ready)=='function'){
|
||||||
this.#options.callback.call(this,e)
|
this.#options.ready.call(this,e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user