Skip to main content
Glama

mcp-structured-memory

moveListItemHelpers.test.ts11.2 kB
import { describe, it, expect } from 'vitest' import { findItemBoundaries, extractItemLines, removeItemFromLines, addReasonToItem, prepareDestinationContent, validateItemExists, countRemainingItems } from './moveListItemHelpers.js' describe('moveListItem Helper Functions', () => { const sampleLines = [ '### Company A', '- **Role**: Engineer', '- **Status**: Applied', '- **Notes**: Great opportunity', '', '### Company B', '- **Role**: Designer', '- **Status**: Interview scheduled', '', '### Company C', '- **Role**: Manager', '- **Compensation**: $120k' ]; describe('findItemBoundaries', () => { it('should find boundaries for first item', () => { const result = findItemBoundaries(sampleLines, 'Company A') expect(result).toEqual({ startIndex: 0, endIndex: 3 }) }) it('should find boundaries for middle item', () => { const result = findItemBoundaries(sampleLines, 'Company B') expect(result).toEqual({ startIndex: 5, endIndex: 7 }) }) it('should find boundaries for last item', () => { const result = findItemBoundaries(sampleLines, 'Company C') expect(result).toEqual({ startIndex: 9, endIndex: 11 }) }) it('should handle case-insensitive search', () => { const result = findItemBoundaries(sampleLines, 'company a') expect(result).toEqual({ startIndex: 0, endIndex: 3 }) }) it('should find item by partial identifier', () => { const result = findItemBoundaries(sampleLines, 'Engineer') expect(result).toEqual({ startIndex: 1, // Finds first occurrence at line 1: "- **Role**: Engineer" endIndex: 3 }) }) it('should return null when item not found', () => { const result = findItemBoundaries(sampleLines, 'Nonexistent Company') expect(result).toBeNull() }) it('should handle empty lines array', () => { const result = findItemBoundaries([], 'anything') expect(result).toBeNull() }) it('should handle item at very end without empty line', () => { const lines = [ '### Company A', '- Details here' ] const result = findItemBoundaries(lines, 'Company A') expect(result).toEqual({ startIndex: 0, endIndex: 1 }) }) it('should handle item followed by empty line and EOF', () => { const lines = [ '### Company A', '- Details here', '' ] const result = findItemBoundaries(lines, 'Company A') expect(result).toEqual({ startIndex: 0, endIndex: 2 }) }) it('should stop at next heading correctly', () => { const lines = [ '### Company A', '- Role: Engineer', '- Notes: Good fit', '### Company B', '- Role: Designer' ] const result = findItemBoundaries(lines, 'Company A') expect(result).toEqual({ startIndex: 0, endIndex: 2 }) }) it('should handle empty line before heading', () => { const lines = [ '### Company A', '- Role: Engineer', '', '### Company B', '- Role: Designer' ] const result = findItemBoundaries(lines, 'Company A') expect(result).toEqual({ startIndex: 0, endIndex: 1 }) }) }) describe('extractItemLines', () => { it('should extract correct lines based on boundaries', () => { const boundaries = { startIndex: 0, endIndex: 3 } const result = extractItemLines(sampleLines, boundaries) expect(result).toEqual([ '### Company A', '- **Role**: Engineer', '- **Status**: Applied', '- **Notes**: Great opportunity' ]) }) it('should extract single line item', () => { const boundaries = { startIndex: 5, endIndex: 5 } const result = extractItemLines(sampleLines, boundaries) expect(result).toEqual(['### Company B']) }) it('should handle boundaries at edges', () => { const boundaries = { startIndex: 0, endIndex: sampleLines.length - 1 } const result = extractItemLines(sampleLines, boundaries) expect(result).toEqual(sampleLines) }) }) describe('removeItemFromLines', () => { it('should remove item from beginning', () => { const boundaries = { startIndex: 0, endIndex: 3 } const result = removeItemFromLines(sampleLines, boundaries) expect(result).toEqual([ '', '### Company B', '- **Role**: Designer', '- **Status**: Interview scheduled', '', '### Company C', '- **Role**: Manager', '- **Compensation**: $120k' ]) }) it('should remove item from middle', () => { const boundaries = { startIndex: 5, endIndex: 7 } const result = removeItemFromLines(sampleLines, boundaries) expect(result).toEqual([ '### Company A', '- **Role**: Engineer', '- **Status**: Applied', '- **Notes**: Great opportunity', '', '', '### Company C', '- **Role**: Manager', '- **Compensation**: $120k' ]) }) it('should remove item from end', () => { const boundaries = { startIndex: 9, endIndex: 11 } const result = removeItemFromLines(sampleLines, boundaries) expect(result).toEqual([ '### Company A', '- **Role**: Engineer', '- **Status**: Applied', '- **Notes**: Great opportunity', '', '### Company B', '- **Role**: Designer', '- **Status**: Interview scheduled', '' ]) }) it('should handle removing entire content', () => { const lines = ['### Only Item'] const boundaries = { startIndex: 0, endIndex: 0 } const result = removeItemFromLines(lines, boundaries) expect(result).toEqual([]) }) }) describe('addReasonToItem', () => { it('should add reason as HTML comment', () => { const itemLines = [ '### Company A', '- **Role**: Engineer' ] const result = addReasonToItem(itemLines, 'Better opportunity', 'Active Pipeline') expect(result).toEqual([ '### Company A', '- **Role**: Engineer', ' <!-- Moved from Active Pipeline: Better opportunity -->' ]) }) it('should handle empty item lines', () => { const result = addReasonToItem([], 'Test reason', 'Source Section') expect(result).toEqual([ ' <!-- Moved from Source Section: Test reason -->' ]) }) it('should handle special characters in reason', () => { const itemLines = ['### Test Item'] const result = addReasonToItem(itemLines, 'Reason with "quotes" & symbols', 'Section') expect(result).toEqual([ '### Test Item', ' <!-- Moved from Section: Reason with "quotes" & symbols -->' ]) }) it('should handle long reasons', () => { const itemLines = ['### Test Item'] const longReason = 'A'.repeat(200) const result = addReasonToItem(itemLines, longReason, 'Section') expect(result).toEqual([ '### Test Item', ` <!-- Moved from Section: ${longReason} -->` ]) }) }) describe('prepareDestinationContent', () => { it('should append to existing content', () => { const itemLines = ['### New Item', '- Details here'] const existingContent = '### Existing Item\n- Existing details' const result = prepareDestinationContent(itemLines, existingContent) expect(result).toBe( '### Existing Item\n- Existing details\n\n### New Item\n- Details here' ) }) it('should create new content when no existing content', () => { const itemLines = ['### New Item', '- Details here'] const result = prepareDestinationContent(itemLines, null) expect(result).toBe('### New Item\n- Details here') }) it('should handle empty existing content', () => { const itemLines = ['### New Item'] const existingContent = '' const result = prepareDestinationContent(itemLines, existingContent) expect(result).toBe('\n\n### New Item') }) it('should handle empty item lines', () => { const itemLines: string[] = [] const existingContent = '### Existing' const result = prepareDestinationContent(itemLines, existingContent) expect(result).toBe('### Existing\n') }) it('should handle both empty', () => { const result = prepareDestinationContent([], null) expect(result).toBe('') }) }) describe('validateItemExists', () => { it('should return true when item exists', () => { const result = validateItemExists(sampleLines, 'Company A') expect(result).toBe(true) }) it('should return true for partial matches', () => { const result = validateItemExists(sampleLines, 'Engineer') expect(result).toBe(true) }) it('should be case insensitive', () => { const result = validateItemExists(sampleLines, 'company a') expect(result).toBe(true) }) it('should return false when item does not exist', () => { const result = validateItemExists(sampleLines, 'Nonexistent') expect(result).toBe(false) }) it('should handle empty lines', () => { const result = validateItemExists([], 'anything') expect(result).toBe(false) }) it('should handle whitespace', () => { const lines = [' ### Company A ', ' - Role: Engineer '] const result = validateItemExists(lines, 'Company A') expect(result).toBe(true) }) }) describe('countRemainingItems', () => { it('should count heading lines correctly', () => { const result = countRemainingItems(sampleLines) expect(result).toBe(3) // Company A, B, and C }) it('should return 0 for lines with no headings', () => { const lines = ['- Some bullet', '- Another bullet', 'Regular text'] const result = countRemainingItems(lines) expect(result).toBe(0) }) it('should handle empty lines array', () => { const result = countRemainingItems([]) expect(result).toBe(0) }) it('should only count level 3 headings', () => { const lines = [ '# Level 1', '## Level 2', '### Level 3', '#### Level 4', '### Another Level 3' ] const result = countRemainingItems(lines) expect(result).toBe(2) // Only the ### headings }) it('should handle headings with extra spaces', () => { const lines = [ ' ### Company A ', '### Company B', ' ###Company C', // No space after ### '### Company D' // Extra space after ### ] const result = countRemainingItems(lines) expect(result).toBe(3) // Should count first three, last one has space after ### }) }) })

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/nmeierpolys/mcp-structured-memory'

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