Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangfisher committed Jan 2, 2025
1 parent ebcaeb7 commit 8f7cc04
Show file tree
Hide file tree
Showing 11 changed files with 257 additions and 103 deletions.
25 changes: 25 additions & 0 deletions packages/runtime/src/__tests__/_utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { VoerkaI18nLanguageLoader } from '@/types'
import { VoerkaI18nScope, VoerkaI18nScopeOptions } from '../scope'
import { VoerkaI18nManager } from "@/manager"

Expand Down Expand Up @@ -26,10 +27,34 @@ export function createVoerkaI18nScope(opts?:Partial<VoerkaI18nScopeOptions>): Vo

export function resetVoerkaI18n() {
try{

if(globalThis.VoerkaI18n){
globalThis.VoerkaI18n.clearLanguage()
}

// @ts-ignore
delete globalThis.__VoerkaI18nScopes__
// @ts-ignore
delete globalThis.VoerkaI18n
VoerkaI18nManager.instance = undefined

}catch{}
}


export function getTestStorage(init?:string){
let saveLanguage:string | undefined= init
return {
get() { return saveLanguage},
set(_:string,value:string){saveLanguage = value},
remove(){ saveLanguage = undefined }
}

}


export function getTestLanguageLoader(patchMsgs?:Record<string,any>):VoerkaI18nLanguageLoader{
return async (language:string,scope:VoerkaI18nScope)=>{
return Object.assign({},patchMsgs)
}
}
13 changes: 11 additions & 2 deletions packages/runtime/src/__tests__/change.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@



import { test, vi, describe, expect, beforeEach } from 'vitest'
import { test, describe, expect, beforeEach } from 'vitest'
import { createVoerkaI18nScope, resetVoerkaI18n } from './_utils';

