summaryrefslogtreecommitdiff
path: root/Zend/tests
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2008-07-14 09:49:03 +0000
committerDmitry Stogov <dmitry@php.net>2008-07-14 09:49:03 +0000
commitd5ef2f466cb112fd977a71419fa4b67d0aa0a2ac (patch)
tree2f61549b96e8db664a1467f36ce11772600c86a9 /Zend/tests
parentd23342397c14a6efb3e0b1ea20928f81ccc48657 (diff)
downloadphp-git-d5ef2f466cb112fd977a71419fa4b67d0aa0a2ac.tar.gz
Added support for lambda functions and closures
Diffstat (limited to 'Zend/tests')
-rw-r--r--Zend/tests/closure_001.phpt30
-rw-r--r--Zend/tests/closure_002.phpt29
-rw-r--r--Zend/tests/closure_003.phpt33
-rw-r--r--Zend/tests/closure_004.phpt35
-rw-r--r--Zend/tests/closure_005.phpt74
-rw-r--r--Zend/tests/closure_006.phpt19
-rw-r--r--Zend/tests/closure_007.phpt38
-rw-r--r--Zend/tests/closure_008.phpt22
-rw-r--r--Zend/tests/closure_009.phpt31
-rw-r--r--Zend/tests/closure_010.phpt18
-rw-r--r--Zend/tests/closure_011.phpt14
-rw-r--r--Zend/tests/closure_012.phpt24
-rw-r--r--Zend/tests/closure_013.phpt25
-rw-r--r--Zend/tests/closure_014.phpt79
-rw-r--r--Zend/tests/closure_015.phpt13
15 files changed, 484 insertions, 0 deletions
diff --git a/Zend/tests/closure_001.phpt b/Zend/tests/closure_001.phpt
new file mode 100644
index 0000000000..ebac729b16
--- /dev/null
+++ b/Zend/tests/closure_001.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Closure 001: Lambda without lexical variables
+--FILE--
+<?php
+
+$lambda1 = function () {
+ echo "Hello World!\n";
+};
+
+$lambda2 = function ($x) {
+ echo "Hello $x!\n";
+};
+
+var_dump(is_callable($lambda1));
+var_dump(is_callable($lambda2));
+$lambda1();
+$lambda2("Universe");
+call_user_func($lambda1);
+call_user_func($lambda2, "Universe");
+
+echo "Done\n";
+?>
+--EXPECT--
+bool(true)
+bool(true)
+Hello World!
+Hello Universe!
+Hello World!
+Hello Universe!
+Done
diff --git a/Zend/tests/closure_002.phpt b/Zend/tests/closure_002.phpt
new file mode 100644
index 0000000000..023d4ecff1
--- /dev/null
+++ b/Zend/tests/closure_002.phpt
@@ -0,0 +1,29 @@
+--TEST--
+Closure 002: Lambda with lexical variables (global scope)
+--FILE--
+<?php
+
+$x = 4;
+
+$lambda1 = function () use ($x) {
+ echo "$x\n";
+};
+
+$lambda2 = function () use (&$x) {
+ echo "$x\n";
+};
+
+$lambda1();
+$lambda2();
+$x++;
+$lambda1();
+$lambda2();
+
+echo "Done\n";
+?>
+--EXPECT--
+4
+4
+4
+5
+Done
diff --git a/Zend/tests/closure_003.phpt b/Zend/tests/closure_003.phpt
new file mode 100644
index 0000000000..6f5cc70bf1
--- /dev/null
+++ b/Zend/tests/closure_003.phpt
@@ -0,0 +1,33 @@
+--TEST--
+Closure 003: Lambda with lexical variables (local scope)
+--FILE--
+<?php
+
+function run () {
+ $x = 4;
+
+ $lambda1 = function () use ($x) {
+ echo "$x\n";
+ };
+
+ $lambda2 = function () use (&$x) {
+ echo "$x\n";
+ };
+
+ $lambda1();
+ $lambda2();
+ $x++;
+ $lambda1();
+ $lambda2();
+}
+
+run();
+
+echo "Done\n";
+?>
+--EXPECT--
+4
+4
+4
+5
+Done
diff --git a/Zend/tests/closure_004.phpt b/Zend/tests/closure_004.phpt
new file mode 100644
index 0000000000..c1c2efb25c
--- /dev/null
+++ b/Zend/tests/closure_004.phpt
@@ -0,0 +1,35 @@
+--TEST--
+Closure 004: Lambda with lexical variables (scope lifetime)
+--FILE--
+<?php
+
+function run () {
+ $x = 4;
+
+ $lambda1 = function () use ($x) {
+ echo "$x\n";
+ };
+
+ $lambda2 = function () use (&$x) {
+ echo "$x\n";
+ $x++;
+ };
+
+ return array($lambda1, $lambda2);
+}
+
+list ($lambda1, $lambda2) = run();
+
+$lambda1();
+$lambda2();
+$lambda1();
+$lambda2();
+
+echo "Done\n";
+?>
+--EXPECT--
+4
+4
+4
+5
+Done
diff --git a/Zend/tests/closure_005.phpt b/Zend/tests/closure_005.phpt
new file mode 100644
index 0000000000..4e32faa017
--- /dev/null
+++ b/Zend/tests/closure_005.phpt
@@ -0,0 +1,74 @@
+--TEST--
+Closure 005: Lambda inside class, lifetime of $this
+--FILE--
+<?php
+
+class A {
+ private $x;
+
+ function __construct($x) {
+ $this->x = $x;
+ }
+
+ function __destruct() {
+ echo "Destroyed\n";
+ }
+
+ function getIncer($val) {
+ return function() use ($val) {
+ $this->x += $val;
+ };
+ }
+
+ function getPrinter() {
+ return function() {
+ echo $this->x."\n";
+ };
+ }
+
+ function getError() {
+ return static function() {
+ echo $this->x."\n";
+ };
+ }
+
+ function printX() {
+ echo $this->x."\n";
+ }
+}
+
+$a = new A(3);
+$incer = $a->getIncer(2);
+$printer = $a->getPrinter();
+$error = $a->getError();
+
+$a->printX();
+$printer();
+$incer();
+$a->printX();
+$printer();
+
+unset($a);
+
+$incer();
+$printer();
+
+unset($incer);
+$printer();
+
+unset($printer);
+
+$error();
+
+echo "Done\n";
+?>
+--EXPECTF--
+3
+3
+5
+5
+7
+7
+Destroyed
+
+Fatal error: Using $this when not in object context in %sclosure_005.php on line 28
diff --git a/Zend/tests/closure_006.phpt b/Zend/tests/closure_006.phpt
new file mode 100644
index 0000000000..aa0ec11995
--- /dev/null
+++ b/Zend/tests/closure_006.phpt
@@ -0,0 +1,19 @@
+--TEST--
+Closure 006: Nested lambdas
+--FILE--
+<?php
+
+$getClosure = function ($v) {
+ return function () use ($v) {
+ echo "Hello World: $v!\n";
+ };
+};
+
+$closure = $getClosure (2);
+$closure ();
+
+echo "Done\n";
+?>
+--EXPECT--
+Hello World: 2!
+Done
diff --git a/Zend/tests/closure_007.phpt b/Zend/tests/closure_007.phpt
new file mode 100644
index 0000000000..89cd06d8a1
--- /dev/null
+++ b/Zend/tests/closure_007.phpt
@@ -0,0 +1,38 @@
+--TEST--
+Closure 007: Nested lambdas in classes
+--FILE--
+<?php
+
+class A {
+ private $x = 0;
+
+ function getClosureGetter () {
+ return function () {
+ return function () {
+ $this->x++;
+ };
+ };
+ }
+
+ function printX () {
+ echo $this->x."\n";
+ }
+}
+
+$a = new A;
+$a->printX();
+$getClosure = $a->getClosureGetter();
+$a->printX();
+$closure = $getClosure();
+$a->printX();
+$closure();
+$a->printX();
+
+echo "Done\n";
+?>
+--EXPECT--
+0
+0
+0
+1
+Done
diff --git a/Zend/tests/closure_008.phpt b/Zend/tests/closure_008.phpt
new file mode 100644
index 0000000000..77b50de8ab
--- /dev/null
+++ b/Zend/tests/closure_008.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Closure 008: Use in preg_replace()
+--FILE--
+<?php
+
+function replace_spaces($text) {
+ $lambda = function ($matches) {
+ return str_replace(' ', '&nbsp;', $matches[1]).' ';
+ };
+ return preg_replace_callback('/( +) /', $lambda, $text);
+}
+
+echo replace_spaces("1 2 3\n");
+echo replace_spaces("1 2 3\n");
+echo replace_spaces("1 2 3\n");
+echo "Done\n";
+?>
+--EXPECT--
+1 2 3
+1&nbsp; 2&nbsp; 3
+1&nbsp;&nbsp; 2&nbsp;&nbsp; 3
+Done
diff --git a/Zend/tests/closure_009.phpt b/Zend/tests/closure_009.phpt
new file mode 100644
index 0000000000..10ec32b80d
--- /dev/null
+++ b/Zend/tests/closure_009.phpt
@@ -0,0 +1,31 @@
+--TEST--
+Closure 009: Use in preg_replace()
+--FILE--
+<?php
+$a = 1;
+$x = function ($x) use ($a) {
+ static $n = 0;
+ $n++;
+ $a = $n.':'.$a;
+ echo $x.':'.$a."\n";
+};
+$y = function ($x) use (&$a) {
+ static $n = 0;
+ $n++;
+ $a = $n.':'.$a;
+ echo $x.':'.$a."\n";
+};
+$x(1);
+$x(2);
+$x(3);
+$y(4);
+$y(5);
+$y(6);
+?>
+--EXPECT--
+1:1:1
+2:2:1
+3:3:1
+4:1:1
+5:2:1:1
+6:3:2:1:1
diff --git a/Zend/tests/closure_010.phpt b/Zend/tests/closure_010.phpt
new file mode 100644
index 0000000000..d4787f0a2b
--- /dev/null
+++ b/Zend/tests/closure_010.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Closure 010: Closure calls itself
+--FILE--
+<?php
+$i = 3;
+$lambda = function ($lambda) use (&$i) {
+ if ($i==0) return;
+ echo $i--."\n";
+ $lambda($lambda);
+};
+$lambda($lambda);
+echo "$i\n";
+?>
+--EXPECT--
+3
+2
+1
+0
diff --git a/Zend/tests/closure_011.phpt b/Zend/tests/closure_011.phpt
new file mode 100644
index 0000000000..707136463d
--- /dev/null
+++ b/Zend/tests/closure_011.phpt
@@ -0,0 +1,14 @@
+--TEST--
+Closure 011: Lexical copies not static in closure
+--FILE--
+<?php
+$i = 1;
+$lambda = function () use ($i) {
+ return ++$i;
+};
+$lambda();
+echo $lambda()."\n";
+//early prototypes gave 3 here because $i was static in $lambda
+?>
+--EXPECT--
+2
diff --git a/Zend/tests/closure_012.phpt b/Zend/tests/closure_012.phpt
new file mode 100644
index 0000000000..7e1b7a2793
--- /dev/null
+++ b/Zend/tests/closure_012.phpt
@@ -0,0 +1,24 @@
+--TEST--
+Closure 012: Undefined lexical variables
+--FILE--
+<?php
+$lambda = function () use ($i) {
+ return ++$i;
+};
+$lambda();
+$lambda();
+var_dump($i);
+$lambda = function () use (&$i) {
+ return ++$i;
+};
+$lambda();
+$lambda();
+var_dump($i);
+?>
+--EXPECTF--
+Notice: Undefined variable: i in %sclosure_012.php on line 2
+
+Notice: Undefined variable: i in %sclosure_012.php on line 7
+NULL
+int(2)
+
diff --git a/Zend/tests/closure_013.phpt b/Zend/tests/closure_013.phpt
new file mode 100644
index 0000000000..72d2b3f963
--- /dev/null
+++ b/Zend/tests/closure_013.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Closure 013: __invoke() on temporary result
+--FILE--
+<?php
+class Foo {
+ function __invoke() {
+ echo "Hello World!\n";
+ }
+}
+
+function foo() {
+ return function() {
+ echo "Hello World!\n";
+ };
+}
+$test = new Foo;
+$test->__invoke();
+$test = foo();
+$test->__invoke();
+$test = foo()->__invoke();
+?>
+--EXPECT--
+Hello World!
+Hello World!
+Hello World!
diff --git a/Zend/tests/closure_014.phpt b/Zend/tests/closure_014.phpt
new file mode 100644
index 0000000000..9e4819b9dd
--- /dev/null
+++ b/Zend/tests/closure_014.phpt
@@ -0,0 +1,79 @@
+--TEST--
+Closure 014: return by value/reference
+--FILE--
+<?php
+class C1 {
+ function __invoke() {
+ return 0;
+ }
+}
+class C2 {
+ function &__invoke(&$a) {
+ return $a;
+ }
+}
+class C3 {
+ function __invoke() {
+ }
+}
+
+$x = new C1();
+var_dump($x());
+var_dump($x->__invoke());
+$x();
+$x->__invoke();
+$x = function() {
+ return 0;
+};
+var_dump($x());
+var_dump($x->__invoke());
+$x();
+$x->__invoke();
+
+$x = new C2();
+$a = $b = $c = $d = 1;
+$e =& $x($a);
+$e = 2;
+var_dump($a);
+$e =& $x->__invoke($b);
+$e = 3;
+var_dump($b);
+$x($b);
+$x->__invoke($b);
+$x = function & (&$a) {
+ return $a;
+};
+$e =& $x($c);
+$e = 4;
+var_dump($c);
+$e =& $x->__invoke($d);
+$e = 5;
+var_dump($d);
+$x($d);
+$x->__invoke($d);
+
+$x = new C3();
+var_dump($x());
+var_dump($x->__invoke());
+$x();
+$x->__invoke();
+$x = function() {
+};
+var_dump($x());
+var_dump($x->__invoke());
+$x();
+$x->__invoke();
+?>
+--EXPECT--
+int(0)
+int(0)
+int(0)
+int(0)
+int(2)
+int(3)
+int(4)
+int(5)
+NULL
+NULL
+NULL
+NULL
diff --git a/Zend/tests/closure_015.phpt b/Zend/tests/closure_015.phpt
new file mode 100644
index 0000000000..d21aca5721
--- /dev/null
+++ b/Zend/tests/closure_015.phpt
@@ -0,0 +1,13 @@
+--TEST--
+Closure 015: converting to string/unicode
+--FILE--
+<?php
+$x = function() { return 1; };
+print (string) $x;
+print "\n";
+print $x;
+print "\n";
+?>
+--EXPECT--
+Closure object
+Closure object