Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SLVS-1563 Raise CurrentConfigurationScopeChanged when configuration scope changed #5783

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions src/SLCore.UnitTests/State/ActiveConfigScopeTrackerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

using System.ComponentModel;
using SonarLint.VisualStudio.Core;
using SonarLint.VisualStudio.Core.Synchronization;
using SonarLint.VisualStudio.SLCore.Core;
Expand All @@ -38,6 +39,7 @@ public class ActiveConfigScopeTrackerTests
private ISLCoreServiceProvider serviceProvider;
private IAsyncLockFactory asyncLockFactory;
private IThreadHandling threadHandling;
private EventHandler currentConfigScopeChangedEventHandler;

[TestInitialize]
public void TestInitialize()
Expand All @@ -50,8 +52,10 @@ public void TestInitialize()
threadHandling = Substitute.For<IThreadHandling>();
ConfigureServiceProvider(isServiceAvailable:true);
ConfigureAsyncLockFactory();
currentConfigScopeChangedEventHandler = Substitute.For<EventHandler>();

testSubject = new ActiveConfigScopeTracker(serviceProvider, asyncLockFactory, threadHandling);
testSubject.CurrentConfigurationScopeChanged += currentConfigScopeChangedEventHandler;
}

[TestMethod]
Expand Down Expand Up @@ -80,6 +84,7 @@ public void SetCurrentConfigScope_SetsUnboundScope()
VerifyThreadHandling();
VerifyServiceAddCall();
VerifyLockTakenSynchronouslyAndReleased();
VerifyCurrentConfigurationScopeChangedRaised();
}

[TestMethod]
Expand All @@ -95,6 +100,7 @@ public void TryUpdateRootOnCurrentConfigScope_ConfigScopeSame_Updates()

result.Should().BeTrue();
testSubject.currentConfigScope.Should().BeEquivalentTo(new ConfigurationScope(configScopeId, connectionId, sonarProjectKey, "some root", isReady));
VerifyCurrentConfigurationScopeChangedRaised();
}

[TestMethod]
Expand All @@ -110,6 +116,7 @@ public void TryUpdateRootOnCurrentConfigScope_ConfigScopeDifferent_DoesNotUpdate

result.Should().BeFalse();
testSubject.currentConfigScope.Should().BeEquivalentTo(new ConfigurationScope(configScopeId, connectionId, sonarProjectKey, isReadyForAnalysis: isReady));
VerifyCurrentConfigurationScopeChangedNotRaised();
}

[TestMethod]
Expand All @@ -125,6 +132,7 @@ public void TryUpdateAnalysisReadinessOnCurrentConfigScope_ConfigScopeSame_Updat

result.Should().BeTrue();
testSubject.currentConfigScope.Should().BeEquivalentTo(new ConfigurationScope(configScopeId, connectionId, sonarProjectKey, root, true));
VerifyCurrentConfigurationScopeChangedRaised();
}

[TestMethod]
Expand All @@ -140,6 +148,7 @@ public void TryUpdateAnalysisReadinessOnCurrentConfigScope_ConfigScopeDifferent_

result.Should().BeFalse();
testSubject.currentConfigScope.Should().BeEquivalentTo(new ConfigurationScope(configScopeId, connectionId, sonarProjectKey, root));
VerifyCurrentConfigurationScopeChangedNotRaised();
}

[TestMethod]
Expand All @@ -155,6 +164,7 @@ public void SetCurrentConfigScope_SetsBoundScope()
VerifyThreadHandling();
VerifyServiceAddCall();
VerifyLockTakenSynchronouslyAndReleased();
VerifyCurrentConfigurationScopeChangedRaised();
}

[TestMethod]
Expand All @@ -174,6 +184,7 @@ public void SetCurrentConfigScope_CurrentScopeExists_UpdatesBoundScope()
VerifyThreadHandling();
VerifyServiceUpdateCall();
VerifyLockTakenSynchronouslyAndReleased();
VerifyCurrentConfigurationScopeChangedRaised();
}

[TestMethod]
Expand All @@ -185,6 +196,7 @@ public void SetCurrentConfigScope_ServiceUnavailable_Throws()

act.Should().ThrowExactly<InvalidOperationException>().WithMessage(SLCoreStrings.ServiceProviderNotInitialized);
VerifyThreadHandling();
VerifyCurrentConfigurationScopeChangedNotRaised();
}

[TestMethod]
Expand All @@ -199,6 +211,7 @@ public void SetCurrentConfigScope_UpdateConfigScopeWithDifferentId_Throws()

act.Should().ThrowExactly<InvalidOperationException>().WithMessage(SLCoreStrings.ConfigScopeConflict);
VerifyThreadHandling();
VerifyCurrentConfigurationScopeChangedNotRaised();
}

[TestMethod]
Expand All @@ -212,6 +225,7 @@ public void RemoveCurrentConfigScope_RemovesScope()
configScopeService.Received().DidRemoveConfigurationScope(Arg.Is<DidRemoveConfigurationScopeParams>(p => p.removedId == configScopeId));
VerifyThreadHandling();
VerifyLockTakenSynchronouslyAndReleased();
VerifyCurrentConfigurationScopeChangedRaised();
}

