mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 02:51:36 -05:00
Schema Compare test coverage (#11042)
* Few tests for Schema Compare * Addressed comment- removed wait in test * Split setEndpointInfo for database and dacpac
This commit is contained in:
@@ -30,7 +30,7 @@ export default class MainController implements Disposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private initializeSchemaCompareDialog(): void {
|
private initializeSchemaCompareDialog(): void {
|
||||||
this.apiWrapper.registerCommand('schemaCompare.start', (context: any) => this.schemaCompareMainWindow.start(context));
|
this.apiWrapper.registerCommand('schemaCompare.start', async (context: any) => { await this.schemaCompareMainWindow.start(context); });
|
||||||
}
|
}
|
||||||
|
|
||||||
public dispose(): void {
|
public dispose(): void {
|
||||||
|
|||||||
@@ -82,12 +82,12 @@ export class SchemaCompareMainWindow {
|
|||||||
// 1. undefined
|
// 1. undefined
|
||||||
// 2. connection profile
|
// 2. connection profile
|
||||||
// 3. dacpac
|
// 3. dacpac
|
||||||
public async start(context: any) {
|
public async start(context: any): Promise<void> {
|
||||||
// if schema compare was launched from a db, set that as the source
|
// if schema compare was launched from a db, set that as the source
|
||||||
let profile = context ? <azdata.IConnectionProfile>context.connectionProfile : undefined;
|
let profile = context ? <azdata.IConnectionProfile>context.connectionProfile : undefined;
|
||||||
let sourceDacpac = context as string;
|
let sourceDacpac = context as string;
|
||||||
if (profile) {
|
if (profile) {
|
||||||
let ownerUri = await azdata.connection.getUriForConnection((profile.id));
|
let ownerUri = await this.apiWrapper.getUriForConnection((profile.id));
|
||||||
this.sourceEndpointInfo = {
|
this.sourceEndpointInfo = {
|
||||||
endpointType: mssql.SchemaCompareEndpointType.Database,
|
endpointType: mssql.SchemaCompareEndpointType.Database,
|
||||||
serverDisplayName: `${profile.serverName} ${profile.userName}`,
|
serverDisplayName: `${profile.serverName} ${profile.userName}`,
|
||||||
@@ -109,138 +109,146 @@ export class SchemaCompareMainWindow {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
this.editor.registerContent(async view => {
|
|
||||||
this.differencesTable = view.modelBuilder.table().withProperties({
|
|
||||||
data: [],
|
|
||||||
title: loc.differencesTableTitle
|
|
||||||
}).component();
|
|
||||||
|
|
||||||
this.diffEditor = view.modelBuilder.diffeditor().withProperties({
|
|
||||||
contentLeft: os.EOL,
|
|
||||||
contentRight: os.EOL,
|
|
||||||
height: 500,
|
|
||||||
title: loc.diffEditorTitle
|
|
||||||
}).component();
|
|
||||||
|
|
||||||
this.splitView = view.modelBuilder.splitViewContainer().component();
|
|
||||||
|
|
||||||
let sourceTargetLabels = view.modelBuilder.flexContainer()
|
|
||||||
.withProperties({
|
|
||||||
alignItems: 'stretch',
|
|
||||||
horizontal: true
|
|
||||||
}).component();
|
|
||||||
|
|
||||||
this.sourceTargetFlexLayout = view.modelBuilder.flexContainer()
|
|
||||||
.withProperties({
|
|
||||||
alignItems: 'stretch',
|
|
||||||
horizontal: true
|
|
||||||
}).component();
|
|
||||||
|
|
||||||
this.createSwitchButton(view);
|
|
||||||
this.createCompareButton(view);
|
|
||||||
this.createCancelButton(view);
|
|
||||||
this.createGenerateScriptButton(view);
|
|
||||||
this.createApplyButton(view);
|
|
||||||
this.createOptionsButton(view);
|
|
||||||
this.createOpenScmpButton(view);
|
|
||||||
this.createSaveScmpButton(view);
|
|
||||||
this.createSourceAndTargetButtons(view);
|
|
||||||
this.resetButtons(ResetButtonState.noSourceTarget);
|
|
||||||
|
|
||||||
let toolBar = view.modelBuilder.toolbarContainer();
|
|
||||||
toolBar.addToolbarItems([{
|
|
||||||
component: this.compareButton
|
|
||||||
}, {
|
|
||||||
component: this.cancelCompareButton
|
|
||||||
}, {
|
|
||||||
component: this.generateScriptButton
|
|
||||||
}, {
|
|
||||||
component: this.applyButton
|
|
||||||
}, {
|
|
||||||
component: this.optionsButton,
|
|
||||||
toolbarSeparatorAfter: true
|
|
||||||
}, {
|
|
||||||
component: this.switchButton,
|
|
||||||
toolbarSeparatorAfter: true
|
|
||||||
}, {
|
|
||||||
component: this.openScmpButton
|
|
||||||
}, {
|
|
||||||
component: this.saveScmpButton
|
|
||||||
}]);
|
|
||||||
|
|
||||||
let sourceLabel = view.modelBuilder.text().withProperties({
|
|
||||||
value: loc.sourceTitle,
|
|
||||||
CSSStyles: { 'margin-bottom': '0px' }
|
|
||||||
}).component();
|
|
||||||
|
|
||||||
let targetLabel = view.modelBuilder.text().withProperties({
|
|
||||||
value: loc.targetTitle,
|
|
||||||
CSSStyles: { 'margin-bottom': '0px' }
|
|
||||||
}).component();
|
|
||||||
|
|
||||||
let arrowLabel = view.modelBuilder.text().withProperties({
|
|
||||||
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' } });
|
|
||||||
this.sourceTargetFlexLayout.addItem(this.selectSourceButton, { CSSStyles: { 'margin-top': '10px' } });
|
|
||||||
this.sourceTargetFlexLayout.addItem(arrowLabel, { CSSStyles: { 'width': '10%', 'font-size': 'larger', 'text-align-last': 'center' } });
|
|
||||||
this.sourceTargetFlexLayout.addItem(this.targetNameComponent, { CSSStyles: { 'width': '40%', 'height': '25px', 'margin-top': '10px', 'margin-left': '15px' } });
|
|
||||||
this.sourceTargetFlexLayout.addItem(this.selectTargetButton, { CSSStyles: { 'margin-top': '10px' } });
|
|
||||||
|
|
||||||
this.loader = view.modelBuilder.loadingComponent().component();
|
|
||||||
this.waitText = view.modelBuilder.text().withProperties({
|
|
||||||
value: loc.waitText
|
|
||||||
}).component();
|
|
||||||
|
|
||||||
this.startText = view.modelBuilder.text().withProperties({
|
|
||||||
value: loc.startText
|
|
||||||
}).component();
|
|
||||||
|
|
||||||
this.noDifferencesLabel = view.modelBuilder.text().withProperties({
|
|
||||||
value: loc.noDifferencesText
|
|
||||||
}).component();
|
|
||||||
|
|
||||||
this.flexModel = view.modelBuilder.flexContainer().component();
|
|
||||||
this.flexModel.addItem(toolBar.component(), { flex: 'none' });
|
|
||||||
this.flexModel.addItem(sourceTargetLabels, { flex: 'none' });
|
|
||||||
this.flexModel.addItem(this.sourceTargetFlexLayout, { flex: 'none' });
|
|
||||||
this.flexModel.addItem(this.startText, { CSSStyles: { 'margin': 'auto' } });
|
|
||||||
|
|
||||||
this.flexModel.setLayout({
|
|
||||||
flexFlow: 'column',
|
|
||||||
height: '100%'
|
|
||||||
});
|
|
||||||
|
|
||||||
await view.initializeModel(this.flexModel);
|
|
||||||
});
|
|
||||||
|
|
||||||
await this.GetDefaultDeploymentOptions();
|
await this.GetDefaultDeploymentOptions();
|
||||||
this.editor.openEditor();
|
await Promise.all([
|
||||||
|
this.registerContent(),
|
||||||
|
this.editor.openEditor()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async registerContent(): Promise<void> {
|
||||||
|
return new Promise<void>((resolve) => {
|
||||||
|
this.editor.registerContent(async view => {
|
||||||
|
this.differencesTable = view.modelBuilder.table().withProperties({
|
||||||
|
data: [],
|
||||||
|
title: loc.differencesTableTitle
|
||||||
|
}).component();
|
||||||
|
|
||||||
|
this.diffEditor = view.modelBuilder.diffeditor().withProperties({
|
||||||
|
contentLeft: os.EOL,
|
||||||
|
contentRight: os.EOL,
|
||||||
|
height: 500,
|
||||||
|
title: loc.diffEditorTitle
|
||||||
|
}).component();
|
||||||
|
|
||||||
|
this.splitView = view.modelBuilder.splitViewContainer().component();
|
||||||
|
|
||||||
|
let sourceTargetLabels = view.modelBuilder.flexContainer()
|
||||||
|
.withProperties({
|
||||||
|
alignItems: 'stretch',
|
||||||
|
horizontal: true
|
||||||
|
}).component();
|
||||||
|
|
||||||
|
this.sourceTargetFlexLayout = view.modelBuilder.flexContainer()
|
||||||
|
.withProperties({
|
||||||
|
alignItems: 'stretch',
|
||||||
|
horizontal: true
|
||||||
|
}).component();
|
||||||
|
|
||||||
|
this.createSwitchButton(view);
|
||||||
|
this.createCompareButton(view);
|
||||||
|
this.createCancelButton(view);
|
||||||
|
this.createGenerateScriptButton(view);
|
||||||
|
this.createApplyButton(view);
|
||||||
|
this.createOptionsButton(view);
|
||||||
|
this.createOpenScmpButton(view);
|
||||||
|
this.createSaveScmpButton(view);
|
||||||
|
this.createSourceAndTargetButtons(view);
|
||||||
|
this.resetButtons(ResetButtonState.noSourceTarget);
|
||||||
|
|
||||||
|
let toolBar = view.modelBuilder.toolbarContainer();
|
||||||
|
toolBar.addToolbarItems([{
|
||||||
|
component: this.compareButton
|
||||||
|
}, {
|
||||||
|
component: this.cancelCompareButton
|
||||||
|
}, {
|
||||||
|
component: this.generateScriptButton
|
||||||
|
}, {
|
||||||
|
component: this.applyButton
|
||||||
|
}, {
|
||||||
|
component: this.optionsButton,
|
||||||
|
toolbarSeparatorAfter: true
|
||||||
|
}, {
|
||||||
|
component: this.switchButton,
|
||||||
|
toolbarSeparatorAfter: true
|
||||||
|
}, {
|
||||||
|
component: this.openScmpButton
|
||||||
|
}, {
|
||||||
|
component: this.saveScmpButton
|
||||||
|
}]);
|
||||||
|
|
||||||
|
let sourceLabel = view.modelBuilder.text().withProperties({
|
||||||
|
value: loc.sourceTitle,
|
||||||
|
CSSStyles: { 'margin-bottom': '0px' }
|
||||||
|
}).component();
|
||||||
|
|
||||||
|
let targetLabel = view.modelBuilder.text().withProperties({
|
||||||
|
value: loc.targetTitle,
|
||||||
|
CSSStyles: { 'margin-bottom': '0px' }
|
||||||
|
}).component();
|
||||||
|
|
||||||
|
let arrowLabel = view.modelBuilder.text().withProperties({
|
||||||
|
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' } });
|
||||||
|
this.sourceTargetFlexLayout.addItem(this.selectSourceButton, { CSSStyles: { 'margin-top': '10px' } });
|
||||||
|
this.sourceTargetFlexLayout.addItem(arrowLabel, { CSSStyles: { 'width': '10%', 'font-size': 'larger', 'text-align-last': 'center' } });
|
||||||
|
this.sourceTargetFlexLayout.addItem(this.targetNameComponent, { CSSStyles: { 'width': '40%', 'height': '25px', 'margin-top': '10px', 'margin-left': '15px' } });
|
||||||
|
this.sourceTargetFlexLayout.addItem(this.selectTargetButton, { CSSStyles: { 'margin-top': '10px' } });
|
||||||
|
|
||||||
|
this.loader = view.modelBuilder.loadingComponent().component();
|
||||||
|
this.waitText = view.modelBuilder.text().withProperties({
|
||||||
|
value: loc.waitText
|
||||||
|
}).component();
|
||||||
|
|
||||||
|
this.startText = view.modelBuilder.text().withProperties({
|
||||||
|
value: loc.startText
|
||||||
|
}).component();
|
||||||
|
|
||||||
|
this.noDifferencesLabel = view.modelBuilder.text().withProperties({
|
||||||
|
value: loc.noDifferencesText
|
||||||
|
}).component();
|
||||||
|
|
||||||
|
this.flexModel = view.modelBuilder.flexContainer().component();
|
||||||
|
this.flexModel.addItem(toolBar.component(), { flex: 'none' });
|
||||||
|
this.flexModel.addItem(sourceTargetLabels, { flex: 'none' });
|
||||||
|
this.flexModel.addItem(this.sourceTargetFlexLayout, { flex: 'none' });
|
||||||
|
this.flexModel.addItem(this.startText, { CSSStyles: { 'margin': 'auto' } });
|
||||||
|
|
||||||
|
this.flexModel.setLayout({
|
||||||
|
flexFlow: 'column',
|
||||||
|
height: '100%'
|
||||||
|
});
|
||||||
|
|
||||||
|
await view.initializeModel(this.flexModel);
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// update source and target name to display
|
// update source and target name to display
|
||||||
@@ -281,6 +289,15 @@ export class SchemaCompareMainWindow {
|
|||||||
return this.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 {
|
public setDeploymentOptions(deploymentOptions: mssql.DeploymentOptions): void {
|
||||||
this.deploymentOptions = deploymentOptions;
|
this.deploymentOptions = deploymentOptions;
|
||||||
}
|
}
|
||||||
@@ -298,7 +315,7 @@ export class SchemaCompareMainWindow {
|
|||||||
.withAdditionalProperties({
|
.withAdditionalProperties({
|
||||||
operationId: this.comparisonResult.operationId
|
operationId: this.comparisonResult.operationId
|
||||||
}).send();
|
}).send();
|
||||||
vscode.window.showErrorMessage(loc.compareErrorMessage(this.comparisonResult.errorMessage));
|
this.apiWrapper.showErrorMessage(loc.compareErrorMessage(this.comparisonResult.errorMessage));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
TelemetryReporter.createActionEvent(TelemetryViews.SchemaCompareMainWindow, 'SchemaComparisonFinished')
|
TelemetryReporter.createActionEvent(TelemetryViews.SchemaCompareMainWindow, 'SchemaComparisonFinished')
|
||||||
|
|||||||
@@ -4,16 +4,16 @@
|
|||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import * as should from 'should';
|
import * as should from 'should';
|
||||||
import * as azdata from 'azdata';
|
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import * as mssql from '../../../mssql';
|
import * as mssql from '../../../mssql';
|
||||||
import * as TypeMoq from 'typemoq';
|
import * as TypeMoq from 'typemoq';
|
||||||
|
import * as loc from '../localizedConstants';
|
||||||
import 'mocha';
|
import 'mocha';
|
||||||
import { SchemaCompareDialog } from './../dialogs/schemaCompareDialog';
|
import { SchemaCompareDialog } from './../dialogs/schemaCompareDialog';
|
||||||
import { SchemaCompareMainWindow } from '../schemaCompareMainWindow';
|
import { SchemaCompareMainWindow } from '../schemaCompareMainWindow';
|
||||||
import { SchemaCompareTestService } from './testSchemaCompareService';
|
import { SchemaCompareTestService, testStateScmp } from './testSchemaCompareService';
|
||||||
import { createContext, TestContext } from './testContext';
|
import { createContext, TestContext } from './testContext';
|
||||||
import { mockIConnectionProfile, mockDacpacEndpoint, mockFilePath } from './testUtils';
|
import { mockIConnectionProfile, mockFilePath, setDacpacEndpointInfo, setDatabaseEndpointInfo, shouldThrowSpecificError } from './testUtils';
|
||||||
|
|
||||||
// Mock test data
|
// Mock test data
|
||||||
const mocksource: string = 'source.dacpac';
|
const mocksource: string = 'source.dacpac';
|
||||||
@@ -26,7 +26,7 @@ before(async function (): Promise<void> {
|
|||||||
testContext = createContext();
|
testContext = createContext();
|
||||||
});
|
});
|
||||||
describe('SchemaCompareDialog.openDialog', function (): void {
|
describe('SchemaCompareDialog.openDialog', function (): void {
|
||||||
beforeEach(() => {
|
before(() => {
|
||||||
mockExtensionContext = TypeMoq.Mock.ofType<vscode.ExtensionContext>();
|
mockExtensionContext = TypeMoq.Mock.ofType<vscode.ExtensionContext>();
|
||||||
mockExtensionContext.setup(x => x.extensionPath).returns(() => '');
|
mockExtensionContext.setup(x => x.extensionPath).returns(() => '');
|
||||||
});
|
});
|
||||||
@@ -42,27 +42,22 @@ describe('SchemaCompareDialog.openDialog', function (): void {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('SchemaCompareResult.start', function (): void {
|
describe('SchemaCompareMainWindow.start', function (): void {
|
||||||
beforeEach(() => {
|
before(() => {
|
||||||
mockExtensionContext = TypeMoq.Mock.ofType<vscode.ExtensionContext>();
|
mockExtensionContext = TypeMoq.Mock.ofType<vscode.ExtensionContext>();
|
||||||
mockExtensionContext.setup(x => x.extensionPath).returns(() => '');
|
mockExtensionContext.setup(x => x.extensionPath).returns(() => '');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should be correct when created.', async function (): Promise<void> {
|
it('Should be correct when created.', async function (): Promise<void> {
|
||||||
let sc = new SchemaCompareTestService();
|
let sc = new SchemaCompareTestService();
|
||||||
|
|
||||||
let result = new SchemaCompareMainWindow(testContext.apiWrapper.object, sc, mockExtensionContext.object);
|
let result = new SchemaCompareMainWindow(testContext.apiWrapper.object, sc, mockExtensionContext.object);
|
||||||
await result.start(null);
|
await result.start(null);
|
||||||
let promise = new Promise(resolve => setTimeout(resolve, 5000)); // to ensure comparison result view is initialized
|
|
||||||
await promise;
|
|
||||||
|
|
||||||
should(result.getComparisonResult() === undefined);
|
should(result.getComparisonResult() === undefined);
|
||||||
|
|
||||||
let sourceEndpointInfo : mssql.SchemaCompareEndpointInfo = {...mockDacpacEndpoint};
|
result.sourceEndpointInfo = await setDacpacEndpointInfo(mocksource);
|
||||||
let targetEndpointInfo : mssql.SchemaCompareEndpointInfo = {...mockDacpacEndpoint};
|
result.targetEndpointInfo = await setDacpacEndpointInfo(mocktarget);
|
||||||
result.sourceEndpointInfo = sourceEndpointInfo;
|
|
||||||
result.sourceEndpointInfo.packageFilePath = mocksource;
|
|
||||||
result.targetEndpointInfo = targetEndpointInfo;
|
|
||||||
result.targetEndpointInfo.packageFilePath = mocktarget;
|
|
||||||
await result.execute();
|
await result.execute();
|
||||||
|
|
||||||
should(result.getComparisonResult() !== undefined);
|
should(result.getComparisonResult() !== undefined);
|
||||||
@@ -74,8 +69,6 @@ describe('SchemaCompareResult.start', function (): void {
|
|||||||
|
|
||||||
let result = new SchemaCompareMainWindow(testContext.apiWrapper.object, sc, mockExtensionContext.object);
|
let result = new SchemaCompareMainWindow(testContext.apiWrapper.object, sc, mockExtensionContext.object);
|
||||||
await result.start(undefined);
|
await result.start(undefined);
|
||||||
let promise = new Promise(resolve => setTimeout(resolve, 5000)); // to ensure comparison result view is initialized
|
|
||||||
await promise;
|
|
||||||
|
|
||||||
should.equal(result.sourceEndpointInfo, undefined);
|
should.equal(result.sourceEndpointInfo, undefined);
|
||||||
should.equal(result.targetEndpointInfo, undefined);
|
should.equal(result.targetEndpointInfo, undefined);
|
||||||
@@ -86,8 +79,6 @@ describe('SchemaCompareResult.start', function (): void {
|
|||||||
|
|
||||||
let result = new SchemaCompareMainWindow(testContext.apiWrapper.object, sc, mockExtensionContext.object);
|
let result = new SchemaCompareMainWindow(testContext.apiWrapper.object, sc, mockExtensionContext.object);
|
||||||
await result.start({connectionProfile: mockIConnectionProfile});
|
await result.start({connectionProfile: mockIConnectionProfile});
|
||||||
let promise = new Promise(resolve => setTimeout(resolve, 5000)); // to ensure comparison result view is initialized
|
|
||||||
await promise;
|
|
||||||
|
|
||||||
should.notEqual(result.sourceEndpointInfo, undefined);
|
should.notEqual(result.sourceEndpointInfo, undefined);
|
||||||
should.equal(result.sourceEndpointInfo.endpointType, mssql.SchemaCompareEndpointType.Database);
|
should.equal(result.sourceEndpointInfo.endpointType, mssql.SchemaCompareEndpointType.Database);
|
||||||
@@ -102,8 +93,6 @@ describe('SchemaCompareResult.start', function (): void {
|
|||||||
let result = new SchemaCompareMainWindow(testContext.apiWrapper.object, sc, mockExtensionContext.object);
|
let result = new SchemaCompareMainWindow(testContext.apiWrapper.object, sc, mockExtensionContext.object);
|
||||||
const dacpacPath = mockFilePath;
|
const dacpacPath = mockFilePath;
|
||||||
await result.start(dacpacPath);
|
await result.start(dacpacPath);
|
||||||
let promise = new Promise(resolve => setTimeout(resolve, 5000)); // to ensure comparison result view is initialized
|
|
||||||
await promise;
|
|
||||||
|
|
||||||
should.notEqual(result.sourceEndpointInfo, undefined);
|
should.notEqual(result.sourceEndpointInfo, undefined);
|
||||||
should.equal(result.sourceEndpointInfo.endpointType, mssql.SchemaCompareEndpointType.Dacpac);
|
should.equal(result.sourceEndpointInfo.endpointType, mssql.SchemaCompareEndpointType.Dacpac);
|
||||||
@@ -111,3 +100,86 @@ describe('SchemaCompareResult.start', function (): void {
|
|||||||
should.equal(result.targetEndpointInfo, undefined);
|
should.equal(result.targetEndpointInfo, undefined);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('SchemaCompareMainWindow.execute', function (): void {
|
||||||
|
before(() => {
|
||||||
|
mockExtensionContext = TypeMoq.Mock.ofType<vscode.ExtensionContext>();
|
||||||
|
mockExtensionContext.setup(x => x.extensionPath).returns(() => '');
|
||||||
|
testContext = createContext();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(async function (): Promise<void> {
|
||||||
|
testContext.apiWrapper.reset();
|
||||||
|
});
|
||||||
|
|
||||||
|
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 SchemaCompareMainWindow(testContext.apiWrapper.object, sc, mockExtensionContext.object);
|
||||||
|
|
||||||
|
await result.start(null);
|
||||||
|
|
||||||
|
should(result.getComparisonResult() === undefined);
|
||||||
|
|
||||||
|
result.sourceEndpointInfo = await setDacpacEndpointInfo(mocksource);
|
||||||
|
result.targetEndpointInfo = await setDacpacEndpointInfo(mocktarget);
|
||||||
|
|
||||||
|
await shouldThrowSpecificError(async () => await result.execute(), loc.compareErrorMessage('Test failure'));
|
||||||
|
});
|
||||||
|
|
||||||
|
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 SchemaCompareMainWindow(testContext.apiWrapper.object, sc, mockExtensionContext.object);
|
||||||
|
|
||||||
|
await result.start(null);
|
||||||
|
|
||||||
|
should(result.getComparisonResult() === undefined);
|
||||||
|
|
||||||
|
result.sourceEndpointInfo = await setDacpacEndpointInfo(mocksource);
|
||||||
|
result.targetEndpointInfo = await 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 SchemaCompareMainWindow(testContext.apiWrapper.object, sc, mockExtensionContext.object);
|
||||||
|
|
||||||
|
await result.start(null);
|
||||||
|
|
||||||
|
should(result.getComparisonResult() === undefined);
|
||||||
|
|
||||||
|
result.sourceEndpointInfo = await setDacpacEndpointInfo(mocksource);
|
||||||
|
result.targetEndpointInfo = await setDacpacEndpointInfo(mocktarget);
|
||||||
|
|
||||||
|
await result.execute();
|
||||||
|
|
||||||
|
//Generate script button and apply button should be disabled for dacpac comparison
|
||||||
|
should(result.verifyButtonsState(false, false)).equal(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
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 SchemaCompareMainWindow(testContext.apiWrapper.object, sc, mockExtensionContext.object);
|
||||||
|
|
||||||
|
await result.start(null);
|
||||||
|
|
||||||
|
should(result.getComparisonResult() === undefined);
|
||||||
|
|
||||||
|
result.sourceEndpointInfo = await setDacpacEndpointInfo(mocksource);
|
||||||
|
result.targetEndpointInfo = await setDatabaseEndpointInfo();
|
||||||
|
|
||||||
|
await result.execute();
|
||||||
|
|
||||||
|
//Generate script button and apply button should be enabled for database comparison
|
||||||
|
should(result.verifyButtonsState(true, true)).equal(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,16 @@ import * as mssql from '../../../mssql';
|
|||||||
export class SchemaCompareTestService implements mssql.ISchemaCompareService {
|
export class SchemaCompareTestService implements mssql.ISchemaCompareService {
|
||||||
|
|
||||||
testOperationId: string = 'Test Operation Id';
|
testOperationId: string = 'Test Operation Id';
|
||||||
|
testState: testStateScmp;
|
||||||
|
|
||||||
|
constructor(state?: testStateScmp) {
|
||||||
|
if (state) {
|
||||||
|
this.testState = state;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.testState = testStateScmp.SUCCESS_EQUAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
schemaComparePublishChanges(operationId: string, targetServerName: string, targetDatabaseName: string, taskExecutionMode: azdata.TaskExecutionMode): Thenable<azdata.ResultStatus> {
|
schemaComparePublishChanges(operationId: string, targetServerName: string, targetDatabaseName: string, taskExecutionMode: azdata.TaskExecutionMode): Thenable<azdata.ResultStatus> {
|
||||||
throw new Error('Method not implemented.');
|
throw new Error('Method not implemented.');
|
||||||
@@ -38,13 +48,56 @@ export class SchemaCompareTestService implements mssql.ISchemaCompareService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
schemaCompare(operationId: string, sourceEndpointInfo: mssql.SchemaCompareEndpointInfo, targetEndpointInfo: mssql.SchemaCompareEndpointInfo, taskExecutionMode: azdata.TaskExecutionMode): Thenable<mssql.SchemaCompareResult> {
|
schemaCompare(operationId: string, sourceEndpointInfo: mssql.SchemaCompareEndpointInfo, targetEndpointInfo: mssql.SchemaCompareEndpointInfo, taskExecutionMode: azdata.TaskExecutionMode): Thenable<mssql.SchemaCompareResult> {
|
||||||
let result: mssql.SchemaCompareResult = {
|
let result: mssql.SchemaCompareResult;
|
||||||
operationId: this.testOperationId,
|
if (this.testState === testStateScmp.FAILURE) {
|
||||||
areEqual: true,
|
result = {
|
||||||
differences: [],
|
operationId: this.testOperationId,
|
||||||
success: true,
|
areEqual: false,
|
||||||
errorMessage: ''
|
differences: [],
|
||||||
};
|
success: false,
|
||||||
|
errorMessage: 'Test failure'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (this.testState === testStateScmp.SUCCESS_NOT_EQUAL) {
|
||||||
|
result = {
|
||||||
|
operationId: this.testOperationId,
|
||||||
|
areEqual: false,
|
||||||
|
differences: [{
|
||||||
|
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
|
||||||
|
}],
|
||||||
|
success: true,
|
||||||
|
errorMessage: ''
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result = {
|
||||||
|
operationId: this.testOperationId,
|
||||||
|
areEqual: true,
|
||||||
|
differences: [],
|
||||||
|
success: true,
|
||||||
|
errorMessage: null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return Promise.resolve(result);
|
return Promise.resolve(result);
|
||||||
}
|
}
|
||||||
@@ -63,3 +116,9 @@ export class SchemaCompareTestService implements mssql.ISchemaCompareService {
|
|||||||
registerOnUpdated(handler: () => any): void {
|
registerOnUpdated(handler: () => any): void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum testStateScmp {
|
||||||
|
SUCCESS_EQUAL,
|
||||||
|
SUCCESS_NOT_EQUAL,
|
||||||
|
FAILURE
|
||||||
|
}
|
||||||
|
|||||||
@@ -99,3 +99,24 @@ export async function shouldThrowSpecificError(block: Function, expectedMessage:
|
|||||||
throw new AssertionError({ message: `Operation succeeded, but expected failure with exception: "${expectedMessage}".${details ? ' ' + details : ''}` });
|
throw new AssertionError({ message: `Operation succeeded, but expected failure with exception: "${expectedMessage}".${details ? ' ' + details : ''}` });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function setDacpacEndpointInfo(path: string): Promise<mssql.SchemaCompareEndpointInfo> {
|
||||||
|
let endpointInfo: mssql.SchemaCompareEndpointInfo;
|
||||||
|
|
||||||
|
endpointInfo = { ...mockDacpacEndpoint };
|
||||||
|
endpointInfo.packageFilePath = path;
|
||||||
|
|
||||||
|
return endpointInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function setDatabaseEndpointInfo(): Promise<mssql.SchemaCompareEndpointInfo> {
|
||||||
|
let endpointInfo: mssql.SchemaCompareEndpointInfo;
|
||||||
|
let dbName = 'My Database';
|
||||||
|
let serverName = 'My Server';
|
||||||
|
|
||||||
|
endpointInfo = { ...mockDatabaseEndpoint };
|
||||||
|
endpointInfo.databaseName = dbName;
|
||||||
|
endpointInfo.serverName = serverName;
|
||||||
|
|
||||||
|
return endpointInfo;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user