chore: Migrate workspaces that use `jest` to `vitest` (#998)

* docs(contributing): add section on testing

Fixes #994

* test(clerk-auth): replace jest with vitest

* test(graphql-server): replace jest with vitest

* test(medley-router): replace jest with vitest

* test(oauth-providers): replace jest with vitest

* test(oidc-auth): replace jest with vitest

* test(sentry): replace jest with vitest

* test(trpc-server): replace jest with vitest

* test(typebox-validator): replace jest with vitest

* test(typia-validator): replace jest with vitest

* test(valibot-validator): replace jest with vitest

* chore: cleanup remaining references to jest

* chore: fix lint errors

* test(typia-validator): fix exclude directory

* test(oauth-providers): use vitest environment miniflare

* chore: update `yarn.lock`

* chore(zod-openapi): pin zod-validator to 0.4.2

* test(graphql-server): remove console filtering

---------

Co-authored-by: Yusuke Wada <yusuke@kamawada.com>
pull/1001/head
Jonathan Haines 2025-03-05 00:00:28 +11:00 committed by GitHub
parent 0f8d2f3d05
commit 5ea7fb5d09
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
64 changed files with 523 additions and 7837 deletions

View File

@ -36,6 +36,15 @@ The specific flow is as follows
2. Write your middleware. Refer to [hello Middleware](https://github.com/honojs/middleware/tree/main/packages/hello). 2. Write your middleware. Refer to [hello Middleware](https://github.com/honojs/middleware/tree/main/packages/hello).
3. Create the pull request. 3. Create the pull request.
We use [Vitest](https://vitest.dev/) to write and run tests.
Test files should be added to the middleware `src` directory,
and include `.test.` in their file name, for example; `index.test.ts`.
Run the following command in the middleware directory to run tests.
```plain
yarn test
```
We use [changesets](https://github.com/changesets/changesets) to manage releases and CHANGELOG. We use [changesets](https://github.com/changesets/changesets) to manage releases and CHANGELOG.
Run the following command at the top level to describe any changes. Run the following command at the top level to describe any changes.

View File

@ -3,6 +3,6 @@ import baseConfig from './packages/eslint-config/index.js'
export default [ export default [
...baseConfig, ...baseConfig,
{ {
ignores: ['**/dist/*'], ignores: ['**/dist/*', '**/test-generated/*'],
}, },
] ]

View File

@ -1,7 +0,0 @@
module.exports = {
testMatch: ['**/test/**/*.+(ts|tsx|js)', '**/src/**/(*.)+(spec|test).+(ts|tsx|js)'],
transform: {
'^.+\\.(ts|tsx)$': 'ts-jest',
},
testEnvironment: 'miniflare',
}

View File

@ -58,16 +58,12 @@
"@changesets/changelog-github": "^0.4.8", "@changesets/changelog-github": "^0.4.8",
"@changesets/cli": "^2.26.0", "@changesets/cli": "^2.26.0",
"@cloudflare/workers-types": "^4.20230307.0", "@cloudflare/workers-types": "^4.20230307.0",
"@types/jest": "^29.5.11",
"@types/node": "^20.10.4", "@types/node": "^20.10.4",
"@typescript-eslint/eslint-plugin": "^8.7.0", "@typescript-eslint/eslint-plugin": "^8.7.0",
"@typescript-eslint/parser": "^8.7.0", "@typescript-eslint/parser": "^8.7.0",
"eslint": "^9.17.0", "eslint": "^9.17.0",
"jest": "^29.5.0",
"jest-environment-miniflare": "^2.14.1",
"npm-run-all2": "^6.2.2", "npm-run-all2": "^6.2.2",
"prettier": "^2.7.1", "prettier": "^2.7.1",
"ts-jest": "^29.1.1",
"typescript": "^5.2.2" "typescript": "^5.2.2"
}, },
"packageManager": "yarn@4.0.2" "packageManager": "yarn@4.0.2"

View File

@ -193,7 +193,7 @@ describe('With Hook', () => {
{ {
keyword: 'required', keyword: 'required',
instancePath: '', instancePath: '',
message: "must have required property 'title'", message: 'must have required property \'title\'',
}, },
]) ])
}) })

View File

@ -60,7 +60,6 @@
"@auth/core": "^0.35.3", "@auth/core": "^0.35.3",
"@types/react": "^18", "@types/react": "^18",
"hono": "^3.11.7", "hono": "^3.11.7",
"jest": "^29.7.0",
"react": "^18.2.0", "react": "^18.2.0",
"tsup": "^8.0.1", "tsup": "^8.0.1",
"typescript": "^5.3.3", "typescript": "^5.3.3",

