Merge branch '3.0'

* 3.0:
  Fix merge
  [SecurityBundle] Removing test insulations for a huge perf win
  [Validator] Use the new interface in the README
  [Validator] Add missing pt_BR translation
  Fix doctrine bridge tests on older PHP versions
  [Filesystem] fix tests on 2.3
  [Filesystem] Recursivly widen non-executable directories
  [DependencyInjection] fixed definition loosing property shared when decorated by a parent definition
  [Form] fix #15544 when a collection type attribute "required" is false, "prototype" should too
  updated validators.bg.xlf
  [Security] Enable bcrypt validation and result length tests on all PHP versions
  [Security] Verify if a password encoded with bcrypt is no longer than 72 characters
  [Console] Avoid extra blank lines when rendering exceptions
  [Console][Table] fixed render row with multiple cells.
  [Yaml] do not remove "comments" in scalar blocks
This commit is contained in:
Nicolas Grekas 2015-12-22 11:39:31 +01:00
commit e48463bd06
35 changed files with 318 additions and 145 deletions

View File

@ -603,7 +603,7 @@ class EntityTypeTest extends TypeTestCase
$this->persist(array($entity1, $entity2)); $this->persist(array($entity1, $entity2));
$field = $this->factory->createNamed('name', EntityType::class, null, array( $field = $this->factory->createNamed('name', 'Symfony\Bridge\Doctrine\Form\Type\EntityType', null, array(
'multiple' => false, 'multiple' => false,
'expanded' => false, 'expanded' => false,
'em' => 'default', 'em' => 'default',
@ -625,7 +625,7 @@ class EntityTypeTest extends TypeTestCase
$this->persist(array($entity1, $entity2)); $this->persist(array($entity1, $entity2));
$field = $this->factory->createNamed('name', EntityType::class, null, array( $field = $this->factory->createNamed('name', 'Symfony\Bridge\Doctrine\Form\Type\EntityType', null, array(
'multiple' => false, 'multiple' => false,
'expanded' => true, 'expanded' => true,
'em' => 'default', 'em' => 'default',
@ -651,7 +651,7 @@ class EntityTypeTest extends TypeTestCase
$this->persist(array($entity1, $entity2, $entity3)); $this->persist(array($entity1, $entity2, $entity3));
$field = $this->factory->createNamed('name', EntityType::class, null, array( $field = $this->factory->createNamed('name', 'Symfony\Bridge\Doctrine\Form\Type\EntityType', null, array(
'multiple' => true, 'multiple' => true,
'expanded' => false, 'expanded' => false,
'em' => 'default', 'em' => 'default',
@ -682,7 +682,7 @@ class EntityTypeTest extends TypeTestCase
$this->persist(array($entity1, $entity2, $entity3)); $this->persist(array($entity1, $entity2, $entity3));
$field = $this->factory->createNamed('name', EntityType::class, null, array( $field = $this->factory->createNamed('name', 'Symfony\Bridge\Doctrine\Form\Type\EntityType', null, array(
'multiple' => true, 'multiple' => true,
'expanded' => false, 'expanded' => false,
'em' => 'default', 'em' => 'default',
@ -707,7 +707,7 @@ class EntityTypeTest extends TypeTestCase
$this->persist(array($entity1, $entity2, $entity3)); $this->persist(array($entity1, $entity2, $entity3));
$field = $this->factory->createNamed('name', EntityType::class, null, array( $field = $this->factory->createNamed('name', 'Symfony\Bridge\Doctrine\Form\Type\EntityType', null, array(
'multiple' => true, 'multiple' => true,
'expanded' => true, 'expanded' => true,
'em' => 'default', 'em' => 'default',

View File

@ -16,7 +16,6 @@ class AuthenticationCommencingTest extends WebTestCase
public function testAuthenticationIsCommencingIfAccessDeniedExceptionIsWrapped() public function testAuthenticationIsCommencingIfAccessDeniedExceptionIsWrapped()
{ {
$client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => 'config.yml')); $client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => 'config.yml'));
$client->insulate();
$client->request('GET', '/secure-but-not-covered-by-access-control'); $client->request('GET', '/secure-but-not-covered-by-access-control');
$this->assertRedirect($client->getResponse(), '/login'); $this->assertRedirect($client->getResponse(), '/login');

View File

@ -19,7 +19,6 @@ class CsrfFormLoginTest extends WebTestCase
public function testFormLoginAndLogoutWithCsrfTokens($config) public function testFormLoginAndLogoutWithCsrfTokens($config)
{ {
$client = $this->createClient(array('test_case' => 'CsrfFormLogin', 'root_config' => $config)); $client = $this->createClient(array('test_case' => 'CsrfFormLogin', 'root_config' => $config));
$client->insulate();
$form = $client->request('GET', '/login')->selectButton('login')->form(); $form = $client->request('GET', '/login')->selectButton('login')->form();
$form['user_login[username]'] = 'johannes'; $form['user_login[username]'] = 'johannes';
@ -50,7 +49,6 @@ class CsrfFormLoginTest extends WebTestCase
public function testFormLoginWithInvalidCsrfToken($config) public function testFormLoginWithInvalidCsrfToken($config)
{ {
$client = $this->createClient(array('test_case' => 'CsrfFormLogin', 'root_config' => $config)); $client = $this->createClient(array('test_case' => 'CsrfFormLogin', 'root_config' => $config));
$client->insulate();
$form = $client->request('GET', '/login')->selectButton('login')->form(); $form = $client->request('GET', '/login')->selectButton('login')->form();
$form['user_login[_token]'] = ''; $form['user_login[_token]'] = '';
@ -68,7 +66,6 @@ class CsrfFormLoginTest extends WebTestCase
public function testFormLoginWithCustomTargetPath($config) public function testFormLoginWithCustomTargetPath($config)
{ {
$client = $this->createClient(array('test_case' => 'CsrfFormLogin', 'root_config' => $config)); $client = $this->createClient(array('test_case' => 'CsrfFormLogin', 'root_config' => $config));
$client->insulate();
$form = $client->request('GET', '/login')->selectButton('login')->form(); $form = $client->request('GET', '/login')->selectButton('login')->form();
$form['user_login[username]'] = 'johannes'; $form['user_login[username]'] = 'johannes';
@ -89,7 +86,6 @@ class CsrfFormLoginTest extends WebTestCase
public function testFormLoginRedirectsToProtectedResourceAfterLogin($config) public function testFormLoginRedirectsToProtectedResourceAfterLogin($config)
{ {
$client = $this->createClient(array('test_case' => 'CsrfFormLogin', 'root_config' => $config)); $client = $this->createClient(array('test_case' => 'CsrfFormLogin', 'root_config' => $config));
$client->insulate();
$client->request('GET', '/protected-resource'); $client->request('GET', '/protected-resource');
$this->assertRedirect($client->getResponse(), '/login'); $this->assertRedirect($client->getResponse(), '/login');
@ -113,17 +109,13 @@ class CsrfFormLoginTest extends WebTestCase
); );
} }
protected function setUp() public static function setUpBeforeClass()
{ {
parent::setUp(); parent::deleteTmpDir('CsrfFormLogin');
$this->deleteTmpDir('CsrfFormLogin');
} }
protected function tearDown() public static function tearDownAfterClass()
{ {
parent::tearDown(); parent::deleteTmpDir('CsrfFormLogin');
$this->deleteTmpDir('CsrfFormLogin');
} }
} }

View File

@ -18,7 +18,6 @@ class FirewallEntryPointTest extends WebTestCase
public function testItUsesTheConfiguredEntryPointWhenUsingUnknownCredentials() public function testItUsesTheConfiguredEntryPointWhenUsingUnknownCredentials()
{ {
$client = $this->createClient(array('test_case' => 'FirewallEntryPoint')); $client = $this->createClient(array('test_case' => 'FirewallEntryPoint'));
$client->insulate();
$client->request('GET', '/secure/resource', array(), array(), array( $client->request('GET', '/secure/resource', array(), array(), array(
'PHP_AUTH_USER' => 'unknown', 'PHP_AUTH_USER' => 'unknown',
@ -35,7 +34,6 @@ class FirewallEntryPointTest extends WebTestCase
public function testItUsesTheConfiguredEntryPointFromTheExceptionListenerWithFormLoginAndNoCredentials() public function testItUsesTheConfiguredEntryPointFromTheExceptionListenerWithFormLoginAndNoCredentials()
{ {
$client = $this->createClient(array('test_case' => 'FirewallEntryPoint', 'root_config' => 'config_form_login.yml')); $client = $this->createClient(array('test_case' => 'FirewallEntryPoint', 'root_config' => 'config_form_login.yml'));
$client->insulate();
$client->request('GET', '/secure/resource'); $client->request('GET', '/secure/resource');
@ -46,17 +44,13 @@ class FirewallEntryPointTest extends WebTestCase
); );
} }
protected function setUp() public static function setUpBeforeClass()
{ {
parent::setUp(); parent::deleteTmpDir('FirewallEntryPoint');
$this->deleteTmpDir('FirewallEntryPoint');
} }
protected function tearDown() public static function tearDownAfterClass()
{ {
parent::tearDown(); parent::deleteTmpDir('FirewallEntryPoint');
$this->deleteTmpDir('FirewallEntryPoint');
} }
} }

View File

@ -19,7 +19,6 @@ class FormLoginTest extends WebTestCase
public function testFormLogin($config) public function testFormLogin($config)
{ {
$client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => $config)); $client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => $config));
$client->insulate();
$form = $client->request('GET', '/login')->selectButton('login')->form(); $form = $client->request('GET', '/login')->selectButton('login')->form();
$form['_username'] = 'johannes'; $form['_username'] = 'johannes';
@ -39,7 +38,6 @@ class FormLoginTest extends WebTestCase
public function testFormLogout($config) public function testFormLogout($config)
{ {
$client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => $config)); $client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => $config));
$client->insulate();
$form = $client->request('GET', '/login')->selectButton('login')->form(); $form = $client->request('GET', '/login')->selectButton('login')->form();
$form['_username'] = 'johannes'; $form['_username'] = 'johannes';
@ -73,7 +71,6 @@ class FormLoginTest extends WebTestCase
public function testFormLoginWithCustomTargetPath($config) public function testFormLoginWithCustomTargetPath($config)
{ {
$client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => $config)); $client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => $config));
$client->insulate();
$form = $client->request('GET', '/login')->selectButton('login')->form(); $form = $client->request('GET', '/login')->selectButton('login')->form();
$form['_username'] = 'johannes'; $form['_username'] = 'johannes';
@ -94,7 +91,6 @@ class FormLoginTest extends WebTestCase
public function testFormLoginRedirectsToProtectedResourceAfterLogin($config) public function testFormLoginRedirectsToProtectedResourceAfterLogin($config)
{ {
$client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => $config)); $client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => $config));
$client->insulate();
$client->request('GET', '/protected_resource'); $client->request('GET', '/protected_resource');
$this->assertRedirect($client->getResponse(), '/login'); $this->assertRedirect($client->getResponse(), '/login');
@ -118,17 +114,13 @@ class FormLoginTest extends WebTestCase
); );
} }
protected function setUp() public static function setUpBeforeClass()
{ {
parent::setUp(); parent::deleteTmpDir('StandardFormLogin');
$this->deleteTmpDir('StandardFormLogin');
} }
protected function tearDown() public static function tearDownAfterClass()
{ {
parent::tearDown(); parent::deleteTmpDir('StandardFormLogin');
$this->deleteTmpDir('StandardFormLogin');
} }
} }

View File

@ -19,7 +19,6 @@ class LocalizedRoutesAsPathTest extends WebTestCase
public function testLoginLogoutProcedure($locale) public function testLoginLogoutProcedure($locale)
{ {
$client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => 'localized_routes.yml')); $client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => 'localized_routes.yml'));
$client->insulate();
$crawler = $client->request('GET', '/'.$locale.'/login'); $crawler = $client->request('GET', '/'.$locale.'/login');
$form = $crawler->selectButton('login')->form(); $form = $crawler->selectButton('login')->form();
@ -41,7 +40,6 @@ class LocalizedRoutesAsPathTest extends WebTestCase
public function testLoginFailureWithLocalizedFailurePath($locale) public function testLoginFailureWithLocalizedFailurePath($locale)
{ {
$client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => 'localized_form_failure_handler.yml')); $client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => 'localized_form_failure_handler.yml'));
$client->insulate();
$crawler = $client->request('GET', '/'.$locale.'/login'); $crawler = $client->request('GET', '/'.$locale.'/login');
$form = $crawler->selectButton('login')->form(); $form = $crawler->selectButton('login')->form();
@ -58,7 +56,6 @@ class LocalizedRoutesAsPathTest extends WebTestCase
public function testAccessRestrictedResource($locale) public function testAccessRestrictedResource($locale)
{ {
$client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => 'localized_routes.yml')); $client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => 'localized_routes.yml'));
$client->insulate();
$client->request('GET', '/'.$locale.'/secure/'); $client->request('GET', '/'.$locale.'/secure/');
$this->assertRedirect($client->getResponse(), '/'.$locale.'/login'); $this->assertRedirect($client->getResponse(), '/'.$locale.'/login');
@ -70,7 +67,6 @@ class LocalizedRoutesAsPathTest extends WebTestCase
public function testAccessRestrictedResourceWithForward($locale) public function testAccessRestrictedResourceWithForward($locale)
{ {
$client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => 'localized_routes_with_forward.yml')); $client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => 'localized_routes_with_forward.yml'));
$client->insulate();
$crawler = $client->request('GET', '/'.$locale.'/secure/'); $crawler = $client->request('GET', '/'.$locale.'/secure/');
$this->assertCount(1, $crawler->selectButton('login'), (string) $client->getResponse()); $this->assertCount(1, $crawler->selectButton('login'), (string) $client->getResponse());
@ -81,17 +77,13 @@ class LocalizedRoutesAsPathTest extends WebTestCase
return array(array('en'), array('de')); return array(array('en'), array('de'));
} }
protected function setUp() public static function setUpBeforeClass()
{ {
parent::setUp(); parent::deleteTmpDir('StandardFormLogin');
$this->deleteTmpDir('StandardFormLogin');
} }
protected function tearDown() public static function tearDownAfterClass()
{ {
parent::tearDown(); parent::deleteTmpDir('StandardFormLogin');
$this->deleteTmpDir('StandardFormLogin');
} }
} }

