Skip to content

Commit

Permalink
Merge pull request #21 from danieskj/file-handeling
Browse files Browse the repository at this point in the history
Finished issue file-handeling
  • Loading branch information
pawelsa authored Mar 25, 2026
2 parents 0258902 + 2c6a8c8 commit 2cb3840
Show file tree
Hide file tree
Showing 5 changed files with 261 additions and 17 deletions.
24 changes: 20 additions & 4 deletions src/main/java/edu/ntnu/idi/idatt/Exchange.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package edu.ntnu.idi.idatt;

import edu.ntnu.idi.idatt.file.ExchangeLoader;
import edu.ntnu.idi.idatt.marked.Share;
import edu.ntnu.idi.idatt.marked.Stock;
import edu.ntnu.idi.idatt.transaction.Purchase;
import edu.ntnu.idi.idatt.transaction.Sale;
import edu.ntnu.idi.idatt.transaction.Transaction;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
Expand All @@ -20,7 +22,7 @@
* </p>
*
*/
public class Exchange {
public class Exchange extends ExchangeLoader {

private final String name;
private int week;
Expand All @@ -33,12 +35,15 @@ public class Exchange {
* @param name - Name of the current stock Exchange
* @param stocks - List of aviable stocks for this exchange.
*/
public Exchange(String name, List<Stock> stocks) {
public Exchange(String name, String path) {
super(path);
this.name = name;
this.week = 1;

for (Stock stock : stocks) {
stockMap.put(stock.getSymbol(), stock);
try {
this.load().forEach(stock -> stockMap.put(stock.getSymbol(), stock));
} catch (IOException e) {
throw new IllegalArgumentException("Problem loading [" + name + "] exchange : " + e);
}

}
Expand All @@ -58,6 +63,10 @@ public int getWeek() {
return week;
}

public List<Stock> getStocks() {
return stockMap.values().stream().toList();
}

/**
* Method for checking if a specific stock exists in the exchange.
*
Expand Down Expand Up @@ -194,6 +203,13 @@ public Transaction sell(Share share, Player player) {
public void advance() {
for (Stock stocks : stockMap.values()) {
stocks.addNewSalesPrice(BigDecimal.valueOf(random.nextDouble()));

// TODO: Move this to JavaFx on Window close?
try {
this.save(stockMap.values().stream().toList());
} catch (IOException e) {
throw new IllegalArgumentException("Problem loading [" + name + "] exchange : " + e);
}
}
}

Expand Down
100 changes: 100 additions & 0 deletions src/main/java/edu/ntnu/idi/idatt/file/ExchangeLoader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package edu.ntnu.idi.idatt.file;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import edu.ntnu.idi.idatt.marked.Stock;

public class ExchangeLoader {

private final File file;

/**
* Constructors for ExchangeLoader
*
* <p>
* Utilizes method overloading for different types
* of path formatting.
* </p>
*
* @throws IllegalArgumentException if specified path doesn't exist.
*/
protected ExchangeLoader(String path) {
file = new File(path);
if (!file.exists()) {
throw new IllegalArgumentException("File at this path doesn't exist!");
}
}

protected ExchangeLoader(URL path) {
file = new File(path.toString());
if (!file.exists()) {
throw new IllegalArgumentException("File at this path doesn't exist!");
}
}

/**
* Method for loading from stocks from file
*
* @return List<Stock> of loaded stocks.
* @throws IOException on BufferedReader error
*/
protected List<Stock> load() throws IOException {

ArrayList<Stock> stocks = new ArrayList<>();

try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
List<String> stockStringList = new ArrayList<>(reader.readAllLines());

// Remove comments
stockStringList.removeIf(s -> s.isBlank());
stockStringList.removeIf(s -> s.startsWith("#"));

for (String stockString : stockStringList) {
String[] stockValues = stockString.split(",");

// TODO: Loading all historical prices not the recent, saved one.
Stock stock = new Stock(stockValues[0], stockValues[1], List.of(new BigDecimal(stockValues[2])));
stocks.add(stock);
}

} catch (IOException e) {
throw new IOException("File loading failed!");
}

return stocks;

}

/**
* Method for saving stocks to file.
*
* @param stocks The destined list to be saved.
* @throws IOException on BufferedWriter error.
*/
protected void save(List<Stock> stocks) throws IOException {

try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {

for (Stock stock : stocks) {
String data = stock.getSymbol() + "," + stock.getCompany() + ","
+ stock.getHistoricalPrices().getLast().toString();
writer.write(data);
writer.newLine();
}

} catch (IOException e) {
throw new IOException("File saving failed!");
}

}

}
44 changes: 31 additions & 13 deletions src/test/java/edu/ntnu/idi/idatt/ExchangeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;

Expand All @@ -17,22 +22,37 @@

class ExchangeTest {

/**
* <p>
* Caution!
* stocks List is not sorted correctly.
* We parse it with hashMap.values().stream().toList
* which dont properly arrange it in memory.
* Take caution when programming or reading here.
*
* @see PTgetGainers_Losers don't take the get(index) literally
* but focus on the differences of last sale value made.
*
* This is a work around for implementing the ExchangeLoader to Exchange
* class.
* </p>
*/
private Exchange exchange;
private List<Stock> stocks;
private Player player;

@BeforeEach
public void PT_setup() {
public void PT_setup() throws IOException {

// Initialize exchange with proper objects
Stock AAPL = new Stock("AAPL", "Apple Inc.", List.of(new BigDecimal("32")));
Stock NVDA = new Stock("NVDA", "NVIDIA", List.of(new BigDecimal("182.81")));
Stock TSLA = new Stock("TSLA", "Tesla", List.of(new BigDecimal("417.44")));
Stock AMD = new Stock("AMD", "Advanced Micro Devices", List.of(new BigDecimal("207.32")));
InputStream is = getClass()
.getClassLoader()
.getResourceAsStream("stocks.csv");

stocks = List.of(AAPL, NVDA, TSLA, AMD);
Path tempFile = Files.createTempFile("stocks", ".csv");
Files.copy(is, tempFile, StandardCopyOption.REPLACE_EXISTING);

exchange = new Exchange("TestExchange", stocks);
exchange = new Exchange("TestExchange", tempFile.toFile().toPath().toString());
stocks = exchange.getStocks();
player = new Player("TestPlayer", new BigDecimal("500"));
}

Expand All @@ -55,12 +75,10 @@ void PTConstructor() {
void PTFindStock() {

assertTrue(exchange.hasStock("AAPL"));
assertEquals(stocks.get(0) /* AAPL Stock */, exchange.getStock("AAPL"));
assertTrue(stocks.contains(exchange.getStock("AAPL")));

// FindStocks for letter "n" should be - AAPL, AMD (both symbols and names!)
List<Stock> expected = List.of(stocks.get(0), stocks.get(3));
//
assertEquals(expected, exchange.findStocks("n"));
assertEquals(2, exchange.findStocks("n").size());

}

Expand Down Expand Up @@ -127,7 +145,7 @@ void PTAdvance() {
void PTgetGainers_Losers() {
// Simulate price change
stocks.get(0).addNewSalesPrice(new BigDecimal("4333"));
stocks.get(1).addNewSalesPrice(new BigDecimal("50"));
stocks.get(1).addNewSalesPrice(new BigDecimal("10"));
stocks.get(2).addNewSalesPrice(new BigDecimal("3"));
stocks.get(3).addNewSalesPrice(new BigDecimal("800"));

Expand Down
103 changes: 103 additions & 0 deletions src/test/java/edu/ntnu/idi/idatt/file/ExchangeLoaderTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package edu.ntnu.idi.idatt.file;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.List;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import edu.ntnu.idi.idatt.marked.Stock;

/**
* Test class for ExchangeLoader
*
* <p>
* Tests the loading and saving of stock data.
* </p>
*/
class ExchangeLoaderTest {

private ExchangeLoader loader;
private List<Stock> exampleStocks;

@BeforeEach
public void PT_setup() throws IOException {

InputStream is = getClass()
.getClassLoader()
.getResourceAsStream("stocks.csv");

Path tempFile = Files.createTempFile("stocks", ".csv");
Files.copy(is, tempFile, StandardCopyOption.REPLACE_EXISTING);

loader = new ExchangeLoader(tempFile.toFile().toPath().toString());

Stock AAPL = new Stock("AAPL", "Apple Inc.", List.of(new BigDecimal("32")));
Stock NVDA = new Stock("NVDA", "NVIDIA", List.of(new BigDecimal("182.81")));
Stock TSLA = new Stock("TSLA", "Tesla", List.of(new BigDecimal("417.44")));
Stock AMD = new Stock("AMD", "Advanced Micro Devices", List.of(new BigDecimal("207.32")));

exampleStocks = List.of(AAPL, NVDA, TSLA, AMD);
}

/**
* Positive test for loading/reading stocks
*/
@Test
void PT_load() {
List<Stock> stocks = null;
try {
stocks = loader.load();
} catch (IOException e) {
e.printStackTrace();
}

assertEquals(4, stocks.size());

}

/**
* Positive test for saving stocks.
*/
@Test
void PT_save() {
exampleStocks.get(3).addNewSalesPrice(new BigDecimal("99999"));

// Save

try {
loader.save(exampleStocks);
} catch (IOException e) {
e.printStackTrace();
}

// Try to read again
List<Stock> stocks = null;
try {
stocks = loader.load();
} catch (IOException e) {
e.printStackTrace();
}

assertEquals(new BigDecimal("99999"), stocks.get(3).getSalesPrice());

}

/**
* Negative tests for constructor
*/
@Test
void NT_IllegalArgumentException_Constructor() {
assertThrows(IllegalArgumentException.class,
() -> new ExchangeLoader("resources/notexistantfile.csv"));
}

}
7 changes: 7 additions & 0 deletions src/test/resources/stocks.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Ticker,Name,Price
AAPL,Apple Inc,32
NVDA,NVIDIA,182.81
TSLA,Tesla,417.44
AMD,Advanced Micro Devices,207.32


0 comments on commit 2cb3840

Please sign in to comment.