Change EditorSettingsManager to not be per-workspace.

- Lifted `DefaultEditorSettingsManagerInternal`s state / event handling functionality into its `DefaultEditorSettingsManager`.
- Re-purposed `EditorSettingsManagerInternal` into a less-API heavy middleman `WorkspaceEditorSettings` for any workspace services concerned with editor settings to consume.
- Moved `DefaultEditorSettingsManagerInternal` into the Editor.Razor assembly and renamed it to `DefaultWorkspaceEditorSettings` since it needed the `EditorSettingsManager` API to function properly. The contract still exists at the `CodeAnalysis.Razor.Workspace` level.

#1982
This commit is contained in:
N. Taylor Mullen 2018-01-26 17:13:58 -08:00
parent 9244383ec7
commit 99010aaea4
12 changed files with 292 additions and 124 deletions

View File

@ -1,63 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.CodeAnalysis.Razor.Editor
{
internal class DefaultEditorSettingsManagerInternal : EditorSettingsManagerInternal
{
public override event EventHandler<EditorSettingsChangedEventArgs> Changed;
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly object SettingsAccessorLock = new object();
private EditorSettings _settings;
public DefaultEditorSettingsManagerInternal(ForegroundDispatcher dispatcher)
{
if (dispatcher == null)
{
throw new ArgumentNullException(nameof(dispatcher));
}
_foregroundDispatcher = dispatcher;
_settings = EditorSettings.Default;
}
public override EditorSettings Current
{
get
{
lock (SettingsAccessorLock)
{
return _settings;
}
}
}
public override void Update(EditorSettings updatedSettings)
{
if (updatedSettings == null)
{
throw new ArgumentNullException(nameof(updatedSettings));
}
lock (SettingsAccessorLock)
{
if (!_settings.Equals(updatedSettings))
{
_settings = updatedSettings;
OnChanged();
}
}
}
private void OnChanged()
{
_foregroundDispatcher.AssertForegroundThread();
var args = new EditorSettingsChangedEventArgs(Current);
Changed?.Invoke(this, args);
}
}
}

View File

@ -6,12 +6,10 @@ using Microsoft.CodeAnalysis.Host;
namespace Microsoft.CodeAnalysis.Razor.Editor
{
internal abstract class EditorSettingsManagerInternal : ILanguageService
internal abstract class WorkspaceEditorSettings : ILanguageService
{
public abstract event EventHandler<EditorSettingsChangedEventArgs> Changed;
public abstract EditorSettings Current { get; }
public abstract void Update(EditorSettings updateSettings);
}
}

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using Microsoft.CodeAnalysis.Razor;
using Microsoft.CodeAnalysis.Razor.Editor;
@ -12,26 +13,55 @@ namespace Microsoft.VisualStudio.Editor.Razor
[Export(typeof(EditorSettingsManager))]
internal class DefaultEditorSettingsManager : EditorSettingsManager
{
private readonly EditorSettingsManagerInternal _editorSettingsManager;
public override event EventHandler<EditorSettingsChangedEventArgs> Changed;
private readonly object SettingsAccessorLock = new object();
private readonly ForegroundDispatcher _foregroundDispatcher;
private EditorSettings _settings;
[ImportingConstructor]
public DefaultEditorSettingsManager(VisualStudioWorkspaceAccessor workspaceAccessor)
public DefaultEditorSettingsManager(ForegroundDispatcher foregroundDispatcher)
{
var razorLanguageServices = workspaceAccessor.Workspace.Services.GetLanguageServices(RazorLanguage.Name);
_editorSettingsManager = razorLanguageServices.GetRequiredService<EditorSettingsManagerInternal>();
_foregroundDispatcher = foregroundDispatcher;
_settings = EditorSettings.Default;
}
public override event EventHandler<EditorSettingsChangedEventArgs> Changed
public override EditorSettings Current
{
add => _editorSettingsManager.Changed += value;
remove => _editorSettingsManager.Changed -= value;
get
{
lock (SettingsAccessorLock)
{
return _settings;
}
}
}
public override EditorSettings Current => _editorSettingsManager.Current;
public override void Update(EditorSettings updateSettings)
public override void Update(EditorSettings updatedSettings)
{
_editorSettingsManager.Update(updateSettings);
if (updatedSettings == null)
{
throw new ArgumentNullException(nameof(updatedSettings));
}
_foregroundDispatcher.AssertForegroundThread();
lock (SettingsAccessorLock)
{
if (!_settings.Equals(updatedSettings))
{
_settings = updatedSettings;
OnChanged();
}
}
}
private void OnChanged()
{
_foregroundDispatcher.AssertForegroundThread();
var args = new EditorSettingsChangedEventArgs(Current);
Changed?.Invoke(this, args);
}
}
}

