Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
LauLaman committed Mar 24, 2016
0 parents commit f22e402
Show file tree
Hide file tree
Showing 10 changed files with 351 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
coverage/
composer
composer.lock
.idea/
vendor/
bin/
13 changes: 13 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
default: help

help:
@echo "Usage:"
@echo " make [command]"
@echo "Available commands:"
@grep '^[^#[:space:]].*:' Makefile | grep -v '^default' | grep -v '^_' | sed 's/://' | xargs -n 1 echo ' -'

coverage:
rm -rf coverage; bin/phpunit --coverage-html=coverage/ --coverage-clover=coverage/clover.xml

unit-tests:
bin/phpunit --testsuite unit
34 changes: 34 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"name": "werkspot/enum",
"description": "Werkspot's Enum Library",
"authors": [
{
"name": "Werkspot Team",
"email": "[email protected]"
},
{
"name": "Laurens Laman",
"email": "[email protected]"
}
],
"autoload": {
"psr-4": {
"Werkspot\\Enum\\": ["src/"]
}
},
"autoload-dev": {
"psr-4": {
"Werkspot\\Enum\\Tests\\": ["tests/"]
}
},
"minimum-stability": "stable",
"require": {
"php": ">=5.6.5"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
},
"config": {
"bin-dir": "bin"
}
}
12 changes: 12 additions & 0 deletions phpunit.bootstrap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php
require_once('vendor/autoload.php');

// Add the 'tests/' directory to the include path for unit tests, as we have Test implementation classes that we need to
// have, but don't want to include in projects that include this library
$loader = new \Composer\Autoload\ClassLoader();

$loader->add('Werkspot\\Enum', ['src/', 'tests/']);

$loader->register();
$loader->setUseIncludePath(true);

27 changes: 27 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>

<!-- http://www.phpunit.de/manual/current/en/appendixes.configuration.html -->
<phpunit
backupGlobals = "false"
backupStaticAttributes = "false"
colors = "true"
convertErrorsToExceptions = "true"
convertNoticesToExceptions = "true"
convertWarningsToExceptions = "true"
processIsolation = "false"
stopOnFailure = "false"
syntaxCheck = "false"
bootstrap = "phpunit.bootstrap.php" >

<!--
<php>
<server name="KERNEL_DIR" value="/path/to/your/app/" />
</php>
-->

<testsuites>
<testsuite name="unit">
<directory>tests</directory>
</testsuite>
</testsuites>
</phpunit>
73 changes: 73 additions & 0 deletions src/AbstractEnum.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php
namespace Werkspot\Enum;

use Werkspot\Enum\Util\ClassNameConverter;

abstract class AbstractEnum
{
protected $value;
protected static $instances = array();

protected function __construct($value)
{
if (!$this->isValid($value)) {
throw new \InvalidArgumentException('Invalid ' . $this->getClassName() . " value: '" . $value . "'");
}

$this->value = $value;
}

/**
* @param $value
*
* @return $this
*/
public static function get($value)
{
$class = get_called_class();
$instanceKey = $class . '.' . $value;

if (!isset(static::$instances[$instanceKey])) {
self::$instances[$instanceKey] = new $class($value);
}

return self::$instances[$instanceKey];
}

public function getValue()
{
return $this->value;
}

public function __toString()
{
if ($this->value === null) {
return '';
}

return (string) $this->value;
}

protected function isValid($value)
{
return in_array($value, $this->getValidOptions(), true);
}

/**
* @return array
*/
public static function getValidOptions()
{
$reflection = new \ReflectionClass(get_called_class());

return array_values($reflection->getConstants());
}

/**
* @return string
*/
protected function getClassName()
{
return ClassNameConverter::stripNameSpace(get_called_class());
}
}
55 changes: 55 additions & 0 deletions src/Util/ClassNameConverter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php
namespace Werkspot\Enum\Util;

