Skip to content

Commit d75e7b2

Browse files
committed
more tests and bug fixes
1 parent 2de7510 commit d75e7b2

File tree

2 files changed

+120
-20
lines changed

2 files changed

+120
-20
lines changed

src/MabeEnum/EnumMap.php

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use SplObjectStorage;
66
use InvalidArgumentException;
7+
use RuntimeException;
78

89
class EnumMap extends SplObjectStorage
910
{
@@ -15,11 +16,17 @@ class EnumMap extends SplObjectStorage
1516
const CURRENT_AS_ENUM = 8;
1617
const CURRENT_AS_DATA = 16;
1718
const CURRENT_AS_NAME = 24;
18-
const CURRENT_AS_VALUE = 56;
19-
const CURRENT_AS_ORDINAL = 120;
19+
const CURRENT_AS_VALUE = 32;
20+
const CURRENT_AS_ORDINAL = 40;
2021

2122
private $enumClass;
22-
private $flags;
23+
24+
/**
25+
* Flags to define behaviors
26+
* (Default = KEY_AS_INDEX | CURRENT_AS_ENUM)
27+
* @var int
28+
*/
29+
private $flags = 9;
2330

2431
public function __construct($enumClass, $flags = null)
2532
{
@@ -31,10 +38,9 @@ public function __construct($enumClass, $flags = null)
3138
}
3239
$this->enumClass = $enumClass;
3340

34-
if ($flags === null) {
35-
$flags = self::KEY_AS_INDEX | self::CURRENT_AS_ENUM;
41+
if ($flags !== null) {
42+
$this->setFlags($flags);
3643
}
37-
$this->setFlags($flags);
3844
}
3945

4046
public function getEnumClass()
@@ -46,21 +52,26 @@ public function setFlags($flags)
4652
{
4753
$flags = (int)$flags;
4854

49-
$keyFlags = $flags & 7;
50-
if ($keyFlags < 1 || $keyFlags > 4) {
55+
$keyFlag = $flags & 7;
56+
if ($keyFlag > 4) {
5157
throw new InvalidArgumentException(
52-
"Flags have to contain one of the 'KEY_AS_*' constants"
58+
"Unsupported flag given for key() behavior"
5359
);
60+
} elseif (!$keyFlag) {
61+
$keyFlag = $this->flags & 7;
5462
}
63+
5564

56-
$currentFlags = $flags & 120;
57-
if ($currentFlags < 8 || $currentFlags > 120) {
65+
$currentFlag = $flags & 56;
66+
if ($currentFlag > 40) {
5867
throw new InvalidArgumentException(
59-
"Flags have to contain one of the 'CURRENT_AS_*' constants"
68+
"Unsupported flag given for current() behavior"
6069
);
70+
} elseif (!$currentFlag) {
71+
$currentFlag = $this->flags & 56;
6172
}
6273

63-
$this->flags = $flags;
74+
$this->flags = $keyFlag | $currentFlag;
6475
}
6576

6677
public function getFlags()
@@ -146,12 +157,14 @@ public function current()
146157
return parent::current();
147158
case self::CURRENT_AS_DATA:
148159
return parent::getInfo();
160+
case self::CURRENT_AS_NAME:
161+
return parent::current()->getName();
149162
case self::CURRENT_AS_VALUE:
150163
return parent::current()->getValue();
164+
case self::CURRENT_AS_ORDINAL:
165+
return parent::current()->getOrdinal();
151166
default:
152-
throw new RuntimeException(
153-
'Invalid current flags'
154-
);
167+
throw new RuntimeException('Invalid current flags');
155168
}
156169
}
157170

@@ -167,9 +180,7 @@ public function key()
167180
case self::KEY_AS_ORDINAL:
168181
return parent::current()->getOrdinal();
169182
default:
170-
throw new RuntimeException(
171-
'Invalid key flags'
172-
);
183+
throw new RuntimeException('Invalid key flags');
173184
}
174185
}
175186
}

tests/MabeEnumTest/EnumMapTest.php

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ class EnumMapTest extends TestCase
1919
public function testBasic()
2020
{
2121
$enumMap = new EnumMap('MabeEnumTest\TestAsset\EnumWithoutDefaultValue');
22-
22+
$this->assertSame('MabeEnumTest\TestAsset\EnumWithoutDefaultValue', $enumMap->getEnumClass());
23+
2324
$enum1 = EnumWithoutDefaultValue::ONE();
2425
$value1 = 'value2';
2526

@@ -113,4 +114,92 @@ public function testIterate()
113114
$this->assertSame(0, $enumMap->key());
114115
$this->assertSame($enum1, $enumMap->current());
115116
}
117+
118+
public function testIterateWithFlags()
119+
{
120+
$enumMap = new EnumMap(
121+
'MabeEnumTest\TestAsset\EnumWithoutDefaultValue',
122+
EnumMap::KEY_AS_INDEX | EnumMap::CURRENT_AS_ENUM
123+
);
124+
125+
$enumMap->attach(EnumWithoutDefaultValue::TWO(), 'first');
126+
$enumMap->attach(EnumWithoutDefaultValue::ONE(), 'second');
127+
128+
// EnumMap::KEY_AS_INDEX | EnumMap::CURRENT_AS_ENUM (first)
129+
$this->assertSame(EnumMap::KEY_AS_INDEX | EnumMap::CURRENT_AS_ENUM, $enumMap->getFlags());
130+
131+
$enumMap->rewind();
132+
$this->assertSame(0, $enumMap->key());
133+
$this->assertSame(EnumWithoutDefaultValue::TWO(), $enumMap->current());
134+
135+
$enumMap->next();
136+
$this->assertSame(1, $enumMap->key());
137+
$this->assertSame(EnumWithoutDefaultValue::ONE(), $enumMap->current());
138+
139+
// EnumMap::KEY_AS_NAME | EnumMap::CURRENT_AS_DATA
140+
$enumMap->setFlags(EnumMap::KEY_AS_NAME | EnumMap::CURRENT_AS_DATA);
141+
$this->assertSame(EnumMap::KEY_AS_NAME | EnumMap::CURRENT_AS_DATA, $enumMap->getFlags());
142+
143+
$enumMap->rewind();
144+
$this->assertSame('TWO', $enumMap->key());
145+
$this->assertSame('first', $enumMap->current());
146+
147+
$enumMap->next();
148+
$this->assertSame('ONE', $enumMap->key());
149+
$this->assertSame('second', $enumMap->current());
150+
151+
// EnumMap::KEY_AS_VALUE | EnumMap::CURRENT_AS_ORDINAL
152+
$enumMap->setFlags(EnumMap::KEY_AS_VALUE | EnumMap::CURRENT_AS_ORDINAL);
153+
$this->assertSame(EnumMap::KEY_AS_VALUE | EnumMap::CURRENT_AS_ORDINAL, $enumMap->getFlags());
154+
155+
$enumMap->rewind();
156+
$this->assertSame(2, $enumMap->key());
157+
$this->assertSame(1, $enumMap->current());
158+
159+
$enumMap->next();
160+
$this->assertSame(1, $enumMap->key());
161+
$this->assertSame(0, $enumMap->current());
162+
163+
// EnumMap::KEY_AS_ORDINAL | EnumMap::CURRENT_AS_VALUE
164+
$enumMap->setFlags(EnumMap::KEY_AS_ORDINAL | EnumMap::CURRENT_AS_VALUE);
165+
$this->assertSame(EnumMap::KEY_AS_ORDINAL | EnumMap::CURRENT_AS_VALUE, $enumMap->getFlags());
166+
167+
$enumMap->rewind();
168+
$this->assertSame(1, $enumMap->key());
169+
$this->assertSame(2, $enumMap->current());
170+
171+
$enumMap->next();
172+
$this->assertSame(0, $enumMap->key());
173+
$this->assertSame(1, $enumMap->current());
174+
175+
// only change current flag to EnumMap::CURRENT_AS_NAME
176+
$enumMap->setFlags(EnumMap::CURRENT_AS_NAME);
177+
$this->assertSame(EnumMap::KEY_AS_ORDINAL | EnumMap::CURRENT_AS_NAME, $enumMap->getFlags());
178+
179+
$enumMap->rewind();
180+
$this->assertSame(1, $enumMap->key());
181+
$this->assertSame('TWO', $enumMap->current());
182+
183+
$enumMap->next();
184+
$this->assertSame(0, $enumMap->key());
185+
$this->assertSame('ONE', $enumMap->current());
186+
187+
// only change key flag to EnumMap::NAME_AS_NAME
188+
$enumMap->setFlags(EnumMap::KEY_AS_NAME);
189+
$this->assertSame(EnumMap::KEY_AS_NAME | EnumMap::CURRENT_AS_NAME, $enumMap->getFlags());
190+
191+
$enumMap->rewind();
192+
$this->assertSame('TWO', $enumMap->key());
193+
$this->assertSame('TWO', $enumMap->current());
194+
195+
$enumMap->next();
196+
$this->assertSame('ONE', $enumMap->key());
197+
$this->assertSame('ONE', $enumMap->current());
198+
}
199+
200+
public function testConstructThrowsInvalidArgumentExceptionIfEnumClassDoesNotExtendBaseEnum()
201+
{
202+
$this->setExpectedException('InvalidArgumentException');
203+
new EnumMap('stdClass');
204+
}
116205
}

0 commit comments

Comments
 (0)