diff --git a/.gitignore b/.gitignore index b1159f3584..b1ef1c1736 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,5 @@ bin/ /text-ui-test/ACTUAL.TXT text-ui-test/EXPECTED-UNIX.TXT META-INF/MANIFEST.MF -data/menu.txt -data/pantry_stock.txt -data/orders.txt +data/ + diff --git a/src/main/java/seedu/cafectrl/parser/Parser.java b/src/main/java/seedu/cafectrl/parser/Parser.java index cca229192d..fc363a5281 100644 --- a/src/main/java/seedu/cafectrl/parser/Parser.java +++ b/src/main/java/seedu/cafectrl/parser/Parser.java @@ -23,6 +23,7 @@ import seedu.cafectrl.data.Order; import seedu.cafectrl.data.OrderList; import seedu.cafectrl.data.Pantry; +import seedu.cafectrl.parser.exception.ParserException; import seedu.cafectrl.ui.ErrorMessages; import seedu.cafectrl.ui.Messages; import seedu.cafectrl.data.Menu; @@ -35,6 +36,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; + /** * Parse everything received from the users on terminal * into a format that can be interpreted by other core classes @@ -183,7 +185,7 @@ private static Command prepareEditPriceCommand(Menu menu, String arguments, Ui u return new IncorrectCommand(ErrorMessages.INVALID_DISH_INDEX, ui); } return new EditPriceCommand(dishIndex, newPrice, menu, ui); - } catch (IllegalArgumentException e) { + } catch (ParserException e) { return new IncorrectCommand(ErrorMessages.WRONG_ARGUMENT_TYPE_FOR_EDIT_PRICE, ui); } } @@ -210,8 +212,12 @@ private static Command prepareAdd(String arguments, Menu menu, Ui ui) { float price = parsePriceToFloat(matcher.group(PRICE_MATCHER_GROUP_LABEL)); String ingredientsListString = matcher.group(INGREDIENTS_MATCHER_GROUP_LABEL); + if (isNameLengthInvalid(dishName)) { + throw new ParserException(ErrorMessages.INVALID_DISH_NAME_LENGTH_MESSAGE); + } + if (isRepeatedDishName(dishName, menu)) { - return new IncorrectCommand(Messages.REPEATED_DISH_MESSAGE, ui); + throw new ParserException(Messages.REPEATED_DISH_MESSAGE); } ArrayList ingredients = parseIngredients(ingredientsListString); @@ -219,13 +225,10 @@ private static Command prepareAdd(String arguments, Menu menu, Ui ui) { Dish dish = new Dish(dishName, ingredients, price); return new AddDishCommand(dish, menu, ui); - } catch (IllegalArgumentException e) { - return new IncorrectCommand(ErrorMessages.INVALID_ADD_DISH_FORMAT_MESSAGE - + AddDishCommand.MESSAGE_USAGE, ui); - } catch (ArithmeticException e) { - return new IncorrectCommand(ErrorMessages.INVALID_PRICE_MESSAGE, ui); } catch (NullPointerException e) { - return new IncorrectCommand(ErrorMessages.NULL_DISH_NAME_MESSAGE, ui); + return new IncorrectCommand(ErrorMessages.NULL_NAME_DETECTED_MESSAGE, ui); + } catch (Exception e) { + return new IncorrectCommand(e.getMessage(), ui); } } @@ -234,9 +237,10 @@ private static Command prepareAdd(String arguments, Menu menu, Ui ui) { * @param ingredientsListString user's input string of ingredients, multiple ingredients seperated by ',' is allowed * @return Ingredient objects that consists of the dish * @throws IllegalArgumentException if the input string of ingredients is in an incorrect format. + * @throws ParserException if the input string does not match the constraints */ private static ArrayList parseIngredients(String ingredientsListString) - throws IllegalArgumentException { + throws IllegalArgumentException, ParserException { String[] inputIngredientList = {ingredientsListString}; ArrayList ingredients = new ArrayList<>(); @@ -252,7 +256,8 @@ private static ArrayList parseIngredients(String ingredientsListStri Matcher ingredientMatcher = ingredientPattern.matcher(inputIngredient); if (!ingredientMatcher.matches()) { - throw new IllegalArgumentException(); + throw new ParserException(ErrorMessages.INVALID_ADD_DISH_FORMAT_MESSAGE + + AddDishCommand.MESSAGE_USAGE); } String ingredientName = ingredientMatcher.group(INGREDIENT_NAME_REGEX_GROUP_LABEL).trim(); @@ -261,6 +266,10 @@ private static ArrayList parseIngredients(String ingredientsListStri int ingredientQty = Integer.parseInt(ingredientQtyString); + if (isNameLengthInvalid(ingredientName)) { + throw new ParserException(ErrorMessages.INVALID_INGREDIENT_NAME_LENGTH_MESSAGE); + } + Ingredient ingredient = new Ingredient(ingredientName, ingredientQty, ingredientUnit); ingredients.add(ingredient); @@ -275,12 +284,12 @@ private static ArrayList parseIngredients(String ingredientsListStri * @return price in float format * @throws ArithmeticException if price > 10000000000.00 */ - public static float parsePriceToFloat(String priceText) throws ArithmeticException { + static float parsePriceToFloat(String priceText) throws ParserException { float price = Float.parseFloat(priceText); float maxPriceValue = (float) 10000000000.00; if (price > maxPriceValue) { - throw new ArithmeticException(); + throw new ParserException(ErrorMessages.INVALID_PRICE_MESSAGE); } return price; @@ -291,8 +300,9 @@ public static float parsePriceToFloat(String priceText) throws ArithmeticExcepti * @param inputDishName dish name entered by the user * @param menu contains all the existing Dishes * @return boolean of whether a repeated dish name is detected + * @throws NullPointerException if the input string is null */ - public static boolean isRepeatedDishName(String inputDishName, Menu menu) throws NullPointerException { + static boolean isRepeatedDishName(String inputDishName, Menu menu) throws NullPointerException { if (inputDishName == null) { throw new NullPointerException(); } @@ -309,6 +319,26 @@ public static boolean isRepeatedDishName(String inputDishName, Menu menu) throws return false; } + /** + * Checks the length of the name is too long + * @param inputName name + * @return boolean of whether the name is more than max character limit set + * @throws NullPointerException if the input string is null + */ + static boolean isNameLengthInvalid(String inputName) throws NullPointerException { + int maxNameLength = 35; + + if (inputName == null) { + throw new NullPointerException(); + } + + if (inputName.length() > maxNameLength) { + return true; + } + + return false; + } + //@@author NaychiMin /** * Parses arguments in the context of the ListIngredient command. @@ -376,7 +406,6 @@ private static Command prepareBuyIngredient(String arguments, Ui ui, Pantry pant String ingredientsListString = matcher.group(0); - try { ArrayList ingredients = parseIngredients(ingredientsListString); return new BuyIngredientCommand(ingredients, ui, pantry); diff --git a/src/main/java/seedu/cafectrl/parser/exception/ParserException.java b/src/main/java/seedu/cafectrl/parser/exception/ParserException.java new file mode 100644 index 0000000000..05eebe2303 --- /dev/null +++ b/src/main/java/seedu/cafectrl/parser/exception/ParserException.java @@ -0,0 +1,12 @@ +package seedu.cafectrl.parser.exception; +/** + * Represents a parse error encountered by parser. + */ +public class ParserException extends Exception { + /** + * @param errorMessage contains relevant information on failed constraint(s) + */ + public ParserException(String errorMessage) { + super(errorMessage); + } +} diff --git a/src/main/java/seedu/cafectrl/ui/ErrorMessages.java b/src/main/java/seedu/cafectrl/ui/ErrorMessages.java index 926feeff1a..5f3d5352c9 100644 --- a/src/main/java/seedu/cafectrl/ui/ErrorMessages.java +++ b/src/main/java/seedu/cafectrl/ui/ErrorMessages.java @@ -3,8 +3,10 @@ public class ErrorMessages { /** Error messages */ public static final String INVALID_ADD_DISH_FORMAT_MESSAGE = "Error: Incorrect format for the add command.\n"; - public static final String NULL_DISH_NAME_MESSAGE = "Error: Null dish name detected"; + public static final String NULL_NAME_DETECTED_MESSAGE = "Error: Null dish name detected"; public static final String INVALID_PRICE_MESSAGE = "Error: Price value entered is too big!"; + public static final String INVALID_DISH_NAME_LENGTH_MESSAGE = "Error: Your dish name length is too long!"; + public static final String INVALID_INGREDIENT_NAME_LENGTH_MESSAGE = "Error: Your dish name length is too long!"; public static final String MISSING_ARGUMENT_FOR_EDIT_PRICE = "Error: Missing arguments " + "for edit price command."; public static final String MISSING_ARGUMENT_FOR_LIST_INGREDIENTS = "Error: Missing arguments " diff --git a/src/test/java/seedu/cafectrl/parser/ParserTest.java b/src/test/java/seedu/cafectrl/parser/ParserTest.java index b99b36258b..88097fb80d 100644 --- a/src/test/java/seedu/cafectrl/parser/ParserTest.java +++ b/src/test/java/seedu/cafectrl/parser/ParserTest.java @@ -15,6 +15,7 @@ import seedu.cafectrl.data.Sales; import seedu.cafectrl.data.dish.Dish; import seedu.cafectrl.data.dish.Ingredient; +import seedu.cafectrl.parser.exception.ParserException; import seedu.cafectrl.ui.ErrorMessages; import seedu.cafectrl.ui.Ui; @@ -441,17 +442,17 @@ void parseCommand_whitespaceBetweenArgumentsForAddDish_dishAddedToMenu() { } @Test - void parsePriceToFloat_validPriceString_exactFloatPrice() { + void parsePriceToFloat_validPriceString_exactFloatPrice() throws ParserException { String inputPriceString = "3.14"; assertEquals((float) 3.14, Parser.parsePriceToFloat(inputPriceString)); } @Test - void parsePriceToFloat_largePriceString_arithmeticExceptionThrown() throws ArithmeticException { + void parsePriceToFloat_largePriceString_arithmeticExceptionThrown() throws ParserException { String inputPriceString = "99999999999.99"; - assertThrows(ArithmeticException.class, () -> Parser.parsePriceToFloat(inputPriceString)); + assertThrows(ParserException.class, () -> Parser.parsePriceToFloat(inputPriceString)); } @Test @@ -496,6 +497,20 @@ void isRepeatedDishName_emptyDishName_false() { assertFalse(Parser.isRepeatedDishName(inputDishName, menu)); } + @Test + void isNameLengthInvalid_moreThanMaxLengthString_true() { + assertTrue(Parser.isNameLengthInvalid("this string is more than 35 characters")); + } + + @Test + void isNameLengthInvalid_lessThanMaxLengthString_false() { + assertFalse(Parser.isNameLengthInvalid("this str is less than 35 chars")); + } + + @Test + void isNameLengthInvalid_nullString_nullPointerExceptionThrown() throws NullPointerException { + assertThrows(NullPointerException.class, () ->Parser.isNameLengthInvalid(null)); + } //@@author ShaniceTang @Test