/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <log4cxx/log4cxx.h>
 /* Prevent error C2491: 'std::numpunct<_Elem>::id': definition of dllimport static data member not allowed */
#if defined(_MSC_VER) && LOG4CXX_UNICHAR_API
#define __FORCE_INSTANCE
#endif
#include <ostream>
#include <iomanip>

#include "vectorappender.h"
#include <log4cxx/logmanager.h>
#include <log4cxx/simplelayout.h>
#include <log4cxx/spi/loggingevent.h>
#include "insertwide.h"
#include "logunit.h"
#include <log4cxx/stream.h>
#include <log4cxx/helpers/loglog.h>

#if LOG4CXX_CFSTRING_API
	#include <CoreFoundation/CFString.h>
#endif

using namespace log4cxx;
using namespace log4cxx::helpers;
using namespace std;

class ExceptionOnInsert
{
	public:
		ExceptionOnInsert()
		{
		}
};

//
//   define an insertion operation that will throw an
//       exception to test that evaluation was short
//       circuited
//
template<class Elem, class Tr>
::std::basic_ostream<Elem, Tr>& operator<<(
	::std::basic_ostream<Elem, Tr>&,
	const ExceptionOnInsert&)
{
	throw std::exception();
}


/**
   Unit tests for the optional stream-like interface for log4cxx
 */
