mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-13 17:22:15 -05:00
1215 lines
68 KiB
TypeScript
1215 lines
68 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
import * as should from 'should';
|
|
import * as path from 'path';
|
|
import * as sinon from 'sinon';
|
|
import * as baselines from './baselines/baselines';
|
|
import * as testUtils from './testUtils';
|
|
import * as constants from '../common/constants';
|
|
|
|
import { promises as fs } from 'fs';
|
|
import { Project } from '../models/project';
|
|
import { exists, convertSlashesForSqlProj, getPlatformSafeFileEntryPath, systemDatabaseToString } from '../common/utils';
|
|
import { Uri, window } from 'vscode';
|
|
import { IDacpacReferenceSettings, INugetPackageReferenceSettings, IProjectReferenceSettings, ISystemDatabaseReferenceSettings } from '../models/IDatabaseReferenceSettings';
|
|
import { ItemType } from 'sqldbproj';
|
|
import { SystemDatabaseReferenceProjectEntry, SqlProjectReferenceProjectEntry, DacpacReferenceProjectEntry } from '../models/projectEntry';
|
|
import { ProjectType, SystemDatabase, SystemDbReferenceType } from 'mssql';
|
|
|
|
describe('Project: sqlproj content operations', function (): void {
|
|
before(async function (): Promise<void> {
|
|
await baselines.loadBaselines();
|
|
});
|
|
|
|
after(async function (): Promise<void> {
|
|
await testUtils.deleteGeneratedTestFolder();
|
|
});
|
|
|
|
it('Should read Project from sqlproj', async function (): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.openProjectFileBaseline);
|
|
const project: Project = await Project.openProject(projFilePath);
|
|
|
|
// Files and folders
|
|
(project.sqlObjectScripts.map(f => f.relativePath)).should.deepEqual([
|
|
'..\\Test\\Test.sql',
|
|
'MyExternalStreamingJob.sql',
|
|
'Tables\\Action History.sql',
|
|
'Tables\\Users.sql',
|
|
'Views\\Maintenance\\Database Performance.sql',
|
|
'Views\\User\\Profile.sql']);
|
|
|
|
(project.folders.map(f => f.relativePath)).should.deepEqual([
|
|
'Tables',
|
|
'Views',
|
|
'Views\\Maintenance',
|
|
'Views\\User']);
|
|
|
|
// SqlCmdVariables
|
|
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)
|
|
should(project.databaseReferences.length).equal(1);
|
|
should(project.databaseReferences[0].referenceName).containEql(constants.master);
|
|
should(project.databaseReferences[0] instanceof SystemDatabaseReferenceProjectEntry).equal(true);
|
|
|
|
// Pre-post deployment scripts
|
|
should(project.preDeployScripts.length).equal(1);
|
|
should(project.postDeployScripts.length).equal(1);
|
|
should(project.noneDeployScripts.length).equal(2);
|
|
should(project.preDeployScripts.find(f => f.relativePath === 'Script.PreDeployment1.sql')).not.equal(undefined, 'File Script.PreDeployment1.sql not read');
|
|
should(project.postDeployScripts.find(f => f.relativePath === 'Script.PostDeployment1.sql')).not.equal(undefined, 'File Script.PostDeployment1.sql not read');
|
|
should(project.noneDeployScripts.find(f => f.relativePath === 'Script.PreDeployment2.sql')).not.equal(undefined, 'File Script.PostDeployment2.sql not read');
|
|
should(project.noneDeployScripts.find(f => f.relativePath === 'Tables\\Script.PostDeployment1.sql')).not.equal(undefined, 'File Tables\\Script.PostDeployment1.sql not read');
|
|
|
|
// Publish profiles
|
|
should(project.publishProfiles.length).equal(3);
|
|
should(project.publishProfiles.find(f => f.relativePath === 'TestProjectName_1.publish.xml')).not.equal(undefined, 'Profile TestProjectName_1.publish.xml not read');
|
|
should(project.publishProfiles.find(f => f.relativePath === 'TestProjectName_2.publish.xml')).not.equal(undefined, 'Profile TestProjectName_2.publish.xml not read');
|
|
should(project.publishProfiles.find(f => f.relativePath === 'TestProjectName_3.publish.xml')).not.equal(undefined, 'Profile TestProjectName_3.publish.xml not read');
|
|
});
|
|
|
|
it('Should read Project with Project reference from sqlproj', async function (): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.openProjectWithProjectReferencesBaseline);
|
|
const project: Project = await Project.openProject(projFilePath);
|
|
|
|
// Database references
|
|
// should only have two database references even though there are two master.dacpac references (1 for ADS and 1 for SSDT)
|
|
(project.databaseReferences.length).should.equal(2);
|
|
(project.databaseReferences[0].referenceName).should.containEql('ReferencedTestProject');
|
|
(project.databaseReferences[0] instanceof SqlProjectReferenceProjectEntry).should.be.true();
|
|
(project.databaseReferences[1].referenceName).should.containEql(constants.master);
|
|
(project.databaseReferences[1] instanceof SystemDatabaseReferenceProjectEntry).should.be.true();
|
|
});
|
|
|
|
it('Should throw warning message while reading Project with more than 1 pre-deploy script from sqlproj', async function (): Promise<void> {
|
|
const stub = sinon.stub(window, 'showWarningMessage').returns(<any>Promise.resolve(constants.okString));
|
|
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.openSqlProjectWithPrePostDeploymentError);
|
|
const project: Project = await Project.openProject(projFilePath);
|
|
|
|
should(stub.calledOnce).be.true('showWarningMessage should have been called exactly once');
|
|
should(stub.calledWith(constants.prePostDeployCount)).be.true(`showWarningMessage not called with expected message '${constants.prePostDeployCount}' Actual '${stub.getCall(0).args[0]}'`);
|
|
|
|
should(project.preDeployScripts.length).equal(2);
|
|
should(project.postDeployScripts.length).equal(1);
|
|
should(project.noneDeployScripts.length).equal(1);
|
|
should(project.preDeployScripts.find(f => f.relativePath === 'Script.PreDeployment1.sql')).not.equal(undefined, 'File Script.PreDeployment1.sql not read');
|
|
should(project.postDeployScripts.find(f => f.relativePath === 'Script.PostDeployment1.sql')).not.equal(undefined, 'File Script.PostDeployment1.sql not read');
|
|
should(project.preDeployScripts.find(f => f.relativePath === 'Script.PreDeployment2.sql')).not.equal(undefined, 'File Script.PostDeployment2.sql not read');
|
|
should(project.noneDeployScripts.find(f => f.relativePath === 'Tables\\Script.PostDeployment1.sql')).not.equal(undefined, 'File Tables\\Script.PostDeployment1.sql not read');
|
|
|
|
sinon.restore();
|
|
});
|
|
|
|
it('Should perform Folder and SQL object script operations', async function (): Promise<void> {
|
|
const project = await testUtils.createTestSqlProject(this.test);
|
|
|
|
const folderPath = 'Stored Procedures';
|
|
const scriptPath = path.join(folderPath, 'Fake Stored Proc.sql');
|
|
const scriptContents = 'SELECT \'This is not actually a stored procedure.\'';
|
|
|
|
const scriptPathTagged = path.join(folderPath, 'Fake External Streaming Job.sql');
|
|
const scriptContentsTagged = 'EXEC sys.sp_create_streaming_job \'job\', \'SELECT 7\'';
|
|
|
|
(project.folders.length).should.equal(0);
|
|
(project.sqlObjectScripts.length).should.equal(0);
|
|
|
|
await project.addFolder(folderPath);
|
|
await project.addScriptItem(scriptPath, scriptContents);
|
|
await project.addScriptItem(scriptPathTagged, scriptContentsTagged, ItemType.externalStreamingJob);
|
|
|
|
(project.folders.length).should.equal(1);
|
|
(project.sqlObjectScripts.length).should.equal(2);
|
|
|
|
should(project.folders.find(f => f.relativePath === convertSlashesForSqlProj(folderPath))).not.equal(undefined);
|
|
should(project.sqlObjectScripts.find(f => f.relativePath === convertSlashesForSqlProj(scriptPath))).not.equal(undefined);
|
|
should(project.sqlObjectScripts.find(f => f.relativePath === convertSlashesForSqlProj(scriptPathTagged))).not.equal(undefined);
|
|
// TODO: support for tagged entries not supported in DacFx.Projects
|
|
//should(project.files.find(f => f.relativePath === convertSlashesForSqlProj(scriptPathTagged))?.sqlObjectType).equal(constants.ExternalStreamingJob);
|
|
});
|
|
|
|
it('Should bulk-add scripts to sqlproj with pre-existing scripts on disk', async function (): Promise<void> {
|
|
const project = await testUtils.createTestSqlProject(this.test);
|
|
|
|
// initial setup
|
|
(project.sqlObjectScripts.length).should.equal(0, 'initial number of scripts');
|
|
|
|
// create files on disk
|
|
const tablePath = path.join(project.projectFolderPath, 'MyTable.sql');
|
|
await fs.writeFile(tablePath, 'CREATE TABLE [MyTable] ([Name] [nvarchar(50)');
|
|
|
|
const viewPath = path.join(project.projectFolderPath, 'MyView.sql');
|
|
await fs.writeFile(viewPath, 'CREATE VIEW [MyView] AS SELECT * FROM [MyTable]');
|
|
|
|
// add to project
|
|
await project.addSqlObjectScripts(['MyTable.sql', 'MyView.sql']);
|
|
|
|
// verify result
|
|
(project.sqlObjectScripts.length).should.equal(2, 'Number of scripts after adding');
|
|
});
|
|
|
|
// TODO: move to DacFx once script contents supported
|
|
it('Should throw error while adding folders and SQL object scripts to sqlproj when a file does not exist on disk', async function (): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.openProjectFileBaseline);
|
|
const project = await testUtils.createTestSqlProject(this.test);
|
|
|
|
let list: Uri[] = [];
|
|
let testFolderPath: string = await testUtils.createDummyFileStructure(this.test, true, list, path.dirname(projFilePath));
|
|
|
|
const nonexistentFile = path.join(testFolderPath, 'nonexistentFile.sql');
|
|
list.push(Uri.file(nonexistentFile));
|
|
|
|
const relativePaths = list.map(f => path.relative(project.projectFolderPath, f.fsPath));
|
|
|
|
await testUtils.shouldThrowSpecificError(async () => await project.addSqlObjectScripts(relativePaths), `Error: No script found at '${nonexistentFile}'`);
|
|
});
|
|
|
|
it('Should perform pre-deployment script operations', async function (): Promise<void> {
|
|
let project = await testUtils.createTestSqlProject(this.test);
|
|
|
|
const relativePath = 'Script.PreDeployment1.sql';
|
|
const absolutePath = path.join(project.projectFolderPath, relativePath);
|
|
const fileContents = 'SELECT 7';
|
|
|
|
// initial state
|
|
(project.preDeployScripts.length).should.equal(0, 'initial state');
|
|
(await exists(absolutePath)).should.be.false('inital state');
|
|
|
|
// add new
|
|
await project.addScriptItem(relativePath, fileContents, ItemType.preDeployScript);
|
|
(project.preDeployScripts.length).should.equal(1);
|
|
(await exists(absolutePath)).should.be.true('add new');
|
|
|
|
// read
|
|
project = await Project.openProject(project.projectFilePath);
|
|
(project.preDeployScripts.length).should.equal(1, 'read');
|
|
(project.preDeployScripts[0].relativePath).should.equal(relativePath, 'read');
|
|
|
|
// exclude
|
|
await project.excludePreDeploymentScript(relativePath);
|
|
(project.preDeployScripts.length).should.equal(0, 'exclude');
|
|
(await exists(absolutePath)).should.be.true('exclude');
|
|
|
|
// add existing
|
|
await project.addScriptItem(relativePath, undefined, ItemType.preDeployScript);
|
|
(project.preDeployScripts.length).should.equal(1, 'add existing');
|
|
|
|
//delete
|
|
await project.deletePreDeploymentScript(relativePath);
|
|
(project.preDeployScripts.length).should.equal(0, 'delete');
|
|
(await exists(absolutePath)).should.be.false('delete');
|
|
});
|
|
|
|
it('Should show information messages when adding more than one pre/post deployment scripts to sqlproj', async function (): Promise<void> {
|
|
const stub = sinon.stub(window, 'showInformationMessage').returns(<any>Promise.resolve());
|
|
|
|
const project: Project = await testUtils.createTestSqlProject(this.test);
|
|
|
|
const preDeploymentScriptFilePath = 'Script.PreDeployment1.sql';
|
|
const postDeploymentScriptFilePath = 'Script.PostDeployment1.sql';
|
|
const preDeploymentScriptFilePath2 = 'Script.PreDeployment2.sql';
|
|
const postDeploymentScriptFilePath2 = 'Script.PostDeployment2.sql';
|
|
const fileContents = 'SELECT 7';
|
|
|
|
await project.addScriptItem(preDeploymentScriptFilePath, fileContents, ItemType.preDeployScript);
|
|
await project.addScriptItem(postDeploymentScriptFilePath, fileContents, ItemType.postDeployScript);
|
|
|
|
(stub.notCalled).should.be.true('showInformationMessage should not have been called');
|
|
|
|
await project.addScriptItem(preDeploymentScriptFilePath2, fileContents, ItemType.preDeployScript);
|
|
(stub.calledOnce).should.be.true('showInformationMessage should have been called once after adding extra pre-deployment script');
|
|
(stub.calledWith(constants.deployScriptExists(constants.PreDeploy))).should.be.true(`showInformationMessage not called with expected message '${constants.deployScriptExists(constants.PreDeploy)}'; actual: '${stub.firstCall.args[0]}'`);
|
|
|
|
stub.resetHistory();
|
|
|
|
await project.addScriptItem(postDeploymentScriptFilePath2, fileContents, ItemType.postDeployScript);
|
|
(stub.calledOnce).should.be.true('showInformationMessage should have been called once after adding extra post-deployment script');
|
|
should(stub.calledWith(constants.deployScriptExists(constants.PostDeploy))).be.true(`showInformationMessage not called with expected message '${constants.deployScriptExists(constants.PostDeploy)}' Actual '${stub.getCall(0).args[0]}'`);
|
|
});
|
|
|
|
// TODO: move to DacFx once script contents supported
|
|
it('Should not overwrite existing files', async function (): Promise<void> {
|
|
// Create new sqlproj
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.newProjectFileBaseline);
|
|
const fileList = await testUtils.createListOfFiles(this.test, path.dirname(projFilePath));
|
|
|
|
let project: Project = await Project.openProject(projFilePath);
|
|
|
|
// Add a file entry to the project with explicit content
|
|
let existingFileUri = fileList[3];
|
|
let fileStats = await fs.stat(existingFileUri.fsPath);
|
|
should(fileStats.isFile()).equal(true, 'Fourth entry in fileList should be a file');
|
|
|
|
const relativePath = path.relative(path.dirname(projFilePath), existingFileUri.fsPath);
|
|
await testUtils.shouldThrowSpecificError(
|
|
async () => await project.addScriptItem(relativePath, 'Hello World!'),
|
|
`A file with the name '${path.parse(relativePath).name}' already exists on disk at this location. Please choose another name.`);
|
|
});
|
|
|
|
// TODO: revisit correct behavior for this, since DacFx.Projects makes no restriction on absolute paths and external folders (which are represented as "..")
|
|
it.skip('Should not add folders outside of the project folder', async function (): Promise<void> {
|
|
// Create new sqlproj
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.newProjectFileBaseline);
|
|
|
|
let project: Project = await Project.openProject(projFilePath);
|
|
|
|
// Try adding project root folder itself - this is silently ignored
|
|
await project.addFolder(path.dirname(projFilePath));
|
|
should.equal(project.sqlObjectScripts.length, 0, 'Nothing should be added to the project');
|
|
|
|
// Try adding a parent of the project folder
|
|
await testUtils.shouldThrowSpecificError(
|
|
async () => await project.addFolder(path.dirname(path.dirname(projFilePath))),
|
|
'Items with absolute path outside project folder are not supported. Please make sure the paths in the project file are relative to project folder.',
|
|
'Folders outside the project folder should not be added.');
|
|
});
|
|
|
|
it('Should handle adding existing items to project', async function (): Promise<void> {
|
|
// Create new sqlproj
|
|
const project: Project = await testUtils.createTestSqlProject(this.test);
|
|
// Create 2 new files, a sql file and a txt file
|
|
const sqlFile = path.join(project.projectFolderPath, 'test.sql');
|
|
const txtFile = path.join(project.projectFolderPath, 'foo', 'test.txt');
|
|
await fs.writeFile(sqlFile, 'CREATE TABLE T1 (C1 INT)');
|
|
await fs.mkdir(path.dirname(txtFile));
|
|
await fs.writeFile(txtFile, 'Hello World!');
|
|
|
|
await project.readProjFile();
|
|
|
|
// Add them as existing files
|
|
await project.addFolder('foo'); // TODO: This shouldn't be necessary; DacFx.Projects needs to refresh the in-memory folder list internally after adding items
|
|
await project.addExistingItem(sqlFile);
|
|
await project.addExistingItem(txtFile);
|
|
|
|
// Validate files should have been added to project
|
|
(project.sqlObjectScripts.length).should.equal(1, `SQL script object count: ${project.sqlObjectScripts.map(x => x.relativePath).join('; ')}`);
|
|
(project.sqlObjectScripts[0].relativePath).should.equal('test.sql');
|
|
|
|
should(project.folders.length).equal(1, 'folders');
|
|
(project.folders[0].relativePath).should.equal('foo');
|
|
|
|
should(project.noneDeployScripts.length).equal(1, '<None> items');
|
|
(project.noneDeployScripts[0].relativePath).should.equal('foo\\test.txt');
|
|
});
|
|
|
|
it('Should read project properties', async function (): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.sqlProjPropertyReadBaseline);
|
|
const project: Project = await Project.openProject(projFilePath);
|
|
|
|
(project.sqlProjStyle).should.equal(ProjectType.SdkStyle);
|
|
(project.outputPath).should.equal(path.join(getPlatformSafeFileEntryPath(project.projectFolderPath), getPlatformSafeFileEntryPath('CustomOutputPath\\Dacpacs\\')));
|
|
(project.configuration).should.equal('Release');
|
|
(project.getDatabaseSourceValues()).should.deepEqual(['oneSource', 'twoSource', 'redSource', 'blueSource']);
|
|
(project.getProjectTargetVersion()).should.equal('130');
|
|
});
|
|
});
|
|
|
|
describe('Project: sdk style project content operations', function (): void {
|
|
before(async function (): Promise<void> {
|
|
await baselines.loadBaselines();
|
|
});
|
|
|
|
beforeEach(function (): void {
|
|
sinon.restore();
|
|
});
|
|
|
|
after(async function (): Promise<void> {
|
|
await testUtils.deleteGeneratedTestFolder();
|
|
});
|
|
|
|
it('Should exclude pre/post/none deploy scripts correctly', async function (): Promise<void> {
|
|
const folderPath = await testUtils.generateTestFolderPath(this.test);
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.newSdkStyleProjectSdkNodeBaseline, folderPath);
|
|
|
|
const project: Project = await Project.openProject(projFilePath);
|
|
await project.addScriptItem('Script.PreDeployment1.sql', 'fake contents', ItemType.preDeployScript);
|
|
await project.addScriptItem('Script.PreDeployment2.sql', 'fake contents', ItemType.preDeployScript);
|
|
await project.addScriptItem('Script.PostDeployment1.sql', 'fake contents', ItemType.postDeployScript);
|
|
|
|
// verify they were added to the sqlproj
|
|
should(project.preDeployScripts.length).equal(1, 'Script.PreDeployment1.sql should have been added');
|
|
should(project.noneDeployScripts.length).equal(1, 'Script.PreDeployment2.sql should have been added');
|
|
should(project.preDeployScripts.length).equal(1, 'Script.PostDeployment1.sql should have been added');
|
|
should(project.sqlObjectScripts.length).equal(0, 'There should not be any SQL object scripts');
|
|
|
|
// exclude the pre/post/none deploy script
|
|
await project.excludePreDeploymentScript('Script.PreDeployment1.sql');
|
|
await project.excludeNoneItem('Script.PreDeployment2.sql');
|
|
await project.excludePostDeploymentScript('Script.PostDeployment1.sql');
|
|
|
|
should(project.preDeployScripts.length).equal(0, 'Script.PreDeployment1.sql should have been removed');
|
|
should(project.noneDeployScripts.length).equal(0, 'Script.PreDeployment2.sql should have been removed');
|
|
should(project.postDeployScripts.length).equal(0, 'Script.PostDeployment1.sql should have been removed');
|
|
should(project.sqlObjectScripts.length).equal(0, 'There should not be any SQL object scripts after the excludes');
|
|
});
|
|
|
|
it('Should handle excluding glob included folders', async function (): Promise<void> {
|
|
const testFolderPath = await testUtils.generateTestFolderPath(this.test);
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.openSdkStyleSqlProjectBaseline, testFolderPath);
|
|
await testUtils.createDummyFileStructureWithPrePostDeployScripts(this.test, false, undefined, path.dirname(projFilePath));
|
|
|
|
const project: Project = await Project.openProject(projFilePath);
|
|
|
|
should(project.sqlObjectScripts.length).equal(13);
|
|
should(project.folders.length).equal(3);
|
|
should(project.noneDeployScripts.length).equal(2);
|
|
|
|
// try to exclude a glob included folder
|
|
await project.excludeFolder('folder1');
|
|
|
|
// verify folder and contents are excluded
|
|
should(project.folders.length).equal(1);
|
|
should(project.sqlObjectScripts.length).equal(6);
|
|
should(project.noneDeployScripts.length).equal(1, 'Script.PostDeployment2.sql should have been excluded');
|
|
should(project.folders.find(f => f.relativePath === 'folder1')).equal(undefined);
|
|
});
|
|
|
|
it('Should handle excluding folders', async function (): Promise<void> {
|
|
const testFolderPath = await testUtils.generateTestFolderPath(this.test,);
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.openSdkStyleSqlProjectBaseline, testFolderPath);
|
|
await testUtils.createDummyFileStructureWithPrePostDeployScripts(this.test, false, undefined, path.dirname(projFilePath));
|
|
|
|
const project: Project = await Project.openProject(projFilePath);
|
|
|
|
should(project.sqlObjectScripts.length).equal(13);
|
|
should(project.folders.length).equal(3);
|
|
|
|
// try to exclude a glob included folder
|
|
await project.excludeFolder('folder1\\nestedFolder');
|
|
|
|
// verify folder and contents are excluded
|
|
should(project.folders.length).equal(2);
|
|
should(project.sqlObjectScripts.length).equal(11);
|
|
should(project.folders.find(f => f.relativePath === 'folder1\\nestedFolder')).equal(undefined);
|
|
});
|
|
|
|
// skipped because exclude folder not yet supported
|
|
it('Should handle excluding explicitly included folders', async function (): Promise<void> {
|
|
const testFolderPath = await testUtils.generateTestFolderPath(this.test,);
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.openSdkStyleSqlProjectWithFilesSpecifiedBaseline, testFolderPath);
|
|
await testUtils.createDummyFileStructure(this.test, false, undefined, path.dirname(projFilePath));
|
|
|
|
const project: Project = await Project.openProject(projFilePath);
|
|
|
|
should(project.sqlObjectScripts.length).equal(11);
|
|
should(project.folders.length).equal(2);
|
|
should(project.folders.find(f => f.relativePath === 'folder1')!).not.equal(undefined);
|
|
should(project.folders.find(f => f.relativePath === 'folder2')!).not.equal(undefined);
|
|
|
|
// try to exclude an explicitly included folder without trailing \ in sqlproj
|
|
await project.excludeFolder('folder1');
|
|
|
|
// verify folder and contents are excluded
|
|
should(project.folders.length).equal(1);
|
|
should(project.sqlObjectScripts.length).equal(6);
|
|
should(project.folders.find(f => f.relativePath === 'folder1')).equal(undefined);
|
|
|
|
// try to exclude an explicitly included folder with trailing \ in sqlproj
|
|
await project.excludeFolder('folder2');
|
|
|
|
// verify folder and contents are excluded
|
|
should(project.folders.length).equal(0);
|
|
should(project.sqlObjectScripts.length).equal(1);
|
|
should(project.folders.find(f => f.relativePath === 'folder2')).equal(undefined);
|
|
});
|
|
|
|
it('Should handle deleting explicitly included folders', async function (): Promise<void> {
|
|
const testFolderPath = await testUtils.generateTestFolderPath(this.test,);
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.openSdkStyleSqlProjectWithFilesSpecifiedBaseline, testFolderPath);
|
|
await testUtils.createDummyFileStructureWithPrePostDeployScripts(this.test, false, undefined, path.dirname(projFilePath));
|
|
|
|
const project: Project = await Project.openProject(projFilePath);
|
|
|
|
should(project.sqlObjectScripts.length).equal(13);
|
|
should(project.folders.length).equal(3);
|
|
should(project.folders.find(f => f.relativePath === 'folder1')!).not.equal(undefined);
|
|
should(project.folders.find(f => f.relativePath === 'folder2')!).not.equal(undefined);
|
|
|
|
// try to delete an explicitly included folder with the trailing \ in sqlproj
|
|
await project.deleteFolder('folder2');
|
|
|
|
// verify the project not longer has folder2 and its contents
|
|
should(project.folders.length).equal(2);
|
|
should(project.sqlObjectScripts.length).equal(8);
|
|
should(project.folders.find(f => f.relativePath === 'folder2')).equal(undefined);
|
|
|
|
// try to delete an explicitly included folder without trailing \ in sqlproj
|
|
await project.deleteFolder('folder1');
|
|
|
|
// verify the project not longer has folder1 and its contents
|
|
should(project.folders.length).equal(0);
|
|
should(project.sqlObjectScripts.length).equal(1);
|
|
should(project.folders.find(f => f.relativePath === 'folder1')).equal(undefined);
|
|
});
|
|
|
|
// TODO: remove once DacFx exposes both absolute and relative outputPath
|
|
it('Should read OutputPath from sqlproj if there is one for SDK-style project', async function (): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.openSdkStyleSqlProjectBaseline);
|
|
const projFileText = (await fs.readFile(projFilePath)).toString();
|
|
|
|
// Verify sqlproj has OutputPath
|
|
should(projFileText.includes(constants.OutputPath)).equal(true);
|
|
|
|
const project: Project = await Project.openProject(projFilePath);
|
|
should(project.outputPath).equal(path.join(getPlatformSafeFileEntryPath(project.projectFolderPath), getPlatformSafeFileEntryPath('..\\otherFolder')));
|
|
should(project.dacpacOutputPath).equal(path.join(getPlatformSafeFileEntryPath(project.projectFolderPath), getPlatformSafeFileEntryPath('..\\otherFolder'), `${project.projectFileName}.dacpac`));
|
|
});
|
|
|
|
// TODO: move test to DacFx
|
|
it('Should use default output path if OutputPath is not specified in sqlproj', async function (): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.openSdkStyleSqlProjectWithGlobsSpecifiedBaseline);
|
|
const projFileText = (await fs.readFile(projFilePath)).toString();
|
|
|
|
// Verify sqlproj doesn't have <OutputPath>
|
|
should(projFileText.includes(`<${constants.OutputPath}>`)).equal(false);
|
|
|
|
const project: Project = await Project.openProject(projFilePath);
|
|
should(project.outputPath).equal(path.join(getPlatformSafeFileEntryPath(project.projectFolderPath), getPlatformSafeFileEntryPath(constants.defaultOutputPath(project.configuration.toString()))) + path.sep);
|
|
should(project.dacpacOutputPath).equal(path.join(getPlatformSafeFileEntryPath(project.projectFolderPath), getPlatformSafeFileEntryPath(constants.defaultOutputPath(project.configuration.toString())), `${project.projectFileName}.dacpac`));
|
|
});
|
|
});
|
|
|
|
describe('Project: database references', function (): void {
|
|
before(async function (): Promise<void> {
|
|
await baselines.loadBaselines();
|
|
});
|
|
|
|
after(async function (): Promise<void> {
|
|
await testUtils.deleteGeneratedTestFolder();
|
|
});
|
|
|
|
it('Should read database references correctly', async function (): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.databaseReferencesReadBaseline);
|
|
const project = await Project.openProject(projFilePath);
|
|
(project.databaseReferences.length).should.equal(5, 'NUmber of database references');
|
|
|
|
const systemRef: SystemDatabaseReferenceProjectEntry | undefined = project.databaseReferences.find(r => r instanceof SystemDatabaseReferenceProjectEntry) as SystemDatabaseReferenceProjectEntry;
|
|
should(systemRef).not.equal(undefined, 'msdb reference');
|
|
(systemRef!.referenceName).should.equal(constants.msdb);
|
|
(systemRef!.databaseVariableLiteralValue!).should.equal('msdbLiteral');
|
|
(systemRef!.suppressMissingDependenciesErrors).should.equal(true, 'suppressMissingDependenciesErrors for system db');
|
|
|
|
let projRef: SqlProjectReferenceProjectEntry | undefined = project.databaseReferences.find(r => r instanceof SqlProjectReferenceProjectEntry && r.referenceName === 'ReferencedProject') as SqlProjectReferenceProjectEntry;
|
|
should(projRef).not.equal(undefined, 'ReferencedProject reference');
|
|
(projRef!.pathForSqlProj()).should.equal('..\\ReferencedProject\\ReferencedProject.sqlproj');
|
|
(projRef!.projectGuid).should.equal('{BA5EBA11-C0DE-5EA7-ACED-BABB1E70A575}');
|
|
should(projRef!.databaseVariableLiteralValue).equal(null, 'databaseVariableLiteralValue for ReferencedProject');
|
|
(projRef!.databaseSqlCmdVariableName!).should.equal('projDbVar');
|
|
(projRef!.databaseSqlCmdVariableValue!).should.equal('$(SqlCmdVar__1)');
|
|
(projRef!.serverSqlCmdVariableName!).should.equal('projServerVar');
|
|
(projRef!.serverSqlCmdVariableValue!).should.equal('$(SqlCmdVar__2)');
|
|
(projRef!.suppressMissingDependenciesErrors).should.equal(true, 'suppressMissingDependenciesErrors for ReferencedProject');
|
|
|
|
projRef = project.databaseReferences.find(r => r instanceof SqlProjectReferenceProjectEntry && r.referenceName === 'OtherProject') as SqlProjectReferenceProjectEntry;
|
|
should(projRef).not.equal(undefined, 'OtherProject reference');
|
|
(projRef!.pathForSqlProj()).should.equal('..\\OtherProject\\OtherProject.sqlproj');
|
|
(projRef!.projectGuid).should.equal('{C0DEBA11-BA5E-5EA7-ACE5-BABB1E70A575}');
|
|
(projRef!.databaseVariableLiteralValue!).should.equal('OtherProjLiteral', 'databaseVariableLiteralValue for OtherProject');
|
|
should(projRef!.databaseSqlCmdVariableName).equal(undefined);
|
|
should(projRef!.databaseSqlCmdVariableValue).equal(undefined);
|
|
should(projRef!.serverSqlCmdVariableName).equal(undefined);
|
|
should(projRef!.serverSqlCmdVariableValue).equal(undefined);
|
|
(projRef!.suppressMissingDependenciesErrors).should.equal(false, 'suppressMissingDependenciesErrors for OtherProject');
|
|
|
|
let dacpacRef: DacpacReferenceProjectEntry | undefined = project.databaseReferences.find(r => r instanceof DacpacReferenceProjectEntry && r.referenceName === 'ReferencedDacpac') as DacpacReferenceProjectEntry;
|
|
should(dacpacRef).not.equal(undefined, 'dacpac reference for ReferencedDacpac');
|
|
(dacpacRef!.pathForSqlProj()).should.equal('..\\ReferencedDacpac\\ReferencedDacpac.dacpac');
|
|
should(dacpacRef!.databaseVariableLiteralValue).equal(null, 'databaseVariableLiteralValue for ReferencedDacpac');
|
|
(dacpacRef!.databaseSqlCmdVariableName!).should.equal('dacpacDbVar');
|
|
(dacpacRef!.databaseSqlCmdVariableValue!).should.equal('$(SqlCmdVar__3)');
|
|
(dacpacRef!.serverSqlCmdVariableName!).should.equal('dacpacServerVar');
|
|
(dacpacRef!.serverSqlCmdVariableValue!).should.equal('$(SqlCmdVar__4)');
|
|
(dacpacRef!.suppressMissingDependenciesErrors).should.equal(false, 'suppressMissingDependenciesErrors for ReferencedDacpac');
|
|
|
|
dacpacRef = project.databaseReferences.find(r => r instanceof DacpacReferenceProjectEntry && r.referenceName === 'OtherDacpac') as DacpacReferenceProjectEntry;
|
|
should(dacpacRef).not.equal(undefined, 'dacpac reference for OtherDacpac');
|
|
(dacpacRef!.pathForSqlProj()).should.equal('..\\OtherDacpac\\OtherDacpac.dacpac');
|
|
(dacpacRef!.databaseVariableLiteralValue!).should.equal('OtherDacpacLiteral', 'databaseVariableLiteralValue for OtherDacpac');
|
|
should(dacpacRef!.databaseSqlCmdVariableName).equal(undefined);
|
|
should(dacpacRef!.databaseSqlCmdVariableValue).equal(undefined);
|
|
should(dacpacRef!.serverSqlCmdVariableName).equal(undefined);
|
|
should(dacpacRef!.serverSqlCmdVariableValue).equal(undefined);
|
|
(dacpacRef!.suppressMissingDependenciesErrors).should.equal(true, 'suppressMissingDependenciesErrors for OtherDacpac');
|
|
});
|
|
|
|
it('Should delete database references correctly', async function (): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.databaseReferencesReadBaseline);
|
|
const project = await Project.openProject(projFilePath);
|
|
|
|
(project.databaseReferences.length).should.equal(5, 'There should be five database references');
|
|
|
|
await project.deleteDatabaseReference(constants.msdb);
|
|
(project.databaseReferences.length).should.equal(4, 'There should be four database references after deletion');
|
|
|
|
let ref = project.databaseReferences.find(r => r.referenceName === constants.msdb);
|
|
should(ref).equal(undefined, 'msdb reference should be deleted');
|
|
});
|
|
|
|
it('Should add system database artifact reference correctly', async function (): Promise<void> {
|
|
let project = await testUtils.createTestSqlProject(this.test);
|
|
|
|
const msdbRefSettings: ISystemDatabaseReferenceSettings = {
|
|
databaseVariableLiteralValue: systemDatabaseToString(SystemDatabase.MSDB),
|
|
systemDb: SystemDatabase.MSDB,
|
|
suppressMissingDependenciesErrors: true,
|
|
systemDbReferenceType: SystemDbReferenceType.ArtifactReference
|
|
};
|
|
await project.addSystemDatabaseReference(msdbRefSettings);
|
|
|
|
(project.databaseReferences.length).should.equal(1, 'There should be one database reference after adding a reference to msdb');
|
|
(project.databaseReferences[0].referenceName).should.equal(msdbRefSettings.databaseVariableLiteralValue, 'databaseName');
|
|
(project.databaseReferences[0].suppressMissingDependenciesErrors).should.equal(msdbRefSettings.suppressMissingDependenciesErrors, 'suppressMissingDependenciesErrors');
|
|
const projFileText = (await fs.readFile(project.projectFilePath)).toString();
|
|
(projFileText).should.containEql('<ArtifactReference Include="$(SystemDacpacsLocation)');
|
|
});
|
|
|
|
it('Should add system database package reference correctly', async function (): Promise<void> {
|
|
let project = await testUtils.createTestSqlProject(this.test);
|
|
|
|
const msdbRefSettings: ISystemDatabaseReferenceSettings = {
|
|
databaseVariableLiteralValue: systemDatabaseToString(SystemDatabase.MSDB),
|
|
systemDb: SystemDatabase.MSDB,
|
|
suppressMissingDependenciesErrors: true,
|
|
systemDbReferenceType: SystemDbReferenceType.PackageReference
|
|
};
|
|
await project.addSystemDatabaseReference(msdbRefSettings);
|
|
|
|
(project.databaseReferences.length).should.equal(1, 'There should be one database reference after adding a reference to msdb');
|
|
(project.databaseReferences[0].referenceName).should.equal(msdbRefSettings.databaseVariableLiteralValue, 'databaseName');
|
|
(project.databaseReferences[0].suppressMissingDependenciesErrors).should.equal(msdbRefSettings.suppressMissingDependenciesErrors, 'suppressMissingDependenciesErrors');
|
|
const projFileText = (await fs.readFile(project.projectFilePath)).toString();
|
|
(projFileText).should.containEql('Include="Microsoft.SqlServer.Dacpacs.Msdb">');
|
|
});
|
|
|
|
it('Should add a dacpac reference to the same database correctly', async function (): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.newProjectFileBaseline);
|
|
let project = await Project.openProject(projFilePath);
|
|
|
|
// add database reference in the same database
|
|
should(project.databaseReferences.length).equal(0, 'There should be no database references to start with');
|
|
await project.addDatabaseReference({ dacpacFileLocation: Uri.file('test1.dacpac'), suppressMissingDependenciesErrors: true });
|
|
|
|
should(project.databaseReferences.length).equal(1, 'There should be a database reference after adding a reference to test1');
|
|
should(project.databaseReferences[0].referenceName).equal('test1', 'The database reference should be test1');
|
|
should(project.databaseReferences[0].suppressMissingDependenciesErrors).equal(true, 'project.databaseReferences[0].suppressMissingDependenciesErrors should be true');
|
|
});
|
|
|
|
it('Should add a dacpac reference to a different database in the same server correctly', async function (): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.newProjectFileBaseline);
|
|
const project = await Project.openProject(projFilePath);
|
|
|
|
// add database reference to a different database on the same server
|
|
should(project.databaseReferences.length).equal(0, 'There should be no database references to start with');
|
|
await project.addDatabaseReference({
|
|
dacpacFileLocation: Uri.file('test2.dacpac'),
|
|
databaseName: 'test2DbName',
|
|
databaseVariable: 'test2Db',
|
|
suppressMissingDependenciesErrors: false
|
|
});
|
|
should(project.databaseReferences.length).equal(1, 'There should be a database reference after adding a reference to test2');
|
|
should(project.databaseReferences[0].referenceName).equal('test2', 'The database reference should be test2');
|
|
should(project.databaseReferences[0].suppressMissingDependenciesErrors).equal(false, 'project.databaseReferences[0].suppressMissingDependenciesErrors should be false');
|
|
});
|
|
|
|
it('Should add a dacpac reference to a different database in a different server correctly', async function (): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.newProjectFileBaseline);
|
|
const project = await Project.openProject(projFilePath);
|
|
|
|
// 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');
|
|
await project.addDatabaseReference({
|
|
dacpacFileLocation: Uri.file('test3.dacpac'),
|
|
databaseName: 'test3DbName',
|
|
databaseVariable: 'test3Db',
|
|
serverName: 'otherServerName',
|
|
serverVariable: 'otherServer',
|
|
suppressMissingDependenciesErrors: false
|
|
});
|
|
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(project.databaseReferences[0].suppressMissingDependenciesErrors).equal(false, 'project.databaseReferences[0].suppressMissingDependenciesErrors should be false');
|
|
});
|
|
|
|
it('Should add a project reference to the same database correctly', async function (): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.newProjectFileBaseline);
|
|
let project = await Project.openProject(projFilePath);
|
|
|
|
// add database reference to the same database
|
|
should(project.databaseReferences.length).equal(0, 'There should be no database references to start with');
|
|
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: '',
|
|
projectRelativePath: Uri.file(path.join('..', 'project1', 'project1.sqlproj')),
|
|
suppressMissingDependenciesErrors: false
|
|
});
|
|
|
|
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(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> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.newProjectFileBaseline);
|
|
let project = await Project.openProject(projFilePath);
|
|
|
|
// add database reference to a different database on the same different server
|
|
should(project.databaseReferences.length).equal(0, 'There should be no database references to start with');
|
|
should(project.sqlCmdVariables.size).equal(0, 'There should be no sqlcmd variables to start with');
|
|
await project.addProjectReference({
|
|
projectName: 'project1',
|
|
projectGuid: '',
|
|
projectRelativePath: Uri.file(path.join('..', 'project1', 'project1.sqlproj')),
|
|
databaseName: 'testdbName',
|
|
databaseVariable: 'testdb',
|
|
suppressMissingDependenciesErrors: false
|
|
});
|
|
|
|
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(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> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.newProjectFileBaseline);
|
|
let project = await Project.openProject(projFilePath);
|
|
|
|
// 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(project.sqlCmdVariables.size).equal(0, 'There should be no sqlcmd variables to start with');
|
|
await project.addProjectReference({
|
|
projectName: 'project1',
|
|
projectGuid: '',
|
|
projectRelativePath: Uri.file(path.join('..', 'project1', 'project1.sqlproj')),
|
|
databaseName: 'testdbName',
|
|
databaseVariable: 'testdb',
|
|
serverName: 'otherServerName',
|
|
serverVariable: 'otherServer',
|
|
suppressMissingDependenciesErrors: false
|
|
});
|
|
|
|
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(project.sqlCmdVariables.size).equal(2, `There should be two new sqlcmd variables added. Actual: ${project.sqlCmdVariables.size}`);
|
|
});
|
|
|
|
it('Should add a nupkg reference to the same database correctly', async function (): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.newSdkStyleProjectSdkNodeBaseline);
|
|
let project = await Project.openProject(projFilePath);
|
|
|
|
// add database reference to the same database
|
|
should(project.sqlProjStyle).equal(ProjectType.SdkStyle, 'Project should be SDK-style');
|
|
should(project.databaseReferences.length).equal(0, 'There should be no database references to start with');
|
|
should(project.sqlCmdVariables.size).equal(0, `There should be no sqlcmd variables to start with. Actual: ${project.sqlCmdVariables.size}`);
|
|
await project.addNugetPackageReference({
|
|
packageName: 'testPackage',
|
|
packageVersion: '1.0.1',
|
|
suppressMissingDependenciesErrors: false
|
|
});
|
|
|
|
should(project.databaseReferences.length).equal(1, 'There should be a database reference after adding a reference to project1');
|
|
should(project.databaseReferences[0].referenceName).equal('testPackage', 'The database reference should be project1');
|
|
should(project.databaseReferences[0].suppressMissingDependenciesErrors).equal(false, 'project.databaseReferences[0].suppressMissingDependenciesErrors should be false');
|
|
should(project.sqlCmdVariables.size).equal(0, `There should be no sqlcmd variables added. Actual: ${project.sqlCmdVariables.size}`);
|
|
});
|
|
|
|
it('Should add a nupkg reference to a different database in the same server correctly', async function (): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.newSdkStyleProjectSdkNodeBaseline);
|
|
let project = await Project.openProject(projFilePath);
|
|
|
|
// add database reference to a different database on the same different server
|
|
should(project.databaseReferences.length).equal(0, 'There should be no database references to start with');
|
|
should(project.sqlCmdVariables.size).equal(0, 'There should be no sqlcmd variables to start with');
|
|
await project.addNugetPackageReference({
|
|
packageName: 'testPackage',
|
|
packageVersion: '1.0.1',
|
|
databaseName: 'testdbName',
|
|
databaseVariable: 'testdb',
|
|
suppressMissingDependenciesErrors: false
|
|
});
|
|
|
|
should(project.databaseReferences.length).equal(1, 'There should be a database reference after adding a reference to testPackage');
|
|
should(project.databaseReferences[0].referenceName).equal('testPackage', 'The database reference should be testPackage');
|
|
should(project.databaseReferences[0].suppressMissingDependenciesErrors).equal(false, 'project.databaseReferences[0].suppressMissingDependenciesErrors should be false');
|
|
should(project.sqlCmdVariables.size).equal(1, `There should be one new sqlcmd variable added. Actual: ${project.sqlCmdVariables.size}`);
|
|
});
|
|
|
|
it('Should add a nupkg reference to a different database in a different server correctly', async function (): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.newSdkStyleProjectSdkNodeBaseline);
|
|
let project = await Project.openProject(projFilePath);
|
|
|
|
// 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(project.sqlCmdVariables.size).equal(0, 'There should be no sqlcmd variables to start with');
|
|
await project.addNugetPackageReference({
|
|
packageName: 'testPackage',
|
|
packageVersion: '1.0.1',
|
|
databaseName: 'testdbName',
|
|
databaseVariable: 'testdb',
|
|
serverName: 'otherServerName',
|
|
serverVariable: 'otherServer',
|
|
suppressMissingDependenciesErrors: false
|
|
});
|
|
|
|
should(project.databaseReferences.length).equal(1, 'There should be a database reference after adding a reference to testPackage');
|
|
should(project.databaseReferences[0].referenceName).equal('testPackage', 'The database reference should be testPackage');
|
|
should(project.databaseReferences[0].suppressMissingDependenciesErrors).equal(false, 'project.databaseReferences[0].suppressMissingDependenciesErrors should be false');
|
|
should(project.sqlCmdVariables.size).equal(2, `There should be two new sqlcmd variables added. Actual: ${project.sqlCmdVariables.size}`);
|
|
});
|
|
|
|
it('Should throw an error trying to add a nupkg reference to legacy style project', async function (): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.newProjectFileBaseline);
|
|
let project = await Project.openProject(projFilePath);
|
|
|
|
// add database reference to the same database
|
|
should(project.sqlProjStyle).equal(ProjectType.LegacyStyle, 'Project should be legacy-style');
|
|
should(project.databaseReferences.length).equal(0, 'There should be no database references to start with');
|
|
should(project.sqlCmdVariables.size).equal(0, `There should be no sqlcmd variables to start with. Actual: ${project.sqlCmdVariables.size}`);
|
|
await testUtils.shouldThrowSpecificError(async () => await project.addNugetPackageReference({
|
|
packageName: 'testPackage',
|
|
packageVersion: '1.0.1',
|
|
suppressMissingDependenciesErrors: false
|
|
}),
|
|
`Error adding database reference to testPackage. Error: Nuget package database references are not supported for the project ${project.projectFilePath}`
|
|
);
|
|
|
|
should(project.databaseReferences.length).equal(0, 'There should not have been any database reference added');
|
|
});
|
|
|
|
it('Should not allow adding duplicate dacpac references', async function (): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.newProjectFileBaseline);
|
|
let project = await Project.openProject(projFilePath);
|
|
|
|
should(project.databaseReferences.length).equal(0, 'There should be no database references to start with');
|
|
|
|
const dacpacReference: IDacpacReferenceSettings = { dacpacFileLocation: Uri.file('test.dacpac'), suppressMissingDependenciesErrors: false };
|
|
await project.addDatabaseReference(dacpacReference);
|
|
|
|
should(project.databaseReferences.length).equal(1, 'There should be one database reference after adding a reference to test.dacpac');
|
|
should(project.databaseReferences[0].referenceName).equal('test', 'project.databaseReferences[0].databaseName should be test');
|
|
|
|
// try to add reference to test.dacpac again
|
|
await testUtils.shouldThrowSpecificError(async () => await project.addDatabaseReference(dacpacReference), constants.databaseReferenceAlreadyExists);
|
|
should(project.databaseReferences.length).equal(1, 'There should be one database reference after trying to add a reference to test.dacpac again');
|
|
});
|
|
|
|
it('Should not allow adding duplicate system database references', async function (): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.newProjectFileBaseline);
|
|
let project = await Project.openProject(projFilePath);
|
|
|
|
should(project.databaseReferences.length).equal(0, 'There should be no database references to start with');
|
|
|
|
const systemDbReference: ISystemDatabaseReferenceSettings = {
|
|
databaseVariableLiteralValue: systemDatabaseToString(SystemDatabase.Master),
|
|
systemDb: SystemDatabase.Master,
|
|
suppressMissingDependenciesErrors: false,
|
|
systemDbReferenceType: SystemDbReferenceType.ArtifactReference
|
|
};
|
|
await project.addSystemDatabaseReference(systemDbReference);
|
|
project = await Project.openProject(projFilePath);
|
|
should(project.databaseReferences.length).equal(1, 'There should be one database reference after adding a reference to master');
|
|
should(project.databaseReferences[0].referenceName).equal(constants.master, 'project.databaseReferences[0].databaseName should be master');
|
|
|
|
// try to add reference to master again
|
|
await testUtils.shouldThrowSpecificError(async () => await project.addSystemDatabaseReference(systemDbReference), constants.databaseReferenceAlreadyExists);
|
|
should(project.databaseReferences.length).equal(1, 'There should only be one database reference after trying to add a reference to master again');
|
|
});
|
|
|
|
it('Should not allow adding duplicate project references', async function (): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.newProjectFileBaseline);
|
|
let project = await Project.openProject(projFilePath);
|
|
|
|
should(project.databaseReferences.length).equal(0, 'There should be no database references to start with');
|
|
|
|
const projectReference: IProjectReferenceSettings = {
|
|
projectName: 'testProject',
|
|
projectGuid: '',
|
|
projectRelativePath: Uri.file('testProject.sqlproj'),
|
|
suppressMissingDependenciesErrors: false
|
|
};
|
|
await project.addProjectReference(projectReference);
|
|
|
|
should(project.databaseReferences.length).equal(1, 'There should be one database reference after adding a reference to testProject.sqlproj');
|
|
should(project.databaseReferences[0].referenceName).equal('testProject', 'project.databaseReferences[0].databaseName should be testProject');
|
|
|
|
// try to add reference to testProject again
|
|
await testUtils.shouldThrowSpecificError(async () => await project.addProjectReference(projectReference), constants.databaseReferenceAlreadyExists);
|
|
should(project.databaseReferences.length).equal(1, 'There should be one database reference after trying to add a reference to testProject again');
|
|
});
|
|
|
|
it('Should not allow adding duplicate nupkg references', async function (): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.newSdkStyleProjectSdkNodeBaseline);
|
|
let project = await Project.openProject(projFilePath);
|
|
|
|
should(project.databaseReferences.length).equal(0, 'There should be no database references to start with');
|
|
|
|
const nupkgReference: INugetPackageReferenceSettings = {
|
|
packageName: 'testPackage',
|
|
packageVersion: '1.0.0',
|
|
suppressMissingDependenciesErrors: false
|
|
};
|
|
await project.addNugetPackageReference(nupkgReference);
|
|
|
|
should(project.databaseReferences.length).equal(1, 'There should be one database reference after adding a reference to testPackage');
|
|
should(project.databaseReferences[0].referenceName).equal('testPackage', 'project.databaseReferences[0].databaseName should be testPackage');
|
|
|
|
// try to add reference to testPackage again
|
|
await testUtils.shouldThrowSpecificError(async () => await project.addNugetPackageReference(nupkgReference), constants.databaseReferenceAlreadyExists);
|
|
should(project.databaseReferences.length).equal(1, 'There should be one database reference after trying to add a reference to testPackage again');
|
|
});
|
|
|
|
it('Should handle trying to add duplicate database references when slashes are different direction', async function (): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.newProjectFileBaseline);
|
|
let project = await Project.openProject(projFilePath);
|
|
|
|
should(project.databaseReferences.length).equal(0, 'There should be no database references to start with');
|
|
|
|
const projectReference: IProjectReferenceSettings = {
|
|
projectName: 'testProject',
|
|
projectGuid: '',
|
|
projectRelativePath: Uri.file('testFolder/testProject.sqlproj'),
|
|
suppressMissingDependenciesErrors: false
|
|
};
|
|
await project.addProjectReference(projectReference);
|
|
|
|
should(project.databaseReferences.length).equal(1, 'There should be one database reference after adding a reference to testProject.sqlproj');
|
|
should(project.databaseReferences[0].referenceName).equal('testProject', 'project.databaseReferences[0].databaseName should be testProject');
|
|
|
|
// try to add reference to testProject again with slashes in the other direction
|
|
projectReference.projectRelativePath = Uri.file('testFolder\\testProject.sqlproj');
|
|
await testUtils.shouldThrowSpecificError(async () => await project.addProjectReference(projectReference), constants.databaseReferenceAlreadyExists);
|
|
should(project.databaseReferences.length).equal(1, 'There should be one database reference after trying to add a reference to testProject again');
|
|
});
|
|
|
|
it('Should update sqlcmd variable values if value changes', async function (): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.newProjectFileBaseline);
|
|
const project = await Project.openProject(projFilePath);
|
|
const databaseVariable = 'test3Db';
|
|
const serverVariable = 'otherServer';
|
|
|
|
should(project.databaseReferences.length).equal(0, 'There should be no database references to start with');
|
|
await project.addDatabaseReference({
|
|
dacpacFileLocation: Uri.file('test3.dacpac'),
|
|
databaseName: 'test3DbName',
|
|
databaseVariable: databaseVariable,
|
|
serverName: 'otherServerName',
|
|
serverVariable: serverVariable,
|
|
suppressMissingDependenciesErrors: false
|
|
});
|
|
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(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();
|
|
should(projFileText).containEql('<SqlCmdVariable Include="test3Db">');
|
|
should(projFileText).containEql('<DefaultValue>test3DbName</DefaultValue>');
|
|
should(projFileText).containEql('<SqlCmdVariable Include="otherServer">');
|
|
should(projFileText).containEql('<DefaultValue>otherServerName</DefaultValue>');
|
|
|
|
// delete reference
|
|
await project.deleteDatabaseReferenceByEntry(project.databaseReferences[0]);
|
|
should(project.databaseReferences.length).equal(0, 'There should be no database references after deleting');
|
|
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({
|
|
dacpacFileLocation: Uri.file('test3.dacpac'),
|
|
databaseName: 'newDbName',
|
|
databaseVariable: databaseVariable,
|
|
serverName: 'newServerName',
|
|
serverVariable: serverVariable,
|
|
suppressMissingDependenciesErrors: false
|
|
});
|
|
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(project.sqlCmdVariables.size).equal(2, 'There should still be 2 sqlcmdvars after adding the dacpac reference again with different sqlcmdvar values');
|
|
});
|
|
});
|
|
|
|
describe('Project: add SQLCMD Variables', function (): void {
|
|
before(async function (): Promise<void> {
|
|
await baselines.loadBaselines();
|
|
});
|
|
|
|
after(async function (): Promise<void> {
|
|
await testUtils.deleteGeneratedTestFolder();
|
|
});
|
|
|
|
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(project.sqlCmdVariables.size).equal(2, 'The project should have 2 sqlcmd variables when opened');
|
|
|
|
// add a new variable
|
|
await project.addSqlCmdVariable('TestDatabaseName', 'TestDb');
|
|
|
|
// update value of an existing sqlcmd variable
|
|
await project.updateSqlCmdVariable('ProdDatabaseName', 'NewProdName');
|
|
|
|
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');
|
|
});
|
|
});
|
|
|
|
describe('Project: publish profiles', function (): void {
|
|
before(async function (): Promise<void> {
|
|
await baselines.loadBaselines();
|
|
});
|
|
|
|
after(async function (): Promise<void> {
|
|
await testUtils.deleteGeneratedTestFolder();
|
|
});
|
|
|
|
it('Should add new publish profile', async function (): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.openProjectFileBaseline);
|
|
const project = await Project.openProject(projFilePath);
|
|
should(project.publishProfiles.length).equal(3);
|
|
|
|
// add a new publish profile
|
|
const newProfilePath = path.join(project.projectFolderPath, 'TestProjectName_4.publish.xml');
|
|
await fs.writeFile(newProfilePath, '<fake-publish-profile type="stage"/>');
|
|
|
|
await project.addNoneItem('TestProjectName_4.publish.xml');
|
|
|
|
should(project.publishProfiles.length).equal(4);
|
|
});
|
|
});
|
|
|
|
describe('Project: properties', function (): void {
|
|
before(async function (): Promise<void> {
|
|
await baselines.loadBaselines();
|
|
});
|
|
|
|
after(async function (): Promise<void> {
|
|
await testUtils.deleteGeneratedTestFolder();
|
|
});
|
|
|
|
it('Should read target database version', async function (): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.openProjectFileBaseline);
|
|
const project = await Project.openProject(projFilePath);
|
|
|
|
should(project.getProjectTargetVersion()).equal('150');
|
|
});
|
|
|
|
it('Should throw on missing target database version', async function (): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.sqlProjectMissingVersionBaseline);
|
|
|
|
await testUtils.shouldThrowSpecificError(async () => await Project.openProject(projFilePath), 'Error: No target platform defined. Missing <DSP> node.');
|
|
});
|
|
|
|
it('Should throw on invalid target database version', async function (): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.sqlProjectInvalidVersionBaseline);
|
|
|
|
try {
|
|
await Project.openProject(projFilePath);
|
|
throw new Error('Should not have succeeded.');
|
|
} catch (e) {
|
|
(e.message).should.startWith('Error: Invalid value for Database Schema Provider:');
|
|
(e.message).should.endWith('expected to be in the form \'Microsoft.Data.Tools.Schema.Sql.Sql160DatabaseSchemaProvider\'.');
|
|
}
|
|
});
|
|
|
|
it('Should read default database collation', async function (): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.sqlProjectCustomCollationBaseline);
|
|
const project = await Project.openProject(projFilePath);
|
|
|
|
should(project.getDatabaseDefaultCollation()).equal('SQL_Latin1_General_CP1255_CS_AS');
|
|
});
|
|
|
|
it('Should return default value when database collation is not specified', async function (): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.newProjectFileBaseline);
|
|
const project = await Project.openProject(projFilePath);
|
|
|
|
should(project.getDatabaseDefaultCollation()).equal('SQL_Latin1_General_CP1_CI_AS');
|
|
});
|
|
|
|
// TODO: skipped until DacFx throws on invalid value
|
|
it.skip('Should throw on invalid default database collation', async function (): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.sqlProjectInvalidCollationBaseline);
|
|
|
|
try {
|
|
await Project.openProject(projFilePath);
|
|
throw new Error('Should not have succeeded.');
|
|
} catch (e) {
|
|
(e.message).should.startWith('Error: Invalid value for DefaultCollation:');
|
|
}
|
|
});
|
|
|
|
it('Should add database source to project property', async function (): Promise<void> {
|
|
const project = await testUtils.createTestSqlProject(this.test);
|
|
|
|
// Should add a single database source
|
|
await project.addDatabaseSource('test1');
|
|
let databaseSourceItems: string[] = project.getDatabaseSourceValues();
|
|
should(databaseSourceItems.length).equal(1, 'number of database sources: ' + databaseSourceItems);
|
|
should(databaseSourceItems[0]).equal('test1');
|
|
|
|
// Should add multiple database sources
|
|
await project.addDatabaseSource('test2');
|
|
await project.addDatabaseSource('test3');
|
|
databaseSourceItems = project.getDatabaseSourceValues();
|
|
should(databaseSourceItems.length).equal(3, 'number of database sources: ' + databaseSourceItems);
|
|
should(databaseSourceItems[0]).equal('test1');
|
|
should(databaseSourceItems[1]).equal('test2');
|
|
should(databaseSourceItems[2]).equal('test3');
|
|
|
|
// Should not add duplicate database sources
|
|
await project.addDatabaseSource('test1');
|
|
await project.addDatabaseSource('test2');
|
|
await project.addDatabaseSource('test3');
|
|
should(databaseSourceItems.length).equal(3);
|
|
should(databaseSourceItems[0]).equal('test1');
|
|
should(databaseSourceItems[1]).equal('test2');
|
|
should(databaseSourceItems[2]).equal('test3');
|
|
});
|
|
|
|
it('Should remove database source from project property', async function (): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.sqlProjectInvalidCollationBaseline);
|
|
const project = await Project.openProject(projFilePath);
|
|
|
|
await project.addDatabaseSource('test1');
|
|
await project.addDatabaseSource('test2');
|
|
await project.addDatabaseSource('test3');
|
|
await project.addDatabaseSource('test4');
|
|
|
|
let databaseSourceItems: string[] = project.getDatabaseSourceValues();
|
|
should(databaseSourceItems.length).equal(4);
|
|
|
|
// Should remove database sources
|
|
await project.removeDatabaseSource('test2');
|
|
await project.removeDatabaseSource('test1');
|
|
await project.removeDatabaseSource('test4');
|
|
|
|
databaseSourceItems = project.getDatabaseSourceValues();
|
|
should(databaseSourceItems.length).equal(1);
|
|
should(databaseSourceItems[0]).equal('test3');
|
|
|
|
// Should remove database source tag when last database source is removed
|
|
await project.removeDatabaseSource('test3');
|
|
databaseSourceItems = project.getDatabaseSourceValues();
|
|
|
|
should(databaseSourceItems.length).equal(0);
|
|
});
|
|
|
|
it('Should throw error when adding or removing database source that contains semicolon', async function (): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(this.test, baselines.sqlProjectInvalidCollationBaseline);
|
|
const project = await Project.openProject(projFilePath);
|
|
const semicolon = ';';
|
|
|
|
await testUtils.shouldThrowSpecificError(
|
|
async () => await project.addDatabaseSource(semicolon),
|
|
constants.invalidProjectPropertyValueProvided(semicolon));
|
|
|
|
await testUtils.shouldThrowSpecificError(
|
|
async () => await project.removeDatabaseSource(semicolon),
|
|
constants.invalidProjectPropertyValueProvided(semicolon));
|
|
});
|
|
});
|
|
|
|
describe('Project: round trip updates', function (): void {
|
|
before(async function (): Promise<void> {
|
|
await baselines.loadBaselines();
|
|
});
|
|
|
|
beforeEach(function (): void {
|
|
sinon.restore();
|
|
});
|
|
|
|
after(async function (): Promise<void> {
|
|
await testUtils.deleteGeneratedTestFolder();
|
|
});
|
|
|
|
it('Should update SSDT project to work in ADS', async function (): Promise<void> {
|
|
await testUpdateInRoundTrip(this.test, baselines.SSDTProjectFileBaseline);
|
|
});
|
|
|
|
it.skip('Should update SSDT project with new system database references', async function (): Promise<void> {
|
|
await testUpdateInRoundTrip(this.test, baselines.SSDTUpdatedProjectBaseline);
|
|
});
|
|
|
|
it('Should update SSDT project to work in ADS handling pre-existing targets', async function (): Promise<void> {
|
|
await testUpdateInRoundTrip(this.test, baselines.SSDTProjectBaselineWithBeforeBuildTarget);
|
|
});
|
|
|
|
it('Should not update project and no backup file should be created when prompt to update project is rejected', async function (): Promise<void> {
|
|
sinon.stub(window, 'showWarningMessage').returns(<any>Promise.resolve(constants.noString));
|
|
// setup test files
|
|
const folderPath = await testUtils.generateTestFolderPath(this.test);
|
|
const sqlProjPath = await testUtils.createTestSqlProjFile(this.test, baselines.SSDTProjectFileBaseline, folderPath);
|
|
|
|
const originalSqlProjContents = (await fs.readFile(sqlProjPath)).toString();
|
|
|
|
// validate original state
|
|
let project = await Project.openProject(sqlProjPath, false);
|
|
(project.isCrossPlatformCompatible).should.be.false('SSDT project should not be cross-platform compatible when not prompted to update');
|
|
|
|
// validate rejection result
|
|
project = await Project.openProject(sqlProjPath, true);
|
|
(project.isCrossPlatformCompatible).should.be.false('SSDT project should not be cross-platform compatible when update prompt is rejected');
|
|
(await exists(sqlProjPath + '_backup')).should.be.false('backup file should not be generated');
|
|
|
|
const newSqlProjContents = (await fs.readFile(sqlProjPath)).toString();
|
|
newSqlProjContents.should.equal(originalSqlProjContents, 'SSDT .sqlproj contents should not have changed when update prompt is rejected')
|
|
|
|
sinon.restore();
|
|
});
|
|
|
|
it('Should not show warning message for non-SSDT projects that have the additional information for Build', async function (): Promise<void> {
|
|
// setup test files
|
|
const folderPath = await testUtils.generateTestFolderPath(this.test);
|
|
const sqlProjPath = await testUtils.createTestSqlProjFile(this.test, baselines.openProjectFileBaseline, folderPath);
|
|
await testUtils.createTestDataSources(this.test, baselines.openDataSourcesBaseline, folderPath);
|
|
|
|
await Project.openProject(Uri.file(sqlProjPath).fsPath); // no error thrown
|
|
});
|
|
|
|
it('Should not show update project warning message when opening sdk style project using Sdk node', async function (): Promise<void> {
|
|
await shouldNotShowUpdateWarning(this.test, baselines.newSdkStyleProjectSdkNodeBaseline);
|
|
});
|
|
|
|
it('Should not show update project warning message when opening sdk style project using Project node with Sdk attribute', async function (): Promise<void> {
|
|
await shouldNotShowUpdateWarning(this.test, baselines.newSdkStyleProjectSdkProjectAttributeBaseline);
|
|
});
|
|
|
|
it('Should not show update project warning message when opening sdk style project using Import node with Sdk attribute', async function (): Promise<void> {
|
|
await shouldNotShowUpdateWarning(this.test, baselines.newStyleProjectSdkImportAttributeBaseline);
|
|
});
|
|
|
|
async function shouldNotShowUpdateWarning(test: Mocha.Runnable | undefined, baselineFile: string): Promise<void> {
|
|
// setup test files
|
|
const folderPath = await testUtils.generateTestFolderPath(test);
|
|
const sqlProjPath = await testUtils.createTestSqlProjFile(test, baselineFile, folderPath);
|
|
const spy = sinon.spy(window, 'showWarningMessage');
|
|
|
|
const project = await Project.openProject(Uri.file(sqlProjPath).fsPath);
|
|
(project.isCrossPlatformCompatible).should.be.true('Project should be detected as cross-plat compatible');
|
|
(spy.notCalled).should.be.true('Prompt to update .sqlproj should not have been shown for cross-plat project.');
|
|
}
|
|
});
|
|
|
|
async function testUpdateInRoundTrip(test: Mocha.Runnable | undefined, fileBeforeupdate: string): Promise<void> {
|
|
const projFilePath = await testUtils.createTestSqlProjFile(test, fileBeforeupdate);
|
|
const project = await Project.openProject(projFilePath); // project gets updated if needed in openProject()
|
|
should(project.isCrossPlatformCompatible).be.false('Project should not be cross-plat compatible before conversion');
|
|
|
|
project.isCrossPlatformCompatible.should.be.false('Project should not be cross-plat compatible before conversion');
|
|
|
|
await project.updateProjectForCrossPlatform();
|
|
|
|
(project.isCrossPlatformCompatible).should.be.true('Project should be cross-plat compatible after conversion');
|
|
(await exists(projFilePath + '_backup')).should.be.true('Backup file should have been generated before the project was updated');
|
|
|
|
sinon.restore();
|
|
}
|