Skip to content

Commit 34b1104

Browse files
committed
update init to always return an instance #19
- update ParallaxController.init() to always return an instance. Copy the instance to the legacy global - fix broken tests
1 parent fe839e3 commit 34b1104

File tree

5 files changed

+182
-123
lines changed

5 files changed

+182
-123
lines changed

__tests__/Parallax.test.js

Lines changed: 71 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,32 @@
1-
import React from 'react';
1+
import React, { Component } from 'react';
2+
import PropTypes from 'prop-types';
23
import ReactDOM from 'react-dom';
34
import renderer from 'react-test-renderer';
45
import Parallax from 'components/Parallax';
56
import ParallaxProvider from 'components/ParallaxProvider';
67
import ParallaxController from 'libs/ParallaxController';
78

9+
// provides a controller to the provider for mocking tests
10+
class MockProvider extends Component {
11+
static childContextTypes = {
12+
parallaxController: PropTypes.object,
13+
};
14+
15+
getChildContext() {
16+
const { controllerMock } = this.props;
17+
return { parallaxController: controllerMock };
18+
}
19+
20+
componentWillUnmount() {
21+
this.props.controllerMock.destroy();
22+
}
23+
24+
render() {
25+
const { children } = this.props;
26+
return children;
27+
}
28+
}
29+
830
const log = global.console.log;
931

