|
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() |
|
|
|
|
|
|
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() |
|
|
|
|
|
|
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() |
|
|
|
|
|
|
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
|
|
|
|
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.