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

Feature/jest to vitest migration #6605

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
Draft
  •  
  •  
  •  
1 change: 1 addition & 0 deletions packages/volto/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ indent_size = 2
indent_style = tab
indent_size = unset
tab_width = unset

3 changes: 3 additions & 0 deletions packages/volto/.eslintignore
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
/types/
.i18nrc.js
build/
dist/
2 changes: 2 additions & 0 deletions packages/volto/.eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -91,5 +91,7 @@
"jest": true,
"socket": true,
"webpackIsomorphicTools": true,
"vitest":true,
"vi":true
},
}
10 changes: 10 additions & 0 deletions packages/volto/.i18nrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* eslint-disable */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this file for?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added it to bypass ESLint warnings that I was encountering while committing. Once the work is complete, I’ll remove it.

module.exports = {
locales: ['en'],
extractMessages: true,
outputFilePattern: 'build/messages/messages.json',
inputFilePattern: [
'src/**/*.{js,jsx,ts,tsx}',
'__tests__/**/*.{js,jsx,ts,tsx}',
],
};
20 changes: 10 additions & 10 deletions packages/volto/__tests__/addon-registry-project.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,22 @@ import {
buildDependencyGraph,
getAddonsLoaderChain,
} from '@plone/registry/addon-registry';
import { vi, expect, describe, test, beforeEach, afterEach } from 'vitest';

