Completed
Push — 2.0 ( 5877a9...9fa07d )
by Peter
07:07 queued 10s
created

EntitySpecificationRepositorySpec   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 280
Duplicated Lines 62.86 %

Coupling/Cohesion

Components 1
Dependencies 11

Importance

Changes 0
Metric Value
wmc 20
lcom 1
cbo 11
dl 176
loc 280
rs 10
c 0
b 0
f 0

20 Methods

Rating   Name   Duplication   Size   Complexity  
A let() 0 4 1
A it_should_modify_query() 14 14 1
A it_should_apply_filter() 16 16 1
A it_should_skip_apply_empty_specification() 0 13 1
A it_matches_a_specification_with_empty_filter() 0 18 1
A it_matches_a_specification_without_result_modifier() 13 13 1
A it_matches_a_single_result_without_result_modifier() 16 16 1
A it_throws_exception_when_expecting_single_result_finding_none_without_result_modifier() 14 14 1
A it_throws_exception_when_expecting_single_result_finding_multiple_without_result_modifier() 14 14 1
A it_matches_a_single_scalar_result_without_result_modifier() 16 16 1
A it_throws_exception_when_expecting_single_scalar_result_finding_multiple_without_result_modifier() 14 14 1
A it_matches_a_scalar_result_when_expecting_one_or_null_without_result_modifier() 0 16 1
A it_matches_a_single_result_when_expecting_one_or_null_without_result_modifier() 16 16 1
A it_matches_null_when_expecting_one_or_null_without_result_modifier() 14 14 1
A it_throws_exception_when_expecting_one_or_null_finding_multiple_without_result_modifier() 14 14 1
A it_matches_a_specification_with_result_modifier() 15 15 1
A prepareStubs() 0 10 1
A prepareEntityManagerStub() 0 4 1
A prepareSpecificationStub() 0 4 1
A prepareQueryBuilderStub() 0 7 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * This file is part of the Happyr Doctrine Specification package.
6
 *
7
 * (c) Tobias Nyholm <[email protected]>
8
 *     Kacper Gunia <[email protected]>
9
 *     Peter Gribanov <[email protected]>
10
 *
11
 * For the full copyright and license information, please view the LICENSE
12
 * file that was distributed with this source code.
13
 */
14
15
namespace tests\Happyr\DoctrineSpecification\Repository;
16
17
use Doctrine\ORM\AbstractQuery;
18
use Doctrine\ORM\EntityManager;
19
use Doctrine\ORM\Mapping\ClassMetadata;
20
use Doctrine\ORM\NonUniqueResultException as DoctrineNonUniqueResultException;
21
use Doctrine\ORM\NoResultException as DoctrineNoResultException;
22
use Doctrine\ORM\QueryBuilder;
23
use Happyr\DoctrineSpecification\Exception\NonUniqueResultException;
24
use Happyr\DoctrineSpecification\Exception\NoResultException;
25
use Happyr\DoctrineSpecification\Exception\UnexpectedResultException;
26
use Happyr\DoctrineSpecification\Filter\Filter;
27
use Happyr\DoctrineSpecification\Query\QueryModifier;
28
use Happyr\DoctrineSpecification\Repository\EntitySpecificationRepository;
29
use Happyr\DoctrineSpecification\Result\ResultModifier;
30
use Happyr\DoctrineSpecification\Specification\Specification;
31
use PhpSpec\ObjectBehavior;
32
use Prophecy\Argument;
33
34
/**
35
 * @mixin EntitySpecificationRepository
36
 */
