hl2_src-leak-2017/src/unittests/dmxtest/dmxtestserialization.cpp

761 lines
25 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Unit test program for DMX testing
//
// $NoKeywords: $
//=============================================================================//
#include "unitlib/unitlib.h"
#include "datamodel/dmelement.h"
#include "datamodel/idatamodel.h"
#include "tier1/utlbuffer.h"
#include "filesystem.h"
#include "datamodel/dmehandle.h"
#include "tier2/tier2.h"
bool AssertEqualElementHierarchies( bool quiet, DmElementHandle_t src1, DmElementHandle_t src2 );
bool AssertUnEqualElementHierarchies( DmElementHandle_t src1, DmElementHandle_t src2 )
{
bool equal = AssertEqualElementHierarchies( true, src1, src2 );
if ( equal )
{
AssertMsg( 0, "Hierarchies equal, expecting mismatch\n" );
}
return !equal;
}
void CreateTestScene( CUtlVector< DmElementHandle_t >& handles, DmFileId_t fileid )
{
DmObjectId_t id;
CreateUniqueId( &id );
VMatrix mat, mat2;
MatrixBuildRotateZ( mat, 45 );
MatrixBuildRotateZ( mat2, 30 );
int i;
unsigned char buf[256];
unsigned char buf2[256];
for ( i = 0; i < 256; ++i )
{
buf[i] = i;
buf2[i] = 255 - i;
}
CDmElement *pElement = CreateElement<CDmElement>( "root", fileid );
Assert( pElement );
CDmElement *pElement2 = CreateElement<CDmElement>( "shared_child", fileid );
Assert( pElement2 );
CDmElement *pElement3 = CreateElement<CDmElement>( "unique_child", fileid );
Assert( pElement3 );
CDmElement *pElement4 = CreateElement<CDmElement>( "shared_array_element", fileid );
Assert( pElement4 );
CDmElement *pElement5 = CreateElement<CDmElement>( "unique_array_element", fileid );
Assert( pElement5 );
CDmElement *pElement6 = CreateElement<CDmElement>( "shared_element", fileid );
Assert( pElement6 );
CDmElement *pElement7 = CreateElement<CDmElement>( "unique_element", fileid );
Assert( pElement7 );
g_pDataModel->SetFileRoot( fileid, pElement->GetHandle() );
handles.AddToTail( pElement->GetHandle() );
handles.AddToTail( pElement2->GetHandle() );
handles.AddToTail( pElement3->GetHandle() );
handles.AddToTail( pElement4->GetHandle() );
handles.AddToTail( pElement5->GetHandle() );
handles.AddToTail( pElement6->GetHandle() );
handles.AddToTail( pElement7->GetHandle() );
pElement->SetValue( "id_test", id );
pElement->SetValue( "bool_test", true );
pElement->SetValue( "int_test", 2 );
pElement->SetValue( "float_test", 3.0f );
pElement->SetValue( "color_test", Color( 0, 64, 128, 255 ) );
pElement->SetValue( "vector2d_test", Vector2D( 1.0f, -1.0f ) );
pElement->SetValue( "vector3d_test", Vector( 1.0f, -1.0f, 0.0f ) );
pElement->SetValue( "vector4d_test", Vector4D( 1.0f, -1.0f, 0.0f, 2.0f ) );
pElement->SetValue( "qangle_test", QAngle( 0.0f, 90.0f, -90.0f ) );
pElement->SetValue( "quat_test", Quaternion( 1.0f, -1.0f, 0.0f, 2.0f ) );
pElement->SetValue( "vmatrix_test", mat );
pElement->SetValue( "string_test", "test" );
pElement->SetValue( "binary_test", buf, 256 );
// Test DONTSAVE
// pElement->SetValue( "dontsave", true );
// CDmAttribute *pAttribute = pElement->GetAttribute( "dontsave" );
// pAttribute->AddFlag( FATTRIB_DONTSAVE );
CDmrArray< bool > boolVec( pElement2, "bool_array_test", true );
boolVec.AddToTail( false );
boolVec.AddToTail( true );
CDmrArray< int > intVec( pElement2, "int_array_test", true );
intVec.AddToTail( 0 );
intVec.AddToTail( 1 );
intVec.AddToTail( 2 );
CDmrArray< float > floatVec( pElement2, "float_array_test", true );
floatVec.AddToTail( -1.0f );
floatVec.AddToTail( 0.0f );
floatVec.AddToTail( 1.0f );
CDmrArray< Color > colorVec( pElement3, "color_array_test", true );
colorVec.AddToTail( Color( 0, 0, 0, 255 ) );
colorVec.AddToTail( Color( 64, 64, 64, 255 ) );
colorVec.AddToTail( Color( 128, 128, 128, 255 ) );
CDmrArray< Vector2D > vector2DVec( pElement3, "vector2d_array_test", true );
vector2DVec.AddToTail( Vector2D( -1.0f, -1.0f ) );
vector2DVec.AddToTail( Vector2D( 1.0f, 1.0f ) );
CDmrArray< Vector > vector3DVec( pElement3, "vector3d_array_test", true );
vector3DVec.AddToTail( Vector( 1.0f, -1.0f, 0.0f ) );
vector3DVec.AddToTail( Vector( 2.0f, -2.0f, 0.0f ) );
CDmrArray< Vector4D > vector4DVec( pElement4, "vector4d_array_test", true );
vector4DVec.AddToTail( Vector4D( 1.0f, -1.0f, 0.0f, 2.0f ) );
vector4DVec.AddToTail( Vector4D( 2.0f, -2.0f, 0.0f, 4.0f ) );
CDmrArray< QAngle > angleVec( pElement4, "qangle_array_test", true );
angleVec.AddToTail( QAngle( 1.0f, -1.0f, 0.0f ) );
angleVec.AddToTail( QAngle( 2.0f, -2.0f, 0.0f ) );
CDmrArray< Quaternion > quatVec( pElement4, "quat_array_test", true );
quatVec.AddToTail( Quaternion( 1.0f, -1.0f, 0.0f, 2.0f ) );
quatVec.AddToTail( Quaternion( 2.0f, -2.0f, 0.0f, 4.0f ) );
CDmrArray< VMatrix > matVec( pElement5, "vmatrix_array_test", true );
matVec.AddToTail( mat );
matVec.AddToTail( mat2 );
CDmrStringArray stringVec( pElement5, "string_array_test", true );
stringVec.AddToTail( "string1" );
stringVec.AddToTail( "string2" );
stringVec.AddToTail( "string3" );
CDmrArray< CUtlBinaryBlock > binaryVec( pElement5, "binary_array_test", true );
CUtlBinaryBlock block( (const void *)buf, 256 );
i = binaryVec.AddToTail( block );
CUtlBinaryBlock block2( (const void *)buf2, 256 );
i = binaryVec.AddToTail( block2);
CDmrArray< DmObjectId_t > idVec( pElement6, "elementid_array_test", true );
i = idVec.AddToTail( pElement6->GetId() );
i = idVec.AddToTail( pElement5->GetId() );
i = idVec.AddToTail( pElement4->GetId() );
CDmrElementArray< > elementVec( pElement6, "element_array_test", true );
elementVec.AddToTail( pElement4 );
elementVec.AddToTail( pElement5 );
CDmrElementArray< > elementVec2( pElement7, "element_array_test", true );
elementVec2.AddToTail( pElement2 );
elementVec2.AddToTail( pElement4 );
pElement->SetValue( "element_test", pElement7 );
pElement->SetValue( "shared_element_test", pElement6 );
CDmrElementArray<> children( pElement, "children", true );
children.InsertBefore( 0, pElement2 );
children.InsertBefore( 1, pElement3 );
pElement7->SetValue( "shared_element_test", pElement6 );
CDmrElementArray<> children2( pElement7, "children", true );
children2.InsertBefore( 0, pElement2 );
}
DmElementHandle_t CreateTestScene( DmFileId_t fileid )
{
CUtlVector< DmElementHandle_t > handles;
CreateTestScene( handles, fileid );
return handles[ 0 ];
}
DmElementHandle_t CreateKeyValuesTestScene( DmFileId_t fileid )
{
CDmElement *pElement = CreateElement<CDmElement>( "root", fileid );
Assert( pElement );
CDmElement *pElement2 = CreateElement<CDmElement>( "shared_child", fileid );
Assert( pElement2 );
CDmElement *pElement3 = CreateElement<CDmElement>( "unique_child", fileid );
Assert( pElement3 );
CDmElement *pElement4 = CreateElement<CDmElement>( "shared_array_element", fileid );
Assert( pElement4 );
CDmElement *pElement5 = CreateElement<CDmElement>( "unique_array_element", fileid );
Assert( pElement5 );
CDmElement *pElement6 = CreateElement<CDmElement>( "shared_element", fileid );
Assert( pElement6 );
CDmElement *pElement7 = CreateElement<CDmElement>( "unique_element", fileid );
Assert( pElement7 );
g_pDataModel->SetFileRoot( fileid, pElement->GetHandle() );
pElement->SetValue( "int_test", 2 );
pElement->SetValue( "float_test", 3.0f );
pElement->SetValue( "string_test", "test" );
CDmrElementArray<> eVec( pElement6, "element_array_test", true );
eVec.AddToTail( pElement4 );
eVec.AddToTail( pElement5 );
CDmrElementArray<> eVec2( pElement7, "element_array_test", true );
eVec2.AddToTail( pElement2 );
eVec2.AddToTail( pElement4 );
pElement->SetValue( "element_test", pElement7 );
pElement->SetValue( "shared_element_test", pElement6 );
CDmrElementArray<> children( pElement, "children", true );
children.InsertBefore( 0, pElement2 );
children.InsertBefore( 1, pElement3 );
pElement7->SetValue( "shared_element_test", pElement6 );
CDmrElementArray<> children2( pElement7, "children", true );
children2.InsertBefore( 0, pElement2 );
return pElement->GetHandle();
}
template< class T >
bool AssertEqualsTest( bool quiet, const T& src1, const T& src2 )
{
if ( !( src1 == src2 ))
{
if ( !quiet )
{
AssertMsg( 0, "Results not equal, expecting equal\n" );
}
return false;
}
return true;
}
template< class T >
bool AssertEqualsUtlVector( bool quiet, const CUtlVector<T> &src1, const CUtlVector<T> &src2 )
{
bool retval = true;
if ( src1.Count() != src2.Count() )
{
if ( !quiet )
{
AssertEqualsTest( quiet, src1.Count(), src2.Count() );
}
retval = false;
}
for ( int i = 0; i < src1.Count(); ++i )
{
if ( !src2.IsValidIndex( i ) )
continue;
if ( !( src1[i] == src2[i] ) )
{
if ( !quiet )
{
AssertEqualsTest( quiet, src1[i], src2[i] );
}
retval = false;
}
}
return retval;
}
template< class T >
bool AssertEqualsUtlVector( bool quiet, CDmAttribute *pAttribute1, CDmAttribute *pAttribute2 )
{
CDmrArray<T> src1( pAttribute1 );
CDmrArray<T> src2( pAttribute2 );
return AssertEqualsUtlVector( quiet, src1.Get(), src2.Get() );
}
bool AssertEqualAttributes( bool quiet, CDmAttribute *pAttribute1, CDmAttribute *pAttribute2 )
{
// Always follow ptrs to elements...
if ( pAttribute1->GetType() != AT_ELEMENT_ARRAY &&
pAttribute1->GetType() != AT_ELEMENT )
{
// Dirty flag checking here is to avoid infinite recursive loops
if ( !pAttribute1->IsFlagSet( FATTRIB_DIRTY ) && !pAttribute2->IsFlagSet( FATTRIB_DIRTY ) )
return true;
}
if ( !pAttribute1 )
{
if ( !quiet )
{
AssertMsg( 0, "AssertEqualAttributes: pAttribute1 is NULL\n" );
}
return false;
}
if ( !pAttribute2 )
{
if ( !quiet )
{
AssertMsg( 0, "AssertEqualAttributes: pAttribute2 is NULL\n" );
}
return false;
}
bool retval = true;
pAttribute1->RemoveFlag( FATTRIB_DIRTY );
pAttribute2->RemoveFlag( FATTRIB_DIRTY );
if ( pAttribute1->GetType() != pAttribute2->GetType() )
{
if ( !quiet )
{
AssertMsg( 0, "pAttribute1->GetType() == pAttribute2->GetType()" );
}
retval = false;
}
switch( pAttribute1->GetType() )
{
case AT_INT:
return AssertEqualsTest( quiet, pAttribute1->GetValue<int>( ), pAttribute2->GetValue<int>( ) );
case AT_FLOAT:
return AssertEqualsTest( quiet, pAttribute1->GetValue<float>( ), pAttribute2->GetValue<float>( ) );
case AT_BOOL:
return AssertEqualsTest( quiet, pAttribute1->GetValue<bool>( ), pAttribute2->GetValue<bool>( ) );
case AT_STRING:
return AssertEqualsTest( quiet, pAttribute1->GetValue<CUtlString>( ), pAttribute2->GetValue<CUtlString>( ) );
case AT_VOID:
return AssertEqualsTest( quiet, pAttribute1->GetValue<CUtlBinaryBlock>( ), pAttribute2->GetValue<CUtlBinaryBlock>( ) );
case AT_OBJECTID:
return true; // skip this for now - two elements can't have the same id, and CreateTestScene currently creates random test_id's each time...
/*
{
if ( !g_pDataModel->IsEqual( pAttribute1->GetValue<DmObjectId_t>( ), pAttribute2->GetValue<DmObjectId_t>( ) ) )
{
if ( !quiet )
{
Assert( g_pDataModel->IsEqual( pAttribute1->GetValue<DmObjectId_t>( ), pAttribute2->GetValue<DmObjectId_t>( ) ) );
}
return false;
}
return true;
}
break;
*/
case AT_COLOR:
return AssertEqualsTest( quiet, pAttribute1->GetValue<Color>( ), pAttribute2->GetValue<Color>( ) );
case AT_VECTOR2:
return AssertEqualsTest( quiet, pAttribute1->GetValue<Vector2D>( ), pAttribute2->GetValue<Vector2D>( ) );
case AT_VECTOR3:
return AssertEqualsTest( quiet, pAttribute1->GetValue<Vector>( ), pAttribute2->GetValue<Vector>( ) );
case AT_VECTOR4:
return AssertEqualsTest( quiet, pAttribute1->GetValue<Vector4D>( ), pAttribute2->GetValue<Vector4D>( ) );
case AT_QANGLE:
return AssertEqualsTest( quiet, pAttribute1->GetValue<QAngle>( ), pAttribute2->GetValue<QAngle>( ) );
case AT_QUATERNION:
return AssertEqualsTest( quiet, pAttribute1->GetValue<Quaternion>( ), pAttribute2->GetValue<Quaternion>( ) );
case AT_VMATRIX:
return AssertEqualsTest( quiet, pAttribute1->GetValue<VMatrix>( ), pAttribute2->GetValue<VMatrix>( ) );
case AT_ELEMENT:
return AssertEqualElementHierarchies( quiet, pAttribute1->GetValue<DmElementHandle_t>( ), pAttribute2->GetValue<DmElementHandle_t>( ) );
case AT_ELEMENT_ARRAY:
{
const CDmrElementArray< CDmElement > src1( pAttribute1 );
const CDmrElementArray< CDmElement > src2( pAttribute2 );
bool differs = !AssertEqualsTest( quiet, src1.Count(), src2.Count() );
bool differs2 = false;
for ( int i = 0; i < src1.Count(); ++i )
{
differs2 |= !AssertEqualElementHierarchies( quiet, src1[ i ]->GetHandle(), src2[ i ]->GetHandle() );
}
return ( !differs && !differs2 );
}
break;
case AT_INT_ARRAY:
return AssertEqualsUtlVector<int>( quiet, pAttribute1, pAttribute2 );
case AT_FLOAT_ARRAY:
return AssertEqualsUtlVector<float>( quiet, pAttribute1, pAttribute2 );
case AT_BOOL_ARRAY:
return AssertEqualsUtlVector<bool>( quiet, pAttribute1, pAttribute2 );
case AT_STRING_ARRAY:
return AssertEqualsUtlVector<CUtlString>( quiet, pAttribute1, pAttribute2 );
case AT_VOID_ARRAY:
return AssertEqualsUtlVector<CUtlBinaryBlock>( quiet, pAttribute1, pAttribute2 );
case AT_OBJECTID_ARRAY:
{
const CDmrArray<DmObjectId_t> src1( pAttribute1 );
const CDmrArray<DmObjectId_t> src2( pAttribute2 );
bool differs = AssertEqualsTest( quiet, src1.Count(), src2.Count() );
return differs; // skip this for now - CreateTestScene currently creates random ids each time...
/*
bool differs2 = false;
for ( int i = 0; i < src1.Count(); ++i )
{
if ( !g_pDataModel->IsEqual( src1[i], src2[i] ) )
{
differs2 = true;
if ( !quiet )
{
Assert( g_pDataModel->IsEqual( src1[i], src2[i] ) );
}
}
}
return ( !differs && !differs2 );
*/
}
break;
case AT_COLOR_ARRAY:
return AssertEqualsUtlVector<Color>( quiet, pAttribute1, pAttribute2 );
case AT_VECTOR2_ARRAY:
return AssertEqualsUtlVector<Vector2D>( quiet, pAttribute1, pAttribute2 );
case AT_VECTOR3_ARRAY:
return AssertEqualsUtlVector<Vector>( quiet, pAttribute1, pAttribute2 );
case AT_VECTOR4_ARRAY:
return AssertEqualsUtlVector<Vector4D>( quiet, pAttribute1, pAttribute2 );
case AT_QANGLE_ARRAY:
return AssertEqualsUtlVector<QAngle>( quiet, pAttribute1, pAttribute2 );
case AT_QUATERNION_ARRAY:
return AssertEqualsUtlVector<Quaternion>( quiet, pAttribute1, pAttribute2 );
case AT_VMATRIX_ARRAY:
return AssertEqualsUtlVector<VMatrix>( quiet, pAttribute1, pAttribute2 );
}
return retval;
}
bool AssertEqualElementHierarchies( bool quiet, DmElementHandle_t src1, DmElementHandle_t src2 )
{
CDmElement *pSrc1 = g_pDataModel->GetElement( src1 );
CDmElement *pSrc2 = g_pDataModel->GetElement( src2 );
if ( !pSrc1 || !pSrc2 )
return false;
// Assume equality
bool retval = true;
if ( pSrc1->GetType() != pSrc2->GetType() )
{
if ( !quiet )
{
AssertMsg( 0, "pSrc1->GetType() == pSrc2->GetType()" );
}
retval = false;
}
if ( Q_strcmp( pSrc1->GetName(), pSrc2->GetName() ) )
{
if ( !quiet )
{
AssertMsg2( 0, "Q_strcmp( %s, %s )", pSrc1->GetName(), pSrc2->GetName() );
}
retval = false;
}
if ( pSrc1->AttributeCount() != pSrc2->AttributeCount() )
{
if ( !quiet )
{
AssertMsg( 0, "pSrc1->NumAttributes() == pSrc2->NumAttributes()" );
}
retval = false;
}
for ( CDmAttribute *pAttribute1 = pSrc1->FirstAttribute(); pAttribute1; pAttribute1 = pAttribute1->NextAttribute() )
{
const char *pName = pAttribute1->GetName();
if ( !pSrc2->HasAttribute( pName ) )
{
if ( !quiet )
{
AssertMsg1( 0, "pSrc2->HasAttribute( %s ) failed\n", pName );
}
retval = false;
}
else
{
CDmAttribute *pAttribute2 = pSrc2->GetAttribute( pName );
bool differs = !AssertEqualAttributes( quiet, pAttribute1, pAttribute2 );
if ( differs )
{
retval = false;
}
}
}
return retval;
}
void TestDeleteOldCR( const char *pSerializationType )
{
DmFileId_t testFileID = g_pDataModel->FindOrCreateFileId( "<TestDeleteOldCR>" );
DmElementHandle_t hRoot = CreateTestScene( testFileID );
int nTestElements = g_pDataModel->NumElementsInFile( testFileID );
const char *pFileName = "DeleteOld.dmx";
CDmElement *pRoot = static_cast< CDmElement* >( g_pDataModel->GetElement( hRoot ) );
bool bOk = g_pDataModel->SaveToFile( pFileName, NULL, pSerializationType, "dmx", pRoot );
Shipping_Assert( bOk );
CDmElement *pReadInRoot = NULL;
DmFileId_t readFileID = g_pDataModel->RestoreFromFile( pFileName, NULL, NULL, &pReadInRoot, CR_DELETE_OLD );
Shipping_Assert( readFileID != DMFILEID_INVALID );
if ( pReadInRoot )
{
Shipping_Assert( pReadInRoot->GetHandle() == hRoot );
Shipping_Assert( g_pDataModel->GetElement( hRoot ) == pReadInRoot );
Shipping_Assert( g_pDataModel->NumElementsInFile( testFileID ) == 0 );
Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == nTestElements );
CDmeHandle< CDmElement > rootHandle( hRoot ); // keeps a reference to root around, even after the file is unloaded
g_pDataModel->UnloadFile( readFileID );
Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == 0 );
Shipping_Assert( g_pDataModel->GetElement( hRoot ) == NULL );
DmFileId_t readFileID2 = g_pDataModel->RestoreFromFile( pFileName, NULL, NULL, &pReadInRoot, CR_DELETE_OLD );
Shipping_Assert( readFileID2 == readFileID );
Shipping_Assert( pReadInRoot->GetHandle() == hRoot );
Shipping_Assert( g_pDataModel->GetElement( hRoot ) == pReadInRoot );
Shipping_Assert( g_pDataModel->NumElementsInFile( testFileID ) == 0 );
Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == nTestElements );
g_pDataModel->RemoveFileId( readFileID );
}
else
{
Msg( "Failed to load %s back from disk!!!", pFileName );
}
g_pDataModel->RemoveFileId( testFileID );
}
void TestDeleteNewCR( const char *pSerializationType )
{
DmFileId_t testFileID = g_pDataModel->FindOrCreateFileId( "<TestDeleteNewCR>" );
DmElementHandle_t hRoot = CreateTestScene( testFileID );
int nTestElements = g_pDataModel->NumElementsInFile( testFileID );
const char *pFileName = "DeleteNew.dmx";
CDmElement *pRoot = static_cast< CDmElement* >( g_pDataModel->GetElement( hRoot ) );
bool bOk = g_pDataModel->SaveToFile( pFileName, NULL, pSerializationType, "dmx", pRoot );
Shipping_Assert( bOk );
CDmElement *pReadInRoot = NULL;
DmFileId_t readFileID = g_pDataModel->RestoreFromFile( pFileName, NULL, NULL, &pReadInRoot, CR_DELETE_NEW );
Shipping_Assert( readFileID != DMFILEID_INVALID );
Shipping_Assert( g_pDataModel->GetElement( hRoot ) == pRoot );
Shipping_Assert( pRoot->GetHandle() == hRoot );
Shipping_Assert( pReadInRoot == pRoot ); // RestoreFromFile now returns the old element when the new root is deleted
Shipping_Assert( g_pDataModel->NumElementsInFile( testFileID ) == nTestElements );
Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == 0 );
g_pDataModel->UnloadFile( readFileID );
Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == 0 );
DmFileId_t readFileID2 = g_pDataModel->RestoreFromFile( pFileName, NULL, NULL, &pReadInRoot, CR_DELETE_NEW );
Shipping_Assert( readFileID2 == readFileID );
Shipping_Assert( g_pDataModel->GetElement( hRoot ) == pRoot );
Shipping_Assert( pRoot->GetHandle() == hRoot );
Shipping_Assert( pReadInRoot == pRoot ); // RestoreFromFile now returns the old element when the new root is deleted
Shipping_Assert( g_pDataModel->NumElementsInFile( testFileID ) == nTestElements );
Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == 0 );
g_pDataModel->RemoveFileId( readFileID );
g_pDataModel->RemoveFileId( testFileID );
}
void TestCopyNewCR( const char *pSerializationType )
{
DmFileId_t testFileID = g_pDataModel->FindOrCreateFileId( "<TestCopyNewCR>" );
DmElementHandle_t hRoot = CreateTestScene( testFileID );
int nTestElements = g_pDataModel->NumElementsInFile( testFileID );
const char *pFileName = "CopyNew.dmx";
CDmElement *pRoot = g_pDataModel->GetElement( hRoot );
bool bOk = g_pDataModel->SaveToFile( pFileName, NULL, pSerializationType, "dmx", pRoot );
Shipping_Assert( bOk );
CDmElement *pReadInRoot = NULL;
DmFileId_t readFileID = g_pDataModel->RestoreFromFile( pFileName, NULL, NULL, &pReadInRoot, CR_COPY_NEW );
Shipping_Assert( readFileID != DMFILEID_INVALID );
if ( pReadInRoot )
{
DmElementHandle_t hReadInRoot = pReadInRoot->GetHandle();
Shipping_Assert( g_pDataModel->GetElement( hRoot ) == pRoot );
Shipping_Assert( pRoot->GetHandle() == hRoot );
Shipping_Assert( pReadInRoot->GetHandle() != hRoot );
Shipping_Assert( !IsUniqueIdEqual( pRoot->GetId(), pReadInRoot->GetId() ) );
Shipping_Assert( g_pDataModel->NumElementsInFile( testFileID ) == nTestElements );
Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == nTestElements );
g_pDataModel->UnloadFile( readFileID );
Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == 0 );
Shipping_Assert( g_pDataModel->GetElement( hReadInRoot ) == NULL );
DmFileId_t readFileID2 = g_pDataModel->RestoreFromFile( pFileName, NULL, NULL, &pReadInRoot, CR_COPY_NEW );
Shipping_Assert( readFileID2 == readFileID );
Shipping_Assert( g_pDataModel->GetElement( hRoot ) == pRoot );
Shipping_Assert( pRoot->GetHandle() == hRoot );
Shipping_Assert( pReadInRoot->GetHandle() != hRoot );
Shipping_Assert( !IsUniqueIdEqual( pRoot->GetId(), pReadInRoot->GetId() ) );
Shipping_Assert( g_pDataModel->NumElementsInFile( testFileID ) == nTestElements );
Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == nTestElements );
g_pDataModel->RemoveFileId( readFileID );
}
else
{
Msg( "Failed to load %s back from disk!!!", pFileName );
}
g_pDataModel->RemoveFileId( testFileID );
}
void TestForceCopyCR( const char *pSerializationType )
{
DmFileId_t testFileID = g_pDataModel->FindOrCreateFileId( "<TestForceCopyCR>" );
DmElementHandle_t hRoot = CreateTestScene( testFileID );
int nTestElements = g_pDataModel->NumElementsInFile( testFileID );
const char *pFileName = "ForceCopy.dmx";
CDmElement *pRoot = static_cast< CDmElement* >( g_pDataModel->GetElement( hRoot ) );
bool bOk = g_pDataModel->SaveToFile( pFileName, NULL, pSerializationType, "dmx", pRoot );
Shipping_Assert( bOk );
CDmElement *pReadInRoot = NULL;
DmFileId_t readFileID = g_pDataModel->RestoreFromFile( pFileName, NULL, NULL, &pReadInRoot, CR_FORCE_COPY );
Shipping_Assert( readFileID != DMFILEID_INVALID );
if ( pReadInRoot )
{
DmElementHandle_t hReadInRoot = pReadInRoot->GetHandle();
Shipping_Assert( g_pDataModel->GetElement( hRoot ) == pRoot );
Shipping_Assert( pRoot->GetHandle() == hRoot );
Shipping_Assert( pReadInRoot->GetHandle() != hRoot );
Shipping_Assert( !IsUniqueIdEqual( pRoot->GetId(), pReadInRoot->GetId() ) );
Shipping_Assert( g_pDataModel->NumElementsInFile( testFileID ) == nTestElements );
Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == nTestElements );
g_pDataModel->UnloadFile( readFileID );
Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == 0 );
Shipping_Assert( g_pDataModel->GetElement( hReadInRoot ) == NULL );
DmFileId_t readFileID2 = g_pDataModel->RestoreFromFile( pFileName, NULL, NULL, &pReadInRoot, CR_FORCE_COPY );
Shipping_Assert( readFileID2 == readFileID );
Shipping_Assert( g_pDataModel->GetElement( hRoot ) == pRoot );
Shipping_Assert( pRoot->GetHandle() == hRoot );
Shipping_Assert( pReadInRoot->GetHandle() != hRoot );
Shipping_Assert( !IsUniqueIdEqual( pRoot->GetId(), pReadInRoot->GetId() ) );
Shipping_Assert( g_pDataModel->NumElementsInFile( testFileID ) == nTestElements );
Shipping_Assert( g_pDataModel->NumElementsInFile( readFileID ) == nTestElements );
g_pDataModel->RemoveFileId( readFileID );
}
else
{
Msg( "Failed to load %s back from disk!!!", pFileName );
}
g_pDataModel->RemoveFileId( testFileID );
}
void TestConflictResolution( const char *pSerializationType )
{
TestDeleteOldCR( pSerializationType );
TestDeleteNewCR( pSerializationType );
TestCopyNewCR( pSerializationType );
TestForceCopyCR( pSerializationType );
}
void TestSerializationMethod( const char *pSerializationType )
{
DmFileId_t testFileID = g_pDataModel->FindOrCreateFileId( "<CreateTestScene>" );
DmElementHandle_t hRoot = CreateTestScene( testFileID );
const char *pFileName = "dmxtest.dmx";
CDmElement *pRoot = static_cast<CDmElement*>(g_pDataModel->GetElement(hRoot));
bool bOk = g_pDataModel->SaveToFile( pFileName, NULL, pSerializationType, "dmx", pRoot );
Shipping_Assert( bOk );
CDmElement *pReadInRoot = NULL;
DmFileId_t dmxFileID = g_pDataModel->RestoreFromFile( pFileName, NULL, NULL, &pReadInRoot, CR_FORCE_COPY );
Shipping_Assert( dmxFileID != DMFILEID_INVALID );
if ( pReadInRoot )
{
AssertEqualElementHierarchies( false, hRoot, pReadInRoot->GetHandle() );
g_pDataModel->RemoveFileId( dmxFileID );
}
else
{
Msg( "Failed to load dmxtest.dmx back from disk!!!" );
}
g_pDataModel->RemoveFileId( testFileID );
TestConflictResolution( pSerializationType );
}
DEFINE_TESTCASE_NOSUITE( DmxSerializationTest )
{
Msg( "Running dmx serialization tests...\n" );
CDisableUndoScopeGuard sg;
TestSerializationMethod( "keyvalues2" );
TestSerializationMethod( "keyvalues2_flat" );
TestSerializationMethod( "xml" );
TestSerializationMethod( "xml_flat" );
TestSerializationMethod( "binary" );
int nEndingCount = g_pDataModel->GetAllocatedElementCount();
AssertEqualsTest( false, 0, nEndingCount );
}