Skip to content

Commit

Permalink
Merge pull request #152 from itsme-zeix/add-filter-by-status
Browse files Browse the repository at this point in the history
Add Filtering by Status
  • Loading branch information
itsme-zeix authored Nov 2, 2024
2 parents b8f1ef3 + c06208c commit 3e6ea34
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE;
import static seedu.address.logic.parser.CliSyntax.PREFIX_REMARK;
import static seedu.address.logic.parser.CliSyntax.PREFIX_STATUS;
import static seedu.address.logic.parser.CliSyntax.PREFIX_TIER;

import java.util.ArrayList;
Expand All @@ -28,6 +29,7 @@
import seedu.address.model.person.predicates.NameContainsSubstringPredicate;
import seedu.address.model.person.predicates.PhoneContainsSubstringPredicate;
import seedu.address.model.person.predicates.RemarkContainsSubstringPredicate;
import seedu.address.model.person.predicates.StatusStartsWithSubstringPredicate;
import seedu.address.model.person.predicates.TierStartsWithSubstringPredicate;
import seedu.address.model.util.IncomeComparisonOperator;

Expand All @@ -45,14 +47,14 @@ public FilterCommand parse(String args) throws ParseException {
requireNonNull(args);
ArgumentMultimap argMultimap =
ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS,
PREFIX_INCOME, PREFIX_JOB, PREFIX_REMARK, PREFIX_TIER);
PREFIX_INCOME, PREFIX_JOB, PREFIX_REMARK, PREFIX_TIER, PREFIX_STATUS);

argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS,
PREFIX_INCOME, PREFIX_JOB, PREFIX_REMARK, PREFIX_TIER);
PREFIX_INCOME, PREFIX_JOB, PREFIX_REMARK, PREFIX_TIER, PREFIX_STATUS);

// Throw an error if no filters are used
long numberOfFiltersUsed = countPrefixesUsed(argMultimap, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL,
PREFIX_ADDRESS, PREFIX_JOB, PREFIX_INCOME, PREFIX_REMARK, PREFIX_TIER);
PREFIX_ADDRESS, PREFIX_JOB, PREFIX_INCOME, PREFIX_REMARK, PREFIX_TIER, PREFIX_STATUS);

if (numberOfFiltersUsed == 0) {
throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, FilterCommand.MESSAGE_USAGE));
Expand Down Expand Up @@ -129,6 +131,10 @@ private List<Predicate<Person>> collectPredicates(ArgumentMultimap argMultimap)
String substring = argMultimap.getValue(PREFIX_TIER).get();
predicates.add(new TierStartsWithSubstringPredicate(substring));
}
if (argMultimap.getValue(PREFIX_STATUS).isPresent()) {
String substring = argMultimap.getValue(PREFIX_STATUS).get();
predicates.add(new StatusStartsWithSubstringPredicate(substring));
}
return predicates;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package seedu.address.model.person.predicates;

import java.util.function.Predicate;

import seedu.address.commons.util.StringUtil;
import seedu.address.commons.util.ToStringBuilder;
import seedu.address.model.person.Person;

/**
* Tests that a {@code Person}'s assigned {@code Status} starts with a specified String.
*/
public class StatusStartsWithSubstringPredicate implements Predicate<Person> {
protected final String substring;

public StatusStartsWithSubstringPredicate(String substring) {
this.substring = substring.toUpperCase();
}

@Override
public boolean test(Person person) {
return StringUtil.startsWithSubstringIgnoreCase(person.getStatus().toParsableString(), substring);
}

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

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

StatusStartsWithSubstringPredicate otherStatusContainsSubstringPredicate =
(StatusStartsWithSubstringPredicate) other;
return substring.equals(otherStatusContainsSubstringPredicate.substring);
}

