Skip to main content
Glama
pshempel

MCP Time Server Node

by pshempel
debug-coverage.test.ts9.59 kB
import { describe, it, expect, beforeEach, afterEach, jest } from '@jest/globals'; /** * Tests for Debug Coverage in Remaining Tools * * These tests verify that debug statements are properly added to: * - subtractTime (timing namespace) * - formatTime (timing namespace) * - nextOccurrence (recurrence namespace) * * Test Strategy: * 1. Mock stderr to capture debug output * 2. Enable specific DEBUG patterns * 3. Call the tool functions * 4. Verify expected debug output appears */ describe('Debug Coverage for Tools', () => { const originalEnv = process.env; const originalStderr = process.stderr.write; let stderrOutput: string[] = []; beforeEach(() => { // Reset environment process.env = { ...originalEnv }; stderrOutput = []; // Mock stderr to capture debug output process.stderr.write = jest.fn((chunk: string | Uint8Array) => { stderrOutput.push(chunk.toString()); return true; }) as any; // Clear module cache to ensure fresh imports jest.resetModules(); }); afterEach(() => { process.env = originalEnv; process.stderr.write = originalStderr; jest.resetModules(); }); describe('subtractTime debug coverage', () => { it('should log entry with timing namespace', async () => { process.env.DEBUG = 'mcp:timing'; const { subtractTime } = await import('../../src/tools/subtractTime'); const result = subtractTime({ time: '2025-01-01T12:00:00Z', amount: 2, unit: 'hours', }); const output = stderrOutput.join(''); // Should contain timing namespace output expect(output).toContain('mcp:timing'); expect(output).toContain('subtractTime called'); // Verify the result is correct expect(result.original).toBe('2025-01-01T12:00:00.000Z'); expect(result.result).toBe('2025-01-01T10:00:00.000Z'); }); it('should log delegation to addTime', async () => { process.env.DEBUG = 'mcp:timing'; const { subtractTime } = await import('../../src/tools/subtractTime'); subtractTime({ time: '2025-01-01T12:00:00Z', amount: 5, unit: 'days', }); const output = stderrOutput.join(''); // Should show it's delegating to addTime with negated amount expect(output).toContain('subtractTime called'); expect(output).toContain('Delegating to addTime with negated amount'); }); it('should not log when DEBUG is not set', async () => { delete process.env.DEBUG; const { subtractTime } = await import('../../src/tools/subtractTime'); subtractTime({ time: '2025-01-01T12:00:00Z', amount: 1, unit: 'hours', }); const output = stderrOutput.join(''); expect(output).toBe(''); }); }); describe('formatTime debug coverage', () => { it('should log entry with timing namespace', async () => { process.env.DEBUG = 'mcp:timing'; const { formatTime } = await import('../../src/tools/formatTime'); const result = formatTime({ time: '2025-01-01T12:00:00Z', format: 'custom', custom_format: 'yyyy-MM-dd', }); const output = stderrOutput.join(''); // Should contain timing namespace output expect(output).toContain('mcp:timing'); expect(output).toContain('formatTime called'); // Verify the result is correct expect(result.formatted).toBe('2025-01-01'); }); it('should log format validation with validation namespace', async () => { process.env.DEBUG = 'mcp:validation'; const { formatTime } = await import('../../src/tools/formatTime'); formatTime({ time: '2025-01-01T12:00:00Z', format: 'custom', custom_format: 'yyyy-MM-dd HH:mm:ss', }); const output = stderrOutput.join(''); // Should contain validation of format string expect(output).toContain('mcp:validation'); expect(output).toContain('isValidFormatString'); }); it('should log parsing with parse namespace', async () => { process.env.DEBUG = 'mcp:parse'; const { formatTime } = await import('../../src/tools/formatTime'); formatTime({ time: '2025-01-01T12:00:00Z', format: 'relative', }); const output = stderrOutput.join(''); // Should contain parse output expect(output).toContain('mcp:parse'); expect(output).toContain('parseTimeWithFallback'); }); it('should log relative formatting logic', async () => { process.env.DEBUG = 'mcp:timing'; const { formatTime } = await import('../../src/tools/formatTime'); formatTime({ time: new Date().toISOString(), format: 'relative', }); const output = stderrOutput.join(''); // Should contain formatting logic expect(output).toContain('mcp:timing'); expect(output).toContain('formatRelativeTime'); }); it('should log return value', async () => { process.env.DEBUG = 'mcp:timing'; const { formatTime } = await import('../../src/tools/formatTime'); const result = formatTime({ time: '2025-01-01T12:00:00Z', format: 'custom', custom_format: 'yyyy', }); const output = stderrOutput.join(''); // Should log the return expect(output).toContain('formatTime returning'); expect(result.formatted).toBe('2025'); }); }); describe('nextOccurrence debug coverage', () => { it('should log entry with recurrence namespace', async () => { process.env.DEBUG = 'mcp:recurrence'; const { nextOccurrence } = await import('../../src/tools/nextOccurrence'); const result = nextOccurrence({ pattern: 'daily', time: '09:00', }); const output = stderrOutput.join(''); // Should contain recurrence namespace output expect(output).toContain('mcp:recurrence'); expect(output).toContain('nextOccurrence called'); // Result should be valid expect(result).toHaveProperty('next'); expect(result).toHaveProperty('unix'); expect(result).toHaveProperty('days_until'); }); it('should log parameter mapping', async () => { process.env.DEBUG = 'mcp:recurrence'; const { nextOccurrence } = await import('../../src/tools/nextOccurrence'); nextOccurrence({ pattern: 'weekly', day_of_week: 1, time: '10:00', }); const output = stderrOutput.join(''); // Should log parameter mapping expect(output).toContain('mapToRecurrenceParams'); expect(output).toContain('pattern: weekly'); }); it('should log calculation steps', async () => { process.env.DEBUG = 'mcp:recurrence'; const { nextOccurrence } = await import('../../src/tools/nextOccurrence'); nextOccurrence({ pattern: 'monthly', day_of_month: 15, }); const output = stderrOutput.join(''); // Should log calculation steps expect(output).toContain('calculateNextOccurrence'); expect(output).toContain('calculateDaysUntil'); }); it('should log parsing with parse namespace when start_from is provided', async () => { process.env.DEBUG = 'mcp:parse'; const { nextOccurrence } = await import('../../src/tools/nextOccurrence'); nextOccurrence({ pattern: 'daily', start_from: '2025-02-01T00:00:00Z', }); const output = stderrOutput.join(''); // Should contain parse output expect(output).toContain('mcp:parse'); expect(output).toContain('Parsing start_from'); }); it('should log validation with validation namespace', async () => { process.env.DEBUG = 'mcp:validation'; const { nextOccurrence } = await import('../../src/tools/nextOccurrence'); nextOccurrence({ pattern: 'daily', timezone: 'America/New_York', }); const output = stderrOutput.join(''); // Should contain validation output expect(output).toContain('mcp:validation'); expect(output).toContain('Validating timezone'); }); it('should log return value', async () => { process.env.DEBUG = 'mcp:recurrence'; const { nextOccurrence } = await import('../../src/tools/nextOccurrence'); const result = nextOccurrence({ pattern: 'daily', }); const output = stderrOutput.join(''); // Should log the return expect(output).toContain('nextOccurrence returning'); expect(result).toHaveProperty('next'); }); }); describe('Cross-namespace isolation', () => { it('subtractTime should only show in timing namespace', async () => { process.env.DEBUG = 'mcp:recurrence'; const { subtractTime } = await import('../../src/tools/subtractTime'); subtractTime({ time: '2025-01-01T12:00:00Z', amount: 1, unit: 'hours', }); const output = stderrOutput.join(''); // Should NOT contain timing output when only recurrence is enabled expect(output).not.toContain('subtractTime'); }); it('nextOccurrence should only show in recurrence namespace', async () => { process.env.DEBUG = 'mcp:timing'; const { nextOccurrence } = await import('../../src/tools/nextOccurrence'); nextOccurrence({ pattern: 'daily', }); const output = stderrOutput.join(''); // Should NOT contain recurrence output when only timing is enabled expect(output).not.toContain('nextOccurrence'); }); }); });

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/pshempel/mcp-time-server-node'

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