Skip to content

Commit

Permalink
Merge 947c215 into f5a877d
Browse files Browse the repository at this point in the history
  • Loading branch information
JoviDeCroock committed Sep 10, 2019
2 parents f5a877d + 947c215 commit 23d6c40
Show file tree
Hide file tree
Showing 11 changed files with 91 additions and 9 deletions.
1 change: 1 addition & 0 deletions compat/test/browser/component.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ describe('components', () => {

let a = React.render(<Parent />, scratch);
a.forceUpdate();
rerender();

expect(props).to.exist.and.deep.equal({
children: 'second'
Expand Down
33 changes: 26 additions & 7 deletions src/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,27 @@ Component.prototype.setState = function(update, callback) {
}
};

const cQ = [];
function processCQ() {
let p;
while ((p=cQ.shift())) p();
}
const queueCommit = (cb) => {
cQ.push(cb);
(options.debounceRendering || defer)(processCQ);
};

const commit = (c, parentDom, vnode, force, oldDom, callback) => {
let mounts = [];
let newDom = diff(parentDom, vnode, assign({}, vnode), c._context, parentDom.ownerSVGElement !== undefined, null, mounts, force, oldDom == null ? getDomSibling(vnode) : oldDom);
commitRoot(mounts, vnode);

if (newDom != oldDom) {
updateParentDomPointers(vnode);
}
if (callback) callback();
};

/**
* Immediately perform a synchronous re-render of the component
* @param {() => void} [callback] A function to be called after component is
Expand All @@ -68,15 +89,13 @@ Component.prototype.forceUpdate = function(callback) {
// shouldComponentUpdate
const force = callback!==false;

let mounts = [];
let newDom = diff(parentDom, vnode, assign({}, vnode), this._context, parentDom.ownerSVGElement!==undefined, null, mounts, force, oldDom == null ? getDomSibling(vnode) : oldDom);
commitRoot(mounts, vnode);

if (newDom != oldDom) {
updateParentDomPointers(vnode);
if (!force) {
commit(this, parentDom, vnode, force, oldDom, callback);
}
else {
queueCommit(() => commit(this, parentDom, vnode, force, oldDom, callback));
}
}
if (callback) callback();
};

/**
Expand Down
8 changes: 8 additions & 0 deletions test/browser/components.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -533,14 +533,17 @@ describe('Components', () => {

comp.setState({ alt: true });
comp.forceUpdate();
rerender();
expect(scratch.innerHTML, 'switching to textnode').to.equal('asdf');

comp.setState({ alt: false });
comp.forceUpdate();
rerender();
expect(scratch.innerHTML, 'switching to element').to.equal('<div>test</div>');

comp.setState({ alt: true });
comp.forceUpdate();
rerender();
expect(scratch.innerHTML, 'switching to textnode 2').to.equal('asdf');
});

Expand Down Expand Up @@ -1264,6 +1267,7 @@ describe('Components', () => {

outer.setState({ child: Inner2 });
outer.forceUpdate();
rerender();

expect(Inner2.prototype.render).to.have.been.calledOnce;

Expand All @@ -1278,6 +1282,7 @@ describe('Components', () => {
expect(Inner2.prototype.componentWillUnmount, 'inner2 swap').not.to.have.been.called;

inner2.forceUpdate();
rerender();

expect(Inner2.prototype.render, 'inner2 update').to.have.been.calledTwice;
expect(Inner2.prototype.componentWillMount, 'inner2 update').to.have.been.calledOnce;
Expand Down Expand Up @@ -1518,11 +1523,13 @@ describe('Components', () => {
expect(child._vnode._dom).to.equalNode(child.base);

app.forceUpdate();
rerender();
expect(child._vnode._dom).to.equalNode(child.base);

parent.setState({});
condition = true;
child.forceUpdate();
rerender();
expect(child._vnode._dom).to.equalNode(child.base);
rerender();

Expand All @@ -1540,6 +1547,7 @@ describe('Components', () => {
class App extends Component {
componentWillReceiveProps() {
this.forceUpdate();
rerender();
}
render() {
if (i++==0) return <div>foo</div>;
Expand Down
3 changes: 3 additions & 0 deletions test/browser/lifecycles/componentDidCatch.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ describe('Lifecycle methods', () => {

render(<Receiver><ThrowErr /></Receiver>, scratch);
receiver.forceUpdate();
rerender();

expect(Receiver.prototype.componentDidCatch).to.have.been.calledWith(expectedError);
});
Expand All @@ -157,6 +158,7 @@ describe('Lifecycle methods', () => {
render(<Receiver><ThrowErr /></Receiver>, scratch);

receiver.forceUpdate();
rerender();
expect(Receiver.prototype.componentDidCatch).to.have.been.calledWith(expectedError);
});

Expand All @@ -166,6 +168,7 @@ describe('Lifecycle methods', () => {
render(<Receiver><ThrowErr /></Receiver>, scratch);

receiver.forceUpdate();
rerender();
expect(Receiver.prototype.componentDidCatch).to.have.been.calledWith(expectedError);
});

Expand Down
1 change: 1 addition & 0 deletions test/browser/lifecycles/componentWillReceiveProps.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ describe('Lifecycle methods', () => {
spyInner.resetHistory();

c.forceUpdate();
rerender();
expect(spy).to.not.be.called;
expect(spyInner).to.be.calledOnce;
});
Expand Down
3 changes: 3 additions & 0 deletions test/browser/lifecycles/getDerivedStateFromError.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ describe('Lifecycle methods', () => {

render(<Receiver><ThrowErr /></Receiver>, scratch);
receiver.forceUpdate();
rerender();

expect(Receiver.getDerivedStateFromError).to.have.been.calledWith(expectedError);
});
Expand All @@ -161,6 +162,7 @@ describe('Lifecycle methods', () => {
render(<Receiver><ThrowErr /></Receiver>, scratch);

receiver.forceUpdate();
rerender();
expect(Receiver.getDerivedStateFromError).to.have.been.calledWith(expectedError);
});

Expand All @@ -170,6 +172,7 @@ describe('Lifecycle methods', () => {
render(<Receiver><ThrowErr /></Receiver>, scratch);

receiver.forceUpdate();
rerender();
expect(Receiver.getDerivedStateFromError).to.have.been.calledWith(expectedError);
});

Expand Down
2 changes: 2 additions & 0 deletions test/browser/lifecycles/lifecycle.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,7 @@ describe('Lifecycle methods', () => {
setState = s => {
this.setState(s);
this.forceUpdate();
rerender();
};
}
componentWillMount() {
Expand Down Expand Up @@ -573,6 +574,7 @@ describe('Lifecycle methods', () => {
for (let i=0; i<20; i++) {
app.setState({ page: i%components.length });
app.forceUpdate();
rerender();
}
});
});
Expand Down
1 change: 1 addition & 0 deletions test/browser/lifecycles/shouldComponentUpdate.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ describe('Lifecycle methods', () => {

render(<Foo />, scratch);
Comp.forceUpdate();
rerender();

expect(Foo.prototype.shouldComponentUpdate).to.not.have.been.called;
expect(Foo.prototype.render).to.have.been.calledTwice;
Expand Down
2 changes: 2 additions & 0 deletions test/browser/refs.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,15 @@ describe('refs', () => {
outer.resetHistory();
inner.resetHistory();
update();
rerender();

expect(outer, 're-render').not.to.have.been.called;
expect(inner, 're-render').not.to.have.been.called;

inner.resetHistory();
InnermostComponent = 'x-span';
update();
rerender();

expect(inner, 're-render swap');
expect(inner.firstCall, 're-render swap').to.have.been.calledWith(null);
Expand Down
5 changes: 5 additions & 0 deletions test/browser/render.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,7 @@ describe('render()', () => {

// Re-render
thing.forceUpdate();
rerender();

expect(firstInnerHTMLChild).to.equalNode(scratch.firstChild.firstChild);
});
Expand Down Expand Up @@ -915,6 +916,7 @@ describe('render()', () => {
checkbox.checked = false;

inputs.forceUpdate();
rerender();

expect(text.value).to.equal('Hello');
expect(checkbox.checked).to.equal(true);
Expand Down Expand Up @@ -974,8 +976,11 @@ describe('render()', () => {
render(<App />, scratch);

updateApp();
rerender();
updateParent();
rerender();
updateApp();
rerender();

// Without a fix it would render: `<div>foo</div><div></div>`
expect(scratch.innerHTML).to.equal('<div>foo</div>');
Expand Down
41 changes: 39 additions & 2 deletions test/browser/spec.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { setupRerender } from 'preact/test-utils';
import { createElement as h, render, Component } from '../../src/index';
import { createElement as h, render, Component, options } from '../../src/index';
import { setupScratch, teardown } from '../_util/helpers';
import { Fragment } from '../../src/create-element';

/** @jsx h */

Expand Down Expand Up @@ -91,6 +92,10 @@ describe('Component spec', () => {
});

describe('forceUpdate', () => {
beforeEach(() => {
delete options._commit;
});

it('should force a rerender', () => {
let forceUpdate;
class ForceUpdateComponent extends Component {
Expand All @@ -108,6 +113,7 @@ describe('Component spec', () => {
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;
Expand All @@ -118,7 +124,10 @@ describe('Component spec', () => {
let callback = sinon.spy();
class ForceUpdateComponent extends Component {
componentDidMount() {
forceUpdate = () => this.forceUpdate(callback);
forceUpdate = () => {
this.forceUpdate(callback);
rerender();
};
}
render() {
return <div />;
Expand All @@ -133,5 +142,33 @@ describe('Component spec', () => {
expect(ForceUpdateComponent.prototype.forceUpdate).to.have.been.calledWith(callback);
expect(callback).to.have.been.called;
});

it('should queue commits', () => {
let spy = sinon.spy();
options._commit = spy;

class Child extends Component {
componentDidMount() {
this.forceUpdate();
}

render() {
return <div>child</div>;
}
}

class App extends Component {
render() {
return <Child />;
}
}

render(<App />, scratch);
rerender();

expect(spy).to.be.calledTwice;
expect(spy.args[0][0]._component.constructor).to.equal(Fragment);
expect(spy.args[1][0]._component.constructor).to.equal(Child);
});
});
});

0 comments on commit 23d6c40

Please sign in to comment.