Skip to content

Commit

Permalink
chore: run tests and storybook in StrictMode (#3352)
Browse files Browse the repository at this point in the history
Co-authored-by: WK Wong <wingkwong.code@gmail.com>
  • Loading branch information
chirokas and wingkwong committed Sep 8, 2024
1 parent d621b29 commit 659cdcf
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 14 deletions.
12 changes: 7 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"build:sb": "pnpm --filter @nextui-org/storybook build",
"start:sb": "pnpm --filter @nextui-org/storybook start",
"test": "jest --verbose --config ./jest.config.js",
"test:strict": "cross-env STRICT_MODE=true pnpm test",
"typecheck": "turbo typecheck",
"lint": "pnpm lint:pkg && pnpm lint:docs",
"lint:pkg": "eslint -c .eslintrc.json ./packages/**/*.{ts,tsx}",
Expand Down Expand Up @@ -54,7 +55,6 @@
"devDependencies": {
"@babel/cli": "^7.14.5",
"@babel/core": "^7.16.7",
"tsx": "^3.8.2",
"@babel/plugin-proposal-object-rest-spread": "^7.15.6",
"@babel/plugin-transform-runtime": "^7.14.5",
"@babel/preset-env": "^7.14.5",
Expand All @@ -69,6 +69,7 @@
"@react-bootstrap/babel-preset": "^2.1.0",
"@react-types/link": "^3.4.4",
"@react-types/shared": "3.23.1",
"@storybook/react": "^7.4.6",
"@swc-node/jest": "^1.5.2",
"@swc/core": "^1.3.35",
"@swc/jest": "^0.2.24",
Expand All @@ -85,10 +86,10 @@
"@types/testing-library__jest-dom": "5.14.5",
"@typescript-eslint/eslint-plugin": "^5.42.0",
"@typescript-eslint/parser": "^5.42.0",
"@storybook/react": "^7.4.6",
"chalk": "^4.1.2",
"concurrently": "^7.6.0",
"commitlint-plugin-function-rules": "^1.7.1",
"concurrently": "^7.6.0",
"cross-env": "^7.0.3",
"eslint": "^7.29.0",
"eslint-config-airbnb": "^18.2.1",
"eslint-config-airbnb-typescript": "^12.3.1",
Expand All @@ -106,19 +107,19 @@
"eslint-plugin-react": "^7.23.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-unused-imports": "^2.0.0",
"npm-check-updates": "^16.10.18",
"intl-messageformat": "^10.1.0",
"execa": "^5.1.1",
"find-up": "^6.3.0",
"fs-extra": "^10.0.0",
"glob": "^8.0.3",
"graceful-fs": "^4.2.6",
"gray-matter": "^4.0.3",
"husky": "^8.0.1",
"intl-messageformat": "^10.1.0",
"jest": "^28.1.1",
"jest-environment-jsdom": "^28.1.1",
"jest-watch-typeahead": "1.1.0",
"lint-staged": "^13.0.3",
"npm-check-updates": "^16.10.18",
"npm-run-all": "^4.1.5",
"p-iteration": "^1.1.8",
"parcel": "^2.3.1",
Expand All @@ -131,6 +132,7 @@
"rimraf": "^3.0.2",
"shelljs": "^0.8.4",
"tsup": "6.4.0",
"tsx": "^3.8.2",
"turbo": "1.6.3",
"typescript": "^4.9.5",
"webpack": "^5.53.0",
Expand Down
29 changes: 29 additions & 0 deletions packages/storybook/.storybook/addons/react-strict-mode/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type { PropsWithChildren } from "react"

import { addons, makeDecorator } from "@storybook/preview-api"
import { getQueryParams } from "@storybook/preview-api"
import React, { StrictMode, useEffect, useState } from "react"

function StrictModeDecorator({ children }: PropsWithChildren<any>) {
const [isStrict, setStrict] = useState(() => getQueryParams()?.strict === "true")

useEffect(() => {
const channel = addons.getChannel()

channel.on("strict/updated", setStrict)

return () => {
channel.removeListener("strict/updated", setStrict)
}
}, [])

return isStrict ? <StrictMode>{children}</StrictMode> : children
}

export const withStrictModeSwitcher = makeDecorator({
name: "withStrictModeSwitcher",
parameterName: "strictModeSwitcher",
wrapper: (getStory, context) => {
return <StrictModeDecorator>{getStory(context)}</StrictModeDecorator>
},
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import type { API } from "@storybook/manager-api";

import { addons, types } from "@storybook/manager-api";
import React, { useEffect, useState } from "react";

const ADDON_ID = "StrictModeSwitcher";

function StrictModeSwitcher({ api }: { api: API }) {
const [isStrict, setStrict] = useState(() => api.getQueryParam("strict") === "true");

const onChange = () => setStrict((val) => !val);

useEffect(() => {
const channel = api.getChannel();

channel?.emit("strict/updated", isStrict);

api.setQueryParams({
strict: String(isStrict),
});
}, [isStrict]);

return (
<div
style={{
alignItems: "center",
display: "flex",
fontSize: "0.75rem",
fontWeight: 600,
lineHeight: "1rem",
}}
title="Enable Strict Mode"
>
<label htmlFor="strictmode">StrictMode:</label>
<input
checked={isStrict}
id="strictmode"
name="strictmode"
onChange={onChange}
type="checkbox"
/>
</div>
);
}

if (process.env.NODE_ENV !== "production") {
addons.register(ADDON_ID, (api) => {
addons.add(ADDON_ID, {
match: ({ viewMode }) => !!viewMode?.match(/^(story|docs)$/),
render: () => <StrictModeSwitcher api={api} />,
title: "Strict Mode Switcher",
type: types.TOOL,
});
});
}
6 changes: 3 additions & 3 deletions packages/storybook/.storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ module.exports = {
getAbsolutePath("@storybook/addon-essentials"),
getAbsolutePath("@storybook/addon-links"),
getAbsolutePath("storybook-dark-mode"),
getAbsolutePath("@storybook/addon-mdx-gfm")
getAbsolutePath("@storybook/addon-mdx-gfm"),
"./addons/react-strict-mode/register",
],
framework: {
name: getAbsolutePath("@storybook/react-vite"),
options: {}
},
core: {
disableTelemetry: true
disableTelemetry: true,
},
typescript: {
reactDocgen: false,
Expand Down
2 changes: 2 additions & 0 deletions packages/storybook/.storybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {NextUIProvider} from "@nextui-org/system/src/provider";
import type {Preview} from "@storybook/react";

import "./style.css";
import { withStrictModeSwitcher } from "./addons/react-strict-mode";

const decorators: Preview["decorators"] = [
(Story, {globals: {locale, disableAnimation}}) => {
Expand All @@ -19,6 +20,7 @@ const decorators: Preview["decorators"] = [
</NextUIProvider>
);
},
...(process.env.NODE_ENV !== "production" ? [withStrictModeSwitcher] : []),
];

const commonTheme = {
Expand Down
2 changes: 2 additions & 0 deletions packages/storybook/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
"@storybook/addon-links": "^7.4.6",
"@storybook/addon-mdx-gfm": "^7.4.6",
"@storybook/cli": "^7.4.6",
"@storybook/manager-api": "^7.6.17",
"@storybook/preview-api": "^7.6.17",
"@storybook/react": "^7.4.6",
"@storybook/react-vite": "^7.4.6",
"@storybook/theming": "^7.4.6",
Expand Down
43 changes: 37 additions & 6 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions scripts/setup-test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import "@testing-library/jest-dom/extend-expect";
import { configure } from "@testing-library/react";

const {getComputedStyle} = window;
window.getComputedStyle = (elt) => getComputedStyle(elt);
Expand Down Expand Up @@ -29,3 +30,7 @@ global.ResizeObserver = jest.fn().mockImplementation(() => ({
unobserve: jest.fn(),
disconnect: jest.fn(),
}));

configure({
reactStrictMode: process.env.STRICT_MODE === "true",
});

0 comments on commit 659cdcf

Please sign in to comment.