Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Zend/tests/pipe_operator/assign_pipe_001.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
--TEST--
Pipe assign operator basic usage with first-class callable
--FILE--
<?php

$x = "hello";
$x |>= strtoupper(...);
var_dump($x);

?>
--EXPECT--
string(5) "HELLO"
29 changes: 29 additions & 0 deletions Zend/tests/pipe_operator/assign_pipe_002.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
--TEST--
Pipe assign operator with closures and arrow functions
--FILE--
<?php

$x = 5;
$x |>= (fn($v) => $v * 2);
var_dump($x);

$y = "hello world";
$y |>= (function($s) { return strtoupper($s); });
var_dump($y);

$arr = [5, 2, 8, 1, 9];
$arr |>= (fn($a) => array_filter($a, fn($n) => $n > 3));
var_dump($arr);

?>
--EXPECT--
int(10)
string(11) "HELLO WORLD"
array(3) {
[0]=>
int(5)
[2]=>
int(8)
[4]=>
int(9)
}
21 changes: 21 additions & 0 deletions Zend/tests/pipe_operator/assign_pipe_003.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
--TEST--
Pipe assign operator chain support (multiple |> on RHS)
--FILE--
<?php

$val = 10;
$val |>= (fn($v) => $v * 2) |> (fn($v) => $v + 3) |> (fn($v) => $v * $v);
var_dump($val);

$data = " the quick brown FOX ";
$data |>= trim(...)
|> strtolower(...)
|> (fn($s) => explode(" ", $s))
|> (fn($a) => array_map(ucfirst(...), $a))
|> (fn($a) => implode("-", $a));
var_dump($data);

?>
--EXPECT--
int(529)
string(19) "The-Quick-Brown-Fox"
35 changes: 35 additions & 0 deletions Zend/tests/pipe_operator/assign_pipe_004.phpt
Comment thread
calebdw marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
--TEST--
Pipe assign operator with all variable target types
--FILE--
<?php

$x = "hello";
$x |>= strtoupper(...);
Comment thread
calebdw marked this conversation as resolved.
var_dump($x);

$data = ["key" => "hello"];
$data["key"] |>= strtoupper(...);
var_dump($data["key"]);

$nested = ["a" => ["b" => "hello"]];
$nested["a"]["b"] |>= strtoupper(...);
var_dump($nested["a"]["b"]);

$obj = new stdClass;
$obj->name = "hello";
$obj->name |>= strtoupper(...);
var_dump($obj->name);

class Foo {
public static string $val = "hello";
}
Foo::$val |>= strtoupper(...);
var_dump(Foo::$val);

?>
--EXPECT--
string(5) "HELLO"
string(5) "HELLO"
string(5) "HELLO"
string(5) "HELLO"
string(5) "HELLO"
27 changes: 27 additions & 0 deletions Zend/tests/pipe_operator/assign_pipe_005.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
--TEST--
Pipe assign operator single-evaluation semantics
--FILE--
<?php

$counter = 0;
function track(): int {
global $counter;
$counter++;
echo "track() called (call #", $counter, ")", PHP_EOL;
return 0;
}

$arr = ["hello"];
$arr[track()] |>= strtoupper(...);

echo "track() was called ", $counter, " time(s)", PHP_EOL;
var_dump($arr);

