60 lines
3 KiB
C#
60 lines
3 KiB
C#
namespace tgcli.Tests;
|
|
|
|
public class MessagePaging {
|
|
[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);
|
|
}
|
|
}
|
|
}
|