View File

@ -19,7 +19,6 @@ class SecurityRoutingIntegrationTest extends WebTestCase
public function testRoutingErrorIsNotExposedForProtectedResourceWhenAnonymous($config) public function testRoutingErrorIsNotExposedForProtectedResourceWhenAnonymous($config)
{ {
$client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => $config)); $client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => $config));
$client->insulate();
$client->request('GET', '/protected_resource'); $client->request('GET', '/protected_resource');
$this->assertRedirect($client->getResponse(), '/login'); $this->assertRedirect($client->getResponse(), '/login');
@ -31,7 +30,6 @@ class SecurityRoutingIntegrationTest extends WebTestCase
public function testRoutingErrorIsExposedWhenNotProtected($config) public function testRoutingErrorIsExposedWhenNotProtected($config)
{ {
$client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => $config)); $client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => $config));
$client->insulate();
$client->request('GET', '/unprotected_resource'); $client->request('GET', '/unprotected_resource');
$this->assertEquals(404, $client->getResponse()->getStatusCode(), (string) $client->getResponse()); $this->assertEquals(404, $client->getResponse()->getStatusCode(), (string) $client->getResponse());
@ -43,7 +41,6 @@ class SecurityRoutingIntegrationTest extends WebTestCase
public function testRoutingErrorIsNotExposedForProtectedResourceWhenLoggedInWithInsufficientRights($config) public function testRoutingErrorIsNotExposedForProtectedResourceWhenLoggedInWithInsufficientRights($config)
{ {
$client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => $config)); $client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => $config));
$client->insulate();
$form = $client->request('GET', '/login')->selectButton('login')->form(); $form = $client->request('GET', '/login')->selectButton('login')->form();
$form['_username'] = 'johannes'; $form['_username'] = 'johannes';
@ -120,17 +117,13 @@ class SecurityRoutingIntegrationTest extends WebTestCase
return array(array('config.yml'), array('routes_as_path.yml')); return array(array('config.yml'), array('routes_as_path.yml'));
} }
protected function setUp() public static function setUpBeforeClass()
{ {
parent::setUp(); parent::deleteTmpDir('StandardFormLogin');
$this->deleteTmpDir('StandardFormLogin');
} }
protected function tearDown() public static function tearDownAfterClass()
{ {
parent::tearDown(); parent::deleteTmpDir('StandardFormLogin');
$this->deleteTmpDir('StandardFormLogin');
} }
} }

