From f3d296e385dd4a46a5ddf507539a6c150c32983e Mon Sep 17 00:00:00 2001 From: Francois Zaninotto Date: Tue, 10 Jul 2012 16:43:46 +0200 Subject: [PATCH] Update Lorem provider to remove WTF effect. `Lorem::words()`, and `Lorem::sentences()` can now return an exact number of words or paragraphs thanks to a second parameter. `Lorem::text()` now works for small number of characters by being smarter. Closes #47. --- src/Faker/Provider/Lorem.php | 115 +++++++++++++++++++++++++----- test/Faker/Provider/LoremTest.php | 42 ++++++++--- 2 files changed, 131 insertions(+), 26 deletions(-) diff --git a/src/Faker/Provider/Lorem.php b/src/Faker/Provider/Lorem.php index 017f9042..4fb115dc 100644 --- a/src/Faker/Provider/Lorem.php +++ b/src/Faker/Provider/Lorem.php @@ -5,7 +5,43 @@ namespace Faker\Provider; class Lorem extends \Faker\Provider\Base { protected static $wordList = array( - 'alias', 'consequatur', 'aut', 'perferendis', 'sit', 'voluptatem', 'accusantium', 'doloremque', 'aperiam', 'eaque', 'ipsa', 'quae', 'ab', 'illo', 'inventore', 'veritatis', 'et', 'quasi', 'architecto', 'beatae', 'vitae', 'dicta', 'sunt', 'explicabo', 'aspernatur', 'aut', 'odit', 'aut', 'fugit', 'sed', 'quia', 'consequuntur', 'magni', 'dolores', 'eos', 'qui', 'ratione', 'voluptatem', 'sequi', 'nesciunt', 'neque', 'dolorem', 'ipsum', 'quia', 'dolor', 'sit', 'amet', 'consectetur', 'adipisci', 'velit', 'sed', 'quia', 'non', 'numquam', 'eius', 'modi', 'tempora', 'incidunt', 'ut', 'labore', 'et', 'dolore', 'magnam', 'aliquam', 'quaerat', 'voluptatem', 'ut', 'enim', 'ad', 'minima', 'veniam', 'quis', 'nostrum', 'exercitationem', 'ullam', 'corporis', 'nemo', 'enim', 'ipsam', 'voluptatem', 'quia', 'voluptas', 'sit', 'suscipit', 'laboriosam', 'nisi', 'ut', 'aliquid', 'ex', 'ea', 'commodi', 'consequatur', 'quis', 'autem', 'vel', 'eum', 'iure', 'reprehenderit', 'qui', 'in', 'ea', 'voluptate', 'velit', 'esse', 'quam', 'nihil', 'molestiae', 'et', 'iusto', 'odio', 'dignissimos', 'ducimus', 'qui', 'blanditiis', 'praesentium', 'laudantium', 'totam', 'rem', 'voluptatum', 'deleniti', 'atque', 'corrupti', 'quos', 'dolores', 'et', 'quas', 'molestias', 'excepturi', 'sint', 'occaecati', 'cupiditate', 'non', 'provident', 'sed', 'ut', 'perspiciatis', 'unde', 'omnis', 'iste', 'natus', 'error', 'similique', 'sunt', 'in', 'culpa', 'qui', 'officia', 'deserunt', 'mollitia', 'animi', 'id', 'est', 'laborum', 'et', 'dolorum', 'fuga', 'et', 'harum', 'quidem', 'rerum', 'facilis', 'est', 'et', 'expedita', 'distinctio', 'nam', 'libero', 'tempore', 'cum', 'soluta', 'nobis', 'est', 'eligendi', 'optio', 'cumque', 'nihil', 'impedit', 'quo', 'porro', 'quisquam', 'est', 'qui', 'minus', 'id', 'quod', 'maxime', 'placeat', 'facere', 'possimus', 'omnis', 'voluptas', 'assumenda', 'est', 'omnis', 'dolor', 'repellendus', 'temporibus', 'autem', 'quibusdam', 'et', 'aut', 'consequatur', 'vel', 'illum', 'qui', 'dolorem', 'eum', 'fugiat', 'quo', 'voluptas', 'nulla', 'pariatur', 'at', 'vero', 'eos', 'et', 'accusamus', 'officiis', 'debitis', 'aut', 'rerum', 'necessitatibus', 'saepe', 'eveniet', 'ut', 'et', 'voluptates', 'repudiandae', 'sint', 'et', 'molestiae', 'non', 'recusandae', 'itaque', 'earum', 'rerum', 'hic', 'tenetur', 'a', 'sapiente', 'delectus', 'ut', 'aut', 'reiciendis', 'voluptatibus', 'maiores', 'doloribus', 'asperiores', 'repellat' + 'alias', 'consequatur', 'aut', 'perferendis', 'sit', 'voluptatem', + 'accusantium', 'doloremque', 'aperiam', 'eaque','ipsa', 'quae', 'ab', + 'illo', 'inventore', 'veritatis', 'et', 'quasi', 'architecto', + 'beatae', 'vitae', 'dicta', 'sunt', 'explicabo', 'aspernatur', 'aut', + 'odit', 'aut', 'fugit', 'sed', 'quia', 'consequuntur', 'magni', + 'dolores', 'eos', 'qui', 'ratione', 'voluptatem', 'sequi', 'nesciunt', + 'neque', 'dolorem', 'ipsum', 'quia', 'dolor', 'sit', 'amet', + 'consectetur', 'adipisci', 'velit', 'sed', 'quia', 'non', 'numquam', + 'eius', 'modi', 'tempora', 'incidunt', 'ut', 'labore', 'et', 'dolore', + 'magnam', 'aliquam', 'quaerat', 'voluptatem', 'ut', 'enim', 'ad', + 'minima', 'veniam', 'quis', 'nostrum', 'exercitationem', 'ullam', + 'corporis', 'nemo', 'enim', 'ipsam', 'voluptatem', 'quia', 'voluptas', + 'sit', 'suscipit', 'laboriosam', 'nisi', 'ut', 'aliquid', 'ex', 'ea', + 'commodi', 'consequatur', 'quis', 'autem', 'vel', 'eum', 'iure', + 'reprehenderit', 'qui', 'in', 'ea', 'voluptate', 'velit', 'esse', + 'quam', 'nihil', 'molestiae', 'et', 'iusto', 'odio', 'dignissimos', + 'ducimus', 'qui', 'blanditiis', 'praesentium', 'laudantium', 'totam', + 'rem', 'voluptatum', 'deleniti', 'atque', 'corrupti', 'quos', + 'dolores', 'et', 'quas', 'molestias', 'excepturi', 'sint', + 'occaecati', 'cupiditate', 'non', 'provident', 'sed', 'ut', + 'perspiciatis', 'unde', 'omnis', 'iste', 'natus', 'error', + 'similique', 'sunt', 'in', 'culpa', 'qui', 'officia', 'deserunt', + 'mollitia', 'animi', 'id', 'est', 'laborum', 'et', 'dolorum', 'fuga', + 'et', 'harum', 'quidem', 'rerum', 'facilis', 'est', 'et', 'expedita', + 'distinctio', 'nam', 'libero', 'tempore', 'cum', 'soluta', 'nobis', + 'est', 'eligendi', 'optio', 'cumque', 'nihil', 'impedit', 'quo', + 'porro', 'quisquam', 'est', 'qui', 'minus', 'id', 'quod', 'maxime', + 'placeat', 'facere', 'possimus', 'omnis', 'voluptas', 'assumenda', + 'est', 'omnis', 'dolor', 'repellendus', 'temporibus', 'autem', + 'quibusdam', 'et', 'aut', 'consequatur', 'vel', 'illum', 'qui', + 'dolorem', 'eum', 'fugiat', 'quo', 'voluptas', 'nulla', 'pariatur', + 'at', 'vero', 'eos', 'et', 'accusamus', 'officiis', 'debitis', 'aut', + 'rerum', 'necessitatibus', 'saepe', 'eveniet', 'ut', 'et', + 'voluptates', 'repudiandae', 'sint', 'et', 'molestiae', 'non', + 'recusandae', 'itaque', 'earum', 'rerum', 'hic', 'tenetur', 'a', + 'sapiente', 'delectus', 'ut', 'aut', 'reiciendis', 'voluptatibus', + 'maiores', 'doloribus', 'asperiores', 'repellat' ); /** @@ -37,15 +73,18 @@ class Lorem extends \Faker\Provider\Base * * @example 'Lorem ipsum dolor sit amet.' * @param integer $nbWords around how many words the sentence should contain + * @param boolean $variableNbWords set to false if you want exactly $nbWords returned, + * otherwise $nbWords may vary by +/-40% with a minimum of 1 * @return string */ - public static function sentence($nbWords = 6) + public static function sentence($nbWords = 6, $variableNbWords = true) { if ($nbWords <= 0) { return ''; } - - $nbWords = ($nbWords * mt_rand(60, 140) / 100) + 1; + if ($variableNbWords) { + $nbWords = self::randomizeNbElements($nbWords); + } $words = static::words($nbWords); $words[0] = ucwords($words[0]); @@ -74,15 +113,18 @@ class Lorem extends \Faker\Provider\Base * * @example 'Sapiente sunt omnis. Ut pariatur ad autem ducimus et. Voluptas rem voluptas sint modi dolorem amet.' * @param integer $nbSentences around how many sentences the paragraph should contain + * @param boolean $variableNbSentences set to false if you want exactly $nbSentences returned, + * otherwise $nbSentences may vary by +/-40% with a minimum of 1 * @return string */ - public static function paragraph($nbSentences = 3) + public static function paragraph($nbSentences = 3, $variableNbSentences = true) { if ($nbSentences <= 0) { return ''; } - - $nbSentences = ($nbSentences * mt_rand(60, 140) / 100) + 1; + if ($variableNbSentences) { + $nbSentences = self::randomizeNbElements($nbSentences); + } return join(static::sentences($nbSentences), ' '); } @@ -104,25 +146,64 @@ class Lorem extends \Faker\Provider\Base } /** - * Generate a long text string + * Generate a text string. + * Depending on the $maxNbChars, returns a string made of words, sentences, or paragraphs. * * @example 'Sapiente sunt omnis. Ut pariatur ad autem ducimus et. Voluptas rem voluptas sint modi dolorem amet.' - * @param integer $maxNbChars Maximum number of characters the text should contain + * @param integer $maxNbChars Maximum number of characters the text should contain (minimum 5) * @return string */ - public function text($maxNbChars = 200) + public static function text($maxNbChars = 200) { - // determine how many paragraphs are needed to reach the $maxNbChars once; $text = array(); - $size = 0; - while ($size < $maxNbChars) { - $paragraph = ($size ? "\n" : '') . static::paragraph(); - $text []= $paragraph; - $size += strlen($paragraph); + if ($maxNbChars < 5) { + throw new \InvalidArgumentException('text() can only generate text of at least 5 characters'); + } else if ($maxNbChars < 25) { + // join words + while(empty($text)) { + $size = 0; + // determine how many words are needed to reach the $maxNbChars once; + while ($size < $maxNbChars) { + $word = ($size ? ' ' : '') . static::word(); + $text []= $word; + $size += strlen($word); + } + array_pop($text); + } + $text[0][0] = strtoupper($text[0][0]); + $text[count($text) - 1] .= '.'; + } else if ($maxNbChars < 100) { + // join sentences + while(empty($text)) { + $size = 0; + // determine how many sentences are needed to reach the $maxNbChars once; + while ($size < $maxNbChars) { + $sentence = ($size ? ' ' : '') . static::sentence(); + $text []= $sentence; + $size += strlen($sentence); + } + array_pop($text); + } + } else { + // join paragraphs + while(empty($text)) { + $size = 0; + // determine how many paragraphs are needed to reach the $maxNbChars once; + while ($size < $maxNbChars) { + $paragraph = ($size ? "\n" : '') . static::paragraph(); + $text []= $paragraph; + $size += strlen($paragraph); + } + array_pop($text); + } } - array_pop($text); return join($text, ''); } + + protected static function randomizeNbElements($nbElements) + { + return (int) ($nbElements * mt_rand(60, 140) / 100) + 1; + } } diff --git a/test/Faker/Provider/LoremTest.php b/test/Faker/Provider/LoremTest.php index 285668b7..c9a59dd6 100644 --- a/test/Faker/Provider/LoremTest.php +++ b/test/Faker/Provider/LoremTest.php @@ -7,13 +7,27 @@ use Faker\Generator; class LoremTest extends \PHPUnit_Framework_TestCase { - public function testText() + /** + * @expectedException \InvalidArgumentException + */ + public function testTextThrowsExceptionWhenAskedLextSizeLessThan5() { - $generator = new Generator(); - $provider = new TestableLorem($generator); - $singleParagraph = 'This is a test paragraph.'; - $this->assertEquals($singleParagraph, $provider->text(51)); - $this->assertEquals($singleParagraph . "\n" . $singleParagraph, $provider->text(52)); + Lorem::text(4); + } + + public function testTextReturnsWordsWhenAskedSizeLessThan25() + { + $this->assertEquals('Word word word word.', TestableLorem::text(24)); + } + + public function testTextReturnsSentencesWhenAskedSizeLessThan100() + { + $this->assertEquals('This is a test sentence. This is a test sentence. This is a test sentence.', TestableLorem::text(99)); + } + + public function testTextReturnsParagraphsWhenAskedSizeGreaterOrEqualThanThan100() + { + $this->assertEquals('This is a test paragraph. It has three sentences. Exactly three.', TestableLorem::text(100)); } public function testSentenceWithZeroNbWordsReturnsEmptyString() @@ -55,9 +69,19 @@ class LoremTest extends \PHPUnit_Framework_TestCase class TestableLorem extends Lorem { - public static function paragraph($nbSentences = 3) + + public static function word() { - // 25 characters - return 'This is a test paragraph.'; + return 'word'; + } + + public static function sentence($nbWords = 5, $variableNbWords = true) + { + return 'This is a test sentence.'; + } + + public static function paragraph($nbSentences = 3, $variableNbSentences = true) + { + return 'This is a test paragraph. It has three sentences. Exactly three.'; } } \ No newline at end of file