Merge branch '2.4'

* 2.4:
  Disable 5.6 until it is stable again.
  Update the fixtures.
  fixed CS
  [HttpKernel] fixed default TTL not applied under certain conditions
  Added test when TTL has expired
  [DomCrawler] Fixed image input case sensitive
This commit is contained in:
Fabien Potencier 2014-05-14 08:54:00 +02:00
commit f50c382979
11 changed files with 141 additions and 26 deletions

View File

@ -10,6 +10,7 @@ php:
matrix:
allow_failures:
- php: 5.6
- php: hhvm-nightly
services: mongodb

View File

@ -530,7 +530,9 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
$application->expects($this->any())
->method('getTerminalWidth')
->will($this->returnValue(120));
$application->register('foo')->setCode(function () {throw new \Exception('エラーメッセージ');});
$application->register('foo')->setCode(function () {
throw new \Exception('エラーメッセージ');
});
$tester = new ApplicationTester($application);
$tester->run(array('command' => 'foo'), array('decorated' => false));
@ -544,7 +546,9 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
$application->expects($this->any())
->method('getTerminalWidth')
->will($this->returnValue(32));
$application->register('foo')->setCode(function () {throw new \Exception('コマンドの実行中にエラーが発生しました。');});
$application->register('foo')->setCode(function () {
throw new \Exception('コマンドの実行中にエラーが発生しました。');
});
$tester = new ApplicationTester($application);
$tester->run(array('command' => 'foo'), array('decorated' => false));
$this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception_doublewidth2.txt', $tester->getDisplay(true), '->renderException() wraps messages when they are bigger than the terminal');

View File

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

View File

