Migrate sequentialthinking and filesystem servers from Jest to Vitest
- Replace Jest dependencies with Vitest and @vitest/coverage-v8 - Update test scripts to use 'vitest run --coverage' - Create vitest.config.ts for both servers with node environment and coverage settings - Update all test files: - Change imports from '@jest/globals' to 'vitest' - Replace jest.mock() with vi.mock() - Replace jest.fn() with vi.fn() - Update mock clearing/restoring to use vi methods - Remove jest.config.cjs files - All 151 tests passing (24 in sequentialthinking, 127 in filesystem) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
a30481da15
commit
b666e7f246
15 changed files with 1590 additions and 3753 deletions
9
AGENTS.md
Normal file
9
AGENTS.md
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
# MCP Reference Server Development Guide
|
||||||
|
|
||||||
|
## Contributing Guidelines
|
||||||
|
|
||||||
|
Before making updates to this repo, thoroughly review the CONTRIBUTING.md guide at the root of this repo.
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
Use vitest when configuring or adding tests for servers implemented in typescript.
|
||||||
2
CLAUDE.md
Normal file
2
CLAUDE.md
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
@./AGENTS.md
|
||||||
|
|
||||||
4994
package-lock.json
generated
4994
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,4 +1,4 @@
|
||||||
import { describe, it, expect, beforeEach, afterEach } from '@jest/globals';
|
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
||||||
import * as fs from 'fs/promises';
|
import * as fs from 'fs/promises';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { describe, it, expect, beforeEach, afterEach, jest } from '@jest/globals';
|
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import os from 'os';
|
import os from 'os';
|
||||||
|
|
@ -23,19 +23,19 @@ import {
|
||||||
} from '../lib.js';
|
} from '../lib.js';
|
||||||
|
|
||||||
// Mock fs module
|
// Mock fs module
|
||||||
jest.mock('fs/promises');
|
vi.mock('fs/promises');
|
||||||
const mockFs = fs as jest.Mocked<typeof fs>;
|
const mockFs = fs as any;
|
||||||
|
|
||||||
describe('Lib Functions', () => {
|
describe('Lib Functions', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
// Set up allowed directories for tests
|
// Set up allowed directories for tests
|
||||||
const allowedDirs = process.platform === 'win32' ? ['C:\\Users\\test', 'C:\\temp', 'C:\\allowed'] : ['/home/user', '/tmp', '/allowed'];
|
const allowedDirs = process.platform === 'win32' ? ['C:\\Users\\test', 'C:\\temp', 'C:\\allowed'] : ['/home/user', '/tmp', '/allowed'];
|
||||||
setAllowedDirectories(allowedDirs);
|
setAllowedDirectories(allowedDirs);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.restoreAllMocks();
|
vi.restoreAllMocks();
|
||||||
// Clear allowed directories after tests
|
// Clear allowed directories after tests
|
||||||
setAllowedDirectories([]);
|
setAllowedDirectories([]);
|
||||||
});
|
});
|
||||||
|
|
@ -567,8 +567,8 @@ describe('Lib Functions', () => {
|
||||||
|
|
||||||
// Mock file handle with proper typing
|
// Mock file handle with proper typing
|
||||||
const mockFileHandle = {
|
const mockFileHandle = {
|
||||||
read: jest.fn(),
|
read: vi.fn(),
|
||||||
close: jest.fn()
|
close: vi.fn()
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
mockFileHandle.read.mockResolvedValue({ bytesRead: 0 });
|
mockFileHandle.read.mockResolvedValue({ bytesRead: 0 });
|
||||||
|
|
@ -586,8 +586,8 @@ describe('Lib Functions', () => {
|
||||||
mockFs.stat.mockResolvedValue({ size: 50 } as any);
|
mockFs.stat.mockResolvedValue({ size: 50 } as any);
|
||||||
|
|
||||||
const mockFileHandle = {
|
const mockFileHandle = {
|
||||||
read: jest.fn(),
|
read: vi.fn(),
|
||||||
close: jest.fn()
|
close: vi.fn()
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
// Simulate reading file content in chunks
|
// Simulate reading file content in chunks
|
||||||
|
|
@ -607,8 +607,8 @@ describe('Lib Functions', () => {
|
||||||
mockFs.stat.mockResolvedValue({ size: 100 } as any);
|
mockFs.stat.mockResolvedValue({ size: 100 } as any);
|
||||||
|
|
||||||
const mockFileHandle = {
|
const mockFileHandle = {
|
||||||
read: jest.fn(),
|
read: vi.fn(),
|
||||||
close: jest.fn()
|
close: vi.fn()
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
mockFileHandle.read.mockResolvedValue({ bytesRead: 0 });
|
mockFileHandle.read.mockResolvedValue({ bytesRead: 0 });
|
||||||
|
|
@ -626,8 +626,8 @@ describe('Lib Functions', () => {
|
||||||
it('opens file for reading', async () => {
|
it('opens file for reading', async () => {
|
||||||
// Mock file handle with proper typing
|
// Mock file handle with proper typing
|
||||||
const mockFileHandle = {
|
const mockFileHandle = {
|
||||||
read: jest.fn(),
|
read: vi.fn(),
|
||||||
close: jest.fn()
|
close: vi.fn()
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
mockFileHandle.read.mockResolvedValue({ bytesRead: 0 });
|
mockFileHandle.read.mockResolvedValue({ bytesRead: 0 });
|
||||||
|
|
@ -642,8 +642,8 @@ describe('Lib Functions', () => {
|
||||||
|
|
||||||
it('handles files with content and returns first lines', async () => {
|
it('handles files with content and returns first lines', async () => {
|
||||||
const mockFileHandle = {
|
const mockFileHandle = {
|
||||||
read: jest.fn(),
|
read: vi.fn(),
|
||||||
close: jest.fn()
|
close: vi.fn()
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
// Simulate reading file content with newlines
|
// Simulate reading file content with newlines
|
||||||
|
|
@ -661,8 +661,8 @@ describe('Lib Functions', () => {
|
||||||
|
|
||||||
it('handles files with leftover content', async () => {
|
it('handles files with leftover content', async () => {
|
||||||
const mockFileHandle = {
|
const mockFileHandle = {
|
||||||
read: jest.fn(),
|
read: vi.fn(),
|
||||||
close: jest.fn()
|
close: vi.fn()
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
// Simulate reading file content without final newline
|
// Simulate reading file content without final newline
|
||||||
|
|
@ -680,8 +680,8 @@ describe('Lib Functions', () => {
|
||||||
|
|
||||||
it('handles reaching requested line count', async () => {
|
it('handles reaching requested line count', async () => {
|
||||||
const mockFileHandle = {
|
const mockFileHandle = {
|
||||||
read: jest.fn(),
|
read: vi.fn(),
|
||||||
close: jest.fn()
|
close: vi.fn()
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
// Simulate reading exactly the requested number of lines
|
// Simulate reading exactly the requested number of lines
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { describe, it, expect } from '@jest/globals';
|
import { describe, it, expect } from 'vitest';
|
||||||
import { normalizePath, expandHome, convertToWindowsPath } from '../path-utils.js';
|
import { normalizePath, expandHome, convertToWindowsPath } from '../path-utils.js';
|
||||||
|
|
||||||
describe('Path Utilities', () => {
|
describe('Path Utilities', () => {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { describe, it, expect, beforeEach, afterEach } from '@jest/globals';
|
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as fs from 'fs/promises';
|
import * as fs from 'fs/promises';
|
||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { describe, it, expect, beforeEach, afterEach } from '@jest/globals';
|
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
||||||
import { getValidRootDirectories } from '../roots-utils.js';
|
import { getValidRootDirectories } from '../roots-utils.js';
|
||||||
import { mkdtempSync, rmSync, mkdirSync, writeFileSync, realpathSync } from 'fs';
|
import { mkdtempSync, rmSync, mkdirSync, writeFileSync, realpathSync } from 'fs';
|
||||||
import { tmpdir } from 'os';
|
import { tmpdir } from 'os';
|
||||||
|
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
/** @type {import('ts-jest').JestConfigWithTsJest} */
|
|
||||||
module.exports = {
|
|
||||||
preset: 'ts-jest',
|
|
||||||
testEnvironment: 'node',
|
|
||||||
extensionsToTreatAsEsm: ['.ts'],
|
|
||||||
moduleNameMapper: {
|
|
||||||
'^(\\.{1,2}/.*)\\.js$': '$1',
|
|
||||||
},
|
|
||||||
transform: {
|
|
||||||
'^.+\\.tsx?$': [
|
|
||||||
'ts-jest',
|
|
||||||
{
|
|
||||||
useESM: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
testMatch: ['**/__tests__/**/*.test.ts'],
|
|
||||||
collectCoverageFrom: [
|
|
||||||
'**/*.ts',
|
|
||||||
'!**/__tests__/**',
|
|
||||||
'!**/dist/**',
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
"build": "tsc && shx chmod +x dist/*.js",
|
"build": "tsc && shx chmod +x dist/*.js",
|
||||||
"prepare": "npm run build",
|
"prepare": "npm run build",
|
||||||
"watch": "tsc --watch",
|
"watch": "tsc --watch",
|
||||||
"test": "jest --config=jest.config.cjs --coverage"
|
"test": "vitest run --coverage"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@modelcontextprotocol/sdk": "^1.19.1",
|
"@modelcontextprotocol/sdk": "^1.19.1",
|
||||||
|
|
@ -27,15 +27,12 @@
|
||||||
"zod-to-json-schema": "^3.23.5"
|
"zod-to-json-schema": "^3.23.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@jest/globals": "^29.7.0",
|
|
||||||
"@types/diff": "^5.0.9",
|
"@types/diff": "^5.0.9",
|
||||||
"@types/jest": "^29.5.14",
|
|
||||||
"@types/minimatch": "^5.1.2",
|
"@types/minimatch": "^5.1.2",
|
||||||
"@types/node": "^22",
|
"@types/node": "^22",
|
||||||
"jest": "^29.7.0",
|
"@vitest/coverage-v8": "^2.1.8",
|
||||||
"shx": "^0.3.4",
|
"shx": "^0.3.4",
|
||||||
"ts-jest": "^29.1.1",
|
"typescript": "^5.8.2",
|
||||||
"ts-node": "^10.9.2",
|
"vitest": "^2.1.8"
|
||||||
"typescript": "^5.8.2"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
14
src/filesystem/vitest.config.ts
Normal file
14
src/filesystem/vitest.config.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
environment: 'node',
|
||||||
|
include: ['**/__tests__/**/*.test.ts'],
|
||||||
|
coverage: {
|
||||||
|
provider: 'v8',
|
||||||
|
include: ['**/*.ts'],
|
||||||
|
exclude: ['**/__tests__/**', '**/dist/**'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { describe, it, expect, beforeEach, jest } from '@jest/globals';
|
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
||||||
import { SequentialThinkingServer, ThoughtData } from '../lib.js';
|
import { SequentialThinkingServer, ThoughtData } from '../lib.js';
|
||||||
|
|
||||||
// Mock chalk to avoid ESM issues in Jest
|
// Mock chalk to avoid ESM issues
|
||||||
jest.mock('chalk', () => {
|
vi.mock('chalk', () => {
|
||||||
const chalkMock = {
|
const chalkMock = {
|
||||||
yellow: (str: string) => str,
|
yellow: (str: string) => str,
|
||||||
green: (str: string) => str,
|
green: (str: string) => str,
|
||||||
|
|
@ -10,7 +10,6 @@ jest.mock('chalk', () => {
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
default: chalkMock,
|
default: chalkMock,
|
||||||
__esModule: true,
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
/** @type {import('ts-jest').JestConfigWithTsJest} */
|
|
||||||
module.exports = {
|
|
||||||
preset: 'ts-jest',
|
|
||||||
testEnvironment: 'node',
|
|
||||||
extensionsToTreatAsEsm: ['.ts'],
|
|
||||||
moduleNameMapper: {
|
|
||||||
'^(\\.{1,2}/.*)\\.js$': '$1',
|
|
||||||
},
|
|
||||||
transform: {
|
|
||||||
'^.+\\.tsx?$': [
|
|
||||||
'ts-jest',
|
|
||||||
{
|
|
||||||
useESM: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
transformIgnorePatterns: [
|
|
||||||
'node_modules/(?!(chalk)/)',
|
|
||||||
],
|
|
||||||
testMatch: ['**/__tests__/**/*.test.ts'],
|
|
||||||
collectCoverageFrom: [
|
|
||||||
'**/*.ts',
|
|
||||||
'!**/__tests__/**',
|
|
||||||
'!**/dist/**',
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
"build": "tsc && shx chmod +x dist/*.js",
|
"build": "tsc && shx chmod +x dist/*.js",
|
||||||
"prepare": "npm run build",
|
"prepare": "npm run build",
|
||||||
"watch": "tsc --watch",
|
"watch": "tsc --watch",
|
||||||
"test": "jest --config=jest.config.cjs --coverage"
|
"test": "vitest run --coverage"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@modelcontextprotocol/sdk": "^1.19.1",
|
"@modelcontextprotocol/sdk": "^1.19.1",
|
||||||
|
|
@ -25,14 +25,11 @@
|
||||||
"yargs": "^17.7.2"
|
"yargs": "^17.7.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@jest/globals": "^29.7.0",
|
|
||||||
"@types/jest": "^29.5.14",
|
|
||||||
"@types/node": "^22",
|
"@types/node": "^22",
|
||||||
"@types/yargs": "^17.0.32",
|
"@types/yargs": "^17.0.32",
|
||||||
"jest": "^29.7.0",
|
"@vitest/coverage-v8": "^2.1.8",
|
||||||
"shx": "^0.3.4",
|
"shx": "^0.3.4",
|
||||||
"ts-jest": "^29.1.1",
|
"typescript": "^5.3.3",
|
||||||
"ts-node": "^10.9.2",
|
"vitest": "^2.1.8"
|
||||||
"typescript": "^5.3.3"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
14
src/sequentialthinking/vitest.config.ts
Normal file
14
src/sequentialthinking/vitest.config.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
environment: 'node',
|
||||||
|
include: ['**/__tests__/**/*.test.ts'],
|
||||||
|
coverage: {
|
||||||
|
provider: 'v8',
|
||||||
|
include: ['**/*.ts'],
|
||||||
|
exclude: ['**/__tests__/**', '**/dist/**'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
Loading…
Reference in a new issue