Skip to content

Commit

Permalink
Merge pull request nus-cs2103-AY2324S1#112 from nicolengk/Add-findcus…
Browse files Browse the repository at this point in the history
…t-feature

Add findcust feature
  • Loading branch information
nicolengk authored Oct 30, 2023
2 parents a512a15 + c1cb1cf commit b74d88b
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 33 deletions.
47 changes: 47 additions & 0 deletions src/main/java/seedu/address/commons/util/StringUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,53 @@ public static boolean containsWordIgnoreCase(String sentence, String word) {
.anyMatch(preppedWord::equalsIgnoreCase);
}

/**
* Returns true if the {@code sentence} contains the {@code word}.
* Ignores case and a full word match is NOT required.
* <br>examples:<pre>
* containsWordIgnoreCase("ABc def", "abc") == true
* containsWordIgnoreCase("ABc def", "DEF") == true
* containsWordIgnoreCase("ABc def", "AB") == true // full word match not needed
* </pre>
* @param sentence cannot be null
* @param word cannot be null, cannot be empty, must be a single word
*/
public static boolean containsWordIgnoreCaseWithoutFullMatch(String sentence, String word) {
requireNonNull(sentence);
requireNonNull(word);

String preppedWord = word.trim();
checkArgument(!preppedWord.isEmpty(), "Word parameter cannot be empty");
checkArgument(preppedWord.split("\\s+").length == 1, "Word parameter should be a single word");

String preppedSentence = sentence;
String[] wordsInPreppedSentence = preppedSentence.split("\\s+");

return Arrays.stream(wordsInPreppedSentence)
.anyMatch(w -> w.toLowerCase().contains(preppedWord.toLowerCase()));
}

/**
* Returns true if the {@code sentence} start with the {@code word}.
* Ignores case and a full word match is NOT required.
* @param sentence cannot be null
* @param word cannot be null, cannot be empty, must be a single word
*/
public static boolean startsWithWordIgnoreCaseWithoutFullMatch(String sentence, String word) {
requireNonNull(sentence);
requireNonNull(word);

String preppedWord = word.trim();
checkArgument(!preppedWord.isEmpty(), "Word parameter cannot be empty");
checkArgument(preppedWord.split("\\s+").length == 1, "Word parameter should be a single word");

String preppedSentence = sentence;
String[] wordsInPreppedSentence = preppedSentence.split("\\s+");

return Arrays.stream(wordsInPreppedSentence)
.anyMatch(w -> w.toLowerCase().startsWith(preppedWord.toLowerCase()));
}

