//
// DynamicAnyTest.h
//
// $Id: //poco/1.4/Foundation/testsuite/src/DynamicAnyTest.h#2 $
//
// Tests for Any types
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
// 
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
// 
// 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//

#ifndef DynamicAnyTest_INCLUDED
#define DynamicAnyTest_INCLUDED


#include "Poco/Foundation.h"
#include "Poco/DynamicAny.h"
#include "Poco/Exception.h"
#include "CppUnit/TestCase.h"


class DynamicAnyTest: public CppUnit::TestCase
{
public:
	DynamicAnyTest(const std::string& name);
	~DynamicAnyTest();

	void testInt8();
	void testInt16();
	void testInt32();
	void testInt64();
	void testUInt8();
	void testUInt16();
	void testUInt32();
	void testUInt64();
	void testBool();
	void testChar();
	void testFloat();
	void testDouble();
	void testLong();
	void testULong();
	void testString();
	void testString2();
	void testConversionOperator();
	void testLimitsInt();
	void testLimitsFloat();
	void testCtor();

	void setUp();
	void tearDown();
	static CppUnit::Test* suite();

private:
	template<typename TL, typename TS>
	void testLimitsSigned()
	{
		TL iMin = std::numeric_limits<TS>::min();
		Poco::DynamicAny da = iMin - 1;

#if defined(_MSC_VER) && _MSC_VER < 1400    // workaround for vc7.1
		try { TS i; i = da.convert<TS>(); fail("must fail"); }
#else
		try { TS i; i = da; fail("must fail"); }
#endif 

		catch (Poco::RangeException&) {}

		TL iMax = std::numeric_limits<TS>::max();
		da = iMax + 1;

#if defined(_MSC_VER) && _MSC_VER < 1400    // workaround for vc7.1
		try { TS i; i = da.convert<TS>(); fail("must fail"); }
#else
		try { TS i; i = da; fail("must fail"); }
#endif  
        
		catch (Poco::RangeException&) {}
	}

	template<typename TL, typename TS>
	void testLimitsFloatToInt()
	{
		Poco::DynamicAny da;

		if (std::numeric_limits<TS>::is_signed)
		{
			TL iMin = static_cast<TL>(std::numeric_limits<TS>::min());
			da = iMin * 10;

#if defined(_MSC_VER) && _MSC_VER < 1400    // workaround for vc7.1
			try { TS i; i = da.convert<TS>(); fail("must fail"); }
#else
			try { TS i; i = da; fail("must fail"); }
#endif 

			catch (Poco::RangeException&) {}
		}

		TL iMax = static_cast<TL>(std::numeric_limits<TS>::max());
		da = iMax * 10;

#if defined(_MSC_VER) && _MSC_VER < 1400    // workaround for vc7.1
		try { TS i; i = da.convert<TS>(); fail("must fail"); }
#else
		try { TS i; i = da; fail("must fail"); }
#endif 

		catch (Poco::RangeException&) {}
	}

	template<typename TS, typename TU>
	void testLimitsSignedUnsigned()
	{
		assert (std::numeric_limits<TS>::is_signed);
		assert (!std::numeric_limits<TU>::is_signed);

		TS iMin = std::numeric_limits<TS>::min();
		Poco::DynamicAny da = iMin;

#if defined(_MSC_VER) && _MSC_VER < 1400    // workaround for vc7.1
		try { TU i; i = da.convert<TU>(); fail("must fail"); }
#else
		try { TU i; i = da; fail("must fail"); }
#endif 

		catch (Poco::RangeException&) {}
	}

	template<typename TL, typename TS>
	void testLimitsUnsigned()
	{
		TL iMax = std::numeric_limits<TS>::max();
		Poco::DynamicAny da = iMax + 1;

#if defined(_MSC_VER) && _MSC_VER < 1400    // workaround for vc7.1
		try { TS i; i = da.convert<TS>(); fail("must fail"); }
#else
		try { TS i; i = da; fail("must fail"); }
#endif 

		catch (Poco::RangeException&) {}
	}
};


#endif // DynamicAnyTest_INCLUDED
