From 177d92e86398ab9beb519e6543eaa535e075ac52 Mon Sep 17 00:00:00 2001 From: James Garbutt <43081j@users.noreply.github.com> Date: Thu, 26 Jun 2025 10:24:05 +0100 Subject: [PATCH 1/2] test: migrate lifecycle tests to use vitest spies Last one for the browser tests! --- .../lifecycles/componentDidCatch.test.js | 157 ++++++++++-------- .../lifecycles/componentDidMount.test.js | 13 +- .../lifecycles/componentDidUpdate.test.js | 21 ++- .../lifecycles/componentWillMount.test.js | 6 +- .../componentWillReceiveProps.test.js | 82 ++++----- .../lifecycles/componentWillUnmount.test.js | 25 ++- .../lifecycles/componentWillUpdate.test.js | 27 +-- .../getDerivedStateFromError.test.js | 84 +++++----- .../getDerivedStateFromProps.test.js | 45 ++--- test/browser/lifecycles/lifecycle.test.js | 71 ++++---- .../lifecycles/shouldComponentUpdate.test.js | 48 +++--- 11 files changed, 307 insertions(+), 272 deletions(-) diff --git a/test/browser/lifecycles/componentDidCatch.test.js b/test/browser/lifecycles/componentDidCatch.test.js index 5e91a5240f..fa9949aca0 100644 --- a/test/browser/lifecycles/componentDidCatch.test.js +++ b/test/browser/lifecycles/componentDidCatch.test.js @@ -1,6 +1,7 @@ import { setupRerender } from 'preact/test-utils'; import { createElement, render, Component, Fragment } from 'preact'; import { setupScratch, teardown } from '../../_util/helpers'; +import { vi } from 'vitest'; /** @jsx createElement */ @@ -42,8 +43,8 @@ describe('Lifecycle methods', () => { let thrower; - sinon.spy(Receiver.prototype, 'componentDidCatch'); - sinon.spy(Receiver.prototype, 'render'); + vi.spyOn(Receiver.prototype, 'componentDidCatch'); + vi.spyOn(Receiver.prototype, 'render'); function throwExpectedError() { throw (expectedError = new Error('Error!')); @@ -63,19 +64,19 @@ describe('Lifecycle methods', () => { return
ThrowErr: componentDidCatch
; } }; - sinon.spy(ThrowErr.prototype, 'componentDidCatch'); + vi.spyOn(ThrowErr.prototype, 'componentDidCatch'); expectedError = undefined; - Receiver.prototype.componentDidCatch.resetHistory(); - Receiver.prototype.render.resetHistory(); + Receiver.prototype.componentDidCatch.mockClear(); + Receiver.prototype.render.mockClear(); }); afterEach(() => { expect( ThrowErr.prototype.componentDidCatch, "Throwing component should not catch it's own error." - ).to.not.be.called; + ).not.toHaveBeenCalled(); thrower = undefined; }); @@ -101,8 +102,9 @@ describe('Lifecycle methods', () => { ); rerender(); - expect(Receiver.prototype.componentDidCatch).to.have.been.calledWith( - expectedError + expect(Receiver.prototype.componentDidCatch).toHaveBeenCalledWith( + expectedError, + expect.anything() ); }); @@ -136,8 +138,9 @@ describe('Lifecycle methods', () => { , scratch ); - expect(Receiver.prototype.componentDidCatch).to.have.been.calledWith( - expectedError + expect(Receiver.prototype.componentDidCatch).toHaveBeenCalledWith( + expectedError, + expect.anything() ); }); @@ -150,8 +153,9 @@ describe('Lifecycle methods', () => { , scratch ); - expect(Receiver.prototype.componentDidCatch).to.have.been.calledWith( - expectedError + expect(Receiver.prototype.componentDidCatch).toHaveBeenCalledWith( + expectedError, + expect.anything() ); }); @@ -164,15 +168,16 @@ describe('Lifecycle methods', () => { , scratch ); - expect(Receiver.prototype.componentDidCatch).to.have.been.calledWith( - expectedError + expect(Receiver.prototype.componentDidCatch).toHaveBeenCalledWith( + expectedError, + expect.anything() ); }); it('should be called when child fails in getDerivedStateFromProps', () => { ThrowErr.getDerivedStateFromProps = throwExpectedError; - sinon.spy(ThrowErr.prototype, 'render'); + vi.spyOn(ThrowErr.prototype, 'render'); render( @@ -180,10 +185,11 @@ describe('Lifecycle methods', () => { scratch ); - expect(Receiver.prototype.componentDidCatch).to.have.been.calledWith( - expectedError + expect(Receiver.prototype.componentDidCatch).toHaveBeenCalledWith( + expectedError, + expect.anything() ); - expect(ThrowErr.prototype.render).not.to.have.been.called; + expect(ThrowErr.prototype.render).not.toHaveBeenCalled(); }); it('should be called when child fails in getSnapshotBeforeUpdate', () => { @@ -198,8 +204,9 @@ describe('Lifecycle methods', () => { thrower.forceUpdate(); rerender(); - expect(Receiver.prototype.componentDidCatch).to.have.been.calledWith( - expectedError + expect(Receiver.prototype.componentDidCatch).toHaveBeenCalledWith( + expectedError, + expect.anything() ); }); @@ -215,8 +222,9 @@ describe('Lifecycle methods', () => { thrower.forceUpdate(); rerender(); - expect(Receiver.prototype.componentDidCatch).to.have.been.calledWith( - expectedError + expect(Receiver.prototype.componentDidCatch).toHaveBeenCalledWith( + expectedError, + expect.anything() ); }); @@ -232,8 +240,9 @@ describe('Lifecycle methods', () => { thrower.forceUpdate(); rerender(); - expect(Receiver.prototype.componentDidCatch).to.have.been.calledWith( - expectedError + expect(Receiver.prototype.componentDidCatch).toHaveBeenCalledWith( + expectedError, + expect.anything() ); }); @@ -259,14 +268,15 @@ describe('Lifecycle methods', () => { } } - sinon.spy(Receiver.prototype, 'componentDidCatch'); + vi.spyOn(Receiver.prototype, 'componentDidCatch'); render(, scratch); receiver.setState({ foo: 'baz' }); rerender(); - expect(Receiver.prototype.componentDidCatch).to.have.been.calledWith( - expectedError + expect(Receiver.prototype.componentDidCatch).toHaveBeenCalledWith( + expectedError, + expect.anything() ); }); @@ -292,14 +302,15 @@ describe('Lifecycle methods', () => { } } - sinon.spy(Receiver.prototype, 'componentDidCatch'); + vi.spyOn(Receiver.prototype, 'componentDidCatch'); render(, scratch); receiver.setState({ foo: 'baz' }); rerender(); - expect(Receiver.prototype.componentDidCatch).to.have.been.calledWith( - expectedError + expect(Receiver.prototype.componentDidCatch).toHaveBeenCalledWith( + expectedError, + expect.anything() ); }); @@ -318,8 +329,9 @@ describe('Lifecycle methods', () => { , scratch ); - expect(Receiver.prototype.componentDidCatch).to.have.been.calledWith( - expectedError + expect(Receiver.prototype.componentDidCatch).toHaveBeenCalledWith( + expectedError, + expect.anything() ); }); @@ -347,10 +359,11 @@ describe('Lifecycle methods', () => { } } - sinon.spy(Receiver.prototype, 'componentDidCatch'); + vi.spyOn(Receiver.prototype, 'componentDidCatch'); render(, scratch); - expect(Receiver.prototype.componentDidCatch).to.have.been.calledWith( - expectedError + expect(Receiver.prototype.componentDidCatch).toHaveBeenCalledWith( + expectedError, + expect.anything() ); }); @@ -376,10 +389,11 @@ describe('Lifecycle methods', () => { } } - sinon.spy(Receiver.prototype, 'componentDidCatch'); + vi.spyOn(Receiver.prototype, 'componentDidCatch'); render(, scratch); - expect(Receiver.prototype.componentDidCatch).to.have.been.calledWith( - expectedError + expect(Receiver.prototype.componentDidCatch).toHaveBeenCalledWith( + expectedError, + expect.anything() ); }); @@ -404,8 +418,10 @@ describe('Lifecycle methods', () => { , scratch ); - expect(Receiver.prototype.componentDidCatch).to.have.been.calledOnceWith( - expectedError + expect(Receiver.prototype.componentDidCatch).toHaveBeenCalledOnce(); + expect(Receiver.prototype.componentDidCatch).toHaveBeenCalledWith( + expectedError, + expect.anything() ); }); @@ -420,8 +436,9 @@ describe('Lifecycle methods', () => { , scratch ); - expect(Receiver.prototype.componentDidCatch).to.have.been.calledWith( - expectedError + expect(Receiver.prototype.componentDidCatch).toHaveBeenCalledWith( + expectedError, + expect.anything() ); }); @@ -438,8 +455,9 @@ describe('Lifecycle methods', () => { , scratch ); - expect(Receiver.prototype.componentDidCatch).to.have.been.calledWith( - expectedError + expect(Receiver.prototype.componentDidCatch).toHaveBeenCalledWith( + expectedError, + expect.anything() ); }); @@ -481,7 +499,7 @@ describe('Lifecycle methods', () => { throwExpectedError(); } - sinon.spy(Adapter.prototype, 'componentDidCatch'); + vi.spyOn(Adapter.prototype, 'componentDidCatch'); render( @@ -491,11 +509,13 @@ describe('Lifecycle methods', () => { scratch ); - expect(Adapter.prototype.componentDidCatch).to.have.been.calledWith( - expectedError + expect(Adapter.prototype.componentDidCatch).toHaveBeenCalledWith( + expectedError, + expect.anything() ); - expect(Receiver.prototype.componentDidCatch).to.have.been.calledWith( - adaptedError + expect(Receiver.prototype.componentDidCatch).toHaveBeenCalledWith( + adaptedError, + expect.anything() ); rerender(); @@ -521,7 +541,7 @@ describe('Lifecycle methods', () => { throwExpectedError(); } - sinon.spy(Adapter.prototype, 'componentDidCatch'); + vi.spyOn(Adapter.prototype, 'componentDidCatch'); render( @@ -533,11 +553,13 @@ describe('Lifecycle methods', () => { ); rerender(); - expect(Adapter.prototype.componentDidCatch).to.have.been.calledWith( - expectedError + expect(Adapter.prototype.componentDidCatch).toHaveBeenCalledWith( + expectedError, + expect.anything() ); - expect(Receiver.prototype.componentDidCatch).to.have.been.calledWith( - expectedError + expect(Receiver.prototype.componentDidCatch).toHaveBeenCalledWith( + expectedError, + expect.anything() ); expect(scratch).to.have.property('textContent', 'Error: Error!'); }); @@ -556,7 +578,7 @@ describe('Lifecycle methods', () => { throw new Error('Error!'); } - sinon.spy(Adapter.prototype, 'componentDidCatch'); + vi.spyOn(Adapter.prototype, 'componentDidCatch'); render( @@ -568,10 +590,8 @@ describe('Lifecycle methods', () => { ); rerender(); - expect(Adapter.prototype.componentDidCatch, 'Adapter').to.have.been - .called; - expect(Receiver.prototype.componentDidCatch, 'Receiver').to.have.been - .called; + expect(Adapter.prototype.componentDidCatch).toHaveBeenCalled(); + expect(Receiver.prototype.componentDidCatch).toHaveBeenCalled(); expect(scratch).to.have.property('textContent', 'Error: Error!'); }); @@ -595,7 +615,7 @@ describe('Lifecycle methods', () => { throwExpectedError(); } - sinon.spy(TopReceiver.prototype, 'componentDidCatch'); + vi.spyOn(TopReceiver.prototype, 'componentDidCatch'); render( @@ -607,9 +627,10 @@ describe('Lifecycle methods', () => { ); rerender(); - expect(TopReceiver.prototype.componentDidCatch).not.to.have.been.called; - expect(Receiver.prototype.componentDidCatch).to.have.been.calledWith( - expectedError + expect(TopReceiver.prototype.componentDidCatch).not.toHaveBeenCalled(); + expect(Receiver.prototype.componentDidCatch).toHaveBeenCalledWith( + expectedError, + expect.anything() ); expect(scratch).to.have.property('textContent', 'Error: Error!'); }); @@ -624,8 +645,9 @@ describe('Lifecycle methods', () => { , scratch ); - expect(Receiver.prototype.componentDidCatch).to.have.been.calledWith( - expectedError + expect(Receiver.prototype.componentDidCatch).toHaveBeenCalledWith( + expectedError, + expect.anything() ); }); @@ -646,8 +668,9 @@ describe('Lifecycle methods', () => { , scratch ); - expect(Receiver.prototype.componentDidCatch).to.have.been.calledWith( - expectedError + expect(Receiver.prototype.componentDidCatch).toHaveBeenCalledWith( + expectedError, + expect.anything() ); }); diff --git a/test/browser/lifecycles/componentDidMount.test.js b/test/browser/lifecycles/componentDidMount.test.js index 8ca136bfe5..52ec460e11 100644 --- a/test/browser/lifecycles/componentDidMount.test.js +++ b/test/browser/lifecycles/componentDidMount.test.js @@ -1,6 +1,7 @@ import { createElement, render, Component } from 'preact'; import { setupRerender } from 'preact/test-utils'; import { setupScratch, teardown } from '../../_util/helpers'; +import { vi } from 'vitest'; /** @jsx createElement */ @@ -20,11 +21,12 @@ describe('Lifecycle methods', () => { describe('#componentDidMount', () => { it('is invoked after refs are set', () => { - const spy = sinon.spy(); + const spy = vi.fn(); class App extends Component { componentDidMount() { - expect(spy).to.have.been.calledOnceWith(scratch.firstChild); + expect(spy).toHaveBeenCalledOnce(); + expect(spy).toHaveBeenCalledWith(scratch.firstChild); } render() { @@ -33,11 +35,12 @@ describe('Lifecycle methods', () => { } render(, scratch); - expect(spy).to.have.been.calledOnceWith(scratch.firstChild); + expect(spy).toHaveBeenCalledOnce(); + expect(spy).toHaveBeenCalledWith(scratch.firstChild); }); it('supports multiple setState callbacks', () => { - const spy = sinon.spy(); + const spy = vi.fn(); class App extends Component { constructor(props) { @@ -60,7 +63,7 @@ describe('Lifecycle methods', () => { render(, scratch); rerender(); - expect(spy).to.have.been.calledTwice; + expect(spy).toHaveBeenCalledTimes(2); }); }); }); diff --git a/test/browser/lifecycles/componentDidUpdate.test.js b/test/browser/lifecycles/componentDidUpdate.test.js index 3f6658b283..5b0f9e7d5c 100644 --- a/test/browser/lifecycles/componentDidUpdate.test.js +++ b/test/browser/lifecycles/componentDidUpdate.test.js @@ -1,6 +1,7 @@ import { setupRerender } from 'preact/test-utils'; import { createElement, render, Component } from 'preact'; import { setupScratch, teardown } from '../../_util/helpers'; +import { vi } from 'vitest'; /** @jsx createElement */ @@ -103,7 +104,7 @@ describe('Lifecycle methods', () => { }); it('cDU should not be called when sDU returned false', () => { - let spy = sinon.spy(); + let spy = vi.fn(); let c; class App extends Component { @@ -125,7 +126,7 @@ describe('Lifecycle methods', () => { c.setState({}); rerender(); - expect(spy).to.not.be.called; + expect(spy).not.toHaveBeenCalled(); }); it("prevState argument should be the same object if state doesn't change", () => { @@ -269,13 +270,14 @@ describe('Lifecycle methods', () => { }); it('is invoked after refs are set', () => { - const spy = sinon.spy(); + const spy = vi.fn(); let inst; let i = 0; class App extends Component { componentDidUpdate() { - expect(spy).to.have.been.calledOnceWith(scratch.firstChild); + expect(spy).toHaveBeenCalledOnce(); + expect(spy).toHaveBeenCalledWith(scratch.firstChild); } render() { @@ -293,12 +295,13 @@ describe('Lifecycle methods', () => { } render(, scratch); - expect(spy).not.to.have.been.called; + expect(spy).not.toHaveBeenCalled(); inst.setState({}); rerender(); - expect(spy).to.have.been.calledOnceWith(scratch.firstChild); + expect(spy).toHaveBeenCalledOnce(); + expect(spy).toHaveBeenCalledWith(scratch.firstChild); }); it('should be called after children are mounted', () => { @@ -367,18 +370,18 @@ describe('Lifecycle methods', () => { } } - sinon.spy(Inner.prototype, 'componentDidUpdate'); + vi.spyOn(Inner.prototype, 'componentDidUpdate'); // Initial render render(, scratch); - expect(Inner.prototype.componentDidUpdate).to.not.have.been.called; + expect(Inner.prototype.componentDidUpdate).not.toHaveBeenCalled(); // Set state with a new i const newValue = 5; setValue(newValue); rerender(); - expect(Inner.prototype.componentDidUpdate).to.have.been.called; + expect(Inner.prototype.componentDidUpdate).toHaveBeenCalled(); expect(outerChildText).to.equal(`Outer: ${newValue.toString()}`); }); diff --git a/test/browser/lifecycles/componentWillMount.test.js b/test/browser/lifecycles/componentWillMount.test.js index 27b5c91212..4e85032ee7 100644 --- a/test/browser/lifecycles/componentWillMount.test.js +++ b/test/browser/lifecycles/componentWillMount.test.js @@ -47,7 +47,7 @@ describe('Lifecycle methods', () => { it('should invoke setState callbacks when setState is called in componentWillMount', () => { let componentState; - let callback = sinon.spy(); + let callback = vi.fn(); class Foo extends Component { constructor(props) { @@ -72,12 +72,12 @@ describe('Lifecycle methods', () => { render(, scratch); expect(componentState).to.deep.equal({ value: 2 }); - expect(callback).to.have.been.calledTwice; + expect(callback).toHaveBeenCalledTimes(2); rerender(); expect(componentState).to.deep.equal({ value: 3 }); - expect(callback).to.have.been.calledThrice; + expect(callback).toHaveBeenCalledTimes(3); }); }); }); diff --git a/test/browser/lifecycles/componentWillReceiveProps.test.js b/test/browser/lifecycles/componentWillReceiveProps.test.js index 0e10b9bbcb..7c5f7d171a 100644 --- a/test/browser/lifecycles/componentWillReceiveProps.test.js +++ b/test/browser/lifecycles/componentWillReceiveProps.test.js @@ -1,6 +1,7 @@ import { setupRerender } from 'preact/test-utils'; import { createElement, render, Component } from 'preact'; import { setupScratch, teardown } from '../../_util/helpers'; +import { vi } from 'vitest'; /** @jsx createElement */ @@ -92,16 +93,17 @@ describe('Lifecycle methods', () => { return
; } } - sinon.spy(ReceivePropsComponent.prototype, 'componentWillReceiveProps'); + vi.spyOn(ReceivePropsComponent.prototype, 'componentWillReceiveProps'); render(, scratch); - expect(ReceivePropsComponent.prototype.componentWillReceiveProps).not.to - .have.been.called; + expect( + ReceivePropsComponent.prototype.componentWillReceiveProps + ).not.toHaveBeenCalled(); }); // See last paragraph of cWRP section https://reactjs.org/docs/react-component.html#unsafe_componentwillreceiveprops it('should not be called on setState or forceUpdate', () => { - let spy = sinon.spy(); - let spyInner = sinon.spy(); + let spy = vi.fn(); + let spyInner = vi.fn(); let c; class Inner extends Component { @@ -130,19 +132,19 @@ describe('Lifecycle methods', () => { } render(, scratch); - expect(spy).to.not.be.called; + expect(spy).not.toHaveBeenCalled(); c.setState({}); rerender(); - expect(spy).to.not.be.called; - expect(spyInner).to.be.calledOnce; - spy.resetHistory(); - spyInner.resetHistory(); + expect(spy).not.toHaveBeenCalled(); + expect(spyInner).toHaveBeenCalledOnce(); + spy.mockClear(); + spyInner.mockClear(); c.forceUpdate(); rerender(); - expect(spy).to.not.be.called; - expect(spyInner).to.be.calledOnce; + expect(spy).not.toHaveBeenCalled(); + expect(spyInner).toHaveBeenCalledOnce(); }); it('should be called when rerender with new props from parent', () => { @@ -170,23 +172,23 @@ describe('Lifecycle methods', () => { return
; } } - sinon.spy(Inner.prototype, 'componentWillReceiveProps'); - sinon.spy(Outer.prototype, 'componentDidMount'); + vi.spyOn(Inner.prototype, 'componentWillReceiveProps'); + vi.spyOn(Outer.prototype, 'componentDidMount'); // Initial render render(, scratch); - expect(Inner.prototype.componentWillReceiveProps).not.to.have.been.called; + expect(Inner.prototype.componentWillReceiveProps).not.toHaveBeenCalled(); // Rerender inner with new props doRender(); rerender(); - expect(Inner.prototype.componentWillReceiveProps).to.have.been.called; + expect(Inner.prototype.componentWillReceiveProps).toHaveBeenCalled(); }); it('should be called when rerender with new props from parent even with setState/forceUpdate in child', () => { let setStateAndUpdateProps; let forceUpdateAndUpdateProps; - let cWRPSpy = sinon.spy(); + let cWRPSpy = vi.fn(); class Outer extends Component { constructor(p, c) { @@ -223,17 +225,17 @@ describe('Lifecycle methods', () => { } // Initial render render(, scratch); - expect(cWRPSpy).not.to.have.been.called; + expect(cWRPSpy).not.toHaveBeenCalled(); // setState in inner component and update with new props setStateAndUpdateProps(); rerender(); - expect(cWRPSpy).to.have.been.calledWith(1); + expect(cWRPSpy).toHaveBeenCalledWith(1); // forceUpdate in inner component and update with new props forceUpdateAndUpdateProps(); rerender(); - expect(cWRPSpy).to.have.been.calledWith(2); + expect(cWRPSpy).toHaveBeenCalledWith(2); }); it('should be called in right execution order', () => { @@ -252,43 +254,43 @@ describe('Lifecycle methods', () => { } class Inner extends Component { componentDidUpdate() { - expect(Inner.prototype.componentWillReceiveProps).to.have.been.called; - expect(Inner.prototype.componentWillUpdate).to.have.been.called; + expect(Inner.prototype.componentWillReceiveProps).toHaveBeenCalled(); + expect(Inner.prototype.componentWillUpdate).toHaveBeenCalled(); } componentWillReceiveProps() { - expect(Inner.prototype.componentWillUpdate).not.to.have.been.called; - expect(Inner.prototype.componentDidUpdate).not.to.have.been.called; + expect(Inner.prototype.componentWillUpdate).not.toHaveBeenCalled(); + expect(Inner.prototype.componentDidUpdate).not.toHaveBeenCalled(); } componentWillUpdate() { - expect(Inner.prototype.componentWillReceiveProps).to.have.been.called; - expect(Inner.prototype.componentDidUpdate).not.to.have.been.called; + expect(Inner.prototype.componentWillReceiveProps).toHaveBeenCalled(); + expect(Inner.prototype.componentDidUpdate).not.toHaveBeenCalled(); } shouldComponentUpdate() { - expect(Inner.prototype.componentWillReceiveProps).to.have.been.called; - expect(Inner.prototype.componentWillUpdate).not.to.have.been.called; + expect(Inner.prototype.componentWillReceiveProps).toHaveBeenCalled(); + expect(Inner.prototype.componentWillUpdate).not.toHaveBeenCalled(); return true; } render() { return
; } } - sinon.spy(Inner.prototype, 'componentWillReceiveProps'); - sinon.spy(Inner.prototype, 'componentDidUpdate'); - sinon.spy(Inner.prototype, 'componentWillUpdate'); - sinon.spy(Inner.prototype, 'shouldComponentUpdate'); - sinon.spy(Outer.prototype, 'componentDidMount'); + vi.spyOn(Inner.prototype, 'componentWillReceiveProps'); + vi.spyOn(Inner.prototype, 'componentDidUpdate'); + vi.spyOn(Inner.prototype, 'componentWillUpdate'); + vi.spyOn(Inner.prototype, 'shouldComponentUpdate'); + vi.spyOn(Outer.prototype, 'componentDidMount'); render(, scratch); doRender(); rerender(); - expect( - Inner.prototype.componentWillReceiveProps - ).to.have.been.calledBefore(Inner.prototype.componentWillUpdate); - expect( - Inner.prototype.componentWillReceiveProps - ).to.have.been.calledBefore(Inner.prototype.shouldComponentUpdate); - expect(Inner.prototype.componentWillUpdate).to.have.been.calledBefore( + expect(Inner.prototype.componentWillReceiveProps).toHaveBeenCalledBefore( + Inner.prototype.componentWillUpdate + ); + expect(Inner.prototype.componentWillReceiveProps).toHaveBeenCalledBefore( + Inner.prototype.shouldComponentUpdate + ); + expect(Inner.prototype.componentWillUpdate).toHaveBeenCalledBefore( Inner.prototype.componentDidUpdate ); }); diff --git a/test/browser/lifecycles/componentWillUnmount.test.js b/test/browser/lifecycles/componentWillUnmount.test.js index 5aa0a841fb..5ba6bc08f5 100644 --- a/test/browser/lifecycles/componentWillUnmount.test.js +++ b/test/browser/lifecycles/componentWillUnmount.test.js @@ -1,5 +1,6 @@ import { createElement, render, Component } from 'preact'; import { setupScratch, teardown } from '../../_util/helpers'; +import { vi } from 'vitest'; /** @jsx createElement */ @@ -31,27 +32,23 @@ describe('Lifecycle methods', () => { return 'bar'; } } - sinon.spy(Foo.prototype, 'componentDidMount'); - sinon.spy(Foo.prototype, 'componentWillUnmount'); - sinon.spy(Foo.prototype, 'render'); + vi.spyOn(Foo.prototype, 'componentDidMount'); + vi.spyOn(Foo.prototype, 'componentWillUnmount'); + vi.spyOn(Foo.prototype, 'render'); - sinon.spy(Bar.prototype, 'componentDidMount'); - sinon.spy(Bar.prototype, 'componentWillUnmount'); - sinon.spy(Bar.prototype, 'render'); + vi.spyOn(Bar.prototype, 'componentDidMount'); + vi.spyOn(Bar.prototype, 'componentWillUnmount'); + vi.spyOn(Bar.prototype, 'render'); render(, scratch); - expect(Foo.prototype.componentDidMount, 'initial render').to.have.been - .calledOnce; + expect(Foo.prototype.componentDidMount).toHaveBeenCalledOnce(); render(, scratch); - expect(Foo.prototype.componentWillUnmount, 'when replaced').to.have.been - .calledOnce; - expect(Bar.prototype.componentDidMount, 'when replaced').to.have.been - .calledOnce; + expect(Foo.prototype.componentWillUnmount).toHaveBeenCalledOnce(); + expect(Bar.prototype.componentDidMount).toHaveBeenCalledOnce(); render(
, scratch); - expect(Bar.prototype.componentWillUnmount, 'when removed').to.have.been - .calledOnce; + expect(Bar.prototype.componentWillUnmount).toHaveBeenCalledOnce(); }); it('should only remove dom after componentWillUnmount was called', () => { diff --git a/test/browser/lifecycles/componentWillUpdate.test.js b/test/browser/lifecycles/componentWillUpdate.test.js index 73d8f1feb6..ca674bbe85 100644 --- a/test/browser/lifecycles/componentWillUpdate.test.js +++ b/test/browser/lifecycles/componentWillUpdate.test.js @@ -28,10 +28,11 @@ describe('Lifecycle methods', () => { return
; } } - sinon.spy(ReceivePropsComponent.prototype, 'componentWillUpdate'); + vi.spyOn(ReceivePropsComponent.prototype, 'componentWillUpdate'); render(, scratch); - expect(ReceivePropsComponent.prototype.componentWillUpdate).not.to.have - .been.called; + expect( + ReceivePropsComponent.prototype.componentWillUpdate + ).not.toHaveBeenCalled(); }); it('should be called when rerender with new props from parent', () => { @@ -57,17 +58,17 @@ describe('Lifecycle methods', () => { return
; } } - sinon.spy(Inner.prototype, 'componentWillUpdate'); - sinon.spy(Outer.prototype, 'componentDidMount'); + vi.spyOn(Inner.prototype, 'componentWillUpdate'); + vi.spyOn(Outer.prototype, 'componentDidMount'); // Initial render render(, scratch); - expect(Inner.prototype.componentWillUpdate).not.to.have.been.called; + expect(Inner.prototype.componentWillUpdate).not.toHaveBeenCalled(); // Rerender inner with new props doRender(); rerender(); - expect(Inner.prototype.componentWillUpdate).to.have.been.called; + expect(Inner.prototype.componentWillUpdate).toHaveBeenCalled(); }); it('should be called on new state', () => { @@ -81,15 +82,17 @@ describe('Lifecycle methods', () => { return
; } } - sinon.spy(ReceivePropsComponent.prototype, 'componentWillUpdate'); + vi.spyOn(ReceivePropsComponent.prototype, 'componentWillUpdate'); render(, scratch); - expect(ReceivePropsComponent.prototype.componentWillUpdate).not.to.have - .been.called; + expect( + ReceivePropsComponent.prototype.componentWillUpdate + ).not.toHaveBeenCalled(); doRender(); rerender(); - expect(ReceivePropsComponent.prototype.componentWillUpdate).to.have.been - .called; + expect( + ReceivePropsComponent.prototype.componentWillUpdate + ).toHaveBeenCalled(); }); }); }); diff --git a/test/browser/lifecycles/getDerivedStateFromError.test.js b/test/browser/lifecycles/getDerivedStateFromError.test.js index 318cf983b8..ee6e15a644 100644 --- a/test/browser/lifecycles/getDerivedStateFromError.test.js +++ b/test/browser/lifecycles/getDerivedStateFromError.test.js @@ -1,6 +1,7 @@ import { setupRerender } from 'preact/test-utils'; import { createElement, render, Component } from 'preact'; import { setupScratch, teardown } from '../../_util/helpers'; +import { vi } from 'vitest'; /** @jsx createElement */ @@ -42,8 +43,8 @@ describe('Lifecycle methods', () => { } } - sinon.spy(Receiver, 'getDerivedStateFromError'); - sinon.spy(Receiver.prototype, 'render'); + vi.spyOn(Receiver, 'getDerivedStateFromError'); + vi.spyOn(Receiver.prototype, 'render'); function throwExpectedError() { throw (expectedError = new Error('Error!')); @@ -64,19 +65,19 @@ describe('Lifecycle methods', () => { return
ThrowErr: getDerivedStateFromError
; } }; - sinon.spy(ThrowErr, 'getDerivedStateFromError'); + vi.spyOn(ThrowErr, 'getDerivedStateFromError'); expectedError = undefined; - Receiver.getDerivedStateFromError.resetHistory(); - Receiver.prototype.render.resetHistory(); + Receiver.getDerivedStateFromError.mockClear(); + Receiver.prototype.render.mockClear(); }); afterEach(() => { expect( ThrowErr.getDerivedStateFromError, "Throwing component should not catch it's own error." - ).to.not.be.called; + ).not.toHaveBeenCalled(); thrower = undefined; }); @@ -103,7 +104,7 @@ describe('Lifecycle methods', () => { ); rerender(); - expect(Receiver.getDerivedStateFromError).to.have.been.calledWith( + expect(Receiver.getDerivedStateFromError).toHaveBeenCalledWith( expectedError ); }); @@ -138,7 +139,7 @@ describe('Lifecycle methods', () => { , scratch ); - expect(Receiver.getDerivedStateFromError).to.have.been.calledWith( + expect(Receiver.getDerivedStateFromError).toHaveBeenCalledWith( expectedError ); }); @@ -152,7 +153,7 @@ describe('Lifecycle methods', () => { , scratch ); - expect(Receiver.getDerivedStateFromError).to.have.been.calledWith( + expect(Receiver.getDerivedStateFromError).toHaveBeenCalledWith( expectedError ); }); @@ -166,7 +167,7 @@ describe('Lifecycle methods', () => { , scratch ); - expect(Receiver.getDerivedStateFromError).to.have.been.calledWith( + expect(Receiver.getDerivedStateFromError).toHaveBeenCalledWith( expectedError ); }); @@ -174,7 +175,7 @@ describe('Lifecycle methods', () => { it('should be called when child fails in getDerivedStateFromProps', () => { ThrowErr.getDerivedStateFromProps = throwExpectedError; - sinon.spy(ThrowErr.prototype, 'render'); + vi.spyOn(ThrowErr.prototype, 'render'); render( @@ -182,10 +183,10 @@ describe('Lifecycle methods', () => { scratch ); - expect(Receiver.getDerivedStateFromError).to.have.been.calledWith( + expect(Receiver.getDerivedStateFromError).toHaveBeenCalledWith( expectedError ); - expect(ThrowErr.prototype.render).not.to.have.been.called; + expect(ThrowErr.prototype.render).not.toHaveBeenCalled(); }); it('should be called when child fails in getSnapshotBeforeUpdate', () => { @@ -200,7 +201,7 @@ describe('Lifecycle methods', () => { thrower.forceUpdate(); rerender(); - expect(Receiver.getDerivedStateFromError).to.have.been.calledWith( + expect(Receiver.getDerivedStateFromError).toHaveBeenCalledWith( expectedError ); }); @@ -217,7 +218,7 @@ describe('Lifecycle methods', () => { thrower.forceUpdate(); rerender(); - expect(Receiver.getDerivedStateFromError).to.have.been.calledWith( + expect(Receiver.getDerivedStateFromError).toHaveBeenCalledWith( expectedError ); }); @@ -234,7 +235,7 @@ describe('Lifecycle methods', () => { thrower.forceUpdate(); rerender(); - expect(Receiver.getDerivedStateFromError).to.have.been.calledWith( + expect(Receiver.getDerivedStateFromError).toHaveBeenCalledWith( expectedError ); }); @@ -261,12 +262,12 @@ describe('Lifecycle methods', () => { } } - sinon.spy(Receiver, 'getDerivedStateFromError'); + vi.spyOn(Receiver, 'getDerivedStateFromError'); render(, scratch); receiver.setState({ foo: 'baz' }); rerender(); - expect(Receiver.getDerivedStateFromError).to.have.been.calledWith( + expect(Receiver.getDerivedStateFromError).toHaveBeenCalledWith( expectedError ); }); @@ -293,13 +294,13 @@ describe('Lifecycle methods', () => { } } - sinon.spy(Receiver, 'getDerivedStateFromError'); + vi.spyOn(Receiver, 'getDerivedStateFromError'); render(, scratch); receiver.setState({ foo: 'baz' }); rerender(); - expect(Receiver.getDerivedStateFromError).to.have.been.calledWith( + expect(Receiver.getDerivedStateFromError).toHaveBeenCalledWith( expectedError ); }); @@ -319,7 +320,7 @@ describe('Lifecycle methods', () => { , scratch ); - expect(Receiver.getDerivedStateFromError).to.have.been.calledWith( + expect(Receiver.getDerivedStateFromError).toHaveBeenCalledWith( expectedError ); }); @@ -348,9 +349,9 @@ describe('Lifecycle methods', () => { } } - sinon.spy(Receiver, 'getDerivedStateFromError'); + vi.spyOn(Receiver, 'getDerivedStateFromError'); render(, scratch); - expect(Receiver.getDerivedStateFromError).to.have.been.calledWith( + expect(Receiver.getDerivedStateFromError).toHaveBeenCalledWith( expectedError ); }); @@ -377,14 +378,14 @@ describe('Lifecycle methods', () => { } } - sinon.spy(Receiver, 'getDerivedStateFromError'); + vi.spyOn(Receiver, 'getDerivedStateFromError'); render( , scratch ); - expect(Receiver.getDerivedStateFromError).to.have.been.calledWith( + expect(Receiver.getDerivedStateFromError).toHaveBeenCalledWith( expectedError ); }); @@ -410,7 +411,8 @@ describe('Lifecycle methods', () => { , scratch ); - expect(Receiver.getDerivedStateFromError).to.have.been.calledOnceWith( + expect(Receiver.getDerivedStateFromError).toHaveBeenCalledOnce(); + expect(Receiver.getDerivedStateFromError).toHaveBeenCalledWith( expectedError ); }); @@ -426,7 +428,7 @@ describe('Lifecycle methods', () => { , scratch ); - expect(Receiver.getDerivedStateFromError).to.have.been.calledWith( + expect(Receiver.getDerivedStateFromError).toHaveBeenCalledWith( expectedError ); }); @@ -469,7 +471,7 @@ describe('Lifecycle methods', () => { throwExpectedError(); } - sinon.spy(Adapter, 'getDerivedStateFromError'); + vi.spyOn(Adapter, 'getDerivedStateFromError'); render( @@ -479,10 +481,10 @@ describe('Lifecycle methods', () => { scratch ); - expect(Adapter.getDerivedStateFromError).to.have.been.calledWith( + expect(Adapter.getDerivedStateFromError).toHaveBeenCalledWith( expectedError ); - expect(Receiver.getDerivedStateFromError).to.have.been.calledWith( + expect(Receiver.getDerivedStateFromError).toHaveBeenCalledWith( adaptedError ); @@ -508,7 +510,7 @@ describe('Lifecycle methods', () => { throwExpectedError(); } - sinon.spy(Adapter, 'getDerivedStateFromError'); + vi.spyOn(Adapter, 'getDerivedStateFromError'); render( @@ -520,10 +522,10 @@ describe('Lifecycle methods', () => { ); rerender(); - expect(Adapter.getDerivedStateFromError).to.have.been.calledWith( + expect(Adapter.getDerivedStateFromError).toHaveBeenCalledWith( expectedError ); - expect(Receiver.getDerivedStateFromError).to.have.been.calledWith( + expect(Receiver.getDerivedStateFromError).toHaveBeenCalledWith( expectedError ); expect(scratch).to.have.property('textContent', 'Error: Error!'); @@ -544,7 +546,7 @@ describe('Lifecycle methods', () => { throw new Error('Error!'); } - sinon.spy(Adapter, 'getDerivedStateFromError'); + vi.spyOn(Adapter, 'getDerivedStateFromError'); render( @@ -556,8 +558,8 @@ describe('Lifecycle methods', () => { ); rerender(); - expect(Adapter.getDerivedStateFromError).to.have.been.called; - expect(Receiver.getDerivedStateFromError).to.have.been.called; + expect(Adapter.getDerivedStateFromError).toHaveBeenCalled(); + expect(Receiver.getDerivedStateFromError).toHaveBeenCalled(); expect(scratch).to.have.property('textContent', 'Error: Error!'); }); @@ -581,7 +583,7 @@ describe('Lifecycle methods', () => { throwExpectedError(); } - sinon.spy(TopReceiver, 'getDerivedStateFromError'); + vi.spyOn(TopReceiver, 'getDerivedStateFromError'); render( @@ -593,8 +595,8 @@ describe('Lifecycle methods', () => { ); rerender(); - expect(TopReceiver.getDerivedStateFromError).not.to.have.been.called; - expect(Receiver.getDerivedStateFromError).to.have.been.calledWith( + expect(TopReceiver.getDerivedStateFromError).not.toHaveBeenCalled(); + expect(Receiver.getDerivedStateFromError).toHaveBeenCalledWith( expectedError ); expect(scratch).to.have.property('textContent', 'Error: Error!'); @@ -611,7 +613,7 @@ describe('Lifecycle methods', () => { , scratch ); - expect(Receiver.getDerivedStateFromError).to.have.been.calledWith( + expect(Receiver.getDerivedStateFromError).toHaveBeenCalledWith( expectedError ); }); @@ -633,7 +635,7 @@ describe('Lifecycle methods', () => { , scratch ); - expect(Receiver.getDerivedStateFromError).to.have.been.calledWith( + expect(Receiver.getDerivedStateFromError).toHaveBeenCalledWith( expectedError ); }); diff --git a/test/browser/lifecycles/getDerivedStateFromProps.test.js b/test/browser/lifecycles/getDerivedStateFromProps.test.js index 0fa1394711..3b199dddc0 100644 --- a/test/browser/lifecycles/getDerivedStateFromProps.test.js +++ b/test/browser/lifecycles/getDerivedStateFromProps.test.js @@ -1,6 +1,7 @@ import { setupRerender } from 'preact/test-utils'; import { createElement, render, Component } from 'preact'; import { setupScratch, teardown } from '../../_util/helpers'; +import { vi } from 'vitest'; /** @jsx createElement */ @@ -85,21 +86,21 @@ describe('Lifecycle methods', () => { } } - sinon.spy(Foo, 'getDerivedStateFromProps'); - sinon.spy(Foo.prototype, 'componentDidMount'); - sinon.spy(Foo.prototype, 'componentDidUpdate'); + vi.spyOn(Foo, 'getDerivedStateFromProps'); + vi.spyOn(Foo.prototype, 'componentDidMount'); + vi.spyOn(Foo.prototype, 'componentDidUpdate'); render(, scratch); expect(scratch.firstChild.className).to.equal('initial'); - expect(Foo.getDerivedStateFromProps).to.have.callCount(1); - expect(Foo.prototype.componentDidMount).to.have.callCount(1); // verify mount occurred - expect(Foo.prototype.componentDidUpdate).to.have.callCount(0); + expect(Foo.getDerivedStateFromProps).toHaveBeenCalledTimes(1); + expect(Foo.prototype.componentDidMount).toHaveBeenCalledTimes(1); // verify mount occurred + expect(Foo.prototype.componentDidUpdate).toHaveBeenCalledTimes(0); render(, scratch); expect(scratch.firstChild.className).to.equal('updated'); - expect(Foo.getDerivedStateFromProps).to.have.callCount(2); - expect(Foo.prototype.componentDidMount).to.have.callCount(1); - expect(Foo.prototype.componentDidUpdate).to.have.callCount(1); // verify update occurred + expect(Foo.getDerivedStateFromProps).toHaveBeenCalledTimes(2); + expect(Foo.prototype.componentDidMount).toHaveBeenCalledTimes(1); + expect(Foo.prototype.componentDidUpdate).toHaveBeenCalledTimes(1); // verify update occurred }); it("should update the instance's state with the value returned from getDerivedStateFromProps when state changes", () => { @@ -129,15 +130,15 @@ describe('Lifecycle methods', () => { } } - sinon.spy(Foo, 'getDerivedStateFromProps'); + vi.spyOn(Foo, 'getDerivedStateFromProps'); render(, scratch); expect(scratch.firstChild.className).to.equal('initial'); - expect(Foo.getDerivedStateFromProps).to.have.been.calledOnce; + expect(Foo.getDerivedStateFromProps).toHaveBeenCalledTimes(1); rerender(); // call rerender to handle cDM setState call expect(scratch.firstChild.className).to.equal('updated derived'); - expect(Foo.getDerivedStateFromProps).to.have.been.calledTwice; + expect(Foo.getDerivedStateFromProps).toHaveBeenCalledTimes(2); }); it('should NOT modify state if null is returned', () => { @@ -157,11 +158,11 @@ describe('Lifecycle methods', () => { } } - sinon.spy(Foo, 'getDerivedStateFromProps'); + vi.spyOn(Foo, 'getDerivedStateFromProps'); render(, scratch); expect(scratch.firstChild.className).to.equal('foo bar'); - expect(Foo.getDerivedStateFromProps).to.have.been.called; + expect(Foo.getDerivedStateFromProps).toHaveBeenCalled(); }); // NOTE: Difference from React @@ -181,11 +182,11 @@ describe('Lifecycle methods', () => { } } - sinon.spy(Foo, 'getDerivedStateFromProps'); + vi.spyOn(Foo, 'getDerivedStateFromProps'); render(, scratch); expect(scratch.firstChild.className).to.equal('foo bar'); - expect(Foo.getDerivedStateFromProps).to.have.been.called; + expect(Foo.getDerivedStateFromProps).toHaveBeenCalled(); }); it('should NOT invoke deprecated lifecycles (cWM/cWRP) if new static gDSFP is present', () => { @@ -198,14 +199,14 @@ describe('Lifecycle methods', () => { } } - sinon.spy(Foo, 'getDerivedStateFromProps'); - sinon.spy(Foo.prototype, 'componentWillMount'); - sinon.spy(Foo.prototype, 'componentWillReceiveProps'); + vi.spyOn(Foo, 'getDerivedStateFromProps'); + vi.spyOn(Foo.prototype, 'componentWillMount'); + vi.spyOn(Foo.prototype, 'componentWillReceiveProps'); render(, scratch); - expect(Foo.getDerivedStateFromProps).to.have.been.called; - expect(Foo.prototype.componentWillMount).to.not.have.been.called; - expect(Foo.prototype.componentWillReceiveProps).to.not.have.been.called; + expect(Foo.getDerivedStateFromProps).toHaveBeenCalled(); + expect(Foo.prototype.componentWillMount).not.toHaveBeenCalled(); + expect(Foo.prototype.componentWillReceiveProps).not.toHaveBeenCalled(); }); it('is not called if neither state nor props have changed', () => { diff --git a/test/browser/lifecycles/lifecycle.test.js b/test/browser/lifecycles/lifecycle.test.js index 2714b4bcfa..5c5977330d 100644 --- a/test/browser/lifecycles/lifecycle.test.js +++ b/test/browser/lifecycles/lifecycle.test.js @@ -1,6 +1,7 @@ import { setupRerender } from 'preact/test-utils'; import { createElement, render, Component } from 'preact'; import { setupScratch, teardown } from '../../_util/helpers'; +import { vi } from 'vitest'; /** @jsx createElement */ @@ -256,17 +257,17 @@ describe('Lifecycle methods', () => { let verifyLifecycleMethods = TestComponent => { let proto = TestComponent.prototype; - spies.forEach(s => sinon.spy(proto, s)); - let reset = () => spies.forEach(s => proto[s].resetHistory()); + spies.forEach(s => vi.spyOn(proto, s)); + let reset = () => spies.forEach(s => proto[s].mockClear()); it('should be invoked for components on initial render', () => { reset(); render(, scratch); - expect(proto.componentDidMount).to.have.been.called; - expect(proto.componentWillMount).to.have.been.calledBefore( + expect(proto.componentDidMount).toHaveBeenCalled(); + expect(proto.componentWillMount).toHaveBeenCalledBefore( proto.componentDidMount ); - expect(proto.componentDidMount).to.have.been.called; + expect(proto.componentDidMount).toHaveBeenCalled(); }); it('should be invoked for components on unmount', () => { @@ -274,7 +275,7 @@ describe('Lifecycle methods', () => { setState({ show: false }); rerender(); - expect(proto.componentWillUnmount).to.have.been.called; + expect(proto.componentWillUnmount).toHaveBeenCalled(); }); it('should be invoked for components on re-render', () => { @@ -282,11 +283,11 @@ describe('Lifecycle methods', () => { setState({ show: true }); rerender(); - expect(proto.componentDidMount).to.have.been.called; - expect(proto.componentWillMount).to.have.been.calledBefore( + expect(proto.componentDidMount).toHaveBeenCalled(); + expect(proto.componentWillMount).toHaveBeenCalledBefore( proto.componentDidMount ); - expect(proto.componentDidMount).to.have.been.called; + expect(proto.componentDidMount).toHaveBeenCalled(); }); }; @@ -338,44 +339,44 @@ describe('Lifecycle methods', () => { 'componentDidMount', 'componentWillUnmount' ]; - spies.forEach(s => sinon.spy(proto, s)); + spies.forEach(s => vi.spyOn(proto, s)); - let reset = () => spies.forEach(s => proto[s].resetHistory()); + let reset = () => spies.forEach(s => proto[s].mockClear()); beforeEach(() => reset()); it('should be invoke normally on initial mount', () => { render(, scratch); - expect(proto.componentWillMount).to.have.been.called; - expect(proto.componentWillMount).to.have.been.calledBefore( + expect(proto.componentWillMount).toHaveBeenCalled(); + expect(proto.componentWillMount).toHaveBeenCalledBefore( proto.componentDidMount ); - expect(proto.componentDidMount).to.have.been.called; + expect(proto.componentDidMount).toHaveBeenCalled(); }); it('should be invoked normally on unmount', () => { setState({ show: false }); rerender(); - expect(proto.componentWillUnmount).to.have.been.called; + expect(proto.componentWillUnmount).toHaveBeenCalled(); }); it('should still invoke mount for shouldComponentUpdate():false', () => { setState({ show: true }); rerender(); - expect(proto.componentWillMount).to.have.been.called; - expect(proto.componentWillMount).to.have.been.calledBefore( + expect(proto.componentWillMount).toHaveBeenCalled(); + expect(proto.componentWillMount).toHaveBeenCalledBefore( proto.componentDidMount ); - expect(proto.componentDidMount).to.have.been.called; + expect(proto.componentDidMount).toHaveBeenCalled(); }); it('should still invoke unmount for shouldComponentUpdate():false', () => { setState({ show: false }); rerender(); - expect(proto.componentWillUnmount).to.have.been.called; + expect(proto.componentWillUnmount).toHaveBeenCalled(); }); }); }); @@ -435,13 +436,13 @@ describe('Lifecycle methods', () => { } } - let renderSpy = sinon.spy(Foo.prototype, 'render'); + let renderSpy = vi.spyOn(Foo.prototype, 'render'); render(, scratch); - renderSpy.resetHistory(); + renderSpy.mockClear(); updateState(); rerender(); - expect(renderSpy).to.not.be.called; + expect(renderSpy).not.toHaveBeenCalled(); }); it('should call callback with correct this binding', () => { @@ -548,37 +549,37 @@ describe('Lifecycle methods', () => { 'componentDidMount', 'componentWillUnmount' ]; - spies.forEach(s => sinon.spy(proto, s)); + spies.forEach(s => vi.spyOn(proto, s)); - let reset = () => spies.forEach(s => proto[s].resetHistory()); + let reset = () => spies.forEach(s => proto[s].mockClear()); render(, scratch); - expect(proto.componentWillMount).to.have.been.called; - expect(proto.componentWillMount).to.have.been.calledBefore( + expect(proto.componentWillMount).toHaveBeenCalled(); + expect(proto.componentWillMount).toHaveBeenCalledBefore( proto.componentDidMount ); - expect(proto.componentDidMount).to.have.been.called; + expect(proto.componentDidMount).toHaveBeenCalled(); reset(); setState({ show: false }); rerender(); - expect(proto.componentWillUnmount).to.have.been.called; + expect(proto.componentWillUnmount).toHaveBeenCalled(); reset(); setState({ show: true }); rerender(); - expect(proto.componentWillMount).to.have.been.called; - expect(proto.componentWillMount).to.have.been.calledBefore( + expect(proto.componentWillMount).toHaveBeenCalled(); + expect(proto.componentWillMount).toHaveBeenCalledBefore( proto.componentDidMount ); - expect(proto.componentDidMount).to.have.been.called; + expect(proto.componentDidMount).toHaveBeenCalled(); }); it('should be able to use getDerivedStateFromError and componentDidCatch together', () => { - let didCatch = sinon.spy(), - getDerived = sinon.spy(); + let didCatch = vi.fn(), + getDerived = vi.fn(); const error = new Error('hi'); class Boundary extends Component { @@ -608,9 +609,9 @@ describe('Lifecycle methods', () => { ); rerender(); - expect(didCatch).to.have.been.calledWith(error); + expect(didCatch).toHaveBeenCalledWith(error); - expect(getDerived).to.have.been.calledWith(error); + expect(getDerived).toHaveBeenCalledWith(error); }); }); }); diff --git a/test/browser/lifecycles/shouldComponentUpdate.test.js b/test/browser/lifecycles/shouldComponentUpdate.test.js index 2cb32fd95d..180a353f59 100644 --- a/test/browser/lifecycles/shouldComponentUpdate.test.js +++ b/test/browser/lifecycles/shouldComponentUpdate.test.js @@ -124,7 +124,7 @@ describe('Lifecycle methods', () => { it('should rerender when sCU returned false before', () => { let c; - let spy = sinon.spy(); + let spy = vi.fn(); class App extends Component { constructor() { @@ -146,16 +146,16 @@ describe('Lifecycle methods', () => { c.setState({}); rerender(); - spy.resetHistory(); + spy.mockClear(); c.setState({ update: true }); rerender(); - expect(spy).to.be.calledOnce; + expect(spy).toHaveBeenCalledOnce(); }); it('should be called with nextState', () => { let c; - let spy = sinon.spy(); + let spy = vi.fn(); class App extends Component { constructor() { @@ -178,15 +178,15 @@ describe('Lifecycle methods', () => { c.setState({}); rerender(); - spy.resetHistory(); + spy.mockClear(); c.setState({ a: true }); rerender(); - expect(spy).to.be.calledOnce; + expect(spy).toHaveBeenCalledOnce(); }); it('should clear renderCallbacks', () => { - const spy = sinon.spy(); + const spy = vi.fn(); let c, renders = 0; @@ -213,7 +213,7 @@ describe('Lifecycle methods', () => { c.setState({}, spy); rerender(); expect(renders).to.equal(1); - expect(spy).to.be.calledOnce; + expect(spy).toHaveBeenCalledOnce(); }); it('should not be called on forceUpdate', () => { @@ -233,15 +233,15 @@ describe('Lifecycle methods', () => { } } - sinon.spy(Foo.prototype, 'shouldComponentUpdate'); - sinon.spy(Foo.prototype, 'render'); + vi.spyOn(Foo.prototype, 'shouldComponentUpdate'); + vi.spyOn(Foo.prototype, 'render'); render(, scratch); Comp.forceUpdate(); rerender(); - expect(Foo.prototype.shouldComponentUpdate).to.not.have.been.called; - expect(Foo.prototype.render).to.have.been.calledTwice; + expect(Foo.prototype.shouldComponentUpdate).not.toHaveBeenCalled(); + expect(Foo.prototype.render).toHaveBeenCalledTimes(2); }); it('should not be called on forceUpdate followed by setState', () => { @@ -261,16 +261,16 @@ describe('Lifecycle methods', () => { } } - sinon.spy(Foo.prototype, 'shouldComponentUpdate'); - sinon.spy(Foo.prototype, 'render'); + vi.spyOn(Foo.prototype, 'shouldComponentUpdate'); + vi.spyOn(Foo.prototype, 'render'); render(, scratch); Comp.forceUpdate(); Comp.setState({}); rerender(); - expect(Foo.prototype.render).to.have.been.calledTwice; - expect(Foo.prototype.shouldComponentUpdate).to.not.have.been.called; + expect(Foo.prototype.render).toHaveBeenCalledTimes(2); + expect(Foo.prototype.shouldComponentUpdate).not.toHaveBeenCalled(); }); it('should not block queued child forceUpdate', () => { @@ -396,7 +396,7 @@ describe('Lifecycle methods', () => { }); it('should update props reference when sCU returns false', () => { - let spy = sinon.spy(); + let spy = vi.fn(); let updateState; class Foo extends Component { @@ -416,16 +416,16 @@ describe('Lifecycle methods', () => { render(, scratch); render(, scratch); - expect(spy).to.be.calledOnce; + expect(spy).toHaveBeenCalledOnce(); updateState(); rerender(); - expect(spy).to.be.calledOnce; + expect(spy).toHaveBeenCalledOnce(); }); it('should update state reference when sCU returns false', () => { - let spy = sinon.spy(); + let spy = vi.fn(); let updateState; class Foo extends Component { @@ -448,14 +448,14 @@ describe('Lifecycle methods', () => { updateState(); rerender(); - expect(spy).to.be.calledOnce; - expect(spy).to.be.calledWithMatch({ foo: 1 }, { foo: 2 }); + expect(spy).toHaveBeenCalledOnce(); + expect(spy).toHaveBeenCalledWith({ foo: 1 }, { foo: 2 }); updateState(); rerender(); - expect(spy).to.be.calledWithMatch({ foo: 2 }, { foo: 2 }); - expect(spy).to.be.calledTwice; + expect(spy).toHaveBeenCalledWith({ foo: 2 }, { foo: 2 }); + expect(spy).toHaveBeenCalledTimes(2); }); // issue #1864 From 1cca4cc35baf12d6b23003c07cd7b8bf58e6b80f Mon Sep 17 00:00:00 2001 From: James Garbutt <43081j@users.noreply.github.com> Date: Thu, 26 Jun 2025 10:27:23 +0100 Subject: [PATCH 2/2] chore: add missing import --- test/browser/lifecycles/componentWillUpdate.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/browser/lifecycles/componentWillUpdate.test.js b/test/browser/lifecycles/componentWillUpdate.test.js index ca674bbe85..ec13781e7d 100644 --- a/test/browser/lifecycles/componentWillUpdate.test.js +++ b/test/browser/lifecycles/componentWillUpdate.test.js @@ -1,6 +1,7 @@ import { setupRerender } from 'preact/test-utils'; import { createElement, render, Component } from 'preact'; import { setupScratch, teardown } from '../../_util/helpers'; +import { vi } from 'vitest'; /** @jsx createElement */