assembly-vitest.client.spec.ts 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. /** Native fixture cleanup remains active after assertion failure and without a started client. */
  2. import { afterAll, describe, expect } from 'vitest'
  3. import { ok } from '@deepseek-ai/dsh-remote-mock'
  4. import type { SessionId } from '@deepseek-ai/dsh-session/types'
  5. import { createClientTest, webApp, type TestClient } from '../src/assembly/index.ts'
  6. const test = createClientTest({ roster: webApp.closure(['@deepseek-ai/dsh-api-gateway']) })
  7. const clients: TestClient[] = []
  8. const expired: (() => Promise<TestClient>)[] = []
  9. afterAll(async () => {
  10. expect(clients).toHaveLength(2)
  11. for (const client of clients) {
  12. expect(client.ctx.get('loader')).toBeUndefined()
  13. expect(client.mock.log.streams('$events').map(stream => stream.state)).toEqual(['cancelled'])
  14. }
  15. for (const start of expired) {
  16. await expect(start()).rejects.toThrow('after its test fixture closed')
  17. }
  18. expect('__DSH_TRANSPORT__' in globalThis).toBe(false)
  19. })
  20. describe('createClientTest', () => {
  21. test('allows response configuration before boot and shares concurrent starts', async ({ mock, remote, start }) => {
  22. expired.push(start)
  23. expect(remote).toBe(mock.remote)
  24. remote.session.rename.mockResolvedValueOnce(ok({ title: 'test title', seq: 1 }))
  25. const first = start()
  26. const second = start()
  27. expect(second).toBe(first)
  28. const client = await first
  29. clients.push(client)
  30. expect(client.mock).toBe(mock)
  31. expect(mock.log.streams('$events')).toHaveLength(1)
  32. await expect(client.ctx.remote.session.rename({ sessionId: 's' as SessionId, title: 't' }))
  33. .resolves.toEqual(ok({ title: 'test title', seq: 1 }))
  34. expect(remote.session.rename).toHaveBeenCalledExactlyOnceWith({ sessionId: 's', title: 't' })
  35. })
  36. test.fails('disposes its client even when the test assertion fails', async ({ start }) => {
  37. expired.push(start)
  38. clients.push(await start())
  39. expect.fail('fixture cleanup negative control')
  40. })
  41. test('does not boot an unused start fixture', ({ mock, start }) => {
  42. expired.push(start)
  43. expect(mock.log.streams()).toEqual([])
  44. expect('__DSH_TRANSPORT__' in globalThis).toBe(false)
  45. })
  46. test('owns a fresh mock when only the mock fixture is requested', ({ mock }) => {
  47. expect(mock.log.calls()).toEqual([])
  48. expect(mock.log.streams()).toEqual([])
  49. expect(mock.endpoints()).not.toContain('session/rename')
  50. })
  51. })
  52. const missingConnection = createClientTest({ roster: webApp.pick(['@deepseek-ai/dsh-typert-registry']) })
  53. missingConnection('keeps a rejected startup with its caller and releases its globals', async ({ start }) => {
  54. expired.push(start)
  55. await expect(start()).rejects.toThrow('provides no `connection` service')
  56. expect('__DSH_TRANSPORT__' in globalThis).toBe(false)
  57. })