Skip to content

Commit

Permalink
UniqueTagList & UniqueActivityList to ignore order of elements
Browse files Browse the repository at this point in the history
Removed erroneous equals method for UniqueTagList
Also fixed an edit test in the process
  • Loading branch information
alexfjw committed Oct 28, 2016
1 parent 03cdea8 commit 393d32b
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 57 deletions.
25 changes: 17 additions & 8 deletions src/main/java/seedu/taskman/model/TaskMan.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import seedu.taskman.model.event.Activity;
import seedu.taskman.model.event.Event;
import seedu.taskman.model.event.MutableTagsEvent;
import seedu.taskman.model.event.Task;
import seedu.taskman.model.event.UniqueActivityList;
import seedu.taskman.model.tag.Tag;
import seedu.taskman.model.tag.UniqueTagList;
Expand Down Expand Up @@ -123,14 +124,22 @@ private void syncTagsWithMasterList(MutableTagsEvent event) {
event.setTags(new UniqueTagList(commonTagReferences));
}

public boolean removeActivity(Task key) throws UniqueActivityList.ActivityNotFoundException {
if (activities.remove(new Activity(key))) {
return true;
} else {
throw new UniqueActivityList.ActivityNotFoundException();
}
}

public boolean removeActivity(Activity key) throws UniqueActivityList.ActivityNotFoundException {
if (activities.remove(key)) {
return true;
} else {
throw new UniqueActivityList.ActivityNotFoundException();
}
}

//// tag-level operations

public void addTag(Tag t) throws UniqueTagList.DuplicateTagException {
Expand Down Expand Up @@ -164,18 +173,18 @@ public UniqueTagList getUniqueTagList() {
return this.tags;
}


@Override
public boolean equals(Object other) {
return other == this // short circuit if same object
|| (other instanceof TaskMan // instanceof handles nulls
&& this.activities.equals(((TaskMan) other).activities)
&& this.tags.equals(((TaskMan) other).tags));
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
TaskMan taskMan = (TaskMan) o;

return Objects.equals(activities, taskMan.activities) &&
Objects.equals(tags, taskMan.tags);
}

@Override
public int hashCode() {
// use this method for custom fields hashing instead of implementing your own
return Objects.hash(activities, tags);
}
}
21 changes: 14 additions & 7 deletions src/main/java/seedu/taskman/model/event/UniqueActivityList.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

/**
* A list of activities that enforces uniqueness between its elements and does not allow nulls.
* Also ignores order of elements when checking for equality
* <p>
* Supports a minimal set of list operations.
*
Expand Down Expand Up @@ -41,7 +42,6 @@ public static class ActivityNotFoundException extends Exception {
public UniqueActivityList() {
}

//TODO Do we need this? Or is simply checking for equivalence of title sufficient?
/**
* Returns true if the list contains an equivalent activity as the given argument.
* Here, equivalence refers to equivalence of all fields in activity.
Expand Down Expand Up @@ -101,15 +101,22 @@ public Iterator<Activity> iterator() {
}

@Override
public boolean equals(Object other) {
return other == this // short circuit if same object
|| (other instanceof UniqueActivityList // instanceof handles nulls
&& this.internalList.equals(
((UniqueActivityList) other).internalList));
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UniqueActivityList that = (UniqueActivityList) o;

HashSet<Activity> setRepresentation = new HashSet<>();
setRepresentation.addAll(internalList);
HashSet<Activity> otherSetRepresentation = new HashSet<>();
otherSetRepresentation.addAll(that.internalList);
return setRepresentation.equals(otherSetRepresentation);
}

@Override
public int hashCode() {
return internalList.hashCode();
HashSet<Activity> setRepresentation = new HashSet<>();
setRepresentation.addAll(internalList);
return Objects.hash(setRepresentation);
}
}
22 changes: 15 additions & 7 deletions src/main/java/seedu/taskman/model/tag/UniqueTagList.java
Original file line number Diff line number Diff line change
Expand Up @@ -129,17 +129,25 @@ public ObservableList<Tag> getInternalList() {
return internalList;
}

// order of the tags does not matter
@Override
public boolean equals(Object other) {
return other == this // short circuit if same object
|| (other instanceof UniqueTagList // instanceof handles nulls
&& this.internalList.containsAll(
((UniqueTagList) other).internalList));
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

UniqueTagList tags = (UniqueTagList) o;

HashSet<Tag> setRepresentation = new HashSet<>();
setRepresentation.addAll(internalList);
HashSet<Tag> otherSetRepresentation = new HashSet<>();
otherSetRepresentation.addAll(tags.internalList);
return setRepresentation.equals(otherSetRepresentation);
}

@Override
public int hashCode() {
return internalList.hashCode();
HashSet<Tag> setRepresentation = new HashSet<>();
setRepresentation.addAll(internalList);

return setRepresentation.hashCode();
}
}
75 changes: 47 additions & 28 deletions src/test/java/seedu/taskman/logic/logicmanager/EditTests.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
package seedu.taskman.logic.logicmanager;

import org.junit.Test;
import seedu.taskman.commons.exceptions.IllegalValueException;
import seedu.taskman.logic.commands.EditCommand;
import seedu.taskman.model.TaskMan;
import seedu.taskman.model.event.Activity;
import seedu.taskman.model.event.Deadline;
import seedu.taskman.model.event.Task;
import seedu.taskman.model.tag.Tag;
import seedu.taskman.model.tag.UniqueTagList;

import java.time.Instant;
import java.util.List;
import java.util.Optional;

public class EditTests extends LogicManagerTestBase {

Expand All @@ -34,61 +37,77 @@ public void execute_edit_invalidTaskData() throws Exception {
assertCommandNoStateChange(String.format(EditCommand.COMMAND_WORD, " []\\[;]"));
}

// @Test
@Test
public void execute_edit_successful() throws Exception {
// set up expectations
LogicManagerTestBase.TestDataHelper helper = new LogicManagerTestBase.TestDataHelper();
int targetIndex = 1, numTasks = 3;
List<Task> threeTasks = helper.generateTaskList(numTasks);
TaskMan expectedTaskMan = helper.generateTaskMan(threeTasks);
Task task = threeTasks.get(targetIndex);

// edit deadline
Deadline deadline;
if (task.getDeadline().isPresent()) {
deadline = new Deadline(task.getDeadline().get().epochSecond + helper.SECONDS_DAY);
} else {
deadline = new Deadline(Instant.now().getEpochSecond() + helper.SECONDS_DAY);
}
task.setDeadline(deadline);

// edit tags
UniqueTagList tags = task.getTags();
int taskToEdit = 1;
int numTasks = 3;
List<Task> originalTasks = helper.generateFullTaskList(numTasks);
Task originalTask = originalTasks.get(taskToEdit);
helper.addToModel(model, originalTasks);

// users start from 1 rather than 0
int filteredIndex = model.getSortedDeadlineList().indexOf(new Activity(originalTask)) + 1;

// edit deadline & tags for one task
Deadline newDeadline = generateDifferentDeadline(new Activity(originalTask));
Task editedTask = originalTask;
editedTask.setDeadline(newDeadline);

UniqueTagList tags = editedTask.getTags();
tags.add(new Tag(helper.STRING_RANDOM));
task.setTags(tags);
editedTask.setTags(tags);

// expectedTaskMan.removeActivity(threeTasks.get(targetIndex));
expectedTaskMan.addActivity(task);
TaskMan expectedTaskMan = helper.generateTaskMan(originalTasks);
expectedTaskMan.removeActivity(new Activity(originalTasks.get(taskToEdit)));
expectedTaskMan.addActivity(editedTask);

// set up actual before edit
helper.addToModel(model, threeTasks);
String inputCommand = helper.generateEditCommand(
model,
Activity.PanelType.DEADLINE,
filteredIndex,
null, // no change in title
newDeadline,
null, // no change in edit
null, // no change in frequency
tags
);

assertCommandStateChange(inputCommand, expectedTaskMan);
}

// java.lang.AssertionError: Activity is neither an event nor a task.
assertCommandStateChange(helper.generateEditCommand(model, targetIndex, task.getTitle(),
deadline, task.getSchedule().orElse(null),
task.getFrequency().orElse(null), tags),
expectedTaskMan,
expectedTaskMan.getActivityList());
private Deadline generateDifferentDeadline(Activity activity) throws IllegalValueException {
int offset = 60 * 60;
long rawDeadline = Instant.now().getEpochSecond() + offset;
Optional<Deadline> currentDeadline = activity.getDeadline();
if (currentDeadline.isPresent() && currentDeadline.get().epochSecond == rawDeadline) {
rawDeadline += offset;
}
return new Deadline(rawDeadline);
}

// @Test
public void execute_editToDuplicate_notAllowed() throws Exception {
// set up expectations
LogicManagerTestBase.TestDataHelper helper = new LogicManagerTestBase.TestDataHelper();
int targetIndex = 1, numTasks = 3;
List<Task> threeTasks = helper.generateTaskList(numTasks);
List<Task> threeTasks = helper.generateFullTaskList(numTasks);
TaskMan expectedTaskMan = helper.generateTaskMan(threeTasks);
Task taskA = threeTasks.get(targetIndex);
Task taskB = threeTasks.get(targetIndex + 1);

// set up actual before edit
helper.addToModel(model, threeTasks);

/*
// java.lang.AssertionError: Activity is neither an event nor a task.
assertCommandStateChange(helper.generateEditCommand(model, targetIndex, taskB.getTitle(),
taskA.getDeadline().orElse(null), taskA.getSchedule().orElse(null),
taskA.getFrequency().orElse(null), taskA.getTags()),
expectedTaskMan,
expectedTaskMan.getActivityList());
*/
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ protected void assertIndexNotFoundBehaviorForCommand(String commandWord) throws
*/
static class TestDataHelper {

public final String STRING_RANDOM = "random";

List<Activity> tasksToActivity(List<Task> tasks) {
ArrayList<Activity> activities = new ArrayList<>();
for(Task task : tasks) {
Expand Down Expand Up @@ -225,24 +227,30 @@ String generateDoCommand(Task task) {
return command.toString();
}

String generateEditCommand(Activity.PanelType panel, Model model, int targetIndex, Title title, Deadline deadline, Schedule schedule,
String generateEditCommand(Model model, Activity.PanelType panel, int targetIndex, Title title, Deadline deadline, Schedule schedule,
Frequency frequency, UniqueTagList tags) {
Activity task = model.getActivityListForPanelType(panel).get(targetIndex);
StringBuilder command = new StringBuilder();

command.append(EditCommand.COMMAND_WORD);
command.append(String.format(" %d ", targetIndex));
command.append(title.toString());
command.append(" " + panel.toString());
command.append(targetIndex);

Instant instant = Instant.ofEpochSecond(deadline.epochSecond);
command.append(" d/").
append(instant.toString());
if (title != null) {
command.append(" " + title.toString());
}

if (deadline != null) {
Instant instant = Instant.ofEpochSecond(deadline.epochSecond);
command.append(" d/").
append(instant.toString());
}

if (task.getFrequency().isPresent()) {
throw new AssertionError("Frequency is not supported yet");
}

if (task.getSchedule().isPresent()) {
if (schedule != null) {
String start = DateTimeParser.epochSecondToShortDateTime(schedule.startEpochSecond);
String end = DateTimeParser.epochSecondToShortDateTime(schedule.endEpochSecond);
command.append(" s/").
Expand Down

0 comments on commit 393d32b

Please sign in to comment.