Merge branch 'main' into shati-patel/run-query-context-menu-local

This commit is contained in:
Shati Patel
2023-06-26 16:46:24 +01:00
committed by GitHub
15 changed files with 340 additions and 272 deletions

View File

@@ -503,7 +503,11 @@
}, },
{ {
"command": "codeQLQueries.runLocalQueryFromQueriesPanel", "command": "codeQLQueries.runLocalQueryFromQueriesPanel",
"title": "Run local query", "title": "Run local query"
},
{
"command": "codeQL.runLocalQueryFromFileTab",
"title": "CodeQL: Run local query",
"icon": "$(run)" "icon": "$(run)"
}, },
{ {
@@ -881,6 +885,13 @@
} }
], ],
"menus": { "menus": {
"editor/title": [
{
"command": "codeQL.runLocalQueryFromFileTab",
"group": "navigation",
"when": "config.codeQL.queriesPanel && resourceExtname == .ql && codeQL.currentDatabaseItem"
}
],
"view/title": [ "view/title": [
{ {
"command": "codeQLDatabases.sortByName", "command": "codeQLDatabases.sortByName",
@@ -1177,6 +1188,10 @@
"command": "codeQLQueries.runLocalQueryFromQueriesPanel", "command": "codeQLQueries.runLocalQueryFromQueriesPanel",
"when": "false" "when": "false"
}, },
{
"command": "codeQL.runLocalQueryFromFileTab",
"when": "false"
},
{ {
"command": "codeQL.runQueryContextEditor", "command": "codeQL.runQueryContextEditor",
"when": "false" "when": "false"

View File

@@ -132,6 +132,7 @@ export type LocalQueryCommands = {
) => Promise<void>; ) => Promise<void>;
"codeQLQueries.runLocalQueryFromQueriesPanel": TreeViewContextSingleSelectionCommandFunction<QueryTreeViewItem>; "codeQLQueries.runLocalQueryFromQueriesPanel": TreeViewContextSingleSelectionCommandFunction<QueryTreeViewItem>;
"codeQLQueries.runLocalQueryContextMenu": TreeViewContextSingleSelectionCommandFunction<QueryTreeViewItem>; "codeQLQueries.runLocalQueryContextMenu": TreeViewContextSingleSelectionCommandFunction<QueryTreeViewItem>;
"codeQL.runLocalQueryFromFileTab": (uri: Uri) => Promise<void>;
"codeQL.runQueries": ExplorerSelectionCommandFunction<Uri>; "codeQL.runQueries": ExplorerSelectionCommandFunction<Uri>;
"codeQL.quickEval": (uri: Uri) => Promise<void>; "codeQL.quickEval": (uri: Uri) => Promise<void>;
"codeQL.quickEvalContextEditor": (uri: Uri) => Promise<void>; "codeQL.quickEvalContextEditor": (uri: Uri) => Promise<void>;

View File

@@ -7,6 +7,8 @@ import {
ModelRequest, ModelRequest,
} from "./auto-model-api"; } from "./auto-model-api";
import type { UsageSnippetsBySignature } from "./auto-model-usages-query"; import type { UsageSnippetsBySignature } from "./auto-model-usages-query";
import { groupMethods, sortGroupNames, sortMethods } from "./shared/sorting";
import { Mode } from "./shared/mode";
// Soft limit on the number of candidates to send to the model. // Soft limit on the number of candidates to send to the model.
// Note that the model may return fewer than this number of candidates. // Note that the model may return fewer than this number of candidates.
@@ -19,6 +21,7 @@ export function createAutoModelRequest(
externalApiUsages: ExternalApiUsage[], externalApiUsages: ExternalApiUsage[],
modeledMethods: Record<string, ModeledMethod>, modeledMethods: Record<string, ModeledMethod>,
usages: UsageSnippetsBySignature, usages: UsageSnippetsBySignature,
mode: Mode,
): ModelRequest { ): ModelRequest {
const request: ModelRequest = { const request: ModelRequest = {
language, language,
@@ -26,11 +29,14 @@ export function createAutoModelRequest(
candidates: [], candidates: [],
}; };
// Sort by number of usages so we always send the most used methods first // Sort the same way as the UI so we send the first ones listed in the UI first
externalApiUsages = [...externalApiUsages]; const grouped = groupMethods(externalApiUsages, mode);
externalApiUsages.sort((a, b) => b.usages.length - a.usages.length); const sortedGroupNames = sortGroupNames(grouped);
const sortedExternalApiUsages = sortedGroupNames.flatMap((name) =>
sortMethods(grouped[name]),
);
for (const externalApiUsage of externalApiUsages) { for (const externalApiUsage of sortedExternalApiUsages) {
const modeledMethod: ModeledMethod = modeledMethods[ const modeledMethod: ModeledMethod = modeledMethods[
externalApiUsage.signature externalApiUsage.signature
] ?? { ] ?? {

View File

@@ -457,6 +457,7 @@ export class DataExtensionsEditorView extends AbstractWebview<
externalApiUsages, externalApiUsages,
modeledMethods, modeledMethods,
usages, usages,
this.mode,
); );
await this.showProgress({ await this.showProgress({

View File

@@ -1,4 +1,4 @@
import { ExternalApiUsage } from "../../data-extensions-editor/external-api-usage"; import { ExternalApiUsage } from "../external-api-usage";
export function calculateModeledPercentage( export function calculateModeledPercentage(
externalApiUsages: Array<Pick<ExternalApiUsage, "supported">>, externalApiUsages: Array<Pick<ExternalApiUsage, "supported">>,

View File

@@ -0,0 +1,88 @@
import { ExternalApiUsage } from "../external-api-usage";
import { Mode } from "./mode";
import { calculateModeledPercentage } from "./modeled-percentage";
export function groupMethods(
externalApiUsages: ExternalApiUsage[],
mode: Mode,
): Record<string, ExternalApiUsage[]> {
const groupedByLibrary: Record<string, ExternalApiUsage[]> = {};
for (const externalApiUsage of externalApiUsages) {
// Group by package if using framework mode
const key =
mode === Mode.Framework
? externalApiUsage.packageName
: externalApiUsage.library;
groupedByLibrary[key] ??= [];
groupedByLibrary[key].push(externalApiUsage);
}
return groupedByLibrary;
}
export function sortGroupNames(
methods: Record<string, ExternalApiUsage[]>,
): string[] {
return Object.keys(methods).sort((a, b) =>
compareGroups(methods[a], a, methods[b], b),
);
}
export function sortMethods(
externalApiUsages: ExternalApiUsage[],
): ExternalApiUsage[] {
const sortedExternalApiUsages = [...externalApiUsages];
sortedExternalApiUsages.sort((a, b) => compareMethod(a, b));
return sortedExternalApiUsages;
}
function compareGroups(
a: ExternalApiUsage[],
aName: string,
b: ExternalApiUsage[],
bName: string,
): number {
const supportedPercentageA = calculateModeledPercentage(a);
const supportedPercentageB = calculateModeledPercentage(b);
// Sort first by supported percentage ascending
if (supportedPercentageA > supportedPercentageB) {
return 1;
}
if (supportedPercentageA < supportedPercentageB) {
return -1;
}
const numberOfUsagesA = a.reduce((acc, curr) => acc + curr.usages.length, 0);
const numberOfUsagesB = b.reduce((acc, curr) => acc + curr.usages.length, 0);
// If the number of usages is equal, sort by number of methods descending
if (numberOfUsagesA === numberOfUsagesB) {
const numberOfMethodsA = a.length;
const numberOfMethodsB = b.length;
// If the number of methods is equal, sort by library name ascending
if (numberOfMethodsA === numberOfMethodsB) {
return aName.localeCompare(bName);
}
return numberOfMethodsB - numberOfMethodsA;
}
// Then sort by number of usages descending
return numberOfUsagesB - numberOfUsagesA;
}
function compareMethod(a: ExternalApiUsage, b: ExternalApiUsage): number {
// Sort first by supported, putting unmodeled methods first.
if (a.supported && !b.supported) {
return 1;
}
if (!a.supported && b.supported) {
return -1;
}
// Then sort by number of usages descending
return b.usages.length - a.usages.length;
}

View File

@@ -105,6 +105,7 @@ export class LocalQueries extends DisposableObject {
this.runQueryFromQueriesPanel.bind(this), this.runQueryFromQueriesPanel.bind(this),
"codeQLQueries.runLocalQueryContextMenu": "codeQLQueries.runLocalQueryContextMenu":
this.runQueryFromQueriesPanel.bind(this), this.runQueryFromQueriesPanel.bind(this),
"codeQL.runLocalQueryFromFileTab": this.runQuery.bind(this),
"codeQL.runQueries": createMultiSelectionCommand( "codeQL.runQueries": createMultiSelectionCommand(
this.runQueries.bind(this), this.runQueries.bind(this),
), ),

View File

@@ -10,7 +10,7 @@ import { ExternalApiUsage } from "../../data-extensions-editor/external-api-usag
import { ModeledMethod } from "../../data-extensions-editor/modeled-method"; import { ModeledMethod } from "../../data-extensions-editor/modeled-method";
import { assertNever } from "../../common/helpers-pure"; import { assertNever } from "../../common/helpers-pure";
import { vscode } from "../vscode-api"; import { vscode } from "../vscode-api";
import { calculateModeledPercentage } from "./modeled"; import { calculateModeledPercentage } from "../../data-extensions-editor/shared/modeled-percentage";
import { LinkIconButton } from "../variant-analysis/LinkIconButton"; import { LinkIconButton } from "../variant-analysis/LinkIconButton";
import { ViewTitle } from "../common"; import { ViewTitle } from "../common";
import { DataExtensionEditorViewState } from "../../data-extensions-editor/shared/view-state"; import { DataExtensionEditorViewState } from "../../data-extensions-editor/shared/view-state";

View File

@@ -5,7 +5,7 @@ import { ExternalApiUsage } from "../../data-extensions-editor/external-api-usag
import { ModeledMethod } from "../../data-extensions-editor/modeled-method"; import { ModeledMethod } from "../../data-extensions-editor/modeled-method";
import { pluralize } from "../../common/word"; import { pluralize } from "../../common/word";
import { ModeledMethodDataGrid } from "./ModeledMethodDataGrid"; import { ModeledMethodDataGrid } from "./ModeledMethodDataGrid";
import { calculateModeledPercentage } from "./modeled"; import { calculateModeledPercentage } from "../../data-extensions-editor/shared/modeled-percentage";
import { decimalFormatter, percentFormatter } from "./formatters"; import { decimalFormatter, percentFormatter } from "./formatters";
import { Codicon } from "../common"; import { Codicon } from "../common";
import { Mode } from "../../data-extensions-editor/shared/mode"; import { Mode } from "../../data-extensions-editor/shared/mode";

View File

@@ -9,6 +9,7 @@ import { ExternalApiUsage } from "../../data-extensions-editor/external-api-usag
import { ModeledMethod } from "../../data-extensions-editor/modeled-method"; import { ModeledMethod } from "../../data-extensions-editor/modeled-method";
import { useMemo } from "react"; import { useMemo } from "react";
import { Mode } from "../../data-extensions-editor/shared/mode"; import { Mode } from "../../data-extensions-editor/shared/mode";
import { sortMethods } from "../../data-extensions-editor/shared/sorting";
type Props = { type Props = {
externalApiUsages: ExternalApiUsage[]; externalApiUsages: ExternalApiUsage[];
@@ -26,21 +27,10 @@ export const ModeledMethodDataGrid = ({
mode, mode,
onChange, onChange,
}: Props) => { }: Props) => {
const sortedExternalApiUsages = useMemo(() => { const sortedExternalApiUsages = useMemo(
const sortedExternalApiUsages = [...externalApiUsages]; () => sortMethods(externalApiUsages),
sortedExternalApiUsages.sort((a, b) => { [externalApiUsages],
// Sort first by supported, putting unmodeled methods first. );
if (a.supported && !b.supported) {
return 1;
}
if (!a.supported && b.supported) {
return -1;
}
// Then sort by number of usages descending
return b.usages.length - a.usages.length;
});
return sortedExternalApiUsages;
}, [externalApiUsages]);
return ( return (
<VSCodeDataGrid> <VSCodeDataGrid>

View File

@@ -2,9 +2,12 @@ import * as React from "react";
import { useMemo } from "react"; import { useMemo } from "react";
import { ExternalApiUsage } from "../../data-extensions-editor/external-api-usage"; import { ExternalApiUsage } from "../../data-extensions-editor/external-api-usage";
import { ModeledMethod } from "../../data-extensions-editor/modeled-method"; import { ModeledMethod } from "../../data-extensions-editor/modeled-method";
import { calculateModeledPercentage } from "./modeled";
import { LibraryRow } from "./LibraryRow"; import { LibraryRow } from "./LibraryRow";
import { Mode } from "../../data-extensions-editor/shared/mode"; import { Mode } from "../../data-extensions-editor/shared/mode";
import {
groupMethods,
sortGroupNames,
} from "../../data-extensions-editor/shared/sorting";
type Props = { type Props = {
externalApiUsages: ExternalApiUsage[]; externalApiUsages: ExternalApiUsage[];
@@ -22,62 +25,12 @@ export const ModeledMethodsList = ({
mode, mode,
onChange, onChange,
}: Props) => { }: Props) => {
const grouped = useMemo(() => { const grouped = useMemo(
const groupedByLibrary: Record<string, ExternalApiUsage[]> = {}; () => groupMethods(externalApiUsages, mode),
[externalApiUsages, mode],
);
for (const externalApiUsage of externalApiUsages) { const sortedGroupNames = useMemo(() => sortGroupNames(grouped), [grouped]);
// Group by package if using framework mode
const key =
mode === Mode.Framework
? externalApiUsage.packageName
: externalApiUsage.library;
groupedByLibrary[key] ??= [];
groupedByLibrary[key].push(externalApiUsage);
}
return groupedByLibrary;
}, [externalApiUsages, mode]);
const sortedGroupNames = useMemo(() => {
return Object.keys(grouped).sort((a, b) => {
const supportedPercentageA = calculateModeledPercentage(grouped[a]);
const supportedPercentageB = calculateModeledPercentage(grouped[b]);
// Sort first by supported percentage ascending
if (supportedPercentageA > supportedPercentageB) {
return 1;
}
if (supportedPercentageA < supportedPercentageB) {
return -1;
}
const numberOfUsagesA = grouped[a].reduce(
(acc, curr) => acc + curr.usages.length,
0,
);
const numberOfUsagesB = grouped[b].reduce(
(acc, curr) => acc + curr.usages.length,
0,
);
// If the number of usages is equal, sort by number of methods descending
if (numberOfUsagesA === numberOfUsagesB) {
const numberOfMethodsA = grouped[a].length;
const numberOfMethodsB = grouped[b].length;
// If the number of methods is equal, sort by library name ascending
if (numberOfMethodsA === numberOfMethodsB) {
return a.localeCompare(b);
}
return numberOfMethodsB - numberOfMethodsA;
}
// Then sort by number of usages descending
return numberOfUsagesB - numberOfUsagesA;
});
}, [grouped]);
return ( return (
<> <>

View File

@@ -1,6 +1,6 @@
import * as React from "react"; import * as React from "react";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { import {
ResultTableProps,
className, className,
emptyQueryResultsMessage, emptyQueryResultsMessage,
jumpToLocation, jumpToLocation,
@@ -19,158 +19,158 @@ import { onNavigation } from "./results";
import { tryGetResolvableLocation } from "../../common/bqrs-utils"; import { tryGetResolvableLocation } from "../../common/bqrs-utils";
import { ScrollIntoViewHelper } from "./scroll-into-view-helper"; import { ScrollIntoViewHelper } from "./scroll-into-view-helper";
import { sendTelemetry } from "../common/telemetry"; import { sendTelemetry } from "../common/telemetry";
import { assertNever } from "../../common/helpers-pure";
export type RawTableProps = ResultTableProps & { export type RawTableProps = {
databaseUri: string;
resultSet: RawTableResultSet; resultSet: RawTableResultSet;
sortState?: RawResultsSortState; sortState?: RawResultsSortState;
offset: number; offset: number;
}; };
interface RawTableState { interface TableItem {
selectedItem?: { row: number; column: number }; readonly row: number;
readonly column: number;
} }
export class RawTable extends React.Component<RawTableProps, RawTableState> { export function RawTable({
private scroller = new ScrollIntoViewHelper(); databaseUri,
resultSet,
sortState,
offset,
}: RawTableProps) {
const [selectedItem, setSelectedItem] = useState<TableItem | undefined>();
constructor(props: RawTableProps) { const scroller = useRef<ScrollIntoViewHelper | undefined>(undefined);
super(props); if (scroller.current === undefined) {
this.setSelection = this.setSelection.bind(this); scroller.current = new ScrollIntoViewHelper();
this.handleNavigationEvent = this.handleNavigationEvent.bind(this);
this.state = {};
} }
useEffect(() => scroller.current?.update());
private setSelection(row: number, column: number) { const setSelection = useCallback((row: number, column: number): void => {
this.setState((prev) => ({ setSelectedItem({ row, column });
...prev,
selectedItem: { row, column },
}));
sendTelemetry("local-results-raw-results-table-selected"); sendTelemetry("local-results-raw-results-table-selected");
}, []);
const navigateWithDelta = useCallback(
(rowDelta: number, columnDelta: number): void => {
setSelectedItem((prevSelectedItem) => {
const numberOfAlerts = resultSet.rows.length;
if (numberOfAlerts === 0) {
return prevSelectedItem;
}
const currentRow = prevSelectedItem?.row;
const nextRow = currentRow === undefined ? 0 : currentRow + rowDelta;
if (nextRow < 0 || nextRow >= numberOfAlerts) {
return prevSelectedItem;
}
const currentColumn = prevSelectedItem?.column;
const nextColumn =
currentColumn === undefined ? 0 : currentColumn + columnDelta;
// Jump to the location of the new cell
const rowData = resultSet.rows[nextRow];
if (nextColumn < 0 || nextColumn >= rowData.length) {
return prevSelectedItem;
}
const cellData = rowData[nextColumn];
if (cellData != null && typeof cellData === "object") {
const location = tryGetResolvableLocation(cellData.url);
if (location !== undefined) {
jumpToLocation(location, databaseUri);
}
}
scroller.current?.scrollIntoViewOnNextUpdate();
return { row: nextRow, column: nextColumn };
});
},
[databaseUri, resultSet, scroller],
);
const handleNavigationEvent = useCallback(
(event: NavigateMsg) => {
switch (event.direction) {
case NavigationDirection.up: {
navigateWithDelta(-1, 0);
break;
}
case NavigationDirection.down: {
navigateWithDelta(1, 0);
break;
}
case NavigationDirection.left: {
navigateWithDelta(0, -1);
break;
}
case NavigationDirection.right: {
navigateWithDelta(0, 1);
break;
}
default:
assertNever(event.direction);
}
},
[navigateWithDelta],
);
useEffect(() => {
onNavigation.addListener(handleNavigationEvent);
return () => {
onNavigation.removeListener(handleNavigationEvent);
};
}, [handleNavigationEvent]);
const [dataRows, numTruncatedResults] = useMemo(() => {
if (resultSet.rows.length <= RAW_RESULTS_LIMIT) {
return [resultSet.rows, 0];
}
return [
resultSet.rows.slice(0, RAW_RESULTS_LIMIT),
resultSet.rows.length - RAW_RESULTS_LIMIT,
];
}, [resultSet]);
if (dataRows.length === 0) {
return emptyQueryResultsMessage();
} }
render(): React.ReactNode { const tableRows = dataRows.map((row: ResultRow, rowIndex: number) => (
const { resultSet, databaseUri } = this.props; <RawTableRow
key={rowIndex}
rowIndex={rowIndex + offset}
row={row}
databaseUri={databaseUri}
selectedColumn={
selectedItem?.row === rowIndex ? selectedItem?.column : undefined
}
onSelected={setSelection}
scroller={scroller.current}
/>
));
let dataRows = resultSet.rows; if (numTruncatedResults > 0) {
if (dataRows.length === 0) { const colSpan = dataRows[0].length + 1; // one row for each data column, plus index column
return emptyQueryResultsMessage(); tableRows.push(
} <tr>
<td
let numTruncatedResults = 0; key={"message"}
if (dataRows.length > RAW_RESULTS_LIMIT) { colSpan={colSpan}
numTruncatedResults = dataRows.length - RAW_RESULTS_LIMIT; style={{ textAlign: "center", fontStyle: "italic" }}
dataRows = dataRows.slice(0, RAW_RESULTS_LIMIT); >
} Too many results to show at once. {numTruncatedResults} result(s)
omitted.
const tableRows = dataRows.map((row: ResultRow, rowIndex: number) => ( </td>
<RawTableRow </tr>,
key={rowIndex}
rowIndex={rowIndex + this.props.offset}
row={row}
databaseUri={databaseUri}
selectedColumn={
this.state.selectedItem?.row === rowIndex
? this.state.selectedItem?.column
: undefined
}
onSelected={this.setSelection}
scroller={this.scroller}
/>
));
if (numTruncatedResults > 0) {
const colSpan = dataRows[0].length + 1; // one row for each data column, plus index column
tableRows.push(
<tr>
<td
key={"message"}
colSpan={colSpan}
style={{ textAlign: "center", fontStyle: "italic" }}
>
Too many results to show at once. {numTruncatedResults} result(s)
omitted.
</td>
</tr>,
);
}
return (
<table className={className}>
<RawTableHeader
columns={resultSet.schema.columns}
schemaName={resultSet.schema.name}
sortState={this.props.sortState}
/>
<tbody>{tableRows}</tbody>
</table>
); );
} }
private handleNavigationEvent(event: NavigateMsg) { return (
switch (event.direction) { <table className={className}>
case NavigationDirection.up: { <RawTableHeader
this.navigateWithDelta(-1, 0); columns={resultSet.schema.columns}
break; schemaName={resultSet.schema.name}
} sortState={sortState}
case NavigationDirection.down: { />
this.navigateWithDelta(1, 0); <tbody>{tableRows}</tbody>
break; </table>
} );
case NavigationDirection.left: {
this.navigateWithDelta(0, -1);
break;
}
case NavigationDirection.right: {
this.navigateWithDelta(0, 1);
break;
}
}
}
private navigateWithDelta(rowDelta: number, columnDelta: number) {
this.setState((prevState) => {
const numberOfAlerts = this.props.resultSet.rows.length;
if (numberOfAlerts === 0) {
return prevState;
}
const currentRow = prevState.selectedItem?.row;
const nextRow = currentRow === undefined ? 0 : currentRow + rowDelta;
if (nextRow < 0 || nextRow >= numberOfAlerts) {
return prevState;
}
const currentColumn = prevState.selectedItem?.column;
const nextColumn =
currentColumn === undefined ? 0 : currentColumn + columnDelta;
// Jump to the location of the new cell
const rowData = this.props.resultSet.rows[nextRow];
if (nextColumn < 0 || nextColumn >= rowData.length) {
return prevState;
}
const cellData = rowData[nextColumn];
if (cellData != null && typeof cellData === "object") {
const location = tryGetResolvableLocation(cellData.url);
if (location !== undefined) {
jumpToLocation(location, this.props.databaseUri);
}
}
this.scroller.scrollIntoViewOnNextUpdate();
return {
...prevState,
selectedItem: { row: nextRow, column: nextColumn },
};
});
}
componentDidUpdate() {
this.scroller.update();
}
componentDidMount() {
this.scroller.update();
onNavigation.addListener(this.handleNavigationEvent);
}
componentWillUnmount() {
onNavigation.removeListener(this.handleNavigationEvent);
}
} }

View File

@@ -66,6 +66,12 @@ describe("commands declared in package.json", () => {
contribContextMenuCmds.add(command); contribContextMenuCmds.add(command);
}); });
menus["editor/title"].forEach((commandDecl: CmdDecl) => {
const { command } = commandDecl;
paletteCmds.delete(command);
contribContextMenuCmds.add(command);
});
debuggers.forEach((debuggerDecl: DebuggerDecl) => { debuggers.forEach((debuggerDecl: DebuggerDecl) => {
if (debuggerDecl.variables !== undefined) { if (debuggerDecl.variables !== undefined) {
for (const command of Object.values(debuggerDecl.variables)) { for (const command of Object.values(debuggerDecl.variables)) {

View File

@@ -9,6 +9,7 @@ import {
ClassificationType, ClassificationType,
Method, Method,
} from "../../../src/data-extensions-editor/auto-model-api"; } from "../../../src/data-extensions-editor/auto-model-api";
import { Mode } from "../../../src/data-extensions-editor/shared/mode";
describe("createAutoModelRequest", () => { describe("createAutoModelRequest", () => {
const externalApiUsages: ExternalApiUsage[] = [ const externalApiUsages: ExternalApiUsage[] = [
@@ -259,7 +260,13 @@ describe("createAutoModelRequest", () => {
it("creates a matching request", () => { it("creates a matching request", () => {
expect( expect(
createAutoModelRequest("java", externalApiUsages, modeledMethods, usages), createAutoModelRequest(
"java",
externalApiUsages,
modeledMethods,
usages,
Mode.Application,
),
).toEqual({ ).toEqual({
language: "java", language: "java",
samples: [ samples: [
@@ -340,60 +347,6 @@ describe("createAutoModelRequest", () => {
input: "Argument[0]", input: "Argument[0]",
classification: undefined, classification: undefined,
}, },
{
package: "org.springframework.boot",
type: "SpringApplication",
name: "run",
signature: "(Class,String[])",
usages:
usages[
"org.springframework.boot.SpringApplication#run(Class,String[])"
],
input: "Argument[this]",
classification: undefined,
},
{
package: "org.springframework.boot",
type: "SpringApplication",
name: "run",
signature: "(Class,String[])",
usages:
usages[
"org.springframework.boot.SpringApplication#run(Class,String[])"
],
input: "Argument[0]",
classification: undefined,
},
{
package: "org.springframework.boot",
type: "SpringApplication",
name: "run",
signature: "(Class,String[])",
usages:
usages[
"org.springframework.boot.SpringApplication#run(Class,String[])"
],
input: "Argument[1]",
classification: undefined,
},
{
package: "java.io",
type: "PrintStream",
name: "println",
signature: "(String)",
usages: usages["java.io.PrintStream#println(String)"],
input: "Argument[this]",
classification: undefined,
},
{
package: "java.io",
type: "PrintStream",
name: "println",
signature: "(String)",
usages: usages["java.io.PrintStream#println(String)"],
input: "Argument[0]",
classification: undefined,
},
{ {
package: "org.sql2o", package: "org.sql2o",
type: "Sql2o", type: "Sql2o",
@@ -430,6 +383,60 @@ describe("createAutoModelRequest", () => {
input: "Argument[2]", input: "Argument[2]",
classification: undefined, classification: undefined,
}, },
{
package: "java.io",
type: "PrintStream",
name: "println",
signature: "(String)",
usages: usages["java.io.PrintStream#println(String)"],
input: "Argument[this]",
classification: undefined,
},
{
package: "java.io",
type: "PrintStream",
name: "println",
signature: "(String)",
usages: usages["java.io.PrintStream#println(String)"],
input: "Argument[0]",
classification: undefined,
},
{
package: "org.springframework.boot",
type: "SpringApplication",
name: "run",
signature: "(Class,String[])",
usages:
usages[
"org.springframework.boot.SpringApplication#run(Class,String[])"
],
input: "Argument[this]",
classification: undefined,
},
{
package: "org.springframework.boot",
type: "SpringApplication",
name: "run",
signature: "(Class,String[])",
usages:
usages[
"org.springframework.boot.SpringApplication#run(Class,String[])"
],
input: "Argument[0]",
classification: undefined,
},
{
package: "org.springframework.boot",
type: "SpringApplication",
name: "run",
signature: "(Class,String[])",
usages:
usages[
"org.springframework.boot.SpringApplication#run(Class,String[])"
],
input: "Argument[1]",
classification: undefined,
},
], ],
}); });
}); });

View File

@@ -1,4 +1,4 @@
import { calculateModeledPercentage } from "../modeled"; import { calculateModeledPercentage } from "../../../../src/data-extensions-editor/shared/modeled-percentage";
describe("calculateModeledPercentage", () => { describe("calculateModeledPercentage", () => {
it("when there are no external API usages", () => { it("when there are no external API usages", () => {