LOGUNIT_CLASS(StreamTestCase)
{
	LOGUNIT_TEST_SUITE(StreamTestCase);
	LOGUNIT_TEST(testSimple);
	LOGUNIT_TEST(testMultiple);
	LOGUNIT_TEST(testShortCircuit);
	LOGUNIT_TEST_EXCEPTION(testInsertException, std::exception);
	LOGUNIT_TEST(testScientific);
	LOGUNIT_TEST(testPrecision);
	LOGUNIT_TEST(testWidth);
#if LOG4CXX_WCHAR_T_API
	LOGUNIT_TEST(testWide);
	LOGUNIT_TEST(testWideAppend);
	LOGUNIT_TEST(testWideWidth);
#endif
	LOGUNIT_TEST(testBaseFlags);
	LOGUNIT_TEST(testBasePrecisionAndWidth);
	LOGUNIT_TEST(testLogStreamSimple);
	LOGUNIT_TEST(testLogStreamMultiple);
	LOGUNIT_TEST(testLogStreamShortCircuit);
	LOGUNIT_TEST_EXCEPTION(testLogStreamInsertException, std::exception);
	LOGUNIT_TEST(testLogStreamScientific);
	LOGUNIT_TEST(testLogStreamPrecision);
	LOGUNIT_TEST(testLogStreamWidth);
	LOGUNIT_TEST(testLogStreamDelegate);
	LOGUNIT_TEST(testLogStreamFormattingPersists);
	LOGUNIT_TEST(testSetWidthInsert);
#if LOG4CXX_WCHAR_T_API
	LOGUNIT_TEST(testWLogStreamSimple);
	LOGUNIT_TEST(testWLogStreamMultiple);
	LOGUNIT_TEST(testWLogStreamShortCircuit);
	LOGUNIT_TEST_EXCEPTION(testWLogStreamInsertException, std::exception);
	LOGUNIT_TEST(testWLogStreamScientific);
	LOGUNIT_TEST(testWLogStreamPrecision);
	LOGUNIT_TEST(testWLogStreamWidth);
	LOGUNIT_TEST(testWLogStreamDelegate);
	LOGUNIT_TEST(testWLogStreamFormattingPersists);
	LOGUNIT_TEST(testWSetWidthInsert);
#endif
#if LOG4CXX_UNICHAR_API
	LOGUNIT_TEST(testUniChar);
	LOGUNIT_TEST(testUniCharAppend);
	//                LOGUNIT_TEST(testUniCharWidth);
	LOGUNIT_TEST(testULogStreamSimple);
	LOGUNIT_TEST(testULogStreamMultiple);
	LOGUNIT_TEST(testULogStreamShortCircuit);
	LOGUNIT_TEST_EXCEPTION(testULogStreamInsertException, std::exception);
	//                LOGUNIT_TEST(testULogStreamScientific);
	//                LOGUNIT_TEST(testULogStreamPrecision);
	//                LOGUNIT_TEST(testULogStreamWidth);
	LOGUNIT_TEST(testULogStreamDelegate);
	//                LOGUNIT_TEST(testULogStreamFormattingPersists);
	//                LOGUNIT_TEST(testUSetWidthInsert);
#endif
#if LOG4CXX_CFSTRING_API
	LOGUNIT_TEST(testCFString);
	LOGUNIT_TEST(testCFStringAppend);
#endif
#if LOG4CXX_UNICHAR_API && LOG4CXX_CFSTRING_API
	LOGUNIT_TEST(testULogStreamCFString);
	LOGUNIT_TEST(testULogStreamCFString2);
#endif
	LOGUNIT_TEST_SUITE_END();

	VectorAppenderPtr vectorAppender;

#ifdef _DEBUG
	struct Fixture
	{
		Fixture() {
			helpers::LogLog::setInternalDebugging(true);
		}
	} suiteFixture;
#endif

public:
	void setUp()
	{
		LoggerPtr root(Logger::getRootLogger());
		LayoutPtr layout(new SimpleLayout());
		vectorAppender = VectorAppenderPtr(new VectorAppender());
		root->addAppender(vectorAppender);
	}

	void tearDown()
	{
		LogManager::shutdown();
	}

	void testSimple()
	{
		LoggerPtr root(Logger::getRootLogger());
		LOG4CXX_INFO(root, "This is a test");
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
	}

	void testMultiple()
	{
		LoggerPtr root(Logger::getRootLogger());
		LOG4CXX_INFO(root, "This is a test" << ": Details to follow");
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
	}

	void testShortCircuit()
	{
		LoggerPtr logger(Logger::getLogger("StreamTestCase.shortCircuit"));
		logger->setLevel(Level::getInfo());
		ExceptionOnInsert someObj;
		LOG4CXX_DEBUG(logger, someObj);
		LOGUNIT_ASSERT_EQUAL((size_t) 0, vectorAppender->getVector().size());
	}

	void testInsertException()
	{
		LoggerPtr logger(Logger::getLogger("StreamTestCase.insertException"));
		ExceptionOnInsert someObj;
		LOG4CXX_INFO(logger, someObj);
	}

	void testScientific()
	{
		LoggerPtr root(Logger::getRootLogger());
		LOG4CXX_INFO(root, std::scientific << 0.000001115);
		spi::LoggingEventPtr event(vectorAppender->getVector()[0]);
		LogString msg(event->getMessage());
		LOGUNIT_ASSERT(msg.find(LOG4CXX_STR("e-")) != LogString::npos ||
			msg.find(LOG4CXX_STR("E-")) != LogString::npos);
	}

	void testPrecision()
	{
		LoggerPtr root(Logger::getRootLogger());
		LOG4CXX_INFO(root, std::setprecision(4) << 1.000001);
		spi::LoggingEventPtr event(vectorAppender->getVector()[0]);
		LogString msg(event->getMessage());
		LOGUNIT_ASSERT(msg.find(LOG4CXX_STR("1.00000")) == LogString::npos);
	}


	void testWidth()
	{
		LoggerPtr root(Logger::getRootLogger());
		LOG4CXX_INFO(root, '[' << std::fixed << std::setprecision(2) << std::setw(7) << std::right << std::setfill('_') << 10.0 << ']');
		spi::LoggingEventPtr event(vectorAppender->getVector()[0]);
		LogString msg(event->getMessage());
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("[__10.00]")), msg);
	}

	void testBaseFlags()
	{
		logstream base1(Logger::getRootLogger(), Level::getInfo());
		logstream base2(Logger::getRootLogger(), Level::getInfo());
		base1 << std::boolalpha;
		base2 << std::noboolalpha;
		std::ostringstream os1a, os1b, os2a, os2b;
		os1a << std::boolalpha;
		int fillchar;

		if (base1.set_stream_state(os1b, fillchar))
		{
			os1b.fill(fillchar);
		}

		LOGUNIT_ASSERT_EQUAL(os1a.flags(), os1b.flags());
		os2a << std::noboolalpha;

		if (base2.set_stream_state(os2b, fillchar))
		{
			os2b.fill(fillchar);
		}

		LOGUNIT_ASSERT_EQUAL(os2a.flags(), os2b.flags());
	}


	void testBasePrecisionAndWidth()
	{
		logstream base(Logger::getRootLogger(), Level::getInfo());
		base.precision(2);
		base.width(5);
		std::ostringstream os1, os2;
		os1.precision(2);
		os1.width(5);
		os1 << 3.1415926;
		int fillchar;

		if (base.set_stream_state(os2, fillchar))
		{
			os2.fill(fillchar);
		}

		os2 << 3.1415926;
		string expected(os1.str());
		string actual(os2.str());
		LOGUNIT_ASSERT_EQUAL(expected, actual);
	}

	void testLogStreamSimple()
	{
		logstream root(Logger::getRootLogger(), Level::getInfo());
		root << std::string("This is a test") << LOG4CXX_ENDMSG;
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
	}

	void testLogStreamMultiple()
	{
		logstream root(Logger::getRootLogger(), Level::getInfo());
		root << std::string("This is a test") << std::string(": Details to follow") << LOG4CXX_ENDMSG;
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
	}

	void testLogStreamShortCircuit()
	{
		LoggerPtr logger(Logger::getLogger("StreamTestCase.shortCircuit"));
		logger->setLevel(Level::getInfo());
		logstream os(logger, Level::getDebug());
		ExceptionOnInsert someObj;
		os << someObj << LOG4CXX_ENDMSG;
		LOGUNIT_ASSERT_EQUAL((size_t) 0, vectorAppender->getVector().size());
	}

	void testLogStreamInsertException()
	{
		LoggerPtr logger(Logger::getLogger("StreamTestCase.insertException"));
		ExceptionOnInsert someObj;
		logstream os(logger, Level::getInfo());
		os << someObj << LOG4CXX_ENDMSG;
	}

	void testLogStreamScientific()
	{
		LoggerPtr root(Logger::getRootLogger());
		logstream os(root, Level::getInfo());
		os << std::scientific << 0.000001115 << LOG4CXX_ENDMSG;
		spi::LoggingEventPtr event(vectorAppender->getVector()[0]);
		LogString msg(event->getMessage());
		LOGUNIT_ASSERT(msg.find(LOG4CXX_STR("e-")) != LogString::npos ||
			msg.find(LOG4CXX_STR("E-")) != LogString::npos);
	}

	void testLogStreamPrecision()
	{
		LoggerPtr root(Logger::getRootLogger());
		logstream os(root, Level::getInfo());
		os << std::setprecision(4) << 1.000001 << LOG4CXX_ENDMSG;
		spi::LoggingEventPtr event(vectorAppender->getVector()[0]);
		LogString msg(event->getMessage());
		LOGUNIT_ASSERT(msg.find(LOG4CXX_STR("1.00000")) == LogString::npos);
	}


	void testLogStreamWidth()
	{
		LoggerPtr root(Logger::getRootLogger());
		logstream os(root, Level::getInfo());
		os << '[' << std::fixed << std::setprecision(2) << std::setw(7) << std::right << std::setfill('_') << 10.0 << ']' << LOG4CXX_ENDMSG;
		spi::LoggingEventPtr event(vectorAppender->getVector()[0]);
		LogString msg(event->getMessage());
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("[__10.00]")), msg);
	}

	void report(std::ostream & os)
	{
		os << "This just in: \n";
		os << "Use logstream in places that expect a std::ostream.\n";
	}

	void testLogStreamDelegate()
	{
		logstream root(Logger::getRootLogger(), Level::getInfo());
		report(root);
		root << LOG4CXX_ENDMSG;
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
	}

	void testLogStreamFormattingPersists()
	{
		LoggerPtr root(Logger::getRootLogger());
		root->setLevel(Level::getInfo());
		logstream os(root, Level::getDebug());
		os << std::hex << 20 << LOG4CXX_ENDMSG;
		os << Level::getInfo() << 16 << LOG4CXX_ENDMSG;
		spi::LoggingEventPtr event(vectorAppender->getVector()[0]);
		LogString msg(event->getMessage());
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("10")), msg);
	}

	void testSetWidthInsert()
	{
		LoggerPtr root(Logger::getRootLogger());
		root->setLevel(Level::getInfo());
		logstream os(root, Level::getInfo());
		os << std::setw(5);
		LOGUNIT_ASSERT_EQUAL(5, os.width());
	}



#if LOG4CXX_WCHAR_T_API
	void testWide()
	{
		LoggerPtr root(Logger::getRootLogger());
		LOG4CXX_INFO(root, L"This is a test");
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
	}

	void testWideAppend()
	{
		LoggerPtr root(Logger::getRootLogger());
		LOG4CXX_INFO(root, L"This is a test" << L": Details to follow");
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
	}

	void testWideWidth()
	{
		LoggerPtr root(Logger::getRootLogger());
		LOG4CXX_INFO(root, L'[' << std::fixed << std::setprecision(2) << std::setw(7) << std::right << std::setfill(L'_') << 10.0 << L"]");
		spi::LoggingEventPtr event(vectorAppender->getVector()[0]);
		LogString msg(event->getMessage());
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("[__10.00]")), msg);
	}

	void testWLogStreamSimple()
	{
		wlogstream root(Logger::getRootLogger(), Level::getInfo());
		root << L"This is a test" << LOG4CXX_ENDMSG;
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
	}

	void testWLogStreamMultiple()
	{
		wlogstream root(Logger::getRootLogger(), Level::getInfo());
		root << L"This is a test" << L": Details to follow" << LOG4CXX_ENDMSG;
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
	}

	void testWLogStreamShortCircuit()
	{
		LoggerPtr logger(Logger::getLogger("StreamTestCase.shortCircuit"));
		logger->setLevel(Level::getInfo());
		wlogstream os(logger, Level::getDebug());
		ExceptionOnInsert someObj;
		os << someObj << LOG4CXX_ENDMSG;
		LOGUNIT_ASSERT_EQUAL((size_t) 0, vectorAppender->getVector().size());
	}

	void testWLogStreamInsertException()
	{
		LoggerPtr logger(Logger::getLogger("StreamTestCase.insertException"));
		ExceptionOnInsert someObj;
		wlogstream os(logger, Level::getInfo());
		os << someObj << LOG4CXX_ENDMSG;
	}

	void testWLogStreamScientific()
	{
		LoggerPtr root(Logger::getRootLogger());
		wlogstream os(root, Level::getInfo());
		os << std::scientific << 0.000001115 << LOG4CXX_ENDMSG;
		spi::LoggingEventPtr event(vectorAppender->getVector()[0]);
		LogString msg(event->getMessage());
		LOGUNIT_ASSERT(msg.find(LOG4CXX_STR("e-")) != LogString::npos ||
			msg.find(LOG4CXX_STR("E-")) != LogString::npos);
	}

	void testWLogStreamPrecision()
	{
		LoggerPtr root(Logger::getRootLogger());
		wlogstream os(root, Level::getInfo());
		os << std::setprecision(4) << 1.000001 << LOG4CXX_ENDMSG;
		spi::LoggingEventPtr event(vectorAppender->getVector()[0]);
		LogString msg(event->getMessage());
		LOGUNIT_ASSERT(msg.find(LOG4CXX_STR("1.00000")) == LogString::npos);
	}


	void testWLogStreamWidth()
	{
		LoggerPtr root(Logger::getRootLogger());
		wlogstream os(root, Level::getInfo());
		os << L"[" << std::fixed << std::setprecision(2) << std::setw(7) << std::right << std::setfill(L'_') << 10.0 << L"]" << LOG4CXX_ENDMSG;
		spi::LoggingEventPtr event(vectorAppender->getVector()[0]);
		LogString msg(event->getMessage());
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("[__10.00]")), msg);
	}

	void wreport(std::basic_ostream<wchar_t>& os)
	{
		os << L"This just in: \n";
		os << L"Use logstream in places that expect a std::ostream.\n";
	}

	void testWLogStreamDelegate()
	{
		wlogstream root(Logger::getRootLogger(), Level::getInfo());
		wreport(root);
		root << LOG4CXX_ENDMSG;
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
	}

	void testWLogStreamFormattingPersists()
	{
		LoggerPtr root(Logger::getRootLogger());
		root->setLevel(Level::getInfo());
		wlogstream os(root, Level::getDebug());
		os << std::hex << 20 << LOG4CXX_ENDMSG;
		os << Level::getInfo() << 16 << LOG4CXX_ENDMSG;
		spi::LoggingEventPtr event(vectorAppender->getVector()[0]);
		LogString msg(event->getMessage());
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("10")), msg);
	}

	void testWSetWidthInsert()
	{
		LoggerPtr root(Logger::getRootLogger());
		root->setLevel(Level::getInfo());
		wlogstream os(root, Level::getInfo());
		os << std::setw(5);
		LOGUNIT_ASSERT_EQUAL(5, os.width());
	}

