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