Skip to content

Commit

Permalink
Merge pull request #712 from thebuilder/fix/test-utils
Browse files Browse the repository at this point in the history
* fix: ensure browser environment in test-utils
  • Loading branch information
thebuilder authored Dec 30, 2024
2 parents e41b9c0 + 120c483 commit f3213dd
Showing 1 changed file with 28 additions and 19 deletions.
47 changes: 28 additions & 19 deletions src/test-utils.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,6 @@
import * as React from "react";
import * as DeprecatedReactTestUtils from "react-dom/test-utils";

declare global {
var IS_REACT_ACT_ENVIRONMENT: boolean;
var jest: { fn: typeof vi.fn } | undefined;
}

const act =
// @ts-ignore - Older versions of React don't have the `act` method, so TypeScript will complain about it
typeof React.act === "function" ? React.act : DeprecatedReactTestUtils.act;

type Item = {
callback: IntersectionObserverCallback;
elements: Set<Element>;
Expand All @@ -20,10 +11,17 @@ let isMocking = false;

const observers = new Map<IntersectionObserver, Item>();

// If we are running in a valid testing environment, we can mock the IntersectionObserver.
if (typeof beforeAll !== "undefined" && typeof afterEach !== "undefined") {
/*
** If we are running in a valid testing environment, we can automate mocking the IntersectionObserver.
*/
if (
typeof window !== "undefined" &&
typeof beforeAll !== "undefined" &&
typeof afterEach !== "undefined"
) {
beforeAll(() => {
// Use the exposed mock function. Currently, only supports Jest (`jest.fn`) and Vitest with globals (`vi.fn`).
// @ts-ignore
if (typeof jest !== "undefined") setupIntersectionMocking(jest.fn);
else if (typeof vi !== "undefined") {
setupIntersectionMocking(vi.fn);
Expand All @@ -35,6 +33,23 @@ if (typeof beforeAll !== "undefined" && typeof afterEach !== "undefined") {
});
}

function getActFn() {
if (
!(
typeof window !== "undefined" &&
// @ts-ignore
window.IS_REACT_ACT_ENVIRONMENT
)
) {
return undefined;
}
// @ts-ignore - Older versions of React don't have the `act` method, so TypeScript will complain about it
return typeof React.act === "function"
? // @ts-ignore
React.act
: DeprecatedReactTestUtils.act;
}

function warnOnMissingSetup() {
if (isMocking) return;
console.error(
Expand Down Expand Up @@ -107,12 +122,6 @@ export function resetIntersectionMocking() {
observers.clear();
}

function getIsReactActEnvironment() {
return Boolean(
typeof window !== "undefined" && window.IS_REACT_ACT_ENVIRONMENT,
);
}

function triggerIntersection(
elements: Element[],
trigger: boolean | number,
Expand Down Expand Up @@ -168,8 +177,8 @@ function triggerIntersection(
}

// Trigger the IntersectionObserver callback with all the entries
if (act && getIsReactActEnvironment())
act(() => item.callback(entries, observer));
const act = getActFn();
if (act) act(() => item.callback(entries, observer));
else item.callback(entries, observer);
}
/**
Expand Down

0 comments on commit f3213dd

Please sign in to comment.