Message 2
Message 2
ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.List;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.io.PrintStream;
//AUTOGENERATED FROM ../src/TrickOrTreaterTests.java
class TrickOrTreaterTests {
TestFunction.assertEqual(string, "Yoon/6/70");
}
@TestCase(name = "Age must be in the inclusive interval [0, 12]. What should an
invalid age default to?")
@Tip(description = "A negative age should default to 8!")
public void threeArgConstructorNegativeAge() throws TestFailedException {
TestFunction.assertEqual(string, "Mark/8/40");
}
TestFunction.assertEqual(string, "Rush/0/27");
}
TestFunction.assertEqual(string, "John/12/34");
}
TestFunction.assertEqual(string, "Ara/8/40");
}
TestFunction.assertEqual(string, "Dipper/12/0");
}
TestFunction.assertEqual(string, "Mabel/12/0");
}
TestFunction.assertEqual(string, "Lindsay/6/70");
}
TestFunction.assertEqual(string, "Elise/6/70");
}
TestFunction.assertEqual(string, "Tarini/9/71");
}
TestFunction.assertEqual(string, "NASA/0/118");
}
TestFunction.assertEqual(string, "Ansel/6/70");
}
TestFunction.assertEqual(string, "Spartan/9/71");
}
TestFunction.assertEqual(string, "Jim/1/0");
}
TestFunction.assertEqual(string, "Bob/1/0");
}
TestFunction.assertEqual(result, -1);
}
@TestCase(name = "compareTo: other has greater candy, equal age")
@Tip(description = COMPARE_TO_METHOD_TIP)
public void compareToGreaterEqual() throws TestFailedException {
TestFunction.assertEqual(result, -1);
}
TestFunction.assertEqual(result, -1);
}
TestFunction.assertEqual(result, 1);
}
TestFunction.assertEqual(result, 0);
}
TestFunction.assertEqual(result, -1);
}
TestFunction.assertEqual(result, 1);
}
TestFunction.assertEqual(result, 1);
}
TestFunction.assertEqual(result, 1);
}
TrickOrTreaterSubclass[] possibleX =
getAllTrickOrTreatersOnInterval("Xander", 0, 12, 0, 50);
TrickOrTreaterSubclass[] possibleY =
getAllTrickOrTreatersOnInterval("Yang", 0, 12, 0, 50);
TrickOrTreaterSubclass[] possibleZ = getAllTrickOrTreatersOnInterval("Zan",
0, 12, 0, 50);
System.out.println(ColorUtils.formatColorString(AsciiColorCode.BRIGHT_RED_BACKGROUN
D,
AsciiColorCode.BRIGHT_WHITE_FOREGROUND, "
TRANSITIVITY TEST FAILED: \u00BB ") + "\nWhen "
+ "x = \"" + trickOrTreaterX + "\", y = \"" +
trickOrTreaterY + "\", z = \"" + trickOrTreaterZ + "\"");
TestFunction.assertEqual(totOne.compareTo(totThree), 1);
}
}
}
}
}
TrickOrTreaterSubclass[] possibleX =
getAllTrickOrTreatersOnInterval("Xander", 0, 12, 0, 50);
TrickOrTreaterSubclass[] possibleY =
getAllTrickOrTreatersOnInterval("Yang", 0, 12, 0, 50);
TrickOrTreaterSubclass[] possibleZ = getAllTrickOrTreatersOnInterval("Zan",
0, 12, 0, 50);
System.out.println(ColorUtils.formatColorString(AsciiColorCode.BRIGHT_RED_BACKGROUN
D,
AsciiColorCode.BRIGHT_WHITE_FOREGROUND, " THIRD
COMPARETO() CONDITION FAILED: \u00BB ") + "\nWhen "
+ "x = \"" + trickOrTreaterX + "\", y = \"" +
trickOrTreaterY + "\", z = \"" + trickOrTreaterZ + "\"");
TestFunction.assertEqual(0, 1);
}
}
}
}
}
/**
* Helper method to retrieve all possible TrickOrTreaters on the given
intervals (inclusive).
* @param name The name of all of the TrickOrTreaters
* @param minAge Min age, inclusive.
* @param maxAge Max age, inclusive.
* @param minCandy Min candy, inclusive.
* @param maxCandy Max candy, inclusive.
* @return An array containing all possible trick or treaters on the interval.
*/
private TrickOrTreaterSubclass[] getAllTrickOrTreatersOnInterval(String name,
int minAge, int maxAge, int minCandy, int maxCandy) {
TrickOrTreaterSubclass[] combos = new TrickOrTreaterSubclass[(maxAge + 1 -
minAge) * (maxCandy + 1 - minCandy)];
int index = 0;
for (int i = minAge; i <= maxAge; i++) {
for (int j = minCandy; j <= maxCandy; j++) {
combos[index] = new TrickOrTreaterSubclass(name, i, j);
index++;
}
}
return combos;
}
/**
* Placeholder subclass to force-call TrickOrTreater's methods
*/
static class TrickOrTreaterSubclass extends TrickOrTreater {
@Override
public void trickOrTreat() {
}
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
@interface TestCase {
/**
* The name of the TestCase, used for describing what a test might be doing
*
* @return The name of the TestCase
*/
public String name() default "UNNAMED_TEST";
}
class TestFunction {
/**
* Detects if the given Strings do not have the same content (case-sensitive)
*
* @param actual The actual value
* @param expected The expected value
* @throws TestFailedException if the test fails
*/
public static void assertEqual(String actual, String expected) throws
TestFailedException {
boolean failed = false;
if (actual == null) {
failed = expected == null;
} else {
if (!actual.replaceAll("\n",
System.lineSeparator()).equals(expected.replaceAll("\n", System.lineSeparator())))
{
failed = true;
}
}
if (failed) {
if (actual.trim().contains("\n")) {
actualString = "\n\"" + actual + "\"\n";
}
if (expected.trim().contains("\n")) {
expectedString = "\n\"" + expected + "\"\n";
}
} else {
failed = !actual.get(i).equals(expected.get(i));
}
if (failed) break;
}
}
if (failed) {
throw new TestFailedException(
"List Different! Received \"" + actual + "\", expected \"" +
expected + "\"");
}
}
/**
* Detects if the given integers are not equal.
*
* @param actual The actual value
* @param expected The expected value
* @throws TestFailedException if the test fails
*/
public static void assertEqual(int actual, int expected) throws
TestFailedException {
boolean failed = (actual != expected);
if (failed) {
throw new TestFailedException("Integer value difference: Received " +
actual + ", expected " + expected);
}
}
/**
* Detects if the given doubles are not within 1.0e-6 of one another.
*
* @param actual The actual value
* @param expected The expected value
* @throws TestFailedException if the test fails
*/
public static void assertEqual(double actual, double expected) throws
TestFailedException {
final double ALLOWABLE_ERROR = 0.000001;
if (failed) {
throw new TestFailedException("Double value difference: Received " +
actual + ", expected " + expected);
}
}
/**
* Detects if the given booleans do not have equal values.
*
* @param actual The actual value
* @param expected The expected value
* @throws TestFailedException if the test fails
*/
public static void assertEqual(boolean actual, boolean expected) throws
TestFailedException {
boolean failed = (actual != expected);
if (failed) {
throw new TestFailedException("Boolean value difference: Received " +
actual + ", expected " + expected);
}
}
/**
* Detects if the given Exceptions are the same TYPE, not if they are caused by
* the same thing. Any two
* NullPointerExceptions will, when passed into this function, return true,
even
* if they are caused by
* two unrelated issues.
*
* @param actual The actual value
* @param expected The expected value
* @throws TestFailedException If the test fails
*/
public static void assertEqual(Exception actual, Exception expected) throws
TestFailedException {
boolean failed = (actual.getCause().getClass() !=
expected.getCause().getClass());
if (failed) {
throw new TestFailedException("Exception class difference: Received " +
actual.getCause().getClass()
+ ", but expected " + expected.getCause().getClass());
}
}
}
/**
* The amount of HORIZONTAL_LINE_CHARACTER elements to use in a line
*/
public static final int HORIZONTAL_LINE_LENGTH = 48;
/**
* Prints a horizontal line to the terminal.
*/
public static void printHorizontalLine() {
System.out
.println(String.format("%0" + HORIZONTAL_LINE_LENGTH + "d",
0).replace("0", HORIZONTAL_LINE_CHARACTER));
}
/**
* Prints centered text to the terminal.
*
* @param text The text to be centered
*/
public static void printTextCentered(String text) {
// HORIZONTAL_LINE_LENGTH is maximum width
// if line is
// xxxxxxxxxxxx
// We can pad the start of the string with half of the horizontal:
// xxxxxhelloxx
// The problem is that this doesn't account for the length of the string.
// We can add half of the string length as well to correct it:
// xxxxhelloxxxx = CENTERED! (or at least as close as it can get)
class TestUtils {
/**
* Returns either 1, 0, or -1 depending on the sign of the input.
*
* @param input
* @return -1 if input < 0, 0 if input = 0, 1 if input > 0
*/
public static int signOf(int input) {
if (input == 0) {
return input;
} else {
return Math.abs(input) / input;
}
}
@Retention(RetentionPolicy.RUNTIME)
@interface Tip {
/**
* Used to display a helpful tip when the user fails a test.
*
* @return The main tip body message
*/
public String description() default "";
}
@TestCase(name = "Constructor: Valid inputs passed in (this test does not check
cackle)")
@Tip(description = "Make sure there isn't any field shadowing in your
constructor!")
public void constructorFourArgs() throws TestFailedException {
TestFunction.assertEqual(string, "Yoon/6/70");
}
@TestCase(name = "Constructor: null name (this test does not check cackle)")
@Tip(description = "What is a valid input for name? What should it default
to?")
public void constructorNullName() throws TestFailedException {
@TestCase(name = "Constructor: empty name (this test does not check cackle)")
@Tip(description = "What is a valid input for name? What should it default
to?")
public void constructorEmptyName() throws TestFailedException {
@TestCase(name = "Constructor: blank name (this test does not check cackle)")
@Tip(description = "What is a valid input for name? What should it default
to?")
public void constructorBlankName() throws TestFailedException {
hijacker.startRecording();
hijacker.startRecording();
hijacker.startRecording();
hijacker.startRecording();
hijacker.startRecording();
hijacker.startRecording();
hijacker.startRecording();
hijacker.stopRecording();
TestFunction.assertEqual(output, "Grey/9/73");
}
hijacker.startRecording();
hijacker.stopRecording();
TestFunction.assertEqual(output, "Spartan/9/71");
}
hijacker.startRecording();
hijacker.stopRecording();
TestFunction.assertEqual(output, "Poof/2/54");
}
TestFunction.assertEqual(result, -1);
}
TestFunction.assertEqual(result, -1);
}
TestFunction.assertEqual(result, -1);
}
TestFunction.assertEqual(result, 1);
}
TestFunction.assertEqual(result, 0);
}
TestFunction.assertEqual(result, -1);
}
TestFunction.assertEqual(result, 1);
}
TestFunction.assertEqual(result, 1);
}
TestFunction.assertEqual(result, 1);
}
TestFunction.assertEqual(result, -1);
}
TestFunction.assertEqual(result, 1);
}
System.out.println(ColorUtils.formatColorString(AsciiColorCode.BRIGHT_RED_BACKGROUN
D,
AsciiColorCode.BRIGHT_WHITE_FOREGROUND, "
TRANSITIVITY TEST FAILED: \u00BB ") + "\nWhen "
+ "x = \"" + witchX + "\", y = \"" + witchY + "\",
z = \"" + witchZ + "\"");
TestFunction.assertEqual(TestUtils.signOf(witchOne.compareTo(witchThree)), 1);
}
}
}
}
}
/**
* Helper method to retrieve all possible Ghosts on the given intervals
(inclusive).
* @param name The name of all of the Ghosts
* @param minAge Min age, inclusive.
* @param maxAge Max age, inclusive.
* @param minCandy Min candy, inclusive.
* @param maxCandy Max candy, inclusive.
* @param minCackleLength Min cackle length, inclusive.
* @param maxCackleLength Max cackle length, inclusive.
* @return An array containing all possible trick or treaters on the interval.
*/
private Witch[] getAllWitchesOnInterval(String name, int minAge, int maxAge,
int minCandy, int maxCandy, int minCackleLength, int maxCackleLength) {
Witch[] combos = new Witch[(maxAge + 1 - minAge) * (maxCandy + 1 -
minCandy) * (maxCackleLength + 1 - minCackleLength)];
int index = 0;
for (int i = minAge; i <= maxAge; i++) {
for (int j = minCandy; j <= maxCandy; j++) {
for (int k = minCackleLength; k <= maxCackleLength; k++) {
StringBuilder s = new StringBuilder();
for (int l = 0; l < k; l++) {
s.append("-");
}
combos[index] = new Witch(name, i, j, s.toString());
index++;
}
}
}
return combos;
}
}
//AUTOGENERATED FROM ../src/TestFailedException.java
/**
* A custom exception used for detecting tests failed.
*/
class TestFailedException extends Exception {
public TestFailedException() {
}
class TestManager {
/**
* A list of the currently registered classes to test
*/
private static final List<Class<?>> testClazzes = new ArrayList<>();
executeTests();
}
/**
* Registers and marks test class to be scanned during test execution.
*
* @param clazz The input class
*/
public static void registerClass(Class<?> clazz) {
testClazzes.add(clazz);
}
/**
* Executes all registered tests.
*/
public static void executeTests() {
int totalTests = 0;
int totalTestsFailed = 0;
int classTests = 0;
int classTestsFailed = 0;
if (testCase != null) {
try {
m.invoke(instance);
System.out.println(ColorUtils.formatColorString(AsciiColorCode.BRIGHT_GREEN_BACKGRO
UND,
AsciiColorCode.BRIGHT_WHITE_FOREGROUND, "
PASSED: \u00BB ") + " "
+ testCase.name());
} catch (InvocationTargetException e) {
if (e.getCause() instanceof TestFailedException) {
TestFailedException tfe = (TestFailedException)
e.getCause();
System.out.println(ColorUtils.formatColorString(AsciiColorCode.BRIGHT_RED_BACKGROUN
D,
AsciiColorCode.BRIGHT_WHITE_FOREGROUND, "
FAILED: \u00BB ") + " "
+ testCase.name());
System.out.println("\t" + tfe.getMessage());
classTestsFailed++;
if (tip != null)
System.out.printf("\tHINT: %s\n",
tip.description());
} else {
e.getCause().printStackTrace();
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
classTests++;
}
}
totalTests += classTests;
totalTestsFailed += classTestsFailed;
System.out.println();
StringUtils.printTextCentered(
String.format("TESTS PASSED: %d/%d", classTests -
classTestsFailed, classTests));
} catch (Exception e) {
e.printStackTrace();
}
}
StringUtils.printHorizontalLine();
StringUtils.printTextCentered("Test Results");
System.out.println();
StringUtils.printTextCentered(
String.format("TOTAL TESTS PASSED: %d/%d", totalTests -
totalTestsFailed, totalTests));
StringUtils.printHorizontalLine();
/**
* Prints a formatted test category section
*
* @param category The name of the section (most likely the class name)
*/
private static void printTestCategory(String category) {
StringUtils.printHorizontalLine();
StringUtils.printTextCentered(category);
System.out.println();
}
}
/**
* A helper class used for redirecting System.out to check against
*/
class IOHijacker {
private static IOHijacker INSTANCE;
private IOHijacker() {
this.originalStream = System.out;
}
/**
* Starts recording all System.out messages to the console and stores them in
* IOHijacker.log.
*
* Until stopRecording is called, no System.out messages will appear.
*/
public void startRecording() {
log = "";
if (redirectedStream == null)
redirectedStream = getRedirectedStream();
System.setOut(redirectedStream);
recording = true;
}
/**
* Stops the current recording, resetting System.out to its default behavior.
*
* @return A list of all messages sent during the recording
*/
public String stopRecording() {
recording = false;
System.setOut(originalStream);
return log;
}
/**
* Retrieves the current log of messages in a recording
*
* @return The current log of messages
*/
public String getCurrentLog() {
return log;
}
/**
* Retrieves a custom PrintStream that redirects print to instead logMessage
*
* @return The custom PrintStream
*/
private PrintStream getRedirectedStream() {
return new PrintStream(System.out, true) {
@Override
public void print(String s) {
IOHijacker.appendMessage(s);
}
@Override
public PrintStream printf(String message, Object... args) {
IOHijacker.appendMessage(String.format(message, args));
return this;
}
@Override
public void println(String s) {
IOHijacker.appendMessage(s + "\n");
}
};
}
/**
* Returns the Singleton's instance, creating one if it doesn't exist.
*
* @return The IOHijacker instance
*/
public static IOHijacker getInstance() {
if (INSTANCE == null) {
INSTANCE = new IOHijacker();
}
return INSTANCE;
}
/**
* Appends a string message to the log ONLY if recording.
*
* @param message The message to be recorded
*/
private static void appendMessage(String message) {
IOHijacker instance = getInstance();
if (!instance.recording)
return;
instance.log += message.replaceAll("\r","");
}
}
TestFunction.assertEqual(string, "Yoon/6/7/0");
}
hijacker.startRecording();
hijacker.startRecording();
hijacker.startRecording();
hijacker.startRecording();
hijacker.stopRecording();
TestFunction.assertEqual(string, "Laura/6/7/0");
}
hijacker.startRecording();
TestFunction.assertEqual(string, "Skyla/6/7/0");
}
hijacker.startRecording();
hijacker.stopRecording();
TestFunction.assertEqual(string, "Radhika/6/7/0");
}
ghost.rob(victim);
TestFunction.assertEqual(string, "Spartan/9/7/1");
}
ghost.rob(null);
TestFunction.assertEqual(string, "Tremor/6/7/0");
}
ghost.rob(victim);
TestFunction.assertEqual(string, "Skipper/6/7/0");
}
ghost.rob(victim);
ghost.rob(victim);
TestFunction.assertEqual(string, "Iron/9/7/2");
}
ghost.rob(victim);
ghost.rob(victim);
ghost.rob(victim);
TestFunction.assertEqual(string, "Grey/9/7/3");
}
TestFunction.assertEqual(result, -1);
}
TestFunction.assertEqual(result, -1);
}
TestFunction.assertEqual(result, -1);
}
TestFunction.assertEqual(result, 1);
}
TestFunction.assertEqual(result, 0);
}
TestFunction.assertEqual(result, -1);
}
TestFunction.assertEqual(result, 1);
}
TestFunction.assertEqual(result, 1);
}
TestFunction.assertEqual(result, 1);
}
TestFunction.assertEqual(result, -1);
}
TestFunction.assertEqual(result, 1);
}
System.out.println(ColorUtils.formatColorString(AsciiColorCode.BRIGHT_RED_BACKGROUN
D,
AsciiColorCode.BRIGHT_WHITE_FOREGROUND, "
TRANSITIVITY TEST FAILED: \u00BB ") + "\nWhen "
+ "x = \"" + ghostX + "\", y = \"" + ghostY + "\",
z = \"" + ghostZ + "\"");
TestFunction.assertEqual(TestUtils.signOf(ghostOne.compareTo(ghostThree)), 1);
}
}
}
}
}
/**
* Private class to test Ghost's rob() function.
*/
private static class RobbableSubclass extends TrickOrTreater implements
Robbable {
@Override
public int beRobbed() {
return this.getNumCandy();
}
@Override
public void trickOrTreat() {
}
}
/**
* Helper method to retrieve all possible Ghosts on the given intervals
(inclusive).
* @param name The name of all of the Ghosts
* @param minAge Min age, inclusive.
* @param maxAge Max age, inclusive.
* @param minCandy Min candy, inclusive.
* @param maxCandy Max candy, inclusive.
* @param minRobberies Min robberies, inclusive.
* @param maxRobberies Max robberies, inclusive.
* @return An array containing all possible trick or treaters on the interval.
*/
private Ghost[] getAllGhostsOnInterval(String name, int minAge, int maxAge, int
minCandy, int maxCandy, int minRobberies, int maxRobberies) {
Ghost[] combos = new Ghost[(maxAge + 1 - minAge) * (maxCandy + 1 -
minCandy) * (maxRobberies + 1 - minRobberies)];
RobbableSubclass dummy = new RobbableSubclass("dummy", 0, 0);
int index = 0;
for (int i = minAge; i <= maxAge; i++) {
for (int j = minCandy; j <= maxCandy; j++) {
for (int k = minRobberies; k <= maxRobberies; k++) {
combos[index] = new Ghost(name, i, j);
for (int l = 0; l < k; l++) {
combos[index].rob(dummy);
}
index++;
}
}
}
return combos;
}
}
/**
* Formats a string to have an ASCII foreground (text color) in terminal.
*
* @param foreground The ASCII representation of the foreground color, pulled
* from AsciiColorCode
* @param s The string to color
* @return The colored string
*/
public static String formatForegroundColorString(String foreground, String s) {
return foreground + s + AsciiColorCode.RESET_COLOR;
/**
* Formats a string to have both an ASCII foreground and background in terminal
*
* @param background The ASCII representation of the background color, pulled
* from AsciiColorCode
* @param foreground The ASCII representation of the foreground color, pulled
* from AsciiColorCode
* @param s The string to color
* @return The colored string
*/
public static String formatColorString(String background, String foreground,
String s) {
return foreground + background + s + AsciiColorCode.RESET_COLOR;
}
}