From 1725345f295cd28943356a996617ab94f8858c74 Mon Sep 17 00:00:00 2001 From: "Bruno P. Kinoshita" Date: Wed, 8 Jul 2020 21:17:13 +1200 Subject: [PATCH 1/8] Create a builder allowing different salutations, postnominals, suffixes, and prefixes --- .../HumanNameParserBuilder.java | 216 ++++++++++++++++++ .../HumanNameParserParser.java | 128 +++++------ .../human_name_parser/ParserTest.java | 3 +- 3 files changed, 269 insertions(+), 78 deletions(-) create mode 100644 src/main/java/com/tupilabs/human_name_parser/HumanNameParserBuilder.java diff --git a/src/main/java/com/tupilabs/human_name_parser/HumanNameParserBuilder.java b/src/main/java/com/tupilabs/human_name_parser/HumanNameParserBuilder.java new file mode 100644 index 0000000..0a1ceec --- /dev/null +++ b/src/main/java/com/tupilabs/human_name_parser/HumanNameParserBuilder.java @@ -0,0 +1,216 @@ +/* + * The MIT License + * + * Copyright (c) 2010-2020 Jason Priem, Bruno P. Kinoshita + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.tupilabs.human_name_parser; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +/** + * @since 0.2 + */ +public final class HumanNameParserBuilder { + + // constants with default values + public static final List DEFAULT_SALUTATIONS = Collections.unmodifiableList( + Arrays.asList( + "mr", + "master", + "mister", + "mrs", + "miss", + "ms", + "dr", + "prof", + "rev", + "fr", + "judge", + "honorable", + "hon")); + public static final List DEFAULT_POSTNOMINALS = Collections.unmodifiableList( + Arrays.asList( + "phd", + "ph.d.", + "ph.d", + "esq", + "esquire", + "apr", + "rph", + "pe", + "md", + "ma", + "dmd", + "cme", + "dds", + "cpa", + "dvm")); + public static final List DEFAULT_PREFIXES = Collections.unmodifiableList( + Arrays.asList( + "bar", + "ben", + "bin", + "da", + "dal", + "de la", + "de", + "del", + "der", + "di", + "ibn", + "la", + "le", + "san", + "st", + "ste", + "van", + "van der", + "van den", + "vel", + "von")); + public static final List DEFAULT_SUFFIXES = Collections.unmodifiableList( + Arrays.asList( + "jr", + "sr", + "2", + "ii", + "iii", + "iv", + "v", + "senior", + "junior")); + + // build values + private Name name; + private List salutations; + private List postnominals; + private List prefixes; + private List suffixes; + + /** + * Create the parser builder for a name. + * @param name the name + */ + public HumanNameParserBuilder(String name) { + super(); + Objects.requireNonNull(name); + this.name = new Name(name); + } + + /** + * Create the parser builder for a name. + * @param name the name + */ + public HumanNameParserBuilder(Name name) { + super(); + Objects.requireNonNull(name); + this.name = name; + } + + /** + * Build the parser. + * @return a {@code HumanNameParserParser} + */ + public HumanNameParserParser build() { + if (this.salutations == null) { + this.salutations = DEFAULT_SALUTATIONS; + } + if (this.postnominals == null) { + this.postnominals = DEFAULT_POSTNOMINALS; + } + if (this.prefixes == null) { + this.prefixes = DEFAULT_PREFIXES; + } + if (this.suffixes == null) { + this.suffixes = DEFAULT_SUFFIXES; + } + return new HumanNameParserParser( + name, + salutations, + postnominals, + prefixes, + suffixes + ); + } + + // salutations + + public HumanNameParserBuilder withSalutations(List salutations) { + Objects.requireNonNull(salutations); + this.salutations = salutations; + return this; + } + + public HumanNameParserBuilder withExtraSalutations(List salutations) { + Objects.requireNonNull(salutations); + this.salutations = DEFAULT_SALUTATIONS; + this.salutations.addAll(salutations); + return this; + } + + // postnominals + + public HumanNameParserBuilder withPostnominals(List postnominals) { + Objects.requireNonNull(postnominals); + this.postnominals = postnominals; + return this; + } + + public HumanNameParserBuilder withExtraPostnominals(List postnominals) { + Objects.requireNonNull(postnominals); + this.postnominals = DEFAULT_POSTNOMINALS; + this.postnominals.addAll(postnominals); + return this; + } + + // prefixes + + public HumanNameParserBuilder withPrefixes(List prefixes) { + Objects.requireNonNull(prefixes); + this.prefixes = prefixes; + return this; + } + + public HumanNameParserBuilder withExtraPrefixes(List prefixes) { + Objects.requireNonNull(prefixes); + this.prefixes = DEFAULT_PREFIXES; + this.prefixes.addAll(prefixes); + return this; + } + + // suffixes + + public HumanNameParserBuilder withSuffixes(List suffixes) { + Objects.requireNonNull(suffixes); + this.suffixes = suffixes; + return this; + } + + public HumanNameParserBuilder withExtraSuffixes(List suffixes) { + Objects.requireNonNull(suffixes); + this.suffixes = DEFAULT_SUFFIXES; + this.suffixes.addAll(suffixes); + return this; + } +} diff --git a/src/main/java/com/tupilabs/human_name_parser/HumanNameParserParser.java b/src/main/java/com/tupilabs/human_name_parser/HumanNameParserParser.java index 4a041d6..321943f 100644 --- a/src/main/java/com/tupilabs/human_name_parser/HumanNameParserParser.java +++ b/src/main/java/com/tupilabs/human_name_parser/HumanNameParserParser.java @@ -23,25 +23,41 @@ */ package com.tupilabs.human_name_parser; -import java.util.Arrays; import java.util.List; import org.apache.commons.lang.StringUtils; /** - *

A parser capable of parsing name parts out of a single string.

+ *

+ * A parser capable of parsing name parts out of a single string. + *

* - *

The code works by basically applying several Regexes in a certain order - * and removing (chopping) tokens off the original string. The parser consumes - * the tokens during its creation.

+ *

+ * The code works by basically applying several Regexes in a certain order and + * removing (chopping) tokens off the original string. The parser consumes the + * tokens during its creation. + *

* - *

This class is not thread-safe.

+ *

+ * This class is not thread-safe. + *

* * @since 0.1 */ public class HumanNameParserParser { + /** + * The input name object. + */ private final Name name; + + // other helpful values + private List salutations; + private List postnominals; + private List prefixes; + private List suffixes; + + // parsed values private String leadingInit; private String first; private String nicknames; @@ -50,61 +66,30 @@ public class HumanNameParserParser { private String suffix; private String salutation; private String postnominal; - - private final List suffixes; - private final List salutations; - private final List prefixes; - private final List postnominals; - - /** - * Creates a parser given a string name. - * - * @param name string name - */ - public HumanNameParserParser(String name) { - this(new Name(name)); - } - - /** - * Creates a parser given a {@code Name} object. - * - * @param name {@code Name} - */ - public HumanNameParserParser(Name name) { + + HumanNameParserParser(final Name name, + List salutations, + List postnominals, + List prefixes, + List suffixes) { this.name = name; - - this.leadingInit = ""; - this.first = ""; - this.nicknames = ""; - this.middle = ""; - this.last = ""; - this.suffix = ""; - this.salutation = ""; - this.postnominal = ""; - - this.salutations = Arrays.asList("mr", "master", "mister", - "mrs", "miss", "ms", "dr", "prof", "rev", "fr", "judge", "honorable", "hon"); - this.suffixes = Arrays.asList("jr", "sr", "2", "ii", - "iii", "iv", "v", "senior", "junior"); - this.postnominals = Arrays.asList("phd", "ph.d.", "ph.d", - "esq", "esquire", "apr", "rph", "pe", "md", "ma", "dmd", "cme", - "dds", "cpa", "dvm"); - this.prefixes = Arrays.asList("bar", "ben", "bin", "da", "dal", - "de la", "de", "del", "der", "di", "ibn", "la", "le", - "san", "st", "ste", "van", "van der", "van den", "vel", - "von"); - - this.parse(); + this.salutations = salutations; + this.postnominals = postnominals; + this.prefixes = prefixes; + this.suffixes = suffixes; } /** * Gets the {@code Name} object. + * * @return the {@code Name} object */ public Name getName() { return name; } + // getters for parsed values + public String getLeadingInit() { return leadingInit; } @@ -137,42 +122,31 @@ public String getSalutation() { return salutation; } - public List getSuffixes() { - return suffixes; - } - - public List getPostnominals() { - return postnominals; - } - - public List getSalutations() { - return salutations; - } - - public List getPrefixes() { - return prefixes; - } - /** * Consumes the string and creates the name parts. * - * @throws ParseException if the parser fails to retrieve the name parts + * @throws ParseException + * if the parser fails to retrieve the name parts */ - private void parse() throws ParseException { + void parse() throws ParseException { String suffixes = StringUtils.join(this.suffixes, "\\.*|") + "\\.*"; String postnominals = StringUtils.join(this.postnominals, "\\.*|") + "\\.*"; String salutations = StringUtils.join(this.salutations, "\\.*|") + "\\.*"; String prefixes = StringUtils.join(this.prefixes, " |") + " "; - // The regex use is a bit tricky. *Everything* matched by the regex will be replaced, + // The regex use is a bit tricky. *Everything* matched by the regex will be + // replaced, // but you can select a particular parenthesized submatch to be returned. - // Also, note that each regex requires that the preceding ones have been run, and matches chopped out. - String nicknamesRegex = "(?i) ('|\\\"|\\(\\\"*'*)(.+?)('|\\\"|\\\"*'*\\)) "; // names that starts or end w/ an apostrophe break this - String suffixRegex = "(?i)[,| ]+(("+suffixes+")$)"; - String postnominalRegex = "(?i)[,| ]+(("+postnominals+")$)"; - String lastRegex = "(?i)(?!^)\\b([^ ]+ y |"+prefixes+")*[^ ]+$"; - String leadingInitRegex = "(?i)(^(.\\.*)(?= \\p{L}{2}))"; // note the lookahead, which isn't returned or replaced - String salutationsRegex = "(?i)^("+salutations+"\\b)(\\.|\\s)+"; //salutation plus a word boundary \b + // Also, note that each regex requires that the preceding ones have been run, + // and matches chopped out. + String nicknamesRegex = "(?i) ('|\\\"|\\(\\\"*'*)(.+?)('|\\\"|\\\"*'*\\)) "; // names that starts or end w/ an + // apostrophe break this + String suffixRegex = "(?i)[,| ]+((" + suffixes + ")$)"; + String postnominalRegex = "(?i)[,| ]+((" + postnominals + ")$)"; + String lastRegex = "(?i)(?!^)\\b([^ ]+ y |" + prefixes + ")*[^ ]+$"; + String leadingInitRegex = "(?i)(^(.\\.*)(?= \\p{L}{2}))"; // note the lookahead, which isn't returned or + // replaced + String salutationsRegex = "(?i)^(" + salutations + "\\b)(\\.|\\s)+"; // salutation plus a word boundary \b String firstRegex = "(?i)^([^ ]+)"; // get nickname, if there is one @@ -190,7 +164,7 @@ private void parse() throws ParseException { // get the last name this.last = this.name.chopWithRegex(lastRegex, 0); if (StringUtils.isBlank(this.last)) { - throw new ParseException("Couldn't find a last name in '{" + this.name.getStr() + "}'."); + throw new ParseException("Couldn't find a last name in '{" + this.name.getStr() + "}'."); } // get salutation, if there is one diff --git a/src/test/java/com/tupilabs/human_name_parser/ParserTest.java b/src/test/java/com/tupilabs/human_name_parser/ParserTest.java index 8e10c1c..0fed4d7 100644 --- a/src/test/java/com/tupilabs/human_name_parser/ParserTest.java +++ b/src/test/java/com/tupilabs/human_name_parser/ParserTest.java @@ -86,7 +86,8 @@ private void validateLine(String[] tokens) { String salutation = tokens[7].trim(); String postnominal = tokens[8].trim(); - HumanNameParserParser parser = new HumanNameParserParser(name); + HumanNameParserBuilder builder = new HumanNameParserBuilder(name); + HumanNameParserParser parser = builder.build(); assertEquals(leadingInit, parser.getLeadingInit()); assertEquals(first, parser.getFirst()); From c97a23fd8f62fa3cfee0d52421fd71a249b58c22 Mon Sep 17 00:00:00 2001 From: "Bruno P. Kinoshita" Date: Wed, 8 Jul 2020 21:35:25 +1200 Subject: [PATCH 2/8] Add changelog for #10 --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 46c37a2..a80f29c 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,13 @@ String nicknames = parser.getNicknames(); ## Changelog +### 0.2 (2020-07-??) + +- [#10](https://github.com/tupilabs/HumanNameParser.java/issues/10) support custom +postnominals. We have added a builder to create a parser. It uses the same default +values as before for suffixes, postnominals, prefixes, and salutations. But now +users can tell the builder to replace or append values to these lists. + ### 0.1 (2020-04-06) Initial release to Maven Central From 337442c18b8fad8100bb3fded8bd267232d27c1d Mon Sep 17 00:00:00 2001 From: "Bruno P. Kinoshita" Date: Wed, 8 Jul 2020 21:45:27 +1200 Subject: [PATCH 3/8] Fix character issues --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a80f29c..d2bede7 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ and parses out the: ``` ``` -Name object = new Name("Sérgio Vieira de Mello"); +Name object = new Name("Sérgio Vieira de Mello"); HumanNameParserParser parser = new HumanNameParserParser(object); String firstName = parser.getFirst(); String nicknames = parser.getNicknames(); From d4ba7c245e00b5b44597d788b8f951c16d271a5e Mon Sep 17 00:00:00 2001 From: "Bruno P. Kinoshita" Date: Wed, 8 Jul 2020 21:45:45 +1200 Subject: [PATCH 4/8] Add more javadocs --- .../com/tupilabs/human_name_parser/HumanNameParserBuilder.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/tupilabs/human_name_parser/HumanNameParserBuilder.java b/src/main/java/com/tupilabs/human_name_parser/HumanNameParserBuilder.java index 0a1ceec..5bd93b7 100644 --- a/src/main/java/com/tupilabs/human_name_parser/HumanNameParserBuilder.java +++ b/src/main/java/com/tupilabs/human_name_parser/HumanNameParserBuilder.java @@ -29,7 +29,9 @@ import java.util.Objects; /** + * A builder to construct {@code HumanNameParserParser}. * @since 0.2 + * @see HumanNameParserParser */ public final class HumanNameParserBuilder { From 7fa5301543a48e656a2f2bdf7cafb4346b5b43b4 Mon Sep 17 00:00:00 2001 From: "Bruno P. Kinoshita" Date: Wed, 8 Jul 2020 22:25:48 +1200 Subject: [PATCH 5/8] #10 add unit tests, and (as it was expected) fix issues found whilst writing them --- .../HumanNameParserBuilder.java | 21 +- .../HumanNameParserParser.java | 8 +- .../human_name_parser/BuilderTest.java | 200 ++++++++++++++++++ 3 files changed, 216 insertions(+), 13 deletions(-) create mode 100644 src/test/java/com/tupilabs/human_name_parser/BuilderTest.java diff --git a/src/main/java/com/tupilabs/human_name_parser/HumanNameParserBuilder.java b/src/main/java/com/tupilabs/human_name_parser/HumanNameParserBuilder.java index 5bd93b7..7d34113 100644 --- a/src/main/java/com/tupilabs/human_name_parser/HumanNameParserBuilder.java +++ b/src/main/java/com/tupilabs/human_name_parser/HumanNameParserBuilder.java @@ -23,6 +23,7 @@ */ package com.tupilabs.human_name_parser; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -147,13 +148,15 @@ public HumanNameParserParser build() { if (this.suffixes == null) { this.suffixes = DEFAULT_SUFFIXES; } - return new HumanNameParserParser( + final HumanNameParserParser parser = new HumanNameParserParser( name, salutations, postnominals, prefixes, suffixes ); + parser.parse(); + return parser; } // salutations @@ -166,8 +169,8 @@ public HumanNameParserBuilder withSalutations(List salutations) { public HumanNameParserBuilder withExtraSalutations(List salutations) { Objects.requireNonNull(salutations); - this.salutations = DEFAULT_SALUTATIONS; - this.salutations.addAll(salutations); + this.salutations = new ArrayList<>(salutations); + this.salutations.addAll(DEFAULT_SALUTATIONS); return this; } @@ -181,8 +184,8 @@ public HumanNameParserBuilder withPostnominals(List postnominals) { public HumanNameParserBuilder withExtraPostnominals(List postnominals) { Objects.requireNonNull(postnominals); - this.postnominals = DEFAULT_POSTNOMINALS; - this.postnominals.addAll(postnominals); + this.postnominals = new ArrayList<>(postnominals); + this.postnominals.addAll(DEFAULT_POSTNOMINALS); return this; } @@ -196,8 +199,8 @@ public HumanNameParserBuilder withPrefixes(List prefixes) { public HumanNameParserBuilder withExtraPrefixes(List prefixes) { Objects.requireNonNull(prefixes); - this.prefixes = DEFAULT_PREFIXES; - this.prefixes.addAll(prefixes); + this.prefixes = new ArrayList<>(prefixes); + this.prefixes.addAll(DEFAULT_PREFIXES); return this; } @@ -211,8 +214,8 @@ public HumanNameParserBuilder withSuffixes(List suffixes) { public HumanNameParserBuilder withExtraSuffixes(List suffixes) { Objects.requireNonNull(suffixes); - this.suffixes = DEFAULT_SUFFIXES; - this.suffixes.addAll(suffixes); + this.suffixes = new ArrayList<>(suffixes); + this.suffixes.addAll(DEFAULT_SUFFIXES); return this; } } diff --git a/src/main/java/com/tupilabs/human_name_parser/HumanNameParserParser.java b/src/main/java/com/tupilabs/human_name_parser/HumanNameParserParser.java index 321943f..e358e1c 100644 --- a/src/main/java/com/tupilabs/human_name_parser/HumanNameParserParser.java +++ b/src/main/java/com/tupilabs/human_name_parser/HumanNameParserParser.java @@ -52,10 +52,10 @@ public class HumanNameParserParser { private final Name name; // other helpful values - private List salutations; - private List postnominals; - private List prefixes; - private List suffixes; + List salutations; + List postnominals; + List prefixes; + List suffixes; // parsed values private String leadingInit; diff --git a/src/test/java/com/tupilabs/human_name_parser/BuilderTest.java b/src/test/java/com/tupilabs/human_name_parser/BuilderTest.java new file mode 100644 index 0000000..ca13480 --- /dev/null +++ b/src/test/java/com/tupilabs/human_name_parser/BuilderTest.java @@ -0,0 +1,200 @@ +/* + * The MIT License + * + * Copyright (c) 2010-2020 Jason Priem, Bruno P. Kinoshita + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.tupilabs.human_name_parser; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; + +import org.junit.Test; + +/** + * Tests for the {@code HumanNameParserBuilder}. + * @author kinow + * + */ +public class BuilderTest { + + // suffixes + + @Test + public void testDefaultSuffixes() { + HumanNameParserBuilder builder = new HumanNameParserBuilder("john"); + HumanNameParserParser parser = builder.build(); + assertTrue(parser.suffixes.contains("senior")); + assertFalse(parser.suffixes.contains("mage")); + } + + @Test + public void testReplacingSuffixes() { + HumanNameParserBuilder builder = new HumanNameParserBuilder("john"); + HumanNameParserParser parser = builder.withSuffixes(Arrays.asList("mage")).build(); + assertFalse(parser.suffixes.contains("senior")); + assertTrue(parser.suffixes.contains("mage")); + } + + @Test + public void testExtraSuffixes() { + HumanNameParserBuilder builder = new HumanNameParserBuilder("john"); + HumanNameParserParser parser = builder.withExtraSuffixes(Arrays.asList("mage")).build(); + assertTrue(parser.suffixes.contains("senior")); + assertTrue(parser.suffixes.contains("mage")); + } + + // prefixes + + @Test + public void testDefaultPrefixes() { + HumanNameParserBuilder builder = new HumanNameParserBuilder("john"); + HumanNameParserParser parser = builder.build(); + assertTrue(parser.prefixes.contains("de la")); + } + + @Test + public void testReplacingPrefixes() { + HumanNameParserBuilder builder = new HumanNameParserBuilder("john"); + HumanNameParserParser parser = builder.withPrefixes(Arrays.asList("sama")).build(); + assertFalse(parser.prefixes.contains("de la")); + assertTrue(parser.prefixes.contains("sama")); + } + + @Test + public void testExtraPrefixes() { + HumanNameParserBuilder builder = new HumanNameParserBuilder("john"); + HumanNameParserParser parser = builder.withExtraPrefixes(Arrays.asList("sama")).build(); + assertTrue(parser.prefixes.contains("de la")); + assertTrue(parser.prefixes.contains("sama")); + } + + // postnominals + + @Test + public void testDefaultPostnominals() { + HumanNameParserBuilder builder = new HumanNameParserBuilder("john"); + HumanNameParserParser parser = builder.build(); + assertTrue(parser.postnominals.contains("phd")); + } + + @Test + public void testReplacingPostnominals() { + HumanNameParserBuilder builder = new HumanNameParserBuilder("john"); + // Au.D. is one of the examples from issue #10 on GitHub + HumanNameParserParser parser = builder.withPostnominals(Arrays.asList("Au.D.")).build(); + assertFalse(parser.postnominals.contains("phd")); + assertTrue(parser.postnominals.contains("Au.D.")); + } + + @Test + public void testExtraPostnominals() { + HumanNameParserBuilder builder = new HumanNameParserBuilder("john"); + HumanNameParserParser parser = builder.withExtraPostnominals(Arrays.asList("Au.D.")).build(); + assertTrue(parser.postnominals.contains("phd")); + assertTrue(parser.postnominals.contains("Au.D.")); + } + + // salutations + + @Test + public void testDefaultSalutations() { + HumanNameParserBuilder builder = new HumanNameParserBuilder("john"); + HumanNameParserParser parser = builder.build(); + assertTrue(parser.salutations.contains("judge")); + } + + @Test + public void testReplacingSalutations() { + HumanNameParserBuilder builder = new HumanNameParserBuilder("john"); + HumanNameParserParser parser = builder.withSalutations(Arrays.asList("sinho")).build(); + assertFalse(parser.salutations.contains("judge")); + assertTrue(parser.salutations.contains("sinho")); + } + + @Test + public void testExtraSalutations() { + HumanNameParserBuilder builder = new HumanNameParserBuilder("john"); + HumanNameParserParser parser = builder.withExtraSalutations(Arrays.asList("sinho")).build(); + assertTrue(parser.salutations.contains("judge")); + assertTrue(parser.salutations.contains("sinho")); + } + + // validations + + @Test(expected = NullPointerException.class) + public void testConstructorFailsWithNullString() { + new HumanNameParserBuilder((String) null); + } + + @Test(expected = NullPointerException.class) + public void testConstructorFailsWithNullName() { + new HumanNameParserBuilder((Name) null); + } + + @Test(expected = NullPointerException.class) + public void testFailsToBuildWithNullSalutations1() { + new HumanNameParserBuilder("john").withSalutations(null).build(); + } + + @Test(expected = NullPointerException.class) + public void testFailsToBuildWithNullSalutations2() { + new HumanNameParserBuilder("john").withExtraSalutations(null).build(); + } + + @Test(expected = NullPointerException.class) + public void testFailsToBuildWithNullPostnominals1() { + new HumanNameParserBuilder("john").withPostnominals(null).build(); + } + + @Test(expected = NullPointerException.class) + public void testFailsToBuildWithNullPostnominals2() { + new HumanNameParserBuilder("john").withExtraPostnominals(null).build(); + } + + @Test(expected = NullPointerException.class) + public void testFailsToBuildWithNullSuffixes1() { + new HumanNameParserBuilder("john").withSuffixes(null).build(); + } + + @Test(expected = NullPointerException.class) + public void testFailsToBuildWithNullSuffixes2() { + new HumanNameParserBuilder("john").withExtraSuffixes(null).build(); + } + + @Test(expected = NullPointerException.class) + public void testFailsToBuildWithNullPrefixes1() { + new HumanNameParserBuilder("john").withPrefixes(null).build(); + } + + @Test(expected = NullPointerException.class) + public void testFailsToBuildWithNullPrefixes2() { + new HumanNameParserBuilder("john").withExtraPrefixes(null).build(); + } + + @Test + public void testCreateWithStringOrName() { + assertEquals("ramon", new HumanNameParserBuilder("don ramon valdez").withSalutations(Arrays.asList("don")).build().getFirst()); + assertEquals("ramon", new HumanNameParserBuilder(new Name("don ramon valdez")).withSalutations(Arrays.asList("don")).build().getFirst()); + } +} From dc1db6569fbe13904f072c595de1adcba23e6af7 Mon Sep 17 00:00:00 2001 From: "Bruno P. Kinoshita" Date: Wed, 8 Jul 2020 22:34:25 +1200 Subject: [PATCH 6/8] Include a surname in tests --- .../human_name_parser/BuilderTest.java | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/test/java/com/tupilabs/human_name_parser/BuilderTest.java b/src/test/java/com/tupilabs/human_name_parser/BuilderTest.java index ca13480..cd393ef 100644 --- a/src/test/java/com/tupilabs/human_name_parser/BuilderTest.java +++ b/src/test/java/com/tupilabs/human_name_parser/BuilderTest.java @@ -42,7 +42,7 @@ public class BuilderTest { @Test public void testDefaultSuffixes() { - HumanNameParserBuilder builder = new HumanNameParserBuilder("john"); + HumanNameParserBuilder builder = new HumanNameParserBuilder("john paul"); HumanNameParserParser parser = builder.build(); assertTrue(parser.suffixes.contains("senior")); assertFalse(parser.suffixes.contains("mage")); @@ -50,7 +50,7 @@ public void testDefaultSuffixes() { @Test public void testReplacingSuffixes() { - HumanNameParserBuilder builder = new HumanNameParserBuilder("john"); + HumanNameParserBuilder builder = new HumanNameParserBuilder("john paul"); HumanNameParserParser parser = builder.withSuffixes(Arrays.asList("mage")).build(); assertFalse(parser.suffixes.contains("senior")); assertTrue(parser.suffixes.contains("mage")); @@ -58,7 +58,7 @@ public void testReplacingSuffixes() { @Test public void testExtraSuffixes() { - HumanNameParserBuilder builder = new HumanNameParserBuilder("john"); + HumanNameParserBuilder builder = new HumanNameParserBuilder("john paul"); HumanNameParserParser parser = builder.withExtraSuffixes(Arrays.asList("mage")).build(); assertTrue(parser.suffixes.contains("senior")); assertTrue(parser.suffixes.contains("mage")); @@ -68,14 +68,14 @@ public void testExtraSuffixes() { @Test public void testDefaultPrefixes() { - HumanNameParserBuilder builder = new HumanNameParserBuilder("john"); + HumanNameParserBuilder builder = new HumanNameParserBuilder("john paul"); HumanNameParserParser parser = builder.build(); assertTrue(parser.prefixes.contains("de la")); } @Test public void testReplacingPrefixes() { - HumanNameParserBuilder builder = new HumanNameParserBuilder("john"); + HumanNameParserBuilder builder = new HumanNameParserBuilder("john paul"); HumanNameParserParser parser = builder.withPrefixes(Arrays.asList("sama")).build(); assertFalse(parser.prefixes.contains("de la")); assertTrue(parser.prefixes.contains("sama")); @@ -83,7 +83,7 @@ public void testReplacingPrefixes() { @Test public void testExtraPrefixes() { - HumanNameParserBuilder builder = new HumanNameParserBuilder("john"); + HumanNameParserBuilder builder = new HumanNameParserBuilder("john paul"); HumanNameParserParser parser = builder.withExtraPrefixes(Arrays.asList("sama")).build(); assertTrue(parser.prefixes.contains("de la")); assertTrue(parser.prefixes.contains("sama")); @@ -93,14 +93,14 @@ public void testExtraPrefixes() { @Test public void testDefaultPostnominals() { - HumanNameParserBuilder builder = new HumanNameParserBuilder("john"); + HumanNameParserBuilder builder = new HumanNameParserBuilder("john paul"); HumanNameParserParser parser = builder.build(); assertTrue(parser.postnominals.contains("phd")); } @Test public void testReplacingPostnominals() { - HumanNameParserBuilder builder = new HumanNameParserBuilder("john"); + HumanNameParserBuilder builder = new HumanNameParserBuilder("john paul"); // Au.D. is one of the examples from issue #10 on GitHub HumanNameParserParser parser = builder.withPostnominals(Arrays.asList("Au.D.")).build(); assertFalse(parser.postnominals.contains("phd")); @@ -109,7 +109,7 @@ public void testReplacingPostnominals() { @Test public void testExtraPostnominals() { - HumanNameParserBuilder builder = new HumanNameParserBuilder("john"); + HumanNameParserBuilder builder = new HumanNameParserBuilder("john paul"); HumanNameParserParser parser = builder.withExtraPostnominals(Arrays.asList("Au.D.")).build(); assertTrue(parser.postnominals.contains("phd")); assertTrue(parser.postnominals.contains("Au.D.")); @@ -119,14 +119,14 @@ public void testExtraPostnominals() { @Test public void testDefaultSalutations() { - HumanNameParserBuilder builder = new HumanNameParserBuilder("john"); + HumanNameParserBuilder builder = new HumanNameParserBuilder("john paul"); HumanNameParserParser parser = builder.build(); assertTrue(parser.salutations.contains("judge")); } @Test public void testReplacingSalutations() { - HumanNameParserBuilder builder = new HumanNameParserBuilder("john"); + HumanNameParserBuilder builder = new HumanNameParserBuilder("john paul"); HumanNameParserParser parser = builder.withSalutations(Arrays.asList("sinho")).build(); assertFalse(parser.salutations.contains("judge")); assertTrue(parser.salutations.contains("sinho")); @@ -134,7 +134,7 @@ public void testReplacingSalutations() { @Test public void testExtraSalutations() { - HumanNameParserBuilder builder = new HumanNameParserBuilder("john"); + HumanNameParserBuilder builder = new HumanNameParserBuilder("john paul"); HumanNameParserParser parser = builder.withExtraSalutations(Arrays.asList("sinho")).build(); assertTrue(parser.salutations.contains("judge")); assertTrue(parser.salutations.contains("sinho")); @@ -154,42 +154,42 @@ public void testConstructorFailsWithNullName() { @Test(expected = NullPointerException.class) public void testFailsToBuildWithNullSalutations1() { - new HumanNameParserBuilder("john").withSalutations(null).build(); + new HumanNameParserBuilder("john paul").withSalutations(null).build(); } @Test(expected = NullPointerException.class) public void testFailsToBuildWithNullSalutations2() { - new HumanNameParserBuilder("john").withExtraSalutations(null).build(); + new HumanNameParserBuilder("john paul").withExtraSalutations(null).build(); } @Test(expected = NullPointerException.class) public void testFailsToBuildWithNullPostnominals1() { - new HumanNameParserBuilder("john").withPostnominals(null).build(); + new HumanNameParserBuilder("john paul").withPostnominals(null).build(); } @Test(expected = NullPointerException.class) public void testFailsToBuildWithNullPostnominals2() { - new HumanNameParserBuilder("john").withExtraPostnominals(null).build(); + new HumanNameParserBuilder("john paul").withExtraPostnominals(null).build(); } @Test(expected = NullPointerException.class) public void testFailsToBuildWithNullSuffixes1() { - new HumanNameParserBuilder("john").withSuffixes(null).build(); + new HumanNameParserBuilder("john paul").withSuffixes(null).build(); } @Test(expected = NullPointerException.class) public void testFailsToBuildWithNullSuffixes2() { - new HumanNameParserBuilder("john").withExtraSuffixes(null).build(); + new HumanNameParserBuilder("john paul").withExtraSuffixes(null).build(); } @Test(expected = NullPointerException.class) public void testFailsToBuildWithNullPrefixes1() { - new HumanNameParserBuilder("john").withPrefixes(null).build(); + new HumanNameParserBuilder("john paul").withPrefixes(null).build(); } @Test(expected = NullPointerException.class) public void testFailsToBuildWithNullPrefixes2() { - new HumanNameParserBuilder("john").withExtraPrefixes(null).build(); + new HumanNameParserBuilder("john paul").withExtraPrefixes(null).build(); } @Test From 84bb4ac429e6b463932fa77b7f635d1855d4dda2 Mon Sep 17 00:00:00 2001 From: "Bruno P. Kinoshita" Date: Wed, 8 Jul 2020 23:07:51 +1200 Subject: [PATCH 7/8] Update readme usage example --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d2bede7..882092b 100644 --- a/README.md +++ b/README.md @@ -43,8 +43,9 @@ and parses out the: ``` ``` -Name object = new Name("Sérgio Vieira de Mello"); -HumanNameParserParser parser = new HumanNameParserParser(object); +Name name = new Name("Sérgio Vieira de Mello"); +HumanNameParserBuilder builder = new HumanNameParserBuilder(name); +HumanNameParserParser parser = builder.build(); String firstName = parser.getFirst(); String nicknames = parser.getNicknames(); // ... From 24f5c807e891cc6fb57ac2761efe9c95833248b7 Mon Sep 17 00:00:00 2001 From: "Bruno P. Kinoshita" Date: Wed, 8 Jul 2020 22:55:09 +1200 Subject: [PATCH 8/8] Update GH action --- .github/workflows/main.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 444d96a..ff5f8ee 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -15,9 +15,10 @@ jobs: with: java-version: '8' - name: Analyze with SonarCloud - run: mvn -B verify sonar:sonar -Dsonar.projectKey=tupilabs_HumanNameParser.java -Dsonar.organization=tupilabs -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN + run: | + if ["$SONAR_TOKEN" != ""]; then + mvn -B verify sonar:sonar -Dsonar.projectKey=tupilabs_HumanNameParser.java -Dsonar.organization=tupilabs -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN || true + fi env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - -