Files
renovate/lib/modules/manager/npm/utils.spec.ts
Sebastian Poxhofer f4fa861457 test(npm): replace file snapshots with explicit assertions (#45658)
* test(npm): replace file snapshots with explicit assertions

* test(npm): replace inline snapshots with explicit assertions
2026-09-04 06:36:41 +00:00

129 lines
3.8 KiB
TypeScript

vi.mock('fs-extra', async () =>
(
await vi.importActual<typeof import('~test/fixtures.ts')>(
'~test/fixtures.ts',
)
).fsExtra(),
);
import { codeBlock } from 'common-tags';
import { Fixtures } from '~test/fixtures.ts';
import { GlobalConfig } from '../../../config/global.ts';
import type { LockFile } from './types.ts';
import { composeLockFile, loadPackageJson, parseLockFile } from './utils.ts';
describe('modules/manager/npm/utils', () => {
describe('parseLockFile', () => {
it('parses lockfile string into an object', () => {
const lockFile = Fixtures.get('lockfile-parsing/package-lock.json');
const parseLockFileResult = parseLockFile(lockFile);
expect(parseLockFileResult).toStrictEqual({
detectedIndent: ' ',
lockFileParsed: {
lockfileVersion: 2,
name: 'lockfile-parsing',
packages: {
'': {
license: 'ISC',
name: 'lockfile-parsing',
version: '1.0.0',
},
},
requires: true,
version: '1.0.0',
},
});
});
it('can deal with invalid lockfiles', () => {
const lockFile = '';
const parseLockFileResult = parseLockFile(lockFile);
expect(parseLockFileResult).toStrictEqual({
detectedIndent: ' ',
lockFileParsed: undefined,
});
});
});
describe('composeLockFile', () => {
it('composes lockfile string out of an object', () => {
const lockFile: LockFile = {
lockfileVersion: 2,
name: 'lockfile-parsing',
packages: {
'': {
license: 'ISC',
name: 'lockfile-parsing',
version: '1.0.0',
},
},
requires: true,
version: '1.0.0',
};
const lockFileComposed = composeLockFile(lockFile, ' ');
expect(lockFileComposed).toBe(
`${codeBlock`
{
"lockfileVersion": 2,
"name": "lockfile-parsing",
"packages": {
"": {
"license": "ISC",
"name": "lockfile-parsing",
"version": "1.0.0"
}
},
"requires": true,
"version": "1.0.0"
}
`}\n`,
);
});
it('adds trailing newline to match npms behavior and avoid diffs', () => {
const lockFile = Fixtures.get('lockfile-parsing/package-lock.json');
const { detectedIndent, lockFileParsed } = parseLockFile(lockFile);
// TODO #22198
const lockFileComposed = composeLockFile(lockFileParsed!, detectedIndent);
expect(lockFileComposed).toBe(lockFile);
});
});
describe('loadPackageJson', () => {
beforeEach(() => {
Fixtures.reset();
GlobalConfig.set({ localDir: '/', cacheDir: '/tmp/cache' });
});
it('loads and parses package.json correctly', async () => {
Fixtures.mock({
'/repo/package.json': JSON.stringify({
dependencies: { leftpad: '1.0.0' },
engines: { node: '>=16.0.0' },
volta: { yarn: '1.22.19' },
packageManager: 'npm@8.5.1',
}),
});
const pkg = await loadPackageJson('/repo');
expect(pkg).toStrictEqual({
dependencies: { leftpad: '1.0.0' },
engines: { node: '>=16.0.0' },
volta: { yarn: '1.22.19' },
packageManager: { name: 'npm', version: '8.5.1' },
});
});
it('returns empty object when package.json is missing', async () => {
const pkg = await loadPackageJson('/missing');
expect(pkg).toStrictEqual({});
});
it('returns empty object when package.json is invalid', async () => {
Fixtures.mock({ '/bad/package.json': '{ invalid json' });
const pkg = await loadPackageJson('/bad');
expect(pkg).toStrictEqual({});
});
});
});