describe('语言切换', () => {
Expand Down Expand Up @@ -117,7 +117,7 @@ describe('语言切换', () => {
expect(appScope.activeLanguage).toBe("en")
expect(appScope.activeMessages).toEqual({ message: 'Hello' })
expect(detachedScope.activeLanguage).toBe("zh")
expect(detachedScope.activeMessages).toEqual({ message: 'Hello' })
expect(detachedScope.activeMessages).toEqual({ message: '你好' })
})

test("独立切换detachedScope语言",async ()=>{
Expand All @@ -130,6 +130,15 @@ describe('语言切换', () => {
expect(detachedScope.activeMessages).toEqual({ message: 'Hello' })

})

test("切换到不存在的语言时进行回退",async ()=>{
const appScope = createVoerkaI18nScope({ id: "a" });
await appScope.change("de")
// 回退到defaultLanguage
expect(appScope.activeLanguage).toBe("zh")
expect(appScope.activeMessages).toEqual({ message: 'Hello' })

})
});


34 changes: 34 additions & 0 deletions packages/runtime/src/__tests__/patch.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
*
* 语言补丁
*
* 语言补丁功能需要配置LnaguageLoader
*
*
*/



import { test, vi, describe, expect, beforeEach } from 'vitest'
import { VoerkaI18nScope } from '../scope'
import { VoerkaI18nManager } from '../manager';
import { createVoerkaI18nScope, getTestLanguageLoader, getTestStorage, resetVoerkaI18n } from './_utils';
import { VoerkaI18nOnlyOneAppScopeError } from '@/errors';
import { VoerkaI18nLanguageLoader } from '@/types';


describe('语言包补丁功能', () => {
beforeEach(() => {
resetVoerkaI18n()
});
test('appScope加载时加载补丁', async () => {
const storage = getTestStorage()
const languageLoader = getTestLanguageLoader()

const appScope = createVoerkaI18nScope({
storage
})
});
});


68 changes: 68 additions & 0 deletions packages/runtime/src/__tests__/save.restore.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@


import { test, vi, describe, expect, beforeEach } from 'vitest'
import { createVoerkaI18nScope, getTestStorage, resetVoerkaI18n } from './_utils';



describe('保存与恢复语言', () => {
beforeEach(() => {
resetVoerkaI18n()
});
test('保存与恢复语言配置到存储', async () => {
const storage = getTestStorage()
const scope = createVoerkaI18nScope({storage});
expect(storage.get()).toBe(undefined);
await scope.change('en')
expect(storage.get()).toBe('en');
await scope.change('zh')
expect(storage.get()).toBe('zh');
});
test('从存储中恢复语言', async () => {
const storage = getTestStorage('en')
const scope = createVoerkaI18nScope({storage});
await scope.refreshing()
expect(scope.activeLanguage).toBe('en');
expect(scope.activeMessages).toEqual({ message: 'Hello' });
});
test('多个scope从存储中恢复语言', async () => {
const storage = getTestStorage('en')
const libScope1 = createVoerkaI18nScope({id:"a", library:true});
const libScope2 = createVoerkaI18nScope({id:"b", library:true});
const libScope3 = createVoerkaI18nScope({id:"c", library:true});
const appScope = createVoerkaI18nScope({id:"app",storage});
await appScope.refreshing()
await libScope1.refreshing()
await libScope2.refreshing()
await libScope3.refreshing()
expect(appScope.activeLanguage).toBe('en');
expect(appScope.activeMessages).toEqual({ message: 'Hello' });
expect(libScope1.activeLanguage).toBe('en');
expect(libScope1.activeMessages).toEqual({ message: 'Hello' });
expect(libScope2.activeLanguage).toBe('en');
expect(libScope2.activeMessages).toEqual({ message: 'Hello' });
expect(libScope3.activeLanguage).toBe('en');
expect(libScope3.activeMessages).toEqual({ message: 'Hello' });
});
test('多个libScope在appScope后面注册时从存储中恢复语言', async () => {
const storage = getTestStorage('en')
const appScope = createVoerkaI18nScope({id:"app",storage});
await appScope.refreshing()
const libScope1 = createVoerkaI18nScope({id:"a", library:true});
const libScope2 = createVoerkaI18nScope({id:"b", library:true});
const libScope3 = createVoerkaI18nScope({id:"c", library:true});
await libScope1.refreshing()
await libScope2.refreshing()
await libScope3.refreshing()
expect(appScope.activeLanguage).toBe('en');
expect(appScope.activeMessages).toEqual({ message: 'Hello' });
expect(libScope1.activeLanguage).toBe('en');
expect(libScope1.activeMessages).toEqual({ message: 'Hello' });
expect(libScope2.activeLanguage).toBe('en');
expect(libScope2.activeMessages).toEqual({ message: 'Hello' });
expect(libScope3.activeLanguage).toBe('en');
expect(libScope3.activeMessages).toEqual({ message: 'Hello' });
});
});


11 changes: 4 additions & 7 deletions packages/runtime/src/__tests__/scope.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import { createVoerkaI18nScope, resetVoerkaI18n } from './_utils';
import { VoerkaI18nOnlyOneAppScopeError } from '@/errors';


describe('VoerkaI18nScope', () => {
describe('创建VoerkaI18nScope实例', () => {
describe('创建VoerkaI18nScope实例', () => {
beforeEach(() => {
resetVoerkaI18n()
});
Expand All @@ -34,22 +33,20 @@ describe('VoerkaI18nScope', () => {
}
});

test('创建多个VoerkaI18nScope实例', () => {
test('先创建appScope再创建多个VoerkaI18nScope实例', () => {
createVoerkaI18nScope({ id: "a" });
createVoerkaI18nScope({ id: "b", library: true });
createVoerkaI18nScope({ id: "c", library: true });
createVoerkaI18nScope({ id: "d", library: true });
expect(globalThis.VoerkaI18n.scopes.length).toBe(4);
})
test('延后创建多个VoerkaI18nScope实例', () => {
test('先创建多个VoerkaI18nScope实例再创建appScope', () => {
createVoerkaI18nScope({ id: "b", library: true });
createVoerkaI18nScope({ id: "c", library: true });
createVoerkaI18nScope({ id: "d", library: true });
createVoerkaI18nScope({ id: "a" });
expect(globalThis.VoerkaI18n.scopes.length).toBe(4);
})

})
})
});


48 changes: 15 additions & 33 deletions packages/runtime/src/manager/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { isFunction } from "flex-tools/typecheck/isFunction"
import type { VoerkaI18nScope } from "../scope"
import type { VoerkaI18nLanguageDefine, VoerkaI18nMessageLoader, VoerkaI18nEvents, IVoerkaI18nStorage } from "../types"
import type { VoerkaI18nLanguageDefine, VoerkaI18nLanguageLoader, VoerkaI18nEvents, IVoerkaI18nStorage } from "../types"
import { VoerkaI18nInvalidLanguageError } from '../errors';
import { LiteEvent } from "flex-tools/events/liteEvent"
import { execAsyncs, isI18nScope, isStorage } from "../utils"
Expand All @@ -26,7 +26,6 @@ export class VoerkaI18nManager extends LiteEvent<VoerkaI18nEvents>{
static instance? : VoerkaI18nManager
private _scopes : VoerkaI18nScope[] = []
private _appScope! : VoerkaI18nScope
private _activeLanguage : string = 'zh'

constructor(appScope:VoerkaI18nScope){
super()
Expand All @@ -43,7 +42,7 @@ export class VoerkaI18nManager extends LiteEvent<VoerkaI18nEvents>{
get logger(){ return this.scope.logger! } // 日志记录器
get scopes(){ return this._scopes } // 注册VoerkaI18nScope实例
get activeLanguage(){ return this._appScope.activeLanguage } // 当前激活语言名称
get messageLoader(){ return this._appScope.messageLoader} // 默认语言包加载器
get languageLoader(){ return this._appScope.languageLoader} // 默认语言包加载器
get storage(){return this.scope!.storage}
get languages(){return this.scope.languages}
get scope(){return this._appScope!}
Expand All @@ -70,8 +69,6 @@ export class VoerkaI18nManager extends LiteEvent<VoerkaI18nEvents>{
private _registerAppScope(scope:VoerkaI18nScope){
this._scopes.push(scope)
this._appScope = scope
this._activeLanguage = scope.activeLanguage
this._getLanguageFromStorage() // 从存储器加载语言包配置
this.logger.debug("注册应用I18nScope: "+scope.id)
this.emitAsync("init",undefined,true)
.then(()=>this.emitAsync("ready",this.activeLanguage,true))
Expand All @@ -90,38 +87,14 @@ export class VoerkaI18nManager extends LiteEvent<VoerkaI18nEvents>{
this._scopes.push(scope)
scope.bind(this)
this.logger.debug(`VoerkaI18nScope<${scope.id}>已注册`)
}
private _getStorage():IVoerkaI18nStorage | undefined{
const storage = this.scope.storage
return isStorage(storage) ? storage: undefined
}
/**
* 从存储器加载语言包配置
*/
private _getLanguageFromStorage(){
const storage = this._getStorage()
if(storage){
const savedLanguage = storage.get("language")
if(!savedLanguage || !this.hasLanguage(savedLanguage)) return
this._activeLanguage = savedLanguage
this.logger.debug("从存储中读取到当前语言:",savedLanguage)
}
}
private _setLanguageToStorage(){
const storage = this._getStorage()
if(storage){
if(!this._activeLanguage) return
storage.set("language",this.activeLanguage)
this.logger.debug("当前语言设置已保存到存储:",this.activeLanguage)
}
}
}
/**
* 切换语言
*/
async change(language:string){
if(this.hasLanguage(language) || isFunction(this.messageLoader)){
await this._refreshScopes(language) // 刷新所有作用域
this._setLanguageToStorage() // 保存语言配置到存储器
if(this.hasLanguage(language) || isFunction(this.languageLoader)){
await this._refreshScopes(language) // 刷新所有作用域
this.scope.saveLanguage() // 保存语言配置到存储器
this.emit("change",language,true)
this.logger.info("语言已切换为:"+ language)
return language
Expand Down Expand Up @@ -164,6 +137,15 @@ export class VoerkaI18nManager extends LiteEvent<VoerkaI18nEvents>{
hasLanguage(language:string) {
return this.languages.findIndex((lang:VoerkaI18nLanguageDefine) => lang.name == language) != -1;
}
clearLanguage(){
this.scope.clearLanguage()
}
saveLanguage(){
this.scope.saveLanguage()
}
restoreLanguage(){
this.scope.restoreLanguage()
}

}

Loading

0 comments on commit 8f7cc04

Please sign in to comment.