View File

@ -19,7 +19,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
private readonly string _filePath;
private readonly string _projectPath;
private readonly ProjectSnapshotManager _projectManager;
private readonly EditorSettingsManagerInternal _editorSettingsManager;
private readonly WorkspaceEditorSettings _workspaceEditorSettings;
private readonly ITextBuffer _textBuffer;
private readonly ImportDocumentManager _importDocumentManager;
private readonly List<ITextView> _textViews;
@ -34,7 +34,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
string filePath,
string projectPath,
ProjectSnapshotManager projectManager,
EditorSettingsManagerInternal editorSettingsManager,
WorkspaceEditorSettings workspaceEditorSettings,
Workspace workspace,
ITextBuffer textBuffer,
ImportDocumentManager importDocumentManager)
@ -59,9 +59,9 @@ namespace Microsoft.VisualStudio.Editor.Razor
throw new ArgumentNullException(nameof(projectManager));
}
if (editorSettingsManager == null)
if (workspaceEditorSettings == null)
{
throw new ArgumentNullException(nameof(editorSettingsManager));
throw new ArgumentNullException(nameof(workspaceEditorSettings));
}
if (workspace == null)
@ -83,7 +83,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
_filePath = filePath;
_projectPath = projectPath;
_projectManager = projectManager;
_editorSettingsManager = editorSettingsManager;
_workspaceEditorSettings = workspaceEditorSettings;
_textBuffer = textBuffer;
_importDocumentManager = importDocumentManager;
_workspace = workspace; // For now we assume that the workspace is the always default VS workspace.
@ -93,7 +93,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
internal override ProjectExtensibilityConfiguration Configuration => _project?.Configuration;
public override EditorSettings EditorSettings => _editorSettingsManager.Current;
public override EditorSettings EditorSettings => _workspaceEditorSettings.Current;
public override IReadOnlyList<TagHelperDescriptor> TagHelpers => _project?.TagHelpers ?? Array.Empty<TagHelperDescriptor>();
@ -154,7 +154,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
{
_importDocumentManager.OnSubscribed(this);
_editorSettingsManager.Changed += EditorSettingsManager_Changed;
_workspaceEditorSettings.Changed += EditorSettingsManager_Changed;
_projectManager.Changed += ProjectManager_Changed;
_importDocumentManager.Changed += Import_Changed;
@ -169,7 +169,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
_importDocumentManager.OnUnsubscribed(this);
_projectManager.Changed -= ProjectManager_Changed;
_editorSettingsManager.Changed -= EditorSettingsManager_Changed;
_workspaceEditorSettings.Changed -= EditorSettingsManager_Changed;
_importDocumentManager.Changed -= Import_Changed;
// Detached from project.

View File

@ -19,12 +19,12 @@ namespace Microsoft.VisualStudio.Editor.Razor
private readonly ImportDocumentManager _importDocumentManager;
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly ProjectSnapshotManager _projectManager;
private readonly EditorSettingsManagerInternal _editorSettingsManager;
private readonly WorkspaceEditorSettings _workspaceEditorSettings;
public DefaultVisualStudioDocumentTrackerFactory(
ForegroundDispatcher foregroundDispatcher,
ProjectSnapshotManager projectManager,
EditorSettingsManagerInternal editorSettingsManager,
WorkspaceEditorSettings workspaceEditorSettings,
TextBufferProjectService projectService,
ITextDocumentFactoryService textDocumentFactory,
ImportDocumentManager importDocumentManager,
@ -40,9 +40,9 @@ namespace Microsoft.VisualStudio.Editor.Razor
throw new ArgumentNullException(nameof(projectManager));
}
if (editorSettingsManager == null)
if (workspaceEditorSettings == null)
{
throw new ArgumentNullException(nameof(editorSettingsManager));
throw new ArgumentNullException(nameof(workspaceEditorSettings));
}
if (projectService == null)
@ -67,7 +67,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
_foregroundDispatcher = foregroundDispatcher;
_projectManager = projectManager;
_editorSettingsManager = editorSettingsManager;
_workspaceEditorSettings = workspaceEditorSettings;
_projectService = projectService;
_textDocumentFactory = textDocumentFactory;
_importDocumentManager = importDocumentManager;
@ -97,7 +97,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
var projectPath = _projectService.GetProjectPath(project);
var tracker = new DefaultVisualStudioDocumentTracker(_foregroundDispatcher, filePath, projectPath, _projectManager, _editorSettingsManager, _workspace, textBuffer, _importDocumentManager);
var tracker = new DefaultVisualStudioDocumentTracker(_foregroundDispatcher, filePath, projectPath, _projectManager, _workspaceEditorSettings, _workspace, textBuffer, _importDocumentManager);
return tracker;
}