describe('AddonRegistry - Project', () => {
jest.mock(
vi.mock(
`${path.join(
__dirname,
'fixtures',
'test-volto-project',
)}/node_modules/@plone/volto/package.json`,
() => ({
// TODO: mock the packages folder inside the mocked @plone/volto to work with resolves
coreAddons: {},
}),
{ virtual: true },
);

it('works in a mock project directory', () => {
test('works in a mock project directory', () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you changing it to test? Which is the reasoning behind?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As u know both it and test work the same in Vitest. When I started migrating tests in Volto, I saw test in some places and it in others. However, for consistency, I wanted to standardize on using it. That said, I noticed that test is used in many existing files. If there's a preference or guideline for which one to use, please let me know so I can align with it.

const base = path.join(__dirname, 'fixtures', 'test-volto-project');
const { registry } = AddonRegistry.init(base);

Expand Down Expand Up @@ -102,7 +102,7 @@ describe('AddonRegistry - Project', () => {
});
});

it('provides aliases for addons', () => {
test('provides aliases for addons', () => {
const base = path.join(__dirname, 'fixtures', 'test-volto-project');
const { registry } = AddonRegistry.init(base);
expect(registry.getResolveAliases()).toStrictEqual({
Expand All @@ -115,13 +115,13 @@ describe('AddonRegistry - Project', () => {
});
});

it('provides addon extenders', () => {
test('provides addon extenders', () => {
const base = path.join(__dirname, 'fixtures', 'test-volto-project');
const { registry } = AddonRegistry.init(base);
expect(registry.getAddonExtenders().length).toBe(1);
});

it('provides a list of addon records ordered by initial package declaration', () => {
test('provides a list of addon records ordered by initial package declaration', () => {
const base = path.join(__dirname, 'fixtures', 'test-volto-project');
const { registry } = AddonRegistry.init(base);
const addons = registry.getAddons();
Expand All @@ -135,7 +135,7 @@ describe('AddonRegistry - Project', () => {
]);
});

it('provides customization paths declared in a Volto project', () => {
test('provides customization paths declared in a Volto project', () => {
const base = path.join(__dirname, 'fixtures', 'test-volto-project');
const { registry } = AddonRegistry.init(base);
expect(registry.getProjectCustomizationPaths()).toStrictEqual({
Expand All @@ -148,7 +148,7 @@ describe('AddonRegistry - Project', () => {
});
});

it('provides customization paths declared in addons', () => {
test('provides customization paths declared in addons', () => {
const base = path.join(__dirname, 'fixtures', 'test-volto-project');
const { registry } = AddonRegistry.init(base);
expect(registry.getAddonCustomizationPaths()).toStrictEqual({
Expand Down Expand Up @@ -220,7 +220,7 @@ describe('Addon via env var - Released addon', () => {
const originalEnv = process.env;

beforeEach(() => {
jest.resetModules();
vi.resetModules();
process.env = {
...originalEnv,
ADDONS: 'test-released-via-addons-env-var',
Expand All @@ -231,7 +231,7 @@ describe('Addon via env var - Released addon', () => {
process.env = originalEnv;
});

it('addons can be specified on the fly using ADDONS env var - Released addon', () => {
test('addons can be specified on the fly using ADDONS env var - Released addon', () => {
const base = path.join(__dirname, 'fixtures', 'test-volto-project');
const { registry } = AddonRegistry.init(base);
expect(
Expand Down
1 change: 1 addition & 0 deletions packages/volto/__tests__/addon-registry-volto.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import path from 'path';
import { AddonRegistry } from '@plone/registry/addon-registry';
import { describe, expect, it } from 'vitest';

describe('AddonRegistry - Volto', () => {
it('works in Volto', () => {
Expand Down
1 change: 1 addition & 0 deletions packages/volto/__tests__/create-addons-loader.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
getAddonsLoaderCode,
nameFromPackage,
} from '@plone/registry/create-addons-loader';
import { describe, expect } from 'vitest';

describe('create-addons-loader code generation', () => {
test('no addon creates simple loader, default = no loadProjectConfig', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/volto/__tests__/volto-slate/deserialize.test.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import config from '@plone/volto/registry';

import { JSDOM } from 'jsdom';
import { deserialize } from '@plone/volto-slate/editor/deserialize';
import * as htmlUtils from '@plone/volto-slate/editor/utils';
import { makeEditor } from '@plone/volto-slate/utils/editor';
import installSlate from '@plone/volto-slate/index';
import { it, describe, expect } from 'vitest';

const tojson = (html) => {
const parsed = new JSDOM(html);
Expand Down
1 change: 1 addition & 0 deletions packages/volto/__tests__/webpack-relative-resolver.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { describe, it, expect } from 'vitest';
const path = require('path');
const { AddonRegistry } = require('@plone/registry/addon-registry');
const WebpackRelativeResolver = require('../../volto/webpack-plugins/webpack-relative-resolver');
Expand Down
7 changes: 6 additions & 1 deletion packages/volto/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,14 @@
"main": "src/index.js",
"types": "types/index.d.ts",
"scripts": {
"test": "vitest",
"test:watch": "vitest --watch",
"coverage": "vitest run --coverage",
"analyze": "BUNDLE_ANALYZE=true razzle build",
"start": "make build-deps && razzle start",
"start:coresandbox": "make build-deps && ADDONS=coresandbox razzle start",
"build": "make build-deps && razzle build --noninteractive",
"build:types": "tsc --project tsconfig.declarations.json",
"test": "razzle test --maxWorkers=50%",
"test:ci": "CI=true NODE_ICU_DATA=node_modules/full-icu razzle test",
"test:husky": "CI=true yarn test --bail --findRelatedTests",
"test:debug": "node --inspect node_modules/.bin/jest --runInBand",
Expand Down Expand Up @@ -315,6 +317,8 @@
"@types/uuid": "^9.0.2",
"@typescript-eslint/eslint-plugin": "^7.7.0",
"@typescript-eslint/parser": "^7.7.0",
"@vitejs/plugin-react": "^4.3.4",
"@vitest/ui": "^2.1.8",
"autoprefixer": "10.4.8",
"axe-core": "4.4.2",
"babel-loader": "9.1.0",
Expand Down Expand Up @@ -384,6 +388,7 @@
"ts-loader": "9.4.4",
"typescript": "^5.6.3",
"use-trace-update": "1.3.2",
"vitest": "^3.0.4",
"wait-on": "6.0.0",
"webpack": "5.90.1",
"webpack-bundle-analyzer": "4.10.1",
Expand Down
6 changes: 3 additions & 3 deletions packages/volto/src/actions/actions/actions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ describe('Actions action', () => {
const url = 'http://localhost';
const action = listActions(url);

expect(action.type).toEqual(LIST_ACTIONS);
expect(action.request.op).toEqual('get');
expect(action.request.path).toEqual(`${url}/@actions`);
expect(action.type).toBe(LIST_ACTIONS);
expect(action.request.op).toBe('get');
expect(action.request.path).toBe(`${url}/@actions`);
});
});
});
27 changes: 15 additions & 12 deletions packages/volto/src/actions/addons/addons.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,35 +16,38 @@ describe('Addons action', () => {
it('should create an action to install an addon', () => {
const id = 'plone.app.example';
const action = installAddon(id);
expect(action.type).toEqual(INSTALL_ADDON);
expect(action.request.op).toEqual('post');
expect(action.request.path).toEqual(`/@addons/${id}/install`);
expect(action.type).toBe(INSTALL_ADDON);
expect(action.request.op).toBe('post');
expect(action.request.path).toBe(`/@addons/${id}/install`);
});
});

describe('uninstallAddon', () => {
it('should create an action to uninstall an addon', () => {
const id = 'plone.app.example';
const action = uninstallAddon(id);
expect(action.type).toEqual(UNINSTALL_ADDON);
expect(action.request.op).toEqual('post');
expect(action.request.path).toEqual(`/@addons/${id}/uninstall`);
expect(action.type).toBe(UNINSTALL_ADDON);
expect(action.request.op).toBe('post');
expect(action.request.path).toBe(`/@addons/${id}/uninstall`);
});
});

describe('upgradeAddon', () => {
it('should create an action to upgrade an addon', () => {
const id = 'plone.app.example';
const action = upgradeAddon(id);
expect(action.type).toEqual(UPGRADE_ADDON);
expect(action.request.op).toEqual('post');
expect(action.request.path).toEqual(`/@addons/${id}/upgrade`);
expect(action.type).toBe(UPGRADE_ADDON);
expect(action.request.op).toBe('post');
expect(action.request.path).toBe(`/@addons/${id}/upgrade`);
});
});

describe('listAddons', () => {
it('should create an action to list all addons', () => {
const action = listAddons();
expect(action.type).toEqual(LIST_ADDONS);
expect(action.request.op).toEqual('get');
expect(action.request.path).toEqual(`/@addons`);
expect(action.type).toBe(LIST_ADDONS);
expect(action.request.op).toBe('get');
expect(action.request.path).toBe(`/@addons`);
});
});
});
2 changes: 1 addition & 1 deletion packages/volto/src/actions/aliases/aliases.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { getAliases, addAliases, removeAliases } from './aliases';

import {
GET_ALIASES,
ADD_ALIASES,
Expand All @@ -18,6 +17,7 @@ describe('Aliases action', () => {
);
});
});

describe('addAliases', () => {
it('should create an action to add aliases', () => {
const url = '/news';
Expand Down
3 changes: 2 additions & 1 deletion packages/volto/src/actions/types/types.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { getTypes } from './types';
import { GET_TYPES } from '@plone/volto/constants/ActionTypes';
import { vi } from 'vitest';

describe('Types action', () => {
describe('getTypes', () => {
Expand All @@ -10,7 +11,7 @@ describe('Types action', () => {
},
});
const url = '/blog';
const dispatch = jest.fn();
const dispatch = vi.fn();

getTypes(url)(dispatch, getState);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import Actions from './Actions';

const mockStore = configureStore();

jest.mock('@plone/volto/components/manage/Contents');
vi.mock('@plone/volto/components/manage/Contents');

describe('Actions', () => {
it('renders an actions component', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`Actions renders an actions component 1`] = `
exports[`Actions > renders an actions component 1`] = `
<div
aria-expanded={false}
className="ui item dropdown"
Expand Down
11 changes: 8 additions & 3 deletions packages/volto/src/components/manage/Add/Add.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { render } from '@testing-library/react';
import configureStore from 'redux-mock-store';
import { Provider } from 'react-intl-redux';
import config from '@plone/volto/registry';

import Add from './Add';

const mockStore = configureStore();
Expand All @@ -16,9 +15,15 @@ beforeAll(() => {
config.settings.loadables = {};
});

jest.mock('../Toolbar/Toolbar', () => jest.fn(() => <div id="Portal" />));
vi.mock('../Toolbar/Toolbar', () => ({
__esModule: true,
default: vi.fn(() => <div id="Portal" />),
}));

jest.mock('../Form/Form', () => jest.fn(() => <div className="Form" />));
vi.mock('../Form/Form', () => ({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should include some docs about how mocks work, and the recommended way in usual cases, like this one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add documentation about how mocks work and the recommended approach for common cases like this. That will make it easier for others to follow.

__esModule: true,
default: vi.fn(() => <div className="Form" />),
}));

describe('Add', () => {
it('renders an empty add component', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`Add renders an add component 1`] = `
exports[`Add > renders an add component 1`] = `
<div>
<div />
</div>
`;

exports[`Add renders an add component with schema 1`] = `
exports[`Add > renders an add component with schema 1`] = `
<div>
<div />
</div>
`;

exports[`Add renders an empty add component 1`] = `
exports[`Add > renders an empty add component 1`] = `
<div>
<div />
</div>
Expand Down
10 changes: 8 additions & 2 deletions packages/volto/src/components/manage/Aliases/Aliases.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,15 @@ import Aliases from './Aliases';
const middlewares = [thunk];
const mockStore = configureMockStore(middlewares);

jest.mock('../Toolbar/Toolbar', () => jest.fn(() => <div id="Portal" />));
vi.mock('../Toolbar/Toolbar', () => ({
__esModule: true,
default: vi.fn(() => <div id="Portal" />),
}));

jest.mock('../Toolbar/More', () => jest.fn(() => <div className="More" />));
vi.mock('../Toolbar/More', () => ({
__esModule: true,
default: vi.fn(() => <div className="More" />),
}));

describe('Aliases', () => {
it('renders aliases object control', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`Aliases renders aliases object control 1`] = `
exports[`Aliases > renders aliases object control 1`] = `
<div>
<div
class="ui container"
Expand Down
Loading
Loading