View File

@ -62,7 +62,6 @@ class SwitchUserTest extends WebTestCase
{ {
$client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => 'switchuser.yml')); $client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => 'switchuser.yml'));
$client->followRedirects(true); $client->followRedirects(true);
$client->insulate();
$form = $client->request('GET', '/login')->selectButton('login')->form(); $form = $client->request('GET', '/login')->selectButton('login')->form();
$form['_username'] = $username; $form['_username'] = $username;
@ -72,17 +71,13 @@ class SwitchUserTest extends WebTestCase
return $client; return $client;
} }
protected function setUp() public static function setUpBeforeClass()
{ {
parent::setUp(); parent::deleteTmpDir('StandardFormLogin');
$this->deleteTmpDir('StandardFormLogin');
} }
protected function tearDown() public static function tearDownAfterClass()
{ {
parent::tearDown(); parent::deleteTmpDir('StandardFormLogin');
$this->deleteTmpDir('StandardFormLogin');
} }
} }

View File

@ -23,7 +23,7 @@ class WebTestCase extends BaseWebTestCase
self::assertEquals('http://localhost'.$location, $response->headers->get('Location')); self::assertEquals('http://localhost'.$location, $response->headers->get('Location'));
} }
protected function deleteTmpDir($testCase) protected static function deleteTmpDir($testCase)
{ {
if (!file_exists($dir = sys_get_temp_dir().'/'.Kernel::VERSION.'/'.$testCase)) { if (!file_exists($dir = sys_get_temp_dir().'/'.Kernel::VERSION.'/'.$testCase)) {
return; return;

View File

@ -65,6 +65,18 @@ class AppKernel extends Kernel
parent::__construct($environment, $debug); parent::__construct($environment, $debug);
} }
/**
* {@inheritdoc}
*/
public function getName()
{
if (null === $this->name) {
$this->name = parent::getName().md5($this->rootConfig);
}
return $this->name;
}
public function registerBundles() public function registerBundles()
{ {
if (!is_file($filename = $this->getRootDir().'/'.$this->testCase.'/bundles.php')) { if (!is_file($filename = $this->getRootDir().'/'.$this->testCase.'/bundles.php')) {

View File

@ -581,6 +581,8 @@ class Application
*/ */
public function renderException(\Exception $e, OutputInterface $output) public function renderException(\Exception $e, OutputInterface $output)
{ {
$output->writeln('', OutputInterface::VERBOSITY_QUIET);
do { do {
$title = sprintf(' [%s] ', get_class($e)); $title = sprintf(' [%s] ', get_class($e));
@ -603,7 +605,7 @@ class Application
} }
} }
$messages = array('', ''); $messages = array();
$messages[] = $emptyLine = $formatter->format(sprintf('<error>%s</error>', str_repeat(' ', $len))); $messages[] = $emptyLine = $formatter->format(sprintf('<error>%s</error>', str_repeat(' ', $len)));
$messages[] = $formatter->format(sprintf('<error>%s%s</error>', $title, str_repeat(' ', max(0, $len - $this->stringWidth($title))))); $messages[] = $formatter->format(sprintf('<error>%s%s</error>', $title, str_repeat(' ', max(0, $len - $this->stringWidth($title)))));
foreach ($lines as $line) { foreach ($lines as $line) {
@ -611,7 +613,6 @@ class Application
} }
$messages[] = $emptyLine; $messages[] = $emptyLine;
$messages[] = ''; $messages[] = '';
$messages[] = '';
$output->writeln($messages, OutputInterface::OUTPUT_RAW | OutputInterface::VERBOSITY_QUIET); $output->writeln($messages, OutputInterface::OUTPUT_RAW | OutputInterface::VERBOSITY_QUIET);
@ -638,14 +639,12 @@ class Application
} }
$output->writeln('', OutputInterface::VERBOSITY_QUIET); $output->writeln('', OutputInterface::VERBOSITY_QUIET);
$output->writeln('', OutputInterface::VERBOSITY_QUIET);
} }
} while ($e = $e->getPrevious()); } while ($e = $e->getPrevious());
if (null !== $this->runningCommand) { if (null !== $this->runningCommand) {
$output->writeln(sprintf('<info>%s</info>', sprintf($this->runningCommand->getSynopsis(), $this->getName())), OutputInterface::VERBOSITY_QUIET); $output->writeln(sprintf('<info>%s</info>', sprintf($this->runningCommand->getSynopsis(), $this->getName())), OutputInterface::VERBOSITY_QUIET);
$output->writeln('', OutputInterface::VERBOSITY_QUIET); $output->writeln('', OutputInterface::VERBOSITY_QUIET);
$output->writeln('', OutputInterface::VERBOSITY_QUIET);
} }
} }

