Files
renovate/lib/modules/manager/bun/artifacts.spec.ts
Sebastian Poxhofer 05e1271376 test: use expect().resolves instead of awaiting inside expect (#45672)
Enables the vitest/prefer-expect-resolves oxlint rule and applies its
autofix across the spec suite.
2026-09-04 10:40:46 +00:00

405 lines
13 KiB
TypeScript

import { fs } from '~test/util.ts';
import { GlobalConfig } from '../../../config/global.ts';
import type {
InternalGlobalConfigOptions,
RepoGlobalConfig,
} from '../../../config/types.ts';
import { TEMPORARY_ERROR } from '../../../constants/error-messages.ts';
import { ExecError } from '../../../util/exec/exec-error.ts';
import { exec as _exec } from '../../../util/exec/index.ts';
import type { UpdateArtifact } from '../types.ts';
import { updateArtifacts } from './artifacts.ts';
vi.mock('../../../util/exec/index.ts');
vi.mock('../../../util/fs/index.ts');
const exec = vi.mocked(_exec);
const globalConfig: RepoGlobalConfig & InternalGlobalConfigOptions = {
localDir: '',
binarySource: 'global',
};
describe('modules/manager/bun/artifacts', () => {
describe('updateArtifacts()', () => {
let updateArtifact: UpdateArtifact;
beforeEach(() => {
GlobalConfig.set(globalConfig);
updateArtifact = {
config: {},
newPackageFileContent: '',
packageFileName: '',
updatedDeps: [],
};
});
it('skips if no updatedDeps and no lockFileMaintenance', async () => {
await expect(updateArtifacts(updateArtifact)).resolves.toBeNull();
});
it('skips if no lock file in config', async () => {
updateArtifact.updatedDeps = [{}];
await expect(updateArtifacts(updateArtifact)).resolves.toBeNull();
});
describe('when using .lockb lockfile format', () => {
it('skips if cannot read lock file', async () => {
updateArtifact.updatedDeps = [
{ manager: 'bun', lockFiles: ['bun.lockb'] },
];
await expect(updateArtifacts(updateArtifact)).resolves.toBeNull();
});
it('returns null if lock content unchanged', async () => {
updateArtifact.updatedDeps = [
{ manager: 'bun', lockFiles: ['bun.lockb'] },
];
const oldLock = Buffer.from('old');
fs.readLocalFile.mockResolvedValueOnce(oldLock as never);
fs.readLocalFile.mockResolvedValueOnce(oldLock as never);
await expect(updateArtifacts(updateArtifact)).resolves.toBeNull();
});
it('returns updated lock content', async () => {
updateArtifact.updatedDeps = [
{ manager: 'bun', lockFiles: ['bun.lockb'] },
];
const oldLock = Buffer.from('old');
fs.readLocalFile.mockResolvedValueOnce(oldLock as never);
// npmrc
fs.readLocalFile.mockResolvedValueOnce('# dummy');
const newLock = Buffer.from('new');
fs.readLocalFile.mockResolvedValueOnce(newLock as never);
await expect(updateArtifacts(updateArtifact)).resolves.toEqual([
{
file: {
path: 'bun.lockb',
type: 'addition',
contents: newLock,
},
},
]);
});
it('updates lock file when workspace package is updated', async () => {
updateArtifact.packageFileName = 'packages/workspace-a/package.json';
updateArtifact.updatedDeps = [
{ manager: 'bun', lockFiles: ['bun.lockb'] },
];
const oldLock = Buffer.from('old');
fs.readLocalFile.mockResolvedValueOnce(oldLock as never);
fs.readLocalFile.mockResolvedValueOnce('# dummy');
const newLock = Buffer.from('new');
fs.readLocalFile.mockResolvedValueOnce(newLock as never);
const result = await updateArtifacts(updateArtifact);
expect(result).toEqual([
{
file: {
path: 'bun.lockb',
type: 'addition',
contents: newLock,
},
},
]);
expect(exec).toHaveBeenCalledWith('bun install --ignore-scripts', {
cwdFile: 'bun.lockb',
docker: {},
toolConstraints: [
{
toolName: 'bun',
},
],
});
});
it('supports lockFileMaintenance', async () => {
updateArtifact.updatedDeps = [
{ manager: 'bun', lockFiles: ['bun.lockb'] },
];
updateArtifact.config.isLockFileMaintenance = true;
const oldLock = Buffer.from('old');
fs.readLocalFile.mockResolvedValueOnce(oldLock as never);
// npmrc
fs.readLocalFile.mockResolvedValueOnce('# dummy');
const newLock = Buffer.from('new');
fs.readLocalFile.mockResolvedValueOnce(newLock as never);
await expect(updateArtifacts(updateArtifact)).resolves.toEqual([
{
file: {
path: 'bun.lockb',
type: 'addition',
contents: newLock,
},
},
]);
});
it('supports lockFileMaintenance (without updated deps)', async () => {
updateArtifact.config.lockFiles = ['bun.lockb'];
updateArtifact.config.isLockFileMaintenance = true;
const oldLock = Buffer.from('old');
fs.readLocalFile.mockResolvedValueOnce(oldLock as never);
// npmrc
fs.readLocalFile.mockResolvedValueOnce('# dummy');
const newLock = Buffer.from('new');
fs.readLocalFile.mockResolvedValueOnce(newLock as never);
await expect(updateArtifacts(updateArtifact)).resolves.toEqual([
{
file: {
path: 'bun.lockb',
type: 'addition',
contents: newLock,
},
},
]);
});
it('handles temporary error', async () => {
const execError = new ExecError(TEMPORARY_ERROR, {
cmd: '',
stdout: '',
stderr: '',
options: {},
});
updateArtifact.updatedDeps = [
{ manager: 'bun', lockFiles: ['bun.lockb'] },
];
const oldLock = Buffer.from('old');
fs.readLocalFile.mockResolvedValueOnce(oldLock as never);
exec.mockRejectedValueOnce(execError);
await expect(updateArtifacts(updateArtifact)).rejects.toThrow(
TEMPORARY_ERROR,
);
});
it('handles full error', async () => {
const execError = new ExecError('nope', {
cmd: '',
stdout: '',
stderr: '',
options: {},
});
updateArtifact.updatedDeps = [
{ manager: 'bun', lockFiles: ['bun.lockb'] },
];
const oldLock = Buffer.from('old');
fs.readLocalFile.mockResolvedValueOnce(oldLock as never);
exec.mockRejectedValueOnce(execError);
await expect(updateArtifacts(updateArtifact)).resolves.toEqual([
{ artifactError: { fileName: 'bun.lockb', stderr: 'nope' } },
]);
});
});
describe('when using .lock lockfile format', () => {
it('skips if cannot read lock file', async () => {
updateArtifact.updatedDeps = [
{ manager: 'bun', lockFiles: ['bun.lock'] },
];
await expect(updateArtifacts(updateArtifact)).resolves.toBeNull();
});
it('returns null if lock content unchanged', async () => {
updateArtifact.updatedDeps = [
{ manager: 'bun', lockFiles: ['bun.lock'] },
];
const oldLock = Buffer.from('old');
fs.readLocalFile.mockResolvedValueOnce(oldLock as never);
fs.readLocalFile.mockResolvedValueOnce(oldLock as never);
await expect(updateArtifacts(updateArtifact)).resolves.toBeNull();
});
it('returns updated lock content', async () => {
updateArtifact.updatedDeps = [
{ manager: 'bun', lockFiles: ['bun.lock'] },
];
const oldLock = Buffer.from('old');
fs.readLocalFile.mockResolvedValueOnce(oldLock as never);
// npmrc
fs.readLocalFile.mockResolvedValueOnce('# dummy');
const newLock = Buffer.from('new');
fs.readLocalFile.mockResolvedValueOnce(newLock as never);
await expect(updateArtifacts(updateArtifact)).resolves.toEqual([
{
file: {
path: 'bun.lock',
type: 'addition',
contents: newLock,
},
},
]);
});
it('supports lockFileMaintenance', async () => {
updateArtifact.updatedDeps = [
{ manager: 'bun', lockFiles: ['bun.lock'] },
];
updateArtifact.config.isLockFileMaintenance = true;
const oldLock = Buffer.from('old');
fs.readLocalFile.mockResolvedValueOnce(oldLock as never);
// npmrc
fs.readLocalFile.mockResolvedValueOnce('# dummy');
const newLock = Buffer.from('new');
fs.readLocalFile.mockResolvedValueOnce(newLock as never);
await expect(updateArtifacts(updateArtifact)).resolves.toEqual([
{
file: {
path: 'bun.lock',
type: 'addition',
contents: newLock,
},
},
]);
});
it('supports lockFileMaintenance (without updated deps)', async () => {
updateArtifact.config.lockFiles = ['bun.lock'];
updateArtifact.config.isLockFileMaintenance = true;
const oldLock = Buffer.from('old');
fs.readLocalFile.mockResolvedValueOnce(oldLock as never);
// npmrc
fs.readLocalFile.mockResolvedValueOnce('# dummy');
const newLock = Buffer.from('new');
fs.readLocalFile.mockResolvedValueOnce(newLock as never);
await expect(updateArtifacts(updateArtifact)).resolves.toEqual([
{
file: {
path: 'bun.lock',
type: 'addition',
contents: newLock,
},
},
]);
});
it('handles temporary error', async () => {
const execError = new ExecError(TEMPORARY_ERROR, {
cmd: '',
stdout: '',
stderr: '',
options: {},
});
updateArtifact.updatedDeps = [
{ manager: 'bun', lockFiles: ['bun.lock'] },
];
const oldLock = Buffer.from('old');
fs.readLocalFile.mockResolvedValueOnce(oldLock as never);
exec.mockRejectedValueOnce(execError);
await expect(updateArtifacts(updateArtifact)).rejects.toThrow(
TEMPORARY_ERROR,
);
});
it('handles full error', async () => {
const execError = new ExecError('nope', {
cmd: '',
stdout: '',
stderr: '',
options: {},
});
updateArtifact.updatedDeps = [
{ manager: 'bun', lockFiles: ['bun.lock'] },
];
const oldLock = Buffer.from('old');
fs.readLocalFile.mockResolvedValueOnce(oldLock as never);
exec.mockRejectedValueOnce(execError);
await expect(updateArtifacts(updateArtifact)).resolves.toEqual([
{ artifactError: { fileName: 'bun.lock', stderr: 'nope' } },
]);
});
});
});
describe('bun command execution', () => {
it('check install options with configs', async () => {
const lockfileFormats = ['bun.lockb', 'bun.lock'];
const testCases = [
{
allowScripts: undefined,
ignoreScripts: undefined,
expectedCmd: 'bun install --ignore-scripts',
},
{
allowScripts: false,
ignoreScripts: undefined,
expectedCmd: 'bun install --ignore-scripts',
},
{
allowScripts: true,
ignoreScripts: undefined,
expectedCmd: 'bun install',
},
{
allowScripts: undefined,
ignoreScripts: true,
expectedCmd: 'bun install --ignore-scripts',
},
{
allowScripts: undefined,
ignoreScripts: false,
expectedCmd: 'bun install --ignore-scripts',
},
{
allowScripts: false,
ignoreScripts: true,
expectedCmd: 'bun install --ignore-scripts',
},
{
allowScripts: false,
ignoreScripts: false,
expectedCmd: 'bun install --ignore-scripts',
},
{
allowScripts: true,
ignoreScripts: true,
expectedCmd: 'bun install --ignore-scripts',
},
{
allowScripts: true,
ignoreScripts: false,
expectedCmd: 'bun install',
},
];
for (const lockFile of lockfileFormats) {
for (const testCase of testCases) {
GlobalConfig.set({
...globalConfig,
allowScripts: testCase.allowScripts,
});
const updateArtifact: UpdateArtifact = {
config: { ignoreScripts: testCase.ignoreScripts },
newPackageFileContent: '',
packageFileName: '',
updatedDeps: [{ manager: 'bun', lockFiles: [lockFile] }],
};
const oldLock = Buffer.from('old');
fs.readLocalFile.mockResolvedValueOnce(oldLock as never);
const newLock = Buffer.from('new');
fs.readLocalFile.mockResolvedValueOnce(newLock as never);
await updateArtifacts(updateArtifact);
expect(exec).toHaveBeenCalledExactlyOnceWith(testCase.expectedCmd, {
cwdFile: lockFile,
docker: {},
toolConstraints: [
{
toolName: 'bun',
},
],
});
exec.mockClear();
GlobalConfig.reset();
}
}
});
});
});