Completed
Push — master ( 3f65c6...83b473 )
by Vincent
02:48
created

TransactionalPointcutTest   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 142
Duplicated Lines 40.14 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 2
Bugs 1 Features 0
Metric Value
wmc 12
c 2
b 1
f 0
lcom 1
cbo 5
dl 57
loc 142
rs 10

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
3
/**
4
 * Copyright 2016 Inneair
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 *
18
 * @license http://www.apache.org/licenses/LICENSE-2.0.html Apache-2.0
19
 */
20
21
namespace Inneair\TransactionBundle\Test\Aop;
22
23
use Doctrine\Common\Annotations\Reader;
24
use PHPUnit_Framework_MockObject_MockObject;
25
use Psr\Log\LoggerInterface;
26
use ReflectionClass;
27
use Inneair\TransactionBundle\Annotation\Transactional;
28
use Inneair\TransactionBundle\Aop\TransactionalPointcut;
29
use Inneair\TransactionBundle\DependencyInjection\Configuration;
30
use Inneair\TransactionBundle\Test\AbstractTest;
31
use Inneair\TransactionBundle\Test\Aop\Fixture\NonTransactionalAwareClass;
32
use Inneair\TransactionBundle\Test\Aop\Fixture\TransactionalAwareClass;
33
use Symfony\Component\DependencyInjection\ContainerInterface;
34
35
/**
36
 * Class containing test suite for the {@link TransactionalPointcut} class.
37
 */
