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)]
2023-01-23 17:55:50 +01:00
public void TestGetPagedMessageInput ( int offset ) {
2023-01-23 17:51:10 +01:00
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 ;
2023-01-23 17:55:50 +01:00
Assert . Equal ( ReferenceMethods . GetPagedMessageInputLine ( testMessage , offset , testBufferWidth ) , Util . GetPagedMessageInputLine ( testMessage , offset , testBufferWidth ) ) ;
2023-01-23 17:51:10 +01:00
}
private static class ReferenceMethods {
2023-01-23 17:55:50 +01:00
internal static ( string messageBuffer , int relCursorPos ) GetPagedMessageInputLine ( string message , int absCursorPos , int bufferWidth ) {
const int wrapOffsetPre = 2 ; // number of "untouchable" characters moving the cursor onto will cause a wrap on the right screen edge
const int wrapOffsetPost = 5 ; // number of "untouchable" characters moving the cursor onto will cause a wrap on the left screen edge
2023-01-23 17:51:10 +01:00
2023-01-23 17:55:50 +01:00
const int wrapOffsetPreI = wrapOffsetPre + 1 ; // offset + 1 (character on the edge), for easier calculations
const int wrapOffsetPostI = wrapOffsetPost + 1 ; // offset + 1 (character on the edge), for easier calculations
2023-01-23 17:51:10 +01:00
2023-01-23 17:55:50 +01:00
if ( absCursorPos > message . Length )
throw new ArgumentOutOfRangeException ( nameof ( absCursorPos ) , "Cursor position exceeds message length" ) ;
2023-01-23 17:51:10 +01:00
if ( message . Length < bufferWidth )
2023-01-23 17:55:50 +01:00
return ( message , absCursorPos ) ;
2023-01-23 17:51:10 +01:00
2023-01-23 17:55:50 +01:00
if ( absCursorPos < bufferWidth - wrapOffsetPre - 1 )
return ( Util . TruncateString ( message , bufferWidth , $"{Util.Ansi.Inverse}>{Util.Ansi.InverseOff}" ) , absCursorPos ) ;
2023-01-23 17:51:10 +01:00
// 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)
2023-01-23 17:55:50 +01:00
var finalMessage = message [ ( bufferWidth - wrapOffsetPreI - wrapOffsetPost ) . . ] ;
var finalCursorPos = absCursorPos - bufferWidth + wrapOffsetPreI + wrapOffsetPostI ;
2023-01-23 17:51:10 +01:00
// 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)
2023-01-23 17:55:50 +01:00
while ( finalCursorPos > = bufferWidth - wrapOffsetPreI ) {
finalMessage = finalMessage [ ( bufferWidth - wrapOffsetPreI - wrapOffsetPostI ) . . ] ;
finalCursorPos = finalCursorPos - bufferWidth + wrapOffsetPreI + wrapOffsetPostI ;
2023-01-23 17:51:10 +01:00
}
finalMessage = Util . TruncateString ( finalMessage , bufferWidth - 1 , $"{Util.Ansi.Inverse}>{Util.Ansi.InverseOff}" ) ;
return ( $"{Util.Ansi.Inverse}<{Util.Ansi.InverseOff}" + finalMessage , finalCursorPos ) ;
}
}
}