1, 'name' => 'John'], ['id' => 2, 'name' => 'Wane'] ]; $matcher = fn($prop, $origin) => $prop['id'] === $origin['id']; $mockedPolicy = $this->makeEmpty(SynchronizationPolicy::class, [ 'handleAdd' => Expected::never(), 'handleUpdate' => Expected::exactly(2, fn ($origin, $updateData) => array_merge($origin, $updateData)), 'handleRemove' => Expected::never(), ]); $collection = new SynchronizedCollection($entry, $mockedPolicy); $synchronized = $collection->sync([ ['id' => 1, 'name' => 'John'], ['id' => 2, 'name' => 'Wane'] ], $matcher); $this->assertEquals([ ['id' => 1, 'name' => 'John'], ['id' => 2, 'name' => 'Wane'] ], $synchronized->toArray()); } /** * @test */ public function itShouldAddNewElementToSynchronizedCollection() { $entry = [ ['id' => 1, 'name' => 'John'], ['id' => 2, 'name' => 'Wane'] ]; $matcher = fn($prop, $origin) => isset($prop['id']) && $prop['id'] === $origin['id']; $mockedPolicy = $this->makeEmpty(SynchronizationPolicy::class, [ 'handleAdd' => Expected::once(fn ($newData) => array_merge(['id' => 3], $newData)), 'handleUpdate' => Expected::exactly(2, fn ($origin, $updateData) => array_merge($origin, $updateData)), 'handleRemove' => Expected::never(), ]); $collection = new SynchronizedCollection($entry, $mockedPolicy); $synchronized = $collection->sync([ ['id' => 1, 'name' => 'John'], ['id' => 2, 'name' => 'Wane'], ['name' => 'Marry'] ], $matcher); $this->assertEquals([ ['id' => 1, 'name' => 'John'], ['id' => 2, 'name' => 'Wane'], ['id' => 3, 'name' => 'Marry'], ], $synchronized->toArray()); } /** * @test */ public function itShouldRemoveExistingElementFromSynchronizedCollection() { $entry = [ ['id' => 1, 'name' => 'John'], ['id' => 2, 'name' => 'Wane'] ]; $matcher = fn($prop, $origin) => isset($prop['id']) && $prop['id'] === $origin['id']; $mockedPolicy = $this->makeEmpty(SynchronizationPolicy::class, [ 'handleAdd' => Expected::never(), 'handleUpdate' => Expected::exactly(1, fn ($origin, $updateData) => array_merge($origin, $updateData)), 'handleRemove' => Expected::once(), ]); $collection = new SynchronizedCollection($entry, $mockedPolicy); $synchronized = $collection->sync([ ['id' => 2, 'name' => 'Wane'] ], $matcher); $this->assertEquals([ ['id' => 2, 'name' => 'Wane'] ], $synchronized->toArray()); } /** * @test */ public function itShouldAddNewElementAndRemoveExistingElementFromSynchronizedCollection() { $entry = [ ['id' => 1, 'name' => 'John'], ['id' => 2, 'name' => 'Wane'] ]; $matcher = fn($prop, $origin) => isset($prop['id']) && $prop['id'] === $origin['id']; $mockedPolicy = $this->makeEmpty(SynchronizationPolicy::class, [ 'handleAdd' => Expected::once(fn ($newData) => array_merge(['id' => 3], $newData)), 'handleUpdate' => Expected::exactly(1, fn ($origin, $updateData) => array_merge($origin, $updateData)), 'handleRemove' => Expected::once(), ]); $collection = new SynchronizedCollection($entry, $mockedPolicy); $synchronized = $collection->sync([ ['name' => 'Tim'], ['id' => 2, 'name' => 'Wane'] ], $matcher); $this->assertEquals([ ['id' => 2, 'name' => 'Wane'], ['id' => 3, 'name' => 'Tim'] ], $synchronized->toArray()); } /** * @test */ public function itShouldUpdateElementAndAddNewElementAndRemoveExistingElementFromSynchronizedCollection() { $entry = [ ['id' => 1, 'name' => 'John'], ['id' => 2, 'name' => 'Wane'] ]; $matcher = fn($prop, $origin) => isset($prop['id']) && $prop['id'] === $origin['id']; $mockedPolicy = $this->makeEmpty(SynchronizationPolicy::class, [ 'handleAdd' => Expected::once(fn ($newData) => array_merge(['id' => 3], $newData)), 'handleUpdate' => Expected::exactly(1, fn ($origin, $updateData) => array_merge($origin, $updateData)), 'handleRemove' => Expected::once(), ]); $collection = new SynchronizedCollection($entry, $mockedPolicy); $synchronized = $collection->sync([ ['name' => 'Tim'], ['id' => 2, 'name' => 'Wane_UPDATED'] ], $matcher); $this->assertEquals([ ['id' => 2, 'name' => 'Wane_UPDATED'], ['id' => 3, 'name' => 'Tim'] ], $synchronized->toArray()); } /** * @test */ public function itShouldThrowExceptionIfProvidedArrayContainsAmbiguousElement() { $entry = [ ['id' => 2, 'name' => 'Wane'] ]; $matcher = fn($prop, $origin) => isset($prop['id']) && $prop['id'] === $origin['id']; $mockedPolicy = $this->makeEmpty(SynchronizationPolicy::class, [ 'handleAdd' => Expected::never(), 'handleUpdate' => Expected::never(), 'handleRemove' => Expected::never() ]); $collection = new SynchronizedCollection($entry, $mockedPolicy); $this->tester->expectThrowable(AmbiguousElementException::class, function () use ($collection, $matcher) { $collection->sync([ ['id' => 2, 'name' => 'Wane'], ['id' => 2, 'name' => 'Tim'] ], $matcher); }); } }