annotate vendor/nikic/php-parser/test/PhpParser/BuilderFactoryTest.php @ 13:5fb285c0d0e3

Update Drupal core to 8.4.7 via Composer. Security update; I *think* we've been lucky to get away with this so far, as we don't support self-registration which seems to be used by the so-called "drupalgeddon 2" attack that 8.4.5 was vulnerable to.
author Chris Cannam
date Mon, 23 Apr 2018 09:33:26 +0100
parents 4c8ae668cc8c
children 129ea1e6d783
rev   line source
Chris@13 1 <?php declare(strict_types=1);
Chris@0 2
Chris@0 3 namespace PhpParser;
Chris@0 4
Chris@13 5 use PhpParser\Builder;
Chris@13 6 use PhpParser\Node\Arg;
Chris@0 7 use PhpParser\Node\Expr;
Chris@13 8 use PhpParser\Node\Expr\BinaryOp\Concat;
Chris@13 9 use PhpParser\Node\Identifier;
Chris@13 10 use PhpParser\Node\Name;
Chris@13 11 use PhpParser\Node\Scalar\LNumber;
Chris@13 12 use PhpParser\Node\Scalar\String_;
Chris@13 13 use PHPUnit\Framework\TestCase;
Chris@13 14 use Symfony\Component\Yaml\Tests\A;
Chris@0 15
Chris@13 16 class BuilderFactoryTest extends TestCase
Chris@0 17 {
Chris@0 18 /**
Chris@0 19 * @dataProvider provideTestFactory
Chris@0 20 */
Chris@0 21 public function testFactory($methodName, $className) {
Chris@0 22 $factory = new BuilderFactory;
Chris@0 23 $this->assertInstanceOf($className, $factory->$methodName('test'));
Chris@0 24 }
Chris@0 25
Chris@0 26 public function provideTestFactory() {
Chris@13 27 return [
Chris@13 28 ['namespace', Builder\Namespace_::class],
Chris@13 29 ['class', Builder\Class_::class],
Chris@13 30 ['interface', Builder\Interface_::class],
Chris@13 31 ['trait', Builder\Trait_::class],
Chris@13 32 ['method', Builder\Method::class],
Chris@13 33 ['function', Builder\Function_::class],
Chris@13 34 ['property', Builder\Property::class],
Chris@13 35 ['param', Builder\Param::class],
Chris@13 36 ['use', Builder\Use_::class],
Chris@13 37 ];
Chris@13 38 }
Chris@13 39
Chris@13 40 public function testVal() {
Chris@13 41 // This method is a wrapper around BuilderHelpers::normalizeValue(),
Chris@13 42 // which is already tested elsewhere
Chris@13 43 $factory = new BuilderFactory();
Chris@13 44 $this->assertEquals(
Chris@13 45 new String_("foo"),
Chris@13 46 $factory->val("foo")
Chris@0 47 );
Chris@0 48 }
Chris@0 49
Chris@13 50 public function testConcat() {
Chris@0 51 $factory = new BuilderFactory();
Chris@13 52 $varA = new Expr\Variable('a');
Chris@13 53 $varB = new Expr\Variable('b');
Chris@13 54 $varC = new Expr\Variable('c');
Chris@13 55
Chris@13 56 $this->assertEquals(
Chris@13 57 new Concat($varA, $varB),
Chris@13 58 $factory->concat($varA, $varB)
Chris@13 59 );
Chris@13 60 $this->assertEquals(
Chris@13 61 new Concat(new Concat($varA, $varB), $varC),
Chris@13 62 $factory->concat($varA, $varB, $varC)
Chris@13 63 );
Chris@13 64 $this->assertEquals(
Chris@13 65 new Concat(new Concat(new String_("a"), $varB), new String_("c")),
Chris@13 66 $factory->concat("a", $varB, "c")
Chris@13 67 );
Chris@13 68 }
Chris@13 69
Chris@13 70 /**
Chris@13 71 * @expectedException \LogicException
Chris@13 72 * @expectedExceptionMessage Expected at least two expressions
Chris@13 73 */
Chris@13 74 public function testConcatOneError() {
Chris@13 75 (new BuilderFactory())->concat("a");
Chris@13 76 }
Chris@13 77
Chris@13 78 /**
Chris@13 79 * @expectedException \LogicException
Chris@13 80 * @expectedExceptionMessage Expected string or Expr
Chris@13 81 */
Chris@13 82 public function testConcatInvalidExpr() {
Chris@13 83 (new BuilderFactory())->concat("a", 42);
Chris@13 84 }
Chris@13 85
Chris@13 86 public function testArgs() {
Chris@13 87 $factory = new BuilderFactory();
Chris@13 88 $unpack = new Arg(new Expr\Variable('c'), false, true);
Chris@13 89 $this->assertEquals(
Chris@13 90 [
Chris@13 91 new Arg(new Expr\Variable('a')),
Chris@13 92 new Arg(new String_('b')),
Chris@13 93 $unpack
Chris@13 94 ],
Chris@13 95 $factory->args([new Expr\Variable('a'), 'b', $unpack])
Chris@13 96 );
Chris@13 97 }
Chris@13 98
Chris@13 99 public function testCalls() {
Chris@13 100 $factory = new BuilderFactory();
Chris@13 101
Chris@13 102 // Simple function call
Chris@13 103 $this->assertEquals(
Chris@13 104 new Expr\FuncCall(
Chris@13 105 new Name('var_dump'),
Chris@13 106 [new Arg(new String_('str'))]
Chris@13 107 ),
Chris@13 108 $factory->funcCall('var_dump', ['str'])
Chris@13 109 );
Chris@13 110 // Dynamic function call
Chris@13 111 $this->assertEquals(
Chris@13 112 new Expr\FuncCall(new Expr\Variable('fn')),
Chris@13 113 $factory->funcCall(new Expr\Variable('fn'))
Chris@13 114 );
Chris@13 115
Chris@13 116 // Simple method call
Chris@13 117 $this->assertEquals(
Chris@13 118 new Expr\MethodCall(
Chris@13 119 new Expr\Variable('obj'),
Chris@13 120 new Identifier('method'),
Chris@13 121 [new Arg(new LNumber(42))]
Chris@13 122 ),
Chris@13 123 $factory->methodCall(new Expr\Variable('obj'), 'method', [42])
Chris@13 124 );
Chris@13 125 // Explicitly pass Identifier node
Chris@13 126 $this->assertEquals(
Chris@13 127 new Expr\MethodCall(
Chris@13 128 new Expr\Variable('obj'),
Chris@13 129 new Identifier('method')
Chris@13 130 ),
Chris@13 131 $factory->methodCall(new Expr\Variable('obj'), new Identifier('method'))
Chris@13 132 );
Chris@13 133 // Dynamic method call
Chris@13 134 $this->assertEquals(
Chris@13 135 new Expr\MethodCall(
Chris@13 136 new Expr\Variable('obj'),
Chris@13 137 new Expr\Variable('method')
Chris@13 138 ),
Chris@13 139 $factory->methodCall(new Expr\Variable('obj'), new Expr\Variable('method'))
Chris@13 140 );
Chris@13 141
Chris@13 142 // Simple static method call
Chris@13 143 $this->assertEquals(
Chris@13 144 new Expr\StaticCall(
Chris@13 145 new Name\FullyQualified('Foo'),
Chris@13 146 new Identifier('bar'),
Chris@13 147 [new Arg(new Expr\Variable('baz'))]
Chris@13 148 ),
Chris@13 149 $factory->staticCall('\Foo', 'bar', [new Expr\Variable('baz')])
Chris@13 150 );
Chris@13 151 // Dynamic static method call
Chris@13 152 $this->assertEquals(
Chris@13 153 new Expr\StaticCall(
Chris@13 154 new Expr\Variable('foo'),
Chris@13 155 new Expr\Variable('bar')
Chris@13 156 ),
Chris@13 157 $factory->staticCall(new Expr\Variable('foo'), new Expr\Variable('bar'))
Chris@13 158 );
Chris@13 159
Chris@13 160 // Simple new call
Chris@13 161 $this->assertEquals(
Chris@13 162 new Expr\New_(new Name\FullyQualified('stdClass')),
Chris@13 163 $factory->new('\stdClass')
Chris@13 164 );
Chris@13 165 // Dynamic new call
Chris@13 166 $this->assertEquals(
Chris@13 167 new Expr\New_(
Chris@13 168 new Expr\Variable('foo'),
Chris@13 169 [new Arg(new String_('bar'))]
Chris@13 170 ),
Chris@13 171 $factory->new(new Expr\Variable('foo'), ['bar'])
Chris@13 172 );
Chris@13 173 }
Chris@13 174
Chris@13 175 public function testConstFetches() {
Chris@13 176 $factory = new BuilderFactory();
Chris@13 177 $this->assertEquals(
Chris@13 178 new Expr\ConstFetch(new Name('FOO')),
Chris@13 179 $factory->constFetch('FOO')
Chris@13 180 );
Chris@13 181 $this->assertEquals(
Chris@13 182 new Expr\ClassConstFetch(new Name('Foo'), new Identifier('BAR')),
Chris@13 183 $factory->classConstFetch('Foo', 'BAR')
Chris@13 184 );
Chris@13 185 $this->assertEquals(
Chris@13 186 new Expr\ClassConstFetch(new Expr\Variable('foo'), new Identifier('BAR')),
Chris@13 187 $factory->classConstFetch(new Expr\Variable('foo'), 'BAR')
Chris@13 188 );
Chris@13 189 }
Chris@13 190
Chris@13 191 /**
Chris@13 192 * @expectedException \LogicException
Chris@13 193 * @expectedExceptionMessage Expected string or instance of Node\Identifier
Chris@13 194 */
Chris@13 195 public function testInvalidIdentifier() {
Chris@13 196 (new BuilderFactory())->classConstFetch('Foo', new Expr\Variable('foo'));
Chris@13 197 }
Chris@13 198
Chris@13 199 /**
Chris@13 200 * @expectedException \LogicException
Chris@13 201 * @expectedExceptionMessage Expected string or instance of Node\Identifier or Node\Expr
Chris@13 202 */
Chris@13 203 public function testInvalidIdentifierOrExpr() {
Chris@13 204 (new BuilderFactory())->staticCall('Foo', new Name('bar'));
Chris@13 205 }
Chris@13 206
Chris@13 207 /**
Chris@13 208 * @expectedException \LogicException
Chris@13 209 * @expectedExceptionMessage Name must be a string or an instance of Node\Name or Node\Expr
Chris@13 210 */
Chris@13 211 public function testInvalidNameOrExpr() {
Chris@13 212 (new BuilderFactory())->funcCall(new Node\Stmt\Return_());
Chris@0 213 }
Chris@0 214
Chris@0 215 public function testIntegration() {
Chris@0 216 $factory = new BuilderFactory;
Chris@0 217 $node = $factory->namespace('Name\Space')
Chris@0 218 ->addStmt($factory->use('Foo\Bar\SomeOtherClass'))
Chris@0 219 ->addStmt($factory->use('Foo\Bar')->as('A'))
Chris@0 220 ->addStmt($factory
Chris@0 221 ->class('SomeClass')
Chris@0 222 ->extend('SomeOtherClass')
Chris@0 223 ->implement('A\Few', '\Interfaces')
Chris@0 224 ->makeAbstract()
Chris@0 225
Chris@0 226 ->addStmt($factory->method('firstMethod'))
Chris@0 227
Chris@0 228 ->addStmt($factory->method('someMethod')
Chris@0 229 ->makePublic()
Chris@0 230 ->makeAbstract()
Chris@0 231 ->addParam($factory->param('someParam')->setTypeHint('SomeClass'))
Chris@0 232 ->setDocComment('/**
Chris@0 233 * This method does something.
Chris@0 234 *
Chris@0 235 * @param SomeClass And takes a parameter
Chris@0 236 */'))
Chris@0 237
Chris@0 238 ->addStmt($factory->method('anotherMethod')
Chris@0 239 ->makeProtected()
Chris@0 240 ->addParam($factory->param('someParam')->setDefault('test'))
Chris@0 241 ->addStmt(new Expr\Print_(new Expr\Variable('someParam'))))
Chris@0 242
Chris@0 243 ->addStmt($factory->property('someProperty')->makeProtected())
Chris@0 244 ->addStmt($factory->property('anotherProperty')
Chris@0 245 ->makePrivate()
Chris@13 246 ->setDefault([1, 2, 3])))
Chris@0 247 ->getNode()
Chris@0 248 ;
Chris@0 249
Chris@0 250 $expected = <<<'EOC'
Chris@0 251 <?php
Chris@0 252
Chris@0 253 namespace Name\Space;
Chris@0 254
Chris@0 255 use Foo\Bar\SomeOtherClass;
Chris@0 256 use Foo\Bar as A;
Chris@0 257 abstract class SomeClass extends SomeOtherClass implements A\Few, \Interfaces
Chris@0 258 {
Chris@0 259 protected $someProperty;
Chris@0 260 private $anotherProperty = array(1, 2, 3);
Chris@0 261 function firstMethod()
Chris@0 262 {
Chris@0 263 }
Chris@0 264 /**
Chris@0 265 * This method does something.
Chris@0 266 *
Chris@0 267 * @param SomeClass And takes a parameter
Chris@0 268 */
Chris@0 269 public abstract function someMethod(SomeClass $someParam);
Chris@0 270 protected function anotherMethod($someParam = 'test')
Chris@0 271 {
Chris@0 272 print $someParam;
Chris@0 273 }
Chris@0 274 }
Chris@0 275 EOC;
Chris@0 276
Chris@13 277 $stmts = [$node];
Chris@0 278 $prettyPrinter = new PrettyPrinter\Standard();
Chris@0 279 $generated = $prettyPrinter->prettyPrintFile($stmts);
Chris@0 280
Chris@0 281 $this->assertEquals(
Chris@0 282 str_replace("\r\n", "\n", $expected),
Chris@0 283 str_replace("\r\n", "\n", $generated)
Chris@0 284 );
Chris@0 285 }
Chris@0 286 }