Make document tracker resilient to multiple subscribes.

- Added tests to verify new functionality.

#2314
This commit is contained in:
N. Taylor Mullen 2018-04-27 11:47:34 -07:00
parent 8bc4c7a15c
commit 2885b4b138
2 changed files with 78 additions and 0 deletions

View File

@ -29,6 +29,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
private readonly Workspace _workspace;
private bool _isSupportedProject;
private ProjectSnapshot _projectSnapshot;
private int _subscribeCount;
// Only allow a single tag helper computation task at a time.
private (ProjectSnapshot project, Task task) _computingTagHelpers;
@ -177,12 +178,18 @@ namespace Microsoft.VisualStudio.Editor.Razor
{
_foregroundDispatcher.AssertForegroundThread();
if (_subscribeCount++ > 0)
{
return;
}
_projectSnapshot = _projectManager.GetOrCreateProject(_projectPath);
_isSupportedProject = true;
_projectManager.Changed += ProjectManager_Changed;
_workspaceEditorSettings.Changed += EditorSettingsManager_Changed;
_importDocumentManager.Changed += Import_Changed;
_importDocumentManager.OnSubscribed(this);
OnContextChanged(ContextChangeKind.ProjectChanged);
@ -192,6 +199,11 @@ namespace Microsoft.VisualStudio.Editor.Razor
{
_foregroundDispatcher.AssertForegroundThread();
if (_subscribeCount == 0 || _subscribeCount-- > 1)
{
return;
}
_importDocumentManager.OnUnsubscribed(this);
_projectManager.Changed -= ProjectManager_Changed;

View File

@ -98,6 +98,72 @@ namespace Microsoft.VisualStudio.Editor.Razor
private DefaultVisualStudioDocumentTracker DocumentTracker { get; }
[ForegroundFact]
public void Subscribe_NoopsIfAlreadySubscribed()
{
// Arrange
var callCount = 0;
DocumentTracker.ContextChanged += (sender, args) =>
{
callCount++;
};
DocumentTracker.Subscribe();
// Call count is 2 right now:
// 1 trigger for initial subscribe context changed.
// 1 trigger for TagHelpers being changed (computed).
// Act
DocumentTracker.Subscribe();
// Assert
Assert.Equal(2, callCount);
}
[ForegroundFact]
public void Unsubscribe_NoopsIfAlreadyUnsubscribed()
{
// Arrange
var callCount = 0;
DocumentTracker.Subscribe();
DocumentTracker.ContextChanged += (sender, args) =>
{
callCount++;
};
DocumentTracker.Unsubscribe();
// Act
DocumentTracker.Unsubscribe();
// Assert
Assert.Equal(1, callCount);
}
[ForegroundFact]
public void Unsubscribe_NoopsIfSubscribeHasBeenCalledMultipleTimes()
{
// Arrange
var callCount = 0;
DocumentTracker.Subscribe();
DocumentTracker.Subscribe();
DocumentTracker.ContextChanged += (sender, args) =>
{
callCount++;
};
// Act - 1
DocumentTracker.Unsubscribe();
// Assert - 1
Assert.Equal(0, callCount);
// Act - 2
DocumentTracker.Unsubscribe();
// Assert - 2
Assert.Equal(1, callCount);
}
[ForegroundFact]
public void EditorSettingsManager_Changed_TriggersContextChanged()
{