Add vitest and configuration

GitOrigin-RevId: 1262f9f32a0db6a29d3feedd8158b8dd04e48b6a
This commit is contained in:
Andrew Rumble
2025-05-29 08:04:55 +00:00
committed by Copybot
parent ce67a27c97
commit 0d3025b8cf
10 changed files with 888 additions and 25 deletions
+24
View File
@@ -64,6 +64,10 @@ module.exports = {
{
// Test specific rules
files: ['**/test/**/*.*'],
excludedFiles: [
'**/test/unit/src/**/*.test.mjs',
'test/unit/vitest_bootstrap.mjs',
], // exclude vitest files
plugins: ['mocha', 'chai-expect', 'chai-friendly'],
env: {
mocha: true,
@@ -95,6 +99,26 @@ module.exports = {
'@typescript-eslint/no-unused-expressions': 'off',
},
},
{
files: [
'**/test/unit/src/**/*.test.mjs',
'test/unit/vitest_bootstrap.mjs',
],
env: {
jest: true, // best match for vitest API etc.
},
plugins: ['@vitest', 'chai-expect', 'chai-friendly'], // still using chai for now
rules: {
// Swap the no-unused-expressions rule with a more chai-friendly one
'no-unused-expressions': 'off',
'chai-friendly/no-unused-expressions': 'error',
// chai-specific rules
'chai-expect/missing-assertion': 'error',
'chai-expect/terminating-properties': 'error',
'@typescript-eslint/no-unused-expressions': 'off',
},
},
{
// ES specific rules
files: [
+10
View File
@@ -83,6 +83,16 @@ test_unit_app:
$(DOCKER_COMPOSE) run --name unit_test_$(BUILD_DIR_NAME) --rm test_unit
$(DOCKER_COMPOSE) down -v -t 0
test_unit_esm: export COMPOSE_PROJECT_NAME=unit_test_esm_$(BUILD_DIR_NAME)
test_unit_esm:
$(DOCKER_COMPOSE) run --rm test_unit npm run test:unit:esm
$(DOCKER_COMPOSE) down -v -t 0
test_unit_esm_watch: export COMPOSE_PROJECT_NAME=unit_test_esm_watch_$(BUILD_DIR_NAME)
test_unit_esm_watch:
$(DOCKER_COMPOSE) run --rm test_unit npm run test:unit:esm:watch
$(DOCKER_COMPOSE) down -v -t 0
TEST_SUITES = $(sort $(filter-out \
$(wildcard test/unit/src/helpers/*), \
$(wildcard test/unit/src/*/*)))
+45
View File
@@ -0,0 +1,45 @@
#!/bin/bash
TARGET_DIR=$1
declare -a vitest_args=("$TARGET_DIR")
if [[ -n "$MOCHA_GREP" ]]; then
vitest_args+=("--testNamePattern" "$MOCHA_GREP")
fi
if [[ -n "$VITEST_NO_CACHE" ]]; then
echo "Disabling cache for vitest."
vitest_args+=("--no-cache")
fi
echo "Running unit tests in directory: $TARGET_DIR"
npm run test:unit:esm -- "${vitest_args[@]}"
vitest_status=$?
if find "$TARGET_DIR" -type f -name "*.js" -print -quit | grep -q '.'; then
mocha --recursive --timeout 25000 --exit --grep="$MOCHA_GREP" --require test/unit/bootstrap.js --extension=js "$TARGET_DIR"
mocha_status=$?
else
echo "No mocha tests found in $TARGET_DIR, skipping mocha step."
mocha_status=0
fi
if [ $mocha_status -eq 0 ] && [ $vitest_status -eq 0 ]; then
exit 0
fi
# Report status briefly at the end for failures
if [ $mocha_status -ne 0 ]; then
echo "Mocha tests failed with status: $mocha_status"
fi
if [ $vitest_status -ne 0 ]; then
echo "Vitest tests failed with status: $vitest_status"
fi
exit 1
+1
View File
@@ -21,6 +21,7 @@ services:
OVERLEAF_CONFIG:
NODE_ENV: test
NODE_OPTIONS: "--unhandled-rejections=strict"
VITEST_NO_CACHE: true
depends_on:
- mongo
+5 -1
View File
@@ -9,10 +9,12 @@
"scripts": {
"test:acceptance:run_dir": "mocha --recursive --timeout 25000 --grep=$MOCHA_GREP --require test/acceptance/bootstrap.js",
"test:acceptance:app": "npm run test:acceptance:run_dir -- test/acceptance/src",
"test:unit:run_dir": "mocha --recursive --timeout 25000 --exit --grep=$MOCHA_GREP --require test/unit/bootstrap.js",
"test:unit:run_dir": "bin/test_unit_run_dir",
"test:unit:all": "npm run test:unit:run_dir -- test/unit/src modules/*/test/unit/src",
"test:unit:all:silent": "npm run test:unit:all -- --reporter dot",
"test:unit:app": "npm run test:unit:run_dir -- test/unit/src",
"test:unit:esm": "vitest run",
"test:unit:esm:watch": "vitest",
"test:frontend": "NODE_ENV=test TZ=GMT mocha --recursive --timeout 5000 --exit --extension js,jsx,mjs,ts,tsx --grep=$MOCHA_GREP --require test/frontend/bootstrap.js --ignore '**/*.spec.{js,jsx,ts,tsx}' --ignore '**/helpers/**/*.{js,jsx,ts,tsx}' test/frontend modules/*/test/frontend",
"test:frontend:coverage": "c8 --all --include 'frontend/js' --include 'modules/*/frontend/js' --exclude 'frontend/js/vendor' --reporter=lcov --reporter=text-summary npm run test:frontend",
"start": "node app.mjs",
@@ -250,6 +252,7 @@
"@uppy/react": "^3.2.1",
"@uppy/utils": "^5.7.0",
"@uppy/xhr-upload": "^3.6.0",
"@vitest/eslint-plugin": "1.1.44",
"5to6-codemod": "^1.8.0",
"abort-controller": "^3.0.0",
"acorn": "^7.1.1",
@@ -356,6 +359,7 @@
"tty-browserify": "^0.0.1",
"typescript": "^5.0.4",
"uuid": "^9.0.1",
"vitest": "^3.1.2",
"w3c-keyname": "^2.2.8",
"webpack": "^5.98.0",
"webpack-assets-manifest": "^5.2.1",
+1 -24
View File
@@ -1,29 +1,6 @@
const Path = require('path')
const chai = require('chai')
const sinon = require('sinon')
/*
* Chai configuration
*/
// add chai.should()
chai.should()
// Load sinon-chai assertions so expect(stubFn).to.have.been.calledWith('abc')
// has a nicer failure messages
chai.use(require('sinon-chai'))
// Load promise support for chai
chai.use(require('chai-as-promised'))
// Do not truncate assertion errors
chai.config.truncateThreshold = 0
// add support for mongoose in sinon
require('sinon-mongoose')
// ensure every ObjectId has the id string as a property for correct comparisons
require('mongodb-legacy').ObjectId.cacheHexString = true
require('./common_bootstrap')
/*
* Global stubs
@@ -0,0 +1,24 @@
const chai = require('chai')
/*
* Chai configuration
*/
// add chai.should()
chai.should()
// Load sinon-chai assertions so expect(stubFn).to.have.been.calledWith('abc')
// has a nicer failure messages
chai.use(require('sinon-chai'))
// Load promise support for chai
chai.use(require('chai-as-promised'))
// Do not truncate assertion errors
chai.config.truncateThreshold = 0
// add support for mongoose in sinon
require('sinon-mongoose')
// ensure every ObjectId has the id string as a property for correct comparisons
require('mongodb-legacy').ObjectId.cacheHexString = true
@@ -0,0 +1,29 @@
import { vi } from 'vitest'
import './common_bootstrap.js'
import sinon from 'sinon'
import logger from '@overleaf/logger'
vi.mock('@overleaf/logger', async () => {
const sinon = (await import('sinon')).default
return {
default: {
debug: sinon.stub(),
info: sinon.stub(),
log: sinon.stub(),
warn: sinon.stub(),
err: sinon.stub(),
error: sinon.stub(),
fatal: sinon.stub(),
},
}
})
beforeEach(ctx => {
ctx.logger = logger
})
afterEach(() => {
vi.restoreAllMocks()
vi.resetModules()
sinon.restore()
})
+12
View File
@@ -0,0 +1,12 @@
const { defineConfig } = require('vitest/config')
module.exports = defineConfig({
test: {
include: [
'modules/*/test/unit/**/*.test.mjs',
'test/unit/src/**/*.test.mjs',
],
setupFiles: ['./test/unit/vitest_bootstrap.mjs'],
globals: true,
},
})