hook-conditional
Version:
Conditionally run different React hooks at runtime with a clean and safe API that follows the Rules of Hooks.
85 lines (84 loc) • 4.14 kB
JavaScript
import { renderHook } from "@testing-library/react";
import { describe, it, expect, vi, beforeEach } from "vitest";
import useConditionalHook from "../index";
describe("useConditionalHook", function () {
var consoleWarnSpy = vi.spyOn(console, "warn");
beforeEach(function () {
consoleWarnSpy.mockClear();
});
it("should return the result of the matching hook for string conditions", function () {
var hookMap = {
admin: function () { return "admin-permissions"; },
user: function () { return "user-permissions"; },
guest: function () { return "guest-permissions"; },
};
var result = renderHook(function () { return useConditionalHook("admin", hookMap); }).result;
expect(result.current).toBe("admin-permissions");
});
it("should return the result of the matching hook for boolean conditions", function () {
var hookMap = {
true: function () { return "new-ui"; },
false: function () { return "legacy-ui"; },
};
var result = renderHook(function () { return useConditionalHook(true, hookMap); }).result;
expect(result.current).toBe("new-ui");
});
it("should return the result of the matching hook for numeric conditions", function () {
var hookMap = {
200: function () { return "success-data"; },
404: function () { return "not-found-data"; },
500: function () { return "error-data"; },
};
var result = renderHook(function () { return useConditionalHook(404, hookMap); }).result;
expect(result.current).toBe("not-found-data");
});
it("should call all hooks unconditionally", function () {
var adminHook = vi.fn(function () { return "admin-permissions"; });
var userHook = vi.fn(function () { return "user-permissions"; });
var guestHook = vi.fn(function () { return "guest-permissions"; });
var hookMap = {
admin: adminHook,
user: userHook,
guest: guestHook,
};
renderHook(function () { return useConditionalHook("admin", hookMap); });
expect(adminHook).toHaveBeenCalled();
expect(userHook).toHaveBeenCalled();
expect(guestHook).toHaveBeenCalled();
});
it("should use fallback hook when condition has no match", function () {
var hookMap = {
admin: function () { return "admin-permissions"; },
user: function () { return "user-permissions"; },
};
var fallbackHook = function () { return "default-permissions"; };
var result = renderHook(function () {
return useConditionalHook("guest", hookMap, fallbackHook);
}).result;
expect(result.current).toBe("default-permissions");
});
it("should warn in development when no match and no fallback", function () {
var hookMap = {
admin: function () { return "admin-permissions"; },
user: function () { return "user-permissions"; },
};
renderHook(function () { return useConditionalHook("guest", hookMap); });
expect(consoleWarnSpy).toHaveBeenCalledWith(expect.stringContaining("No matching hook found for condition \"guest\""));
});
it("should return first hook result as fallback when no match and no fallback", function () {
var hookMap = {
admin: function () { return "admin-permissions"; },
user: function () { return "user-permissions"; },
};
var result = renderHook(function () { return useConditionalHook("guest", hookMap); }).result;
expect(result.current).toBe("admin-permissions");
});
it("should maintain type safety across different hook results", function () {
var hookMap = {
admin: function () { return ({ id: 1, name: "Admin" }); },
user: function () { return ({ id: 2, name: "User" }); },
};
var result = renderHook(function () { return useConditionalHook("admin", hookMap); }).result;
expect(result.current).toEqual({ id: 1, name: "Admin" });
});
});