windows-nt/Source/XPSP1/NT/com/oleutest/cachetst/enum.cpp
2020-09-26 16:20:57 +08:00

319 lines
6.7 KiB
C++

//+----------------------------------------------------------------------------
//
// File:
// enum.cpp
//
// Contents:
// Enumerator test methods for the cache unit test
//
// History:
//
// 04-Sep-94 davepl Created
//
//-----------------------------------------------------------------------------
#include "headers.hxx"
#pragma hdrstop
//+----------------------------------------------------------------------------
//
// Member: TestInstance::EnumeratorTest
//
// Synopsis: Performs various tests on the cache enumerator
//
// Arguments: (void)
//
// Returns: HRESULT
//
// Notes: General sequence of events is as follows:
//
// - Add cache nodes for EMF, DIB (and BMP) and MF
// - Try to add BMP node (expecting failure)
// - Create a cache enumerator
// - Run generic enumerator tests on that cache enumerator
// - Reset the enumerator
// - Grab the 4 nodes added above in a single Next()
// - Verify that the correct 4 nodes were returned
// - Reset the enumerator
// - Uncache the MF node
// - Grab the 3 remaining nodes
// - Verify that the correct 3 nodes were returned
// - Reset the enumerator
// - Skip 1 node
// - Uncache the DIB (and BMP) node
// - Try to uncache the BMP node (expecting failure)
// - Try to skip (expecting failure, as BMP node has disappeared midflight)
// - Uncache the EMF node (cache should now be empty)
// - Reset and Skip (expecting failure to verify the cache is empty)
// - Release the enumerator
//
// History: 23-Aug-94 Davepl Created
//
//-----------------------------------------------------------------------------
HRESULT TestInstance::EnumeratorTest()
{
HRESULT hr;
DWORD dwEMFCon, dwBMPCon, dwDIBCon, dwMFCon;
TraceLog Log(this, "TestInstance::EnumeratorTest", GS_CACHE, VB_MINIMAL);
Log.OnEntry ();
Log.OnExit (" ( %X )\n", &hr);
SetCurrentState(TESTING_ENUMERATOR);
//
// Cache DIB, MF, EMF, and BITMAP nodes
//
hr = AddEMFCacheNode(&dwEMFCon);
if (S_OK == hr)
{
hr = AddDIBCacheNode(&dwDIBCon);
}
if (S_OK == hr)
{
hr = AddMFCacheNode(&dwMFCon);
}
if (S_OK == hr)
{
hr = AddBITMAPCacheNode(&dwBMPCon);
//
// We expect that caching a Bitmap node when a DIB node has
// already been cached should return CACHE_S_SAMECACHE, so
// we transform that into S_OK
//
if (CACHE_S_SAMECACHE == hr)
{
hr = S_OK;
}
}
//
// Get an enumerator on the cache
//
LPENUMSTATDATA pEsd;
if (S_OK == hr)
{
hr = m_pOleCache->EnumCache(&pEsd);
}
//
// Perform generic emnumerator testing
//
if (S_OK == hr)
{
hr = TestEnumerator((void *) pEsd, sizeof(STATDATA), 4, NULL, NULL,NULL);
}
//
// Reset the enumerator before our specific tests
//
if (S_OK == hr)
{
hr = pEsd->Reset();
}
ULONG cFetched; // Count of elements enumd
STATDATA rgStat[4]; // Array of STATDATA to enum into
//
// Get an enumeration of the expected 4 nodes, then check to
// ensure that all four match (at a basic level) the four
// we expect to find
//
if (S_OK == hr)
{
hr = pEsd->Next(4, rgStat, &cFetched);
}
STATDATA sdEMF, sdMF, sdBMP, sdDIB;
// These are the STATDATAs we expect to find
sdEMF.formatetc.cfFormat = CF_ENHMETAFILE;
sdEMF.dwConnection = dwEMFCon;
sdMF.formatetc.cfFormat = CF_METAFILEPICT;
sdMF.dwConnection = dwMFCon;
sdDIB.formatetc.cfFormat = CF_BITMAP;
sdDIB.dwConnection = dwBMPCon;
sdBMP.formatetc.cfFormat = CF_DIB;
sdBMP.dwConnection = dwBMPCon;
//
// Verify that each of our STATDATAs came back
// from the enumeration
//
if (S_OK == hr)
{
if (S_FALSE == EltIsInArray(sdDIB, rgStat, 4))
{
hr = E_FAIL;
}
else if (S_FALSE == EltIsInArray(sdBMP, rgStat, 4))
{
hr = E_FAIL;
}
else if (S_FALSE == EltIsInArray(sdEMF, rgStat, 4))
{
hr = E_FAIL;
}
else if (S_FALSE == EltIsInArray(sdMF, rgStat, 4))
{
hr = E_FAIL;
}
}
//
// Reset the enumerator
//
if (S_OK == hr)
{
hr = pEsd->Reset();
}
//
// Remove the EMF node, leaving only MF, DIB and Bitmap
//
if (S_OK == hr)
{
hr = m_pOleCache->Uncache(dwMFCon);
}
//
// Get an enumeration of the expected 3 nodes, then check to
// ensure that the DIB and Bitmap nodes are there
//
if (S_OK == hr)
{
hr = pEsd->Next(3, rgStat, &cFetched);
}
//
// Verify that each of our STATDATAs came back
// from the enumeration.
//
if (S_OK == hr)
{
if (S_FALSE == EltIsInArray(sdDIB, rgStat, 3))
{
hr = E_FAIL;
}
else if (S_FALSE == EltIsInArray(sdBMP, rgStat, 3))
{
hr = E_FAIL;
}
else if (S_FALSE == EltIsInArray(sdEMF, rgStat, 3))
{
hr = E_FAIL;
}
}
//
// Reset and Skip one node. WARNING: We assume that the EMF
// node is the first on to be enum'd. This is NOT valid, but
// is based on knowledge of how the cache is implemented, and
// is our only way of testing this...
//
if (S_OK == hr)
{
hr = pEsd->Reset();
}
if (S_OK == hr)
{
hr = pEsd->Skip(1);
}
//
// What we expect at this point: EMF
// DIB <---
// BMP
//
//
// If we kill the DIB or BMP node, both should disappear, and Next()
// must fail (even though we can't assume order, we know that DIB
// and BMP are never enum'd out of order, such as DIB-EMF-DIB
//
if (S_OK == hr)
{
hr = m_pOleCache->Uncache(dwDIBCon);
}
// Since we have uncached the DIB node, the BITMAP node should have
// been automatically uncached as well. First we ensure that we are
// unable to uncache the BITMAP node...
if (S_OK == hr)
{
hr = m_pOleCache->Uncache(dwBMPCon);
// This _should_ have failed, so adjust the error code
hr = MassageErrorCode(OLE_E_NOCONNECTION, hr);
}
//
// Now try to skip; the next node automatically disappeared,
// so it should fail
//
if (S_OK == hr)
{
hr = pEsd->Skip(1);
// The above _should_ fail
hr = MassageErrorCode(S_FALSE, hr);
}
//
// The EMF node should be the only one remaining, so uncache it
// to ensure that we leave the cache as empty as we found it.
//
if (S_OK == hr)
{
hr = m_pOleCache->Uncache(dwEMFCon);
}
//
// Verify that the cache is empty
//
if (S_OK == hr)
{
hr = pEsd->Reset();
if (hr == S_OK)
{
hr = pEsd->Skip(1);
hr = MassageErrorCode(S_FALSE, hr);
}
}
//
// Release the enumerator
//
pEsd->Release();
return hr;
}