Merge pull request #801 from eightyeight/gtest-tests

Googletest tests
This commit is contained in:
LuisAntonRebollo 2014-10-02 01:31:13 +02:00
commit 535f56af6e
71 changed files with 3056 additions and 20158 deletions

View file

@ -0,0 +1,189 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2014 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifdef TORQUE_TESTS_ENABLED
#include "testing/unitTesting.h"
#include "core/util/journal/journaledSignal.h"
#include "core/util/safeDelete.h"
FIXTURE(Journal)
{
public:
// Used for basic API test.
struct receiver
{
U16 lastTriggerValue;
void trigger(U16 msg)
{
lastTriggerValue = msg;
}
};
// Used for non-basic test.
typedef JournaledSignal<void(U32, U16)> EventA;
typedef JournaledSignal<void(U8, S8)> EventB;
typedef JournaledSignal<void(U32, S32)> EventC;
// Root, non-dynamic signal receiver.
struct multiReceiver {
U32 recvA, recvB, recvC;
EventA *dynamicA;
EventB *dynamicB;
EventC *dynamicC;
void receiverRoot(U8 msg)
{
if(msg==1)
{
dynamicA = new EventA();
dynamicA->notify(this, &multiReceiver::receiverA);
}
if(msg==2)
{
dynamicB = new EventB();
dynamicB->notify(this, &multiReceiver::receiverB);
}
if(msg==3)
{
dynamicC = new EventC();
dynamicC->notify(this, &multiReceiver::receiverC);
}
}
void receiverA(U32, U16 d)
{
recvA += d;
}
void receiverB(U8, S8 d)
{
recvB += d;
}
void receiverC(U32, S32 d)
{
recvC += d;
}
};
};
TEST_FIX(Journal, BasicAPI)
{
receiver rec;
rec.lastTriggerValue = 0;
// Set up a journaled signal to test with.
JournaledSignal<void(U16)> testEvent;
testEvent.notify(&rec, &receiver::trigger);
// Initialize journal recording and fire off some events...
Journal::Record("test.jrn");
ASSERT_TRUE(Journal::IsRecording());
testEvent.trigger(16);
testEvent.trigger(17);
testEvent.trigger(18);
EXPECT_EQ(rec.lastTriggerValue, 18)
<< "Should encounter last triggered value (18).";
Journal::Stop();
ASSERT_FALSE(Journal::IsRecording());
// Clear it...
rec.lastTriggerValue = 0;
// and play back - should get same thing.
Journal::Play("test.jrn");
// Since we fired 3 events, it should take three loops.
EXPECT_TRUE(Journal::PlayNext()) << "Should be two more events.";
EXPECT_TRUE(Journal::PlayNext()) << "Should be one more event.";
EXPECT_FALSE(Journal::PlayNext()) << "Should be no more events.";
EXPECT_EQ(rec.lastTriggerValue, 18)
<< "Should encounter last journaled value (18).";
}
TEST_FIX(Journal, DynamicSignals)
{
multiReceiver rec;
// Reset our state values.
rec.recvA = rec.recvB = rec.recvC = 0;
// Set up a signal to start with.
JournaledSignal<void(U8)> testEvent;
testEvent.notify(&rec, &multiReceiver::receiverRoot);
// Initialize journal recording and fire off some events...
Journal::Record("test.jrn");
ASSERT_TRUE(Journal::IsRecording());
testEvent.trigger(1);
rec.dynamicA->trigger(8, 100);
testEvent.trigger(2);
rec.dynamicA->trigger(8, 8);
rec.dynamicB->trigger(9, 'a');
testEvent.trigger(3);
SAFE_DELETE(rec.dynamicB); // Test a deletion.
rec.dynamicC->trigger(8, 1);
rec.dynamicC->trigger(8, 1);
// Did we end up with expected values? Check before clearing.
EXPECT_EQ(rec.recvA, 108) << "recvA wasn't 108 - something broken in signals?";
EXPECT_EQ(rec.recvB, 'a') << "recvB wasn't 'a' - something broken in signals?";
EXPECT_EQ(rec.recvC, 2) << "recvC wasn't 2 - something broken in signals?";
// Reset our state values.
rec.recvA = rec.recvB = rec.recvC = 0;
// And kill the journal...
Journal::Stop();
// Also kill our remaining dynamic signals.
SAFE_DELETE(rec.dynamicA);
SAFE_DELETE(rec.dynamicB);
SAFE_DELETE(rec.dynamicC);
// Play back - should get same thing.
Journal::Play("test.jrn");
// Since we fired 8 events, it should take 7+1=8 loops.
for(S32 i = 0; i < 7; i++)
{
EXPECT_TRUE(Journal::PlayNext())
<< "Should be more events.";
}
EXPECT_FALSE(Journal::PlayNext())
<< "Should be no more events.";
EXPECT_EQ(rec.recvA, 108) << "recvA wasn't 108 - something broken in journal?";
EXPECT_EQ(rec.recvB, 'a') << "recvB wasn't 'a' - something broken in journal?";
EXPECT_EQ(rec.recvC, 2) << "recvC wasn't 2 - something broken in journal?";
}
#endif

View file

@ -1,5 +1,5 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
// Copyright (c) 2014 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
@ -20,39 +20,41 @@
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "unit/test.h"
#ifdef TORQUE_TESTS_ENABLED
#include "testing/unitTesting.h"
#include "core/util/journal/process.h"
#include "core/util/safeDelete.h"
using namespace UnitTesting;
CreateUnitTest(TestingProcess, "Journal/Process")
FIXTURE(Process)
{
// How many ticks remaining?
U32 _remainingTicks;
// Callback for process list.
void process()
public:
U32 remainingTicks;
void notification()
{
if(_remainingTicks==0)
if(remainingTicks == 0)
Process::requestShutdown();
_remainingTicks--;
remainingTicks--;
}
};
void run()
TEST_FIX(Process, BasicAPI)
{
// We'll run 30 ticks, then quit.
remainingTicks = 30;
// Register with the process list.
Process::notify(this, &ProcessFixture::notification);
// And do 30 notifies, making sure we end on the 30th.
for(S32 i = 0; i < 30; i++)
{
// We'll run 30 ticks, then quit.
_remainingTicks = 30;
// Register with the process list.
Process::notify(this, &TestingProcess::process);
// And do 30 notifies, making sure we end on the 30th.
for(S32 i=0; i<30; i++)
test(Process::processEvents(), "Should quit after 30 ProcessEvents() calls - not before!");
test(!Process::processEvents(), "Should quit after the 30th ProcessEvent() call!");
Process::remove(this, &TestingProcess::process);
EXPECT_TRUE(Process::processEvents())
<< "Should quit after 30 ProcessEvents() calls - not before!";
}
};
EXPECT_FALSE(Process::processEvents())
<< "Should quit after the 30th ProcessEvent() call!";
Process::remove(this, &ProcessFixture::notification);
};
#endif

