Use turbo for all unit tests (#5815)

- Upgrade vitest from 1.x to 3.x.
  - Fix some tests that now became more strict and started failing
-  Add test command to all packages + needed dependencies
- Add turbo config for running tests

Another PR will completely redo the e2e test suite.
This commit is contained in:
Merlijn Vos 2025-07-12 13:21:35 +02:00 committed by GitHub
parent 33e4b37106
commit 7c609a56d9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 697 additions and 467 deletions

View file

@ -1,4 +1,4 @@
name: Test different bundlers with Uppy
name: Bundlers
on:
push:

View file

@ -34,8 +34,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
# fix node versions so we don't get sudden unrelated CI breakage
node-version: [18.20.8, 20.19.1]
node-version: [lts/*]
steps:
- name: Checkout sources
uses: actions/checkout@v4
@ -66,7 +65,7 @@ jobs:
- name: Build
run: corepack yarn run build
- name: Run tests
run: corepack yarn run test:unit
run: corepack yarn run test
types:
name: Type tests

View file

@ -1,16 +0,0 @@
diff --git a/dist/error.d.ts b/dist/error.d.ts
index bd657d5311ff3d255dc57a2f7224301d532a3177..8924e0982c64c566f4d9808cde62292d7ed334ac 100644
--- a/dist/error.d.ts
+++ b/dist/error.d.ts
@@ -1,9 +1,9 @@
import { D as DiffOptions } from './types-widbdqe5.js';
import 'pretty-format';
-declare function serializeError(val: any, seen?: WeakMap<WeakKey, any>): any;
+declare function serializeError(val: any, seen?: WeakMap<object, any>): any;
declare function processError(err: any, diffOptions?: DiffOptions): any;
-declare function replaceAsymmetricMatcher(actual: any, expected: any, actualReplaced?: WeakSet<WeakKey>, expectedReplaced?: WeakSet<WeakKey>): {
+declare function replaceAsymmetricMatcher(actual: any, expected: any, actualReplaced?: WeakSet<object>, expectedReplaced?: WeakSet<object>): {
replacedActual: any;
replacedExpected: any;
};

View file

@ -16,6 +16,7 @@
"scripts": {
"build": "turbo run build build:css --filter='./packages/@uppy/*' --filter='./packages/uppy'",
"build:clean": "cp .gitignore .gitignore.bak && printf '!node_modules\n!**/node_modules/**/*\n' >> .gitignore; git clean -Xfd packages e2e .parcel-cache coverage; mv .gitignore.bak .gitignore",
"build:watch": "turbo watch build build:css --filter='./packages/@uppy/*'",
"migrate:components": "yarn workspace @uppy/components migrate",
"check": "yarn exec biome check --write",
"check:ci": "yarn exec biome ci",
@ -31,25 +32,15 @@
"size": "echo 'JS Bundle mingz:' && cat ./packages/uppy/dist/uppy.min.js | gzip | wc -c && echo 'CSS Bundle mingz:' && cat ./packages/uppy/dist/uppy.min.css | gzip | wc -c",
"start:companion": "yarn workspace @uppy/companion start:dev",
"start:companion:with-loadbalancer": "e2e/start-companion-with-load-balancer.mjs",
"test": "npm-run-all lint test:locale-pack test:unit test:companion",
"test:companion": "yarn workspace @uppy/companion test",
"test:companion:watch": "yarn workspace @uppy/companion test --watch",
"test:locale-packs": "yarn locale-packs:unused && yarn locale-packs:warnings",
"test:locale-packs:unused": "yarn workspace @uppy-dev/locale-pack test unused",
"test:locale-packs:warnings": "yarn workspace @uppy-dev/locale-pack test warnings",
"test:unit": "yarn test:watch --run",
"test:watch": "vitest --environment jsdom --dir packages/@uppy",
"test": "turbo run test --filter='./packages/@uppy/*' --filter='./packages/uppy'",
"test:watch": "turbo watch test --filter='./packages/@uppy/*' --filter='./packages/uppy'",
"typecheck": "turbo run typecheck --filter='./packages/@uppy/*' --filter='./packages/uppy'",
"watch": "turbo watch build build:css --filter='./packages/@uppy/*'",
"test:locale-pack": "yarn workspace @uppy/locales test",
"test:ts": "yarn tsc -b && yarn workspace @uppy/svelte check",
"uploadcdn": "yarn workspace uppy exec -- node upload-to-cdn.js",
"version": "yarn node ./bin/after-version-bump.js"
},
"resolutions": {
"@types/react": "^18",
"@types/webpack-dev-server": "^4",
"@vitest/utils": "patch:@vitest/utils@npm%3A1.2.1#./.yarn/patches/@vitest-utils-npm-1.2.1-3028846845.patch",
"p-queue": "patch:p-queue@npm%3A8.0.1#~/.yarn/patches/p-queue-npm-8.0.1-fe1ddcd827.patch",
"resize-observer-polyfill": "patch:resize-observer-polyfill@npm%3A1.5.1#./.yarn/patches/resize-observer-polyfill-npm-1.5.1-603120e8a0.patch",
"start-server-and-test": "patch:start-server-and-test@npm:1.14.0#.yarn/patches/start-server-and-test-npm-1.14.0-841aa34fdf.patch",
@ -57,12 +48,10 @@
},
"devDependencies": {
"@biomejs/biome": "2.0.5",
"jsdom": "^26.1.0",
"npm-run-all": "^4.1.5",
"start-server-and-test": "^1.14.0",
"turbo": "^2.5.4",
"typescript": "^5.8.3",
"vitest": "^1.6.1",
"vue-template-compiler": "workspace:*"
},
"packageManager": "yarn@4.4.1+sha224.fd21d9eb5fba020083811af1d4953acc21eeb9f6ff97efd1b3f9d4de",

View file

@ -5,8 +5,7 @@
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test"
"watch": "ng build --watch --configuration development"
},
"private": true,
"dependencies": {

View file

@ -30,11 +30,12 @@
},
"devDependencies": {
"cssnano": "^7.0.7",
"jsdom": "^26.1.0",
"postcss": "^8.5.6",
"postcss-cli": "^11.0.1",
"sass": "^1.89.2",
"typescript": "^5.8.3",
"vitest": "^1.6.1"
"vitest": "^3.2.4"
},
"peerDependencies": {
"@uppy/core": "workspace:^"
@ -45,6 +46,7 @@
"scripts": {
"build": "tsc --build tsconfig.build.json",
"build:css": "sass --load-path=../../ src/style.scss dist/style.css && postcss dist/style.css -u cssnano -o dist/style.min.css",
"typecheck": "tsc --build"
"typecheck": "tsc --build",
"test": "vitest run --environment=jsdom --silent='passed-only'"
}
}

