From 06f6474020378285f0d00d8ba774cd8cade4ea93 Mon Sep 17 00:00:00 2001 From: notnotmax <156508404+notnotmax@users.noreply.github.com> Date: Thu, 10 Oct 2024 15:36:42 +0800 Subject: [PATCH 1/8] Add Course.java --- .../seedu/address/model/course/Course.java | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 src/main/java/seedu/address/model/course/Course.java diff --git a/src/main/java/seedu/address/model/course/Course.java b/src/main/java/seedu/address/model/course/Course.java new file mode 100644 index 00000000000..88af8f3aaf6 --- /dev/null +++ b/src/main/java/seedu/address/model/course/Course.java @@ -0,0 +1,63 @@ +package seedu.address.model.course; + +import static java.util.Objects.requireNonNull; + +import static seedu.address.commons.util.AppUtil.checkArgument; + +/** + * Represents a Student's course in the system. + * Guarantees: immutable; is valid as declared in {@link #isValidCourse(String)} + */ +public class Course { + public static final String MESSAGE_CONSTRAINTS = "Courses should be in the format of two to four letters " + + "followed by four digits, followed by 0-2 letters: e.g., MA1100, GEA1000N, GESS1000T etc."; + /* + * The course code must follow the format specified in MESSAGE_CONSTRAINTS as shown above. + */ + public static final String VALIDATION_REGEX = "[a-zA-Z]{2,4}\\d{4}[a-zA-Z]{0,2}"; + + public final String courseCode; + + /** + * Constructs a {@code Course}. + * + * @param courseCode A valid course code. + */ + public Course(String courseCode) { + requireNonNull(courseCode); + checkArgument(isValidCourse(courseCode), MESSAGE_CONSTRAINTS); + this.courseCode = courseCode; + } + + /** + * Returns true if a given string is a valid course code. + */ + public static boolean isValidCourse(String test) { + return test.matches(VALIDATION_REGEX); + } + + @Override + public String toString() { + return courseCode; + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof Course)) { + return false; + } + + Course otherCourse = (Course) other; + return courseCode.equals(otherCourse.courseCode); + } + + @Override + public int hashCode() { + return courseCode.hashCode(); + } +} \ No newline at end of file From ad55990a368f9bd2f71bba108a858c276a050e29 Mon Sep 17 00:00:00 2001 From: notnotmax <156508404+notnotmax@users.noreply.github.com> Date: Thu, 10 Oct 2024 15:43:54 +0800 Subject: [PATCH 2/8] Link Course.java to Person.java --- .../seedu/address/model/person/Person.java | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/main/java/seedu/address/model/person/Person.java b/src/main/java/seedu/address/model/person/Person.java index abe8c46b535..5d8723ec57d 100644 --- a/src/main/java/seedu/address/model/person/Person.java +++ b/src/main/java/seedu/address/model/person/Person.java @@ -8,6 +8,7 @@ import java.util.Set; import seedu.address.commons.util.ToStringBuilder; +import seedu.address.model.course.Course; import seedu.address.model.tag.Tag; /** @@ -24,17 +25,19 @@ public class Person { // Data fields private final Address address; private final Set tags = new HashSet<>(); + private final Set courses = new HashSet<>(); /** * Every field must be present and not null. */ - public Person(Name name, Phone phone, Email email, Address address, Set tags) { - requireAllNonNull(name, phone, email, address, tags); + public Person(Name name, Phone phone, Email email, Address address, Set tags, Set courses) { + requireAllNonNull(name, phone, email, address, tags, courses); this.name = name; this.phone = phone; this.email = email; this.address = address; this.tags.addAll(tags); + this.courses.addAll(courses); } public Name getName() { @@ -61,6 +64,14 @@ public Set getTags() { return Collections.unmodifiableSet(tags); } + /** + * Returns an immutable course set, which throws {@code UnsupportedOperationException} + * if modification is attempted. + */ + public Set getCourses() { + return Collections.unmodifiableSet(courses); + } + /** * Returns true if both persons have the same name. * This defines a weaker notion of equality between two persons. @@ -94,13 +105,14 @@ public boolean equals(Object other) { && phone.equals(otherPerson.phone) && email.equals(otherPerson.email) && address.equals(otherPerson.address) - && tags.equals(otherPerson.tags); + && tags.equals(otherPerson.tags) + && courses.equals(otherPerson.courses); } @Override public int hashCode() { // use this method for custom fields hashing instead of implementing your own - return Objects.hash(name, phone, email, address, tags); + return Objects.hash(name, phone, email, address, tags, courses); } @Override @@ -111,6 +123,7 @@ public String toString() { .add("email", email) .add("address", address) .add("tags", tags) + .add("courses", courses) .toString(); } From adf9a77550c98fab0a55409637605714adb03f16 Mon Sep 17 00:00:00 2001 From: notnotmax <156508404+notnotmax@users.noreply.github.com> Date: Thu, 10 Oct 2024 16:00:17 +0800 Subject: [PATCH 3/8] Make course codes case insensitive --- src/main/java/seedu/address/model/course/Course.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/seedu/address/model/course/Course.java b/src/main/java/seedu/address/model/course/Course.java index 88af8f3aaf6..8af0f7e5774 100644 --- a/src/main/java/seedu/address/model/course/Course.java +++ b/src/main/java/seedu/address/model/course/Course.java @@ -19,14 +19,14 @@ public class Course { public final String courseCode; /** - * Constructs a {@code Course}. + * Constructs a {@code Course} and converts the given courseCode into uppercase. * - * @param courseCode A valid course code. + * @param courseCode A valid course code, case-insensitive. */ public Course(String courseCode) { requireNonNull(courseCode); checkArgument(isValidCourse(courseCode), MESSAGE_CONSTRAINTS); - this.courseCode = courseCode; + this.courseCode = courseCode.toUpperCase(); } /** From 6dd4622baa9a6f54634c7b1880f76154ce313758 Mon Sep 17 00:00:00 2001 From: notnotmax <156508404+notnotmax@users.noreply.github.com> Date: Thu, 10 Oct 2024 16:00:34 +0800 Subject: [PATCH 4/8] Add CourseTest.java --- .../address/model/course/CourseTest.java | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/test/java/seedu/address/model/course/CourseTest.java diff --git a/src/test/java/seedu/address/model/course/CourseTest.java b/src/test/java/seedu/address/model/course/CourseTest.java new file mode 100644 index 00000000000..bb2417ecf5a --- /dev/null +++ b/src/test/java/seedu/address/model/course/CourseTest.java @@ -0,0 +1,55 @@ +package seedu.address.model.course; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +public class CourseTest { + + @Test + public void constructor_null_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> new Course(null)); + } + + @Test + public void constructor_emptyCourseCode_throwsIllegalArgumentException() { + String invalidTagName = ""; + assertThrows(IllegalArgumentException.class, () -> new Course(invalidTagName)); + } + + @Test + public void constructor_invalidCourseCode_throwsIllegalArgumentException() { + String invalidTagName = "CS1K"; + assertThrows(IllegalArgumentException.class, () -> new Course(invalidTagName)); + } + + @Test + public void constructor_isValidCourseCode_1_success() { + assertDoesNotThrow(() -> new Course("MA1100")); + } + + @Test + public void constructor_isValidCourseCode_2_success() { + assertDoesNotThrow(() -> new Course("CS1231S")); + } + + @Test + public void constructor_isValidCourseCode_3_success() { + assertDoesNotThrow(() -> new Course("GEA1000N")); + } + + @Test + public void constructor_lowercaseCourseCode_success() { + assertDoesNotThrow(() -> new Course("cs2109s")); + } + + @Test + public void equals_caseInsensitive() { + Course c1 = new Course("CS1101S"); + Course c2 = new Course("cs1101s"); + assertTrue(() -> c1.equals(c2)); + } + +} From 423a79219a6d977b9b32eb034ac33ef9d9e500f7 Mon Sep 17 00:00:00 2001 From: notnotmax <156508404+notnotmax@users.noreply.github.com> Date: Thu, 10 Oct 2024 16:03:50 +0800 Subject: [PATCH 5/8] Add newline at EOF --- src/main/java/seedu/address/model/course/Course.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/address/model/course/Course.java b/src/main/java/seedu/address/model/course/Course.java index 8af0f7e5774..c080090d19c 100644 --- a/src/main/java/seedu/address/model/course/Course.java +++ b/src/main/java/seedu/address/model/course/Course.java @@ -60,4 +60,4 @@ public boolean equals(Object other) { public int hashCode() { return courseCode.hashCode(); } -} \ No newline at end of file +} From b9c879cf1d8dedfa4a77e32460eba879204b52e6 Mon Sep 17 00:00:00 2001 From: notnotmax <156508404+notnotmax@users.noreply.github.com> Date: Thu, 10 Oct 2024 16:07:50 +0800 Subject: [PATCH 6/8] Fix style errors --- src/main/java/seedu/address/model/course/Course.java | 1 - src/test/java/seedu/address/model/course/CourseTest.java | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/seedu/address/model/course/Course.java b/src/main/java/seedu/address/model/course/Course.java index c080090d19c..b787ed54362 100644 --- a/src/main/java/seedu/address/model/course/Course.java +++ b/src/main/java/seedu/address/model/course/Course.java @@ -1,7 +1,6 @@ package seedu.address.model.course; import static java.util.Objects.requireNonNull; - import static seedu.address.commons.util.AppUtil.checkArgument; /** diff --git a/src/test/java/seedu/address/model/course/CourseTest.java b/src/test/java/seedu/address/model/course/CourseTest.java index bb2417ecf5a..00399bbdb5d 100644 --- a/src/test/java/seedu/address/model/course/CourseTest.java +++ b/src/test/java/seedu/address/model/course/CourseTest.java @@ -26,17 +26,17 @@ public void constructor_invalidCourseCode_throwsIllegalArgumentException() { } @Test - public void constructor_isValidCourseCode_1_success() { + public void constructor_isValidCourseCode1_success() { assertDoesNotThrow(() -> new Course("MA1100")); } @Test - public void constructor_isValidCourseCode_2_success() { + public void constructor_isValidCourseCode2_success() { assertDoesNotThrow(() -> new Course("CS1231S")); } @Test - public void constructor_isValidCourseCode_3_success() { + public void constructor_isValidCourseCode3_success() { assertDoesNotThrow(() -> new Course("GEA1000N")); } From f7ac2c1d8ddbfa39c4ad4d89e4b6bac1f63e8ebf Mon Sep 17 00:00:00 2001 From: notnotmax <156508404+notnotmax@users.noreply.github.com> Date: Thu, 10 Oct 2024 16:46:06 +0800 Subject: [PATCH 7/8] Link Course to usages of Person --- .../address/logic/commands/EditCommand.java | 29 ++++++++++-- .../logic/parser/AddCommandParser.java | 5 +- .../seedu/address/logic/parser/CliSyntax.java | 1 + .../address/logic/parser/ParserUtil.java | 28 +++++++++++ .../address/model/util/SampleDataUtil.java | 22 ++++++--- .../address/storage/JsonAdaptedCourse.java | 47 +++++++++++++++++++ .../address/storage/JsonAdaptedPerson.java | 21 ++++++++- .../address/model/person/PersonTest.java | 3 +- .../storage/JsonAdaptedPersonTest.java | 21 +++++---- .../seedu/address/testutil/PersonBuilder.java | 14 +++++- 10 files changed, 168 insertions(+), 23 deletions(-) create mode 100644 src/main/java/seedu/address/storage/JsonAdaptedCourse.java diff --git a/src/main/java/seedu/address/logic/commands/EditCommand.java b/src/main/java/seedu/address/logic/commands/EditCommand.java index 4b581c7331e..3ead740edc3 100644 --- a/src/main/java/seedu/address/logic/commands/EditCommand.java +++ b/src/main/java/seedu/address/logic/commands/EditCommand.java @@ -21,6 +21,7 @@ import seedu.address.logic.Messages; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.model.Model; +import seedu.address.model.course.Course; import seedu.address.model.person.Address; import seedu.address.model.person.Email; import seedu.address.model.person.Name; @@ -100,8 +101,9 @@ private static Person createEditedPerson(Person personToEdit, EditPersonDescript Email updatedEmail = editPersonDescriptor.getEmail().orElse(personToEdit.getEmail()); Address updatedAddress = editPersonDescriptor.getAddress().orElse(personToEdit.getAddress()); Set updatedTags = editPersonDescriptor.getTags().orElse(personToEdit.getTags()); + Set updatedCourses = editPersonDescriptor.getCourses().orElse(personToEdit.getCourses()); - return new Person(updatedName, updatedPhone, updatedEmail, updatedAddress, updatedTags); + return new Person(updatedName, updatedPhone, updatedEmail, updatedAddress, updatedTags, updatedCourses); } @Override @@ -138,6 +140,7 @@ public static class EditPersonDescriptor { private Email email; private Address address; private Set tags; + private Set courses; public EditPersonDescriptor() {} @@ -151,13 +154,14 @@ public EditPersonDescriptor(EditPersonDescriptor toCopy) { setEmail(toCopy.email); setAddress(toCopy.address); setTags(toCopy.tags); + setCourses(toCopy.courses); } /** * Returns true if at least one field is edited. */ public boolean isAnyFieldEdited() { - return CollectionUtil.isAnyNonNull(name, phone, email, address, tags); + return CollectionUtil.isAnyNonNull(name, phone, email, address, tags, courses); } public void setName(Name name) { @@ -209,6 +213,23 @@ public Optional> getTags() { return (tags != null) ? Optional.of(Collections.unmodifiableSet(tags)) : Optional.empty(); } + /** + * Sets {@code courses} to this object's {@code courses}. + * A defensive copy of {@code courses} is used internally. + */ + public void setCourses(Set courses) { + this.courses = (courses != null) ? new HashSet<>(courses) : null; + } + + /** + * Returns an unmodifiable course set, which throws {@code UnsupportedOperationException} + * if modification is attempted. + * Returns {@code Optional#empty()} if {@code courses} is null. + */ + public Optional> getCourses() { + return (tags != null) ? Optional.of(Collections.unmodifiableSet(courses)) : Optional.empty(); + } + @Override public boolean equals(Object other) { if (other == this) { @@ -225,7 +246,8 @@ public boolean equals(Object other) { && Objects.equals(phone, otherEditPersonDescriptor.phone) && Objects.equals(email, otherEditPersonDescriptor.email) && Objects.equals(address, otherEditPersonDescriptor.address) - && Objects.equals(tags, otherEditPersonDescriptor.tags); + && Objects.equals(tags, otherEditPersonDescriptor.tags) + && Objects.equals(courses, otherEditPersonDescriptor.courses); } @Override @@ -236,6 +258,7 @@ public String toString() { .add("email", email) .add("address", address) .add("tags", tags) + .add("courses", courses) .toString(); } } diff --git a/src/main/java/seedu/address/logic/parser/AddCommandParser.java b/src/main/java/seedu/address/logic/parser/AddCommandParser.java index 4ff1a97ed77..c5b4cbba4a1 100644 --- a/src/main/java/seedu/address/logic/parser/AddCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/AddCommandParser.java @@ -6,12 +6,14 @@ 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_TAG; +import static seedu.address.logic.parser.CliSyntax.PREFIX_COURSE; import java.util.Set; import java.util.stream.Stream; import seedu.address.logic.commands.AddCommand; import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.course.Course; import seedu.address.model.person.Address; import seedu.address.model.person.Email; import seedu.address.model.person.Name; @@ -44,8 +46,9 @@ public AddCommand parse(String args) throws ParseException { Email email = ParserUtil.parseEmail(argMultimap.getValue(PREFIX_EMAIL).get()); Address address = ParserUtil.parseAddress(argMultimap.getValue(PREFIX_ADDRESS).get()); Set tagList = ParserUtil.parseTags(argMultimap.getAllValues(PREFIX_TAG)); + Set courseList = ParserUtil.parseCourses(argMultimap.getAllValues(PREFIX_COURSE)); - Person person = new Person(name, phone, email, address, tagList); + Person person = new Person(name, phone, email, address, tagList, courseList); return new AddCommand(person); } diff --git a/src/main/java/seedu/address/logic/parser/CliSyntax.java b/src/main/java/seedu/address/logic/parser/CliSyntax.java index 75b1a9bf119..17b8f8ec3e9 100644 --- a/src/main/java/seedu/address/logic/parser/CliSyntax.java +++ b/src/main/java/seedu/address/logic/parser/CliSyntax.java @@ -11,5 +11,6 @@ public class CliSyntax { public static final Prefix PREFIX_EMAIL = new Prefix("e/"); public static final Prefix PREFIX_ADDRESS = new Prefix("a/"); public static final Prefix PREFIX_TAG = new Prefix("t/"); + public static final Prefix PREFIX_COURSE = new Prefix("c/"); } diff --git a/src/main/java/seedu/address/logic/parser/ParserUtil.java b/src/main/java/seedu/address/logic/parser/ParserUtil.java index b117acb9c55..1f6dbb6ff12 100644 --- a/src/main/java/seedu/address/logic/parser/ParserUtil.java +++ b/src/main/java/seedu/address/logic/parser/ParserUtil.java @@ -9,6 +9,7 @@ import seedu.address.commons.core.index.Index; import seedu.address.commons.util.StringUtil; import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.course.Course; import seedu.address.model.person.Address; import seedu.address.model.person.Email; import seedu.address.model.person.Name; @@ -121,4 +122,31 @@ public static Set parseTags(Collection tags) throws ParseException } return tagSet; } + + /** + * Parses a {@code String course} into a {@code Course}. + * Leading and trailing whitespaces will be trimmed. + * + * @throws ParseException if the given {@code tag} is invalid. + */ + public static Course parseCourse(String course) throws ParseException { + requireNonNull(course); + String trimmedCourse = course.trim(); + if (!Course.isValidCourse(trimmedCourse)) { + throw new ParseException(Course.MESSAGE_CONSTRAINTS); + } + return new Course(trimmedCourse); + } + + /** + * Parses {@code Collection courses} into a {@code Set}. + */ + public static Set parseCourses(Collection courses) throws ParseException { + requireNonNull(courses); + final Set courseSet = new HashSet<>(); + for (String courseName : courses) { + courseSet.add(parseCourse(courseName)); + } + return courseSet; + } } diff --git a/src/main/java/seedu/address/model/util/SampleDataUtil.java b/src/main/java/seedu/address/model/util/SampleDataUtil.java index 1806da4facf..cdcb0450c58 100644 --- a/src/main/java/seedu/address/model/util/SampleDataUtil.java +++ b/src/main/java/seedu/address/model/util/SampleDataUtil.java @@ -6,6 +6,7 @@ import seedu.address.model.AddressBook; import seedu.address.model.ReadOnlyAddressBook; +import seedu.address.model.course.Course; import seedu.address.model.person.Address; import seedu.address.model.person.Email; import seedu.address.model.person.Name; @@ -21,22 +22,22 @@ public static Person[] getSamplePersons() { return new Person[] { new Person(new Name("Alex Yeoh"), new Phone("87438807"), new Email("alexyeoh@example.com"), new Address("Blk 30 Geylang Street 29, #06-40"), - getTagSet("friends")), + getTagSet("friends"), getCourseSet("cs2103t")), new Person(new Name("Bernice Yu"), new Phone("99272758"), new Email("berniceyu@example.com"), new Address("Blk 30 Lorong 3 Serangoon Gardens, #07-18"), - getTagSet("colleagues", "friends")), + getTagSet("colleagues", "friends"), getCourseSet("cs2103t, cs2109s")), new Person(new Name("Charlotte Oliveiro"), new Phone("93210283"), new Email("charlotte@example.com"), new Address("Blk 11 Ang Mo Kio Street 74, #11-04"), - getTagSet("neighbours")), + getTagSet("neighbours"), getCourseSet("ma1100")), new Person(new Name("David Li"), new Phone("91031282"), new Email("lidavid@example.com"), new Address("Blk 436 Serangoon Gardens Street 26, #16-43"), - getTagSet("family")), + getTagSet("family"), getCourseSet("ma1100, ma2104, ma2108")), new Person(new Name("Irfan Ibrahim"), new Phone("92492021"), new Email("irfan@example.com"), new Address("Blk 47 Tampines Street 20, #17-35"), - getTagSet("classmates")), + getTagSet("classmates"), getCourseSet("CS3230, CS3263, CS3264")), new Person(new Name("Roy Balakrishnan"), new Phone("92624417"), new Email("royb@example.com"), new Address("Blk 45 Aljunied Street 85, #11-31"), - getTagSet("colleagues")) + getTagSet("colleagues"), getCourseSet()) }; } @@ -57,4 +58,13 @@ public static Set getTagSet(String... strings) { .collect(Collectors.toSet()); } + /** + * Returns a course set containing the list of strings given. + */ + public static Set getCourseSet(String... strings) { + return Arrays.stream(strings) + .map(Course::new) + .collect(Collectors.toSet()); + } + } diff --git a/src/main/java/seedu/address/storage/JsonAdaptedCourse.java b/src/main/java/seedu/address/storage/JsonAdaptedCourse.java new file mode 100644 index 00000000000..73ba62ff7c1 --- /dev/null +++ b/src/main/java/seedu/address/storage/JsonAdaptedCourse.java @@ -0,0 +1,47 @@ +package seedu.address.storage; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import seedu.address.commons.exceptions.IllegalValueException; +import seedu.address.model.course.Course; + +/** + * Jackson-friendly version of {@link Course}. + */ +class JsonAdaptedCourse { + + private final String courseCode; + + /** + * Constructs a {@code JsonAdaptedCourse} with the given {@code courseCode}. + */ + @JsonCreator + public JsonAdaptedCourse(String courseCode) { + this.courseCode = courseCode; + } + + /** + * Converts a given {@code Course} into this class for Jackson use. + */ + public JsonAdaptedCourse(Course source) { + courseCode = source.courseCode; + } + + @JsonValue + public String getCourseCode() { + return courseCode; + } + + /** + * Converts this Jackson-friendly adapted tag object into the model's {@code Course} object. + * + * @throws IllegalValueException if there were any data constraints violated in the adapted tag. + */ + public Course toModelType() throws IllegalValueException { + if (!Course.isValidCourse(courseCode)) { + throw new IllegalValueException(Course.MESSAGE_CONSTRAINTS); + } + return new Course(courseCode); + } + +} diff --git a/src/main/java/seedu/address/storage/JsonAdaptedPerson.java b/src/main/java/seedu/address/storage/JsonAdaptedPerson.java index bd1ca0f56c8..b06149d70e9 100644 --- a/src/main/java/seedu/address/storage/JsonAdaptedPerson.java +++ b/src/main/java/seedu/address/storage/JsonAdaptedPerson.java @@ -10,6 +10,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import seedu.address.commons.exceptions.IllegalValueException; +import seedu.address.model.course.Course; import seedu.address.model.person.Address; import seedu.address.model.person.Email; import seedu.address.model.person.Name; @@ -29,6 +30,7 @@ class JsonAdaptedPerson { private final String email; private final String address; private final List tags = new ArrayList<>(); + private final List courses = new ArrayList<>(); /** * Constructs a {@code JsonAdaptedPerson} with the given person details. @@ -36,7 +38,8 @@ class JsonAdaptedPerson { @JsonCreator public JsonAdaptedPerson(@JsonProperty("name") String name, @JsonProperty("phone") String phone, @JsonProperty("email") String email, @JsonProperty("address") String address, - @JsonProperty("tags") List tags) { + @JsonProperty("tags") List tags, + @JsonProperty("courses") List courses) { this.name = name; this.phone = phone; this.email = email; @@ -44,6 +47,9 @@ public JsonAdaptedPerson(@JsonProperty("name") String name, @JsonProperty("phone if (tags != null) { this.tags.addAll(tags); } + if (courses != null) { + this.courses.addAll(courses); + } } /** @@ -57,6 +63,9 @@ public JsonAdaptedPerson(Person source) { tags.addAll(source.getTags().stream() .map(JsonAdaptedTag::new) .collect(Collectors.toList())); + courses.addAll(source.getCourses().stream() + .map(JsonAdaptedCourse::new) + .collect(Collectors.toList())); } /** @@ -66,9 +75,14 @@ public JsonAdaptedPerson(Person source) { */ public Person toModelType() throws IllegalValueException { final List personTags = new ArrayList<>(); + final List personCourses = new ArrayList<>(); + for (JsonAdaptedTag tag : tags) { personTags.add(tag.toModelType()); } + for (JsonAdaptedCourse course : courses) { + personCourses.add(course.toModelType()); + } if (name == null) { throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Name.class.getSimpleName())); @@ -103,7 +117,10 @@ public Person toModelType() throws IllegalValueException { final Address modelAddress = new Address(address); final Set modelTags = new HashSet<>(personTags); - return new Person(modelName, modelPhone, modelEmail, modelAddress, modelTags); + + final Set modelCourses = new HashSet<>(personCourses); + + return new Person(modelName, modelPhone, modelEmail, modelAddress, modelTags, modelCourses); } } diff --git a/src/test/java/seedu/address/model/person/PersonTest.java b/src/test/java/seedu/address/model/person/PersonTest.java index 31a10d156c9..758f31f2f6c 100644 --- a/src/test/java/seedu/address/model/person/PersonTest.java +++ b/src/test/java/seedu/address/model/person/PersonTest.java @@ -93,7 +93,8 @@ public void equals() { @Test public void toStringMethod() { String expected = Person.class.getCanonicalName() + "{name=" + ALICE.getName() + ", phone=" + ALICE.getPhone() - + ", email=" + ALICE.getEmail() + ", address=" + ALICE.getAddress() + ", tags=" + ALICE.getTags() + "}"; + + ", email=" + ALICE.getEmail() + ", address=" + ALICE.getAddress() + ", tags=" + ALICE.getTags() + + ", courses=" + ALICE.getCourses() + "}"; assertEquals(expected, ALICE.toString()); } } diff --git a/src/test/java/seedu/address/storage/JsonAdaptedPersonTest.java b/src/test/java/seedu/address/storage/JsonAdaptedPersonTest.java index 83b11331cdb..908072e8d81 100644 --- a/src/test/java/seedu/address/storage/JsonAdaptedPersonTest.java +++ b/src/test/java/seedu/address/storage/JsonAdaptedPersonTest.java @@ -31,6 +31,9 @@ public class JsonAdaptedPersonTest { private static final List VALID_TAGS = BENSON.getTags().stream() .map(JsonAdaptedTag::new) .collect(Collectors.toList()); + private static final List VALID_COURSES = BENSON.getCourses().stream() + .map(JsonAdaptedCourse::new) + .collect(Collectors.toList()); @Test public void toModelType_validPersonDetails_returnsPerson() throws Exception { @@ -41,14 +44,14 @@ public void toModelType_validPersonDetails_returnsPerson() throws Exception { @Test public void toModelType_invalidName_throwsIllegalValueException() { JsonAdaptedPerson person = - new JsonAdaptedPerson(INVALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS); + new JsonAdaptedPerson(INVALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS, VALID_COURSES); String expectedMessage = Name.MESSAGE_CONSTRAINTS; assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); } @Test public void toModelType_nullName_throwsIllegalValueException() { - JsonAdaptedPerson person = new JsonAdaptedPerson(null, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS); + JsonAdaptedPerson person = new JsonAdaptedPerson(null, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS, VALID_COURSES); String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Name.class.getSimpleName()); assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); } @@ -56,14 +59,14 @@ public void toModelType_nullName_throwsIllegalValueException() { @Test public void toModelType_invalidPhone_throwsIllegalValueException() { JsonAdaptedPerson person = - new JsonAdaptedPerson(VALID_NAME, INVALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS); + new JsonAdaptedPerson(VALID_NAME, INVALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS, VALID_COURSES); String expectedMessage = Phone.MESSAGE_CONSTRAINTS; assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); } @Test public void toModelType_nullPhone_throwsIllegalValueException() { - JsonAdaptedPerson person = new JsonAdaptedPerson(VALID_NAME, null, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS); + JsonAdaptedPerson person = new JsonAdaptedPerson(VALID_NAME, null, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS, VALID_COURSES); String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Phone.class.getSimpleName()); assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); } @@ -71,14 +74,14 @@ public void toModelType_nullPhone_throwsIllegalValueException() { @Test public void toModelType_invalidEmail_throwsIllegalValueException() { JsonAdaptedPerson person = - new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, INVALID_EMAIL, VALID_ADDRESS, VALID_TAGS); + new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, INVALID_EMAIL, VALID_ADDRESS, VALID_TAGS, VALID_COURSES); String expectedMessage = Email.MESSAGE_CONSTRAINTS; assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); } @Test public void toModelType_nullEmail_throwsIllegalValueException() { - JsonAdaptedPerson person = new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, null, VALID_ADDRESS, VALID_TAGS); + JsonAdaptedPerson person = new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, null, VALID_ADDRESS, VALID_TAGS, VALID_COURSES); String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Email.class.getSimpleName()); assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); } @@ -86,14 +89,14 @@ public void toModelType_nullEmail_throwsIllegalValueException() { @Test public void toModelType_invalidAddress_throwsIllegalValueException() { JsonAdaptedPerson person = - new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, INVALID_ADDRESS, VALID_TAGS); + new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, INVALID_ADDRESS, VALID_TAGS, VALID_COURSES); String expectedMessage = Address.MESSAGE_CONSTRAINTS; assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); } @Test public void toModelType_nullAddress_throwsIllegalValueException() { - JsonAdaptedPerson person = new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, null, VALID_TAGS); + JsonAdaptedPerson person = new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, null, VALID_TAGS, VALID_COURSES); String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Address.class.getSimpleName()); assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); } @@ -103,7 +106,7 @@ public void toModelType_invalidTags_throwsIllegalValueException() { List invalidTags = new ArrayList<>(VALID_TAGS); invalidTags.add(new JsonAdaptedTag(INVALID_TAG)); JsonAdaptedPerson person = - new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, invalidTags); + new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, invalidTags, VALID_COURSES); assertThrows(IllegalValueException.class, person::toModelType); } diff --git a/src/test/java/seedu/address/testutil/PersonBuilder.java b/src/test/java/seedu/address/testutil/PersonBuilder.java index 6be381d39ba..9823fff237d 100644 --- a/src/test/java/seedu/address/testutil/PersonBuilder.java +++ b/src/test/java/seedu/address/testutil/PersonBuilder.java @@ -3,6 +3,7 @@ import java.util.HashSet; import java.util.Set; +import seedu.address.model.course.Course; import seedu.address.model.person.Address; import seedu.address.model.person.Email; import seedu.address.model.person.Name; @@ -26,6 +27,7 @@ public class PersonBuilder { private Email email; private Address address; private Set tags; + private Set courses; /** * Creates a {@code PersonBuilder} with the default details. @@ -36,6 +38,7 @@ public PersonBuilder() { email = new Email(DEFAULT_EMAIL); address = new Address(DEFAULT_ADDRESS); tags = new HashSet<>(); + courses = new HashSet<>(); } /** @@ -47,6 +50,7 @@ public PersonBuilder(Person personToCopy) { email = personToCopy.getEmail(); address = personToCopy.getAddress(); tags = new HashSet<>(personToCopy.getTags()); + courses = new HashSet<>(personToCopy.getCourses()); } /** @@ -89,8 +93,16 @@ public PersonBuilder withEmail(String email) { return this; } + /** + * Parses the {@code courses} into a {@code Set} and set it to the {@code Person} that we are building. + */ + public PersonBuilder withCourses(String ... courses) { + this.courses = SampleDataUtil.getCourseSet(courses); + return this; + } + public Person build() { - return new Person(name, phone, email, address, tags); + return new Person(name, phone, email, address, tags, courses); } } From a3a72b714951682f3da7515098a9818421185b05 Mon Sep 17 00:00:00 2001 From: notnotmax <156508404+notnotmax@users.noreply.github.com> Date: Thu, 10 Oct 2024 17:03:20 +0800 Subject: [PATCH 8/8] Fix bugs and update testcases --- .../seedu/address/logic/commands/EditCommand.java | 2 +- .../seedu/address/logic/parser/AddCommandParser.java | 2 +- .../seedu/address/storage/JsonAdaptedCourse.java | 1 + .../logic/commands/EditPersonDescriptorTest.java | 3 ++- .../seedu/address/storage/JsonAdaptedPersonTest.java | 12 ++++++++---- 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/EditCommand.java b/src/main/java/seedu/address/logic/commands/EditCommand.java index 3ead740edc3..f200785fbb5 100644 --- a/src/main/java/seedu/address/logic/commands/EditCommand.java +++ b/src/main/java/seedu/address/logic/commands/EditCommand.java @@ -227,7 +227,7 @@ public void setCourses(Set courses) { * Returns {@code Optional#empty()} if {@code courses} is null. */ public Optional> getCourses() { - return (tags != null) ? Optional.of(Collections.unmodifiableSet(courses)) : Optional.empty(); + return (courses != null) ? Optional.of(Collections.unmodifiableSet(courses)) : Optional.empty(); } @Override diff --git a/src/main/java/seedu/address/logic/parser/AddCommandParser.java b/src/main/java/seedu/address/logic/parser/AddCommandParser.java index c5b4cbba4a1..72a1eeaed71 100644 --- a/src/main/java/seedu/address/logic/parser/AddCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/AddCommandParser.java @@ -2,11 +2,11 @@ import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS; +import static seedu.address.logic.parser.CliSyntax.PREFIX_COURSE; import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL; 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_TAG; -import static seedu.address.logic.parser.CliSyntax.PREFIX_COURSE; import java.util.Set; import java.util.stream.Stream; diff --git a/src/main/java/seedu/address/storage/JsonAdaptedCourse.java b/src/main/java/seedu/address/storage/JsonAdaptedCourse.java index 73ba62ff7c1..562fdddbc4d 100644 --- a/src/main/java/seedu/address/storage/JsonAdaptedCourse.java +++ b/src/main/java/seedu/address/storage/JsonAdaptedCourse.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; + import seedu.address.commons.exceptions.IllegalValueException; import seedu.address.model.course.Course; diff --git a/src/test/java/seedu/address/logic/commands/EditPersonDescriptorTest.java b/src/test/java/seedu/address/logic/commands/EditPersonDescriptorTest.java index b17c1f3d5c2..817887b72dc 100644 --- a/src/test/java/seedu/address/logic/commands/EditPersonDescriptorTest.java +++ b/src/test/java/seedu/address/logic/commands/EditPersonDescriptorTest.java @@ -65,7 +65,8 @@ public void toStringMethod() { + editPersonDescriptor.getPhone().orElse(null) + ", email=" + editPersonDescriptor.getEmail().orElse(null) + ", address=" + editPersonDescriptor.getAddress().orElse(null) + ", tags=" - + editPersonDescriptor.getTags().orElse(null) + "}"; + + editPersonDescriptor.getTags().orElse(null) + ", courses=" + + editPersonDescriptor.getCourses().orElse(null) + "}"; assertEquals(expected, editPersonDescriptor.toString()); } } diff --git a/src/test/java/seedu/address/storage/JsonAdaptedPersonTest.java b/src/test/java/seedu/address/storage/JsonAdaptedPersonTest.java index 908072e8d81..29234d4b3de 100644 --- a/src/test/java/seedu/address/storage/JsonAdaptedPersonTest.java +++ b/src/test/java/seedu/address/storage/JsonAdaptedPersonTest.java @@ -51,7 +51,8 @@ public void toModelType_invalidName_throwsIllegalValueException() { @Test public void toModelType_nullName_throwsIllegalValueException() { - JsonAdaptedPerson person = new JsonAdaptedPerson(null, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS, VALID_COURSES); + JsonAdaptedPerson person = new JsonAdaptedPerson(null, VALID_PHONE, VALID_EMAIL, + VALID_ADDRESS, VALID_TAGS, VALID_COURSES); String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Name.class.getSimpleName()); assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); } @@ -66,7 +67,8 @@ public void toModelType_invalidPhone_throwsIllegalValueException() { @Test public void toModelType_nullPhone_throwsIllegalValueException() { - JsonAdaptedPerson person = new JsonAdaptedPerson(VALID_NAME, null, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS, VALID_COURSES); + JsonAdaptedPerson person = new JsonAdaptedPerson(VALID_NAME, null, VALID_EMAIL, + VALID_ADDRESS, VALID_TAGS, VALID_COURSES); String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Phone.class.getSimpleName()); assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); } @@ -81,7 +83,8 @@ public void toModelType_invalidEmail_throwsIllegalValueException() { @Test public void toModelType_nullEmail_throwsIllegalValueException() { - JsonAdaptedPerson person = new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, null, VALID_ADDRESS, VALID_TAGS, VALID_COURSES); + JsonAdaptedPerson person = new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, null, + VALID_ADDRESS, VALID_TAGS, VALID_COURSES); String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Email.class.getSimpleName()); assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); } @@ -96,7 +99,8 @@ public void toModelType_invalidAddress_throwsIllegalValueException() { @Test public void toModelType_nullAddress_throwsIllegalValueException() { - JsonAdaptedPerson person = new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, null, VALID_TAGS, VALID_COURSES); + JsonAdaptedPerson person = new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, + null, VALID_TAGS, VALID_COURSES); String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Address.class.getSimpleName()); assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); }