mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
platformService tests and move tests from tdd to bdd (#13131)
This commit is contained in:
@@ -85,9 +85,9 @@ function validate(test: TestDefinition, semVerProxy: SymVerProxyTest) {
|
||||
}
|
||||
}
|
||||
|
||||
suite('SemVeryProxy Tests', function (): void {
|
||||
describe('SemVeryProxy Tests', function (): void {
|
||||
testDefinitions.forEach((semVerTest: TestDefinition) => {
|
||||
test(semVerTest.testName, () => {
|
||||
it(semVerTest.testName, () => {
|
||||
const semVerProxy = new SymVerProxyTest(semVerTest.inputVersion);
|
||||
validate(semVerTest, semVerProxy);
|
||||
});
|
||||
|
||||
@@ -9,7 +9,7 @@ const testRunner = require('vscodetestcover');
|
||||
const suite = 'resource-deployment Extension Tests';
|
||||
|
||||
const mochaOptions: any = {
|
||||
ui: 'tdd',
|
||||
ui: 'bdd',
|
||||
useColors: true,
|
||||
timeout: 10000
|
||||
};
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'mocha';
|
||||
import { apiService } from '../../services/apiService';
|
||||
import assert = require('assert');
|
||||
import { apiService } from '../services/apiService';
|
||||
|
||||
suite('API Service Tests', function (): void {
|
||||
test('getAzurecoreApi returns azure api', () => {
|
||||
describe('API Service Tests', function (): void {
|
||||
it('get azurecoreApi returns azure api', () => {
|
||||
const api = apiService.azurecoreApi;
|
||||
assert(api !== undefined);
|
||||
});
|
||||
@@ -6,12 +6,12 @@
|
||||
import 'mocha';
|
||||
import * as TypeMoq from 'typemoq';
|
||||
import * as should from 'should';
|
||||
import { IPlatformService, CommandOptions } from '../services/platformService';
|
||||
import { AzdataService } from '../services/azdataService';
|
||||
import { BdcDeploymentType } from '../interfaces';
|
||||
import { IPlatformService, CommandOptions } from '../../services/platformService';
|
||||
import { AzdataService } from '../../services/azdataService';
|
||||
import { BdcDeploymentType } from '../../interfaces';
|
||||
|
||||
suite('azdata service Tests', function (): void {
|
||||
test('azdata service handles deployment types properly', async () => {
|
||||
describe('azdata service Tests', function (): void {
|
||||
it('azdata service handles deployment types properly', async () => {
|
||||
const mockPlatformService = TypeMoq.Mock.ofType<IPlatformService>();
|
||||
const azdataService = new AzdataService(mockPlatformService.object);
|
||||
mockPlatformService.setup((service) => service.runCommand(TypeMoq.It.isAnyString(), TypeMoq.It.isAny())).returns((command: string, options: CommandOptions | undefined) => {
|
||||
@@ -30,7 +30,7 @@ suite('azdata service Tests', function (): void {
|
||||
mockPlatformService.verify((service) => service.runCommand(TypeMoq.It.isAnyString(), TypeMoq.It.isAny()), TypeMoq.Times.exactly(5));
|
||||
});
|
||||
|
||||
test('azdata service returns correct deployment profiles', async () => {
|
||||
it('azdata service returns correct deployment profiles', async () => {
|
||||
const mockPlatformService = TypeMoq.Mock.ofType<IPlatformService>();
|
||||
const azdataService = new AzdataService(mockPlatformService.object);
|
||||
mockPlatformService.setup((service => service.storagePath())).returns(() => {
|
||||
@@ -5,14 +5,14 @@
|
||||
|
||||
import * as TypeMoq from 'typemoq';
|
||||
import 'mocha';
|
||||
import { NotebookService } from '../services/notebookService';
|
||||
import { NotebookService } from '../../services/notebookService';
|
||||
import assert = require('assert');
|
||||
import { NotebookPathInfo } from '../interfaces';
|
||||
import { IPlatformService } from '../services/platformService';
|
||||
import { NotebookPathInfo } from '../../interfaces';
|
||||
import { IPlatformService } from '../../services/platformService';
|
||||
|
||||
suite('Notebook Service Tests', function (): void {
|
||||
describe('Notebook Service Tests', function (): void {
|
||||
|
||||
test('getNotebook with string parameter', () => {
|
||||
it('getNotebook with string parameter', () => {
|
||||
const mockPlatformService = TypeMoq.Mock.ofType<IPlatformService>();
|
||||
const notebookService = new NotebookService(mockPlatformService.object, '');
|
||||
const notebookInput = 'test-notebook.ipynb';
|
||||
@@ -28,7 +28,7 @@ suite('Notebook Service Tests', function (): void {
|
||||
mockPlatformService.verify((service) => service.platform(), TypeMoq.Times.never());
|
||||
});
|
||||
|
||||
test('getNotebook with NotebookInfo parameter', () => {
|
||||
it('getNotebook with NotebookInfo parameter', () => {
|
||||
const mockPlatformService = TypeMoq.Mock.ofType<IPlatformService>();
|
||||
const notebookService = new NotebookService(mockPlatformService.object, '');
|
||||
const notebookWin32 = 'test-notebook-win32.ipynb';
|
||||
@@ -58,7 +58,7 @@ suite('Notebook Service Tests', function (): void {
|
||||
mockPlatformService.verify((service) => service.platform(), TypeMoq.Times.once());
|
||||
});
|
||||
|
||||
test('findNextUntitledEditorName with no name conflict', () => {
|
||||
it('findNextUntitledEditorName with no name conflict', () => {
|
||||
const mockPlatformService = TypeMoq.Mock.ofType<IPlatformService>();
|
||||
const notebookService = new NotebookService(mockPlatformService.object, '');
|
||||
const notebookFileName = 'mynotebook.ipynb';
|
||||
@@ -72,7 +72,7 @@ suite('Notebook Service Tests', function (): void {
|
||||
assert.equal(actualFileName, expectedTargetFile, 'target file name is not correct');
|
||||
});
|
||||
|
||||
test('findNextUntitledEditorName with name conflicts', () => {
|
||||
it('findNextUntitledEditorName with name conflicts', () => {
|
||||
const mockPlatformService = TypeMoq.Mock.ofType<IPlatformService>();
|
||||
const notebookService = new NotebookService(mockPlatformService.object, '');
|
||||
const notebookFileName = 'mynotebook.ipynb';
|
||||
@@ -0,0 +1,243 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import * as azdata from 'azdata';
|
||||
import * as fs from 'fs';
|
||||
import 'mocha';
|
||||
import * as os from 'os';
|
||||
import * as cp from 'promisify-child-process';
|
||||
import * as should from 'should';
|
||||
import * as sinon from 'sinon';
|
||||
import * as sudo from 'sudo-prompt';
|
||||
import * as TypeMoq from 'typemoq';
|
||||
import * as vscode from 'vscode';
|
||||
import { tryExecuteAction } from '../../common/utils';
|
||||
import { OsDistribution } from '../../interfaces';
|
||||
import { extensionOutputChannel, PlatformService } from '../../services/platformService';
|
||||
import { TestChildProcessPromise } from '../stubs';
|
||||
|
||||
const globalStoragePath = os.tmpdir();
|
||||
const platformService = new PlatformService(globalStoragePath);
|
||||
|
||||
describe('PlatformService', () => {
|
||||
beforeEach('PlatformService setup', async () => {
|
||||
await platformService.initialize();
|
||||
});
|
||||
afterEach('PlatformService cleanup', () => {
|
||||
sinon.restore();
|
||||
});
|
||||
it('storagePath', () => {
|
||||
const result = platformService.storagePath();
|
||||
result.should.equal(globalStoragePath);
|
||||
});
|
||||
it('platform', () => {
|
||||
const result = platformService.platform();
|
||||
result.should.equal(process.platform);
|
||||
});
|
||||
it('outputChannelName', () => {
|
||||
const result = platformService.outputChannelName();
|
||||
result.should.equal(extensionOutputChannel);
|
||||
});
|
||||
describe('output channel', () => {
|
||||
let outputChannelStub: TypeMoq.IMock<vscode.OutputChannel>;
|
||||
beforeEach('output channel setup', () => {
|
||||
outputChannelStub = TypeMoq.Mock.ofType<vscode.OutputChannel>();
|
||||
});
|
||||
it('showOutputChannel', () => {
|
||||
outputChannelStub.setup(c => c.show(TypeMoq.It.isAny())).callback((preserveFocus => {
|
||||
preserveFocus.should.be.true();
|
||||
}));
|
||||
platformService.showOutputChannel(true);
|
||||
});
|
||||
describe('logToOutputChannel', () => {
|
||||
['', undefined, 'header'].forEach(header => {
|
||||
it(`header = ${header}`, () => {
|
||||
const data = 'data';
|
||||
outputChannelStub.setup(c => c.appendLine(TypeMoq.It.isAny())).callback((line => {
|
||||
line.should.equal(header + line);
|
||||
}));
|
||||
platformService.logToOutputChannel(data, header);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
it('osDistribution', () => {
|
||||
const result = platformService.osDistribution();
|
||||
switch (process.platform) {
|
||||
case 'darwin': result.should.equal(OsDistribution.darwin); break;
|
||||
case 'win32': result.should.equal(OsDistribution.win32); break;
|
||||
case 'linux': result.should.equal(OsDistribution.debian); break;
|
||||
default: result.should.equal(OsDistribution.others); break;
|
||||
}
|
||||
});
|
||||
describe('file/directory', () => {
|
||||
const filePath = __filename;
|
||||
const contents = __dirname; //a known value
|
||||
[true, false, 'throws'].forEach((fileExists => {
|
||||
it(`fileExists - ${fileExists}`, async () => {
|
||||
switch (fileExists) {
|
||||
case true: (await platformService.fileExists(filePath)).should.be.true(); break;
|
||||
case false: {
|
||||
sinon.stub(fs.promises, 'access').rejects({ code: 'ENOENT' });
|
||||
(await platformService.fileExists(filePath)).should.be.false();
|
||||
break;
|
||||
}
|
||||
case 'throws': {
|
||||
sinon.stub(fs.promises, 'access').rejects({});
|
||||
const { error } = await tryExecuteAction(() => platformService.fileExists(filePath));
|
||||
should(error).not.be.undefined();
|
||||
break;
|
||||
}
|
||||
default: throw new Error('unexpected error');
|
||||
}
|
||||
});
|
||||
}));
|
||||
describe('deleteFile', () => {
|
||||
[true, false].forEach(fileExists => {
|
||||
it(`fileExists - ${fileExists}`, async () => {
|
||||
if (fileExists) {
|
||||
const stub = sinon.stub(fs.promises, 'unlink').resolves();
|
||||
await platformService.deleteFile(filePath);
|
||||
stub.callCount.should.equal(1);
|
||||
stub.getCall(0).args[0].should.equal(filePath);
|
||||
} else {
|
||||
sinon.stub(fs.promises, 'access').rejects({ code: 'ENOENT' }); // causes fileExists to return false
|
||||
const stub = sinon.stub(fs.promises, 'unlink').resolves();
|
||||
await platformService.deleteFile(filePath);
|
||||
stub.callCount.should.equal(0); // verifies that unlink was not called
|
||||
}
|
||||
});
|
||||
});
|
||||
[true, false].forEach(async ignoreError => {
|
||||
it(`throws with ignoreError: ${ignoreError}`, async () => {
|
||||
const stub = sinon.stub(fs.promises, 'unlink').throws();
|
||||
const { error } = await tryExecuteAction(() => platformService.deleteFile(filePath, ignoreError));
|
||||
stub.callCount.should.equal(1);
|
||||
stub.getCall(0).args[0].should.equal(filePath);
|
||||
if (ignoreError) {
|
||||
should(error).be.undefined();
|
||||
} else {
|
||||
should(error).not.be.undefined();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
it('openFile', () => {
|
||||
const stub = sinon.stub(vscode.commands, 'executeCommand').resolves(); //resolves with a known string
|
||||
platformService.openFile(filePath);
|
||||
stub.callCount.should.equal(1);
|
||||
stub.getCall(0).args[0].should.equal('vscode.open');
|
||||
stub.getCall(0).args[1].path.should.equal(filePath);
|
||||
});
|
||||
it('readTextFile', async () => {
|
||||
sinon.stub(fs.promises, 'readFile').resolves(contents);
|
||||
const result = await platformService.readTextFile(filePath);
|
||||
result.should.equal(contents);
|
||||
});
|
||||
it('saveTextFile', async () => {
|
||||
const stub = sinon.stub(fs.promises, 'writeFile').resolves(); //resolves with a known string
|
||||
await platformService.saveTextFile(contents, filePath);
|
||||
stub.callCount.should.equal(1);
|
||||
stub.getCall(0).args[0].should.equal(filePath);
|
||||
stub.getCall(0).args[1].should.equal(contents);
|
||||
});
|
||||
it('copyFile', async () => {
|
||||
const target = __dirname; //arbitrary path
|
||||
const stub = sinon.stub(fs.promises, 'copyFile').resolves();
|
||||
await platformService.copyFile(filePath, target);
|
||||
stub.callCount.should.equal(1);
|
||||
stub.getCall(0).args[0].should.equal(filePath);
|
||||
stub.getCall(0).args[1].should.equal(target);
|
||||
});
|
||||
it('makeDirectory ', async () => {
|
||||
const target = __dirname; //arbitrary path
|
||||
sinon.stub(fs.promises, 'access').rejects({ code: 'ENOENT' }); // this simulates the target directory to not Exist.
|
||||
const stub = sinon.stub(fs.promises, 'mkdir').resolves();
|
||||
await platformService.makeDirectory(target);
|
||||
stub.callCount.should.equal(1);
|
||||
stub.getCall(0).args[0].should.equal(target);
|
||||
});
|
||||
});
|
||||
it('showErrorMessage', () => {
|
||||
const error = __dirname; //arbitrary known string
|
||||
const stub = sinon.stub(vscode.window, 'showErrorMessage').resolves(); //resolves with a known string
|
||||
platformService.showErrorMessage(error);
|
||||
stub.callCount.should.equal(1);
|
||||
stub.getCall(0).args[0].should.equal(error);
|
||||
});
|
||||
describe('isNotebookNameUsed', () => {
|
||||
[true, false].forEach((isUsed => {
|
||||
it(`return value: ${isUsed}`, () => {
|
||||
const title = __filename; //arbitrary known string
|
||||
if (isUsed) {
|
||||
sinon.stub(azdata.nb, 'notebookDocuments').get(() => [{ isUntitled: true, fileName: title }]);
|
||||
sinon.stub(vscode.workspace, 'textDocuments').get(() => [{ isUntitled: true, fileName: title }]);
|
||||
} else {
|
||||
sinon.stub(azdata.nb, 'notebookDocuments').get(() => [{ isUntitled: true, fileName: '' }]);
|
||||
sinon.stub(vscode.workspace, 'textDocuments').get(() => [{ isUntitled: true, fileName: '' }]);
|
||||
}
|
||||
const result = platformService.isNotebookNameUsed(title);
|
||||
result.should.equal(isUsed);
|
||||
});
|
||||
}));
|
||||
});
|
||||
describe('runCommand', () => {
|
||||
[
|
||||
{ commandSucceeds: true },
|
||||
{ commandSucceeds: false, ignoreError: true },
|
||||
{ commandSucceeds: false, ignoreError: false },
|
||||
].forEach(({ commandSucceeds, ignoreError }) => {
|
||||
if (ignoreError && commandSucceeds) {
|
||||
return; //exit out of the loop as we do not handle ignoreError when command is successful
|
||||
}
|
||||
it(`non-sudo, commandSucceeds: ${commandSucceeds}, ignoreError: ${ignoreError}`, async () => {
|
||||
const command = __dirname; // arbitrary command string, and success string on successful execution and error string on error
|
||||
const child = new TestChildProcessPromise<cp.Output>();
|
||||
const stub = sinon.stub(cp, 'spawn').returns(child);
|
||||
const runningCommand = platformService.runCommand(command, { commandTitle: 'title', ignoreError: ignoreError });
|
||||
// fake runCommand to behave like echo, returning the command back as stdout/stderr/error.
|
||||
// TestChildProcessPromise object shares the stdout/stderr stream for convenience with the child stream.
|
||||
if (commandSucceeds) {
|
||||
child.emit('data', command);
|
||||
child.emit('exit', 0, null); //resolve with 0 exit code
|
||||
child.resolve({ stdout: command });
|
||||
} else {
|
||||
child.emit('data', command);
|
||||
child.emit('exit', 1, null); // resolve with non-zero exit code
|
||||
child.reject({ stderr: command });
|
||||
}
|
||||
const { result, error } = await tryExecuteAction(() => runningCommand);
|
||||
verifyCommandExecution(stub, result, error, command, commandSucceeds, ignoreError);
|
||||
});
|
||||
|
||||
it(`sudo, commandSucceeds: ${commandSucceeds}, ignoreError: ${ignoreError}`, async () => {
|
||||
const command = __dirname; // arbitrary command string, and success string on successful execution
|
||||
const stub = sinon.stub(sudo, 'exec').callsFake((cmd, _options, cb) => {
|
||||
// behaves like echo, returning the _cmd back as stdout/stderr/error.
|
||||
if (commandSucceeds) {
|
||||
cb(''/* error */, cmd/* stdout */, ''/* stderr */);
|
||||
} else {
|
||||
cb(cmd/* error */, ''/* stdout */, cmd/* stderr */);
|
||||
}
|
||||
});
|
||||
const { error, result } = await tryExecuteAction(() => platformService.runCommand(command, { commandTitle: 'title', ignoreError: ignoreError, sudo: true, workingDirectory: __dirname }));
|
||||
verifyCommandExecution(stub, result, error, command, commandSucceeds, ignoreError);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function verifyCommandExecution(stub: sinon.SinonStub, result: string | undefined, error: any, command: string, commandSucceeds: boolean | undefined, ignoreError: boolean | undefined) {
|
||||
stub.callCount.should.equal(1);
|
||||
if (commandSucceeds) {
|
||||
result!.should.equal(command);
|
||||
} else {
|
||||
if (ignoreError) {
|
||||
should(error).be.undefined();
|
||||
(result === undefined || result.length === 0).should.be.true('result should be an empty string or be undefined when an error occurs');
|
||||
} else {
|
||||
should(error).not.be.undefined();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,14 +8,14 @@ import * as TypeMoq from 'typemoq';
|
||||
import assert = require('assert');
|
||||
import should = require('should');
|
||||
import { EOL } from 'os';
|
||||
import { ResourceTypeService, processWhenClause } from '../services/resourceTypeService';
|
||||
import { IPlatformService } from '../services/platformService';
|
||||
import { ToolsService } from '../services/toolsService';
|
||||
import { NotebookService } from '../services/notebookService';
|
||||
import { ResourceTypeService, processWhenClause } from '../../services/resourceTypeService';
|
||||
import { IPlatformService } from '../../services/platformService';
|
||||
import { ToolsService } from '../../services/toolsService';
|
||||
import { NotebookService } from '../../services/notebookService';
|
||||
|
||||
suite('Resource Type Service Tests', function (): void {
|
||||
describe('Resource Type Service Tests', function (): void {
|
||||
|
||||
test('test resource types', () => {
|
||||
it('test resource types', () => {
|
||||
const mockPlatformService = TypeMoq.Mock.ofType<IPlatformService>();
|
||||
const toolsService = new ToolsService(mockPlatformService.object);
|
||||
const notebookService = new NotebookService(mockPlatformService.object, '');
|
||||
@@ -47,7 +47,7 @@ suite('Resource Type Service Tests', function (): void {
|
||||
assert(validationErrors.length === 0, `Validation errors detected in the package.json: ${validationErrors.join(EOL)}.`);
|
||||
});
|
||||
|
||||
test('Selected options containing all when clauses should return true', () => {
|
||||
it('Selected options containing all when clauses should return true', () => {
|
||||
const whenSelectedTrue: { when: string; selectedOptions: { option: string, value: string }[] }[] = [
|
||||
{
|
||||
when: 'resourceType=sql-bdc && newType=sql-windows-setup', selectedOptions: [{ option: 'resourceType', value: 'sql-image' }, { option: 'resourceType', value: 'sql-bdc' }, { option: 'newType', value: 'sql-windows-setup' }]
|
||||
@@ -62,16 +62,16 @@ suite('Resource Type Service Tests', function (): void {
|
||||
});
|
||||
});
|
||||
|
||||
test('When clause that reads "true" (ignoring case) should always return true', () => {
|
||||
it('When clause that reads "true" (ignoring case) should always return true', () => {
|
||||
should(processWhenClause(undefined, [])).be.true('undefined when clause should always return true');
|
||||
should(processWhenClause('TrUe', [])).be.true(`"true" when clause should always return true`);
|
||||
});
|
||||
|
||||
test('No selected options returns false', () => {
|
||||
it('No selected options returns false', () => {
|
||||
should(processWhenClause('newType=empty', [])).be.false('No selected options should return false');
|
||||
});
|
||||
|
||||
test('Unfulfilled or partially fulfilled when clauses return false', () => {
|
||||
it('Unfulfilled or partially fulfilled when clauses return false', () => {
|
||||
const whenSelectedFalse: { when: string; selectedOptions: { option: string, value: string }[] }[] = [
|
||||
{
|
||||
when: 'resourceType=sql-bdc && dneType=does-not-exist', selectedOptions: [{ option: 'resourceType', value: 'sql-image' }, { option: 'resourceType', value: 'sql-bdc' }, { option: 'newType', value: 'sql-windows-setup' }]
|
||||
@@ -85,7 +85,7 @@ suite('Resource Type Service Tests', function (): void {
|
||||
});
|
||||
});
|
||||
|
||||
test('An invalid when clause should always return false', () => {
|
||||
it('An invalid when clause should always return false', () => {
|
||||
should(processWhenClause('badWhenClause', [{ option: 'bad', value: 'WhenClause' }])).be.false(`invalid when clause should return false`);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,59 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as TypeMoq from 'typemoq';
|
||||
import { ITool, ToolType } from '../../interfaces';
|
||||
import { IPlatformService } from '../../services/platformService';
|
||||
import { ToolsService } from '../../services/toolsService';
|
||||
|
||||
|
||||
const tools: { name: string; type: ToolType }[] = [
|
||||
{ name: 'azure-cli', type: ToolType.AzCli },
|
||||
{ name: 'docker', type: ToolType.Docker },
|
||||
{ name: 'kubectl', type: ToolType.KubeCtl },
|
||||
{ name: 'azdata', type: ToolType.Azdata }
|
||||
];
|
||||
const mockPlatformService = TypeMoq.Mock.ofType<IPlatformService>();
|
||||
const toolsService = new ToolsService(mockPlatformService.object);
|
||||
|
||||
describe('Tools Service Tests', function (): void {
|
||||
|
||||
it('run getToolByName with all known values', () => {
|
||||
const missingTypes: string[] = [];
|
||||
// Make sure all the enum values are covered
|
||||
for (const type in ToolType) {
|
||||
if (typeof ToolType[type] === 'number') {
|
||||
if (tools.findIndex(element => element.type === parseInt(ToolType[type])) === -1) {
|
||||
missingTypes.push(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
(missingTypes.length === 0).should.be.true(`the following enum values are not included in the test:${missingTypes.join(',')}`);
|
||||
|
||||
tools.forEach(toolInfo => {
|
||||
const tool = toolsService.getToolByName(toolInfo.name);
|
||||
(!!tool).should.be.true(`The tool: ${toolInfo.name} is not recognized`);
|
||||
(tool!.type).should.equal(toolInfo.type, 'returned notebook name does not match expected value');
|
||||
});
|
||||
});
|
||||
|
||||
it('run getToolByName with a name that is not defined', () => {
|
||||
const mockPlatformService = TypeMoq.Mock.ofType<IPlatformService>();
|
||||
const toolsService = new ToolsService(mockPlatformService.object);
|
||||
const tool = toolsService.getToolByName('no-such-tool');
|
||||
(tool === undefined).should.be.true('for a not defined tool, expected value is undefined');
|
||||
});
|
||||
|
||||
it('get/set tools for CurrentProvider', () => {
|
||||
const iTools: ITool[] = tools.map(toolInfo => {
|
||||
const tool = toolsService.getToolByName(toolInfo.name);
|
||||
(!!tool).should.be.true(`The tool: ${toolInfo.name} is not recognized`);
|
||||
tool!.type.should.equal(toolInfo.type, 'returned notebook name does not match expected value');
|
||||
return tool!;
|
||||
});
|
||||
toolsService.toolsForCurrentProvider = iTools;
|
||||
iTools.should.deepEqual(toolsService.toolsForCurrentProvider, 'toolsForCurrentProvider did not return the value we set');
|
||||
});
|
||||
});
|
||||
@@ -1,51 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'mocha';
|
||||
import assert = require('assert');
|
||||
import * as TypeMoq from 'typemoq';
|
||||
import { ToolsService } from '../services/toolsService';
|
||||
import { ToolType } from '../interfaces';
|
||||
import { isNumber } from 'util';
|
||||
import { IPlatformService } from '../services/platformService';
|
||||
|
||||
suite('Tools Service Tests', function (): void {
|
||||
|
||||
test('run getToolByName with all known values', () => {
|
||||
const mockPlatformService = TypeMoq.Mock.ofType<IPlatformService>();
|
||||
const toolsService = new ToolsService(mockPlatformService.object);
|
||||
|
||||
const tools: { name: string; type: ToolType }[] = [
|
||||
{ name: 'azure-cli', type: ToolType.AzCli },
|
||||
{ name: 'docker', type: ToolType.Docker },
|
||||
{ name: 'kubectl', type: ToolType.KubeCtl },
|
||||
{ name: 'azdata', type: ToolType.Azdata }];
|
||||
|
||||
const missingTypes: string[] = [];
|
||||
|
||||
// Make sure all the enum values are covered
|
||||
for (const type in ToolType) {
|
||||
if (isNumber(ToolType[type])) {
|
||||
if (tools.findIndex(element => element.type === parseInt(ToolType[type])) === -1) {
|
||||
missingTypes.push(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
assert(missingTypes.length === 0, `the following enum values are not included in the test:${missingTypes.join(',')}`);
|
||||
|
||||
tools.forEach(toolInfo => {
|
||||
const tool = toolsService.getToolByName(toolInfo.name);
|
||||
assert(!!tool, `The tool: ${toolInfo.name} is not recognized`);
|
||||
assert.equal(tool!.type, toolInfo.type, 'returned notebook name does not match expected value');
|
||||
});
|
||||
});
|
||||
|
||||
test('run getToolByName with a name that is not defined', () => {
|
||||
const mockPlatformService = TypeMoq.Mock.ofType<IPlatformService>();
|
||||
const toolsService = new ToolsService(mockPlatformService.object);
|
||||
const tool = toolsService.getToolByName('no-such-tool');
|
||||
assert(tool === undefined, 'for a not defined tool, expected value is undefined');
|
||||
});
|
||||
});
|
||||
@@ -35,14 +35,14 @@ const testValidations = [
|
||||
}
|
||||
];
|
||||
|
||||
suite('Validation', () => {
|
||||
suite('createValidation and validate input Box', () => {
|
||||
setup(() => {
|
||||
describe('Validation', () => {
|
||||
describe('createValidation and validate input Box', () => {
|
||||
beforeEach(() => {
|
||||
sinon.restore(); //cleanup all previously defined sinon mocks
|
||||
inputBoxStub = sinon.stub(inputBox, 'updateProperty').resolves();
|
||||
});
|
||||
testValidations.forEach(testObj => {
|
||||
test(`validationType: ${testObj.type}`, async () => {
|
||||
it(`validationType: ${testObj.type}`, async () => {
|
||||
const validation = createValidation(testObj, async () => undefined, async (_varName: string) => undefined);
|
||||
switch (testObj.type) {
|
||||
case ValidationType.IsInteger: should(validation).be.instanceOf(IntegerValidation); break;
|
||||
@@ -59,7 +59,7 @@ suite('Validation', () => {
|
||||
});
|
||||
});
|
||||
|
||||
suite('IntegerValidation', () => {
|
||||
describe('IntegerValidation', () => {
|
||||
// all the below test values are arbitrary representative values or sentinel values for integer validation
|
||||
[
|
||||
{ value: '342520596781', expected: true },
|
||||
@@ -72,7 +72,7 @@ suite('Validation', () => {
|
||||
{ value: NaN, expected: false },
|
||||
].forEach((testObj) => {
|
||||
const displayTestValue = getDisplayString(testObj.value);
|
||||
test(`testValue:${displayTestValue}`, async () => {
|
||||
it(`testValue:${displayTestValue}`, async () => {
|
||||
const validationDescription = `value: ${displayTestValue} was not an integer`;
|
||||
const validation = new IntegerValidation(
|
||||
{ type: ValidationType.IsInteger, description: validationDescription },
|
||||
@@ -83,7 +83,7 @@ suite('Validation', () => {
|
||||
});
|
||||
});
|
||||
|
||||
suite('RegexValidation', () => {
|
||||
describe('RegexValidation', () => {
|
||||
const testRegex = '^[0-9]+$';
|
||||
// tests
|
||||
[
|
||||
@@ -97,7 +97,7 @@ suite('Validation', () => {
|
||||
{ value: undefined, expected: false },
|
||||
].forEach(testOb => {
|
||||
const displayTestValue = getDisplayString(testOb.value);
|
||||
test(`regex: /${testRegex}/, testValue:${displayTestValue}, expect result: ${testOb.expected}`, async () => {
|
||||
it(`regex: /${testRegex}/, testValue:${displayTestValue}, expect result: ${testOb.expected}`, async () => {
|
||||
const validationDescription = `value:${displayTestValue} did not match the regex:/${testRegex}/`;
|
||||
const validation = new RegexValidation(
|
||||
{ type: ValidationType.IsInteger, description: validationDescription, regex: testRegex },
|
||||
@@ -108,7 +108,7 @@ suite('Validation', () => {
|
||||
});
|
||||
});
|
||||
|
||||
suite('LessThanOrEqualsValidation', () => {
|
||||
describe('LessThanOrEqualsValidation', () => {
|
||||
const targetVariableName = 'comparisonTarget';
|
||||
// tests - when operands are mix of string and number then number comparison is performed
|
||||
[
|
||||
@@ -147,7 +147,7 @@ suite('Validation', () => {
|
||||
].forEach(testObj => {
|
||||
const displayTestValue = getDisplayString(testObj.value);
|
||||
const displayTargetValue = getDisplayString(testObj.targetValue);
|
||||
test(`testValue:${displayTestValue}, targetValue:${displayTargetValue}`, async () => {
|
||||
it(`testValue:${displayTestValue}, targetValue:${displayTargetValue}`, async () => {
|
||||
const validationDescription = `${displayTestValue} did not test as <= ${displayTargetValue}`;
|
||||
const validation = new LessThanOrEqualsValidation(
|
||||
{ type: ValidationType.IsInteger, description: validationDescription, target: targetVariableName },
|
||||
@@ -159,7 +159,7 @@ suite('Validation', () => {
|
||||
});
|
||||
});
|
||||
|
||||
suite('GreaterThanOrEqualsValidation', () => {
|
||||
describe('GreaterThanOrEqualsValidation', () => {
|
||||
const targetVariableName = 'comparisonTarget';
|
||||
// tests - when operands are mix of string and number then number comparison is performed
|
||||
[
|
||||
@@ -190,7 +190,7 @@ suite('Validation', () => {
|
||||
].forEach(testObj => {
|
||||
const displayTestValue = getDisplayString(testObj.value);
|
||||
const displayTargetValue = getDisplayString(testObj.targetValue);
|
||||
test(`testValue:${displayTestValue}, targetValue:${displayTargetValue}`, async () => {
|
||||
it(`testValue:${displayTestValue}, targetValue:${displayTargetValue}`, async () => {
|
||||
const validationDescription = `${displayTestValue} did not test as >= ${displayTargetValue}`;
|
||||
const validation = new GreaterThanOrEqualsValidation(
|
||||
{ type: ValidationType.IsInteger, description: validationDescription, target: targetVariableName },
|
||||
|
||||
Reference in New Issue
Block a user