View File

@ -44,14 +44,14 @@ namespace Microsoft.VisualStudio.Editor.Razor
}
var projectManager = languageServices.GetRequiredService<ProjectSnapshotManager>();
var editorSettingsManager = languageServices.GetRequiredService<EditorSettingsManagerInternal>();
var workspaceEditorSettings = languageServices.GetRequiredService<WorkspaceEditorSettings>();
var projectService = languageServices.GetRequiredService<TextBufferProjectService>();
var importDocumentManager = languageServices.GetRequiredService<ImportDocumentManager>();
return new DefaultVisualStudioDocumentTrackerFactory(
_foregroundDispatcher,
projectManager,
editorSettingsManager,
workspaceEditorSettings,
projectService,
_textDocumentFactory,
importDocumentManager,

View File

@ -0,0 +1,94 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Diagnostics;
using Microsoft.CodeAnalysis.Razor;
using Microsoft.CodeAnalysis.Razor.Editor;
namespace Microsoft.VisualStudio.Editor.Razor
{
internal class DefaultWorkspaceEditorSettings : WorkspaceEditorSettings
{
private readonly EditorSettingsManager _editorSettingsManager;
private readonly EventHandler<EditorSettingsChangedEventArgs> _onChanged;
private EventHandler<EditorSettingsChangedEventArgs> _changed;
private readonly ForegroundDispatcher _foregroundDispatcher;
private int _listenerCount = 0;
public DefaultWorkspaceEditorSettings(ForegroundDispatcher foregroundDispatcher, EditorSettingsManager editorSettingsManager)
{
if (foregroundDispatcher == null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
}
if (editorSettingsManager == null)
{
throw new ArgumentNullException(nameof(editorSettingsManager));
}
_foregroundDispatcher = foregroundDispatcher;
_editorSettingsManager = editorSettingsManager;
_onChanged = OnChanged;
}
public override event EventHandler<EditorSettingsChangedEventArgs> Changed
{
add
{
_foregroundDispatcher.AssertForegroundThread();
_listenerCount++;
_changed += value;
if (_listenerCount == 1)
{
// We bind to the editor settings manager only when we have listeners to avoid leaking memory.
// Basically we're relying on anyone listening to us to have an understanding of when they're going
// to be torn down. In Razor's case this will just be the document tracker factory (which does know).
AttachToEditorSettingsManager();
}
}
remove
{
_foregroundDispatcher.AssertForegroundThread();
_listenerCount--;
_changed -= value;
if (_listenerCount == 0)
{
// We detatch from the editor settings manager when no one is listening to allow us to be garbage
// collected in the case that the workspace is tearing down.
DetachFromEditorSettingsManager();
}
}
}
// Internal for testing
internal virtual void AttachToEditorSettingsManager()
{
_editorSettingsManager.Changed += _onChanged;
}
// Internal for testing
internal virtual void DetachFromEditorSettingsManager()
{
_editorSettingsManager.Changed -= _onChanged;
}
public override EditorSettings Current => _editorSettingsManager.Current;
// Internal for testing
internal void OnChanged(object sender, EditorSettingsChangedEventArgs e)
{
_foregroundDispatcher.AssertForegroundThread();
Debug.Assert(_changed != null, nameof(OnChanged) + " should not be invoked when there are no listeners.");
var args = new EditorSettingsChangedEventArgs(Current);
_changed?.Invoke(this, args);
}
}
}

View File

@ -5,24 +5,33 @@ using System;
using System.Composition;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Razor;
using Microsoft.CodeAnalysis.Razor.Editor;
namespace Microsoft.CodeAnalysis.Razor.Editor
namespace Microsoft.VisualStudio.Editor.Razor
{
[Shared]
[ExportLanguageServiceFactory(typeof(EditorSettingsManagerInternal), RazorLanguage.Name)]
internal class DefaultEditorSettingsManagerInternalFactory : ILanguageServiceFactory
[ExportLanguageServiceFactory(typeof(WorkspaceEditorSettings), RazorLanguage.Name)]
internal class DefaultWorkspaceEditorSettingsFactory : ILanguageServiceFactory
{
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly EditorSettingsManager _editorSettingsManager;
[ImportingConstructor]
public DefaultEditorSettingsManagerInternalFactory(ForegroundDispatcher foregroundDispatcher)
public DefaultWorkspaceEditorSettingsFactory(ForegroundDispatcher foregroundDispatcher, EditorSettingsManager editorSettingsManager)
{
if (foregroundDispatcher == null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
}
if (editorSettingsManager == null)
{
throw new ArgumentNullException(nameof(editorSettingsManager));
}
_foregroundDispatcher = foregroundDispatcher;
_editorSettingsManager = editorSettingsManager;
}
public ILanguageService CreateLanguageService(HostLanguageServices languageServices)
@ -32,7 +41,7 @@ namespace Microsoft.CodeAnalysis.Razor.Editor
throw new ArgumentNullException(nameof(languageServices));
}
return new DefaultEditorSettingsManagerInternal(_foregroundDispatcher);
return new DefaultWorkspaceEditorSettings(_foregroundDispatcher, _editorSettingsManager);
}
}
}

