/*
 * 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 "fileappendertestcase.h"
#include <log4cxx/fileappender.h>
#include "insertwide.h"

using namespace log4cxx;
using namespace log4cxx::helpers;

WriterAppender* FileAppenderAbstractTestCase::createWriterAppender() const
{
	return createFileAppender();
}


/**
   Unit tests of log4cxx::FileAppender
 */
class FileAppenderTestCase : public FileAppenderAbstractTestCase
{
		LOGUNIT_TEST_SUITE(FileAppenderTestCase);
		//
		//    tests inherited from AppenderSkeletonTestCase
		//
		LOGUNIT_TEST(testDefaultThreshold);
		LOGUNIT_TEST(testSetOptionThreshold);

		//  tests defined here
		LOGUNIT_TEST(testSetDoubleBackslashes);
		LOGUNIT_TEST(testStripDuplicateBackslashes);

		LOGUNIT_TEST_SUITE_END();




	public:

		FileAppender* createFileAppender() const
		{
			return new log4cxx::FileAppender();
		}

		void testSetDoubleBackslashes()
		{
			FileAppender appender;
			appender.setOption(LOG4CXX_STR("FILE"), LOG4CXX_STR("output\\\\temp"));
			const File& file = appender.getFile();
			LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("output\\temp"), getPath(file));
		}

		/**
		 * Tests that double backslashes in filespecs are stripped
		 *  on calls to setOption.
		 *
		 */
		void testStripDoubleBackslashes()
		{

			FileAppender appender;
			appender.setOption(LOG4CXX_STR("FILE"), LOG4CXX_STR("output\\\\temp"));
			const File& file = appender.getFile();
			LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("output\\temp"), getPath(file));
		}

		/**
		 * Tests stripDuplicateBackslashes
		 *
		 *
		 */
		void testStripDuplicateBackslashes()
		{
			LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("\\foo\\bar\\foo"),
				FileAppender::stripDuplicateBackslashes(LOG4CXX_STR("\\foo\\bar\\foo")));
			LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("\\foo\\bar\\foo\\"),
				FileAppender::stripDuplicateBackslashes(LOG4CXX_STR("\\\\foo\\\\bar\\\\foo\\\\")));
			LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("\\foo\\bar\\foo\\"),
				FileAppender::stripDuplicateBackslashes(LOG4CXX_STR("\\foo\\bar\\foo\\")));
			//
			//   UNC's should either start with two backslashes and contain additional singles
			//       or four back slashes and addition doubles
			LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("\\\\foo\\bar\\foo"),
				FileAppender::stripDuplicateBackslashes(LOG4CXX_STR("\\\\\\\\foo\\\\bar\\\\foo")));
			LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("\\\\foo\\bar\\foo"),
				FileAppender::stripDuplicateBackslashes(LOG4CXX_STR("\\\\foo\\bar\\foo")));
			//
			//   it it starts with doubles but has no other path component
			//      then it is a file path
			LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("\\foo.log"),
				FileAppender::stripDuplicateBackslashes(LOG4CXX_STR("\\\\foo.log")));
			//
			//   it it starts with quads but has no other path component
			//      then it is a UNC
			LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("\\\\foo.log"),
				FileAppender::stripDuplicateBackslashes(LOG4CXX_STR("\\\\\\\\foo.log")));
		}

};

LOGUNIT_TEST_SUITE_REGISTRATION(FileAppenderTestCase);
