diff --git a/docs/diagrams/LogicClassDiagram.puml b/docs/diagrams/LogicClassDiagram.puml index 732b2fbb2c2..cf357c70ce1 100644 --- a/docs/diagrams/LogicClassDiagram.puml +++ b/docs/diagrams/LogicClassDiagram.puml @@ -9,7 +9,7 @@ package Logic { Class AddressBookParser Class XYZCommand Class CommandResult -Class "{abstract}\nCommand" as Command +abstract Class "{abstract}\nCommand" as Command Interface Logic <> diff --git a/docs/diagrams/TaskClassDiagram.puml b/docs/diagrams/TaskClassDiagram.puml index 67f374ed013..a922c751cc0 100644 --- a/docs/diagrams/TaskClassDiagram.puml +++ b/docs/diagrams/TaskClassDiagram.puml @@ -5,7 +5,7 @@ skinparam arrowColor MODEL_COLOR skinparam classBackgroundColor MODEL_COLOR Package Task <> { -abstract Class Task +abstract Class "{abstract}\nTask" as Task Class TaskName Class Description Class TaskDate diff --git a/docs/images/LogicClassDiagram.png b/docs/images/LogicClassDiagram.png index fcff3fa4522..30167a63ee3 100644 Binary files a/docs/images/LogicClassDiagram.png and b/docs/images/LogicClassDiagram.png differ diff --git a/docs/images/TaskClassDiagram.png b/docs/images/TaskClassDiagram.png index 6a865413999..4c893a74f27 100644 Binary files a/docs/images/TaskClassDiagram.png and b/docs/images/TaskClassDiagram.png differ diff --git a/docs/team/itsraveen.md b/docs/team/itsraveen.md index a7b217f97cd..010f1674eab 100644 --- a/docs/team/itsraveen.md +++ b/docs/team/itsraveen.md @@ -5,6 +5,8 @@ title: Raveen's Project Portfolio Page ### Project: tApp +tApp is a desktop app for managing tutorial groups and personal tasks, optimized for use via a Command Line Interface (CLI). It has a GUI created with JavaFX. It is written in Java, and has about 15 kLoC. + Given below are my contributions to the project. * **Code contributed:** [RepoSense link](https://nus-cs2103-ay2122s1.github.io/tp-dashboard/?search=raveen) diff --git a/src/main/java/seedu/address/logic/commands/MarkTaskDoneCommand.java b/src/main/java/seedu/address/logic/commands/MarkTaskDoneCommand.java index 51acb51ab85..20c29f13d84 100644 --- a/src/main/java/seedu/address/logic/commands/MarkTaskDoneCommand.java +++ b/src/main/java/seedu/address/logic/commands/MarkTaskDoneCommand.java @@ -39,6 +39,12 @@ public CommandResult execute(Model model) throws CommandException { List savedStateList = new ArrayList<>(model.getFilteredTaskList()); StringBuilder result = new StringBuilder(); + for (Index targetIndex : targetIndexList) { + if (targetIndex.getZeroBased() >= savedStateList.size()) { + throw new CommandException(Messages.MESSAGE_INVALID_TASK_DISPLAYED_INDEX); + } + } + for (Index targetIndex : targetIndexList) { if (targetIndex.getZeroBased() >= savedStateList.size()) { throw new CommandException(Messages.MESSAGE_INVALID_TASK_DISPLAYED_INDEX); diff --git a/src/main/java/seedu/address/model/AddressBook.java b/src/main/java/seedu/address/model/AddressBook.java index 9fabb96976a..51f49b3cc0a 100644 --- a/src/main/java/seedu/address/model/AddressBook.java +++ b/src/main/java/seedu/address/model/AddressBook.java @@ -246,7 +246,6 @@ public void addGroup(Group g) { */ public void setGroup(Group target, Group editedGroup) { requireNonNull(editedGroup); - groups.setGroup(target, editedGroup); } diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/seedu/address/model/ModelManager.java index f3ef685cbcf..4765ebff5fd 100644 --- a/src/main/java/seedu/address/model/ModelManager.java +++ b/src/main/java/seedu/address/model/ModelManager.java @@ -171,7 +171,7 @@ public void markStudentAttendance(Student target, int week) { requireAllNonNull(target, week); Student newStudent = target.clone(); newStudent.toggleAttendance(week); - updateGroup(target, newStudent); + setStudent(target, newStudent); } @Override @@ -185,7 +185,7 @@ public void markStudentParticipation(Student target, int week) { requireAllNonNull(target, week); Student newStudent = target.clone(); newStudent.toggleParticipation(week); - updateGroup(target, newStudent); + setStudent(target, newStudent); } @Override @@ -198,8 +198,10 @@ public String getStudentParticipation(Student target, int week) { public void addMember(Student student, Group group) { requireAllNonNull(student, group); Student updatedStudent = new Student(student, group.getName()); - group.addMember(updatedStudent); + Group newGroup = group.clone(); + newGroup.addMember(updatedStudent); addressBook.setStudent(student, updatedStudent); + addressBook.setGroup(group, newGroup); } @Override @@ -257,6 +259,7 @@ public void deleteGroup(Group target) { List students = target.getMembersList(); addressBook.clearGroupFromStudents(students); addressBook.deleteGroup(target); + displayType = GROUPS; } @Override diff --git a/src/main/java/seedu/address/model/group/Group.java b/src/main/java/seedu/address/model/group/Group.java index 0df3c61ccfb..8378463fd7d 100644 --- a/src/main/java/seedu/address/model/group/Group.java +++ b/src/main/java/seedu/address/model/group/Group.java @@ -35,22 +35,9 @@ public class Group { public Group(GroupName name, Members members, LinkYear year, RepoName repoName, Set tags) { requireNonNull(name); this.name = name; - if (members != null) { - this.members = members; - } else { - this.members = new Members(); - } - if (year != null) { - this.year = year; - } else { - this.year = new LinkYear(); - } - if (repoName != null) { - this.repoName = repoName; - } else { - this.repoName = new RepoName(); - } - + this.members = Objects.requireNonNullElseGet(members, Members::new); + this.year = Objects.requireNonNullElseGet(year, LinkYear::new); + this.repoName = Objects.requireNonNullElseGet(repoName, RepoName::new); this.tags.addAll(tags); } @@ -58,12 +45,7 @@ public Group(GroupName name, Members members, LinkYear year, RepoName repoName, * Constructor for a new Group object given only name and tags */ public Group(GroupName name, Set tags) { - requireAllNonNull(name); - this.name = name; - this.members = new Members(); - this.tags.addAll(tags); - this.year = new LinkYear(); - this.repoName = new RepoName(); + this(name, new Members(), new LinkYear(), new RepoName(), tags); } public GroupName getName() { @@ -113,7 +95,7 @@ public void removeAllMembers() { } /** - * Returns the formatted Github link + * Returns the formatted GitHub link */ public String getGroupGithubLink() { if (!year.isNull() && !repoName.isNull()) { @@ -123,20 +105,6 @@ public String getGroupGithubLink() { } } - /** - * Returns the formatted Github link with given inputs - * @param year A valid year to parse - * @param repoName A valid repoName to parse - */ - public String getGroupGithubLink(LinkYear year, RepoName repoName) { - if (!year.isNull() && !repoName.isNull()) { - return String.format(new GroupGithub(year, repoName).toString(), getName()); - } else { - return "-"; - } - } - - /** * Returns an immutable tag set, which throws {@code UnsupportedOperationException} * if modification is attempted. @@ -192,7 +160,7 @@ public String toString() { .append("; Members: ") .append(getMembers()) .append("; Github: ") - .append(getGroupGithubLink());; + .append(getGroupGithubLink()); Set tags = getTags(); if (!tags.isEmpty()) { @@ -203,6 +171,15 @@ public String toString() { return builder.toString(); } + /** + * Makes a shallow copy of a group. + * + * @return a cloned Group with the exact same data fields as the original. + */ + public Group clone() { + return new Group(name, new Members(getMembersList()), year, repoName, new HashSet<>(tags)); + } + /** * Represents a Group's name in tApp. * Guarantees: immutable; diff --git a/src/main/java/seedu/address/model/group/GroupName.java b/src/main/java/seedu/address/model/group/GroupName.java index bd1d214df0c..5b4b09dc99e 100644 --- a/src/main/java/seedu/address/model/group/GroupName.java +++ b/src/main/java/seedu/address/model/group/GroupName.java @@ -37,7 +37,7 @@ public GroupName() { } public boolean isNull () { - return name == null ? true : false; + return name == null; } /** diff --git a/src/main/java/seedu/address/model/group/Members.java b/src/main/java/seedu/address/model/group/Members.java index 16828fc4ad9..640283934f4 100644 --- a/src/main/java/seedu/address/model/group/Members.java +++ b/src/main/java/seedu/address/model/group/Members.java @@ -1,25 +1,24 @@ package seedu.address.model.group; -import java.util.ArrayList; +import java.util.List; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; import seedu.address.model.student.Student; public class Members { - public final ArrayList studentList; + public final ObservableList studentList = FXCollections.observableArrayList(); /** * Constructs a {@code Members}. */ - public Members() { - studentList = new ArrayList<>(); - } + public Members() { } /** * Constructs a existing {@code Members}. */ - public Members(ArrayList studentList) { - this.studentList = new ArrayList<>(); + public Members(List studentList) { this.studentList.addAll(studentList); } diff --git a/src/main/java/seedu/address/model/group/UniqueGroupList.java b/src/main/java/seedu/address/model/group/UniqueGroupList.java index 218b168fe09..1a5c5313962 100644 --- a/src/main/java/seedu/address/model/group/UniqueGroupList.java +++ b/src/main/java/seedu/address/model/group/UniqueGroupList.java @@ -122,7 +122,7 @@ public void removeStudentFromGroup(Student student, Group group) { throw new GroupNotFoundException(); } - Group updatedGroup = group; + Group updatedGroup = group.clone(); updatedGroup.removeMember(student); if (!group.isSameGroup(updatedGroup) && contains(updatedGroup)) { diff --git a/src/main/java/seedu/address/model/student/Student.java b/src/main/java/seedu/address/model/student/Student.java index e36e3958373..9f00a3d62e3 100644 --- a/src/main/java/seedu/address/model/student/Student.java +++ b/src/main/java/seedu/address/model/student/Student.java @@ -36,24 +36,8 @@ public class Student { */ public Student(Name name, Email email, StudentNumber studentNumber, UserName userName, RepoName repoName, Set tags) { - requireAllNonNull(name, email, studentNumber, tags); - this.name = name; - this.email = email; - this.studentNumber = studentNumber; - this.tags.addAll(tags); - this.attendance = new Attendance(); - this.participation = new Participation(); - if (userName != null) { - this.userName = userName; - } else { - this.userName = new UserName(); - } - if (repoName != null) { - this.repoName = repoName; - } else { - this.repoName = new RepoName(); - } - this.groupName = new GroupName(); + this(name, email, studentNumber, userName, repoName, tags, + new Attendance(), new Participation(), new GroupName()); } /** @@ -62,23 +46,15 @@ public Student(Name name, Email email, StudentNumber studentNumber, UserName use public Student(Name name, Email email, StudentNumber studentNumber, UserName userName, RepoName repoName, Set tags, Attendance attendance, Participation participation, GroupName groupName) { - requireAllNonNull(name, email, studentNumber, tags, attendance); + requireAllNonNull(name, email, studentNumber, tags, attendance, participation); this.name = name; this.email = email; this.studentNumber = studentNumber; this.tags.addAll(tags); this.attendance = attendance; this.participation = participation; - if (userName != null) { - this.userName = userName; - } else { - this.userName = new UserName(); - } - if (repoName != null) { - this.repoName = repoName; - } else { - this.repoName = new RepoName(); - } + this.userName = Objects.requireNonNullElseGet(userName, UserName::new); + this.repoName = Objects.requireNonNullElseGet(repoName, RepoName::new); this.groupName = groupName; } @@ -87,16 +63,8 @@ public Student(Name name, Email email, StudentNumber studentNumber, UserName use */ public Student(Student student, GroupName groupName) { - requireAllNonNull(student, groupName); - this.name = student.getName(); - this.email = student.getEmail(); - this.studentNumber = student.getStudentNumber(); - this.userName = student.getUserName(); - this.repoName = student.getRepoName(); - this.tags.addAll(student.getTags()); - this.attendance = student.getAttendance(); - this.participation = student.getParticipation(); - this.groupName = groupName; + this(student.name, student.email, student.studentNumber, student.userName, student.repoName, student.tags, + student.getAttendance(), student.getParticipation(), groupName); } public Name getName() { @@ -187,9 +155,7 @@ public boolean hasGroupName() { * @return a cloned Student with the exact same data fields as the original. */ public Student clone() { - Student clone = new Student(name, email, studentNumber, userName, repoName, tags, attendance, - participation, groupName); - return clone; + return new Student(name, email, studentNumber, userName, repoName, tags, attendance, participation, groupName); } /** @@ -243,7 +209,7 @@ public String toString() { } /** - * Represents a Student's github ip link in tApp. + * Represents a Student's GitHub ip link in tApp. * Guarantees: immutable; */ public static class GithubLink { diff --git a/src/main/java/seedu/address/model/tag/Tag.java b/src/main/java/seedu/address/model/tag/Tag.java index f5805dedfe7..2a741b6f1a2 100644 --- a/src/main/java/seedu/address/model/tag/Tag.java +++ b/src/main/java/seedu/address/model/tag/Tag.java @@ -9,8 +9,9 @@ */ public class Tag { - public static final String MESSAGE_CONSTRAINTS = "Tags names should be alphanumeric with no spaces."; - public static final String VALIDATION_REGEX = "\\p{Alnum}+"; + public static final String MESSAGE_CONSTRAINTS = + "Tags names should be alphanumeric, contain no spaces, and must be between 1 to 20 characters long."; + public static final String VALIDATION_REGEX = "^[a-zA-Z0-9]{1,20}$"; public final String tagName; diff --git a/src/main/java/seedu/address/model/task/Task.java b/src/main/java/seedu/address/model/task/Task.java index 99e05b38c4a..336c95d4d4b 100644 --- a/src/main/java/seedu/address/model/task/Task.java +++ b/src/main/java/seedu/address/model/task/Task.java @@ -1,5 +1,7 @@ package seedu.address.model.task; +import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; + import java.time.LocalDate; import java.util.Collections; import java.util.HashSet; @@ -34,6 +36,7 @@ public enum Priority { * @param priority A valid priority for the Task. */ public Task(TaskName name, Set tags, boolean isDone, Description description, Priority priority) { + requireAllNonNull(name, priority); this.name = name; this.tags.addAll(tags); this.isDone = isDone; @@ -50,11 +53,7 @@ public Task(TaskName name, Set tags, boolean isDone, Description descriptio * @param priority A valid Priority. */ public Task(TaskName name, Set tags, Description description, Priority priority) { - this.name = name; - this.tags.addAll(tags); - this.isDone = false; - this.description = description; - this.priority = priority; + this(name, tags, false, description, priority); } public TaskName getName() { diff --git a/src/main/java/seedu/address/ui/GroupCard.java b/src/main/java/seedu/address/ui/GroupCard.java index 714a20314d4..a4afcf1075e 100644 --- a/src/main/java/seedu/address/ui/GroupCard.java +++ b/src/main/java/seedu/address/ui/GroupCard.java @@ -2,7 +2,6 @@ import java.util.Comparator; -import javafx.collections.FXCollections; import javafx.fxml.FXML; import javafx.scene.control.Label; import javafx.scene.layout.FlowPane; @@ -12,7 +11,7 @@ import seedu.address.model.group.Group; /** - * An UI component that displays information of a {@code Group}. + * A UI component that displays information of a {@code Group}. */ public class GroupCard extends UiPart { @@ -51,8 +50,7 @@ public GroupCard(Group group, int displayedIndex) { id.setText(displayedIndex + ". "); name.setText(group.getName().name); link.setText("Github: " + group.getGroupGithubLink()); - memberListPanel = new MemberListPanel( - FXCollections.observableArrayList(group.getMembers().studentList)); + memberListPanel = new MemberListPanel(group.getMembers().studentList); memberListPanelPlaceholder.getChildren().add(memberListPanel.getRoot()); diff --git a/src/main/java/seedu/address/ui/GroupListPanel.java b/src/main/java/seedu/address/ui/GroupListPanel.java index 95fab5c9835..cb5e0da3490 100644 --- a/src/main/java/seedu/address/ui/GroupListPanel.java +++ b/src/main/java/seedu/address/ui/GroupListPanel.java @@ -29,10 +29,17 @@ public GroupListPanel(ObservableList groupList) { groupListView.setCellFactory(listView -> new GroupListViewCell()); } + /** + * Returns the group list region. + */ + public Region getRegion() { + return groupListView; + } + /** * Custom {@code ListCell} that displays the graphics of a {@code Group} using a {@code GroupCard}. */ - class GroupListViewCell extends ListCell { + static class GroupListViewCell extends ListCell { @Override protected void updateItem(Group group, boolean empty) { super.updateItem(group, empty); diff --git a/src/main/java/seedu/address/ui/MainWindow.java b/src/main/java/seedu/address/ui/MainWindow.java index e16304d49d4..3f72e368420 100644 --- a/src/main/java/seedu/address/ui/MainWindow.java +++ b/src/main/java/seedu/address/ui/MainWindow.java @@ -1,8 +1,6 @@ package seedu.address.ui; -import static seedu.address.model.Model.DisplayType.GROUPS; import static seedu.address.model.Model.DisplayType.STUDENTS; -import static seedu.address.model.Model.DisplayType.TASKS; import java.util.logging.Logger; @@ -23,6 +21,7 @@ import seedu.address.logic.commands.CommandResult; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.Model; /** * The Main Window. Provides the basic application layout containing @@ -41,9 +40,10 @@ public class MainWindow extends UiPart { private final Logic logic; // Independent Ui parts residing in this Ui container - private StudentListPanel studentListPanel; - private TaskListPanel taskListPanel; - private GroupListPanel groupListPanel; + private final StudentListPanel studentListPanel; + private final TaskListPanel taskListPanel; + private final GroupListPanel groupListPanel; + private Model.DisplayType currentDisplay; private final HelpWindow helpWindow; @FXML @@ -53,7 +53,7 @@ public class MainWindow extends UiPart { private MenuItem helpMenuItem; @FXML - private StackPane studentListPanelPlaceholder; + private StackPane listPanelPlaceholder; @FXML private ScrollPane terminalScrollPane; @@ -62,7 +62,7 @@ public class MainWindow extends UiPart { private VBox terminalContainer; @FXML - private StackPane statusbarPlaceholder; + private StackPane statusBarPlaceholder; @FXML private Label listName; @@ -83,6 +83,12 @@ public MainWindow(Stage primaryStage, Logic logic) { setAccelerators(); helpWindow = new HelpWindow(); + studentListPanel = new StudentListPanel(logic.getFilteredStudentList()); + groupListPanel = new GroupListPanel(logic.getFilteredGroupList()); + taskListPanel = new TaskListPanel(logic.getFilteredTaskList()); + listPanelPlaceholder.getChildren().add(groupListPanel.getRegion()); + listPanelPlaceholder.getChildren().add(taskListPanel.getRegion()); + listPanelPlaceholder.getChildren().add(studentListPanel.getRegion()); } public Stage getPrimaryStage() { @@ -127,31 +133,43 @@ private void setAccelerator(MenuItem menuItem, KeyCombination keyCombination) { * Fills up all the placeholders of this window. */ void fillInnerParts() { - studentListPanel = new StudentListPanel(logic.getFilteredStudentList()); - studentListPanelPlaceholder.getChildren().add(studentListPanel.getRoot()); + currentDisplay = STUDENTS; listName.setText(STUDENTS_LIST_NAME); StatusBarFooter statusBarFooter = new StatusBarFooter(logic.getAddressBookFilePath()); - statusbarPlaceholder.getChildren().add(statusBarFooter.getRoot()); + statusBarPlaceholder.getChildren().add(statusBarFooter.getRoot()); CommandBox commandBox = new CommandBox(this::executeCommand); commandBoxPlaceholder.getChildren().add(commandBox.getRoot()); } + /** + * Update the data lists. + */ void updateInnerParts() { - if (logic.getDisplayType().equals(STUDENTS)) { - studentListPanel = new StudentListPanel(logic.getFilteredStudentList()); - studentListPanelPlaceholder.getChildren().add(studentListPanel.getRoot()); - listName.setText(STUDENTS_LIST_NAME); - } else if (logic.getDisplayType().equals(TASKS)) { - taskListPanel = new TaskListPanel(logic.getFilteredTaskList()); - studentListPanelPlaceholder.getChildren().add(taskListPanel.getRoot()); - listName.setText(TASKS_LIST_NAME); - } else if (logic.getDisplayType().equals(GROUPS)) { - groupListPanel = new GroupListPanel(logic.getFilteredGroupList()); - studentListPanelPlaceholder.getChildren().add(groupListPanel.getRoot()); - listName.setText(GROUPS_LIST_NAME); + Model.DisplayType type = logic.getDisplayType(); + if (currentDisplay != type) { + switch (type) { + case STUDENTS: + listPanelPlaceholder.getChildren().remove(studentListPanel.getRegion()); + listPanelPlaceholder.getChildren().add(studentListPanel.getRegion()); + listName.setText(STUDENTS_LIST_NAME); + break; + case GROUPS: + listPanelPlaceholder.getChildren().remove(groupListPanel.getRegion()); + listPanelPlaceholder.getChildren().add(groupListPanel.getRegion()); + listName.setText(GROUPS_LIST_NAME); + break; + case TASKS: + listPanelPlaceholder.getChildren().remove(taskListPanel.getRegion()); + listPanelPlaceholder.getChildren().add(taskListPanel.getRegion()); + listName.setText(TASKS_LIST_NAME); + break; + default: + break; + } + currentDisplay = type; } } @@ -212,13 +230,12 @@ private CommandResult executeCommand(String commandText) throws CommandException if (commandResult.isShowHelp()) { handleHelp(); - } - - if (commandResult.isExit()) { + } else if (commandResult.isExit()) { handleExit(); + } else { + updateInnerParts(); } - updateInnerParts(); terminalContainer.getChildren().add( new TerminalBox(commandText, commandResult.getFeedbackToUser())); return commandResult; diff --git a/src/main/java/seedu/address/ui/StudentListPanel.java b/src/main/java/seedu/address/ui/StudentListPanel.java index f1e6a281bb7..8e5387bdcc2 100644 --- a/src/main/java/seedu/address/ui/StudentListPanel.java +++ b/src/main/java/seedu/address/ui/StudentListPanel.java @@ -29,6 +29,13 @@ public StudentListPanel(ObservableList studentList) { studentListView.setCellFactory(listView -> new StudentListViewCell()); } + /** + * Returns the student list region. + */ + public Region getRegion() { + return studentListView; + } + /** * Custom {@code ListCell} that displays the graphics of a {@code Student} using a {@code StudentCard}. */ diff --git a/src/main/java/seedu/address/ui/TaskListPanel.java b/src/main/java/seedu/address/ui/TaskListPanel.java index 62e95047843..5c2e72aa08b 100644 --- a/src/main/java/seedu/address/ui/TaskListPanel.java +++ b/src/main/java/seedu/address/ui/TaskListPanel.java @@ -32,10 +32,17 @@ public TaskListPanel(ObservableList taskList) { taskListView.setCellFactory(listView -> new TaskListViewCell()); } + /** + * Returns the task list region. + */ + public Region getRegion() { + return taskListView; + } + /** * Custom {@code ListCell} that displays the graphics of a {@code Student} using a {@code StudentCard}. */ - class TaskListViewCell extends ListCell { + static class TaskListViewCell extends ListCell { @Override protected void updateItem(Task task, boolean empty) { super.updateItem(task, empty); diff --git a/src/main/resources/view/MainWindow.fxml b/src/main/resources/view/MainWindow.fxml index ecca6f7ffd5..7a7400c2d93 100644 --- a/src/main/resources/view/MainWindow.fxml +++ b/src/main/resources/view/MainWindow.fxml @@ -51,7 +51,7 @@ - + @@ -70,7 +70,7 @@ - + diff --git a/src/test/java/seedu/address/storage/JsonAdaptedGroupTest.java b/src/test/java/seedu/address/storage/JsonAdaptedGroupTest.java index aa1dfc9a89e..44193e00bb0 100644 --- a/src/test/java/seedu/address/storage/JsonAdaptedGroupTest.java +++ b/src/test/java/seedu/address/storage/JsonAdaptedGroupTest.java @@ -32,7 +32,7 @@ public class JsonAdaptedGroupTest { private static final List VALID_TAGS = VALID_TAGS_SET.stream() .map(JsonAdaptedTag::new) .collect(Collectors.toList()); - private static final ArrayList VALID_MEMBER_ARRAY = GROUP1.getMembers().studentList; + private static final ArrayList VALID_MEMBER_ARRAY = new ArrayList<>(GROUP1.getMembers().studentList); private static final ArrayList VALID_MEMBERS = new ArrayList<>(VALID_MEMBER_ARRAY.stream() .map(JsonAdaptedStudent::new) .collect(Collectors.toList()));