feisty meow concerns codebase 2.140
test_string.cpp
Go to the documentation of this file.
1/*****************************************************************************\
2* *
3* Name : test_string *
4* Author : Chris Koeritz *
5* *
6*******************************************************************************
7* Copyright (c) 1992-$now By Author. This program is free software; you can *
8* redistribute it and/or modify it under the terms of the GNU General Public *
9* License as published by the Free Software Foundation; either version 2 of *
10* the License or (at your option) any later version. This is online at: *
11* http://www.fsf.org/copyleft/gpl.html *
12* Please send any updates to: fred@gruntose.com *
13\*****************************************************************************/
14
15//#define DEBUG_STRING
16 // set this to enable debugging features of the string class.
17
19#include <basis/astring.h>
20#include <basis/enhance_cpp.h>
21#include <basis/functions.h>
22#include <basis/guards.h>
24#include <loggers/file_logger.h>
25#include <mathematics/chaos.h>
32#include <timely/earth_time.h>
33#include <timely/time_stamp.h>
34#include <unit_test/unit_base.h>
35
36//#ifdef _MSC_VER
37// #include <comdef.h>
38//#endif
39#include <stdio.h>
40#include <stdlib.h>
41#include <string.h>
42
43using namespace application;
44using namespace basis;
45using namespace loggers;
46using namespace mathematics;
47using namespace structures;
48using namespace textual;
49using namespace timely;
50using namespace unit_test;
51
52//#define DEBUG_STRING_TEST
53 // uncomment for testing version.
54
55const float TEST_RUNTIME_DEFAULT = .02 * MINUTE_ms;
56 // the test, by default, will run for this long.
57
59
60class test_string : public application_shell, public unit_base
61{
62public:
63 test_string() {}
64 ~test_string() {}
65
66 DEFINE_CLASS_NAME("test_string");
67
68 virtual int execute();
69
70 void run_test_01();
71 void run_test_02();
72 void run_test_03();
73 void run_test_04();
74 void run_test_05();
75 void run_test_06();
76 void run_test_07();
77 void run_test_08();
78 void run_test_09();
79 void run_test_10();
80 void run_test_11();
81 void run_test_12();
82 void run_test_13();
83 void run_test_14();
84 void run_test_15();
85 void run_test_16();
86 void run_test_17();
87 void run_test_18();
88 void run_test_19();
89 void run_test_20();
90 void run_test_21();
91 void run_test_22();
92 void run_test_23();
93 void run_test_24();
94 void run_test_25();
95 void run_test_26();
96 void run_test_27();
97 void run_test_28();
98 void run_test_29();
99 void run_test_30();
100 void run_test_31();
101 void run_test_32();
102 void run_test_33();
103 void run_test_34();
104 void run_test_35();
105 void run_test_36();
106 void run_test_37();
107 void run_test_38();
108 void run_test_39();
109 void run_test_40();
110 void run_test_41();
111 void run_test_42();
112};
113
115
117
118#define LOG(s) EMERGENCY_LOG(program_wide_logger::get(), s)
119
120#define WHERE __WHERE__.s()
121
122// test: reports an error if the condition evaluates to non-zero.
123#define test(expr) { \
124 ASSERT_FALSE(expr, astring("operator test should work: ") + #expr); \
125}
126
127static basis::astring staticity_test("yo!");
128 // used below to check whether static strings are looking right.
129
131
132void test_string::run_test_01()
133{
134 FUNCDEF("run_test_01");
135
136// const int TEST_EMPTY = 10000000;
137// time_stamp started;
138// for (int i = 0; i < TEST_EMPTY; i++) {
139// astring glob = astring::empty_string();
140// }
141// int duration = int(time_stamp().value() - started.value());
142// LOG(a_sprintf("duration of empty string test=%d ms", duration));
143
144 // test simple string operations, like construction, length, equality.
145 astring fred1("hyeargh!");
146 astring fred2("matey.");
147 astring fred3;
148 fred3 = fred1;
149 fred3 += fred2;
150 astring fred4(fred2);
151
152 ASSERT_EQUAL(fred1.length(), int(strlen(fred1.s())), "length should be correct (a).");
153 ASSERT_EQUAL(fred2.length(), int(strlen(fred2.s())), "length should be correct (b).");
154 ASSERT_EQUAL(fred3.length(), int(strlen(fred3.s())), "length should be correct (c).");
155 ASSERT_EQUAL(fred4.length(), int(strlen(fred4.s())), "length should be correct (d).");
156
157#ifdef DEBUG_STRING_TEST
158 LOG("[ " + fred1 + " & " + fred2 + "] -> " + fred3);
159#endif
160
161 ASSERT_EQUAL(fred1, astring("hyeargh!"), "failure in comparison (a).");
162 ASSERT_EQUAL(fred2, astring("matey."), "failure in comparison (b).");
163 ASSERT_EQUAL(fred3, astring("hyeargh!matey."), "failure in comparison (c).");
164 ASSERT_EQUAL(fred4, astring("matey."), "failure in comparison (d-1).");
165 ASSERT_EQUAL(fred4, fred2, "failure in comparison (d-2).");
166
167 a_sprintf nullo;
168 ASSERT_EQUAL(nullo, astring(), "forward blank a_sprintf isn't blank.");
169 ASSERT_EQUAL(astring(), nullo, "backward blank a_sprintf isn't blank.");
170 ASSERT_EQUAL(nullo, astring::empty_string(), "forward blank a_sprintf isn't empty.");
171 ASSERT_EQUAL(astring::empty_string(), nullo, "backward blank a_sprintf isn't empty.");
172}
173
174void test_string::run_test_02()
175{
176 FUNCDEF("run_test_02");
177 // assorted tests involving strings as pointers.
178 astring *fred1 = new astring("flipper ate");
179 astring *fred2 = new astring(" my sandwich.");
180 astring *fred3 = new astring;
181 *fred3 = *fred1;
182 *fred3 += *fred2;
183
184 // testing adding a null to a string.
185 *fred2 += (char *)NULL_POINTER;
186 *fred3 += (char *)NULL_POINTER;
187
188#ifdef DEBUG_STRING_TEST
189 LOG(astring("[ ") + *fred1 + " & " + *fred2 + "] -> " + *fred3);
190#endif
191
192 ASSERT_EQUAL(*fred1, astring("flipper ate"), "flipper A failure in comparison");
193 ASSERT_EQUAL(*fred2, astring(" my sandwich."), "sandwich A failure in comparison");
194 ASSERT_EQUAL(*fred3, astring("flipper ate my sandwich."), "full f-s A failure in comparison");
195 delete fred1;
196 delete fred2;
197 delete fred3;
198}
199
200void test_string::run_test_03()
201{
202 FUNCDEF("run_test_03");
203 // tests some things about zap.
204 astring fleermipe("hello my frobious.");
205 fleermipe.zap(0, fleermipe.length() - 1);
206 ASSERT_EQUAL(fleermipe.length(), 0, "length not 0 after deleting entire astring");
207}
208
209void test_string::run_test_04()
210{
211 FUNCDEF("run_test_04");
212 astring test_string("this test string will be chopped up.");
213#ifdef DEBUG_STRING_TEST
214 LOG(astring("original is: ") + test_string);
215#endif
216 astring fred(test_string.s());
217 fred.zap(0, fred.find('w'));
218
219#ifdef DEBUG_STRING_TEST
220 LOG(astring("now, the one chopped through 'w' is: ") + fred);
221#endif
222
223 ASSERT_EQUAL(fred, astring("ill be chopped up."), "first zap failed");
224
225 astring blorg(test_string);
226 blorg.zap(blorg.find('p'), blorg.length() - 1);
227#ifdef DEBUG_STRING_TEST
228 LOG(astring("now the one chopped from p to the end: ") + blorg);
229#endif
230
231 ASSERT_EQUAL(blorg, astring("this test string will be cho"), "second zap failed");
232
233 astring fleen;
234 fleen += test_string;
235 fleen.zap(7, 14);
236#ifdef DEBUG_STRING_TEST
237 LOG(astring("now the one with 7 through 14 missing: ") + fleen);
238#endif
239
240 ASSERT_EQUAL(fleen, astring("this teg will be chopped up."), "third zap failed");
241
242#ifdef DEBUG_STRING_TEST
243 LOG(astring("original astring is now: ") + test_string);
244#endif
245 ASSERT_EQUAL(test_string, astring("this test string will be chopped up."),
246 "original astring was changed");
247}
248
249void test_string::run_test_05()
250{
251 FUNCDEF("run_test_05");
252#ifdef DEBUG_STRING_TEST
253 LOG("about to test weird things:");
254#endif
255 astring frieda("glorp");
256 astring jorb(frieda);
257 astring *kleeg = new astring(jorb.s());
258 astring plok = frieda;
259 test(frieda != jorb);
260 test(jorb != *kleeg);
261 test(*kleeg != plok);
262 test(plok != frieda);
263 astring glorp("glorp");
264 test(frieda != glorp);
265
266 WHACK(kleeg);
267
268#ifdef DEBUG_STRING_TEST
269 LOG("strings matched up okay.");
270#endif
271
272 // test new features sprintf is relying upon.
273 astring bubba("gumpternations");
274 bubba += "_02193";
275#ifdef DEBUG_STRING_TEST
276 LOG(astring("bubba = ") + bubba);
277#endif
278 ASSERT_EQUAL(bubba, astring("gumpternations_02193"), "+= on char pointer failed.");
279
280 astring bubelah("laksos");
281 bubelah += '3';
282 bubelah += '8';
283 bubelah += '2';
284#ifdef DEBUG_STRING_TEST
285 LOG(astring("bubelah = ") + bubelah);
286#endif
287 ASSERT_EQUAL(bubelah, astring("laksos382"), "+= on char failed.");
288
289 astring simple_spr0(astring::SPRINTF, "%% yoga splorch %%");
290#ifdef DEBUG_STRING_TEST
291 LOG(astring("simple sprintf 0 = ") + simple_spr0);
292#endif
293 ASSERT_EQUAL(simple_spr0, astring("% yoga splorch %"), "simple sprintf 0 is wrong");
294 astring simple_spr1(astring::SPRINTF, "%d", 23);
295#ifdef DEBUG_STRING_TEST
296 LOG(astring("simple sprintf 1 = ") + simple_spr1);
297#endif
298 ASSERT_EQUAL(simple_spr1, astring("23"), "simple sprintf 1 is wrong");
299 astring simple_spr2(astring::SPRINTF, "%s", "yoyo");
300#ifdef DEBUG_STRING_TEST
301 LOG(astring("simple sprintf 2 = ") + simple_spr2);
302#endif
303 ASSERT_EQUAL(simple_spr2, astring("yoyo"), "simple sprintf 2 is wrong");
304
305 astring sprintest(astring::SPRINTF, "%s has got me up the %s some %d "
306 "times, in %p with %d and %lu.", "marge", "ladder", 32, &kleeg,
307 812377487L, 213123123L);
308 astring sprintest2;
309 sprintest2.reset(astring::SPRINTF, "%s has got me up the %s some %d "
310 "times, in %p with %d and %lu.", "marge", "ladder", 32, &kleeg,
311 812377487L, 213123123L);
312 astring addr(astring::SPRINTF, "%p", &kleeg);
313#ifdef DEBUG_STRING_TEST
314 LOG("here is your astring sir...");
315 LOG(sprintest);
316 LOG("and addr we will see is...");
317 LOG(addr);
318#endif
319 if (sprintest != astring(astring::SPRINTF, "marge has got me up the "
320 "ladder some 32 times, in %s with 812377487 and 213123123.", addr.s()))
321 "constructed astring is wrong";
322 if (sprintest2 != astring(astring::SPRINTF, "marge has got me up the "
323 "ladder some 32 times, in %s with 812377487 and 213123123.", addr.s()))
324 "reset astring is wrong";
325}
326
327void test_string::run_test_06()
328{
329 FUNCDEF("run_test_06");
330 astring bungee;
331 bungee += "this astring";
332 bungee += " has been constructed gradua";
333 bungee += 'l';
334 bungee += 'l';
335 bungee += 'y';
336 astring blorpun(astring::SPRINTF, " out of severa%c", 'l');
337 bungee += blorpun;
338 bungee += " different bits,\nincluding";
339 astring freeple(astring::SPRINTF, "%s constructed %s blarg from %f ", " this", "silly", 3.14159265358);
340 bungee += freeple;
341 bungee += "radians awa";
342 bungee += 'y';
343 bungee += '.';
344 bungee += "\nhow does it look?\n";
345#ifdef DEBUG_STRING_TEST
346 LOG(bungee);
347#endif
348
349//MessageBox(0, bungee.s(), "yo, got this", MB_ICONINFORMATION | MB_OK);
350 ASSERT_EQUAL(bungee, astring("this astring has been constructed gradually out of several different bits,\nincluding this constructed silly blarg from 3.141593 radians away.\nhow does it look?\n"), "constructed astring is wrong");
351}
352
353void test_string::run_test_07()
354{
355 FUNCDEF("run_test_07");
356 astring a("axes");
357 astring b("bakesales");
358 astring x("xylophone");
359
360 test(a >= x);
361 test(a == b);
362 test(a > b);
363 test(b >= x);
364 test(x <= a);
365 test(x != x);
366 test(a != a);
367#ifdef DEBUG_STRING_TEST
368 LOG("comparisons worked");
369#endif
370}
371
372void test_string::run_test_08()
373{
374 FUNCDEF("run_test_08");
375#ifdef DEBUG_STRING_TEST
376 LOG("now testing + operator");
377#endif
378 astring a("fred");
379 astring b(" is");
380 astring c(" his");
381 astring d(" name.");
382 astring e;
383 e = a + b + c + d;
384#ifdef DEBUG_STRING_TEST
385 LOG(astring("result is: ") + e);
386#endif
387 astring f;
388 f = d + c + b + a;
389#ifdef DEBUG_STRING_TEST
390 LOG(astring("reverse is: ") + f);
391#endif
392 astring g;
393 g = a + c + d + b;
394#ifdef DEBUG_STRING_TEST
395 LOG(astring("tibetan style is: ") + g);
396#endif
397 ASSERT_EQUAL(e, astring("fred is his name."), "astring looks wrong");
398 ASSERT_EQUAL(f, astring(" name. his isfred"), "astring looks wrong");
399 ASSERT_EQUAL(g, astring("fred his name. is"), "astring looks wrong");
400}
401
402void test_string::run_test_09()
403{
404 FUNCDEF("run_test_09");
405 astring bleer(astring::SPRINTF, "urghla burgla #%d\n", 23);
406 char holder[50];
407 for (int i = 0; i < bleer.length(); i++) {
408 bleer.stuff(holder, i);
409#ifdef DEBUG_STRING_TEST
410 LOG(astring(astring::SPRINTF, "%d", i) + " has: " + holder);
411#endif
412 astring my_copy(bleer);
413 my_copy.zap(i, bleer.length() - 1);
414 ASSERT_EQUAL(my_copy, astring(holder), "should see no inaccurate stuff() call");
415 }
416}
417
418void test_string::run_test_10()
419{
420 FUNCDEF("run_test_10");
421#ifdef DEBUG_STRING_TEST
422 LOG("The tenth ones:");
423#endif
424 astring george("this one will be mangled.");
425 ASSERT_EQUAL(george.length(), int(strlen(george.s())), "length is incorrect (q).");
426 astring tmp1(george.substring(1, 7)); // constructor.
427 astring tmp2 = george.substring(10, george.length() - 1); // constructor.
428#ifdef DEBUG_STRING_TEST
429 LOG(tmp1 + "... " + tmp2);
430#endif
431 ASSERT_INEQUAL(tmp1, tmp2, "bizarre equality occurred!");
432 ASSERT_FALSE( (tmp1 > tmp2) || (tmp2 < tmp1), "bizarre comparison error.");
433 ASSERT_EQUAL(george.length(), int(strlen(george.s())), "length is incorrect (z).");
434#ifdef DEBUG_STRING_TEST
435 LOG(george.substring(1, 7));
436 LOG("... ");
437 LOG(george.substring(10, george.length() - 1));
438#endif
439 ASSERT_EQUAL(george.length(), int(strlen(george.s())), "length is incorrect (a).");
440 george.insert(14, "terribly ");
441 ASSERT_EQUAL(george.length(), int(strlen(george.s())), "length is incorrect (b).");
442#ifdef DEBUG_STRING_TEST
443 LOG(george);
444#endif
445 astring chunky;
446 astring mssr_boef_la_tet("eeyoy eye eye capn");
447 mssr_boef_la_tet.substring(chunky, 2, 7);
448 ASSERT_EQUAL(chunky, astring("yoy ey"), "contents wrong after substring");
449
450 astring fred(george);
451 ASSERT_TRUE(george.compare(fred, 0, 0, george.length() - 1, true), "did not work");
452 ASSERT_TRUE(george.compare(fred, 8, 8, george.length() - 1 - 8, true), "partial did not work");
453
454 astring taco1("iLikeTacosNSuch");
455 astring taco2("iLikeTaCosNSuch");
456 ASSERT_TRUE(taco1.compare(taco2, 0, 0, taco1.length() - 1, false),
457 "tacos case-insensitive compare A did not work");
458 ASSERT_FALSE(taco1.compare(taco2, 0, 0, taco1.length() - 1, true),
459 "tacos case-sensitive compare B did not work");
460
461 ASSERT_EQUAL(george.length(), int(strlen(george.s())), "length is incorrect (c).");
462 george.zap(14, 22);
463#ifdef DEBUG_STRING_TEST
464 LOG(george);
465#endif
466 astring fred_part;
467 fred_part = fred.substring(0, 13);
468 ASSERT_EQUAL(fred_part.length(), int(strlen(fred_part.s())), "length incorrect (d).");
469 ASSERT_TRUE(george.compare(fred_part, 0, 0, 13, true), "did not work");
470 fred_part = fred.substring(23, fred.length() - 1);
471 ASSERT_EQUAL(fred_part.length(), int(strlen(fred_part.s())), "length incorrect (e).");
472 ASSERT_TRUE(george.compare(fred_part, 14, 0, fred_part.length() - 1, true), "did not work");
473#ifdef DEBUG_STRING_TEST
474 LOG("compares okay");
475#endif
476}
477
478void test_string::run_test_11()
479{
480 FUNCDEF("run_test_11");
481 astring empty;
482 ASSERT_FALSE(empty.length(), "empty string judged not");
483 ASSERT_TRUE(!empty, "not on empty string doesn't work");
484 astring non_empty("grungee");
485 ASSERT_TRUE(non_empty.length(), "non-empty string judged empty");
486 ASSERT_FALSE(!non_empty, "not on non-empty string doesn't work");
487}
488
489void test_string::run_test_12()
490{
491 FUNCDEF("run_test_12");
492 astring elf0(astring::SPRINTF, "%%_%%_%%");
493 ASSERT_FALSE(strcmp(elf0.s(), "%_%_%"), "failed %% printing");
494
495 char fred[6] = { 'h', 'y', 'a', 'r', 'g', '\0' };
496 astring fred_copy(astring::UNTERMINATED, fred, 5);
497 ASSERT_EQUAL(fred_copy.length(), 5, "length of copy is wrong");
498 ASSERT_EQUAL(fred_copy, astring("hyarg"), "length of copy is wrong");
499
500 char hugh[6] = { 'o', 'y', 'o', 'b', 'o', 'y' };
501 astring hugh_copy(astring::UNTERMINATED, hugh, 3);
502 ASSERT_EQUAL(hugh_copy.length(), 3, "length of copy is wrong");
503 ASSERT_EQUAL(hugh_copy, astring("oyo"), "length of copy is wrong");
504
505 astring another_copy;
506 another_copy.reset(astring::UNTERMINATED, fred, strlen(fred));
507 ASSERT_EQUAL(another_copy.length(), 5, "length of reset copy is wrong");
508 ASSERT_EQUAL(another_copy, astring("hyarg"), "length of reset copy is wrong");
509}
510
511void test_string::run_test_13()
512{
513 FUNCDEF("run_test_13");
514 // check for possible memory leaks in these combined ops.... 13th.
515 const astring churg("borjh sjh oiweoklj");
516 astring pud = churg;
517 astring flug = "kase iqk aksjir kljasdo";
518 const char *nerf = "ausd qwoeui sof zjh qwei";
519 astring snorp = nerf;
520 pud = "snugbo";
521 snorp = flug;
522 astring pundit("murph");
523 pundit = nerf;
524}
525
526void test_string::run_test_14()
527{
528 FUNCDEF("run_test_14");
529 // test the new dynamic sprintf'ing for long strings... 14th.
530 const int longish_size = 5000;
531 char temp[longish_size];
532 for (int i = 0; i < longish_size; i++)
533 temp[i] = char(rando.inclusive(1, 255));
534 temp[longish_size - 1] = '\0';
535 a_sprintf longish("this is a really darned long string of stuff: %s,\nbut doesn't it look interesting?", temp);
536 // still with us?
537 longish.zap(longish.length() / 3, 2 * longish.length() / 3);
538 longish += longish;
539 ASSERT_EQUAL(longish.length(), int(strlen(longish.s())), "length is incorrect.");
540}
541
542void test_string::run_test_15()
543{
544 FUNCDEF("run_test_15");
545 // test the new dynamic sprintf'ing for long strings... 15th.
546 int try_1 = 32767;
547 astring testy(astring::SPRINTF, "%d", try_1);
548 ASSERT_INEQUAL(testy.convert(95), 95, "default value returned, so it failed.");
549 ASSERT_EQUAL(testy.convert(95), try_1, "correct value was not returned.");
550
551 long try_2 = 2938754L;
552 testy = astring(astring::SPRINTF, "%ld", try_2);
553 ASSERT_INEQUAL((double)testy.convert(98L), (double)98L, "default value returned, so it failed.");
554 ASSERT_EQUAL((double)testy.convert(98L), (double)try_2, "correct value was not returned.");
555
556 testy = astring(astring::SPRINTF, "%ld", try_2);
557 ASSERT_INEQUAL((double)testy.convert(98L), (double)98L, "default value returned, so it failed.");
558 ASSERT_EQUAL((double)testy.convert(98L), (double)try_2, "correct value was not returned.");
559
560 float try_3 = float(2938.754); // weird msvcpp error if don't cast.
561 testy = astring(astring::SPRINTF, "%f", try_3);
562 float found = testy.convert(float(98.6));
563 ASSERT_INEQUAL(found, 98.6, "default value returned, so it failed.");
564 ASSERT_EQUAL(found, try_3, "correct value was not returned.");
565
566 {
567 double try_4 = 25598437.712385;
568 testy = astring(astring::SPRINTF, "%f", try_4);
569 double found2 = testy.convert(double(98.6));
570 ASSERT_INEQUAL(found2, 98.6, "default value returned, so it failed.");
571 ASSERT_EQUAL(found2, try_4, "correct value was not returned.");
572 }
573
574 {
575 double try_4 = 25598437.712385e38;
576 testy = astring(astring::SPRINTF, "%f", try_4);
577 double found2 = testy.convert(double(98.6));
578 ASSERT_INEQUAL(found2, 98.6, "default value returned, so it failed.");
579 ASSERT_EQUAL(found2, try_4, "correct value was not returned.");
580 }
581}
582
583void test_string::run_test_16()
584{
585 FUNCDEF("run_test_16");
586 // the 16th test group tests boundary checking.
587 astring gorf("abc");
588 for (int i = -3; i < 25; i++) gorf[i] = 't';
589 ASSERT_EQUAL(gorf, astring("ttt"), "correct value was not returned (a).");
590 ASSERT_EQUAL(gorf.length(), 3, "length is incorrect (a).");
591 gorf.insert(3, astring("bru"));
592 ASSERT_EQUAL(gorf, astring("tttbru"), "correct value was not returned (b).");
593 ASSERT_EQUAL(gorf.length(), 6, "length is incorrect (b).");
594 gorf.insert(35, astring("snu"));
595 ASSERT_EQUAL(gorf, astring("tttbru"), "correct value was not returned (c).");
596 ASSERT_EQUAL(gorf.length(), 6, "length is incorrect (c).");
597 gorf.insert(-30, astring("eep"));
598 ASSERT_EQUAL(gorf, astring("tttbru"), "correct value was not returned (d).");
599 ASSERT_EQUAL(gorf.length(), 6, "length is incorrect (d).");
600}
601
602void test_string::run_test_17()
603{
604 FUNCDEF("run_test_17");
605 // 17th test checks construction of temporaries.
606/* this test set causes the obnoxious 16 bit codeguard error from hell, as
607 does use of temporary objects in ostream << operators. argh! */
608 astring("jubjo");
609 astring("obo");
610 astring("flrrpominort").substring(3, 6);
611}
612
613void test_string::run_test_18()
614{
615#ifdef DEBUG_STRING_TEST
616 FUNCDEF("run_test_18");
617#endif
618 // 18th test group checks windows related functions.
619#ifdef AFXDLL
620 AfxSetResourceHandle(GET_INSTANCE_HANDLE());
621 // required for mfc to see the proper instance handle.
622
623 // this tests the "constructor from resource".
624 astring libname = rc_string(IDS_BASIS_NAME);
625 ASSERT_EQUAL(libname, astring("Basis Library"),
626 astring("library name is a mismatch: comes out as \"") + libname + "\".");
627 #define IDS_SOME_BAD_UNKNOWN_STRING_HANDLE 30802
628 astring bogus_name = rc_string(IDS_SOME_BAD_UNKNOWN_STRING_HANDLE);
629 ASSERT_FALSE(bogus_name.length(), "bogus rc string had length");
630
631 // tests conversions from CString to astring and back.
632 astring george("yo yo yo");
633 CString hal = convert(george);
634 astring borgia = convert(hal);
635
636#ifdef DEBUG_STRING_TEST
637 LOG(astring("cstringy conversions: ") + george);
638 LOG((const char *)hal);
639 LOG(borgia);
640#endif
641
642 ASSERT_EQUAL(borgia, george, "got the wrong value");
643#endif
644}
645
646void test_string::run_test_19()
647{
648 FUNCDEF("run_test_19");
649 // 19th test group is devoted to anthony wenzel's % printing bug.
650 astring problematic_example(astring::SPRINTF, "this should have %d% more "
651 "stuffing than before!", 20);
652//MessageBox(0, astring("got a string of \"%s!\"", problematic_example.s()).s(), "yo!", MB_OK);
653 ASSERT_EQUAL(problematic_example, astring("this should have 20% more stuffing than before!"), "failure to print correct phrase");
654}
655
656void test_string::run_test_20()
657{
658#ifdef DEBUG_STRING_TEST
659 FUNCDEF("run_test_20");
660#endif
661 // 20th test group is devoted to another wenzelbug.
662
663 // Hey, I just found out (in an ugly way) that the following doesn't work:
664 char myText[] = "OK";
665 astring myString(astring::SPRINTF, "%04s", myText);
666#ifdef DEBUG_STRING_TEST
667 LOG(astring("first try gets: ") + myString);
668#endif
669
670 char myText8[] = "OK";
671 char my_text_4[90];
672 sprintf(my_text_4, "%4s", myText8);
673#ifdef DEBUG_STRING_TEST
674 LOG(astring("second try gets: ") + astring(my_text_4));
675#endif
676
677 // Looks like you don't handle the "%04s" arguments properly. I can make
678 // it work as follows:
679 char myText2[] = "OK";
680 char myText3[50];
681 sprintf(myText3, "%4s", myText2);
682 astring myString2(myText3);
683#ifdef DEBUG_STRING_TEST
684 LOG(astring("third try gets: ") + myString2);
685#endif
686}
687
688void test_string::run_test_21()
689{
690 FUNCDEF("run_test_21");
691 // 21st test group checks out the strip spaces and replace functions.
692 astring spacey(" dufunk ");
693 astring temp = spacey;
694 temp.strip_spaces(astring::FROM_FRONT);
695 ASSERT_EQUAL(temp, astring("dufunk "), "created wrong string");
696 temp = spacey;
697 temp.strip_spaces(astring::FROM_END);
698 ASSERT_EQUAL(temp, astring(" dufunk"), "created wrong string");
699 temp = spacey;
700 temp.strip_spaces(astring::FROM_BOTH_SIDES);
701 ASSERT_EQUAL(temp, astring("dufunk"), "created wrong string");
702
703 astring placemat("mary had a red hooded cobra she kept around her neck "
704 "and it hissed at the people as they walked by her tent.");
705 ASSERT_TRUE(placemat.replace("had", "bought"), "replace failed");
706 ASSERT_TRUE(!placemat.replace("hoded", "bought"), "replace didn't fail but should have");
707 ASSERT_TRUE(placemat.replace("she", "funkateria"), "replace failed");
708 ASSERT_TRUE(placemat.replace("hooded", "hood"), "replace failed");
709 ASSERT_TRUE(placemat.replace("cobra", "in the"), "replace failed");
710
711 int indy = placemat.find("kept");
712 ASSERT_FALSE(negative(indy), "couldn't find string");
713 placemat[indy - 1] = '.';
714 placemat.zap(indy, placemat.end());
715 ASSERT_EQUAL(placemat, astring("mary bought a red hood in the funkateria."), "got wrong result string");
716}
717
718void test_string::run_test_22()
719{
720 FUNCDEF("run_test_22");
721 // 22nd test: morgan's find bug.
722 astring B("buzz*buzz*");
723 {
724 int x = B.find('*'); // correctly finds the first *.
725 ASSERT_EQUAL(x, 4, "got wrong index for first");
726 x++;
727 x = B.find('*', x); // correctly finds the second *.
728 ASSERT_EQUAL(x, 9, "got wrong index for second");
729 x++; // now x == B.length().
730 x = B.find('*', x);
731 // error was: finds the second * again (and again and again and
732 // again...). At this point it should return OUT_OF_RANGE.
733 ASSERT_FALSE(x > 0, "got wrong outcome for third");
734 }
735 {
736 int x = B.find("z*"); // correctly finds the first z*.
737 ASSERT_EQUAL(x, 3, "got wrong index for fourth");
738 x++;
739 x = B.find("z*", x); // correctly finds the second *.
740 ASSERT_EQUAL(x, 8, "got wrong index for fifth");
741 x++; // now x == B.length().
742 x = B.find("z*", x);
743 // error was: finds the second * again (and again and again and
744 // again...). At this point it should return OUT_OF_RANGE.
745 ASSERT_FALSE(x > 0, "got wrong outcome for sixth");
746 }
747}
748
749void test_string::run_test_23()
750{
751 FUNCDEF("run_test_23");
752 // 23rd test: test the new strip function.
753 astring strip_string("!@#$%^&*()");
754
755 astring no_stripper("this shouldn't change");
756 no_stripper.strip(strip_string, astring::FROM_BOTH_SIDES);
757 ASSERT_EQUAL(no_stripper, astring("this shouldn't change"), "first test failed comparison");
758
759 astring strippee_orig("&$(*(@&@*()()!()@*(@(*fudge#((@(*@**#)(@#)(#");
760 astring strippee(strippee_orig);
761 strippee.strip(strip_string, astring::FROM_BOTH_SIDES);
762 ASSERT_EQUAL(strippee, astring("fudge"), "second test failed comparison");
763
764 strippee = strippee_orig;
765 strippee.strip(strip_string, astring::FROM_FRONT);
766 ASSERT_EQUAL(strippee, astring("fudge#((@(*@**#)(@#)(#"), "third test failed comparison");
767
768 strippee = strippee_orig;
769 strippee.strip(strip_string, astring::FROM_END);
770 ASSERT_EQUAL(strippee, astring("&$(*(@&@*()()!()@*(@(*fudge"), "fourth test failed comparison");
771}
772
773void test_string::run_test_24()
774{
775 FUNCDEF("run_test_24");
776#ifndef __GNU_WINDOWS__
777#ifdef __WIN32__
778 // 24th test group tests _bstr_t conversions.
779 _bstr_t beast("abcdefgh");
780#ifdef DEBUG_STRING_TEST
781 LOG(astring("the beast is ") + beast.operator char *() +
782 astring(astring::SPRINTF, " with length %d", beast.length()));
783#endif
784 astring convert = beast;
785#ifdef DEBUG_STRING_TEST
786 LOG(astring("the convert is ") + convert
787 + astring(astring::SPRINTF, " with length %d", convert.length()));
788#endif
789 ASSERT_EQUAL(convert, astring("abcdefgh"), "first test failed comparison");
790
791 astring jethro("i want a hog sandwich");
792 _bstr_t pork = string_convert::to_bstr_t(jethro);
793 ASSERT_FALSE(strcmp(pork.operator char *(), jethro.s()), "second test failed comparison");
794#endif
795#endif
796}
797
798void test_string::run_test_25()
799{
800 FUNCDEF("run_test_25");
801 // 25th test group tests simple comparisons.
802 astring fred = "asdoiuaoisud";
803 ASSERT_INEQUAL(fred, astring(), "first test failed comparison");
804 astring bub = fred;
805 ASSERT_EQUAL(fred, bub, "second test failed comparison");
806 fred = "";
807 ASSERT_EQUAL(fred, astring(), "third test failed comparison");
808 ASSERT_FALSE(fred.length(), "fourth test failed comparison");
809}
810
811void test_string::run_test_26()
812{
813 FUNCDEF("run_test_26");
814 // 26th test group does simple time_stamp::notarize operations. these are more for
815 // ensuring boundschecker gets to see some of this.
816 astring t2 = time_stamp::notarize(false);
817 astring t4 = time_stamp::notarize(true);
818}
819
820void test_string::run_test_27()
821{
822 FUNCDEF("run_test_27");
823 // 27th test group plays around with idate in an attempt to get
824 // boundschecker to complain.
827 timely::time_locus dt1 = now();
828 astring sd1 = d1.text_form();
829 astring st1 = t1.text_form();
830 astring sdt1 = dt1.text_form_long();
831}
832
833void test_string::run_test_28()
834{
835 FUNCDEF("run_test_28");
836 // 28th test group does sprintfs on shorts and such.
837 basis::un_int in1 = 27;
838 basis::un_short in2 = 39;
839 char in3 = 'Q';
840 astring testy(astring::SPRINTF, "%u:%hu:%c", in1, in2, in3);
841 ASSERT_EQUAL(testy, astring("27:39:Q"), "fourth test failed comparison");
842}
843
844void test_string::run_test_29()
845{
846 FUNCDEF("run_test_29");
847 // 29th test group tries out the packing support.
848 astring a("would an onion smell so sweet?");
849 byte_array p1;
850 a.pack(p1);
851 astring b;
852 ASSERT_TRUE(b.unpack(p1), "first unpack failed");
853 ASSERT_EQUAL(b, a, "first comparison failed");
854 a = "128 salamanders cannot be wrong.";
855 a.pack(p1);
856 ASSERT_TRUE(b.unpack(p1), "second unpack failed");
857 ASSERT_EQUAL(b, a, "second comparison failed");
858}
859
860#define static_class_name() "test_string"
861
862void standard_sprintf_test(const char *parm_string)
863{
864 FUNCDEF("standard_sprintf_test");
865 astring print_into(' ', 20000);
866 print_into[0] = '\0';
867//check these!!!:
868 int i1 = int(rando.inclusive(0, 23945));
869 long l1 = long(rando.inclusive(-2394, 2998238));
870 un_int u1 = basis::un_int(rando.inclusive(0, 124395));
871 un_short s1 = basis::un_short(rando.inclusive(0, 65535));
872 sprintf(print_into.s(), "%d %ld %u %hu %s", i1, l1, u1, s1, parm_string);
873 sprintf(print_into.s(), "%c %d %c %s %s %lu", char(rando.inclusive('a', 'z')),
874 int(rando.inclusive(0, 23945)), char(rando.inclusive('A', 'Z')),
875 parm_string, parm_string, basis::un_long(rando.inclusive(0, 2998238)));
876}
877
878#undef static_class_name
879
880void test_string::run_test_30()
881{
882 // 30th test group checks astring sprintf.
883 FUNCDEF("run_test_30");
884 astring parm_string = string_manipulation::make_random_name(40, 140);
885 astring print_into(' ', 20000);
886 print_into[0] = '\0';
887 int i1 = int(rando.inclusive(0, 23945));
888 long l1 = long(rando.inclusive(-2394, 2998238));
889 un_int u1 = basis::un_int(rando.inclusive(0, 124395));
890 un_short s1 = basis::un_short(rando.inclusive(0, 65535));
891 char test_same[20010];
892 sprintf(test_same, "%d %ld %u %hu %s", i1, l1, u1, s1, parm_string.s());
893 print_into.sprintf("%d %ld %u %hu %s", i1, l1, u1, s1, parm_string.s());
894 ASSERT_EQUAL(astring(test_same), print_into, "sprintf should get same results as standard");
895//do test for this one too.
896 print_into.sprintf("%c %d %c %s %s %lu", char(rando.inclusive('a', 'z')),
897 int(rando.inclusive(0, 23945)), char(rando.inclusive('A', 'Z')),
898 parm_string.observe(), parm_string.s(), basis::un_long(rando.inclusive(0, 2998238)));
899}
900
901void test_string::run_test_31()
902{
903 FUNCDEF("run_test_31");
904 // testing of character repeat constructor.
905 astring dashes('-', 20);
906 astring non_plusses('+', 0);
907 astring plusses('+', 1);
908 ASSERT_EQUAL(dashes.length(), 20, astring("dashes has wrong length!"));
909 ASSERT_EQUAL(dashes, astring("--------------------"), astring("dashes has wrong contents! '") + dashes + "' vs. '" + astring("--------------------'"));
910 ASSERT_FALSE(non_plusses.length(), astring("non_plusses has wrong length!"));
911 ASSERT_EQUAL(plusses.length(), 1, astring("plusses has wrong length!"));
912 ASSERT_EQUAL(plusses, astring("+"), astring("plusses has wrong contents!"));
913 ASSERT_EQUAL(plusses, astring('+', 1), astring("plusses second compare failed!"));
914}
915
916void test_string::run_test_32()
917{
918 FUNCDEF("run_test_32");
919 // tests creating a huge string and ripping it apart.
920
921 const int CHUNK_SIZE = 2 * MEGABYTE;
922 // the block factor for our string. we expect not to go above this during
923 // the testing.
924 const int MIN_ADDITION = 10000; const int MAX_ADDITION = 80000;
925 // these are the largest chunk we add to a string at a time.
926 const int BUILD_AND_BURN_ITERATIONS = 1;
927 // number of times to test building up and tearing down.
928
929 // the string we build up and tear down.
930 astring slab;
931
932//hmmm: maybe have a mixed phase where tearing and adding
933// happens frequently and interspersed.
934
935 for (int iters = 0; iters < BUILD_AND_BURN_ITERATIONS; iters++) {
936
937 int size = 0; // independent count of expected size.
938 // we don't want to bother allocating the big chunk more than once, so
939 // we'll add to the string until it's within range of going over.
940 while (slab.length() < CHUNK_SIZE - MAX_ADDITION - 20) {
941//make this into add_a_chunk
942 astring addition = string_manipulation::make_random_name(MIN_ADDITION,
943 MAX_ADDITION);
944 slab += addition;
945 size += addition.length();
946 ASSERT_EQUAL(size, slab.length(), astring("size is incorrect after add!"));
947 }
948
949 // now we eat it up.
950 while (slab.length()) {
951//make this into zap_a_chunk
952 int zap_start = rando.inclusive(0, slab.end());
953 int zap_end = rando.inclusive(0, slab.end());
954 flip_increasing(zap_start, zap_end);
955 int range_length = zap_end - zap_start + 1;
956 ASSERT_FALSE(negative(range_length), astring("flip_increasing failed!"));
957 slab.zap(zap_start, zap_end);
958 size -= range_length;
959 ASSERT_EQUAL(size, slab.length(), astring("size is incorrect after zap!"));
960 }
961 }
962}
963
964void test_string::run_test_33()
965{
966 FUNCDEF("run_test_33");
967 // 33rd test group exercises the replace functions.
968 {
969 astring to_modify("\\\\feeby\\path\\yo");
970 ASSERT_TRUE(to_modify.replace("\\", "/"), "failed to replace the string");
971 ASSERT_EQUAL(to_modify, astring("/\\feeby\\path\\yo"), "produced wrong resultant string");
972 while (to_modify.replace("\\", "/")) {}
973 ASSERT_EQUAL(to_modify, astring("//feeby/path/yo"), "produced wrong final string");
974 }
975 {
976 astring to_modify("\\superduper\\dynamo\\looper");
977 ASSERT_TRUE(to_modify.replace("\\", "/"), "failed to replace the string");
978 ASSERT_EQUAL(to_modify, astring("/superduper\\dynamo\\looper"), "produced wrong resultant string");
979 while (to_modify.replace("\\", "/")) {}
980 ASSERT_EQUAL(to_modify, astring("/superduper/dynamo/looper"), "produced wrong final string");
981 }
982 {
983 astring id = "/SRV=1/SRC=1";
984 astring id1 = id;
985 while (id1.replace("/", " ")) {}
986// LOG(astring("replacing / with ' ' in first test (was ") + id +
987// ") gives " + id1);
988 ASSERT_EQUAL(id1, astring(" SRV=1 SRC=1"), "produced wrong final string");
989
990 astring id2 = id;
991 while (id2.replace("=", ":")) {}
992// LOG(astring("replacing = with : in second test (was ") + id +
993// ") gives " + id2);
994 ASSERT_EQUAL(id2, astring("/SRV:1/SRC:1"), "produced wrong final string");
995 }
996}
997
998void test_string::run_test_34()
999{
1000 FUNCDEF("run_test_34");
1001
1002//not in use right now.
1003
1004}
1005
1006void test_string::run_test_35()
1007{
1008 FUNCDEF("run_test_35");
1009 // test the shrink method.
1010 astring termo('R', 2812);
1011 ASSERT_EQUAL(termo.length(), 2812, "length should be as requested");
1012 termo[1008] = '\0';
1013 termo.shrink();
1014 ASSERT_EQUAL(termo.get_implementation().internal_real_length(), 1010, a_sprintf("failure in shrunken size: " "wanted 1010 and got %d.", termo.get_implementation().internal_real_length()));
1015 astring termo2('R', 1008);
1016 ASSERT_EQUAL(termo, termo2, "wrong value produced");
1017}
1018
1019void test_string::run_test_36()
1020{
1021 FUNCDEF("run_test_36");
1022 // test the text form on a string array (which is mildly related to strings;
1023 // this could be moved to a common templates test someday).
1024 string_array torpid;
1025 torpid += "york";
1026 torpid += "burger";
1027 torpid += "petunia";
1028 torpid += "dumptruck";
1029 ASSERT_EQUAL(torpid.text_form(), astring("\"york\",\"burger\",\"petunia\",\"dumptruck\""), "wrong value computed");
1030 string_array sacral;
1031 sacral += "gumboat";
1032 ASSERT_EQUAL(sacral.text_form(), astring("\"gumboat\""), "wrong value computed");
1033
1034 string_array paknid;
1035 paknid += "gorboochy";
1036 paknid += "rangolent";
1037 byte_array packed;
1038 structures::pack_array(packed, paknid);
1039
1040 string_array upnort;
1041 ASSERT_TRUE(structures::unpack_array(packed, upnort), "failed to unpack");
1042 ASSERT_FALSE(packed.length(), "array still has bytes!");
1043
1044 string_array stongent;
1045 stongent += "pemulack";
1046 stongent += "bluzzent";
1047 stongent += "crupto";
1048 stongent += "floonack";
1049 stongent += "atoona";
1050 packed.reset();
1051 structures::pack_array(packed, stongent);
1052
1053 string_array belzorp;
1054 ASSERT_TRUE(structures::unpack_array(packed, belzorp), "failed to unpack");
1055 ASSERT_FALSE(packed.length(), "array still has bytes!");
1056}
1057
1058void test_string::run_test_37()
1059{
1060 FUNCDEF("run_test_37");
1061 // 37th test group used to try out the old packing support, but now is
1062 // just the same as test 29. it would be good to make this different.
1063 astring a("would an onion smell so sweet?");
1064 byte_array p1;
1065 a.pack(p1);
1066 astring b;
1067 ASSERT_TRUE(b.unpack(p1), "first unpack failed");
1068 ASSERT_EQUAL(b, a, "first comparison failed");
1069 a = "128 salamanders cannot be wrong.";
1070 a.pack(p1);
1071 ASSERT_TRUE(b.unpack(p1), "second unpack failed");
1072 ASSERT_EQUAL(b, a, "second comparison failed");
1073}
1074
1075void test_string::run_test_38()
1076{
1077 FUNCDEF("run_test_38");
1078 double to_print = 2.345;
1079 a_sprintf non_deadly("%.1f", to_print);
1081
1082 to_print = 1.797E+254;
1083 // this value breaks things.
1084
1085 char bucket[2000];
1086 bucket[0] = '\0';
1087 sprintf(bucket, "%.1f", to_print);
1089
1090 a_sprintf deadly("%.1f", to_print);
1092}
1093
1094void test_string::run_test_39()
1095{
1096 FUNCDEF("run_test_39");
1097 const char *find_set = "!?.;";
1098 astring test_1 = "how do i get to balthazar square? it stinks!";
1099 ASSERT_EQUAL(test_1.find_any(find_set), 32, "first find returned wrong result");
1100 ASSERT_EQUAL(test_1.find_any(find_set, 33), 44, "second find returned wrong result");
1101 ASSERT_EQUAL(test_1.find_any(find_set, 40, true), 32, "third find returned wrong result");
1102}
1103
1104void test_string::run_test_40()
1105{
1106 FUNCDEF("run_test_40");
1107 int test_num = 1;
1108 #define test_name() a_sprintf("test %d: ", test_num)
1109 {
1110 astring target = "xabab";
1111 astring from = "ab";
1112 astring to = "dc";
1113 ASSERT_TRUE(target.replace_all(from, to), test_name() + "didn't find from string");
1114 ASSERT_EQUAL(target, astring("xdcdc"), test_name() + "didn't replace properly");
1115 test_num++;
1116 }
1117 {
1118 astring target = "xabab";
1119 astring from = "ab";
1120 astring to = "ab";
1121 ASSERT_TRUE(target.replace_all(from, to), test_name() + "didn't find from string");
1122 ASSERT_EQUAL(target, astring("xabab"), test_name() + "didn't replace properly");
1123 test_num++;
1124 }
1125 {
1126 astring target = "xabab";
1127 astring from = "ab";
1128 astring to = "a";
1129 ASSERT_TRUE(target.replace_all(from, to), test_name() + "didn't find from string");
1130 ASSERT_EQUAL(target, astring("xaa"), test_name() + "didn't replace properly");
1131 test_num++;
1132 }
1133 {
1134 astring target = "ababx";
1135 astring from = "ab";
1136 astring to = "a";
1137 ASSERT_TRUE(target.replace_all(from, to), test_name() + "didn't find from string");
1138 ASSERT_EQUAL(target, astring("aax"), test_name() + "didn't replace properly");
1139 test_num++;
1140 }
1141 {
1142 astring target = "suzzle rumpetzzes gnargle rezztor";
1143 astring from = "zz";
1144 astring to = "zzz";
1145 ASSERT_TRUE(target.replace_all(from, to), test_name() + "didn't find from string");
1146 ASSERT_EQUAL(target, astring("suzzzle rumpetzzzes gnargle rezzztor"), test_name() + "didn't replace properly");
1147 test_num++;
1148 }
1149 {
1150 astring target = "qqqq";
1151 astring from = "q";
1152 astring to = "qqq";
1153 ASSERT_TRUE(target.replace_all(from, to), test_name() + "didn't find from string");
1154 ASSERT_EQUAL(target, astring("qqqqqqqqqqqq"), test_name() + "didn't replace properly");
1155 test_num++;
1156 }
1157 {
1158 astring target = "glorg snorp pendle funk";
1159 astring from = " ";
1160 astring to = "";
1161 ASSERT_TRUE(target.replace_all(from, to), test_name() + "didn't find from string");
1162 ASSERT_EQUAL(target, astring("glorgsnorppendlefunk"), test_name() + "didn't replace properly");
1163 test_num++;
1164 }
1165}
1166
1167void test_string::run_test_41()
1168{
1169 FUNCDEF("run_test_41");
1170 int test_num = 0;
1171 #define test_name() a_sprintf("test %d: ", test_num)
1172 {
1173 test_num++;
1174 astring target = "xabab";
1175 const char *finding1 = "ab";
1176 ASSERT_EQUAL(target.find_non_match(finding1, 0, false), 0, test_name() + "didn't find right location A");
1177 const char *finding2 = "xb";
1178 ASSERT_EQUAL(target.find_non_match(finding2, target.length() - 1, true), 3, test_name() + "didn't find right location B");
1179 const char *finding3 = "c";
1180 ASSERT_EQUAL(target.find_non_match(finding3, 0, false), 0, test_name() + "wrong answer for test C");
1181 ASSERT_EQUAL(target.find_non_match(finding3, target.length() - 1, true), target.length() - 1,
1182 test_name() + "wrong answer for test D");
1183 }
1184 {
1185 test_num++;
1186 astring target = "abcadefghoota";
1187 const char *finding1 = "bcdfghot";
1188 ASSERT_EQUAL(target.find_non_match(finding1, 0, false), 0, test_name() + "didn't find right location A");
1189 ASSERT_EQUAL(target.find_non_match(finding1, 1, false), 3, test_name() + "didn't find right location B");
1190 ASSERT_EQUAL(target.find_non_match(finding1, target.length() - 1, true), target.length() - 1, test_name() + "didn't find right location C");
1191 ASSERT_EQUAL(target.find_non_match(finding1, target.length() - 2, true), 5, test_name() + "didn't find right location D");
1192 ASSERT_EQUAL(target.find_non_match(finding1, 3, false), 3, test_name() + "didn't find right location E");
1193 ASSERT_EQUAL(target.find_non_match(finding1, 4, false), 5, test_name() + "didn't find right location F");
1194
1195 }
1196
1197}
1198
1199// exercise the middle, right and left methods.
1200void test_string::run_test_42()
1201{
1202 FUNCDEF("run_test_42");
1203
1204 astring hobnob("all the best robots are bending robots");
1205
1206 ASSERT_EQUAL(hobnob.middle(5, 7), astring("he best"), "failed to find middle of string");
1207 ASSERT_EQUAL(hobnob.right(10), astring("ing robots"), "failed to find right side of string");
1208 ASSERT_EQUAL(hobnob.left(6), astring("all th"), "failed to find right side of string");
1209}
1210
1212
1213int test_string::execute()
1214{
1215 FUNCDEF("execute");
1216
1217// ASSERT_EQUAL(0, 1, "fake assertion to test jenkins log parsing");
1218 ASSERT_EQUAL(1, 1, "non-fake assertion to test jenkins log parsing");
1219
1220 ASSERT_EQUAL(staticity_test, astring("yo!"), "wrong contents");
1221
1223 // when we're done testing.
1224
1225 int i = 0; // iteration counter.
1226 while (time_stamp() < end_time) {
1227 // we run the test until our time runs out.
1228 i++; // next iteration.
1229#ifdef DEBUG_STRING_TEST
1230 LOG(astring(astring::SPRINTF, "index %d", i));
1231#endif
1232
1233 // beginning of test sets.
1234 run_test_01();
1235 run_test_02();
1236 run_test_03();
1237 run_test_04();
1238 run_test_05();
1239 run_test_06();
1240 run_test_07();
1241 run_test_08();
1242 run_test_09();
1243 run_test_10();
1244 run_test_11();
1245 run_test_12();
1246 run_test_13();
1247 run_test_14();
1248 run_test_15();
1249 run_test_16();
1250 run_test_17();
1251 run_test_18();
1252 run_test_19();
1253 run_test_20();
1254 run_test_21();
1255 run_test_22();
1256 run_test_23();
1257 run_test_24();
1258 run_test_25();
1259 run_test_26();
1260 run_test_27();
1261 run_test_28();
1262 run_test_29();
1263//too slow run_test_30();
1264 run_test_31();
1265 run_test_32();
1266 run_test_33();
1267//retired run_test_34();
1268 run_test_35();
1269 run_test_36();
1270 run_test_37();
1271 run_test_38();
1272 run_test_39();
1273 run_test_40();
1274 run_test_41();
1275 run_test_42();
1276 }
1277
1278 return final_report();
1279}
1280
1281HOOPLE_MAIN(test_string, )
1282
The application_shell is a base object for console programs.
virtual int execute()=0
< retrieves the command line from the /proc hierarchy on linux.
a_sprintf is a specialization of astring that provides printf style support.
Definition astring.h:440
void reset(int number=0, const contents *initial_contents=NULL_POINTER)
Resizes this array and sets the contents from an array of contents.
Definition array.h:349
int length() const
Returns the current reported length of the allocated C array.
Definition array.h:115
Provides a dynamically resizable ASCII character string.
Definition astring.h:35
bool replace(const astring &tag, const astring &replacement)
replaces the first occurrence of "tag" text with the "replacement".
Definition astring.cpp:908
const char * s() const
synonym for observe. the 's' stands for "string", if that helps.
Definition astring.h:113
virtual void zap(int start, int end)
Deletes the characters between "start" and "end" inclusively.
Definition astring.cpp:524
bool substring(astring &target, int start, int end) const
a version that stores the substring in an existing "target" string.
Definition astring.cpp:868
static const astring & empty_string()
useful wherever empty strings are needed, e.g., function defaults.
Definition astring.cpp:128
void reset()
clears out the contents string.
Definition astring.h:202
int find_non_match(const char *to_find, int position=0, bool reverse=false) const
searches for any character that is not in "to_find" and returns index.
Definition astring.cpp:586
int end() const
returns the index of the last (non-null) character in the string.
Definition astring.h:86
int find_any(const char *to_find, int position=0, bool reverse=false) const
searches for any of the characters in "to_find".
Definition astring.cpp:580
bool replace_all(char to_replace, char new_char)
changes all occurrences of "to_replace" with "new_char".
Definition astring.cpp:932
int length() const
Returns the current length of the string.
Definition astring.cpp:132
bool unpack(byte_array &source)
retrieves a string (packed with pack()) from "source" into this string.
Definition astring.cpp:967
virtual const char * observe() const
observes the underlying pointer to the zero-terminated string.
Definition astring.cpp:140
A very common template for a dynamic array of bytes.
Definition byte_array.h:36
a platform-independent way to acquire random numbers in a specific range.
Definition chaos.h:51
int inclusive(int low, int high) const
< Returns a pseudo-random number r, such that "low" <= r <= "high".
Definition chaos.h:88
An array of strings with some additional helpful methods.
basis::astring text_form() const
A synonym for the text_format() method.
static basis::astring make_random_name(int min=1, int max=64)
creates a random name, where the letters are between 'a' and 'z'.
A specific point in time as represented by a 24 hour clock.
Definition earth_time.h:85
basis::astring text_form(int how=MERIDIAN) const
Prints the clock_time according to "how".
An object that represents a particular day in a year.
Definition earth_time.h:141
basis::astring text_form(int how=SHORT_MONTH) const
Prints the day according to "how".
An object that represents a particular point in time.
Definition earth_time.h:192
basis::astring text_form_long(int t=clock_time::MERIDIAN, int d=day_in_year::SHORT_MONTH, int y=LONG_YEAR) const
Represents a point in time relative to the operating system startup time.
Definition time_stamp.h:38
static basis::astring notarize(bool add_space=true)
a useful method for getting a textual version of the time "right now".
#define NULL_POINTER
The value representing a pointer to nothing.
Definition definitions.h:32
#define DEFINE_CLASS_NAME(objname)
Defines the name of a class by providing a couple standard methods.
Definition enhance_cpp.h:42
#define FUNCDEF(func_in)
FUNCDEF sets the name of a function (and plugs it into the callstack).
Definition enhance_cpp.h:54
Provides macros that implement the 'main' program of an application.
#define HOOPLE_MAIN(obj_name, obj_args)
options that should work for most unix and linux apps.
Definition hoople_main.h:61
Implements an application lock to ensure only one is running at once.
The guards collection helps in testing preconditions and reporting errors.
Definition array.h:30
void WHACK(contents *&ptr)
deletion with clearing of the pointer.
Definition functions.h:121
const int MEGABYTE
Number of bytes in a megabyte.
unsigned long un_long
Abbreviated name for unsigned long integers.
Definition definitions.h:66
unsigned int un_int
Abbreviated name for unsigned integers.
Definition definitions.h:62
void flip_increasing(type &a, type &b)
Makes sure that two values are in increasing order (a < b).
Definition functions.h:95
unsigned short un_short
Abbreviated name for unsigned short integers.
Definition definitions.h:64
bool negative(const type &a)
negative returns true if "a" is less than zero.
Definition functions.h:43
const int MINUTE_ms
Number of milliseconds in a minute.
A logger that sends to the console screen using the standard output device.
An extension to floating point primitives providing approximate equality.
Definition averager.h:21
A dynamic container class that holds any kind of object via pointers.
Definition amorph.h:55
bool unpack_array(basis::byte_array &packed_form, basis::array< contents > &to_unpack)
provides a way to unpack any array that stores packable objects.
void pack_array(basis::byte_array &packed_form, const basis::array< contents > &to_pack)
provides a way to pack any array that stores packable objects.
#include <time.h>
time_locus now()
returns our current locus in the time continuum.
clock_time time_now()
what time is it?
time_locus convert(time_number seconds, time_number useconds, const tm &cal_values)
day_in_year date_now()
what day on the calendar is it?
Useful support functions for unit testing, especially within hoople.
Definition unit_base.cpp:35
gerkin borgia
const float TEST_RUNTIME_DEFAULT
#define LOG(s)
#define test(expr)
#define test_name()
void standard_sprintf_test(const char *parm_string)
chaos rando
#define ASSERT_EQUAL(a, b, test_name)
Definition unit_base.h:38
#define ASSERT_TRUE(a, test_name)
Definition unit_base.h:46
#define ASSERT_FALSE(a, test_name)
Definition unit_base.h:50
#define ASSERT_INEQUAL(a, b, test_name)
Definition unit_base.h:42
#define GET_INSTANCE_HANDLE()
a handy macro that frees one from knowing the name of the handle.