Completed
Push — master ( b7729b...1130ef )
by Alejandro
13s
created

PhpEnumTypeTest::SQLCommentHintIsAlwaysRequired()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 7
rs 9.4285
c 1
b 0
f 0
cc 1
eloc 4
nc 1
nop 0
1
<?php
2
namespace Acelaya\Test\Doctrine\Type;
3
4
use Acelaya\Doctrine\Exception\InvalidArgumentException;
5
use Acelaya\Doctrine\Type\PhpEnumType;
6
use Acelaya\Test\Doctrine\Enum\Action;
7
use Acelaya\Test\Doctrine\Enum\Gender;
8
use Doctrine\DBAL\Platforms\AbstractPlatform;
9
use Doctrine\DBAL\Types\Type;
10
use MyCLabs\Enum\Enum;
11
use PHPUnit\Framework\TestCase;
12
use Prophecy\Argument;
13
use Prophecy\Prophecy\ObjectProphecy;
14
15
class PhpEnumTypeTest extends TestCase
16
{
17
    /**
18
     * @var ObjectProphecy
19
     */
20
    protected $platform;
21
22
    public function setUp()
23
    {
24
        $this->platform = $this->prophesize(AbstractPlatform::class);
25
26
        // Before every test, clean registered types
27
        $refProp = new \ReflectionProperty(Type::class, '_typeObjects');
28
        $refProp->setAccessible(true);
29
        $refProp->setValue(null, []);
30
        $refProp = new \ReflectionProperty(Type::class, '_typesMap');
31
        $refProp->setAccessible(true);
32
        $refProp->setValue(null, []);
33
    }
34
35
    /**
36
     * @test
37
     */
38
    public function enumTypesAreProperlyRegistered()
39
    {
40
        $this->assertFalse(Type::hasType(Action::class));
41
        $this->assertFalse(Type::hasType('gender'));
42
43
        PhpEnumType::registerEnumType(Action::class);
44
        PhpEnumType::registerEnumTypes([
45
            'gender' => Gender::class,
46
        ]);
47
48
        $this->assertTrue(Type::hasType(Action::class));
49
        $this->assertTrue(Type::hasType('gender'));
50
    }
51
52
    /**
53
     * @test
54
     */
55
    public function enumTypesAreProperlyCustomizedWhenRegistered()
56
    {
57
        $this->assertFalse(Type::hasType(Action::class));
58
        $this->assertFalse(Type::hasType(Gender::class));
59
60
        PhpEnumType::registerEnumTypes([
61
            'gender' => Gender::class,
62
            Action::class,
63
        ]);
64
65
        /** @var Type $actionType */
66
        $actionType = Type::getType(Action::class);
67
        $this->assertInstanceOf(PhpEnumType::class, $actionType);
68
        $this->assertEquals(Action::class, $actionType->getName());
69
70
        /** @var Type $actionType */
71
        $genderType = Type::getType('gender');
72
        $this->assertInstanceOf(PhpEnumType::class, $genderType);
73
        $this->assertEquals('gender', $genderType->getName());
74
    }
75
76
    /**
77
     * @test
78
     */
79
    public function registerInvalidEnumThrowsException()
80
    {
81
        $this->expectException(InvalidArgumentException::class);
82
        $this->expectExceptionMessage(sprintf(
83
            'Provided enum class "%s" is not valid. Enums must extend "%s"',
84
            \stdClass::class,
85
            Enum::class
86
        ));
87
        PhpEnumType::registerEnumType(\stdClass::class);
88
    }
89
90
    /**
91
     * @test
92
     */
93
    public function getSQLDeclarationReturnsValueFromPlatform()
94
    {
95
        $this->platform->getVarcharTypeDeclarationSQL(Argument::cetera())->willReturn('declaration');
96
97
        PhpEnumType::registerEnumType(Gender::class);
98
        $type = Type::getType(Gender::class);
99
100
        $this->assertEquals('declaration', $type->getSQLDeclaration([], $this->platform->reveal()));
101
    }
102
103
    /**
104
     * @test
105
     */
106
    public function convertToDatabaseValueParsesEnum()
107
    {
108
        PhpEnumType::registerEnumType(Action::class);
109
        $type = Type::getType(Action::class);
110
111
        $value = Action::CREATE();
112
        $this->assertEquals(Action::CREATE, $type->convertToDatabaseValue($value, $this->platform->reveal()));
113
114
        $value = Action::READ();
115
        $this->assertEquals(Action::READ, $type->convertToDatabaseValue($value, $this->platform->reveal()));
116
117
        $value = Action::UPDATE();
118
        $this->assertEquals(Action::UPDATE, $type->convertToDatabaseValue($value, $this->platform->reveal()));
119
120
        $value = Action::DELETE();
121
        $this->assertEquals(Action::DELETE, $type->convertToDatabaseValue($value, $this->platform->reveal()));
122
    }
123
124
    /**
125
     * @test
126
     */
127
    public function convertToPHPValueWithValidValueReturnsParsedData()
128
    {
129
        PhpEnumType::registerEnumType(Action::class);
130
        $type = Type::getType(Action::class);
131
132
        /** @var Action $value */
133
        $value = $type->convertToPHPValue(Action::CREATE, $this->platform->reveal());
134
        $this->assertInstanceOf(Action::class, $value);
135
        $this->assertEquals(Action::CREATE, $value->getValue());
136
137
        $value = $type->convertToPHPValue(Action::DELETE, $this->platform->reveal());
138
        $this->assertInstanceOf(Action::class, $value);
139
        $this->assertEquals(Action::DELETE, $value->getValue());
140
    }
141
142
    /**
143
     * @test
144
     */
145 View Code Duplication
    public function convertToPHPValueWithNullReturnsNull()
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...
146
    {
147
        PhpEnumType::registerEnumType(Action::class);
148
        $type = Type::getType(Action::class);
149
150
        $value = $type->convertToPHPValue(null, $this->platform->reveal());
151
        $this->assertNull($value);
152
    }
153
154
    /**
155
     * @test
156
     */
157
    public function convertToPHPValueWithInvalidValueThrowsException()
158
    {
159
        PhpEnumType::registerEnumType(Action::class);
160
        $type = Type::getType(Action::class);
161
162
        $this->expectException(InvalidArgumentException::class);
163
        $this->expectExceptionMessage(sprintf(
164
            'The value "invalid" is not valid for the enum "%s". Expected one of ["%s"]',
165
            Action::class,
166
            implode('", "', Action::toArray())
167
        ));
168
        $type->convertToPHPValue('invalid', $this->platform->reveal());
169
    }
170
171
    /**
172
     * @test
173
     */
174 View Code Duplication
    public function usingChildEnumTypeRegisteredValueIsCorrect()
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...
175
    {
176
        MyType::registerEnumType(Action::class);
177
        $type = Type::getType(Action::class);
178
179
        $this->assertInstanceOf(MyType::class, $type);
180
        $this->assertEquals('FOO BAR', $type->getSQLDeclaration([], $this->platform->reveal()));
181
    }
182
183
    /**
184
     * @test
185
     */
186 View Code Duplication
    public function usingChildCustomEnumTypeRegisteredValueIsCorrect()
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...
187
    {
188
        MyCustomEnumType::registerEnumType(Action::class);
189
        $type = MyCustomEnumType::getType(Action::class);
190
191
        $this->assertInstanceOf(MyCustomEnumType::class, $type);
192
        $this->assertEquals(
193
            'ENUM("create", "read", "update", "delete") COMMENT "Acelaya\Test\Doctrine\Enum\Action"',
194
            $type->getSQLDeclaration([], $this->platform->reveal())
195
        );
196
    }
197
198
    /**
199
     * @test
200
     */
201
    public function SQLCommentHintIsAlwaysRequired()
202
    {
203
        PhpEnumType::registerEnumType(Gender::class);
204
        $type = Type::getType(Gender::class);
205
206
        $this->assertTrue($type->requiresSQLCommentHint($this->platform->reveal()));
207
    }
208
}
209