dynamic-keys.client.spec.ts 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. // Dynamic-key escape hatches and untouched-key behavior of the terminal core.
  2. import { describe, expect, it } from 'vitest'
  3. import type { SlotComponent } from '@deepseek-ai/dsh-client-ui-slots'
  4. import { SlotCore } from '@deepseek-ai/dsh-client-ui-slots'
  5. declare module '@deepseek-ai/dsh-client-ui-slots' {
  6. interface SlotMap {
  7. 'dynamic.a': { kind: 'single'; scope: 'root' }
  8. 'dynamic.b': { kind: 'single'; scope: 'root' }
  9. 'surface.injected': { kind: 'single'; scope: 'root'; inject: { token: string } }
  10. }
  11. }
  12. const Comp: SlotComponent<object> = () => null
  13. describe('dynamic-key escape hatch', () => {
  14. it('specDynamic reads wide-typed specs for string keys; undefined while undeclared', () => {
  15. const core = new SlotCore()
  16. expect(core.specDynamic('dynamic.a')).toBeUndefined()
  17. core.register({ name: 'root', children: { 'dynamic.a': { kind: 'single', scope: 'root' } } }, Comp as never)
  18. expect(core.specDynamic('dynamic.a')).toEqual({ kind: 'single', scope: 'root' })
  19. expect(core.specDynamic('never.declared')).toBeUndefined()
  20. })
  21. it('spec() narrows by SlotMap key', () => {
  22. const core = new SlotCore()
  23. core.register({ name: 'root', children: { 'dynamic.a': { kind: 'single', scope: 'root' } } }, Comp as never)
  24. expect(core.spec('dynamic.a')).toEqual({ kind: 'single', scope: 'root' })
  25. expect(core.spec('dynamic.b')).toBeUndefined()
  26. })
  27. it('records the parent-declared Slot inject on the runtime spec', () => {
  28. const core = new SlotCore()
  29. const inject = { token: 'shared' }
  30. core.register({
  31. name: 'root',
  32. children: { 'surface.injected': { kind: 'single', scope: 'root', inject } },
  33. }, Comp as never)
  34. expect(core.spec('surface.injected')?.inject).toBe(inject)
  35. })
  36. it('entries/getVersion on an untouched key return the frozen empty array and 0', () => {
  37. const core = new SlotCore()
  38. expect(core.entries('dynamic.b')).toHaveLength(0)
  39. expect(core.entries('dynamic.b')).toBe(core.entries('dynamic.b'))
  40. expect(core.getVersion('dynamic.b')).toBe(0)
  41. })
  42. it('isLive is false for entries the core never held', () => {
  43. const core = new SlotCore()
  44. expect(core.isLive({ component: Comp, options: {} })).toBe(false)
  45. })
  46. })