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