Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions test/_util/helpers.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { createElement, options } from 'preact';
import { clearLog, getLog } from './logCall';
import { teardown as testUtilTeardown } from 'preact/test-utils';
import { vi } from 'vitest';

/** @jsx createElement */

Expand Down Expand Up @@ -263,24 +264,25 @@ let attributesSpy, originalAttributesPropDescriptor;

export function spyOnElementAttributes() {
const test = Object.getOwnPropertyDescriptor(Element.prototype, 'attributes');
const getter = test?.get;

// IE11 doesn't correctly restore the prototype methods so we have to check
// whether this prototype method is already a sinon spy.
if (!attributesSpy && !(test && test.get && test.get.isSinonProxy)) {
// whether this prototype method is already a spy.
if (!attributesSpy && !(getter && vi.isMockFunction(getter))) {
if (!originalAttributesPropDescriptor) {
originalAttributesPropDescriptor = Object.getOwnPropertyDescriptor(
Element.prototype,
'attributes'
);
}

attributesSpy = sinon.spy(Element.prototype, 'attributes', ['get']);
} else if (test && test.get && test.get.isSinonProxy) {
attributesSpy = vi.spyOn(Element.prototype, 'attributes', 'get');
} else if (getter && vi.isMockFunction(getter)) {
// Due to IE11 not resetting we will do this manually when it is a proxy.
test.get.resetHistory();
getter.mockClear();
}

return attributesSpy || test;
return attributesSpy || getter;
}

function restoreElementAttributes() {
Expand Down
5 changes: 3 additions & 2 deletions test/browser/customBuiltInElements.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { createElement, render, Component } from 'preact';
import { setupScratch, teardown } from '../_util/helpers';
import { vi } from 'vitest';

/** @jsx createElement */

Expand All @@ -23,7 +24,7 @@ runSuite('customised built-in elements', () => {
}
}

const spy = sinon.spy();
const spy = vi.fn();

class BuiltIn extends HTMLDivElement {
connectedCallback() {
Expand All @@ -35,6 +36,6 @@ runSuite('customised built-in elements', () => {

render(<Foo />, scratch);

expect(spy).to.have.been.calledOnce;
expect(spy).toHaveBeenCalledTimes(1);
});
});
55 changes: 25 additions & 30 deletions test/browser/hydrate.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from '../_util/helpers';
import { ul, li, div } from '../_util/dom';
import { logCall, clearLog, getLog } from '../_util/logCall';
import { vi } from 'vitest';

/** @jsx createElement */

Expand Down Expand Up @@ -77,7 +78,7 @@ describe('hydrate()', () => {
});

it('should reuse existing DOM', () => {
const onClickSpy = sinon.spy();
const onClickSpy = vi.fn();
const html = ul([li('1'), li('2'), li('3')]);

scratch.innerHTML = html;
Expand All @@ -94,11 +95,11 @@ describe('hydrate()', () => {

expect(scratch.innerHTML).to.equal(html);
expect(getLog()).to.deep.equal([]);
expect(onClickSpy).not.to.have.been.called;
expect(onClickSpy).not.toHaveBeenCalled();

scratch.querySelector('li:last-child').dispatchEvent(createEvent('click'));

expect(onClickSpy).to.have.been.called.calledOnce;
expect(onClickSpy).toHaveBeenCalledOnce();
});

it('should skip comment nodes between dom nodes', () => {
Expand All @@ -115,7 +116,7 @@ describe('hydrate()', () => {
});

it('should reuse existing DOM when given components', () => {
const onClickSpy = sinon.spy();
const onClickSpy = vi.fn();
const html = ul([li('1'), li('2'), li('3')]);

scratch.innerHTML = html;
Expand All @@ -132,18 +133,18 @@ describe('hydrate()', () => {

expect(scratch.innerHTML).to.equal(html);
expect(getLog()).to.deep.equal([]);
expect(onClickSpy).not.to.have.been.called;
expect(onClickSpy).not.toHaveBeenCalled();

scratch.querySelector('li:last-child').dispatchEvent(createEvent('click'));

expect(onClickSpy).to.have.been.called.calledOnce;
expect(onClickSpy).toHaveBeenCalledOnce();
});

it('should properly set event handlers to existing DOM when given components', () => {
const proto = Element.prototype;
sinon.spy(proto, 'addEventListener');
vi.spyOn(proto, 'addEventListener');

const clickHandlers = [sinon.spy(), sinon.spy(), sinon.spy()];
const clickHandlers = [vi.fn(), vi.fn(), vi.fn()];

const html = ul([li('1'), li('2'), li('3')]);

Expand All @@ -161,11 +162,11 @@ describe('hydrate()', () => {

expect(scratch.innerHTML).to.equal(html);
expect(getLog()).to.deep.equal([]);
expect(proto.addEventListener).to.have.been.calledThrice;
expect(clickHandlers[2]).not.to.have.been.called;
expect(proto.addEventListener).toHaveBeenCalledTimes(3);
expect(clickHandlers[2]).not.toHaveBeenCalled();

scratch.querySelector('li:last-child').dispatchEvent(createEvent('click'));
expect(clickHandlers[2]).to.have.been.calledOnce;
expect(clickHandlers[2]).toHaveBeenCalledTimes(1);
});

it('should add missing nodes to existing DOM when hydrating', () => {
Expand Down Expand Up @@ -225,7 +226,7 @@ describe('hydrate()', () => {
clearLog();
hydrate(vnode, scratch);

expect(attributesSpy.get).to.not.have.been.called;
expect(attributesSpy).not.toHaveBeenCalled();

expect(serializeHtml(scratch)).to.equal(
sortAttributes(
Expand All @@ -247,7 +248,7 @@ describe('hydrate()', () => {
scratch.innerHTML = html;
clearLog();

const clickHandlers = [sinon.spy(), sinon.spy(), sinon.spy(), sinon.spy()];
const clickHandlers = [vi.fn(), vi.fn(), vi.fn(), vi.fn()];

hydrate(
<List>
Expand All @@ -263,13 +264,13 @@ describe('hydrate()', () => {

expect(scratch.innerHTML).to.equal(html);
expect(getLog()).to.deep.equal([]);
expect(clickHandlers[2]).not.to.have.been.called;
expect(clickHandlers[2]).not.toHaveBeenCalled();

scratch
.querySelector('li:nth-child(3)')
.dispatchEvent(createEvent('click'));

expect(clickHandlers[2]).to.have.been.called.calledOnce;
expect(clickHandlers[2]).toHaveBeenCalledOnce();
});

it('should correctly hydrate root Fragments', () => {
Expand All @@ -281,13 +282,7 @@ describe('hydrate()', () => {
scratch.innerHTML = html;
clearLog();

const clickHandlers = [
sinon.spy(),
sinon.spy(),
sinon.spy(),
sinon.spy(),
sinon.spy()
];
const clickHandlers = [vi.fn(), vi.fn(), vi.fn(), vi.fn(), vi.fn()];

hydrate(
<Fragment>
Expand All @@ -306,19 +301,19 @@ describe('hydrate()', () => {

expect(scratch.innerHTML).to.equal(html);
expect(getLog()).to.deep.equal([]);
expect(clickHandlers[2]).not.to.have.been.called;
expect(clickHandlers[2]).not.toHaveBeenCalled();

scratch
.querySelector('li:nth-child(3)')
.dispatchEvent(createEvent('click'));

expect(clickHandlers[2]).to.have.been.calledOnce;
expect(clickHandlers[4]).not.to.have.been.called;
expect(clickHandlers[2]).toHaveBeenCalledTimes(1);
expect(clickHandlers[4]).not.toHaveBeenCalled();

scratch.querySelector('div').dispatchEvent(createEvent('click'));

expect(clickHandlers[2]).to.have.been.calledOnce;
expect(clickHandlers[4]).to.have.been.calledOnce;
expect(clickHandlers[2]).toHaveBeenCalledTimes(1);
expect(clickHandlers[4]).toHaveBeenCalledTimes(1);
});

it('should override incorrect pre-existing DOM with VNodes passed into render', () => {
Expand Down Expand Up @@ -374,22 +369,22 @@ describe('hydrate()', () => {
);

hydrate(preactElement, scratch);
expect(attributesSpy.get).to.not.have.been.called;
expect(attributesSpy).not.toHaveBeenCalled();
expect(scratch).to.have.property(
'innerHTML',
'<div><a foo="bar"></a></div>'
);
});

it('should attach event handlers', () => {
let spy = sinon.spy();
let spy = vi.fn();
scratch.innerHTML = '<span>Test</span>';
let vnode = <span onClick={spy}>Test</span>;

hydrate(vnode, scratch);

scratch.firstChild.click();
expect(spy).to.be.calledOnce;
expect(spy).toHaveBeenCalledOnce();
});

// #2237
Expand Down
5 changes: 3 additions & 2 deletions test/browser/keys.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { setupRerender } from 'preact/test-utils';
import { setupScratch, teardown } from '../_util/helpers';
import { logCall, clearLog, getLog } from '../_util/logCall';
import { div } from '../_util/dom';
import { vi } from 'vitest';

/** @jsx createElement */

Expand Down Expand Up @@ -101,11 +102,11 @@ describe('keys', () => {

// https://fb.me/react-special-props
it('should not pass key in props', () => {
const Foo = sinon.spy(function Foo() {
const Foo = vi.fn(function Foo() {
return null;
});
render(<Foo key="foo" />, scratch);
expect(Foo.args[0][0]).to.deep.equal({});
expect(Foo.mock.calls[0][0]).to.deep.equal({});
});

it('should update in-place keyed DOM nodes', () => {
Expand Down
9 changes: 5 additions & 4 deletions test/browser/placeholders.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { setupRerender } from 'preact/test-utils';
import { setupScratch, teardown } from '../_util/helpers';
import { logCall, clearLog, getLog } from '../_util/logCall';
import { div } from '../_util/dom';
import { vi } from 'vitest';

/** @jsx createElement */

Expand Down Expand Up @@ -436,7 +437,7 @@ describe('null placeholders', () => {

const Test2 = () => <div>Test2</div>;

const ref = sinon.spy();
const ref = vi.fn();

class App extends Component {
constructor(props) {
Expand Down Expand Up @@ -466,9 +467,9 @@ describe('null placeholders', () => {
expect(scratch.innerHTML).to.equal(
'<div><div>Test2</div><div>Test3</div><div>Iframe</div></div>'
);
expect(ref).to.have.been.calledOnce;
expect(ref).toHaveBeenCalledTimes(1);

ref.resetHistory();
ref.mockClear();
clearLog();
setState({ value: false });
rerender();
Expand All @@ -477,6 +478,6 @@ describe('null placeholders', () => {
'<div><div>Test2</div><div>Iframe</div></div>'
);
expect(getLog()).to.deep.equal(['<div>Test3.remove()']);
expect(ref).to.have.been.calledOnce;
expect(ref).toHaveBeenCalledTimes(1);
});
});
13 changes: 6 additions & 7 deletions test/browser/render.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
} from '../_util/helpers';
import { clearLog, getLog, logCall } from '../_util/logCall';
import { useState } from 'preact/hooks';
import { vi } from 'vitest';

/** @jsx createElement */

Expand Down Expand Up @@ -1236,19 +1237,17 @@ describe('render()', () => {
render(<A />, scratch);
expect(scratch.innerHTML).to.equal('<div>0</div>');

const sandbox = sinon.createSandbox();
const debounceSpy = vi.spyOn(options, 'debounceRendering');
try {
sandbox.spy(options, 'debounceRendering');

comp.setState({ updates: 1 }, () => {
comp.setState({ updates: 2 });
});
rerender();
expect(scratch.innerHTML).to.equal('<div>2</div>');

expect(options.debounceRendering).to.have.been.calledOnce;
expect(debounceSpy).toHaveBeenCalledTimes(1);
} finally {
sandbox.restore();
debounceSpy.mockRestore();
}
});

Expand Down Expand Up @@ -1300,7 +1299,7 @@ describe('render()', () => {
'<div id="wrapper"><div id="page1">Page 1</div></div>'
);

expect(attributesSpy.get).to.not.have.been.called;
expect(attributesSpy).not.toHaveBeenCalled();

render(
<div id="wrapper">
Expand All @@ -1312,7 +1311,7 @@ describe('render()', () => {
'<div id="wrapper"><div id="page2">Page 2</div></div>'
);

expect(attributesSpy.get).to.not.have.been.called;
expect(attributesSpy).not.toHaveBeenCalled();
});

// #2926
Expand Down
Loading
Loading