//------------------------------------------------------------------------------
// Lamp : Open source game middleware
// Copyright (C) 2004  Junpei Ohtani ( Email : junpee@users.sourceforge.jp )
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//------------------------------------------------------------------------------

/** @file
 * デックのテスト実装
 * @author Junpee
 */

#include "Test/stdafx.h"
#include <Core/Container/Deque.h>
#include "Core/Container/DequeTest.h"

//------------------------------------------------------------------------------
// テストスィートの取得
Test* DequeTest::suite(){
	TestSuite* suite = new TestSuite("DequeTest");
	suite->addTest(new TestCaller(DequeTest, testIntDeque));
	suite->addTest(new TestCaller(DequeTest, testPointerDeque));
	suite->addTest(new TestCaller(DequeTest, testSort));
	return suite;
}
//------------------------------------------------------------------------------
// intデックテスト
void DequeTest::testIntDeque(){
	typedef Deque<int> IntDeque;
	TestEquals(16, (int)sizeof(IntDeque));
	IntDeque intDeque(1);
	TestAssert(intDeque.isEmpty());
	intDeque.trim();
	TestEquals(0, intDeque.getCount());
	TestEquals(1, intDeque.getCapacity());
	for(int i = 0; i < 7; i++){ intDeque.pushBack(i); }
	TestAssert(!intDeque.isEmpty());
	TestEquals(7, intDeque.getCount());
	TestEquals(8, intDeque.getCapacity());
	intDeque.pushBack(7);
	TestEquals(8, intDeque.getCount());
	TestEquals(8, intDeque.getCapacity());
	for(int i = 0; i < 8; i++){ TestEquals(i, intDeque.get(i)); }
	intDeque.pushBack(8);
	TestEquals(9, intDeque.getCount());
	TestEquals(16, intDeque.getCapacity());
	IntDeque cloneDeque;
	intDeque.clone(cloneDeque);
	TestEquals(9, cloneDeque.getCount());
	TestEquals(16, cloneDeque.getCapacity());
	for(int i = 0; i < 9; i++){ TestEquals(i, cloneDeque.get(i)); }
	intDeque.trim();
	TestEquals(9, intDeque.getCount());
	TestEquals(9, intDeque.getCapacity());
	for(int i = 0; i < 9; i++){
		TestEquals(i, intDeque.indexOf(i));
		TestEquals(i, intDeque.lastIndexOf(i));
	}
	for(int i = 8; i >= 4; i--){ TestEquals(i, intDeque.remove(i)); }
	TestEquals(4, intDeque.getCount());
	TestEquals(9, intDeque.getCapacity());
	for(int i = 0; i < 4; i++){ TestEquals(i, intDeque.get(i)); }
	for(int i = 0; i < 4; i++){ TestEquals(0, intDeque.removeByValue(i)); }
	TestEquals(0, intDeque.getCount());
	TestEquals(9, intDeque.getCapacity());
	intDeque.pushBack(0);
	intDeque[0] = 1;
	TestEquals(1, intDeque[0]);
	intDeque.set(0, 2);
	TestEquals(2, intDeque[0]);
}
//------------------------------------------------------------------------------
// ポインタデックテスト
void DequeTest::testPointerDeque(){
	typedef Deque<int*> PointerDeque;
	PointerDeque pointerDeque(2);
	TestAssert(pointerDeque.isEmpty());
	TestEquals(0, pointerDeque.getCount());
	TestEquals(2, pointerDeque.getCapacity());
	pointerDeque.trim();
	TestEquals(0, pointerDeque.getCount());
	TestEquals(1, pointerDeque.getCapacity());
	int* array[8];
	for(int i = 0; i < 8; i++){
		array[i] = new int();
		pointerDeque.pushBack(array[i]);
	}
	TestAssert(!pointerDeque.isEmpty());
	TestEquals(8, pointerDeque.getCount());
	TestEquals(8, pointerDeque.getCapacity());
	pointerDeque.setCapacity(16);
	TestEquals(8, pointerDeque.getCount());
	TestEquals(16, pointerDeque.getCapacity());
	for(int i = 0; i < 8; i++){ TestAssert((array[i] == pointerDeque.get(i))); }
	PointerDeque cloneDeque;
	pointerDeque.clone(cloneDeque);
	TestEquals(8, cloneDeque.getCount());
	TestEquals(16, cloneDeque.getCapacity());
	for(int i = 0; i < 8; i++){ TestAssert((array[i] == cloneDeque.get(i))); }
	cloneDeque.clear();
	TestEquals(0, cloneDeque.getCount());
	TestEquals(16, cloneDeque.getCapacity());
	pointerDeque.trim();
	TestEquals(8, pointerDeque.getCount());
	TestEquals(8, pointerDeque.getCapacity());
	for(int i = 0; i < 8; i++){
		TestEquals(i, pointerDeque.indexOf(array[i]));
		TestEquals(i, pointerDeque.lastIndexOf(array[i]));
	}
	for(int i = 7; i >= 4; i--){ TestAssert(array[i] == pointerDeque.remove(i)); }
	TestEquals(4, pointerDeque.getCount());
	TestEquals(8, pointerDeque.getCapacity());
	for(int i = 0; i < 4; i++){ TestAssert(array[i] == pointerDeque.get(i)); }
	for(int i = 0; i < 4; i++){ TestEquals(0, pointerDeque.removeByValue(array[i])); }
	TestEquals(0, pointerDeque.getCount());
	TestEquals(8, pointerDeque.getCapacity());
	for(int i = 0; i < 8; i++){ delete array[i]; }
}
//------------------------------------------------------------------------------
// ソートテスト
void DequeTest::testSort(){
	typedef Deque<int> IntDeque;
	int size = 16;
	IntDeque intDeque(size);
	for(int i = 0; i < size; i++){
		intDeque.pushBack(size - i - 1);
	}
	intDeque.sort(compareInt);
	for(int i = 0; i < size; i++){
		TestEquals(i, intDeque[i]);
	}
	for(int i = 0; i < size; i++){
		int* result = intDeque.search(i, compareInt);
		TestEquals(i, *result);
	}
}
//------------------------------------------------------------------------------
// Intの比較
int DequeTest::compareInt(const int* left, const int* right){
	return (*left) - (*right);
}
//------------------------------------------------------------------------------
