| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- import { describe, expect, it } from 'vitest'
- import { Context } from 'cordis'
- import { CodeRuntime } from '@deepseek-ai/dsh-code-runtime'
- import type { CodeRunRequest, CodeRunResult } from '@deepseek-ai/dsh-code-runtime'
- /**
- * Minimal concrete runtime: records requests, "executes" by invoking every
- * binding once in declaration order, and lets tests script the outcome. The
- * seam package ships no implementation, so the contract is exercised through
- * the smallest subclass that honors it.
- */
- class StubRuntime extends CodeRuntime {
- readonly language = 'typescript'
- readonly isolation = 'in-process-stub'
- requests: CodeRunRequest[] = []
- nextResult: CodeRunResult = { logs: [] }
- async run(request: CodeRunRequest): Promise<CodeRunResult> {
- this.requests.push(request)
- if (request.signal?.aborted) {
- return { logs: [], error: { kind: 'abort', message: String(request.signal.reason) } }
- }
- for (const namespace of request.bindings) {
- for (const fn of Object.values(namespace.functions)) {
- await fn({ from: 'stub' })
- }
- }
- return this.nextResult
- }
- }
- async function setup() {
- const ctx = new Context()
- await ctx.plugin(StubRuntime)
- const runtime = ctx.codeRuntime as StubRuntime
- return { ctx, runtime }
- }
- describe('CodeRuntime service seam', () => {
- it('registers as ctx.codeRuntime and serves the abstract API', async () => {
- const { runtime } = await setup()
- expect(runtime.language).toBe('typescript')
- expect(runtime.isolation).toBe('in-process-stub')
- const calls: unknown[] = []
- const result = await runtime.run({
- program: 'return 1',
- bindings: [{ global: 'tools', functions: { probe: async args => void calls.push(args) } }],
- })
- expect(result).toEqual({ logs: [] })
- expect(calls).toEqual([{ from: 'stub' }])
- expect(runtime.requests).toHaveLength(1)
- })
- it('reports a failed run as an error field on a resolved result, never a rejection', async () => {
- const { runtime } = await setup()
- runtime.nextResult = {
- logs: ['boom'],
- error: { kind: 'exception', message: 'boom' },
- }
- const result = await runtime.run({ program: 'throw new Error("boom")', bindings: [] })
- expect(result.error).toEqual({ kind: 'exception', message: 'boom' })
- expect(result.value).toBeUndefined()
- })
- it('reports a pre-aborted signal as an abort failure', async () => {
- const { runtime } = await setup()
- const controller = new AbortController()
- controller.abort('cancelled')
- const result = await runtime.run({ program: 'return 1', bindings: [], signal: controller.signal })
- expect(result.error).toEqual({ kind: 'abort', message: 'cancelled' })
- })
- it('is removed from the context when the providing fiber disposes (HMR safety)', async () => {
- const ctx = new Context()
- const fiber = await ctx.plugin(StubRuntime)
- expect(ctx.get('codeRuntime')).toBeInstanceOf(StubRuntime)
- await fiber.dispose()
- expect(ctx.get('codeRuntime')).toBeUndefined()
- })
- it('rejects a second implementation in the same context (duplicate service)', async () => {
- const { ctx } = await setup()
- await expect(ctx.plugin(StubRuntime)).rejects.toThrow(/registered/)
- })
- it.each([
- [{ language: 'typescript', isolation: 'worker' }, /must expose method "run"/],
- [{ language: 'TypeScript', isolation: 'worker', run() {} }, /must be lowercase identifiers/],
- ])('rejects an invalid runtime implementation through the package invariant', async (value, message) => {
- const ctx = new Context()
- const invalidRuntime = {
- name: 'invalid-code-runtime',
- apply(child: Context) {
- child.provide('codeRuntime', value as unknown as CodeRuntime)
- },
- }
- await expect(ctx.plugin(invalidRuntime)).rejects.toThrow(message)
- })
- })
|