1<?php
2
3/*
4 * This file is part of Twig.
5 *
6 * (c) Fabien Potencier
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12use Twig\Node\Expression\CallExpression;
13
14class Twig_Tests_Node_Expression_CallTest extends \PHPUnit\Framework\TestCase
15{
16    public function testGetArguments()
17    {
18        $node = new Twig_Tests_Node_Expression_Call([], ['type' => 'function', 'name' => 'date']);
19        $this->assertEquals(['U', null], $node->getArguments('date', ['format' => 'U', 'timestamp' => null]));
20    }
21
22    /**
23     * @expectedException        \Twig\Error\SyntaxError
24     * @expectedExceptionMessage Positional arguments cannot be used after named arguments for function "date".
25     */
26    public function testGetArgumentsWhenPositionalArgumentsAfterNamedArguments()
27    {
28        $node = new Twig_Tests_Node_Expression_Call([], ['type' => 'function', 'name' => 'date']);
29        $node->getArguments('date', ['timestamp' => 123456, 'Y-m-d']);
30    }
31
32    /**
33     * @expectedException        \Twig\Error\SyntaxError
34     * @expectedExceptionMessage Argument "format" is defined twice for function "date".
35     */
36    public function testGetArgumentsWhenArgumentIsDefinedTwice()
37    {
38        $node = new Twig_Tests_Node_Expression_Call([], ['type' => 'function', 'name' => 'date']);
39        $node->getArguments('date', ['Y-m-d', 'format' => 'U']);
40    }
41
42    /**
43     * @expectedException        \Twig\Error\SyntaxError
44     * @expectedExceptionMessage Unknown argument "unknown" for function "date(format, timestamp)".
45     */
46    public function testGetArgumentsWithWrongNamedArgumentName()
47    {
48        $node = new Twig_Tests_Node_Expression_Call([], ['type' => 'function', 'name' => 'date']);
49        $node->getArguments('date', ['Y-m-d', 'timestamp' => null, 'unknown' => '']);
50    }
51
52    /**
53     * @expectedException        \Twig\Error\SyntaxError
54     * @expectedExceptionMessage Unknown arguments "unknown1", "unknown2" for function "date(format, timestamp)".
55     */
56    public function testGetArgumentsWithWrongNamedArgumentNames()
57    {
58        $node = new Twig_Tests_Node_Expression_Call([], ['type' => 'function', 'name' => 'date']);
59        $node->getArguments('date', ['Y-m-d', 'timestamp' => null, 'unknown1' => '', 'unknown2' => '']);
60    }
61
62    /**
63     * @expectedException        \Twig\Error\SyntaxError
64     * @expectedExceptionMessage Argument "case_sensitivity" could not be assigned for function "substr_compare(main_str, str, offset, length, case_sensitivity)" because it is mapped to an internal PHP function which cannot determine default value for optional argument "length".
65     */
66    public function testResolveArgumentsWithMissingValueForOptionalArgument()
67    {
68        $node = new Twig_Tests_Node_Expression_Call([], ['type' => 'function', 'name' => 'substr_compare']);
69        $node->getArguments('substr_compare', ['abcd', 'bc', 'offset' => 1, 'case_sensitivity' => true]);
70    }
71
72    public function testResolveArgumentsOnlyNecessaryArgumentsForCustomFunction()
73    {
74        $node = new Twig_Tests_Node_Expression_Call([], ['type' => 'function', 'name' => 'custom_function']);
75
76        $this->assertEquals(['arg1'], $node->getArguments([$this, 'customFunction'], ['arg1' => 'arg1']));
77    }
78
79    public function testGetArgumentsForStaticMethod()
80    {
81        $node = new Twig_Tests_Node_Expression_Call([], ['type' => 'function', 'name' => 'custom_static_function']);
82        $this->assertEquals(['arg1'], $node->getArguments(__CLASS__.'::customStaticFunction', ['arg1' => 'arg1']));
83    }
84
85    /**
86     * @expectedException        \LogicException
87     * @expectedExceptionMessage The last parameter of "Twig_Tests_Node_Expression_CallTest::customFunctionWithArbitraryArguments" for function "foo" must be an array with default value, eg. "array $arg = []".
88     */
89    public function testResolveArgumentsWithMissingParameterForArbitraryArguments()
90    {
91        $node = new Twig_Tests_Node_Expression_Call([], ['type' => 'function', 'name' => 'foo', 'is_variadic' => true]);
92        $node->getArguments([$this, 'customFunctionWithArbitraryArguments'], []);
93    }
94
95    public static function customStaticFunction($arg1, $arg2 = 'default', $arg3 = [])
96    {
97    }
98
99    public function customFunction($arg1, $arg2 = 'default', $arg3 = [])
100    {
101    }
102
103    public function customFunctionWithArbitraryArguments()
104    {
105    }
106
107    /**
108     * @expectedException              \LogicException
109     * @expectedExceptionMessageRegExp #^The last parameter of "custom_Twig_Tests_Node_Expression_CallTest_function" for function "foo" must be an array with default value, eg\. "array \$arg \= \[\]"\.$#
110     */
111    public function testResolveArgumentsWithMissingParameterForArbitraryArgumentsOnFunction()
112    {
113        $node = new Twig_Tests_Node_Expression_Call([], ['type' => 'function', 'name' => 'foo', 'is_variadic' => true]);
114        $node->getArguments('custom_Twig_Tests_Node_Expression_CallTest_function', []);
115    }
116
117    /**
118     * @expectedException              \LogicException
119     * @expectedExceptionMessageRegExp #^The last parameter of "CallableTestClass\:\:__invoke" for function "foo" must be an array with default value, eg\. "array \$arg \= \[\]"\.$#
120     */
121    public function testResolveArgumentsWithMissingParameterForArbitraryArgumentsOnObject()
122    {
123        $node = new Twig_Tests_Node_Expression_Call([], ['type' => 'function', 'name' => 'foo', 'is_variadic' => true]);
124        $node->getArguments(new CallableTestClass(), []);
125    }
126}
127
128class Twig_Tests_Node_Expression_Call extends CallExpression
129{
130    public function getArguments($callable, $arguments)
131    {
132        return parent::getArguments($callable, $arguments);
133    }
134}
135
136class CallableTestClass
137{
138    public function __invoke($required)
139    {
140    }
141}
142
143function custom_Twig_Tests_Node_Expression_CallTest_function($required)
144{
145}
146