Skip to content

Commit

Permalink
Compare a diff by identifier
Browse files Browse the repository at this point in the history
  • Loading branch information
rgazelot committed Jul 16, 2014
1 parent 5b6994f commit 27549e9
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 5 deletions.
5 changes: 3 additions & 2 deletions src/AbstractSnapshot.php
Expand Up @@ -52,18 +52,19 @@ public function setSetClass($class)
* Calculate the diff between two snapshots
*
* @param AbstractSnapshot $snapshot Snapshot to compare this one to
* @param mixed $id Compare the old and new entries by a given key
*
* @return Set Changeset between the two snapshots
* @throws IncomparableDataException If the two snapshots are not comparable
*/
public function diff(AbstractSnapshot $snapshot)
public function diff(AbstractSnapshot $snapshot, $id = null)
{
if (!$this->isComparable($snapshot)) {
throw new IncomparableDataException;
}

$set = new $this->setClass;
$set->compute($this, $snapshot);
$set->compute($this, $snapshot, $id);

return $set;
}
Expand Down
38 changes: 37 additions & 1 deletion src/Set.php
Expand Up @@ -134,14 +134,20 @@ public function getIterator()
}

/** {@inheritDoc} */
public function compute(AbstractSnapshot $old, AbstractSnapshot $new)
public function compute(AbstractSnapshot $old, AbstractSnapshot $new, $id = null)
{
if (null !== $this->changes) {
return;
}

$this->changes = [];

if (null !== $id) {
$this->computeEntryById($old, $new, $id);

return;
}

foreach (array_replace($old->getDataKeys(), $new->getDataKeys()) as $key) {
$result = $this->computeEntry($old, $new, $key);

Expand All @@ -151,6 +157,36 @@ public function compute(AbstractSnapshot $old, AbstractSnapshot $new)
}
}

/**
* Compare old and new snapshot by a given id
*
* @param AbstractSnapshot $old
* @param AbstractSnapshot $new
* @param mixed $id
*/
private function computeEntryById(AbstractSnapshot $old, AbstractSnapshot $new, $id)
{
foreach ($old->getRawData() as $oldArray) {
foreach ($new->getRawData() as $newArray) {
if ($oldArray[$id] === $newArray[$id]) {
continue 2;
}
}

$this->changes[] = new Removal($oldArray);
}

foreach ($new->getRawData() as $newArray) {
foreach ($new->getRawData() as $oldArray) {
if ($oldArray[$id] === $newArray[$id]) {
continue 2;
}
}

$this->changes[] = new Addition($newArray);
}
}

/**
* Calculate the difference between two snapshots for a given key
*
Expand Down
3 changes: 2 additions & 1 deletion src/SetInterface.php
Expand Up @@ -48,7 +48,8 @@ public function hasChanged($property);
*
* @param AbstractSnapshot $old Old snapshot
* @param AbstractSnapshot $new New snapshot
* @param mixed $id Compare the old and new entries by a given key
*/
public function compute(AbstractSnapshot $old, AbstractSnapshot $new);
public function compute(AbstractSnapshot $old, AbstractSnapshot $new, $id = null);
}

26 changes: 25 additions & 1 deletion test/SetTest.php
Expand Up @@ -16,6 +16,7 @@
use \PHPUnit_Framework_TestCase;

use Totem\Set,
Totem\AbstractSnapshot,
Totem\Snapshot\ArraySnapshot,
Totem\Snapshot\ObjectSnapshot;

Expand Down Expand Up @@ -181,5 +182,28 @@ public function testAlreadyComputedSetShouldNotRecompute()

$set->compute($old, $new);
}
}

public function testComputeWithById()
{
$old = new ArraySnapshot([
['hash' => 'aaa', 'name' => 'foo'],
['hash' => 'bbb', 'name' => 'bar'],
['hash' => 'ccc', 'name' => 'baz'],
]);
$new = new ArraySnapshot([
['hash' => 'aaa', 'name' => 'foo'],
['hash' => 'ccc', 'name' => 'baz'],
]);

$set = new Set;
$set->compute($old, $new, 'hash');

$this->assertEquals(1, $set->count());

foreach ($set as $change) {
$this->assertInstanceOf('Totem\\Change\\Removal', $change);
$this->assertEquals('bbb', $change->getOld()['hash']);
$this->assertNull($change->getNew());
}
}
}

0 comments on commit 27549e9

Please sign in to comment.