Swapping Record usage to Map in SQL Projects (#22758)

* Changing SqlCmdVars from Record to Map

* Converting the rest

* Updating tests

* more cleanup

* Updating test to use new test creation API
This commit is contained in:
Benjin Dubishar
2023-04-17 12:56:39 -07:00
committed by GitHub
parent 4a4580e9ef
commit 02e61d1598
21 changed files with 132 additions and 138 deletions

View File

@@ -83,10 +83,10 @@ describe('Publish Database Dialog', () => {
databaseName: 'MockDatabaseName',
serverName: 'MockServer',
connectionUri: 'Mock|Connection|Uri',
sqlCmdVariables: {
'ProdDatabaseName': 'MyProdDatabase',
'BackupDatabaseName': 'MyBackupDatabase'
},
sqlCmdVariables: new Map([
['ProdDatabaseName', 'MyProdDatabase'],
['BackupDatabaseName', 'MyBackupDatabase']
]),
deploymentOptions: mockDacFxOptionsResult.deploymentOptions,
profileUsed: false
};
@@ -100,10 +100,10 @@ describe('Publish Database Dialog', () => {
databaseName: 'MockDatabaseName',
serverName: 'MockServer',
connectionUri: 'Mock|Connection|Uri',
sqlCmdVariables: {
'ProdDatabaseName': 'MyProdDatabase',
'BackupDatabaseName': 'MyBackupDatabase'
},
sqlCmdVariables: new Map([
['ProdDatabaseName', 'MyProdDatabase'],
['BackupDatabaseName', 'MyBackupDatabase']
]),
deploymentOptions: mockDacFxOptionsResult.deploymentOptions,
profileUsed: false
};
@@ -128,10 +128,10 @@ describe('Publish Database Dialog', () => {
databaseName: 'MockDatabaseName',
serverName: 'localhost',
connectionUri: '',
sqlCmdVariables: {
'ProdDatabaseName': 'MyProdDatabase',
'BackupDatabaseName': 'MyBackupDatabase'
},
sqlCmdVariables: new Map([
['ProdDatabaseName', 'MyProdDatabase'],
['BackupDatabaseName', 'MyBackupDatabase']
]),
deploymentOptions: mockDacFxOptionsResult.deploymentOptions,
profileUsed: false
}

View File

@@ -48,9 +48,9 @@ describe('Project: sqlproj content operations', function (): void {
'Views\\User']);
// SqlCmdVariables
should(Object.keys(project.sqlCmdVariables).length).equal(2);
should(project.sqlCmdVariables['ProdDatabaseName']).equal('MyProdDatabase');
should(project.sqlCmdVariables['BackupDatabaseName']).equal('MyBackupDatabase');
should(project.sqlCmdVariables.size).equal(2);
should(project.sqlCmdVariables.get('ProdDatabaseName')).equal('MyProdDatabase');
should(project.sqlCmdVariables.get('BackupDatabaseName')).equal('MyBackupDatabase');
// Database references
// should only have one database reference even though there are two master.dacpac references (1 for ADS and 1 for SSDT)
@@ -647,7 +647,7 @@ describe('Project: database references', function (): void {
// add database reference to a different database on a different server
should(project.databaseReferences.length).equal(0, 'There should be no database references to start with');
should(Object.keys(project.sqlCmdVariables).length).equal(0, `There should be no sqlcmd variables to start with. Actual: ${Object.keys(project.sqlCmdVariables).length}`);
should(project.sqlCmdVariables.size).equal(0, `There should be no sqlcmd variables to start with. Actual: ${project.sqlCmdVariables.size}`);
await project.addProjectReference({
projectName: 'project1',
projectGuid: '',
@@ -658,7 +658,7 @@ describe('Project: database references', function (): void {
should(project.databaseReferences.length).equal(1, 'There should be a database reference after adding a reference to project1');
should(project.databaseReferences[0].referenceName).equal('project1', 'The database reference should be project1');
should(project.databaseReferences[0].suppressMissingDependenciesErrors).equal(false, 'project.databaseReferences[0].suppressMissingDependenciesErrors should be false');
should(Object.keys(project.sqlCmdVariables).length).equal(0, `There should be no sqlcmd variables added. Actual: ${Object.keys(project.sqlCmdVariables).length}`);
should(project.sqlCmdVariables.size).equal(0, `There should be no sqlcmd variables added. Actual: ${project.sqlCmdVariables.size}`);
});
it('Should add a project reference to a different database in the same server correctly', async function (): Promise<void> {
@@ -667,7 +667,7 @@ describe('Project: database references', function (): void {
// add database reference to a different database on a different server
should(project.databaseReferences.length).equal(0, 'There should be no database references to start with');
should(Object.keys(project.sqlCmdVariables).length).equal(0, 'There should be no sqlcmd variables to start with');
should(project.sqlCmdVariables.size).equal(0, 'There should be no sqlcmd variables to start with');
await project.addProjectReference({
projectName: 'project1',
projectGuid: '',
@@ -680,7 +680,7 @@ describe('Project: database references', function (): void {
should(project.databaseReferences.length).equal(1, 'There should be a database reference after adding a reference to project1');
should(project.databaseReferences[0].referenceName).equal('project1', 'The database reference should be project1');
should(project.databaseReferences[0].suppressMissingDependenciesErrors).equal(false, 'project.databaseReferences[0].suppressMissingDependenciesErrors should be false');
should(Object.keys(project.sqlCmdVariables).length).equal(1, `There should be one new sqlcmd variable added. Actual: ${Object.keys(project.sqlCmdVariables).length}`);
should(project.sqlCmdVariables.size).equal(1, `There should be one new sqlcmd variable added. Actual: ${project.sqlCmdVariables.size}`);
});
it('Should add a project reference to a different database in a different server correctly', async function (): Promise<void> {
@@ -689,7 +689,7 @@ describe('Project: database references', function (): void {
// add database reference to a different database on a different server
should(project.databaseReferences.length).equal(0, 'There should be no database references to start with');
should(Object.keys(project.sqlCmdVariables).length).equal(0, 'There should be no sqlcmd variables to start with');
should(project.sqlCmdVariables.size).equal(0, 'There should be no sqlcmd variables to start with');
await project.addProjectReference({
projectName: 'project1',
projectGuid: '',
@@ -704,7 +704,7 @@ describe('Project: database references', function (): void {
should(project.databaseReferences.length).equal(1, 'There should be a database reference after adding a reference to project1');
should(project.databaseReferences[0].referenceName).equal('project1', 'The database reference should be project1');
should(project.databaseReferences[0].suppressMissingDependenciesErrors).equal(false, 'project.databaseReferences[0].suppressMissingDependenciesErrors should be false');
should(Object.keys(project.sqlCmdVariables).length).equal(2, `There should be two new sqlcmd variables added. Actual: ${Object.keys(project.sqlCmdVariables).length}`);
should(project.sqlCmdVariables.size).equal(2, `There should be two new sqlcmd variables added. Actual: ${project.sqlCmdVariables.size}`);
});
it('Should not allow adding duplicate dacpac references', async function (): Promise<void> {
@@ -803,7 +803,7 @@ describe('Project: database references', function (): void {
});
should(project.databaseReferences.length).equal(1, 'There should be a database reference after adding a reference to test3');
should(project.databaseReferences[0].referenceName).equal('test3', 'The database reference should be test3');
should(Object.keys(project.sqlCmdVariables).length).equal(2, 'There should be 2 sqlcmdvars after adding the dacpac reference');
should(project.sqlCmdVariables.size).equal(2, 'There should be 2 sqlcmdvars after adding the dacpac reference');
// make sure reference to test3.dacpac and SQLCMD variables were added
let projFileText = (await fs.readFile(projFilePath)).toString();
@@ -815,7 +815,7 @@ describe('Project: database references', function (): void {
// delete reference
await project.deleteDatabaseReferenceByEntry(project.databaseReferences[0]);
should(project.databaseReferences.length).equal(0, 'There should be no database references after deleting');
should(Object.keys(project.sqlCmdVariables).length).equal(2, 'There should still be 2 sqlcmdvars after deleting the dacpac reference');
should(project.sqlCmdVariables.size).equal(2, 'There should still be 2 sqlcmdvars after deleting the dacpac reference');
// add reference to the same dacpac again but with different values for the sqlcmd variables
await project.addDatabaseReference({
@@ -828,7 +828,7 @@ describe('Project: database references', function (): void {
});
should(project.databaseReferences.length).equal(1, 'There should be a database reference after adding a reference to test3');
should(project.databaseReferences[0].referenceName).equal('test3', 'The database reference should be test3');
should(Object.keys(project.sqlCmdVariables).length).equal(2, 'There should still be 2 sqlcmdvars after adding the dacpac reference again with different sqlcmdvar values');
should(project.sqlCmdVariables.size).equal(2, 'There should still be 2 sqlcmdvars after adding the dacpac reference again with different sqlcmdvar values');
projFileText = (await fs.readFile(projFilePath)).toString();
should(projFileText).containEql('<SqlCmdVariable Include="test3Db">');
@@ -850,7 +850,7 @@ describe('Project: add SQLCMD Variables', function (): void {
it('Should update .sqlproj with new sqlcmd variables', async function (): Promise<void> {
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.openProjectFileBaseline);
let project = await Project.openProject(projFilePath);
should(Object.keys(project.sqlCmdVariables).length).equal(2, 'The project should have 2 sqlcmd variables when opened');
should(project.sqlCmdVariables.size).equal(2, 'The project should have 2 sqlcmd variables when opened');
// add a new variable
await project.addSqlCmdVariable('TestDatabaseName', 'TestDb');
@@ -858,9 +858,9 @@ describe('Project: add SQLCMD Variables', function (): void {
// update value of an existing sqlcmd variable
await project.updateSqlCmdVariable('ProdDatabaseName', 'NewProdName');
should(Object.keys(project.sqlCmdVariables).length).equal(3, 'There should be 3 sqlcmd variables after adding TestDatabaseName');
should(project.sqlCmdVariables['TestDatabaseName']).equal('TestDb', 'Value of TestDatabaseName should be TestDb');
should(project.sqlCmdVariables['ProdDatabaseName']).equal('NewProdName', 'ProdDatabaseName value should have been updated to the new value');
should(project.sqlCmdVariables.size).equal(3, 'There should be 3 sqlcmd variables after adding TestDatabaseName');
should(project.sqlCmdVariables.get('TestDatabaseName')).equal('TestDb', 'Value of TestDatabaseName should be TestDb');
should(project.sqlCmdVariables.get('ProdDatabaseName')).equal('NewProdName', 'ProdDatabaseName value should have been updated to the new value');
});
});

View File

@@ -303,7 +303,7 @@ describe('ProjectsController', function (): void {
});
it('Should exclude nested ProjectEntry from node', async function (): Promise<void> {
let proj = await testUtils.createTestProject(this.test, templates.newSqlProjectTemplate);
let proj = await testUtils.createTestSqlProject(this.test);
const setupResult = await setupDeleteExcludeTest(proj);
const scriptEntry = setupResult[0], projTreeRoot = setupResult[1], preDeployEntry = setupResult[2], postDeployEntry = setupResult[3], noneEntry = setupResult[4];
@@ -997,14 +997,14 @@ describe('ProjectsController', function (): void {
const projController = new ProjectsController(testContext.outputChannel);
const projRoot = new ProjectRootTreeItem(project);
should(Object.keys(project.sqlCmdVariables).length).equal(2, 'The project should start with 2 sqlcmd variables');
should(project.sqlCmdVariables.size).equal(2, 'The project should start with 2 sqlcmd variables');
sinon.stub(vscode.window, 'showWarningMessage').returns(<any>Promise.resolve('Cancel'));
await projController.delete(createWorkspaceTreeItem(projRoot.children.find(x => x.friendlyName === constants.sqlcmdVariablesNodeName)!.children[0]));
// reload project
project = await Project.openProject(project.projectFilePath);
should(Object.keys(project.sqlCmdVariables).length).equal(2, 'The project should still have 2 sqlcmd variables if no was selected');
should(project.sqlCmdVariables.size).equal(2, 'The project should still have 2 sqlcmd variables if no was selected');
sinon.restore();
sinon.stub(vscode.window, 'showWarningMessage').returns(<any>Promise.resolve('Yes'));
@@ -1012,7 +1012,7 @@ describe('ProjectsController', function (): void {
// reload project
project = await Project.openProject(project.projectFilePath);
should(Object.keys(project.sqlCmdVariables).length).equal(1, 'The project should only have 1 sqlcmd variable after deletion');
should(project.sqlCmdVariables.size).equal(1, 'The project should only have 1 sqlcmd variable after deletion');
});
it('Should add sqlcmd variable', async function (): Promise<void> {
@@ -1023,7 +1023,7 @@ describe('ProjectsController', function (): void {
const projController = new ProjectsController(testContext.outputChannel);
const projRoot = new ProjectRootTreeItem(project);
should(Object.keys(project.sqlCmdVariables).length).equal(2, 'The project should start with 2 sqlcmd variables');
should(project.sqlCmdVariables.size).equal(2, 'The project should start with 2 sqlcmd variables');
const inputBoxStub = sinon.stub(vscode.window, 'showInputBox');
inputBoxStub.resolves('');
@@ -1031,7 +1031,7 @@ describe('ProjectsController', function (): void {
// reload project
project = await Project.openProject(project.projectFilePath);
should(Object.keys(project.sqlCmdVariables).length).equal(2, 'The project should still have 2 sqlcmd variables if no name was provided');
should(project.sqlCmdVariables.size).equal(2, 'The project should still have 2 sqlcmd variables if no name was provided');
inputBoxStub.reset();
inputBoxStub.onFirstCall().resolves('newVariable');
@@ -1040,7 +1040,7 @@ describe('ProjectsController', function (): void {
// reload project
project = await Project.openProject(project.projectFilePath);
should(Object.keys(project.sqlCmdVariables).length).equal(3, 'The project should have 3 sqlcmd variable after adding a new one');
should(project.sqlCmdVariables.size).equal(3, 'The project should have 3 sqlcmd variable after adding a new one');
});
it('Should update sqlcmd variable', async function (): Promise<void> {
@@ -1051,18 +1051,18 @@ describe('ProjectsController', function (): void {
const projController = new ProjectsController(testContext.outputChannel);
const projRoot = new ProjectRootTreeItem(project);
should(Object.keys(project.sqlCmdVariables).length).equal(2, 'The project should start with 2 sqlcmd variables');
should(project.sqlCmdVariables.size).equal(2, 'The project should start with 2 sqlcmd variables');
const inputBoxStub = sinon.stub(vscode.window, 'showInputBox');
inputBoxStub.resolves('');
const sqlcmdVarToUpdate = projRoot.children.find(x => x.friendlyName === constants.sqlcmdVariablesNodeName)!.children[0];
const originalValue = project.sqlCmdVariables[sqlcmdVarToUpdate.friendlyName];
const originalValue = project.sqlCmdVariables.get(sqlcmdVarToUpdate.friendlyName);
await projController.editSqlCmdVariable(createWorkspaceTreeItem(sqlcmdVarToUpdate));
// reload project
project = await Project.openProject(project.projectFilePath);
should(Object.keys(project.sqlCmdVariables).length).equal(2, 'The project should still have 2 sqlcmd variables');
should(project.sqlCmdVariables[sqlcmdVarToUpdate.friendlyName]).equal(originalValue, 'The value of the sqlcmd variable should not have changed');
should(project.sqlCmdVariables.size).equal(2, 'The project should still have 2 sqlcmd variables');
should(project.sqlCmdVariables.get(sqlcmdVarToUpdate.friendlyName)).equal(originalValue, 'The value of the sqlcmd variable should not have changed');
inputBoxStub.reset();
const updatedValue = 'newValue';
@@ -1071,8 +1071,8 @@ describe('ProjectsController', function (): void {
// reload project
project = await Project.openProject(project.projectFilePath);
should(Object.keys(project.sqlCmdVariables).length).equal(2, 'The project should still have 2 sqlcmd variables');
should(project.sqlCmdVariables[sqlcmdVarToUpdate.friendlyName]).equal(updatedValue, 'The value of the sqlcmd variable should have been updated');
should(project.sqlCmdVariables.size).equal(2, 'The project should still have 2 sqlcmd variables');
should(project.sqlCmdVariables.get(sqlcmdVarToUpdate.friendlyName)).equal(updatedValue, 'The value of the sqlcmd variable should have been updated');
});
});
});

View File

@@ -49,8 +49,8 @@ describe('Publish profile tests', function (): void {
const result = await load(vscode.Uri.file(profilePath), testContext.dacFxService.object);
should(result.databaseName).equal('targetDb');
should(Object.keys(result.sqlCmdVariables).length).equal(1);
should(result.sqlCmdVariables['ProdDatabaseName']).equal('MyProdDatabase');
should(result.sqlCmdVariables.size).equal(1);
should(result.sqlCmdVariables.get('ProdDatabaseName')).equal('MyProdDatabase');
should(result.connectionId).equal('connId');
should(result.connection).equal('testserver (default)');
should(result.options).equal(mockDacFxOptionsResult.deploymentOptions);
@@ -74,8 +74,8 @@ describe('Publish profile tests', function (): void {
const result = await load(vscode.Uri.file(profilePath), testContext.dacFxService.object);
should(result.databaseName).equal('targetDb');
should(Object.keys(result.sqlCmdVariables).length).equal(1);
should(result.sqlCmdVariables['ProdDatabaseName']).equal('MyProdDatabase');
should(result.sqlCmdVariables.size).equal(1);
should(result.sqlCmdVariables.get('ProdDatabaseName')).equal('MyProdDatabase');
should(result.connectionId).equal('connId');
should(result.connection).equal('testserver (testUser)');
should(result.options).equal(mockDacFxOptionsResult.deploymentOptions);
@@ -89,10 +89,10 @@ describe('Publish profile tests', function (): void {
});
const result = await load(vscode.Uri.file(profilePath), testContext.dacFxService.object);
should(Object.keys(result.sqlCmdVariables).length).equal(1);
should(result.sqlCmdVariables.size).equal(1);
// the profile has both Value and DefaultValue, but Value should be the one used
should(result.sqlCmdVariables['ProdDatabaseName']).equal('MyProdDatabase');
should(result.sqlCmdVariables.get('ProdDatabaseName')).equal('MyProdDatabase');
});
it('Should throw error when connecting does not work', async function (): Promise<void> {

View File

@@ -56,13 +56,13 @@ export class MockDacFxService implements mssql.IDacFxService {
public importBacpac(_packageFilePath: string, _databaseName: string, _ownerUri: string, _taskExecutionMode: azdata.TaskExecutionMode): Thenable<mssql.DacFxResult> { return Promise.resolve(mockDacFxResult); }
public extractDacpac(_databaseName: string, _packageFilePath: string, _applicationName: string, _applicationVersion: string, _ownerUri: string, _taskExecutionMode: azdata.TaskExecutionMode): Thenable<mssql.DacFxResult> { return Promise.resolve(mockDacFxResult); }
public createProjectFromDatabase(_databaseName: string, _targetFilePath: string, _applicationName: string, _applicationVersion: string, _ownerUri: string, _extractTarget: mssql.ExtractTarget, _taskExecutionMode: azdata.TaskExecutionMode, _includePermissions?: boolean): Thenable<mssql.DacFxResult> { return Promise.resolve(mockDacFxResult); }
public deployDacpac(_packageFilePath: string, _targetDatabaseName: string, _upgradeExisting: boolean, _ownerUri: string, _taskExecutionMode: azdata.TaskExecutionMode, _sqlCommandVariableValues?: Record<string, string>, _deploymentOptions?: mssql.DeploymentOptions): Thenable<mssql.DacFxResult> { return Promise.resolve(mockDacFxResult); }
public generateDeployScript(_packageFilePath: string, _targetDatabaseName: string, _ownerUri: string, _taskExecutionMode: azdata.TaskExecutionMode, _sqlCommandVariableValues?: Record<string, string>, _deploymentOptions?: mssql.DeploymentOptions): Thenable<mssql.DacFxResult> { return Promise.resolve(mockDacFxResult); }
public deployDacpac(_packageFilePath: string, _targetDatabaseName: string, _upgradeExisting: boolean, _ownerUri: string, _taskExecutionMode: azdata.TaskExecutionMode, _sqlCommandVariableValues?: Map<string, string>, _deploymentOptions?: mssql.DeploymentOptions): Thenable<mssql.DacFxResult> { return Promise.resolve(mockDacFxResult); }
public generateDeployScript(_packageFilePath: string, _targetDatabaseName: string, _ownerUri: string, _taskExecutionMode: azdata.TaskExecutionMode, _sqlCommandVariableValues?: Map<string, string>, _deploymentOptions?: mssql.DeploymentOptions): Thenable<mssql.DacFxResult> { return Promise.resolve(mockDacFxResult); }
public generateDeployPlan(_packageFilePath: string, _targetDatabaseName: string, _ownerUri: string, _taskExecutionMode: azdata.TaskExecutionMode): Thenable<mssql.GenerateDeployPlanResult> { return Promise.resolve(mockDacFxResult); }
public getOptionsFromProfile(_profilePath: string): Thenable<mssql.DacFxOptionsResult> { return Promise.resolve(mockDacFxOptionsResult); }
public validateStreamingJob(_packageFilePath: string, _createStreamingJobTsql: string): Thenable<mssql.ValidateStreamingJobResult> { return Promise.resolve(mockDacFxResult); }
public parseTSqlScript(_filePath: string, _databaseSchemaProvider: string): Thenable<mssql.ParseTSqlScriptResult> { return Promise.resolve({ containsCreateTableStatement: true }); }
public savePublishProfile(_profilePath: string, _databaseName: string, _connectionString: string, _sqlCommandVariableValues?: Record<string, string>, _deploymentOptions?: mssql.DeploymentOptions): Thenable<azdata.ResultStatus> { return Promise.resolve(mockSavePublishResult); }
public savePublishProfile(_profilePath: string, _databaseName: string, _connectionString: string, _sqlCommandVariableValues?: Map<string, string>, _deploymentOptions?: mssql.DeploymentOptions): Thenable<azdata.ResultStatus> { return Promise.resolve(mockSavePublishResult); }
}
export function createContext(): TestContext {

View File

@@ -43,9 +43,7 @@ export async function getTestProjectPath(test: Mocha.Runnable | undefined): Prom
export async function createTestSqlProjFile(test: Mocha.Runnable | undefined, contents: string, folderPath?: string): Promise<string> {
folderPath = folderPath ?? path.join(await generateTestFolderPath(test), 'TestProject');
const macroDict: Record<string, string> = {
'PROJECT_DSP': constants.defaultDSP
};
const macroDict: Map<string, string> = new Map([['PROJECT_DSP', constants.defaultDSP]]);
contents = templates.macroExpansion(contents, macroDict);
return await createTestFile(test, contents, 'TestProject.sqlproj', folderPath);
}