Skip to content

Commit

Permalink
Merge pull request #56 from KrashKart/branch-Find-Contact
Browse files Browse the repository at this point in the history
Implement filtering of contacts by number
  • Loading branch information
CYX22222003 authored Oct 10, 2024
2 parents 8da6efe + 723a527 commit a48b49b
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package seedu.address.logic.commands;

import seedu.address.model.person.ContactContainsKeywordsPredicate;

/**
* Finds and lists all persons in address book whose contact contains any of the argument keywords.
*/
public class FindByContactCommand extends AbstractFindCommand {
public static final String COMMAND_WORD = "find /c";

public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all persons whose contact numbers "
+ "contain any of the specified keywords (case-insensitive) and displays them as a list with indices.\n"
+ "Parameters: KEYWORD [MORE_KEYWORDS]...\n"
+ "Example: " + COMMAND_WORD + " 91112345 999 995";
public FindByContactCommand(ContactContainsKeywordsPredicate predicate) {
super(predicate);
}

@Override
public boolean equals(Object other) {
if (other == this) {
return true;
}

// instanceof handles nulls
if (!(other instanceof FindByContactCommand)) {
return false;
}

FindByContactCommand otherFindCommand = (FindByContactCommand) other;
return this.getPredicate().equals(otherFindCommand.getPredicate());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
* Keyword matching is case-insensitive.
*/
public class FindByNameCommand extends AbstractFindCommand {
public static final String COMMAND_WORD = "find /n";

public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all persons whose names "
+ "contain any of the specified keywords (case-insensitive) and displays them as a list with indices.\n"
+ "Parameters: KEYWORD [MORE_KEYWORDS]...\n"
+ "Example: " + COMMAND_WORD + " alice bob charlie";
public FindByNameCommand(NameContainsKeywordsPredicate predicate) {
super(predicate);
}
Expand Down
10 changes: 7 additions & 3 deletions src/main/java/seedu/address/logic/parser/FindCommandParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
import java.util.regex.Pattern;

import seedu.address.logic.commands.AbstractFindCommand;
import seedu.address.logic.commands.FindByContactCommand;
import seedu.address.logic.commands.FindByNameCommand;
import seedu.address.logic.commands.FindCommand;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.person.ContactContainsKeywordsPredicate;
import seedu.address.model.person.NameContainsKeywordsPredicate;

/**
Expand All @@ -32,19 +33,22 @@ public AbstractFindCommand parse(String args) throws ParseException {
// will throw exception if no args/command format not correct
if (trimmedArgs.isEmpty() || !m.matches()) {
throw new ParseException(
String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindCommand.MESSAGE_USAGE));
String.format(MESSAGE_INVALID_COMMAND_FORMAT, AbstractFindCommand.MESSAGE_USAGE));
}

// extract tag and search argument
String tag = m.group("tag");
String searchTerms = m.group("arguments");
String[] searchTermArray = searchTerms.split("\\s+");

// return approppriate FindCommand class depending on tag
// return appropriate FindCommand class depending on tag
switch (tag) {
case "/n":
return new FindByNameCommand(
new NameContainsKeywordsPredicate(Arrays.asList(searchTermArray)));
case "/c":
return new FindByContactCommand(
new ContactContainsKeywordsPredicate(Arrays.asList(searchTermArray)));
default:
return null; // temporary value, this should not occur due to regex
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package seedu.address.logic.commands;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static seedu.address.logic.Messages.MESSAGE_PERSONS_LISTED_OVERVIEW;
import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;

import java.util.Arrays;
import java.util.Collections;

import org.junit.jupiter.api.Test;

import seedu.address.model.Model;
import seedu.address.model.ModelManager;
import seedu.address.model.UserPrefs;
import seedu.address.model.person.ContactContainsKeywordsPredicate;
import seedu.address.model.person.NameContainsKeywordsPredicate;

/**
* Contains integration tests (interaction with the Model) for {@code FindByContactCommand}.
*/
public class FindByContactCommandTest {
private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
private Model expectedModel = new ModelManager(getTypicalAddressBook(), new UserPrefs());

@Test
public void equals() {
ContactContainsKeywordsPredicate firstPredicate =
new ContactContainsKeywordsPredicate(Collections.singletonList("first"));
ContactContainsKeywordsPredicate secondPredicate =
new ContactContainsKeywordsPredicate(Collections.singletonList("second"));

FindByContactCommand findFirstCommand = new FindByContactCommand(firstPredicate);
FindByContactCommand findSecondCommand = new FindByContactCommand(secondPredicate);

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

// same values -> returns true
FindByContactCommand findFirstCommandCopy = new FindByContactCommand(firstPredicate);
assertTrue(findFirstCommand.equals(findFirstCommandCopy));

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

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

// different person -> returns false
assertFalse(findFirstCommand.equals(findSecondCommand));
}

@Test
public void execute_zeroKeywords_noPersonFound() {
String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 0);
ContactContainsKeywordsPredicate predicate = preparePredicate(" ");
FindByContactCommand command = new FindByContactCommand(predicate);
expectedModel.updateFilteredPersonList(predicate);
assertCommandSuccess(command, model, expectedMessage, expectedModel);
assertEquals(Collections.emptyList(), model.getFilteredPersonList());
}

// Commented out because expectedModel does not contain contact numbers
// @Test
// public void execute_multipleKeywords_multiplePersonsFound() {
// String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 0);
// ContactContainsKeywordsPredicate predicate = preparePredicate("999");
// FindByContactCommand command = new FindByContactCommand(predicate);
// expectedModel.updateFilteredPersonList(predicate);
// assertCommandSuccess(command, model, expectedMessage, expectedModel);
// assertEquals(Arrays.asList(CARL, ELLE, FIONA), model.getFilteredPersonList());
// }

@Test
public void toStringMethod() {
NameContainsKeywordsPredicate predicate = new NameContainsKeywordsPredicate(Arrays.asList("keyword"));
FindByNameCommand findCommand = new FindByNameCommand(predicate);
String expected = FindByNameCommand.class.getCanonicalName() + "{predicate=" + predicate + "}";
assertEquals(expected, findCommand.toString());
}

/**
* Parses {@code userInput} into a {@code NameContainsKeywordsPredicate}.
*/
private ContactContainsKeywordsPredicate preparePredicate(String userInput) {
return new ContactContainsKeywordsPredicate(Arrays.asList(userInput.split("\\s+")));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import seedu.address.model.person.NameContainsKeywordsPredicate;

/**
* Contains integration tests (interaction with the Model) for {@code FindCommand}.
* Contains integration tests (interaction with the Model) for {@code FindByNameCommand}.
*/
public class FindByNameCommandTest {
private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@
import seedu.address.logic.commands.EditCommand;
import seedu.address.logic.commands.EditCommand.EditPersonDescriptor;
import seedu.address.logic.commands.ExitCommand;
import seedu.address.logic.commands.FindByContactCommand;
import seedu.address.logic.commands.FindByNameCommand;
import seedu.address.logic.commands.HelpCommand;
import seedu.address.logic.commands.ListCommand;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.person.ContactContainsKeywordsPredicate;
import seedu.address.model.person.NameContainsKeywordsPredicate;
import seedu.address.model.person.Person;
import seedu.address.testutil.EditPersonDescriptorBuilder;
Expand Down Expand Up @@ -80,11 +82,20 @@ public void parseCommand_exit() throws Exception {
public void parseCommand_findByName() throws Exception {
List<String> keywords = Arrays.asList("foo", "bar", "baz");
FindByNameCommand command = (FindByNameCommand) parser.parseCommand(
FindByNameCommand.COMMAND_WORD + " /n "
FindByNameCommand.COMMAND_WORD + " "
+ keywords.stream().collect(Collectors.joining(" ")));
assertEquals(new FindByNameCommand(new NameContainsKeywordsPredicate(keywords)), command);
}

@Test
public void parseCommand_findByContact() throws Exception {
List<String> keywords = Arrays.asList("995", "91234567", "132");
FindByContactCommand command = (FindByContactCommand) parser.parseCommand(
FindByContactCommand.COMMAND_WORD + " "
+ keywords.stream().collect(Collectors.joining(" ")));
assertEquals(new FindByContactCommand(new ContactContainsKeywordsPredicate(keywords)), command);
}

@Test
public void parseCommand_help() throws Exception {
assertTrue(parser.parseCommand(HelpCommand.COMMAND_WORD) instanceof HelpCommand);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@

import org.junit.jupiter.api.Test;

import seedu.address.logic.commands.AbstractFindCommand;
import seedu.address.logic.commands.FindByContactCommand;
import seedu.address.logic.commands.FindByNameCommand;
import seedu.address.logic.commands.FindCommand;
import seedu.address.model.person.ContactContainsKeywordsPredicate;
import seedu.address.model.person.NameContainsKeywordsPredicate;

public class FindCommandParserTest {
Expand All @@ -18,7 +20,8 @@ public class FindCommandParserTest {

@Test
public void parse_emptyArg_throwsParseException() {
assertParseFailure(parser, " ", String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindCommand.MESSAGE_USAGE));
assertParseFailure(parser, " ", String.format(MESSAGE_INVALID_COMMAND_FORMAT,
AbstractFindCommand.MESSAGE_USAGE));
}

@Test
Expand All @@ -33,4 +36,17 @@ public void parse_validArgs_returnsFindByNameCommand() {
assertParseSuccess(parser, "/n \n Alice \n \t Bob \t", expectedFindCommand);
}

@Test
public void parse_validArgs_returnsFindByContactCommand() {
FindByContactCommand expectedFindCommand =
new FindByContactCommand(new ContactContainsKeywordsPredicate(
Arrays.asList("91234567", "995")));

// no leading and trailing whitespaces
assertParseSuccess(parser, "/c 91234567 995", expectedFindCommand);

// multiple whitespaces between keywords
assertParseSuccess(parser, "/c \n 91234567 \n \t 995 \t", expectedFindCommand);
}

}

0 comments on commit a48b49b

Please sign in to comment.