1168 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			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;
 | |
|     }
 | |
|   }
 | |
| }
 |