Skip to content

Commit 93b2c20

Browse files
committed
test: add integration and package configuration tests
1 parent fc7e639 commit 93b2c20

File tree

2 files changed

+148
-0
lines changed

2 files changed

+148
-0
lines changed

src/integration.test.ts

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
2+
import { spawn, ChildProcess } from 'child_process';
3+
import { fileURLToPath } from 'url';
4+
import { dirname, join } from 'path';
5+
6+
const __dirname = dirname(fileURLToPath(import.meta.url));
7+
8+
describe('Build artifact integration tests', () => {
9+
let serverProcess: ChildProcess;
10+
let serverOutput: string = '';
11+
let serverError: string = '';
12+
13+
beforeAll(async () => {
14+
// Build the project first
15+
await new Promise((resolve, reject) => {
16+
const buildProcess = spawn('yarn', ['build'], {
17+
cwd: join(__dirname, '..'),
18+
shell: true,
19+
});
20+
21+
buildProcess.on('close', (code) => {
22+
if (code === 0) {
23+
resolve(undefined);
24+
} else {
25+
reject(new Error(`Build failed with code ${code}`));
26+
}
27+
});
28+
});
29+
30+
// Start the server
31+
serverProcess = spawn('node', [join(__dirname, '../dist/index.js')], {
32+
stdio: ['pipe', 'pipe', 'pipe'],
33+
});
34+
35+
// Capture output
36+
serverProcess.stdout?.on('data', (data) => {
37+
serverOutput += data.toString();
38+
});
39+
40+
serverProcess.stderr?.on('data', (data) => {
41+
serverError += data.toString();
42+
});
43+
44+
// Wait for server to start
45+
await new Promise((resolve) => setTimeout(resolve, 1000));
46+
});
47+
48+
afterAll(() => {
49+
if (serverProcess) {
50+
serverProcess.kill();
51+
}
52+
});
53+
54+
it('should start without errors', () => {
55+
expect(serverError).toContain('MCP Wayback Machine server running on stdio');
56+
expect(serverProcess.killed).toBe(false);
57+
});
58+
59+
it('should respond to list_tools request', async () => {
60+
const request = {
61+
jsonrpc: '2.0',
62+
method: 'tools/list',
63+
params: {},
64+
id: 1,
65+
};
66+
67+
// Send request
68+
serverProcess.stdin?.write(JSON.stringify(request) + '\n');
69+
70+
// Wait for response
71+
await new Promise((resolve) => setTimeout(resolve, 500));
72+
73+
// The response should be in stdout (not stderr)
74+
expect(serverOutput.length).toBeGreaterThan(0);
75+
});
76+
77+
it('should handle malformed requests gracefully', async () => {
78+
const malformedRequest = 'not json';
79+
80+
serverProcess.stdin?.write(malformedRequest + '\n');
81+
82+
// Wait for potential error handling
83+
await new Promise((resolve) => setTimeout(resolve, 500));
84+
85+
// Server should still be running
86+
expect(serverProcess.killed).toBe(false);
87+
});
88+
});
89+
90+
describe('Executable permissions', () => {
91+
it('should have shebang in built file', async () => {
92+
const fs = await import('fs/promises');
93+
const builtFile = join(__dirname, '../dist/index.js');
94+
95+
const content = await fs.readFile(builtFile, 'utf-8');
96+
expect(content).toMatch(/^#!/);
97+
expect(content).toContain('#!/usr/bin/env node');
98+
});
99+
});

src/package.test.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { describe, it, expect } from 'vitest';
2+
import { readFileSync } from 'fs';
3+
import { join, dirname } from 'path';
4+
import { fileURLToPath } from 'url';
5+
6+
const __dirname = dirname(fileURLToPath(import.meta.url));
7+
8+
describe('Package configuration', () => {
9+
const packageJson = JSON.parse(
10+
readFileSync(join(__dirname, '../package.json'), 'utf-8')
11+
);
12+
13+
it('should have correct bin configuration', () => {
14+
expect(packageJson.bin).toBeDefined();
15+
expect(packageJson.bin['mcp-wayback-machine']).toBe('dist/index.js');
16+
});
17+
18+
it('should have correct main entry point', () => {
19+
expect(packageJson.main).toBe('dist/index.js');
20+
});
21+
22+
it('should be configured as ES module', () => {
23+
expect(packageJson.type).toBe('module');
24+
});
25+
26+
it('should have all required dependencies', () => {
27+
expect(packageJson.dependencies).toHaveProperty('@modelcontextprotocol/sdk');
28+
expect(packageJson.dependencies).toHaveProperty('zod');
29+
});
30+
31+
it('should have correct repository information', () => {
32+
expect(packageJson.repository.url).toBe('git+https://github.com/Mearman/mcp-wayback-machine.git');
33+
expect(packageJson.author).toBe('Joseph Mearman');
34+
});
35+
36+
it('should include necessary files in npm package', () => {
37+
expect(packageJson.files).toContain('dist/**/*.js');
38+
expect(packageJson.files).toContain('dist/**/*.d.ts');
39+
expect(packageJson.files).toContain('LICENSE');
40+
expect(packageJson.files).toContain('README.md');
41+
});
42+
43+
it('should have required scripts', () => {
44+
expect(packageJson.scripts).toHaveProperty('build');
45+
expect(packageJson.scripts).toHaveProperty('test');
46+
expect(packageJson.scripts).toHaveProperty('start');
47+
expect(packageJson.scripts).toHaveProperty('prepublishOnly');
48+
});
49+
});

0 commit comments

Comments
 (0)