Major enhancements for type safety and developer experience: - Add BrainyTypes static API for type management and AI-powered suggestions - Implement strict type validation for all 31 NounType categories - Remove dangerous generic add() method that bypassed type safety - Add intelligent type inference with confidence scoring - Provide helpful error messages with typo suggestions using Levenshtein distance - Update all internal code, examples, and documentation to use typed methods - Enhance CLI with new type management commands (types, suggest, validate) Breaking changes: - Remove deprecated add() method - use addNoun() with explicit type parameter - All addNoun() calls now require explicit type as second parameter This release significantly improves type safety across the entire system while maintaining backward compatibility for properly typed method calls. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
103 lines
No EOL
3.6 KiB
TypeScript
103 lines
No EOL
3.6 KiB
TypeScript
import { describe, it, expect, beforeEach } from 'vitest'
|
|
import { BrainyData } from '../src/brainyData.js'
|
|
import { NounType, VerbType } from '../src/types/graphTypes.js'
|
|
import { validateNounType, validateVerbType } from '../src/utils/typeValidation.js'
|
|
|
|
describe('Type Enforcement System', () => {
|
|
describe('Type Validation Module', () => {
|
|
it('should validate correct noun types', () => {
|
|
expect(validateNounType(NounType.Person)).toBe('person')
|
|
expect(validateNounType('organization')).toBe('organization')
|
|
expect(validateNounType(NounType.Document)).toBe('document')
|
|
})
|
|
|
|
it('should reject invalid noun types with helpful errors', () => {
|
|
expect(() => validateNounType('invalid')).toThrow('Invalid noun type')
|
|
expect(() => validateNounType('')).toThrow('Invalid noun type')
|
|
expect(() => validateNounType(null)).toThrow('Invalid noun type')
|
|
expect(() => validateNounType(undefined)).toThrow('Invalid noun type')
|
|
})
|
|
|
|
it('should provide helpful suggestions for typos', () => {
|
|
expect(() => validateNounType('persan')).toThrow(/Did you mean 'person'/)
|
|
expect(() => validateNounType('doc')).toThrow(/Did you mean 'document'/)
|
|
expect(() => validateNounType('org')).toThrow(/Did you mean 'organization'/)
|
|
})
|
|
|
|
it('should validate correct verb types', () => {
|
|
expect(validateVerbType(VerbType.RelatedTo)).toBe('relatedTo')
|
|
expect(validateVerbType('contains')).toBe('contains')
|
|
expect(validateVerbType(VerbType.Creates)).toBe('creates')
|
|
})
|
|
})
|
|
|
|
describe('addNoun with Type Enforcement', () => {
|
|
let brain: BrainyData
|
|
|
|
beforeEach(async () => {
|
|
brain = new BrainyData({
|
|
storage: { forceMemoryStorage: true },
|
|
logging: { verbose: false }
|
|
})
|
|
await brain.init()
|
|
})
|
|
|
|
it('should require noun type parameter', async () => {
|
|
// TypeScript should prevent this, but test runtime validation
|
|
await expect(
|
|
(brain.addNoun as any)('Test data', { title: 'Test' })
|
|
).rejects.toThrow()
|
|
})
|
|
|
|
it('should accept valid noun type', async () => {
|
|
const id = await brain.addNoun('John Doe', NounType.Person, { age: 30 })
|
|
expect(id).toBeDefined()
|
|
|
|
const noun = await brain.getNoun(id)
|
|
expect(noun.metadata.noun).toBe('person')
|
|
expect(noun.metadata.age).toBe(30)
|
|
})
|
|
|
|
it('should accept noun type as string', async () => {
|
|
const id = await brain.addNoun('Document content', 'document', {
|
|
title: 'Important Doc',
|
|
author: 'Jane'
|
|
})
|
|
expect(id).toBeDefined()
|
|
|
|
const noun = await brain.getNoun(id)
|
|
expect(noun.metadata.noun).toBe('document')
|
|
expect(noun.metadata.title).toBe('Important Doc')
|
|
})
|
|
|
|
it('should validate noun type and reject invalid ones', async () => {
|
|
await expect(
|
|
brain.addNoun('Test', 'invalidType', {})
|
|
).rejects.toThrow('Invalid noun type')
|
|
})
|
|
|
|
it('should provide suggestions for typos', async () => {
|
|
await expect(
|
|
brain.addNoun('Test', 'persan', {})
|
|
).rejects.toThrow(/Did you mean 'person'/)
|
|
})
|
|
})
|
|
|
|
describe('Type Validation Performance', () => {
|
|
it('should validate types quickly (O(1) with Set)', () => {
|
|
const start = performance.now()
|
|
|
|
// Validate 10000 types
|
|
for (let i = 0; i < 10000; i++) {
|
|
validateNounType(NounType.Person)
|
|
validateVerbType(VerbType.Contains)
|
|
}
|
|
|
|
const end = performance.now()
|
|
const duration = end - start
|
|
|
|
// Should complete in less than 50ms (very generous, usually < 5ms)
|
|
expect(duration).toBeLessThan(50)
|
|
})
|
|
})
|
|
}) |