Completed
Push — patch-meta ( 5bd3e7 )
by Tobias
08:29
created

it_should_modify_query()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 14
rs 9.4285
cc 1
eloc 10
nc 1
nop 4
1
<?php
2
3
namespace tests\Happyr\DoctrineSpecification;
4
5
use Doctrine\ORM\AbstractQuery;
6
use Doctrine\ORM\EntityManager;
7
use Doctrine\ORM\Mapping\ClassMetadata;
8
use Doctrine\ORM\NonUniqueResultException;
9
use Doctrine\ORM\NoResultException;
10
use Doctrine\ORM\QueryBuilder;
11
use Happyr\DoctrineSpecification\EntitySpecificationRepository;
12
use Happyr\DoctrineSpecification\Filter\Filter;
13
use Happyr\DoctrineSpecification\Query\QueryModifier;
14
use Happyr\DoctrineSpecification\Result\ResultModifier;
15
use Happyr\DoctrineSpecification\Specification\Specification;
16
use PhpSpec\ObjectBehavior;
17
use Prophecy\Argument;
18
19
/**
20
 * @mixin EntitySpecificationRepository
21
 */
22
class EntitySpecificationRepositorySpec extends ObjectBehavior
23
{
24
    private $alias = 'e';
25
    private $expression = 'expression';
26
    private $result = 'result';
27
28
    public function let(EntityManager $entityManager, ClassMetadata $classMetadata)
29
    {
30
        $this->beConstructedWith($entityManager, $classMetadata);
31
    }
32
33
    public function it_should_modify_query(
34
        QueryModifier $specification,
35
        EntityManager $entityManager,
36
        QueryBuilder $qb,
37
        AbstractQuery $query
38
    ) {
39
        $this->prepareEntityManagerStub($entityManager, $qb);
40
        $this->prepareQueryBuilderStub($qb, $query);
41
        $query->execute()->willReturn($this->result);
42
43
        $specification->modify($qb, $this->alias)->shouldBeCalled();
44
45
        $this->match($specification);
46
    }
47
48 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...
49
        Filter $specification,
50
        EntityManager $entityManager,
51
        QueryBuilder $qb,
52
        AbstractQuery $query
53
    ) {
54
        $this->prepareEntityManagerStub($entityManager, $qb);
55
        $this->prepareQueryBuilderStub($qb, $query);
56
        $specification->getFilter($qb, $this->alias)->willReturn($this->expression);
57
58
        $qb->andWhere($this->expression)->willReturn($qb);
59
        $qb->where()->shouldNotBeCalled();
60
61
        $this->match($specification);
62
    }
63
64
    public function it_should_skip_apply_empty_specification(
65
        EntityManager $entityManager,
66
        QueryBuilder $qb,
67
        AbstractQuery $query
68
    ) {
69
        $this->prepareEntityManagerStub($entityManager, $qb);
70
        $this->prepareQueryBuilderStub($qb, $query);
71
72
        $qb->andWhere()->shouldNotBeCalled();
73
        $qb->where()->shouldNotBeCalled();
74
75
        $this->match(null);
76
    }
77
78
    public function it_should_throw_exception_when_apply_not_specification(
79
        EntityManager $entityManager,
80
        QueryBuilder $qb,
81
        AbstractQuery $query
82
    ) {
83
        $this->prepareEntityManagerStub($entityManager, $qb);
84
        $this->prepareQueryBuilderStub($qb, $query);
85
86
        $this->shouldThrow('\InvalidArgumentException')->duringMatch(new \stdClass());
87
        $this->shouldThrow('\InvalidArgumentException')->duringMatch(['fake', 'array']);
88
        $this->shouldThrow('\InvalidArgumentException')->duringMatch('fake');
89
    }
90
91
    public function it_matches_a_specification_with_empty_filter(
92
        Specification $specification,
93
        EntityManager $entityManager,
94
        QueryBuilder $qb,
95
        AbstractQuery $query
96
    ) {
97
        $this->prepareEntityManagerStub($entityManager, $qb);
98
        $this->prepareQueryBuilderStub($qb, $query);
99
        $query->execute()->willReturn($this->result);
100
101
        $qb->andWhere()->shouldNotBeCalled();
102
        $qb->where()->shouldNotBeCalled();
103
104
        $this->match($specification)->shouldReturn($this->result);
105
    }
106
107
    public function it_matches_a_specification_without_result_modifier(
108
        Specification $specification,
109
        EntityManager $entityManager,
110
        QueryBuilder $qb,
111
        AbstractQuery $query
112
    ) {
113
        $this->prepareStubs($specification, $entityManager, $qb, $query);
114
        $query->execute()->willReturn($this->result);
115
116
        $specification->modify($qb, $this->alias)->shouldBeCalled();
117
118
        $this->match($specification)->shouldReturn($this->result);
119
    }
120
121 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...
122
        Specification $specification,
123
        EntityManager $entityManager,
124
        QueryBuilder $qb,
