scaffold-generation.spec.ts 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import { afterEach, describe, expect, it } from 'vitest'
  2. import { mkdtemp, rm, writeFile } from 'node:fs/promises'
  3. import { tmpdir } from 'node:os'
  4. import { join } from 'node:path'
  5. import {
  6. assertFixtureInventory,
  7. recordedSessionFixturePath,
  8. selectedSessionFixture,
  9. } from './scaffold.ts'
  10. const roots: string[] = []
  11. afterEach(async () => {
  12. for (const root of roots.splice(0)) await rm(root, { recursive: true, force: true })
  13. })
  14. describe('Web snapshot generation filenames', () => {
  15. it('selects the highest parent and child generations without counting retained inputs twice', async () => {
  16. const root = await mkdtemp(join(tmpdir(), 'dsh-web-fixture-generations-'))
  17. roots.push(root)
  18. for (const [name, version] of [
  19. ['session.jsonl', 0],
  20. ['session.v2.jsonl', 2],
  21. ['session.1.jsonl', 0],
  22. ['session.1.v1.jsonl', 1],
  23. ] as const) {
  24. await writeFile(join(root, name), `${JSON.stringify({
  25. type: 'session', version, id: '{{session:1}}', createdAt: 0, delegationDepth: 0,
  26. })}\n`)
  27. }
  28. await expect(selectedSessionFixture(join(root, 'session.jsonl')))
  29. .resolves.toBe(join(root, 'session.v2.jsonl'))
  30. await expect(selectedSessionFixture(join(root, 'session.1.jsonl')))
  31. .resolves.toBe(join(root, 'session.1.v1.jsonl'))
  32. await expect(selectedSessionFixture(join(root, 'replay.override.json')))
  33. .resolves.toBe(join(root, 'replay.override.json'))
  34. })
  35. it('leaves an absent override-only parent fixture unresolved', async () => {
  36. const root = await mkdtemp(join(tmpdir(), 'dsh-web-fixture-generations-'))
  37. roots.push(root)
  38. await expect(selectedSessionFixture(join(root, 'session.jsonl'), true))
  39. .resolves.toBe(join(root, 'session.jsonl'))
  40. await expect(selectedSessionFixture(join(root, 'session.jsonl')))
  41. .rejects.toThrow('missing parent session fixture')
  42. })
  43. it('records beside an older generation and preserves the parent or child role', () => {
  44. const fixtures = join('/', 'fixtures')
  45. expect(recordedSessionFixturePath(join(fixtures, 'session.jsonl'), 1))
  46. .toBe(join(fixtures, 'session.v1.jsonl'))
  47. expect(recordedSessionFixturePath(join(fixtures, 'session.2.jsonl'), 3))
  48. .toBe(join(fixtures, 'session.2.v3.jsonl'))
  49. expect(recordedSessionFixturePath(join(fixtures, 'session.v1.jsonl'), 1))
  50. .toBe(join(fixtures, 'session.v1.jsonl'))
  51. expect(() => recordedSessionFixturePath(join(fixtures, 'notes.jsonl'), 1))
  52. .toThrow('invalid Session fixture path')
  53. })
  54. it('treats retained generations as one exact inventory role', async () => {
  55. const root = await mkdtemp(join(tmpdir(), 'dsh-web-fixture-inventory-'))
  56. roots.push(root)
  57. await writeFile(join(root, 'session.jsonl'), `${JSON.stringify({
  58. type: 'session', version: 0, id: '{{session:1}}', createdAt: 0, delegationDepth: 0,
  59. })}\n`)
  60. await writeFile(join(root, 'session.v1.jsonl'), `${JSON.stringify({
  61. type: 'session', version: 1, id: '{{session:1}}', createdAt: 0, delegationDepth: 0,
  62. })}\n`)
  63. await writeFile(join(root, 'ui.expected.md'), 'stable\n')
  64. await expect(assertFixtureInventory(root, ['session.jsonl', 'ui.expected.md']))
  65. .resolves.toBeUndefined()
  66. })
  67. })