1 //===-- HighlighterTest.cpp -------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "gtest/gtest.h" 11 12 #include "lldb/Core/Highlighter.h" 13 14 #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" 15 #include "Plugins/Language/Go/GoLanguage.h" 16 #include "Plugins/Language/Java/JavaLanguage.h" 17 #include "Plugins/Language/OCaml/OCamlLanguage.h" 18 #include "Plugins/Language/ObjC/ObjCLanguage.h" 19 #include "Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h" 20 21 using namespace lldb_private; 22 23 namespace { 24 class HighlighterTest : public testing::Test { 25 public: 26 static void SetUpTestCase(); 27 static void TearDownTestCase(); 28 }; 29 } // namespace 30 31 void HighlighterTest::SetUpTestCase() { 32 // The HighlighterManager uses the language plugins under the hood, so we 33 // have to initialize them here for our test process. 34 CPlusPlusLanguage::Initialize(); 35 GoLanguage::Initialize(); 36 JavaLanguage::Initialize(); 37 ObjCLanguage::Initialize(); 38 ObjCPlusPlusLanguage::Initialize(); 39 OCamlLanguage::Initialize(); 40 } 41 42 void HighlighterTest::TearDownTestCase() { 43 CPlusPlusLanguage::Terminate(); 44 GoLanguage::Terminate(); 45 JavaLanguage::Terminate(); 46 ObjCLanguage::Terminate(); 47 ObjCPlusPlusLanguage::Terminate(); 48 OCamlLanguage::Terminate(); 49 } 50 51 static std::string getName(lldb::LanguageType type) { 52 HighlighterManager m; 53 return m.getHighlighterFor(type, "").GetName().str(); 54 } 55 56 static std::string getName(llvm::StringRef path) { 57 HighlighterManager m; 58 return m.getHighlighterFor(lldb::eLanguageTypeUnknown, path).GetName().str(); 59 } 60 61 TEST_F(HighlighterTest, HighlighterSelectionType) { 62 EXPECT_EQ(getName(lldb::eLanguageTypeC_plus_plus), "clang"); 63 EXPECT_EQ(getName(lldb::eLanguageTypeC_plus_plus_03), "clang"); 64 EXPECT_EQ(getName(lldb::eLanguageTypeC_plus_plus_11), "clang"); 65 EXPECT_EQ(getName(lldb::eLanguageTypeC_plus_plus_14), "clang"); 66 EXPECT_EQ(getName(lldb::eLanguageTypeObjC), "clang"); 67 EXPECT_EQ(getName(lldb::eLanguageTypeObjC_plus_plus), "clang"); 68 69 EXPECT_EQ(getName(lldb::eLanguageTypeUnknown), "none"); 70 EXPECT_EQ(getName(lldb::eLanguageTypeJulia), "none"); 71 EXPECT_EQ(getName(lldb::eLanguageTypeJava), "none"); 72 EXPECT_EQ(getName(lldb::eLanguageTypeHaskell), "none"); 73 } 74 75 TEST_F(HighlighterTest, HighlighterSelectionPath) { 76 EXPECT_EQ(getName("myfile.cc"), "clang"); 77 EXPECT_EQ(getName("moo.cpp"), "clang"); 78 EXPECT_EQ(getName("mar.cxx"), "clang"); 79 EXPECT_EQ(getName("foo.C"), "clang"); 80 EXPECT_EQ(getName("bar.CC"), "clang"); 81 EXPECT_EQ(getName("a/dir.CC"), "clang"); 82 EXPECT_EQ(getName("/a/dir.hpp"), "clang"); 83 EXPECT_EQ(getName("header.h"), "clang"); 84 85 EXPECT_EQ(getName(""), "none"); 86 EXPECT_EQ(getName("/dev/null"), "none"); 87 EXPECT_EQ(getName("Factory.java"), "none"); 88 EXPECT_EQ(getName("poll.py"), "none"); 89 EXPECT_EQ(getName("reducer.hs"), "none"); 90 } 91 92 TEST_F(HighlighterTest, FallbackHighlighter) { 93 HighlighterManager mgr; 94 const Highlighter &h = 95 mgr.getHighlighterFor(lldb::eLanguageTypePascal83, "foo.pas"); 96 97 HighlightStyle style; 98 style.identifier.Set("[", "]"); 99 style.semicolons.Set("<", ">"); 100 101 const char *code = "program Hello;"; 102 std::string output = h.Highlight(style, code); 103 104 EXPECT_STREQ(output.c_str(), code); 105 } 106 107 TEST_F(HighlighterTest, DefaultHighlighter) { 108 HighlighterManager mgr; 109 const Highlighter &h = mgr.getHighlighterFor(lldb::eLanguageTypeC, "main.c"); 110 111 HighlightStyle style; 112 113 const char *code = "int my_main() { return 22; } \n"; 114 std::string output = h.Highlight(style, code); 115 116 EXPECT_STREQ(output.c_str(), code); 117 } 118 119 //------------------------------------------------------------------------------ 120 // Tests highlighting with the Clang highlighter. 121 //------------------------------------------------------------------------------ 122 123 static std::string highlightC(llvm::StringRef code, HighlightStyle style) { 124 HighlighterManager mgr; 125 const Highlighter &h = mgr.getHighlighterFor(lldb::eLanguageTypeC, "main.c"); 126 return h.Highlight(style, code); 127 } 128 129 TEST_F(HighlighterTest, ClangEmptyInput) { 130 HighlightStyle s; 131 EXPECT_EQ("", highlightC("", s)); 132 } 133 134 TEST_F(HighlighterTest, ClangScalarLiterals) { 135 HighlightStyle s; 136 s.scalar_literal.Set("<scalar>", "</scalar>"); 137 138 EXPECT_EQ(" int i = <scalar>22</scalar>;", highlightC(" int i = 22;", s)); 139 } 140 141 TEST_F(HighlighterTest, ClangStringLiterals) { 142 HighlightStyle s; 143 s.string_literal.Set("<str>", "</str>"); 144 145 EXPECT_EQ("const char *f = 22 + <str>\"foo\"</str>;", 146 highlightC("const char *f = 22 + \"foo\";", s)); 147 } 148 149 TEST_F(HighlighterTest, ClangUnterminatedString) { 150 HighlightStyle s; 151 s.string_literal.Set("<str>", "</str>"); 152 153 EXPECT_EQ(" f = \"", highlightC(" f = \"", s)); 154 } 155 156 TEST_F(HighlighterTest, Keywords) { 157 HighlightStyle s; 158 s.keyword.Set("<k>", "</k>"); 159 160 EXPECT_EQ(" <k>return</k> 1; ", highlightC(" return 1; ", s)); 161 } 162 163 TEST_F(HighlighterTest, Colons) { 164 HighlightStyle s; 165 s.colon.Set("<c>", "</c>"); 166 167 EXPECT_EQ("foo<c>:</c><c>:</c>bar<c>:</c>", highlightC("foo::bar:", s)); 168 } 169 170 TEST_F(HighlighterTest, ClangBraces) { 171 HighlightStyle s; 172 s.braces.Set("<b>", "</b>"); 173 174 EXPECT_EQ("a<b>{</b><b>}</b>", highlightC("a{}", s)); 175 } 176 177 TEST_F(HighlighterTest, ClangSquareBrackets) { 178 HighlightStyle s; 179 s.square_brackets.Set("<sb>", "</sb>"); 180 181 EXPECT_EQ("a<sb>[</sb><sb>]</sb>", highlightC("a[]", s)); 182 } 183 184 TEST_F(HighlighterTest, ClangCommas) { 185 HighlightStyle s; 186 s.comma.Set("<comma>", "</comma>"); 187 188 EXPECT_EQ(" bool f = foo()<comma>,</comma> 1;", 189 highlightC(" bool f = foo(), 1;", s)); 190 } 191 192 TEST_F(HighlighterTest, ClangPPDirectives) { 193 HighlightStyle s; 194 s.pp_directive.Set("<pp>", "</pp>"); 195 196 EXPECT_EQ("<pp>#</pp><pp>include</pp><pp> </pp><pp>\"foo\"</pp><pp> </pp>//c", 197 highlightC("#include \"foo\" //c", s)); 198 } 199 200 TEST_F(HighlighterTest, ClangComments) { 201 HighlightStyle s; 202 s.comment.Set("<cc>", "</cc>"); 203 204 EXPECT_EQ(" <cc>/*com */</cc> <cc>// com /*n*/</cc>", 205 highlightC(" /*com */ // com /*n*/", s)); 206 } 207 208 TEST_F(HighlighterTest, ClangOperators) { 209 HighlightStyle s; 210 s.operators.Set("[", "]"); 211 212 EXPECT_EQ(" 1[+]2[/]a[*]f[&]x[|][~]l", highlightC(" 1+2/a*f&x|~l", s)); 213 } 214 215 TEST_F(HighlighterTest, ClangIdentifiers) { 216 HighlightStyle s; 217 s.identifier.Set("<id>", "</id>"); 218 219 EXPECT_EQ(" <id>foo</id> <id>c</id> = <id>bar</id>(); return 1;", 220 highlightC(" foo c = bar(); return 1;", s)); 221 } 222