View File

@ -7,10 +7,7 @@
"rootDir": "./", "rootDir": "./",
"outDir": "./dist", "outDir": "./dist",
"jsx": "react", "jsx": "react",
"types": ["jest","node","vitest/globals"] "types": ["node", "vitest/globals"]
}, },
"include": [ "include": ["src/**/*.ts", "src/**/*.tsx"]
"src/**/*.ts","src/**/*.tsx" }
],
}

View File

@ -1,8 +0,0 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
displayName: 'hono',
injectGlobals: true,
testMatch: ['**/test/**/*.+(ts|tsx|js)', '**/src/**/(*.)+(spec|test).+(ts|tsx|js)'],
transform: { '^.+\\.m?tsx?$': 'ts-jest' },
testPathIgnorePatterns: ['/node_modules/', '/jest/'],
}

View File

@ -10,7 +10,7 @@
"dist" "dist"
], ],
"scripts": { "scripts": {
"test": "jest", "test": "vitest",
"build": "tsup ./src/index.ts --format esm,cjs --dts", "build": "tsup ./src/index.ts --format esm,cjs --dts",
"prerelease": "yarn build && yarn test", "prerelease": "yarn build && yarn test",
"release": "yarn publish" "release": "yarn publish"
@ -45,10 +45,10 @@
"@clerk/backend": "^1.0.0", "@clerk/backend": "^1.0.0",
"@types/react": "^18", "@types/react": "^18",
"hono": "^3.11.7", "hono": "^3.11.7",
"jest": "^29.7.0",
"node-fetch-native": "^1.4.0", "node-fetch-native": "^1.4.0",
"react": "^18.2.0", "react": "^18.2.0",
"tsup": "^8.0.1" "tsup": "^8.0.1",
"vitest": "^2.1.8"
}, },
"engines": { "engines": {
"node": ">=16.x.x" "node": ">=16.x.x"

View File

@ -1,36 +1,31 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { Hono } from 'hono' import { Hono } from 'hono'
import { clerkMiddleware, getAuth } from '../src' import { clerkMiddleware, getAuth } from '.'
const EnvVariables = { const EnvVariables = {
CLERK_SECRET_KEY: 'TEST_API_KEY', CLERK_SECRET_KEY: 'TEST_API_KEY',
CLERK_PUBLISHABLE_KEY: 'TEST_API_KEY', CLERK_PUBLISHABLE_KEY: 'TEST_API_KEY',
} }
const authenticateRequestMock = jest.fn() const authenticateRequestMock = vi.fn()
vi.mock(import('@clerk/backend'), async (importOriginal) => {
const original = await importOriginal()
jest.mock('@clerk/backend', () => {
return { return {
...jest.requireActual('@clerk/backend'), ...original,
createClerkClient: () => { createClerkClient(options) {
return { const client = original.createClerkClient(options)
authenticateRequest: (...args: any) => authenticateRequestMock(...args), vi.spyOn(client, 'authenticateRequest').mockImplementation(authenticateRequestMock)
} return client
}, },
} }
}) })
// Test are based on Clerk's test suite for Fastify plugin - https://github.com/clerkinc/javascript/blob/main/packages/fastify/src/withClerkMiddleware.test.ts // Test are based on Clerk's test suite for Fastify plugin - https://github.com/clerk/javascript/blob/main/packages/fastify/src/__tests__/withClerkMiddleware.test.ts
describe('clerkMiddleware()', () => { describe('clerkMiddleware()', () => {
beforeEach(() => { beforeEach(() => {
process.env.CLERK_SECRET_KEY = EnvVariables.CLERK_SECRET_KEY vi.stubEnv('CLERK_SECRET_KEY', EnvVariables.CLERK_SECRET_KEY)
process.env.CLERK_PUBLISHABLE_KEY = EnvVariables.CLERK_PUBLISHABLE_KEY vi.stubEnv('CLERK_PUBLISHABLE_KEY', EnvVariables.CLERK_PUBLISHABLE_KEY)
jest.clearAllMocks()
jest.restoreAllMocks()
})
afterEach(() => {
jest.clearAllMocks()
}) })
test('handles signin with Authorization Bearer', async () => { test('handles signin with Authorization Bearer', async () => {

View File

@ -3,8 +3,7 @@
"compilerOptions": { "compilerOptions": {
"rootDir": "./src", "rootDir": "./src",
"outDir": "./dist", "outDir": "./dist",
"types": ["vitest/globals"]
}, },
"include": [ "include": ["src/**/*.ts"]
"src/**/*.ts" }
],
}

View File

@ -0,0 +1,9 @@
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
globals: true,
restoreMocks: true,
unstubEnvs: true,
},
})

View File

@ -279,7 +279,7 @@ describe('Cloudflare Access middleware', async () => {
expect(res).not.toBeNull() expect(res).not.toBeNull()
expect(res.status).toBe(500) expect(res.status).toBe(500)
expect(await res.json()).toEqual({ expect(await res.json()).toEqual({
err: "Error: Authentication error: The Access Organization 'my-cool-team-name' does not exist", err: 'Error: Authentication error: The Access Organization \'my-cool-team-name\' does not exist',
}) })
}) })

View File

@ -1 +0,0 @@
module.exports = require('../../jest.config.js')

View File

@ -14,7 +14,7 @@
"registry": "https://registry.npmjs.org/" "registry": "https://registry.npmjs.org/"
}, },
"scripts": { "scripts": {
"test": "jest", "test": "vitest",
"test:all": "yarn test", "test:all": "yarn test",
"build": "rimraf dist && tsc", "build": "rimraf dist && tsc",
"lint": "eslint --ext js,ts src .eslintrc.js", "lint": "eslint --ext js,ts src .eslintrc.js",
@ -31,7 +31,6 @@
"devDependencies": { "devDependencies": {
"@cloudflare/workers-types": "^3.14.0", "@cloudflare/workers-types": "^3.14.0",
"@eslint-community/eslint-plugin-eslint-comments": "^4.4.0", "@eslint-community/eslint-plugin-eslint-comments": "^4.4.0",
"@types/jest": "^28.1.4",
"@typescript-eslint/eslint-plugin": "^5.21.0", "@typescript-eslint/eslint-plugin": "^5.21.0",
"@typescript-eslint/parser": "^5.21.0", "@typescript-eslint/parser": "^5.21.0",
"eslint": "^8.57.0", "eslint": "^8.57.0",
@ -42,13 +41,11 @@
"eslint-plugin-import-x": "^4.1.1", "eslint-plugin-import-x": "^4.1.1",
"eslint-plugin-n": "^17.10.2", "eslint-plugin-n": "^17.10.2",
"hono": "^4.0.2", "hono": "^4.0.2",
"jest": "^28.1.2",
"jest-environment-miniflare": "^2.6.0",
"np": "^7.6.2", "np": "^7.6.2",
"prettier": "^2.7.1", "prettier": "^2.7.1",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"ts-jest": "^28.0.5", "typescript": "^4.7.4",
"typescript": "^4.7.4" "vitest": "^2.1.8"
}, },
"engines": { "engines": {
"node": ">=16.0.0" "node": ">=16.0.0"

View File

@ -7,23 +7,22 @@ import {
} from 'graphql' } from 'graphql'
import { Hono } from 'hono' import { Hono } from 'hono'
import type { Context, Next } from 'hono' import type { Context, Next } from 'hono'
import { errorMessages, graphqlServer } from '../src' import { errorMessages, graphqlServer } from '.'
import type { RootResolver } from '../src' import type { RootResolver } from '.'
// Do not show `console.error` messages
jest.spyOn(console, 'error').mockImplementation()
describe('errorMessages', () => { describe('errorMessages', () => {
const messages = errorMessages(['message a', 'message b']) it('Should handle messages', () => {
expect(messages).toEqual({ const messages = errorMessages(['message a', 'message b'])
errors: [ expect(messages).toEqual({
{ errors: [
message: 'message a', {
}, message: 'message a',
{ },
message: 'message b', {
}, message: 'message b',
], },
],
})
}) })
}) })

View File

@ -1,4 +1,4 @@
import { parseBody } from '../src/parse-body' import { parseBody } from './parse-body'
describe('parseBody', () => { describe('parseBody', () => {
it('Should return a blank JSON object', async () => { it('Should return a blank JSON object', async () => {

View File

@ -3,8 +3,7 @@
"compilerOptions": { "compilerOptions": {
"rootDir": "./src", "rootDir": "./src",
"outDir": "./dist", "outDir": "./dist",
"types": ["vitest/globals"]
}, },
"include": [ "include": ["src/**/*.ts"]
"src/**/*.ts" }
],
}

View File

@ -0,0 +1,10 @@
import { defaultExclude, defineConfig } from 'vitest/config'
export default defineConfig({
test: {
exclude: [...defaultExclude, 'bun_test'],
globals: true,
restoreMocks: true,
unstubEnvs: true,
},
})

View File

@ -1 +0,0 @@
module.exports = require('../../jest.config.js')

View File

@ -8,7 +8,7 @@
"dist" "dist"
], ],
"scripts": { "scripts": {
"test": "jest", "test": "vitest",
"build": "rimraf dist && tsc", "build": "rimraf dist && tsc",
"prerelease": "yarn build && yarn test", "prerelease": "yarn build && yarn test",
"release": "yarn publish" "release": "yarn publish"
@ -28,8 +28,8 @@
}, },
"devDependencies": { "devDependencies": {
"hono": "^3.11.7", "hono": "^3.11.7",
"jest": "^29.7.0", "rimraf": "^5.0.5",
"rimraf": "^5.0.5" "vitest": "^2.1.8"
}, },
"dependencies": { "dependencies": {
"@medley/router": "^0.2.1" "@medley/router": "^0.2.1"

View File

@ -3,8 +3,7 @@
"compilerOptions": { "compilerOptions": {
"rootDir": "./src", "rootDir": "./src",
"outDir": "./dist", "outDir": "./dist",
"types": ["vitest/globals"]
}, },
"include": [ "include": ["src/**/*.ts"]
"src/**/*.ts" }
],
}

View File

@ -0,0 +1,7 @@
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
globals: true,
},
})

View File

@ -1,7 +0,0 @@
module.exports = {
...require('../../jest.config.js'),
testEnvironmentOptions: {
customExportConditions: [''],
},
modulePathIgnorePatterns: ['handlers'],
}

View File

@ -7,7 +7,7 @@
"./dist" "./dist"
], ],
"scripts": { "scripts": {
"test": "jest", "test": "vitest",
"build": "tsup && publint", "build": "tsup && publint",
"watch": "tsup --watch", "watch": "tsup --watch",
"publint": "publint", "publint": "publint",
@ -112,16 +112,14 @@
}, },
"devDependencies": { "devDependencies": {
"@cloudflare/workers-types": "^4.20231025.0", "@cloudflare/workers-types": "^4.20231025.0",
"@types/jest": "^29.5.7",
"hono": "^4.5.1", "hono": "^4.5.1",
"jest": "^29.7.0",
"jest-environment-miniflare": "^2.14.1",
"msw": "^2.0.11", "msw": "^2.0.11",
"patch-package": "^8.0.0", "patch-package": "^8.0.0",
"publint": "^0.2.6", "publint": "^0.2.6",
"ts-jest": "^29.1.1",
"tsup": "^8.0.0", "tsup": "^8.0.0",
"typescript": "^5.2.2" "typescript": "^5.2.2",
"vitest": "^2.1.8",
"vitest-environment-miniflare": "^2.14.4"
}, },
"engines": { "engines": {
"node": ">=18.4.0" "node": ">=18.4.0"

View File

@ -3,8 +3,7 @@
"compilerOptions": { "compilerOptions": {
"rootDir": "./src", "rootDir": "./src",
"outDir": "./dist", "outDir": "./dist",
"types": ["vitest/globals"]
}, },
"include": [ "include": ["src/**/*.ts"]
"src/**/*.ts" }
],
}

View File

@ -0,0 +1,8 @@
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
environment: 'miniflare',
globals: true,
},
})

