2023-01-23 17:51:10 +01:00
namespace tgcli.Tests ;
2023-01-23 17:54:18 +01:00
public class PagedMessageInput {
2023-01-23 17:51:10 +01:00
[Theory]
[InlineData(0)]
[InlineData(76)]
[InlineData(77)]
[InlineData(147)]
[InlineData(148)]
[InlineData(218)]
[InlineData(219)]
[InlineData(289)]
public void Test1 ( int offset ) {
const string testMessage =
"this is a test string please ignore 1, this is a test string please ignore 2, this is a test string please ignore 3, this is a test string please ignore 4, this is a test string please ignore 5, this is a test string please ignore 6, this is a test string please ignore 7, this is a test str." ;
const int testBufferWidth = 80 ;
Assert . Equal ( ReferenceMethods . GetViewIntoMessageBuffer ( testMessage , offset , testBufferWidth ) ,
Util . GetViewIntoMessageBuffer ( testMessage , offset , testBufferWidth ) ) ;
}
private static class ReferenceMethods {
internal static ( string messageBuffer , int relativeCursorPosition )
GetViewIntoMessageBuffer ( string message , int absoluteCursorPosition , int bufferWidth ) {
const int wraparoundOffsetPre = 2 ; // number of "untouchable" characters moving the cursor onto will cause a wrap on the right screen edge
const int wraparoundOffsetPost = 5 ; // number of "untouchable" characters moving the cursor onto will cause a wrap on the left screen edge
const int wraparoundOffsetPreW = wraparoundOffsetPre + 1 ; // offset + 1 (character on the edge), for easier calculations
const int wraparoundOffsetPostW = wraparoundOffsetPost + 1 ; // offset + 1 (character on the edge), for easier calculations
if ( absoluteCursorPosition > message . Length )
throw new ArgumentOutOfRangeException ( ) ;
if ( message . Length < bufferWidth )
return ( message , absoluteCursorPosition ) ;
if ( absoluteCursorPosition < bufferWidth - wraparoundOffsetPre - 1 )
return ( Util . TruncateString ( message , bufferWidth , $"{Util.Ansi.Inverse}>{Util.Ansi.InverseOff}" ) , absoluteCursorPosition ) ;
// now we can be sure the message needs at least one wrap
// first wrap
// get rid of the content shown on the zeroth wrap, which is buf width minus wraparoundPreW (respects > character on screen edge)
var finalMessage = message [ ( bufferWidth - wraparoundOffsetPreW - wraparoundOffsetPost ) . . ] ;
var finalCursorPos = absoluteCursorPosition - bufferWidth + wraparoundOffsetPreW + wraparoundOffsetPostW ;
// successive wraps
// repeat above steps (but counting the new < character) until the string fits into the buffer
// it fits into the buffer when cursorPos >= bufferwidth minus wraparound (this time respecting > character absent on first wrap)
while ( finalCursorPos > = bufferWidth - wraparoundOffsetPreW ) {
finalMessage = finalMessage [ ( bufferWidth - wraparoundOffsetPreW - wraparoundOffsetPostW ) . . ] ;
finalCursorPos = finalCursorPos - bufferWidth + wraparoundOffsetPreW + wraparoundOffsetPostW ;
}
finalMessage = Util . TruncateString ( finalMessage , bufferWidth - 1 , $"{Util.Ansi.Inverse}>{Util.Ansi.InverseOff}" ) ;
return ( $"{Util.Ansi.Inverse}<{Util.Ansi.InverseOff}" + finalMessage , finalCursorPos ) ;
}
}
}