mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-13 17:22:15 -05:00
Adds toggle button to switch between estimated and actual execution plans (#19629)
* Creates toggle button to switch between estimate and actual query plans * Renames ID for the toggleActualExecutionPlanModeAction class * Renames button back to explain * Creating actual execution plans resembles SSMS * Adds CTRL/CMD + L shortcut to display estimated execution plans * Alphabetically organizes telemetry actions * Adds telemetry when the setting for actual execution plan toggle is used * Resolves build errors * Fixes broken unit tests. * Code review changes * Removes unnecessary null-coalescing operator. * Creates placeholder icons for actual execution plans enabled * Code review changes * Shortens label names * Telemetry moved to toggle button * Telemetry review changes * Clarifies misleading label
This commit is contained in:
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#fff;}</style></defs><title>query_plan_inverse_16x16</title><path class="cls-1" d="M13.06,10.49H15v5H10.22v-5h1.89v-2H3.59v2H5.48v5H.75v-5h1.9v-3H7.38v-2H5.48v-5h4.74v5H8.33v2h4.74Zm-8.53,4v-3H1.69v3Zm1.9-13v3H9.27v-3Zm7.58,13v-3H11.17v3Z"/></svg>
|
||||
|
After Width: | Height: | Size: 365 B |
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><title>query_plan_16x16</title><path d="M13.16,10.59h1.9v5H10.32v-5h1.89v-2H3.68v2H5.58v5H.84v-5h1.9v-3H7.47v-2H5.58v-5h4.74v5H8.42v2h4.74Zm-8.53,4v-3H1.79v3Zm1.9-13v3H9.37v-3Zm7.58,13v-3H11.26v3Z"/></svg>
|
||||
|
After Width: | Height: | Size: 298 B |
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#fff;}</style></defs><title>query_plan_inverse_16x16</title><path class="cls-1" d="M13.06,10.49H15v5H10.22v-5h1.89v-2H3.59v2H5.48v5H.75v-5h1.9v-3H7.38v-2H5.48v-5h4.74v5H8.33v2h4.74Zm-8.53,4v-3H1.69v3Zm1.9-13v3H9.27v-3Zm7.58,13v-3H11.17v3Z"/></svg>
|
||||
|
After Width: | Height: | Size: 365 B |
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><title>query_plan_16x16</title><path d="M13.16,10.59h1.9v5H10.32v-5h1.89v-2H3.68v2H5.58v5H.84v-5h1.9v-3H7.47v-2H5.58v-5h4.74v5H8.42v2h4.74Zm-8.53,4v-3H1.79v3Zm1.9-13v3H9.37v-3Zm7.58,13v-3H11.26v3Z"/></svg>
|
||||
|
After Width: | Height: | Size: 298 B |
@@ -65,6 +65,14 @@
|
||||
background-image: url('query-plan.svg');
|
||||
}
|
||||
|
||||
.vs .codicon.disabledActualExecutionPlan {
|
||||
background-image: url('disabled-actual-execution-plan.svg');
|
||||
}
|
||||
|
||||
.vs .codicon.enabledActualExecutionPlan {
|
||||
background-image: url('enabled-actual-execution-plan.svg');
|
||||
}
|
||||
|
||||
.vs-dark .codicon.estimatedQueryPlan,
|
||||
.hc-black .codicon.estimatedQueryPlan,
|
||||
.vs-dark .codicon.actualQueryPlan,
|
||||
@@ -72,6 +80,16 @@
|
||||
background-image: url('query-plan-inverse.svg');
|
||||
}
|
||||
|
||||
.vs-dark .codicon.codicon.disabledActualExecutionPlan,
|
||||
.hc-black .codicon.codicon.disabledActualExecutionPlan {
|
||||
background-image: url('disabled-actual-execution-plan-inverse.svg');
|
||||
}
|
||||
|
||||
.vs-dark .codicon.codicon.enabledActualExecutionPlan,
|
||||
.hc-black .codicon.codicon.enabledActualExecutionPlan {
|
||||
background-image: url('enabled-actual-execution-plan-inverse.svg');
|
||||
}
|
||||
|
||||
.vs .codicon.createInsight {
|
||||
background-image: url('create_insight.svg');
|
||||
}
|
||||
|
||||
@@ -55,12 +55,16 @@ export const enum TelemetryError {
|
||||
}
|
||||
|
||||
export const enum TelemetryAction {
|
||||
adsCommandExecuted = 'adsCommandExecuted',
|
||||
AddExecutionPlan = 'AddExecutionPlan',
|
||||
AddServerGroup = 'AddServerGroup',
|
||||
adsCommandExecuted = 'adsCommandExecuted',
|
||||
BackupCreated = 'BackupCreated',
|
||||
ConnectToServer = 'ConnectToServer',
|
||||
CustomZoom = 'CustomZoom',
|
||||
BackupCreated = 'BackupCreated',
|
||||
CancelQuery = 'CancelQuery',
|
||||
ChartCreated = 'ChartCreated',
|
||||
Click = 'Click',
|
||||
CompareExecutionPlan = 'CompareExecutionPlan',
|
||||
DashboardNavigated = 'DashboardNavigated',
|
||||
DatabaseConnected = 'DatabaseConnected',
|
||||
DatabaseDisconnected = 'DatabaseDisconnected',
|
||||
@@ -71,10 +75,6 @@ export const enum TelemetryAction {
|
||||
DeleteAgentProxy = 'DeleteAgentProxy',
|
||||
DeleteConnection = 'DeleteConnection',
|
||||
DeleteServerGroup = 'DeleteServerGroup',
|
||||
CancelQuery = 'CancelQuery',
|
||||
ChartCreated = 'ChartCreated',
|
||||
Click = 'Click',
|
||||
CompareExecutionPlan = 'CompareExecutionPlan',
|
||||
FindNode = 'FindNode',
|
||||
FirewallRuleRequested = 'FirewallRuleCreated',
|
||||
GenerateScript = 'GenerateScript',
|
||||
@@ -97,13 +97,14 @@ export const enum TelemetryAction {
|
||||
RunQuery = 'RunQuery',
|
||||
RunQueryStatement = 'RunQueryStatement',
|
||||
RunQueryString = 'RunQueryString',
|
||||
SearchCompleted = 'SearchCompleted',
|
||||
SearchStarted = 'SearchStarted',
|
||||
ShowChart = 'ShowChart',
|
||||
StopAgentJob = 'StopAgentJob',
|
||||
ToggleActualExecutionPlan = 'ToggleActualExecutionPlan',
|
||||
ViewExecutionPlanComparisonProperties = 'ViewExecutionPlanComparisonProperties',
|
||||
ViewTopOperations = 'ViewTopOperations',
|
||||
WizardPagesNavigation = 'WizardPagesNavigation',
|
||||
SearchStarted = 'SearchStarted',
|
||||
SearchCompleted = 'SearchCompleted',
|
||||
ZoomIn = 'ZoomIn',
|
||||
ZoomOut = 'ZoomOut',
|
||||
ZoomToFit = 'ZoomToFIt'
|
||||
|
||||
@@ -41,6 +41,7 @@ export interface IQueryEditorStateChange {
|
||||
executingChange?: boolean;
|
||||
connectingChange?: boolean;
|
||||
sqlCmdModeChanged?: boolean;
|
||||
actualExecutionPlanModeChanged?: boolean;
|
||||
}
|
||||
|
||||
export class QueryEditorState extends Disposable {
|
||||
@@ -49,6 +50,7 @@ export class QueryEditorState extends Disposable {
|
||||
private _resultsVisible = false;
|
||||
private _executing = false;
|
||||
private _connecting = false;
|
||||
private _isActualExecutionPlanMode = false;
|
||||
|
||||
private _onChange = this._register(new Emitter<IQueryEditorStateChange>());
|
||||
public onChange = this._onChange.event;
|
||||
@@ -108,12 +110,24 @@ export class QueryEditorState extends Disposable {
|
||||
return this._isSqlCmdMode;
|
||||
}
|
||||
|
||||
public set isActualExecutionPlanMode(val: boolean) {
|
||||
if (val !== this._isActualExecutionPlanMode) {
|
||||
this._isActualExecutionPlanMode = val;
|
||||
this._onChange.fire({ actualExecutionPlanModeChanged: true });
|
||||
}
|
||||
}
|
||||
|
||||
public get isActualExecutionPlanMode() {
|
||||
return this._isActualExecutionPlanMode;
|
||||
}
|
||||
|
||||
public setState(newState: QueryEditorState): void {
|
||||
this.connected = newState.connected;
|
||||
this.connecting = newState.connecting;
|
||||
this.resultsVisible = newState.resultsVisible;
|
||||
this.executing = newState.executing;
|
||||
this.isSqlCmdMode = newState.isSqlCmdMode;
|
||||
this.isActualExecutionPlanMode = newState.isActualExecutionPlanMode;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -206,6 +206,27 @@ export class CopyQueryWithResultsKeyboardAction extends Action {
|
||||
}
|
||||
}
|
||||
|
||||
export class EstimatedExecutionPlanKeyboardAction extends Action {
|
||||
public static ID = 'estimatedExecutionPlanKeyboardAction';
|
||||
public static LABEL = nls.localize('estimatedExecutionPlanKeyboardAction', "Display Estimated Execution Plan");
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IEditorService private _editorService: IEditorService
|
||||
) {
|
||||
super(id, label);
|
||||
this.enabled = true;
|
||||
}
|
||||
|
||||
public override async run(): Promise<void> {
|
||||
const editor = this._editorService.activeEditorPane;
|
||||
if (editor instanceof QueryEditor) {
|
||||
editor.input.runQuery(editor.getSelection(), { displayEstimatedQueryPlan: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class RunCurrentQueryWithActualPlanKeyboardAction extends Action {
|
||||
public static ID = 'runCurrentQueryWithActualPlanKeyboardAction';
|
||||
public static LABEL = nls.localize('runCurrentQueryWithActualPlanKeyboardAction', "Run Current Query with Actual Plan");
|
||||
|
||||
@@ -19,7 +19,7 @@ import { QueryResultsInput } from 'sql/workbench/common/editor/query/queryResult
|
||||
import * as queryContext from 'sql/workbench/contrib/query/common/queryContext';
|
||||
import {
|
||||
RunQueryKeyboardAction, RunCurrentQueryKeyboardAction, CancelQueryKeyboardAction, RefreshIntellisenseKeyboardAction, ToggleQueryResultsKeyboardAction,
|
||||
RunQueryShortcutAction, RunCurrentQueryWithActualPlanKeyboardAction, CopyQueryWithResultsKeyboardAction, FocusOnCurrentQueryKeyboardAction, ParseSyntaxAction, ToggleFocusBetweenQueryEditorAndResultsAction
|
||||
RunQueryShortcutAction, RunCurrentQueryWithActualPlanKeyboardAction, CopyQueryWithResultsKeyboardAction, FocusOnCurrentQueryKeyboardAction, ParseSyntaxAction, ToggleFocusBetweenQueryEditorAndResultsAction, EstimatedExecutionPlanKeyboardAction
|
||||
} from 'sql/workbench/contrib/query/browser/keyboardQueryActions';
|
||||
import * as gridActions from 'sql/workbench/contrib/editData/browser/gridActions';
|
||||
import * as gridCommands from 'sql/workbench/contrib/editData/browser/gridCommands';
|
||||
@@ -135,6 +135,16 @@ actionRegistry.registerWorkbenchAction(
|
||||
RunCurrentQueryKeyboardAction.LABEL
|
||||
);
|
||||
|
||||
actionRegistry.registerWorkbenchAction(
|
||||
SyncActionDescriptor.create(
|
||||
EstimatedExecutionPlanKeyboardAction,
|
||||
EstimatedExecutionPlanKeyboardAction.ID,
|
||||
EstimatedExecutionPlanKeyboardAction.LABEL,
|
||||
{ primary: KeyMod.CtrlCmd | KeyCode.KEY_L }
|
||||
),
|
||||
EstimatedExecutionPlanKeyboardAction.LABEL
|
||||
);
|
||||
|
||||
actionRegistry.registerWorkbenchAction(
|
||||
SyncActionDescriptor.create(
|
||||
RunCurrentQueryWithActualPlanKeyboardAction,
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
import 'vs/css!./media/queryActions';
|
||||
import * as nls from 'vs/nls';
|
||||
import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys';
|
||||
import { Action, IAction, IActionRunner } from 'vs/base/common/actions';
|
||||
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
|
||||
@@ -46,6 +47,7 @@ import { getErrorMessage, onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { IActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { gen3Version, sqlDataWarehouse } from 'sql/platform/connection/common/constants';
|
||||
import { Dropdown } from 'sql/base/browser/ui/editableDropdown/browser/dropdown';
|
||||
import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry';
|
||||
|
||||
/**
|
||||
* Action class that query-based Actions will extend. This base class automatically handles activating and
|
||||
@@ -242,9 +244,15 @@ export class RunQueryAction extends QueryTaskbarAction {
|
||||
if (runCurrentStatement && selection && this.isCursorPosition(selection)) {
|
||||
editor.input.runQueryStatement(selection);
|
||||
} else {
|
||||
// get the selection again this time with trimming
|
||||
selection = editor.getSelection();
|
||||
editor.input.runQuery(selection);
|
||||
if (editor.input.state.isActualExecutionPlanMode) {
|
||||
selection = editor.getSelection();
|
||||
editor.input.runQuery(selection, { displayActualQueryPlan: true });
|
||||
}
|
||||
else {
|
||||
// get the selection again this time with trimming
|
||||
selection = editor.getSelection();
|
||||
editor.input.runQuery(selection);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -300,7 +308,7 @@ export class EstimatedQueryPlanAction extends QueryTaskbarAction {
|
||||
@IConnectionManagementService connectionManagementService: IConnectionManagementService
|
||||
) {
|
||||
super(connectionManagementService, editor, EstimatedQueryPlanAction.ID, EstimatedQueryPlanAction.EnabledClass);
|
||||
this.label = nls.localize('estimatedQueryPlan', "Explain");
|
||||
this.label = nls.localize('estimatedQueryPlan', "Estimated Plan");
|
||||
}
|
||||
|
||||
public override async run(): Promise<void> {
|
||||
@@ -323,13 +331,57 @@ export class EstimatedQueryPlanAction extends QueryTaskbarAction {
|
||||
}
|
||||
|
||||
if (this.isConnected(editor)) {
|
||||
editor.input.runQuery(editor.getSelection(), {
|
||||
displayEstimatedQueryPlan: true
|
||||
});
|
||||
editor.input.runQuery(editor.getSelection(), { displayEstimatedQueryPlan: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Action class that toggles the actual execution plan mode for the editor
|
||||
*/
|
||||
export class ToggleActualExecutionPlanModeAction extends QueryTaskbarAction {
|
||||
public static EnabledClass = 'enabledActualExecutionPlan';
|
||||
public static ID = 'toggleActualExecutionPlanModeAction';
|
||||
|
||||
private _enableActualPlanLabel = nls.localize('enableActualPlanLabel', "Include Actual Plan");
|
||||
private _disableActualPlanLabel = nls.localize('disableActualPlanLabel', "Exclude Actual Plan");
|
||||
|
||||
constructor(
|
||||
editor: QueryEditor,
|
||||
private _isActualPlanMode: boolean,
|
||||
@IQueryManagementService protected readonly queryManagementService: IQueryManagementService,
|
||||
@IConfigurationService protected readonly configurationService: IConfigurationService,
|
||||
@IConnectionManagementService connectionManagementService: IConnectionManagementService,
|
||||
@IAdsTelemetryService private readonly telemetryService: IAdsTelemetryService
|
||||
) {
|
||||
super(connectionManagementService, editor, ToggleActualExecutionPlanModeAction.ID, ToggleActualExecutionPlanModeAction.EnabledClass);
|
||||
this.updateLabel();
|
||||
}
|
||||
|
||||
public get isActualExecutionPlanMode(): boolean {
|
||||
return this._isActualPlanMode;
|
||||
}
|
||||
|
||||
public set isActualExecutionPlanMode(value: boolean) {
|
||||
this._isActualPlanMode = value;
|
||||
this.updateLabel();
|
||||
}
|
||||
|
||||
private updateLabel(): void {
|
||||
// show option to disable actual plan mode if already enabled
|
||||
this.label = this.isActualExecutionPlanMode ? this._disableActualPlanLabel : this._enableActualPlanLabel;
|
||||
}
|
||||
|
||||
public override async run(): Promise<void> {
|
||||
const toActualPlanState = !this.isActualExecutionPlanMode;
|
||||
this.editor.input.state.isActualExecutionPlanMode = toActualPlanState;
|
||||
|
||||
this.telemetryService.createActionEvent(TelemetryKeys.TelemetryView.ExecutionPlan, TelemetryKeys.TelemetryAction.Click, 'ToggleActualExecutionPlan')
|
||||
.withAdditionalProperties({ actualExecutionPlanMode: this.isActualExecutionPlanMode })
|
||||
.send();
|
||||
}
|
||||
}
|
||||
|
||||
export class ActualQueryPlanAction extends QueryTaskbarAction {
|
||||
public static EnabledClass = 'actualQueryPlan';
|
||||
public static ID = 'actualQueryPlanAction';
|
||||
@@ -522,6 +574,7 @@ export class ToggleSqlCmdModeAction extends QueryTaskbarAction {
|
||||
|
||||
private _enablesqlcmdLabel = nls.localize('enablesqlcmdLabel', "Enable SQLCMD");
|
||||
private _disablesqlcmdLabel = nls.localize('disablesqlcmdLabel', "Disable SQLCMD");
|
||||
|
||||
constructor(
|
||||
editor: QueryEditor,
|
||||
private _isSqlCmdMode: boolean,
|
||||
|
||||
@@ -96,6 +96,7 @@ export class QueryEditor extends EditorPane {
|
||||
private _actualQueryPlanAction: actions.ActualQueryPlanAction;
|
||||
private _listDatabasesActionItem: actions.ListDatabasesActionItem;
|
||||
private _toggleSqlcmdMode: actions.ToggleSqlCmdModeAction;
|
||||
private _toggleActualExecutionPlanMode: actions.ToggleActualExecutionPlanModeAction;
|
||||
private _exportAsNotebookAction: actions.ExportAsNotebookAction;
|
||||
|
||||
constructor(
|
||||
@@ -205,6 +206,7 @@ export class QueryEditor extends EditorPane {
|
||||
this._estimatedQueryPlanAction = this.instantiationService.createInstance(actions.EstimatedQueryPlanAction, this);
|
||||
this._actualQueryPlanAction = this.instantiationService.createInstance(actions.ActualQueryPlanAction, this);
|
||||
this._toggleSqlcmdMode = this.instantiationService.createInstance(actions.ToggleSqlCmdModeAction, this, false);
|
||||
this._toggleActualExecutionPlanMode = this.instantiationService.createInstance(actions.ToggleActualExecutionPlanModeAction, this, false);
|
||||
this._exportAsNotebookAction = this.instantiationService.createInstance(actions.ExportAsNotebookAction, this);
|
||||
this.setTaskbarContent();
|
||||
this._register(this.configurationService.onDidChangeConfiguration(e => {
|
||||
@@ -241,6 +243,10 @@ export class QueryEditor extends EditorPane {
|
||||
this._toggleSqlcmdMode.isSqlCmdMode = this.input.state.isSqlCmdMode;
|
||||
}
|
||||
|
||||
if (stateChangeEvent.actualExecutionPlanModeChanged) {
|
||||
this._toggleActualExecutionPlanMode.isActualExecutionPlanMode = this.input.state.isActualExecutionPlanMode;
|
||||
}
|
||||
|
||||
if (stateChangeEvent.connectingChange) {
|
||||
this._runQueryAction.enabled = !this.input.state.connecting;
|
||||
this._estimatedQueryPlanAction.enabled = !this.input.state.connecting;
|
||||
@@ -322,6 +328,7 @@ export class QueryEditor extends EditorPane {
|
||||
content.push(
|
||||
{ element: Taskbar.createTaskbarSeparator() },
|
||||
{ action: this._estimatedQueryPlanAction },
|
||||
{ action: this._toggleActualExecutionPlanMode },
|
||||
{ action: this._toggleSqlcmdMode },
|
||||
{ action: this._exportAsNotebookAction }
|
||||
);
|
||||
@@ -367,7 +374,7 @@ export class QueryEditor extends EditorPane {
|
||||
|
||||
this.inputDisposables.clear();
|
||||
this.inputDisposables.add(this.input.state.onChange(c => this.updateState(c)));
|
||||
this.updateState({ connectingChange: true, connectedChange: true, executingChange: true, resultsVisibleChange: true, sqlCmdModeChanged: true });
|
||||
this.updateState({ connectingChange: true, connectedChange: true, executingChange: true, resultsVisibleChange: true, sqlCmdModeChanged: true, actualExecutionPlanModeChanged: true });
|
||||
|
||||
const editorViewState = this.loadTextEditorViewState(this.input.resource);
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ import { IUntitledTextEditorService } from 'vs/workbench/services/untitled/commo
|
||||
import { TestStorageService } from 'vs/workbench/test/common/workbenchTestServices';
|
||||
import { IRange } from 'vs/editor/common/core/range';
|
||||
import { ServerInfo } from 'azdata';
|
||||
import { QueryEditorState } from 'sql/workbench/common/editor/query/queryEditorInput';
|
||||
|
||||
suite('SQL QueryAction Tests', () => {
|
||||
|
||||
@@ -41,6 +42,7 @@ suite('SQL QueryAction Tests', () => {
|
||||
let editor: TypeMoq.Mock<QueryEditor>;
|
||||
let calledRunQueryOnInput: boolean = undefined;
|
||||
let testQueryInput: TypeMoq.Mock<UntitledQueryEditorInput>;
|
||||
let testQueryInputState: TypeMoq.Mock<QueryEditorState>;
|
||||
let configurationService: TypeMoq.Mock<TestConfigurationService>;
|
||||
let queryModelService: TypeMoq.Mock<TestQueryModelService>;
|
||||
let connectionManagementService: TypeMoq.Mock<TestConnectionManagementService>;
|
||||
@@ -76,9 +78,13 @@ suite('SQL QueryAction Tests', () => {
|
||||
const service = accessor.untitledTextEditorService;
|
||||
let fileInput = workbenchinstantiationService.createInstance(UntitledTextEditorInput, service.create({ associatedResource: URI.parse('file://testUri') }));
|
||||
// Setup a reusable mock QueryInput
|
||||
testQueryInputState = TypeMoq.Mock.ofType(QueryEditorState, TypeMoq.MockBehavior.Strict);
|
||||
testQueryInputState.setup(x => x.isActualExecutionPlanMode).returns(() => false);
|
||||
|
||||
testQueryInput = TypeMoq.Mock.ofType(UntitledQueryEditorInput, TypeMoq.MockBehavior.Strict, undefined, fileInput, undefined, connectionManagementService.object, queryModelService.object, configurationService.object);
|
||||
testQueryInput.setup(x => x.uri).returns(() => testUri);
|
||||
testQueryInput.setup(x => x.runQuery(undefined)).callback(() => { calledRunQueryOnInput = true; });
|
||||
testQueryInput.setup(x => x.state).returns(() => testQueryInputState.object);
|
||||
});
|
||||
|
||||
test('setClass sets child CSS class correctly', () => {
|
||||
@@ -184,11 +190,15 @@ suite('SQL QueryAction Tests', () => {
|
||||
let fileInput = workbenchinstantiationService.createInstance(UntitledTextEditorInput, service.create({ associatedResource: URI.parse('file://testUri') }));
|
||||
|
||||
// ... Mock "isSelectionEmpty" in QueryEditor
|
||||
let queryInputState = TypeMoq.Mock.ofType(QueryEditorState, TypeMoq.MockBehavior.Loose);
|
||||
queryInputState.setup(x => x.isActualExecutionPlanMode).returns(() => false);
|
||||
|
||||
let queryInput = TypeMoq.Mock.ofType(UntitledQueryEditorInput, TypeMoq.MockBehavior.Strict, undefined, fileInput, undefined, connectionManagementService.object, queryModelService.object, configurationService.object);
|
||||
queryInput.setup(x => x.uri).returns(() => testUri);
|
||||
queryInput.setup(x => x.runQuery(undefined)).callback(() => {
|
||||
countCalledRunQuery++;
|
||||
});
|
||||
queryInput.setup(x => x.state).returns(() => queryInputState.object);
|
||||
const contextkeyservice = new MockContextKeyService();
|
||||
|
||||
// Setup a reusable mock QueryEditor
|
||||
@@ -234,12 +244,16 @@ suite('SQL QueryAction Tests', () => {
|
||||
const service = accessor.untitledTextEditorService;
|
||||
let fileInput = workbenchinstantiationService.createInstance(UntitledTextEditorInput, service.create({ associatedResource: URI.parse('file://testUri') }));
|
||||
|
||||
let queryInputState = TypeMoq.Mock.ofType(QueryEditorState, TypeMoq.MockBehavior.Loose);
|
||||
queryInputState.setup(x => x.isActualExecutionPlanMode).returns(() => false);
|
||||
|
||||
let queryInput = TypeMoq.Mock.ofType(UntitledQueryEditorInput, TypeMoq.MockBehavior.Loose, undefined, fileInput, undefined, connectionManagementService.object, queryModelService.object, configurationService.object);
|
||||
queryInput.setup(x => x.uri).returns(() => testUri);
|
||||
queryInput.setup(x => x.runQuery(TypeMoq.It.isAny())).callback((selection: IRange) => {
|
||||
runQuerySelection = selection;
|
||||
countCalledRunQuery++;
|
||||
});
|
||||
queryInput.setup(x => x.state).returns(() => queryInputState.object);
|
||||
queryInput.setup(x => x.runQuery(undefined)).callback((selection: IRange) => {
|
||||
runQuerySelection = selection;
|
||||
countCalledRunQuery++;
|
||||
|
||||
Reference in New Issue
Block a user