Skip to main content
Glama
portel-dev

NCP - Natural Context Provider

by portel-dev
natural-language-parser.test.ts9.17 kB
/** * Unit Tests for NaturalLanguageParser * Tests schedule parsing from natural language to cron expressions */ import { describe, it, expect } from '@jest/globals'; import { NaturalLanguageParser } from '../../src/services/scheduler/natural-language-parser'; describe('NaturalLanguageParser', () => { describe('parseSchedule', () => { describe('every minute patterns', () => { it('should parse "every minute"', () => { const result = NaturalLanguageParser.parseSchedule('every minute'); expect(result.success).toBe(true); expect(result.cronExpression).toBe('* * * * *'); expect(result.explanation).toContain('every minute'); }); }); describe('every X minutes patterns', () => { it('should parse "every 5 minutes"', () => { const result = NaturalLanguageParser.parseSchedule('every 5 minutes'); expect(result.success).toBe(true); expect(result.cronExpression).toBe('*/5 * * * *'); }); it('should parse "every 30 minutes"', () => { const result = NaturalLanguageParser.parseSchedule('every 30 minutes'); expect(result.success).toBe(true); expect(result.cronExpression).toBe('*/30 * * * *'); }); it('should handle singular "minute"', () => { const result = NaturalLanguageParser.parseSchedule('every 1 minute'); expect(result.success).toBe(true); expect(result.cronExpression).toBe('*/1 * * * *'); }); }); describe('hourly patterns', () => { it('should parse "every hour"', () => { const result = NaturalLanguageParser.parseSchedule('every hour'); expect(result.success).toBe(true); expect(result.cronExpression).toBe('0 * * * *'); }); it('should parse "hourly"', () => { const result = NaturalLanguageParser.parseSchedule('hourly'); expect(result.success).toBe(true); expect(result.cronExpression).toBe('0 * * * *'); }); }); describe('daily patterns', () => { it('should parse "every day at 9am"', () => { const result = NaturalLanguageParser.parseSchedule('every day at 9am'); expect(result.success).toBe(true); expect(result.cronExpression).toBe('0 9 * * *'); }); it('should parse "daily at 2:30pm"', () => { const result = NaturalLanguageParser.parseSchedule('daily at 2:30pm'); expect(result.success).toBe(true); expect(result.cronExpression).toBe('30 14 * * *'); }); it('should parse "every day at noon"', () => { const result = NaturalLanguageParser.parseSchedule('every day at noon'); expect(result.success).toBe(true); expect(result.cronExpression).toBe('0 12 * * *'); }); it('should parse "every day at midnight"', () => { const result = NaturalLanguageParser.parseSchedule('every day at midnight'); expect(result.success).toBe(true); expect(result.cronExpression).toBe('0 0 * * *'); }); it('should default to 9am if no time specified', () => { const result = NaturalLanguageParser.parseSchedule('every day'); expect(result.success).toBe(true); expect(result.cronExpression).toBe('0 9 * * *'); }); }); describe('weekday patterns', () => { it('should parse "every weekday at 9am"', () => { const result = NaturalLanguageParser.parseSchedule('every weekday at 9am'); expect(result.success).toBe(true); expect(result.cronExpression).toBe('0 9 * * 1-5'); }); it('should parse "monday to friday at 2:30pm"', () => { const result = NaturalLanguageParser.parseSchedule('monday to friday at 2:30pm'); expect(result.success).toBe(true); expect(result.cronExpression).toBe('30 14 * * 1-5'); }); it('should default to 9am for weekdays if no time', () => { const result = NaturalLanguageParser.parseSchedule('every weekday'); expect(result.success).toBe(true); expect(result.cronExpression).toBe('0 9 * * 1-5'); }); }); describe('weekend patterns', () => { it('should parse "every weekend at 10am"', () => { const result = NaturalLanguageParser.parseSchedule('every weekend at 10am'); expect(result.success).toBe(true); expect(result.cronExpression).toBe('0 10 * * 0,6'); }); }); describe('specific weekday patterns', () => { it('should parse "every monday at 9am"', () => { const result = NaturalLanguageParser.parseSchedule('every monday at 9am'); expect(result.success).toBe(true); expect(result.cronExpression).toBe('0 9 * * 1'); }); it('should parse "every friday at 5pm"', () => { const result = NaturalLanguageParser.parseSchedule('every friday at 5pm'); expect(result.success).toBe(true); expect(result.cronExpression).toBe('0 17 * * 5'); }); it('should parse "every sunday at noon"', () => { const result = NaturalLanguageParser.parseSchedule('every sunday at noon'); expect(result.success).toBe(true); expect(result.cronExpression).toBe('0 12 * * 0'); }); }); describe('monthly patterns', () => { it('should parse "monthly at 9am"', () => { const result = NaturalLanguageParser.parseSchedule('monthly at 9am'); expect(result.success).toBe(true); expect(result.cronExpression).toBe('0 9 1 * *'); }); it('should parse "first day of month at 10am"', () => { const result = NaturalLanguageParser.parseSchedule('first day of the month at 10am'); expect(result.success).toBe(true); expect(result.cronExpression).toBe('0 10 1 * *'); }); }); describe('relative time patterns', () => { it('should parse "in 5 minutes"', () => { const result = NaturalLanguageParser.parseSchedule('in 5 minutes'); expect(result.success).toBe(true); expect(result.fireOnce).toBe(true); expect(result.explanation).toContain('5 minutes from now'); // Cron expression will be specific to current time + 5 minutes expect(result.cronExpression).toMatch(/^\d+ \d+ \d+ \d+ \*$/); }); it('should parse "in 2 hours"', () => { const result = NaturalLanguageParser.parseSchedule('in 2 hours'); expect(result.success).toBe(true); expect(result.fireOnce).toBe(true); expect(result.explanation).toContain('2 hours from now'); }); it('should parse "in 1 day"', () => { const result = NaturalLanguageParser.parseSchedule('in 1 day'); expect(result.success).toBe(true); expect(result.fireOnce).toBe(true); expect(result.explanation).toContain('1 day from now'); }); }); describe('time formats', () => { it('should handle 12-hour format with minutes', () => { const result = NaturalLanguageParser.parseSchedule('every day at 2:30pm'); expect(result.success).toBe(true); expect(result.cronExpression).toBe('30 14 * * *'); }); it('should handle AM/PM correctly', () => { const resultAM = NaturalLanguageParser.parseSchedule('every day at 9am'); const resultPM = NaturalLanguageParser.parseSchedule('every day at 9pm'); expect(resultAM.cronExpression).toBe('0 9 * * *'); expect(resultPM.cronExpression).toBe('0 21 * * *'); }); it('should handle noon correctly', () => { const result = NaturalLanguageParser.parseSchedule('every day at noon'); expect(result.cronExpression).toBe('0 12 * * *'); }); it('should handle midnight correctly', () => { const result = NaturalLanguageParser.parseSchedule('every day at midnight'); expect(result.cronExpression).toBe('0 0 * * *'); }); }); describe('error cases', () => { it('should return error for invalid pattern', () => { const result = NaturalLanguageParser.parseSchedule('something invalid'); expect(result.success).toBe(false); expect(result.error).toBeDefined(); }); it('should return error for empty string', () => { const result = NaturalLanguageParser.parseSchedule(''); expect(result.success).toBe(false); }); it('should provide helpful error messages with examples', () => { const result = NaturalLanguageParser.parseSchedule('invalid schedule'); expect(result.success).toBe(false); expect(result.error).toContain('Supported patterns'); expect(result.error).toContain('every day at 9am'); }); }); describe('case insensitivity', () => { it('should handle different cases', () => { const lower = NaturalLanguageParser.parseSchedule('every day at 9am'); const upper = NaturalLanguageParser.parseSchedule('EVERY DAY AT 9AM'); const mixed = NaturalLanguageParser.parseSchedule('Every Day At 9AM'); expect(lower.cronExpression).toBe(upper.cronExpression); expect(lower.cronExpression).toBe(mixed.cronExpression); }); }); }); });

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/portel-dev/ncp'

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