Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate from Jest to Vitest #1202

Merged
merged 18 commits into from
Oct 22, 2023
Merged
Show file tree
Hide file tree
Changes from 14 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
23 changes: 23 additions & 0 deletions bin/run-vitest-all.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/bash

# Get all workspace names
workspaces=$(yarn workspaces --json info | jq -r 'if .type == "log" then .data | fromjson | keys[] else empty end')
weaverryan marked this conversation as resolved.
Show resolved Hide resolved

# Flag to track if any test fails
all_tests_passed=true

for workspace in $workspaces; do
echo "Running tests in $workspace..."

# Run the tests and if they fail, set the flag to false
yarn workspace $workspace run vitest --run || { echo "$workspace failed"; all_tests_passed=false; }
done

# Check the flag at the end and exit with code 1 if any test failed
if [ "$all_tests_passed" = false ]; then
echo "Some tests failed."
exit 1
else
echo "All tests passed!"
exit 0
fi
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
],
"scripts": {
"build": "node bin/build_javascript.js && node bin/build_styles.js",
"test": "yarn workspaces run jest",
"test": "bin/run-vitest-all.sh",
"test:jest": "yarn workspaces run jest",
"lint": "yarn workspaces run eslint src test",
"format": "prettier src/*/assets/src/*.ts src/*/assets/test/*.js {,src/*/}*.{json,md} --write",
"check-lint": "yarn lint --no-fix",
Expand All @@ -31,7 +32,8 @@
"prettier": "^2.2.1",
"rollup": "^3.7.0",
"tslib": "^2.3.1",
"typescript": "^4.4.4"
"typescript": "^4.4.4",
"vitest": "^0.34.6"
},
"eslintConfig": {
"root": true,
Expand Down
4 changes: 2 additions & 2 deletions src/Autocomplete/assets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
},
"devDependencies": {
"@hotwired/stimulus": "^3.0.0",
"fetch-mock-jest": "^1.5.1",
"tom-select": "^2.2.2"
"tom-select": "^2.2.2",
"vitest-fetch-mock": "^0.2.2"
}
}
72 changes: 44 additions & 28 deletions src/Autocomplete/assets/test/controller.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ import AutocompleteController, {
AutocompleteConnectOptions,
AutocompletePreConnectOptions,
} from '../src/controller';
import fetchMock from 'fetch-mock-jest';
import userEvent from '@testing-library/user-event';
import TomSelect from 'tom-select';
import createFetchMock from 'vitest-fetch-mock';
import { vi } from 'vitest';

const shortDelay = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms));

Expand Down Expand Up @@ -50,19 +51,21 @@ const startAutocompleteTest = async (html: string): Promise<{ container: HTMLEle
return { container, tomSelect };
}

const fetchMocker = createFetchMock(vi);
describe('AutocompleteController', () => {
beforeAll(() => {
const application = Application.start();
application.register('autocomplete', AutocompleteController);

fetchMocker.enableMocks();
});

beforeEach(() => {
fetchMocker.resetMocks();
});

afterEach(() => {
document.body.innerHTML = '';

if (!fetchMock.done()) {
throw new Error('Mocked requests did not match');
}
fetchMock.reset();
});

it('connect without options', async () => {
Expand All @@ -74,6 +77,7 @@ describe('AutocompleteController', () => {
`);

expect(tomSelect.input).toBe(getByTestId(container, 'main-element'));
expect(fetchMock.requests().length).toEqual(0);
});

it('connect with ajax URL on a select element', async () => {
Expand All @@ -88,8 +92,7 @@ describe('AutocompleteController', () => {
`);

// initial Ajax request on focus
fetchMock.mock(
'/path/to/autocomplete?query=',
fetchMock.mockResponseOnce(
JSON.stringify({
results: [
{
Expand All @@ -100,8 +103,7 @@ describe('AutocompleteController', () => {
}),
);

fetchMock.mock(
'/path/to/autocomplete?query=foo',
fetchMock.mockResponseOnce(
JSON.stringify({
results: [
{
Expand Down Expand Up @@ -132,6 +134,10 @@ describe('AutocompleteController', () => {
await waitFor(() => {
expect(container.querySelectorAll('.option[data-selectable]')).toHaveLength(2);
});

expect(fetchMock.requests().length).toEqual(2);
expect(fetchMock.requests()[0].url).toEqual('/path/to/autocomplete?query=');
expect(fetchMock.requests()[1].url).toEqual('/path/to/autocomplete?query=foo');
});

it('connect with ajax URL on an input element', async () => {
Expand All @@ -146,8 +152,7 @@ describe('AutocompleteController', () => {
`);

// initial Ajax request on focus
fetchMock.mock(
'/path/to/autocomplete?query=',
fetchMock.mockResponseOnce(
JSON.stringify({
results: [
{
Expand All @@ -158,8 +163,7 @@ describe('AutocompleteController', () => {
}),
);

fetchMock.mock(
'/path/to/autocomplete?query=foo',
fetchMock.mockResponseOnce(
JSON.stringify({
results: [
{
Expand Down Expand Up @@ -190,6 +194,10 @@ describe('AutocompleteController', () => {
await waitFor(() => {
expect(container.querySelectorAll('.option[data-selectable]')).toHaveLength(2);
});

expect(fetchMock.requests().length).toEqual(2);
expect(fetchMock.requests()[0].url).toEqual('/path/to/autocomplete?query=');
expect(fetchMock.requests()[1].url).toEqual('/path/to/autocomplete?query=foo');
});

it('limits updates when min-characters', async () => {
Expand All @@ -212,6 +220,8 @@ describe('AutocompleteController', () => {
await waitFor(() => {
expect(container.querySelectorAll('.option[data-selectable]')).toHaveLength(0);
});

expect(fetchMock.requests().length).toEqual(0);
});

it('min-characters can be a falsy value', async () => {
Expand Down Expand Up @@ -241,8 +251,7 @@ describe('AutocompleteController', () => {
const controlInput = tomSelect.control_input;

// ajax call from initial focus
fetchMock.mock(
'/path/to/autocomplete?query=',
fetchMock.mockResponseOnce(
JSON.stringify({
results: [
{
Expand All @@ -267,8 +276,7 @@ describe('AutocompleteController', () => {
});

// now trigger a load
fetchMock.mock(
'/path/to/autocomplete?query=foo',
fetchMock.mockResponseOnce(
JSON.stringify({
results: [
{
Expand All @@ -290,8 +298,7 @@ describe('AutocompleteController', () => {
});

// now go below the min characters, but it should still load
fetchMock.mock(
'/path/to/autocomplete?query=fo',
fetchMock.mockResponseOnce(
JSON.stringify({
results: [
{
Expand All @@ -315,6 +322,11 @@ describe('AutocompleteController', () => {
await waitFor(() => {
expect(container.querySelectorAll('.option[data-selectable]')).toHaveLength(3);
});

expect(fetchMock.requests().length).toEqual(3);
expect(fetchMock.requests()[0].url).toEqual('/path/to/autocomplete?query=');
expect(fetchMock.requests()[1].url).toEqual('/path/to/autocomplete?query=foo');
expect(fetchMock.requests()[2].url).toEqual('/path/to/autocomplete?query=fo');
});

it('adds work-around for live-component & multiple select', async () => {
Expand Down Expand Up @@ -359,8 +371,7 @@ describe('AutocompleteController', () => {
`);

// initial Ajax request on focus
fetchMock.mock(
'/path/to/autocomplete?query=',
fetchMock.mockResponseOnce(
JSON.stringify({
results: [
{value: 1, text: 'dog1'},
Expand Down Expand Up @@ -390,8 +401,7 @@ describe('AutocompleteController', () => {
throw new Error('cannot find dropdown content element');
}

fetchMock.mock(
'/path/to/autocomplete?query=&page=2',
fetchMock.mockResponseOnce(
JSON.stringify({
results: [
{value: 11, text: 'dog11'},
Expand All @@ -407,6 +417,10 @@ describe('AutocompleteController', () => {
await waitFor(() => {
expect(container.querySelectorAll('.option[data-selectable]')).toHaveLength(12);
});

expect(fetchMock.requests().length).toEqual(2);
expect(fetchMock.requests()[0].url).toEqual('/path/to/autocomplete?query=');
expect(fetchMock.requests()[1].url).toEqual('/path/to/autocomplete?query=&page=2');
});

it('continues working even if options html rearranges', async () => {
Expand Down Expand Up @@ -625,8 +639,7 @@ describe('AutocompleteController', () => {
`);

// initial Ajax request on focus with group_by options
fetchMock.mock(
'/path/to/autocomplete?query=',
fetchMock.mockResponseOnce(
JSON.stringify({
results: {
options: [
Expand Down Expand Up @@ -665,8 +678,7 @@ describe('AutocompleteController', () => {
}),
);

fetchMock.mock(
'/path/to/autocomplete?query=foo',
fetchMock.mockResponseOnce(
JSON.stringify({
results: {
options: [
Expand Down Expand Up @@ -709,5 +721,9 @@ describe('AutocompleteController', () => {
expect(container.querySelectorAll('.option[data-selectable]')).toHaveLength(2);
expect(container.querySelectorAll('.optgroup-header')).toHaveLength(1);
});

expect(fetchMock.requests().length).toEqual(2);
expect(fetchMock.requests()[0].url).toEqual('/path/to/autocomplete?query=');
expect(fetchMock.requests()[1].url).toEqual('/path/to/autocomplete?query=foo');
});
});
12 changes: 0 additions & 12 deletions src/Autocomplete/assets/test/setup.js

This file was deleted.

4 changes: 2 additions & 2 deletions src/Chartjs/assets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"@hotwired/stimulus": "^3.0.0",
"@types/chart.js": "^2.9.34",
"chart.js": "^3.4.1 <3.9",
"jest-canvas-mock": "^2.3.0",
"resize-observer-polyfill": "^1.5.1"
"resize-observer-polyfill": "^1.5.1",
"vitest-canvas-mock": "^0.3.3"
}
}
2 changes: 1 addition & 1 deletion src/Chartjs/assets/test/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@

'use strict';

import 'jest-canvas-mock';
import 'vitest-canvas-mock';
// eslint-disable-next-line
global.ResizeObserver = require('resize-observer-polyfill');
19 changes: 19 additions & 0 deletions src/Chartjs/assets/vitest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { defineConfig, mergeConfig } from 'vitest/config';
import configShared from '../../../vitest.config.js'
import path from 'path';

export default mergeConfig(
configShared,
defineConfig({
test: {
setupFiles: [path.join(__dirname, 'test', 'setup.js')],
deps: {
optimizer: {
web: {
include: ['vitest-canvas-mock'],
},
},
},
}
})
);
12 changes: 0 additions & 12 deletions src/LiveComponent/assets/test/setup.js

This file was deleted.

8 changes: 7 additions & 1 deletion src/LiveComponent/assets/test/tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ let activeTests: FunctionalTest[] = [];
let application: Application;

export function shutdownTests() {
if (application) {
application.stop();
}

if (activeTests.length === 0) {
// no test was run, apparently
return;
Expand Down Expand Up @@ -366,7 +370,9 @@ export function createTestForExistingComponent(component: Component): Functional

export async function startStimulus(element: string|HTMLElement) {
// start the Stimulus app just once per test suite
if (!application) {
if (application) {
await application.start();
} else {
application = Application.start();
application.register('live', LiveController);
}
Expand Down
10 changes: 5 additions & 5 deletions src/Notify/assets/test/controller.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,14 @@ describe('NotifyController', () => {
afterEach(() => {
clearDOM();
application.stop();
jest.clearAllMocks();
vi.clearAllMocks();
});

const addEventListenerMock = jest.fn();
const removeEventListenerMock = jest.fn();
const closeMock = jest.fn();
const addEventListenerMock = vi.fn();
const removeEventListenerMock = vi.fn();
const closeMock = vi.fn();

global.EventSource = jest.fn().mockImplementation(() => {
global.EventSource = vi.fn().mockImplementation(() => {
return {
addEventListener: addEventListenerMock,
removeEventListener: removeEventListenerMock,
Expand Down
1 change: 1 addition & 0 deletions src/React/assets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"@types/react": "^18.0",
"@types/react-dom": "^18.0",
"@types/webpack-env": "^1.16",
"@vitejs/plugin-react": "^4.1.0",
"react": "^18.0",
"react-dom": "^18.0"
}
Expand Down
Loading
Loading