/**
* EtherStrategy: A simulation of space and interstellar civilization.
*
* Copyright * (C) 2007 Wayne Witzke
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program 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 General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* (COPYING.txt) along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* To contact the author of EtherStrategy, send e-mail to wwitzke at
* users.sourceforge.net
*/
package etherstrategy.simulation;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
import java.util.LinkedList;
import java.lang.NullPointerException;
import java.lang.reflect.InvocationTargetException;
import java.util.NoSuchElementException;
import etherstrategy.simulation.TestUElement;
import com.jme.math.Vector3f;
import java.util.Arrays;
/**
* TestUElementTest is a set of tests that is primarily designed to test the
* UniverseElement methods. UniverseElement is abstract (to prevent type
* information from being lost for used elements through carelessness, or idiocy),
* so this set of tests uses the derived class TestUElement, which has no, or at
* least very few, members of its own.
*
* There is potential for confusion here, but all tests on TestUElement are, in
* fact, tests for UniverseElement. The terms could almost be used
* interchangeably in this set of tests (and probably are several times).
*
* TODO: Lots of redundancy here(?) Should reduce it eventually.
*
* @author Wayne Witzke
*/
public class TestUElementTest
{
TestUElement testElement;
/**
* TestA is an empty class that will be used to insure that the type of the
* UniverseElement is being considered where appropriate in the various
* UniverseElement methods.
*
* @author Wayne Witzke
*
*/
public static class TestA extends UniverseElement
{
public TestA()
{
}
public TestA( TestA toBeCopied )
throws NoSuchMethodException, IllegalAccessException,
InstantiationException, InvocationTargetException
{
super( toBeCopied );
}
}
/**
* TestB is like TestA, but will present as a different type.
* @author Wayne Witzke
*
*/
public static class TestB extends UniverseElement
{
public TestB()
{
}
public TestB( TestB toBeCopied )
throws NoSuchMethodException, IllegalAccessException,
InstantiationException, InvocationTargetException
{
super( toBeCopied );
}
}
/**
* TestC is like TestA, but will present as a different type.
* @author Wayne Witzke
*
*/
public static class TestC extends UniverseElement
{
public TestC()
{
}
public TestC( TestC toBeCopied )
throws NoSuchMethodException, IllegalAccessException,
InstantiationException, InvocationTargetException
{
super( toBeCopied );
}
}
/**
* TestDerivedFromC is like TestA, but is derived from TestC and will present
* as a different type with a different supertype.
* @author Wayne Witzke
*
*/
public static class TestDerivedFromC extends TestC
{
public TestDerivedFromC()
{
}
public TestDerivedFromC( TestDerivedFromC toBeCopied )
throws NoSuchMethodException, IllegalAccessException,
InstantiationException, InvocationTargetException
{
super( toBeCopied );
}
}
/**
* It would be a drag to create a new test element for every single test, so
* we'll do it once here. In theory, this should take the place of any
* constructor test for TestUElement.
*
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception
{
testElement = new TestUElement();
assertNotNull( "A newly constructed test element should not be null",
testElement );
}
/**
* This will nullify the test element for the next test. May not be necessary.
*
* @throws java.lang.Exception
*/
@After
public void tearDown() throws Exception
{
testElement = null;
}
/**
* For UniverseElements, the similar method will insure that the (significant)
* data members are the same for two otherwise different UniverseElements.
* This is different from ==, or even equals() when applied to
* UniverseElements, since two UniverseElements can only be equal if they are,
* in fact, the same object.
*
* @throws Exception
*/
@Test
public void compareBlankUniverseElements() throws Exception
{
TestUElement testElement2 = new TestUElement();
assertTrue(
"Two UniverseElements created with a default constructor should be similar, but are not",
testElement.similar( testElement2 ) );
}
/**
* Here we just want to make sure that we can get an iterator back from a
* UniverseElement. If this doesn't work, then the constructor for the
* iterator, or the iterator accessor function, are broken. The Iterator for
* a UniverseElement is very basic, since a basic UniverseElement is a
* collection that is always empty.
*
* @throws Exception
*/
@Test
public void constructUniverseElementIterator() throws Exception
{
UniverseElement.Iterator testIterator = null;
try
{
testIterator = testElement.iterator();
}
catch ( Exception e )
{
fail("Creating a UniverseElement iterator should not throw an exception.");
}
assertNotNull(
"After constructing an iterator, the variable storing the iterator should not be null.",
testIterator );
}
/**
* UniverseElements have the potential to be composite entities, and the
* various collection-style methods must be declared as part of the abstract
* class. However, they also have the potential to be primitives, and so the
* abstract class should provide a default, primitive implementation of these
* methods. Included in these are the methods to determine if a composite
* UniverseElement is empty, and to determine the size of a composite
* UniverseElement. These methods should always return false and 0 for a
* primitive UniverseElement.
*/
@Test
public void accessElementsInEmptyUniverseElement() throws Exception
{
assertEquals(
"A primitive UniverseElement should always have a zero count of elements.",
testElement.size(), 0 );
assertTrue( "A primitive UniverseElement should always be empty.",
testElement.isEmpty() );
}
/**
* Another method that must be present for the sake of derived composite
* UniverseElements, but must have a default primitive implementation, is the
* add() method. For primitives, it should always return false and have no
* side effects.
*/
@Test
public void addTestElementsToUniverseElement() throws Exception
{
TestUElement testElementToAdd = new TestUElement();
TestUElement emptyTestElement = new TestUElement();
assertFalse(
"Prior to adding a UniverseElement to another UniverseElement, the potential child UniverseElement should not report itself as being contained within another UniverseElement",
testElementToAdd.isContained() );
assertFalse(
"Adding a UniverseElement to an empty, primitive UniverseElement should return false, since primitive UniverseElements cannot have child elements.",
testElement.add( testElementToAdd ) );
assertTrue(
"A primitive UniverseElement that has had an element added should still be equal to a primitive UniverseElement that has no children, since primitive Universe Elements cannot have children.",
testElement.similar( emptyTestElement ) );
assertTrue(
"A UniverseElement that has an element added should still be marked as empty.",
testElement.isEmpty() );
assertEquals(
"A UniverseElement that has had exactly one element added should report a size of zero (can't have children).",
testElement.size(), 0 );
assertFalse(
"Having attempted to add one primitive UniverseElement to another, the added element should be reported itself as not being contained by another UniverseElement class (primitives cannot have children).",
testElementToAdd.isContained() );
}
/**
* Another method that must be available to composite UniverseElements is
* contains(). A primitive UniverseElement never contains another
* UniverseElement. Ever.
*
* @throws Exception
*/
@Test
public void checkIfElementInUniverseElement() throws Exception
{
TestUElement element1 = new TestUElement();
TestUElement element2 = new TestUElement();
TestUElement element3 = new TestUElement();
TestUElement elementNotAdded = new TestUElement();
testElement.add(element1);
testElement.add( element2 );
testElement.add(element3);
assertEquals("Having added three elements to a primitive UniverseElement, the size of the UniverseElement should be 0 (can't contain children).",
testElement.size(), 0 );
assertFalse("If we've added an element to a primitive UniverseElement, then we should get \"false\" when we ask UniverseElement if it contains that element, since a primitive UniverseElement cannot contain other elements.",
testElement.contains( element1 ) );
assertFalse("A primitive UniverseElement should return false for any element added to it when asked if it contains that element.",
testElement.contains( element2 )
&& testElement.contains( element3 ) );
assertFalse("A primitive UniverseElement should return false when asked if it contains an element that was never added to the UniverseElement.",
testElement.contains( elementNotAdded ) );
}
/**
* This checks to insure that contains() returns false for null references
* as well as for other references.
* @throws Exception
*/
@Test
public void checkIfNullInUniverseElement() throws Exception
{
assertFalse(
"A primitive UniverseElement can never contain a null (or anything else for that matter), and when asked if it does, it should always return false.",
testElement.contains( null ) );
}
/**
* This test will insure that two UniverseElements don't compare as similar
* when the data members of the two elements are not, in fact, the same.
* @throws Exception
*/
@Test
public void similarityForUniverseElementWithVariousSetsOfMemberData() throws Exception
{
TestUElement elementToCompare = new TestUElement();
testElement.setCenter( 1, 1, 1 );
assertFalse(
"A newly created UniverseElement with no members should not be similar to an empty UniverseElement where the center has been changed so that it is not (0, 0, 0).",
testElement.similar( elementToCompare ) );
elementToCompare.setCenter( 2, 2, 2 );
assertFalse(
"Two empty UniverseElements that have had their centers set to different values should not be similar.",
testElement.similar( elementToCompare ) );
elementToCompare.setCenter( 1, 1, 1 );
assertTrue(
"Two empty UniverseElements that have had their centers set to the same value, and have all other members the same, should be similar.",
testElement.similar( elementToCompare ) );
}
/**
* We need to make sure that attempting to check the similarity between a
* UniverseElement and a null pointer throws a null pointer exception.
*
* @throws Exception
*/
@Test ( expected = NullPointerException.class )
public void similartyBetweenNullAndUniverseElement() throws Exception
{
assertFalse(
"A UniverseElement should not be similar to a null reference.",
testElement.similar( null ) );
}
/**
* remove() is another composite operation that should always just return
* false and have no side effects for a primitive UniverseElement.
*
* @throws Exception
*/
@Test
public void removeFromUniverseElement() throws Exception
{
TestUElement element1 = new TestUElement();
TestUElement element2 = new TestUElement();
TestUElement element3 = new TestUElement();
testElement.add(element1);
testElement.add(element2);
assertFalse(
"Removing an non-existent child from a primitive UniverseElement should return false.",
testElement.remove( element3 ) );
assertFalse(
"Removing an added child element from a primitive UniverseElement should return false (no children allowed).",
testElement.remove( element1 ) );
assertEquals(
"Having removed an added child element from a primitive UniverseElement, the UniverseElement should still have a count of 0.",
testElement.size(), 0 );
assertFalse(
"A UniverseElement that has been \"removed\" from a primitive UniverseElement should still not report itself as being contained.",
element1.isContained() );
}
/**
* It should be possible to clear a composite UniverseElement. Similarly, it
* should be possible to clear a primitive UniverseElement. However, the
* primitive UniverseElement will not change as a result to a call to clear().
*
* @throws Exception
*/
@Test
public void clearingUniverseElement() throws Exception
{
testElement.setCenter(1, 1, 1);
testElement.clear();
assertTrue(
"Clearing a primitive UnvierseElement should have no effect on the UniverseElement, including not making the primitive non-empty.",
testElement.isEmpty() );
assertEquals(
"Clearing a primitive UniverseElement should have no effect on the UniverseElement, including not giving it a non-zero size().",
testElement.size(), 0 );
assertEquals(
"Clearing a primitive UniverseElement should have no effect on its data members.",
testElement.getCenter(), new Vector3f(1, 1, 1) );
}
/**
* addAll is yet another method for composite UniverseElements. For
* primitives, it should always return false and have no side effects.
*
* @throws Exception
*/
@Test
public void addingACollectionOfUniverseElementsToAUniverseElement() throws Exception
{
LinkedList<UniverseElement> testCollection =
new LinkedList<UniverseElement>();
assertFalse(
"Adding an empty collection to a primitive UniverseElement should return false, since the UniverseElement was not modified.",
testElement.addAll( testCollection ) );
assertTrue(
"Having added an empty collection to a primitive UniverseElement, the UniverseElement should report itself as being empty.",
testElement.isEmpty() );
testCollection.add( new TestA() );
testCollection.add( new TestB() );
testCollection.add( new TestA() );
assertFalse(
"Adding a non-empty collection of UniverseElements to a primitive UniverseElement should return false (children not allowed).",
testElement.addAll( testCollection ) );
assertTrue(
"Having added a non-empty collection of UniverseElements to a primitive UniverseElement, the UniverseElement should continue to report itself as being empty.",
testElement.isEmpty() );
assertEquals(
"Having added a non-empty collection to a primitive UniverseElement, the UniverseElement should still have a size of 0.",
testElement.size(), 0 );
assertFalse(
"Elements added to a primitive UniverseElement through addAll should report themselves as not being contained.",
testCollection.get(0).isContained()
|| testCollection.get(1).isContained()
|| testCollection.get( 2 ).isContained() );
}
/**
* containsAll() is <i>yet another</i> method that is important for composite
* UniverseElements. For primitives, it should always return false, except
* when the passed collection is, itself, empty.
* @throws Exception
*/
@Test
public void checkingUniverseElementContentsUsingContainersOfUniverseElements() throws Exception
{
LinkedList<Object> testCollection =
new LinkedList<Object>();
LinkedList<Object> emptyCollection =
new LinkedList<Object>();
TestUElement element1 = new TestUElement();
TestUElement element2 = new TestUElement();
TestUElement element3 = new TestUElement();
testCollection.add(element1);
testCollection.add(element2);
assertTrue(
"Checking a primitive UniverseElement to see if it contains the elements of an empty collection should return true.",
testElement.containsAll( emptyCollection ) );
assertFalse(
"Checking to see if a UniverseElement contains the elements of a non-empty collection should return false.",
testElement.containsAll( testCollection ) );
testElement.add(element3);
testElement.add( element2 );
assertFalse(
"Checking to see if a primitive UniverseElement which had elements added contains the elements of a non-empty collection should return false regardless of whether the element(s) added were in the collection.",
testElement.containsAll( testCollection ) );
testElement.add( element1 );
assertFalse(
"Checking to see if a primitive UniverseElement contains the elements of a non-empty collection should always return false, even when the UniverseElement had had the elements in the collection specifically added to that UniverseElement.",
testElement.containsAll( testCollection ) );
testCollection.clear();
testCollection.add( null );
assertFalse(
"Checking to see if a primitive UniverseElement contains the elements of a non-empty collection should return false, even if all the elements in the collection are null.",
testElement.containsAll( testCollection ) );
}
/**
* This test insures that trying to compare a collection that is actually a
* null reference to a UniverseElement throws an exception.
* @throws Exception
*/
@Test ( expected = NullPointerException.class )
public void checkingUniverseElementContentsUsingNullCollection() throws Exception
{
testElement.containsAll( null );
}
/**
* removeAll() is important for composite UniverseElements. For primitives,
* it should always return false and have no side effects.
*
* @throws Exception
*/
@Test
public void removingCollectionsOfElementsFromUniverseElement() throws Exception
{
LinkedList<Object> testCollection =
new LinkedList<Object>();
LinkedList<Object> emptyCollection =
new LinkedList<Object>();
TestUElement element1 = new TestUElement();
TestUElement element2 = new TestUElement();
/* By now we've established that adding elements to a primitive
* UniverseElement has no effect. . . We'll leave that part out and just
* do the parts that might possibly have some effect.
*/
testCollection.add(element1);
testCollection.add(element2);
assertFalse(
"Removing an empty collection from a primitive UniverseElement should return false (nothing changed).",
testElement.removeAll( emptyCollection ) );
assertTrue(
"After removing an empty collection from a primitive UniverseElement, the UniverseElement should still be empty.",
testElement.isEmpty() );
assertFalse(
"Removing a non-empty collection from a primitive UniverseElement should return false (nothing changed).",
testElement.removeAll( testCollection ) );
assertTrue(
"After removing a non-empty collection from a primitive UniverseElement, the UnvierseElement should still be empty.",
testElement.isEmpty() );
assertEquals(
"After removing a non-empty collection from a primitive UniverseElement, the UniverseElement should still have a size() of 0.",
testElement.size(), 0 );
}
/**
* retainAll() is only applicable for a composite UniverseElement. For
* primitives it should always return false and have no side effects.
*
* @throws Exception
*/
@Test
public void retainingCollectionsOfElementsInUniverseElement() throws Exception
{
LinkedList<Object> testCollection =
new LinkedList<Object>();
LinkedList<Object> emptyCollection =
new LinkedList<Object>();
TestUElement element1 = new TestUElement();
TestUElement element2 = new TestUElement();
testCollection.add(element1);
testCollection.add(element2);
assertFalse(
"Retaining an empty collection in a primitive UniverseElement should return false (nothing changed).",
testElement.retainAll( emptyCollection ) );
assertTrue(
"After retaining an empty collection in a primitive UniverseElement, the UniverseElement should still be empty.",
testElement.isEmpty() );
assertFalse(
"Retaining a non-empty collection in a primitive UniverseElement should return false (nothing changed).",
testElement.retainAll( testCollection ) );
assertTrue(
"After retaining a non-empty collection in a primitive UniverseElement, the UnvierseElement should still be empty.",
testElement.isEmpty() );
assertEquals(
"After retaining a non-empty collection in a primitive UniverseElement, the UniverseElement should still have a size() of 0.",
testElement.size(), 0 );
}
/**
* This test will make sure that the functions related to center work
* properly.
*
* @throws Exception
*/
@Test
public void settingAndMovingTheCenter() throws Exception
{
Vector3f tempVec;
assertEquals(
"A newly created UniverseElement should have a center at (0, 0, 0).",
testElement.getCenter(), new Vector3f(0, 0, 0) );
testElement.setCenter(1, 2, 3);
assertEquals(
"A UniverseElement that has had its center set to (1, 2, 3) should return a vector with those coordinates when asked for its center.",
testElement.getCenter(), new Vector3f(1, 2, 3) );
tempVec = new Vector3f(5, 6, 7);
testElement.setCenter(tempVec);
assertEquals(
"A UniverseElement that has had its center set to (5, 6, 7) using another vector should return a vector with those coordinates when asked for its center.",
testElement.getCenter(), tempVec );
testElement.move(.5f, 1.5f, -1.5f);
assertEquals(
"A UniverseElement with its center at (5, 6, 7) that has been moved by (.5, 1.5, -1.5) should, after the move, have its center at (5.5, 7.5, 5.5).",
testElement.getCenter(), new Vector3f(5.5f, 7.5f, 5.5f) );
tempVec = new Vector3f(-1, -3f, .5f);
testElement.move(tempVec);
assertEquals(
"A UniverseElement with its center at (5.5, 7.5, 5.5) that has been moved by (-1, -3, .5) using another vector should, after the move, have its center at (4.5, 4.5, 6)",
testElement.getCenter(), new Vector3f(4.5f, 4.5f, 6) );
TestUElement comparisonElement = new TestUElement();
comparisonElement.setCenter( 1, 1, 1 );
assertFalse(
"Two UniverseElements that have different centers but are otherwise similar should not be similar.",
testElement.similar( comparisonElement ) );
comparisonElement.setCenter( testElement.getCenter() );
assertTrue(
"Two UniverseElements that have everything the same, including their centers, should be similar.",
testElement.similar( comparisonElement ) );
}
/**
* toArray() is an important composite UniverseElement member. For primitives
* it should always return an empty array, and should never populate the array
* that was passed to it (except for setting a null as the first element).
* @throws Exception
*/
@Test
public void creatingArraysFromUniverseElements() throws Exception
{
/* By now we know that adding elements to a UniverseElement has no effect,
* so we're skipping that part.
*/
UniverseElement[] UEArray =
{ new TestUElement(), new TestUElement(), new TestUElement(),
new TestUElement(), new TestUElement(), new TestUElement(),
new TestUElement(), new TestUElement(),
};
UniverseElement[] clonedUEArray = UEArray.clone();
UniverseElement[] returnedUEArray;
returnedUEArray = testElement.toArray(UEArray);
assertEquals(
"After creating a UniverseElement array from a primitive UniverseElement, the returned array should be the same size as the UniverseElement (otherwise known as empty).",
returnedUEArray.length, 0 );
assertNull(
"The array that was passed to the array creation method for a primitive UniverseElement should have null as the first element of the array.",
UEArray[0]);
assertEquals(
"The array that was passed to the array creation method for a primitive UniverseElement should, except for the first element, contain all the same elements that it contained before the call.",
Arrays.copyOfRange(UEArray, 1, UEArray.length),
Arrays.copyOfRange(clonedUEArray, 1, clonedUEArray.length) );
try
{
testElement.toArray( null );
fail("Passing a null reference to toArray() should throw an exception, but it did not.");
}
catch ( NullPointerException e )
{
}
catch ( Exception e )
{
fail("Passing a null reference to toArray() should only throw a NullPointerException, but a(n) " + e.getClass().getName() + " was thrown.");
}
try
{
testElement.toArray( new Integer[7] );
fail("Attempting to call toArray() by passing it an array that is not a UniverseElement array (or some derivation thereof) should throw an exception, but did not.");
}
catch ( ArrayStoreException e )
{
}
catch ( Exception e )
{
fail("Attempting to call toArray() by passing it an array that is not a UniverseElement array (or some derivation thereof) should only throw an ArrayStoreException, but a(n) " + e.getClass().getName() + " was thrown.");
}
Object[] objectArray = testElement.toArray();
assertEquals(
"After creating an Object array from a primitive UniverseElement, the resulting object array should be the same size as the UniverseElement (i.e. empty).",
objectArray.length, 0 );
}
/**
* Iterators should work properly for primitives as well as for composite
* UniverseElements. However, for primitives, they should only ever behave as
* though they are operating on an empty collection.
* @throws Exception
*/
@Test
public void creatingAndUsingUniverseElementIterators() throws Exception
{
UniverseElement.Iterator testIter = testElement.iterator();
assertFalse(
"A iterator for a primitive UniverseElement should always report that there is no next element.",
testIter.hasNext() );
try
{
testIter.next();
fail("Attempting to iterate to the next element of a primitive UniverseElement should throw an exception, but did not.");
}
catch ( NoSuchElementException e )
{
}
catch ( Exception e )
{
fail("Attempting to iterate to the next element of a primitive UniverseElement should only throw a NoSuchElementException, but a(n) " + e.getClass().getName() + " was thrown.");
}
try
{
testIter.remove();
fail("Attempting to call remove() on the iterator of a primitive UniverseElement should throw an exception, but did not.");
}
catch ( IllegalStateException e )
{
}
catch ( Exception e )
{
fail("Attempting to call remove() on the iterator of a primitive UniverseElement should only throw an IllegalStateException, but a(n) " + e.getClass().getName() + " was thrown.");
}
}
/**
* This method will test the copy constructor for UniverseElement. There is
* really only one condition that the copy constructor has to obey: the
* resulting copy should be similar() to the original.
* @throws Exception
*/
@Test
public void copyingUniverseElements() throws Exception
{
testElement.setCenter( 1, 2, 3 );
TestUElement copiedElement = new TestUElement(testElement);
assertNotNull(
"After creating a new UnvierseElement through a copy constructor, the new UniverseElement should not be null.",
copiedElement );
assertTrue(
"After creating a new UnvierseElement through a copy constructor, the copy should be similar to the original.",
testElement.similar( copiedElement ) );
assertEquals(
"After creating a new UniverseElement through a copy constructor, the centers of the two element should be equal.",
testElement.getCenter(), copiedElement.getCenter() );
testElement.setCenter( 1, 1, 1 );
assertFalse(
"After creating a new UniverseElement through a copy constructor and then changing the center of the original UniverseElement, the centers of the two elements should not be equal.",
testElement.getCenter() == copiedElement.getCenter() );
}
/**
* Okay, this test is over-the-top, crazy unnecessary, but I'm putting it in
* anyway, just in case.
* @throws Exception
*/
@Test
public void checkingForUniverseElementLeafState() throws Exception
{
assertTrue(
"UniverseElements that do not override isLeaf() should always return true when that method is called.",
(new TestUElement()).isLeaf()
&& (new TestA()).isLeaf()
&& (new TestB()).isLeaf()
&& (new TestC()).isLeaf()
&& (new TestDerivedFromC()).isLeaf() );
}
}