Skip to content

Commit

Permalink
Major version update: React-18 support & removal of Enzyme support (#26)
Browse files Browse the repository at this point in the history
* updated package.json, yarn.lock, and documentation to remove enzyme with react-18

* updated react-testing-library

* updated rtl again
  • Loading branch information
MattSchiller authored Jun 28, 2024
1 parent 4001f59 commit cc7f214
Show file tree
Hide file tree
Showing 11 changed files with 2,023 additions and 2,684 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ node_modules/
!*.config.js
!.eslintrc.js
!test/*
.DS_Store
40 changes: 11 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,24 @@
Standardized test setup methods for React components.

Tired of copy and pasting default prop templates for React component tests?
Use this cute little package with React Testing Library or Enzyme to standardize your component setups.
Use this cute little package with React Testing Library to standardize your component setups.

> 🧠 This library is a _very_ small wrapper on top of Enzyme or RTL, and exists only to help standardize test setup behavior.
> 🧠 This library is a _very_ small wrapper on top of RTL, and exists only to help standardize test setup behavior.
## Usage

```shell
npm install component-test-setup --save-dev
```

For both RTL and Enzyme, this library provides a `setup*` function that takes in:
For RTL, this library provides a `setup*` function that takes in:

1. Your React component class or function
2. Any prop defaults for the component _(optional)_

That function returns a `render*` function that takes in any more props and returns:

- The library's rendered equivalent: `view` for RTL and `wrapper` for Enzyme.
- The library's rendered equivalent: `view` for RTL
- `props`: The computed props the component rendered with.

### React Testing Library
Expand Down Expand Up @@ -66,49 +66,31 @@ const { view } = renderView(MyComponent).options({

### Enzyme

Use `setupEnzyme` to create a `renderWrapper` function.
It returns a `wrapper` result from RTL and a `props` object of the computed props used to render.
Previous versions of this library supported Enzyme, but with the upgrade to React-18 and Enzyme nop longer being supported,
this library has moved to a place of no longer supporting it either.

```js
import { setupEnzyme } from "component-test-setup";

import { MyComponent } from "./MyComponent";

const renderWrapper = setupEnzyme(MyComponent, {
someProp: "value",
});

describe("MyComponent", () => {
it("does a thing", () => {
const { props, wrapper } = renderWrapper({
some: "otherProp",
});

wrapper.getByText(props.someProp);
});
});
```
For Enzyme support, please check older major versions of this library.

### Updating Props

Often you'd like to test lifecycle methods/hooks and `component-test-setup` is written to help accommodate that.

For both RTL and Enzyme the API is the same, the `update` method returned in the `render*` method:
The `update` method returned in the `render*` method:

```js
const renderWrapper = setupEnzyme(MyComponent, {
const renderView = setupRtl(MyComponent, {
someProp: "value",
});

describe("MyComponent", () => {
it("does a thing", () => {
const { wrapper, update } = renderWrapper({
const { view, update } = renderView({
some: "otherProp",
});

update({ someProp: "another-value" });

wrapper.getByText("another-value"); // It has been updated to render with the new someProp value
view.getByText("another-value"); // It has been updated to render with the new someProp value
});
});
```
Expand Down
1 change: 0 additions & 1 deletion jest.config.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
{
"moduleFileExtensions": ["tsx", "ts", "js"],
"setupFiles": ["<rootDir>test/base-setup.js"],
"testRegex": ["\\.test\\.tsx?$"]
}
18 changes: 7 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,22 @@
"@babel/preset-env": "^7.12.11",
"@babel/preset-react": "^7.12.10",
"@babel/preset-typescript": "^7.12.7",
"@testing-library/react": "^11.2.3",
"@types/enzyme": "^3.10.8",
"@testing-library/react": "^15.0.0",
"@types/jest": "^26.0.20",
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"@typescript-eslint/eslint-plugin": "4.13.0",
"@typescript-eslint/parser": "^4.13.0",
"@wojtekmaj/enzyme-adapter-react-17": "^0.4.1",
"babel-jest": "^26.6.3",
"enzyme": "^3.11.0",
"eslint": "^7.17.0",
"eslint-config-prettier": "^7.1.0",
"husky": "^4.3.7",
"jest": "^26.6.3",
"lint-staged": "^10.5.3",
"prettier": "^2.2.1",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"typescript": "^4.1.3"
"react": "^18.0.1",
"react-dom": "^18.0.1",
"typescript": "^4.9.5"
},
"main": "src/index.js",
"homepage": "https://github.com/Codecademy/component-test-setup#readme",
Expand All @@ -35,7 +32,6 @@
},
"keywords": [
"component",
"enzyme",
"react",
"rtl",
"test"
Expand All @@ -60,5 +56,5 @@
"compile": "tsc --module commonjs"
},
"types": "src/index.d.ts",
"version": "0.3.3"
"version": "1.0.0"
}
1 change: 0 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
export * from "./setupEnzyme";
export * from "./setupRtl";
export * from "./types";
71 changes: 0 additions & 71 deletions src/setupEnzyme.test.tsx

This file was deleted.

48 changes: 0 additions & 48 deletions src/setupEnzyme.tsx

This file was deleted.

3 changes: 1 addition & 2 deletions src/setupRtl.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { RenderOptions } from "@testing-library/react";
import { render, type RenderOptions } from "@testing-library/react";
import React from "react";

import { RemainingPropsAndTestOverrides, FullProps, RenderRtl, SetupComponentType } from "./types";
Expand All @@ -25,7 +25,6 @@ export function setupRtl<
/* eslint-disable-next-line @typescript-eslint/ban-types */
BaseProps extends Partial<FullProps<ComponentType>> = {}
>(Component: ComponentType, baseProps?: BaseProps): RenderRtl<ComponentType, BaseProps> {
const { render } = require("@testing-library/react") as typeof import("@testing-library/react");
let options: RenderOptions;

function renderView(testProps?: RemainingPropsAndTestOverrides<ComponentType, BaseProps>) {
Expand Down
34 changes: 11 additions & 23 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { RenderOptions, RenderResult } from "@testing-library/react";
import { ReactWrapper } from "enzyme";
import { ReactElement } from "react";

// eslint-disable-next-line @typescript-eslint/ban-types
Expand All @@ -9,34 +8,27 @@ interface PureFunctionComponent<P = {}> {
export type SetupComponentType = React.ComponentType<any> | PureFunctionComponent;

// Given a C component type, extracts the props of it:
export type FullProps<C extends SetupComponentType> = React.ComponentProps<C>
export type FullProps<C extends SetupComponentType> = React.ComponentProps<C>;

export type RenderEnzyme<
Component extends SetupComponentType,
Props extends Partial<FullProps<Component>>
> = (
// By using the spread operator in this type, we leverage the optionality of the entire argument itself.
// eg: If the caller needs no more required props, we don't require they provide test props. But if
// they DO still need props, we require a parameter in the function signature.
// So the syntax `renderWrapper()` is valid if there are no required props,
// otherwise we force `renderWrapper({ ...missingReqs })`
...testProps: ConditionallyRequiredTestProps<Component, Props>
) => RenderEnzymeReturn<Component>;

// Just like RenderEnzyme, but RenderRtl also allows callers to do `renderRtl.options({...})(props)`
// RenderRtl allows callers to do `renderRtl.options({...})(props)`
// In order to support both signature types, we extend the function's base type and add the options
// attribute for those "in the know" ;)
export type RenderRtl<
Component extends SetupComponentType,
Props extends Partial<FullProps<Component>>
Props extends Partial<FullProps<Component>>,
> = {
// By using the spread operator in this type, we leverage the optionality of the entire argument itself.
// eg: If the caller needs no more required props, we don't require they provide test props. But if
// they DO still need props, we require a parameter in the function signature.
// So the syntax `renderView()` is valid if there are no required props,
// otherwise we force `renderView({ ...missingReqs })`
(...testProps: ConditionallyRequiredTestProps<Component, Props>): RenderRtlReturn<Component>;
options: (options: RenderOptions) => RenderRtl<Component, Props>;
};

type ConditionallyRequiredTestProps<
Component extends SetupComponentType,
Props extends Partial<FullProps<Component>>
Props extends Partial<FullProps<Component>>,
> =
// This is where the real magic happens. At type-interpretation time, the compiler can infer from the
// component's prop type and from the passed props into the `setup*` function if there are any missing
Expand All @@ -63,10 +55,6 @@ type RequiredKeys<T> = {
[K in keyof T]-?: Record<string, unknown> extends { [P in K]: T[K] } ? never : K;
}[keyof T];

interface RenderEnzymeReturn<Component extends SetupComponentType>
extends BaseRenderReturn<Component> {
wrapper: ReactWrapper<FullProps<Component>, React.ComponentState>;
}
interface RenderRtlReturn<Component extends SetupComponentType>
extends BaseRenderReturn<Component> {
view: RenderResult;
Expand All @@ -85,10 +73,10 @@ interface BaseRenderReturn<Component extends SetupComponentType> {
*/
export type RemainingPropsAndTestOverrides<
ComponentType extends SetupComponentType,
BaseProps extends Partial<FullProps<ComponentType>>
BaseProps extends Partial<FullProps<ComponentType>>,
> = RemainingProps<ComponentType, BaseProps> & Partial<FullProps<ComponentType>>;

type RemainingProps<
ComponentType extends SetupComponentType,
BaseProps extends Partial<FullProps<ComponentType>>
BaseProps extends Partial<FullProps<ComponentType>>,
> = Omit<FullProps<ComponentType>, keyof BaseProps>;
5 changes: 0 additions & 5 deletions test/base-setup.js

This file was deleted.

Loading

0 comments on commit cc7f214

Please sign in to comment.