From 491547b03f086f7d3cc8bab5d995ac69f9516ecf Mon Sep 17 00:00:00 2001 From: Andre Wyrwa Date: Thu, 15 Dec 2016 01:02:55 +1100 Subject: [PATCH] cleanup; add more tests; improve handling of edge cases; --- composer.json | 4 +- phpunit.xml.dist | 2 +- src/Mapper/AbstractMapper.php | 5 +- src/Mapper/FirstnameMapper.php | 54 +-- src/Mapper/InitialMapper.php | 6 +- src/Mapper/LastnameMapper.php | 5 +- src/Mapper/MiddlenameMapper.php | 26 +- src/Mapper/NicknameMapper.php | 22 +- src/Mapper/SalutationMapper.php | 2 - src/Mapper/SuffixMapper.php | 12 +- src/Name.php | 6 +- src/Parser.php | 22 +- src/Part/AbstractPart.php | 2 +- src/Part/Firstname.php | 2 - src/Part/Initial.php | 10 +- src/Part/Lastname.php | 2 - src/Part/Middlename.php | 2 - src/Part/Nickname.php | 2 - src/Part/Salutation.php | 1 - src/Part/Suffix.php | 2 - tests/Mapper/AbstractMapperTest.php | 22 ++ tests/Mapper/FirstnameMapperTest.php | 53 +++ tests/Mapper/InitialMapperTest.php | 55 +++ tests/Mapper/LastnameMapperTest.php | 79 +++++ tests/ParserTest.php | 389 +++++++++++++++++++++ tests/TheIconic/NameParser/ParserTest.php | 397 ---------------------- 26 files changed, 721 insertions(+), 463 deletions(-) create mode 100644 tests/Mapper/AbstractMapperTest.php create mode 100644 tests/Mapper/FirstnameMapperTest.php create mode 100644 tests/Mapper/InitialMapperTest.php create mode 100644 tests/Mapper/LastnameMapperTest.php create mode 100644 tests/ParserTest.php delete mode 100644 tests/TheIconic/NameParser/ParserTest.php diff --git a/composer.json b/composer.json index b170988..e4055fb 100644 --- a/composer.json +++ b/composer.json @@ -13,12 +13,12 @@ "php": ">=5.4" }, "require-dev": { - "phpunit/phpunit": "4.4.*", + "phpunit/phpunit": "^5.0", "satooshi/php-coveralls": "^1.0" }, "autoload": { "psr-4": { - "TheIconic\\NameParser\\": "src/" + "TheIconic\\NameParser\\": ["src/", "tests/"] } } } diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 0f5b828..4f8d9ca 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -5,7 +5,7 @@ > - ./tests/TheIconic/NameParser + ./tests diff --git a/src/Mapper/AbstractMapper.php b/src/Mapper/AbstractMapper.php index 7f64c3a..e87b41c 100644 --- a/src/Mapper/AbstractMapper.php +++ b/src/Mapper/AbstractMapper.php @@ -4,7 +4,9 @@ abstract class AbstractMapper { - + /** + * @var array + */ protected $options = []; /** @@ -26,5 +28,4 @@ public function __construct(array $options = null) * @return array $parts - the mapped parts */ abstract public function map(array $parts); - } diff --git a/src/Mapper/FirstnameMapper.php b/src/Mapper/FirstnameMapper.php index d7d3be0..96ad7a8 100644 --- a/src/Mapper/FirstnameMapper.php +++ b/src/Mapper/FirstnameMapper.php @@ -10,7 +10,6 @@ class FirstnameMapper extends AbstractMapper { - /** * map firstnames in parts array * @@ -19,23 +18,11 @@ class FirstnameMapper extends AbstractMapper */ public function map(array $parts) { if (count($parts) < 2) { - if ($parts[0] instanceof AbstractPart) { - return $parts; - } - - $parts[0] = new Firstname($parts[0]); - - return $parts; + return [$this->handleSinglePart($parts[0])]; } - // skip to after salutation $length = count($parts); - $start = 0; - for ($i = 0; $i < $length; $i++) { - if ($parts[$i] instanceof Salutation) { - $start = $i + 1; - } - } + $start = $this->getStartIndex($parts, $length); $pos = null; @@ -46,10 +33,8 @@ public function map(array $parts) { break; } - if ($part instanceof Initial) { - if (null === $pos) { - $pos = $k; - } + if ($part instanceof Initial && null === $pos) { + $pos = $k; } if ($part instanceof AbstractPart) { @@ -67,4 +52,35 @@ public function map(array $parts) { return $parts; } + /** + * @param $part + * @return Firstname + */ + protected function handleSinglePart($part) + { + if ($part instanceof AbstractPart) { + return $part; + } + + return new Firstname($part); + } + + /** + * @param array $parts + * @param int $total + * @return int + */ + protected function getStartIndex(array $parts, $total) + { + // skip to after salutation + $start = 0; + + for ($i = 0; $i < $total; $i++) { + if ($parts[$i] instanceof Salutation) { + $start = $i + 1; + } + } + + return $start; + } } diff --git a/src/Mapper/InitialMapper.php b/src/Mapper/InitialMapper.php index ff6230a..7738d51 100644 --- a/src/Mapper/InitialMapper.php +++ b/src/Mapper/InitialMapper.php @@ -5,10 +5,11 @@ use TheIconic\NameParser\Part\AbstractPart; use TheIconic\NameParser\Part\Initial; -// single letter, possibly followed by a period +/** + * single letter, possibly followed by a period + */ class InitialMapper extends AbstractMapper { - /** * map intials in parts array * @@ -28,5 +29,4 @@ function map(array $parts) { return $parts; } - } diff --git a/src/Mapper/LastnameMapper.php b/src/Mapper/LastnameMapper.php index a14e7d8..e714187 100644 --- a/src/Mapper/LastnameMapper.php +++ b/src/Mapper/LastnameMapper.php @@ -8,7 +8,6 @@ class LastnameMapper extends AbstractMapper { - /** * @var array options */ @@ -67,8 +66,7 @@ public function map(array $parts) { */ protected function hasUnmappedPartsBefore(array $parts, $index) { - foreach ($parts as $k => $part) - { + foreach ($parts as $k => $part) { if ($k === $index) { break; } @@ -80,5 +78,4 @@ protected function hasUnmappedPartsBefore(array $parts, $index) return false; } - } diff --git a/src/Mapper/MiddlenameMapper.php b/src/Mapper/MiddlenameMapper.php index ef7d6e0..ae95e59 100644 --- a/src/Mapper/MiddlenameMapper.php +++ b/src/Mapper/MiddlenameMapper.php @@ -9,7 +9,6 @@ class MiddlenameMapper extends AbstractMapper { - /** * map middlenames in the parts array * @@ -23,12 +22,7 @@ public function map(array $parts) { // skip to after salutation $length = count($parts); - $start = 0; - for ($i = 0; $i < $length; $i++) { - if ($parts[$i] instanceof Firstname) { - $start = $i + 1; - } - } + $start = $this->getStartIndex($parts, $length); for ($k = $start; $k < $length; $k++) { $part = $parts[$k]; @@ -47,4 +41,22 @@ public function map(array $parts) { return $parts; } + /** + * @param array $parts + * @param int $total + * @return int + */ + protected function getStartIndex(array $parts, $total) + { + // skip to after salutation + $start = 0; + + for ($i = 0; $i < $total; $i++) { + if ($parts[$i] instanceof Firstname) { + $start = $i + 1; + } + } + + return $start; + } } diff --git a/src/Mapper/NicknameMapper.php b/src/Mapper/NicknameMapper.php index d8bcc80..4919923 100644 --- a/src/Mapper/NicknameMapper.php +++ b/src/Mapper/NicknameMapper.php @@ -5,10 +5,8 @@ use TheIconic\NameParser\Part\AbstractPart; use TheIconic\NameParser\Part\Nickname; -// single letter, possibly followed by a period class NicknameMapper extends AbstractMapper { - /** * map nicknames in the parts array * @@ -16,17 +14,31 @@ class NicknameMapper extends AbstractMapper * @return array the mapped parts */ function map(array $parts) { + $isEncapsulated = false; + foreach ($parts as $k => $part) { if ($part instanceof AbstractPart) { continue; } - if (preg_match('/^[\(\[\<\{].*[\)\]\>\}]$/', $part)) { - $parts[$k] = new Nickname(substr($part, 1, -1)); + if (preg_match('/^[\(\[\<\{]/', $part)) { + $isEncapsulated = true; + + $part = substr($part, 1); + } + + $addPart = $isEncapsulated; + + if (preg_match('/[\)\]\>\}]$/', $part)) { + $isEncapsulated = false; + $part = substr($part, 0, -1); + } + + if ($addPart) { + $parts[$k] = new Nickname($part); } } return $parts; } - } diff --git a/src/Mapper/SalutationMapper.php b/src/Mapper/SalutationMapper.php index a188adf..6545706 100644 --- a/src/Mapper/SalutationMapper.php +++ b/src/Mapper/SalutationMapper.php @@ -7,7 +7,6 @@ class SalutationMapper extends AbstractMapper { - /** * map salutations in the parts array * @@ -27,5 +26,4 @@ function map(array $parts) { return $parts; } - } diff --git a/src/Mapper/SuffixMapper.php b/src/Mapper/SuffixMapper.php index bf8f734..9a68a34 100644 --- a/src/Mapper/SuffixMapper.php +++ b/src/Mapper/SuffixMapper.php @@ -7,6 +7,12 @@ class SuffixMapper extends AbstractMapper { + /** + * @var array options + */ + protected $options = [ + 'match_single' => false, + ]; /** * map suffixes in the parts array @@ -15,6 +21,11 @@ class SuffixMapper extends AbstractMapper * @return array the mapped parts */ function map(array $parts) { + if ($this->options['match_single'] && count($parts) == 1 && Suffix::isSuffix($parts[0])) { + $parts[0] = new Suffix($parts[0]); + return $parts; + } + $start = count($parts) - 1; for ($k = $start; $k > 1; $k--) { @@ -33,5 +44,4 @@ function map(array $parts) { return $parts; } - } diff --git a/src/Name.php b/src/Name.php index fd3b256..a11892f 100644 --- a/src/Name.php +++ b/src/Name.php @@ -6,7 +6,6 @@ class Name { - /** * @var array the parts that make up this name */ @@ -14,6 +13,7 @@ class Name /** * constructor takes the array of parts this name consists of + * * @param array|null $parts */ public function __construct(array $parts = null) @@ -46,6 +46,9 @@ public function getParts() return $this->parts; } + /** + * @return array + */ public function getAll() { $results = []; @@ -149,5 +152,4 @@ protected function export($type) return implode(' ', $matched); } - } diff --git a/src/Parser.php b/src/Parser.php index 2dee6e6..a2faad6 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -12,9 +12,14 @@ class Parser { - + /** + * @var string + */ protected $whitespace = " \r\n\t"; + /** + * @var array + */ protected $mappers = []; /** @@ -28,8 +33,8 @@ class Parser * @param $full_name * @return Name */ - public function parse($name) { - + public function parse($name) + { $name = $this->normalize($name); if (false !== $pos = strpos($name, ',')) { @@ -53,24 +58,32 @@ public function parse($name) { * * @return Name */ - protected function parseSplitName($left, $right) { + protected function parseSplitName($left, $right) + { $first = new Parser(); $first->setMappers([ new SalutationMapper(), new SuffixMapper(), new LastnameMapper(['match_single' => true]), + new FirstnameMapper(), + new MiddlenameMapper(), ]); + $second = new Parser(); $second->setMappers([ + new SalutationMapper(), + new SuffixMapper(['match_single' => true]), new NicknameMapper(), new InitialMapper(), new FirstnameMapper(), new MiddlenameMapper(), ]); + $parts = array_merge( $first->parse($left)->getParts(), $second->parse($right)->getParts() ); + return new Name($parts); } @@ -140,5 +153,4 @@ protected function setWhitespace($whitespace) { $this->whitespace = $whitespace; } - } diff --git a/src/Part/AbstractPart.php b/src/Part/AbstractPart.php index 1cfebc5..42b224b 100644 --- a/src/Part/AbstractPart.php +++ b/src/Part/AbstractPart.php @@ -67,7 +67,7 @@ public function normalize() */ protected function camelcase($word) { - if (preg_match("/[A-Za-z]([A-Z]*[a-z][a-z]*[A-Z]|[a-z]*[A-Z][A-Z]*[a-z])[A-Za-z]*/", $word)) { + if (preg_match('/[A-Za-z]([A-Z]*[a-z][a-z]*[A-Z]|[a-z]*[A-Z][A-Z]*[a-z])[A-Za-z]*/', $word)) { return $word; } diff --git a/src/Part/Firstname.php b/src/Part/Firstname.php index ba8fd18..8d9aa6b 100644 --- a/src/Part/Firstname.php +++ b/src/Part/Firstname.php @@ -4,7 +4,6 @@ class Firstname extends AbstractPart { - /** * camelcase the firstname * @@ -14,5 +13,4 @@ public function normalize() { return $this->camelcase($this->getValue()); } - } diff --git a/src/Part/Initial.php b/src/Part/Initial.php index 91e1efb..36a6153 100644 --- a/src/Part/Initial.php +++ b/src/Part/Initial.php @@ -4,5 +4,13 @@ class Initial extends AbstractPart { - + /** + * uppercase the initial + * + * @return mixed + */ + public function normalize() + { + return strtoupper($this->getValue()); + } } diff --git a/src/Part/Lastname.php b/src/Part/Lastname.php index d9163a7..3fb0b0e 100644 --- a/src/Part/Lastname.php +++ b/src/Part/Lastname.php @@ -4,7 +4,6 @@ class Lastname extends AbstractPart { - /** * @var array possible lastname prefixes */ @@ -64,5 +63,4 @@ public function normalize() return $this->camelcase($this->getValue()); } - } diff --git a/src/Part/Middlename.php b/src/Part/Middlename.php index 5346940..a81e616 100644 --- a/src/Part/Middlename.php +++ b/src/Part/Middlename.php @@ -4,7 +4,6 @@ class Middlename extends AbstractPart { - /** * camelcase the middlename for normalization * @@ -14,5 +13,4 @@ public function normalize() { return $this->camelcase($this->getValue()); } - } diff --git a/src/Part/Nickname.php b/src/Part/Nickname.php index 68175dd..9371c19 100644 --- a/src/Part/Nickname.php +++ b/src/Part/Nickname.php @@ -4,7 +4,6 @@ class Nickname extends AbstractPart { - /** * camelcase the nickname for normalization * @@ -14,5 +13,4 @@ public function normalize() { return $this->camelcase($this->getValue()); } - } diff --git a/src/Part/Salutation.php b/src/Part/Salutation.php index d1b693e..289b07b 100644 --- a/src/Part/Salutation.php +++ b/src/Part/Salutation.php @@ -4,7 +4,6 @@ class Salutation extends AbstractPart { - /** * @var array possible salutations */ diff --git a/src/Part/Suffix.php b/src/Part/Suffix.php index b64d4e9..4194a16 100644 --- a/src/Part/Suffix.php +++ b/src/Part/Suffix.php @@ -4,7 +4,6 @@ class Suffix extends AbstractPart { - /** * @var array possible suffixes */ @@ -64,5 +63,4 @@ public function normalize() { return static::$suffixes[self::getKey($this->getValue())]; } - } diff --git a/tests/Mapper/AbstractMapperTest.php b/tests/Mapper/AbstractMapperTest.php new file mode 100644 index 0000000..580f043 --- /dev/null +++ b/tests/Mapper/AbstractMapperTest.php @@ -0,0 +1,22 @@ +assertEquals($expectation, $mapper->map($input)); + } +} \ No newline at end of file diff --git a/tests/Mapper/FirstnameMapperTest.php b/tests/Mapper/FirstnameMapperTest.php new file mode 100644 index 0000000..db8ba7e --- /dev/null +++ b/tests/Mapper/FirstnameMapperTest.php @@ -0,0 +1,53 @@ + [ + 'Peter', + 'Pan', + ], + 'expectation' => [ + new Firstname('Peter'), + 'Pan', + ], + ], + [ + 'input' => [ + new Salutation('Mr'), + 'Peter', + 'Pan', + ], + 'expectation' => [ + new Salutation('Mr'), + new Firstname('Peter'), + 'Pan', + ], + ], + [ + 'input' => [ + new Salutation('Mr'), + 'Peter', + new Lastname('Pan'), + ], + 'expectation' => [ + new Salutation('Mr'), + new Firstname('Peter'), + new Lastname('Pan'), + ], + ], + ]; + } +} \ No newline at end of file diff --git a/tests/Mapper/InitialMapperTest.php b/tests/Mapper/InitialMapperTest.php new file mode 100644 index 0000000..61fea15 --- /dev/null +++ b/tests/Mapper/InitialMapperTest.php @@ -0,0 +1,55 @@ + [ + 'A', + 'B', + ], + 'expectation' => [ + new Initial('A'), + new Initial('B'), + ], + ], + [ + 'input' => [ + new Salutation('Mr'), + 'P.', + 'Pan', + ], + 'expectation' => [ + new Salutation('Mr'), + new Initial('P.'), + 'Pan', + ], + ], + [ + 'input' => [ + new Salutation('Mr'), + 'Peter', + 'D.', + new Lastname('Pan'), + ], + 'expectation' => [ + new Salutation('Mr'), + 'Peter', + new Initial('D.'), + new Lastname('Pan'), + ], + ], + ]; + } +} \ No newline at end of file diff --git a/tests/Mapper/LastnameMapperTest.php b/tests/Mapper/LastnameMapperTest.php new file mode 100644 index 0000000..8f06c1f --- /dev/null +++ b/tests/Mapper/LastnameMapperTest.php @@ -0,0 +1,79 @@ + [ + 'Peter', + 'Pan', + ], + 'expectation' => [ + 'Peter', + new Lastname('Pan'), + ], + ], + [ + 'input' => [ + new Salutation('Mr'), + 'Peter', + 'Pan', + ], + 'expectation' => [ + new Salutation('Mr'), + 'Peter', + new Lastname('Pan'), + ], + ], + [ + 'input' => [ + new Salutation('Mr'), + new Firstname('Peter'), + 'Pan', + ], + 'expectation' => [ + new Salutation('Mr'), + new Firstname('Peter'), + new Lastname('Pan'), + ], + ], + [ + 'input' => [ + new Salutation('Mr'), + 'Lars', + 'van', + 'Trier', + ], + 'expectation' => [ + new Salutation('Mr'), + 'Lars', + new Lastname('van'), + new Lastname('Trier'), + ], + ], + [ + 'input' => [ + new Salutation('Mr'), + 'Dan', + 'Huong', + ], + 'expectation' => [ + new Salutation('Mr'), + 'Dan', + new Lastname('Huong'), + ], + ], + ]; + } +} \ No newline at end of file diff --git a/tests/ParserTest.php b/tests/ParserTest.php new file mode 100644 index 0000000..0c5be65 --- /dev/null +++ b/tests/ParserTest.php @@ -0,0 +1,389 @@ + 'James', + 'lastname' => 'Norrington', + ] + + ], + [ + 'Hans Christian Anderssen', + [ + 'firstname' => 'Hans', + 'lastname' => 'Anderssen', + 'middlename' => 'Christian', + ] + ], + [ + 'Mr Anthony R Von Fange III', + [ + 'salutation' => 'Mr.', + 'firstname' => 'Anthony', + 'initials' => 'R', + 'lastname' => 'von Fange', + 'suffix' => 'III', + ] + ], + [ + 'J. B. Hunt', + [ + 'firstname' => 'J.', + 'initials' => 'B.', + 'lastname' => 'Hunt', + ] + ], + [ + 'J.B. Hunt', + [ + 'firstname' => 'J.B.', + 'lastname' => 'Hunt', + ] + ], + [ + 'Edward Senior III', + [ + 'firstname' => 'Edward', + 'lastname' => 'Senior', + 'suffix' => 'III' + ] + ], + [ + 'Edward Dale Senior II', + [ + 'firstname' => 'Edward', + 'lastname' => 'Dale', + 'suffix' => 'Senior II' + ] + ], + [ + 'Dale Edward Jones Senior', + [ + 'firstname' => 'Dale', + 'middlename' => 'Edward', + 'lastname' => 'Jones', + 'suffix' => 'Senior' + ] + ], + [ + 'Jason Rodriguez Sr.', + [ + 'firstname' => 'Jason', + 'lastname' => 'Rodriguez', + 'suffix' => 'Sr' + ] + ], + [ + 'Jason Senior', + [ + 'firstname' => 'Jason', + 'lastname' => 'Senior', + ] + ], + [ + 'Bill Junior', + [ + 'firstname' => 'Bill', + 'lastname' => 'Junior', + ] + ], + [ + 'Sara Ann Fraser', + [ + 'firstname' => 'Sara', + 'middlename' => 'Ann', + 'lastname' => 'Fraser', + ] + ], + [ + 'Adam', + [ + 'firstname' => 'Adam', + ] + ], + [ + 'OLD MACDONALD', + [ + 'firstname' => 'Old', + 'lastname' => 'Macdonald', + ] + ], + [ + 'Old MacDonald', + [ + 'firstname' => 'Old', + 'lastname' => 'MacDonald', + ] + ], + [ + 'Old McDonald', + [ + 'firstname' => 'Old', + 'lastname' => 'McDonald', + ] + ], + [ + 'Old Mc Donald', + [ + 'firstname' => 'Old', + 'middlename' => 'Mc', + 'lastname' => 'Donald', + ] + ], + [ + 'Old Mac Donald', + [ + 'firstname' => 'Old', + 'middlename' => 'Mac', + 'lastname' => 'Donald', + ] + ], + [ + 'James van Allen', + [ + 'firstname' => 'James', + 'lastname' => 'van Allen', + ] + ], + [ + 'Jimmy (Bubba) Smith', + [ + 'firstname' => 'Jimmy', + 'lastname' => 'Smith', + 'nickname' => 'Bubba', + ] + ], + [ + 'Miss Jennifer Shrader Lawrence', + [ + 'salutation' => 'Ms.', + 'firstname' => 'Jennifer', + 'middlename' => 'Shrader', + 'lastname' => 'Lawrence', + ] + ], + [ + 'Dr. Jonathan Smith', + [ + 'salutation' => 'Dr.', + 'firstname' => 'Jonathan', + 'lastname' => 'Smith', + ] + ], + [ + 'Miss Jamie P. Harrowitz', + [ + 'salutation' => 'Ms.', + 'firstname' => 'Jamie', + 'initials' => 'P.', + 'lastname' => 'Harrowitz', + ] + ], + [ + 'Mr John Doe', + [ + 'salutation' => 'Mr.', + 'firstname' => 'John', + 'lastname' => 'Doe', + ] + ], + [ + 'Rev. Dr John Doe', + [ + 'salutation' => 'Rev. Dr.', + 'firstname' => 'John', + 'lastname' => 'Doe', + ] + ], + [ + 'Anthony Von Fange III', + [ + 'firstname' => 'Anthony', + 'lastname' => 'von Fange', + 'suffix' => 'III' + ] + ], + [ + 'Smarty Pants Phd', + [ + 'firstname' => 'Smarty', + 'lastname' => 'Pants', + 'suffix' => 'PhD' + ] + ], + [ + 'Mark Peter Williams', + [ + 'firstname' => 'Mark', + 'middlename' => 'Peter', + 'lastname' => 'Williams', + ] + ], + [ + 'Mark P Williams', + [ + 'firstname' => 'Mark', + 'lastname' => 'Williams', + 'initials' => 'P', + ] + ], + [ + 'Mark P. Williams', + [ + 'firstname' => 'Mark', + 'initials' => 'P.', + 'lastname' => 'Williams', + ] + ], + [ + 'M Peter Williams', + [ + 'firstname' => 'Peter', + 'initials' => 'M', + 'lastname' => 'Williams', + ] + ], + [ + 'M. Peter Williams', + [ + 'firstname' => 'Peter', + 'initials' => 'M.', + 'lastname' => 'Williams', + ] + ], + [ + 'M. P. Williams', + [ + 'firstname' => 'M.', + 'initials' => 'P.', + 'lastname' => 'Williams', + ] + ], + [ + 'The Rev. Mark Williams', + [ + 'salutation' => 'Rev.', + 'firstname' => 'Mark', + 'lastname' => 'Williams', + ] + ], + [ + 'Mister Mark Williams', + [ + 'salutation' => 'Mr.', + 'firstname' => 'Mark', + 'lastname' => 'Williams', + ] + ], + [ + 'Fraser, Joshua', + [ + 'firstname' => 'Joshua', + 'lastname' => 'Fraser', + ] + ], + [ + 'Mrs. Brown, Amanda', + [ + 'salutation' => 'Mrs.', + 'firstname' => 'Amanda', + 'lastname' => 'Brown', + ] + ], + [ + "Mr.\r\nPaul\rJoseph\nMaria\tWinters", + [ + 'salutation' => 'Mr.', + 'firstname' => 'Paul', + 'middlename' => 'Joseph Maria', + 'lastname' => 'Winters', + ] + ], + [ + 'Van Truong', + [ + 'firstname' => 'Van', + 'lastname' => 'Truong', + ], + ], + [ + 'Mr. Van Truong', + [ + 'salutation' => 'Mr.', + 'firstname' => 'Van', + 'lastname' => 'Truong', + ], + ], + [ + 'Anthony Von Fange III, PHD', + [ + 'firstname' => 'Anthony', + 'lastname' => 'von Fange', + 'suffix' => 'III PhD' + ] + ], + [ + 'Jimmy (Bubba Junior) Smith', + [ + 'nickname' => 'Bubba Junior', + 'firstname' => 'Jimmy', + 'lastname' => 'Smith', + ] + ], + [ + 'Jonathan Smith, MD', + [ + 'firstname' => 'Jonathan', + 'lastname' => 'Smith', + 'suffix' => 'MD' + ] + ], + ]; + } + + /** + * @return array + */ + public function disfunctionalastnameProvider() + { + return [ + // fails. both initials should be capitalized + [ + 'JB Hunt', + [ + 'firstname' => 'JB', + 'lastname' => 'Hunt', + ] + ], + ]; + } + + /** + * @dataProvider provider + * + * @param $input + * @param $expectation + */ + public function testParse($input, $expectation) + { + $parser = new Parser(); + $name = $parser->parse($input); + + $this->assertInstanceOf('\\TheIconic\\NameParser\\Name', $name); + $this->assertEquals($expectation, $name->getAll()); + } + +} diff --git a/tests/TheIconic/NameParser/ParserTest.php b/tests/TheIconic/NameParser/ParserTest.php deleted file mode 100644 index b02937e..0000000 --- a/tests/TheIconic/NameParser/ParserTest.php +++ /dev/null @@ -1,397 +0,0 @@ - 'James', - 'lastname' => 'Norrington', - ) - - ), - array( - 'Hans Christian Anderssen', - array( - 'firstname' => 'Hans', - 'lastname' => 'Anderssen', - 'middlename' => 'Christian', - ) - ), - array( - 'Mr Anthony R Von Fange III', - array( - 'salutation' => 'Mr.', - 'firstname' => 'Anthony', - 'initials' => 'R', - 'lastname' => 'von Fange', - 'suffix' => 'III', - ) - ), - array( - 'Mr Anthony R Von Fange III', - array( - 'salutation' => 'Mr.', - 'firstname' => 'Anthony', - 'initials' => 'R', - 'lastname' => 'von Fange', - 'suffix' => 'III' - ) - ), - array( - 'J. B. Hunt', - array( - 'firstname' => 'J.', - 'initials' => 'B.', - 'lastname' => 'Hunt', - ) - ), - array( - 'J.B. Hunt', - array( - 'firstname' => 'J.B.', - 'lastname' => 'Hunt', - ) - ), - array( - 'Edward Senior III', - array( - 'firstname' => 'Edward', - 'lastname' => 'Senior', - 'suffix' => 'III' - ) - ), - array( - 'Edward Dale Senior II', - array( - 'firstname' => 'Edward', - 'lastname' => 'Dale', - 'suffix' => 'Senior II' - ) - ), - array( - 'Dale Edward Jones Senior', - array( - 'firstname' => 'Dale', - 'middlename' => 'Edward', - 'lastname' => 'Jones', - 'suffix' => 'Senior' - ) - ), - array( - 'Jason Rodriguez Sr.', - array( - 'firstname' => 'Jason', - 'lastname' => 'Rodriguez', - 'suffix' => 'Sr' - ) - ), - array( - 'Jason Senior', - array( - 'firstname' => 'Jason', - 'lastname' => 'Senior', - ) - ), - array( - 'Bill Junior', - array( - 'firstname' => 'Bill', - 'lastname' => 'Junior', - ) - ), - array( - 'Sara Ann Fraser', - array( - 'firstname' => 'Sara', - 'middlename' => 'Ann', - 'lastname' => 'Fraser', - ) - ), - array( - 'Adam', - array( - 'firstname' => 'Adam', - ) - ), - array( - 'OLD MACDONALD', - array( - 'firstname' => 'Old', - 'lastname' => 'Macdonald', - ) - ), - array( - 'Old MacDonald', - array( - 'firstname' => 'Old', - 'lastname' => 'MacDonald', - ) - ), - array( - 'Old McDonald', - array( - 'firstname' => 'Old', - 'lastname' => 'McDonald', - ) - ), - array( - 'Old Mc Donald', - array( - 'firstname' => 'Old', - 'middlename' => 'Mc', - 'lastname' => 'Donald', - ) - ), - array( - 'Old Mac Donald', - array( - 'firstname' => 'Old', - 'middlename' => 'Mac', - 'lastname' => 'Donald', - ) - ), - array( - 'James van Allen', - array( - 'firstname' => 'James', - 'lastname' => 'van Allen', - ) - ), - array( - 'Jimmy (Bubba) Smith', - array( - 'firstname' => 'Jimmy', - 'lastname' => 'Smith', - 'nickname' => 'Bubba', - ) - ), - array( - 'Miss Jennifer Shrader Lawrence', - array( - 'salutation' => 'Ms.', - 'firstname' => 'Jennifer', - 'middlename' => 'Shrader', - 'lastname' => 'Lawrence', - ) - ), - array( - 'Dr. Jonathan Smith', - array( - 'salutation' => 'Dr.', - 'firstname' => 'Jonathan', - 'lastname' => 'Smith', - ) - ), - array( - 'Miss Jamie P. Harrowitz', - array( - 'salutation' => 'Ms.', - 'firstname' => 'Jamie', - 'initials' => 'P.', - 'lastname' => 'Harrowitz', - ) - ), - array( - 'Mr John Doe', - array( - 'salutation' => 'Mr.', - 'firstname' => 'John', - 'lastname' => 'Doe', - ) - ), - array( - 'Rev. Dr John Doe', - array( - 'salutation' => 'Rev. Dr.', - 'firstname' => 'John', - 'lastname' => 'Doe', - ) - ), - array( - 'Anthony Von Fange III', - array( - 'firstname' => 'Anthony', - 'lastname' => 'von Fange', - 'suffix' => 'III' - ) - ), - array( - 'Smarty Pants Phd', - array( - 'firstname' => 'Smarty', - 'lastname' => 'Pants', - 'suffix' => 'PhD' - ) - ), - array( - 'Mark Peter Williams', - array( - 'firstname' => 'Mark', - 'middlename' => 'Peter', - 'lastname' => 'Williams', - ) - ), - array( - 'Mark P Williams', - array( - 'firstname' => 'Mark', - 'lastname' => 'Williams', - 'initials' => 'P', - ) - ), - array( - 'Mark P. Williams', - array( - 'firstname' => 'Mark', - 'initials' => 'P.', - 'lastname' => 'Williams', - ) - ), - array( - 'M Peter Williams', - array( - 'firstname' => 'Peter', - 'initials' => 'M', - 'lastname' => 'Williams', - ) - ), - array( - 'M. Peter Williams', - array( - 'firstname' => 'Peter', - 'initials' => 'M.', - 'lastname' => 'Williams', - ) - ), - array( - 'M. P. Williams', - array( - 'firstname' => 'M.', - 'initials' => 'P.', - 'lastname' => 'Williams', - ) - ), - array( - 'The Rev. Mark Williams', - array( - 'salutation' => 'Rev.', - 'firstname' => 'Mark', - 'lastname' => 'Williams', - ) - ), - array( - 'Mister Mark Williams', - array( - 'salutation' => 'Mr.', - 'firstname' => 'Mark', - 'lastname' => 'Williams', - ) - ), - array( - 'Fraser, Joshua', - array( - 'firstname' => 'Joshua', - 'lastname' => 'Fraser', - ) - ), - array( - 'Mrs. Brown, Amanda', - array( - 'salutation' => 'Mrs.', - 'firstname' => 'Amanda', - 'lastname' => 'Brown', - ) - ), - array( - "Mr.\r\nPaul\rJoseph\nMaria\tWinters", - array( - 'salutation' => 'Mr.', - 'firstname' => 'Paul', - 'middlename' => 'Joseph Maria', - 'lastname' => 'Winters', - ) - ), - array( - 'Van Truong', - array( - 'firstname' => 'Van', - 'lastname' => 'Truong', - ), - ), - ); - } - - public function disfunctionalastnameProvider() - { - return array( - array( - 'Jonathan Smith, MD', - array( - 'firstname' => 'Jonathan', - 'lastname' => 'Smith', - 'suffix' => 'MD' - ) - ), - // fails. both initials should be capitalized - array( - 'JB Hunt', - array( - 'firstname' => 'JB', - 'lastname' => 'Hunt', - ) - ), - // fails. doesn't handle multiple words inside parenthesis - array( - 'Jimmy (Bubba Junior) Smith', - array( - 'nickname' => 'Bubba Junior', - 'firstname' => 'Jimmy', - 'lastname' => 'Smith', - ) - ), - // fails. should normalize the PhD suffix - array( - 'Anthony Von Fange III, PHD', - array( - 'firstname' => 'Anthony', - 'lastname' => 'Von Fange', - 'suffix' => 'III, PhD' - ) - ), - // fails. should treat 'Silly' as the nickname or remove altogether - array( - 'Not So Smarty Pants, Silly', - array( - 'nickname' => 'Silly', - 'firstname' => 'Not So Smarty', - 'lastname' => 'Pants', - ) - ), - ); - } - - /** - * @dataProvider provider - * - * @param $input - * @param $expectation - */ - public function testParse($input, $expectation) - { - $parser = new Parser(); - $name = $parser->parse($input); - - $this->assertInstanceOf('\\TheIconic\\NameParser\\Name', $name); - $this->assertEquals($expectation, $name->getAll()); - } - -}