diff --git a/readme.md b/readme.md index 1b3af78..c265b0d 100644 --- a/readme.md +++ b/readme.md @@ -55,7 +55,7 @@ array(4) { $post = Factory::attributesFor('Post'); ``` -The difference between `build()` and `attributesFor()` is that the former will return an instance of the given model type (such as `Post`). The latter will simply return an array of the generated attributes, which can be useful in some situations. +The difference between `build()` and `attributesFor()` is that the former will return an instance of the given model type (such as `Post`). The latter will simply return an array of the generated attributes, which can be useful in some situations. ### Build and persist a song entity. @@ -211,6 +211,16 @@ use Laracasts\TestDummy\Factory; $adminUser = Factory::create('admin_user'); ``` +#### Custom Pivot Models + +If your model is a [Custom Pivot Model](http://laravel.com/docs/5.0/eloquent#working-with-pivot-tables) use TestDummy's EloquentPivotModel provider and pass through the pivot models parent and the pivot table name. Don't forget to reset the TestDummy database provider back to an Eloquent model before creating any further factories; + +``` +Factory::$databaseProvider = new Laracasts\TestDummy\EloquentPivotModel(new Post, 'post_tags'); +Factory::create('PostTag'); +Factory::$databaseProvider = new Laracasts\TestDummy\EloquentModel(); +``` + #### Defining with Closures Alternatively, you may pass a closure as the second argument to the `$factory` method. This can be useful for situations where you need a bit more control over the values that you assign to each attribute. Here's an example: @@ -218,7 +228,7 @@ Alternatively, you may pass a closure as the second argument to the `$factory` m ```php $factory('App\Artist', function($faker) { $name = sprintf('Some Band Named %s', $faker->word); - + return [ 'name' => $name ]; diff --git a/src/EloquentPivotModel.php b/src/EloquentPivotModel.php new file mode 100644 index 0000000..6db5600 --- /dev/null +++ b/src/EloquentPivotModel.php @@ -0,0 +1,88 @@ +parent = $parent; + $this->table = $table; + } + + /** + * Build the entity with attributes. + * + * @param string $type + * @param array $attributes + * @throws TestDummyException + * @return Eloquent + */ + public function build($type, array $attributes) + { + if ( ! class_exists($type)) { + throw new TestDummyException("The {$type} model was not found."); + } + + return $this->fill($type, $attributes); + } + + /** + * Persist the entity. + * + * @param Model $entity + * @return void + */ + public function save($entity) + { + $entity->save(); + } + + /** + * Get all attributes for the model. + * + * @param object $entity + * @return array + */ + public function getAttributes($entity) + { + return $entity->getAttributes(); + } + + /** + * Force fill an object with attributes. + * + * @param string $type + * @param array $attributes + * @return Model + */ + private function fill($type, $attributes) + { + Eloquent::unguard(); + + $model = new $type($this->parent, $attributes, $this->table, $exists = false); + + Eloquent::reguard(); + + return $model; + } + +} diff --git a/tests/FactoryTest.php b/tests/FactoryTest.php index 813cd88..e0e7d9a 100644 --- a/tests/FactoryTest.php +++ b/tests/FactoryTest.php @@ -57,6 +57,18 @@ protected function migrateTables() $table->string('contents'); $table->timestamps(); }); + + DB::schema()->create('tags', function ($table) { + $table->increments('id'); + $table->string('tag'); + $table->timestamps(); + }); + + DB::schema()->create('post_tags', function ($table) { + $table->increments('id'); + $table->integer('post_id')->unsigned(); + $table->integer('tag_id')->unsigned(); + }); } /** @test */ @@ -64,8 +76,8 @@ public function it_builds_up_attributes_for_an_entity() { $attributes = TestDummy::build('Post'); - assertInstanceOf('Post', $attributes); - assertEquals('Post Title', $attributes->title); + $this->assertInstanceOf('Post', $attributes); + $this->assertEquals('Post Title', $attributes->title); } /** @test */ @@ -73,7 +85,7 @@ public function it_allows_for_overriding_attributes() { $post = TestDummy::build('Post', ['title' => 'override']); - assertEquals('override', $post->title); + $this->assertEquals('override', $post->title); } /** @test */ @@ -81,7 +93,7 @@ public function it_accepts_a_short_name_identifier_instead_of_the_model_class() { $post = TestDummy::build('scheduled_post'); - assertInstanceOf('Post', $post); + $this->assertInstanceOf('Post', $post); } /** @test */ @@ -89,11 +101,11 @@ public function it_allows_a_closure_to_be_used_for_defining_factories() { $comments = TestDummy::times(2)->create('Comment'); - assertInstanceOf('Comment', $comments[0]); - assertInternalType('string', $comments[0]->body); + $this->assertInstanceOf('Comment', $comments[0]); + $this->assertInternalType('string', $comments[0]->body); // Faker should produce a unique value for each generation. - assertNotEquals($comments[0]->body, $comments[1]->body); + $this->assertNotEquals($comments[0]->body, $comments[1]->body); } /** @test */ @@ -101,8 +113,8 @@ public function it_gets_an_array_only_of_attributes() { $attributes = TestDummy::attributesFor('Post', ['title' => 'override']); - assertInternalType('array', $attributes); - assertEquals('override', $attributes['title']); + $this->assertInternalType('array', $attributes); + $this->assertEquals('override', $attributes['title']); } /** @test */ @@ -110,8 +122,8 @@ public function it_builds_and_persists_attributes() { $post = TestDummy::create('Post'); - assertInstanceOf('Post', $post); - assertNotNull($post->id); + $this->assertInstanceOf('Post', $post); + $this->assertNotNull($post->id); } /** @test */ @@ -119,8 +131,8 @@ public function it_builds_up_relationships_if_specified() { $comment = TestDummy::create('Comment'); - assertInstanceOf('Comment', $comment); - assertInstanceOf('Post', $comment->post); + $this->assertInstanceOf('Comment', $comment); + $this->assertInstanceOf('Post', $comment->post); } /** @test */ @@ -128,8 +140,8 @@ public function it_can_build_and_persist_multiple_times() { $posts = TestDummy::times(3)->create('Post'); - assertInstanceOf('Illuminate\Support\Collection', $posts); - assertCount(3, $posts); + $this->assertInstanceOf('Illuminate\Support\Collection', $posts); + $this->assertCount(3, $posts); } /** @@ -154,7 +166,7 @@ public function it_overrides_relationship_attributes_if_specified() 'post_id.title' => 'override' ]); - assertEquals('override', $comment->post->title); + $this->assertEquals('override', $comment->post->title); } /** @test */ @@ -165,8 +177,8 @@ public function it_overrides_relationship_attributes_separately_for_relationship 'receiver_id.name' => 'Jeffrey', ]); - assertEquals('Adam', $message->sender->name); - assertEquals('Jeffrey', $message->receiver->name); + $this->assertEquals('Adam', $message->sender->name); + $this->assertEquals('Jeffrey', $message->receiver->name); } /** @test */ @@ -178,9 +190,9 @@ public function it_can_override_deeply_nested_relationships() 'post_id.author_id.name' => 'Overridden Author Name', ]); - assertEquals('Overridden Comment Body', $comment->body); - assertEquals('Overridden Post Title', $comment->post->title); - assertEquals('Overridden Author Name', $comment->post->author->name); + $this->assertEquals('Overridden Comment Body', $comment->body); + $this->assertEquals('Overridden Post Title', $comment->post->title); + $this->assertEquals('Overridden Author Name', $comment->post->author->name); } /** @test */ @@ -191,8 +203,21 @@ public function relationship_overrides_are_ignored_if_the_relationship_is_not_ac 'post_id.title' => 'override' ]); - assertNull($comment->post); - assertNull($comment->getAttribute('post_id.title')); + $this->assertNull($comment->post); + $this->assertNull($comment->getAttribute('post_id.title')); + } + + /** @test */ + public function it_uses_a_pivot_model() + { + $parent = new Post; + TestDummy::$databaseProvider = new Laracasts\TestDummy\EloquentPivotModel($parent, 'post_tags'); + + $postTag = TestDummy::create('PostTag'); + + TestDummy::$databaseProvider = new Laracasts\TestDummy\EloquentModel(); + + $this->assertInstanceOf('PostTag', $postTag); } } diff --git a/tests/support/factories/factories.php b/tests/support/factories/factories.php index 4618dd5..94114a9 100644 --- a/tests/support/factories/factories.php +++ b/tests/support/factories/factories.php @@ -39,3 +39,12 @@ $factory('Person', [ 'name' => $faker->name ]); + +$factory('Tag', [ + 'tag' => $faker->name +]); + +$factory('PostTag', [ + 'post_id' => '1', + 'tag_id' => '1' +]); diff --git a/tests/support/models/Post.php b/tests/support/models/Post.php index bff888e..3b82086 100644 --- a/tests/support/models/Post.php +++ b/tests/support/models/Post.php @@ -5,4 +5,5 @@ class Post extends Model { public function comments() { return $this->hasMany('Comment'); } public function author() { return $this->belongsTo('Person', 'author_id'); } + public function tags() { return $this->belongsToMany('Tag'); } } diff --git a/tests/support/models/PostTag.php b/tests/support/models/PostTag.php new file mode 100644 index 0000000..a116b65 --- /dev/null +++ b/tests/support/models/PostTag.php @@ -0,0 +1,7 @@ +belongsToMany('Post'); } +}