Files
zeekay 94741a8363 refactor(rebrand): sweep the remaining langflow — env vars, identifiers, stragglers
Completes the rebrand per direction: LANGFLOW_/LANGFLOW -> FLOW_/FLOW (env vars,
headers), langflow_ -> flow_ (settings fields, local vars), camelCase identifiers
(LangflowClient/Logo/HTTPError, builtWithLangflow, getLangflowDesktop) -> Flow*,
and all remaining bare tokens. Fixed the identifier-space hazard (Langflow ->
'Hanzo Flow' is prose-only; in code it collapses to Flow so no identifier gains a
space). compileall of flow + lfx is clean.

Repo-wide langflow now = 4, all the protected MIT attribution to langflow-ai/
langflow in README (legally required; deliberately preserved).

Breaking (per no-backwards-compat / forward-perfection): the LANGFLOW_* env-var
prefix is now FLOW_* — deployments must update their env. CI's uv + frontend
build is the runtime gate.
2026-07-16 10:18:53 -07:00

241 lines
7.0 KiB
TypeScript

/**
* Test template for custom React hooks in Flow.
*
* Usage:
* 1. Copy this file to `__tests__/use-hook-name.test.ts`
* 2. Replace all TEMPLATE_* placeholders with actual values
* 3. Remove unused sections
* 4. Run: npm test -- path/to/__tests__/use-hook-name.test.ts
*/
import { act, renderHook, waitFor } from "@testing-library/react";
// Replace with actual hook import path
import { TEMPLATE_HOOK } from "../TEMPLATE_HOOK";
// ============================================================
// Mocks
// ============================================================
// Mock dependencies (if the hook calls APIs, reads stores, etc.)
// jest.mock("@/controllers/API/api", () => ({
// __esModule: true,
// default: {
// get: jest.fn(),
// post: jest.fn(),
// },
// }));
// Mock Zustand store (if the hook reads from a store)
// import useMyStore from "@/stores/myStore";
// beforeEach(() => {
// useMyStore.setState({ items: [], loading: false });
// });
// ============================================================
// Tests
// ============================================================
describe("TEMPLATE_HOOK", () => {
beforeEach(() => {
jest.clearAllMocks();
});
// ----------------------------------------------------------
// Initial State
// ----------------------------------------------------------
describe("initial state", () => {
it("should return the correct initial value", () => {
const { result } = renderHook(() => TEMPLATE_HOOK());
// Replace with actual initial state assertions
// expect(result.current.value).toBe(initialValue);
// expect(result.current.loading).toBe(false);
// expect(result.current.error).toBeNull();
});
});
// ----------------------------------------------------------
// State Updates
// ----------------------------------------------------------
describe("state updates", () => {
it("should update state when action is called", () => {
const { result } = renderHook(() => TEMPLATE_HOOK());
act(() => {
// Call the hook's update function
// result.current.setValue("new value");
});
// Assert the new state
// expect(result.current.value).toBe("new value");
});
it("should handle multiple sequential updates", () => {
const { result } = renderHook(() => TEMPLATE_HOOK());
act(() => {
// result.current.increment();
// result.current.increment();
// result.current.increment();
});
// expect(result.current.count).toBe(3);
});
});
// ----------------------------------------------------------
// Parameters
// ----------------------------------------------------------
describe("parameters", () => {
it("should accept and use initial parameters", () => {
const { result } = renderHook(() =>
TEMPLATE_HOOK(/* initial params */),
);
// Assert hook uses the provided parameters
});
it("should react to parameter changes on rerender", () => {
const { result, rerender } = renderHook(
({ param }) => TEMPLATE_HOOK(param),
{ initialProps: { param: "initial" } },
);
// Assert initial state
// expect(result.current.value).toBe("initial");
// Rerender with new parameter
rerender({ param: "updated" });
// Assert updated state
// expect(result.current.value).toBe("updated");
});
});
// ----------------------------------------------------------
// Async Behavior
// ----------------------------------------------------------
// describe("async behavior", () => {
// it("should fetch data on mount", async () => {
// jest.mocked(api.get).mockResolvedValueOnce({
// data: { items: [{ id: "1" }] },
// });
//
// const { result } = renderHook(() => TEMPLATE_HOOK());
//
// // Initially loading
// expect(result.current.loading).toBe(true);
//
// // Wait for data
// await waitFor(() => {
// expect(result.current.loading).toBe(false);
// });
//
// expect(result.current.data).toEqual([{ id: "1" }]);
// });
//
// it("should handle fetch errors", async () => {
// jest.mocked(api.get).mockRejectedValueOnce(new Error("Failed"));
//
// const { result } = renderHook(() => TEMPLATE_HOOK());
//
// await waitFor(() => {
// expect(result.current.error).toBeTruthy();
// });
// });
// });
// ----------------------------------------------------------
// Debounced/Throttled Behavior
// ----------------------------------------------------------
// describe("debounced behavior", () => {
// beforeEach(() => {
// jest.useFakeTimers();
// });
//
// afterEach(() => {
// jest.runOnlyPendingTimers();
// jest.useRealTimers();
// });
//
// it("should debounce the callback", () => {
// const callback = jest.fn();
// const { result } = renderHook(() => TEMPLATE_HOOK(callback, 500));
//
// result.current("arg1");
// result.current("arg2");
// result.current("arg3");
//
// expect(callback).not.toHaveBeenCalled();
//
// jest.advanceTimersByTime(500);
//
// expect(callback).toHaveBeenCalledTimes(1);
// expect(callback).toHaveBeenCalledWith("arg3");
// });
// });
// ----------------------------------------------------------
// Memoization
// ----------------------------------------------------------
describe("memoization", () => {
it("should return stable reference when dependencies do not change", () => {
const { result, rerender } = renderHook(() => TEMPLATE_HOOK());
const firstResult = result.current;
rerender();
const secondResult = result.current;
// For functions/objects that should be memoized:
// expect(firstResult.handler).toBe(secondResult.handler);
});
});
// ----------------------------------------------------------
// Edge Cases
// ----------------------------------------------------------
describe("edge cases", () => {
it("should handle empty input", () => {
const { result } = renderHook(() => TEMPLATE_HOOK(/* empty/null */));
// Assert graceful handling
});
it("should handle rapid calls", () => {
const { result } = renderHook(() => TEMPLATE_HOOK());
act(() => {
for (let i = 0; i < 100; i++) {
// result.current.action();
}
});
// Assert correct final state
});
});
// ----------------------------------------------------------
// Cleanup
// ----------------------------------------------------------
// describe("cleanup", () => {
// it("should clean up resources on unmount", () => {
// const removeListenerSpy = jest.fn();
// jest.spyOn(window, "addEventListener").mockImplementation(() => {});
// jest.spyOn(window, "removeEventListener").mockImplementation(removeListenerSpy);
//
// const { unmount } = renderHook(() => TEMPLATE_HOOK());
// unmount();
//
// expect(removeListenerSpy).toHaveBeenCalled();
// });
// });
});