Skip to content

Commit f6452ae

Browse files
committed
test: add vitest configuration and test setup
1 parent 2e1c8c8 commit f6452ae

6 files changed

Lines changed: 83 additions & 7 deletions

File tree

package.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@
1616
"lint": "npx eslint \"src/**/*.{ts,js}\"",
1717
"build": "tsc --noEmit && cross-env NODE_ENV=production node scripts/build.js",
1818
"dev": "cross-env NODE_ENV=local concurrently \"tsc --noEmit --watch\" \"node scripts/dev.js\"",
19-
"test": "c8 --reporter=lcov --reporter=text tsx ./src/index.ts",
20-
"report": "c8 report --reporter=lcov --reporter=html",
21-
"coverage": "rimraf coverage && npm run test",
19+
"test": "vitest run",
20+
"coverage": "rimraf coverage && vitest run --coverage",
2221
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 -n changelog-option.js"
2322
},
2423
"dependencies": {
@@ -31,7 +30,6 @@
3130
"@typescript-eslint/eslint-plugin": "^8.39.1",
3231
"@typescript-eslint/parser": "^8.39.1",
3332
"@vitest/coverage-v8": "^3.2.4",
34-
"c8": "^10.1.3",
3533
"compare-func": "^2.0.0",
3634
"concurrently": "^9.2.0",
3735
"conventional-changelog-angular": "^8.0.0",

src/index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'
55
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'
66
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js'
77

8-
async function testStdioTransport() {
8+
export async function testStdioTransport() {
99
console.log('start stdio client transport')
1010
const client = new Client({
1111
name: 'mcp-stdio-client',
@@ -47,7 +47,7 @@ async function testStdioTransport() {
4747
await sleep(1000)
4848
}
4949

50-
async function testStreamableHttpTransport() {
50+
export async function testStreamableHttpTransport() {
5151
console.log('start streamable http client transport')
5252
const client = new Client({
5353
name: 'mcp-http-client',
@@ -84,7 +84,7 @@ async function testStreamableHttpTransport() {
8484
await sleep(1000)
8585
}
8686

87-
async function testSSETransport() {
87+
export async function testSSETransport() {
8888
console.log('start sse client transport')
8989
const client = new Client({
9090
name: 'mcp-sse-client',

tests/index.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { describe, test } from 'vitest'
2+
import { testStdioTransport, testStreamableHttpTransport, testSSETransport } from '@/index'
3+
4+
describe('MCP client', () => {
5+
test('stdio transport', async () => {
6+
await testStdioTransport()
7+
})
8+
9+
test('streamable http transport', async () => {
10+
await testStreamableHttpTransport()
11+
})
12+
13+
test('sse transport', async () => {
14+
await testSSETransport()
15+
})
16+
})

tests/utils.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
export function waitForValue<T>(
2+
getterFn: () => T | undefined | null,
3+
checkInterval = 100,
4+
timeout = 10000,
5+
): Promise<T> {
6+
return new Promise((resolve, reject) => {
7+
const start = Date.now()
8+
9+
const intervalId = setInterval(() => {
10+
const value = getterFn()
11+
if (value) {
12+
clearInterval(intervalId)
13+
resolve(value)
14+
} else if (Date.now() - start > timeout) {
15+
clearInterval(intervalId)
16+
reject(new Error('Timeout waiting for value'))
17+
}
18+
}, checkInterval)
19+
})
20+
}

vitest.config.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { defineConfig } from 'vitest/config'
2+
3+
export default defineConfig({
4+
resolve: {
5+
alias: {
6+
'@': '/src',
7+
},
8+
},
9+
test: {
10+
globalSetup: ['./vitest.global.ts'],
11+
coverage: {
12+
include: ['src/**/*.ts'],
13+
reporter: ['text', 'lcov', 'html'],
14+
},
15+
pool: 'threads',
16+
poolOptions: {
17+
threads: {
18+
maxThreads: 1,
19+
minThreads: 1,
20+
}
21+
},
22+
},
23+
})

vitest.global.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { spawn } from 'child_process'
2+
import { waitForValue } from './tests/utils'
3+
4+
export default async function setup() {
5+
const webProcess = spawn('npx', ['-y', '@my-mcp-hub/node-mcp-server', 'web'], {
6+
stdio: 'pipe',
7+
})
8+
let webStarted = false
9+
webProcess.stdout?.on('data', async (data) => {
10+
const output = data.toString()
11+
if (output.includes('MCP server started')) {
12+
webStarted = true
13+
}
14+
});
15+
await waitForValue(() => webStarted)
16+
return () => {
17+
webProcess.kill('SIGINT')
18+
}
19+
}

0 commit comments

Comments
 (0)