mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-28 02:11:43 +00:00
Applies Google Styleguide to Java parts of the library (#23)
This was partially applied to simulation but simulation is a bit of a mess and has a lot of duplicated code.
This commit is contained in:
committed by
Peter Johnson
parent
64ab6e51fe
commit
a834fff7b2
@@ -7,15 +7,15 @@
|
||||
|
||||
package edu.wpi.first.wpilibj.test;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Rule;
|
||||
import org.junit.rules.TestWatcher;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.MultipleFailureException;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import edu.wpi.first.wpilibj.DriverStation;
|
||||
import edu.wpi.first.wpilibj.RobotBase;
|
||||
import edu.wpi.first.wpilibj.Timer;
|
||||
@@ -23,16 +23,18 @@ import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary;
|
||||
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
|
||||
|
||||
/**
|
||||
* This class serves as a superclass for all tests that involve the hardware on
|
||||
* the roboRIO. It uses an {@link BeforeClass} statement to initialize network
|
||||
* communications. Any test that needs to use the hardware <b>MUST</b> extend
|
||||
* from this class, to ensure that all of the hardware will be able to run.
|
||||
*$
|
||||
* This class serves as a superclass for all tests that involve the hardware on the roboRIO. It uses
|
||||
* an {@link BeforeClass} statement to initialize network communications. Any test that needs to use
|
||||
* the hardware <b>MUST</b> extend from this class, to ensure that all of the hardware will be able
|
||||
* to run.
|
||||
*
|
||||
* @author Fredric Silberberg
|
||||
* @author Jonathan Leitschuh
|
||||
*/
|
||||
public abstract class AbstractComsSetup {
|
||||
/** Stores whether network coms have been initialized */
|
||||
/**
|
||||
* Stores whether network coms have been initialized.
|
||||
*/
|
||||
private static boolean initialized = false;
|
||||
|
||||
/**
|
||||
@@ -40,7 +42,6 @@ public abstract class AbstractComsSetup {
|
||||
* station. After starting network coms, it will loop until the driver station
|
||||
* returns that the robot is enabled, to ensure that tests will be able to run
|
||||
* on the hardware.
|
||||
*$
|
||||
*/
|
||||
static {
|
||||
if (!initialized) {
|
||||
@@ -52,15 +53,15 @@ public abstract class AbstractComsSetup {
|
||||
TestBench.out().println("Started coms");
|
||||
|
||||
// Wait until the robot is enabled before starting the tests
|
||||
int i = 0;
|
||||
int enableCounter = 0;
|
||||
while (!DriverStation.getInstance().isEnabled()) {
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
// Prints the message on one line overwriting itself each time
|
||||
TestBench.out().print("\rWaiting for enable: " + i++);
|
||||
TestBench.out().print("\rWaiting for enable: " + enableCounter++);
|
||||
}
|
||||
TestBench.out().println();
|
||||
|
||||
@@ -74,8 +75,7 @@ public abstract class AbstractComsSetup {
|
||||
protected abstract Logger getClassLogger();
|
||||
|
||||
/**
|
||||
* This causes a stack trace to be printed as the test is running as well as
|
||||
* at the end
|
||||
* This causes a stack trace to be printed as the test is running as well as at the end.
|
||||
*/
|
||||
@Rule
|
||||
public final TestWatcher getTestWatcher() {
|
||||
@@ -83,8 +83,8 @@ public abstract class AbstractComsSetup {
|
||||
}
|
||||
|
||||
/**
|
||||
* Given as a way to provide a custom test watcher for a test or set of tests
|
||||
*$
|
||||
* Given as a way to provide a custom test watcher for a test or set of tests.
|
||||
*
|
||||
* @return the test watcher to use
|
||||
*/
|
||||
protected TestWatcher getOverridenTestWatcher() {
|
||||
@@ -93,68 +93,69 @@ public abstract class AbstractComsSetup {
|
||||
|
||||
protected class DefaultTestWatcher extends TestWatcher {
|
||||
/**
|
||||
* Allows a failure to supply a custom status message to be displayed along
|
||||
* with the stack trace.
|
||||
* Allows a failure to supply a custom status message to be displayed along with the stack
|
||||
* trace.
|
||||
*/
|
||||
protected void failed(Throwable e, Description description, String status) {
|
||||
protected void failed(Throwable throwable, Description description, String status) {
|
||||
TestBench.out().println();
|
||||
// Instance of is the best way I know to retrieve this data.
|
||||
if (e instanceof MultipleFailureException) {
|
||||
if (throwable instanceof MultipleFailureException) {
|
||||
/*
|
||||
* MultipleFailureExceptions hold multiple exceptions in one exception.
|
||||
* In order to properly display these stack traces we have to cast the
|
||||
* throwable and work with the list of thrown exceptions stored within
|
||||
* it.
|
||||
*/
|
||||
int i = 1; // Running exception count
|
||||
int failureCount = ((MultipleFailureException) e).getFailures().size();
|
||||
for (Throwable singleThrown : ((MultipleFailureException) e).getFailures()) {
|
||||
int exceptionCount = 1; // Running exception count
|
||||
int failureCount = ((MultipleFailureException) throwable).getFailures().size();
|
||||
for (Throwable singleThrown : ((MultipleFailureException) throwable).getFailures()) {
|
||||
getClassLogger().logp(
|
||||
Level.SEVERE,
|
||||
description.getClassName(),
|
||||
description.getMethodName(),
|
||||
(i++) + "/" + failureCount + " " + description.getDisplayName() + " failed "
|
||||
+ singleThrown.getMessage() + "\n" + status, singleThrown);
|
||||
(exceptionCount++) + "/" + failureCount + " " + description.getDisplayName() + " "
|
||||
+ "failed " + singleThrown.getMessage() + "\n" + status, singleThrown);
|
||||
}
|
||||
|
||||
} else {
|
||||
getClassLogger().logp(Level.SEVERE, description.getClassName(),
|
||||
description.getMethodName(),
|
||||
description.getDisplayName() + " failed " + e.getMessage() + "\n" + status, e);
|
||||
description.getDisplayName() + " failed " + throwable.getMessage() + "\n" + status,
|
||||
throwable);
|
||||
}
|
||||
super.failed(e, description);
|
||||
super.failed(throwable, description);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*$
|
||||
*
|
||||
* @see org.junit.rules.TestWatcher#failed(java.lang.Throwable,
|
||||
* org.junit.runner.Description)
|
||||
*/
|
||||
@Override
|
||||
protected void failed(Throwable e, Description description) {
|
||||
failed(e, description, "");
|
||||
protected void failed(Throwable exception, Description description) {
|
||||
failed(exception, description, "");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*$
|
||||
*
|
||||
* @see org.junit.rules.TestWatcher#starting(org.junit.runner.Description)
|
||||
*/
|
||||
@Override
|
||||
protected void starting(Description description) {
|
||||
TestBench.out().println();
|
||||
// Wait until the robot is enabled before starting the next tests
|
||||
int i = 0;
|
||||
int enableCounter = 0;
|
||||
while (!DriverStation.getInstance().isEnabled()) {
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
// Prints the message on one line overwriting itself each time
|
||||
TestBench.out().print("\rWaiting for enable: " + i++);
|
||||
TestBench.out().print("\rWaiting for enable: " + enableCounter++);
|
||||
}
|
||||
getClassLogger().logp(Level.INFO, description.getClassName(), description.getMethodName(),
|
||||
"Starting");
|
||||
@@ -167,12 +168,12 @@ public abstract class AbstractComsSetup {
|
||||
super.succeeded(description);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a simple message without the logger formatting associated with it.
|
||||
*$
|
||||
* @param level The level to log the message at
|
||||
*
|
||||
* @param level The level to log the message at
|
||||
* @param message The message to log
|
||||
*/
|
||||
protected void simpleLog(Level level, String message) {
|
||||
@@ -182,50 +183,50 @@ public abstract class AbstractComsSetup {
|
||||
}
|
||||
|
||||
/**
|
||||
* Provided as a replacement to lambda functions to allow for repeatable
|
||||
* checks to see if a correct state is reached
|
||||
*$
|
||||
* @author Jonathan Leitschuh
|
||||
* Provided as a replacement to lambda functions to allow for repeatable checks to see if a
|
||||
* correct state is reached.
|
||||
*
|
||||
* @author Jonathan Leitschuh
|
||||
*/
|
||||
public abstract class BooleanCheck {
|
||||
public BooleanCheck() {}
|
||||
public BooleanCheck() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the enclosed code and evaluates it to determine what state it should
|
||||
* return.
|
||||
*$
|
||||
* Runs the enclosed code and evaluates it to determine what state it should return.
|
||||
*
|
||||
* @return true if the code provided within the method returns true
|
||||
*/
|
||||
abstract public boolean getAsBoolean();
|
||||
};
|
||||
public abstract boolean getAsBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delays until either the correct state is reached or we reach the timeout.
|
||||
*$
|
||||
* @param level The level to log the message at.
|
||||
* @param timeout How long the delay should run before it should timeout and
|
||||
* allow the test to continue
|
||||
* @param message The message to accompany the delay. The message will display
|
||||
* 'message' took 'timeout' seconds if it passed.
|
||||
* @param correctState A method to determine if the test has reached a state
|
||||
* where it is valid to continue
|
||||
*
|
||||
* @param level The level to log the message at.
|
||||
* @param timeout How long the delay should run before it should timeout and allow the test
|
||||
* to continue
|
||||
* @param message The message to accompany the delay. The message will display 'message' took
|
||||
* 'timeout' seconds if it passed.
|
||||
* @param correctState A method to determine if the test has reached a state where it is valid to
|
||||
* continue
|
||||
* @return a double representing how long the delay took to run in seconds.
|
||||
*/
|
||||
public double delayTillInCorrectStateWithMessage(Level level, double timeout, String message,
|
||||
BooleanCheck correctState) {
|
||||
int i = 0;
|
||||
BooleanCheck correctState) {
|
||||
int timeoutIndex;
|
||||
// As long as we are not in the correct state and the timeout has not been
|
||||
// reached then continue to run this loop
|
||||
for (i = 0; i < (timeout * 100) && !correctState.getAsBoolean(); i++) {
|
||||
for (timeoutIndex = 0; timeoutIndex < (timeout * 100) && !correctState.getAsBoolean();
|
||||
timeoutIndex++) {
|
||||
Timer.delay(.01);
|
||||
}
|
||||
if (correctState.getAsBoolean()) {
|
||||
simpleLog(level, message + " took " + (i * .01) + " seconds");
|
||||
simpleLog(level, message + " took " + (timeoutIndex * .01) + " seconds");
|
||||
} else {
|
||||
simpleLog(level, message + " timed out after " + (i * .01) + " seconds");
|
||||
simpleLog(level, message + " timed out after " + (timeoutIndex * .01) + " seconds");
|
||||
}
|
||||
return i * .01;
|
||||
return timeoutIndex * .01;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,6 +7,11 @@
|
||||
|
||||
package edu.wpi.first.wpilibj.test;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.Request;
|
||||
import org.junit.runners.Suite.SuiteClasses;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
@@ -14,33 +19,23 @@ import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.Request;
|
||||
import org.junit.runners.Suite.SuiteClasses;
|
||||
import org.junit.runners.model.InitializationError;
|
||||
|
||||
/**
|
||||
* Allows tests suites and tests to be run selectively from the command line
|
||||
* using a regex text pattern.
|
||||
*$
|
||||
* @author jonathanleitschuh
|
||||
* Allows tests suites and tests to be run selectively from the command line using a regex text
|
||||
* pattern.
|
||||
*
|
||||
* @author jonathanleitschuh
|
||||
*/
|
||||
public abstract class AbstractTestSuite {
|
||||
private static final Logger logger = Logger.getLogger(AbstractTestSuite.class.getName());
|
||||
|
||||
/**
|
||||
* Gets all of the classes listed within the SuiteClasses annotation. To use
|
||||
* it, annotate a class with <code>@RunWith(Suite.class)</code> and
|
||||
* <code>@SuiteClasses({TestClass1.class, ...})</code>. When you run this
|
||||
* class, it will run all the tests in all the suite classes. When loading the
|
||||
* tests using regex the test list will be generated from this annotation.
|
||||
*$
|
||||
* @return the list of classes listed in the
|
||||
* <code>@SuiteClasses({TestClass1.class, ...})</code> annotation.
|
||||
* @throws RuntimeException If the <code>@SuiteClasses</code> annotation is
|
||||
* missing.
|
||||
* Gets all of the classes listed within the SuiteClasses annotation. To use it, annotate a class
|
||||
* with <code>@RunWith(Suite.class)</code> and <code>@SuiteClasses({TestClass1.class,
|
||||
* ...})</code>. When you run this class, it will run all the tests in all the suite classes. When
|
||||
* loading the tests using regex the test list will be generated from this annotation.
|
||||
*
|
||||
* @return the list of classes listed in the <code>@SuiteClasses({TestClass1.class, ...})</code>.
|
||||
* @throws RuntimeException If the <code>@SuiteClasses</code> annotation is missing.
|
||||
*/
|
||||
protected List<Class<?>> getAnnotatedTestClasses() {
|
||||
SuiteClasses annotation = getClass().getAnnotation(SuiteClasses.class);
|
||||
@@ -66,23 +61,22 @@ public abstract class AbstractTestSuite {
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a method name and method class pair. Used when searching for methods
|
||||
* matching a given regex text.
|
||||
*$
|
||||
* @author jonathanleitschuh
|
||||
* Stores a method name and method class pair. Used when searching for methods matching a given
|
||||
* regex text.
|
||||
*
|
||||
* @author jonathanleitschuh
|
||||
*/
|
||||
protected class ClassMethodPair {
|
||||
public final Class<?> methodClass;
|
||||
public final String methodName;
|
||||
public final Class<?> m_methodClass;
|
||||
public final String m_methodName;
|
||||
|
||||
public ClassMethodPair(Class<?> klass, Method m) {
|
||||
this.methodClass = klass;
|
||||
this.methodName = m.getName();
|
||||
public ClassMethodPair(Class<?> klass, Method method) {
|
||||
m_methodClass = klass;
|
||||
m_methodName = method.getName();
|
||||
}
|
||||
|
||||
public Request getMethodRunRequest() {
|
||||
return Request.method(methodClass, methodName);
|
||||
return Request.method(m_methodClass, m_methodName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,9 +99,9 @@ public abstract class AbstractTestSuite {
|
||||
|
||||
|
||||
/**
|
||||
* Gets all of the test classes listed in this suite. Does not include any of
|
||||
* the test suites. All of these classes contain tests.
|
||||
*$
|
||||
* Gets all of the test classes listed in this suite. Does not include any of the test suites. All
|
||||
* of these classes contain tests.
|
||||
*
|
||||
* @param runningList the running list of classes to prevent recursion.
|
||||
* @return The list of base test classes.
|
||||
*/
|
||||
@@ -117,21 +111,20 @@ public abstract class AbstractTestSuite {
|
||||
if (areAnySuperClassesOfTypeAbstractTestSuite(c)) {
|
||||
// Create a new instance of this class so that we can retrieve its data
|
||||
try {
|
||||
AbstractTestSuite suite = null;
|
||||
Object o = c.newInstance();
|
||||
suite = (AbstractTestSuite) c.newInstance();
|
||||
AbstractTestSuite suite = (AbstractTestSuite) c.newInstance();
|
||||
// Add the tests from this suite that match the regex to the list of
|
||||
// tests to run
|
||||
runningList = suite.getAllContainedBaseTests(runningList);
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
} catch (InstantiationException | IllegalAccessException ex) {
|
||||
// This shouldn't happen unless the constructor is changed in some
|
||||
// way.
|
||||
logger.log(Level.SEVERE, "Test suites can not take paramaters in their constructors.", e);
|
||||
logger.log(Level.SEVERE, "Test suites can not take paramaters in their constructors.",
|
||||
ex);
|
||||
}
|
||||
} else if (c.getAnnotation(SuiteClasses.class) != null) {
|
||||
logger.log(Level.SEVERE,
|
||||
String.format("class '%s' must extend %s to be searchable using regex.", c.getName()),
|
||||
AbstractTestSuite.class.getName());
|
||||
String.format("class '%s' must extend %s to be searchable using regex.",
|
||||
c.getName(), AbstractTestSuite.class.getName()));
|
||||
} else { // This is a class containing tests
|
||||
// so add it to the list
|
||||
runningList.add(c);
|
||||
@@ -141,9 +134,9 @@ public abstract class AbstractTestSuite {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all of the test classes listed in this suite. Does not include any of
|
||||
* the test suites. All of these classes contain tests.
|
||||
*$
|
||||
* Gets all of the test classes listed in this suite. Does not include any of the test suites. All
|
||||
* of these classes contain tests.
|
||||
*
|
||||
* @return The list of base test classes.
|
||||
*/
|
||||
public List<Class<?>> getAllContainedBaseTests() {
|
||||
@@ -153,10 +146,10 @@ public abstract class AbstractTestSuite {
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves all of the classes listed in the
|
||||
* <code>@SuiteClasses</code> annotation that match the given regex text.
|
||||
*$
|
||||
* @param regex the text pattern to retrieve.
|
||||
* Retrieves all of the classes listed in the <code>@SuiteClasses</code> annotation that match the
|
||||
* given regex text.
|
||||
*
|
||||
* @param regex the text pattern to retrieve.
|
||||
* @param runningList the running list of classes to prevent recursion
|
||||
* @return The list of classes matching the regex pattern
|
||||
*/
|
||||
@@ -171,9 +164,9 @@ public abstract class AbstractTestSuite {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all of the classes listed in the
|
||||
* <code>@SuiteClasses</code> annotation that match the given regex text.
|
||||
*$
|
||||
* Retrieves all of the classes listed in the <code>@SuiteClasses</code> annotation that match the
|
||||
* given regex text.
|
||||
*
|
||||
* @param regex the text pattern to retrieve.
|
||||
* @return The list of classes matching the regex pattern
|
||||
*/
|
||||
@@ -183,15 +176,15 @@ public abstract class AbstractTestSuite {
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches through all of the suites and tests and loads only the test or
|
||||
* test suites matching the regex text. This method also prevents a single
|
||||
* test from being loaded multiple times by loading the suite first then
|
||||
* loading tests from all non loaded suites.
|
||||
*$
|
||||
* Searches through all of the suites and tests and loads only the test or test suites matching
|
||||
* the regex text. This method also prevents a single test from being loaded multiple times by
|
||||
* loading the suite first then loading tests from all non loaded suites.
|
||||
*
|
||||
* @param regex the regex text to search for
|
||||
* @return the list of suite and/or test classes matching the regex.
|
||||
*/
|
||||
private List<Class<?>> getSuiteOrTestMatchingRegex(final String regex, List<Class<?>> runningList) {
|
||||
private List<Class<?>> getSuiteOrTestMatchingRegex(final String regex, List<Class<?>>
|
||||
runningList) {
|
||||
// Get any test suites matching the regex using the superclass methods
|
||||
runningList = getAllClassMatching(regex, runningList);
|
||||
|
||||
@@ -206,22 +199,22 @@ public abstract class AbstractTestSuite {
|
||||
// Prevents recursively adding tests/suites that have already been added
|
||||
if (!runningList.contains(c)) {
|
||||
try {
|
||||
AbstractTestSuite suite = null;
|
||||
final AbstractTestSuite suite;
|
||||
// Check the class to make sure that it is not a test class
|
||||
if (areAnySuperClassesOfTypeAbstractTestSuite(c)) {
|
||||
// Create a new instance of this class so that we can retrieve its
|
||||
// data.
|
||||
Object o = c.newInstance();
|
||||
suite = (AbstractTestSuite) c.newInstance();
|
||||
// Add the tests from this suite that match the regex to the list of
|
||||
// tests to run
|
||||
runningList = suite.getSuiteOrTestMatchingRegex(regex, runningList);
|
||||
}
|
||||
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
} catch (InstantiationException | IllegalAccessException ex) {
|
||||
// This shouldn't happen unless the constructor is changed in some
|
||||
// way.
|
||||
logger.log(Level.SEVERE, "Test suites can not take paramaters in their constructors.", e);
|
||||
logger.log(Level.SEVERE, "Test suites can not take paramaters in their constructors.",
|
||||
ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -229,11 +222,10 @@ public abstract class AbstractTestSuite {
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches through all of the suites and tests and loads only the test or
|
||||
* test suites matching the regex text. This method also prevents a single
|
||||
* test from being loaded multiple times by loading the suite first then
|
||||
* loading tests from all non loaded suites.
|
||||
*$
|
||||
* Searches through all of the suites and tests and loads only the test or test suites matching
|
||||
* the regex text. This method also prevents a single test from being loaded multiple times by
|
||||
* loading the suite first then loading tests from all non loaded suites.
|
||||
*
|
||||
* @param regex the regex text to search for
|
||||
* @return the list of suite and/or test classes matching the regex.
|
||||
*/
|
||||
@@ -243,26 +235,21 @@ public abstract class AbstractTestSuite {
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves all of the classes listed in the
|
||||
* <code>@SuiteClasses</code> annotation.
|
||||
*$
|
||||
* Retrieves all of the classes listed in the <code>@SuiteClasses</code> annotation.
|
||||
*
|
||||
* @return List of SuiteClasses
|
||||
* @throws RuntimeException If the <code>@SuiteClasses</code> annotation is
|
||||
* missing.
|
||||
* @throws RuntimeException If the <code>@SuiteClasses</code> annotation is missing.
|
||||
*/
|
||||
public List<Class<?>> getAllClasses() {
|
||||
return getAnnotatedTestClasses();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of all of the classes listed within the
|
||||
* <code>@SuiteClasses</code> annotation.
|
||||
*$
|
||||
* Gets the name of all of the classes listed within the <code>@SuiteClasses</code> annotation.
|
||||
*
|
||||
* @return the list of classes.
|
||||
* @throws RuntimeException If the <code>@SuiteClasses</code> annotation is
|
||||
* missing.
|
||||
* @throws RuntimeException If the <code>@SuiteClasses</code> annotation is missing.
|
||||
*/
|
||||
public List<String> getAllClassName() {
|
||||
List<String> classNames = new Vector<String>();
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2008-2016. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
package edu.wpi.first.wpilibj.test;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Suite;
|
||||
import org.junit.runners.Suite.SuiteClasses;
|
||||
import org.junit.runners.model.InitializationError;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import edu.wpi.first.wpilibj.test.AbstractTestSuite.ClassMethodPair;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.hasItems;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Yes, this is the test system testing itself. Functionally, this is making sure that all tests get
|
||||
* run correctly when you use parametrized arguments.
|
||||
*
|
||||
* @author jonathanleitschuh
|
||||
*/
|
||||
public class AbstractTestSuiteTest {
|
||||
|
||||
@Ignore("Prevents ANT from trying to run these as tests")
|
||||
@RunWith(Suite.class)
|
||||
@SuiteClasses({FirstSampleTest.class, SecondSampleTest.class, ThirdSampleTest.class,
|
||||
FourthSampleTest.class, UnusualTest.class, ExampleSubSuite.class, EmptySuite.class})
|
||||
class TestForAbstractTestSuite extends AbstractTestSuite {
|
||||
}
|
||||
|
||||
TestForAbstractTestSuite m_testSuite;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
m_testSuite = new TestForAbstractTestSuite();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTestsMatchingAll() throws InitializationError {
|
||||
// when
|
||||
List<Class<?>> collectedTests = m_testSuite.getAllClassMatching(".*");
|
||||
// then
|
||||
assertEquals(7, collectedTests.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTestsMatchingSample() throws InitializationError {
|
||||
// when
|
||||
List<Class<?>> collectedTests = m_testSuite.getAllClassMatching(".*Sample.*");
|
||||
// then
|
||||
assertEquals(4, collectedTests.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTestsMatchingUnusual() throws InitializationError {
|
||||
// when
|
||||
List<Class<?>> collectedTests = m_testSuite.getAllClassMatching(".*Unusual.*");
|
||||
// then
|
||||
assertEquals(1, collectedTests.size());
|
||||
assertEquals(UnusualTest.class, collectedTests.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTestsFromSuiteMatchingAll() throws InitializationError {
|
||||
// when
|
||||
List<Class<?>> collectedTests = m_testSuite.getSuiteOrTestMatchingRegex(".*");
|
||||
// then
|
||||
assertEquals(7, collectedTests.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTestsFromSuiteMatchingTest() throws InitializationError {
|
||||
// when
|
||||
List<Class<?>> collectedTests = m_testSuite.getSuiteOrTestMatchingRegex(".*Test.*");
|
||||
// then
|
||||
assertEquals(7, collectedTests.size());
|
||||
assertThat(collectedTests, hasItems(FirstSubSuiteTest.class,
|
||||
SecondSubSuiteTest.class, UnusualTest.class));
|
||||
assertThat(collectedTests,
|
||||
not(hasItems(new Class<?>[]{ExampleSubSuite.class, EmptySuite.class})));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMethodFromTest() {
|
||||
// when
|
||||
List<ClassMethodPair> pairs = m_testSuite.getMethodMatching(".*Method.*");
|
||||
// then
|
||||
assertEquals(1, pairs.size());
|
||||
assertEquals(FirstSubSuiteTest.class, pairs.get(0).m_methodClass);
|
||||
assertEquals(FirstSubSuiteTest.METHODNAME, pairs.get(0).m_methodName);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("OneTopLevelClass")
|
||||
class FirstSampleTest {
|
||||
}
|
||||
|
||||
@SuppressWarnings("OneTopLevelClass")
|
||||
class SecondSampleTest {
|
||||
}
|
||||
|
||||
@SuppressWarnings("OneTopLevelClass")
|
||||
class ThirdSampleTest {
|
||||
}
|
||||
|
||||
@SuppressWarnings("OneTopLevelClass")
|
||||
class FourthSampleTest {
|
||||
}
|
||||
|
||||
@SuppressWarnings("OneTopLevelClass")
|
||||
class UnusualTest {
|
||||
} // This is a member of both suites
|
||||
|
||||
|
||||
@Ignore("Prevents ANT from trying to run these as tests")
|
||||
@SuppressWarnings("OneTopLevelClass")
|
||||
class FirstSubSuiteTest {
|
||||
public static final String METHODNAME = "aTestMethod";
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("MethodName")
|
||||
public void aTestMethod() {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("OneTopLevelClass")
|
||||
class SecondSubSuiteTest {
|
||||
}
|
||||
|
||||
|
||||
@RunWith(Suite.class)
|
||||
@SuiteClasses({FirstSubSuiteTest.class, SecondSubSuiteTest.class, UnusualTest.class})
|
||||
@Ignore("Prevents ANT from trying to run these as tests")
|
||||
@SuppressWarnings("OneTopLevelClass")
|
||||
class ExampleSubSuite extends AbstractTestSuite {
|
||||
}
|
||||
|
||||
|
||||
@Ignore("Prevents ANT from trying to run these as tests")
|
||||
@RunWith(Suite.class)
|
||||
@SuiteClasses({})
|
||||
@SuppressWarnings("OneTopLevelClass")
|
||||
class EmptySuite extends AbstractTestSuite {
|
||||
}
|
||||
@@ -7,8 +7,6 @@
|
||||
|
||||
package edu.wpi.first.wpilibj.test;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.apache.tools.ant.BuildLogger;
|
||||
import org.apache.tools.ant.DefaultLogger;
|
||||
import org.apache.tools.ant.Project;
|
||||
@@ -16,15 +14,21 @@ import org.apache.tools.ant.taskdefs.optional.junit.FormatterElement;
|
||||
import org.apache.tools.ant.taskdefs.optional.junit.JUnitTask;
|
||||
import org.apache.tools.ant.taskdefs.optional.junit.JUnitTest;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Provides an entry point for tests to run with ANT. This allows ant to output
|
||||
* JUnit XML test results for Jenkins.
|
||||
*$
|
||||
* @author jonathanleitschuh
|
||||
* Provides an entry point for tests to run with ANT. This allows ant to output JUnit XML test
|
||||
* results for Jenkins.
|
||||
*
|
||||
* @author jonathanleitschuh
|
||||
*/
|
||||
public class AntJunitLanucher {
|
||||
|
||||
/**
|
||||
* Main entry point for jenkins
|
||||
*
|
||||
* @param args Arguments passed to java.
|
||||
*/
|
||||
public static void main(String... args) {
|
||||
if (args.length == 0) {
|
||||
String path =
|
||||
@@ -35,7 +39,6 @@ public class AntJunitLanucher {
|
||||
try {
|
||||
// Create the file to store the test output
|
||||
new File(pathToReports).mkdirs();
|
||||
JUnitTask task = new JUnitTask();
|
||||
|
||||
project.setProperty("java.io.tmpdir", pathToReports);
|
||||
|
||||
@@ -46,6 +49,8 @@ public class AntJunitLanucher {
|
||||
formatToScreen.setType(typeScreen);
|
||||
formatToScreen.setUseFile(false);
|
||||
formatToScreen.setOutput(System.out);
|
||||
|
||||
JUnitTask task = new JUnitTask();
|
||||
task.addFormatter(formatToScreen);
|
||||
|
||||
// add a build listener to the project
|
||||
@@ -73,8 +78,8 @@ public class AntJunitLanucher {
|
||||
|
||||
TestBench.out().println("Beginning Test Execution With ANT");
|
||||
task.execute();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
TestBench.out().println(
|
||||
|
||||
@@ -7,19 +7,16 @@
|
||||
|
||||
package edu.wpi.first.wpilibj.test;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* This class is designated to allow for simple testing of the library without
|
||||
* the overlying testing framework. This test is NOT run as a normal part of the
|
||||
* testing process and must be explicitly selected at runtime by using the
|
||||
* 'quick' argument.
|
||||
*$
|
||||
* This test should never be committed with changes to it but can be used during
|
||||
* development to aid in feature testing.
|
||||
*$
|
||||
* This class is designated to allow for simple testing of the library without the overlying testing
|
||||
* framework. This test is NOT run as a normal part of the testing process and must be explicitly
|
||||
* selected at runtime by using the 'quick' argument. This test should never be committed with
|
||||
* changes to it but can be used during development to aid in feature testing.
|
||||
*
|
||||
* @author Jonathan Leitschuh
|
||||
*/
|
||||
public class QuickTest extends AbstractComsSetup {
|
||||
@@ -27,7 +24,7 @@ public class QuickTest extends AbstractComsSetup {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*$
|
||||
*
|
||||
* @see edu.wpi.first.wpilibj.test.AbstractComsSetup#getClassLogger()
|
||||
*/
|
||||
@Override
|
||||
|
||||
@@ -7,20 +7,22 @@
|
||||
|
||||
package edu.wpi.first.wpilibj.test;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* This JUnit Rule allows you to apply this rule to any test to allow it to run
|
||||
* multiple times. This is important if you have a test that fails only
|
||||
* "sometimes" and needs to be rerun to find the issue.
|
||||
* This JUnit Rule allows you to apply this rule to any test to allow it to run multiple times. This
|
||||
* is important if you have a test that fails only "sometimes" and needs to be rerun to find the
|
||||
* issue.
|
||||
*
|
||||
* This code was originally found here: <a href="http://www.codeaffine.com/2013/04/10/running-junit-tests-repeatedly-without-loops/">Running JUnit Tests Repeatedly Without Loops</a>
|
||||
* <p>This code was originally found here:
|
||||
* <a href="http://www.codeaffine.com/2013/04/10/running-junit-tests-repeatedly-without-loops/">
|
||||
* Running JUnit Tests Repeatedly Without Loops</a>
|
||||
*
|
||||
* @author Frank Appel
|
||||
*/
|
||||
@@ -28,24 +30,27 @@ public class RepeatRule implements TestRule {
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({java.lang.annotation.ElementType.METHOD})
|
||||
public @interface Repeat {
|
||||
public abstract int times();
|
||||
/**
|
||||
* The number of times to repeat the test.
|
||||
*/
|
||||
int times();
|
||||
}
|
||||
|
||||
|
||||
private static class RepeatStatement extends Statement {
|
||||
|
||||
private final int times;
|
||||
private final Statement statement;
|
||||
private final int m_times;
|
||||
private final Statement m_statement;
|
||||
|
||||
private RepeatStatement(int times, Statement statement) {
|
||||
this.times = times;
|
||||
this.statement = statement;
|
||||
m_times = times;
|
||||
m_statement = statement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void evaluate() throws Throwable {
|
||||
for (int i = 0; i < times; i++) {
|
||||
statement.evaluate();
|
||||
for (int i = 0; i < m_times; i++) {
|
||||
m_statement.evaluate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,23 +34,21 @@ import edu.wpi.first.wpilibj.fixtures.FilterOutputFixture;
|
||||
import edu.wpi.first.wpilibj.fixtures.MotorEncoderFixture;
|
||||
import edu.wpi.first.wpilibj.fixtures.RelayCrossConnectFixture;
|
||||
import edu.wpi.first.wpilibj.fixtures.TiltPanCameraFixture;
|
||||
import edu.wpi.first.wpilibj.interfaces.Gyro;
|
||||
import edu.wpi.first.wpilibj.mockhardware.FakePotentiometerSource;
|
||||
|
||||
/**
|
||||
* This class provides access to all of the elements on the test bench, for use
|
||||
* in fixtures. This class is a singleton, you should use {@link #getInstance()}
|
||||
* to obtain a reference to the {@code TestBench}.
|
||||
* This class provides access to all of the elements on the test bench, for use in fixtures. This
|
||||
* class is a singleton, you should use {@link #getInstance()} to obtain a reference to the {@code
|
||||
* TestBench}.
|
||||
*
|
||||
* TODO: This needs to be updated to the most recent test bench setup.
|
||||
* <p>TODO: This needs to be updated to the most recent test bench setup.
|
||||
*
|
||||
* @author Fredric Silberberg
|
||||
*/
|
||||
public final class TestBench {
|
||||
|
||||
/**
|
||||
* The time that it takes to have a motor go from rotating at full speed to
|
||||
* completely stopped
|
||||
* The time that it takes to have a motor go from rotating at full speed to completely stopped.
|
||||
*/
|
||||
public static final double MOTOR_STOP_TIME = 0.25;
|
||||
|
||||
@@ -95,18 +93,21 @@ public final class TestBench {
|
||||
public static final int kMovAvgTaps = 6;
|
||||
public static final double kMovAvgExpectedOutput = -10.191644;
|
||||
|
||||
/** The Singleton instance of the Test Bench */
|
||||
/**
|
||||
* The Singleton instance of the Test Bench.
|
||||
*/
|
||||
private static TestBench instance = null;
|
||||
|
||||
/**
|
||||
* The single constructor for the TestBench. This method is private in order
|
||||
* to prevent multiple TestBench objects from being allocated
|
||||
* The single constructor for the TestBench. This method is private in order to prevent multiple
|
||||
* TestBench objects from being allocated.
|
||||
*/
|
||||
protected TestBench() {}
|
||||
protected TestBench() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new set of objects representing a connected set of Talon
|
||||
* controlled Motors and an encoder
|
||||
* Constructs a new set of objects representing a connected set of Talon controlled Motors and an
|
||||
* encoder.
|
||||
*
|
||||
* @return a freshly allocated Talon, Encoder pair
|
||||
*/
|
||||
@@ -137,8 +138,8 @@ public final class TestBench {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new set of objects representing a connected set of Victor
|
||||
* controlled Motors and an encoder
|
||||
* Constructs a new set of objects representing a connected set of Victor controlled Motors and an
|
||||
* encoder.
|
||||
*
|
||||
* @return a freshly allocated Victor, Encoder pair
|
||||
*/
|
||||
@@ -169,8 +170,8 @@ public final class TestBench {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new set of objects representing a connected set of Jaguar
|
||||
* controlled Motors and an encoder
|
||||
* Constructs a new set of objects representing a connected set of Jaguar controlled Motors and an
|
||||
* encoder.
|
||||
*
|
||||
* @return a freshly allocated Jaguar, Encoder pair
|
||||
*/
|
||||
@@ -232,7 +233,7 @@ public final class TestBench {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*$
|
||||
*
|
||||
* @see
|
||||
* edu.wpi.first.wpilibj.fixtures.CANMotorEncoderFixture#givePowerCycleRelay
|
||||
* ()
|
||||
@@ -249,10 +250,9 @@ public final class TestBench {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new set of objects representing a connected set of CANJaguar
|
||||
* controlled Motors and an encoder<br>
|
||||
* Note: The CANJaguar is not freshly allocated because the CANJaguar lacks a
|
||||
* free() method
|
||||
* Constructs a new set of objects representing a connected set of CANJaguar controlled Motors and
|
||||
* an encoder<br> Note: The CANJaguar is not freshly allocated because the CANJaguar lacks a
|
||||
* free() method.
|
||||
*
|
||||
* @return an existing CANJaguar and a freshly allocated Encoder
|
||||
*/
|
||||
@@ -302,20 +302,18 @@ public final class TestBench {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets two lists of possible DIO pairs for the two pairs
|
||||
*$
|
||||
* @return
|
||||
* Gets two lists of possible DIO pairs for the two pairs.
|
||||
*/
|
||||
private List<List<Integer[]>> getDIOCrossConnect() {
|
||||
List<List<Integer[]>> pairs = new ArrayList<List<Integer[]>>();
|
||||
List<Integer[]> setA =
|
||||
Arrays.asList(new Integer[][] {
|
||||
Arrays.asList(new Integer[][]{
|
||||
{new Integer(DIOCrossConnectA1), new Integer(DIOCrossConnectA2)},
|
||||
{new Integer(DIOCrossConnectA2), new Integer(DIOCrossConnectA1)}});
|
||||
pairs.add(setA);
|
||||
|
||||
List<Integer[]> setB =
|
||||
Arrays.asList(new Integer[][] {
|
||||
Arrays.asList(new Integer[][]{
|
||||
{new Integer(DIOCrossConnectB1), new Integer(DIOCrossConnectB2)},
|
||||
{new Integer(DIOCrossConnectB2), new Integer(DIOCrossConnectB1)}});
|
||||
pairs.add(setB);
|
||||
@@ -323,6 +321,7 @@ public final class TestBench {
|
||||
return pairs;
|
||||
}
|
||||
|
||||
@SuppressWarnings("JavadocMethod")
|
||||
public static AnalogCrossConnectFixture getAnalogCrossConnectFixture() {
|
||||
AnalogCrossConnectFixture analogIO = new AnalogCrossConnectFixture() {
|
||||
@Override
|
||||
@@ -338,6 +337,7 @@ public final class TestBench {
|
||||
return analogIO;
|
||||
}
|
||||
|
||||
@SuppressWarnings("JavadocMethod")
|
||||
public static RelayCrossConnectFixture getRelayCrossConnectFixture() {
|
||||
RelayCrossConnectFixture relay = new RelayCrossConnectFixture() {
|
||||
|
||||
@@ -360,9 +360,9 @@ public final class TestBench {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a single Collection containing all of the DIOCrossConnectFixtures in
|
||||
* all two pair combinations
|
||||
*$
|
||||
* Return a single Collection containing all of the DIOCrossConnectFixtures in all two pair
|
||||
* combinations.
|
||||
*
|
||||
* @return pairs of DIOCrossConnectFixtures
|
||||
*/
|
||||
public Collection<Integer[]> getDIOCrossConnectCollection() {
|
||||
@@ -374,19 +374,16 @@ public final class TestBench {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of pairs for the encoder to use using two different lists
|
||||
*$
|
||||
* @param listA
|
||||
* @param listB
|
||||
* Gets an array of pairs for the encoder to use using two different lists.
|
||||
*
|
||||
* @param flip whether this encoder needs to be flipped
|
||||
* @return A list of different inputs to use for the tests
|
||||
*/
|
||||
private Collection<Integer[]> getPairArray(List<Integer[]> listA, List<Integer[]> listB,
|
||||
boolean flip) {
|
||||
boolean flip) {
|
||||
Collection<Integer[]> encoderPortPairs = new ArrayList<Integer[]>();
|
||||
for (Integer[] portPairsA : listA) {
|
||||
ArrayList<Integer[]> construtorInput = new ArrayList<Integer[]>();
|
||||
Integer inputs[] = new Integer[5];
|
||||
Integer[] inputs = new Integer[5];
|
||||
inputs[0] = portPairsA[0]; // InputA
|
||||
inputs[1] = portPairsA[1]; // InputB
|
||||
|
||||
@@ -396,6 +393,7 @@ public final class TestBench {
|
||||
inputs[4] = flip ? 0 : 1; // The flip bit
|
||||
}
|
||||
|
||||
ArrayList<Integer[]> construtorInput = new ArrayList<Integer[]>();
|
||||
construtorInput.add(inputs);
|
||||
|
||||
inputs = inputs.clone();
|
||||
@@ -411,8 +409,8 @@ public final class TestBench {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the list of inputs to be used for the encoder test
|
||||
*$
|
||||
* Constructs the list of inputs to be used for the encoder test.
|
||||
*
|
||||
* @return A collection of different input pairs to use for the encoder
|
||||
*/
|
||||
public Collection<Integer[]> getEncoderDIOCrossConnectCollection() {
|
||||
@@ -427,8 +425,7 @@ public final class TestBench {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new set of objects representing a single-pole IIR filter with
|
||||
* a noisy data source
|
||||
* Constructs a new set of objects representing a single-pole IIR filter with a noisy data source.
|
||||
*
|
||||
* @return a single-pole IIR filter with a noisy data source
|
||||
*/
|
||||
@@ -437,15 +434,15 @@ public final class TestBench {
|
||||
@Override
|
||||
protected LinearDigitalFilter giveFilter(PIDSource source) {
|
||||
return LinearDigitalFilter.singlePoleIIR(source,
|
||||
kSinglePoleIIRTimeConstant,
|
||||
kFilterStep);
|
||||
kSinglePoleIIRTimeConstant,
|
||||
kFilterStep);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new set of objects representing a moving average filter with a
|
||||
* noisy data source using a linear digital filter
|
||||
* Constructs a new set of objects representing a moving average filter with a noisy data source
|
||||
* using a linear digital filter.
|
||||
*
|
||||
* @return a moving average filter with a noisy data source
|
||||
*/
|
||||
@@ -459,8 +456,8 @@ public final class TestBench {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new set of objects representing a single-pole IIR filter with
|
||||
* a repeatable data source
|
||||
* Constructs a new set of objects representing a single-pole IIR filter with a repeatable data
|
||||
* source.
|
||||
*
|
||||
* @return a single-pole IIR filter with a repeatable data source
|
||||
*/
|
||||
@@ -469,15 +466,14 @@ public final class TestBench {
|
||||
@Override
|
||||
protected LinearDigitalFilter giveFilter(PIDSource source) {
|
||||
return LinearDigitalFilter.singlePoleIIR(source,
|
||||
kSinglePoleIIRTimeConstant,
|
||||
kFilterStep);
|
||||
kSinglePoleIIRTimeConstant,
|
||||
kFilterStep);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new set of objects representing a high-pass filter with a
|
||||
* repeatable data source
|
||||
* Constructs a new set of objects representing a high-pass filter with a repeatable data source.
|
||||
*
|
||||
* @return a high-pass filter with a repeatable data source
|
||||
*/
|
||||
@@ -486,14 +482,14 @@ public final class TestBench {
|
||||
@Override
|
||||
protected LinearDigitalFilter giveFilter(PIDSource source) {
|
||||
return LinearDigitalFilter.highPass(source, kHighPassTimeConstant,
|
||||
kFilterStep);
|
||||
kFilterStep);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new set of objects representing a moving average filter with a
|
||||
* repeatable data source using a linear digital filter
|
||||
* Constructs a new set of objects representing a moving average filter with a repeatable data
|
||||
* source using a linear digital filter.
|
||||
*
|
||||
* @return a moving average filter with a repeatable data source
|
||||
*/
|
||||
@@ -507,9 +503,8 @@ public final class TestBench {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the singleton of the TestBench. If the TestBench is not already
|
||||
* allocated in constructs an new instance of it. Otherwise it returns the
|
||||
* existing instance.
|
||||
* Gets the singleton of the TestBench. If the TestBench is not already allocated in constructs an
|
||||
* new instance of it. Otherwise it returns the existing instance.
|
||||
*
|
||||
* @return The Singleton instance of the TestBench
|
||||
*/
|
||||
@@ -521,10 +516,10 @@ public final class TestBench {
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides access to the output stream for the test system. This should be
|
||||
* used instead of System.out This is gives us a way to implement changes to
|
||||
* where the output text of this test system is sent.
|
||||
*$
|
||||
* Provides access to the output stream for the test system. This should be used instead of
|
||||
* System.out This is gives us a way to implement changes to where the output text of this test
|
||||
* system is sent.
|
||||
*
|
||||
* @return The test bench global print stream.
|
||||
*/
|
||||
public static PrintStream out() {
|
||||
@@ -532,10 +527,10 @@ public final class TestBench {
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides access to the error stream for the test system. This should be
|
||||
* used instead of System.err This is gives us a way to implement changes to
|
||||
* where the output text of this test system is sent.
|
||||
*$
|
||||
* Provides access to the error stream for the test system. This should be used instead of
|
||||
* System.err This is gives us a way to implement changes to where the output text of this test
|
||||
* system is sent.
|
||||
*
|
||||
* @return The test bench global print stream.
|
||||
*/
|
||||
public static PrintStream err() {
|
||||
|
||||
@@ -7,16 +7,6 @@
|
||||
|
||||
package edu.wpi.first.wpilibj.test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
import java.util.logging.LogManager;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import junit.framework.JUnit4TestAdapter;
|
||||
import junit.runner.Version;
|
||||
|
||||
@@ -27,16 +17,24 @@ import org.junit.runner.notification.Failure;
|
||||
import org.junit.runners.Suite;
|
||||
import org.junit.runners.Suite.SuiteClasses;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.logging.LogManager;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import edu.wpi.first.wpilibj.WpiLibJTestSuite;
|
||||
import edu.wpi.first.wpilibj.can.CANTestSuite;
|
||||
import edu.wpi.first.wpilibj.command.CommandTestSuite;
|
||||
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboardTestSuite;
|
||||
|
||||
/**
|
||||
* The WPILibJ Integeration Test Suite collects all of the tests to be run by
|
||||
* junit. In order for a test to be run, it must be added the list of suite
|
||||
* classes below. The tests will be run in the order they are listed in the
|
||||
* suite classes annotation.
|
||||
* The WPILibJ Integeration Test Suite collects all of the tests to be run by junit. In order for a
|
||||
* test to be run, it must be added the list of suite classes below. The tests will be run in the
|
||||
* order they are listed in the suite classes annotation.
|
||||
*/
|
||||
@RunWith(Suite.class)
|
||||
// These are listed on separate lines to prevent merge conflicts
|
||||
@@ -47,17 +45,19 @@ public class TestSuite extends AbstractTestSuite {
|
||||
// Sets up the logging output
|
||||
final InputStream inputStream = TestSuite.class.getResourceAsStream("/logging.properties");
|
||||
try {
|
||||
if (inputStream == null)
|
||||
if (inputStream == null) {
|
||||
throw new NullPointerException("./logging.properties was not loaded");
|
||||
}
|
||||
LogManager.getLogManager().readConfiguration(inputStream);
|
||||
Logger.getAnonymousLogger().info("Loaded");
|
||||
} catch (final IOException | NullPointerException e) {
|
||||
} catch (final IOException | NullPointerException ex) {
|
||||
Logger.getAnonymousLogger().severe("Could not load default logging.properties file");
|
||||
Logger.getAnonymousLogger().severe(e.getMessage());
|
||||
Logger.getAnonymousLogger().severe(ex.getMessage());
|
||||
}
|
||||
|
||||
TestBench.out().println("Starting Tests");
|
||||
}
|
||||
|
||||
private static final Logger WPILIBJ_ROOT_LOGGER = Logger.getLogger("edu.wpi.first.wpilibj");
|
||||
private static final Logger WPILIBJ_COMMAND_ROOT_LOGGER = Logger
|
||||
.getLogger("edu.wpi.first.wpilibj.command");
|
||||
@@ -72,6 +72,9 @@ public class TestSuite extends AbstractTestSuite {
|
||||
|
||||
private static TestSuite instance = null;
|
||||
|
||||
/**
|
||||
* Get the singleton instance of the test suite.
|
||||
*/
|
||||
public static TestSuite getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new TestSuite();
|
||||
@@ -80,13 +83,13 @@ public class TestSuite extends AbstractTestSuite {
|
||||
}
|
||||
|
||||
/**
|
||||
* This has to be public so that the JUnit4
|
||||
* This has to be public so that the JUnit4.
|
||||
*/
|
||||
public TestSuite() {}
|
||||
public TestSuite() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a help message for the user when they use the --help flag at
|
||||
* runtime.
|
||||
* Displays a help message for the user when they use the --help flag at runtime.
|
||||
*/
|
||||
protected static void displayHelp() {
|
||||
StringBuilder helpMessage = new StringBuilder("Test Parameters help: \n");
|
||||
@@ -104,7 +107,8 @@ public class TestSuite extends AbstractTestSuite {
|
||||
+ QUICK_TEST_FLAG + " or " + CLASS_NAME_FILTER
|
||||
+ " and run them the given number of times.\n");
|
||||
helpMessage
|
||||
.append("[NOTE] All regex uses the syntax defined by java.util.regex.Pattern. This documentation can be found at "
|
||||
.append("[NOTE] All regex uses the syntax defined by java.util.regex.Pattern. This "
|
||||
+ "documentation can be found at "
|
||||
+ "http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html\n");
|
||||
helpMessage.append("\n");
|
||||
helpMessage.append("\n");
|
||||
@@ -113,8 +117,8 @@ public class TestSuite extends AbstractTestSuite {
|
||||
}
|
||||
|
||||
/**
|
||||
* Lets the user know that they used the TestSuite improperly and gives
|
||||
* details about how to use it correctly in the future.
|
||||
* Lets the user know that they used the TestSuite improperly and gives details about how to use
|
||||
* it correctly in the future.
|
||||
*/
|
||||
protected static void displayInvalidUsage(String message, String... args) {
|
||||
StringBuilder invalidMessage = new StringBuilder("Invalid Usage: " + message + "\n");
|
||||
@@ -133,16 +137,16 @@ public class TestSuite extends AbstractTestSuite {
|
||||
|
||||
/**
|
||||
* Prints the loaded tests before they are run.
|
||||
*$
|
||||
*
|
||||
* @param classes the classes that were loaded.
|
||||
*/
|
||||
protected static void printLoadedTests(final Class<?>... classes) {
|
||||
StringBuilder loadedTestsMessage = new StringBuilder("The following tests were loaded:\n");
|
||||
Package p = null;
|
||||
Package packagE = null;
|
||||
for (Class<?> c : classes) {
|
||||
if (c.getPackage().equals(p)) {
|
||||
p = c.getPackage();
|
||||
loadedTestsMessage.append(p.getName() + "\n");
|
||||
if (c.getPackage().equals(packagE)) {
|
||||
packagE = c.getPackage();
|
||||
loadedTestsMessage.append(packagE.getName() + "\n");
|
||||
}
|
||||
loadedTestsMessage.append("\t" + c.getSimpleName() + "\n");
|
||||
}
|
||||
@@ -151,16 +155,15 @@ public class TestSuite extends AbstractTestSuite {
|
||||
|
||||
|
||||
/**
|
||||
* Parses the arguments passed at runtime and runs the appropriate tests based
|
||||
* upon these arguments
|
||||
*$
|
||||
* Parses the arguments passed at runtime and runs the appropriate tests based upon these
|
||||
* arguments
|
||||
*
|
||||
* @param args the args passed into the program at runtime
|
||||
* @return the restults of the tests that have run. If no tests were run then
|
||||
* null is returned.
|
||||
* @return the restults of the tests that have run. If no tests were run then null is returned.
|
||||
*/
|
||||
protected static Result parseArgsRunAndGetResult(final String[] args) {
|
||||
if (args.length == 0) { // If there are no args passed at runtime then just
|
||||
// run all of the tests.
|
||||
// run all of the tests.
|
||||
printLoadedTests(TestSuite.class);
|
||||
return JUnitCore.runClasses(TestSuite.class);
|
||||
}
|
||||
@@ -171,7 +174,6 @@ public class TestSuite extends AbstractTestSuite {
|
||||
// The class filter was passed
|
||||
boolean classFilter = false;
|
||||
String classRegex = "";
|
||||
boolean repeatFilter = false;
|
||||
int repeatCount = 1;
|
||||
|
||||
for (String s : args) {
|
||||
@@ -180,22 +182,20 @@ public class TestSuite extends AbstractTestSuite {
|
||||
methodRegex = new String(s).replace(METHOD_NAME_FILTER, "");
|
||||
}
|
||||
if (Pattern.matches(METHOD_REPEAT_FILTER + ".*", s)) {
|
||||
repeatFilter = true;
|
||||
try {
|
||||
repeatCount = Integer.parseInt(new String(s).replace(METHOD_REPEAT_FILTER, ""));
|
||||
} catch (NumberFormatException e) {
|
||||
} catch (NumberFormatException ex) {
|
||||
displayInvalidUsage("The argument passed to the repeat rule was not a valid integer.",
|
||||
args);
|
||||
}
|
||||
}
|
||||
if (Pattern.matches(CLASS_NAME_FILTER + ".*", s)) {
|
||||
classFilter = true;
|
||||
classRegex = new String(s).replace(CLASS_NAME_FILTER, "");
|
||||
classRegex = s.replace(CLASS_NAME_FILTER, "");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
ArrayList<String> argsParsed = new ArrayList<String>(Arrays.asList(args));
|
||||
if (argsParsed.contains(HELP_FLAG)) {
|
||||
// If the user inputs the help flag then return the help message and exit
|
||||
@@ -214,46 +214,46 @@ public class TestSuite extends AbstractTestSuite {
|
||||
*/
|
||||
class MultipleResult extends Result {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final List<Failure> failures = new Vector<Failure>();
|
||||
private int runCount = 0;
|
||||
private int ignoreCount = 0;
|
||||
private long runTime = 0;
|
||||
private final List<Failure> m_failures = new ArrayList<>();
|
||||
private int m_runCount = 0;
|
||||
private int m_ignoreCount = 0;
|
||||
private long m_runTime = 0;
|
||||
|
||||
@Override
|
||||
public int getRunCount() {
|
||||
return runCount;
|
||||
return m_runCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFailureCount() {
|
||||
return failures.size();
|
||||
return m_failures.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getRunTime() {
|
||||
return runTime;
|
||||
return m_runTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Failure> getFailures() {
|
||||
return failures;
|
||||
return m_failures;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIgnoreCount() {
|
||||
return ignoreCount;
|
||||
return m_ignoreCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given result's data to this result
|
||||
*$
|
||||
* @param r the result to add to this result
|
||||
* Adds the given result's data to this result.
|
||||
*
|
||||
* @param result the result to add to this result
|
||||
*/
|
||||
void addResult(Result r) {
|
||||
failures.addAll(r.getFailures());
|
||||
runCount += r.getRunCount();
|
||||
ignoreCount += r.getIgnoreCount();
|
||||
runTime += r.getRunTime();
|
||||
void addResult(Result result) {
|
||||
m_failures.addAll(result.getFailures());
|
||||
m_runCount += result.getRunCount();
|
||||
m_ignoreCount += result.getIgnoreCount();
|
||||
m_runTime += result.getRunTime();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,19 +261,20 @@ public class TestSuite extends AbstractTestSuite {
|
||||
if (methodFilter) {
|
||||
List<ClassMethodPair> pairs = (new TestSuite()).getMethodMatching(methodRegex);
|
||||
if (pairs.size() == 0) {
|
||||
displayInvalidUsage("None of the arguments passed to the method name filter matched.", args);
|
||||
displayInvalidUsage("None of the arguments passed to the method name filter matched.",
|
||||
args);
|
||||
return null;
|
||||
}
|
||||
// Print out the list of tests before we run them
|
||||
TestBench.out().println("Running the following tests:");
|
||||
Class<?> classListing = null;
|
||||
for (ClassMethodPair p : pairs) {
|
||||
if (!p.methodClass.equals(classListing)) {
|
||||
if (!p.m_methodClass.equals(classListing)) {
|
||||
// Only display the class name every time it changes
|
||||
classListing = p.methodClass;
|
||||
classListing = p.m_methodClass;
|
||||
TestBench.out().println(classListing);
|
||||
}
|
||||
TestBench.out().println("\t" + p.methodName);
|
||||
TestBench.out().println("\t" + p.m_methodName);
|
||||
}
|
||||
|
||||
|
||||
@@ -353,9 +354,9 @@ public class TestSuite extends AbstractTestSuite {
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used by ant to get the Junit tests. This is required because the
|
||||
* tests try to load using a JUnit 3 framework. JUnit4 uses annotations to
|
||||
* load tests. This method allows JUnit3 to load JUnit4 tests.
|
||||
* This is used by ant to get the Junit tests. This is required because the tests try to load
|
||||
* using a JUnit 3 framework. JUnit4 uses annotations to load tests. This method allows JUnit3 to
|
||||
* load JUnit4 tests.
|
||||
*/
|
||||
public static junit.framework.Test suite() {
|
||||
return new JUnit4TestAdapter(TestSuite.class);
|
||||
@@ -363,8 +364,8 @@ public class TestSuite extends AbstractTestSuite {
|
||||
|
||||
|
||||
/**
|
||||
* The method called at runtime
|
||||
*$
|
||||
* The method called at runtime.
|
||||
*
|
||||
* @param args The test suites to run
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
/**
|
||||
* This is the starting point for the integration testing framework. This
|
||||
* package should contain classes that are not explicitly for testing the
|
||||
* library but instead provide the framework that the tests can extend from.
|
||||
* Every test should extend from
|
||||
* {@link edu.wpi.first.wpilibj.test.AbstractComsSetup} to ensure that Network
|
||||
* Communications is properly instantiated before the test is run.
|
||||
*$
|
||||
* The {@link edu.wpi.first.wpilibj.test.TestBench} should contain the port
|
||||
* numbers for all of the hardware and these values should not be explicitly
|
||||
* defined anywhere else in the testing framework.
|
||||
* This is the starting point for the integration testing framework. This package should contain
|
||||
* classes that are not explicitly for testing the library but instead provide the framework that
|
||||
* the tests can extend from. Every test should extend from
|
||||
* {@link edu.wpi.first.wpilibj.test.AbstractComsSetup}
|
||||
* to ensure that Network Communications is properly instantiated before the test is run. The
|
||||
* {@link edu.wpi.first.wpilibj.test.TestBench} should contain the port numbers for all of the
|
||||
* hardware and these values should not be explicitly defined anywhere else in the testing
|
||||
* framework.
|
||||
*/
|
||||
package edu.wpi.first.wpilibj.test;
|
||||
package edu.wpi.first.wpilibj.test;
|
||||
|
||||
Reference in New Issue
Block a user