From 912b3ff1a657e6f8a100d5bcc8ddefd295d52fb3 Mon Sep 17 00:00:00 2001
From: ashahidu <ashahidu@caltech.edu>
Date: Sun, 21 Feb 2021 16:06:01 -0700
Subject: [PATCH] Fix issues

---
 .../cs2/datastructures/BeaverMapsGraph.java   | 15 +----
 src/edu/caltech/cs2/datastructures/Graph.java |  2 +-
 .../caltech/cs2/interfaces/IDictionary.java   |  2 +
 src/edu/caltech/cs2/interfaces/IGraph.java    | 24 ++++----
 src/edu/caltech/cs2/project08/BeaverMaps.java |  1 +
 .../cs2/project08/MapsAutoCompleter.java      |  2 +
 .../caltech/cs2/project08/BeavermapTests.java | 60 +++++++++++++++----
 .../caltech/cs2/project08/DijkstraTest.java   | 19 +++---
 .../edu/caltech/cs2/project08/GraphTests.java | 32 ++++++++++
 9 files changed, 113 insertions(+), 44 deletions(-)

diff --git a/src/edu/caltech/cs2/datastructures/BeaverMapsGraph.java b/src/edu/caltech/cs2/datastructures/BeaverMapsGraph.java
index d824b98..f3372fa 100644
--- a/src/edu/caltech/cs2/datastructures/BeaverMapsGraph.java
+++ b/src/edu/caltech/cs2/datastructures/BeaverMapsGraph.java
@@ -2,18 +2,13 @@ package edu.caltech.cs2.datastructures;
 
 import com.google.gson.JsonElement;
 import com.google.gson.JsonParser;
-import edu.caltech.cs2.interfaces.IDeque;
-import edu.caltech.cs2.interfaces.IDictionary;
-import edu.caltech.cs2.interfaces.ISet;
+import edu.caltech.cs2.interfaces.*;
 
