diff --git a/xpcom/tests/StringFactoringTests/Makefile.in b/xpcom/tests/StringFactoringTests/Makefile.in new file mode 100644 index 00000000000..70a14fa93e1 --- /dev/null +++ b/xpcom/tests/StringFactoringTests/Makefile.in @@ -0,0 +1,56 @@ +# +# The contents of this file are subject to the Netscape Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/NPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All +# Rights Reserved. +# +# Contributor(s): +# + +DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +PROGRAM = profile_strings +#PROGRAM = test_main + +CPPSRCS = \ + $(topsrcdir)/xpcom/ds/nsString2.cpp \ + $(topsrcdir)/xpcom/ds/nsStr.cpp \ + $(topsrcdir)/xpcom/ds/nsString.cpp \ + $(topsrcdir)/xpcom/ds/nsCRT.cpp \ + $(topsrcdir)/xpcom/base/nsAllocator.cpp \ + $(topsrcdir)/xpcom/ds/nsDeque.cpp \ + profile_main.cpp \ + $(NULL) +# test_main.cpp \ + + +LIBS += \ + $(NSPR_LIBS) \ + $(NULL) + +include $(topsrcdir)/config/rules.mk + +DEFINES += -DNEW_STRING_APIS -DSTANDALONE_STRING_TESTS -UDEBUG -DNDEBUG +#DEFINES += -DSTANDALONE_STRING_TESTS -UDEBUG -DNDEBUG +INCLUDES += -I$(srcdir)/../public -I$(srcdir)/services + +install:: + $(INSTALL) $(srcdir)/test.properties $(DIST)/bin/res + diff --git a/xpcom/tests/StringFactoringTests/profile_main.cpp b/xpcom/tests/StringFactoringTests/profile_main.cpp index 59f48238235..02ee331787c 100644 --- a/xpcom/tests/StringFactoringTests/profile_main.cpp +++ b/xpcom/tests/StringFactoringTests/profile_main.cpp @@ -5,8 +5,11 @@ #include #include #include +#include +#ifdef XP_MAC #include "Profiler.h" +#endif #ifndef TEST_STD_STRING #include "nsString.h" @@ -15,8 +18,6 @@ typedef nsStdCString nsCString; #endif -#include - static const int kTestSucceeded = 0; static const int kTestFailed = 1; @@ -55,37 +56,31 @@ Find( const string& text, const string& pattern ) return text.find(pattern); } +#ifndef HAVE_LONG_LONG inline -UnsignedWide -operator-( const UnsignedWide& lhs, const UnsignedWide& rhs ) +PRUint64 +operator-( const PRUint64& lhs, const PRUint64& rhs ) { - PRInt64 a = LL_INIT(lhs.hi, lhs.lo); - PRInt64 b = LL_INIT(rhs.hi, rhs.lo); - PRInt64 c; - LL_SUB(c, a, b); - - UnsignedWide result = {c.hi, c.lo}; - + PRInt64 result; + LL_SUB(result, lhs, rhs); return result; } +#endif class TestTimer { public: - TestTimer() { Microseconds(&mStartTime); } + TestTimer() : mStartTime(PR_Now()) { } ~TestTimer() { - UnsignedWide stopTime; - Microseconds(&stopTime); - UnsignedWide totalTime = stopTime - mStartTime; - if ( totalTime.hi ) - cout << "*"; - cout << setw(10) << totalTime.lo << " µs : "; + PRTime stopTime = PR_Now(); + PRTime totalTime = stopTime - mStartTime; + cout << setw(10) << totalTime << " µs : "; } private: - UnsignedWide mStartTime; + PRTime mStartTime; }; static @@ -335,6 +330,11 @@ class Profiler #endif } + void + Dump( const char* output_name ) + { + } + void Dump( const unsigned char* output_name ) { diff --git a/xpcom/tests/StringFactoringTests/test_main.cpp b/xpcom/tests/StringFactoringTests/test_main.cpp new file mode 100644 index 00000000000..9f659db6159 --- /dev/null +++ b/xpcom/tests/StringFactoringTests/test_main.cpp @@ -0,0 +1,399 @@ +#include + +#include "nsString.h" +#include "nsSharedString.h" +#ifdef TEST_STD_STRING +#include "nsStdStringWrapper.h" +#else + +typedef nsString nsStdString; +typedef nsCString nsStdCString; + +#endif + +// #define NS_USE_WCHAR_T + +#if 0 +static +ostream& +print_string( const nsAReadableString& s ) + { + struct PRUnichar_to_char + { + char operator()( PRUnichar c ) { return char(c); } + }; + + transform(s.BeginReading(), s.EndReading(), ostream_iterator(cout), PRUnichar_to_char()); + return cout; + } +#endif + + +template +basic_nsLiteralString +literal_hello( CharT* ) + { + } + +NS_SPECIALIZE_TEMPLATE +basic_nsLiteralString +literal_hello( char* ) + { + return basic_nsLiteralString("Hello"); + } + +NS_SPECIALIZE_TEMPLATE +basic_nsLiteralString +literal_hello( PRUnichar* ) + { +#ifdef NS_USE_WCHAR_T + return basic_nsLiteralString(L"Hello"); +#else + static PRUnichar constant_unicode[] = { 'H', 'e', 'l', 'l', 'o', PRUnichar() }; + return basic_nsLiteralString(constant_unicode); +#endif + } + +static +void +CallCMid( nsAWritableCString& aResult, const nsAReadableCString& aSource, PRUint32 aStartPos, PRUint32 aLengthToCopy ) + { + aSource.Mid(aResult, aStartPos, aLengthToCopy); + } + + + +template +int +test_multifragment_iterators( const basic_nsAReadableString& aString ) + /* + ...this tests a problem that was present in |nsPromiseConcatenation| where, + because it originally stored some iteration state in the object itself, rather than + in the fragment, the iterators could get confused if used out of sequence. + + This test should be run on any multi-fragment implementation to verify that it + does not have the same bug. Make sure the first fragment is only one character long. + */ + { + typedef typename basic_nsAReadableString::ConstIterator ConstIterator; + + int tests_failed = 0; + + ConstIterator iter1 = aString.BeginReading(); + ConstIterator iter2 = aString.BeginReading(); + ++iter2; ++iter2; + + ConstIterator iter3 = aString.EndReading(); + --iter3; + ++iter1; ++iter1; + if ( iter1 != iter2 ) + { + cout << "FAILED in |test_multifragment_iterators|" << endl; + ++tests_failed; + } + + return tests_failed; + } + +template +int +test_readable_hello( const basic_nsAReadableString& aReadable ) + { + int tests_failed = 0; + + if ( aReadable.Length() != 5 ) + { + cout << "FAILED |test_readable_hello|: |Length()| --> " << aReadable.Length() << endl; + ++tests_failed; + } + + if ( aReadable.First() != CharT('H') ) + { + cout << "FAILED |test_readable_hello|: |First()| --> '" << aReadable.First() << "'" << endl; + ++tests_failed; + } + + if ( aReadable.Last() != CharT('o') ) + { + cout << "FAILED |test_readable_hello|: |Last()| --> '" << aReadable.Last() << "'" << endl; + ++tests_failed; + } + + if ( aReadable[3] != CharT('l') ) + { + cout << "FAILED |test_readable_hello|: |operator[]| --> '" << aReadable[3] << "'" << endl; + ++tests_failed; + } + + if ( aReadable.CountChar( CharT('l') ) != 2 ) + { + cout << "FAILED |test_readable_hello|: |CountChar('l')| --> " << aReadable.CountChar(CharT('l')) << endl; + ++tests_failed; + } + + basic_nsAReadableString::ConstIterator iter = aReadable.BeginReading(); + if ( *iter != CharT('H') ) + { + cout << "FAILED |test_readable_hello|: didn't start out pointing to the right thing, or else couldn't be dereferenced. --> '" << *iter << "'" << endl; + ++tests_failed; + } + + ++iter; + + if ( *iter != CharT('e') ) + { + cout << "FAILED |test_readable_hello|: iterator couldn't be incremented, or else couldn't be dereferenced. --> '" << *iter << "'" << endl; + ++tests_failed; + } + + iter = aReadable.EndReading(); + --iter; + if ( *iter != CharT('o') ) + { + 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; + ++tests_failed; + } + + basic_nsAReadableString::ConstIterator iter1 = aReadable.BeginReading(3); + if ( *iter1 != CharT('l') ) + { + cout << "FAILED |test_readable_hello|: iterator couldn't be set to |BeginReading(n)|, or else couldn't be dereferenced. --> '" << *iter1 << "'" << endl; + ++tests_failed; + } + + basic_nsAReadableString::ConstIterator iter2 = aReadable.EndReading(2); + if ( *iter2 != CharT('l') ) + { + cout << "FAILED |test_readable_hello|: iterator couldn't be set to |EndReading(n)|, or else couldn't be dereferenced. --> '" << *iter2 << "'" << endl; + ++tests_failed; + } + + if ( iter1 != iter2 ) + { + cout << "FAILED |test_readable_hello|: iterator comparison with !=." << endl; + ++tests_failed; + } + + if ( !(iter1 == iter2) ) + { + cout << "FAILED |test_readable_hello|: iterator comparison with ==." << endl; + ++tests_failed; + } + + typedef CharT* CharT_ptr; + if ( aReadable != literal_hello(CharT_ptr()) ) + { + cout << "FAILED |test_readable_hello|: comparison with \"Hello\"" << endl; + ++tests_failed; + } + + tests_failed += test_multifragment_iterators(aReadable); + // tests_failed += test_deprecated_GetBufferGetUnicode(aReadable); + + return tests_failed; + } + + + + + +template +int +test_writable( basic_nsAWritableString& aWritable ) + { + int tests_failed = 0; + // ... + + + { + typedef CharT* CharT_ptr; + aWritable = literal_hello(CharT_ptr()); + + if ( aWritable != literal_hello(CharT_ptr()) ) + { + cout << "FAILED assignment and/or comparison in |test_writable|." << endl; + ++tests_failed; + } + + tests_failed += test_readable_hello(aWritable); + } + + return tests_failed; + } + + + +typedef void* void_ptr; + +int +main() + { + int tests_failed = 0; + cout << "String unit tests. Compiled " __DATE__ " " __TIME__ << endl; + + + { +#ifdef NS_USE_WCHAR_T + nsLiteralString s0(L"Hello"); +#else + PRUnichar b0[] = { 'H', 'e', 'l', 'l', 'o', PRUnichar() }; + nsLiteralString s0(b0); +#endif + tests_failed += test_readable_hello(s0); + + nsLiteralCString s1("Hello"); + tests_failed += test_readable_hello(s1); + } + + { +#ifdef NS_USE_WCHAR_T + nsString s3(L"Hello"); +#else + PRUnichar b3[] = { 'H', 'e', 'l', 'l', 'o', PRUnichar() }; + nsString s3(b3); +#endif + tests_failed += test_readable_hello(s3); + tests_failed += test_writable(s3); + + nsCString s4("Hello"); + tests_failed += test_readable_hello(s4); + tests_failed += test_writable(s4); + } + + { +#ifdef NS_USE_WCHAR_T + nsStdString s5(L"Hello"); +#else + PRUnichar b5[] = { 'H', 'e', 'l', 'l', 'o', PRUnichar() }; + nsStdString s5(b5); +#endif + tests_failed += test_readable_hello(s5); + tests_failed += test_writable(s5); + + nsStdCString s6("Hello"); + tests_failed += test_readable_hello(s6); + tests_failed += test_writable(s6); + } + + { +#ifdef NS_USE_WCHAR_T + nsLiteralString s7(L"He"); + nsString s8(L"l"); + nsStdString s9(L"lo"); +#else + PRUnichar b7[] = { 'H', 'e', PRUnichar() }; + PRUnichar b8[] = { 'l', PRUnichar() }; + PRUnichar b9[] = { 'l', 'o', PRUnichar() }; + + nsLiteralString s7(b7); + nsString s8(b8); + nsStdString s9(b9); +#endif + + tests_failed += test_readable_hello(s7+s8+s9); + + nsString s13( s7 + s8 + s9 ); + tests_failed += test_readable_hello(s13); + + nsStdString s14( s7 + s8 + s9 ); + tests_failed += test_readable_hello(s14); + + nsSharedString* s15 = new_nsSharedString( s7 + s8 + s9 ); + tests_failed += test_readable_hello(*s15); + // cout << "Here's a string: \""; print_string(*s15) << "\"" << endl; + + nsCString s10("He"); + nsLiteralCString s11("l"); + nsStdCString s12("lo"); + + tests_failed += test_readable_hello(s10+s11+s12); + + + } + + + { + nsLiteralCString str1("Hello"); + nsStdCString str2("Hello"); + + nsLiteralCString str3("Hello there"); + + if ( str1 != str2 ) + { + cout << "string comparison using != failed" << endl; + ++tests_failed; + } + + if ( !(str3 > str2) ) + { + cout << "string comparison using > failed" << endl; + ++tests_failed; + } + + if ( !(str2 < str3) ) + { + cout << "string comparison using < failed" << endl; + ++tests_failed; + } + + if ( str1 != "Hello" ) + { + cout << "string comparison using == failed" << endl; + ++tests_failed; + } + } + +#if 0 + nsStdCString extracted_middle("XXXXXXXXXX"); + CallCMid(extracted_middle, part1+part2a+part2b, 1, 3); + + cout << "The result of mid was \"" << extracted_middle << "\"" << endl; + + nsLiteralCString middle_answer("ell"); + if ( middle_answer != extracted_middle ) + { + cout << "mid FAILED on nsConcatString" << endl; + ++tests_failed; + } + + + + // + // |nsStdStringWrapper|, i.e., |nsStdCString| + // + + { + nsStdCString extracted_middle; + CallCMid(extracted_middle, part1+part2a+part2b, 1, 3); + + cout << "The result of mid was \"" << extracted_middle << "\"" << endl; + + nsLiteralCString middle_answer("ell"); + if ( middle_answer != extracted_middle ) + { + cout << "mid FAILED on nsStdCString" << endl; + ++tests_failed; + } + } + + + + nsStdCString leftString; + source.Left(leftString, 9); + // cout << static_cast(leftString) << endl; + + + + tests_failed += test_multifragment_iterators(part1+part2a+part2b); +#endif + + + + cout << "End of string unit tests." << endl; + if ( !tests_failed ) + cout << "OK, all tests passed." << endl; + else + cout << "FAILED one or more tests." << endl; + + return 0; + }