Skip to content

Commit 30fcaa1

Browse files
author
Raice Hannay
committed
implement beforeMount method
1 parent 421bf64 commit 30fcaa1

File tree

10 files changed

+91
-77
lines changed

10 files changed

+91
-77
lines changed

docs/Wrapper.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ extend this one, so all methods defined on this class are also available on the
66

77
As with all of these classes, you can extend it to implement your own additional functionality.
88

9+
10+
Protected abstract methods to define when extending
11+
---------------------------------------------------
12+
13+
### `beforeMount`
14+
This method is called before `mount`, `render` or `shallow` are called. The intention is to use this
15+
when defining any instance properties that need to be passed as props in your `WrappingComponent`,
16+
such as the Redux store instance (see [`WrapperWithRedux`](./WrapperWithRedux.md) for example).
17+
18+
919
Public read-only properties
1020
---------------------------
1121

docs/WrapperWithRedux.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ How to extend for use in your project
4747

4848
```typescript jsx
4949
import * as React from "react";
50-
import { IntlConfig } from "react-intl";
5150
import { WrapperWithRedux as BaseWrapper } from "react-test-wrapper";
5251

5352
import { createStore, TStoreState } from "../store";

package.json

Lines changed: 2 additions & 2 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": "1.0.5",
6+
"version": "1.0.6",
77
"keywords": [
88
"component",
99
"enzyme",
@@ -87,6 +87,6 @@
8787
"typescript-fsa-reducers": "^1.2.1"
8888
},
8989
"dependencies": {
90-
"ts-deepmerge": "^1.0.0"
90+
"ts-deepmerge": "^1.0.2"
9191
}
9292
}

src/Wrapper.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ export default class Wrapper<
5151
};
5252

5353
public mount = () => {
54+
this.beforeMount();
55+
5456
const props = this.defineProps() as P;
5557
const wrapper = mount<C>(<this.Component {...props} />, {
5658
wrappingComponent: this.WrappingComponent
@@ -62,6 +64,8 @@ export default class Wrapper<
6264
};
6365

6466
public render = () => {
67+
this.beforeMount();
68+
6569
const props = this.defineProps() as P;
6670
const wrapper = render(
6771
this.WrappingComponent ? (
@@ -79,6 +83,8 @@ export default class Wrapper<
7983
};
8084

8185
public shallow = () => {
86+
this.beforeMount();
87+
8288
const props = this.defineProps() as P;
8389
const wrapper = shallow(
8490
this.WrappingComponent ? (
@@ -95,6 +101,10 @@ export default class Wrapper<
95101
return wrapper;
96102
};
97103

104+
protected beforeMount = () => {
105+
// Implement this method when extending to define properties to pass to `WrappingComponent`
106+
};
107+
98108
protected defineProps = () => {
99109
this.mergedProps = merge(this.defaultProps, this.scenarioProps, {
100110
children: this.scenarioChildren || this.defaultChildren

src/WrapperWithIntl.test.tsx

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,5 @@
1-
import * as React from "react";
2-
import { IntlConfig } from "react-intl";
3-
41
import { IntlDummy } from "../test/IntlDummy";
5-
import WrapperWithIntl from "./WrapperWithIntl";
6-
7-
const messages = {
8-
BUTTON: "Button"
9-
};
10-
11-
class Wrapper<
12-
C extends React.ComponentType<any>,
13-
P extends React.ComponentProps<C> = React.ComponentProps<C>
14-
> extends WrapperWithIntl<C, P> {
15-
protected intlProviderProps: Partial<IntlConfig> = {
16-
messages
17-
};
18-
}
2+
import Wrapper, { messages } from "../test/TestWrapperWithIntl";
193

204
describe("WrapperWithIntl", () => {
215
const component = new Wrapper(IntlDummy).withDefaultProps({

src/WrapperWithRedux.test.tsx

Lines changed: 25 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,21 @@
11
import { ReactWrapper } from "enzyme";
2-
import * as React from "react";
3-
import { DeepPartial, Middleware } from "redux";
42

53
import * as actions from "../test/actions";
64
import { ConnectedDummy } from "../test/Dummy";
7-
import { createStore, TStoreState } from "../test/store";
8-
import WrapperWithRedux from "./WrapperWithRedux";
9-
10-
class Wrapper<
11-
C extends React.ComponentType<any>,
12-
S extends {} = TStoreState,
13-
P extends React.ComponentProps<C> = React.ComponentProps<C>
14-
> extends WrapperWithRedux<C, S, P> {
15-
protected createStore(
16-
initialState: DeepPartial<S>,
17-
middlewares: Middleware[]
18-
) {
19-
return createStore(initialState, middlewares);
5+
import Wrapper from "../test/TestWrapperWithRedux";
6+
7+
const initialState = {
8+
test: {
9+
value: "Default value"
2010
}
21-
}
11+
};
12+
13+
const component = new Wrapper(ConnectedDummy).withDefaultReduxState(
14+
initialState
15+
);
2216

2317
describe("WrapperWithRedux", () => {
2418
describe("when using the different render methods", () => {
25-
const component = new Wrapper(ConnectedDummy).withDefaultReduxState({
26-
test: {
27-
value: "Default value"
28-
}
29-
});
30-
3119
describe("when using 'shallow'", () => {
3220
it("throws an error", () => {
3321
expect(() => component.shallow()).toThrowError();
@@ -58,12 +46,6 @@ describe("WrapperWithRedux", () => {
5846
});
5947

6048
describe("when using the reduxState API", () => {
61-
const component = new Wrapper(ConnectedDummy).withDefaultReduxState({
62-
test: {
63-
value: "Default value"
64-
}
65-
});
66-
6749
it("mounts with default reduxState correctly", () => {
6850
const wrapper = component.mount();
6951

@@ -90,13 +72,16 @@ describe("WrapperWithRedux", () => {
9072
});
9173

9274
describe("when using the reduxHistory API", () => {
93-
const component = new Wrapper(ConnectedDummy);
9475
const wrapper = component.mount();
9576

9677
it("starts with an empty history", () => {
9778
expect(component.reduxHistory).toEqual([]);
9879
});
9980

81+
it("renders the correct value", () => {
82+
expect(wrapper.find(".Dummy--value").text()).toBe("Default value");
83+
});
84+
10085
it("clicks the button", () => {
10186
wrapper.find(".Dummy--button").simulate("click");
10287
});
@@ -110,6 +95,10 @@ describe("WrapperWithRedux", () => {
11095
expect(matchingActions[0].payload).toBe("Click");
11196
});
11297

98+
it("renders the correct value", () => {
99+
expect(wrapper.find(".Dummy--value").text()).toBe("Click");
100+
});
101+
113102
it("clicks the button again", () => {
114103
wrapper.find(".Dummy--button").simulate("click");
115104
});
@@ -156,27 +145,19 @@ describe("WrapperWithRedux", () => {
156145
describe("when accessing the store", () => {
157146
let wrapper: ReactWrapper<typeof ConnectedDummy>;
158147
const payload = "Dispatched value";
159-
const state = {
160-
test: {
161-
value: "Default value"
162-
}
163-
};
164-
const component = new Wrapper(ConnectedDummy).withDefaultReduxState(state);
165-
166-
it("doesn't have the store defined before mounting", () => {
167-
expect(component.store).toBeUndefined();
168-
});
169148

170149
it("mounts the component", () => {
171150
wrapper = component.mount();
172151
});
173152

174-
it("has the store defined after mounting", () => {
175-
expect(component.store).toBeDefined();
153+
it("has the expected state in the store", () => {
154+
expect(component.store?.getState()).toEqual(initialState);
176155
});
177156

178-
it("has the expected state in the store", () => {
179-
expect(component.store?.getState()).toEqual(state);
157+
it("renders the default value", () => {
158+
expect(wrapper.find(".Dummy--value").text()).toBe(
159+
initialState.test.value
160+
);
180161
});
181162

182163
it("dispatches an action", () => {
@@ -198,12 +179,7 @@ describe("WrapperWithRedux", () => {
198179
});
199180

200181
it("renders the new value", () => {
201-
expect(
202-
wrapper
203-
.update()
204-
.find(".Dummy--value")
205-
.text()
206-
).toBe(payload);
182+
expect(wrapper.find(".Dummy--value").text()).toBe(payload);
207183
});
208184
});
209185
});

src/WrapperWithRedux.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export default abstract class WrapperWithRedux<
4343
};
4444

4545
public render = () => {
46+
this.beforeMount();
4647
this.reset();
4748

4849
throw new Error(
@@ -51,6 +52,7 @@ export default abstract class WrapperWithRedux<
5152
};
5253

5354
public shallow = () => {
55+
this.beforeMount();
5456
this.reset();
5557

5658
throw new Error(
@@ -67,12 +69,10 @@ export default abstract class WrapperWithRedux<
6769
middlewares: Middleware[]
6870
): Store;
6971

70-
protected defineStore = () => {
72+
protected beforeMount = () => {
7173
this.reduxStore = this.createStore(this.mergedReduxState, [
7274
this.reduxHistoryMiddleware
7375
]);
74-
75-
return this.reduxStore;
7676
};
7777

7878
protected reduxHistoryMiddleware: Middleware = () => next => action => {
@@ -81,7 +81,7 @@ export default abstract class WrapperWithRedux<
8181
};
8282

8383
protected WrappingComponent: React.FC = ({ children }) => (
84-
<Provider store={this.defineStore()}>{children}</Provider>
84+
<Provider store={this.store!}>{children}</Provider>
8585
);
8686

8787
protected reset() {

test/TestWrapperWithIntl.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import * as React from "react";
2+
import { IntlConfig } from "react-intl";
3+
4+
import WrapperWithIntl from "../src/WrapperWithIntl";
5+
6+
export const messages = {
7+
BUTTON: "Button"
8+
};
9+
10+
export default class TestWrapperWithIntl<
11+
C extends React.ComponentType<any>,
12+
P extends React.ComponentProps<C> = React.ComponentProps<C>
13+
> extends WrapperWithIntl<C, P> {
14+
protected intlProviderProps: Partial<IntlConfig> = {
15+
messages
16+
};
17+
}

test/TestWrapperWithRedux.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import * as React from "react";
2+
import { DeepPartial, Middleware } from "redux";
3+
4+
import WrapperWithRedux from "../src/WrapperWithRedux";
5+
import { createStore, TStoreState } from "./store";
6+
7+
export default class TestWrapperWithRedux<
8+
C extends React.ComponentType<any>,
9+
S extends {} = TStoreState,
10+
P extends React.ComponentProps<C> = React.ComponentProps<C>
11+
> extends WrapperWithRedux<C, S, P> {
12+
protected createStore(
13+
initialState: DeepPartial<S>,
14+
middlewares: Middleware[]
15+
) {
16+
return createStore(initialState, middlewares);
17+
}
18+
}

yarn.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4088,10 +4088,10 @@ tr46@^1.0.1:
40884088
dependencies:
40894089
punycode "^2.1.0"
40904090

4091-
ts-deepmerge@^1.0.0:
4092-
version "1.0.0"
4093-
resolved "https://registry.yarnpkg.com/ts-deepmerge/-/ts-deepmerge-1.0.0.tgz#f068b4ffc547fa67124d46f6b89f3a4f15a9bd61"
4094-
integrity sha512-ExxHq1g8SptwuDLYiW5yFtk6DyNIZ4pOeSRwE38VffDJAMUk51yD/Jn8j7AsPVhY4rfeajYi2+i8r9r2nVDTRA==
4091+
ts-deepmerge@^1.0.2:
4092+
version "1.0.2"
4093+
resolved "https://registry.yarnpkg.com/ts-deepmerge/-/ts-deepmerge-1.0.2.tgz#28d0799dadb62cfa1eb557e7b72929ce07109f99"
4094+
integrity sha512-FKzWi+9FFueqdDuhtxYyAHlUyFbmBi09tQQvlG5PvR0NmD745DMnpiAzZZVShwFnBdir5e1gz+wwPKTykMKkKg==
40954095

40964096
ts-jest@^24.2.0:
40974097
version "24.2.0"

0 commit comments

Comments
 (0)