cli: add test for versions:bump command

This commit is contained in:
Patrik Oldsberg
2020-11-23 12:43:54 +01:00
parent 0c597a8d62
commit d20f605082
4 changed files with 167 additions and 7 deletions
@@ -0,0 +1,161 @@
/*
* Copyright 2020 Spotify AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import fs from 'fs-extra';
import mockFs from 'mock-fs';
import { resolve as resolvePath } from 'path';
import { paths } from '../../lib/paths';
import { mapDependencies } from '../../lib/versioning';
import * as runObj from '../../lib/run';
import bump from './bump';
import { withLogCollector } from '@backstage/test-utils';
const REGISTRY_VERSIONS: { [name: string]: string } = {
'@backstage/core': '1.0.7',
'@backstage/theme': '2.0.0',
};
const HEADER = `# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
`;
const lockfileMock = `${HEADER}
"@backstage/core@^1.0.5":
version "1.0.6"
resolved "https://my-registry/a-1.0.01.tgz#abc123"
integrity sha512-xyz
"@backstage/core@^1.0.3":
version "1.0.3"
resolved "https://my-registry/a-1.0.01.tgz#abc123"
integrity sha512-xyz
"@backstage/theme@^1.0.0":
version "1.0.0"
resolved "https://my-registry/a-1.0.01.tgz#abc123"
integrity sha512-xyz
`;
const lockfileMockResult = `${HEADER}
"@backstage/core@^1.0.3", "@backstage/core@^1.0.5":
version "1.0.6"
resolved "https://my-registry/a-1.0.01.tgz#abc123"
integrity sha512-xyz
"@backstage/theme@^1.0.0":
version "1.0.0"
resolved "https://my-registry/a-1.0.01.tgz#abc123"
integrity sha512-xyz
`;
describe('bump', () => {
afterEach(() => {
mockFs.restore();
jest.resetAllMocks();
});
it('should bump backstage dependencies', async () => {
// Make sure all modules involved in package discovery are in the module cache before we mock fs
await mapDependencies(paths.targetDir);
mockFs({
'/yarn.lock': lockfileMock,
'/lerna.json': JSON.stringify({
packages: ['packages/*'],
}),
'/packages/a/package.json': JSON.stringify({
name: 'a',
dependencies: {
'@backstage/core': '^1.0.5',
},
}),
'/packages/b/package.json': JSON.stringify({
name: 'b',
dependencies: {
'@backstage/core': '^1.0.3',
'@backstage/theme': '^1.0.0',
},
}),
});
paths.targetDir = '/';
jest
.spyOn(paths, 'resolveTargetRoot')
.mockImplementation((...paths) => resolvePath('/', ...paths));
jest.spyOn(runObj, 'runPlain').mockImplementation(async (...[, , , name]) =>
JSON.stringify({
type: 'inspect',
data: {
name: name,
'dist-tags': {
latest: REGISTRY_VERSIONS[name],
},
},
}),
);
jest.spyOn(runObj, 'run').mockResolvedValue(undefined);
const { log: logs } = await withLogCollector(['log'], async () => {
await bump();
});
expect(logs.filter(Boolean)).toEqual([
'Checking for updates of @backstage/theme',
'Checking for updates of @backstage/core',
'Some packages are outdated, updating',
'Bumping @backstage/theme in b to ^2.0.0',
"Running 'yarn install' to install new versions",
'Removing duplicate dependencies from yarn.lock',
"Running 'yarn install' to remove duplicates from node_modules",
]);
expect(runObj.runPlain).toHaveBeenCalledTimes(2);
expect(runObj.runPlain).toHaveBeenCalledWith(
'yarn',
'info',
'--json',
'@backstage/core',
);
expect(runObj.runPlain).toHaveBeenCalledWith(
'yarn',
'info',
'--json',
'@backstage/theme',
);
expect(runObj.run).toHaveBeenCalledTimes(2);
expect(runObj.run).toHaveBeenCalledWith('yarn', ['install']);
const lockfileContents = await fs.readFile('/yarn.lock', 'utf8');
expect(lockfileContents).toBe(lockfileMockResult);
const packageA = await fs.readJson('/packages/a/package.json');
expect(packageA).toEqual({
name: 'a',
dependencies: {
'@backstage/core': '^1.0.5', // not bumped since new version is within range
},
});
const packageB = await fs.readJson('/packages/b/package.json');
expect(packageB).toEqual({
name: 'b',
dependencies: {
'@backstage/core': '^1.0.3', // not bumped
'@backstage/theme': '^2.0.0', // bumped since newer
},
});
});
});
+1 -1
View File
@@ -40,7 +40,7 @@ type PkgVersionInfo = {
export default async () => {
// First we discover all Backstage dependencies within our own repo
const dependencyMap = await mapDependencies();
const dependencyMap = await mapDependencies(paths.targetDir);
// Next check with the package registry what the latest version of all of those dependencies are
const targetVersions = new Map<string, string>();
@@ -75,7 +75,7 @@ describe('mapDependencies', () => {
const oldDir = paths.targetDir;
paths.targetDir = '/';
const dependencyMap = await mapDependencies();
const dependencyMap = await mapDependencies(paths.targetDir);
expect(Array.from(dependencyMap)).toEqual([
[
'@backstage/core',
+4 -5
View File
@@ -15,7 +15,6 @@
*/
import { runPlain } from '../../lib/run';
import { paths } from '../../lib/paths';
const PREFIX = '@backstage';
@@ -59,11 +58,11 @@ export async function fetchPackageInfo(
}
/** Map all dependencies in the repo as dependency => dependents */
export async function mapDependencies(): Promise<
Map<string, PkgVersionInfo[]>
> {
export async function mapDependencies(
targetDir: string,
): Promise<Map<string, PkgVersionInfo[]>> {
const LernaProject = require('@lerna/project');
const project = new LernaProject(paths.targetDir);
const project = new LernaProject(targetDir);
const packages = await project.getPackages();
const dependencyMap = new Map<string, PkgVersionInfo[]>();