Files
vscode-codeql/extensions/ql-vscode/test/vscode-tests/cli-integration/model-editor/modeled-method-fs.test.ts
Anders Starcke Henriksen eeac123ee5 Update non-build references.
2023-08-29 14:39:22 +02:00

206 lines
5.5 KiB
TypeScript

import { Uri, workspace } from "vscode";
import * as tmp from "tmp";
import { CodeQLCliServer } from "../../../../src/codeql-cli/cli";
import { getActivatedExtension } from "../../global.helper";
import { mkdirSync, writeFileSync } from "fs";
import {
listModelFiles,
loadModeledMethods,
} from "../../../../src/model-editor/modeled-method-fs";
import { ExtensionPack } from "../../../../src/model-editor/shared/extension-pack";
import { join } from "path";
import { extLogger } from "../../../../src/common/logging/vscode";
import { homedir } from "os";
const dummyExtensionPackContents = `
name: dummy/pack
version: 0.0.0
library: true
extensionTargets:
codeql/java-all: '*'
dataExtensions:
- models/**/*.yml
`;
const dummyModelContents = `
extensions:
- addsTo:
pack: codeql/java-all
extensible: sourceModel
data: []
- addsTo:
pack: codeql/java-all
extensible: sinkModel
data:
- ["org.eclipse.jetty.server","Server",true,"getConnectors","()","","Argument[this]","sql","manual"]
- addsTo:
pack: codeql/java-all
extensible: summaryModel
data: []
- addsTo:
pack: codeql/java-all
extensible: neutralModel
data: []
`;
describe("modeled-method-fs", () => {
let tmpDir: string;
let tmpDirRemoveCallback: (() => void) | undefined;
let workspacePath: string;
let cli: CodeQLCliServer;
beforeAll(async () => {
const extension = await getActivatedExtension();
cli = extension.cliServer;
// All transitive dependencies must be available for resolve extensions to succeed.
const packUsingExtensionsPath = join(
__dirname,
"../../..",
"data-extensions",
"pack-using-extensions",
);
await cli.packInstall(packUsingExtensionsPath);
});
beforeEach(async () => {
// On windows, make sure to use a temp directory that isn't an alias and therefore won't be canonicalised by CodeQL.
// See https://github.com/github/vscode-codeql/pull/2605 for more context.
const t = tmp.dirSync({
dir:
process.platform === "win32"
? join(homedir(), "AppData", "Local", "Temp")
: undefined,
});
tmpDir = t.name;
tmpDirRemoveCallback = t.removeCallback;
const workspaceFolder = {
uri: Uri.file(join(tmpDir, "workspace")),
name: "workspace",
index: 0,
};
workspacePath = workspaceFolder.uri.fsPath;
mkdirSync(workspacePath);
jest
.spyOn(workspace, "workspaceFolders", "get")
.mockReturnValue([workspaceFolder]);
const extension = await getActivatedExtension();
cli = extension.cliServer;
});
afterEach(() => {
tmpDirRemoveCallback?.();
});
function writeExtensionPackFiles(
extensionPackName: string,
modelFileNames: string[],
): string {
const extensionPackPath = join(workspacePath, extensionPackName);
mkdirSync(extensionPackPath);
writeFileSync(
join(extensionPackPath, "codeql-pack.yml"),
dummyExtensionPackContents,
);
mkdirSync(join(extensionPackPath, "models"));
for (const filename of modelFileNames) {
writeFileSync(
join(extensionPackPath, "models", filename),
dummyModelContents,
);
}
return extensionPackPath;
}
function makeExtensionPack(path: string): ExtensionPack {
return {
path,
yamlPath: path,
name: "dummy/pack",
version: "0.0.1",
language: "java",
extensionTargets: {},
dataExtensions: [],
};
}
describe("listModelFiles", () => {
it("should return the empty set when the extension pack is empty", async () => {
if (!(await cli.cliConstraints.supportsResolveExtensions())) {
return;
}
const extensionPackPath = writeExtensionPackFiles("extension-pack", []);
const modelFiles = await listModelFiles(extensionPackPath, cli);
expect(modelFiles).toEqual(new Set());
});
it("should find all model files", async () => {
if (!(await cli.cliConstraints.supportsResolveExtensions())) {
return;
}
const extensionPackPath = writeExtensionPackFiles("extension-pack", [
"library1.model.yml",
"library2.model.yml",
]);
const modelFiles = await listModelFiles(extensionPackPath, cli);
expect(modelFiles).toEqual(
new Set([
join("models", "library1.model.yml"),
join("models", "library2.model.yml"),
]),
);
});
it("should ignore model files from other extension packs", async () => {
if (!(await cli.cliConstraints.supportsResolveExtensions())) {
return;
}
const extensionPackPath = writeExtensionPackFiles("extension-pack", [
"library1.model.yml",
]);
writeExtensionPackFiles("another-extension-pack", ["library2.model.yml"]);
const modelFiles = await listModelFiles(extensionPackPath, cli);
expect(modelFiles).toEqual(
new Set([join("models", "library1.model.yml")]),
);
});
});
describe("loadModeledMethods", () => {
it("should load modeled methods", async () => {
if (!(await cli.cliConstraints.supportsResolveExtensions())) {
return;
}
const extensionPackPath = writeExtensionPackFiles("extension-pack", [
"library.model.yml",
]);
const modeledMethods = await loadModeledMethods(
makeExtensionPack(extensionPackPath),
cli,
extLogger,
);
expect(Object.keys(modeledMethods).length).toEqual(1);
expect(Object.keys(modeledMethods)[0]).toEqual(
"org.eclipse.jetty.server.Server#getConnectors()",
);
});
});
});