1 /*
2  *  unittests/core/String.cc
3  *  Apto
4  *
5  *  Created by David on 2/14/11.
6  *  Copyright 2011 David Michael Bryson. All rights reserved.
7  *  http://programerror.com/software/apto
8  *
9  *  Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
10  *  following conditions are met:
11  *
12  *  1.  Redistributions of source code must retain the above copyright notice, this list of conditions and the
13  *      following disclaimer.
14  *  2.  Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
15  *      following disclaimer in the documentation and/or other materials provided with the distribution.
16  *  3.  Neither the name of David Michael Bryson, nor the names of contributors may be used to endorse or promote
17  *      products derived from this software without specific prior written permission.
18  *
19  *  THIS SOFTWARE IS PROVIDED BY DAVID MICHAEL BRYSON AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20  *  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  *  DISCLAIMED. IN NO EVENT SHALL DAVID MICHAEL BRYSON OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23  *  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24  *  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
25  *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  *  Authors: David M. Bryson <david@programerror.com>
28  *
29  */
30 
31 #include "apto/core/String.h"
32 
33 #include "gtest/gtest.h"
34 
35 
TEST(CoreBasicString,Construction)36 TEST(CoreBasicString, Construction) {
37   // These should all be synonymous
38   Apto::BasicString<> s1;
39   EXPECT_EQ(0, s1.GetSize());
40   Apto::BasicString<Apto::SingleThreaded> s2;
41   EXPECT_EQ(0, s2.GetSize());
42   Apto::String s3;
43   EXPECT_EQ(0, s3.GetSize());
44 
45   // Test Multithreaded
46   Apto::BasicString<Apto::ThreadSafe> s4;
47   EXPECT_EQ(0, s4.GetSize());
48 
49 
50   // Test Construction with strings
51   const char* teststr = "Foo Bar Baz";
52   Apto::String s5(teststr);
53   EXPECT_EQ(11, s5.GetSize());
54   Apto::String s6(3, teststr);
55   EXPECT_EQ(3, s6.GetSize());
56 
57   // Test Threading-Type Cross Conversion
58   Apto::String s7(s4);
59   EXPECT_EQ(0, s7.GetSize());
60   Apto::BasicString<Apto::ThreadSafe> s8(s1);
61   EXPECT_EQ(0, s8.GetSize());
62 }
63 
64 
TEST(CoreBasicString,Indexing)65 TEST(CoreBasicString, Indexing) {
66   Apto::String s1("foo");
67   EXPECT_EQ('f', s1[0]);
68   EXPECT_EQ('o', s1[1]);
69   EXPECT_EQ('o', s1[2]);
70 }
71 
72 
TEST(CoreBasicString,Assignment)73 TEST(CoreBasicString, Assignment) {
74   Apto::String s1("foo");
75   EXPECT_EQ('f', s1[0]);
76   EXPECT_EQ('o', s1[1]);
77   EXPECT_EQ('o', s1[2]);
78   Apto::String s2("bar");
79   EXPECT_EQ('b', s2[0]);
80   EXPECT_EQ('a', s2[1]);
81   EXPECT_EQ('r', s2[2]);
82 
83   Apto::String s3(s1);
84   EXPECT_EQ('f', s3[0]);
85   EXPECT_EQ('o', s3[1]);
86   EXPECT_EQ('o', s3[2]);
87 
88   s2 = s1;
89   EXPECT_EQ('f', s2[0]);
90   EXPECT_EQ('o', s2[1]);
91   EXPECT_EQ('o', s2[2]);
92 
93   s3 = "baz";
94   EXPECT_EQ('b', s3[0]);
95   EXPECT_EQ('a', s3[1]);
96   EXPECT_EQ('z', s3[2]);
97 }
98 
99 
TEST(CoreBasicString,Iterators)100 TEST(CoreBasicString, Iterators) {
101   Apto::String s1("abcdef");
102 
103   Apto::String::Iterator it = s1.Begin();
104   for (int i = 0; it.Next(); i++) EXPECT_EQ('a' + i, *it.Get());
105 
106   const Apto::String& cs1 = s1;
107   Apto::String::ConstIterator cit = cs1.Begin();
108   for (int i = 0; cit.Next(); i++) EXPECT_EQ('a' + i, *cit.Get());
109 }
110 
111 
TEST(CoreBasicString,Comparison)112 TEST(CoreBasicString, Comparison) {
113   Apto::String s1("bar");
114   Apto::String s2("baz");
115 
116   EXPECT_TRUE(s1 == s1);
117   EXPECT_TRUE(s2 == s2);
118   EXPECT_FALSE(s1 == s2);
119   EXPECT_FALSE(s2 == s1);
120   EXPECT_TRUE(s1 == "bar");
121   EXPECT_TRUE("bar" == s1);
122   EXPECT_FALSE(s1 == "baz");
123   EXPECT_FALSE("baz" == s1);
124   EXPECT_TRUE(s2 == "baz");
125   EXPECT_TRUE("baz" == s2);
126   EXPECT_FALSE(s2 == "bar");
127   EXPECT_FALSE("bar" == s2);
128 
129   EXPECT_FALSE(s1 != s1);
130   EXPECT_FALSE(s2 != s2);
131   EXPECT_TRUE(s1 != s2);
132   EXPECT_TRUE(s2 != s1);
133   EXPECT_FALSE(s1 != "bar");
134   EXPECT_FALSE("bar" != s1);
135   EXPECT_TRUE(s1 != "baz");
136   EXPECT_TRUE("baz" != s1);
137   EXPECT_FALSE(s2 != "baz");
138   EXPECT_FALSE("baz" != s2);
139   EXPECT_TRUE(s2 != "bar");
140   EXPECT_TRUE("bar" != s2);
141 
142   EXPECT_FALSE(s1 < s1);
143   EXPECT_FALSE(s2 < s2);
144   EXPECT_TRUE(s1 < s2);
145   EXPECT_FALSE(s2 < s1);
146   EXPECT_FALSE(s1 < "bar");
147   EXPECT_FALSE("bar" < s1);
148   EXPECT_TRUE(s1 < "baz");
149   EXPECT_FALSE("baz" < s1);
150   EXPECT_FALSE(s2 < "bar");
151   EXPECT_TRUE("bar" < s2);
152   EXPECT_FALSE(s2 < "baz");
153   EXPECT_FALSE("baz" < s2);
154 
155   EXPECT_FALSE(s1 > s1);
156   EXPECT_FALSE(s2 > s2);
157   EXPECT_FALSE(s1 > s2);
158   EXPECT_TRUE(s2 > s1);
159   EXPECT_FALSE(s1 > "bar");
160   EXPECT_FALSE("bar" > s1);
161   EXPECT_FALSE(s1 > "baz");
162   EXPECT_TRUE("baz" > s1);
163   EXPECT_TRUE(s2 > "bar");
164   EXPECT_FALSE("bar" > s2);
165   EXPECT_FALSE(s2 > "baz");
166   EXPECT_FALSE("baz" > s2);
167 
168   EXPECT_TRUE(s1 <= s1);
169   EXPECT_TRUE(s2 <= s2);
170   EXPECT_TRUE(s1 <= s2);
171   EXPECT_FALSE(s2 <= s1);
172   EXPECT_TRUE(s1 <= "bar");
173   EXPECT_TRUE("bar" <= s1);
174   EXPECT_TRUE(s1 <= "baz");
175   EXPECT_FALSE("baz" <= s1);
176   EXPECT_FALSE(s2 <= "bar");
177   EXPECT_TRUE("bar" <= s2);
178   EXPECT_TRUE(s2 <= "baz");
179   EXPECT_TRUE("baz" <= s2);
180 
181   EXPECT_TRUE(s1 >= s1);
182   EXPECT_TRUE(s2 >= s2);
183   EXPECT_FALSE(s1 >= s2);
184   EXPECT_TRUE(s2 >= s1);
185   EXPECT_TRUE(s1 >= "bar");
186   EXPECT_TRUE("bar" >= s1);
187   EXPECT_FALSE(s1 >= "baz");
188   EXPECT_TRUE("baz" >= s1);
189   EXPECT_TRUE(s2 >= "bar");
190   EXPECT_FALSE("bar" >= s2);
191   EXPECT_TRUE(s2 >= "baz");
192   EXPECT_TRUE("baz" >= s2);
193 }
194 
195 
TEST(CoreBasicString,Concatenation)196 TEST(CoreBasicString, Concatenation) {
197   Apto::String s1("foo");
198   EXPECT_EQ(3, s1.GetSize());
199   EXPECT_EQ('f', s1[0]);
200   EXPECT_EQ('o', s1[1]);
201   EXPECT_EQ('o', s1[2]);
202 
203   s1 += 'b';
204   EXPECT_EQ(4, s1.GetSize());
205   EXPECT_EQ('f', s1[0]);
206   EXPECT_EQ('o', s1[1]);
207   EXPECT_EQ('o', s1[2]);
208   EXPECT_EQ('b', s1[3]);
209 
210   s1 += "ar";
211   EXPECT_EQ(6, s1.GetSize());
212   EXPECT_EQ('f', s1[0]);
213   EXPECT_EQ('o', s1[1]);
214   EXPECT_EQ('o', s1[2]);
215   EXPECT_EQ('b', s1[3]);
216   EXPECT_EQ('a', s1[4]);
217   EXPECT_EQ('r', s1[5]);
218 
219   s1 += Apto::String("baz");
220   EXPECT_EQ(9, s1.GetSize());
221   EXPECT_EQ('f', s1[0]);
222   EXPECT_EQ('o', s1[1]);
223   EXPECT_EQ('o', s1[2]);
224   EXPECT_EQ('b', s1[3]);
225   EXPECT_EQ('a', s1[4]);
226   EXPECT_EQ('r', s1[5]);
227   EXPECT_EQ('b', s1[6]);
228   EXPECT_EQ('a', s1[7]);
229   EXPECT_EQ('z', s1[8]);
230 
231   s1 = s1 + ' ';
232   EXPECT_EQ(10, s1.GetSize());
233   EXPECT_EQ('f', s1[0]);
234   EXPECT_EQ('o', s1[1]);
235   EXPECT_EQ('o', s1[2]);
236   EXPECT_EQ('b', s1[3]);
237   EXPECT_EQ('a', s1[4]);
238   EXPECT_EQ('r', s1[5]);
239   EXPECT_EQ('b', s1[6]);
240   EXPECT_EQ('a', s1[7]);
241   EXPECT_EQ('z', s1[8]);
242   EXPECT_EQ(' ', s1[9]);
243 
244 
245   s1 = s1 + "- ";
246   EXPECT_EQ(12, s1.GetSize());
247   EXPECT_EQ('f', s1[0]);
248   EXPECT_EQ('o', s1[1]);
249   EXPECT_EQ('o', s1[2]);
250   EXPECT_EQ('b', s1[3]);
251   EXPECT_EQ('a', s1[4]);
252   EXPECT_EQ('r', s1[5]);
253   EXPECT_EQ('b', s1[6]);
254   EXPECT_EQ('a', s1[7]);
255   EXPECT_EQ('z', s1[8]);
256   EXPECT_EQ(' ', s1[9]);
257   EXPECT_EQ('-', s1[10]);
258   EXPECT_EQ(' ', s1[11]);
259 
260 
261 
262   s1 = s1 + s1;
263   EXPECT_EQ(24, s1.GetSize());
264   EXPECT_EQ('f', s1[0]);
265   EXPECT_EQ('o', s1[1]);
266   EXPECT_EQ('o', s1[2]);
267   EXPECT_EQ('b', s1[3]);
268   EXPECT_EQ('a', s1[4]);
269   EXPECT_EQ('r', s1[5]);
270   EXPECT_EQ('b', s1[6]);
271   EXPECT_EQ('a', s1[7]);
272   EXPECT_EQ('z', s1[8]);
273   EXPECT_EQ(' ', s1[9]);
274   EXPECT_EQ('-', s1[10]);
275   EXPECT_EQ(' ', s1[11]);
276   EXPECT_EQ('f', s1[12]);
277   EXPECT_EQ('o', s1[13]);
278   EXPECT_EQ('o', s1[14]);
279   EXPECT_EQ('b', s1[15]);
280   EXPECT_EQ('a', s1[16]);
281   EXPECT_EQ('r', s1[17]);
282   EXPECT_EQ('b', s1[18]);
283   EXPECT_EQ('a', s1[19]);
284   EXPECT_EQ('z', s1[20]);
285   EXPECT_EQ(' ', s1[21]);
286   EXPECT_EQ('-', s1[22]);
287   EXPECT_EQ(' ', s1[23]);
288 }
289 
290 
TEST(CoreBasicString,Substring)291 TEST(CoreBasicString, Substring) {
292   Apto::String s1("foobarbaz");
293   Apto::String s2 = s1.Substring(3, 3);
294   EXPECT_EQ(3, s2.GetSize());
295   EXPECT_EQ('b', s2[0]);
296   EXPECT_EQ('a', s2[1]);
297   EXPECT_EQ('r', s2[2]);
298 }
299 
TEST(CoreBasicString,Pop)300 TEST(CoreBasicString, Pop) {
301   Apto::String s1("foo bar,baz");
302   Apto::String foo = s1.Pop(' ');
303   EXPECT_TRUE(foo == Apto::String("foo"));
304   Apto::String bar = s1.Pop(',');
305   EXPECT_TRUE(bar == Apto::String("bar"));
306   EXPECT_TRUE(s1 == Apto::String("baz"));
307 }
308 
309 
TEST(CoreBasicString,CharacterInstpection)310 TEST(CoreBasicString, CharacterInstpection) {
311   Apto::String s1("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 \f\n\r\t\v.");
312   for (int i = 0; i < s1.GetSize(); i++) {
313     if (i <  26          ) EXPECT_TRUE(s1.IsUpper(i));  else EXPECT_FALSE(s1.IsUpper(i));
314     if (i >= 26 && i < 52) EXPECT_TRUE(s1.IsLower(i));  else EXPECT_FALSE(s1.IsLower(i));
315     if (i <  52          ) EXPECT_TRUE(s1.IsLetter(i)); else EXPECT_FALSE(s1.IsLetter(i));
316     if (i >= 52 && i < 62) EXPECT_TRUE(s1.IsNumber(i)); else EXPECT_FALSE(s1.IsNumber(i));
317     if (i >= 62 && i < 68) EXPECT_TRUE(s1.IsWhitespace(i)); else EXPECT_FALSE(s1.IsWhitespace(i));
318   }
319 }
320