View file

@ -1,185 +0,0 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "unit/test.h"
#include "core/util/journal/journaledSignal.h"
#include "core/util/safeDelete.h"
using namespace UnitTesting;
CreateUnitTest(TestsJournalRecordAndPlayback, "Journal/Basic")
{
U32 _lastTriggerValue;
void triggerReceiver(U16 msg)
{
_lastTriggerValue = msg;
}
void run()
{
// Reset the last trigger value just in case...
_lastTriggerValue = 0;
// Set up a journaled signal to test with.
JournaledSignal<void(U16)> testEvent;
testEvent.notify(this, &TestsJournalRecordAndPlayback::triggerReceiver);
// Initialize journal recording and fire off some events...
Journal::Record("test.jrn");
if( !Journal::IsRecording() )
{
test(false, "Fail");
return;
}
testEvent.trigger(16);
testEvent.trigger(17);
testEvent.trigger(18);
test(_lastTriggerValue == 18, "Should encounter last triggered value (18).");
Journal::Stop();
// Clear it...
_lastTriggerValue = 0;
// and play back - should get same thing.
Journal::Play("test.jrn");
// Since we fired 3 events, it should take three loops.
test(Journal::PlayNext(), "Should be two more events.");
test(Journal::PlayNext(), "Should be one more event.");
test(!Journal::PlayNext(), "Should be no more events.");
test(_lastTriggerValue == 18, "Should encounter last journaled value (18).");
}
};
CreateUnitTest(TestsJournalDynamicSignals, "Journal/DynamicSignals")
{
typedef JournaledSignal<void(U32, U16)> EventA;
typedef JournaledSignal<void(U8, S8)> EventB;
typedef JournaledSignal<void(U32, S32)> EventC;
EventA *dynamicA;
EventB *dynamicB;
EventC *dynamicC;
// Root, non-dynamic signal receiver.
void receiverRoot(U8 msg)
{
if(msg==1)
{
dynamicA = new EventA();
dynamicA->notify(this, &TestsJournalDynamicSignals::receiverA);
}
if(msg==2)
{
dynamicB = new EventB();
dynamicB->notify(this, &TestsJournalDynamicSignals::receiverB);
}
if(msg==3)
{
dynamicC = new EventC();
dynamicC->notify(this, &TestsJournalDynamicSignals::receiverC);
}
}
U32 recvA, recvB, recvC;
void receiverA(U32, U16 d)
{
recvA += d;
}
void receiverB(U8, S8 d)
{
recvB += d;
}
void receiverC(U32, S32 d)
{
recvC += d;
}
void run()
{
// Reset our state values.
recvA = recvB = recvC = 0;
// Set up a signal to start with.
JournaledSignal<void(U8)> testEvent;
testEvent.notify(this, &TestsJournalDynamicSignals::receiverRoot);
// Initialize journal recording and fire off some events...
Journal::Record("test.jrn");
if( !Journal::IsRecording() )
{
test(false, "Fail");
return;
}
testEvent.trigger(1);
dynamicA->trigger(8, 100);
testEvent.trigger(2);
dynamicA->trigger(8, 8);
dynamicB->trigger(9, 'a');
testEvent.trigger(3);
SAFE_DELETE(dynamicB); // Test a deletion.
dynamicC->trigger(8, 1);
dynamicC->trigger(8, 1);
// Did we end up with expected values? Check before clearing.
test(recvA == 108, "recvA wasn't 108 - something broken in signals?");
test(recvB == 'a', "recvB wasn't 'a' - something broken in signals?");
test(recvC == 2, "recvC wasn't 2 - something broken in signals?");
// Reset our state values.
recvA = recvB = recvC = 0;
// And kill the journal...
Journal::Stop();
// Also kill our remaining dynamic signals.
SAFE_DELETE(dynamicA);
SAFE_DELETE(dynamicB);
SAFE_DELETE(dynamicC);
// Play back - should get same thing.
Journal::Play("test.jrn");
// Since we fired 8 events, it should take 7+1=8 loops.
for(S32 i=0; i<7; i++)
test(Journal::PlayNext(), "Should be more events.");
test(!Journal::PlayNext(), "Should be no more events.");
test(recvA == 108, "recvA wasn't 108 - something broken in journal?");
test(recvB == 'a', "recvB wasn't 'a' - something broken in journal?");
test(recvC == 2, "recvC wasn't 2 - something broken in journal?");
}
};

View file

@ -0,0 +1,40 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2014 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifdef TORQUE_TESTS_ENABLED
#include "testing/unitTesting.h"
#include "core/util/path.h"
TEST(MakeRelativePath, MakeRelativePath)
{
EXPECT_EQ(Torque::Path::MakeRelativePath("art/interiors/burg/file.png", "art/interiors/"), "burg/file.png");
EXPECT_EQ(Torque::Path::MakeRelativePath("art/interiors/file.png", "art/interiors/burg/"), "../file.png");
EXPECT_EQ(Torque::Path::MakeRelativePath("art/file.png", "art/interiors/burg/"), "../../file.png");
EXPECT_EQ(Torque::Path::MakeRelativePath("file.png", "art/interiors/burg/"), "../../../file.png");
EXPECT_EQ(Torque::Path::MakeRelativePath("art/interiors/burg/file.png", "art/interiors/burg/"), "file.png");
EXPECT_EQ(Torque::Path::MakeRelativePath("art/interiors/camp/file.png", "art/interiors/burg/"), "../camp/file.png");
EXPECT_EQ(Torque::Path::MakeRelativePath("art/interiors/burg/file.png", "art/shapes/"), "../interiors/burg/file.png");
EXPECT_EQ(Torque::Path::MakeRelativePath("levels/den/file.png", "art/interiors/burg/"), "../../../levels/den/file.png");
EXPECT_EQ(Torque::Path::MakeRelativePath("art/interiors/burg/file.png", "art/dts/burg/"), "../../interiors/burg/file.png");
};
#endif

View file

