Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added test cases for parser util, add expense parser #224

Merged
merged 2 commits into from
Apr 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/main/java/fasttrack/commons/core/Messages.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ public class Messages {
public static final String MESSAGE_UNKNOWN_COMMAND = "Unknown command";
public static final String MESSAGE_EXPENSES_LISTED_OVERVIEW = "%1$d expenses listed";

public static final String MESSAGE_INVALID_DATE_FORMAT = "Date should be of the form D/M/YY";

public static final String MESSAGE_INVALID_COMMAND_FORMAT = "Invalid command format! \n%1$s";
public static final String MESSAGE_INVALID_INDEX = "The index provided is invalid.";
public static final String MESSAGE_INVALID_CATEGORY_DISPLAYED_INDEX = "The category index provided is invalid!";
Expand Down
6 changes: 0 additions & 6 deletions src/main/java/fasttrack/logic/parser/CliSyntax.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,6 @@ public class CliSyntax {

/* Prefix definitions */
public static final Prefix PREFIX_NAME = new Prefix("n/");
public static final Prefix PREFIX_PHONE = new Prefix("p/");
public static final Prefix PREFIX_EMAIL = new Prefix("e/");
public static final Prefix PREFIX_ADDRESS = new Prefix("a/");
public static final Prefix PREFIX_REMARK = new Prefix("r/");
// PREFIX_TAG seems to only be used in AddressBook, I'll hijack the t/ for timespan
public static final Prefix PREFIX_TAG = new Prefix("tag/");
public static final Prefix PREFIX_CATEGORY = new Prefix("c/");
public static final Prefix PREFIX_SUMMARY = new Prefix("s/");
public static final Prefix PREFIX_PRICE = new Prefix("p/");
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/fasttrack/logic/parser/ParserUtil.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package fasttrack.logic.parser;

import static fasttrack.commons.core.Messages.MESSAGE_INVALID_DATE_FORMAT;
import static java.util.Objects.requireNonNull;

import java.time.DayOfWeek;
Expand Down Expand Up @@ -126,7 +127,7 @@ public static LocalDate parseDate(String dateString) throws ParseException {
try {
parsedDate = CommandUtility.parseDateFromUserInput(trimmedDate);
} catch (IllegalArgumentException e) {
throw new ParseException("Date should be of the form D/M/YY");
throw new ParseException(MESSAGE_INVALID_DATE_FORMAT);
}
return parsedDate;
}
Expand Down
86 changes: 51 additions & 35 deletions src/test/java/fasttrack/logic/commands/CommandTestUtil.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package fasttrack.logic.commands;

import static fasttrack.logic.parser.CliSyntax.PREFIX_ADDRESS;
import static fasttrack.logic.parser.CliSyntax.PREFIX_EMAIL;
import static fasttrack.logic.parser.CliSyntax.PREFIX_CATEGORY;
import static fasttrack.logic.parser.CliSyntax.PREFIX_DATE;
import static fasttrack.logic.parser.CliSyntax.PREFIX_NAME;
import static fasttrack.logic.parser.CliSyntax.PREFIX_PHONE;
import static fasttrack.logic.parser.CliSyntax.PREFIX_TAG;
import static fasttrack.logic.parser.CliSyntax.PREFIX_PRICE;
import static fasttrack.testutil.Assert.assertThrows;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
Expand All @@ -24,35 +23,52 @@
*/
public class CommandTestUtil {

public static final String VALID_NAME_AMY = "Amy Bee";
public static final String VALID_NAME_BOB = "Bob Choo";
public static final String VALID_PHONE_AMY = "11111111";
public static final String VALID_PHONE_BOB = "22222222";
public static final String VALID_EMAIL_AMY = "amy@example.com";
public static final String VALID_EMAIL_BOB = "bob@example.com";
public static final String VALID_ADDRESS_AMY = "Block 312, Amy Street 1";
public static final String VALID_ADDRESS_BOB = "Block 123, Bobby Street 3";
public static final String VALID_TAG_HUSBAND = "husband";
public static final String VALID_TAG_FRIEND = "friend";
public static final String VALID_REMARK_AMY = "Like skiing.";
public static final String VALID_REMARK_BOB = "Favourite pastime: Eating";

public static final String NAME_DESC_AMY = " " + PREFIX_NAME + VALID_NAME_AMY;
public static final String NAME_DESC_BOB = " " + PREFIX_NAME + VALID_NAME_BOB;
public static final String PHONE_DESC_AMY = " " + PREFIX_PHONE + VALID_PHONE_AMY;
public static final String PHONE_DESC_BOB = " " + PREFIX_PHONE + VALID_PHONE_BOB;
public static final String EMAIL_DESC_AMY = " " + PREFIX_EMAIL + VALID_EMAIL_AMY;
public static final String EMAIL_DESC_BOB = " " + PREFIX_EMAIL + VALID_EMAIL_BOB;
public static final String ADDRESS_DESC_AMY = " " + PREFIX_ADDRESS + VALID_ADDRESS_AMY;
public static final String ADDRESS_DESC_BOB = " " + PREFIX_ADDRESS + VALID_ADDRESS_BOB;
public static final String TAG_DESC_FRIEND = " " + PREFIX_TAG + VALID_TAG_FRIEND;
public static final String TAG_DESC_HUSBAND = " " + PREFIX_TAG + VALID_TAG_HUSBAND;

public static final String INVALID_NAME_DESC = " " + PREFIX_NAME + "James&"; // '&' not allowed in names
public static final String INVALID_PHONE_DESC = " " + PREFIX_PHONE + "911a"; // 'a' not allowed in phones
public static final String INVALID_EMAIL_DESC = " " + PREFIX_EMAIL + "bob!yahoo"; // missing '@' symbol
public static final String INVALID_ADDRESS_DESC = " " + PREFIX_ADDRESS; // empty string not allowed for addresses
public static final String INVALID_TAG_DESC = " " + PREFIX_TAG + "hubby*"; // '*' not allowed in tags
public static final String VALID_NAME_APPLE = "Apple";
public static final String VALID_NAME_BANANA = "Banana";
public static final String VALID_NAME_CHERRY = "Cherry";
public static final String VALID_NAME_DURIAN = "Durian";
public static final String VALID_NAME_ELDERBERRY = "Elderberry";
public static final String VALID_NAME_FIG = "Fig";
public static final String VALID_NAME_GRAPE = "Grape";

public static final double VALID_PRICE_APPLE = 1.50;
public static final double VALID_PRICE_BANANA = 1.00;
public static final double VALID_PRICE_CHERRY = 0.20;
public static final double VALID_PRICE_DURIAN = 15.0;
public static final double VALID_PRICE_ELDERBERRY = 4.0;
public static final double VALID_PRICE_FIG = 1000.0;
public static final double VALID_PRICE_GRAPE = 10.0;

public static final String VALID_CATEGORY_FOOD = "food";
public static final String VALID_CATEGORY_TECH = "tech";
public static final String VALID_CATEGORY_SCHOOL = "school";


public static final String VALID_DATE_APPLE = "1/3/2023";
public static final String VALID_DATE_BANANA = "2/3/2023";
public static final String VALID_DATE_CHERRY = "1/3/2023";
public static final String VALID_DATE_DURIAN = "15/3/2023";
public static final String VALID_DATE_ELDERBERRY = "1/1/2023";
public static final String VALID_DATE_FIG = "15/2/2023";
public static final String VALID_DATE_GRAPE = "17/3/2023";

public static final String DESC_APPLE = " " + PREFIX_NAME + VALID_NAME_APPLE;
public static final String AMT_APPLE = " " + PREFIX_PRICE + VALID_PRICE_APPLE;
public static final String DATE_APPLE = " " + PREFIX_DATE + VALID_DATE_APPLE;
public static final String CAT_APPLE = " " + PREFIX_CATEGORY + VALID_CATEGORY_FOOD;

public static final String DESC_BANANA = " " + PREFIX_NAME + VALID_NAME_BANANA;
public static final String AMT_BANANA = " " + PREFIX_PRICE + VALID_PRICE_BANANA;
public static final String DATE_BANANA = " " + PREFIX_DATE + VALID_DATE_BANANA;
public static final String CAT_BANANA = " " + PREFIX_CATEGORY + VALID_CATEGORY_FOOD;


public static final String INVALID_AMOUNT_DESC = " " + PREFIX_PRICE + "10x";
// non-numeric character not allowed in amount
public static final String INVALID_DATE_FORMAT_DESC = " " + PREFIX_DATE + "2023/04/10";
// invalid date format
public static final String INVALID_CATEGORY_DESC = " " + PREFIX_CATEGORY + "food@";
// symbols in category not allowed

public static final String PREAMBLE_WHITESPACE = "\t \r \n";
public static final String PREAMBLE_NON_EMPTY = "NonEmptyPreamble";
Expand All @@ -64,7 +80,8 @@ public class CommandTestUtil {
* <br>
* - the {@code actualModel} matches {@code expectedModel}
*/
public static void assertCommandSuccess(Command command, Model actualDataModel, CommandResult expectedCommandResult,
public static void assertCommandSuccess(Command command, Model actualDataModel,
CommandResult expectedCommandResult,
Model expectedDataModel) {
try {
CommandResult result = command.execute(actualDataModel);
Expand Down Expand Up @@ -116,7 +133,6 @@ public static void showExpenseAtIndex(Model dataModel, Index targetIndex) {
final String name = expense.getName();
//TODO update predicates here when created
//model.updateFilteredExpensesList(new NameContainsKeywordsPredicate(Arrays.asList(name)));

assertEquals(1, dataModel.getFilteredExpenseList().size());
}

Expand Down
138 changes: 138 additions & 0 deletions src/test/java/fasttrack/logic/parser/ParserUtilTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package fasttrack.logic.parser;

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

import java.time.DayOfWeek;
import java.time.LocalDate;

import org.junit.jupiter.api.Test;

import fasttrack.commons.core.index.Index;
import fasttrack.logic.parser.exceptions.ParseException;
import fasttrack.model.expense.Price;
import fasttrack.model.expense.RecurringExpenseType;


public class ParserUtilTest {

@Test
public void parseIndex_validInput_success() throws ParseException {
assertEquals(Index.fromOneBased(1), ParserUtil.parseIndex(" 1 "));
assertEquals(Index.fromOneBased(2), ParserUtil.parseIndex("2"));
}

@Test
public void parseIndex_invalidInput_throwsParseException() {
// empty string
assertThrows(ParseException.class, () -> ParserUtil.parseIndex(""));
// string based input
assertThrows(ParseException.class, () -> ParserUtil.parseIndex("one"));
assertThrows(ParseException.class, () -> ParserUtil.parseIndex("0"));
assertThrows(ParseException.class, () -> ParserUtil.parseIndex("-1"));
}

@Test
public void parseExpenseName_nullInput_throwsNullPointerException() {
assertThrows(NullPointerException.class, () -> ParserUtil.parseExpenseName(null));
}

@Test
public void parseExpenseName_validInput_success() throws ParseException {
assertEquals("milk", ParserUtil.parseExpenseName(" milk "));
}

@Test
public void parseExpenseName_invalidInput_throwsParseException() {
assertThrows(ParseException.class, () -> ParserUtil.parseExpenseName(""));
}

@Test
public void parsePrice_nullInput_throwsNullPointerException() {
assertThrows(NullPointerException.class, () -> ParserUtil.parsePrice(null));
}

@Test
public void parsePrice_validInput_success() throws ParseException {
assertEquals(new Price("1.23"), ParserUtil.parsePrice(" 1.23 "));
}

@Test
public void parsePrice_invalidInput_throwsParseException() {
assertThrows(ParseException.class, () -> ParserUtil.parsePrice(""));
assertThrows(ParseException.class, () -> ParserUtil.parsePrice("-1.23"));
assertThrows(ParseException.class, () -> ParserUtil.parsePrice("one"));
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 parseCategory_invalidInput_throwsParseException() {
// empty category name
assertThrows(ParseException.class, () -> ParserUtil.parseCategory(""));
assertThrows(ParseException.class, () -> ParserUtil.parseCategory("@food"));
}


@Test
void parseDate_validInput_success() throws ParseException {
LocalDate date = ParserUtil.parseDate("22/3/2023");
assertEquals(LocalDate.parse("2023-03-22"), date);
}

@Test
void parseDate_invalidInput_throwsParseException() {
assertThrows(ParseException.class, () -> {
ParserUtil.parseDate("2023/03/14");
});
}

@Test
void parseTimespan_validInput_success() throws ParseException {
assertEquals(ParserUtil.Timespan.WEEK, ParserUtil.parseTimespan("week"));
assertEquals(ParserUtil.Timespan.MONTH, ParserUtil.parseTimespan("month"));
assertEquals(ParserUtil.Timespan.YEAR, ParserUtil.parseTimespan("year"));
assertEquals(ParserUtil.Timespan.WEEK, ParserUtil.parseTimespan("w"));
assertEquals(ParserUtil.Timespan.MONTH, ParserUtil.parseTimespan("m"));
assertEquals(ParserUtil.Timespan.YEAR, ParserUtil.parseTimespan("y"));
}

@Test
void parseTimespan_invalidInput_throwsParseException() {
assertThrows(ParseException.class, () -> {
ParserUtil.parseTimespan("wk");
});
}

@Test
void parseTimeSpanRecurringExpense_validInput_success() throws ParseException {
assertEquals(RecurringExpenseType.DAILY, ParserUtil.parseTimeSpanRecurringExpense("day"));
assertEquals(RecurringExpenseType.WEEKLY, ParserUtil.parseTimeSpanRecurringExpense("week"));
assertEquals(RecurringExpenseType.MONTHLY, ParserUtil.parseTimeSpanRecurringExpense("month"));
assertEquals(RecurringExpenseType.YEARLY, ParserUtil.parseTimeSpanRecurringExpense("year"));
assertEquals(RecurringExpenseType.DAILY, ParserUtil.parseTimeSpanRecurringExpense("d"));
assertEquals(RecurringExpenseType.WEEKLY, ParserUtil.parseTimeSpanRecurringExpense("w"));
assertEquals(RecurringExpenseType.MONTHLY, ParserUtil.parseTimeSpanRecurringExpense("m"));
assertEquals(RecurringExpenseType.YEARLY, ParserUtil.parseTimeSpanRecurringExpense("y"));
}

@Test
void getDateByTimespan_validInput_success() {
LocalDate expectedWeekDate = LocalDate.now().with(DayOfWeek.MONDAY);
LocalDate expectedMonthDate = LocalDate.now().withDayOfMonth(1);
LocalDate expectedYearDate = LocalDate.now().withDayOfYear(1);
assertEquals(expectedWeekDate, ParserUtil.getDateByTimespan(ParserUtil.Timespan.WEEK));
assertEquals(expectedMonthDate, ParserUtil.getDateByTimespan(ParserUtil.Timespan.MONTH));
assertEquals(expectedYearDate, ParserUtil.getDateByTimespan(ParserUtil.Timespan.YEAR));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package fasttrack.logic.parser.add;

import static fasttrack.commons.core.Messages.MESSAGE_INVALID_DATE_FORMAT;
import static fasttrack.logic.commands.CommandTestUtil.AMT_APPLE;
import static fasttrack.logic.commands.CommandTestUtil.AMT_BANANA;
import static fasttrack.logic.commands.CommandTestUtil.CAT_APPLE;
import static fasttrack.logic.commands.CommandTestUtil.CAT_BANANA;
import static fasttrack.logic.commands.CommandTestUtil.DATE_APPLE;
import static fasttrack.logic.commands.CommandTestUtil.DATE_BANANA;
import static fasttrack.logic.commands.CommandTestUtil.DESC_APPLE;
import static fasttrack.logic.commands.CommandTestUtil.DESC_BANANA;
import static fasttrack.logic.commands.CommandTestUtil.INVALID_AMOUNT_DESC;
import static fasttrack.logic.commands.CommandTestUtil.INVALID_CATEGORY_DESC;
import static fasttrack.logic.commands.CommandTestUtil.INVALID_DATE_FORMAT_DESC;
import static fasttrack.logic.parser.CommandParserTestUtil.assertParseFailure;
import static fasttrack.logic.parser.CommandParserTestUtil.assertParseSuccess;
import static fasttrack.testutil.TypicalExpenses.APPLE;
import static fasttrack.testutil.TypicalExpenses.BANANA;

import org.junit.jupiter.api.Test;

import fasttrack.logic.commands.add.AddExpenseCommand;
import fasttrack.model.category.Category;
import fasttrack.model.expense.Price;


class AddExpenseCommandParserTest {

private final AddExpenseCommandParser parser = new AddExpenseCommandParser();

@Test
void parse_validArgs_returnsAddExpenseCommand() {
String input1 = DESC_APPLE + AMT_APPLE + DATE_APPLE + CAT_APPLE;
AddExpenseCommand expectedCommand1 = new AddExpenseCommand(APPLE);
assertParseSuccess(parser, input1, expectedCommand1);

String input2 = DESC_BANANA + AMT_BANANA + CAT_BANANA + DATE_BANANA;
AddExpenseCommand expectedCommand2 = new AddExpenseCommand(BANANA);
assertParseSuccess(parser, input2, expectedCommand2);
}

@Test
void parse_invalidValue_throwsParseException() {
// invalid category name (with alphanumeric)
String input1 = DESC_APPLE + AMT_APPLE + DATE_APPLE + INVALID_CATEGORY_DESC;
assertParseFailure(parser, input1, Category.MESSAGE_CONSTRAINTS);

// invalid date format
String input2 = DESC_APPLE + AMT_APPLE + INVALID_DATE_FORMAT_DESC + CAT_APPLE;
assertParseFailure(parser, input2, MESSAGE_INVALID_DATE_FORMAT);

// invalid price
String input3 = DESC_APPLE + INVALID_AMOUNT_DESC + DATE_APPLE + CAT_APPLE;
assertParseFailure(parser, input3, Price.MESSAGE_CONSTRAINTS);
}
}
7 changes: 7 additions & 0 deletions src/test/java/fasttrack/testutil/TypicalCategories.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,11 @@ public class TypicalCategories {
public static final Category FOOD = new UserDefinedCategory("food", "For consumable expenses");
public static final Category TECH = new UserDefinedCategory("tech", "For electronics");
public static final Category SCHOOL = new UserDefinedCategory("school", "School expenses");
public static final Category FITNESS = new UserDefinedCategory("fitness", "for fitness related expenses");
public static final Category ENTERTAINMENT = new UserDefinedCategory("entertainment",
"for entertainment expenses");
public static final Category HOUSING = new UserDefinedCategory("housing", "housing payments");
public static final Category UTILITIES = new UserDefinedCategory("utilities", "utility bills");


}
36 changes: 36 additions & 0 deletions src/test/java/fasttrack/testutil/TypicalRecurringExpenses.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package fasttrack.testutil;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import fasttrack.model.expense.RecurringExpenseManager;
import fasttrack.model.expense.RecurringExpenseType;


/**
* A utility class containing a list of {@code RecurringExpenseManager} objects to be used in tests.
*/
public class TypicalRecurringExpenses {

public static final RecurringExpenseManager GYM_MEMBERSHIP =
new RecurringExpenseManager("Gym Membership", 50, TypicalCategories.FITNESS,
LocalDate.of(2023, 4, 1), null, RecurringExpenseType.MONTHLY);
public static final RecurringExpenseManager NETFLIX_SUBSCRIPTION =
new RecurringExpenseManager("Netflix Subscription", 15, TypicalCategories.ENTERTAINMENT,
LocalDate.of(2023, 2, 20), null, RecurringExpenseType.MONTHLY);
public static final RecurringExpenseManager RENT =
new RecurringExpenseManager("Rent", 800, TypicalCategories.HOUSING,
LocalDate.of(2023, 1, 15), null, RecurringExpenseType.MONTHLY);
public static final RecurringExpenseManager INTERNET =
new RecurringExpenseManager("Water", 60, TypicalCategories.UTILITIES,
LocalDate.of(2023, 4, 1), LocalDate.of(2026, 4, 1), RecurringExpenseType.MONTHLY);

private TypicalRecurringExpenses() {} // prevents instantiation

public static List<RecurringExpenseManager> getTypicalRecurringExpenses() {
return new ArrayList<>(Arrays.asList(GYM_MEMBERSHIP, NETFLIX_SUBSCRIPTION, RENT, INTERNET));
}
}