View file

@ -7,7 +7,8 @@
"type": "module",
"scripts": {
"build": "tsc --build tsconfig.build.json",
"typecheck": "tsc --build"
"typecheck": "tsc --build",
"test": "vitest run --environment=jsdom --silent='passed-only'"
},
"keywords": [
"file uploader",
@ -33,9 +34,10 @@
"devDependencies": {
"@aws-sdk/client-s3": "^3.362.0",
"@aws-sdk/s3-request-presigner": "^3.362.0",
"jsdom": "^26.1.0",
"nock": "^13.1.0",
"typescript": "^5.8.3",
"vitest": "^1.6.1",
"vitest": "^3.2.4",
"whatwg-fetch": "3.6.2"
},
"peerDependencies": {

View file

@ -0,0 +1,4 @@
import { webcrypto } from 'node:crypto'
import { vi } from 'vitest'
vi.stubGlobal('crypto', webcrypto)

View file

@ -0,0 +1,7 @@
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
setupFiles: ['./test-setup.mjs'],
},
})

View file

@ -7,7 +7,8 @@
"type": "module",
"scripts": {
"build": "tsc --build tsconfig.build.json",
"typecheck": "tsc --build"
"typecheck": "tsc --build",
"test": "vitest run --environment=jsdom --silent='passed-only'"
},
"keywords": [
"file uploader",
@ -30,8 +31,9 @@
"p-retry": "^6.1.0"
},
"devDependencies": {
"jsdom": "^26.1.0",
"typescript": "^5.8.3",
"vitest": "^1.6.1"
"vitest": "^3.2.4"
},
"peerDependencies": {
"@uppy/core": "workspace:^"

View file

@ -87,7 +87,8 @@
"jest": "^29.0.0",
"nock": "^13.1.3",
"supertest": "6.2.4",
"typescript": "^5.8.3"
"typescript": "^5.8.3",
"vitest": "^3.2.4"
},
"files": [
"bin/",
@ -96,19 +97,14 @@
"jest": {
"testEnvironment": "node",
"testTimeout": 10000,
"automock": false,
"collectCoverage": true,
"collectCoverageFrom": [
"src/**",
"!src/**/*.d.ts"
]
"automock": false
},
"scripts": {
"build": "tsc -p .",
"deploy": "kubectl apply -f infra/kube/companion-kube.yml",
"start": "node ./lib/standalone/start-server.js",
"start:dev": "bash start-dev",
"test": "NODE_OPTIONS=--experimental-vm-modules jest --runInBand",
"test": "NODE_OPTIONS=--experimental-vm-modules jest --runInBand --silent",
"typecheck": "tsc --build"
},
"engines": {

View file

@ -35,11 +35,13 @@
"access": "public"
},
"devDependencies": {
"jsdom": "^26.1.0",
"typescript": "^5.8.3",
"vitest": "^1.6.1"
"vitest": "^3.2.4"
},
"scripts": {
"build": "tsc --build tsconfig.build.json",
"typecheck": "tsc --build"
"typecheck": "tsc --build",
"test": "vitest run --environment=jsdom --silent='passed-only'"
}
}