@ -0,0 +1,332 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2014 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifdef TORQUE_TESTS_ENABLED
#include "testing/unitTesting.h"
#include "core/util/str.h"
#include "core/util/tVector.h"
#include "core/strings/stringFunctions.h"
#include "core/strings/unicode.h"
/// This is called Str, not String, because googletest doesn't let you use both
/// TEST(x) and TEST_FIX(x). So this fixture is called Str, to match the StrTest
/// struct, and the remaining fixture-les tests are named String.
FIXTURE(Str)
{
protected:
struct StrTest
{
const UTF8* mData;
const UTF16* mUTF16;
U32 mLength;
StrTest() : mData( 0 ), mUTF16( 0 ) {}
StrTest( const char* str )
: mData( str ), mLength( str ? dStrlen( str ) : 0 ), mUTF16( NULL )
{
if( str )
mUTF16 = convertUTF8toUTF16( mData );
}
~StrTest()
{
if( mUTF16 )
delete [] mUTF16;
}
};
Vector< StrTest* > mStrings;
virtual void SetUp()
{
mStrings.push_back( new StrTest( NULL ) );
mStrings.push_back( new StrTest( "" ) );
mStrings.push_back( new StrTest( "Torque" ) );
mStrings.push_back( new StrTest( "TGEA" ) );
mStrings.push_back( new StrTest( "GarageGames" ) );
mStrings.push_back( new StrTest( "TGB" ) );
mStrings.push_back( new StrTest( "games" ) );
mStrings.push_back( new StrTest( "engine" ) );
mStrings.push_back( new StrTest( "rocks" ) );
mStrings.push_back( new StrTest( "technology" ) );
mStrings.push_back( new StrTest( "Torque 3D" ) );
mStrings.push_back( new StrTest( "Torque 2D" ) );
}
virtual void TearDown()
{
for( U32 i = 0; i < mStrings.size(); ++ i )
delete mStrings[ i ];
mStrings.clear();
}
};
#define EACH_STRING(i) \
for( U32 i = 0; i < mStrings.size(); ++ i )
#define EACH_PAIR(i, j) \
for( U32 i = 0; i < mStrings.size(); ++ i ) \
for( U32 j = 0; j < mStrings.size(); ++ j )
TEST_FIX(Str, Test1)
{
EACH_STRING(i)
{
StrTest& data = *mStrings[i];
String str( data.mData );
String str16( data.mUTF16 );
EXPECT_TRUE( str.length() == data.mLength );
EXPECT_TRUE( str.size() == data.mLength + 1 );
EXPECT_TRUE( str.isEmpty() || str.length() > 0 );
EXPECT_TRUE( str.length() == str16.length() );
EXPECT_TRUE( str.size() == str16.size() );
EXPECT_TRUE( dMemcmp( str.utf16(), str16.utf16(), str.length() * sizeof( UTF16 ) ) == 0 );
EXPECT_TRUE( !data.mData || dMemcmp( str.utf16(), data.mUTF16, str.length() * sizeof( UTF16 ) ) == 0 );
EXPECT_TRUE( !data.mData || dMemcmp( str16.utf8(), data.mData, str.length() ) == 0 );
EXPECT_TRUE( !data.mData || dStrcmp( str.utf8(), data.mData ) == 0 );
EXPECT_TRUE( !data.mData || dStrcmp( str.utf16(), data.mUTF16 ) == 0 );
}
}
TEST_FIX(Str, Test2)
{
EACH_STRING(i)
{
StrTest& data = *mStrings[i];
String str( data.mData );
EXPECT_TRUE( str == str );
EXPECT_FALSE( str != str );
EXPECT_FALSE( str < str );
EXPECT_FALSE( str > str );
EXPECT_TRUE( str.equal( str ) );
EXPECT_TRUE( str.equal( str, String::NoCase ) );
}
}
TEST_FIX(Str, Test3)
{
EACH_PAIR(i, j)
{
StrTest& d1 = *mStrings[i];
StrTest& d2 = *mStrings[j];
if( &d1 != &d2 )
EXPECT_TRUE( String( d1.mData ) != String( d2.mData )
|| ( String( d1.mData ).isEmpty() && String( d2.mData ).isEmpty() ) );
else
EXPECT_TRUE( String( d1.mData ) == String( d2.mData ) );
}
}
TEST(String, Empty)
{
EXPECT_TRUE( String().length() == 0 );
EXPECT_TRUE( String( "" ).length() == 0 );
EXPECT_TRUE( String().size() == 1 );
EXPECT_TRUE( String( "" ).size() == 1 );
EXPECT_TRUE( String().isEmpty() );
EXPECT_TRUE( String( "" ).isEmpty() );
}
TEST(String, Trim)
{
EXPECT_TRUE( String( " Foobar Barfoo \n\t " ).trim() == String( "Foobar Barfoo" ) );
EXPECT_TRUE( String( "Foobar" ).trim() == String( "Foobar" ) );
EXPECT_TRUE( String( " " ).trim().isEmpty() );
}
TEST(String, Compare)
{
String str( "Foobar" );
EXPECT_TRUE( str.compare( "Foo", 3 ) == 0 );
EXPECT_TRUE( str.compare( "bar", 3, String::NoCase | String::Right ) == 0 );
EXPECT_TRUE( str.compare( "foo", 3, String::NoCase ) == 0 );
EXPECT_TRUE( str.compare( "BAR", 3, String::NoCase | String::Right ) == 0 );
EXPECT_TRUE( str.compare( "Foobar" ) == 0 );
EXPECT_TRUE( str.compare( "Foo" ) != 0 );
EXPECT_TRUE( str.compare( "foobar", 0, String::NoCase ) == 0 );
EXPECT_TRUE( str.compare( "FOOBAR", 0, String::NoCase ) == 0 );
EXPECT_TRUE( str.compare( "Foobar", 0, String::Right ) == 0 );
EXPECT_TRUE( str.compare( "foobar", 0, String::NoCase | String::Right ) == 0 );
}
TEST(String, Order)
{
Vector< String > strs;
strs.push_back( "a" );
strs.push_back( "a0" );
strs.push_back( "a1" );
strs.push_back( "a1a" );
strs.push_back( "a1b" );
strs.push_back( "a2" );
strs.push_back( "a10" );
strs.push_back( "a20" );
for( U32 i = 0; i < strs.size(); ++ i )
{
for( U32 j = 0; j < i; ++ j )
{
EXPECT_TRUE( strs[ j ] < strs[ i ] );
EXPECT_TRUE( strs[ i ] > strs[ j ] );
EXPECT_TRUE( !( strs[ j ] > strs[ i ] ) );
EXPECT_TRUE( !( strs[ i ] < strs[ i ] ) );
EXPECT_TRUE( strs[ j ] <= strs[ i ] );
EXPECT_TRUE( strs[ i ] >= strs[ j ] );
}
EXPECT_TRUE( !( strs[ i ] < strs[ i ] ) );
EXPECT_TRUE( !( strs[ i ] > strs[ i ] ) );
EXPECT_TRUE( strs[ i ] <= strs[ i ] );
EXPECT_TRUE( strs[ i ] >= strs[ i ] );
for( U32 j = i + 1; j < strs.size(); ++ j )
{
EXPECT_TRUE( strs[ j ] > strs[ i ] );
EXPECT_TRUE( strs[ i ] < strs[ j ] );
EXPECT_TRUE( !( strs[ j ] < strs[ i ] ) );
EXPECT_TRUE( !( strs[ i ] > strs[ j ] ) );
EXPECT_TRUE( strs[ j ] >= strs[ i ] );
EXPECT_TRUE( strs[ i ] <= strs[ j ] );
}
}
}
/// TODO
TEST(String, Find)
{
}
TEST(String, Insert)
{
// String.insert( Pos, Char )
EXPECT_TRUE( String( "aa" ).insert( 1, 'c' ) == String( "aca" ) );
// String.insert( Pos, String )
EXPECT_TRUE( String( "aa" ).insert( 1, "cc" ) == String( "acca" ) );
EXPECT_TRUE( String( "aa" ).insert( 1, String( "cc" ) ) == String( "acca" ) );
// String.insert( Pos, String, Len )
EXPECT_TRUE( String( "aa" ).insert( 1, "ccdddd", 2 ) == String( "acca" ) );
}
TEST(String, Erase)
{
EXPECT_TRUE( String( "abba" ).erase( 1, 2 ) == String( "aa" ) );
EXPECT_TRUE( String( "abba" ).erase( 0, 4 ).isEmpty() );
}
TEST(String, Replace)
{
// String.replace( Pos, Len, String )
EXPECT_TRUE( String( "abba" ).replace( 1, 2, "ccc" ) == String( "accca" ) );
EXPECT_TRUE( String( "abba" ).replace( 1, 2, String( "ccc" ) ) == String( "accca" ) );
EXPECT_TRUE( String( "abba" ).replace( 0, 4, "" ).isEmpty() );
EXPECT_TRUE( String( "abba" ).replace( 2, 2, "c" ) == String( "abc" ) );
// String.replace( Char, Char )
EXPECT_TRUE( String().replace( 'a', 'b' ).isEmpty() );
EXPECT_TRUE( String( "ababc" ).replace( 'a', 'b' ) == String( "bbbbc" ) );
EXPECT_TRUE( String( "ababc" ).replace( 'd', 'e' ) == String( "ababc" ) );
// String.replace( String, String )
EXPECT_TRUE( String().replace( "foo", "bar" ).isEmpty() );
EXPECT_TRUE( String( "foobarfoo" ).replace( "foo", "bar" ) == String( "barbarbar" ) );
EXPECT_TRUE( String( "foobar" ).replace( "xx", "yy" ) == String( "foobar" ) );
EXPECT_TRUE( String( "foofoofoo" ).replace( "foo", "" ).isEmpty() );
}
TEST(String, SubStr)
{
EXPECT_TRUE( String( "foobar" ).substr( 0, 3 ) == String( "foo" ) );
EXPECT_TRUE( String( "foobar" ).substr( 3 ) == String( "bar" ) );
EXPECT_TRUE( String( "foobar" ).substr( 2, 2 ) == String( "ob" ) );
EXPECT_TRUE( String( "foobar" ).substr( 2, 0 ).isEmpty() );
EXPECT_TRUE( String( "foobar" ).substr( 0, 6 ) == String( "foobar" ) );
}
TEST(String, ToString)
{
EXPECT_TRUE( String::ToString( U32( 1 ) ) == String( "1" ) );
EXPECT_TRUE( String::ToString( S32( -1 ) ) == String( "-1" ) );
EXPECT_TRUE( String::ToString( F32( 1.01 ) ) == String( "1.01" ) );
EXPECT_TRUE( String::ToString( "%s%i", "foo", 1 ) == String( "foo1" ) );
}
TEST(String, CaseConversion)
{
EXPECT_TRUE( String::ToLower( "foobar123." ) == String( "foobar123." ) );
EXPECT_TRUE( String::ToLower( "FOOBAR123." ) == String( "foobar123." ) );
EXPECT_TRUE( String::ToUpper( "barfoo123." ) == String( "BARFOO123." ) );
EXPECT_TRUE( String::ToUpper( "BARFOO123." ) == String( "BARFOO123." ) );
}
TEST(String, Concat)
{
EXPECT_TRUE( String( "foo" ) + String( "bar" ) == String( "foobar" ) );
EXPECT_TRUE( String() + String( "bar" ) == String( "bar" ) );
EXPECT_TRUE( String( "foo" ) + String() == String( "foo" ) );
EXPECT_TRUE( String() + String() == String() );
EXPECT_TRUE( String( "fo" ) + 'o' == String( "foo" ) );
EXPECT_TRUE( 'f' + String( "oo" ) == String( "foo" ) );
EXPECT_TRUE( String( "foo" ) + "bar" == String( "foobar" ) );
EXPECT_TRUE( "foo" + String( "bar" ) == String( "foobar" ) );
}
TEST(String, Hash)
{
EXPECT_TRUE( String( "foo" ).getHashCaseSensitive() == String( "foo" ).getHashCaseSensitive() );
EXPECT_TRUE( String( "foo" ).getHashCaseSensitive() != String( "bar" ).getHashCaseSensitive() );
EXPECT_TRUE( String( "foo" ).getHashCaseInsensitive() == String( "FOO" ).getHashCaseInsensitive() );
}
TEST(String, Intern)
{
EXPECT_TRUE( String( "foo" ).intern().isSame( String( "foo" ).intern() ) );
EXPECT_TRUE( !String( "foo" ).intern().isSame( String( "bar" ).intern() ) );
EXPECT_TRUE( !String( "foo" ).intern().isSame( String( "Foo" ).intern() ) );
EXPECT_TRUE( String( "foo" ).intern() == String( "foo" ).intern() );
EXPECT_TRUE( String( "foo" ).intern() != String( "bar" ).intern() );
EXPECT_TRUE( String( "foo" ).intern().isInterned() );
}
TEST(StringBuilder, StringBuilder)
{
StringBuilder str;
str.append( 'f' );
str.append( "oo" );
str.append( String( "ba" ) );
str.append( "rfajskfdj", 1 );
str.format( "%s", "barfoo" );
EXPECT_TRUE( str.end() == String( "foobarbarfoo" ) );
}
#endif