#endif

#if LOG4CXX_UNICHAR_API
	void testUniChar()
	{
		LoggerPtr root(Logger::getRootLogger());
		const log4cxx::UniChar msg[] = { 'T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 's', 't', 0 };
		LOG4CXX_INFO(root, msg);
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
	}

	void testUniCharAppend()
	{
		LoggerPtr root(Logger::getRootLogger());
		const log4cxx::UniChar msg1[] = { 'T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 's', 't', 0 };
		const log4cxx::UniChar msg2[] = { ':', ' ', 'D', 'e', 't', 'a', 'i', 'l', 's', ' ', 't', 'o', ' ', 'f', 'o', 'l', 'l', 'o', 'w', 0 };
		LOG4CXX_INFO(root, msg1 << msg2);
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
	}

	void testUniCharWidth()
	{
		LoggerPtr root(Logger::getRootLogger());
		const log4cxx::UniChar openBracket[] = { '[', 0 };
		const log4cxx::UniChar closeBracket[] = { ']', 0 };
		LOG4CXX_INFO(root, openBracket << std::fixed << std::setprecision(2) << std::setw(7) << std::right << std::setfill((log4cxx::UniChar)'_') << 10.0 << closeBracket);
		spi::LoggingEventPtr event(vectorAppender->getVector()[0]);
		LogString msg(event->getMessage());
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("[__10.00]")), msg);
	}

	void testULogStreamSimple()
	{
		ulogstream root(Logger::getRootLogger(), Level::getInfo());
		const log4cxx::UniChar msg[] = { 'T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 's', 't', 0 };
		root << msg << LOG4CXX_ENDMSG;
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
	}

	void testULogStreamMultiple()
	{
		ulogstream root(Logger::getRootLogger(), Level::getInfo());
		const log4cxx::UniChar msg1[] = { 'T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 's', 't', 0 };
		const log4cxx::UniChar msg2[] = { ':',  ' ', 'D', 'e', 't', 'a', 'i', 'l', 's', ' ', 't', 'o', ' ', 'f', 'o', 'l', 'l', 'o', 'w', 0 };
		root << msg1 << msg2 << LOG4CXX_ENDMSG;
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
	}

	void testULogStreamShortCircuit()
	{
		LoggerPtr logger(Logger::getLogger("StreamTestCase.shortCircuit"));
		logger->setLevel(Level::getInfo());
		ulogstream os(logger, Level::getDebug());
		ExceptionOnInsert someObj;
		os << someObj << LOG4CXX_ENDMSG;
		LOGUNIT_ASSERT_EQUAL((size_t) 0, vectorAppender->getVector().size());
	}

	void testULogStreamInsertException()
	{
		LoggerPtr logger(Logger::getLogger("StreamTestCase.insertException"));
		ExceptionOnInsert someObj;
		ulogstream os(logger, Level::getInfo());
		os << someObj << LOG4CXX_ENDMSG;
	}

	void testULogStreamScientific()
	{
		LoggerPtr root(Logger::getRootLogger());
		ulogstream os(root, Level::getInfo());
		os << std::scientific << 0.000001115 << LOG4CXX_ENDMSG;
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
		spi::LoggingEventPtr event(vectorAppender->getVector()[0]);
		LogString msg(event->getMessage());
		LOGUNIT_ASSERT(msg.find(LOG4CXX_STR("e-")) != LogString::npos ||
			msg.find(LOG4CXX_STR("E-")) != LogString::npos);
	}

	void testULogStreamPrecision()
	{
		LoggerPtr root(Logger::getRootLogger());
		ulogstream os(root, Level::getInfo());
		os << std::setprecision(4) << 1.000001 << LOG4CXX_ENDMSG;
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
		spi::LoggingEventPtr event(vectorAppender->getVector()[0]);
		LogString msg(event->getMessage());
		LOGUNIT_ASSERT(msg.find(LOG4CXX_STR("1.00000")) == LogString::npos);
	}


	void testULogStreamWidth()
	{
		LoggerPtr root(Logger::getRootLogger());
		ulogstream os(root, Level::getInfo());
		const log4cxx::UniChar openBracket[] = { '[', 0 };
		const log4cxx::UniChar closeBracket[] = { ']', 0 };

		os << openBracket << std::fixed << std::setprecision(2) << std::setw(7) << std::right
			<< std::setfill((log4cxx::UniChar) '_') << 10.0 << closeBracket << LOG4CXX_ENDMSG;
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
		spi::LoggingEventPtr event(vectorAppender->getVector()[0]);
		LogString msg(event->getMessage());
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("[__10.00]")), msg);
	}

	void ureport(std::basic_ostream<log4cxx::UniChar>& os)
	{
		const log4cxx::UniChar msg1[] = { 'T', 'h', 'i', 's', ' ', 'j', 'u', 's', 't', ' ', 'i', 'n', ':', ' ', '\n', 0 };
		const log4cxx::UniChar msg2[] = { 'U', 's', 'e', ' ', 'l', 'o', 'g', 's', 't', 'r', 'e', 'a', 'm', '\n', 0 };
		os << msg1;
		os << msg2;
	}

	void testULogStreamDelegate()
	{
		ulogstream root(Logger::getRootLogger(), Level::getInfo());
		ureport(root);
		root << LOG4CXX_ENDMSG;
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
	}

	void testULogStreamFormattingPersists()
	{
		LoggerPtr root(Logger::getRootLogger());
		root->setLevel(Level::getInfo());
		ulogstream os(root, Level::getDebug());
		os << std::hex << 20 << LOG4CXX_ENDMSG;
		os << Level::getInfo() << 16 << LOG4CXX_ENDMSG;
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
		spi::LoggingEventPtr event(vectorAppender->getVector()[0]);
		LogString msg(event->getMessage());
		LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("10")), msg);
	}

	void testUSetWidthInsert()
	{
		LoggerPtr root(Logger::getRootLogger());
		root->setLevel(Level::getInfo());
		ulogstream os(root, Level::getInfo());
		os << std::setw(5);
		LOGUNIT_ASSERT_EQUAL(5, os.width());
	}