View file

@ -12,7 +12,8 @@
"scripts": {
"build": "tsc --build tsconfig.build.json",
"build:css": "sass --load-path=../../ src/style.scss dist/style.css && postcss dist/style.css -u cssnano -o dist/style.min.css",
"typecheck": "tsc --build"
"typecheck": "tsc --build",
"test": "vitest run --environment=jsdom --silent='passed-only'"
},
"keywords": [
"file uploader",
@ -39,10 +40,11 @@
},
"devDependencies": {
"cssnano": "^7.0.7",
"jsdom": "^26.1.0",
"postcss": "^8.5.6",
"postcss-cli": "^11.0.1",
"sass": "^1.89.2",
"typescript": "^5.8.3",
"vitest": "^1.6.1"
"vitest": "^3.2.4"
}
}

View file

@ -18,6 +18,7 @@ import AcquirerPlugin2 from './mocks/acquirerPlugin2.js'
import InvalidPlugin from './mocks/invalidPlugin.js'
import InvalidPluginWithoutId from './mocks/invalidPluginWithoutId.js'
import InvalidPluginWithoutType from './mocks/invalidPluginWithoutType.js'
import { RestrictionError } from './Restricter.js'
import UIPlugin from './UIPlugin.js'
import type { State } from './Uppy.js'
@ -1282,10 +1283,8 @@ describe('src/Core', () => {
data: testImage,
})
return core.upload().catch((err) => {
expect(err).toMatchObject(
new Error(
'Not starting the upload because onBeforeUpload returned false',
),
expect(err.message).toStrictEqual(
'Not starting the upload because onBeforeUpload returned false',
)
})
})
@ -1615,7 +1614,8 @@ describe('src/Core', () => {
data: new File([sampleImage], { type: 'image/png' }),
})
} catch (err) {
expect(err).toMatchObject(new Error('You can only upload: image/jpeg'))
expect(err).toBeInstanceOf(RestrictionError)
expect(err.message).toEqual('You can only upload: image/jpeg')
}
core.setOptions({
@ -1631,8 +1631,9 @@ describe('src/Core', () => {
data: new File([sampleImage], { type: 'image/png' }),
})
} catch (err) {
expect(err).toMatchObject(
new Error('Vous pouvez seulement téléverser: image/jpeg'),
expect(err).toBeInstanceOf(RestrictionError)
expect(err.message).toEqual(
'Vous pouvez seulement téléverser: image/jpeg',
)
}
@ -2069,7 +2070,8 @@ describe('src/Core', () => {
})
throw new Error('should have thrown')
} catch (err) {
expect(err).toMatchObject(new Error('You can only upload 1 file'))
expect(err).toBeInstanceOf(RestrictionError)
expect(err.message).toStrictEqual('You can only upload 1 file')
expect(core.getState().info[0].message).toEqual(
'You can only upload 1 file',
)
@ -2121,8 +2123,9 @@ describe('src/Core', () => {
})
throw new Error('should have thrown')
} catch (err) {
expect(err).toMatchObject(
new Error('You can only upload: image/gif, image/png'),
expect(err).toBeInstanceOf(RestrictionError)
expect(err.message).toStrictEqual(
'You can only upload: image/gif, image/png',
)
expect(core.getState().info[0].message).toEqual(
'You can only upload: image/gif, image/png',
@ -2162,8 +2165,8 @@ describe('src/Core', () => {
})
throw new Error('should have thrown')
} catch (err) {
expect(err).toMatchObject(
new Error('You can only upload: .gif, .jpg, .jpeg'),
expect(err.message).toStrictEqual(
'You can only upload: .gif, .jpg, .jpeg',
)
expect(core.getState().info[0].message).toEqual(
'You can only upload: .gif, .jpg, .jpeg',
@ -2196,8 +2199,8 @@ describe('src/Core', () => {
})
throw new Error('should have thrown')
} catch (err) {
expect(err).toMatchObject(
new Error('foo.jpg exceeds maximum allowed size of 1.2 KB'),
expect(err.message).toStrictEqual(
'foo.jpg exceeds maximum allowed size of 1.2 KB',
)
expect(core.getState().info[0].message).toEqual(
'foo.jpg exceeds maximum allowed size of 1.2 KB',
@ -2221,8 +2224,8 @@ describe('src/Core', () => {
})
throw new Error('should have thrown')
} catch (err) {
expect(err).toMatchObject(
new Error('This file is smaller than the allowed size of 1 GB'),
expect(err.message).toStrictEqual(
'This file is smaller than the allowed size of 1 GB',
)
expect(core.getState().info[0].message).toEqual(
'This file is smaller than the allowed size of 1 GB',
@ -2252,7 +2255,7 @@ describe('src/Core', () => {
data: testImage,
})
}).toThrowError(
new Error(
new RestrictionError(
'You selected 34 KB of files, but maximum allowed size is 20 KB',
),
)

View file

@ -9,7 +9,8 @@
"scripts": {
"build": "tsc --build tsconfig.build.json",
"build:css": "sass --load-path=../../ src/style.scss dist/style.css && postcss dist/style.css -u cssnano -o dist/style.min.css",
"typecheck": "tsc --build"
"typecheck": "tsc --build",
"test": "vitest run --environment=jsdom --silent='passed-only'"
},
"keywords": [
"file uploader",
@ -45,12 +46,13 @@
"@uppy/url": "workspace:^",
"@uppy/webcam": "workspace:^",
"cssnano": "^7.0.7",
"jsdom": "^26.1.0",
"postcss": "^8.5.6",
"postcss-cli": "^11.0.1",
"resize-observer-polyfill": "^1.5.0",
"sass": "^1.89.2",
"typescript": "^5.8.3",
"vitest": "^1.6.1"
"vitest": "^3.2.4"
},
"peerDependencies": {
"@uppy/core": "workspace:^"

View file

@ -9,7 +9,8 @@
"scripts": {
"build": "tsc --build tsconfig.build.json",
"build:css": "sass --load-path=../../ src/style.scss dist/style.css && postcss dist/style.css -u cssnano -o dist/style.min.css",
"typecheck": "tsc --build"
"typecheck": "tsc --build",
"test": "vitest run --environment=jsdom --silent='passed-only'"
},
"keywords": [
"file uploader",
@ -35,11 +36,12 @@
"@types/google.accounts": "^0.0.14",
"@types/google.picker": "^0.0.42",
"cssnano": "^7.0.7",
"jsdom": "^26.1.0",
"postcss": "^8.5.6",
"postcss-cli": "^11.0.1",
"sass": "^1.89.2",
"typescript": "^5.8.3",
"vitest": "^1.6.1"
"vitest": "^3.2.4"
},
"peerDependencies": {
"@uppy/core": "workspace:^"

View file

@ -8,7 +8,8 @@
"scripts": {
"build": "tsc --build tsconfig.build.json",
"build:css": "mkdir -p dist && cp ../components/dist/styles.css dist/styles.css",
"typecheck": "tsc --build"
"typecheck": "tsc --build",
"test": "vitest run --environment=jsdom --silent='passed-only'"
},
"keywords": [
"file uploader",
@ -36,9 +37,11 @@
"@testing-library/react": "^14.2.2",
"@types/react": "^18.0.8",
"@types/use-sync-external-store": "^0.0.6",
"jsdom": "^26.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"typescript": "^5.8.3"
"typescript": "^5.8.3",
"vitest": "^3.2.4"
},
"peerDependencies": {
"@uppy/core": "workspace:^",

View file

@ -7,7 +7,8 @@
"type": "module",
"scripts": {
"build": "tsc --build tsconfig.build.json",
"typecheck": "tsc --build"
"typecheck": "tsc --build",
"test": "vitest run --environment=jsdom --silent='passed-only'"
},
"keywords": [
"file uploader",
@ -48,8 +49,9 @@
"access": "public"
},
"devDependencies": {
"jsdom": "^26.1.0",
"resize-observer-polyfill": "^1.5.1",
"typescript": "^5.8.3",
"vitest": "^1.6.1"
"vitest": "^3.2.4"
}
}

View file

@ -7,7 +7,8 @@
"type": "module",
"scripts": {
"build": "tsc --build tsconfig.build.json",
"typecheck": "tsc --build"
"typecheck": "tsc --build",
"test": "vitest run --environment=jsdom --silent='passed-only'"
},
"keywords": [
"file uploader",
@ -19,8 +20,9 @@
"url": "https://github.com/transloadit/uppy/issues"
},
"devDependencies": {
"jsdom": "^26.1.0",
"typescript": "^5.8.3",
"vitest": "^1.6.1"
"vitest": "^3.2.4"
},
"repository": {
"type": "git",

View file

@ -23,11 +23,13 @@
"nanoid": "^5.0.9"
},
"devDependencies": {
"jsdom": "^26.1.0",
"redux": "^4.0.0",
"vitest": "^1.6.1"
"vitest": "^3.2.4"
},
"scripts": {
"build": "tsc --build tsconfig.build.json",
"typecheck": "tsc --build"
"typecheck": "tsc --build",
"test": "vitest run --environment=jsdom --silent='passed-only'"
}
}

View file

@ -7,7 +7,8 @@
"type": "module",
"scripts": {
"build": "tsc --build tsconfig.build.json",
"typecheck": "tsc --build"
"typecheck": "tsc --build",
"test": "vitest run --environment=jsdom --silent='passed-only'"
},
"keywords": [
"file uploader",
@ -30,9 +31,10 @@
"exifr": "^7.0.0"
},
"devDependencies": {
"jsdom": "^26.1.0",
"namespace-emitter": "2.0.1",
"typescript": "^5.8.3",
"vitest": "^1.6.1"
"vitest": "^3.2.4"
},
"peerDependencies": {
"@uppy/core": "workspace:^"

View file

@ -7,7 +7,8 @@
"type": "module",
"scripts": {
"build": "tsc --build tsconfig.build.json",
"typecheck": "tsc --build"
"typecheck": "tsc --build",
"test": "vitest run --environment=jsdom --silent='passed-only'"
},
"keywords": [
"file uploader",
@ -41,8 +42,9 @@
"@uppy/core": "workspace:^"
},
"devDependencies": {
"jsdom": "^26.1.0",
"typescript": "^5.8.3",
"vitest": "^1.6.1",
"vitest": "^3.2.4",
"whatwg-fetch": "^3.6.2"
}
}

View file

@ -7,7 +7,8 @@
"type": "module",
"scripts": {
"build": "tsc --build tsconfig.build.json",
"typecheck": "tsc --build"
"typecheck": "tsc --build",
"test": "vitest run --environment=jsdom --silent='passed-only'"
},
"keywords": [
"file uploader",
@ -31,8 +32,9 @@
"tus-js-client": "^4.2.3"
},
"devDependencies": {
"jsdom": "^26.1.0",
"typescript": "^5.8.3",
"vitest": "^1.6.1"
"vitest": "^3.2.4"
},
"peerDependencies": {
"@uppy/core": "workspace:^"

View file

@ -6,7 +6,8 @@
"type": "module",
"scripts": {
"build": "tsc --build tsconfig.build.json",
"typecheck": "tsc --build"
"typecheck": "tsc --build",
"test": "vitest run --environment=jsdom --silent='passed-only'"
},
"keywords": [
"file uploader",
@ -81,7 +82,8 @@
},
"devDependencies": {
"@types/lodash": "^4.14.199",
"jsdom": "^26.1.0",
"typescript": "^5.8.3",
"vitest": "^1.6.1"
"vitest": "^3.2.4"
}
}

View file

@ -9,7 +9,8 @@
"scripts": {
"build": "tsc --build tsconfig.build.json",
"build:css": "sass --load-path=../../ src/style.scss dist/style.css && postcss dist/style.css -u cssnano -o dist/style.min.css",
"typecheck": "tsc --build"
"typecheck": "tsc --build",
"test": "vitest run --environment=jsdom --silent='passed-only'"
},
"keywords": [
"file uploader",
@ -37,11 +38,12 @@
},
"devDependencies": {
"cssnano": "^7.0.7",
"jsdom": "^26.1.0",
"postcss": "^8.5.6",
"postcss-cli": "^11.0.1",
"sass": "^1.89.2",
"typescript": "^5.8.3",
"vitest": "^1.6.1"
"vitest": "^3.2.4"
},
"peerDependencies": {
"@uppy/core": "workspace:^"

View file

@ -7,7 +7,8 @@
"type": "module",
"scripts": {
"build": "tsc --build tsconfig.build.json",
"typecheck": "tsc --build"
"typecheck": "tsc --build",
"test": "vitest run --environment=jsdom --silent='passed-only'"
},
"keywords": [
"file uploader",
@ -32,9 +33,10 @@
"@uppy/utils": "workspace:^"
},
"devDependencies": {
"jsdom": "^26.1.0",
"nock": "^13.1.0",
"typescript": "^5.8.3",
"vitest": "^1.6.1"
"vitest": "^3.2.4"
},
"peerDependencies": {
"@uppy/core": "workspace:^"

View file

@ -1,4 +0,0 @@
import { webcrypto } from 'node:crypto'
import { vi } from 'vitest' // eslint-disable-line import/no-extraneous-dependencies
vi.stubGlobal('crypto', webcrypto)

View file

@ -1,5 +1,6 @@
{
"$schema": "https://turborepo.com/schema.json",
"concurrency": "20",
"tasks": {
"build": {
"outputLogs": "new-only",
@ -12,16 +13,6 @@
],
"outputs": ["lib/**", "dist/**"]
},
"build:css": {
"outputLogs": "new-only",
"inputs": ["src/**/*.scss"],
"outputs": ["lib/**/*.css", "dist/**/*.css"]
},
"typecheck": {
"outputLogs": "new-only",
"dependsOn": ["build"],
"inputs": ["src/**/*.{js,ts,jsx,tsx}", "tsconfig.json"]
},
"uppy#build": {
"outputLogs": "new-only",
"dependsOn": ["^build"],
@ -33,9 +24,29 @@
],
"outputs": ["lib/**", "dist/**"]
},
"watch": {
"build:watch": {
"outputLogs": "new-only",
"persistent": true,
"cache": false
},
"build:css": {
"outputLogs": "new-only",
"inputs": ["src/**/*.scss"],
"outputs": ["lib/**/*.css", "dist/**/*.css"]
},
"typecheck": {
"outputLogs": "new-only",
"dependsOn": ["build"],
"inputs": ["src/**/*.{js,ts,jsx,tsx}", "tsconfig.json"]
},
"test": {
"outputLogs": "errors-only",
"dependsOn": ["^test"]
},
"test:watch": {
"outputLogs": "new-only",
"persistent": true,
"cache": false
}
}
}
}

View file

@ -1,12 +0,0 @@
import { configDefaults, defineConfig } from 'vitest/config'
export default defineConfig({
test: {
exclude: [
...configDefaults.exclude,
'**/angular/**',
'packages/@uppy/companion/*',
],
setupFiles: ['./private/test/globalSetup.mjs'],
},
})

907
yarn.lock

File diff suppressed because it is too large Load diff