View File

@ -1,6 +0,0 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
export default {
preset: 'ts-jest/presets/default-esm',
testEnvironment: 'node',
collectCoverage: true,
}

View File

@ -9,7 +9,7 @@
"dist" "dist"
], ],
"scripts": { "scripts": {
"test": "NODE_OPTIONS=--experimental-vm-modules jest --verbose --coverage", "test": "vitest --coverage",
"build": "tsup ./src/index.ts --format esm --dts", "build": "tsup ./src/index.ts --format esm --dts",
"prerelease": "yarn build && yarn test", "prerelease": "yarn build && yarn test",
"release": "yarn prerelease && yarn npm publish" "release": "yarn prerelease && yarn npm publish"
@ -36,15 +36,13 @@
"hono": ">=3.*" "hono": ">=3.*"
}, },
"devDependencies": { "devDependencies": {
"@jest/globals": "^29.7.0",
"@types/jest": "^29.5.11",
"@types/jsonwebtoken": "^9.0.5", "@types/jsonwebtoken": "^9.0.5",
"@vitest/coverage-v8": "^2.1.8",
"hono": "^4.0.1", "hono": "^4.0.1",
"jest": "^29.7.0",
"jsonwebtoken": "^9.0.2", "jsonwebtoken": "^9.0.2",
"ts-jest": "^29.1.1",
"tsup": "^8.0.1", "tsup": "^8.0.1",
"typescript": "^5.3.3" "typescript": "^5.3.3",
"vitest": "^2.1.8"
}, },
"dependencies": { "dependencies": {
"oauth4webapi": "^2.6.0" "oauth4webapi": "^2.6.0"

View File

@ -1,7 +1,5 @@
import { jest } from '@jest/globals'
import { Hono } from 'hono' import { Hono } from 'hono'
import jwt from 'jsonwebtoken' import jwt from 'jsonwebtoken'
import * as oauth2 from 'oauth4webapi'
import crypto from 'node:crypto' import crypto from 'node:crypto'
const MOCK_ISSUER = 'https://accounts.google.com' const MOCK_ISSUER = 'https://accounts.google.com'
@ -110,10 +108,12 @@ const MOCK_JWT_INVALID_ALGORITHM = jwt.sign(
null, null,
{ algorithm: 'none', expiresIn: '1h' } { algorithm: 'none', expiresIn: '1h' }
) )
jest.unstable_mockModule('oauth4webapi', () => { vi.mock(import('oauth4webapi'), async (importOriginal) => {
const original = await importOriginal()
return { return {
...oauth2, ...original,
discoveryRequest: jest.fn(async () => { discoveryRequest: vi.fn(async () => {
return new Response( return new Response(
JSON.stringify({ JSON.stringify({
issuer: MOCK_ISSUER, issuer: MOCK_ISSUER,
@ -124,9 +124,9 @@ jest.unstable_mockModule('oauth4webapi', () => {
}) })
) )
}), }),
generateRandomState: jest.fn(() => MOCK_STATE), generateRandomState: vi.fn(() => MOCK_STATE),
generateRandomNonce: jest.fn(() => MOCK_NONCE), generateRandomNonce: vi.fn(() => MOCK_NONCE),
authorizationCodeGrantRequest: jest.fn(async () => { authorizationCodeGrantRequest: vi.fn(async () => {
return new Response( return new Response(
JSON.stringify({ JSON.stringify({
access_token: 'DUMMY_ACCESS_TOKEN', access_token: 'DUMMY_ACCESS_TOKEN',
@ -138,7 +138,7 @@ jest.unstable_mockModule('oauth4webapi', () => {
}) })
) )
}), }),
refreshTokenGrantRequest: jest.fn(async () => { refreshTokenGrantRequest: vi.fn(async () => {
return new Response( return new Response(
JSON.stringify({ JSON.stringify({
access_token: 'DUMMY_ACCESS_TOKEN', access_token: 'DUMMY_ACCESS_TOKEN',
@ -150,7 +150,7 @@ jest.unstable_mockModule('oauth4webapi', () => {
}) })
) )
}), }),
revocationRequest: jest.fn(async () => { revocationRequest: vi.fn(async () => {
return new Response(JSON.stringify({})) return new Response(JSON.stringify({}))
}), }),
} }

View File

@ -4,8 +4,7 @@
"module": "ESNext", "module": "ESNext",
"rootDir": "./src", "rootDir": "./src",
"outDir": "./dist", "outDir": "./dist",
"types": ["vitest/globals"]
}, },
"include": [ "include": ["src/**/*.ts"]
"src/**/*.ts" }
],
}

View File

@ -0,0 +1,9 @@
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
globals: true,
restoreMocks: true,
unstubEnvs: true,
},
})

View File

@ -1 +0,0 @@
module.exports = require('../../jest.config.js')

View File

@ -1 +0,0 @@
module.exports = require('../../jest.config.js')

View File

@ -10,7 +10,7 @@
"dist" "dist"
], ],
"scripts": { "scripts": {
"test": "jest", "test": "vitest",
"build": "tsup ./src/index.ts --format esm,cjs --dts", "build": "tsup ./src/index.ts --format esm,cjs --dts",
"prerelease": "yarn build && yarn test:all" "prerelease": "yarn build && yarn test:all"
}, },
@ -41,7 +41,6 @@
"devDependencies": { "devDependencies": {
"@cloudflare/workers-types": "^3.14.0", "@cloudflare/workers-types": "^3.14.0",
"@eslint-community/eslint-plugin-eslint-comments": "^4.4.0", "@eslint-community/eslint-plugin-eslint-comments": "^4.4.0",
"@types/jest": "^28.1.4",
"@typescript-eslint/eslint-plugin": "^5.32.0", "@typescript-eslint/eslint-plugin": "^5.32.0",
"@typescript-eslint/parser": "^5.32.0", "@typescript-eslint/parser": "^5.32.0",
"eslint": "^8.57.0", "eslint": "^8.57.0",
@ -52,12 +51,10 @@
"eslint-plugin-import-x": "^4.1.1", "eslint-plugin-import-x": "^4.1.1",
"eslint-plugin-n": "^17.10.2", "eslint-plugin-n": "^17.10.2",
"hono": "^3.11.7", "hono": "^3.11.7",
"jest": "^28.1.2",
"jest-environment-miniflare": "^2.6.0",
"prettier": "^2.7.1", "prettier": "^2.7.1",
"publint": "^0.2.7", "publint": "^0.2.7",
"ts-jest": "^28.0.5",
"tsup": "^8.0.2", "tsup": "^8.0.2",
"typescript": "^4.7.4" "typescript": "^4.7.4",
"vitest": "^2.1.8"
} }
} }

View File

@ -1,5 +1,6 @@
import { Hono } from 'hono' import { Hono } from 'hono'
import { getSentry, sentry } from '../src' import { Toucan } from 'toucan-js'
import { getSentry, sentry } from '.'
// Mock // Mock
class Context implements ExecutionContext { class Context implements ExecutionContext {
@ -12,14 +13,15 @@ class Context implements ExecutionContext {
} }
} }
const captureException = jest.fn() vi.mock(import('toucan-js'), async (importOriginal) => {
const log = jest.fn() const original = await importOriginal()
jest.mock('toucan-js', () => ({ Object.assign(original.Toucan.prototype, { captureException: vi.fn(), log: vi.fn() })
Toucan: jest.fn().mockImplementation(() => ({ captureException, log })),
}))
const callback = jest.fn() return original
})
const callback = vi.fn()
describe('Sentry middleware', () => { describe('Sentry middleware', () => {
const app = new Hono() const app = new Hono()
@ -46,7 +48,9 @@ describe('Sentry middleware', () => {
const res = await app.fetch(req, {}, new Context()) const res = await app.fetch(req, {}, new Context())
expect(res).not.toBeNull() expect(res).not.toBeNull()
expect(res.status).toBe(200) expect(res.status).toBe(200)
expect(log).toHaveBeenCalled() // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
expect(Toucan.prototype.log).toHaveBeenCalled()
}) })
it('Should report errors', async () => { it('Should report errors', async () => {
@ -54,6 +58,6 @@ describe('Sentry middleware', () => {
const res = await app.fetch(req, {}, new Context()) const res = await app.fetch(req, {}, new Context())
expect(res).not.toBeNull() expect(res).not.toBeNull()
expect(res.status).toBe(500) expect(res.status).toBe(500)
expect(captureException).toHaveBeenCalled() expect(Toucan.prototype.captureException).toHaveBeenCalled()
}) })
}) })

View File

@ -3,8 +3,7 @@
"compilerOptions": { "compilerOptions": {
"rootDir": "./src", "rootDir": "./src",
"outDir": "./dist", "outDir": "./dist",
"types": ["vitest/globals"]
}, },
"include": [ "include": ["src/**/*.ts"]
"src/**/*.ts" }
],
}

View File

@ -0,0 +1,9 @@
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
globals: true,
restoreMocks: true,
unstubEnvs: true,
},
})

View File

@ -1 +0,0 @@
module.exports = require('../../jest.config.js')

View File

@ -9,7 +9,7 @@
"dist" "dist"
], ],
"scripts": { "scripts": {
"test": "jest", "test": "vitest",
"build:cjs": "tsc -p tsconfig.cjs.json", "build:cjs": "tsc -p tsconfig.cjs.json",
"build:esm": "tsc -p tsconfig.esm.json", "build:esm": "tsc -p tsconfig.esm.json",
"build": "rimraf dist && yarn build:cjs && yarn build:esm", "build": "rimraf dist && yarn build:cjs && yarn build:esm",
@ -33,8 +33,8 @@
"devDependencies": { "devDependencies": {
"@trpc/server": "^10.10.0 || >11.0.0-rc", "@trpc/server": "^10.10.0 || >11.0.0-rc",
"hono": "^4.3.6", "hono": "^4.3.6",
"jest": "^29.7.0",
"rimraf": "^5.0.5", "rimraf": "^5.0.5",
"vitest": "^2.1.8",
"zod": "^3.20.2" "zod": "^3.20.2"
}, },
"engines": { "engines": {

View File

@ -48,7 +48,7 @@ describe('tRPC Adapter Middleware passing synchronous Context', () => {
}) })
) )
it.only('Should return 200 response', async () => { it('Should return 200 response', async () => {
const searchParams = new URLSearchParams({ const searchParams = new URLSearchParams({
input: JSON.stringify({ '0': 'Hono' }), input: JSON.stringify({ '0': 'Hono' }),
batch: '1', batch: '1',
@ -112,7 +112,7 @@ describe('tRPC Adapter Middleware passing asynchronous Context', () => {
}) })
) )
it.only('Should return 200 response', async () => { it('Should return 200 response', async () => {
const searchParams = new URLSearchParams({ const searchParams = new URLSearchParams({
input: JSON.stringify({ '0': 'Hono' }), input: JSON.stringify({ '0': 'Hono' }),
batch: '1', batch: '1',

View File

@ -2,8 +2,7 @@
"extends": "../../tsconfig.json", "extends": "../../tsconfig.json",
"compilerOptions": { "compilerOptions": {
"rootDir": "./src", "rootDir": "./src",
"types": ["vitest/globals"]
}, },
"include": [ "include": ["src/**/*.ts"]
"src/**/*.ts" }
],
}

View File

@ -0,0 +1,7 @@
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
globals: true,
},
})

View File

@ -1 +0,0 @@
module.exports = require('../../jest.config.js')

View File

@ -12,7 +12,7 @@
"dist" "dist"
], ],
"scripts": { "scripts": {
"test": "jest", "test": "vitest",
"build:cjs": "tsc -p tsconfig.cjs.json", "build:cjs": "tsc -p tsconfig.cjs.json",
"build:esm": "tsc -p tsconfig.esm.json && echo '{\"type\": \"module\"}' > dist/esm/package.json", "build:esm": "tsc -p tsconfig.esm.json && echo '{\"type\": \"module\"}' > dist/esm/package.json",
"build": "rimraf dist && yarn build:cjs && yarn build:esm", "build": "rimraf dist && yarn build:cjs && yarn build:esm",
@ -36,7 +36,7 @@
"devDependencies": { "devDependencies": {
"@sinclair/typebox": "^0.31.15", "@sinclair/typebox": "^0.31.15",
"hono": "^3.11.7", "hono": "^3.11.7",
"jest": "^29.7.0", "rimraf": "^5.0.5",
"rimraf": "^5.0.5" "vitest": "^2.1.8"
} }
} }

View File

@ -2,7 +2,7 @@ import { Type as T } from '@sinclair/typebox'
import type { ValueError } from '@sinclair/typebox/value' import type { ValueError } from '@sinclair/typebox/value'
import { Hono } from 'hono' import { Hono } from 'hono'
import type { Equal, Expect } from 'hono/utils/types' import type { Equal, Expect } from 'hono/utils/types'
import { tbValidator } from '../src' import { tbValidator } from '.'
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
type ExtractSchema<T> = T extends Hono<infer _, infer S> ? S : never type ExtractSchema<T> = T extends Hono<infer _, infer S> ? S : never

View File

@ -2,8 +2,7 @@
"extends": "../../tsconfig.json", "extends": "../../tsconfig.json",
"compilerOptions": { "compilerOptions": {
"rootDir": "./src", "rootDir": "./src",
"types": ["vitest/globals"]
}, },
"include": [ "include": ["src/**/*.ts"]
"src/**/*.ts" }
],
}

View File

@ -0,0 +1,7 @@
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
globals: true,
},
})

View File

@ -1,9 +0,0 @@
module.exports = {
testMatch: ['**/test-generated/**/*.+(ts|tsx|js)'],
testPathIgnorePatterns: ['/node_modules/', '/dist/', '/.history/'],
transform: {
'^.+\\.(ts|tsx)$': 'ts-jest',
},
testEnvironment: 'miniflare',
}

View File

@ -24,7 +24,7 @@
], ],
"scripts": { "scripts": {
"generate-test": "rimraf test-generated && typia generate --input test --output test-generated --project tsconfig.json && node scripts/add-ts-ignore.cjs", "generate-test": "rimraf test-generated && typia generate --input test --output test-generated --project tsconfig.json && node scripts/add-ts-ignore.cjs",
"test": "npm run generate-test && jest", "test": "npm run generate-test && vitest",
"build:cjs": "tsc -p tsconfig.cjs.json", "build:cjs": "tsc -p tsconfig.cjs.json",
"build:esm": "tsc -p tsconfig.esm.json", "build:esm": "tsc -p tsconfig.esm.json",
"build": "rimraf dist && yarn build:cjs && yarn build:esm", "build": "rimraf dist && yarn build:cjs && yarn build:esm",
@ -47,9 +47,9 @@
}, },
"devDependencies": { "devDependencies": {
"hono": "^3.11.7", "hono": "^3.11.7",
"jest": "^29.7.0",
"rimraf": "^5.0.5", "rimraf": "^5.0.5",
"typescript": "^5.4.0", "typescript": "^5.4.0",
"typia": "^7.3.0" "typia": "^7.3.0",
"vitest": "^2.1.8"
} }
} }

View File

@ -359,9 +359,9 @@ describe('With target', () => {
const validateQuery = typia.http.createValidateQuery<Schema>() const validateQuery = typia.http.createValidateQuery<Schema>()
const validateHeader = typia.http.createValidateHeaders<Schema>() const validateHeader = typia.http.createValidateHeaders<Schema>()
const jsonHook = jest.fn() const jsonHook = vi.fn()
const headerHook = jest.fn() const headerHook = vi.fn()
const queryHook = jest.fn() const queryHook = vi.fn()
app.post( app.post(
'/post', '/post',
typiaValidator('json', validateSchema, jsonHook), typiaValidator('json', validateSchema, jsonHook),

View File

@ -2,13 +2,12 @@
"extends": "../../tsconfig.json", "extends": "../../tsconfig.json",
"compilerOptions": { "compilerOptions": {
"rootDir": "./src", "rootDir": "./src",
"types": ["vitest/globals"]
}, },
"include": [ "include": ["src/**/*.ts"],
"src/**/*.ts"
],
"plugins": [ "plugins": [
{ {
"transform": "typia/lib/transform" "transform": "typia/lib/transform"
} }
], ]
} }

View File

@ -0,0 +1,8 @@
import { defineConfig, defaultExclude } from 'vitest/config'
export default defineConfig({
test: {
globals: true,
exclude: [...defaultExclude, 'test'],
},
})

View File

@ -1 +0,0 @@
module.exports = require('../../jest.config.js')

View File

@ -15,7 +15,7 @@
"dist" "dist"
], ],
"scripts": { "scripts": {
"test": "jest", "test": "vitest",
"build": "tsup", "build": "tsup",
"prerelease": "yarn build && yarn test", "prerelease": "yarn build && yarn test",
"release": "yarn publish" "release": "yarn publish"
@ -36,8 +36,8 @@
}, },
"devDependencies": { "devDependencies": {
"hono": "^4.5.1", "hono": "^4.5.1",
"jest": "^29.7.0",
"tsup": "^8.3.0", "tsup": "^8.3.0",
"valibot": "^1.0.0-beta.5" "valibot": "^1.0.0-beta.5",
"vitest": "^2.1.8"
} }
} }

