Skip to content

Commit 2d9656c

Browse files
author
Raice Hannay
committed
support optional redux array merging + update deps
1 parent 09121ab commit 2d9656c

File tree

10 files changed

+279
-183
lines changed

10 files changed

+279
-183
lines changed

package.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"author": "Raice Hannay <[email protected]>",
44
"description": "A set of classes to make setting up React components for unit tests easy.",
55
"license": "ISC",
6-
"version": "3.0.5",
6+
"version": "3.1.0",
77
"keywords": [
88
"component",
99
"enzyme",
@@ -75,16 +75,16 @@
7575
"devDependencies": {
7676
"@testing-library/react": "^12.0.0",
7777
"@types/enzyme": "^3.10.12",
78-
"@types/jest": "^29.0.2",
78+
"@types/jest": "^29.0.3",
7979
"@types/react": "^17.0.14",
8080
"@types/react-redux": "^7.1.24",
81-
"@typescript-eslint/eslint-plugin": "^5.37.0",
82-
"@typescript-eslint/parser": "^5.37.0",
81+
"@typescript-eslint/eslint-plugin": "^5.38.1",
82+
"@typescript-eslint/parser": "^5.38.1",
8383
"@wojtekmaj/enzyme-adapter-react-17": "^0.6.7",
8484
"cross-env": "^7.0.3",
8585
"enzyme": "^3.11.0",
8686
"enzyme-to-json": "^3.6.2",
87-
"eslint": "^8.23.1",
87+
"eslint": "^8.24.0",
8888
"eslint-config-voodoocreation": "^3.0.2",
8989
"eslint-plugin-import": "^2.26.0",
9090
"eslint-plugin-jest": "^27.0.4",
@@ -99,11 +99,11 @@
9999
"react": "^17.0.2",
100100
"react-dom": "^17.0.2",
101101
"react-intl": "^6.1.1",
102-
"react-redux": "^8.0.2",
102+
"react-redux": "^8.0.4",
103103
"redux": "^4.2.0",
104104
"rimraf": "^3.0.2",
105-
"ts-jest": "^29.0.1",
106-
"typescript": "^4.8.3",
105+
"ts-jest": "^29.0.2",
106+
"typescript": "^4.8.4",
107107
"typescript-fsa": "^3.0.0",
108108
"typescript-fsa-reducers": "^1.2.2"
109109
},

src/enzyme/WrapperWithRedux.test.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { ReduxDummy } from "../../test/ReduxDummy";
66

77
const initialState = {
88
test: {
9+
array: ["item-a"],
910
value: "Default value",
1011
},
1112
};
@@ -62,6 +63,20 @@ describe("WrapperWithRedux", () => {
6263
expect(wrapper.find(".Dummy--value").text()).toBe("Test value");
6364
});
6465

66+
it("doesn't merge arrays when withMergedReduxArrays(false) is used", () => {
67+
const wrapper = component
68+
.withMergedReduxArrays(false)
69+
.withReduxState({
70+
test: {
71+
array: ["item-b"],
72+
},
73+
})
74+
.mount();
75+
76+
expect(wrapper.find("li")).toHaveLength(1);
77+
expect(wrapper.find("li").text()).toBe("item-b");
78+
});
79+
6580
it("clears test-specific reduxState after previous test and uses default reduxState again", () => {
6681
const wrapper = component.mount();
6782

@@ -171,6 +186,7 @@ describe("WrapperWithRedux", () => {
171186
it("updates the store", () => {
172187
expect(wrapper.store.getState()).toEqual({
173188
test: {
189+
array: initialState.test.array,
174190
value: payload,
175191
},
176192
});

src/enzyme/WrapperWithRedux.tsx

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ export default abstract class WrapperWithRedux<
2020
> extends Wrapper<C, P> {
2121
// region Properties that remain throughout instance lifecycle
2222

23+
/**
24+
* Determines whether arrays in Redux state are merged when rendering the component.
25+
*/
26+
protected isMergingReduxArrays = true;
27+
2328
/**
2429
* The default Redux store state for all test scenarios for the current test suite.
2530
*
@@ -63,9 +68,24 @@ export default abstract class WrapperWithRedux<
6368
* Returns the merged Redux store state used by the current test scenario
6469
*/
6570
protected get mergedReduxState(): S {
66-
return merge(this.defaultReduxState, this.scenarioReduxState) as S;
71+
return merge.withOptions(
72+
{ mergeArrays: this.isMergingReduxArrays },
73+
this.defaultReduxState,
74+
this.scenarioReduxState
75+
) as S;
6776
}
6877

78+
/**
79+
* Toggles whether to merge arrays in the Redux state
80+
*
81+
* @param value The new value
82+
*/
83+
public withMergedReduxArrays = (value: boolean) => {
84+
this.isMergingReduxArrays = value;
85+
86+
return this;
87+
};
88+
6989
/**
7090
* Sets the default Redux store state used by all test scenarios for the current test suite.
7191
*

src/enzyme/__snapshots__/WrapperWithRedux.test.tsx.snap

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@ exports[`WrapperWithRedux when using the different render methods when using 'mo
1010
>
1111
Default value
1212
</div>
13+
<ul
14+
className="Dummy--array"
15+
>
16+
<li
17+
key="item-a"
18+
>
19+
item-a
20+
</li>
21+
</ul>
1322
<div
1423
className="Dummy--children"
1524
/>

src/react-testing-library/WrapperWithRedux.test.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { ReduxDummy } from "../../test/ReduxDummy";
66

77
const initialState = {
88
test: {
9+
array: ["item-a"],
910
value: "Default value",
1011
},
1112
};
@@ -33,6 +34,21 @@ describe("WrapperWithRedux", () => {
3334
expect(getByText("Test value")).toBeDefined();
3435
});
3536

37+
it("doesn't merge arrays when withMergedReduxArrays(false) is used", () => {
38+
const { getByText, queryByText, queryAllByRole } = component
39+
.withMergedReduxArrays(false)
40+
.withReduxState({
41+
test: {
42+
array: ["item-b"],
43+
},
44+
})
45+
.render();
46+
47+
expect(queryAllByRole("listitem")).toHaveLength(1);
48+
expect(getByText("item-b")).toBeDefined();
49+
expect(queryByText("item-a")).toBeNull();
50+
});
51+
3652
it("clears test-specific reduxState after previous test and uses default reduxState again", () => {
3753
const { getByText } = component.render();
3854

@@ -139,6 +155,7 @@ describe("WrapperWithRedux", () => {
139155
it("updates the store", () => {
140156
expect(result.store.getState()).toEqual({
141157
test: {
158+
array: initialState.test.array,
142159
value: payload,
143160
},
144161
});

src/react-testing-library/WrapperWithRedux.tsx

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ export default abstract class WrapperWithRedux<
3232
> extends Wrapper<C, P> {
3333
// region Properties that remain throughout instance lifecycle
3434

35+
/**
36+
* Determines whether arrays in Redux state are merged when rendering the component.
37+
*/
38+
protected isMergingReduxArrays = true;
39+
3540
/**
3641
* The default Redux store state for all test scenarios for the current test suite.
3742
*
@@ -75,9 +80,24 @@ export default abstract class WrapperWithRedux<
7580
* Returns the merged Redux store state used by the current test scenario
7681
*/
7782
protected get mergedReduxState(): S {
78-
return merge(this.defaultReduxState, this.scenarioReduxState) as S;
83+
return merge.withOptions(
84+
{ mergeArrays: this.isMergingReduxArrays },
85+
this.defaultReduxState,
86+
this.scenarioReduxState
87+
) as S;
7988
}
8089

90+
/**
91+
* Toggles whether to merge arrays in the Redux state
92+
*
93+
* @param value The new value
94+
*/
95+
public withMergedReduxArrays = (value: boolean) => {
96+
this.isMergingReduxArrays = value;
97+
98+
return this;
99+
};
100+
81101
/**
82102
* Sets the default Redux store state used by all test scenarios for the current test suite.
83103
*

test/ReduxDummy.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export const ReduxDummy = ({ children }: IProps) => {
1212
const dispatch = useDispatch();
1313

1414
const value = useSelector(selectors.getValue);
15+
const array = useSelector(selectors.getArray);
1516

1617
const onClick = React.useCallback(() => {
1718
dispatch(actions.setValue("Click"));
@@ -20,6 +21,11 @@ export const ReduxDummy = ({ children }: IProps) => {
2021
return (
2122
<div className="Dummy">
2223
<div className="Dummy--value">{value}</div>
24+
<ul className="Dummy--array">
25+
{array.map((item) => (
26+
<li key={item}>{item}</li>
27+
))}
28+
</ul>
2329
<div className="Dummy--children">{children}</div>
2430
<button className="Dummy--button" type="button" onClick={onClick}>
2531
Button

test/reducer.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ import { reducerWithInitialState } from "typescript-fsa-reducers";
44
import * as actions from "./actions";
55

66
export interface ITestState {
7+
array: string[];
78
value: string;
89
}
910

1011
const testInitialState: ITestState = {
12+
array: [],
1113
value: "",
1214
};
1315

test/selectors.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
import { TStoreState } from "./store";
22

33
export const getValue = (store: TStoreState) => store.test.value;
4+
5+
export const getArray = (store: TStoreState) => store.test.array;

0 commit comments

Comments
 (0)