This is an automated email from the ASF dual-hosted git repository.
garydgregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-codec.git
The following commit(s) were added to refs/heads/master by this push:
new f13dd50f [CODEC-347] Handle names emptied during Match Rating Approach
cleaning (#448)
f13dd50f is described below
commit f13dd50f566c318283c4138820b15d75c26a0217
Author: Gary Gregory <[email protected]>
AuthorDate: Sun Oct 18 09:35:46 2026 -0400
[CODEC-347] Handle names emptied during Match Rating Approach cleaning
(#448)
Clarify Match Rating Approach comparison contract and tests.
PR #448 correctly fixed CODEC-347, but left the existing Javadoc
claiming
that matching requires identical encodings. The method uses an MRA
similarity threshold and also accepts inputs equal ignoring case after
its initial input checks.
Document these rules, including false results for cleaned-empty names
and the existing shortcut for identical punctuation or whitespace
inputs.
Add tests preserving that shortcut and parameterize the six regression
cases so each failure is reported independently.
---
src/changes/changes.xml | 1 +
.../codec/language/MatchRatingApproachEncoder.java | 19 +++++++-----
.../language/MatchRatingApproachEncoderTest.java | 34 +++++++++++++++-------
3 files changed, 36 insertions(+), 18 deletions(-)
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 1c217375..ce3b232b 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -45,6 +45,7 @@ The <action> type attribute can be add,update,fix,remove.
<body>
<release version="1.23.1" date="YYYY-MM-DD" description="This is a feature
and maintenance release. Java 8 or later is required.">
<!-- FIX -->
+ <action type="fix" dev="ggregory" due-to="Aryan R. Ganjoo, Gary Gregory"
issue="CODEC-347">Handle names emptied during Match Rating Approach cleaning
(#448).</action>
<!-- ADD -->
<!-- UPDATE -->
<action type="update" dev="ggregory" due-to="Gary Gregory">Bump
org.apache.commons:commons-parent from 105 to 106.</action>
diff --git
a/src/main/java/org/apache/commons/codec/language/MatchRatingApproachEncoder.java
b/src/main/java/org/apache/commons/codec/language/MatchRatingApproachEncoder.java
index 664dacf6..d6973cdc 100644
---
a/src/main/java/org/apache/commons/codec/language/MatchRatingApproachEncoder.java
+++
b/src/main/java/org/apache/commons/codec/language/MatchRatingApproachEncoder.java
@@ -208,14 +208,19 @@ public class MatchRatingApproachEncoder implements
StringEncoder {
}
/**
- * Tests if two names are homophonous via Match Rating Approach (MRA)
algorithm. It should be noted that the
- * strings are cleaned in the same way as {@link #encode(String)}.
+ * Tests if two names are homophonous via the Match Rating Approach (MRA)
algorithm.
+ * <p>
+ * The strings are cleaned in the same way as {@link #encode(String)}. A
match is based on the MRA similarity rating and does not require identical
+ * encodings.
+ * </p>
+ * <p>
+ * Returns {@code false} if either input is {@code null}, empty, or a
single character. Otherwise, inputs equal ignoring case return {@code true}
before
+ * cleaning, even if cleaning would remove all characters. For remaining
inputs, returns {@code false} if either name becomes empty after cleaning.
+ * </p>
*
- * @param name1
- * First of the 2 strings (names) to compare.
- * @param name2
- * Second of the 2 names to compare.
- * @return {@code true} if the encodings are identical {@code false}
otherwise.
+ * @param name1 First of the 2 strings (names) to compare.
+ * @param name2 Second of the 2 names to compare.
+ * @return {@code true} if the names are equal ignoring case after the
initial input checks or meet the MRA similarity threshold; {@code false}
otherwise.
*/
public boolean isEncodeEquals(String name1, String name2) {
// Bulletproof for trivial input - NINO
diff --git
a/src/test/java/org/apache/commons/codec/language/MatchRatingApproachEncoderTest.java
b/src/test/java/org/apache/commons/codec/language/MatchRatingApproachEncoderTest.java
index d94bb3c0..632b185f 100644
---
a/src/test/java/org/apache/commons/codec/language/MatchRatingApproachEncoderTest.java
+++
b/src/test/java/org/apache/commons/codec/language/MatchRatingApproachEncoderTest.java
@@ -30,6 +30,7 @@ import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.MethodSource;
+import org.junit.jupiter.params.provider.ValueSource;
/**
* Series of tests for the Match Rating Approach algorithm.
@@ -57,6 +58,16 @@ class MatchRatingApproachEncoderTest extends
AbstractStringEncoderTest<MatchRati
// @formatter:on
}
+ static Stream<Arguments> emptyAfterCleaningComparisonCases() {
+ return Stream.of(
+ Arguments.of("--", "Smith"),
+ Arguments.of("Smith", "--"),
+ Arguments.of(".,-", "Smith"),
+ Arguments.of(" ", "Smith"),
+ Arguments.of("Smith", " "),
+ Arguments.of("--", ".,"));
+ }
+
static Stream<Arguments> encodingCases() {
// @formatter:off
return Stream.of(
@@ -361,6 +372,18 @@ class MatchRatingApproachEncoderTest extends
AbstractStringEncoderTest<MatchRati
assertFalse(getStringEncoder().isEncodeEquals(null, "test"));
}
+ @ParameterizedTest
+ @ValueSource(strings = { "--", " " })
+ final void
testIsEncodeEquals_CornerCase_IdenticalNamesEmptyAfterCleaning_ReturnsTrue(final
String name) {
+ assertTrue(getStringEncoder().isEncodeEquals(name, name));
+ }
+
+ @ParameterizedTest
+ @MethodSource("emptyAfterCleaningComparisonCases")
+ final void
testIsEncodeEquals_CornerCase_NameEmptyAfterCleaning_ReturnsFalse(final String
name1, final String name2) {
+ assertFalse(getStringEncoder().isEncodeEquals(name1, name2));
+ }
+
@Test
final void
testIsEncodeEquals_CornerCase_SecondNameJustSpace_ReturnsFalse() {
assertFalse(getStringEncoder().isEncodeEquals("test", " "));
@@ -381,17 +404,6 @@ class MatchRatingApproachEncoderTest extends
AbstractStringEncoderTest<MatchRati
assertFalse(getStringEncoder().isEncodeEquals("test", "t"));
}
- @Test
- final void
testIsEncodeEquals_CornerCase_NameEmptyAfterCleaning_ReturnsFalse() {
- // Names that become empty after cleanName(String), consistent with
encode(String) returning "".
- assertFalse(getStringEncoder().isEncodeEquals("--", "Smith"));
- assertFalse(getStringEncoder().isEncodeEquals("Smith", "--"));
- assertFalse(getStringEncoder().isEncodeEquals(".,-", "Smith"));
- assertFalse(getStringEncoder().isEncodeEquals(" ", "Smith"));
- assertFalse(getStringEncoder().isEncodeEquals("Smith", " "));
- assertFalse(getStringEncoder().isEncodeEquals("--", ".,"));
- }
-
@Test
final void testIsVowel_CapitalA_ReturnsTrue() {
assertTrue(getStringEncoder().isVowel("A"));