mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-23 17:23:02 -05:00
remove event emitter and use event and emitter instead (#5361)
This commit is contained in:
@@ -7,7 +7,6 @@ import { Action, IActionItem, IActionRunner } from 'vs/base/common/actions';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { IQueryModelService } from 'sql/platform/query/common/queryModel';
|
||||
import { SelectBox } from 'sql/base/browser/ui/selectBox/selectBox';
|
||||
import { EventEmitter } from 'sql/base/common/eventEmitter';
|
||||
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
||||
import { EditDataEditor } from 'sql/workbench/parts/editData/browser/editDataEditor';
|
||||
import * as nls from 'vs/nls';
|
||||
@@ -151,7 +150,7 @@ export class ChangeMaxRowsAction extends EditDataAction {
|
||||
* Action item that handles the dropdown (combobox) that lists the avaliable number of row selections
|
||||
* for an edit data session
|
||||
*/
|
||||
export class ChangeMaxRowsActionItem extends EventEmitter implements IActionItem {
|
||||
export class ChangeMaxRowsActionItem implements IActionItem {
|
||||
|
||||
public actionRunner: IActionRunner;
|
||||
public defaultRowCount: number;
|
||||
@@ -167,7 +166,6 @@ export class ChangeMaxRowsActionItem extends EventEmitter implements IActionItem
|
||||
private _editor: EditDataEditor,
|
||||
@IContextViewService contextViewService: IContextViewService,
|
||||
@IThemeService private _themeService: IThemeService) {
|
||||
super();
|
||||
this._options = ['200', '1000', '10000'];
|
||||
this._currentOptionsIndex = 0;
|
||||
this.toDispose = [];
|
||||
|
||||
@@ -433,7 +433,7 @@ export class ProfilerEditor extends BaseEditor {
|
||||
if (this._stateListener) {
|
||||
this._stateListener.dispose();
|
||||
}
|
||||
this._stateListener = input.state.addChangeListener(e => this._onStateChange(e));
|
||||
this._stateListener = input.state.onProfilerStateChange(e => this._onStateChange(e));
|
||||
this._onStateChange({
|
||||
isConnected: true,
|
||||
isRunning: true,
|
||||
|
||||
@@ -123,7 +123,7 @@ export class ProfilerTableEditor extends BaseEditor implements IProfilerControll
|
||||
if (this._stateListener) {
|
||||
this._stateListener.dispose();
|
||||
}
|
||||
this._stateListener = input.state.addChangeListener(e => this._onStateChange(e));
|
||||
this._stateListener = input.state.onProfilerStateChange(e => this._onStateChange(e));
|
||||
input.data.onRowCountChange(() => {
|
||||
this._profilerTable.updateRowCount();
|
||||
this._updateRowCountStatus();
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { EventEmitter } from 'sql/base/common/eventEmitter';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
|
||||
export interface IProfilerStateChangedEvent {
|
||||
isConnected?: boolean;
|
||||
@@ -25,7 +25,6 @@ export interface INewProfilerState {
|
||||
}
|
||||
|
||||
export class ProfilerState implements IDisposable {
|
||||
private static _CHANGED_EVENT = 'changed';
|
||||
|
||||
private _isConnected: boolean;
|
||||
private _isRunning: boolean;
|
||||
@@ -33,7 +32,6 @@ export class ProfilerState implements IDisposable {
|
||||
private _isStopped: boolean;
|
||||
private _autoscroll: boolean;
|
||||
private _isPanelCollapsed = true;
|
||||
private _eventEmitter: EventEmitter;
|
||||
|
||||
public get isConnected(): boolean { return this._isConnected; }
|
||||
public get isRunning(): boolean { return this._isRunning; }
|
||||
@@ -42,16 +40,10 @@ export class ProfilerState implements IDisposable {
|
||||
public get autoscroll(): boolean { return this._autoscroll; }
|
||||
public get isPanelCollapsed(): boolean { return this._isPanelCollapsed; }
|
||||
|
||||
constructor() {
|
||||
this._eventEmitter = new EventEmitter();
|
||||
}
|
||||
private readonly _onProfilerStateChange = new Emitter<IProfilerStateChangedEvent>();
|
||||
public readonly onProfilerStateChange = this._onProfilerStateChange.event;
|
||||
|
||||
public dispose(): void {
|
||||
this._eventEmitter.dispose();
|
||||
}
|
||||
|
||||
public addChangeListener(listener: (e: IProfilerStateChangedEvent) => void): IDisposable {
|
||||
return this._eventEmitter.addListener(ProfilerState._CHANGED_EVENT, listener);
|
||||
}
|
||||
|
||||
public change(newState: INewProfilerState): void {
|
||||
@@ -109,7 +101,7 @@ export class ProfilerState implements IDisposable {
|
||||
}
|
||||
|
||||
if (somethingChanged) {
|
||||
this._eventEmitter.emit(ProfilerState._CHANGED_EVENT, changeEvent);
|
||||
this._onProfilerStateChange.fire(changeEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ import { QueryEditor } from 'sql/workbench/parts/query/browser/queryEditor';
|
||||
import { IQueryModelService } from 'sql/platform/query/common/queryModel';
|
||||
import { SelectBox } from 'sql/base/browser/ui/selectBox/selectBox';
|
||||
import { attachEditableDropdownStyler, attachSelectBoxStyler } from 'sql/platform/theme/common/styler';
|
||||
import { EventEmitter } from 'sql/base/common/eventEmitter';
|
||||
import { Dropdown } from 'sql/base/parts/editableDropdown/browser/dropdown';
|
||||
|
||||
/**
|
||||
@@ -428,7 +427,7 @@ export class ListDatabasesAction extends QueryTaskbarAction {
|
||||
* Action item that handles the dropdown (combobox) that lists the available databases.
|
||||
* Based off StartDebugActionItem.
|
||||
*/
|
||||
export class ListDatabasesActionItem extends EventEmitter implements IActionItem {
|
||||
export class ListDatabasesActionItem implements IActionItem {
|
||||
public static ID = 'listDatabaseQueryActionItem';
|
||||
|
||||
public actionRunner: IActionRunner;
|
||||
@@ -450,7 +449,6 @@ export class ListDatabasesActionItem extends EventEmitter implements IActionItem
|
||||
@IContextViewService contextViewProvider: IContextViewService,
|
||||
@IConfigurationService private readonly _configurationService: IConfigurationService
|
||||
) {
|
||||
super();
|
||||
this._toDispose = [];
|
||||
this._databaseListDropdown = $('.databaseListDropdown');
|
||||
this._isInAccessibilityMode = this._configurationService.getValue('editor.accessibilitySupport') === 'on';
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
||||
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||
import { IInsightsConfigDetails } from 'sql/workbench/parts/dashboard/widgets/insights/interfaces';
|
||||
import QueryRunner, { EventType as QREvents } from 'sql/platform/query/common/queryRunner';
|
||||
import QueryRunner from 'sql/platform/query/common/queryRunner';
|
||||
import * as Utils from 'sql/platform/connection/common/utils';
|
||||
import { IInsightsDialogModel } from 'sql/workbench/services/insights/common/insightsDialogService';
|
||||
import { IErrorMessageService } from 'sql/platform/errorMessage/common/errorMessageService';
|
||||
@@ -141,12 +141,12 @@ export class InsightsDialogController {
|
||||
}
|
||||
|
||||
private addQueryEventListeners(queryRunner: QueryRunner): void {
|
||||
queryRunner.addListener(QREvents.COMPLETE, () => {
|
||||
queryRunner.onQueryEnd(() => {
|
||||
this.queryComplete().catch(error => {
|
||||
this._errorMessageService.showDialog(Severity.Error, nls.localize("insightsError", "Insights error"), error);
|
||||
});
|
||||
});
|
||||
queryRunner.addListener(QREvents.MESSAGE, message => {
|
||||
queryRunner.onMessage(message => {
|
||||
if (message.isError) {
|
||||
this._errorMessageService.showDialog(Severity.Error, nls.localize("insightsError", "Insights error"), message.message);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,253 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { IInsightsLabel, IInsightsConfigDetails } from 'sql/workbench/parts/dashboard/widgets/insights/interfaces';
|
||||
import { InsightsDialogModel } from 'sql/workbench/services/insights/common/insightsDialogModel';
|
||||
import { isUndefinedOrNull } from 'vs/base/common/types';
|
||||
|
||||
import * as assert from 'assert';
|
||||
|
||||
suite('Insights Dialog Model Tests', () => {
|
||||
test('does parse condition right', () => {
|
||||
let insightsDialogModel = new InsightsDialogModel();
|
||||
|
||||
let label: IInsightsLabel = {
|
||||
column: undefined,
|
||||
state: [
|
||||
{
|
||||
condition: {
|
||||
if: 'always'
|
||||
},
|
||||
color: 'green'
|
||||
}
|
||||
]
|
||||
} as IInsightsLabel;
|
||||
insightsDialogModel.insight = { label } as IInsightsConfigDetails;
|
||||
insightsDialogModel.rows = [
|
||||
['label1', 'value1'],
|
||||
['label2', 'value2'],
|
||||
['label3', 'value3']
|
||||
];
|
||||
let result = insightsDialogModel.getListResources(0, 1);
|
||||
for (let resource of result) {
|
||||
assert.equal(resource.stateColor, 'green', 'always Condition did not return val as expected');
|
||||
}
|
||||
|
||||
label.state = [
|
||||
{
|
||||
condition: {
|
||||
if: 'equals',
|
||||
equals: 'specific value'
|
||||
},
|
||||
color: 'green'
|
||||
}
|
||||
];
|
||||
|
||||
insightsDialogModel.insight = { label } as IInsightsConfigDetails;
|
||||
insightsDialogModel.rows = [
|
||||
['label1', 'specific value'],
|
||||
['label2', 'value2'],
|
||||
['label3', 'value3']
|
||||
];
|
||||
result = insightsDialogModel.getListResources(0, 1);
|
||||
assert.equal(result[0].stateColor, 'green', 'always Condition did not return val as expected');
|
||||
assert.equal(isUndefinedOrNull(result[1].stateColor), true, 'always Condition did not return val as expected');
|
||||
assert.equal(isUndefinedOrNull(result[2].stateColor), true, 'always Condition did not return val as expected');
|
||||
|
||||
label.state = [
|
||||
{
|
||||
condition: {
|
||||
if: 'equals',
|
||||
equals: 'specific value'
|
||||
},
|
||||
color: 'green'
|
||||
},
|
||||
{
|
||||
condition: {
|
||||
if: 'equals',
|
||||
equals: 'specific value2'
|
||||
},
|
||||
color: 'red'
|
||||
}
|
||||
];
|
||||
|
||||
insightsDialogModel.insight = { label } as IInsightsConfigDetails;
|
||||
insightsDialogModel.rows = [
|
||||
['label1', 'specific value'],
|
||||
['label2', 'specific value2'],
|
||||
['label3', 'value3']
|
||||
];
|
||||
result = insightsDialogModel.getListResources(0, 1);
|
||||
assert.equal(result[0].stateColor, 'green', 'always Condition did not return val as expected');
|
||||
assert.equal(result[1].stateColor, 'red', 'always Condition did not return val as expected');
|
||||
assert.equal(isUndefinedOrNull(result[2].stateColor), true, 'always Condition did not return val as expected');
|
||||
|
||||
label.state = [
|
||||
{
|
||||
condition: {
|
||||
if: 'greaterThan',
|
||||
equals: '2'
|
||||
},
|
||||
color: 'green'
|
||||
},
|
||||
{
|
||||
condition: {
|
||||
if: 'equals',
|
||||
equals: 'specific value2'
|
||||
},
|
||||
color: 'red'
|
||||
}
|
||||
];
|
||||
|
||||
insightsDialogModel.insight = { label } as IInsightsConfigDetails;
|
||||
insightsDialogModel.rows = [
|
||||
['label1', '3'],
|
||||
['label2', 'specific value2'],
|
||||
['label3', 'value3']
|
||||
];
|
||||
result = insightsDialogModel.getListResources(0, 1);
|
||||
assert.equal(result[0].stateColor, 'green', 'always Condition did not return val as expected');
|
||||
assert.equal(result[1].stateColor, 'red', 'always Condition did not return val as expected');
|
||||
assert.equal(isUndefinedOrNull(result[2].stateColor), true, 'always Condition did not return val as expected');
|
||||
|
||||
label.state = [
|
||||
{
|
||||
condition: {
|
||||
if: 'greaterThanOrEquals',
|
||||
equals: '2'
|
||||
},
|
||||
color: 'green'
|
||||
},
|
||||
{
|
||||
condition: {
|
||||
if: 'equals',
|
||||
equals: 'specific value2'
|
||||
},
|
||||
color: 'red'
|
||||
}
|
||||
];
|
||||
|
||||
insightsDialogModel.insight = { label } as IInsightsConfigDetails;
|
||||
insightsDialogModel.rows = [
|
||||
['label1', '2'],
|
||||
['label2', 'specific value2'],
|
||||
['label3', 'value3']
|
||||
];
|
||||
result = insightsDialogModel.getListResources(0, 1);
|
||||
assert.equal(result[0].stateColor, 'green', 'always Condition did not return val as expected');
|
||||
assert.equal(result[1].stateColor, 'red', 'always Condition did not return val as expected');
|
||||
assert.equal(isUndefinedOrNull(result[2].stateColor), true, 'always Condition did not return val as expected');
|
||||
|
||||
label.state = [
|
||||
{
|
||||
condition: {
|
||||
if: 'lessThan',
|
||||
equals: '8'
|
||||
},
|
||||
color: 'green'
|
||||
},
|
||||
{
|
||||
condition: {
|
||||
if: 'equals',
|
||||
equals: 'specific value2'
|
||||
},
|
||||
color: 'red'
|
||||
}
|
||||
];
|
||||
|
||||
insightsDialogModel.insight = { label } as IInsightsConfigDetails;
|
||||
insightsDialogModel.rows = [
|
||||
['label1', '5'],
|
||||
['label2', 'specific value2'],
|
||||
['label3', 'value3']
|
||||
];
|
||||
result = insightsDialogModel.getListResources(0, 1);
|
||||
assert.equal(result[0].stateColor, 'green', 'always Condition did not return val as expected');
|
||||
assert.equal(result[1].stateColor, 'red', 'always Condition did not return val as expected');
|
||||
assert.equal(isUndefinedOrNull(result[2].stateColor), true, 'always Condition did not return val as expected');
|
||||
|
||||
label.state = [
|
||||
{
|
||||
condition: {
|
||||
if: 'lessThanOrEquals',
|
||||
equals: '8'
|
||||
},
|
||||
color: 'green'
|
||||
},
|
||||
{
|
||||
condition: {
|
||||
if: 'equals',
|
||||
equals: 'specific value2'
|
||||
},
|
||||
color: 'red'
|
||||
}
|
||||
];
|
||||
|
||||
insightsDialogModel.insight = { label } as IInsightsConfigDetails;
|
||||
insightsDialogModel.rows = [
|
||||
['label1', '8'],
|
||||
['label2', 'specific value2'],
|
||||
['label3', 'value3']
|
||||
];
|
||||
result = insightsDialogModel.getListResources(0, 1);
|
||||
assert.equal(result[0].stateColor, 'green', 'always Condition did not return val as expected');
|
||||
assert.equal(result[1].stateColor, 'red', 'always Condition did not return val as expected');
|
||||
assert.equal(isUndefinedOrNull(result[2].stateColor), true, 'always Condition did not return val as expected');
|
||||
|
||||
label.state = [
|
||||
{
|
||||
condition: {
|
||||
if: 'notEquals',
|
||||
equals: '9'
|
||||
},
|
||||
color: 'green'
|
||||
},
|
||||
{
|
||||
condition: {
|
||||
if: 'equals',
|
||||
equals: 'specific value2'
|
||||
},
|
||||
color: 'red'
|
||||
}
|
||||
];
|
||||
|
||||
insightsDialogModel.insight = { label } as IInsightsConfigDetails;
|
||||
insightsDialogModel.rows = [
|
||||
['label1', '8'],
|
||||
['label2', '9'],
|
||||
['label3', 'value3']
|
||||
];
|
||||
result = insightsDialogModel.getListResources(0, 1);
|
||||
assert.equal(result[0].stateColor, 'green', 'always Condition did not return val as expected');
|
||||
assert.equal(isUndefinedOrNull(result[1].stateColor), true, 'always Condition did not return val as expected');
|
||||
assert.equal(result[2].stateColor, 'green', 'always Condition did not return val as expected');
|
||||
|
||||
label.state = [
|
||||
{
|
||||
condition: {
|
||||
if: 'notEquals',
|
||||
equals: '9'
|
||||
},
|
||||
color: 'green'
|
||||
},
|
||||
{
|
||||
condition: {
|
||||
if: 'always'
|
||||
},
|
||||
color: 'red'
|
||||
}
|
||||
];
|
||||
|
||||
insightsDialogModel.insight = { label } as IInsightsConfigDetails;
|
||||
insightsDialogModel.rows = [
|
||||
['label1', '8'],
|
||||
['label2', 'specific value2'],
|
||||
['label3', 'value3']
|
||||
];
|
||||
result = insightsDialogModel.getListResources(0, 1);
|
||||
assert.equal(result[0].stateColor, 'green', 'always Condition did not return val as expected');
|
||||
assert.equal(result[1].stateColor, 'green', 'always Condition did not return val as expected');
|
||||
assert.equal(result[2].stateColor, 'green', 'always Condition did not return val as expected');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,235 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { equal, fail } from 'assert';
|
||||
import * as os from 'os';
|
||||
|
||||
import { resolveQueryFilePath } from 'sql/workbench/services/insights/common/insightsUtils';
|
||||
|
||||
import * as path from 'vs/base/common/path';
|
||||
import * as pfs from 'vs/base/node/pfs';
|
||||
|
||||
import { getRandomTestPath } from 'vs/base/test/node/testUtils';
|
||||
import { Workspace, toWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||
import { ConfigurationResolverService } from 'vs/workbench/services/configurationResolver/browser/configurationResolverService';
|
||||
import { TestContextService } from 'vs/workbench/test/workbenchTestServices';
|
||||
import { IExtensionHostDebugParams, IDebugParams, ParsedArgs } from 'vs/platform/environment/common/environment';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { IWindowConfiguration } from 'vs/platform/windows/common/windows';
|
||||
|
||||
class TestEnvironmentService implements IWorkbenchEnvironmentService {
|
||||
machineSettingsHome: string;
|
||||
machineSettingsPath: string;
|
||||
extensionDevelopmentLocationURI?: URI[];
|
||||
|
||||
constructor(private userEnv: { [key: string]: any }) {
|
||||
|
||||
}
|
||||
|
||||
get configuration(): IWindowConfiguration {
|
||||
return {
|
||||
userEnv: this.userEnv
|
||||
} as IWindowConfiguration;
|
||||
}
|
||||
|
||||
_serviceBrand: any;
|
||||
args: ParsedArgs;
|
||||
execPath: string;
|
||||
cliPath: string;
|
||||
appRoot: string;
|
||||
userHome: string;
|
||||
userDataPath: string;
|
||||
appNameLong: string;
|
||||
appQuality?: string;
|
||||
appSettingsHome: string;
|
||||
appSettingsPath: string;
|
||||
appKeybindingsPath: string;
|
||||
settingsSearchBuildId?: number;
|
||||
settingsSearchUrl?: string;
|
||||
globalStorageHome: string;
|
||||
workspaceStorageHome: string;
|
||||
backupHome: string;
|
||||
backupWorkspacesPath: string;
|
||||
untitledWorkspacesHome: URI;
|
||||
isExtensionDevelopment: boolean;
|
||||
disableExtensions: boolean | string[];
|
||||
builtinExtensionsPath: string;
|
||||
extensionsPath: string;
|
||||
extensionTestsLocationURI?: URI;
|
||||
debugExtensionHost: IExtensionHostDebugParams;
|
||||
debugSearch: IDebugParams;
|
||||
logExtensionHostCommunication: boolean;
|
||||
isBuilt: boolean;
|
||||
wait: boolean;
|
||||
status: boolean;
|
||||
log?: string;
|
||||
logsPath: string;
|
||||
verbose: boolean;
|
||||
skipGettingStarted: boolean;
|
||||
skipReleaseNotes: boolean;
|
||||
skipAddToRecentlyOpened: boolean;
|
||||
mainIPCHandle: string;
|
||||
sharedIPCHandle: string;
|
||||
nodeCachedDataDir?: string;
|
||||
installSourcePath: string;
|
||||
disableUpdates: boolean;
|
||||
disableCrashReporter: boolean;
|
||||
driverHandle?: string;
|
||||
driverVerbose: boolean;
|
||||
}
|
||||
|
||||
suite('Insights Utils tests', function () {
|
||||
let testRootPath: string;
|
||||
let queryFileDir: string;
|
||||
let queryFilePath: string;
|
||||
|
||||
suiteSetup(async () => {
|
||||
// Create test file - just needs to exist for verifying the path resolution worked correctly
|
||||
testRootPath = path.join(os.tmpdir(), 'adstests');
|
||||
queryFileDir = getRandomTestPath(testRootPath, 'insightsutils');
|
||||
await pfs.mkdirp(queryFileDir);
|
||||
queryFilePath = path.join(queryFileDir, 'test.sql');
|
||||
await pfs.writeFile(queryFilePath, '');
|
||||
});
|
||||
|
||||
test('resolveQueryFilePath resolves path correctly with fully qualified path', async () => {
|
||||
const configurationResolverService = new ConfigurationResolverService(
|
||||
undefined,
|
||||
new TestEnvironmentService({}),
|
||||
undefined,
|
||||
undefined,
|
||||
new TestContextService(),
|
||||
undefined);
|
||||
|
||||
const resolvedPath = await resolveQueryFilePath(queryFilePath, new TestContextService(), configurationResolverService);
|
||||
equal(resolvedPath, queryFilePath);
|
||||
});
|
||||
|
||||
test('resolveQueryFilePath resolves path correctly with workspaceRoot var and non-empty workspace containing file', async () => {
|
||||
// Create mock context service with our test folder added as a workspace folder for resolution
|
||||
const contextService = new TestContextService(
|
||||
new Workspace(
|
||||
'TestWorkspace',
|
||||
[toWorkspaceFolder(URI.file(queryFileDir))]
|
||||
));
|
||||
const configurationResolverService = new ConfigurationResolverService(
|
||||
undefined,
|
||||
new TestEnvironmentService({}),
|
||||
undefined,
|
||||
undefined,
|
||||
contextService,
|
||||
undefined);
|
||||
|
||||
const resolvedPath = await resolveQueryFilePath(path.join('${workspaceRoot}', 'test.sql'), contextService, configurationResolverService);
|
||||
equal(resolvedPath, queryFilePath);
|
||||
});
|
||||
|
||||
test('resolveQueryFilePath throws with workspaceRoot var and non-empty workspace not containing file', async (done) => {
|
||||
const tokenizedPath = path.join('${workspaceRoot}', 'test.sql');
|
||||
// Create mock context service with a folder NOT containing our test file to verify it returns original path
|
||||
const contextService = new TestContextService(
|
||||
new Workspace(
|
||||
'TestWorkspace',
|
||||
[toWorkspaceFolder(URI.file(os.tmpdir()))])
|
||||
);
|
||||
const configurationResolverService = new ConfigurationResolverService(
|
||||
undefined,
|
||||
new TestEnvironmentService({}),
|
||||
undefined,
|
||||
undefined,
|
||||
contextService,
|
||||
undefined);
|
||||
|
||||
try {
|
||||
await resolveQueryFilePath(tokenizedPath, contextService, configurationResolverService);
|
||||
fail('Should have thrown');
|
||||
}
|
||||
catch (e) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
test('resolveQueryFilePath throws with workspaceRoot var and empty workspace', async (done) => {
|
||||
const tokenizedPath = path.join('${workspaceRoot}', 'test.sql');
|
||||
// Create mock context service with an empty workspace
|
||||
const contextService = new TestContextService(
|
||||
new Workspace(
|
||||
'TestWorkspace'));
|
||||
const configurationResolverService = new ConfigurationResolverService(
|
||||
undefined,
|
||||
new TestEnvironmentService({}),
|
||||
undefined,
|
||||
undefined,
|
||||
contextService,
|
||||
undefined);
|
||||
|
||||
try {
|
||||
await resolveQueryFilePath(tokenizedPath, contextService, configurationResolverService);
|
||||
fail('Should have thrown');
|
||||
}
|
||||
catch (e) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
test('resolveQueryFilePath resolves path correctly with env var and empty workspace', async () => {
|
||||
const contextService = new TestContextService(
|
||||
new Workspace('TestWorkspace'));
|
||||
|
||||
// Create mock window service with env variable containing test folder for resolution
|
||||
const configurationResolverService = new ConfigurationResolverService(
|
||||
undefined,
|
||||
new TestEnvironmentService({ TEST_PATH: queryFileDir }),
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined);
|
||||
|
||||
const resolvedPath = await resolveQueryFilePath(path.join('${env:TEST_PATH}', 'test.sql'), contextService, configurationResolverService);
|
||||
equal(resolvedPath, queryFilePath);
|
||||
});
|
||||
|
||||
test('resolveQueryFilePath resolves path correctly with env var and non-empty workspace', async () => {
|
||||
const contextService = new TestContextService(
|
||||
new Workspace('TestWorkspace', [toWorkspaceFolder(URI.file(os.tmpdir()))]));
|
||||
|
||||
// Create mock window service with env variable containing test folder for resolution
|
||||
const configurationResolverService = new ConfigurationResolverService(
|
||||
undefined,
|
||||
new TestEnvironmentService({ TEST_PATH: queryFileDir }),
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined);
|
||||
|
||||
const resolvedPath = await resolveQueryFilePath(path.join('${env:TEST_PATH}', 'test.sql'), contextService, configurationResolverService);
|
||||
equal(resolvedPath, queryFilePath);
|
||||
});
|
||||
|
||||
test('resolveQueryFilePath throws if invalid param var specified', async (done) => {
|
||||
const invalidPath = path.join('${INVALID}', 'test.sql');
|
||||
const configurationResolverService = new ConfigurationResolverService(
|
||||
undefined,
|
||||
new TestEnvironmentService({}),
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined);
|
||||
|
||||
try {
|
||||
await resolveQueryFilePath(invalidPath, new TestContextService(), configurationResolverService);
|
||||
fail('Should have thrown');
|
||||
} catch (e) {
|
||||
done();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
suiteTeardown(() => {
|
||||
// Clean up our test files
|
||||
return pfs.rimraf(testRootPath, pfs.RimRafMode.MOVE);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,138 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { InsightsDialogController } from 'sql/workbench/services/insights/node/insightsDialogController';
|
||||
import { InsightsDialogModel } from 'sql/workbench/services/insights/common/insightsDialogModel';
|
||||
import QueryRunner from 'sql/platform/query/common/queryRunner';
|
||||
import { ConnectionManagementService } from 'sql/platform/connection/common/connectionManagementService';
|
||||
import { IInsightsConfigDetails } from 'sql/workbench/parts/dashboard/widgets/insights/interfaces';
|
||||
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||
|
||||
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import { equal } from 'assert';
|
||||
import { Mock, MockBehavior, It } from 'typemoq';
|
||||
import { TestStorageService } from 'vs/workbench/test/workbenchTestServices';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
|
||||
const testData: string[][] = [
|
||||
['1', '2', '3', '4'],
|
||||
['5', '6', '7', '8']
|
||||
];
|
||||
|
||||
const testColumns: string[] = [
|
||||
'col1',
|
||||
'col2'
|
||||
];
|
||||
|
||||
suite('Insights Dialog Controller Tests', () => {
|
||||
test('updates correctly with good input', done => {
|
||||
|
||||
let model = new InsightsDialogModel();
|
||||
|
||||
let { runner, complete } = getPrimedQueryRunner(testData, testColumns);
|
||||
|
||||
let instMoq = Mock.ofType(InstantiationService, MockBehavior.Strict);
|
||||
instMoq.setup(x => x.createInstance(It.isValue(QueryRunner), It.isAny()))
|
||||
.returns(() => runner);
|
||||
|
||||
let connMoq = Mock.ofType(ConnectionManagementService, MockBehavior.Strict, {}, {}, new TestStorageService());
|
||||
connMoq.setup(x => x.connect(It.isAny(), It.isAny()))
|
||||
.returns(() => Promise.resolve(undefined));
|
||||
|
||||
let controller = new InsightsDialogController(
|
||||
model,
|
||||
undefined,
|
||||
undefined,
|
||||
instMoq.object,
|
||||
connMoq.object,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined
|
||||
);
|
||||
|
||||
let profile: IConnectionProfile = {
|
||||
connectionName: 'newname',
|
||||
serverName: 'server',
|
||||
databaseName: 'database',
|
||||
userName: 'user',
|
||||
password: '',
|
||||
authenticationType: '',
|
||||
savePassword: true,
|
||||
groupFullName: '',
|
||||
groupId: '',
|
||||
getOptionsKey: () => '',
|
||||
matches: undefined,
|
||||
providerName: '',
|
||||
saveProfile: true,
|
||||
id: '',
|
||||
options: {}
|
||||
};
|
||||
|
||||
controller.update(<IInsightsConfigDetails>{ query: 'query' }, profile).then(() => {
|
||||
// Once we update the controller, listen on when it changes the model and verify the data it
|
||||
// puts in is correct
|
||||
model.onDataChange(() => {
|
||||
for (let i = 0; i < testData.length; i++) {
|
||||
for (let j = 0; j < testData[i].length; j++) {
|
||||
equal(testData[i][j], model.rows[i][j]);
|
||||
}
|
||||
}
|
||||
done();
|
||||
});
|
||||
// Fake the query Runner telling the controller the query is complete
|
||||
complete();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
interface IPrimedQueryRunner {
|
||||
runner: QueryRunner;
|
||||
complete: () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a mock of query runner than will recreate what a query runner does to return data
|
||||
*/
|
||||
function getPrimedQueryRunner(data: string[][], columns: string[]): IPrimedQueryRunner {
|
||||
const emitter = new Emitter<string>();
|
||||
const querymock = Mock.ofType(QueryRunner, MockBehavior.Strict);
|
||||
querymock.setup(x => x.onQueryEnd).returns(x => emitter.event);
|
||||
querymock.setup(x => x.onMessage).returns(x => new Emitter<azdata.IResultMessage>().event);
|
||||
querymock.setup(x => x.batchSets).returns(x => {
|
||||
return <Array<azdata.BatchSummary>>[
|
||||
{
|
||||
id: 0,
|
||||
resultSetSummaries: [
|
||||
{
|
||||
columnInfo: <Array<azdata.IDbColumn>>columns.map(c => { return { columnName: c }; }),
|
||||
id: 0,
|
||||
rowCount: data.length
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
});
|
||||
|
||||
querymock.setup(x => x.getQueryRows(It.isAnyNumber(), It.isAnyNumber(), It.isAnyNumber(), It.isAnyNumber()))
|
||||
.returns(x => Promise.resolve(<azdata.QueryExecuteSubsetResult>{
|
||||
resultSubset: <azdata.ResultSetSubset>{
|
||||
rowCount: data.length,
|
||||
rows: data.map(r => r.map(c => { return { displayValue: c }; }))
|
||||
}
|
||||
}));
|
||||
|
||||
querymock.setup(x => x.runQuery(It.isAnyString())).returns(x => Promise.resolve());
|
||||
|
||||
const complete = () => {
|
||||
emitter.fire('time');
|
||||
};
|
||||
|
||||
return {
|
||||
runner: querymock.object,
|
||||
complete
|
||||
};
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import { nb, QueryExecuteSubsetResult, IDbColumn, BatchSummary, IResultMessage,
|
||||
import { localize } from 'vs/nls';
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
import { FutureInternal, ILanguageMagic, notebookConstants } from 'sql/workbench/parts/notebook/models/modelInterfaces';
|
||||
import QueryRunner, { EventType } from 'sql/platform/query/common/queryRunner';
|
||||
import QueryRunner from 'sql/platform/query/common/queryRunner';
|
||||
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
@@ -304,18 +304,18 @@ class SqlKernel extends Disposable implements nb.IKernel {
|
||||
}
|
||||
|
||||
private addQueryEventListeners(queryRunner: QueryRunner): void {
|
||||
this._register(queryRunner.addListener(EventType.COMPLETE, () => {
|
||||
this._register(queryRunner.onQueryEnd(() => {
|
||||
this.queryComplete().catch(error => {
|
||||
this._errorMessageService.showDialog(Severity.Error, sqlKernelError, error);
|
||||
});
|
||||
}));
|
||||
this._register(queryRunner.addListener(EventType.MESSAGE, message => {
|
||||
this._register(queryRunner.onMessage(message => {
|
||||
// TODO handle showing a messages output (should be updated with all messages, only changing 1 output in total)
|
||||
if (this._future) {
|
||||
this._future.handleMessage(message);
|
||||
}
|
||||
}));
|
||||
this._register(queryRunner.addListener(EventType.BATCH_COMPLETE, batch => {
|
||||
this._register(queryRunner.onBatchEnd(batch => {
|
||||
if (this._future) {
|
||||
this._future.handleBatchEnd(batch);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user