1 | import { expect } from 'chai';
|
2 | import sinon from 'sinon';
|
3 | import React from 'react';
|
4 | import ReactDOM from 'react-dom';
|
5 | import TestUtils from 'react-addons-test-utils';
|
6 |
|
7 | import { documentEvent, renderComponent, ExampleComponent } from './helpers';
|
8 | import Holdable from '../Holdable.react';
|
9 | import defineHold from '../defineHold';
|
10 |
|
11 |
|
12 |
|
13 | let clock;
|
14 | const renderHoldable = renderComponent(Holdable);
|
15 |
|
16 | describe("Holdable", () => {
|
17 | beforeEach(() => {
|
18 | clock = sinon.useFakeTimers();
|
19 | });
|
20 |
|
21 | afterEach(() => {
|
22 | clock.restore();
|
23 | });
|
24 |
|
25 | it("should pass updates to callback child as 'holdProgress'", () => {
|
26 | const progressUpdates = [];
|
27 | const holdable = TestUtils.renderIntoDocument(
|
28 | <Holdable>
|
29 | {({ holdProgress }) => {
|
30 | progressUpdates.push(holdProgress);
|
31 | return <div></div>;
|
32 | }}
|
33 | </Holdable>
|
34 | );
|
35 | TestUtils.Simulate.touchStart(ReactDOM.findDOMNode(holdable));
|
36 | clock.tick(250);
|
37 | expect(progressUpdates).to.be.lengthOf(3);
|
38 | clock.tick(250);
|
39 | expect(progressUpdates[3]).to.be.above(progressUpdates[2]);
|
40 | });
|
41 |
|
42 | it("should fire a callback 'onHoldProgress' when progress is made", () => {
|
43 | const spy = sinon.spy();
|
44 | const holdable = renderHoldable({onHoldProgress: spy});
|
45 | TestUtils.Simulate.touchStart(ReactDOM.findDOMNode(holdable));
|
46 | clock.tick(1000);
|
47 | expect(spy.callCount).to.be.equal(4);
|
48 | });
|
49 |
|
50 | it("should fire a callback 'onHoldComplete' after hold is completed", () => {
|
51 | const spy = sinon.spy();
|
52 | const holdable = renderHoldable({onHoldComplete: spy});
|
53 | TestUtils.Simulate.touchStart(ReactDOM.findDOMNode(holdable));
|
54 | clock.tick(1500);
|
55 | expect(spy.calledOnce).to.be.true;
|
56 | });
|
57 |
|
58 | it("should stop firing 'onHoldProgress' when touch is moved", () => {
|
59 | const spy = sinon.spy();
|
60 | const holdable = renderHoldable({onHoldProgress: spy});
|
61 |
|
62 | TestUtils.Simulate.touchStart(ReactDOM.findDOMNode(holdable));
|
63 | clock.tick(250);
|
64 | expect(spy.calledOnce).to.be.true;
|
65 | documentEvent('touchmove');
|
66 | clock.tick(250);
|
67 | expect(spy.calledOnce).to.be.true;
|
68 | });
|
69 |
|
70 | it("should not fire 'onHoldComplete' when touch is moved", () => {
|
71 | const spy = sinon.spy();
|
72 | const holdable = renderHoldable({onHoldComplete: spy});
|
73 |
|
74 | TestUtils.Simulate.touchStart(ReactDOM.findDOMNode(holdable));
|
75 | clock.tick(250);
|
76 | documentEvent('touchmove');
|
77 | expect(spy.notCalled).to.be.true;
|
78 | clock.tick(1000);
|
79 | expect(spy.notCalled).to.be.true;
|
80 | });
|
81 |
|
82 | it("should stop firing 'onHoldProgress' when touch is released", () => {
|
83 | const spy = sinon.spy();
|
84 | const holdable = renderHoldable({onHoldProgress: spy});
|
85 | TestUtils.Simulate.touchStart(ReactDOM.findDOMNode(holdable));
|
86 | clock.tick(250);
|
87 | documentEvent('touchend');
|
88 | clock.tick(250);
|
89 | expect(spy.calledOnce).to.be.true;
|
90 | });
|
91 |
|
92 | it("should not fire 'onHoldComplete' when touch is released", () => {
|
93 | const spy = sinon.spy();
|
94 | const holdable = renderHoldable({onHoldComplete: spy});
|
95 | TestUtils.Simulate.touchStart(ReactDOM.findDOMNode(holdable));
|
96 | clock.tick(250);
|
97 | documentEvent('touchend');
|
98 | clock.tick(1000);
|
99 | expect(spy.notCalled).to.be.true;
|
100 | });
|
101 |
|
102 | it("should reset the state when touch is ended", () => {
|
103 | const holdable = renderHoldable();
|
104 | TestUtils.Simulate.touchStart(ReactDOM.findDOMNode(holdable));
|
105 | documentEvent('touchend');
|
106 | expect(holdable.state).to.eql({initial: null, current: null, duration: 0});
|
107 | });
|
108 |
|
109 | it("should alter its progress updates when 'updateEvery' is used", () => {
|
110 | const spy = sinon.spy();
|
111 | const config = defineHold({updateEvery: 50});
|
112 | const holdable = renderHoldable({ onHoldProgress: spy, config });
|
113 | TestUtils.Simulate.touchStart(ReactDOM.findDOMNode(holdable));
|
114 |
|
115 | expect(spy.notCalled).to.be.true;
|
116 | clock.tick(50);
|
117 | expect(spy.calledOnce).to.be.true;
|
118 | clock.tick(50);
|
119 | expect(spy.calledTwice).to.be.true;
|
120 | clock.tick(50);
|
121 | expect(spy.calledThrice).to.be.true;
|
122 | });
|
123 |
|
124 |
|
125 | it("should alter its hold length when 'holdFor' is used", () => {
|
126 | const spy = sinon.spy();
|
127 | const config = defineHold({holdFor: 500});
|
128 | const holdable = renderHoldable({ onHoldComplete: spy, config });
|
129 | TestUtils.Simulate.touchStart(ReactDOM.findDOMNode(holdable));
|
130 |
|
131 | clock.tick(250);
|
132 | expect(spy.notCalled).to.be.true;
|
133 | clock.tick(500);
|
134 | expect(spy.calledOnce).to.be.true;
|
135 | clock.tick(500);
|
136 | expect(spy.calledOnce).to.be.true;
|
137 | });
|
138 |
|
139 | it("should render its child as its only output", () => {
|
140 | const renderer = TestUtils.createRenderer();
|
141 | renderer.render(<Holdable><div></div></Holdable>);
|
142 | const output = renderer.getRenderOutput();
|
143 | expect(output.type).to.be.equal('div');
|
144 | });
|
145 |
|
146 | it("should pass the correct props to nested react-touch components", () => {
|
147 | const renderer = TestUtils.createRenderer();
|
148 | renderer.render(<Holdable>
|
149 | <Holdable><div></div></Holdable>
|
150 | </Holdable>);
|
151 | const output = renderer.getRenderOutput();
|
152 | expect(output.props).to.have.keys([
|
153 | '__passThrough',
|
154 | 'children',
|
155 | 'config',
|
156 | 'onMouseDown',
|
157 | 'onTouchStart',
|
158 | 'onHoldComplete',
|
159 | 'onHoldProgress',
|
160 | ]);
|
161 | });
|
162 |
|
163 | it("should not pass custom props to its children", () => {
|
164 | const renderer = TestUtils.createRenderer();
|
165 | renderer.render(<Holdable><ExampleComponent /></Holdable>);
|
166 | const output = renderer.getRenderOutput();
|
167 | expect(output.props).to.have.keys(['onMouseDown', 'onTouchStart']);
|
168 | });
|
169 |
|
170 |
|
171 | it("should not pass custom props down to DOM nodes", () => {
|
172 | const renderer = TestUtils.createRenderer();
|
173 | renderer.render(<Holdable><div></div></Holdable>);
|
174 | const output = renderer.getRenderOutput();
|
175 | expect(output.props).to.have.keys(['onMouseDown', 'onTouchStart']);
|
176 | });
|
177 |
|
178 | it("should remove timers and listeners when the component unmounts", () => {
|
179 | const container = document.createElement('div');
|
180 | const spy = sinon.spy();
|
181 | const holdable = ReactDOM.render(
|
182 | <Holdable onHoldProgress={spy}>
|
183 | <div></div>
|
184 | </Holdable>,
|
185 | container
|
186 | );
|
187 | TestUtils.Simulate.touchStart(ReactDOM.findDOMNode(holdable));
|
188 | ReactDOM.unmountComponentAtNode(container);
|
189 | clock.tick(250);
|
190 | expect(spy.notCalled).to.be.true;
|
191 | });
|
192 | });
|