rescope-vendor.spec.ts 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. /** Recorded npm evidence stays intact while authored files and exact edits remain checked. */
  2. import { describe, expect, it } from 'vitest'
  3. import { exactEditState, isRescopeExcluded } from './rescope-vendor.ts'
  4. const ANCHOR = '\n## Sync procedure'
  5. const INSERTED = `\n15. **rescope**: one log entry.\n${ANCHOR}`
  6. describe('rescope file selection', () => {
  7. it('preserves the recorded npm resolution', () => {
  8. expect(isRescopeExcluded('scripts/dependency-catalog/package-lock.json')).toBe(true)
  9. })
  10. it.each([
  11. 'scripts/dependency-catalog/package.json',
  12. 'scripts/dependency-catalog/source.ts',
  13. 'scripts/other/package-lock.json',
  14. 'packages/example/src/index.ts',
  15. 'packages/example/package.json',
  16. ])('keeps %s subject to upstream package-name checks', (file) => {
  17. expect(isRescopeExcluded(file)).toBe(false)
  18. })
  19. })
  20. describe('exactEditState', () => {
  21. it('classifies an insertion by its target form, so a duplicate is invalid', () => {
  22. expect(exactEditState(`log\n${ANCHOR}\n`, ANCHOR, INSERTED, 1)).toBe('pending')
  23. expect(exactEditState(`log${INSERTED}\n`, ANCHOR, INSERTED, 1)).toBe('applied')
  24. // The anchor survives an insertion, so counting the source form would have
  25. // called this pending and inserted the entry a second time.
  26. expect(exactEditState(`log${INSERTED}${INSERTED}\n`, ANCHOR, INSERTED, 1)).toBe('invalid')
  27. expect(exactEditState('log\n', ANCHOR, INSERTED, 1)).toBe('invalid')
  28. })
  29. it('classifies a deletion by its source form, and requires its remainder to survive', () => {
  30. const remainder = 'exclude:\n'
  31. const withEntries = 'exclude:\n - cordis@4\n'
  32. expect(exactEditState(withEntries, withEntries, remainder, 1)).toBe('pending')
  33. expect(exactEditState(remainder, withEntries, remainder, 1)).toBe('applied')
  34. // Upstream dropped the whole field: the source form is gone, but so is the
  35. // remainder, so this is a moved site rather than a completed deletion.
  36. expect(exactEditState('unrelated:\n', withEntries, remainder, 1)).toBe('invalid')
  37. })
  38. it('requires a replacement to leave no source form and the exact target count', () => {
  39. expect(exactEditState('a = 1\n', 'a = 1', 'b = 2', 1)).toBe('pending')
  40. expect(exactEditState('b = 2\n', 'a = 1', 'b = 2', 1)).toBe('applied')
  41. expect(exactEditState('b = 2\nb = 2\n', 'a = 1', 'b = 2', 1)).toBe('invalid')
  42. // A moved or partially applied site: neither state is complete.
  43. expect(exactEditState('a = 1\nb = 2\n', 'a = 1', 'b = 2', 1)).toBe('invalid')
  44. expect(exactEditState('x\n', 'a = 1', 'b = 2', 1)).toBe('invalid')
  45. })
  46. })