UNPKG

@emmahyde/thinking-patterns

Version:

MCP server combining systematic thinking, mental models, debugging approaches, and stochastic algorithms for comprehensive cognitive pattern support

414 lines (413 loc) 16.7 kB
import { VisualReasoningSchema, VisualElementSchema, SpatialRelationshipSchema, VisualPatternSchema, CognitiveLoadSchema, ReasoningStepSchema, DiagramAnalysisSchema } from '../../src/schemas/VisualReasoningSchema.js'; describe('VisualReasoningSchema', () => { describe('SpatialRelationshipSchema', () => { it('should validate a basic spatial relationship', () => { const validData = { type: 'adjacent', elementA: 'node1', elementB: 'node2' }; const result = SpatialRelationshipSchema.safeParse(validData); expect(result.success).toBe(true); }); it('should validate with optional fields', () => { const validData = { type: 'overlapping', elementA: 'shape1', elementB: 'shape2', strength: 0.8, description: 'Partially overlapping circles' }; const result = SpatialRelationshipSchema.safeParse(validData); expect(result.success).toBe(true); }); it('should reject invalid relationship type', () => { const invalidData = { type: 'invalid-type', elementA: 'node1', elementB: 'node2' }; const result = SpatialRelationshipSchema.safeParse(invalidData); expect(result.success).toBe(false); }); }); describe('VisualPatternSchema', () => { it('should validate a basic visual pattern', () => { const validData = { type: 'symmetry', elements: ['elem1', 'elem2', 'elem3'], confidence: 0.9, significance: 'high', description: 'Bilateral symmetry pattern' }; const result = VisualPatternSchema.safeParse(validData); expect(result.success).toBe(true); }); it('should validate with optional id', () => { const validData = { id: 'pattern-001', type: 'repetition', elements: ['item1', 'item2'], confidence: 0.7, significance: 'medium', description: 'Repeating geometric pattern' }; const result = VisualPatternSchema.safeParse(validData); expect(result.success).toBe(true); }); }); describe('CognitiveLoadSchema', () => { it('should validate cognitive load assessment', () => { const validData = { complexity: 'medium', elementCount: 15, connectionDensity: 0.6, informationDensity: 'moderate' }; const result = CognitiveLoadSchema.safeParse(validData); expect(result.success).toBe(true); }); it('should validate with all optional fields', () => { const validData = { complexity: 'high', elementCount: 25, connectionDensity: 0.8, hierarchyDepth: 4, informationDensity: 'dense', readabilityScore: 0.4 }; const result = CognitiveLoadSchema.safeParse(validData); expect(result.success).toBe(true); }); }); describe('ReasoningStepSchema', () => { it('should validate a basic reasoning step', () => { const validData = { stepNumber: 1, type: 'observation', description: 'Initial observation of the diagram structure', confidence: 0.9 }; const result = ReasoningStepSchema.safeParse(validData); expect(result.success).toBe(true); }); it('should validate with all optional fields', () => { const validData = { id: 'step-001', stepNumber: 2, type: 'inference', description: 'Inferred relationship between components', evidence: ['visual-cue-1', 'pattern-match'], confidence: 0.8, dependencies: ['step-001'] }; const result = ReasoningStepSchema.safeParse(validData); expect(result.success).toBe(true); }); }); describe('VisualElementSchema', () => { it('should validate a basic visual element', () => { const validData = { id: 'node1', type: 'node', properties: { color: 'blue', size: 'medium' } }; const result = VisualElementSchema.safeParse(validData); expect(result.success).toBe(true); }); it('should validate with enhanced properties format', () => { const validData = { id: 'shape1', type: 'shape', label: 'Process Step', properties: { position: { x: 100, y: 200 }, dimensions: { width: 80, height: 40 }, style: { color: 'blue', shape: 'rectangle', size: 'medium', opacity: 0.8 }, semantics: { meaning: 'Business process', importance: 'high', category: 'workflow' } } }; const result = VisualElementSchema.safeParse(validData); expect(result.success).toBe(true); }); it('should validate edge elements with source and target', () => { const validData = { id: 'edge1', type: 'edge', source: 'node1', target: 'node2', properties: { style: { color: 'gray' } } }; const result = VisualElementSchema.safeParse(validData); expect(result.success).toBe(true); }); it('should validate container elements', () => { const validData = { id: 'container1', type: 'container', label: 'Group A', contains: ['node1', 'node2', 'edge1'], properties: { style: { color: 'lightgray' } } }; const result = VisualElementSchema.safeParse(validData); expect(result.success).toBe(true); }); }); describe('DiagramAnalysisSchema', () => { it('should validate basic diagram analysis', () => { const validData = { structure: { type: 'hierarchical' } }; const result = DiagramAnalysisSchema.safeParse(validData); expect(result.success).toBe(true); }); it('should validate comprehensive diagram analysis', () => { const validData = { structure: { type: 'network', balance: 'symmetric', flow: 'top-down' }, patterns: [{ type: 'hierarchy', elements: ['root', 'child1', 'child2'], confidence: 0.9, significance: 'high', description: 'Clear hierarchical structure' }], relationships: [{ type: 'above', elementA: 'parent', elementB: 'child', strength: 0.8 }], cognitiveLoad: { complexity: 'medium', elementCount: 12, connectionDensity: 0.5, informationDensity: 'moderate' }, effectiveness: { clarity: 0.8, completeness: 0.9, efficiency: 0.7 } }; const result = DiagramAnalysisSchema.safeParse(validData); expect(result.success).toBe(true); }); }); describe('VisualReasoningSchema', () => { it('should validate minimal visual reasoning data', () => { const validData = { operation: 'observe', diagramId: 'diagram-001', diagramType: 'flowchart', iteration: 1, nextOperationNeeded: false }; const result = VisualReasoningSchema.safeParse(validData); expect(result.success).toBe(true); if (result.success) { const data = result.data; expect(data.operation).toBe('observe'); expect(data.diagramId).toBe('diagram-001'); expect(data.diagramType).toBe('flowchart'); } }); it('should validate comprehensive visual reasoning data', () => { const validData = { operation: 'analyze', diagramId: 'complex-diagram', diagramType: 'concept-map', elements: [ { id: 'concept1', type: 'node', label: 'Main Concept', properties: { position: { x: 100, y: 100 }, style: { color: 'blue', size: 'large' } } }, { id: 'relation1', type: 'edge', source: 'concept1', target: 'concept2', properties: { style: { color: 'gray' } } } ], transformationType: 'highlight', transformationDetails: { target: ['concept1'], parameters: { highlightColor: 'yellow' }, rationale: 'Emphasize key concept' }, reasoningChain: [ { stepNumber: 1, type: 'observation', description: 'Identified central concept', confidence: 0.9 }, { stepNumber: 2, type: 'inference', description: 'Concept appears to be hub node', confidence: 0.8, dependencies: ['step-1'] } ], iteration: 3, observation: 'The diagram shows a hub-and-spoke pattern', insight: 'Central concept is the key organizing principle', hypothesis: 'Highlighting the central concept will improve comprehension', diagramAnalysis: { structure: { type: 'network', balance: 'radial' }, effectiveness: { clarity: 0.7, completeness: 0.8, efficiency: 0.6 } }, recommendations: [ 'Increase font size of central concept', 'Use consistent color coding for related concepts' ], nextOperationNeeded: true, suggestedOperations: ['transform', 'update'], purpose: 'Improve diagram readability and comprehension', audience: 'Students learning the subject matter', context: 'Educational material for introductory course' }; const result = VisualReasoningSchema.safeParse(validData); expect(result.success).toBe(true); if (result.success) { const data = result.data; expect(data.elements).toHaveLength(2); expect(data.reasoningChain).toHaveLength(2); expect(data.recommendations).toHaveLength(2); expect(data.suggestedOperations).toHaveLength(2); } }); it('should validate different diagram types', () => { const diagramTypes = ['graph', 'flowchart', 'state-diagram', 'concept-map', 'tree-diagram', 'network-diagram', 'mind-map', 'organization-chart', 'custom']; diagramTypes.forEach(diagramType => { const validData = { operation: 'create', diagramId: `${diagramType}-test`, diagramType, iteration: 1, nextOperationNeeded: false }; const result = VisualReasoningSchema.safeParse(validData); expect(result.success).toBe(true); }); }); it('should validate different operations', () => { const operations = ['create', 'update', 'delete', 'transform', 'observe', 'analyze', 'compare', 'synthesize']; operations.forEach(operation => { const validData = { operation, diagramId: 'test-diagram', diagramType: 'graph', iteration: 1, nextOperationNeeded: false }; const result = VisualReasoningSchema.safeParse(validData); expect(result.success).toBe(true); }); }); it('should reject missing required fields', () => { const invalidData = { operation: 'observe', diagramType: 'flowchart', iteration: 1 // Missing diagramId and nextOperationNeeded }; const result = VisualReasoningSchema.safeParse(invalidData); expect(result.success).toBe(false); }); it('should reject invalid operation type', () => { const invalidData = { operation: 'invalid-operation', diagramId: 'test', diagramType: 'graph', iteration: 1, nextOperationNeeded: false }; const result = VisualReasoningSchema.safeParse(invalidData); expect(result.success).toBe(false); }); it('should handle legacy properties format', () => { const validData = { operation: 'update', diagramId: 'legacy-diagram', diagramType: 'custom', elements: [ { id: 'legacy-node', type: 'node', properties: { // Legacy format - any object customField: 'value', anotherField: 123, nestedObject: { key: 'value' } } } ], iteration: 1, nextOperationNeeded: false }; const result = VisualReasoningSchema.safeParse(validData); expect(result.success).toBe(true); }); }); describe('Type inference', () => { it('should properly infer TypeScript types', () => { const validData = { operation: 'analyze', diagramId: 'type-test', diagramType: 'graph', iteration: 1, nextOperationNeeded: true, observation: 'Test observation', insight: 'Test insight' }; const result = VisualReasoningSchema.safeParse(validData); expect(result.success).toBe(true); if (result.success) { const data = result.data; // TypeScript should infer these types correctly expect(typeof data.operation).toBe('string'); expect(typeof data.diagramId).toBe('string'); expect(typeof data.iteration).toBe('number'); expect(typeof data.nextOperationNeeded).toBe('boolean'); expect(typeof data.observation).toBe('string'); expect(typeof data.insight).toBe('string'); } }); }); });