Remove fs mocking from no-workspace tests

This commit is contained in:
Koen Vlaswinkel 2022-12-02 13:40:12 +01:00 коммит произвёл Koen Vlaswinkel
Родитель f13f0b3bc3
Коммит 0d8c90a7b5
5 изменённых файлов: 104 добавлений и 99 удалений

Просмотреть файл

@ -13,8 +13,6 @@ import { CodeQLCliServer } from "../../../../src/cli";
import { DatabaseItem } from "../../../../src/databases"; import { DatabaseItem } from "../../../../src/databases";
describe("queryResolver", () => { describe("queryResolver", () => {
let writeFileSpy: jest.SpiedFunction<typeof fs.writeFile>;
let getQlPackForDbschemeSpy: jest.SpiedFunction< let getQlPackForDbschemeSpy: jest.SpiedFunction<
typeof helpers.getQlPackForDbscheme typeof helpers.getQlPackForDbscheme
>; >;
@ -30,10 +28,6 @@ describe("queryResolver", () => {
}; };
beforeEach(() => { beforeEach(() => {
writeFileSpy = jest
.spyOn(fs, "writeFile")
.mockImplementation(() => Promise.resolve());
getQlPackForDbschemeSpy = jest getQlPackForDbschemeSpy = jest
.spyOn(helpers, "getQlPackForDbscheme") .spyOn(helpers, "getQlPackForDbscheme")
.mockResolvedValue({ .mockResolvedValue({
@ -61,13 +55,15 @@ describe("queryResolver", () => {
KeyType.DefinitionQuery, KeyType.DefinitionQuery,
); );
expect(result).toEqual(["a", "b"]); expect(result).toEqual(["a", "b"]);
expect(writeFileSpy).toHaveBeenNthCalledWith(
1, expect(mockCli.resolveQueriesInSuite).toHaveBeenCalledWith(
expect.stringMatching(/.qls$/), expect.stringMatching(/\.qls$/),
expect.anything(), [],
expect.anything(),
); );
expect(load(writeFileSpy.mock.calls[0][1])).toEqual([
const fileName = mockCli.resolveQueriesInSuite.mock.calls[0][0];
expect(load(await fs.readFile(fileName, "utf-8"))).toEqual([
{ {
from: "my-qlpack", from: "my-qlpack",
queries: ".", queries: ".",
@ -95,13 +91,15 @@ describe("queryResolver", () => {
KeyType.DefinitionQuery, KeyType.DefinitionQuery,
); );
expect(result).toEqual(["a", "b"]); expect(result).toEqual(["a", "b"]);
expect(writeFileSpy).toHaveBeenNthCalledWith(
1, expect(mockCli.resolveQueriesInSuite).toHaveBeenCalledWith(
expect.stringMatching(/.qls$/), expect.stringMatching(/\.qls$/),
expect.anything(), [],
expect.anything(),
); );
expect(load(writeFileSpy.mock.calls[0][1])).toEqual([
const fileName = mockCli.resolveQueriesInSuite.mock.calls[0][0];
expect(load(await fs.readFile(fileName, "utf-8"))).toEqual([
{ {
from: "my-qlpack2", from: "my-qlpack2",
queries: ".", queries: ".",

Просмотреть файл

@ -1,11 +1,12 @@
import { sep } from "path";
import * as fetch from "node-fetch"; import * as fetch from "node-fetch";
import { Range } from "semver"; import { Range } from "semver";
import * as helpers from "../../../src/helpers"; import * as helpers from "../../../src/helpers";
import { extLogger } from "../../../src/common"; import { extLogger } from "../../../src/common";
import * as fs from "fs-extra"; import * as fs from "fs-extra";
import * as path from "path";
import * as os from "os"; import * as os from "os";
import * as tmp from "tmp-promise";
import { import {
GithubRelease, GithubRelease,
GithubReleaseAsset, GithubReleaseAsset,
@ -13,6 +14,17 @@ import {
getExecutableFromDirectory, getExecutableFromDirectory,
DistributionManager, DistributionManager,
} from "../../../src/distribution"; } from "../../../src/distribution";
import { DirectoryResult } from "tmp-promise";
jest.mock("os", () => {
const original = jest.requireActual("os");
return {
...original,
platform: jest.fn(),
};
});
const mockedOS = jest.mocked(os);
describe("Releases API consumer", () => { describe("Releases API consumer", () => {
const owner = "someowner"; const owner = "someowner";
@ -192,17 +204,16 @@ describe("Releases API consumer", () => {
}); });
describe("Launcher path", () => { describe("Launcher path", () => {
const pathToCmd = `abc${sep}codeql.cmd`;
const pathToExe = `abc${sep}codeql.exe`;
let warnSpy: jest.SpiedFunction<typeof helpers.showAndLogWarningMessage>; let warnSpy: jest.SpiedFunction<typeof helpers.showAndLogWarningMessage>;
let errorSpy: jest.SpiedFunction<typeof helpers.showAndLogErrorMessage>; let errorSpy: jest.SpiedFunction<typeof helpers.showAndLogErrorMessage>;
let logSpy: jest.SpiedFunction<typeof extLogger.log>; let logSpy: jest.SpiedFunction<typeof extLogger.log>;
let pathExistsSpy: jest.SpiedFunction<typeof fs.pathExists>;
let launcherThatExists = ""; let directory: DirectoryResult;
beforeEach(() => { let pathToCmd: string;
let pathToExe: string;
beforeEach(async () => {
warnSpy = jest warnSpy = jest
.spyOn(helpers, "showAndLogWarningMessage") .spyOn(helpers, "showAndLogWarningMessage")
.mockResolvedValue(undefined); .mockResolvedValue(undefined);
@ -210,22 +221,25 @@ describe("Launcher path", () => {
.spyOn(helpers, "showAndLogErrorMessage") .spyOn(helpers, "showAndLogErrorMessage")
.mockResolvedValue(undefined); .mockResolvedValue(undefined);
logSpy = jest.spyOn(extLogger, "log").mockResolvedValue(undefined); logSpy = jest.spyOn(extLogger, "log").mockResolvedValue(undefined);
pathExistsSpy = jest
.spyOn(fs, "pathExists")
.mockImplementation(async (path: string) => {
return path.endsWith(launcherThatExists);
});
jest.spyOn(os, "platform").mockReturnValue("win32"); mockedOS.platform.mockReturnValue("win32");
directory = await tmp.dir({
unsafeCleanup: true,
});
pathToCmd = path.join(directory.path, "codeql.cmd");
pathToExe = path.join(directory.path, "codeql.exe");
});
afterEach(async () => {
await directory.cleanup();
}); });
it("should not warn with proper launcher name", async () => { it("should not warn with proper launcher name", async () => {
launcherThatExists = "codeql.exe"; await fs.writeFile(pathToExe, "");
const result = await getExecutableFromDirectory("abc");
expect(pathExistsSpy).toBeCalledWith(pathToExe);
// correct launcher has been found, so alternate one not looked for const result = await getExecutableFromDirectory(directory.path);
expect(pathExistsSpy).not.toBeCalledWith(pathToCmd);
// no warning message // no warning message
expect(warnSpy).not.toHaveBeenCalled(); expect(warnSpy).not.toHaveBeenCalled();
@ -235,10 +249,9 @@ describe("Launcher path", () => {
}); });
it("should warn when using a hard-coded deprecated launcher name", async () => { it("should warn when using a hard-coded deprecated launcher name", async () => {
launcherThatExists = "codeql.cmd"; await fs.writeFile(pathToCmd, "");
const result = await getExecutableFromDirectory("abc");
expect(pathExistsSpy).toBeCalledWith(pathToExe); const result = await getExecutableFromDirectory(directory.path);
expect(pathExistsSpy).toBeCalledWith(pathToCmd);
// Should have opened a warning message // Should have opened a warning message
expect(warnSpy).toHaveBeenCalled(); expect(warnSpy).toHaveBeenCalled();
@ -248,10 +261,7 @@ describe("Launcher path", () => {
}); });
it("should avoid warn when no launcher is found", async () => { it("should avoid warn when no launcher is found", async () => {
launcherThatExists = "xxx"; const result = await getExecutableFromDirectory(directory.path, false);
const result = await getExecutableFromDirectory("abc", false);
expect(pathExistsSpy).toBeCalledWith(pathToExe);
expect(pathExistsSpy).toBeCalledWith(pathToCmd);
// no warning message // no warning message
expect(warnSpy).not.toHaveBeenCalled(); expect(warnSpy).not.toHaveBeenCalled();
@ -261,10 +271,7 @@ describe("Launcher path", () => {
}); });
it("should warn when no launcher is found", async () => { it("should warn when no launcher is found", async () => {
launcherThatExists = "xxx";
const result = await getExecutableFromDirectory("abc", true); const result = await getExecutableFromDirectory("abc", true);
expect(pathExistsSpy).toBeCalledWith(pathToExe);
expect(pathExistsSpy).toBeCalledWith(pathToCmd);
// no warning message // no warning message
expect(warnSpy).not.toHaveBeenCalled(); expect(warnSpy).not.toHaveBeenCalled();
@ -274,12 +281,13 @@ describe("Launcher path", () => {
}); });
it("should not warn when deprecated launcher is used, but no new launcher is available", async function () { it("should not warn when deprecated launcher is used, but no new launcher is available", async function () {
await fs.writeFile(pathToCmd, "");
const manager = new DistributionManager( const manager = new DistributionManager(
{ customCodeQlPath: pathToCmd } as any, { customCodeQlPath: pathToCmd } as any,
{} as any, {} as any,
undefined as any, undefined as any,
); );
launcherThatExists = "codeql.cmd";
const result = await manager.getCodeQlPathWithoutVersionCheck(); const result = await manager.getCodeQlPathWithoutVersionCheck();
expect(result).toBe(pathToCmd); expect(result).toBe(pathToCmd);
@ -290,12 +298,14 @@ describe("Launcher path", () => {
}); });
it("should warn when deprecated launcher is used, and new launcher is available", async () => { it("should warn when deprecated launcher is used, and new launcher is available", async () => {
await fs.writeFile(pathToCmd, "");
await fs.writeFile(pathToExe, "");
const manager = new DistributionManager( const manager = new DistributionManager(
{ customCodeQlPath: pathToCmd } as any, { customCodeQlPath: pathToCmd } as any,
{} as any, {} as any,
undefined as any, undefined as any,
); );
launcherThatExists = ""; // pretend both launchers exist
const result = await manager.getCodeQlPathWithoutVersionCheck(); const result = await manager.getCodeQlPathWithoutVersionCheck();
expect(result).toBe(pathToCmd); expect(result).toBe(pathToCmd);
@ -311,7 +321,6 @@ describe("Launcher path", () => {
{} as any, {} as any,
undefined as any, undefined as any,
); );
launcherThatExists = "xxx"; // pretend neither launcher exists
const result = await manager.getCodeQlPathWithoutVersionCheck(); const result = await manager.getCodeQlPathWithoutVersionCheck();
expect(result).toBeUndefined(); expect(result).toBeUndefined();

Просмотреть файл

@ -1,5 +1,8 @@
import { QuickPickItem, window } from "vscode"; import { QuickPickItem, window } from "vscode";
import * as fs from "fs-extra"; import { join } from "path";
import { DirectoryResult } from "tmp-promise";
import * as tmp from "tmp-promise";
import { ensureDir, writeFile, writeJson } from "fs-extra";
import { UserCancellationException } from "../../../../src/commandRunner"; import { UserCancellationException } from "../../../../src/commandRunner";
import * as config from "../../../../src/config"; import * as config from "../../../../src/config";
@ -126,10 +129,6 @@ describe("repository selection", () => {
typeof config.getRemoteRepositoryListsPath typeof config.getRemoteRepositoryListsPath
>; >;
let pathExistsStub: jest.SpiedFunction<typeof fs.pathExists>;
let fsStatStub: jest.SpiedFunction<typeof fs.stat>;
let fsReadFileStub: jest.SpiedFunction<typeof fs.readFile>;
beforeEach(() => { beforeEach(() => {
quickPickSpy = jest quickPickSpy = jest
.spyOn(window, "showQuickPick") .spyOn(window, "showQuickPick")
@ -144,16 +143,6 @@ describe("repository selection", () => {
getRemoteRepositoryListsPathSpy = jest getRemoteRepositoryListsPathSpy = jest
.spyOn(config, "getRemoteRepositoryListsPath") .spyOn(config, "getRemoteRepositoryListsPath")
.mockReturnValue(undefined); .mockReturnValue(undefined);
pathExistsStub = jest
.spyOn(fs, "pathExists")
.mockImplementation(() => false);
fsStatStub = jest
.spyOn(fs, "stat")
.mockRejectedValue(new Error("not found"));
fsReadFileStub = jest
.spyOn(fs, "readFile")
.mockRejectedValue(new Error("not found"));
}); });
describe("repo lists from settings", () => { describe("repo lists from settings", () => {
it("should allow selection from repo lists from your pre-defined config", async () => { it("should allow selection from repo lists from your pre-defined config", async () => {
@ -362,21 +351,31 @@ describe("repository selection", () => {
}); });
describe("external repository lists file", () => { describe("external repository lists file", () => {
let directory: DirectoryResult;
beforeEach(async () => {
directory = await tmp.dir({
unsafeCleanup: true,
});
});
afterEach(async () => {
await directory.cleanup();
});
it("should fail if path does not exist", async () => { it("should fail if path does not exist", async () => {
const fakeFilePath = "/path/that/does/not/exist.json"; const nonExistingFile = join(directory.path, "non-existing-file.json");
getRemoteRepositoryListsPathSpy.mockReturnValue(fakeFilePath); getRemoteRepositoryListsPathSpy.mockReturnValue(nonExistingFile);
pathExistsStub.mockImplementation(() => false);
await expect(getRepositorySelection()).rejects.toThrow( await expect(getRepositorySelection()).rejects.toThrow(
`External repository lists file does not exist at ${fakeFilePath}`, `External repository lists file does not exist at ${nonExistingFile}`,
); );
}); });
it("should fail if path points to directory", async () => { it("should fail if path points to directory", async () => {
const fakeFilePath = "/path/to/dir"; const existingDirectory = join(directory.path, "directory");
getRemoteRepositoryListsPathSpy.mockReturnValue(fakeFilePath); await ensureDir(existingDirectory);
pathExistsStub.mockImplementation(() => true); getRemoteRepositoryListsPathSpy.mockReturnValue(existingDirectory);
fsStatStub.mockResolvedValue({ isDirectory: () => true } as any);
await expect(getRepositorySelection()).rejects.toThrow( await expect(getRepositorySelection()).rejects.toThrow(
"External repository lists path should not point to a directory", "External repository lists path should not point to a directory",
@ -384,11 +383,9 @@ describe("repository selection", () => {
}); });
it("should fail if file does not have valid JSON", async () => { it("should fail if file does not have valid JSON", async () => {
const fakeFilePath = "/path/to/file.json"; const existingFile = join(directory.path, "repository-lists.json");
getRemoteRepositoryListsPathSpy.mockReturnValue(fakeFilePath); await writeFile(existingFile, "not-json");
pathExistsStub.mockImplementation(() => true); getRemoteRepositoryListsPathSpy.mockReturnValue(existingFile);
fsStatStub.mockResolvedValue({ isDirectory: () => false } as any);
fsReadFileStub.mockResolvedValue("not-json" as any as Buffer);
await expect(getRepositorySelection()).rejects.toThrow( await expect(getRepositorySelection()).rejects.toThrow(
"Invalid repository lists file. It should contain valid JSON.", "Invalid repository lists file. It should contain valid JSON.",
@ -396,11 +393,9 @@ describe("repository selection", () => {
}); });
it("should fail if file contains array", async () => { it("should fail if file contains array", async () => {
const fakeFilePath = "/path/to/file.json"; const existingFile = join(directory.path, "repository-lists.json");
getRemoteRepositoryListsPathSpy.mockReturnValue(fakeFilePath); await writeJson(existingFile, []);
pathExistsStub.mockImplementation(() => true); getRemoteRepositoryListsPathSpy.mockReturnValue(existingFile);
fsStatStub.mockResolvedValue({ isDirectory: () => false } as any);
fsReadFileStub.mockResolvedValue("[]" as any as Buffer);
await expect(getRepositorySelection()).rejects.toThrow( await expect(getRepositorySelection()).rejects.toThrow(
"Invalid repository lists file. It should be an object mapping names to a list of repositories.", "Invalid repository lists file. It should be an object mapping names to a list of repositories.",
@ -408,16 +403,12 @@ describe("repository selection", () => {
}); });
it("should fail if file does not contain repo lists in the right format", async () => { it("should fail if file does not contain repo lists in the right format", async () => {
const fakeFilePath = "/path/to/file.json"; const existingFile = join(directory.path, "repository-lists.json");
getRemoteRepositoryListsPathSpy.mockReturnValue(fakeFilePath);
pathExistsStub.mockImplementation(() => true);
fsStatStub.mockResolvedValue({ isDirectory: () => false } as any);
const repoLists = { const repoLists = {
list1: "owner1/repo1", list1: "owner1/repo1",
}; };
fsReadFileStub.mockResolvedValue( await writeJson(existingFile, repoLists);
JSON.stringify(repoLists) as any as Buffer, getRemoteRepositoryListsPathSpy.mockReturnValue(existingFile);
);
await expect(getRepositorySelection()).rejects.toThrow( await expect(getRepositorySelection()).rejects.toThrow(
"Invalid repository lists file. It should contain an array of repositories for each list.", "Invalid repository lists file. It should contain an array of repositories for each list.",
@ -425,17 +416,13 @@ describe("repository selection", () => {
}); });
it("should get repo lists from file", async () => { it("should get repo lists from file", async () => {
const fakeFilePath = "/path/to/file.json"; const existingFile = join(directory.path, "repository-lists.json");
getRemoteRepositoryListsPathSpy.mockReturnValue(fakeFilePath);
pathExistsStub.mockImplementation(() => true);
fsStatStub.mockResolvedValue({ isDirectory: () => false } as any);
const repoLists = { const repoLists = {
list1: ["owner1/repo1", "owner2/repo2"], list1: ["owner1/repo1", "owner2/repo2"],
list2: ["owner3/repo3"], list2: ["owner3/repo3"],
}; };
fsReadFileStub.mockResolvedValue( await writeJson(existingFile, repoLists);
JSON.stringify(repoLists) as any as Buffer, getRemoteRepositoryListsPathSpy.mockReturnValue(existingFile);
);
getRemoteRepositoryListsSpy.mockReturnValue({ getRemoteRepositoryListsSpy.mockReturnValue({
list3: ["onwer4/repo4"], list3: ["onwer4/repo4"],
list4: [], list4: [],

Просмотреть файл

@ -10,6 +10,16 @@ import {
FullDatabaseOptions, FullDatabaseOptions,
} from "../../../src/databases"; } from "../../../src/databases";
jest.mock("fs-extra", () => {
const original = jest.requireActual("fs-extra");
return {
...original,
access: jest.fn(),
};
});
const mockedFsExtra = jest.mocked(fs);
describe("test-adapter", () => { describe("test-adapter", () => {
let adapter: QLTestAdapter; let adapter: QLTestAdapter;
let fakeDatabaseManager: DatabaseManager; let fakeDatabaseManager: DatabaseManager;
@ -118,7 +128,7 @@ describe("test-adapter", () => {
}); });
it("should reregister testproj databases around test run", async () => { it("should reregister testproj databases around test run", async () => {
jest.spyOn(fs, "access").mockResolvedValue(undefined); mockedFsExtra.access.mockResolvedValue(undefined);
currentDatabaseItem = preTestDatabaseItem; currentDatabaseItem = preTestDatabaseItem;
databaseItems = [preTestDatabaseItem]; databaseItems = [preTestDatabaseItem];

Просмотреть файл

@ -20,7 +20,8 @@
"noUnusedLocals": true, "noUnusedLocals": true,
"noUnusedParameters": true, "noUnusedParameters": true,
"esModuleInterop": true, "esModuleInterop": true,
"resolveJsonModule": true "resolveJsonModule": true,
"noEmit": true
}, },
"include": ["src/**/*.ts"], "include": ["src/**/*.ts"],
"exclude": ["node_modules", "test", "**/view"] "exclude": ["node_modules", "test", "**/view"]