import { setupRerender } from 'preact/test-utils';
import { createElement, render, Component } from 'preact';
import { setupScratch, teardown } from '../_util/helpers';
/** @jsx createElement */
describe('Component spec', () => {
let scratch, rerender;
beforeEach(() => {
scratch = setupScratch();
rerender = setupRerender();
});
afterEach(() => {
teardown(scratch);
});
describe('defaultProps', () => {
it('should apply default props on initial render', () => {
class WithDefaultProps extends Component {
constructor(props, context) {
super(props, context);
expect(props).to.be.deep.equal({
fieldA: 1,
fieldB: 2,
fieldC: 1,
fieldD: 2
});
}
render() {
return
;
}
}
WithDefaultProps.defaultProps = { fieldC: 1, fieldD: 1 };
render(, scratch);
});
it('should apply default props on rerender', () => {
let doRender;
class Outer extends Component {
constructor() {
super();
this.state = { i: 1 };
}
componentDidMount() {
doRender = () => this.setState({ i: 2 });
}
render(props, { i }) {
return ;
}
}
class WithDefaultProps extends Component {
constructor(props, context) {
super(props, context);
this.ctor(props, context);
}
ctor() {}
componentWillReceiveProps() {}
render() {
return ;
}
}
WithDefaultProps.defaultProps = { fieldC: 1, fieldD: 1 };
let proto = WithDefaultProps.prototype;
sinon.spy(proto, 'ctor');
sinon.spy(proto, 'componentWillReceiveProps');
sinon.spy(proto, 'render');
render(, scratch);
doRender();
const PROPS1 = {
fieldA: 1,
fieldB: 1,
fieldC: 1,
fieldD: 1
};
const PROPS2 = {
fieldA: 1,
fieldB: 2,
fieldC: 1,
fieldD: 2
};
expect(proto.ctor).to.have.been.calledWithMatch(PROPS1);
expect(proto.render).to.have.been.calledWithMatch(PROPS1);
rerender();
// expect(proto.ctor).to.have.been.calledWith(PROPS2);
expect(proto.componentWillReceiveProps).to.have.been.calledWithMatch(
PROPS2
);
expect(proto.render).to.have.been.calledWithMatch(PROPS2);
});
});
describe('forceUpdate', () => {
it('should force a rerender', () => {
let forceUpdate;
class ForceUpdateComponent extends Component {
componentWillUpdate() {}
componentDidMount() {
forceUpdate = () => this.forceUpdate();
}
render() {
return ;
}
}
sinon.spy(ForceUpdateComponent.prototype, 'componentWillUpdate');
sinon.spy(ForceUpdateComponent.prototype, 'forceUpdate');
render(, scratch);
expect(ForceUpdateComponent.prototype.componentWillUpdate).not.to.have
.been.called;
forceUpdate();
rerender();
expect(ForceUpdateComponent.prototype.componentWillUpdate).to.have.been
.called;
expect(ForceUpdateComponent.prototype.forceUpdate).to.have.been.called;
});
it('should add callback to renderCallbacks', () => {
let forceUpdate;
let callback = sinon.spy();
class ForceUpdateComponent extends Component {
componentDidMount() {
forceUpdate = () => this.forceUpdate(callback);
}
render() {
return ;
}
}
sinon.spy(ForceUpdateComponent.prototype, 'forceUpdate');
render(, scratch);
forceUpdate();
rerender();
expect(ForceUpdateComponent.prototype.forceUpdate).to.have.been.called;
expect(
ForceUpdateComponent.prototype.forceUpdate
).to.have.been.calledWith(callback);
expect(callback).to.have.been.called;
});
});
});