public async Task TryLoadSqlProjectPropertiesAsync_UseNameIfSqlTargetNameIsEmpty_Async() { // Arrange const string xml = @"<?xml version=""1.0"" encoding=""utf-8""?> <Project> <PropertyGroup> <Name>TestProject</Name> <OutputPath>bin\Output</OutputPath> <DacVersion>2.2.3</DacVersion> <SqlTargetName></SqlTargetName> </PropertyGroup> </Project>"; var project = new SqlProject("a", @"C:\TestProject\TestProject.sqlproj", "c"); var vsMock = Mock.Of <IVersionService>(); var fsaMock = new Mock <IFileSystemAccess>(); fsaMock.Setup(m => m.ReadFileAsync(project.FullName)) .ReturnsAsync(xml); var loggerMock = new Mock <ILogger>(); ISqlProjectService service = new SqlProjectService(vsMock, fsaMock.Object, loggerMock.Object); // Act var loadedSuccessfully = await service.TryLoadSqlProjectPropertiesAsync(project); // Assert Assert.IsTrue(loadedSuccessfully); loggerMock.Verify(m => m.LogErrorAsync(It.IsAny <string>()), Times.Never); loggerMock.Verify(m => m.LogErrorAsync(It.IsAny <Exception>(), It.IsAny <string>()), Times.Never); Assert.AreEqual("TestProject", project.ProjectProperties.SqlTargetName); Assert.AreEqual(@"C:\TestProject\bin\Output", project.ProjectProperties.BinaryDirectory); Assert.AreEqual(new Version(2, 2, 3), project.ProjectProperties.DacVersion); }
public void GetExistingArtifactVersions_ShowError_ExceptionDuringFileSystemAccess() { // Arrange var project = new SqlProject("a", @"C:\TestProject\TestProject.sqlproj", "c"); var config = new ConfigurationModel { ArtifactsPath = "_Deployment", PublishProfilePath = "TestProfile.publish.xml", ReplaceUnnamedDefaultConstraintDrops = false, VersionPattern = "1.2.3.4", CommentOutUnnamedDefaultConstraintDrops = true, CreateDocumentationWithScriptCreation = false, CustomHeader = "TestHeader", CustomFooter = "TestFooter", BuildBeforeScriptCreation = true, TrackDacpacVersion = true }; var vsaMock = new Mock <IVisualStudioAccess>(); var fsaMock = new Mock <IFileSystemAccess>(); fsaMock.Setup(m => m.GetDirectoriesIn(@"C:\TestProject\_Deployment")) .Throws(new InvalidOperationException("test exception")); IArtifactsService service = new ArtifactsService(vsaMock.Object, fsaMock.Object); // Act var result = service.GetExistingArtifactVersions(project, config); // Assert Assert.IsNotNull(result); Assert.AreEqual(0, result.Length); vsaMock.Verify(m => m.ShowModalError("ERROR: Failed to open script creation window: test exception"), Times.Once); }
public void GetExistingArtifactVersions_ShowError_InvalidArtifactsPathConfiguration() { // Arrange var project = new SqlProject("a", @"C:\TestProject\TestProject.sqlproj", "c"); var config = new ConfigurationModel { ArtifactsPath = "", PublishProfilePath = "TestProfile.publish.xml", ReplaceUnnamedDefaultConstraintDrops = false, VersionPattern = "1.2.3.4", CommentOutUnnamedDefaultConstraintDrops = true, CreateDocumentationWithScriptCreation = false, CustomHeader = "TestHeader", CustomFooter = "TestFooter", BuildBeforeScriptCreation = true, TrackDacpacVersion = true }; var vsaMock = new Mock <IVisualStudioAccess>(); var fsaMock = new Mock <IFileSystemAccess>(); IArtifactsService service = new ArtifactsService(vsaMock.Object, fsaMock.Object); // Act var result = service.GetExistingArtifactVersions(project, config); // Assert Assert.IsNotNull(result); Assert.AreEqual(0, result.Length); vsaMock.Verify(m => m.ShowModalError("ERROR: The configured artifacts path is not valid. Please ensure that the configuration is correct."), Times.Once); }
public async Task Work_ScriptCreationStateModel_CompleteRun_Async() { // Arrange var fsaMock = new Mock <IFileSystemAccess>(); var loggerMock = new Mock <ILogger>(); IWorkUnit <ScriptCreationStateModel> unit = new CleanNewArtifactsDirectoryUnit(fsaMock.Object, loggerMock.Object); var project = new SqlProject("a", "b", "c"); var configuration = ConfigurationModel.GetDefault(); var previousVersion = new Version(1, 0); Task HandlerFunc(bool b) => Task.CompletedTask; var directories = new DirectoryPaths("projectDirectory", "latestArtifactsDirectory", "newArtifactsDirectory"); var sourcePaths = new DeploySourcePaths("newDacpacPath", "publishProfilePath", "previousDacpacPath"); var targetPaths = new DeployTargetPaths("deployScriptPath", "deployReportPath"); var paths = new PathCollection(directories, sourcePaths, targetPaths); var model = new ScriptCreationStateModel(project, configuration, previousVersion, true, HandlerFunc) { Paths = paths }; // Act await unit.Work(model, CancellationToken.None); // Assert Assert.AreEqual(StateModelState.TriedToCleanArtifactsDirectory, model.CurrentState); Assert.IsNull(model.Result); fsaMock.Verify(m => m.TryToCleanDirectory("newArtifactsDirectory"), Times.Once); loggerMock.Verify(m => m.LogInfoAsync(It.IsNotNull <string>()), Times.Once); }
public async Task Work_ScriptCreationStateModel_ValidVersion_Latest_Async() { // Arrange var project = new SqlProject("a", "b", "c"); var configuration = ConfigurationModel.GetDefault(); var previousVersion = new Version(1, 2, 3); Task HandleWorkInProgressChanged(bool arg) => Task.CompletedTask; var model = new ScriptCreationStateModel(project, configuration, previousVersion, true, HandleWorkInProgressChanged) { FormattedTargetVersion = null }; var vsaMock = new Mock <IVisualStudioAccess>(); var loggerMock = new Mock <ILogger>(); IWorkUnit <ScriptCreationStateModel> unit = new ValidateTargetVersionUnit(vsaMock.Object, loggerMock.Object); // Act await unit.Work(model, CancellationToken.None); // Assert Assert.AreEqual(StateModelState.FormattedTargetVersionValidated, model.CurrentState); Assert.IsNull(model.Result); vsaMock.Verify(m => m.ShowModalError(It.IsAny <string>()), Times.Never); loggerMock.Verify(m => m.LogErrorAsync(It.IsAny <string>()), Times.Never); }
public async Task SaveConfiguration_SavedWithChangeNotification_Async() { // Arrange var fsaMock = new Mock <IFileSystemAccess>(); fsaMock.Setup(m => m.WriteFileAsync(It.IsNotNull <string>(), It.IsNotNull <string>())) .Returns(Task.CompletedTask); var vsaMock = new Mock <IVisualStudioAccess>(); SqlProject configurationChangedProject = null; var loggerMock = Mock.Of <ILogger>(); IConfigurationService service = new ConfigurationService(fsaMock.Object, vsaMock.Object, loggerMock); service.ConfigurationChanged += (sender, args) => configurationChangedProject = args.Project; var project = new SqlProject("", "C:\\Temp\\Test\\Test.sqlproj", ""); var model = ConfigurationModel.GetDefault(); // Act var result = await service.SaveConfigurationAsync(project, model); // Assert Assert.IsTrue(result); fsaMock.Verify(m => m.WriteFileAsync("C:\\Temp\\Test\\Properties\\ssdtlifecycle.json", It.IsNotNull <string>()), Times.Once); Assert.AreSame(project, configurationChangedProject); vsaMock.Verify(m => m.AddItemToProjectProperties(project, "C:\\Temp\\Test\\Properties\\ssdtlifecycle.json"), Times.Once); }
public async Task ScaffoldAsync_InvalidOperationException_CallCreateWhileRunning_Async() { // Arrange var wufMock = Mock.Of <IWorkUnitFactory>(); var vsaMock = Mock.Of <IVisualStudioAccess>(); var loggerMock = Mock.Of <ILogger>(); IScaffoldingService service = new ScaffoldingService(wufMock, vsaMock, loggerMock); var project = new SqlProject("a", "b", "c"); var configuration = ConfigurationModel.GetDefault(); var targetVersion = new Version(1, 0); var invokedSecondTime = false; Exception thrownException = null; service.IsScaffoldingChanged += (sender, args) => { if (!service.IsScaffolding) { return; } invokedSecondTime = true; thrownException = Assert.Throws <InvalidOperationException>(() => service.ScaffoldAsync(project, configuration, targetVersion, CancellationToken.None)); }; // Act await service.ScaffoldAsync(project, configuration, targetVersion, CancellationToken.None); // Assert Assert.IsTrue(invokedSecondTime); Assert.IsNotNull(thrownException); Assert.IsInstanceOf <InvalidOperationException>(thrownException); }
public async Task Work_ScaffoldingStateModel_LoadedSuccessful_Async() { // Arrange var project = new SqlProject("a", "b", "c"); var configuration = ConfigurationModel.GetDefault(); var targetVersion = new Version(1, 2, 3); Task HandleWorkInProgressChanged(bool arg) => Task.CompletedTask; var model = new ScaffoldingStateModel(project, configuration, targetVersion, HandleWorkInProgressChanged); var directories = new DirectoryPaths("projectDirectory", "latestArtifactsDirectory", "newArtifactsDirectory"); var sourcePaths = new DeploySourcePaths("newDacpacPath", "publishProfilePath", "previousDacpacPath"); var targetPaths = new DeployTargetPaths("deployScriptPath", "deployReportPath"); var paths = new PathCollection(directories, sourcePaths, targetPaths); var spsMock = new Mock <ISqlProjectService>(); spsMock.Setup(m => m.TryLoadPathsForScaffoldingAsync(project, configuration)).ReturnsAsync(paths); IWorkUnit <ScaffoldingStateModel> unit = new LoadPathsUnit(spsMock.Object); // Act await unit.Work(model, CancellationToken.None); // Assert Assert.AreEqual(StateModelState.PathsLoaded, model.CurrentState); Assert.IsNull(model.Result); }
private bool TryGetArtifactsBaseDirectory(SqlProject project, ConfigurationModel configuration, out string artifactsBaseDirectory) { var projectPath = project.FullName; var projectDirectory = Path.GetDirectoryName(projectPath); if (projectDirectory == null) { _visualStudioAccess.ShowModalError("ERROR: Cannot determine project directory."); artifactsBaseDirectory = null; return(false); } var artifactPathErrors = ConfigurationModelValidations.ValidateArtifactsPath(configuration); if (artifactPathErrors.Any()) { _visualStudioAccess.ShowModalError("ERROR: The configured artifacts path is not valid. Please ensure that the configuration is correct."); artifactsBaseDirectory = null; return(false); } artifactsBaseDirectory = Path.Combine(projectDirectory, configuration.ArtifactsPath); return(true); }
public async Task Modify_ReplaceSpecialKeyword_PreviousVersion_Async() { // Arrange IScriptModifier s = new AddCustomHeaderModifier(); const string input = "foobar"; var project = new SqlProject("a", "b", "c"); project.ProjectProperties.DacVersion = new Version(1, 3, 0); var configuration = new ConfigurationModel { CustomHeader = "Script base version: {PREVIOUS_VERSION}" }; var directories = new DirectoryPaths("projectDirectory", "latestArtifactsDirectory", "newArtifactsDirectory"); var sourcePaths = new DeploySourcePaths("newDacpacPath", "publishProfilePath", "previousDacpacPath"); var targetPaths = new DeployTargetPaths("deployScriptPath", "deployReportPath"); var paths = new PathCollection(directories, sourcePaths, targetPaths); var model = new ScriptModificationModel(input, project, configuration, paths, new Version(1, 2, 0), false); // Act await s.ModifyAsync(model); // Assert Assert.IsNotNull(model.CurrentScript); Assert.AreEqual("Script base version: 1.2.0\r\nfoobar", model.CurrentScript); }
public void Modify(SqlProject project) { foreach (var modifier in _modifiers) { modifier.Modify(project); } }
void IVisualStudioAccess.RemoveItemFromProjectRoot(SqlProject project, string item) { if (project == null) { throw new ArgumentNullException(nameof(project)); } if (item == null) { throw new ArgumentNullException(nameof(item)); } ThreadHelper.ThrowIfNotOnUIThread(); var p = _dte2.Solution.Projects.OfType <Project>().SingleOrDefault(m => { ThreadHelper.ThrowIfNotOnUIThread(); return(m.UniqueName == project.UniqueName); }); var matchingItem = p?.ProjectItems.OfType <ProjectItem>().SingleOrDefault(m => { ThreadHelper.ThrowIfNotOnUIThread(); return(m.Name == item); }); matchingItem?.Remove(); }
public async Task TryLoadSqlProjectPropertiesAsync_Error_NoXmlRoot_Async() { // Arrange const string xml = @"<?xml version=""1.0"" encoding=""utf-8""?>"; var project = new SqlProject("a", @"C:\TestProject.sqlproj", "c"); var vsMock = Mock.Of <IVersionService>(); var fsaMock = new Mock <IFileSystemAccess>(); fsaMock.Setup(m => m.ReadFileAsync(project.FullName)) .ReturnsAsync(xml); var loggedErrorMessages = new List <(Exception Exception, string Message)>(); var loggerMock = new Mock <ILogger>(); loggerMock.Setup(m => m.LogErrorAsync(It.IsAny <Exception>(), It.IsAny <string>())) .Callback((Exception e, string message) => loggedErrorMessages.Add((e, message))) .Returns(Task.CompletedTask); ISqlProjectService service = new SqlProjectService(vsMock, fsaMock.Object, loggerMock.Object); // Act var loadedSuccessfully = await service.TryLoadSqlProjectPropertiesAsync(project); // Assert Assert.IsFalse(loadedSuccessfully); Assert.AreEqual(1, loggedErrorMessages.Count); Assert.IsNotNull(loggedErrorMessages[0]); Assert.IsNotNull(loggedErrorMessages[0].Exception); Assert.IsTrue(loggedErrorMessages[0].Message.StartsWith(@"Cannot read contents of ""C:\TestProject.sqlproj""")); }
public async Task TryLoadSqlProjectPropertiesAsync_IssueWarningIfNameNodeIsDifferentFromProjectName_Async() { // Arrange const string xml = @"<?xml version=""1.0"" encoding=""utf-8""?> <Project> <PropertyGroup> <Name>TestProject</Name> <OutputPath>bin\Output</OutputPath> <DacVersion>2.2.3</DacVersion> </PropertyGroup> </Project>"; var project = new SqlProject("awesomeproject", @"C:\TestProject\TestProject.sqlproj", "c"); var vsMock = Mock.Of <IVersionService>(); var fsaMock = new Mock <IFileSystemAccess>(); fsaMock.Setup(m => m.ReadFileAsync(project.FullName)) .ReturnsAsync(xml); var loggerMock = new Mock <ILogger>(); ISqlProjectService service = new SqlProjectService(vsMock, fsaMock.Object, loggerMock.Object); // Act var loadedSuccessfully = await service.TryLoadSqlProjectPropertiesAsync(project); // Assert Assert.IsTrue(loadedSuccessfully); loggerMock.Verify(m => m.LogErrorAsync(It.IsAny <string>()), Times.Never); loggerMock.Verify(m => m.LogErrorAsync(It.IsAny <Exception>(), It.IsAny <string>()), Times.Never); Assert.AreEqual("TestProject", project.ProjectProperties.SqlTargetName); Assert.AreEqual(@"C:\TestProject\bin\Output", project.ProjectProperties.BinaryDirectory); Assert.AreEqual(new Version(2, 2, 3), project.ProjectProperties.DacVersion); loggerMock.Verify(m => m.LogWarningAsync("XML node 'Name' doesn't match the actual project name. This could cause an unexpected behavior."), Times.Once); loggerMock.Verify(m => m.LogDebugAsync("Value of 'Name' node: TestProject"), Times.Once); loggerMock.Verify(m => m.LogDebugAsync("Actual project name: awesomeproject"), Times.Once); }
public async Task GetConfigurationOrDefaultAsync_SqlProject_ErrorWhileReading_UseDefault_Async() { // Arrange var exception = new FileNotFoundException("foo"); var fsaMock = new Mock <IFileSystemAccess>(); fsaMock.Setup(m => m.CheckIfFileExists("C:\\Temp\\Test\\Properties\\ssdtlifecycle.json")) .Returns(true); fsaMock.Setup(m => m.ReadFileAsync("C:\\Temp\\Test\\Properties\\ssdtlifecycle.json")) .Throws(exception); var vsaMock = new Mock <IVisualStudioAccess>(); var loggerMock = new Mock <ILogger>(); IConfigurationService service = new ConfigurationService(fsaMock.Object, vsaMock.Object, loggerMock.Object); var project = new SqlProject("", "C:\\Temp\\Test\\Test.sqlproj", ""); var defaultConfiguration = ConfigurationModel.GetDefault(); // Act var configuration = await service.GetConfigurationOrDefaultAsync(project); // Assert Assert.IsNotNull(configuration); vsaMock.Verify(m => m.ShowModalError(It.Is <string>(s => s.Contains("Accessing the configuration file failed."))), Times.Once); loggerMock.Verify(m => m.LogErrorAsync(exception, It.Is <string>(s => s.Contains("Failed to read the configuration from file"))), Times.Once); Assert.IsTrue(defaultConfiguration.Equals(configuration)); }
public async Task Work_ScriptCreationStateModel_NoRepositoryConfigured_Async() { // Arrange var project = new SqlProject("a", "b", "c"); var configuration = ConfigurationModel.GetDefault(); var previousVersion = new Version(1, 2, 3); Task HandleWorkInProgressChanged(bool arg) => Task.CompletedTask; var directories = new DirectoryPaths("projectDirectory", "latestArtifactsDirectory", "newArtifactsDirectory"); var sourcePaths = new DeploySourcePaths("newDacpacPath", "publishProfilePath", "previousDacpacPath"); var targetPaths = new DeployTargetPaths("deployScriptPath", "deployReportPath"); var paths = new PathCollection(directories, sourcePaths, targetPaths); var model = new ScriptCreationStateModel(project, configuration, previousVersion, true, HandleWorkInProgressChanged) { Paths = paths }; var fsaMock = new Mock <IFileSystemAccess>(); var loggerMock = new Mock <ILogger>(); IWorkUnit <ScriptCreationStateModel> unit = new CopyDacpacToSharedDacpacRepositoryUnit(fsaMock.Object, loggerMock.Object); // Act await unit.Work(model, CancellationToken.None); // Assert Assert.AreEqual(StateModelState.TriedToCopyDacpacToSharedDacpacRepository, model.CurrentState); Assert.IsNull(model.Result); fsaMock.Verify(m => m.EnsureDirectoryExists(It.IsAny <string>()), Times.Never); fsaMock.Verify(m => m.CopyFile(It.IsAny <string>(), It.IsAny <string>()), Times.Never); loggerMock.Verify(m => m.LogErrorAsync(It.IsAny <string>()), Times.Never); loggerMock.Verify(m => m.LogErrorAsync(It.IsAny <Exception>(), It.IsAny <string>()), Times.Never); }
public async Task SaveConfiguration_FileSystemAccessError_Async() { // Arrange var exception = new IOException("foo"); var fsaMock = new Mock <IFileSystemAccess>(); fsaMock.Setup(m => m.WriteFileAsync(It.IsNotNull <string>(), It.IsNotNull <string>())) .Throws(exception); var vsaMock = new Mock <IVisualStudioAccess>(); SqlProject configurationChangedProject = null; var loggerMock = new Mock <ILogger>(); IConfigurationService service = new ConfigurationService(fsaMock.Object, vsaMock.Object, loggerMock.Object); service.ConfigurationChanged += (sender, args) => configurationChangedProject = args.Project; var project = new SqlProject("", "C:\\Temp\\Test\\Test.sqlproj", ""); var model = ConfigurationModel.GetDefault(); // Act var result = await service.SaveConfigurationAsync(project, model); // Assert Assert.IsFalse(result); fsaMock.Verify(m => m.WriteFileAsync("C:\\Temp\\Test\\Properties\\ssdtlifecycle.json", It.IsNotNull <string>()), Times.Once); Assert.IsNull(configurationChangedProject); vsaMock.Verify(m => m.AddItemToProjectProperties(It.IsAny <SqlProject>(), It.IsAny <string>()), Times.Never); loggerMock.Verify(m => m.LogErrorAsync(exception, "Failed to save the configuration"), Times.Once); vsaMock.Verify(m => m.ShowModalError("Failed to save the configuration. Please check the SSDT Lifecycle output window for details."), Times.Once); }
public async Task Work_ScaffoldingStateModel_InvalidCharsInNewDacpacPath_Async() { // Arrange var project = new SqlProject("a", "b", "c"); var configuration = ConfigurationModel.GetDefault(); configuration.SharedDacpacRepositoryPath = "C:\\Temp\\Test\\"; var targetVersion = new Version(1, 2, 3); Task HandleWorkInProgressChanged(bool arg) => Task.CompletedTask; var directories = new DirectoryPaths("projectDirectory", "latestArtifactsDirectory", "newArtifactsDirectory"); var sourcePaths = new DeploySourcePaths("newDacpacPath" + new string(Path.GetInvalidPathChars()), "publishProfilePath", "previousDacpacPath"); var targetPaths = new DeployTargetPaths("deployScriptPath", "deployReportPath"); var paths = new PathCollection(directories, sourcePaths, targetPaths); var model = new ScaffoldingStateModel(project, configuration, targetVersion, HandleWorkInProgressChanged) { Paths = paths }; var fsaMock = new Mock <IFileSystemAccess>(); var loggerMock = new Mock <ILogger>(); IWorkUnit <ScaffoldingStateModel> unit = new CopyDacpacToSharedDacpacRepositoryUnit(fsaMock.Object, loggerMock.Object); // Act await unit.Work(model, CancellationToken.None); // Assert Assert.AreEqual(StateModelState.TriedToCopyDacpacToSharedDacpacRepository, model.CurrentState); Assert.IsFalse(model.Result); fsaMock.Verify(m => m.EnsureDirectoryExists(It.IsAny <string>()), Times.Never); fsaMock.Verify(m => m.CopyFile(It.IsAny <string>(), It.IsAny <string>()), Times.Never); loggerMock.Verify(m => m.LogInfoAsync("Copying DACPAC to shared DACPAC repository ..."), Times.Once); loggerMock.Verify(m => m.LogErrorAsync(It.Is <string>(s => s.StartsWith("Failed to copy DACPAC to shared DACPAC repository: "))), Times.Once); }
public void Modify(SqlProject project) { foreach (var batch in project.Objects.Batches.ToList()) { foreach (var statement in batch.Statements.OfType <CreateTableStatement>()) { var constrains = statement.Definition.TableConstraints; if (constrains.Count == 0) { continue; } var alterTable = new AlterTableAddTableElementStatement { SchemaObjectName = statement.SchemaObjectName, Definition = new TableDefinition() }; foreach (var constraint in constrains) { alterTable.Definition.TableConstraints.Add(constraint); } project.Objects.Batches.Add(new TSqlBatch { Statements = { alterTable } }); statement.Definition.TableConstraints.Clear(); } } }
private async Task TryToDeleteRefactorLogInternal(IStateModel stateModel, SqlProject project, ConfigurationModel configuration, PathCollection paths) { if (!configuration.DeleteRefactorlogAfterVersionedScriptGeneration) { stateModel.CurrentState = StateModelState.DeletedRefactorLog; return; } await _logger.LogInfoAsync("Deleting refactorlog files ..."); var deletedFiles = _fileSystemAccess.TryToCleanDirectory(paths.Directories.ProjectDirectory, "*.refactorlog"); if (deletedFiles.Length == 0) { await _logger.LogTraceAsync("No files were deleted."); } else { foreach (var deletedFile in deletedFiles) { _visualStudioAccess.RemoveItemFromProjectRoot(project, deletedFile); await _logger.LogTraceAsync($"Deleted file {deletedFile} ..."); } } stateModel.CurrentState = StateModelState.DeletedRefactorLog; }
public async Task ScaffoldAsync_CompleteRun_ExceptionInStopLongRunningTask_Async() { // Arrange var wufMock = Mock.Of <IWorkUnitFactory>(); var vsaMock = new Mock <IVisualStudioAccess>(); vsaMock.Setup(m => m.StopLongRunningTaskIndicatorAsync()) .ThrowsAsync(new Exception("test exception")); var loggerMock = Mock.Of <ILogger>(); IScaffoldingService service = new ScaffoldingService(wufMock, vsaMock.Object, loggerMock); var project = new SqlProject("a", "b", "c"); var configuration = ConfigurationModel.GetDefault(); var targetVersion = new Version(1, 0); var isCreatingList = new List <bool>(); service.IsScaffoldingChanged += (sender, args) => { isCreatingList.Add(service.IsScaffolding); }; // Act var result = await service.ScaffoldAsync(project, configuration, targetVersion, CancellationToken.None); // Assert Assert.IsTrue(result); Assert.AreEqual(2, isCreatingList.Count); Assert.IsTrue(isCreatingList[0]); Assert.IsFalse(isCreatingList[1]); vsaMock.Verify(m => m.StartLongRunningTaskIndicatorAsync(), Times.Once); vsaMock.Verify(m => m.ClearSSDTLifecycleOutputAsync(), Times.Once); vsaMock.Verify(m => m.StopLongRunningTaskIndicatorAsync(), Times.Once); }
public void GetViewModel_SameInstanceForSameProjects_DifferentSqlProjectInstancesWithSameUniqueName() { // Arrange var vsaMock = Mock.Of <IVisualStudioAccess>(); var loggerMock = Mock.Of <ILogger>(); var spMock = Mock.Of <IServiceProvider>(); var cs = new OleMenuCommandService(spMock); var p1 = new SqlProject("", "", "1"); var p2 = new SqlProject("", "", "1"); ViewModelTestImplementation vm1; ViewModelTestImplementation vm2; using (var dr = new DependencyResolver(vsaMock, loggerMock, cs)) // Act { vm1 = dr.GetViewModel <ViewModelTestImplementation>(p1); vm2 = dr.GetViewModel <ViewModelTestImplementation>(p2); } // Assert Assert.IsNotNull(vm1); Assert.IsNotNull(vm2); Assert.AreSame(vm1, vm2); Assert.AreSame(p1, vm1.Project); Assert.AreSame(p1, vm2.Project); }
private async Task <bool> SaveConfigurationInternalAsync(SqlProject project, ConfigurationModel model) { var targetPath = GetConfigurationPath(project); var serialized = JsonConvert.SerializeObject(model, Formatting.Indented); try { // Save configuration physically. await _fileSystemAccess.WriteFileAsync(targetPath, serialized); } catch (Exception e) { await _logger.LogErrorAsync(e, "Failed to save the configuration"); _visualStudioAccess.ShowModalError("Failed to save the configuration. Please check the SSDT Lifecycle output window for details."); return(false); } // Notify about changes ConfigurationChanged?.Invoke(this, new ProjectConfigurationChangedEventArgs(project)); // Add configuration to the project, if it hasn't been added before. _visualStudioAccess.AddItemToProjectProperties(project, targetPath); return(true); }
public async Task TryInitializeToolWindowAsync_ViewModelInitializationSucceeds_Async() { // Arrange var project = new SqlProject("a", "b", "c"); var vsaMock = new Mock <IVisualStudioAccess>(); vsaMock.Setup(m => m.GetSelectedSqlProject()).Returns(project); var loggerMock = Mock.Of <ILogger>(); var spMock = Mock.Of <IServiceProvider>(); var cs = new OleMenuCommandService(spMock); var dr = new DependencyResolver(vsaMock.Object, loggerMock, cs); var twi = new ToolWindowInitializer(vsaMock.Object, dr); var viewMock = new Mock <IView>(); var windowMock = new Mock <IVisualStudioToolWindow>(); windowMock.SetupGet(m => m.Content).Returns(viewMock.Object); // Act var(success, fullProjectPath) = await twi.TryInitializeToolWindowAsync <ViewModelBaseTestImplementationWithSuccessfulInitialization>(windowMock.Object); // Assert Assert.IsTrue(success); Assert.AreEqual("b", fullProjectPath); viewMock.Verify(m => m.SetDataContext(It.Is <IViewModel>(model => model != null && model.GetType() == typeof(ViewModelBaseTestImplementationWithSuccessfulInitialization)))); }
public async Task Work_ScaffoldingStateModel_InvalidVersion_Async(string dacVersionString) { // Arrange var dacVersion = Version.Parse(dacVersionString); var formattedTargetVersion = new Version(1, 2, 4); var project = new SqlProject("a", "b", "c"); project.ProjectProperties.DacVersion = dacVersion; var configuration = ConfigurationModel.GetDefault(); var targetVersion = new Version(1, 2, 3); Task HandleWorkInProgressChanged(bool arg) => Task.CompletedTask; var model = new ScaffoldingStateModel(project, configuration, targetVersion, HandleWorkInProgressChanged) { FormattedTargetVersion = formattedTargetVersion }; var vsaMock = new Mock <IVisualStudioAccess>(); var loggerMock = new Mock <ILogger>(); IWorkUnit <ScaffoldingStateModel> unit = new ValidateTargetVersionUnit(vsaMock.Object, loggerMock.Object); // Act await unit.Work(model, CancellationToken.None); // Assert Assert.AreEqual(StateModelState.FormattedTargetVersionValidated, model.CurrentState); Assert.IsFalse(model.Result); vsaMock.Verify(m => m.ShowModalError("Please change the DAC version in the SQL project settings (see output window)."), Times.Once); loggerMock.Verify(m => m.LogErrorAsync(It.IsAny <string>()), Times.Once); }
public async Task Work_ScaffoldingStateModel_CopyFailed_Async() { // Arrange var project = new SqlProject("a", "b", "c"); var configuration = ConfigurationModel.GetDefault(); var targetVersion = new Version(1, 2, 3); Task HandleWorkInProgressChanged(bool arg) => Task.CompletedTask; var directories = new DirectoryPaths("projectDirectory", "latestArtifactsDirectory", "newArtifactsDirectory"); var sourcePaths = new DeploySourcePaths("newDacpacPath", "publishProfilePath", "previousDacpacPath"); var targetPaths = new DeployTargetPaths("deployScriptPath", "deployReportPath"); var paths = new PathCollection(directories, sourcePaths, targetPaths); var model = new ScaffoldingStateModel(project, configuration, targetVersion, HandleWorkInProgressChanged) { Paths = paths }; var bsMock = new Mock <IBuildService>(); bsMock.Setup(m => m.CopyBuildResultAsync(project, paths.Directories.NewArtifactsDirectory)).ReturnsAsync(false); IWorkUnit <ScaffoldingStateModel> unit = new CopyBuildResultUnit(bsMock.Object); // Act await unit.Work(model, CancellationToken.None); // Assert Assert.AreEqual(StateModelState.TriedToCopyBuildResult, model.CurrentState); Assert.IsFalse(model.Result); }
public void GetExistingArtifactVersions_NoValidDirectories() { // Arrange var project = new SqlProject("a", @"C:\TestProject\TestProject.sqlproj", "c"); var config = new ConfigurationModel { ArtifactsPath = "_Deployment", PublishProfilePath = "TestProfile.publish.xml", ReplaceUnnamedDefaultConstraintDrops = false, VersionPattern = "1.2.3.4", CommentOutUnnamedDefaultConstraintDrops = true, CreateDocumentationWithScriptCreation = false, CustomHeader = "TestHeader", CustomFooter = "TestFooter", BuildBeforeScriptCreation = true, TrackDacpacVersion = true }; var vsaMock = new Mock <IVisualStudioAccess>(); var fsaMock = new Mock <IFileSystemAccess>(); fsaMock.Setup(m => m.GetDirectoriesIn(@"C:\TestProject\_Deployment")) .Returns(new [] { @"C:\TestProject\_Deployment\foo" }); IArtifactsService service = new ArtifactsService(vsaMock.Object, fsaMock.Object); // Act var result = service.GetExistingArtifactVersions(project, config); // Assert Assert.IsNotNull(result); Assert.AreEqual(0, result.Length); vsaMock.Verify(m => m.ShowModalError(It.IsAny <string>()), Times.Never); }
public async Task Work_ScriptCreationStateModel_NoModifiers_Async() { // Arrange var mpsMock = new Mock <IScriptModifierProviderService>(); var fsaMock = new Mock <IFileSystemAccess>(); var loggerMock = new Mock <ILogger>(); IWorkUnit <ScriptCreationStateModel> unit = new ModifyDeploymentScriptUnit(mpsMock.Object, fsaMock.Object, loggerMock.Object); var project = new SqlProject("a", "b", "c"); var configuration = ConfigurationModel.GetDefault(); var previousVersion = new Version(1, 0); Task HandlerFunc(bool b) => Task.CompletedTask; var model = new ScriptCreationStateModel(project, configuration, previousVersion, false, HandlerFunc); mpsMock.Setup(m => m.GetScriptModifiers(configuration)).Returns(new Dictionary <ScriptModifier, IScriptModifier>()); // Act await unit.Work(model, CancellationToken.None); // Assert Assert.AreEqual(StateModelState.ModifiedDeploymentScript, model.CurrentState); Assert.IsNull(model.Result); mpsMock.Verify(m => m.GetScriptModifiers(It.IsAny <ConfigurationModel>()), Times.Once); fsaMock.Verify(m => m.ReadFileAsync(It.IsAny <string>()), Times.Never); fsaMock.Verify(m => m.WriteFileAsync(It.IsAny <string>(), It.IsAny <string>()), Times.Never); loggerMock.Verify(m => m.LogInfoAsync(It.IsAny <string>()), Times.Never); }
internal TViewModel GetViewModel <TViewModel>([NotNull] SqlProject project) where TViewModel : IViewModel { if (_disposed) { throw new ObjectDisposedException(nameof(DependencyResolver)); } if (project == null) { throw new ArgumentNullException(nameof(project)); } // Check for an existing view model registered with the project. if (_viewModels.TryGetValue(typeof(TViewModel), out var instances) && instances.TryGetValue(project.UniqueName, out var instance) && instance is TViewModel existingViewModel) { return(existingViewModel); } // Create a new view model and register it with the project. var newViewModel = _container.Resolve <TViewModel>(new ParameterOverride("project", project)); if (!_viewModels.TryGetValue(typeof(TViewModel), out instances)) { instances = new Dictionary <string, object>(); _viewModels.Add(typeof(TViewModel), instances); } instances[project.UniqueName] = newViewModel; return(newViewModel); }
public async Task TryLoadSqlProjectPropertiesAsync_Error_NoOutputPath_Async() { // Arrange const string xml = @"<?xml version=""1.0"" encoding=""utf-8""?> <Project> <PropertyGroup> <Name>TestProject</Name> </PropertyGroup> </Project>"; var project = new SqlProject("a", @"C:\TestProject.sqlproj", "c"); var vsMock = Mock.Of <IVersionService>(); var fsaMock = new Mock <IFileSystemAccess>(); fsaMock.Setup(m => m.ReadFileAsync(project.FullName)) .ReturnsAsync(xml); var loggedErrorMessages = new List <string>(); var loggerMock = new Mock <ILogger>(); loggerMock.Setup(m => m.LogErrorAsync(It.IsAny <string>())) .Callback((string message) => loggedErrorMessages.Add(message)) .Returns(Task.CompletedTask); ISqlProjectService service = new SqlProjectService(vsMock, fsaMock.Object, loggerMock.Object); // Act var loadedSuccessfully = await service.TryLoadSqlProjectPropertiesAsync(project); // Assert Assert.IsFalse(loadedSuccessfully); Assert.AreEqual(1, loggedErrorMessages.Count); Assert.AreEqual(@"Cannot read output path of ""C:\TestProject.sqlproj"". " + "Please make sure that the \"OutputPath\" for the current configuration is set correctly, e.g. \"bin\\Output\\\". " + "This value can be set from your database project => \"Properties\" => \"Build\" => \"Output path\".", loggedErrorMessages[0]); }