| OLD | NEW |
| (Empty) |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "base/strings/stringprintf.h" | |
| 6 | |
| 7 #include <errno.h> | |
| 8 | |
| 9 #include "base/basictypes.h" | |
| 10 #include "testing/gtest/include/gtest/gtest.h" | |
| 11 | |
| 12 namespace base { | |
| 13 | |
| 14 namespace { | |
| 15 | |
| 16 // A helper for the StringAppendV test that follows. | |
| 17 // | |
| 18 // Just forwards its args to StringAppendV. | |
| 19 static void StringAppendVTestHelper(std::string* out, const char* format, ...) { | |
| 20 va_list ap; | |
| 21 va_start(ap, format); | |
| 22 StringAppendV(out, format, ap); | |
| 23 va_end(ap); | |
| 24 } | |
| 25 | |
| 26 } // namespace | |
| 27 | |
| 28 TEST(StringPrintfTest, StringPrintfEmpty) { | |
| 29 EXPECT_EQ("", StringPrintf("%s", "")); | |
| 30 } | |
| 31 | |
| 32 TEST(StringPrintfTest, StringPrintfMisc) { | |
| 33 EXPECT_EQ("123hello w", StringPrintf("%3d%2s %1c", 123, "hello", 'w')); | |
| 34 #if defined(OS_WIN) | |
| 35 EXPECT_EQ(L"123hello w", StringPrintf(L"%3d%2ls %1lc", 123, L"hello", 'w')); | |
| 36 #endif | |
| 37 } | |
| 38 | |
| 39 TEST(StringPrintfTest, StringAppendfEmptyString) { | |
| 40 std::string value("Hello"); | |
| 41 StringAppendF(&value, "%s", ""); | |
| 42 EXPECT_EQ("Hello", value); | |
| 43 | |
| 44 #if defined(OS_WIN) | |
| 45 std::wstring valuew(L"Hello"); | |
| 46 StringAppendF(&valuew, L"%ls", L""); | |
| 47 EXPECT_EQ(L"Hello", valuew); | |
| 48 #endif | |
| 49 } | |
| 50 | |
| 51 TEST(StringPrintfTest, StringAppendfString) { | |
| 52 std::string value("Hello"); | |
| 53 StringAppendF(&value, " %s", "World"); | |
| 54 EXPECT_EQ("Hello World", value); | |
| 55 | |
| 56 #if defined(OS_WIN) | |
| 57 std::wstring valuew(L"Hello"); | |
| 58 StringAppendF(&valuew, L" %ls", L"World"); | |
| 59 EXPECT_EQ(L"Hello World", valuew); | |
| 60 #endif | |
| 61 } | |
| 62 | |
| 63 TEST(StringPrintfTest, StringAppendfInt) { | |
| 64 std::string value("Hello"); | |
| 65 StringAppendF(&value, " %d", 123); | |
| 66 EXPECT_EQ("Hello 123", value); | |
| 67 | |
| 68 #if defined(OS_WIN) | |
| 69 std::wstring valuew(L"Hello"); | |
| 70 StringAppendF(&valuew, L" %d", 123); | |
| 71 EXPECT_EQ(L"Hello 123", valuew); | |
| 72 #endif | |
| 73 } | |
| 74 | |
| 75 // Make sure that lengths exactly around the initial buffer size are handled | |
| 76 // correctly. | |
| 77 TEST(StringPrintfTest, StringPrintfBounds) { | |
| 78 const int kSrcLen = 1026; | |
| 79 char src[kSrcLen]; | |
| 80 for (size_t i = 0; i < arraysize(src); i++) | |
| 81 src[i] = 'A'; | |
| 82 | |
| 83 wchar_t srcw[kSrcLen]; | |
| 84 for (size_t i = 0; i < arraysize(srcw); i++) | |
| 85 srcw[i] = 'A'; | |
| 86 | |
| 87 for (int i = 1; i < 3; i++) { | |
| 88 src[kSrcLen - i] = 0; | |
| 89 std::string out; | |
| 90 SStringPrintf(&out, "%s", src); | |
| 91 EXPECT_STREQ(src, out.c_str()); | |
| 92 | |
| 93 #if defined(OS_WIN) | |
| 94 srcw[kSrcLen - i] = 0; | |
| 95 std::wstring outw; | |
| 96 SStringPrintf(&outw, L"%ls", srcw); | |
| 97 EXPECT_STREQ(srcw, outw.c_str()); | |
| 98 #endif | |
| 99 } | |
| 100 } | |
| 101 | |
| 102 // Test very large sprintfs that will cause the buffer to grow. | |
| 103 TEST(StringPrintfTest, Grow) { | |
| 104 char src[1026]; | |
| 105 for (size_t i = 0; i < arraysize(src); i++) | |
| 106 src[i] = 'A'; | |
| 107 src[1025] = 0; | |
| 108 | |
| 109 const char fmt[] = "%sB%sB%sB%sB%sB%sB%s"; | |
| 110 | |
| 111 std::string out; | |
| 112 SStringPrintf(&out, fmt, src, src, src, src, src, src, src); | |
| 113 | |
| 114 const int kRefSize = 320000; | |
| 115 char* ref = new char[kRefSize]; | |
| 116 #if defined(OS_WIN) | |
| 117 sprintf_s(ref, kRefSize, fmt, src, src, src, src, src, src, src); | |
| 118 #elif defined(OS_POSIX) | |
| 119 snprintf(ref, kRefSize, fmt, src, src, src, src, src, src, src); | |
| 120 #endif | |
| 121 | |
| 122 EXPECT_STREQ(ref, out.c_str()); | |
| 123 delete[] ref; | |
| 124 } | |
| 125 | |
| 126 TEST(StringPrintfTest, StringAppendV) { | |
| 127 std::string out; | |
| 128 StringAppendVTestHelper(&out, "%d foo %s", 1, "bar"); | |
| 129 EXPECT_EQ("1 foo bar", out); | |
| 130 } | |
| 131 | |
| 132 // Test the boundary condition for the size of the string_util's | |
| 133 // internal buffer. | |
| 134 TEST(StringPrintfTest, GrowBoundary) { | |
| 135 const int kStringUtilBufLen = 1024; | |
| 136 // Our buffer should be one larger than the size of StringAppendVT's stack | |
| 137 // buffer. | |
| 138 // And need extra one for NULL-terminator. | |
| 139 const int kBufLen = kStringUtilBufLen + 1 + 1; | |
| 140 char src[kBufLen]; | |
| 141 for (int i = 0; i < kBufLen - 1; ++i) | |
| 142 src[i] = 'a'; | |
| 143 src[kBufLen - 1] = 0; | |
| 144 | |
| 145 std::string out; | |
| 146 SStringPrintf(&out, "%s", src); | |
| 147 | |
| 148 EXPECT_STREQ(src, out.c_str()); | |
| 149 } | |
| 150 | |
| 151 // TODO(evanm): what's the proper cross-platform test here? | |
| 152 #if defined(OS_WIN) | |
| 153 // sprintf in Visual Studio fails when given U+FFFF. This tests that the | |
| 154 // failure case is gracefuly handled. | |
| 155 TEST(StringPrintfTest, Invalid) { | |
| 156 wchar_t invalid[2]; | |
| 157 invalid[0] = 0xffff; | |
| 158 invalid[1] = 0; | |
| 159 | |
| 160 std::wstring out; | |
| 161 SStringPrintf(&out, L"%ls", invalid); | |
| 162 EXPECT_STREQ(L"", out.c_str()); | |
| 163 } | |
| 164 #endif | |
| 165 | |
| 166 // Test that StringPrintf and StringAppendV do not change errno. | |
| 167 TEST(StringPrintfTest, StringPrintfErrno) { | |
| 168 errno = 1; | |
| 169 EXPECT_EQ("", StringPrintf("%s", "")); | |
| 170 EXPECT_EQ(1, errno); | |
| 171 std::string out; | |
| 172 StringAppendVTestHelper(&out, "%d foo %s", 1, "bar"); | |
| 173 EXPECT_EQ(1, errno); | |
| 174 } | |
| 175 | |
| 176 } // namespace base | |
| OLD | NEW |