3 //#define TEST_STD_STRING
7 #include "nsFragmentedString.h"
8 #include "nsReadableUtils.h"
9 #include "nsSlidingString.h"
11 #ifdef TEST_STD_STRING
12 #include "nsStdStringWrapper.h"
14 typedef nsString nsStdString
;
15 typedef nsCString nsStdCString
;
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");
38 static PRUnichar constant_unicode
[] = { 'H', 'e', 'l', 'l', 'o', PRUnichar() };
39 return basic_nsLiteralString
<PRUnichar
>(constant_unicode
);
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()); }
69 CallCMid( nsACString
& aResult
, const nsACString
& aSource
, PRUint32 aStartPos
, PRUint32 aLengthToCopy
)
71 aSource
.Mid(aResult
, aStartPos
, aLengthToCopy
);
76 template <class CharT
>
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
;
92 ConstIterator iter1
= aString
.BeginReading();
93 ConstIterator iter2
= aString
.BeginReading();
96 ConstIterator iter3
= aString
.EndReading();
101 cout
<< "FAILED in |test_multifragment_iterators|" << endl
;
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
);
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
;
133 if ( aReadable
.First() != CharT('H') )
135 cout
<< "FAILED |test_readable_hello|: |First()| --> '" << aReadable
.First() << "'" << endl
;
139 if ( aReadable
.Last() != CharT('o') )
141 cout
<< "FAILED |test_readable_hello|: |Last()| --> '" << aReadable
.Last() << "'" << endl
;
145 if ( aReadable
[3] != CharT('l') )
147 cout
<< "FAILED |test_readable_hello|: |operator[]| --> '" << aReadable
[3] << "'" << endl
;
151 if ( aReadable
.CountChar( CharT('l') ) != 2 )
153 cout
<< "FAILED |test_readable_hello|: |CountChar('l')| --> " << aReadable
.CountChar(CharT('l')) << endl
;
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
;
166 if ( *iter
!= CharT('e') )
168 cout
<< "FAILED |test_readable_hello|: iterator couldn't be incremented, or else couldn't be dereferenced. --> '" << *iter
<< "'" << endl
;
172 iter
= aReadable
.EndReading();
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
;
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
;
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
;
194 if ( iter1
!= iter2
)
196 cout
<< "FAILED |test_readable_hello|: iterator comparison with !=." << endl
;
200 if ( !(iter1
== iter2
) )
202 cout
<< "FAILED |test_readable_hello|: iterator comparison with ==." << endl
;
206 typedef CharT
* CharT_ptr
;
207 if ( aReadable
!= literal_hello(CharT_ptr()) )
209 cout
<< "FAILED |test_readable_hello|: comparison with \"Hello\"" << endl
;
213 tests_failed
+= test_multifragment_iterators(aReadable
);
214 // tests_failed += test_deprecated_GetBufferGetUnicode(aReadable);
216 test_Vidur_functions(aReadable
);
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
;
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
;
248 if ( oldValue
!= Substring(aWritable
, 0, oldLength
) )
250 cout
<< "FAILED growing a string in |test_SetLength|, contents damaged after growing." << endl
;
254 aWritable
.SetLength(oldLength
);
255 if ( aWritable
.Length() != oldLength
)
257 cout
<< "FAILED shrinking a string in |test_SetLength|." << endl
;
261 if ( oldValue
!= Substring(aWritable
, 0, oldLength
) )
263 cout
<< "FAILED growing a string in |test_SetLength|, contents damaged after shrinking." << endl
;
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
;
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
;
296 aWritable
= oldValue
;
302 template <class CharT
>
304 test_cut( basic_nsAString
<CharT
>& aWritable
)
306 int tests_failed
= 0;
308 aWritable
.Cut(0, aWritable
.Length()+5);
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
;
327 aWritable
= oldValue
;
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
;
345 aWritable
= oldValue
;
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
;
363 aWritable
= oldValue
;
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
;
381 aWritable
= oldValue
;
387 template <class CharT
>
389 test_writable( basic_nsAString
<CharT
>& aWritable
)
391 int tests_failed
= 0;
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
;
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
);
421 typedef void* void_ptr
;
426 int tests_failed
= 0;
427 cout
<< "String unit tests. Compiled " __DATE__
" " __TIME__
<< endl
;
431 nsFragmentedCString fs0
;
433 tests_failed
+= test_readable_hello(fs0
);
434 tests_failed
+= test_writable(fs0
);
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);
456 ss0
.DiscardPrefix(ri0
);
458 tests_failed
+= test_readable_hello(ss0
);
459 tests_failed
+= test_readable_hello(ss1
);
461 nsReadingIterator
<PRUnichar
> 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
);
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
;
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");
555 cout
<< "string comparison using != failed" << endl
;
559 if ( !(str3
> str2
) )
561 cout
<< "string comparison using > failed" << endl
;
565 if ( !(str2
< str3
) )
567 cout
<< "string comparison using < failed" << endl
;
571 if ( str1
!= "Hello" )
573 cout
<< "string comparison using == failed" << endl
;
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
;
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
;
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
);
624 cout
<< "End of string unit tests." << endl
;
626 cout
<< "OK, all tests passed." << endl
;
628 cout
<< "FAILED one or more tests." << endl
;