[TestMethod]
Expand All @@ -222,6 +236,7 @@ public void RemoveCurrentConfigScope_NoCurrentScope_DoesNothing()
configScopeService.ReceivedCalls().Count().Should().Be(0);
VerifyThreadHandling();
VerifyLockTakenSynchronouslyAndReleased();
VerifyCurrentConfigurationScopeChangedNotRaised();
}

[TestMethod]
Expand All @@ -234,6 +249,7 @@ public void RemoveCurrentConfigScope_ServiceUnavailable_Throws()

act.Should().ThrowExactly<InvalidOperationException>().WithMessage(SLCoreStrings.ServiceProviderNotInitialized);
VerifyThreadHandling();
VerifyCurrentConfigurationScopeChangedNotRaised();
}

[TestMethod]
Expand Down Expand Up @@ -279,6 +295,7 @@ public void Reset_SetsCurrentScopeToNull()
serviceProvider.ReceivedCalls().Count().Should().Be(0);
VerifyThreadHandling();
VerifyLockTakenSynchronouslyAndReleased();
VerifyCurrentConfigurationScopeChangedRaised();
}

[TestMethod]
Expand Down Expand Up @@ -335,6 +352,16 @@ private void ConfigureServiceProvider(bool isServiceAvailable)
});
}

private void VerifyCurrentConfigurationScopeChangedRaised()
{
currentConfigScopeChangedEventHandler.Received(1).Invoke(testSubject, Arg.Any<EventArgs>());
}

private void VerifyCurrentConfigurationScopeChangedNotRaised()
{
currentConfigScopeChangedEventHandler.DidNotReceive().Invoke(testSubject, Arg.Any<EventArgs>());
}

private class ConfigurationScopeDtoComparer : IEqualityComparer<ConfigurationScopeDto>
{
public bool Equals(ConfigurationScopeDto x, ConfigurationScopeDto y)
Expand Down
34 changes: 24 additions & 10 deletions src/SLCore/State/ActiveConfigScopeTracker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

using System;
using System.ComponentModel.Composition;
using System.Diagnostics;
using SonarLint.VisualStudio.Core;
using SonarLint.VisualStudio.Core.Synchronization;
using SonarLint.VisualStudio.SLCore.Core;
Expand All @@ -43,6 +41,8 @@ public interface IActiveConfigScopeTracker : IDisposable
bool TryUpdateRootOnCurrentConfigScope(string id, string root);

bool TryUpdateAnalysisReadinessOnCurrentConfigScope(string id, bool isReady);

event EventHandler CurrentConfigurationScopeChanged;
}

public record ConfigurationScope(
Expand Down Expand Up @@ -107,23 +107,26 @@ public void SetCurrentConfigScope(string id, string connectionId = null, string
{
configurationScopeService.DidUpdateBinding(new DidUpdateBindingParams(id, GetBinding(connectionId, sonarProjectKey)));
currentConfigScope = currentConfigScope with { ConnectionId = connectionId, SonarProjectId = sonarProjectKey };
return;
}

configurationScopeService.DidAddConfigurationScopes(new DidAddConfigurationScopesParams([
new ConfigurationScopeDto(id, id, true, GetBinding(connectionId, sonarProjectKey))]));
currentConfigScope = new ConfigurationScope(id, connectionId, sonarProjectKey);
else
{
configurationScopeService.DidAddConfigurationScopes(new DidAddConfigurationScopesParams([
new ConfigurationScopeDto(id, id, true, GetBinding(connectionId, sonarProjectKey))]));
currentConfigScope = new ConfigurationScope(id, connectionId, sonarProjectKey);
}
}

OnCurrentConfigurationScopeChanged();
}

public void Reset()
{
threadHandling.ThrowIfOnUIThread();

using (asyncLock.Acquire())
{
currentConfigScope = null;
}
OnCurrentConfigurationScopeChanged();
}

public void RemoveCurrentConfigScope()
Expand All @@ -146,6 +149,8 @@ public void RemoveCurrentConfigScope()
new DidRemoveConfigurationScopeParams(currentConfigScope.Id));
currentConfigScope = null;
}

OnCurrentConfigurationScopeChanged();
}

public bool TryUpdateRootOnCurrentConfigScope(string id, string root)
Expand All @@ -158,8 +163,9 @@ public bool TryUpdateRootOnCurrentConfigScope(string id, string root)
}

currentConfigScope = currentConfigScope with { RootPath = root };
return true;
}
OnCurrentConfigurationScopeChanged();
return true;
}

public bool TryUpdateAnalysisReadinessOnCurrentConfigScope(string id, bool isReady)
Expand All @@ -172,10 +178,13 @@ public bool TryUpdateAnalysisReadinessOnCurrentConfigScope(string id, bool isRea
}

currentConfigScope = currentConfigScope with { isReadyForAnalysis = isReady};
return true;
}
OnCurrentConfigurationScopeChanged();
return true;
}

public event EventHandler CurrentConfigurationScopeChanged;

public void Dispose()
{
asyncLock?.Dispose();
Expand All @@ -184,4 +193,9 @@ public void Dispose()
private BindingConfigurationDto GetBinding(string connectionId, string sonarProjectKey) => connectionId is not null
? new BindingConfigurationDto(connectionId, sonarProjectKey)
: null;

private void OnCurrentConfigurationScopeChanged()
{
CurrentConfigurationScopeChanged?.Invoke(this, EventArgs.Empty);
}
}