diff options
author | andy wharmby <wharmby@php.net> | 2009-06-17 19:07:17 +0000 |
---|---|---|
committer | andy wharmby <wharmby@php.net> | 2009-06-17 19:07:17 +0000 |
commit | fb3132f502265e3602f4ab4bb0f0f5d93ad1fff4 (patch) | |
tree | 9e18915db27e8d63cc0d61a371aadbbbcef4f06c /tests/lang | |
parent | b685def15acadf29e0657dc6bce3c53404948f3b (diff) | |
download | php-git-fb3132f502265e3602f4ab4bb0f0f5d93ad1fff4.tar.gz |
New foreach tests. Tested on Windows, Linux and Linux 64 bit.
Diffstat (limited to 'tests/lang')
-rw-r--r-- | tests/lang/foreachLoopIterator.001.phpt | 134 | ||||
-rw-r--r-- | tests/lang/foreachLoopIterator.002.phpt | 24 | ||||
-rw-r--r-- | tests/lang/foreachLoopIteratorAggregate.001.phpt | 270 | ||||
-rw-r--r-- | tests/lang/foreachLoopIteratorAggregate.002.phpt | 53 | ||||
-rw-r--r-- | tests/lang/foreachLoopIteratorAggregate.003.phpt | 133 | ||||
-rw-r--r-- | tests/lang/foreachLoopIteratorAggregate.004.phpt | 104 |
6 files changed, 718 insertions, 0 deletions
diff --git a/tests/lang/foreachLoopIterator.001.phpt b/tests/lang/foreachLoopIterator.001.phpt new file mode 100644 index 0000000000..c049cb7668 --- /dev/null +++ b/tests/lang/foreachLoopIterator.001.phpt @@ -0,0 +1,134 @@ +--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) { + ["pos":"MealIterator":private]=> + int(0) + ["myContent":"MealIterator":private]=> + array(3) { + [0]=> + string(9) "breakfast" + [1]=> + string(5) "lunch" + [2]=> + string(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===
\ No newline at end of file diff --git a/tests/lang/foreachLoopIterator.002.phpt b/tests/lang/foreachLoopIterator.002.phpt new file mode 100644 index 0000000000..f40e09b3c3 --- /dev/null +++ b/tests/lang/foreachLoopIterator.002.phpt @@ -0,0 +1,24 @@ +--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
\ No newline at end of file diff --git a/tests/lang/foreachLoopIteratorAggregate.001.phpt b/tests/lang/foreachLoopIteratorAggregate.001.phpt new file mode 100644 index 0000000000..b20d3ea3c5 --- /dev/null +++ b/tests/lang/foreachLoopIteratorAggregate.001.phpt @@ -0,0 +1,270 @@ +--TEST-- +foreach with iteratorAggregate +--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) { + ["storedEnglishMealIterator":"EuropeanMeals":private]=> + object(EnglishMealIterator)#%d (2) { + ["pos":"EnglishMealIterator":private]=> + int(0) + ["myContent":"EnglishMealIterator":private]=> + array(3) { + [0]=> + string(9) "breakfast" + [1]=> + string(6) "dinner" + [2]=> + string(3) "tea" + } + } + ["storedFrenchMealIterator":"EuropeanMeals":private]=> + object(FrenchMealIterator)#%d (2) { + ["pos":"FrenchMealIterator":private]=> + int(0) + ["myContent":"FrenchMealIterator":private]=> + array(4) { + [0]=> + string(14) "petit dejeuner" + [1]=> + string(8) "dejeuner" + [2]=> + string(6) "gouter" + [3]=> + string(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===
\ No newline at end of file diff --git a/tests/lang/foreachLoopIteratorAggregate.002.phpt b/tests/lang/foreachLoopIteratorAggregate.002.phpt new file mode 100644 index 0000000000..eef430237f --- /dev/null +++ b/tests/lang/foreachLoopIteratorAggregate.002.phpt @@ -0,0 +1,53 @@ +--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===
\ No newline at end of file diff --git a/tests/lang/foreachLoopIteratorAggregate.003.phpt b/tests/lang/foreachLoopIteratorAggregate.003.phpt new file mode 100644 index 0000000000..0a0e23c51a --- /dev/null +++ b/tests/lang/foreachLoopIteratorAggregate.003.phpt @@ -0,0 +1,133 @@ +--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=== diff --git a/tests/lang/foreachLoopIteratorAggregate.004.phpt b/tests/lang/foreachLoopIteratorAggregate.004.phpt new file mode 100644 index 0000000000..9a1e612c23 --- /dev/null +++ b/tests/lang/foreachLoopIteratorAggregate.004.phpt @@ -0,0 +1,104 @@ +--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=== |