Line data Source code
1 : /*
2 : Minetest
3 : Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4 :
5 : This program is free software; you can redistribute it and/or modify
6 : it under the terms of the GNU Lesser General Public License as published by
7 : the Free Software Foundation; either version 2.1 of the License, or
8 : (at your option) any later version.
9 :
10 : This program is distributed in the hope that it will be useful,
11 : but WITHOUT ANY WARRANTY; without even the implied warranty of
12 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 : GNU Lesser General Public License for more details.
14 :
15 : You should have received a copy of the GNU Lesser General Public License along
16 : with this program; if not, write to the Free Software Foundation, Inc.,
17 : 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 : */
19 :
20 : #include "test.h"
21 :
22 : #include "util/numeric.h"
23 : #include "util/string.h"
24 :
25 1 : class TestUtilities : public TestBase {
26 : public:
27 1 : TestUtilities() { TestManager::registerTestModule(this); }
28 0 : const char *getName() { return "TestUtilities"; }
29 :
30 : void runTests(IGameDef *gamedef);
31 :
32 : void testAngleWrapAround();
33 : void testLowercase();
34 : void testTrim();
35 : void testIsYes();
36 : void testRemoveStringEnd();
37 : void testUrlEncode();
38 : void testUrlDecode();
39 : void testPadString();
40 : void testStartsWith();
41 : void testStrEqual();
42 : void testStringTrim();
43 : void testStrToIntConversion();
44 : void testStringReplace();
45 : void testStringAllowed();
46 : void testUTF8();
47 : void testWrapRows();
48 : void testIsNumber();
49 : void testIsPowerOfTwo();
50 : void testMyround();
51 : };
52 :
53 1 : static TestUtilities g_test_instance;
54 :
55 0 : void TestUtilities::runTests(IGameDef *gamedef)
56 : {
57 0 : TEST(testAngleWrapAround);
58 0 : TEST(testLowercase);
59 0 : TEST(testTrim);
60 0 : TEST(testIsYes);
61 0 : TEST(testRemoveStringEnd);
62 0 : TEST(testUrlEncode);
63 0 : TEST(testUrlDecode);
64 0 : TEST(testPadString);
65 0 : TEST(testStartsWith);
66 0 : TEST(testStrEqual);
67 0 : TEST(testStringTrim);
68 0 : TEST(testStrToIntConversion);
69 0 : TEST(testStringReplace);
70 0 : TEST(testStringAllowed);
71 0 : TEST(testUTF8);
72 0 : TEST(testWrapRows);
73 0 : TEST(testIsNumber);
74 0 : TEST(testIsPowerOfTwo);
75 0 : TEST(testMyround);
76 0 : }
77 :
78 : ////////////////////////////////////////////////////////////////////////////////
79 :
80 0 : inline float ref_WrapDegrees180(float f)
81 : {
82 : // This is a slower alternative to the wrapDegrees_180() function;
83 : // used as a reference for testing
84 0 : float value = fmodf(f + 180, 360);
85 0 : if (value < 0)
86 0 : value += 360;
87 0 : return value - 180;
88 : }
89 :
90 :
91 0 : inline float ref_WrapDegrees_0_360(float f)
92 : {
93 : // This is a slower alternative to the wrapDegrees_0_360() function;
94 : // used as a reference for testing
95 0 : float value = fmodf(f, 360);
96 0 : if (value < 0)
97 0 : value += 360;
98 0 : return value < 0 ? value + 360 : value;
99 : }
100 :
101 :
102 0 : void TestUtilities::testAngleWrapAround()
103 : {
104 0 : UASSERT(fabs(modulo360f(100.0) - 100.0) < 0.001);
105 0 : UASSERT(fabs(modulo360f(720.5) - 0.5) < 0.001);
106 0 : UASSERT(fabs(modulo360f(-0.5) - (-0.5)) < 0.001);
107 0 : UASSERT(fabs(modulo360f(-365.5) - (-5.5)) < 0.001);
108 :
109 0 : for (float f = -720; f <= -360; f += 0.25) {
110 0 : UASSERT(fabs(modulo360f(f) - modulo360f(f + 360)) < 0.001);
111 : }
112 :
113 0 : for (float f = -1440; f <= 1440; f += 0.25) {
114 0 : UASSERT(fabs(modulo360f(f) - fmodf(f, 360)) < 0.001);
115 0 : UASSERT(fabs(wrapDegrees_180(f) - ref_WrapDegrees180(f)) < 0.001);
116 0 : UASSERT(fabs(wrapDegrees_0_360(f) - ref_WrapDegrees_0_360(f)) < 0.001);
117 0 : UASSERT(wrapDegrees_0_360(fabs(wrapDegrees_180(f) - wrapDegrees_0_360(f))) < 0.001);
118 : }
119 0 : }
120 :
121 :
122 0 : void TestUtilities::testLowercase()
123 : {
124 0 : UASSERT(lowercase("Foo bAR") == "foo bar");
125 0 : }
126 :
127 :
128 0 : void TestUtilities::testTrim()
129 : {
130 0 : UASSERT(trim("") == "");
131 0 : UASSERT(trim("dirt_with_grass") == "dirt_with_grass");
132 0 : UASSERT(trim("\n \t\r Foo bAR \r\n\t\t ") == "Foo bAR");
133 0 : UASSERT(trim("\n \t\r \r\n\t\t ") == "");
134 0 : }
135 :
136 :
137 0 : void TestUtilities::testIsYes()
138 : {
139 0 : UASSERT(is_yes("YeS") == true);
140 0 : UASSERT(is_yes("") == false);
141 0 : UASSERT(is_yes("FAlse") == false);
142 0 : UASSERT(is_yes("-1") == true);
143 0 : UASSERT(is_yes("0") == false);
144 0 : UASSERT(is_yes("1") == true);
145 0 : UASSERT(is_yes("2") == true);
146 0 : }
147 :
148 :
149 0 : void TestUtilities::testRemoveStringEnd()
150 : {
151 0 : const char *ends[] = {"abc", "c", "bc", "", NULL};
152 0 : UASSERT(removeStringEnd("abc", ends) == "");
153 0 : UASSERT(removeStringEnd("bc", ends) == "b");
154 0 : UASSERT(removeStringEnd("12c", ends) == "12");
155 0 : UASSERT(removeStringEnd("foo", ends) == "");
156 0 : }
157 :
158 :
159 0 : void TestUtilities::testUrlEncode()
160 : {
161 0 : UASSERT(urlencode("\"Aardvarks lurk, OK?\"")
162 0 : == "%22Aardvarks%20lurk%2C%20OK%3F%22");
163 0 : }
164 :
165 :
166 0 : void TestUtilities::testUrlDecode()
167 : {
168 0 : UASSERT(urldecode("%22Aardvarks%20lurk%2C%20OK%3F%22")
169 0 : == "\"Aardvarks lurk, OK?\"");
170 0 : }
171 :
172 :
173 0 : void TestUtilities::testPadString()
174 : {
175 0 : UASSERT(padStringRight("hello", 8) == "hello ");
176 0 : }
177 :
178 0 : void TestUtilities::testStartsWith()
179 : {
180 0 : UASSERT(str_starts_with(std::string(), std::string()) == true);
181 0 : UASSERT(str_starts_with(std::string("the sharp pickaxe"),
182 0 : std::string()) == true);
183 0 : UASSERT(str_starts_with(std::string("the sharp pickaxe"),
184 0 : std::string("the")) == true);
185 0 : UASSERT(str_starts_with(std::string("the sharp pickaxe"),
186 0 : std::string("The")) == false);
187 0 : UASSERT(str_starts_with(std::string("the sharp pickaxe"),
188 0 : std::string("The"), true) == true);
189 0 : UASSERT(str_starts_with(std::string("T"), std::string("The")) == false);
190 0 : }
191 :
192 0 : void TestUtilities::testStrEqual()
193 : {
194 0 : UASSERT(str_equal(narrow_to_wide("abc"), narrow_to_wide("abc")));
195 0 : UASSERT(str_equal(narrow_to_wide("ABC"), narrow_to_wide("abc"), true));
196 0 : }
197 :
198 :
199 0 : void TestUtilities::testStringTrim()
200 : {
201 0 : UASSERT(trim(" a") == "a");
202 0 : UASSERT(trim(" a ") == "a");
203 0 : UASSERT(trim("a ") == "a");
204 0 : UASSERT(trim("") == "");
205 0 : }
206 :
207 :
208 0 : void TestUtilities::testStrToIntConversion()
209 : {
210 0 : UASSERT(mystoi("123", 0, 1000) == 123);
211 0 : UASSERT(mystoi("123", 0, 10) == 10);
212 0 : }
213 :
214 :
215 0 : void TestUtilities::testStringReplace()
216 : {
217 0 : std::string test_str;
218 0 : test_str = "Hello there";
219 0 : str_replace(test_str, "there", "world");
220 0 : UASSERT(test_str == "Hello world");
221 0 : test_str = "ThisAisAaAtest";
222 0 : str_replace(test_str, 'A', ' ');
223 0 : UASSERT(test_str == "This is a test");
224 0 : }
225 :
226 :
227 0 : void TestUtilities::testStringAllowed()
228 : {
229 0 : UASSERT(string_allowed("hello", "abcdefghijklmno") == true);
230 0 : UASSERT(string_allowed("123", "abcdefghijklmno") == false);
231 0 : UASSERT(string_allowed_blacklist("hello", "123") == true);
232 0 : UASSERT(string_allowed_blacklist("hello123", "123") == false);
233 0 : }
234 :
235 0 : void TestUtilities::testUTF8()
236 : {
237 0 : UASSERT(wide_to_utf8(utf8_to_wide("")) == "");
238 0 : UASSERT(wide_to_utf8(utf8_to_wide("the shovel dug a crumbly node!"))
239 0 : == "the shovel dug a crumbly node!");
240 0 : }
241 :
242 0 : void TestUtilities::testWrapRows()
243 : {
244 0 : UASSERT(wrap_rows("12345678",4) == "1234\n5678");
245 : // test that wrap_rows doesn't wrap inside multibyte sequences
246 : {
247 : const unsigned char s[] = {
248 : 0x2f, 0x68, 0x6f, 0x6d, 0x65, 0x2f, 0x72, 0x61, 0x70, 0x74, 0x6f,
249 : 0x72, 0x2f, 0xd1, 0x82, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x82, 0x2f,
250 : 0x6d, 0x69, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x74, 0x2f, 0x62, 0x69,
251 0 : 0x6e, 0x2f, 0x2e, 0x2e, 0};
252 0 : std::string str((char *)s);
253 0 : UASSERT(utf8_to_wide(wrap_rows(str, 20)) != L"<invalid UTF-8 string>");
254 : };
255 : {
256 : const unsigned char s[] = {
257 : 0x74, 0x65, 0x73, 0x74, 0x20, 0xd1, 0x82, 0xd0, 0xb5, 0xd1, 0x81,
258 : 0xd1, 0x82, 0x20, 0xd1, 0x82, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x82,
259 0 : 0x20, 0xd1, 0x82, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x82, 0};
260 0 : std::string str((char *)s);
261 0 : UASSERT(utf8_to_wide(wrap_rows(str, 8)) != L"<invalid UTF-8 string>");
262 : }
263 0 : }
264 :
265 :
266 0 : void TestUtilities::testIsNumber()
267 : {
268 0 : UASSERT(is_number("123") == true);
269 0 : UASSERT(is_number("") == false);
270 0 : UASSERT(is_number("123a") == false);
271 0 : }
272 :
273 :
274 0 : void TestUtilities::testIsPowerOfTwo()
275 : {
276 0 : UASSERT(is_power_of_two(0) == false);
277 0 : UASSERT(is_power_of_two(1) == true);
278 0 : UASSERT(is_power_of_two(2) == true);
279 0 : UASSERT(is_power_of_two(3) == false);
280 0 : for (int exponent = 2; exponent <= 31; ++exponent) {
281 0 : UASSERT(is_power_of_two((1 << exponent) - 1) == false);
282 0 : UASSERT(is_power_of_two((1 << exponent)) == true);
283 0 : UASSERT(is_power_of_two((1 << exponent) + 1) == false);
284 : }
285 0 : UASSERT(is_power_of_two((u32)-1) == false);
286 0 : }
287 :
288 0 : void TestUtilities::testMyround()
289 : {
290 0 : UASSERT(myround(4.6f) == 5);
291 0 : UASSERT(myround(1.2f) == 1);
292 0 : UASSERT(myround(-3.1f) == -3);
293 0 : UASSERT(myround(-6.5f) == -7);
294 3 : }
295 :
|