1 //
2 // StringTest.h
3 //
4 // Definition of the StringTest class.
5 //
6 // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
7 // and Contributors.
8 //
9 // SPDX-License-Identifier:	BSL-1.0
10 //
11 
12 
13 #ifndef StringTest_INCLUDED
14 #define StringTest_INCLUDED
15 
16 
17 #include "Poco/Foundation.h"
18 #include "CppUnit/TestCase.h"
19 #include "Poco/NumericString.h"
20 #include "Poco/MemoryStream.h"
21 #include "Poco/NumberFormatter.h"
22 
23 
24 class StringTest: public CppUnit::TestCase
25 {
26 public:
27 	StringTest(const std::string& name);
28 	~StringTest();
29 
30 	void testTrimLeft();
31 	void testTrimLeftInPlace();
32 	void testTrimRight();
33 	void testTrimRightInPlace();
34 	void testTrim();
35 	void testTrimInPlace();
36 	void testToUpper();
37 	void testToLower();
38 	void testIstring();
39 	void testIcompare();
40 	void testCILessThan();
41 	void testTranslate();
42 	void testTranslateInPlace();
43 	void testReplace();
44 	void testReplaceInPlace();
45 	void testCat();
46 	void testStartsWith();
47 	void testEndsWith();
48 
49 	void testStringToInt();
50 	void testStringToFloat();
51 	void testStringToDouble();
52 	void testNumericStringPadding();
53 	void testNumericStringLimit();
54 	void testStringToFloatError();
55 	void testNumericLocale();
56 	void benchmarkStrToFloat();
57 	void benchmarkStrToInt();
58 
59 	void testIntToString();
60 	void testFloatToString();
61 	void benchmarkFloatToStr();
62 
63 	void testJSONString();
64 
65 	void setUp();
66 	void tearDown();
67 
68 	static CppUnit::Test* suite();
69 
70 private:
71 
72 	template <typename T>
stringToInt()73 	void stringToInt()
74 	{
75 		T result = 0;
76 		if (123 <= std::numeric_limits<T>::max())
77 			assertTrue (Poco::strToInt("123", result, 10)); assertTrue (result == 123);
78 
79 		assertTrue (Poco::strToInt("0", result, 10)); assertTrue (result == 0);
80 		assertTrue (Poco::strToInt("000", result, 10)); assertTrue (result == 0);
81 
82 		if (std::numeric_limits<T>::is_signed && (-123 > std::numeric_limits<T>::min()))
83 			{ assertTrue (Poco::strToInt("-123", result, 10)); assertTrue (result == -123); }
84 		if (0x123 < std::numeric_limits<T>::max())
85 			{ assertTrue (Poco::strToInt("123", result, 0x10)); assertTrue (result == 0x123); }
86 		if (0x12ab < std::numeric_limits<T>::max())
87 			{ assertTrue (Poco::strToInt("12AB", result, 0x10)); assertTrue (result == 0x12ab); }
88 		if (123 < std::numeric_limits<T>::max())
89 			{ assertTrue (Poco::strToInt("00", result, 0x10)); assertTrue (result == 0); }
90 		if (0123 < std::numeric_limits<T>::max())
91 			{ assertTrue (Poco::strToInt("123", result, 010));  assertTrue (result == 0123); }
92 		if (0123 < std::numeric_limits<T>::max())
93 			{ assertTrue (Poco::strToInt("0123", result, 010)); assertTrue (result == 0123); }
94 
95 		assertTrue (Poco::strToInt("0", result, 010)); assertTrue (result == 0);
96 		assertTrue (Poco::strToInt("000", result, 010)); assertTrue (result == 0);
97 	}
98 
99 	template <typename Larger, typename Smaller>
numericStringLimitSameSign()100 	void numericStringLimitSameSign()
101 	{
102 		Larger l = std::numeric_limits<Smaller>::max();
103 		std::string str = Poco::NumberFormatter::format(l);
104 
105 		Smaller s;
106 		assertTrue(Poco::strToInt<Smaller>(str, s, 10));
107 		assertTrue(s == std::numeric_limits<Smaller>::max());
108 		++l; str = Poco::NumberFormatter::format(l);
109 		assertFalse(Poco::strToInt<Smaller>(str, s, 10));
110 		++l; str = Poco::NumberFormatter::format(l);
111 		assertFalse(Poco::strToInt<Smaller>(str, s, 10));
112 		++l; str = Poco::NumberFormatter::format(l);
113 		assertFalse(Poco::strToInt<Smaller>(str, s, 10));
114 		++l; str = Poco::NumberFormatter::format(l);
115 		assertFalse(Poco::strToInt<Smaller>(str, s, 10));
116 		++l; str = Poco::NumberFormatter::format(l);
117 		assertFalse(Poco::strToInt<Smaller>(str, s, 10));
118 		++l; str = Poco::NumberFormatter::format(l);
119 		assertFalse(Poco::strToInt<Smaller>(str, s, 10));
120 	}
121 
122 	template <typename Larger, typename Smaller>
numericStringLowerLimit()123 	void numericStringLowerLimit()
124 	{
125 		Larger l = std::numeric_limits<Smaller>::min();
126 		std::string val = Poco::NumberFormatter::format(l);
127 		Smaller s = -1;
128 		assertFalse(s == std::numeric_limits<Smaller>::min());
129 		assertTrue(Poco::strToInt<Smaller>(val, s, 10));
130 		assertTrue (s == std::numeric_limits<Smaller>::min());
131 		assertTrue(s == std::numeric_limits<Smaller>::min());
132 		--l; val = Poco::NumberFormatter::format(l);
133 		assertFalse(Poco::strToInt<Smaller>(val, s, 10));
134 		--l; val = Poco::NumberFormatter::format(l);
135 		assertFalse(Poco::strToInt<Smaller>(val, s, 10));
136 		--l; val = Poco::NumberFormatter::format(l);
137 		assertFalse(Poco::strToInt<Smaller>(val, s, 10));
138 		--l; val = Poco::NumberFormatter::format(l);
139 		assertFalse(Poco::strToInt<Smaller>(val, s, 10));
140 		--l; val = Poco::NumberFormatter::format(l);
141 		assertFalse(Poco::strToInt<Smaller>(val, s, 10));
142 		--l; val = Poco::NumberFormatter::format(l);
143 		assertFalse(Poco::strToInt<Smaller>(val, s, 10));
144 	}
145 
146 	template <typename T>
parseStream(const std::string & s,T & value)147 	bool parseStream(const std::string& s, T& value)
148 	{
149 		Poco::MemoryInputStream istr(s.data(), s.size());
150 #if !defined(POCO_NO_LOCALE)
151 		istr.imbue(std::locale::classic());
152 #endif
153 		istr >> value;
154 		return istr.eof() && !istr.fail();
155 	}
156 };
157 
158 
159 #endif // StringTest_INCLUDED
160