jest.mock('child_process', () => ({ execFileSync: jest.fn(), })); jest.mock('fs', () => ({ readFileSync: jest.fn(), writeFileSync: jest.fn(), })); jest.mock('path', () => ({ join: (...parts: string[]) => parts.join('/'), })); import { execFileSync } from 'child_process'; import fs from 'fs'; import { publishTestPackage } from '../../src/scripts/publish-test-package'; describe('publishTestPackage', () => { it('writes updated package.json and restores after publish', async () => { const readFileSync = fs.readFileSync as jest.Mock; const writeFileSync = fs.writeFileSync as jest.Mock; readFileSync.mockReturnValueOnce( JSON.stringify({ name: 'orig', version: '0.1.0' }), ); await publishTestPackage({ projectRoot: '/repo', version: '1.2.3', packageName: 'test-package', }); expect(writeFileSync).toHaveBeenNthCalledWith( 1, '/repo/package.json', JSON.stringify({ name: 'test-package', version: '1.2.3' }, null, 2), ); expect(execFileSync).toHaveBeenCalledWith( 'npm', ['publish', '--access', 'public'], expect.objectContaining({ cwd: '/repo', stdio: 'inherit' }), ); expect(writeFileSync).toHaveBeenNthCalledWith( 2, '/repo/package.json', JSON.stringify({ name: 'orig', version: '0.1.0' }), ); }); it('restores package.json when publish throws', async () => { const readFileSync = fs.readFileSync as jest.Mock; const writeFileSync = fs.writeFileSync as jest.Mock; readFileSync.mockReturnValueOnce(JSON.stringify({ name: 'orig' })); (execFileSync as jest.Mock).mockImplementationOnce(() => { throw new Error('publish failed'); }); await expect( publishTestPackage({ projectRoot: '/repo', version: '2.0.0' }), ).rejects.toThrow('publish failed'); expect(writeFileSync).toHaveBeenCalledWith( '/repo/package.json', JSON.stringify({ name: 'orig' }), ); }); });