diff --git a/Rubberduck.Core/UI/CodeExplorer/Commands/DeleteCommand.cs b/Rubberduck.Core/UI/CodeExplorer/Commands/DeleteCommand.cs index 09934cd5ef..bb89cd144b 100644 --- a/Rubberduck.Core/UI/CodeExplorer/Commands/DeleteCommand.cs +++ b/Rubberduck.Core/UI/CodeExplorer/Commands/DeleteCommand.cs @@ -13,14 +13,14 @@ namespace Rubberduck.UI.CodeExplorer.Commands public class DeleteCommand : CodeExplorerCommandBase { private readonly RemoveCommand _removeCommand; - private readonly IProjectsRepository _projectsRepository; + private readonly IProjectsProvider _projectsProvider; private readonly IMessageBox _messageBox; private readonly IVBE _vbe; - public DeleteCommand(RemoveCommand removeCommand, IProjectsRepository projectsRepository, IMessageBox messageBox, IVBE vbe) + public DeleteCommand(RemoveCommand removeCommand, IProjectsProvider projectsProvider, IMessageBox messageBox, IVBE vbe) { _removeCommand = removeCommand; - _projectsRepository = projectsRepository; + _projectsProvider = projectsProvider; _messageBox = messageBox; _vbe = vbe; @@ -41,7 +41,7 @@ protected override void OnExecute(object parameter) } var qualifiedModuleName = node.Declaration.QualifiedName.QualifiedModuleName; - var component = _projectsRepository.Component(qualifiedModuleName); + var component = _projectsProvider.Component(qualifiedModuleName); if (component is null) { return; diff --git a/Rubberduck.VBEEditor/ComManagement/IProjectsProvider.cs b/Rubberduck.VBEEditor/ComManagement/IProjectsProvider.cs index c1695b61b8..5addf15031 100644 --- a/Rubberduck.VBEEditor/ComManagement/IProjectsProvider.cs +++ b/Rubberduck.VBEEditor/ComManagement/IProjectsProvider.cs @@ -14,6 +14,5 @@ public interface IProjectsProvider : IDisposable IEnumerable<(QualifiedModuleName QualifiedModuleName, IVBComponent Component)> Components(); IEnumerable<(QualifiedModuleName QualifiedModuleName, IVBComponent Component)> Components(string projectId); IVBComponent Component(QualifiedModuleName qualifiedModuleName); - void RemoveComponent(QualifiedModuleName qualifiedModuleName); } } diff --git a/Rubberduck.VBEEditor/ComManagement/IProjectsRepository.cs b/Rubberduck.VBEEditor/ComManagement/IProjectsRepository.cs index 8356fe9c37..86f5927f94 100644 --- a/Rubberduck.VBEEditor/ComManagement/IProjectsRepository.cs +++ b/Rubberduck.VBEEditor/ComManagement/IProjectsRepository.cs @@ -4,5 +4,6 @@ public interface IProjectsRepository : IProjectsProvider { void Refresh(); void Refresh(string projectId); + void RemoveComponent(QualifiedModuleName qualifiedModuleName); } } diff --git a/Rubberduck.VBEEditor/ComManagement/ProjectsRepository.cs b/Rubberduck.VBEEditor/ComManagement/ProjectsRepository.cs index ce74f3049d..951a1fd9d2 100644 --- a/Rubberduck.VBEEditor/ComManagement/ProjectsRepository.cs +++ b/Rubberduck.VBEEditor/ComManagement/ProjectsRepository.cs @@ -223,7 +223,7 @@ public IEnumerable<(string ProjectId, IVBProject Project)> LockedProjects() var readLockTaken = false; try { - _refreshProtectionLock.EnterUpgradeableReadLock(); + _refreshProtectionLock.EnterReadLock(); readLockTaken = true; return function.Invoke(); } @@ -231,7 +231,7 @@ public IEnumerable<(string ProjectId, IVBProject Project)> LockedProjects() { if (readLockTaken) { - _refreshProtectionLock.ExitUpgradeableReadLock(); + _refreshProtectionLock.ExitReadLock(); } } } @@ -276,25 +276,16 @@ public IVBComponent Component(QualifiedModuleName qualifiedModuleName) public void RemoveComponent(QualifiedModuleName qualifiedModuleName) { - EvaluateWithinReadLock(() => + ExecuteWithinWriteLock(() => { - if (_components.TryGetValue(qualifiedModuleName, out var component)) + if (!_components.TryGetValue(qualifiedModuleName, out var component) || + !_componentsCollections.TryGetValue(qualifiedModuleName.ProjectId, out var components)) { - ExecuteWithinWriteLock(() => - { - if (_projects.TryGetValue(qualifiedModuleName.ProjectId, out var project)) - { - using (var components = project.VBComponents) - { - // Remove the actual component... - components.Remove(component); - } - } - // ...and our cached copy of it - _components.Remove(qualifiedModuleName); - }); + return; } - return new { }; + + _components.Remove(qualifiedModuleName); + components.Remove(component); }); } diff --git a/RubberduckTests/CodeExplorer/CodeExplorerViewModelTests.cs b/RubberduckTests/CodeExplorer/CodeExplorerViewModelTests.cs index e320bff509..1c444adc7c 100644 --- a/RubberduckTests/CodeExplorer/CodeExplorerViewModelTests.cs +++ b/RubberduckTests/CodeExplorer/CodeExplorerViewModelTests.cs @@ -467,7 +467,7 @@ public void RemoveCommand_RemovesModuleWhenPromptOk() var component = explorer.VbComponent.Object; explorer.ViewModel.RemoveCommand.Execute(removing); - explorer.VbComponents.Verify(c => c.Remove(component), Times.Once); + explorer.ProjectsRepository.Verify(c => c.RemoveComponent(component.QualifiedModuleName), Times.Once); } } @@ -503,8 +503,9 @@ public void RemoveCommand_GivenMsgBoxNo_RemovesModuleNoExport() var removing = explorer.ViewModel.SelectedItem; var component = explorer.VbComponent.Object; + explorer.ViewModel.RemoveCommand.Execute(removing); - explorer.VbComponents.Verify(c => c.Remove(component), Times.Once); + explorer.ProjectsRepository.Verify(c => c.RemoveComponent(component.QualifiedModuleName), Times.Once); } } diff --git a/RubberduckTests/CodeExplorer/MockedCodeExplorer.cs b/RubberduckTests/CodeExplorer/MockedCodeExplorer.cs index 61f7582efb..ef0848b8bd 100644 --- a/RubberduckTests/CodeExplorer/MockedCodeExplorer.cs +++ b/RubberduckTests/CodeExplorer/MockedCodeExplorer.cs @@ -24,6 +24,8 @@ using Rubberduck.UnitTesting; using Rubberduck.UnitTesting.CodeGeneration; using Rubberduck.UnitTesting.Settings; +using Rubberduck.VBEditor; +using Rubberduck.VBEditor.ComManagement; using Rubberduck.VBEditor.SourceCodeHandling; using Rubberduck.VBEditor.Utility; using RubberduckTests.Settings; @@ -87,6 +89,10 @@ public MockedCodeExplorer(ProjectType projectType, ComponentType componentType = VbProject = project.Build(); Vbe = builder.AddProject(VbProject).Build(); + ProjectsRepository = new Mock(); + ProjectsRepository.Setup(x => x.Project(It.IsAny())).Returns(VbProject.Object); + ProjectsRepository.Setup(x => x.Component(It.IsAny())).Returns(VbComponent.Object); + SetupViewModelAndParse(); } @@ -120,6 +126,10 @@ public MockedCodeExplorer(ProjectType projectType, ComponentType componentType = VbProject = project.Build(); Vbe = builder.AddProject(VbProject).Build(); + ProjectsRepository = new Mock(); + ProjectsRepository.Setup(x => x.Project(It.IsAny())).Returns(VbProject.Object); + ProjectsRepository.Setup(x => x.Component(It.IsAny())).Returns(VbComponent.Object); + SetupViewModelAndParse(); VbProject.SetupGet(m => m.VBComponents.Count).Returns(componentTypes.Count); @@ -130,7 +140,8 @@ private void SetupViewModelAndParse() var parser = MockParser.Create(Vbe.Object, null, MockVbeEvents.CreateMockVbeEvents(Vbe)); State = parser.State; - var removeCommand = new RemoveCommand(BrowserFactory.Object, MessageBox.Object, State.ProjectsProvider); + var exportCommand = new ExportCommand(BrowserFactory.Object, MessageBox.Object, State.ProjectsProvider, Vbe.Object); + var removeCommand = new RemoveCommand(exportCommand, ProjectsRepository.Object, MessageBox.Object, Vbe.Object); ViewModel = new CodeExplorerViewModel(State, removeCommand, _generalSettingsProvider.Object, @@ -157,6 +168,7 @@ private void SetupViewModelAndParse() public Mock OpenDialog { get; } public Mock FolderBrowser { get; } public Mock MessageBox { get; } = new Mock(); + public Mock ProjectsRepository { get; } public WindowSettings WindowSettings { get; } = new WindowSettings(); @@ -354,7 +366,7 @@ public void ExecuteExportCommand() public MockedCodeExplorer ImplementExportCommand() { - ViewModel.ExportCommand = new ExportCommand(BrowserFactory.Object, MessageBox.Object, State.ProjectsProvider); + ViewModel.ExportCommand = new ExportCommand(BrowserFactory.Object, MessageBox.Object, State.ProjectsProvider, Vbe.Object); return this; }