37
final class EntitySpecificationRepositorySpec extends ObjectBehavior
38
{
39
    private $alias = 'root';
40
41
    private $expression = 'expression';
42
43
    private $result = 'result';
44
45
    public function let(EntityManager $entityManager, ClassMetadata $classMetadata): void
46
    {
47
        $this->beConstructedWith($entityManager, $classMetadata);
48
    }
49
50 View Code Duplication
    public function it_should_modify_query(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
51
        QueryModifier $specification,
52
        EntityManager $entityManager,
53
        QueryBuilder $qb,
54
        AbstractQuery $query
55
    ): void {
56
        $this->prepareEntityManagerStub($entityManager, $qb);
57
        $this->prepareQueryBuilderStub($qb, $query);
58
        $query->execute()->willReturn($this->result);
59
60
        $specification->modify($qb, $this->alias)->shouldBeCalled();
61
62
        $this->match($specification);
63
    }
64
65 View Code Duplication
    public function it_should_apply_filter(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
66
        Filter $specification,
67
        EntityManager $entityManager,
68
        QueryBuilder $qb,
69
        AbstractQuery $query
70
    ): void {
71
        $this->prepareEntityManagerStub($entityManager, $qb);
72
        $this->prepareQueryBuilderStub($qb, $query);
73
74
        $specification->getFilter($qb, $this->alias)->willReturn($this->expression);
75
76
        $qb->andWhere($this->expression)->willReturn($qb);
77
        $qb->where()->shouldNotBeCalled();
78
79
        $this->match($specification);
80
    }
81
82
    public function it_should_skip_apply_empty_specification(
83
        EntityManager $entityManager,
84
        QueryBuilder $qb,
85
        AbstractQuery $query
86
    ): void {
87
        $this->prepareEntityManagerStub($entityManager, $qb);
88
        $this->prepareQueryBuilderStub($qb, $query);
89
90
        $qb->andWhere()->shouldNotBeCalled();
91
        $qb->where()->shouldNotBeCalled();
92
93
        $this->match(null);
94
    }
95
96
    public function it_matches_a_specification_with_empty_filter(
97
        Specification $specification,
98
        EntityManager $entityManager,
99
        QueryBuilder $qb,
100
        AbstractQuery $query
101
    ): void {
102
        $this->prepareEntityManagerStub($entityManager, $qb);
103
        $this->prepareQueryBuilderStub($qb, $query);
104
        $query->execute()->willReturn($this->result);
105
106
        $specification->modify($qb, $this->alias)->shouldBeCalled();
107
        $specification->getFilter($qb, $this->alias)->willReturn('');
108
109
        $qb->andWhere()->shouldNotBeCalled();
110
        $qb->where()->shouldNotBeCalled();
111
112
        $this->match($specification)->shouldReturn($this->result);
113
    }
114
115 View Code Duplication
    public function it_matches_a_specification_without_result_modifier(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
116
        Specification $specification,
117
        EntityManager $entityManager,
118
        QueryBuilder $qb,
119
        AbstractQuery $query
120
    ): void {
121
        $this->prepareStubs($specification, $entityManager, $qb, $query);
122
        $query->execute()->willReturn($this->result);
123
124
        $specification->modify($qb, $this->alias)->shouldBeCalled();
125
126
        $this->match($specification)->shouldReturn($this->result);
127
    }
128
129 View Code Duplication
    public function it_matches_a_single_result_without_result_modifier(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
130
        Specification $specification,
131
        EntityManager $entityManager,
132
        QueryBuilder $qb,
133
        AbstractQuery $query
134
    ): void {
135
        $singleResult = new \stdClass();
136
137
        $this->prepareStubs($specification, $entityManager, $qb, $query);
138
139
        $specification->modify($qb, $this->alias)->shouldBeCalled();
140
141
        $query->getSingleResult()->willReturn($singleResult);
142
143
        $this->matchSingleResult($specification)->shouldReturn($singleResult);
144
    }
145
146 View Code Duplication
    public function it_throws_exception_when_expecting_single_result_finding_none_without_result_modifier(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
147
        Specification $specification,
148
        EntityManager $entityManager,
149
        QueryBuilder $qb,
150
        AbstractQuery $query
151
    ): void {
152
        $this->prepareStubs($specification, $entityManager, $qb, $query);
153
154
        $specification->modify($qb, $this->alias)->shouldBeCalled();
155
156
        $query->getSingleResult()->willThrow(new DoctrineNoResultException());
157
158
        $this->shouldThrow(NoResultException::class)->duringMatchSingleResult($specification);
159
    }
160
161 View Code Duplication
    public function it_throws_exception_when_expecting_single_result_finding_multiple_without_result_modifier(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
162
        Specification $specification,
163
        EntityManager $entityManager,
164
        QueryBuilder $qb,
165
        AbstractQuery $query
166
    ): void {
167
        $this->prepareStubs($specification, $entityManager, $qb, $query);
168
169
        $specification->modify($qb, $this->alias)->shouldBeCalled();
170
171
        $query->getSingleResult()->willThrow(new DoctrineNonUniqueResultException());
172
173
        $this->shouldThrow(NonUniqueResultException::class)->duringMatchSingleResult($specification);
174
    }
175
176 View Code Duplication
    public function it_matches_a_single_scalar_result_without_result_modifier(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
177
        Specification $specification,
178
        EntityManager $entityManager,
179
        QueryBuilder $qb,
180
        AbstractQuery $query
181
    ): void {
182
        $singleScalarResult = '1';
183
184
        $this->prepareStubs($specification, $entityManager, $qb, $query);
185
186
        $specification->modify($qb, $this->alias)->shouldBeCalled();
187
188
        $query->getSingleScalarResult()->willReturn($singleScalarResult);
189
190
        $this->matchSingleScalarResult($specification)->shouldReturn($singleScalarResult);
191
    }
192
193 View Code Duplication
    public function it_throws_exception_when_expecting_single_scalar_result_finding_multiple_without_result_modifier(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
194
        Specification $specification,
195
        EntityManager $entityManager,
196
        QueryBuilder $qb,
197
        AbstractQuery $query
198
    ): void {
199
        $this->prepareStubs($specification, $entityManager, $qb, $query);
200
201
        $specification->modify($qb, $this->alias)->shouldBeCalled();
202
203
        $query->getSingleScalarResult()->willThrow(new DoctrineNonUniqueResultException());
204
205
        $this->shouldThrow(NonUniqueResultException::class)->duringMatchSingleScalarResult($specification);
206
    }
207
208
    public function it_matches_a_scalar_result_when_expecting_one_or_null_without_result_modifier(
209
        Specification $specification,
210
        EntityManager $entityManager,
211
        QueryBuilder $qb,
212
        AbstractQuery $query
213
    ): void {
214
        $scalarResult = ['1', '2', '3'];
215
216
        $this->prepareStubs($specification, $entityManager, $qb, $query);
217
218
        $specification->modify($qb, $this->alias)->shouldBeCalled();
219
220
        $query->getScalarResult()->willReturn($scalarResult);
221
222
        $this->matchScalarResult($specification)->shouldReturn($scalarResult);
223
    }
224
225 View Code Duplication
    public function it_matches_a_single_result_when_expecting_one_or_null_without_result_modifier(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
226
        Specification $specification,
227
        EntityManager $entityManager,
228
        QueryBuilder $qb,
229
        AbstractQuery $query
230
    ): void {
231
        $singleResult = new \stdClass();
232
233
        $this->prepareStubs($specification, $entityManager, $qb, $query);
234
235
        $specification->modify($qb, $this->alias)->shouldBeCalled();
236
237
        $query->getSingleResult()->willReturn($singleResult);
238
239
        $this->matchOneOrNullResult($specification)->shouldReturn($singleResult);
240
    }
241
242 View Code Duplication
    public function it_matches_null_when_expecting_one_or_null_without_result_modifier(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
243
        Specification $specification,
244
        EntityManager $entityManager,
245
        QueryBuilder $qb,
246
        AbstractQuery $query
247
    ): void {
248
        $this->prepareStubs($specification, $entityManager, $qb, $query);
249
250
        $specification->modify($qb, $this->alias)->shouldBeCalled();
251
252
        $query->getSingleResult()->willThrow(new DoctrineNonUniqueResultException());
253
254
        $this->shouldThrow(NonUniqueResultException::class)->duringMatchOneOrNullResult($specification);
255
    }
256
257 View Code Duplication
    public function it_throws_exception_when_expecting_one_or_null_finding_multiple_without_result_modifier(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
258
        Specification $specification,
259
        EntityManager $entityManager,
260
        QueryBuilder $qb,
261
        AbstractQuery $query
262
    ): void {
263
        $this->prepareStubs($specification, $entityManager, $qb, $query);
264
265
        $specification->modify($qb, $this->alias)->shouldBeCalled();
266
267
        $query->getSingleResult()->willThrow(new DoctrineNonUniqueResultException());
268
269
        $this->shouldThrow(UnexpectedResultException::class)->duringMatchOneOrNullResult($specification);
270
    }
271
272 View Code Duplication
    public function it_matches_a_specification_with_result_modifier(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
273
        Specification $specification,
274
        EntityManager $entityManager,
275
        QueryBuilder $qb,
276
        AbstractQuery $query,
277
        ResultModifier $modifier
278
    ): void {
279
        $this->prepareStubs($specification, $entityManager, $qb, $query);
280
        $query->execute()->willReturn($this->result);
281
282
        $specification->modify($qb, $this->alias)->shouldBeCalled();
283
        $modifier->modify($query)->shouldBeCalled();
284
285
        $this->match($specification, $modifier)->shouldReturn($this->result);
286
    }
287
288
    private function prepareStubs(
289
        Specification $specification,
290
        EntityManager $entityManager,
291
        QueryBuilder $qb,
292
        AbstractQuery $query
293
    ): void {
294
        $this->prepareEntityManagerStub($entityManager, $qb);
295
        $this->prepareSpecificationStub($specification, $qb);
296
        $this->prepareQueryBuilderStub($qb, $query);
297
    }
298
299
    private function prepareEntityManagerStub(EntityManager $entityManager, QueryBuilder $qb): void
300
    {
301
        $entityManager->createQueryBuilder()->willReturn($qb);
302
    }
303
304
    private function prepareSpecificationStub(Specification $specification, QueryBuilder $qb): void
305
    {
306
        $specification->getFilter($qb, $this->alias)->willReturn($this->expression);
307
    }
308
309
    private function prepareQueryBuilderStub(QueryBuilder $qb, AbstractQuery $query): void
310
    {
311
        $qb->from(Argument::any(), $this->alias, null)->willReturn($qb);
312
        $qb->select($this->alias)->willReturn($qb);
313
        $qb->andWhere($this->expression)->willReturn($qb);
314
        $qb->getQuery()->willReturn($query);
315
    }
316
}
317