summaryrefslogtreecommitdiffstats
path: root/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/xpcom18a4/xpcom/tests/StringFactoringTests')
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/Makefile.in76
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTest.Prefix4
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTest.mcpbin0 -> 245184 bytes
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestDebug.Prefix4
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestNo_wchar_t.Prefix5
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestProfileNew.Prefix3
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestProfileOld.Prefix6
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestProfileStd.Prefix7
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/ToDo.doc41
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/nsStdStringWrapper.h234
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/profile_main.cpp497
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/test_main.cpp651
12 files changed, 1528 insertions, 0 deletions
diff --git a/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/Makefile.in b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/Makefile.in
new file mode 100644
index 00000000..1ced5d3e
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/Makefile.in
@@ -0,0 +1,76 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla 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/MPL/
+#
+# 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 the Initial Developer are Copyright (C) 1998
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of the GNU General Public License Version 2 or later (the "GPL"),
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH = ../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = xpcom
+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
+
+libs::
+ $(INSTALL) $(srcdir)/test.properties $(DIST)/bin/res
+
+install::
+ $(SYSINSTALL) $(IFLAGS1) $(srcdir)/test.properties $(DESTDIR)$(mozappdir)/res
+
diff --git a/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTest.Prefix b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTest.Prefix
new file mode 100644
index 00000000..b9580e49
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTest.Prefix
@@ -0,0 +1,4 @@
+// StringTest.Prefix
+
+#define STANDALONE_STRING_TESTS
+#define HAVE_CPP_2BYTE_WCHAR_T
diff --git a/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTest.mcp b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTest.mcp
new file mode 100644
index 00000000..12b125ed
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTest.mcp
Binary files differ
diff --git a/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestDebug.Prefix b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestDebug.Prefix
new file mode 100644
index 00000000..3724af94
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestDebug.Prefix
@@ -0,0 +1,4 @@
+#include "StringTest.Prefix"
+
+#define DEBUG 1
+#undef NDEBUG
diff --git a/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestNo_wchar_t.Prefix b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestNo_wchar_t.Prefix
new file mode 100644
index 00000000..dddf8450
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestNo_wchar_t.Prefix
@@ -0,0 +1,5 @@
+// StringTestNo_wchar_t.Prefix
+
+#include "StringTest.Prefix"
+
+#undef HAVE_CPP_2BYTE_WCHAR_T
diff --git a/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestProfileNew.Prefix b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestProfileNew.Prefix
new file mode 100644
index 00000000..b6ca50d3
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestProfileNew.Prefix
@@ -0,0 +1,3 @@
+// StringTestProfileNew.Prefix
+
+#include "StringTest.Prefix"
diff --git a/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestProfileOld.Prefix b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestProfileOld.Prefix
new file mode 100644
index 00000000..d23e3ea9
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestProfileOld.Prefix
@@ -0,0 +1,6 @@
+// StringTestProfileOld.Prefix
+
+#include "StringTest.Prefix"
+
+#define OLD_STRING_APIS
+#undef HAVE_CPP_2BYTE_WCHAR_T \ No newline at end of file
diff --git a/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestProfileStd.Prefix b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestProfileStd.Prefix
new file mode 100644
index 00000000..eb8a7a85
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestProfileStd.Prefix
@@ -0,0 +1,7 @@
+// StringTestProfileOld.Prefix
+
+#include "StringTest.Prefix"
+
+#define OLD_STRING_APIS
+#define TEST_STD_STRING
+#undef HAVE_CPP_2BYTE_WCHAR_T \ No newline at end of file
diff --git a/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/ToDo.doc b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/ToDo.doc
new file mode 100644
index 00000000..da114471
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/ToDo.doc
@@ -0,0 +1,41 @@
+// To Do...
+
+ - Decide: do I really want to define |Equals| (i.e., so many extra signatures)
+
+ . Make |ns[C]String| rename its converting operations to, e.g., |EqualsWithConversion|,
+ |AssignWithConversion|, |CompareWithConversion|, |AppendWithConversion|, etc.
+
+ . Bring |Equals| and |Compare| into scope
+
+ . Implement chunky iterators
+
+ . Get "nsAReadableString.h" and "nsAWritableString.h" to added to the MANIFEST, etc.
+
+ - Get "nsAReadableString.h" and "nsAWritableString.h" to compile everywhere
+
+ - Add test for |Replace|...
+
+ - Add tests for Find and RFind
+
+ - Implement the Find and RFind signatures
+
+ . Fix Truncate / SetLength confusion (make SetLength the real function in |nsString|)
+
+ . Chop out conflicting |ns[C]String| operators
+
+ . Figure out how if we can make PRUnichar be wchar_t, so we get the cheap constructors,
+ ...and ensure the cheap constructors can be made to work everywhere
+
+ x Try the |static const unsigned long kLeftString = 1 - 1; /* because VC++ doesn't like =0 */| hack
+
+ . Add tests for |nsShared[C]String|
+
+ . Implement |nsShared[C]String|
+
+ - Add tests for the shared string smart pointer
+
+ . Implement the shared string smart pointer
+
+ . Figure out why StdStringWrapper isn't as good as raw std::string
+
+ - Implement a smart allocator for StdStringWrapper
diff --git a/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/nsStdStringWrapper.h b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/nsStdStringWrapper.h
new file mode 100644
index 00000000..6e43b528
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/nsStdStringWrapper.h
@@ -0,0 +1,234 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla 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/MPL/
+ *
+ * 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 the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Scott Collins <scc@mozilla.org>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsStdStringWrapper_h___
+#define nsStdStringWrapper_h___
+
+#include <string>
+
+#ifndef nsAString_h___
+#include "nsAString.h"
+#endif
+
+
+template <class T>
+class nsStringAllocator
+ : public std::allocator<T> // temporarily
+ {
+ // ...
+ };
+
+
+template < class CharT, class TraitsT = nsCharTraits<CharT>, class AllocatorT = nsStringAllocator<CharT> >
+class basic_nsStdStringWrapper
+ : public basic_nsAString<CharT>
+ /*
+ ...
+ */
+ {
+ protected:
+ std::basic_string<CharT, TraitsT, AllocatorT> mRawString;
+
+ typedef std::basic_string<CharT, TraitsT, AllocatorT> basic_string_t;
+
+ using typename basic_string_t::traits_type;
+ using typename basic_string_t::value_type;
+ using typename basic_string_t::allocator_type;
+ using typename basic_string_t::size_type;
+ using typename basic_string_t::difference_type;
+ using typename basic_string_t::reference;
+ using typename basic_string_t::const_reference;
+ using typename basic_string_t::pointer;
+ using typename basic_string_t::const_pointer;
+ using typename basic_string_t::iterator;
+ using typename basic_string_t::const_iterator;
+ using typename basic_string_t::reverse_iterator;
+ using typename basic_string_t::const_reverse_iterator;
+
+ static const size_type npos = size_type(-1);
+
+ protected:
+ virtual const void* Implementation() const;
+
+ virtual const CharT* GetReadableFragment( nsReadableFragment<CharT>&, nsFragmentRequest, PRUint32 ) const;
+ virtual CharT* GetWritableFragment( nsWritableFragment<CharT>&, nsFragmentRequest, PRUint32 );
+
+ public:
+ basic_nsStdStringWrapper() { }
+
+#if 0
+ explicit
+ basic_nsStdStringWrapper( const AllocatorT& a = AllocatorT() )
+ : mRawString(a)
+ {
+ }
+#endif
+
+ explicit
+ basic_nsStdStringWrapper( const basic_nsAString<CharT>& str )
+ {
+ Assign(str);
+ }
+
+#if 0
+ explicit
+ basic_nsStdStringWrapper( const basic_string_t& str, size_type pos = 0, size_type n = npos )
+ : mRawString(str, pos, n)
+ {
+ }
+
+ basic_nsStdStringWrapper( const basic_string_t& str, size_type pos, size_type n, const AllocatorT& a )
+ : mRawString(str, pos, n, a)
+ {
+ }
+#endif
+
+ basic_nsStdStringWrapper( const CharT* s, size_type n, const AllocatorT& a = AllocatorT() )
+ : mRawString(s, n, a)
+ {
+ }
+
+ explicit
+ basic_nsStdStringWrapper( const CharT* s, const AllocatorT& a = AllocatorT() )
+ : mRawString(s, a)
+ {
+ }
+
+#if 0
+ basic_nsStdStringWrapper( size_type n, CharT c, const AllocatorT& a = AllocatorT() )
+ : mRawString(n, c, a)
+ {
+ }
+#endif
+
+ virtual
+ PRUint32
+ Length() const
+ {
+ return mRawString.length();
+ }
+
+ virtual
+ void
+ SetCapacity( PRUint32 aNewCapacity )
+ {
+ mRawString.reserve(aNewCapacity);
+ }
+
+ virtual
+ void
+ SetLength( PRUint32 aNewLength )
+ {
+ mRawString.resize(aNewLength);
+ }
+
+ protected:
+ virtual void do_AssignFromReadable( const basic_nsAString<CharT>& );
+
+ // ...
+ };
+
+NS_DEF_TEMPLATE_STRING_COMPARISON_OPERATORS(basic_nsStdStringWrapper<CharT>, CharT)
+
+
+
+template <class CharT, class TraitsT, class AllocatorT>
+const void*
+basic_nsStdStringWrapper<CharT, TraitsT, AllocatorT>::Implementation() const
+ {
+ static const char* implementation = "nsStdStringWrapper";
+ return implementation;
+ }
+
+
+template <class CharT, class TraitsT, class AllocatorT>
+const CharT*
+basic_nsStdStringWrapper<CharT, TraitsT, AllocatorT>::GetReadableFragment( nsReadableFragment<CharT>& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const
+ {
+ switch ( aRequest )
+ {
+ case kFirstFragment:
+ case kLastFragment:
+ case kFragmentAt:
+ aFragment.mEnd = (aFragment.mStart = mRawString.data()) + mRawString.length();
+ return aFragment.mStart + aOffset;
+
+ case kPrevFragment:
+ case kNextFragment:
+ default:
+ return 0;
+ }
+ }
+
+template <class CharT, class TraitsT, class AllocatorT>
+CharT*
+basic_nsStdStringWrapper<CharT, TraitsT, AllocatorT>::GetWritableFragment( nsWritableFragment<CharT>& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset )
+ {
+ switch ( aRequest )
+ {
+ case kFirstFragment:
+ case kLastFragment:
+ case kFragmentAt:
+ aFragment.mEnd = (aFragment.mStart = NS_CONST_CAST(CharT*, mRawString.data())) + mRawString.length();
+ return aFragment.mStart + aOffset;
+
+ case kPrevFragment:
+ case kNextFragment:
+ default:
+ return 0;
+ }
+ }
+
+template <class CharT, class TraitsT, class AllocatorT>
+void
+basic_nsStdStringWrapper<CharT, TraitsT, AllocatorT>::do_AssignFromReadable( const basic_nsAString<CharT>& rhs )
+ {
+ typedef basic_nsStdStringWrapper<CharT, TraitsT, AllocatorT> this_t;
+
+ if ( SameImplementation(*this, rhs) )
+ mRawString = NS_STATIC_CAST(this_t, rhs).mRawString;
+ else
+ basic_nsAString<CharT>::do_AssignFromReadable(rhs);
+ }
+
+
+typedef basic_nsStdStringWrapper<PRUnichar> nsStdString;
+typedef basic_nsStdStringWrapper<char> nsStdCString;
+
+
+#endif // !defined(nsStdStringWrapper_h___)
diff --git a/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/profile_main.cpp b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/profile_main.cpp
new file mode 100644
index 00000000..d7c14621
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/profile_main.cpp
@@ -0,0 +1,497 @@
+// profile_main.cpp
+
+#include "nscore.h"
+#include <iostream.h>
+#include <string>
+#include <iomanip>
+
+#include "nsInt64.h"
+
+#ifdef XP_MAC
+#include <Timer.h>
+#include "Profiler.h"
+#else
+#include "prtime.h"
+#endif
+
+#ifndef TEST_STD_STRING
+#include "nsString.h"
+#else
+#include "nsStdStringWrapper.h"
+typedef nsStdCString nsCString;
+#endif
+
+static const int kTestSucceeded = 0;
+static const int kTestFailed = 1;
+
+static const size_t N = 100000;
+
+
+template <class T>
+inline
+PRUint32
+TotalLength( const T& s )
+ {
+ return s.Length();
+ }
+
+NS_SPECIALIZE_TEMPLATE
+inline
+PRUint32
+TotalLength( const string& s )
+ {
+ return s.length();
+ }
+
+template <class T>
+inline
+PRUint32
+Find( const T& text, const T& pattern )
+ {
+ return text.Find(pattern);
+ }
+
+NS_SPECIALIZE_TEMPLATE
+inline
+PRUint32
+Find( const string& text, const string& pattern )
+ {
+ return text.find(pattern);
+ }
+
+inline
+nsInt64
+GetTime()
+ {
+#ifdef XP_MAC
+ UnsignedWide time;
+ Microseconds(&time);
+ return nsInt64( *reinterpret_cast<PRInt64*>(&time) );
+#else
+ return nsInt64( PR_Now() );
+#endif
+ }
+
+class TestTimer
+ {
+ public:
+ TestTimer() : mStartTime(GetTime()) { }
+
+ ~TestTimer()
+ {
+ nsInt64 stopTime = GetTime();
+ nsInt64 totalTime = stopTime - mStartTime;
+#ifdef HAVE_LONG_LONG
+ cout << setw(10) << NS_STATIC_CAST(PRInt64, totalTime) << " µs : ";
+#else
+ cout << setw(10) << NS_STATIC_CAST(PRInt32, totalTime) << "µs : ";
+#endif
+ }
+
+ private:
+ nsInt64 mStartTime;
+ };
+
+inline
+int
+foo( const nsCString& )
+ {
+ return 1;
+ }
+
+static
+int
+test_construction()
+ {
+ cout << endl;
+
+ {
+ nsCString someCString;
+ int total = 0;
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ {
+ total += foo( someCString );
+ }
+ }
+ cout << "null loop time for constructor" << endl;
+
+
+ {
+ int total = 0;
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ {
+ total += foo( nsCString() );
+ }
+ }
+ cout << "nsCString()" << endl;
+
+
+ {
+ int total = 0;
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ {
+ total += foo( nsCString("This is a reasonable length string with some text in it and it is good.") );
+ }
+ }
+ cout << "nsCString(\"abc\")" << endl;
+
+ return kTestSucceeded;
+ }
+
+static
+int
+test_concat()
+ {
+ cout << endl;
+
+ //---------|---------|---------|---------|---------|---------|---------|
+ nsCString s1("This is a reasonable length string with some text in it and it is good.");
+ nsCString s2("This is another string that I will use in the concatenation test.");
+ nsCString s3("This is yet a third string that I will use in the concatenation test.");
+
+ PRUint32 len = TotalLength( s1 + s2 + s3 + s1 + s2 + s3 );
+ if ( len != (71 + 65 + 69 + 71 + 65 + 69) )
+ {
+ cout << "|test_concat()| FAILED" << endl;
+ return kTestFailed;
+ }
+
+
+ {
+ nsCString anEmptyCString;
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ {
+ len += TotalLength( anEmptyCString );
+ }
+ }
+ cout << "null loop time for concat" << endl;
+
+
+ {
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ len += TotalLength( s1 + s2 + s3 + s1 + s2 + s3 );
+ }
+ cout << "TotalLength( s1 + s2 + s3 + s1 + s2 + s3 )" << endl;
+
+
+ {
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ len += TotalLength( s1 + s2 );
+ }
+ cout << "TotalLength( s1 + s2 )" << endl;
+
+ return kTestSucceeded;
+ }
+
+static
+int
+test_concat_and_assign()
+ {
+ //---------|---------|---------|---------|---------|---------|---------|
+ nsCString s1("This is a reasonable length string with some text in it and it is good.");
+ nsCString s2("This is another string that I will use in the concatenation test.");
+ nsCString s3("This is yet a third string that I will use in the concatenation test.");
+
+ nsCString s4( s1 + s2 + s3 + s1 + s2 + s3 );
+ if ( TotalLength(s4) != (71 + 65 + 69 + 71 + 65 + 69) )
+ {
+ cout << "|test_concat()| FAILED" << endl;
+ return kTestFailed;
+ }
+
+
+ {
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ s4 = s1 + s2 + s3 + s1 + s2 + s3;
+ }
+ cout << "s4 = s1 + s2 + s3 + s1 + s2 + s3" << endl;
+
+ {
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ s4 = s1 + s2;
+ }
+ cout << "s4 = s1 + s2" << endl;
+
+ return kTestSucceeded;
+ }
+
+static
+int
+test_compare()
+ {
+ nsCString s1("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxThis is a reasonable length string with some text in it and it is good.");
+ nsCString s2("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxThis is a reasonable length string with some text in it and it is bad.");
+
+ int count = 0;
+ {
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ if ( s1 > s2 )
+ ++count;
+ }
+ cout << "s1 > s2" << endl;
+
+ {
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ if ( s1 == s1 )
+ ++count;
+ }
+ cout << "s1 == s1" << endl;
+
+ return kTestSucceeded;
+ }
+
+static
+int
+test_countchar()
+ {
+ nsCString s1("This is a reasonable length string with some text in it and it is good.");
+
+ if ( s1.CountChar('e') != 5 )
+ {
+ cout << "|test_countchar()| FAILED: found a count of " << s1.CountChar('e') << endl;
+ return kTestFailed;
+ }
+
+ PRUint32 total = 0;
+ {
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ total += s1.CountChar('e');
+ }
+ cout << "s1.CountChar('e')" << endl;
+
+ return kTestSucceeded;
+ }
+
+static
+int
+test_append_string()
+ {
+ nsCString s1("This is a reasonable length string with some text in it and it is good.");
+ nsCString s2("This is another string that I will use in the concatenation test.");
+
+ PRUint32 len = 0;
+
+ {
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ {
+ nsCString s3;
+ s3.Append(s1);
+ s3.Append(s2);
+ len += TotalLength(s3);
+ }
+ }
+ cout << "s3.Append(s1); s3.Append(s2)" << endl;
+
+ return kTestSucceeded;
+ }
+
+static
+int
+test_repeated_append_string()
+ {
+ nsCString s1("This is a reasonable length string with some text in it and it is good.");
+ nsCString s2("This is another string that I will use in the concatenation test.");
+
+ PRUint32 len = 0;
+
+ {
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ {
+ nsCString s3;
+ for ( int j=0; j<100; ++j )
+ {
+ s3.Append(s1);
+ s3.Append(s2);
+ len += TotalLength(s3);
+ }
+ }
+ }
+ cout << "repeated s3.Append(s1); s3.Append(s2)" << endl;
+
+ return kTestSucceeded;
+ }
+
+static
+int
+test_append_char()
+ {
+ cout << endl;
+
+ PRUint32 len = 0;
+
+ nsCString s1("hello");
+ PRUint32 oldLength = s1.Length();
+
+ {
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ {
+ s1.SetLength(oldLength);
+ }
+ }
+ cout << "null loop time for append char" << endl;
+
+ {
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ {
+ s1.Append('e');
+ s1.SetLength(oldLength);
+ }
+ }
+ cout << "s1.Append('e')" << endl;
+
+ return kTestSucceeded;
+ }
+
+static
+int
+test_repeated_append_char()
+ {
+ PRUint32 len = 0;
+
+ {
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ {
+ nsCString s1;
+ for ( int j=0; j<1000; ++j )
+ {
+ s1.Append('e');
+ len += TotalLength(s1);
+ }
+ }
+ }
+ cout << "repeated s1.Append('e')" << endl;
+
+ return kTestSucceeded;
+ }
+
+static
+int
+test_insert_string()
+ {
+ nsCString s1("This is a reasonable length string with some text in it and it is good.");
+
+ PRUint32 len = 0;
+
+ {
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ {
+ nsCString s2("This is another string that I will use in the concatenation test.");
+ s2.Insert(s1, 3);
+ len += TotalLength(s2);
+ }
+ }
+ cout << "s2.Insert(s1, 3)" << endl;
+
+ return kTestSucceeded;
+ }
+
+#ifndef TEST_STD_STRING
+static
+int
+test_find_string()
+ {
+ nsCString text("aaaaaaaaaab");
+ nsCString pattern("aab");
+
+ PRUint32 position = 0;
+ {
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ position = Find(text, pattern);
+ }
+ cout << "text.Find(pattern)" << endl;
+
+ return kTestSucceeded;
+ }
+#endif
+
+class Profiler
+ {
+ public:
+ Profiler()
+ {
+#if 0
+ ProfilerInit(collectDetailed, bestTimeBase, 100, 32);
+#endif
+ }
+
+ void
+ Dump( const char* output_name )
+ {
+ }
+
+ void
+ Dump( const unsigned char* output_name )
+ {
+#if 0
+ ProfilerDump(output_name);
+#endif
+ }
+
+ ~Profiler()
+ {
+#if 0
+ ProfilerDump(mOutputName);
+ ProfilerTerm();
+#endif
+ }
+ };
+
+int
+main()
+ {
+
+ cout << "String performance profiling. Compiled " __DATE__ " " __TIME__ << endl;
+#ifdef TEST_STD_STRING
+ cout << "Testing std::string." << endl;
+#else
+ cout << "Testing factored nsString." << endl;
+#endif
+
+ int tests_failed = 0;
+
+ Profiler profiler;
+
+ tests_failed += test_construction();
+ tests_failed += test_concat();
+ tests_failed += test_concat_and_assign();
+ tests_failed += test_compare();
+ tests_failed += test_countchar();
+ tests_failed += test_append_string();
+ tests_failed += test_repeated_append_string();
+ tests_failed += test_append_char();
+ tests_failed += test_repeated_append_char();
+ tests_failed += test_insert_string();
+#ifndef TEST_STD_STRING
+ tests_failed += test_find_string();
+#endif
+
+#ifdef TEST_STD_STRING
+ profiler.Dump("\pStandard String.prof");
+#else
+ profiler.Dump("\pFactored String.prof");
+#endif
+
+ if ( tests_failed )
+ cout << "One or more tests FAILED. Measurements may be invalid." << endl;
+
+ cout << "End of string performance profiling." << endl;
+ return 0;
+ }
diff --git a/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/test_main.cpp b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/test_main.cpp
new file mode 100644
index 00000000..b8365dac
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/test_main.cpp
@@ -0,0 +1,651 @@
+#include <iostream.h>
+#include "nsStringIO.h"
+
+//#define TEST_STD_STRING
+
+
+#include "nsString.h"
+#include "nsFragmentedString.h"
+#include "nsReadableUtils.h"
+#include "nsSlidingString.h"
+
+#ifdef TEST_STD_STRING
+#include "nsStdStringWrapper.h"
+#else
+ typedef nsString nsStdString;
+ typedef nsCString nsStdCString;
+#endif
+
+template <class CharT>
+basic_nsLiteralString<CharT>
+literal_hello( CharT* )
+ {
+ }
+
+NS_SPECIALIZE_TEMPLATE
+basic_nsLiteralString<char>
+literal_hello( char* )
+ {
+ return basic_nsLiteralString<char>("Hello");
+ }
+
+NS_SPECIALIZE_TEMPLATE
+basic_nsLiteralString<PRUnichar>
+literal_hello( PRUnichar* )
+ {
+#ifdef HAVE_CPP_2BYTE_WCHAR_T
+ return basic_nsLiteralString<PRUnichar>(L"Hello");
+#else
+ static PRUnichar constant_unicode[] = { 'H', 'e', 'l', 'l', 'o', PRUnichar() };
+ return basic_nsLiteralString<PRUnichar>(constant_unicode);
+#endif
+ }
+
+template <class T>
+struct string_class_traits
+ {
+ };
+
+NS_SPECIALIZE_TEMPLATE
+struct string_class_traits<PRUnichar>
+ {
+ typedef PRUnichar* pointer;
+ typedef nsString implementation_t;
+
+ static basic_nsLiteralString<PRUnichar> literal_hello() { return ::literal_hello(pointer()); }
+ };
+
+NS_SPECIALIZE_TEMPLATE
+struct string_class_traits<char>
+ {
+ typedef char* pointer;
+ typedef nsCString implementation_t;
+
+ static basic_nsLiteralString<char> literal_hello() { return ::literal_hello(pointer()); }
+ };
+
+
+static
+void
+CallCMid( nsACString& aResult, const nsACString& aSource, PRUint32 aStartPos, PRUint32 aLengthToCopy )
+ {
+ aSource.Mid(aResult, aStartPos, aLengthToCopy);
+ }
+
+
+
+template <class CharT>
+int
+test_multifragment_iterators( const basic_nsAString<CharT>& 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_nsAString<CharT>::const_iterator 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 <class CharT>
+int
+test_Vidur_functions( const basic_nsAString<CharT>& aString )
+ {
+ char* char_copy = ToNewCString(aString);
+ PRUnichar* PRUnichar_copy = ToNewUnicode(aString);
+
+ nsMemory::Free(PRUnichar_copy);
+ nsMemory::Free(char_copy);
+
+ return 0;
+ }
+
+template <class CharT>
+int
+test_readable_hello( const basic_nsAString<CharT>& 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_nsAString<CharT>::const_iterator 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_nsAString<CharT>::const_iterator iter1 = aReadable.BeginReading().advance(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_nsAString<CharT>::const_iterator iter2 = aReadable.EndReading().advance(-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);
+
+ test_Vidur_functions(aReadable);
+
+ return tests_failed;
+ }
+
+
+template <class CharT>
+int
+test_SetLength( basic_nsAString<CharT>& aWritable )
+ {
+ int tests_failed = 0;
+
+ string_class_traits<CharT>::implementation_t oldValue(aWritable);
+
+
+ size_t oldLength = aWritable.Length();
+
+ if ( oldValue != Substring(aWritable, 0, oldLength) )
+ {
+ cout << "FAILED growing a string in |test_SetLength|, saving the value didn't work." << endl;
+ ++tests_failed;
+ }
+
+ size_t newLength = 2*(oldLength+1);
+
+ aWritable.SetLength(newLength);
+ if ( aWritable.Length() != newLength )
+ {
+ cout << "FAILED growing a string in |test_SetLength|, length is wrong." << endl;
+ ++tests_failed;
+ }
+
+ if ( oldValue != Substring(aWritable, 0, oldLength) )
+ {
+ cout << "FAILED growing a string in |test_SetLength|, contents damaged after growing." << endl;
+ ++tests_failed;
+ }
+
+ aWritable.SetLength(oldLength);
+ if ( aWritable.Length() != oldLength )
+ {
+ cout << "FAILED shrinking a string in |test_SetLength|." << endl;
+ ++tests_failed;
+ }
+
+ if ( oldValue != Substring(aWritable, 0, oldLength) )
+ {
+ cout << "FAILED growing a string in |test_SetLength|, contents damaged after shrinking." << endl;
+ ++tests_failed;
+ }
+
+ return tests_failed;
+ }
+
+
+template <class CharT>
+int
+test_insert( basic_nsAString<CharT>& aWritable )
+ {
+ int tests_failed = 0;
+
+ string_class_traits<CharT>::implementation_t oldValue(aWritable);
+
+ if ( oldValue != aWritable )
+ {
+ cout << "FAILED saving the old string value in |test_insert|." << endl;
+ ++tests_failed;
+ }
+
+ string_class_traits<CharT>::implementation_t insertable( string_class_traits<CharT>::literal_hello() );
+
+ insertable.SetLength(1);
+ aWritable.Insert(insertable, 0);
+
+ if ( aWritable != (insertable + oldValue) )
+ {
+ cout << "FAILED in |test_insert|." << endl;
+ ++tests_failed;
+ }
+
+ aWritable = oldValue;
+
+ return tests_failed;
+ }
+
+
+template <class CharT>
+int
+test_cut( basic_nsAString<CharT>& aWritable )
+ {
+ int tests_failed = 0;
+
+ aWritable.Cut(0, aWritable.Length()+5);
+
+ return tests_failed;
+ }
+
+template <class CharT>
+int
+test_self_assign( basic_nsAString<CharT>& aWritable )
+ {
+ int tests_failed = 0;
+ string_class_traits<CharT>::implementation_t oldValue(aWritable);
+
+ aWritable = aWritable;
+ if ( aWritable != oldValue )
+ {
+ cout << "FAILED self assignment." << endl;
+ ++tests_failed;
+ }
+
+ aWritable = oldValue;
+ return tests_failed;
+ }
+
+template <class CharT>
+int
+test_self_append( basic_nsAString<CharT>& aWritable )
+ {
+ int tests_failed = 0;
+ string_class_traits<CharT>::implementation_t oldValue(aWritable);
+
+ aWritable += aWritable;
+ if ( aWritable != oldValue + oldValue )
+ {
+ cout << "FAILED self append." << endl;
+ ++tests_failed;
+ }
+
+ aWritable = oldValue;
+ return tests_failed;
+ }
+
+template <class CharT>
+int
+test_self_insert( basic_nsAString<CharT>& aWritable )
+ {
+ int tests_failed = 0;
+ string_class_traits<CharT>::implementation_t oldValue(aWritable);
+
+ aWritable.Insert(aWritable, 0);
+ if ( aWritable != oldValue + oldValue )
+ {
+ cout << "FAILED self insert." << endl;
+ ++tests_failed;
+ }
+
+ aWritable = oldValue;
+ return tests_failed;
+ }
+
+template <class CharT>
+int
+test_self_replace( basic_nsAString<CharT>& aWritable )
+ {
+ int tests_failed = 0;
+ string_class_traits<CharT>::implementation_t oldValue(aWritable);
+
+ aWritable.Replace(0, 0, aWritable);
+ if ( aWritable != oldValue + oldValue )
+ {
+ cout << "FAILED self insert." << endl;
+ ++tests_failed;
+ }
+
+ aWritable = oldValue;
+ return tests_failed;
+ }
+
+
+
+template <class CharT>
+int
+test_writable( basic_nsAString<CharT>& 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);
+ }
+
+ tests_failed += test_SetLength(aWritable);
+ tests_failed += test_insert(aWritable);
+ tests_failed += test_cut(aWritable);
+ tests_failed += test_self_assign(aWritable);
+ tests_failed += test_self_append(aWritable);
+ tests_failed += test_self_insert(aWritable);
+ tests_failed += test_self_replace(aWritable);
+
+ return tests_failed;
+ }
+
+
+
+typedef void* void_ptr;
+
+int
+main()
+ {
+ int tests_failed = 0;
+ cout << "String unit tests. Compiled " __DATE__ " " __TIME__ << endl;
+
+#if 0
+ {
+ nsFragmentedCString fs0;
+ fs0.Append("Hello");
+ tests_failed += test_readable_hello(fs0);
+ tests_failed += test_writable(fs0);
+ }
+#endif
+
+ {
+ NS_NAMED_LITERAL_STRING(literal, "Hello");
+ PRUnichar* buffer = ToNewUnicode(literal);
+
+ nsSlidingString ss0(buffer, buffer+5, buffer+6);
+// ss0.AppendBuffer(buffer, buffer+5, buffer+6);
+ nsReadingIterator<PRUnichar> ri0;
+ ss0.BeginReading(ri0);
+
+ tests_failed += test_readable_hello(ss0);
+
+ nsSlidingSubstring ss1(ss0);
+ tests_failed += test_readable_hello(ss1);
+
+ buffer = ToNewUnicode(literal);
+ ss0.AppendBuffer(buffer, buffer+5, buffer+6);
+
+ ri0.advance(5);
+ ss0.DiscardPrefix(ri0);
+
+ tests_failed += test_readable_hello(ss0);
+ tests_failed += test_readable_hello(ss1);
+
+ nsReadingIterator<PRUnichar> ri1;
+ ss0.EndReading(ri1);
+
+ nsSlidingSubstring ss2(ss0, ri0, ri1);
+ tests_failed += test_readable_hello(ss2);
+ }
+
+
+ {
+ nsLiteralCString s0("Patrick Beard made me write this: \"This is just a test\"\n");
+ print_string(s0);
+
+ const char* raw_string = "He also made me write this.\n";
+ nsFileCharSink<char> output(stdout);
+ copy_string(raw_string, raw_string+nsCharTraits<char>::length(raw_string), output);
+
+ nsLiteralCString s1("This ", 5), s2("is ", 3), s3("a ", 2), s4("test\n", 5);
+ print_string(s1+s2+s3+s4);
+
+ nsLiteralCString s5( "This is " "a " "test" );
+ print_string(s5+NS_LITERAL_CSTRING("\n"));
+
+ print_string(nsLiteralCString("The value of the string |x| is \"") + Substring(s0, 0, s0.Length()-1) + NS_LITERAL_CSTRING("\". Hope you liked it."));
+ }
+
+
+ {
+ tests_failed += test_readable_hello(NS_LITERAL_STRING("Hello"));
+
+ nsLiteralCString s1("Hello");
+ tests_failed += test_readable_hello(s1);
+ }
+
+ {
+
+ nsString s3( NS_LITERAL_STRING("Hello") );
+
+ 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);
+ }
+
+ {
+ nsStdString s5( NS_LITERAL_STRING("Hello") );
+
+ 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);
+ }
+
+ {
+ nsLiteralString s7(NS_LITERAL_STRING("He"));
+ nsString s8(NS_LITERAL_STRING("l"));
+ nsStdString s9(NS_LITERAL_STRING("lo"));
+
+ 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);
+
+ nsCString s10("He");
+ nsLiteralCString s11("l");
+ nsStdCString s12("lo");
+
+ tests_failed += test_readable_hello(s10+s11+s12);
+
+
+ }
+
+ {
+ const char *foo = "this is a really long string";
+ nsCString origString;
+ nsCString string2;
+ nsCString string3;
+
+ origString = foo;
+
+ string2 = Substring(origString, 0, 5);
+ string3 = Substring(origString, 6, origString.Length() - 6);
+ }
+
+ {
+ nsLiteralCString s13("He");
+ nsCAutoString s14("l");
+ nsLiteralCString s15("lo");
+
+ s14.Assign(s13 + s14 + s15);
+
+ if ( int failures = test_readable_hello(s14) )
+ {
+ tests_failed += failures;
+ cout << "FAILED to keep a promise." << endl;
+ }
+ }
+
+
+ {
+ 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<const nsACString>(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 tests_failed;
+ }