View File

@ -395,7 +395,6 @@ class Table
// Remove any new line breaks and replace it with a new line // Remove any new line breaks and replace it with a new line
foreach ($rows[$rowKey] as $column => $cell) { foreach ($rows[$rowKey] as $column => $cell) {
$rows[$rowKey] = $this->fillCells($rows[$rowKey], $column);
if (!strstr($cell, "\n")) { if (!strstr($cell, "\n")) {
continue; continue;
} }
@ -415,7 +414,7 @@ class Table
$tableRows = array(); $tableRows = array();
foreach ($rows as $rowKey => $row) { foreach ($rows as $rowKey => $row) {
$tableRows[] = $row; $tableRows[] = $this->fillCells($row);
if (isset($unmergedRows[$rowKey])) { if (isset($unmergedRows[$rowKey])) {
$tableRows = array_merge($tableRows, $unmergedRows[$rowKey]); $tableRows = array_merge($tableRows, $unmergedRows[$rowKey]);
} }
@ -481,21 +480,23 @@ class Table
* fill cells for a row that contains colspan > 1. * fill cells for a row that contains colspan > 1.
* *
* @param array $row * @param array $row
* @param int $column
* *
* @return array * @return array
*/ */
private function fillCells($row, $column) private function fillCells($row)
{ {
$cell = $row[$column]; $newRow = array();
foreach ($row as $column => $cell) {
$newRow[] = $cell;
if ($cell instanceof TableCell && $cell->getColspan() > 1) { if ($cell instanceof TableCell && $cell->getColspan() > 1) {
foreach (range($column + 1, $column + $cell->getColspan() - 1) as $position) { foreach (range($column + 1, $column + $cell->getColspan() - 1) as $position) {
// insert empty value into rows at column position // insert empty value at column position
array_splice($row, $position, 0, ''); $newRow[] = '';
}
} }
} }
return $row; return $newRow ?: $row;
} }
/** /**

View File

@ -1,8 +1,6 @@
[Symfony\Component\Console\Exception\CommandNotFoundException] [Symfony\Component\Console\Exception\CommandNotFoundException]
Command "foo" is not defined. Command "foo" is not defined.

View File

@ -1,11 +1,8 @@
[Symfony\Component\Console\Exception\InvalidOptionException] [Symfony\Component\Console\Exception\InvalidOptionException]
The "--foo" option does not exist. The "--foo" option does not exist.
list [--raw] [--format FORMAT] [--] [<namespace>] list [--raw] [--format FORMAT] [--] [<namespace>]

View File

@ -1,27 +1,18 @@
[Exception] [Exception]
Third exception comment Third exception comment
[Exception] [Exception]
Second exception comment Second exception comment
[Exception] [Exception]
First exception <p>this is html</p> First exception <p>this is html</p>
foo3:bar foo3:bar

View File

@ -1,27 +1,18 @@
   
 [Exception]   [Exception] 
 Third exception comment   Third exception comment 
   
   
 [Exception]   [Exception] 
 Second exception comment   Second exception comment 
   
   
 [Exception]   [Exception] 
 First exception <p>this is html</p>   First exception <p>this is html</p> 
   
foo3:bar foo3:bar

View File

@ -1,9 +1,7 @@
[Symfony\Component\Console\Exception\CommandNotFoundException] [Symfony\Component\Console\Exception\CommandNotFoundException]
Command "foo" is not define Command "foo" is not define
d. d.

View File

@ -1,11 +1,8 @@
[Exception] [Exception]
エラーメッセージ エラーメッセージ
foo foo

View File

@ -1,11 +1,8 @@
   
 [Exception]   [Exception] 
 エラーメッセージ   エラーメッセージ 
   
foo foo

View File

@ -1,12 +1,9 @@
[Exception] [Exception]
コマンドの実行中にエラーが コマンドの実行中にエラーが
発生しました。 発生しました。
foo foo

View File

@ -459,6 +459,24 @@ TABLE
| ISBN | Title | Author | | ISBN | Title | Author |
+------+-------+--------+ +------+-------+--------+
TABLE
),
'Row with multiple cells' => array(
array(),
array(
array(
new TableCell('1', array('colspan' => 3)),
new TableCell('2', array('colspan' => 2)),
new TableCell('3', array('colspan' => 2)),
new TableCell('4', array('colspan' => 2)),
),
),
'default',
<<<TABLE
+--+--+--+--+--+--+--+--+--+
| 1 | 2 | 3 | 4 |
+--+--+--+--+--+--+--+--+--+
TABLE TABLE
), ),
); );

View File

@ -192,6 +192,7 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface
// these attributes are always taken from the child // these attributes are always taken from the child
$def->setAbstract($definition->isAbstract()); $def->setAbstract($definition->isAbstract());
$def->setShared($definition->isShared());
$def->setTags($definition->getTags()); $def->setTags($definition->getTags());
return $def; return $def;

View File

@ -79,6 +79,25 @@ class ResolveDefinitionTemplatesPassTest extends \PHPUnit_Framework_TestCase
$this->assertFalse($def->isAbstract()); $this->assertFalse($def->isAbstract());
} }
public function testProcessDoesNotCopyShared()
{
$container = new ContainerBuilder();
$container
->register('parent')
->setShared(false)
;
$container
->setDefinition('child', new DefinitionDecorator('parent'))
;
$this->process($container);
$def = $container->getDefinition('child');
$this->assertTrue($def->isShared());
}
public function testProcessDoesNotCopyTags() public function testProcessDoesNotCopyTags()
{ {
$container = new ContainerBuilder(); $container = new ContainerBuilder();
@ -117,6 +136,25 @@ class ResolveDefinitionTemplatesPassTest extends \PHPUnit_Framework_TestCase
$this->assertNull($def->getDecoratedService()); $this->assertNull($def->getDecoratedService());
} }
public function testProcessDoesNotDropShared()
{
$container = new ContainerBuilder();
$container
->register('parent')
;
$container
->setDefinition('child', new DefinitionDecorator('parent'))
->setShared(false)
;
$this->process($container);
$def = $container->getDefinition('child');
$this->assertFalse($def->isShared());
}
public function testProcessHandlesMultipleInheritance() public function testProcessHandlesMultipleInheritance()
{ {
$container = new ContainerBuilder(); $container = new ContainerBuilder();

View File

@ -192,12 +192,12 @@ class Filesystem
public function chmod($files, $mode, $umask = 0000, $recursive = false) public function chmod($files, $mode, $umask = 0000, $recursive = false)
{ {
foreach ($this->toIterator($files) as $file) { foreach ($this->toIterator($files) as $file) {
if ($recursive && is_dir($file) && !is_link($file)) {
$this->chmod(new \FilesystemIterator($file), $mode, $umask, true);
}
if (true !== @chmod($file, $mode & ~$umask)) { if (true !== @chmod($file, $mode & ~$umask)) {
throw new IOException(sprintf('Failed to chmod file "%s".', $file), 0, null, $file); throw new IOException(sprintf('Failed to chmod file "%s".', $file), 0, null, $file);
} }
if ($recursive && is_dir($file) && !is_link($file)) {
$this->chmod(new \FilesystemIterator($file), $mode, $umask, true);
}
} }
} }

View File

@ -483,6 +483,22 @@ class FilesystemTest extends FilesystemTestCase
$this->assertFilePermissions(753, $directory); $this->assertFilePermissions(753, $directory);
} }
public function testChmodChangesZeroModeOnSubdirectoriesOnRecursive()
{
$this->markAsSkippedIfChmodIsMissing();
$directory = $this->workspace.DIRECTORY_SEPARATOR.'directory';
$subdirectory = $directory.DIRECTORY_SEPARATOR.'subdirectory';
mkdir($directory);
mkdir($subdirectory);
chmod($subdirectory, 0000);
$this->filesystem->chmod($directory, 0753, 0000, true);
$this->assertFilePermissions(753, $subdirectory);
}
public function testChown() public function testChown()
{ {
$this->markAsSkippedIfPosixIsMissing(); $this->markAsSkippedIfPosixIsMissing();

View File

@ -28,8 +28,9 @@ class CollectionType extends AbstractType
{ {
if ($options['allow_add'] && $options['prototype']) { if ($options['allow_add'] && $options['prototype']) {
$prototypeOptions = array_replace(array( $prototypeOptions = array_replace(array(
'required' => $options['required'],
'label' => $options['prototype_name'].'label__', 'label' => $options['prototype_name'].'label__',
), $options['options']); ), $options['entry_options']);
if (null !== $options['prototype_data']) { if (null !== $options['prototype_data']) {
$prototypeOptions['data'] = $options['prototype_data']; $prototypeOptions['data'] = $options['prototype_data'];

View File

@ -289,19 +289,29 @@ class CollectionTypeTest extends \Symfony\Component\Form\Test\TypeTestCase
$this->assertSame('foo', $form->createView()->vars['prototype']->vars['value']); $this->assertSame('foo', $form->createView()->vars['prototype']->vars['value']);
} }
/** public function testPrototypeDefaultRequired()
* @group legacy
*/
public function testLegacyPrototypeData()
{ {
$form = $this->factory->create('Symfony\Component\Form\Extension\Core\Type\CollectionType', array(), array( $form = $this->factory->create('Symfony\Component\Form\Extension\Core\Type\CollectionType', array(), array(
'entry_type' => 'Symfony\Component\Form\Extension\Core\Type\FileType',
'allow_add' => true, 'allow_add' => true,
'prototype' => true, 'prototype' => true,
'type' => 'Symfony\Component\Form\Extension\Core\Type\TextType', 'prototype_name' => '__test__',
'options' => array(
'data' => 'bar',
),
)); ));
$this->assertSame('bar', $form->createView()->vars['prototype']->vars['value']);
$this->assertTrue($form->createView()->vars['prototype']->vars['required']);
}
public function testPrototypeSetNotRequired()
{
$form = $this->factory->create('Symfony\Component\Form\Extension\Core\Type\CollectionType', array(), array(
'entry_type' => 'Symfony\Component\Form\Extension\Core\Type\FileType',
'allow_add' => true,
'prototype' => true,
'prototype_name' => '__test__',
'required' => false,
));
$this->assertFalse($form->createView()->vars['required'], 'collection is not required');
$this->assertFalse($form->createView()->vars['prototype']->vars['required'], '"prototype" should not be required');
} }
} }

View File

@ -19,6 +19,8 @@ use Symfony\Component\Security\Core\Exception\BadCredentialsException;
*/ */
class BCryptPasswordEncoder extends BasePasswordEncoder class BCryptPasswordEncoder extends BasePasswordEncoder
{ {
const MAX_PASSWORD_LENGTH = 72;
/** /**
* @var string * @var string
*/ */

View File

@ -93,6 +93,6 @@ abstract class BasePasswordEncoder implements PasswordEncoderInterface
*/ */
protected function isPasswordTooLong($password) protected function isPasswordTooLong($password)
{ {
return strlen($password) > self::MAX_PASSWORD_LENGTH; return strlen($password) > static::MAX_PASSWORD_LENGTH;
} }
} }

View File

@ -67,13 +67,15 @@ class BCryptPasswordEncoderTest extends \PHPUnit_Framework_TestCase
{ {
$encoder = new BCryptPasswordEncoder(self::VALID_COST); $encoder = new BCryptPasswordEncoder(self::VALID_COST);
$encoder->encodePassword(str_repeat('a', 5000), 'salt'); $encoder->encodePassword(str_repeat('a', 73), 'salt');
} }
public function testCheckPasswordLength() public function testCheckPasswordLength()
{ {
$encoder = new BCryptPasswordEncoder(self::VALID_COST); $encoder = new BCryptPasswordEncoder(self::VALID_COST);
$result = $encoder->encodePassword(str_repeat('a', 72), null);
$this->assertFalse($encoder->isPasswordValid('encoded', str_repeat('a', 5000), 'salt')); $this->assertFalse($encoder->isPasswordValid($result, str_repeat('a', 73), 'salt'));
$this->assertTrue($encoder->isPasswordValid($result, str_repeat('a', 72), 'salt'));
} }
} }