?>
--EXPECT--
track() called (call #1)
track() was called 1 time(s)
array(1) {
[0]=>
string(5) "HELLO"
}
11 changes: 11 additions & 0 deletions Zend/tests/pipe_operator/assign_pipe_006.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
--TEST--
Pipe assign operator error: unparenthesized arrow function
--FILE--
<?php

$x = 5;
$x |>= fn($v) => $v * 2;

?>
--EXPECTF--
Fatal error: Arrow functions on the right hand side of |>= must be parenthesized in %s on line %d
14 changes: 14 additions & 0 deletions Zend/tests/pipe_operator/assign_pipe_007.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
--TEST--
Pipe assign operator error: cannot reassign $this
--FILE--
<?php

class Bar {
public function test() {
$this |>= trim(...);
}
}

?>
--EXPECTF--
Fatal error: Cannot re-assign $this in %s on line %d
23 changes: 23 additions & 0 deletions Zend/tests/pipe_operator/assign_pipe_008.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
--TEST--
Pipe assign operator error: by-reference rejection
--FILE--
<?php

function modify_ref(int &$a): int {
$a += 1;
return $a;
}

try {
$a = 5;
$a |>= modify_ref(...);
} catch (\Error $e) {
echo $e::class, ": ", $e->getMessage(), PHP_EOL;
}

var_dump($a);

?>
--EXPECTF--
Error: modify_ref(): Argument #1 ($a) could not be passed by reference
int(5)
41 changes: 41 additions & 0 deletions Zend/tests/pipe_operator/assign_pipe_009.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
--TEST--
Pipe assign operator expression result and precedence
--FILE--
<?php

function triple(int $x): int { return $x * 3; }
function add_five(int $x): int { return $x + 5; }
function to_string(int $x): string { return "value:$x"; }

$x = 5;
$result = ($x |>= triple(...));
var_dump($x, $result);

$e = 4;
$f = ($e |>= triple(...)) |> add_five(...) |> to_string(...);
Comment thread
calebdw marked this conversation as resolved.
var_dump($e, $f);

// Right-associativity
// Parses as: $foo |>= ($bar |>= x(...))
// 1. $bar |>= x(...) calls x(0), which prints int(0) and returns a Closure
// 2. $bar is assigned the Closure
// 3. $foo |>= <Closure> calls Closure(1) = 2
// 4. $foo is assigned 2
function x(int $bar): Closure {
var_dump($bar);
return function (int $foo): int { return $foo + 1; };
}
$bar = 0;
$foo = 1;
$foo |>= $bar |>= x(...);
var_dump($bar instanceof Closure, $foo);

?>
--EXPECT--
int(15)
int(15)
int(12)
string(8) "value:17"
int(0)
bool(true)
int(2)
47 changes: 47 additions & 0 deletions Zend/tests/pipe_operator/assign_pipe_010.phpt
Comment thread
calebdw marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
--TEST--
Pipe assign operator with mixed callable types
--FILE--
<?php

function double(int $x): int { return $x * 2; }

class Math {
public function triple(int $x): int { return $x * 3; }
public static function quadruple(int $x): int { return $x * 4; }
}

$math = new Math();

$v1 = 5;
$v1 |>= double(...);
var_dump($v1);

$v2 = 5;
$v2 |>= $math->triple(...);
var_dump($v2);

$v3 = 5;
$v3 |>= Math::quadruple(...);
var_dump($v3);

class Multiplier {
public function __construct(private int $factor) {}
public function __invoke(int $x): int { return $x * $this->factor; }
}

$v4 = 5;
$v4 |>= new Multiplier(10);
var_dump($v4);

$times6 = fn($x) => $x * 6;
$v5 = 5;
$v5 |>= $times6;
var_dump($v5);

?>
--EXPECT--
int(10)
int(15)
int(20)
int(50)
int(30)
18 changes: 18 additions & 0 deletions Zend/tests/pipe_operator/assign_pipe_011.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
--TEST--
Pipe assign operator with mixed callable types in chains
--FILE--
<?php

function add_prefix(string $s): string { return "prefix_" . $s; }

class Transform {
public static function upper(string $s): string { return strtoupper($s); }
}

$s = "hello";
$s |>= add_prefix(...) |> Transform::upper(...) |> (fn($s) => $s . "_done");
var_dump($s);

?>
--EXPECT--
string(17) "PREFIX_HELLO_done"
22 changes: 22 additions & 0 deletions Zend/tests/pipe_operator/assign_pipe_012.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
--TEST--
Pipe assign operator sequential usage equivalent to chain
--FILE--
<?php

$s = " Hello World ";
$s |>= trim(...);
$s |>= strtolower(...);
$s |>= (fn($s) => str_replace(" ", "-", $s));
var_dump($s);

$s2 = " Hello World ";
$s2 |>= trim(...) |> strtolower(...) |> (fn($s) => str_replace(" ", "-", $s));
var_dump($s2);

var_dump($s === $s2);

?>
--EXPECT--
string(11) "hello-world"
string(11) "hello-world"
bool(true)
22 changes: 22 additions & 0 deletions Zend/tests/pipe_operator/assign_pipe_013.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
--TEST--
Pipe assign operator exception interruption
--FILE--
<?php

function will_throw(int $x): int {
throw new RuntimeException("interrupted at $x");
}

$x = 42;
try {
$x |>= (fn($v) => $v * 2) |> will_throw(...);
} catch (RuntimeException $e) {
echo $e::class, ": ", $e->getMessage(), PHP_EOL;
}

var_dump($x);

?>
--EXPECT--
RuntimeException: interrupted at 84
int(42)
21 changes: 21 additions & 0 deletions Zend/tests/pipe_operator/assign_pipe_014.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
--TEST--
Pipe assign operator with userland function chains
--FILE--
<?php

function double(int $x): int { return $x * 2; }
function increment(int $x): int { return $x + 1; }
function square(int $x): int { return $x * $x; }

$a = 5;
$a |>= double(...);
var_dump($a);

$b = 3;
$b |>= double(...) |> increment(...) |> square(...);
var_dump($b);

?>
--EXPECT--
int(10)
int(49)
12 changes: 12 additions & 0 deletions Zend/tests/pipe_operator/assign_pipe_015.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
--TEST--
Pipe assign operator error: cannot use function call as target
--FILE--
<?php

function getVal(): string { return "hello"; }

getVal() |>= strtoupper(...);

?>
--EXPECTF--
Fatal error: Can't use function return value in write context in %s on line %d
Loading
Loading