wharmby Wed Jun 17 19:07:15 2009 UTC Added files: /php-src/tests/lang foreachLoopIteratorAggregate.002.phpt foreachLoopIteratorAggregate.003.phpt foreachLoopIteratorAggregate.001.phpt foreachLoopIterator.002.phpt foreachLoopIteratorAggregate.004.phpt foreachLoopIterator.001.phpt Log: New foreach tests. Tested on Windows, Linux and Linux 64 bit.
http://cvs.php.net/viewvc.cgi/php-src/tests/lang/foreachLoopIteratorAggregate.002.phpt?view=markup&rev=1.1 Index: php-src/tests/lang/foreachLoopIteratorAggregate.002.phpt +++ php-src/tests/lang/foreachLoopIteratorAggregate.002.phpt --TEST-- IteratorAggregate::getIterator bad return type --FILE-- <?php
class bad1 implements IteratorAggregate { function getIterator() { return null; } } class bad2 implements IteratorAggregate { function getIterator() { return new stdClass; } } class bad3 implements IteratorAggregate { function getIterator() { return 1; } } class bad4 implements IteratorAggregate { function getIterator() { return array(1,2,3); } } function f($className) { try { foreach (new $className as $k=>$v) { echo "$k => $v\n"; } } catch (Exception $e) { echo $e->getLine() . ": " . $e->getMessage() ."\n"; } } f("bad1"); f("bad2"); f("bad3"); f("bad4"); ?> ===DONE=== --EXPECTF-- 30: Objects returned by bad1::getIterator() must be traversable or implement interface Iterator 30: Objects returned by bad2::getIterator() must be traversable or implement interface Iterator 30: Objects returned by bad3::getIterator() must be traversable or implement interface Iterator 30: Objects returned by bad4::getIterator() must be traversable or implement interface Iterator ===DONE=== http://cvs.php.net/viewvc.cgi/php-src/tests/lang/foreachLoopIteratorAggregate.003.phpt?view=markup&rev=1.1 Index: php-src/tests/lang/foreachLoopIteratorAggregate.003.phpt +++ php-src/tests/lang/foreachLoopIteratorAggregate.003.phpt --TEST-- foreach with nested iteratorAggregates --FILE-- <?php class EnglishMealIterator implements Iterator { private $pos=0; private $myContent=array("breakfast", "dinner", "tea"); public function valid() { global $indent; echo "$indent--> " . __METHOD__ . " ($this->pos)\n"; return $this->pos<3; } public function next() { global $indent; echo "$indent--> " . __METHOD__ . " ($this->pos)\n"; return $this->myContent[$this->pos++]; } public function rewind() { global $indent; echo "$indent--> " . __METHOD__ . " ($this->pos)\n"; $this->pos=0; } public function current() { global $indent; echo "$indent--> " . __METHOD__ . " ($this->pos)\n"; return $this->myContent[$this->pos]; } public function key() { global $indent; echo "$indent--> " . __METHOD__ . " ($this->pos)\n"; return "meal " . $this->pos; } } class A1 implements IteratorAggregate { function getIterator() { return new EnglishMealIterator; } } class A2 implements IteratorAggregate { function getIterator() { return new A1; } } class A3 implements IteratorAggregate { function getIterator() { return new A2; } } echo "\n-----( A1: )-----\n"; foreach (new A1 as $k=>$v) { echo "$k => $v\n"; } echo "\n-----( A2: )-----\n"; foreach (new A2 as $k=>$v) { echo "$k => $v\n"; } echo "\n-----( A3: )-----\n"; foreach (new A3 as $k=>$v) { echo "$k => $v\n"; } ?> ===DONE=== --EXPECTF-- -----( A1: )----- --> EnglishMealIterator::rewind (0) --> EnglishMealIterator::valid (0) --> EnglishMealIterator::current (0) --> EnglishMealIterator::key (0) meal 0 => breakfast --> EnglishMealIterator::next (0) --> EnglishMealIterator::valid (1) --> EnglishMealIterator::current (1) --> EnglishMealIterator::key (1) meal 1 => dinner --> EnglishMealIterator::next (1) --> EnglishMealIterator::valid (2) --> EnglishMealIterator::current (2) --> EnglishMealIterator::key (2) meal 2 => tea --> EnglishMealIterator::next (2) --> EnglishMealIterator::valid (3) -----( A2: )----- --> EnglishMealIterator::rewind (0) --> EnglishMealIterator::valid (0) --> EnglishMealIterator::current (0) --> EnglishMealIterator::key (0) meal 0 => breakfast --> EnglishMealIterator::next (0) --> EnglishMealIterator::valid (1) --> EnglishMealIterator::current (1) --> EnglishMealIterator::key (1) meal 1 => dinner --> EnglishMealIterator::next (1) --> EnglishMealIterator::valid (2) --> EnglishMealIterator::current (2) --> EnglishMealIterator::key (2) meal 2 => tea --> EnglishMealIterator::next (2) --> EnglishMealIterator::valid (3) -----( A3: )----- --> EnglishMealIterator::rewind (0) --> EnglishMealIterator::valid (0) --> EnglishMealIterator::current (0) --> EnglishMealIterator::key (0) meal 0 => breakfast --> EnglishMealIterator::next (0) --> EnglishMealIterator::valid (1) --> EnglishMealIterator::current (1) --> EnglishMealIterator::key (1) meal 1 => dinner --> EnglishMealIterator::next (1) --> EnglishMealIterator::valid (2) --> EnglishMealIterator::current (2) --> EnglishMealIterator::key (2) meal 2 => tea --> EnglishMealIterator::next (2) --> EnglishMealIterator::valid (3) ===DONE=== http://cvs.php.net/viewvc.cgi/php-src/tests/lang/foreachLoopIteratorAggregate.001.phpt?view=markup&rev=1.1 Index: php-src/tests/lang/foreachLoopIteratorAggregate.001.phpt +++ php-src/tests/lang/foreachLoopIteratorAggregate.001.phpt --TEST-- foreach with iteratorAggregate --INI-- unicode.script_encoding=ISO-8859-1 unicode.runtime_encoding=ISO-8859-1 --FILE-- <?php class EnglishMealIterator implements Iterator { private $pos=0; private $myContent=array("breakfast", "dinner", "tea"); public function valid() { global $indent; echo "$indent--> " . __METHOD__ . " ($this->pos)\n"; return $this->pos < count($this->myContent); } public function next() { global $indent; echo "$indent--> " . __METHOD__ . " ($this->pos)\n"; $this->pos++; } public function rewind() { global $indent; echo "$indent--> " . __METHOD__ . " ($this->pos)\n"; $this->pos=0; } public function current() { global $indent; echo "$indent--> " . __METHOD__ . " ($this->pos)\n"; return $this->myContent[$this->pos]; } public function key() { global $indent; echo "$indent--> " . __METHOD__ . " ($this->pos)\n"; return "meal " . $this->pos; } } class FrenchMealIterator implements Iterator { private $pos=0; private $myContent=array("petit dejeuner", "dejeuner", "gouter", "dinner"); public function valid() { global $indent; echo "$indent--> " . __METHOD__ . " ($this->pos)\n"; return $this->pos < count($this->myContent); } public function next() { global $indent; echo "$indent--> " . __METHOD__ . " ($this->pos)\n"; $this->pos++; } public function rewind() { global $indent; echo "$indent--> " . __METHOD__ . " ($this->pos)\n"; $this->pos=0; } public function current() { global $indent; echo "$indent--> " . __METHOD__ . " ($this->pos)\n"; return $this->myContent[$this->pos]; } public function key() { global $indent; echo "$indent--> " . __METHOD__ . " ($this->pos)\n"; return "meal " . $this->pos; } } Class EuropeanMeals implements IteratorAggregate { private $storedEnglishMealIterator; private $storedFrenchMealIterator; public function __construct() { $this->storedEnglishMealIterator = new EnglishMealIterator; $this->storedFrenchMealIterator = new FrenchMealIterator; } public function getIterator() { global $indent; echo "$indent--> " . __METHOD__ . "\n"; //Alternate between English and French meals static $i = 0; if ($i++%2 == 0) { return $this->storedEnglishMealIterator; } else { return $this->storedFrenchMealIterator; } } } $f = new EuropeanMeals; var_dump($f); echo "-----( Simple iteration 1: )-----\n"; foreach ($f as $k=>$v) { echo "$k => $v\n"; } echo "-----( Simple iteration 2: )-----\n"; foreach ($f as $k=>$v) { echo "$k => $v\n"; } $indent = " "; echo "\n\n\n-----( Nested iteration: )-----\n"; $count=1; foreach ($f as $k=>$v) { echo "\nTop level " . $count++ . ": \n"; echo "$k => $v\n"; $indent = " "; foreach ($f as $k=>$v) { echo " $k => $v\n"; } $indent = " "; } ?> ===DONE=== --EXPECTF-- object(EuropeanMeals)#%d (2) { [u"storedEnglishMealIterator":u"EuropeanMeals":private]=> object(EnglishMealIterator)#%d (2) { [u"pos":u"EnglishMealIterator":private]=> int(0) [u"myContent":u"EnglishMealIterator":private]=> array(3) { [0]=> unicode(9) "breakfast" [1]=> unicode(6) "dinner" [2]=> unicode(3) "tea" } } [u"storedFrenchMealIterator":u"EuropeanMeals":private]=> object(FrenchMealIterator)#%d (2) { [u"pos":u"FrenchMealIterator":private]=> int(0) [u"myContent":u"FrenchMealIterator":private]=> array(4) { [0]=> unicode(14) "petit dejeuner" [1]=> unicode(8) "dejeuner" [2]=> unicode(6) "gouter" [3]=> unicode(6) "dinner" } } } -----( Simple iteration 1: )----- --> EuropeanMeals::getIterator --> EnglishMealIterator::rewind (0) --> EnglishMealIterator::valid (0) --> EnglishMealIterator::current (0) --> EnglishMealIterator::key (0) meal 0 => breakfast --> EnglishMealIterator::next (0) --> EnglishMealIterator::valid (1) --> EnglishMealIterator::current (1) --> EnglishMealIterator::key (1) meal 1 => dinner --> EnglishMealIterator::next (1) --> EnglishMealIterator::valid (2) --> EnglishMealIterator::current (2) --> EnglishMealIterator::key (2) meal 2 => tea --> EnglishMealIterator::next (2) --> EnglishMealIterator::valid (3) -----( Simple iteration 2: )----- --> EuropeanMeals::getIterator --> FrenchMealIterator::rewind (0) --> FrenchMealIterator::valid (0) --> FrenchMealIterator::current (0) --> FrenchMealIterator::key (0) meal 0 => petit dejeuner --> FrenchMealIterator::next (0) --> FrenchMealIterator::valid (1) --> FrenchMealIterator::current (1) --> FrenchMealIterator::key (1) meal 1 => dejeuner --> FrenchMealIterator::next (1) --> FrenchMealIterator::valid (2) --> FrenchMealIterator::current (2) --> FrenchMealIterator::key (2) meal 2 => gouter --> FrenchMealIterator::next (2) --> FrenchMealIterator::valid (3) --> FrenchMealIterator::current (3) --> FrenchMealIterator::key (3) meal 3 => dinner --> FrenchMealIterator::next (3) --> FrenchMealIterator::valid (4) -----( Nested iteration: )----- --> EuropeanMeals::getIterator --> EnglishMealIterator::rewind (3) --> EnglishMealIterator::valid (0) --> EnglishMealIterator::current (0) --> EnglishMealIterator::key (0) Top level 1: meal 0 => breakfast --> EuropeanMeals::getIterator --> FrenchMealIterator::rewind (4) --> FrenchMealIterator::valid (0) --> FrenchMealIterator::current (0) --> FrenchMealIterator::key (0) meal 0 => petit dejeuner --> FrenchMealIterator::next (0) --> FrenchMealIterator::valid (1) --> FrenchMealIterator::current (1) --> FrenchMealIterator::key (1) meal 1 => dejeuner --> FrenchMealIterator::next (1) --> FrenchMealIterator::valid (2) --> FrenchMealIterator::current (2) --> FrenchMealIterator::key (2) meal 2 => gouter --> FrenchMealIterator::next (2) --> FrenchMealIterator::valid (3) --> FrenchMealIterator::current (3) --> FrenchMealIterator::key (3) meal 3 => dinner --> FrenchMealIterator::next (3) --> FrenchMealIterator::valid (4) --> EnglishMealIterator::next (0) --> EnglishMealIterator::valid (1) --> EnglishMealIterator::current (1) --> EnglishMealIterator::key (1) Top level 2: meal 1 => dinner --> EuropeanMeals::getIterator --> EnglishMealIterator::rewind (1) --> EnglishMealIterator::valid (0) --> EnglishMealIterator::current (0) --> EnglishMealIterator::key (0) meal 0 => breakfast --> EnglishMealIterator::next (0) --> EnglishMealIterator::valid (1) --> EnglishMealIterator::current (1) --> EnglishMealIterator::key (1) meal 1 => dinner --> EnglishMealIterator::next (1) --> EnglishMealIterator::valid (2) --> EnglishMealIterator::current (2) --> EnglishMealIterator::key (2) meal 2 => tea --> EnglishMealIterator::next (2) --> EnglishMealIterator::valid (3) --> EnglishMealIterator::next (3) --> EnglishMealIterator::valid (4) ===DONE=== http://cvs.php.net/viewvc.cgi/php-src/tests/lang/foreachLoopIterator.002.phpt?view=markup&rev=1.1 Index: php-src/tests/lang/foreachLoopIterator.002.phpt +++ php-src/tests/lang/foreachLoopIterator.002.phpt --TEST-- foreach with iterator and &$value reference --FILE-- <?php class MyIterator implements Iterator { public function valid() { return true; } public function next() { } public function rewind() { } public function current() { } public function key() { } } $f = new MyIterator; echo "-----( Try to iterate with &\$value: )-----\n"; foreach ($f as $k=>&$v) { echo "$k => $v\n"; } ?> --EXPECTF-- -----( Try to iterate with &$value: )----- Fatal error: An iterator cannot be used with foreach by reference in %s on line 13 http://cvs.php.net/viewvc.cgi/php-src/tests/lang/foreachLoopIteratorAggregate.004.phpt?view=markup&rev=1.1 Index: php-src/tests/lang/foreachLoopIteratorAggregate.004.phpt +++ php-src/tests/lang/foreachLoopIteratorAggregate.004.phpt --TEST-- Duplicate of zend test tests/classes/iterators_002.phpt without expected output from destructor --FILE-- <?php class c_iter implements Iterator { private $obj; private $num = 0; function __construct($obj) { echo __METHOD__ . "\n"; $this->obj = $obj; } function rewind() { echo __METHOD__ . "\n"; $this->num = 0; } function valid() { $more = $this->num < $this->obj->max; echo __METHOD__ . ' = ' .($more ? 'true' : 'false') . "\n"; return $more; } function current() { echo __METHOD__ . "\n"; return $this->num; } function next() { echo __METHOD__ . "\n"; $this->num++; } function key() { echo __METHOD__ . "\n"; switch($this->num) { case 0: return "1st"; case 1: return "2nd"; case 2: return "3rd"; default: return "???"; } } function __destruct() { } } class c implements IteratorAggregate { public $max = 3; function getIterator() { echo __METHOD__ . "\n"; return new c_iter($this); } function __destruct() { } } $t = new c(); foreach($t as $k => $v) { foreach($t as $w) { echo "double:$v:$w\n"; break; } } unset($t); ?> ===DONE=== --EXPECT-- c::getIterator c_iter::__construct c_iter::rewind c_iter::valid = true c_iter::current c_iter::key c::getIterator c_iter::__construct c_iter::rewind c_iter::valid = true c_iter::current double:0:0 c_iter::next c_iter::valid = true c_iter::current c_iter::key c::getIterator c_iter::__construct c_iter::rewind c_iter::valid = true c_iter::current double:1:0 c_iter::next c_iter::valid = true c_iter::current c_iter::key c::getIterator c_iter::__construct c_iter::rewind c_iter::valid = true c_iter::current double:2:0 c_iter::next c_iter::valid = false ===DONE=== http://cvs.php.net/viewvc.cgi/php-src/tests/lang/foreachLoopIterator.001.phpt?view=markup&rev=1.1 Index: php-src/tests/lang/foreachLoopIterator.001.phpt +++ php-src/tests/lang/foreachLoopIterator.001.phpt --TEST-- foreach with Iterator. --FILE-- <?php class MealIterator implements Iterator { private $pos=0; private $myContent=array("breakfast", "lunch", "dinner"); public function valid() { global $indent; echo "$indent--> " . __METHOD__ . " ($this->pos)\n"; return $this->pos<3; } public function next() { global $indent; echo "$indent--> " . __METHOD__ . " ($this->pos)\n"; return $this->myContent[$this->pos++]; } public function rewind() { global $indent; echo "$indent--> " . __METHOD__ . " ($this->pos)\n"; $this->pos=0; } public function current() { global $indent; echo "$indent--> " . __METHOD__ . " ($this->pos)\n"; return $this->myContent[$this->pos]; } public function key() { global $indent; echo "$indent--> " . __METHOD__ . " ($this->pos)\n"; return "meal " . $this->pos; } } $f = new MealIterator; var_dump($f); echo "-----( Simple iteration: )-----\n"; foreach ($f as $k=>$v) { echo "$k => $v\n"; } $f->rewind(); $indent = " "; echo "\n\n\n-----( Nested iteration: )-----\n"; $count=1; foreach ($f as $k=>$v) { echo "\nTop level " . $count++ . ": \n"; echo "$k => $v\n"; $indent = " "; foreach ($f as $k=>$v) { echo " $k => $v\n"; } $indent = " "; } ?> ===DONE=== --EXPECTF-- object(MealIterator)#%d (2) { [u"pos":u"MealIterator":private]=> int(0) [u"myContent":u"MealIterator":private]=> array(3) { [0]=> unicode(9) "breakfast" [1]=> unicode(5) "lunch" [2]=> unicode(6) "dinner" } } -----( Simple iteration: )----- --> MealIterator::rewind (0) --> MealIterator::valid (0) --> MealIterator::current (0) --> MealIterator::key (0) meal 0 => breakfast --> MealIterator::next (0) --> MealIterator::valid (1) --> MealIterator::current (1) --> MealIterator::key (1) meal 1 => lunch --> MealIterator::next (1) --> MealIterator::valid (2) --> MealIterator::current (2) --> MealIterator::key (2) meal 2 => dinner --> MealIterator::next (2) --> MealIterator::valid (3) --> MealIterator::rewind (3) -----( Nested iteration: )----- --> MealIterator::rewind (0) --> MealIterator::valid (0) --> MealIterator::current (0) --> MealIterator::key (0) Top level 1: meal 0 => breakfast --> MealIterator::rewind (0) --> MealIterator::valid (0) --> MealIterator::current (0) --> MealIterator::key (0) meal 0 => breakfast --> MealIterator::next (0) --> MealIterator::valid (1) --> MealIterator::current (1) --> MealIterator::key (1) meal 1 => lunch --> MealIterator::next (1) --> MealIterator::valid (2) --> MealIterator::current (2) --> MealIterator::key (2) meal 2 => dinner --> MealIterator::next (2) --> MealIterator::valid (3) --> MealIterator::next (3) Notice: Undefined offset: 3 in %s on line %d --> MealIterator::valid (4) ===DONE===
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php