Completed
Pull Request — master (#83)
by Sascha-Oliver
02:47
created

EnumTest::testFailureEnumWithArguments()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 12
rs 9.4285
cc 1
eloc 8
nc 1
nop 0
1
<?php
2
3
namespace MabeEnumTest;
4
5
use MabeEnumTest\TestAsset\EnumBasic;
6
use MabeEnumTest\TestAsset\EnumInheritance;
7
use MabeEnumTest\TestAsset\EnumAmbiguous;
8
use MabeEnumTest\TestAsset\EnumExtendedAmbiguous;
9
use MabeEnumTest\TestAsset\ConstVisibilityEnum;
10
use MabeEnumTest\TestAsset\ConstVisibilityEnumExtended;
11
use MabeEnumTest\TestAsset\FailureEnumWithArguments;
12
use MabeEnumTest\TestAsset\SerializableEnum;
13
use PHPUnit_Framework_TestCase as TestCase;
14
use ReflectionClass;
15
16
/**
17
 * Unit tests for the class MabeEnum\Enum
18
 *
19
 * @link http://github.com/marc-mabe/php-enum for the canonical source repository
20
 * @copyright Copyright (c) 2015 Marc Bennewitz
21
 * @license http://github.com/marc-mabe/php-enum/blob/master/LICENSE.txt New BSD License
22
 */
23
class EnumTest extends TestCase
24
{
25
    public function testGetNameReturnsConstantNameOfCurrentValue()
26
    {
27
        $enum = EnumBasic::get(EnumBasic::ONE);
28
        $this->assertSame('ONE', $enum->getName());
29
    }
30
31
    public function testToStringMagicMethodReturnsName()
32
    {
33
        $enum = EnumBasic::get(EnumBasic::ONE);
34
        $this->assertSame('ONE', $enum->__toString());
35
    }
36
37
    public function testEnumInheritance()
38
    {
39
        $this->assertSame(array(
40
            'ONE'           => 1,
41
            'TWO'           => 2,
42
            'THREE'         => 3,
43
            'FOUR'          => 4,
44
            'FIVE'          => 5,
45
            'SIX'           => 6,
46
            'SEVEN'         => 7,
47
            'EIGHT'         => 8,
48
            'NINE'          => 9,
49
            'ZERO'          => 0,
50
            'FLOAT'         => 0.123,
51
            'STR'           => 'str',
52
            'STR_EMPTY'     => '',
53
            'NIL'           => null,
54
            'BOOLEAN_TRUE'  => true,
55
            'BOOLEAN_FALSE' => false,
56
            'INHERITANCE'   => 'Inheritance',
57
        ), EnumInheritance::getConstants());
58
59
        $enum = EnumInheritance::get(EnumInheritance::ONE);
60
        $this->assertSame(EnumInheritance::ONE, $enum->getValue());
61
        $this->assertSame(0, $enum->getOrdinal());
62
63
        $enum = EnumInheritance::get(EnumInheritance::INHERITANCE);
64
        $this->assertSame(EnumInheritance::INHERITANCE, $enum->getValue());
65
        $this->assertSame(16, $enum->getOrdinal());
66
    }
67
68
    public function testGetWithStrictValue()
69
    {
70
        $enum = EnumBasic::get(EnumBasic::ONE);
71
        $this->assertSame(1, $enum->getValue());
72
        $this->assertSame(0, $enum->getOrdinal());
73
    }
74
75
    public function testGetWithNonStrictValueThrowsInvalidArgumentException()
76
    {
77
        $this->setExpectedException('InvalidArgumentException');
78
        EnumBasic::get((string)EnumBasic::TWO);
79
    }
80
81
    public function testGetWithInvalidValueThrowsInvalidArgumentException()
82
    {
83
        $this->setExpectedException('InvalidArgumentException');
84
        EnumBasic::get('unknown');
85
    }
86
87
    public function testGetWithInvalidTypeOfValueThrowsInvalidArgumentException()
88
    {
89
        $this->setExpectedException('InvalidArgumentException');
90
        EnumBasic::get(array());
91
    }
92
93
    public function testGetByInstance()
94
    {
95
        $enum1 = EnumBasic::get(EnumBasic::ONE);
96
        $enum2 = EnumBasic::get($enum1);
97
        $this->assertSame($enum1, $enum2);
98
    }
99
100
    public function testGetByExtendedInstanceOfKnownValue()
101
    {
102
        $enum = EnumInheritance::get(EnumInheritance::ONE);
103
104
        $this->setExpectedException('InvalidArgumentException');
105
        EnumBasic::get($enum);
106
    }
107
108
    public function testGetEnumerators()
109
    {
110
        $constants   = EnumInheritance::getConstants();
111
        $enumerators = EnumInheritance::getEnumerators();
112
        $count       = count($enumerators);
113
114
        $this->assertSame(count($constants), $count);
115
        for ($i = 0; $i < $count; ++$i) {
116
            $this->assertArrayHasKey($i, $enumerators);
117
            $this->assertInstanceOf('MabeEnumTest\TestAsset\EnumInheritance', $enumerators[$i]);
118
119
            $enumerator = $enumerators[$i];
120
            $this->assertArrayHasKey($enumerator->getName(), $constants);
121
            $this->assertSame($constants[$enumerator->getName()], $enumerator->getValue());
122
        }
123
    }
124
125 View Code Duplication
    public function testGetValues()
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...
126
    {
127
        $expectedValues = array_values(EnumInheritance::getConstants());
128
        $values         = EnumInheritance::getValues();
129
        $count          = count($values);
130
131
        $this->assertSame(count($expectedValues), $count);
132
        for ($i = 0; $i < $count; ++$i) {
133
            $this->assertArrayHasKey($i, $values);
134
            $this->assertSame($expectedValues[$i], $values[$i]);
135
        }
136
    }
137
138 View Code Duplication
    public function testGetNames()
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
    {
140
        $expectedNames = array_keys(EnumInheritance::getConstants());
141
        $names         = EnumInheritance::getNames();
142
        $count         = count($names);
143
144
        $this->assertSame(count($expectedNames), $count);
145
        for ($i = 0; $i < $count; ++$i) {
146
            $this->assertArrayHasKey($i, $names);
147
            $this->assertSame($expectedNames[$i], $names[$i]);
148
        }
149
    }
150
151 View Code Duplication
    public function testGetOrdinals()
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...
152
    {
153
        $constants = EnumInheritance::getConstants();
154
        $ordinals  = EnumInheritance::getOrdinals();
155
        $count     = count($ordinals);
156
157
        $this->assertSame(count($constants), $count);
158
        for ($i = 0; $i < $count; ++$i) {
159
            $this->assertArrayHasKey($i, $ordinals);
160
            $this->assertSame($i, $ordinals[$i]);
161
        }
162
    }
163
164
    public function testGetAllValues()
165
    {
166
        $constants = EnumBasic::getConstants();
167
        foreach ($constants as $name => $value) {
168
            $enum = EnumBasic::get($value);
169
            $this->assertSame($value, $enum->getValue());
170
            $this->assertSame($name, $enum->getName());
171
        }
172
    }
173
174 View Code Duplication
    public function testIsBasic()
175
    {
176
        $enum = EnumBasic::ONE();
177
178
        // by value
179
        $this->assertTrue($enum->is(EnumBasic::ONE));   // same
180
        $this->assertFalse($enum->is('1'));             // wrong value by strict comparison
181
182
        // by instance
183
        $this->assertTrue($enum->is(EnumBasic::ONE()));        // same
184
        $this->assertFalse($enum->is(EnumBasic::TWO()));       // different enumerators
185
        $this->assertFalse($enum->is(EnumInheritance::ONE())); // different enumeration type
186
    }
187
188
    public function testCallingGetOrdinalTwoTimesWillResultTheSameValue()
189
    {
190
        $enum = EnumBasic::get(EnumBasic::TWO);
191
        $this->assertSame(1, $enum->getOrdinal());
192
        $this->assertSame(1, $enum->getOrdinal());
193
    }
194
195
    public function testInstantiateUsingOrdinalNumber()
196
    {
197
        $enum = EnumInheritance::byOrdinal(16);
198
        $this->assertSame(16, $enum->getOrdinal());
199
        $this->assertSame('INHERITANCE', $enum->getName());
200
    }
201
202
    public function testInstantiateUsingInvalidOrdinalNumberThrowsInvalidArgumentException()
203
    {
204
        $this->setExpectedException('InvalidArgumentException');
205
        EnumInheritance::byOrdinal(17);
206
    }
207
208
    public function testInstantiateByName()
209
    {
210
        $enum = EnumInheritance::byName('ONE');
211
        $this->assertInstanceOf('MabeEnumTest\TestAsset\EnumInheritance', $enum);
212
        $this->assertSame(EnumInheritance::ONE, $enum->getValue());
213
    }
214
215
    public function testInstantiateByUnknownNameThrowsInvalidArgumentException()
216
    {
217
        $this->setExpectedException('InvalidArgumentException');
218
        EnumInheritance::byName('UNKNOWN');
219
    }
220
221
    public function testInstantiateUsingMagicMethod()
222
    {
223
        $enum = EnumInheritance::ONE();
224
        $this->assertInstanceOf('MabeEnumTest\TestAsset\EnumInheritance', $enum);
225
        $this->assertSame(EnumInheritance::ONE, $enum->getValue());
226
    }
227
228
    public function testAmbiguousConstantsThrowsLogicException()
229
    {
230
        $this->setExpectedException('LogicException');
231
        EnumAmbiguous::get('unknown');
232
    }
233
234
    public function testExtendedAmbiguousCanstantsThrowsLogicException()
235
    {
236
        $this->setExpectedException('LogicException');
237
        EnumExtendedAmbiguous::get('unknown');
238
    }
239
240
    public function testSingleton()
241
    {
242
        $enum1 = EnumBasic::get(EnumBasic::ONE);
243
        $enum2 = EnumBasic::ONE();
244
        $this->assertSame($enum1, $enum2);
245
    }
246
247
    public function testClear()
248
    {
249
        $enum1 = EnumBasic::ONE();
250
        EnumBasic::clear();
0 ignored issues
show
Deprecated Code introduced by
The method MabeEnum\Enum::clear() has been deprecated.

This method has been deprecated.

Loading history...
251
        $enum2 = EnumBasic::ONE();
252
        $enum3 = EnumBasic::ONE();
253
        
254
        $this->assertNotSame($enum1, $enum2);
255
        $this->assertSame($enum2, $enum3);
256
    }
257
258 View Code Duplication
    public function testCloneNotCallableAndThrowsLogicException()
259
    {
260
        $enum = EnumBasic::ONE();
261
262
        $reflectionClass  = new ReflectionClass($enum);
263
        $reflectionMethod = $reflectionClass->getMethod('__clone');
264
        $this->assertTrue($reflectionMethod->isPrivate(), 'The method __clone must be private');
265
        $this->assertTrue($reflectionMethod->isFinal(), 'The method __clone must be final');
266
267
        $reflectionMethod->setAccessible(true);
268
        $this->setExpectedException('LogicException');
269
        $reflectionMethod->invoke($enum);
270
    }
271
272
    public function testNotSerializable()
273
    {
274
        $enum = EnumBasic::ONE();
275
276
        $this->setExpectedException('LogicException');
277
        serialize($enum);
278
    }
279
280
    public function testNotUnserializable()
281
    {
282
        $this->setExpectedException('LogicException');
283
        unserialize("O:32:\"MabeEnumTest\TestAsset\EnumBasic\":0:{}");
284
    }
285
286 View Code Duplication
    public function testHas()
287
    {
288
        $enum = EnumBasic::ONE();
289
290
        $this->assertFalse($enum->has('invalid'));
291
        $this->assertFalse($enum->has(EnumInheritance::ONE()));
292
        $this->assertTrue($enum->has(EnumBasic::ONE()));
293
        $this->assertTrue($enum->has(EnumBasic::ONE));
294
    }
295
    
296
    public function testConstVisibility()
297
    {
298
        if (PHP_VERSION_ID < 70100) {
299
            $this->markTestSkipped('This test is for PHP-7.1 and upper only');
300
        }
301
302
        $constants = ConstVisibilityEnum::getConstants();
303
        $this->assertSame(array(
304
            'IPUB' => ConstVisibilityEnum::IPUB,
305
            'PUB'  => ConstVisibilityEnum::PUB,
306
        ), $constants);
307
    }
308
    
309
    public function testConstVisibilityExtended()
310
    {
311
        if (PHP_VERSION_ID < 70100) {
312
            $this->markTestSkipped('This test is for PHP-7.1 and upper only');
313
        }
314
315
        $constants = ConstVisibilityEnumExtended::getConstants();
316
        $this->assertSame(array(
317
            'IPUB'  => ConstVisibilityEnumExtended::IPUB,
318
            'PUB'   => ConstVisibilityEnumExtended::PUB,
319
            'IPUB2' => ConstVisibilityEnumExtended::IPUB2,
320
            'PUB2'  => ConstVisibilityEnumExtended::PUB2,
321
        ), $constants);
322
    }
323
324
    public function testIsSerializableIssue()
325
    {
326
        if (PHP_VERSION_ID < 50400) {
327
            $this->markTestSkipped('This test is for PHP-5.4 and upper only');
328
        }
329
330
        $enum1 = SerializableEnum::INT();
331
        $enum2 = unserialize(serialize($enum1));
332
333
        $this->assertFalse($enum1 === $enum2, 'Wrong test implementation');
334
        $this->assertTrue($enum1->is($enum2), 'Two different instances of exact the same enumerator should be equal');
335
    }
336
337
    public function testFailureEnumWithArguments()
338
    {
339
        $failure1 = FailureEnumWithArguments::VALIDATION_ERROR('foo');
340
        $this->assertInstanceOf(FailureEnumWithArguments::class, $failure1);
341
        $this->assertEquals('foo', $failure1->message());
342
343
        $failure2 = FailureEnumWithArguments::DB_ERROR('bar');
344
        $this->assertInstanceOf(FailureEnumWithArguments::class, $failure2);
345
        $this->assertEquals('bar', $failure2->message());
346
347
        $this->assertNotSame($failure1, $failure2);
348
    }
349
}
350