@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
JavaScript
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');
}
});
});
});