/******************************************************************

WinUnitSEH.h - additional macros to enable the use of WinUnit with 
functions that throw the SEH exceptions 

THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Copyright (C) 2008.  WinAbility Software Corporation. All rights reserved.

Author: Andrei Belogortseff [ http://www.softblog.com ]

TERMS OF USE: You are free to use this file in any way you like, 
for both the commercial and non-commercial purposes, royalty-free,
AS LONG AS you agree with the warranty disclaimer above, 
EXCEPT that you may not remove or modify this or any of the 
preceeding paragraphs. If you make any changes, please document 
them in the MODIFICATIONS section below. If the changes are of general 
interest, please let us know and we will consider incorporating them in 
this file, as well.

If you use this file in your own project, an acknowledgement will be 
appreciated, although it's not required.

SUMMARY:

As of this writing WinUnit uses C++ exception handling that cannot be used
to test functions that use Structured Exception Handling (SEH). To make it 
possible to write unit tests for such functions, this file defines the 
following C/C++ macros:

BEGIN_TEST_SEH( TestName )
END_TEST_SEH
FIXTURE_SEH( FixtureName )
SETUP_SEH( FixtureName )
TEARDOWN_SEH( FixtureName )
BEGIN_TESTF_SEH( TestName, FixtureName )
END_TESTF_SEH( FixtureName )
WIN_ASSERT_THROWS_SEH( expression, ... )

They should be used in place of their regular counterparts (BEGIN_TEST, 
END_TEST, etc.) when writing tests for functions that throw SEH exceptions.
For more information, visit http://www.softblog.com and search there for 
WinUnit or SEH. 

MODIFICATIONS:
2008-Jan-15: created by Andrei Belogortseff.

******************************************************************/

#define BEGIN_TEST_BLOCK_SEH					\
	__try 

#define END_TEST_BLOCK_SEH                			\
	__except(EXCEPTION_EXECUTE_HANDLER)         		\
	{                                           		\
		EMIT_ERROR(L"%s(%d): SEH Exception thrown.",	\
		__WFILE__, __LINE__);           		\
	}                                           		\

#define BEGIN_TEST_SEH( TestName )   				\
	BEGIN_TEST_FUNC( TestName ) 				\
	BEGIN_TEST_BLOCK_SEH

#define END_TEST_SEH        					\
	END_TEST_BLOCK_SEH     					\
	END_TEST_FUNC

///////////////////////////

#define FIXTURE_SEH( FixtureName )

#define SETUP_SEH( FixtureName ) 				\
	void Setup_FIXTURE_##FixtureName()

#define TEARDOWN_SEH( FixtureName ) 				\
	void Teardown_FIXTURE_##FixtureName()

#define BEGIN_FIXTURE_BLOCK_SEH( fixtureName )			\
	__try { Setup_FIXTURE_##fixtureName();

#define END_FIXTURE_BLOCK_SEH(fixtureName)                      \
	Teardown_FIXTURE_##fixtureName();			\
    }                                                           \
    __except(EXCEPTION_EXECUTE_HANDLER)				\
    {                                                        	\
        EMIT_ERROR(L"%s(%d): Exception thrown in fixture.",     \
            __WFILE__, __LINE__);                               \
    }                                                           \

#define BEGIN_TESTF_SEH( TestName, FixtureName ) 		\
	BEGIN_TEST_FUNC( TestName) 				\
	BEGIN_FIXTURE_BLOCK_SEH( FixtureName ) 			\
	BEGIN_TEST_BLOCK_SEH

#define END_TESTF_SEH( FixtureName )       			\
	END_TEST_BLOCK_SEH     					\
	END_FIXTURE_BLOCK_SEH( FixtureName )      		\
	END_TEST_FUNC

#define WIN_ASSERT_THROWS_SEH(expression, ...)                  \
{                                                               \
    bool __thrown = false;                                      \
    __try { (expression); }                                     \
    __except(EXCEPTION_EXECUTE_HANDLER) { __thrown = true; }    \
    WinUnit::Assert::ThrowsException(                           \
       TSTRING(expression), _T(""),                             \
       __thrown, __TFILE__, __LINE__, __VA_ARGS__);             \
}


