import { h, render, Component } from '../../src/preact';
/** @jsx h */
// gives call count and argument errors names (otherwise sinon just uses "spy"):
let spy = (name, ...args) => {
let spy = sinon.spy(...args);
spy.displayName = `spy('${name}')`;
return spy;
};
describe('refs', () => {
let scratch;
before( () => {
scratch = document.createElement('div');
(document.body || document.documentElement).appendChild(scratch);
});
beforeEach( () => {
scratch.innerHTML = '';
});
after( () => {
scratch.parentNode.removeChild(scratch);
scratch = null;
});
it('should invoke refs in render()', () => {
let ref = spy('ref');
render(
this.outer=c }>
this.inner=c } />
);
}
}
sinon.spy(TestUnmount.prototype, 'componentWillUnmount');
sinon.spy(TestUnmount.prototype, 'componentDidUnmount');
root = render(
, scratch, root);
outer = scratch.querySelector('#outer');
inner = scratch.querySelector('#inner');
expect(TestUnmount.prototype.componentWillUnmount).not.to.have.been.called;
expect(TestUnmount.prototype.componentDidUnmount).not.to.have.been.called;
root = render(
, scratch, root);
expect(TestUnmount.prototype.componentWillUnmount).to.have.been.calledOnce;
expect(TestUnmount.prototype.componentDidUnmount).to.have.been.calledOnce;
});
it('should null and re-invoke refs when swapping component root element type', () => {
let inst;
class App extends Component {
render() {
return
;
}
}
class Child extends Component {
constructor(props, context) {
super(props, context);
this.state = { show:false };
inst = this;
}
handleMount(){}
render(_, { show }) {
if (!show) return
;
return
some test content;
}
}
sinon.spy(Child.prototype, 'handleMount');
render(
, scratch);
expect(inst.handleMount).to.have.been.calledOnce.and.calledWith(scratch.querySelector('#div'));
inst.handleMount.reset();
inst.setState({ show:true });
inst.forceUpdate();
expect(inst.handleMount).to.have.been.calledTwice;
expect(inst.handleMount.firstCall).to.have.been.calledWith(null);
expect(inst.handleMount.secondCall).to.have.been.calledWith(scratch.querySelector('#span'));
inst.handleMount.reset();
inst.setState({ show:false });
inst.forceUpdate();
expect(inst.handleMount).to.have.been.calledTwice;
expect(inst.handleMount.firstCall).to.have.been.calledWith(null);
expect(inst.handleMount.secondCall).to.have.been.calledWith(scratch.querySelector('#div'));
});
it('should add refs to components representing DOM nodes with no attributes if they have been pre-rendered', () => {
// Simulate pre-render
let parent = document.createElement('div');
let child = document.createElement('div');
parent.appendChild(child);
scratch.appendChild(parent); // scratch contains:
let ref = spy('ref');
function Wrapper() {
return
;
}
render(
, scratch, scratch.firstChild);
expect(ref).to.have.been.calledOnce.and.calledWith(scratch.firstChild.firstChild);
});
});