From c6d8cf0c6abfb3485aa49d6f2a3cd48e2d1216d9 Mon Sep 17 00:00:00 2001 From: Nicholas Lee Date: Mon, 10 Apr 2023 01:17:06 +0800 Subject: [PATCH 1/3] added test cases for other utility classes --- .../fasttrack/logic/parser/ParserUtil.java | 2 +- .../java/fasttrack/ui/CategoryListPanel.java | 2 +- .../logic/parser/ParserUtilTest.java | 22 ++++---- .../model/util/CommandUtilityTest.java | 28 ++++++++++ .../model/util/StorageUtilityTest.java | 26 ++++++++++ .../model/util/UserInterfaceUtilTest.java | 52 +++++++++++++++++++ 6 files changed, 120 insertions(+), 12 deletions(-) create mode 100644 src/test/java/fasttrack/model/util/CommandUtilityTest.java create mode 100644 src/test/java/fasttrack/model/util/StorageUtilityTest.java create mode 100644 src/test/java/fasttrack/model/util/UserInterfaceUtilTest.java diff --git a/src/main/java/fasttrack/logic/parser/ParserUtil.java b/src/main/java/fasttrack/logic/parser/ParserUtil.java index 1161958ca3b..4b40085232a 100644 --- a/src/main/java/fasttrack/logic/parser/ParserUtil.java +++ b/src/main/java/fasttrack/logic/parser/ParserUtil.java @@ -111,7 +111,7 @@ public static Category parseCategory(String categoryName) throws ParseException public static UserDefinedCategory parseCategory(String category, String summary) throws ParseException { requireNonNull(category); String trimmedCategory = category.trim(); - if (!Category.isValidCategoryName(category)) { + if (!Category.isValidCategoryName(trimmedCategory)) { throw new ParseException(Category.MESSAGE_CONSTRAINTS); } return new UserDefinedCategory(trimmedCategory, summary); diff --git a/src/main/java/fasttrack/ui/CategoryListPanel.java b/src/main/java/fasttrack/ui/CategoryListPanel.java index 5329f48996c..85588406333 100644 --- a/src/main/java/fasttrack/ui/CategoryListPanel.java +++ b/src/main/java/fasttrack/ui/CategoryListPanel.java @@ -32,7 +32,7 @@ public CategoryListPanel(ObservableList categoryList, ObservableList new CategoryListViewCell()); } - private int getAssociatedExpenseCount(Category category) { + public int getAssociatedExpenseCount(Category category) { return (int) expenseObservableList.stream() .filter(e -> e.getCategory().equals(category)) .count(); diff --git a/src/test/java/fasttrack/logic/parser/ParserUtilTest.java b/src/test/java/fasttrack/logic/parser/ParserUtilTest.java index 49ed333f6f9..43983d4d618 100644 --- a/src/test/java/fasttrack/logic/parser/ParserUtilTest.java +++ b/src/test/java/fasttrack/logic/parser/ParserUtilTest.java @@ -10,6 +10,8 @@ import fasttrack.commons.core.index.Index; import fasttrack.logic.parser.exceptions.ParseException; +import fasttrack.model.category.MiscellaneousCategory; +import fasttrack.model.category.UserDefinedCategory; import fasttrack.model.expense.Price; import fasttrack.model.expense.RecurringExpenseType; @@ -65,16 +67,16 @@ public void parsePrice_invalidInput_throwsParseException() { assertThrows(ParseException.class, () -> ParserUtil.parsePrice("0")); } - //@Test - //public void parseCategoryWithSummary_validInput_success() throws ParseException { - // // leading and trailing whitespace - // assertEquals(new UserDefinedCategory("category", "abc"), ParserUtil.parseCategory(" category ", "abc")); - // // miscellaneous category - // assertEquals(new MiscellaneousCategory(), ParserUtil.parseCategory("miscellaneous")); - // UserDefinedCategory category = ParserUtil.parseCategory("food", "for dining"); - // assertEquals("food", category.getCategoryName()); - // assertEquals("for dining", category.getSummary()); - //} + @Test + public void parseCategoryWithSummary_validInput_success() throws ParseException { + // leading and trailing whitespace + assertEquals(new UserDefinedCategory("category", "abc"), ParserUtil.parseCategory(" category ", "abc")); + // miscellaneous category + assertEquals(new MiscellaneousCategory(), ParserUtil.parseCategory("miscellaneous")); + UserDefinedCategory category = ParserUtil.parseCategory("food", "for dining"); + assertEquals("food", category.getCategoryName()); + assertEquals("for dining", category.getSummary()); + } @Test public void parseCategory_invalidInput_throwsParseException() { diff --git a/src/test/java/fasttrack/model/util/CommandUtilityTest.java b/src/test/java/fasttrack/model/util/CommandUtilityTest.java new file mode 100644 index 00000000000..67c4eaff0d9 --- /dev/null +++ b/src/test/java/fasttrack/model/util/CommandUtilityTest.java @@ -0,0 +1,28 @@ +package fasttrack.model.util; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.time.LocalDate; + +import org.junit.jupiter.api.Test; + +class CommandUtilityTest { + + @Test + void testParseDateFromUserInput_validFormats_success() { + assertEquals(LocalDate.of(2023, 3, 1), CommandUtility.parseDateFromUserInput("1/3/23")); + assertEquals(LocalDate.of(2023, 6, 5), CommandUtility.parseDateFromUserInput("5/6/2023")); + assertEquals(LocalDate.of(2022, 7, 16), CommandUtility.parseDateFromUserInput("16/7/22")); + assertEquals(LocalDate.of(2021, 12, 31), CommandUtility.parseDateFromUserInput("31/12/2021")); + } + @Test + void testParseDateFromUserInput_invalidFormats_throwsException() { + assertThrows(IllegalArgumentException.class, () -> CommandUtility.parseDateFromUserInput("32/2/2022")); + assertThrows(IllegalArgumentException.class, () -> CommandUtility.parseDateFromUserInput("12/13/2023")); + assertThrows(IllegalArgumentException.class, () -> CommandUtility.parseDateFromUserInput("12w/12/23a")); + assertThrows(IllegalArgumentException.class, () -> CommandUtility.parseDateFromUserInput("12/c12/23a")); + assertThrows(IllegalArgumentException.class, () -> CommandUtility.parseDateFromUserInput("2023-4-31")); + } + +} diff --git a/src/test/java/fasttrack/model/util/StorageUtilityTest.java b/src/test/java/fasttrack/model/util/StorageUtilityTest.java new file mode 100644 index 00000000000..1c498fff157 --- /dev/null +++ b/src/test/java/fasttrack/model/util/StorageUtilityTest.java @@ -0,0 +1,26 @@ +package fasttrack.model.util; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.time.LocalDate; + +import org.junit.jupiter.api.Test; + + +public class StorageUtilityTest { + + @Test + public void testParseDateFromJson_validDate() { + LocalDate expectedDate = LocalDate.of(2023, 4, 30); + LocalDate parsedDate = StorageUtility.parseDateFromJson("2023-04-30"); + assertEquals(expectedDate, parsedDate); + } + + @Test + public void testParseDateFromJson_invalidDate() { + assertThrows(java.time.format.DateTimeParseException.class, () -> { + StorageUtility.parseDateFromJson("20-4-31"); + }); + } +} diff --git a/src/test/java/fasttrack/model/util/UserInterfaceUtilTest.java b/src/test/java/fasttrack/model/util/UserInterfaceUtilTest.java new file mode 100644 index 00000000000..97f48ee062c --- /dev/null +++ b/src/test/java/fasttrack/model/util/UserInterfaceUtilTest.java @@ -0,0 +1,52 @@ +package fasttrack.model.util; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.time.LocalDate; + +import org.junit.jupiter.api.Test; + +public class UserInterfaceUtilTest { + + @Test + public void testParseDate_validDate_success() { + LocalDate date1 = LocalDate.of(2023, 4, 10); + String formattedDate1 = UserInterfaceUtil.parseDate(date1); + assertEquals("10/04/23", formattedDate1); + LocalDate date2 = LocalDate.of(2023, 12, 31); + String formattedDate2 = UserInterfaceUtil.parseDate(date2); + assertEquals("31/12/23", formattedDate2); + } + + @Test + public void testParsePrice_validInput_success() { + double amount1 = 10.00; + String formattedAmount1 = UserInterfaceUtil.parsePrice(amount1); + assertEquals("$10.00", formattedAmount1); + + double amount2 = -5.50; + String formattedAmount2 = UserInterfaceUtil.parsePrice(amount2); + assertEquals("$-5.50", formattedAmount2); + + double amount3 = 3.14159; + String formattedAmount3 = UserInterfaceUtil.parsePrice(amount3); + assertEquals("$3.14", formattedAmount3); + } + + @Test + public void testCapitalizeFirstLetter_validInput_success() { + String input1 = "hello"; + String capitalized1 = UserInterfaceUtil.capitalizeFirstLetter(input1); + assertEquals("Hello", capitalized1); + + String input2 = "wORLD"; + String capitalized2 = UserInterfaceUtil.capitalizeFirstLetter(input2); + assertEquals("WORLD", capitalized2); + + String input3 = "TEST"; + String capitalized3 = UserInterfaceUtil.capitalizeFirstLetter(input3); + assertEquals("TEST", capitalized3); + } + +} + From 052b4a370be2b32fdbb665d988f5bdc669d14424 Mon Sep 17 00:00:00 2001 From: Nicholas Lee Date: Mon, 10 Apr 2023 01:24:07 +0800 Subject: [PATCH 2/3] update ug with additional clarification --- docs/UserGuide.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index fc9dbf8c61f..7aca2a2af09 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -928,6 +928,16 @@ For example, if your monthly budget is $1000, and you have already spent $500, y This gives you an idea of how much of your monthly budget you have used up. +
+ +**:exclamation: Caution**
+ +Even if you have exceeded your budget, this statistic will reflect that you have fully utilised your budget, and will remain at `100%`. + +
+ + +

Back to Top

From 31db9d8860e6e91e871a98b4c185f3e8e592ac64 Mon Sep 17 00:00:00 2001 From: Nicholas Lee Date: Mon, 10 Apr 2023 12:54:28 +0800 Subject: [PATCH 3/3] add some test cases for ui classes --- .../java/fasttrack/ui/CategoryListPanel.java | 6 +- src/main/java/fasttrack/ui/CommandBox.java | 9 +- src/main/java/fasttrack/ui/MainWindow.java | 2 +- .../java/fasttrack/ui/CategoryCardTest.java | 87 ++++++++++++++++ .../fasttrack/ui/CategoryListPanelTest.java | 82 ++++++++++++++++ .../java/fasttrack/ui/CommandBoxTest.java | 88 +++++++++++++++++ .../java/fasttrack/ui/ExpenseCardTest.java | 93 ++++++++++++++++++ .../fasttrack/ui/ExpenseListPanelTest.java | 77 +++++++++++++++ .../ui/RecurringExpenseCardTest.java | 98 +++++++++++++++++++ .../ui/RecurringExpensePanelTest.java | 80 +++++++++++++++ 10 files changed, 613 insertions(+), 9 deletions(-) create mode 100644 src/test/java/fasttrack/ui/CategoryCardTest.java create mode 100644 src/test/java/fasttrack/ui/CategoryListPanelTest.java create mode 100644 src/test/java/fasttrack/ui/CommandBoxTest.java create mode 100644 src/test/java/fasttrack/ui/ExpenseCardTest.java create mode 100644 src/test/java/fasttrack/ui/ExpenseListPanelTest.java create mode 100644 src/test/java/fasttrack/ui/RecurringExpenseCardTest.java create mode 100644 src/test/java/fasttrack/ui/RecurringExpensePanelTest.java diff --git a/src/main/java/fasttrack/ui/CategoryListPanel.java b/src/main/java/fasttrack/ui/CategoryListPanel.java index 85588406333..1bedc02fa46 100644 --- a/src/main/java/fasttrack/ui/CategoryListPanel.java +++ b/src/main/java/fasttrack/ui/CategoryListPanel.java @@ -1,8 +1,5 @@ package fasttrack.ui; -import java.util.logging.Logger; - -import fasttrack.commons.core.LogsCenter; import fasttrack.model.category.Category; import fasttrack.model.expense.Expense; import javafx.collections.ObservableList; @@ -16,7 +13,6 @@ */ public class CategoryListPanel extends UiPart { private static final String FXML = "CategoryListPanel.fxml"; - private final Logger logger = LogsCenter.getLogger(CategoryListPanel.class); private final ObservableList expenseObservableList; @FXML @@ -32,7 +28,7 @@ public CategoryListPanel(ObservableList categoryList, ObservableList new CategoryListViewCell()); } - public int getAssociatedExpenseCount(Category category) { + private int getAssociatedExpenseCount(Category category) { return (int) expenseObservableList.stream() .filter(e -> e.getCategory().equals(category)) .count(); diff --git a/src/main/java/fasttrack/ui/CommandBox.java b/src/main/java/fasttrack/ui/CommandBox.java index bd77f4e55cc..7aad050dbe2 100644 --- a/src/main/java/fasttrack/ui/CommandBox.java +++ b/src/main/java/fasttrack/ui/CommandBox.java @@ -29,19 +29,22 @@ public class CommandBox extends UiPart { /** * Creates a {@code CommandBox} with the given {@code CommandExecutor}. */ - public CommandBox(CommandExecutor commandExecutor) { + public CommandBox(CommandExecutor commandExecutor, boolean initialiseAutocompletion) { super(FXML); this.commandExecutor = commandExecutor; // calls #setStyleToDefault() whenever there is a change to the text of the command box. commandTextField.textProperty().addListener((unused1, unused2, unused3) -> setStyleToDefault()); - initialiseAutocompleteHandler(); + if (initialiseAutocompletion) { + initialiseAutocompleteHandler(); + } } + /** * Handles the Enter button pressed event. */ @FXML - private void handleCommandEntered() { + public void handleCommandEntered() { String commandText = commandTextField.getText(); if (commandText.equals("")) { return; diff --git a/src/main/java/fasttrack/ui/MainWindow.java b/src/main/java/fasttrack/ui/MainWindow.java index 56ca14cb035..b398df58fe8 100644 --- a/src/main/java/fasttrack/ui/MainWindow.java +++ b/src/main/java/fasttrack/ui/MainWindow.java @@ -145,7 +145,7 @@ void fillInnerParts() { StatusBarFooter statusBarFooter = new StatusBarFooter(logic.getAddressBookFilePath()); statusbarPlaceholder.getChildren().add(statusBarFooter.getRoot()); - CommandBox commandBox = new CommandBox(this::executeCommand); + CommandBox commandBox = new CommandBox(this::executeCommand, true); SuggestionListPanel suggestionListPanel = new SuggestionListPanel(logic.getFilteredCategoryList(), commandBox); diff --git a/src/test/java/fasttrack/ui/CategoryCardTest.java b/src/test/java/fasttrack/ui/CategoryCardTest.java new file mode 100644 index 00000000000..9a5e3c1c5b2 --- /dev/null +++ b/src/test/java/fasttrack/ui/CategoryCardTest.java @@ -0,0 +1,87 @@ +package fasttrack.ui; + +import static fasttrack.testutil.TypicalCategories.FOOD; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.fail; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.opentest4j.AssertionFailedError; + +import fasttrack.model.category.Category; +import javafx.application.Platform; +import javafx.embed.swing.JFXPanel; +import javafx.scene.control.Label; + + +public class CategoryCardTest { + + private Category category; + private int displayedIndex; + private int associatedExpenseCount; + + @BeforeEach + public void setUp() { + category = FOOD; + displayedIndex = 1; + associatedExpenseCount = 3; + // Initialise fake JavaFX environment + new JFXPanel(); + } + + @Test + public void testCategoryCard_validData_success() { + CategoryCard categoryCard = new CategoryCard(category, displayedIndex, associatedExpenseCount); + CompletableFuture future = new CompletableFuture<>(); + Platform.runLater(() -> { + try { + // Test that the category name label is set correctly + Label categoryNameLabel = (Label) categoryCard.getRoot().lookup("#categoryName"); + assertEquals("Food", categoryNameLabel.getText()); + + // Test that the index label is set correctly + Label indexLabel = (Label) categoryCard.getRoot().lookup("#id"); + assertEquals("1. ", indexLabel.getText()); + + // Test that the expense count label is set correctly + Label expenseCountLabel = (Label) categoryCard.getRoot().lookup("#expenseCount"); + assertEquals("3", expenseCountLabel.getText()); + future.complete(null); + } catch (AssertionFailedError e) { + future.completeExceptionally(e); + } + }); + try { + future.get(); + } catch (InterruptedException | ExecutionException e) { + fail("Assertion error thrown in Platform.runLater thread: " + e.getMessage()); + } + } + + @Test + public void testEquals_validCategoryCard_success() { + CategoryCard categoryCard1 = new CategoryCard(category, displayedIndex, associatedExpenseCount); + CategoryCard categoryCard2 = new CategoryCard(category, displayedIndex + 1, associatedExpenseCount - 1); + CategoryCard categoryCard3 = new CategoryCard(category, displayedIndex + 1, associatedExpenseCount - 1); + CompletableFuture future = new CompletableFuture<>(); + Platform.runLater(() -> { + try { + assertEquals(categoryCard1, categoryCard1); + assertNotEquals(categoryCard1, categoryCard2); + assertEquals(categoryCard2, categoryCard3); + future.complete(null); + } catch (AssertionFailedError e) { + future.completeExceptionally(e); + } + }); + try { + future.get(); + } catch (InterruptedException | ExecutionException e) { + fail("Assertion error thrown in Platform.runLater thread: " + e.getMessage()); + } + } +} diff --git a/src/test/java/fasttrack/ui/CategoryListPanelTest.java b/src/test/java/fasttrack/ui/CategoryListPanelTest.java new file mode 100644 index 00000000000..1a8fcb0ac3d --- /dev/null +++ b/src/test/java/fasttrack/ui/CategoryListPanelTest.java @@ -0,0 +1,82 @@ +package fasttrack.ui; + +import static fasttrack.testutil.TypicalCategories.FOOD; +import static fasttrack.testutil.TypicalCategories.TECH; +import static fasttrack.testutil.TypicalExpenses.APPLE; +import static fasttrack.testutil.TypicalExpenses.CHERRY; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.opentest4j.AssertionFailedError; + +import fasttrack.model.category.Category; +import fasttrack.model.expense.Expense; +import javafx.application.Platform; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.embed.swing.JFXPanel; +import javafx.scene.control.ListView; + + +public class CategoryListPanelTest { + + private CategoryListPanel categoryListPanel; + private ObservableList categories; + private ObservableList expenses; + + @BeforeEach + public void setUp() { + categories = FXCollections.observableArrayList(FOOD, TECH); + expenses = FXCollections.observableArrayList(APPLE, CHERRY); + // Initialise fake JavaFX environment + new JFXPanel(); + } + + @Test + public void categoryListView_validCategories_countEqual() { + CompletableFuture future = new CompletableFuture<>(); + categoryListPanel = new CategoryListPanel(categories, expenses); + Platform.runLater(() -> { + try { + // Test that the number of categories is correct + ListView categoryListView = (ListView) categoryListPanel.getRoot().lookup("#categoryListView"); + assertEquals(categories.size(), categoryListView.getItems().size()); + future.complete(null); + } catch (AssertionFailedError e) { + future.completeExceptionally(e); + } + }); + try { + future.get(); + } catch (InterruptedException | ExecutionException e) { + fail("Assertion error thrown in Platform.runLater thread: " + e.getMessage()); + } + } + + @Test + public void categoryListView_emptyList_countZero() { + categories = FXCollections.observableArrayList(); + expenses = FXCollections.observableArrayList(); + CompletableFuture future = new CompletableFuture<>(); + categoryListPanel = new CategoryListPanel(categories, expenses); + Platform.runLater(() -> { + try { + ListView categoryListView = (ListView) categoryListPanel.getRoot().lookup("#categoryListView"); + assertEquals(0, categoryListView.getItems().size()); + future.complete(null); + } catch (AssertionFailedError e) { + future.completeExceptionally(e); + } + }); + try { + future.get(); + } catch (InterruptedException | ExecutionException e) { + fail("Assertion error thrown in Platform.runLater thread: " + e.getMessage()); + } + } +} diff --git a/src/test/java/fasttrack/ui/CommandBoxTest.java b/src/test/java/fasttrack/ui/CommandBoxTest.java new file mode 100644 index 00000000000..7df8ff03460 --- /dev/null +++ b/src/test/java/fasttrack/ui/CommandBoxTest.java @@ -0,0 +1,88 @@ +package fasttrack.ui; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Objects; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import fasttrack.logic.commands.exceptions.CommandException; +import javafx.collections.ObservableList; +import javafx.embed.swing.JFXPanel; +import javafx.scene.Scene; +import javafx.scene.control.TextField; +import javafx.scene.layout.HBox; + +public class CommandBoxTest { + + private static final String VALID_COMMAND = "add n/Milk c/Groceries p/12"; + private static final String INCOMPLETE_COMMAND = "add n/Milk c/Gro"; + private static final String ERROR_STYLE_CLASS = "error"; + + private CommandBox commandBox; + private boolean commandExecuted; + + + @BeforeEach + public void setUp() { + new JFXPanel(); + commandExecuted = false; + // Dummy command executor function + CommandBox.CommandExecutor commandExecutor = commandText -> { + if (Objects.equals(commandText, "invalid command")) { + throw new CommandException("Invalid command"); + } + commandExecuted = true; + return null; + }; + commandBox = new CommandBox(commandExecutor, false); + } + + @Test + public void handleCommandEntered_emptyCommand_commandNotExecuted() { + TextField textField = (TextField) commandBox.getRoot().lookup("#commandTextField"); + textField.setText(""); + commandBox.handleCommandEntered(); + assertFalse(commandExecuted); + } + + @Test + public void handleCommandEntered_validCommand_commandExecutedSuccessfully() { + TextField textField = (TextField) commandBox.getRoot().lookup("#commandTextField"); + textField.setText(VALID_COMMAND); + commandBox.handleCommandEntered(); + assertTrue(commandExecuted); + } + + @Test + public void handleCommandEntered_invalidCommand_setsStyleToIndicateCommandFailure() { + commandBox.getTextProperty().setValue("invalid command"); + commandBox.handleCommandEntered(); + TextField commandTextField = (TextField) commandBox.getRoot().lookup("#commandTextField"); + ObservableList styleClass = commandTextField.getStyleClass(); + assertTrue(styleClass.contains(ERROR_STYLE_CLASS)); + } + + @Test + public void setFocus_commandBox_getsFocus() { + TextField textField = (TextField) commandBox.getRoot().lookup("#commandTextField"); + HBox hbox = new HBox(); + hbox.getChildren().add(commandBox.getRoot()); + Scene scene = new Scene(hbox); + commandBox.setFocus(); + TextField focusedTextField = (TextField) scene.getFocusOwner(); + assertEquals(focusedTextField, textField); + } + + @Test + public void updateCommandBoxText_validCategoryName_updatesText() { + TextField textField = (TextField) commandBox.getRoot().lookup("#commandTextField"); + textField.setText(INCOMPLETE_COMMAND); + commandBox.updateCommandBoxText("Groceries"); + String expected = "add n/Milk c/Groceries "; + assertEquals(expected, textField.getText()); + } +} diff --git a/src/test/java/fasttrack/ui/ExpenseCardTest.java b/src/test/java/fasttrack/ui/ExpenseCardTest.java new file mode 100644 index 00000000000..ca8c643cf9a --- /dev/null +++ b/src/test/java/fasttrack/ui/ExpenseCardTest.java @@ -0,0 +1,93 @@ +package fasttrack.ui; + +import static fasttrack.testutil.TypicalExpenses.APPLE; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.fail; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.opentest4j.AssertionFailedError; + +import fasttrack.model.expense.Expense; +import javafx.application.Platform; +import javafx.embed.swing.JFXPanel; +import javafx.scene.control.Label; + +class ExpenseCardTest { + + private Expense expense; + private int displayedIndex; + + @BeforeEach + public void setUp() { + expense = APPLE; + displayedIndex = 1; + // Initialise fake JavaFX environment + new JFXPanel(); + } + + @Test + public void testExpenseCard_validData_success() { + ExpenseCard expenseCard = new ExpenseCard(expense, displayedIndex); + CompletableFuture future = new CompletableFuture<>(); + Platform.runLater(() -> { + try { + // Test that the category name label is set correctly + Label expenseNameLabel = (Label) expenseCard.getRoot().lookup("#expenseName"); + assertEquals("Apple", expenseNameLabel.getText()); + + // Test that the index label is set correctly + Label indexLabel = (Label) expenseCard.getRoot().lookup("#id"); + assertEquals("1. ", indexLabel.getText()); + + // Test that the price label is set correctly + Label priceLabel = (Label) expenseCard.getRoot().lookup("#price"); + assertEquals("$1.50", priceLabel.getText()); + + // Test that the category label is set correctly + Label categoryLabel = (Label) expenseCard.getRoot().lookup("#category"); + assertEquals("Food", categoryLabel.getText()); + + // Test that the date label is set correctly + Label frequencyLabel = (Label) expenseCard.getRoot().lookup("#date"); + assertEquals("01/03/23", frequencyLabel.getText()); + future.complete(null); + } catch (AssertionFailedError e) { + future.completeExceptionally(e); + } + }); + try { + future.get(); + } catch (InterruptedException | ExecutionException e) { + fail("Assertion error thrown in Platform.runLater thread: " + e.getMessage()); + } + } + + @Test + public void testEquals_validExpenseCard_success() { + ExpenseCard expenseCard1 = new ExpenseCard(expense, displayedIndex); + ExpenseCard expenseCard2 = new ExpenseCard(expense, displayedIndex + 1); + ExpenseCard expenseCard3 = new ExpenseCard(expense, displayedIndex + 1); + CompletableFuture future = new CompletableFuture<>(); + Platform.runLater(() -> { + try { + assertEquals(expenseCard1, expenseCard1); + assertNotEquals(expenseCard1, expenseCard2); + assertEquals(expenseCard2, expenseCard3); + future.complete(null); + } catch (AssertionFailedError e) { + future.completeExceptionally(e); + } + }); + try { + future.get(); + } catch (InterruptedException | ExecutionException e) { + fail("Assertion error thrown in Platform.runLater thread: " + e.getMessage()); + } + } + +} diff --git a/src/test/java/fasttrack/ui/ExpenseListPanelTest.java b/src/test/java/fasttrack/ui/ExpenseListPanelTest.java new file mode 100644 index 00000000000..b63e2aa5989 --- /dev/null +++ b/src/test/java/fasttrack/ui/ExpenseListPanelTest.java @@ -0,0 +1,77 @@ +package fasttrack.ui; + +import static fasttrack.testutil.TypicalExpenses.APPLE; +import static fasttrack.testutil.TypicalExpenses.BANANA; +import static fasttrack.testutil.TypicalExpenses.CHERRY; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.opentest4j.AssertionFailedError; + +import fasttrack.model.expense.Expense; +import javafx.application.Platform; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.embed.swing.JFXPanel; +import javafx.scene.control.ListView; + + +class ExpenseListPanelTest { + + private ExpenseListPanel expensePanel; + private ObservableList expenses; + + @BeforeEach + public void setUp() { + expenses = FXCollections.observableArrayList(APPLE, BANANA, CHERRY); + // Initialise fake JavaFX environment + new JFXPanel(); + } + + @Test + public void expenseListView_validExpenses_countEqual() { + expensePanel = new ExpenseListPanel(expenses); + CompletableFuture future = new CompletableFuture<>(); + Platform.runLater(() -> { + try { + // Test that the number of recurring expenses is correct + ListView expenseListView = (ListView) expensePanel.getRoot().lookup("#expenseListView"); + assertEquals(expenses.size(), expenseListView.getItems().size()); + future.complete(null); + } catch (AssertionFailedError e) { + future.completeExceptionally(e); + } + }); + try { + future.get(); + } catch (InterruptedException | ExecutionException e) { + fail("Assertion error thrown in Platform.runLater thread: " + e.getMessage()); + } + } + + @Test + public void expenseListView_validExpenses_countZero() { + expenses = FXCollections.observableArrayList(); + expensePanel = new ExpenseListPanel(expenses); + CompletableFuture future = new CompletableFuture<>(); + Platform.runLater(() -> { + try { + ListView expenseListView = (ListView) expensePanel.getRoot().lookup("#expenseListView"); + assertEquals(0, expenseListView.getItems().size()); + future.complete(null); + } catch (AssertionFailedError e) { + future.completeExceptionally(e); + } + }); + try { + future.get(); + } catch (InterruptedException | ExecutionException e) { + fail("Assertion error thrown in Platform.runLater thread: " + e.getMessage()); + } + } +} diff --git a/src/test/java/fasttrack/ui/RecurringExpenseCardTest.java b/src/test/java/fasttrack/ui/RecurringExpenseCardTest.java new file mode 100644 index 00000000000..aa57e4dc235 --- /dev/null +++ b/src/test/java/fasttrack/ui/RecurringExpenseCardTest.java @@ -0,0 +1,98 @@ +package fasttrack.ui; + +import static fasttrack.testutil.TypicalRecurringExpenses.GYM_MEMBERSHIP; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.fail; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.opentest4j.AssertionFailedError; + +import fasttrack.model.expense.RecurringExpenseManager; +import javafx.application.Platform; +import javafx.embed.swing.JFXPanel; +import javafx.scene.control.Label; + +class RecurringExpenseCardTest { + + private RecurringExpenseManager recurringExpenseManager; + private int displayedIndex; + + @BeforeEach + public void setUp() { + recurringExpenseManager = GYM_MEMBERSHIP; + displayedIndex = 1; + // Initialise fake JavaFX environment + new JFXPanel(); + } + + @Test + public void testRecurringExpenseCard_validData_success() { + RecurringExpenseCard recurringExpenseCard = new RecurringExpenseCard( + recurringExpenseManager, displayedIndex); + CompletableFuture future = new CompletableFuture<>(); + Platform.runLater(() -> { + try { + // Test that the category name label is set correctly + Label expenseNameLabel = (Label) recurringExpenseCard.getRoot().lookup("#expenseName"); + assertEquals("Gym Membership", expenseNameLabel.getText()); + + // Test that the index label is set correctly + Label indexLabel = (Label) recurringExpenseCard.getRoot().lookup("#id"); + assertEquals("1. ", indexLabel.getText()); + + // Test that the price label is set correctly + Label priceLabel = (Label) recurringExpenseCard.getRoot().lookup("#price"); + assertEquals("$50.00", priceLabel.getText()); + + // Test that the category label is set correctly + Label categoryLabel = (Label) recurringExpenseCard.getRoot().lookup("#category"); + assertEquals("Fitness", categoryLabel.getText()); + + // Test that the frequency label is set correctly + Label frequencyLabel = (Label) recurringExpenseCard.getRoot().lookup("#frequency"); + assertEquals("Monthly", frequencyLabel.getText()); + future.complete(null); + } catch (AssertionFailedError e) { + future.completeExceptionally(e); + } + }); + try { + future.get(); + } catch (InterruptedException | ExecutionException e) { + fail("Assertion error thrown in Platform.runLater thread: " + e.getMessage()); + } + } + + @Test + public void testEquals_validRecurringExpenseCard_success() { + RecurringExpenseCard recurringExpenseCard1 = new RecurringExpenseCard( + recurringExpenseManager, displayedIndex); + RecurringExpenseCard recurringExpenseCard2 = new RecurringExpenseCard( + recurringExpenseManager, displayedIndex + 1); + RecurringExpenseCard recurringExpenseCard3 = new RecurringExpenseCard( + recurringExpenseManager, displayedIndex + 1); + CompletableFuture future = new CompletableFuture<>(); + + Platform.runLater(() -> { + try { + assertEquals(recurringExpenseCard1, recurringExpenseCard1); + assertNotEquals(recurringExpenseCard1, recurringExpenseCard2); + assertEquals(recurringExpenseCard2, recurringExpenseCard3); + future.complete(null); + } catch (AssertionFailedError e) { + future.completeExceptionally(e); + } + }); + try { + future.get(); + } catch (InterruptedException | ExecutionException e) { + fail("Assertion error thrown in Platform.runLater thread: " + e.getMessage()); + } + } + +} diff --git a/src/test/java/fasttrack/ui/RecurringExpensePanelTest.java b/src/test/java/fasttrack/ui/RecurringExpensePanelTest.java new file mode 100644 index 00000000000..8b3d76197ac --- /dev/null +++ b/src/test/java/fasttrack/ui/RecurringExpensePanelTest.java @@ -0,0 +1,80 @@ +package fasttrack.ui; + +import static fasttrack.testutil.TypicalRecurringExpenses.GYM_MEMBERSHIP; +import static fasttrack.testutil.TypicalRecurringExpenses.NETFLIX_SUBSCRIPTION; +import static fasttrack.testutil.TypicalRecurringExpenses.RENT; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.opentest4j.AssertionFailedError; + +import fasttrack.model.expense.RecurringExpenseManager; +import javafx.application.Platform; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.embed.swing.JFXPanel; +import javafx.scene.control.ListView; + + +class RecurringExpensePanelTest { + + private RecurringExpensePanel recurringExpensePanel; + private ObservableList recurringExpenses; + + @BeforeEach + public void setUp() { + recurringExpenses = FXCollections.observableArrayList(GYM_MEMBERSHIP, NETFLIX_SUBSCRIPTION, RENT); + // Initialise fake JavaFX environment + new JFXPanel(); + } + + @Test + public void recurringExpenseListView_validExpenses_countEqual() { + recurringExpensePanel = new RecurringExpensePanel(recurringExpenses); + CompletableFuture future = new CompletableFuture<>(); + Platform.runLater(() -> { + try { + // Test that the number of recurring expenses is correct + ListView recurringExpenseListView = (ListView) recurringExpensePanel + .getRoot().lookup("#recurringExpenseListView"); + assertEquals(recurringExpenses.size(), recurringExpenseListView.getItems().size()); + future.complete(null); + } catch (AssertionFailedError e) { + future.completeExceptionally(e); + } + }); + try { + future.get(); + } catch (InterruptedException | ExecutionException e) { + fail("Assertion error thrown in Platform.runLater thread: " + e.getMessage()); + } + } + + @Test + public void recurringExpenseListView_validExpenses_countZero() { + recurringExpenses = FXCollections.observableArrayList(); + RecurringExpensePanel recurringExpensePanel = new RecurringExpensePanel(recurringExpenses); + CompletableFuture future = new CompletableFuture<>(); + Platform.runLater(() -> { + try { + ListView recurringExpenseListView = (ListView) recurringExpensePanel + .getRoot().lookup("#recurringExpenseListView"); + assertEquals(0, recurringExpenseListView.getItems().size()); + future.complete(null); + } catch (AssertionFailedError e) { + future.completeExceptionally(e); + } + }); + try { + future.get(); + } catch (InterruptedException | ExecutionException e) { + fail("Assertion error thrown in Platform.runLater thread: " + e.getMessage()); + } + } + +}