From 9fcff0c9d86d1a0fe212b9abe8a3e9453d6d6ae3 Mon Sep 17 00:00:00 2001 From: haonan <214611026@qq.com> Date: Fri, 27 Aug 2021 10:59:33 +0800 Subject: [PATCH] dict --- src/tests/useTranslation.test.tsx | 66 +++++++++++++++++++++++++++++++ src/useTranslation.ts | 10 +++-- 2 files changed, 72 insertions(+), 4 deletions(-) diff --git a/src/tests/useTranslation.test.tsx b/src/tests/useTranslation.test.tsx index 5d4b939..308dddb 100644 --- a/src/tests/useTranslation.test.tsx +++ b/src/tests/useTranslation.test.tsx @@ -1,3 +1,4 @@ +import "react"; import {renderHook} from "@testing-library/react-hooks/native"; import {FC} from "react"; import React = require("react"); @@ -15,6 +16,13 @@ const settings: TranslationSettings = { only: { english: "Hello", }, + categories: { + "default": "Categories", + "category1": "Category 1", + "category2": "Category 2", + "category3": "Category 3", + "category4": "Category 4" + } }, [Language.Chinese]: { people: "{{people}}个人", @@ -25,6 +33,13 @@ const settings: TranslationSettings = { nested: { property: "I am nested", }, + categories: { + "default": "分类", + "category1": "分类 1", + "category2": "分类 2", + "category3": "分类 3", + "category4": "分类 4" + } }, [Language.Russian]: { cool: "Крутой", @@ -32,6 +47,13 @@ const settings: TranslationSettings = { people_1: "Человек", people_2: "Людей", people_3: "Людей", + categories: { + "default": "Категория", + "category1": "Категория 1", + "category2": "Категория 2", + "category3": "Категория 3", + "category4": "Категория 4" + } }, }, language: Language.Chinese, @@ -99,3 +121,47 @@ test("should support templates", () => { const {t, language} = result.current; expect(t("people", {people: 2})).toBe("2个人"); }); + + +describe("dict", () => { + test("默认 mapper 下,dict 通过路径,拿到这个路径下的所有 key,不包括 default", () => { + const {result} = renderHook(() => useTranslation(), {wrapper: ContextMockWrapper}); + const {t, language, dict} = result.current; + expect(dict("categories")).toEqual(["category1", "category2", "category3", "category4"]); + }); + + describe("mapper", () => { + test("path 是完整路径", () => { + const {result} = renderHook(() => useTranslation(), {wrapper: ContextMockWrapper}); + const {t, language, dict} = result.current; + dict("categories", (key, path) => { + expect(path).toEqual("categories." + key); + return key; + }); + }); + + test("映射出来的 path,全都正确", () => { + const {result} = renderHook(() => useTranslation(), {wrapper: ContextMockWrapper}); + const {t, language, dict} = result.current; + expect(dict("categories", (_key, path) => path)).toEqual(["categories.category1", "categories.category2", "categories.category3", "categories.category4"]) + }); + + test("映射出来的 path,全都正确", () => { + const {result} = renderHook(() => useTranslation(), {wrapper: ContextMockWrapper}); + const {t, language, dict} = result.current; + expect(dict("categories", (_key, path) => path)).toEqual(["categories.category1", "categories.category2", "categories.category3", "categories.category4"]) + }); + + test("映射出 key val", () => { + const {result} = renderHook(() => useTranslation(), {wrapper: ContextMockWrapper}); + const {t, language, dict} = result.current; + expect(dict("categories", (_key, path) => t(path))).toEqual(["分类 1", "分类 2", "分类 3", "分类 4"]) + }); + + test("切换成英文", () => { + const {result} = renderHook(() => useTranslation(), {wrapper: ContextMockWrapper}); + const {t, language, dict} = result.current; + expect(dict("categories", (_key, path) => t(path, undefined, Language.English))).toEqual(["Category 1", "Category 2", "Category 3", "Category 4"]) + }); + }); +}); diff --git a/src/useTranslation.ts b/src/useTranslation.ts index a66a969..ee34df5 100644 --- a/src/useTranslation.ts +++ b/src/useTranslation.ts @@ -98,10 +98,12 @@ export const generateTranslationFunction = (translations: TranslationMap, langua }; }; -export const generateDictFunction = (translationMap: TranslationMap) => { +export const generateDictFunction = (translationMap: TranslationMap, language: Language, fallbackLanguage: Language) => { const ramdaPath = path; - return (path: string, mapper: (key: string, path: string) => string = key => key) => { - const subMap = ramdaPath(path.split("."), translationMap) as Record; + return (path: string, mapper: (key: string, path: string) => string = key => key, enforceLanguage?: Language) => { + const finalLanguage = enforceLanguage ?? language ?? fallbackLanguage + + const subMap = ramdaPath([finalLanguage as string].concat(path.split(".")), translationMap) as Record; if (Object.prototype.toString.call(subMap) !== "[object Object]") return []; return Object.keys(subMap).reduce((acc, key) => { @@ -118,7 +120,7 @@ export const useTranslation = () => { return { t: generateTranslationFunction(translations, settings.language, fallbackLanguage), language: settings?.language ?? fallbackLanguage, - dict: generateDictFunction(translations) + dict: generateDictFunction(translations, settings.language, fallbackLanguage) }; };