diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/router_dev.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/router_dev.php index 64c90b4bd2..9e70bf7acd 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/router_dev.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/router_dev.php @@ -25,6 +25,7 @@ if (is_file($_SERVER['DOCUMENT_ROOT'].DIRECTORY_SEPARATOR.$_SERVER['SCRIPT_NAME' return false; } +$_SERVER = array_merge($_SERVER, $_ENV); $_SERVER['SCRIPT_FILENAME'] = $_SERVER['DOCUMENT_ROOT'].DIRECTORY_SEPARATOR.'app_dev.php'; require 'app_dev.php'; diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/router_prod.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/router_prod.php index 4278b4bba1..a3ef29d8db 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/router_prod.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/router_prod.php @@ -25,6 +25,7 @@ if (is_file($_SERVER['DOCUMENT_ROOT'].DIRECTORY_SEPARATOR.$_SERVER['SCRIPT_NAME' return false; } +$_SERVER = array_merge($_SERVER, $_ENV); $_SERVER['SCRIPT_FILENAME'] = $_SERVER['DOCUMENT_ROOT'].DIRECTORY_SEPARATOR.'app.php'; require 'app.php'; diff --git a/src/Symfony/Component/Finder/Shell/Shell.php b/src/Symfony/Component/Finder/Shell/Shell.php index 8586cbc3e5..d17f2fac35 100644 --- a/src/Symfony/Component/Finder/Shell/Shell.php +++ b/src/Symfony/Component/Finder/Shell/Shell.php @@ -50,17 +50,19 @@ class Shell */ public function testCommand($command) { - if (self::TYPE_WINDOWS === $this->type) { - // todo: find a way to test if Windows command exists - return false; - } - if (!function_exists('exec')) { return false; } // todo: find a better way (command could not be available) - exec('command -v '.$command, $output, $code); + $testCommand = 'which '; + if (self::TYPE_WINDOWS === $this->type) { + $testCommand = 'where '; + } + + $command = escapeshellcmd($command); + + exec($testCommand.$command, $output, $code); return 0 === $code && count($output) > 0; } diff --git a/src/Symfony/Component/Form/CallbackTransformer.php b/src/Symfony/Component/Form/CallbackTransformer.php index c53c6df788..03459d4e8a 100644 --- a/src/Symfony/Component/Form/CallbackTransformer.php +++ b/src/Symfony/Component/Form/CallbackTransformer.php @@ -18,24 +18,33 @@ class CallbackTransformer implements DataTransformerInterface { /** * The callback used for forward transform - * @var \Closure + * @var callable */ private $transform; /** * The callback used for reverse transform - * @var \Closure + * @var callable */ private $reverseTransform; /** * Constructor. * - * @param \Closure $transform The forward transform callback - * @param \Closure $reverseTransform The reverse transform callback + * @param callable $transform The forward transform callback + * @param callable $reverseTransform The reverse transform callback + * + * @throws \InvalidArgumentException when the given callbacks is invalid */ - public function __construct(\Closure $transform, \Closure $reverseTransform) + public function __construct($transform, $reverseTransform) { + if (!is_callable($transform)) { + throw new \InvalidArgumentException('Argument 1 should be a callable'); + } + if (!is_callable($reverseTransform)) { + throw new \InvalidArgumentException('Argument 2 should be a callable'); + } + $this->transform = $transform; $this->reverseTransform = $reverseTransform; } @@ -47,7 +56,7 @@ class CallbackTransformer implements DataTransformerInterface * * @return mixed The value in the transformed representation * - * @throws UnexpectedTypeException when the argument is not a string + * @throws UnexpectedTypeException when the argument is not of the expected type * @throws TransformationFailedException when the transformation fails */ public function transform($data) diff --git a/src/Symfony/Component/Form/Tests/CallbackTransformerTest.php b/src/Symfony/Component/Form/Tests/CallbackTransformerTest.php new file mode 100644 index 0000000000..706bc076ec --- /dev/null +++ b/src/Symfony/Component/Form/Tests/CallbackTransformerTest.php @@ -0,0 +1,37 @@ +assertEquals('foo has been transformed', $transformer->transform('foo')); + $this->assertEquals('bar has reversely been transformed', $transformer->reverseTransform('bar')); + } + + /** + * @dataProvider invalidCallbacksProvider + * + * @expectedException \InvalidArgumentException + */ + public function testConstructorWithInvalidCallbacks($transformCallback, $reverseTransformCallback) + { + new CallbackTransformer($transformCallback, $reverseTransformCallback); + } + + public function invalidCallbacksProvider() + { + return array( + array( null, function(){} ), + array( function(){}, null ), + ); + } +} diff --git a/src/Symfony/Component/Process/Tests/AbstractProcessTest.php b/src/Symfony/Component/Process/Tests/AbstractProcessTest.php index 762651465f..03d602476d 100644 --- a/src/Symfony/Component/Process/Tests/AbstractProcessTest.php +++ b/src/Symfony/Component/Process/Tests/AbstractProcessTest.php @@ -260,13 +260,23 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase public function testGetIncrementalErrorOutput() { - $p = $this->getProcess(sprintf('php -r %s', escapeshellarg('$n = 0; while ($n < 3) { usleep(100000); file_put_contents(\'php://stderr\', \'ERROR\'); $n++; }'))); + // use a lock file to toggle between writing ("W") and reading ("R") the + // error stream + $lock = tempnam(sys_get_temp_dir(), get_class($this).'Lock'); + file_put_contents($lock, 'W'); + + $p = $this->getProcess(sprintf('php -r %s', escapeshellarg('$n = 0; while ($n < 3) { if (\'W\' === file_get_contents('.var_export($lock, true).')) { file_put_contents(\'php://stderr\', \'ERROR\'); $n++; file_put_contents('.var_export($lock, true).', \'R\'); } usleep(100); }'))); $p->start(); while ($p->isRunning()) { - $this->assertLessThanOrEqual(1, preg_match_all('/ERROR/', $p->getIncrementalErrorOutput(), $matches)); - usleep(20000); + if ('R' === file_get_contents($lock)) { + $this->assertLessThanOrEqual(1, preg_match_all('/ERROR/', $p->getIncrementalErrorOutput(), $matches)); + file_put_contents($lock, 'W'); + } + usleep(100); } + + unlink($lock); } public function testFlushErrorOutput() @@ -280,7 +290,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase public function testGetOutput() { - $p = $this->getProcess(sprintf('php -r %s', escapeshellarg('$n=0;while ($n<3) {echo \' foo \';$n++; usleep(500); }'))); + $p = $this->getProcess(sprintf('php -r %s', escapeshellarg('$n = 0; while ($n < 3) { echo \' foo \'; $n++; }'))); $p->run(); $this->assertEquals(3, preg_match_all('/foo/', $p->getOutput(), $matches)); @@ -288,13 +298,23 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase public function testGetIncrementalOutput() { - $p = $this->getProcess(sprintf('php -r %s', escapeshellarg('$n=0;while ($n<3) { echo \' foo \'; usleep(50000); $n++; }'))); + // use a lock file to toggle between writing ("W") and reading ("R") the + // output stream + $lock = tempnam(sys_get_temp_dir(), get_class($this).'Lock'); + file_put_contents($lock, 'W'); + + $p = $this->getProcess(sprintf('php -r %s', escapeshellarg('$n = 0; while ($n < 3) { if (\'W\' === file_get_contents('.var_export($lock, true).')) { echo \' foo \'; $n++; file_put_contents('.var_export($lock, true).', \'R\'); } usleep(100); }'))); $p->start(); while ($p->isRunning()) { - $this->assertLessThanOrEqual(1, preg_match_all('/foo/', $p->getIncrementalOutput(), $matches)); - usleep(20000); + if ('R' === file_get_contents($lock)) { + $this->assertLessThanOrEqual(1, preg_match_all('/foo/', $p->getIncrementalOutput(), $matches)); + file_put_contents($lock, 'W'); + } + usleep(100); } + + unlink($lock); } public function testFlushOutput()