View File

@ -1,17 +1,18 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.CodeAnalysis.Razor.Editor;
using Xunit;
namespace Microsoft.CodeAnalysis.Razor.Editor
namespace Microsoft.VisualStudio.Editor.Razor
{
public class DefaultEditorSettingsManagerInternalTest : ForegroundDispatcherTestBase
public class DefaultEditorSettingsManagerTest : ForegroundDispatcherTestBase
{
[Fact]
public void InitialSettingsAreDefault()
{
// Act
var manager = new DefaultEditorSettingsManagerInternal(Dispatcher);
var manager = new DefaultEditorSettingsManager(Dispatcher);
// Assert
Assert.Equal(EditorSettings.Default, manager.Current);
@ -21,7 +22,7 @@ namespace Microsoft.CodeAnalysis.Razor.Editor
public void Update_TriggersChangedIfEditorSettingsAreDifferent()
{
// Arrange
var manager = new DefaultEditorSettingsManagerInternal(Dispatcher);
var manager = new DefaultEditorSettingsManager(Dispatcher);
var called = false;
manager.Changed += (caller, args) =>
{
@ -41,7 +42,7 @@ namespace Microsoft.CodeAnalysis.Razor.Editor
public void Update_DoesNotTriggerChangedIfEditorSettingsAreSame()
{
// Arrange
var manager = new DefaultEditorSettingsManagerInternal(Dispatcher);
var manager = new DefaultEditorSettingsManager(Dispatcher);
var called = false;
manager.Changed += (caller, args) =>
{

View File

@ -27,7 +27,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
private ProjectSnapshotManager ProjectManager => Mock.Of<ProjectSnapshotManager>(p => p.Projects == new List<ProjectSnapshot>());
private EditorSettingsManagerInternal EditorSettingsManager => new DefaultEditorSettingsManagerInternal(Dispatcher);
private WorkspaceEditorSettings WorkspaceEditorSettings => new DefaultWorkspaceEditorSettings(Dispatcher, Mock.Of<EditorSettingsManager>());
private ImportDocumentManager ImportDocumentManager => Mock.Of<ImportDocumentManager>();
@ -81,7 +81,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
{
Mock.Of<ITextBuffer>(b => b.ContentType == RazorCoreContentType && b.Properties == new PropertyCollection()),
};
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, EditorSettingsManager, Workspace, buffers[0], ImportDocumentManager) as VisualStudioDocumentTracker;
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, WorkspaceEditorSettings, Workspace, buffers[0], ImportDocumentManager) as VisualStudioDocumentTracker;
var editorFactoryService = Mock.Of<RazorEditorFactoryService>(factoryService => factoryService.TryGetDocumentTracker(It.IsAny<ITextBuffer>(), out documentTracker) == true);
var documentManager = new DefaultRazorDocumentManager(Dispatcher, editorFactoryService, SupportedProjectService);
@ -102,7 +102,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
Mock.Of<ITextBuffer>(b => b.ContentType == RazorCoreContentType && b.Properties == new PropertyCollection()),
Mock.Of<ITextBuffer>(b => b.ContentType == NonRazorCoreContentType && b.Properties == new PropertyCollection()),
};
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, EditorSettingsManager, Workspace, buffers[0], ImportDocumentManager) as VisualStudioDocumentTracker;
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, WorkspaceEditorSettings, Workspace, buffers[0], ImportDocumentManager) as VisualStudioDocumentTracker;
var editorFactoryService = Mock.Of<RazorEditorFactoryService>(f => f.TryGetDocumentTracker(It.IsAny<ITextBuffer>(), out documentTracker) == true);
var documentManager = new DefaultRazorDocumentManager(Dispatcher, editorFactoryService, SupportedProjectService);
@ -165,12 +165,12 @@ namespace Microsoft.VisualStudio.Editor.Razor
};
// Preload the buffer's properties with a tracker, so it's like we've already tracked this one.
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, EditorSettingsManager, Workspace, buffers[0], ImportDocumentManager);
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, WorkspaceEditorSettings, Workspace, buffers[0], ImportDocumentManager);
documentTracker.AddTextView(textView1);
documentTracker.AddTextView(textView2);
buffers[0].Properties.AddProperty(typeof(VisualStudioDocumentTracker), documentTracker);
documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, EditorSettingsManager, Workspace, buffers[1], ImportDocumentManager);
documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, WorkspaceEditorSettings, Workspace, buffers[1], ImportDocumentManager);
documentTracker.AddTextView(textView1);
documentTracker.AddTextView(textView2);
buffers[1].Properties.AddProperty(typeof(VisualStudioDocumentTracker), documentTracker);
@ -200,7 +200,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
Mock.Of<ITextBuffer>(b => b.ContentType == RazorCoreContentType && b.Properties == new PropertyCollection()),
Mock.Of<ITextBuffer>(b => b.ContentType == NonRazorCoreContentType && b.Properties == new PropertyCollection()),
};
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, EditorSettingsManager, Workspace, buffers[0], ImportDocumentManager);
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, WorkspaceEditorSettings, Workspace, buffers[0], ImportDocumentManager);
buffers[0].Properties.AddProperty(typeof(VisualStudioDocumentTracker), documentTracker);
var editorFactoryService = Mock.Of<RazorEditorFactoryService>();
var documentManager = new DefaultRazorDocumentManager(Dispatcher, editorFactoryService, SupportedProjectService);