View file

@ -0,0 +1,129 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2014 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifdef TORQUE_TESTS_ENABLED
#include "platform/platform.h"
#include "testing/unitTesting.h"
#include "core/util/swizzle.h"
#include "math/mRandom.h"
class TestStruct
{
private:
static U32 smIdx;
U32 mIdx;
U32 mData;
public:
TestStruct( const S32 data = -1 ) : mData( data ), mIdx( smIdx++ ) {};
dsize_t Idx() const { return mIdx; }
U32 Data() const { return mData; }
void Data(U32 val) { mData = val; }
};
U32 TestStruct::smIdx = 0;
TEST(Swizzle, Swizzle)
{
//------------------------------------------------------------------------
// Debugger-Observable Functionality Tests
//------------------------------------------------------------------------
U8 simpleBuffer[] = { 0, 1, 2, 3 };
U8 simpleTest[] = { 0, 1, 2, 3 };
#define RESET_SIMPLE() dMemcpy( simpleTest, simpleBuffer, sizeof( simpleBuffer ) )
//------------------------------------------------------------------------
// No-switch test
dsize_t noSwzl4[] = { 0, 1, 2, 3 };
Swizzle<U8,4> noSwizzle4( noSwzl4 );
noSwizzle4.InPlace( simpleTest, sizeof( simpleTest ) );
EXPECT_EQ( dMemcmp( simpleTest, simpleBuffer, sizeof( simpleBuffer ) ), 0 )
<< "No-switch test failed!";
RESET_SIMPLE();
//------------------------------------------------------------------------
// No-brainer RGBA->BGRA test
dsize_t bgraSwzl[] = { 2, 1, 0, 3 };
Swizzle<U8,4> bgraSwizzle( bgraSwzl );
U8 bgraTest[] = { 2, 1, 0, 3 };
bgraSwizzle.InPlace( simpleTest, sizeof( simpleTest ) );
EXPECT_EQ( dMemcmp( simpleTest, bgraTest, sizeof( bgraTest ) ), 0 )
<< "U8 RGBA->BGRA test failed";
//------------------------------------------------------------------------
// Reverse test
bgraSwizzle.InPlace( simpleTest, sizeof( simpleTest ) );
EXPECT_EQ( dMemcmp( simpleTest, simpleBuffer, sizeof( simpleBuffer ) ), 0 )
<< "U8 RGBA->BGRA reverse test failed";
RESET_SIMPLE();
//------------------------------------------------------------------------
// Object support test
Swizzle<TestStruct,4> bgraObjSwizzle( bgraSwzl );
{
U32 objIdx[] = { 0, 1, 2, 3 };
FrameTemp<TestStruct> objTest( sizeof( objIdx ) / sizeof( U32 ) );
FrameTemp<U32> randData( sizeof( objIdx ) / sizeof( U32 ) );
bool same = true;
for( U32 i = 0; i < sizeof( objIdx ) / sizeof( U32 ); i++ )
{
// Make random data and assign it
randData[i] = gRandGen.randI();
objTest[i].Data( randData[i] );
// Continue object sanity check
same &= ( objTest[i].Idx() == objIdx[i] );
}
EXPECT_TRUE( same )
<< "Test object failed to be competent";
bgraObjSwizzle.InPlace( ~objTest, sizeof( TestStruct ) * ( sizeof( objIdx ) / sizeof( U32 ) ) );
same = true;
for( U32 i = 0; i < sizeof( objIdx ) / sizeof( U32 ); i++ )
same &= ( objTest[i].Idx() == bgraTest[i] ) && ( objTest[i].Data() == randData[ (U32)bgraTest[ i ] ] );
EXPECT_TRUE( same )
<< "Object RGBA->BGRA test failed.";
bgraObjSwizzle.InPlace( ~objTest, sizeof( TestStruct ) * ( sizeof( objIdx ) / sizeof( U32 ) ) );
same = true;
for( U32 i = 0; i < sizeof( objIdx ) / sizeof( U32 ); i++ )
same &= ( objTest[i].Idx() == objIdx[i] ) && ( objTest[i].Data() == randData[i] );
EXPECT_TRUE( same )
<< "Object RGBA->BGRA reverse test failed.";
}
};
#endif