-import java.io.File;
 import java.io.FileReader;
 import java.io.IOException;
 
 
 public class BeaverMapsGraph extends Graph<Long, Double> {
-    private static JsonParser JSON_PARSER = new JsonParser();
-
     private IDictionary<Long, Location> ids;
     private ISet<Location> buildings;
 
@@ -117,12 +112,8 @@ public class BeaverMapsGraph extends Graph<Long, Double> {
      * @return the JSON data from filename
      */
     private static JsonElement fromFile(String filename) {
-        try {
-            return JSON_PARSER.parse(
-                    new FileReader(
-                            new File(filename)
-                    )
-            );
+        try (FileReader reader = new FileReader(filename)) {
+            return JsonParser.parseReader(reader);
         } catch (IOException e) {
             return null;
         }
diff --git a/src/edu/caltech/cs2/datastructures/Graph.java b/src/edu/caltech/cs2/datastructures/Graph.java
index da8d092..223b49c 100644
--- a/src/edu/caltech/cs2/datastructures/Graph.java
+++ b/src/edu/caltech/cs2/datastructures/Graph.java
@@ -2,7 +2,7 @@ package edu.caltech.cs2.datastructures;
 
 import edu.caltech.cs2.interfaces.*;
 
-public class Graph<V, E> extends IGraph<V, E> {
+public class Graph<V, E> implements IGraph<V, E> {
 
     @Override
     public boolean addVertex(V vertex) {
diff --git a/src/edu/caltech/cs2/interfaces/IDictionary.java b/src/edu/caltech/cs2/interfaces/IDictionary.java
index 588ec43..04c3f79 100644
--- a/src/edu/caltech/cs2/interfaces/IDictionary.java
+++ b/src/edu/caltech/cs2/interfaces/IDictionary.java
@@ -1,5 +1,7 @@
 package edu.caltech.cs2.interfaces;
 
+import edu.caltech.cs2.datastructures.LinkedDeque;
+
 public interface IDictionary<K, V> extends Iterable<K> {
 
     public static class Entry<K, V> {
diff --git a/src/edu/caltech/cs2/interfaces/IGraph.java b/src/edu/caltech/cs2/interfaces/IGraph.java
index 6e0e757..24a47c8 100644
--- a/src/edu/caltech/cs2/interfaces/IGraph.java
+++ b/src/edu/caltech/cs2/interfaces/IGraph.java
@@ -1,32 +1,32 @@
 package edu.caltech.cs2.interfaces;
 
-public abstract class IGraph<V, E> {
+public interface IGraph<V, E> {
     /**
      * Add a vertex to the graph.
      * @param vertex The vertex to add
      * @return true if vertex was not present already.
      */
-    public abstract boolean addVertex(V vertex);
+    public boolean addVertex(V vertex);
 
     /**
      * Adds edge e to the graph.
      *
      * @param e The edge to add.
      * @throws IllegalArgumentException
-     *             If e is not a valid edge (eg. refers to vertices not in the graph).
-     * @return true If e was not already present; false if it was (in which case the graph is still updated).
+     *             If src and dest are not valid vertices (eg. refers to vertices not in the graph).
+     * @return true If src and dest were not already present; false if it was (in which case the graph is still updated).
      */
-    public abstract boolean addEdge(V src, V dest, E e);
+    public boolean addEdge(V src, V dest, E e);
 
     /**
      * Adds edge e to the graph in both directionns.
      *
      * @param e The edge to add.
      * @throws IllegalArgumentException
-     *    If e is not a valid edge (eg. refers to vertices not in the graph).
-     * @return true If e was not already present in either direction; false if it was (in which case the graph is still updated).
+     *    If src and dest are not valid vertices (eg. refers to vertices not in the graph).
+     * @return true If src and dest were not already present in either direction; false if it was (in which case the graph is still updated).
      */
-    public abstract boolean addUndirectedEdge(V src, V dest, E e);
+    public boolean addUndirectedEdge(V src, V dest, E e);
 
     /**
      * Remove an edge from src to dest from the graph.
@@ -34,13 +34,13 @@ public abstract class IGraph<V, E> {
      * @throws IllegalArgumentException if src or dest is not in the graph.
      * @return true if an edge from src to dest edge was present.
      */
-    public abstract boolean removeEdge(V src, V dest);
+    public boolean removeEdge(V src, V dest);
 
     /**
      * Returns the set of vertices in the graph.
      * @return The set of all vertices in the graph.
      */
-    public abstract ISet<V> vertices();
+    public ISet<V> vertices();
 
     /**
      * Tests if vertices i and j are adjacent, returning the edge between
@@ -50,7 +50,7 @@ public abstract class IGraph<V, E> {
      * @return The edge from i to j if it exists in the graph;
      * 		   null otherwise.
      */
-    public abstract E adjacent(V i, V j);
+    public E adjacent(V i, V j);
 
     /**
      * Return the neighbours of a given vertex when this graph is treated as
@@ -60,5 +60,5 @@ public abstract class IGraph<V, E> {
      * @throws IllegalArgumentException if vertex is not in the graph.
      * @return The set of neighbors of vertex.
      */
-    public abstract ISet<V> neighbors(V vertex);
+    public ISet<V> neighbors(V vertex);
 }
\ No newline at end of file
diff --git a/src/edu/caltech/cs2/project08/BeaverMaps.java b/src/edu/caltech/cs2/project08/BeaverMaps.java
index 3acb98e..e11e8d1 100644
--- a/src/edu/caltech/cs2/project08/BeaverMaps.java
+++ b/src/edu/caltech/cs2/project08/BeaverMaps.java
@@ -5,6 +5,7 @@ import com.sun.net.httpserver.HttpExchange;
 import com.sun.net.httpserver.HttpHandler;
 import com.sun.net.httpserver.HttpServer;
 import edu.caltech.cs2.datastructures.BeaverMapsGraph;
+import edu.caltech.cs2.datastructures.LinkedDeque;
 import edu.caltech.cs2.datastructures.Location;
 import edu.caltech.cs2.interfaces.IDeque;
 import edu.caltech.cs2.interfaces.ISet;
diff --git a/src/edu/caltech/cs2/project08/MapsAutoCompleter.java b/src/edu/caltech/cs2/project08/MapsAutoCompleter.java
index db88dfa..7be91f5 100644
--- a/src/edu/caltech/cs2/project08/MapsAutoCompleter.java
+++ b/src/edu/caltech/cs2/project08/MapsAutoCompleter.java
@@ -1,6 +1,8 @@
 package edu.caltech.cs2.project08;
 
+import edu.caltech.cs2.datastructures.LinkedDeque;
 import edu.caltech.cs2.datastructures.Location;
+import edu.caltech.cs2.datastructures.TrieMap;
 import edu.caltech.cs2.interfaces.IDeque;
 import edu.caltech.cs2.interfaces.ISet;
 import edu.caltech.cs2.interfaces.ITrieMap;
diff --git a/tests/edu/caltech/cs2/project08/BeavermapTests.java b/tests/edu/caltech/cs2/project08/BeavermapTests.java
index bc4fddf..50c7327 100644
--- a/tests/edu/caltech/cs2/project08/BeavermapTests.java
+++ b/tests/edu/caltech/cs2/project08/BeavermapTests.java
@@ -9,7 +9,6 @@ import edu.caltech.cs2.datastructures.Location;
 import edu.caltech.cs2.helpers.Inspection;
 import edu.caltech.cs2.helpers.Reflection;
 
-import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileReader;
 import java.io.IOException;
@@ -22,7 +21,7 @@ import edu.caltech.cs2.interfaces.ISet;
 import org.hamcrest.MatcherAssert;
 import org.hamcrest.collection.IsIterableContainingInAnyOrder;
 import org.hamcrest.collection.IsIterableContainingInOrder;
-import org.hamcrest.core.IsCollectionContaining;
+import org.hamcrest.core.IsIterableContaining;
 import org.junit.jupiter.api.*;
 import org.junit.jupiter.api.MethodOrderer;
 import org.junit.jupiter.api.TestMethodOrder;
@@ -34,16 +33,12 @@ import static org.junit.jupiter.api.Assertions.*;
 @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
 public class BeavermapTests {
     private static String BEAVERMAP_GRAPH_SOURCE = "src/edu/caltech/cs2/datastructures/BeaverMapsGraph.java";
-    private static JsonParser JSON_PARSER = new JsonParser();
 
     private static JsonElement fromFile(String filename) {
-        try {
-            return JSON_PARSER.parse(
-                    new FileReader(
-                            new File(filename)
-                    )
-            );
-        } catch (IOException e) {
+        try (FileReader reader = new FileReader(filename)) {
+            return JsonParser.parseReader(reader);
+        }
+        catch (IOException e) {
             return null;
         }
     }
@@ -130,6 +125,22 @@ public class BeavermapTests {
         }
     }
 
+    @Tag("C")
+    @DisplayName("Test addVertex() updates BeaverMapsGraph properly")
+    @Test
+    public void testAddVertexBeaverMapsGraph() {
+        BeaverMapsGraph bmg = new BeaverMapsGraph(
+                "data/caltech/caltech.buildings.json",
+                "data/caltech/caltech.waypoints.json",
+                "data/caltech/caltech.roads.json");
+        JsonElement bs = fromFile("data/pasadena/pasadena.buildings.json");
+        for (JsonElement b : bs.getAsJsonArray()) {
+            Location loc = new Location(b.getAsJsonObject());
+            bmg.addVertex(loc);
+            assertNotNull(bmg.getLocationByID(loc.id), "Location id " + loc.id + " not found by id");
+        }
+    }
+
     @Tag("C")
     @DisplayName("BeaverMapsGraph implements required public methods")
     @Test
@@ -143,7 +154,7 @@ public class BeavermapTests {
                         .map(x -> x.getName())
                         .collect(Collectors.toList()));
         MatcherAssert.assertThat(new ArrayList<>(actual),
-                IsCollectionContaining.hasItems((expected.toArray())));
+                IsIterableContaining.hasItems((expected.toArray())));
     }
 
 
@@ -226,6 +237,33 @@ public class BeavermapTests {
         }
     }
 
+    @Tag("A")
+    @DisplayName("Test buildings are ignored in dijkstra path")
+    @Test
+    public void testDijkstraIgnoreBuildings() {
+        BeaverMapsGraph bmg = new BeaverMapsGraph(
+                "data/caltech/caltech.buildings.json",
+                "data/caltech/caltech.waypoints.json",
+                "data/caltech/caltech.roads.json");
+        JsonElement s = fromFile("data/caltech/caltech.paths_trace.json");
+        for (JsonElement b : s.getAsJsonArray()) {
+            JsonObject curr = b.getAsJsonObject();
+            Location start = bmg.getLocationByID(curr.get("start").getAsLong());
+            Location target = bmg.getLocationByID(curr.get("target").getAsLong());
+
+            IDeque<Location> actualPath = bmg.dijkstra(start, target);
+            if (actualPath == null) {
+                continue;
+            }
+            for (Location loc : actualPath){
+                if (loc.id == start.id || loc.id == target.id) {
+                    continue;
+                }
+                ISet<Location> buildings = Reflection.getFieldValue(BeaverMapsGraph.class, "buildings", bmg);
+                assertFalse(buildings.contains(loc), "Location " + loc.id + " in path is a building");
+            }
+        }
+    }
 
     @Tag("A")
     @DisplayName("Test Dijkstra")
diff --git a/tests/edu/caltech/cs2/project08/DijkstraTest.java b/tests/edu/caltech/cs2/project08/DijkstraTest.java
index 1070100..e8ad31e 100644
--- a/tests/edu/caltech/cs2/project08/DijkstraTest.java
+++ b/tests/edu/caltech/cs2/project08/DijkstraTest.java
@@ -77,10 +77,12 @@ public class DijkstraTest {
 
         Scanner s = new Scanner(new File("data/dijkstra/" + traceFile));
 
-        if (res == null) {
-            assertEquals(s.nextLine(), "null", "Path exists but was not found");
+        String line = s.nextLine();
+        if (line.equals("null")) {
+            assertNull(res, "Path does not exist but was found");
         }
         else {
+            assertNotNull(res, "Path exists but was not found");
             for (Location l : res) {
                 if (prev != null) {
                     pathLen += bmg.adjacent(prev.id, l.id);
@@ -88,7 +90,7 @@ public class DijkstraTest {
                 prev = l;
             }
 
-            double expectedLen = s.nextDouble();
+            double expectedLen = Double.parseDouble(line);
 
             assertEquals(expectedLen, pathLen, "Path lengths are not equivalent");
         }
@@ -97,7 +99,7 @@ public class DijkstraTest {
     @Order(3)
     @DisplayName("Tests Dijkstra on random graph and paths")
     @Test
-    public void dijkstraStressTest() throws FileNotFoundException{
+    public void dijkstraStressTest() throws FileNotFoundException {
         final int num_tests = 1000;
         IGraph<Integer, Integer> refg = new Graph<Integer, Integer>();
 
@@ -131,10 +133,12 @@ public class DijkstraTest {
             BeaverMapsGraph bmg = GraphMaker.transformToLocations(refg);
             IDeque<Location> res = bmg.dijkstra(new Location(startvertex), new Location(endvertex));
 
-            if (res == null) {
-                assertEquals(s.nextLine(), "null", "Path exists but was not found");
+            String line = s.nextLine();
+            if (line.equals("null")) {
+                assertNull(res, "Path does not exist but was found");
             }
             else {
+                assertNotNull(res, "Path exists but was not found");
                 double pathLen = 0;
                 Location prev = null;
                 for (Location l : res) {
@@ -144,8 +148,7 @@ public class DijkstraTest {
                     prev = l;
                 }
 
-                double expectedLen = s.nextDouble();
-                s.nextLine();
+                double expectedLen = Double.parseDouble(line);
                 assertEquals(expectedLen, pathLen, "Path lengths are not equivalent");
             }
         }
diff --git a/tests/edu/caltech/cs2/project08/GraphTests.java b/tests/edu/caltech/cs2/project08/GraphTests.java
index c38df58..c15c08c 100644
--- a/tests/edu/caltech/cs2/project08/GraphTests.java
+++ b/tests/edu/caltech/cs2/project08/GraphTests.java
@@ -187,6 +187,38 @@ public class GraphTests {
         });
     }
 
+    @Test
+    public void undirectedEdgeTest() {
+        assertTimeout(Duration.ofMillis(SIMPLE_OP_TIMEOUT_MS), () -> {
+            IGraph<String, Integer> g = new Graph<>();
+
+            assertTrue(g.addVertex("1"), "Should be able to add a vertex");
+            assertEquals(1, g.vertices().size(), "Should have correct number of vertices");
+            assertTrue(g.addVertex("2"), "Should be able to add a vertex");
+            assertEquals(2, g.vertices().size(), "Should have correct number of vertices");
+            assertTrue(g.addVertex("3"), "Should be able to add a vertex");
+            assertEquals(3, g.vertices().size(), "Should have correct number of vertices");
+
+            assertTrue(g.addUndirectedEdge("1", "2", 1), "Should be able to add new edge");
+            assertFalse(g.addEdge("1", "2", 1), "Should not be able to add new edge");
+            assertFalse(g.addEdge("1", "2", 2), "Should not be able to add new edge");
+            assertFalse(g.addEdge("2", "1", 1), "Should not be able to add new edge");
+            assertFalse(g.addEdge("2", "1", 2), "Should not be able to add new edge");
+
+            assertTrue(g.addUndirectedEdge("1", "3", 1), "Should be able to add new edge");
+            assertFalse(g.addEdge("1", "3", 1), "Should not be able to add new edge");
+            assertFalse(g.addEdge("1", "3", 2), "Should not be able to add new edge");
+            assertFalse(g.addEdge("3", "1", 1), "Should not be able to add new edge");
+            assertFalse(g.addEdge("3", "1", 2), "Should not be able to add new edge");
+
+            assertTrue(g.addUndirectedEdge("2", "3", 1), "Should be able to add new edge");
+            assertFalse(g.addEdge("2", "3", 1), "Should not be able to add new edge");
+            assertFalse(g.addEdge("2", "3", 2), "Should not be able to add new edge");
+            assertFalse(g.addEdge("3", "2", 1), "Should not be able to add new edge");
+            assertFalse(g.addEdge("3", "2", 2), "Should not be able to add new edge");
+        });
+    }
+
     @Test
     public void stringEdgeTest() {
         assertTimeout(Duration.ofMillis(SIMPLE_OP_TIMEOUT_MS), () -> {
-- 
GitLab