1--TEST--
2runkit7_function_redefine() function, etc. can redefine variadic functions with return types.
3--SKIPIF--
4<?php if(!extension_loaded("runkit7") || !RUNKIT7_FEATURE_MANIPULATION) print "skip"; ?>
5--INI--
6display_errors=on
7--FILE--
8<?php
9function create_function_mock($originalName, $temporaryName) {
10    if (!runkit7_function_copy($originalName, $temporaryName))
11        throw new RuntimeException($originalName . ' runkit_method_copy create_function_mock');
12    if (!runkit7_function_remove($originalName))
13        throw new RuntimeException($originalName . ' runkit_function_remove create_function_mock');
14    if (!runkit7_function_add($originalName, '', 'printf("In mock: %s\n", serialize(func_get_args()));return null;'))
15        throw new RuntimeException($originalName . ' runkit_function_add create_function_mock');
16}
17
18function remove_function_mock($originalName, $temporaryName) {
19    if (!runkit7_function_remove($originalName))
20        throw new RuntimeException($originalName . ' runkit_function_remove1 remove_function_mock');
21    if (!runkit7_function_rename($temporaryName, $originalName))
22        throw new RuntimeException($originalName . ' runkit_function_rename remove_function_mock');
23}
24
25class FooImpl {
26    public function methodName($arg) {
27        return 33 + $arg;
28    }
29}
30
31function bar($method, ...$args) : string {
32    global $impl;
33    if ($impl === null) {
34        throw new RuntimeException('No $impl');
35    }
36
37    $id = getter();
38    return $id . call_user_func_array(array($impl, $method), $args);
39}
40
41function getter() {
42    return 'VALUE';
43}
44
45function main() {
46    ini_set('error_reporting', E_ALL | E_STRICT);
47    global $impl;
48    $impl = new FooImpl();
49    printf("Before mock: %s\n", var_export(bar('methodName', 0), true));
50    create_function_mock('bar', 'bar0000001123');
51    printf("After mock: %s\n", var_export(bar('methodName', 0), true));
52    remove_function_mock('bar', 'bar0000001123');
53    printf("After unmock: %s\n", var_export(bar('methodName', 100), true));
54    create_function_mock('bar', 'bar0000001123');
55    printf("After mock: %s\n", var_export(bar('methodName', 0), true));
56    remove_function_mock('bar', 'bar0000001123');
57    printf("After unmock: %s\n", var_export(bar('methodName', 100), true));
58}
59main();
60?>
61--EXPECT--
62Before mock: 'VALUE33'
63In mock: a:2:{i:0;s:10:"methodName";i:1;i:0;}
64After mock: NULL
65After unmock: 'VALUE133'
66In mock: a:2:{i:0;s:10:"methodName";i:1;i:0;}
67After mock: NULL
68After unmock: 'VALUE133'
69