зеркало из https://github.com/mozilla/pjs.git
make string tests build on unix
This commit is contained in:
Родитель
a069779429
Коммит
e306ef5572
|
@ -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
|
||||||
|
|
|
@ -5,8 +5,11 @@
|
||||||
#include <iostream.h>
|
#include <iostream.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#ifdef XP_MAC
|
||||||
#include "Profiler.h"
|
#include "Profiler.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef TEST_STD_STRING
|
#ifndef TEST_STD_STRING
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
|
@ -15,8 +18,6 @@
|
||||||
typedef nsStdCString nsCString;
|
typedef nsStdCString nsCString;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <Timer.h>
|
|
||||||
|
|
||||||
static const int kTestSucceeded = 0;
|
static const int kTestSucceeded = 0;
|
||||||
static const int kTestFailed = 1;
|
static const int kTestFailed = 1;
|
||||||
|
|
||||||
|
@ -55,37 +56,31 @@ Find( const string& text, const string& pattern )
|
||||||
return text.find(pattern);
|
return text.find(pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_LONG_LONG
|
||||||
inline
|
inline
|
||||||
UnsignedWide
|
PRUint64
|
||||||
operator-( const UnsignedWide& lhs, const UnsignedWide& rhs )
|
operator-( const PRUint64& lhs, const PRUint64& rhs )
|
||||||
{
|
{
|
||||||
PRInt64 a = LL_INIT(lhs.hi, lhs.lo);
|
PRInt64 result;
|
||||||
PRInt64 b = LL_INIT(rhs.hi, rhs.lo);
|
LL_SUB(result, lhs, rhs);
|
||||||
PRInt64 c;
|
|
||||||
LL_SUB(c, a, b);
|
|
||||||
|
|
||||||
UnsignedWide result = {c.hi, c.lo};
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
class TestTimer
|
class TestTimer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TestTimer() { Microseconds(&mStartTime); }
|
TestTimer() : mStartTime(PR_Now()) { }
|
||||||
|
|
||||||
~TestTimer()
|
~TestTimer()
|
||||||
{
|
{
|
||||||
UnsignedWide stopTime;
|
PRTime stopTime = PR_Now();
|
||||||
Microseconds(&stopTime);
|
PRTime totalTime = stopTime - mStartTime;
|
||||||
UnsignedWide totalTime = stopTime - mStartTime;
|
cout << setw(10) << totalTime << " µs : ";
|
||||||
if ( totalTime.hi )
|
|
||||||
cout << "*";
|
|
||||||
cout << setw(10) << totalTime.lo << " µs : ";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UnsignedWide mStartTime;
|
PRTime mStartTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
static
|
static
|
||||||
|
@ -335,6 +330,11 @@ class Profiler
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Dump( const char* output_name )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Dump( const unsigned char* output_name )
|
Dump( const unsigned char* output_name )
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,399 @@
|
||||||
|
#include <iostream.h>
|
||||||
|
|
||||||
|
#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<char>(cout), PRUnichar_to_char());
|
||||||
|
return cout;
|
||||||
|
}
|
||||||
|
#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 NS_USE_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
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void
|
||||||
|
CallCMid( nsAWritableCString& aResult, const nsAReadableCString& aSource, PRUint32 aStartPos, PRUint32 aLengthToCopy )
|
||||||
|
{
|
||||||
|
aSource.Mid(aResult, aStartPos, aLengthToCopy);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class CharT>
|
||||||
|
int
|
||||||
|
test_multifragment_iterators( const basic_nsAReadableString<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_nsAReadableString<CharT>::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 <class CharT>
|
||||||
|
int
|
||||||
|
test_readable_hello( const basic_nsAReadableString<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_nsAReadableString<CharT>::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<CharT>::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<CharT>::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 <class CharT>
|
||||||
|
int
|
||||||
|
test_writable( basic_nsAWritableString<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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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<nsAReadableCString>(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;
|
||||||
|
}
|
Загрузка…
Ссылка в новой задаче