================
@@ -116,3 +116,62 @@ TEST(AnsiTerminal, TrimAndPad) {
EXPECT_EQ("12❤️4❤️", ansi::TrimAndPad("12❤️4❤️", 5));
EXPECT_EQ("12❤️45", ansi::TrimAndPad("12❤️45❤️", 5));
}
+
+TEST(AnsiTerminal, VisibleIndexToActualIndex) {
+ using Hint = ansi::VisibleActualIdxPair;
+ EXPECT_EQ((Hint{0, 0}), ansi::VisibleIndexToActualIndex("", 0,
std::nullopt));
+ EXPECT_EQ((Hint{0, 0}),
+ ansi::VisibleIndexToActualIndex("abc", 0, std::nullopt));
+ EXPECT_EQ((Hint{1, 1}),
+ ansi::VisibleIndexToActualIndex("abc", 1, std::nullopt));
+ EXPECT_EQ((Hint{2, 2}),
+ ansi::VisibleIndexToActualIndex("abc", 2, std::nullopt));
+ // We expect callers to limit the visible index to its valid range.
+
+ // When a visible character is preceeded by an ANSI code, we would need to
+ // print that code when printing the character. Therefore, the actual index
+ // points to the preceeding ANSI code, not the visible character itself.
+ EXPECT_EQ((Hint{0, 0}),
+ ansi::VisibleIndexToActualIndex("\x1B[4mabc", 0, std::nullopt));
+ EXPECT_EQ((Hint{1, 1}),
+ ansi::VisibleIndexToActualIndex("a\x1B[4mbc", 1, std::nullopt));
+ EXPECT_EQ((Hint{2, 2}),
+ ansi::VisibleIndexToActualIndex("ab\x1B[4mc", 2, std::nullopt));
+
+ // If the visible character is proceeded by an ANSI code, we don't need to
+ // adjust anything. The actual index is the index of the visible character
+ // itself.
+ EXPECT_EQ((Hint{0, 0}),
+ ansi::VisibleIndexToActualIndex("a\x1B[4mbc", 0, std::nullopt));
+ EXPECT_EQ((Hint{1, 1}),
+ ansi::VisibleIndexToActualIndex("ab\x1B[4mc", 1, std::nullopt));
+ EXPECT_EQ((Hint{2, 2}),
+ ansi::VisibleIndexToActualIndex("abc\x1B[4m", 2, std::nullopt));
+
+ // If we want a visible character that is after ANSI codes for other
+ // characters, the actual index must know to skip those previous codes.
+ EXPECT_EQ((Hint{1, 5}),
+ ansi::VisibleIndexToActualIndex("\x1B[4mabc", 1, std::nullopt));
+ EXPECT_EQ((Hint{2, 6}),
+ ansi::VisibleIndexToActualIndex("a\x1B[4mbc", 2, std::nullopt));
+
+ // We can give it a previous result to skip forward. To prove it does not
look
+ // at the early parts of the string, give it hints that actually produce
+ // incorrect results.
+
+ const char *actual_text = "abcdefghijk";
+ // This does nothing because the hint is the answer.
+ EXPECT_EQ((Hint{1, 5}),
+ ansi::VisibleIndexToActualIndex(actual_text, 1, Hint{1, 5}));
+ // The hint can be completely bogus, but we trust it. So if it refers to the
+ // visible index being asked for, we just return the hint.
+ EXPECT_EQ((Hint{99, 127}),
+ ansi::VisibleIndexToActualIndex(actual_text, 99, Hint{99, 127}));
+ // This should return {2, 1}, but the actual is offset by 5 due to the hint.
+ EXPECT_EQ((Hint{2, 6}),
+ ansi::VisibleIndexToActualIndex(actual_text, 2, Hint{1, 5}));
+ // If the hint is for a visible index > the wanted visible index, we cannot
do
+ // anything with it. The function can only look forward.
+ EXPECT_EQ((Hint{2, 2}),
+ ansi::VisibleIndexToActualIndex(actual_text, 2, Hint{3, 6}));
+}
----------------
DavidSpickett wrote:
Will add a test case for when the hint is valid and is used, but the function
has to read beyond the hinted index. Which is the normal use of it.
https://github.com/llvm/llvm-project/pull/178653
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits