Skip to main content
Glama
lis186

Taiwan Holiday MCP Server

by lis186
package-installation.test.ts6.53 kB
/** * 套件安裝測試 */ import { promises as fs } from 'fs'; import { join } from 'path'; import { spawn } from 'child_process'; import { tmpdir } from 'os'; /** * 輔助函數:執行命令並回傳結果 */ async function execCommand(command: string, args: string[] = [], cwd?: string): Promise<{ stdout: string; stderr: string; code: number }> { return new Promise((resolve, reject) => { const child = spawn(command, args, { stdio: ['pipe', 'pipe', 'pipe'], cwd: cwd || process.cwd() }); let stdout = ''; let stderr = ''; child.stdout?.on('data', (data) => { stdout += data.toString(); }); child.stderr?.on('data', (data) => { stderr += data.toString(); }); child.on('close', (code) => { resolve({ stdout, stderr, code: code || 0 }); }); child.on('error', (error) => { reject(error); }); setTimeout(() => { child.kill(); reject(new Error('命令執行超時')); }, 30000); }); } describe('套件安裝測試', () => { test('應支援 npm pack 打包', async () => { // 執行 npm pack const result = await execCommand('npm', ['pack']); expect(result.code).toBe(0); expect(result.stdout).toContain('.tgz'); // 清理打包檔案 const files = await fs.readdir('.'); const tgzFiles = files.filter(f => f.endsWith('.tgz')); for (const file of tgzFiles) { await fs.unlink(file); } }, 30000); test('應支援本地安裝測試', async () => { const tempDir = await fs.mkdtemp(join(tmpdir(), 'taiwan-holiday-test-')); try { // 在臨時目錄中建立測試專案 await fs.writeFile(join(tempDir, 'package.json'), JSON.stringify({ name: 'test-project', version: '1.0.0', private: true }, null, 2)); // 建立 npm pack const packResult = await execCommand('npm', ['pack']); expect(packResult.code).toBe(0); const files = await fs.readdir('.'); const tgzFile = files.find(f => f.endsWith('.tgz')); expect(tgzFile).toBeDefined(); if (tgzFile) { // 複製打包檔案到臨時目錄 const tgzPath = join(process.cwd(), tgzFile); const tempTgzPath = join(tempDir, tgzFile); await fs.copyFile(tgzPath, tempTgzPath); // 在臨時目錄中安裝 const installResult = await execCommand('npm', ['install', tgzFile], tempDir); expect(installResult.code).toBe(0); // 檢查是否正確安裝 const nodeModulesPath = join(tempDir, 'node_modules', 'taiwan-holiday-mcp'); const stats = await fs.stat(nodeModulesPath); expect(stats.isDirectory()).toBe(true); // 清理打包檔案 await fs.unlink(tgzPath); } } finally { // 清理臨時目錄 await fs.rmdir(tempDir, { recursive: true }); } }, 60000); test('應正確處理依賴版本', async () => { const packageJson = JSON.parse( await fs.readFile('package.json', 'utf8') ); // 檢查關鍵依賴版本 expect(packageJson.dependencies['@modelcontextprotocol/sdk']).toBeDefined(); expect(packageJson.engines?.node).toBeDefined(); expect(packageJson.engines.node).toMatch(/>=18/); // 檢查 bin 設定 expect(packageJson.bin['taiwan-holiday-mcp']).toBe('dist/index.js'); // 檢查 files 設定 expect(packageJson.files).toContain('dist'); expect(packageJson.files).toContain('README.md'); // 檢查 main 和 types 設定 expect(packageJson.main).toBe('dist/index.js'); expect(packageJson.types).toBe('dist/index.d.ts'); }); test('應包含必要的建置檔案', async () => { // 確保建置已完成 const buildResult = await execCommand('npm', ['run', 'build']); expect(buildResult.code).toBe(0); // 檢查必要檔案是否存在 const requiredFiles = [ 'dist/index.js', 'dist/index.d.ts', 'dist/server.js', 'dist/server.d.ts', 'dist/holiday-service.js', 'dist/holiday-service.d.ts', 'dist/types.js', 'dist/types.d.ts' ]; for (const file of requiredFiles) { const stats = await fs.stat(file); expect(stats.isFile()).toBe(true); } // 檢查入口點檔案是否可執行 const indexStats = await fs.stat('dist/index.js'); if (process.platform !== 'win32') { // Unix 系統檢查執行權限 expect(indexStats.mode & 0o111).toBeGreaterThan(0); } }); test('應正確設定 package.json 欄位', async () => { const packageJson = JSON.parse( await fs.readFile('package.json', 'utf8') ); // 基本資訊 expect(packageJson.name).toBe('taiwan-holiday-mcp'); expect(packageJson.version).toMatch(/^\d+\.\d+\.\d+/); expect(packageJson.description).toBeTruthy(); expect(packageJson.license).toBe('MIT'); expect(packageJson.author).toBeTruthy(); // 模組設定 expect(packageJson.type).toBe('module'); expect(packageJson.main).toBe('dist/index.js'); expect(packageJson.types).toBe('dist/index.d.ts'); // 執行檔設定 expect(packageJson.bin).toBeDefined(); expect(packageJson.bin['taiwan-holiday-mcp']).toBe('dist/index.js'); // 發布檔案設定 expect(packageJson.files).toContain('dist'); expect(packageJson.files).toContain('README.md'); // 腳本設定 expect(packageJson.scripts.build).toBeTruthy(); expect(packageJson.scripts.test).toBeTruthy(); expect(packageJson.scripts.prepare).toBeTruthy(); // 引擎要求 expect(packageJson.engines.node).toMatch(/>=18/); // 關鍵字 expect(packageJson.keywords).toContain('mcp'); expect(packageJson.keywords).toContain('taiwan'); expect(packageJson.keywords).toContain('holiday'); // 儲存庫資訊 expect(packageJson.repository).toBeDefined(); expect(packageJson.repository.type).toBe('git'); expect(packageJson.repository.url).toBeTruthy(); }); test('應正確處理 npm scripts', async () => { // 測試建置腳本 const buildResult = await execCommand('npm', ['run', 'build']); expect(buildResult.code).toBe(0); // 測試 lint 腳本 const lintResult = await execCommand('npm', ['run', 'lint']); expect(lintResult.code).toBe(0); // 測試 prepare 腳本(模擬 npm install 時的行為) const prepareResult = await execCommand('npm', ['run', 'prepare']); expect(prepareResult.code).toBe(0); }, 30000); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/lis186/taiwan-holiday-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server