workspace.spec.ts 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. import { mkdtemp, mkdir, rm, symlink, writeFile } from 'node:fs/promises'
  2. import { tmpdir } from 'node:os'
  3. import { join } from 'node:path'
  4. import { afterEach, describe, expect, it } from 'vitest'
  5. import {
  6. captureExpectedWorkspaceSnapshot,
  7. captureWorkspaceSnapshot,
  8. EMPTY_WORKSPACE_MARKER,
  9. } from '../src/workspace.ts'
  10. describe('workspace snapshots', () => {
  11. const roots: string[] = []
  12. async function root(): Promise<string> {
  13. const value = await mkdtemp(join(tmpdir(), 'dsh-workspace-snapshot-'))
  14. roots.push(value)
  15. return value
  16. }
  17. afterEach(async () => {
  18. await Promise.all(roots.splice(0).map(path => rm(path, { recursive: true, force: true })))
  19. })
  20. it('captures readable text, binary bytes, links, and empty directories in path order', async () => {
  21. const directory = await root()
  22. await writeFile(join(directory, 'a.txt'), 'hello\n')
  23. await writeFile(join(directory, 'b.bin'), Buffer.from([0xff, 0x01]))
  24. await mkdir(join(directory, 'empty'))
  25. await symlink('a.txt', join(directory, 'link'))
  26. expect(await captureWorkspaceSnapshot(directory)).toEqual([
  27. { path: 'a.txt', kind: 'text', content: 'hello\n' },
  28. { path: 'b.bin', kind: 'binary', base64: '/wE=' },
  29. { path: 'empty', kind: 'empty-directory' },
  30. { path: 'link', kind: 'symlink', target: 'a.txt' },
  31. ])
  32. })
  33. it('keeps generic marker files but omits declared runtime roots and the expected-empty marker', async () => {
  34. const directory = await root()
  35. await mkdir(join(directory, '.dsh'))
  36. await writeFile(join(directory, '.dsh', 'runtime.json'), '{}')
  37. await writeFile(join(directory, EMPTY_WORKSPACE_MARKER), '')
  38. await writeFile(join(directory, 'visible.txt'), 'visible')
  39. expect(await captureWorkspaceSnapshot(directory, { ignoredRootEntries: ['.dsh'] })).toEqual([
  40. { path: '.empty', kind: 'text', content: '' },
  41. { path: 'visible.txt', kind: 'text', content: 'visible' },
  42. ])
  43. expect(await captureExpectedWorkspaceSnapshot(directory)).toEqual([
  44. { path: '.dsh/runtime.json', kind: 'text', content: '{}' },
  45. { path: 'visible.txt', kind: 'text', content: 'visible' },
  46. ])
  47. })
  48. it('treats NUL-bearing UTF-8 as binary workspace state', async () => {
  49. const directory = await root()
  50. await writeFile(join(directory, 'nul.bin'), Buffer.from([0x61, 0x00, 0x62]))
  51. expect(await captureWorkspaceSnapshot(directory)).toEqual([
  52. { path: 'nul.bin', kind: 'binary', base64: 'YQBi' },
  53. ])
  54. })
  55. })