1 //===- TwineTest.cpp - Twine unit tests -----------------------------------===// 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 "llvm/ADT/Twine.h" 11 #include "llvm/ADT/SmallString.h" 12 #include "llvm/Support/FormatAdapters.h" 13 #include "llvm/Support/FormatVariadic.h" 14 #include "llvm/Support/raw_ostream.h" 15 #include "gtest/gtest.h" 16 using namespace llvm; 17 18 namespace { 19 20 std::string repr(const Twine &Value) { 21 std::string res; 22 llvm::raw_string_ostream OS(res); 23 Value.printRepr(OS); 24 return OS.str(); 25 } 26 27 TEST(TwineTest, Construction) { 28 EXPECT_EQ("", Twine().str()); 29 EXPECT_EQ("hi", Twine("hi").str()); 30 EXPECT_EQ("hi", Twine(std::string("hi")).str()); 31 EXPECT_EQ("hi", Twine(StringRef("hi")).str()); 32 EXPECT_EQ("hi", Twine(StringRef(std::string("hi"))).str()); 33 EXPECT_EQ("hi", Twine(StringRef("hithere", 2)).str()); 34 EXPECT_EQ("hi", Twine(SmallString<4>("hi")).str()); 35 EXPECT_EQ("hi", Twine(formatv("{0}", "hi")).str()); 36 } 37 38 TEST(TwineTest, Numbers) { 39 EXPECT_EQ("123", Twine(123U).str()); 40 EXPECT_EQ("123", Twine(123).str()); 41 EXPECT_EQ("-123", Twine(-123).str()); 42 EXPECT_EQ("123", Twine(123).str()); 43 EXPECT_EQ("-123", Twine(-123).str()); 44 45 EXPECT_EQ("7b", Twine::utohexstr(123).str()); 46 } 47 48 TEST(TwineTest, Characters) { 49 EXPECT_EQ("x", Twine('x').str()); 50 EXPECT_EQ("x", Twine(static_cast<unsigned char>('x')).str()); 51 EXPECT_EQ("x", Twine(static_cast<signed char>('x')).str()); 52 } 53 54 TEST(TwineTest, Concat) { 55 // Check verse repr, since we care about the actual representation not just 56 // the result. 57 58 // Concat with null. 59 EXPECT_EQ("(Twine null empty)", 60 repr(Twine("hi").concat(Twine::createNull()))); 61 EXPECT_EQ("(Twine null empty)", 62 repr(Twine::createNull().concat(Twine("hi")))); 63 64 // Concat with empty. 65 EXPECT_EQ("(Twine cstring:\"hi\" empty)", 66 repr(Twine("hi").concat(Twine()))); 67 EXPECT_EQ("(Twine cstring:\"hi\" empty)", 68 repr(Twine().concat(Twine("hi")))); 69 EXPECT_EQ("(Twine smallstring:\"hi\" empty)", 70 repr(Twine().concat(Twine(SmallString<5>("hi"))))); 71 EXPECT_EQ("(Twine formatv:\"howdy\" empty)", 72 repr(Twine(formatv("howdy")).concat(Twine()))); 73 EXPECT_EQ("(Twine formatv:\"howdy\" empty)", 74 repr(Twine().concat(Twine(formatv("howdy"))))); 75 EXPECT_EQ("(Twine smallstring:\"hey\" cstring:\"there\")", 76 repr(Twine(SmallString<7>("hey")).concat(Twine("there")))); 77 78 // Concatenation of unary ropes. 79 EXPECT_EQ("(Twine cstring:\"a\" cstring:\"b\")", 80 repr(Twine("a").concat(Twine("b")))); 81 82 // Concatenation of other ropes. 83 EXPECT_EQ("(Twine rope:(Twine cstring:\"a\" cstring:\"b\") cstring:\"c\")", 84 repr(Twine("a").concat(Twine("b")).concat(Twine("c")))); 85 EXPECT_EQ("(Twine cstring:\"a\" rope:(Twine cstring:\"b\" cstring:\"c\"))", 86 repr(Twine("a").concat(Twine("b").concat(Twine("c"))))); 87 EXPECT_EQ("(Twine cstring:\"a\" rope:(Twine smallstring:\"b\" cstring:\"c\"))", 88 repr(Twine("a").concat(Twine(SmallString<3>("b")).concat(Twine("c"))))); 89 } 90 91 TEST(TwineTest, toNullTerminatedStringRef) { 92 SmallString<8> storage; 93 EXPECT_EQ(0, *Twine("hello").toNullTerminatedStringRef(storage).end()); 94 EXPECT_EQ(0, 95 *Twine(StringRef("hello")).toNullTerminatedStringRef(storage).end()); 96 EXPECT_EQ(0, *Twine(SmallString<11>("hello")) 97 .toNullTerminatedStringRef(storage) 98 .end()); 99 EXPECT_EQ(0, *Twine(formatv("{0}{1}", "how", "dy")) 100 .toNullTerminatedStringRef(storage) 101 .end()); 102 } 103 104 TEST(TwineTest, LazyEvaluation) { 105 struct formatter : FormatAdapter<int> { 106 explicit formatter(int &Count) : FormatAdapter(0), Count(Count) {} 107 int &Count; 108 109 void format(raw_ostream &OS, StringRef Style) { ++Count; } 110 }; 111 112 int Count = 0; 113 formatter Formatter(Count); 114 (void)Twine(formatv("{0}", Formatter)); 115 EXPECT_EQ(0, Count); 116 (void)Twine(formatv("{0}", Formatter)).str(); 117 EXPECT_EQ(1, Count); 118 } 119 120 // I suppose linking in the entire code generator to add a unit test to check 121 // the code size of the concat operation is overkill... :) 122 123 } // end anonymous namespace 124