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