View file

@ -1,5 +1,5 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
// Copyright (c) 2014 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
@ -20,35 +20,30 @@
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "unit/test.h"
#ifdef TORQUE_TESTS_ENABLED
#include "testing/unitTesting.h"
#include "core/util/tFixedSizeDeque.h"
using namespace UnitTesting;
#define TEST( x ) test( ( x ), "FAIL: " #x )
CreateUnitTest( TestFixedSizeDeque, "Util/FixedSizeDeque" )
TEST(FixedSizeDeque, FixedSizeDeque)
{
void run()
{
enum { DEQUE_SIZE = 3 };
FixedSizeDeque< U32 > deque( DEQUE_SIZE );
enum { DEQUE_SIZE = 3 };
FixedSizeDeque< U32 > deque( DEQUE_SIZE );
TEST( deque.capacity() == DEQUE_SIZE );
TEST( deque.size() == 0 );
EXPECT_EQ( deque.capacity(), DEQUE_SIZE );
EXPECT_EQ( deque.size(), 0 );
deque.pushFront( 1 );
TEST( deque.capacity() == ( DEQUE_SIZE - 1 ) );
TEST( deque.size() == 1 );
TEST( !deque.isEmpty() );
deque.pushFront( 1 );
EXPECT_EQ( deque.capacity(), ( DEQUE_SIZE - 1 ) );
EXPECT_EQ( deque.size(), 1 );
EXPECT_FALSE( deque.isEmpty() );
deque.pushBack( 2 );
TEST( deque.capacity() == ( DEQUE_SIZE - 2 ) );
TEST( deque.size() == 2 );
deque.pushBack( 2 );
EXPECT_EQ( deque.capacity(), ( DEQUE_SIZE - 2 ) );
EXPECT_EQ( deque.size(), 2 );
TEST( deque.popFront() == 1 );
TEST( deque.popFront() == 2 );
TEST( deque.isEmpty() );
}
EXPECT_EQ( deque.popFront(), 1 );
EXPECT_EQ( deque.popFront(), 2 );
EXPECT_TRUE( deque.isEmpty() );
};
#endif

View file