View File

@ -2,7 +2,7 @@ import { Hono } from 'hono'
import type { StatusCode } from 'hono/utils/http-status' import type { StatusCode } from 'hono/utils/http-status'
import type { Equal, Expect } from 'hono/utils/types' import type { Equal, Expect } from 'hono/utils/types'
import { number, object, objectAsync, optional, optionalAsync, string } from 'valibot' import { number, object, objectAsync, optional, optionalAsync, string } from 'valibot'
import { vValidator } from '../src' import { vValidator } from '.'
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
type ExtractSchema<T> = T extends Hono<infer _, infer S> ? S : never type ExtractSchema<T> = T extends Hono<infer _, infer S> ? S : never

View File

@ -0,0 +1,7 @@
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
globals: true,
},
})

View File

@ -43,7 +43,6 @@
"devDependencies": { "devDependencies": {
"@cloudflare/workers-types": "^4.20240117.0", "@cloudflare/workers-types": "^4.20240117.0",
"hono": "^4.6.10", "hono": "^4.6.10",
"jest": "^29.7.0",
"tsup": "^8.0.1", "tsup": "^8.0.1",
"typescript": "^5.4.4", "typescript": "^5.4.4",
"vitest": "^1.4.0", "vitest": "^1.4.0",
@ -52,7 +51,7 @@
}, },
"dependencies": { "dependencies": {
"@asteasolutions/zod-to-openapi": "^7.1.0", "@asteasolutions/zod-to-openapi": "^7.1.0",
"@hono/zod-validator": "^0.4.1" "@hono/zod-validator": "npm:0.4.2"
}, },
"engines": { "engines": {
"node": ">=16.0.0" "node": ">=16.0.0"

File diff suppressed because it is too large Load Diff

View File

@ -44,4 +44,4 @@
"vitest": "^1.4.0", "vitest": "^1.4.0",
"zod": "^3.22.4" "zod": "^3.22.4"
} }
} }

View File

@ -10,10 +10,6 @@
"skipLibCheck": true, "skipLibCheck": true,
"noUnusedLocals": false, "noUnusedLocals": false,
"noUnusedParameters": true, "noUnusedParameters": true,
"types": [ "types": ["node", "@cloudflare/workers-types"]
"jest",
"node",
"@cloudflare/workers-types"
],
} }
} }

3054
yarn.lock

File diff suppressed because it is too large Load Diff