mirror of
https://github.com/renovatebot/renovate.git
synced 2026-10-31 17:51:49 +00:00
05e1271376
Enables the vitest/prefer-expect-resolves oxlint rule and applies its autofix across the spec suite.
522 lines
16 KiB
TypeScript
522 lines
16 KiB
TypeScript
import { codeBlock } from 'common-tags';
|
|
import { findPackages } from 'find-packages';
|
|
import { fs } from '../../../../test/util.ts';
|
|
import { GlobalConfig } from '../../../config/global.ts';
|
|
import * as compat from './compat.ts';
|
|
import {
|
|
extractAllPackageFiles,
|
|
getLockFiles,
|
|
processDenoExtract,
|
|
processImportMap,
|
|
} from './extract.ts';
|
|
|
|
vi.mock('../../../util/fs/index.ts');
|
|
vi.mock('./compat.ts');
|
|
// used in detectNodeCompatWorkspaces()
|
|
vi.mock('find-packages', () => ({
|
|
findPackages: vi.fn(),
|
|
}));
|
|
|
|
describe('modules/manager/deno/extract', () => {
|
|
describe('getLockFiles()', () => {
|
|
it('found lock file', async () => {
|
|
fs.getSiblingFileName.mockReturnValueOnce('deno.lock');
|
|
fs.localPathIsFile.mockResolvedValue(true);
|
|
const result = await getLockFiles('deno.lock', 'deno.json');
|
|
expect(result).toEqual(['deno.lock']);
|
|
});
|
|
|
|
it('not found lock file', async () => {
|
|
fs.getSiblingFileName.mockReturnValueOnce('package-lock.json');
|
|
const result = await getLockFiles(false, 'deno.json');
|
|
expect(result).toEqual([]);
|
|
});
|
|
});
|
|
|
|
describe('processImportMap()', () => {
|
|
it('importMap', async () => {
|
|
fs.readLocalFile.mockResolvedValueOnce(
|
|
JSON.stringify({
|
|
imports: {
|
|
dep1: 'jsr:@scope/name@3.0.0',
|
|
},
|
|
scopes: {
|
|
'https://deno.land/x/name/mod.ts': {
|
|
'@scope/name': 'jsr:@scope/name@0.2.0',
|
|
},
|
|
},
|
|
}),
|
|
);
|
|
const result = await processImportMap('import_map.json', 'deno.json', [
|
|
'deno.lock',
|
|
]);
|
|
|
|
expect(result).toStrictEqual({
|
|
deps: [
|
|
{
|
|
currentRawValue: 'jsr:@scope/name@3.0.0',
|
|
currentValue: '3.0.0',
|
|
datasource: 'jsr',
|
|
depName: '@scope/name',
|
|
depType: 'imports',
|
|
versioning: 'deno',
|
|
},
|
|
{
|
|
currentRawValue: 'jsr:@scope/name@0.2.0',
|
|
currentValue: '0.2.0',
|
|
datasource: 'jsr',
|
|
depName: '@scope/name',
|
|
depType: 'scopes',
|
|
versioning: 'deno',
|
|
},
|
|
],
|
|
lockFiles: ['deno.lock'],
|
|
managerData: {
|
|
importMapReferrer: 'deno.json',
|
|
},
|
|
packageFile: 'import_map.json',
|
|
});
|
|
});
|
|
|
|
it('remote importMap', async () => {
|
|
const result = await processImportMap(
|
|
'https://deno.land/x/import_map.json',
|
|
'demo.json',
|
|
[],
|
|
);
|
|
|
|
expect(result).toBeNull();
|
|
});
|
|
|
|
it('importMap path specified but not exists', async () => {
|
|
fs.readLocalFile.mockResolvedValueOnce(null);
|
|
const result = await processImportMap('import_map.json', 'demo.json', []);
|
|
|
|
expect(result).toBeNull();
|
|
});
|
|
|
|
it('invalid importMap file', async () => {
|
|
fs.readLocalFile.mockResolvedValueOnce('invalid');
|
|
const result = await processImportMap('import_map.json', 'demo.json', []);
|
|
|
|
expect(result).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe('processDenoExtract()', () => {
|
|
it('importMap', async () => {
|
|
const result = await processDenoExtract({
|
|
content: {
|
|
lock: undefined,
|
|
dependencies: [],
|
|
importMap: 'import_map.json',
|
|
managerData: {
|
|
workspaces: undefined,
|
|
},
|
|
},
|
|
fileName: 'deno.json',
|
|
});
|
|
expect(result).toStrictEqual([
|
|
{
|
|
deps: [],
|
|
lockFiles: [],
|
|
managerData: {
|
|
workspaces: undefined,
|
|
},
|
|
packageFile: 'deno.json',
|
|
},
|
|
]);
|
|
});
|
|
});
|
|
|
|
describe('extractAllPackageFiles()', () => {
|
|
it('invalid deno.json file', async () => {
|
|
fs.getSiblingFileName.mockReturnValueOnce('deno.json');
|
|
fs.readLocalFile.mockResolvedValueOnce('invalid');
|
|
await expect(extractAllPackageFiles({}, ['deno.json'])).resolves.toEqual(
|
|
[],
|
|
);
|
|
});
|
|
|
|
it('multiple matched files with deno.json only', async () => {
|
|
// Mock for deno.json - returns valid package file
|
|
fs.readLocalFile.mockResolvedValueOnce(
|
|
JSON.stringify({
|
|
imports: {
|
|
dep1: 'npm:dep1@1.0.0',
|
|
},
|
|
}),
|
|
);
|
|
fs.getSiblingFileName.mockReturnValueOnce('deno.lock');
|
|
fs.localPathIsFile.mockResolvedValueOnce(false);
|
|
|
|
const result = await extractAllPackageFiles({}, ['deno.json']);
|
|
expect(result).toHaveLength(1);
|
|
expect(result[0].packageFile).toBe('deno.json');
|
|
expect(result[0].deps).toHaveLength(1);
|
|
});
|
|
|
|
it('deno.lock without package.json', async () => {
|
|
fs.getSiblingFileName.mockReturnValueOnce('deno.lock');
|
|
fs.localPathIsFile.mockResolvedValue(false);
|
|
await expect(extractAllPackageFiles({}, ['deno.lock'])).resolves.toEqual(
|
|
[],
|
|
);
|
|
});
|
|
|
|
it('deno.lock when collectPackageJson returns null', async () => {
|
|
vi.mocked(compat.collectPackageJson).mockResolvedValueOnce(null);
|
|
await expect(extractAllPackageFiles({}, ['deno.lock'])).resolves.toEqual(
|
|
[],
|
|
);
|
|
});
|
|
|
|
it('deno.lock when collectPackageJson returns empty array', async () => {
|
|
vi.mocked(compat.collectPackageJson).mockResolvedValueOnce([]);
|
|
await expect(extractAllPackageFiles({}, ['deno.lock'])).resolves.toEqual(
|
|
[],
|
|
);
|
|
});
|
|
|
|
it('complex config with imports, scopes, tasks and lint', async () => {
|
|
fs.readLocalFile.mockResolvedValueOnce(
|
|
JSON.stringify({
|
|
imports: {
|
|
dep1: 'npm:dep1@1.0.0',
|
|
dep10: 'https://deno.land/x/dep10@v0.1.12/mod.ts',
|
|
},
|
|
scopes: {
|
|
'https://deno.land/x/': {
|
|
dep1: 'npm:dep1@^2.0.0',
|
|
},
|
|
},
|
|
tasks: {
|
|
init: 'deno run -RWE jsr:@scope/dep4@latest',
|
|
dev: {
|
|
command: 'deno run -A --node-modules-dir=auto npm:dep5@6.0.0',
|
|
dependencies: ['init'],
|
|
},
|
|
build: 'deno run -A --node-modules-dir=auto npm:dep6 build',
|
|
changelog: {
|
|
description: 'description',
|
|
command:
|
|
'deno run --allow-read --allow-write https://deno.land/x/dep@v1.0.1/bin.ts',
|
|
},
|
|
joke: 'deno npm:dep7',
|
|
// these should be ignored
|
|
'not-contain-a-datasource': 'deno task npm:example',
|
|
'npm:example': 'deno task jsr:@scope/task',
|
|
'jsr:@scope/task': 'curl http://example.com',
|
|
},
|
|
compilerOptions: {
|
|
types: ['npm:@types/dep1@1.0.0'],
|
|
jsxImportSource: 'npm:dep2@1.0.0',
|
|
jsxImportSourceTypes: 'npm:@types/dep2@1.0.0',
|
|
},
|
|
lint: {
|
|
plugins: [
|
|
'npm:dep3@1.0.0/mod.ts',
|
|
'./local_dep.js', // should be ignored
|
|
],
|
|
},
|
|
}),
|
|
);
|
|
fs.getSiblingFileName.mockReturnValueOnce('deno.lock');
|
|
fs.localPathIsFile.mockResolvedValue(true);
|
|
fs.readLocalFile.mockResolvedValueOnce(
|
|
JSON.stringify({
|
|
version: '5',
|
|
}),
|
|
);
|
|
await expect(
|
|
extractAllPackageFiles({}, ['deno.jsonc', 'deno.lock']),
|
|
).resolves.toStrictEqual([
|
|
{
|
|
deps: [
|
|
{
|
|
currentRawValue: 'npm:dep1@1.0.0',
|
|
currentValue: '1.0.0',
|
|
datasource: 'npm',
|
|
depName: 'dep1',
|
|
depType: 'imports',
|
|
versioning: 'deno',
|
|
},
|
|
{
|
|
currentRawValue: 'https://deno.land/x/dep10@v0.1.12/mod.ts',
|
|
currentValue: 'v0.1.12',
|
|
datasource: 'deno',
|
|
depName: 'https://deno.land/x/dep10',
|
|
depType: 'imports',
|
|
},
|
|
{
|
|
currentRawValue: 'npm:dep1@^2.0.0',
|
|
currentValue: '^2.0.0',
|
|
datasource: 'npm',
|
|
depName: 'dep1',
|
|
depType: 'scopes',
|
|
versioning: 'deno',
|
|
},
|
|
{
|
|
currentRawValue: 'jsr:@scope/dep4@latest',
|
|
currentValue: 'latest',
|
|
datasource: 'jsr',
|
|
depName: '@scope/dep4',
|
|
depType: 'tasks',
|
|
versioning: 'deno',
|
|
},
|
|
{
|
|
currentRawValue: 'npm:dep5@6.0.0',
|
|
currentValue: '6.0.0',
|
|
datasource: 'npm',
|
|
depName: 'dep5',
|
|
depType: 'tasks.command',
|
|
versioning: 'deno',
|
|
},
|
|
{
|
|
currentRawValue: 'npm:dep6',
|
|
currentValue: undefined,
|
|
datasource: 'npm',
|
|
depName: 'dep6',
|
|
depType: 'tasks',
|
|
versioning: 'deno',
|
|
},
|
|
{
|
|
currentRawValue: 'https://deno.land/x/dep@v1.0.1/bin.ts',
|
|
currentValue: 'v1.0.1',
|
|
datasource: 'deno',
|
|
depName: 'https://deno.land/x/dep',
|
|
depType: 'tasks.command',
|
|
},
|
|
{
|
|
currentRawValue: 'npm:dep7',
|
|
currentValue: undefined,
|
|
datasource: 'npm',
|
|
depName: 'dep7',
|
|
depType: 'tasks',
|
|
versioning: 'deno',
|
|
},
|
|
{
|
|
depName: 'deno task npm:example',
|
|
depType: 'tasks',
|
|
skipReason: 'unsupported',
|
|
skipStage: 'extract',
|
|
},
|
|
{
|
|
depName: 'deno task jsr:@scope/task',
|
|
depType: 'tasks',
|
|
skipReason: 'unsupported',
|
|
skipStage: 'extract',
|
|
},
|
|
{
|
|
depName: 'curl http://example.com',
|
|
depType: 'tasks',
|
|
skipReason: 'unsupported',
|
|
skipStage: 'extract',
|
|
},
|
|
{
|
|
currentRawValue: 'npm:@types/dep1@1.0.0',
|
|
currentValue: '1.0.0',
|
|
datasource: 'npm',
|
|
depName: '@types/dep1',
|
|
depType: 'compilerOptions.types',
|
|
versioning: 'deno',
|
|
},
|
|
{
|
|
currentRawValue: 'npm:dep2@1.0.0',
|
|
currentValue: '1.0.0',
|
|
datasource: 'npm',
|
|
depName: 'dep2',
|
|
depType: 'compilerOptions.jsxImportSource',
|
|
versioning: 'deno',
|
|
},
|
|
{
|
|
currentRawValue: 'npm:@types/dep2@1.0.0',
|
|
currentValue: '1.0.0',
|
|
datasource: 'npm',
|
|
depName: '@types/dep2',
|
|
depType: 'compilerOptions.jsxImportSourceTypes',
|
|
versioning: 'deno',
|
|
},
|
|
{
|
|
currentRawValue: 'npm:dep3@1.0.0/',
|
|
currentValue: '1.0.0',
|
|
datasource: 'npm',
|
|
depName: 'dep3',
|
|
depType: 'lint.plugins',
|
|
versioning: 'deno',
|
|
},
|
|
{
|
|
depName: './local_dep.js',
|
|
depType: 'lint.plugins',
|
|
skipReason: 'unsupported',
|
|
skipStage: 'extract',
|
|
},
|
|
],
|
|
lockFiles: ['deno.lock'],
|
|
managerData: {
|
|
workspaces: undefined,
|
|
},
|
|
packageFile: 'deno.jsonc',
|
|
},
|
|
]);
|
|
});
|
|
|
|
// workspace tests
|
|
describe('workspaces', () => {
|
|
beforeAll(() => {
|
|
GlobalConfig.set({ localDir: '' });
|
|
});
|
|
|
|
it('npm workspace compatible', async () => {
|
|
vi.mocked(findPackages).mockResolvedValue([
|
|
{
|
|
dir: 'sub',
|
|
manifest: { name: 'sub' },
|
|
writeProjectManifest: Promise.resolve,
|
|
},
|
|
]);
|
|
// Mock collectPackageJson to return the npm workspace package files
|
|
vi.mocked(compat.collectPackageJson).mockImplementation((file) => {
|
|
if (file === 'deno.lock') {
|
|
return Promise.resolve([
|
|
{
|
|
deps: [
|
|
{
|
|
currentValue: '1.0.0',
|
|
datasource: 'npm',
|
|
depName: 'dep1',
|
|
depType: 'dependencies',
|
|
prettyDepType: 'dependency',
|
|
lockedVersion: '1.0.0',
|
|
},
|
|
],
|
|
managerData: {
|
|
packageName: 'root',
|
|
workspaces: ['sub'],
|
|
},
|
|
extractedConstraints: {},
|
|
lockFiles: ['deno.lock'],
|
|
packageFile: 'package.json',
|
|
packageFileVersion: '0.0.1',
|
|
},
|
|
{
|
|
deps: [
|
|
{
|
|
currentValue: '2.0.0',
|
|
datasource: 'npm',
|
|
depName: 'dep2',
|
|
depType: 'dependencies',
|
|
lockedVersion: '2.0.0',
|
|
prettyDepType: 'dependency',
|
|
},
|
|
],
|
|
managerData: {
|
|
packageName: 'sub',
|
|
workspaces: undefined,
|
|
},
|
|
extractedConstraints: {},
|
|
lockFiles: ['deno.lock'],
|
|
packageFile: 'sub/package.json',
|
|
packageFileVersion: '0.0.2',
|
|
},
|
|
] as any);
|
|
}
|
|
return Promise.resolve(null);
|
|
});
|
|
fs.getSiblingFileName.mockReturnValue('package.json');
|
|
fs.readLocalFile.mockImplementation((fileName) => {
|
|
if (fileName === 'package.json') {
|
|
return Promise.resolve(codeBlock`
|
|
{
|
|
"name": "root",
|
|
"version": "0.0.1",
|
|
"dependencies": {
|
|
"dep1": "1.0.0"
|
|
},
|
|
"workspaces": [
|
|
"sub"
|
|
]
|
|
}
|
|
`);
|
|
}
|
|
if (fileName === 'sub/package.json') {
|
|
return Promise.resolve(codeBlock`
|
|
{
|
|
"name": "sub",
|
|
"version": "0.0.2",
|
|
"dependencies": {
|
|
"dep2": "2.0.0"
|
|
}
|
|
}
|
|
`);
|
|
}
|
|
if (fileName === 'deno.lock') {
|
|
return Promise.resolve(codeBlock`
|
|
{
|
|
"version": "5",
|
|
"specifiers": {
|
|
"npm:dep1@1.0.0": "1.0.0",
|
|
"npm:dep2@2.0.0": "2.0.0"
|
|
}
|
|
}
|
|
`);
|
|
}
|
|
return Promise.resolve(null);
|
|
});
|
|
fs.localPathIsFile.mockImplementation((fileName) => {
|
|
return Promise.resolve(
|
|
fileName === 'package.json' ||
|
|
fileName === 'sub/package.json' ||
|
|
fileName === 'deno.lock',
|
|
);
|
|
});
|
|
|
|
await expect(
|
|
extractAllPackageFiles({}, ['deno.lock']),
|
|
).resolves.toStrictEqual([
|
|
{
|
|
deps: [
|
|
{
|
|
currentValue: '1.0.0',
|
|
datasource: 'npm',
|
|
depName: 'dep1',
|
|
depType: 'dependencies',
|
|
prettyDepType: 'dependency',
|
|
lockedVersion: '1.0.0',
|
|
},
|
|
],
|
|
managerData: {
|
|
packageName: 'root',
|
|
workspaces: ['sub'],
|
|
},
|
|
extractedConstraints: {},
|
|
lockFiles: ['deno.lock'],
|
|
packageFile: 'package.json',
|
|
packageFileVersion: '0.0.1',
|
|
},
|
|
{
|
|
deps: [
|
|
{
|
|
currentValue: '2.0.0',
|
|
datasource: 'npm',
|
|
depName: 'dep2',
|
|
depType: 'dependencies',
|
|
lockedVersion: '2.0.0',
|
|
prettyDepType: 'dependency',
|
|
},
|
|
],
|
|
managerData: {
|
|
packageName: 'sub',
|
|
workspaces: undefined,
|
|
},
|
|
extractedConstraints: {},
|
|
lockFiles: ['deno.lock'],
|
|
packageFile: 'sub/package.json',
|
|
packageFileVersion: '0.0.2',
|
|
},
|
|
]);
|
|
});
|
|
});
|
|
});
|
|
});
|