From 27549e9eff28f765facd9954d472788ae86cecfe Mon Sep 17 00:00:00 2001 From: rgazelot Date: Wed, 16 Jul 2014 18:13:48 +0200 Subject: [PATCH] Compare a diff by identifier --- src/AbstractSnapshot.php | 5 +++-- src/Set.php | 38 +++++++++++++++++++++++++++++++++++++- src/SetInterface.php | 3 ++- test/SetTest.php | 26 +++++++++++++++++++++++++- 4 files changed, 67 insertions(+), 5 deletions(-) diff --git a/src/AbstractSnapshot.php b/src/AbstractSnapshot.php index 64414f1..c7102a3 100644 --- a/src/AbstractSnapshot.php +++ b/src/AbstractSnapshot.php @@ -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; } diff --git a/src/Set.php b/src/Set.php index e6f5b39..e10bdae 100644 --- a/src/Set.php +++ b/src/Set.php @@ -134,7 +134,7 @@ 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; @@ -142,6 +142,12 @@ public function compute(AbstractSnapshot $old, AbstractSnapshot $new) $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); @@ -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 * diff --git a/src/SetInterface.php b/src/SetInterface.php index 19c21fe..00100f2 100644 --- a/src/SetInterface.php +++ b/src/SetInterface.php @@ -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); } diff --git a/test/SetTest.php b/test/SetTest.php index fa46cb9..307bca3 100644 --- a/test/SetTest.php +++ b/test/SetTest.php @@ -16,6 +16,7 @@ use \PHPUnit_Framework_TestCase; use Totem\Set, + Totem\AbstractSnapshot, Totem\Snapshot\ArraySnapshot, Totem\Snapshot\ObjectSnapshot; @@ -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()); + } + } +}