@ -666,8 +666,9 @@ class Crawler extends \SplObjectStorage
*/
public function selectButton($value)
{
$xpath = sprintf('//input[((@type="submit" or @type="button") and contains(concat(\' \', normalize-space(string(@value)), \' \'), %s)) ', static::xpathLiteral(' '.$value.' ')).
sprintf('or (@type="image" and contains(concat(\' \', normalize-space(string(@alt)), \' \'), %s)) or @id="%s" or @name="%s"] ', static::xpathLiteral(' '.$value.' '), $value, $value).
$translate = 'translate(@type, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz")';
$xpath = sprintf('//input[((contains(%s, "submit") or contains(%s, "button")) and contains(concat(\' \', normalize-space(string(@value)), \' \'), %s)) ', $translate, $translate, static::xpathLiteral(' '.$value.' ')).
sprintf('or (contains(%s, "image") and contains(concat(\' \', normalize-space(string(@alt)), \' \'), %s)) or @id="%s" or @name="%s"] ', $translate, static::xpathLiteral(' '.$value.' '), $value, $value).
sprintf('| //button[contains(concat(\' \', normalize-space(string(.)), \' \'), %s) or @id="%s" or @name="%s"]', static::xpathLiteral(' '.$value.' '), $value, $value);
return $this->filterXPath($xpath);

View File

@ -210,7 +210,7 @@ class ChoiceFormField extends FormField
throw new \LogicException(sprintf('A ChoiceFormField can only be created from an input or select tag (%s given).', $this->node->nodeName));
}
if ('input' == $this->node->nodeName && 'checkbox' != $this->node->getAttribute('type') && 'radio' != $this->node->getAttribute('type')) {
if ('input' == $this->node->nodeName && 'checkbox' != strtolower($this->node->getAttribute('type')) && 'radio' != strtolower($this->node->getAttribute('type'))) {
throw new \LogicException(sprintf('A ChoiceFormField can only be created from an input tag with a type of checkbox or radio (given type is %s).', $this->node->getAttribute('type')));
}
@ -219,7 +219,7 @@ class ChoiceFormField extends FormField
$this->multiple = false;
if ('input' == $this->node->nodeName) {
$this->type = $this->node->getAttribute('type');
$this->type = strtolower($this->node->getAttribute('type'));
$optionValue = $this->buildOptionValue($this->node);
$this->options[] = $optionValue;

View File

@ -103,7 +103,7 @@ class FileFormField extends FormField
throw new \LogicException(sprintf('A FileFormField can only be created from an input tag (%s given).', $this->node->nodeName));
}
if ('file' != $this->node->getAttribute('type')) {
if ('file' != strtolower($this->node->getAttribute('type'))) {
throw new \LogicException(sprintf('A FileFormField can only be created from an input tag with a type of file (given type is %s).', $this->node->getAttribute('type')));
}

View File

@ -34,11 +34,11 @@ class InputFormField extends FormField
throw new \LogicException(sprintf('An InputFormField can only be created from an input or button tag (%s given).', $this->node->nodeName));
}
if ('checkbox' == $this->node->getAttribute('type')) {
if ('checkbox' == strtolower($this->node->getAttribute('type'))) {
throw new \LogicException('Checkboxes should be instances of ChoiceFormField.');
}
if ('file' == $this->node->getAttribute('type')) {
if ('file' == strtolower($this->node->getAttribute('type'))) {
throw new \LogicException('File inputs should be instances of FileFormField.');
}

View File

@ -368,7 +368,7 @@ class Form extends Link implements \ArrayAccess
protected function setNode(\DOMNode $node)
{
$this->button = $node;
if ('button' == $node->nodeName || ('input' == $node->nodeName && in_array($node->getAttribute('type'), array('submit', 'button', 'image')))) {
if ('button' == $node->nodeName || ('input' == $node->nodeName && in_array(strtolower($node->getAttribute('type')), array('submit', 'button', 'image')))) {
if ($node->hasAttribute('form')) {
// if the node has the HTML5-compliant 'form' attribute, use it
$formId = $node->getAttribute('form');
@ -410,7 +410,7 @@ class Form extends Link implements \ArrayAccess
// add submitted button if it has a valid name
if ('form' !== $this->button->nodeName && $this->button->hasAttribute('name') && $this->button->getAttribute('name')) {
if ('input' == $this->button->nodeName && 'image' == $this->button->getAttribute('type')) {
if ('input' == $this->button->nodeName && 'image' == strtolower($this->button->getAttribute('type'))) {
$name = $this->button->getAttribute('name');
$this->button->setAttribute('value', '0');
@ -461,17 +461,17 @@ class Form extends Link implements \ArrayAccess
}
$nodeName = $node->nodeName;
if ('select' == $nodeName || 'input' == $nodeName && 'checkbox' == $node->getAttribute('type')) {
if ('select' == $nodeName || 'input' == $nodeName && 'checkbox' == strtolower($node->getAttribute('type'))) {
$this->set(new Field\ChoiceFormField($node));
} elseif ('input' == $nodeName && 'radio' == $node->getAttribute('type')) {
} elseif ('input' == $nodeName && 'radio' == strtolower($node->getAttribute('type'))) {
if ($this->has($node->getAttribute('name'))) {
$this->get($node->getAttribute('name'))->addChoice($node);
} else {
$this->set(new Field\ChoiceFormField($node));
}
} elseif ('input' == $nodeName && 'file' == $node->getAttribute('type')) {
} elseif ('input' == $nodeName && 'file' == strtolower($node->getAttribute('type'))) {
$this->set(new Field\FileFormField($node));
} elseif ('input' == $nodeName && !in_array($node->getAttribute('type'), array('submit', 'button', 'image'))) {
} elseif ('input' == $nodeName && !in_array(strtolower($node->getAttribute('type')), array('submit', 'button', 'image'))) {
$this->set(new Field\InputFormField($node));
} elseif ('textarea' == $nodeName) {
$this->set(new Field\TextareaFormField($node));

View File

@ -651,6 +651,13 @@ class FormTest extends \PHPUnit_Framework_TestCase
$this->assertSame($nodes->item(0), $form->getFormNode(), '->getFormNode() returns the form node associated with this form');
}
public function testTypeAttributeIsCaseInsensitive()
{
$form = $this->createForm('<form method="post"><input type="IMAGE" name="example" /></form>');
$this->assertTrue($form->has('example.x'), '->has() returns true if the image input was correctly turned into an x and a y fields');
$this->assertTrue($form->has('example.y'), '->has() returns true if the image input was correctly turned into an x and a y fields');
}
/**
* @expectedException \InvalidArgumentException
*/

View File

@ -428,12 +428,6 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
$response = $this->forward($subRequest, $catch);
if ($this->isPrivateRequest($request) && !$response->headers->hasCacheControlDirective('public')) {
$response->setPrivate(true);
} elseif ($this->options['default_ttl'] > 0 && null === $response->getTtl() && !$response->headers->getCacheControlDirective('must-revalidate')) {
$response->setTtl($this->options['default_ttl']);
}
if ($response->isCacheable()) {
$this->store($request, $response);
}
@ -487,6 +481,12 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
$this->processResponseBody($request, $response);
if ($this->isPrivateRequest($request) && !$response->headers->hasCacheControlDirective('public')) {
$response->setPrivate(true);
} elseif ($this->options['default_ttl'] > 0 && null === $response->getTtl() && !$response->headers->getCacheControlDirective('must-revalidate')) {
$response->setTtl($this->options['default_ttl']);
}
return $response;
}

View File

@ -582,6 +582,107 @@ class HttpCacheTest extends HttpCacheTestCase
$this->assertTraceContains('fresh');
$this->assertTraceNotContains('store');
$this->assertEquals('Hello World', $this->response->getContent());
$this->assertRegExp('/s-maxage=10/', $this->response->headers->get('Cache-Control'));
}
public function testAssignsDefaultTtlWhenResponseHasNoFreshnessInformationAndAfterTtlWasExpired()
{
$this->setNextResponse();
$this->cacheConfig['default_ttl'] = 2;
$this->request('GET', '/');
$this->assertHttpKernelIsCalled();
$this->assertTraceContains('miss');
$this->assertTraceContains('store');
$this->assertEquals('Hello World', $this->response->getContent());
$this->assertRegExp('/s-maxage=2/', $this->response->headers->get('Cache-Control'));
$this->request('GET', '/');
$this->assertHttpKernelIsNotCalled();
$this->assertEquals(200, $this->response->getStatusCode());
$this->assertTraceContains('fresh');
$this->assertTraceNotContains('store');
$this->assertEquals('Hello World', $this->response->getContent());
$this->assertRegExp('/s-maxage=2/', $this->response->headers->get('Cache-Control'));
// expires the cache
$values = $this->getMetaStorageValues();
$this->assertCount(1, $values);
$tmp = unserialize($values[0]);
$time = \DateTime::createFromFormat('U', time());
$tmp[0][1]['date'] = \DateTime::createFromFormat('U', time() - 5)->format(DATE_RFC2822);
$r = new \ReflectionObject($this->store);
$m = $r->getMethod('save');
$m->setAccessible(true);
$m->invoke($this->store, 'md'.sha1('http://localhost/'), serialize($tmp));
$this->request('GET', '/');
$this->assertHttpKernelIsCalled();
$this->assertEquals(200, $this->response->getStatusCode());
$this->assertTraceContains('stale');
$this->assertTraceContains('invalid');
$this->assertTraceContains('store');
$this->assertEquals('Hello World', $this->response->getContent());
$this->assertRegExp('/s-maxage=2/', $this->response->headers->get('Cache-Control'));
$this->setNextResponse();
$this->request('GET', '/');
$this->assertHttpKernelIsNotCalled();
$this->assertEquals(200, $this->response->getStatusCode());
$this->assertTraceContains('fresh');
$this->assertTraceNotContains('store');
$this->assertEquals('Hello World', $this->response->getContent());
$this->assertRegExp('/s-maxage=2/', $this->response->headers->get('Cache-Control'));
}
public function testAssignsDefaultTtlWhenResponseHasNoFreshnessInformationAndAfterTtlWasExpiredWithStatus304()
{
$this->setNextResponse();
$this->cacheConfig['default_ttl'] = 2;
$this->request('GET', '/');
$this->assertHttpKernelIsCalled();
$this->assertTraceContains('miss');
$this->assertTraceContains('store');
$this->assertEquals('Hello World', $this->response->getContent());
$this->assertRegExp('/s-maxage=2/', $this->response->headers->get('Cache-Control'));
$this->request('GET', '/');
$this->assertHttpKernelIsNotCalled();
$this->assertEquals(200, $this->response->getStatusCode());
$this->assertTraceContains('fresh');
$this->assertTraceNotContains('store');
$this->assertEquals('Hello World', $this->response->getContent());
// expires the cache
$values = $this->getMetaStorageValues();
$this->assertCount(1, $values);
$tmp = unserialize($values[0]);
$time = \DateTime::createFromFormat('U', time());
$tmp[0][1]['date'] = \DateTime::createFromFormat('U', time() - 5)->format(DATE_RFC2822);
$r = new \ReflectionObject($this->store);
$m = $r->getMethod('save');
$m->setAccessible(true);
$m->invoke($this->store, 'md'.sha1('http://localhost/'), serialize($tmp));
$this->request('GET', '/');
$this->assertHttpKernelIsCalled();
$this->assertEquals(200, $this->response->getStatusCode());
$this->assertTraceContains('stale');
$this->assertTraceContains('valid');
$this->assertTraceContains('store');
$this->assertTraceNotContains('miss');
$this->assertEquals('Hello World', $this->response->getContent());
$this->assertRegExp('/s-maxage=2/', $this->response->headers->get('Cache-Control'));
$this->request('GET', '/');
$this->assertHttpKernelIsNotCalled();
$this->assertEquals(200, $this->response->getStatusCode());
$this->assertTraceContains('fresh');
$this->assertTraceNotContains('store');
$this->assertEquals('Hello World', $this->response->getContent());
$this->assertRegExp('/s-maxage=2/', $this->response->headers->get('Cache-Control'));
}
public function testDoesNotAssignDefaultTtlWhenResponseHasMustRevalidateDirective()