1 /*
2 * Copyright (c) 2018, The OpenThread Authors.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 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 * 3. Neither the name of the copyright holder nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include "test_platform.h"
30
31 #include <openthread/config.h>
32
33 #include "test_util.h"
34 #include "common/code_utils.hpp"
35 #include "common/string.hpp"
36
37 namespace ot {
38
39 enum
40 {
41 kStringSize = 10,
42 };
43
PrintString(const char * aName,const String<kSize> aString)44 template <uint16_t kSize> void PrintString(const char *aName, const String<kSize> aString)
45 {
46 printf("\t%s = [%zu] \"%s\"\n", aName, strlen(aString.AsCString()), aString.AsCString());
47 }
48
TestStringWriter(void)49 void TestStringWriter(void)
50 {
51 String<kStringSize> str;
52 constexpr char kLongString[] = "abcdefghijklmnopqratuvwxyzabcdefghijklmnopqratuvwxyz";
53
54 printf("\nTest 1: StringWriter constructor\n");
55
56 VerifyOrQuit(str.GetSize() == kStringSize);
57 VerifyOrQuit(str.GetLength() == 0, "failed for empty string");
58
59 VerifyOrQuit(strcmp(str.AsCString(), "") == 0);
60
61 PrintString("str", str);
62
63 printf(" -- PASS\n");
64
65 printf("\nTest 2: StringWriter::Append() method\n");
66
67 str.Append("Hi");
68 VerifyOrQuit(str.GetLength() == 2);
69 VerifyOrQuit(strcmp(str.AsCString(), "Hi") == 0);
70 PrintString("str", str);
71
72 str.Append("%s%d", "!", 12);
73 VerifyOrQuit(str.GetLength() == 5);
74 VerifyOrQuit(strcmp(str.AsCString(), "Hi!12") == 0);
75 PrintString("str", str);
76
77 str.Append(kLongString);
78 VerifyOrQuit(str.IsTruncated() && str.GetLength() == 5 + sizeof(kLongString) - 1,
79 "String::Append() did not handle overflow buffer correctly");
80 PrintString("str", str);
81
82 printf("\nTest 3: StringWriter::Clear() method\n");
83
84 str.Clear();
85 str.Append("Hello");
86 VerifyOrQuit(str.GetLength() == 5);
87 VerifyOrQuit(strcmp(str.AsCString(), "Hello") == 0);
88 PrintString("str", str);
89
90 str.Clear();
91 VerifyOrQuit(str.GetLength() == 0, "failed after Clear()");
92 VerifyOrQuit(strcmp(str.AsCString(), "") == 0);
93
94 str.Append("%d", 12);
95 VerifyOrQuit(str.GetLength() == 2);
96 VerifyOrQuit(strcmp(str.AsCString(), "12") == 0);
97 PrintString("str", str);
98
99 str.Clear();
100 str.Append(kLongString);
101 VerifyOrQuit(str.IsTruncated() && str.GetLength() == sizeof(kLongString) - 1,
102 "String::Clear() + String::Append() did not handle overflow buffer correctly");
103 PrintString("str", str);
104
105 printf(" -- PASS\n");
106 }
107
TestStringLength(void)108 void TestStringLength(void)
109 {
110 char string_a[5] = "\0foo";
111 char string_b[8] = "foo\0bar";
112
113 printf("\nTest 4: String::StringLength() method\n");
114
115 VerifyOrQuit(StringLength(string_a, 0) == 0);
116 VerifyOrQuit(StringLength(string_a, 1) == 0);
117 VerifyOrQuit(StringLength(string_a, 2) == 0);
118
119 VerifyOrQuit(StringLength(string_b, 0) == 0);
120 VerifyOrQuit(StringLength(string_b, 1) == 1);
121 VerifyOrQuit(StringLength(string_b, 2) == 2);
122 VerifyOrQuit(StringLength(string_b, 3) == 3);
123 VerifyOrQuit(StringLength(string_b, 4) == 3);
124 VerifyOrQuit(StringLength(string_b, 5) == 3);
125 VerifyOrQuit(StringLength(string_b, 6) == 3);
126
127 printf(" -- PASS\n");
128 }
129
TestUtf8(void)130 void TestUtf8(void)
131 {
132 printf("\nTest 5: IsValidUtf8String() function\n");
133
134 VerifyOrQuit(IsValidUtf8String("An ASCII string"));
135 VerifyOrQuit(IsValidUtf8String(u8"Строка UTF-8"));
136 VerifyOrQuit(!IsValidUtf8String("\xbf"));
137 VerifyOrQuit(!IsValidUtf8String("\xdf"));
138 VerifyOrQuit(!IsValidUtf8String("\xef\x80"));
139 VerifyOrQuit(!IsValidUtf8String("\xf7\x80\x80"));
140 VerifyOrQuit(!IsValidUtf8String("\xff"));
141
142 printf(" -- PASS\n");
143 }
144
TestStringFind(void)145 void TestStringFind(void)
146 {
147 char emptyString[1] = {'\0'};
148 char testString[] = "foo.bar.bar\\.";
149 char testString2[] = "abcabcabcdabc";
150
151 printf("\nTest 6: StringFind() function\n");
152
153 VerifyOrQuit(StringFind(testString, 'f') == testString);
154 VerifyOrQuit(StringFind(testString, 'o') == &testString[1]);
155 VerifyOrQuit(StringFind(testString, '.') == &testString[3]);
156 VerifyOrQuit(StringFind(testString, 'r') == &testString[6]);
157 VerifyOrQuit(StringFind(testString, '\\') == &testString[11]);
158 VerifyOrQuit(StringFind(testString, 'x') == nullptr);
159 VerifyOrQuit(StringFind(testString, ',') == nullptr);
160
161 VerifyOrQuit(StringFind(emptyString, 'f') == nullptr);
162 VerifyOrQuit(StringFind(emptyString, '.') == nullptr);
163
164 VerifyOrQuit(StringFind(testString, "foo") == &testString[0]);
165 VerifyOrQuit(StringFind(testString, "oo") == &testString[1]);
166 VerifyOrQuit(StringFind(testString, "bar") == &testString[4]);
167 VerifyOrQuit(StringFind(testString, "bar\\") == &testString[8]);
168 VerifyOrQuit(StringFind(testString, "\\.") == &testString[11]);
169 VerifyOrQuit(StringFind(testString, testString) == testString);
170 VerifyOrQuit(StringFind(testString, "fooo") == nullptr);
171 VerifyOrQuit(StringFind(testString, "far") == nullptr);
172 VerifyOrQuit(StringFind(testString, "bar\\..") == nullptr);
173 VerifyOrQuit(StringFind(testString, "") == &testString[0]);
174
175 VerifyOrQuit(StringFind(emptyString, "foo") == nullptr);
176 VerifyOrQuit(StringFind(emptyString, "bar") == nullptr);
177 VerifyOrQuit(StringFind(emptyString, "") == &emptyString[0]);
178
179 // Verify when sub-string has repeated patterns
180 VerifyOrQuit(StringFind(testString2, "abcabc") == &testString2[0]);
181 VerifyOrQuit(StringFind(testString2, "abcabcd") == &testString2[3]);
182
183 printf(" -- PASS\n");
184 }
185
TestStringEndsWith(void)186 void TestStringEndsWith(void)
187 {
188 printf("\nTest 7: StringEndsWith() function\n");
189
190 VerifyOrQuit(StringEndsWith("foobar", 'r'));
191 VerifyOrQuit(!StringEndsWith("foobar", 'a'));
192 VerifyOrQuit(!StringEndsWith("foobar", '\0'));
193 VerifyOrQuit(StringEndsWith("a", 'a'));
194 VerifyOrQuit(!StringEndsWith("a", 'b'));
195
196 VerifyOrQuit(StringEndsWith("foobar", "bar"));
197 VerifyOrQuit(!StringEndsWith("foobar", "ba"));
198 VerifyOrQuit(StringEndsWith("foobar", "foobar"));
199 VerifyOrQuit(!StringEndsWith("foobar", "foobarr"));
200
201 VerifyOrQuit(!StringEndsWith("", 'a'));
202 VerifyOrQuit(!StringEndsWith("", "foo"));
203
204 printf(" -- PASS\n");
205 }
206
207 } // namespace ot
208
main(void)209 int main(void)
210 {
211 ot::TestStringWriter();
212 ot::TestStringLength();
213 ot::TestUtf8();
214 ot::TestStringFind();
215 ot::TestStringEndsWith();
216 printf("\nAll tests passed.\n");
217 return 0;
218 }
219