/*==========================================================================*\
| $Id: GraphicTestCase.java,v 1.3 2010/06/01 12:23:39 fr3lm0 Exp $
|*-------------------------------------------------------------------------*|
| Copyright (C) 2007-2010 Virginia Tech
|
| This file is part of the Student-Library.
|
| The Student-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 3 of the
| License, or (at your option) any later version.
|
| The Student-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 the Student-Library; if not, see <http://www.gnu.org/licenses/>.
\*==========================================================================*/
package student;
import acm.graphics.GCanvas;
import acm.graphics.GObject;
import acm.program.GraphicsProgram;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import junit.framework.Assert;
import student.testingsupport.GObjectFilter;
//-------------------------------------------------------------------------
/**
* This class provides enhancements to {@link GUITestCase} to support
* testing of ACM graphics programs that use {@link GObject} instances.
*
* @author Stephen Edwards
* @author Last changed by $Author: fr3lm0 $
* @version $Revision: 1.3 $, $Date: 2010/06/01 12:23:39 $
*/
public class GraphicTestCase
extends GUITestCase
{
//~ Constants .............................................................
/**
* This field re-exports the <code>where</code> operator from
* {@link student.testingsupport.GObjectFilter} so that it is available
* in test methods without requiring a static import.
*/
public final GObjectFilter.Operator where =
GObjectFilter.ClientImports.where;
//~ Constructors ..........................................................
// ----------------------------------------------------------
/**
* Creates a new GraphicTestCase object.
*/
public GraphicTestCase()
{
super();
}
// ----------------------------------------------------------
/**
* Creates a new GraphicTestCase object.
* @param name The name of this test case.
*/
public GraphicTestCase(String name)
{
super(name);
}
//~ Public Methods ........................................................
// ----------------------------------------------------------
/**
* Look up a {@link GObject} on the canvas of the {@link GraphicsProgram}
* being tested by specifying its class. This method expects the given
* class to identify a unique GObject, meaning that there should only
* be one instance of the given class on the canvas.
* If no matching GObject exists, the test case will fail with an
* appropriate message. If more than one matching GObject exists,
* the test case will fail with an appropriate message.
*
* @param <T> This method is a template method, and the type T used for
* the return value is implicitly deduced from the provided
* argument <code>type</code>.
* @param type The type (class) of the GObject you wish to retrieve, and
* also the way you specify the return type of this method.
* @return The single instance of the desired type that was found
* (otherwise, a test case failure results).
* @see #getFirstGObjectMatching(Class)
* @see #getAllGObjectsMatching(Class)
*/
public <T extends GObject> T getGObject(Class<T> type)
{
@SuppressWarnings("unchecked")
T result = (T)getGObject(where.typeIs(type));
return result;
}
// ----------------------------------------------------------
/**
* Look up a {@link GObject} on the canvas of the {@link GraphicsProgram}
* being tested by specifying its class and a {@link GObjectFilter}.
* This method expects exactly one GObject to match your criteria.
* If no matching GObjecty exists, the test case will fail with an
* appropriate message. If more than one matching GObject exists,
* the test case will fail with an appropriate message.
*
* @param <T> This method is a template method, and the type T used for
* the return value is implicitly deduced from the provided
* argument <code>type</code>.
* @param type The type (class) of the GObject you wish to retrieve, and
* also the way you specify the return type of this method.
* @param filter The search criteria.
* @return The single GObject matching the criteria specified
* (otherwise, a test case failure results).
* @see #getFirstGObjectMatching(Class, GObjectFilter)
* @see #getAllGObjectsMatching(Class, GObjectFilter)
*/
public <T extends GObject> T getGObject(Class<T> type, GObjectFilter filter)
{
@SuppressWarnings("unchecked")
T result = (T)getGObject(filter.and.typeIs(type));
return result;
}
// ----------------------------------------------------------
/**
* Look up a {@link GObject} on the canvas of the {@link GraphicsProgram}
* being tested, using a filter to specify which GObject you want. This
* method is more general than {@link #getGObject(Class, GObjectFilter)},
* since no class needs to be specified, but that also means the return
* type is less specific (it is always <code>GObject</code>).
* This method expects the given filter to identify a unique GObject. If
* no matching GObject exists, the test case will fail with an appropriate
* message. If more than one matching GObject exists, the test case will
* fail with an appropriate message.
*
* @param filter The search criteria.
* @return The single GObject matching the provided filter (otherwise, a
* test case failure results).
* @see #getFirstGObjectMatching(GObjectFilter)
* @see #getAllGObjectsMatching(GObjectFilter)
*/
public GObject getGObject(GObjectFilter filter)
{
List<GObject> gobjs = getAllGObjectsMatching(filter);
if (gobjs.size() == 0)
{
Assert.fail("Cannot find GObject matching: " + filter);
}
else if (gobjs.size() > 1)
{
Assert.fail(
"Found " + gobjs.size() + " GObjects matching: " + filter);
}
return gobjs.get(0);
}
// ----------------------------------------------------------
/**
* Look up a {@link GObject} on the canvas of the {@link GraphicsProgram}
* being tested by specifying its class.
* This method expects the given class to identify at least one such
* GObject. If no matching GObject exists, the test case will fail
* with an appropriate message. If more than one matching GObject
* exists, the first one found will be returned (although client code
* should not expect a specific search order).
*
* @param <T> This method is a template method, and the type T used for
* the return value is implicitly deduced from the provided
* argument <code>type</code>.
* @param type The type (class) of the GObject you wish to retrieve, and
* also the way you specify the return type of this method.
* @return The first GObject of the desired type that was found
* (a test case failure results if there are none).
* @see #getGObject(Class)
* @see #getAllGObjectsMatching(Class)
*/
public <T extends GObject> T getFirstGObjectMatching(Class<T> type)
{
@SuppressWarnings("unchecked")
T result = (T)getFirstGObjectMatching(where.typeIs(type));
return result;
}
// ----------------------------------------------------------
/**
* Look up a {@link GObject} on the canvas of the {@link GraphicsProgram}
* being tested by specifying its class and a {@link GObjectFilter}.
* This method expects the given criteria to identify at least one such
* GObject. If no matching GObject exists, the test case will fail
* with an appropriate message. If more than one matching GObject
* exists, the first one found will be returned (although client code
* should not expect a specific search order).
*
* @param <T> This method is a template method, and the type T used for
* the return value is implicitly deduced from the provided
* argument <code>type</code>.
* @param type The type (class) of the GObject you wish to retrieve, and
* also the way you specify the return type of this method.
* @param filter The search criteria.
* @return The first GObject that was found matching the criteria
* specified (a test case failure results if there are none).
* @see #getGObject(Class, GObjectFilter)
* @see #getAllGObjectsMatching(Class, GObjectFilter)
*/
public <T extends GObject> T getFirstGObjectMatching(
Class<T> type, GObjectFilter filter)
{
@SuppressWarnings("unchecked")
T result = (T)getFirstGObjectMatching(filter.and.typeIs(type));
return result;
}
// ----------------------------------------------------------
/**
* Look up a {@link GObject} on the canvas of the {@link GraphicsProgram}
* being tested by specifying a {@link GObjectFilter}.
* This method is more general
* than {@link #getFirstGObjectMatching(Class, GObjectFilter)}, since no
* class needs to be specified, but that also means the return type
* is less specific (it is always <code>GObject</code>).
* This method expects the given criteria to identify at least one such
* GObject. If no matching GObject exists, the test case will fail
* with an appropriate message. If more than one matching GObject
* exists, the first one found will be returned (although client code
* should not expect a specific search order).
*
* @param filter The search criteria.
* @return The first GObject that was found matching the criteria
* specified (a test case failure results if there are none).
* @see #getGObject(GObjectFilter)
* @see #getAllGObjectsMatching(GObjectFilter)
*/
public GObject getFirstGObjectMatching(GObjectFilter filter)
{
Iterator<GObject> iter = getCanvas().iterator();
while (iter.hasNext())
{
GObject gobj = iter.next();
if (filter.test(gobj))
{
return gobj;
}
}
fail("Cannot find GObject matching: " + filter);
return null;
}
// ----------------------------------------------------------
/**
* Look up all {@link GObject}s on the canvas of the
* {@link GraphicsProgram} being tested by specifying their
* class. All matching objects are returned in a list.
*
* @param <T> This method is a template method, and the type T used as
* the <code>List</code> element type in
* the return value is implicitly deduced from the provided
* argument <code>type</code>.
* @param type The type (class) of the GObjects you wish to retrieve,
* and also the way you specify the type of elements in
* the list returned by this method.
* @return A list of all GObjects of the desired type that were found.
* This will be an empty list (not null) if no matching GObjects
* are found.
* @see #getGObject(Class)
* @see #getFirstGObjectMatching(Class)
*/
public <T extends GObject> List<T> getAllGObjectsMatching(Class<T> type)
{
@SuppressWarnings("unchecked")
List<T> result =
(List<T>)getAllGObjectsMatching(where.typeIs(type));
return result;
}
// ----------------------------------------------------------
/**
* Look up all {@link GObject}s on the canvas of the
* {@link GraphicsProgram} being tested by specifying their
* class and a {@link GObjectFilter}. All matching objects are returned in
* a list.
* @param <T> This method is a template method, and the type T used as
* the <code>List</code> element type in
* the return value is implicitly deduced from the provided
* argument <code>type</code>.
* @param type The type (class) of the GObjects you wish to retrieve,
* and also the way you specify the type of elements in
* the list returned by this method.
* @param filter The search criteria.
* @return A list of all GObjects found matching the criteria specified.
* This will be an empty list (not null) if no matching GObjects
* are found.
* @see #getGObject(Class,GObjectFilter)
* @see #getAllGObjectsMatching(Class, GObjectFilter)
*/
public <T extends GObject> List<T> getAllGObjectsMatching(
Class<T> type, GObjectFilter filter)
{
@SuppressWarnings("unchecked")
List<T> result =
(List<T>)getAllGObjectsMatching(filter.and.typeIs(type));
return result;
}
// ----------------------------------------------------------
/**
* Look up all {@link GObject}s on the canvas of the
* {@link GraphicsProgram} being tested by specifying
* a {@link GObjectFilter}.
* All matching objects are returned in a list.
* This method is more general than
* {@link #getAllGObjectsMatching(Class, GObjectFilter)}, since no
* class needs to be specified, but that also means the return type
* is less specific (it is always <code>List<GObject></code>).
*
* @param filter The search criteria.
* @return A list of all GObjects found matching the criteria specified.
* This will be an empty list (not null) if no matching GObjects
* are found.
* @see #getGObject(GObjectFilter)
* @see #getAllGObjectsMatching(GObjectFilter)
*/
public List<GObject> getAllGObjectsMatching(GObjectFilter filter)
{
ArrayList<GObject> matches = new ArrayList<GObject>();
Iterator<GObject> iter = getCanvas().iterator();
while (iter.hasNext())
{
GObject gobj = iter.next();
if (filter.test(gobj))
{
matches.add(gobj);
}
}
return matches;
}
//~ Protected Methods/Declarations ........................................
// ----------------------------------------------------------
/**
* Retrieve the {@link GCanvas} object associated
* with the {@link GraphicsProgram} being tested.
*
* @return The GCanvas containing all of the GraphicsProgram's GObjects.
*/
protected GCanvas getCanvas()
{
return getComponent(GCanvas.class);
}
}