Skip to content

Commit c30d791

Browse files
Merge pull request sebastianbergmann#1125 from asystance/fix-CountIterator-3.7
Fixed a bug in PHPUnit_Framework_Constraint_Count
2 parents 31d9d06 + 36cc20f commit c30d791

File tree

3 files changed

+144
-2
lines changed

3 files changed

+144
-2
lines changed

PHPUnit/Framework/Constraint/Count.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,20 @@ protected function getCountOf($other)
9494
}
9595

9696
else if ($other instanceof Iterator) {
97-
return iterator_count($other);
97+
$key = $other->key();
98+
$count = iterator_count($other);
99+
100+
// manually rewind $other to previous key, since iterator_count moves pointer
101+
if ($key !== null) {
102+
$other->rewind();
103+
while ($key !== $other->key()) {
104+
$other->next();
105+
}
106+
}
107+
108+
return $count;
98109
}
110+
99111
}
100112

101113

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
<?php
2+
/**
3+
* PHPUnit
4+
*
5+
* Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
6+
* All rights reserved.
7+
*
8+
* Redistribution and use in source and binary forms, with or without
9+
* modification, are permitted provided that the following conditions
10+
* are met:
11+
*
12+
* * Redistributions of source code must retain the above copyright
13+
* notice, this list of conditions and the following disclaimer.
14+
*
15+
* * Redistributions in binary form must reproduce the above copyright
16+
* notice, this list of conditions and the following disclaimer in
17+
* the documentation and/or other materials provided with the
18+
* distribution.
19+
*
20+
* * Neither the name of Sebastian Bergmann nor the names of his
21+
* contributors may be used to endorse or promote products derived
22+
* from this software without specific prior written permission.
23+
*
24+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27+
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28+
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30+
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34+
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35+
* POSSIBILITY OF SUCH DAMAGE.
36+
*
37+
* @package PHPUnit
38+
* @author Sebastian Bergmann <sebastian@phpunit.de>
39+
* @author Jeroen Versteeg <jversteeg@gmail.com>
40+
* @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
41+
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
42+
* @link http://www.phpunit.de/
43+
* @since File available since Release 3.9.0
44+
*/
45+
46+
require_once __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'TestIterator.php';
47+
48+
class TestIterator2 implements Iterator {
49+
50+
protected $data;
51+
52+
public function __construct(array $array)
53+
{
54+
$this->data = $array;
55+
}
56+
57+
public function current()
58+
{
59+
return current($this->data);
60+
}
61+
62+
public function next()
63+
{
64+
next($this->data);
65+
}
66+
67+
public function key()
68+
{
69+
return key($this->data);
70+
}
71+
72+
public function valid()
73+
{
74+
return key($this->data) !== null;
75+
}
76+
77+
public function rewind()
78+
{
79+
reset($this->data);
80+
}
81+
}
82+
83+
class CountTest extends PHPUnit_Framework_TestCase {
84+
85+
public function test_Count() {
86+
$countConstraint = new PHPUnit_Framework_Constraint_Count(3);
87+
$this->assertTrue($countConstraint->evaluate(array(1,2,3), '', true));
88+
89+
$countConstraint = new PHPUnit_Framework_Constraint_Count(0);
90+
$this->assertTrue($countConstraint->evaluate(array(), '', true));
91+
92+
$countConstraint = new PHPUnit_Framework_Constraint_Count(2);
93+
$it = new TestIterator(array(1, 2));
94+
$this->assertTrue($countConstraint->evaluate($it, '', true));
95+
}
96+
97+
public function test_CountDoesNotChangeIteratorKey ()
98+
{
99+
$countConstraint = new PHPUnit_Framework_Constraint_Count(2);
100+
101+
// test with 1st implementation of Iterator
102+
$it = new TestIterator(array(1, 2));
103+
104+
$countConstraint->evaluate($it, '', true);
105+
$this->assertEquals(1, $it->current());
106+
107+
$it->next();
108+
$countConstraint->evaluate($it, '', true);
109+
$this->assertEquals(2, $it->current());
110+
111+
$it->next();
112+
$countConstraint->evaluate($it, '', true);
113+
$this->assertFalse($it->valid());
114+
115+
// test with 2nd implementation of Iterator
116+
$it = new TestIterator2(array(1, 2));
117+
118+
$countConstraint = new PHPUnit_Framework_Constraint_Count(2);
119+
$countConstraint->evaluate($it, '', true);
120+
$this->assertEquals(1, $it->current());
121+
122+
$it->next();
123+
$countConstraint->evaluate($it, '', true);
124+
$this->assertEquals(2, $it->current());
125+
126+
$it->next();
127+
$countConstraint->evaluate($it, '', true);
128+
$this->assertFalse($it->valid());
129+
}
130+
}

Tests/_files/TestIterator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
class TestIterator implements Iterator
33
{
44
protected $array;
5-
protected $position;
5+
protected $position = 0;
66

77
public function __construct($array = array())
88
{

0 commit comments

Comments
 (0)