#endif

#if LOG4CXX_CFSTRING_API
	void testCFString()
	{
		LoggerPtr root(Logger::getRootLogger());
		LOG4CXX_INFO(root, CFSTR("This is a test"));
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
	}

	void testCFStringAppend()
	{
		LoggerPtr root(Logger::getRootLogger());
		LOG4CXX_INFO(root, CFSTR("This is a test") << CFSTR(": Details to follow"));
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
	}
#endif

#if LOG4CXX_UNICHAR_API && LOG4CXX_CFSTRING_API
	void testULogStreamCFString()
	{
		ulogstream root(Logger::getRootLogger(), Level::getInfo());
		root << CFSTR("This is a test") << LOG4CXX_ENDMSG;
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
	}

	void testULogStreamCFString2()
	{
		ulogstream root(Logger::getRootLogger(), Level::getInfo());
		root << CFSTR("This is a test") << CFSTR(": Details to follow") << LOG4CXX_ENDMSG;
		LOGUNIT_ASSERT_EQUAL((size_t) 1, vectorAppender->getVector().size());
	}
#endif

};

LOGUNIT_TEST_SUITE_REGISTRATION(StreamTestCase);


#if !LOG4CXX_USE_GLOBAL_SCOPE_TEMPLATE
//
//   The following code tests compilation errors
//      around bug LOGCXX-150 and is not intended to be executed.
//      Skipped for VC6 since it can't handle having the
//      templated operator<< in class scope.s
namespace foo
{
class Bar
{
		void fn();
};

std::ostream& operator<<(std::ostream& o, Bar const& b)
{
	return o << "Bar";
}
}


using namespace foo;

namespace
{
log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger("foo"));
log4cxx::logstream lout(logger, log4cxx::Level::getDebug());
}

void Bar::fn()
{
	lout << "hi" << LOG4CXX_ENDMSG;
}
#endif

