123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315 |
- <?php
- declare(strict_types=1);
- /*
- * This file is part of the league/commonmark package.
- *
- * (c) Colin O'Dell <colinodell@gmail.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
- namespace League\CommonMark\Tests\Unit\Node;
- use League\CommonMark\Node\Node;
- use League\CommonMark\Node\Query;
- use PHPUnit\Framework\TestCase;
- final class QueryTest extends TestCase
- {
- public function testFindOne(): void
- {
- $result = (new Query())
- ->where(static function (Node $node): bool {
- return $node->data->get('number') === 7;
- })
- ->findOne($this->createAST());
- $this->assertNotNull($result);
- $this->assertSame(7, $result->data->get('number'));
- }
- public function testFindOneWhenNothingMatches(): void
- {
- $result = (new Query())
- ->where(Query::hasParent())
- ->findOne(new SimpleNode());
- $this->assertNull($result);
- }
- public function testFindOneWithNoCriteria(): void
- {
- $result = (new Query())
- ->findOne($this->createAST());
- $this->assertNotNull($result);
- $this->assertSame(1, $result->data->get('number'));
- }
- public function testFindAll(): void
- {
- $result = (new Query())
- ->where(Query::hasParent())
- ->findAll($this->createAST());
- $result = \iterator_to_array($result);
- $this->assertCount(6, $result);
- // The order is based on node walking
- $this->assertSame(2, $result[0]->data->get('number'));
- $this->assertSame(3, $result[1]->data->get('number'));
- $this->assertSame(6, $result[2]->data->get('number'));
- $this->assertSame(4, $result[3]->data->get('number'));
- $this->assertSame(7, $result[4]->data->get('number'));
- $this->assertSame(5, $result[5]->data->get('number'));
- }
- public function testFindAllWithLimit(): void
- {
- $result = (new Query())
- ->where(Query::hasParent())
- ->findAll($this->createAST(), 3);
- $result = \iterator_to_array($result);
- $this->assertCount(3, $result);
- $this->assertSame(2, $result[0]->data->get('number'));
- $this->assertSame(3, $result[1]->data->get('number'));
- $this->assertSame(6, $result[2]->data->get('number'));
- }
- public function testFindAllWithMixedConditions(): void
- {
- $ast = $this->createAST();
- // "class is SimpleNode AND has parent"
- $query = (new Query())->where(Query::type(SimpleNode::class), Query::hasParent());
- $this->assertCount(6, $query->findAll($ast));
- // "class is SimpleNode AND has parent AND number > 2"
- $query->andWhere(static function (Node $node): bool {
- return $node->data->get('number') > 2;
- });
- $this->assertCount(5, $query->findAll($ast));
- // "class is SimpleNode AND has parent AND number > 2 AND number > 3 AND number > 7"
- $query->andWhere(
- static function (Node $node): bool {
- return $node->data->get('number') > 3;
- },
- static function (Node $node): bool {
- return $node->data->get('number') < 7;
- }
- );
- $this->assertCount(3, $query->findAll($ast));
- // "has child OR (class is SimpleNode AND has parent AND number > 2 AND number > 3 AND number > 7)"
- $query->orWhere(Query::hasChild());
- $this->assertCount(5, $query->findAll($ast));
- // "has child OR (class is SimpleNode AND has parent AND number > 2 AND number > 3 AND number > 7) OR has parent OR class is SimpleNode"
- $query->orWhere(Query::hasParent(), Query::type(SimpleNode::class));
- $this->assertCount(7, $query->findAll($ast));
- // "number > 4 AND (has child OR (class is SimpleNode AND has parent AND number > 2 AND number > 3 AND number > 7) OR has parent OR class is SimpleNode)"
- $query->andWhere(static function (Node $node): bool {
- return $node->data->get('number') > 4;
- });
- $this->assertCount(3, $query->findAll($ast));
- }
- public function testWhereUsingExpressionInterface(): void
- {
- $query = (new Query())->where(new class implements Query\ExpressionInterface {
- public function __invoke(Node $node): bool
- {
- return $node->data->get('number') % 2 === 0;
- }
- });
- $this->assertCount(3, $query->findAll($this->createAST()));
- }
- public function testWhereClausesUsingExpressionInterface(): void
- {
- $hasEvenNumber = new class implements Query\ExpressionInterface {
- public function __invoke(Node $node): bool
- {
- return $node->data->get('number') % 2 === 0;
- }
- };
- $greaterThanThree = new class implements Query\ExpressionInterface {
- public function __invoke(Node $node): bool
- {
- return $node->data->get('number') > 3;
- }
- };
- $isNumberFive = new class implements Query\ExpressionInterface {
- public function __invoke(Node $node): bool
- {
- return $node->data->get('number') === 5;
- }
- };
- $result = (new Query())
- ->where($hasEvenNumber)
- ->orWhere($isNumberFive)
- ->andWhere($greaterThanThree)
- ->findAll($this->createAST());
- $result = \iterator_to_array($result);
- $this->assertCount(3, $result);
- $this->assertSame(6, $result[0]->data->get('number'));
- $this->assertSame(4, $result[1]->data->get('number'));
- $this->assertSame(5, $result[2]->data->get('number'));
- }
- public function testOrWhereUsingExpressionInterface(): void
- {
- $query = (new Query())
- ->where(Query::hasChild())
- ->orWhere(
- new class implements Query\ExpressionInterface {
- public function __invoke(Node $node): bool
- {
- return $node->data->get('number') % 2 === 0;
- }
- }
- );
- $this->assertCount(5, $query->findAll($this->createAST()));
- }
- public function testFindAllWhenNothingMatches(): void
- {
- $result = (new Query())
- ->where(static function (Node $node): bool {
- return false;
- })
- ->findAll($this->createAST());
- $this->assertCount(0, $result);
- }
- public function testFindAllWithNoCriteria(): void
- {
- $result = (new Query())->findAll($this->createAST());
- $this->assertCount(7, $result);
- }
- public function testType(): void
- {
- $test = Query::type(SimpleNode::class);
- $this->assertTrue($test(new SimpleNode()));
- $this->assertFalse($test($this->createMock(Node::class)));
- }
- public function testHasChild(): void
- {
- $test = Query::hasChild();
- $parent = new SimpleNode();
- $child = new SimpleNode();
- $parent->appendChild($child);
- $this->assertTrue($test($parent));
- $this->assertFalse($test($child));
- }
- public function testHasChildWithCondition(): void
- {
- $test = Query::hasChild(static function (Node $node): bool {
- return $node->data->has('test');
- });
- $parent = new SimpleNode();
- $child = new SimpleNode();
- $parent->appendChild($child);
- $this->assertFalse($test($parent));
- $this->assertFalse($test($child));
- $child->data->set('test', true);
- $this->assertTrue($test($parent));
- $this->assertFalse($test($child));
- }
- public function testHasParent(): void
- {
- $test = Query::hasParent();
- $parent = new SimpleNode();
- $child = new SimpleNode();
- $parent->appendChild($child);
- $this->assertFalse($test($parent));
- $this->assertTrue($test($child));
- }
- public function testHasParentWithCondition(): void
- {
- $test = Query::hasParent(static function (Node $node): bool {
- return $node->data->has('test');
- });
- $parent = new SimpleNode();
- $child = new SimpleNode();
- $parent->appendChild($child);
- $this->assertFalse($test($parent));
- $this->assertFalse($test($child));
- $parent->data->set('test', true);
- $this->assertFalse($test($parent));
- $this->assertTrue($test($child));
- }
- private function createAST(): Node
- {
- $parent = new SimpleNode();
- $parent->data->set('number', 1);
- $child1 = new SimpleNode();
- $child1->data->set('number', 2);
- $parent->appendChild($child1);
- $child2 = new SimpleNode();
- $child2->data->set('number', 3);
- $parent->appendChild($child2);
- $child3 = new SimpleNode();
- $child3->data->set('number', 4);
- $parent->appendChild($child3);
- $child4 = new SimpleNode();
- $child4->data->set('number', 5);
- $parent->appendChild($child4);
- $grandchild1 = new SimpleNode();
- $grandchild1->data->set('number', 6);
- $child2->appendChild($grandchild1);
- $grandchild2 = new SimpleNode();
- $grandchild2->data->set('number', 7);
- $child3->appendChild($grandchild2);
- return $parent;
- }
- }
|