Skip to content

Commit

Permalink
resolve merge conflicts; rename 'delete' to 'remove'; change getDelet…
Browse files Browse the repository at this point in the history
…edEntitiesIds() to getRemovedEntities(), which now returns an array of entities keyed on their identity values
  • Loading branch information
Paul M. Jones committed May 7, 2013
2 parents b53e0aa + d9a1d57 commit a51afa7
Show file tree
Hide file tree
Showing 2 changed files with 258 additions and 1 deletion.
83 changes: 82 additions & 1 deletion src/Aura/Marshal/Type/GenericType.php
Expand Up @@ -97,9 +97,18 @@ class GenericType extends Data
*/
protected $index_new = [];

/**
*
* An array of all entities removed via `removeEntity()`.
*
* @var array
*
*/
protected $removed = [];

/**
*
* An object store of the initial data for entity in the IdentityMap.
* An object store of the initial data for entities in the IdentityMap.
*
* @var SplObjectStorage
*
Expand Down Expand Up @@ -746,6 +755,65 @@ public function newEntity(array $data = [])
return $entity;
}

/**
*
* Removes an entity from the collection.
*
* @param $identity_value int The identity value of the entity to be
* removed.
*
* @return bool True on success, false on failure.
*
*/
public function removeEntity($identity_value)
{
// if the entity is not in the identity index, exit early
if (! isset($this->index_identity[$identity_value])) {
return false;
}

// look up the sequential offset for the identity value
$offset = $this->index_identity[$identity_value];

// get the entity
$entity = $this->offsetGet($offset);

// add the entity to the removed array
$this->removed[$identity_value] = $entity;

// remove the entity from the identity index
unset($this->index_identity[$identity_value]);

// get the index fields
$index_fields = array_keys($this->index_fields);

// loop through indices and remove offsets of this entity
foreach ($index_fields as $field) {

// get the field value
$value = $entity->$field;

// find index of the offset with that value
$offset_idx = array_search(
$offset,
$this->index_fields[$field][$value]
);

// if the index exists, remove it, preserving index integrity
if ($offset_idx !== false) {
array_splice(
$this->index_fields[$field][$value],
$offset_idx,
1
);
}
}

// really remove the entity, and done
$this->offsetUnset($offset);
return true;
}

/**
*
* Returns an array of all entities in the IdentityMap that have been
Expand Down Expand Up @@ -782,6 +850,19 @@ public function getNewEntities()
}
return $list;
}

/**
*
* Returns an array of all entities that were removed using
* `removeEntity()`.
*
* @return array
*
*/
public function getRemovedEntities()
{
return $this->removed;
}

/**
*
Expand Down
176 changes: 176 additions & 0 deletions tests/Aura/Marshal/TypeTest.php
Expand Up @@ -465,4 +465,180 @@ public function testLoadCollection()
$collection
);
}

public function testRemove_none()
{
$this->loadTypeWithPosts();

$this->assertSame([], $this->type->getRemovedEntities());
}

public function testRemove_single()
{
$this->loadTypeWithPosts();

$this->assertTrue($this->type->removeEntity(1));

$this->assertSame([1], array_keys($this->type->getRemovedEntities()));
}

public function testRemove_many()
{
$this->loadTypeWithPosts();

$this->assertTrue($this->type->removeEntity(1));
$this->assertTrue($this->type->removeEntity(2));
$this->assertTrue($this->type->removeEntity(3));

$this->assertSame(
[1, 2, 3],
array_keys($this->type->getRemovedEntities())
);
}

public function testRemoveNonExistent()
{
$this->loadTypeWithPosts();

$this->assertFalse($this->type->removeEntity(99999));
}

public function testRemoveAndGet()
{
$this->loadTypeWithPosts();
$this->assertTrue($this->type->removeEntity(1));

$this->assertNull($this->type->getEntity(1));
}

public function testRemoveAndDeleteAgain()
{
$this->loadTypeWithPosts();
$this->assertTrue($this->type->removeEntity(1));
$this->assertFalse($this->type->removeEntity(1));
}

public function testRemoveEmpty()
{
$this->assertFalse($this->type->removeEntity(1));
}

public function testRemoveAndGetCollectionByIndex_first()
{
$data = $this->loadTypeWithPosts();

$expect = [
(object) $data[1],
(object) $data[2]
];

$this->assertTrue($this->type->removeEntity(1));

$collection = $this->type->getCollectionByField('author_id', 1);

foreach ($collection as $offset => $actual) {
$this->assertSame($expect[$offset]->id, $actual->id);
$this->assertSame($expect[$offset]->author_id, $actual->author_id);
$this->assertSame($expect[$offset]->body, $actual->body);
$this->assertSame($expect[$offset]->fake_field, $actual->fake_field);
}
}

public function testRemoveAndGetCollectionByIndex_second()
{
$data = $this->loadTypeWithPosts();

$expect = [
(object) $data[0],
(object) $data[2]
];

$this->assertTrue($this->type->removeEntity(2));

$collection = $this->type->getCollectionByField('author_id', 1);

foreach ($collection as $offset => $actual) {
$this->assertSame($expect[$offset]->id, $actual->id);
$this->assertSame($expect[$offset]->author_id, $actual->author_id);
$this->assertSame($expect[$offset]->body, $actual->body);
$this->assertSame($expect[$offset]->fake_field, $actual->fake_field);
}
}

public function testRemoveAndGetCollectionByField_first()
{
$data = $this->loadTypeWithPosts();

$expect = [
(object) $data[4]
];

$this->assertTrue($this->type->removeEntity(4));

$collection = $this->type->getCollectionByField('fake_field', 88);

foreach ($collection as $offset => $actual) {
$this->assertSame($expect[$offset]->id, $actual->id);
$this->assertSame($expect[$offset]->author_id, $actual->author_id);
$this->assertSame($expect[$offset]->body, $actual->body);
$this->assertSame($expect[$offset]->fake_field, $actual->fake_field);
}
}

public function testRemoveAndGetCollectionByField_second()
{
$data = $this->loadTypeWithPosts();

$expect = [
(object) $data[0],
(object) $data[2],
];

$this->assertTrue($this->type->removeEntity(2));

$collection = $this->type->getCollectionByField('fake_field', 69);

foreach ($collection as $offset => $actual) {
$this->assertSame($expect[$offset]->id, $actual->id);
$this->assertSame($expect[$offset]->author_id, $actual->author_id);
$this->assertSame($expect[$offset]->body, $actual->body);
$this->assertSame($expect[$offset]->fake_field, $actual->fake_field);
}
}

public function testRemoveAndGetCollectionByField_many()
{
$data = $this->loadTypeWithPosts();

$expect = [
(object) $data[0],
(object) $data[2],
(object) $data[4]
];

$this->assertTrue($this->type->removeEntity(2));
$this->assertTrue($this->type->removeEntity(4));

$collection = $this->type->getCollectionByField('fake_field', [88, 69]);

foreach ($collection as $offset => $actual) {
$this->assertSame($expect[$offset]->id, $actual->id);
$this->assertSame($expect[$offset]->author_id, $actual->author_id);
$this->assertSame($expect[$offset]->body, $actual->body);
$this->assertSame($expect[$offset]->fake_field, $actual->fake_field);
}
}

public function testRemoveAll()
{
$data = $this->loadTypeWithPosts();

foreach ($data as $post) {
$this->assertTrue($this->type->removeEntity($post['id']));
}

$this->assertSame(0, $this->type->count());

$this->assertNull($this->type->getEntity(1));
}
}

0 comments on commit a51afa7

Please sign in to comment.