@ -0,0 +1,125 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2014 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifdef TORQUE_TESTS_ENABLED
#include "testing/unitTesting.h"
#include "core/util/tVector.h"
// Define some test data used below.
FIXTURE(Vector)
{
public:
struct Dtor
{
bool* ptr;
Dtor() {} // Needed for vector increment.
Dtor(bool* ptr): ptr(ptr) {}
~Dtor()
{
*ptr = true;
}
};
static const S32 ints[];
static const U32 length;
static S32 QSORT_CALLBACK sortInts(const S32* a, const S32* b)
{
S32 av = *a;
S32 bv = *b;
if (av < bv)
return -1;
else if (av > bv)
return 1;
else
return 0;
}
};
const S32 VectorFixture::ints[] = {0, 10, 2, 3, 14, 4, 12, 6, 16, 7, 8, 1, 11, 5, 13, 9, 15};
const U32 VectorFixture::length = sizeof(VectorFixture::ints) / sizeof(S32);
TEST_FIX(Vector, Allocation)
{
Vector<S32> *vector = new Vector<S32>;
for (S32 i = 0; i < 1000; i++)
vector->push_back(10000 + i);
// Erase the first element, 500 times.
for (S32 i = 0; i < 500; i++)
vector->erase(U32(0));
vector->compact();
EXPECT_EQ(vector->size(), 500) << "Vector was unexpectedly short!";
delete vector;
}
TEST_FIX(Vector, Deallocation)
{
bool dtorVals[10];
Vector<Dtor> v;
// Only add the first 9 entries; the last is populated below.
for (U32 i = 0; i < 9; i++)
v.push_back(Dtor(&dtorVals[i]));
// Fill the values array with false so we can test for destruction.
for (U32 i = 0; i < 10; i++)
dtorVals[i] = false;
v.decrement();
EXPECT_TRUE(dtorVals[8]) << "Vector::decrement failed to call destructor";
v.decrement(2);
EXPECT_TRUE(dtorVals[7]) << "Vector::decrement failed to call destructor";
EXPECT_TRUE(dtorVals[6]) << "Vector::decrement failed to call destructor";
v.pop_back();
EXPECT_TRUE(dtorVals[5]) << "Vector::pop_back failed to call destructor";
v.increment();
v.last() = Dtor(&dtorVals[9]);
v.clear();
// All elements should have been destructed.
for (U32 i = 0; i < 10; i++)
EXPECT_TRUE(dtorVals[i])
<< "Element " << i << "'s destructor was not called";
}
TEST_FIX(Vector, Sorting)
{
Vector<S32> v;
for(U32 i = 0; i < length; i++)
v.push_back(ints[i]);
v.sort(sortInts);
for(U32 i = 0; i < length - 1; i++)
EXPECT_TRUE(v[i] <= v[i + 1])
<< "Element " << i << " was not in sorted order";
}
#endif

View file

@ -1,44 +0,0 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "unit/test.h"
#include "core/util/path.h"
using namespace UnitTesting;
#define TEST( x ) test( ( x ), "FAIL: " #x )
CreateUnitTest(TestPathMakeRelativePath, "Core/Util/Path/MakeRelativePath")
{
void run()
{
TEST(Torque::Path::MakeRelativePath("art/interiors/burg/file.png", "art/interiors/") == "burg/file.png");
TEST(Torque::Path::MakeRelativePath("art/interiors/file.png", "art/interiors/burg/") == "../file.png");
TEST(Torque::Path::MakeRelativePath("art/file.png", "art/interiors/burg/") == "../../file.png");
TEST(Torque::Path::MakeRelativePath("file.png", "art/interiors/burg/") == "../../../file.png");
TEST(Torque::Path::MakeRelativePath("art/interiors/burg/file.png", "art/interiors/burg/") == "file.png");
TEST(Torque::Path::MakeRelativePath("art/interiors/camp/file.png", "art/interiors/burg/") == "../camp/file.png");
TEST(Torque::Path::MakeRelativePath("art/interiors/burg/file.png", "art/shapes/") == "../interiors/burg/file.png");
TEST(Torque::Path::MakeRelativePath("levels/den/file.png", "art/interiors/burg/") == "../../../levels/den/file.png");
TEST(Torque::Path::MakeRelativePath("art/interiors/burg/file.png", "art/dts/burg/") == "../../interiors/burg/file.png");
}
};

View file

@ -1,358 +0,0 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "unit/test.h"
#include "core/util/str.h"
#include "core/util/tVector.h"
#include "core/strings/stringFunctions.h"
#include "core/strings/unicode.h"
#ifndef TORQUE_SHIPPING
using namespace UnitTesting;
#define TEST( x ) test( ( x ), "FAIL: " #x )
#define XTEST( t, x ) t->test( ( x ), "FAIL: " #x )
CreateUnitTest( TestString, "Util/String" )
{
struct StrTest
{
const UTF8* mData;
const UTF16* mUTF16;
U32 mLength;
StrTest() : mData( 0 ), mUTF16( 0 ) {}
StrTest( const char* str )
: mData( str ), mLength( str ? dStrlen( str ) : 0 ), mUTF16( NULL )
{
if( str )
mUTF16 = convertUTF8toUTF16( mData );
}
~StrTest()
{
if( mUTF16 )
delete [] mUTF16;
}
};
Vector< StrTest* > mStrings;
template< class T >
void runTestOnStrings()
{
for( U32 i = 0; i < mStrings.size(); ++ i )
T::run( this, *mStrings[ i ] );
}
template< class T >
void runPairwiseTestOnStrings()
{
for( U32 i = 0; i < mStrings.size(); ++ i )
for( U32 j = 0; j < mStrings.size(); ++ j )
T::run( this, *mStrings[ i ], *mStrings[ j ] );
}
struct Test1
{
static void run( TestString* test, StrTest& data )
{
String str( data.mData );
String str16( data.mUTF16 );
XTEST( test, str.length() == data.mLength );
XTEST( test, str.size() == data.mLength + 1 );
XTEST( test, str.isEmpty() || str.length() > 0 );
XTEST( test, str.length() == str16.length() );
XTEST( test, str.size() == str16.size() );
XTEST( test, dMemcmp( str.utf16(), str16.utf16(), str.length() * sizeof( UTF16 ) ) == 0 );
XTEST( test, !data.mData || dMemcmp( str.utf16(), data.mUTF16, str.length() * sizeof( UTF16 ) ) == 0 );
XTEST( test, !data.mData || dMemcmp( str16.utf8(), data.mData, str.length() ) == 0 );
XTEST( test, !data.mData || dStrcmp( str.utf8(), data.mData ) == 0 );
XTEST( test, !data.mData || dStrcmp( str.utf16(), data.mUTF16 ) == 0 );
}
};
struct Test2
{
static void run( TestString* test, StrTest& data )
{
String str( data.mData );
XTEST( test, str == str );
XTEST( test, !( str != str ) );
XTEST( test, !( str < str ) );
XTEST( test, !( str > str ) );
XTEST( test, str.equal( str ) );
XTEST( test, str.equal( str, String::NoCase ) );
}
};
struct Test3
{
static void run( TestString* test, StrTest& d1, StrTest& d2 )
{
if( &d1 != &d2 )
XTEST( test, String( d1.mData ) != String( d2.mData )
|| ( String( d1.mData ).isEmpty() && String( d2.mData ).isEmpty() ) );
else
XTEST( test, String( d1.mData ) == String( d2.mData ) );
}
};
void testEmpty()
{
TEST( String().length() == 0 );
TEST( String( "" ).length() == 0 );
TEST( String().size() == 1 );
TEST( String( "" ).size() == 1 );
TEST( String().isEmpty() );
TEST( String( "" ).isEmpty() );
}
void testTrim()
{
TEST( String( " Foobar Barfoo \n\t " ).trim() == String( "Foobar Barfoo" ) );
TEST( String( "Foobar" ).trim() == String( "Foobar" ) );
TEST( String( " " ).trim().isEmpty() );
}
void testCompare()
{
String str( "Foobar" );
TEST( str.compare( "Foo", 3 ) == 0 );
TEST( str.compare( "bar", 3, String::NoCase | String::Right ) == 0 );
TEST( str.compare( "foo", 3, String::NoCase ) == 0 );
TEST( str.compare( "BAR", 3, String::NoCase | String::Right ) == 0 );
TEST( str.compare( "Foobar" ) == 0 );
TEST( str.compare( "Foo" ) != 0 );
TEST( str.compare( "foobar", 0, String::NoCase ) == 0 );
TEST( str.compare( "FOOBAR", 0, String::NoCase ) == 0 );
TEST( str.compare( "Foobar", 0, String::Right ) == 0 );
TEST( str.compare( "foobar", 0, String::NoCase | String::Right ) == 0 );
}
void testOrder()
{
Vector< String > strs;
strs.push_back( "a" );
strs.push_back( "a0" );
strs.push_back( "a1" );
strs.push_back( "a1a" );
strs.push_back( "a1b" );
strs.push_back( "a2" );
strs.push_back( "a10" );
strs.push_back( "a20" );
for( U32 i = 0; i < strs.size(); ++ i )
{
for( U32 j = 0; j < i; ++ j )
{
TEST( strs[ j ] < strs[ i ] );
TEST( strs[ i ] > strs[ j ] );
TEST( !( strs[ j ] > strs[ i ] ) );
TEST( !( strs[ i ] < strs[ i ] ) );
TEST( strs[ j ] <= strs[ i ] );
TEST( strs[ i ] >= strs[ j ] );
}
TEST( !( strs[ i ] < strs[ i ] ) );
TEST( !( strs[ i ] > strs[ i ] ) );
TEST( strs[ i ] <= strs[ i ] );
TEST( strs[ i ] >= strs[ i ] );
for( U32 j = i + 1; j < strs.size(); ++ j )
{
TEST( strs[ j ] > strs[ i ] );
TEST( strs[ i ] < strs[ j ] );
TEST( !( strs[ j ] < strs[ i ] ) );
TEST( !( strs[ i ] > strs[ j ] ) );
TEST( strs[ j ] >= strs[ i ] );
TEST( strs[ i ] <= strs[ j ] );
}
}
}
void testFind()
{
//TODO
}
void testInsert()
{
// String.insert( Pos, Char )
TEST( String( "aa" ).insert( 1, 'c' ) == String( "aca" ) );
// String.insert( Pos, String )
TEST( String( "aa" ).insert( 1, "cc" ) == String( "acca" ) );
TEST( String( "aa" ).insert( 1, String( "cc" ) ) == String( "acca" ) );
// String.insert( Pos, String, Len )
TEST( String( "aa" ).insert( 1, "ccdddd", 2 ) == String( "acca" ) );
}
void testErase()
{
TEST( String( "abba" ).erase( 1, 2 ) == String( "aa" ) );
TEST( String( "abba" ).erase( 0, 4 ).isEmpty() );
}
void testReplace()
{
// String.replace( Pos, Len, String )
TEST( String( "abba" ).replace( 1, 2, "ccc" ) == String( "accca" ) );
TEST( String( "abba" ).replace( 1, 2, String( "ccc" ) ) == String( "accca" ) );
TEST( String( "abba" ).replace( 0, 4, "" ).isEmpty() );
TEST( String( "abba" ).replace( 2, 2, "c" ) == String( "abc" ) );
// String.replace( Char, Char )
TEST( String().replace( 'a', 'b' ).isEmpty() );
TEST( String( "ababc" ).replace( 'a', 'b' ) == String( "bbbbc" ) );
TEST( String( "ababc" ).replace( 'd', 'e' ) == String( "ababc" ) );
// String.replace( String, String )
TEST( String().replace( "foo", "bar" ).isEmpty() );
TEST( String( "foobarfoo" ).replace( "foo", "bar" ) == String( "barbarbar" ) );
TEST( String( "foobar" ).replace( "xx", "yy" ) == String( "foobar" ) );
TEST( String( "foofoofoo" ).replace( "foo", "" ).isEmpty() );
}
void testSubstr()
{
TEST( String( "foobar" ).substr( 0, 3 ) == String( "foo" ) );
TEST( String( "foobar" ).substr( 3 ) == String( "bar" ) );
TEST( String( "foobar" ).substr( 2, 2 ) == String( "ob" ) );
TEST( String( "foobar" ).substr( 2, 0 ).isEmpty() );
TEST( String( "foobar" ).substr( 0, 6 ) == String( "foobar" ) );
}
void testToString()
{
TEST( String::ToString( U32( 1 ) ) == String( "1" ) );
TEST( String::ToString( S32( -1 ) ) == String( "-1" ) );
TEST( String::ToString( F32( 1.01 ) ) == String( "1.01" ) );
TEST( String::ToString( "%s%i", "foo", 1 ) == String( "foo1" ) );
}
void testCaseConversion()
{
TEST( String::ToLower( "foobar123." ) == String( "foobar123." ) );
TEST( String::ToLower( "FOOBAR123." ) == String( "foobar123." ) );
TEST( String::ToUpper( "barfoo123." ) == String( "BARFOO123." ) );
TEST( String::ToUpper( "BARFOO123." ) == String( "BARFOO123." ) );
}
void testConcat()
{
TEST( String( "foo" ) + String( "bar" ) == String( "foobar" ) );
TEST( String() + String( "bar" ) == String( "bar" ) );
TEST( String( "foo" ) + String() == String( "foo" ) );
TEST( String() + String() == String() );
TEST( String( "fo" ) + 'o' == String( "foo" ) );
TEST( 'f' + String( "oo" ) == String( "foo" ) );
TEST( String( "foo" ) + "bar" == String( "foobar" ) );
TEST( "foo" + String( "bar" ) == String( "foobar" ) );
}
void testHash()
{
TEST( String( "foo" ).getHashCaseSensitive() == String( "foo" ).getHashCaseSensitive() );
TEST( String( "foo" ).getHashCaseSensitive() != String( "bar" ).getHashCaseSensitive() );
TEST( String( "foo" ).getHashCaseInsensitive() == String( "FOO" ).getHashCaseInsensitive() );
}
void testIntern()
{
TEST( String( "foo" ).intern().isSame( String( "foo" ).intern() ) );
TEST( !String( "foo" ).intern().isSame( String( "bar" ).intern() ) );
TEST( !String( "foo" ).intern().isSame( String( "Foo" ).intern() ) );
TEST( String( "foo" ).intern() == String( "foo" ).intern() );
TEST( String( "foo" ).intern() != String( "bar" ).intern() );
TEST( String( "foo" ).intern().isInterned() );
}
void run()
{
mStrings.push_back( new StrTest( NULL ) );
mStrings.push_back( new StrTest( "" ) );
mStrings.push_back( new StrTest( "Torque" ) );
mStrings.push_back( new StrTest( "TGEA" ) );
mStrings.push_back( new StrTest( "GarageGames" ) );
mStrings.push_back( new StrTest( "TGB" ) );
mStrings.push_back( new StrTest( "games" ) );
mStrings.push_back( new StrTest( "engine" ) );
mStrings.push_back( new StrTest( "rocks" ) );
mStrings.push_back( new StrTest( "technology" ) );
mStrings.push_back( new StrTest( "Torque 3D" ) );
mStrings.push_back( new StrTest( "Torque 2D" ) );
runTestOnStrings< Test1 >();
runTestOnStrings< Test2 >();
runPairwiseTestOnStrings< Test3 >();
testEmpty();
testTrim();
testCompare();
testOrder();
testFind();
testInsert();
testReplace();
testErase();
testSubstr();
testToString();
testCaseConversion();
testConcat();
testHash();
testIntern();
for( U32 i = 0; i < mStrings.size(); ++ i )
delete mStrings[ i ];
mStrings.clear();
}
};
CreateUnitTest( TestStringBuilder, "Util/StringBuilder" )
{
void run()
{
StringBuilder str;
str.append( 'f' );
str.append( "oo" );
str.append( String( "ba" ) );
str.append( "rfajskfdj", 1 );
str.format( "%s", "barfoo" );
TEST( str.end() == String( "foobarbarfoo" ) );
}
};
#endif // !TORQUE_SHIPPING

