================
@@ -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

Reply via email to