hello
+ > + ); + const A = sinon.fake(groggy(() => route('A'), 1)); + const B = sinon.fake(groggy(() => route('B'), 1)); + const C = sinon.fake(groggy(() =>hello
'); + expect(A).to.have.been.calledWith({ path: '/', query: {}, params: {}, rest: '' }); + + A.resetHistory(); + navigation.navigate('/b'); + + expect(scratch).to.have.property('innerHTML', 'hello
'); + expect(A).not.to.have.been.called; + + await sleep(1); + + expect(scratch).to.have.property('innerHTML', 'hello
'); + // We should never re-invoke while loading (that would be a remount of the old route): + expect(A).not.to.have.been.called; + expect(B).to.have.been.calledWith({ path: '/b', query: {}, params: {}, rest: '' }); + + B.resetHistory(); + await sleep(10); + + expect(scratch).to.have.property('innerHTML', 'hello
'); + expect(B).to.have.been.calledOnce; + expect(B).to.have.been.calledWith({ path: '/b', query: {}, params: {}, rest: '' }); + + B.resetHistory(); + navigation.navigate('/c'); + navigation.navigate('/c?1'); + navigation.navigate('/c'); + + expect(scratch).to.have.property('innerHTML', 'hello
'); + expect(B).not.to.have.been.called; + + await sleep(1); + + navigation.navigate('/c'); + navigation.navigate('/c?2'); + navigation.navigate('/c'); + + expect(scratch).to.have.property('innerHTML', 'hello
'); + // We should never re-invoke while loadinghello
'); + expect(C).not.to.have.been.called; + expect(B).to.have.been.calledOnce; + expect(B).to.have.been.calledWith({ path: '/b', query: {}, params: {}, rest: '' }); + + A.resetHistory(); + B.resetHistory(); + navigation.navigate('/'); + await sleep(1); + + expect(scratch).to.have.property('innerHTML', 'hello
'); + expect(B).not.to.have.been.called; + expect(A).to.have.been.calledOnce; + expect(A).to.have.been.calledWith({ path: '/', query: {}, params: {}, rest: '' }); + }); + + it('rerenders same-component routes rather than swap', async () => { + const A = sinon.fake(() =>hello
+ > + ); + const A = sinon.fake(groggy(() => route('A'), 1)); + const loadStart = sinon.fake(); + const loadEnd = sinon.fake(); + const routeChange = sinon.fake(); + + render( +hello
'); + expect(A).to.have.been.calledWith({ path: '/', query: {}, params: {}, rest: '' }); + expect(loadStart).not.to.have.been.called; + expect(loadEnd).to.have.been.calledWith('/'); + expect(routeChange).not.to.have.been.called; + }); + + it('should support onLoadStart/onLoadEnd/onRouteChange w/ navigation', async () => { + const route = name => ( + <> +hello
+ > + ); + const A = sinon.fake(() => route('A')); + const B = sinon.fake(groggy(() => route('B'), 1)); + const loadStart = sinon.fake(); + const loadEnd = sinon.fake(); + const routeChange = sinon.fake(); + + render( +hello
'); + expect(loadStart).not.to.have.been.called; + expect(loadEnd).to.have.been.calledWith('/b'); + expect(routeChange).to.have.been.calledWith('/b'); + }); + + it('should only call onLoadEnd once upon promise flush', async () => { + const route = name => ( + <> +hello
+ > + ); + const A = sinon.fake(groggy(() => route('A'), 1)); + const loadEnd = sinon.fake(); + + /** @type {(string) => void} */ + let set; + + const App = () => { + set = useState('1')[1]; + return ( +hello
hello
+hello
hello