View file

@ -1,138 +0,0 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "unit/test.h"
#include "console/console.h"
#include "core/util/tVector.h"
#ifndef TORQUE_SHIPPING
using namespace UnitTesting;
#define TEST( x ) test( ( x ), "FAIL: " #x )
#define XTEST( t, x ) t->test( ( x ), "FAIL: " #x )
CreateUnitTest( TestVector, "Util/Vector" )
{
bool dtorVals[ 10 ];
struct Dtor
{
bool* ptr;
Dtor() {}
Dtor( bool* ptr )
: ptr( ptr ) { *ptr = false; }
~Dtor()
{
*ptr = true;
}
};
void testDestruction()
{
Vector< Dtor > v;
for( U32 i = 0; i < 9; ++ i )
v.push_back( Dtor( &dtorVals[ i ] ) );
v.decrement();
v.decrement( 2 );
v.pop_back();
v.increment();
v.last() = Dtor( &dtorVals[ 9 ] );
v.clear();
TEST( dtorVals[ 0 ] );
TEST( dtorVals[ 1 ] );
TEST( dtorVals[ 2 ] );
TEST( dtorVals[ 3 ] );
TEST( dtorVals[ 4 ] );
TEST( dtorVals[ 5 ] );
TEST( dtorVals[ 6 ] );
TEST( dtorVals[ 7 ] );
TEST( dtorVals[ 8 ] );
TEST( dtorVals[ 9 ] );
}
static S32 QSORT_CALLBACK sortInts( const S32* a, const S32* b )
{
S32 av = *a;
S32 bv = *b;
if( av < bv )
return -1;
else if( av > bv )
return 1;
else
return 0;
}
void testSort()
{
Vector< S32 > v;
v.push_back( 0 );
v.push_back( 10 );
v.push_back( 2 );
v.push_back( 3 );
v.push_back( 14 );
v.push_back( 4 );
v.push_back( 12 );
v.push_back( 6 );
v.push_back( 16 );
v.push_back( 7 );
v.push_back( 8 );
v.push_back( 1 );
v.push_back( 11 );
v.push_back( 5 );
v.push_back( 13 );
v.push_back( 9 );
v.push_back( 15 );
v.sort( sortInts );
TEST( v[ 0 ] == 0 );
TEST( v[ 1 ] == 1 );
TEST( v[ 2 ] == 2 );
TEST( v[ 3 ] == 3 );
TEST( v[ 4 ] == 4 );
TEST( v[ 5 ] == 5 );
TEST( v[ 6 ] == 6 );
TEST( v[ 7 ] == 7 );
TEST( v[ 8 ] == 8 );
TEST( v[ 9 ] == 9 );
TEST( v[ 10 ] == 10 );
TEST( v[ 11 ] == 11 );
TEST( v[ 12 ] == 12 );
TEST( v[ 13 ] == 13 );
TEST( v[ 14 ] == 14 );
TEST( v[ 15 ] == 15 );
TEST( v[ 16 ] == 16 );
}
void run()
{
testSort();
testDestruction();
}
};
#endif

View file

@ -19,7 +19,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
/*
#include "core/crc.h"
#include "core/strings/stringFunctions.h"
#include "core/util/zip/zipArchive.h"
@ -194,3 +194,4 @@ private:
return ret;
}
};
*/

View file

@ -19,7 +19,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
/*
#include "platform/platform.h"
#include "unit/test.h"
@ -250,3 +250,4 @@ private:
return ret;
}
};
*/

View file

@ -19,7 +19,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
/*
#include "core/strings/stringFunctions.h"
#include "core/util/zip/zipArchive.h"
#include "core/util/zip/unitTests/zipTest.h"
@ -242,3 +242,4 @@ bail:
return ret;
}
};
*/