Support for getting the full T set when using generic AnsiResponseParser

This commit is contained in:
tznind
2024-10-26 19:37:32 +01:00
parent 085a0cf32c
commit bdcf36c314
3 changed files with 71 additions and 7 deletions

View File

@@ -1,10 +1,10 @@
#nullable enable
namespace Terminal.Gui;
public record AnsiResponseExpectation (string Terminator, Action<string> Response)
internal record AnsiResponseExpectation (string Terminator, Action<IHeld> Response)
{
public bool Matches (string cur)
{
return cur.EndsWith (Terminator);
}
}
}

View File

@@ -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<T> : AnsiResponseParserBase
public IEnumerable<Tuple<char, T>> Release ()
{
foreach (Tuple<char, T> h in (IEnumerable<Tuple<char, T>>)heldContent.HeldToObjects ())
foreach (Tuple<char, T> h in HeldToEnumerable())
{
yield return h;
}
ResetState ();
}
private IEnumerable<Tuple<char, T>> HeldToEnumerable ()
{
return (IEnumerable<Tuple<char, T>>)heldContent.HeldToObjects ();
}
/// <summary>
/// '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.
/// </summary>
/// <param name="terminator"></param>
/// <param name="response"></param>
/// <param name="persistent"></param>
public void ExpectResponseT (string terminator, Action<IEnumerable<Tuple<char,T>>> 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

View File

@@ -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> ();
int m = 0;
var result = new List<Tuple<char,int>> ();
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<char, int>>
{
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<char, int> [] StringToBatch (string batch)
{
return batch.Select ((k) => Tuple.Create (k, tIndex++)).ToArray ();