diff --git a/libs/image-utils/.eslintignore b/libs/image-utils/.eslintignore index f84d3c9b8c..2efc8cd24a 100644 --- a/libs/image-utils/.eslintignore +++ b/libs/image-utils/.eslintignore @@ -1,4 +1,4 @@ bin build coverage -jest.config.js \ No newline at end of file +vitest.config.mts \ No newline at end of file diff --git a/libs/image-utils/jest.config.js b/libs/image-utils/jest.config.js deleted file mode 100644 index a686134604..0000000000 --- a/libs/image-utils/jest.config.js +++ /dev/null @@ -1,13 +0,0 @@ -const shared = require('../../jest.config.shared'); - -/** - * @type {import('@jest/types').Config.InitialOptions} - */ -module.exports = { - ...shared, - coveragePathIgnorePatterns: [ - 'src/jest_pdf_snapshot.ts', - 'src/cli/pdf_to_images.ts', - ], - setupFilesAfterEnv: ['/test/setupTests.ts'], -}; diff --git a/libs/image-utils/package.json b/libs/image-utils/package.json index 68e8bf31c9..4bed97ccf0 100644 --- a/libs/image-utils/package.json +++ b/libs/image-utils/package.json @@ -14,9 +14,9 @@ "lint": "pnpm type-check && eslint .", "lint:fix": "pnpm type-check && eslint . --fix", "test": "is-ci test:ci test:watch", - "test:ci": "jest --coverage --ci --reporters=default --reporters=jest-junit --maxWorkers=6", - "test:coverage": "jest --coverage", - "test:watch": "jest --watch" + "test:ci": "vitest run --coverage", + "test:coverage": "vitest --coverage", + "test:watch": "vitest" }, "packageManager": "pnpm@8.15.5", "dependencies": { @@ -32,23 +32,19 @@ "tmp": "^0.2.1" }, "devDependencies": { - "@jest/types": "^29.6.1", "@types/debug": "4.1.8", - "@types/jest": "^29.5.3", "@types/jest-image-snapshot": "^6.4.0", "@types/node": "20.16.0", "@types/pdfjs-dist": "2.1.3", "@types/pixelmatch": "^5.2.6", "@types/tmp": "0.2.4", + "@vitest/coverage-istanbul": "^2.1.8", "esbuild": "0.21.2", "esbuild-runner": "2.2.2", "eslint-plugin-vx": "workspace:*", "fast-check": "2.23.2", "is-ci-cli": "2.2.0", - "jest": "^29.6.2", - "jest-junit": "^16.0.0", - "jest-watch-typeahead": "^2.2.2", "lint-staged": "11.0.0", - "ts-jest": "29.1.1" + "vitest": "^2.1.8" } } diff --git a/libs/image-utils/src/crop.test.ts b/libs/image-utils/src/crop.test.mts similarity index 92% rename from libs/image-utils/src/crop.test.ts rename to libs/image-utils/src/crop.test.mts index d29d832462..534c0b3fc9 100644 --- a/libs/image-utils/src/crop.test.ts +++ b/libs/image-utils/src/crop.test.mts @@ -1,10 +1,11 @@ +import { expect, test } from 'vitest'; import { Rect } from '@votingworks/types'; import { createImageData, ImageData } from 'canvas'; import fc from 'fast-check'; -import { arbitraryImageData, arbitraryRect } from '../test/arbitraries'; -import { crop } from './crop'; -import { int } from './types'; -import { RGBA_CHANNEL_COUNT } from '.'; +import { arbitraryImageData, arbitraryRect } from '../test/arbitraries.mjs'; +import { crop } from './crop.js'; +import { int } from './types.js'; +import { RGBA_CHANNEL_COUNT } from './index.js'; /** * A slow-but-accurate implementation of `crop` to compare against. diff --git a/libs/image-utils/src/image_data.test.ts b/libs/image-utils/src/image_data.test.mts similarity index 98% rename from libs/image-utils/src/image_data.test.ts rename to libs/image-utils/src/image_data.test.mts index 47c164f43f..837e41a196 100644 --- a/libs/image-utils/src/image_data.test.ts +++ b/libs/image-utils/src/image_data.test.mts @@ -1,3 +1,4 @@ +import { expect, test } from 'vitest'; import { Buffer } from 'node:buffer'; import { ImageData, createImageData } from 'canvas'; import fc from 'fast-check'; @@ -5,7 +6,7 @@ import { writeFile } from 'node:fs/promises'; import { fileSync } from 'tmp'; import { randomFillSync } from 'node:crypto'; import { MaybePromise } from '@votingworks/basics'; -import { arbitraryImageData } from '../test/arbitraries'; +import { arbitraryImageData } from '../test/arbitraries.mjs'; import { RGBA_CHANNEL_COUNT, encodeImageData, @@ -17,7 +18,7 @@ import { toDataUrl, toImageBuffer, writeImageData, -} from './image_data'; +} from './image_data.js'; test('channels', () => { const rgbaImage = createImageData(1, 1); diff --git a/libs/image-utils/src/jest_match_image.test.ts b/libs/image-utils/src/jest_match_image.test.mts similarity index 97% rename from libs/image-utils/src/jest_match_image.test.ts rename to libs/image-utils/src/jest_match_image.test.mts index 8246b43cb6..935ffb0ad0 100644 --- a/libs/image-utils/src/jest_match_image.test.ts +++ b/libs/image-utils/src/jest_match_image.test.mts @@ -1,7 +1,8 @@ +import { expect, test } from 'vitest'; import { sampleBallotImages } from '@votingworks/fixtures'; import { createImageData } from 'canvas'; import { basename } from 'node:path'; -import { crop } from './crop'; +import { crop } from './crop.js'; test('matching images', async () => { const image = createImageData(1, 1); diff --git a/libs/image-utils/src/numeric.test.ts b/libs/image-utils/src/numeric.test.mts similarity index 96% rename from libs/image-utils/src/numeric.test.ts rename to libs/image-utils/src/numeric.test.mts index 752a054bc0..2470e63bb7 100644 --- a/libs/image-utils/src/numeric.test.ts +++ b/libs/image-utils/src/numeric.test.mts @@ -1,5 +1,6 @@ +import { expect, test } from 'vitest'; import fc from 'fast-check'; -import { assertInteger, EPSILON, isCloseToZero } from './numeric'; +import { assertInteger, EPSILON, isCloseToZero } from './numeric.js'; test('isCloseToZero', () => { expect(isCloseToZero(0)).toEqual(true); diff --git a/libs/image-utils/src/pdf_to_images.test.ts b/libs/image-utils/src/pdf_to_images.test.mts similarity index 96% rename from libs/image-utils/src/pdf_to_images.test.ts rename to libs/image-utils/src/pdf_to_images.test.mts index 356baeb32f..2f497edbc1 100644 --- a/libs/image-utils/src/pdf_to_images.test.ts +++ b/libs/image-utils/src/pdf_to_images.test.mts @@ -1,3 +1,4 @@ +import { expect, test } from 'vitest'; import { iter } from '@votingworks/basics'; import { electionGridLayoutNewHampshireHudsonFixtures } from '@votingworks/fixtures'; import { Size } from '@votingworks/types'; @@ -9,7 +10,7 @@ import { parsePdf, pdfToImages, setPdfRenderWorkerSrc, -} from './pdf_to_images'; +} from './pdf_to_images.js'; const pdfNotRequiringPdfjsIntermediateCanvasBuffer = readFileSync( join( diff --git a/libs/image-utils/test/arbitraries.ts b/libs/image-utils/test/arbitraries.mts similarity index 97% rename from libs/image-utils/test/arbitraries.ts rename to libs/image-utils/test/arbitraries.mts index 300ea807b1..d7524a1d90 100644 --- a/libs/image-utils/test/arbitraries.ts +++ b/libs/image-utils/test/arbitraries.mts @@ -2,8 +2,8 @@ import { assert } from '@votingworks/basics'; import { Rect } from '@votingworks/types'; import { createImageData, ImageData } from 'canvas'; import fc from 'fast-check'; -import { int, RGBA_CHANNEL_COUNT } from '../src'; -import { assertInteger } from '../src/numeric'; +import { int, RGBA_CHANNEL_COUNT } from '../src/index.js'; +import { assertInteger } from '../src/numeric.js'; /** * Options for building an arbitrary image data. diff --git a/libs/image-utils/test/arbitraries.test.ts b/libs/image-utils/test/arbitraries.test.mts similarity index 97% rename from libs/image-utils/test/arbitraries.test.ts rename to libs/image-utils/test/arbitraries.test.mts index 00dcde4d5e..5da640d30c 100644 --- a/libs/image-utils/test/arbitraries.test.ts +++ b/libs/image-utils/test/arbitraries.test.mts @@ -1,6 +1,7 @@ +import { expect, test } from 'vitest'; import fc from 'fast-check'; -import { assertInteger } from '../src/numeric'; -import { arbitraryImageData, arbitraryRect } from './arbitraries'; +import { assertInteger } from '../src/numeric.js'; +import { arbitraryImageData, arbitraryRect } from './arbitraries.mjs'; test('arbitraryImageData has sensible values', () => { fc.assert( diff --git a/libs/image-utils/test/setupTests.ts b/libs/image-utils/test/setupTests.ts index 2b02085c56..d91217a0a4 100644 --- a/libs/image-utils/test/setupTests.ts +++ b/libs/image-utils/test/setupTests.ts @@ -1,4 +1,5 @@ import { ImageData } from 'canvas'; +import { expect } from 'vitest'; import { toMatchImage, ToMatchImageOptions } from '../src'; declare global { diff --git a/libs/image-utils/tsconfig.build.json b/libs/image-utils/tsconfig.build.json index 231e6621ec..8cd64d18d7 100644 --- a/libs/image-utils/tsconfig.build.json +++ b/libs/image-utils/tsconfig.build.json @@ -1,7 +1,12 @@ { "extends": "./tsconfig.json", "include": ["src"], - "exclude": ["**/*.test.ts", "**/*.test.tsx"], + "exclude": [ + "**/*.test.ts", + "**/*.test.tsx", + "**/*.test.mts", + "**/*.test.mtsx" + ], "compilerOptions": { "noEmit": false, "outDir": "build", diff --git a/libs/image-utils/vitest.config.mts b/libs/image-utils/vitest.config.mts new file mode 100644 index 0000000000..2b249733b9 --- /dev/null +++ b/libs/image-utils/vitest.config.mts @@ -0,0 +1,10 @@ +import { defineConfig } from '../../vitest.config.shared.mjs'; + +export default defineConfig({ + test: { + setupFiles: ['test/setupTests.ts'], + coverage: { + exclude: ['src/jest_pdf_snapshot.ts', 'src/cli/pdf_to_images.ts'], + }, + }, +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 270e92c51d..f3508e9ca7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4534,15 +4534,9 @@ importers: specifier: ^0.2.1 version: 0.2.1 devDependencies: - '@jest/types': - specifier: ^29.6.1 - version: 29.6.1 '@types/debug': specifier: 4.1.8 version: 4.1.8 - '@types/jest': - specifier: ^29.5.3 - version: 29.5.3 '@types/jest-image-snapshot': specifier: ^6.4.0 version: 6.4.0 @@ -4558,6 +4552,9 @@ importers: '@types/tmp': specifier: 0.2.4 version: 0.2.4 + '@vitest/coverage-istanbul': + specifier: ^2.1.8 + version: 2.1.8(vitest@2.1.8) esbuild: specifier: 0.21.2 version: 0.21.2 @@ -4573,21 +4570,12 @@ importers: is-ci-cli: specifier: 2.2.0 version: 2.2.0 - jest: - specifier: ^29.6.2 - version: 29.6.2(@types/node@20.16.0) - jest-junit: - specifier: ^16.0.0 - version: 16.0.0 - jest-watch-typeahead: - specifier: ^2.2.2 - version: 2.2.2(jest@29.6.2) lint-staged: specifier: 11.0.0 version: 11.0.0 - ts-jest: - specifier: 29.1.1 - version: 29.1.1(@babel/core@7.26.0)(@jest/types@29.6.1)(esbuild@0.21.2)(jest@29.6.2)(typescript@5.6.2) + vitest: + specifier: ^2.1.8 + version: 2.1.8(@types/node@20.16.0) libs/logging: dependencies: