diff --git a/src/AbstractMultiton.php b/src/AbstractMultiton.php index fff55b1..3c6c4c9 100644 --- a/src/AbstractMultiton.php +++ b/src/AbstractMultiton.php @@ -19,22 +19,6 @@ */ abstract class AbstractMultiton implements MultitonInterface { - /** - * Returns an array of all members in this multiton. - * - * @return array All members. - */ - final public static function members() - { - $class = get_called_class(); - if (!array_key_exists($class, self::$members)) { - self::$members[$class] = array(); - static::initializeMembers(); - } - - return self::$members[$class]; - } - /** * Returns a single member by string key. * @@ -147,41 +131,40 @@ function (MultitonInterface $member) use ( } /** - * Returns a set of members by comparison with the result of an accessor - * method. + * Returns a single member by comparison with the result of an accessor + * method. Additionally returns null if the supplied value is null. * * @param string $property The name of the property (accessor method) to match. - * @param mixed $value The value to match. + * @param mixed $value The value to match, or null. * @param boolean|null $isCaseSensitive True if the search should be case sensitive. * - * @return array All members for which $member->{$property}() === $value. + * @return MultitonInterface|null The first member for which $member->{$property}() === $value, or null if the supplied value is null. + * @throws Exception\UndefinedMemberExceptionInterface If no associated member is found. */ - final public static function membersBy( + final public static function memberOrNullBy( $property, $value, $isCaseSensitive = null ) { - if (null === $isCaseSensitive) { - $isCaseSensitive = true; - } - if (!$isCaseSensitive && is_scalar($value)) { - $value = strtoupper(strval($value)); - } + $member = static::memberByWithDefault( + $property, + $value, + null, + $isCaseSensitive + ); + if (null === $member) { + if (null === $value) { + return null; + } - return static::membersByPredicate( - function (MultitonInterface $member) use ( + throw static::createUndefinedMemberException( + get_called_class(), $property, - $value, - $isCaseSensitive - ) { - $memberValue = $member->{$property}(); - if (!$isCaseSensitive && is_scalar($memberValue)) { - $memberValue = strtoupper(strval($memberValue)); - } + $value + ); + } - return $memberValue === $value; - } - ); + return $member; } /** @@ -228,6 +211,60 @@ final public static function memberByPredicateWithDefault( return $default; } + /** + * Returns an array of all members in this multiton. + * + * @return array All members. + */ + final public static function members() + { + $class = get_called_class(); + if (!array_key_exists($class, self::$members)) { + self::$members[$class] = array(); + static::initializeMembers(); + } + + return self::$members[$class]; + } + + /** + * Returns a set of members by comparison with the result of an accessor + * method. + * + * @param string $property The name of the property (accessor method) to match. + * @param mixed $value The value to match. + * @param boolean|null $isCaseSensitive True if the search should be case sensitive. + * + * @return array All members for which $member->{$property}() === $value. + */ + final public static function membersBy( + $property, + $value, + $isCaseSensitive = null + ) { + if (null === $isCaseSensitive) { + $isCaseSensitive = true; + } + if (!$isCaseSensitive && is_scalar($value)) { + $value = strtoupper(strval($value)); + } + + return static::membersByPredicate( + function (MultitonInterface $member) use ( + $property, + $value, + $isCaseSensitive + ) { + $memberValue = $member->{$property}(); + if (!$isCaseSensitive && is_scalar($memberValue)) { + $memberValue = strtoupper(strval($memberValue)); + } + + return $memberValue === $value; + } + ); + } + /** * Returns a set of members by predicate callback. * diff --git a/src/AbstractValueMultiton.php b/src/AbstractValueMultiton.php index ead96ed..7404456 100644 --- a/src/AbstractValueMultiton.php +++ b/src/AbstractValueMultiton.php @@ -31,19 +31,6 @@ final public static function memberByValue($value, $isCaseSensitive = null) return static::memberBy('value', $value, $isCaseSensitive); } - /** - * Returns a set of members matching the supplied value. - * - * @param scalar $value The value associated with the members. - * @param boolean|null $isCaseSensitive True if the search should be case sensitive. - * - * @return array All members with the supplied value. - */ - final public static function membersByValue($value, $isCaseSensitive = null) - { - return static::membersBy('value', $value, $isCaseSensitive); - } - /** * Returns a single member by value. Additionally returns a default if no * associated member is found. @@ -67,6 +54,35 @@ final public static function memberByValueWithDefault( ); } + /** + * Returns a single member by value. + * + * @param scalar|null $value The value associated with the member, or null. + * @param boolean|null $isCaseSensitive True if the search should be case sensitive. + * + * @return ValueMultitonInterface|null The first member with the supplied value, or null if the supplied value is null. + * @throws Exception\UndefinedMemberException If no associated member is found. + */ + final public static function memberOrNullByValue( + $value, + $isCaseSensitive = null + ) { + return static::memberOrNullBy('value', $value, $isCaseSensitive); + } + + /** + * Returns a set of members matching the supplied value. + * + * @param scalar $value The value associated with the members. + * @param boolean|null $isCaseSensitive True if the search should be case sensitive. + * + * @return array All members with the supplied value. + */ + final public static function membersByValue($value, $isCaseSensitive = null) + { + return static::membersBy('value', $value, $isCaseSensitive); + } + /** * Returns the value of this member. * diff --git a/test/suite/AbstractEnumerationTest.php b/test/suite/AbstractEnumerationTest.php index 20d3389..b71f116 100644 --- a/test/suite/AbstractEnumerationTest.php +++ b/test/suite/AbstractEnumerationTest.php @@ -30,15 +30,6 @@ protected function setUp() // Multiton tests ========================================================== - public function testMembers() - { - $this->assertSame(array( - 'BAZ' => ValidEnumeration::BAZ(), - 'FOO' => ValidEnumeration::FOO(), - 'BAR' => ValidEnumeration::BAR(), - ), ValidEnumeration::members()); - } - public function testMemberByKey() { $foo = ValidEnumeration::memberByKey('FOO'); @@ -101,13 +92,18 @@ public function testMemberByWithDefault() $this->assertNull(ValidEnumeration::memberByWithDefault('key', 'qux')); } - public function testMembersBy() + public function testMemberOrNullBy() { - $foo = ValidEnumeration::membersBy('value', 'oof'); - $bar = ValidEnumeration::membersBy('value', 'RAB', false); + $this->assertSame(ValidEnumeration::FOO(), ValidEnumeration::memberOrNullBy('key', 'FOO')); + $this->assertSame(ValidEnumeration::BAR(), ValidEnumeration::memberOrNullBy('key', 'BAR')); + $this->assertSame(ValidEnumeration::FOO(), ValidEnumeration::memberOrNullBy('key', 'Foo', false)); + $this->assertNull(ValidEnumeration::memberOrNullBy('key', null)); + } - $this->assertSame(array('FOO' => ValidEnumeration::FOO()), $foo); - $this->assertSame(array('BAR' => ValidEnumeration::BAR()), $bar); + public function testMemberOrNullByFailureUndefined() + { + $this->setExpectedException('Eloquent\Enumeration\Exception\UndefinedMemberException'); + ValidEnumeration::memberOrNullBy('key', 'DOOM'); } public function testMemberByPredicate() @@ -170,6 +166,24 @@ function (ValidEnumeration $member) { $this->assertNull($defaultNull); } + public function testMembers() + { + $this->assertSame(array( + 'BAZ' => ValidEnumeration::BAZ(), + 'FOO' => ValidEnumeration::FOO(), + 'BAR' => ValidEnumeration::BAR(), + ), ValidEnumeration::members()); + } + + public function testMembersBy() + { + $foo = ValidEnumeration::membersBy('value', 'oof'); + $bar = ValidEnumeration::membersBy('value', 'RAB', false); + + $this->assertSame(array('FOO' => ValidEnumeration::FOO()), $foo); + $this->assertSame(array('BAR' => ValidEnumeration::BAR()), $bar); + } + public function testMembersByPredicate() { $notBaz = ValidEnumeration::membersByPredicate( @@ -280,6 +294,20 @@ public function testMemberByValueWithDefault() $this->assertNull(ValidEnumeration::memberByValueWithDefault('qux')); } + public function testMemberOrNullByValue() + { + $this->assertSame(ValidEnumeration::FOO(), ValidEnumeration::memberOrNullByValue('oof')); + $this->assertSame(ValidEnumeration::BAR(), ValidEnumeration::memberOrNullByValue('rab')); + $this->assertSame(ValidEnumeration::FOO(), ValidEnumeration::memberOrNullByValue('Oof', false)); + $this->assertNull(ValidEnumeration::memberOrNullByValue(null)); + } + + public function testMemberOrNullByValueFailureUndefined() + { + $this->setExpectedException('Eloquent\Enumeration\Exception\UndefinedMemberException'); + ValidEnumeration::memberOrNullByValue('mood'); + } + public function testMembersByValue() { $this->assertSame(array('FOO' => ValidEnumeration::FOO()), ValidEnumeration::membersByValue('oof')); diff --git a/test/suite/AbstractMultitonTest.php b/test/suite/AbstractMultitonTest.php index a3a9bf8..7461f3a 100644 --- a/test/suite/AbstractMultitonTest.php +++ b/test/suite/AbstractMultitonTest.php @@ -32,18 +32,6 @@ protected function setUp() // Multiton tests ========================================================== - public function testMembers() - { - $this->assertSame( - array( - 'FOO' => ValidMultiton::FOO(), - 'BAR' => ValidMultiton::BAR(), - 'BAZ' => ValidMultiton::BAZ(), - ), - ValidMultiton::members() - ); - } - public function testMemberByKey() { $this->assertSame(array(), ValidMultiton::calls()); @@ -118,22 +106,18 @@ public function testMemberByWithDefault() $this->assertNull(ValidMultiton::memberByWithDefault('key', 'qux')); } - public function testMembersBy() + public function testMemberOrNullBy() { - $this->assertSame(array(), ValidMultiton::calls()); - - $foo = ValidMultiton::membersBy('value', 'oof'); - $bar = ValidMultiton::membersBy('value', 'RAB', false); - - $this->assertSame(array('FOO' => ValidMultiton::FOO()), $foo); - $this->assertSame(array('BAR' => ValidMultiton::BAR()), $bar); + $this->assertSame(ValidMultiton::FOO(), ValidMultiton::memberOrNullBy('key', 'FOO')); + $this->assertSame(ValidMultiton::BAR(), ValidMultiton::memberOrNullBy('key', 'BAR')); + $this->assertSame(ValidMultiton::FOO(), ValidMultiton::memberOrNullBy('key', 'Foo', false)); + $this->assertNull(ValidMultiton::memberOrNullBy('key', null)); + } - $this->assertSame(array( - array( - 'Eloquent\Enumeration\Test\Fixture\ValidMultiton::initializeMembers', - array(), - ), - ), ValidMultiton::calls()); + public function testMemberOrNullByFailureUndefined() + { + $this->setExpectedException('Eloquent\Enumeration\Exception\UndefinedMemberException'); + ValidMultiton::memberOrNullBy('key', 'DOOM'); } public function testMemberByPredicate() @@ -205,6 +189,36 @@ function (ValidMultiton $member) { $this->assertNull($defaultNull); } + public function testMembers() + { + $this->assertSame( + array( + 'FOO' => ValidMultiton::FOO(), + 'BAR' => ValidMultiton::BAR(), + 'BAZ' => ValidMultiton::BAZ(), + ), + ValidMultiton::members() + ); + } + + public function testMembersBy() + { + $this->assertSame(array(), ValidMultiton::calls()); + + $foo = ValidMultiton::membersBy('value', 'oof'); + $bar = ValidMultiton::membersBy('value', 'RAB', false); + + $this->assertSame(array('FOO' => ValidMultiton::FOO()), $foo); + $this->assertSame(array('BAR' => ValidMultiton::BAR()), $bar); + + $this->assertSame(array( + array( + 'Eloquent\Enumeration\Test\Fixture\ValidMultiton::initializeMembers', + array(), + ), + ), ValidMultiton::calls()); + } + public function testMembersByPredicate() { $this->assertSame(array(), ValidMultiton::calls()); diff --git a/test/suite/AbstractValueMultitonTest.php b/test/suite/AbstractValueMultitonTest.php index 8da4798..10645b2 100644 --- a/test/suite/AbstractValueMultitonTest.php +++ b/test/suite/AbstractValueMultitonTest.php @@ -32,15 +32,6 @@ protected function setUp() // Multiton tests ========================================================== - public function testMembers() - { - $this->assertSame(array( - 'FOO' => ValidValueMultiton::FOO(), - 'BAR' => ValidValueMultiton::BAR(), - 'BAZ' => ValidValueMultiton::BAZ(), - ), ValidValueMultiton::members()); - } - public function testMemberByKey() { $this->assertSame(array(), ValidValueMultiton::calls()); @@ -115,22 +106,18 @@ public function testMemberByWithDefault() $this->assertNull(ValidValueMultiton::memberByWithDefault('key', 'qux')); } - public function testMembersBy() + public function testMemberOrNullBy() { - $this->assertSame(array(), ValidValueMultiton::calls()); - - $foo = ValidValueMultiton::membersBy('value', 'oof'); - $bar = ValidValueMultiton::membersBy('value', 'RAB', false); - - $this->assertSame(array('FOO' => ValidValueMultiton::FOO()), $foo); - $this->assertSame(array('BAR' => ValidValueMultiton::BAR()), $bar); + $this->assertSame(ValidValueMultiton::FOO(), ValidValueMultiton::memberOrNullBy('key', 'FOO')); + $this->assertSame(ValidValueMultiton::BAR(), ValidValueMultiton::memberOrNullBy('key', 'BAR')); + $this->assertSame(ValidValueMultiton::FOO(), ValidValueMultiton::memberOrNullBy('key', 'Foo', false)); + $this->assertNull(ValidValueMultiton::memberOrNullBy('key', null)); + } - $this->assertSame(array( - array( - 'Eloquent\Enumeration\Test\Fixture\ValidValueMultiton::initializeMembers', - array(), - ), - ), ValidValueMultiton::calls()); + public function testMemberOrNullByFailureUndefined() + { + $this->setExpectedException('Eloquent\Enumeration\Exception\UndefinedMemberException'); + ValidValueMultiton::memberOrNullBy('key', 'DOOM'); } public function testMemberByPredicate() @@ -202,6 +189,33 @@ function (ValidValueMultiton $member) { $this->assertNull($defaultNull); } + public function testMembers() + { + $this->assertSame(array( + 'FOO' => ValidValueMultiton::FOO(), + 'BAR' => ValidValueMultiton::BAR(), + 'BAZ' => ValidValueMultiton::BAZ(), + ), ValidValueMultiton::members()); + } + + public function testMembersBy() + { + $this->assertSame(array(), ValidValueMultiton::calls()); + + $foo = ValidValueMultiton::membersBy('value', 'oof'); + $bar = ValidValueMultiton::membersBy('value', 'RAB', false); + + $this->assertSame(array('FOO' => ValidValueMultiton::FOO()), $foo); + $this->assertSame(array('BAR' => ValidValueMultiton::BAR()), $bar); + + $this->assertSame(array( + array( + 'Eloquent\Enumeration\Test\Fixture\ValidValueMultiton::initializeMembers', + array(), + ), + ), ValidValueMultiton::calls()); + } + public function testMembersByPredicate() { $this->assertSame(array(), ValidValueMultiton::calls()); @@ -309,18 +323,9 @@ public function testMemberByValueFailureUndefined() public function testMemberByValueWithDefault() { - $this->assertSame( - ValidValueMultiton::FOO(), - ValidValueMultiton::memberByValueWithDefault('oof') - ); - $this->assertSame( - ValidValueMultiton::BAR(), - ValidValueMultiton::memberByValueWithDefault('rab') - ); - $this->assertSame( - ValidValueMultiton::FOO(), - ValidValueMultiton::memberByValueWithDefault('Oof', null, false) - ); + $this->assertSame(ValidValueMultiton::FOO(), ValidValueMultiton::memberByValueWithDefault('oof')); + $this->assertSame(ValidValueMultiton::BAR(), ValidValueMultiton::memberByValueWithDefault('rab')); + $this->assertSame(ValidValueMultiton::FOO(), ValidValueMultiton::memberByValueWithDefault('Oof', null, false)); $this->assertSame( ValidValueMultiton::FOO(), ValidValueMultiton::memberByValueWithDefault('qux', ValidValueMultiton::FOO()) @@ -328,6 +333,20 @@ public function testMemberByValueWithDefault() $this->assertNull(ValidValueMultiton::memberByValueWithDefault('qux')); } + public function testMemberOrNullByValue() + { + $this->assertSame(ValidValueMultiton::FOO(), ValidValueMultiton::memberOrNullByValue('oof')); + $this->assertSame(ValidValueMultiton::BAR(), ValidValueMultiton::memberOrNullByValue('rab')); + $this->assertSame(ValidValueMultiton::FOO(), ValidValueMultiton::memberOrNullByValue('Oof', false)); + $this->assertNull(ValidValueMultiton::memberOrNullByValue(null)); + } + + public function testMemberOrNullByValueFailureUndefined() + { + $this->setExpectedException('Eloquent\Enumeration\Exception\UndefinedMemberException'); + ValidValueMultiton::memberOrNullByValue('mood'); + } + public function testMembersByValue() { $this->assertSame(array('FOO' => ValidValueMultiton::FOO()), ValidValueMultiton::membersByValue('oof'));