class ClassNameConverter
{
/**
* In: ServicePro\SomeCommand
* Out: service_pro.some_command
*
* @param string $className
* @return string
*/
public static function convertClassNameToServiceName($className)
{
// Namespace 'directories' should be '.', like 'ServicePro\Foo' => 'ServicePro.Foo'
$className = str_replace('\\', '.', $className);

// 'ServicePro.Foo' => 'service_pro._foo'
$serviceName = lcfirst($className);
$serviceName = preg_replace('/([A-Z])/', '_$1', $serviceName);

// 'service_pro._foo' => 'service_pro.foo'
$serviceName = str_replace('._', '.', $serviceName);
return strtolower($serviceName);
}

/**
* In: service_pro.some_command
* Out: ServicePro\SomeCommand
*
* @param string $serviceName
* @return string
*/
public static function convertServiceNameToClassName($serviceName)
{
// Namespace 'directories' should be '.', like 'service_pro.foo_class' => 'service_pro\Foo_class'
$className = preg_replace_callback('/\.([a-z])/', function($c) { return '\\' . ucfirst($c[1]); }, $serviceName);

// 'service_pro\Foo_class' => 'ServicePro\FooClass'
$className = preg_replace_callback('/_([a-z])/', function($c) { return ucfirst($c[1]); }, $className);
return ucfirst($className);
}

/**
* In: Some\Namespace\And\Class
* Out: Class
*
* @param string $className
* @return string
*/
public static function stripNameSpace($className)
{
return preg_replace('|.+\\\\|', '', $className);
}
}
76 changes: 76 additions & 0 deletions tests/AbstractEnumTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php
namespace Werkspot\Enum\Tests;

use PHPUnit_Framework_TestCase;

class AbstractEnumTest extends PHPUnit_Framework_TestCase
{
public function testEnum()
{
$a = FooEnum::get(FooEnum::A);
$b = FooEnum::get(FooEnum::B);

$this->assertSame(FooEnum::A, $a->getValue());
$this->assertSame(FooEnum::B, $b->getValue());
$this->assertSame(FooEnum::A, (string) $a);
$this->assertSame(FooEnum::B, (string) $b);
}

public function testNull()
{
$nullEnum = FooEnum::get(null);
$this->assertNull($nullEnum->getValue());
$this->assertSame('', (string) $nullEnum);
}

public function testInteger()
{
$integerEnum = FooEnum::get(3);
$this->assertSame(3, $integerEnum->getValue());
$this->assertSame('3', (string) $integerEnum);
}

public function testSingleton()
{
$a = FooEnum::get(FooEnum::A);
$a2 = FooEnum::get(FooEnum::A);
$b = FooEnum::get(FooEnum::B);

$this->assertSame($a, $a2);
$this->assertNotSame($a, $b);
}

/**
* @expectedException \InvalidArgumentException
* @dataProvider getExceptionData
*/
public function testException($illegalValue)
{
FooEnum::get($illegalValue);
}

public function getExceptionData()
{
return array(
array('a'),
array('bee'),
array('B '),
array('C'),
array(true),
);
}

public function testGetValidOptions()
{
$this->assertSame(
array(
FooEnum::A,
FooEnum::B,
FooEnum::A3,
FooEnum::ANULL,
),
FooEnum::getValidOptions()
);
}

}
12 changes: 12 additions & 0 deletions tests/FooEnum.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php
namespace Werkspot\Enum\Tests;

use Werkspot\Enum\AbstractEnum;

class FooEnum extends AbstractEnum
{
const A = 'A';
const B = 'BEE';
const A3 = 3;
const ANULL = null;
}
43 changes: 43 additions & 0 deletions tests/Util/ClassNameConverterTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php
namespace Werkspot\Enum\Tests\Util;

use PHPUnit_Framework_TestCase;
use Werkspot\Enum\Util\ClassNameConverter;

class ClassNameConverterTest extends PHPUnit_Framework_TestCase
{
/** @dataProvider getConversionData */
public function testConvertClassNameToServiceName($class, $service)
{
$this->assertSame($service, ClassNameConverter::convertClassNameToServiceName($class));
}

/** @dataProvider getConversionData */
public function testConvertServiceNameToClassName($class, $service)
{
$this->assertSame($class, ClassNameConverter::convertServiceNameToClassName($service));
}

public function getConversionData()
{
return array(
array('ServicePro', 'service_pro'),
array('ServicePro\\FooClass', 'service_pro.foo_class'),
);
}

/** @dataProvider getNamespaceData */
public function testStripNamespace($class, $fullClass)
{
$this->assertSame($class, ClassNameConverter::stripNameSpace($fullClass));
}

public function getNamespaceData()
{
return array(
array('ServicePro', 'ServicePro'),
array('FooClass', 'ServicePro\\FooClass'),
array('FooClass', 'Some\\ServicePro\\FooClass'),
);
}
}

0 comments on commit f22e402

Please sign in to comment.