125
        AbstractQuery $query
126
    ) {
127
        $singleResult = new \stdClass();
128
129
        $this->prepareStubs($specification, $entityManager, $qb, $query);
130
131
        $specification->modify($qb, $this->alias)->shouldBeCalled();
132
133
        $query->getSingleResult()->willReturn($singleResult);
134
135
        $this->matchSingleResult($specification)->shouldReturn($singleResult);
136
    }
137
138 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...
139
        Specification $specification,
140
        EntityManager $entityManager,
141
        QueryBuilder $qb,
142
        AbstractQuery $query
143
    ) {
144
        $this->prepareStubs($specification, $entityManager, $qb, $query);
145
146
        $specification->modify($qb, $this->alias)->shouldBeCalled();
147
148
        $query->getSingleResult()->willThrow(new NoResultException());
149
150
        $this->shouldThrow('Happyr\DoctrineSpecification\Exception\NoResultException')->duringMatchSingleResult($specification);
151
    }
152
153 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...
154
        Specification $specification,
155
        EntityManager $entityManager,
156
        QueryBuilder $qb,
157
        AbstractQuery $query
158
    ) {
159
        $this->prepareStubs($specification, $entityManager, $qb, $query);
160
161
        $specification->modify($qb, $this->alias)->shouldBeCalled();
162
163
        $query->getSingleResult()->willThrow(new NonUniqueResultException());
164
165
        $this->shouldThrow('Happyr\DoctrineSpecification\Exception\NonUniqueResultException')->duringMatchSingleResult($specification);
166
    }
167
168 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...
169
        Specification $specification,
170
        EntityManager $entityManager,
171
        QueryBuilder $qb,
172
        AbstractQuery $query
173
    ) {
174
        $singleResult = new \stdClass();
175
176
        $this->prepareStubs($specification, $entityManager, $qb, $query);
177
178
        $specification->modify($qb, $this->alias)->shouldBeCalled();
179
180
        $query->getSingleResult()->willReturn($singleResult);
181
182
        $this->matchOneOrNullResult($specification)->shouldReturn($singleResult);
183
    }
184
185 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...
186
        Specification $specification,
187
        EntityManager $entityManager,
188
        QueryBuilder $qb,
189
        AbstractQuery $query
190
    ) {
191
        $this->prepareStubs($specification, $entityManager, $qb, $query);
192
193
        $specification->modify($qb, $this->alias)->shouldBeCalled();
194
195
        $query->getSingleResult()->willThrow(new NonUniqueResultException());
196
197
        $this->shouldThrow('Happyr\DoctrineSpecification\Exception\NonUniqueResultException')->duringMatchOneOrNullResult($specification);
198
    }
199
200 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...
201
        Specification $specification,
202
        EntityManager $entityManager,
203
        QueryBuilder $qb,
204
        AbstractQuery $query
205
    ) {
206
        $this->prepareStubs($specification, $entityManager, $qb, $query);
207
208
        $specification->modify($qb, $this->alias)->shouldBeCalled();
209
210
        $query->getSingleResult()->willThrow(new NonUniqueResultException());
211
212
        $this->shouldThrow('Happyr\DoctrineSpecification\Exception\UnexpectedResultException')->duringMatchOneOrNullResult($specification);
213
    }
214
215 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...
216
        Specification $specification,
217
        EntityManager $entityManager,
218
        QueryBuilder $qb,
219
        AbstractQuery $query,
220
        ResultModifier $modifier
221
    ) {
222
        $this->prepareStubs($specification, $entityManager, $qb, $query);
223
        $query->execute()->willReturn($this->result);
224
225
        $specification->modify($qb, $this->alias)->shouldBeCalled();
226
        $modifier->modify($query)->shouldBeCalled();
227
228
        $this->match($specification, $modifier)->shouldReturn($this->result);
229
    }
230
231
    private function prepareStubs(Specification $specification, EntityManager $entityManager, QueryBuilder $qb, AbstractQuery $query)
232
    {
233
        $this->prepareEntityManagerStub($entityManager, $qb);
234
        $this->prepareSpecificationStub($specification, $qb);
235
        $this->prepareQueryBuilderStub($qb, $query);
236
    }
237
238
    private function prepareEntityManagerStub(EntityManager $entityManager, QueryBuilder $qb)
239
    {
240
        $entityManager->createQueryBuilder()->willReturn($qb);
241
    }
242
243
    private function prepareSpecificationStub(Specification $specification, QueryBuilder $qb)
244
    {
245
        $specification->getFilter($qb, $this->alias)->willReturn($this->expression);
246
    }
247
248
    private function prepareQueryBuilderStub(QueryBuilder $qb, Query $query)
249
    {
250
        $qb->from(Argument::any(), $this->alias, null)->willReturn($qb);
251
        $qb->select($this->alias)->willReturn($qb);
252
        $qb->andWhere($this->expression)->willReturn($qb);
253
        $qb->getQuery()->willReturn($query);
254
    }
255
}
256