From 665bb5e9c964fbfb02afe072397fcd92db51d9cb Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Wed, 13 Aug 2014 12:20:09 +0100 Subject: [PATCH] Initial commit --- .gitignore | 4 ++ app/config/sculpin_kernel.yml | 5 ++ app/config/sculpin_site.yml | 25 +++++++ sculpin.json | 11 +++ sculpin.lock | 39 +++++++++++ source/api.md | 9 +++ source/contributing.md | 42 ++++++++++++ source/index.md | 15 ++++ source/installing.md | 18 +++++ source/license.md | 11 +++ source/upgrading-1.5.md | 28 ++++++++ source/upgrading-1.6.md | 22 ++++++ source/upgrading-2.0.md | 115 +++++++++++++++++++++++++++++++ source/upgrading-intro.md | 9 +++ source/usage-creating.md | 17 +++++ source/usage-definitions.md | 11 +++ source/usage-deleting.md | 16 +++++ source/usage-examples.md | 63 +++++++++++++++++ source/usage-exceptions.md | 13 ++++ source/usage-facade.md | 9 +++ source/usage-generators.md | 126 ++++++++++++++++++++++++++++++++++ source/usage-intro.md | 9 +++ source/usage-more.md | 12 ++++ 23 files changed, 629 insertions(+) create mode 100644 .gitignore create mode 100644 app/config/sculpin_kernel.yml create mode 100644 app/config/sculpin_site.yml create mode 100644 sculpin.json create mode 100644 sculpin.lock create mode 100644 source/api.md create mode 100644 source/contributing.md create mode 100644 source/index.md create mode 100644 source/installing.md create mode 100644 source/license.md create mode 100644 source/upgrading-1.5.md create mode 100644 source/upgrading-1.6.md create mode 100644 source/upgrading-2.0.md create mode 100644 source/upgrading-intro.md create mode 100644 source/usage-creating.md create mode 100644 source/usage-definitions.md create mode 100644 source/usage-deleting.md create mode 100644 source/usage-examples.md create mode 100644 source/usage-exceptions.md create mode 100644 source/usage-facade.md create mode 100644 source/usage-generators.md create mode 100644 source/usage-intro.md create mode 100644 source/usage-more.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..46a53d6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/.sculpin/ +/output_*/ +/source/themes/ +sculpin.phar diff --git a/app/config/sculpin_kernel.yml b/app/config/sculpin_kernel.yml new file mode 100644 index 0000000..c96e8a0 --- /dev/null +++ b/app/config/sculpin_kernel.yml @@ -0,0 +1,5 @@ +sculpin: + exclude: + - sass/ +sculpin_theme: + theme: thephpleague/thephpleague.github.com \ No newline at end of file diff --git a/app/config/sculpin_site.yml b/app/config/sculpin_site.yml new file mode 100644 index 0000000..c279c9a --- /dev/null +++ b/app/config/sculpin_site.yml @@ -0,0 +1,25 @@ +title: Factory Muffin +tagline: Enables The Rapid Creation Of Objects For Testing +description: Enables The Rapid Creation Of Objects For Testing +menu: + 'Getting Started': + 'Introduction': '/' + 'Installing': '/installing/' + 'Contributing': '/contributing/' + 'Credits & License': '/license/' + 'API Docs': '/api/' + 'Usage Guide': + 'Introduction': '/usage/' + 'The Facade': '/usage/facade/' + 'Factory Definitions': '/usage/definitions/' + 'Generators': '/usage/generators/' + 'Creating & Seeding': '/usage/creating/' + 'Deleting': '/usage/deleting/' + 'Exceptions': '/usage/exceptions/' + 'Real Examples': '/usage/examples/' + 'Further Information': '/usage/more/' + 'Upgrade Guide': + 'Introduction': '/upgrading/' + '1.6.x to 2.0.x': '/upgrading/2.0/' + '1.5.x to 1.6.x': '/upgrading/1.6/' + '1.4.x to 1.5.x': '/upgrading/1.5/' diff --git a/sculpin.json b/sculpin.json new file mode 100644 index 0000000..c343f37 --- /dev/null +++ b/sculpin.json @@ -0,0 +1,11 @@ +{ + "require": { + "thephpleague/thephpleague.github.com": "dev-project-website-theme" + }, + "repositories": [ + { + "type": "vcs", + "url": "git@github.com:thephpleague/thephpleague.github.com.git" + } + ] +} \ No newline at end of file diff --git a/sculpin.lock b/sculpin.lock new file mode 100644 index 0000000..fb89645 --- /dev/null +++ b/sculpin.lock @@ -0,0 +1,39 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file" + ], + "hash": "2d9ba092767514b1d4a45d2b577545a3", + "packages": [ + { + "name": "thephpleague/thephpleague.github.com", + "version": "dev-project-website-theme", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/thephpleague.github.com.git", + "reference": "cf7fbf8e665dd77bccc40a086fde04e2c96796fc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/thephpleague.github.com/zipball/cf7fbf8e665dd77bccc40a086fde04e2c96796fc", + "reference": "cf7fbf8e665dd77bccc40a086fde04e2c96796fc", + "shasum": "" + }, + "type": "sculpin-theme", + "description": "A Sculpin based theme for the proejct websites of The League of Extraordinary Packages.", + "support": { + "source": "https://github.com/thephpleague/thephpleague.github.com/tree/project-website-theme", + "issues": "https://github.com/thephpleague/thephpleague.github.com/issues" + }, + "time": "2014-02-27 17:29:01" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": { + "thephpleague/thephpleague.github.com": 20 + }, + "platform": [], + "platform-dev": [] +} diff --git a/source/api.md b/source/api.md new file mode 100644 index 0000000..6bd2eb2 --- /dev/null +++ b/source/api.md @@ -0,0 +1,9 @@ +--- +layout: layout +title: API Docs +permalink: /api/ +--- + +# API Docs + +This is a place holder for the real api docs. diff --git a/source/contributing.md b/source/contributing.md new file mode 100644 index 0000000..1580efe --- /dev/null +++ b/source/contributing.md @@ -0,0 +1,42 @@ +--- +layout: layout +title: Contributing +permalink: /contributing/ +--- + +# Contributing + +Welcome to the contribution guide for Factory Muffin. Contributions are welcome, and are accepted via pull requests. Please review these guidelines before submitting any pull requests. + +## Which Branch? + +* Please submit all pull requests for new features to the master branch. +* Please submit pull requests for bug fixes and typos to the earliest branch the issue can be found in. + +## Guidelines + +* Please follow the [PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md) and [PHP-FIG Naming Conventions](https://github.com/php-fig/fig-standards/blob/master/bylaws/002-psr-naming-conventions.md). +* Ensure that the current tests pass, and if you've added something new, add the tests where relevant. +* Remember that we follow [SemVer](http://semver.org). If you are changing the behaviour, or the public api, you may need to update the docs. +* Send a coherent commit history, making sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please [squash](http://git-scm.com/book/en/Git-Tools-Rewriting-History) them before submitting. +* You may also need to [rebase](http://git-scm.com/book/en/Git-Branching-Rebasing) to avoid merge conflicts. + +## Running Tests + +You will need an install of [Composer](https://getcomposer.org) before continuing. + +First, install the dependencies: + +```bash +$ composer install +``` + +Then run phpunit: + +```bash +$ vendor/bin/phpunit +``` + +If the test suite passes on your local machine you should be good to go. + +When you make a pull requests the tests will automatically be run again by [Travis CI](https://travis-ci.org/) on multiple php versions and hhvm. diff --git a/source/index.md b/source/index.md new file mode 100644 index 0000000..13fb778 --- /dev/null +++ b/source/index.md @@ -0,0 +1,15 @@ +--- +layout: layout +--- + +# Introduction + + + +The goal of this package is to enable the rapid creation of objects for the purpose of testing. + +It's basically a "[factory\_girl](https://github.com/thoughtbot/factory_girl)", simplified for use with PHP. diff --git a/source/installing.md b/source/installing.md new file mode 100644 index 0000000..68c280c --- /dev/null +++ b/source/installing.md @@ -0,0 +1,18 @@ +--- +layout: layout +title: Installing +permalink: /installing/ +--- + +# Installing + +[PHP](https://php.net) 5.3+ and [Composer](https://getcomposer.org) are required. + +In your composer.json, simply add `"league/factory-muffin": "~2.0"` to your `"require-dev"` section: +```json +{ + "require-dev": { + "league/factory-muffin": "~2.0" + } +} +``` diff --git a/source/license.md b/source/license.md new file mode 100644 index 0000000..8d762e2 --- /dev/null +++ b/source/license.md @@ -0,0 +1,11 @@ +--- +layout: layout +title: Credits and License +permalink: /license/ +--- + +# Credits and License + +Factory Muffin is based on [Zizaco Zizuini](https://github.com/Zizaco)'s original work on "Factory Muff", and is currently maintained by [Scott Robertson](https://github.com/scottrobertson) and [Graham Campbell](https://github.com/GrahamCampbell). Thank you to all our wonderful [contributors](https://github.com/thephpleague/factory-muffin/contributors) too. + +Factory Muffin is licensed under [The MIT License (MIT)](https://github.com/thephpleague/factory-muffin/blob/2.0/LICENSE). diff --git a/source/upgrading-1.5.md b/source/upgrading-1.5.md new file mode 100644 index 0000000..4e30d78 --- /dev/null +++ b/source/upgrading-1.5.md @@ -0,0 +1,28 @@ +--- +layout: layout +title: Upgrading from 1.4.x to 1.5.x +permalink: /upgrading/1.5/ +--- + +# Upgrading from 1.4.x to 1.5.x + +## Exceptions + +We've added some exceptions for certain events: +* The `Zizaco\FactoryMuff\SaveException` will now be thrown on model creation if the save function returns false. +* The `Zizaco\FactoryMuff\NoDefinedFactoryException` will now be thrown if you attempt to generate attributes for an model that has no defined factory. Previously, php would raise a fatal error. + +## Factory Definitions + +Instead of having a `public static $factory = array('foo' => 'bar')` property on your model, you should call `Zizaco\FactoryMuff\Facade\FactoryMuff::define('Fully\Qualifed\ModelName', array('foo' => 'bar'))` to define your model's factory. Note that the property on the model is still supported for now, but is deprecated, and will be removed in 2.0. + +## Installing This Version + +In your composer.json, add: +```json +{ + "require-dev": { + "league/factory-muffin": "1.5.*" + } +} +``` diff --git a/source/upgrading-1.6.md b/source/upgrading-1.6.md new file mode 100644 index 0000000..cca3ee3 --- /dev/null +++ b/source/upgrading-1.6.md @@ -0,0 +1,22 @@ +--- +layout: layout +title: Upgrading from 1.5.x to 1.6.x +permalink: /upgrading/1.6/ +--- + +# Upgrading from 1.5.x to 1.6.x + +## Faker Usage + +* We now use the faker package, so our `Zizaco\FactoryMuff\Wordlist` class has been removed. All your previous definitions should still work in as close to the same way as possible, but watch out for any minor differences. With the addition of the faker library, far more definitions are now possible since any definitions not natively provided by us, fall back to the faker package. Also, it should be noted you may use closures now to generate completely custom attributes. The new classes can be found under the `Zizaco\FactoryMuff\Kind` namespace. + +## Installing This Version + +In your composer.json, add: +```json +{ + "require-dev": { + "league/factory-muffin": "1.6.*" + } +} +``` diff --git a/source/upgrading-2.0.md b/source/upgrading-2.0.md new file mode 100644 index 0000000..b864562 --- /dev/null +++ b/source/upgrading-2.0.md @@ -0,0 +1,115 @@ +--- +layout: layout +title: Upgrading from 1.6.x to 2.0.x +permalink: /upgrading/2.0/ +--- + +# Upgrading from 1.6.x to 2.0.x + +## Introduction + +Version 2.0 marks a major file milestone in this project, under the new name of "Factory Muffin". We see a large number of improvements and some breaking changes. Within this section of the upgrading guide, you will see "the `xyz` function can be called". You should assume that these functions should be called statically on the `League\FactoryMuffin\Facade` class. + +## Class Name Changes + +Every class has moved, so here's a summary of the changes: +* The root namespace has been moved from `Zizaco\FactoryMuff` to `League\FactoryMuffin`. You should now access the facade using `League\FactoryMuffin\Facade::fooBar()`. +* Many generator (kind) classes have been removed in favour of the faker alternatives. Those remaining can be found under the `League\FactoryMuffin\Generators` namespace. +* There are many more exceptions, and the names of the existing exceptions have changed. The exceptions can be found under the `League\FactoryMuffin\Exceptions` namespace. + +A detailed list of every change with FQCNs is listed below: +* Moved: `Zizaco\FactoryMuff\FactoryMuff` => `League\FactoryMuffin\Factory` +* Moved: `Zizaco\FactoryMuff\Facade\FactoryMuff` => `League\FactoryMuffin\Facade` +* Moved: `Zizaco\FactoryMuff\SaveException` => `League\FactoryMuffin\Exceptions\SaveFailedException` +* Moved: `Zizaco\FactoryMuff\NoDefinedFactoryException` => `League\FactoryMuffin\Exceptions\NoDefinedFactoryException` +* Moved: `Zizaco\FactoryMuff\Kind` => `League\FactoryMuffin\Generators\Base` +* Moved: `Zizaco\FactoryMuff\Kind\Call` => `League\FactoryMuffin\Generators\Call` +* Moved: `Zizaco\FactoryMuff\Kind\Closure` => `League\FactoryMuffin\Generators\Closure` +* Moved: `Zizaco\FactoryMuff\Kind\Factory` => `League\FactoryMuffin\Generators\Factory` +* Moved: `Zizaco\FactoryMuff\Kind\Generic` => `League\FactoryMuffin\Generators\Generic` +* Added: `League\FactoryMuffin\Exceptions\DeleteFailedException` +* Added: `League\FactoryMuffin\Exceptions\DeleteMethodNotFoundException` +* Added: `League\FactoryMuffin\Exceptions\DeletingFailedException` +* Added: `League\FactoryMuffin\Exceptions\DirectoryNotFoundException` +* Added: `League\FactoryMuffin\Exceptions\MethodNotFoundException` +* Added: `League\FactoryMuffin\Exceptions\ModelException` +* Added: `League\FactoryMuffin\Exceptions\SaveMethodNotFoundException` +* Removed: `Zizaco\FactoryMuff\Kind\Date` +* Removed: `Zizaco\FactoryMuff\Kind\Integer` +* Removed: `Zizaco\FactoryMuff\Kind\Name` +* Removed: `Zizaco\FactoryMuff\Kind\String` +* Removed: `Zizaco\FactoryMuff\Kind\Text` + +It also should be noted that we've moved from PSR-0 to PSR-4 for autoloading. + +## Facade Changes + +Under it's new name, the facade class now uses `__callStatic` to dynamically call the underlying factory instance. Also, note that all public methods that would have returned void, return the factory instance in order to support method chaining. + +## Factory Definitions + +Having a public static factory property is no longer supported. You must use the `define` function introduced in the 1.5.x series. You may call it like this: `League\FactoryMuffin\Facade::define('Fully\Qualifed\ModelName', array('foo' => 'bar'))`. We have provided a nifty way for you to do this in your tests. PHPUnit provides a `setupBeforeClass` function. Within that function you can call `League\FactoryMuffin\Facade::loadFactories(__DIR__ . '/factories');`, and it will include all files in the factories folder. Within those php files, you can put your definitions (all your code that calls the define function). The `loadFactories` function will throw a `League\FactoryMuffin\Exceptions\DirectoryNotFoundException` exception if the directory you're loading is not found. A full example is included in the readme. + +## Generator (Kind) Changes + +We now refer to what was previously the kind classes, as generator classes. We've removed some of these in favour of the faker alternatives. We currently provide the following generators: `Call`, `Closure`, `Factory`, and `Generic`. The call, closure, and factory generators have not changed significantly since previous versions, and the generic generator still provides access to the faker generators. The closure generator will now pass the instance of your model into your closure as the first parameter too. + +There are two syntax changes to watch out for: +* You can now use a `;` to send multiple arguments to the generators. +* Unique and optional attributes are now supported by prefixing the definition with `unique:` or `optional:`. + +The removed generators are `Date`, `Integer`, `Name`, `String`, and `Text`, however, these are still callable as they are available through the generic generator using faker. Here are some possible changes you will need to make: +* Instead of using `integer|8`, you can use `randomNumber|8`. +* Instead of using `string`, you can use `sentence`, or `word`. +* Instead of using `name`, you can use things like `firstNameMale`. +* `date` and `text` can be used in the same way you were using them before. + +It should be noted that we are using faker 1.4 which is a change since the previous release. We've made a more strict version requirement to avoid potential BC breaks caused by faker. + +## Creating And Seeding + +The `create` function can be called in the same way, but has internal improvements. Now, it will also save anything you generate with the `Factory` generator too. We now have a new function called `seed`, which accepts an additional argument at the start which is the number of models to generate in the process. The `seed` function will effectively be calling the `create` function over and over. It should be noted that you can set a custom save function before you get going with the `setSaveMethod` function. Also, a reminder that the `instance` function is still available if you don't want database persistence. + +You may encounter the following exceptions: +* `League\FactoryMuffin\Exceptions\NoDefinedFactoryException` will be thrown if you try to create a model and you haven't defined a factory definition for it earlier. +* `League\FactoryMuffin\Exceptions\SaveFailedException` will be thrown if the save function on your model returns false. +* `League\FactoryMuffin\Exceptions\SaveMethodNotFoundException` will be thrown if the save function on your model does not exist. +* Any other exception thrown by your model while trying to create or save it. + +There are 2 other helper functions available. You may call `saved` to return an array of all the saved objects. You may call `isSaved` with an instance of a model to check if it's saved. + +## Deleting + +You can now delete all your saved models with the `deleteSaved` function. It should be noted that you can set a custom delete function before you get going with the `setDeleteMethod` function. + +If one or more models cannot be deleted, a `League\FactoryMuffin\Exceptions\DeletingFailedException` will be raised after we have attempted to delete all the saved models. You may access each underlying exception, in the order they were thrown during the whole process, with the `getExceptions` function which will return an array of exceptions. You may encounter the following exceptions: +* `League\FactoryMuffin\Exceptions\DeleteFailedException` will be thrown if the delete function on your model returns false. +* `League\FactoryMuffin\Exceptions\DeleteMethodNotFoundException` will be thrown if the delete function on your model does not exist. +* Any other exception thrown by your model while trying to delete it. + +It's recommended that you call the `deleteSaved` function from PHPUnit's `tearDownAfterClass` function. A full example is included in the readme. + +## Exceptions + +The exceptions have been completely overhauled. Each exception is documented with the documentation for the functions that throw them. + +You can see a diagram showing the exception hierarchy here: + +![diagram](https://cloud.githubusercontent.com/assets/2829600/3790579/8fc52572-1b0d-11e4-96b1-7f0eac0dc10d.png) + +## Other BC Breaks + +The `attributesFor` function no longer accepts a class name as the first argument, and the `generateAttr` function no longer accepts a class name as a second argument. Please pass an actual model instance to both functions instead. + +We now require php 5.3.3 as a minimum version. This is an increase on our previous requirement of php 5.3.0. + +## Installing This Version + +In your composer.json, add: +```json +{ + "require-dev": { + "league/factory-muffin": "2.0.*" + } +} +``` diff --git a/source/upgrading-intro.md b/source/upgrading-intro.md new file mode 100644 index 0000000..2b4a683 --- /dev/null +++ b/source/upgrading-intro.md @@ -0,0 +1,9 @@ +--- +layout: layout +title: Upgrading +permalink: /upgrading/ +--- + +# Upgrading + +Welcome to the upgrade guide for Factory Muffin. We've tried to cover all changes from 1.4 through to the current release. If we've missed anything, feel free to create an issue, or send a pull request. From 2.0, we are following the PSR-2 coding standard, and semantic versioning, so there will be no BC breaks until 3.0 other than essential fixes, and any changes will be documented here. diff --git a/source/usage-creating.md b/source/usage-creating.md new file mode 100644 index 0000000..edda08b --- /dev/null +++ b/source/usage-creating.md @@ -0,0 +1,17 @@ +--- +layout: layout +title: Usage - Creating & Seeding +permalink: /usage/creating/ +--- + +# Usage - Creating & Seeding + +The `create` function will create and save your model, and will also save anything you generate with the `Factory` generator too. If you want to create multiple instances, check out the seed `seed` function, which accepts an additional argument at the start which is the number of models to generate in the process. The `seed` function will effectively be calling the `create` function over and over. It should be noted that you can set a custom save function before you get going with the `setSaveMethod` function. Also, a reminder that the `instance` function is still available if you don't want database persistence. + +You may encounter the following exceptions: +* `League\FactoryMuffin\Exceptions\NoDefinedFactoryException` will be thrown if you try to create a model and you haven't defined a factory definition for it earlier. +* `League\FactoryMuffin\Exceptions\SaveFailedException` will be thrown if the save function on your model returns false. +* `League\FactoryMuffin\Exceptions\SaveMethodNotFoundException` will be thrown if the save function on your model does not exist. +* Any other exception thrown by your model while trying to create or save it. + +There are 2 other helper functions available. You may call `saved` to return an array of all the saved objects. You may call `isSaved` with an instance of a model to check if it's saved. diff --git a/source/usage-definitions.md b/source/usage-definitions.md new file mode 100644 index 0000000..509e077 --- /dev/null +++ b/source/usage-definitions.md @@ -0,0 +1,11 @@ +--- +layout: layout +title: Usage - Factory Definitions +permalink: /usage/definitions/ +--- + +# Usage - Factory Definitions + +You can define model factories using the `define` function. You may call it like this: `League\FactoryMuffin\Facade::define('Fully\Qualifed\ModelName', array('foo' => 'bar'))`, where `foo` is the name of the attribute you want set on your model, and `bar` describes how you wish to generate the attribute. Please see the generators section for more information on how this works. + +We have provided a nifty way for you to do this in your tests. PHPUnit provides a `setupBeforeClass` function. Within that function you can call `League\FactoryMuffin\Facade::loadFactories(__DIR__ . '/factories');`, and it will include all files in the factories folder. Within those php files, you can put your definitions (all your code that calls the define function). The `loadFactories` function will throw a `League\FactoryMuffin\Exceptions\DirectoryNotFoundException` exception if the directory you're loading is not found. diff --git a/source/usage-deleting.md b/source/usage-deleting.md new file mode 100644 index 0000000..cd2c4b7 --- /dev/null +++ b/source/usage-deleting.md @@ -0,0 +1,16 @@ +--- +layout: layout +title: Usage - Deleting +permalink: /usage/deleting/ +--- + +# Usage - Deleting + +You can delete all your saved models with the `deleteSaved` function. It should be noted that you can set a custom delete function before you get going with the `setDeleteMethod` function. + +If one or more models cannot be deleted, a `League\FactoryMuffin\Exceptions\DeletingFailedException` will be raised after we have attempted to delete all the saved models. You may access each underlying exception, in the order they were thrown during the whole process, with the `getExceptions` function which will return an array of exceptions. You may encounter the following exceptions: +* `League\FactoryMuffin\Exceptions\DeleteFailedException` will be thrown if the delete function on your model returns false. +* `League\FactoryMuffin\Exceptions\DeleteMethodNotFoundException` will be thrown if the delete function on your model does not exist. +* Any other exception thrown by your model while trying to delete it. + +It's recommended that you call the `deleteSaved` function from PHPUnit's `tearDownAfterClass` function. diff --git a/source/usage-examples.md b/source/usage-examples.md new file mode 100644 index 0000000..fbd0c91 --- /dev/null +++ b/source/usage-examples.md @@ -0,0 +1,63 @@ +--- +layout: layout +title: Usage - Real Examples +permalink: /usage/examples/ +--- + +# Usage - Real Examples + +To start with, we need to create some definitions: +```php +# tests/factories/all.php + +use League\FactoryMuffin\Facade as FactoryMuffin; + +FactoryMuffin::define('Message', array( + 'user_id' => 'factory|User', + 'subject' => 'sentence', + 'message' => 'text', + 'phone_number' => 'randomNumber|8', + 'created' => 'date|Ymd h:s', + 'slug' => 'call|makeSlug|word', +)); + +FactoryMuffin::define('User', array( + 'username' => 'firstNameMale', + 'email' => 'email', + 'avatar' => 'imageUrl|400;600', + 'greeting' => RandomGreeting::get(), + 'four' => function() { + return 2 + 2; + }, +)); +``` + +You can then use these factories in your tests: +```php +# tests/TestUserModel.php + +use League\FactoryMuffin\Facade as FactoryMuffin; + +class TestUserModel extends PHPUnit_Framework_TestCase +{ + public static function setupBeforeClass() + { + // note that method chaining is supported + FactoryMuffin::setFakerLocale('en_EN')->setSaveMethod('save'); // optional step + FactoryMuffin::loadFactories(__DIR__ . '/factories'); + } + + public function testSampleFactory() + { + $message = FactoryMuffin::create('Message'); + $this->assertInstanceOf('Message', $message); + $this->assertInstanceOf('User', $message->user); + } + + public static function tearDownAfterClass() + { + FactoryMuffin::setDeleteMethod('delete'); // optional step + FactoryMuffin::deleteSaved(); + } +} +``` diff --git a/source/usage-exceptions.md b/source/usage-exceptions.md new file mode 100644 index 0000000..978416b --- /dev/null +++ b/source/usage-exceptions.md @@ -0,0 +1,13 @@ +--- +layout: layout +title: Usage - Exceptions +permalink: /usage/exceptions/ +--- + +# Usage - Exceptions + +Each exception is documented with the documentation for the functions that throw them. + +You can see a diagram showing the exception hierarchy here: + +![diagram](https://cloud.githubusercontent.com/assets/2829600/3790579/8fc52572-1b0d-11e4-96b1-7f0eac0dc10d.png) diff --git a/source/usage-facade.md b/source/usage-facade.md new file mode 100644 index 0000000..ea0757e --- /dev/null +++ b/source/usage-facade.md @@ -0,0 +1,9 @@ +--- +layout: layout +title: Usage - The Facade +permalink: /usage/facade/ +--- + +# Usage - The Facade + +The facade class (`League\FactoryMuffin\Facade`) should always be your main point of entry for communicating with Factory Muffin. It will dynamically proxy static method calls to the underlying factory instance. The other classes, including the factory class (`League\FactoryMuffin\Factory`), are not intended for direct public use. Also, note that all public methods that would have returned void, return the factory instance in order to support method chaining. diff --git a/source/usage-generators.md b/source/usage-generators.md new file mode 100644 index 0000000..e8cf4cb --- /dev/null +++ b/source/usage-generators.md @@ -0,0 +1,126 @@ +--- +layout: layout +title: Usage - Generators +permalink: /usage/generators/ +--- + +# Usage - Generators + +## Generic + +The generic generator will be the generator you use the most. It will communicate with the faker library in order to generate your attribute. + +### Example 1 + +There is a simple example of setting a few different attributes. +```php +League\FactoryMuffin\Facade::define('MyModel', array( + 'foo' => 'word', // Set the foo attribute to a random word + 'name' => 'firstNameMale', // Set the name attribute to a random male first name + 'email' => 'email', // Set the email attribute to a random email address + 'body' => 'text', // Set the body attribute to a random string of text + 'slogan' => 'sentence', // Set the slogan attribute to a random sentence +)); +``` + +### Example 2 + +This will set the `age` attribute to a random number between 20 and 40. Note how we're using the `;` here to pass multiple arguments to the faker method. +```php +League\FactoryMuffin\Facade::define('MyModel', array( + 'age' => 'numberBetween|20;40', +)); +``` + +### Example 3 + +This will set the `name` attribute to a random female first name. It will ensure that it is unique between all your generated models. +```php +League\FactoryMuffin\Facade::define('MyModel', array( + 'name' => 'unique:firstNameFemale', +)); +``` + +### Example 4 + +This will set the `profile_pic` attribute to a random image url of dimensions 400 by 400. Because we've added the optional flag at the start, not all the generated models will have an image url set; sometimes we will return null. +```php +League\FactoryMuffin\Facade::define('MyModel', array( + 'profile_pic' => 'optional:imageUrl|400;400', +)); +``` + +### More + +Check out the [faker library](https://github.com/fzaninotto/Faker) itself to see all the available methods. There are far too many to cover in the documentation here, and far too many for them to cover in their documentation too. + +## Factory + +The factory generator can be useful for setting up relationships between models. The factory generator will return the model id of the model you ask it to generate. + +### Example 1 + +When we create a Foo object, we will find that the Bar object will been generated and saved too, and it's id will be assigned to the `bar_id` attribute of the Foo model. +```php +League\FactoryMuffin\Facade::define('Foo', array( + 'bar_id' => 'factory|Bar' +)); + +League\FactoryMuffin\Facade::define('Bar', array( + 'baz' => 'date|Y-m-d' +)); +``` + +## Call + +The call generator allows you to generate attributes by calling **static** methods on your models. + +### Example 1 + +This will set the `foo` attribute to whatever calling `MyModel::exampleMethod()` returns. +```php +League\FactoryMuffin\Facade::define('MyModel', array( + 'foo' => 'call|exampleMethod', +)); +``` + +### Example 2 + +This will set the `bar` attribute to whatever calling `MyModel::anotherMethod('hello')` returns. +```php +League\FactoryMuffin\Facade::define('MyModel', array( + 'bar' => 'call|anotherMethod|hello', +)); +``` + +### Example 3 + +This will set the `baz` attribute to whatever calling the `exampleMethod` method on the `OtherModel` after we generate and save it. +```php +League\FactoryMuffin\Facade::define('MyModel', array( + 'baz' => 'call|exampleMethod|factory|OtherModel', +)); + +League\FactoryMuffin\Facade::define('OtherModel', array( + 'example' => 'boolean', +)); +``` + +## Closure + +The closure generator can be used if you want a more custom solution. Whatever you return from the closure you write will be set as the attribute. Note that we pass an instance of your model as the first parameter of the closure to give you even more flexibility to modify it as you wish. + +### Example 1 + +As you can see from this example, the ability to use a closure to generate attributes can be so useful and flexible. Here we use it to generate a slug based on the initially randomly generated 5 word long title. +```php +League\FactoryMuffin\Facade::define('MyModel', array( + 'title' => 'sentence|5', + 'slug' => function ($object) { + $slug = preg_replace("/[^a-zA-Z0-9\/_|+ -]/", '', $object->title); + $slug = strtolower(trim($slug, '-')); + $slug = preg_replace("/[\/_|+ -]+/", '-', $slug); + + return $slug; + }, +)); diff --git a/source/usage-intro.md b/source/usage-intro.md new file mode 100644 index 0000000..352c83b --- /dev/null +++ b/source/usage-intro.md @@ -0,0 +1,9 @@ +--- +layout: layout +title: Usage - Introduction +permalink: /usage/ +--- + +# Usage - Introduction + +This is the usage guide for Factory Muffin 2.0. Within this guide, you will see "the `xyz` function can be called". You should assume that these functions should be called statically on the `League\FactoryMuffin\Facade` class. It should also be noted that you can see a real example at the end of the guide. diff --git a/source/usage-more.md b/source/usage-more.md new file mode 100644 index 0000000..a38ca97 --- /dev/null +++ b/source/usage-more.md @@ -0,0 +1,12 @@ +--- +layout: layout +title: Usage - Further Information +permalink: /usage/more/ +--- + +# Usage - Further Information + +If you want more information, the following resources are available to you: + * Generated api docs are available [here](http://factory-muffin.thephpleague.com/api/). + * [Philip Brown's](https://github.com/philipbrown) article is available [here](http://culttt.com/2013/05/27/laravel-4-fixture-replacement-with-factorymuff/). + * Our [test suite](https://github.com/thephpleague/factory-muffin/tree/2.0/tests) may also be useful to you.