UNPKG

core-native

Version:

A lightweight framework based on React Native + Redux + Redux Saga, in strict TypeScript.

243 lines (197 loc) 9.99 kB
import {useAction, useBinaryAction, useObjectKeyAction, useUnaryAction} from "../src/hooks"; import {Action} from "../src/reducer"; /** * Using real useModuleAction in Jest environment will error, because the hooks are not called in a React component context. */ jest.mock("../src/hooks", () => ({useAction: () => () => {}, useUnaryAction: () => () => {}, useBinaryAction: () => () => {}, useObjectKeyAction: () => () => {}})); type ActionCreator<P extends any[]> = (...args: P) => Action<P>; describe("useAction(type test)", () => { test("Should accept ActionCreator with only primitive dependency", () => { const allPrimitiveActionCreator: ActionCreator<[number, string, boolean]> = (a, b, c) => ({type: "test", payload: [a, b, c]}); const allCurry = useAction(allPrimitiveActionCreator, 1, "", false); const expectAllCurryToPass = allCurry(); }); test("Should reject ActionCreators with object as deps", () => { const updateAction: ActionCreator<[string, {value: number}]> = (id: string, data: {value: number}) => ({type: "test", payload: [id, data]}); // @ts-expect-error const updateDataWithObject = useAction(updateAction, "id", {value: 2}); }); test("type union test", () => { const createTabChangeAction: ActionCreator<["a" | "b" | "c"]> = tab => ({type: "String Union test", payload: [tab]}); const changeToA = useAction(createTabChangeAction, "a"); const changeToB = useAction(createTabChangeAction, "b"); const changeToC = useAction(createTabChangeAction, "c"); const expectPassA = changeToA(); const expectPassB = changeToB(); const expectPassC = changeToC(); // @ts-expect-error const expectToFail1 = useAction(createTabChangeAction, "not valid"); // @ts-expect-error const expectToFail2 = useAction(createTabChangeAction, null); // @ts-expect-error const shouldNotHaveParam = changeToA(1); }); test("String literal union with multiple param", () => { const createTabChangeAction: ActionCreator<["a" | "b" | "c" | null | undefined | 100, {data: string}]> = (tab, data) => ({type: "String Union test", payload: [tab, data]}); const changeToA = useUnaryAction(createTabChangeAction, "a"); const changeToB = useUnaryAction(createTabChangeAction, "b"); const changeToC = useUnaryAction(createTabChangeAction, "c"); const changeToNull = useUnaryAction(createTabChangeAction, null); const changeToUndefined = useUnaryAction(createTabChangeAction, undefined); const changeTo100 = useUnaryAction(createTabChangeAction, 100); const expectChangeToAToPass = changeToA({data: "test"}); // @ts-expect-error const expectToFail1 = changeToA(); // @ts-expect-error const expectToFail2 = changeToA(""); }); }); describe("useUnaryAction(type test)", () => { test("Misuse no-arg action", () => { const noArgAction: ActionCreator<[]> = () => ({type: "test", payload: []}); // @ts-expect-error const curried = useUnaryAction(noArgAction); }); test("single-arg action", () => { const noArgAction: ActionCreator<[string]> = () => ({type: "test", payload: [""]}); const curried = useUnaryAction(noArgAction); }); test("Should curry id", () => { const updateAction: ActionCreator<[string, {value: number}]> = (id: string, data: {value: number}) => ({type: "test", payload: [id, data]}); const updateObjectWithId = useUnaryAction(updateAction, "id"); updateObjectWithId({value: 1}); // @ts-expect-error updateObjectWithId({value: "s"}); }); test("Cannot use object as dependency", () => { const updateAction: ActionCreator<[string, {value: number}, number]> = (id: string, data: {value: number}, number: number) => ({type: "test", payload: [id, data, number]}); // @ts-expect-error const cannotUseObjectAsDeps = useUnaryAction(updateAction, "", {value: 1}); }); test("String literal union with multiple param", () => { const createTabChangeAction: ActionCreator<["a" | "b" | "c" | null | undefined | 100, {data: string}]> = (tab, data) => ({type: "String Union test", payload: [tab, data]}); const changeToA = useUnaryAction(createTabChangeAction, "a"); const changeToB = useUnaryAction(createTabChangeAction, "b"); const changeToC = useUnaryAction(createTabChangeAction, "c"); const changeToNull = useUnaryAction(createTabChangeAction, null); const changeToUndefined = useUnaryAction(createTabChangeAction, undefined); const changeTo100 = useUnaryAction(createTabChangeAction, 100); const expectChangeToAToPass = changeToA({data: "test"}); // @ts-expect-error const expectToFail1 = changeToA(); // @ts-expect-error const expectToFail2 = changeToA(""); }); test("Curry with type union args", () => { const createTabChangeAction: ActionCreator<[id: string, tabId: "a" | "b" | "c" | null | undefined | 100]> = (id, tabId) => ({type: "String Union test", payload: [id, tabId]}); const changeTab = useUnaryAction(createTabChangeAction, "test"); changeTab("a"); // @ts-expect-error changeTab("d"); // @ts-expect-error changeTab({}); }); }); describe("useBinaryAction(type test)", () => { test("Curry two params", () => { const updateAction: ActionCreator<[string, number]> = (id: string, data: number) => ({type: "test", payload: [id, data]}); const updateObjectWithId = useBinaryAction(updateAction); updateObjectWithId("54", 50); // @ts-expect-error const updateObjectUnaryParam = useBinaryAction(updateAction, "10"); // @ts-expect-error const updateObjectBinaryParam = useBinaryAction(updateAction, "10", 5); // @ts-expect-error updateObjectWithId("5", "100"); // @ts-expect-error updateObjectWithId(5, "10"); // @ts-expect-error updateObjectWithId(5, 100); // @ts-expect-error updateObjectWithId("5", {value: "5"}); }); test("Curry union type params", () => { const action: ActionCreator<["a" | "b" | "c" | null | undefined | 100, {data: string}]> = (tab, data) => ({type: "String Union test", payload: [tab, data]}); const update = useBinaryAction(action); update("a", {data: "100"}); update(null, {data: "100"}); update(100, {data: "100"}); // @ts-expect-error const updateObject1 = useBinaryAction(action, 100); // @ts-expect-error const updateObject2 = useBinaryAction(action, "a"); // @ts-expect-error update("d"); // @ts-expect-error update("a", {data: 5}); // @ts-expect-error update("d", {data: "100"}); }); test("Curry union null dep type params", () => { const action: ActionCreator<["a" | "b" | "c" | null | undefined | 100, {data: string}, string]> = (tab, data) => ({type: "String Union test", payload: [tab, data, "more-data"]}); const update = useBinaryAction(action, null); update({data: "100"}, "moreData"); const updateA = useBinaryAction(action, "a"); updateA({data: "100"}, "moreData"); const updateB = useBinaryAction(action, "b"); updateB({data: "100"}, "moreData"); const updateObject1 = useBinaryAction(action, 100); const updateObject2 = useBinaryAction(action, "a"); updateObject1({data: "good data"}, "more-data"); // @ts-expect-error updateObject1("d"); // @ts-expect-error updateObject2("a", {data: 5}); // @ts-expect-error updateObject2("d", {data: "100"}); }); test("Curry union type union arg test", () => { const action: ActionCreator<[string, "a" | "b" | "c" | null | undefined | 100, {data: string}]> = (moreData, tab, data) => ({type: "String Union test", payload: [moreData, tab, data]}); const update = useBinaryAction(action, "null"); update("a", {data: "payload"}); update("b", {data: "payload"}); update("c", {data: "payload"}); update(null, {data: "payload"}); update(undefined, {data: "payload"}); update(100, {data: "payload"}); }); test("Misuse no-arg action", () => { const noArgAction: ActionCreator<[]> = () => ({type: "test", payload: []}); // @ts-expect-error useBinaryAction(noArgAction); }); test("Misuse 1-arg action", () => { const oneArgAction: ActionCreator<[number]> = id => ({type: "test", payload: [id]}); // @ts-expect-error useBinaryAction(oneArgAction, 1); // @ts-expect-error useBinaryAction(oneArgAction); }); }); describe("useModuleObjectKeyAction(type test)", () => { test("Should accept key of object", () => { const updateObjectAction: ActionCreator<[{a: string; b: number; c: boolean; d: null | "a" | "b"}]> = object => ({type: "update object", payload: [object]}); const updateA = useObjectKeyAction(updateObjectAction, "a"); const updateB = useObjectKeyAction(updateObjectAction, "b"); const updateC = useObjectKeyAction(updateObjectAction, "c"); const updateD = useObjectKeyAction(updateObjectAction, "d"); // @ts-expect-error const updateNotKey = useObjectKeyAction(updateObjectAction, "NOT KEY"); updateA("string"); updateB(1); updateC(false); updateD(null); updateD("a"); updateD("b"); // @ts-expect-error updateA(1); // @ts-expect-error updateB("s"); // @ts-expect-error updateC(3); // @ts-expect-error updateD("e"); // @ts-expect-error updateD(undefined); }); });