1 <?php declare(strict_types=1);
6 use PhpParser\Node\Arg;
7 use PhpParser\Node\Expr;
8 use PhpParser\Node\Expr\BinaryOp\Concat;
9 use PhpParser\Node\Identifier;
10 use PhpParser\Node\Name;
11 use PhpParser\Node\Scalar\LNumber;
12 use PhpParser\Node\Scalar\String_;
13 use PHPUnit\Framework\TestCase;
14 use Symfony\Component\Yaml\Tests\A;
16 class BuilderFactoryTest extends TestCase
19 * @dataProvider provideTestFactory
21 public function testFactory($methodName, $className) {
22 $factory = new BuilderFactory;
23 $this->assertInstanceOf($className, $factory->$methodName('test'));
26 public function provideTestFactory() {
28 ['namespace', Builder\Namespace_::class],
29 ['class', Builder\Class_::class],
30 ['interface', Builder\Interface_::class],
31 ['trait', Builder\Trait_::class],
32 ['method', Builder\Method::class],
33 ['function', Builder\Function_::class],
34 ['property', Builder\Property::class],
35 ['param', Builder\Param::class],
36 ['use', Builder\Use_::class],
40 public function testVal() {
41 // This method is a wrapper around BuilderHelpers::normalizeValue(),
42 // which is already tested elsewhere
43 $factory = new BuilderFactory();
50 public function testConcat() {
51 $factory = new BuilderFactory();
52 $varA = new Expr\Variable('a');
53 $varB = new Expr\Variable('b');
54 $varC = new Expr\Variable('c');
57 new Concat($varA, $varB),
58 $factory->concat($varA, $varB)
61 new Concat(new Concat($varA, $varB), $varC),
62 $factory->concat($varA, $varB, $varC)
65 new Concat(new Concat(new String_("a"), $varB), new String_("c")),
66 $factory->concat("a", $varB, "c")
71 * @expectedException \LogicException
72 * @expectedExceptionMessage Expected at least two expressions
74 public function testConcatOneError() {
75 (new BuilderFactory())->concat("a");
79 * @expectedException \LogicException
80 * @expectedExceptionMessage Expected string or Expr
82 public function testConcatInvalidExpr() {
83 (new BuilderFactory())->concat("a", 42);
86 public function testArgs() {
87 $factory = new BuilderFactory();
88 $unpack = new Arg(new Expr\Variable('c'), false, true);
91 new Arg(new Expr\Variable('a')),
92 new Arg(new String_('b')),
95 $factory->args([new Expr\Variable('a'), 'b', $unpack])
99 public function testCalls() {
100 $factory = new BuilderFactory();
102 // Simple function call
105 new Name('var_dump'),
106 [new Arg(new String_('str'))]
108 $factory->funcCall('var_dump', ['str'])
110 // Dynamic function call
112 new Expr\FuncCall(new Expr\Variable('fn')),
113 $factory->funcCall(new Expr\Variable('fn'))
116 // Simple method call
119 new Expr\Variable('obj'),
120 new Identifier('method'),
121 [new Arg(new LNumber(42))]
123 $factory->methodCall(new Expr\Variable('obj'), 'method', [42])
125 // Explicitly pass Identifier node
128 new Expr\Variable('obj'),
129 new Identifier('method')
131 $factory->methodCall(new Expr\Variable('obj'), new Identifier('method'))
133 // Dynamic method call
136 new Expr\Variable('obj'),
137 new Expr\Variable('method')
139 $factory->methodCall(new Expr\Variable('obj'), new Expr\Variable('method'))
142 // Simple static method call
145 new Name\FullyQualified('Foo'),
146 new Identifier('bar'),
147 [new Arg(new Expr\Variable('baz'))]
149 $factory->staticCall('\Foo', 'bar', [new Expr\Variable('baz')])
151 // Dynamic static method call
154 new Expr\Variable('foo'),
155 new Expr\Variable('bar')
157 $factory->staticCall(new Expr\Variable('foo'), new Expr\Variable('bar'))
162 new Expr\New_(new Name\FullyQualified('stdClass')),
163 $factory->new('\stdClass')
168 new Expr\Variable('foo'),
169 [new Arg(new String_('bar'))]
171 $factory->new(new Expr\Variable('foo'), ['bar'])
175 public function testConstFetches() {
176 $factory = new BuilderFactory();
178 new Expr\ConstFetch(new Name('FOO')),
179 $factory->constFetch('FOO')
182 new Expr\ClassConstFetch(new Name('Foo'), new Identifier('BAR')),
183 $factory->classConstFetch('Foo', 'BAR')
186 new Expr\ClassConstFetch(new Expr\Variable('foo'), new Identifier('BAR')),
187 $factory->classConstFetch(new Expr\Variable('foo'), 'BAR')
192 * @expectedException \LogicException
193 * @expectedExceptionMessage Expected string or instance of Node\Identifier
195 public function testInvalidIdentifier() {
196 (new BuilderFactory())->classConstFetch('Foo', new Expr\Variable('foo'));
200 * @expectedException \LogicException
201 * @expectedExceptionMessage Expected string or instance of Node\Identifier or Node\Expr
203 public function testInvalidIdentifierOrExpr() {
204 (new BuilderFactory())->staticCall('Foo', new Name('bar'));
208 * @expectedException \LogicException
209 * @expectedExceptionMessage Name must be a string or an instance of Node\Name or Node\Expr
211 public function testInvalidNameOrExpr() {
212 (new BuilderFactory())->funcCall(new Node\Stmt\Return_());
215 public function testIntegration() {
216 $factory = new BuilderFactory;
217 $node = $factory->namespace('Name\Space')
218 ->addStmt($factory->use('Foo\Bar\SomeOtherClass'))
219 ->addStmt($factory->use('Foo\Bar')->as('A'))
222 ->extend('SomeOtherClass')
223 ->implement('A\Few', '\Interfaces')
226 ->addStmt($factory->method('firstMethod'))
228 ->addStmt($factory->method('someMethod')
231 ->addParam($factory->param('someParam')->setTypeHint('SomeClass'))
233 * This method does something.
235 * @param SomeClass And takes a parameter
238 ->addStmt($factory->method('anotherMethod')
240 ->addParam($factory->param('someParam')->setDefault('test'))
241 ->addStmt(new Expr\Print_(new Expr\Variable('someParam'))))
243 ->addStmt($factory->property('someProperty')->makeProtected())
244 ->addStmt($factory->property('anotherProperty')
246 ->setDefault([1, 2, 3])))
253 namespace Name\Space;
255 use Foo\Bar\SomeOtherClass;
257 abstract class SomeClass extends SomeOtherClass implements A\Few, \Interfaces
259 protected $someProperty;
260 private $anotherProperty = array(1, 2, 3);
261 function firstMethod()
265 * This method does something.
267 * @param SomeClass And takes a parameter
269 public abstract function someMethod(SomeClass $someParam);
270 protected function anotherMethod($someParam = 'test')
278 $prettyPrinter = new PrettyPrinter\Standard();
279 $generated = $prettyPrinter->prettyPrintFile($stmts);
282 str_replace("\r\n", "\n", $expected),
283 str_replace("\r\n", "\n", $generated)