]> git.lizzy.rs Git - dragonfireclient.git/blob - src/unittest/test_utilities.cpp
Remove deprecated code segments (#5891)
[dragonfireclient.git] / src / unittest / test_utilities.cpp
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 class TestUtilities : public TestBase {
26 public:
27         TestUtilities() { TestManager::registerTestModule(this); }
28         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 testAsciiPrintableHelper();
47         void testUTF8();
48         void testRemoveEscapes();
49         void testWrapRows();
50         void testIsNumber();
51         void testIsPowerOfTwo();
52         void testMyround();
53 };
54
55 static TestUtilities g_test_instance;
56
57 void TestUtilities::runTests(IGameDef *gamedef)
58 {
59         TEST(testAngleWrapAround);
60         TEST(testLowercase);
61         TEST(testTrim);
62         TEST(testIsYes);
63         TEST(testRemoveStringEnd);
64         TEST(testUrlEncode);
65         TEST(testUrlDecode);
66         TEST(testPadString);
67         TEST(testStartsWith);
68         TEST(testStrEqual);
69         TEST(testStringTrim);
70         TEST(testStrToIntConversion);
71         TEST(testStringReplace);
72         TEST(testStringAllowed);
73         TEST(testAsciiPrintableHelper);
74         TEST(testUTF8);
75         TEST(testRemoveEscapes);
76         TEST(testWrapRows);
77         TEST(testIsNumber);
78         TEST(testIsPowerOfTwo);
79         TEST(testMyround);
80 }
81
82 ////////////////////////////////////////////////////////////////////////////////
83
84 inline float ref_WrapDegrees180(float f)
85 {
86         // This is a slower alternative to the wrapDegrees_180() function;
87         // used as a reference for testing
88         float value = fmodf(f + 180, 360);
89         if (value < 0)
90                 value += 360;
91         return value - 180;
92 }
93
94
95 inline float ref_WrapDegrees_0_360(float f)
96 {
97         // This is a slower alternative to the wrapDegrees_0_360() function;
98         // used as a reference for testing
99         float value = fmodf(f, 360);
100         if (value < 0)
101                 value += 360;
102         return value < 0 ? value + 360 : value;
103 }
104
105
106 void TestUtilities::testAngleWrapAround()
107 {
108         UASSERT(fabs(modulo360f(100.0) - 100.0) < 0.001);
109         UASSERT(fabs(modulo360f(720.5) - 0.5) < 0.001);
110         UASSERT(fabs(modulo360f(-0.5) - (-0.5)) < 0.001);
111         UASSERT(fabs(modulo360f(-365.5) - (-5.5)) < 0.001);
112
113         for (float f = -720; f <= -360; f += 0.25) {
114                 UASSERT(fabs(modulo360f(f) - modulo360f(f + 360)) < 0.001);
115         }
116
117         for (float f = -1440; f <= 1440; f += 0.25) {
118                 UASSERT(fabs(modulo360f(f) - fmodf(f, 360)) < 0.001);
119                 UASSERT(fabs(wrapDegrees_180(f) - ref_WrapDegrees180(f)) < 0.001);
120                 UASSERT(fabs(wrapDegrees_0_360(f) - ref_WrapDegrees_0_360(f)) < 0.001);
121                 UASSERT(wrapDegrees_0_360(fabs(wrapDegrees_180(f) - wrapDegrees_0_360(f))) < 0.001);
122         }
123 }
124
125
126 void TestUtilities::testLowercase()
127 {
128         UASSERT(lowercase("Foo bAR") == "foo bar");
129 }
130
131
132 void TestUtilities::testTrim()
133 {
134         UASSERT(trim("") == "");
135         UASSERT(trim("dirt_with_grass") == "dirt_with_grass");
136         UASSERT(trim("\n \t\r  Foo bAR  \r\n\t\t  ") == "Foo bAR");
137         UASSERT(trim("\n \t\r    \r\n\t\t  ") == "");
138 }
139
140
141 void TestUtilities::testIsYes()
142 {
143         UASSERT(is_yes("YeS") == true);
144         UASSERT(is_yes("") == false);
145         UASSERT(is_yes("FAlse") == false);
146         UASSERT(is_yes("-1") == true);
147         UASSERT(is_yes("0") == false);
148         UASSERT(is_yes("1") == true);
149         UASSERT(is_yes("2") == true);
150 }
151
152
153 void TestUtilities::testRemoveStringEnd()
154 {
155         const char *ends[] = {"abc", "c", "bc", "", NULL};
156         UASSERT(removeStringEnd("abc", ends) == "");
157         UASSERT(removeStringEnd("bc", ends) == "b");
158         UASSERT(removeStringEnd("12c", ends) == "12");
159         UASSERT(removeStringEnd("foo", ends) == "");
160 }
161
162
163 void TestUtilities::testUrlEncode()
164 {
165         UASSERT(urlencode("\"Aardvarks lurk, OK?\"")
166                         == "%22Aardvarks%20lurk%2C%20OK%3F%22");
167 }
168
169
170 void TestUtilities::testUrlDecode()
171 {
172         UASSERT(urldecode("%22Aardvarks%20lurk%2C%20OK%3F%22")
173                         == "\"Aardvarks lurk, OK?\"");
174 }
175
176
177 void TestUtilities::testPadString()
178 {
179         UASSERT(padStringRight("hello", 8) == "hello   ");
180 }
181
182 void TestUtilities::testStartsWith()
183 {
184         UASSERT(str_starts_with(std::string(), std::string()) == true);
185         UASSERT(str_starts_with(std::string("the sharp pickaxe"),
186                 std::string()) == true);
187         UASSERT(str_starts_with(std::string("the sharp pickaxe"),
188                 std::string("the")) == true);
189         UASSERT(str_starts_with(std::string("the sharp pickaxe"),
190                 std::string("The")) == false);
191         UASSERT(str_starts_with(std::string("the sharp pickaxe"),
192                 std::string("The"), true) == true);
193         UASSERT(str_starts_with(std::string("T"), std::string("The")) == false);
194 }
195
196 void TestUtilities::testStrEqual()
197 {
198         UASSERT(str_equal(narrow_to_wide("abc"), narrow_to_wide("abc")));
199         UASSERT(str_equal(narrow_to_wide("ABC"), narrow_to_wide("abc"), true));
200 }
201
202
203 void TestUtilities::testStringTrim()
204 {
205         UASSERT(trim("  a") == "a");
206         UASSERT(trim("   a  ") == "a");
207         UASSERT(trim("a   ") == "a");
208         UASSERT(trim("") == "");
209 }
210
211
212 void TestUtilities::testStrToIntConversion()
213 {
214         UASSERT(mystoi("123", 0, 1000) == 123);
215         UASSERT(mystoi("123", 0, 10) == 10);
216 }
217
218
219 void TestUtilities::testStringReplace()
220 {
221         std::string test_str;
222         test_str = "Hello there";
223         str_replace(test_str, "there", "world");
224         UASSERT(test_str == "Hello world");
225         test_str = "ThisAisAaAtest";
226         str_replace(test_str, 'A', ' ');
227         UASSERT(test_str == "This is a test");
228 }
229
230
231 void TestUtilities::testStringAllowed()
232 {
233         UASSERT(string_allowed("hello", "abcdefghijklmno") == true);
234         UASSERT(string_allowed("123", "abcdefghijklmno") == false);
235         UASSERT(string_allowed_blacklist("hello", "123") == true);
236         UASSERT(string_allowed_blacklist("hello123", "123") == false);
237 }
238
239 void TestUtilities::testAsciiPrintableHelper()
240 {
241         UASSERT(IS_ASCII_PRINTABLE_CHAR('e') == true);
242         UASSERT(IS_ASCII_PRINTABLE_CHAR('\0') == false);
243
244         // Ensures that there is no cutting off going on...
245         // If there were, 331 would be cut to 75 in this example
246         // and 73 is a valid ASCII char.
247         int ch = 331;
248         UASSERT(IS_ASCII_PRINTABLE_CHAR(ch) == false);
249 }
250
251 void TestUtilities::testUTF8()
252 {
253         UASSERT(wide_to_utf8(utf8_to_wide("")) == "");
254         UASSERT(wide_to_utf8(utf8_to_wide("the shovel dug a crumbly node!"))
255                 == "the shovel dug a crumbly node!");
256 }
257
258 void TestUtilities::testRemoveEscapes()
259 {
260         UASSERT(unescape_enriched<wchar_t>(
261                 L"abc\x1bXdef") == L"abcdef");
262         UASSERT(unescape_enriched<wchar_t>(
263                 L"abc\x1b(escaped)def") == L"abcdef");
264         UASSERT(unescape_enriched<wchar_t>(
265                 L"abc\x1b((escaped with parenthesis\\))def") == L"abcdef");
266         UASSERT(unescape_enriched<wchar_t>(
267                 L"abc\x1b(incomplete") == L"abc");
268         UASSERT(unescape_enriched<wchar_t>(
269                 L"escape at the end\x1b") == L"escape at the end");
270         // Nested escapes not supported
271         UASSERT(unescape_enriched<wchar_t>(
272                 L"abc\x1b(outer \x1b(inner escape)escape)def") == L"abcescape)def");
273 }
274
275 void TestUtilities::testWrapRows()
276 {
277         UASSERT(wrap_rows("12345678",4) == "1234\n5678");
278         // test that wrap_rows doesn't wrap inside multibyte sequences
279         {
280                 const unsigned char s[] = {
281                         0x2f, 0x68, 0x6f, 0x6d, 0x65, 0x2f, 0x72, 0x61, 0x70, 0x74, 0x6f,
282                         0x72, 0x2f, 0xd1, 0x82, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x82, 0x2f,
283                         0x6d, 0x69, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x74, 0x2f, 0x62, 0x69,
284                         0x6e, 0x2f, 0x2e, 0x2e, 0};
285                 std::string str((char *)s);
286                 UASSERT(utf8_to_wide(wrap_rows(str, 20)) != L"<invalid UTF-8 string>");
287         };
288         {
289                 const unsigned char s[] = {
290                         0x74, 0x65, 0x73, 0x74, 0x20, 0xd1, 0x82, 0xd0, 0xb5, 0xd1, 0x81,
291                         0xd1, 0x82, 0x20, 0xd1, 0x82, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x82,
292                         0x20, 0xd1, 0x82, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x82, 0};
293                 std::string str((char *)s);
294                 UASSERT(utf8_to_wide(wrap_rows(str, 8)) != L"<invalid UTF-8 string>");
295         }
296 }
297
298
299 void TestUtilities::testIsNumber()
300 {
301         UASSERT(is_number("123") == true);
302         UASSERT(is_number("") == false);
303         UASSERT(is_number("123a") == false);
304 }
305
306
307 void TestUtilities::testIsPowerOfTwo()
308 {
309         UASSERT(is_power_of_two(0) == false);
310         UASSERT(is_power_of_two(1) == true);
311         UASSERT(is_power_of_two(2) == true);
312         UASSERT(is_power_of_two(3) == false);
313         for (int exponent = 2; exponent <= 31; ++exponent) {
314                 UASSERT(is_power_of_two((1 << exponent) - 1) == false);
315                 UASSERT(is_power_of_two((1 << exponent)) == true);
316                 UASSERT(is_power_of_two((1 << exponent) + 1) == false);
317         }
318         UASSERT(is_power_of_two(U32_MAX) == false);
319 }
320
321 void TestUtilities::testMyround()
322 {
323         UASSERT(myround(4.6f) == 5);
324         UASSERT(myround(1.2f) == 1);
325         UASSERT(myround(-3.1f) == -3);
326         UASSERT(myround(-6.5f) == -7);
327 }
328