Merge remote-tracking branch 'origin/main' into koesie10/hide-type-models-non-canary
This commit is contained in:
@@ -977,6 +977,7 @@ async function activateWithInstalledDistribution(
|
|||||||
const modelEditorModule = await ModelEditorModule.initialize(
|
const modelEditorModule = await ModelEditorModule.initialize(
|
||||||
app,
|
app,
|
||||||
dbm,
|
dbm,
|
||||||
|
variantAnalysisManager,
|
||||||
cliServer,
|
cliServer,
|
||||||
qs,
|
qs,
|
||||||
tmpDir.name,
|
tmpDir.name,
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import { getModelsAsDataLanguage } from "./languages";
|
|||||||
import { INITIAL_MODE } from "./shared/mode";
|
import { INITIAL_MODE } from "./shared/mode";
|
||||||
import { isSupportedLanguage } from "./supported-languages";
|
import { isSupportedLanguage } from "./supported-languages";
|
||||||
import { DefaultNotifier, checkConsistency } from "./consistency-check";
|
import { DefaultNotifier, checkConsistency } from "./consistency-check";
|
||||||
|
import type { VariantAnalysisManager } from "../variant-analysis/variant-analysis-manager";
|
||||||
|
|
||||||
export class ModelEditorModule extends DisposableObject {
|
export class ModelEditorModule extends DisposableObject {
|
||||||
private readonly queryStorageDir: string;
|
private readonly queryStorageDir: string;
|
||||||
@@ -43,6 +44,7 @@ export class ModelEditorModule extends DisposableObject {
|
|||||||
private constructor(
|
private constructor(
|
||||||
private readonly app: App,
|
private readonly app: App,
|
||||||
private readonly databaseManager: DatabaseManager,
|
private readonly databaseManager: DatabaseManager,
|
||||||
|
private readonly variantAnalysisManager: VariantAnalysisManager,
|
||||||
private readonly cliServer: CodeQLCliServer,
|
private readonly cliServer: CodeQLCliServer,
|
||||||
private readonly queryRunner: QueryRunner,
|
private readonly queryRunner: QueryRunner,
|
||||||
baseQueryStorageDir: string,
|
baseQueryStorageDir: string,
|
||||||
@@ -65,6 +67,7 @@ export class ModelEditorModule extends DisposableObject {
|
|||||||
public static async initialize(
|
public static async initialize(
|
||||||
app: App,
|
app: App,
|
||||||
databaseManager: DatabaseManager,
|
databaseManager: DatabaseManager,
|
||||||
|
variantAnalysisManager: VariantAnalysisManager,
|
||||||
cliServer: CodeQLCliServer,
|
cliServer: CodeQLCliServer,
|
||||||
queryRunner: QueryRunner,
|
queryRunner: QueryRunner,
|
||||||
queryStorageDir: string,
|
queryStorageDir: string,
|
||||||
@@ -72,6 +75,7 @@ export class ModelEditorModule extends DisposableObject {
|
|||||||
const modelEditorModule = new ModelEditorModule(
|
const modelEditorModule = new ModelEditorModule(
|
||||||
app,
|
app,
|
||||||
databaseManager,
|
databaseManager,
|
||||||
|
variantAnalysisManager,
|
||||||
cliServer,
|
cliServer,
|
||||||
queryRunner,
|
queryRunner,
|
||||||
queryStorageDir,
|
queryStorageDir,
|
||||||
@@ -240,6 +244,7 @@ export class ModelEditorModule extends DisposableObject {
|
|||||||
this.modelingEvents,
|
this.modelingEvents,
|
||||||
this.modelConfig,
|
this.modelConfig,
|
||||||
this.databaseManager,
|
this.databaseManager,
|
||||||
|
this.variantAnalysisManager,
|
||||||
this.cliServer,
|
this.cliServer,
|
||||||
this.queryRunner,
|
this.queryRunner,
|
||||||
this.queryStorageDir,
|
this.queryStorageDir,
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ import { runSuggestionsQuery } from "./suggestion-queries";
|
|||||||
import { parseAccessPathSuggestionRowsToOptions } from "./suggestions-bqrs";
|
import { parseAccessPathSuggestionRowsToOptions } from "./suggestions-bqrs";
|
||||||
import { ModelEvaluator } from "./model-evaluator";
|
import { ModelEvaluator } from "./model-evaluator";
|
||||||
import type { ModelEvaluationRunState } from "./shared/model-evaluation-run-state";
|
import type { ModelEvaluationRunState } from "./shared/model-evaluation-run-state";
|
||||||
|
import type { VariantAnalysisManager } from "../variant-analysis/variant-analysis-manager";
|
||||||
|
|
||||||
export class ModelEditorView extends AbstractWebview<
|
export class ModelEditorView extends AbstractWebview<
|
||||||
ToModelEditorMessage,
|
ToModelEditorMessage,
|
||||||
@@ -78,6 +79,7 @@ export class ModelEditorView extends AbstractWebview<
|
|||||||
private readonly modelingEvents: ModelingEvents,
|
private readonly modelingEvents: ModelingEvents,
|
||||||
private readonly modelConfig: ModelConfigListener,
|
private readonly modelConfig: ModelConfigListener,
|
||||||
private readonly databaseManager: DatabaseManager,
|
private readonly databaseManager: DatabaseManager,
|
||||||
|
private readonly variantAnalysisManager: VariantAnalysisManager,
|
||||||
private readonly cliServer: CodeQLCliServer,
|
private readonly cliServer: CodeQLCliServer,
|
||||||
private readonly queryRunner: QueryRunner,
|
private readonly queryRunner: QueryRunner,
|
||||||
private readonly queryStorageDir: string,
|
private readonly queryStorageDir: string,
|
||||||
@@ -116,9 +118,13 @@ export class ModelEditorView extends AbstractWebview<
|
|||||||
this.languageDefinition = getModelsAsDataLanguage(language);
|
this.languageDefinition = getModelsAsDataLanguage(language);
|
||||||
|
|
||||||
this.modelEvaluator = new ModelEvaluator(
|
this.modelEvaluator = new ModelEvaluator(
|
||||||
|
this.app.logger,
|
||||||
|
this.cliServer,
|
||||||
modelingStore,
|
modelingStore,
|
||||||
modelingEvents,
|
modelingEvents,
|
||||||
|
this.variantAnalysisManager,
|
||||||
databaseItem,
|
databaseItem,
|
||||||
|
language,
|
||||||
this.updateModelEvaluationRun.bind(this),
|
this.updateModelEvaluationRun.bind(this),
|
||||||
);
|
);
|
||||||
this.push(this.modelEvaluator);
|
this.push(this.modelEvaluator);
|
||||||
@@ -803,6 +809,7 @@ export class ModelEditorView extends AbstractWebview<
|
|||||||
this.modelingEvents,
|
this.modelingEvents,
|
||||||
this.modelConfig,
|
this.modelConfig,
|
||||||
this.databaseManager,
|
this.databaseManager,
|
||||||
|
this.variantAnalysisManager,
|
||||||
this.cliServer,
|
this.cliServer,
|
||||||
this.queryRunner,
|
this.queryRunner,
|
||||||
this.queryStorageDir,
|
this.queryStorageDir,
|
||||||
|
|||||||
@@ -3,14 +3,24 @@ import type { ModelingEvents } from "./modeling-events";
|
|||||||
import type { DatabaseItem } from "../databases/local-databases";
|
import type { DatabaseItem } from "../databases/local-databases";
|
||||||
import type { ModelEvaluationRun } from "./model-evaluation-run";
|
import type { ModelEvaluationRun } from "./model-evaluation-run";
|
||||||
import { DisposableObject } from "../common/disposable-object";
|
import { DisposableObject } from "../common/disposable-object";
|
||||||
import { sleep } from "../common/time";
|
|
||||||
import type { ModelEvaluationRunState } from "./shared/model-evaluation-run-state";
|
import type { ModelEvaluationRunState } from "./shared/model-evaluation-run-state";
|
||||||
|
import type { BaseLogger } from "../common/logging";
|
||||||
|
import type { CodeQLCliServer } from "../codeql-cli/cli";
|
||||||
|
import type { VariantAnalysisManager } from "../variant-analysis/variant-analysis-manager";
|
||||||
|
import type { QueryLanguage } from "../common/query-language";
|
||||||
|
import { resolveCodeScanningQueryPack } from "../variant-analysis/code-scanning-pack";
|
||||||
|
import { withProgress } from "../common/vscode/progress";
|
||||||
|
import type { VariantAnalysis } from "../variant-analysis/shared/variant-analysis";
|
||||||
|
|
||||||
export class ModelEvaluator extends DisposableObject {
|
export class ModelEvaluator extends DisposableObject {
|
||||||
public constructor(
|
public constructor(
|
||||||
|
private readonly logger: BaseLogger,
|
||||||
|
private readonly cliServer: CodeQLCliServer,
|
||||||
private readonly modelingStore: ModelingStore,
|
private readonly modelingStore: ModelingStore,
|
||||||
private readonly modelingEvents: ModelingEvents,
|
private readonly modelingEvents: ModelingEvents,
|
||||||
|
private readonly variantAnalysisManager: VariantAnalysisManager,
|
||||||
private readonly dbItem: DatabaseItem,
|
private readonly dbItem: DatabaseItem,
|
||||||
|
private readonly language: QueryLanguage,
|
||||||
private readonly updateView: (
|
private readonly updateView: (
|
||||||
run: ModelEvaluationRunState,
|
run: ModelEvaluationRunState,
|
||||||
) => Promise<void>,
|
) => Promise<void>,
|
||||||
@@ -28,18 +38,48 @@ export class ModelEvaluator extends DisposableObject {
|
|||||||
};
|
};
|
||||||
this.modelingStore.updateModelEvaluationRun(this.dbItem, evaluationRun);
|
this.modelingStore.updateModelEvaluationRun(this.dbItem, evaluationRun);
|
||||||
|
|
||||||
// For now, just wait 5 seconds and then update the store.
|
// Build pack
|
||||||
// In the future, this will be replaced with the actual evaluation process.
|
const qlPack = await resolveCodeScanningQueryPack(
|
||||||
void sleep(5000).then(() => {
|
this.logger,
|
||||||
const completedEvaluationRun: ModelEvaluationRun = {
|
this.cliServer,
|
||||||
isPreparing: false,
|
this.language,
|
||||||
variantAnalysisId: undefined,
|
);
|
||||||
};
|
|
||||||
this.modelingStore.updateModelEvaluationRun(
|
if (!qlPack) {
|
||||||
this.dbItem,
|
this.modelingStore.updateModelEvaluationRun(this.dbItem, undefined);
|
||||||
completedEvaluationRun,
|
throw new Error("Unable to trigger evaluation run");
|
||||||
);
|
}
|
||||||
});
|
|
||||||
|
// Submit variant analysis and monitor progress
|
||||||
|
return withProgress(
|
||||||
|
async (progress, token) => {
|
||||||
|
let variantAnalysisId: number | undefined = undefined;
|
||||||
|
try {
|
||||||
|
variantAnalysisId =
|
||||||
|
await this.variantAnalysisManager.runVariantAnalysis(
|
||||||
|
qlPack,
|
||||||
|
progress,
|
||||||
|
token,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
this.modelingStore.updateModelEvaluationRun(this.dbItem, undefined);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (variantAnalysisId) {
|
||||||
|
this.monitorVariantAnalysis(variantAnalysisId);
|
||||||
|
} else {
|
||||||
|
this.modelingStore.updateModelEvaluationRun(this.dbItem, undefined);
|
||||||
|
throw new Error(
|
||||||
|
"Unable to trigger variant analysis for evaluation run",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Run Variant Analysis",
|
||||||
|
cancellable: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async stopEvaluation() {
|
public async stopEvaluation() {
|
||||||
@@ -55,19 +95,51 @@ export class ModelEvaluator extends DisposableObject {
|
|||||||
private registerToModelingEvents() {
|
private registerToModelingEvents() {
|
||||||
this.push(
|
this.push(
|
||||||
this.modelingEvents.onModelEvaluationRunChanged(async (event) => {
|
this.modelingEvents.onModelEvaluationRunChanged(async (event) => {
|
||||||
if (
|
if (event.dbUri === this.dbItem.databaseUri.toString()) {
|
||||||
event.evaluationRun &&
|
if (!event.evaluationRun) {
|
||||||
event.dbUri === this.dbItem.databaseUri.toString()
|
await this.updateView({
|
||||||
) {
|
isPreparing: false,
|
||||||
const run: ModelEvaluationRunState = {
|
variantAnalysis: undefined,
|
||||||
isPreparing: event.evaluationRun.isPreparing,
|
});
|
||||||
|
} else {
|
||||||
// TODO: Get variant analysis from id.
|
const variantAnalysis = await this.getVariantAnalysisForRun(
|
||||||
variantAnalysis: undefined,
|
event.evaluationRun,
|
||||||
};
|
);
|
||||||
await this.updateView(run);
|
const run: ModelEvaluationRunState = {
|
||||||
|
isPreparing: event.evaluationRun.isPreparing,
|
||||||
|
variantAnalysis,
|
||||||
|
};
|
||||||
|
await this.updateView(run);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async getVariantAnalysisForRun(
|
||||||
|
evaluationRun: ModelEvaluationRun,
|
||||||
|
): Promise<VariantAnalysis | undefined> {
|
||||||
|
if (evaluationRun.variantAnalysisId) {
|
||||||
|
return await this.variantAnalysisManager.getVariantAnalysis(
|
||||||
|
evaluationRun.variantAnalysisId,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
private monitorVariantAnalysis(variantAnalysisId: number) {
|
||||||
|
this.push(
|
||||||
|
this.variantAnalysisManager.onVariantAnalysisStatusUpdated(
|
||||||
|
async (variantAnalysis) => {
|
||||||
|
// Make sure it's the variant analysis we're interested in
|
||||||
|
if (variantAnalysisId === variantAnalysis.id) {
|
||||||
|
await this.updateView({
|
||||||
|
isPreparing: false,
|
||||||
|
variantAnalysis,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,36 +8,39 @@
|
|||||||
"extensions": {
|
"extensions": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"type": "object",
|
"$ref": "#/definitions/ModelExtension"
|
||||||
"properties": {
|
|
||||||
"addsTo": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"pack": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"extensible": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": ["pack", "extensible"]
|
|
||||||
},
|
|
||||||
"data": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"$ref": "#/definitions/DataTuple"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": ["addsTo", "data"]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": ["extensions"]
|
"required": ["extensions"]
|
||||||
},
|
},
|
||||||
|
"ModelExtension": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"addsTo": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"pack": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"extensible": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["pack", "extensible"]
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/DataTuple"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["addsTo", "data"]
|
||||||
|
},
|
||||||
"DataTuple": {
|
"DataTuple": {
|
||||||
"type": ["boolean", "number", "string"]
|
"type": ["boolean", "number", "string"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ export type DataTuple = boolean | number | string;
|
|||||||
|
|
||||||
type DataRow = DataTuple[];
|
type DataRow = DataTuple[];
|
||||||
|
|
||||||
type ModelExtension = {
|
export type ModelExtension = {
|
||||||
addsTo: ExtensibleReference;
|
addsTo: ExtensibleReference;
|
||||||
data: DataRow[];
|
data: DataRow[];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -378,7 +378,7 @@ export class ModelingStore extends DisposableObject {
|
|||||||
|
|
||||||
public updateModelEvaluationRun(
|
public updateModelEvaluationRun(
|
||||||
dbItem: DatabaseItem,
|
dbItem: DatabaseItem,
|
||||||
evaluationRun: ModelEvaluationRun,
|
evaluationRun: ModelEvaluationRun | undefined,
|
||||||
) {
|
) {
|
||||||
this.changeModelEvaluationRun(dbItem, (state) => {
|
this.changeModelEvaluationRun(dbItem, (state) => {
|
||||||
state.modelEvaluationRun = evaluationRun;
|
state.modelEvaluationRun = evaluationRun;
|
||||||
|
|||||||
@@ -16,7 +16,10 @@ import type {
|
|||||||
import { getModelsAsDataLanguage } from "./languages";
|
import { getModelsAsDataLanguage } from "./languages";
|
||||||
import { Mode } from "./shared/mode";
|
import { Mode } from "./shared/mode";
|
||||||
import { assertNever } from "../common/helpers-pure";
|
import { assertNever } from "../common/helpers-pure";
|
||||||
import type { ModelExtensionFile } from "./model-extension-file";
|
import type {
|
||||||
|
ModelExtension,
|
||||||
|
ModelExtensionFile,
|
||||||
|
} from "./model-extension-file";
|
||||||
import type { QueryLanguage } from "../common/query-language";
|
import type { QueryLanguage } from "../common/query-language";
|
||||||
|
|
||||||
import modelExtensionFileSchema from "./model-extension-file.schema.json";
|
import modelExtensionFileSchema from "./model-extension-file.schema.json";
|
||||||
@@ -24,38 +27,22 @@ import modelExtensionFileSchema from "./model-extension-file.schema.json";
|
|||||||
const ajv = new Ajv({ allErrors: true, allowUnionTypes: true });
|
const ajv = new Ajv({ allErrors: true, allowUnionTypes: true });
|
||||||
const modelExtensionFileSchemaValidate = ajv.compile(modelExtensionFileSchema);
|
const modelExtensionFileSchemaValidate = ajv.compile(modelExtensionFileSchema);
|
||||||
|
|
||||||
function createDataProperty<T>(
|
|
||||||
methods: readonly T[],
|
|
||||||
definition: ModelsAsDataLanguagePredicate<T>,
|
|
||||||
) {
|
|
||||||
if (methods.length === 0) {
|
|
||||||
return " []";
|
|
||||||
}
|
|
||||||
|
|
||||||
return `\n${methods
|
|
||||||
.map(
|
|
||||||
(method) =>
|
|
||||||
` - ${JSON.stringify(
|
|
||||||
definition.generateMethodDefinition(method),
|
|
||||||
)}`,
|
|
||||||
)
|
|
||||||
.join("\n")}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function createExtensions<T>(
|
function createExtensions<T>(
|
||||||
language: QueryLanguage,
|
language: QueryLanguage,
|
||||||
methods: readonly T[],
|
methods: readonly T[],
|
||||||
definition: ModelsAsDataLanguagePredicate<T> | undefined,
|
definition: ModelsAsDataLanguagePredicate<T> | undefined,
|
||||||
) {
|
): ModelExtension | undefined {
|
||||||
if (!definition) {
|
if (!definition) {
|
||||||
return "";
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ` - addsTo:
|
return {
|
||||||
pack: codeql/${language}-all
|
addsTo: {
|
||||||
extensible: ${definition.extensiblePredicate}
|
pack: `codeql/${language}-all`,
|
||||||
data:${createDataProperty(methods, definition)}
|
extensible: definition.extensiblePredicate,
|
||||||
`;
|
},
|
||||||
|
data: methods.map((method) => definition.generateMethodDefinition(method)),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createDataExtensionYaml(
|
export function createDataExtensionYaml(
|
||||||
@@ -99,7 +86,7 @@ export function createDataExtensionYaml(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const extensions = Object.keys(methodsByType)
|
const extensions = Object.keys(methodsByType)
|
||||||
.map((typeKey) => {
|
.map((typeKey): ModelExtension | undefined => {
|
||||||
const type = typeKey as keyof ModelsAsDataLanguagePredicates;
|
const type = typeKey as keyof ModelsAsDataLanguagePredicates;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@@ -137,10 +124,11 @@ export function createDataExtensionYaml(
|
|||||||
assertNever(type);
|
assertNever(type);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter((extensions) => extensions !== "");
|
.filter(
|
||||||
|
(extension): extension is ModelExtension => extension !== undefined,
|
||||||
|
);
|
||||||
|
|
||||||
return `extensions:
|
return modelExtensionFileToYaml({ extensions });
|
||||||
${extensions.join("\n")}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createDataExtensionYamls(
|
export function createDataExtensionYamls(
|
||||||
@@ -341,6 +329,36 @@ function validateModelExtensionFile(data: unknown): data is ModelExtensionFile {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a string for the data extension YAML file from the
|
||||||
|
* structure of the data extension file. This should be used
|
||||||
|
* instead of creating a JSON string directly or dumping the
|
||||||
|
* YAML directly to ensure that the file is formatted correctly.
|
||||||
|
*
|
||||||
|
* @param data The data extension file
|
||||||
|
*/
|
||||||
|
function modelExtensionFileToYaml(data: ModelExtensionFile) {
|
||||||
|
const extensions = data.extensions
|
||||||
|
.map((extension) => {
|
||||||
|
const data =
|
||||||
|
extension.data.length === 0
|
||||||
|
? " []"
|
||||||
|
: `\n${extension.data
|
||||||
|
.map((row) => ` - ${JSON.stringify(row)}`)
|
||||||
|
.join("\n")}`;
|
||||||
|
|
||||||
|
return ` - addsTo:
|
||||||
|
pack: ${extension.addsTo.pack}
|
||||||
|
extensible: ${extension.addsTo.extensible}
|
||||||
|
data:${data}
|
||||||
|
`;
|
||||||
|
})
|
||||||
|
.filter((extensions) => extensions !== "");
|
||||||
|
|
||||||
|
return `extensions:
|
||||||
|
${extensions.join("\n")}`;
|
||||||
|
}
|
||||||
|
|
||||||
export function loadDataExtensionYaml(
|
export function loadDataExtensionYaml(
|
||||||
data: unknown,
|
data: unknown,
|
||||||
language: QueryLanguage,
|
language: QueryLanguage,
|
||||||
|
|||||||
@@ -298,7 +298,7 @@ export class VariantAnalysisManager
|
|||||||
qlPackDetails: QlPackDetails,
|
qlPackDetails: QlPackDetails,
|
||||||
progress: ProgressCallback,
|
progress: ProgressCallback,
|
||||||
token: CancellationToken,
|
token: CancellationToken,
|
||||||
): Promise<void> {
|
): Promise<number | undefined> {
|
||||||
await saveBeforeStart();
|
await saveBeforeStart();
|
||||||
|
|
||||||
progress({
|
progress({
|
||||||
@@ -379,7 +379,7 @@ export class VariantAnalysisManager
|
|||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
// If the error is handled by the handleRequestError function, we don't need to throw
|
// If the error is handled by the handleRequestError function, we don't need to throw
|
||||||
if (e instanceof RequestError && handleRequestError(e, this.app.logger)) {
|
if (e instanceof RequestError && handleRequestError(e, this.app.logger)) {
|
||||||
return;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw e;
|
throw e;
|
||||||
@@ -405,6 +405,8 @@ export class VariantAnalysisManager
|
|||||||
"codeQL.monitorNewVariantAnalysis",
|
"codeQL.monitorNewVariantAnalysis",
|
||||||
processedVariantAnalysis,
|
processedVariantAnalysis,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return processedVariantAnalysis.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async rehydrateVariantAnalysis(variantAnalysis: VariantAnalysis) {
|
public async rehydrateVariantAnalysis(variantAnalysis: VariantAnalysis) {
|
||||||
|
|||||||
@@ -10,33 +10,45 @@ import { MultipleModeledMethodsPanel } from "../MultipleModeledMethodsPanel";
|
|||||||
import { userEvent } from "@testing-library/user-event";
|
import { userEvent } from "@testing-library/user-event";
|
||||||
import type { ModeledMethod } from "../../../model-editor/modeled-method";
|
import type { ModeledMethod } from "../../../model-editor/modeled-method";
|
||||||
import { QueryLanguage } from "../../../common/query-language";
|
import { QueryLanguage } from "../../../common/query-language";
|
||||||
|
import type { ModelingStatus } from "../../../model-editor/shared/modeling-status";
|
||||||
|
|
||||||
describe(MultipleModeledMethodsPanel.name, () => {
|
describe(MultipleModeledMethodsPanel.name, () => {
|
||||||
const render = (props: MultipleModeledMethodsPanelProps) =>
|
|
||||||
reactRender(<MultipleModeledMethodsPanel {...props} />);
|
|
||||||
|
|
||||||
const language = QueryLanguage.Java;
|
const language = QueryLanguage.Java;
|
||||||
const isCanary = false;
|
|
||||||
const method = createMethod();
|
const method = createMethod();
|
||||||
const isModelingInProgress = false;
|
const isModelingInProgress = false;
|
||||||
const isProcessedByAutoModel = false;
|
const isProcessedByAutoModel = false;
|
||||||
const modelingStatus = "unmodeled";
|
const modelingStatus: ModelingStatus = "unmodeled";
|
||||||
const onChange = jest.fn<void, [string, ModeledMethod[]]>();
|
const onChange = jest.fn<void, [string, ModeledMethod[]]>();
|
||||||
|
const isCanary = false;
|
||||||
|
|
||||||
|
const baseProps = {
|
||||||
|
language,
|
||||||
|
method,
|
||||||
|
modelingStatus,
|
||||||
|
isModelingInProgress,
|
||||||
|
isCanary,
|
||||||
|
isProcessedByAutoModel,
|
||||||
|
onChange,
|
||||||
|
};
|
||||||
|
|
||||||
|
const createRender =
|
||||||
|
(modeledMethods: ModeledMethod[]) =>
|
||||||
|
(props: Partial<MultipleModeledMethodsPanelProps> = {}) =>
|
||||||
|
reactRender(
|
||||||
|
<MultipleModeledMethodsPanel
|
||||||
|
{...baseProps}
|
||||||
|
modeledMethods={modeledMethods}
|
||||||
|
{...props}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
|
||||||
describe("with no modeled methods", () => {
|
describe("with no modeled methods", () => {
|
||||||
const modeledMethods: ModeledMethod[] = [];
|
const modeledMethods: ModeledMethod[] = [];
|
||||||
|
|
||||||
|
const render = createRender(modeledMethods);
|
||||||
|
|
||||||
it("renders the method modeling inputs once", () => {
|
it("renders the method modeling inputs once", () => {
|
||||||
render({
|
render();
|
||||||
language,
|
|
||||||
isCanary,
|
|
||||||
method,
|
|
||||||
modeledMethods,
|
|
||||||
modelingStatus,
|
|
||||||
isModelingInProgress,
|
|
||||||
isProcessedByAutoModel,
|
|
||||||
onChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(screen.getAllByRole("combobox")).toHaveLength(4);
|
expect(screen.getAllByRole("combobox")).toHaveLength(4);
|
||||||
expect(
|
expect(
|
||||||
@@ -47,16 +59,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("disables all pagination", () => {
|
it("disables all pagination", () => {
|
||||||
render({
|
render();
|
||||||
language,
|
|
||||||
isCanary,
|
|
||||||
method,
|
|
||||||
modeledMethods,
|
|
||||||
modelingStatus,
|
|
||||||
isModelingInProgress,
|
|
||||||
isProcessedByAutoModel,
|
|
||||||
onChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
screen
|
screen
|
||||||
@@ -71,16 +74,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("cannot add or delete modeling", () => {
|
it("cannot add or delete modeling", () => {
|
||||||
render({
|
render();
|
||||||
language,
|
|
||||||
isCanary,
|
|
||||||
method,
|
|
||||||
modeledMethods,
|
|
||||||
modelingStatus,
|
|
||||||
isModelingInProgress,
|
|
||||||
isProcessedByAutoModel,
|
|
||||||
onChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
screen
|
screen
|
||||||
@@ -103,17 +97,10 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
|||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const render = createRender(modeledMethods);
|
||||||
|
|
||||||
it("renders the method modeling inputs once", () => {
|
it("renders the method modeling inputs once", () => {
|
||||||
render({
|
render();
|
||||||
language,
|
|
||||||
isCanary,
|
|
||||||
method,
|
|
||||||
modeledMethods,
|
|
||||||
modelingStatus,
|
|
||||||
isModelingInProgress,
|
|
||||||
isProcessedByAutoModel,
|
|
||||||
onChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(screen.getAllByRole("combobox")).toHaveLength(4);
|
expect(screen.getAllByRole("combobox")).toHaveLength(4);
|
||||||
expect(
|
expect(
|
||||||
@@ -124,16 +111,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("disables all pagination", () => {
|
it("disables all pagination", () => {
|
||||||
render({
|
render();
|
||||||
language,
|
|
||||||
isCanary,
|
|
||||||
method,
|
|
||||||
modeledMethods,
|
|
||||||
modelingStatus,
|
|
||||||
isModelingInProgress,
|
|
||||||
isProcessedByAutoModel,
|
|
||||||
onChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
screen
|
screen
|
||||||
@@ -147,16 +125,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("cannot delete modeling", () => {
|
it("cannot delete modeling", () => {
|
||||||
render({
|
render();
|
||||||
language,
|
|
||||||
isCanary,
|
|
||||||
method,
|
|
||||||
modeledMethods,
|
|
||||||
modelingStatus,
|
|
||||||
isModelingInProgress,
|
|
||||||
isProcessedByAutoModel,
|
|
||||||
onChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
screen
|
screen
|
||||||
@@ -166,16 +135,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("can add modeling", async () => {
|
it("can add modeling", async () => {
|
||||||
render({
|
render();
|
||||||
language,
|
|
||||||
isCanary,
|
|
||||||
method,
|
|
||||||
modeledMethods,
|
|
||||||
modelingStatus,
|
|
||||||
isModelingInProgress,
|
|
||||||
isProcessedByAutoModel,
|
|
||||||
onChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
await userEvent.click(screen.getByLabelText("Add modeling"));
|
await userEvent.click(screen.getByLabelText("Add modeling"));
|
||||||
|
|
||||||
@@ -194,31 +154,16 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("changes selection to the newly added modeling", async () => {
|
it("changes selection to the newly added modeling", async () => {
|
||||||
const { rerender } = render({
|
const { rerender } = render();
|
||||||
language,
|
|
||||||
isCanary,
|
|
||||||
method,
|
|
||||||
modeledMethods,
|
|
||||||
modelingStatus,
|
|
||||||
isModelingInProgress,
|
|
||||||
isProcessedByAutoModel,
|
|
||||||
onChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
await userEvent.click(screen.getByLabelText("Add modeling"));
|
await userEvent.click(screen.getByLabelText("Add modeling"));
|
||||||
|
|
||||||
rerender(
|
rerender(
|
||||||
<MultipleModeledMethodsPanel
|
<MultipleModeledMethodsPanel
|
||||||
language={language}
|
{...baseProps}
|
||||||
isCanary={isCanary}
|
|
||||||
method={method}
|
|
||||||
modeledMethods={
|
modeledMethods={
|
||||||
onChange.mock.calls[onChange.mock.calls.length - 1][1]
|
onChange.mock.calls[onChange.mock.calls.length - 1][1]
|
||||||
}
|
}
|
||||||
isModelingInProgress={isModelingInProgress}
|
|
||||||
isProcessedByAutoModel={isProcessedByAutoModel}
|
|
||||||
modelingStatus={modelingStatus}
|
|
||||||
onChange={onChange}
|
|
||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -236,17 +181,10 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
|||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const render = createRender(modeledMethods);
|
||||||
|
|
||||||
it("renders the method modeling inputs once", () => {
|
it("renders the method modeling inputs once", () => {
|
||||||
render({
|
render();
|
||||||
language,
|
|
||||||
isCanary,
|
|
||||||
method,
|
|
||||||
modeledMethods,
|
|
||||||
isModelingInProgress,
|
|
||||||
isProcessedByAutoModel,
|
|
||||||
modelingStatus,
|
|
||||||
onChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(screen.getAllByRole("combobox")).toHaveLength(4);
|
expect(screen.getAllByRole("combobox")).toHaveLength(4);
|
||||||
expect(
|
expect(
|
||||||
@@ -257,16 +195,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("renders the pagination", () => {
|
it("renders the pagination", () => {
|
||||||
render({
|
render();
|
||||||
language,
|
|
||||||
isCanary,
|
|
||||||
method,
|
|
||||||
modeledMethods,
|
|
||||||
isModelingInProgress,
|
|
||||||
isProcessedByAutoModel,
|
|
||||||
modelingStatus,
|
|
||||||
onChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(screen.getByLabelText("Previous modeling")).toBeInTheDocument();
|
expect(screen.getByLabelText("Previous modeling")).toBeInTheDocument();
|
||||||
expect(screen.getByLabelText("Next modeling")).toBeInTheDocument();
|
expect(screen.getByLabelText("Next modeling")).toBeInTheDocument();
|
||||||
@@ -274,16 +203,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("disables the correct pagination", async () => {
|
it("disables the correct pagination", async () => {
|
||||||
render({
|
render();
|
||||||
language,
|
|
||||||
isCanary,
|
|
||||||
method,
|
|
||||||
modeledMethods,
|
|
||||||
isModelingInProgress,
|
|
||||||
isProcessedByAutoModel,
|
|
||||||
modelingStatus,
|
|
||||||
onChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
screen
|
screen
|
||||||
@@ -296,16 +216,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("can use the pagination", async () => {
|
it("can use the pagination", async () => {
|
||||||
render({
|
render();
|
||||||
language,
|
|
||||||
isCanary,
|
|
||||||
method,
|
|
||||||
modeledMethods,
|
|
||||||
isModelingInProgress,
|
|
||||||
isProcessedByAutoModel,
|
|
||||||
modelingStatus,
|
|
||||||
onChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
await userEvent.click(screen.getByLabelText("Next modeling"));
|
await userEvent.click(screen.getByLabelText("Next modeling"));
|
||||||
|
|
||||||
@@ -335,29 +246,14 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("correctly updates selected pagination index when the number of models decreases", async () => {
|
it("correctly updates selected pagination index when the number of models decreases", async () => {
|
||||||
const { rerender } = render({
|
const { rerender } = render();
|
||||||
language,
|
|
||||||
isCanary,
|
|
||||||
method,
|
|
||||||
modeledMethods,
|
|
||||||
isModelingInProgress,
|
|
||||||
isProcessedByAutoModel,
|
|
||||||
modelingStatus,
|
|
||||||
onChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
await userEvent.click(screen.getByLabelText("Next modeling"));
|
await userEvent.click(screen.getByLabelText("Next modeling"));
|
||||||
|
|
||||||
rerender(
|
rerender(
|
||||||
<MultipleModeledMethodsPanel
|
<MultipleModeledMethodsPanel
|
||||||
language={language}
|
{...baseProps}
|
||||||
isCanary={isCanary}
|
|
||||||
method={method}
|
|
||||||
modeledMethods={[modeledMethods[1]]}
|
modeledMethods={[modeledMethods[1]]}
|
||||||
isModelingInProgress={isModelingInProgress}
|
|
||||||
isProcessedByAutoModel={isProcessedByAutoModel}
|
|
||||||
modelingStatus={modelingStatus}
|
|
||||||
onChange={onChange}
|
|
||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -370,31 +266,13 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("does not show errors", () => {
|
it("does not show errors", () => {
|
||||||
render({
|
render();
|
||||||
language,
|
|
||||||
isCanary,
|
|
||||||
method,
|
|
||||||
modeledMethods,
|
|
||||||
isModelingInProgress,
|
|
||||||
isProcessedByAutoModel,
|
|
||||||
modelingStatus,
|
|
||||||
onChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(screen.queryByRole("alert")).not.toBeInTheDocument();
|
expect(screen.queryByRole("alert")).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("can update the first modeling", async () => {
|
it("can update the first modeling", async () => {
|
||||||
render({
|
render();
|
||||||
language,
|
|
||||||
isCanary,
|
|
||||||
method,
|
|
||||||
modeledMethods,
|
|
||||||
isModelingInProgress,
|
|
||||||
isProcessedByAutoModel,
|
|
||||||
modelingStatus,
|
|
||||||
onChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
const modelTypeDropdown = screen.getByRole("combobox", {
|
const modelTypeDropdown = screen.getByRole("combobox", {
|
||||||
name: "Model type",
|
name: "Model type",
|
||||||
@@ -420,16 +298,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("can update the second modeling", async () => {
|
it("can update the second modeling", async () => {
|
||||||
render({
|
render();
|
||||||
language,
|
|
||||||
isCanary,
|
|
||||||
method,
|
|
||||||
modeledMethods,
|
|
||||||
isModelingInProgress,
|
|
||||||
isProcessedByAutoModel,
|
|
||||||
modelingStatus,
|
|
||||||
onChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
await userEvent.click(screen.getByLabelText("Next modeling"));
|
await userEvent.click(screen.getByLabelText("Next modeling"));
|
||||||
|
|
||||||
@@ -457,16 +326,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("can delete modeling", async () => {
|
it("can delete modeling", async () => {
|
||||||
render({
|
render();
|
||||||
language,
|
|
||||||
isCanary,
|
|
||||||
method,
|
|
||||||
modeledMethods,
|
|
||||||
isModelingInProgress,
|
|
||||||
isProcessedByAutoModel,
|
|
||||||
modelingStatus,
|
|
||||||
onChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
await userEvent.click(screen.getByLabelText("Delete modeling"));
|
await userEvent.click(screen.getByLabelText("Delete modeling"));
|
||||||
|
|
||||||
@@ -477,16 +337,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("can add modeling", async () => {
|
it("can add modeling", async () => {
|
||||||
render({
|
render();
|
||||||
language,
|
|
||||||
isCanary,
|
|
||||||
method,
|
|
||||||
modeledMethods,
|
|
||||||
isModelingInProgress,
|
|
||||||
isProcessedByAutoModel,
|
|
||||||
modelingStatus,
|
|
||||||
onChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
await userEvent.click(screen.getByLabelText("Add modeling"));
|
await userEvent.click(screen.getByLabelText("Add modeling"));
|
||||||
|
|
||||||
@@ -505,31 +356,16 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("shows an error when adding a neutral modeling", async () => {
|
it("shows an error when adding a neutral modeling", async () => {
|
||||||
const { rerender } = render({
|
const { rerender } = render();
|
||||||
language,
|
|
||||||
isCanary,
|
|
||||||
method,
|
|
||||||
modeledMethods,
|
|
||||||
isModelingInProgress,
|
|
||||||
isProcessedByAutoModel,
|
|
||||||
modelingStatus,
|
|
||||||
onChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
await userEvent.click(screen.getByLabelText("Add modeling"));
|
await userEvent.click(screen.getByLabelText("Add modeling"));
|
||||||
|
|
||||||
rerender(
|
rerender(
|
||||||
<MultipleModeledMethodsPanel
|
<MultipleModeledMethodsPanel
|
||||||
language={language}
|
{...baseProps}
|
||||||
isCanary={isCanary}
|
|
||||||
method={method}
|
|
||||||
modeledMethods={
|
modeledMethods={
|
||||||
onChange.mock.calls[onChange.mock.calls.length - 1][1]
|
onChange.mock.calls[onChange.mock.calls.length - 1][1]
|
||||||
}
|
}
|
||||||
isModelingInProgress={isModelingInProgress}
|
|
||||||
isProcessedByAutoModel={isProcessedByAutoModel}
|
|
||||||
modelingStatus={modelingStatus}
|
|
||||||
onChange={onChange}
|
|
||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -543,16 +379,10 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
|||||||
|
|
||||||
rerender(
|
rerender(
|
||||||
<MultipleModeledMethodsPanel
|
<MultipleModeledMethodsPanel
|
||||||
language={language}
|
{...baseProps}
|
||||||
isCanary={isCanary}
|
|
||||||
method={method}
|
|
||||||
modeledMethods={
|
modeledMethods={
|
||||||
onChange.mock.calls[onChange.mock.calls.length - 1][1]
|
onChange.mock.calls[onChange.mock.calls.length - 1][1]
|
||||||
}
|
}
|
||||||
isModelingInProgress={isModelingInProgress}
|
|
||||||
isProcessedByAutoModel={isProcessedByAutoModel}
|
|
||||||
modelingStatus={modelingStatus}
|
|
||||||
onChange={onChange}
|
|
||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -564,16 +394,10 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
|||||||
|
|
||||||
rerender(
|
rerender(
|
||||||
<MultipleModeledMethodsPanel
|
<MultipleModeledMethodsPanel
|
||||||
language={language}
|
{...baseProps}
|
||||||
isCanary={isCanary}
|
|
||||||
method={method}
|
|
||||||
modeledMethods={
|
modeledMethods={
|
||||||
onChange.mock.calls[onChange.mock.calls.length - 1][1]
|
onChange.mock.calls[onChange.mock.calls.length - 1][1]
|
||||||
}
|
}
|
||||||
isModelingInProgress={isModelingInProgress}
|
|
||||||
isProcessedByAutoModel={isProcessedByAutoModel}
|
|
||||||
modelingStatus={modelingStatus}
|
|
||||||
onChange={onChange}
|
|
||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -584,16 +408,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("changes selection to the newly added modeling", async () => {
|
it("changes selection to the newly added modeling", async () => {
|
||||||
const { rerender } = render({
|
const { rerender } = render();
|
||||||
language,
|
|
||||||
isCanary,
|
|
||||||
method,
|
|
||||||
modeledMethods,
|
|
||||||
isModelingInProgress,
|
|
||||||
isProcessedByAutoModel,
|
|
||||||
modelingStatus,
|
|
||||||
onChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(screen.getByText("1/2")).toBeInTheDocument();
|
expect(screen.getByText("1/2")).toBeInTheDocument();
|
||||||
|
|
||||||
@@ -601,16 +416,10 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
|||||||
|
|
||||||
rerender(
|
rerender(
|
||||||
<MultipleModeledMethodsPanel
|
<MultipleModeledMethodsPanel
|
||||||
language={language}
|
{...baseProps}
|
||||||
isCanary={isCanary}
|
|
||||||
method={method}
|
|
||||||
modeledMethods={
|
modeledMethods={
|
||||||
onChange.mock.calls[onChange.mock.calls.length - 1][1]
|
onChange.mock.calls[onChange.mock.calls.length - 1][1]
|
||||||
}
|
}
|
||||||
isModelingInProgress={isModelingInProgress}
|
|
||||||
isProcessedByAutoModel={isProcessedByAutoModel}
|
|
||||||
modelingStatus={modelingStatus}
|
|
||||||
onChange={onChange}
|
|
||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -637,17 +446,10 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
|||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const render = createRender(modeledMethods);
|
||||||
|
|
||||||
it("can use the pagination", async () => {
|
it("can use the pagination", async () => {
|
||||||
render({
|
render();
|
||||||
language,
|
|
||||||
isCanary,
|
|
||||||
method,
|
|
||||||
modeledMethods,
|
|
||||||
isModelingInProgress,
|
|
||||||
isProcessedByAutoModel,
|
|
||||||
modelingStatus,
|
|
||||||
onChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
screen
|
screen
|
||||||
@@ -731,29 +533,14 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("preserves selection when a modeling other than the selected modeling is removed", async () => {
|
it("preserves selection when a modeling other than the selected modeling is removed", async () => {
|
||||||
const { rerender } = render({
|
const { rerender } = render();
|
||||||
language,
|
|
||||||
isCanary,
|
|
||||||
method,
|
|
||||||
modeledMethods,
|
|
||||||
isModelingInProgress,
|
|
||||||
isProcessedByAutoModel,
|
|
||||||
modelingStatus,
|
|
||||||
onChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(screen.getByText("1/3")).toBeInTheDocument();
|
expect(screen.getByText("1/3")).toBeInTheDocument();
|
||||||
|
|
||||||
rerender(
|
rerender(
|
||||||
<MultipleModeledMethodsPanel
|
<MultipleModeledMethodsPanel
|
||||||
language={language}
|
{...baseProps}
|
||||||
isCanary={isCanary}
|
|
||||||
method={method}
|
|
||||||
modeledMethods={modeledMethods.slice(0, 2)}
|
modeledMethods={modeledMethods.slice(0, 2)}
|
||||||
isModelingInProgress={isModelingInProgress}
|
|
||||||
isProcessedByAutoModel={isProcessedByAutoModel}
|
|
||||||
modelingStatus={modelingStatus}
|
|
||||||
onChange={onChange}
|
|
||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -761,16 +548,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("reduces selection when the selected modeling is removed", async () => {
|
it("reduces selection when the selected modeling is removed", async () => {
|
||||||
const { rerender } = render({
|
const { rerender } = render();
|
||||||
language,
|
|
||||||
isCanary,
|
|
||||||
method,
|
|
||||||
modeledMethods,
|
|
||||||
isModelingInProgress,
|
|
||||||
isProcessedByAutoModel,
|
|
||||||
modelingStatus,
|
|
||||||
onChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
await userEvent.click(screen.getByLabelText("Next modeling"));
|
await userEvent.click(screen.getByLabelText("Next modeling"));
|
||||||
await userEvent.click(screen.getByLabelText("Next modeling"));
|
await userEvent.click(screen.getByLabelText("Next modeling"));
|
||||||
@@ -778,14 +556,8 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
|||||||
|
|
||||||
rerender(
|
rerender(
|
||||||
<MultipleModeledMethodsPanel
|
<MultipleModeledMethodsPanel
|
||||||
language={language}
|
{...baseProps}
|
||||||
isCanary={isCanary}
|
|
||||||
method={method}
|
|
||||||
modeledMethods={modeledMethods.slice(0, 2)}
|
modeledMethods={modeledMethods.slice(0, 2)}
|
||||||
isModelingInProgress={isModelingInProgress}
|
|
||||||
isProcessedByAutoModel={isProcessedByAutoModel}
|
|
||||||
modelingStatus={modelingStatus}
|
|
||||||
onChange={onChange}
|
|
||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -806,17 +578,10 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
|||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const render = createRender(modeledMethods);
|
||||||
|
|
||||||
it("can add modeling", () => {
|
it("can add modeling", () => {
|
||||||
render({
|
render();
|
||||||
language,
|
|
||||||
isCanary,
|
|
||||||
method,
|
|
||||||
modeledMethods,
|
|
||||||
isModelingInProgress,
|
|
||||||
isProcessedByAutoModel,
|
|
||||||
modelingStatus,
|
|
||||||
onChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
screen.getByLabelText("Add modeling").getElementsByTagName("input")[0],
|
screen.getByLabelText("Add modeling").getElementsByTagName("input")[0],
|
||||||
@@ -824,16 +589,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("can delete first modeling", async () => {
|
it("can delete first modeling", async () => {
|
||||||
render({
|
render();
|
||||||
language,
|
|
||||||
isCanary,
|
|
||||||
method,
|
|
||||||
modeledMethods,
|
|
||||||
isModelingInProgress,
|
|
||||||
isProcessedByAutoModel,
|
|
||||||
modelingStatus,
|
|
||||||
onChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
await userEvent.click(screen.getByLabelText("Delete modeling"));
|
await userEvent.click(screen.getByLabelText("Delete modeling"));
|
||||||
|
|
||||||
@@ -844,16 +600,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("can delete second modeling", async () => {
|
it("can delete second modeling", async () => {
|
||||||
render({
|
render();
|
||||||
language,
|
|
||||||
isCanary,
|
|
||||||
method,
|
|
||||||
modeledMethods,
|
|
||||||
isModelingInProgress,
|
|
||||||
isProcessedByAutoModel,
|
|
||||||
modelingStatus,
|
|
||||||
onChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
await userEvent.click(screen.getByLabelText("Next modeling"));
|
await userEvent.click(screen.getByLabelText("Next modeling"));
|
||||||
await userEvent.click(screen.getByLabelText("Delete modeling"));
|
await userEvent.click(screen.getByLabelText("Delete modeling"));
|
||||||
@@ -865,16 +612,7 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("can add modeling after deleting second modeling", async () => {
|
it("can add modeling after deleting second modeling", async () => {
|
||||||
const { rerender } = render({
|
const { rerender } = render();
|
||||||
language,
|
|
||||||
isCanary,
|
|
||||||
method,
|
|
||||||
modeledMethods,
|
|
||||||
isModelingInProgress,
|
|
||||||
isProcessedByAutoModel,
|
|
||||||
modelingStatus,
|
|
||||||
onChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
await userEvent.click(screen.getByLabelText("Next modeling"));
|
await userEvent.click(screen.getByLabelText("Next modeling"));
|
||||||
await userEvent.click(screen.getByLabelText("Delete modeling"));
|
await userEvent.click(screen.getByLabelText("Delete modeling"));
|
||||||
@@ -886,14 +624,8 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
|||||||
|
|
||||||
rerender(
|
rerender(
|
||||||
<MultipleModeledMethodsPanel
|
<MultipleModeledMethodsPanel
|
||||||
language={language}
|
{...baseProps}
|
||||||
isCanary={isCanary}
|
|
||||||
method={method}
|
|
||||||
modeledMethods={modeledMethods.slice(0, 1)}
|
modeledMethods={modeledMethods.slice(0, 1)}
|
||||||
isModelingInProgress={isModelingInProgress}
|
|
||||||
isProcessedByAutoModel={isProcessedByAutoModel}
|
|
||||||
modelingStatus={modelingStatus}
|
|
||||||
onChange={onChange}
|
|
||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -925,32 +657,16 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
|||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const render = createRender(modeledMethods);
|
||||||
|
|
||||||
it("shows errors", () => {
|
it("shows errors", () => {
|
||||||
render({
|
render();
|
||||||
language,
|
|
||||||
isCanary,
|
|
||||||
method,
|
|
||||||
modeledMethods,
|
|
||||||
isModelingInProgress,
|
|
||||||
isProcessedByAutoModel,
|
|
||||||
modelingStatus,
|
|
||||||
onChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(screen.getByRole("alert")).toBeInTheDocument();
|
expect(screen.getByRole("alert")).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("shows the correct error message", async () => {
|
it("shows the correct error message", async () => {
|
||||||
render({
|
render();
|
||||||
language,
|
|
||||||
isCanary,
|
|
||||||
method,
|
|
||||||
modeledMethods,
|
|
||||||
isModelingInProgress,
|
|
||||||
isProcessedByAutoModel,
|
|
||||||
modelingStatus,
|
|
||||||
onChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
screen.getByText("Error: Duplicated classification"),
|
screen.getByText("Error: Duplicated classification"),
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
[
|
[
|
||||||
|
"v2.16.3",
|
||||||
"v2.16.2",
|
"v2.16.2",
|
||||||
"v2.15.5",
|
"v2.15.5",
|
||||||
"v2.14.6",
|
"v2.14.6",
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { createMockModelingStore } from "../../../__mocks__/model-editor/modelin
|
|||||||
import type { ModelConfigListener } from "../../../../src/config";
|
import type { ModelConfigListener } from "../../../../src/config";
|
||||||
import { createMockModelingEvents } from "../../../__mocks__/model-editor/modelingEventsMock";
|
import { createMockModelingEvents } from "../../../__mocks__/model-editor/modelingEventsMock";
|
||||||
import { QueryLanguage } from "../../../../src/common/query-language";
|
import { QueryLanguage } from "../../../../src/common/query-language";
|
||||||
|
import type { VariantAnalysisManager } from "../../../../src/variant-analysis/variant-analysis-manager";
|
||||||
|
|
||||||
describe("ModelEditorView", () => {
|
describe("ModelEditorView", () => {
|
||||||
const app = createMockApp({});
|
const app = createMockApp({});
|
||||||
@@ -21,6 +22,7 @@ describe("ModelEditorView", () => {
|
|||||||
onDidChangeConfiguration: jest.fn(),
|
onDidChangeConfiguration: jest.fn(),
|
||||||
});
|
});
|
||||||
const databaseManager = mockEmptyDatabaseManager();
|
const databaseManager = mockEmptyDatabaseManager();
|
||||||
|
const variantAnalysisManager = mockedObject<VariantAnalysisManager>({});
|
||||||
const cliServer = mockedObject<CodeQLCliServer>({});
|
const cliServer = mockedObject<CodeQLCliServer>({});
|
||||||
const queryRunner = mockedObject<QueryRunner>({});
|
const queryRunner = mockedObject<QueryRunner>({});
|
||||||
const queryStorageDir = "/a/b/c/d";
|
const queryStorageDir = "/a/b/c/d";
|
||||||
@@ -48,6 +50,7 @@ describe("ModelEditorView", () => {
|
|||||||
modelingEvents,
|
modelingEvents,
|
||||||
modelConfig,
|
modelConfig,
|
||||||
databaseManager,
|
databaseManager,
|
||||||
|
variantAnalysisManager,
|
||||||
cliServer,
|
cliServer,
|
||||||
queryRunner,
|
queryRunner,
|
||||||
queryStorageDir,
|
queryStorageDir,
|
||||||
|
|||||||
Reference in New Issue
Block a user