1 /* 2 * Copyright (C) 2012 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include "config.h" 27 28 #include "wtf/StringExtras.h" 29 #include "wtf/text/CString.h" 30 #include "wtf/text/WTFString.h" 31 #include <gtest/gtest.h> 32 #include <limits> 33 34 namespace { 35 36 template<typename IntegerType> struct PrintfFormatTrait { static const char format[]; }; 37 38 template<> struct PrintfFormatTrait<short> { static const char format[]; }; 39 const char PrintfFormatTrait<short>::format[] = "%hd"; 40 41 template<> struct PrintfFormatTrait<int> { static const char format[]; }; 42 const char PrintfFormatTrait<int>::format[] = "%d"; 43 44 template<> struct PrintfFormatTrait<long> { static const char format[]; }; 45 const char PrintfFormatTrait<long>::format[] = "%ld"; 46 47 template<> struct PrintfFormatTrait<long long> { static const char format[]; }; 48 #if OS(WIN) 49 const char PrintfFormatTrait<long long>::format[] = "%I64i"; 50 #else 51 const char PrintfFormatTrait<long long>::format[] = "%lli"; 52 #endif // OS(WIN) 53 54 template<> struct PrintfFormatTrait<unsigned short> { static const char format[]; }; 55 const char PrintfFormatTrait<unsigned short>::format[] = "%hu"; 56 57 template<> struct PrintfFormatTrait<unsigned> { static const char format[]; }; 58 const char PrintfFormatTrait<unsigned>::format[] = "%u"; 59 60 template<> struct PrintfFormatTrait<unsigned long> { static const char format[]; }; 61 const char PrintfFormatTrait<unsigned long>::format[] = "%lu"; 62 63 template<> struct PrintfFormatTrait<unsigned long long> { static const char format[]; }; 64 #if OS(WIN) 65 const char PrintfFormatTrait<unsigned long long>::format[] = "%I64u"; 66 #else 67 const char PrintfFormatTrait<unsigned long long>::format[] = "%llu"; 68 #endif // OS(WIN) 69 70 71 // FIXME: use snprintf from StringExtras.h 72 template<typename IntegerType> 73 void testBoundaries() 74 { 75 const unsigned bufferSize = 256; 76 Vector<char, bufferSize> buffer; 77 buffer.resize(bufferSize); 78 79 const IntegerType min = std::numeric_limits<IntegerType>::min(); 80 CString minStringData = String::number(min).latin1(); 81 snprintf(buffer.data(), bufferSize, PrintfFormatTrait<IntegerType>::format, min); 82 EXPECT_STREQ(buffer.data(), minStringData.data()); 83 84 const IntegerType max = std::numeric_limits<IntegerType>::max(); 85 CString maxStringData = String::number(max).latin1(); 86 snprintf(buffer.data(), bufferSize, PrintfFormatTrait<IntegerType>::format, max); 87 EXPECT_STREQ(buffer.data(), maxStringData.data()); 88 } 89 90 template<typename IntegerType> 91 void testNumbers() 92 { 93 const unsigned bufferSize = 256; 94 Vector<char, bufferSize> buffer; 95 buffer.resize(bufferSize); 96 97 for (int i = -100; i < 100; ++i) { 98 const IntegerType number = static_cast<IntegerType>(i); 99 CString numberStringData = String::number(number).latin1(); 100 snprintf(buffer.data(), bufferSize, PrintfFormatTrait<IntegerType>::format, number); 101 EXPECT_STREQ(buffer.data(), numberStringData.data()); 102 } 103 } 104 105 TEST(StringExtraTest, IntegerToStringConversionSignedIntegerBoundaries) 106 { 107 testBoundaries<short>(); 108 testBoundaries<int>(); 109 testBoundaries<long>(); 110 testBoundaries<long long>(); 111 } 112 113 TEST(StringExtraTest, IntegerToStringConversionSignedIntegerRegularNumbers) 114 { 115 testNumbers<short>(); 116 testNumbers<int>(); 117 testNumbers<long>(); 118 testNumbers<long long>(); 119 } 120 121 TEST(StringExtraTest, IntegerToStringConversionUnsignedIntegerBoundaries) 122 { 123 testBoundaries<unsigned short>(); 124 testBoundaries<unsigned>(); 125 testBoundaries<unsigned long>(); 126 testBoundaries<unsigned long long>(); 127 } 128 129 TEST(StringExtraTest, IntegerToStringConversionUnsignedIntegerRegularNumbers) 130 { 131 testNumbers<unsigned short>(); 132 testNumbers<unsigned>(); 133 testNumbers<unsigned long>(); 134 testNumbers<unsigned long long>(); 135 } 136 137 } // namespace 138