@idooel/runtime-context
Version:
Runtime data pool with namespaces, stackable contexts, subscriptions and optional persistence. Vue adapter included.
147 lines (114 loc) • 4.85 kB
text/typescript
import { describe, it, expect } from 'vitest'
import { Context } from '../../src/core/Context'
describe('Context', () => {
describe('Constructor', () => {
it('should create empty context without initial data', () => {
const context = new Context()
expect(context.id).toBeDefined()
expect(typeof context.id).toBe('string')
expect(context.store).toBeInstanceOf(Map)
expect(context.store.size).toBe(0)
})
it('should create context with initial data', () => {
const initialData = {
user: { name: 'John', age: 30 },
app: { theme: 'dark', language: 'en' }
}
const context = new Context(initialData)
expect(context.id).toBeDefined()
expect(context.store.size).toBe(2)
// Check user namespace (Context doesn't add prefix, DataPool does)
const userNs = context.store.get('user')
expect(userNs).toBeDefined()
expect(userNs!.get('name')).toBe('John')
expect(userNs!.get('age')).toBe(30)
// Check app namespace
const appNs = context.store.get('app')
expect(appNs).toBeDefined()
expect(appNs!.get('theme')).toBe('dark')
expect(appNs!.get('language')).toBe('en')
})
it('should handle empty initial data', () => {
const context = new Context({})
expect(context.store.size).toBe(0)
})
it('should handle null/undefined initial data', () => {
const context1 = new Context(null)
const context2 = new Context(undefined)
expect(context1.store.size).toBe(0)
expect(context2.store.size).toBe(0)
})
it('should ignore non-object initial data', () => {
const context1 = new Context('string' as any)
const context2 = new Context(123 as any)
const context3 = new Context(true as any)
// Currently Context treats any input as potential keys, so string creates namespaces
expect(context1.store.size).toBe(6) // 's', 't', 'r', 'i', 'n', 'g' keys
expect(context2.store.size).toBe(0) // No keys
expect(context3.store.size).toBe(0) // No keys
})
it('should handle nested objects in initial data', () => {
const initialData = {
config: {
database: { host: 'localhost', port: 5432 },
cache: { ttl: 3600, type: 'redis' }
}
}
const context = new Context(initialData)
const configNs = context.store.get('config')
expect(configNs).toBeDefined()
expect(configNs!.get('database')).toEqual({ host: 'localhost', port: 5432 })
expect(configNs!.get('cache')).toEqual({ ttl: 3600, type: 'redis' })
})
it('should generate unique IDs for each context', () => {
const context1 = new Context()
const context2 = new Context()
const context3 = new Context()
expect(context1.id).not.toBe(context2.id)
expect(context2.id).not.toBe(context3.id)
expect(context1.id).not.toBe(context3.id)
})
it('should generate IDs with expected format', () => {
const context = new Context()
expect(context.id).toMatch(/^ctx_[a-z0-9]+_[a-z0-9]+$/)
})
})
describe('Store Structure', () => {
it('should maintain namespace isolation', () => {
const initialData = {
user: { name: 'John' },
admin: { name: 'Admin' }
}
const context = new Context(initialData)
const userNs = context.store.get('user')
const adminNs = context.store.get('admin')
expect(userNs).not.toBe(adminNs)
expect(userNs!.get('name')).toBe('John')
expect(adminNs!.get('name')).toBe('Admin')
})
it('should preserve data references', () => {
const userData = { name: 'John', preferences: { theme: 'dark' } }
const initialData = { user: userData }
const context = new Context(initialData)
const userNs = context.store.get('user')
const storedData = userNs!.get('preferences')
expect(storedData).toBe(userData.preferences)
expect(storedData).toEqual({ theme: 'dark' })
})
it('should handle mixed valid and invalid namespace data', () => {
const initialData = {
valid: { key: 'value' },
invalid: 'string', // Should be ignored
alsoValid: { another: 'data' }
}
const context = new Context(initialData)
expect(context.store.size).toBe(3) // valid, invalid, alsoValid
const validNs = context.store.get('valid')
const invalidNs = context.store.get('invalid')
const alsoValidNs = context.store.get('alsoValid')
expect(validNs!.get('key')).toBe('value')
expect(alsoValidNs!.get('another')).toBe('data')
expect(invalidNs).toBeDefined() // Should create empty namespace
})
})
})