diff --git a/Terminal.Gui/ConsoleDrivers/AnsiResponseParser/AnsiResponseExpectation.cs b/Terminal.Gui/ConsoleDrivers/AnsiResponseParser/AnsiResponseExpectation.cs index d1245adcc..75fdb308a 100644 --- a/Terminal.Gui/ConsoleDrivers/AnsiResponseParser/AnsiResponseExpectation.cs +++ b/Terminal.Gui/ConsoleDrivers/AnsiResponseParser/AnsiResponseExpectation.cs @@ -1,10 +1,10 @@ #nullable enable namespace Terminal.Gui; -public record AnsiResponseExpectation (string Terminator, Action Response) +internal record AnsiResponseExpectation (string Terminator, Action Response) { public bool Matches (string cur) { return cur.EndsWith (Terminator); } -} +} \ No newline at end of file diff --git a/Terminal.Gui/ConsoleDrivers/AnsiResponseParser/AnsiResponseParser.cs b/Terminal.Gui/ConsoleDrivers/AnsiResponseParser/AnsiResponseParser.cs index 1153e9236..7366e382b 100644 --- a/Terminal.Gui/ConsoleDrivers/AnsiResponseParser/AnsiResponseParser.cs +++ b/Terminal.Gui/ConsoleDrivers/AnsiResponseParser/AnsiResponseParser.cs @@ -213,7 +213,7 @@ internal abstract class AnsiResponseParserBase : IAnsiResponseParser { if (invokeCallback) { - matchingResponse.Response?.Invoke (heldContent.HeldToString ()); + matchingResponse.Response.Invoke (heldContent); } ResetState (); @@ -233,11 +233,11 @@ internal abstract class AnsiResponseParserBase : IAnsiResponseParser { if (persistent) { - persistentExpectations.Add (new (terminator, response)); + persistentExpectations.Add (new (terminator, (h)=>response.Invoke (h.HeldToString ()))); } else { - expectedResponses.Add (new (terminator, response)); + expectedResponses.Add (new (terminator, (h) => response.Invoke (h.HeldToString ()))); } } @@ -287,13 +287,37 @@ internal class AnsiResponseParser : AnsiResponseParserBase public IEnumerable> Release () { - foreach (Tuple h in (IEnumerable>)heldContent.HeldToObjects ()) + foreach (Tuple h in HeldToEnumerable()) { yield return h; } ResetState (); } + + private IEnumerable> HeldToEnumerable () + { + return (IEnumerable>)heldContent.HeldToObjects (); + } + + /// + /// 'Overload' for specifying an expectation that requires the metadata as well as characters. Has + /// a unique name because otherwise most lamdas will give ambiguous overload errors. + /// + /// + /// + /// + public void ExpectResponseT (string terminator, Action>> response, bool persistent) + { + if (persistent) + { + persistentExpectations.Add (new (terminator, (h) => response.Invoke (HeldToEnumerable ()))); + } + else + { + expectedResponses.Add (new (terminator, (h) => response.Invoke (HeldToEnumerable ()))); + } + } } internal class AnsiResponseParser : AnsiResponseParserBase diff --git a/UnitTests/ConsoleDrivers/AnsiResponseParserTests.cs b/UnitTests/ConsoleDrivers/AnsiResponseParserTests.cs index fa7fac4f7..99e71fed0 100644 --- a/UnitTests/ConsoleDrivers/AnsiResponseParserTests.cs +++ b/UnitTests/ConsoleDrivers/AnsiResponseParserTests.cs @@ -1,4 +1,6 @@ -using System.Diagnostics; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; using System.Text; using Xunit.Abstractions; @@ -374,6 +376,44 @@ public class AnsiResponseParserTests (ITestOutputHelper output) Assert.Equal (4, M); // Expected three `M` responses plus the initial value of 1 } + [Fact] + public void TestPersistentResponses_WithMetadata () + { + var p = new AnsiResponseParser (); + + int m = 0; + + var result = new List> (); + + p.ExpectResponseT ("m", (r) => + { + result = r.ToList (); + m++; + }, true); + + // Act - Feed input strings containing ANSI sequences + p.ProcessInput (StringToBatch("\u001b[<0;10;10m")); // Should match and increment `m` + + // Prepare expected result: + var expected = new List> + { + Tuple.Create('\u001b', 0), // Escape character + Tuple.Create('[', 1), + Tuple.Create('<', 2), + Tuple.Create('0', 3), + Tuple.Create(';', 4), + Tuple.Create('1', 5), + Tuple.Create('0', 6), + Tuple.Create(';', 7), + Tuple.Create('1', 8), + Tuple.Create('0', 9), + Tuple.Create('m', 10) + }; + + Assert.Equal (expected.Count, result.Count); // Ensure the count is as expected + Assert.True (expected.SequenceEqual (result), "The result does not match the expected output."); // Check the actual content + } + private Tuple [] StringToBatch (string batch) { return batch.Select ((k) => Tuple.Create (k, tIndex++)).ToArray ();