nur-sery/tests/php/funcTest.php

1168 lines
31 KiB
PHP

<?php
namespace nur\sery\php {
use nulib\tests\TestCase;
use nur\sery\ValueException;
use nur\sery\php\impl\C0;
use nur\sery\php\impl\C1;
use nur\sery\php\impl\SC;
use ReflectionException;
class funcTest extends TestCase {
const FUNCTION_TESTS = [
# scalaires
[null,
false, null,
false, null,
],
[false,
false, null,
false, null,
],
["",
false, null,
false, null,
],
["::",
false, null,
false, null,
],
["->",
false, null,
false, null,
],
["tsimple",
true, [false, "tsimple"],
true, [false, "tsimple"],
],
['nur\sery\php\impl\ntsimple',
true, [false, 'nur\sery\php\impl\ntsimple'],
true, [false, 'nur\sery\php\impl\ntsimple'],
],
['tmissing',
false, null,
true, [false, 'tmissing'],
],
["::tstatic",
false, null,
false, null,
],
["->tmethod",
false, null,
false, null,
],
["::tmissing",
false, null,
false, null,
],
["->tmissing",
false, null,
false, null,
],
["xxx::tmissing",
false, null,
false, null,
],
["xxx->tmissing",
false, null,
false, null,
],
[SC::class."::tstatic",
false, null,
false, null,
],
[SC::class."->tmethod",
false, null,
false, null,
],
[SC::class."::tmissing",
false, null,
false, null,
],
[SC::class."->tmissing",
false, null,
false, null,
],
# tableaux avec un seul scalaire
[[],
false, null,
false, null,
],
[[null],
false, null,
false, null,
],
[[false],
false, null,
false, null,
],
[[""],
false, null,
false, null,
],
[["::"],
false, null,
false, null,
],
[["->"],
false, null,
false, null,
],
[["tsimple"],
false, null,
false, null,
],
[['nur\sery\php\impl\ntsimple'],
false, null,
false, null,
],
[["::tstatic"],
false, null,
false, null,
],
[["->tmethod"],
false, null,
false, null,
],
[["::tmissing"],
false, null,
false, null,
],
[["->tmissing"],
false, null,
false, null,
],
[["xxx::tmissing"],
false, null,
false, null,
],
[["xxx->tmissing"],
false, null,
false, null,
],
[[SC::class."::tstatic"],
false, null,
false, null,
],
[[SC::class."->tmethod"],
false, null,
false, null,
],
[[SC::class."::tmissing"],
false, null,
false, null,
],
[[SC::class."->tmissing"],
false, null,
false, null,
],
# tableaux avec deux scalaires
[[null, "tsimple"],
false, null,
false, null,
],
[[null, 'nur\sery\php\impl\ntsimple'],
false, null,
false, null,
],
[[null, "tmissing"],
false, null,
false, null,
],
[[null, "::tstatic"],
false, null,
false, null,
],
[[null, "->tmethod"],
false, null,
false, null,
],
[[null, "::tmissing"],
false, null,
false, null,
],
[[null, "->tmissing"],
false, null,
false, null,
],
[[false, "tsimple"],
true, [false, "tsimple"],
true, [false, "tsimple"],
],
[[false, 'nur\sery\php\impl\ntsimple'],
true, [false, 'nur\sery\php\impl\ntsimple'],
true, [false, 'nur\sery\php\impl\ntsimple'],
],
[[false, "tmissing"],
false, null,
true, [false, "tmissing"],
],
[[false, "::tstatic"],
false, null,
false, null,
],
[[false, "->tmethod"],
false, null,
false, null,
],
[[false, "::tmissing"],
false, null,
false, null,
],
[[false, "->tmissing"],
false, null,
false, null,
],
[["", "tsimple"],
false, null,
false, null,
],
[["", 'nur\sery\php\impl\ntsimple'],
false, null,
false, null,
],
[["", "tmissing"],
false, null,
false, null,
],
[["", "::tstatic"],
false, null,
false, null,
],
[["", "->tmethod"],
false, null,
false, null,
],
[["", "::tmissing"],
false, null,
false, null,
],
[["", "->tmissing"],
false, null,
false, null,
],
[["xxx", "tmissing"],
false, null,
false, null,
],
[["xxx", "::tmissing"],
false, null,
false, null,
],
[["xxx", "->tmissing"],
false, null,
false, null,
],
[[SC::class, "tstatic"],
false, null,
false, null,
],
[[SC::class, "::tstatic"],
false, null,
false, null,
],
[[SC::class, "tmethod"],
false, null,
false, null,
],
[[SC::class, "->tmethod"],
false, null,
false, null,
],
[[SC::class, "tmissing"],
false, null,
false, null,
],
[[SC::class, "::tmissing"],
false, null,
false, null,
],
[[SC::class, "->tmissing"],
false, null,
false, null,
],
];
function testFunction() {
foreach (self::FUNCTION_TESTS as $args) {
[$func,
$verifix1, $func1,
$verifix2, $func2,
] = $args;
if ($func === ["", "tsimple"]) {
//echo "breakpoint";
}
$workf = $func;
$msg = var_export($func, true)." (strict)";
self::assertSame($verifix1, func::verifix_function($workf, true), "$msg --> verifix");
if ($verifix1) {
self::assertSame($func1, $workf, "$msg --> func");
}
$workf = $func;
$msg = var_export($func, true)." (lenient)";
self::assertSame($verifix2, func::verifix_function($workf, false), "$msg --> verifix");
if ($verifix2) {
self::assertSame($func2, $workf, "$msg --> func");
}
}
}
const STATIC_TESTS = [
# scalaires
[null,
false, null, null,
false, null, null,
],
[false,
false, null, null,
false, null, null,
],
["",
false, null, null,
false, null, null,
],
["::",
false, null, null,
false, null, null,
],
["->",
false, null, null,
false, null, null,
],
["tsimple",
false, null, null,
false, null, null,
],
['nur\sery\php\impl\ntsimple',
false, null, null,
false, null, null,
],
['tmissing',
false, null, null,
false, null, null,
],
["::tstatic",
true, false, [null, "tstatic"],
true, false, [null, "tstatic"],
],
["->tmethod",
false, null, null,
false, null, null,
],
["::tmissing",
true, false, [null, "tmissing"],
true, false, [null, "tmissing"],
],
["->tmissing",
false, null, null,
false, null, null,
],
["xxx::tmissing",
false, null, null,
true, true, ["xxx", "tmissing"],
],
["xxx->tmissing",
false, null, null,
false, null, null,
],
[SC::class."::tstatic",
true, true, [SC::class, "tstatic"],
true, true, [SC::class, "tstatic"],
],
[SC::class."->tmethod",
false, null, null,
false, null, null,
],
[SC::class."::tmissing",
false, null, null,
true, true, [SC::class, "tmissing"],
],
[SC::class."->tmissing",
false, null, null,
false, null, null,
],
# tableaux avec un seul scalaire
[[],
false, null, null,
false, null, null,
],
[[null],
false, null, null,
false, null, null,
],
[[false],
false, null, null,
false, null, null,
],
[[""],
false, null, null,
false, null, null,
],
[["::"],
false, null, null,
false, null, null,
],
[["->"],
false, null, null,
false, null, null,
],
[["tsimple"],
false, null, null,
false, null, null,
],
[['nur\sery\php\impl\ntsimple'],
false, null, null,
false, null, null,
],
[["::tstatic"],
true, false, [null, "tstatic"],
true, false, [null, "tstatic"],
],
[["->tmethod"],
false, null, null,
false, null, null,
],
[["::tmissing"],
true, false, [null, "tmissing"],
true, false, [null, "tmissing"],
],
[["->tmissing"],
false, null, null,
false, null, null,
],
[["xxx::tmissing"],
false, null, null,
true, true, ["xxx", "tmissing"],
],
[["xxx->tmissing"],
false, null, null,
false, null, null,
],
[[SC::class."::tstatic"],
true, true, [SC::class, "tstatic"],
true, true, [SC::class, "tstatic"],
],
[[SC::class."->tmethod"],
false, null, null,
false, null, null,
],
[[SC::class."::tmissing"],
false, null, null,
true, true, [SC::class, "tmissing"],
],
[[SC::class."->tmissing"],
false, null, null,
false, null, null,
],
# tableaux avec deux scalaires
[[null, "tsimple"],
true, false, [null, "tsimple"],
true, false, [null, "tsimple"],
],
[[null, 'nur\sery\php\impl\ntsimple'],
false, null, null,
false, null, null,
],
[[null, "tmissing"],
true, false, [null, "tmissing"],
true, false, [null, "tmissing"],
],
[[null, "::tstatic"],
true, false, [null, "tstatic"],
true, false, [null, "tstatic"],
],
[[null, "->tmethod"],
false, null, null,
false, null, null,
],
[[null, "::tmissing"],
true, false, [null, "tmissing"],
true, false, [null, "tmissing"],
],
[[null, "->tmissing"],
false, null, null,
false, null, null,
],
[[false, "tsimple"],
false, null, null,
false, null, null,
],
[[false, 'nur\sery\php\impl\ntsimple'],
false, null, null,
false, null, null,
],
[[false, "tmissing"],
false, null, null,
false, null, null,
],
[[false, "::tstatic"],
false, null, null,
false, null, null,
],
[[false, "->tmethod"],
false, null, null,
false, null, null,
],
[[false, "::tmissing"],
false, null, null,
false, null, null,
],
[[false, "->tmissing"],
false, null, null,
false, null, null,
],
[["", "tsimple"],
false, null, null,
false, null, null,
],
[["", 'nur\sery\php\impl\ntsimple'],
false, null, null,
false, null, null,
],
[["", "tmissing"],
false, null, null,
false, null, null,
],
[["", "::tstatic"],
false, null, null,
false, null, null,
],
[["", "->tmethod"],
false, null, null,
false, null, null,
],
[["", "::tmissing"],
false, null, null,
false, null, null,
],
[["", "->tmissing"],
false, null, null,
false, null, null,
],
[["xxx", "tmissing"],
false, null, null,
true, true, ["xxx", "tmissing"],
],
[["xxx", "::tmissing"],
false, null, null,
true, true, ["xxx", "tmissing"],
],
[["xxx", "->tmissing"],
false, null, null,
false, null, null,
],
[[SC::class, "tstatic"],
true, true, [SC::class, "tstatic"],
true, true, [SC::class, "tstatic"],
],
[[SC::class, "::tstatic"],
true, true, [SC::class, "tstatic"],
true, true, [SC::class, "tstatic"],
],
[[SC::class, "tmethod"],
true, true, [SC::class, "tmethod"],
true, true, [SC::class, "tmethod"],
],
[[SC::class, "->tmethod"],
false, null, null,
false, null, null,
],
[[SC::class, "tmissing"],
false, null, null,
true, true, [SC::class, "tmissing"],
],
[[SC::class, "::tmissing"],
false, null, null,
true, true, [SC::class, "tmissing"],
],
[[SC::class, "->tmissing"],
false, null, null,
false, null, null,
],
];
function testStatic() {
foreach (self::STATIC_TESTS as $args) {
[$func,
$verifix1, $bound1, $func1,
$verifix2, $bound2, $func2,
] = $args;
if ($func === ["", "tsimple"]) {
//echo "breakpoint";
}
$workf = $func;
$msg = var_export($func, true)." (strict)";
self::assertSame($verifix1, func::verifix_static($workf, true, $bound), "$msg --> verifix");
if ($verifix1) {
self::assertSame($bound1, $bound, "$msg --> bound");
self::assertSame($func1, $workf, "$msg --> func");
}
$workf = $func;
$msg = var_export($func, true)." (lenient)";
self::assertSame($verifix2, func::verifix_static($workf, false, $bound), "$msg --> verifix");
if ($verifix2) {
self::assertSame($bound2, $bound, "$msg --> bound");
self::assertSame($func2, $workf, "$msg --> func");
}
}
}
const METHOD_TESTS = [
# scalaires
[null,
false, null, null,
false, null, null,
],
[false,
false, null, null,
false, null, null,
],
["",
false, null, null,
false, null, null,
],
["::",
false, null, null,
false, null, null,
],
["->",
false, null, null,
false, null, null,
],
["tsimple",
false, null, null,
false, null, null,
],
['nur\sery\php\impl\ntsimple',
false, null, null,
false, null, null,
],
['tmissing',
false, null, null,
false, null, null,
],
["::tstatic",
false, null, null,
false, null, null,
],
["->tmethod",
true, false, [null, "tmethod"],
true, false, [null, "tmethod"],
],
["::tmissing",
false, null, null,
false, null, null,
],
["->tmissing",
true, false, [null, "tmissing"],
true, false, [null, "tmissing"],
],
["xxx::tmissing",
false, null, null,
false, null, null,
],
["xxx->tmissing",
false, null, null,
true, true, ["xxx", "tmissing"],
],
[SC::class."::tstatic",
false, null, null,
false, null, null,
],
[SC::class."->tmethod",
true, true, [SC::class, "tmethod"],
true, true, [SC::class, "tmethod"],
],
[SC::class."::tmissing",
false, null, null,
false, null, null,
],
[SC::class."->tmissing",
false, null, null,
true, true, [SC::class, "tmissing"],
],
# tableaux avec un seul scalaire
[[],
false, null, null,
false, null, null,
],
[[null],
false, null, null,
false, null, null,
],
[[false],
false, null, null,
false, null, null,
],
[[""],
false, null, null,
false, null, null,
],
[["::"],
false, null, null,
false, null, null,
],
[["->"],
false, null, null,
false, null, null,
],
[["tsimple"],
false, null, null,
false, null, null,
],
[['nur\sery\php\impl\ntsimple'],
false, null, null,
false, null, null,
],
[["::tstatic"],
false, null, null,
false, null, null,
],
[["->tmethod"],
true, false, [null, "tmethod"],
true, false, [null, "tmethod"],
],
[["::tmissing"],
false, null, null,
false, null, null,
],
[["->tmissing"],
true, false, [null, "tmissing"],
true, false, [null, "tmissing"],
],
[["xxx::tmissing"],
false, null, null,
false, null, null,
],
[["xxx->tmissing"],
false, null, null,
true, true, ["xxx", "tmissing"],
],
[[SC::class."::tstatic"],
false, null, null,
false, null, null,
],
[[SC::class."->tmethod"],
true, true, [SC::class, "tmethod"],
true, true, [SC::class, "tmethod"],
],
[[SC::class."::tmissing"],
false, null, null,
false, null, null,
],
[[SC::class."->tmissing"],
false, null, null,
true, true, [SC::class, "tmissing"],
],
# tableaux avec deux scalaires
[[null, "tsimple"],
true, false, [null, "tsimple"],
true, false, [null, "tsimple"],
],
[[null, 'nur\sery\php\impl\ntsimple'],
false, null, null,
false, null, null,
],
[[null, "tmissing"],
true, false, [null, "tmissing"],
true, false, [null, "tmissing"],
],
[[null, "::tstatic"],
false, null, null,
false, null, null,
],
[[null, "->tmethod"],
true, false, [null, "tmethod"],
true, false, [null, "tmethod"],
],
[[null, "::tmissing"],
false, null, null,
false, null, null,
],
[[null, "->tmissing"],
true, false, [null, "tmissing"],
true, false, [null, "tmissing"],
],
[[false, "tsimple"],
false, null, null,
false, null, null,
],
[[false, 'nur\sery\php\impl\ntsimple'],
false, null, null,
false, null, null,
],
[[false, "tmissing"],
false, null, null,
false, null, null,
],
[[false, "::tstatic"],
false, null, null,
false, null, null,
],
[[false, "->tmethod"],
false, null, null,
false, null, null,
],
[[false, "::tmissing"],
false, null, null,
false, null, null,
],
[[false, "->tmissing"],
false, null, null,
false, null, null,
],
[["", "tsimple"],
false, null, null,
false, null, null,
],
[["", 'nur\sery\php\impl\ntsimple'],
false, null, null,
false, null, null,
],
[["", "tmissing"],
false, null, null,
false, null, null,
],
[["", "::tstatic"],
false, null, null,
false, null, null,
],
[["", "->tmethod"],
false, null, null,
false, null, null,
],
[["", "::tmissing"],
false, null, null,
false, null, null,
],
[["", "->tmissing"],
false, null, null,
false, null, null,
],
[["xxx", "tmissing"],
false, null, null,
true, true, ["xxx", "tmissing"],
],
[["xxx", "::tmissing"],
false, null, null,
false, null, null,
],
[["xxx", "->tmissing"],
false, null, null,
true, true, ["xxx", "tmissing"],
],
[[SC::class, "tstatic"],
true, true, [SC::class, "tstatic"],
true, true, [SC::class, "tstatic"],
],
[[SC::class, "::tstatic"],
false, null, null,
false, null, null,
],
[[SC::class, "tmethod"],
true, true, [SC::class, "tmethod"],
true, true, [SC::class, "tmethod"],
],
[[SC::class, "->tmethod"],
true, true, [SC::class, "tmethod"],
true, true, [SC::class, "tmethod"],
],
[[SC::class, "tmissing"],
false, null, null,
true, true, [SC::class, "tmissing"],
],
[[SC::class, "::tmissing"],
false, null, null,
false, null, null,
],
[[SC::class, "->tmissing"],
false, null, null,
true, true, [SC::class, "tmissing"],
],
];
function testMethod() {
foreach (self::METHOD_TESTS as $args) {
[$func,
$verifix1, $bound1, $func1,
$verifix2, $bound2, $func2,
] = $args;
$workf = $func;
$msg = var_export($func, true)." (strict)";
self::assertSame($verifix1, func::verifix_method($workf, true, $bound), "$msg --> verifix");
if ($verifix1) {
self::assertSame($bound1, $bound, "$msg --> bound");
self::assertSame($func1, $workf, "$msg --> func");
}
$workf = $func;
$msg = var_export($func, true)." (lenient)";
self::assertSame($verifix2, func::verifix_method($workf, false, $bound), "$msg --> verifix");
if ($verifix2) {
self::assertSame($bound2, $bound, "$msg --> bound");
self::assertSame($func2, $workf, "$msg --> func");
}
}
}
function testInvokeFunction() {
# m1
self::assertSame([null], func::call("tm1"));
self::assertSame([null], func::call("tm1", null));
self::assertSame([null], func::call("tm1", null, null));
self::assertSame([null], func::call("tm1", null, null, null));
self::assertSame([null], func::call("tm1", null, null, null, null));
self::assertSame([1], func::call("tm1", 1));
self::assertSame([1], func::call("tm1", 1, 2));
self::assertSame([1], func::call("tm1", 1, 2, 3));
self::assertSame([1], func::call("tm1", 1, 2, 3, 4));
# o1
self::assertSame([9], func::call("to1"));
self::assertSame([null], func::call("to1", null));
self::assertSame([null], func::call("to1", null, null));
self::assertSame([null], func::call("to1", null, null, null));
self::assertSame([null], func::call("to1", null, null, null, null));
self::assertSame([1], func::call("to1", 1));
self::assertSame([1], func::call("to1", 1, 2));
self::assertSame([1], func::call("to1", 1, 2, 3));
self::assertSame([1], func::call("to1", 1, 2, 3, 4));
# v
self::assertSame([], func::call("tv"));
self::assertSame([null], func::call("tv", null));
self::assertSame([null, null], func::call("tv", null, null));
self::assertSame([null, null, null], func::call("tv", null, null, null));
self::assertSame([null, null, null, null], func::call("tv", null, null, null, null));
self::assertSame([1], func::call("tv", 1));
self::assertSame([1, 2], func::call("tv", 1, 2));
self::assertSame([1, 2, 3], func::call("tv", 1, 2, 3));
self::assertSame([1, 2, 3, 4], func::call("tv", 1, 2, 3, 4));
# m1o1
self::assertSame([null, 9], func::call("tm1o1"));
self::assertSame([null, 9], func::call("tm1o1", null));
self::assertSame([null, null], func::call("tm1o1", null, null));
self::assertSame([null, null], func::call("tm1o1", null, null, null));
self::assertSame([null, null], func::call("tm1o1", null, null, null, null));
self::assertSame([1, 9], func::call("tm1o1", 1));
self::assertSame([1, 2], func::call("tm1o1", 1, 2));
self::assertSame([1, 2], func::call("tm1o1", 1, 2, 3));
self::assertSame([1, 2], func::call("tm1o1", 1, 2, 3, 4));
# m1v
self::assertSame([null], func::call("tm1v"));
self::assertSame([null], func::call("tm1v", null));
self::assertSame([null, null], func::call("tm1v", null, null));
self::assertSame([null, null, null], func::call("tm1v", null, null, null));
self::assertSame([null, null, null, null], func::call("tm1v", null, null, null, null));
self::assertSame([1], func::call("tm1v", 1));
self::assertSame([1, 2], func::call("tm1v", 1, 2));
self::assertSame([1, 2, 3], func::call("tm1v", 1, 2, 3));
self::assertSame([1, 2, 3, 4], func::call("tm1v", 1, 2, 3, 4));
# m1o1v
self::assertSame([null, 9], func::call("tm1o1v"));
self::assertSame([null, 9], func::call("tm1o1v", null));
self::assertSame([null, null], func::call("tm1o1v", null, null));
self::assertSame([null, null, null], func::call("tm1o1v", null, null, null));
self::assertSame([null, null, null, null], func::call("tm1o1v", null, null, null, null));
self::assertSame([1, 9], func::call("tm1o1v", 1));
self::assertSame([1, 2], func::call("tm1o1v", 1, 2));
self::assertSame([1, 2, 3], func::call("tm1o1v", 1, 2, 3));
self::assertSame([1, 2, 3, 4], func::call("tm1o1v", 1, 2, 3, 4));
# o1v
self::assertSame([9], func::call("to1v"));
self::assertSame([null], func::call("to1v", null));
self::assertSame([null, null], func::call("to1v", null, null));
self::assertSame([null, null, null], func::call("to1v", null, null, null));
self::assertSame([null, null, null, null], func::call("to1v", null, null, null, null));
self::assertSame([1], func::call("to1v", 1));
self::assertSame([1, 2], func::call("to1v", 1, 2));
self::assertSame([1, 2, 3], func::call("to1v", 1, 2, 3));
self::assertSame([1, 2, 3, 4], func::call("to1v", 1, 2, 3, 4));
}
function testInvokeClass() {
$func = func::with(SC::class);
self::assertInstanceOf(SC::class, $func->invoke());
self::assertInstanceOf(SC::class, $func->invoke([]));
self::assertInstanceOf(SC::class, $func->invoke([1]));
self::assertInstanceOf(SC::class, $func->invoke([1, 2]));
self::assertInstanceOf(SC::class, $func->invoke([1, 2, 3]));
$func = func::with(C0::class);
self::assertInstanceOf(C0::class, $func->invoke());
self::assertInstanceOf(C0::class, $func->invoke([]));
self::assertInstanceOf(C0::class, $func->invoke([1]));
self::assertInstanceOf(C0::class, $func->invoke([1, 2]));
self::assertInstanceOf(C0::class, $func->invoke([1, 2, 3]));
$func = func::with(C1::class);
/** @var C1 $i1 */
$i1 = $func->invoke();
self::assertInstanceOf(C1::class, $i1); self::assertSame(0, $i1->base);
$i1 = $func->invoke([]);
self::assertInstanceOf(C1::class, $i1); self::assertSame(0, $i1->base);
$i1 = $func->invoke([1]);
self::assertInstanceOf(C1::class, $i1); self::assertSame(1, $i1->base);
$i1 = $func->invoke([1, 2]);
self::assertInstanceOf(C1::class, $i1); self::assertSame(1, $i1->base);
}
private static function invoke_asserts(): array {
$inv_ok = function($func) {
return func::with($func)->invoke();
};
$inv_ko = function($func) use ($inv_ok) {
return function() use ($func, $inv_ok) {
return $inv_ok($func);
};
};
$bind_ok = function($func, $objet) {
return func::with($func)->bind($objet)->invoke();
};
$bind_ko = function($func, $object) use ($bind_ok) {
return function() use ($func, $object, $bind_ok) {
return $bind_ok($func, $object);
};
};
return [$inv_ok, $inv_ko, $bind_ok, $bind_ko];
}
function testInvokeStatic() {
[$inv_ok, $inv_ko, $bind_ok, $bind_ko] = self::invoke_asserts();
$sc = new SC();
self::assertSame(10, $inv_ok([SC::class, "tstatic"]));
self::assertSame(10, $inv_ok([SC::class, "::tstatic"]));
self::assertSame(10, $inv_ok([SC::class, "->tstatic"]));
self::assertSame(10, $inv_ok([$sc, "tstatic"]));
self::assertSame(10, $inv_ok([$sc, "::tstatic"]));
self::assertSame(10, $inv_ok([$sc, "->tstatic"]));
self::assertException(ValueException::class, $inv_ko([null, "tstatic"]));
self::assertException(ValueException::class, $inv_ko([null, "::tstatic"]));
self::assertException(ValueException::class, $inv_ko([null, "->tstatic"]));
self::assertSame(10, $bind_ok([null, "tstatic"], SC::class));
self::assertSame(10, $bind_ok([null, "::tstatic"], SC::class));
self::assertSame(10, $bind_ok([null, "->tstatic"], SC::class));
self::assertSame(10, $bind_ok([null, "tstatic"], $sc));
self::assertSame(10, $bind_ok([null, "::tstatic"], $sc));
self::assertSame(10, $bind_ok([null, "->tstatic"], $sc));
}
function testInvokeMethod() {
[$inv_ok, $inv_ko, $bind_ok, $bind_ko] = self::invoke_asserts();
$sc = new SC();
self::assertException(ReflectionException::class, $inv_ko([SC::class, "tmethod"]));
self::assertException(ReflectionException::class, $inv_ko([SC::class, "::tmethod"]));
self::assertException(ReflectionException::class, $inv_ko([SC::class, "->tmethod"]));
self::assertSame(11, $inv_ok([$sc, "tmethod"]));
self::assertException(ReflectionException::class, $inv_ko([$sc, "::tmethod"]));
self::assertSame(11, $inv_ok([$sc, "->tmethod"]));
self::assertException(ValueException::class, $inv_ko([null, "tmethod"]));
self::assertException(ValueException::class, $inv_ko([null, "::tmethod"]));
self::assertException(ValueException::class, $inv_ko([null, "->tmethod"]));
self::assertException(ReflectionException::class, $bind_ko([null, "tmethod"], SC::class));
self::assertException(ReflectionException::class, $bind_ko([null, "::tmethod"], SC::class));
self::assertException(ReflectionException::class, $bind_ko([null, "->tmethod"], SC::class));
self::assertSame(11, $bind_ok([null, "tmethod"], $sc));
self::assertException(ReflectionException::class, $bind_ko([null, "::tmethod"], $sc));
self::assertSame(11, $bind_ok([null, "->tmethod"], $sc));
}
function testArgs() {
$func = function(int $a, int $b, int $c): int {
return $a + $b + $c;
};
self::assertSame(6, func::call($func, 1, 2, 3));
self::assertSame(6, func::call($func, 1, 2, 3, 4));
self::assertSame(6, func::with($func)->invoke([1, 2, 3]));
self::assertSame(6, func::with($func, [1])->invoke([2, 3]));
self::assertSame(6, func::with($func, [1, 2])->invoke([3]));
self::assertSame(6, func::with($func, [1, 2, 3])->invoke());
self::assertSame(6, func::with($func, [1, 2, 3, 4])->invoke());
}
function testRebind() {
$func = func::with([C1::class, "tmethod"]);
self::assertSame(11, $func->bind(new C1(0))->invoke());
self::assertSame(12, $func->bind(new C1(1))->invoke());
self::assertException(ValueException::class, function() use ($func) {
$func->bind(new C0())->invoke();
});
}
}
}
namespace {
function tsimple(): int { return 0; }
function tm1($a): array { return [$a]; }
function to1($b=9): array { return [$b]; }
function tv(...$c): array { return [...$c]; }
function tm1o1($a, $b=9): array { return [$a, $b]; }
function tm1v($a, ...$c): array { return [$a, ...$c]; }
function tm1o1v($a, $b=9, ...$c): array { return [$a, $b, ...$c]; }
function to1v($b=9, ...$c): array { return [$b, ...$c]; }
}
namespace nur\sery\php\impl {
function ntsimple(): int { return 0; }
class SC {
static function tstatic(): int {
return 10;
}
function tmethod(): int {
return 11;
}
}
class C0 {
function __construct() {
}
static function tstatic(): int {
return 10;
}
function tmethod(): int {
return 11;
}
}
class C1 {
function __construct(int $base=0) {
$this->base = $base;
}
public int $base;
static function tstatic(): int {
return 10;
}
function tmethod(): int {
return 11 + $this->base;
}
}
}