Skip to content

Commit f565804

Browse files
author
Aditya Bist
authored
Increase code coverage (#1546)
* added some more tests * more coverage * remove empty test * add run query test * add more utils and connection store tests * add server status view tests * service installer util tests * added more OE tests * fix timer tests
1 parent e3d42ca commit f565804

16 files changed

+393
-13
lines changed

gulpfile.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ gulp.task('ext:test', (done) => {
243243
workspace = process.cwd();
244244
}
245245
process.env.JUNIT_REPORT_PATH = workspace + '/test-reports/ext_xunit.xml';
246-
var args = ['--verbose', '--disable-gpu', '--disable-telemetry', '--disable-updates'];
246+
var args = ['--verbose', '--disable-gpu', '--disable-telemetry', '--disable-updates', '-n'];
247247
cproc.exec(`code --extensionDevelopmentPath="${workspace}" --extensionTestsPath="${workspace}/out/test" ${args.join(' ')}`,
248248
{ maxBuffer: 1024 * 500 },
249249
(error, stdout, stderr) => {

src/controllers/mainController.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ export default class MainController implements vscode.Disposable {
320320
self._prompter = new CodeAdapter(self._vscodeWrapper);
321321

322322
// Init content provider for results pane
323-
self._outputContentProvider = new SqlOutputContentProvider(self._context, self._statusview);
323+
self._outputContentProvider = new SqlOutputContentProvider(self._context, self._statusview, self._vscodeWrapper);
324324

325325
// Init connection manager and connection MRU
326326
self._connectionMgr = new ConnectionManager(self._context, self._statusview, self._prompter);
@@ -461,8 +461,9 @@ export default class MainController implements vscode.Disposable {
461461

462462
/**
463463
* Manage connection profiles (create, edit, remove).
464+
* Public for testing purposes
464465
*/
465-
private async onManageProfiles(): Promise<void> {
466+
public async onManageProfiles(): Promise<void> {
466467
if (this.canRunCommand()) {
467468
Telemetry.sendTelemetryEvent('ManageProfiles');
468469
await this._connectionMgr.onManageProfiles();

src/controllers/webviewController.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,10 @@ export class WebviewPanelController implements vscode.Disposable {
6969
this.proxy = createProxy(createMessageProtocol(this._panel.webview), serverProxy, false);
7070
}
7171

72-
private newResultPaneViewColumn(queryUri: string): vscode.ViewColumn {
72+
/**
73+
* Public for testing purposes
74+
*/
75+
public newResultPaneViewColumn(queryUri: string): vscode.ViewColumn {
7376
// Find configuration options
7477
let config = this._vscodeWrapper.getConfiguration(Constants.extensionConfigSectionName, queryUri);
7578
let splitPaneSelection = config[Constants.configSplitPaneSelection];

src/languageservice/serverStatus.ts

+7
Original file line numberDiff line numberDiff line change
@@ -121,5 +121,12 @@ export class ServerStatusView implements IStatusView, vscode.Disposable {
121121
this._statusBarItem.dispose();
122122
}
123123
}
124+
125+
/**
126+
* For testing purposes
127+
*/
128+
public get statusBarItem(): vscode.StatusBarItem {
129+
return this._statusBarItem;
130+
}
124131
}
125132

src/languageservice/serviceInstallerUtil.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import ServerProvider from './server';
1212
import {IStatusView} from './interfaces';
1313
import {ILogger} from '../models/interfaces';
1414

15-
class StubStatusView implements IStatusView {
15+
export class StubStatusView implements IStatusView {
1616
installingService(): void {
1717
console.log('...');
1818
}
@@ -29,7 +29,7 @@ class StubStatusView implements IStatusView {
2929
}
3030
}
3131

32-
class StubLogger implements ILogger {
32+
export class StubLogger implements ILogger {
3333
logDebug(message: string): void {
3434
console.log(message);
3535
}

src/models/sqlOutputContentProvider.ts

+7-3
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,16 @@ export class SqlOutputContentProvider {
4040

4141
// MEMBER VARIABLES ////////////////////////////////////////////////////
4242
private _queryResultsMap: Map<string, QueryRunnerState> = new Map<string, QueryRunnerState>();
43-
private _vscodeWrapper: VscodeWrapper;
4443
private _panels = new Map<string, WebviewPanelController>();
4544

4645
// CONSTRUCTOR /////////////////////////////////////////////////////////
47-
constructor(private context: vscode.ExtensionContext, private _statusView: StatusView) {
48-
this._vscodeWrapper = new VscodeWrapper();
46+
constructor(
47+
private context: vscode.ExtensionContext,
48+
private _statusView: StatusView,
49+
private _vscodeWrapper) {
50+
if (!_vscodeWrapper) {
51+
this._vscodeWrapper = new VscodeWrapper();
52+
}
4953
}
5054

5155
public rowRequestHandler(uri: string, batchId: number, resultId: number, rowStart: number, numberOfRows: number): Promise<ResultSetSubset> {

test/connectionStore.test.ts

+26
Original file line numberDiff line numberDiff line change
@@ -645,5 +645,31 @@ suite('ConnectionStore tests', () => {
645645
done();
646646
});
647647

648+
test('lookupPassword should call the credential store to read the credential', async () => {
649+
650+
let connectionStore = new ConnectionStore(context.object, credentialStore.object, connectionConfig.object);
651+
let connectionCredentials: any = {
652+
server: 'test_server',
653+
database: 'test_database',
654+
user: 'test_user'
655+
};
656+
let password = await connectionStore.lookupPassword(connectionCredentials);
657+
credentialStore.verify(c => c.readCredential(TypeMoq.It.isAnyString()), TypeMoq.Times.once());
658+
assert.equal(password, undefined);
659+
});
660+
661+
test('deleteCredential should call the credential store to delete the credential', async () => {
662+
credentialStore.setup(c => c.readCredential(TypeMoq.It.isAny())).returns(() => Promise.resolve({ credentialId: 'test', password: 'test'}));
663+
credentialStore.setup(c => c.deleteCredential(TypeMoq.It.isAny())).returns(() => undefined);
664+
let connectionStore = new ConnectionStore(context.object, credentialStore.object, connectionConfig.object);
665+
let connectionCredentials: any = {
666+
server: 'test_server',
667+
database: 'test_database',
668+
user: 'test_user'
669+
};
670+
let password = await connectionStore.deleteCredential(connectionCredentials);
671+
credentialStore.verify(c => c.deleteCredential(TypeMoq.It.isAnyString()), TypeMoq.Times.once());
672+
assert.equal(password, undefined);
673+
});
648674
});
649675

test/mainController.test.ts

+12
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import LocalizedConstants = require('../src/constants/localizedConstants');
1616
import VscodeWrapper from '../src/controllers/vscodeWrapper';
1717
import { TestExtensionContext } from './stubs';
1818
import assert = require('assert');
19+
import { connect } from 'http2';
1920

2021
suite('MainController Tests', () => {
2122
let document: vscode.TextDocument;
@@ -251,4 +252,15 @@ suite('MainController Tests', () => {
251252
let result = (controller as any).validateTextDocumentHasFocus();
252253
assert.equal(result, true, 'Expected validateTextDocumentHasFocus to return true when the active document URI is not undefined');
253254
});
255+
256+
test('onManageProfiles should call the connetion manager to manage profiles', async () => {
257+
let contextMock: TypeMoq.IMock<vscode.ExtensionContext> = TypeMoq.Mock.ofType(TestExtensionContext);
258+
let vscodeWrapperMock: TypeMoq.IMock<VscodeWrapper> = TypeMoq.Mock.ofType(VscodeWrapper);
259+
connectionManager.setup(c => c.onManageProfiles());
260+
let controller: MainController = new MainController(contextMock.object,
261+
connectionManager.object,
262+
vscodeWrapperMock.object);
263+
await controller.onManageProfiles();
264+
connectionManager.verify(c => c.onManageProfiles(), TypeMoq.Times.once());
265+
});
254266
});

test/objectExplorerProvider.test.ts

+60-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { ObjectExplorerProvider } from '../src/objectExplorer/objectExplorerProv
88
import { ObjectExplorerService } from '../src/objectExplorer/objectExplorerService';
99
import ConnectionManager from '../src/controllers/connectionManager';
1010
import SqlToolsServiceClient from '../src/languageservice/serviceclient';
11-
import { expect } from 'chai';
11+
import { expect, assert } from 'chai';
1212
import { TreeNodeInfo } from '../src/objectExplorer/treeNodeInfo';
1313
import { ConnectionCredentials } from '../src/models/connectionCredentials';
1414
import { Deferred } from '../src/protocol';
@@ -17,6 +17,8 @@ import * as LocalizedConstants from '../src/constants/localizedConstants';
1717
import { AccountSignInTreeNode } from '../src/objectExplorer/accountSignInTreeNode';
1818
import { ConnectTreeNode } from '../src/objectExplorer/connectTreeNode';
1919
import { NodeInfo } from '../src/models/contracts/objectExplorer/nodeInfo';
20+
import { IConnectionCredentials } from '../src/models/interfaces';
21+
import { Type } from '@angular/core';
2022

2123
suite('Object Explorer Provider Tests', () => {
2224

@@ -122,6 +124,63 @@ suite('Object Explorer Provider Tests', () => {
122124
}
123125
done();
124126
});
127+
128+
test('Test expandNode function', () => {
129+
objectExplorerService.setup(s => s.expandNode(TypeMoq.It.isAny(), TypeMoq.It.isAnyString(), TypeMoq.It.isAny()));
130+
let node: any = {
131+
connectionCredentials: undefined
132+
};
133+
objectExplorerProvider.expandNode(node, 'test_session', undefined);
134+
objectExplorerService.verify(s => s.expandNode(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
135+
let treeItem = objectExplorerProvider.getTreeItem(node);
136+
assert.equal(treeItem, node);
137+
});
138+
139+
test('Test signInNode function', () => {
140+
objectExplorerService.setup(s => s.signInNodeServer(TypeMoq.It.isAny()));
141+
let node: any = {
142+
connectionCredentials: undefined
143+
};
144+
objectExplorerProvider.signInNodeServer(node);
145+
objectExplorerService.verify(s => s.signInNodeServer(TypeMoq.It.isAny()), TypeMoq.Times.once());
146+
});
147+
148+
test('Test updateNode function', () => {
149+
objectExplorerService.setup(s => s.updateNode(TypeMoq.It.isAny()));
150+
let node: any = {
151+
connectionCredentials: undefined
152+
};
153+
objectExplorerProvider.updateNode(node);
154+
objectExplorerService.verify(s => s.updateNode(node), TypeMoq.Times.once());
155+
});
156+
157+
test('Test removeConnectionNodes function', () => {
158+
objectExplorerService.setup(s => s.removeConnectionNodes(TypeMoq.It.isAny()));
159+
let connections: any[] = [{server: 'test_server'}];
160+
objectExplorerProvider.removeConnectionNodes(connections);
161+
objectExplorerService.verify(s => s.removeConnectionNodes(connections), TypeMoq.Times.once());
162+
});
163+
164+
test('Test addDisconnectedNode function', () => {
165+
objectExplorerService.setup(s => s.addDisconnectedNode(TypeMoq.It.isAny()));
166+
let connectionCredentials: any = { server: 'test_server'};
167+
objectExplorerProvider.addDisconnectedNode(connectionCredentials);
168+
objectExplorerService.verify(s => s.addDisconnectedNode(TypeMoq.It.isAny()), TypeMoq.Times.once());
169+
});
170+
171+
test('Test currentNode getter', () => {
172+
objectExplorerService.setup(s => s.currentNode);
173+
objectExplorerProvider.currentNode;
174+
objectExplorerService.verify(s => s.currentNode, TypeMoq.Times.once());
175+
});
176+
177+
test('Test rootNodeConnections getter', () => {
178+
let testConnections = [new ConnectionCredentials()];
179+
objectExplorerService.setup(s => s.rootNodeConnections).returns(() => testConnections);
180+
let rootConnections = objectExplorerProvider.rootNodeConnections;
181+
objectExplorerService.verify(s => s.rootNodeConnections, TypeMoq.Times.once());
182+
assert.equal(rootConnections, testConnections);
183+
});
125184
});
126185

127186
suite('Object Explorer Node Types Test', () => {

test/objectExplorerUtils.test.ts

+8
Original file line numberDiff line numberDiff line change
@@ -98,4 +98,12 @@ suite('Object Explorer Utils Tests', () => {
9898
assert.equal(databaseName, expectedDatabaseNames[i]);
9999
}
100100
});
101+
102+
test('Test isFirewallError', () => {
103+
const testMessage = 'test_error';
104+
assert.isNotTrue(ObjectExplorerUtils.isFirewallError(testMessage), 'Error should not be a firewall error');
105+
const firewallMessageCheck = Constants.firewallErrorMessage;
106+
let testFirewallMessage = `test ${firewallMessageCheck} foo bar`;
107+
assert.isTrue(ObjectExplorerUtils.isFirewallError(testFirewallMessage), 'Error should be a firewall error');
108+
});
101109
});

test/serverStatus.test.ts

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
'use strict';
7+
8+
import { ServerStatusView } from '../src/languageservice/serverStatus';
9+
import { assert } from 'chai';
10+
import Constants = require('../src/constants/constants');
11+
12+
suite('Server Status View Tests', () => {
13+
14+
let serverStatusView: ServerStatusView;
15+
16+
setup(() => {
17+
serverStatusView = new ServerStatusView();
18+
});
19+
20+
test('Test installing service status', (done) => {
21+
serverStatusView.installingService();
22+
let p = new Promise((resolve, reject) => {
23+
setTimeout(() => {
24+
let statusBarItem = serverStatusView.statusBarItem;
25+
assert.isUndefined(statusBarItem.command, 'Status Bar Item command should be undefined');
26+
let installingServiceText = '$(desktop-download) ' + Constants.serviceInstalling;
27+
assert.isTrue(statusBarItem.text.includes(installingServiceText), 'Status Bar Item text should be updated');
28+
serverStatusView.dispose();
29+
resolve();
30+
}, 300);
31+
});
32+
p.then(() => done());
33+
});
34+
35+
test('Test update service download progress status', () => {
36+
serverStatusView.updateServiceDownloadingProgress(50);
37+
let statusBarItem = serverStatusView.statusBarItem;
38+
let progressText = '$(cloud-download) ' + `${Constants.serviceDownloading} ... 50%`;
39+
assert.equal(statusBarItem.text, progressText, 'Status bar item text should show the correct progress percentage');
40+
serverStatusView.dispose();
41+
});
42+
43+
test('Test service installed status', () => {
44+
serverStatusView.serviceInstalled();
45+
let statusBarItem = serverStatusView.statusBarItem;
46+
assert.isUndefined(statusBarItem.command, 'Status Bar Item command should be undefined');
47+
assert.equal(statusBarItem.text, Constants.serviceInstalled, 'Status Bar Item text should show installed');
48+
serverStatusView.dispose();
49+
});
50+
51+
test('Test service installation failed status', () => {
52+
serverStatusView.serviceInstallationFailed();
53+
let statusBarItem = serverStatusView.statusBarItem;
54+
assert.isUndefined(statusBarItem.command, 'Status Bar Item command should be undefined');
55+
assert.equal(statusBarItem.text, Constants.serviceInstallationFailed, 'Status Bar Item text should show installation failure');
56+
serverStatusView.dispose();
57+
});
58+
});

0 commit comments

Comments
 (0)