diff --git a/.idea/runConfigurations/BeaverMapsGraph_Tests__C_.xml b/.idea/runConfigurations/BeaverMapsGraph_Tests__C_.xml new file mode 100644 index 0000000000000000000000000000000000000000..1a7e0adbc412932f4b4cb9e9791b37dfd8ad4f38 --- /dev/null +++ b/.idea/runConfigurations/BeaverMapsGraph_Tests__C_.xml @@ -0,0 +1,12 @@ +<component name="ProjectRunConfigurationManager"> + <configuration default="false" name="BeaverMapsGraph Tests (C)" type="JUnit" factoryName="JUnit"> + <module name="project08-beavermaps" /> + <option name="MAIN_CLASS_NAME" value="" /> + <option name="METHOD_NAME" value="" /> + <option name="TEST_OBJECT" value="tags" /> + <tag value="C & Beavermap" /> + <method v="2"> + <option name="Make" enabled="true" /> + </method> + </configuration> +</component> \ No newline at end of file diff --git a/src/edu/caltech/cs2/datastructures/BeaverMapsGraph.java b/src/edu/caltech/cs2/datastructures/BeaverMapsGraph.java index 96520b1c6881c31cf1bbcefd9295b625d2647c27..757eb661290e1e0667b059da377a9c8022f303d2 100644 --- a/src/edu/caltech/cs2/datastructures/BeaverMapsGraph.java +++ b/src/edu/caltech/cs2/datastructures/BeaverMapsGraph.java @@ -75,8 +75,7 @@ public class BeaverMapsGraph extends Graph<Long, Double> { } /** - * Returns a set of locations which are no more than threshold feet - * away from start. + * Returns a set of locations which are reachable along a path that goes no further than `threshold` feet from start * @param start the location to search around * @param threshold the number of feet in the search radius * @return diff --git a/tests/edu/caltech/cs2/project08/BeavermapTests.java b/tests/edu/caltech/cs2/project08/BeavermapTests.java index a592cc13bf0759e6c25b480b562eec36fe31050e..081a62b15e8411de691b5921cd3f380c3e26b249 100644 --- a/tests/edu/caltech/cs2/project08/BeavermapTests.java +++ b/tests/edu/caltech/cs2/project08/BeavermapTests.java @@ -44,6 +44,26 @@ public class BeavermapTests { } @Tag("C") + @Tag("Beavermap") + @DisplayName("BeaverMapsGraph implements required public methods") + @Test + @Order(0) + public void testMethodsBeaverMapsGraph() { + SortedSet<String> expected = new TreeSet<>(List.of( + "getLocationByName", "getBuildings", "getClosestBuilding", "dfs", "dijkstra", "addVertex" + )); + SortedSet<String> actual = new TreeSet<>( + Stream.of(BeaverMapsGraph.class.getDeclaredMethods()) + .filter(Reflection.hasModifier("public")) + .map(x -> x.getName()) + .collect(Collectors.toList())); + MatcherAssert.assertThat(new ArrayList<>(actual), + IsIterableContaining.hasItems((expected.toArray()))); + } + + @Tag("C") + @Tag("Beavermap") + @Order(1) @DisplayName("Does not use or import disallowed classes") @Test public void testForInvalidClasses() { @@ -52,10 +72,11 @@ public class BeavermapTests { Inspection.assertNoUsageOf(BEAVERMAP_GRAPH_SOURCE, graphDisallow); } - @Order(1) + @Order(2) @DisplayName("Does not use or import disallowed classes from java.util") @Test @Tag("C") + @Tag("Beavermap") public void testForInvalidImportsJavaUtil() { List<String> allowed = List.of("Iterator"); Inspection.assertNoImportsOfExcept(BEAVERMAP_GRAPH_SOURCE, "java\\.util", allowed); @@ -67,7 +88,10 @@ public class BeavermapTests { // Only use Caltech map and buildings to test for correctness @Tag("C") + @Tag("Beavermap") @Test + @Order(3) + @DisplayName("Test getLocationById()") public void testGetLocationByID() { BeaverMapsGraph bmg = new BeaverMapsGraph( "data/caltech/caltech.buildings.json", @@ -81,7 +105,10 @@ public class BeavermapTests { } @Tag("C") + @Tag("Beavermap") @Test + @Order(4) + @DisplayName("Test getLocationByName()") public void testGetLocationByName() { BeaverMapsGraph bmg = new BeaverMapsGraph( "data/caltech/caltech.buildings.json", @@ -97,12 +124,14 @@ public class BeavermapTests { } @Tag("C") + @Tag("Beavermap") @DisplayName("Test getBuildings()") @ParameterizedTest(name = "Test getBuildings() on {0}") @CsvSource({ "caltech/caltech.buildings.json, caltech/caltech.waypoints.json, caltech/caltech.roads.json", "pasadena/pasadena.buildings.json, pasadena/pasadena.waypoints.json, pasadena/pasadena.roads.json", }) + @Order(5) public void testGetBuildings(String buildingsFile, String waypointsFile, String roadsFile) { BeaverMapsGraph bmg = new BeaverMapsGraph( "data/" + buildingsFile, "data/" + waypointsFile, "data/" + roadsFile); @@ -117,12 +146,14 @@ public class BeavermapTests { } @Tag("C") + @Tag("Beavermap") @DisplayName("Test getClosestBuilding()") @ParameterizedTest(name = "Test getClosestBuilding() on {0}") @CsvSource({ "caltech/caltech.buildings.json, caltech/caltech.waypoints.json, caltech/caltech.roads.json, caltech/caltech.closest_trace.json", "pasadena/pasadena.buildings.json, pasadena/pasadena.waypoints.json, pasadena/pasadena.roads.json, pasadena/pasadena.closest_trace.json", }) + @Order(6) public void testGetClosestLocation(String buildingsFile, String waypointsFile, String roadsFile, String traceFile) { BeaverMapsGraph bmg = new BeaverMapsGraph( "data/" + buildingsFile, "data/" + waypointsFile, "data/" + roadsFile); @@ -138,8 +169,10 @@ public class BeavermapTests { } @Tag("C") - @DisplayName("Test addVertex() updates BeaverMapsGraph properly") + @Tag("Beavermap") + @DisplayName("Test addVertex() updates BeaverMapsGraph and underlying Graph properly") @Test + @Order(7) public void testAddVertexBeaverMapsGraph() { BeaverMapsGraph bmg = new BeaverMapsGraph( "data/caltech/caltech.buildings.json", @@ -150,33 +183,20 @@ public class BeavermapTests { Location loc = new Location(b.getAsJsonObject()); bmg.addVertex(loc); assertNotNull(bmg.getLocationByID(loc.id), "Location id " + loc.id + " not found by id"); + // Test that the vertex was actually added to the graph + bmg.neighbors(loc.id); } } - @Tag("C") - @DisplayName("BeaverMapsGraph implements required public methods") - @Test - public void testMethodsBeaverMapsGraph() { - SortedSet<String> expected = new TreeSet<>(List.of( - "getLocationByName", "getBuildings", "getClosestBuilding", "dfs", "dijkstra", "addVertex" - )); - SortedSet<String> actual = new TreeSet<>( - Stream.of(BeaverMapsGraph.class.getDeclaredMethods()) - .filter(Reflection.hasModifier("public")) - .map(x -> x.getName()) - .collect(Collectors.toList())); - MatcherAssert.assertThat(new ArrayList<>(actual), - IsIterableContaining.hasItems((expected.toArray()))); - } - - // Note: Pasadena map is WAY TOO LARGE to test all edges, don't try @Tag("C") - @DisplayName("Tests nodes and edges in map for filename") + @Tag("Beavermap") + @DisplayName("Completely check all nodes and edges in BeaverMapsGraph loaded from files") @ParameterizedTest(name = "Test nodes in file {0}") @CsvSource({ "caltech/caltech.buildings.json, caltech/caltech.waypoints.json, caltech/caltech.roads.json, caltech/caltech.neighbors_trace.json" }) + @Order(8) public void testNodesEdgesInMap(String bFile, String wFile, String roadsFile, String traceFile) { BeaverMapsGraph bmg = new BeaverMapsGraph("data/" + bFile, "data/" + wFile, "data/" + roadsFile); @@ -204,6 +224,7 @@ public class BeavermapTests { } // Use this instead of MatcherAssert to provide better errors (though I doubt they'll be needed) + // Should use Truth instead... but not this year. if (missingNeighbors.size() > 0) { fail(locID + " missing neighbors " + missingNeighbors); } else if (actualNeighbors.size() != 0) { @@ -221,6 +242,7 @@ public class BeavermapTests { "caltech/caltech.buildings.json, caltech/caltech.waypoints.json, caltech/caltech.roads.json, caltech/caltech.radius_trace.json", "pasadena/pasadena.buildings.json, pasadena/pasadena.waypoints.json, pasadena/pasadena.roads.json, pasadena/pasadena.radius_trace.json", }) + @Order(9) public void testDFSRadius(String buildingsFile, String waypointsFile, String roadsFile, String traceFile) { BeaverMapsGraph bmg = new BeaverMapsGraph( @@ -252,6 +274,7 @@ public class BeavermapTests { @Tag("A") @DisplayName("Test buildings are ignored in dijkstra path") @Test + @Order(10) public void testDijkstraIgnoreBuildings() { BeaverMapsGraph bmg = new BeaverMapsGraph( "data/caltech/caltech.buildings.json", @@ -284,6 +307,7 @@ public class BeavermapTests { "caltech/caltech.buildings.json, caltech/caltech.waypoints.json, caltech/caltech.roads.json, caltech/caltech.paths_trace.json", "pasadena/pasadena.buildings.json, pasadena/pasadena.waypoints.json, pasadena/pasadena.roads.json, pasadena/pasadena.paths_trace.json", }) + @Order(11) public void testDijkstraBeaverMap(String buildingsFile, String waypointsFile, String roadsFile, String traceFile) throws FileNotFoundException { BeaverMapsGraph bmg = new BeaverMapsGraph( "data/" + buildingsFile, "data/" + waypointsFile, "data/" + roadsFile); diff --git a/tests/edu/caltech/cs2/project08/DijkstraTest.java b/tests/edu/caltech/cs2/project08/DijkstraTest.java index e159e6cddc8542dfc360ecf115d7a2f007cffda3..047e86d129a8bdac5620512e96164d88b2229633 100644 --- a/tests/edu/caltech/cs2/project08/DijkstraTest.java +++ b/tests/edu/caltech/cs2/project08/DijkstraTest.java @@ -7,10 +7,7 @@ import edu.caltech.cs2.helpers.Reflection; import edu.caltech.cs2.interfaces.IDeque; import edu.caltech.cs2.interfaces.IGraph; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.*; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; @@ -25,13 +22,14 @@ import java.util.Scanner; import static org.junit.jupiter.api.Assertions.*; @Tag("A") +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) public class DijkstraTest { @Order(0) @DisplayName("Loop path should be singleton") @Test public void dijkstraShortTripTest() { - IDeque<Location> res = GraphMaker.transformToLocations(GraphMaker.generateCompleteGraph(10)).dijkstra(new Location(1), new Location(1)); + IDeque<Location> res = GraphMaker.transformToLocations(GraphMaker.completeGraph(10)).dijkstra(new Location(1), new Location(1)); assertEquals(1, res.size(), "Path from a node to itself should only include the node once"); assertEquals(res.peek(), new Location(1), "Path from a node to itself should only include the node once"); } @@ -40,27 +38,27 @@ public class DijkstraTest { @DisplayName("Disconnected graph should not have a path") @Test public void dijkstraDisconnectedTest() { - IDeque<Location> res = GraphMaker.transformToLocations(GraphMaker.generateDisjointCompleteGraphs(10)).dijkstra(new Location(1), new Location(9)); + IDeque<Location> res = GraphMaker.transformToLocations(GraphMaker.disjointCompleteGraphs(10)).dijkstra(new Location(1), new Location(9)); assertNull(res, "Disconnected graph should give null path"); } @Order(2) - @ParameterizedTest + @ParameterizedTest(name = "Graph: {0}, start: {1}, end: {2}, trace file: {3}") @DisplayName("Tests correctness of Dijkstra implementation") @CsvSource({ - "graph1, 1, 3, simple_1_3", - "graph2, 0, 1, line_0_1", - "graph2, 0, 5, line_0_5", - "graph2, 0, 20, line_0_20", - "graph2, 0, 99, line_0_99", - "graph2, 1, 0, line_1_0", - "graph3, 0, 1, graph3_0_1", - "graph3, 99, 0, graph3_99_0" + "simpleGraph, 1, 3, simple_1_3", + "linearGraph, 0, 1, line_0_1", + "linearGraph, 0, 5, line_0_5", + "linearGraph, 0, 20, line_0_20", + "linearGraph, 0, 99, line_0_99", + "linearGraph, 1, 0, line_1_0", + "tournamentGraph, 0, 1, graph3_0_1", + "tournamentGraph, 99, 0, graph3_99_0" }) public void dijkstraTestGraph(String graphName, int start, int end, String traceFile) throws IllegalAccessException, InvocationTargetException, FileNotFoundException { BeaverMapsGraph bmg; - if (graphName.equals("graph1")) { + if (graphName.equals("simpleGraph")) { Method graphGen = Reflection.getMethod(GraphMaker.class, graphName); bmg = GraphMaker.transformToLocations( (IGraph<Integer, Integer>) graphGen.invoke(null)); @@ -121,6 +119,7 @@ public class DijkstraTest { two = (two + 1) % num_vertices; int dice = r.nextInt(5); + // TODO: y if (dice <= 4) { refg.addEdge(one, two, r.nextInt(100)); } else if (dice <= 5) { @@ -135,10 +134,10 @@ public class DijkstraTest { String line = s.nextLine(); if (line.equals("null")) { - assertNull(res, "Path does not exist from " + startvertex + " to " + endvertex + " but was found"); + assertNull(res, "Path does not exist from " + startvertex + " to " + endvertex + " but a path was found"); } else { - assertNotNull(res, "Path exists from " + startvertex + " to " + endvertex + " but was not found"); + assertNotNull(res, "Path exists from " + startvertex + " to " + endvertex + " but a path was not found"); double pathLen = 0; Location prev = null; for (Location l : res) { @@ -149,7 +148,7 @@ public class DijkstraTest { } double expectedLen = Double.parseDouble(line); - assertEquals(expectedLen, pathLen, "Path lengths are not equivalent"); + assertEquals(expectedLen, pathLen, "Path is not the shortest path by length"); } } } diff --git a/tests/edu/caltech/cs2/project08/GraphMaker.java b/tests/edu/caltech/cs2/project08/GraphMaker.java index 770da6dc8d07073efe3eb02bd64cfda8d6242343..2f1a5f2153b0ba15c833815159015d327da82d77 100644 --- a/tests/edu/caltech/cs2/project08/GraphMaker.java +++ b/tests/edu/caltech/cs2/project08/GraphMaker.java @@ -27,7 +27,7 @@ public class GraphMaker { * Generate a simple graph * @return graph */ - public static IGraph<Integer, Integer> generateSimpleGraph() { + public static IGraph<Integer, Integer> simpleGraph() { IGraph<Integer, Integer> g = new Graph<>(); g.addVertex(1); g.addVertex(2); @@ -43,7 +43,7 @@ public class GraphMaker { * @param n - number of vertices in the linear graph * @return graph, with edges labelled with the source vertex */ - public static IGraph<Integer, Integer> generateLinearGraph(int n) { + public static IGraph<Integer, Integer> linearGraph(int n) { IGraph<Integer, Integer> g = new Graph<>(); for (int i = 0; i < n; i++) { assertTrue(g.addVertex(i), "Adding a new vertex should return true"); @@ -81,7 +81,7 @@ public class GraphMaker { * @param n - number of vertices * @return graph */ - public static IGraph<Integer, Integer> generateTournamentGraph(int n) { + public static IGraph<Integer, Integer> tournamentGraph(int n) { IGraph<Integer, Integer> g = new Graph<>(); for (int i = 0; i < n; i++) { assertTrue(g.addVertex(i), "Adding a new vertex should return true"); @@ -115,7 +115,7 @@ public class GraphMaker { * @param n - number of vertices * @return graph */ - public static IGraph<Integer, Integer> generateCompleteGraph(int n) { + public static IGraph<Integer, Integer> completeGraph(int n) { IGraph<Integer, Integer> g = new Graph<>(); for (int i = 0; i < n; i++) { assertTrue(g.addVertex(i), "Adding a new vertex should return true"); @@ -153,7 +153,7 @@ public class GraphMaker { * @param n - number of vertices in each complete component * @return graph */ - public static IGraph<Integer, Integer> generateDisjointCompleteGraphs(int n) { + public static IGraph<Integer, Integer> disjointCompleteGraphs(int n) { IGraph<Integer, Integer> g = new Graph<>(); for (int i = 0; i < n; i++) { assertTrue(g.addVertex(i), "Adding a new vertex should return true"); diff --git a/tests/edu/caltech/cs2/project08/GraphTests.java b/tests/edu/caltech/cs2/project08/GraphTests.java index c1d52ce18135bb5e07ea8312a7535b8f3226ecb6..bdddca1d4d5d93799952a67b1b38e89f262951b1 100644 --- a/tests/edu/caltech/cs2/project08/GraphTests.java +++ b/tests/edu/caltech/cs2/project08/GraphTests.java @@ -57,11 +57,11 @@ public class GraphTests { @DisplayName("Test creating various graphs") public void creationTest() { assertTimeout(Duration.ofMillis(MEDIUM_OP_TIMEOUT_MS), () -> { - GraphMaker.generateSimpleGraph(); - GraphMaker.verifyLinearGraph(GraphMaker.generateLinearGraph(100), 100); - GraphMaker.verifyTournamentGraph(GraphMaker.generateTournamentGraph(100), 100); - GraphMaker.verifyCompleteGraph(GraphMaker.generateCompleteGraph(100), 100); - GraphMaker.verifyDisjointCompleteGraphs(GraphMaker.generateDisjointCompleteGraphs(100), 100); + GraphMaker.simpleGraph(); + GraphMaker.verifyLinearGraph(GraphMaker.linearGraph(100), 100); + GraphMaker.verifyTournamentGraph(GraphMaker.tournamentGraph(100), 100); + GraphMaker.verifyCompleteGraph(GraphMaker.completeGraph(100), 100); + GraphMaker.verifyDisjointCompleteGraphs(GraphMaker.disjointCompleteGraphs(100), 100); }); } @@ -206,7 +206,7 @@ public class GraphTests { @DisplayName("Test that all edges in a complete graph are present") public void adjacentStressTest() { assertTimeout(Duration.ofMillis(STRESS_OP_TIMEOUT_MS), () -> { - IGraph<Integer, Integer> g = GraphMaker.generateCompleteGraph(400); + IGraph<Integer, Integer> g = GraphMaker.completeGraph(400); for (int i = 0; i < 400; i++) for (int j = 0; j < 400; j++) if (i != j) @@ -219,7 +219,7 @@ public class GraphTests { @DisplayName("Test that directed edges in a tournament graph are correct") public void testNeighbors() { assertTimeout(Duration.ofMillis(SIMPLE_OP_TIMEOUT_MS), () -> { - IGraph<Integer, Integer> g = GraphMaker.generateTournamentGraph(10); + IGraph<Integer, Integer> g = GraphMaker.tournamentGraph(10); Set<Integer> vertices = new HashSet<Integer>(); for (int i = 0; i < 10; i++) { diff --git a/tests/edu/caltech/cs2/project08/MarvelTests.java b/tests/edu/caltech/cs2/project08/MarvelTests.java index 11a3c190fa5da167189c0e4b8bb206b29848ce43..06320c88a360627382dbeda3951a003e68a01f21 100644 --- a/tests/edu/caltech/cs2/project08/MarvelTests.java +++ b/tests/edu/caltech/cs2/project08/MarvelTests.java @@ -13,7 +13,7 @@ import java.util.*; import static org.junit.jupiter.api.Assertions.*; @Tag("C") -@DisplayName("Test graph of shared appearances in Marvel comic books") +@DisplayName("Test graph of shared appearances in Marvel comic books (MarvelTests)") public class MarvelTests { private static Graph<String, Integer> MARVEL_GRAPH; private static final int COMMON_TIMEOUT_MS = 1500;