diff --git a/.travis.yml b/.travis.yml index 58a1367748..25329620c0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,6 +13,7 @@ addons: env: global: - MIN_PHP=5.3.9 + - SYMFONY_PROCESS_PHP_TEST_BINARY=~/.phpenv/versions/5.6/bin/php matrix: include: diff --git a/phpunit b/phpunit index 9cf03f071e..9806b0053f 100755 --- a/phpunit +++ b/phpunit @@ -11,7 +11,7 @@ */ // Please update when phpunit needs to be reinstalled with fresh deps: -// Cache-Id-Version: 2015-11-28 09:05 UTC +// Cache-Id-Version: 2016-03-16 15:36 UTC use Symfony\Component\Process\ProcessUtils; @@ -52,7 +52,7 @@ if (!file_exists("$PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/phpunit") || md5_file(__ $zip->close(); chdir("phpunit-$PHPUNIT_VERSION"); passthru("$COMPOSER remove --no-update symfony/yaml"); - passthru("$COMPOSER require --dev --no-update symfony/phpunit-bridge \">=2.8@dev\""); + passthru("$COMPOSER require --dev --no-update symfony/phpunit-bridge \">=3.1@dev\""); passthru("$COMPOSER install --prefer-dist --no-progress --ansi"); file_put_contents('phpunit', << - Symfony\Component\HttpFoundation + Symfony\Component\HttpFoundation diff --git a/src/Symfony/Bundle/FrameworkBundle/Client.php b/src/Symfony/Bundle/FrameworkBundle/Client.php index d9b064e5ec..04fbd3ab0f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Client.php +++ b/src/Symfony/Bundle/FrameworkBundle/Client.php @@ -42,7 +42,7 @@ class Client extends BaseClient /** * Returns the container. * - * @return ContainerInterface + * @return ContainerInterface|null Returns null when the Kernel has been shutdown or not started yet */ public function getContainer() { diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SecurityFactoryInterface.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SecurityFactoryInterface.php index fce2f07580..2b3310c61a 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SecurityFactoryInterface.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SecurityFactoryInterface.php @@ -21,6 +21,20 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; */ interface SecurityFactoryInterface { + /** + * Configures the container services required to use the authentication listener. + * + * @param ContainerBuilder $container + * @param string $id The unique id of the firewall + * @param array $config The options array for the listener + * @param string $userProvider The service id of the user provider + * @param string $defaultEntryPoint + * + * @return array containing three values: + * - the provider id + * - the listener id + * - the entry point id + */ public function create(ContainerBuilder $container, $id, $config, $userProvider, $defaultEntryPoint); /** @@ -31,6 +45,12 @@ interface SecurityFactoryInterface */ public function getPosition(); + /** + * Defines the configuration key used to reference the provider + * in the firewall configuration. + * + * @return string + */ public function getKey(); public function addConfiguration(NodeDefinition $builder); diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php index cbfa98c2e5..d8a072f1cc 100644 --- a/src/Symfony/Component/Filesystem/Filesystem.php +++ b/src/Symfony/Component/Filesystem/Filesystem.php @@ -24,18 +24,18 @@ class Filesystem /** * Copies a file. * - * This method only copies the file if the origin file is newer than the target file. + * If the target file is older than the origin file, it's always overwritten. + * If the target file is newer, it is overwritten only when the + * $overwriteNewerFiles option is set to true. * - * By default, if the target already exists, it is not overridden. - * - * @param string $originFile The original filename - * @param string $targetFile The target filename - * @param bool $override Whether to override an existing file or not + * @param string $originFile The original filename + * @param string $targetFile The target filename + * @param bool $overwriteNewerFiles If true, target files newer than origin files are overwritten * * @throws FileNotFoundException When originFile doesn't exist * @throws IOException When copy fails */ - public function copy($originFile, $targetFile, $override = false) + public function copy($originFile, $targetFile, $overwriteNewerFiles = false) { if (stream_is_local($originFile) && !is_file($originFile)) { throw new FileNotFoundException(sprintf('Failed to copy "%s" because file does not exist.', $originFile), 0, null, $originFile); @@ -44,7 +44,7 @@ class Filesystem $this->mkdir(dirname($targetFile)); $doCopy = true; - if (!$override && null === parse_url($originFile, PHP_URL_HOST) && is_file($targetFile)) { + if (!$overwriteNewerFiles && null === parse_url($originFile, PHP_URL_HOST) && is_file($targetFile)) { $doCopy = filemtime($originFile) > filemtime($targetFile); } diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php index 2c884b983b..c0cfdad7e2 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php @@ -187,7 +187,15 @@ class NumberToLocalizedStringTransformer implements DataTransformerInterface $value = str_replace(',', $decSep, $value); } - $result = $formatter->parse($value, \NumberFormatter::TYPE_DOUBLE, $position); + if (false !== strpos($value, $decSep)) { + $type = \NumberFormatter::TYPE_DOUBLE; + } else { + $type = PHP_INT_SIZE === 8 + ? \NumberFormatter::TYPE_INT64 + : \NumberFormatter::TYPE_INT32; + } + + $result = $formatter->parse($value, $type, $position); if (intl_is_failure($formatter->getErrorCode())) { throw new TransformationFailedException($formatter->getErrorMessage()); 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 02131f68c4..7f8626bdbd 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/NumberToLocalizedStringTransformerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/NumberToLocalizedStringTransformerTest.php @@ -641,4 +641,11 @@ class NumberToLocalizedStringTransformerTest extends \PHPUnit_Framework_TestCase $transformer->reverseTransform("12\xc2\xa0345,678foo"); } + + public function testReverseTransformBigint() + { + $transformer = new NumberToLocalizedStringTransformer(null, true); + + $this->assertEquals(PHP_INT_MAX - 1, (int) $transformer->reverseTransform((string) (PHP_INT_MAX - 1))); + } } diff --git a/src/Symfony/Component/HttpKernel/Tests/HttpCache/ResponseCacheStrategyTest.php b/src/Symfony/Component/HttpKernel/Tests/HttpCache/ResponseCacheStrategyTest.php index c70d4e71f3..41e4096240 100644 --- a/src/Symfony/Component/HttpKernel/Tests/HttpCache/ResponseCacheStrategyTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/HttpCache/ResponseCacheStrategyTest.php @@ -16,13 +16,13 @@ namespace Symfony\Component\HttpKernel\Tests\HttpCache; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\HttpCache\EsiResponseCacheStrategy; +use Symfony\Component\HttpKernel\HttpCache\ResponseCacheStrategy; -class EsiResponseCacheStrategyTest extends \PHPUnit_Framework_TestCase +class ResponseCacheStrategyTest extends \PHPUnit_Framework_TestCase { public function testMinimumSharedMaxAgeWins() { - $cacheStrategy = new EsiResponseCacheStrategy(); + $cacheStrategy = new ResponseCacheStrategy(); $response1 = new Response(); $response1->setSharedMaxAge(60); @@ -41,7 +41,7 @@ class EsiResponseCacheStrategyTest extends \PHPUnit_Framework_TestCase public function testSharedMaxAgeNotSetIfNotSetInAnyEmbeddedRequest() { - $cacheStrategy = new EsiResponseCacheStrategy(); + $cacheStrategy = new ResponseCacheStrategy(); $response1 = new Response(); $response1->setSharedMaxAge(60); @@ -59,7 +59,7 @@ class EsiResponseCacheStrategyTest extends \PHPUnit_Framework_TestCase public function testSharedMaxAgeNotSetIfNotSetInMasterRequest() { - $cacheStrategy = new EsiResponseCacheStrategy(); + $cacheStrategy = new ResponseCacheStrategy(); $response1 = new Response(); $response1->setSharedMaxAge(60); diff --git a/src/Symfony/Component/HttpKernel/phpunit.xml.dist b/src/Symfony/Component/HttpKernel/phpunit.xml.dist index 17c48935c7..b29969b36f 100644 --- a/src/Symfony/Component/HttpKernel/phpunit.xml.dist +++ b/src/Symfony/Component/HttpKernel/phpunit.xml.dist @@ -30,7 +30,7 @@ - Symfony\Component\HttpFoundation + Symfony\Component\HttpFoundation diff --git a/src/Symfony/Component/Process/Tests/ProcessTest.php b/src/Symfony/Component/Process/Tests/ProcessTest.php index 501662f8ac..9d6a607830 100644 --- a/src/Symfony/Component/Process/Tests/ProcessTest.php +++ b/src/Symfony/Component/Process/Tests/ProcessTest.php @@ -31,7 +31,7 @@ class ProcessTest extends \PHPUnit_Framework_TestCase public static function setUpBeforeClass() { $phpBin = new PhpExecutableFinder(); - self::$phpBin = 'phpdbg' === PHP_SAPI ? 'php' : $phpBin->find(); + self::$phpBin = getenv('SYMFONY_PROCESS_PHP_TEST_BINARY') ?: ('phpdbg' === PHP_SAPI ? 'php' : $phpBin->find()); if ('\\' !== DIRECTORY_SEPARATOR) { // exec is mandatory to deal with sending a signal to the process // see https://github.com/symfony/symfony/issues/5030 about prepending diff --git a/src/Symfony/Component/Translation/Loader/PoFileLoader.php b/src/Symfony/Component/Translation/Loader/PoFileLoader.php index b5d12e9821..29e898cc47 100644 --- a/src/Symfony/Component/Translation/Loader/PoFileLoader.php +++ b/src/Symfony/Component/Translation/Loader/PoFileLoader.php @@ -108,14 +108,20 @@ class PoFileLoader extends ArrayLoader $messages = array(); $item = $defaults; + $flags = array(); while ($line = fgets($stream)) { $line = trim($line); if ($line === '') { // Whitespace indicated current item is done - $this->addMessage($messages, $item); + if (!in_array('fuzzy', $flags)) { + $this->addMessage($messages, $item); + } $item = $defaults; + $flags = array(); + } elseif (substr($line, 0, 2) === '#,') { + $flags = array_map('trim', explode(',', substr($line, 2))); } elseif (substr($line, 0, 7) === 'msgid "') { // We start a new msg so save previous // TODO: this fails when comments or contexts are added @@ -141,7 +147,9 @@ class PoFileLoader extends ArrayLoader } } // save last item - $this->addMessage($messages, $item); + if (!in_array('fuzzy', $flags)) { + $this->addMessage($messages, $item); + } fclose($stream); return $messages; diff --git a/src/Symfony/Component/Translation/Tests/Loader/PoFileLoaderTest.php b/src/Symfony/Component/Translation/Tests/Loader/PoFileLoaderTest.php index 87090eb736..5d340c766f 100644 --- a/src/Symfony/Component/Translation/Tests/Loader/PoFileLoaderTest.php +++ b/src/Symfony/Component/Translation/Tests/Loader/PoFileLoaderTest.php @@ -93,4 +93,16 @@ class PoFileLoaderTest extends \PHPUnit_Framework_TestCase $this->assertEquals('escaped "bar"', $messages['escaped "foo"']); $this->assertEquals('escaped "bar"|escaped "bars"', $messages['escaped "foos"']); } + + public function testSkipFuzzyTranslations() + { + $loader = new PoFileLoader(); + $resource = __DIR__.'/../fixtures/fuzzy-translations.po'; + $catalogue = $loader->load($resource, 'en', 'domain1'); + + $messages = $catalogue->all('domain1'); + $this->assertArrayHasKey('foo1', $messages); + $this->assertArrayNotHasKey('foo2', $messages); + $this->assertArrayHasKey('foo3', $messages); + } } diff --git a/src/Symfony/Component/Translation/Tests/fixtures/fuzzy-translations.po b/src/Symfony/Component/Translation/Tests/fixtures/fuzzy-translations.po new file mode 100644 index 0000000000..04d4047aa4 --- /dev/null +++ b/src/Symfony/Component/Translation/Tests/fixtures/fuzzy-translations.po @@ -0,0 +1,10 @@ +#, php-format +msgid "foo1" +msgstr "bar1" + +#, fuzzy, php-format +msgid "foo2" +msgstr "fuzzy bar2" + +msgid "foo3" +msgstr "bar3" diff --git a/src/Symfony/Component/Validator/ConstraintValidator.php b/src/Symfony/Component/Validator/ConstraintValidator.php index df6e86e627..c0db7e29ef 100644 --- a/src/Symfony/Component/Validator/ConstraintValidator.php +++ b/src/Symfony/Component/Validator/ConstraintValidator.php @@ -118,9 +118,9 @@ abstract class ConstraintValidator implements ConstraintValidatorInterface * This method returns the equivalent PHP tokens for most scalar types * (i.e. "false" for false, "1" for 1 etc.). Strings are always wrapped * in double quotes ("). Objects, arrays and resources are formatted as - * "object", "array" and "resource". If the parameter $prettyDateTime - * is set to true, {@link \DateTime} objects will be formatted as - * RFC-3339 dates ("Y-m-d H:i:s"). + * "object", "array" and "resource". If the $format bitmask contains + * the PRETTY_DATE bit, then {@link \DateTime} objects will be formatted + * as RFC-3339 dates ("Y-m-d H:i:s"). * * Be careful when passing message parameters to a constraint violation * that (may) contain objects, arrays or resources. These parameters @@ -159,7 +159,7 @@ abstract class ConstraintValidator implements ConstraintValidatorInterface } if (is_object($value)) { - if ($format & self::OBJECT_TO_STRING && method_exists($value, '__toString')) { + if (($format & self::OBJECT_TO_STRING) && method_exists($value, '__toString')) { return $value->__toString(); } diff --git a/src/Symfony/Component/Validator/Tests/Constraints/EmailValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/EmailValidatorTest.php index 7e7a5cc70f..c0dab3d706 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/EmailValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/EmailValidatorTest.php @@ -11,10 +11,14 @@ namespace Symfony\Component\Validator\Tests\Constraints; +use Symfony\Bridge\PhpUnit\DnsMock; use Symfony\Component\Validator\Constraints\Email; use Symfony\Component\Validator\Constraints\EmailValidator; use Symfony\Component\Validator\Validation; +/** + * @group dns-sensitive + */ class EmailValidatorTest extends AbstractConstraintValidatorTest { protected function getApiVersion() @@ -103,4 +107,40 @@ class EmailValidatorTest extends AbstractConstraintValidatorTest $this->assertNoViolation(); } + + /** + * @dataProvider getDnsChecks + */ + public function testDnsChecks($type, $violation) + { + DnsMock::withMockedHosts(array('example.com' => array(array('type' => $violation ? false : $type)))); + + $constraint = new Email(array( + 'message' => 'myMessage', + 'MX' === $type ? 'checkMX' : 'checkHost' => true, + )); + + $this->validator->validate('foo@example.com', $constraint); + + if (!$violation) { + $this->assertNoViolation(); + } else { + $this->buildViolation('myMessage') + ->setParameter('{{ value }}', '"foo@example.com"') + ->setCode($violation) + ->assertRaised(); + } + } + + public function getDnsChecks() + { + return array( + array('MX', false), + array('MX', Email::MX_CHECK_FAILED_ERROR), + array('A', false), + array('A', Email::HOST_CHECK_FAILED_ERROR), + array('AAAA', false), + array('AAAA', Email::HOST_CHECK_FAILED_ERROR), + ); + } }