Skip to content

Commit

Permalink
Switch from Jest to Vitest
Browse files Browse the repository at this point in the history
  • Loading branch information
jsynowiec committed Apr 14, 2024
1 parent e2e8c78 commit 9039a5f
Show file tree
Hide file tree
Showing 13 changed files with 2,095 additions and 3,605 deletions.
3 changes: 3 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
/**/*.js
build/**
tmp/**
coverage/**
4 changes: 2 additions & 2 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
"sourceType": "module",
"ecmaVersion": 2020
},
"plugins": ["@typescript-eslint", "jest"],
"plugins": ["@typescript-eslint", "vitest"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:jest/recommended",
"plugin:vitest/recommended",
"prettier"
],
"rules": {
Expand Down
7 changes: 3 additions & 4 deletions .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: volta-cli/action@v1
- uses: actions/checkout@v4
- uses: volta-cli/action@v4
- run: npm ci --no-audit
- run: npm run lint --if-present
- run: npm run prettier:check --if-present
- run: npm test
- run: npm run build --if-present
env:
CI: true
12 changes: 3 additions & 9 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
{
"parser": "typescript",
"semi": true,
"singleQuote": true,
"trailingComma": "all",
"overrides": [
{
"files": ["*.ts", "*.mts"],
"options": {
"parser": "typescript"
}
}
]
"trailingComma": "all"
}
20 changes: 14 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
- [TypeScript][typescript] [5.4][typescript-5-4]
- [ESM][esm]
- [ESLint][eslint] with some initial rules recommendation
- [Jest][jest] for fast unit testing and code coverage
- Type definitions for Node.js and Jest
- [Vitest][vitest] for fast unit testing and code coverage
- Type definitions for Node.js
- [Prettier][prettier] to enforce consistent code style
- NPM [scripts](#available-scripts) for common operations
- [EditorConfig][editorconfig] for consistent coding style
Expand Down Expand Up @@ -53,22 +53,31 @@ unzip node-typescript-boilerplate.zip && rm node-typescript-boilerplate.zip

## Available Scripts

- `clean` - remove coverage data, Jest cache and transpiled files,
- `clean` - remove coverage data, cache and transpiled files,
- `prebuild` - lint source files and tests before building,
- `build` - transpile TypeScript to ES6,
- `build:watch` - interactive watch mode to automatically transpile source files,
- `lint` - lint source files and tests,
- `prettier` - reformat files,
- `test` - run tests,
- `test:watch` - interactive watch mode to automatically re-run tests
- `test:coverage` - run test and print out test coverage

## Additional Information

### Why include Volta

I recommend to [install][volta-getting-started] Volta and use it to manage your project's toolchain.

[Volta][volta]’s toolchain always keeps track of where you are, it makes sure the tools you use always respect the settings of the project you’re working on. This means you don’t have to worry about changing the state of your installed software when switching between projects. For example, it's [used by engineers at LinkedIn][volta-tomdale] to standardize tools and have reproducible development environments.

I recommend to [install][volta-getting-started] Volta and use it to manage your project's toolchain.
### Why Vitest instead of Jest

I recommend using [Vitest][vitest] for unit and integration testing of your TypeScript code.

In 2023, my team and I gradually switched from Jest to [Vitest][vitest] in all the projects. We've found out that generally, Vitest is faster than Jest, especially for large test suits. Furthermore, Vitest has native support for ES modules, is easier to configure, and has a much nicer developer experience when used with TypeScript. For example, when working with mocks, spies and types.

Nevertheless, the choice of specific tooling always depends on the specific requirements and characteristics of the project.

### ES Modules

Expand Down Expand Up @@ -97,9 +106,7 @@ Licensed under the APLv2. See the [LICENSE](https://github.com/jsynowiec/node-ty
[license]: https://github.com/jsynowiec/node-typescript-boilerplate/blob/main/LICENSE
[sponsor-badge]: https://img.shields.io/badge/♥-Sponsor-fc0fb5.svg
[sponsor]: https://github.com/sponsors/jsynowiec
[jest]: https://facebook.github.io/jest/
[eslint]: https://github.com/eslint/eslint
[wiki-js-tests]: https://github.com/jsynowiec/node-typescript-boilerplate/wiki/Unit-tests-in-plain-JavaScript
[prettier]: https://prettier.io
[volta]: https://volta.sh
[volta-getting-started]: https://docs.volta.sh/guide/getting-started
Expand All @@ -111,3 +118,4 @@ Licensed under the APLv2. See the [LICENSE](https://github.com/jsynowiec/node-ty
[nodejs-esm]: https://nodejs.org/docs/latest-v16.x/api/esm.html
[ts47-esm]: https://devblogs.microsoft.com/typescript/announcing-typescript-4-7/#esm-nodejs
[editorconfig]: https://editorconfig.org
[vitest]: https://vitest.dev
42 changes: 0 additions & 42 deletions __tests__/main.test.ts

This file was deleted.

40 changes: 40 additions & 0 deletions __tests__/unit/main.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { describe, it, afterEach, beforeEach, vi, expect } from 'vitest';
import { Delays, greeter } from '../../src/main.js';

describe('greeter function', () => {
const name = 'John';

beforeEach(() => {
// Read more about fake timers
// https://vitest.dev/api/vi.html#vi-usefaketimers
vi.useFakeTimers();
});

afterEach(() => {
vi.useRealTimers();
vi.restoreAllMocks();
});

// Assert if setTimeout was called properly
it('delays the greeting by 2 seconds', async () => {
vi.spyOn(global, 'setTimeout');
const p = greeter(name);

await vi.runAllTimersAsync();
await p;

expect(setTimeout).toHaveBeenCalledTimes(1);
expect(setTimeout).toHaveBeenLastCalledWith(
expect.any(Function),
Delays.Long,
);
});

// Assert greeter result
it('greets a user with `Hello, {name}` message', async () => {
const p = greeter(name);
await vi.runAllTimersAsync();

expect(await p).toBe(`Hello, ${name}`);
});
});
18 changes: 0 additions & 18 deletions jest.config.js

This file was deleted.

Loading

0 comments on commit 9039a5f

Please sign in to comment.