Skip to content

Commit 625c9e3

Browse files
committed
Add parameters validation and tests for FlowTip DOM component
1 parent 029c359 commit 625c9e3

3 files changed

Lines changed: 118 additions & 0 deletions

File tree

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
"react": "^15.3.1",
5353
"react-addons-test-utils": "^15.3.1",
5454
"react-dom": "^15.3.1",
55+
"sinon": "^1.17.6",
5556
"webpack": "^1.12.11",
5657
"webpack-dev-server": "^1.14.1"
5758
},

src/dom.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ import FlowTip from './flowtip';
66
import ResizeObserver from 'react-resize-observer';
77

88
export default (Content, Tail) => {
9+
if (typeof(Content) !== 'function') {
10+
throw new TypeError('Content component is not a function.');
11+
}
12+
13+
if (typeof(Tail) !== 'function') {
14+
throw new TypeError('Tail component is not a function.');
15+
}
16+
917
return class FlowTipDOM extends Component {
1018
static defaultProps = {
1119
clamp: true,

test/spec/dom.spec.js

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import {createElement} from 'react';
2+
import sinon from 'sinon';
3+
import {shallow} from 'enzyme';
4+
import {expect} from 'chai';
5+
6+
import FlowTip from '../../src/flowtip';
7+
import FlowTipDOM from '../../src/dom';
8+
9+
describe('FlowTip DOM', () => {
10+
const ContentComponent = () => (
11+
<div className="dummp-content" />
12+
);
13+
14+
const TailComponent = () => (
15+
<div className="dummp-tail" />
16+
);
17+
18+
const getComponentClass = (content, tail) => {
19+
return FlowTipDOM(content, tail);
20+
};
21+
22+
const getComponent = (ComponentClass, children) => {
23+
return shallow(
24+
<ComponentClass parentClass="dummy-parent">
25+
{children}
26+
</ComponentClass>
27+
);
28+
};
29+
30+
let sandbox;
31+
32+
beforeEach(() => {
33+
sandbox = sinon.sandbox.create();
34+
});
35+
36+
afterEach(() => {
37+
sandbox.restore();
38+
});
39+
40+
describe('Invalid parameters', () => {
41+
it('should throw error when given invalid content component', () => {
42+
const renderDOMFlowTip = () => {
43+
return shallow(getComponentClass({lala: 42}, TailComponent));
44+
};
45+
expect(renderDOMFlowTip).to.throw(TypeError, /component is not a function/);
46+
});
47+
48+
it('should throw error when given invalid tail component', () => {
49+
const renderDOMFlowTip = () => {
50+
return shallow(getComponentClass(ContentComponent, {lala: 42}));
51+
};
52+
expect(renderDOMFlowTip).to.throw(TypeError, /component is not a function/);
53+
});
54+
});
55+
56+
describe('Valid parameters', () => {
57+
it('should render an instance of FlowTip', () => {
58+
const FlowTipComponent = getComponentClass(ContentComponent, TailComponent);
59+
const component = getComponent(FlowTipComponent, (<span>Test</span>));
60+
expect(component.find(FlowTip)).to.have.length(1);
61+
});
62+
63+
it('should calculate correct parent and anchor properties', () => {
64+
const FlowTipComponent = getComponentClass(ContentComponent, TailComponent);
65+
const component = getComponent(FlowTipComponent, (<span>Test</span>));
66+
const instance = component.instance();
67+
68+
const dummyWindow = {
69+
addEventListener: sandbox.stub(),
70+
removeEventListener: sandbox.stub(),
71+
getComputedStyle: () => ({position: "relative", overflow: "auto"}),
72+
innerHeight: 1000,
73+
innerWidth: 2000
74+
};
75+
76+
const dummyParent = {
77+
className: "dummy-parent",
78+
offsetWidth: 210,
79+
clientWidth: 200,
80+
offsetHeight: 430,
81+
clientHeight: 400,
82+
addEventListener: sandbox.stub(),
83+
removeEventListener: sandbox.stub(),
84+
getBoundingClientRect: () => ({top: 10, left: 20, right: 300, bottom: 400})
85+
};
86+
87+
const dummyAnchor = {
88+
className: "dummy-anchor",
89+
parentNode: dummyParent,
90+
getBoundingClientRect: () => ({top: 10, left: 20, width: 30, height: 40})
91+
};
92+
93+
sandbox.stub(FlowTipComponent.prototype, "getWindow").returns(dummyWindow);
94+
sandbox.stub(FlowTipComponent.prototype, "getAnchorElement").returns(dummyAnchor);
95+
96+
instance.componentDidMount();
97+
98+
expect(instance.state.parent).to.have.property('top', 10);
99+
expect(instance.state.parent).to.have.property('left', 20);
100+
expect(instance.state.parent).to.have.property('width', 270);
101+
expect(instance.state.parent).to.have.property('height', 360);
102+
103+
expect(instance.state.anchor).to.have.property('top', 10);
104+
expect(instance.state.anchor).to.have.property('left', 20);
105+
expect(instance.state.anchor).to.have.property('width', 30);
106+
expect(instance.state.anchor).to.have.property('height', 40);
107+
});
108+
});
109+
});

0 commit comments

Comments
 (0)