Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
05fdae9
added a method for retrieving all indices
phroggyy May 23, 2015
21ef8d5
added a method to retrieve a random index of an existing entry, using…
phroggyy May 23, 2015
eb492e9
added comment for existing post to test the ability to use an existin…
phroggyy May 23, 2015
d638bb1
using $this for testing and added test to check if it can establish a…
phroggyy May 23, 2015
29c8af7
corrected preg matching
phroggyy May 23, 2015
4bafcab
fixed allIndices
phroggyy May 23, 2015
1df1af9
added random method to interface
phroggyy May 23, 2015
97d8602
added random and exists methods
phroggyy May 23, 2015
1b9f7d2
added random and get random methods
phroggyy May 23, 2015
21d3da1
removed existingIndex and made exists public
phroggyy May 23, 2015
f357386
allowed overwriting attributes of existing posts
phroggyy May 23, 2015
a2472a5
added new factories for testing purposes
phroggyy May 23, 2015
fe153e0
added existing keys to support excluding related models that have alr…
phroggyy May 23, 2015
9cb9edb
now exclude the already taken keys when fetching a random existing model
phroggyy May 23, 2015
70826e4
added existing keys to interface
phroggyy May 23, 2015
046b57a
ensured a new instance is created if the user used the `model:factory…
phroggyy May 23, 2015
391d4da
set a default timezone to avoid errors about using get_default_timezo…
phroggyy May 23, 2015
f9483b6
added the `post_by_existing_person` factory
phroggyy May 23, 2015
3edf5f1
added test case to check if it still works multiple times when using …
phroggyy May 23, 2015
a1a3be3
added docblocks
phroggyy May 23, 2015
23b5a92
added a test to assert that we never receive the same related child e…
phroggyy May 23, 2015
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
67 changes: 60 additions & 7 deletions src/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,43 @@ protected function persist($name, array $attributes = [])
return $entity;
}

/**
* Fetch a random existing entity, or create a new one
*
* @param $name
* @param $overrides
* @param array $existingKeys
* @return mixed
* @throws TestDummyException
*/
protected function random($name, $overrides, array $existingKeys = [])
{
$attributes = $this->getAttributes($name, $overrides);
$class = $this->getFixture($name)->name;

// We'll pass off the process of creating the entity.
// That way, folks can use different persistence layers.

return $this->model->random($class, $attributes, $existingKeys);
}

/**
* Assign relationships to a randomly fetched entity
* @param $name
* @param $attributes
* @param array $existingKeys
* @return mixed
*/
public function exists($name, $attributes, array $existingKeys = [])
{
$entity = $this->random($name, $attributes, $existingKeys);

$this->assignRelationships($entity, $attributes);
$this->model->save($entity);

return $entity;
}

/**
* Merge the fixture with any potential overrides.
*
Expand Down Expand Up @@ -282,12 +319,14 @@ protected function assignRelationships($entity, $attributes)
// to see if there are any defined relationships. If there
// are, then we'll need to create those records as well.

$existing = [];

foreach ($modelAttributes as $columnName => $value) {
if ($relationship = $this->findRelation($value)) {
$entity[$columnName] = $this->fetchRelationId($relationship, $columnName, $attributes);
// $relationship is now our $matches array from findRelation
$existing[] = $entity[$columnName] = $this->fetchRelationId($relationship, $columnName, $attributes, $existing);
}
}

return $entity;
}

Expand All @@ -299,8 +338,8 @@ protected function assignRelationships($entity, $attributes)
*/
protected function findRelation($attribute)
{
if (is_string($attribute) && preg_match('/^factory:(.+)$/i', $attribute, $matches)) {
return $matches[1];
if (is_string($attribute) && (preg_match('/^factory:(.+)$/i', $attribute, $matches) || preg_match('/^model:(.+)$/i', $attribute, $matches))) {
return $matches;
}

return false;
Expand All @@ -312,12 +351,26 @@ protected function findRelation($attribute)
* @param string $factoryName
* @param string $relationshipName
* @param array $attributes
* @param array $existingKeys
* @return int
* @throws \Exception
*/
protected function fetchRelationId($factoryName, $relationshipName, array $attributes)
protected function fetchRelationId($factoryName, $relationshipName, array $attributes, array $existingKeys)
{
$attributes = $this->extractRelationshipAttributes($relationshipName, $attributes);
$relationKey = $this->persist($factoryName, $attributes)->getKey();
// $factoryName is our matches, containing both 'model:factoryName'/'factory:factoryName' and just the factoryName
$type = preg_replace('/' . $factoryName[1] . '/', '', $factoryName[0]);
switch ($type) {
case 'factory:':
$attributes = $this->extractRelationshipAttributes($relationshipName, $attributes);
$relationKey = $this->persist($factoryName[1], $attributes)->getKey();
break;
case 'model:':
$attributes = $this->extractRelationshipAttributes($relationshipName, $attributes);
$relationKey = $this->exists($factoryName[1], $attributes, $existingKeys)->getKey();
break;
default:
throw new \Exception('Relation identifier not allowed. Please use model or factory.');
}

return $relationKey;
}
Expand Down
43 changes: 43 additions & 0 deletions src/EloquentModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,30 @@ public function build($type, array $attributes)
return $this->fill($type, $attributes);
}


/**
* Get a random entity and fill any override attributes
* @param $type
* @param array $attributes
* @param array $existingKeys
* @return mixed
* @throws TestDummyException
*/
public function random($type, array $attributes, array $existingKeys)
{
if ( ! class_exists($type)) {
throw new TestDummyException("The {$type} model was not found.");
}

$model = $this->getRandom($type, $existingKeys);

Eloquent::unguard();
$model->fill($attributes);
Eloquent::reguard();

return $model;
}

/**
* Persist the entity.
*
Expand Down Expand Up @@ -64,4 +88,23 @@ private function fill($type, $attributes)
return $object;
}

/**
* Fetch a random entity from the database which is not already in use
* If none exists, create a new one
*
* @param $type
* @param array $existingKeys
* @return mixed
*/
private function getRandom($type, array $existingKeys)
{
$object = new $type;
$count = $type::count() - count($existingKeys);
if ($count > 0) {
$rand = mt_rand(0,$count-1);
return $object->whereNotIn($object->getKeyName(), $existingKeys)->get()[$rand];
}
return $object;
}

}
2 changes: 2 additions & 0 deletions src/IsPersistable.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,6 @@ public function save($entity);
*/
public function getAttributes($entity);

public function random($type, array $attributes, array $existingKeys);

}
Loading