On x86 compilers without fastcall, simulate it when invoking traces and un-simulate...
[wine-gecko.git] / xpcom / tests / StringFactoringTests / test_main.cpp
blob5b7cbb06b0eae275c4a5a8955305a505074c1d8b
1 #include <iostream.h>
3 //#define TEST_STD_STRING
6 #include "nsString.h"
7 #include "nsFragmentedString.h"
8 #include "nsReadableUtils.h"
9 #include "nsSlidingString.h"
11 #ifdef TEST_STD_STRING
12 #include "nsStdStringWrapper.h"
13 #else
14 typedef nsString nsStdString;
15 typedef nsCString nsStdCString;
16 #endif
18 template <class CharT>
19 basic_nsLiteralString<CharT>
20 literal_hello( CharT* )
24 NS_SPECIALIZE_TEMPLATE
25 basic_nsLiteralString<char>
26 literal_hello( char* )
28 return basic_nsLiteralString<char>("Hello");
31 NS_SPECIALIZE_TEMPLATE
32 basic_nsLiteralString<PRUnichar>
33 literal_hello( PRUnichar* )
35 #ifdef HAVE_CPP_2BYTE_WCHAR_T
36 return basic_nsLiteralString<PRUnichar>(L"Hello");
37 #else
38 static PRUnichar constant_unicode[] = { 'H', 'e', 'l', 'l', 'o', PRUnichar() };
39 return basic_nsLiteralString<PRUnichar>(constant_unicode);
40 #endif
43 template <class T>
44 struct string_class_traits
48 NS_SPECIALIZE_TEMPLATE
49 struct string_class_traits<PRUnichar>
51 typedef PRUnichar* pointer;
52 typedef nsString implementation_t;
54 static basic_nsLiteralString<PRUnichar> literal_hello() { return ::literal_hello(pointer()); }
57 NS_SPECIALIZE_TEMPLATE
58 struct string_class_traits<char>
60 typedef char* pointer;
61 typedef nsCString implementation_t;
63 static basic_nsLiteralString<char> literal_hello() { return ::literal_hello(pointer()); }
67 static
68 void
69 CallCMid( nsACString& aResult, const nsACString& aSource, PRUint32 aStartPos, PRUint32 aLengthToCopy )
71 aSource.Mid(aResult, aStartPos, aLengthToCopy);
76 template <class CharT>
77 int
78 test_multifragment_iterators( const basic_nsAString<CharT>& aString )
80 ...this tests a problem that was present in |nsPromiseConcatenation| where,
81 because it originally stored some iteration state in the object itself, rather than
82 in the fragment, the iterators could get confused if used out of sequence.
84 This test should be run on any multi-fragment implementation to verify that it
85 does not have the same bug. Make sure the first fragment is only one character long.
88 typedef typename basic_nsAString<CharT>::const_iterator ConstIterator;
90 int tests_failed = 0;
92 ConstIterator iter1 = aString.BeginReading();
93 ConstIterator iter2 = aString.BeginReading();
94 ++iter2; ++iter2;
96 ConstIterator iter3 = aString.EndReading();
97 --iter3;
98 ++iter1; ++iter1;
99 if ( iter1 != iter2 )
101 cout << "FAILED in |test_multifragment_iterators|" << endl;
102 ++tests_failed;
105 return tests_failed;
108 template <class CharT>
110 test_Vidur_functions( const basic_nsAString<CharT>& aString )
112 char* char_copy = ToNewCString(aString);
113 PRUnichar* PRUnichar_copy = ToNewUnicode(aString);
115 nsMemory::Free(PRUnichar_copy);
116 nsMemory::Free(char_copy);
118 return 0;
121 template <class CharT>
123 test_readable_hello( const basic_nsAString<CharT>& aReadable )
125 int tests_failed = 0;
127 if ( aReadable.Length() != 5 )
129 cout << "FAILED |test_readable_hello|: |Length()| --> " << aReadable.Length() << endl;
130 ++tests_failed;
133 if ( aReadable.First() != CharT('H') )
135 cout << "FAILED |test_readable_hello|: |First()| --> '" << aReadable.First() << "'" << endl;
136 ++tests_failed;
139 if ( aReadable.Last() != CharT('o') )
141 cout << "FAILED |test_readable_hello|: |Last()| --> '" << aReadable.Last() << "'" << endl;
142 ++tests_failed;
145 if ( aReadable[3] != CharT('l') )
147 cout << "FAILED |test_readable_hello|: |operator[]| --> '" << aReadable[3] << "'" << endl;
148 ++tests_failed;
151 if ( aReadable.CountChar( CharT('l') ) != 2 )
153 cout << "FAILED |test_readable_hello|: |CountChar('l')| --> " << aReadable.CountChar(CharT('l')) << endl;
154 ++tests_failed;
157 basic_nsAString<CharT>::const_iterator iter = aReadable.BeginReading();
158 if ( *iter != CharT('H') )
160 cout << "FAILED |test_readable_hello|: didn't start out pointing to the right thing, or else couldn't be dereferenced. --> '" << *iter << "'" << endl;
161 ++tests_failed;
164 ++iter;
166 if ( *iter != CharT('e') )
168 cout << "FAILED |test_readable_hello|: iterator couldn't be incremented, or else couldn't be dereferenced. --> '" << *iter << "'" << endl;
169 ++tests_failed;
172 iter = aReadable.EndReading();
173 --iter;
174 if ( *iter != CharT('o') )
176 cout << "FAILED |test_readable_hello|: iterator couldn't be set to |EndReading()|, or else couldn't be decremented, or else couldn't be dereferenced. --> '" << *iter << "'" << endl;
177 ++tests_failed;
180 basic_nsAString<CharT>::const_iterator iter1 = aReadable.BeginReading().advance(3);
181 if ( *iter1 != CharT('l') )
183 cout << "FAILED |test_readable_hello|: iterator couldn't be set to |BeginReading()+=n|, or else couldn't be dereferenced. --> '" << *iter1 << "'" << endl;
184 ++tests_failed;
187 basic_nsAString<CharT>::const_iterator iter2 = aReadable.EndReading().advance(-2);
188 if ( *iter2 != CharT('l') )
190 cout << "FAILED |test_readable_hello|: iterator couldn't be set to |EndReading()-=n|, or else couldn't be dereferenced. --> '" << *iter2 << "'" << endl;
191 ++tests_failed;
194 if ( iter1 != iter2 )
196 cout << "FAILED |test_readable_hello|: iterator comparison with !=." << endl;
197 ++tests_failed;
200 if ( !(iter1 == iter2) )
202 cout << "FAILED |test_readable_hello|: iterator comparison with ==." << endl;
203 ++tests_failed;
206 typedef CharT* CharT_ptr;
207 if ( aReadable != literal_hello(CharT_ptr()) )
209 cout << "FAILED |test_readable_hello|: comparison with \"Hello\"" << endl;
210 ++tests_failed;
213 tests_failed += test_multifragment_iterators(aReadable);
214 // tests_failed += test_deprecated_GetBufferGetUnicode(aReadable);
216 test_Vidur_functions(aReadable);
218 return tests_failed;
222 template <class CharT>
224 test_SetLength( basic_nsAString<CharT>& aWritable )
226 int tests_failed = 0;
228 string_class_traits<CharT>::implementation_t oldValue(aWritable);
231 size_t oldLength = aWritable.Length();
233 if ( oldValue != Substring(aWritable, 0, oldLength) )
235 cout << "FAILED growing a string in |test_SetLength|, saving the value didn't work." << endl;
236 ++tests_failed;
239 size_t newLength = 2*(oldLength+1);
241 aWritable.SetLength(newLength);
242 if ( aWritable.Length() != newLength )
244 cout << "FAILED growing a string in |test_SetLength|, length is wrong." << endl;
245 ++tests_failed;
248 if ( oldValue != Substring(aWritable, 0, oldLength) )
250 cout << "FAILED growing a string in |test_SetLength|, contents damaged after growing." << endl;
251 ++tests_failed;
254 aWritable.SetLength(oldLength);
255 if ( aWritable.Length() != oldLength )
257 cout << "FAILED shrinking a string in |test_SetLength|." << endl;
258 ++tests_failed;
261 if ( oldValue != Substring(aWritable, 0, oldLength) )
263 cout << "FAILED growing a string in |test_SetLength|, contents damaged after shrinking." << endl;
264 ++tests_failed;
267 return tests_failed;
271 template <class CharT>
273 test_insert( basic_nsAString<CharT>& aWritable )
275 int tests_failed = 0;
277 string_class_traits<CharT>::implementation_t oldValue(aWritable);
279 if ( oldValue != aWritable )
281 cout << "FAILED saving the old string value in |test_insert|." << endl;
282 ++tests_failed;
285 string_class_traits<CharT>::implementation_t insertable( string_class_traits<CharT>::literal_hello() );
287 insertable.SetLength(1);
288 aWritable.Insert(insertable, 0);
290 if ( aWritable != (insertable + oldValue) )
292 cout << "FAILED in |test_insert|." << endl;
293 ++tests_failed;
296 aWritable = oldValue;
298 return tests_failed;
302 template <class CharT>
304 test_cut( basic_nsAString<CharT>& aWritable )
306 int tests_failed = 0;
308 aWritable.Cut(0, aWritable.Length()+5);
310 return tests_failed;
313 template <class CharT>
315 test_self_assign( basic_nsAString<CharT>& aWritable )
317 int tests_failed = 0;
318 string_class_traits<CharT>::implementation_t oldValue(aWritable);
320 aWritable = aWritable;
321 if ( aWritable != oldValue )
323 cout << "FAILED self assignment." << endl;
324 ++tests_failed;
327 aWritable = oldValue;
328 return tests_failed;
331 template <class CharT>
333 test_self_append( basic_nsAString<CharT>& aWritable )
335 int tests_failed = 0;
336 string_class_traits<CharT>::implementation_t oldValue(aWritable);
338 aWritable += aWritable;
339 if ( aWritable != oldValue + oldValue )
341 cout << "FAILED self append." << endl;
342 ++tests_failed;
345 aWritable = oldValue;
346 return tests_failed;
349 template <class CharT>
351 test_self_insert( basic_nsAString<CharT>& aWritable )
353 int tests_failed = 0;
354 string_class_traits<CharT>::implementation_t oldValue(aWritable);
356 aWritable.Insert(aWritable, 0);
357 if ( aWritable != oldValue + oldValue )
359 cout << "FAILED self insert." << endl;
360 ++tests_failed;
363 aWritable = oldValue;
364 return tests_failed;
367 template <class CharT>
369 test_self_replace( basic_nsAString<CharT>& aWritable )
371 int tests_failed = 0;
372 string_class_traits<CharT>::implementation_t oldValue(aWritable);
374 aWritable.Replace(0, 0, aWritable);
375 if ( aWritable != oldValue + oldValue )
377 cout << "FAILED self insert." << endl;
378 ++tests_failed;
381 aWritable = oldValue;
382 return tests_failed;
387 template <class CharT>
389 test_writable( basic_nsAString<CharT>& aWritable )
391 int tests_failed = 0;
392 // ...
396 typedef CharT* CharT_ptr;
397 aWritable = literal_hello(CharT_ptr());
399 if ( aWritable != literal_hello(CharT_ptr()) )
401 cout << "FAILED assignment and/or comparison in |test_writable|." << endl;
402 ++tests_failed;
405 tests_failed += test_readable_hello(aWritable);
408 tests_failed += test_SetLength(aWritable);
409 tests_failed += test_insert(aWritable);
410 tests_failed += test_cut(aWritable);
411 tests_failed += test_self_assign(aWritable);
412 tests_failed += test_self_append(aWritable);
413 tests_failed += test_self_insert(aWritable);
414 tests_failed += test_self_replace(aWritable);
416 return tests_failed;
421 typedef void* void_ptr;
424 main()
426 int tests_failed = 0;
427 cout << "String unit tests. Compiled " __DATE__ " " __TIME__ << endl;
429 #if 0
431 nsFragmentedCString fs0;
432 fs0.Append("Hello");
433 tests_failed += test_readable_hello(fs0);
434 tests_failed += test_writable(fs0);
436 #endif
439 NS_NAMED_LITERAL_STRING(literal, "Hello");
440 PRUnichar* buffer = ToNewUnicode(literal);
442 nsSlidingString ss0(buffer, buffer+5, buffer+6);
443 // ss0.AppendBuffer(buffer, buffer+5, buffer+6);
444 nsReadingIterator<PRUnichar> ri0;
445 ss0.BeginReading(ri0);
447 tests_failed += test_readable_hello(ss0);
449 nsSlidingSubstring ss1(ss0);
450 tests_failed += test_readable_hello(ss1);
452 buffer = ToNewUnicode(literal);
453 ss0.AppendBuffer(buffer, buffer+5, buffer+6);
455 ri0.advance(5);
456 ss0.DiscardPrefix(ri0);
458 tests_failed += test_readable_hello(ss0);
459 tests_failed += test_readable_hello(ss1);
461 nsReadingIterator<PRUnichar> ri1;
462 ss0.EndReading(ri1);
464 nsSlidingSubstring ss2(ss0, ri0, ri1);
465 tests_failed += test_readable_hello(ss2);
469 tests_failed += test_readable_hello(NS_LITERAL_STRING("Hello"));
471 nsLiteralCString s1("Hello");
472 tests_failed += test_readable_hello(s1);
477 nsString s3( NS_LITERAL_STRING("Hello") );
479 tests_failed += test_readable_hello(s3);
480 tests_failed += test_writable(s3);
482 nsCString s4("Hello");
483 tests_failed += test_readable_hello(s4);
484 tests_failed += test_writable(s4);
488 nsStdString s5( NS_LITERAL_STRING("Hello") );
490 tests_failed += test_readable_hello(s5);
491 tests_failed += test_writable(s5);
493 nsStdCString s6("Hello");
494 tests_failed += test_readable_hello(s6);
495 tests_failed += test_writable(s6);
499 nsLiteralString s7(NS_LITERAL_STRING("He"));
500 nsString s8(NS_LITERAL_STRING("l"));
501 nsStdString s9(NS_LITERAL_STRING("lo"));
503 tests_failed += test_readable_hello(s7+s8+s9);
505 nsString s13( s7 + s8 + s9 );
506 tests_failed += test_readable_hello(s13);
508 nsStdString s14( s7 + s8 + s9 );
509 tests_failed += test_readable_hello(s14);
511 nsCString s10("He");
512 nsLiteralCString s11("l");
513 nsStdCString s12("lo");
515 tests_failed += test_readable_hello(s10+s11+s12);
521 const char *foo = "this is a really long string";
522 nsCString origString;
523 nsCString string2;
524 nsCString string3;
526 origString = foo;
528 string2 = Substring(origString, 0, 5);
529 string3 = Substring(origString, 6, origString.Length() - 6);
533 nsLiteralCString s13("He");
534 nsCAutoString s14("l");
535 nsLiteralCString s15("lo");
537 s14.Assign(s13 + s14 + s15);
539 if ( int failures = test_readable_hello(s14) )
541 tests_failed += failures;
542 cout << "FAILED to keep a promise." << endl;
548 nsLiteralCString str1("Hello");
549 nsStdCString str2("Hello");
551 nsLiteralCString str3("Hello there");
553 if ( str1 != str2 )
555 cout << "string comparison using != failed" << endl;
556 ++tests_failed;
559 if ( !(str3 > str2) )
561 cout << "string comparison using > failed" << endl;
562 ++tests_failed;
565 if ( !(str2 < str3) )
567 cout << "string comparison using < failed" << endl;
568 ++tests_failed;
571 if ( str1 != "Hello" )
573 cout << "string comparison using == failed" << endl;
574 ++tests_failed;
578 #if 0
579 nsStdCString extracted_middle("XXXXXXXXXX");
580 CallCMid(extracted_middle, part1+part2a+part2b, 1, 3);
582 cout << "The result of mid was \"" << extracted_middle << "\"" << endl;
584 nsLiteralCString middle_answer("ell");
585 if ( middle_answer != extracted_middle )
587 cout << "mid FAILED on nsConcatString" << endl;
588 ++tests_failed;
594 // |nsStdStringWrapper|, i.e., |nsStdCString|
598 nsStdCString extracted_middle;
599 CallCMid(extracted_middle, part1+part2a+part2b, 1, 3);
601 cout << "The result of mid was \"" << extracted_middle << "\"" << endl;
603 nsLiteralCString middle_answer("ell");
604 if ( middle_answer != extracted_middle )
606 cout << "mid FAILED on nsStdCString" << endl;
607 ++tests_failed;
613 nsStdCString leftString;
614 source.Left(leftString, 9);
615 // cout << static_cast<const nsACString>(leftString) << endl;
619 tests_failed += test_multifragment_iterators(part1+part2a+part2b);
620 #endif
624 cout << "End of string unit tests." << endl;
625 if ( !tests_failed )
626 cout << "OK, all tests passed." << endl;
627 else
628 cout << "FAILED one or more tests." << endl;
630 return tests_failed;