", false, null, false, null, ], ["tsimple", true, [false, "tsimple"], true, [false, "tsimple"], ], ['nur\sery\wip\php\impl\ntsimple', true, [false, 'nur\sery\wip\php\impl\ntsimple'], true, [false, 'nur\sery\wip\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\wip\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\wip\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\wip\php\impl\ntsimple'], true, [false, 'nur\sery\wip\php\impl\ntsimple'], true, [false, 'nur\sery\wip\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\wip\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\wip\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\wip\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\wip\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\wip\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\wip\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\wip\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\wip\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\wip\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\wip\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\wip\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(null, $i1->first); $i1 = $func->invoke([]); self::assertInstanceOf(C1::class, $i1); self::assertSame(null, $i1->first); $i1 = $func->invoke([1]); self::assertInstanceOf(C1::class, $i1); self::assertSame(1, $i1->first); $i1 = $func->invoke([1, 2]); self::assertInstanceOf(C1::class, $i1); self::assertSame(1, $i1->first); } function testInvokeStatic() { $func = func::with([SC::class, "tstatic"]); self::assertSame(10, $func->invoke()); $func = func::with([SC::class, "tmethod"]); self::assertException(ReflectionException::class, function() use ($func) { $func->invoke(); }); $func = func::with([null, "tstatic"]); self::assertException(ReflectionException::class, function() use ($func) { $func->invoke(); }); $func = func::with([null, "tmethod"]); self::assertException(ReflectionException::class, function() use ($func) { $func->invoke(); }); } function testInvokeMethod() { $func = func::with([SC::class, "tstatic"]); self::assertSame(10, $func->invoke()); $func = func::with([new SC(), "tstatic"]); self::assertSame(10, $func->invoke()); $func = func::with([SC::class, "tmethod"]); self::assertException(ReflectionException::class, function() use ($func) { $func->invoke(); }); $func = func::with([new SC(), "tmethod"]); self::assertSame(11, $func->invoke()); } } }