View File

@ -18,7 +18,7 @@ use Symfony\Component\Validator\Constraints\Length;
$validator = Validation::createValidator(); $validator = Validation::createValidator();
$violations = $validator->validateValue('Bernhard', new Length(array('min' => 10))); $violations = $validator->validate('Bernhard', new Length(array('min' => 10)));
``` ```
This validation will fail because the given string is shorter than ten This validation will fail because the given string is shorter than ten
@ -46,7 +46,7 @@ $constraint = new Assert\Collection(array(
'password' => new Assert\Length(array('min' => 60)), 'password' => new Assert\Length(array('min' => 60)),
)); ));
$violations = $validator->validateValue($input, $constraint); $violations = $validator->validate($input, $constraint);
``` ```
Again, the validator returns the list of violations. Again, the validator returns the list of violations.

View File

@ -278,6 +278,42 @@
<source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source> <source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
<target>Стойността не трябва да бъде идентична с {{ compared_value_type }} {{ compared_value }}.</target> <target>Стойността не трябва да бъде идентична с {{ compared_value_type }} {{ compared_value }}.</target>
</trans-unit> </trans-unit>
<trans-unit id="73">
<source>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</source>
<target>Изображението е с твърде голяма пропорция ({{ ratio }}). Максималната пропорция трябва да е {{ max_ratio }}.</target>
</trans-unit>
<trans-unit id="74">
<source>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</source>
<target>Изображението е с твърде малка пропорция ({{ ratio }}). Минималната пропорция трябва да е {{ min_ratio }}.</target>
</trans-unit>
<trans-unit id="75">
<source>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</source>
<target>Изображението е квадрат ({{ width }}x{{ height }}px). Такива изображения не са разрешени.</target>
</trans-unit>
<trans-unit id="76">
<source>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</source>
<target>Изображението е с пейзажна ориентация ({{ width }}x{{ height }}px). Изображения с такава ориентация не са разрешени.</target>
</trans-unit>
<trans-unit id="77">
<source>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</source>
<target>Изображението е с портретна ориентация ({{ width }}x{{ height }}px). Изображения с такава ориентация не са разрешени.</target>
</trans-unit>
<trans-unit id="78">
<source>An empty file is not allowed.</source>
<target>Празни файлове не са разрешени.</target>
</trans-unit>
<trans-unit id="79">
<source>The host could not be resolved.</source>
<target>Хостът е недостъпен.</target>
</trans-unit>
<trans-unit id="80">
<source>This value does not match the expected {{ charset }} charset.</source>
<target>Стойността не съвпада с {{ charset }}.</target>
</trans-unit>
<trans-unit id="81">
<source>This is not a valid Business Identifier Code (BIC).</source>
<target>Невалиден бизнес идентификационен код (BIC).</target>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View File