38
class TransactionalPointcutTest extends AbstractTest
39
{
40
    /**
41
     * Mocked service container.
42
     * @var PHPUnit_Framework_MockObject_MockObject
43
     */
44
    private $container;
45
    /**
46
     * Mocked logger.
47
     * @var PHPUnit_Framework_MockObject_MockObject
48
     */
49
    private $logger;
50
    /**
51
     * Mocked annotation reader.
52
     * @var PHPUnit_Framework_MockObject_MockObject
53
     */
54
    private $reader;
55
56
    /**
57
     * {@inheritDoc}
58
     */
59
    public function setUp()
60
    {
61
        parent::setUp();
62
63
        $this->container = $this->getMock(ContainerInterface::class);
64
        $this->logger = $this->getMock(LoggerInterface::class);
65
        $this->reader = $this->getMock(Reader::class);
66
    }
67
68
    public function testMatchesNonTransactionalAwareClassWithoutStrictMode()
69
    {
70
        $this->assertTrue(
71
            $this->buildTransactionPointcut(false)->matchesClass(
72
                new ReflectionClass(NonTransactionalAwareClass::class)
73
            )
74
        );
75
    }
76
77
    public function testMatchesNonTransactionalAwareClassWithStrictMode()
78
    {
79
        $this->assertFalse(
80
            $this->buildTransactionPointcut(true)->matchesClass(
81
                new ReflectionClass(NonTransactionalAwareClass::class)
82
            )
83
        );
84
    }
85
86
    public function testMatchesTransactionalAwareClassWithStrictMode()
87
    {
88
        $this->assertTrue(
89
            $this->buildTransactionPointcut(true)->matchesClass(
90
                new ReflectionClass(TransactionalAwareClass::class)
91
            )
92
        );
93
    }
94
95
    public function testMatchesNonPublicMethod()
96
    {
97
        $class = new ReflectionClass(TransactionalAwareClass::class);
98
        $this->assertFalse($this->buildTransactionPointcut(false)->matchesMethod($class->getMethod('nonPublicMethod')));
99
        $this->assertFalse($this->buildTransactionPointcut(true)->matchesMethod($class->getMethod('nonPublicMethod')));
100
    }
101
102
    public function testMatchesAnnotatedPublicMethodWithDefaultPolicy()
103
    {
104
        $this->reader->expects(static::exactly(2))->method('getMethodAnnotation')->willReturn(new Transactional());
105
        $this->reader->expects(static::never())->method('getClassAnnotation');
106
107
        $class = new ReflectionClass(TransactionalAwareClass::class);
108
        $this->assertTrue($this->buildTransactionPointcut(true)->matchesMethod($class->getMethod('publicMethod')));
109
        $this->assertTrue($this->buildTransactionPointcut(false)->matchesMethod($class->getMethod('publicMethod')));
110
    }
111
112
    public function testMatchesAnnotatedPublicMethodWithNotRequiredPolicy()
113
    {
114
        $this->reader->expects(static::once())->method('getMethodAnnotation')->willReturn(
115
            new Transactional(array('policy' => Transactional::NOT_REQUIRED))
116
        );
117
        $this->reader->expects(static::never())->method('getClassAnnotation');
118
119
        $class = new ReflectionClass(TransactionalAwareClass::class);
120
        $this->assertTrue($this->buildTransactionPointcut(false)->matchesMethod($class->getMethod('publicMethod')));
121
    }
122
123
    public function testMatchesAnnotatedPublicMethodWithRequiredPolicy()
124
    {
125
        $this->reader->expects(static::once())->method('getMethodAnnotation')->willReturn(
126
            new Transactional(array('policy' => Transactional::REQUIRED))
127
        );
128
        $this->reader->expects(static::never())->method('getClassAnnotation');
129
130
        $class = new ReflectionClass(TransactionalAwareClass::class);
131
        $this->assertTrue($this->buildTransactionPointcut(false)->matchesMethod($class->getMethod('publicMethod')));
132
    }
133
134
    public function testMatchesAnnotatedPublicMethodWithNestedPolicy()
135
    {
136
        $this->reader->expects(static::once())->method('getMethodAnnotation')->willReturn(
137
            new Transactional(array('policy' => Transactional::NESTED))
138
        );
139
        $this->reader->expects(static::never())->method('getClassAnnotation');
140
141
        $class = new ReflectionClass(TransactionalAwareClass::class);
142
        $this->assertTrue($this->buildTransactionPointcut(false)->matchesMethod($class->getMethod('publicMethod')));
143
    }
144
145
    public function testMatchesUnannotatedPublicMethodInAnnotatedClass()
146
    {
147
        $this->reader->expects(static::exactly(2))->method('getMethodAnnotation')->willReturn(null);
148
        $this->reader->expects(static::exactly(2))->method('getClassAnnotation')->willReturn(new Transactional());
149
150
        $class = new ReflectionClass(TransactionalAwareClass::class);
151
        $this->assertTrue($this->buildTransactionPointcut(false)->matchesMethod($class->getMethod('publicMethod')));
152
        $this->assertTrue($this->buildTransactionPointcut(true)->matchesMethod($class->getMethod('publicMethod')));
153
    }
154
155
    public function testMatchesUnannotatedPublicMethodInUnannotatedClass()
156
    {
157
        $this->reader->expects(static::exactly(2))->method('getMethodAnnotation')->willReturn(null);
158
        $this->reader->expects(static::exactly(2))->method('getClassAnnotation')->willReturn(null);
159
160
        $class = new ReflectionClass(TransactionalAwareClass::class);
161
        $this->assertFalse($this->buildTransactionPointcut(false)->matchesMethod($class->getMethod('publicMethod')));
162
        $this->assertFalse($this->buildTransactionPointcut(true)->matchesMethod($class->getMethod('publicMethod')));
163
    }
164
165
    /**
166
     * Builds a transactional pointcut with/without strict mode enabled.
167
     *
168
     * @param boolean $strictModeEnabled Whether strict mode is enabled.
169
     * @return TransactionalPointcut Pointcut.
170
     */
171
    private function buildTransactionPointcut($strictModeEnabled)
172
    {
173
        $this->container->expects(static::any())->method('getParameter')->with(
174
            Configuration::ROOT_NODE_NAME . '.' . Configuration::STRICT_MODE
175
        )->willReturn($strictModeEnabled);
176
177
        return new TransactionalPointcut($this->container, $this->reader, $this->logger);
178
    }
179
}
180