From fd29e351990ab1306f674d1fcc9a6820cbbfcc36 Mon Sep 17 00:00:00 2001 From: Sakshi Sharma <57200045+SakshiS-harma@users.noreply.github.com> Date: Wed, 1 Jul 2020 18:35:54 -0700 Subject: [PATCH] Schema compare test coverage (#11080) * Schema compare tests for updateSourceAndTarget method * Merge conflict resolution * Move resetbutton call before adding them to toolbar * PR comments- added a buttons interface for readability and created a test class to add test functionality to the orginal class * Moved interface ButtonState to test code --- .../src/schemaCompareMainWindow.ts | 88 ++++++-------- .../src/test/schemaCompare.test.ts | 110 +++++++++++++++--- .../src/test/testSchemaCompareMainWindow.ts | 74 ++++++++++++ 3 files changed, 203 insertions(+), 69 deletions(-) create mode 100644 extensions/schema-compare/src/test/testSchemaCompareMainWindow.ts diff --git a/extensions/schema-compare/src/schemaCompareMainWindow.ts b/extensions/schema-compare/src/schemaCompareMainWindow.ts index f525dc05ef..4d29fb14ab 100644 --- a/extensions/schema-compare/src/schemaCompareMainWindow.ts +++ b/extensions/schema-compare/src/schemaCompareMainWindow.ts @@ -38,19 +38,19 @@ export class SchemaCompareMainWindow { private flexModel: azdata.FlexContainer; private noDifferencesLabel: azdata.TextComponent; private sourceTargetFlexLayout: azdata.FlexContainer; - private switchButton: azdata.ButtonComponent; - private compareButton: azdata.ButtonComponent; - private cancelCompareButton: azdata.ButtonComponent; - private optionsButton: azdata.ButtonComponent; - private generateScriptButton: azdata.ButtonComponent; - private applyButton: azdata.ButtonComponent; - private openScmpButton: azdata.ButtonComponent; - private selectSourceButton: azdata.ButtonComponent; - private selectTargetButton: azdata.ButtonComponent; - private saveScmpButton: azdata.ButtonComponent; + protected switchButton: azdata.ButtonComponent; + protected compareButton: azdata.ButtonComponent; + protected cancelCompareButton: azdata.ButtonComponent; + protected optionsButton: azdata.ButtonComponent; + protected generateScriptButton: azdata.ButtonComponent; + protected applyButton: azdata.ButtonComponent; + protected openScmpButton: azdata.ButtonComponent; + protected selectSourceButton: azdata.ButtonComponent; + protected selectTargetButton: azdata.ButtonComponent; + protected saveScmpButton: azdata.ButtonComponent; private SchemaCompareActionMap: Map; private operationId: string; - private comparisonResult: mssql.SchemaCompareResult; + protected comparisonResult: mssql.SchemaCompareResult; private sourceNameComponent: azdata.TableComponent; private targetNameComponent: azdata.TableComponent; private deploymentOptions: mssql.DeploymentOptions; @@ -154,6 +154,29 @@ export class SchemaCompareMainWindow { this.createOpenScmpButton(view); this.createSaveScmpButton(view); this.createSourceAndTargetButtons(view); + + this.sourceName = getEndpointName(this.sourceEndpointInfo); + this.targetName = ' '; + this.sourceNameComponent = view.modelBuilder.table().withProperties({ + columns: [ + { + value: this.sourceName, + headerCssClass: 'no-borders', + toolTip: this.sourceName + }, + ] + }).component(); + + this.targetNameComponent = view.modelBuilder.table().withProperties({ + columns: [ + { + value: this.targetName, + headerCssClass: 'no-borders', + toolTip: this.targetName + }, + ] + }).component(); + this.resetButtons(ResetButtonState.noSourceTarget); let toolBar = view.modelBuilder.toolbarContainer(); @@ -191,28 +214,6 @@ export class SchemaCompareMainWindow { value: '➔' }).component(); - this.sourceName = getEndpointName(this.sourceEndpointInfo); - this.targetName = ' '; - this.sourceNameComponent = view.modelBuilder.table().withProperties({ - columns: [ - { - value: this.sourceName, - headerCssClass: 'no-borders', - toolTip: this.sourceName - }, - ] - }).component(); - - this.targetNameComponent = view.modelBuilder.table().withProperties({ - columns: [ - { - value: this.targetName, - headerCssClass: 'no-borders', - toolTip: this.targetName - }, - ] - }).component(); - sourceTargetLabels.addItem(sourceLabel, { CSSStyles: { 'width': '55%', 'margin-left': '15px', 'font-size': 'larger', 'font-weight': 'bold' } }); sourceTargetLabels.addItem(targetLabel, { CSSStyles: { 'width': '45%', 'font-size': 'larger', 'font-weight': 'bold' } }); this.sourceTargetFlexLayout.addItem(this.sourceNameComponent, { CSSStyles: { 'width': '40%', 'height': '25px', 'margin-top': '10px', 'margin-left': '15px' } }); @@ -279,25 +280,6 @@ export class SchemaCompareMainWindow { } } - // only for test - public getComparisonResult(): mssql.SchemaCompareResult { - return this.comparisonResult; - } - - // only for test - public getDeploymentOptions(): mssql.DeploymentOptions { - return this.deploymentOptions; - } - - // only for test - public verifyButtonsState(generateScriptButtonState: boolean, applyButtonState: boolean): boolean { - let result: boolean = false; - if (this.generateScriptButton.enabled === generateScriptButtonState && this.applyButton.enabled === applyButtonState) { - result = true; - } - return result; - } - public setDeploymentOptions(deploymentOptions: mssql.DeploymentOptions): void { this.deploymentOptions = deploymentOptions; } @@ -802,7 +784,7 @@ export class SchemaCompareMainWindow { case (ResetButtonState.noSourceTarget): { this.compareButton.enabled = false; this.optionsButton.enabled = false; - this.switchButton.enabled = this.sourceEndpointInfo ? true : false; // allows switching if the source is set + this.switchButton.enabled = ((this.sourceName && this.sourceName !== ' ') || (this.targetName && this.targetName !== ' ')) ? true : false; // allows switching if the source or target name is set this.openScmpButton.enabled = true; this.cancelCompareButton.enabled = false; this.selectSourceButton.enabled = true; diff --git a/extensions/schema-compare/src/test/schemaCompare.test.ts b/extensions/schema-compare/src/test/schemaCompare.test.ts index 06c58c00f5..0ac2779c50 100644 --- a/extensions/schema-compare/src/test/schemaCompare.test.ts +++ b/extensions/schema-compare/src/test/schemaCompare.test.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ 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'; @@ -14,6 +15,7 @@ import { SchemaCompareMainWindow } from '../schemaCompareMainWindow'; import { SchemaCompareTestService, testStateScmp } from './testSchemaCompareService'; import { createContext, TestContext } from './testContext'; import { mockIConnectionProfile, mockFilePath, setDacpacEndpointInfo, setDatabaseEndpointInfo, shouldThrowSpecificError } from './testUtils'; +import { SchemaCompareMainWindowTest } from './testSchemaCompareMainWindow'; // Mock test data const mocksource: string = 'source.dacpac'; @@ -47,12 +49,11 @@ describe('SchemaCompareMainWindow.start', function (): void { mockExtensionContext = TypeMoq.Mock.ofType(); mockExtensionContext.setup(x => x.extensionPath).returns(() => ''); }); - it('Should be correct when created.', async function (): Promise { let sc = new SchemaCompareTestService(); - let result = new SchemaCompareMainWindow(testContext.apiWrapper.object, sc, mockExtensionContext.object); - await result.start(null); + let result = new SchemaCompareMainWindowTest(testContext.apiWrapper.object, sc, mockExtensionContext.object); + await result.start(undefined); should(result.getComparisonResult() === undefined); @@ -67,7 +68,7 @@ describe('SchemaCompareMainWindow.start', function (): void { it('Should start with the source as undefined', async function (): Promise { let sc = new SchemaCompareTestService(); - let result = new SchemaCompareMainWindow(testContext.apiWrapper.object, sc, mockExtensionContext.object); + let result = new SchemaCompareMainWindowTest(testContext.apiWrapper.object, sc, mockExtensionContext.object); await result.start(undefined); should.equal(result.sourceEndpointInfo, undefined); @@ -77,7 +78,7 @@ describe('SchemaCompareMainWindow.start', function (): void { it('Should start with the source as database', async function (): Promise { let sc = new SchemaCompareTestService(); - let result = new SchemaCompareMainWindow(testContext.apiWrapper.object, sc, mockExtensionContext.object); + let result = new SchemaCompareMainWindowTest(testContext.apiWrapper.object, sc, mockExtensionContext.object); await result.start({connectionProfile: mockIConnectionProfile}); should.notEqual(result.sourceEndpointInfo, undefined); @@ -90,7 +91,7 @@ describe('SchemaCompareMainWindow.start', function (): void { it('Should start with the source as dacpac.', async function (): Promise { let sc = new SchemaCompareTestService(); - let result = new SchemaCompareMainWindow(testContext.apiWrapper.object, sc, mockExtensionContext.object); + let result = new SchemaCompareMainWindowTest(testContext.apiWrapper.object, sc, mockExtensionContext.object); const dacpacPath = mockFilePath; await result.start(dacpacPath); @@ -116,9 +117,9 @@ describe('SchemaCompareMainWindow.execute', function (): 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 SchemaCompareMainWindow(testContext.apiWrapper.object, sc, mockExtensionContext.object); + let result = new SchemaCompareMainWindowTest(testContext.apiWrapper.object, sc, mockExtensionContext.object); - await result.start(null); + await result.start(undefined); should(result.getComparisonResult() === undefined); @@ -132,9 +133,9 @@ describe('SchemaCompareMainWindow.execute', function (): void { let sc = new SchemaCompareTestService(testStateScmp.FAILURE); testContext.apiWrapper.setup(x => x.showErrorMessage(TypeMoq.It.isAny())).returns(() => Promise.resolve('')); - let result = new SchemaCompareMainWindow(testContext.apiWrapper.object, sc, mockExtensionContext.object); + let result = new SchemaCompareMainWindowTest(testContext.apiWrapper.object, sc, mockExtensionContext.object); - await result.start(null); + await result.start(undefined); should(result.getComparisonResult() === undefined); @@ -148,9 +149,9 @@ describe('SchemaCompareMainWindow.execute', function (): void { it('Should disable script button and apply button for Schema Compare service for dacpac', async function (): Promise { let sc = new SchemaCompareTestService(testStateScmp.SUCCESS_NOT_EQUAL); - let result = new SchemaCompareMainWindow(testContext.apiWrapper.object, sc, mockExtensionContext.object); + let result = new SchemaCompareMainWindowTest(testContext.apiWrapper.object, sc, mockExtensionContext.object); - await result.start(null); + await result.start(undefined); should(result.getComparisonResult() === undefined); @@ -160,15 +161,18 @@ describe('SchemaCompareMainWindow.execute', function (): void { await result.execute(); //Generate script button and apply button should be disabled for dacpac comparison - should(result.verifyButtonsState(false, false)).equal(true); + should(result.verifyButtonsState( {compareButtonState: true, optionsButtonState: true, switchButtonState: true, + openScmpButtonState: true, saveScmpButtonState: true, cancelCompareButtonState: false, + selectSourceButtonState: true, selectTargetButtonState: true, generateScriptButtonState: false, + applyButtonState: false} )).equal(true); }); it('Should disable script button and apply button for Schema Compare service for database', async function (): Promise { let sc = new SchemaCompareTestService(testStateScmp.SUCCESS_NOT_EQUAL); - let result = new SchemaCompareMainWindow(testContext.apiWrapper.object, sc, mockExtensionContext.object); + let result = new SchemaCompareMainWindowTest(testContext.apiWrapper.object, sc, mockExtensionContext.object); - await result.start(null); + await result.start(undefined); should(result.getComparisonResult() === undefined); @@ -178,8 +182,82 @@ describe('SchemaCompareMainWindow.execute', function (): void { await result.execute(); //Generate script button and apply button should be enabled for database comparison - should(result.verifyButtonsState(true, true)).equal(true); + should(result.verifyButtonsState( {compareButtonState: true, optionsButtonState: true, switchButtonState: true, + openScmpButtonState: true, saveScmpButtonState: true, cancelCompareButtonState: false, + selectSourceButtonState: true, selectTargetButtonState: true, generateScriptButtonState: true, + applyButtonState: true} )).equal(true); }); }); +describe('SchemaCompareMainWindow.updateSourceAndTarget', function (): void { + before(() => { + mockExtensionContext = TypeMoq.Mock.ofType(); + mockExtensionContext.setup(x => x.extensionPath).returns(() => ''); + testContext = createContext(); + }); + + it('Should set buttons appropriately when source and target endpoints are empty', async function (): Promise { + let sc = new SchemaCompareTestService(); + let endpointInfo: mssql.SchemaCompareEndpointInfo; + + let result = new SchemaCompareMainWindowTest(testContext.apiWrapper.object, sc, mockExtensionContext.object); + + await result.start(undefined); + + should(result.getComparisonResult() === undefined); + + result.sourceEndpointInfo = {...endpointInfo}; + result.targetEndpointInfo = {...endpointInfo}; + + result.updateSourceAndTarget(); + + should(result.verifyButtonsState( {compareButtonState: false, optionsButtonState: false, switchButtonState: false, + openScmpButtonState: true, saveScmpButtonState: false, cancelCompareButtonState: false, + selectSourceButtonState: true, selectTargetButtonState: true, generateScriptButtonState: false, + applyButtonState: false} )).equal(true); + }); + + it('Should set buttons appropriately when source endpoint is empty and target endpoint is populated', async function (): Promise { + let sc = new SchemaCompareTestService(); + let endpointInfo: mssql.SchemaCompareEndpointInfo; + + let result = new SchemaCompareMainWindowTest(testContext.apiWrapper.object, sc, mockExtensionContext.object); + + await result.start(undefined); + + should(result.getComparisonResult() === undefined); + + result.sourceEndpointInfo = {...endpointInfo}; + result.targetEndpointInfo = await setDacpacEndpointInfo(mocktarget); + + result.updateSourceAndTarget(); + + should(result.verifyButtonsState( {compareButtonState: false, optionsButtonState: false, switchButtonState: true, + openScmpButtonState: true, saveScmpButtonState: false, cancelCompareButtonState: false, + selectSourceButtonState: true, selectTargetButtonState: true, generateScriptButtonState: false, + applyButtonState: false} )).equal(true); + }); + + it('Should set buttons appropriately when source and target endpoints are populated', async function (): Promise { + let sc = new SchemaCompareTestService(); + let endpointInfo: mssql.SchemaCompareEndpointInfo; + + let result = new SchemaCompareMainWindowTest(testContext.apiWrapper.object, sc, mockExtensionContext.object); + + await result.start(undefined); + + should(result.getComparisonResult() === undefined); + + result.sourceEndpointInfo = await setDacpacEndpointInfo(mocksource); + result.targetEndpointInfo = await setDacpacEndpointInfo(mocktarget); + + result.updateSourceAndTarget(); + + should(result.verifyButtonsState( {compareButtonState: true, optionsButtonState: true, switchButtonState: true, + openScmpButtonState: true, saveScmpButtonState: true, cancelCompareButtonState: false, + selectSourceButtonState: true, selectTargetButtonState: true, generateScriptButtonState: false, + applyButtonState: false} )).equal(true); + }); + +}); diff --git a/extensions/schema-compare/src/test/testSchemaCompareMainWindow.ts b/extensions/schema-compare/src/test/testSchemaCompareMainWindow.ts new file mode 100644 index 0000000000..184d0943b0 --- /dev/null +++ b/extensions/schema-compare/src/test/testSchemaCompareMainWindow.ts @@ -0,0 +1,74 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as vscode from 'vscode'; +import * as mssql from '../../../mssql'; +import { SchemaCompareMainWindow } from '../schemaCompareMainWindow'; +import { ApiWrapper } from '../common/apiWrapper'; + +export interface ButtonState { + compareButtonState: boolean; + optionsButtonState: boolean; + switchButtonState: boolean; + openScmpButtonState: boolean; + saveScmpButtonState: boolean; + cancelCompareButtonState: boolean; + selectSourceButtonState: boolean; + selectTargetButtonState: boolean; + generateScriptButtonState: boolean; + applyButtonState: boolean; +} +export class SchemaCompareMainWindowTest extends SchemaCompareMainWindow { + + constructor( + apiWrapper: ApiWrapper, + schemaCompareService: mssql.ISchemaCompareService, + extensionContext: vscode.ExtensionContext) { + super(apiWrapper, schemaCompareService, extensionContext); + } + + // only for test + public getComparisonResult(): mssql.SchemaCompareResult { + return this.comparisonResult; + } + + // only for test + public getButtonsState(): ButtonState { + + let buttonObject: ButtonState = { + compareButtonState: this.compareButton.enabled, + optionsButtonState: this.optionsButton.enabled, + switchButtonState: this.switchButton.enabled, + openScmpButtonState: this.openScmpButton.enabled, + saveScmpButtonState: this.saveScmpButton.enabled, + cancelCompareButtonState: this.cancelCompareButton.enabled, + selectSourceButtonState: this.selectSourceButton.enabled, + selectTargetButtonState: this.selectTargetButton.enabled, + generateScriptButtonState: this.generateScriptButton.enabled, + applyButtonState: this.applyButton.enabled + }; + + return buttonObject; + } + + public verifyButtonsState(buttonState: ButtonState): boolean { + let result: boolean = false; + + if (this.compareButton.enabled === buttonState.compareButtonState && + this.optionsButton.enabled === buttonState.optionsButtonState && + this.switchButton.enabled === buttonState.switchButtonState && + this.openScmpButton.enabled === buttonState.openScmpButtonState && + this.saveScmpButton.enabled === buttonState.saveScmpButtonState && + this.cancelCompareButton.enabled === buttonState.cancelCompareButtonState && + this.selectSourceButton.enabled === buttonState.selectSourceButtonState && + this.selectTargetButton.enabled === buttonState.selectTargetButtonState && + this.generateScriptButton.enabled === buttonState.generateScriptButtonState && + this.applyButton.enabled === buttonState.applyButtonState) { + result = true; + } + + return result; + } +}