Skip to content

Commit

Permalink
Switch jest unit tests to vitest (#243)
Browse files Browse the repository at this point in the history
* Switch jest unit tests to vitest

* Cleanup vite config after debugging
  • Loading branch information
SeinopSys authored Apr 30, 2024
1 parent dd8c2c8 commit 2417f40
Show file tree
Hide file tree
Showing 23 changed files with 1,433 additions and 3,295 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,5 @@ npm-debug.log
/native/**/target
/.cargo

# Jest coverage
# Vitest coverage
/assets/coverage
1 change: 0 additions & 1 deletion assets/.eslintignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
js/vendor/*
vite.config.ts
jest.config.js
8 changes: 5 additions & 3 deletions assets/.eslintrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ parserOptions:

plugins:
- '@typescript-eslint'
- jest
- vitest

globals:
ga: false
Expand Down Expand Up @@ -276,12 +276,14 @@ overrides:
'@typescript-eslint/no-extra-parens': 2
no-shadow: 0
'@typescript-eslint/no-shadow': 2
# Jest Tests (also written in TypeScript)
# Unit Tests (also written in TypeScript)
# Disable rules that do not make sense in test files (e.g. testing for undefined input values should be allowed)
- files:
- '*.spec.ts'
- 'test/*.ts'
extends:
- 'plugin:jest/recommended'
- 'plugin:vitest/legacy-recommended'
rules:
no-undefined: 0
no-unused-expressions: 0
vitest/valid-expect: 0
13 changes: 0 additions & 13 deletions assets/fix-jsdom.ts

This file was deleted.

42 changes: 0 additions & 42 deletions assets/jest.config.js

This file was deleted.

17 changes: 9 additions & 8 deletions assets/js/__tests__/input-duplicator.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { inputDuplicatorCreator } from '../input-duplicator';
import { assertNotNull } from '../utils/assert';
import { $, $$, removeEl } from '../utils/dom';
import { fireEvent } from '@testing-library/dom';

describe('Input duplicator functionality', () => {
beforeEach(() => {
Expand Down Expand Up @@ -41,7 +42,7 @@ describe('Input duplicator functionality', () => {

expect($$('input')).toHaveLength(1);

assertNotNull($<HTMLButtonElement>('.js-add-input')).click();
fireEvent.click(assertNotNull($<HTMLButtonElement>('.js-add-input')));

expect($$('input')).toHaveLength(2);
});
Expand All @@ -53,7 +54,7 @@ describe('Input duplicator functionality', () => {
form.insertAdjacentElement('afterbegin', buttonDiv);
runCreator();

assertNotNull($<HTMLButtonElement>('.js-add-input')).click();
fireEvent.click(assertNotNull($<HTMLButtonElement>('.js-add-input')));

expect($$('input')).toHaveLength(2);
});
Expand All @@ -62,7 +63,7 @@ describe('Input duplicator functionality', () => {
runCreator();

for (let i = 0; i < 5; i += 1) {
assertNotNull($<HTMLButtonElement>('.js-add-input')).click();
fireEvent.click(assertNotNull($<HTMLButtonElement>('.js-add-input')));
}

expect($$('input')).toHaveLength(3);
Expand All @@ -71,19 +72,19 @@ describe('Input duplicator functionality', () => {
it('should remove duplicated input elements', () => {
runCreator();

assertNotNull($<HTMLButtonElement>('.js-add-input')).click();
assertNotNull($<HTMLAnchorElement>('.js-remove-input')).click();
fireEvent.click(assertNotNull($<HTMLButtonElement>('.js-add-input')));
fireEvent.click(assertNotNull($<HTMLAnchorElement>('.js-remove-input')));

expect($$('input')).toHaveLength(1);
});

it('should not remove the last input element', () => {
runCreator();

assertNotNull($<HTMLAnchorElement>('.js-remove-input')).click();
assertNotNull($<HTMLAnchorElement>('.js-remove-input')).click();
fireEvent.click(assertNotNull($<HTMLAnchorElement>('.js-remove-input')));
fireEvent.click(assertNotNull($<HTMLAnchorElement>('.js-remove-input')));
for (let i = 0; i < 5; i += 1) {
assertNotNull($<HTMLAnchorElement>('.js-remove-input')).click();
fireEvent.click(assertNotNull($<HTMLAnchorElement>('.js-remove-input')));
}

expect($$('input')).toHaveLength(1);
Expand Down
37 changes: 19 additions & 18 deletions assets/js/__tests__/ujs.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import fetchMock from 'jest-fetch-mock';
import { fireEvent, waitFor } from '@testing-library/dom';
import { assertType } from '../utils/assert';
import '../ujs';
import { fetchMock } from '../../test/fetch-mock';

const mockEndpoint = 'http://localhost/endpoint';
const mockVerb = 'POST';
Expand Down Expand Up @@ -38,7 +38,7 @@ describe('Remote utilities', () => {
}

document.documentElement.insertAdjacentElement('beforeend', a);
a.click();
fireEvent.click(a, { button: 0 });

return a;
};
Expand Down Expand Up @@ -88,7 +88,7 @@ describe('Remote utilities', () => {
a.dataset.method = mockVerb;

document.documentElement.insertAdjacentElement('beforeend', a);
a.click();
fireEvent.click(a);

return a;
};
Expand Down Expand Up @@ -128,7 +128,7 @@ describe('Remote utilities', () => {
...Object.getOwnPropertyDescriptors(oldWindowLocation),
reload: {
configurable: true,
value: jest.fn(),
value: vi.fn(),
},
},
);
Expand All @@ -155,7 +155,7 @@ describe('Remote utilities', () => {
const submitForm = () => {
const form = configureForm();
form.method = mockVerb;
form.submit();
fireEvent.submit(form);
return form;
};

Expand All @@ -176,7 +176,7 @@ describe('Remote utilities', () => {
it('should submit a PUT request with put data-method specified', () => {
const form = configureForm();
form.dataset.method = 'put';
form.submit();
fireEvent.submit(form);
expect(fetch).toHaveBeenCalledTimes(1);
expect(fetch).toHaveBeenNthCalledWith(1, mockEndpoint, {
method: 'PUT',
Expand All @@ -201,7 +201,7 @@ describe('Remote utilities', () => {
}));

it('should reload the page on 300 multiple choices response', () => {
jest.spyOn(global, 'fetch').mockResolvedValue(new Response('', { status: 300}));
vi.spyOn(global, 'fetch').mockResolvedValue(new Response('', { status: 300}));

submitForm();
return waitFor(() => expect(window.location.reload).toHaveBeenCalledTimes(1));
Expand All @@ -211,28 +211,29 @@ describe('Remote utilities', () => {

describe('Form utilities', () => {
beforeEach(() => {
jest.spyOn(window, 'requestAnimationFrame').mockImplementation(cb => {
vi.spyOn(window, 'requestAnimationFrame').mockImplementation(cb => {
cb(1);
return 1;
});
});

afterEach(() => {
jest.clearAllMocks();
vi.clearAllMocks();
});

describe('[data-confirm]', () => {
const createA = () => {
const a = document.createElement('a');
a.dataset.confirm = 'confirm';
a.href = mockEndpoint;
// We cannot use mockEndpoint here since anything except a hash change will log an error in the test output
a.href = '#hash';
document.documentElement.insertAdjacentElement('beforeend', a);
return a;
};

it('should cancel the event on failed confirm', () => {
const a = createA();
const confirm = jest.spyOn(window, 'confirm').mockImplementationOnce(() => false);
const confirm = vi.spyOn(window, 'confirm').mockImplementationOnce(() => false);
const event = new MouseEvent('click', { bubbles: true, cancelable: true });

expect(fireEvent(a, event)).toBe(false);
Expand All @@ -241,7 +242,7 @@ describe('Form utilities', () => {

it('should allow the event on confirm', () => {
const a = createA();
const confirm = jest.spyOn(window, 'confirm').mockImplementationOnce(() => true);
const confirm = vi.spyOn(window, 'confirm').mockImplementationOnce(() => true);
const event = new MouseEvent('click', { bubbles: true, cancelable: true });

expect(fireEvent(a, event)).toBe(true);
Expand Down Expand Up @@ -276,15 +277,15 @@ describe('Form utilities', () => {

it('should disable submit button containing a text child on click', () => {
const [ , button ] = createFormAndButton(submitText, loadingText);
button.click();
fireEvent.click(button);

expect(button.textContent).toEqual(' Loading...');
expect(button.dataset.enableWith).toEqual(submitText);
});

it('should disable submit button containing element children on click', () => {
const [ , button ] = createFormAndButton(submitMarkup, loadingMarkup);
button.click();
fireEvent.click(button);

expect(button.innerHTML).toEqual(loadingMarkup);
expect(button.dataset.enableWith).toEqual(submitMarkup);
Expand All @@ -293,15 +294,15 @@ describe('Form utilities', () => {
it('should not disable anything when the form is invalid', () => {
const [ form, button ] = createFormAndButton(submitText, loadingText);
form.insertAdjacentHTML('afterbegin', '<input type="text" name="valid" required="true" />');
button.click();
fireEvent.click(button);

expect(button.textContent).toEqual(submitText);
expect(button.dataset.enableWith).not.toBeDefined();
});

it('should reset submit button containing a text child on completion', () => {
const [ form, button ] = createFormAndButton(submitText, loadingText);
button.click();
fireEvent.click(button);
fireEvent(form, new CustomEvent('reset', { bubbles: true }));

expect(button.textContent?.trim()).toEqual(submitText);
Expand All @@ -310,7 +311,7 @@ describe('Form utilities', () => {

it('should reset submit button containing element children on completion', () => {
const [ form, button ] = createFormAndButton(submitMarkup, loadingMarkup);
button.click();
fireEvent.click(button);
fireEvent(form, new CustomEvent('reset', { bubbles: true }));

expect(button.innerHTML).toEqual(submitMarkup);
Expand All @@ -319,7 +320,7 @@ describe('Form utilities', () => {

it('should reset disabled form elements on pageshow', () => {
const [ , button ] = createFormAndButton(submitText, loadingText);
button.click();
fireEvent.click(button);
fireEvent(window, new CustomEvent('pageshow'));

expect(button.textContent?.trim()).toEqual(submitText);
Expand Down
Loading

0 comments on commit 2417f40

Please sign in to comment.