From 95a330cb0d512c40e717574a13f9de373c812274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Wa=C5=9B?= Date: Sun, 13 Sep 2015 14:19:19 +0200 Subject: [PATCH 1/3] replace preg_replace_callback with for loops; add support for an asterisk in bothify --- src/Faker/Provider/Base.php | 31 +++++++++++++++++++++++++------ test/Faker/Provider/BaseTest.php | 5 +++++ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/Faker/Provider/Base.php b/src/Faker/Provider/Base.php index d16f8b5ca6..9c7aefe2c6 100644 --- a/src/Faker/Provider/Base.php +++ b/src/Faker/Provider/Base.php @@ -317,6 +317,19 @@ public static function shuffleString($string = '', $encoding = 'UTF-8') return join('', static::shuffleArray($array)); } + private static function replaceWildcard($string, $wildcard = '#', $callback = 'static::randomDigit') + { + if (($pos = strpos($string, $wildcard)) === false) { + return $string; + } + for ($i = $pos, $last = strrpos($string, $wildcard, $pos) + 1; $i < $last; $i++) { + if ($string[$i] === $wildcard) { + $string[$i] = call_user_func($callback); + } + } + return $string; + } + /** * Replaces all hash sign ('#') occurrences with a random number * Replaces all percentage sign ('%') occurrences with a not null number @@ -329,9 +342,11 @@ public static function numerify($string = '###') // instead of using randomDigit() several times, which is slow, // count the number of hashes and generate once a large number $toReplace = array(); - for ($i = 0, $count = strlen($string); $i < $count; $i++) { - if ($string[$i] === '#') { - $toReplace []= $i; + if (($pos = strpos($string, '#')) !== false) { + for ($i = $pos, $last = strrpos($string, '#', $pos) + 1; $i < $last; $i++) { + if ($string[$i] === '#') { + $toReplace[] = $i; + } } } if ($nbReplacements = count($toReplace)) { @@ -347,7 +362,7 @@ public static function numerify($string = '###') $string[$toReplace[$i]] = $numbers[$i]; } } - $string = preg_replace_callback('/\%/u', 'static::randomDigitNotNull', $string); + $string = self::replaceWildcard($string, '%', 'static::randomDigitNotNull'); return $string; } @@ -360,17 +375,21 @@ public static function numerify($string = '###') */ public static function lexify($string = '????') { - return preg_replace_callback('/\?/u', 'static::randomLetter', $string); + return self::replaceWildcard($string, '?', 'static::randomLetter'); } /** - * Replaces hash signs and question marks with random numbers and letters + * Replaces hash signs ('#') and question marks ('?') with random numbers and letters + * An asterisk ('*') is replaced with either a random number or a random letter * * @param string $string String that needs to bet parsed * @return string */ public static function bothify($string = '## ??') { + $string = self::replaceWildcard($string, '*', function () { + return mt_rand(0, 1) ? '#' : '?'; + }); return static::lexify(static::numerify($string)); } diff --git a/test/Faker/Provider/BaseTest.php b/test/Faker/Provider/BaseTest.php index a426dc62d7..75881352c9 100644 --- a/test/Faker/Provider/BaseTest.php +++ b/test/Faker/Provider/BaseTest.php @@ -276,6 +276,11 @@ public function testBothifyCombinesNumerifyAndLexify() $this->assertRegExp('/foo[a-z]Ba\dr/', BaseProvider::bothify('foo?Ba#r')); } + public function testBothifyAsterisk() + { + $this->assertRegExp('/foo([a-z]|\d)Ba([a-z]|\d)r/', BaseProvider::bothify('foo*Ba*r')); + } + public function testAsciifyReturnsSameStringWhenItContainsNoStarSign() { $this->assertEquals('fooBar?', BaseProvider::asciify('fooBar?')); From a49c4c3209d49989e0e0987dea3ba3c3ae5e79d3 Mon Sep 17 00:00:00 2001 From: John Was Date: Mon, 14 Sep 2015 10:14:20 +0200 Subject: [PATCH 2/3] add strpos on utf unit test --- test/Faker/Provider/BaseTest.php | 44 ++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/test/Faker/Provider/BaseTest.php b/test/Faker/Provider/BaseTest.php index 75881352c9..df3764da41 100644 --- a/test/Faker/Provider/BaseTest.php +++ b/test/Faker/Provider/BaseTest.php @@ -276,6 +276,50 @@ public function testBothifyCombinesNumerifyAndLexify() $this->assertRegExp('/foo[a-z]Ba\dr/', BaseProvider::bothify('foo?Ba#r')); } + public function allUtfCharsDataProvider() + { + // create test data + /** @link http://stackoverflow.com/questions/2748956/how-would-you-create-a-string-of-all-utf-8-characters */ + function unichr($i) + { + return iconv('UCS-4LE', 'UTF-8', pack('V', $i)); + } + $codeunits = array(); + for ($i = 0; $i<0xD800; $i++) { + $codeunits[] = unichr($i); + } + for ($i = 0xE000; $i<0xFFFF; $i++) { + $codeunits[] = unichr($i); + } + $data = implode($codeunits); + // end of test data + + return array( + array('#', $data), + array('?', $data), + array('*', $data), + ); + } + + /** + * @dataProvider allUtfCharsDataProvider + */ + public function testStrposOnUtf($char, $data) + { + $pos = 0; + $mbpos = 0; + $count = 0; + $mbcount = 0; + while (($mbpos = mb_strpos($data, $char, $mbpos + 1, 'UTF-8')) !== false) { + $mbcount++; + } + while (($pos = strpos($data, $char, $pos + 1)) !== false) { + $count++; + } + $this->assertEquals(1, $mbcount); + $this->assertEquals(1, $count); + } + public function testBothifyAsterisk() { $this->assertRegExp('/foo([a-z]|\d)Ba([a-z]|\d)r/', BaseProvider::bothify('foo*Ba*r')); From 9fa1546ef556fcb27bd35248216170639eed4fbc Mon Sep 17 00:00:00 2001 From: John Was Date: Mon, 14 Sep 2015 10:36:17 +0200 Subject: [PATCH 3/3] remove strpos unit test; add another utf unit test --- test/Faker/Provider/BaseTest.php | 48 ++++---------------------------- 1 file changed, 5 insertions(+), 43 deletions(-) diff --git a/test/Faker/Provider/BaseTest.php b/test/Faker/Provider/BaseTest.php index df3764da41..4af392965c 100644 --- a/test/Faker/Provider/BaseTest.php +++ b/test/Faker/Provider/BaseTest.php @@ -276,53 +276,15 @@ public function testBothifyCombinesNumerifyAndLexify() $this->assertRegExp('/foo[a-z]Ba\dr/', BaseProvider::bothify('foo?Ba#r')); } - public function allUtfCharsDataProvider() + public function testBothifyAsterisk() { - // create test data - /** @link http://stackoverflow.com/questions/2748956/how-would-you-create-a-string-of-all-utf-8-characters */ - function unichr($i) - { - return iconv('UCS-4LE', 'UTF-8', pack('V', $i)); - } - $codeunits = array(); - for ($i = 0; $i<0xD800; $i++) { - $codeunits[] = unichr($i); - } - for ($i = 0xE000; $i<0xFFFF; $i++) { - $codeunits[] = unichr($i); - } - $data = implode($codeunits); - // end of test data - - return array( - array('#', $data), - array('?', $data), - array('*', $data), - ); - } - - /** - * @dataProvider allUtfCharsDataProvider - */ - public function testStrposOnUtf($char, $data) - { - $pos = 0; - $mbpos = 0; - $count = 0; - $mbcount = 0; - while (($mbpos = mb_strpos($data, $char, $mbpos + 1, 'UTF-8')) !== false) { - $mbcount++; - } - while (($pos = strpos($data, $char, $pos + 1)) !== false) { - $count++; - } - $this->assertEquals(1, $mbcount); - $this->assertEquals(1, $count); + $this->assertRegExp('/foo([a-z]|\d)Ba([a-z]|\d)r/', BaseProvider::bothify('foo*Ba*r')); } - public function testBothifyAsterisk() + public function testBothifyUtf() { - $this->assertRegExp('/foo([a-z]|\d)Ba([a-z]|\d)r/', BaseProvider::bothify('foo*Ba*r')); + $utf = 'œ∑´®†¥¨ˆøπ“‘和製╯°□°╯︵ ┻━┻🐵 🙈 ﺚﻣ ﻦﻔﺳ ﺲﻘﻄﺗ ﻮﺑﺎﻠﺘﺣﺪﻳﺩ،, ﺝﺰﻳﺮﺘﻳ ﺏﺎﺴﺘﺧﺩﺎﻣ ﺄﻧ ﺪﻧﻭ. ﺇﺫ ﻪﻧﺍ؟ ﺎﻠﺴﺗﺍﺭ ﻮﺘ'; + $this->assertRegExp('/'.$utf.'foo\dB[a-z]a([a-z]|\d)r/u', BaseProvider::bothify($utf.'foo#B?a*r')); } public function testAsciifyReturnsSameStringWhenItContainsNoStarSign()