diff --git a/Src/Roflcopter.Plugin.Tests/TodoItems/TestTodoItemsCountConsumer.cs b/Src/Roflcopter.Plugin.Tests/TodoItems/TestTodoItemsCountConsumer.cs index 7483c65..0036e01 100644 --- a/Src/Roflcopter.Plugin.Tests/TodoItems/TestTodoItemsCountConsumer.cs +++ b/Src/Roflcopter.Plugin.Tests/TodoItems/TestTodoItemsCountConsumer.cs @@ -1,12 +1,13 @@ using System.Collections.Generic; using JetBrains.Annotations; using JetBrains.Application; +using JetBrains.Application.Parts; using JetBrains.DataFlow; using Roflcopter.Plugin.TodoItems; namespace Roflcopter.Plugin.Tests.TodoItems { - [ShellComponent] + [ShellComponent(Instantiation.DemandAnyThreadSafe)] internal class TestTodoItemsCountConsumer : ITodoItemsCountConsumer { [CanBeNull] diff --git a/Src/Roflcopter.Plugin.Tests/TodoItems/TodoItemsCountTests.cs b/Src/Roflcopter.Plugin.Tests/TodoItems/TodoItemsCountTests.cs index 290c6b1..eec55e7 100644 --- a/Src/Roflcopter.Plugin.Tests/TodoItems/TodoItemsCountTests.cs +++ b/Src/Roflcopter.Plugin.Tests/TodoItems/TodoItemsCountTests.cs @@ -4,6 +4,7 @@ using JetBrains.Application.Components; using JetBrains.Application.Settings; using JetBrains.Diagnostics; +using JetBrains.Lifetimes; using JetBrains.ProjectModel; using JetBrains.ReSharper.TestFramework; using NUnit.Framework; @@ -37,7 +38,7 @@ public void TodoItemsCountsWithCondition() Test((consumer, settings) => { var definitionText = "Todo\n Todo [Important] "; - RunGuarded(() => settings.SetValue((TodoItemsCountSettings s) => s.Definitions, definitionText)); + settings.SetValue((TodoItemsCountSettings s) => s.Definitions, definitionText); Assert.That(consumer.TodoItemsCounts.NotNull().Select(x => (x.Definition.ToString(), x.Count)), Is.EqualTo(new[] { @@ -52,7 +53,7 @@ public void TodoItemsCounts_WithNonMatchingName() { Test((consumer, settings) => { - RunGuarded(() => settings.SetValue((TodoItemsCountSettings s) => s.Definitions, "Todo\nNON_MATCHING")); + settings.SetValue((TodoItemsCountSettings s) => s.Definitions, "Todo\nNON_MATCHING"); Assert.That(consumer.TodoItemsCounts.NotNull().Select(x => (x.Definition.ToString(), x.Count)), Is.EqualTo(new[] { @@ -67,7 +68,7 @@ public void TodoItemsCounts_WithDuplicateDefinition() { Test((consumer, settings) => { - RunGuarded(() => settings.SetValue((TodoItemsCountSettings s) => s.Definitions, "Todo\nTodo")); + settings.SetValue((TodoItemsCountSettings s) => s.Definitions, "Todo\nTodo"); Assert.That(consumer.TodoItemsCounts.NotNull().Select(x => (x.Definition.ToString(), x.Count)), Is.EqualTo(new[] { @@ -114,23 +115,24 @@ public void TodoItemsCounts_ConsumerUpdateRequestSignal() private void Test(Action action) { - var files = new[] { "Sample.cs", "Sample.xml" }; + // Use an explicit short-lived lifetime for the "settings transaction" because a) it must be scoped per test, + // and b) the `base.TestLifetime` is destroyed within the test tear-down phase which would raise + // "target dispatcher [...] does not support asynchronous execution or cross-thread marshalling" errors + // (b/c TearDown is not `RunWithAsyncBehaviorAllowed`). - ExecuteWithinSettingsTransaction(settings => + using var temporarySettingsLifetimeDefinition = Lifetime.Define("TemporarySettings"); + + ExecuteWithinSettingsTransactionGuarded(temporarySettingsLifetimeDefinition.Lifetime, (_, settings) => { - WithSingleProject( - files.Select(x => GetTestDataFilePath2(x).FullPath), - (_, solution, _) => - { - Assert.That(solution.GetComponent, Is.Not.Null); - var consumer = ShellInstance.GetComponent(); - - action(consumer, settings); - }); - - // Disable to solve issues with TodoItemsCountProvider-updates during termination of - // the "settings transaction": - settings.SetValue((TodoItemsCountSettings s) => s.IsEnabled, false); + var projectFiles = new[] { "Sample.cs", "Sample.xml" }.Select(x => GetTestDataFilePath2(x).FullPath); + + WithSingleProject(projectFiles, (_, solution, _) => + { + Assert.That(solution.GetComponent, Is.Not.Null); + var consumer = ShellInstance.GetComponent(); + + action(consumer, settings); + }); }); } } diff --git a/Src/Roflcopter.Plugin.Tests/test/data/TodoItems/Sample.cs b/Src/Roflcopter.Plugin.Tests/test/data/TodoItems/Sample.cs index 2832e43..0bd59b6 100644 --- a/Src/Roflcopter.Plugin.Tests/test/data/TodoItems/Sample.cs +++ b/Src/Roflcopter.Plugin.Tests/test/data/TodoItems/Sample.cs @@ -4,9 +4,9 @@ public class Sample { // TODO - // TODO 1 before Important after - // TODO 2 before Important after - // TODO 3 before imPOrTaNt after + // TODO: 1 before Important after + // TODO: 2 before Important after + // TODO: 3 before imPOrTaNt after // BUG: 1 // BUG: 2 diff --git a/Src/Roflcopter.Plugin.Tests/test/data/TodoItems/Sample.xml b/Src/Roflcopter.Plugin.Tests/test/data/TodoItems/Sample.xml index 4459924..fa4b1ac 100644 --- a/Src/Roflcopter.Plugin.Tests/test/data/TodoItems/Sample.xml +++ b/Src/Roflcopter.Plugin.Tests/test/data/TodoItems/Sample.xml @@ -1,4 +1,4 @@  - + diff --git a/Src/Roflcopter.Plugin/TodoItems/Presentation/TodoItemsCountPresenter.cs b/Src/Roflcopter.Plugin/TodoItems/Presentation/TodoItemsCountPresenter.cs index 133a066..fa18c5b 100644 --- a/Src/Roflcopter.Plugin/TodoItems/Presentation/TodoItemsCountPresenter.cs +++ b/Src/Roflcopter.Plugin/TodoItems/Presentation/TodoItemsCountPresenter.cs @@ -6,6 +6,7 @@ using System.Windows.Input; using JetBrains.Annotations; using JetBrains.Application; +using JetBrains.Application.Parts; using JetBrains.Application.Threading; using JetBrains.Application.UI.Actions; using JetBrains.Application.UI.ActionSystem.ActionBar; @@ -21,7 +22,7 @@ namespace Roflcopter.Plugin.TodoItems.Presentation { - [ShellComponent] + [ShellComponent(Instantiation.DemandAnyThreadSafe)] [ExcludeFromCodeCoverage /* manually tested UI code */] public class TodoItemsCountPresenter : IActionBarPatcher, ITodoItemsCountConsumer { diff --git a/Src/Roflcopter.Plugin/TodoItems/TodoItemsCountDefinitionsCachedSettingsReader.cs b/Src/Roflcopter.Plugin/TodoItems/TodoItemsCountDefinitionsCachedSettingsReader.cs index 53aef5d..99c0458 100644 --- a/Src/Roflcopter.Plugin/TodoItems/TodoItemsCountDefinitionsCachedSettingsReader.cs +++ b/Src/Roflcopter.Plugin/TodoItems/TodoItemsCountDefinitionsCachedSettingsReader.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Text.RegularExpressions; using JetBrains.Annotations; +using JetBrains.Application.Parts; using JetBrains.Application.Settings; using JetBrains.Application.Settings.Extentions; using JetBrains.Lifetimes; @@ -9,7 +10,7 @@ namespace Roflcopter.Plugin.TodoItems { - [SolutionComponent] + [SolutionComponent(Instantiation.DemandAnyThreadSafe)] public class TodoItemsCountDefinitionsCachedSettingsReader : ICachedSettingsReader> { private readonly ISettingsStore _settingsStore; diff --git a/Src/Roflcopter.Plugin/TodoItems/TodoItemsCountProvider.cs b/Src/Roflcopter.Plugin/TodoItems/TodoItemsCountProvider.cs index cfa5a4b..aef78b8 100644 --- a/Src/Roflcopter.Plugin/TodoItems/TodoItemsCountProvider.cs +++ b/Src/Roflcopter.Plugin/TodoItems/TodoItemsCountProvider.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; +using JetBrains.Application.Parts; using JetBrains.Application.Settings; using JetBrains.Application.Settings.Extentions; using JetBrains.DataFlow; @@ -16,7 +17,7 @@ namespace Roflcopter.Plugin.TodoItems { - [SolutionComponent] + [SolutionComponent(Instantiation.ContainerAsyncPrimaryThread /* req to inject `MultiplexingTodoManager` */)] public class TodoItemsCountProvider { private static readonly ILogger Logger = JetBrains.Util.Logging.Logger.GetLogger(typeof(TodoItemsCountProvider));