/**
* Returns a detailed message of the t, including the stack trace.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
* Finds and lists all customers in address book whose name contains any of the argument keywords.
* Keyword matching is case insensitive.
*/
public class FindCommand extends Command {
public class FindCustomerCommand extends Command {

public static final String COMMAND_WORD = "find";
public static final String COMMAND_WORD = "findcust";

public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all customers whose names contain any of "
+ "the specified keywords (case-insensitive) and displays them as a list with index numbers.\n"
Expand All @@ -22,7 +22,7 @@ public class FindCommand extends Command {

private final NameContainsKeywordsPredicate predicate;

public FindCommand(NameContainsKeywordsPredicate predicate) {
public FindCustomerCommand(NameContainsKeywordsPredicate predicate) {
this.predicate = predicate;
}

Expand All @@ -41,12 +41,12 @@ public boolean equals(Object other) {
}

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

FindCommand otherFindCommand = (FindCommand) other;
return predicate.equals(otherFindCommand.predicate);
FindCustomerCommand otherFindCustomerCommand = (FindCustomerCommand) other;
return predicate.equals(otherFindCustomerCommand.predicate);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import seedu.address.logic.commands.EditPropertyCommand;
import seedu.address.logic.commands.ExitCommand;
import seedu.address.logic.commands.FilterCustomerCommand;
import seedu.address.logic.commands.FindCommand;
import seedu.address.logic.commands.FindCustomerCommand;
import seedu.address.logic.commands.HelpCommand;
import seedu.address.logic.commands.ListCustomerCommand;
import seedu.address.logic.commands.ListPropertyCommand;
Expand Down Expand Up @@ -79,8 +79,8 @@ public Command parseCommand(String userInput) throws ParseException {
case ClearCommand.COMMAND_WORD:
return new ClearCommand();

case FindCommand.COMMAND_WORD:
return new FindCommandParser().parse(arguments);
case FindCustomerCommand.COMMAND_WORD:
return new FindCustomerCommandParser().parse(arguments);

case FilterCustomerCommand.COMMAND_WORD:
return new FilterCustomerCommandParser().parse(arguments);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,30 @@

import java.util.Arrays;

import seedu.address.logic.commands.FindCommand;
import seedu.address.logic.commands.FindCustomerCommand;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.customer.NameContainsKeywordsPredicate;

/**
* Parses input arguments and creates a new FindCommand object
*/
public class FindCommandParser implements Parser<FindCommand> {
public class FindCustomerCommandParser implements Parser<FindCustomerCommand> {

/**
* 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 FindCommand parse(String args) throws ParseException {
public FindCustomerCommand parse(String args) throws ParseException {
String trimmedArgs = args.trim();
if (trimmedArgs.isEmpty()) {
throw new ParseException(
String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindCommand.MESSAGE_USAGE));
String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindCustomerCommand.MESSAGE_USAGE));
}

String[] nameKeywords = trimmedArgs.split("\\s+");

return new FindCommand(new NameContainsKeywordsPredicate(Arrays.asList(nameKeywords)));
return new FindCustomerCommand(new NameContainsKeywordsPredicate(Arrays.asList(nameKeywords)));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ public NameContainsKeywordsPredicate(List<String> keywords) {
@Override
public boolean test(Customer customer) {
return keywords.stream()
.anyMatch(keyword -> StringUtil.containsWordIgnoreCase(customer.getName().fullName, keyword));
.anyMatch(keyword -> StringUtil.startsWithWordIgnoreCaseWithoutFullMatch(customer.getName().fullName,
keyword));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
/**
* Contains integration tests (interaction with the Model) for {@code FindCommand}.
*/
public class FindCommandTest {
public class FindCustomerCommandTest {
private Model model = new ModelManager(getTypicalAddressBook(), getTypicalPropertyBook(), new UserPrefs());
private Model expectedModel = new ModelManager(getTypicalAddressBook(), getTypicalPropertyBook(), new UserPrefs());

Expand All @@ -35,14 +35,14 @@ public void equals() {
NameContainsKeywordsPredicate secondPredicate =
new NameContainsKeywordsPredicate(Collections.singletonList("second"));

FindCommand findFirstCommand = new FindCommand(firstPredicate);
FindCommand findSecondCommand = new FindCommand(secondPredicate);
FindCustomerCommand findFirstCommand = new FindCustomerCommand(firstPredicate);
FindCustomerCommand findSecondCommand = new FindCustomerCommand(secondPredicate);

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

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

// different types -> returns false
Expand All @@ -59,7 +59,7 @@ public void equals() {
public void execute_zeroKeywords_noCustomerFound() {
String expectedMessage = String.format(MESSAGE_CUSTOMERS_LISTED_OVERVIEW, 0);
NameContainsKeywordsPredicate predicate = preparePredicate(" ");
FindCommand command = new FindCommand(predicate);
FindCustomerCommand command = new FindCustomerCommand(predicate);
expectedModel.updateFilteredCustomerList(predicate);
assertCommandSuccess(command, model, expectedMessage, expectedModel);
assertEquals(Collections.emptyList(), model.getFilteredCustomerList());
Expand All @@ -69,7 +69,7 @@ public void execute_zeroKeywords_noCustomerFound() {
public void execute_multipleKeywords_multipleCustomersFound() {
String expectedMessage = String.format(MESSAGE_CUSTOMERS_LISTED_OVERVIEW, 3);
NameContainsKeywordsPredicate predicate = preparePredicate("Kurz Elle Kunz");
FindCommand command = new FindCommand(predicate);
FindCustomerCommand command = new FindCustomerCommand(predicate);
expectedModel.updateFilteredCustomerList(predicate);
assertCommandSuccess(command, model, expectedMessage, expectedModel);
assertEquals(Arrays.asList(CARL, ELLE, FIONA), model.getFilteredCustomerList());
Expand All @@ -78,8 +78,8 @@ public void execute_multipleKeywords_multipleCustomersFound() {
@Test
public void toStringMethod() {
NameContainsKeywordsPredicate predicate = new NameContainsKeywordsPredicate(Arrays.asList("keyword"));
FindCommand findCommand = new FindCommand(predicate);
String expected = FindCommand.class.getCanonicalName() + "{predicate=" + predicate + "}";
FindCustomerCommand findCommand = new FindCustomerCommand(predicate);
String expected = FindCustomerCommand.class.getCanonicalName() + "{predicate=" + predicate + "}";
assertEquals(expected, findCommand.toString());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import seedu.address.logic.commands.EditCustomerCommand;
import seedu.address.logic.commands.EditPropertyCommand;
import seedu.address.logic.commands.ExitCommand;
import seedu.address.logic.commands.FindCommand;
import seedu.address.logic.commands.FindCustomerCommand;
import seedu.address.logic.commands.HelpCommand;
import seedu.address.logic.commands.ListCustomerCommand;
import seedu.address.logic.parser.exceptions.ParseException;
Expand Down Expand Up @@ -101,9 +101,9 @@ public void parseCommand_exit() throws Exception {
@Test
public void parseCommand_find() throws Exception {
List<String> keywords = Arrays.asList("foo", "bar", "baz");
FindCommand command = (FindCommand) parser.parseCommand(
FindCommand.COMMAND_WORD + " " + keywords.stream().collect(Collectors.joining(" ")));
assertEquals(new FindCommand(new NameContainsKeywordsPredicate(keywords)), command);
FindCustomerCommand command = (FindCustomerCommand) parser.parseCommand(
FindCustomerCommand.COMMAND_WORD + " " + keywords.stream().collect(Collectors.joining(" ")));
assertEquals(new FindCustomerCommand(new NameContainsKeywordsPredicate(keywords)), command);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,24 @@

import org.junit.jupiter.api.Test;

import seedu.address.logic.commands.FindCommand;
import seedu.address.logic.commands.FindCustomerCommand;
import seedu.address.model.customer.NameContainsKeywordsPredicate;

public class FindCommandParserTest {
public class FindCustomerCommandParserTest {

private FindCommandParser parser = new FindCommandParser();
private FindCustomerCommandParser parser = new FindCustomerCommandParser();

@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,
FindCustomerCommand.MESSAGE_USAGE));
}

@Test
public void parse_validArgs_returnsFindCommand() {
// no leading and trailing whitespaces
FindCommand expectedFindCommand =
new FindCommand(new NameContainsKeywordsPredicate(Arrays.asList("Alice", "Bob")));
FindCustomerCommand expectedFindCommand =
new FindCustomerCommand(new NameContainsKeywordsPredicate(Arrays.asList("Alice", "Bob")));
assertParseSuccess(parser, "Alice Bob", expectedFindCommand);

// multiple whitespaces between keywords
Expand Down

0 comments on commit b74d88b

Please sign in to comment.