diff --git a/AxoCover.Runner/TestDiscoveryService.cs b/AxoCover.Runner/TestDiscoveryService.cs index 059a807..a4aa07f 100644 --- a/AxoCover.Runner/TestDiscoveryService.cs +++ b/AxoCover.Runner/TestDiscoveryService.cs @@ -6,6 +6,7 @@ using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Reflection; using System.ServiceModel; @@ -85,14 +86,14 @@ private void DiscoverTests(string[] adapterSources, IEnumerable testSour } _monitor.RecordMessage(TestMessageLevel.Informational, $"Discovering tests..."); - if (runSettingsPath != null) + if (!string.IsNullOrEmpty(runSettingsPath)) { _monitor.RecordMessage(TestMessageLevel.Informational, $"Using run settings {runSettingsPath}."); } try { - var runSettings = new RunSettings(runSettingsPath == null ? null : File.ReadAllText(runSettingsPath)); + var runSettings = new RunSettings(string.IsNullOrEmpty(runSettingsPath) ? null : File.ReadAllText(runSettingsPath)); var context = new TestDiscoveryContext(_monitor, runSettings); foreach (var testDiscoverer in _testDiscoverers) diff --git a/AxoCover.Runner/TestExecutionContext.cs b/AxoCover.Runner/TestExecutionContext.cs index 0f967ad..f9309c1 100644 --- a/AxoCover.Runner/TestExecutionContext.cs +++ b/AxoCover.Runner/TestExecutionContext.cs @@ -93,7 +93,7 @@ public TestExecutionContext(ITestExecutionMonitor monitor, TestExecutionOptions { _monitor = monitor; _options = options; - _runSettings = new RunSettings(options.RunSettingsPath == null ? null : File.ReadAllText(options.RunSettingsPath)); + _runSettings = new RunSettings(string.IsNullOrEmpty(options.RunSettingsPath) ? null : File.ReadAllText(options.RunSettingsPath)); } class EmptyTestCaseFilterExpression : ITestCaseFilterExpression diff --git a/AxoCover.Runner/TestExecutionService.cs b/AxoCover.Runner/TestExecutionService.cs index 75616c6..d07cecb 100644 --- a/AxoCover.Runner/TestExecutionService.cs +++ b/AxoCover.Runner/TestExecutionService.cs @@ -126,7 +126,7 @@ private void RunTests(IEnumerable testCases, TestExecutionOptions opti } _monitor.RecordMessage(TestMessageLevel.Informational, $"Executing tests..."); - if (options.RunSettingsPath != null) + if (!string.IsNullOrEmpty(options.RunSettingsPath)) { _monitor.RecordMessage(TestMessageLevel.Informational, $"Using run settings {options.RunSettingsPath}."); } diff --git a/AxoCover/AxoCover.csproj b/AxoCover/AxoCover.csproj index 20a5765..f204600 100644 --- a/AxoCover/AxoCover.csproj +++ b/AxoCover/AxoCover.csproj @@ -155,7 +155,7 @@ ..\packages\Microsoft.TestPlatform.ObjectModel.11.0.0\lib\net35\Microsoft.VisualStudio.TestPlatform.ObjectModel.dll - True + False ..\packages\VSSDK.Text.11.0.4\lib\net45\Microsoft.VisualStudio.Text.Data.dll @@ -187,6 +187,10 @@ True False + + ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll + True + False @@ -266,6 +270,7 @@ + @@ -288,6 +293,7 @@ + @@ -319,10 +325,12 @@ + + diff --git a/AxoCover/AxoCoverPackage.cs b/AxoCover/AxoCoverPackage.cs index 32aee0d..fdc795a 100644 --- a/AxoCover/AxoCoverPackage.cs +++ b/AxoCover/AxoCoverPackage.cs @@ -1,10 +1,9 @@ using AxoCover.Models; -using AxoCover.Properties; using AxoCover.Views; +using Microsoft.Practices.Unity; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; using System; -using System.ComponentModel; using System.IO; using System.Reflection; using System.Runtime.InteropServices; @@ -35,16 +34,17 @@ static AxoCoverPackage() Manifest = PackageManifest.FromFile(Path.Combine(PackageRoot, "extension.vsixmanifest")); } + private readonly IOptions _options; + public AxoCoverPackage() { - Settings.Default.PropertyChanged += OnSettingChanged; - ContainerProvider.Initialize(); + _options = ContainerProvider.Container.Resolve(); Application.Current.Dispatcher.BeginInvoke(new Action(InitializeTelemetry), DispatcherPriority.ApplicationIdle); } - private static void InitializeTelemetry() + private void InitializeTelemetry() { - if (!Settings.Default.IsTelemetryModeSelected) + if (!_options.IsTelemetryModeSelected) { var dialog = new ViewDialog() { @@ -53,16 +53,11 @@ private static void InitializeTelemetry() if (dialog.ShowDialog() == true) { - Settings.Default.IsTelemetryModeSelected = true; + _options.IsTelemetryModeSelected = true; } } } - private void OnSettingChanged(object sender, PropertyChangedEventArgs e) - { - Settings.Default.Save(); - } - protected override void Initialize() { base.Initialize(); diff --git a/AxoCover/Converters/EmptyToBooleanConverter.cs b/AxoCover/Converters/EmptyToBooleanConverter.cs new file mode 100644 index 0000000..fe3ccd8 --- /dev/null +++ b/AxoCover/Converters/EmptyToBooleanConverter.cs @@ -0,0 +1,19 @@ +using System; +using System.Globalization; +using System.Windows.Data; + +namespace AxoCover.Converters +{ + public class EmptyToBooleanConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + return string.IsNullOrEmpty(value as string); + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotSupportedException(); + } + } +} diff --git a/AxoCover/LineCoverageAdornment.cs b/AxoCover/LineCoverageAdornment.cs index 528fd75..dabaea1 100644 --- a/AxoCover/LineCoverageAdornment.cs +++ b/AxoCover/LineCoverageAdornment.cs @@ -2,12 +2,12 @@ using AxoCover.Models; using AxoCover.Models.Commands; using AxoCover.Models.Data; -using AxoCover.Properties; using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Editor; using Microsoft.VisualStudio.Text.Formatting; using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Windows; using System.Windows.Controls; @@ -33,85 +33,21 @@ public class LineCoverageAdornment private FileCoverage _fileCoverage = FileCoverage.Empty; private FileResults _fileResults = FileResults.Empty; - private static readonly BrushAndPenContainer _selectedBrushAndPen = new BrushAndPenContainer(Settings.Default.SelectedColor, _branchCoverageSpotBorderThickness); - public static Color SelectedColor - { - get { return _selectedBrushAndPen.Color; } - set - { - _selectedBrushAndPen.Color = value; - Settings.Default.SelectedColor = value; - _isHighlightingChanged?.Invoke(); - } - } - - private static readonly BrushAndPenContainer _coveredBrushAndPen = new BrushAndPenContainer(Settings.Default.CoveredColor, _branchCoverageSpotBorderThickness); - public static Color CoveredColor - { - get { return _coveredBrushAndPen.Color; } - set - { - _coveredBrushAndPen.Color = value; - Settings.Default.CoveredColor = value; - _isHighlightingChanged?.Invoke(); - } - } - - private static readonly BrushAndPenContainer _mixedBrushAndPen = new BrushAndPenContainer(Settings.Default.MixedColor, _branchCoverageSpotBorderThickness); - public static Color MixedColor - { - get { return _mixedBrushAndPen.Color; } - set - { - _mixedBrushAndPen.Color = value; - Settings.Default.MixedColor = value; - _isHighlightingChanged?.Invoke(); - } - } - - private static readonly BrushAndPenContainer _uncoveredBrushAndPen = new BrushAndPenContainer(Settings.Default.UncoveredColor, _branchCoverageSpotBorderThickness); - public static Color UncoveredColor - { - get { return _uncoveredBrushAndPen.Color; } - set - { - _uncoveredBrushAndPen.Color = value; - Settings.Default.UncoveredColor = value; - _isHighlightingChanged?.Invoke(); - } - } + private readonly BrushAndPenContainer _selectedBrushAndPen; + private readonly BrushAndPenContainer _coveredBrushAndPen; + private readonly BrushAndPenContainer _mixedBrushAndPen; + private readonly BrushAndPenContainer _uncoveredBrushAndPen; + private readonly BrushAndPenContainer _exceptionOriginBrushAndPen; + private readonly BrushAndPenContainer _exceptionTraceBrushAndPen; - private static readonly BrushAndPenContainer _exceptionOriginBrushAndPen = new BrushAndPenContainer(Settings.Default.ExceptionOriginColor, _branchCoverageSpotBorderThickness); - public static Color ExceptionOriginColor - { - get { return _exceptionOriginBrushAndPen.Color; } - set - { - _exceptionOriginBrushAndPen.Color = value; - Settings.Default.ExceptionOriginColor = value; - _isHighlightingChanged?.Invoke(); - } - } + private readonly Dictionary _brushesAndPens; - private static readonly BrushAndPenContainer _exceptionTraceBrushAndPen = new BrushAndPenContainer(Settings.Default.ExceptionTraceColor, _branchCoverageSpotBorderThickness); - public static Color ExceptionTraceColor - { - get { return _exceptionTraceBrushAndPen.Color; } - set - { - _exceptionTraceBrushAndPen.Color = value; - Settings.Default.ExceptionTraceColor = value; - _isHighlightingChanged?.Invoke(); - } - } + private string _filePath; - private readonly static Dictionary _brushesAndPens = new Dictionary() - { - { CoverageState.Unknown, new BrushAndPenContainer(Colors.Transparent, _branchCoverageSpotBorderThickness) }, - { CoverageState.Uncovered, _uncoveredBrushAndPen }, - { CoverageState.Mixed, _mixedBrushAndPen }, - { CoverageState.Covered, _coveredBrushAndPen } - }; + private readonly SelectTestCommand _selectTestCommand; + private readonly JumpToTestCommand _jumpToTestCommand; + private readonly DebugTestCommand _debugTestCommand; + private readonly IOptions _options; private static HashSet _selectedTests; public static HashSet SelectedTests @@ -127,78 +63,14 @@ public static HashSet SelectedTests } } - private static bool _isShowingLineCoverage = Settings.Default.IsShowingLineCoverage; - public static bool IsShowingLineCoverage - { - get - { - return _isShowingLineCoverage; - } - set - { - _isShowingLineCoverage = value; - Settings.Default.IsShowingLineCoverage = value; - _isHighlightingChanged?.Invoke(); - } - } - - private static bool _isShowingPartialCoverage = Settings.Default.IsShowingPartialCoverage; - public static bool IsShowingPartialCoverage - { - get - { - return _isShowingPartialCoverage; - } - set - { - _isShowingPartialCoverage = value; - Settings.Default.IsShowingPartialCoverage = value; - _isHighlightingChanged?.Invoke(); - } - } - - private static bool _isShowingBranchCoverage = Settings.Default.IsShowingBranchCoverage; - public static bool IsShowingBranchCoverage - { - get - { - return _isShowingBranchCoverage; - } - set - { - _isShowingBranchCoverage = value; - Settings.Default.IsShowingBranchCoverage = value; - _isHighlightingChanged?.Invoke(); - } - } - - private static bool _isShowingExceptions = Settings.Default.IsShowingExceptions; - public static bool IsShowingExceptions - { - get - { - return _isShowingExceptions; - } - set - { - _isShowingExceptions = value; - Settings.Default.IsShowingExceptions = value; - _isHighlightingChanged?.Invoke(); - } - } - private static event Action _isHighlightingChanged; - private string _filePath; - - private readonly SelectTestCommand _selectTestCommand; - private readonly JumpToTestCommand _jumpToTestCommand; - private readonly DebugTestCommand _debugTestCommand; public LineCoverageAdornment( IWpfTextView textView, ITextDocumentFactoryService documentFactory, ICoverageProvider coverageProvider, IResultProvider resultProvider, + IOptions options, SelectTestCommand selectTestCommand, JumpToTestCommand jumpToTestCommand, DebugTestCommand debugTestCommand) @@ -206,6 +78,22 @@ public LineCoverageAdornment( if (textView == null) throw new ArgumentNullException(nameof(textView)); + _options = options; + _selectedBrushAndPen = new BrushAndPenContainer(_options.SelectedColor, _branchCoverageSpotBorderThickness); + _coveredBrushAndPen = new BrushAndPenContainer(_options.CoveredColor, _branchCoverageSpotBorderThickness); + _mixedBrushAndPen = new BrushAndPenContainer(_options.MixedColor, _branchCoverageSpotBorderThickness); + _uncoveredBrushAndPen = new BrushAndPenContainer(_options.UncoveredColor, _branchCoverageSpotBorderThickness); + _exceptionOriginBrushAndPen = new BrushAndPenContainer(_options.ExceptionOriginColor, _branchCoverageSpotBorderThickness); + _exceptionTraceBrushAndPen = new BrushAndPenContainer(_options.ExceptionTraceColor, _branchCoverageSpotBorderThickness); + + _brushesAndPens = new Dictionary() + { + { CoverageState.Unknown, new BrushAndPenContainer(Colors.Transparent, _branchCoverageSpotBorderThickness) }, + { CoverageState.Uncovered, _uncoveredBrushAndPen }, + { CoverageState.Mixed, _mixedBrushAndPen }, + { CoverageState.Covered, _coveredBrushAndPen } + }; + _documentFactory = documentFactory; _textView = textView; @@ -226,9 +114,39 @@ public LineCoverageAdornment( UpdateCoverage(); UpdateResults(); + options.PropertyChanged += OnOptionsPropertyChanged; _isHighlightingChanged += UpdateAllLines; } + private string[] _visualizationProperties = new[] + { + nameof(IOptions.SelectedColor), + nameof(IOptions.CoveredColor), + nameof(IOptions.MixedColor), + nameof(IOptions.UncoveredColor), + nameof(IOptions.ExceptionOriginColor), + nameof(IOptions.ExceptionTraceColor), + nameof(IOptions.IsShowingLineCoverage), + nameof(IOptions.IsShowingPartialCoverage), + nameof(IOptions.IsShowingBranchCoverage), + nameof(IOptions.IsShowingExceptions) + }; + + private void OnOptionsPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == null || _visualizationProperties.Contains(e.PropertyName)) + { + _selectedBrushAndPen.Color = _options.SelectedColor; + _coveredBrushAndPen.Color = _options.CoveredColor; + _mixedBrushAndPen.Color = _options.MixedColor; + _uncoveredBrushAndPen.Color = _options.UncoveredColor; + _exceptionOriginBrushAndPen.Color = _options.ExceptionOriginColor; + _exceptionTraceBrushAndPen.Color = _options.ExceptionTraceColor; + + UpdateAllLines(); + } + } + private bool TryInitilaizeFilePath() { if (_filePath == null) @@ -286,12 +204,12 @@ private void UpdateLine(ITextViewLine line) if (coverage.SequenceCoverageState != CoverageState.Unknown) { - if (IsShowingLineCoverage) + if (_options.IsShowingLineCoverage) { AddSequenceAdornment(line, span, coverage); } - if (IsShowingPartialCoverage) + if (_options.IsShowingPartialCoverage) { AddUncoveredAdornment(snapshotLine, span, coverage); } @@ -299,12 +217,12 @@ private void UpdateLine(ITextViewLine line) if (line.IsFirstTextViewLineForSnapshotLine) { - if (IsShowingBranchCoverage && coverage.SequenceCoverageState != CoverageState.Unknown) + if (_options.IsShowingBranchCoverage && coverage.SequenceCoverageState != CoverageState.Unknown) { AddBranchAdornment(line, span, coverage); } - if (IsShowingExceptions) + if (_options.IsShowingExceptions) { AddLineResultAdornment(line, span, results); } diff --git a/AxoCover/Models/AxoTestRunner.cs b/AxoCover/Models/AxoTestRunner.cs index 3e096cf..70d9d5d 100644 --- a/AxoCover/Models/AxoTestRunner.cs +++ b/AxoCover/Models/AxoTestRunner.cs @@ -4,7 +4,6 @@ using AxoCover.Models.Data; using AxoCover.Models.Data.CoverageReport; using AxoCover.Models.Extensions; -using AxoCover.Properties; using System; using System.Collections.Generic; using System.IO; @@ -18,15 +17,17 @@ public class AxoTestRunner : TestRunner private ExecutionProcess _executionProcess; private readonly IEditorContext _editorContext; private readonly IStorageController _storageController; + private readonly IOptions _options; private readonly TimeSpan _debuggerTimeout = TimeSpan.FromSeconds(10); - public AxoTestRunner(IEditorContext editorContext, IStorageController storageController) + public AxoTestRunner(IEditorContext editorContext, IStorageController storageController, IOptions options) { _editorContext = editorContext; _storageController = storageController; + _options = options; } - protected override TestReport RunTests(TestItem testItem, string testSettings, bool isCovering, bool isDebugging) + protected override TestReport RunTests(TestItem testItem, bool isCovering, bool isDebugging) { List testResults = new List(); try @@ -48,12 +49,24 @@ protected override TestReport RunTests(TestItem testItem, string testSettings, b var solution = testItem.GetParent(); if (isCovering) { - var coverageReportPath = Path.Combine(outputDirectory, "coverageReport.xml"); - hostProcessInfo = new OpenCoverProcessInfo(solution.CodeAssemblies, solution.TestAssemblies, coverageReportPath); + var openCoverOptions = new OpenCoverOptions() + { + CodeAssemblies = solution.CodeAssemblies, + TestAssemblies = solution.TestAssemblies, + CoverageReportPath = Path.Combine(outputDirectory, "coverageReport.xml"), + IsCoveringByTest = _options.IsCoveringByTest, + IsIncludingSolutionAssemblies = _options.IsIncludingSolutionAssemblies, + IsExcludingTestAssemblies = _options.IsExcludingTestAssemblies, + ExcludeAttributes = _options.ExcludeAttributes, + ExcludeDirectories = _options.ExcludeDirectories, + ExcludeFiles = _options.ExcludeFiles, + Filters = _options.Filters + }; + hostProcessInfo = new OpenCoverProcessInfo(openCoverOptions); } var finishEvent = new ManualResetEvent(false); - _executionProcess = ExecutionProcess.Create(hostProcessInfo, Settings.Default.TestPlatform); + _executionProcess = ExecutionProcess.Create(hostProcessInfo, _options.TestPlatform); _executionProcess.MessageReceived += (o, e) => OnTestLogAdded(e.Value); _executionProcess.TestStarted += (o, e) => { @@ -99,8 +112,8 @@ protected override TestReport RunTests(TestItem testItem, string testSettings, b var options = new TestExecutionOptions() { AdapterSources = AdapterExtensions.GetAdapters(), - RunSettingsPath = testSettings, - ApartmentState = Settings.Default.TestApartmentState, + RunSettingsPath = _options.TestSettings, + ApartmentState = _options.TestApartmentState, OutputPath = outputDirectory, SolutionPath = solution.FilePath }; diff --git a/AxoCover/Models/ContainerProvider.cs b/AxoCover/Models/ContainerProvider.cs index 0a06cd4..b3abee5 100644 --- a/AxoCover/Models/ContainerProvider.cs +++ b/AxoCover/Models/ContainerProvider.cs @@ -8,19 +8,20 @@ namespace AxoCover.Models { public static class ContainerProvider { - public static UnityContainer Container; - - public static void Initialize() + private static IUnityContainer _container; + public static IUnityContainer Container { - if (Container != null) + get { - return; - } + if (_container == null) + { + Assembly.LoadFrom(AdapterExtensions.GetTestPlatformPath()); - Assembly.LoadFrom(AdapterExtensions.GetTestPlatformPath()); - - Container = new UnityContainer(); - RegisterTypes(); + _container = new UnityContainer(); + RegisterTypes(); + } + return _container; + } } private static void RegisterTypes() @@ -36,6 +37,7 @@ private static void RegisterTypes() Container.RegisterType(new ContainerControlledLifetimeManager()); Container.RegisterType(new ContainerControlledLifetimeManager()); Container.RegisterType(new ContainerControlledLifetimeManager()); + Container.RegisterType(new ContainerControlledLifetimeManager()); Container.RegisterInstance(new SelectTestCommand()); Container.RegisterInstance(new JumpToTestCommand()); Container.RegisterInstance(new DebugTestCommand()); diff --git a/AxoCover/Models/Data/OpenCoverOptions.cs b/AxoCover/Models/Data/OpenCoverOptions.cs new file mode 100644 index 0000000..a2b97b1 --- /dev/null +++ b/AxoCover/Models/Data/OpenCoverOptions.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; + +namespace AxoCover.Models.Data +{ + public class OpenCoverOptions + { + public IEnumerable CodeAssemblies { get; set; } + public IEnumerable TestAssemblies { get; set; } + public string CoverageReportPath { get; set; } + public bool IsCoveringByTest { get; set; } + public bool IsIncludingSolutionAssemblies { get; set; } + public bool IsExcludingTestAssemblies { get; set; } + public string ExcludeAttributes { get; set; } + public string ExcludeFiles { get; set; } + public string ExcludeDirectories { get; set; } + public string Filters { get; set; } + } +} diff --git a/AxoCover/Models/HockeyClient.cs b/AxoCover/Models/HockeyClient.cs index 27ed7c0..eaca53c 100644 --- a/AxoCover/Models/HockeyClient.cs +++ b/AxoCover/Models/HockeyClient.cs @@ -1,5 +1,4 @@ using AxoCover.Models.Extensions; -using AxoCover.Properties; using System; using System.Diagnostics; using System.IO; @@ -33,17 +32,17 @@ public class HockeyClient : TelemetryManager, IDisposable private readonly Regex _stackRegex; - public HockeyClient(IEditorContext editorContext) - : base(editorContext) + public HockeyClient(IEditorContext editorContext, IOptions options) + : base(editorContext, options) { - var installationId = Settings.Default.InstallationId; + var installationId = options.InstallationId; if (installationId == Guid.Empty) { installationId = Guid.NewGuid(); - Settings.Default.InstallationId = installationId; + options.InstallationId = installationId; } - AppId = Settings.Default.TelemetryKey; + AppId = options.TelemetryKey; PackageName = AxoCoverPackage.Manifest.Name; Version = AxoCoverPackage.Manifest.Version; InstallationId = installationId; diff --git a/AxoCover/Models/IOptions.cs b/AxoCover/Models/IOptions.cs new file mode 100644 index 0000000..8404d4e --- /dev/null +++ b/AxoCover/Models/IOptions.cs @@ -0,0 +1,42 @@ +using System; +using System.ComponentModel; +using System.Windows.Media; +using AxoCover.Common.Settings; + +namespace AxoCover.Models +{ + public interface IOptions + { + Color CoveredColor { get; set; } + Color ExceptionOriginColor { get; set; } + Color ExceptionTraceColor { get; set; } + string ExcludeAttributes { get; set; } + string ExcludeDirectories { get; set; } + string ExcludeFiles { get; set; } + string FeedbackEmail { get; } + string Filters { get; set; } + Guid InstallationId { get; set; } + bool IsCoveringByTest { get; set; } + bool IsExcludingTestAssemblies { get; set; } + bool IsIncludingSolutionAssemblies { get; set; } + bool IsShowingBranchCoverage { get; set; } + bool IsShowingExceptions { get; set; } + bool IsShowingLineCoverage { get; set; } + bool IsShowingPartialCoverage { get; set; } + string IssuesUrl { get; } + bool IsTelemetryEnabled { get; set; } + bool IsTelemetryModeSelected { get; set; } + Color MixedColor { get; set; } + string TestSettings { get; set; } + Color SelectedColor { get; set; } + string SolutionSettingsPath { get; } + string SourceCodeUrl { get; } + string TelemetryKey { get; } + TestApartmentState TestApartmentState { get; set; } + TestPlatform TestPlatform { get; set; } + string TestRunner { get; set; } + Color UncoveredColor { get; set; } + + event PropertyChangedEventHandler PropertyChanged; + } +} \ No newline at end of file diff --git a/AxoCover/Models/IStorageController.cs b/AxoCover/Models/IStorageController.cs index fba4801..b91cd3e 100644 --- a/AxoCover/Models/IStorageController.cs +++ b/AxoCover/Models/IStorageController.cs @@ -5,6 +5,7 @@ namespace AxoCover.Models { public interface IStorageController { + string AxoCoverRoot { get; } string CreateTestRunDirectory(); string CreateReportDirectory(); string[] GetOutputDirectories(); diff --git a/AxoCover/Models/ITestRunner.cs b/AxoCover/Models/ITestRunner.cs index 5562a85..ef7e39e 100644 --- a/AxoCover/Models/ITestRunner.cs +++ b/AxoCover/Models/ITestRunner.cs @@ -8,7 +8,7 @@ namespace AxoCover.Models { public interface ITestRunner { - Task RunTestsAsync(TestItem testItem, string testSettings = null, bool isCovering = true, bool isDebugging = false); + Task RunTestsAsync(TestItem testItem, bool isCovering = true, bool isDebugging = false); Task AbortTestsAsync(); bool IsBusy { get; } diff --git a/AxoCover/Models/MultiplexedTestRunner.cs b/AxoCover/Models/MultiplexedTestRunner.cs index 2a094c5..6169fc6 100644 --- a/AxoCover/Models/MultiplexedTestRunner.cs +++ b/AxoCover/Models/MultiplexedTestRunner.cs @@ -1,9 +1,9 @@ using AxoCover.Common.Events; using AxoCover.Models.Data; using AxoCover.Models.Events; -using AxoCover.Properties; using Microsoft.Practices.Unity; using System; +using System.ComponentModel; using System.Linq; using System.Threading.Tasks; @@ -28,13 +28,12 @@ public bool IsBusy } } - public MultiplexedTestRunner(IUnityContainer container) : base(container) + private readonly IOptions _options; + + public MultiplexedTestRunner(IUnityContainer container, IOptions options) : base(container) { - var selectedImlementation = Settings.Default.TestRunner; - if (Implementations.Contains(selectedImlementation)) - { - Implementation = selectedImlementation; - } + _options = options; + UpdateImplementation(); foreach (var implementation in _implementations.Values) { @@ -47,22 +46,32 @@ public MultiplexedTestRunner(IUnityContainer container) : base(container) implementation.TestsFinished += (o, e) => TestsFinished?.Invoke(this, e); implementation.TestsStarted += (o, e) => TestsStarted?.Invoke(this, e); } + + options.PropertyChanged += OnOptionChanged; } - public Task RunTestsAsync(TestItem testItem, string testSettings = null, bool isCovering = true, bool isDebugging = false) + private void UpdateImplementation() { - return _implementation.RunTestsAsync(testItem, testSettings, isCovering, isDebugging); + var selectedImlementation = _options.TestRunner; + if (Implementations.Contains(selectedImlementation)) + { + Implementation = selectedImlementation; + } } - public Task AbortTestsAsync() + private void OnOptionChanged(object sender, PropertyChangedEventArgs e) { - return _implementation.AbortTestsAsync(); + if (e.PropertyName == nameof(IOptions.TestRunner)) UpdateImplementation(); + } + + public Task RunTestsAsync(TestItem testItem, bool isCovering = true, bool isDebugging = false) + { + return _implementation.RunTestsAsync(testItem, isCovering, isDebugging); } - protected override void OnImplementationChanged() + public Task AbortTestsAsync() { - Settings.Default.TestRunner = Implementation; - base.OnImplementationChanged(); + return _implementation.AbortTestsAsync(); } } } diff --git a/AxoCover/Models/OpenCoverProcessInfo.cs b/AxoCover/Models/OpenCoverProcessInfo.cs index e989d66..e96a29a 100644 --- a/AxoCover/Models/OpenCoverProcessInfo.cs +++ b/AxoCover/Models/OpenCoverProcessInfo.cs @@ -1,6 +1,6 @@ using AxoCover.Common.Extensions; using AxoCover.Common.ProcessHost; -using AxoCover.Properties; +using AxoCover.Models.Data; using System; using System.Collections.Generic; using System.Linq; @@ -39,53 +39,53 @@ public string FilePath public string CoverageReportPath { get; private set; } - public OpenCoverProcessInfo(IEnumerable codeAssemblies, IEnumerable testAssemblies, string coverageReportPath) + public OpenCoverProcessInfo(OpenCoverOptions options) { - CoverageReportPath = coverageReportPath; - _baseArguments = GetSettingsBasedArguments(codeAssemblies, testAssemblies) + $"-mergebyhash -output:\"{coverageReportPath}\" -register:user"; + CoverageReportPath = options.CoverageReportPath; + _baseArguments = GetSettingsBasedArguments(options) + $"-mergebyhash -output:\"{options.CoverageReportPath}\" -register:user"; } - public static string GetSettingsBasedArguments(IEnumerable codeAssemblies, IEnumerable testAssemblies) + private static string GetSettingsBasedArguments(OpenCoverOptions options) { var arguments = string.Empty; - if (Settings.Default.IsCoveringByTest) + if (options.IsCoveringByTest) { - arguments += " -coverbytest:" + string.Join(";", testAssemblies.Select(p => "*" + p + "*")); + arguments += " -coverbytest:" + string.Join(";", options.TestAssemblies.Select(p => "*" + p + "*")); } - if (!string.IsNullOrWhiteSpace(Settings.Default.ExcludeAttributes)) + if (!string.IsNullOrWhiteSpace(options.ExcludeAttributes)) { - arguments += $" \"-excludebyattribute:{Settings.Default.ExcludeAttributes}\""; + arguments += $" \"-excludebyattribute:{options.ExcludeAttributes}\""; } - if (!string.IsNullOrWhiteSpace(Settings.Default.ExcludeFiles)) + if (!string.IsNullOrWhiteSpace(options.ExcludeFiles)) { - arguments += $" \"-excludebyfile:{Settings.Default.ExcludeFiles}\""; + arguments += $" \"-excludebyfile:{options.ExcludeFiles}\""; } - if (!string.IsNullOrWhiteSpace(Settings.Default.ExcludeDirectories)) + if (!string.IsNullOrWhiteSpace(options.ExcludeDirectories)) { - arguments += $" \"-excludedirs:{Settings.Default.ExcludeDirectories}\""; + arguments += $" \"-excludedirs:{options.ExcludeDirectories}\""; } var filters = string.Empty; - if (Settings.Default.IsIncludingSolutionAssemblies) + if (options.IsIncludingSolutionAssemblies) { - filters += GetAssemblyList(codeAssemblies); + filters += GetAssemblyList(options.CodeAssemblies); - if (!Settings.Default.IsExcludingTestAssemblies) + if (!options.IsExcludingTestAssemblies) { - filters += GetAssemblyList(testAssemblies); + filters += GetAssemblyList(options.TestAssemblies); } } - else if (!string.IsNullOrWhiteSpace(Settings.Default.Filters)) + else if (!string.IsNullOrWhiteSpace(options.Filters)) { - filters += Settings.Default.Filters; + filters += options.Filters; - if (Settings.Default.IsExcludingTestAssemblies) + if (options.IsExcludingTestAssemblies) { - filters += GetAssemblyList(testAssemblies, false); + filters += GetAssemblyList(options.TestAssemblies, false); } } diff --git a/AxoCover/Models/Options.cs b/AxoCover/Models/Options.cs new file mode 100644 index 0000000..9e7b5bb --- /dev/null +++ b/AxoCover/Models/Options.cs @@ -0,0 +1,288 @@ +using AxoCover.Common.Extensions; +using AxoCover.Common.Settings; +using AxoCover.Properties; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System; +using System.ComponentModel; +using System.IO; +using System.Windows; +using System.Windows.Media; + +namespace AxoCover.Models +{ + public class Options : INotifyPropertyChanged, IOptions + { + public event PropertyChangedEventHandler PropertyChanged; + + #region Test settings + public string TestRunner + { + get { return Settings.Default.TestRunner; } + set { Settings.Default.TestRunner = value; } + } + + [JsonConverter(typeof(StringEnumConverter))] + public TestPlatform TestPlatform + { + get { return Settings.Default.TestPlatform; } + set { Settings.Default.TestPlatform = value; } + } + + [JsonConverter(typeof(StringEnumConverter))] + public TestApartmentState TestApartmentState + { + get { return Settings.Default.TestApartmentState; } + set { Settings.Default.TestApartmentState = value; } + } + + public string TestSettings + { + get { return Settings.Default.TestSettings; } + set { Settings.Default.TestSettings = value; } + } + #endregion + + #region Coverage settings + public string ExcludeAttributes + { + get { return Settings.Default.ExcludeAttributes; } + set { Settings.Default.ExcludeAttributes = value; } + } + + public string ExcludeFiles + { + get { return Settings.Default.ExcludeFiles; } + set { Settings.Default.ExcludeFiles = value; } + } + + public string ExcludeDirectories + { + get { return Settings.Default.ExcludeDirectories; } + set { Settings.Default.ExcludeDirectories = value; } + } + + public string Filters + { + get { return Settings.Default.Filters; } + set { Settings.Default.Filters = value; } + } + + public bool IsIncludingSolutionAssemblies + { + get { return Settings.Default.IsIncludingSolutionAssemblies; } + set { Settings.Default.IsIncludingSolutionAssemblies = value; } + } + + public bool IsExcludingTestAssemblies + { + get { return Settings.Default.IsExcludingTestAssemblies; } + set { Settings.Default.IsExcludingTestAssemblies = value; } + } + + public bool IsCoveringByTest + { + get { return Settings.Default.IsCoveringByTest; } + set { Settings.Default.IsCoveringByTest = value; } + } + #endregion + + #region Visualization settings + [JsonIgnore] + public bool IsShowingLineCoverage + { + get { return Settings.Default.IsShowingLineCoverage; } + set { Settings.Default.IsShowingLineCoverage = value; } + } + + [JsonIgnore] + public bool IsShowingBranchCoverage + { + get { return Settings.Default.IsShowingBranchCoverage; } + set { Settings.Default.IsShowingBranchCoverage = value; } + } + + [JsonIgnore] + public bool IsShowingExceptions + { + get { return Settings.Default.IsShowingExceptions; } + set { Settings.Default.IsShowingExceptions = value; } + } + + [JsonIgnore] + public bool IsShowingPartialCoverage + { + get { return Settings.Default.IsShowingPartialCoverage; } + set { Settings.Default.IsShowingPartialCoverage = value; } + } + + [JsonIgnore] + public Color CoveredColor + { + get { return Settings.Default.CoveredColor; } + set { Settings.Default.CoveredColor = value; } + } + + [JsonIgnore] + public Color MixedColor + { + get { return Settings.Default.MixedColor; } + set { Settings.Default.MixedColor = value; } + } + + [JsonIgnore] + public Color UncoveredColor + { + get { return Settings.Default.UncoveredColor; } + set { Settings.Default.UncoveredColor = value; } + } + + [JsonIgnore] + public Color SelectedColor + { + get { return Settings.Default.SelectedColor; } + set { Settings.Default.SelectedColor = value; } + } + + [JsonIgnore] + public Color ExceptionOriginColor + { + get { return Settings.Default.ExceptionOriginColor; } + set { Settings.Default.ExceptionOriginColor = value; } + } + + [JsonIgnore] + public Color ExceptionTraceColor + { + get { return Settings.Default.ExceptionTraceColor; } + set { Settings.Default.ExceptionTraceColor = value; } + } + #endregion + + #region Application settings + [JsonIgnore] + public string IssuesUrl + { + get { return Settings.Default.IssuesUrl; } + } + + [JsonIgnore] + public string FeedbackEmail + { + get { return Settings.Default.FeedbackEmail; } + } + + [JsonIgnore] + public string TelemetryKey + { + get { return Settings.Default.TelemetryKey; } + } + + [JsonIgnore] + public Guid InstallationId + { + get { return Settings.Default.InstallationId; } + set { Settings.Default.InstallationId = value; } + } + + [JsonIgnore] + public bool IsTelemetryEnabled + { + get { return Settings.Default.IsTelemetryEnabled; } + set { Settings.Default.IsTelemetryEnabled = value; } + } + + [JsonIgnore] + public bool IsTelemetryModeSelected + { + get { return Settings.Default.IsTelemetryModeSelected; } + set { Settings.Default.IsTelemetryModeSelected = value; } + } + + [JsonIgnore] + public string SourceCodeUrl + { + get { return Settings.Default.SourceCodeUrl; } + } + #endregion + + private readonly IEditorContext _editorContext; + private readonly IStorageController _storageController; + + [JsonIgnore] + public string SolutionSettingsPath + { + get + { + if (_storageController.AxoCoverRoot != null) + { + return Path.Combine(_storageController.AxoCoverRoot, "settings.json"); + } + else + { + return null; + } + } + } + + public Options(IEditorContext editorContext, IStorageController storageController) + { + Settings.Default.SettingChanging += (o, e) => Application.Current.Dispatcher.BeginInvoke(() => OnSettingChanged(e.SettingName)); + _editorContext = editorContext; + _storageController = storageController; + + editorContext.SolutionOpened += OnSolutionOpened; + } + + private void OnSolutionOpened(object sender, EventArgs e) + { + TryLoadFrom(SolutionSettingsPath); + } + + private bool TryLoadFrom(string path) + { + if (File.Exists(path)) + { + try + { + var text = File.ReadAllText(path); + JsonConvert.PopulateObject(text, this); + return true; + } + catch (Exception e) + { + _editorContext.WriteToLog($"Could not load solution settings from: {path}.\r\n" + e.GetDescription()); + } + } + + return false; + } + + private bool TrySaveTo(string path) + { + if (path != null) + { + try + { + Directory.CreateDirectory(Path.GetDirectoryName(path)); + var text = JsonConvert.SerializeObject(this, Formatting.Indented); + File.WriteAllText(path, text); + return true; + } + catch (Exception e) + { + _editorContext.WriteToLog($"Could not save solution settings to: {path}.\r\n" + e.GetDescription()); + } + } + + return false; + } + + private void OnSettingChanged(string settingName) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(settingName)); + Settings.Default.Save(); + TrySaveTo(SolutionSettingsPath); + } + } +} diff --git a/AxoCover/Models/TelemetryManager.cs b/AxoCover/Models/TelemetryManager.cs index 2e986f0..a173306 100644 --- a/AxoCover/Models/TelemetryManager.cs +++ b/AxoCover/Models/TelemetryManager.cs @@ -1,5 +1,4 @@ using AxoCover.Common.Extensions; -using AxoCover.Properties; using System; using System.Diagnostics; using System.Threading.Tasks; @@ -11,16 +10,18 @@ namespace AxoCover.Models public abstract class TelemetryManager : ITelemetryManager { protected IEditorContext _editorContext; + protected IOptions _options; public bool IsTelemetryEnabled { - get { return Settings.Default.IsTelemetryEnabled; } - set { Settings.Default.IsTelemetryEnabled = value; } + get { return _options.IsTelemetryEnabled; } + set { _options.IsTelemetryEnabled = value; } } - public TelemetryManager(IEditorContext editorContext) + public TelemetryManager(IEditorContext editorContext, IOptions options) { _editorContext = editorContext; + _options = options; Application.Current.DispatcherUnhandledException += OnDispatcherUnhandledException; } diff --git a/AxoCover/Models/TestRunner.cs b/AxoCover/Models/TestRunner.cs index c598bb3..c22a932 100644 --- a/AxoCover/Models/TestRunner.cs +++ b/AxoCover/Models/TestRunner.cs @@ -38,7 +38,7 @@ public bool IsBusy } } - public Task RunTestsAsync(TestItem testItem, string testSettings = null, bool isCovering = true, bool isDebugging = false) + public Task RunTestsAsync(TestItem testItem, bool isCovering = true, bool isDebugging = false) { if (IsBusy) { @@ -50,7 +50,7 @@ public Task RunTestsAsync(TestItem testItem, string testSettings = null, bool is try { OnTestLogAdded(Resources.TestExecutionStarted); - var result = RunTests(testItem, testSettings, isCovering, isDebugging); + var result = RunTests(testItem, isCovering, isDebugging); OnTestsFinished(result); OnTestLogAdded(Resources.TestExecutionFinished); } @@ -77,7 +77,7 @@ public Task RunTestsAsync(TestItem testItem, string testSettings = null, bool is return _testTask; } - protected abstract TestReport RunTests(TestItem testItem, string testSettings, bool isCovering, bool isDebugging); + protected abstract TestReport RunTests(TestItem testItem, bool isCovering, bool isDebugging); protected void OnTestLogAdded(string text) { @@ -127,10 +127,5 @@ public Task AbortTestsAsync() } protected abstract void AbortTests(); - - protected string GetSettingsBasedArguments(IEnumerable codeAssemblies, IEnumerable testAssemblies) - { - return OpenCoverProcessInfo.GetSettingsBasedArguments(codeAssemblies, testAssemblies); - } } } diff --git a/AxoCover/Properties/Settings.Designer.cs b/AxoCover/Properties/Settings.Designer.cs index ad3d331..8eb4b47 100644 --- a/AxoCover/Properties/Settings.Designer.cs +++ b/AxoCover/Properties/Settings.Designer.cs @@ -334,5 +334,17 @@ public string SourceCodeUrl { this["TestApartmentState"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string TestSettings { + get { + return ((string)(this["TestSettings"])); + } + set { + this["TestSettings"] = value; + } + } } } diff --git a/AxoCover/Properties/Settings.settings b/AxoCover/Properties/Settings.settings index 0ad14a0..218cc6f 100644 --- a/AxoCover/Properties/Settings.settings +++ b/AxoCover/Properties/Settings.settings @@ -83,5 +83,8 @@ STA + + + \ No newline at end of file diff --git a/AxoCover/TextViewCreationListener.cs b/AxoCover/TextViewCreationListener.cs index e15c988..277e2cf 100644 --- a/AxoCover/TextViewCreationListener.cs +++ b/AxoCover/TextViewCreationListener.cs @@ -26,7 +26,7 @@ public sealed class TextViewCreationListener : IWpfTextViewCreationListener public TextViewCreationListener() { - ContainerProvider.Initialize(); + } public void TextViewCreated(IWpfTextView textView) diff --git a/AxoCover/ViewModels/SettingsViewModel.cs b/AxoCover/ViewModels/SettingsViewModel.cs index 1700810..d5196e3 100644 --- a/AxoCover/ViewModels/SettingsViewModel.cs +++ b/AxoCover/ViewModels/SettingsViewModel.cs @@ -1,8 +1,6 @@ -using AxoCover.Common.Settings; -using AxoCover.Models; +using AxoCover.Models; using AxoCover.Models.Data; using AxoCover.Models.Extensions; -using AxoCover.Properties; using AxoCover.Views; using System; using System.Collections.Generic; @@ -11,7 +9,6 @@ using System.Reflection; using System.Text.RegularExpressions; using System.Windows.Input; -using System.Windows.Media; namespace AxoCover.ViewModels { @@ -20,7 +17,7 @@ public class SettingsViewModel : ViewModel private readonly IEditorContext _editorContext; private readonly IStorageController _storageController; private readonly ITestRunner _testRunner; - private readonly ITelemetryManager _telemetryManager; + private readonly IOptions _options; public PackageManifest Manifest { @@ -38,283 +35,11 @@ public string AssemblyVersion } } - public bool IsTelemetryEnabled + public IOptions Options { get { - return _telemetryManager.IsTelemetryEnabled; - } - set - { - _telemetryManager.IsTelemetryEnabled = value; - NotifyPropertyChanged(nameof(IsTelemetryEnabled)); - } - } - - public bool IsShowingLineCoverage - { - get - { - return LineCoverageAdornment.IsShowingLineCoverage; - } - set - { - LineCoverageAdornment.IsShowingLineCoverage = value; - NotifyPropertyChanged(nameof(IsShowingLineCoverage)); - } - } - - public bool IsShowingBranchCoverage - { - get - { - return LineCoverageAdornment.IsShowingBranchCoverage; - } - set - { - LineCoverageAdornment.IsShowingBranchCoverage = value; - NotifyPropertyChanged(nameof(IsShowingBranchCoverage)); - } - } - - public bool IsShowingExceptions - { - get - { - return LineCoverageAdornment.IsShowingExceptions; - } - set - { - LineCoverageAdornment.IsShowingExceptions = value; - NotifyPropertyChanged(nameof(IsShowingExceptions)); - } - } - - public bool IsShowingPartialCoverage - { - get - { - return LineCoverageAdornment.IsShowingPartialCoverage; - } - set - { - LineCoverageAdornment.IsShowingPartialCoverage = value; - NotifyPropertyChanged(nameof(IsShowingPartialCoverage)); - } - } - - public Color SelectedColor - { - get - { - return LineCoverageAdornment.SelectedColor; - } - set - { - LineCoverageAdornment.SelectedColor = value; - NotifyPropertyChanged(nameof(SelectedColor)); - } - } - - public Color CoveredColor - { - get - { - return LineCoverageAdornment.CoveredColor; - } - set - { - LineCoverageAdornment.CoveredColor = value; - NotifyPropertyChanged(nameof(CoveredColor)); - } - } - - public Color MixedColor - { - get - { - return LineCoverageAdornment.MixedColor; - } - set - { - LineCoverageAdornment.MixedColor = value; - NotifyPropertyChanged(nameof(MixedColor)); - } - } - - public Color UncoveredColor - { - get - { - return LineCoverageAdornment.UncoveredColor; - } - set - { - LineCoverageAdornment.UncoveredColor = value; - NotifyPropertyChanged(nameof(UncoveredColor)); - } - } - - public Color ExceptionOriginColor - { - get - { - return LineCoverageAdornment.ExceptionOriginColor; - } - set - { - LineCoverageAdornment.ExceptionOriginColor = value; - NotifyPropertyChanged(nameof(ExceptionOriginColor)); - } - } - - public Color ExceptionTraceColor - { - get - { - return LineCoverageAdornment.ExceptionTraceColor; - } - set - { - LineCoverageAdornment.ExceptionTraceColor = value; - NotifyPropertyChanged(nameof(ExceptionTraceColor)); - } - } - - private bool _isCoveringByTest = Settings.Default.IsCoveringByTest; - public bool IsCoveringByTest - { - get - { - return _isCoveringByTest; - } - set - { - _isCoveringByTest = value; - Settings.Default.IsCoveringByTest = value; - if (value) IsExcludingTestAssemblies = false; - NotifyPropertyChanged(nameof(IsCoveringByTest)); - } - } - - private string _excludeAttributes = Settings.Default.ExcludeAttributes; - public string ExcludeAttributes - { - get - { - return _excludeAttributes; - } - set - { - _excludeAttributes = value; - Settings.Default.ExcludeAttributes = value; - NotifyPropertyChanged(nameof(ExcludeAttributes)); - } - } - - private string _excludeFiles = Settings.Default.ExcludeFiles; - public string ExcludeFiles - { - get - { - return _excludeFiles; - } - set - { - _excludeFiles = value; - Settings.Default.ExcludeFiles = value; - NotifyPropertyChanged(nameof(ExcludeFiles)); - } - } - - private string _excludeDirectories = Settings.Default.ExcludeDirectories; - public string ExcludeDirectories - { - get - { - return _excludeDirectories; - } - set - { - _excludeDirectories = value; - Settings.Default.ExcludeDirectories = value; - NotifyPropertyChanged(nameof(ExcludeDirectories)); - } - } - - private string _filters = Settings.Default.Filters; - public string Filters - { - get - { - return _filters; - } - set - { - _filters = value; - Settings.Default.Filters = value; - NotifyPropertyChanged(nameof(Filters)); - } - } - - private bool _isIncludingSolutionAssemblies = Settings.Default.IsIncludingSolutionAssemblies; - public bool IsIncludingSolutionAssemblies - { - get - { - return _isIncludingSolutionAssemblies; - } - set - { - _isIncludingSolutionAssemblies = value; - Settings.Default.IsIncludingSolutionAssemblies = value; - NotifyPropertyChanged(nameof(IsIncludingSolutionAssemblies)); - } - } - - private bool _isExcludingTestAssemblies = Settings.Default.IsExcludingTestAssemblies; - public bool IsExcludingTestAssemblies - { - get - { - return _isExcludingTestAssemblies; - } - set - { - _isExcludingTestAssemblies = value; - Settings.Default.IsExcludingTestAssemblies = value; - if (value) IsCoveringByTest = false; - NotifyPropertyChanged(nameof(IsExcludingTestAssemblies)); - } - } - - private TestPlatform _testPlatform; - public TestPlatform TestPlatform - { - get - { - return _testPlatform; - } - set - { - _testPlatform = value; - Settings.Default.TestPlatform = value; - NotifyPropertyChanged(nameof(TestPlatform)); - } - } - - private TestApartmentState _testApartmentState; - public TestApartmentState TestApartmentState - { - get - { - return _testApartmentState; - } - set - { - _testApartmentState = value; - Settings.Default.TestApartmentState = value; - NotifyPropertyChanged(nameof(TestApartmentState)); + return _options; } } @@ -336,20 +61,6 @@ public ObservableEnumeration TestSettingsFiles } } - private string _selectedTestSettings; - public string SelectedTestSettings - { - get - { - return _selectedTestSettings; - } - set - { - _selectedTestSettings = value; - NotifyPropertyChanged(nameof(SelectedTestSettings)); - } - } - public bool CanSelectTestRunner { get @@ -366,19 +77,6 @@ public IEnumerable TestRunners } } - public string SelectedTestRunner - { - get - { - return (_testRunner as IMultiplexer).Implementation; - } - set - { - (_testRunner as IMultiplexer).Implementation = value; - NotifyPropertyChanged(nameof(SelectedTestRunner)); - } - } - public ICommand OpenWebSiteCommand { get @@ -391,7 +89,7 @@ public ICommand OpenIssuesCommand { get { - return new DelegateCommand(p => Process.Start(Settings.Default.IssuesUrl)); + return new DelegateCommand(p => Process.Start(Options.IssuesUrl)); } } @@ -399,7 +97,7 @@ public ICommand OpenSourceCodeCommand { get { - return new DelegateCommand(p => Process.Start(Settings.Default.SourceCodeUrl)); + return new DelegateCommand(p => Process.Start(Options.SourceCodeUrl)); } } @@ -407,7 +105,7 @@ public ICommand SendFeedbackCommand { get { - return new DelegateCommand(p => Process.Start("mailto:" + Settings.Default.FeedbackEmail)); + return new DelegateCommand(p => Process.Start("mailto:" + Options.FeedbackEmail)); } } @@ -467,10 +165,7 @@ public ICommand ClearTestSettingsCommand { get { - return new DelegateCommand( - p => SelectedTestSettings = null, - p => SelectedTestSettings != null, - p => ExecuteOnPropertyChange(p, nameof(SelectedTestSettings))); + return new DelegateCommand(p => Options.TestSettings = null); } } @@ -486,12 +181,12 @@ public ICommand NavigateToFileCommand } } - public SettingsViewModel(IEditorContext editorContext, IStorageController storageController, ITestRunner testRunner, ITelemetryManager telemetryManager) + public SettingsViewModel(IEditorContext editorContext, IStorageController storageController, ITestRunner testRunner, ITelemetryManager telemetryManager, IOptions options) { _editorContext = editorContext; _storageController = storageController; _testRunner = testRunner; - _telemetryManager = telemetryManager; + _options = options; _outputDirectories = new ObservableEnumeration(() => storageController.GetOutputDirectories().Select(p => new OutputDirectoryViewModel(p)), (a, b) => StringComparer.OrdinalIgnoreCase.Compare(a.Name, b.Name)); @@ -502,10 +197,10 @@ public SettingsViewModel(IEditorContext editorContext, IStorageController storag editorContext.SolutionOpened += (o, e) => Refresh(); //Fix unsupported state - if (IsExcludingTestAssemblies && IsCoveringByTest) + if (_options.IsExcludingTestAssemblies && _options.IsCoveringByTest) { - IsExcludingTestAssemblies = false; - IsCoveringByTest = false; + _options.IsExcludingTestAssemblies = false; + _options.IsCoveringByTest = false; } } diff --git a/AxoCover/ViewModels/TelemetryIntroductionViewModel.cs b/AxoCover/ViewModels/TelemetryIntroductionViewModel.cs index 3857fa9..ea6be0e 100644 --- a/AxoCover/ViewModels/TelemetryIntroductionViewModel.cs +++ b/AxoCover/ViewModels/TelemetryIntroductionViewModel.cs @@ -1,22 +1,27 @@ -using AxoCover.Properties; +using AxoCover.Models; namespace AxoCover.ViewModels { public class TelemetryIntroductionViewModel : ViewModel { - private bool _isTelemetryEnabled = Settings.Default.IsTelemetryEnabled; + private readonly IOptions _options; + public bool IsTelemetryEnabled { get { - return _isTelemetryEnabled; + return _options.IsTelemetryEnabled; } set { - _isTelemetryEnabled = value; - Settings.Default.IsTelemetryEnabled = value; + _options.IsTelemetryEnabled = value; NotifyPropertyChanged(nameof(IsTelemetryEnabled)); } } + + public TelemetryIntroductionViewModel(IOptions options) + { + _options = options; + } } } diff --git a/AxoCover/ViewModels/TestExplorerViewModel.cs b/AxoCover/ViewModels/TestExplorerViewModel.cs index 2ac21a2..6275b66 100644 --- a/AxoCover/ViewModels/TestExplorerViewModel.cs +++ b/AxoCover/ViewModels/TestExplorerViewModel.cs @@ -380,7 +380,7 @@ public TestExplorerViewModel(IEditorContext editorContext, ITestProvider testPro private void RunTestItem(TestItemViewModel target, bool isCovering, bool isDebugging) { - _testRunner.RunTestsAsync(target.CodeItem, SelectedTestSettings, isCovering, isDebugging); + _testRunner.RunTestsAsync(target.CodeItem, isCovering, isDebugging); target.ScheduleAll(); } diff --git a/AxoCover/Views/SettingsView.xaml b/AxoCover/Views/SettingsView.xaml index 0c87c43..c054572 100644 --- a/AxoCover/Views/SettingsView.xaml +++ b/AxoCover/Views/SettingsView.xaml @@ -18,6 +18,7 @@ + - +