//------------------------------------------------------------------------------
// 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/Primitive/BitSetTest.h"
#include "Core/Primitive/BitSet.h"

//------------------------------------------------------------------------------
// コンストラクタ
BitSetTest::BitSetTest(String name) : TestCase(name){
}
//------------------------------------------------------------------------------
// テストスィートの取得
Test* BitSetTest::suite(){
	TestSuite* suite = new TestSuite("BitSetTest");
	suite->addTest(new TestCaller(BitSetTest, testUChar));
	suite->addTest(new TestCaller(BitSetTest, testUShort));
	suite->addTest(new TestCaller(BitSetTest, testUInt));
	return suite;
}
//------------------------------------------------------------------------------
// u_charテスト
void BitSetTest::testUChar(){
	TestEquals(1, (int)sizeof(BitSet<u_char>));
	// コンストラクタ
	BitSet<u_char> bitSet0;
	int length = bitSet0.getLength();
	TestEquals(8, length);
	TestEquals(0, bitSet0.getBits());
	BitSet<u_char> bitSet1(0xFF);
	TestEquals(0xFF, bitSet1.getBits());
	bitSet0 = bitSet1;
	TestEquals(0xFF, bitSet0.getBits());
	bitSet0.clear();
	TestEquals(0x00, bitSet0.getBits());
	bitSet0.setBits(0x0F);
	TestEquals(0x0F, bitSet0.getBits());
	// 全ビットに対する操作
	bitSet0.not();
	TestEquals(0xF0, bitSet0.getBits());
	bitSet0.onAllBits();
	TestEquals(0xFF, bitSet0.getBits());
	bitSet0.offAllBits();
	TestEquals(0x00, bitSet0.getBits());
	bitSet0.setAllBits(true);
	TestEquals(0xFF, bitSet0.getBits());
	// ビットセットによるビット操作
	bitSet1.setBits(0x0F);
	TestEquals(0x0F, bitSet0.and(bitSet1).getBits());
	bitSet1.setBits(0xF0);
	TestEquals(0xFF, bitSet0.or(bitSet1).getBits());
	TestEquals(0x0F, bitSet0.xor(bitSet1).getBits());
	TestEquals(0xFF, bitSet0.onBit(bitSet1).getBits());
	TestEquals(0x0F, bitSet0.offBit(bitSet1).getBits());
	TestEquals(0xFF, bitSet0.setBit(bitSet1, true).getBits());
	TestAssert(bitSet0.getBit(bitSet1));
	// ビット列によるビット操作
	TestEquals(0x0F, bitSet0.and(0x0F).getBits());
	TestEquals(0xFF, bitSet0.or(0xF0).getBits());
	TestEquals(0x0F, bitSet0.xor(0xF0).getBits());
	TestEquals(0xFF, bitSet0.onBit(0xF0).getBits());
	TestEquals(0x0F, bitSet0.offBit(0xF0).getBits());
	TestEquals(0xFF, bitSet0.setBit(0xF0, true).getBits());
	TestAssert(bitSet0.getBit(0xF0));
	// インデックスによるビット操作
	bitSet0.clear();
	for(int i = 0; i < length; i++){
		u_char indexBit = (0x1 << i);
		TestAssert(bitSet0.onIndexedBit(i).getBit(indexBit));
		TestAssert(!bitSet0.offIndexedBit(i).getBit(indexBit));
		TestAssert(bitSet0.setIndexedBit(i, true).getBit(indexBit));
		TestAssert(bitSet0.getIndexedBit(i));
	}
	// 文字列のテスト
	bitSet0.setBits(0xF0);
	TestEquals("11110000", bitSet0.toString());
}
//------------------------------------------------------------------------------
// u_shortテスト
void BitSetTest::testUShort(){
	TestEquals(2, (int)sizeof(BitSet<u_short>));
	// コンストラクタ
	BitSet<u_short> bitSet0;
	int length = bitSet0.getLength();
	TestEquals(16, length);
	TestEquals(0, bitSet0.getBits());
	BitSet<u_short> bitSet1(0xFFFF);
	TestEquals(0xFFFF, bitSet1.getBits());
	bitSet0 = bitSet1;
	TestEquals(0xFFFF, bitSet0.getBits());
	bitSet0.clear();
	TestEquals(0x0000, bitSet0.getBits());
	bitSet0.setBits(0x00FF);
	TestEquals(0x00FF, bitSet0.getBits());
	// 全ビットに対する操作
	bitSet0.not();
	TestEquals(0xFF00, bitSet0.getBits());
	bitSet0.onAllBits();
	TestEquals(0xFFFF, bitSet0.getBits());
	bitSet0.offAllBits();
	TestEquals(0x0000, bitSet0.getBits());
	bitSet0.setAllBits(true);
	TestEquals(0xFFFF, bitSet0.getBits());
	// ビットセットによるビット操作
	bitSet1.setBits(0x00FF);
	TestEquals(0x00FF, bitSet0.and(bitSet1).getBits());
	bitSet1.setBits(0xFF00);
	TestEquals(0xFFFF, bitSet0.or(bitSet1).getBits());
	TestEquals(0x00FF, bitSet0.xor(bitSet1).getBits());
	TestEquals(0xFFFF, bitSet0.onBit(bitSet1).getBits());
	TestEquals(0x00FF, bitSet0.offBit(bitSet1).getBits());
	TestEquals(0xFFFF, bitSet0.setBit(bitSet1, true).getBits());
	TestAssert(bitSet0.getBit(bitSet1));
	// ビット列によるビット操作
	TestEquals(0x00FF, bitSet0.and(0x00FF).getBits());
	TestEquals(0xFFFF, bitSet0.or(0xFF00).getBits());
	TestEquals(0x00FF, bitSet0.xor(0xFF00).getBits());
	TestEquals(0xFFFF, bitSet0.onBit(0xFF00).getBits());
	TestEquals(0x00FF, bitSet0.offBit(0xFF00).getBits());
	TestEquals(0xFFFF, bitSet0.setBit(0xFF00, true).getBits());
	TestAssert(bitSet0.getBit(0xFF00));
	// インデックスによるビット操作
	bitSet0.clear();
	for(int i = 0; i < length; i++){
		u_short indexBit = (0x1 << i);
		TestAssert(bitSet0.onIndexedBit(i).getBit(indexBit));
		TestAssert(!bitSet0.offIndexedBit(i).getBit(indexBit));
		TestAssert(bitSet0.setIndexedBit(i, true).getBit(indexBit));
		TestAssert(bitSet0.getIndexedBit(i));
	}
	// 文字列のテスト
	bitSet0.setBits(0xFF00);
	TestEquals("1111111100000000", bitSet0.toString());
}
//------------------------------------------------------------------------------
// u_intテスト
void BitSetTest::testUInt(){
	TestEquals(4, (int)sizeof(BitSet<u_int>));
	// コンストラクタ
	BitSet<u_int> bitSet0;
	int length = bitSet0.getLength();
	TestEquals(32, length);
	TestEquals(0u, bitSet0.getBits());
	BitSet<u_int> bitSet1(0xFFFFFFFF);
	TestEquals(0xFFFFFFFF, bitSet1.getBits());
	bitSet0 = bitSet1;
	TestEquals(0xFFFFFFFF, bitSet0.getBits());
	bitSet0.clear();
	TestEquals(0x00000000u, bitSet0.getBits());
	bitSet0.setBits(0x0000FFFF);
	TestEquals(0x0000FFFFu, bitSet0.getBits());
	// 全ビットに対する操作
	bitSet0.not();
	TestEquals(0xFFFF0000, bitSet0.getBits());
	bitSet0.onAllBits();
	TestEquals(0xFFFFFFFF, bitSet0.getBits());
	bitSet0.offAllBits();
	TestEquals(0x00000000u, bitSet0.getBits());
	bitSet0.setAllBits(true);
	TestEquals(0xFFFFFFFF, bitSet0.getBits());
	// ビットセットによるビット操作
	bitSet1.setBits(0x0000FFFF);
	TestEquals(0x0000FFFFu, bitSet0.and(bitSet1).getBits());
	bitSet1.setBits(0xFFFF0000);
	TestEquals(0xFFFFFFFF, bitSet0.or(bitSet1).getBits());
	TestEquals(0x0000FFFFu, bitSet0.xor(bitSet1).getBits());
	TestEquals(0xFFFFFFFF, bitSet0.onBit(bitSet1).getBits());
	TestEquals(0x0000FFFFu, bitSet0.offBit(bitSet1).getBits());
	TestEquals(0xFFFFFFFF, bitSet0.setBit(bitSet1, true).getBits());
	TestAssert(bitSet0.getBit(bitSet1));
	// ビット列によるビット操作
	TestEquals(0x0000FFFFu, bitSet0.and(0x0000FFFF).getBits());
	TestEquals(0xFFFFFFFF, bitSet0.or(0xFFFF0000).getBits());
	TestEquals(0x0000FFFFu, bitSet0.xor(0xFFFF0000).getBits());
	TestEquals(0xFFFFFFFF, bitSet0.onBit(0xFFFF0000).getBits());
	TestEquals(0x0000FFFFu, bitSet0.offBit(0xFFFF0000).getBits());
	TestEquals(0xFFFFFFFF, bitSet0.setBit(0xFFFF0000, true).getBits());
	TestAssert(bitSet0.getBit(0xFFFF0000));
	// インデックスによるビット操作
	bitSet0.clear();
	for(int i = 0; i < length; i++){
		u_int indexBit = (0x1 << i);
		TestAssert(bitSet0.onIndexedBit(i).getBit(indexBit));
		TestAssert(!bitSet0.offIndexedBit(i).getBit(indexBit));
		TestAssert(bitSet0.setIndexedBit(i, true).getBit(indexBit));
		TestAssert(bitSet0.getIndexedBit(i));
	}
	// 文字列のテスト
	bitSet0.setBits(0xFFFF0000);
	TestEquals("11111111111111110000000000000000", bitSet0.toString());
}
//------------------------------------------------------------------------------