View File

@ -27,7 +27,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
private ProjectSnapshotManager ProjectManager => Mock.Of<ProjectSnapshotManager>(p => p.Projects == new List<ProjectSnapshot>());
private EditorSettingsManagerInternal EditorSettingsManager => new DefaultEditorSettingsManagerInternal(Dispatcher);
private WorkspaceEditorSettings WorkspaceEditorSettings => new DefaultWorkspaceEditorSettings(Dispatcher, Mock.Of<EditorSettingsManager>());
private Workspace Workspace => TestWorkspace.Create();
@ -37,7 +37,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
public void EditorSettingsManager_Changed_TriggersContextChanged()
{
// Arrange
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, EditorSettingsManager, Workspace, TextBuffer, ImportDocumentManager);
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, WorkspaceEditorSettings, Workspace, TextBuffer, ImportDocumentManager);
var called = false;
documentTracker.ContextChanged += (sender, args) =>
{
@ -62,7 +62,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
{
project = ws.AddProject(ProjectInfo.Create(ProjectId.CreateNewId(), new VersionStamp(), "Test1", "TestAssembly", LanguageNames.CSharp, filePath: "C:/Some/Path/TestProject.csproj"));
});
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, EditorSettingsManager, workspace, TextBuffer, ImportDocumentManager);
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, WorkspaceEditorSettings, workspace, TextBuffer, ImportDocumentManager);
var projectSnapshot = new DefaultProjectSnapshot(project);
var projectChangedArgs = new ProjectChangeEventArgs(projectSnapshot, ProjectChangeKind.Changed);
@ -90,7 +90,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
{
project = ws.AddProject(ProjectInfo.Create(ProjectId.CreateNewId(), new VersionStamp(), "Test1", "TestAssembly", LanguageNames.CSharp, filePath: "C:/Some/Path/TestProject.csproj"));
});
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, EditorSettingsManager, workspace, TextBuffer, ImportDocumentManager);
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, WorkspaceEditorSettings, workspace, TextBuffer, ImportDocumentManager);
var projectSnapshot = new DefaultProjectSnapshot(project);
var projectChangedArgs = new ProjectChangeEventArgs(projectSnapshot, ProjectChangeKind.TagHelpersChanged);
@ -118,7 +118,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
{
project = ws.AddProject(ProjectInfo.Create(ProjectId.CreateNewId(), new VersionStamp(), "Test1", "TestAssembly", LanguageNames.CSharp, filePath: "C:/Some/Other/Path/TestProject.csproj"));
});
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, EditorSettingsManager, workspace, TextBuffer, ImportDocumentManager);
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, WorkspaceEditorSettings, workspace, TextBuffer, ImportDocumentManager);
var projectSnapshot = new DefaultProjectSnapshot(project);
var projectChangedArgs = new ProjectChangeEventArgs(projectSnapshot, ProjectChangeKind.Changed);
@ -140,7 +140,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
public void Import_Changed_ImportAssociatedWithDocument_TriggersContextChanged()
{
// Arrange
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, EditorSettingsManager, Workspace, TextBuffer, ImportDocumentManager);
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, WorkspaceEditorSettings, Workspace, TextBuffer, ImportDocumentManager);
var called = false;
documentTracker.ContextChanged += (sender, args) =>
@ -162,7 +162,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
public void Import_Changed_UnrelatedImport_DoesNothing()
{
// Arrange
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, EditorSettingsManager, Workspace, TextBuffer, ImportDocumentManager);
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, WorkspaceEditorSettings, Workspace, TextBuffer, ImportDocumentManager);
documentTracker.ContextChanged += (sender, args) =>
{
@ -179,7 +179,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
public void Subscribe_SetsSupportedProjectAndTriggersContextChanged()
{
// Arrange
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, EditorSettingsManager, Workspace, TextBuffer, ImportDocumentManager);
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, WorkspaceEditorSettings, Workspace, TextBuffer, ImportDocumentManager);
var called = false;
documentTracker.ContextChanged += (sender, args) =>
{
@ -199,7 +199,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
public void Unsubscribe_ResetsSupportedProjectAndTriggersContextChanged()
{
// Arrange
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, EditorSettingsManager, Workspace, TextBuffer, ImportDocumentManager);
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, WorkspaceEditorSettings, Workspace, TextBuffer, ImportDocumentManager);
// Subscribe once to set supported project
documentTracker.Subscribe();
@ -223,7 +223,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
public void AddTextView_AddsToTextViewCollection()
{
// Arrange
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, EditorSettingsManager, Workspace, TextBuffer, ImportDocumentManager);
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, WorkspaceEditorSettings, Workspace, TextBuffer, ImportDocumentManager);
var textView = Mock.Of<ITextView>();
// Act
@ -237,7 +237,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
public void AddTextView_DoesNotAddDuplicateTextViews()
{
// Arrange
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, EditorSettingsManager, Workspace, TextBuffer, ImportDocumentManager);
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, WorkspaceEditorSettings, Workspace, TextBuffer, ImportDocumentManager);
var textView = Mock.Of<ITextView>();
// Act
@ -252,7 +252,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
public void AddTextView_AddsMultipleTextViewsToCollection()
{
// Arrange
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, EditorSettingsManager, Workspace, TextBuffer, ImportDocumentManager);
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, WorkspaceEditorSettings, Workspace, TextBuffer, ImportDocumentManager);
var textView1 = Mock.Of<ITextView>();
var textView2 = Mock.Of<ITextView>();
@ -271,7 +271,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
public void RemoveTextView_RemovesTextViewFromCollection_SingleItem()
{
// Arrange
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, EditorSettingsManager, Workspace, TextBuffer, ImportDocumentManager);
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, WorkspaceEditorSettings, Workspace, TextBuffer, ImportDocumentManager);
var textView = Mock.Of<ITextView>();
documentTracker.AddTextView(textView);
@ -286,7 +286,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
public void RemoveTextView_RemovesTextViewFromCollection_MultipleItems()
{
// Arrange
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, EditorSettingsManager, Workspace, TextBuffer, ImportDocumentManager);
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, WorkspaceEditorSettings, Workspace, TextBuffer, ImportDocumentManager);
var textView1 = Mock.Of<ITextView>();
var textView2 = Mock.Of<ITextView>();
var textView3 = Mock.Of<ITextView>();
@ -308,7 +308,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
public void RemoveTextView_NoopsWhenRemovingTextViewNotInCollection()
{
// Arrange
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, EditorSettingsManager, Workspace, TextBuffer, ImportDocumentManager);
var documentTracker = new DefaultVisualStudioDocumentTracker(Dispatcher, FilePath, ProjectPath, ProjectManager, WorkspaceEditorSettings, Workspace, TextBuffer, ImportDocumentManager);
var textView1 = Mock.Of<ITextView>();
documentTracker.AddTextView(textView1);
var textView2 = Mock.Of<ITextView>();

