commit 1de1d8a39fd89c1ab84cb352926e31bc6446b02a Author: Francois Zaninotto Date: Sat Oct 15 00:49:26 2011 +0200 first commit diff --git a/readme.md b/readme.md new file mode 100644 index 00000000..a8dc7eb9 --- /dev/null +++ b/readme.md @@ -0,0 +1,250 @@ +# Faker + +Faker is a PHP library that generates fake data for you. Whether you need to bootstrap your database, create good-looking XML documents, fill-in your persistence to stress test it, or anonymize data taken from a production service, Faker is for you. + +Faker is heavily inspired by Perl's [Data::Faker](http://search.cpan.org/~jasonk/Data-Faker-0.07/), and by ruby's [Faker](http://faker.rubyforge.org/). + +Faker requires PHP >= 5.3. + +## Usage + +Faker offers a `Generator` object for all data generation. Prior to using a generator, you must add providers to it, to give the generator the ability to generate certain types of data. Here is the usual setup: + +```php +addProvider(new Faker\Provider\Name($generator)); +$generator->addProvider(new Faker\Provider\Address($generator)); +$generator->addProvider(new Faker\Provider\PhoneNumber($generator)); +$generator->addProvider(new Faker\Provider\Company($generator)); +$generator->addProvider(new Faker\Provider\Lorem($generator)); +``` + +Once it's initialized, a `Generator` object generates data by calling the type of data you want as a property. + +```php +name; + // 'Lucy Cechtelar'; +echo $generator->address; + // "426 Jordy Lodge + // Cartwrightshire, SC 88120-6700" +echo $generator->lorem; + // Sint velit eveniet. Rerum atque repellat voluptatem quia rerum. Numquam excepturi beatae sint laudantium consequatur. Magni occaecati itaque sint et sit tempore. Nesciunt amet quidem. Iusto deleniti cum autem ad quia aperiam. + // A consectetur quos aliquam. In iste aliquid et aut similique suscipit. Consequatur qui quaerat iste minus hic expedita. Consequuntur error magni et laboriosam. Aut aspernatur voluptatem sit aliquam. Dolores voluptatum est. + // Aut molestias et maxime. Fugit autem facilis quos vero. Eius quibusdam possimus est. +Ea quaerat et quisquam. Deleniti sunt quam. Adipisci consequatur id in occaecati. Et sint et. Ut ducimus quod nemo ab voluptatum. +``` + +## Providers + +Bundled providers offer many data types: + +* Address +* Company +* Lorem +* Name +* PhoneNumber + +## Real Life Usage + +The following script generates a valid XML document: + +```php + + + + + + + country ?> + +
+ streetAddress ?> + city ?> + postcode ?> + state ?> +
+ + + bs ?> + + + + + + +
+ lorem(3) ?>]]> +
+ +
+ +
+``` + +When you run this script, you end up with a document looking like: + +```xml + + + + +
+ 09678 Douglas Throughway + Cronaville + 97573-1273 + Wisconsin +
+ + enhance scalable vortals + + +
+ +
+
+ + +
+ 413 Harber Street Apt. 536 + Port Kaleighport + 16436 + Oregon +
+ + +
+ + +
+ 034 Pollich Fords Suite 763 + Port Cloydberg + 95235 + NewHampshire +
+ + +
+ + + Pitcairn Islands +
+ 70028 Wisoky Wall + Tremblayberg + 59624-3945 + Ohio +
+ + unleash front-end deliverables + + +
+ +
+
+ + +
+ 5208 Celia Route Suite 082 + Port Albin + 91670-9099 + Wisconsin +
+ + +
+ + +
+ 692 Nelda Branch + North Shaina + 40220 + Nebraska +
+ + exploit sexy models + + +
+ + +
+ 620 Watsica Extension + Quigleybury + 31688-4724 + Alaska +
+ + +
+ + +
+ 026 Florian Lights Apt. 130 + North Mireille + 68929 + Maryland +
+ + cultivate rich infomediaries + +
+ + +
+ 485 Imani Falls Suite 202 + Marvinbury + 12186-1993 + WestVirginia +
+ + streamline granular users + + +
+ +
+
+ + + Italy +
+ 36949 Weissnat Cape + Swiftfort + 80494 + WestVirginia +
+ + +
+
+``` + +## License + +Faker is released under the MIT Licence. + +Copyright (c) 2011 François Zaninotto +Portions Copyright (c) 2008 Caius Durling +Portions Copyright (c) 2008 Adam Royle +Portions Copyright (c) 2008 Fiona Burrows + +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. \ No newline at end of file diff --git a/src/Generator.php b/src/Generator.php new file mode 100644 index 00000000..2444fcec --- /dev/null +++ b/src/Generator.php @@ -0,0 +1,127 @@ +providers[]= $providers; + } + + public function format($formatter, $arguments = array()) + { + return call_user_func_array($this->getFormatter($formatter), $arguments); + } + + /** + * @return Callable + */ + public function getFormatter($formatter) + { + if (isset($this->formatters[$formatter])) { + return $this->formatters[$formatter]; + } + foreach ($this->providers as $provider) { + if (method_exists($provider, $formatter)) { + $this->formatters[$formatter] = array($provider, $formatter); + return $this->formatters[$formatter]; + } + } + throw new \InvalidArgumentException(sprintf('Unknown formatter "%s"', $formatter)); + } + + /** + * Returns a random number between 0 and 9 + * + * @return integer + */ + public static function randomDigit() + { + return mt_rand(0, 9); + } + + /** + * Returns a random letter from a to z + * + * @return string + */ + public static function randomLetter() + { + return chr(mt_rand(97, 122)); + } + + /** + * Returns a random element from a passed array + * + * @param array $array + * @return mixed + */ + public static function randomElement($array) + { + return $array[array_rand($array)]; + } + + /** + * Replaces all hash sign ('#') occurrences with a random number + * + * @param string $string String that needs to bet parsed + * @return string + */ + public static function numerify($string) + { + return preg_replace_callback('/\#/', get_called_class() . '::randomDigit', $string); + } + + /** + * Replaces all question mark ('?') occurrences with a random letter + * + * @param string $string String that needs to bet parsed + * @return string + */ + public static function lexify($string) + { + return preg_replace_callback('/\?/', get_called_class() . '::randomLetter', $string); + } + + /** + * Replaces hash signs and question marks with random numbers and letters + * + * @param string $string String that needs to bet parsed + * @return string + */ + public static function bothify($string) + { + return self::lexify(self::numerify($string)); + } + + /** + * Replaces tokens ('{{ tokenName }}') with the result from the token method call + * + * @param string $string String that needs to bet parsed + * @return string + */ + public function parse($string) + { + return preg_replace_callback('/\{\{\s?(\w+)\s?\}\}/', array($this, 'callFormatWithMatches'), $string); + } + + protected function callFormatWithMatches($matches) + { + return $this->format($matches[1]); + } + + public function __get($attribute) + { + return $this->format($attribute); + } + + public function __call($method, $attributes) + { + return $this->format($method, $attributes); + } + +} diff --git a/src/Provider/Address.php b/src/Provider/Address.php new file mode 100644 index 00000000..260826fb --- /dev/null +++ b/src/Provider/Address.php @@ -0,0 +1,145 @@ +generator = $generator; + } + + public static function cityPrefix() + { + return self::$cityPrefix[array_rand(self::$cityPrefix)]; + } + + public static function citySuffix() + { + return self::$citySuffix[array_rand(self::$citySuffix)]; + } + + public function buildingNumber() + { + $format = self::$buildingNumber[array_rand(self::$buildingNumber)]; + return $this->generator->numerify($format); + } + + public static function streetSuffix() + { + return self::$streetSuffix[array_rand(self::$streetSuffix)]; + } + + public function city() + { + $format = self::$cityFormats[array_rand(self::$cityFormats)]; + return $this->generator->parse($format); + } + + public function streetName() + { + $format = self::$streetNameFormats[array_rand(self::$streetNameFormats)]; + return $this->generator->parse($format); + } + + public function streetAddress() + { + $format = self::$streetAddressFormats[array_rand(self::$streetAddressFormats)]; + return $this->generator->numerify($this->generator->parse($format)); + } + + public function secondaryAddress() + { + $format = self::$secondaryAddress[array_rand(self::$secondaryAddress)]; + return $this->generator->numerify($format); + } + + public function postcode() + { + $format = self::$postcode[array_rand(self::$postcode)]; + return $this->generator->numerify($format); + } + + public static function state() + { + return self::$state[array_rand(self::$state)]; + } + + public static function stateAbbr() + { + return self::$stateAbbr[array_rand(self::$stateAbbr)]; + } + + public function address() + { + $format = self::$addressFormats[array_rand(self::$addressFormats)]; + return $this->generator->parse($format); + } + + public static function country() + { + return self::$country[array_rand(self::$country)]; + } + +} \ No newline at end of file diff --git a/src/Provider/Company.php b/src/Provider/Company.php new file mode 100644 index 00000000..47e23d3d --- /dev/null +++ b/src/Provider/Company.php @@ -0,0 +1,76 @@ +generator = $generator; + } + + public function company() + { + $format = self::$formats[array_rand(self::$formats)]; + return $this->generator->parse($format); + } + + public function companySuffix() + { + return self::$companySuffix[array_rand(self::$companySuffix)];; + } + + public function catchPhrase() + { + $result = array(); + foreach (self::$catchPhraseWords as &$word) { + $result[] = $this->generator->randomElement($word); + } + + return join($result, ' '); + } + + public function bs() + { + $result = array(); + foreach (self::$bsWords as &$word) { + $result[] = $this->generator->randomElement($word); + } + + return join($result, ' '); + } +} \ No newline at end of file diff --git a/src/Provider/Lorem.php b/src/Provider/Lorem.php new file mode 100644 index 00000000..79e4f038 --- /dev/null +++ b/src/Provider/Lorem.php @@ -0,0 +1,96 @@ +generator = $generator; + } + + public function name() + { + $format = self::$formats[array_rand(self::$formats)]; + return $this->generator->parse($format); + } + + public static function firstName() + { + return self::$firstName[array_rand(self::$firstName)]; + } + + public static function lastName() + { + return self::$lastName[array_rand(self::$lastName)]; + } + + public static function prefix() + { + return self::$prefix[array_rand(self::$prefix)]; + } + + public static function suffix() + { + return self::$suffix[array_rand(self::$suffix)]; + } +} \ No newline at end of file diff --git a/src/Provider/PhoneNumber.php b/src/Provider/PhoneNumber.php new file mode 100644 index 00000000..d8beeb06 --- /dev/null +++ b/src/Provider/PhoneNumber.php @@ -0,0 +1,45 @@ +generator = $generator; + } + + public function phoneNumber() + { + return $this->generator->numerify(self::$formats[array_rand(self::$formats)]); + } +} \ No newline at end of file diff --git a/test/GeneratorTest.php b/test/GeneratorTest.php new file mode 100644 index 00000000..350d5ffb --- /dev/null +++ b/test/GeneratorTest.php @@ -0,0 +1,172 @@ +addProvider($provider); + $expected = array($provider, 'fooFormatter'); + $this->assertTrue(is_callable($generator->getFormatter('fooFormatter'))); + } + + public function testGetFormatterReturnsCorrectFormatter() + { + $generator = new Generator; + $provider = new FooProvider(); + $generator->addProvider($provider); + $expected = array($provider, 'fooFormatter'); + $this->assertEquals($expected, $generator->getFormatter('fooFormatter')); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testGetFormatterThrowsExceptionOnIncorrectProvider() + { + $generator = new Generator; + $generator->getFormatter('fooFormatter'); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testGetFormatterThrowsExceptionOnIncorrectFormatter() + { + $generator = new Generator; + $provider = new FooProvider(); + $generator->addProvider($provider); + $generator->getFormatter('barFormatter'); + } + + public function testFormatCallsFormatterOnProvider() + { + $generator = new Generator; + $provider = new FooProvider(); + $generator->addProvider($provider); + $this->assertEquals('foobar', $generator->format('fooFormatter')); + } + + public function testFormatTransfersArgumentsToFormatter() + { + $generator = new Generator; + $provider = new FooProvider(); + $generator->addProvider($provider); + $this->assertEquals('bazfoo', $generator->format('fooFormatterWithArguments', array('foo'))); + } + + public function testRandomDigitReturnsInteger() + { + $this->assertTrue(is_integer(Generator::randomDigit())); + } + + public function testRandomDigitReturnsDigit() + { + $this->assertTrue(Generator::randomDigit() >= 0); + $this->assertTrue(Generator::randomDigit() < 10); + } + + public function testRandomLetterReturnsString() + { + $this->assertTrue(is_string(Generator::randomLetter())); + } + + public function testRandomLetterReturnsSingleLetter() + { + $this->assertEquals(1, strlen(Generator::randomLetter())); + } + + public function testRandomLetterReturnsLowercaseLetter() + { + $lowercaseLetters = 'abcdefghijklmnopqrstuvwxyz'; + $this->assertTrue(strpos($lowercaseLetters, Generator::randomLetter()) !== false); + } + + public function testRandomElementReturnsElementFromArray() + { + $elements = array('23', 'e', 32, '#'); + $this->assertContains(Generator::randomElement($elements), $elements); + } + + public function testNumerifyReturnsSameStringWhenItContainsNoHashSign() + { + $this->assertEquals('fooBar?', Generator::numerify('fooBar?')); + } + + public function testNumerifyReturnsStringWithHashSignsReplacedByDigits() + { + $this->assertRegExp('/foo\dBa\dr/', Generator::numerify('foo#Ba#r')); + } + + public function testLexifyReturnsSameStringWhenItContainsNoQuestionMark() + { + $this->assertEquals('fooBar#', Generator::lexify('fooBar#')); + } + + public function testNumerifyReturnsStringWithQuestionMarksReplacedByLetters() + { + $this->assertRegExp('/foo[a-z]Ba[a-z]r/', Generator::lexify('foo?Ba?r')); + } + + public function testBothifyCombinesNumerifyAndLexify() + { + $this->assertRegExp('/foo[a-z]Ba\dr/', Generator::bothify('foo?Ba#r')); + } + + public function testParseReturnsSameStringWhenItContainsNoCurlyBraces() + { + $generator = new Generator(); + $this->assertEquals('fooBar#?', $generator->parse('fooBar#?')); + } + + public function testParseReturnsStringWithTokensReplacedByFormatters() + { + $generator = new Generator(); + $provider = new FooProvider(); + $generator->addProvider($provider); + $this->assertEquals('This is foobar a text with foobar', $generator->parse('This is {{fooFormatter}} a text with {{ fooFormatter }}')); + } + + public function testMagicGetCallsFormat() + { + $generator = new Generator; + $provider = new FooProvider(); + $generator->addProvider($provider); + $this->assertEquals('foobar', $generator->fooFormatter); + } + + public function testMagicCallCallsFormat() + { + $generator = new Generator; + $provider = new FooProvider(); + $generator->addProvider($provider); + $this->assertEquals('foobar', $generator->fooFormatter()); + } + + public function testMagicCallCallsFormatWithArguments() + { + $generator = new Generator; + $provider = new FooProvider(); + $generator->addProvider($provider); + $this->assertEquals('bazfoo', $generator->fooFormatterWithArguments('foo')); + } + +} + +class FooProvider +{ + public function fooFormatter() + { + return 'foobar'; + } + + public function fooFormatterWithArguments($value = '') + { + return 'baz' . $value; + } +} \ No newline at end of file diff --git a/test/test.php b/test/test.php new file mode 100644 index 00000000..3c9dbf2f --- /dev/null +++ b/test/test.php @@ -0,0 +1,46 @@ +addProvider(new Faker\Provider\Name($generator)); +$generator->addProvider(new Faker\Provider\Address($generator)); +$generator->addProvider(new Faker\Provider\PhoneNumber($generator)); +$generator->addProvider(new Faker\Provider\Company($generator)); +$generator->addProvider(new Faker\Provider\Lorem($generator)); +?> + + + + + + + address ?> + +
+ streetAddress ?> + city ?> + postcode ?> + state ?> +
+ + + bs ?> + + + + + + +
+ lorem(3) ?>]]> +
+ +
+ +