Files
deepseek-harness/packages/workspace/workspace/tests/invariant.spec.ts
imccyu f5506cf35f refactor(storage): rename dsh-domain to dsh-storage-domain
The bare 'domain' name was too generic for a published package. The
directory moves to packages/storage/storage-domain, the package becomes
@deepseek-ai/dsh-storage-domain, and the plugin/invariant names follow;
the ctx surface (ctx.storage.domain), the domain/changed event, and all
runtime behavior are unchanged. References, catalogs, graphs, and the
bilingual design note move together.
2026-07-25 11:08:04 +08:00

57 lines
2.0 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { Context } from 'cordis'
import InvariantService from '@deepseek-ai/dsh-invariants'
import type { DomainChanged } from '@deepseek-ai/dsh-storage-domain'
import * as WorkspaceInvariant from '../src/invariant.ts'
import { WorkspaceId } from '../src/index.ts'
/** Boot the invariant service plus the companion over a stubbed registry knowing exactly `ids`. */
async function setup(ids: string[]): Promise<Context> {
const ctx = new Context()
await ctx.plugin(InvariantService)
ctx.provide('workspace', {
get: (id: WorkspaceId) => (ids.includes(id) ? { id } : undefined),
})
await ctx.plugin(WorkspaceInvariant)
return ctx
}
type ChangeLocation = Partial<Pick<DomainChanged, 'domain' | 'table' | 'key'>>
const put = (overrides?: ChangeLocation): DomainChanged => ({
domain: 'workspace',
table: 'workspaces',
key: 'w1',
operation: 'put',
value: {},
...overrides,
})
const deleted = (): DomainChanged => ({
domain: 'workspace',
table: 'workspaces',
key: 'w1',
operation: 'deleted',
})
describe('workspace cache/table invariant', () => {
it('accepts a put whose record has a cached entity and ignores foreign events', async () => {
const ctx = await setup(['w1'])
expect(() => { ctx.emit('domain/changed', put()) }).not.toThrow()
// Other domains and other tables are out of scope, whatever their shape.
expect(() => { ctx.emit('domain/changed', put({ domain: 'other', key: 'missing' })) }).not.toThrow()
expect(() => { ctx.emit('domain/changed', put({ table: 'other', key: 'missing' })) }).not.toThrow()
})
it('fails a deleted operation — this phase exposes no delete entry point', async () => {
const ctx = await setup(['w1'])
expect(() => { ctx.emit('domain/changed', deleted()) })
.toThrow(/no delete entry point/)
})
it('fails a put whose record the registry cache does not hold', async () => {
const ctx = await setup([])
expect(() => { ctx.emit('domain/changed', put()) }).toThrow(/diverged/)
})
})