Files
renovate/lib/util/exec/hermit.spec.ts
T
Sebastian Poxhofer 7436b80cda test(linter): add renovate/no-redundant-mock-reset rule (#44557)
ci(linter): add renovate/no-redundant-mock-reset rule

Vitest sets mockReset: true globally in vitest.config.mts, which resets
all mocks before each test. This makes vi.resetAllMocks() /
vi.clearAllMocks() and per-mock .mockReset() / .mockClear() calls inside
beforeEach/afterEach hooks redundant. Add a custom oxlint rule (enabled
for **/*.spec.ts and test/**) flagging such calls, and remove the 40
redundant calls it found. restoreAllMocks/mockRestore are not flagged
because restoreMocks is not enabled globally.

Two sites keep an inline disable with a reason: nested beforeEach hooks
in filter-checks.spec.ts and onboarding/pr/index.spec.ts intentionally
call mockReset() to discard once-values queued by an outer beforeEach.

Requested by maintainer review feedback (review comment 3052324877).

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 11:26:20 +00:00

88 lines
2.8 KiB
TypeScript

import { codeBlock } from 'common-tags';
import { findUp as _findUp } from 'find-up';
import upath from 'upath';
import { mockExecAll } from '~test/exec-util.ts';
import { partial } from '~test/util.ts';
import { GlobalConfig } from '../../config/global.ts';
import { findHermitCwd, getHermitEnvs, isHermit } from './hermit.ts';
import type { RawExecOptions } from './types.ts';
vi.mock('find-up');
const findUp = vi.mocked(_findUp);
const localDir = '/tmp/renovate/repository/project-a';
describe('util/exec/hermit', () => {
describe('isHermit', () => {
it('should return true when binarySource is hermit', () => {
GlobalConfig.set({ binarySource: 'docker' });
expect(isHermit()).toBeFalse();
GlobalConfig.set({ binarySource: 'hermit' });
expect(isHermit()).toBeTruthy();
});
});
describe('findHermitCwd', () => {
beforeEach(() => {
GlobalConfig.set({ localDir });
});
it.each`
dir | hermitLocation | expected
${'nested/other/directory'} | ${'nested/bin/hermit'} | ${'nested/bin'}
${'nested'} | ${'nested/bin/hermit'} | ${'nested/bin'}
${'other/directory'} | ${'bin/hermit'} | ${'bin'}
${''} | ${'bin/hermit'} | ${'bin'}
`(
'("$dir") === $expected (hermit: $hermitLocation)',
async ({ dir, hermitLocation, expected }) => {
const cwd = upath.join(localDir, dir);
findUp.mockResolvedValueOnce(upath.join(localDir, hermitLocation));
expect(await findHermitCwd(cwd)).toBe(upath.join(localDir, expected));
expect(findUp.mock.calls[0][1]?.cwd).toBe(cwd);
},
);
it('should throw error when hermit cwd is not found', async () => {
const err = new Error('hermit not found for other/directory');
await expect(findHermitCwd('other/directory')).rejects.toThrow(err);
});
});
describe('getHermitEnvs', () => {
beforeEach(() => {
GlobalConfig.set({ localDir });
});
it('should return hermit environment variables when hermit env returns successfully', async () => {
findUp.mockResolvedValueOnce(upath.join(localDir, 'bin/hermit'));
mockExecAll({
stdout: codeBlock`
GOBIN=/usr/src/app/repository-a/.hermit/go/bin
PATH=/usr/src/app/repository-a/bin
`,
stderr: '',
});
const relativeCwd = 'nested/other/bin';
const fullCwd = upath.join(localDir, relativeCwd);
const resp = await getHermitEnvs(
partial<RawExecOptions>({
cwd: fullCwd,
}),
);
expect(findUp.mock.calls[0][1]?.cwd).toEqual(fullCwd);
expect(resp).toStrictEqual({
GOBIN: '/usr/src/app/repository-a/.hermit/go/bin',
PATH: '/usr/src/app/repository-a/bin',
});
});
});
});