summaryrefslogtreecommitdiff
path: root/Zend/tests/arrow_functions
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-05-02 14:57:16 +0200
committerNikita Popov <nikita.ppv@gmail.com>2019-05-02 15:04:03 +0200
commitf3e5bbe6f37ce52a9ecd42812389e6aaf3aa2892 (patch)
tree4d7baab746e966624ee4557c2153e5099cbbcbd3 /Zend/tests/arrow_functions
parenteaab0a2b6f6f61bc0b8c42579a74a626b179a070 (diff)
downloadphp-git-f3e5bbe6f37ce52a9ecd42812389e6aaf3aa2892.tar.gz
Implement arrow functions
Per RFC: https://wiki.php.net/rfc/arrow_functions_v2 Co-authored-by: Levi Morrison <levim@php.net> Co-authored-by: Bob Weinand <bobwei9@hotmail.com>
Diffstat (limited to 'Zend/tests/arrow_functions')
-rw-r--r--Zend/tests/arrow_functions/001.phpt45
-rw-r--r--Zend/tests/arrow_functions/002.phpt13
-rw-r--r--Zend/tests/arrow_functions/003.phpt21
-rw-r--r--Zend/tests/arrow_functions/004.phpt13
-rw-r--r--Zend/tests/arrow_functions/005.phpt54
-rw-r--r--Zend/tests/arrow_functions/006.phpt44
-rw-r--r--Zend/tests/arrow_functions/007.phpt14
-rw-r--r--Zend/tests/arrow_functions/008.phpt28
8 files changed, 232 insertions, 0 deletions
diff --git a/Zend/tests/arrow_functions/001.phpt b/Zend/tests/arrow_functions/001.phpt
new file mode 100644
index 0000000000..27b2557b99
--- /dev/null
+++ b/Zend/tests/arrow_functions/001.phpt
@@ -0,0 +1,45 @@
+--TEST--
+Basic arrow function functionality check
+--FILE--
+<?php
+
+$foo = fn() => 1;
+var_dump($foo());
+
+$foo = fn($x) => $x;
+var_dump($foo(2));
+
+$foo = fn($x, $y) => $x + $y;
+var_dump($foo(1, 2));
+
+// Closing over $var
+$var = 4;
+$foo = fn() => $var;
+var_dump($foo());
+
+// Not closing over $var, it's a parameter
+$foo = fn($var) => $var;
+var_dump($foo(5));
+
+// Close over $var by-value, not by-reference
+$var = 5;
+$foo = fn() => ++$var;
+var_dump($foo());
+var_dump($var);
+
+// Nested arrow functions closing over variable
+$var = 6;
+var_dump((fn() => fn() => $var)()());
+var_dump((fn() => function() use($var) { return $var; })()());
+
+?>
+--EXPECT--
+int(1)
+int(2)
+int(3)
+int(4)
+int(5)
+int(6)
+int(5)
+int(6)
+int(6)
diff --git a/Zend/tests/arrow_functions/002.phpt b/Zend/tests/arrow_functions/002.phpt
new file mode 100644
index 0000000000..52c8020c19
--- /dev/null
+++ b/Zend/tests/arrow_functions/002.phpt
@@ -0,0 +1,13 @@
+--TEST--
+Arrow functions implicit use must be throwing notices only upon actual use
+--FILE--
+<?php
+
+$b = 1;
+
+var_dump((fn() => $b + $c)());
+
+?>
+--EXPECTF--
+Notice: Undefined variable: c in %s on line %d
+int(1)
diff --git a/Zend/tests/arrow_functions/003.phpt b/Zend/tests/arrow_functions/003.phpt
new file mode 100644
index 0000000000..5e77743fad
--- /dev/null
+++ b/Zend/tests/arrow_functions/003.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Variable-variables inside arrow functions
+--FILE--
+<?php
+
+$a = 1;
+$var = "a";
+$fn = fn() => $$var;
+var_dump($fn());
+
+${5} = 2;
+$fn = fn() => ${5};
+var_dump($fn());
+
+?>
+--EXPECTF--
+Notice: Undefined variable: a in %s on line %d
+NULL
+
+Notice: Undefined variable: 5 in %s on line %d
+NULL
diff --git a/Zend/tests/arrow_functions/004.phpt b/Zend/tests/arrow_functions/004.phpt
new file mode 100644
index 0000000000..51467dae1d
--- /dev/null
+++ b/Zend/tests/arrow_functions/004.phpt
@@ -0,0 +1,13 @@
+--TEST--
+Auto-globals in arrow functions
+--FILE--
+<?php
+
+// This should work, but *not* generate a binding for $GLOBALS
+$a = 123;
+$fn = fn() => $GLOBALS['a'];
+var_dump($fn());
+
+?>
+--EXPECT--
+int(123)
diff --git a/Zend/tests/arrow_functions/005.phpt b/Zend/tests/arrow_functions/005.phpt
new file mode 100644
index 0000000000..7371be57bb
--- /dev/null
+++ b/Zend/tests/arrow_functions/005.phpt
@@ -0,0 +1,54 @@
+--TEST--
+Arrow function $this binding
+--FILE--
+<?php
+
+class Test {
+ public function method() {
+ // It would be okay if this is NULL, but the rest should work
+ $fn = fn() => 42;
+ $r = new ReflectionFunction($fn);
+ var_dump($r->getClosureThis());
+
+ $fn = fn() => $this;
+ var_dump($fn());
+
+ $fn = fn() => Test::method2();
+ $fn();
+
+ $fn = fn() => call_user_func('Test::method2');
+ $fn();
+
+ $thisName = "this";
+ $fn = fn() => $$thisName;
+ var_dump($fn());
+
+ $fn = fn() => self::class;
+ var_dump($fn());
+
+ // static can be used to unbind $this
+ $fn = static fn() => isset($this);
+ var_dump($fn());
+ }
+
+ public function method2() {
+ var_dump($this);
+ }
+}
+
+(new Test)->method();
+
+?>
+--EXPECT--
+object(Test)#1 (0) {
+}
+object(Test)#1 (0) {
+}
+object(Test)#1 (0) {
+}
+object(Test)#1 (0) {
+}
+object(Test)#1 (0) {
+}
+string(4) "Test"
+bool(false)
diff --git a/Zend/tests/arrow_functions/006.phpt b/Zend/tests/arrow_functions/006.phpt
new file mode 100644
index 0000000000..16427146a8
--- /dev/null
+++ b/Zend/tests/arrow_functions/006.phpt
@@ -0,0 +1,44 @@
+--TEST--
+Arrow functions syntax variations
+--FILE--
+<?php
+
+// By-reference argument and return
+$var = 1;
+$id = fn&(&$x) => $x;
+$ref =& $id($var);
+$ref++;
+var_dump($var);
+
+// int argument and return type
+$var = 10;
+$int_fn = fn(int $x): int => $x;
+var_dump($int_fn($var));
+try {
+ $int_fn("foo");
+} catch (TypeError $e) {
+ echo $e->getMessage(), "\n";
+}
+
+$varargs = fn(?int... $args): array => $args;
+var_dump($varargs(20, null, 30));
+try {
+ $varargs(40, "foo");
+} catch (TypeError $e) {
+ echo $e->getMessage(), "\n";
+}
+
+?>
+--EXPECTF--
+int(2)
+int(10)
+Argument 1 passed to {closure}() must be of the type int, string given, called in %s on line %d
+array(3) {
+ [0]=>
+ int(20)
+ [1]=>
+ NULL
+ [2]=>
+ int(30)
+}
+Argument 2 passed to {closure}() must be of the type int or null, string given, called in %s on line %d
diff --git a/Zend/tests/arrow_functions/007.phpt b/Zend/tests/arrow_functions/007.phpt
new file mode 100644
index 0000000000..0fcc4930d1
--- /dev/null
+++ b/Zend/tests/arrow_functions/007.phpt
@@ -0,0 +1,14 @@
+--TEST--
+Pretty printing for arrow functions
+--FILE--
+<?php
+
+// TODO We're missing parentheses for the direct call
+assert((fn() => false)());
+assert((fn&(int... $args): ?bool => $args[0])(false));
+
+?>
+--EXPECTF--
+Warning: assert(): assert(fn() => false()) failed in %s on line %d
+
+Warning: assert(): assert(fn&(int ...$args): ?bool => $args[0](false)) failed in %s on line %d
diff --git a/Zend/tests/arrow_functions/008.phpt b/Zend/tests/arrow_functions/008.phpt
new file mode 100644
index 0000000000..df3fe5dba7
--- /dev/null
+++ b/Zend/tests/arrow_functions/008.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Yield inside arrow functions
+--FILE--
+<?php
+
+// This doesn't make terribly much sense, but it works...
+
+$fn = fn() => yield 123;
+foreach ($fn() as $val) {
+ var_dump($val);
+}
+
+$fn = fn() => yield from [456, 789];
+foreach ($fn() as $val) {
+ var_dump($val);
+}
+
+$fn = fn() => fn() => yield 987;
+foreach ($fn()() as $val) {
+ var_dump($val);
+}
+
+?>
+--EXPECT--
+int(123)
+int(456)
+int(789)
+int(987)