Changeset 895

Show
Ignore:
Timestamp:
09/06/07 13:47:59 (1 year ago)
Author:
mikey
Message:

refined enum implementation

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/main/php/net/stubbles/lang/stubEnum.php

    r894 r895  
    22/** 
    33 * Base class for enums. 
    4  *  
     4 * 
    55 * @author      Frank Kleine  <mikey@stubbles.net> 
    66 * @package     stubbles 
     
    1010/** 
    1111 * Base class for enums. 
    12  *  
     12 * 
    1313 * @package     stubbles 
    1414 * @subpackage  lang 
     
    2323    protected $name; 
    2424    /** 
    25      * ordinal number of enum 
     25     * value of enum 
    2626     * 
    2727     * @var  int 
    2828     */ 
    29     protected $ordinal
     29    protected $value
    3030 
    3131    /** 
     
    3333     * 
    3434     * @param  string  $name 
    35      * @param  int     $ordinal  optional 
    36      */ 
    37     protected function __construct($name, $ordinal = null) 
    38     { 
    39         $this->name    = $name; 
    40         $this->ordinal = $ordinal
     35     * @param  mixed   $value  optional 
     36     */ 
     37    protected function __construct($name, $value = null) 
     38    { 
     39        $this->name  = $name; 
     40        $this->value = ((null !== $value) ? ($value) : ($name))
    4141    } 
    4242 
     
    6060 
    6161    /** 
    62      * returns the ordinal number of the enum 
    63      * 
    64      * @return  int 
    65      */ 
    66     public function ordinal() 
    67     { 
    68         return $this->ordinal
     62     * returns the value of the enum 
     63     * 
     64     * @return  mixed 
     65     */ 
     66    public function value() 
     67    { 
     68        return $this->value
    6969    } 
    7070 
     
    7676     * @return  stubEnum 
    7777     */ 
    78     public static function valueOf(ReflectionClass $enum, $name) 
    79     { 
    80         if ($enum->isSubclassOf(__CLASS__) === false) { 
    81             throw new stubIllegalArgumentException('Given class is not an instance of net.stubbles.lang.stubEnum.'); 
     78    public static function forName(ReflectionClass $enum, $name) 
     79    { 
     80        if ($enum->isSubclassOf(__CLASS__) === false) { 
     81            throw new stubIllegalArgumentException('Given class is not an instance of ' . stubClassLoader::getFullQualifiedClassName(__CLASS__)); 
    8282        } 
    8383         
     
    9090 
    9191    /** 
     92     * returns the enum instance of given class identified by its value 
     93     * 
     94     * @param   ReflectionClass  $enum 
     95     * @param   string           $name 
     96     * @return  stubEnum 
     97     */ 
     98    public static function forValue(ReflectionClass $enum, $value) 
     99    { 
     100        if ($enum->isSubclassOf(__CLASS__) === false) { 
     101            throw new stubIllegalArgumentException('Given class is not an instance of ' . stubClassLoader::getFullQualifiedClassName(__CLASS__)); 
     102        } 
     103         
     104        try { 
     105            foreach ($enum->getStaticProperties() as $instance) { 
     106                if ($instance->value() === $value) { 
     107                    return $instance; 
     108                } 
     109            } 
     110        } catch (ReflectionException $re) { 
     111            throw new stubIllegalArgumentException($re->getMessage()); 
     112        } 
     113         
     114        throw new stubIllegalArgumentException('Enum ' . stubClassLoader::getFullQualifiedClassName($enum->getName()) . ' for value ' . $value . ' does not exist.'); 
     115    } 
     116 
     117    /** 
     118     * returns a list of all instances for given enum 
     119     * 
     120     * @param   ReflectionClass  $enum 
     121     * @return  array<$enum->getName()> 
     122     * @throws  stubIllegalArgumentException 
     123     */ 
     124    public static function instances(ReflectionClass $enum) 
     125    { 
     126        if ($enum->isSubclassOf(__CLASS__) === false) { 
     127            throw new stubIllegalArgumentException('Given class is not an instance of ' . stubClassLoader::getFullQualifiedClassName(__CLASS__)); 
     128        } 
     129         
     130        return array_values($enum->getStaticProperties()); 
     131    } 
     132 
     133    /** 
     134     * returns a list of enum names for given enum 
     135     * 
     136     * @param   ReflectionClass  $enum 
     137     * @return  array<string> 
     138     * @throws  stubIllegalArgumentException 
     139     */ 
     140    public static function namesOf(ReflectionClass $enum) 
     141    { 
     142        if ($enum->isSubclassOf(__CLASS__) === false) { 
     143            throw new stubIllegalArgumentException('Given class is not an instance of ' . stubClassLoader::getFullQualifiedClassName(__CLASS__)); 
     144        } 
     145         
     146        return array_keys($enum->getStaticProperties()); 
     147    } 
     148 
     149    /** 
     150     * returns a list of values for given enum 
     151     * 
     152     * @param   ReflectionClass      $enum 
     153     * @return  array<string,mixed> 
     154     * @throws  stubIllegalArgumentException 
     155     */ 
     156    public static function valuesOf(ReflectionClass $enum) 
     157    { 
     158        if ($enum->isSubclassOf(__CLASS__) === false) { 
     159            throw new stubIllegalArgumentException('Given class is not an instance of ' . stubClassLoader::getFullQualifiedClassName(__CLASS__)); 
     160        } 
     161         
     162        $values = array(); 
     163        foreach ($enum->getStaticProperties() as $name => $instance) { 
     164            $values[$name] = $instance->value; 
     165        } 
     166         
     167        return $values; 
     168    } 
     169 
     170    /** 
    92171     * checks whether a value is equal to the class 
    93172     * 
     
    115194        $string  = $this->getClassName() . " {\n"; 
    116195        $string .= '    ' . $this->name . "\n"; 
    117         if (null !== $this->ordinal) { 
    118             $string .= '    ' . $this->ordinal . "\n"; 
    119         } 
    120          
     196        $string .= '    ' . $this->value . "\n"; 
    121197        $string .= "}\n"; 
    122198        return $string; 
  • trunk/src/test/php/net/stubbles/lang/stubEnumTestCase.php

    r894 r895  
    88 */ 
    99stubClassLoader::load('net.stubbles.lang.stubEnum'); 
     10/** 
     11 * Concrete instance of net.stubbles.lang.stubEnum. 
     12 * 
     13 * @author      Frank Kleine <mikey@stubbles.net> 
     14 * @package     stubbles 
     15 * @subpackage  lang_test 
     16 */ 
    1017class TeststubEnum extends stubEnum 
    1118{ 
     
    1320    public static $BAR; 
    1421     
    15     public static function init($ordinals = false) 
    16     { 
    17         if (false === $ordinals) { 
     22    public static function init($values = false) 
     23    { 
     24        if (false === $values) { 
    1825            self::$FOO = new self('FOO'); 
    1926            self::$BAR = new self('BAR'); 
     
    4855     * assure that enums work as expected 
    4956     */ 
    50     public function testWithoutOrdinal() 
     57    public function testWithoutValues() 
    5158    { 
    5259        $this->assertEqual(TeststubEnum::$FOO->name(), 'FOO'); 
    5360        $this->assertEqual(TeststubEnum::$BAR->name(), 'BAR'); 
    54         $this->assertNull(TeststubEnum::$FOO->ordinal()); 
    55         $this->assertNull(TeststubEnum::$BAR->ordinal()); 
     61        $this->assertEqual(TeststubEnum::$FOO->value(), 'FOO'); 
     62        $this->assertEqual(TeststubEnum::$BAR->value(), 'BAR'); 
    5663        $this->assertTrue(TeststubEnum::$FOO->equals(TeststubEnum::$FOO)); 
    5764        $this->assertFalse(TeststubEnum::$FOO->equals(TeststubEnum::$BAR)); 
    5865        $this->assertFalse(TeststubEnum::$BAR->equals(TeststubEnum::$FOO)); 
    5966        $this->assertFalse(TeststubEnum::$BAR->equals(new stdClass())); 
    60         $this->assertEqual((string) TeststubEnum::$FOO, "net.stubbles.lang.TeststubEnum {\n    FOO\n}\n"); 
    61         $this->assertEqual((string) TeststubEnum::$BAR, "net.stubbles.lang.TeststubEnum {\n    BAR\n}\n"); 
     67        $this->assertEqual((string) TeststubEnum::$FOO, "net.stubbles.lang.TeststubEnum {\n    FOO\n    FOO\n}\n"); 
     68        $this->assertEqual((string) TeststubEnum::$BAR, "net.stubbles.lang.TeststubEnum {\n    BAR\n    BAR\n}\n"); 
    6269    } 
    6370 
     
    6572     * assure that enums work as expected 
    6673     */ 
    67     public function testWithOrdinal() 
     74    public function testWithValues() 
    6875    { 
    6976        TeststubEnum::init(true); 
    7077        $this->assertEqual(TeststubEnum::$FOO->name(), 'FOO'); 
    7178        $this->assertEqual(TeststubEnum::$BAR->name(), 'BAR'); 
    72         $this->assertEqual(TeststubEnum::$FOO->ordinal(), 10); 
    73         $this->assertEqual(TeststubEnum::$BAR->ordinal(), 20); 
     79        $this->assertEqual(TeststubEnum::$FOO->value(), 10); 
     80        $this->assertEqual(TeststubEnum::$BAR->value(), 20); 
    7481        $this->assertTrue(TeststubEnum::$FOO->equals(TeststubEnum::$FOO)); 
    7582        $this->assertFalse(TeststubEnum::$FOO->equals(TeststubEnum::$BAR)); 
     
    8794    public function testClone() 
    8895    { 
    89         TeststubEnum::init(); 
    9096        $this->expectException('stubRuntimeException'); 
    9197        $foo = clone (TeststubEnum::$FOO); 
     
    9399 
    94100    /** 
    95      * assure that valueOf() works as expected 
    96      */ 
    97     public function testValueOf() 
    98     { 
    99         TeststubEnum::init(); 
    100         $foo = stubEnum::valueOf(new ReflectionClass('TeststubEnum'), 'FOO'); 
     101     * assure that forName() works as expected 
     102     */ 
     103    public function testForName() 
     104    { 
     105        $foo = stubEnum::forName(new ReflectionClass('TeststubEnum'), 'FOO'); 
    101106        $this->assertReference($foo, TeststubEnum::$FOO); 
    102         $bar = stubEnum::valueOf(new ReflectionClass('TeststubEnum'), 'BAR'); 
     107        $bar = stubEnum::forName(new ReflectionClass('TeststubEnum'), 'BAR'); 
    103108        $this->assertReference($bar, TeststubEnum::$BAR); 
    104109    } 
    105110 
    106111    /** 
    107      * assure that valueOf() works as expected 
    108      */ 
    109     public function testValueOfNonExistingName() 
    110     { 
    111         $this->expectException('stubIllegalArgumentException'); 
    112         stubEnum::valueOf(new ReflectionClass('TeststubEnum'), 'BAZ'); 
    113     } 
    114  
    115     /** 
    116      * assure that valueOf() works as expected 
    117      */ 
    118     public function testValueOfWrongClass() 
    119     { 
    120         $this->expectException('stubIllegalArgumentException'); 
    121         stubEnum::valueOf(new ReflectionClass('stdClass'), 'BAZ'); 
     112     * assure that forName() works as expected 
     113     */ 
     114    public function testForNameNonExistingName() 
     115    { 
     116        $this->expectException('stubIllegalArgumentException'); 
     117        stubEnum::forName(new ReflectionClass('TeststubEnum'), 'BAZ'); 
     118    } 
     119 
     120    /** 
     121     * assure that forName() works as expected 
     122     */ 
     123    public function testForNameWrongClass() 
     124    { 
     125        $this->expectException('stubIllegalArgumentException'); 
     126        stubEnum::forName(new ReflectionClass('stdClass'), 'BAZ'); 
     127    } 
     128 
     129    /** 
     130     * assure that forValue() works as expected 
     131     */ 
     132    public function testForValueWithoutValues() 
     133    { 
     134        $foo = stubEnum::forValue(new ReflectionClass('TeststubEnum'), 'FOO'); 
     135        $this->assertReference($foo, TeststubEnum::$FOO); 
     136        $bar = stubEnum::forValue(new ReflectionClass('TeststubEnum'), 'BAR'); 
     137        $this->assertReference($bar, TeststubEnum::$BAR); 
     138    } 
     139 
     140    /** 
     141     * assure that forValue() works as expected 
     142     */ 
     143    public function testForValueWithValues() 
     144    { 
     145        TeststubEnum::init(true); 
     146        $foo = stubEnum::forValue(new ReflectionClass('TeststubEnum'), 10); 
     147        $this->assertReference($foo, TeststubEnum::$FOO); 
     148        $bar = stubEnum::forValue(new ReflectionClass('TeststubEnum'), 20); 
     149        $this->assertReference($bar, TeststubEnum::$BAR); 
     150    } 
     151 
     152    /** 
     153     * assure that forValue() works as expected 
     154     */ 
     155    public function testForValueNonExistingValue() 
     156    { 
     157        $this->expectException('stubIllegalArgumentException'); 
     158        stubEnum::forValue(new ReflectionClass('TeststubEnum'), 'BAZ'); 
     159    } 
     160 
     161    /** 
     162     * assure that forValue() works as expected 
     163     */ 
     164    public function testForValueWrongClass() 
     165    { 
     166        $this->expectException('stubIllegalArgumentException'); 
     167        stubEnum::forValue(new ReflectionClass('stdClass'), 'BAZ'); 
     168    } 
     169 
     170    /** 
     171     * assure that instances() works as expected 
     172     */ 
     173    public function testInstances() 
     174    { 
     175        $this->assertEqual(stubEnum::instances(new ReflectionClass('TeststubEnum')), array(TeststubEnum::$FOO, TeststubEnum::$BAR)); 
     176    } 
     177 
     178    /** 
     179     * assure that instances() works as expected 
     180     */ 
     181    public function testInstancesWrongClass() 
     182    { 
     183        $this->expectException('stubIllegalArgumentException'); 
     184        stubEnum::instances(new ReflectionClass('stdClass')); 
     185    } 
     186 
     187    /** 
     188     * assure that namesOf() works as expected 
     189     */ 
     190    public function testNamesOf() 
     191    { 
     192        $this->assertEqual(stubEnum::namesOf(new ReflectionClass('TeststubEnum')), array('FOO', 'BAR')); 
     193    } 
     194 
     195    /** 
     196     * assure that namesOf() works as expected 
     197     */ 
     198    public function testNamesOfWrongClass() 
     199    { 
     200        $this->expectException('stubIllegalArgumentException'); 
     201        stubEnum::namesOf(new ReflectionClass('stdClass')); 
     202    } 
     203 
     204    /** 
     205     * assure that instance() works as expected 
     206     */ 
     207    public function testValuesOfWithoutValues() 
     208    { 
     209        $this->assertEqual(stubEnum::valuesOf(new ReflectionClass('TeststubEnum')), array('FOO' => 'FOO', 'BAR' => 'BAR')); 
     210    } 
     211 
     212    /** 
     213     * assure that instance() works as expected 
     214     */ 
     215    public function testValuesOfWithValues() 
     216    { 
     217        TeststubEnum::init(true); 
     218        $this->assertEqual(stubEnum::valuesOf(new ReflectionClass('TeststubEnum')), array('FOO' => 10, 'BAR' => 20)); 
     219    } 
     220 
     221    /** 
     222     * assure that valuesOf() works as expected 
     223     */ 
     224    public function testValuesOfWrongClass() 
     225    { 
     226        $this->expectException('stubIllegalArgumentException'); 
     227        stubEnum::valuesOf(new ReflectionClass('stdClass')); 
    122228    } 
    123229}