Created
August 7, 2012 12:18
-
-
Save jubianchi/3284862 to your computer and use it in GitHub Desktop.
Conditionnal configuration validation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use \mageekguy\atoum; | |
define('COVERAGE_TITLE', 'Config'); | |
define('COVERAGE_DIRECTORY', './coverage'); | |
define('COVERAGE_WEB_PATH', 'http://%host%/coverage'); | |
if(false === is_dir(COVERAGE_DIRECTORY)) | |
{ | |
mkdir(COVERAGE_DIRECTORY, 0777, true); | |
} | |
$coverageField = new atoum\report\fields\runner\coverage\html(COVERAGE_TITLE, COVERAGE_DIRECTORY); | |
$coverageField->setRootUrl(COVERAGE_WEB_PATH); | |
$stdOutWriter = new atoum\writers\std\out(); | |
$cliReport = new atoum\reports\realtime\cli(); | |
$cliReport | |
->addWriter($stdOutWriter) | |
->addField($coverageField, array(atoum\runner::runStop)) | |
; | |
$xunitFileWriter = new atoum\writers\file('atoum.xml'); | |
$xunit = new atoum\reports\asynchronous\xunit(); | |
$xunit->addWriter($xunitFileWriter); | |
$cloverFileWriter = new atoum\writers\file('atoum.coverage.xml'); | |
$clover = new atoum\reports\asynchronous\clover(); | |
$clover->addWriter($cloverFileWriter); | |
$runner->addReport($cliReport); | |
$runner->addReport($clover); | |
$runner->addReport($xunit); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace jubianchi\Config; | |
class Chart extends Table implements Type { | |
const TYPE_NAME = 'chart'; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace tests\unit\jubianchi\Config; | |
use mageekguy\atoum; | |
use jubianchi\Config\Chart as TestedClass; | |
require_once dirname(__DIR__) . '/../../../vendor/autoload.php'; | |
require_once dirname(__DIR__) . '/../../../vendor/mageekguy/atoum/scripts/runner.php'; | |
class Chart extends atoum\test { | |
public function testConstants() { | |
$this | |
->string(TestedClass::TYPE_NAME)->isEqualTo('chart') | |
->string(TestedClass::CLASS_ATTR)->isEqualTo('class') | |
->string(TestedClass::COLS_ATTR)->isEqualTo('columns') | |
->string(TestedClass::ROWS_ATTR)->isEqualTo('rows') | |
; | |
} | |
public function testGetType() { | |
$this | |
->if($object = new TestedClass()) | |
->then | |
->string($object->getType())->isEqualTo(TestedClass::TYPE_NAME) | |
; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "sandbox", | |
"type": "script", | |
"description": "PHP Sandbox", | |
"authors": [ | |
{ | |
"name": "Julien Bianchi", | |
"email": "[email protected]", | |
"homepage": "http://jubianchi.fr" | |
} | |
], | |
"autoload": { | |
"psr-0": { "jubianchi": "src/" } | |
}, | |
"minimum-stability": "dev", | |
"require": { | |
"php": ">=5.3.2", | |
"symfony/config": "*" | |
}, | |
"require-dev": { | |
"mageekguy/atoum": "dev-master" | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"hash": "709c1a146f21274a7a6253c4a07e795e", | |
"packages": [ | |
{ | |
"package": "symfony/config", | |
"version": "dev-master", | |
"source-reference": "v2.1.0-RC1", | |
"commit-date": "1343512949" | |
} | |
], | |
"packages-dev": [ | |
{ | |
"package": "mageekguy/atoum", | |
"version": "dev-master", | |
"source-reference": "8ff37c48b558a33ce9cdfa252937e8ca08713364", | |
"commit-date": "1343308831" | |
} | |
], | |
"aliases": [ | |
], | |
"minimum-stability": "dev", | |
"stability-flags": { | |
"mageekguy/atoum": 20 | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace jubianchi\Config; | |
class Configuration { | |
const ROOT_NAME = 'layouts'; | |
const TYPE_ATTR = 'type'; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace tests\unit\jubianchi\Config; | |
use mageekguy\atoum; | |
use jubianchi\Config\Configuration as TestedClass; | |
require_once dirname(__DIR__) . '/../../../vendor/autoload.php'; | |
require_once dirname(__DIR__) . '/../../../vendor/mageekguy/atoum/scripts/runner.php'; | |
class Configuration extends atoum\test { | |
public function testConstants() { | |
$this | |
->string(TestedClass::ROOT_NAME)->isEqualTo('layouts') | |
->string(TestedClass::TYPE_ATTR)->isEqualTo('type') | |
; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use jubianchi\Config\Configuration, | |
jubianchi\Config\Table, | |
jubianchi\Config\Listing, | |
jubianchi\Config\Chart; | |
require_once __DIR__ . '/vendor/autoload.php'; | |
$config = array( | |
'layouts' => array( | |
'tableau' => array( | |
Configuration::TYPE_ATTR => Table::TYPE_NAME, | |
Table::CLASS_ATTR => 'formated_table', | |
Table::ROWS_ATTR => array('measures'), | |
Table::COLS_ATTR => array('dim1', 'dim2') | |
), | |
'liste' => array( | |
Configuration::TYPE_ATTR => Listing::TYPE_NAME, | |
Listing::CLASS_ATTR => 'formated_table', | |
Listing::ITEMS_ATTR => array('measures') | |
), | |
'graphique' => array( | |
Configuration::TYPE_ATTR => Chart::TYPE_NAME, | |
Chart::CLASS_ATTR => 'formated_table', | |
Chart::ROWS_ATTR => array('measures'), | |
Chart::COLS_ATTR => array('dim1', 'dim2') | |
) | |
) | |
); | |
$validator = new \jubianchi\Config\Validator(); | |
$validator->validate($config, new \jubianchi\Config\TypeFinder()); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace jubianchi\Config; | |
class Listing implements Type { | |
const TYPE_NAME = 'listing'; | |
const CLASS_ATTR = 'class'; | |
const ITEMS_ATTR = 'items'; | |
/** | |
* @static | |
* | |
* @return string | |
*/ | |
public static function getType() { | |
return static::TYPE_NAME; | |
} | |
/** | |
* @static | |
* | |
* @return array | |
*/ | |
public static function getFields() { | |
return array(static::CLASS_ATTR, static::ITEMS_ATTR); | |
} | |
/** | |
* @static | |
* | |
* @param \Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition $root | |
*/ | |
public static function build(\Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition $root) { | |
$root | |
->children() | |
->scalarNode(static::CLASS_ATTR)->isRequired()->end() | |
->arrayNode(static::ITEMS_ATTR) | |
->isRequired() | |
->prototype('scalar')->end() | |
->end() | |
->end() | |
; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace tests\unit\jubianchi\Config; | |
use mageekguy\atoum; | |
use jubianchi\Config\Listing as TestedClass; | |
require_once dirname(__DIR__) . '/../../../vendor/autoload.php'; | |
require_once dirname(__DIR__) . '/../../../vendor/mageekguy/atoum/scripts/runner.php'; | |
class Listing extends atoum\test { | |
public function testConstants() { | |
$this | |
->string(TestedClass::TYPE_NAME)->isEqualTo('listing') | |
->string(TestedClass::CLASS_ATTR)->isEqualTo('class') | |
->string(TestedClass::ITEMS_ATTR)->isEqualTo('items') | |
; | |
} | |
public function testGetType() { | |
$this | |
->if($object = new TestedClass()) | |
->then | |
->string($object->getType())->isEqualTo(TestedClass::TYPE_NAME) | |
; | |
} | |
public function testGetFields() { | |
$this | |
->if($object = new TestedClass()) | |
->then | |
->array($object->getFields())->isIdenticalTo(array(TestedClass::CLASS_ATTR, TestedClass::ITEMS_ATTR)) | |
; | |
} | |
public function testBuild() { | |
$this | |
->if($object = new TestedClass()) | |
->and($builder = new \mock\Symfony\Component\Config\Definition\Builder\NodeBuilder()) | |
->and($root = new \mock\Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition(uniqid())) | |
->and($node = new \mock\Symfony\Component\Config\Definition\Builder\NodeDefinition(uniqid())) | |
->and($builder->getMockController()->scalarNode = function() use($node) { return $node; }) | |
->and($builder->getMockController()->arrayNode = function() use($root) { return $root; }) | |
->and($root->getMockController()->children = function() use($builder) { return $builder; }) | |
->and($root->getMockController()->end = function() use($builder) { return $builder; }) | |
->and($node->getMockController()->end = function() use($builder) { return $builder; }) | |
->and($node->getMockController()->isRequired = function() use($node) { return $node; }) | |
->then | |
->variable($object->build($root))->isNull() | |
->mock($root) | |
->call('children')->once() | |
; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace jubianchi\Config; | |
class Table implements Type { | |
const TYPE_NAME = 'table'; | |
const CLASS_ATTR = 'class'; | |
const ROWS_ATTR = 'rows'; | |
const COLS_ATTR = 'columns'; | |
/** | |
* @static | |
* | |
* @return string | |
*/ | |
public static function getType() { | |
return static::TYPE_NAME; | |
} | |
/** | |
* @static | |
* | |
* @return array | |
*/ | |
public static function getFields() { | |
return array(static::CLASS_ATTR, static::ROWS_ATTR, static::COLS_ATTR); | |
} | |
/** | |
* @static | |
* | |
* @param \Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition $root | |
*/ | |
public static function build(\Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition $root) { | |
$root | |
->children() | |
->scalarNode(static::CLASS_ATTR)->isRequired()->end() | |
->arrayNode(static::ROWS_ATTR) | |
->isRequired() | |
->prototype('scalar')->end() | |
->end() | |
->arrayNode(static::COLS_ATTR) | |
->isRequired() | |
->prototype('scalar')->end() | |
->end() | |
->end() | |
; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace tests\unit\jubianchi\Config; | |
use mageekguy\atoum; | |
use jubianchi\Config\Table as TestedClass; | |
require_once dirname(__DIR__) . '/../../../vendor/autoload.php'; | |
require_once dirname(__DIR__) . '/../../../vendor/mageekguy/atoum/scripts/runner.php'; | |
class Table extends atoum\test { | |
public function testConstants() { | |
$this | |
->string(TestedClass::TYPE_NAME)->isEqualTo('table') | |
->string(TestedClass::CLASS_ATTR)->isEqualTo('class') | |
->string(TestedClass::COLS_ATTR)->isEqualTo('columns') | |
->string(TestedClass::ROWS_ATTR)->isEqualTo('rows') | |
; | |
} | |
public function testGetType() { | |
$this | |
->if($object = new TestedClass()) | |
->then | |
->string($object->getType())->isEqualTo(TestedClass::TYPE_NAME) | |
; | |
} | |
public function testGetFields() { | |
$this | |
->if($object = new TestedClass()) | |
->then | |
->array($object->getFields())->isIdenticalTo(array(TestedClass::CLASS_ATTR, TestedClass::ROWS_ATTR, TestedClass::COLS_ATTR)) | |
; | |
} | |
public function testBuild() { | |
$this | |
->if($object = new TestedClass()) | |
->and($builder = new \mock\Symfony\Component\Config\Definition\Builder\NodeBuilder()) | |
->and($root = new \mock\Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition(uniqid())) | |
->and($node = new \mock\Symfony\Component\Config\Definition\Builder\NodeDefinition(uniqid())) | |
->and($builder->getMockController()->scalarNode = function() use($node) { return $node; }) | |
->and($builder->getMockController()->arrayNode = function() use($root) { return $root; }) | |
->and($root->getMockController()->children = function() use($builder) { return $builder; }) | |
->and($root->getMockController()->end = function() use($builder) { return $builder; }) | |
->and($node->getMockController()->end = function() use($builder) { return $builder; }) | |
->and($node->getMockController()->isRequired = function() use($node) { return $node; }) | |
->then | |
->variable($object->build($root))->isNull() | |
->mock($root) | |
->call('children')->once() | |
; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace jubianchi\Config; | |
interface Type { | |
/** | |
* @static | |
* @abstract | |
* | |
* @return string | |
*/ | |
static function getType(); | |
/** | |
* @static | |
* @abstract | |
* | |
* @return array | |
*/ | |
static function getFields(); | |
/** | |
* @static | |
* @abstract | |
* | |
* @param \Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition $root | |
*/ | |
static function build(\Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition $root); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace jubianchi\Config; | |
use mageekguy\atoum\adapter; | |
class TypeFinder { | |
private $adapter; | |
public function setAdapter(adapter $adapter) { | |
$this->adapter = $adapter; | |
return $this; | |
} | |
public function getAdapter() { | |
if(null === $this->adapter) { | |
$this->setAdapter(new adapter()); | |
} | |
return $this->adapter; | |
} | |
/** | |
* This should be changed to a better strategy!!! | |
* * Use a classmap | |
* * Use Symfony2 tagged services | |
* | |
* @return array | |
*/ | |
public function getValidTypes() { | |
$classes = $this->getAdapter()->get_declared_classes(); | |
$types = array(); | |
foreach($classes as $class) { | |
if($this->getAdapter()->is_subclass_of($class, '\\jubianchi\\Config\\Type')) { | |
$types[$class] = $class::getType(); | |
} | |
} | |
return $types; | |
} | |
/** | |
* @param string $type | |
* | |
* @return mixed|null | |
*/ | |
public function getClassFromType($type) { | |
$class = array_search($type, $this->getValidTypes()); | |
return false !== $class ? $class : null; | |
} | |
/** | |
* @return array | |
*/ | |
public function getValidFields() { | |
$fields = array(); | |
foreach($this->getValidTypes() as $class => $type) { | |
$fields = array_unique(array_merge($class::getFields(), $fields)); | |
} | |
return $fields; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace tests\unit\jubianchi\Config; | |
use mageekguy\atoum; | |
use jubianchi\Config\TypeFinder as TestedClass; | |
require_once dirname(__DIR__) . '/../../../vendor/autoload.php'; | |
require_once dirname(__DIR__) . '/../../../vendor/mageekguy/atoum/scripts/runner.php'; | |
/** | |
* @ignore on | |
*/ | |
class BazType implements \jubianchi\Config\Type { | |
static function getType() | |
{ | |
return 'baz'; | |
} | |
static function getFields() | |
{ | |
return array('foo', 'bar'); | |
} | |
static function build(\Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition $root) | |
{ | |
} | |
} | |
class TypeFinder extends atoum\test { | |
public function testSetAdapter() { | |
$this | |
->if($object = new TestedClass()) | |
->and($adapter = new \mageekguy\atoum\adapter()) | |
->then | |
->object($object->setAdapter($adapter))->isIdenticalTo($object) | |
->object($object->getAdapter())->isIdenticalTo($adapter) | |
; | |
} | |
public function testGetAdapter() { | |
$this | |
->if($object = new TestedClass()) | |
->then | |
->object($object->getAdapter())->isInstanceOf('\\mageekguy\\atoum\\adapter') | |
; | |
} | |
public function testGetValidTypes() { | |
$this | |
->if($object = new TestedClass()) | |
->and($adapter = new \mageekguy\atoum\test\adapter()) | |
->and($object->setAdapter($adapter)) | |
->and($adapter->get_declared_classes = array()) | |
->then | |
->array($object->getValidTypes())->isEqualTo(array()) | |
->adapter($adapter) | |
->call('get_declared_classes')->once() | |
->if($adapter->get_declared_classes = array('Foo\\Bar', 'Bar\\Foo')) | |
->then | |
->array($object->getValidTypes())->isEqualTo(array()) | |
->adapter($adapter) | |
->call('is_subclass_of')->withArguments('Foo\\Bar', '\\jubianchi\\Config\\Type')->once() | |
->call('is_subclass_of')->withArguments('Bar\\Foo', '\\jubianchi\\Config\\Type')->once() | |
->if($object = new TestedClass()) | |
->then | |
->array($object->getValidTypes())->isEqualTo(array( | |
'tests\\unit\\jubianchi\\Config\\BazType' => 'baz' | |
)) | |
; | |
} | |
public function testGetClassFromType() { | |
$this | |
->if($object = new TestedClass()) | |
->then | |
->string($object->getClassFromType('baz'))->isEqualTo('tests\\unit\\jubianchi\\Config\\BazType') | |
->variable($object->getClassFromType(uniqid()))->isNull() | |
; | |
} | |
public function testGetValidFields() { | |
$this | |
->if($object = new TestedClass()) | |
->then | |
->array($object->getValidFields())->isEqualTo(array('foo', 'bar')) | |
->if($object = new TestedClass()) | |
->and($adapter = new \mageekguy\atoum\test\adapter()) | |
->and($object->setAdapter($adapter)) | |
->and($adapter->get_declared_classes = array()) | |
->then | |
->array($object->getValidFields())->isEqualTo(array()) | |
; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace jubianchi\Config; | |
use Symfony\Component\Config\Definition\Builder\TreeBuilder, | |
Symfony\Component\Config\Definition\Processor, | |
Symfony\Component\Config\Definition\Exception\InvalidConfigurationException, | |
jubianchi\Config\TypeFinder; | |
class Validator { | |
/** @var \Symfony\Component\Config\Definition\Builder\TreeBuilder */ | |
private $builder; | |
/** @var \Symfony\Component\Config\Definition\Builder\NodeDefinition */ | |
private $root; | |
/** @var \Symfony\Component\Config\Definition\Builder\NodeDefinition */ | |
private $prototype; | |
/** | |
* @return \Symfony\Component\Config\Definition\Builder\TreeBuilder | |
*/ | |
public function getNewBuilder() { | |
return new TreeBuilder(); | |
} | |
/** | |
* @return \Symfony\Component\Config\Definition\Processor | |
*/ | |
public function getNewProcessor() { | |
return new Processor(); | |
} | |
/** | |
* @return \Symfony\Component\Config\Definition\Builder\TreeBuilder | |
*/ | |
public function getBuilder() { | |
if(null === $this->builder) { | |
$this->builder = $this->getNewBuilder(); | |
} | |
return $this->builder; | |
} | |
/** | |
* @return \Symfony\Component\Config\Definition\Builder\NodeDefinition | |
*/ | |
public function getRoot() { | |
if(null === $this->root) { | |
$this->root = $this->getBuilder()->root(Configuration::ROOT_NAME); | |
} | |
return $this->root; | |
} | |
/** | |
* @return \Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition | |
*/ | |
public function getPrototype() { | |
if(null === $this->prototype) { | |
$this->prototype = $this->getRoot()->prototype('array'); | |
} | |
return $this->prototype; | |
} | |
/** | |
* @param TypeFinder $finder | |
* @throws \RuntimeException | |
* @throws \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException | |
*/ | |
protected function build(TypeFinder $finder) { | |
$prototype = $this->getPrototype(); | |
try { | |
$prototype | |
->children() | |
->enumNode(Configuration::TYPE_ATTR)->values($finder->getValidTypes())->end() | |
->end() | |
; | |
} catch(\InvalidArgumentException $exception) { | |
throw new \RuntimeException('No valid types found', $exception->getCode(), $exception); | |
} | |
foreach($finder->getValidFields() as $field) { | |
$prototype->append(new \Symfony\Component\Config\Definition\Builder\VariableNodeDefinition($field)); | |
} | |
$self = $this; | |
$prototype | |
->validate() | |
->ifTrue(function($v) { return is_array($v); }) | |
->then(function($v) use($self, $finder) { | |
$builder = $self->getNewBuilder(); | |
$root = $builder->root($v[Configuration::TYPE_ATTR]); | |
$root->children()->scalarNode(Configuration::TYPE_ATTR)->isRequired()->end(); | |
$validator = $finder->getClassFromType($v[Configuration::TYPE_ATTR]); | |
if(null === $validator) { | |
throw new InvalidConfigurationException( | |
sprintf( | |
'No validator defined for type "%s"', | |
$v[Configuration::TYPE_ATTR] | |
) | |
); | |
} | |
$validator::build($root); | |
$self->process(array($v[Configuration::TYPE_ATTR] => $v), $builder); | |
}) | |
->end() | |
; | |
} | |
/** | |
* @param array $config | |
* @param TypeFinder $finder | |
*/ | |
public function validate(array $config, TypeFinder $finder) { | |
$this->build($finder); | |
$this->process($config, $this->getBuilder()); | |
} | |
/** | |
* @param array $config | |
* @param \Symfony\Component\Config\Definition\Builder\TreeBuilder $builder | |
*/ | |
public function process(array $config, TreeBuilder $builder) { | |
$this->getNewProcessor()->process($builder->buildTree(), $config); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace tests\unit\jubianchi\Config; | |
use mageekguy\atoum; | |
use jubianchi\Config\Validator as TestedClass; | |
require_once dirname(__DIR__) . '/../../../vendor/autoload.php'; | |
require_once dirname(__DIR__) . '/../../../vendor/mageekguy/atoum/scripts/runner.php'; | |
/** | |
* @ignore on | |
*/ | |
class FooType implements \jubianchi\Config\Type { | |
static function getType() | |
{ | |
return 'foo'; | |
} | |
static function getFields() | |
{ | |
return array('foo', 'bar'); | |
} | |
static function build(\Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition $root) | |
{ | |
} | |
} | |
/** | |
* @ignore on | |
*/ | |
class BarType implements \jubianchi\Config\Type { | |
static function getType() | |
{ | |
return 'bar'; | |
} | |
static function getFields() | |
{ | |
return array('foo', 'bar'); | |
} | |
static function build(\Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition $root) | |
{ | |
} | |
} | |
class Validator extends atoum\test { | |
public function testGetNewBuilder() { | |
$this | |
->if($object = new TestedClass()) | |
->then | |
->object($builder = $object->getNewBuilder())->isInstanceOf('\\Symfony\\Component\\Config\\Definition\\Builder\\TreeBuilder') | |
->object($object->getNewBuilder())->isNotIdenticalTo($builder) | |
; | |
} | |
public function testGetNewProcessor() { | |
$this | |
->if($object = new TestedClass()) | |
->then | |
->object($processor = $object->getNewProcessor())->isInstanceOf('\\Symfony\\Component\\Config\\Definition\\Processor') | |
->object($object->getNewProcessor())->isNotIdenticalTo($processor) | |
; | |
} | |
public function testGetBuilder() { | |
$this | |
->if($object = new \mock\jubianchi\Config\Validator()) | |
->then | |
->object($builder = $object->getBuilder())->isInstanceOf('\\Symfony\\Component\\Config\\Definition\\Builder\\TreeBuilder') | |
->object($object->getBuilder())->isIdenticalTo($builder) | |
->mock($object) | |
->call('getNewBuilder')->once() | |
; | |
} | |
public function testGetRoot() { | |
$this | |
->if($object = new \mock\jubianchi\Config\Validator()) | |
->and($object->getMockController()->getBuilder = $builder = new \mock\Symfony\Component\Config\Definition\Builder\TreeBuilder()) | |
->then | |
->object($root = $object->getRoot())->isInstanceOf('\\Symfony\\Component\\Config\\Definition\\Builder\\ArrayNodeDefinition') | |
->object($object->getRoot())->isIdenticalTo($root) | |
->mock($object) | |
->call('getBuilder')->once() | |
->mock($builder) | |
->call('root')->withArguments(\jubianchi\Config\Configuration::ROOT_NAME) | |
; | |
} | |
public function testGetPrototype() { | |
$this | |
->if($object = new \mock\jubianchi\Config\Validator()) | |
->and($object->getMockController()->getRoot = $root = new \mock\Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition(uniqid())) | |
->then | |
->object($prototype = $object->getPrototype())->isInstanceOf('\\Symfony\\Component\\Config\\Definition\\Builder\\NodeDefinition') | |
->object($object->getPrototype())->isIdenticalTo($prototype) | |
->mock($object) | |
->call('getRoot')->once() | |
->mock($root) | |
->call('prototype')->withArguments('array') | |
; | |
} | |
public function testValidate() { | |
$this | |
->if($object = new \mock\jubianchi\Config\Validator()) | |
->and($object->getMockController()->getBuilder = $builder = new \mock\Symfony\Component\Config\Definition\Builder\TreeBuilder()) | |
->and($finder = new \mock\jubianchi\Config\TypeFinder()) | |
->and($finder->getMockController()->getValidTypes = array( | |
'tests\\unit\\jubianchi\Config\\FooType' => 'foo', | |
'tests\\unit\\jubianchi\Config\\BarType' => 'bar' | |
)) | |
->then | |
->variable($object->validate(array(), $finder))->isNull() | |
->mock($object) | |
->call('process')->withArguments(array(), $builder)->once() | |
->if($object->getMockController()->getPrototype = $prototype = new \mock\Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition(uniqid())) | |
->and($finder->getMockController()->getValidFields = array('foo', 'bar')) | |
->and($prototype->getMockController()->append = function() use($prototype) { return $prototype; }) | |
->then | |
->variable($object->validate(array(), $finder))->isNull() | |
->mock($prototype) | |
->call('append')->withArguments(new \Symfony\Component\Config\Definition\Builder\VariableNodeDefinition('foo'))->once() | |
->call('append')->withArguments(new \Symfony\Component\Config\Definition\Builder\VariableNodeDefinition('bar'))->once() | |
->if($finder->getMockController()->getValidTypes = array()) | |
->then | |
->exception(function() use($object, $finder) { | |
$object->validate(array(), $finder); | |
}) | |
->isInstanceOf('\\RuntimeException') | |
->hasMessage('No valid types found') | |
; | |
} | |
public function testProcess() { | |
$this | |
->if($object = new \mock\jubianchi\Config\Validator()) | |
->and($object->getMockController()->getNewProcessor = $processor = new \mock\Symfony\Component\Config\Definition\Processor()) | |
->and($builder = new \mock\Symfony\Component\Config\Definition\Builder\TreeBuilder()) | |
->and($builder->root(uniqid())) | |
->then | |
->variable($object->process(array(), $builder))->isNull() | |
->mock($processor) | |
->call('process')->withArguments($builder->buildTree(), array())->once() | |
; | |
} | |
} |
Author
jubianchi
commented
Aug 8, 2012
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment