forked from nus-cs2103-AY2122S1/tp
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #54 from cliveong/search-by-involvement
Add filter by involvement
- Loading branch information
Showing
6 changed files
with
235 additions
and
0 deletions.
There are no files selected for viewing
43 changes: 43 additions & 0 deletions
43
src/main/java/seedu/address/logic/commands/FilterCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package seedu.address.logic.commands; | ||
|
||
import static java.util.Objects.requireNonNull; | ||
|
||
import seedu.address.commons.core.Messages; | ||
import seedu.address.model.Model; | ||
import seedu.address.model.person.InvolvementContainsKeywordsPredicate; | ||
|
||
/** | ||
* Filters and lists all persons in address book whose involvement contains any of the argument keywords. | ||
* Keyword matching is case insensitive. | ||
*/ | ||
public class FilterCommand extends Command { | ||
|
||
public static final String COMMAND_WORD = "filter"; | ||
|
||
public static final String MESSAGE_USAGE = COMMAND_WORD + ": Filters all persons whose involvement contain any of " | ||
+ "the specified keywords (case-insensitive) and displays them as a list with index numbers.\n" | ||
+ "Parameters: KEYWORD [MORE_KEYWORDS]...\n" | ||
+ "Example: " + COMMAND_WORD + " donut buddies"; | ||
|
||
private final InvolvementContainsKeywordsPredicate predicate; | ||
|
||
public FilterCommand(InvolvementContainsKeywordsPredicate predicate) { | ||
this.predicate = predicate; | ||
} | ||
|
||
@Override | ||
public CommandResult execute(Model model) { | ||
requireNonNull(model); | ||
model.updateFilteredPersonList(predicate); | ||
return new CommandResult( | ||
String.format(Messages.MESSAGE_PERSONS_LISTED_OVERVIEW, model.getFilteredPersonList().size())); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object other) { | ||
return other == this // short circuit if same object | ||
|| (other instanceof FilterCommand // instanceof handles nulls | ||
&& predicate.equals(((FilterCommand) other).predicate)); // state check | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
35 changes: 35 additions & 0 deletions
35
src/main/java/seedu/address/logic/parser/FilterCommandParser.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package seedu.address.logic.parser; | ||
|
||
import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; | ||
|
||
import java.util.Arrays; | ||
|
||
import seedu.address.logic.commands.FilterCommand; | ||
import seedu.address.logic.parser.exceptions.ParseException; | ||
import seedu.address.model.person.InvolvementContainsKeywordsPredicate; | ||
|
||
|
||
|
||
/** | ||
* Parses input arguments and creates a new FindCommand object | ||
*/ | ||
public class FilterCommandParser implements Parser<FilterCommand> { | ||
|
||
/** | ||
* Parses the given {@code String} of arguments in the context of the FindCommand | ||
* and returns a FindCommand object for execution. | ||
* @throws ParseException if the user input does not conform the expected format | ||
*/ | ||
public FilterCommand parse(String args) throws ParseException { | ||
String trimmedArgs = args.trim(); | ||
if (trimmedArgs.isEmpty()) { | ||
throw new ParseException( | ||
String.format(MESSAGE_INVALID_COMMAND_FORMAT, FilterCommand.MESSAGE_USAGE)); | ||
} | ||
|
||
String[] nameKeywords = trimmedArgs.split("\\s+"); | ||
|
||
return new FilterCommand(new InvolvementContainsKeywordsPredicate(Arrays.asList(nameKeywords))); | ||
} | ||
|
||
} |
31 changes: 31 additions & 0 deletions
31
src/main/java/seedu/address/model/person/InvolvementContainsKeywordsPredicate.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package seedu.address.model.person; | ||
|
||
import java.util.List; | ||
import java.util.function.Predicate; | ||
|
||
import seedu.address.commons.util.StringUtil; | ||
|
||
/** | ||
* Tests that a {@code Person}'s {@code Name} matches any of the keywords given. | ||
*/ | ||
public class InvolvementContainsKeywordsPredicate implements Predicate<Person> { | ||
private final List<String> keywords; | ||
|
||
public InvolvementContainsKeywordsPredicate(List<String> keywords) { | ||
this.keywords = keywords; | ||
} | ||
|
||
@Override | ||
public boolean test(Person person) { | ||
return keywords.stream() | ||
.anyMatch(keyword -> StringUtil.containsWordIgnoreCase(person.getInvolvement().involvement, keyword)); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object other) { | ||
return other == this // short circuit if same object | ||
|| (other instanceof InvolvementContainsKeywordsPredicate // instanceof handles nulls | ||
&& keywords.equals(((InvolvementContainsKeywordsPredicate) other).keywords)); // state check | ||
} | ||
|
||
} |
87 changes: 87 additions & 0 deletions
87
src/test/java/seedu/address/logic/commands/FilterCommandTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.assertFalse; | ||
import static org.junit.jupiter.api.Assertions.assertTrue; | ||
import static seedu.address.commons.core.Messages.MESSAGE_PERSONS_LISTED_OVERVIEW; | ||
import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; | ||
import static seedu.address.testutil.TypicalStudents.ALICE; | ||
import static seedu.address.testutil.TypicalStudents.BENSON; | ||
import static seedu.address.testutil.TypicalStudents.CARL; | ||
import static seedu.address.testutil.TypicalStudents.DANIEL; | ||
import static seedu.address.testutil.TypicalStudents.ELLE; | ||
import static seedu.address.testutil.TypicalStudents.FIONA; | ||
import static seedu.address.testutil.TypicalStudents.GEORGE; | ||
import static seedu.address.testutil.TypicalStudents.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.InvolvementContainsKeywordsPredicate; | ||
|
||
/** | ||
* Contains integration tests (interaction with the Model) for {@code FindCommand}. | ||
*/ | ||
public class FilterCommandTest { | ||
private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); | ||
private Model expectedModel = new ModelManager(getTypicalAddressBook(), new UserPrefs()); | ||
|
||
@Test | ||
public void equals() { | ||
InvolvementContainsKeywordsPredicate firstPredicate = | ||
new InvolvementContainsKeywordsPredicate(Collections.singletonList("first")); | ||
InvolvementContainsKeywordsPredicate secondPredicate = | ||
new InvolvementContainsKeywordsPredicate(Collections.singletonList("second")); | ||
|
||
FilterCommand findFirstCommand = new FilterCommand(firstPredicate); | ||
FilterCommand findSecondCommand = new FilterCommand(secondPredicate); | ||
|
||
// same object -> returns true | ||
assertTrue(findFirstCommand.equals(findFirstCommand)); | ||
|
||
// same values -> returns true | ||
FilterCommand findFirstCommandCopy = new FilterCommand(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); | ||
InvolvementContainsKeywordsPredicate predicate = preparePredicate(" "); | ||
FilterCommand command = new FilterCommand(predicate); | ||
expectedModel.updateFilteredPersonList(predicate); | ||
assertCommandSuccess(command, model, expectedMessage, expectedModel); | ||
assertEquals(Collections.emptyList(), model.getFilteredPersonList()); | ||
} | ||
|
||
@Test | ||
public void execute_multipleKeywords_multiplePersonsFound() { | ||
String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 7); | ||
InvolvementContainsKeywordsPredicate predicate = preparePredicate("Form class"); | ||
FilterCommand command = new FilterCommand(predicate); | ||
expectedModel.updateFilteredPersonList(predicate); | ||
assertCommandSuccess(command, model, expectedMessage, expectedModel); | ||
assertEquals(Arrays.asList(ALICE, BENSON, CARL, DANIEL, ELLE, FIONA, GEORGE), model.getFilteredPersonList()); | ||
} | ||
|
||
/** | ||
* Parses {@code userInput} into a {@code NameContainsKeywordsPredicate}. | ||
*/ | ||
private InvolvementContainsKeywordsPredicate preparePredicate(String userInput) { | ||
return new InvolvementContainsKeywordsPredicate(Arrays.asList(userInput.split("\\s+"))); | ||
} | ||
} |
35 changes: 35 additions & 0 deletions
35
src/test/java/seedu/address/logic/parser/FilterCommandParserTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package seedu.address.logic.parser; | ||
|
||
import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; | ||
import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure; | ||
import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess; | ||
|
||
import java.util.Arrays; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
import seedu.address.logic.commands.FilterCommand; | ||
import seedu.address.model.person.InvolvementContainsKeywordsPredicate; | ||
|
||
|
||
public class FilterCommandParserTest { | ||
|
||
private FilterCommandParser parser = new FilterCommandParser(); | ||
|
||
@Test | ||
public void parse_emptyArg_throwsParseException() { | ||
assertParseFailure(parser, " ", String.format(MESSAGE_INVALID_COMMAND_FORMAT, FilterCommand.MESSAGE_USAGE)); | ||
} | ||
|
||
@Test | ||
public void parse_validArgs_returnsFilterCommand() { | ||
// no leading and trailing whitespaces | ||
FilterCommand expectedFilterCommand = | ||
new FilterCommand(new InvolvementContainsKeywordsPredicate(Arrays.asList("Alice", "Bob"))); | ||
assertParseSuccess(parser, "Alice Bob", expectedFilterCommand); | ||
|
||
// multiple whitespaces between keywords | ||
assertParseSuccess(parser, " \n Alice \n \t Bob \t", expectedFilterCommand); | ||
} | ||
|
||
} |