1//===-- AnsiTerminalTest.cpp ----------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "gtest/gtest.h"
10
11#include "lldb/Utility/AnsiTerminal.h"
12
13using namespace lldb_private;
14
15TEST(AnsiTerminal, Empty) { EXPECT_EQ("", ansi::FormatAnsiTerminalCodes("")); }
16
17TEST(AnsiTerminal, WhiteSpace) {
18 EXPECT_EQ(" ", ansi::FormatAnsiTerminalCodes(" "));
19 EXPECT_EQ(" ", ansi::StripAnsiTerminalCodes(" "));
20}
21
22TEST(AnsiTerminal, AtEnd) {
23 EXPECT_EQ("abc\x1B[30m",
24 ansi::FormatAnsiTerminalCodes("abc${ansi.fg.black}"));
25
26 EXPECT_EQ("abc", ansi::StripAnsiTerminalCodes("abc\x1B[30m"));
27}
28
29TEST(AnsiTerminal, AtStart) {
30 EXPECT_EQ("\x1B[30mabc",
31 ansi::FormatAnsiTerminalCodes("${ansi.fg.black}abc"));
32
33 EXPECT_EQ("abc", ansi::StripAnsiTerminalCodes("\x1B[30mabc"));
34}
35
36TEST(AnsiTerminal, KnownPrefix) {
37 EXPECT_EQ("${ansi.fg.redish}abc",
38 ansi::FormatAnsiTerminalCodes("${ansi.fg.redish}abc"));
39}
40
41TEST(AnsiTerminal, Unknown) {
42 EXPECT_EQ("${ansi.fg.foo}abc",
43 ansi::FormatAnsiTerminalCodes("${ansi.fg.foo}abc"));
44}
45
46TEST(AnsiTerminal, Incomplete) {
47 EXPECT_EQ("abc${ansi.", ansi::FormatAnsiTerminalCodes("abc${ansi."));
48}
49
50TEST(AnsiTerminal, Twice) {
51 EXPECT_EQ("\x1B[30m\x1B[31mabc",
52 ansi::FormatAnsiTerminalCodes("${ansi.fg.black}${ansi.fg.red}abc"));
53
54 EXPECT_EQ("abc", ansi::StripAnsiTerminalCodes("\x1B[30m\x1B[31mabc"));
55}
56
57TEST(AnsiTerminal, Basic) {
58 EXPECT_EQ(
59 "abc\x1B[31mabc\x1B[0mabc",
60 ansi::FormatAnsiTerminalCodes("abc${ansi.fg.red}abc${ansi.normal}abc"));
61
62 EXPECT_EQ("abcabcabc",
63 ansi::StripAnsiTerminalCodes("abc\x1B[31mabc\x1B[0mabc"));
64}
65
66TEST(AnsiTerminal, InvalidEscapeCode) {
67 EXPECT_EQ("abc\x1B[31kabcabc",
68 ansi::StripAnsiTerminalCodes("abc\x1B[31kabc\x1B[0mabc"));
69}
70
71TEST(AnsiTerminal, FindNextAnsiSequenceBasic) {
72 auto [left, escape, right] = ansi::FindNextAnsiSequence(str: "foo\x1B[31mbar");
73 EXPECT_EQ("foo", left);
74 EXPECT_EQ("\x1B[31m", escape);
75 EXPECT_EQ("bar", right);
76}
77
78TEST(AnsiTerminal, FindNextAnsiSequenceIncompleteStart) {
79 auto [left, escape, right] =
80 ansi::FindNextAnsiSequence(str: "foo\x1B[bar\x1B[31mbaz");
81 EXPECT_EQ("foo\x1B[bar", left);
82 EXPECT_EQ("\x1B[31m", escape);
83 EXPECT_EQ("baz", right);
84}
85
86TEST(AnsiTerminal, FindNextAnsiSequenceEscapeStart) {
87 auto [left, escape, right] = ansi::FindNextAnsiSequence(str: "\x1B[31mfoo");
88 EXPECT_EQ("", left);
89 EXPECT_EQ("\x1B[31m", escape);
90 EXPECT_EQ("foo", right);
91}
92
93TEST(AnsiTerminal, TrimAndPad) {
94 // Test basic ASCII.
95 EXPECT_EQ(" ", ansi::TrimAndPad("", 5));
96 EXPECT_EQ("foo ", ansi::TrimAndPad("foo", 5));
97 EXPECT_EQ("fooba", ansi::TrimAndPad("fooba", 5));
98 EXPECT_EQ("fooba", ansi::TrimAndPad("foobar", 5));
99
100 // Simple test that ANSI escape codes don't contribute to the visible width.
101 EXPECT_EQ("\x1B[30m ", ansi::TrimAndPad("\x1B[30m", 5));
102 EXPECT_EQ("\x1B[30mfoo ", ansi::TrimAndPad("\x1B[30mfoo", 5));
103 EXPECT_EQ("\x1B[30mfooba", ansi::TrimAndPad("\x1B[30mfooba", 5));
104 EXPECT_EQ("\x1B[30mfooba", ansi::TrimAndPad("\x1B[30mfoobar", 5));
105
106 // Test that we include as many escape codes as we can.
107 EXPECT_EQ("fooba\x1B[30m", ansi::TrimAndPad("fooba\x1B[30m", 5));
108 EXPECT_EQ("fooba\x1B[30m\x1B[34m",
109 ansi::TrimAndPad("fooba\x1B[30m\x1B[34m", 5));
110 EXPECT_EQ("fooba\x1B[30m\x1B[34m",
111 ansi::TrimAndPad("fooba\x1B[30m\x1B[34mr", 5));
112
113 // Test Unicode.
114 EXPECT_EQ("❤️ ", ansi::TrimAndPad("❤️", 5));
115 EXPECT_EQ(" ❤️", ansi::TrimAndPad(" ❤️", 5));
116 EXPECT_EQ("12❤️4❤️", ansi::TrimAndPad("12❤️4❤️", 5));
117 EXPECT_EQ("12❤️45", ansi::TrimAndPad("12❤️45❤️", 5));
118}
119

source code of lldb/unittests/Utility/AnsiTerminalTest.cpp