mirror of
https://github.com/renovatebot/renovate.git
synced 2026-10-31 01:37:24 +00:00
7436b80cda
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>
109 lines
2.9 KiB
TypeScript
109 lines
2.9 KiB
TypeScript
import { getChangedFiles, getRepoRoot } from './git.ts';
|
|
|
|
const mockGit = vi.hoisted(() => {
|
|
const obj = {
|
|
raw: vi.fn(),
|
|
revparse: vi.fn(),
|
|
diff: vi.fn(),
|
|
env: vi.fn(),
|
|
};
|
|
obj.env.mockReturnValue(obj);
|
|
return obj;
|
|
});
|
|
|
|
vi.mock('simple-git', () => ({
|
|
simpleGit: vi.fn(() => mockGit),
|
|
}));
|
|
|
|
beforeEach(() => {
|
|
mockGit.env.mockReturnValue(mockGit);
|
|
});
|
|
|
|
it('returns changed files using merge-base with origin/main', async () => {
|
|
mockGit.raw.mockResolvedValueOnce('abc1234\n');
|
|
mockGit.diff.mockResolvedValueOnce('lib/foo.ts\nlib/bar.ts\n');
|
|
|
|
const result = await getChangedFiles();
|
|
|
|
expect(mockGit.raw).toHaveBeenCalledWith([
|
|
'merge-base',
|
|
'origin/main',
|
|
'HEAD',
|
|
]);
|
|
expect(mockGit.diff).toHaveBeenCalledWith([
|
|
'--name-only',
|
|
'--diff-filter=ACMR',
|
|
'abc1234',
|
|
]);
|
|
expect(result).toEqual(['lib/foo.ts', 'lib/bar.ts']);
|
|
});
|
|
|
|
it('falls back to upstream tracking branch when origin/main is not available', async () => {
|
|
mockGit.raw.mockRejectedValueOnce(new Error('no origin/main'));
|
|
mockGit.revparse.mockResolvedValueOnce('upstream/feature\n');
|
|
mockGit.diff.mockResolvedValueOnce('lib/foo.ts\n');
|
|
|
|
const result = await getChangedFiles();
|
|
|
|
expect(mockGit.revparse).toHaveBeenCalledWith([
|
|
'--abbrev-ref',
|
|
'--symbolic-full-name',
|
|
'@{u}',
|
|
]);
|
|
expect(mockGit.diff).toHaveBeenCalledWith([
|
|
'--name-only',
|
|
'--diff-filter=ACMR',
|
|
'upstream/feature',
|
|
]);
|
|
expect(result).toEqual(['lib/foo.ts']);
|
|
});
|
|
|
|
it('falls back to HEAD when neither origin/main nor upstream is available', async () => {
|
|
mockGit.raw.mockRejectedValueOnce(new Error('no origin/main'));
|
|
mockGit.revparse.mockRejectedValueOnce(new Error('no upstream'));
|
|
mockGit.diff.mockResolvedValueOnce('lib/foo.ts\n');
|
|
|
|
const result = await getChangedFiles();
|
|
|
|
expect(mockGit.diff).toHaveBeenCalledWith([
|
|
'--name-only',
|
|
'--diff-filter=ACMR',
|
|
'HEAD',
|
|
]);
|
|
expect(result).toEqual(['lib/foo.ts']);
|
|
});
|
|
|
|
it('returns empty array when no files changed', async () => {
|
|
mockGit.raw.mockResolvedValueOnce('abc1234\n');
|
|
mockGit.diff.mockResolvedValueOnce('');
|
|
|
|
const result = await getChangedFiles();
|
|
|
|
expect(result).toEqual([]);
|
|
});
|
|
|
|
it('getRepoRoot returns trimmed path when git reports a toplevel', async () => {
|
|
mockGit.revparse.mockResolvedValueOnce('/home/user/repo\n');
|
|
|
|
const result = await getRepoRoot('/home/user/repo/sub');
|
|
|
|
expect(mockGit.revparse).toHaveBeenCalledWith(['--show-toplevel']);
|
|
expect(result).toBe('/home/user/repo');
|
|
});
|
|
|
|
it('getRepoRoot returns null when not inside a git repo', async () => {
|
|
mockGit.revparse.mockRejectedValueOnce(new Error('not a git repo'));
|
|
|
|
const result = await getRepoRoot('/tmp/not-a-repo');
|
|
|
|
expect(result).toBeNull();
|
|
});
|
|
|
|
it('getRepoRoot returns null when output is empty', async () => {
|
|
mockGit.revparse.mockResolvedValueOnce('');
|
|
|
|
const result = await getRepoRoot();
|
|
|
|
expect(result).toBeNull();
|
|
});
|