View File

@ -0,0 +1,99 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.CodeAnalysis.Razor;
using Microsoft.CodeAnalysis.Razor.Editor;
using Moq;
using Xunit;
namespace Microsoft.VisualStudio.Editor.Razor
{
public class DefaultWorkspaceEditorSettingsTest : ForegroundDispatcherTestBase
{
[Fact]
public void InitialSettingsAreEditorSettingsManagerDefault()
{
// Arrange
var editorSettings = new EditorSettings(true, 123);
var editorSettingsManager = Mock.Of<EditorSettingsManager>(m => m.Current == editorSettings);
// Act
var manager = new DefaultWorkspaceEditorSettings(Dispatcher, editorSettingsManager);
// Assert
Assert.Equal(editorSettings, manager.Current);
}
[Fact]
public void OnChanged_TriggersChanged()
{
// Arrange
var manager = new DefaultWorkspaceEditorSettings(Dispatcher, Mock.Of<EditorSettingsManager>());
var called = false;
manager.Changed += (caller, args) =>
{
called = true;
};
// Act
manager.OnChanged(null, null);
// Assert
Assert.True(called);
}
[Fact]
public void Attach_CalledOnceForMultipleListeners()
{
// Arrange
var manager = new TestEditorSettingsManagerInternal(Dispatcher);
// Act
manager.Changed += (caller, args) => { };
manager.Changed += (caller, args) => { };
// Assert
Assert.Equal(1, manager.AttachCount);
}
[Fact]
public void Detach_CalledOnceWhenNoMoreListeners()
{
// Arrange
var manager = new TestEditorSettingsManagerInternal(Dispatcher);
EventHandler<EditorSettingsChangedEventArgs> listener1 = (caller, args) => { };
EventHandler<EditorSettingsChangedEventArgs> listener2 = (caller, args) => { };
manager.Changed += listener1;
manager.Changed += listener2;
// Act
manager.Changed -= listener1;
manager.Changed -= listener2;
// Assert
Assert.Equal(1, manager.DetachCount);
}
private class TestEditorSettingsManagerInternal : DefaultWorkspaceEditorSettings
{
public TestEditorSettingsManagerInternal(ForegroundDispatcher foregroundDispatcher) : base(foregroundDispatcher, Mock.Of<EditorSettingsManager>())
{
}
public int AttachCount { get; private set; }
public int DetachCount { get; private set; }
internal override void AttachToEditorSettingsManager()
{
AttachCount++;
}
internal override void DetachFromEditorSettingsManager()
{
DetachCount++;
}
}
}
}