diff --git a/Editor.Tests/Extensions/CommandServiceExtensions.cs b/Editor.Tests/Extensions/CommandServiceExtensions.cs
index 6870e94..ef55e83 100644
--- a/Editor.Tests/Extensions/CommandServiceExtensions.cs
+++ b/Editor.Tests/Extensions/CommandServiceExtensions.cs
@@ -14,6 +14,11 @@ namespace MonoDevelop.Xml.Editor.Tests.Extensions
{
public static class CommandServiceExtensions
{
+ ///
+ /// Enables logging of additional trace information to debug nondeterministic test failures
+ ///
+ public static bool EnableDebugTrace { get; set; }
+
public static void Type (this IEditorCommandHandlerService commandService, string text)
{
foreach (var c in text) {
@@ -22,7 +27,9 @@ public static void Type (this IEditorCommandHandlerService commandService, strin
Enter (commandService);
break;
default:
- System.Console.WriteLine($"Typing '{c}'");
+ if (EnableDebugTrace) {
+ LogTrace ($"Typing '{c}'");
+ }
commandService.CheckAndExecute ((v, b) => new TypeCharCommandArgs (v, b, c));
break;
}
@@ -30,10 +37,20 @@ public static void Type (this IEditorCommandHandlerService commandService, strin
}
public static void Enter (this IEditorCommandHandlerService commandService)
- => commandService.CheckAndExecute ((v, b) => new ReturnKeyCommandArgs (v, b));
+ {
+ if (EnableDebugTrace) {
+ LogTrace ("Invoking return key");
+ }
+ commandService.CheckAndExecute ((v, b) => new ReturnKeyCommandArgs (v, b));
+ }
public static void InvokeCompletion (this IEditorCommandHandlerService commandService)
- => commandService.CheckAndExecute ((v, b) => new InvokeCompletionListCommandArgs (v, b));
+ {
+ if (EnableDebugTrace) {
+ LogTrace ("Invoking completion");
+ }
+ commandService.CheckAndExecute ((v, b) => new InvokeCompletionListCommandArgs (v, b));
+ }
public static void CheckAndExecute (
this IEditorCommandHandlerService commandService,
@@ -47,17 +64,44 @@ public static void CheckAndExecute (
throw new InvalidOperationException ($"No handler available for `{typeof (T)}`");
}
- //ensure the computation is completed before we continue typing
if (textView != null) {
if (textView.Properties.TryGetProperty (typeof (IAsyncCompletionSession), out IAsyncCompletionSession session)) {
+ if (EnableDebugTrace) {
+ LogTrace ("Session open");
+ RegisterTraceHandlers (session);
+ }
+ //ensure the computation is completed before we continue typing
session.GetComputedItems (CancellationToken.None);
- Console.WriteLine("Session open");
+ LogTrace ("Session open");
}
} else{
- Console.WriteLine("Session not open");
+ LogTrace ("Session not open");
}
}
+ const string TraceID = "CommandServiceExtensions.Trace";
+
+ static void LogTrace(string message) => Console.WriteLine ($"{TraceID}: {message}");
+
+ static void RegisterTraceHandlers (IAsyncCompletionSession session)
+ {
+ if (session.Properties.TryGetProperty (TraceID, out bool hasHandler)) {
+ return;
+ }
+
+ session.Properties.AddProperty (TraceID, true);
+ session.Dismissed += (s, e) => {
+ LogTrace ($"Session dismissed:\n{Environment.StackTrace}");
+ LogTrace (Environment.StackTrace);
+ };
+ session.ItemCommitted += (s, e) => {
+ LogTrace ($"Session committed '{e.Item.InsertText}':\n{Environment.StackTrace}");
+ };
+ session.ItemsUpdated += (s, e) => {
+ LogTrace ($"Session updated");
+ };
+ }
+
static Action Noop { get; } = new Action (() => { });
static Func Unspecified { get; } = () => CommandState.Unspecified;
}