| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- #nullable enable
- using Moq;
- namespace DrawingTests;
- public class SixelSupportDetectorTests
- {
- [Fact]
- public void Detect_SetsSupportedAndResolution_WhenDeviceAttributesContain4_AndResolutionResponds()
- {
- // Arrange
- Mock<IDriver> driverMock = new (MockBehavior.Strict);
- // Setup IsLegacyConsole - false means modern terminal with ANSI support
- driverMock.Setup (d => d.IsLegacyConsole).Returns (false);
- // Expect QueueAnsiRequest to be called at least twice:
- // 1) CSI_SendDeviceAttributes (terminator "c")
- // 2) CSI_RequestSixelResolution (terminator "t")
- driverMock.Setup (d => d.QueueAnsiRequest (It.IsAny<AnsiEscapeSequenceRequest> ()))
- .Callback<AnsiEscapeSequenceRequest> (req =>
- {
- // Respond to the SendDeviceAttributes request with a value that indicates support (contains "4")
- if (req.Request == EscSeqUtils.CSI_SendDeviceAttributes.Request)
- {
- req.ResponseReceived.Invoke ("1;4;7c");
- }
- else if (req.Request == EscSeqUtils.CSI_RequestSixelResolution.Request)
- {
- // Reply with a resolution response matching regex "\[\d+;(\d+);(\d+)t$"
- // Group 1 -> ry, Group 2 -> rx. The detector constructs resolution as new(rx, ry)
- req.ResponseReceived.Invoke ("[6;20;10t");
- }
- else
- {
- // Any other request - call abandoned to avoid hanging
- req.Abandoned?.Invoke ();
- }
- })
- .Verifiable ();
- var detector = new SixelSupportDetector (driverMock.Object);
- SixelSupportResult? final = null;
- // Act
- detector.Detect (r => final = r);
- // Assert
- Assert.NotNull (final);
- Assert.True (final.IsSupported); // Response contained "4"
- // Resolution should be constructed as new(rx, ry) where rx=10, ry=20 from our reply "[6;20;10t"
- Assert.Equal (10, final.Resolution.Width);
- Assert.Equal (20, final.Resolution.Height);
- driverMock.Verify (d => d.QueueAnsiRequest (It.IsAny<AnsiEscapeSequenceRequest> ()), Times.AtLeast (2));
- }
- [Fact]
- public void Detect_DoesNotSetSupported_WhenDeviceAttributesDoNotContain4()
- {
- // Arrange
- var driverMock = new Mock<IDriver>(MockBehavior.Strict);
- // Setup IsLegacyConsole - false means modern terminal with ANSI support
- driverMock.Setup (d => d.IsLegacyConsole).Returns (false);
- driverMock.Setup (d => d.QueueAnsiRequest (It.IsAny<AnsiEscapeSequenceRequest> ()))
- .Callback<AnsiEscapeSequenceRequest> (req =>
- {
- // SendDeviceAttributes -> reply without "4"
- if (req.Request == EscSeqUtils.CSI_SendDeviceAttributes.Request)
- {
- req.ResponseReceived.Invoke ("1;0;7c");
- }
- else
- {
- // Any other requests should be abandoned
- req.Abandoned?.Invoke ();
- }
- })
- .Verifiable ();
- var detector = new SixelSupportDetector (driverMock.Object);
- SixelSupportResult? final = null;
- // Act
- detector.Detect (r => final = r);
- // Assert
- Assert.NotNull (final);
- Assert.False (final.IsSupported);
- // On no support, the direct resolution request path isn't followed so resolution remains the default
- Assert.Equal (10, final.Resolution.Width);
- Assert.Equal (20, final.Resolution.Height);
- driverMock.Verify (d => d.QueueAnsiRequest (It.IsAny<AnsiEscapeSequenceRequest> ()), Times.AtLeast (1));
- }
- [Theory]
- [InlineData (true)]
- [InlineData (false)]
- public void Detect_SetsSupported_WhenIsLegacyConsoleIsFalseAndResponseContain4OrFalse (bool isLegacyConsole)
- {
- // Arrange
- var responseReceived = false;
- var output = new FakeOutput ();
- output.IsLegacyConsole = isLegacyConsole;
- Mock<DriverImpl> driverMock = new (
- MockBehavior.Strict,
- new FakeInputProcessor (null!),
- new OutputBufferImpl (),
- output,
- new AnsiRequestScheduler (new AnsiResponseParser ()),
- new SizeMonitorImpl (output)
- );
- driverMock.Setup (d => d.QueueAnsiRequest (It.IsAny<AnsiEscapeSequenceRequest> ()))
- .Callback<AnsiEscapeSequenceRequest> (req =>
- {
- if (req.Request == EscSeqUtils.CSI_SendDeviceAttributes.Request)
- {
- responseReceived = true;
- if (!isLegacyConsole)
- {
- // Response does contain "4" (so DAR indicates has sixel)
- req.ResponseReceived.Invoke ("?1;4;0;7c");
- }
- else
- {
- // Response does NOT contain "4" (so DAR indicates no sixel)
- req.ResponseReceived.Invoke ("");
- }
- }
- else
- {
- // Abandon all requests
- req.Abandoned?.Invoke ();
- }
- })
- .Verifiable ();
- var detector = new SixelSupportDetector (driverMock.Object);
- SixelSupportResult? final = null;
- // Act
- detector.Detect (r => final = r);
- // Assert
- Assert.Equal (isLegacyConsole, driverMock.Object.IsLegacyConsole);
- Assert.NotNull (final);
- if (!isLegacyConsole)
- {
- Assert.True (final.IsSupported);
- }
- else
- {
- // Not a real VT, so should be supported
- Assert.False (final.IsSupported);
- }
- Assert.True (responseReceived);
- driverMock.Verify (d => d.QueueAnsiRequest (It.IsAny<AnsiEscapeSequenceRequest> ()), Times.AtLeast (1));
- }
- [Theory]
- [InlineData (true)]
- [InlineData (false)]
- public void Detect_SetsSupported_WhenIsLegacyConsoleIsTrueOrFalse_With_Response (bool isLegacyConsole)
- {
- // Arrange
- var responseReceived = false;
- var output = new FakeOutput ();
- output.IsLegacyConsole = isLegacyConsole;
- Mock<DriverImpl> driverMock = new (
- MockBehavior.Strict,
- new FakeInputProcessor (null!),
- new OutputBufferImpl (),
- output,
- new AnsiRequestScheduler (new AnsiResponseParser ()),
- new SizeMonitorImpl (output)
- );
- driverMock.Setup (d => d.QueueAnsiRequest (It.IsAny<AnsiEscapeSequenceRequest> ()))
- .Callback<AnsiEscapeSequenceRequest> (req =>
- {
- if (req.Request == EscSeqUtils.CSI_SendDeviceAttributes.Request)
- {
- responseReceived = true;
- // Respond to the SendDeviceAttributes request with a value that indicates support (contains "4")
- // Respond to the SendDeviceAttributes request with an empty value that indicates non-support
- req.ResponseReceived.Invoke (!driverMock.Object.IsLegacyConsole ? "1;4;7c" : "");
- }
- // Abandon all requests
- req.Abandoned?.Invoke ();
- })
- .Verifiable ();
- var detector = new SixelSupportDetector (driverMock.Object);
- SixelSupportResult? final = null;
- // Act
- detector.Detect (r => final = r);
- // Assert
- Assert.Equal (isLegacyConsole, driverMock.Object.IsLegacyConsole);
- Assert.NotNull (final);
- if (!isLegacyConsole)
- {
- Assert.True (final.IsSupported);
- Assert.True (final.SupportsTransparency);
- }
- else
- {
- // Not a real VT, so shouldn't be supported
- Assert.False (final.IsSupported);
- Assert.False (final.SupportsTransparency);
- }
- Assert.True (responseReceived);
- }
- }
|