package lab.turtle; import static org.junit.Assert.*; import java.awt.Color; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.Arrays; import org.junit.Test; public class TurtleTest { @Test public void checkNonStaticAttributes() { try { String[] types = { "double", "java.awt.Color", "lab.turtle.Point2D" }; Class clazz = Class.forName("lab.turtle.Turtle"); int number = 0; for (Field field : clazz.getDeclaredFields()) { if (!Modifier.isStatic(field.getModifiers())) { if (Arrays.binarySearch(types, field.getType().getName()) < 0) { fail("non-static attribute: new one of type " + field.getType().getName()); } number++; } } assertEquals("non-static attributes: there are not three in your class", 3, number); } catch (ClassNotFoundException e) { fail("Class lab.turtle.Turtle cannot be found"); } } @Test public void testTurtleCtor() { Turtle t = new Turtle(); assertTrue("default ctor: position is not (0, 0)", t.getPosition().equals(new Point2D(0, 0))); assertTrue("default ctor: angle is not 0.0", t.getAngle() == 0.0); assertTrue("default ctor: color is not black", t.getPenColor().equals(Color.BLACK)); } @Test public void testTurtleCopyCtor() { Point2D pos = new Point2D(0.1, 0.1); double ang = -64.0; Color c = Color.BLUE; Turtle t = new Turtle(pos, ang, c); Turtle u = new Turtle(t); assertTrue("copy ctor: position is incorrect", u.getPosition().equals(pos)); assertFalse( "copy ctor: position object is being shared with another turtle", u.getPosition() == t.getPosition()); assertTrue("copy ctor: angle is incorrect", u.getAngle() == ang); assertTrue("copy ctor: pen color is incorrect", u.getPenColor().equals(c)); } @Test public void testTurtleCopyCtor2() { Turtle t = new Turtle(); Turtle u = new Turtle(t); Field pos = null; try { pos = t.getClass().getDeclaredField("position"); } catch (NoSuchFieldException x) { fail("why is there no field named \"position\"?"); } pos.setAccessible(true); try { Point2D tp = (Point2D) pos.get(t); Point2D up = (Point2D) pos.get(u); assertFalse("copy constructor is not making a new copy of position", tp == up); } catch (IllegalAccessException x) { fail("this should not happen; please contact your instructor"); } } @Test public void testTurtlePositionAngleColorCtor() { Point2D pos = new Point2D(0.1, 0.1); double ang = -64.0; Color c = Color.BLUE; Turtle u = new Turtle(pos, ang, c); assertTrue("ctor: position is incorrect", u.getPosition().equals(pos)); assertFalse("ctor: position object is being shared with client", u.getPosition() == pos); assertTrue("ctor: angle is incorrect", u.getAngle() == ang); assertTrue("ctor: pen color is incorrect", u.getPenColor().equals(c)); // illegal starting positions final double radius = 1.000001; for (int i = 0; i < 360; i++) { double x = radius * TurtleUtil.cos(i); double y = radius * TurtleUtil.sin(i); pos = new Point2D(x, y); try { new Turtle(pos, ang, c); fail(pos + " is an illegal starting position"); } catch (IllegalArgumentException ex) { } } } @Test public void testMaxDistance() { // max distance == 1 Turtle t = new Turtle(); assertEquals("maxDistance failed for turtle " + t, 1.0, t.maxDistance(), 1e-6); // max distance == 0 t = new Turtle(new Point2D(0, 1), 90, Color.BLACK); assertEquals("maxDistance failed for turtle " + t, 0.0, t.maxDistance(), 1e-6); // max distance == 2 t = new Turtle(new Point2D(0, 1), -90, Color.BLACK); assertEquals("maxDistance failed for turtle " + t, 2.0, t.maxDistance(), 1e-6); // max distance == 0.15 final double x = 1 / Math.sqrt(2.0); final double y = 1 / Math.sqrt(2.0); final double dist = 0.15; t = new Turtle(new Point2D((1 - dist) * x, (1 - dist) * y), 45, Color.BLACK); assertEquals("maxDistance failed for turtle " + t, dist, t.maxDistance(), 1e-6); } @Test public void testMove() { Turtle t = new Turtle(); t.move(0.2); Point2D expected = new Point2D(0.2, 0.0); assertTrue("move: incorrect final position", expected.similarTo(t.getPosition(), 1e-6)); // try to move outside of the circle on the right t.move(100.0); expected.setX(1.0); assertTrue("move: incorrect final position", expected.similarTo(t.getPosition(), 1e-6)); } @Test(expected = IllegalArgumentException.class) public void testMoveException() { Turtle michael = new Turtle(); michael.move(-1); } private static boolean isSimilarAngles(double a, double b) { if (a < 0.) { a += 360.; } if (b < 0.) { b += 360.; } return Math.abs(a - b) < 1e-9; } @Test public void testTurnLeft() { Point2D pos = new Point2D(0.1, 0.1); double ang = 359.0; Turtle t = new Turtle(pos, ang, Color.BLACK); t.turnLeft(); double tang = t.getAngle() % 360.; double expected = (ang + 90.) % 360; boolean similarAngle = isSimilarAngles(expected, tang); assertTrue("turnLeft: final angle is incorrect", similarAngle); } @Test public void testTurnRight() { Point2D pos = new Point2D(0.1, 0.1); double ang = 1.0; Turtle t = new Turtle(pos, ang, Color.BLACK); t.turnRight(); double tang = t.getAngle() % 360.; double expected = (ang - 90.) % 360; boolean similarAngle = isSimilarAngles(expected, tang); assertTrue("turnRight: final angle is incorrect", similarAngle); } @Test public void testTurn() { Point2D pos = new Point2D(0.1, 0.1); double delta = 100000.; Turtle t = new Turtle(pos, 0.0, Color.BLACK); t.turn(delta); double tang = t.getAngle(); if (tang >= 360. || tang <= -360.) { fail("turn: angle is out of range -> " + tang); } double expected = (0. + delta) % 360; boolean similarAngle = isSimilarAngles(expected, tang); assertTrue("turnRight: final angle is incorrect", similarAngle); } @Test public void testSetPenColor() { Turtle t = new Turtle(); t.setPenColor(Color.GREEN); assertTrue("setPenColor: wrong pen color", t.getPenColor().equals(Color.GREEN)); } @Test public void testGetPenColor() { Turtle t = new Turtle(); Color c = t.getPenColor(); assertTrue("getPenColor: expected Color.BLACK, got : " + c, t.getPenColor() .equals(Color.BLACK)); assertTrue("getPenColor: pen color should not be held using composition", t.getPenColor() == t.getPenColor()); } @Test public void testGetPosition() { Point2D pos = new Point2D(0.1, 0.1); Turtle t = new Turtle(pos, 0.0, Color.BLACK); Point2D got = t.getPosition(); assertTrue("getPosition: wrong position returned", pos.equals(got)); assertTrue("getPosition: position should not be held using aggregation", t.getPosition() != t.getPosition()); } @Test public void testGetAngle() { Point2D pos = new Point2D(0.1, 0.1); double ang = -64.0; Color c = Color.BLUE; Turtle u = new Turtle(pos, ang, c); assertEquals("getAngle: wrong angle returned", ang, u.getAngle(), 1e-9); } }