@Override
public String toString() {
return new ToStringBuilder(this).add("substring", substring).toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package seedu.address.model.person.predicates;


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 org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import seedu.address.testutil.PersonBuilder;

public class StatusStartsWithSubstringPredicateTest {

@Test
public void equals() {
String firstPredicateSubstring = "first";
String secondPredicateSubstring = "first second";

StatusStartsWithSubstringPredicate firstPredicate =
new StatusStartsWithSubstringPredicate(firstPredicateSubstring);
StatusStartsWithSubstringPredicate secondPredicate =
new StatusStartsWithSubstringPredicate(secondPredicateSubstring);

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

// same values -> returns true
StatusStartsWithSubstringPredicate firstPredicateCopy =
new StatusStartsWithSubstringPredicate(firstPredicateSubstring);
assertTrue(firstPredicate.equals(firstPredicateCopy));

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

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

// different person -> returns false
assertFalse(firstPredicate.equals(secondPredicate));
}

@Test
public void test_statusStartsWithSubstring_returnsTrue() {
// Full status match
StatusStartsWithSubstringPredicate predicate = new StatusStartsWithSubstringPredicate("urgent");
assertTrue(predicate.test(new PersonBuilder().withStatus("urgent").build()));

// Partial status match
predicate = new StatusStartsWithSubstringPredicate("ur");
assertTrue(predicate.test(new PersonBuilder().withStatus("urgent").build()));

// Mixed-case substring
predicate = new StatusStartsWithSubstringPredicate("uRgEnt");
assertTrue(predicate.test(new PersonBuilder().withStatus("URGENT").build()));
}

@Test
public void test_emptySubstring_throwsException() {
StatusStartsWithSubstringPredicate predicate = new StatusStartsWithSubstringPredicate("");
Assertions.assertThrows(IllegalArgumentException.class, () -> predicate.test(
new PersonBuilder().withStatus("URGENT").build()));
}

@Test
public void test_statusDoesNotStartWithSubstring_returnsFalse() {
// Non-matching substring
StatusStartsWithSubstringPredicate predicate = new StatusStartsWithSubstringPredicate("URGENT");
assertFalse(predicate.test(new PersonBuilder().withStatus("Non_urgent").build()));

// Substring matches name but does not match status
predicate = new StatusStartsWithSubstringPredicate("Alice");
assertFalse(predicate.test(new PersonBuilder().withName("Alice").withPhone("91234567")
.withEmail("[email protected]").withAddress("Main Street").withRemark("Genius")
.withJob("Doctor").withTier("GOLD").withStatus("URGENT").build()));

// Substring matches phone but does not match status
predicate = new StatusStartsWithSubstringPredicate("91234567");
assertFalse(predicate.test(new PersonBuilder().withName("Alice").withPhone("91234567")
.withEmail("[email protected]").withAddress("Main Street").withRemark("Genius")
.withJob("Doctor").withTier("GOLD").withStatus("URGENT").build()));

// Substring matches email but does not match status
predicate = new StatusStartsWithSubstringPredicate("[email protected]");
assertFalse(predicate.test(new PersonBuilder().withName("Alice").withPhone("91234567")
.withEmail("[email protected]").withAddress("Main Street").withRemark("Genius")
.withJob("Doctor").withTier("GOLD").withStatus("URGENT").build()));

// Substring matches address but does not match status
predicate = new StatusStartsWithSubstringPredicate("Main Street");
assertFalse(predicate.test(new PersonBuilder().withName("Alice").withPhone("91234567")
.withEmail("[email protected]").withAddress("Main Street").withRemark("Genius")
.withJob("Doctor").withTier("GOLD").withStatus("URGENT").build()));

// Substring matches remark but does not match status
predicate = new StatusStartsWithSubstringPredicate("Doctor");
assertFalse(predicate.test(new PersonBuilder().withName("Alice").withPhone("91234567")
.withEmail("[email protected]").withAddress("Main Street").withRemark("Genius")
.withJob("Doctor").withTier("GOLD").withStatus("URGENT").build()));
}

@Test
public void toStringMethod() {
String substring = "testing substring";
StatusStartsWithSubstringPredicate predicate = new StatusStartsWithSubstringPredicate(substring);

String expected = StatusStartsWithSubstringPredicate.class.getCanonicalName()
+ "{substring=" + substring.toUpperCase() + "}";
assertEquals(expected, predicate.toString());
}
}

0 comments on commit 3e6ea34

Please sign in to comment.