Skip to content

Commit

Permalink
Merge pull request #50 from CS2103AUG2016-F10-C3/C3/refactoring/date-…
Browse files Browse the repository at this point in the history
…parser

Refactor date parser and add support for edit in main Parser
  • Loading branch information
tessav committed Nov 1, 2016
2 parents c51e4d5 + 18c136e commit 080ef0c
Show file tree
Hide file tree
Showing 12 changed files with 829 additions and 94 deletions.
206 changes: 187 additions & 19 deletions libs/A0146130W.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
# A0146130W
###### /src/main/java/seedu/gtd/commons/exceptions/DataConversionException.java
``` java
public DataConversionException(String cause) {
super(cause);
}
}
```
###### /src/main/java/seedu/gtd/logic/commands/EditCommand.java
``` java
/**
Expand Down Expand Up @@ -46,8 +53,8 @@
return new CommandResult(ive.getMessage());
}

assert model != null;
try {
assert model != null;
try {
model.editTask(targetIndex, taskToUpdate);
} catch (TaskNotFoundException e) {
assert false : "The target task cannot be missing";
Expand Down Expand Up @@ -95,40 +102,64 @@
```
###### /src/main/java/seedu/gtd/logic/parser/DateNaturalLanguageProcessor.java
``` java

/**
* Uses natty API: http://natty.joestelmach.com to parse natural language into dates or string
*/
public class DateNaturalLanguageProcessor implements NaturalLanguageProcessor {

private static final com.joestelmach.natty.Parser parser = new com.joestelmach.natty.Parser();
private static final String DATE_FORMAT = "dd/MM/yyyy HH:mm:ss";

@Override
public String formatString(String naturalLanguageDate) {
List<DateGroup> dateGroups = parser.parse(naturalLanguageDate);
return refineDateGroupList(dateGroups);
Date parsedDate;
try {
parsedDate = refineDateGroupList(dateGroups);
} catch (NaturalLanguageException e) {
return "";
}
return formatDateToString(parsedDate);
}

/*Does not tolerate alternative dates*/
private String refineDateGroupList(List<DateGroup> groups) {
if(groups.size() == 1) {
return formatDateToString(groups.get(0).getDates().get(0));
}
else return "";
/**
* Chooses the first date from a list of dates that Natty has parsed from the natural language string
* @throws NaturalLanguageException
* */
private Date refineDateGroupList(List<DateGroup> groups) throws NaturalLanguageException {
if(groups.size() == 0) throw new NaturalLanguageException();
return groups.get(0).getDates().get(0);
}

private String formatDateToString(Date date) {
Format formatter = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
Format formatter = new SimpleDateFormat(DATE_FORMAT);
return formatter.format(date);
}
}
```
###### /src/main/java/seedu/gtd/logic/parser/NaturalLanguageProcessor.java
``` java

package seedu.gtd.logic.parser;

import seedu.gtd.commons.exceptions.DataConversionException;

public interface NaturalLanguageProcessor {

/*Takes in a string written in natural language and formats it.*/
/** Takes in a string written in natural language and formats it.*/
String formatString(String s);

public static class NaturalLanguageException extends DataConversionException {
protected NaturalLanguageException() {
super("Natural Language Processor was unable to convert input");
}
}
}
```
###### /src/main/java/seedu/gtd/logic/parser/Parser.java
``` java

private String parseDueDate(String dueDateRaw) {
NaturalLanguageProcessor nlp = new DateNaturalLanguageProcessor();
return nlp.formatString(dueDateRaw);
Expand All @@ -153,14 +184,9 @@ public interface NaturalLanguageProcessor {

Optional<Integer> index = Optional.of(Integer.parseInt(matcher.group("targetIndex")));
String newDetail = matcher.group("newDetail");
System.out.println(newDetail);
String detailType = extractDetailType(newDetail);

if(detailType != "name") {
newDetail = newDetail.substring(2);
}

System.out.println(index.get() + " " + detailType + " " + newDetail);
String detailType = extractDetailType(newDetail);
newDetail = prepareNewDetail(detailType, newDetail);

return new EditCommand(
(index.get() - 1),
Expand All @@ -170,7 +196,6 @@ public interface NaturalLanguageProcessor {
}

private String extractDetailType(String detailType) {
System.out.println(detailType.substring(0, 2));
switch(detailType.substring(0, 2)) {
case "d/": return "dueDate";
case "a/": return "address";
Expand All @@ -179,6 +204,19 @@ public interface NaturalLanguageProcessor {
}
}

private String prepareNewDetail(String detailType, String newDetail) {

if(detailType == "name") {
return newDetail;
}

newDetail = newDetail.substring(2);
if(detailType == "dueDate") {
newDetail = parseDueDate(newDetail);
}
return newDetail;
}

```
###### /src/main/java/seedu/gtd/model/AddressBook.java
``` java
Expand Down Expand Up @@ -226,3 +264,133 @@ public interface NaturalLanguageProcessor {
}

```
###### /src/test/java/guitests/EditCommandTest.java
``` java

package guitests;

import org.junit.Test;

import seedu.gtd.testutil.TestTask;
import seedu.gtd.testutil.TestUtil;

import static org.junit.Assert.assertTrue;
import static seedu.gtd.logic.commands.EditCommand.MESSAGE_EDIT_TASK_SUCCESS;

public class EditCommandTest extends AddressBookGuiTest {

@Test
public void edit() {

//edit the priority of the first task
TestTask[] currentList = td.getTypicalTasks();
int targetIndex = 1;
String change = "p/4";
assertEditSuccess(targetIndex, change, currentList);

//edit the dueDate of the last in the list
currentList = TestUtil.editTaskInList(currentList, targetIndex, change, currentList[targetIndex-1]);
targetIndex = currentList.length;
change = "d/2";
assertEditSuccess(targetIndex, change, currentList);

//edit the name task from the middle of the list
currentList = TestUtil.editTaskInList(currentList, targetIndex, change, currentList[targetIndex-1]);
targetIndex = currentList.length/2;
change = "Tutorial 4";
assertEditSuccess(targetIndex, change, currentList);

//edit the address task from the middle of the list
currentList = TestUtil.editTaskInList(currentList, targetIndex, change, currentList[targetIndex-1]);
change = "a/NTU";
assertEditSuccess(targetIndex, change, currentList);

//invalid index
commandBox.runCommand("edit " + currentList.length + 1 + " Invalid");
assertResultMessage("The task index provided is invalid");

}

/**
* Runs the delete command to delete the task at specified index and confirms the result is correct.
* @param targetIndexOneIndexed e.g. to delete the first task in the list, 1 should be given as the target index.
* @param currentList A copy of the current list of tasks (before deletion).
*/
private void assertEditSuccess(int targetIndexOneIndexed, String change, final TestTask[] currentList) {
TestTask taskToEdit = currentList[targetIndexOneIndexed-1]; //-1 because array uses zero indexing
TestTask[] expectedRemainder = TestUtil.editTaskInList(currentList, targetIndexOneIndexed, change, taskToEdit);
commandBox.runCommand("edit " + targetIndexOneIndexed + " " + change);

//confirm the list now contains all previous tasks except the deleted task
assertTrue(taskListPanel.isListMatching(expectedRemainder));

//confirm the result message is correct
assertResultMessage(String.format(MESSAGE_EDIT_TASK_SUCCESS, expectedRemainder[targetIndexOneIndexed-1]));
}

}
```
###### /src/test/java/seedu/gtd/testutil/TestUtil.java
``` java

/**
* Edits a task in the array of tasks.
* @param tasks A array of tasks.
* @param tasksToAdd The tasks that are to be appended behind the original array.
* @return The modified array of tasks.
* @throws IllegalValueException
*/
public static TestTask[] editTaskInList(final TestTask[] tasks, int index, String change, TestTask taskToEdit) {
List<TestTask> listOfTasks = asList(tasks);
TestTask taskEditted;
try {
taskEditted = TestUtilParser.editTask(taskToEdit, change);
} catch (IllegalValueException e) {
taskEditted = taskToEdit;
e.printStackTrace();
}
listOfTasks.set(index-1, taskEditted);
return listOfTasks.toArray(new TestTask[listOfTasks.size()]);
}

```
###### /src/test/java/seedu/gtd/testutil/TestUtilParser.java
``` java

package seedu.gtd.testutil;

import seedu.gtd.commons.exceptions.IllegalValueException;
import seedu.gtd.logic.parser.DateNaturalLanguageProcessor;
import seedu.gtd.logic.parser.NaturalLanguageProcessor;
import seedu.gtd.model.task.Address;
import seedu.gtd.model.task.DueDate;
import seedu.gtd.model.task.Name;
import seedu.gtd.model.task.Priority;

/**
* A utility class that parses tasks for test cases.
*/
public class TestUtilParser {

public static TestTask editTask(TestTask task, String change) throws IllegalValueException {

TestTask newTask = task;
String changeWithoutPrefix = change.substring(2);
String changePrefix = change.substring(0, 2);
System.out.println("From TestUtil Parser: " + changePrefix + " " + changeWithoutPrefix);

switch(change.substring(0, 2)) {
case "d/": newTask = new TestTask(task.getName(), new DueDate(parseDueDate(changeWithoutPrefix)), task.getAddress(), task.getPriority(), task.getTags()); break;
case "a/": newTask = new TestTask(task.getName(), task.getDueDate(), new Address(changeWithoutPrefix), task.getPriority(), task.getTags()); break;
case "p/": newTask = new TestTask(task.getName(), task.getDueDate(), task.getAddress(), new Priority(changeWithoutPrefix), task.getTags()); break;
default: newTask = new TestTask(new Name(change), task.getDueDate(), task.getAddress(), task.getPriority(), task.getTags());
}
return newTask;
}

public static String parseDueDate(String dueDateRaw) {
NaturalLanguageProcessor nlp = new DateNaturalLanguageProcessor();
return nlp.formatString(dueDateRaw);
}
}
```
Loading

0 comments on commit 080ef0c

Please sign in to comment.