Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down Expand Up @@ -211,14 +211,24 @@ 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:

```php
$factory('App\Artist', function($faker) {
$name = sprintf('Some Band Named %s', $faker->word);

return [
'name' => $name
];
Expand Down
88 changes: 88 additions & 0 deletions src/EloquentPivotModel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?php

namespace Laracasts\TestDummy;

use Illuminate\Database\Eloquent\Model as Eloquent;

class EloquentPivotModel implements IsPersistable {

/**
* @var Eloquent
*/
protected $parent;

/**
* @var string
*/
protected $table;

/**
* Constructor.
*
* @param Eloquent $parent
* @param string $table
*/
public function __construct(Eloquent $parent, $table)
{
$this->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;
}

}
71 changes: 48 additions & 23 deletions tests/FactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,79 +57,91 @@ 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 */
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 */
public function it_allows_for_overriding_attributes()
{
$post = TestDummy::build('Post', ['title' => 'override']);

assertEquals('override', $post->title);
$this->assertEquals('override', $post->title);
}

/** @test */
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 */
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 */
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 */
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 */
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 */
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);
}

/**
Expand All @@ -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 */
Expand All @@ -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 */
Expand All @@ -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 */
Expand All @@ -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);
}
}

Expand Down
9 changes: 9 additions & 0 deletions tests/support/factories/factories.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,12 @@
$factory('Person', [
'name' => $faker->name
]);

$factory('Tag', [
'tag' => $faker->name
]);

$factory('PostTag', [
'post_id' => '1',
'tag_id' => '1'
]);
1 change: 1 addition & 0 deletions tests/support/models/Post.php
Original file line number Diff line number Diff line change
Expand Up @@ -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'); }
}
7 changes: 7 additions & 0 deletions tests/support/models/PostTag.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

use \Illuminate\Database\Eloquent\Relations\Pivot;

class PostTag extends Pivot {

}
7 changes: 7 additions & 0 deletions tests/support/models/Tag.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

use \Illuminate\Database\Eloquent\Model;

class Tag extends Model {
public function posts() { return $this->belongsToMany('Post'); }
}