testFilterWillApplyFiltering()   A
last analyzed

Complexity

Conditions 5
Paths 16

Size

Total Lines 57
Code Lines 38

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 38
c 1
b 0
f 0
nc 16
nop 1
dl 0
loc 57
rs 9.0008

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace ArpTest\DoctrineQueryFilter\Filter;
6
7
use Arp\DoctrineQueryFilter\Enum\WhereType;
8
use Arp\DoctrineQueryFilter\Filter\Exception\FilterException;
9
use Arp\DoctrineQueryFilter\Filter\FilterInterface;
10
use Doctrine\ORM\Query\Expr;
11
use PHPUnit\Framework\MockObject\MockObject;
12
13
abstract class AbstractComparisonTest extends AbstractFilterTest
14
{
15
    protected FilterInterface $filter;
16
17
    protected string $filterClassName;
18
19
    protected string $expressionMethodName;
20
21
    protected string $expressionSymbol;
22
23
    public function setUp(): void
24
    {
25
        parent::setUp();
26
27
        /** @var FilterInterface $filter */
28
        $filter = new $this->filterClassName($this->queryFilterManager, $this->typecaster, $this->paramNameGenerator);
29
        $this->filter = $filter;
30
    }
31
32
    /**
33
     * Assert that the filter implements FilterInterface
34
     */
35
    public function testImplementsFilterInterface(): void
36
    {
37
        $this->assertInstanceOf(FilterInterface::class, $this->filter);
38
    }
39
40
    /**
41
     * Assert that the query filter can be applied with the provided $criteria
42
     *
43
     * @dataProvider getFilterWillApplyFilteringData
44
     *
45
     * @throws FilterException
46
     */
47
    public function testFilterWillApplyFiltering(array $criteria): void
48
    {
49
        $fieldName = $criteria['field'] ?? 'testFieldName';
50
        $alias = $criteria['alias'] ?? null;
51
52
        $this->metadata->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not exist on Arp\DoctrineQueryFilter\Metadata\MetadataInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

52
        $this->metadata->/** @scrutinizer ignore-call */ 
53
                         expects($this->once())

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
53
            ->method('hasField')
54
            ->with($fieldName)
55
            ->willReturn(true);
56
57
        /** @var Expr&MockObject $expr */
58
        $expr = $this->createMock(Expr::class);
59
60
        $this->queryBuilder->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not exist on Arp\DoctrineQueryFilter\QueryBuilderInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

60
        $this->queryBuilder->/** @scrutinizer ignore-call */ 
61
                             expects($this->once())

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
61
            ->method('expr')
62
            ->willReturn($expr);
63
64
        /** @var Expr\Comparison&MockObject $comparisonExpr */
65
        $comparisonExpr = $this->createMock(Expr\Comparison::class);
66
67
        if (null === $alias) {
68
            $alias = 'entity';
69
            $this->queryBuilder->expects($this->once())
70
                ->method('getRootAlias')
71
                ->willReturn($alias);
72
        }
73
74
        $expressionString = $this->getExpressionString($fieldName, $alias, $criteria);
75
76
        $expr->expects($this->once())
77
            ->method($this->expressionMethodName)
78
            ->willReturn($comparisonExpr);
79
80
        $comparisonExpr->expects($this->once())
81
            ->method('__toString')
82
            ->willReturn($expressionString);
83
84
        $methodName = (!isset($criteria['where']) || WhereType::AND === $criteria['where'])
85
            ? 'andWhere'
86
            : 'orWhere';
87
88
        $this->queryBuilder->expects($this->once())->method($methodName);
89
90
        if (array_key_exists('value', $criteria)) {
91
            $this->typecaster->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not exist on Arp\DoctrineQueryFilter\...ata\TypecasterInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

91
            $this->typecaster->/** @scrutinizer ignore-call */ 
92
                               expects($this->once())

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
92
                ->method('typecast')
93
                ->with($this->metadata, $fieldName, $criteria['value'])
94
                ->willReturn($criteria['value']);
95
96
            $this->queryBuilder->expects($this->once())
97
                ->method('setParameter')
98
                ->with($this->callback(static function ($argument) {
99
                    return is_string($argument);
100
                }), $criteria['value']);
101
        }
102
103
        $this->filter->filter($this->queryBuilder, $this->metadata, $criteria);
104
    }
105
106
    abstract public function getFilterWillApplyFilteringData(): array;
107
108
    protected function getExpressionString(string $fieldName, ?string $alias, array $criteria): string
109
    {
110
        $expressionString = $alias . '.' . $fieldName . ' ' . $this->expressionSymbol;
111
        if (array_key_exists('value', $criteria)) {
112
            $expressionString .= ' :param_name';
113
        }
114
        return $expressionString;
115
    }
116
}
117