Browse Source

Make Collection::every() return true for empty sets.

An empty list should pass all conditions as it is the vacuous truth.
We incorrectly made Collection::every() return false in #8670. Returning
true makes Collection::every() match implementations in most other
languages/libraries.

Add additional tests to other filter/member checks to verify empty set
behavior there as well.

Refs #10002
Mark Story 9 years ago
parent
commit
ecebfb00c2

+ 3 - 1
src/Collection/CollectionInterface.php

@@ -112,9 +112,11 @@ interface CollectionInterface extends Iterator, JsonSerializable
      * });
      * ```
      *
+     * Empty collections always return true because it is a vacuous truth.
+     *
      * @param callable $c a callback function
      * @return bool true if for all elements in this collection the provided
-     * callback returns true, false otherwise
+     *   callback returns true, false otherwise.
      */
     public function every(callable $c);
 

+ 1 - 2
src/Collection/CollectionTrait.php

@@ -89,9 +89,8 @@ trait CollectionTrait
      */
     public function every(callable $c)
     {
-        $return = false;
+        $return = true;
         foreach ($this->unwrap() as $key => $value) {
-            $return = true;
             if (!$c($value, $key)) {
                 return false;
             }

+ 16 - 1
tests/TestCase/Collection/CollectionTest.php

@@ -141,6 +141,12 @@ class CollectionTest extends TestCase
      */
     public function testReject()
     {
+        $collection = new Collection([]);
+        $result = $collection->reject(function ($v) {
+            return false;
+        });
+        $this->assertSame([], iterator_to_array($result));
+
         $items = ['a' => 1, 'b' => 2, 'c' => 3];
         $collection = new Collection($items);
         $result = $collection->reject(function ($v, $k, $items) use ($collection) {
@@ -212,7 +218,7 @@ class CollectionTest extends TestCase
 
         $callable->expects($this->never())
             ->method('__invoke');
-        $this->assertFalse($collection->every($callable));
+        $this->assertTrue($collection->every($callable));
     }
 
     /**
@@ -222,6 +228,12 @@ class CollectionTest extends TestCase
      */
     public function testSomeReturnTrue()
     {
+        $collection = new Collection([]);
+        $result = $collection->some(function ($v) {
+            return true;
+        });
+        $this->assertFalse($result);
+
         $items = ['a' => 1, 'b' => 2, 'c' => 3];
         $collection = new Collection($items);
         $callable = $this->getMockBuilder(\StdClass::class)
@@ -275,6 +287,9 @@ class CollectionTest extends TestCase
      */
     public function testContains()
     {
+        $collection = new Collection([]);
+        $this->assertFalse($collection->contains('a'));
+
         $items = ['a' => 1, 'b' => 2, 'c' => 3];
         $collection = new Collection($items);
         $this->assertTrue($collection->contains(2));