Line data Source code
1 : // Copyright (c) 2015-2022 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/csspp
4 : // contact@m2osw.com
5 : //
6 : // This program is free software; you can redistribute it and/or modify
7 : // it under the terms of the GNU General Public License as published by
8 : // the Free Software Foundation; either version 2 of the License, or
9 : // (at your option) any later version.
10 : //
11 : // This program is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 : //
16 : // You should have received a copy of the GNU General Public License along
17 : // with this program; if not, write to the Free Software Foundation, Inc.,
18 : // 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 :
20 : /** \file
21 : * \brief Test the unicode_range.cpp file.
22 : *
23 : * This test runs a battery of tests agains the unicode_range.cpp
24 : * implementation to ensure full coverage.
25 : */
26 :
27 : // csspp
28 : //
29 : #include <csspp/unicode_range.h>
30 :
31 : #include <csspp/exception.h>
32 : #include <csspp/lexer.h>
33 :
34 :
35 : // self
36 : //
37 : #include "catch_main.h"
38 :
39 :
40 : // C++
41 : //
42 : #include <sstream>
43 :
44 :
45 : // C
46 : //
47 : #include <string.h>
48 :
49 :
50 : // last include
51 : //
52 : #include <snapdev/poison.h>
53 :
54 :
55 :
56 : namespace
57 : {
58 :
59 :
60 : } // no name namespace
61 :
62 :
63 1 : CATCH_TEST_CASE("Unicode range: start/end equal", "[unicode-range] [code-point]")
64 : {
65 1001 : for(int i(0); i < 1000; ++i)
66 : {
67 1000 : csspp::wide_char_t unicode(rand() % 0x110000);
68 1000 : csspp::unicode_range_t range(unicode, unicode);
69 :
70 1000 : std::stringstream ss;
71 1000 : ss << std::hex << unicode;
72 :
73 1000 : CATCH_REQUIRE(range.to_string() == ss.str());
74 1000 : }
75 :
76 : // no error left over
77 1 : VERIFY_ERRORS("");
78 1 : }
79 :
80 1 : CATCH_TEST_CASE("Unicode range: start/end differ", "[unicode-range] [range]")
81 : {
82 15 : for(int i(1); i < 15; ++i)
83 : {
84 14 : csspp::unicode_range_t range(0, i);
85 :
86 14 : std::stringstream ss;
87 14 : ss << std::hex << "0-" << i;
88 :
89 14 : CATCH_REQUIRE(range.to_string() == ss.str());
90 14 : }
91 :
92 1001 : for(int i(0); i < 1000; ++i)
93 : {
94 1000 : csspp::wide_char_t unicode_start;
95 1000 : csspp::wide_char_t unicode_end;
96 :
97 : // try once with the range construtor
98 : do
99 : {
100 1000 : unicode_start = rand() % 0x110000;
101 1000 : unicode_end = rand() % 0x110000;
102 1000 : if(unicode_start > unicode_end)
103 : {
104 497 : std::swap(unicode_start, unicode_end);
105 : }
106 1070 : while((unicode_end & 15) == 15)
107 : {
108 70 : unicode_end &= rand() % 15;
109 70 : if(unicode_start > unicode_end)
110 : {
111 68 : std::swap(unicode_start, unicode_end);
112 : }
113 : }
114 : }
115 1000 : while(unicode_start == unicode_end);
116 1000 : csspp::unicode_range_t range(unicode_start, unicode_end);
117 :
118 1000 : csspp_test::our_unicode_range_t our_range(unicode_start, unicode_end);
119 1000 : CATCH_REQUIRE(range.get_range() == our_range.get_range());
120 :
121 1000 : CATCH_REQUIRE(range.get_start() == unicode_start);
122 1000 : CATCH_REQUIRE(range.get_end() == unicode_end);
123 :
124 1000 : std::stringstream ss;
125 1000 : ss << std::hex << unicode_start << "-" << unicode_end;
126 :
127 1000 : CATCH_REQUIRE(range.to_string() == ss.str());
128 :
129 : // try again with new values and using set_range(start, end)
130 : do
131 : {
132 1000 : unicode_start = rand() % 0x110000;
133 1000 : unicode_end = rand() % 0x110000;
134 1000 : if(unicode_start > unicode_end)
135 : {
136 490 : std::swap(unicode_start, unicode_end);
137 : }
138 1061 : while((unicode_end & 15) == 15)
139 : {
140 61 : unicode_end &= rand() % 15;
141 61 : if(unicode_start > unicode_end)
142 : {
143 60 : std::swap(unicode_start, unicode_end);
144 : }
145 : }
146 : }
147 1000 : while(unicode_start == unicode_end);
148 1000 : range.set_range(unicode_start, unicode_end);
149 :
150 1000 : our_range.set_start(unicode_start);
151 1000 : our_range.set_end(unicode_end);
152 1000 : CATCH_REQUIRE(range.get_range() == our_range.get_range());
153 :
154 1000 : CATCH_REQUIRE(range.get_start() == unicode_start);
155 1000 : CATCH_REQUIRE(range.get_end() == unicode_end);
156 :
157 1000 : ss.str("");
158 1000 : ss << std::hex << unicode_start << "-" << unicode_end;
159 :
160 1000 : CATCH_REQUIRE(range.to_string() == ss.str());
161 :
162 : // try again with new values and using set_range(range)
163 : do
164 : {
165 1000 : unicode_start = rand() % 0x110000;
166 1000 : unicode_end = rand() % 0x110000;
167 1000 : if(unicode_start > unicode_end)
168 : {
169 488 : std::swap(unicode_start, unicode_end);
170 : }
171 1066 : while((unicode_end & 15) == 15)
172 : {
173 66 : unicode_end &= rand() % 15;
174 66 : if(unicode_start > unicode_end)
175 : {
176 65 : std::swap(unicode_start, unicode_end);
177 : }
178 : }
179 : }
180 1000 : while(unicode_start == unicode_end);
181 :
182 1000 : our_range.set_start(unicode_start);
183 1000 : our_range.set_end(unicode_end);
184 :
185 1000 : range.set_range(our_range.get_range());
186 :
187 1000 : CATCH_REQUIRE(range.get_range() == our_range.get_range());
188 :
189 1000 : CATCH_REQUIRE(range.get_start() == unicode_start);
190 1000 : CATCH_REQUIRE(range.get_end() == unicode_end);
191 :
192 1000 : ss.str("");
193 1000 : ss << std::hex << unicode_start << "-" << unicode_end;
194 :
195 1000 : CATCH_REQUIRE(range.to_string() == ss.str());
196 :
197 : // try again with new values and using range constructor with range value
198 : do
199 : {
200 1000 : unicode_start = rand() % 0x110000;
201 1000 : unicode_end = rand() % 0x110000;
202 1000 : if(unicode_start > unicode_end)
203 : {
204 509 : std::swap(unicode_start, unicode_end);
205 : }
206 1072 : while((unicode_end & 15) == 15)
207 : {
208 72 : unicode_end &= rand() % 15;
209 72 : if(unicode_start > unicode_end)
210 : {
211 69 : std::swap(unicode_start, unicode_end);
212 : }
213 : }
214 : }
215 1000 : while(unicode_start == unicode_end);
216 :
217 1000 : our_range.set_start(unicode_start);
218 1000 : our_range.set_end(unicode_end);
219 :
220 1000 : csspp::unicode_range_t new_range(our_range.get_range());
221 :
222 1000 : CATCH_REQUIRE(new_range.get_range() == our_range.get_range());
223 :
224 1000 : CATCH_REQUIRE(new_range.get_start() == unicode_start);
225 1000 : CATCH_REQUIRE(new_range.get_end() == unicode_end);
226 :
227 1000 : ss.str("");
228 1000 : ss << std::hex << unicode_start << "-" << unicode_end;
229 :
230 1000 : CATCH_REQUIRE(new_range.to_string() == ss.str());
231 1000 : }
232 :
233 : // no error left over
234 1 : VERIFY_ERRORS("");
235 1 : }
236 :
237 1 : CATCH_TEST_CASE("Unicode range: 6 x '?'", "[unicode-range] [mask]")
238 : {
239 : // the mask of 6 x '?' is a special case
240 : {
241 1 : csspp::unicode_range_t range(0, 0x10FFFF);
242 :
243 1 : CATCH_REQUIRE(range.to_string() == "??????");
244 : }
245 :
246 : // no error left over
247 1 : VERIFY_ERRORS("");
248 1 : }
249 :
250 1 : CATCH_TEST_CASE("Unicode range: 5 x '?'", "[unicode-range] [mask]")
251 : {
252 : // a mask of 5 x '?' has a very few possibilities
253 : {
254 1 : csspp::unicode_range_t range(0, 0x0FFFFF);
255 :
256 1 : CATCH_REQUIRE(range.to_string() == "?????");
257 : }
258 :
259 : {
260 : // this is a special range where the maximum (end) is larger
261 : // than what Unicode otherwise allows...
262 1 : csspp::unicode_range_t range(0x100000, 0x1FFFFF);
263 :
264 1 : CATCH_REQUIRE(range.to_string() == "1?????");
265 : }
266 :
267 : // no error left over
268 1 : VERIFY_ERRORS("");
269 1 : }
270 :
271 1 : CATCH_TEST_CASE("Unicode range: 4 x '?'", "[unicode-range] [mask]")
272 : {
273 : // a mask of 4 x '?' has a small number of possibilities
274 : {
275 1 : csspp::unicode_range_t range(0, 0x00FFFF);
276 :
277 1 : CATCH_REQUIRE(range.to_string() == "????");
278 : }
279 :
280 17 : for(int i(1); i < 0x11; ++i)
281 : {
282 16 : csspp::unicode_range_t range(i << 16, (i << 16) | 0x00FFFF);
283 :
284 16 : std::stringstream ss;
285 16 : ss << std::hex << i << "????";
286 :
287 16 : CATCH_REQUIRE(range.to_string() == ss.str());
288 16 : }
289 :
290 : // no error left over
291 1 : VERIFY_ERRORS("");
292 1 : }
293 :
294 1 : CATCH_TEST_CASE("Unicode range: 3 x '?'", "[unicode-range] [mask]")
295 : {
296 : // a mask of 3 x '?' has a small number of possibilities
297 : {
298 1 : csspp::unicode_range_t range(0, 0x000FFF);
299 :
300 1 : CATCH_REQUIRE(range.to_string() == "???");
301 : }
302 :
303 271 : for(int i(1); i < 0x10F; ++i)
304 : {
305 270 : csspp::unicode_range_t range(i << 12, (i << 12) | 0x000FFF);
306 :
307 270 : std::stringstream ss;
308 270 : ss << std::hex << i << "???";
309 :
310 270 : CATCH_REQUIRE(range.to_string() == ss.str());
311 270 : }
312 :
313 : // no error left over
314 1 : VERIFY_ERRORS("");
315 1 : }
316 :
317 1 : CATCH_TEST_CASE("Unicode range: 2 x '?'", "[unicode-range] [mask]")
318 : {
319 : // a mask of 2 x '?' has a small number of possibilities
320 : {
321 1 : csspp::unicode_range_t range(0, 0x0000FF);
322 :
323 1 : CATCH_REQUIRE(range.to_string() == "??");
324 : }
325 :
326 4351 : for(int i(1); i < 0x10FF; ++i)
327 : {
328 4350 : csspp::unicode_range_t range(i << 8, (i << 8) | 0x0000FF);
329 :
330 4350 : std::stringstream ss;
331 4350 : ss << std::hex << i << "??";
332 :
333 4350 : CATCH_REQUIRE(range.to_string() == ss.str());
334 4350 : }
335 :
336 : // no error left over
337 1 : VERIFY_ERRORS("");
338 1 : }
339 :
340 1 : CATCH_TEST_CASE("Unicode range: 1 x '?'", "[unicode-range] [mask]")
341 : {
342 : // a mask of 1 x '?' has a small number of possibilities
343 : {
344 1 : csspp::unicode_range_t range(0, 0x00000F);
345 :
346 1 : CATCH_REQUIRE(range.to_string() == "?");
347 : }
348 :
349 69631 : for(int i(1); i < 0x10FFF; ++i)
350 : {
351 69630 : csspp::unicode_range_t range(i << 4, (i << 4) | 0x00000F);
352 :
353 69630 : std::stringstream ss;
354 69630 : ss << std::hex << i << "?";
355 :
356 69630 : CATCH_REQUIRE(range.to_string() == ss.str());
357 69630 : }
358 :
359 : // no error left over
360 1 : VERIFY_ERRORS("");
361 1 : }
362 :
363 1 : CATCH_TEST_CASE("Unicode range: invalid start/end values", "[unicode-range] [code-point]")
364 : {
365 : // Do a little more?
366 2 : CATCH_REQUIRE_THROWS_AS(new csspp::unicode_range_t(0x110000, 0x012345), csspp::csspp_exception_overflow);
367 2 : CATCH_REQUIRE_THROWS_AS(new csspp::unicode_range_t(0x012345, 0x200000), csspp::csspp_exception_overflow);
368 2 : CATCH_REQUIRE_THROWS_AS(new csspp::unicode_range_t(0x004000, 0x000200), csspp::csspp_exception_overflow);
369 :
370 : // no error left over
371 1 : VERIFY_ERRORS("");
372 1 : }
373 :
374 : // vim: ts=4 sw=4 et
|