Added MOD/EFF/REQ

workbranch
asdfasdf 6 years ago
parent 88e46f3b41
commit 4e2180dd6f

@ -66,5 +66,6 @@ public abstract class DataSource {
return Objects.hash(name); return Objects.hash(name);
} }
//Effect: returns updated data in the form: double[2], [0] is price, [1] is %change
public abstract double[] update(String stype, String idstring) throws IOException; public abstract double[] update(String stype, String idstring) throws IOException;
} }

@ -15,16 +15,21 @@ public class ListOfWatchList {
return lowl; return lowl;
} }
//Effect: add a watchlist to this list, if it isn't already in the list
//Modifies: this
public void addWatchList(WatchList wlist) { public void addWatchList(WatchList wlist) {
if (!(wlists.contains(wlist))) { if (!(wlists.contains(wlist))) {
wlists.add(wlist); wlists.add(wlist);
} }
} }
//Effect: remove a watchlist
//Modifies: this
public void delWatchList(WatchList wlist) { public void delWatchList(WatchList wlist) {
wlists.remove(wlist); wlists.remove(wlist);
} }
//Effect: return a watchlist by index
public WatchList getWatchList(int index) { public WatchList getWatchList(int index) {
return (WatchList) wlists.get(index); return (WatchList) wlists.get(index);
} }

@ -8,7 +8,6 @@ public class Nyse extends StockType {
public Nyse() { public Nyse() {
super(); super();
name = "NYSE"; name = "NYSE";
addSource(new AlphaVantage()); addSource(new AlphaVantage());
delSource(new AlphaVantage());
} }
} }