1032
describe('Expect the <Parallax> component', () => {
@@ -84,16 +106,12 @@ describe('Expect the <Parallax> component', () => {
84106
global.console.log = jest.fn();
85107
global.ParallaxController = ParallaxController.init();
86108

87-
const render = () => {
88-
ReactDOM.render(
89-
<Parallax>
90-
<div />
91-
</Parallax>,
92-
node
93-
);
94-
};
95-
96-
render();
109+
ReactDOM.render(
110+
<Parallax>
111+
<div />
112+
</Parallax>,
113+
node
114+
);
97115

98116
expect(global.console.log).toBeCalledWith(
99117
'Calling ParallaxController.init() has been deprecated in favor of using the <ParallaxProvider /> component. For usage details see: https://github.com/jscottsmith/react-scroll-parallax/tree/v1.1.0#usage'
@@ -103,24 +121,19 @@ describe('Expect the <Parallax> component', () => {
103121
it('to create an element in the controller on mount', () => {
104122
const node = document.createElement('div');
105123

106-
global.ParallaxController = ParallaxController.init();
107-
global.ParallaxController.createElement = jest.fn();
108-
const spy = global.ParallaxController.createElement;
124+
const controller = ParallaxController.init();
125+
controller.createElement = jest.fn();
109126

110-
const render = () => {
111-
ReactDOM.render(
112-
<ParallaxProvider>
113-
<Parallax offsetYMin={-100} offsetYMax={100}>
114-
<div />
115-
</Parallax>
116-
</ParallaxProvider>,
117-
node
118-
);
119-
};
120-
121-
render();
127+
ReactDOM.render(
128+
<MockProvider controllerMock={controller}>
129+
<Parallax offsetYMin={-100} offsetYMax={100}>
130+
<div />
131+
</Parallax>
132+
</MockProvider>,
133+
node
134+
);
122135

123-
expect(spy).toBeCalledWith({
136+
expect(controller.createElement).toBeCalledWith({
124137
elInner: expect.any(Object),
125138
elOuter: expect.any(Object),
126139
props: {
@@ -137,34 +150,30 @@ describe('Expect the <Parallax> component', () => {
137150
it('to remove an element in the controller when unmounting', () => {
138151
const node = document.createElement('div');
139152

140-
global.ParallaxController = ParallaxController.init();
141-
global.ParallaxController.removeElement = jest.fn();
142-
const spy = global.ParallaxController.removeElement;
153+
const controller = ParallaxController.init();
154+
controller.removeElement = jest.fn();
143155

144156
let instance;
145-
const render = () => {
146-
ReactDOM.render(
147-
<ParallaxProvider>
148-
<Parallax ref={ref => (instance = ref)}>
149-
<div />
150-
</Parallax>
151-
</ParallaxProvider>,
152-
node
153-
);
154-
};
157+
ReactDOM.render(
158+
<MockProvider controllerMock={controller}>
159+
<Parallax ref={ref => (instance = ref)}>
160+
<div />
161+
</Parallax>
162+
</MockProvider>,
163+
node
164+
);
155165

156-
render();
157166
const element = instance.element;
158167
ReactDOM.unmountComponentAtNode(node);
159-
expect(spy).toBeCalledWith(element);
168+
expect(controller.removeElement).toBeCalledWith(element);
160169
});
161170

162171
it('to update an element in the controller when receiving new props and disable an element if the disable prop is true', () => {
163172
const node = document.createElement('div');
164173

165-
global.ParallaxController = ParallaxController.init();
166-
global.ParallaxController.updateElement = jest.fn();
167-
global.ParallaxController.resetElementStyles = jest.fn();
174+
const controller = ParallaxController.init();
175+
controller.updateElement = jest.fn();
176+
controller.resetElementStyles = jest.fn();
168177

169178
let instance;
170179

@@ -185,33 +194,24 @@ describe('Expect the <Parallax> component', () => {
185194
}
186195
}
187196

188-
const render = () => {
189-
ReactDOM.render(
190-
<ParallaxProvider>
191-
<StateChanger />
192-
</ParallaxProvider>,
193-
node
194-
);
195-
};
196-
197-
render();
198-
199-
expect(global.ParallaxController.updateElement).toBeCalledWith(
200-
instance.element,
201-
{
202-
props: {
203-
disabled: instance.props.disabled,
204-
offsetXMax: instance.props.offsetXMax,
205-
offsetXMin: instance.props.offsetXMin,
206-
offsetYMax: instance.props.offsetYMax,
207-
offsetYMin: instance.props.offsetYMin,
208-
slowerScrollRate: instance.props.slowerScrollRate,
209-
},
210-
}
197+
ReactDOM.render(
198+
<MockProvider controllerMock={controller}>
199+
<StateChanger />
200+
</MockProvider>,
201+
node
211202
);
212203

213-
expect(global.ParallaxController.resetElementStyles).toBeCalledWith(
214-
instance.element
215-
);
204+
expect(controller.updateElement).toBeCalledWith(instance.element, {
205+
props: {
206+
disabled: instance.props.disabled,
207+
offsetXMax: instance.props.offsetXMax,
208+
offsetXMin: instance.props.offsetXMin,
209+
offsetYMax: instance.props.offsetYMax,
210+
offsetYMin: instance.props.offsetYMin,
211+
slowerScrollRate: instance.props.slowerScrollRate,
212+
},
213+
});
214+
215+
expect(controller.resetElementStyles).toBeCalledWith(instance.element);
216216
});
217217
});

__tests__/ParallaxController.test.js

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,23 @@ describe('Expect the ParallaxController', () => {
1010
});
1111

1212
it('to return an instance on init', () => {
13-
const instance = ParallaxController.init();
14-
expect(instance).toBeInstanceOf(ParallaxController);
13+
const controller = ParallaxController.init();
14+
expect(controller).toBeInstanceOf(ParallaxController);
1515
});
1616

17-
it('to return an existing instance from the window on init', () => {
18-
window.ParallaxController = 'foo';
19-
const instance = ParallaxController.init();
20-
expect(instance).toBe('foo');
21-
window.ParallaxController = undefined;
17+
it('to copy the instance to a legacy global on init', () => {
18+
const controller = ParallaxController.init();
19+
expect(window.ParallaxController).toBeInstanceOf(ParallaxController);
2220
});
2321

2422
it("to throw on init if there's no window");
2523

2624
it('to add listeners when init', () => {
2725
window.addEventListener = jest.fn();
28-
const instance = ParallaxController.init();
29-
26+
const controller = ParallaxController.init();
27+
expect(window.addEventListener.mock.calls[0]).toEqual(
28+
expect.arrayContaining(['test', null, expect.any(Object)])
29+
);
3030
expect(window.addEventListener.mock.calls[1]).toEqual(
3131
expect.arrayContaining(['scroll', expect.any(Function), false])
3232
);
@@ -36,7 +36,7 @@ describe('Expect the ParallaxController', () => {
3636
});
3737

3838
it('to create an element and return it', () => {
39-
const instance = ParallaxController.init();
39+
const controller = ParallaxController.init();
4040
const options = {
4141
elInner: document.createElement('div'),
4242
elOuter: document.createElement('div'),
@@ -49,7 +49,7 @@ describe('Expect the ParallaxController', () => {
4949
slowerScrollRate: false,
5050
},
5151
};
52-
const element = instance.createElement(options);
52+
const element = controller.createElement(options);
5353

5454
const expectedElement = {
5555
attributes: {
@@ -88,8 +88,8 @@ describe('Expect the ParallaxController', () => {
8888

8989
it('to update the controller when creating an element', () => {
9090
window.removeEventListener = jest.fn();
91-
window.ParallaxController = ParallaxController.init();
92-
window.ParallaxController.update = jest.fn();
91+
const controller = ParallaxController.init();
92+
controller.update = jest.fn();
9393

9494
const options = {
9595
elInner: document.createElement('div'),
@@ -104,15 +104,15 @@ describe('Expect the ParallaxController', () => {
104104
},
105105
};
106106

107-
window.ParallaxController.createElement(options);
108-
expect(window.ParallaxController.update).toBeCalled();
109-
window.ParallaxController.destroy();
107+
controller.createElement(options);
108+
expect(controller.update).toBeCalled();
109+
controller.destroy();
110110
});
111111

112112
it('to update the controller when updating an element', () => {
113113
window.removeEventListener = jest.fn();
114-
window.ParallaxController = ParallaxController.init();
115-
window.ParallaxController.update = jest.fn();
114+
const controller = ParallaxController.init();
115+
controller.update = jest.fn();
116116

117117
const options = {
118118
elInner: document.createElement('div'),
@@ -127,18 +127,18 @@ describe('Expect the ParallaxController', () => {
127127
},
128128
};
129129

130-
const element = window.ParallaxController.createElement(options);
131-
window.ParallaxController.updateElement(element, {
130+
const element = controller.createElement(options);
131+
controller.updateElement(element, {
132132
prop: { disabled: false },
133133
});
134-
expect(window.ParallaxController.update).toBeCalled();
135-
window.ParallaxController.destroy();
134+
expect(controller.update).toBeCalled();
135+
controller.destroy();
136136
});
137137

138138
it('to create an element then update the controller', () => {
139139
window.removeEventListener = jest.fn();
140-
window.ParallaxController = ParallaxController.init();
141-
window.ParallaxController.update = jest.fn();
140+
const controller = ParallaxController.init();
141+
controller.update = jest.fn();
142142

143143
const options = {
144144
elInner: document.createElement('div'),
@@ -153,22 +153,24 @@ describe('Expect the ParallaxController', () => {
153153
},
154154
};
155155

156-
window.ParallaxController.createElement(options);
156+
controller.createElement(options);
157157

158-
expect(window.ParallaxController.update).toBeCalled();
158+
expect(controller.update).toBeCalled();
159159
});
160160

161161
it('to remove listeners when destroyed', () => {
162162
window.removeEventListener = jest.fn();
163163
const instance = ParallaxController.init();
164+
expect(window.removeEventListener.mock.calls[0]).toEqual(
165+
expect.arrayContaining(['test', null, expect.any(Object)])
166+
);
164167

165168
instance.destroy();
166-
expect(window.removeEventListener.mock.calls[0]).toEqual(
169+
expect(window.removeEventListener.mock.calls[1]).toEqual(
167170
expect.arrayContaining(['scroll', expect.any(Function), false])
168171
);
169-
expect(window.removeEventListener.mock.calls[1]).toEqual(
172+
expect(window.removeEventListener.mock.calls[2]).toEqual(
170173
expect.arrayContaining(['resize', expect.any(Function), false])
171174
);
172-
expect(window.ParallaxController).toBe(null);
173175
});
174176
});

0 commit comments

Comments
 (0)