From 81c4fec6216f04488970293309f0bb1197f8633b Mon Sep 17 00:00:00 2001 From: justinlengch Date: Wed, 3 Apr 2024 20:21:03 +0800 Subject: [PATCH 1/2] Update lesson class to use arraylist, and add schedule lesson command --- .../address/logic/commands/AddCommand.java | 8 +- .../logic/commands/AddLessonCommand.java | 84 +++++++++++++++++++ .../address/logic/commands/EditCommand.java | 19 ++--- .../address/logic/commands/RemarkCommand.java | 2 +- .../logic/parser/AddCommandParser.java | 6 +- .../logic/parser/AddLessonCommandParser.java | 82 ++++++++++++++++++ .../logic/parser/AddressBookParser.java | 5 ++ .../logic/parser/EditCommandParser.java | 14 ++-- .../address/logic/parser/ParserUtil.java | 70 ++++++++++------ .../seedu/address/model/student/Lesson.java | 77 ++++++++++------- .../seedu/address/model/student/Student.java | 31 ++++--- .../seedu/address/model/student/Subject.java | 2 +- .../address/model/util/SampleDataUtil.java | 39 +++++---- .../address/storage/JsonAdaptedLesson.java | 64 ++++++++++++-- .../address/storage/JsonAdaptedStudent.java | 12 +-- .../invalidAndValidStudentAddressBook.json | 4 +- .../invalidStudentAddressBook.json | 2 +- .../duplicateStudentAddressBook.json | 4 +- .../typicalStudentAddressBook.json | 12 +-- .../seedu/address/logic/LogicManagerTest.java | 3 +- .../logic/commands/CommandTestUtil.java | 8 +- .../logic/parser/AddCommandParserTest.java | 2 +- .../address/logic/parser/ParserUtilTest.java | 37 ++++---- .../address/model/student/LessonTest.java | 31 ++++--- .../address/model/student/StudentTest.java | 7 -- .../model/util/SampleDataUtilTest.java | 14 ++-- .../EditStudentDescriptorBuilder.java | 25 +++--- .../address/testutil/StudentBuilder.java | 28 ++++--- .../seedu/address/testutil/StudentUtil.java | 4 +- .../address/testutil/TypicalStudents.java | 17 ++-- 30 files changed, 498 insertions(+), 215 deletions(-) create mode 100644 src/main/java/seedu/address/logic/commands/AddLessonCommand.java create mode 100644 src/main/java/seedu/address/logic/parser/AddLessonCommandParser.java diff --git a/src/main/java/seedu/address/logic/commands/AddCommand.java b/src/main/java/seedu/address/logic/commands/AddCommand.java index 3ae3978948e..d3afc4124a0 100644 --- a/src/main/java/seedu/address/logic/commands/AddCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddCommand.java @@ -6,7 +6,6 @@ import static seedu.address.logic.parser.CliSyntax.PREFIX_LESSON; import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; -import static seedu.address.logic.parser.CliSyntax.PREFIX_REMARK; import static seedu.address.logic.parser.CliSyntax.PREFIX_SUBJECT; import seedu.address.commons.util.ToStringBuilder; @@ -28,17 +27,14 @@ public class AddCommand extends Command { + PREFIX_PHONE + "PHONE " + PREFIX_EMAIL + "EMAIL " + PREFIX_ADDRESS + "ADDRESS " - + PREFIX_SUBJECT + "SUBJECT " - + PREFIX_REMARK + "REMARK " - + "[" + PREFIX_LESSON + "LESSON]...\n" + + PREFIX_SUBJECT + "SUBJECT \n" + "Example: " + COMMAND_WORD + " " + PREFIX_NAME + "John Doe " + PREFIX_PHONE + "98765432 " + PREFIX_EMAIL + "johnd@example.com " + PREFIX_ADDRESS + "311, Clementi Ave 2, #02-25 " + PREFIX_SUBJECT + "Maths " - + PREFIX_REMARK + "He is a slow learner. " - + PREFIX_LESSON + "Maths|23-05-2024|10:00|1"; + + PREFIX_LESSON + "Maths|2021-03-01|10:00"; public static final String MESSAGE_SUCCESS = "New student added: %1$s"; public static final String MESSAGE_DUPLICATE_STUDENT = "This student already exists in the address book"; diff --git a/src/main/java/seedu/address/logic/commands/AddLessonCommand.java b/src/main/java/seedu/address/logic/commands/AddLessonCommand.java new file mode 100644 index 00000000000..91624a9e9ee --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/AddLessonCommand.java @@ -0,0 +1,84 @@ +package seedu.address.logic.commands; + +import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; +import static seedu.address.model.Model.PREDICATE_SHOW_ALL_STUDENTS; + +import java.time.LocalDate; +import java.time.LocalTime; +import java.util.ArrayList; +import java.util.List; + +import seedu.address.commons.core.index.Index; +import seedu.address.logic.Messages; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.student.Lesson; +import seedu.address.model.student.Student; + + +/** + * Adds a lesson to the student identified using it's displayed index from the address book. + */ +public class AddLessonCommand extends Command { + public static final String COMMAND_WORD = "schedule"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + + ": Adds a lesson to the student identified " + + "by the index number used in the last person listing. " + + "Parameters: INDEX (must be a positive integer) " + + "l/ [LESSON]\n" + + "Example: " + COMMAND_WORD + " 1 " + + "l/ 20-02-2002|10:00"; + public static final String MESSAGE_ADD_LESSON_SUCCESS = "Scheduled lesson to student: %1$s"; + private final Index index; + private final LocalDate date; + private final LocalTime time; + private Integer isCompleted; + /*** + * Creates a AddLessonCommand to add the lesson to the specified {@code Person}, + * without the isCompleted field. + */ + public AddLessonCommand(Index index, LocalDate date, LocalTime time) { + requireAllNonNull(index, date, time); + this.index = index; + this.date = date; + this.time = time; + } + /*** + * Creates a AddLessonCommand to add the lesson to the specified {@code Person}, + * with the isCompleted field. + */ + public AddLessonCommand(Index index, LocalDate date, LocalTime time, int isCompleted) { + this(index, date, time); + this.isCompleted = isCompleted; + } + @Override + public CommandResult execute(Model model) throws CommandException { + List lastShownList = model.getFilteredStudentList(); + + if (index.getZeroBased() >= lastShownList.size()) { + throw new CommandException(Messages.MESSAGE_INVALID_STUDENT_DISPLAYED_INDEX); + } + + Student studentToEdit = lastShownList.get(index.getZeroBased()); + List lessonList = new ArrayList<>(studentToEdit.getLessons()); + String studentToEditSubject = studentToEdit.getSubject().value; + if (isCompleted != null) { + lessonList.add(new Lesson(studentToEditSubject, this.date, this.time, this.isCompleted)); + } else { + lessonList.add(new Lesson(studentToEditSubject, this.date, this.time)); + } + Student editedStudent = new Student(studentToEdit.getName(), studentToEdit.getPhone(), studentToEdit.getEmail(), + studentToEdit.getAddress(), studentToEdit.getSubject(), + studentToEdit.getRemark(), lessonList); + + model.setStudent(studentToEdit, editedStudent); + model.updateFilteredStudentList(PREDICATE_SHOW_ALL_STUDENTS); + + return new CommandResult(generateSuccessMessage(editedStudent)); + } + + private String generateSuccessMessage(Student editedStudent) { + return String.format(MESSAGE_ADD_LESSON_SUCCESS, editedStudent); + } +} diff --git a/src/main/java/seedu/address/logic/commands/EditCommand.java b/src/main/java/seedu/address/logic/commands/EditCommand.java index c4ab751e7ae..94a3fde9ed5 100644 --- a/src/main/java/seedu/address/logic/commands/EditCommand.java +++ b/src/main/java/seedu/address/logic/commands/EditCommand.java @@ -8,12 +8,9 @@ import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; import static seedu.address.model.Model.PREDICATE_SHOW_ALL_STUDENTS; -import java.util.Collections; -import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Optional; -import java.util.Set; import seedu.address.commons.core.index.Index; import seedu.address.commons.util.CollectionUtil; @@ -101,7 +98,7 @@ private static Student createEditedStudent(Student studentToEdit, EditStudentDes Phone updatedPhone = editStudentDescriptor.getPhone().orElse(studentToEdit.getPhone()); Email updatedEmail = editStudentDescriptor.getEmail().orElse(studentToEdit.getEmail()); Address updatedAddress = editStudentDescriptor.getAddress().orElse(studentToEdit.getAddress()); - Set updatedLessons = editStudentDescriptor.getLessons().orElse(studentToEdit.getLessons()); + List updatedLessons = editStudentDescriptor.getLessons().orElse(studentToEdit.getLessons()); Remark updatedRemark = studentToEdit.getRemark(); Subject updatedSubject = editStudentDescriptor.getSubject().orElse(studentToEdit.getSubject()); @@ -142,7 +139,7 @@ public static class EditStudentDescriptor { private Phone phone; private Email email; private Address address; - private Set lessons; + private List lessons; private Subject subject; private Remark remark; public EditStudentDescriptor() {} @@ -159,7 +156,6 @@ public EditStudentDescriptor(EditStudentDescriptor toCopy) { setLessons(toCopy.lessons); setSubject(toCopy.subject); setRemark(toCopy.remark); - setLessons(toCopy.lessons); } public void setRemark(Remark remark) { @@ -213,17 +209,16 @@ public Optional
getAddress() { * Sets {@code lessons} to this object's {@code lessons}. * A defensive copy of {@code lessons} is used internally. */ - public void setLessons(Set lessons) { - this.lessons = (lessons != null) ? new HashSet<>(lessons) : null; + public void setLessons(List lessons) { + this.lessons = lessons; } /** - * Returns an unmodifiable lesson set, which throws {@code UnsupportedOperationException} - * if modification is attempted. + * Returns an modifiable lesson list, * Returns {@code Optional#empty()} if {@code lessons} is null. */ - public Optional> getLessons() { - return (lessons != null) ? Optional.of(Collections.unmodifiableSet(lessons)) : Optional.empty(); + public Optional> getLessons() { + return Optional.ofNullable(lessons); } public void setSubject(Subject subject) { diff --git a/src/main/java/seedu/address/logic/commands/RemarkCommand.java b/src/main/java/seedu/address/logic/commands/RemarkCommand.java index 96aba177939..839269d7e14 100644 --- a/src/main/java/seedu/address/logic/commands/RemarkCommand.java +++ b/src/main/java/seedu/address/logic/commands/RemarkCommand.java @@ -51,7 +51,7 @@ public CommandResult execute(Model model) throws CommandException { Student studentToEdit = lastShownList.get(index.getZeroBased()); Student editedStudent = new Student(studentToEdit.getName(), studentToEdit.getPhone(), studentToEdit.getEmail(), studentToEdit.getAddress(), studentToEdit.getSubject(), - studentToEdit.getRemark(), studentToEdit.getLessons()); + this.remark, studentToEdit.getLessons()); model.setStudent(studentToEdit, editedStudent); model.updateFilteredStudentList(PREDICATE_SHOW_ALL_STUDENTS); diff --git a/src/main/java/seedu/address/logic/parser/AddCommandParser.java b/src/main/java/seedu/address/logic/parser/AddCommandParser.java index 9b2d7d44e3c..acbb24d999c 100644 --- a/src/main/java/seedu/address/logic/parser/AddCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/AddCommandParser.java @@ -9,7 +9,7 @@ import static seedu.address.logic.parser.CliSyntax.PREFIX_REMARK; import static seedu.address.logic.parser.CliSyntax.PREFIX_SUBJECT; -import java.util.Set; +import java.util.List; import java.util.stream.Stream; import seedu.address.logic.commands.AddCommand; @@ -49,9 +49,9 @@ public AddCommand parse(String args) throws ParseException { Phone phone = ParserUtil.parsePhone(argMultimap.getValue(PREFIX_PHONE).get()); Email email = ParserUtil.parseEmail(argMultimap.getValue(PREFIX_EMAIL).get()); Address address = ParserUtil.parseAddress(argMultimap.getValue(PREFIX_ADDRESS).get()); - Set lessonList = ParserUtil.parseLessons(argMultimap.getAllValues(PREFIX_LESSON)); Subject subject = ParserUtil.parseSubject(argMultimap.getValue(PREFIX_SUBJECT).get()); - Remark remark = new Remark(argMultimap.getValue(PREFIX_REMARK).orElse("")); // default value + Remark remark = new Remark(""); // default value + List lessonList = ParserUtil.parseLessons((argMultimap.getAllValues(PREFIX_LESSON))); Student student = new Student(name, phone, email, address, subject, remark, lessonList); return new AddCommand(student); } diff --git a/src/main/java/seedu/address/logic/parser/AddLessonCommandParser.java b/src/main/java/seedu/address/logic/parser/AddLessonCommandParser.java new file mode 100644 index 00000000000..ef4390bd37b --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/AddLessonCommandParser.java @@ -0,0 +1,82 @@ +package seedu.address.logic.parser; + +import static java.util.Objects.requireNonNull; +import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.parser.CliSyntax.PREFIX_LESSON; +import static seedu.address.model.student.Lesson.DATE_FORMATTER; +import static seedu.address.model.student.Lesson.TIME_FORMATTER; + +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.format.DateTimeParseException; + +import seedu.address.commons.core.index.Index; +import seedu.address.commons.exceptions.IllegalValueException; +import seedu.address.logic.commands.AddLessonCommand; +import seedu.address.logic.parser.exceptions.ParseException; + +/** + * Parses input arguments and creates a new AddLessonCommand object + */ +public class AddLessonCommandParser implements Parser { + /** + * Parses the given {@code String} of arguments in the context of the AddLessonCommand + * and returns an AddLessonCommand object for execution. + * @throws ParseException if the user input does not conform the expected format + */ + public AddLessonCommand parse(String args) throws ParseException { + requireNonNull(args); + ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_LESSON); + + Index index; + try { + index = ParserUtil.parseIndex(argMultimap.getPreamble()); + } catch (IllegalValueException ive) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, + AddLessonCommand.MESSAGE_USAGE), ive); + } + + String lesson = argMultimap.getValue(PREFIX_LESSON).orElse(""); + + if (!isValidLesson(lesson)) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, + AddLessonCommand.MESSAGE_USAGE)); + } + // split lesson into its attributes based on "|" character + String[] lessonDetails = lesson.trim().split("\\|"); + LocalDate dateDetail = LocalDate.parse(lessonDetails[0], DATE_FORMATTER); + LocalTime timeDetail = LocalTime.parse(lessonDetails[1], TIME_FORMATTER); + int isCompleted; + if (lessonDetails.length == 3) { + isCompleted = Integer.parseInt(lessonDetails[3]); + return new AddLessonCommand(index, dateDetail, timeDetail, isCompleted); + } else { + return new AddLessonCommand(index, dateDetail, timeDetail); + } + } + + /** + * Checks if the lesson is in the correct format. + * @param lesson the lesson to be checked + * @return true if the lesson is in the correct format, false otherwise + */ + public boolean isValidLesson(String lesson) { + String[] lessonDetails = lesson.trim().split("\\|"); + if (lessonDetails.length != 2 && lessonDetails.length != 3) { + return false; + } + try { + LocalDate.parse(lessonDetails[0], DATE_FORMATTER); + LocalTime.parse(lessonDetails[1], TIME_FORMATTER); + if (lessonDetails.length == 3) { + int isCompleted = Integer.parseInt(lessonDetails[2]); + if (isCompleted != 0 && isCompleted != 1) { + return false; + } + } + } catch (DateTimeParseException | NumberFormatException e) { + return false; + } + return true; + } +} diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index 6e23a66022b..dcd77a670f5 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -9,6 +9,7 @@ import seedu.address.commons.core.LogsCenter; import seedu.address.logic.commands.AddCommand; +import seedu.address.logic.commands.AddLessonCommand; import seedu.address.logic.commands.ClearCommand; import seedu.address.logic.commands.Command; import seedu.address.logic.commands.DeleteCommand; @@ -81,6 +82,10 @@ public Command parseCommand(String userInput) throws ParseException { case RemarkCommand.COMMAND_WORD: return new RemarkCommandParser().parse(arguments); + case AddLessonCommand.COMMAND_WORD: + return new AddLessonCommandParser().parse(arguments); + + default: logger.finer("This user input caused a ParseException: " + userInput); throw new ParseException(MESSAGE_UNKNOWN_COMMAND); diff --git a/src/main/java/seedu/address/logic/parser/EditCommandParser.java b/src/main/java/seedu/address/logic/parser/EditCommandParser.java index 0920f0b3d70..5406fccf8da 100644 --- a/src/main/java/seedu/address/logic/parser/EditCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/EditCommandParser.java @@ -11,8 +11,8 @@ import java.util.Collection; import java.util.Collections; +import java.util.List; import java.util.Optional; -import java.util.Set; import seedu.address.commons.core.index.Index; import seedu.address.logic.commands.EditCommand; @@ -74,18 +74,18 @@ public EditCommand parse(String args) throws ParseException { } /** - * Parses {@code Collection tags} into a {@code Set} if {@code tags} is non-empty. - * If {@code tags} contain only one element which is an empty string, it will be parsed into a - * {@code Set} containing zero tags. + * Parses {@code Collection lessons} into a {@code List} if {@code lessons} is non-empty. + * If {@code lessons} contain only one element which is an empty string, it will be parsed into a + * {@code List} containing zero lessons. */ - private Optional> parseLessonsForEdit(Collection lessons) throws ParseException { + private Optional> parseLessonsForEdit(Collection lessons) throws ParseException { assert lessons != null; if (lessons.isEmpty()) { return Optional.empty(); } - Collection lessonSet = lessons.size() == 1 && lessons.contains("") ? Collections.emptySet() : lessons; - return Optional.of(ParserUtil.parseLessons(lessonSet)); + Collection lessonList = lessons.size() == 1 && lessons.contains("") ? Collections.emptyList() : lessons; + return Optional.of(ParserUtil.parseLessons(lessonList)); } } diff --git a/src/main/java/seedu/address/logic/parser/ParserUtil.java b/src/main/java/seedu/address/logic/parser/ParserUtil.java index f947dd465ff..207cbec6d50 100644 --- a/src/main/java/seedu/address/logic/parser/ParserUtil.java +++ b/src/main/java/seedu/address/logic/parser/ParserUtil.java @@ -1,10 +1,16 @@ package seedu.address.logic.parser; import static java.util.Objects.requireNonNull; +import static seedu.address.model.student.Lesson.DATE_FORMATTER; +import static seedu.address.model.student.Lesson.TIME_FORMATTER; +import static seedu.address.model.student.Lesson.isValidLesson; +import static seedu.address.storage.JsonAdaptedLesson.isValidJsonLesson; +import java.time.LocalDate; +import java.time.LocalTime; +import java.util.ArrayList; import java.util.Collection; -import java.util.HashSet; -import java.util.Set; +import java.util.List; import seedu.address.commons.core.index.Index; import seedu.address.commons.util.StringUtil; @@ -80,7 +86,6 @@ public static Address parseAddress(String address) throws ParseException { } return new Address(trimmedAddress); } - /** * Parses a {@code String email} into an {@code Email}. * Leading and trailing whitespaces will be trimmed. @@ -95,44 +100,57 @@ public static Email parseEmail(String email) throws ParseException { } return new Email(trimmedEmail); } + /** + * Parses a {@code String subject} into an {@code Subject}. + * Leading and trailing whitespaces will be trimmed. + * + * @throws ParseException if the given {@code subject} is invalid. + */ + public static Subject parseSubject(String subject) throws ParseException { + requireNonNull(subject); + String trimmedSubject = subject.trim(); + if (!Subject.isValidSubject(trimmedSubject)) { + throw new ParseException(Subject.MESSAGE_CONSTRAINTS); + } + return new Subject(trimmedSubject); + } /** * Parses a {@code String lesson} into a {@code Lesson}. * Leading and trailing whitespaces will be trimmed. * - * @throws ParseException if the given {@code tag} is invalid. + * @throws ParseException if the given {@code lesson} is invalid. */ public static Lesson parseLesson(String lesson) throws ParseException { requireNonNull(lesson); - if (!Lesson.isValidLesson(lesson)) { + if (!isValidLesson(lesson) && !isValidJsonLesson(lesson)) { throw new ParseException(Lesson.MESSAGE_CONSTRAINTS); } - return new Lesson(lesson); - } - - /** - * Parses {@code Collection tags} into a {@code Set}. - */ - public static Set parseLessons(Collection lessons) throws ParseException { - requireNonNull(lessons); - final Set lessonSet = new HashSet<>(); - for (String lessonValue : lessons) { - lessonSet.add(parseLesson(lessonValue)); + // split lesson into its attributes based on "|" character + String[] lessonDetails = lesson.trim().split("\\|"); + String subjectDetail = lessonDetails[0]; + LocalDate dateDetail = LocalDate.parse(lessonDetails[1], DATE_FORMATTER); + LocalTime timeDetail = LocalTime.parse(lessonDetails[2], TIME_FORMATTER); + int isCompleted; + if (lessonDetails.length == 4) { + isCompleted = Integer.parseInt(lessonDetails[3]); + return new Lesson(subjectDetail, dateDetail, timeDetail, isCompleted); + } else { + return new Lesson(subjectDetail, dateDetail, timeDetail); } - return lessonSet; } + /** - * Parses a {@code String subject} into an {@code Subject}. - * Leading and trailing whitespaces will be trimmed. + * Parses a {@code Collection lessonList} into a {@code List}. * - * @throws ParseException if the given {@code subject} is invalid. + * @throws ParseException if the given {@code lessonSet} is invalid. */ - public static Subject parseSubject(String subject) throws ParseException { - requireNonNull(subject); - String trimmedSubject = subject.trim(); - if (!Subject.isValidSubject(trimmedSubject)) { - throw new ParseException(Subject.MESSAGE_CONSTRAINTS); + public static List parseLessons(Collection lessons) throws ParseException { + requireNonNull(lessons); + List lessonList = new ArrayList<>(); + for (String lesson : lessons) { + lessonList.add(parseLesson(lesson)); } - return new Subject(trimmedSubject); + return lessonList; } } diff --git a/src/main/java/seedu/address/model/student/Lesson.java b/src/main/java/seedu/address/model/student/Lesson.java index 97520dc1810..886b1a5b7a5 100644 --- a/src/main/java/seedu/address/model/student/Lesson.java +++ b/src/main/java/seedu/address/model/student/Lesson.java @@ -1,6 +1,7 @@ package seedu.address.model.student; import static java.util.Objects.requireNonNull; +import static seedu.address.commons.util.AppUtil.checkArgument; import java.time.LocalDate; import java.time.LocalTime; @@ -18,39 +19,54 @@ public class Lesson { public static final String VALIDATION_REGEX = "^[a-zA-Z][a-zA-Z ]*$"; public static final String DATE_REGEX = "\\d{2}-\\d{2}-\\d{4}"; public static final String TIME_REGEX = "\\d{2}:\\d{2}"; - public static final String INT_REGEX = "[01]"; - private static final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy"); - private static final DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm"); + public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("dd-MM-yyyy"); + public static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm"); private String value; + private String jsonValue; private final Subject subject; private final LocalDate date; private final LocalTime time; private int isCompleted; /** - * Constructs a Lesson with the specified subject, date, and time. + * Constructs a {@code Lesson} that is already parsed. * - * @param lesson The details of the lesson. + * @param subject A valid subject. + * @param date A valid date. + * @param time A valid time. */ - public Lesson(String lesson) { - requireNonNull(lesson); - // split lesson into its attributes based on "|" character - String[] lessonDetails = lesson.trim().split("\\|"); - // throws IllegalArgumentException if the lesson is not in the correct format. - if (lessonDetails.length != 4) { - throw new IllegalArgumentException(MESSAGE_CONSTRAINTS); - } - String subjectDetail = lessonDetails[0]; - String dateDetail = lessonDetails[1]; - String timeDetail = lessonDetails[2]; - int isCompletedDetail = Integer.parseInt(lessonDetails[3]); + public Lesson(String subject, LocalDate date, LocalTime time) { + requireNonNull(subject); + requireNonNull(date); + requireNonNull(time); + checkArgument(subject.matches(VALIDATION_REGEX), MESSAGE_CONSTRAINTS); // assign the attributes to the lesson - this.subject = new Subject(subjectDetail); - this.date = LocalDate.parse(dateDetail, dateFormatter); - this.time = LocalTime.parse(timeDetail, timeFormatter); - this.isCompleted = isCompletedDetail; - // parseable form of lesson (temporary) - this.value = subjectDetail + "|" + dateDetail + "|" + timeDetail + "|" + isCompleted; + this.subject = new Subject(subject); + this.date = LocalDate.parse(date.format(DATE_FORMATTER), DATE_FORMATTER); + this.time = time; + this.isCompleted = 0; + // jSON readable form of lesson + this.jsonValue = this.subject.value + "|" + this.date.format(DATE_FORMATTER) + "|" + + this.time.format(TIME_FORMATTER) + "|" + this.isCompleted; + // UI displayed form of lesson + this.value = this.subject + " " + this.date + " " + this.time; + } + + /** + * Constructs a {@code Lesson} that is already parsed, with the optional isCompleted field. + * + * @param subject A valid subject. + * @param date A valid date. + * @param time A valid time. + * @param isCompleted A valid isCompleted int field. + */ + public Lesson(String subject, LocalDate date, LocalTime time, int isCompleted) { + this(subject, date, time); + if (isCompleted == 1) { + this.setLessonComplete(); + } else { + this.setLessonIncomplete(); + } } /** @@ -58,20 +74,18 @@ public Lesson(String lesson) { */ public static boolean isValidLesson(String lessonValue) { String[] lessonDetails = lessonValue.split("\\|"); - if (lessonDetails.length != 4) { + if (lessonDetails.length != 3) { return false; } try { - LocalDate.parse(lessonDetails[1], dateFormatter); - LocalTime.parse(lessonDetails[2], timeFormatter); - Integer.parseInt(lessonDetails[3]); - } catch (DateTimeParseException | NumberFormatException e) { + LocalDate.parse(lessonDetails[1], DATE_FORMATTER); + LocalTime.parse(lessonDetails[2], TIME_FORMATTER); + } catch (DateTimeParseException e) { return false; } return lessonDetails[0].matches(VALIDATION_REGEX) && lessonDetails[1].matches(DATE_REGEX) - && lessonDetails[2].matches(TIME_REGEX) - && lessonDetails[3].matches(INT_REGEX); + && lessonDetails[2].matches(TIME_REGEX); } /** @@ -113,6 +127,9 @@ public int getLessonStatus() { public String getLessonValue() { return value; } + public String getJsonValue() { + return jsonValue; + } public void setLessonComplete() { this.isCompleted = 1; diff --git a/src/main/java/seedu/address/model/student/Student.java b/src/main/java/seedu/address/model/student/Student.java index d0e458dc2bf..2d06159eb49 100644 --- a/src/main/java/seedu/address/model/student/Student.java +++ b/src/main/java/seedu/address/model/student/Student.java @@ -2,10 +2,9 @@ import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; -import java.util.Collections; -import java.util.HashSet; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; -import java.util.Set; import seedu.address.commons.util.ToStringBuilder; /** @@ -21,15 +20,15 @@ public class Student { // Data fields private final Address address; private final Remark remark; - private final Set lessons = new HashSet<>(); + private List lessons = new ArrayList<>(); private final Subject subject; /** * Student constructor with all fields. */ public Student(Name name, Phone phone, Email email, Address address, Subject subject, - Remark remark, Set lessons) { - requireAllNonNull(name, phone, email, address, subject, lessons); + Remark remark, List lessons) { + requireAllNonNull(name, phone, email, address, subject); this.name = name; this.phone = phone; this.email = email; @@ -38,6 +37,19 @@ public Student(Name name, Phone phone, Email email, Address address, Subject sub this.lessons.addAll(lessons); this.remark = remark; } + /** + * Student constructor with default values for remark and lessons. + */ + public Student(Name name, Phone phone, Email email, Address address, Subject subject) { + requireAllNonNull(name, phone, email, address, subject); + this.name = name; + this.phone = phone; + this.email = email; + this.address = address; + this.subject = subject; + this.lessons = new ArrayList<>(); + this.remark = new Remark(""); + } public Name getName() { return name; @@ -56,11 +68,10 @@ public Address getAddress() { } /** - * Returns an immutable tag set, which throws {@code UnsupportedOperationException} - * if modification is attempted. + * Returns the ArrayList of lessons for the student, this list is mutable. */ - public Set getLessons() { - return Collections.unmodifiableSet(lessons); + public List getLessons() { + return lessons; } public Remark getRemark() { diff --git a/src/main/java/seedu/address/model/student/Subject.java b/src/main/java/seedu/address/model/student/Subject.java index 8e94c9cf01f..b758d9fd8f6 100644 --- a/src/main/java/seedu/address/model/student/Subject.java +++ b/src/main/java/seedu/address/model/student/Subject.java @@ -11,7 +11,7 @@ public class Subject { public static final String MESSAGE_CONSTRAINTS = "Subjects can only take alphanumeric values and spaces, and it should not be blank"; - public static final String VALIDATION_REGEX = "^[a-zA-Z][a-zA-Z ]*$"; + public static final String VALIDATION_REGEX = "^[A-Z][a-zA-Z ]*$"; public final String value; diff --git a/src/main/java/seedu/address/model/util/SampleDataUtil.java b/src/main/java/seedu/address/model/util/SampleDataUtil.java index b450a1617da..961c0167cd8 100644 --- a/src/main/java/seedu/address/model/util/SampleDataUtil.java +++ b/src/main/java/seedu/address/model/util/SampleDataUtil.java @@ -1,9 +1,11 @@ package seedu.address.model.util; -import java.util.Arrays; -import java.util.Set; -import java.util.stream.Collectors; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import seedu.address.logic.parser.ParserUtil; +import seedu.address.logic.parser.exceptions.ParseException; import seedu.address.model.AddressBook; import seedu.address.model.ReadOnlyAddressBook; import seedu.address.model.student.Address; @@ -24,28 +26,24 @@ public static Student[] getSampleStudents() { return new Student[] { new Student(new Name("Alex Yeoh"), new Phone("87438807"), new Email("alexyeoh@example.com"), new Address("Blk 30 Geylang Street 29, #06-40"), - new Subject("Math"), - EMPTY_REMARK, getLessonSet("Maths|10-05-2004|12:29|0")), + new Subject("Math")), new Student(new Name("Bernice Yu"), new Phone("99272758"), new Email("berniceyu@example.com"), new Address("Blk 30 Lorong 3 Serangoon Gardens, #07-18"), - new Subject("English"), - EMPTY_REMARK, getLessonSet("English|10-05-2004|12:29|1")), + new Subject("English")), new Student(new Name("Charlotte Oliveiro"), new Phone("93210283"), new Email("charlotte@example.com"), new Address("Blk 11 Ang Mo Kio Street 74, #11-04"), - new Subject("Physics"), - EMPTY_REMARK, getLessonSet("Maths|11-05-2004|12:29|0")), + new Subject("Physics")), new Student(new Name("David Li"), new Phone("91031282"), new Email("lidavid@example.com"), new Address("Blk 436 Serangoon Gardens Street 26, #16-43"), new Subject("History"), - EMPTY_REMARK, getLessonSet("Maths|10-05-2004|12:30|1")), + EMPTY_REMARK, Collections.emptyList()), new Student(new Name("Irfan Ibrahim"), new Phone("92492021"), new Email("irfan@example.com"), new Address("Blk 47 Tampines Street 20, #17-35"), new Subject("Chemistry"), - EMPTY_REMARK, getLessonSet("Geography|10-05-2004|12:29|1")), + EMPTY_REMARK, Collections.emptyList()), new Student(new Name("Roy Balakrishnan"), new Phone("92624417"), new Email("royb@example.com"), new Address("Blk 45 Aljunied Street 85, #11-31"), - new Subject("Biology"), - EMPTY_REMARK, getLessonSet("Maths|10-05-2004|12:30|0")) + new Subject("Biology"), EMPTY_REMARK, Collections.emptyList()) }; } @@ -58,12 +56,17 @@ public static ReadOnlyAddressBook getSampleAddressBook() { } /** - * Returns a tag set containing the list of strings given. + * Returns a List containing the list of lesson strings given. */ - public static Set getLessonSet(String... strings) { - return Arrays.stream(strings) - .map(Lesson::new) - .collect(Collectors.toSet()); + public static List getLessonList(String... strings) throws ParseException { + List lessonList = new ArrayList<>(); + for (String lessonString : strings) { + Lesson lesson = ParserUtil.parseLesson(lessonString); + if (lesson != null) { + lessonList.add(lesson); + } + } + return lessonList; } } diff --git a/src/main/java/seedu/address/storage/JsonAdaptedLesson.java b/src/main/java/seedu/address/storage/JsonAdaptedLesson.java index 30bfe4ea8bf..421e3819141 100644 --- a/src/main/java/seedu/address/storage/JsonAdaptedLesson.java +++ b/src/main/java/seedu/address/storage/JsonAdaptedLesson.java @@ -1,5 +1,12 @@ package seedu.address.storage; +import static java.util.Objects.requireNonNull; +import static seedu.address.model.student.Lesson.DATE_FORMATTER; +import static seedu.address.model.student.Lesson.TIME_FORMATTER; + +import java.time.LocalDate; +import java.time.LocalTime; + import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; @@ -9,7 +16,11 @@ /** * Jackson-friendly version of {@link Lesson}. */ -class JsonAdaptedLesson { +public class JsonAdaptedLesson { + + private static final String MESSAGE_CONSTRAINTS = + "Jackson-adapted Lessons must be of the form subject|dd-MM-yyyy|hh:mm|0/1, where subject contains only" + + " alphabets and spaces, and indicate lesson incomplete/completed with 0 or 1 respectively."; private final String lesson; @@ -25,7 +36,7 @@ public JsonAdaptedLesson(String lesson) { * Converts a given {@code Lesson} into this class for Jackson use. */ public JsonAdaptedLesson(Lesson source) { - lesson = source.getLessonValue(); + lesson = source.getJsonValue(); } @@ -40,10 +51,53 @@ public String getLessonName() { * @throws IllegalValueException if there were any data constraints violated in the adapted lesson. */ public Lesson toModelType() throws IllegalValueException { - if (!Lesson.isValidLesson(lesson)) { - throw new IllegalValueException(Lesson.MESSAGE_CONSTRAINTS); + if (!isValidJsonLesson(getLessonName())) { + throw new IllegalValueException(MESSAGE_CONSTRAINTS); + } + return parseJsonLesson(getLessonName()); + } + /** + * Returns true if a given Jackson-friendly adapted lesson object is a valid lesson. + */ + public static boolean isValidJsonLesson(String jsonLesson) { + requireNonNull(jsonLesson); + + String[] lessonDetails = jsonLesson.trim().split("\\|"); + if (lessonDetails.length != 4) { + return false; + } + if (!lessonDetails[0].matches(Lesson.VALIDATION_REGEX)) { + return false; + } + if (!lessonDetails[1].matches(Lesson.DATE_REGEX)) { + return false; + } + if (!lessonDetails[2].matches(Lesson.TIME_REGEX)) { + return false; + } + if (!lessonDetails[3].matches("0|1")) { + return false; + } + return true; + } + + /** + * Parses a Jackson-friendly adapted lesson into a model {@code Lesson} object. + */ + public static Lesson parseJsonLesson(String jsonLesson) { + requireNonNull(jsonLesson); + assert isValidJsonLesson(jsonLesson); + + String[] lessonDetails = jsonLesson.trim().split("\\|"); + String subjectDetail = lessonDetails[0]; + LocalDate dateDetail = LocalDate.parse(lessonDetails[1], DATE_FORMATTER); + LocalTime timeDetail = LocalTime.parse(lessonDetails[2], TIME_FORMATTER); + int isCompleted = Integer.parseInt(lessonDetails[3]); + Lesson newLesson = new Lesson(subjectDetail, dateDetail, timeDetail); + if (isCompleted == 1) { + newLesson.setLessonComplete(); } - return new Lesson(lesson); + return newLesson; } } diff --git a/src/main/java/seedu/address/storage/JsonAdaptedStudent.java b/src/main/java/seedu/address/storage/JsonAdaptedStudent.java index d6527e47851..653ad5ae1a7 100644 --- a/src/main/java/seedu/address/storage/JsonAdaptedStudent.java +++ b/src/main/java/seedu/address/storage/JsonAdaptedStudent.java @@ -1,9 +1,7 @@ package seedu.address.storage; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; import java.util.stream.Collectors; import com.fasterxml.jackson.annotation.JsonCreator; @@ -65,7 +63,7 @@ public JsonAdaptedStudent(Student source) { subject = source.getSubject().value; remark = source.getRemark().value; lessons.addAll(source.getLessons().stream() - .map(JsonAdaptedLesson::new) + .map(lesson -> new JsonAdaptedLesson(lesson.getJsonValue())) .collect(Collectors.toList())); } @@ -75,9 +73,9 @@ public JsonAdaptedStudent(Student source) { * @throws IllegalValueException if there were any data constraints violated in the adapted student. */ public Student toModelType() throws IllegalValueException { - final List lessonList = new ArrayList<>(); + final List modelLessons = new ArrayList<>(); for (JsonAdaptedLesson lesson : lessons) { - lessonList.add(lesson.toModelType()); + modelLessons.add(lesson.toModelType()); } if (name == null) { @@ -110,15 +108,11 @@ public Student toModelType() throws IllegalValueException { if (!Address.isValidAddress(address)) { throw new IllegalValueException(Address.MESSAGE_CONSTRAINTS); } - if (remark == null) { - throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Remark.class.getSimpleName())); - } if (subject == null) { throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Subject.class.getSimpleName())); } final Remark modelRemark = new Remark(remark); final Address modelAddress = new Address(address); - final Set modelLessons = new HashSet<>(lessonList); final Subject modelSubject = new Subject(subject); return new Student(modelName, modelPhone, modelEmail, modelAddress, modelSubject, diff --git a/src/test/data/JsonAddressBookStorageTest/invalidAndValidStudentAddressBook.json b/src/test/data/JsonAddressBookStorageTest/invalidAndValidStudentAddressBook.json index 42744717e44..84d8a90fb38 100644 --- a/src/test/data/JsonAddressBookStorageTest/invalidAndValidStudentAddressBook.json +++ b/src/test/data/JsonAddressBookStorageTest/invalidAndValidStudentAddressBook.json @@ -6,7 +6,7 @@ "address": "4th street", "subject": "Math", "remark": "Good", - "lessons": ["Maths|10-05-2004|12:29|1"] + "lessons": ["Maths|10-05-2004|12:29"] }, { "name": "Student With Invalid Phone Field", "phone": "948asdf2424", @@ -14,6 +14,6 @@ "address": "4th street", "subject": "Math", "remark": "Good", - "lessons": ["Maths|10-05-2004|12:29|0"] + "lessons": ["Maths|10-05-2004|12:29"] } ] } diff --git a/src/test/data/JsonAddressBookStorageTest/invalidStudentAddressBook.json b/src/test/data/JsonAddressBookStorageTest/invalidStudentAddressBook.json index 6755c74265e..c8e172d0a6a 100644 --- a/src/test/data/JsonAddressBookStorageTest/invalidStudentAddressBook.json +++ b/src/test/data/JsonAddressBookStorageTest/invalidStudentAddressBook.json @@ -6,6 +6,6 @@ "address": "4th street", "subject": "Math", "remarks": "He is a good teacher", - "lessons": ["Maths|10-05-2004|12:29|1"] + "lessons": ["Maths|10-05-2004|12:29"] } ] } diff --git a/src/test/data/JsonSerializableAddressBookTest/duplicateStudentAddressBook.json b/src/test/data/JsonSerializableAddressBookTest/duplicateStudentAddressBook.json index 285fee43683..c4cdc461f49 100644 --- a/src/test/data/JsonSerializableAddressBookTest/duplicateStudentAddressBook.json +++ b/src/test/data/JsonSerializableAddressBookTest/duplicateStudentAddressBook.json @@ -6,7 +6,7 @@ "address": "123, Jurong West Ave 6, #08-111", "subject": "Science", "remark": "", - "lessons": [ "Maths|10-05-2004|12:29|1" ] + "lessons": [ "Maths|10-05-2004|12:29|0" ] }, { "name": "Alice Pauline", "phone": "94351253", @@ -14,6 +14,6 @@ "address": "4th street", "subject": "Science", "remark": "", - "lessons": [ "Maths|10-05-2004|12:29|1" ] + "lessons": [ "Maths|10-05-2004|12:29|0" ] } ] } diff --git a/src/test/data/JsonSerializableAddressBookTest/typicalStudentAddressBook.json b/src/test/data/JsonSerializableAddressBookTest/typicalStudentAddressBook.json index 26fa88a42c0..936cfb3c3bf 100644 --- a/src/test/data/JsonSerializableAddressBookTest/typicalStudentAddressBook.json +++ b/src/test/data/JsonSerializableAddressBookTest/typicalStudentAddressBook.json @@ -15,7 +15,7 @@ "address" : "311, Clementi Ave 2, #02-25", "subject" : "Geography", "remark" : "", - "lessons" : [ "Geography|10-05-2004|12:29|0" ] + "lessons" : [ "Geography|10-05-2004|12:29|1" ] }, { "name" : "Carl Kurz", "phone" : "95352563", @@ -23,7 +23,7 @@ "address" : "wall street", "subject" : "English", "remark" : "", - "lessons" : [ "English|10-05-2004|12:29|1" ] + "lessons" : [ "English|10-05-2004|12:29|0" ] }, { "name" : "Daniel Meier", "phone" : "87652533", @@ -31,7 +31,7 @@ "address" : "10th street", "subject" : "History", "remark" : "", - "lessons" : [ "Geography|10-05-2004|12:29|1" ] + "lessons" : [ "Geography|10-05-2004|12:29|0" ] }, { "name" : "Elle Meyer", "phone" : "9482224", @@ -39,7 +39,7 @@ "address" : "michegan ave", "subject" : "Psychology", "remark" : "", - "lessons" : [ "Geography|10-05-2004|12:29|0" ] + "lessons" : [ "Geography|10-05-2004|12:29|1" ] }, { "name" : "Fiona Kunz", "phone" : "9482427", @@ -47,7 +47,7 @@ "address" : "little tokyo", "subject" : "English", "remark" : "", - "lessons" : [ ] + "lessons" : [ "English|10-05-2004|12:29|0" ] }, { "name" : "George Best", "phone" : "9482442", @@ -55,6 +55,6 @@ "address" : "4th street", "subject" : "Art", "remark" : "", - "lessons" : [ "Art|10-05-2004|12:29|0" ] + "lessons" : [ "Art|10-05-2004|12:29|1" ] } ] } diff --git a/src/test/java/seedu/address/logic/LogicManagerTest.java b/src/test/java/seedu/address/logic/LogicManagerTest.java index 51bfe069a24..f43e8cd0552 100644 --- a/src/test/java/seedu/address/logic/LogicManagerTest.java +++ b/src/test/java/seedu/address/logic/LogicManagerTest.java @@ -5,6 +5,7 @@ import static seedu.address.logic.Messages.MESSAGE_UNKNOWN_COMMAND; import static seedu.address.logic.commands.CommandTestUtil.ADDRESS_DESC_AMY; import static seedu.address.logic.commands.CommandTestUtil.EMAIL_DESC_AMY; +import static seedu.address.logic.commands.CommandTestUtil.LESSON_DESC_AMY; import static seedu.address.logic.commands.CommandTestUtil.NAME_DESC_AMY; import static seedu.address.logic.commands.CommandTestUtil.PHONE_DESC_AMY; import static seedu.address.logic.commands.CommandTestUtil.SUBJECT_DESC_MATHS; @@ -167,7 +168,7 @@ public void saveAddressBook(ReadOnlyAddressBook addressBook, Path filePath) // Triggers the saveAddressBook method by executing an add command String addCommand = AddCommand.COMMAND_WORD + NAME_DESC_AMY + PHONE_DESC_AMY - + EMAIL_DESC_AMY + ADDRESS_DESC_AMY + SUBJECT_DESC_MATHS; + + EMAIL_DESC_AMY + ADDRESS_DESC_AMY + SUBJECT_DESC_MATHS + LESSON_DESC_AMY; Student expectedStudent = new StudentBuilder(AMY).build(); ModelManager expectedModel = new ModelManager(); expectedModel.addStudent(expectedStudent); diff --git a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java b/src/test/java/seedu/address/logic/commands/CommandTestUtil.java index 66788454c07..cce62990a95 100644 --- a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java +++ b/src/test/java/seedu/address/logic/commands/CommandTestUtil.java @@ -38,10 +38,10 @@ public class CommandTestUtil { public static final String VALID_ADDRESS_BOB = "Block 123, Bobby Street 3"; public static final String VALID_REMARK_BOB = "Likes to swim"; public static final String VALID_REMARK_AMY = "Likes to run"; - public static final String VALID_SUBJECT_AMY = "Maths"; + public static final String VALID_SUBJECT_AMY = "Math"; public static final String VALID_SUBJECT_BOB = "Science"; - public static final String VALID_LESSON_AMY = "Math|10-05-2002|10:00|0"; - public static final String VALID_LESSON_BOB = "Science|12-06-2003|14:30|1"; + public static final String VALID_LESSON_AMY = "Math|10-05-2002|13:00|0"; + public static final String VALID_LESSON_BOB = "Science|12-06-2003|14:30|0"; public static final String NAME_DESC_AMY = " " + PREFIX_NAME + VALID_NAME_AMY; public static final String NAME_DESC_BOB = " " + PREFIX_NAME + VALID_NAME_BOB; @@ -55,7 +55,7 @@ public class CommandTestUtil { public static final String LESSON_DESC_INCOMPLETE = " " + PREFIX_LESSON + VALID_LESSON_AMY; public static final String SUBJECT_DESC_MATHS = " " + PREFIX_SUBJECT + VALID_SUBJECT_AMY; public static final String SUBJECT_DESC_SCIENCE = " " + PREFIX_SUBJECT + VALID_SUBJECT_BOB; - public static final String LESSON_DESC_AMY = " " + PREFIX_LESSON + VALID_SUBJECT_AMY; + public static final String LESSON_DESC_AMY = " " + PREFIX_LESSON + VALID_LESSON_AMY; public static final String REMARK_DESC_AMY = " " + PREFIX_REMARK + VALID_REMARK_AMY; public static final String REMARK_DESC_BOB = " " + PREFIX_REMARK + VALID_REMARK_BOB; public static final String INVALID_NAME_DESC = " " + PREFIX_NAME + "James&"; // '&' not allowed in names diff --git a/src/test/java/seedu/address/logic/parser/AddCommandParserTest.java b/src/test/java/seedu/address/logic/parser/AddCommandParserTest.java index fe1b35d52fd..23f38cb1292 100644 --- a/src/test/java/seedu/address/logic/parser/AddCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddCommandParserTest.java @@ -138,7 +138,7 @@ public void parse_repeatedNonLessonValue_failure() { @Test public void parse_optionalFieldsMissing_success() { // zero lessons - Student expectedStudent = new StudentBuilder(AMY).build(); + Student expectedStudent = new StudentBuilder(AMY).withLessons().build(); assertParseSuccess(parser, NAME_DESC_AMY + PHONE_DESC_AMY + EMAIL_DESC_AMY + ADDRESS_DESC_AMY + SUBJECT_DESC_MATHS, new AddCommand(expectedStudent)); diff --git a/src/test/java/seedu/address/logic/parser/ParserUtilTest.java b/src/test/java/seedu/address/logic/parser/ParserUtilTest.java index 737ba8f62a0..e9a8655bd14 100644 --- a/src/test/java/seedu/address/logic/parser/ParserUtilTest.java +++ b/src/test/java/seedu/address/logic/parser/ParserUtilTest.java @@ -6,10 +6,12 @@ import static seedu.address.testutil.Assert.assertThrows; import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_STUDENT; +import java.time.LocalDate; +import java.time.LocalTime; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.HashSet; -import java.util.Set; +import java.util.List; import org.junit.jupiter.api.Test; @@ -25,13 +27,17 @@ public class ParserUtilTest { private static final String INVALID_PHONE = "+651234"; private static final String INVALID_ADDRESS = " "; private static final String INVALID_EMAIL = "example.com"; - private static final String INVALID_LESSON = "#MATH|10-05-2002|13:00|0"; + private static final String INVALID_LESSON = "#MATH|10-05-2002|13:00"; private static final String VALID_NAME = "Rachel Walker"; private static final String VALID_PHONE = "123456"; private static final String VALID_ADDRESS = "123 Main Street #0505"; private static final String VALID_EMAIL = "rachel@example.com"; - private static final String VALID_LESSON_1 = "Maths|10-05-2002|13:00|0"; - private static final String VALID_LESSON_2 = "Science|10-05-2002|13:00|0"; + private static final String VALID_LESSON_1 = "Maths|10-05-2002|13:00"; + private static final String VALID_LESSON_2 = "Science|10-05-2002|13:00"; + private static final String VALID_SUBJECT_MATHS = "Maths"; + private static final String VALID_SUBJECT_SCIENCE = "Science"; + private static final LocalDate VALID_DATE_1 = LocalDate.parse("10-05-2002", Lesson.DATE_FORMATTER); + private static final LocalTime VALID_TIME_1 = LocalTime.parse("13:00", Lesson.TIME_FORMATTER); private static final String WHITESPACE = " \t\r\n"; @@ -57,7 +63,7 @@ public void parseIndex_validInput_success() throws Exception { @Test public void parseName_null_throwsNullPointerException() { - assertThrows(NullPointerException.class, () -> ParserUtil.parseName((String) null)); + assertThrows(NullPointerException.class, () -> ParserUtil.parseName(null)); } @Test @@ -80,7 +86,7 @@ public void parseName_validValueWithWhitespace_returnsTrimmedName() throws Excep @Test public void parsePhone_null_throwsNullPointerException() { - assertThrows(NullPointerException.class, () -> ParserUtil.parsePhone((String) null)); + assertThrows(NullPointerException.class, () -> ParserUtil.parsePhone(null)); } @Test @@ -103,7 +109,7 @@ public void parsePhone_validValueWithWhitespace_returnsTrimmedPhone() throws Exc @Test public void parseAddress_null_throwsNullPointerException() { - assertThrows(NullPointerException.class, () -> ParserUtil.parseAddress((String) null)); + assertThrows(NullPointerException.class, () -> ParserUtil.parseAddress(null)); } @Test @@ -126,7 +132,7 @@ public void parseAddress_validValueWithWhitespace_returnsTrimmedAddress() throws @Test public void parseEmail_null_throwsNullPointerException() { - assertThrows(NullPointerException.class, () -> ParserUtil.parseEmail((String) null)); + assertThrows(NullPointerException.class, () -> ParserUtil.parseEmail(null)); } @Test @@ -169,16 +175,17 @@ public void parseLessons_collectionWithInvalidTags_throwsParseException() { } @Test - public void parseLessons_emptyCollection_returnsEmptySet() throws Exception { + public void parseLessons_emptyCollection_returnsEmptyList() throws Exception { assertTrue(ParserUtil.parseLessons(Collections.emptyList()).isEmpty()); } @Test - public void parseLessons_collectionWithValidTags_returnsTagSet() throws Exception { - Set actualLessonSet = ParserUtil.parseLessons(Arrays.asList(VALID_LESSON_1, VALID_LESSON_2)); - Set expectedLessonSet = new HashSet(Arrays.asList(new Lesson(VALID_LESSON_1), - new Lesson(VALID_LESSON_2))); + public void parseLessons_collectionWithValidLessons_returnsLessonList() throws Exception { + List actualLessonList = ParserUtil.parseLessons(Arrays.asList(VALID_LESSON_1, VALID_LESSON_2)); + List expectedLessonSet = new ArrayList<>(Arrays.asList( + new Lesson(VALID_SUBJECT_MATHS, VALID_DATE_1, VALID_TIME_1), + new Lesson(VALID_SUBJECT_SCIENCE, VALID_DATE_1, VALID_TIME_1))); - assertEquals(expectedLessonSet, actualLessonSet); + assertEquals(expectedLessonSet, actualLessonList); } } diff --git a/src/test/java/seedu/address/model/student/LessonTest.java b/src/test/java/seedu/address/model/student/LessonTest.java index a343c976b91..c36323cf278 100644 --- a/src/test/java/seedu/address/model/student/LessonTest.java +++ b/src/test/java/seedu/address/model/student/LessonTest.java @@ -5,19 +5,24 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static seedu.address.testutil.Assert.assertThrows; +import java.time.LocalDate; +import java.time.LocalTime; + import org.junit.jupiter.api.Test; public class LessonTest { @Test public void constructor_null_throwsNullPointerException() { - assertThrows(NullPointerException.class, () -> new Lesson(null)); + assertThrows(NullPointerException.class, () -> new Lesson(null, null, null)); } @Test public void constructor_invalidLesson_throwsIllegalArgumentException() { - String invalidLesson = ""; - assertThrows(IllegalArgumentException.class, () -> new Lesson(invalidLesson)); + String invalidSubject = ""; + LocalDate validDate = LocalDate.parse("10-01-2023", Lesson.DATE_FORMATTER); + LocalTime validTime = LocalTime.parse("23:00", Lesson.TIME_FORMATTER); + assertThrows(IllegalArgumentException.class, () -> new Lesson(invalidSubject, validDate, validTime)); } @Test @@ -28,21 +33,24 @@ public void isValidLesson() { // invalid lessons assertFalse(Lesson.isValidLesson("")); // empty string assertFalse(Lesson.isValidLesson(" ")); // spaces only - assertFalse(Lesson.isValidLesson("Math|invalidDate|09:00|0")); // invalid date format - assertFalse(Lesson.isValidLesson("Math|01-01-2023|invalidTime|0")); // invalid time format - assertFalse(Lesson.isValidLesson("Math|01-01-2023|09:00|2")); // invalid isCompleted value + assertFalse(Lesson.isValidLesson("Math|invalidDate|09:00")); // invalid date format + assertFalse(Lesson.isValidLesson("Math|01-01-2023|invalidTime")); // invalid time format // valid lessons - assertTrue(Lesson.isValidLesson("Math|01-01-2023|09:00|0")); - assertTrue(Lesson.isValidLesson("Science|01-01-2023|10:00|1")); + assertTrue(Lesson.isValidLesson("Math|01-01-2023|09:00")); + assertTrue(Lesson.isValidLesson("Science|01-01-2023|10:00")); } @Test public void equals() { - Lesson lesson = new Lesson("Math|01-01-2023|09:00|0"); + Lesson lesson = new Lesson("Math", LocalDate.parse("01-01-2023", Lesson.DATE_FORMATTER), + LocalTime.parse("09:00", Lesson.TIME_FORMATTER)); // same values -> returns true - assertTrue(lesson.equals(new Lesson("Math|01-01-2023|09:00|0"))); + String validLesson = "Math"; + LocalDate validDate = LocalDate.parse("01-01-2023", Lesson.DATE_FORMATTER); + LocalTime validTime = LocalTime.parse("09:00", Lesson.TIME_FORMATTER); + assertTrue(lesson.equals(new Lesson(validLesson, validDate, validTime))); // same object -> returns true assertEquals(lesson, lesson); @@ -54,6 +62,7 @@ public void equals() { assertFalse(lesson.equals(5.0f)); // different values -> returns false - assertFalse(lesson.equals(new Lesson("Science|01-01-2023|09:00|0"))); + String differentLesson = "Science"; + assertFalse(lesson.equals(new Lesson(differentLesson, validDate, validTime))); } } diff --git a/src/test/java/seedu/address/model/student/StudentTest.java b/src/test/java/seedu/address/model/student/StudentTest.java index 79c98292717..50b4723acab 100644 --- a/src/test/java/seedu/address/model/student/StudentTest.java +++ b/src/test/java/seedu/address/model/student/StudentTest.java @@ -8,7 +8,6 @@ import static seedu.address.logic.commands.CommandTestUtil.VALID_LESSON_AMY; import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_BOB; import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB; -import static seedu.address.testutil.Assert.assertThrows; import static seedu.address.testutil.TypicalStudents.ALICE; import static seedu.address.testutil.TypicalStudents.BOB; @@ -18,12 +17,6 @@ public class StudentTest { - @Test - public void asObservableList_modifyList_throwsUnsupportedOperationException() { - Student person = new StudentBuilder().build(); - assertThrows(UnsupportedOperationException.class, () -> person.getLessons().remove(0)); - } - @Test public void isSameStudent() { // same object -> returns true diff --git a/src/test/java/seedu/address/model/util/SampleDataUtilTest.java b/src/test/java/seedu/address/model/util/SampleDataUtilTest.java index d4c81b7d5ef..e84885f44a0 100644 --- a/src/test/java/seedu/address/model/util/SampleDataUtilTest.java +++ b/src/test/java/seedu/address/model/util/SampleDataUtilTest.java @@ -4,10 +4,12 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; -import java.util.Set; +import java.util.List; import org.junit.jupiter.api.Test; +import seedu.address.logic.parser.ParserUtil; +import seedu.address.logic.parser.exceptions.ParseException; import seedu.address.model.ReadOnlyAddressBook; import seedu.address.model.student.Lesson; import seedu.address.model.student.Student; @@ -27,10 +29,10 @@ void getSampleAddressBook() { } @Test - void getLessonSet() { - Set lessonSet = SampleDataUtil.getLessonSet("Maths|10-05-2004|12:29|0", "English|10-05-2004|12:29|1"); - assertEquals(2, lessonSet.size()); - assertTrue(lessonSet.contains(new Lesson("Maths|10-05-2004|12:29|0"))); - assertTrue(lessonSet.contains(new Lesson("English|10-05-2004|12:29|1"))); + void getLessonList() throws ParseException { + List lessonList = SampleDataUtil.getLessonList("Maths|10-05-2004|12:29", "English|10-05-2004|12:29"); + assertEquals(2, lessonList.size()); + assertTrue(lessonList.contains(ParserUtil.parseLesson("Maths|10-05-2004|12:29"))); + assertTrue(lessonList.contains(ParserUtil.parseLesson("English|10-05-2004|12:29"))); } } diff --git a/src/test/java/seedu/address/testutil/EditStudentDescriptorBuilder.java b/src/test/java/seedu/address/testutil/EditStudentDescriptorBuilder.java index e4fe729f9fd..e4877b17e8a 100644 --- a/src/test/java/seedu/address/testutil/EditStudentDescriptorBuilder.java +++ b/src/test/java/seedu/address/testutil/EditStudentDescriptorBuilder.java @@ -1,8 +1,8 @@ package seedu.address.testutil; -import java.util.Set; +import java.util.Arrays; +import java.util.List; import java.util.stream.Collectors; -import java.util.stream.Stream; import seedu.address.logic.commands.EditCommand.EditStudentDescriptor; import seedu.address.model.student.Address; @@ -13,6 +13,7 @@ import seedu.address.model.student.Remark; import seedu.address.model.student.Student; import seedu.address.model.student.Subject; +import seedu.address.storage.JsonAdaptedLesson; /** @@ -75,15 +76,6 @@ public EditStudentDescriptorBuilder withAddress(String address) { descriptor.setAddress(new Address(address)); return this; } - /** - * Parses the {@code lessons} into a {@code Set} and set it to the {@code EditStudentDescriptor} - * that we are building. - */ - public EditStudentDescriptorBuilder withLessons(String... lessons) { - Set lessonSet = Stream.of(lessons).map(Lesson::new).collect(Collectors.toSet()); - descriptor.setLessons(lessonSet); - return this; - } /** * Sets the {@code Subject} of the {@code EditStudentDescriptor} that we are building. */ @@ -101,4 +93,15 @@ public EditStudentDescriptorBuilder withRemark(String remark) { public EditStudentDescriptor build() { return descriptor; } + + /** + * Sets the {@code Lessons} of the {@code EditStudentDescriptor} that we are building. + */ + public EditStudentDescriptorBuilder withLessons(String... lessons) { + List lessonList = Arrays.stream(lessons) + .map(lesson -> JsonAdaptedLesson.parseJsonLesson(lesson)) + .collect(Collectors.toList()); + descriptor.setLessons(lessonList); + return this; + } } diff --git a/src/test/java/seedu/address/testutil/StudentBuilder.java b/src/test/java/seedu/address/testutil/StudentBuilder.java index bb042062127..342e6bb13fb 100644 --- a/src/test/java/seedu/address/testutil/StudentBuilder.java +++ b/src/test/java/seedu/address/testutil/StudentBuilder.java @@ -1,7 +1,11 @@ package seedu.address.testutil; -import java.util.HashSet; -import java.util.Set; +import java.time.LocalDate; +import java.time.LocalTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; import seedu.address.model.student.Address; import seedu.address.model.student.Email; @@ -11,7 +15,7 @@ import seedu.address.model.student.Remark; import seedu.address.model.student.Student; import seedu.address.model.student.Subject; -import seedu.address.model.util.SampleDataUtil; +import seedu.address.storage.JsonAdaptedLesson; /** * A utility class to help with building Student objects. @@ -24,13 +28,15 @@ public class StudentBuilder { public static final String DEFAULT_ADDRESS = "123, Jurong West Ave 6, #08-111"; private static final String DEFAULT_REMARK = ""; private static final String DEFAULT_SUBJECT = "Math"; - private static final String DEFAULT_LESSON = "Math|10-05-2002|13:00|0"; + private static final LocalDate DEFAULT_DATE = LocalDate.parse("10-05-2002", Lesson.DATE_FORMATTER); + private static final LocalTime DEFAULT_TIME = LocalTime.parse("13:00", Lesson.TIME_FORMATTER); + private static final Lesson DEFAULT_LESSON = new Lesson(DEFAULT_SUBJECT, DEFAULT_DATE, DEFAULT_TIME); private Name name; private Phone phone; private Email email; private Address address; private Subject subject; - private Set lessons; + private List lessons; private Remark remark; /** @@ -42,7 +48,7 @@ public StudentBuilder() { email = new Email(DEFAULT_EMAIL); address = new Address(DEFAULT_ADDRESS); subject = new Subject(DEFAULT_SUBJECT); - lessons = new HashSet<>(); + lessons = new ArrayList<>(); remark = new Remark(DEFAULT_REMARK); } @@ -55,7 +61,7 @@ public StudentBuilder(Student personToCopy) { email = personToCopy.getEmail(); address = personToCopy.getAddress(); subject = personToCopy.getSubject(); - lessons = new HashSet<>(personToCopy.getLessons()); + lessons = personToCopy.getLessons(); remark = personToCopy.getRemark(); } @@ -68,10 +74,12 @@ public StudentBuilder withName(String name) { } /** - * Parses the {@code lessons} into a {@code Set} and set it to the {@code Student} that we are building. + * Parses the {@code lessons} into a {@code List} and set it to the {@code Student} that we are building. */ - public StudentBuilder withLessons(String ... lessons) { - this.lessons = SampleDataUtil.getLessonSet(lessons); + public StudentBuilder withLessons(String... lessons) { + this.lessons = Arrays.stream(lessons) + .map(JsonAdaptedLesson::parseJsonLesson) + .collect(Collectors.toList()); return this; } diff --git a/src/test/java/seedu/address/testutil/StudentUtil.java b/src/test/java/seedu/address/testutil/StudentUtil.java index dc474c99b04..1b7821a4f14 100644 --- a/src/test/java/seedu/address/testutil/StudentUtil.java +++ b/src/test/java/seedu/address/testutil/StudentUtil.java @@ -7,7 +7,7 @@ import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; import static seedu.address.logic.parser.CliSyntax.PREFIX_SUBJECT; -import java.util.Set; +import java.util.List; import seedu.address.logic.commands.AddCommand; import seedu.address.logic.commands.EditCommand.EditStudentDescriptor; @@ -53,7 +53,7 @@ public static String getEditStudentDescriptorDetails(EditStudentDescriptor descr descriptor.getAddress().ifPresent(address -> sb.append(PREFIX_ADDRESS).append(address.value).append(" ")); descriptor.getSubject().ifPresent(subject -> sb.append(PREFIX_SUBJECT).append(subject.value).append(" ")); if (descriptor.getLessons().isPresent()) { - Set lessons = descriptor.getLessons().get(); + List lessons = descriptor.getLessons().get(); if (lessons.isEmpty()) { sb.append(PREFIX_LESSON); } else { diff --git a/src/test/java/seedu/address/testutil/TypicalStudents.java b/src/test/java/seedu/address/testutil/TypicalStudents.java index 3615787c2c3..51713a10b39 100644 --- a/src/test/java/seedu/address/testutil/TypicalStudents.java +++ b/src/test/java/seedu/address/testutil/TypicalStudents.java @@ -4,6 +4,7 @@ import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB; import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_AMY; import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_BOB; +import static seedu.address.logic.commands.CommandTestUtil.VALID_LESSON_AMY; import static seedu.address.logic.commands.CommandTestUtil.VALID_LESSON_BOB; import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_AMY; import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_BOB; @@ -36,22 +37,22 @@ public class TypicalStudents { .withAddress("311, Clementi Ave 2, #02-25") .withEmail("johnd@example.com").withPhone("98765432") .withSubject("Geography") - .withLessons("Geography|10-05-2004|12:29|0") + .withLessons("Geography|10-05-2004|12:29|1") .build(); public static final Student CARL = new StudentBuilder().withName("Carl Kurz").withPhone("95352563") - .withSubject("English").withLessons("English|10-05-2004|12:29|1") + .withSubject("English").withLessons("English|10-05-2004|12:29|0") .withEmail("heinz@example.com").withAddress("wall street").build(); public static final Student DANIEL = new StudentBuilder().withName("Daniel Meier").withPhone("87652533") - .withSubject("History").withLessons("Geography|10-05-2004|12:29|1") + .withSubject("History").withLessons("Geography|10-05-2004|12:29|0") .withEmail("cornelia@example.com").withAddress("10th street").build(); public static final Student ELLE = new StudentBuilder().withName("Elle Meyer").withPhone("9482224") - .withSubject("Psychology").withLessons("Geography|10-05-2004|12:29|0") + .withSubject("Psychology").withLessons("Geography|10-05-2004|12:29|1") .withEmail("werner@example.com").withAddress("michegan ave").build(); public static final Student FIONA = new StudentBuilder().withName("Fiona Kunz").withPhone("9482427") - .withSubject("English") + .withSubject("English").withLessons("English|10-05-2004|12:29|0") .withEmail("lydia@example.com").withAddress("little tokyo").build(); public static final Student GEORGE = new StudentBuilder().withName("George Best").withPhone("9482442") - .withSubject("Art").withLessons("Art|10-05-2004|12:29|0") + .withSubject("Art").withLessons("Art|10-05-2004|12:29|1") .withEmail("anna@example.com").withAddress("4th street").build(); // Manually added @@ -59,13 +60,13 @@ public class TypicalStudents { .withSubject("Music").withLessons("Science|10-05-2004|12:29|1") .withEmail("stefan@example.com").withAddress("little india").build(); public static final Student IDA = new StudentBuilder().withName("Ida Mueller").withPhone("8482131") - .withSubject("Dance").withLessons("Maths|10-06-2004|12:29|1") + .withSubject("Dance").withLessons("Maths|10-06-2004|12:29|0") .withEmail("hans@example.com").withAddress("chicago ave").build(); // Manually added - Student's details found in {@code CommandTestUtil} public static final Student AMY = new StudentBuilder().withName(VALID_NAME_AMY).withPhone(VALID_PHONE_AMY) .withEmail(VALID_EMAIL_AMY).withAddress(VALID_ADDRESS_AMY) - .withSubject(VALID_SUBJECT_AMY).build(); + .withSubject(VALID_SUBJECT_AMY).withLessons(VALID_LESSON_AMY).build(); public static final Student BOB = new StudentBuilder().withName(VALID_NAME_BOB).withPhone(VALID_PHONE_BOB) .withEmail(VALID_EMAIL_BOB).withAddress(VALID_ADDRESS_BOB).withLessons(VALID_LESSON_BOB) .withSubject(VALID_SUBJECT_BOB).withRemark(VALID_REMARK_BOB).build(); From 5c1807f87b640795e141c01bc9c84fe273a3ff14 Mon Sep 17 00:00:00 2001 From: justinlengch Date: Wed, 3 Apr 2024 20:41:46 +0800 Subject: [PATCH 2/2] Sync branch to master and fix merge conflicts --- .../seedu/address/model/student/LessonTest.java | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/test/java/seedu/address/model/student/LessonTest.java b/src/test/java/seedu/address/model/student/LessonTest.java index b9b424afede..c36323cf278 100644 --- a/src/test/java/seedu/address/model/student/LessonTest.java +++ b/src/test/java/seedu/address/model/student/LessonTest.java @@ -65,19 +65,4 @@ public void equals() { String differentLesson = "Science"; assertFalse(lesson.equals(new Lesson(differentLesson, validDate, validTime))); } - - @Test - public void getLessonStatusIsValid() { - Lesson lesson1 = new Lesson("Math|01-01-2023|09:00|0"); - assertEquals(lesson1.getLessonStatus(), 0); - - Lesson lesson2 = new Lesson("Math|01-01-2023|09:00|1"); - assertEquals(lesson2.getLessonStatus(), 1); - } - - @Test - public void toStringTest() { - Lesson lesson = new Lesson("Math|01-01-2023|09:00|0"); - assertEquals(lesson.toString(), "Math 2023-01-01 09:00"); - } }