Skip to content

Commit

Permalink
Merge pull request #77 from mhdsyfq/change-find-command
Browse files Browse the repository at this point in the history
Change find command to allow better searches
  • Loading branch information
Silvernitro authored Oct 21, 2020
2 parents c23fe05 + 28416a8 commit 4fc17ec
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 65 deletions.
35 changes: 16 additions & 19 deletions src/main/java/seedu/address/commons/util/StringUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,34 @@

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Arrays;

/**
* Helper functions for handling strings.
*/
public class StringUtil {

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

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 preppedModuleCode = moduleCode.trim().toUpperCase();
String preppedCharSequence = charSequence.trim().toUpperCase();
checkArgument(!preppedCharSequence.isEmpty(), "CharSequence parameter cannot be empty");
checkArgument(preppedCharSequence.split("\\s+").length == 1, "CharSequence parameter should be a "
+ "single word");

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

return Arrays.stream(wordsInPreppedSentence)
.anyMatch(preppedWord::equalsIgnoreCase);
return preppedModuleCode.contains(preppedCharSequence);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/seedu/address/model/module/ModuleCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class ModuleCode {
public ModuleCode(String moduleCode) {
requireNonNull(moduleCode);
checkArgument(isValidModuleCode(moduleCode), MESSAGE_CONSTRAINTS);
this.moduleCode = moduleCode;
this.moduleCode = moduleCode.toUpperCase();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ public ModuleCodeContainsKeywordsPredicate(List<String> keywords) {
@Override
public boolean test(Module module) {
return keywords.stream()
.anyMatch(keyword -> StringUtil.containsWordIgnoreCase(module.getModuleCode().moduleCode, keyword));
.anyMatch(keyword -> StringUtil.containsCharSequenceIgnoreCase(module.getModuleCode().moduleCode,
keyword));
}

@Override
Expand Down
83 changes: 39 additions & 44 deletions src/test/java/seedu/address/commons/util/StringUtilTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,81 +46,76 @@ public void isNonZeroUnsignedInteger() {
}


//---------------- Tests for containsWordIgnoreCase --------------------------------------
//---------------- Tests for containsCharSequenceIgnoreCase --------------------------------------

/*
* Invalid equivalence partitions for word: null, empty, multiple words
* Invalid equivalence partitions for sentence: null
* Invalid equivalence partitions for ModuleCode: null
* The four test cases below test one invalid input at a time.
*/

@Test
public void containsWordIgnoreCase_nullWord_throwsNullPointerException() {
assertThrows(NullPointerException.class, () -> StringUtil.containsWordIgnoreCase("typical sentence", null));
public void containsCharSequenceIgnoreCase_nullWord_throwsNullPointerException() {
assertThrows(NullPointerException.class, () -> StringUtil.containsCharSequenceIgnoreCase(
"typical ModuleCode", null));
}

@Test
public void containsWordIgnoreCase_emptyWord_throwsIllegalArgumentException() {
assertThrows(IllegalArgumentException.class, "Word parameter cannot be empty", ()
-> StringUtil.containsWordIgnoreCase("typical sentence", " "));
public void containsCharSequenceIgnoreCase_emptyWord_throwsIllegalArgumentException() {
assertThrows(IllegalArgumentException.class, "CharSequence parameter cannot be empty", () ->
StringUtil.containsCharSequenceIgnoreCase("typical ModuleCode", " "));
}

@Test
public void containsWordIgnoreCase_multipleWords_throwsIllegalArgumentException() {
assertThrows(IllegalArgumentException.class, "Word parameter should be a single word", ()
-> StringUtil.containsWordIgnoreCase("typical sentence", "aaa BBB"));
public void containsCharSequenceIgnoreCase_multipleWords_throwsIllegalArgumentException() {
assertThrows(IllegalArgumentException.class, "CharSequence parameter should be a single word", () ->
StringUtil.containsCharSequenceIgnoreCase("typical ModuleCode", "aaa BBB"));
}

@Test
public void containsWordIgnoreCase_nullSentence_throwsNullPointerException() {
assertThrows(NullPointerException.class, () -> StringUtil.containsWordIgnoreCase(null, "abc"));
public void containsCharSequenceIgnoreCase_nullModuleCode_throwsNullPointerException() {
assertThrows(NullPointerException.class, () -> StringUtil.containsCharSequenceIgnoreCase(null, "abc"));
}

/*
* Valid equivalence partitions for word:
* - any word
* - word containing symbols/numbers
* - word with leading/trailing spaces
* Valid equivalence partitions for CharSequence:
* - any charSequence
* - charSequence containing symbols/numbers
* - charSequence with leading/trailing spaces
*
* Valid equivalence partitions for sentence:
* - empty string
* - one word
* - multiple words
* - sentence with extra spaces
* Valid equivalence partitions for ModuleCode:
* - one moduleCode
* - ModuleCode with extra spaces
*
* Possible scenarios returning true:
* - matches first word in sentence
* - last word in sentence
* - middle word in sentence
* - matches multiple words
* - charSequence matches any part of moduleCode
*
* Possible scenarios returning false:
* - query word matches part of a sentence word
* - sentence word matches part of the query word
* - ModuleCode does not contain charSequence
*
* The test method below tries to verify all above with a reasonably low number of test cases.
*/

@Test
public void containsWordIgnoreCase_validInputs_correctResult() {
public void containsCharSequenceIgnoreCase_validInputs_correctResult() {

// Empty sentence
assertFalse(StringUtil.containsWordIgnoreCase("", "abc")); // Boundary case
assertFalse(StringUtil.containsWordIgnoreCase(" ", "123"));
// Empty ModuleCode
assertFalse(StringUtil.containsCharSequenceIgnoreCase("", "abc")); // Boundary case
assertFalse(StringUtil.containsCharSequenceIgnoreCase(" ", "123"));

// Matches a partial word only
assertFalse(StringUtil.containsWordIgnoreCase("aaa bbb ccc", "bb")); // Sentence word bigger than query word
assertFalse(StringUtil.containsWordIgnoreCase("aaa bbb ccc", "bbbb")); // Query word bigger than sentence word

// Matches word in the sentence, different upper/lower case letters
assertTrue(StringUtil.containsWordIgnoreCase("aaa bBb ccc", "Bbb")); // First word (boundary case)
assertTrue(StringUtil.containsWordIgnoreCase("aaa bBb ccc@1", "CCc@1")); // Last word (boundary case)
assertTrue(StringUtil.containsWordIgnoreCase(" AAA bBb ccc ", "aaa")); // Sentence has extra spaces
assertTrue(StringUtil.containsWordIgnoreCase("Aaa", "aaa")); // Only one word in sentence (boundary case)
assertTrue(StringUtil.containsWordIgnoreCase("aaa bbb ccc", " ccc ")); // Leading/trailing spaces

// Matches multiple words in sentence
assertTrue(StringUtil.containsWordIgnoreCase("AAA bBb ccc bbb", "bbB"));
assertTrue(StringUtil.containsCharSequenceIgnoreCase("bbb", "bb")); // ModuleCode word
// bigger than CharSequence
assertFalse(StringUtil.containsCharSequenceIgnoreCase("bbb", "bbbb")); // CharSequence bigger
// than ModuleCode word

// Matches word in the ModuleCode, different upper/lower case letters
assertTrue(StringUtil.containsCharSequenceIgnoreCase("bBb", "Bbb")); // Different upper/lower case
assertTrue(StringUtil.containsCharSequenceIgnoreCase("ccc@1", "CCc@1")); // With symbols/numbers
assertTrue(StringUtil.containsCharSequenceIgnoreCase(" AAA ", "aaa")); // ModuleCode has extra
// spaces
assertTrue(StringUtil.containsCharSequenceIgnoreCase("ccc", " ccc ")); // CharSequence has extra
// spaces
}

//---------------- Tests for getDetails --------------------------------------
Expand All @@ -132,7 +127,7 @@ public void containsWordIgnoreCase_validInputs_correctResult() {
@Test
public void getDetails_exceptionGiven() {
assertTrue(StringUtil.getDetails(new FileNotFoundException("file not found"))
.contains("java.io.FileNotFoundException: file not found"));
.contains("java.io.FileNotFoundException: file not found"));
}

@Test
Expand Down

0 comments on commit 4fc17ec

Please sign in to comment.