From 58c4432815d0dbe2173dbb1a4aed4c6683a10e1a Mon Sep 17 00:00:00 2001 From: WillemDalton Date: Mon, 10 Nov 2025 19:47:15 -0500 Subject: a bit more progress on the menu for import export --- .../userinput/menus/ImportExportMenu.java | 25 ++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/main/java/design/controller/userinput/menus/ImportExportMenu.java b/src/main/java/design/controller/userinput/menus/ImportExportMenu.java index ed313d7..43970ea 100644 --- a/src/main/java/design/controller/userinput/menus/ImportExportMenu.java +++ b/src/main/java/design/controller/userinput/menus/ImportExportMenu.java @@ -2,10 +2,16 @@ package design.controller.userinput.menus; import design.controller.userinput.Menu; import design.controller.userinput.MenuOption; +import design.persistence.JSONPersonalDatabase; +import design.persistence.XMLParser; import java.util.List; public class ImportExportMenu extends Menu { + + String currentFormat = "JSON"; + XMLParser xmlParser = new XMLParser(); + @Override public String getTitle() { return "import export menu"; @@ -15,17 +21,24 @@ public class ImportExportMenu extends Menu { public List getMenuOptions() { List opts = new java.util.ArrayList<>(); + opts.add(new MenuOption("return to main menu", () -> new MainMenu().present())); - opts.add(new MenuOption("set to XML", () -> new MainMenu().present())); - opts.add(new MenuOption("set to JSON", () -> new MainMenu().present())); + opts.add(new MenuOption("set to XML", () -> {currentFormat = "XML";})); + opts.add(new MenuOption("set to JSON", () -> {currentFormat = "JSON";})); - opts.add(new MenuOption("import league...", () -> { - })); + // TO DO: think of better solution for menus...i don't want to layer them deeply but saving format in a string is kind of a dumb solution. + opts.add(new MenuOption("import league...", () -> {})); opts.add(new MenuOption("export league...", () -> {})); - opts.add(new MenuOption("import personal profile...", () -> {})); - opts.add(new MenuOption("export personal profile...", () -> {})); + opts.add(new MenuOption("import personal profile...", () -> { + // if(currentFormat == "JSON") + // { + // JSONPersonalDatabase.instance().importData(null); + // } + })); + opts.add(new MenuOption("export personal profile...", () -> { + })); return opts; } -- cgit v1.2.3 From f7102fd39b266b3d31fe72448b5d64d139648dee Mon Sep 17 00:00:00 2001 From: WillemDalton Date: Tue, 11 Nov 2025 08:50:31 -0500 Subject: progress on import/export --- .../userinput/menus/ImportExportMenu.java | 70 ++++++++++++++++------ src/main/java/design/model/DataHandler.java | 11 ++++ src/main/java/design/persistence/XMLParser.java | 26 +++++--- 3 files changed, 83 insertions(+), 24 deletions(-) create mode 100644 src/main/java/design/model/DataHandler.java (limited to 'src') diff --git a/src/main/java/design/controller/userinput/menus/ImportExportMenu.java b/src/main/java/design/controller/userinput/menus/ImportExportMenu.java index 43970ea..4c7df00 100644 --- a/src/main/java/design/controller/userinput/menus/ImportExportMenu.java +++ b/src/main/java/design/controller/userinput/menus/ImportExportMenu.java @@ -5,13 +5,26 @@ import design.controller.userinput.MenuOption; import design.persistence.JSONPersonalDatabase; import design.persistence.XMLParser; +import java.io.File; +import java.io.IOException; import java.util.List; +import java.util.Map; +import java.util.Scanner; public class ImportExportMenu extends Menu { - - String currentFormat = "JSON"; XMLParser xmlParser = new XMLParser(); + private static final Map> handlers = Map.of( + "json", Map.of( + true, new PersonalJsonHandler(), + false, new LeagueJsonHandler() + ), + "csv", Map.of( + true, new PersonalCsvHandler(), + false, new LeagueCsvHandler() + )); + + @Override public String getTitle() { return "import export menu"; @@ -24,23 +37,46 @@ public class ImportExportMenu extends Menu { opts.add(new MenuOption("return to main menu", () -> new MainMenu().present())); - opts.add(new MenuOption("set to XML", () -> {currentFormat = "XML";})); - opts.add(new MenuOption("set to JSON", () -> {currentFormat = "JSON";})); + opts.add(new MenuOption("import league...", () -> promptForPath(true, false))); + opts.add(new MenuOption("export league...", () -> promptForPath(false, false))); + opts.add(new MenuOption("import personal profile...", () -> promptForPath(true, true))); + opts.add(new MenuOption("export personal profile...", () -> promptForPath(false, true))); + return opts; + } - // TO DO: think of better solution for menus...i don't want to layer them deeply but saving format in a string is kind of a dumb solution. - opts.add(new MenuOption("import league...", () -> {})); - opts.add(new MenuOption("export league...", () -> {})); - opts.add(new MenuOption("import personal profile...", () -> { - // if(currentFormat == "JSON") - // { - // JSONPersonalDatabase.instance().importData(null); - // } - })); - opts.add(new MenuOption("export personal profile...", () -> { - })); + private void promptForPath(boolean isImporting, boolean isPersonalProfile) + { + System.out.println("Enter file path: "); + Scanner sc = new Scanner(System.in); + String path = sc.nextLine(); + File file = new File(path); - return opts; + String ext = getExtension(path); + Map map = handlers.get(ext); + if (map == null) { + System.out.println("Unsupported file type: " + ext); + return; + } + + DataHandler handler = map.get(isPersonalProfile); + if (handler == null) { + System.out.println("No handler for this profile type."); + return; + } + + try { + if (isImporting) + handler.importData(file); + else + handler.exportData(file); + } catch (IOException e) { + System.err.println("I/O error: " + e.getMessage()); + } } -} \ No newline at end of file + private static String getExtension(String fileName) { + int i = fileName.lastIndexOf('.'); + return (i >= 0) ? fileName.substring(i + 1).toLowerCase() : ""; + } +} diff --git a/src/main/java/design/model/DataHandler.java b/src/main/java/design/model/DataHandler.java new file mode 100644 index 0000000..e7dda33 --- /dev/null +++ b/src/main/java/design/model/DataHandler.java @@ -0,0 +1,11 @@ +package design.model; + +import java.io.File; +import java.io.IOException; + +public interface DataHandler { + void importPersonalData(File file) throws IOException; + void exportPersonalData(File file) throws IOException; + void importLeagueData(File file) throws IOException; + void exportLeagueData(File file) throws IOException; +} \ No newline at end of file diff --git a/src/main/java/design/persistence/XMLParser.java b/src/main/java/design/persistence/XMLParser.java index 472931a..3d04a03 100644 --- a/src/main/java/design/persistence/XMLParser.java +++ b/src/main/java/design/persistence/XMLParser.java @@ -1,6 +1,7 @@ package design.persistence; import java.io.File; import java.io.IOException; +import design.model.DataHandler; import com.fasterxml.jackson.databind.ObjectMapper; @@ -9,24 +10,35 @@ import com.fasterxml.jackson.dataformat.xml.XmlMapper; -public class XMLParser { - +public class XMLParser implements DataHandler +{ private final ObjectMapper jsonMapper = new ObjectMapper(); private final XmlMapper xmlMapper = new XmlMapper(); - public File exportData() throws IOException { + public void exportPersonalData(File fileName) throws IOException { File jsonData = JSONPersonalDatabase.instance().exportData(); Golfer[] golfers = jsonMapper.readValue(jsonData, Golfer[].class); - File xmlFile = new File("data/data.xml"); + File xmlFile = new File(fileName + ".xml"); xmlMapper.writerWithDefaultPrettyPrinter().writeValue(xmlFile, golfers); - return xmlFile; } - public void importData(File xmlFile) throws IOException { - Golfer[] golfers = xmlMapper.readValue(xmlFile, Golfer[].class); + public void importPersonalData(File fileName) throws IOException { + Golfer[] golfers = xmlMapper.readValue(fileName, Golfer[].class); File tempJson = File.createTempFile("imported", ".json"); jsonMapper.writerWithDefaultPrettyPrinter().writeValue(tempJson, golfers); JSONPersonalDatabase.instance().importData(tempJson); tempJson.delete(); } + + public void exportLeagueData(File fileName) + { + // TO DO: exporting league data + } + + public void importLeagueData(File fileName) + { + // TO DO: importing league data + } } + + -- cgit v1.2.3 From 94ac731c00da6022909bbb96c835d7c63204da73 Mon Sep 17 00:00:00 2001 From: WillemDalton Date: Tue, 11 Nov 2025 09:01:01 -0500 Subject: progress on importing exporting --- .../userinput/menus/ImportExportMenu.java | 52 ++++++++++------------ .../controller/userinput/menus/UserSettings.java | 9 +--- src/main/java/design/persistence/JSONHandler.java | 28 ++++++++++++ src/main/java/design/persistence/XMLHandler.java | 44 ++++++++++++++++++ src/main/java/design/persistence/XMLParser.java | 44 ------------------ 5 files changed, 97 insertions(+), 80 deletions(-) create mode 100644 src/main/java/design/persistence/JSONHandler.java create mode 100644 src/main/java/design/persistence/XMLHandler.java delete mode 100644 src/main/java/design/persistence/XMLParser.java (limited to 'src') diff --git a/src/main/java/design/controller/userinput/menus/ImportExportMenu.java b/src/main/java/design/controller/userinput/menus/ImportExportMenu.java index 4c7df00..db861c5 100644 --- a/src/main/java/design/controller/userinput/menus/ImportExportMenu.java +++ b/src/main/java/design/controller/userinput/menus/ImportExportMenu.java @@ -2,8 +2,8 @@ package design.controller.userinput.menus; import design.controller.userinput.Menu; import design.controller.userinput.MenuOption; -import design.persistence.JSONPersonalDatabase; -import design.persistence.XMLParser; +import design.persistence.JSONHandler; +import design.persistence.XMLHandler; import java.io.File; import java.io.IOException; @@ -11,20 +11,14 @@ import java.util.List; import java.util.Map; import java.util.Scanner; -public class ImportExportMenu extends Menu { - XMLParser xmlParser = new XMLParser(); +import design.model.DataHandler; - private static final Map> handlers = Map.of( - "json", Map.of( - true, new PersonalJsonHandler(), - false, new LeagueJsonHandler() - ), - "csv", Map.of( - true, new PersonalCsvHandler(), - false, new LeagueCsvHandler() - )); +public class ImportExportMenu extends Menu { + private static final Map handlers = Map.of( + "xml", new XMLHandler(), + "json", new JSONHandler() + ); - @Override public String getTitle() { return "import export menu"; @@ -49,27 +43,29 @@ public class ImportExportMenu extends Menu { { System.out.println("Enter file path: "); Scanner sc = new Scanner(System.in); - String path = sc.nextLine(); - File file = new File(path); + String filePath = sc.nextLine(); + File file = new File(filePath); - String ext = getExtension(path); - Map map = handlers.get(ext); - if (map == null) { - System.out.println("Unsupported file type: " + ext); - return; - } + String ext = getExtension(filePath); + DataHandler handler = handlers.get(ext); - DataHandler handler = map.get(isPersonalProfile); if (handler == null) { - System.out.println("No handler for this profile type."); + System.out.println("Unsupported file type: " + ext); return; } try { - if (isImporting) - handler.importData(file); - else - handler.exportData(file); + if (isImporting) { + if (isPersonalProfile) + handler.importPersonalData(file); + else + handler.importLeagueData(file); + } else { + if (isPersonalProfile) + handler.exportPersonalData(file); + else + handler.exportLeagueData(file); + } } catch (IOException e) { System.err.println("I/O error: " + e.getMessage()); } diff --git a/src/main/java/design/controller/userinput/menus/UserSettings.java b/src/main/java/design/controller/userinput/menus/UserSettings.java index d029e45..865b00d 100644 --- a/src/main/java/design/controller/userinput/menus/UserSettings.java +++ b/src/main/java/design/controller/userinput/menus/UserSettings.java @@ -60,15 +60,8 @@ public class UserSettings extends Menu { this.present(); })); - - opts.add(new MenuOption("import...", () -> { - - })); + opts.add(new MenuOption("manage data...", () -> new ImportExportMenu().present())); - opts.add(new MenuOption("export...", () -> { - - this.present(); - })); return opts; } diff --git a/src/main/java/design/persistence/JSONHandler.java b/src/main/java/design/persistence/JSONHandler.java new file mode 100644 index 0000000..06ed202 --- /dev/null +++ b/src/main/java/design/persistence/JSONHandler.java @@ -0,0 +1,28 @@ +package design.persistence; +import java.io.File; +import java.io.IOException; +import design.model.DataHandler; + +public class JSONHandler implements DataHandler +{ + + public void exportPersonalData(File fileName) throws IOException { + JSONPersonalDatabase.instance().exportData(); // fix this + } + + public void importPersonalData(File fileName) throws IOException { + JSONPersonalDatabase.instance().importData(fileName); + } + + public void exportLeagueData(File fileName) + { + // TO DO: exporting league data + } + + public void importLeagueData(File fileName) + { + // TO DO: importing league data + } +} + + diff --git a/src/main/java/design/persistence/XMLHandler.java b/src/main/java/design/persistence/XMLHandler.java new file mode 100644 index 0000000..413defc --- /dev/null +++ b/src/main/java/design/persistence/XMLHandler.java @@ -0,0 +1,44 @@ +package design.persistence; +import java.io.File; +import java.io.IOException; +import design.model.DataHandler; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import design.model.Golfer; +import com.fasterxml.jackson.dataformat.xml.XmlMapper; + + + +public class XMLHandler implements DataHandler +{ + private final ObjectMapper jsonMapper = new ObjectMapper(); + private final XmlMapper xmlMapper = new XmlMapper(); + + public void exportPersonalData(File fileName) throws IOException { + File jsonData = JSONPersonalDatabase.instance().exportData(); + Golfer[] golfers = jsonMapper.readValue(jsonData, Golfer[].class); + File xmlFile = new File(fileName + ".xml"); + xmlMapper.writerWithDefaultPrettyPrinter().writeValue(xmlFile, golfers); + } + + public void importPersonalData(File fileName) throws IOException { + Golfer[] golfers = xmlMapper.readValue(fileName, Golfer[].class); + File tempJson = File.createTempFile("imported", ".json"); + jsonMapper.writerWithDefaultPrettyPrinter().writeValue(tempJson, golfers); + JSONPersonalDatabase.instance().importData(tempJson); + tempJson.delete(); + } + + public void exportLeagueData(File fileName) + { + // TO DO: exporting league data + } + + public void importLeagueData(File fileName) + { + // TO DO: importing league data + } +} + + diff --git a/src/main/java/design/persistence/XMLParser.java b/src/main/java/design/persistence/XMLParser.java deleted file mode 100644 index 3d04a03..0000000 --- a/src/main/java/design/persistence/XMLParser.java +++ /dev/null @@ -1,44 +0,0 @@ -package design.persistence; -import java.io.File; -import java.io.IOException; -import design.model.DataHandler; - -import com.fasterxml.jackson.databind.ObjectMapper; - -import design.model.Golfer; -import com.fasterxml.jackson.dataformat.xml.XmlMapper; - - - -public class XMLParser implements DataHandler -{ - private final ObjectMapper jsonMapper = new ObjectMapper(); - private final XmlMapper xmlMapper = new XmlMapper(); - - public void exportPersonalData(File fileName) throws IOException { - File jsonData = JSONPersonalDatabase.instance().exportData(); - Golfer[] golfers = jsonMapper.readValue(jsonData, Golfer[].class); - File xmlFile = new File(fileName + ".xml"); - xmlMapper.writerWithDefaultPrettyPrinter().writeValue(xmlFile, golfers); - } - - public void importPersonalData(File fileName) throws IOException { - Golfer[] golfers = xmlMapper.readValue(fileName, Golfer[].class); - File tempJson = File.createTempFile("imported", ".json"); - jsonMapper.writerWithDefaultPrettyPrinter().writeValue(tempJson, golfers); - JSONPersonalDatabase.instance().importData(tempJson); - tempJson.delete(); - } - - public void exportLeagueData(File fileName) - { - // TO DO: exporting league data - } - - public void importLeagueData(File fileName) - { - // TO DO: importing league data - } -} - - -- cgit v1.2.3 From d29548bd7d04375578361f6a75659c046a270b75 Mon Sep 17 00:00:00 2001 From: WillemDalton Date: Tue, 11 Nov 2025 16:42:39 -0500 Subject: fixed exporting xml --- .../design/controller/userinput/menus/ImportExportMenu.java | 2 ++ src/main/java/design/persistence/JSONHandler.java | 2 +- src/main/java/design/persistence/JSONPersonalDatabase.java | 11 ++++++----- src/main/java/design/persistence/PersonalDatabase.java | 4 ---- src/main/java/design/persistence/XMLHandler.java | 11 +++++++---- 5 files changed, 16 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/main/java/design/controller/userinput/menus/ImportExportMenu.java b/src/main/java/design/controller/userinput/menus/ImportExportMenu.java index db861c5..dbad0e3 100644 --- a/src/main/java/design/controller/userinput/menus/ImportExportMenu.java +++ b/src/main/java/design/controller/userinput/menus/ImportExportMenu.java @@ -69,6 +69,8 @@ public class ImportExportMenu extends Menu { } catch (IOException e) { System.err.println("I/O error: " + e.getMessage()); } + + new ImportExportMenu().present(); } private static String getExtension(String fileName) { diff --git a/src/main/java/design/persistence/JSONHandler.java b/src/main/java/design/persistence/JSONHandler.java index 06ed202..419d080 100644 --- a/src/main/java/design/persistence/JSONHandler.java +++ b/src/main/java/design/persistence/JSONHandler.java @@ -7,7 +7,7 @@ public class JSONHandler implements DataHandler { public void exportPersonalData(File fileName) throws IOException { - JSONPersonalDatabase.instance().exportData(); // fix this + JSONPersonalDatabase.instance().exportData(fileName); // fix this } public void importPersonalData(File fileName) throws IOException { diff --git a/src/main/java/design/persistence/JSONPersonalDatabase.java b/src/main/java/design/persistence/JSONPersonalDatabase.java index 2f003cb..8d263fc 100644 --- a/src/main/java/design/persistence/JSONPersonalDatabase.java +++ b/src/main/java/design/persistence/JSONPersonalDatabase.java @@ -13,6 +13,8 @@ import design.model.League; import java.io.File; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; import java.util.HashMap; import java.util.Map; @@ -99,13 +101,12 @@ public class JSONPersonalDatabase implements PersonalDatabase { save(); } - @Override - public File exportData() throws IOException{ - save(); - return file; + + public File exportData(File newFile) throws IOException{ + Files.copy(file.toPath(), newFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + return newFile; } - @Override public void importData(File newFile) throws IOException { Golfer[] newGolfers = mapper.readValue(newFile, Golfer[].class); cache.clear(); diff --git a/src/main/java/design/persistence/PersonalDatabase.java b/src/main/java/design/persistence/PersonalDatabase.java index 186474e..63f9182 100644 --- a/src/main/java/design/persistence/PersonalDatabase.java +++ b/src/main/java/design/persistence/PersonalDatabase.java @@ -19,8 +19,4 @@ public interface PersonalDatabase { void removeGolfer(Golfer golfer) throws IOException; void updateGolfer(Golfer golfer) throws IOException; - - void importData(File newFile) throws IOException; - - File exportData() throws IOException; } diff --git a/src/main/java/design/persistence/XMLHandler.java b/src/main/java/design/persistence/XMLHandler.java index 413defc..dc67687 100644 --- a/src/main/java/design/persistence/XMLHandler.java +++ b/src/main/java/design/persistence/XMLHandler.java @@ -3,7 +3,9 @@ import java.io.File; import java.io.IOException; import design.model.DataHandler; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; import design.model.Golfer; import com.fasterxml.jackson.dataformat.xml.XmlMapper; @@ -16,10 +18,11 @@ public class XMLHandler implements DataHandler private final XmlMapper xmlMapper = new XmlMapper(); public void exportPersonalData(File fileName) throws IOException { - File jsonData = JSONPersonalDatabase.instance().exportData(); - Golfer[] golfers = jsonMapper.readValue(jsonData, Golfer[].class); - File xmlFile = new File(fileName + ".xml"); - xmlMapper.writerWithDefaultPrettyPrinter().writeValue(xmlFile, golfers); + File jsonData = JSONPersonalDatabase.instance().exportData(fileName); + JsonNode golfersNode = jsonMapper.readTree(jsonData); + ObjectNode root = xmlMapper.createObjectNode(); + root.set("golfers", golfersNode); + xmlMapper.writerWithDefaultPrettyPrinter().writeValue(fileName, root); } public void importPersonalData(File fileName) throws IOException { -- cgit v1.2.3 From 7de856cbb656d8b5fa88fed62380a8d4611060a1 Mon Sep 17 00:00:00 2001 From: WillemDalton Date: Tue, 11 Nov 2025 17:51:31 -0500 Subject: working on XML formatting --- src/main/java/design/model/Golfer.java | 3 +++ src/main/java/design/persistence/JSONHandler.java | 12 +++++------ src/main/java/design/persistence/XMLHandler.java | 25 +++++++++++++++-------- 3 files changed, 26 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/main/java/design/model/Golfer.java b/src/main/java/design/model/Golfer.java index 960568f..1c4e669 100644 --- a/src/main/java/design/model/Golfer.java +++ b/src/main/java/design/model/Golfer.java @@ -1,6 +1,7 @@ package design.model; import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; import java.util.ArrayList; @@ -17,6 +18,8 @@ public class Golfer { private int nextClubId; private final List invites; + + @JsonCreator private Golfer(String username, int passwordHash, String fullName, List courses, List rounds, List clubs, List invites) { diff --git a/src/main/java/design/persistence/JSONHandler.java b/src/main/java/design/persistence/JSONHandler.java index 419d080..a8967d2 100644 --- a/src/main/java/design/persistence/JSONHandler.java +++ b/src/main/java/design/persistence/JSONHandler.java @@ -6,20 +6,20 @@ import design.model.DataHandler; public class JSONHandler implements DataHandler { - public void exportPersonalData(File fileName) throws IOException { - JSONPersonalDatabase.instance().exportData(fileName); // fix this + public void exportPersonalData(File file) throws IOException { + JSONPersonalDatabase.instance().exportData(file); } - public void importPersonalData(File fileName) throws IOException { - JSONPersonalDatabase.instance().importData(fileName); + public void importPersonalData(File file) throws IOException { + JSONPersonalDatabase.instance().importData(file); } - public void exportLeagueData(File fileName) + public void exportLeagueData(File file) { // TO DO: exporting league data } - public void importLeagueData(File fileName) + public void importLeagueData(File file) { // TO DO: importing league data } diff --git a/src/main/java/design/persistence/XMLHandler.java b/src/main/java/design/persistence/XMLHandler.java index dc67687..c71712b 100644 --- a/src/main/java/design/persistence/XMLHandler.java +++ b/src/main/java/design/persistence/XMLHandler.java @@ -17,28 +17,37 @@ public class XMLHandler implements DataHandler private final ObjectMapper jsonMapper = new ObjectMapper(); private final XmlMapper xmlMapper = new XmlMapper(); - public void exportPersonalData(File fileName) throws IOException { - File jsonData = JSONPersonalDatabase.instance().exportData(fileName); + public void exportPersonalData(File file) throws IOException { + // get our json data + File jsonData = JSONPersonalDatabase.instance().exportData(file); + + // read the top tree node (the array) JsonNode golfersNode = jsonMapper.readTree(jsonData); + + // map it to an object node (not sure if im gonna use this) ObjectNode root = xmlMapper.createObjectNode(); - root.set("golfers", golfersNode); - xmlMapper.writerWithDefaultPrettyPrinter().writeValue(fileName, root); + root.set("golfer", golfersNode); + xmlMapper.writerWithDefaultPrettyPrinter().writeValue(file, root); } - public void importPersonalData(File fileName) throws IOException { - Golfer[] golfers = xmlMapper.readValue(fileName, Golfer[].class); + public void importPersonalData(File file) throws IOException { + + // get our root node + JsonNode root = xmlMapper.readTree(file); + Golfer[] golfers = xmlMapper.treeToValue(root, Golfer[].class); + File tempJson = File.createTempFile("imported", ".json"); jsonMapper.writerWithDefaultPrettyPrinter().writeValue(tempJson, golfers); JSONPersonalDatabase.instance().importData(tempJson); tempJson.delete(); } - public void exportLeagueData(File fileName) + public void exportLeagueData(File file) { // TO DO: exporting league data } - public void importLeagueData(File fileName) + public void importLeagueData(File file) { // TO DO: importing league data } -- cgit v1.2.3 From 0efa0586e27c173211153b186ae08eb3b7c8d588 Mon Sep 17 00:00:00 2001 From: WillemDalton Date: Thu, 13 Nov 2025 08:28:18 -0500 Subject: added league JSON import/export, still working with XML import --- src/main/java/design/persistence/JSONHandler.java | 8 +++--- .../design/persistence/JSONLeagueDatabase.java | 17 ++++++++++++ .../design/persistence/JSONPersonalDatabase.java | 1 - src/main/java/design/persistence/XMLHandler.java | 31 +++++++++++++--------- 4 files changed, 40 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/main/java/design/persistence/JSONHandler.java b/src/main/java/design/persistence/JSONHandler.java index a8967d2..77ec987 100644 --- a/src/main/java/design/persistence/JSONHandler.java +++ b/src/main/java/design/persistence/JSONHandler.java @@ -14,14 +14,14 @@ public class JSONHandler implements DataHandler JSONPersonalDatabase.instance().importData(file); } - public void exportLeagueData(File file) + public void exportLeagueData(File file) throws IOException { - // TO DO: exporting league data + JSONLeagueDatabase.instance().importData(file); } - public void importLeagueData(File file) + public void importLeagueData(File file) throws IOException { - // TO DO: importing league data + JSONLeagueDatabase.instance().exportData(file); } } diff --git a/src/main/java/design/persistence/JSONLeagueDatabase.java b/src/main/java/design/persistence/JSONLeagueDatabase.java index 8b201e6..edc649b 100644 --- a/src/main/java/design/persistence/JSONLeagueDatabase.java +++ b/src/main/java/design/persistence/JSONLeagueDatabase.java @@ -13,6 +13,8 @@ import design.model.League; import java.io.File; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -97,4 +99,19 @@ public class JSONLeagueDatabase implements LeagueDatabase { cache.put(league.getId(), league); save(); } + + public File exportData(File newFile) throws IOException{ + Files.copy(file.toPath(), newFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + return newFile; + } + + public void importData(File newFile) throws IOException { + League[] newLeagues = mapper.readValue(newFile, League[].class); + cache.clear(); + for (League l: newLeagues) { + cache.put(l.getId(), l); + } + save(); + } + } diff --git a/src/main/java/design/persistence/JSONPersonalDatabase.java b/src/main/java/design/persistence/JSONPersonalDatabase.java index 8d263fc..3fc5cab 100644 --- a/src/main/java/design/persistence/JSONPersonalDatabase.java +++ b/src/main/java/design/persistence/JSONPersonalDatabase.java @@ -113,7 +113,6 @@ public class JSONPersonalDatabase implements PersonalDatabase { for (Golfer g : newGolfers) { cache.put(g.getUsername(), g); } - save(); } } diff --git a/src/main/java/design/persistence/XMLHandler.java b/src/main/java/design/persistence/XMLHandler.java index c71712b..eaae811 100644 --- a/src/main/java/design/persistence/XMLHandler.java +++ b/src/main/java/design/persistence/XMLHandler.java @@ -20,11 +20,9 @@ public class XMLHandler implements DataHandler public void exportPersonalData(File file) throws IOException { // get our json data File jsonData = JSONPersonalDatabase.instance().exportData(file); - // read the top tree node (the array) JsonNode golfersNode = jsonMapper.readTree(jsonData); - - // map it to an object node (not sure if im gonna use this) + // map it to an object node ObjectNode root = xmlMapper.createObjectNode(); root.set("golfer", golfersNode); xmlMapper.writerWithDefaultPrettyPrinter().writeValue(file, root); @@ -32,22 +30,31 @@ public class XMLHandler implements DataHandler public void importPersonalData(File file) throws IOException { - // get our root node - JsonNode root = xmlMapper.readTree(file); - Golfer[] golfers = xmlMapper.treeToValue(root, Golfer[].class); + JsonNode root = xmlMapper.readTree(file); + JsonNode golfersNode = root.get("golfer"); + if (golfersNode == null) { + throw new IOException("Expected 'golfer' element in XML root, but none found"); + } + if (!golfersNode.isArray()) { + golfersNode = xmlMapper.createArrayNode().add(golfersNode); + } + + Golfer[] golfers = xmlMapper.treeToValue(golfersNode, Golfer[].class); - File tempJson = File.createTempFile("imported", ".json"); - jsonMapper.writerWithDefaultPrettyPrinter().writeValue(tempJson, golfers); - JSONPersonalDatabase.instance().importData(tempJson); - tempJson.delete(); + File tempJson = File.createTempFile("imported", ".json"); + jsonMapper.writerWithDefaultPrettyPrinter().writeValue(tempJson, golfers); + JSONPersonalDatabase.instance().importData(tempJson); + tempJson.delete(); } - public void exportLeagueData(File file) + + + public void exportLeagueData(File file) throws IOException { // TO DO: exporting league data } - public void importLeagueData(File file) + public void importLeagueData(File file) throws IOException { // TO DO: importing league data } -- cgit v1.2.3 From 18a142e6d76288ae9bc6a597461e06a5ee02f6ad Mon Sep 17 00:00:00 2001 From: WillemDalton Date: Thu, 13 Nov 2025 09:00:56 -0500 Subject: more work on adapting to XML --- src/main/java/design/persistence/XMLHandler.java | 28 ++++++++---------------- 1 file changed, 9 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/main/java/design/persistence/XMLHandler.java b/src/main/java/design/persistence/XMLHandler.java index eaae811..174407a 100644 --- a/src/main/java/design/persistence/XMLHandler.java +++ b/src/main/java/design/persistence/XMLHandler.java @@ -23,28 +23,18 @@ public class XMLHandler implements DataHandler // read the top tree node (the array) JsonNode golfersNode = jsonMapper.readTree(jsonData); // map it to an object node - ObjectNode root = xmlMapper.createObjectNode(); - root.set("golfer", golfersNode); - xmlMapper.writerWithDefaultPrettyPrinter().writeValue(file, root); + xmlMapper.writerWithDefaultPrettyPrinter().writeValue(file, golfersNode); } public void importPersonalData(File file) throws IOException { - - JsonNode root = xmlMapper.readTree(file); - JsonNode golfersNode = root.get("golfer"); - if (golfersNode == null) { - throw new IOException("Expected 'golfer' element in XML root, but none found"); - } - if (!golfersNode.isArray()) { - golfersNode = xmlMapper.createArrayNode().add(golfersNode); - } - - Golfer[] golfers = xmlMapper.treeToValue(golfersNode, Golfer[].class); - - File tempJson = File.createTempFile("imported", ".json"); - jsonMapper.writerWithDefaultPrettyPrinter().writeValue(tempJson, golfers); - JSONPersonalDatabase.instance().importData(tempJson); - tempJson.delete(); + JsonNode root = xmlMapper.readTree(file); + + System.out.println(root.toPrettyString()); + Golfer[] golfers = xmlMapper.treeToValue(root, Golfer[].class); + File tempJson = File.createTempFile("imported", ".json"); + jsonMapper.writerWithDefaultPrettyPrinter().writeValue(tempJson, golfers); + JSONPersonalDatabase.instance().importData(tempJson); + tempJson.delete(); } -- cgit v1.2.3 From 38aacc304d5bc55a8e5705f9eb378ca18fc5a4a7 Mon Sep 17 00:00:00 2001 From: WillemDalton Date: Thu, 13 Nov 2025 09:05:29 -0500 Subject: added comments to adapter --- src/main/java/design/persistence/XMLHandler.java | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/main/java/design/persistence/XMLHandler.java b/src/main/java/design/persistence/XMLHandler.java index 174407a..706dabd 100644 --- a/src/main/java/design/persistence/XMLHandler.java +++ b/src/main/java/design/persistence/XMLHandler.java @@ -18,19 +18,32 @@ public class XMLHandler implements DataHandler private final XmlMapper xmlMapper = new XmlMapper(); public void exportPersonalData(File file) throws IOException { - // get our json data + // get our json data just from the JSON database File jsonData = JSONPersonalDatabase.instance().exportData(file); - // read the top tree node (the array) + + // read the the data from the JSON, as a JsonNode. JsonNode golfersNode = jsonMapper.readTree(jsonData); - // map it to an object node - xmlMapper.writerWithDefaultPrettyPrinter().writeValue(file, golfersNode); + + // XML requires a parent node, we can't just throw the golfersnode into the xml or else it will only produce the first element + ObjectNode root = xmlMapper.createObjectNode(); + root.set("golfer", golfersNode); + + //write to the xml file. + xmlMapper.writerWithDefaultPrettyPrinter().writeValue(file, root); } public void importPersonalData(File file) throws IOException { + + // read our root, the object node JsonNode root = xmlMapper.readTree(file); + // debug print line System.out.println(root.toPrettyString()); + + // !!! here is where it's failing...our root is not serializable to an array of golfers. !!! Golfer[] golfers = xmlMapper.treeToValue(root, Golfer[].class); + + // from here out should be good File tempJson = File.createTempFile("imported", ".json"); jsonMapper.writerWithDefaultPrettyPrinter().writeValue(tempJson, golfers); JSONPersonalDatabase.instance().importData(tempJson); -- cgit v1.2.3 From 7c08fd2cc7da786cc7770f63afac167eb379ffd6 Mon Sep 17 00:00:00 2001 From: WillemDalton Date: Thu, 13 Nov 2025 16:53:48 -0500 Subject: fixed broken unit tests in club --- src/test/java/design/model/ClubTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/test/java/design/model/ClubTest.java b/src/test/java/design/model/ClubTest.java index 9ac8130..f73f322 100644 --- a/src/test/java/design/model/ClubTest.java +++ b/src/test/java/design/model/ClubTest.java @@ -17,7 +17,7 @@ public class ClubTest { { Club testClub = new Club("John Doe", "The Slammer", ClubType.DRIVER); - assertEquals(0, testClub.getId()); + assertEquals(-1, testClub.getId()); assertEquals("John Doe", testClub.getManufacture()); assertEquals("The Slammer", testClub.getNickname()); assertEquals(ClubType.DRIVER, testClub.getClubType()); @@ -55,7 +55,7 @@ public class ClubTest { void testToString() { Club testClub = new Club("John Doe", "The Slammer", ClubType.DRIVER); - String expectedString = "#0 The Slammer - John Doe (DRIVER)"; + String expectedString = "#-1 The Slammer - John Doe (DRIVER)"; assertEquals(expectedString, testClub.toString()); } } -- cgit v1.2.3 From 229a469f61f842260618ee52294b5dae0f3c1bb4 Mon Sep 17 00:00:00 2001 From: WillemDalton Date: Thu, 13 Nov 2025 17:35:47 -0500 Subject: completed coverage for stroke league --- src/test/java/design/model/ClubTest.java | 25 +++++++++ src/test/java/design/model/HoleTest.java | 55 ++++++++++++++++++++ src/test/java/design/model/RoundTest.java | 50 ++++++++++++++++++ src/test/java/design/model/StrokeLeagueTest.java | 66 ++++++++++++++++++++++++ 4 files changed, 196 insertions(+) create mode 100644 src/test/java/design/model/HoleTest.java create mode 100644 src/test/java/design/model/StrokeLeagueTest.java (limited to 'src') diff --git a/src/test/java/design/model/ClubTest.java b/src/test/java/design/model/ClubTest.java index f73f322..f47405f 100644 --- a/src/test/java/design/model/ClubTest.java +++ b/src/test/java/design/model/ClubTest.java @@ -1,6 +1,13 @@ package design.model; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Modifier; + import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @@ -23,6 +30,16 @@ public class ClubTest { assertEquals(ClubType.DRIVER, testClub.getClubType()); } + @Test + void testPrivateConstructor() throws Exception + { + Constructor constructor = Club.class.getDeclaredConstructor(int.class, String.class, String.class, ClubType.class); + assertTrue(Modifier.isPrivate(constructor.getModifiers())); + constructor.setAccessible(true); + Club testClub = constructor.newInstance(0, "John Doe", "The Slammer", ClubType.DRIVER); + assertNotNull(testClub); + } + @Test void testGetClubType() { @@ -51,6 +68,14 @@ public class ClubTest { assertEquals(-1, testClub.getId()); } + @Test + void testSetId() + { + Club testClub = new Club("John Doe", "The Slammer", ClubType.DRIVER); + testClub.setId(10); + assertThrows(AssertionError.class, () -> testClub.setId(5)); + } + @Test void testToString() { diff --git a/src/test/java/design/model/HoleTest.java b/src/test/java/design/model/HoleTest.java new file mode 100644 index 0000000..58aff49 --- /dev/null +++ b/src/test/java/design/model/HoleTest.java @@ -0,0 +1,55 @@ +package design.model; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +/** Tests for the hole model class. + * @author Willem Dalton + */ +@Tag("Model-tier") +public class HoleTest { + + @Test + void testValidEquals() + { + Hole hole1 = new Hole(0, 10); + Hole hole2 = new Hole(0, 10); + assertTrue(hole1.equals(hole2)); + } + + @Test + void testNotAHole() + { + Hole hole1 = new Hole(0, 10); + String notAHole = "ImNotAHole!"; + assertFalse(hole1.equals(notAHole)); + } + + @Test + void testNotEquals() + { + Hole hole1 = new Hole(0, 10); + Hole hole2 = new Hole(10, 999); + assertFalse(hole1.equals(hole2)); + } + + @Test + void testNotEqualPar() + { + Hole hole1 = new Hole(0, 10); + Hole hole2 = new Hole(0, 999); + assertFalse(hole1.equals(hole2)); + } + + @Test + void testNotEqualNumber() + { + Hole hole1 = new Hole(0, 10); + Hole hole2 = new Hole(10, 10); + assertFalse(hole1.equals(hole2)); + } +} + diff --git a/src/test/java/design/model/RoundTest.java b/src/test/java/design/model/RoundTest.java index d472f5b..76d8f47 100644 --- a/src/test/java/design/model/RoundTest.java +++ b/src/test/java/design/model/RoundTest.java @@ -1,12 +1,19 @@ package design.model; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +import design.model.Club.ClubType; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Modifier; import java.time.LocalDateTime; import java.util.ArrayList; +import java.util.List; /** Unit Tests for the Round class. * @author Willem Dalton @@ -26,6 +33,18 @@ public class RoundTest { assertEquals(testHole, testRound.getStartingHole()); } + @Test + void testPrivateConstructor() throws Exception + { + Course testCourse = new Course(0, "Rolling Waves", 62, "Rochester, NY", 9, 20, new ArrayList()); + Constructor constructor = Round.class.getDeclaredConstructor(Course.class, LocalDateTime.class, Hole.class, List.class); + assertTrue(Modifier.isPrivate(constructor.getModifiers())); + constructor.setAccessible(true); + Round testRound = constructor.newInstance(testCourse, LocalDateTime.now(), new Hole(0, 0), new ArrayList()); + assertNotNull(testRound); + } + + @Test void testHolePlay() { @@ -36,7 +55,38 @@ public class RoundTest { Play testPlay = new Play(0); testRound.addPlay(testPlay); + assertEquals(1, testRound.getPlays().length); assertEquals(testPlay, testRound.getPlays()[0]); + assertEquals(0, testRound.getTotalSwings()); + + Club newClub = new Club("John Doe Inc", "The Slammer", ClubType.DRIVER); + Swing newSwing = new Swing(200, newClub); + + // try swinging, expect to see another swing added. + testPlay.addSwing(newSwing); + + assertEquals(1, testRound.getTotalSwings()); + assertEquals(200, testRound.getTotalDistance()); + } + + @Test + void testProgressHole() + { + Hole testHole = new Hole(0,3); + Hole nextHole = new Hole(1, 5); + + ArrayList testHoles = new ArrayList(); + testHoles.add(testHole); + testHoles.add(nextHole); + + Course testCourse = new Course(0, "Rolling Waves", 62, "Rochester, NY", 9, 20, testHoles); + LocalDateTime testTime = LocalDateTime.now(); + Round testRound = new Round(testCourse, testTime, testHole); + + // progress a Hole and check value. + assertEquals(testHole, testRound.getCurrentHole()); + testRound.nextHole(); + assertEquals(nextHole, testRound.getCurrentHole()); } } diff --git a/src/test/java/design/model/StrokeLeagueTest.java b/src/test/java/design/model/StrokeLeagueTest.java new file mode 100644 index 0000000..cc37887 --- /dev/null +++ b/src/test/java/design/model/StrokeLeagueTest.java @@ -0,0 +1,66 @@ +package design.model; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +/** Tests for the league model class. + * @author Willem Dalton + */ +@Tag("Model-tier") +public class StrokeLeagueTest { + + @Test + void testConstructor() + { + Date testStart = new Date(1234567); + Date testRegistration = new Date(1234568); + Date testEnd = new Date(12345679); + Golfer testOwner = new Golfer("Bobby", "bobby123", "iloveswen262"); + StrokeLeague testLeague = new StrokeLeague("Bobby's Band", testRegistration, testStart, testEnd, testOwner); + assertEquals(-1, testLeague.getId()); + assertEquals("Bobby's Band", testLeague.getName()); + assertEquals(testRegistration, testLeague.getRegistrationDate()); + assertEquals(testStart, testLeague.getStartDate()); + assertEquals(testEnd, testLeague.getEndDate()); + assertEquals(testOwner, testLeague.getOwner()); + } + + @Test + void testPrivateConstructor() throws Exception + { + Golfer testOwner = new Golfer("Bobby", "bobby123", "iloveswen262"); + Constructor constructor = StrokeLeague.class.getDeclaredConstructor(int.class, String.class, Date.class, Date.class, Date.class, Golfer.class, List.class, List.class); + assertTrue(Modifier.isPrivate(constructor.getModifiers())); + constructor.setAccessible(true); + StrokeLeague testLeague = constructor.newInstance(1, "Bobby's Band", new Date(), new Date(), new Date(), testOwner, new ArrayList(), new ArrayList()); + assertNotNull(testLeague); + } + + @Test + void testParticipants() throws Exception + { + Date testStart = new Date(1234567); + Date testRegistration = new Date(1234568); + Date testEnd = new Date(12345679); + Golfer testOwner = new Golfer("Bobby", "bobby123", "iloveswen262"); + StrokeLeague testLeague = new StrokeLeague("Bobby's Band", testRegistration, testStart, testEnd, testOwner); + + // add and remove participant + testLeague.addParticipants(testOwner); + assertEquals(testOwner, testLeague.getParticipants()[0]); + assertEquals(1, testLeague.getParticipants().length); + testLeague.removeParticipants(testOwner); + assertEquals(0, testLeague.getParticipants().length); + } +} -- cgit v1.2.3 From ea93075796d8af8e7dee1d2eac7407e7bbe8aea8 Mon Sep 17 00:00:00 2001 From: WillemDalton Date: Thu, 13 Nov 2025 17:48:29 -0500 Subject: completed unit testing for scramble --- src/test/java/design/model/ScrambleLeagueTest.java | 89 ++++++++++++++++++++++ src/test/java/design/model/StrokeLeagueTest.java | 3 +- 2 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 src/test/java/design/model/ScrambleLeagueTest.java (limited to 'src') diff --git a/src/test/java/design/model/ScrambleLeagueTest.java b/src/test/java/design/model/ScrambleLeagueTest.java new file mode 100644 index 0000000..e8fe63c --- /dev/null +++ b/src/test/java/design/model/ScrambleLeagueTest.java @@ -0,0 +1,89 @@ +package design.model; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +/** Tests for the scramble league model class. + * @author Willem Dalton + */ +@Tag("Model-tier") +public class ScrambleLeagueTest { + + @Test + void testConstructor() + { + Date testStart = new Date(1234567); + Date testRegistration = new Date(1234568); + Date testEnd = new Date(12345679); + Golfer testOwner = new Golfer("Bobby", "bobby123", "iloveswen262"); + ScrambleLeague testLeague = new ScrambleLeague("Bobby's Band", testRegistration, testStart, testEnd, testOwner); + assertEquals(-1, testLeague.getId()); + assertEquals("Bobby's Band", testLeague.getName()); + assertEquals(testRegistration, testLeague.getRegistrationDate()); + assertEquals(testStart, testLeague.getStartDate()); + assertEquals(testEnd, testLeague.getEndDate()); + assertEquals(testOwner, testLeague.getOwner()); + } + + @Test + void testPrivateConstructor() throws Exception + { + Golfer testOwner = new Golfer("Bobby", "bobby123", "iloveswen262"); + Constructor constructor = ScrambleLeague.class.getDeclaredConstructor(int.class, String.class, Date.class, Date.class, Date.class, Golfer.class, List.class, List.class); + assertTrue(Modifier.isPrivate(constructor.getModifiers())); + constructor.setAccessible(true); + ScrambleLeague testLeague = constructor.newInstance(1, "Bobby's Band", new Date(), new Date(), new Date(), testOwner, new ArrayList(), new ArrayList()); + assertNotNull(testLeague); + } + + @Test + void testParticipants() throws Exception + { + Date testStart = new Date(1234567); + Date testRegistration = new Date(1234568); + Date testEnd = new Date(12345679); + Golfer testOwner = new Golfer("Bobby", "bobby123", "iloveswen262"); + ScrambleLeague testLeague = new ScrambleLeague("Bobby's Band", testRegistration, testStart, testEnd, testOwner); + Team testTeam = new Team("The A Team", testOwner); + + // add and remove participant + testLeague.addParticipants(testTeam); + assertEquals(testTeam, testLeague.getParticipants()[0]); + assertEquals(1, testLeague.getParticipants().length); + testLeague.removeParticipants(testTeam); + assertEquals(0, testLeague.getParticipants().length); + } + + @Test + void testLocateTeam() throws Exception + { + Date testStart = new Date(1234567); + Date testRegistration = new Date(1234568); + Date testEnd = new Date(12345679); + Golfer testOwner = new Golfer("Bobby", "bobby123", "iloveswen262"); + ScrambleLeague testLeague = new ScrambleLeague("Bobby's Band", testRegistration, testStart, testEnd, testOwner); + + Team testTeam = new Team("The A Team", testOwner); + Golfer teamMember = new Golfer("Jane Doe", "jane_doe", "weback"); + Golfer nonMember = new Golfer("NAN doe", "nan_doe", "wenotback"); + + // expect a result if member is part of team. expect null if they are not. + testTeam.addMember(teamMember); + testLeague.addParticipants(testTeam); + Team result = testLeague.locateTeam(teamMember); + assertEquals(result, testTeam); + result = testLeague.locateTeam(nonMember); + assertNull(result); + } +} diff --git a/src/test/java/design/model/StrokeLeagueTest.java b/src/test/java/design/model/StrokeLeagueTest.java index cc37887..8af7561 100644 --- a/src/test/java/design/model/StrokeLeagueTest.java +++ b/src/test/java/design/model/StrokeLeagueTest.java @@ -1,6 +1,5 @@ package design.model; -import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -14,7 +13,7 @@ import java.util.List; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; -/** Tests for the league model class. +/** Tests for the stroke league model class. * @author Willem Dalton */ @Tag("Model-tier") -- cgit v1.2.3 From cf3db9a7e13f7e919381cd2c8555ee31e3d50cf0 Mon Sep 17 00:00:00 2001 From: WillemDalton Date: Thu, 13 Nov 2025 17:56:52 -0500 Subject: completed unit testing for play class --- src/test/java/design/TestCourseList.java | 86 -------------------------------- src/test/java/design/model/TestPlay.java | 43 ++++++++++++++++ 2 files changed, 43 insertions(+), 86 deletions(-) delete mode 100644 src/test/java/design/TestCourseList.java create mode 100644 src/test/java/design/model/TestPlay.java (limited to 'src') diff --git a/src/test/java/design/TestCourseList.java b/src/test/java/design/TestCourseList.java deleted file mode 100644 index f943852..0000000 --- a/src/test/java/design/TestCourseList.java +++ /dev/null @@ -1,86 +0,0 @@ -// package design; - -// import static org.junit.jupiter.api.Assertions.assertEquals; -// import static org.junit.jupiter.api.Assertions.assertTrue; - -// import org.junit.jupiter.api.Test; -// import design.model.course_search.*; -// import design.model.*; - -// import java.util.List; - -// class TestCourseList { - -// // A dummy Course implementation for testing -// private static class DummyCourse implements ICourse { -// private final String name; -// private final float difficulty; - -// public DummyCourse(String name, float difficulty) { -// this.name = name; -// this.difficulty = difficulty; -// } - -// @Override -// public String getName() { return name; } - -// @Override -// public float getDifficultyRating() { return difficulty; } - -// @Override -// public String getLocation() { return ""; } - -// @Override -// public int getTotalPar() { return 0; } - -// @Override -// public int getHoleCount() { return 0; } - -// @Override -// public List getHoles() { return null; } -// } - -// // A simple sorter that sorts courses by difficulty -// private static class SortByDifficultyTest implements CourseSorter { -// @Override -// public void sortCourses(List courses) { -// courses.sort((c1, c2) -> Float.compare(c1.getDifficultyRating(), c2.getDifficultyRating())); -// } -// } - -// @Test -// public void testAddAndRemoveCourses() { -// CourseList courseList = new CourseList(); -// ICourse course1 = new DummyCourse("Course A", 2.0f); -// ICourse course2 = new DummyCourse("Course B", 5.0f); - -// courseList.add(course1); -// courseList.add(course2); - -// assertEquals(2, courseList.getCourses().size(), "Should have 2 courses after adding"); -// assertTrue(courseList.getCourses().contains(course1), "Course A should be in the list"); -// assertTrue(courseList.getCourses().contains(course2), "Course B should be in the list"); - -// courseList.remove(course1); -// assertEquals(1, courseList.getCourses().size(), "Should have 1 course after removal"); -// assertTrue(!courseList.getCourses().contains(course1), "Course A should no longer be in the list"); -// } - -// @Test -// public void testSortCourses() { -// CourseList courseList = new CourseList(); -// courseList.add(new DummyCourse("Course A", 3.0f)); -// courseList.add(new DummyCourse("Course B", 1.0f)); -// courseList.add(new DummyCourse("Course C", 2.0f)); - -// // Set sorting strategy -// courseList.setSorter(new SortByDifficultyTest()); - -// courseList.sort(); - -// List sorted = courseList.getCourses(); -// assertEquals("Course B", sorted.get(0).getName(), "First course should have lowest difficulty"); -// assertEquals("Course C", sorted.get(1).getName(), "Second course should have medium difficulty"); -// assertEquals("Course A", sorted.get(2).getName(), "Last course should have highest difficulty"); -// } -// } \ No newline at end of file diff --git a/src/test/java/design/model/TestPlay.java b/src/test/java/design/model/TestPlay.java new file mode 100644 index 0000000..c3282bf --- /dev/null +++ b/src/test/java/design/model/TestPlay.java @@ -0,0 +1,43 @@ +package design.model; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import design.model.Club.ClubType; + +import java.util.ArrayList; + +/** Unit Tests for the Play class. + * @author Willem Dalton + **/ +@Tag("Model-tier") +public class TestPlay { + @Test + void testConstructor() + { + Play testPlay = new Play(0); + assertEquals(0, testPlay.getHoleNumber()); + } + + @Test + void testConstructorNull() + { + Play testPlay2 = new Play(0, null); + assertEquals(0, testPlay2.getHoleNumber()); + assertEquals(0, testPlay2.getSwings().length); + } + + @Test + void testConstructorNotNull() + { + Club newClub = new Club("John Doe Inc", "The Slammer", ClubType.DRIVER); + Swing newSwing = new Swing(100, newClub); + ArrayList swings = new ArrayList(); + swings.add(newSwing); + Play testPlay3 = new Play(0, swings); + assertEquals(0, testPlay3.getHoleNumber()); + assertEquals(swings.get(0), testPlay3.getSwings()[0]); + } +} -- cgit v1.2.3 From 9adc51f8d74577b5c4ae9c1f88341252f2c22939 Mon Sep 17 00:00:00 2001 From: sowgro Date: Thu, 13 Nov 2025 20:05:25 -0500 Subject: export almost working --- .../userinput/menus/ImportExportMenu.java | 58 +++++++++---------- .../controller/userinput/menus/MainMenu.java | 3 +- .../controller/userinput/menus/UserSettings.java | 3 - src/main/java/design/model/DataHandler.java | 11 ---- src/main/java/design/persistence/JSONHandler.java | 28 --------- .../design/persistence/JSONLeagueDatabase.java | 21 ++++--- .../design/persistence/JSONPersonalDatabase.java | 27 ++++----- .../java/design/persistence/LeagueDatabase.java | 3 +- .../java/design/persistence/PersonalDatabase.java | 5 +- src/main/java/design/persistence/XMLHandler.java | 66 ---------------------- .../persistence/importexport/DataHandler.java | 11 ++++ .../persistence/importexport/DataSource.java | 12 ++++ .../persistence/importexport/JSONHandler.java | 30 ++++++++++ .../persistence/importexport/XMLHandler.java | 34 +++++++++++ 14 files changed, 145 insertions(+), 167 deletions(-) delete mode 100644 src/main/java/design/model/DataHandler.java delete mode 100644 src/main/java/design/persistence/JSONHandler.java delete mode 100644 src/main/java/design/persistence/XMLHandler.java create mode 100644 src/main/java/design/persistence/importexport/DataHandler.java create mode 100644 src/main/java/design/persistence/importexport/DataSource.java create mode 100644 src/main/java/design/persistence/importexport/JSONHandler.java create mode 100644 src/main/java/design/persistence/importexport/XMLHandler.java (limited to 'src') diff --git a/src/main/java/design/controller/userinput/menus/ImportExportMenu.java b/src/main/java/design/controller/userinput/menus/ImportExportMenu.java index dbad0e3..dda465f 100644 --- a/src/main/java/design/controller/userinput/menus/ImportExportMenu.java +++ b/src/main/java/design/controller/userinput/menus/ImportExportMenu.java @@ -2,22 +2,18 @@ package design.controller.userinput.menus; import design.controller.userinput.Menu; import design.controller.userinput.MenuOption; -import design.persistence.JSONHandler; -import design.persistence.XMLHandler; +import design.persistence.*; +import design.persistence.importexport.DataHandler; +import design.persistence.importexport.DataSource; +import design.persistence.importexport.JSONHandler; +import design.persistence.importexport.XMLHandler; import java.io.File; import java.io.IOException; import java.util.List; -import java.util.Map; import java.util.Scanner; -import design.model.DataHandler; - public class ImportExportMenu extends Menu { - private static final Map handlers = Map.of( - "xml", new XMLHandler(), - "json", new JSONHandler() - ); @Override public String getTitle() { @@ -31,46 +27,50 @@ public class ImportExportMenu extends Menu { opts.add(new MenuOption("return to main menu", () -> new MainMenu().present())); - opts.add(new MenuOption("import league...", () -> promptForPath(true, false))); - opts.add(new MenuOption("export league...", () -> promptForPath(false, false))); - opts.add(new MenuOption("import personal profile...", () -> promptForPath(true, true))); - opts.add(new MenuOption("export personal profile...", () -> promptForPath(false, true))); + opts.add(new MenuOption("import leagues...", () -> promptForPath(true, false))); + opts.add(new MenuOption("export leagues...", () -> promptForPath(false, false))); + opts.add(new MenuOption("import profiles...", () -> promptForPath(true, true))); + opts.add(new MenuOption("export profiles...", () -> promptForPath(false, true))); return opts; } private void promptForPath(boolean isImporting, boolean isPersonalProfile) { - System.out.println("Enter file path: "); + System.out.print("Enter file path: "); Scanner sc = new Scanner(System.in); String filePath = sc.nextLine(); File file = new File(filePath); - String ext = getExtension(filePath); - DataHandler handler = handlers.get(ext); + DataSource source; + if (isPersonalProfile) { + source = PersonalDatabase.instance(); + } else { + source = LeagueDatabase.instance(); + } - if (handler == null) { - System.out.println("Unsupported file type: " + ext); - return; + DataHandler handler; + String ext = getExtension(filePath); + switch (ext) { + case "json" -> handler = new JSONHandler(source); + case "xml" -> handler = new XMLHandler(source); + default -> { + System.out.println("Unsupported file type: " + ext); + return; + } } try { if (isImporting) { - if (isPersonalProfile) - handler.importPersonalData(file); - else - handler.importLeagueData(file); + handler.importData(file); } else { - if (isPersonalProfile) - handler.exportPersonalData(file); - else - handler.exportLeagueData(file); + handler.exportData(file); } } catch (IOException e) { - System.err.println("I/O error: " + e.getMessage()); + throw new RuntimeException(e); } - new ImportExportMenu().present(); + this.present(); } private static String getExtension(String fileName) { diff --git a/src/main/java/design/controller/userinput/menus/MainMenu.java b/src/main/java/design/controller/userinput/menus/MainMenu.java index 7522ceb..9d5204f 100644 --- a/src/main/java/design/controller/userinput/menus/MainMenu.java +++ b/src/main/java/design/controller/userinput/menus/MainMenu.java @@ -19,7 +19,8 @@ public class MainMenu extends Menu { new MenuOption("manage courses...", () -> new ManageCourses().present()), new MenuOption("manage clubs...", () -> new ManageClubs().present()), new MenuOption("statistics...", () -> new StatisticsMenu().present()), - new MenuOption("log round...", () -> new HolePlayMenu().present()) + new MenuOption("log round...", () -> new HolePlayMenu().present()), + new MenuOption("manage data...", () -> new ImportExportMenu().present()) ); } } diff --git a/src/main/java/design/controller/userinput/menus/UserSettings.java b/src/main/java/design/controller/userinput/menus/UserSettings.java index 865b00d..47b0a5b 100644 --- a/src/main/java/design/controller/userinput/menus/UserSettings.java +++ b/src/main/java/design/controller/userinput/menus/UserSettings.java @@ -60,9 +60,6 @@ public class UserSettings extends Menu { this.present(); })); - opts.add(new MenuOption("manage data...", () -> new ImportExportMenu().present())); - - return opts; } } diff --git a/src/main/java/design/model/DataHandler.java b/src/main/java/design/model/DataHandler.java deleted file mode 100644 index e7dda33..0000000 --- a/src/main/java/design/model/DataHandler.java +++ /dev/null @@ -1,11 +0,0 @@ -package design.model; - -import java.io.File; -import java.io.IOException; - -public interface DataHandler { - void importPersonalData(File file) throws IOException; - void exportPersonalData(File file) throws IOException; - void importLeagueData(File file) throws IOException; - void exportLeagueData(File file) throws IOException; -} \ No newline at end of file diff --git a/src/main/java/design/persistence/JSONHandler.java b/src/main/java/design/persistence/JSONHandler.java deleted file mode 100644 index 77ec987..0000000 --- a/src/main/java/design/persistence/JSONHandler.java +++ /dev/null @@ -1,28 +0,0 @@ -package design.persistence; -import java.io.File; -import java.io.IOException; -import design.model.DataHandler; - -public class JSONHandler implements DataHandler -{ - - public void exportPersonalData(File file) throws IOException { - JSONPersonalDatabase.instance().exportData(file); - } - - public void importPersonalData(File file) throws IOException { - JSONPersonalDatabase.instance().importData(file); - } - - public void exportLeagueData(File file) throws IOException - { - JSONLeagueDatabase.instance().importData(file); - } - - public void importLeagueData(File file) throws IOException - { - JSONLeagueDatabase.instance().exportData(file); - } -} - - diff --git a/src/main/java/design/persistence/JSONLeagueDatabase.java b/src/main/java/design/persistence/JSONLeagueDatabase.java index edc649b..795c582 100644 --- a/src/main/java/design/persistence/JSONLeagueDatabase.java +++ b/src/main/java/design/persistence/JSONLeagueDatabase.java @@ -13,8 +13,6 @@ import design.model.League; import java.io.File; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.StandardCopyOption; import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -100,18 +98,19 @@ public class JSONLeagueDatabase implements LeagueDatabase { save(); } - public File exportData(File newFile) throws IOException{ - Files.copy(file.toPath(), newFile.toPath(), StandardCopyOption.REPLACE_EXISTING); - return newFile; - } - - public void importData(File newFile) throws IOException { - League[] newLeagues = mapper.readValue(newFile, League[].class); + @Override + public void importData(JsonNode tree) throws IOException { + League[] data = mapper.treeToValue(tree, League[].class); cache.clear(); - for (League l: newLeagues) { - cache.put(l.getId(), l); + for (League league : data) { + cache.put(league.getId(), league); } save(); } + @Override + public JsonNode exportData() { + Object[] data = cache.values().toArray(); + return mapper.valueToTree(data); + } } diff --git a/src/main/java/design/persistence/JSONPersonalDatabase.java b/src/main/java/design/persistence/JSONPersonalDatabase.java index 3fc5cab..3e70629 100644 --- a/src/main/java/design/persistence/JSONPersonalDatabase.java +++ b/src/main/java/design/persistence/JSONPersonalDatabase.java @@ -13,8 +13,6 @@ import design.model.League; import java.io.File; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.StandardCopyOption; import java.util.HashMap; import java.util.Map; @@ -38,9 +36,6 @@ public class JSONPersonalDatabase implements PersonalDatabase { this.cache = new HashMap<>(); this.mapper = new ObjectMapper(); - // TODO: Once the saved JSON matches the model, consider removing. - // TEMP: tolerate unknown props while the model stabilizes - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); SimpleModule module = new SimpleModule(); module.addDeserializer(Course.class, new Serializers.CourseIdDeserializer()); @@ -48,6 +43,7 @@ public class JSONPersonalDatabase implements PersonalDatabase { module.addSerializer(League.class, new Serializers.LeagueIDSerializer()); module.addDeserializer(League.class, new Serializers.LeagueIDDeserializer()); mapper.registerModule(module); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); mapper.registerModule(new ParameterNamesModule(JsonCreator.Mode.PROPERTIES)); mapper.registerModule(new JavaTimeModule()); @@ -101,18 +97,19 @@ public class JSONPersonalDatabase implements PersonalDatabase { save(); } - - public File exportData(File newFile) throws IOException{ - Files.copy(file.toPath(), newFile.toPath(), StandardCopyOption.REPLACE_EXISTING); - return newFile; - } - - public void importData(File newFile) throws IOException { - Golfer[] newGolfers = mapper.readValue(newFile, Golfer[].class); + @Override + public void importData(JsonNode tree) throws IOException { + Golfer[] data = mapper.treeToValue(tree, Golfer[].class); cache.clear(); - for (Golfer g : newGolfers) { - cache.put(g.getUsername(), g); + for (Golfer golfer : data) { + cache.put(golfer.getUsername(), golfer); } save(); } + + @Override + public JsonNode exportData() { + Object[] data = cache.values().toArray(); + return mapper.valueToTree(data); + } } diff --git a/src/main/java/design/persistence/LeagueDatabase.java b/src/main/java/design/persistence/LeagueDatabase.java index 953624d..9f835ff 100644 --- a/src/main/java/design/persistence/LeagueDatabase.java +++ b/src/main/java/design/persistence/LeagueDatabase.java @@ -1,10 +1,11 @@ package design.persistence; import design.model.League; +import design.persistence.importexport.DataSource; import java.io.IOException; -public interface LeagueDatabase { +public interface LeagueDatabase extends DataSource { static LeagueDatabase instance() { return JSONLeagueDatabase.instance(); } diff --git a/src/main/java/design/persistence/PersonalDatabase.java b/src/main/java/design/persistence/PersonalDatabase.java index 63f9182..77e43cc 100644 --- a/src/main/java/design/persistence/PersonalDatabase.java +++ b/src/main/java/design/persistence/PersonalDatabase.java @@ -1,10 +1,11 @@ package design.persistence; import design.model.Golfer; +import design.persistence.importexport.DataSource; + import java.io.IOException; -import java.io.File; -public interface PersonalDatabase { +public interface PersonalDatabase extends DataSource { static PersonalDatabase instance() { return JSONPersonalDatabase.instance(); diff --git a/src/main/java/design/persistence/XMLHandler.java b/src/main/java/design/persistence/XMLHandler.java deleted file mode 100644 index 706dabd..0000000 --- a/src/main/java/design/persistence/XMLHandler.java +++ /dev/null @@ -1,66 +0,0 @@ -package design.persistence; -import java.io.File; -import java.io.IOException; -import design.model.DataHandler; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; - -import design.model.Golfer; -import com.fasterxml.jackson.dataformat.xml.XmlMapper; - - - -public class XMLHandler implements DataHandler -{ - private final ObjectMapper jsonMapper = new ObjectMapper(); - private final XmlMapper xmlMapper = new XmlMapper(); - - public void exportPersonalData(File file) throws IOException { - // get our json data just from the JSON database - File jsonData = JSONPersonalDatabase.instance().exportData(file); - - // read the the data from the JSON, as a JsonNode. - JsonNode golfersNode = jsonMapper.readTree(jsonData); - - // XML requires a parent node, we can't just throw the golfersnode into the xml or else it will only produce the first element - ObjectNode root = xmlMapper.createObjectNode(); - root.set("golfer", golfersNode); - - //write to the xml file. - xmlMapper.writerWithDefaultPrettyPrinter().writeValue(file, root); - } - - public void importPersonalData(File file) throws IOException { - - // read our root, the object node - JsonNode root = xmlMapper.readTree(file); - - // debug print line - System.out.println(root.toPrettyString()); - - // !!! here is where it's failing...our root is not serializable to an array of golfers. !!! - Golfer[] golfers = xmlMapper.treeToValue(root, Golfer[].class); - - // from here out should be good - File tempJson = File.createTempFile("imported", ".json"); - jsonMapper.writerWithDefaultPrettyPrinter().writeValue(tempJson, golfers); - JSONPersonalDatabase.instance().importData(tempJson); - tempJson.delete(); - } - - - - public void exportLeagueData(File file) throws IOException - { - // TO DO: exporting league data - } - - public void importLeagueData(File file) throws IOException - { - // TO DO: importing league data - } -} - - diff --git a/src/main/java/design/persistence/importexport/DataHandler.java b/src/main/java/design/persistence/importexport/DataHandler.java new file mode 100644 index 0000000..59df9be --- /dev/null +++ b/src/main/java/design/persistence/importexport/DataHandler.java @@ -0,0 +1,11 @@ +package design.persistence.importexport; + +import java.io.File; +import java.io.IOException; + +public interface DataHandler { + + void importData(File file) throws IOException; + + void exportData(File file) throws IOException; +} diff --git a/src/main/java/design/persistence/importexport/DataSource.java b/src/main/java/design/persistence/importexport/DataSource.java new file mode 100644 index 0000000..5290e33 --- /dev/null +++ b/src/main/java/design/persistence/importexport/DataSource.java @@ -0,0 +1,12 @@ +package design.persistence.importexport; + +import com.fasterxml.jackson.databind.JsonNode; + +import java.io.IOException; + +public interface DataSource { + + void importData(JsonNode tree) throws IOException; + + JsonNode exportData() throws IOException; +} \ No newline at end of file diff --git a/src/main/java/design/persistence/importexport/JSONHandler.java b/src/main/java/design/persistence/importexport/JSONHandler.java new file mode 100644 index 0000000..239eb6b --- /dev/null +++ b/src/main/java/design/persistence/importexport/JSONHandler.java @@ -0,0 +1,30 @@ +package design.persistence.importexport; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.json.JsonMapper; + +import java.io.File; +import java.io.IOException; + +public class JSONHandler implements DataHandler { + + private final DataSource dataSource; + private final JsonMapper jsonMapper = new JsonMapper(); + + public JSONHandler(DataSource dataSource) { + this.dataSource = dataSource; + } + + @Override + public void importData(File file) throws IOException { + JsonNode tree = jsonMapper.readTree(file); + dataSource.importData(tree); + } + + @Override + public void exportData(File file) throws IOException{ + JsonNode tree = dataSource.exportData(); + jsonMapper.writerWithDefaultPrettyPrinter().writeValue(file, tree); + } +} + + diff --git a/src/main/java/design/persistence/importexport/XMLHandler.java b/src/main/java/design/persistence/importexport/XMLHandler.java new file mode 100644 index 0000000..1a16b90 --- /dev/null +++ b/src/main/java/design/persistence/importexport/XMLHandler.java @@ -0,0 +1,34 @@ +package design.persistence.importexport; +import java.io.File; +import java.io.IOException; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.fasterxml.jackson.dataformat.xml.XmlMapper; + +public class XMLHandler implements DataHandler { + + private final DataSource dataSource; + private final XmlMapper xmlMapper = new XmlMapper(); + + public XMLHandler(DataSource dataSource) { + this.dataSource = dataSource; + } + + @Override + public void importData(File file) throws IOException { + JsonNode tree = xmlMapper.readTree(file); + JsonNode unwrapped = tree.get("items"); + dataSource.importData(unwrapped); + } + + @Override + public void exportData(File file) throws IOException { + JsonNode tree = dataSource.exportData(); + ObjectNode wrapper = xmlMapper.createObjectNode(); + wrapper.set("items", tree); + xmlMapper.writerWithDefaultPrettyPrinter().withRootName("export").writeValue(file, wrapper); + } +} + + -- cgit v1.2.3 From dd60732c456a6e0851f8b2f8e24600cc9eed77d0 Mon Sep 17 00:00:00 2001 From: WillemDalton Date: Fri, 14 Nov 2025 12:27:53 -0500 Subject: finished unit testing for teams and matches --- src/main/java/design/model/Golfer.java | 2 +- src/test/InviteTest.java | 0 src/test/java/design/model/GolferTest.java | 11 ++++++ src/test/java/design/model/MatchTest.java | 59 ++++++++++++++++++++++++++++++ src/test/java/design/model/PlayTest.java | 43 ++++++++++++++++++++++ src/test/java/design/model/TeamTest.java | 42 +++++++++++++++++++++ src/test/java/design/model/TestPlay.java | 43 ---------------------- 7 files changed, 156 insertions(+), 44 deletions(-) create mode 100644 src/test/InviteTest.java create mode 100644 src/test/java/design/model/MatchTest.java create mode 100644 src/test/java/design/model/PlayTest.java create mode 100644 src/test/java/design/model/TeamTest.java delete mode 100644 src/test/java/design/model/TestPlay.java (limited to 'src') diff --git a/src/main/java/design/model/Golfer.java b/src/main/java/design/model/Golfer.java index 870b460..6ea9d32 100644 --- a/src/main/java/design/model/Golfer.java +++ b/src/main/java/design/model/Golfer.java @@ -160,5 +160,5 @@ public class Golfer implements Originator { this.clubs.addAll(gm.clubs); this.nextClubId = gm.nextClubId; - } + } } diff --git a/src/test/InviteTest.java b/src/test/InviteTest.java new file mode 100644 index 0000000..e69de29 diff --git a/src/test/java/design/model/GolferTest.java b/src/test/java/design/model/GolferTest.java index 65229f3..5f113ab 100644 --- a/src/test/java/design/model/GolferTest.java +++ b/src/test/java/design/model/GolferTest.java @@ -10,6 +10,7 @@ import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import design.model.Club.ClubType; +import design.model.undo.Memento; import java.lang.reflect.Constructor; import java.time.LocalDateTime; @@ -137,6 +138,16 @@ public class GolferTest { assertEquals(expectedString, testGolfer.toString()); } + @Test + void testMemento() + { + Golfer testGolfer = new Golfer("John Doe", "jdoesgolf2", "weback4321"); + Memento memento = testGolfer.createMemento(); + testGolfer.setFullName("Joe Doe"); + assertEquals("Joe Doe", testGolfer.getFullName()); + testGolfer.restore(memento); + assertEquals("John Doe", testGolfer.getFullName()); + } } diff --git a/src/test/java/design/model/MatchTest.java b/src/test/java/design/model/MatchTest.java new file mode 100644 index 0000000..9058218 --- /dev/null +++ b/src/test/java/design/model/MatchTest.java @@ -0,0 +1,59 @@ +package design.model; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; +import java.lang.reflect.Constructor; +import java.lang.reflect.Modifier; +import java.util.Date; +import java.time.LocalDateTime; + +/** Unit Tests for the Match class. + * @author Willem Dalton + **/ +@Tag("Model-tier") +public class MatchTest { + + @Test + void testConstructor() + { + Course testCourse = new Course(0, "Rolling Waves", 67, "Rochester. NY", 9, 30, new ArrayList()); + Date testDate = new Date(1234567); + LocalDateTime now = LocalDateTime.now(); + Match testMatch = new Match(testCourse, testDate, now, 9); + assertEquals(testCourse, testMatch.getCourse()); + assertEquals(testDate, testMatch.getDateScheduled()); + assertEquals(now, testMatch.getStart()); + assertEquals(9, testMatch.getHoleCount()); + } + + @Test + void testPrivateConstructor() throws Exception + { + Course testCourse = new Course(0, "Rolling Waves", 67, "Rochester. NY", 9, 30, new ArrayList()); + Constructor constructor = Match.class.getDeclaredConstructor(Course.class, Date.class, LocalDateTime.class, int.class, List.class); + assertTrue(Modifier.isPrivate(constructor.getModifiers())); + constructor.setAccessible(true); + Match testMatch = constructor.newInstance(testCourse, new Date(1234), LocalDateTime.now(), 0, new ArrayList<>()); + assertNotNull(testMatch); + } + + @Test + void testAddRound() + { + Course testCourse = new Course(0, "Rolling Waves", 67, "Rochester. NY", 9, 30, new ArrayList()); + Date testDate = new Date(1234567); + LocalDateTime now = LocalDateTime.now(); + Match testMatch = new Match(testCourse, testDate, now, 9); + Round testRound = new Round(testCourse, now, new Hole(0, 5)); + testMatch.addRound(testRound); + assertEquals(testRound, testMatch.getRounds()[0]); + assertEquals(1, testMatch.getRounds().length); + } +} diff --git a/src/test/java/design/model/PlayTest.java b/src/test/java/design/model/PlayTest.java new file mode 100644 index 0000000..0a27076 --- /dev/null +++ b/src/test/java/design/model/PlayTest.java @@ -0,0 +1,43 @@ +package design.model; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import design.model.Club.ClubType; + +import java.util.ArrayList; + +/** Unit Tests for the Play class. + * @author Willem Dalton + **/ +@Tag("Model-tier") +public class PlayTest { + @Test + void testConstructor() + { + Play testPlay = new Play(0); + assertEquals(0, testPlay.getHoleNumber()); + } + + @Test + void testConstructorNull() + { + Play testPlay2 = new Play(0, null); + assertEquals(0, testPlay2.getHoleNumber()); + assertEquals(0, testPlay2.getSwings().length); + } + + @Test + void testConstructorNotNull() + { + Club newClub = new Club("John Doe Inc", "The Slammer", ClubType.DRIVER); + Swing newSwing = new Swing(100, newClub); + ArrayList swings = new ArrayList(); + swings.add(newSwing); + Play testPlay3 = new Play(0, swings); + assertEquals(0, testPlay3.getHoleNumber()); + assertEquals(swings.get(0), testPlay3.getSwings()[0]); + } +} diff --git a/src/test/java/design/model/TeamTest.java b/src/test/java/design/model/TeamTest.java new file mode 100644 index 0000000..c81aa1e --- /dev/null +++ b/src/test/java/design/model/TeamTest.java @@ -0,0 +1,42 @@ +package design.model; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +/** Unit Tests for the Team Class. + * @author Willem Dalton + **/ +@Tag("Model-tier") +public class TeamTest { + @Test + void testConstructor() + { + Golfer testGolfer = new Golfer("John Doe", "j_doe_golfs", "ilovegolf123"); + Team testTeam = new Team("A Team", testGolfer); + assertEquals("A Team", testTeam.getName()); + assertEquals(testGolfer, testTeam.getOwner()); + } + + @Test + void testSetName() + { + Golfer testGolfer = new Golfer("John Doe", "j_doe_golfs", "ilovegolf123"); + Team testTeam = new Team("A Team", testGolfer); + testTeam.setName("B Team"); + assertEquals("B Team", testTeam.getName()); + } + + @Test + void testRemoveMember() + { + Golfer testGolfer = new Golfer("John Doe", "j_doe_golfs", "ilovegolf123"); + Golfer newGolfer = new Golfer("Jane Doe", "j_doe_golfs2", "ilovegolf321"); + Team testTeam = new Team("A Team", testGolfer); + testTeam.addMember(newGolfer); + assertEquals(1, testTeam.getMembers().length); + testTeam.removeMember(newGolfer); + assertEquals(0, testTeam.getMembers().length); + } +} diff --git a/src/test/java/design/model/TestPlay.java b/src/test/java/design/model/TestPlay.java deleted file mode 100644 index c3282bf..0000000 --- a/src/test/java/design/model/TestPlay.java +++ /dev/null @@ -1,43 +0,0 @@ -package design.model; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -import design.model.Club.ClubType; - -import java.util.ArrayList; - -/** Unit Tests for the Play class. - * @author Willem Dalton - **/ -@Tag("Model-tier") -public class TestPlay { - @Test - void testConstructor() - { - Play testPlay = new Play(0); - assertEquals(0, testPlay.getHoleNumber()); - } - - @Test - void testConstructorNull() - { - Play testPlay2 = new Play(0, null); - assertEquals(0, testPlay2.getHoleNumber()); - assertEquals(0, testPlay2.getSwings().length); - } - - @Test - void testConstructorNotNull() - { - Club newClub = new Club("John Doe Inc", "The Slammer", ClubType.DRIVER); - Swing newSwing = new Swing(100, newClub); - ArrayList swings = new ArrayList(); - swings.add(newSwing); - Play testPlay3 = new Play(0, swings); - assertEquals(0, testPlay3.getHoleNumber()); - assertEquals(swings.get(0), testPlay3.getSwings()[0]); - } -} -- cgit v1.2.3 From e7b18c044ff58001c8ac193c62ea692cb7d43505 Mon Sep 17 00:00:00 2001 From: WillemDalton Date: Fri, 14 Nov 2025 12:49:00 -0500 Subject: completed courselist testing --- src/test/InviteTest.java | 0 src/test/java/design/model/InviteTest.java | 37 +++++++++++++ .../design/model/coursesearch/CourseListTest.java | 60 +++++++++++++++++++++- .../model/coursesearch/sortStrategyTest.java | 11 ++-- 4 files changed, 101 insertions(+), 7 deletions(-) delete mode 100644 src/test/InviteTest.java create mode 100644 src/test/java/design/model/InviteTest.java (limited to 'src') diff --git a/src/test/InviteTest.java b/src/test/InviteTest.java deleted file mode 100644 index e69de29..0000000 diff --git a/src/test/java/design/model/InviteTest.java b/src/test/java/design/model/InviteTest.java new file mode 100644 index 0000000..a71271d --- /dev/null +++ b/src/test/java/design/model/InviteTest.java @@ -0,0 +1,37 @@ +package design.model; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import java.util.Date; + +/** Unit Tests for the Invite Class. + * @author Willem Dalton + **/ +public class InviteTest { + @Test + void testConstructor() + { + Golfer testOwner = new Golfer("Jane Doe", "j_doe_rocks", "1234"); + Team testTeam = new Team("A Team", testOwner); + Date testDate = new Date(123456); + Invite testInvite = new Invite(testTeam, testDate); + + assertEquals(testTeam, testInvite.getTeam()); + assertEquals(testDate, testInvite.getSendDate()); + } + + @Test + void testAccept() + { + Golfer testOwner = new Golfer("Jane Doe", "j_doe_rocks", "1234"); + Golfer testInvitee = new Golfer("James Doe", "j_doe_is_cool", "54321"); + Team testTeam = new Team("A Team", testOwner); + Date testDate = new Date(123456); + Invite testInvite = new Invite(testTeam, testDate); + testInvite.accept(testInvitee); + assertEquals(testInvitee, testTeam.getMembers()[0]); + } +} diff --git a/src/test/java/design/model/coursesearch/CourseListTest.java b/src/test/java/design/model/coursesearch/CourseListTest.java index 7538ba5..5969486 100644 --- a/src/test/java/design/model/coursesearch/CourseListTest.java +++ b/src/test/java/design/model/coursesearch/CourseListTest.java @@ -1,12 +1,13 @@ package design.model.coursesearch; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import java.util.ArrayList; +import design.model.course_search.ICourse; import design.model.course_search.*; import design.model.Course; @@ -22,6 +23,61 @@ public class CourseListTest { void testConstructor() { CourseList testList = new CourseList(); + assertNotNull(testList); + } + + @Test + void testSetCourses() + { + CourseList testList = new CourseList(); + Course testCourse1 = new Course(0, "Rolling Waves", 10, "Rochester, NY", 0, 0, null); + Course testCourse2 = new Course(1, "Arcadia Hills", 10, "Rochester, NY", 0, 0, null); + ArrayList courses = new ArrayList(); + courses.add(testCourse1); + courses.add(testCourse2); + testList.setCourses(courses); + assertEquals(courses, testList.getCourses()); + } + @Test + void testSort() + { + CourseList testList = new CourseList(); + Course testCourse1 = new Course(0, "Rolling Waves", 10, "Rochester, NY", 0, 0, null); + Course testCourse2 = new Course(1, "Arcadia Hills", 10, "Rochester, NY", 0, 0, null); + ArrayList courses = new ArrayList(); + courses.add(testCourse1); + courses.add(testCourse2); + testList.setCourses(courses); + SortByName sorter = new SortByName(); + testList.setSorter(sorter); + testList.sort(); + assertEquals(testCourse2, testList.getCourses().get(0)); + assertEquals(testCourse1, testList.getCourses().get(1)); + } + + @Test + void testAddRemove() + { + CourseList testList = new CourseList(); + Course testCourse1 = new Course(0, "Rolling Waves", 10, "Rochester, NY", 0, 0, null); + testList.add(testCourse1); + assertEquals(testCourse1, testList.getCourses().get(0)); + assertEquals(1, testList.getCourses().size()); + testList.remove(testCourse1); + assertEquals(0, testList.getCourses().size()); + } + + @Test + void testOverrides() + { + CourseList testList = new CourseList(); + assertEquals("Course List", testList.getName()); + assertEquals("Course List", testList.toString()); + assertEquals(0, testList.getDifficultyRating()); + assertEquals("", testList.getLocation()); + assertEquals(0, testList.getTotalPar()); + assertEquals(0, testList.getHoleCount()); + assertNull(testList.getHoles()); } } diff --git a/src/test/java/design/model/coursesearch/sortStrategyTest.java b/src/test/java/design/model/coursesearch/sortStrategyTest.java index aecbeff..60a8735 100644 --- a/src/test/java/design/model/coursesearch/sortStrategyTest.java +++ b/src/test/java/design/model/coursesearch/sortStrategyTest.java @@ -14,6 +14,7 @@ import design.model.Course; /** Unit Tests for the Difficulty Sorter class * @author Willem Dalton **/ +@Tag("Model-tier") public class sortStrategyTest { Course test1 = new Course(0, "Rolling Waves", 67, "Rochester, NY", 9, 30, null); @@ -25,7 +26,7 @@ public class sortStrategyTest { void testDifficultySort() { SortByDifficulty sorter = new SortByDifficulty(); - ArrayList courses = new ArrayList(); + ArrayList courses = new ArrayList(); courses.add(test1); courses.add(test2); sorter.sortCourses(courses); @@ -38,7 +39,7 @@ public class sortStrategyTest { void testNameSort() { SortByName sorter = new SortByName(); - ArrayList courses = new ArrayList(); + ArrayList courses = new ArrayList(); courses.add(test1); courses.add(test4); sorter.sortCourses(courses); @@ -51,7 +52,7 @@ public class sortStrategyTest { void testLocationSort() { SortByLocation sorter = new SortByLocation(); - ArrayList courses = new ArrayList(); + ArrayList courses = new ArrayList(); courses.add(test1); courses.add(test4); sorter.sortCourses(courses); @@ -64,7 +65,7 @@ public class sortStrategyTest { void testParSort() { SortByPar sorter = new SortByPar(); - ArrayList courses = new ArrayList(); + ArrayList courses = new ArrayList(); courses.add(test1); courses.add(test4); sorter.sortCourses(courses); @@ -77,7 +78,7 @@ public class sortStrategyTest { void testHoleSort() { SortByHoles sorter = new SortByHoles(); - ArrayList courses = new ArrayList(); + ArrayList courses = new ArrayList(); courses.add(test1); courses.add(test4); sorter.sortCourses(courses); -- cgit v1.2.3 From d2b35ee84843dc74afce87c3fb8b7e5a53cd56a7 Mon Sep 17 00:00:00 2001 From: WillemDalton Date: Fri, 14 Nov 2025 13:15:12 -0500 Subject: finished testing most of JSON personal database --- .../design/persistence/JSONPersonalDatabase.java | 5 ++ .../design/model/coursesearch/CourseListTest.java | 2 +- .../model/coursesearch/CurrentSearchQueryTest.java | 27 ++++++++++ .../model/coursesearch/sortStrategyTest.java | 4 +- .../persistence/JSONPersonalDatabaseTest.java | 63 ++++++++++++++++++++++ 5 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 src/test/java/design/model/coursesearch/CurrentSearchQueryTest.java create mode 100644 src/test/java/design/persistence/JSONPersonalDatabaseTest.java (limited to 'src') diff --git a/src/main/java/design/persistence/JSONPersonalDatabase.java b/src/main/java/design/persistence/JSONPersonalDatabase.java index 30c280a..ed83ef6 100644 --- a/src/main/java/design/persistence/JSONPersonalDatabase.java +++ b/src/main/java/design/persistence/JSONPersonalDatabase.java @@ -29,6 +29,11 @@ public class JSONPersonalDatabase implements PersonalDatabase { return INSTANCE; } + static JSONPersonalDatabase testInstance(String filename) { + INSTANCE = new JSONPersonalDatabase(filename); + return INSTANCE; + } + private final Map cache; private final ObjectMapper mapper; private final File file; diff --git a/src/test/java/design/model/coursesearch/CourseListTest.java b/src/test/java/design/model/coursesearch/CourseListTest.java index 5969486..6bc5529 100644 --- a/src/test/java/design/model/coursesearch/CourseListTest.java +++ b/src/test/java/design/model/coursesearch/CourseListTest.java @@ -13,7 +13,7 @@ import design.model.course_search.*; import design.model.Course; -/** Unit Tests for the Club class. +/** Unit Tests for the Course List class. * @author Willem Dalton **/ @Tag("Model-tier") diff --git a/src/test/java/design/model/coursesearch/CurrentSearchQueryTest.java b/src/test/java/design/model/coursesearch/CurrentSearchQueryTest.java new file mode 100644 index 0000000..10f3f87 --- /dev/null +++ b/src/test/java/design/model/coursesearch/CurrentSearchQueryTest.java @@ -0,0 +1,27 @@ +package design.model.coursesearch; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import java.util.ArrayList; + +import design.model.course_search.*; +import design.model.Course; + +/** Unit Tests for the Current Search Query Class + * @author Willem Dalton + **/ +@Tag("Model-tier") +public class CurrentSearchQueryTest { + + // @Test + // void testReset() + // { + // CurrentSearchQuery query + // } + + +} diff --git a/src/test/java/design/model/coursesearch/sortStrategyTest.java b/src/test/java/design/model/coursesearch/sortStrategyTest.java index 60a8735..35fa335 100644 --- a/src/test/java/design/model/coursesearch/sortStrategyTest.java +++ b/src/test/java/design/model/coursesearch/sortStrategyTest.java @@ -11,11 +11,11 @@ import java.util.ArrayList; import design.model.course_search.*; import design.model.Course; -/** Unit Tests for the Difficulty Sorter class +/** Unit Tests for the Sorter Strategy classes * @author Willem Dalton **/ @Tag("Model-tier") -public class sortStrategyTest { +public class SortStrategyTest { Course test1 = new Course(0, "Rolling Waves", 67, "Rochester, NY", 9, 30, null); Course test2 = new Course(1, "Balls in the Rough", 60, "Buffalo, NY", 18, 60, null); diff --git a/src/test/java/design/persistence/JSONPersonalDatabaseTest.java b/src/test/java/design/persistence/JSONPersonalDatabaseTest.java new file mode 100644 index 0000000..55270c4 --- /dev/null +++ b/src/test/java/design/persistence/JSONPersonalDatabaseTest.java @@ -0,0 +1,63 @@ +package design.persistence; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import design.model.Golfer; + +/** Unit Tests for the JSON Personal Database Singleton + * @author Willem Dalton + **/ +@Tag("Persistence-tier") +public class JSONPersonalDatabaseTest { + Path tempDB; + + @BeforeEach + void clearDB() throws IOException + { + tempDB = Files.createTempFile("testdb", ".json"); + Files.writeString(tempDB, "[]"); + JSONPersonalDatabase.testInstance(tempDB.toString()); + } + + @Test + void testInstance() + { + JSONPersonalDatabase instance = JSONPersonalDatabase.instance(); // makes new instance + assertNotNull(instance); + JSONPersonalDatabase instance2 = JSONPersonalDatabase.instance(); // instance already exists + assertNotNull(instance2); + } + + @Test + void testAddRemove() throws IOException + { + JSONPersonalDatabase instance = JSONPersonalDatabase.testInstance(tempDB.toString()); // makes new instance + Golfer testGolfer = new Golfer("Jamie Doe", "joe_cool", "12345"); + instance.addGolfer(testGolfer); + assertEquals(testGolfer, instance.getGolfer("joe_cool")); + instance.removeGolfer(testGolfer); + assertEquals(null, instance.getGolfer("joe_cool")); + } + + @Test + void testUpdateGolfer() throws IOException + { + JSONPersonalDatabase instance = JSONPersonalDatabase.testInstance(tempDB.toString()); // makes new instance + Golfer testGolfer = new Golfer("Jamie Doe", "joe_cool", "12345"); + instance.addGolfer(testGolfer); + testGolfer.setUsername("joe_super_cool"); + instance.updateGolfer(testGolfer); + assertEquals(testGolfer, instance.getGolfer("joe_super_cool")); + } +} -- cgit v1.2.3 From c052f5cb104ff5d4599161cf5fad95545c3be957 Mon Sep 17 00:00:00 2001 From: WillemDalton Date: Fri, 14 Nov 2025 13:36:42 -0500 Subject: progress on league database testing --- .../design/persistence/JSONLeagueDatabase.java | 6 ++ .../design/persistence/JSONPersonalDatabase.java | 1 + .../design/persistence/JSONLeagueDatabaseTest.java | 67 ++++++++++++++++++++++ .../persistence/JSONPersonalDatabaseTest.java | 1 - 4 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 src/test/java/design/persistence/JSONLeagueDatabaseTest.java (limited to 'src') diff --git a/src/main/java/design/persistence/JSONLeagueDatabase.java b/src/main/java/design/persistence/JSONLeagueDatabase.java index 8a55065..42fa000 100644 --- a/src/main/java/design/persistence/JSONLeagueDatabase.java +++ b/src/main/java/design/persistence/JSONLeagueDatabase.java @@ -30,6 +30,12 @@ public class JSONLeagueDatabase implements LeagueDatabase { return INSTANCE; } + // static instance strictly for testing, to not add data to leaguedb.json + static JSONLeagueDatabase testInstance(String filename) { + INSTANCE = new JSONLeagueDatabase(filename); + return INSTANCE; + } + private final Map cache; private final ObjectMapper mapper; private final File file; diff --git a/src/main/java/design/persistence/JSONPersonalDatabase.java b/src/main/java/design/persistence/JSONPersonalDatabase.java index ed83ef6..7f55f78 100644 --- a/src/main/java/design/persistence/JSONPersonalDatabase.java +++ b/src/main/java/design/persistence/JSONPersonalDatabase.java @@ -29,6 +29,7 @@ public class JSONPersonalDatabase implements PersonalDatabase { return INSTANCE; } + // static instance strictly for testing, to not add data to personaldb.json static JSONPersonalDatabase testInstance(String filename) { INSTANCE = new JSONPersonalDatabase(filename); return INSTANCE; diff --git a/src/test/java/design/persistence/JSONLeagueDatabaseTest.java b/src/test/java/design/persistence/JSONLeagueDatabaseTest.java new file mode 100644 index 0000000..1dcdbb1 --- /dev/null +++ b/src/test/java/design/persistence/JSONLeagueDatabaseTest.java @@ -0,0 +1,67 @@ +package design.persistence; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Date; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import design.model.League; +import design.model.StrokeLeague; +import design.model.Golfer; + +/** Unit Tests for the JSON Personal Database Singleton + * @author Willem Dalton + **/ +@Tag("Persistence-tier") +public class JSONLeagueDatabaseTest { + Path tempDB; + + @BeforeEach + void clearDB() throws IOException + { + tempDB = Files.createTempFile("testleaguedb", ".json"); + Files.writeString(tempDB, "[]"); + JSONLeagueDatabase.testInstance(tempDB.toString()); + } + + @Test + void testInstance() + { + JSONLeagueDatabase instance = JSONLeagueDatabase.instance(); // makes new instance + assertNotNull(instance); + JSONLeagueDatabase instance2 = JSONLeagueDatabase.instance(); // instance already exists + assertNotNull(instance2); + } + + @Test + void testAddRemove() throws IOException + { + JSONLeagueDatabase instance = JSONLeagueDatabase.testInstance(tempDB.toString()); // makes new instance + Golfer testOwner = new Golfer("Jamie Doe", "joe_cool", "12345"); + League testLeague = new StrokeLeague("The A Team", new Date(1234), new Date(123), new Date(12345), testOwner); + instance.addLeague(testLeague); + assertEquals(1, instance.getLeagues().length); + assertEquals(testLeague, instance.getLeagues()[0]); + instance.removeLeague(testLeague); + assertEquals(0, instance.getLeagues().length); + } + + // @Test + // void testUpdateGolfer() throws IOException + // { + // JSONLeagueDatabase instance = JSONLeagueDatabase.testInstance(tempDB.toString()); // makes new instance + // Golfer testGolfer = new Golfer("Jamie Doe", "joe_cool", "12345"); + // instance.addGolfer(testGolfer); + // testGolfer.setUsername("joe_super_cool"); + // instance.updateGolfer(testGolfer); + // assertEquals(testGolfer, instance.getGolfer("joe_super_cool")); + // } +} diff --git a/src/test/java/design/persistence/JSONPersonalDatabaseTest.java b/src/test/java/design/persistence/JSONPersonalDatabaseTest.java index 55270c4..21cc366 100644 --- a/src/test/java/design/persistence/JSONPersonalDatabaseTest.java +++ b/src/test/java/design/persistence/JSONPersonalDatabaseTest.java @@ -1,7 +1,6 @@ package design.persistence; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.IOException; import java.nio.file.Files; -- cgit v1.2.3 From 1da6f53677108558ca1403dbb82f4adc0a84797e Mon Sep 17 00:00:00 2001 From: WillemDalton Date: Sat, 15 Nov 2025 12:47:37 -0500 Subject: finished testing for persistence --- .../design/persistence/CSVMasterDatabaseTest.java | 43 ++++++++++++++++++++++ .../design/persistence/JSONLeagueDatabaseTest.java | 28 +++++++++----- 2 files changed, 61 insertions(+), 10 deletions(-) create mode 100644 src/test/java/design/persistence/CSVMasterDatabaseTest.java (limited to 'src') diff --git a/src/test/java/design/persistence/CSVMasterDatabaseTest.java b/src/test/java/design/persistence/CSVMasterDatabaseTest.java new file mode 100644 index 0000000..853d51c --- /dev/null +++ b/src/test/java/design/persistence/CSVMasterDatabaseTest.java @@ -0,0 +1,43 @@ +package design.persistence; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import design.model.Club.ClubType; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Modifier; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +/** Unit Tests for the CSV Master Database Singleton class. + * @author Willem Dalton + **/ +@Tag("Model-tier") +public class CSVMasterDatabaseTest { + + @Test + void testInstance() + { + CSVMasterDatabase instance = CSVMasterDatabase.instance(); + assertNotNull(instance); + CSVMasterDatabase instance2 = CSVMasterDatabase.instance(); + assertNotNull(instance2); + } + + @Test + void testGetCourses() + { + CSVMasterDatabase instance = CSVMasterDatabase.instance(); + String expectedResult = "Mountain View Links (Mobile, AL) | Holes: 18 | Total Par: 70 | Difficulty: 73.0"; + assertEquals(1000, instance.getCourses().length); + assertNotNull(instance.getCourseList()); + assertEquals(expectedResult, instance.getCourse(0).toString()); + } + +} diff --git a/src/test/java/design/persistence/JSONLeagueDatabaseTest.java b/src/test/java/design/persistence/JSONLeagueDatabaseTest.java index 1dcdbb1..b27555c 100644 --- a/src/test/java/design/persistence/JSONLeagueDatabaseTest.java +++ b/src/test/java/design/persistence/JSONLeagueDatabaseTest.java @@ -5,6 +5,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.Date; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -15,7 +17,10 @@ import org.junit.jupiter.api.Test; import design.model.League; import design.model.StrokeLeague; +import design.model.Course; import design.model.Golfer; +import design.model.Hole; +import design.model.Match; /** Unit Tests for the JSON Personal Database Singleton * @author Willem Dalton @@ -54,14 +59,17 @@ public class JSONLeagueDatabaseTest { assertEquals(0, instance.getLeagues().length); } - // @Test - // void testUpdateGolfer() throws IOException - // { - // JSONLeagueDatabase instance = JSONLeagueDatabase.testInstance(tempDB.toString()); // makes new instance - // Golfer testGolfer = new Golfer("Jamie Doe", "joe_cool", "12345"); - // instance.addGolfer(testGolfer); - // testGolfer.setUsername("joe_super_cool"); - // instance.updateGolfer(testGolfer); - // assertEquals(testGolfer, instance.getGolfer("joe_super_cool")); - // } + @Test + void testUpdateGolfer() throws IOException + { + JSONLeagueDatabase instance = JSONLeagueDatabase.testInstance(tempDB.toString()); // makes new instance + Golfer testOwner = new Golfer("Jamie Doe", "joe_cool", "12345"); + League testLeague = new StrokeLeague("The A Team", new Date(1234), new Date(123), new Date(12345), testOwner); + instance.addLeague(testLeague); + Course testCourse = new Course(0, "Rolling Waves", 62, "Rochester, NY", 9, 20, new ArrayList()); + Match testMatch = new Match(testCourse, new Date(123), LocalDateTime.now(), 3); + testLeague.addMatchToSchedule(testMatch); + instance.updateLeague(testLeague); + assertEquals(testLeague, instance.getLeague(testLeague.getId())); + } } -- cgit v1.2.3 From a5668e0b228115eb828c84148cdcf27eb56b28a7 Mon Sep 17 00:00:00 2001 From: WillemDalton Date: Sat, 15 Nov 2025 12:48:48 -0500 Subject: removed unused dependencies in CSV testing --- src/test/java/design/persistence/CSVMasterDatabaseTest.java | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'src') diff --git a/src/test/java/design/persistence/CSVMasterDatabaseTest.java b/src/test/java/design/persistence/CSVMasterDatabaseTest.java index 853d51c..7ecf59f 100644 --- a/src/test/java/design/persistence/CSVMasterDatabaseTest.java +++ b/src/test/java/design/persistence/CSVMasterDatabaseTest.java @@ -2,19 +2,10 @@ package design.persistence; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; -import design.model.Club.ClubType; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Modifier; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; - /** Unit Tests for the CSV Master Database Singleton class. * @author Willem Dalton **/ @@ -39,5 +30,4 @@ public class CSVMasterDatabaseTest { assertNotNull(instance.getCourseList()); assertEquals(expectedResult, instance.getCourse(0).toString()); } - } -- cgit v1.2.3 From d06215b7ce9004943f370756a35e40cbbf46f672 Mon Sep 17 00:00:00 2001 From: WillemDalton Date: Sat, 15 Nov 2025 13:58:06 -0500 Subject: finished testing for statistics subsystem --- src/test/java/design/model/InviteTest.java | 1 + .../design/model/holeplay/HolePlayContextTest.java | 69 ++++++++ .../design/model/statistics/StatisticsTest.java | 180 +++++++++++++++++++++ .../design/persistence/CSVMasterDatabaseTest.java | 2 +- 4 files changed, 251 insertions(+), 1 deletion(-) create mode 100644 src/test/java/design/model/statistics/StatisticsTest.java (limited to 'src') diff --git a/src/test/java/design/model/InviteTest.java b/src/test/java/design/model/InviteTest.java index a71271d..29388a2 100644 --- a/src/test/java/design/model/InviteTest.java +++ b/src/test/java/design/model/InviteTest.java @@ -10,6 +10,7 @@ import java.util.Date; /** Unit Tests for the Invite Class. * @author Willem Dalton **/ +@Tag("Model-tier") public class InviteTest { @Test void testConstructor() diff --git a/src/test/java/design/model/holeplay/HolePlayContextTest.java b/src/test/java/design/model/holeplay/HolePlayContextTest.java index de0f1e9..c2ca619 100644 --- a/src/test/java/design/model/holeplay/HolePlayContextTest.java +++ b/src/test/java/design/model/holeplay/HolePlayContextTest.java @@ -1,5 +1,74 @@ package design.model.holeplay; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import java.util.Date; +import java.time.LocalDateTime; +import java.util.ArrayList; + +import design.model.Golfer; +import design.model.Round; +import design.model.Club.ClubType; +import design.persistence.PersonalDatabase; +import design.model.Course; +import design.model.Hole; +import design.model.Club; + +/** Unit Tests for the HolePlayContext Class. + * @author Willem Dalton + **/ +@Tag("Model-tier") public class HolePlayContextTest { + @Test + void testConstructor() + { + Golfer testGolfer = new Golfer("John Doe", "j_doe", "weback"); + Course testCourse = new Course(0, "Rolling Waves", 67, "Rochester, NY", 0, 0, new ArrayList()); + Round testRound = new Round(testCourse, LocalDateTime.now(), new Hole(0, 10)); + HolePlayContext testContext = new HolePlayContext(testGolfer, testRound, PersonalDatabase.instance()); + assertEquals(testGolfer, testContext.getGolfer()); + assertEquals(testRound, testContext.getRound()); + } + + @Test + void testPlay() + { + Golfer testGolfer = new Golfer("John Doe", "j_doe", "weback"); + Course testCourse = new Course(0, "Rolling Waves", 67, "Rochester, NY", 0, 0, new ArrayList()); + Round testRound = new Round(testCourse, LocalDateTime.now(), new Hole(0, 10)); + HolePlayContext testContext = new HolePlayContext(testGolfer, testRound, PersonalDatabase.instance()); + testContext.beginNewPlay(0); + Club testClub = new Club("John Doe Inc", "The Slammer", ClubType.DRIVER); + testContext.addSwing(testClub, 100); + assertEquals(1, testContext.getCurrentPlay().getSwingCount()); + assertEquals(100, testContext.getCurrentPlay().getDistance()); + } + + @Test + void testPlayNull() + { + Golfer testGolfer = new Golfer("John Doe", "j_doe", "weback"); + Course testCourse = new Course(0, "Rolling Waves", 67, "Rochester, NY", 0, 0, new ArrayList()); + Round testRound = new Round(testCourse, LocalDateTime.now(), new Hole(0, 10)); + HolePlayContext testContext = new HolePlayContext(testGolfer, testRound, PersonalDatabase.instance()); + testContext.beginNewPlay(0); + Club testClub = new Club("John Doe Inc", "The Slammer", ClubType.DRIVER); + testContext.addSwing(testClub, null); + assertEquals(1, testContext.getCurrentPlay().getSwingCount()); + assertEquals(0, testContext.getCurrentPlay().getDistance()); + } + + // @Test + // void testHolePlay() + // { + // Golfer testGolfer = new Golfer("John Doe", "j_doe", "weback"); + // Course testCourse = new Course(0, "Rolling Waves", 67, "Rochester, NY", 0, 0, new ArrayList()); + // Round testRound = new Round(testCourse, LocalDateTime.now(), new Hole(0, 10)); + // HolePlayContext testContext = new HolePlayContext(testGolfer, testRound, PersonalDatabase.instance()); + // testContext.startHole(); + // } } \ No newline at end of file diff --git a/src/test/java/design/model/statistics/StatisticsTest.java b/src/test/java/design/model/statistics/StatisticsTest.java new file mode 100644 index 0000000..e68796a --- /dev/null +++ b/src/test/java/design/model/statistics/StatisticsTest.java @@ -0,0 +1,180 @@ +package design.model.statistics; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Arrays; + +import design.model.Course; +import design.model.Golfer; +import design.model.Hole; +import design.model.Round; +import design.model.Club.ClubType; +import design.model.Play; +import design.model.Club; +import design.model.Swing; + +/** Unit Tests for the Statistics Subsystem + * @author Willem Dalton + **/ +@Tag("Model-tier") +public class StatisticsTest { + + /* base stats wrapper for testing purposes */ + private static class StubStatistics implements Statistics { + private final Golfer golfer; + + public StubStatistics(Golfer golfer) { + this.golfer = golfer; + } + + @Override + public Round[] getRounds() { + return golfer.getRounds(); + } + + @Override + public int get_score() { + return Arrays.stream(getRounds()) + .mapToInt(Round::getTotalSwings) + .sum(); + } + + @Override + public double get_distance() { + return Arrays.stream(getRounds()) + .mapToDouble(Round::getTotalDistance) + .sum(); + } + } + + @Test + void testLifeTime() + { + Golfer testGolfer = new Golfer("John Doe", "j_doe", "weback"); + Course testCourse = new Course(0, "Rolling Waves", 67, "Rochester, NY", 0, 0, new ArrayList()); + Round testRound = new Round(testCourse, LocalDateTime.now(), new Hole(0, 10)); + Swing testSwing = new Swing(100, new Club("John Doe Inc", "The Slammer", ClubType.DRIVER)); + LifetimeStats stats = new LifetimeStats(testGolfer); + + assertNotNull(stats); + assertEquals(0, stats.get_score()); + assertEquals(0, stats.get_distance()); + + ArrayList testSwings = new ArrayList(); + testSwings.add(testSwing); + Play testPlay = new Play(0, testSwings); + testRound.addPlay(testPlay); + testGolfer.addRound(testRound); + + assertEquals(1, stats.get_score()); + assertEquals(100, stats.get_distance()); + } + + @Test + void testYearly() + { + Golfer testGolfer = new Golfer("John Doe", "j_doe", "weback"); + Course testCourse = new Course(0, "Rolling Waves", 67, "Rochester, NY", 0, 0, new ArrayList()); + Round testRound = new Round(testCourse, LocalDateTime.now(), new Hole(0, 10)); + Swing testSwing = new Swing(100, new Club("John Doe Inc", "The Slammer", ClubType.DRIVER)); + + Statistics wrapper = new StubStatistics(testGolfer); + YearlyStats stats = new YearlyStats(wrapper, 2025); + + assertNotNull(stats); + assertEquals(0, stats.get_score()); + assertEquals(0, stats.get_distance()); + + ArrayList testSwings = new ArrayList(); + testSwings.add(testSwing); + Play testPlay = new Play(0, testSwings); + testRound.addPlay(testPlay); + testGolfer.addRound(testRound); + + assertEquals(1, stats.get_score()); + assertEquals(100, stats.get_distance()); + } + + @Test + void testCourse() + { + Golfer testGolfer = new Golfer("John Doe", "j_doe", "weback"); + Course testCourse = new Course(0, "Rolling Waves", 67, "Rochester, NY", 0, 0, new ArrayList()); + Round testRound = new Round(testCourse, LocalDateTime.now(), new Hole(0, 10)); + Swing testSwing = new Swing(100, new Club("John Doe Inc", "The Slammer", ClubType.DRIVER)); + + Statistics wrapper = new StubStatistics(testGolfer); + CourseStats stats = new CourseStats(wrapper, testCourse); + + assertNotNull(stats); + assertEquals(0, stats.get_score()); + assertEquals(0, stats.get_distance()); + + ArrayList testSwings = new ArrayList(); + testSwings.add(testSwing); + Play testPlay = new Play(0, testSwings); + testRound.addPlay(testPlay); + testGolfer.addRound(testRound); + + assertEquals(1, stats.get_score()); + assertEquals(100, stats.get_distance()); + } + + @Test + void testRound() + { + Golfer testGolfer = new Golfer("John Doe", "j_doe", "weback"); + Course testCourse = new Course(0, "Rolling Waves", 67, "Rochester, NY", 0, 0, new ArrayList()); + Round testRound = new Round(testCourse, LocalDateTime.now(), new Hole(0, 10)); + Swing testSwing = new Swing(100, new Club("John Doe Inc", "The Slammer", ClubType.DRIVER)); + + Statistics wrapper = new StubStatistics(testGolfer); + RoundStats stats = new RoundStats(wrapper, testRound); + + assertNotNull(stats); + assertEquals(0, stats.get_score()); + assertEquals(0, stats.get_distance()); + + ArrayList testSwings = new ArrayList(); + testSwings.add(testSwing); + Play testPlay = new Play(0, testSwings); + testRound.addPlay(testPlay); + testGolfer.addRound(testRound); + + assertEquals(1, stats.get_score()); + assertEquals(100, stats.get_distance()); + } + + @Test + void testHole() + { + Golfer testGolfer = new Golfer("John Doe", "j_doe", "weback"); + Course testCourse = new Course(0, "Rolling Waves", 67, "Rochester, NY", 0, 0, new ArrayList()); + Round testRound = new Round(testCourse, LocalDateTime.now(), new Hole(0, 10)); + Swing testSwing = new Swing(100, new Club("John Doe Inc", "The Slammer", ClubType.DRIVER)); + Hole testHole = new Hole(0, 10); + + Statistics wrapper = new StubStatistics(testGolfer); + HoleStats stats = new HoleStats(wrapper, testHole); + + assertNotNull(stats); + assertEquals(0, stats.get_score()); + assertEquals(0, stats.get_distance()); + + ArrayList testSwings = new ArrayList(); + testSwings.add(testSwing); + Play testPlay = new Play(0, testSwings); + testRound.addPlay(testPlay); + testGolfer.addRound(testRound); + + assertEquals(1, stats.get_score()); + assertEquals(100, stats.get_distance()); + assertEquals(0, stats.getRounds().length); + } +} diff --git a/src/test/java/design/persistence/CSVMasterDatabaseTest.java b/src/test/java/design/persistence/CSVMasterDatabaseTest.java index 7ecf59f..4c78800 100644 --- a/src/test/java/design/persistence/CSVMasterDatabaseTest.java +++ b/src/test/java/design/persistence/CSVMasterDatabaseTest.java @@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test; /** Unit Tests for the CSV Master Database Singleton class. * @author Willem Dalton **/ -@Tag("Model-tier") +@Tag("Persistence-tier") public class CSVMasterDatabaseTest { @Test -- cgit v1.2.3 From 0c614ec078ea6d46b85d5032835cb98f9dc28c6c Mon Sep 17 00:00:00 2001 From: WillemDalton Date: Sat, 15 Nov 2025 14:21:14 -0500 Subject: finished work on unit testing for npw --- src/main/java/design/model/ScrambleLeague.java | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/main/java/design/model/ScrambleLeague.java b/src/main/java/design/model/ScrambleLeague.java index d372264..b0d65f8 100644 --- a/src/main/java/design/model/ScrambleLeague.java +++ b/src/main/java/design/model/ScrambleLeague.java @@ -4,7 +4,6 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonTypeName; import java.util.ArrayList; -import java.util.Arrays; import java.util.Date; import java.util.List; -- cgit v1.2.3 From 73cb1c77c99330360313bb07fcbc3c23a2516680 Mon Sep 17 00:00:00 2001 From: sowgro Date: Sat, 15 Nov 2025 23:27:40 -0500 Subject: fix nulls --- .../java/design/controller/userinput/menus/ImportExportMenu.java | 3 ++- src/main/java/design/persistence/JSONLeagueDatabase.java | 6 +++--- src/main/java/design/persistence/JSONPersonalDatabase.java | 6 +++--- 3 files changed, 8 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/main/java/design/controller/userinput/menus/ImportExportMenu.java b/src/main/java/design/controller/userinput/menus/ImportExportMenu.java index dda465f..21ffa6c 100644 --- a/src/main/java/design/controller/userinput/menus/ImportExportMenu.java +++ b/src/main/java/design/controller/userinput/menus/ImportExportMenu.java @@ -56,6 +56,7 @@ public class ImportExportMenu extends Menu { case "xml" -> handler = new XMLHandler(source); default -> { System.out.println("Unsupported file type: " + ext); + this.present(); return; } } @@ -75,6 +76,6 @@ public class ImportExportMenu extends Menu { private static String getExtension(String fileName) { int i = fileName.lastIndexOf('.'); - return (i >= 0) ? fileName.substring(i + 1).toLowerCase() : ""; + return (i >= 0) ? fileName.substring(i + 1).toLowerCase() : "unknown"; } } diff --git a/src/main/java/design/persistence/JSONLeagueDatabase.java b/src/main/java/design/persistence/JSONLeagueDatabase.java index 795c582..81a4913 100644 --- a/src/main/java/design/persistence/JSONLeagueDatabase.java +++ b/src/main/java/design/persistence/JSONLeagueDatabase.java @@ -1,8 +1,6 @@ package design.persistence; -import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.annotation.*; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; @@ -15,6 +13,7 @@ import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Map; public class JSONLeagueDatabase implements LeagueDatabase { @@ -48,6 +47,7 @@ public class JSONLeagueDatabase implements LeagueDatabase { mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); mapper.registerModule(new ParameterNamesModule(JsonCreator.Mode.PROPERTIES)); mapper.registerModule(new JavaTimeModule()); + mapper.configOverride(List.class).setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY)); try { load(); diff --git a/src/main/java/design/persistence/JSONPersonalDatabase.java b/src/main/java/design/persistence/JSONPersonalDatabase.java index 3e70629..a5a4795 100644 --- a/src/main/java/design/persistence/JSONPersonalDatabase.java +++ b/src/main/java/design/persistence/JSONPersonalDatabase.java @@ -1,8 +1,6 @@ package design.persistence; -import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.annotation.*; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; @@ -14,6 +12,7 @@ import design.model.League; import java.io.File; import java.io.IOException; import java.util.HashMap; +import java.util.List; import java.util.Map; public class JSONPersonalDatabase implements PersonalDatabase { @@ -47,6 +46,7 @@ public class JSONPersonalDatabase implements PersonalDatabase { mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); mapper.registerModule(new ParameterNamesModule(JsonCreator.Mode.PROPERTIES)); mapper.registerModule(new JavaTimeModule()); + mapper.configOverride(List.class).setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY)); try { load(); -- cgit v1.2.3 From 4ac38e80c2442e085c53986f5717d44f9d2d821a Mon Sep 17 00:00:00 2001 From: sowgro Date: Sun, 16 Nov 2025 00:22:00 -0500 Subject: fix datetime issue --- src/main/java/design/persistence/JSONLeagueDatabase.java | 4 +++- src/main/java/design/persistence/JSONPersonalDatabase.java | 4 +++- src/main/java/design/persistence/Serializers.java | 9 +++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/main/java/design/persistence/JSONLeagueDatabase.java b/src/main/java/design/persistence/JSONLeagueDatabase.java index 81a4913..0891551 100644 --- a/src/main/java/design/persistence/JSONLeagueDatabase.java +++ b/src/main/java/design/persistence/JSONLeagueDatabase.java @@ -11,6 +11,7 @@ import design.model.League; import java.io.File; import java.io.IOException; +import java.time.LocalDateTime; import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -42,11 +43,12 @@ public class JSONLeagueDatabase implements LeagueDatabase { module.addSerializer(Course.class, new Serializers.CourseIdSerializer()); module.addDeserializer(Golfer.class, new Serializers.GolferUsernameDeserializer()); module.addSerializer(Golfer.class, new Serializers.GolferUsernameSerializer()); + module.addSerializer(LocalDateTime.class, new Serializers.DateTimeStringSerializer()); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - mapper.registerModule(module); mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); mapper.registerModule(new ParameterNamesModule(JsonCreator.Mode.PROPERTIES)); mapper.registerModule(new JavaTimeModule()); + mapper.registerModule(module); mapper.configOverride(List.class).setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY)); try { diff --git a/src/main/java/design/persistence/JSONPersonalDatabase.java b/src/main/java/design/persistence/JSONPersonalDatabase.java index a5a4795..bf0dda9 100644 --- a/src/main/java/design/persistence/JSONPersonalDatabase.java +++ b/src/main/java/design/persistence/JSONPersonalDatabase.java @@ -11,6 +11,7 @@ import design.model.League; import java.io.File; import java.io.IOException; +import java.time.LocalDateTime; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -41,11 +42,12 @@ public class JSONPersonalDatabase implements PersonalDatabase { module.addSerializer(Course.class, new Serializers.CourseIdSerializer()); module.addSerializer(League.class, new Serializers.LeagueIDSerializer()); module.addDeserializer(League.class, new Serializers.LeagueIDDeserializer()); - mapper.registerModule(module); + module.addSerializer(LocalDateTime.class, new Serializers.DateTimeStringSerializer()); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); mapper.registerModule(new ParameterNamesModule(JsonCreator.Mode.PROPERTIES)); mapper.registerModule(new JavaTimeModule()); + mapper.registerModule(module); mapper.configOverride(List.class).setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY)); try { diff --git a/src/main/java/design/persistence/Serializers.java b/src/main/java/design/persistence/Serializers.java index 3940b44..2f2b208 100644 --- a/src/main/java/design/persistence/Serializers.java +++ b/src/main/java/design/persistence/Serializers.java @@ -8,11 +8,13 @@ import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; import design.model.Course; import design.model.Golfer; import design.model.League; import java.io.IOException; +import java.time.LocalDateTime; public class Serializers { public static class CustomPrettyPrinter extends DefaultPrettyPrinter { @@ -76,4 +78,11 @@ public class Serializers { return personalDB.getGolfer(username); } } + + public static class DateTimeStringSerializer extends JsonSerializer { + @Override + public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeString(value.toString()); + } + } } -- cgit v1.2.3 From cf59d52cba70742f1d4098c38b4c7a798b3d89fa Mon Sep 17 00:00:00 2001 From: sowgro Date: Sun, 16 Nov 2025 01:56:27 -0500 Subject: IMPORT-EXPORT WORKING!!!!!!!!!!!!!!!!!!!!!!!!!! --- .../design/persistence/JSONLeagueDatabase.java | 45 ++++++++++----------- .../design/persistence/JSONPersonalDatabase.java | 46 +++++++++++----------- .../java/design/persistence/LeagueDatabase.java | 6 +++ .../java/design/persistence/PersonalDatabase.java | 6 +++ src/main/java/design/persistence/Serializers.java | 18 ++++++--- .../persistence/importexport/DataSource.java | 10 +++-- .../persistence/importexport/JSONHandler.java | 17 +++++--- .../persistence/importexport/XMLHandler.java | 22 ++++++----- 8 files changed, 102 insertions(+), 68 deletions(-) (limited to 'src') diff --git a/src/main/java/design/persistence/JSONLeagueDatabase.java b/src/main/java/design/persistence/JSONLeagueDatabase.java index 0891551..977e162 100644 --- a/src/main/java/design/persistence/JSONLeagueDatabase.java +++ b/src/main/java/design/persistence/JSONLeagueDatabase.java @@ -1,20 +1,15 @@ package design.persistence; -import com.fasterxml.jackson.annotation.*; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.module.SimpleModule; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import com.fasterxml.jackson.module.paramnames.ParameterNamesModule; import design.model.Course; import design.model.Golfer; import design.model.League; import java.io.File; import java.io.IOException; -import java.time.LocalDateTime; import java.util.Arrays; import java.util.HashMap; -import java.util.List; import java.util.Map; public class JSONLeagueDatabase implements LeagueDatabase { @@ -38,18 +33,8 @@ public class JSONLeagueDatabase implements LeagueDatabase { this.cache = new HashMap<>(); this.mapper = new ObjectMapper(); - SimpleModule module = new SimpleModule(); - module.addDeserializer(Course.class, new Serializers.CourseIdDeserializer()); - module.addSerializer(Course.class, new Serializers.CourseIdSerializer()); - module.addDeserializer(Golfer.class, new Serializers.GolferUsernameDeserializer()); - module.addSerializer(Golfer.class, new Serializers.GolferUsernameSerializer()); - module.addSerializer(LocalDateTime.class, new Serializers.DateTimeStringSerializer()); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); - mapper.registerModule(new ParameterNamesModule(JsonCreator.Mode.PROPERTIES)); - mapper.registerModule(new JavaTimeModule()); - mapper.registerModule(module); - mapper.configOverride(List.class).setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY)); + Serializers.configureMapper(mapper); + mapper.registerModule(this.getJacksonModule()); try { load(); @@ -101,8 +86,10 @@ public class JSONLeagueDatabase implements LeagueDatabase { } @Override - public void importData(JsonNode tree) throws IOException { - League[] data = mapper.treeToValue(tree, League[].class); + public void importData(Object rawData) throws IOException { + if (!(rawData instanceof League[] data)) { + throw new ClassCastException(); + } cache.clear(); for (League league : data) { cache.put(league.getId(), league); @@ -111,8 +98,22 @@ public class JSONLeagueDatabase implements LeagueDatabase { } @Override - public JsonNode exportData() { - Object[] data = cache.values().toArray(); - return mapper.valueToTree(data); + public League[] exportData() { + return getLeagues(); + } + + @Override + public SimpleModule getJacksonModule() { + SimpleModule module = new SimpleModule(); + module.addDeserializer(Course.class, new Serializers.CourseIdDeserializer()); + module.addSerializer(Course.class, new Serializers.CourseIdSerializer()); + module.addDeserializer(Golfer.class, new Serializers.GolferUsernameDeserializer()); + module.addSerializer(Golfer.class, new Serializers.GolferUsernameSerializer()); + return module; + } + + @Override + public Class getTargetClass() { + return League[].class; } } diff --git a/src/main/java/design/persistence/JSONPersonalDatabase.java b/src/main/java/design/persistence/JSONPersonalDatabase.java index bf0dda9..b92dddf 100644 --- a/src/main/java/design/persistence/JSONPersonalDatabase.java +++ b/src/main/java/design/persistence/JSONPersonalDatabase.java @@ -1,19 +1,14 @@ package design.persistence; -import com.fasterxml.jackson.annotation.*; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.module.SimpleModule; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import com.fasterxml.jackson.module.paramnames.ParameterNamesModule; import design.model.Course; import design.model.Golfer; import design.model.League; import java.io.File; import java.io.IOException; -import java.time.LocalDateTime; import java.util.HashMap; -import java.util.List; import java.util.Map; public class JSONPersonalDatabase implements PersonalDatabase { @@ -36,19 +31,8 @@ public class JSONPersonalDatabase implements PersonalDatabase { this.cache = new HashMap<>(); this.mapper = new ObjectMapper(); - - SimpleModule module = new SimpleModule(); - module.addDeserializer(Course.class, new Serializers.CourseIdDeserializer()); - module.addSerializer(Course.class, new Serializers.CourseIdSerializer()); - module.addSerializer(League.class, new Serializers.LeagueIDSerializer()); - module.addDeserializer(League.class, new Serializers.LeagueIDDeserializer()); - module.addSerializer(LocalDateTime.class, new Serializers.DateTimeStringSerializer()); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); - mapper.registerModule(new ParameterNamesModule(JsonCreator.Mode.PROPERTIES)); - mapper.registerModule(new JavaTimeModule()); - mapper.registerModule(module); - mapper.configOverride(List.class).setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY)); + Serializers.configureMapper(mapper); + mapper.registerModule(this.getJacksonModule()); try { load(); @@ -100,8 +84,10 @@ public class JSONPersonalDatabase implements PersonalDatabase { } @Override - public void importData(JsonNode tree) throws IOException { - Golfer[] data = mapper.treeToValue(tree, Golfer[].class); + public void importData(Object rawData) throws IOException { + if (!(rawData instanceof Golfer[] data)) { + throw new ClassCastException(); + } cache.clear(); for (Golfer golfer : data) { cache.put(golfer.getUsername(), golfer); @@ -110,8 +96,22 @@ public class JSONPersonalDatabase implements PersonalDatabase { } @Override - public JsonNode exportData() { - Object[] data = cache.values().toArray(); - return mapper.valueToTree(data); + public Golfer[] exportData() { + return getGolfers(); + } + + @Override + public SimpleModule getJacksonModule() { + SimpleModule module = new SimpleModule(); + module.addDeserializer(Course.class, new Serializers.CourseIdDeserializer()); + module.addSerializer(Course.class, new Serializers.CourseIdSerializer()); + module.addSerializer(League.class, new Serializers.LeagueIDSerializer()); + module.addDeserializer(League.class, new Serializers.LeagueIDDeserializer()); + return module; + } + + @Override + public Class getTargetClass() { + return Golfer[].class; } } diff --git a/src/main/java/design/persistence/LeagueDatabase.java b/src/main/java/design/persistence/LeagueDatabase.java index 9f835ff..ed6ddae 100644 --- a/src/main/java/design/persistence/LeagueDatabase.java +++ b/src/main/java/design/persistence/LeagueDatabase.java @@ -19,4 +19,10 @@ public interface LeagueDatabase extends DataSource { void removeLeague(League league) throws IOException; void updateLeague(League league) throws IOException; + + @Override + void importData(Object data) throws IOException; + + @Override + Object exportData() throws IOException; } diff --git a/src/main/java/design/persistence/PersonalDatabase.java b/src/main/java/design/persistence/PersonalDatabase.java index 77e43cc..70dd37d 100644 --- a/src/main/java/design/persistence/PersonalDatabase.java +++ b/src/main/java/design/persistence/PersonalDatabase.java @@ -20,4 +20,10 @@ public interface PersonalDatabase extends DataSource { void removeGolfer(Golfer golfer) throws IOException; void updateGolfer(Golfer golfer) throws IOException; + + @Override + void importData(Object data) throws IOException; + + @Override + Object exportData() throws IOException; } diff --git a/src/main/java/design/persistence/Serializers.java b/src/main/java/design/persistence/Serializers.java index 2f2b208..246dbf1 100644 --- a/src/main/java/design/persistence/Serializers.java +++ b/src/main/java/design/persistence/Serializers.java @@ -1,20 +1,20 @@ package design.persistence; +import com.fasterxml.jackson.annotation.*; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.util.DefaultIndenter; import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.databind.*; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.module.paramnames.ParameterNamesModule; import design.model.Course; import design.model.Golfer; import design.model.League; import java.io.IOException; import java.time.LocalDateTime; +import java.util.List; public class Serializers { public static class CustomPrettyPrinter extends DefaultPrettyPrinter { @@ -85,4 +85,12 @@ public class Serializers { gen.writeString(value.toString()); } } + + public static void configureMapper(ObjectMapper mapper) { + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); + mapper.registerModule(new ParameterNamesModule(JsonCreator.Mode.PROPERTIES)); + mapper.registerModule(new JavaTimeModule()); + mapper.configOverride(List.class).setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY)); + } } diff --git a/src/main/java/design/persistence/importexport/DataSource.java b/src/main/java/design/persistence/importexport/DataSource.java index 5290e33..e735c7e 100644 --- a/src/main/java/design/persistence/importexport/DataSource.java +++ b/src/main/java/design/persistence/importexport/DataSource.java @@ -1,12 +1,16 @@ package design.persistence.importexport; -import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.module.SimpleModule; import java.io.IOException; public interface DataSource { - void importData(JsonNode tree) throws IOException; + void importData(Object data) throws IOException; - JsonNode exportData() throws IOException; + Object exportData() throws IOException; + + SimpleModule getJacksonModule(); + + Class getTargetClass(); } \ No newline at end of file diff --git a/src/main/java/design/persistence/importexport/JSONHandler.java b/src/main/java/design/persistence/importexport/JSONHandler.java index 239eb6b..9c04281 100644 --- a/src/main/java/design/persistence/importexport/JSONHandler.java +++ b/src/main/java/design/persistence/importexport/JSONHandler.java @@ -1,6 +1,7 @@ package design.persistence.importexport; -import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.json.JsonMapper; +import design.persistence.Serializers; import java.io.File; import java.io.IOException; @@ -8,22 +9,26 @@ import java.io.IOException; public class JSONHandler implements DataHandler { private final DataSource dataSource; - private final JsonMapper jsonMapper = new JsonMapper(); + private final ObjectMapper jsonMapper = new JsonMapper(); public JSONHandler(DataSource dataSource) { this.dataSource = dataSource; + + Serializers.configureMapper(jsonMapper); + jsonMapper.registerModule(dataSource.getJacksonModule()); } @Override public void importData(File file) throws IOException { - JsonNode tree = jsonMapper.readTree(file); - dataSource.importData(tree); + Object data = jsonMapper.readValue(file, dataSource.getTargetClass()); + dataSource.importData(data); } @Override public void exportData(File file) throws IOException{ - JsonNode tree = dataSource.exportData(); - jsonMapper.writerWithDefaultPrettyPrinter().writeValue(file, tree); + Object data = dataSource.exportData(); + jsonMapper.writer(new Serializers.CustomPrettyPrinter()) + .writeValue(file, data); } } diff --git a/src/main/java/design/persistence/importexport/XMLHandler.java b/src/main/java/design/persistence/importexport/XMLHandler.java index 1a16b90..0a07d6e 100644 --- a/src/main/java/design/persistence/importexport/XMLHandler.java +++ b/src/main/java/design/persistence/importexport/XMLHandler.java @@ -1,10 +1,11 @@ package design.persistence.importexport; import java.io.File; import java.io.IOException; +import java.time.LocalDateTime; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ObjectNode; +import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.dataformat.xml.XmlMapper; +import design.persistence.Serializers; public class XMLHandler implements DataHandler { @@ -13,21 +14,24 @@ public class XMLHandler implements DataHandler { public XMLHandler(DataSource dataSource) { this.dataSource = dataSource; + + Serializers.configureMapper(xmlMapper); + SimpleModule module = dataSource.getJacksonModule(); + module.addSerializer(LocalDateTime.class, new Serializers.DateTimeStringSerializer()); + xmlMapper.registerModule(module); } @Override public void importData(File file) throws IOException { - JsonNode tree = xmlMapper.readTree(file); - JsonNode unwrapped = tree.get("items"); - dataSource.importData(unwrapped); + Object data = xmlMapper.readValue(file, dataSource.getTargetClass()); + dataSource.importData(data); } @Override public void exportData(File file) throws IOException { - JsonNode tree = dataSource.exportData(); - ObjectNode wrapper = xmlMapper.createObjectNode(); - wrapper.set("items", tree); - xmlMapper.writerWithDefaultPrettyPrinter().withRootName("export").writeValue(file, wrapper); + Object data = dataSource.exportData(); + xmlMapper.writerWithDefaultPrettyPrinter() + .writeValue(file, data); } } -- cgit v1.2.3 From b5d46c7701716bcb2dd6127aeb97f8fcdb7774fc Mon Sep 17 00:00:00 2001 From: sowgro Date: Sun, 16 Nov 2025 02:12:47 -0500 Subject: tweak main menu --- .../controller/userinput/menus/HistoryMenu.java | 30 +++++++++++++++++ .../controller/userinput/menus/MainMenu.java | 39 ++++++++-------------- 2 files changed, 43 insertions(+), 26 deletions(-) create mode 100644 src/main/java/design/controller/userinput/menus/HistoryMenu.java (limited to 'src') diff --git a/src/main/java/design/controller/userinput/menus/HistoryMenu.java b/src/main/java/design/controller/userinput/menus/HistoryMenu.java new file mode 100644 index 0000000..226b331 --- /dev/null +++ b/src/main/java/design/controller/userinput/menus/HistoryMenu.java @@ -0,0 +1,30 @@ +package design.controller.userinput.menus; + +import design.controller.userinput.Menu; +import design.controller.userinput.MenuOption; +import design.controller.userinput.UndoActions; + +import java.util.List; + +public class HistoryMenu extends Menu { + + @Override + public String getTitle() { + return "History"; + } + + @Override + public List getMenuOptions() { + return List.of( + new MenuOption("return to main menu", () -> new MainMenu().present()), + new MenuOption("undo", () -> { + UndoActions.undoWithSave(); + this.present(); + }), + new MenuOption("redo", () -> { + UndoActions.redoWithSave(); + this.present(); + }) + ); + } +} diff --git a/src/main/java/design/controller/userinput/menus/MainMenu.java b/src/main/java/design/controller/userinput/menus/MainMenu.java index 75ad88f..4331e56 100644 --- a/src/main/java/design/controller/userinput/menus/MainMenu.java +++ b/src/main/java/design/controller/userinput/menus/MainMenu.java @@ -2,7 +2,6 @@ package design.controller.userinput.menus; import design.controller.userinput.Menu; import design.controller.userinput.MenuOption; -import design.controller.userinput.UndoActions; import design.runtime.Session; import java.util.List; @@ -15,32 +14,20 @@ public class MainMenu extends Menu { @Override public List getMenuOptions() { - boolean guest = Session.isGuest(); - if (guest) { - return List.of( - new MenuOption("quit", () -> System.exit(0)), - new MenuOption("guest settings...", () -> new UserSettings().present()), - new MenuOption("browse courses...", () -> new SearchMenu().present()) - - ); + List options = new java.util.ArrayList<>(); + options.add(new MenuOption("quit", () -> System.exit(0))); + if (Session.isGuest()) { + options.add(new MenuOption("guest settings...", () -> new UserSettings().present())); + options.add(new MenuOption("browse courses...", () -> new SearchMenu().present())); } else { - return List.of( - new MenuOption("quit", () -> System.exit(0)), - new MenuOption("undo", () -> { - UndoActions.undoWithSave(); - this.present(); - }), - new MenuOption("redo", () -> { - UndoActions.redoWithSave(); - this.present(); - }), - new MenuOption("user settings...", () -> new UserSettings().present()), - new MenuOption("manage courses...", () -> new ManageCourses().present()), - new MenuOption("manage clubs...", () -> new ManageClubs().present()), - new MenuOption("statistics...", () -> new StatisticsMenu().present()), - new MenuOption("log round...", () -> new HolePlayMenu().present()), - new MenuOption("League play...", () -> new SelectLeague().present()) - ); + options.add(new MenuOption("manage history...", () -> new HistoryMenu().present())); + options.add(new MenuOption("user settings...", () -> new UserSettings().present())); + options.add(new MenuOption("manage courses...", () -> new ManageCourses().present())); + options.add(new MenuOption("manage clubs...", () -> new ManageClubs().present())); + options.add(new MenuOption("statistics...", () -> new StatisticsMenu().present())); + options.add(new MenuOption("log round...", () -> new HolePlayMenu().present())); + options.add(new MenuOption("league play...", () -> new SelectLeague().present())); } + return options; } } -- cgit v1.2.3