diff options
18 files changed, 422 insertions, 226 deletions
@@ -3,4 +3,5 @@ target/ .classpath .idea/ **.DS_Store** -maps.sqlite3
\ No newline at end of file +maps.sqlite3 +node_modules/
\ No newline at end of file diff --git a/data/empty.sqlite3 b/data/empty.sqlite3 Binary files differnew file mode 100644 index 0000000..3d10907 --- /dev/null +++ b/data/empty.sqlite3 diff --git a/data/lil_mock.sqlite3 b/data/lil_mock.sqlite3 Binary files differindex c326719..28b5b55 100644 --- a/data/lil_mock.sqlite3 +++ b/data/lil_mock.sqlite3 diff --git a/data/mock_trades.sqlite3 b/data/mock_trades.sqlite3 Binary files differindex 7658214..ade96f8 100644 --- a/data/mock_trades.sqlite3 +++ b/data/mock_trades.sqlite3 diff --git a/src/main/java/edu/brown/cs/student/term/DatabaseQuerier.java b/src/main/java/edu/brown/cs/student/term/DatabaseQuerier.java index f4be9b3..688270f 100644 --- a/src/main/java/edu/brown/cs/student/term/DatabaseQuerier.java +++ b/src/main/java/edu/brown/cs/student/term/DatabaseQuerier.java @@ -7,7 +7,7 @@ import java.time.Instant; import java.util.ArrayList; import java.util.List; -public class DatabaseQuerier{ +public class DatabaseQuerier { private static Connection conn = null; //TODO: Be prepared to overhaul this to account for IDs @@ -49,10 +49,19 @@ public class DatabaseQuerier{ while(rs.next()){ stocks.add(rs.getString(1)); } + + rs.close(); + prep.close(); return stocks; } - //TODO: Fill these in + /** + * Gets all the trades in by stock and buy type, ordered by time + * @param startDate - the start date of these trades + * @param endDate - the end date of these trades + * @return a list of list of trades as specified above + * @throws SQLException - if something goes wrong with connection + */ public List<List<Trade>> getAllTradesByStock(Instant startDate, Instant endDate) throws SQLException { List<List<Trade>> allTrades = new ArrayList<>(); List<String> stocks = getRecentStocks(startDate, endDate); @@ -64,6 +73,15 @@ public class DatabaseQuerier{ return allTrades; } + /** + * Gets a single stock's list of trades for that time period (either buy or sell) + * @param stock - string name of the stock to get the trades for + * @param isBuy - integer whether it's a buy or sell + * @param startDate - an Instant representing the start of the time period + * @param endDate - an Instant representing the end of the time period + * @return - a list of trades for that stock + * @throws SQLException - if issue getting connection + */ public List<Trade> getTradeByStock(String stock, int isBuy, Instant startDate, Instant endDate) throws SQLException{ List<Trade> trades = new ArrayList<>(); @@ -84,6 +102,9 @@ public class DatabaseQuerier{ rs.getDouble(8))); } + rs.close(); + prep.close(); + return trades; } } diff --git a/src/main/java/edu/brown/cs/student/term/Main.java b/src/main/java/edu/brown/cs/student/term/Main.java index 0a70b91..5ca40e8 100644 --- a/src/main/java/edu/brown/cs/student/term/Main.java +++ b/src/main/java/edu/brown/cs/student/term/Main.java @@ -1,9 +1,11 @@ package edu.brown.cs.student.term; +import com.google.common.collect.ImmutableMap; import edu.brown.cs.student.term.hub.Holder; import edu.brown.cs.student.term.hub.HubSearch; import edu.brown.cs.student.term.hub.LinkMapper; import edu.brown.cs.student.term.profit.StockHolding; +import edu.brown.cs.student.term.hub.SuspicionRanker; import edu.brown.cs.student.term.repl.Command; import edu.brown.cs.student.term.repl.REPL; import edu.brown.cs.student.term.repl.commands.LoadCommand; @@ -11,30 +13,13 @@ import edu.brown.cs.student.term.repl.commands.SetupCommand; import joptsimple.OptionParser; import joptsimple.OptionSet; -import java.sql.Connection; -import java.sql.Date; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.sql.Statement; import java.time.Instant; +import java.sql.Date; import java.util.HashMap; -import java.io.*; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import joptsimple.OptionParser; -import joptsimple.OptionSet; import spark.*; import spark.template.freemarker.FreeMarkerEngine; - -import java.io.BufferedReader; -import java.io.InputStreamReader; - -import com.google.common.collect.ImmutableMap; - import freemarker.template.Configuration; //fix @@ -42,46 +27,19 @@ import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; -import java.sql.ResultSet; -import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.*; -import com.google.common.collect.ImmutableMap; import com.google.gson.Gson; -import joptsimple.OptionParser; -import joptsimple.OptionSet; -import spark.ExceptionHandler; -import spark.ModelAndView; -import spark.QueryParamsMap; -import spark.Request; -import spark.Response; -import spark.Route; -import spark.Filter; -import spark.Spark; -import spark.TemplateViewRoute; -import spark.template.freemarker.FreeMarkerEngine; - -import freemarker.template.Configuration; - import org.json.JSONObject; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.sql.Statement; - /** * The Main class of our project. This is where execution begins. */ public final class Main { - // TODO: fix temproary solution public static JSONObject xmlLinks = null; - - private static final Gson GSON = new Gson(); private static final int DEFAULT_PORT = 4567; @@ -110,6 +68,9 @@ public final class Main { if (options.has("gui")) { runSparkServer((int) options.valueOf("port")); + //will auto connect to correct db when running gui! + SetupCommand setConnection = new SetupCommand(); + setConnection.run(new String[]{"data/trades.sqlite3"}); } HashMap<String, Command> commandHashMap = new HashMap<>(); @@ -157,31 +118,36 @@ public final class Main { return "OK"; }); - - Spark.before((request, response) -> response.header("Access-Control-Allow-Origin", "*")); - Spark.post("/data", new DataHandler()); + Spark.post("/data", new SuspicionRankHandler()); Spark.post("/profit", new ProfitQueryHandler()); } - - private static class DataHandler implements Route { + /** + * Gets the list of holders with id, name, and suspicion rank + */ + private static class SuspicionRankHandler implements Route { @Override + /** + * Expects that the request will contain two longs that are the start/end + * dates for the suspicion rank to run on as epoch time in milliseconds + */ public Object handle(Request request, Response response) throws Exception { - String str = request.body(); - xmlLinks = new JSONObject(str); //this is all the filedAt times and xml files - + //String str = request.body(); + //xmlLinks = new JSONObject(str); //this is all the filedAt times and xml files try { - DatabaseQuerier db = new DatabaseQuerier("data/trades.sqlite3"); - LinkMapper lm = new LinkMapper(db); - - Instant start = Instant.parse("2021-03-30T05:00:00.00Z"); - //12 am on 3/28 in UTC - Instant end = Instant.parse("2021-04-12T05:00:00.00Z"); - lm.makeFollowerLinks(start, end); - HubSearch hub = new HubSearch(lm); - Map<Holder, Double> him = hub.runHubSearch(start, end); - return GSON.toJson(him); + DatabaseQuerier db = SetupCommand.getDq(); + SuspicionRanker ranker = new SuspicionRanker(db); + + JSONObject data = new JSONObject(request.body()); + + long startMilli = data.getLong("start"); + long endMilli = data.getLong("end"); + Instant start = Instant.ofEpochMilli(startMilli); + Instant end = Instant.ofEpochMilli(endMilli); + List<Holder> suspiciousHolders = ranker.getSuspicionScoreList(start, end); + Map<String, Object> variables = ImmutableMap.of("holders", suspiciousHolders); + return GSON.toJson(variables); } catch (Exception e) { System.out.println("DBQuerier Test, couldn't connect to db???"); return "Error"; @@ -223,7 +189,9 @@ public final class Main { res.put("SP500", (1 + sp500PercentGain) * profit.getMoneyInput()); res.put("percentSP500", 100 * sp500PercentGain); return GSON.toJson(res); + } + } /** @@ -242,6 +210,4 @@ public final class Main { res.body(stacktrace.toString()); } } - - }
\ No newline at end of file diff --git a/src/main/java/edu/brown/cs/student/term/ProfitCalculation.java b/src/main/java/edu/brown/cs/student/term/ProfitCalculation.java index 28f7c79..88b4b04 100644 --- a/src/main/java/edu/brown/cs/student/term/ProfitCalculation.java +++ b/src/main/java/edu/brown/cs/student/term/ProfitCalculation.java @@ -362,6 +362,10 @@ public class ProfitCalculation { while (rs.next()) { int id = rs.getInt("holder_id"); this.person = rs.getString("holder_name"); + //TODO: Temporary fix for the moneyinput divide by 0 error + if(moneyInput == 0){ + moneyInput = 1; + } profitMap.put(id, this.calculateGains() / moneyInput); } } catch (SQLException throwables) { diff --git a/src/main/java/edu/brown/cs/student/term/hub/Holder.java b/src/main/java/edu/brown/cs/student/term/hub/Holder.java index abe59df..66def5e 100644 --- a/src/main/java/edu/brown/cs/student/term/hub/Holder.java +++ b/src/main/java/edu/brown/cs/student/term/hub/Holder.java @@ -5,6 +5,7 @@ import java.util.Objects; public class Holder { private int id; private String name; + private double suspicionScore; public Holder(int id, String name){ this.id = id; @@ -15,6 +16,12 @@ public class Holder { return id; } + public void setSuspicionScore(double sus){ + this.suspicionScore = sus; + } + + public double getSuspicionScore(){return suspicionScore;} + public String getName() { return name; } diff --git a/src/main/java/edu/brown/cs/student/term/hub/HubSearch.java b/src/main/java/edu/brown/cs/student/term/hub/HubSearch.java index 4d5755c..ccefeef 100644 --- a/src/main/java/edu/brown/cs/student/term/hub/HubSearch.java +++ b/src/main/java/edu/brown/cs/student/term/hub/HubSearch.java @@ -11,12 +11,10 @@ public class HubSearch { LinkMapper mapper; Map<Holder, Set<Holder>> followerToLeaderMap = new HashMap<>(); - //TODO: Make this just take in a map from holder -> set of holder public HubSearch(LinkMapper mapper){ this.mapper = mapper; } - //TODO: reevaluate this basic version and tweak to customize public Map<Holder, Double> runHubSearch(Instant start, Instant end){ followerToLeaderMap = mapper.makeFollowerLinks(start, end); int numHolders = followerToLeaderMap.size(); @@ -54,15 +52,9 @@ public class HubSearch { //dampening factor double damp = 0.15; /* - In normal page rank: - links is the pages that k links to, if k links to j, then - we want to add some weight to j from k, but that - weight is diluted by the number of links that k has - in general because we don't want to count a bunch of links - from a page as highly as one targeted link from one page to another In Hub Search - leader = j, follower = k, if follower links to (follows) leader, + we have the leader and follower if follower links to (follows) leader, then we want to add some weight from follower to leader, but should that weight be diluted by the number of people who followed leader or the number of people who follower followed @@ -87,62 +79,4 @@ public class HubSearch { return sum <= 0.001; } - - - - - - - - - - /* - def pageRank(pList: List[Page]): mutable.HashMap[Int, Double] = { - val n = pList.length - val weights = new Array[Double](n) - val r = new Array[Double](n) - val rPrime = Array.fill[Double](n)(1.0 / n) - - while (!distance(r, rPrime)) { - Array.copy(rPrime, 0, r, 0, n) - for (j <- 0 to n - 1) { - rPrime(j) = 0 - for (k <- 0 to n - 1) { - val wjk = getWeight(pList(j), pList(k), n) - rPrime(j) = (rPrime(j) + (wjk * r(k))) - } - } - } - - val pageRank = new mutable.HashMap[Int, Double]() - - for (i <- 0 to rPrime.length - 1) { - pageRank.put(pList(i).getID, rPrime(i)) - } - pageRank - } - - def getWeight(j: Page, k: Page, n: Int): Double = { - - val links = k.getLinks - val nk = links.size - - if (links.contains(j.getTitle.toLowerCase)) { - ((0.15 / n) + ((1 - 0.15) * (1.0 / nk))) - } else if (nk == 0) { - ((0.15 / n) + ((1 - 0.15) * (1.0 / n))) - } else { - (0.15 / n) - } - } - - def distance(r1: Array[Double], r2: Array[Double]): Boolean = { - var sum = 0.0 - for (i <- 0 to r1.length - 1) { - sum = sum + Math.pow((r1(i) - r2(i)), 2) - } - sum <= .001 - - } - */ } diff --git a/src/main/java/edu/brown/cs/student/term/hub/LinkMapper.java b/src/main/java/edu/brown/cs/student/term/hub/LinkMapper.java index 8bc8cf9..b490ea1 100644 --- a/src/main/java/edu/brown/cs/student/term/hub/LinkMapper.java +++ b/src/main/java/edu/brown/cs/student/term/hub/LinkMapper.java @@ -21,7 +21,7 @@ public class LinkMapper { /** - * Returns the follower => leaders map as is, does not update it + * Returns the follower to leaders map as is, does not update it * @return person to follower map */ public Map<Holder, Set<Holder>> getFollowerToLeaders() { @@ -29,9 +29,11 @@ public class LinkMapper { } /** - * The links between people and their followers who made the same trade + * This links a person and the set of people whose trades they followed * in the same time period - * @return the newly updated link map + * @param start - instant representing start of time period to look at + * @param end - instant representing end of time period to look at + * @return - the newly updated link map */ public Map<Holder, Set<Holder>> makeFollowerLinks(Instant start, Instant end){ if(databaseQuerier != null){ @@ -54,9 +56,10 @@ public class LinkMapper { return followerToLeaders; } - - //TODO: Try to create both leader => follower and follower => leader map at once - //only if necessary tho! + /** + * Converts a single trade list into entries in the follower to leader map + * @param tradeList - a list of trades for a single stock (either buy or sell) + */ private void convertTradeListToFollowerMap(List<Trade> tradeList){ List<Holder> holderList = new ArrayList<>(); diff --git a/src/main/java/edu/brown/cs/student/term/hub/SuspicionRanker.java b/src/main/java/edu/brown/cs/student/term/hub/SuspicionRanker.java index a1196d8..dd959f0 100644 --- a/src/main/java/edu/brown/cs/student/term/hub/SuspicionRanker.java +++ b/src/main/java/edu/brown/cs/student/term/hub/SuspicionRanker.java @@ -1,4 +1,53 @@ package edu.brown.cs.student.term.hub; +import edu.brown.cs.student.term.DatabaseQuerier; +import edu.brown.cs.student.term.ProfitCalculation; + +import java.time.Instant; +import java.sql.Date; +import java.util.*; + public class SuspicionRanker { + + DatabaseQuerier querier; + public SuspicionRanker(DatabaseQuerier db){ + this.querier = db; + } + + public <K, V extends Comparable<V>> V getMaxOfMap(Map<K, V> map) { + Map.Entry<K, V> maxEntry = Collections.max(map.entrySet(), Map.Entry.comparingByValue()); + System.out.println(maxEntry); + System.out.println(maxEntry.getValue()); + return maxEntry.getValue(); + } + + public List<Holder> getSuspicionScoreList(Instant start, Instant end){ + List<Holder> suspicionList = new ArrayList<>(); + try { + LinkMapper lm = new LinkMapper(querier); + HubSearch hub = new HubSearch(lm); + Map<Holder, Double> holderToHubScore = hub.runHubSearch(start, end); + + ProfitCalculation pc = new ProfitCalculation(DatabaseQuerier.getConn(), "", + new Date(start.toEpochMilli()), + new Date(end.toEpochMilli())); + + Map<Integer, Double> profitMap = pc.getProfitMap(); + + double profitMax = getMaxOfMap(profitMap); + + double hubMax = getMaxOfMap(holderToHubScore); + + for(Holder guy: holderToHubScore.keySet()){ + double normalizedProfitScore = profitMap.get(guy.getId()) / profitMax; + double normalizedHubScore = holderToHubScore.get(guy) / hubMax; + double suspicionScore = normalizedHubScore * 0.6 + normalizedProfitScore * 0.4; + guy.setSuspicionScore(suspicionScore); + suspicionList.add(guy); + } + } catch (Exception e) { + System.out.println("ERROR: Could not connect to database querier"); + } + return suspicionList; + } } diff --git a/src/main/java/edu/brown/cs/student/term/repl/Command.java b/src/main/java/edu/brown/cs/student/term/repl/Command.java index 056c7df..b110644 100644 --- a/src/main/java/edu/brown/cs/student/term/repl/Command.java +++ b/src/main/java/edu/brown/cs/student/term/repl/Command.java @@ -1,13 +1,13 @@ package edu.brown.cs.student.term.repl; /** - * Interface implemented by all five StarsCommand commands. - * Implemented by StarsCommand, NaiveNeighbors, NaiveRadiusCommand, RadiusCommand, NeighborsCommand + * Interface implemented by all the commands that the REPL is responsible for */ public interface Command { /** - * Main run method for every command. - * @param args arguments for the command + * The function that the command calls when run from the REPL + * @param args - the arguments for the command + * @return a string representation of the output, or error message */ String run(String[] args); } diff --git a/src/main/java/edu/brown/cs/student/term/repl/REPL.java b/src/main/java/edu/brown/cs/student/term/repl/REPL.java index a1d5c23..5381d45 100644 --- a/src/main/java/edu/brown/cs/student/term/repl/REPL.java +++ b/src/main/java/edu/brown/cs/student/term/repl/REPL.java @@ -16,6 +16,7 @@ public class REPL { /** * Constructor for a REPL object. + * @param userCommands - map of string to Command object for REPL to run */ public REPL(HashMap<String, Command> userCommands) { commands = userCommands; diff --git a/src/main/java/edu/brown/cs/student/term/repl/commands/SetupCommand.java b/src/main/java/edu/brown/cs/student/term/repl/commands/SetupCommand.java index e19117c..a6ef1f0 100644 --- a/src/main/java/edu/brown/cs/student/term/repl/commands/SetupCommand.java +++ b/src/main/java/edu/brown/cs/student/term/repl/commands/SetupCommand.java @@ -34,34 +34,6 @@ public class SetupCommand implements Command { System.out.println(error); return error; } - - try{ - /** Just for testing purposes **/ - //12 am on 3/12 in UTC - Instant start = Instant.parse("2021-03-12T05:00:00.00Z"); - //12 am on 3/27 in UTC - Instant end = Instant.parse("2021-03-27T05:00:00.00Z"); - - System.out.println(end.toEpochMilli()); - System.out.println(start.getEpochSecond()); - - ZonedDateTime zdt = ZonedDateTime.ofInstant(start, ZoneId.of("America/New_York")); - System.out.println(zdt.toString()); - List<List<Trade>> trades = dq.getAllTradesByStock(start, end); - - int sum = 0; - for(List<Trade> t: trades){ - System.out.println(t); - sum += t.size(); - } - - System.out.println("num of trades: " + sum); - - - } catch(Exception e){ - e.printStackTrace(); - } - return error; } diff --git a/src/test/java/edu/brown/cs/student/DBQuerierTest.java b/src/test/java/edu/brown/cs/student/DBQuerierTest.java index d813969..b3ea140 100644 --- a/src/test/java/edu/brown/cs/student/DBQuerierTest.java +++ b/src/test/java/edu/brown/cs/student/DBQuerierTest.java @@ -1,21 +1,18 @@ package edu.brown.cs.student; -import java.io.PrintStream; -import java.sql.SQLException; import java.time.Instant; import java.util.ArrayList; import java.util.List; import edu.brown.cs.student.term.DatabaseQuerier; -import edu.brown.cs.student.term.repl.commands.SetupCommand; import edu.brown.cs.student.term.trade.Trade; import org.junit.After; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertFalse; -//TODO: Write more tests for methods besides stock by name public class DBQuerierTest { /** these should span the entire mock dataset */ @@ -35,12 +32,6 @@ public class DBQuerierTest { } } - /* - * try{ - - } catch(Exception e) { - System.out.println("Error in test"); - }*/ @After public void tearDown() { @@ -50,34 +41,114 @@ public class DBQuerierTest { @Test public void testNonExistentStock(){ setUp(); + List<Trade> fakeStockList = new ArrayList<>(); + try{ + fakeStockList = db.getTradeByStock("NONO", 1, start, end); + } catch(Exception e) { + System.out.println("Error in test"); + } + assertTrue(fakeStockList.isEmpty()); + tearDown(); + } + + @Test + public void testEmptyDatabase(){ try{ - List<Trade> fakeStockList = db.getTradeByStock("NONO", 1, start, end); - assertTrue(fakeStockList.isEmpty()); + db = new DatabaseQuerier("data/empty.sqlite3"); + } catch(Exception e){ + System.out.println("DBQuerier Test, couldn't connect to db???"); + } + + List<Trade> gmeBadDatesList = new ArrayList<>(); + List<String> noStocks = new ArrayList<>(); + List<List<Trade>> noTrades = new ArrayList<>(); + try { + gmeBadDatesList = db.getTradeByStock("GME", 1, start, end); + noStocks = db.getRecentStocks(start, end); + noTrades = db.getAllTradesByStock(start, end); + } catch (Exception e){ + System.out.println("ERROR: in test"); + } + assertTrue(gmeBadDatesList.isEmpty()); + assertTrue(noStocks.isEmpty()); + assertTrue(noTrades.isEmpty()); + tearDown(); + } + + @Test + public void testEmptyStringStock(){ + setUp(); + List<Trade> fakeStockList = new ArrayList<>(); + try{ + fakeStockList = db.getTradeByStock("", 1, start, end); } catch(Exception e) { System.out.println("Error in test"); } + assertTrue(fakeStockList.isEmpty()); tearDown(); } @Test - public void testFlippedDates(){ + public void testNeitherIsBuyOrSell(){ setUp(); + List<Trade> fakeStockList = new ArrayList<>(); try{ - List<Trade> gmeBadDatesList = db.getTradeByStock("GME", 1, end, start); - assertTrue(gmeBadDatesList.isEmpty()); + fakeStockList = db.getTradeByStock("GME", 3, start, end); + } catch(Exception e) { + System.out.println("Error in test"); + } + assertTrue(fakeStockList.isEmpty()); + tearDown(); + } + @Test + public void testIsSell(){ + setUp(); + List<Trade> sellGMEList = new ArrayList<>(); + try{ + sellGMEList = db.getTradeByStock("GME", 0, start, end); } catch(Exception e) { System.out.println("Error in test"); } + assertEquals(7, sellGMEList.size()); + for(Trade t: sellGMEList){ + assertFalse(t.isBuy()); + } + tearDown(); + } + + + @Test + public void testFlippedDates(){ + setUp(); + List<Trade> gmeBadDatesList = new ArrayList<>(); + List<String> noStocks = new ArrayList<>(); + List<List<Trade>> noTrades = new ArrayList<>(); + try{ + gmeBadDatesList = db.getTradeByStock("GME", 1, end, start); + noStocks = db.getRecentStocks(end, start); + noTrades = db.getAllTradesByStock(end, start); + } catch(Exception e) { + System.out.println("Error in test"); + } + assertTrue(gmeBadDatesList.isEmpty()); + assertTrue(noStocks.isEmpty()); + assertTrue(noTrades.isEmpty()); tearDown(); } @Test public void testTradeByStockNameBuy(){ setUp(); + List<Trade> gmeBuyList = new ArrayList<>(); + List<Trade> teslaBuyList = new ArrayList<>(); try{ - List<Trade> gmeBuyList = db.getTradeByStock("GME", 1, start, end); + gmeBuyList = db.getTradeByStock("GME", 1, start, end); + teslaBuyList = db.getTradeByStock("TSLA", 1, start, end); + } catch(Exception e) { + System.out.println("Error in testTradeByStockName"); + } System.out.println(gmeBuyList); assertEquals(gmeBuyList.size(), 6); assertEquals(gmeBuyList.get(0).getId(), 482); @@ -85,16 +156,12 @@ public class DBQuerierTest { assertEquals(gmeBuyList.get(4).getId(), 275); assertEquals(gmeBuyList.get(5).getId(), 30); - - List<Trade> teslaBuyList = db.getTradeByStock("TSLA", 1, start, end); assertEquals(teslaBuyList.size(), 16); assertEquals(teslaBuyList.get(0).getId(), 328); assertEquals(teslaBuyList.get(7).getId(), 241); assertEquals(teslaBuyList.get(15).getId(), 774); - } catch(Exception e) { - System.out.println("Error in testTradeByStockName"); - } + tearDown(); } @@ -103,20 +170,60 @@ public class DBQuerierTest { public void testTradeByNameOrdering(){ setUp(); + List<Trade> gmeSellList = new ArrayList<>(); + List<Trade> amznBuyList = new ArrayList<>(); try{ - List<Trade> gmeSellList = db.getTradeByStock("GME", 0, start, end); - for(int i = 1; i < gmeSellList.size(); i++){ - assertTrue(gmeSellList.get(i-1).getTimestamp() < gmeSellList.get(i).getTimestamp()); - } + gmeSellList = db.getTradeByStock("GME", 0, start, end); + amznBuyList = db.getTradeByStock("AMZN", 1, start, end); + } catch(Exception e) { + System.out.println("Error in test"); + } - List<Trade> amznBuyList = db.getTradeByStock("AMZN", 1, start, end); - for(int i = 1; i < amznBuyList.size(); i++){ - assertTrue(amznBuyList.get(i-1).getTimestamp() < amznBuyList.get(i).getTimestamp()); - } + for(int i = 1; i < gmeSellList.size(); i++){ + assertTrue(gmeSellList.get(i-1).getTimestamp() < gmeSellList.get(i).getTimestamp()); + } - } catch(Exception e) { + + for(int i = 1; i < amznBuyList.size(); i++){ + assertTrue(amznBuyList.get(i-1).getTimestamp() < amznBuyList.get(i).getTimestamp()); + } + tearDown(); + } + + @Test + public void testGetRecentStocks(){ + setUp(); + List<String> stockNames = new ArrayList<>(); + try { + stockNames = db.getRecentStocks(start, end); + }catch(Exception e){ System.out.println("Error in test"); } + assertEquals(50, stockNames.size()); tearDown(); } + + @Test + public void testGetAllTradesByStock(){ + setUp(); + List<List<Trade>> trades = new ArrayList<>(); + try { + trades = db.getAllTradesByStock(start, end); + }catch(Exception e){ + System.out.println("Error in test"); + } + + assertEquals(100, trades.size()); + + for(List<Trade> tList: trades){ + Trade first = tList.get(0); + for(Trade t: tList){ + //all things in each list should be for the same stock and same isBuy type + assertEquals(first.isBuy(), t.isBuy()); + assertEquals(first.getStock(), t.getStock()); + } + } + tearDown(); + } + } diff --git a/src/test/java/edu/brown/cs/student/HubRankTest.java b/src/test/java/edu/brown/cs/student/HubRankTest.java index 9ba0987..cbe6112 100644 --- a/src/test/java/edu/brown/cs/student/HubRankTest.java +++ b/src/test/java/edu/brown/cs/student/HubRankTest.java @@ -7,9 +7,12 @@ import edu.brown.cs.student.term.hub.LinkMapper; import org.junit.After; import org.junit.Before; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import java.time.Instant; import java.util.Map; +import java.util.Set; public class HubRankTest { @@ -30,25 +33,66 @@ public class HubRankTest { } } - /* - * try{ - - } catch(Exception e) { - System.out.println("Error in test"); - }*/ - @After public void tearDown() { db = null; } @Test - public void testMapper(){ + public void testEmptyDB(){ + try{ + db = new DatabaseQuerier("data/empty.sqlite3"); + } catch(Exception e){ + System.out.println("DBQuerier Test, couldn't connect to db???"); + } + LinkMapper lm = new LinkMapper(db); + HubSearch hub = new HubSearch(lm); + Map<Holder, Double> hubRanks = hub.runHubSearch(start, end); + assertTrue(hubRanks.isEmpty()); + tearDown(); + } + + @Test + public void flippedDates(){ + setUp(); + LinkMapper lm = new LinkMapper(db); + HubSearch hub = new HubSearch(lm); + Map<Holder, Double> hubRanks = hub.runHubSearch(end, start); + assertTrue(hubRanks.isEmpty()); + tearDown(); + + } + + @Test + public void testHubRankSmall(){ setUp(); LinkMapper lm = new LinkMapper(db); - lm.makeFollowerLinks(start, end); HubSearch hub = new HubSearch(lm); - Map<Holder, Double> him = hub.runHubSearch(start, end); - System.out.println(him); + Map<Holder, Double> hubRanks = hub.runHubSearch(start, end); + assertEquals(6, hubRanks.size()); + tearDown(); + } + + @Test + public void testCheckRightValues(){ + setUp(); + LinkMapper lm = new LinkMapper(db); + HubSearch hub = new HubSearch(lm); + Map<Holder, Double> hubRanks = hub.runHubSearch(start, end); + Holder don = new Holder(1, "Don"); + Holder mitch = new Holder(2, "Mitch"); + Holder nancy = new Holder(3, "Nancy"); + Holder midge = new Holder(4, "Midge"); + Holder bob = new Holder(5, "Bob"); + Holder jane = new Holder(6, "Jane"); + + System.out.println(hubRanks); + assertTrue(hubRanks.get(mitch) > hubRanks.get(don)); + assertTrue(hubRanks.get(don) > hubRanks.get(bob)); + assertTrue(hubRanks.get(bob) > hubRanks.get(nancy)); + assertTrue(hubRanks.get(nancy)> hubRanks.get(jane)); + assertTrue(hubRanks.get(nancy) > hubRanks.get(midge)); + + tearDown(); } } diff --git a/src/test/java/edu/brown/cs/student/LinkMapperTest.java b/src/test/java/edu/brown/cs/student/LinkMapperTest.java index 2683b90..3d4bedc 100644 --- a/src/test/java/edu/brown/cs/student/LinkMapperTest.java +++ b/src/test/java/edu/brown/cs/student/LinkMapperTest.java @@ -10,6 +10,10 @@ import org.junit.Test; import java.time.Instant; import java.util.Map; +import java.util.Set; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + public class LinkMapperTest { @@ -30,26 +34,57 @@ public class LinkMapperTest { } } - /* - * try{ - - } catch(Exception e) { - System.out.println("Error in test"); - }*/ - @After public void tearDown() { db = null; } @Test - public void testMapper(){ + public void testBasicMapper(){ + setUp(); + LinkMapper lm = new LinkMapper(db); + Map<Holder, Set<Holder>> linkMap = lm.makeFollowerLinks(start, end); + //should be one for each person in little mock (6) + assertEquals(6, linkMap.keySet().size()); + + for(Holder h: linkMap.keySet()){ + //didn't follow anyone elses trades + if(h.getName().equals("Don") || h.getName().equals("Jane")){ + assertTrue(linkMap.get(h).isEmpty()); + //biggest follower + } else if(h.getName().equals("Midge")){ + assertEquals(4, linkMap.get(h).size()); + } else if(h.getName().equals("Nancy") || h.getName().equals("Mitch")){ + assertEquals(2, linkMap.get(h).size()); + } else { + //should be Bob, only followed Mitch + assertEquals(1, linkMap.get(h).size()); + } + } + tearDown(); + } + + @Test + public void testBadDate(){ setUp(); LinkMapper lm = new LinkMapper(db); - lm.makeFollowerLinks(start, end); - HubSearch hub = new HubSearch(lm); - Map<Holder, Double> him = hub.runHubSearch(start, end); - System.out.println(him); + Map<Holder, Set<Holder>> linkMap = lm.makeFollowerLinks(end, start); + assertTrue(linkMap.isEmpty()); + tearDown(); + } + + @Test + public void testEmptyDB(){ + try{ + db = new DatabaseQuerier("data/empty.sqlite3"); + } catch(Exception e){ + System.out.println("DBQuerier Test, couldn't connect to db???"); + } + LinkMapper lm = new LinkMapper(db); + Map<Holder, Set<Holder>> linkMap = lm.makeFollowerLinks(start, end); + //should be one for each person in little mock (6) + assertTrue(linkMap.isEmpty()); + } } diff --git a/src/test/java/edu/brown/cs/student/SuspicionRankerTest.java b/src/test/java/edu/brown/cs/student/SuspicionRankerTest.java new file mode 100644 index 0000000..d641507 --- /dev/null +++ b/src/test/java/edu/brown/cs/student/SuspicionRankerTest.java @@ -0,0 +1,52 @@ +package edu.brown.cs.student; + +import edu.brown.cs.student.term.DatabaseQuerier; +import edu.brown.cs.student.term.hub.Holder; +import edu.brown.cs.student.term.hub.HubSearch; +import edu.brown.cs.student.term.hub.LinkMapper; +import edu.brown.cs.student.term.hub.SuspicionRanker; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.time.Instant; +import java.util.List; +import java.util.Map; + +public class SuspicionRankerTest { + + //12 am on 3/11 in UTC + //private Instant start = Instant.parse("2021-03-11T05:00:00.00Z"); + private Instant start = Instant.ofEpochMilli(161800418000L); + //12 am on 3/28 in UTC + //private Instant end = Instant.parse("2021-03-28T05:00:00.00Z"); + private Instant end = Instant.ofEpochMilli(1618019436000L); + + private DatabaseQuerier db; + + @Before + public void setUp() { + try{ + db = new DatabaseQuerier("data/trades.sqlite3"); + } catch(Exception e){ + System.out.println("DBQuerier Test, couldn't connect to db???"); + } + } + + @After + public void tearDown() { + db = null; + } + + @Test + public void testMapper(){ + setUp(); + SuspicionRanker r = new SuspicionRanker(db); + List<Holder> him = r.getSuspicionScoreList(start, end); + //System.out.println(him); + for(Holder guy: him){ + System.out.println(guy.getName() + " " + guy.getSuspicionScore()); + } + tearDown(); + } +} |