@ -310,6 +310,10 @@
<source>This value does not match the expected {{ charset }} charset.</source> <source>This value does not match the expected {{ charset }} charset.</source>
<target>Este valor não corresponde ao charset {{ charset }} esperado.</target> <target>Este valor não corresponde ao charset {{ charset }} esperado.</target>
</trans-unit> </trans-unit>
<trans-unit id="81">
<source>This is not a valid Business Identifier Code (BIC).</source>
<target>Este não é um Código Identificador Bancário (BIC) válido.</target>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View File

@ -337,6 +337,7 @@ class Parser
private function getNextEmbedBlock($indentation = null, $inSequence = false) private function getNextEmbedBlock($indentation = null, $inSequence = false)
{ {
$oldLineIndentation = $this->getCurrentLineIndentation(); $oldLineIndentation = $this->getCurrentLineIndentation();
$insideBlockScalar = $this->isBlockScalarHeader();
if (!$this->moveToNextLine()) { if (!$this->moveToNextLine()) {
return; return;
@ -373,17 +374,21 @@ class Parser
$isItUnindentedCollection = $this->isStringUnIndentedCollectionItem(); $isItUnindentedCollection = $this->isStringUnIndentedCollectionItem();
// Comments must not be removed inside a block scalar if (!$insideBlockScalar) {
$removeCommentsPattern = '~'.self::BLOCK_SCALAR_HEADER_PATTERN.'$~'; $insideBlockScalar = $this->isBlockScalarHeader();
$removeComments = !preg_match($removeCommentsPattern, $this->currentLine); }
$previousLineIndentation = $this->getCurrentLineIndentation();
while ($this->moveToNextLine()) { while ($this->moveToNextLine()) {
$indent = $this->getCurrentLineIndentation(); $indent = $this->getCurrentLineIndentation();
if ($indent === $newIndent) { if (!$insideBlockScalar && $indent === $previousLineIndentation) {
$removeComments = !preg_match($removeCommentsPattern, $this->currentLine); $insideBlockScalar = $this->isBlockScalarHeader();
} }
$previousLineIndentation = $indent;
if ($isItUnindentedCollection && !$this->isStringUnIndentedCollectionItem() && $newIndent === $indent) { if ($isItUnindentedCollection && !$this->isStringUnIndentedCollectionItem() && $newIndent === $indent) {
$this->moveToPreviousLine(); $this->moveToPreviousLine();
break; break;
@ -394,7 +399,8 @@ class Parser
continue; continue;
} }
if ($removeComments && $this->isCurrentLineComment()) { // we ignore "comment" lines only when we are not inside a scalar block
if (!$insideBlockScalar && $this->isCurrentLineComment()) {
continue; continue;
} }
@ -714,4 +720,14 @@ class Parser
{ {
return 0 === strpos($this->currentLine, '- '); return 0 === strpos($this->currentLine, '- ');
} }
/**
* Tests whether or not the current line is the header of a block scalar.
*
* @return bool
*/
private function isBlockScalarHeader()
{
return (bool) preg_match('~'.self::BLOCK_SCALAR_HEADER_PATTERN.'$~', $this->currentLine);
}
} }

View File

@ -806,6 +806,100 @@ EOT;
$this->assertSame(array('foo' => array('bar' => 'foobar')), $this->parser->parse($yaml)); $this->assertSame(array('foo' => array('bar' => 'foobar')), $this->parser->parse($yaml));
} }
/**
* @dataProvider getCommentLikeStringInScalarBlockData
*/
public function testCommentLikeStringsAreNotStrippedInBlockScalars($yaml, $expectedParserResult)
{
$this->assertSame($expectedParserResult, $this->parser->parse($yaml));
}
public function getCommentLikeStringInScalarBlockData()
{
$yaml1 = <<<EOT
pages:
-
title: some title
content: |
# comment 1
header
# comment 2
<body>
<h1>title</h1>
</body>
footer # comment3
EOT;
$expected1 = array(
'pages' => array(
array(
'title' => 'some title',
'content' => <<<EOT
# comment 1
header
# comment 2
<body>
<h1>title</h1>
</body>
footer # comment3
EOT
,
),
),
);
$yaml2 = <<<EOT
test: |
foo
# bar
baz
collection:
- one: |
foo
# bar
baz
- two: |
foo
# bar
baz
EOT;
$expected2 = array(
'test' => <<<EOT
foo
# bar
baz
EOT
,
'collection' => array(
array(
'one' => <<<EOT
foo
# bar
baz
EOT
,
),
array(
'two' => <<<EOT
foo
# bar
baz
EOT
,
),
),
);
return array(
array($yaml1, $expected1),
array($yaml2, $expected2),
);
}
} }
class B class B