Skip to content

Added support for reading and writing stock data to a file #36

Merged
merged 6 commits into from
Apr 13, 2026
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 0 additions & 40 deletions src/main/java/millions/controller/StockInformationReader.java

This file was deleted.

34 changes: 0 additions & 34 deletions src/main/java/millions/controller/StockInformationWriter.java

This file was deleted.

42 changes: 42 additions & 0 deletions src/main/java/millions/controller/fileIO/CSVStockFileParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package millions.controller.fileIO;

import millions.model.Stock;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

public class CSVStockFileParser {
private List<String> lines;

public CSVStockFileParser(List<String> lines) {
if (verifyCSV(lines)) {
this.lines = lines;
}
else {
// throw file format error
}
}

// returns true if all entries have exactly 3 data points
public boolean verifyCSV(List<String> lines) {
return lines.stream()
.filter(l -> !(l.startsWith("#") || l.isBlank()))
.noneMatch(l -> l.split(",").length != 3);

}

public List<Stock> parse() {
List<Stock> stocks = new ArrayList<>();
lines.stream()
.filter(l -> !((l.startsWith("#") || l.isBlank())))
.forEach(l -> {
String[] split = l.split(",");
String symbol = split[0];
String company = split[1];
BigDecimal price = new BigDecimal(split[2]);
stocks.add(new Stock(symbol, company, price));
});
return stocks;
}
}
43 changes: 43 additions & 0 deletions src/main/java/millions/controller/fileIO/CSVStockFileWriter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package millions.controller.fileIO;

import millions.model.Stock;

import java.io.BufferedWriter;
import java.io.*;
import java.nio.file.Path;
import java.util.List;

//TODO: Validation of data before writing
public class CSVStockFileWriter implements StockFileWriter {
private final List<Stock> stocks;
private String finalString;

public CSVStockFileWriter(List<Stock> stocks) {
this.stocks = stocks;
}

@Override
public void formatString() {
StringBuilder builder = new StringBuilder();
stocks.forEach(stock -> {
builder.append(stock.getSymbol());
builder.append(",");
builder.append(stock.getCompany());
builder.append(",");
builder.append(stock.getSalesPrice().toString());
builder.append("\n");
});
this.finalString = builder.toString();
}

@Override
public boolean write(Path path){
try (FileWriter fw = new FileWriter(path.toString()); BufferedWriter writer = new BufferedWriter(fw);) {
this.formatString();
writer.write(finalString);
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
}
26 changes: 26 additions & 0 deletions src/main/java/millions/controller/fileIO/StockFileReader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package millions.controller.fileIO;

import java.io.*;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;


public class StockFileReader {
private final Path filePath;

public StockFileReader(Path path) {
this.filePath = path;
}

public List<String> readFile() {
File file = new File(filePath.toString());
List<String> lines = new ArrayList<>();
try (Reader reader = new FileReader(file); BufferedReader bufferedReader = new BufferedReader(reader)) {
lines = bufferedReader.readAllLines();
} catch (IOException e) {
e.printStackTrace();
}
return lines;
}
}
8 changes: 8 additions & 0 deletions src/main/java/millions/controller/fileIO/StockFileWriter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package millions.controller.fileIO;

import java.nio.file.Path;

public interface StockFileWriter {
public void formatString();
public boolean write(Path path);
}
5 changes: 5 additions & 0 deletions src/main/java/millions/model/Stock.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,9 @@ public BigDecimal getLatestPriceChange() {

return currentPrice.subtract(lastPrice);
}

@Override
public String toString() {
return "Stock [symbol: " + symbol + ", company: " + company + ", prices: " + prices + "]";
}
}
41 changes: 41 additions & 0 deletions src/test/java/millions/CSVStockFileParserTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package millions;

import millions.controller.fileIO.CSVStockFileParser;
import millions.controller.fileIO.StockFileReader;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

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

public class CSVStockFileParserTest {
@TempDir
static Path tempDir;

static Path sharedFile;

@BeforeAll
public static void setUpTestFile() throws Exception {
sharedFile = Files.createFile(tempDir.resolve("file.csv"));
String string = "# Top 500 US Stocks by Market Cap\n";
string += "# Ticker,Name,Price\n";
string += "\n";
string += "NVDA,Nvidia,191.27\n";
string += "AAPL,Apple Inc.,276.43\n";
string += "MSFT,Microsoft,404.68\n";
Files.writeString(sharedFile, string);
}

@Test
public void parseStockFileTest(){
StockFileReader stockFileReader = new StockFileReader(sharedFile);

CSVStockFileParser parser = new CSVStockFileParser(stockFileReader.readFile());
assertEquals(3, parser.parse().size());
}
}
43 changes: 43 additions & 0 deletions src/test/java/millions/CSVStockFileWriterTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package millions;

import millions.controller.fileIO.CSVStockFileWriter;
import millions.controller.fileIO.StockFileReader;
import millions.model.Stock;

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

import java.math.BigDecimal;
import java.nio.file.Path;
import java.util.List;

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

public class CSVStockFileWriterTest {
@TempDir
static Path tempDir;

List<Stock> stocks;

@BeforeEach
void setup() {
Stock s1 = new Stock("PEAR", "Pear Inc.", BigDecimal.valueOf(300));
Stock s2 = new Stock("DOGL", "DOOGLE Inc.", BigDecimal.valueOf(200.00));
Stock s3 = new Stock("MSFT", "EpsteinSoft Inc.", BigDecimal.valueOf(0.02));

this.stocks = List.of(s1, s2, s3);
}

@Test
public void testWrite() {
for(Stock stock : this.stocks) {
System.out.println(stock.toString());
}
CSVStockFileWriter csvStockFileWriter = new CSVStockFileWriter(stocks);
csvStockFileWriter.write(tempDir.resolve("stocks.csv"));

StockFileReader stockFileReader = new StockFileReader(tempDir.resolve("stocks.csv"));
assertEquals(3, stockFileReader.readFile().size());
}
}
35 changes: 35 additions & 0 deletions src/test/java/millions/StockFileReaderTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package millions;

import millions.controller.fileIO.StockFileReader;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

import java.nio.file.Files;
import java.nio.file.Path;

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

public class StockFileReaderTest {
@TempDir
static Path tempDir;

static Path sharedFile;
@BeforeAll
public static void setUpTestFile() throws Exception {
sharedFile = Files.createFile(tempDir.resolve("file.csv"));
String string = "# Top 500 US Stocks by Market Cap\n";
string += "# Ticker,Name,Price\n";
string += "\n";
string += "NVDA,Nvidia,191.27\n";
string += "AAPL,Apple Inc.,276.43\n";
string += "MSFT,Microsoft,404.68\n";
Files.writeString(sharedFile, string);
}

@Test
public void testReadStockFile() {
StockFileReader stockFileReader = new StockFileReader(sharedFile);
assertEquals(6, stockFileReader.readFile().size());
}
}