diff --git a/.gitignore b/.gitignore
index 76f1ab9a39..0f504231b6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,4 @@ phpunit.xml
composer.phar
package.tar
/packages.json
+/.phpunit
diff --git a/.travis.yml b/.travis.yml
index 09fac89e0d..d6d25cc6a9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,9 +3,9 @@ language: php
sudo: false
addons:
- apt_packages:
- - parallel
- - language-pack-fr-base
+ apt_packages:
+ - parallel
+ - language-pack-fr-base
matrix:
include:
@@ -15,9 +15,8 @@ matrix:
- php: 5.5
- php: 5.6
env: deps=low
- - php: 5.6
+ - php: 7.0
env: deps=high
- - php: nightly
fast_finish: true
services: mongodb
@@ -30,26 +29,24 @@ env:
before_install:
- composer self-update
- if [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then echo "memory_limit = -1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini; fi;
- - if [[ "$TRAVIS_PHP_VERSION" != "nightly" ]] && [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then phpenv config-rm xdebug.ini; fi;
- - if [[ "$TRAVIS_PHP_VERSION" != "nightly" ]] && [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then echo "extension = mongo.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi;
- - if [[ "$TRAVIS_PHP_VERSION" != "nightly" ]] && [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]] && [ $(php -r "echo PHP_MINOR_VERSION;") -le 4 ]; then echo "extension = apc.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi;
- - if [[ "$TRAVIS_PHP_VERSION" != "nightly" ]] && [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then (pecl install -f memcached-2.1.0 && echo "extension = memcache.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini) || echo "Let's continue without memcache extension"; fi;
- - if [[ "$TRAVIS_PHP_VERSION" != "nightly" ]] && [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then (cd src/Symfony/Component/Debug/Resources/ext && phpize && ./configure && make && echo "extension = $(pwd)/modules/symfony_debug.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini); fi;
- - if [[ "$TRAVIS_PHP_VERSION" != "nightly" ]] && [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then php -i; fi;
- # Build a standalone phpunit without symfony/yaml and that works around https://github.com/sebastianbergmann/phpunit-mock-objects/issues/223
- - (mkdir phpunit && cd phpunit && wget https://github.com/sebastianbergmann/phpunit/archive/4.7.zip && unzip 4.7.zip && cd phpunit-4.7 && composer remove --no-update symfony/yaml && composer require --prefer-source phpunit/phpunit-mock-objects '2.3.0')
- - export PHPUNIT="$(readlink -f ./phpunit/phpunit-4.7/phpunit) --colors=always"
- # Set the COMPOSER_ROOT_VERSION to the right version according to the branch being built
- - if [ "$TRAVIS_BRANCH" = "master" ]; then export COMPOSER_ROOT_VERSION=dev-master; else export COMPOSER_ROOT_VERSION="$TRAVIS_BRANCH".x-dev; fi;
+ - if [[ "$TRAVIS_PHP_VERSION" = 5.* ]]; then phpenv config-rm xdebug.ini; fi;
+ - if [[ "$TRAVIS_PHP_VERSION" = 5.* ]]; then echo "extension = mongo.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi;
+ - if [[ "$TRAVIS_PHP_VERSION" =~ 5.[34] ]]; then echo "extension = apc.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi;
+ - if [[ "$TRAVIS_PHP_VERSION" = 5.* ]]; then (pecl install -f memcached-2.1.0 && echo "extension = memcache.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini) || echo "Let's continue without memcache extension"; fi;
+ - if [[ "$TRAVIS_PHP_VERSION" = 5.* ]]; then (cd src/Symfony/Component/Debug/Resources/ext && phpize && ./configure && make && echo "extension = $(pwd)/modules/symfony_debug.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini); fi;
+ - if [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then php -i; fi;
+ - ./phpunit install
+ - export PHPUNIT="$(readlink -f ./phpunit)"
install:
+ - if [ "$TRAVIS_BRANCH" = "master" ]; then export COMPOSER_ROOT_VERSION=dev-master; else export COMPOSER_ROOT_VERSION="$TRAVIS_BRANCH".x-dev; fi;
- if [ "$deps" = "no" ]; then export SYMFONY_DEPRECATIONS_HELPER=strict; fi;
- if [ "$deps" = "no" ]; then composer --prefer-source install; fi;
- - components=$(find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist -printf '%h\n')
- - if [ "$deps" != "no" ]; then php .travis.php $TRAVIS_COMMIT_RANGE $TRAVIS_BRANCH $components; fi;
+ - COMPONENTS=$(find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist -printf '%h\n')
+ - if [ "$deps" != "no" ]; then php .travis.php $TRAVIS_COMMIT_RANGE $TRAVIS_BRANCH $COMPONENTS; fi;
script:
- - if [ "$deps" = "no" ]; then echo "$components" | parallel --gnu --keep-order 'echo -e "\\nRunning {} tests"; $PHPUNIT --exclude-group tty,benchmark,intl-data {} || (echo -e "\\e[41mKO\\e[0m {}" && $(exit 1));'; fi;
- - if [ "$deps" = "no" ]; then echo -e "\\nRunning tests requiring tty"; $PHPUNIT --group tty || (echo -e "\\e[41mKO\\e[0m tty group" && $(exit 1)); fi;
- - if [ "$deps" = "high" ]; then echo "$components" | parallel --gnu --keep-order -j10% 'echo -e "\\nRunning {} tests"; cd {}; composer --prefer-source update; $PHPUNIT --exclude-group tty,benchmark,intl-data,legacy || (echo -e "\\e[41mKO\\e[0m {}" && $(exit 1));'; fi;
- - if [ "$deps" = "low" ]; then echo "$components" | parallel --gnu --keep-order -j10% 'echo -e "\\nRunning {} tests"; cd {}; composer --prefer-source --prefer-lowest --prefer-stable update; $PHPUNIT --exclude-group tty,benchmark,intl-data || (echo -e "\\e[41mKO\\e[0m {}" && $(exit 1));'; fi;
+ - if [ "$deps" = "no" ]; then echo "$COMPONENTS" | parallel --gnu --keep-order 'echo -e "\\nRunning {} tests"; $PHPUNIT --exclude-group tty,benchmark,intl-data {}'; fi;
+ - if [ "$deps" = "no" ]; then echo -e "\\nRunning tests requiring tty"; $PHPUNIT --group tty; fi;
+ - if [ "$deps" = "high" ]; then echo "$COMPONENTS" | parallel --gnu --keep-order -j10% 'echo -e "\\nRunning {} tests"; cd {}; composer --prefer-source update; $PHPUNIT --exclude-group tty,benchmark,intl-data,legacy'; fi;
+ - if [ "$deps" = "low" ]; then echo "$COMPONENTS" | parallel --gnu --keep-order -j10% 'echo -e "\\nRunning {} tests"; cd {}; composer --prefer-source --prefer-lowest --prefer-stable update; $PHPUNIT --exclude-group tty,benchmark,intl-data'; fi;
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 0000000000..f0484755f9
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,53 @@
+build: false
+shallow_clone: true
+platform: x86
+clone_folder: c:\projects\symfony
+
+environment:
+ matrix:
+ - PHP_EXT: 1
+ - PHP_EXT: 0
+
+cache:
+ - c:\php -> appveyor.yml
+ - .phpunit -> phpunit
+
+init:
+ - SET PATH=c:\php;%PATH%
+ - SET COMPOSER_NO_INTERACTION=1
+ - SET SYMFONY_DEPRECATIONS_HELPER=strict
+ - SET PHP=1
+ - SET ANSICON=121x90 (121x90)
+
+install:
+ - IF EXIST c:\php (SET PHP=0) ELSE (mkdir c:\php)
+ - cd c:\php
+ - IF %PHP%==1 appveyor DownloadFile http://windows.php.net/downloads/releases/archives/php-5.4.43-nts-Win32-VC9-x86.zip
+ - IF %PHP%==1 7z x php-5.4.43-nts-Win32-VC9-x86.zip -y > 7z.log
+ - IF %PHP%==1 appveyor DownloadFile http://nebm.ist.utl.pt/~glopes/misc/intl_win/ICU-51.2-dlls.zip
+ - IF %PHP%==1 7z x ICU-51.2-dlls.zip -y > 7z.log
+ - IF %PHP%==1 cd ext
+ - IF %PHP%==1 appveyor DownloadFile http://nebm.ist.utl.pt/~glopes/misc/intl_win/php_intl-3.0.0-5.4-nts-vc9-x86.zip
+ - IF %PHP%==1 7z x php_intl-3.0.0-5.4-nts-vc9-x86.zip -y > 7z.log
+ - IF %PHP%==1 appveyor DownloadFile http://windows.php.net/downloads/pecl/releases/apc/3.1.13/php_apc-3.1.13-5.4-nts-vc9-x86.zip
+ - IF %PHP%==1 7z x php_apc-3.1.13-5.4-nts-vc9-x86.zip -y > 7z.log
+ - IF %PHP%==1 cd ..
+ - IF %PHP%==1 echo @php %%~dp0composer.phar %%* > composer.bat
+ - appveyor DownloadFile https://getcomposer.org/composer.phar
+ - copy php.ini-production php.ini /Y
+ - echo date.timezone="UTC" >> php.ini
+ - echo extension_dir=ext >> php.ini
+ - echo extension=php_openssl.dll >> php.ini
+ - IF %PHP_EXT%==1 echo extension=php_apc.dll >> php.ini
+ - IF %PHP_EXT%==1 echo extension=php_intl.dll >> php.ini
+ - IF %PHP_EXT%==1 echo extension=php_mbstring.dll >> php.ini
+ - IF %PHP_EXT%==1 echo extension=php_fileinfo.dll >> php.ini
+ - IF %PHP_EXT%==1 echo extension=php_pdo_sqlite.dll >> php.ini
+ - cd c:\projects\symfony
+ - php phpunit install
+ - IF %APPVEYOR_REPO_BRANCH%==master (SET COMPOSER_ROOT_VERSION=dev-master) ELSE (SET COMPOSER_ROOT_VERSION=%APPVEYOR_REPO_BRANCH%.x-dev)
+ - composer update --prefer-source --no-progress --ansi
+
+test_script:
+ - cd c:\projects\symfony
+ - php phpunit symfony --exclude-group benchmark,intl-data
diff --git a/phpunit b/phpunit
new file mode 100755
index 0000000000..cc1bbc8e83
--- /dev/null
+++ b/phpunit
@@ -0,0 +1,126 @@
+#!/usr/bin/env php
+open("$PHPUNIT_VERSION.zip");
+ $zip->extractTo(getcwd());
+ $zip->close();
+ chdir("phpunit-$PHPUNIT_VERSION");
+ passthru("composer remove --no-update symfony/yaml");
+ passthru("composer install --prefer-source --no-progress --ansi");
+ chdir($oldPwd);
+}
+
+$cmd = array_map('escapeshellarg', $argv);
+$exit = 0;
+
+if (isset($argv[1]) && 'symfony' === $argv[1]) {
+ // Find Symfony components in plain php for Windows portability
+
+ $finder = new RecursiveDirectoryIterator('src/Symfony', FilesystemIterator::KEY_AS_FILENAME | FilesystemIterator::UNIX_PATHS);
+ $finder = new RecursiveIteratorIterator($finder);
+ $finder->setMaxDepth(3);
+
+ array_shift($cmd);
+ $cmd[0] = "php $PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/phpunit --colors=always";
+ $procs = array();
+
+ foreach ($finder as $file => $fileInfo) {
+ if ('phpunit.xml.dist' === $file) {
+ $component = dirname($fileInfo->getPathname());
+
+ // Run phpunit tests in parallel
+
+ $c = escapeshellarg($component);
+
+ if ($proc = proc_open(implode(' ', $cmd)." $c > $c/phpunit.stdout 2> $c/phpunit.stderr", array(), $pipes)) {
+ $procs[$component] = $proc;
+ } else {
+ $exit = 1;
+ echo "\033[41mKO\033[0m $component\n\n";
+ }
+ }
+ }
+
+ // Fixes for colors support on appveyor
+ // See http://help.appveyor.com/discussions/suggestions/197-support-ansi-color-codes
+ $colorFixes = array(
+ array("S\033[0m\033[0m\033[36m\033[1mS", "E\033[0m\033[0m\033[31m\033[1mE", "I\033[0m\033[0m\033[33m\033[1mI", "F\033[0m\033[0m\033[41m\033[37mF"),
+ array("SS", "EE", "II", "FF"),
+ );
+ $colorFixes[0] = array_merge($colorFixes[0], $colorFixes[0]);
+ $colorFixes[1] = array_merge($colorFixes[1], $colorFixes[1]);
+
+ foreach ($procs as $component => $proc) {
+ $procStatus = proc_close($proc);
+
+ foreach (array('out', 'err') as $file) {
+ $file = "$component/phpunit.std$file";
+
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $h = fopen($file, 'rb');
+ while (false !== $line = fgets($h)) {
+ echo str_replace($colorFixes[0], $colorFixes[1], preg_replace(
+ '/(\033\[[0-9]++);([0-9]++m)(?:(.)(\033\[0m))?/',
+ "$1m\033[$2$3$4$4",
+ $line
+ ));
+ }
+ fclose($h);
+ } else {
+ readfile($file);
+ }
+ unlink($file);
+ }
+
+ if ($procStatus) {
+ $exit = 1;
+ echo "\033[41mKO\033[0m $component\n\n";
+ } else {
+ echo "\033[32mOK\033[0m $component\n\n";
+ }
+ }
+
+} elseif (!isset($argv[1]) || 'install' !== $argv[1]) {
+ // Run regular phpunit in a subprocess
+
+ $cmd[0] = "php $PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/phpunit --colors=always";
+
+ $errFile = tempnam(sys_get_temp_dir(), 'phpunit.stderr.');
+ if ($proc = proc_open(implode(' ', $cmd).' 2> '.escapeshellarg($errFile), array(1 => array('pipe', 'w')), $pipes)) {
+ stream_copy_to_stream($pipes[1], STDOUT);
+ fclose($pipes[1]);
+ $exit = proc_close($proc);
+
+ readfile($errFile);
+ unlink($errFile);
+ }
+
+ if (!file_exists($component = array_pop($argv))) {
+ $component = basename(getcwd());
+ }
+
+ if ($exit) {
+ echo "\033[41mKO\033[0m $component\n\n";
+ } else {
+ echo "\033[32mOK\033[0m $component\n\n";
+ }
+}
+
+exit($exit);
diff --git a/src/Symfony/Bridge/Twig/Extension/CodeExtension.php b/src/Symfony/Bridge/Twig/Extension/CodeExtension.php
index e4955db0d0..b7c3605d95 100644
--- a/src/Symfony/Bridge/Twig/Extension/CodeExtension.php
+++ b/src/Symfony/Bridge/Twig/Extension/CodeExtension.php
@@ -32,7 +32,7 @@ class CodeExtension extends \Twig_Extension
public function __construct($fileLinkFormat, $rootDir, $charset)
{
$this->fileLinkFormat = $fileLinkFormat ?: ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format');
- $this->rootDir = str_replace('\\', '/', dirname($rootDir)).'/';
+ $this->rootDir = str_replace('/', DIRECTORY_SEPARATOR, dirname($rootDir)).DIRECTORY_SEPARATOR;
$this->charset = $charset;
}
@@ -163,11 +163,11 @@ class CodeExtension extends \Twig_Extension
$file = trim($file);
if (null === $text) {
- $text = str_replace('\\', '/', $file);
+ $text = str_replace('/', DIRECTORY_SEPARATOR, $file);
if (0 === strpos($text, $this->rootDir)) {
$text = substr($text, strlen($this->rootDir));
- $text = explode('/', $text, 2);
- $text = sprintf('%s%s', $this->rootDir, $text[0], isset($text[1]) ? '/'.$text[1] : '');
+ $text = explode(DIRECTORY_SEPARATOR, $text, 2);
+ $text = sprintf('%s%s', $this->rootDir, $text[0], isset($text[1]) ? DIRECTORY_SEPARATOR.$text[1] : '');
}
}
diff --git a/src/Symfony/Bridge/Twig/Tests/Command/LintCommandTest.php b/src/Symfony/Bridge/Twig/Tests/Command/LintCommandTest.php
index a86f74b548..877e4b98eb 100644
--- a/src/Symfony/Bridge/Twig/Tests/Command/LintCommandTest.php
+++ b/src/Symfony/Bridge/Twig/Tests/Command/LintCommandTest.php
@@ -28,7 +28,7 @@ class LintCommandTest extends \PHPUnit_Framework_TestCase
$tester = $this->createCommandTester();
$filename = $this->createFile('{{ foo }}');
- $ret = $tester->execute(array('filename' => array($filename)), array('verbosity' => OutputInterface::VERBOSITY_VERBOSE));
+ $ret = $tester->execute(array('filename' => array($filename)), array('verbosity' => OutputInterface::VERBOSITY_VERBOSE, 'decorated' => false));
$this->assertEquals(0, $ret, 'Returns 0 in case of success');
$this->assertRegExp('/^OK in /', $tester->getDisplay());
@@ -39,7 +39,7 @@ class LintCommandTest extends \PHPUnit_Framework_TestCase
$tester = $this->createCommandTester();
$filename = $this->createFile('{{ foo');
- $ret = $tester->execute(array('filename' => array($filename)));
+ $ret = $tester->execute(array('filename' => array($filename)), array('decorated' => false));
$this->assertEquals(1, $ret, 'Returns 1 in case of error');
$this->assertRegExp('/^KO in /', $tester->getDisplay());
@@ -54,7 +54,7 @@ class LintCommandTest extends \PHPUnit_Framework_TestCase
$filename = $this->createFile('');
unlink($filename);
- $ret = $tester->execute(array('filename' => array($filename)));
+ $ret = $tester->execute(array('filename' => array($filename)), array('decorated' => false));
}
public function testLintFileCompileTimeException()
@@ -62,7 +62,7 @@ class LintCommandTest extends \PHPUnit_Framework_TestCase
$tester = $this->createCommandTester();
$filename = $this->createFile("{{ 2|number_format(2, decimal_point='.', ',') }}");
- $ret = $tester->execute(array('filename' => array($filename)));
+ $ret = $tester->execute(array('filename' => array($filename)), array('decorated' => false));
$this->assertEquals(1, $ret, 'Returns 1 in case of error');
$this->assertRegExp('/^KO in /', $tester->getDisplay());
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
index bad9f51c32..023276e476 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
@@ -424,7 +424,7 @@ class Configuration implements ConfigurationInterface
->addDefaultChildrenIfNoneSet()
->prototype('scalar')->defaultValue('FrameworkBundle:Form')->end()
->validate()
- ->ifNotInArray(array('FrameworkBundle:Form'))
+ ->ifTrue(function ($v) {return !in_array('FrameworkBundle:Form', $v); })
->then(function ($v) {
return array_merge(array('FrameworkBundle:Form'), $v);
})
diff --git a/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateFilenameParser.php b/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateFilenameParser.php
index a4a5e92cf3..df3ab19c4d 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateFilenameParser.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateFilenameParser.php
@@ -31,7 +31,7 @@ class TemplateFilenameParser implements TemplateNameParserInterface
return $name;
}
- $parts = explode('/', strtr($name, '\\', '/'));
+ $parts = explode('/', str_replace('\\', '/', $name));
$elements = explode('.', array_pop($parts));
if (3 > count($elements)) {
diff --git a/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateNameParser.php b/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateNameParser.php
index 5730807fac..e4a7053d25 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateNameParser.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateNameParser.php
@@ -49,7 +49,7 @@ class TemplateNameParser extends BaseTemplateNameParser
}
// normalize name
- $name = str_replace(':/', ':', preg_replace('#/{2,}#', '/', strtr($name, '\\', '/')));
+ $name = str_replace(':/', ':', preg_replace('#/{2,}#', '/', str_replace('\\', '/', $name)));
if (false !== strpos($name, '..')) {
throw new \RuntimeException(sprintf('Template name "%s" contains invalid characters.', $name));
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php
index 621ea4bdee..04b6c95b46 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php
@@ -27,6 +27,19 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
);
}
+ public function testDoNoDuplicateDefaultFormResources()
+ {
+ $input = array('templating' => array(
+ 'form' => array('resources' => array('FrameworkBundle:Form')),
+ 'engines' => array('php'),
+ ));
+
+ $processor = new Processor();
+ $config = $processor->processConfiguration(new Configuration(true), array($input));
+
+ $this->assertEquals(array('FrameworkBundle:Form'), $config['templating']['form']['resources']);
+ }
+
/**
* @dataProvider getTestValidTrustedProxiesData
*/
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
index 7d3445ec7a..6e220740a5 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
@@ -276,7 +276,7 @@ abstract class FrameworkExtensionTest extends TestCase
$container = $this->createContainerFromFile('full');
$ref = new \ReflectionClass('Symfony\Component\Form\Form');
- $xmlMappings = array(realpath(dirname($ref->getFileName()).'/Resources/config/validation.xml'));
+ $xmlMappings = array(dirname($ref->getFileName()).'/Resources/config/validation.xml');
$calls = $container->getDefinition('validator.builder')->getMethodCalls();
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php
index 8f8e6ba7e0..86a69fdb76 100644
--- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php
@@ -33,8 +33,8 @@ class UserPasswordEncoderCommandTest extends WebTestCase
'password' => 'password',
'user-class' => 'Symfony\Component\Security\Core\User\User',
'--empty-salt' => true,
- ));
- $expected = file_get_contents(__DIR__.'/app/PasswordEncode/emptysalt.txt');
+ ), array('decorated' => false));
+ $expected = str_replace("\n", PHP_EOL, file_get_contents(__DIR__.'/app/PasswordEncode/emptysalt.txt'));
$this->assertEquals($expected, $this->passwordEncoderCommandTester->getDisplay());
}
diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Configuration.php
index 9056ea299e..52c70f3318 100644
--- a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Configuration.php
+++ b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Configuration.php
@@ -81,7 +81,7 @@ class Configuration implements ConfigurationInterface
->prototype('scalar')->defaultValue('form_div_layout.html.twig')->end()
->example(array('MyBundle::form.html.twig'))
->validate()
- ->ifNotInArray(array('form_div_layout.html.twig'))
+ ->ifTrue(function ($v) {return !in_array('form_div_layout.html.twig', $v); })
->then(function ($v) {
return array_merge(array('form_div_layout.html.twig'), $v);
})
diff --git a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/ConfigurationTest.php b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/ConfigurationTest.php
new file mode 100644
index 0000000000..4dfb54eb76
--- /dev/null
+++ b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/ConfigurationTest.php
@@ -0,0 +1,30 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\TwigBundle\Tests\DependencyInjection;
+
+use Symfony\Bundle\TwigBundle\DependencyInjection\Configuration;
+use Symfony\Component\Config\Definition\Processor;
+
+class ConfigurationTest extends \PHPUnit_Framework_TestCase
+{
+ public function testDoNoDuplicateDefaultFormResources()
+ {
+ $input = array(
+ 'form_themes' => array('form_div_layout.html.twig'),
+ );
+
+ $processor = new Processor();
+ $config = $processor->processConfiguration(new Configuration(), array($input));
+
+ $this->assertEquals(array('form_div_layout.html.twig'), $config['form_themes']);
+ }
+}
diff --git a/src/Symfony/Component/ClassLoader/Tests/ClassMapGeneratorTest.php b/src/Symfony/Component/ClassLoader/Tests/ClassMapGeneratorTest.php
index e6756f1898..7bdf5aa0dc 100644
--- a/src/Symfony/Component/ClassLoader/Tests/ClassMapGeneratorTest.php
+++ b/src/Symfony/Component/ClassLoader/Tests/ClassMapGeneratorTest.php
@@ -140,10 +140,10 @@ class ClassMapGeneratorTest extends \PHPUnit_Framework_TestCase
protected function assertEqualsNormalized($expected, $actual, $message = null)
{
foreach ($expected as $ns => $path) {
- $expected[$ns] = strtr($path, '\\', '/');
+ $expected[$ns] = str_replace('\\', '/', $path);
}
foreach ($actual as $ns => $path) {
- $actual[$ns] = strtr($path, '\\', '/');
+ $actual[$ns] = str_replace('\\', '/', $path);
}
$this->assertEquals($expected, $actual, $message);
}
diff --git a/src/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php b/src/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php
index 0c891ca20a..c3b2fcdea3 100644
--- a/src/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php
+++ b/src/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php
@@ -257,7 +257,7 @@ class XmlReferenceDumper
$indent = strlen($text) + $indent;
$format = '%'.$indent.'s';
- $this->reference .= sprintf($format, $text)."\n";
+ $this->reference .= sprintf($format, $text).PHP_EOL;
}
/**
diff --git a/src/Symfony/Component/Config/Tests/Definition/Dumper/XmlReferenceDumperTest.php b/src/Symfony/Component/Config/Tests/Definition/Dumper/XmlReferenceDumperTest.php
index ab6bdaa79e..699751da7a 100644
--- a/src/Symfony/Component/Config/Tests/Definition/Dumper/XmlReferenceDumperTest.php
+++ b/src/Symfony/Component/Config/Tests/Definition/Dumper/XmlReferenceDumperTest.php
@@ -34,7 +34,7 @@ class XmlReferenceDumperTest extends \PHPUnit_Framework_TestCase
private function getConfigurationAsString()
{
- return <<
@@ -75,6 +75,7 @@ class XmlReferenceDumperTest extends \PHPUnit_Framework_TestCase
-EOL;
+EOL
+ );
}
}
diff --git a/src/Symfony/Component/Console/Tests/ApplicationTest.php b/src/Symfony/Component/Console/Tests/ApplicationTest.php
index dfee2321d5..45242cf1cf 100644
--- a/src/Symfony/Component/Console/Tests/ApplicationTest.php
+++ b/src/Symfony/Component/Console/Tests/ApplicationTest.php
@@ -553,6 +553,10 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
public function testRenderExceptionWithDoubleWidthCharacters()
{
+ if (!function_exists('mb_strwidth')) {
+ $this->markTestSkipped('The "mb_strwidth" function is not available');
+ }
+
$application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth'));
$application->setAutoExit(false);
$application->expects($this->any())
diff --git a/src/Symfony/Component/Console/Tests/Helper/ProcessHelperTest.php b/src/Symfony/Component/Console/Tests/Helper/ProcessHelperTest.php
index 9f83885a50..a51fb4359d 100644
--- a/src/Symfony/Component/Console/Tests/Helper/ProcessHelperTest.php
+++ b/src/Symfony/Component/Console/Tests/Helper/ProcessHelperTest.php
@@ -75,7 +75,7 @@ EOT;
EOT;
$syntaxErrorOutputDebug = <<42\';"', StreamOutput::VERBOSITY_DEBUG, null),
array('', 'php -r "syntax error"', StreamOutput::VERBOSITY_VERBOSE, null),
array($syntaxErrorOutputVerbose, 'php -r "fwrite(STDERR, \'error message\');usleep(50000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_VERY_VERBOSE, null),
- array($syntaxErrorOutputDebug, 'php -r "fwrite(STDERR, \'error message\');usleep(50000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_DEBUG, null),
+ array($syntaxErrorOutputDebug, 'php -r "fwrite(STDERR, \'error message\');usleep(500000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_DEBUG, null),
array($errorMessage.PHP_EOL, 'php -r "fwrite(STDERR, \'error message\');usleep(50000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_VERBOSE, $errorMessage),
array($syntaxErrorOutputVerbose.$errorMessage.PHP_EOL, 'php -r "fwrite(STDERR, \'error message\');usleep(50000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_VERY_VERBOSE, $errorMessage),
- array($syntaxErrorOutputDebug.$errorMessage.PHP_EOL, 'php -r "fwrite(STDERR, \'error message\');usleep(50000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_DEBUG, $errorMessage),
+ array($syntaxErrorOutputDebug.$errorMessage.PHP_EOL, 'php -r "fwrite(STDERR, \'error message\');usleep(500000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_DEBUG, $errorMessage),
array($successOutputProcessDebug, array('php', '-r', 'echo 42;'), StreamOutput::VERBOSITY_DEBUG, null),
array($successOutputDebug, new Process('php -r "echo 42;"'), StreamOutput::VERBOSITY_DEBUG, null),
);
diff --git a/src/Symfony/Component/DomCrawler/Crawler.php b/src/Symfony/Component/DomCrawler/Crawler.php
index 3fd87bd766..0ab6b98221 100644
--- a/src/Symfony/Component/DomCrawler/Crawler.php
+++ b/src/Symfony/Component/DomCrawler/Crawler.php
@@ -166,20 +166,43 @@ class Crawler extends \SplObjectStorage
$dom = new \DOMDocument('1.0', $charset);
$dom->validateOnParse = true;
- if (function_exists('mb_convert_encoding')) {
- $hasError = false;
- set_error_handler(function () use (&$hasError) {
- $hasError = true;
- });
- $tmpContent = @mb_convert_encoding($content, 'HTML-ENTITIES', $charset);
+ set_error_handler(function () {throw new \Exception();});
- restore_error_handler();
+ try {
+ // Convert charset to HTML-entities to work around bugs in DOMDocument::loadHTML()
- if (!$hasError) {
- $content = $tmpContent;
+ if (function_exists('mb_convert_encoding')) {
+ $content = mb_convert_encoding($content, 'HTML-ENTITIES', $charset);
+ } elseif (function_exists('iconv')) {
+ $content = preg_replace_callback(
+ '/[\x80-\xFF]+/',
+ function ($m) {
+ $m = unpack('C*', $m[0]);
+ $i = 1;
+ $entities = '';
+
+ while (isset($m[$i])) {
+ if (0xF0 <= $m[$i]) {
+ $c = (($m[$i++] - 0xF0) << 18) + (($m[$i++] - 0x80) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
+ } elseif (0xE0 <= $m[$i]) {
+ $c = (($m[$i++] - 0xE0) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
+ } else {
+ $c = (($m[$i++] - 0xC0) << 6) + $m[$i++] - 0x80;
+ }
+
+ $entities .= ''.$c.';';
+ }
+
+ return $entities;
+ },
+ iconv($charset, 'UTF-8', $content)
+ );
}
+ } catch (\Exception $e) {
}
+ restore_error_handler();
+
if ('' !== trim($content)) {
@$dom->loadHTML($content);
}
diff --git a/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php b/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php
index 3c281eb479..9560d06999 100755
--- a/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php
+++ b/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php
@@ -81,6 +81,7 @@ class CrawlerTest extends \PHPUnit_Framework_TestCase
/**
* @covers Symfony\Component\DomCrawler\Crawler::addHtmlContent
+ * @requires extension mbstring
*/
public function testAddHtmlContentCharset()
{
@@ -115,6 +116,7 @@ class CrawlerTest extends \PHPUnit_Framework_TestCase
/**
* @covers Symfony\Component\DomCrawler\Crawler::addHtmlContent
+ * @requires extension mbstring
*/
public function testAddHtmlContentCharsetGbk()
{
@@ -235,7 +237,7 @@ EOF
$this->assertEquals('中文', $crawler->filterXPath('//span')->text(), '->addContent() guess wrong charset');
$crawler = new Crawler();
- $crawler->addContent(mb_convert_encoding('日本語', 'SJIS', 'UTF-8'));
+ $crawler->addContent(iconv('UTF-8', 'SJIS', '日本語'));
$this->assertEquals('日本語', $crawler->filterXPath('//body')->text(), '->addContent() can recognize "Shift_JIS" in html5 meta charset tag');
}
diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php
index 4a77f939ad..1bb7db350b 100644
--- a/src/Symfony/Component/Filesystem/Filesystem.php
+++ b/src/Symfony/Component/Filesystem/Filesystem.php
@@ -309,11 +309,10 @@ class Filesystem
$report = error_get_last();
if (is_array($report)) {
if ('\\' === DIRECTORY_SEPARATOR && false !== strpos($report['message'], 'error code(1314)')) {
- throw new IOException('Unable to create symlink due to error code 1314: \'A required privilege is not held by the client\'. Do you have the required Administrator-rights?');
+ throw new IOException('Unable to create symlink due to error code 1314: \'A required privilege is not held by the client\'. Do you have the required Administrator-rights?', 0, null, $targetDir);
}
- throw new IOException(sprintf('Failed to create symbolic link from "%s" to "%s".', $originDir, $targetDir), 0, null, $targetDir);
}
- throw new IOException(sprintf('Failed to create symbolic link from %s to %s', $originDir, $targetDir));
+ throw new IOException(sprintf('Failed to create symbolic link from "%s" to "%s".', $originDir, $targetDir), 0, null, $targetDir);
}
}
@@ -329,8 +328,8 @@ class Filesystem
{
// Normalize separators on Windows
if ('\\' === DIRECTORY_SEPARATOR) {
- $endPath = strtr($endPath, '\\', '/');
- $startPath = strtr($startPath, '\\', '/');
+ $endPath = str_replace('\\', '/', $endPath);
+ $startPath = str_replace('\\', '/', $startPath);
}
// Split the paths into arrays
diff --git a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php
index ae8885f3d6..b0f4152ecb 100644
--- a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php
+++ b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php
@@ -11,24 +11,11 @@
namespace Symfony\Component\Filesystem\Tests;
-use Symfony\Component\Filesystem\Filesystem;
-
/**
* Test class for Filesystem.
*/
class FilesystemTest extends FilesystemTestCase
{
- /**
- * @var \Symfony\Component\Filesystem\Filesystem
- */
- private $filesystem = null;
-
- protected function setUp()
- {
- parent::setUp();
- $this->filesystem = new Filesystem();
- }
-
public function testCopyCreatesNewFile()
{
$sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
@@ -681,7 +668,9 @@ class FilesystemTest extends FilesystemTestCase
public function testSymlink()
{
- $this->markAsSkippedIfSymlinkIsMissing();
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->markAsSkipped('Windows does not support creating "broken" symlinks');
+ }
$file = $this->workspace.DIRECTORY_SEPARATOR.'file';
$link = $this->workspace.DIRECTORY_SEPARATOR.'link';
@@ -1011,6 +1000,8 @@ class FilesystemTest extends FilesystemTestCase
public function testCopyShouldKeepExecutionPermission()
{
+ $this->markAsSkippedIfChmodIsMissing();
+
$sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
$targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';
diff --git a/src/Symfony/Component/Filesystem/Tests/FilesystemTestCase.php b/src/Symfony/Component/Filesystem/Tests/FilesystemTestCase.php
index 74802fc314..0ef9c8dddd 100644
--- a/src/Symfony/Component/Filesystem/Tests/FilesystemTestCase.php
+++ b/src/Symfony/Component/Filesystem/Tests/FilesystemTestCase.php
@@ -11,29 +11,33 @@
namespace Symfony\Component\Filesystem\Tests;
+use Symfony\Component\Filesystem\Filesystem;
+
class FilesystemTestCase extends \PHPUnit_Framework_TestCase
{
private $umask;
+ /**
+ * @var \Symfony\Component\Filesystem\Filesystem
+ */
+ protected $filesystem = null;
+
/**
* @var string
*/
protected $workspace = null;
- protected static $symlinkOnWindows = null;
+ private static $symlinkOnWindows = null;
public static function setUpBeforeClass()
{
- if ('\\' === DIRECTORY_SEPARATOR) {
- static::$symlinkOnWindows = true;
- $originDir = tempnam(sys_get_temp_dir(), 'sl');
- $targetDir = tempnam(sys_get_temp_dir(), 'sl');
- if (true !== @symlink($originDir, $targetDir)) {
- $report = error_get_last();
- if (is_array($report) && false !== strpos($report['message'], 'error code(1314)')) {
- static::$symlinkOnWindows = false;
- }
+ if ('\\' === DIRECTORY_SEPARATOR && null === self::$symlinkOnWindows) {
+ $target = tempnam(sys_get_temp_dir(), 'sl');
+ $link = sys_get_temp_dir().'/sl'.microtime(true).mt_rand();
+ if (self::$symlinkOnWindows = @symlink($target, $link)) {
+ unlink($link);
}
+ unlink($target);
}
}
@@ -43,31 +47,15 @@ class FilesystemTestCase extends \PHPUnit_Framework_TestCase
$this->workspace = rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.time().mt_rand(0, 1000);
mkdir($this->workspace, 0777, true);
$this->workspace = realpath($this->workspace);
+ $this->filesystem = new Filesystem();
}
protected function tearDown()
{
- $this->clean($this->workspace);
+ $this->filesystem->remove($this->workspace);
umask($this->umask);
}
- /**
- * @param string $file
- */
- protected function clean($file)
- {
- if (is_dir($file) && !is_link($file)) {
- $dir = new \FilesystemIterator($file);
- foreach ($dir as $childFile) {
- $this->clean($childFile);
- }
-
- rmdir($file);
- } else {
- unlink($file);
- }
- }
-
/**
* @param int $expectedFilePerms expected file permissions as three digits (i.e. 755)
* @param string $filePath
@@ -110,7 +98,7 @@ class FilesystemTestCase extends \PHPUnit_Framework_TestCase
$this->markTestSkipped('symlink is not supported');
}
- if ('\\' === DIRECTORY_SEPARATOR && false === static::$symlinkOnWindows) {
+ if ('\\' === DIRECTORY_SEPARATOR && false === self::$symlinkOnWindows) {
$this->markTestSkipped('symlink requires "Create symbolic links" privilege on windows');
}
}
diff --git a/src/Symfony/Component/Filesystem/Tests/LockHandlerTest.php b/src/Symfony/Component/Filesystem/Tests/LockHandlerTest.php
index c2058ffc58..f229ffd83e 100644
--- a/src/Symfony/Component/Filesystem/Tests/LockHandlerTest.php
+++ b/src/Symfony/Component/Filesystem/Tests/LockHandlerTest.php
@@ -12,6 +12,9 @@ class LockHandlerTest extends \PHPUnit_Framework_TestCase
*/
public function testConstructWhenRepositoryDoesNotExist()
{
+ if (!getenv('USER') || 'root' === getenv('USER')) {
+ $this->markTestSkipped('This test will fail if run under superuser');
+ }
new LockHandler('lock', '/a/b/c/d/e');
}
@@ -21,6 +24,9 @@ class LockHandlerTest extends \PHPUnit_Framework_TestCase
*/
public function testConstructWhenRepositoryIsNotWriteable()
{
+ if (!getenv('USER') || 'root' === getenv('USER')) {
+ $this->markTestSkipped('This test will fail if run under superuser');
+ }
new LockHandler('lock', '/');
}
diff --git a/src/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php b/src/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php
index 1ddde851b9..f15d953e4d 100644
--- a/src/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php
+++ b/src/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php
@@ -43,7 +43,7 @@ class ExcludeDirectoryFilterIterator extends FilterIterator
public function accept()
{
$path = $this->isDir() ? $this->current()->getRelativePathname() : $this->current()->getRelativePath();
- $path = strtr($path, '\\', '/');
+ $path = str_replace('\\', '/', $path);
foreach ($this->patterns as $pattern) {
if (preg_match($pattern, $path)) {
return false;
diff --git a/src/Symfony/Component/Finder/Iterator/PathFilterIterator.php b/src/Symfony/Component/Finder/Iterator/PathFilterIterator.php
index 2bb8ebd223..4971692c69 100644
--- a/src/Symfony/Component/Finder/Iterator/PathFilterIterator.php
+++ b/src/Symfony/Component/Finder/Iterator/PathFilterIterator.php
@@ -29,7 +29,7 @@ class PathFilterIterator extends MultiplePcreFilterIterator
$filename = $this->current()->getRelativePathname();
if ('\\' === DIRECTORY_SEPARATOR) {
- $filename = strtr($filename, '\\', '/');
+ $filename = str_replace('\\', '/', $filename);
}
// should at least not match one rule to exclude
diff --git a/src/Symfony/Component/Finder/Tests/Iterator/RecursiveDirectoryIteratorTest.php b/src/Symfony/Component/Finder/Tests/Iterator/RecursiveDirectoryIteratorTest.php
index 412054b379..436d8af560 100644
--- a/src/Symfony/Component/Finder/Tests/Iterator/RecursiveDirectoryIteratorTest.php
+++ b/src/Symfony/Component/Finder/Tests/Iterator/RecursiveDirectoryIteratorTest.php
@@ -60,9 +60,6 @@ class RecursiveDirectoryIteratorTest extends IteratorTestCase
$i->seek(1);
$actual[] = $i->getPathname();
- $i->seek(2);
- $actual[] = $i->getPathname();
-
$this->assertEquals($contains, $actual);
}
@@ -73,7 +70,6 @@ class RecursiveDirectoryIteratorTest extends IteratorTestCase
// ftp
$contains = array(
'ftp://ftp.mozilla.org'.DIRECTORY_SEPARATOR.'README',
- 'ftp://ftp.mozilla.org'.DIRECTORY_SEPARATOR.'index.html',
'ftp://ftp.mozilla.org'.DIRECTORY_SEPARATOR.'pub',
);
$data[] = array('ftp://ftp.mozilla.org/', false, $contains);
diff --git a/src/Symfony/Component/Finder/Tests/Iterator/SortableIteratorTest.php b/src/Symfony/Component/Finder/Tests/Iterator/SortableIteratorTest.php
index effaf76868..ed24f3ea0d 100644
--- a/src/Symfony/Component/Finder/Tests/Iterator/SortableIteratorTest.php
+++ b/src/Symfony/Component/Finder/Tests/Iterator/SortableIteratorTest.php
@@ -33,7 +33,11 @@ class SortableIteratorTest extends RealIteratorTestCase
if (!is_callable($mode)) {
switch ($mode) {
case SortableIterator::SORT_BY_ACCESSED_TIME :
- file_get_contents(self::toAbsolute('.git'));
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ touch(self::toAbsolute('.git'));
+ } else {
+ file_get_contents(self::toAbsolute('.git'));
+ }
sleep(1);
file_get_contents(self::toAbsolute('.bar'));
break;
@@ -56,7 +60,11 @@ class SortableIteratorTest extends RealIteratorTestCase
if ($mode === SortableIterator::SORT_BY_ACCESSED_TIME
|| $mode === SortableIterator::SORT_BY_CHANGED_TIME
- || $mode === SortableIterator::SORT_BY_MODIFIED_TIME) {
+ || $mode === SortableIterator::SORT_BY_MODIFIED_TIME
+ ) {
+ if ('\\' === DIRECTORY_SEPARATOR && SortableIterator::SORT_BY_MODIFIED_TIME !== $mode) {
+ $this->markTestSkipped('Sorting by atime or ctime is not supported on Windows');
+ }
$this->assertOrderedIteratorForGroups($expected, $iterator);
} else {
$this->assertOrderedIterator($expected, $iterator);
diff --git a/src/Symfony/Component/Finder/Tests/Shell/CommandTest.php b/src/Symfony/Component/Finder/Tests/Shell/CommandTest.php
index f967cdaa54..e9145127ea 100644
--- a/src/Symfony/Component/Finder/Tests/Shell/CommandTest.php
+++ b/src/Symfony/Component/Finder/Tests/Shell/CommandTest.php
@@ -86,7 +86,7 @@ class CommandTest extends \PHPUnit_Framework_TestCase
$cmd = Command::create()->add('--force');
$cmd->arg('--run');
- $this->assertSame('--force \'--run\'', $cmd->join());
+ $this->assertSame('--force '.escapeshellarg('--run'), $cmd->join());
}
public function testCmd()
diff --git a/src/Symfony/Component/Form/ChoiceList/ArrayChoiceList.php b/src/Symfony/Component/Form/ChoiceList/ArrayChoiceList.php
index 9996966f19..156735b817 100644
--- a/src/Symfony/Component/Form/ChoiceList/ArrayChoiceList.php
+++ b/src/Symfony/Component/Form/ChoiceList/ArrayChoiceList.php
@@ -155,7 +155,7 @@ class ArrayChoiceList implements ChoiceListInterface
$givenValues = array();
foreach ($choices as $i => $givenChoice) {
- $givenValues[$i] = call_user_func($this->valueCallback, $givenChoice);
+ $givenValues[$i] = (string) call_user_func($this->valueCallback, $givenChoice);
}
return array_intersect($givenValues, array_keys($this->choices));
diff --git a/src/Symfony/Component/Form/ChoiceList/Factory/CachingFactoryDecorator.php b/src/Symfony/Component/Form/ChoiceList/Factory/CachingFactoryDecorator.php
index 8796acfc4d..0692781f40 100644
--- a/src/Symfony/Component/Form/ChoiceList/Factory/CachingFactoryDecorator.php
+++ b/src/Symfony/Component/Form/ChoiceList/Factory/CachingFactoryDecorator.php
@@ -62,7 +62,7 @@ class CachingFactoryDecorator implements ChoiceListFactoryInterface
});
}
- return hash('sha256', $namespace.':'.json_encode($value));
+ return hash('sha256', $namespace.':'.serialize($value));
}
/**
diff --git a/src/Symfony/Component/Form/ChoiceList/Factory/PropertyAccessDecorator.php b/src/Symfony/Component/Form/ChoiceList/Factory/PropertyAccessDecorator.php
index ef41d497be..87a364a5f4 100644
--- a/src/Symfony/Component/Form/ChoiceList/Factory/PropertyAccessDecorator.php
+++ b/src/Symfony/Component/Form/ChoiceList/Factory/PropertyAccessDecorator.php
@@ -141,7 +141,13 @@ class PropertyAccessDecorator implements ChoiceListFactoryInterface
if ($value instanceof PropertyPath) {
$accessor = $this->propertyAccessor;
$value = function ($choice) use ($accessor, $value) {
- return $accessor->getValue($choice, $value);
+ // The callable may be invoked with a non-object/array value
+ // when such values are passed to
+ // ChoiceListInterface::getValuesForChoices(). Handle this case
+ // so that the call to getValue() doesn't break.
+ if (is_object($choice) || is_array($choice)) {
+ return $accessor->getValue($choice, $value);
+ }
};
}
diff --git a/src/Symfony/Component/Form/Extension/Core/Type/DateType.php b/src/Symfony/Component/Form/Extension/Core/Type/DateType.php
index 59500c8915..2a620a1220 100644
--- a/src/Symfony/Component/Form/Extension/Core/Type/DateType.php
+++ b/src/Symfony/Component/Form/Extension/Core/Type/DateType.php
@@ -275,7 +275,7 @@ class DateType extends AbstractType
$pattern = $formatter->getPattern();
$timezone = $formatter->getTimezoneId();
- if ($setTimeZone = method_exists($formatter, 'setTimeZone')) {
+ if ($setTimeZone = PHP_VERSION_ID >= 50500 || method_exists($formatter, 'setTimeZone')) {
$formatter->setTimeZone('UTC');
} else {
$formatter->setTimeZoneId('UTC');
diff --git a/src/Symfony/Component/Form/Tests/ChoiceList/Factory/PropertyAccessDecoratorTest.php b/src/Symfony/Component/Form/Tests/ChoiceList/Factory/PropertyAccessDecoratorTest.php
index 8697a9cac5..311db477b1 100644
--- a/src/Symfony/Component/Form/Tests/ChoiceList/Factory/PropertyAccessDecoratorTest.php
+++ b/src/Symfony/Component/Form/Tests/ChoiceList/Factory/PropertyAccessDecoratorTest.php
@@ -93,6 +93,36 @@ class PropertyAccessDecoratorTest extends \PHPUnit_Framework_TestCase
$this->assertSame('value', $this->factory->createListFromLoader($loader, 'property'));
}
+ // https://github.com/symfony/symfony/issues/5494
+ public function testCreateFromChoicesAssumeNullIfValuePropertyPathUnreadable()
+ {
+ $choices = array(null);
+
+ $this->decoratedFactory->expects($this->once())
+ ->method('createListFromChoices')
+ ->with($choices, $this->isInstanceOf('\Closure'))
+ ->will($this->returnCallback(function ($choices, $callback) {
+ return array_map($callback, $choices);
+ }));
+
+ $this->assertSame(array(null), $this->factory->createListFromChoices($choices, 'property'));
+ }
+
+ // https://github.com/symfony/symfony/issues/5494
+ public function testCreateFromChoiceLoaderAssumeNullIfValuePropertyPathUnreadable()
+ {
+ $loader = $this->getMock('Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface');
+
+ $this->decoratedFactory->expects($this->once())
+ ->method('createListFromLoader')
+ ->with($loader, $this->isInstanceOf('\Closure'))
+ ->will($this->returnCallback(function ($loader, $callback) {
+ return $callback(null);
+ }));
+
+ $this->assertNull($this->factory->createListFromLoader($loader, 'property'));
+ }
+
public function testCreateFromLoaderPropertyPathInstance()
{
$loader = $this->getMock('Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface');
diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/NumberToLocalizedStringTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/NumberToLocalizedStringTransformerTest.php
index 21a74ab486..8f23af510a 100644
--- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/NumberToLocalizedStringTransformerTest.php
+++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/NumberToLocalizedStringTransformerTest.php
@@ -92,11 +92,6 @@ class NumberToLocalizedStringTransformerTest extends \PHPUnit_Framework_TestCase
public function transformWithRoundingProvider()
{
- // Since we test against "de_AT", we need the full implementation
- IntlTestHelper::requireFullIntl($this);
-
- \Locale::setDefault('de_AT');
-
return array(
// towards positive infinity (1.6 -> 2, -1.6 -> -1)
array(0, 1234.5, '1235', NumberToLocalizedStringTransformer::ROUND_CEILING),
@@ -189,6 +184,11 @@ class NumberToLocalizedStringTransformerTest extends \PHPUnit_Framework_TestCase
*/
public function testTransformWithRounding($scale, $input, $output, $roundingMode)
{
+ // Since we test against "de_AT", we need the full implementation
+ IntlTestHelper::requireFullIntl($this);
+
+ \Locale::setDefault('de_AT');
+
$transformer = new NumberToLocalizedStringTransformer($scale, null, $roundingMode);
$this->assertEquals($output, $transformer->transform($input));
diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php
index 67241a1be9..cf15b0a3b7 100644
--- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php
+++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php
@@ -1337,6 +1337,42 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase
$this->assertNull($form[4]->getViewData());
}
+ public function testSingleSelectedObjectChoices()
+ {
+ $form = $this->factory->create('choice', $this->objectChoices[3], array(
+ 'multiple' => false,
+ 'expanded' => false,
+ 'choices' => $this->objectChoices,
+ 'choices_as_values' => true,
+ 'choice_label' => 'name',
+ 'choice_value' => 'id',
+ ));
+
+ $view = $form->createView();
+ $selectedChecker = $view->vars['is_selected'];
+
+ $this->assertTrue($selectedChecker($view->vars['choices'][3]->value, $view->vars['value']));
+ $this->assertFalse($selectedChecker($view->vars['choices'][1]->value, $view->vars['value']));
+ }
+
+ public function testMultipleSelectedObjectChoices()
+ {
+ $form = $this->factory->create('choice', array($this->objectChoices[3]), array(
+ 'multiple' => true,
+ 'expanded' => false,
+ 'choices' => $this->objectChoices,
+ 'choices_as_values' => true,
+ 'choice_label' => 'name',
+ 'choice_value' => 'id',
+ ));
+
+ $view = $form->createView();
+ $selectedChecker = $view->vars['is_selected'];
+
+ $this->assertTrue($selectedChecker($view->vars['choices'][3]->value, $view->vars['value']));
+ $this->assertFalse($selectedChecker($view->vars['choices'][1]->value, $view->vars['value']));
+ }
+
/*
* We need this functionality to create choice fields for Boolean types,
* e.g. false => 'No', true => 'Yes'
diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php
index 36ae61ba41..510a97175e 100644
--- a/src/Symfony/Component/HttpFoundation/Request.php
+++ b/src/Symfony/Component/HttpFoundation/Request.php
@@ -1852,9 +1852,9 @@ class Request
return $prefix;
}
- if ($baseUrl && false !== $prefix = $this->getUrlencodedPrefix($requestUri, rtrim(dirname($baseUrl), '/').'/')) {
+ if ($baseUrl && false !== $prefix = $this->getUrlencodedPrefix($requestUri, rtrim(dirname($baseUrl), '/'.DIRECTORY_SEPARATOR).'/')) {
// directory portion of $baseUrl matches
- return rtrim($prefix, '/');
+ return rtrim($prefix, '/'.DIRECTORY_SEPARATOR);
}
$truncatedRequestUri = $requestUri;
@@ -1875,7 +1875,7 @@ class Request
$baseUrl = substr($requestUri, 0, $pos + strlen($baseUrl));
}
- return rtrim($baseUrl, '/');
+ return rtrim($baseUrl, '/'.DIRECTORY_SEPARATOR);
}
/**
diff --git a/src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php b/src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php
index 47e4d4fed8..550014dc73 100644
--- a/src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php
+++ b/src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php
@@ -54,7 +54,7 @@ class BinaryFileResponseTest extends ResponseTestCase
*/
public function testRequests($requestRange, $offset, $length, $responseRange)
{
- $response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif')->setAutoEtag();
+ $response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif', 200, array('Content-Type' => 'application/octet-stream'))->setAutoEtag();
// do a request to get the ETag
$request = Request::create('/');
@@ -96,7 +96,7 @@ class BinaryFileResponseTest extends ResponseTestCase
*/
public function testFullFileRequests($requestRange)
{
- $response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif')->setAutoEtag();
+ $response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif', 200, array('Content-Type' => 'application/octet-stream'))->setAutoEtag();
// prepare a request for a range of the testing file
$request = Request::create('/');
@@ -131,7 +131,7 @@ class BinaryFileResponseTest extends ResponseTestCase
*/
public function testInvalidRequests($requestRange)
{
- $response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif')->setAutoEtag();
+ $response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif', 200, array('Content-Type' => 'application/octet-stream'))->setAutoEtag();
// prepare a request for a range of the testing file
$request = Request::create('/');
@@ -159,7 +159,7 @@ class BinaryFileResponseTest extends ResponseTestCase
$request->headers->set('X-Sendfile-Type', 'X-Sendfile');
BinaryFileResponse::trustXSendfileTypeHeader();
- $response = BinaryFileResponse::create(__DIR__.'/../README.md');
+ $response = BinaryFileResponse::create(__DIR__.'/../README.md', 200, array('Content-Type' => 'application/octet-stream'));
$response->prepare($request);
$this->expectOutputString('');
@@ -180,7 +180,7 @@ class BinaryFileResponseTest extends ResponseTestCase
$file = new FakeFile($realpath, __DIR__.'/File/Fixtures/test');
BinaryFileResponse::trustXSendfileTypeHeader();
- $response = new BinaryFileResponse($file);
+ $response = new BinaryFileResponse($file, 200, array('Content-Type' => 'application/octet-stream'));
$reflection = new \ReflectionObject($response);
$property = $reflection->getProperty('file');
$property->setAccessible(true);
@@ -199,7 +199,7 @@ class BinaryFileResponseTest extends ResponseTestCase
$realPath = realpath($path);
$this->assertFileExists($realPath);
- $response = new BinaryFileResponse($realPath);
+ $response = new BinaryFileResponse($realPath, 200, array('Content-Type' => 'application/octet-stream'));
$response->deleteFileAfterSend(true);
$response->prepare($request);
@@ -211,7 +211,7 @@ class BinaryFileResponseTest extends ResponseTestCase
public function testAcceptRangeOnUnsafeMethods()
{
$request = Request::create('/', 'POST');
- $response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif');
+ $response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif', 200, array('Content-Type' => 'application/octet-stream'));
$response->prepare($request);
$this->assertEquals('none', $response->headers->get('Accept-Ranges'));
@@ -220,7 +220,7 @@ class BinaryFileResponseTest extends ResponseTestCase
public function testAcceptRangeNotOverriden()
{
$request = Request::create('/', 'POST');
- $response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif');
+ $response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif', 200, array('Content-Type' => 'application/octet-stream'));
$response->headers->set('Accept-Ranges', 'foo');
$response->prepare($request);
@@ -237,7 +237,7 @@ class BinaryFileResponseTest extends ResponseTestCase
protected function provideResponse()
{
- return new BinaryFileResponse(__DIR__.'/../README.md');
+ return new BinaryFileResponse(__DIR__.'/../README.md', 200, array('Content-Type' => 'application/octet-stream'));
}
public static function tearDownAfterClass()
diff --git a/src/Symfony/Component/HttpFoundation/Tests/File/FileTest.php b/src/Symfony/Component/HttpFoundation/Tests/File/FileTest.php
index 6777849c8a..d216eab516 100644
--- a/src/Symfony/Component/HttpFoundation/Tests/File/FileTest.php
+++ b/src/Symfony/Component/HttpFoundation/Tests/File/FileTest.php
@@ -45,6 +45,9 @@ class FileTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('gif', $file->guessExtension());
}
+ /**
+ * @requires extension fileinfo
+ */
public function testGuessExtensionWithReset()
{
$file = new File(__DIR__.'/Fixtures/other-file.example');
diff --git a/src/Symfony/Component/HttpFoundation/Tests/File/MimeType/MimeTypeTest.php b/src/Symfony/Component/HttpFoundation/Tests/File/MimeType/MimeTypeTest.php
index b2a573e27a..1d5648eada 100644
--- a/src/Symfony/Component/HttpFoundation/Tests/File/MimeType/MimeTypeTest.php
+++ b/src/Symfony/Component/HttpFoundation/Tests/File/MimeType/MimeTypeTest.php
@@ -14,17 +14,16 @@ namespace Symfony\Component\HttpFoundation\Tests\File\MimeType;
use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser;
use Symfony\Component\HttpFoundation\File\MimeType\FileBinaryMimeTypeGuesser;
+/**
+ * @requires extension fileinfo
+ */
class MimeTypeTest extends \PHPUnit_Framework_TestCase
{
protected $path;
public function testGuessImageWithoutExtension()
{
- if (extension_loaded('fileinfo')) {
- $this->assertEquals('image/gif', MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/test'));
- } else {
- $this->assertNull(MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/test'));
- }
+ $this->assertEquals('image/gif', MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/test'));
}
public function testGuessImageWithDirectory()
@@ -38,29 +37,17 @@ class MimeTypeTest extends \PHPUnit_Framework_TestCase
{
$guesser = MimeTypeGuesser::getInstance();
$guesser->register(new FileBinaryMimeTypeGuesser());
- if (extension_loaded('fileinfo')) {
- $this->assertEquals('image/gif', MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/test'));
- } else {
- $this->assertNull(MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/test'));
- }
+ $this->assertEquals('image/gif', MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/test'));
}
public function testGuessImageWithKnownExtension()
{
- if (extension_loaded('fileinfo')) {
- $this->assertEquals('image/gif', MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/test.gif'));
- } else {
- $this->assertNull(MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/test.gif'));
- }
+ $this->assertEquals('image/gif', MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/test.gif'));
}
public function testGuessFileWithUnknownExtension()
{
- if (extension_loaded('fileinfo')) {
- $this->assertEquals('application/octet-stream', MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/.unknownextension'));
- } else {
- $this->assertNull(MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/.unknownextension'));
- }
+ $this->assertEquals('application/octet-stream', MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/.unknownextension'));
}
public function testGuessWithIncorrectPath()
@@ -75,7 +62,7 @@ class MimeTypeTest extends \PHPUnit_Framework_TestCase
$this->markTestSkipped('Can not verify chmod operations on Windows');
}
- if ('root' === get_current_user()) {
+ if (!getenv('USER') || 'root' === getenv('USER')) {
$this->markTestSkipped('This test will fail if run under superuser');
}
@@ -83,7 +70,7 @@ class MimeTypeTest extends \PHPUnit_Framework_TestCase
touch($path);
@chmod($path, 0333);
- if (get_current_user() != 'root' && substr(sprintf('%o', fileperms($path)), -4) == '0333') {
+ if (substr(sprintf('%o', fileperms($path)), -4) == '0333') {
$this->setExpectedException('Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException');
MimeTypeGuesser::getInstance()->guess($path);
} else {
diff --git a/src/Symfony/Component/Intl/DateFormatter/IntlDateFormatter.php b/src/Symfony/Component/Intl/DateFormatter/IntlDateFormatter.php
index 1b5b90091c..af398afc91 100644
--- a/src/Symfony/Component/Intl/DateFormatter/IntlDateFormatter.php
+++ b/src/Symfony/Component/Intl/DateFormatter/IntlDateFormatter.php
@@ -209,7 +209,7 @@ class IntlDateFormatter
$argumentError = null;
if (!is_int($timestamp) && !$timestamp instanceof \DateTime) {
$argumentError = 'datefmt_format: takes either an array or an integer timestamp value or a DateTime object';
- if (PHP_VERSION_ID >= 50500 && !is_int($timestamp)) {
+ if (PHP_VERSION_ID >= 50500 || (extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'))) {
$argumentError = sprintf('datefmt_format: string \'%s\' is not numeric, which would be required for it to be a valid date', $timestamp);
}
}
@@ -371,7 +371,7 @@ class IntlDateFormatter
}
// In PHP 5.5 default timezone depends on `date_default_timezone_get()` method
- if (PHP_VERSION_ID >= 50500) {
+ if (PHP_VERSION_ID >= 50500 || (extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'))) {
return date_default_timezone_get();
}
}
@@ -536,7 +536,7 @@ class IntlDateFormatter
{
if (null === $timeZoneId) {
// In PHP 5.5 if $timeZoneId is null it fallbacks to `date_default_timezone_get()` method
- if (PHP_VERSION_ID >= 50500) {
+ if (PHP_VERSION_ID >= 50500 || (extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'))) {
$timeZoneId = date_default_timezone_get();
} else {
// TODO: changes were made to ext/intl in PHP 5.4.4 release that need to be investigated since it will
@@ -563,8 +563,16 @@ class IntlDateFormatter
try {
$this->dateTimeZone = new \DateTimeZone($timeZoneId);
+ if ('GMT' !== $timeZoneId && $this->dateTimeZone->getName() !== $timeZoneId) {
+ $timeZoneId = $timeZone = $this->getTimeZoneId();
+ }
} catch (\Exception $e) {
- $this->dateTimeZone = new \DateTimeZone('UTC');
+ if (PHP_VERSION_ID >= 50500 || (extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'))) {
+ $timeZoneId = $timeZone = $this->getTimeZoneId();
+ } else {
+ $timeZoneId = 'UTC';
+ }
+ $this->dateTimeZone = new \DateTimeZone($timeZoneId);
}
$this->timeZoneId = $timeZone;
@@ -630,7 +638,7 @@ class IntlDateFormatter
if (self::NONE !== $this->timetype) {
$patternParts[] = $this->defaultTimeFormats[$this->timetype];
}
- $pattern = implode(' ', $patternParts);
+ $pattern = implode(', ', $patternParts);
return $pattern;
}
diff --git a/src/Symfony/Component/Intl/NumberFormatter/NumberFormatter.php b/src/Symfony/Component/Intl/NumberFormatter/NumberFormatter.php
index fe8a307428..eaed44781c 100644
--- a/src/Symfony/Component/Intl/NumberFormatter/NumberFormatter.php
+++ b/src/Symfony/Component/Intl/NumberFormatter/NumberFormatter.php
@@ -538,22 +538,30 @@ class NumberFormatter
return false;
}
- preg_match('/^([^0-9\-\.]{0,})(.*)/', $value, $matches);
+ $groupSep = $this->getAttribute(self::GROUPING_USED) ? ',' : '';
// Any string before the numeric value causes error in the parsing
- if (isset($matches[1]) && !empty($matches[1])) {
+ if (preg_match("/^-?(?:\.\d++|([\d{$groupSep}]++)(?:\.\d++)?)/", $value, $matches)) {
+ $value = $matches[0];
+ $position = strlen($value);
+ if ($error = $groupSep && isset($matches[1]) && !preg_match('/^\d{1,3}+(?:(?:,\d{3})++|\d*+)$/', $matches[1])) {
+ $position -= strlen(preg_replace('/^\d{1,3}+(?:(?:,\d++)++|\d*+)/', '', $matches[1]));
+ }
+ } else {
+ $error = 1;
+ $position = 0;
+ }
+
+ if ($error) {
IntlGlobals::setError(IntlGlobals::U_PARSE_ERROR, 'Number parsing failed');
$this->errorCode = IntlGlobals::getErrorCode();
$this->errorMessage = IntlGlobals::getErrorMessage();
- $position = 0;
return false;
}
- preg_match('/^[0-9\-\.\,]*/', $value, $matches);
- $value = preg_replace('/[^0-9\.\-]/', '', $matches[0]);
+ $value = str_replace(',', '', $value);
$value = $this->convertValueDataType($value, $type);
- $position = strlen($matches[0]);
// behave like the intl extension
$this->resetError();
diff --git a/src/Symfony/Component/Intl/Tests/DateFormatter/AbstractIntlDateFormatterTest.php b/src/Symfony/Component/Intl/Tests/DateFormatter/AbstractIntlDateFormatterTest.php
index 6cae5aedd0..a3000957be 100644
--- a/src/Symfony/Component/Intl/Tests/DateFormatter/AbstractIntlDateFormatterTest.php
+++ b/src/Symfony/Component/Intl/Tests/DateFormatter/AbstractIntlDateFormatterTest.php
@@ -38,11 +38,16 @@ abstract class AbstractIntlDateFormatterTest extends \PHPUnit_Framework_TestCase
$formatter = $this->getDateFormatter('en', IntlDateFormatter::MEDIUM, IntlDateFormatter::SHORT);
// In PHP 5.5 default timezone depends on `date_default_timezone_get()` method
- if (PHP_VERSION_ID >= 50500) {
+ if (PHP_VERSION_ID >= 50500 || (extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'))) {
$this->assertEquals(date_default_timezone_get(), $formatter->getTimeZoneId());
} else {
$this->assertNull($formatter->getTimeZoneId());
}
+
+ $this->assertEquals(
+ $this->getDateTime(0, $formatter->getTimeZoneId())->format('M j, Y, g:i A'),
+ $formatter->format(0)
+ );
}
/**
@@ -267,7 +272,7 @@ abstract class AbstractIntlDateFormatterTest extends \PHPUnit_Framework_TestCase
public function formatErrorProvider()
{
// With PHP 5.5 IntlDateFormatter accepts empty values ('0')
- if (PHP_VERSION_ID >= 50500) {
+ if (PHP_VERSION_ID >= 50500 || (extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'))) {
return array(
array('y-M-d', 'foobar', 'datefmt_format: string \'foobar\' is not numeric, which would be required for it to be a valid date: U_ILLEGAL_ARGUMENT_ERROR'),
);
@@ -320,7 +325,7 @@ abstract class AbstractIntlDateFormatterTest extends \PHPUnit_Framework_TestCase
);
// As of PHP 5.5, intl ext no longer fallbacks invalid time zones to UTC
- if (PHP_VERSION_ID < 50500) {
+ if (PHP_VERSION_ID < 50500 && !(extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'))) {
// When time zone not exists, uses UTC by default
$data[] = array(0, 'Foo/Bar', '1970-01-01 00:00:00');
$data[] = array(0, 'UTC+04:30', '1970-01-01 00:00:00');
@@ -334,7 +339,7 @@ abstract class AbstractIntlDateFormatterTest extends \PHPUnit_Framework_TestCase
{
$formatter = $this->getDefaultDateFormatter('zzzz');
- if (PHP_VERSION_ID >= 50500) {
+ if (PHP_VERSION_ID >= 50500 || (extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'))) {
$formatter->setTimeZone('GMT+03:00');
} else {
$formatter->setTimeZoneId('GMT+03:00');
@@ -347,7 +352,7 @@ abstract class AbstractIntlDateFormatterTest extends \PHPUnit_Framework_TestCase
{
$formatter = $this->getDefaultDateFormatter('zzzz');
- if (PHP_VERSION_ID >= 50500) {
+ if (PHP_VERSION_ID >= 50500 || (extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'))) {
$formatter->setTimeZone('GMT+00:30');
} else {
$formatter->setTimeZoneId('GMT+00:30');
@@ -360,7 +365,7 @@ abstract class AbstractIntlDateFormatterTest extends \PHPUnit_Framework_TestCase
{
$formatter = $this->getDefaultDateFormatter('zzzz');
- if (PHP_VERSION_ID >= 50500) {
+ if (PHP_VERSION_ID >= 50500 || (extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'))) {
$formatter->setTimeZone('Pacific/Fiji');
} else {
$formatter->setTimeZoneId('Pacific/Fiji');
@@ -397,7 +402,7 @@ abstract class AbstractIntlDateFormatterTest extends \PHPUnit_Framework_TestCase
public function testFormatWithIntlTimeZone()
{
- if (PHP_VERSION_ID < 50500) {
+ if (PHP_VERSION_ID < 50500 && !(extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'))) {
$this->markTestSkipped('Only in PHP 5.5+ IntlDateFormatter allows to use DateTimeZone objects.');
}
@@ -412,7 +417,7 @@ abstract class AbstractIntlDateFormatterTest extends \PHPUnit_Framework_TestCase
public function testFormatWithTimezoneFromEnvironmentVariable()
{
- if (PHP_VERSION_ID >= 50500) {
+ if (PHP_VERSION_ID >= 50500 || (extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'))) {
$this->markTestSkipped('IntlDateFormatter in PHP 5.5 no longer depends on TZ environment.');
}
@@ -435,7 +440,7 @@ abstract class AbstractIntlDateFormatterTest extends \PHPUnit_Framework_TestCase
public function testFormatWithTimezoneFromPhp()
{
- if (PHP_VERSION_ID < 50500) {
+ if (PHP_VERSION_ID < 50500 && !(extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'))) {
$this->markTestSkipped('Only in PHP 5.5 IntlDateFormatter depends on default timezone (`date_default_timezone_get()`).');
}
@@ -866,7 +871,7 @@ abstract class AbstractIntlDateFormatterTest extends \PHPUnit_Framework_TestCase
{
$formatter = $this->getDefaultDateFormatter();
- if (PHP_VERSION_ID >= 50500) {
+ if (PHP_VERSION_ID >= 50500 || (extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'))) {
$formatter->setTimeZone($timeZoneId);
} else {
$formatter->setTimeZoneId($timeZoneId);
@@ -877,15 +882,17 @@ abstract class AbstractIntlDateFormatterTest extends \PHPUnit_Framework_TestCase
public function setTimeZoneIdProvider()
{
+ $isPhp55 = PHP_VERSION_ID >= 50500 || (extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'));
+
return array(
array('UTC', 'UTC'),
array('GMT', 'GMT'),
array('GMT-03:00', 'GMT-03:00'),
array('Europe/Zurich', 'Europe/Zurich'),
- array('GMT-0300', 'GMT-0300'),
- array('Foo/Bar', 'Foo/Bar'),
- array('GMT+00:AA', 'GMT+00:AA'),
- array('GMT+00AA', 'GMT+00AA'),
+ array(null, $isPhp55 ? date_default_timezone_get() : null),
+ array('Foo/Bar', $isPhp55 ? 'UTC' : 'Foo/Bar'),
+ array('GMT+00:AA', $isPhp55 ? 'UTC' : 'GMT+00:AA'),
+ array('GMT+00AA', $isPhp55 ? 'UTC' : 'GMT+00AA'),
);
}
@@ -898,7 +905,9 @@ abstract class AbstractIntlDateFormatterTest extends \PHPUnit_Framework_TestCase
{
$dateTime = new \DateTime();
$dateTime->setTimestamp(null === $timestamp ? time() : $timestamp);
- $dateTime->setTimezone(new \DateTimeZone($timeZone));
+ if (null !== $timeZone) {
+ $dateTime->setTimezone(new \DateTimeZone($timeZone));
+ }
return $dateTime;
}
diff --git a/src/Symfony/Component/Intl/Tests/DateFormatter/Verification/IntlDateFormatterTest.php b/src/Symfony/Component/Intl/Tests/DateFormatter/Verification/IntlDateFormatterTest.php
index bf4cdae26a..dcf38473f2 100644
--- a/src/Symfony/Component/Intl/Tests/DateFormatter/Verification/IntlDateFormatterTest.php
+++ b/src/Symfony/Component/Intl/Tests/DateFormatter/Verification/IntlDateFormatterTest.php
@@ -45,7 +45,11 @@ class IntlDateFormatterTest extends AbstractIntlDateFormatterTest
protected function getDateFormatter($locale, $datetype, $timetype, $timezone = null, $calendar = IntlDateFormatter::GREGORIAN, $pattern = null)
{
- return new \IntlDateFormatter($locale, $datetype, $timetype, $timezone, $calendar, $pattern);
+ if (!$formatter = new \IntlDateFormatter($locale, $datetype, $timetype, $timezone, $calendar, $pattern)) {
+ throw new \InvalidArgumentException(intl_get_error_message());
+ }
+
+ return $formatter;
}
protected function getIntlErrorMessage()
diff --git a/src/Symfony/Component/Intl/Tests/NumberFormatter/AbstractNumberFormatterTest.php b/src/Symfony/Component/Intl/Tests/NumberFormatter/AbstractNumberFormatterTest.php
index 9bde822486..c0eec6ebc1 100644
--- a/src/Symfony/Component/Intl/Tests/NumberFormatter/AbstractNumberFormatterTest.php
+++ b/src/Symfony/Component/Intl/Tests/NumberFormatter/AbstractNumberFormatterTest.php
@@ -602,10 +602,11 @@ abstract class AbstractNumberFormatterTest extends \PHPUnit_Framework_TestCase
/**
* @dataProvider parseProvider
*/
- public function testParse($value, $expected, $message, $expectedPosition)
+ public function testParse($value, $expected, $message, $expectedPosition, $groupingUsed = true)
{
$position = 0;
$formatter = $this->getNumberFormatter('en', NumberFormatter::DECIMAL);
+ $formatter->setAttribute(NumberFormatter::GROUPING_USED, $groupingUsed);
$parsedValue = $formatter->parse($value, NumberFormatter::TYPE_DOUBLE, $position);
$this->assertSame($expected, $parsedValue, $message);
$this->assertSame($expectedPosition, $position, $message);
@@ -631,6 +632,11 @@ abstract class AbstractNumberFormatterTest extends \PHPUnit_Framework_TestCase
return array(
array('prefix1', false, '->parse() does not parse a number with a string prefix.', 0),
array('1.4suffix', (float) 1.4, '->parse() parses a number with a string suffix.', 3),
+ array('-.4suffix', (float) -0.4, '->parse() parses a negative dot float with suffix.', 3),
+ array('-123,4', false, '->parse() does not parse when invalid grouping used.', 6),
+ array('-1234,567', false, '->parse() does not parse when invalid grouping used.', 5),
+ array('-123,,456', false, '->parse() does not parse when invalid grouping used.', 4),
+ array('-123,,456', -123.0, '->parse() parses when grouping is disabled.', 4, false),
);
}
diff --git a/src/Symfony/Component/Locale/Tests/LocaleTest.php b/src/Symfony/Component/Locale/Tests/LocaleTest.php
index 033d68903c..7419d28369 100644
--- a/src/Symfony/Component/Locale/Tests/LocaleTest.php
+++ b/src/Symfony/Component/Locale/Tests/LocaleTest.php
@@ -12,6 +12,7 @@
namespace Symfony\Component\Locale\Tests;
use Symfony\Component\Locale\Locale;
+use Symfony\Component\Intl\Util\IntlTestHelper;
/**
* Test case for the {@link Locale} class.
@@ -35,6 +36,8 @@ class LocaleTest extends \PHPUnit_Framework_TestCase
public function testGetDisplayCountriesForSwitzerland()
{
+ IntlTestHelper::requireFullIntl($this);
+
$countries = Locale::getDisplayCountries('de_CH');
$this->assertEquals('Schweiz', $countries['CH']);
}
diff --git a/src/Symfony/Component/Process/Tests/AbstractProcessTest.php b/src/Symfony/Component/Process/Tests/AbstractProcessTest.php
index eb3f65dc93..93b5779ad2 100644
--- a/src/Symfony/Component/Process/Tests/AbstractProcessTest.php
+++ b/src/Symfony/Component/Process/Tests/AbstractProcessTest.php
@@ -172,6 +172,9 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
*/
public function testSetStreamAsInput($code, $size)
{
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->markTestIncomplete('This test fails with a timeout on Windows, can someone investigate please?');
+ }
$expected = str_repeat(str_repeat('*', 1024), $size).'!';
$expectedLength = (1024 * $size) + 1;
@@ -179,7 +182,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
fwrite($stream, $expected);
rewind($stream);
- $p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg($code)));
+ $p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg($code)), null, null, null, 5);
$p->setInput($stream);
$p->run();
@@ -559,7 +562,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
$start = microtime(true);
$process->start();
$end = microtime(true);
- $this->assertLessThan(0.2, $end - $start);
+ $this->assertLessThan(0.4, $end - $start);
$process->wait();
}
@@ -637,8 +640,10 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
{
$process = $this->getProcess(self::$phpBin.' -r "sleep(1);"');
$process->start();
+
+ $this->assertFalse($process->isSuccessful());
+
while ($process->isRunning()) {
- $this->assertFalse($process->isSuccessful());
usleep(300000);
}
@@ -844,6 +849,9 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
public function testIdleTimeoutNotExceededWhenOutputIsSent()
{
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->markTestIncomplete('This test fails with a timeout on Windows, can someone investigate please?');
+ }
$process = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('$n = 30; while ($n--) {echo "foo\n"; usleep(100000); }')));
$process->setTimeout(2);
$process->setIdleTimeout(1);
diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php b/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php
index 1d12ab0dba..7538648b13 100644
--- a/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php
+++ b/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php
@@ -33,7 +33,7 @@ abstract class AbstractToken implements TokenInterface
/**
* Constructor.
*
- * @param RoleInterface[] $roles An array of roles
+ * @param RoleInterface[]|string[] $roles An array of roles
*
* @throws \InvalidArgumentException
*/
diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/PreAuthenticatedToken.php b/src/Symfony/Component/Security/Core/Authentication/Token/PreAuthenticatedToken.php
index abcd2bffa3..1798203690 100644
--- a/src/Symfony/Component/Security/Core/Authentication/Token/PreAuthenticatedToken.php
+++ b/src/Symfony/Component/Security/Core/Authentication/Token/PreAuthenticatedToken.php
@@ -11,6 +11,8 @@
namespace Symfony\Component\Security\Core\Authentication\Token;
+use Symfony\Component\Security\Core\Role\RoleInterface;
+
/**
* PreAuthenticatedToken implements a pre-authenticated token.
*
@@ -23,6 +25,11 @@ class PreAuthenticatedToken extends AbstractToken
/**
* Constructor.
+ *
+ * @param string|object $user The user
+ * @param mixed $credentials The user credentials
+ * @param string $providerKey The provider key
+ * @param RoleInterface[]|string[] $roles An array of roles
*/
public function __construct($user, $credentials, $providerKey, array $roles = array())
{
diff --git a/src/Symfony/Component/Translation/Loader/XliffFileLoader.php b/src/Symfony/Component/Translation/Loader/XliffFileLoader.php
index f2cbacb4f0..937fa097a7 100644
--- a/src/Symfony/Component/Translation/Loader/XliffFileLoader.php
+++ b/src/Symfony/Component/Translation/Loader/XliffFileLoader.php
@@ -48,14 +48,14 @@ class XliffFileLoader implements LoaderInterface
foreach ($xml->xpath('//xliff:trans-unit') as $translation) {
$attributes = $translation->attributes();
- if (!(isset($attributes['resname']) || isset($translation->source)) || !isset($translation->target)) {
+ if (!(isset($attributes['resname']) || isset($translation->source))) {
continue;
}
$source = isset($attributes['resname']) && $attributes['resname'] ? $attributes['resname'] : $translation->source;
// If the xlf file has another encoding specified, try to convert it because
// simple_xml will always return utf-8 encoded values
- $target = $this->utf8ToCharset((string) $translation->target, $encoding);
+ $target = $this->utf8ToCharset((string) (isset($translation->target) ? $translation->target : $source), $encoding);
$catalogue->set((string) $source, $target, $domain);
diff --git a/src/Symfony/Component/Translation/Tests/Loader/XliffFileLoaderTest.php b/src/Symfony/Component/Translation/Tests/Loader/XliffFileLoaderTest.php
index 18c3aaeb25..a67af1a340 100644
--- a/src/Symfony/Component/Translation/Tests/Loader/XliffFileLoaderTest.php
+++ b/src/Symfony/Component/Translation/Tests/Loader/XliffFileLoaderTest.php
@@ -25,6 +25,7 @@ class XliffFileLoaderTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('en', $catalogue->getLocale());
$this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
$this->assertSame(array(), libxml_get_errors());
+ $this->assertContainsOnly('string', $catalogue->all('domain1'));
}
public function testLoadWithInternalErrorsEnabled()
@@ -55,8 +56,7 @@ class XliffFileLoaderTest extends \PHPUnit_Framework_TestCase
$loader = new XliffFileLoader();
$catalogue = $loader->load(__DIR__.'/../fixtures/resources.xlf', 'en', 'domain1');
- $this->assertEquals(array('foo' => 'bar', 'key' => '', 'test' => 'with'), $catalogue->all('domain1'));
- $this->assertFalse($catalogue->has('extra', 'domain1'));
+ $this->assertEquals(array('foo' => 'bar', 'extra' => 'extra', 'key' => '', 'test' => 'with'), $catalogue->all('domain1'));
}
public function testEncoding()
@@ -145,7 +145,8 @@ class XliffFileLoaderTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(array('notes' => array(array('priority' => 1, 'content' => 'foo'))), $catalogue->getMetadata('foo', 'domain1'));
// message without target
- $this->assertNull($catalogue->getMetadata('extra', 'domain1'));
+ $this->assertEquals(array('notes' => array(array('content' => 'bar', 'from' => 'foo'))), $catalogue->getMetadata('extra', 'domain1'));
+ // message with empty target
$this->assertEquals(array('notes' => array(array('content' => 'baz'), array('priority' => 2, 'from' => 'bar', 'content' => 'qux'))), $catalogue->getMetadata('key', 'domain1'));
}
}
diff --git a/src/Symfony/Component/Validator/Constraints/LengthValidator.php b/src/Symfony/Component/Validator/Constraints/LengthValidator.php
index 9597f3869a..7ef9f269d0 100644
--- a/src/Symfony/Component/Validator/Constraints/LengthValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/LengthValidator.php
@@ -45,23 +45,25 @@ class LengthValidator extends ConstraintValidator
$charset = 'UTF-8';
}
- if (function_exists('iconv_strlen')) {
- $length = @iconv_strlen($stringValue, $constraint->charset);
- $invalidCharset = false === $length;
+ if ('UTF-8' === $charset) {
+ if (!preg_match('//u', $stringValue)) {
+ $invalidCharset = true;
+ } elseif (function_exists('utf8_decode')) {
+ $length = strlen(utf8_decode($stringValue));
+ } else {
+ preg_replace('/./u', '', $stringValue, -1, $length);
+ }
} elseif (function_exists('mb_strlen')) {
- if (mb_check_encoding($stringValue, $constraint->charset)) {
+ if (@mb_check_encoding($stringValue, $constraint->charset)) {
$length = mb_strlen($stringValue, $constraint->charset);
} else {
$invalidCharset = true;
}
- } elseif ('UTF-8' !== $charset) {
- $length = strlen($stringValue);
- } elseif (!preg_match('//u', $stringValue)) {
- $invalidCharset = true;
- } elseif (function_exists('utf8_decode')) {
- $length = strlen(utf8_decode($stringValue));
+ } elseif (function_exists('iconv_strlen')) {
+ $length = @iconv_strlen($stringValue, $constraint->charset);
+ $invalidCharset = false === $length;
} else {
- preg_replace('/./u', '', $stringValue, -1, $length);
+ $length = strlen($stringValue);
}
if ($invalidCharset) {
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/ImageValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/ImageValidatorTest.php
index 18f9c1bc06..4605a06577 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/ImageValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/ImageValidatorTest.php
@@ -15,6 +15,9 @@ use Symfony\Component\Validator\Constraints\Image;
use Symfony\Component\Validator\Constraints\ImageValidator;
use Symfony\Component\Validator\Validation;
+/**
+ * @requires extension fileinfo
+ */
class ImageValidatorTest extends AbstractConstraintValidatorTest
{
protected $context;
diff --git a/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php b/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php
index 399465938c..48d5cffa40 100644
--- a/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php
+++ b/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php
@@ -129,7 +129,7 @@ var refStyle = doc.createElement('style'),
e.addEventListener(n, cb, false);
};
-doc.documentElement.firstChild.appendChild(refStyle);
+(doc.documentElement.firstElementChild || doc.documentElement.children[0]).appendChild(refStyle);
if (!doc.addEventListener) {
addEventListener = function (element, eventName, callback) {