Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: remove __PRODUCTION__ and invariant; add tests for development environment #180

Merged
merged 3 commits into from
May 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions src/PrismicImage.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as React from "react";
import * as prismic from "@prismicio/client";

import { __PRODUCTION__ } from "./lib/__PRODUCTION__";
import { devMsg } from "./lib/devMsg";

/**
Expand Down Expand Up @@ -117,7 +116,7 @@ export const PrismicImage = React.forwardRef(function PrismicImage(
...restProps
} = props;

if (!__PRODUCTION__) {
if (process.env.NODE_ENV === "development") {
if (typeof alt === "string" && props.alt !== "") {
console.warn(
`[PrismicImage] The "alt" prop can only be used to declare an image as decorative by passing an empty string (alt="") but was provided a non-empty string. You can resolve this warning by removing the "alt" prop or changing it to alt="". For more details, see ${devMsg(
Expand Down
39 changes: 20 additions & 19 deletions src/SliceZone.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import * as React from "react";
import * as prismic from "@prismicio/client";

import { __PRODUCTION__ } from "./lib/__PRODUCTION__";

/**
* The minimum required properties to represent a Prismic Slice from the Prismic
* Rest API V2 for the `<SliceZone>` component.
Expand Down Expand Up @@ -110,24 +108,27 @@ export type SliceComponentType<
* This is also the default React component rendered when a component mapping
* cannot be found in `<SliceZone>`.
*/
export const TODOSliceComponent = __PRODUCTION__
? () => null
: <TSlice extends SliceLike, TContext>({
export const TODOSliceComponent = <TSlice extends SliceLike, TContext>({
slice,
}: SliceComponentProps<TSlice, TContext>): JSX.Element | null => {
if (process.env.NODE_ENV === "development") {
const type = "slice_type" in slice ? slice.slice_type : slice.type;

console.warn(
`[SliceZone] Could not find a component for Slice type "${type}"`,
slice,
}: SliceComponentProps<TSlice, TContext>): JSX.Element | null => {
const type = "slice_type" in slice ? slice.slice_type : slice.type;

console.warn(
`[SliceZone] Could not find a component for Slice type "${type}"`,
);

return (
<section data-slice-zone-todo-component="" data-slice-type={type}>
Could not find a component for Slice type &ldquo;{type}
&rdquo;
</section>
);
};
);

return (
<section data-slice-zone-todo-component="" data-slice-type={type}>
Could not find a component for Slice type &ldquo;{type}
&rdquo;
</section>
);
} else {
return null;
}
};

/**
* React props for the `<SliceZone>` component.
Expand Down
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import "./lib/processPolyfill";

export { PrismicProvider } from "./PrismicProvider";
export type {
PrismicProviderProps,
Expand Down
12 changes: 0 additions & 12 deletions src/lib/__PRODUCTION__.ts

This file was deleted.

49 changes: 0 additions & 49 deletions src/lib/invariant.ts

This file was deleted.

4 changes: 4 additions & 0 deletions src/lib/processPolyfill.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Polyfill `process` in environments like the browser.
if (typeof process === "undefined") {
globalThis.process = { env: {} } as typeof process;
}
3 changes: 1 addition & 2 deletions src/react-server/PrismicLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
AsLinkAttrsConfig,
} from "@prismicio/client";

import { __PRODUCTION__ } from "../lib/__PRODUCTION__";
import { devMsg } from "../lib/devMsg";
import { isInternalURL } from "../lib/isInternalURL";

Expand Down Expand Up @@ -108,7 +107,7 @@ export const PrismicLink = React.forwardRef(function PrismicLink<
}: PrismicLinkProps<InternalComponentProps, ExternalComponentProps>,
ref: React.ForwardedRef<Element>,
): JSX.Element {
if (!__PRODUCTION__) {
if (process.env.NODE_ENV === "development") {
if (field) {
if (!field.link_type) {
console.error(
Expand Down
12 changes: 6 additions & 6 deletions src/usePrismicClient.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import type * as prismic from "@prismicio/client";

import { invariant } from "./lib/invariant";

import { usePrismicContext } from "./usePrismicContext";

/**
Expand All @@ -19,10 +17,12 @@ export const usePrismicClient = (
const context = usePrismicContext();

const client = explicitClient || context?.client;
invariant(
client,
"A @prismicio/client is required to query documents. Provide a client to the hook or to a <PrismicProvider> higher in your component tree.",
);

if (!client) {
throw new Error(
"A @prismicio/client is required to query documents. Provide a client to the hook or to a <PrismicProvider> higher in your component tree.",
);
}

return client;
};
12 changes: 12 additions & 0 deletions test/PrismicImage.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ it("warns if both widths and pixelDensites are given", async (ctx) => {
model: ctx.mock.model.image(),
});

// The warning only logs in "development".
const originalNodeEnv = process.env.NODE_ENV;
process.env.NODE_ENV = "development";
const consoleWarnSpy = vi
.spyOn(console, "warn")
.mockImplementation(() => void 0);
Expand All @@ -163,6 +166,7 @@ it("warns if both widths and pixelDensites are given", async (ctx) => {
);

consoleWarnSpy.mockRestore();
process.env.NODE_ENV = originalNodeEnv;
});

it("uses the field's alt if given", async (ctx) => {
Expand Down Expand Up @@ -215,6 +219,9 @@ it("warns if a non-decorative fallback alt value is given", async (ctx) => {
model: ctx.mock.model.image(),
});

// The warning only logs in "development".
const originalNodeEnv = process.env.NODE_ENV;
process.env.NODE_ENV = "development";
const consoleWarnSpy = vi
.spyOn(console, "warn")
.mockImplementation(() => void 0);
Expand All @@ -229,6 +236,7 @@ it("warns if a non-decorative fallback alt value is given", async (ctx) => {
);

consoleWarnSpy.mockRestore();
process.env.NODE_ENV = originalNodeEnv;
});

it("supports an explicit decorative alt when field has an alt value", async (ctx) => {
Expand Down Expand Up @@ -264,6 +272,9 @@ it("warns if a non-decorative alt value is given", async (ctx) => {
model: ctx.mock.model.image(),
});

// The warning only logs in "development".
const originalNodeEnv = process.env.NODE_ENV;
process.env.NODE_ENV = "development";
const consoleWarnSpy = vi
.spyOn(console, "warn")
.mockImplementation(() => void 0);
Expand All @@ -278,6 +289,7 @@ it("warns if a non-decorative alt value is given", async (ctx) => {
);

consoleWarnSpy.mockRestore();
process.env.NODE_ENV = originalNodeEnv;
});

it("forwards ref", async (ctx) => {
Expand Down
53 changes: 44 additions & 9 deletions test/SliceZone.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ it("passes context to each component if provided", () => {
});

it("renders TODO component if component mapping is missing", () => {
// The full component only renders in "development".
const originalNodeEnv = process.env.NODE_ENV;
process.env.NODE_ENV = "development";
const consoleWarnSpy = vi
.spyOn(console, "warn")
.mockImplementation(() => void 0);
Expand Down Expand Up @@ -149,21 +152,53 @@ it("renders TODO component if component mapping is missing", () => {
expect(actual).toStrictEqual(expected);
expect(consoleWarnSpy).toHaveBeenCalledWith(
expect.stringMatching(/could not find a component/i),
slices[1],
);

consoleWarnSpy.mockRestore();
process.env.NODE_ENV = originalNodeEnv;
});

it.skip("TODO component renders null in production", () => {
// ts-eager does not allow esbuild configuration.
// We cannot override the `process.env.NODE_ENV` inline replacement.
// As a result, we cannot it for production currently.
});
it("TODO component renders null in production", () => {
const originalNodeEnv = process.env.NODE_ENV;
process.env.NODE_ENV = "production";
const consoleWarnSpy = vi
.spyOn(console, "warn")
.mockImplementation(() => void 0);

it.skip("TODO component does not warn in production", () => {
// ts-eager does not allow esbuild configuration.
// We cannot override the `process.env.NODE_ENV` inline replacement.
// As a result, we cannot it for production currently.
const slices = [{ slice_type: "foo" }, { slice_type: "bar" }] as const;

const actual = renderJSON(
<SliceZone
slices={slices}
components={{
foo: (props) => <StringifySliceComponent id="foo" {...props} />,
// NOTE: The `bar` component is purposely left out of this it.
// bar: (props) => <StringifySliceComponent id="bar" {...props} />,
}}
/>,
);
const expected = renderJSON(
<>
<StringifySliceComponent
id="foo"
slice={slices[0]}
index={0}
slices={slices}
context={{}}
/>
{null}
</>,
);

expect(actual).toStrictEqual(expected);
expect(consoleWarnSpy).not.toHaveBeenCalledWith(
expect.stringMatching(/could not find a component/i),
slices[1],
);

consoleWarnSpy.mockRestore();
process.env.NODE_ENV = originalNodeEnv;
});

it("supports the GraphQL API", () => {
Expand Down
19 changes: 19 additions & 0 deletions test/react-server/PrismicLink.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,10 @@ it("throws error if `link_type` is missing from a given field", async (ctx) => {
// @ts-expect-error - We are purposely deleting a non-optional field.
delete field.link_type;

// The warning only logs in "development".
const originalNodeEnv = process.env.NODE_ENV;
process.env.NODE_ENV = "development";

const consoleErrorSpy = vi
.spyOn(console, "error")
.mockImplementation(() => void 0);
Expand All @@ -309,11 +313,16 @@ it("throws error if `link_type` is missing from a given field", async (ctx) => {
);

consoleErrorSpy.mockRestore();
process.env.NODE_ENV = originalNodeEnv;
});

it("warns if properties are missing from a given field", async () => {
const field = { link_type: prismic.LinkType.Web, target: "_blank" };

// The warning only logs in "development".
const originalNodeEnv = process.env.NODE_ENV;
process.env.NODE_ENV = "development";

const consoleWarnSpy = vi
.spyOn(console, "warn")
.mockImplementation(() => void 0);
Expand All @@ -326,11 +335,16 @@ it("warns if properties are missing from a given field", async () => {
);

consoleWarnSpy.mockRestore();
process.env.NODE_ENV = originalNodeEnv;
});

it("does not warn if given field is empty", async (ctx) => {
const field = ctx.mock.value.link({ state: "empty" });

// The warning only logs in "development".
const originalNodeEnv = process.env.NODE_ENV;
process.env.NODE_ENV = "development";

const consoleWarnSpy = vi
.spyOn(console, "warn")
.mockImplementation(() => void 0);
Expand All @@ -340,11 +354,15 @@ it("does not warn if given field is empty", async (ctx) => {
expect(consoleWarnSpy).not.toHaveBeenCalled();

consoleWarnSpy.mockRestore();
process.env.NODE_ENV = originalNodeEnv;
});

it("warns if properties are missing from a given document", async () => {
const document = {} as prismic.PrismicDocument;

// The warning only logs in "development".
const originalNodeEnv = process.env.NODE_ENV;
process.env.NODE_ENV = "development";
const consoleWarnSpy = vi
.spyOn(console, "warn")
.mockImplementation(() => void 0);
Expand All @@ -357,4 +375,5 @@ it("warns if properties are missing from a given document", async () => {
);

consoleWarnSpy.mockRestore();
process.env.NODE_ENV = originalNodeEnv;
});