From 44c9da6f43bc38119da3314a7c8c140289849c20 Mon Sep 17 00:00:00 2001 From: Sten Laane Date: Sat, 23 Mar 2019 17:43:04 +0000 Subject: [PATCH] better exception handling + some unit testing --- pom.xml | 9 +- .../stocktracker/CurrencyRateFetcher.java | 35 +++---- .../java/stocktracker/DataAggregator.java | 95 +++++++++--------- src/main/java/stocktracker/FileManager.java | 8 +- .../java/stocktracker/StockInfoFetcher.java | 99 +++++++++---------- src/main/java/stocktracker/StockTracker.java | 54 +++++++--- .../java/stocktracker/StockTrackerGUI.java | 2 +- .../stocktracker/CurrencyRateFetcherTest.java | 54 ++++++++++ .../java/stocktracker/DataAggregatorTest.java | 79 +++++++++++++++ .../stocktracker/StockInfoFetcherTest.java | 75 ++++++++++++++ .../java/stocktracker/StockTrackerTest.java | 54 ++++++++++ 11 files changed, 423 insertions(+), 141 deletions(-) create mode 100644 src/test/java/stocktracker/CurrencyRateFetcherTest.java create mode 100644 src/test/java/stocktracker/DataAggregatorTest.java create mode 100644 src/test/java/stocktracker/StockInfoFetcherTest.java create mode 100644 src/test/java/stocktracker/StockTrackerTest.java diff --git a/pom.xml b/pom.xml index 843e484..8ba1de5 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ Laane.Sten StockTracker - 1.1.3 + 1.2.0 UTF-8 @@ -38,6 +38,12 @@ jmetro 5.2 + + org.junit.jupiter + junit-jupiter-api + 5.3.2 + test + scm:git:https://github.com/StenAL/StockTracker @@ -142,6 +148,7 @@ ${project.build.directory} + *${project.version}*-dependencies*.jar *${project.version}*.zip diff --git a/src/main/java/stocktracker/CurrencyRateFetcher.java b/src/main/java/stocktracker/CurrencyRateFetcher.java index e5bd8ce..51736f3 100644 --- a/src/main/java/stocktracker/CurrencyRateFetcher.java +++ b/src/main/java/stocktracker/CurrencyRateFetcher.java @@ -27,44 +27,39 @@ private CurrencyRateFetcher(String currencyCode) { this.xmlParser = new XMLParser(); } - public static void main(String[] args) { - writeCurrencyInfo("USD", LocalDate.of(2018, 9, 24)); + public static void main(String[] args) throws IOException { + writeCurrencyInfo("USDD", LocalDate.of(2018, 9, 24)); } - static void writeCurrencyInfo(String currencyCode, LocalDate firstDate) { + static void writeCurrencyInfo(String currencyCode, LocalDate firstDate) throws IOException { CurrencyRateFetcher fetcher = new CurrencyRateFetcher(currencyCode); String url_str = "https://sdw-wsrest.ecb.europa.eu/service/data/EXR/D." + currencyCode + ".EUR.SP00.A?startPeriod=" + firstDate + "&detail=dataonly"; - try { - fetcher.xmlParser.downloadXMLFile(new URL(url_str)); - List dataList = fetcher.xmlParser.parse(StockTracker.PATH); - FileManager.writeList(StockTracker.PATH + currencyCode + "_temp.txt", dataList); - System.out.println("Fetching " + currencyCode + " done"); - } catch (Exception e) { - e.printStackTrace(); - } + fetcher.xmlParser.downloadXMLFile(new URL(url_str)); + List dataList = fetcher.xmlParser.parse(StockTracker.PATH); + FileManager.writeList(StockTracker.PATH + currencyCode + "_temp.txt", dataList); + System.out.println("Fetching " + currencyCode + " done"); } private class XMLParser { - private void downloadXMLFile(URL url) { - try { + private void downloadXMLFile(URL url) throws IOException { final HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setDoInput(true); connection.setDoOutput(true); connection.setRequestMethod("GET"); connection.setRequestProperty("Accept", "text/xml"); - //TODO: Unit testing - assert response code 200 System.out.println("Response code: " + connection.getResponseCode()); String readStream = readStream(connection.getInputStream()); - List lines = Arrays.asList(readStream.split("\n")); - Path file = Paths.get(StockTracker.PATH + currencyCode + "_XML_temp.xml"); - Files.write(file, lines, Charset.forName("UTF-8")); - } catch (Exception e) { - e.printStackTrace(); - } + try { + List lines = Arrays.asList(readStream.split("\n")); + Path file = Paths.get(StockTracker.PATH + currencyCode + "_XML_temp.xml"); + Files.write(file, lines, Charset.forName("UTF-8")); + } catch (IOException e) { + e.printStackTrace(); + } } /** diff --git a/src/main/java/stocktracker/DataAggregator.java b/src/main/java/stocktracker/DataAggregator.java index 3ce89a6..6b9eb62 100644 --- a/src/main/java/stocktracker/DataAggregator.java +++ b/src/main/java/stocktracker/DataAggregator.java @@ -1,28 +1,27 @@ package stocktracker; -import java.nio.file.Files; -import java.nio.file.Paths; +import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; class DataAggregator { // TODO: Padding money and stock decimal places with zeroes - public static void main(String[] args) { + public static void main(String[] args) throws IOException { test(); } - private static void test() { + private static void test() throws IOException { ArrayList testList = new ArrayList<>(); + testList.add("QQ_USD"); testList.add("IVV_USD"); - testList.add("QQQ_USD"); ArrayList testAmounts = new ArrayList<>(); testAmounts.add(5); testAmounts.add(10); calculateMoney(testList, testAmounts); } - static void calculateMoney(List ticker_currency, List stockAmounts) { + static void calculateMoney(List ticker_currency, List stockAmounts) throws IOException { aggregate(ticker_currency); List finalData = FileManager.readLines(StockTracker.PATH + "aggregated_temp.txt"); List dateMoney = new ArrayList<>(); @@ -43,7 +42,7 @@ static void calculateMoney(List ticker_currency, List stockAmoun FileManager.writeList(StockTracker.PATH + "money.txt", dateMoney); } - private static void aggregate(List ticker_currency) { + private static void aggregate(List ticker_currency) throws IOException { String workingDir = StockTracker.PATH; for (String combination: ticker_currency) { aggregate(combination); @@ -76,7 +75,7 @@ private static void aggregate(List ticker_currency) { * on dates with no values. If the first day of the whole file happens to be a market * holiday then we use the next available day's close value instead. */ - private static void aggregate(String ticker_currency) { + private static void aggregate(String ticker_currency) throws IOException { String workingDir = StockTracker.PATH; String ticker = ticker_currency.split("_")[0]; String currency = ticker_currency.split("_")[1]; @@ -86,57 +85,53 @@ private static void aggregate(String ticker_currency) { List missingDates = new ArrayList<>(); List currencyRates = new ArrayList<>(); List stockRates = new ArrayList<>(); - try { - for (String line: FileManager.readLines(workingDir + ticker + "_temp.txt")) { - stockDates.add(line.split(" ")[0]); - stockRates.add(line.split(" ")[1]); - } + for (String line: FileManager.readLines(workingDir + ticker + "_temp.txt")) { + stockDates.add(line.split(" ")[0]); + stockRates.add(line.split(" ")[1]); + } - for (String line: FileManager.readLines(workingDir + currency + "_temp.txt")) { - currencyDates.add(line.split(" ")[0]); - currencyRates.add(line.split(" ")[1]); - } + for (String line: FileManager.readLines(workingDir + currency + "_temp.txt")) { + currencyDates.add(line.split(" ")[0]); + currencyRates.add(line.split(" ")[1]); + } - for (String stockDate: stockDates) { - aggregateDates.add(stockDate); - if (!currencyDates.contains(stockDate)) {missingDates.add(stockDate + " C");} // C for currency - } - for (String currencyDate: currencyDates) { - if (!aggregateDates.contains(currencyDate)) { - missingDates.add(currencyDate + " S"); // S for stock - aggregateDates.add(currencyDate); - } + for (String stockDate: stockDates) { + aggregateDates.add(stockDate); + if (!currencyDates.contains(stockDate)) {missingDates.add(stockDate + " C");} // C for currency + } + for (String currencyDate: currencyDates) { + if (!aggregateDates.contains(currencyDate)) { + missingDates.add(currencyDate + " S"); // S for stock + aggregateDates.add(currencyDate); } - Collections.sort(aggregateDates); - for (String date: missingDates) { - String missing = date.split(" ")[1]; - date = date.split(" ")[0]; - if (missing.equals("C")) { - fillMissingDates(currencyDates, currencyRates, date); - } - else { - fillMissingDates(stockDates, stockRates, date); - } - //TODO: Add actual logging for this - System.out.println(ticker + ": missing " + missing + " on " + date); + } + Collections.sort(aggregateDates); + for (String date: missingDates) { + String missing = date.split(" ")[1]; + date = date.split(" ")[0]; + if (missing.equals("C")) { + fillMissingDates(currencyDates, currencyRates, date); } - - if (aggregateDates.size() != currencyRates.size() || aggregateDates.size() != stockRates.size()) { - System.out.println("Something went horrendously wrong :("); - throw new Exception(); + else { + fillMissingDates(stockDates, stockRates, date); } + //TODO: Add actual logging for this + System.out.println(ticker + ": missing " + missing + " on " + date); + } + if (aggregateDates.size() != currencyRates.size() || aggregateDates.size() != stockRates.size()) { + System.out.println("Something went horrendously wrong :("); + throw new IOException(); + } - String dest = StockTracker.PATH + ticker + "_" + currency + "_temp.txt"; - List writeList = new ArrayList<>(); - for (int i = 0; i < aggregateDates.size(); i++) { - writeList.add(aggregateDates.get(i) + " " + stockRates.get(i) + " " + currencyRates.get(i)); - } - FileManager.writeList(dest, writeList); - } catch (Exception e) { - e.printStackTrace(); + String dest = StockTracker.PATH + ticker + "_" + currency + "_temp.txt"; + List writeList = new ArrayList<>(); + for (int i = 0; i < aggregateDates.size(); i++) { + writeList.add(aggregateDates.get(i) + " " + stockRates.get(i) + " " + currencyRates.get(i)); } + FileManager.writeList(dest, writeList); + } private static void fillMissingDates(List datesList, List ratesList, String date) { diff --git a/src/main/java/stocktracker/FileManager.java b/src/main/java/stocktracker/FileManager.java index 83cbeed..5555eba 100644 --- a/src/main/java/stocktracker/FileManager.java +++ b/src/main/java/stocktracker/FileManager.java @@ -3,9 +3,7 @@ import java.io.File; import java.io.FileWriter; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; +import java.nio.file.*; import java.util.ArrayList; import java.util.List; @@ -60,7 +58,9 @@ public static List readLines(String dest) { try { Files.lines(Paths.get(dest)) .forEach(lines::add); - } catch (Exception e) { + } catch (NoSuchFileException e) { + throw new InvalidPathException("", "No such file exists"); + } catch (IOException e) { e.printStackTrace(); } return lines; diff --git a/src/main/java/stocktracker/StockInfoFetcher.java b/src/main/java/stocktracker/StockInfoFetcher.java index eae8d2c..af3a741 100644 --- a/src/main/java/stocktracker/StockInfoFetcher.java +++ b/src/main/java/stocktracker/StockInfoFetcher.java @@ -7,9 +7,6 @@ import org.patriques.output.timeseries.DailyAdjusted; import org.patriques.output.timeseries.data.StockData; -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; import java.time.LocalDate; import java.util.*; @@ -17,15 +14,13 @@ class StockInfoFetcher { private static final String API_KEY = "NZ04YC2MOTE5AN4P"; private static final int TIMEOUT = 3000; - //private static String generated; public static void main(String[] args) { test(); } private static void test() { - //getData("AAPL", LocalDate.now().minusDays(365)); - getData("AAPL", LocalDate.now().minusYears(7), 1); + getData("AAPL", LocalDate.now().minusDays(35)); } static void getData(String ticker, LocalDate startDate, double splitCoefficient) { @@ -35,61 +30,61 @@ static void getData(String ticker, LocalDate startDate, double splitCoefficient) System.out.println("Fetcing " + ticker + " done"); } + static void getData(String ticker, LocalDate startDate) { + Map data = fetchData(ticker, startDate, 1); + writeData(data, ticker); + System.out.println("Fetcing " + ticker + " done"); + } + private static Map fetchData(String ticker, LocalDate startDate, double splitCoefficient) { AlphaVantageConnector apiConnector = new AlphaVantageConnector(API_KEY, TIMEOUT); TimeSeries stockTimeSeries = new TimeSeries(apiConnector); - try { - // Alpha Vantage has two data OutputSizes: COMPACT which returns the first 100 - // stock data entries and FULL which returns all available stock data. - // 100 stock market days is equivalent to ~140 calendar days (actually - // a few more because of market holidays) - OutputSize size; - if (LocalDate.now().minusDays(140).isBefore(startDate) ) { - // startDate is in last 140 days - size = OutputSize.COMPACT; - } - else { - size = OutputSize.FULL; - } - HashMap dateCloses = new HashMap<>(); - DailyAdjusted response = stockTimeSeries.dailyAdjusted(ticker, size); - //Map metaData = response.getMetaData(); - //generated = metaData.get("3. Last Refreshed"); - List stockData = response.getStockData(); - boolean start = true; - Collections.reverse(stockData); - for (StockData stock: stockData) { - LocalDate entryDate = stock.getDateTime().toLocalDate(); - if (entryDate.isAfter(startDate.minusDays(1))) { - if (start) { - splitCoefficient /= stock.getSplitCoefficient(); - start = false; - } - if (stock.getSplitCoefficient() != 1) { - splitCoefficient *= stock.getSplitCoefficient(); - } - double money = Math.round(stock.getClose()*splitCoefficient*100)/100.0; - dateCloses.put("" + entryDate, "" + money); + // Alpha Vantage has two data OutputSizes: COMPACT which returns the first 100 + // stock data entries and FULL which returns all available stock data. + // 100 stock market days is equivalent to ~140 calendar days (actually + // a few more because of market holidays) + OutputSize size; + if (LocalDate.now().minusDays(140).isBefore(startDate) ) { + // startDate is in last 140 days + size = OutputSize.COMPACT; + } + else { + size = OutputSize.FULL; + } + HashMap dateCloses = new HashMap<>(); + DailyAdjusted response = stockTimeSeries.dailyAdjusted(ticker, size); + //Map metaData = response.getMetaData(); + //generated = metaData.get("3. Last Refreshed"); + List stockData = response.getStockData(); + boolean start = true; + Collections.reverse(stockData); + for (StockData stock: stockData) { + LocalDate entryDate = stock.getDateTime().toLocalDate(); + if (entryDate.isAfter(startDate.minusDays(1))) { + if (start) { + splitCoefficient /= stock.getSplitCoefficient(); + start = false; } - } - List oldConfig = FileManager.readLines(StockTracker.PATH + "save_config.txt"); - List newConfig = new ArrayList<>(); - for (String line: oldConfig) { - if (line.startsWith(ticker) && splitCoefficient != 1) { - String[] splitLine = line.split(" "); - line = splitLine[0] + " " + splitLine[1] + " " + splitCoefficient; + if (stock.getSplitCoefficient() != 1) { + splitCoefficient *= stock.getSplitCoefficient(); } - newConfig.add(line); + double money = Math.round(stock.getClose()*splitCoefficient*100)/100.0; + dateCloses.put("" + entryDate, "" + money); } - FileManager.writeList(StockTracker.PATH + "save_config.txt", newConfig); - return dateCloses; - - } catch (AlphaVantageException e) { - System.out.println("something went wrong"); - return null; } + List oldConfig = FileManager.readLines(StockTracker.PATH + "save_config.txt"); + List newConfig = new ArrayList<>(); + for (String line: oldConfig) { + if (line.startsWith(ticker) && splitCoefficient != 1) { + String[] splitLine = line.split(" "); + line = splitLine[0] + " " + splitLine[1] + " " + splitCoefficient; + } + newConfig.add(line); + } + FileManager.writeList(StockTracker.PATH + "save_config.txt", newConfig); + return dateCloses; } private static void writeData(Map data, String ticker) { diff --git a/src/main/java/stocktracker/StockTracker.java b/src/main/java/stocktracker/StockTracker.java index 2222e16..51bec80 100644 --- a/src/main/java/stocktracker/StockTracker.java +++ b/src/main/java/stocktracker/StockTracker.java @@ -1,6 +1,9 @@ package stocktracker; +import org.patriques.output.AlphaVantageException; + import java.io.File; +import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.text.NumberFormat; @@ -9,12 +12,12 @@ import java.util.List; //TODO: migrate files to .csv format? -//TODO: Add unit testing +//TODO: Add more/better jUnit testing //TODO: Automatically get currency of stock -- use Yahoo Finance page //TODO: Add euro support -//TODO: Account for dividends and splits using AlphaVantage -//TODO: Add license file? Reasearch about licenses -//TODO: Aggregate save_data and save_money in file +//TODO: Account for dividends using AlphaVantage + add boolean for reinvesting dividends +//TODO: Add license file? Research about licenses +//TODO: Aggregate save_data and save_money in a single file public class StockTracker { public static final String VERSION = "1.1.2"; @@ -46,11 +49,12 @@ private static void runNewTest() testAmounts.add(10); createConfig(testList, testAmounts); //writeData("IVV", "USD", LocalDate.of(2018, 9, 24)); - writeData("IVV", "USD", LocalDate.now().minusDays(139), 1); - writeData("QQQ", "USD", LocalDate.now().minusDays(139), 1); + writeData("IVV", "USD", LocalDate.now().minusDays(139)); + writeData("QQQ", "USD", LocalDate.now().minusDays(139)); System.out.println("Data fetching done"); System.out.println("$$$"); + calculateMoney(testList, testAmounts); createSave(); deleteTempFiles(); System.out.println("Files aggregated, money calculated"); @@ -67,9 +71,26 @@ private static void runExistingTest() { * @param currencyCode Currcency code of currency to be recorded. * @param startDate First date the data is written from. */ - public static void writeData(String ticker, String currencyCode, LocalDate startDate, double splitCoefficient) { - StockInfoFetcher.getData(ticker, startDate, splitCoefficient); - CurrencyRateFetcher.writeCurrencyInfo(currencyCode, startDate); + public static void writeData(String ticker, String currencyCode, LocalDate startDate) { + try { + StockInfoFetcher.getData(ticker, startDate); + CurrencyRateFetcher.writeCurrencyInfo(currencyCode, startDate); + } catch (AlphaVantageException e) { + System.out.println("Invalid stock ticker '" + ticker + "'"); + } catch (IOException e) { + System.out.println("Invalid currency code'" + currencyCode + "'"); + } + } + + public static void updateData(String ticker, String currencyCode, LocalDate startDate, double splitCoefficient) { + try { + StockInfoFetcher.getData(ticker, startDate, splitCoefficient); + CurrencyRateFetcher.writeCurrencyInfo(currencyCode, startDate); + } catch (AlphaVantageException e) { + System.out.println("Invalid stock ticker '" + ticker + "'"); + } catch (IOException e) { + System.out.println("Invalid currency code'" + currencyCode + "'"); + } } /** @@ -79,7 +100,11 @@ public static void writeData(String ticker, String currencyCode, LocalDate start */ public static void calculateMoney(List ticker_currency, List stockAmounts) { - DataAggregator.calculateMoney(ticker_currency, stockAmounts); + try { + DataAggregator.calculateMoney(ticker_currency, stockAmounts); + } catch (IOException e) { + System.out.println("Something went horrendously wrong"); + } } /** @@ -87,7 +112,7 @@ public static void calculateMoney(List ticker_currency, List sto * "TICKER_CURRENCYCODE". * @param amountList List containing amounts of stocks specified in nameList owned. */ - private static void createConfig(ArrayList nameList, ArrayList amountList) { + public static void createConfig(ArrayList nameList, ArrayList amountList) { boolean append = false; for (int i = 0; i < nameList.size(); i++) { String line = nameList.get(i) + " " + amountList.get(i); @@ -114,8 +139,9 @@ public static void createSave() { /** * Reads the save files and if data in them is outdated, updates them. + * @return */ - public static void updateSave() { + public static boolean updateSave() { List saveConfig = FileManager.readLines(PATH + "save_config.txt"); List saveData = FileManager.readLines(PATH + "save_data.txt"); List ticker_currency = new ArrayList<>(); @@ -132,7 +158,7 @@ public static void updateSave() { e.printStackTrace(); } String[] lineArray = line.split(" ")[0].split("_"); - writeData(lineArray[0], lineArray[1], lastDate.plusDays(1), Double.parseDouble(line.split(" ")[2])); + updateData(lineArray[0], lineArray[1], lastDate.plusDays(1), Double.parseDouble(line.split(" ")[2])); } calculateMoney(ticker_currency, stockAmounts); List newDataList = FileManager.readLines(PATH + "aggregated_temp.txt"); @@ -145,7 +171,9 @@ public static void updateSave() { } else { System.out.println("All up to date"); + return false; } + return true; } /** diff --git a/src/main/java/stocktracker/StockTrackerGUI.java b/src/main/java/stocktracker/StockTrackerGUI.java index 356890b..f0d12bf 100644 --- a/src/main/java/stocktracker/StockTrackerGUI.java +++ b/src/main/java/stocktracker/StockTrackerGUI.java @@ -284,7 +284,7 @@ private void updateExistingData() { private void writeData(String ticker, String currencyCode, LocalDate startDate) { setStatusLabel("Fetching " + ticker + " data..."); - StockTracker.writeData(ticker, currencyCode, startDate, 1); + StockTracker.writeData(ticker, currencyCode, startDate); } private static void createSave() { diff --git a/src/test/java/stocktracker/CurrencyRateFetcherTest.java b/src/test/java/stocktracker/CurrencyRateFetcherTest.java new file mode 100644 index 0000000..1b2be12 --- /dev/null +++ b/src/test/java/stocktracker/CurrencyRateFetcherTest.java @@ -0,0 +1,54 @@ +package stocktracker; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.time.LocalDate; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +class CurrencyRateFetcherTest { + + private static String PATH = StockTracker.PATH; + private static List dataList; + + @BeforeAll + static void setUp() { + try { + CurrencyRateFetcher.writeCurrencyInfo("USD", LocalDate.now().minusDays(365)); + } catch (IOException e) { + e.printStackTrace(); + } + dataList = FileManager.readLines(PATH + "USD_temp.txt"); + } + + @Test + void testInvalidCurrency() { + assertThrows(FileNotFoundException.class, () -> CurrencyRateFetcher + .writeCurrencyInfo("USDD", LocalDate.now().minusDays(365))); + } + + @Test + void testDataValidity() { + for (String entry : dataList) { + String[] splitEntry = entry.split(" "); + assertEquals(splitEntry.length, 2); + assertDoesNotThrow(() -> LocalDate.parse(splitEntry[0])); + } + } + + @Test + void testDataSize() { + assertTrue(dataList.size() > 200); + } + + @Test + void testFetchingNewData() { + File dataFile = new File(PATH + "USD_temp.txt"); + assertTrue(dataFile.lastModified() > System.currentTimeMillis()-120000); + } +} \ No newline at end of file diff --git a/src/test/java/stocktracker/DataAggregatorTest.java b/src/test/java/stocktracker/DataAggregatorTest.java new file mode 100644 index 0000000..f0dc6e8 --- /dev/null +++ b/src/test/java/stocktracker/DataAggregatorTest.java @@ -0,0 +1,79 @@ +package stocktracker; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.io.IOException; +import java.nio.file.InvalidPathException; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +class DataAggregatorTest { + + private static String PATH = StockTracker.PATH; + private static List dataList; + + @BeforeAll + static void updateData() { + try { + StockInfoFetcher.getData("AAPL", LocalDate.now().minusDays(365)); + StockInfoFetcher.getData("MSFT", LocalDate.now().minusDays(365)); + CurrencyRateFetcher.writeCurrencyInfo("USD", LocalDate.now().minusDays(365)); + } catch (Exception e) { + e.printStackTrace(); + } + + ArrayList testList = new ArrayList<>(); + testList.add("AAPL_USD"); + testList.add("MSFT_USD"); + ArrayList testAmounts = new ArrayList<>(); + testAmounts.add(5); + testAmounts.add(10); + try { + DataAggregator.calculateMoney(testList, testAmounts); + } catch (IOException e) { + e.printStackTrace(); + } + dataList = FileManager.readLines(PATH + "aggregated_temp.txt"); + } + + @Test + void testInvalidData() { + List invalidList = new ArrayList<>(); + invalidList.add("AAAPL_USD"); + List amounts = new ArrayList<>(); + amounts.add(1); + assertThrows(InvalidPathException.class, () -> DataAggregator.calculateMoney(invalidList, amounts)); + } + + @Test + void testDataValidity() { + for (String entry : dataList) { + String[] splitEntry = entry.split(" "); + assertEquals(splitEntry.length, 7); + assertDoesNotThrow(() -> LocalDate.parse(splitEntry[0])); + } + } + + @Test + void testDataSize() { + assertTrue(dataList.size() > 200); + } + + @Test + void testFetchingNewData() { + File dataFile = new File(PATH + "aggregated_temp.txt"); + assertTrue(dataFile.lastModified() > System.currentTimeMillis()-120000); + } + + @Test + void testCurrencyAggregation() { + List data = FileManager.readLines(PATH + "AAPL_USD_temp.txt"); + assertTrue(data.size() > 200); + assertTrue(new File(PATH + "AAPL_USD_temp.txt").lastModified() > System.currentTimeMillis()-120000); + } +} \ No newline at end of file diff --git a/src/test/java/stocktracker/StockInfoFetcherTest.java b/src/test/java/stocktracker/StockInfoFetcherTest.java new file mode 100644 index 0000000..fdb0c55 --- /dev/null +++ b/src/test/java/stocktracker/StockInfoFetcherTest.java @@ -0,0 +1,75 @@ +package stocktracker; + +import org.junit.jupiter.api.*; +import org.patriques.AlphaVantageConnector; +import org.patriques.TimeSeries; +import org.patriques.output.AlphaVantageException; + +import java.time.format.DateTimeParseException; + +import java.io.File; +import java.time.LocalDate; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +class StockInfoFetcherTest { + + @BeforeAll + static void updateData() { + StockInfoFetcher.getData("AAPL", LocalDate.now().minusDays(365)); + } + + @Nested + @DisplayName("getData") + class getDataTests { + + String PATH = StockTracker.PATH; + List dataList = FileManager.readLines(PATH + "AAPL_temp.txt"); + + @Test + void testInvalidTicker() { + assertThrows(AlphaVantageException.class, () -> StockInfoFetcher + .getData("AAAPL", LocalDate.now().minusDays(365))); + } + + @Test + void testDataValidity() { + for (String entry : dataList) { + String[] splitEntry = entry.split(" "); + assertEquals(splitEntry.length, 2); + assertDoesNotThrow(() -> LocalDate.parse(splitEntry[0])); + } + } + + @Test + void testDataSize() { + assertTrue(dataList.size() > 200); + } + + @Test + void testFetchingNewData() { + File dataFile = new File(PATH + "AAPL_temp.txt"); + assertTrue(dataFile.lastModified() > System.currentTimeMillis()-120000); + } + + @Test + void testConfig() { + File configFile = new File(PATH + "save_config.txt"); + if (configFile.exists()) { + String[] config = FileManager.readLines(PATH + "save_config.txt").get(0).split(" "); + assertDoesNotThrow(() -> Integer.parseInt(config[1])); + assertDoesNotThrow(() -> Double.parseDouble(config[2])); + } + + } + } + + @Test + void testGetMostRecentDay() { + LocalDate now = LocalDate.now(); + LocalDate mostRecent = StockInfoFetcher.getMostRecentDay(); + assertTrue(mostRecent.isBefore(now) || mostRecent.isEqual(now)); + assertTrue(mostRecent.isAfter(now.minusDays(7))); + } +} \ No newline at end of file diff --git a/src/test/java/stocktracker/StockTrackerTest.java b/src/test/java/stocktracker/StockTrackerTest.java new file mode 100644 index 0000000..a266c6d --- /dev/null +++ b/src/test/java/stocktracker/StockTrackerTest.java @@ -0,0 +1,54 @@ +package stocktracker; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.patriques.output.AlphaVantageException; + +import java.io.IOException; +import java.text.NumberFormat; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +//TODO: This test is bad. Fix it +class StockTrackerTest { + + private static ArrayList testList; + private static ArrayList testAmounts; + private static String PATH = StockTracker.PATH; + + @BeforeAll + static void setup() { + testList = new ArrayList<>(); + testList.add("IVV_USD"); + testList.add("QQQ_USD"); + testAmounts = new ArrayList<>(); + testAmounts.add(5); + testAmounts.add(10); + } + + @Test + void runNewTest() + { + StockTracker.createConfig(testList, testAmounts); + StockTracker.writeData("ASDIVV", "USD", LocalDate.now().minusDays(139)); + StockTracker.writeData("QQQ", "USD", LocalDate.now().minusDays(139)); + + System.out.println("Data fetching done"); + System.out.println("$$$"); + StockTracker.calculateMoney(testList, testAmounts); + StockTracker.createSave(); + StockTracker.deleteTempFiles(); + System.out.println("Files aggregated, money calculated"); + System.out.println("Done"); + } + + //TODO: test actually updating the save + @Test + void updateSave() { + assertFalse(StockTracker.updateSave()); + } + +} \ No newline at end of file