@ -15,6 +15,9 @@ public class StockEntry {
this.stype = stype; this.stype = stype;
} }
//Effect: return true if price or change is/are new
// update the price and %change by the stype update
//Modifies: this
public boolean update() { public boolean update() {
boolean changed = false; boolean changed = false;
updating = true; updating = true;

@ -31,6 +31,7 @@ public class StypeMap {
// Effects: Returns the StockType // Effects: Returns the StockType
// Require: Valid typeString // Require: Valid typeString
// note: this is a shortcut to getMap and then getInstStype
public static StockType getStype(String typeString) { public static StockType getStype(String typeString) {
return stypemap.getInstStype(typeString); return stypemap.getInstStype(typeString);
} }

@ -44,12 +44,13 @@ public class WatchList extends Observable implements Load,Save {
if (!listdata.containsKey(target)) { if (!listdata.containsKey(target)) {
throw new StockNotExistsException(); throw new StockNotExistsException();
} }
int index = new ArrayList(listdata.keySet()).indexOf(target); int index = new ArrayList(listdata.keySet()).indexOf(target);
this.listdata.remove(target); this.listdata.remove(target);
setChanged(); setChanged();
notifyObservers(new Wevent(Etype.DEL, index)); notifyObservers(new Wevent(Etype.DEL, index));
} }
// Effects: return an array of all Stock names in list
public String[] getNames() { public String[] getNames() {
return listdata.keySet().toArray(new String[0]); return listdata.keySet().toArray(new String[0]);
} }
@ -61,6 +62,7 @@ public class WatchList extends Observable implements Load,Save {
return entryset.iterator(); return entryset.iterator();
} }
//Effects: return a stockentry given its index
public StockEntry getStock(int index) { public StockEntry getStock(int index) {
String key = (String) listdata.keySet().toArray()[index]; String key = (String) listdata.keySet().toArray()[index];
return (StockEntry) listdata.get(key); return (StockEntry) listdata.get(key);
@ -71,6 +73,7 @@ public class WatchList extends Observable implements Load,Save {
return listdata.size(); return listdata.size();
} }
//Effect: save list to a file, save to DEFAULT_SAVEFILE if filename is empty
@Override @Override
public void save(String filename) { public void save(String filename) {
if (filename.equals("")) { if (filename.equals("")) {
@ -93,12 +96,15 @@ public class WatchList extends Observable implements Load,Save {
} }
} }
//Effect: return true if filename exists and is a file
@Override @Override
public boolean fileExists(String filename) { public boolean fileExists(String filename) {
File fileObj = new File(filename); File fileObj = new File(filename);
return fileObj.isFile(); return fileObj.isFile();
} }
//Effect: load list from file, load from DEFAULT_SAVEFILE if filename is empty
//Modifies: this
@Override @Override
public void load(String filename) { public void load(String filename) {
if (filename.equals("")) { if (filename.equals("")) {
@ -120,6 +126,8 @@ public class WatchList extends Observable implements Load,Save {
} }
} }
//Effect: perform price and %update for @ stockentry in list
//Modifies: this, stockentries
public void updateList() { public void updateList() {
Iterator watchit = iterator(); Iterator watchit = iterator();
boolean changed = false; boolean changed = false;

@ -12,6 +12,7 @@ public class AlphaVantage extends DataSource {
super("AlphaVantage", "https://www.alphavantage.co/query", "4MC2LL0HOQ2TFQL1"); super("AlphaVantage", "https://www.alphavantage.co/query", "4MC2LL0HOQ2TFQL1");
} }
//Effect: get intraday price and %change through JSON given the stock ticker
@Override @Override
public double[] update(String stype, String idstring) throws IOException { public double[] update(String stype, String idstring) throws IOException {
double[] result = {0.0, 0.0}; double[] result = {0.0, 0.0};

@ -10,6 +10,7 @@ import network.exceptions.*;
//Ref: https://stackoverflow.com/questions/2793150/how-to-use-java-net-urlconnection-to-fire-and-handle-http-requests //Ref: https://stackoverflow.com/questions/2793150/how-to-use-java-net-urlconnection-to-fire-and-handle-http-requests
public class Net { public class Net {
//Effect: returns a String of url built with given url and paras
public static String urlStringBuilder(String url, String... paras) throws ParaMismatchException { public static String urlStringBuilder(String url, String... paras) throws ParaMismatchException {
String urlString = url; String urlString = url;
String charset = "UTF-8"; String charset = "UTF-8";
@ -31,6 +32,7 @@ public class Net {
return urlString; return urlString;
} }
//Effect: Open connection, fires a http GET and returns the InputStream of result
public static InputStream urlToInputStream(String url) throws IOException { public static InputStream urlToInputStream(String url) throws IOException {
try { try {
return (new URL(url).openStream()); return (new URL(url).openStream());

@ -27,27 +27,31 @@ public class StockJson {
} }
} }
// Effect: return double from jsonnumber
public static double doubleGetter(JsonObject jobj, String name) { public static double doubleGetter(JsonObject jobj, String name) {
return jobj.getJsonNumber(name).doubleValue(); return jobj.getJsonNumber(name).doubleValue();
} }
// Effect: return jsonobject from jsonobject
public static JsonObject jsonInJson(JsonObject jobj, String name) { public static JsonObject jsonInJson(JsonObject jobj, String name) {
return jobj.getJsonObject(name); return jobj.getJsonObject(name);
} }
// Effect: return string from jsonstring
public static String stringGetter(JsonObject jobj, String name) { public static String stringGetter(JsonObject jobj, String name) {
return jobj.getString(name); return jobj.getString(name);
} }
// Effect: return double from percentage string
public static double doublePercent(JsonObject jobj, String name) { public static double doublePercent(JsonObject jobj, String name) {
String temp = stringGetter(jobj, name); String temp = stringGetter(jobj, name);
return Double.parseDouble(temp.split("%")[0]); return Double.parseDouble(temp.split("%")[0]);
} }
// From https://stackoverflow.com/questions/33531041/jsonobject-get-value-of-first-node-regardless-of-name // From https://stackoverflow.com/questions/33531041/jsonobject-get-value-of-first-node-regardless-of-name
// Effect: extract the jsonobject from jsonobject by index
public static JsonObject timeSeriesElement(JsonObject jobj, int index) { public static JsonObject timeSeriesElement(JsonObject jobj, int index) {
String name = (String) jobj.keySet().toArray()[index]; String name = (String) jobj.keySet().toArray()[index];
System.out.println(name);
return jsonInJson(jobj, name); return jsonInJson(jobj, name);
} }
} }

@ -21,6 +21,8 @@ public class Gui extends JFrame implements Iface {
private WatchTablePane wtable; private WatchTablePane wtable;
private WatchList wlist; private WatchList wlist;
private Runnable init = new Runnable() { private Runnable init = new Runnable() {
//Effect: Init gui all components
//Modifies: this
public void run() { public void run() {
addComponents(); addComponents();
createLayout(); createLayout();
@ -65,11 +67,15 @@ public class Gui extends JFrame implements Iface {
setVisible(true); setVisible(true);
} }
//Effect: nothing
//not enough time to do something useful for this
@Override @Override
public void redraw() { public void redraw() {
//Nothing for now //Nothing for now
} }
//Effect: nothing
//not enough time to do something useful for this
@Override @Override
public void destory() { public void destory() {
//Nothing for now //Nothing for now

@ -16,11 +16,6 @@ public class Main {
iface = IfaceFactory.getIface(); iface = IfaceFactory.getIface();
} }
//Constructor for testing
public Main(boolean debug) {
WatchList mainList = new WatchList();
}
// java main // java main
public static void main(String[] args) { public static void main(String[] args) {
new Main(args); new Main(args);

@ -29,6 +29,7 @@ public class Tui implements Iface, Observer {
demo(); demo();
} }
//Effect: wait for user input and get a line (pressed Enter)
public String getInputLine() { public String getInputLine() {
String result; String result;
try { try {
@ -45,6 +46,8 @@ public class Tui implements Iface, Observer {
return ""; return "";
} }
//Effect: capture user input, constantly
//Unused, for future dev uses
public String readUntil(char end) { public String readUntil(char end) {
String result = ""; String result = "";
char c; char c;
@ -88,18 +91,22 @@ public class Tui implements Iface, Observer {
maxcol = maxCoord[1]; maxcol = maxCoord[1];
} }
//Effect: nothing has to be done
@Override @Override
public void destory() { public void destory() {
//Nothing has to be done //Nothing has to be done
return; return;
} }
//Effect: nothing
//will be used when Tui is redesigned
@Override @Override
public void redraw() { public void redraw() {
//XXX Do nothing for now //XXX Do nothing for now
return; return;
} }
//Effect: Show a menu of functions
public void demomenu() { public void demomenu() {
System.out.println("Function select:"); System.out.println("Function select:");
System.out.println("1: Update watchlist"); System.out.println("1: Update watchlist");
@ -109,6 +116,7 @@ public class Tui implements Iface, Observer {
System.out.println("Enter a number or q, then press enter.\n"); System.out.println("Enter a number or q, then press enter.\n");
} }
//Effect: execute functions basing on user input from menu
public boolean demoinput() { public boolean demoinput() {
switch (getInputLine()) { switch (getInputLine()) {
case "1": case "1":
@ -129,6 +137,7 @@ public class Tui implements Iface, Observer {
return true; return true;
} }
//Effect: main loop of program, displays menu, get input and execute functions
public void demo() { public void demo() {
System.out.println(" Welcome to " + Const.PROGRAM_NAME + "!"); System.out.println(" Welcome to " + Const.PROGRAM_NAME + "!");
boolean cont = true; boolean cont = true;
@ -182,6 +191,7 @@ public class Tui implements Iface, Observer {
} }
} }
//Effect: reprint the list when the list is updated, or if stocks are added or deleted
@Override @Override
public void update(Observable obsed, Object event) { public void update(Observable obsed, Object event) {
printWatchList(); printWatchList();

@ -22,7 +22,6 @@ public class AddButt extends JButton {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
//https://docs.oracle.com/javase/tutorial/uiswing/components/dialog.html#input //https://docs.oracle.com/javase/tutorial/uiswing/components/dialog.html#input
//https://docs.oracle.com/javase/7/docs/api/javax/swing/JOptionPane.html //https://docs.oracle.com/javase/7/docs/api/javax/swing/JOptionPane.html
System.out.println("Count of listeners: " + ((JButton) e.getSource()).getActionListeners().length);
String userin = (String)JOptionPane.showInputDialog("Enter the identifier:"); String userin = (String)JOptionPane.showInputDialog("Enter the identifier:");
if ((userin != null) && (userin.length() > 0)) { if ((userin != null) && (userin.length() > 0)) {
new Thread(new Runnable() { new Thread(new Runnable() {

@ -34,6 +34,7 @@ public class WatchTableModel extends AbstractTableModel implements Observer {
return colnames[num]; return colnames[num];
} }
//Effect: return generated table data for whatever asked
public Object getValueAt(int stock, int field) { public Object getValueAt(int stock, int field) {
StockEntry entry = watch.getStock(stock); StockEntry entry = watch.getStock(stock);
switch (field) { switch (field) {
@ -54,6 +55,8 @@ public class WatchTableModel extends AbstractTableModel implements Observer {
return example[col].getClass(); return example[col].getClass();
} }
//Effect: updates table for different events, ran by event dispatch thread as recommanded
//Modifies: Table displayed
@Override @Override
public void update(Observable obsed, Object event) { public void update(Observable obsed, Object event) {
Wevent weve = (Wevent) event; Wevent weve = (Wevent) event;

@ -18,6 +18,7 @@ public class DataSourceTest {
testSource = new AlphaVantage(); testSource = new AlphaVantage();
} }
//Effect: test add and double deleting for many to many relationship
@Test @Test
public void testAddDel() { public void testAddDel() {
testStype.addSource(testSource); testStype.addSource(testSource);
@ -25,6 +26,7 @@ public class DataSourceTest {
testSource.delStype(testStype); testSource.delStype(testStype);
} }
//Effect: test overridden equals and hashcode
@Test @Test
public void testEqualsHash() { public void testEqualsHash() {
DataSource testSource2 = new AlphaVantage(); DataSource testSource2 = new AlphaVantage();

@ -18,11 +18,13 @@ public class ListOfWatchListTest {
watchlist = new WatchList(); watchlist = new WatchList();
} }
//Effect: check if only one instance is returned
@Test @Test
public void singletonCheck() { public void singletonCheck() {
assertTrue(ListOfWatchList.getList() == ListOfWatchList.getList()); assertTrue(ListOfWatchList.getList() == ListOfWatchList.getList());
} }
//Effect: check double adding and deleting watchlists
@Test @Test
public void addDelWatchList() { public void addDelWatchList() {
ListOfWatchList lowl = ListOfWatchList.getList(); ListOfWatchList lowl = ListOfWatchList.getList();

@ -14,16 +14,19 @@ public class NasdaqTest {
private StockType naasdaq; private StockType naasdaq;
@BeforeEach @BeforeEach
// Effect: Initialize Stype
public void runBefore() { public void runBefore() {
naasdaq = StypeMap.getStype("NASDAQ"); naasdaq = StypeMap.getStype("NASDAQ");
} }
@Test @Test
//Effect: test if name matches
public void testName() { public void testName() {
assertTrue(naasdaq.getName().equals("NASDAQ")); assertTrue(naasdaq.getName().equals("NASDAQ"));
} }
@Test @Test
//Effect: check (indirectly) if update works, require internet to AlphaVantage
public void testUpdate() { public void testUpdate() {
try { try {
double[] farray = naasdaq.update("MSFT"); double[] farray = naasdaq.update("MSFT");

@ -18,11 +18,14 @@ public class NyseTest {
nyyyse = StypeMap.getStype("NYSE"); nyyyse = StypeMap.getStype("NYSE");
} }
//Effect: test constructor and if name matches
@Test @Test
public void testNameInit() { public void testNameInit() {
assertTrue(nyyyse.getName().equals("NYSE")); assertTrue(nyyyse.getName().equals("NYSE"));
} }
//Effect: will connect to the internet and test update
//Require: internet connection to AlphaVantage.co
@Test @Test
public void testUpdate() { public void testUpdate() {
try { try {
@ -32,6 +35,7 @@ public class NyseTest {
} }
} }
//Effect: test overridden equals and hashcode
@Test @Test
public void testEqualsHash() { public void testEqualsHash() {
StockType testst1 = new Nyse(); StockType testst1 = new Nyse();

@ -21,6 +21,7 @@ public class StockEntryTest {
nyyyse = StypeMap.getStype("NYSE"); nyyyse = StypeMap.getStype("NYSE");
} }
//Effect: test constructor, two getters and default 0 price
@Test @Test
public void testTypeAndName() { public void testTypeAndName() {
entry = new StockEntry(nyyyse, "test"); entry = new StockEntry(nyyyse, "test");
@ -31,6 +32,7 @@ public class StockEntryTest {
assertEquals(0, entry.getChange()); assertEquals(0, entry.getChange());
} }
//Effect: test overridden equals and hashcode
@Test @Test
public void testEqualsHash() { public void testEqualsHash() {
entry = new StockEntry(nyyyse, "test"); entry = new StockEntry(nyyyse, "test");

@ -11,11 +11,8 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
public class StypeMapTest { public class StypeMapTest {
@BeforeEach
public void runBefore() {
}
@Test @Test
//Effect: Test if Stype NYSE exists in StypeMap
public void testGetStype() { public void testGetStype() {
StockType stype = StypeMap.getStype("NYSE"); StockType stype = StypeMap.getStype("NYSE");
assertEquals(stype.getName(), "NYSE"); assertEquals(stype.getName(), "NYSE");

@ -22,6 +22,8 @@ public class WatchListTest {
watchlist = new WatchList(); watchlist = new WatchList();
} }
//Effect: add stock named 1 to 100 to watchlist, test if index is keep
//counting up and if getNames() works
@Test @Test
public void testAddStockNames() { public void testAddStockNames() {
String[] testarray = new String[100]; String[] testarray = new String[100];
@ -39,6 +41,7 @@ public class WatchListTest {
} }
} }
//Effect: test size function for 100 stocks
@Test @Test
public void testSize() { public void testSize() {
assertEquals(watchlist.size(), 0); assertEquals(watchlist.size(), 0);

Loading…
Cancel
Save