Skip to content

Commit

Permalink
Merge pull request #12 from stephpy/command
Browse files Browse the repository at this point in the history
[WIP] Atoum command
  • Loading branch information
stephpy committed Feb 13, 2013
2 parents c74d6fd + 66dec4c commit e5b211e
Show file tree
Hide file tree
Showing 10 changed files with 454 additions and 1 deletion.
30 changes: 30 additions & 0 deletions AtoumAtoumBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,37 @@
namespace atoum\AtoumBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use atoum\AtoumBundle\DependencyInjection\AtoumAtoumExtension;
use atoum\AtoumBundle\DependencyInjection\Compiler\BundleDirectoriesResolverPass;

/**
* AtoumAtoumBundle
*
* @uses Bundle
* @author Stephane PY <[email protected]>
*/
class AtoumAtoumBundle extends Bundle
{
/**
* {@inheritdoc}
*/
public function build(ContainerBuilder $container)
{
parent::build($container);

$container->addCompilerPass(new BundleDirectoriesResolverPass());
}

/**
* {@inheritdoc}
*/
public function getContainerExtension()
{
if (null === $this->extension) {
$this->extension = new AtoumAtoumExtension;
}

return $this->extension;
}
}
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
* master (next 1.1.0)

* Add command to launch tests on bundles.
* Add fluent interface for controllers testing
* Add support for Faker (https://github.com/fzaninotto/Faker)
* Compatibility break
Expand All @@ -9,4 +10,4 @@
* 1.0.0 (2012)

* Move the bundle to atoum vendor namespace
* Add ControllerTest class
* Add ControllerTest class
141 changes: 141 additions & 0 deletions Command/AtoumCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
<?php

namespace atoum\AtoumBundle\Command;

use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use atoum\AtoumBundle\Configuration\Bundle as BundleConfiguration;
use mageekguy\atoum\scripts\runner;

/**
* AtoumCommand
*
* @uses ContainerAwareCommand
* @author Stephane PY <[email protected]>
*/
class AtoumCommand extends ContainerAwareCommand
{
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('atoum')
->setDescription('Launch atoum tests.')
->setHelp(<<<EOF
Launch tests of AcmeFooBundle:
<comment>./app/console atoum AcmeFooBundle</comment>
Launch tests of many bundles:
<comment>./app/console atoum AcmeFooBundle bundle_alias_extension ...</comment>
Launch tests of all bundles defined on configuration:
<comment>./app/console atoum</comment>
EOF
)
->addArgument('bundles', InputArgument::IS_ARRAY, 'Launch tests of these bundles.')
;
}

/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$runner = new runner('atoum');

$bundles = $input->getArgument('bundles');
if (count($bundles) > 0) {
$self = $this;
$bundles = array_map(function($v) use ($self) {
return $self->extractBundleConfigurationFromKernel($v);
}, $bundles);
} else {
$bundles = $this->getContainer()->get('atoum.configuration.bundle.container')->all();
}

foreach ($bundles as $bundle) {
$directories = array_filter($bundle->getDirectories(), function($dir) {
return is_dir($dir);
});

if (empty($directories)) {
$output->writeln(sprintf('<error>There is no test found on "%s".</error>', $bundle->getName()));
}

foreach ($directories as $directory) {
$runner->addTestAllDirectory($directory);
}
}

if (count($runner->getTestAllDirectories()) == 0) {
$output->writeln('<error>There is no test to launch.</error>');
} else {
$runner->run(array(
'--test-all'
));
}
}

/**
* @param string $name name
*
* @return BundleConfiguration
*/
public function extractBundleConfigurationFromKernel($name)
{
$kernelBundles = $this->getContainer()->get('kernel')->getBundles();
$bundle = null;

if (preg_match('/Bundle$/', $name)) {
if (!isset($kernelBundles[$name])) {
throw new \LogicException(sprintf('Bundle "%s" does not exists or is not activated.', $name));
}

$bundle = $kernelBundles[$name];
} else {
foreach ($kernelBundles as $kernelBundle) {
$extension = $kernelBundle->getContainerExtension();

if ($extension && $extension->getAlias() == $name) {
$bundle = $kernelBundle;
break;
}
}

if (null === $bundle) {
throw new \LogicException(sprintf('Bundle with alias "%s" does not exists or is not activated.', $name));
}
}

$bundleContainer = $this->getContainer()->get('atoum.configuration.bundle.container');

if ($bundleContainer->has($bundle->getName())) {
return $bundleContainer->get($bundle->getName());
} else {
return new BundleConfiguration($bundle->getName(), $this->getDefaultDirectoriesForBundle($bundle));
}
}

/**
* @param Bundle $bundle bundle
*
* @return array
*/
public function getDefaultDirectoriesForBundle(Bundle $bundle)
{
return array(
sprintf('%s/Tests/Units', $bundle->getPath()),
sprintf('%s/Tests/Controller', $bundle->getPath()),
);
}
}
47 changes: 47 additions & 0 deletions Configuration/Bundle.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace atoum\AtoumBundle\Configuration;

/**
* Bundle
*
* @author Stephane PY <[email protected]>
*/
class Bundle
{
/**
* @var string
*/
protected $name;

/**
* @var array
*/
protected $directories = array();

/**
* @param string $name name
* @param array $directories directories
*/
public function __construct($name, array $directories)
{
$this->name = $name;
$this->directories = $directories;
}

/**
* @return string
*/
public function getName()
{
return $this->name;
}

/**
* @return array
*/
public function getDirectories()
{
return $this->directories;
}
}
56 changes: 56 additions & 0 deletions Configuration/BundleContainer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

namespace atoum\AtoumBundle\Configuration;

/**
* BundleContainer
*
* @author Stephane PY <[email protected]>
*/
class BundleContainer
{
/**
* @var array
*/
protected $bundles = array();

/**
* @param Bundle $bundle bundle
*
* @return BundleContainer
*/
public function add(Bundle $bundle)
{
$this->bundles[$bundle->getName()] = $bundle;

return $this;
}

/**
* @param string $ident ident
*
* @return Bundle|null
*/
public function get($ident)
{
return $this->has($ident) ? $this->bundles[$ident] : null;
}

/**
* @param string $ident ident
*
* @return boolean
*/
public function has($ident)
{
return isset($this->bundles[$ident]);
}

/**
* @return array
*/
public function all()
{
return $this->bundles;
}
}
42 changes: 42 additions & 0 deletions DependencyInjection/AtoumAtoumExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

namespace atoum\AtoumBundle\DependencyInjection;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\Config\Definition\Processor;

/**
* AtoumAtoumExtension
*
* @uses Extension
* @author Stephane PY <[email protected]>
*/
class AtoumAtoumExtension extends Extension
{
/**
* {@inheritdoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$processor = new Processor();
$configuration = new Configuration();

$config = $processor->processConfiguration($configuration, $configs);

$loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config/services'));
$loader->load('configuration.xml');

$container->setParameter('atoum.bundles', $config['bundles']);
}

/**
* {@inheritdoc}
*/
public function getAlias()
{
return 'atoum';
}
}
43 changes: 43 additions & 0 deletions DependencyInjection/Compiler/BundleDirectoriesResolverPass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

namespace atoum\AtoumBundle\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Definition;

/**
* BundleDirectoriesResolverPass
*
* @uses CompilerPassInterface
* @author Stephane PY <[email protected]>
*/
class BundleDirectoriesResolverPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$bundles = $container->getParameter('kernel.bundles');
$bundleContainer = $container->getDefinition('atoum.configuration.bundle.container');
$configuration = $container->getParameterBag()->resolveValue($container->getParameter('atoum.bundles'));

foreach ($configuration as $bundleName => $data) {
if (!isset($bundles[$bundleName])) {
throw new \LogicException(sprintf('Bundle "%s" does not exists.', $bundleName));
}

$rc = new \ReflectionClass($bundles[$bundleName]);
$directory = dirname($rc->getFileName());

$directories = array_map(function($v) use ($directory) {
return $directory.'/'.$v;
}, $data['directories']);

$definition = new Definition(
$container->getParameter('atoum.configuration.bundle.class'),
array($bundleName, $directories)
);

$bundleContainer->addMethodCall('add', array($definition));
}
}
}
Loading

0 comments on commit e5b211e

Please sign in to comment.