Skip to content

Commit

Permalink
Merge pull request nus-cs2103-AY2021S1#96 from li-s/branch-RenameCommand
Browse files Browse the repository at this point in the history
Branch rename command
  • Loading branch information
li-s authored Oct 13, 2020
2 parents 3d0660e + 9b7838b commit b6727f1
Show file tree
Hide file tree
Showing 10 changed files with 353 additions and 6 deletions.
4 changes: 2 additions & 2 deletions src/main/java/seedu/address/logic/commands/ListCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
import seedu.address.model.Model;

/**
* Lists all persons in the address book to the user.
* Lists all tags in the address book to the user.
*/
public class ListCommand extends Command {

public static final String COMMAND_WORD = "list";

public static final String MESSAGE_SUCCESS = "Listed all persons";
public static final String MESSAGE_SUCCESS = "Listed all tags";


@Override
Expand Down
93 changes: 93 additions & 0 deletions src/main/java/seedu/address/logic/commands/RetagCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package seedu.address.logic.commands;

import static java.util.Objects.requireNonNull;
import static seedu.address.logic.parser.CliSyntax.PREFIX_OLD_TAG_NAME;
import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG_NAME;

import java.util.List;

import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.model.Model;
import seedu.address.model.tag.FileAddress;
import seedu.address.model.tag.Tag;
import seedu.address.model.tag.TagName;
import seedu.address.model.tag.TagNameEqualsKeywordPredicate;

/**
* Adds a person to the address book.
*/
public class RetagCommand extends Command {
public static final String COMMAND_WORD = "retag";

public static final String MESSAGE_USAGE = COMMAND_WORD
+ ": Retags the tagged file identified by the old tag into the new tag.\n"
+ "Parameters: "
+ PREFIX_OLD_TAG_NAME + "OLD_TAG_NAME "
+ PREFIX_TAG_NAME + "NEW_TAG_NAME\n"
+ "Example: " + COMMAND_WORD + " "
+ PREFIX_OLD_TAG_NAME + "my_files "
+ PREFIX_TAG_NAME + "my_old_files ";

public static final String MESSAGE_RETAG_TAG_SUCCESS = "Retagged Tag: %s to Tag: %s";
public static final String MESSAGE_OLD_TAG_NOT_FOUND = " %s tag not found!"
+ " Please make sure that the old tag is present before retagging.";
public static final String MESSAGE_DUPLICATE_TAG = "Duplicate tag name!";

private final TagName newTagName;
private final TagName oldTagName;

/**
* Creates a RetagCommand to retag the specified {@code oldTagName} to {@code newTagName}
*/
public RetagCommand(TagName oldTagName, TagName newTagName) {
requireNonNull(oldTagName);
requireNonNull(newTagName);

this.oldTagName = oldTagName;
this.newTagName = newTagName;
}

/**
* Executes the command and renames the tag in the model to the new tag.
*
* @param model {@code Model} which the command should operate on.
* @return A Command result of executing retag command.
* @throws CommandException
*/
@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);

// Check if oldTagName is in tag list
List<Tag> oldTagList = model.findFilteredTagList(new TagNameEqualsKeywordPredicate(oldTagName));
if (oldTagList.isEmpty()) {
throw new CommandException(String.format(MESSAGE_OLD_TAG_NOT_FOUND, oldTagName.toString()));
}

// Check if newTagName is in tag list
List<Tag> newTagList = model.findFilteredTagList(new TagNameEqualsKeywordPredicate(newTagName));
if (!newTagList.isEmpty()) {
throw new CommandException(String.format(MESSAGE_DUPLICATE_TAG));
}

// Get oldTagName
Tag tagToChange = oldTagList.get(0);
// Get file path
FileAddress fileAddress = tagToChange.getFileAddress();
// Delete old tag
model.deleteTag(tagToChange);

Tag newTag = new Tag(newTagName, fileAddress);
// Add new tag
model.addTag(newTag);
return new CommandResult(String.format(MESSAGE_RETAG_TAG_SUCCESS, oldTagName, newTagName));
}

@Override
public boolean equals(Object other) {
return other == this // short circuit if same object
|| (other instanceof RetagCommand // instanceof handles nulls
&& newTagName.equals(((RetagCommand) other).newTagName)
&& oldTagName.equals(((RetagCommand) other).oldTagName));
}
}
6 changes: 3 additions & 3 deletions src/main/java/seedu/address/logic/commands/TagCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@
import seedu.address.model.tag.Tag;

/**
* Adds a person to the address book.
* Adds a tag to the address book.
*/
public class TagCommand extends Command {

public static final String COMMAND_WORD = "tag";

public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a tag to the HelleFile's address book. "
public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a tag to the HelleFile's address book.\n"
+ "Parameters: "
+ PREFIX_TAG_NAME + "TAG_NAME "
+ PREFIX_FILE_ADDRESS + "FILE_ADDRESS "
+ PREFIX_FILE_ADDRESS + "FILE_ADDRESS\n"
+ "Example: " + COMMAND_WORD + " "
+ PREFIX_TAG_NAME + "cs2103 "
+ PREFIX_FILE_ADDRESS + "F:\\OneDrive\\CS2013T ";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import seedu.address.logic.commands.HelpCommand;
import seedu.address.logic.commands.ListCommand;
import seedu.address.logic.commands.OpenCommand;
import seedu.address.logic.commands.RetagCommand;
import seedu.address.logic.commands.ShowCommand;
import seedu.address.logic.commands.TagCommand;
import seedu.address.logic.commands.UntagCommand;
Expand Down Expand Up @@ -51,6 +52,9 @@ public Command parseCommand(String userInput) throws ParseException {
case UntagCommand.COMMAND_WORD:
return new UntagCommandParser().parse(arguments);

case RetagCommand.COMMAND_WORD:
return new RetagCommandParser().parse(arguments);

case OpenCommand.COMMAND_WORD:
return new OpenCommandParser().parse(arguments);

Expand Down
48 changes: 48 additions & 0 deletions src/main/java/seedu/address/logic/parser/RetagCommandParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package seedu.address.logic.parser;

import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.address.logic.parser.CliSyntax.PREFIX_OLD_TAG_NAME;
import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG_NAME;

import java.util.stream.Stream;

import seedu.address.logic.commands.RetagCommand;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.tag.TagName;

/**
* Parses input arguments and creates a new RetagCommand object
*/
public class RetagCommandParser implements Parser<RetagCommand> {

/**
* Parses the given {@code String} of arguments in the context of the RetagCommand
* and returns a RetagCommand object for execution.
* @throws ParseException if the user input does not conform the expected format
*/
public RetagCommand parse(String args) throws ParseException {
ArgumentMultimap argMultimap =
ArgumentTokenizer.tokenize(args, PREFIX_OLD_TAG_NAME, PREFIX_TAG_NAME);

boolean a = arePrefixesPresent(argMultimap, PREFIX_OLD_TAG_NAME, PREFIX_TAG_NAME);
boolean b = argMultimap.getPreamble().isEmpty();
Object c = argMultimap.getPreamble();
if (!arePrefixesPresent(argMultimap, PREFIX_OLD_TAG_NAME, PREFIX_TAG_NAME)
|| !argMultimap.getPreamble().isEmpty()) {
throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, RetagCommand.MESSAGE_USAGE));
}

TagName oldTagName = ParserUtil.parseTagName(argMultimap.getValue(PREFIX_OLD_TAG_NAME).get());
TagName newTagName = ParserUtil.parseTagName(argMultimap.getValue(PREFIX_TAG_NAME).get());

return new RetagCommand(oldTagName, newTagName);
}

/**
* Returns true if none of the prefixes contains empty {@code Optional} values in the given
* {@code ArgumentMultimap}.
*/
private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) {
return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static seedu.address.logic.parser.CliSyntax.PREFIX_FILE_ADDRESS;
import static seedu.address.logic.parser.CliSyntax.PREFIX_OLD_TAG_NAME;
import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG_NAME;
import static seedu.address.testutil.Assert.assertThrows;

Expand Down Expand Up @@ -34,6 +35,8 @@ public class CommandTestUtil {
public static final String VALID_TAG_HUSBAND = "husband";
public static final String VALID_TAG_FRIEND = "friend";

public static final String NAME_DESC_OLD_CS2101 = " " + PREFIX_OLD_TAG_NAME + VALID_NAME_CS2101;
public static final String NAME_DESC_OLD_CS2103 = " " + PREFIX_OLD_TAG_NAME + VALID_NAME_CS2103;
public static final String NAME_DESC_CS2103 = " " + PREFIX_TAG_NAME + VALID_NAME_CS2103;
public static final String NAME_DESC_CS2101 = " " + PREFIX_TAG_NAME + VALID_NAME_CS2101;
public static final String NAME_DESC_AMY = " " + PREFIX_TAG_NAME + VALID_NAME_AMY;
Expand All @@ -46,6 +49,8 @@ public class CommandTestUtil {
public static final String TAG_DESC_FRIEND = " " + VALID_TAG_FRIEND;
public static final String TAG_DESC_HUSBAND = " " + VALID_TAG_HUSBAND;

public static final String INVALID_OLD_TAG_DESC = " " + PREFIX_OLD_TAG_NAME + "myfile&"; // '&' not allowed in names
public static final String INVALID_NEW_TAG_DESC = " " + PREFIX_TAG_NAME + "myfile&"; // '&' not allowed in names
public static final String INVALID_NAME_DESC = " " + PREFIX_TAG_NAME + "James&"; // '&' not allowed in names
public static final String INVALID_FILE_ADDRESS_DESC = " "
+ PREFIX_FILE_ADDRESS; // empty string not allowed for addresses
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package seedu.address.logic.commands;

import static java.util.Objects.requireNonNull;

import java.util.List;
import java.util.function.Predicate;

import seedu.address.model.tag.Tag;

public class ModelStubWithTagAndTaglist extends ModelStub {
private Tag tag;

ModelStubWithTagAndTaglist(Tag tag) {
requireNonNull(tag);
this.tag = tag;
}

public Tag getTag() {
return this.tag;
}

@Override
public void addTag(Tag tag) {
this.tag = tag;
}

@Override
public void deleteTag(Tag tag) {

}

@Override
public List<Tag> findFilteredTagList(Predicate<Tag> predicate) {
if (predicate.test(tag)) {
return List.of(tag);
}

return List.of();
}

@Override
public boolean equals(Object other) {
boolean a = other instanceof ModelStubWithTagAndTaglist;
return other == this // short circuit if same object
|| (other instanceof ModelStubWithTagAndTaglist // instanceof handles nulls
&& ((ModelStubWithTagAndTaglist) other).tag.equals(this.tag));
}
}
87 changes: 87 additions & 0 deletions src/test/java/seedu/address/logic/commands/RetagCommandTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package seedu.address.logic.commands;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
import static seedu.address.testutil.Assert.assertThrows;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.model.tag.Tag;
import seedu.address.model.tag.TagName;
import seedu.address.testutil.TagBuilder;

public class RetagCommandTest {

private ModelStubWithTagAndTaglist modelStub;

@BeforeEach
public void setUp() {
Tag validTag = new TagBuilder().build();

modelStub = new ModelStubWithTagAndTaglist(validTag);
}

@Test
public void execute_duplicateNewTagName_throwsCommandException() {
TagName oldTag = new TagBuilder().build().getTagName();
TagName newTag = new TagBuilder().build().getTagName();

RetagCommand retagCommand = new RetagCommand(oldTag, newTag);

assertThrows(CommandException.class, RetagCommand.MESSAGE_DUPLICATE_TAG, () -> retagCommand.execute(modelStub));
}

@Test
public void execute_oldTagNotInModel_throwCommandException() {
TagName oldTagName = new TagName("noExist");
TagName newTagName = new TagName("noMatter");

RetagCommand retagCommand = new RetagCommand(oldTagName, newTagName);

assertThrows(CommandException.class, String.format(RetagCommand.MESSAGE_OLD_TAG_NOT_FOUND,
oldTagName.tagName), () -> retagCommand.execute(modelStub));
}

@Test
public void execute_validInput_retagSuccess() {
Tag newTag = new TagBuilder().withTagName("new").build();

TagName oldTagName = new TagBuilder().build().getTagName();
TagName newTagName = newTag.getTagName();

RetagCommand retagCommand = new RetagCommand(oldTagName, newTagName);

ModelStubWithTagAndTaglist expectedModelStub = new ModelStubWithTagAndTaglist(newTag);

assertCommandSuccess(retagCommand, modelStub,
String.format(retagCommand.MESSAGE_RETAG_TAG_SUCCESS, oldTagName, newTagName), expectedModelStub);
}

@Test
public void equals() {
TagName oldTagName = new TagName("oldTag");
TagName newTagName = new TagName("newTag");

RetagCommand retagCommand1 = new RetagCommand(oldTagName, newTagName);
RetagCommand retagCommand2 = new RetagCommand(newTagName, oldTagName);

// same object -> returns true
assertTrue(retagCommand1.equals(retagCommand1));

// same values -> returns true
RetagCommand retagCommand1Copy = new RetagCommand(oldTagName, newTagName);
assertTrue(retagCommand1.equals(retagCommand1Copy));

// different types -> returns false
assertFalse(retagCommand1.equals(1));

// null -> returns false
assertFalse(retagCommand1.equals(null));

// different tagName -> returns false
assertFalse(retagCommand1.equals(retagCommand2));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public void execute_invalidTagName_throwsCommandException() {
}

@Test
public void execute_validTagName_throwsCommandException() {
public void execute_validTagName_showTagFileSuccess() {
Tag tagToBeShown = model.getFilteredTagList().get(INDEX_FIRST_TAG.getZeroBased());
TagNameEqualsKeywordPredicate predicate = new TagNameEqualsKeywordPredicate(tagToBeShown.getTagName());
ShowCommand showCommand = new ShowCommand(predicate);
Expand Down
Loading

0 comments on commit b6727f1

Please sign in to comment.