Adding unit tests for schema compare service (#13642)

This commit is contained in:
Leila Lali
2020-12-07 14:42:38 -08:00
committed by GitHub
parent 099e94fa2d
commit 9977e83380
12 changed files with 703 additions and 319 deletions

View File

@@ -4,13 +4,12 @@
*--------------------------------------------------------------------------------------------*/
import * as should from 'should';
import * as azdata from 'azdata';
import * as vscode from 'vscode';
import * as mssql from '../../../mssql';
import * as TypeMoq from 'typemoq';
import * as loc from '../localizedConstants';
import 'mocha';
import { SchemaCompareDialog } from './../dialogs/schemaCompareDialog';
import * as sinon from 'sinon';
import { SchemaCompareMainWindow } from '../schemaCompareMainWindow';
import { SchemaCompareTestService, testStateScmp } from './testSchemaCompareService';
import { createContext, TestContext } from './testContext';
@@ -28,15 +27,24 @@ before(function (): void {
testContext = createContext();
});
afterEach(function (): void {
sinon.restore();
});
describe('SchemaCompareMainWindow.start', function (): void {
before(() => {
mockExtensionContext = TypeMoq.Mock.ofType<vscode.ExtensionContext>();
mockExtensionContext.setup(x => x.extensionPath).returns(() => '');
});
this.afterEach(() => {
sinon.restore();
});
it('Should be correct when created.', async function (): Promise<void> {
let sc = new SchemaCompareTestService();
let result = new SchemaCompareMainWindowTest(testContext.apiWrapper.object, sc, mockExtensionContext.object);
let result = new SchemaCompareMainWindowTest(sc, mockExtensionContext.object);
await result.start(undefined);
should(result.getComparisonResult() === undefined);
@@ -52,7 +60,7 @@ describe('SchemaCompareMainWindow.start', function (): void {
it('Should start with the source as undefined', async function (): Promise<void> {
let sc = new SchemaCompareTestService();
let result = new SchemaCompareMainWindowTest(testContext.apiWrapper.object, sc, mockExtensionContext.object);
let result = new SchemaCompareMainWindowTest(sc, mockExtensionContext.object);
await result.start(undefined);
should.equal(result.sourceEndpointInfo, undefined);
@@ -62,8 +70,8 @@ describe('SchemaCompareMainWindow.start', function (): void {
it('Should start with the source as database', async function (): Promise<void> {
let sc = new SchemaCompareTestService();
let result = new SchemaCompareMainWindowTest(testContext.apiWrapper.object, sc, mockExtensionContext.object);
await result.start({connectionProfile: mockIConnectionProfile});
let result = new SchemaCompareMainWindowTest(sc, mockExtensionContext.object);
await result.start({ connectionProfile: mockIConnectionProfile });
should.notEqual(result.sourceEndpointInfo, undefined);
should.equal(result.sourceEndpointInfo.endpointType, mssql.SchemaCompareEndpointType.Database);
@@ -75,7 +83,7 @@ describe('SchemaCompareMainWindow.start', function (): void {
it('Should start with the source as dacpac.', async function (): Promise<void> {
let sc = new SchemaCompareTestService();
let result = new SchemaCompareMainWindowTest(testContext.apiWrapper.object, sc, mockExtensionContext.object);
let result = new SchemaCompareMainWindowTest(sc, mockExtensionContext.object);
const dacpacPath = mockFilePath;
await result.start(dacpacPath);
@@ -85,7 +93,287 @@ describe('SchemaCompareMainWindow.start', function (): void {
should.equal(result.targetEndpointInfo, undefined);
});
});
let showErrorMessageSpy: any;
let showWarningMessageStub: any;
let showOpenDialogStub: any;
describe('SchemaCompareMainWindow.results', function (): void {
before(() => {
mockExtensionContext = TypeMoq.Mock.ofType<vscode.ExtensionContext>();
mockExtensionContext.setup(x => x.extensionPath).returns(() => '');
});
this.afterEach(() => {
sinon.restore();
});
this.beforeEach(() => {
sinon.restore();
showErrorMessageSpy = sinon.spy(vscode.window, 'showErrorMessage');
});
it('Should show error if publish changes fails', async function (): Promise<void> {
let service = createServiceMock();
service.setup(x => x.schemaComparePublishChanges(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({
success: false,
errorMessage: 'error1'
}));
showWarningMessageStub = sinon.stub(vscode.window, 'showWarningMessage').returns(<any>Promise.resolve('Yes'));
let schemaCompareResult = new SchemaCompareMainWindow(service.object, mockExtensionContext.object);
await schemaCompareResult.start(undefined);
schemaCompareResult.sourceEndpointInfo = setDacpacEndpointInfo(mocksource);
schemaCompareResult.targetEndpointInfo = setDacpacEndpointInfo(mocktarget);
await schemaCompareResult.execute();
await schemaCompareResult.publishChanges();
should(showErrorMessageSpy.calledOnce).be.true();
should.equal(showErrorMessageSpy.getCall(0).args[0], loc.applyErrorMessage('error1'));
});
it('Should show not error if publish changes succeed', async function (): Promise<void> {
let service = createServiceMock();
service.setup(x => x.schemaComparePublishChanges(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({
success: true,
errorMessage: ''
}));
showWarningMessageStub = sinon.stub(vscode.window, 'showWarningMessage').returns(<any>Promise.resolve('Yes'));
let schemaCompareResult = new SchemaCompareMainWindow(service.object, mockExtensionContext.object);
await schemaCompareResult.start(undefined);
schemaCompareResult.sourceEndpointInfo = setDacpacEndpointInfo(mocksource);
schemaCompareResult.targetEndpointInfo = setDacpacEndpointInfo(mocktarget);
await schemaCompareResult.execute();
await schemaCompareResult.publishChanges();
should(showErrorMessageSpy.notCalled).be.true();
});
it('Should show error if openScmp fails', async function (): Promise<void> {
let service = createServiceMock();
let files: vscode.Uri[] = [vscode.Uri.parse('file:///test')];
service.setup(x => x.schemaCompareOpenScmp(TypeMoq.It.isAny())).returns(() => Promise.resolve({
sourceEndpointInfo: undefined,
targetEndpointInfo: undefined,
originalTargetName: 'string',
originalConnectionString: '',
deploymentOptions: undefined,
excludedSourceElements: [],
excludedTargetElements: [],
success: false,
errorMessage: 'error1'
}));
showWarningMessageStub = sinon.stub(vscode.window, 'showWarningMessage').returns(<any>Promise.resolve('Yes'));
showOpenDialogStub = sinon.stub(vscode.window, 'showOpenDialog').returns(<any>Promise.resolve(files));
let schemaCompareResult = new SchemaCompareMainWindow(service.object, mockExtensionContext.object);
await schemaCompareResult.start(undefined);
schemaCompareResult.sourceEndpointInfo = setDacpacEndpointInfo(mocksource);
schemaCompareResult.targetEndpointInfo = setDacpacEndpointInfo(mocktarget);
await schemaCompareResult.openScmp();
should(showErrorMessageSpy.calledOnce).be.true();
should.equal(showErrorMessageSpy.getCall(0).args[0], loc.openScmpErrorMessage('error1'));
});
it('Should show error if saveScmp fails', async function (): Promise<void> {
let service = createServiceMock();
let file: vscode.Uri = vscode.Uri.parse('file:///test');
service.setup(x => x.schemaCompareSaveScmp(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({
sourceEndpointInfo: undefined,
targetEndpointInfo: undefined,
originalTargetName: 'string',
originalConnectionString: '',
deploymentOptions: undefined,
excludedSourceElements: [],
excludedTargetElements: [],
success: false,
errorMessage: 'error1'
}));
showWarningMessageStub = sinon.stub(vscode.window, 'showWarningMessage').returns(<any>Promise.resolve('Yes'));
showOpenDialogStub = sinon.stub(vscode.window, 'showSaveDialog').returns(<any>Promise.resolve(file));
let schemaCompareResult = new SchemaCompareMainWindow(service.object, mockExtensionContext.object);
await schemaCompareResult.start(undefined);
schemaCompareResult.sourceEndpointInfo = setDacpacEndpointInfo(mocksource);
schemaCompareResult.targetEndpointInfo = setDacpacEndpointInfo(mocktarget);
await schemaCompareResult.execute();
await schemaCompareResult.saveScmp();
should(showErrorMessageSpy.calledOnce).be.true();
should.equal(showErrorMessageSpy.getCall(0).args[0], loc.saveScmpErrorMessage('error1'));
});
it('Should show error if generateScript fails', async function (): Promise<void> {
let service = createServiceMock();
service.setup(x => x.schemaCompareGenerateScript(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({
success: false,
errorMessage: 'error1'
}));
showWarningMessageStub = sinon.stub(vscode.window, 'showWarningMessage').returns(<any>Promise.resolve('Yes'));
let schemaCompareResult = new SchemaCompareMainWindow(service.object, mockExtensionContext.object);
await schemaCompareResult.start(undefined);
schemaCompareResult.sourceEndpointInfo = setDacpacEndpointInfo(mocksource);
schemaCompareResult.targetEndpointInfo = setDacpacEndpointInfo(mocktarget);
await schemaCompareResult.execute();
await schemaCompareResult.generateScript();
should(showErrorMessageSpy.calledOnce).be.true();
should.equal(showErrorMessageSpy.getCall(0).args[0], loc.generateScriptErrorMessage('error1'));
});
it('Should show error if cancel fails', async function (): Promise<void> {
let service = createServiceMock();
service.setup(x => x.schemaCompareCancel(TypeMoq.It.isAny())).returns(() => Promise.resolve({
success: false,
errorMessage: 'error1'
}));
showWarningMessageStub = sinon.stub(vscode.window, 'showWarningMessage').returns(<any>Promise.resolve('Yes'));
let schemaCompareResult = new SchemaCompareMainWindow(service.object, mockExtensionContext.object);
await schemaCompareResult.start(undefined);
schemaCompareResult.sourceEndpointInfo = setDacpacEndpointInfo(mocksource);
schemaCompareResult.targetEndpointInfo = setDacpacEndpointInfo(mocktarget);
await schemaCompareResult.execute();
await schemaCompareResult.cancelCompare();
should(showErrorMessageSpy.calledOnce).be.true();
should.equal(showErrorMessageSpy.getCall(0).args[0], loc.cancelErrorMessage('error1'));
});
it('Should show error if IncludeExcludeNode fails', async function (): Promise<void> {
let service = createServiceMock();
service.setup(x => x.schemaCompareIncludeExcludeNode(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({
success: false,
errorMessage: '',
affectedDependencies: [],
blockingDependencies: [{
updateAction: 2,
differenceType: 0,
name: 'SqlTable',
sourceValue: ['dbo', 'table1'],
targetValue: null,
parent: null,
children: [{
updateAction: 2,
differenceType: 0,
name: 'SqlSimpleColumn',
sourceValue: ['dbo', 'table1', 'id'],
targetValue: null,
parent: null,
children: [],
sourceScript: '',
targetScript: null,
included: false
}],
sourceScript: 'CREATE TABLE [dbo].[table1](id int)',
targetScript: null,
included: true
}]
}));
showWarningMessageStub = sinon.stub(vscode.window, 'showWarningMessage').returns(<any>Promise.resolve(''));
let schemaCompareResult = new SchemaCompareMainWindow(service.object, mockExtensionContext.object);
await schemaCompareResult.start(undefined);
schemaCompareResult.sourceEndpointInfo = setDacpacEndpointInfo(mocksource);
schemaCompareResult.targetEndpointInfo = setDacpacEndpointInfo(mocktarget);
await schemaCompareResult.execute();
await schemaCompareResult.applyIncludeExclude({
row: 0,
column: 0,
columnName: 1,
checked: true
});
should(showWarningMessageStub.calledOnce).be.true();
});
it('Should not show warning if IncludeExcludeNode succeed', async function (): Promise<void> {
let service = createServiceMock();
service.setup(x => x.schemaCompareIncludeExcludeNode(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({
success: true,
errorMessage: '',
affectedDependencies: [],
blockingDependencies: [{
updateAction: 2,
differenceType: 0,
name: 'SqlTable',
sourceValue: ['dbo', 'table1'],
targetValue: null,
parent: null,
children: [{
updateAction: 2,
differenceType: 0,
name: 'SqlSimpleColumn',
sourceValue: ['dbo', 'table1', 'id'],
targetValue: null,
parent: null,
children: [],
sourceScript: '',
targetScript: null,
included: false
}],
sourceScript: 'CREATE TABLE [dbo].[table1](id int)',
targetScript: null,
included: true
}]
}));
showWarningMessageStub = sinon.stub(vscode.window, 'showWarningMessage').returns(<any>Promise.resolve(''));
let schemaCompareResult = new SchemaCompareMainWindow(service.object, mockExtensionContext.object);
await schemaCompareResult.start(undefined);
schemaCompareResult.sourceEndpointInfo = setDacpacEndpointInfo(mocksource);
schemaCompareResult.targetEndpointInfo = setDacpacEndpointInfo(mocktarget);
await schemaCompareResult.execute();
await schemaCompareResult.applyIncludeExclude({
row: 0,
column: 0,
columnName: 1,
checked: false
});
should(showWarningMessageStub.notCalled).be.true();
});
it('Should not show error if user does not want to publish', async function (): Promise<void> {
let service = createServiceMock();
service.setup(x => x.schemaComparePublishChanges(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({
success: true,
errorMessage: ''
}));
showWarningMessageStub = sinon.stub(vscode.window, 'showWarningMessage').returns(<any>Promise.resolve('No'));
let schemaCompareResult = new SchemaCompareMainWindow(service.object, mockExtensionContext.object);
await schemaCompareResult.start(undefined);
schemaCompareResult.sourceEndpointInfo = setDacpacEndpointInfo(mocksource);
schemaCompareResult.targetEndpointInfo = setDacpacEndpointInfo(mocktarget);
await schemaCompareResult.execute();
await schemaCompareResult.publishChanges();
should(showErrorMessageSpy.notCalled).be.true();
});
function createServiceMock() {
let sc = new SchemaCompareTestService(testStateScmp.SUCCESS_NOT_EQUAL);
let service = TypeMoq.Mock.ofInstance(new SchemaCompareTestService());
service.setup(x => x.schemaCompareGetDefaultOptions()).returns(x => sc.schemaCompareGetDefaultOptions());
service.setup(x => x.schemaCompare(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => sc.schemaCompare('', undefined, undefined, undefined, undefined));
return service;
}
});
let showErrorMessageStub: any;
describe('SchemaCompareMainWindow.execute', function (): void {
before(() => {
mockExtensionContext = TypeMoq.Mock.ofType<vscode.ExtensionContext>();
@@ -93,16 +381,22 @@ describe('SchemaCompareMainWindow.execute', function (): void {
testContext = createContext();
});
beforeEach(function (): void {
testContext.apiWrapper.reset();
this.afterEach(() => {
sinon.restore();
});
this.beforeEach(() => {
sinon.restore();
});
it('Should fail for failing Schema Compare service', async function (): Promise<void> {
let sc = new SchemaCompareTestService(testStateScmp.FAILURE);
testContext.apiWrapper.setup(x => x.showErrorMessage(TypeMoq.It.isAny())).returns((s) => { throw new Error(s); });
let result = new SchemaCompareMainWindowTest(testContext.apiWrapper.object, sc, mockExtensionContext.object);
showErrorMessageStub = sinon.stub(vscode.window, 'showErrorMessage').callsFake((message) => {
throw new Error(message);
});
let result = new SchemaCompareMainWindowTest(sc, mockExtensionContext.object);
await result.start(undefined);
should(result.getComparisonResult() === undefined);
@@ -116,8 +410,7 @@ describe('SchemaCompareMainWindow.execute', function (): void {
it('Should exit for failing Schema Compare service', async function (): Promise<void> {
let sc = new SchemaCompareTestService(testStateScmp.FAILURE);
testContext.apiWrapper.setup(x => x.showErrorMessage(TypeMoq.It.isAny())).returns(() => Promise.resolve(''));
let result = new SchemaCompareMainWindowTest(testContext.apiWrapper.object, sc, mockExtensionContext.object);
let result = new SchemaCompareMainWindowTest(sc, mockExtensionContext.object);
await result.start(undefined);
@@ -127,13 +420,12 @@ describe('SchemaCompareMainWindow.execute', function (): void {
result.targetEndpointInfo = setDacpacEndpointInfo(mocktarget);
await result.execute();
testContext.apiWrapper.verify(x => x.showErrorMessage(TypeMoq.It.isAny()), TypeMoq.Times.once());
});
it('Should disable script button and apply button for Schema Compare service for dacpac', async function (): Promise<void> {
let sc = new SchemaCompareTestService(testStateScmp.SUCCESS_NOT_EQUAL);
let result = new SchemaCompareMainWindowTest(testContext.apiWrapper.object, sc, mockExtensionContext.object);
let result = new SchemaCompareMainWindowTest(sc, mockExtensionContext.object);
await result.start(undefined);
@@ -145,7 +437,7 @@ describe('SchemaCompareMainWindow.execute', function (): void {
await result.execute();
//Generate script button and apply button should be disabled for dacpac comparison
result.verifyButtonsState( {
result.verifyButtonsState({
compareButtonState: true,
optionsButtonState: true,
switchButtonState: true,
@@ -156,13 +448,13 @@ describe('SchemaCompareMainWindow.execute', function (): void {
selectTargetButtonState: true,
generateScriptButtonState: false,
applyButtonState: false
} );
});
});
it('Should disable script button and apply button for Schema Compare service for database', async function (): Promise<void> {
let sc = new SchemaCompareTestService(testStateScmp.SUCCESS_NOT_EQUAL);
let result = new SchemaCompareMainWindowTest(testContext.apiWrapper.object, sc, mockExtensionContext.object);
let result = new SchemaCompareMainWindowTest(sc, mockExtensionContext.object);
await result.start(undefined);
@@ -174,7 +466,7 @@ describe('SchemaCompareMainWindow.execute', function (): void {
await result.execute();
//Generate script button and apply button should be enabled for database comparison
result.verifyButtonsState( {
result.verifyButtonsState({
compareButtonState: true,
optionsButtonState: true,
switchButtonState: true,
@@ -185,7 +477,7 @@ describe('SchemaCompareMainWindow.execute', function (): void {
selectTargetButtonState: true,
generateScriptButtonState: true,
applyButtonState: true
} );
});
});
});
@@ -201,18 +493,18 @@ describe('SchemaCompareMainWindow.updateSourceAndTarget', function (): void {
let sc = new SchemaCompareTestService();
let endpointInfo: mssql.SchemaCompareEndpointInfo;
let result = new SchemaCompareMainWindowTest(testContext.apiWrapper.object, sc, mockExtensionContext.object);
let result = new SchemaCompareMainWindowTest(sc, mockExtensionContext.object);
await result.start(undefined);
should(result.getComparisonResult() === undefined);
result.sourceEndpointInfo = {...endpointInfo};
result.targetEndpointInfo = {...endpointInfo};
result.sourceEndpointInfo = { ...endpointInfo };
result.targetEndpointInfo = { ...endpointInfo };
result.updateSourceAndTarget();
result.verifyButtonsState( {
result.verifyButtonsState({
compareButtonState: false,
optionsButtonState: false,
switchButtonState: false,
@@ -223,25 +515,25 @@ describe('SchemaCompareMainWindow.updateSourceAndTarget', function (): void {
selectTargetButtonState: true,
generateScriptButtonState: false,
applyButtonState: false
} );
});
});
it('Should set buttons appropriately when source endpoint is empty and target endpoint is populated', async function (): Promise<void> {
let sc = new SchemaCompareTestService();
let endpointInfo: mssql.SchemaCompareEndpointInfo;
let result = new SchemaCompareMainWindowTest(testContext.apiWrapper.object, sc, mockExtensionContext.object);
let result = new SchemaCompareMainWindowTest(sc, mockExtensionContext.object);
await result.start(undefined);
should(result.getComparisonResult() === undefined);
result.sourceEndpointInfo = {...endpointInfo};
result.sourceEndpointInfo = { ...endpointInfo };
result.targetEndpointInfo = setDacpacEndpointInfo(mocktarget);
result.updateSourceAndTarget();
result.verifyButtonsState( {
result.verifyButtonsState({
compareButtonState: false,
optionsButtonState: false,
switchButtonState: true,
@@ -252,14 +544,14 @@ describe('SchemaCompareMainWindow.updateSourceAndTarget', function (): void {
selectTargetButtonState: true,
generateScriptButtonState: false,
applyButtonState: false
} );
});
});
it('Should set buttons appropriately when source and target endpoints are populated', async function (): Promise<void> {
let sc = new SchemaCompareTestService();
let endpointInfo: mssql.SchemaCompareEndpointInfo;
let result = new SchemaCompareMainWindowTest(testContext.apiWrapper.object, sc, mockExtensionContext.object);
let result = new SchemaCompareMainWindowTest(sc, mockExtensionContext.object);
await result.start(undefined);
@@ -270,7 +562,7 @@ describe('SchemaCompareMainWindow.updateSourceAndTarget', function (): void {
result.updateSourceAndTarget();
result.verifyButtonsState( {
result.verifyButtonsState({
compareButtonState: true,
optionsButtonState: true,
switchButtonState: true,
@@ -281,7 +573,7 @@ describe('SchemaCompareMainWindow.updateSourceAndTarget', function (): void {
selectTargetButtonState: true,
generateScriptButtonState: false,
applyButtonState: false
} );
});
});
});