From 94b4cac2cbdd5cef965e81227beb9055021bc3c8 Mon Sep 17 00:00:00 2001 From: juck Date: Wed, 8 Mar 2023 19:47:54 +0800 Subject: [PATCH] fix: Missing i18n partial translation prevents startup --- package.json | 1 + pnpm-lock.yaml | 2 ++ src/__test__/i18n.spec.ts | 27 ++++++++++++++++ src/__test__/utils/common.spec.ts | 53 +++++++++++++++++++++++++++++++ src/i18n.ts | 5 ++- src/locale/en.ts | 8 +++++ src/locale/zh-cn.ts | 5 +++ src/utils/common.ts | 21 ++++++++++++ vite.config.ts | 5 +++ vitest.config.ts | 7 ++++ 10 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 src/__test__/i18n.spec.ts create mode 100644 src/__test__/utils/common.spec.ts create mode 100644 vitest.config.ts diff --git a/package.json b/package.json index 045f36b..7ce08fa 100644 --- a/package.json +++ b/package.json @@ -147,6 +147,7 @@ "cursor-effects": "^1.0.8", "emoji-mart": "^5.5.2", "jsonfile": "^6.1.0", + "lodash": "^4.17.21", "naive-ui": "^2.34.3", "ora": "^6.1.2", "party-js": "^2.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 00bf099..b143237 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -55,6 +55,7 @@ specifiers: jsdom: ^21.1.0 jsonfile: ^6.1.0 lint-staged: ^13.0.3 + lodash: ^4.17.21 naive-ui: ^2.34.3 npm-run-all: ^4.1.5 obsidian: ^1.1.1 @@ -100,6 +101,7 @@ dependencies: cursor-effects: 1.0.11 emoji-mart: 5.5.2 jsonfile: 6.1.0 + lodash: 4.17.21 naive-ui: 2.34.3_vue@3.2.47 ora: 6.1.2 party-js: 2.2.0 diff --git a/src/__test__/i18n.spec.ts b/src/__test__/i18n.spec.ts new file mode 100644 index 0000000..d85d047 --- /dev/null +++ b/src/__test__/i18n.spec.ts @@ -0,0 +1,27 @@ +import { beforeAll, describe, expect, it } from 'vitest'; +import chalk from 'chalk'; + +import enPack from '../locale/en'; +import zhPack from '../locale/zh-cn'; + +let languagePack; +describe('i18n', () => { + beforeAll(() => { + localStorage.setItem('language', 'zh'); + }); + it('localstorage work fine', () => { + expect(localStorage.getItem('name')).null; + localStorage.setItem('name', 'awesome'); + expect(localStorage.getItem('name')).eq('awesome'); + }); + + it('should return selected lang', async () => { + languagePack = (await import('../i18n')).default; + console.log(languagePack); + expect(languagePack['__FOR_TEST'].exist.child).eq(zhPack['__FOR_TEST'].exist.child); + }); + + it('should return default lang', () => { + expect(languagePack['__FOR_TEST'].notExist.child).eq(enPack['__FOR_TEST'].notExist.child); + }); +}); diff --git a/src/__test__/utils/common.spec.ts b/src/__test__/utils/common.spec.ts new file mode 100644 index 0000000..00a6272 --- /dev/null +++ b/src/__test__/utils/common.spec.ts @@ -0,0 +1,53 @@ +import { describe, expect, it } from 'vitest'; +import { deepClone, deepCloneArr, deepCloneObj } from '../../utils/common'; + +const obj1 = { + name: 'John', + age: 30, + address: { + city: 'New York', + state: 'NY', + }, + skills: [ + 'js', + 'ts', + 'py', + () => { + console.log(111); + }, + ], +}; +const arr1 = [ + { name: 'John', age: 30 }, + { name: 'Mary', age: 25 }, + { + name: 'Bob', + age: 40, + skill() { + console.log('js'); + }, + }, + { + others: [ + { name: 'Mary', age: 25 }, + { name: 'Bob', age: 40 }, + ], + }, +]; + +describe('common utils', () => { + it('placeholder', () => { + expect(1 + 1).toBe(2); + }); + // it('clone object[]', () => { + // const arr2 = deepCloneArr(arr1); + // expect(arr1).not.toBe(arr2); + // expect(arr1).toEqual(arr2); + // }); + + // it('clone object', async () => { + // const obj2 = deepCloneObj(obj1); + // expect(obj1).not.toBe(obj2); + // expect(obj1).toEqual(obj2); + // }); +}); diff --git a/src/i18n.ts b/src/i18n.ts index 76d1e2e..f17e1d4 100644 --- a/src/i18n.ts +++ b/src/i18n.ts @@ -1,3 +1,4 @@ +import { merge } from 'lodash'; import en from './locale/en'; import zh from './locale/zh-cn'; class T { @@ -13,7 +14,9 @@ class T { } get texts(): typeof this.all.en { - return this.all[this.lang]; + const selectLangPack = this.all[this.lang]; + const defaultLangPack = this.all['en']; + return merge(defaultLangPack, selectLangPack); } } diff --git a/src/locale/en.ts b/src/locale/en.ts index 86f1a40..428beff 100644 --- a/src/locale/en.ts +++ b/src/locale/en.ts @@ -1,4 +1,12 @@ export default { + __FOR_TEST: { + notExist: { + child: 'This is child', + }, + exist: { + child: 'This is child', + }, + }, menu: { setBannerForCurrent: 'Set Random Banner For Current File', setBannerForTheFolder: 'Set random banner for this path', diff --git a/src/locale/zh-cn.ts b/src/locale/zh-cn.ts index 7780496..f3d30dc 100644 --- a/src/locale/zh-cn.ts +++ b/src/locale/zh-cn.ts @@ -1,4 +1,9 @@ export default { + __FOR_TEST: { + exist: { + child: '我是中文包', + }, + }, menu: { setBannerForCurrent: '切换当前文件banner图', setBannerForTheFolder: '切换当前路径下文件的banner图', diff --git a/src/utils/common.ts b/src/utils/common.ts index 33a5948..bc8387a 100644 --- a/src/utils/common.ts +++ b/src/utils/common.ts @@ -19,3 +19,24 @@ export function getNumberFromStr(str: string) { const nums = str.match(/\d+(.\d+)?/g); return nums?.map(num => parseFloat(num)) || []; } + +export function deepCloneObj(source) { + // TODO + // const target = {}; + // for (const key in source) { + // if (typeof source[key] === 'object' && source[key] !== null) { + // target[key] = deepClone(source[key]); + // } else { + // target[key] = source[key]; + // } + // } + // return target; +} + +export function deepCloneArr(source) { + // TODO +} + +export function deepClone(source) { + // TODO +} diff --git a/vite.config.ts b/vite.config.ts index 4f2b231..26a1257 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -53,6 +53,10 @@ export default defineConfig({ } return assetInfo.name || ''; }, + // // 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量 + globals: { + // vue: 'Vue', + }, }, external: [ 'obsidian', @@ -108,4 +112,5 @@ export default defineConfig({ }, ], }, + logLevel: 'info', }); diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..1c9a076 --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + environment: 'jsdom', + }, +});