mirror of
https://github.com/standardebooks/web.git
synced 2025-07-15 19:06:49 -04:00
Add Composer autoloading functions and PHPStan for testing
This commit is contained in:
parent
e198c4db65
commit
f5d7d4e02a
1518 changed files with 169063 additions and 30 deletions
153
vendor/nikic/php-parser/test/PhpParser/Builder/ClassTest.php
vendored
Normal file
153
vendor/nikic/php-parser/test/PhpParser/Builder/ClassTest.php
vendored
Normal file
|
@ -0,0 +1,153 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Builder;
|
||||
|
||||
use PhpParser\Comment;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Stmt;
|
||||
|
||||
class ClassTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected function createClassBuilder($class) {
|
||||
return new Class_($class);
|
||||
}
|
||||
|
||||
public function testExtendsImplements() {
|
||||
$node = $this->createClassBuilder('SomeLogger')
|
||||
->extend('BaseLogger')
|
||||
->implement('Namespaced\Logger', new Name('SomeInterface'))
|
||||
->implement('\Fully\Qualified', 'namespace\NamespaceRelative')
|
||||
->getNode()
|
||||
;
|
||||
|
||||
$this->assertEquals(
|
||||
new Stmt\Class_('SomeLogger', [
|
||||
'extends' => new Name('BaseLogger'),
|
||||
'implements' => [
|
||||
new Name('Namespaced\Logger'),
|
||||
new Name('SomeInterface'),
|
||||
new Name\FullyQualified('Fully\Qualified'),
|
||||
new Name\Relative('NamespaceRelative'),
|
||||
],
|
||||
]),
|
||||
$node
|
||||
);
|
||||
}
|
||||
|
||||
public function testAbstract() {
|
||||
$node = $this->createClassBuilder('Test')
|
||||
->makeAbstract()
|
||||
->getNode()
|
||||
;
|
||||
|
||||
$this->assertEquals(
|
||||
new Stmt\Class_('Test', [
|
||||
'flags' => Stmt\Class_::MODIFIER_ABSTRACT
|
||||
]),
|
||||
$node
|
||||
);
|
||||
}
|
||||
|
||||
public function testFinal() {
|
||||
$node = $this->createClassBuilder('Test')
|
||||
->makeFinal()
|
||||
->getNode()
|
||||
;
|
||||
|
||||
$this->assertEquals(
|
||||
new Stmt\Class_('Test', [
|
||||
'flags' => Stmt\Class_::MODIFIER_FINAL
|
||||
]),
|
||||
$node
|
||||
);
|
||||
}
|
||||
|
||||
public function testStatementOrder() {
|
||||
$method = new Stmt\ClassMethod('testMethod');
|
||||
$property = new Stmt\Property(
|
||||
Stmt\Class_::MODIFIER_PUBLIC,
|
||||
[new Stmt\PropertyProperty('testProperty')]
|
||||
);
|
||||
$const = new Stmt\ClassConst([
|
||||
new Node\Const_('TEST_CONST', new Node\Scalar\String_('ABC'))
|
||||
]);
|
||||
$use = new Stmt\TraitUse([new Name('SomeTrait')]);
|
||||
|
||||
$node = $this->createClassBuilder('Test')
|
||||
->addStmt($method)
|
||||
->addStmt($property)
|
||||
->addStmts([$const, $use])
|
||||
->getNode()
|
||||
;
|
||||
|
||||
$this->assertEquals(
|
||||
new Stmt\Class_('Test', [
|
||||
'stmts' => [$use, $const, $property, $method]
|
||||
]),
|
||||
$node
|
||||
);
|
||||
}
|
||||
|
||||
public function testDocComment() {
|
||||
$docComment = <<<'DOC'
|
||||
/**
|
||||
* Test
|
||||
*/
|
||||
DOC;
|
||||
$class = $this->createClassBuilder('Test')
|
||||
->setDocComment($docComment)
|
||||
->getNode();
|
||||
|
||||
$this->assertEquals(
|
||||
new Stmt\Class_('Test', [], [
|
||||
'comments' => [
|
||||
new Comment\Doc($docComment)
|
||||
]
|
||||
]),
|
||||
$class
|
||||
);
|
||||
|
||||
$class = $this->createClassBuilder('Test')
|
||||
->setDocComment(new Comment\Doc($docComment))
|
||||
->getNode();
|
||||
|
||||
$this->assertEquals(
|
||||
new Stmt\Class_('Test', [], [
|
||||
'comments' => [
|
||||
new Comment\Doc($docComment)
|
||||
]
|
||||
]),
|
||||
$class
|
||||
);
|
||||
}
|
||||
|
||||
public function testInvalidStmtError() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('Unexpected node of type "Stmt_Echo"');
|
||||
$this->createClassBuilder('Test')
|
||||
->addStmt(new Stmt\Echo_([]))
|
||||
;
|
||||
}
|
||||
|
||||
public function testInvalidDocComment() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('Doc comment must be a string or an instance of PhpParser\Comment\Doc');
|
||||
$this->createClassBuilder('Test')
|
||||
->setDocComment(new Comment('Test'));
|
||||
}
|
||||
|
||||
public function testEmptyName() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('Name cannot be empty');
|
||||
$this->createClassBuilder('Test')
|
||||
->extend('');
|
||||
}
|
||||
|
||||
public function testInvalidName() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('Name must be a string or an instance of Node\Name');
|
||||
$this->createClassBuilder('Test')
|
||||
->extend(['Foo']);
|
||||
}
|
||||
}
|
114
vendor/nikic/php-parser/test/PhpParser/Builder/FunctionTest.php
vendored
Normal file
114
vendor/nikic/php-parser/test/PhpParser/Builder/FunctionTest.php
vendored
Normal file
|
@ -0,0 +1,114 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Builder;
|
||||
|
||||
use PhpParser\Comment;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\Print_;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use PhpParser\Node\Stmt;
|
||||
|
||||
class FunctionTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function createFunctionBuilder($name) {
|
||||
return new Function_($name);
|
||||
}
|
||||
|
||||
public function testReturnByRef() {
|
||||
$node = $this->createFunctionBuilder('test')
|
||||
->makeReturnByRef()
|
||||
->getNode()
|
||||
;
|
||||
|
||||
$this->assertEquals(
|
||||
new Stmt\Function_('test', [
|
||||
'byRef' => true
|
||||
]),
|
||||
$node
|
||||
);
|
||||
}
|
||||
|
||||
public function testParams() {
|
||||
$param1 = new Node\Param(new Variable('test1'));
|
||||
$param2 = new Node\Param(new Variable('test2'));
|
||||
$param3 = new Node\Param(new Variable('test3'));
|
||||
|
||||
$node = $this->createFunctionBuilder('test')
|
||||
->addParam($param1)
|
||||
->addParams([$param2, $param3])
|
||||
->getNode()
|
||||
;
|
||||
|
||||
$this->assertEquals(
|
||||
new Stmt\Function_('test', [
|
||||
'params' => [$param1, $param2, $param3]
|
||||
]),
|
||||
$node
|
||||
);
|
||||
}
|
||||
|
||||
public function testStmts() {
|
||||
$stmt1 = new Print_(new String_('test1'));
|
||||
$stmt2 = new Print_(new String_('test2'));
|
||||
$stmt3 = new Print_(new String_('test3'));
|
||||
|
||||
$node = $this->createFunctionBuilder('test')
|
||||
->addStmt($stmt1)
|
||||
->addStmts([$stmt2, $stmt3])
|
||||
->getNode()
|
||||
;
|
||||
|
||||
$this->assertEquals(
|
||||
new Stmt\Function_('test', [
|
||||
'stmts' => [
|
||||
new Stmt\Expression($stmt1),
|
||||
new Stmt\Expression($stmt2),
|
||||
new Stmt\Expression($stmt3),
|
||||
]
|
||||
]),
|
||||
$node
|
||||
);
|
||||
}
|
||||
|
||||
public function testDocComment() {
|
||||
$node = $this->createFunctionBuilder('test')
|
||||
->setDocComment('/** Test */')
|
||||
->getNode();
|
||||
|
||||
$this->assertEquals(new Stmt\Function_('test', [], [
|
||||
'comments' => [new Comment\Doc('/** Test */')]
|
||||
]), $node);
|
||||
}
|
||||
|
||||
public function testReturnType() {
|
||||
$node = $this->createFunctionBuilder('test')
|
||||
->setReturnType('void')
|
||||
->getNode();
|
||||
|
||||
$this->assertEquals(new Stmt\Function_('test', [
|
||||
'returnType' => 'void'
|
||||
], []), $node);
|
||||
}
|
||||
|
||||
public function testInvalidNullableVoidType() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('void type cannot be nullable');
|
||||
$this->createFunctionBuilder('test')->setReturnType('?void');
|
||||
}
|
||||
|
||||
public function testInvalidParamError() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('Expected parameter node, got "Name"');
|
||||
$this->createFunctionBuilder('test')
|
||||
->addParam(new Node\Name('foo'))
|
||||
;
|
||||
}
|
||||
|
||||
public function testAddNonStmt() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('Expected statement or expression node');
|
||||
$this->createFunctionBuilder('test')
|
||||
->addStmt(new Node\Name('Test'));
|
||||
}
|
||||
}
|
102
vendor/nikic/php-parser/test/PhpParser/Builder/InterfaceTest.php
vendored
Normal file
102
vendor/nikic/php-parser/test/PhpParser/Builder/InterfaceTest.php
vendored
Normal file
|
@ -0,0 +1,102 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Builder;
|
||||
|
||||
use PhpParser\Comment;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Scalar\DNumber;
|
||||
use PhpParser\Node\Stmt;
|
||||
|
||||
class InterfaceTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/** @var Interface_ */
|
||||
protected $builder;
|
||||
|
||||
protected function setUp() {
|
||||
$this->builder = new Interface_('Contract');
|
||||
}
|
||||
|
||||
private function dump($node) {
|
||||
$pp = new \PhpParser\PrettyPrinter\Standard;
|
||||
return $pp->prettyPrint([$node]);
|
||||
}
|
||||
|
||||
public function testEmpty() {
|
||||
$contract = $this->builder->getNode();
|
||||
$this->assertInstanceOf(Stmt\Interface_::class, $contract);
|
||||
$this->assertEquals(new Node\Identifier('Contract'), $contract->name);
|
||||
}
|
||||
|
||||
public function testExtending() {
|
||||
$contract = $this->builder->extend('Space\Root1', 'Root2')->getNode();
|
||||
$this->assertEquals(
|
||||
new Stmt\Interface_('Contract', [
|
||||
'extends' => [
|
||||
new Node\Name('Space\Root1'),
|
||||
new Node\Name('Root2')
|
||||
],
|
||||
]), $contract
|
||||
);
|
||||
}
|
||||
|
||||
public function testAddMethod() {
|
||||
$method = new Stmt\ClassMethod('doSomething');
|
||||
$contract = $this->builder->addStmt($method)->getNode();
|
||||
$this->assertSame([$method], $contract->stmts);
|
||||
}
|
||||
|
||||
public function testAddConst() {
|
||||
$const = new Stmt\ClassConst([
|
||||
new Node\Const_('SPEED_OF_LIGHT', new DNumber(299792458.0))
|
||||
]);
|
||||
$contract = $this->builder->addStmt($const)->getNode();
|
||||
$this->assertSame(299792458.0, $contract->stmts[0]->consts[0]->value->value);
|
||||
}
|
||||
|
||||
public function testOrder() {
|
||||
$const = new Stmt\ClassConst([
|
||||
new Node\Const_('SPEED_OF_LIGHT', new DNumber(299792458))
|
||||
]);
|
||||
$method = new Stmt\ClassMethod('doSomething');
|
||||
$contract = $this->builder
|
||||
->addStmt($method)
|
||||
->addStmt($const)
|
||||
->getNode()
|
||||
;
|
||||
|
||||
$this->assertInstanceOf(Stmt\ClassConst::class, $contract->stmts[0]);
|
||||
$this->assertInstanceOf(Stmt\ClassMethod::class, $contract->stmts[1]);
|
||||
}
|
||||
|
||||
public function testDocComment() {
|
||||
$node = $this->builder
|
||||
->setDocComment('/** Test */')
|
||||
->getNode();
|
||||
|
||||
$this->assertEquals(new Stmt\Interface_('Contract', [], [
|
||||
'comments' => [new Comment\Doc('/** Test */')]
|
||||
]), $node);
|
||||
}
|
||||
|
||||
public function testInvalidStmtError() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('Unexpected node of type "Stmt_PropertyProperty"');
|
||||
$this->builder->addStmt(new Stmt\PropertyProperty('invalid'));
|
||||
}
|
||||
|
||||
public function testFullFunctional() {
|
||||
$const = new Stmt\ClassConst([
|
||||
new Node\Const_('SPEED_OF_LIGHT', new DNumber(299792458))
|
||||
]);
|
||||
$method = new Stmt\ClassMethod('doSomething');
|
||||
$contract = $this->builder
|
||||
->addStmt($method)
|
||||
->addStmt($const)
|
||||
->getNode()
|
||||
;
|
||||
|
||||
eval($this->dump($contract));
|
||||
|
||||
$this->assertTrue(interface_exists('Contract', false));
|
||||
}
|
||||
}
|
162
vendor/nikic/php-parser/test/PhpParser/Builder/MethodTest.php
vendored
Normal file
162
vendor/nikic/php-parser/test/PhpParser/Builder/MethodTest.php
vendored
Normal file
|
@ -0,0 +1,162 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Builder;
|
||||
|
||||
use PhpParser\Comment;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\Print_;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use PhpParser\Node\Stmt;
|
||||
|
||||
class MethodTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function createMethodBuilder($name) {
|
||||
return new Method($name);
|
||||
}
|
||||
|
||||
public function testModifiers() {
|
||||
$node = $this->createMethodBuilder('test')
|
||||
->makePublic()
|
||||
->makeAbstract()
|
||||
->makeStatic()
|
||||
->getNode()
|
||||
;
|
||||
|
||||
$this->assertEquals(
|
||||
new Stmt\ClassMethod('test', [
|
||||
'flags' => Stmt\Class_::MODIFIER_PUBLIC
|
||||
| Stmt\Class_::MODIFIER_ABSTRACT
|
||||
| Stmt\Class_::MODIFIER_STATIC,
|
||||
'stmts' => null,
|
||||
]),
|
||||
$node
|
||||
);
|
||||
|
||||
$node = $this->createMethodBuilder('test')
|
||||
->makeProtected()
|
||||
->makeFinal()
|
||||
->getNode()
|
||||
;
|
||||
|
||||
$this->assertEquals(
|
||||
new Stmt\ClassMethod('test', [
|
||||
'flags' => Stmt\Class_::MODIFIER_PROTECTED
|
||||
| Stmt\Class_::MODIFIER_FINAL
|
||||
]),
|
||||
$node
|
||||
);
|
||||
|
||||
$node = $this->createMethodBuilder('test')
|
||||
->makePrivate()
|
||||
->getNode()
|
||||
;
|
||||
|
||||
$this->assertEquals(
|
||||
new Stmt\ClassMethod('test', [
|
||||
'type' => Stmt\Class_::MODIFIER_PRIVATE
|
||||
]),
|
||||
$node
|
||||
);
|
||||
}
|
||||
|
||||
public function testReturnByRef() {
|
||||
$node = $this->createMethodBuilder('test')
|
||||
->makeReturnByRef()
|
||||
->getNode()
|
||||
;
|
||||
|
||||
$this->assertEquals(
|
||||
new Stmt\ClassMethod('test', [
|
||||
'byRef' => true
|
||||
]),
|
||||
$node
|
||||
);
|
||||
}
|
||||
|
||||
public function testParams() {
|
||||
$param1 = new Node\Param(new Variable('test1'));
|
||||
$param2 = new Node\Param(new Variable('test2'));
|
||||
$param3 = new Node\Param(new Variable('test3'));
|
||||
|
||||
$node = $this->createMethodBuilder('test')
|
||||
->addParam($param1)
|
||||
->addParams([$param2, $param3])
|
||||
->getNode()
|
||||
;
|
||||
|
||||
$this->assertEquals(
|
||||
new Stmt\ClassMethod('test', [
|
||||
'params' => [$param1, $param2, $param3]
|
||||
]),
|
||||
$node
|
||||
);
|
||||
}
|
||||
|
||||
public function testStmts() {
|
||||
$stmt1 = new Print_(new String_('test1'));
|
||||
$stmt2 = new Print_(new String_('test2'));
|
||||
$stmt3 = new Print_(new String_('test3'));
|
||||
|
||||
$node = $this->createMethodBuilder('test')
|
||||
->addStmt($stmt1)
|
||||
->addStmts([$stmt2, $stmt3])
|
||||
->getNode()
|
||||
;
|
||||
|
||||
$this->assertEquals(
|
||||
new Stmt\ClassMethod('test', [
|
||||
'stmts' => [
|
||||
new Stmt\Expression($stmt1),
|
||||
new Stmt\Expression($stmt2),
|
||||
new Stmt\Expression($stmt3),
|
||||
]
|
||||
]),
|
||||
$node
|
||||
);
|
||||
}
|
||||
public function testDocComment() {
|
||||
$node = $this->createMethodBuilder('test')
|
||||
->setDocComment('/** Test */')
|
||||
->getNode();
|
||||
|
||||
$this->assertEquals(new Stmt\ClassMethod('test', [], [
|
||||
'comments' => [new Comment\Doc('/** Test */')]
|
||||
]), $node);
|
||||
}
|
||||
|
||||
public function testReturnType() {
|
||||
$node = $this->createMethodBuilder('test')
|
||||
->setReturnType('bool')
|
||||
->getNode();
|
||||
$this->assertEquals(new Stmt\ClassMethod('test', [
|
||||
'returnType' => 'bool'
|
||||
], []), $node);
|
||||
}
|
||||
|
||||
public function testAddStmtToAbstractMethodError() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('Cannot add statements to an abstract method');
|
||||
$this->createMethodBuilder('test')
|
||||
->makeAbstract()
|
||||
->addStmt(new Print_(new String_('test')))
|
||||
;
|
||||
}
|
||||
|
||||
public function testMakeMethodWithStmtsAbstractError() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('Cannot make method with statements abstract');
|
||||
$this->createMethodBuilder('test')
|
||||
->addStmt(new Print_(new String_('test')))
|
||||
->makeAbstract()
|
||||
;
|
||||
}
|
||||
|
||||
public function testInvalidParamError() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('Expected parameter node, got "Name"');
|
||||
$this->createMethodBuilder('test')
|
||||
->addParam(new Node\Name('foo'))
|
||||
;
|
||||
}
|
||||
}
|
46
vendor/nikic/php-parser/test/PhpParser/Builder/NamespaceTest.php
vendored
Normal file
46
vendor/nikic/php-parser/test/PhpParser/Builder/NamespaceTest.php
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Builder;
|
||||
|
||||
use PhpParser\Comment\Doc;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt;
|
||||
|
||||
class NamespaceTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected function createNamespaceBuilder($fqn) {
|
||||
return new Namespace_($fqn);
|
||||
}
|
||||
|
||||
public function testCreation() {
|
||||
$stmt1 = new Stmt\Class_('SomeClass');
|
||||
$stmt2 = new Stmt\Interface_('SomeInterface');
|
||||
$stmt3 = new Stmt\Function_('someFunction');
|
||||
$docComment = new Doc('/** Test */');
|
||||
$expected = new Stmt\Namespace_(
|
||||
new Node\Name('Name\Space'),
|
||||
[$stmt1, $stmt2, $stmt3],
|
||||
['comments' => [$docComment]]
|
||||
);
|
||||
|
||||
$node = $this->createNamespaceBuilder('Name\Space')
|
||||
->addStmt($stmt1)
|
||||
->addStmts([$stmt2, $stmt3])
|
||||
->setDocComment($docComment)
|
||||
->getNode()
|
||||
;
|
||||
$this->assertEquals($expected, $node);
|
||||
|
||||
$node = $this->createNamespaceBuilder(new Node\Name(['Name', 'Space']))
|
||||
->setDocComment($docComment)
|
||||
->addStmts([$stmt1, $stmt2])
|
||||
->addStmt($stmt3)
|
||||
->getNode()
|
||||
;
|
||||
$this->assertEquals($expected, $node);
|
||||
|
||||
$node = $this->createNamespaceBuilder(null)->getNode();
|
||||
$this->assertNull($node->name);
|
||||
$this->assertEmpty($node->stmts);
|
||||
}
|
||||
}
|
166
vendor/nikic/php-parser/test/PhpParser/Builder/ParamTest.php
vendored
Normal file
166
vendor/nikic/php-parser/test/PhpParser/Builder/ParamTest.php
vendored
Normal file
|
@ -0,0 +1,166 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Builder;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Scalar;
|
||||
|
||||
class ParamTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function createParamBuilder($name) {
|
||||
return new Param($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideTestDefaultValues
|
||||
*/
|
||||
public function testDefaultValues($value, $expectedValueNode) {
|
||||
$node = $this->createParamBuilder('test')
|
||||
->setDefault($value)
|
||||
->getNode()
|
||||
;
|
||||
|
||||
$this->assertEquals($expectedValueNode, $node->default);
|
||||
}
|
||||
|
||||
public function provideTestDefaultValues() {
|
||||
return [
|
||||
[
|
||||
null,
|
||||
new Expr\ConstFetch(new Node\Name('null'))
|
||||
],
|
||||
[
|
||||
true,
|
||||
new Expr\ConstFetch(new Node\Name('true'))
|
||||
],
|
||||
[
|
||||
false,
|
||||
new Expr\ConstFetch(new Node\Name('false'))
|
||||
],
|
||||
[
|
||||
31415,
|
||||
new Scalar\LNumber(31415)
|
||||
],
|
||||
[
|
||||
3.1415,
|
||||
new Scalar\DNumber(3.1415)
|
||||
],
|
||||
[
|
||||
'Hallo World',
|
||||
new Scalar\String_('Hallo World')
|
||||
],
|
||||
[
|
||||
[1, 2, 3],
|
||||
new Expr\Array_([
|
||||
new Expr\ArrayItem(new Scalar\LNumber(1)),
|
||||
new Expr\ArrayItem(new Scalar\LNumber(2)),
|
||||
new Expr\ArrayItem(new Scalar\LNumber(3)),
|
||||
])
|
||||
],
|
||||
[
|
||||
['foo' => 'bar', 'bar' => 'foo'],
|
||||
new Expr\Array_([
|
||||
new Expr\ArrayItem(
|
||||
new Scalar\String_('bar'),
|
||||
new Scalar\String_('foo')
|
||||
),
|
||||
new Expr\ArrayItem(
|
||||
new Scalar\String_('foo'),
|
||||
new Scalar\String_('bar')
|
||||
),
|
||||
])
|
||||
],
|
||||
[
|
||||
new Scalar\MagicConst\Dir,
|
||||
new Scalar\MagicConst\Dir
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideTestTypes
|
||||
*/
|
||||
public function testTypes($typeHint, $expectedType) {
|
||||
$node = $this->createParamBuilder('test')
|
||||
->setTypeHint($typeHint)
|
||||
->getNode()
|
||||
;
|
||||
$type = $node->type;
|
||||
|
||||
/* Manually implement comparison to avoid __toString stupidity */
|
||||
if ($expectedType instanceof Node\NullableType) {
|
||||
$this->assertInstanceOf(get_class($expectedType), $type);
|
||||
$expectedType = $expectedType->type;
|
||||
$type = $type->type;
|
||||
}
|
||||
|
||||
$this->assertInstanceOf(get_class($expectedType), $type);
|
||||
$this->assertEquals($expectedType, $type);
|
||||
}
|
||||
|
||||
public function provideTestTypes() {
|
||||
return [
|
||||
['array', new Node\Identifier('array')],
|
||||
['callable', new Node\Identifier('callable')],
|
||||
['bool', new Node\Identifier('bool')],
|
||||
['int', new Node\Identifier('int')],
|
||||
['float', new Node\Identifier('float')],
|
||||
['string', new Node\Identifier('string')],
|
||||
['iterable', new Node\Identifier('iterable')],
|
||||
['object', new Node\Identifier('object')],
|
||||
['Array', new Node\Identifier('array')],
|
||||
['CALLABLE', new Node\Identifier('callable')],
|
||||
['Some\Class', new Node\Name('Some\Class')],
|
||||
['\Foo', new Node\Name\FullyQualified('Foo')],
|
||||
['self', new Node\Name('self')],
|
||||
['?array', new Node\NullableType(new Node\Identifier('array'))],
|
||||
['?Some\Class', new Node\NullableType(new Node\Name('Some\Class'))],
|
||||
[new Node\Name('Some\Class'), new Node\Name('Some\Class')],
|
||||
[
|
||||
new Node\NullableType(new Node\Identifier('int')),
|
||||
new Node\NullableType(new Node\Identifier('int'))
|
||||
],
|
||||
[
|
||||
new Node\NullableType(new Node\Name('Some\Class')),
|
||||
new Node\NullableType(new Node\Name('Some\Class'))
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function testVoidTypeError() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('Parameter type cannot be void');
|
||||
$this->createParamBuilder('test')->setType('void');
|
||||
}
|
||||
|
||||
public function testInvalidTypeError() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('Type must be a string, or an instance of Name, Identifier or NullableType');
|
||||
$this->createParamBuilder('test')->setType(new \stdClass);
|
||||
}
|
||||
|
||||
public function testByRef() {
|
||||
$node = $this->createParamBuilder('test')
|
||||
->makeByRef()
|
||||
->getNode()
|
||||
;
|
||||
|
||||
$this->assertEquals(
|
||||
new Node\Param(new Expr\Variable('test'), null, null, true),
|
||||
$node
|
||||
);
|
||||
}
|
||||
|
||||
public function testVariadic() {
|
||||
$node = $this->createParamBuilder('test')
|
||||
->makeVariadic()
|
||||
->getNode()
|
||||
;
|
||||
|
||||
$this->assertEquals(
|
||||
new Node\Param(new Expr\Variable('test'), null, null, false, true),
|
||||
$node
|
||||
);
|
||||
}
|
||||
}
|
147
vendor/nikic/php-parser/test/PhpParser/Builder/PropertyTest.php
vendored
Normal file
147
vendor/nikic/php-parser/test/PhpParser/Builder/PropertyTest.php
vendored
Normal file
|
@ -0,0 +1,147 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Builder;
|
||||
|
||||
use PhpParser\Comment;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Scalar;
|
||||
use PhpParser\Node\Stmt;
|
||||
|
||||
class PropertyTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function createPropertyBuilder($name) {
|
||||
return new Property($name);
|
||||
}
|
||||
|
||||
public function testModifiers() {
|
||||
$node = $this->createPropertyBuilder('test')
|
||||
->makePrivate()
|
||||
->makeStatic()
|
||||
->getNode()
|
||||
;
|
||||
|
||||
$this->assertEquals(
|
||||
new Stmt\Property(
|
||||
Stmt\Class_::MODIFIER_PRIVATE
|
||||
| Stmt\Class_::MODIFIER_STATIC,
|
||||
[
|
||||
new Stmt\PropertyProperty('test')
|
||||
]
|
||||
),
|
||||
$node
|
||||
);
|
||||
|
||||
$node = $this->createPropertyBuilder('test')
|
||||
->makeProtected()
|
||||
->getNode()
|
||||
;
|
||||
|
||||
$this->assertEquals(
|
||||
new Stmt\Property(
|
||||
Stmt\Class_::MODIFIER_PROTECTED,
|
||||
[
|
||||
new Stmt\PropertyProperty('test')
|
||||
]
|
||||
),
|
||||
$node
|
||||
);
|
||||
|
||||
$node = $this->createPropertyBuilder('test')
|
||||
->makePublic()
|
||||
->getNode()
|
||||
;
|
||||
|
||||
$this->assertEquals(
|
||||
new Stmt\Property(
|
||||
Stmt\Class_::MODIFIER_PUBLIC,
|
||||
[
|
||||
new Stmt\PropertyProperty('test')
|
||||
]
|
||||
),
|
||||
$node
|
||||
);
|
||||
}
|
||||
|
||||
public function testDocComment() {
|
||||
$node = $this->createPropertyBuilder('test')
|
||||
->setDocComment('/** Test */')
|
||||
->getNode();
|
||||
|
||||
$this->assertEquals(new Stmt\Property(
|
||||
Stmt\Class_::MODIFIER_PUBLIC,
|
||||
[
|
||||
new Stmt\PropertyProperty('test')
|
||||
],
|
||||
[
|
||||
'comments' => [new Comment\Doc('/** Test */')]
|
||||
]
|
||||
), $node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideTestDefaultValues
|
||||
*/
|
||||
public function testDefaultValues($value, $expectedValueNode) {
|
||||
$node = $this->createPropertyBuilder('test')
|
||||
->setDefault($value)
|
||||
->getNode()
|
||||
;
|
||||
|
||||
$this->assertEquals($expectedValueNode, $node->props[0]->default);
|
||||
}
|
||||
|
||||
public function provideTestDefaultValues() {
|
||||
return [
|
||||
[
|
||||
null,
|
||||
new Expr\ConstFetch(new Name('null'))
|
||||
],
|
||||
[
|
||||
true,
|
||||
new Expr\ConstFetch(new Name('true'))
|
||||
],
|
||||
[
|
||||
false,
|
||||
new Expr\ConstFetch(new Name('false'))
|
||||
],
|
||||
[
|
||||
31415,
|
||||
new Scalar\LNumber(31415)
|
||||
],
|
||||
[
|
||||
3.1415,
|
||||
new Scalar\DNumber(3.1415)
|
||||
],
|
||||
[
|
||||
'Hallo World',
|
||||
new Scalar\String_('Hallo World')
|
||||
],
|
||||
[
|
||||
[1, 2, 3],
|
||||
new Expr\Array_([
|
||||
new Expr\ArrayItem(new Scalar\LNumber(1)),
|
||||
new Expr\ArrayItem(new Scalar\LNumber(2)),
|
||||
new Expr\ArrayItem(new Scalar\LNumber(3)),
|
||||
])
|
||||
],
|
||||
[
|
||||
['foo' => 'bar', 'bar' => 'foo'],
|
||||
new Expr\Array_([
|
||||
new Expr\ArrayItem(
|
||||
new Scalar\String_('bar'),
|
||||
new Scalar\String_('foo')
|
||||
),
|
||||
new Expr\ArrayItem(
|
||||
new Scalar\String_('foo'),
|
||||
new Scalar\String_('bar')
|
||||
),
|
||||
])
|
||||
],
|
||||
[
|
||||
new Scalar\MagicConst\Dir,
|
||||
new Scalar\MagicConst\Dir
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
46
vendor/nikic/php-parser/test/PhpParser/Builder/TraitTest.php
vendored
Normal file
46
vendor/nikic/php-parser/test/PhpParser/Builder/TraitTest.php
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Builder;
|
||||
|
||||
use PhpParser\Comment;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Stmt;
|
||||
|
||||
class TraitTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected function createTraitBuilder($class) {
|
||||
return new Trait_($class);
|
||||
}
|
||||
|
||||
public function testStmtAddition() {
|
||||
$method1 = new Stmt\ClassMethod('test1');
|
||||
$method2 = new Stmt\ClassMethod('test2');
|
||||
$method3 = new Stmt\ClassMethod('test3');
|
||||
$prop = new Stmt\Property(Stmt\Class_::MODIFIER_PUBLIC, [
|
||||
new Stmt\PropertyProperty('test')
|
||||
]);
|
||||
$use = new Stmt\TraitUse([new Name('OtherTrait')]);
|
||||
$trait = $this->createTraitBuilder('TestTrait')
|
||||
->setDocComment('/** Nice trait */')
|
||||
->addStmt($method1)
|
||||
->addStmts([$method2, $method3])
|
||||
->addStmt($prop)
|
||||
->addStmt($use)
|
||||
->getNode();
|
||||
$this->assertEquals(new Stmt\Trait_('TestTrait', [
|
||||
'stmts' => [$use, $prop, $method1, $method2, $method3]
|
||||
], [
|
||||
'comments' => [
|
||||
new Comment\Doc('/** Nice trait */')
|
||||
]
|
||||
]), $trait);
|
||||
}
|
||||
|
||||
public function testInvalidStmtError() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('Unexpected node of type "Stmt_Echo"');
|
||||
$this->createTraitBuilder('Test')
|
||||
->addStmt(new Stmt\Echo_([]))
|
||||
;
|
||||
}
|
||||
}
|
106
vendor/nikic/php-parser/test/PhpParser/Builder/TraitUseAdaptationTest.php
vendored
Normal file
106
vendor/nikic/php-parser/test/PhpParser/Builder/TraitUseAdaptationTest.php
vendored
Normal file
|
@ -0,0 +1,106 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Builder;
|
||||
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Stmt;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
|
||||
class TraitUseAdaptationTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected function createTraitUseAdaptationBuilder($trait, $method) {
|
||||
return new TraitUseAdaptation($trait, $method);
|
||||
}
|
||||
|
||||
public function testAsMake() {
|
||||
$builder = $this->createTraitUseAdaptationBuilder(null, 'foo');
|
||||
|
||||
$this->assertEquals(
|
||||
new Stmt\TraitUseAdaptation\Alias(null, 'foo', null, 'bar'),
|
||||
(clone $builder)->as('bar')->getNode()
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
new Stmt\TraitUseAdaptation\Alias(null, 'foo', Class_::MODIFIER_PUBLIC, null),
|
||||
(clone $builder)->makePublic()->getNode()
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
new Stmt\TraitUseAdaptation\Alias(null, 'foo', Class_::MODIFIER_PROTECTED, null),
|
||||
(clone $builder)->makeProtected()->getNode()
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
new Stmt\TraitUseAdaptation\Alias(null, 'foo', Class_::MODIFIER_PRIVATE, null),
|
||||
(clone $builder)->makePrivate()->getNode()
|
||||
);
|
||||
}
|
||||
|
||||
public function testInsteadof() {
|
||||
$node = $this->createTraitUseAdaptationBuilder('SomeTrait', 'foo')
|
||||
->insteadof('AnotherTrait')
|
||||
->getNode()
|
||||
;
|
||||
|
||||
$this->assertEquals(
|
||||
new Stmt\TraitUseAdaptation\Precedence(
|
||||
new Name('SomeTrait'),
|
||||
'foo',
|
||||
[new Name('AnotherTrait')]
|
||||
),
|
||||
$node
|
||||
);
|
||||
}
|
||||
|
||||
public function testAsOnNotAlias() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('Cannot set alias for not alias adaptation buider');
|
||||
$this->createTraitUseAdaptationBuilder('Test', 'foo')
|
||||
->insteadof('AnotherTrait')
|
||||
->as('bar')
|
||||
;
|
||||
}
|
||||
|
||||
public function testInsteadofOnNotPrecedence() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('Cannot add overwritten traits for not precedence adaptation buider');
|
||||
$this->createTraitUseAdaptationBuilder('Test', 'foo')
|
||||
->as('bar')
|
||||
->insteadof('AnotherTrait')
|
||||
;
|
||||
}
|
||||
|
||||
public function testInsteadofWithoutTrait() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('Precedence adaptation must have trait');
|
||||
$this->createTraitUseAdaptationBuilder(null, 'foo')
|
||||
->insteadof('AnotherTrait')
|
||||
;
|
||||
}
|
||||
|
||||
public function testMakeOnNotAlias() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('Cannot set access modifier for not alias adaptation buider');
|
||||
$this->createTraitUseAdaptationBuilder('Test', 'foo')
|
||||
->insteadof('AnotherTrait')
|
||||
->makePublic()
|
||||
;
|
||||
}
|
||||
|
||||
public function testMultipleMake() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('Multiple access type modifiers are not allowed');
|
||||
$this->createTraitUseAdaptationBuilder(null, 'foo')
|
||||
->makePrivate()
|
||||
->makePublic()
|
||||
;
|
||||
}
|
||||
|
||||
public function testUndefinedType() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('Type of adaptation is not defined');
|
||||
$this->createTraitUseAdaptationBuilder(null, 'foo')
|
||||
->getNode()
|
||||
;
|
||||
}
|
||||
}
|
52
vendor/nikic/php-parser/test/PhpParser/Builder/TraitUseTest.php
vendored
Normal file
52
vendor/nikic/php-parser/test/PhpParser/Builder/TraitUseTest.php
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Builder;
|
||||
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Stmt;
|
||||
|
||||
class TraitUseTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected function createTraitUseBuilder(...$traits) {
|
||||
return new TraitUse(...$traits);
|
||||
}
|
||||
|
||||
public function testAnd() {
|
||||
$node = $this->createTraitUseBuilder('SomeTrait')
|
||||
->and('AnotherTrait')
|
||||
->getNode()
|
||||
;
|
||||
|
||||
$this->assertEquals(
|
||||
new Stmt\TraitUse([
|
||||
new Name('SomeTrait'),
|
||||
new Name('AnotherTrait')
|
||||
]),
|
||||
$node
|
||||
);
|
||||
}
|
||||
|
||||
public function testWith() {
|
||||
$node = $this->createTraitUseBuilder('SomeTrait')
|
||||
->with(new Stmt\TraitUseAdaptation\Alias(null, 'foo', null, 'bar'))
|
||||
->with((new TraitUseAdaptation(null, 'test'))->as('baz'))
|
||||
->getNode()
|
||||
;
|
||||
|
||||
$this->assertEquals(
|
||||
new Stmt\TraitUse([new Name('SomeTrait')], [
|
||||
new Stmt\TraitUseAdaptation\Alias(null, 'foo', null, 'bar'),
|
||||
new Stmt\TraitUseAdaptation\Alias(null, 'test', null, 'baz')
|
||||
]),
|
||||
$node
|
||||
);
|
||||
}
|
||||
|
||||
public function testInvalidAdaptationNode() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('Adaptation must have type TraitUseAdaptation');
|
||||
$this->createTraitUseBuilder('Test')
|
||||
->with(new Stmt\Echo_([]))
|
||||
;
|
||||
}
|
||||
}
|
36
vendor/nikic/php-parser/test/PhpParser/Builder/UseTest.php
vendored
Normal file
36
vendor/nikic/php-parser/test/PhpParser/Builder/UseTest.php
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Builder;
|
||||
|
||||
use PhpParser\Builder;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Stmt;
|
||||
|
||||
class UseTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected function createUseBuilder($name, $type = Stmt\Use_::TYPE_NORMAL) {
|
||||
return new Builder\Use_($name, $type);
|
||||
}
|
||||
|
||||
public function testCreation() {
|
||||
$node = $this->createUseBuilder('Foo\Bar')->getNode();
|
||||
$this->assertEquals(new Stmt\Use_([
|
||||
new Stmt\UseUse(new Name('Foo\Bar'), null)
|
||||
]), $node);
|
||||
|
||||
$node = $this->createUseBuilder(new Name('Foo\Bar'))->as('XYZ')->getNode();
|
||||
$this->assertEquals(new Stmt\Use_([
|
||||
new Stmt\UseUse(new Name('Foo\Bar'), 'XYZ')
|
||||
]), $node);
|
||||
|
||||
$node = $this->createUseBuilder('foo\bar', Stmt\Use_::TYPE_FUNCTION)->as('foo')->getNode();
|
||||
$this->assertEquals(new Stmt\Use_([
|
||||
new Stmt\UseUse(new Name('foo\bar'), 'foo')
|
||||
], Stmt\Use_::TYPE_FUNCTION), $node);
|
||||
|
||||
$node = $this->createUseBuilder('foo\BAR', Stmt\Use_::TYPE_CONSTANT)->as('FOO')->getNode();
|
||||
$this->assertEquals(new Stmt\Use_([
|
||||
new Stmt\UseUse(new Name('foo\BAR'), 'FOO')
|
||||
], Stmt\Use_::TYPE_CONSTANT), $node);
|
||||
}
|
||||
}
|
327
vendor/nikic/php-parser/test/PhpParser/BuilderFactoryTest.php
vendored
Normal file
327
vendor/nikic/php-parser/test/PhpParser/BuilderFactoryTest.php
vendored
Normal file
|
@ -0,0 +1,327 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser;
|
||||
|
||||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\BinaryOp\Concat;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Scalar\LNumber;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
|
||||
class BuilderFactoryTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideTestFactory
|
||||
*/
|
||||
public function testFactory($methodName, $className) {
|
||||
$factory = new BuilderFactory;
|
||||
$this->assertInstanceOf($className, $factory->$methodName('test'));
|
||||
}
|
||||
|
||||
public function provideTestFactory() {
|
||||
return [
|
||||
['namespace', Builder\Namespace_::class],
|
||||
['class', Builder\Class_::class],
|
||||
['interface', Builder\Interface_::class],
|
||||
['trait', Builder\Trait_::class],
|
||||
['method', Builder\Method::class],
|
||||
['function', Builder\Function_::class],
|
||||
['property', Builder\Property::class],
|
||||
['param', Builder\Param::class],
|
||||
['use', Builder\Use_::class],
|
||||
['useFunction', Builder\Use_::class],
|
||||
['useConst', Builder\Use_::class],
|
||||
];
|
||||
}
|
||||
|
||||
public function testVal() {
|
||||
// This method is a wrapper around BuilderHelpers::normalizeValue(),
|
||||
// which is already tested elsewhere
|
||||
$factory = new BuilderFactory();
|
||||
$this->assertEquals(
|
||||
new String_("foo"),
|
||||
$factory->val("foo")
|
||||
);
|
||||
}
|
||||
|
||||
public function testConcat() {
|
||||
$factory = new BuilderFactory();
|
||||
$varA = new Expr\Variable('a');
|
||||
$varB = new Expr\Variable('b');
|
||||
$varC = new Expr\Variable('c');
|
||||
|
||||
$this->assertEquals(
|
||||
new Concat($varA, $varB),
|
||||
$factory->concat($varA, $varB)
|
||||
);
|
||||
$this->assertEquals(
|
||||
new Concat(new Concat($varA, $varB), $varC),
|
||||
$factory->concat($varA, $varB, $varC)
|
||||
);
|
||||
$this->assertEquals(
|
||||
new Concat(new Concat(new String_("a"), $varB), new String_("c")),
|
||||
$factory->concat("a", $varB, "c")
|
||||
);
|
||||
}
|
||||
|
||||
public function testConcatOneError() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('Expected at least two expressions');
|
||||
(new BuilderFactory())->concat("a");
|
||||
}
|
||||
|
||||
public function testConcatInvalidExpr() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('Expected string or Expr');
|
||||
(new BuilderFactory())->concat("a", 42);
|
||||
}
|
||||
|
||||
public function testArgs() {
|
||||
$factory = new BuilderFactory();
|
||||
$unpack = new Arg(new Expr\Variable('c'), false, true);
|
||||
$this->assertEquals(
|
||||
[
|
||||
new Arg(new Expr\Variable('a')),
|
||||
new Arg(new String_('b')),
|
||||
$unpack
|
||||
],
|
||||
$factory->args([new Expr\Variable('a'), 'b', $unpack])
|
||||
);
|
||||
}
|
||||
|
||||
public function testCalls() {
|
||||
$factory = new BuilderFactory();
|
||||
|
||||
// Simple function call
|
||||
$this->assertEquals(
|
||||
new Expr\FuncCall(
|
||||
new Name('var_dump'),
|
||||
[new Arg(new String_('str'))]
|
||||
),
|
||||
$factory->funcCall('var_dump', ['str'])
|
||||
);
|
||||
// Dynamic function call
|
||||
$this->assertEquals(
|
||||
new Expr\FuncCall(new Expr\Variable('fn')),
|
||||
$factory->funcCall(new Expr\Variable('fn'))
|
||||
);
|
||||
|
||||
// Simple method call
|
||||
$this->assertEquals(
|
||||
new Expr\MethodCall(
|
||||
new Expr\Variable('obj'),
|
||||
new Identifier('method'),
|
||||
[new Arg(new LNumber(42))]
|
||||
),
|
||||
$factory->methodCall(new Expr\Variable('obj'), 'method', [42])
|
||||
);
|
||||
// Explicitly pass Identifier node
|
||||
$this->assertEquals(
|
||||
new Expr\MethodCall(
|
||||
new Expr\Variable('obj'),
|
||||
new Identifier('method')
|
||||
),
|
||||
$factory->methodCall(new Expr\Variable('obj'), new Identifier('method'))
|
||||
);
|
||||
// Dynamic method call
|
||||
$this->assertEquals(
|
||||
new Expr\MethodCall(
|
||||
new Expr\Variable('obj'),
|
||||
new Expr\Variable('method')
|
||||
),
|
||||
$factory->methodCall(new Expr\Variable('obj'), new Expr\Variable('method'))
|
||||
);
|
||||
|
||||
// Simple static method call
|
||||
$this->assertEquals(
|
||||
new Expr\StaticCall(
|
||||
new Name\FullyQualified('Foo'),
|
||||
new Identifier('bar'),
|
||||
[new Arg(new Expr\Variable('baz'))]
|
||||
),
|
||||
$factory->staticCall('\Foo', 'bar', [new Expr\Variable('baz')])
|
||||
);
|
||||
// Dynamic static method call
|
||||
$this->assertEquals(
|
||||
new Expr\StaticCall(
|
||||
new Expr\Variable('foo'),
|
||||
new Expr\Variable('bar')
|
||||
),
|
||||
$factory->staticCall(new Expr\Variable('foo'), new Expr\Variable('bar'))
|
||||
);
|
||||
|
||||
// Simple new call
|
||||
$this->assertEquals(
|
||||
new Expr\New_(new Name\FullyQualified('stdClass')),
|
||||
$factory->new('\stdClass')
|
||||
);
|
||||
// Dynamic new call
|
||||
$this->assertEquals(
|
||||
new Expr\New_(
|
||||
new Expr\Variable('foo'),
|
||||
[new Arg(new String_('bar'))]
|
||||
),
|
||||
$factory->new(new Expr\Variable('foo'), ['bar'])
|
||||
);
|
||||
}
|
||||
|
||||
public function testConstFetches() {
|
||||
$factory = new BuilderFactory();
|
||||
$this->assertEquals(
|
||||
new Expr\ConstFetch(new Name('FOO')),
|
||||
$factory->constFetch('FOO')
|
||||
);
|
||||
$this->assertEquals(
|
||||
new Expr\ClassConstFetch(new Name('Foo'), new Identifier('BAR')),
|
||||
$factory->classConstFetch('Foo', 'BAR')
|
||||
);
|
||||
$this->assertEquals(
|
||||
new Expr\ClassConstFetch(new Expr\Variable('foo'), new Identifier('BAR')),
|
||||
$factory->classConstFetch(new Expr\Variable('foo'), 'BAR')
|
||||
);
|
||||
}
|
||||
|
||||
public function testVar() {
|
||||
$factory = new BuilderFactory();
|
||||
$this->assertEquals(
|
||||
new Expr\Variable("foo"),
|
||||
$factory->var("foo")
|
||||
);
|
||||
$this->assertEquals(
|
||||
new Expr\Variable(new Expr\Variable("foo")),
|
||||
$factory->var($factory->var("foo"))
|
||||
);
|
||||
}
|
||||
|
||||
public function testPropertyFetch() {
|
||||
$f = new BuilderFactory();
|
||||
$this->assertEquals(
|
||||
new Expr\PropertyFetch(new Expr\Variable('foo'), 'bar'),
|
||||
$f->propertyFetch($f->var('foo'), 'bar')
|
||||
);
|
||||
$this->assertEquals(
|
||||
new Expr\PropertyFetch(new Expr\Variable('foo'), 'bar'),
|
||||
$f->propertyFetch($f->var('foo'), new Identifier('bar'))
|
||||
);
|
||||
$this->assertEquals(
|
||||
new Expr\PropertyFetch(new Expr\Variable('foo'), new Expr\Variable('bar')),
|
||||
$f->propertyFetch($f->var('foo'), $f->var('bar'))
|
||||
);
|
||||
}
|
||||
|
||||
public function testInvalidIdentifier() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('Expected string or instance of Node\Identifier');
|
||||
(new BuilderFactory())->classConstFetch('Foo', new Expr\Variable('foo'));
|
||||
}
|
||||
|
||||
public function testInvalidIdentifierOrExpr() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('Expected string or instance of Node\Identifier or Node\Expr');
|
||||
(new BuilderFactory())->staticCall('Foo', new Name('bar'));
|
||||
}
|
||||
|
||||
public function testInvalidNameOrExpr() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('Name must be a string or an instance of Node\Name or Node\Expr');
|
||||
(new BuilderFactory())->funcCall(new Node\Stmt\Return_());
|
||||
}
|
||||
|
||||
public function testInvalidVar() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('Variable name must be string or Expr');
|
||||
(new BuilderFactory())->var(new Node\Stmt\Return_());
|
||||
}
|
||||
|
||||
public function testIntegration() {
|
||||
$factory = new BuilderFactory;
|
||||
$node = $factory->namespace('Name\Space')
|
||||
->addStmt($factory->use('Foo\Bar\SomeOtherClass'))
|
||||
->addStmt($factory->use('Foo\Bar')->as('A'))
|
||||
->addStmt($factory->useFunction('strlen'))
|
||||
->addStmt($factory->useConst('PHP_VERSION'))
|
||||
->addStmt($factory
|
||||
->class('SomeClass')
|
||||
->extend('SomeOtherClass')
|
||||
->implement('A\Few', '\Interfaces')
|
||||
->makeAbstract()
|
||||
|
||||
->addStmt($factory->useTrait('FirstTrait'))
|
||||
|
||||
->addStmt($factory->useTrait('SecondTrait', 'ThirdTrait')
|
||||
->and('AnotherTrait')
|
||||
->with($factory->traitUseAdaptation('foo')->as('bar'))
|
||||
->with($factory->traitUseAdaptation('AnotherTrait', 'baz')->as('test'))
|
||||
->with($factory->traitUseAdaptation('AnotherTrait', 'func')->insteadof('SecondTrait')))
|
||||
|
||||
->addStmt($factory->method('firstMethod'))
|
||||
|
||||
->addStmt($factory->method('someMethod')
|
||||
->makePublic()
|
||||
->makeAbstract()
|
||||
->addParam($factory->param('someParam')->setType('SomeClass'))
|
||||
->setDocComment('/**
|
||||
* This method does something.
|
||||
*
|
||||
* @param SomeClass And takes a parameter
|
||||
*/'))
|
||||
|
||||
->addStmt($factory->method('anotherMethod')
|
||||
->makeProtected()
|
||||
->addParam($factory->param('someParam')->setDefault('test'))
|
||||
->addStmt(new Expr\Print_(new Expr\Variable('someParam'))))
|
||||
|
||||
->addStmt($factory->property('someProperty')->makeProtected())
|
||||
->addStmt($factory->property('anotherProperty')
|
||||
->makePrivate()
|
||||
->setDefault([1, 2, 3])))
|
||||
->getNode()
|
||||
;
|
||||
|
||||
$expected = <<<'EOC'
|
||||
<?php
|
||||
|
||||
namespace Name\Space;
|
||||
|
||||
use Foo\Bar\SomeOtherClass;
|
||||
use Foo\Bar as A;
|
||||
use function strlen;
|
||||
use const PHP_VERSION;
|
||||
abstract class SomeClass extends SomeOtherClass implements A\Few, \Interfaces
|
||||
{
|
||||
use FirstTrait;
|
||||
use SecondTrait, ThirdTrait, AnotherTrait {
|
||||
foo as bar;
|
||||
AnotherTrait::baz as test;
|
||||
AnotherTrait::func insteadof SecondTrait;
|
||||
}
|
||||
protected $someProperty;
|
||||
private $anotherProperty = array(1, 2, 3);
|
||||
function firstMethod()
|
||||
{
|
||||
}
|
||||
/**
|
||||
* This method does something.
|
||||
*
|
||||
* @param SomeClass And takes a parameter
|
||||
*/
|
||||
public abstract function someMethod(SomeClass $someParam);
|
||||
protected function anotherMethod($someParam = 'test')
|
||||
{
|
||||
print $someParam;
|
||||
}
|
||||
}
|
||||
EOC;
|
||||
|
||||
$stmts = [$node];
|
||||
$prettyPrinter = new PrettyPrinter\Standard();
|
||||
$generated = $prettyPrinter->prettyPrintFile($stmts);
|
||||
|
||||
$this->assertEquals(
|
||||
str_replace("\r\n", "\n", $expected),
|
||||
str_replace("\r\n", "\n", $generated)
|
||||
);
|
||||
}
|
||||
}
|
119
vendor/nikic/php-parser/test/PhpParser/CodeParsingTest.php
vendored
Normal file
119
vendor/nikic/php-parser/test/PhpParser/CodeParsingTest.php
vendored
Normal file
|
@ -0,0 +1,119 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser;
|
||||
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Stmt;
|
||||
|
||||
class CodeParsingTest extends CodeTestAbstract
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideTestParse
|
||||
*/
|
||||
public function testParse($name, $code, $expected, $modeLine) {
|
||||
if (null !== $modeLine) {
|
||||
$modes = array_fill_keys(explode(',', $modeLine), true);
|
||||
} else {
|
||||
$modes = [];
|
||||
}
|
||||
|
||||
list($parser5, $parser7) = $this->createParsers($modes);
|
||||
list($stmts5, $output5) = $this->getParseOutput($parser5, $code, $modes);
|
||||
list($stmts7, $output7) = $this->getParseOutput($parser7, $code, $modes);
|
||||
|
||||
if (isset($modes['php5'])) {
|
||||
$this->assertSame($expected, $output5, $name);
|
||||
$this->assertNotSame($expected, $output7, $name);
|
||||
} elseif (isset($modes['php7'])) {
|
||||
$this->assertNotSame($expected, $output5, $name);
|
||||
$this->assertSame($expected, $output7, $name);
|
||||
} else {
|
||||
$this->assertSame($expected, $output5, $name);
|
||||
$this->assertSame($expected, $output7, $name);
|
||||
}
|
||||
|
||||
$this->checkAttributes($stmts5);
|
||||
$this->checkAttributes($stmts7);
|
||||
}
|
||||
|
||||
public function createParsers(array $modes) {
|
||||
$lexer = new Lexer\Emulative(['usedAttributes' => [
|
||||
'startLine', 'endLine',
|
||||
'startFilePos', 'endFilePos',
|
||||
'startTokenPos', 'endTokenPos',
|
||||
'comments'
|
||||
]]);
|
||||
|
||||
return [
|
||||
new Parser\Php5($lexer),
|
||||
new Parser\Php7($lexer),
|
||||
];
|
||||
}
|
||||
|
||||
// Must be public for updateTests.php
|
||||
public function getParseOutput(Parser $parser, $code, array $modes) {
|
||||
$dumpPositions = isset($modes['positions']);
|
||||
|
||||
$errors = new ErrorHandler\Collecting;
|
||||
$stmts = $parser->parse($code, $errors);
|
||||
|
||||
$output = '';
|
||||
foreach ($errors->getErrors() as $error) {
|
||||
$output .= $this->formatErrorMessage($error, $code) . "\n";
|
||||
}
|
||||
|
||||
if (null !== $stmts) {
|
||||
$dumper = new NodeDumper(['dumpComments' => true, 'dumpPositions' => $dumpPositions]);
|
||||
$output .= $dumper->dump($stmts, $code);
|
||||
}
|
||||
|
||||
return [$stmts, canonicalize($output)];
|
||||
}
|
||||
|
||||
public function provideTestParse() {
|
||||
return $this->getTests(__DIR__ . '/../code/parser', 'test');
|
||||
}
|
||||
|
||||
private function formatErrorMessage(Error $e, $code) {
|
||||
if ($e->hasColumnInfo()) {
|
||||
return $e->getMessageWithColumnInfo($code);
|
||||
}
|
||||
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
private function checkAttributes($stmts) {
|
||||
if ($stmts === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$traverser = new NodeTraverser();
|
||||
$traverser->addVisitor(new class extends NodeVisitorAbstract {
|
||||
public function enterNode(Node $node) {
|
||||
$startLine = $node->getStartLine();
|
||||
$endLine = $node->getEndLine();
|
||||
$startFilePos = $node->getStartFilePos();
|
||||
$endFilePos = $node->getEndFilePos();
|
||||
$startTokenPos = $node->getStartTokenPos();
|
||||
$endTokenPos = $node->getEndTokenPos();
|
||||
if ($startLine < 0 || $endLine < 0 ||
|
||||
$startFilePos < 0 || $endFilePos < 0 ||
|
||||
$startTokenPos < 0 || $endTokenPos < 0
|
||||
) {
|
||||
throw new \Exception('Missing location information on ' . $node->getType());
|
||||
}
|
||||
|
||||
if ($endLine < $startLine ||
|
||||
$endFilePos < $startFilePos ||
|
||||
$endTokenPos < $startTokenPos
|
||||
) {
|
||||
// Nops and error can have inverted order, if they are empty
|
||||
if (!$node instanceof Stmt\Nop && !$node instanceof Expr\Error) {
|
||||
throw new \Exception('End < start on ' . $node->getType());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
$traverser->traverse($stmts);
|
||||
}
|
||||
}
|
26
vendor/nikic/php-parser/test/PhpParser/CodeTestAbstract.php
vendored
Normal file
26
vendor/nikic/php-parser/test/PhpParser/CodeTestAbstract.php
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser;
|
||||
|
||||
abstract class CodeTestAbstract extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected function getTests($directory, $fileExtension, $chunksPerTest = 2) {
|
||||
$parser = new CodeTestParser;
|
||||
$allTests = [];
|
||||
foreach (filesInDir($directory, $fileExtension) as $fileName => $fileContents) {
|
||||
list($name, $tests) = $parser->parseTest($fileContents, $chunksPerTest);
|
||||
|
||||
// first part is the name
|
||||
$name .= ' (' . $fileName . ')';
|
||||
$shortName = ltrim(str_replace($directory, '', $fileName), '/\\');
|
||||
|
||||
// multiple sections possible with always two forming a pair
|
||||
foreach ($tests as $i => list($mode, $parts)) {
|
||||
$dataSetName = $shortName . (count($parts) > 1 ? '#' . $i : '');
|
||||
$allTests[$dataSetName] = array_merge([$name], $parts, [$mode]);
|
||||
}
|
||||
}
|
||||
|
||||
return $allTests;
|
||||
}
|
||||
}
|
68
vendor/nikic/php-parser/test/PhpParser/CodeTestParser.php
vendored
Normal file
68
vendor/nikic/php-parser/test/PhpParser/CodeTestParser.php
vendored
Normal file
|
@ -0,0 +1,68 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser;
|
||||
|
||||
class CodeTestParser
|
||||
{
|
||||
public function parseTest($code, $chunksPerTest) {
|
||||
$code = canonicalize($code);
|
||||
|
||||
// evaluate @@{expr}@@ expressions
|
||||
$code = preg_replace_callback(
|
||||
'/@@\{(.*?)\}@@/',
|
||||
function($matches) {
|
||||
return eval('return ' . $matches[1] . ';');
|
||||
},
|
||||
$code
|
||||
);
|
||||
|
||||
// parse sections
|
||||
$parts = preg_split("/\n-----(?:\n|$)/", $code);
|
||||
|
||||
// first part is the name
|
||||
$name = array_shift($parts);
|
||||
|
||||
// multiple sections possible with always two forming a pair
|
||||
$chunks = array_chunk($parts, $chunksPerTest);
|
||||
$tests = [];
|
||||
foreach ($chunks as $i => $chunk) {
|
||||
$lastPart = array_pop($chunk);
|
||||
list($lastPart, $mode) = $this->extractMode($lastPart);
|
||||
$tests[] = [$mode, array_merge($chunk, [$lastPart])];
|
||||
}
|
||||
|
||||
return [$name, $tests];
|
||||
}
|
||||
|
||||
public function reconstructTest($name, array $tests) {
|
||||
$result = $name;
|
||||
foreach ($tests as list($mode, $parts)) {
|
||||
$lastPart = array_pop($parts);
|
||||
foreach ($parts as $part) {
|
||||
$result .= "\n-----\n$part";
|
||||
}
|
||||
|
||||
$result .= "\n-----\n";
|
||||
if (null !== $mode) {
|
||||
$result .= "!!$mode\n";
|
||||
}
|
||||
$result .= $lastPart;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function extractMode($expected) {
|
||||
$firstNewLine = strpos($expected, "\n");
|
||||
if (false === $firstNewLine) {
|
||||
$firstNewLine = strlen($expected);
|
||||
}
|
||||
|
||||
$firstLine = substr($expected, 0, $firstNewLine);
|
||||
if (0 !== strpos($firstLine, '!!')) {
|
||||
return [$expected, null];
|
||||
}
|
||||
|
||||
$expected = (string) substr($expected, $firstNewLine + 1);
|
||||
return [$expected, substr($firstLine, 2)];
|
||||
}
|
||||
}
|
74
vendor/nikic/php-parser/test/PhpParser/CommentTest.php
vendored
Normal file
74
vendor/nikic/php-parser/test/PhpParser/CommentTest.php
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser;
|
||||
|
||||
class CommentTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testGetSet() {
|
||||
$comment = new Comment('/* Some comment */', 1, 10, 2);
|
||||
|
||||
$this->assertSame('/* Some comment */', $comment->getText());
|
||||
$this->assertSame('/* Some comment */', (string) $comment);
|
||||
$this->assertSame(1, $comment->getLine());
|
||||
$this->assertSame(10, $comment->getFilePos());
|
||||
$this->assertSame(2, $comment->getTokenPos());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideTestReformatting
|
||||
*/
|
||||
public function testReformatting($commentText, $reformattedText) {
|
||||
$comment = new Comment($commentText);
|
||||
$this->assertSame($reformattedText, $comment->getReformattedText());
|
||||
}
|
||||
|
||||
public function provideTestReformatting() {
|
||||
return [
|
||||
['// Some text' . "\n", '// Some text'],
|
||||
['/* Some text */', '/* Some text */'],
|
||||
[
|
||||
'/**
|
||||
* Some text.
|
||||
* Some more text.
|
||||
*/',
|
||||
'/**
|
||||
* Some text.
|
||||
* Some more text.
|
||||
*/'
|
||||
],
|
||||
[
|
||||
'/*
|
||||
Some text.
|
||||
Some more text.
|
||||
*/',
|
||||
'/*
|
||||
Some text.
|
||||
Some more text.
|
||||
*/'
|
||||
],
|
||||
[
|
||||
'/* Some text.
|
||||
More text.
|
||||
Even more text. */',
|
||||
'/* Some text.
|
||||
More text.
|
||||
Even more text. */'
|
||||
],
|
||||
[
|
||||
'/* Some text.
|
||||
More text.
|
||||
Indented text. */',
|
||||
'/* Some text.
|
||||
More text.
|
||||
Indented text. */',
|
||||
],
|
||||
// invalid comment -> no reformatting
|
||||
[
|
||||
'hallo
|
||||
world',
|
||||
'hallo
|
||||
world',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
130
vendor/nikic/php-parser/test/PhpParser/ConstExprEvaluatorTest.php
vendored
Normal file
130
vendor/nikic/php-parser/test/PhpParser/ConstExprEvaluatorTest.php
vendored
Normal file
|
@ -0,0 +1,130 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser;
|
||||
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Scalar;
|
||||
|
||||
class ConstExprEvaluatorTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/** @dataProvider provideTestEvaluate */
|
||||
public function testEvaluate($exprString, $expected) {
|
||||
$parser = new Parser\Php7(new Lexer());
|
||||
$expr = $parser->parse('<?php ' . $exprString . ';')[0]->expr;
|
||||
$evaluator = new ConstExprEvaluator();
|
||||
$this->assertSame($expected, $evaluator->evaluateDirectly($expr));
|
||||
}
|
||||
|
||||
public function provideTestEvaluate() {
|
||||
return [
|
||||
['1', 1],
|
||||
['1.0', 1.0],
|
||||
['"foo"', "foo"],
|
||||
['[0, 1]', [0, 1]],
|
||||
['["foo" => "bar"]', ["foo" => "bar"]],
|
||||
['NULL', null],
|
||||
['False', false],
|
||||
['true', true],
|
||||
['+1', 1],
|
||||
['-1', -1],
|
||||
['~0', -1],
|
||||
['!true', false],
|
||||
['[0][0]', 0],
|
||||
['"a"[0]', "a"],
|
||||
['true ? 1 : (1/0)', 1],
|
||||
['false ? (1/0) : 1', 1],
|
||||
['42 ?: (1/0)', 42],
|
||||
['false ?: 42', 42],
|
||||
['false ?? 42', false],
|
||||
['null ?? 42', 42],
|
||||
['[0][0] ?? 42', 0],
|
||||
['[][0] ?? 42', 42],
|
||||
['0b11 & 0b10', 0b10],
|
||||
['0b11 | 0b10', 0b11],
|
||||
['0b11 ^ 0b10', 0b01],
|
||||
['1 << 2', 4],
|
||||
['4 >> 2', 1],
|
||||
['"a" . "b"', "ab"],
|
||||
['4 + 2', 6],
|
||||
['4 - 2', 2],
|
||||
['4 * 2', 8],
|
||||
['4 / 2', 2],
|
||||
['4 % 2', 0],
|
||||
['4 ** 2', 16],
|
||||
['1 == 1.0', true],
|
||||
['1 != 1.0', false],
|
||||
['1 < 2.0', true],
|
||||
['1 <= 2.0', true],
|
||||
['1 > 2.0', false],
|
||||
['1 >= 2.0', false],
|
||||
['1 <=> 2.0', -1],
|
||||
['1 === 1.0', false],
|
||||
['1 !== 1.0', true],
|
||||
['true && true', true],
|
||||
['true and true', true],
|
||||
['false && (1/0)', false],
|
||||
['false and (1/0)', false],
|
||||
['false || false', false],
|
||||
['false or false', false],
|
||||
['true || (1/0)', true],
|
||||
['true or (1/0)', true],
|
||||
['true xor false', true],
|
||||
];
|
||||
}
|
||||
|
||||
public function testEvaluateFails() {
|
||||
$this->expectException(ConstExprEvaluationException::class);
|
||||
$this->expectExceptionMessage('Expression of type Expr_Variable cannot be evaluated');
|
||||
$evaluator = new ConstExprEvaluator();
|
||||
$evaluator->evaluateDirectly(new Expr\Variable('a'));
|
||||
}
|
||||
|
||||
public function testEvaluateFallback() {
|
||||
$evaluator = new ConstExprEvaluator(function(Expr $expr) {
|
||||
if ($expr instanceof Scalar\MagicConst\Line) {
|
||||
return 42;
|
||||
}
|
||||
throw new ConstExprEvaluationException();
|
||||
});
|
||||
$expr = new Expr\BinaryOp\Plus(
|
||||
new Scalar\LNumber(8),
|
||||
new Scalar\MagicConst\Line()
|
||||
);
|
||||
$this->assertSame(50, $evaluator->evaluateDirectly($expr));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideTestEvaluateSilently
|
||||
*/
|
||||
public function testEvaluateSilently($expr, $exception, $msg) {
|
||||
$evaluator = new ConstExprEvaluator();
|
||||
|
||||
try {
|
||||
$evaluator->evaluateSilently($expr);
|
||||
} catch (ConstExprEvaluationException $e) {
|
||||
$this->assertSame(
|
||||
'An error occurred during constant expression evaluation',
|
||||
$e->getMessage()
|
||||
);
|
||||
|
||||
$prev = $e->getPrevious();
|
||||
$this->assertInstanceOf($exception, $prev);
|
||||
$this->assertSame($msg, $prev->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function provideTestEvaluateSilently() {
|
||||
return [
|
||||
[
|
||||
new Expr\BinaryOp\Mod(new Scalar\LNumber(42), new Scalar\LNumber(0)),
|
||||
\Error::class,
|
||||
'Modulo by zero'
|
||||
],
|
||||
[
|
||||
new Expr\BinaryOp\Div(new Scalar\LNumber(42), new Scalar\LNumber(0)),
|
||||
\ErrorException::class,
|
||||
'Division by zero'
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
23
vendor/nikic/php-parser/test/PhpParser/ErrorHandler/CollectingTest.php
vendored
Normal file
23
vendor/nikic/php-parser/test/PhpParser/ErrorHandler/CollectingTest.php
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\ErrorHandler;
|
||||
|
||||
use PhpParser\Error;
|
||||
|
||||
class CollectingTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testHandleError() {
|
||||
$errorHandler = new Collecting();
|
||||
$this->assertFalse($errorHandler->hasErrors());
|
||||
$this->assertEmpty($errorHandler->getErrors());
|
||||
|
||||
$errorHandler->handleError($e1 = new Error('Test 1'));
|
||||
$errorHandler->handleError($e2 = new Error('Test 2'));
|
||||
$this->assertTrue($errorHandler->hasErrors());
|
||||
$this->assertSame([$e1, $e2], $errorHandler->getErrors());
|
||||
|
||||
$errorHandler->clearErrors();
|
||||
$this->assertFalse($errorHandler->hasErrors());
|
||||
$this->assertEmpty($errorHandler->getErrors());
|
||||
}
|
||||
}
|
15
vendor/nikic/php-parser/test/PhpParser/ErrorHandler/ThrowingTest.php
vendored
Normal file
15
vendor/nikic/php-parser/test/PhpParser/ErrorHandler/ThrowingTest.php
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\ErrorHandler;
|
||||
|
||||
use PhpParser\Error;
|
||||
|
||||
class ThrowingTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testHandleError() {
|
||||
$this->expectException(Error::class);
|
||||
$this->expectExceptionMessage('Test');
|
||||
$errorHandler = new Throwing();
|
||||
$errorHandler->handleError(new Error('Test'));
|
||||
}
|
||||
}
|
104
vendor/nikic/php-parser/test/PhpParser/ErrorTest.php
vendored
Normal file
104
vendor/nikic/php-parser/test/PhpParser/ErrorTest.php
vendored
Normal file
|
@ -0,0 +1,104 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser;
|
||||
|
||||
class ErrorTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testConstruct() {
|
||||
$attributes = [
|
||||
'startLine' => 10,
|
||||
'endLine' => 11,
|
||||
];
|
||||
$error = new Error('Some error', $attributes);
|
||||
|
||||
$this->assertSame('Some error', $error->getRawMessage());
|
||||
$this->assertSame($attributes, $error->getAttributes());
|
||||
$this->assertSame(10, $error->getStartLine());
|
||||
$this->assertSame(11, $error->getEndLine());
|
||||
$this->assertSame('Some error on line 10', $error->getMessage());
|
||||
|
||||
return $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testConstruct
|
||||
*/
|
||||
public function testSetMessageAndLine(Error $error) {
|
||||
$error->setRawMessage('Some other error');
|
||||
$this->assertSame('Some other error', $error->getRawMessage());
|
||||
|
||||
$error->setStartLine(15);
|
||||
$this->assertSame(15, $error->getStartLine());
|
||||
$this->assertSame('Some other error on line 15', $error->getMessage());
|
||||
}
|
||||
|
||||
public function testUnknownLine() {
|
||||
$error = new Error('Some error');
|
||||
|
||||
$this->assertSame(-1, $error->getStartLine());
|
||||
$this->assertSame(-1, $error->getEndLine());
|
||||
$this->assertSame('Some error on unknown line', $error->getMessage());
|
||||
}
|
||||
|
||||
/** @dataProvider provideTestColumnInfo */
|
||||
public function testColumnInfo($code, $startPos, $endPos, $startColumn, $endColumn) {
|
||||
$error = new Error('Some error', [
|
||||
'startFilePos' => $startPos,
|
||||
'endFilePos' => $endPos,
|
||||
]);
|
||||
|
||||
$this->assertTrue($error->hasColumnInfo());
|
||||
$this->assertSame($startColumn, $error->getStartColumn($code));
|
||||
$this->assertSame($endColumn, $error->getEndColumn($code));
|
||||
|
||||
}
|
||||
|
||||
public function provideTestColumnInfo() {
|
||||
return [
|
||||
// Error at "bar"
|
||||
["<?php foo bar baz", 10, 12, 11, 13],
|
||||
["<?php\nfoo bar baz", 10, 12, 5, 7],
|
||||
["<?php foo\nbar baz", 10, 12, 1, 3],
|
||||
["<?php foo bar\nbaz", 10, 12, 11, 13],
|
||||
["<?php\r\nfoo bar baz", 11, 13, 5, 7],
|
||||
// Error at "baz"
|
||||
["<?php foo bar baz", 14, 16, 15, 17],
|
||||
["<?php foo bar\nbaz", 14, 16, 1, 3],
|
||||
// Error at string literal
|
||||
["<?php foo 'bar\nbaz' xyz", 10, 18, 11, 4],
|
||||
["<?php\nfoo 'bar\nbaz' xyz", 10, 18, 5, 4],
|
||||
["<?php foo\n'\nbarbaz\n'\nxyz", 10, 19, 1, 1],
|
||||
// Error over full string
|
||||
["<?php", 0, 4, 1, 5],
|
||||
["<?\nphp", 0, 5, 1, 3],
|
||||
];
|
||||
}
|
||||
|
||||
public function testNoColumnInfo() {
|
||||
$error = new Error('Some error', 3);
|
||||
|
||||
$this->assertFalse($error->hasColumnInfo());
|
||||
try {
|
||||
$error->getStartColumn('');
|
||||
$this->fail('Expected RuntimeException');
|
||||
} catch (\RuntimeException $e) {
|
||||
$this->assertSame('Error does not have column information', $e->getMessage());
|
||||
}
|
||||
try {
|
||||
$error->getEndColumn('');
|
||||
$this->fail('Expected RuntimeException');
|
||||
} catch (\RuntimeException $e) {
|
||||
$this->assertSame('Error does not have column information', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function testInvalidPosInfo() {
|
||||
$this->expectException(\RuntimeException::class);
|
||||
$this->expectExceptionMessage('Invalid position information');
|
||||
$error = new Error('Some error', [
|
||||
'startFilePos' => 10,
|
||||
'endFilePos' => 11,
|
||||
]);
|
||||
$error->getStartColumn('code');
|
||||
}
|
||||
}
|
65
vendor/nikic/php-parser/test/PhpParser/Internal/DifferTest.php
vendored
Normal file
65
vendor/nikic/php-parser/test/PhpParser/Internal/DifferTest.php
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Internal;
|
||||
|
||||
class DifferTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
private function formatDiffString(array $diff) {
|
||||
$diffStr = '';
|
||||
foreach ($diff as $diffElem) {
|
||||
switch ($diffElem->type) {
|
||||
case DiffElem::TYPE_KEEP:
|
||||
$diffStr .= $diffElem->old;
|
||||
break;
|
||||
case DiffElem::TYPE_REMOVE:
|
||||
$diffStr .= '-' . $diffElem->old;
|
||||
break;
|
||||
case DiffElem::TYPE_ADD:
|
||||
$diffStr .= '+' . $diffElem->new;
|
||||
break;
|
||||
case DiffElem::TYPE_REPLACE:
|
||||
$diffStr .= '/' . $diffElem->old . $diffElem->new;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $diffStr;
|
||||
}
|
||||
|
||||
/** @dataProvider provideTestDiff */
|
||||
public function testDiff($oldStr, $newStr, $expectedDiffStr) {
|
||||
$differ = new Differ(function($a, $b) { return $a === $b; });
|
||||
$diff = $differ->diff(str_split($oldStr), str_split($newStr));
|
||||
$this->assertSame($expectedDiffStr, $this->formatDiffString($diff));
|
||||
}
|
||||
|
||||
public function provideTestDiff() {
|
||||
return [
|
||||
['abc', 'abc', 'abc'],
|
||||
['abc', 'abcdef', 'abc+d+e+f'],
|
||||
['abcdef', 'abc', 'abc-d-e-f'],
|
||||
['abcdef', 'abcxyzdef', 'abc+x+y+zdef'],
|
||||
['axyzb', 'ab', 'a-x-y-zb'],
|
||||
['abcdef', 'abxyef', 'ab-c-d+x+yef'],
|
||||
['abcdef', 'cdefab', '-a-bcdef+a+b'],
|
||||
];
|
||||
}
|
||||
|
||||
/** @dataProvider provideTestDiffWithReplacements */
|
||||
public function testDiffWithReplacements($oldStr, $newStr, $expectedDiffStr) {
|
||||
$differ = new Differ(function($a, $b) { return $a === $b; });
|
||||
$diff = $differ->diffWithReplacements(str_split($oldStr), str_split($newStr));
|
||||
$this->assertSame($expectedDiffStr, $this->formatDiffString($diff));
|
||||
}
|
||||
|
||||
public function provideTestDiffWithReplacements() {
|
||||
return [
|
||||
['abcde', 'axyze', 'a/bx/cy/dze'],
|
||||
['abcde', 'xbcdy', '/axbcd/ey'],
|
||||
['abcde', 'axye', 'a-b-c-d+x+ye'],
|
||||
['abcde', 'axyzue', 'a-b-c-d+x+y+z+ue'],
|
||||
];
|
||||
}
|
||||
}
|
43
vendor/nikic/php-parser/test/PhpParser/JsonDecoderTest.php
vendored
Normal file
43
vendor/nikic/php-parser/test/PhpParser/JsonDecoderTest.php
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser;
|
||||
|
||||
class JsonDecoderTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testRoundTrip() {
|
||||
$code = <<<'PHP'
|
||||
<?php
|
||||
// comment
|
||||
/** doc comment */
|
||||
function functionName(&$a = 0, $b = 1.0) {
|
||||
echo 'Foo';
|
||||
}
|
||||
PHP;
|
||||
|
||||
$parser = new Parser\Php7(new Lexer());
|
||||
$stmts = $parser->parse($code);
|
||||
$json = json_encode($stmts);
|
||||
|
||||
$jsonDecoder = new JsonDecoder();
|
||||
$decodedStmts = $jsonDecoder->decode($json);
|
||||
$this->assertEquals($stmts, $decodedStmts);
|
||||
}
|
||||
|
||||
/** @dataProvider provideTestDecodingError */
|
||||
public function testDecodingError($json, $expectedMessage) {
|
||||
$jsonDecoder = new JsonDecoder();
|
||||
$this->expectException(\RuntimeException::class);
|
||||
$this->expectExceptionMessage($expectedMessage);
|
||||
$jsonDecoder->decode($json);
|
||||
}
|
||||
|
||||
public function provideTestDecodingError() {
|
||||
return [
|
||||
['???', 'JSON decoding error: Syntax error'],
|
||||
['{"nodeType":123}', 'Node type must be a string'],
|
||||
['{"nodeType":"Name","attributes":123}', 'Attributes must be an array'],
|
||||
['{"nodeType":"Comment"}', 'Comment must have text'],
|
||||
['{"nodeType":"xxx"}', 'Unknown node type "xxx"'],
|
||||
];
|
||||
}
|
||||
}
|
195
vendor/nikic/php-parser/test/PhpParser/Lexer/EmulativeTest.php
vendored
Normal file
195
vendor/nikic/php-parser/test/PhpParser/Lexer/EmulativeTest.php
vendored
Normal file
|
@ -0,0 +1,195 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Lexer;
|
||||
|
||||
use PhpParser\ErrorHandler;
|
||||
use PhpParser\LexerTest;
|
||||
use PhpParser\Parser\Tokens;
|
||||
|
||||
class EmulativeTest extends LexerTest
|
||||
{
|
||||
protected function getLexer(array $options = []) {
|
||||
return new Emulative($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideTestReplaceKeywords
|
||||
*/
|
||||
public function testReplaceKeywords($keyword, $expectedToken) {
|
||||
$lexer = $this->getLexer();
|
||||
$lexer->startLexing('<?php ' . $keyword);
|
||||
|
||||
$this->assertSame($expectedToken, $lexer->getNextToken());
|
||||
$this->assertSame(0, $lexer->getNextToken());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideTestReplaceKeywords
|
||||
*/
|
||||
public function testNoReplaceKeywordsAfterObjectOperator($keyword) {
|
||||
$lexer = $this->getLexer();
|
||||
$lexer->startLexing('<?php ->' . $keyword);
|
||||
|
||||
$this->assertSame(Tokens::T_OBJECT_OPERATOR, $lexer->getNextToken());
|
||||
$this->assertSame(Tokens::T_STRING, $lexer->getNextToken());
|
||||
$this->assertSame(0, $lexer->getNextToken());
|
||||
}
|
||||
|
||||
public function provideTestReplaceKeywords() {
|
||||
return [
|
||||
// PHP 5.5
|
||||
['finally', Tokens::T_FINALLY],
|
||||
['yield', Tokens::T_YIELD],
|
||||
|
||||
// PHP 5.4
|
||||
['callable', Tokens::T_CALLABLE],
|
||||
['insteadof', Tokens::T_INSTEADOF],
|
||||
['trait', Tokens::T_TRAIT],
|
||||
['__TRAIT__', Tokens::T_TRAIT_C],
|
||||
|
||||
// PHP 5.3
|
||||
['__DIR__', Tokens::T_DIR],
|
||||
['goto', Tokens::T_GOTO],
|
||||
['namespace', Tokens::T_NAMESPACE],
|
||||
['__NAMESPACE__', Tokens::T_NS_C],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideTestLexNewFeatures
|
||||
*/
|
||||
public function testLexNewFeatures($code, array $expectedTokens) {
|
||||
$lexer = $this->getLexer();
|
||||
$lexer->startLexing('<?php ' . $code);
|
||||
|
||||
$tokens = [];
|
||||
while (0 !== $token = $lexer->getNextToken($text)) {
|
||||
$tokens[] = [$token, $text];
|
||||
}
|
||||
$this->assertSame($expectedTokens, $tokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideTestLexNewFeatures
|
||||
*/
|
||||
public function testLeaveStuffAloneInStrings($code) {
|
||||
$stringifiedToken = '"' . addcslashes($code, '"\\') . '"';
|
||||
|
||||
$lexer = $this->getLexer();
|
||||
$lexer->startLexing('<?php ' . $stringifiedToken);
|
||||
|
||||
$this->assertSame(Tokens::T_CONSTANT_ENCAPSED_STRING, $lexer->getNextToken($text));
|
||||
$this->assertSame($stringifiedToken, $text);
|
||||
$this->assertSame(0, $lexer->getNextToken());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideTestLexNewFeatures
|
||||
*/
|
||||
public function testErrorAfterEmulation($code) {
|
||||
$errorHandler = new ErrorHandler\Collecting;
|
||||
$lexer = $this->getLexer([]);
|
||||
$lexer->startLexing('<?php ' . $code . "\0", $errorHandler);
|
||||
|
||||
$errors = $errorHandler->getErrors();
|
||||
$this->assertCount(1, $errors);
|
||||
|
||||
$error = $errors[0];
|
||||
$this->assertSame('Unexpected null byte', $error->getRawMessage());
|
||||
|
||||
$attrs = $error->getAttributes();
|
||||
$expPos = strlen('<?php ' . $code);
|
||||
$expLine = 1 + substr_count('<?php ' . $code, "\n");
|
||||
$this->assertSame($expPos, $attrs['startFilePos']);
|
||||
$this->assertSame($expPos, $attrs['endFilePos']);
|
||||
$this->assertSame($expLine, $attrs['startLine']);
|
||||
$this->assertSame($expLine, $attrs['endLine']);
|
||||
}
|
||||
|
||||
public function provideTestLexNewFeatures() {
|
||||
return [
|
||||
// PHP 7.4
|
||||
['??=', [
|
||||
[Tokens::T_COALESCE_EQUAL, '??='],
|
||||
]],
|
||||
['yield from', [
|
||||
[Tokens::T_YIELD_FROM, 'yield from'],
|
||||
]],
|
||||
["yield\r\nfrom", [
|
||||
[Tokens::T_YIELD_FROM, "yield\r\nfrom"],
|
||||
]],
|
||||
['...', [
|
||||
[Tokens::T_ELLIPSIS, '...'],
|
||||
]],
|
||||
['**', [
|
||||
[Tokens::T_POW, '**'],
|
||||
]],
|
||||
['**=', [
|
||||
[Tokens::T_POW_EQUAL, '**='],
|
||||
]],
|
||||
['??', [
|
||||
[Tokens::T_COALESCE, '??'],
|
||||
]],
|
||||
['<=>', [
|
||||
[Tokens::T_SPACESHIP, '<=>'],
|
||||
]],
|
||||
['0b1010110', [
|
||||
[Tokens::T_LNUMBER, '0b1010110'],
|
||||
]],
|
||||
['0b1011010101001010110101010010101011010101010101101011001110111100', [
|
||||
[Tokens::T_DNUMBER, '0b1011010101001010110101010010101011010101010101101011001110111100'],
|
||||
]],
|
||||
['\\', [
|
||||
[Tokens::T_NS_SEPARATOR, '\\'],
|
||||
]],
|
||||
["<<<'NOWDOC'\nNOWDOC;\n", [
|
||||
[Tokens::T_START_HEREDOC, "<<<'NOWDOC'\n"],
|
||||
[Tokens::T_END_HEREDOC, 'NOWDOC'],
|
||||
[ord(';'), ';'],
|
||||
]],
|
||||
["<<<'NOWDOC'\nFoobar\nNOWDOC;\n", [
|
||||
[Tokens::T_START_HEREDOC, "<<<'NOWDOC'\n"],
|
||||
[Tokens::T_ENCAPSED_AND_WHITESPACE, "Foobar\n"],
|
||||
[Tokens::T_END_HEREDOC, 'NOWDOC'],
|
||||
[ord(';'), ';'],
|
||||
]],
|
||||
|
||||
// Flexible heredoc/nowdoc
|
||||
["<<<LABEL\nLABEL,", [
|
||||
[Tokens::T_START_HEREDOC, "<<<LABEL\n"],
|
||||
[Tokens::T_END_HEREDOC, "LABEL"],
|
||||
[ord(','), ','],
|
||||
]],
|
||||
["<<<LABEL\n LABEL,", [
|
||||
[Tokens::T_START_HEREDOC, "<<<LABEL\n"],
|
||||
[Tokens::T_END_HEREDOC, " LABEL"],
|
||||
[ord(','), ','],
|
||||
]],
|
||||
["<<<LABEL\n Foo\n LABEL;", [
|
||||
[Tokens::T_START_HEREDOC, "<<<LABEL\n"],
|
||||
[Tokens::T_ENCAPSED_AND_WHITESPACE, " Foo\n"],
|
||||
[Tokens::T_END_HEREDOC, " LABEL"],
|
||||
[ord(';'), ';'],
|
||||
]],
|
||||
["<<<A\n A,<<<A\n A,", [
|
||||
[Tokens::T_START_HEREDOC, "<<<A\n"],
|
||||
[Tokens::T_END_HEREDOC, " A"],
|
||||
[ord(','), ','],
|
||||
[Tokens::T_START_HEREDOC, "<<<A\n"],
|
||||
[Tokens::T_END_HEREDOC, " A"],
|
||||
[ord(','), ','],
|
||||
]],
|
||||
["<<<LABEL\nLABELNOPE\nLABEL\n", [
|
||||
[Tokens::T_START_HEREDOC, "<<<LABEL\n"],
|
||||
[Tokens::T_ENCAPSED_AND_WHITESPACE, "LABELNOPE\n"],
|
||||
[Tokens::T_END_HEREDOC, "LABEL"],
|
||||
]],
|
||||
// Interpretation changed
|
||||
["<<<LABEL\n LABEL\nLABEL\n", [
|
||||
[Tokens::T_START_HEREDOC, "<<<LABEL\n"],
|
||||
[Tokens::T_END_HEREDOC, " LABEL"],
|
||||
[Tokens::T_STRING, "LABEL"],
|
||||
]],
|
||||
];
|
||||
}
|
||||
}
|
263
vendor/nikic/php-parser/test/PhpParser/LexerTest.php
vendored
Normal file
263
vendor/nikic/php-parser/test/PhpParser/LexerTest.php
vendored
Normal file
|
@ -0,0 +1,263 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser;
|
||||
|
||||
use PhpParser\Parser\Tokens;
|
||||
|
||||
class LexerTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/* To allow overwriting in parent class */
|
||||
protected function getLexer(array $options = []) {
|
||||
return new Lexer($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideTestError
|
||||
*/
|
||||
public function testError($code, $messages) {
|
||||
if (defined('HHVM_VERSION')) {
|
||||
$this->markTestSkipped('HHVM does not throw warnings from token_get_all()');
|
||||
}
|
||||
|
||||
$errorHandler = new ErrorHandler\Collecting();
|
||||
$lexer = $this->getLexer(['usedAttributes' => [
|
||||
'comments', 'startLine', 'endLine', 'startFilePos', 'endFilePos'
|
||||
]]);
|
||||
$lexer->startLexing($code, $errorHandler);
|
||||
$errors = $errorHandler->getErrors();
|
||||
|
||||
$this->assertCount(count($messages), $errors);
|
||||
for ($i = 0; $i < count($messages); $i++) {
|
||||
$this->assertSame($messages[$i], $errors[$i]->getMessageWithColumnInfo($code));
|
||||
}
|
||||
}
|
||||
|
||||
public function provideTestError() {
|
||||
return [
|
||||
["<?php /*", ["Unterminated comment from 1:7 to 1:9"]],
|
||||
["<?php \1", ["Unexpected character \"\1\" (ASCII 1) from 1:7 to 1:7"]],
|
||||
["<?php \0", ["Unexpected null byte from 1:7 to 1:7"]],
|
||||
// Error with potentially emulated token
|
||||
["<?php ?? \0", ["Unexpected null byte from 1:10 to 1:10"]],
|
||||
["<?php\n\0\1 foo /* bar", [
|
||||
"Unexpected null byte from 2:1 to 2:1",
|
||||
"Unexpected character \"\1\" (ASCII 1) from 2:2 to 2:2",
|
||||
"Unterminated comment from 2:8 to 2:14"
|
||||
]],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideTestLex
|
||||
*/
|
||||
public function testLex($code, $options, $tokens) {
|
||||
$lexer = $this->getLexer($options);
|
||||
$lexer->startLexing($code);
|
||||
while ($id = $lexer->getNextToken($value, $startAttributes, $endAttributes)) {
|
||||
$token = array_shift($tokens);
|
||||
|
||||
$this->assertSame($token[0], $id);
|
||||
$this->assertSame($token[1], $value);
|
||||
$this->assertEquals($token[2], $startAttributes);
|
||||
$this->assertEquals($token[3], $endAttributes);
|
||||
}
|
||||
}
|
||||
|
||||
public function provideTestLex() {
|
||||
return [
|
||||
// tests conversion of closing PHP tag and drop of whitespace and opening tags
|
||||
[
|
||||
'<?php tokens ?>plaintext',
|
||||
[],
|
||||
[
|
||||
[
|
||||
Tokens::T_STRING, 'tokens',
|
||||
['startLine' => 1], ['endLine' => 1]
|
||||
],
|
||||
[
|
||||
ord(';'), '?>',
|
||||
['startLine' => 1], ['endLine' => 1]
|
||||
],
|
||||
[
|
||||
Tokens::T_INLINE_HTML, 'plaintext',
|
||||
['startLine' => 1, 'hasLeadingNewline' => false],
|
||||
['endLine' => 1]
|
||||
],
|
||||
]
|
||||
],
|
||||
// tests line numbers
|
||||
[
|
||||
'<?php' . "\n" . '$ token /** doc' . "\n" . 'comment */ $',
|
||||
[],
|
||||
[
|
||||
[
|
||||
ord('$'), '$',
|
||||
['startLine' => 2], ['endLine' => 2]
|
||||
],
|
||||
[
|
||||
Tokens::T_STRING, 'token',
|
||||
['startLine' => 2], ['endLine' => 2]
|
||||
],
|
||||
[
|
||||
ord('$'), '$',
|
||||
[
|
||||
'startLine' => 3,
|
||||
'comments' => [
|
||||
new Comment\Doc('/** doc' . "\n" . 'comment */', 2, 14, 5),
|
||||
]
|
||||
],
|
||||
['endLine' => 3]
|
||||
],
|
||||
]
|
||||
],
|
||||
// tests comment extraction
|
||||
[
|
||||
'<?php /* comment */ // comment' . "\n" . '/** docComment 1 *//** docComment 2 */ token',
|
||||
[],
|
||||
[
|
||||
[
|
||||
Tokens::T_STRING, 'token',
|
||||
[
|
||||
'startLine' => 2,
|
||||
'comments' => [
|
||||
new Comment('/* comment */', 1, 6, 1),
|
||||
new Comment('// comment' . "\n", 1, 20, 3),
|
||||
new Comment\Doc('/** docComment 1 */', 2, 31, 4),
|
||||
new Comment\Doc('/** docComment 2 */', 2, 50, 5),
|
||||
],
|
||||
],
|
||||
['endLine' => 2]
|
||||
],
|
||||
]
|
||||
],
|
||||
// tests differing start and end line
|
||||
[
|
||||
'<?php "foo' . "\n" . 'bar"',
|
||||
[],
|
||||
[
|
||||
[
|
||||
Tokens::T_CONSTANT_ENCAPSED_STRING, '"foo' . "\n" . 'bar"',
|
||||
['startLine' => 1], ['endLine' => 2]
|
||||
],
|
||||
]
|
||||
],
|
||||
// tests exact file offsets
|
||||
[
|
||||
'<?php "a";' . "\n" . '// foo' . "\n" . '"b";',
|
||||
['usedAttributes' => ['startFilePos', 'endFilePos']],
|
||||
[
|
||||
[
|
||||
Tokens::T_CONSTANT_ENCAPSED_STRING, '"a"',
|
||||
['startFilePos' => 6], ['endFilePos' => 8]
|
||||
],
|
||||
[
|
||||
ord(';'), ';',
|
||||
['startFilePos' => 9], ['endFilePos' => 9]
|
||||
],
|
||||
[
|
||||
Tokens::T_CONSTANT_ENCAPSED_STRING, '"b"',
|
||||
['startFilePos' => 18], ['endFilePos' => 20]
|
||||
],
|
||||
[
|
||||
ord(';'), ';',
|
||||
['startFilePos' => 21], ['endFilePos' => 21]
|
||||
],
|
||||
]
|
||||
],
|
||||
// tests token offsets
|
||||
[
|
||||
'<?php "a";' . "\n" . '// foo' . "\n" . '"b";',
|
||||
['usedAttributes' => ['startTokenPos', 'endTokenPos']],
|
||||
[
|
||||
[
|
||||
Tokens::T_CONSTANT_ENCAPSED_STRING, '"a"',
|
||||
['startTokenPos' => 1], ['endTokenPos' => 1]
|
||||
],
|
||||
[
|
||||
ord(';'), ';',
|
||||
['startTokenPos' => 2], ['endTokenPos' => 2]
|
||||
],
|
||||
[
|
||||
Tokens::T_CONSTANT_ENCAPSED_STRING, '"b"',
|
||||
['startTokenPos' => 5], ['endTokenPos' => 5]
|
||||
],
|
||||
[
|
||||
ord(';'), ';',
|
||||
['startTokenPos' => 6], ['endTokenPos' => 6]
|
||||
],
|
||||
]
|
||||
],
|
||||
// tests all attributes being disabled
|
||||
[
|
||||
'<?php /* foo */ $bar;',
|
||||
['usedAttributes' => []],
|
||||
[
|
||||
[
|
||||
Tokens::T_VARIABLE, '$bar',
|
||||
[], []
|
||||
],
|
||||
[
|
||||
ord(';'), ';',
|
||||
[], []
|
||||
]
|
||||
]
|
||||
],
|
||||
// tests no tokens
|
||||
[
|
||||
'',
|
||||
[],
|
||||
[]
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideTestHaltCompiler
|
||||
*/
|
||||
public function testHandleHaltCompiler($code, $remaining) {
|
||||
$lexer = $this->getLexer();
|
||||
$lexer->startLexing($code);
|
||||
|
||||
while (Tokens::T_HALT_COMPILER !== $lexer->getNextToken());
|
||||
|
||||
$this->assertSame($remaining, $lexer->handleHaltCompiler());
|
||||
$this->assertSame(0, $lexer->getNextToken());
|
||||
}
|
||||
|
||||
public function provideTestHaltCompiler() {
|
||||
return [
|
||||
['<?php ... __halt_compiler();Remaining Text', 'Remaining Text'],
|
||||
['<?php ... __halt_compiler ( ) ;Remaining Text', 'Remaining Text'],
|
||||
['<?php ... __halt_compiler() ?>Remaining Text', 'Remaining Text'],
|
||||
//array('<?php ... __halt_compiler();' . "\0", "\0"),
|
||||
//array('<?php ... __halt_compiler /* */ ( ) ;Remaining Text', 'Remaining Text'),
|
||||
];
|
||||
}
|
||||
|
||||
public function testHandleHaltCompilerError() {
|
||||
$this->expectException(Error::class);
|
||||
$this->expectExceptionMessage('__HALT_COMPILER must be followed by "();"');
|
||||
$lexer = $this->getLexer();
|
||||
$lexer->startLexing('<?php ... __halt_compiler invalid ();');
|
||||
|
||||
while (Tokens::T_HALT_COMPILER !== $lexer->getNextToken());
|
||||
$lexer->handleHaltCompiler();
|
||||
}
|
||||
|
||||
public function testGetTokens() {
|
||||
$code = '<?php "a";' . "\n" . '// foo' . "\n" . '"b";';
|
||||
$expectedTokens = [
|
||||
[T_OPEN_TAG, '<?php ', 1],
|
||||
[T_CONSTANT_ENCAPSED_STRING, '"a"', 1],
|
||||
';',
|
||||
[T_WHITESPACE, "\n", 1],
|
||||
[T_COMMENT, '// foo' . "\n", 2],
|
||||
[T_CONSTANT_ENCAPSED_STRING, '"b"', 3],
|
||||
';',
|
||||
];
|
||||
|
||||
$lexer = $this->getLexer();
|
||||
$lexer->startLexing($code);
|
||||
$this->assertSame($expectedTokens, $lexer->getTokens());
|
||||
}
|
||||
}
|
65
vendor/nikic/php-parser/test/PhpParser/NameContextTest.php
vendored
Normal file
65
vendor/nikic/php-parser/test/PhpParser/NameContextTest.php
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser;
|
||||
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Stmt\Use_;
|
||||
|
||||
class NameContextTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideTestGetPossibleNames
|
||||
*/
|
||||
public function testGetPossibleNames($type, $name, $expectedPossibleNames) {
|
||||
$nameContext = new NameContext(new ErrorHandler\Throwing());
|
||||
$nameContext->startNamespace(new Name('NS'));
|
||||
$nameContext->addAlias(new Name('Foo'), 'Foo', Use_::TYPE_NORMAL);
|
||||
$nameContext->addAlias(new Name('Foo\Bar'), 'Alias', Use_::TYPE_NORMAL);
|
||||
$nameContext->addAlias(new Name('Foo\fn'), 'fn', Use_::TYPE_FUNCTION);
|
||||
$nameContext->addAlias(new Name('Foo\CN'), 'CN', Use_::TYPE_CONSTANT);
|
||||
|
||||
$possibleNames = $nameContext->getPossibleNames($name, $type);
|
||||
$possibleNames = array_map(function (Name $name) {
|
||||
return $name->toCodeString();
|
||||
}, $possibleNames);
|
||||
|
||||
$this->assertSame($expectedPossibleNames, $possibleNames);
|
||||
|
||||
// Here the last name is always the shortest one
|
||||
$expectedShortName = $expectedPossibleNames[count($expectedPossibleNames) - 1];
|
||||
$this->assertSame(
|
||||
$expectedShortName,
|
||||
$nameContext->getShortName($name, $type)->toCodeString()
|
||||
);
|
||||
}
|
||||
|
||||
public function provideTestGetPossibleNames() {
|
||||
return [
|
||||
[Use_::TYPE_NORMAL, 'Test', ['\Test']],
|
||||
[Use_::TYPE_NORMAL, 'Test\Namespaced', ['\Test\Namespaced']],
|
||||
[Use_::TYPE_NORMAL, 'NS\Test', ['\NS\Test', 'Test']],
|
||||
[Use_::TYPE_NORMAL, 'ns\Test', ['\ns\Test', 'Test']],
|
||||
[Use_::TYPE_NORMAL, 'NS\Foo\Bar', ['\NS\Foo\Bar']],
|
||||
[Use_::TYPE_NORMAL, 'ns\foo\Bar', ['\ns\foo\Bar']],
|
||||
[Use_::TYPE_NORMAL, 'Foo', ['\Foo', 'Foo']],
|
||||
[Use_::TYPE_NORMAL, 'Foo\Bar', ['\Foo\Bar', 'Foo\Bar', 'Alias']],
|
||||
[Use_::TYPE_NORMAL, 'Foo\Bar\Baz', ['\Foo\Bar\Baz', 'Foo\Bar\Baz', 'Alias\Baz']],
|
||||
[Use_::TYPE_NORMAL, 'Foo\fn\Bar', ['\Foo\fn\Bar', 'Foo\fn\Bar']],
|
||||
[Use_::TYPE_FUNCTION, 'Foo\fn\bar', ['\Foo\fn\bar', 'Foo\fn\bar']],
|
||||
[Use_::TYPE_FUNCTION, 'Foo\fn', ['\Foo\fn', 'Foo\fn', 'fn']],
|
||||
[Use_::TYPE_FUNCTION, 'Foo\FN', ['\Foo\FN', 'Foo\FN', 'fn']],
|
||||
[Use_::TYPE_CONSTANT, 'Foo\CN\BAR', ['\Foo\CN\BAR', 'Foo\CN\BAR']],
|
||||
[Use_::TYPE_CONSTANT, 'Foo\CN', ['\Foo\CN', 'Foo\CN', 'CN']],
|
||||
[Use_::TYPE_CONSTANT, 'foo\CN', ['\foo\CN', 'Foo\CN', 'CN']],
|
||||
[Use_::TYPE_CONSTANT, 'foo\cn', ['\foo\cn', 'Foo\cn']],
|
||||
// self/parent/static must not be fully qualified
|
||||
[Use_::TYPE_NORMAL, 'self', ['self']],
|
||||
[Use_::TYPE_NORMAL, 'parent', ['parent']],
|
||||
[Use_::TYPE_NORMAL, 'static', ['static']],
|
||||
// true/false/null do not need to be fully qualified, even in namespaces
|
||||
[Use_::TYPE_CONSTANT, 'true', ['\true', 'true']],
|
||||
[Use_::TYPE_CONSTANT, 'false', ['\false', 'false']],
|
||||
[Use_::TYPE_CONSTANT, 'null', ['\null', 'null']],
|
||||
];
|
||||
}
|
||||
}
|
29
vendor/nikic/php-parser/test/PhpParser/Node/IdentifierTest.php
vendored
Normal file
29
vendor/nikic/php-parser/test/PhpParser/Node/IdentifierTest.php
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Node;
|
||||
|
||||
class IdentifierTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testToString() {
|
||||
$identifier = new Identifier('Foo');
|
||||
|
||||
$this->assertSame('Foo', (string) $identifier);
|
||||
$this->assertSame('Foo', $identifier->toString());
|
||||
$this->assertSame('foo', $identifier->toLowerString());
|
||||
}
|
||||
|
||||
/** @dataProvider provideTestIsSpecialClassName */
|
||||
public function testIsSpecialClassName($identifier, $expected) {
|
||||
$identifier = new Identifier($identifier);
|
||||
$this->assertSame($expected, $identifier->isSpecialClassName());
|
||||
}
|
||||
|
||||
public function provideTestIsSpecialClassName() {
|
||||
return [
|
||||
['self', true],
|
||||
['PARENT', true],
|
||||
['Static', true],
|
||||
['other', false],
|
||||
];
|
||||
}
|
||||
}
|
157
vendor/nikic/php-parser/test/PhpParser/Node/NameTest.php
vendored
Normal file
157
vendor/nikic/php-parser/test/PhpParser/Node/NameTest.php
vendored
Normal file
|
@ -0,0 +1,157 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Node;
|
||||
|
||||
class NameTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testConstruct() {
|
||||
$name = new Name(['foo', 'bar']);
|
||||
$this->assertSame(['foo', 'bar'], $name->parts);
|
||||
|
||||
$name = new Name('foo\bar');
|
||||
$this->assertSame(['foo', 'bar'], $name->parts);
|
||||
|
||||
$name = new Name($name);
|
||||
$this->assertSame(['foo', 'bar'], $name->parts);
|
||||
}
|
||||
|
||||
public function testGet() {
|
||||
$name = new Name('foo');
|
||||
$this->assertSame('foo', $name->getFirst());
|
||||
$this->assertSame('foo', $name->getLast());
|
||||
|
||||
$name = new Name('foo\bar');
|
||||
$this->assertSame('foo', $name->getFirst());
|
||||
$this->assertSame('bar', $name->getLast());
|
||||
}
|
||||
|
||||
public function testToString() {
|
||||
$name = new Name('Foo\Bar');
|
||||
|
||||
$this->assertSame('Foo\Bar', (string) $name);
|
||||
$this->assertSame('Foo\Bar', $name->toString());
|
||||
$this->assertSame('foo\bar', $name->toLowerString());
|
||||
}
|
||||
|
||||
public function testSlice() {
|
||||
$name = new Name('foo\bar\baz');
|
||||
$this->assertEquals(new Name('foo\bar\baz'), $name->slice(0));
|
||||
$this->assertEquals(new Name('bar\baz'), $name->slice(1));
|
||||
$this->assertNull($name->slice(3));
|
||||
$this->assertEquals(new Name('foo\bar\baz'), $name->slice(-3));
|
||||
$this->assertEquals(new Name('bar\baz'), $name->slice(-2));
|
||||
$this->assertEquals(new Name('foo\bar'), $name->slice(0, -1));
|
||||
$this->assertNull($name->slice(0, -3));
|
||||
$this->assertEquals(new Name('bar'), $name->slice(1, -1));
|
||||
$this->assertNull($name->slice(1, -2));
|
||||
$this->assertEquals(new Name('bar'), $name->slice(-2, 1));
|
||||
$this->assertEquals(new Name('bar'), $name->slice(-2, -1));
|
||||
$this->assertNull($name->slice(-2, -2));
|
||||
}
|
||||
|
||||
public function testSliceOffsetTooLarge() {
|
||||
$this->expectException(\OutOfBoundsException::class);
|
||||
$this->expectExceptionMessage('Offset 4 is out of bounds');
|
||||
(new Name('foo\bar\baz'))->slice(4);
|
||||
}
|
||||
|
||||
public function testSliceOffsetTooSmall() {
|
||||
$this->expectException(\OutOfBoundsException::class);
|
||||
$this->expectExceptionMessage('Offset -4 is out of bounds');
|
||||
(new Name('foo\bar\baz'))->slice(-4);
|
||||
}
|
||||
|
||||
public function testSliceLengthTooLarge() {
|
||||
$this->expectException(\OutOfBoundsException::class);
|
||||
$this->expectExceptionMessage('Length 4 is out of bounds');
|
||||
(new Name('foo\bar\baz'))->slice(0, 4);
|
||||
}
|
||||
|
||||
public function testSliceLengthTooSmall() {
|
||||
$this->expectException(\OutOfBoundsException::class);
|
||||
$this->expectExceptionMessage('Length -4 is out of bounds');
|
||||
(new Name('foo\bar\baz'))->slice(0, -4);
|
||||
}
|
||||
|
||||
public function testConcat() {
|
||||
$this->assertEquals(new Name('foo\bar\baz'), Name::concat('foo', 'bar\baz'));
|
||||
$this->assertEquals(
|
||||
new Name\FullyQualified('foo\bar'),
|
||||
Name\FullyQualified::concat(['foo'], new Name('bar'))
|
||||
);
|
||||
|
||||
$attributes = ['foo' => 'bar'];
|
||||
$this->assertEquals(
|
||||
new Name\Relative('foo\bar\baz', $attributes),
|
||||
Name\Relative::concat(new Name\FullyQualified('foo\bar'), 'baz', $attributes)
|
||||
);
|
||||
|
||||
$this->assertEquals(new Name('foo'), Name::concat(null, 'foo'));
|
||||
$this->assertEquals(new Name('foo'), Name::concat('foo', null));
|
||||
$this->assertNull(Name::concat(null, null));
|
||||
}
|
||||
|
||||
public function testNameTypes() {
|
||||
$name = new Name('foo');
|
||||
$this->assertTrue($name->isUnqualified());
|
||||
$this->assertFalse($name->isQualified());
|
||||
$this->assertFalse($name->isFullyQualified());
|
||||
$this->assertFalse($name->isRelative());
|
||||
$this->assertSame('foo', $name->toCodeString());
|
||||
|
||||
$name = new Name('foo\bar');
|
||||
$this->assertFalse($name->isUnqualified());
|
||||
$this->assertTrue($name->isQualified());
|
||||
$this->assertFalse($name->isFullyQualified());
|
||||
$this->assertFalse($name->isRelative());
|
||||
$this->assertSame('foo\bar', $name->toCodeString());
|
||||
|
||||
$name = new Name\FullyQualified('foo');
|
||||
$this->assertFalse($name->isUnqualified());
|
||||
$this->assertFalse($name->isQualified());
|
||||
$this->assertTrue($name->isFullyQualified());
|
||||
$this->assertFalse($name->isRelative());
|
||||
$this->assertSame('\foo', $name->toCodeString());
|
||||
|
||||
$name = new Name\Relative('foo');
|
||||
$this->assertFalse($name->isUnqualified());
|
||||
$this->assertFalse($name->isQualified());
|
||||
$this->assertFalse($name->isFullyQualified());
|
||||
$this->assertTrue($name->isRelative());
|
||||
$this->assertSame('namespace\foo', $name->toCodeString());
|
||||
}
|
||||
|
||||
public function testInvalidArg() {
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Expected string, array of parts or Name instance');
|
||||
Name::concat('foo', new \stdClass);
|
||||
}
|
||||
|
||||
public function testInvalidEmptyString() {
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Name cannot be empty');
|
||||
new Name('');
|
||||
}
|
||||
|
||||
public function testInvalidEmptyArray() {
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Name cannot be empty');
|
||||
new Name([]);
|
||||
}
|
||||
|
||||
/** @dataProvider provideTestIsSpecialClassName */
|
||||
public function testIsSpecialClassName($name, $expected) {
|
||||
$name = new Name($name);
|
||||
$this->assertSame($expected, $name->isSpecialClassName());
|
||||
}
|
||||
|
||||
public function provideTestIsSpecialClassName() {
|
||||
return [
|
||||
['self', true],
|
||||
['PARENT', true],
|
||||
['Static', true],
|
||||
['self\not', false],
|
||||
['not\self', false],
|
||||
];
|
||||
}
|
||||
}
|
26
vendor/nikic/php-parser/test/PhpParser/Node/Scalar/MagicConstTest.php
vendored
Normal file
26
vendor/nikic/php-parser/test/PhpParser/Node/Scalar/MagicConstTest.php
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Node\Scalar;
|
||||
|
||||
class MagicConstTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideTestGetName
|
||||
*/
|
||||
public function testGetName(MagicConst $magicConst, $name) {
|
||||
$this->assertSame($name, $magicConst->getName());
|
||||
}
|
||||
|
||||
public function provideTestGetName() {
|
||||
return [
|
||||
[new MagicConst\Class_, '__CLASS__'],
|
||||
[new MagicConst\Dir, '__DIR__'],
|
||||
[new MagicConst\File, '__FILE__'],
|
||||
[new MagicConst\Function_, '__FUNCTION__'],
|
||||
[new MagicConst\Line, '__LINE__'],
|
||||
[new MagicConst\Method, '__METHOD__'],
|
||||
[new MagicConst\Namespace_, '__NAMESPACE__'],
|
||||
[new MagicConst\Trait_, '__TRAIT__'],
|
||||
];
|
||||
}
|
||||
}
|
61
vendor/nikic/php-parser/test/PhpParser/Node/Scalar/StringTest.php
vendored
Normal file
61
vendor/nikic/php-parser/test/PhpParser/Node/Scalar/StringTest.php
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Node\Scalar;
|
||||
|
||||
class StringTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideTestParseEscapeSequences
|
||||
*/
|
||||
public function testParseEscapeSequences($expected, $string, $quote) {
|
||||
$this->assertSame(
|
||||
$expected,
|
||||
String_::parseEscapeSequences($string, $quote)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideTestParse
|
||||
*/
|
||||
public function testCreate($expected, $string) {
|
||||
$this->assertSame(
|
||||
$expected,
|
||||
String_::parse($string)
|
||||
);
|
||||
}
|
||||
|
||||
public function provideTestParseEscapeSequences() {
|
||||
return [
|
||||
['"', '\\"', '"'],
|
||||
['\\"', '\\"', '`'],
|
||||
['\\"\\`', '\\"\\`', null],
|
||||
["\\\$\n\r\t\f\v", '\\\\\$\n\r\t\f\v', null],
|
||||
["\x1B", '\e', null],
|
||||
[chr(255), '\xFF', null],
|
||||
[chr(255), '\377', null],
|
||||
[chr(0), '\400', null],
|
||||
["\0", '\0', null],
|
||||
['\xFF', '\\\\xFF', null],
|
||||
];
|
||||
}
|
||||
|
||||
public function provideTestParse() {
|
||||
$tests = [
|
||||
['A', '\'A\''],
|
||||
['A', 'b\'A\''],
|
||||
['A', '"A"'],
|
||||
['A', 'b"A"'],
|
||||
['\\', '\'\\\\\''],
|
||||
['\'', '\'\\\'\''],
|
||||
];
|
||||
|
||||
foreach ($this->provideTestParseEscapeSequences() as $i => $test) {
|
||||
// skip second and third tests, they aren't for double quotes
|
||||
if ($i !== 1 && $i !== 2) {
|
||||
$tests[] = [$test[0], '"' . $test[1] . '"'];
|
||||
}
|
||||
}
|
||||
|
||||
return $tests;
|
||||
}
|
||||
}
|
34
vendor/nikic/php-parser/test/PhpParser/Node/Stmt/ClassConstTest.php
vendored
Normal file
34
vendor/nikic/php-parser/test/PhpParser/Node/Stmt/ClassConstTest.php
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Node\Stmt;
|
||||
|
||||
class ClassConstTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideModifiers
|
||||
*/
|
||||
public function testModifiers($modifier) {
|
||||
$node = new ClassConst(
|
||||
[], // invalid
|
||||
constant('PhpParser\Node\Stmt\Class_::MODIFIER_' . strtoupper($modifier))
|
||||
);
|
||||
|
||||
$this->assertTrue($node->{'is' . $modifier}());
|
||||
}
|
||||
|
||||
public function testNoModifiers() {
|
||||
$node = new ClassConst([], 0);
|
||||
|
||||
$this->assertTrue($node->isPublic());
|
||||
$this->assertFalse($node->isProtected());
|
||||
$this->assertFalse($node->isPrivate());
|
||||
}
|
||||
|
||||
public function provideModifiers() {
|
||||
return [
|
||||
['public'],
|
||||
['protected'],
|
||||
['private'],
|
||||
];
|
||||
}
|
||||
}
|
123
vendor/nikic/php-parser/test/PhpParser/Node/Stmt/ClassMethodTest.php
vendored
Normal file
123
vendor/nikic/php-parser/test/PhpParser/Node/Stmt/ClassMethodTest.php
vendored
Normal file
|
@ -0,0 +1,123 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Node\Stmt;
|
||||
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Param;
|
||||
|
||||
class ClassMethodTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideModifiers
|
||||
*/
|
||||
public function testModifiers($modifier) {
|
||||
$node = new ClassMethod('foo', [
|
||||
'type' => constant('PhpParser\Node\Stmt\Class_::MODIFIER_' . strtoupper($modifier))
|
||||
]);
|
||||
|
||||
$this->assertTrue($node->{'is' . $modifier}());
|
||||
}
|
||||
|
||||
public function testNoModifiers() {
|
||||
$node = new ClassMethod('foo', ['type' => 0]);
|
||||
|
||||
$this->assertTrue($node->isPublic());
|
||||
$this->assertFalse($node->isProtected());
|
||||
$this->assertFalse($node->isPrivate());
|
||||
$this->assertFalse($node->isAbstract());
|
||||
$this->assertFalse($node->isFinal());
|
||||
$this->assertFalse($node->isStatic());
|
||||
$this->assertFalse($node->isMagic());
|
||||
}
|
||||
|
||||
public function provideModifiers() {
|
||||
return [
|
||||
['public'],
|
||||
['protected'],
|
||||
['private'],
|
||||
['abstract'],
|
||||
['final'],
|
||||
['static'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that implicit public modifier detection for method is working
|
||||
*
|
||||
* @dataProvider implicitPublicModifiers
|
||||
*
|
||||
* @param string $modifier Node type modifier
|
||||
*/
|
||||
public function testImplicitPublic(string $modifier)
|
||||
{
|
||||
$node = new ClassMethod('foo', [
|
||||
'type' => constant('PhpParser\Node\Stmt\Class_::MODIFIER_' . strtoupper($modifier))
|
||||
]);
|
||||
|
||||
$this->assertTrue($node->isPublic(), 'Node should be implicitly public');
|
||||
}
|
||||
|
||||
public function implicitPublicModifiers() {
|
||||
return [
|
||||
['abstract'],
|
||||
['final'],
|
||||
['static'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideMagics
|
||||
*
|
||||
* @param string $name Node name
|
||||
*/
|
||||
public function testMagic(string $name) {
|
||||
$node = new ClassMethod($name);
|
||||
$this->assertTrue($node->isMagic(), 'Method should be magic');
|
||||
}
|
||||
|
||||
public function provideMagics() {
|
||||
return [
|
||||
['__construct'],
|
||||
['__DESTRUCT'],
|
||||
['__caLL'],
|
||||
['__callstatic'],
|
||||
['__get'],
|
||||
['__set'],
|
||||
['__isset'],
|
||||
['__unset'],
|
||||
['__sleep'],
|
||||
['__wakeup'],
|
||||
['__tostring'],
|
||||
['__set_state'],
|
||||
['__clone'],
|
||||
['__invoke'],
|
||||
['__debuginfo'],
|
||||
];
|
||||
}
|
||||
|
||||
public function testFunctionLike() {
|
||||
$param = new Param(new Variable('a'));
|
||||
$type = new Name('Foo');
|
||||
$return = new Return_(new Variable('a'));
|
||||
$method = new ClassMethod('test', [
|
||||
'byRef' => false,
|
||||
'params' => [$param],
|
||||
'returnType' => $type,
|
||||
'stmts' => [$return],
|
||||
]);
|
||||
|
||||
$this->assertFalse($method->returnsByRef());
|
||||
$this->assertSame([$param], $method->getParams());
|
||||
$this->assertSame($type, $method->getReturnType());
|
||||
$this->assertSame([$return], $method->getStmts());
|
||||
|
||||
$method = new ClassMethod('test', [
|
||||
'byRef' => true,
|
||||
'stmts' => null,
|
||||
]);
|
||||
|
||||
$this->assertTrue($method->returnsByRef());
|
||||
$this->assertNull($method->getStmts());
|
||||
}
|
||||
}
|
59
vendor/nikic/php-parser/test/PhpParser/Node/Stmt/ClassTest.php
vendored
Normal file
59
vendor/nikic/php-parser/test/PhpParser/Node/Stmt/ClassTest.php
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Node\Stmt;
|
||||
|
||||
class ClassTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testIsAbstract() {
|
||||
$class = new Class_('Foo', ['type' => Class_::MODIFIER_ABSTRACT]);
|
||||
$this->assertTrue($class->isAbstract());
|
||||
|
||||
$class = new Class_('Foo');
|
||||
$this->assertFalse($class->isAbstract());
|
||||
}
|
||||
|
||||
public function testIsFinal() {
|
||||
$class = new Class_('Foo', ['type' => Class_::MODIFIER_FINAL]);
|
||||
$this->assertTrue($class->isFinal());
|
||||
|
||||
$class = new Class_('Foo');
|
||||
$this->assertFalse($class->isFinal());
|
||||
}
|
||||
|
||||
public function testGetMethods() {
|
||||
$methods = [
|
||||
new ClassMethod('foo'),
|
||||
new ClassMethod('bar'),
|
||||
new ClassMethod('fooBar'),
|
||||
];
|
||||
$class = new Class_('Foo', [
|
||||
'stmts' => [
|
||||
new TraitUse([]),
|
||||
$methods[0],
|
||||
new ClassConst([]),
|
||||
$methods[1],
|
||||
new Property(0, []),
|
||||
$methods[2],
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertSame($methods, $class->getMethods());
|
||||
}
|
||||
|
||||
public function testGetMethod() {
|
||||
$methodConstruct = new ClassMethod('__CONSTRUCT');
|
||||
$methodTest = new ClassMethod('test');
|
||||
$class = new Class_('Foo', [
|
||||
'stmts' => [
|
||||
new ClassConst([]),
|
||||
$methodConstruct,
|
||||
new Property(0, []),
|
||||
$methodTest,
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertSame($methodConstruct, $class->getMethod('__construct'));
|
||||
$this->assertSame($methodTest, $class->getMethod('test'));
|
||||
$this->assertNull($class->getMethod('nonExisting'));
|
||||
}
|
||||
}
|
26
vendor/nikic/php-parser/test/PhpParser/Node/Stmt/InterfaceTest.php
vendored
Normal file
26
vendor/nikic/php-parser/test/PhpParser/Node/Stmt/InterfaceTest.php
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Node\Stmt;
|
||||
|
||||
use PhpParser\Node;
|
||||
|
||||
class InterfaceTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testGetMethods() {
|
||||
$methods = [
|
||||
new ClassMethod('foo'),
|
||||
new ClassMethod('bar'),
|
||||
];
|
||||
$interface = new Class_('Foo', [
|
||||
'stmts' => [
|
||||
new Node\Stmt\ClassConst([new Node\Const_('C1', new Node\Scalar\String_('C1'))]),
|
||||
$methods[0],
|
||||
new Node\Stmt\ClassConst([new Node\Const_('C2', new Node\Scalar\String_('C2'))]),
|
||||
$methods[1],
|
||||
new Node\Stmt\ClassConst([new Node\Const_('C3', new Node\Scalar\String_('C3'))]),
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertSame($methods, $interface->getMethods());
|
||||
}
|
||||
}
|
44
vendor/nikic/php-parser/test/PhpParser/Node/Stmt/PropertyTest.php
vendored
Normal file
44
vendor/nikic/php-parser/test/PhpParser/Node/Stmt/PropertyTest.php
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Node\Stmt;
|
||||
|
||||
class PropertyTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideModifiers
|
||||
*/
|
||||
public function testModifiers($modifier) {
|
||||
$node = new Property(
|
||||
constant('PhpParser\Node\Stmt\Class_::MODIFIER_' . strtoupper($modifier)),
|
||||
[] // invalid
|
||||
);
|
||||
|
||||
$this->assertTrue($node->{'is' . $modifier}());
|
||||
}
|
||||
|
||||
public function testNoModifiers() {
|
||||
$node = new Property(0, []);
|
||||
|
||||
$this->assertTrue($node->isPublic());
|
||||
$this->assertFalse($node->isProtected());
|
||||
$this->assertFalse($node->isPrivate());
|
||||
$this->assertFalse($node->isStatic());
|
||||
}
|
||||
|
||||
public function testStaticImplicitlyPublic() {
|
||||
$node = new Property(Class_::MODIFIER_STATIC, []);
|
||||
$this->assertTrue($node->isPublic());
|
||||
$this->assertFalse($node->isProtected());
|
||||
$this->assertFalse($node->isPrivate());
|
||||
$this->assertTrue($node->isStatic());
|
||||
}
|
||||
|
||||
public function provideModifiers() {
|
||||
return [
|
||||
['public'],
|
||||
['protected'],
|
||||
['private'],
|
||||
['static'],
|
||||
];
|
||||
}
|
||||
}
|
325
vendor/nikic/php-parser/test/PhpParser/NodeAbstractTest.php
vendored
Normal file
325
vendor/nikic/php-parser/test/PhpParser/NodeAbstractTest.php
vendored
Normal file
|
@ -0,0 +1,325 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser;
|
||||
|
||||
class DummyNode extends NodeAbstract
|
||||
{
|
||||
public $subNode1;
|
||||
public $subNode2;
|
||||
|
||||
public function __construct($subNode1, $subNode2, $attributes) {
|
||||
parent::__construct($attributes);
|
||||
$this->subNode1 = $subNode1;
|
||||
$this->subNode2 = $subNode2;
|
||||
}
|
||||
|
||||
public function getSubNodeNames() : array {
|
||||
return ['subNode1', 'subNode2'];
|
||||
}
|
||||
|
||||
// This method is only overwritten because the node is located in an unusual namespace
|
||||
public function getType() : string {
|
||||
return 'Dummy';
|
||||
}
|
||||
}
|
||||
|
||||
class NodeAbstractTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function provideNodes() {
|
||||
$attributes = [
|
||||
'startLine' => 10,
|
||||
'endLine' => 11,
|
||||
'startTokenPos' => 12,
|
||||
'endTokenPos' => 13,
|
||||
'startFilePos' => 14,
|
||||
'endFilePos' => 15,
|
||||
'comments' => [
|
||||
new Comment('// Comment' . "\n"),
|
||||
new Comment\Doc('/** doc comment */'),
|
||||
],
|
||||
];
|
||||
|
||||
$node = new DummyNode('value1', 'value2', $attributes);
|
||||
$node->notSubNode = 'value3';
|
||||
|
||||
return [
|
||||
[$attributes, $node],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideNodes
|
||||
*/
|
||||
public function testConstruct(array $attributes, Node $node) {
|
||||
$this->assertSame('Dummy', $node->getType());
|
||||
$this->assertSame(['subNode1', 'subNode2'], $node->getSubNodeNames());
|
||||
$this->assertSame(10, $node->getLine());
|
||||
$this->assertSame(10, $node->getStartLine());
|
||||
$this->assertSame(11, $node->getEndLine());
|
||||
$this->assertSame(12, $node->getStartTokenPos());
|
||||
$this->assertSame(13, $node->getEndTokenPos());
|
||||
$this->assertSame(14, $node->getStartFilePos());
|
||||
$this->assertSame(15, $node->getEndFilePos());
|
||||
$this->assertSame('/** doc comment */', $node->getDocComment()->getText());
|
||||
$this->assertSame('value1', $node->subNode1);
|
||||
$this->assertSame('value2', $node->subNode2);
|
||||
$this->assertObjectHasAttribute('subNode1', $node);
|
||||
$this->assertObjectHasAttribute('subNode2', $node);
|
||||
$this->assertObjectNotHasAttribute('subNode3', $node);
|
||||
$this->assertSame($attributes, $node->getAttributes());
|
||||
$this->assertSame($attributes['comments'], $node->getComments());
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideNodes
|
||||
*/
|
||||
public function testGetDocComment(array $attributes, Node $node) {
|
||||
$this->assertSame('/** doc comment */', $node->getDocComment()->getText());
|
||||
$comments = $node->getComments();
|
||||
|
||||
array_pop($comments); // remove doc comment
|
||||
$node->setAttribute('comments', $comments);
|
||||
$this->assertNull($node->getDocComment());
|
||||
|
||||
array_pop($comments); // remove comment
|
||||
$node->setAttribute('comments', $comments);
|
||||
$this->assertNull($node->getDocComment());
|
||||
}
|
||||
|
||||
public function testSetDocComment() {
|
||||
$node = new DummyNode(null, null, []);
|
||||
|
||||
// Add doc comment to node without comments
|
||||
$docComment = new Comment\Doc('/** doc */');
|
||||
$node->setDocComment($docComment);
|
||||
$this->assertSame($docComment, $node->getDocComment());
|
||||
|
||||
// Replace it
|
||||
$docComment = new Comment\Doc('/** doc 2 */');
|
||||
$node->setDocComment($docComment);
|
||||
$this->assertSame($docComment, $node->getDocComment());
|
||||
|
||||
// Add docmment to node with other comments
|
||||
$c1 = new Comment('/* foo */');
|
||||
$c2 = new Comment('/* bar */');
|
||||
$docComment = new Comment\Doc('/** baz */');
|
||||
$node->setAttribute('comments', [$c1, $c2]);
|
||||
$node->setDocComment($docComment);
|
||||
$this->assertSame([$c1, $c2, $docComment], $node->getAttribute('comments'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideNodes
|
||||
*/
|
||||
public function testChange(array $attributes, Node $node) {
|
||||
// direct modification
|
||||
$node->subNode = 'newValue';
|
||||
$this->assertSame('newValue', $node->subNode);
|
||||
|
||||
// indirect modification
|
||||
$subNode =& $node->subNode;
|
||||
$subNode = 'newNewValue';
|
||||
$this->assertSame('newNewValue', $node->subNode);
|
||||
|
||||
// removal
|
||||
unset($node->subNode);
|
||||
$this->assertObjectNotHasAttribute('subNode', $node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideNodes
|
||||
*/
|
||||
public function testIteration(array $attributes, Node $node) {
|
||||
// Iteration is simple object iteration over properties,
|
||||
// not over subnodes
|
||||
$i = 0;
|
||||
foreach ($node as $key => $value) {
|
||||
if ($i === 0) {
|
||||
$this->assertSame('subNode1', $key);
|
||||
$this->assertSame('value1', $value);
|
||||
} elseif ($i === 1) {
|
||||
$this->assertSame('subNode2', $key);
|
||||
$this->assertSame('value2', $value);
|
||||
} elseif ($i === 2) {
|
||||
$this->assertSame('notSubNode', $key);
|
||||
$this->assertSame('value3', $value);
|
||||
} else {
|
||||
throw new \Exception;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
$this->assertSame(3, $i);
|
||||
}
|
||||
|
||||
public function testAttributes() {
|
||||
/** @var $node Node */
|
||||
$node = $this->getMockForAbstractClass(NodeAbstract::class);
|
||||
|
||||
$this->assertEmpty($node->getAttributes());
|
||||
|
||||
$node->setAttribute('key', 'value');
|
||||
$this->assertTrue($node->hasAttribute('key'));
|
||||
$this->assertSame('value', $node->getAttribute('key'));
|
||||
|
||||
$this->assertFalse($node->hasAttribute('doesNotExist'));
|
||||
$this->assertNull($node->getAttribute('doesNotExist'));
|
||||
$this->assertSame('default', $node->getAttribute('doesNotExist', 'default'));
|
||||
|
||||
$node->setAttribute('null', null);
|
||||
$this->assertTrue($node->hasAttribute('null'));
|
||||
$this->assertNull($node->getAttribute('null'));
|
||||
$this->assertNull($node->getAttribute('null', 'default'));
|
||||
|
||||
$this->assertSame(
|
||||
[
|
||||
'key' => 'value',
|
||||
'null' => null,
|
||||
],
|
||||
$node->getAttributes()
|
||||
);
|
||||
|
||||
$node->setAttributes(
|
||||
[
|
||||
'a' => 'b',
|
||||
'c' => null,
|
||||
]
|
||||
);
|
||||
$this->assertSame(
|
||||
[
|
||||
'a' => 'b',
|
||||
'c' => null,
|
||||
],
|
||||
$node->getAttributes()
|
||||
);
|
||||
}
|
||||
|
||||
public function testJsonSerialization() {
|
||||
$code = <<<'PHP'
|
||||
<?php
|
||||
// comment
|
||||
/** doc comment */
|
||||
function functionName(&$a = 0, $b = 1.0) {
|
||||
echo 'Foo';
|
||||
}
|
||||
PHP;
|
||||
$expected = <<<'JSON'
|
||||
[
|
||||
{
|
||||
"nodeType": "Stmt_Function",
|
||||
"byRef": false,
|
||||
"name": {
|
||||
"nodeType": "Identifier",
|
||||
"name": "functionName",
|
||||
"attributes": {
|
||||
"startLine": 4,
|
||||
"endLine": 4
|
||||
}
|
||||
},
|
||||
"params": [
|
||||
{
|
||||
"nodeType": "Param",
|
||||
"type": null,
|
||||
"byRef": true,
|
||||
"variadic": false,
|
||||
"var": {
|
||||
"nodeType": "Expr_Variable",
|
||||
"name": "a",
|
||||
"attributes": {
|
||||
"startLine": 4,
|
||||
"endLine": 4
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"nodeType": "Scalar_LNumber",
|
||||
"value": 0,
|
||||
"attributes": {
|
||||
"startLine": 4,
|
||||
"endLine": 4,
|
||||
"kind": 10
|
||||
}
|
||||
},
|
||||
"attributes": {
|
||||
"startLine": 4,
|
||||
"endLine": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"nodeType": "Param",
|
||||
"type": null,
|
||||
"byRef": false,
|
||||
"variadic": false,
|
||||
"var": {
|
||||
"nodeType": "Expr_Variable",
|
||||
"name": "b",
|
||||
"attributes": {
|
||||
"startLine": 4,
|
||||
"endLine": 4
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"nodeType": "Scalar_DNumber",
|
||||
"value": 1,
|
||||
"attributes": {
|
||||
"startLine": 4,
|
||||
"endLine": 4
|
||||
}
|
||||
},
|
||||
"attributes": {
|
||||
"startLine": 4,
|
||||
"endLine": 4
|
||||
}
|
||||
}
|
||||
],
|
||||
"returnType": null,
|
||||
"stmts": [
|
||||
{
|
||||
"nodeType": "Stmt_Echo",
|
||||
"exprs": [
|
||||
{
|
||||
"nodeType": "Scalar_String",
|
||||
"value": "Foo",
|
||||
"attributes": {
|
||||
"startLine": 5,
|
||||
"endLine": 5,
|
||||
"kind": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"attributes": {
|
||||
"startLine": 5,
|
||||
"endLine": 5
|
||||
}
|
||||
}
|
||||
],
|
||||
"attributes": {
|
||||
"startLine": 4,
|
||||
"comments": [
|
||||
{
|
||||
"nodeType": "Comment",
|
||||
"text": "\/\/ comment\n",
|
||||
"line": 2,
|
||||
"filePos": 6,
|
||||
"tokenPos": 1
|
||||
},
|
||||
{
|
||||
"nodeType": "Comment_Doc",
|
||||
"text": "\/** doc comment *\/",
|
||||
"line": 3,
|
||||
"filePos": 17,
|
||||
"tokenPos": 2
|
||||
}
|
||||
],
|
||||
"endLine": 6
|
||||
}
|
||||
}
|
||||
]
|
||||
JSON;
|
||||
|
||||
$parser = new Parser\Php7(new Lexer());
|
||||
$stmts = $parser->parse(canonicalize($code));
|
||||
$json = json_encode($stmts, JSON_PRETTY_PRINT);
|
||||
$this->assertEquals(canonicalize($expected), canonicalize($json));
|
||||
}
|
||||
}
|
105
vendor/nikic/php-parser/test/PhpParser/NodeDumperTest.php
vendored
Normal file
105
vendor/nikic/php-parser/test/PhpParser/NodeDumperTest.php
vendored
Normal file
|
@ -0,0 +1,105 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser;
|
||||
|
||||
class NodeDumperTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
private function canonicalize($string) {
|
||||
return str_replace("\r\n", "\n", $string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideTestDump
|
||||
*/
|
||||
public function testDump($node, $dump) {
|
||||
$dumper = new NodeDumper;
|
||||
|
||||
$this->assertSame($this->canonicalize($dump), $this->canonicalize($dumper->dump($node)));
|
||||
}
|
||||
|
||||
public function provideTestDump() {
|
||||
return [
|
||||
[
|
||||
[],
|
||||
'array(
|
||||
)'
|
||||
],
|
||||
[
|
||||
['Foo', 'Bar', 'Key' => 'FooBar'],
|
||||
'array(
|
||||
0: Foo
|
||||
1: Bar
|
||||
Key: FooBar
|
||||
)'
|
||||
],
|
||||
[
|
||||
new Node\Name(['Hallo', 'World']),
|
||||
'Name(
|
||||
parts: array(
|
||||
0: Hallo
|
||||
1: World
|
||||
)
|
||||
)'
|
||||
],
|
||||
[
|
||||
new Node\Expr\Array_([
|
||||
new Node\Expr\ArrayItem(new Node\Scalar\String_('Foo'))
|
||||
]),
|
||||
'Expr_Array(
|
||||
items: array(
|
||||
0: Expr_ArrayItem(
|
||||
key: null
|
||||
value: Scalar_String(
|
||||
value: Foo
|
||||
)
|
||||
byRef: false
|
||||
)
|
||||
)
|
||||
)'
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function testDumpWithPositions() {
|
||||
$parser = (new ParserFactory)->create(
|
||||
ParserFactory::ONLY_PHP7,
|
||||
new Lexer(['usedAttributes' => ['startLine', 'endLine', 'startFilePos', 'endFilePos']])
|
||||
);
|
||||
$dumper = new NodeDumper(['dumpPositions' => true]);
|
||||
|
||||
$code = "<?php\n\$a = 1;\necho \$a;";
|
||||
$expected = <<<'OUT'
|
||||
array(
|
||||
0: Stmt_Expression[2:1 - 2:7](
|
||||
expr: Expr_Assign[2:1 - 2:6](
|
||||
var: Expr_Variable[2:1 - 2:2](
|
||||
name: a
|
||||
)
|
||||
expr: Scalar_LNumber[2:6 - 2:6](
|
||||
value: 1
|
||||
)
|
||||
)
|
||||
)
|
||||
1: Stmt_Echo[3:1 - 3:8](
|
||||
exprs: array(
|
||||
0: Expr_Variable[3:6 - 3:7](
|
||||
name: a
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
OUT;
|
||||
|
||||
$stmts = $parser->parse($code);
|
||||
$dump = $dumper->dump($stmts, $code);
|
||||
|
||||
$this->assertSame($this->canonicalize($expected), $this->canonicalize($dump));
|
||||
}
|
||||
|
||||
public function testError() {
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Can only dump nodes and arrays.');
|
||||
$dumper = new NodeDumper;
|
||||
$dumper->dump(new \stdClass);
|
||||
}
|
||||
}
|
59
vendor/nikic/php-parser/test/PhpParser/NodeFinderTest.php
vendored
Normal file
59
vendor/nikic/php-parser/test/PhpParser/NodeFinderTest.php
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser;
|
||||
|
||||
use PhpParser\Node\Expr;
|
||||
|
||||
class NodeFinderTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
private function getStmtsAndVars() {
|
||||
$assign = new Expr\Assign(new Expr\Variable('a'), new Expr\BinaryOp\Concat(
|
||||
new Expr\Variable('b'), new Expr\Variable('c')
|
||||
));
|
||||
$stmts = [new Node\Stmt\Expression($assign)];
|
||||
$vars = [$assign->var, $assign->expr->left, $assign->expr->right];
|
||||
return [$stmts, $vars];
|
||||
}
|
||||
|
||||
public function testFind() {
|
||||
$finder = new NodeFinder;
|
||||
list($stmts, $vars) = $this->getStmtsAndVars();
|
||||
$varFilter = function(Node $node) {
|
||||
return $node instanceof Expr\Variable;
|
||||
};
|
||||
$this->assertSame($vars, $finder->find($stmts, $varFilter));
|
||||
$this->assertSame($vars, $finder->find($stmts[0], $varFilter));
|
||||
|
||||
$noneFilter = function () { return false; };
|
||||
$this->assertSame([], $finder->find($stmts, $noneFilter));
|
||||
}
|
||||
|
||||
public function testFindInstanceOf() {
|
||||
$finder = new NodeFinder;
|
||||
list($stmts, $vars) = $this->getStmtsAndVars();
|
||||
$this->assertSame($vars, $finder->findInstanceOf($stmts, Expr\Variable::class));
|
||||
$this->assertSame($vars, $finder->findInstanceOf($stmts[0], Expr\Variable::class));
|
||||
$this->assertSame([], $finder->findInstanceOf($stmts, Expr\BinaryOp\Mul::class));
|
||||
}
|
||||
|
||||
public function testFindFirst() {
|
||||
$finder = new NodeFinder;
|
||||
list($stmts, $vars) = $this->getStmtsAndVars();
|
||||
$varFilter = function(Node $node) {
|
||||
return $node instanceof Expr\Variable;
|
||||
};
|
||||
$this->assertSame($vars[0], $finder->findFirst($stmts, $varFilter));
|
||||
$this->assertSame($vars[0], $finder->findFirst($stmts[0], $varFilter));
|
||||
|
||||
$noneFilter = function () { return false; };
|
||||
$this->assertNull($finder->findFirst($stmts, $noneFilter));
|
||||
}
|
||||
|
||||
public function testFindFirstInstanceOf() {
|
||||
$finder = new NodeFinder;
|
||||
list($stmts, $vars) = $this->getStmtsAndVars();
|
||||
$this->assertSame($vars[0], $finder->findFirstInstanceOf($stmts, Expr\Variable::class));
|
||||
$this->assertSame($vars[0], $finder->findFirstInstanceOf($stmts[0], Expr\Variable::class));
|
||||
$this->assertNull($finder->findFirstInstanceOf($stmts, Expr\BinaryOp\Mul::class));
|
||||
}
|
||||
}
|
344
vendor/nikic/php-parser/test/PhpParser/NodeTraverserTest.php
vendored
Normal file
344
vendor/nikic/php-parser/test/PhpParser/NodeTraverserTest.php
vendored
Normal file
|
@ -0,0 +1,344 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser;
|
||||
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
|
||||
class NodeTraverserTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testNonModifying() {
|
||||
$str1Node = new String_('Foo');
|
||||
$str2Node = new String_('Bar');
|
||||
$echoNode = new Node\Stmt\Echo_([$str1Node, $str2Node]);
|
||||
$stmts = [$echoNode];
|
||||
|
||||
$visitor = $this->getMockBuilder(NodeVisitor::class)->getMock();
|
||||
|
||||
$visitor->expects($this->at(0))->method('beforeTraverse')->with($stmts);
|
||||
$visitor->expects($this->at(1))->method('enterNode')->with($echoNode);
|
||||
$visitor->expects($this->at(2))->method('enterNode')->with($str1Node);
|
||||
$visitor->expects($this->at(3))->method('leaveNode')->with($str1Node);
|
||||
$visitor->expects($this->at(4))->method('enterNode')->with($str2Node);
|
||||
$visitor->expects($this->at(5))->method('leaveNode')->with($str2Node);
|
||||
$visitor->expects($this->at(6))->method('leaveNode')->with($echoNode);
|
||||
$visitor->expects($this->at(7))->method('afterTraverse')->with($stmts);
|
||||
|
||||
$traverser = new NodeTraverser;
|
||||
$traverser->addVisitor($visitor);
|
||||
|
||||
$this->assertEquals($stmts, $traverser->traverse($stmts));
|
||||
}
|
||||
|
||||
public function testModifying() {
|
||||
$str1Node = new String_('Foo');
|
||||
$str2Node = new String_('Bar');
|
||||
$printNode = new Expr\Print_($str1Node);
|
||||
|
||||
// first visitor changes the node, second verifies the change
|
||||
$visitor1 = $this->getMockBuilder(NodeVisitor::class)->getMock();
|
||||
$visitor2 = $this->getMockBuilder(NodeVisitor::class)->getMock();
|
||||
|
||||
// replace empty statements with string1 node
|
||||
$visitor1->expects($this->at(0))->method('beforeTraverse')->with([])
|
||||
->willReturn([$str1Node]);
|
||||
$visitor2->expects($this->at(0))->method('beforeTraverse')->with([$str1Node]);
|
||||
|
||||
// replace string1 node with print node
|
||||
$visitor1->expects($this->at(1))->method('enterNode')->with($str1Node)
|
||||
->willReturn($printNode);
|
||||
$visitor2->expects($this->at(1))->method('enterNode')->with($printNode);
|
||||
|
||||
// replace string1 node with string2 node
|
||||
$visitor1->expects($this->at(2))->method('enterNode')->with($str1Node)
|
||||
->willReturn($str2Node);
|
||||
$visitor2->expects($this->at(2))->method('enterNode')->with($str2Node);
|
||||
|
||||
// replace string2 node with string1 node again
|
||||
$visitor1->expects($this->at(3))->method('leaveNode')->with($str2Node)
|
||||
->willReturn($str1Node);
|
||||
$visitor2->expects($this->at(3))->method('leaveNode')->with($str1Node);
|
||||
|
||||
// replace print node with string1 node again
|
||||
$visitor1->expects($this->at(4))->method('leaveNode')->with($printNode)
|
||||
->willReturn($str1Node);
|
||||
$visitor2->expects($this->at(4))->method('leaveNode')->with($str1Node);
|
||||
|
||||
// replace string1 node with empty statements again
|
||||
$visitor1->expects($this->at(5))->method('afterTraverse')->with([$str1Node])
|
||||
->willReturn([]);
|
||||
$visitor2->expects($this->at(5))->method('afterTraverse')->with([]);
|
||||
|
||||
$traverser = new NodeTraverser;
|
||||
$traverser->addVisitor($visitor1);
|
||||
$traverser->addVisitor($visitor2);
|
||||
|
||||
// as all operations are reversed we end where we start
|
||||
$this->assertEquals([], $traverser->traverse([]));
|
||||
}
|
||||
|
||||
public function testRemove() {
|
||||
$str1Node = new String_('Foo');
|
||||
$str2Node = new String_('Bar');
|
||||
|
||||
$visitor = $this->getMockBuilder(NodeVisitor::class)->getMock();
|
||||
|
||||
// remove the string1 node, leave the string2 node
|
||||
$visitor->expects($this->at(2))->method('leaveNode')->with($str1Node)
|
||||
->willReturn(NodeTraverser::REMOVE_NODE);
|
||||
|
||||
$traverser = new NodeTraverser;
|
||||
$traverser->addVisitor($visitor);
|
||||
|
||||
$this->assertEquals([$str2Node], $traverser->traverse([$str1Node, $str2Node]));
|
||||
}
|
||||
|
||||
public function testMerge() {
|
||||
$strStart = new String_('Start');
|
||||
$strMiddle = new String_('End');
|
||||
$strEnd = new String_('Middle');
|
||||
$strR1 = new String_('Replacement 1');
|
||||
$strR2 = new String_('Replacement 2');
|
||||
|
||||
$visitor = $this->getMockBuilder(NodeVisitor::class)->getMock();
|
||||
|
||||
// replace strMiddle with strR1 and strR2 by merge
|
||||
$visitor->expects($this->at(4))->method('leaveNode')->with($strMiddle)
|
||||
->willReturn([$strR1, $strR2]);
|
||||
|
||||
$traverser = new NodeTraverser;
|
||||
$traverser->addVisitor($visitor);
|
||||
|
||||
$this->assertEquals(
|
||||
[$strStart, $strR1, $strR2, $strEnd],
|
||||
$traverser->traverse([$strStart, $strMiddle, $strEnd])
|
||||
);
|
||||
}
|
||||
|
||||
public function testInvalidDeepArray() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('Invalid node structure: Contains nested arrays');
|
||||
$strNode = new String_('Foo');
|
||||
$stmts = [[[$strNode]]];
|
||||
|
||||
$traverser = new NodeTraverser;
|
||||
$this->assertEquals($stmts, $traverser->traverse($stmts));
|
||||
}
|
||||
|
||||
public function testDontTraverseChildren() {
|
||||
$strNode = new String_('str');
|
||||
$printNode = new Expr\Print_($strNode);
|
||||
$varNode = new Expr\Variable('foo');
|
||||
$mulNode = new Expr\BinaryOp\Mul($varNode, $varNode);
|
||||
$negNode = new Expr\UnaryMinus($mulNode);
|
||||
$stmts = [$printNode, $negNode];
|
||||
|
||||
$visitor1 = $this->getMockBuilder(NodeVisitor::class)->getMock();
|
||||
$visitor2 = $this->getMockBuilder(NodeVisitor::class)->getMock();
|
||||
|
||||
$visitor1->expects($this->at(1))->method('enterNode')->with($printNode)
|
||||
->willReturn(NodeTraverser::DONT_TRAVERSE_CHILDREN);
|
||||
$visitor2->expects($this->at(1))->method('enterNode')->with($printNode);
|
||||
|
||||
$visitor1->expects($this->at(2))->method('leaveNode')->with($printNode);
|
||||
$visitor2->expects($this->at(2))->method('leaveNode')->with($printNode);
|
||||
|
||||
$visitor1->expects($this->at(3))->method('enterNode')->with($negNode);
|
||||
$visitor2->expects($this->at(3))->method('enterNode')->with($negNode);
|
||||
|
||||
$visitor1->expects($this->at(4))->method('enterNode')->with($mulNode);
|
||||
$visitor2->expects($this->at(4))->method('enterNode')->with($mulNode)
|
||||
->willReturn(NodeTraverser::DONT_TRAVERSE_CHILDREN);
|
||||
|
||||
$visitor1->expects($this->at(5))->method('leaveNode')->with($mulNode);
|
||||
$visitor2->expects($this->at(5))->method('leaveNode')->with($mulNode);
|
||||
|
||||
$visitor1->expects($this->at(6))->method('leaveNode')->with($negNode);
|
||||
$visitor2->expects($this->at(6))->method('leaveNode')->with($negNode);
|
||||
|
||||
$traverser = new NodeTraverser;
|
||||
$traverser->addVisitor($visitor1);
|
||||
$traverser->addVisitor($visitor2);
|
||||
|
||||
$this->assertEquals($stmts, $traverser->traverse($stmts));
|
||||
}
|
||||
|
||||
public function testDontTraverseCurrentAndChildren() {
|
||||
// print 'str'; -($foo * $foo);
|
||||
$strNode = new String_('str');
|
||||
$printNode = new Expr\Print_($strNode);
|
||||
$varNode = new Expr\Variable('foo');
|
||||
$mulNode = new Expr\BinaryOp\Mul($varNode, $varNode);
|
||||
$divNode = new Expr\BinaryOp\Div($varNode, $varNode);
|
||||
$negNode = new Expr\UnaryMinus($mulNode);
|
||||
$stmts = [$printNode, $negNode];
|
||||
|
||||
$visitor1 = $this->getMockBuilder(NodeVisitor::class)->getMock();
|
||||
$visitor2 = $this->getMockBuilder(NodeVisitor::class)->getMock();
|
||||
|
||||
$visitor1->expects($this->at(1))->method('enterNode')->with($printNode)
|
||||
->willReturn(NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN);
|
||||
$visitor1->expects($this->at(2))->method('leaveNode')->with($printNode);
|
||||
|
||||
$visitor1->expects($this->at(3))->method('enterNode')->with($negNode);
|
||||
$visitor2->expects($this->at(1))->method('enterNode')->with($negNode);
|
||||
|
||||
$visitor1->expects($this->at(4))->method('enterNode')->with($mulNode)
|
||||
->willReturn(NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN);
|
||||
$visitor1->expects($this->at(5))->method('leaveNode')->with($mulNode)->willReturn($divNode);
|
||||
|
||||
$visitor1->expects($this->at(6))->method('leaveNode')->with($negNode);
|
||||
$visitor2->expects($this->at(2))->method('leaveNode')->with($negNode);
|
||||
|
||||
$traverser = new NodeTraverser;
|
||||
$traverser->addVisitor($visitor1);
|
||||
$traverser->addVisitor($visitor2);
|
||||
|
||||
$resultStmts = $traverser->traverse($stmts);
|
||||
|
||||
$this->assertInstanceOf(Expr\BinaryOp\Div::class, $resultStmts[1]->expr);
|
||||
}
|
||||
|
||||
public function testStopTraversal() {
|
||||
$varNode1 = new Expr\Variable('a');
|
||||
$varNode2 = new Expr\Variable('b');
|
||||
$varNode3 = new Expr\Variable('c');
|
||||
$mulNode = new Expr\BinaryOp\Mul($varNode1, $varNode2);
|
||||
$printNode = new Expr\Print_($varNode3);
|
||||
$stmts = [$mulNode, $printNode];
|
||||
|
||||
// From enterNode() with array parent
|
||||
$visitor = $this->getMockBuilder(NodeVisitor::class)->getMock();
|
||||
$visitor->expects($this->at(1))->method('enterNode')->with($mulNode)
|
||||
->willReturn(NodeTraverser::STOP_TRAVERSAL);
|
||||
$visitor->expects($this->at(2))->method('afterTraverse');
|
||||
$traverser = new NodeTraverser;
|
||||
$traverser->addVisitor($visitor);
|
||||
$this->assertEquals($stmts, $traverser->traverse($stmts));
|
||||
|
||||
// From enterNode with Node parent
|
||||
$visitor = $this->getMockBuilder(NodeVisitor::class)->getMock();
|
||||
$visitor->expects($this->at(2))->method('enterNode')->with($varNode1)
|
||||
->willReturn(NodeTraverser::STOP_TRAVERSAL);
|
||||
$visitor->expects($this->at(3))->method('afterTraverse');
|
||||
$traverser = new NodeTraverser;
|
||||
$traverser->addVisitor($visitor);
|
||||
$this->assertEquals($stmts, $traverser->traverse($stmts));
|
||||
|
||||
// From leaveNode with Node parent
|
||||
$visitor = $this->getMockBuilder(NodeVisitor::class)->getMock();
|
||||
$visitor->expects($this->at(3))->method('leaveNode')->with($varNode1)
|
||||
->willReturn(NodeTraverser::STOP_TRAVERSAL);
|
||||
$visitor->expects($this->at(4))->method('afterTraverse');
|
||||
$traverser = new NodeTraverser;
|
||||
$traverser->addVisitor($visitor);
|
||||
$this->assertEquals($stmts, $traverser->traverse($stmts));
|
||||
|
||||
// From leaveNode with array parent
|
||||
$visitor = $this->getMockBuilder(NodeVisitor::class)->getMock();
|
||||
$visitor->expects($this->at(6))->method('leaveNode')->with($mulNode)
|
||||
->willReturn(NodeTraverser::STOP_TRAVERSAL);
|
||||
$visitor->expects($this->at(7))->method('afterTraverse');
|
||||
$traverser = new NodeTraverser;
|
||||
$traverser->addVisitor($visitor);
|
||||
$this->assertEquals($stmts, $traverser->traverse($stmts));
|
||||
|
||||
// Check that pending array modifications are still carried out
|
||||
$visitor = $this->getMockBuilder(NodeVisitor::class)->getMock();
|
||||
$visitor->expects($this->at(6))->method('leaveNode')->with($mulNode)
|
||||
->willReturn(NodeTraverser::REMOVE_NODE);
|
||||
$visitor->expects($this->at(7))->method('enterNode')->with($printNode)
|
||||
->willReturn(NodeTraverser::STOP_TRAVERSAL);
|
||||
$visitor->expects($this->at(8))->method('afterTraverse');
|
||||
$traverser = new NodeTraverser;
|
||||
$traverser->addVisitor($visitor);
|
||||
$this->assertEquals([$printNode], $traverser->traverse($stmts));
|
||||
|
||||
}
|
||||
|
||||
public function testRemovingVisitor() {
|
||||
$visitor1 = $this->getMockBuilder(NodeVisitor::class)->getMock();
|
||||
$visitor2 = $this->getMockBuilder(NodeVisitor::class)->getMock();
|
||||
$visitor3 = $this->getMockBuilder(NodeVisitor::class)->getMock();
|
||||
|
||||
$traverser = new NodeTraverser;
|
||||
$traverser->addVisitor($visitor1);
|
||||
$traverser->addVisitor($visitor2);
|
||||
$traverser->addVisitor($visitor3);
|
||||
|
||||
$preExpected = [$visitor1, $visitor2, $visitor3];
|
||||
$this->assertAttributeSame($preExpected, 'visitors', $traverser, 'The appropriate visitors have not been added');
|
||||
|
||||
$traverser->removeVisitor($visitor2);
|
||||
|
||||
$postExpected = [0 => $visitor1, 2 => $visitor3];
|
||||
$this->assertAttributeSame($postExpected, 'visitors', $traverser, 'The appropriate visitors are not present after removal');
|
||||
}
|
||||
|
||||
public function testNoCloneNodes() {
|
||||
$stmts = [new Node\Stmt\Echo_([new String_('Foo'), new String_('Bar')])];
|
||||
|
||||
$traverser = new NodeTraverser;
|
||||
|
||||
$this->assertSame($stmts, $traverser->traverse($stmts));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideTestInvalidReturn
|
||||
*/
|
||||
public function testInvalidReturn($visitor, $message) {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
|
||||
$stmts = [new Node\Stmt\Expression(new Node\Scalar\LNumber(42))];
|
||||
|
||||
$traverser = new NodeTraverser();
|
||||
$traverser->addVisitor($visitor);
|
||||
$traverser->traverse($stmts);
|
||||
}
|
||||
|
||||
public function provideTestInvalidReturn() {
|
||||
$visitor1 = $this->getMockBuilder(NodeVisitor::class)->getMock();
|
||||
$visitor1->expects($this->at(1))->method('enterNode')
|
||||
->willReturn('foobar');
|
||||
|
||||
$visitor2 = $this->getMockBuilder(NodeVisitor::class)->getMock();
|
||||
$visitor2->expects($this->at(2))->method('enterNode')
|
||||
->willReturn('foobar');
|
||||
|
||||
$visitor3 = $this->getMockBuilder(NodeVisitor::class)->getMock();
|
||||
$visitor3->expects($this->at(3))->method('leaveNode')
|
||||
->willReturn('foobar');
|
||||
|
||||
$visitor4 = $this->getMockBuilder(NodeVisitor::class)->getMock();
|
||||
$visitor4->expects($this->at(4))->method('leaveNode')
|
||||
->willReturn('foobar');
|
||||
|
||||
$visitor5 = $this->getMockBuilder(NodeVisitor::class)->getMock();
|
||||
$visitor5->expects($this->at(3))->method('leaveNode')
|
||||
->willReturn([new Node\Scalar\DNumber(42.0)]);
|
||||
|
||||
$visitor6 = $this->getMockBuilder(NodeVisitor::class)->getMock();
|
||||
$visitor6->expects($this->at(4))->method('leaveNode')
|
||||
->willReturn(false);
|
||||
|
||||
$visitor7 = $this->getMockBuilder(NodeVisitor::class)->getMock();
|
||||
$visitor7->expects($this->at(1))->method('enterNode')
|
||||
->willReturn(new Node\Scalar\LNumber(42));
|
||||
|
||||
$visitor8 = $this->getMockBuilder(NodeVisitor::class)->getMock();
|
||||
$visitor8->expects($this->at(2))->method('enterNode')
|
||||
->willReturn(new Node\Stmt\Return_());
|
||||
|
||||
return [
|
||||
[$visitor1, 'enterNode() returned invalid value of type string'],
|
||||
[$visitor2, 'enterNode() returned invalid value of type string'],
|
||||
[$visitor3, 'leaveNode() returned invalid value of type string'],
|
||||
[$visitor4, 'leaveNode() returned invalid value of type string'],
|
||||
[$visitor5, 'leaveNode() may only return an array if the parent structure is an array'],
|
||||
[$visitor6, 'bool(false) return from leaveNode() no longer supported. Return NodeTraverser::REMOVE_NODE instead'],
|
||||
[$visitor7, 'Trying to replace statement (Stmt_Expression) with expression (Scalar_LNumber). Are you missing a Stmt_Expression wrapper?'],
|
||||
[$visitor8, 'Trying to replace expression (Scalar_LNumber) with statement (Stmt_Return)'],
|
||||
];
|
||||
}
|
||||
}
|
53
vendor/nikic/php-parser/test/PhpParser/NodeVisitor/FindingVisitorTest.php
vendored
Normal file
53
vendor/nikic/php-parser/test/PhpParser/NodeVisitor/FindingVisitorTest.php
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\NodeVisitor;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\NodeTraverser;
|
||||
|
||||
class FindingVisitorTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testFindVariables() {
|
||||
$traverser = new NodeTraverser();
|
||||
$visitor = new FindingVisitor(function(Node $node) {
|
||||
return $node instanceof Node\Expr\Variable;
|
||||
});
|
||||
$traverser->addVisitor($visitor);
|
||||
|
||||
$assign = new Expr\Assign(new Expr\Variable('a'), new Expr\BinaryOp\Concat(
|
||||
new Expr\Variable('b'), new Expr\Variable('c')
|
||||
));
|
||||
$stmts = [new Node\Stmt\Expression($assign)];
|
||||
|
||||
$traverser->traverse($stmts);
|
||||
$this->assertSame([
|
||||
$assign->var,
|
||||
$assign->expr->left,
|
||||
$assign->expr->right,
|
||||
], $visitor->getFoundNodes());
|
||||
}
|
||||
|
||||
public function testFindAll() {
|
||||
$traverser = new NodeTraverser();
|
||||
$visitor = new FindingVisitor(function(Node $node) {
|
||||
return true; // All nodes
|
||||
});
|
||||
$traverser->addVisitor($visitor);
|
||||
|
||||
$assign = new Expr\Assign(new Expr\Variable('a'), new Expr\BinaryOp\Concat(
|
||||
new Expr\Variable('b'), new Expr\Variable('c')
|
||||
));
|
||||
$stmts = [new Node\Stmt\Expression($assign)];
|
||||
|
||||
$traverser->traverse($stmts);
|
||||
$this->assertSame([
|
||||
$stmts[0],
|
||||
$assign,
|
||||
$assign->var,
|
||||
$assign->expr,
|
||||
$assign->expr->left,
|
||||
$assign->expr->right,
|
||||
], $visitor->getFoundNodes());
|
||||
}
|
||||
}
|
38
vendor/nikic/php-parser/test/PhpParser/NodeVisitor/FirstFindingVisitorTest.php
vendored
Normal file
38
vendor/nikic/php-parser/test/PhpParser/NodeVisitor/FirstFindingVisitorTest.php
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\NodeVisitor;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\NodeTraverser;
|
||||
|
||||
class FirstFindingVisitorTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testFindFirstVariable() {
|
||||
$traverser = new NodeTraverser();
|
||||
$visitor = new FirstFindingVisitor(function(Node $node) {
|
||||
return $node instanceof Node\Expr\Variable;
|
||||
});
|
||||
$traverser->addVisitor($visitor);
|
||||
|
||||
$assign = new Expr\Assign(new Expr\Variable('a'), new Expr\Variable('b'));
|
||||
$stmts = [new Node\Stmt\Expression($assign)];
|
||||
|
||||
$traverser->traverse($stmts);
|
||||
$this->assertSame($assign->var, $visitor->getFoundNode());
|
||||
}
|
||||
|
||||
public function testFindNone() {
|
||||
$traverser = new NodeTraverser();
|
||||
$visitor = new FirstFindingVisitor(function(Node $node) {
|
||||
return $node instanceof Node\Expr\BinaryOp;
|
||||
});
|
||||
$traverser->addVisitor($visitor);
|
||||
|
||||
$assign = new Expr\Assign(new Expr\Variable('a'), new Expr\Variable('b'));
|
||||
$stmts = [new Node\Stmt\Expression($assign)];
|
||||
|
||||
$traverser->traverse($stmts);
|
||||
$this->assertNull($visitor->getFoundNode());
|
||||
}
|
||||
}
|
505
vendor/nikic/php-parser/test/PhpParser/NodeVisitor/NameResolverTest.php
vendored
Normal file
505
vendor/nikic/php-parser/test/PhpParser/NodeVisitor/NameResolverTest.php
vendored
Normal file
|
@ -0,0 +1,505 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\NodeVisitor;
|
||||
|
||||
use PhpParser;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Stmt;
|
||||
|
||||
class NameResolverTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
private function canonicalize($string) {
|
||||
return str_replace("\r\n", "\n", $string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \PhpParser\NodeVisitor\NameResolver
|
||||
*/
|
||||
public function testResolveNames() {
|
||||
$code = <<<'EOC'
|
||||
<?php
|
||||
|
||||
namespace Foo {
|
||||
use Hallo as Hi;
|
||||
|
||||
new Bar();
|
||||
new Hi();
|
||||
new Hi\Bar();
|
||||
new \Bar();
|
||||
new namespace\Bar();
|
||||
|
||||
bar();
|
||||
hi();
|
||||
Hi\bar();
|
||||
foo\bar();
|
||||
\bar();
|
||||
namespace\bar();
|
||||
}
|
||||
namespace {
|
||||
use Hallo as Hi;
|
||||
|
||||
new Bar();
|
||||
new Hi();
|
||||
new Hi\Bar();
|
||||
new \Bar();
|
||||
new namespace\Bar();
|
||||
|
||||
bar();
|
||||
hi();
|
||||
Hi\bar();
|
||||
foo\bar();
|
||||
\bar();
|
||||
namespace\bar();
|
||||
}
|
||||
namespace Bar {
|
||||
use function foo\bar as baz;
|
||||
use const foo\BAR as BAZ;
|
||||
use foo as bar;
|
||||
|
||||
bar();
|
||||
baz();
|
||||
bar\foo();
|
||||
baz\foo();
|
||||
BAR();
|
||||
BAZ();
|
||||
BAR\FOO();
|
||||
BAZ\FOO();
|
||||
|
||||
bar;
|
||||
baz;
|
||||
bar\foo;
|
||||
baz\foo;
|
||||
BAR;
|
||||
BAZ;
|
||||
BAR\FOO;
|
||||
BAZ\FOO;
|
||||
}
|
||||
namespace Baz {
|
||||
use A\T\{B\C, D\E};
|
||||
use function X\T\{b\c, d\e};
|
||||
use const Y\T\{B\C, D\E};
|
||||
use Z\T\{G, function f, const K};
|
||||
|
||||
new C;
|
||||
new E;
|
||||
new C\D;
|
||||
new E\F;
|
||||
new G;
|
||||
|
||||
c();
|
||||
e();
|
||||
f();
|
||||
C;
|
||||
E;
|
||||
K;
|
||||
|
||||
class ClassWithTypeProperties
|
||||
{
|
||||
public float $php = 7.4;
|
||||
public ?Foo $person;
|
||||
protected static ?bool $probability;
|
||||
}
|
||||
}
|
||||
EOC;
|
||||
$expectedCode = <<<'EOC'
|
||||
namespace Foo {
|
||||
use Hallo as Hi;
|
||||
new \Foo\Bar();
|
||||
new \Hallo();
|
||||
new \Hallo\Bar();
|
||||
new \Bar();
|
||||
new \Foo\Bar();
|
||||
bar();
|
||||
hi();
|
||||
\Hallo\bar();
|
||||
\Foo\foo\bar();
|
||||
\bar();
|
||||
\Foo\bar();
|
||||
}
|
||||
namespace {
|
||||
use Hallo as Hi;
|
||||
new \Bar();
|
||||
new \Hallo();
|
||||
new \Hallo\Bar();
|
||||
new \Bar();
|
||||
new \Bar();
|
||||
\bar();
|
||||
\hi();
|
||||
\Hallo\bar();
|
||||
\foo\bar();
|
||||
\bar();
|
||||
\bar();
|
||||
}
|
||||
namespace Bar {
|
||||
use function foo\bar as baz;
|
||||
use const foo\BAR as BAZ;
|
||||
use foo as bar;
|
||||
bar();
|
||||
\foo\bar();
|
||||
\foo\foo();
|
||||
\Bar\baz\foo();
|
||||
BAR();
|
||||
\foo\bar();
|
||||
\foo\FOO();
|
||||
\Bar\BAZ\FOO();
|
||||
bar;
|
||||
baz;
|
||||
\foo\foo;
|
||||
\Bar\baz\foo;
|
||||
BAR;
|
||||
\foo\BAR;
|
||||
\foo\FOO;
|
||||
\Bar\BAZ\FOO;
|
||||
}
|
||||
namespace Baz {
|
||||
use A\T\{B\C, D\E};
|
||||
use function X\T\{b\c, d\e};
|
||||
use const Y\T\{B\C, D\E};
|
||||
use Z\T\{G, function f, const K};
|
||||
new \A\T\B\C();
|
||||
new \A\T\D\E();
|
||||
new \A\T\B\C\D();
|
||||
new \A\T\D\E\F();
|
||||
new \Z\T\G();
|
||||
\X\T\b\c();
|
||||
\X\T\d\e();
|
||||
\Z\T\f();
|
||||
\Y\T\B\C;
|
||||
\Y\T\D\E;
|
||||
\Z\T\K;
|
||||
class ClassWithTypeProperties
|
||||
{
|
||||
public float $php = 7.4;
|
||||
public ?\Baz\Foo $person;
|
||||
protected static ?bool $probability;
|
||||
}
|
||||
}
|
||||
EOC;
|
||||
|
||||
$parser = new PhpParser\Parser\Php7(new PhpParser\Lexer\Emulative);
|
||||
$prettyPrinter = new PhpParser\PrettyPrinter\Standard;
|
||||
$traverser = new PhpParser\NodeTraverser;
|
||||
$traverser->addVisitor(new NameResolver);
|
||||
|
||||
$stmts = $parser->parse($code);
|
||||
$stmts = $traverser->traverse($stmts);
|
||||
|
||||
$this->assertSame(
|
||||
$this->canonicalize($expectedCode),
|
||||
$prettyPrinter->prettyPrint($stmts)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \PhpParser\NodeVisitor\NameResolver
|
||||
*/
|
||||
public function testResolveLocations() {
|
||||
$code = <<<'EOC'
|
||||
<?php
|
||||
namespace NS;
|
||||
|
||||
class A extends B implements C, D {
|
||||
use E, F, G {
|
||||
f as private g;
|
||||
E::h as i;
|
||||
E::j insteadof F, G;
|
||||
}
|
||||
}
|
||||
|
||||
interface A extends C, D {
|
||||
public function a(A $a) : A;
|
||||
}
|
||||
|
||||
function fn(A $a) : A {}
|
||||
function fn2(array $a) : array {}
|
||||
function(A $a) : A {};
|
||||
|
||||
function fn3(?A $a) : ?A {}
|
||||
function fn4(?array $a) : ?array {}
|
||||
|
||||
A::b();
|
||||
A::$b;
|
||||
A::B;
|
||||
new A;
|
||||
$a instanceof A;
|
||||
|
||||
namespace\a();
|
||||
namespace\A;
|
||||
|
||||
try {
|
||||
$someThing;
|
||||
} catch (A $a) {
|
||||
$someThingElse;
|
||||
}
|
||||
EOC;
|
||||
$expectedCode = <<<'EOC'
|
||||
namespace NS;
|
||||
|
||||
class A extends \NS\B implements \NS\C, \NS\D
|
||||
{
|
||||
use \NS\E, \NS\F, \NS\G {
|
||||
f as private g;
|
||||
\NS\E::h as i;
|
||||
\NS\E::j insteadof \NS\F, \NS\G;
|
||||
}
|
||||
}
|
||||
interface A extends \NS\C, \NS\D
|
||||
{
|
||||
public function a(\NS\A $a) : \NS\A;
|
||||
}
|
||||
function fn(\NS\A $a) : \NS\A
|
||||
{
|
||||
}
|
||||
function fn2(array $a) : array
|
||||
{
|
||||
}
|
||||
function (\NS\A $a) : \NS\A {
|
||||
};
|
||||
function fn3(?\NS\A $a) : ?\NS\A
|
||||
{
|
||||
}
|
||||
function fn4(?array $a) : ?array
|
||||
{
|
||||
}
|
||||
\NS\A::b();
|
||||
\NS\A::$b;
|
||||
\NS\A::B;
|
||||
new \NS\A();
|
||||
$a instanceof \NS\A;
|
||||
\NS\a();
|
||||
\NS\A;
|
||||
try {
|
||||
$someThing;
|
||||
} catch (\NS\A $a) {
|
||||
$someThingElse;
|
||||
}
|
||||
EOC;
|
||||
|
||||
$parser = new PhpParser\Parser\Php7(new PhpParser\Lexer\Emulative);
|
||||
$prettyPrinter = new PhpParser\PrettyPrinter\Standard;
|
||||
$traverser = new PhpParser\NodeTraverser;
|
||||
$traverser->addVisitor(new NameResolver);
|
||||
|
||||
$stmts = $parser->parse($code);
|
||||
$stmts = $traverser->traverse($stmts);
|
||||
|
||||
$this->assertSame(
|
||||
$this->canonicalize($expectedCode),
|
||||
$prettyPrinter->prettyPrint($stmts)
|
||||
);
|
||||
}
|
||||
|
||||
public function testNoResolveSpecialName() {
|
||||
$stmts = [new Node\Expr\New_(new Name('self'))];
|
||||
|
||||
$traverser = new PhpParser\NodeTraverser;
|
||||
$traverser->addVisitor(new NameResolver);
|
||||
|
||||
$this->assertEquals($stmts, $traverser->traverse($stmts));
|
||||
}
|
||||
|
||||
public function testAddDeclarationNamespacedName() {
|
||||
$nsStmts = [
|
||||
new Stmt\Class_('A'),
|
||||
new Stmt\Interface_('B'),
|
||||
new Stmt\Function_('C'),
|
||||
new Stmt\Const_([
|
||||
new Node\Const_('D', new Node\Scalar\LNumber(42))
|
||||
]),
|
||||
new Stmt\Trait_('E'),
|
||||
new Expr\New_(new Stmt\Class_(null)),
|
||||
];
|
||||
|
||||
$traverser = new PhpParser\NodeTraverser;
|
||||
$traverser->addVisitor(new NameResolver);
|
||||
|
||||
$stmts = $traverser->traverse([new Stmt\Namespace_(new Name('NS'), $nsStmts)]);
|
||||
$this->assertSame('NS\\A', (string) $stmts[0]->stmts[0]->namespacedName);
|
||||
$this->assertSame('NS\\B', (string) $stmts[0]->stmts[1]->namespacedName);
|
||||
$this->assertSame('NS\\C', (string) $stmts[0]->stmts[2]->namespacedName);
|
||||
$this->assertSame('NS\\D', (string) $stmts[0]->stmts[3]->consts[0]->namespacedName);
|
||||
$this->assertSame('NS\\E', (string) $stmts[0]->stmts[4]->namespacedName);
|
||||
$this->assertObjectNotHasAttribute('namespacedName', $stmts[0]->stmts[5]->class);
|
||||
|
||||
$stmts = $traverser->traverse([new Stmt\Namespace_(null, $nsStmts)]);
|
||||
$this->assertSame('A', (string) $stmts[0]->stmts[0]->namespacedName);
|
||||
$this->assertSame('B', (string) $stmts[0]->stmts[1]->namespacedName);
|
||||
$this->assertSame('C', (string) $stmts[0]->stmts[2]->namespacedName);
|
||||
$this->assertSame('D', (string) $stmts[0]->stmts[3]->consts[0]->namespacedName);
|
||||
$this->assertSame('E', (string) $stmts[0]->stmts[4]->namespacedName);
|
||||
$this->assertObjectNotHasAttribute('namespacedName', $stmts[0]->stmts[5]->class);
|
||||
}
|
||||
|
||||
public function testAddRuntimeResolvedNamespacedName() {
|
||||
$stmts = [
|
||||
new Stmt\Namespace_(new Name('NS'), [
|
||||
new Expr\FuncCall(new Name('foo')),
|
||||
new Expr\ConstFetch(new Name('FOO')),
|
||||
]),
|
||||
new Stmt\Namespace_(null, [
|
||||
new Expr\FuncCall(new Name('foo')),
|
||||
new Expr\ConstFetch(new Name('FOO')),
|
||||
]),
|
||||
];
|
||||
|
||||
$traverser = new PhpParser\NodeTraverser;
|
||||
$traverser->addVisitor(new NameResolver);
|
||||
$stmts = $traverser->traverse($stmts);
|
||||
|
||||
$this->assertSame('NS\\foo', (string) $stmts[0]->stmts[0]->name->getAttribute('namespacedName'));
|
||||
$this->assertSame('NS\\FOO', (string) $stmts[0]->stmts[1]->name->getAttribute('namespacedName'));
|
||||
|
||||
$this->assertFalse($stmts[1]->stmts[0]->name->hasAttribute('namespacedName'));
|
||||
$this->assertFalse($stmts[1]->stmts[1]->name->hasAttribute('namespacedName'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideTestError
|
||||
*/
|
||||
public function testError(Node $stmt, $errorMsg) {
|
||||
$this->expectException(\PhpParser\Error::class);
|
||||
$this->expectExceptionMessage($errorMsg);
|
||||
|
||||
$traverser = new PhpParser\NodeTraverser;
|
||||
$traverser->addVisitor(new NameResolver);
|
||||
$traverser->traverse([$stmt]);
|
||||
}
|
||||
|
||||
public function provideTestError() {
|
||||
return [
|
||||
[
|
||||
new Stmt\Use_([
|
||||
new Stmt\UseUse(new Name('A\B'), 'B', 0, ['startLine' => 1]),
|
||||
new Stmt\UseUse(new Name('C\D'), 'B', 0, ['startLine' => 2]),
|
||||
], Stmt\Use_::TYPE_NORMAL),
|
||||
'Cannot use C\D as B because the name is already in use on line 2'
|
||||
],
|
||||
[
|
||||
new Stmt\Use_([
|
||||
new Stmt\UseUse(new Name('a\b'), 'b', 0, ['startLine' => 1]),
|
||||
new Stmt\UseUse(new Name('c\d'), 'B', 0, ['startLine' => 2]),
|
||||
], Stmt\Use_::TYPE_FUNCTION),
|
||||
'Cannot use function c\d as B because the name is already in use on line 2'
|
||||
],
|
||||
[
|
||||
new Stmt\Use_([
|
||||
new Stmt\UseUse(new Name('A\B'), 'B', 0, ['startLine' => 1]),
|
||||
new Stmt\UseUse(new Name('C\D'), 'B', 0, ['startLine' => 2]),
|
||||
], Stmt\Use_::TYPE_CONSTANT),
|
||||
'Cannot use const C\D as B because the name is already in use on line 2'
|
||||
],
|
||||
[
|
||||
new Expr\New_(new Name\FullyQualified('self', ['startLine' => 3])),
|
||||
"'\\self' is an invalid class name on line 3"
|
||||
],
|
||||
[
|
||||
new Expr\New_(new Name\Relative('self', ['startLine' => 3])),
|
||||
"'\\self' is an invalid class name on line 3"
|
||||
],
|
||||
[
|
||||
new Expr\New_(new Name\FullyQualified('PARENT', ['startLine' => 3])),
|
||||
"'\\PARENT' is an invalid class name on line 3"
|
||||
],
|
||||
[
|
||||
new Expr\New_(new Name\Relative('STATIC', ['startLine' => 3])),
|
||||
"'\\STATIC' is an invalid class name on line 3"
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function testClassNameIsCaseInsensitive()
|
||||
{
|
||||
$source = <<<'EOC'
|
||||
<?php
|
||||
namespace Foo;
|
||||
use Bar\Baz;
|
||||
$test = new baz();
|
||||
EOC;
|
||||
|
||||
$parser = new PhpParser\Parser\Php7(new PhpParser\Lexer\Emulative);
|
||||
$stmts = $parser->parse($source);
|
||||
|
||||
$traverser = new PhpParser\NodeTraverser;
|
||||
$traverser->addVisitor(new NameResolver);
|
||||
|
||||
$stmts = $traverser->traverse($stmts);
|
||||
$stmt = $stmts[0];
|
||||
|
||||
$assign = $stmt->stmts[1]->expr;
|
||||
$this->assertSame(['Bar', 'Baz'], $assign->expr->class->parts);
|
||||
}
|
||||
|
||||
public function testSpecialClassNamesAreCaseInsensitive() {
|
||||
$source = <<<'EOC'
|
||||
<?php
|
||||
namespace Foo;
|
||||
|
||||
class Bar
|
||||
{
|
||||
public static function method()
|
||||
{
|
||||
SELF::method();
|
||||
PARENT::method();
|
||||
STATIC::method();
|
||||
}
|
||||
}
|
||||
EOC;
|
||||
|
||||
$parser = new PhpParser\Parser\Php7(new PhpParser\Lexer\Emulative);
|
||||
$stmts = $parser->parse($source);
|
||||
|
||||
$traverser = new PhpParser\NodeTraverser;
|
||||
$traverser->addVisitor(new NameResolver);
|
||||
|
||||
$stmts = $traverser->traverse($stmts);
|
||||
$classStmt = $stmts[0];
|
||||
$methodStmt = $classStmt->stmts[0]->stmts[0];
|
||||
|
||||
$this->assertSame('SELF', (string) $methodStmt->stmts[0]->expr->class);
|
||||
$this->assertSame('PARENT', (string) $methodStmt->stmts[1]->expr->class);
|
||||
$this->assertSame('STATIC', (string) $methodStmt->stmts[2]->expr->class);
|
||||
}
|
||||
|
||||
public function testAddOriginalNames() {
|
||||
$traverser = new PhpParser\NodeTraverser;
|
||||
$traverser->addVisitor(new NameResolver(null, ['preserveOriginalNames' => true]));
|
||||
|
||||
$n1 = new Name('Bar');
|
||||
$n2 = new Name('bar');
|
||||
$origStmts = [
|
||||
new Stmt\Namespace_(new Name('Foo'), [
|
||||
new Expr\ClassConstFetch($n1, 'FOO'),
|
||||
new Expr\FuncCall($n2),
|
||||
])
|
||||
];
|
||||
|
||||
$stmts = $traverser->traverse($origStmts);
|
||||
|
||||
$this->assertSame($n1, $stmts[0]->stmts[0]->class->getAttribute('originalName'));
|
||||
$this->assertSame($n2, $stmts[0]->stmts[1]->name->getAttribute('originalName'));
|
||||
}
|
||||
|
||||
public function testAttributeOnlyMode() {
|
||||
$traverser = new PhpParser\NodeTraverser;
|
||||
$traverser->addVisitor(new NameResolver(null, ['replaceNodes' => false]));
|
||||
|
||||
$n1 = new Name('Bar');
|
||||
$n2 = new Name('bar');
|
||||
$origStmts = [
|
||||
new Stmt\Namespace_(new Name('Foo'), [
|
||||
new Expr\ClassConstFetch($n1, 'FOO'),
|
||||
new Expr\FuncCall($n2),
|
||||
])
|
||||
];
|
||||
|
||||
$traverser->traverse($origStmts);
|
||||
|
||||
$this->assertEquals(
|
||||
new Name\FullyQualified('Foo\Bar'), $n1->getAttribute('resolvedName'));
|
||||
$this->assertFalse($n2->hasAttribute('resolvedName'));
|
||||
$this->assertEquals(
|
||||
new Name\FullyQualified('Foo\bar'), $n2->getAttribute('namespacedName'));
|
||||
}
|
||||
}
|
94
vendor/nikic/php-parser/test/PhpParser/Parser/MultipleTest.php
vendored
Normal file
94
vendor/nikic/php-parser/test/PhpParser/Parser/MultipleTest.php
vendored
Normal file
|
@ -0,0 +1,94 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Parser;
|
||||
|
||||
use PhpParser\Error;
|
||||
use PhpParser\Lexer;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Scalar\LNumber;
|
||||
use PhpParser\Node\Stmt;
|
||||
use PhpParser\ParserTest;
|
||||
|
||||
class MultipleTest extends ParserTest
|
||||
{
|
||||
// This provider is for the generic parser tests, just pick an arbitrary order here
|
||||
protected function getParser(Lexer $lexer) {
|
||||
return new Multiple([new Php5($lexer), new Php7($lexer)]);
|
||||
}
|
||||
|
||||
private function getPrefer7() {
|
||||
$lexer = new Lexer(['usedAttributes' => []]);
|
||||
return new Multiple([new Php7($lexer), new Php5($lexer)]);
|
||||
}
|
||||
|
||||
private function getPrefer5() {
|
||||
$lexer = new Lexer(['usedAttributes' => []]);
|
||||
return new Multiple([new Php5($lexer), new Php7($lexer)]);
|
||||
}
|
||||
|
||||
/** @dataProvider provideTestParse */
|
||||
public function testParse($code, Multiple $parser, $expected) {
|
||||
$this->assertEquals($expected, $parser->parse($code));
|
||||
}
|
||||
|
||||
public function provideTestParse() {
|
||||
return [
|
||||
[
|
||||
// PHP 7 only code
|
||||
'<?php class Test { function function() {} }',
|
||||
$this->getPrefer5(),
|
||||
[
|
||||
new Stmt\Class_('Test', ['stmts' => [
|
||||
new Stmt\ClassMethod('function')
|
||||
]]),
|
||||
]
|
||||
],
|
||||
[
|
||||
// PHP 5 only code
|
||||
'<?php global $$a->b;',
|
||||
$this->getPrefer7(),
|
||||
[
|
||||
new Stmt\Global_([
|
||||
new Expr\Variable(new Expr\PropertyFetch(new Expr\Variable('a'), 'b'))
|
||||
])
|
||||
]
|
||||
],
|
||||
[
|
||||
// Different meaning (PHP 5)
|
||||
'<?php $$a[0];',
|
||||
$this->getPrefer5(),
|
||||
[
|
||||
new Stmt\Expression(new Expr\Variable(
|
||||
new Expr\ArrayDimFetch(new Expr\Variable('a'), LNumber::fromString('0'))
|
||||
))
|
||||
]
|
||||
],
|
||||
[
|
||||
// Different meaning (PHP 7)
|
||||
'<?php $$a[0];',
|
||||
$this->getPrefer7(),
|
||||
[
|
||||
new Stmt\Expression(new Expr\ArrayDimFetch(
|
||||
new Expr\Variable(new Expr\Variable('a')), LNumber::fromString('0')
|
||||
))
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function testThrownError() {
|
||||
$this->expectException(Error::class);
|
||||
$this->expectExceptionMessage('FAIL A');
|
||||
|
||||
$parserA = $this->getMockBuilder(\PhpParser\Parser::class)->getMock();
|
||||
$parserA->expects($this->at(0))
|
||||
->method('parse')->willThrowException(new Error('FAIL A'));
|
||||
|
||||
$parserB = $this->getMockBuilder(\PhpParser\Parser::class)->getMock();
|
||||
$parserB->expects($this->at(0))
|
||||
->method('parse')->willThrowException(new Error('FAIL B'));
|
||||
|
||||
$parser = new Multiple([$parserA, $parserB]);
|
||||
$parser->parse('dummy');
|
||||
}
|
||||
}
|
13
vendor/nikic/php-parser/test/PhpParser/Parser/Php5Test.php
vendored
Normal file
13
vendor/nikic/php-parser/test/PhpParser/Parser/Php5Test.php
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Parser;
|
||||
|
||||
use PhpParser\Lexer;
|
||||
use PhpParser\ParserTest;
|
||||
|
||||
class Php5Test extends ParserTest
|
||||
{
|
||||
protected function getParser(Lexer $lexer) {
|
||||
return new Php5($lexer);
|
||||
}
|
||||
}
|
13
vendor/nikic/php-parser/test/PhpParser/Parser/Php7Test.php
vendored
Normal file
13
vendor/nikic/php-parser/test/PhpParser/Parser/Php7Test.php
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Parser;
|
||||
|
||||
use PhpParser\Lexer;
|
||||
use PhpParser\ParserTest;
|
||||
|
||||
class Php7Test extends ParserTest
|
||||
{
|
||||
protected function getParser(Lexer $lexer) {
|
||||
return new Php7($lexer);
|
||||
}
|
||||
}
|
36
vendor/nikic/php-parser/test/PhpParser/ParserFactoryTest.php
vendored
Normal file
36
vendor/nikic/php-parser/test/PhpParser/ParserFactoryTest.php
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser;
|
||||
|
||||
/* This test is very weak, because PHPUnit's assertEquals assertion is way too slow dealing with the
|
||||
* large objects involved here. So we just do some basic instanceof tests instead. */
|
||||
|
||||
class ParserFactoryTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/** @dataProvider provideTestCreate */
|
||||
public function testCreate($kind, $lexer, $expected) {
|
||||
$this->assertInstanceOf($expected, (new ParserFactory)->create($kind, $lexer));
|
||||
}
|
||||
|
||||
public function provideTestCreate() {
|
||||
$lexer = new Lexer();
|
||||
return [
|
||||
[
|
||||
ParserFactory::PREFER_PHP7, $lexer,
|
||||
Parser\Multiple::class
|
||||
],
|
||||
[
|
||||
ParserFactory::PREFER_PHP5, null,
|
||||
Parser\Multiple::class
|
||||
],
|
||||
[
|
||||
ParserFactory::ONLY_PHP7, null,
|
||||
Parser\Php7::class
|
||||
],
|
||||
[
|
||||
ParserFactory::ONLY_PHP5, $lexer,
|
||||
Parser\Php5::class
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
183
vendor/nikic/php-parser/test/PhpParser/ParserTest.php
vendored
Normal file
183
vendor/nikic/php-parser/test/PhpParser/ParserTest.php
vendored
Normal file
|
@ -0,0 +1,183 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser;
|
||||
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Scalar;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use PhpParser\Node\Stmt;
|
||||
|
||||
abstract class ParserTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/** @returns Parser */
|
||||
abstract protected function getParser(Lexer $lexer);
|
||||
|
||||
public function testParserThrowsSyntaxError() {
|
||||
$this->expectException(Error::class);
|
||||
$this->expectExceptionMessage('Syntax error, unexpected EOF on line 1');
|
||||
$parser = $this->getParser(new Lexer());
|
||||
$parser->parse('<?php foo');
|
||||
}
|
||||
|
||||
public function testParserThrowsSpecialError() {
|
||||
$this->expectException(Error::class);
|
||||
$this->expectExceptionMessage('Cannot use foo as self because \'self\' is a special class name on line 1');
|
||||
$parser = $this->getParser(new Lexer());
|
||||
$parser->parse('<?php use foo as self;');
|
||||
}
|
||||
|
||||
public function testParserThrowsLexerError() {
|
||||
$this->expectException(Error::class);
|
||||
$this->expectExceptionMessage('Unterminated comment on line 1');
|
||||
$parser = $this->getParser(new Lexer());
|
||||
$parser->parse('<?php /*');
|
||||
}
|
||||
|
||||
public function testAttributeAssignment() {
|
||||
$lexer = new Lexer([
|
||||
'usedAttributes' => [
|
||||
'comments', 'startLine', 'endLine',
|
||||
'startTokenPos', 'endTokenPos',
|
||||
]
|
||||
]);
|
||||
|
||||
$code = <<<'EOC'
|
||||
<?php
|
||||
/** Doc comment */
|
||||
function test($a) {
|
||||
// Line
|
||||
// Comments
|
||||
echo $a;
|
||||
}
|
||||
EOC;
|
||||
$code = canonicalize($code);
|
||||
|
||||
$parser = $this->getParser($lexer);
|
||||
$stmts = $parser->parse($code);
|
||||
|
||||
/** @var Stmt\Function_ $fn */
|
||||
$fn = $stmts[0];
|
||||
$this->assertInstanceOf(Stmt\Function_::class, $fn);
|
||||
$this->assertEquals([
|
||||
'comments' => [
|
||||
new Comment\Doc('/** Doc comment */', 2, 6, 1),
|
||||
],
|
||||
'startLine' => 3,
|
||||
'endLine' => 7,
|
||||
'startTokenPos' => 3,
|
||||
'endTokenPos' => 21,
|
||||
], $fn->getAttributes());
|
||||
|
||||
$param = $fn->params[0];
|
||||
$this->assertInstanceOf(Node\Param::class, $param);
|
||||
$this->assertEquals([
|
||||
'startLine' => 3,
|
||||
'endLine' => 3,
|
||||
'startTokenPos' => 7,
|
||||
'endTokenPos' => 7,
|
||||
], $param->getAttributes());
|
||||
|
||||
/** @var Stmt\Echo_ $echo */
|
||||
$echo = $fn->stmts[0];
|
||||
$this->assertInstanceOf(Stmt\Echo_::class, $echo);
|
||||
$this->assertEquals([
|
||||
'comments' => [
|
||||
new Comment("// Line\n", 4, 49, 12),
|
||||
new Comment("// Comments\n", 5, 61, 14),
|
||||
],
|
||||
'startLine' => 6,
|
||||
'endLine' => 6,
|
||||
'startTokenPos' => 16,
|
||||
'endTokenPos' => 19,
|
||||
], $echo->getAttributes());
|
||||
|
||||
/** @var \PhpParser\Node\Expr\Variable $var */
|
||||
$var = $echo->exprs[0];
|
||||
$this->assertInstanceOf(Expr\Variable::class, $var);
|
||||
$this->assertEquals([
|
||||
'startLine' => 6,
|
||||
'endLine' => 6,
|
||||
'startTokenPos' => 18,
|
||||
'endTokenPos' => 18,
|
||||
], $var->getAttributes());
|
||||
}
|
||||
|
||||
public function testInvalidToken() {
|
||||
$this->expectException(\RangeException::class);
|
||||
$this->expectExceptionMessage('The lexer returned an invalid token (id=999, value=foobar)');
|
||||
$lexer = new InvalidTokenLexer;
|
||||
$parser = $this->getParser($lexer);
|
||||
$parser->parse('dummy');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideTestExtraAttributes
|
||||
*/
|
||||
public function testExtraAttributes($code, $expectedAttributes) {
|
||||
$parser = $this->getParser(new Lexer\Emulative);
|
||||
$stmts = $parser->parse("<?php $code;");
|
||||
$node = $stmts[0] instanceof Stmt\Expression ? $stmts[0]->expr : $stmts[0];
|
||||
$attributes = $node->getAttributes();
|
||||
foreach ($expectedAttributes as $name => $value) {
|
||||
$this->assertSame($value, $attributes[$name]);
|
||||
}
|
||||
}
|
||||
|
||||
public function provideTestExtraAttributes() {
|
||||
return [
|
||||
['0', ['kind' => Scalar\LNumber::KIND_DEC]],
|
||||
['9', ['kind' => Scalar\LNumber::KIND_DEC]],
|
||||
['07', ['kind' => Scalar\LNumber::KIND_OCT]],
|
||||
['0xf', ['kind' => Scalar\LNumber::KIND_HEX]],
|
||||
['0XF', ['kind' => Scalar\LNumber::KIND_HEX]],
|
||||
['0b1', ['kind' => Scalar\LNumber::KIND_BIN]],
|
||||
['0B1', ['kind' => Scalar\LNumber::KIND_BIN]],
|
||||
['[]', ['kind' => Expr\Array_::KIND_SHORT]],
|
||||
['array()', ['kind' => Expr\Array_::KIND_LONG]],
|
||||
["'foo'", ['kind' => String_::KIND_SINGLE_QUOTED]],
|
||||
["b'foo'", ['kind' => String_::KIND_SINGLE_QUOTED]],
|
||||
["B'foo'", ['kind' => String_::KIND_SINGLE_QUOTED]],
|
||||
['"foo"', ['kind' => String_::KIND_DOUBLE_QUOTED]],
|
||||
['b"foo"', ['kind' => String_::KIND_DOUBLE_QUOTED]],
|
||||
['B"foo"', ['kind' => String_::KIND_DOUBLE_QUOTED]],
|
||||
['"foo$bar"', ['kind' => String_::KIND_DOUBLE_QUOTED]],
|
||||
['b"foo$bar"', ['kind' => String_::KIND_DOUBLE_QUOTED]],
|
||||
['B"foo$bar"', ['kind' => String_::KIND_DOUBLE_QUOTED]],
|
||||
["<<<'STR'\nSTR\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR', 'docIndentation' => '']],
|
||||
["<<<STR\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR', 'docIndentation' => '']],
|
||||
["<<<\"STR\"\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR', 'docIndentation' => '']],
|
||||
["b<<<'STR'\nSTR\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR', 'docIndentation' => '']],
|
||||
["B<<<'STR'\nSTR\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR', 'docIndentation' => '']],
|
||||
["<<< \t 'STR'\nSTR\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR', 'docIndentation' => '']],
|
||||
["<<<'\xff'\n\xff\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => "\xff", 'docIndentation' => '']],
|
||||
["<<<\"STR\"\n\$a\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR', 'docIndentation' => '']],
|
||||
["b<<<\"STR\"\n\$a\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR', 'docIndentation' => '']],
|
||||
["B<<<\"STR\"\n\$a\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR', 'docIndentation' => '']],
|
||||
["<<< \t \"STR\"\n\$a\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR', 'docIndentation' => '']],
|
||||
["<<<STR\n STR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR', 'docIndentation' => ' ']],
|
||||
["<<<STR\n\tSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR', 'docIndentation' => "\t"]],
|
||||
["<<<'STR'\n Foo\n STR\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR', 'docIndentation' => ' ']],
|
||||
["die", ['kind' => Expr\Exit_::KIND_DIE]],
|
||||
["die('done')", ['kind' => Expr\Exit_::KIND_DIE]],
|
||||
["exit", ['kind' => Expr\Exit_::KIND_EXIT]],
|
||||
["exit(1)", ['kind' => Expr\Exit_::KIND_EXIT]],
|
||||
["?>Foo", ['hasLeadingNewline' => false]],
|
||||
["?>\nFoo", ['hasLeadingNewline' => true]],
|
||||
["namespace Foo;", ['kind' => Stmt\Namespace_::KIND_SEMICOLON]],
|
||||
["namespace Foo {}", ['kind' => Stmt\Namespace_::KIND_BRACED]],
|
||||
["namespace {}", ['kind' => Stmt\Namespace_::KIND_BRACED]],
|
||||
["(float) 5.0", ['kind' => Expr\Cast\Double::KIND_FLOAT]],
|
||||
["(double) 5.0", ['kind' => Expr\Cast\Double::KIND_DOUBLE]],
|
||||
["(real) 5.0", ['kind' => Expr\Cast\Double::KIND_REAL]],
|
||||
[" ( REAL ) 5.0", ['kind' => Expr\Cast\Double::KIND_REAL]],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
class InvalidTokenLexer extends Lexer
|
||||
{
|
||||
public function getNextToken(&$value = null, &$startAttributes = null, &$endAttributes = null) : int {
|
||||
$value = 'foobar';
|
||||
return 999;
|
||||
}
|
||||
}
|
307
vendor/nikic/php-parser/test/PhpParser/PrettyPrinterTest.php
vendored
Normal file
307
vendor/nikic/php-parser/test/PhpParser/PrettyPrinterTest.php
vendored
Normal file
|
@ -0,0 +1,307 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser;
|
||||
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Scalar\DNumber;
|
||||
use PhpParser\Node\Scalar\Encapsed;
|
||||
use PhpParser\Node\Scalar\EncapsedStringPart;
|
||||
use PhpParser\Node\Scalar\LNumber;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use PhpParser\Node\Stmt;
|
||||
use PhpParser\PrettyPrinter\Standard;
|
||||
|
||||
class PrettyPrinterTest extends CodeTestAbstract
|
||||
{
|
||||
protected function doTestPrettyPrintMethod($method, $name, $code, $expected, $modeLine) {
|
||||
$lexer = new Lexer\Emulative;
|
||||
$parser5 = new Parser\Php5($lexer);
|
||||
$parser7 = new Parser\Php7($lexer);
|
||||
|
||||
list($version, $options) = $this->parseModeLine($modeLine);
|
||||
$prettyPrinter = new Standard($options);
|
||||
|
||||
try {
|
||||
$output5 = canonicalize($prettyPrinter->$method($parser5->parse($code)));
|
||||
} catch (Error $e) {
|
||||
$output5 = null;
|
||||
if ('php7' !== $version) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$output7 = canonicalize($prettyPrinter->$method($parser7->parse($code)));
|
||||
} catch (Error $e) {
|
||||
$output7 = null;
|
||||
if ('php5' !== $version) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
if ('php5' === $version) {
|
||||
$this->assertSame($expected, $output5, $name);
|
||||
$this->assertNotSame($expected, $output7, $name);
|
||||
} elseif ('php7' === $version) {
|
||||
$this->assertSame($expected, $output7, $name);
|
||||
$this->assertNotSame($expected, $output5, $name);
|
||||
} else {
|
||||
$this->assertSame($expected, $output5, $name);
|
||||
$this->assertSame($expected, $output7, $name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideTestPrettyPrint
|
||||
* @covers \PhpParser\PrettyPrinter\Standard<extended>
|
||||
*/
|
||||
public function testPrettyPrint($name, $code, $expected, $mode) {
|
||||
$this->doTestPrettyPrintMethod('prettyPrint', $name, $code, $expected, $mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideTestPrettyPrintFile
|
||||
* @covers \PhpParser\PrettyPrinter\Standard<extended>
|
||||
*/
|
||||
public function testPrettyPrintFile($name, $code, $expected, $mode) {
|
||||
$this->doTestPrettyPrintMethod('prettyPrintFile', $name, $code, $expected, $mode);
|
||||
}
|
||||
|
||||
public function provideTestPrettyPrint() {
|
||||
return $this->getTests(__DIR__ . '/../code/prettyPrinter', 'test');
|
||||
}
|
||||
|
||||
public function provideTestPrettyPrintFile() {
|
||||
return $this->getTests(__DIR__ . '/../code/prettyPrinter', 'file-test');
|
||||
}
|
||||
|
||||
public function testPrettyPrintExpr() {
|
||||
$prettyPrinter = new Standard;
|
||||
$expr = new Expr\BinaryOp\Mul(
|
||||
new Expr\BinaryOp\Plus(new Expr\Variable('a'), new Expr\Variable('b')),
|
||||
new Expr\Variable('c')
|
||||
);
|
||||
$this->assertEquals('($a + $b) * $c', $prettyPrinter->prettyPrintExpr($expr));
|
||||
|
||||
$expr = new Expr\Closure([
|
||||
'stmts' => [new Stmt\Return_(new String_("a\nb"))]
|
||||
]);
|
||||
$this->assertEquals("function () {\n return 'a\nb';\n}", $prettyPrinter->prettyPrintExpr($expr));
|
||||
}
|
||||
|
||||
public function testCommentBeforeInlineHTML() {
|
||||
$prettyPrinter = new PrettyPrinter\Standard;
|
||||
$comment = new Comment\Doc("/**\n * This is a comment\n */");
|
||||
$stmts = [new Stmt\InlineHTML('Hello World!', ['comments' => [$comment]])];
|
||||
$expected = "<?php\n\n/**\n * This is a comment\n */\n?>\nHello World!";
|
||||
$this->assertSame($expected, $prettyPrinter->prettyPrintFile($stmts));
|
||||
}
|
||||
|
||||
private function parseModeLine($modeLine) {
|
||||
$parts = explode(' ', (string) $modeLine, 2);
|
||||
$version = $parts[0] ?? 'both';
|
||||
$options = isset($parts[1]) ? json_decode($parts[1], true) : [];
|
||||
return [$version, $options];
|
||||
}
|
||||
|
||||
public function testArraySyntaxDefault() {
|
||||
$prettyPrinter = new Standard(['shortArraySyntax' => true]);
|
||||
$expr = new Expr\Array_([
|
||||
new Expr\ArrayItem(new String_('val'), new String_('key'))
|
||||
]);
|
||||
$expected = "['key' => 'val']";
|
||||
$this->assertSame($expected, $prettyPrinter->prettyPrintExpr($expr));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideTestKindAttributes
|
||||
*/
|
||||
public function testKindAttributes($node, $expected) {
|
||||
$prttyPrinter = new PrettyPrinter\Standard;
|
||||
$result = $prttyPrinter->prettyPrintExpr($node);
|
||||
$this->assertSame($expected, $result);
|
||||
}
|
||||
|
||||
public function provideTestKindAttributes() {
|
||||
$nowdoc = ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR'];
|
||||
$heredoc = ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR'];
|
||||
return [
|
||||
// Defaults to single quoted
|
||||
[new String_('foo'), "'foo'"],
|
||||
// Explicit single/double quoted
|
||||
[new String_('foo', ['kind' => String_::KIND_SINGLE_QUOTED]), "'foo'"],
|
||||
[new String_('foo', ['kind' => String_::KIND_DOUBLE_QUOTED]), '"foo"'],
|
||||
// Fallback from doc string if no label
|
||||
[new String_('foo', ['kind' => String_::KIND_NOWDOC]), "'foo'"],
|
||||
[new String_('foo', ['kind' => String_::KIND_HEREDOC]), '"foo"'],
|
||||
// Fallback if string contains label
|
||||
[new String_("A\nB\nC", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'A']), "'A\nB\nC'"],
|
||||
[new String_("A\nB\nC", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'B']), "'A\nB\nC'"],
|
||||
[new String_("A\nB\nC", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'C']), "'A\nB\nC'"],
|
||||
[new String_("STR;", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR']), "'STR;'"],
|
||||
// Doc string if label not contained (or not in ending position)
|
||||
[new String_("foo", $nowdoc), "<<<'STR'\nfoo\nSTR\n"],
|
||||
[new String_("foo", $heredoc), "<<<STR\nfoo\nSTR\n"],
|
||||
[new String_("STRx", $nowdoc), "<<<'STR'\nSTRx\nSTR\n"],
|
||||
[new String_("xSTR", $nowdoc), "<<<'STR'\nxSTR\nSTR\n"],
|
||||
// Empty doc string variations (encapsed variant does not occur naturally)
|
||||
[new String_("", $nowdoc), "<<<'STR'\nSTR\n"],
|
||||
[new String_("", $heredoc), "<<<STR\nSTR\n"],
|
||||
[new Encapsed([new EncapsedStringPart('')], $heredoc), "<<<STR\nSTR\n"],
|
||||
// Encapsed doc string variations
|
||||
[new Encapsed([new EncapsedStringPart('foo')], $heredoc), "<<<STR\nfoo\nSTR\n"],
|
||||
[new Encapsed([new EncapsedStringPart('foo'), new Expr\Variable('y')], $heredoc), "<<<STR\nfoo{\$y}\nSTR\n"],
|
||||
[new Encapsed([new EncapsedStringPart("\nSTR"), new Expr\Variable('y')], $heredoc), "<<<STR\n\nSTR{\$y}\nSTR\n"],
|
||||
[new Encapsed([new EncapsedStringPart("\nSTR"), new Expr\Variable('y')], $heredoc), "<<<STR\n\nSTR{\$y}\nSTR\n"],
|
||||
[new Encapsed([new Expr\Variable('y'), new EncapsedStringPart("STR\n")], $heredoc), "<<<STR\n{\$y}STR\n\nSTR\n"],
|
||||
// Encapsed doc string fallback
|
||||
[new Encapsed([new Expr\Variable('y'), new EncapsedStringPart("\nSTR")], $heredoc), '"{$y}\\nSTR"'],
|
||||
[new Encapsed([new EncapsedStringPart("STR\n"), new Expr\Variable('y')], $heredoc), '"STR\\n{$y}"'],
|
||||
[new Encapsed([new EncapsedStringPart("STR")], $heredoc), '"STR"'],
|
||||
];
|
||||
}
|
||||
|
||||
/** @dataProvider provideTestUnnaturalLiterals */
|
||||
public function testUnnaturalLiterals($node, $expected) {
|
||||
$prttyPrinter = new PrettyPrinter\Standard;
|
||||
$result = $prttyPrinter->prettyPrintExpr($node);
|
||||
$this->assertSame($expected, $result);
|
||||
}
|
||||
|
||||
public function provideTestUnnaturalLiterals() {
|
||||
return [
|
||||
[new LNumber(-1), '-1'],
|
||||
[new LNumber(-PHP_INT_MAX - 1), '(-' . PHP_INT_MAX . '-1)'],
|
||||
[new LNumber(-1, ['kind' => LNumber::KIND_BIN]), '-0b1'],
|
||||
[new LNumber(-1, ['kind' => LNumber::KIND_OCT]), '-01'],
|
||||
[new LNumber(-1, ['kind' => LNumber::KIND_HEX]), '-0x1'],
|
||||
[new DNumber(\INF), '\INF'],
|
||||
[new DNumber(-\INF), '-\INF'],
|
||||
[new DNumber(-\NAN), '\NAN'],
|
||||
];
|
||||
}
|
||||
|
||||
public function testPrettyPrintWithError() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('Cannot pretty-print AST with Error nodes');
|
||||
$stmts = [new Stmt\Expression(
|
||||
new Expr\PropertyFetch(new Expr\Variable('a'), new Expr\Error())
|
||||
)];
|
||||
$prettyPrinter = new PrettyPrinter\Standard;
|
||||
$prettyPrinter->prettyPrint($stmts);
|
||||
}
|
||||
|
||||
public function testPrettyPrintWithErrorInClassConstFetch() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('Cannot pretty-print AST with Error nodes');
|
||||
$stmts = [new Stmt\Expression(
|
||||
new Expr\ClassConstFetch(new Name('Foo'), new Expr\Error())
|
||||
)];
|
||||
$prettyPrinter = new PrettyPrinter\Standard;
|
||||
$prettyPrinter->prettyPrint($stmts);
|
||||
}
|
||||
|
||||
public function testPrettyPrintEncapsedStringPart() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('Cannot directly print EncapsedStringPart');
|
||||
$expr = new Node\Scalar\EncapsedStringPart('foo');
|
||||
$prettyPrinter = new PrettyPrinter\Standard;
|
||||
$prettyPrinter->prettyPrintExpr($expr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideTestFormatPreservingPrint
|
||||
* @covers \PhpParser\PrettyPrinter\Standard<extended>
|
||||
*/
|
||||
public function testFormatPreservingPrint($name, $code, $modification, $expected, $modeLine) {
|
||||
$lexer = new Lexer\Emulative([
|
||||
'usedAttributes' => [
|
||||
'comments',
|
||||
'startLine', 'endLine',
|
||||
'startTokenPos', 'endTokenPos',
|
||||
],
|
||||
]);
|
||||
|
||||
$parser = new Parser\Php7($lexer);
|
||||
$traverser = new NodeTraverser();
|
||||
$traverser->addVisitor(new NodeVisitor\CloningVisitor());
|
||||
|
||||
$printer = new PrettyPrinter\Standard();
|
||||
|
||||
$oldStmts = $parser->parse($code);
|
||||
$oldTokens = $lexer->getTokens();
|
||||
|
||||
$newStmts = $traverser->traverse($oldStmts);
|
||||
|
||||
/** @var callable $fn */
|
||||
eval(<<<CODE
|
||||
use PhpParser\Comment;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Scalar;
|
||||
use PhpParser\Node\Stmt;
|
||||
\$fn = function(&\$stmts) { $modification };
|
||||
CODE
|
||||
);
|
||||
$fn($newStmts);
|
||||
|
||||
$newCode = $printer->printFormatPreserving($newStmts, $oldStmts, $oldTokens);
|
||||
$this->assertSame(canonicalize($expected), canonicalize($newCode), $name);
|
||||
}
|
||||
|
||||
public function provideTestFormatPreservingPrint() {
|
||||
return $this->getTests(__DIR__ . '/../code/formatPreservation', 'test', 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideTestRoundTripPrint
|
||||
* @covers \PhpParser\PrettyPrinter\Standard<extended>
|
||||
*/
|
||||
public function testRoundTripPrint($name, $code, $expected, $modeLine) {
|
||||
/**
|
||||
* This test makes sure that the format-preserving pretty printer round-trips for all
|
||||
* the pretty printer tests (i.e. returns the input if no changes occurred).
|
||||
*/
|
||||
|
||||
list($version) = $this->parseModeLine($modeLine);
|
||||
|
||||
$lexer = new Lexer\Emulative([
|
||||
'usedAttributes' => [
|
||||
'comments',
|
||||
'startLine', 'endLine',
|
||||
'startTokenPos', 'endTokenPos',
|
||||
],
|
||||
]);
|
||||
|
||||
$parserClass = $version === 'php5' ? Parser\Php5::class : Parser\Php7::class;
|
||||
/** @var Parser $parser */
|
||||
$parser = new $parserClass($lexer);
|
||||
|
||||
$traverser = new NodeTraverser();
|
||||
$traverser->addVisitor(new NodeVisitor\CloningVisitor());
|
||||
|
||||
$printer = new PrettyPrinter\Standard();
|
||||
|
||||
try {
|
||||
$oldStmts = $parser->parse($code);
|
||||
} catch (Error $e) {
|
||||
// Can't do a format-preserving print on a file with errors
|
||||
return;
|
||||
}
|
||||
|
||||
$oldTokens = $lexer->getTokens();
|
||||
|
||||
$newStmts = $traverser->traverse($oldStmts);
|
||||
|
||||
$newCode = $printer->printFormatPreserving($newStmts, $oldStmts, $oldTokens);
|
||||
$this->assertSame(canonicalize($code), canonicalize($newCode), $name);
|
||||
}
|
||||
|
||||
public function provideTestRoundTripPrint() {
|
||||
return array_merge(
|
||||
$this->getTests(__DIR__ . '/../code/prettyPrinter', 'test'),
|
||||
$this->getTests(__DIR__ . '/../code/parser', 'test')
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue