+ {%- else -%}
+ {%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-check-input')|trim}) -%}
+
{%- endif -%}
@@ -121,18 +135,21 @@
{% block radio_widget -%}
{%- set parent_label_class = parent_label_class|default(label_attr.class|default('')) -%}
- {%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-check-input')|trim}) -%}
- {%- if 'radio-inline' in parent_label_class -%}
- {{- form_label(form, null, { widget: parent() }) -}}
+ {%- if 'radio-custom' in parent_label_class -%}
+ {%- set attr = attr|merge({class: (attr.class|default('') ~ ' custom-control-input')|trim}) -%}
+
+ {%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-check-input')|trim}) -%}
+
{{- form_label(form, null, { widget: parent() }) -}}
{%- endif -%}
{%- endblock radio_widget %}
{% block choice_widget_expanded -%}
- {% if '-inline' in label_attr.class|default('') -%}
+
{%- for child in form %}
{{- form_widget(child, {
parent_label_class: label_attr.class|default(''),
@@ -140,20 +157,7 @@
valid: valid,
}) -}}
{% endfor -%}
- {%- else -%}
- {%- if not valid -%}
- {%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-control is-invalid')|trim}) %}
- {%- endif -%}
-
- {%- for child in form %}
- {{- form_widget(child, {
- parent_label_class: label_attr.class|default(''),
- translation_domain: choice_translation_domain,
- valid: true,
- }) -}}
- {% endfor -%}
-
- {%- endif %}
+
{%- endblock choice_widget_expanded %}
{# Labels #}
@@ -162,7 +166,7 @@
{% if label is not same as(false) -%}
{%- if compound is defined and compound -%}
{%- set element = 'legend' -%}
- {%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' col-form-legend')|trim}) -%}
+ {%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' col-form-label')|trim}) -%}
{%- else -%}
{%- set label_attr = label_attr|merge({for: id, class: (label_attr.class|default('') ~ ' form-control-label')|trim}) -%}
{%- endif -%}
@@ -179,19 +183,26 @@
{% set label = name|humanize %}
{%- endif -%}
{%- endif -%}
- <{{ element|default('label') }}{% if label_attr %}{% with { attr: label_attr } %}{{ block('attributes') }}{% endwith %}{% endif %}>{{ translation_domain is same as(false) ? label : label|trans({}, translation_domain) }}{% block form_label_errors %}{{- form_errors(form) -}}{% endblock form_label_errors %}{{ element|default('label') }}>
+ <{{ element|default('label') }}{% if label_attr %}{% with { attr: label_attr } %}{{ block('attributes') }}{% endwith %}{% endif %}>{{ translation_domain is same as(false) ? label : label|trans({}, translation_domain) }}{{- form_errors(form) -}}{{ element|default('label') }}>
{%- endif -%}
{%- endblock form_label %}
{% block checkbox_radio_label -%}
{#- Do not display the label if widget is not defined in order to prevent double label rendering -#}
{%- if widget is defined -%}
- {%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' form-check-label')|trim}) -%}
+ {%- if parent_label_class is defined and ('checkbox-custom' in parent_label_class or 'radio-custom' in parent_label_class) -%}
+ {%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' custom-control-label')|trim}) -%}
+ {%- else %}
+ {%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' form-check-label')|trim}) -%}
+ {%- endif %}
+ {%- if not compound -%}
+ {% set label_attr = label_attr|merge({'for': id}) %}
+ {%- endif -%}
{%- if required -%}
{%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' required')|trim}) -%}
{%- endif -%}
{%- if parent_label_class is defined -%}
- {%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' ' ~ parent_label_class)|trim}) -%}
+ {%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' ' ~ parent_label_class)|replace({'checkbox-inline': '', 'radio-inline': '', 'checkbox-custom': '', 'radio-custom': ''})|trim}) -%}
{%- endif -%}
{%- if label is not same as(false) and label is empty -%}
{%- if label_format is not empty -%}
@@ -203,8 +214,11 @@
{%- set label = name|humanize -%}
{%- endif -%}
{%- endif -%}
+
+ {{ widget|raw }}
{%- endif -%}
{%- endblock checkbox_radio_label %}
@@ -225,12 +239,12 @@
{% block form_errors -%}
{%- if errors|length > 0 -%}
-
+
{%- endif %}
{%- endblock form_errors %}
diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_base_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_base_layout.html.twig
index d57978220f..71aedf99ad 100644
--- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_base_layout.html.twig
+++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_base_layout.html.twig
@@ -147,7 +147,7 @@
{% block choice_label -%}
{# remove the checkbox-inline and radio-inline class, it's only useful for embed labels #}
- {%- set label_attr = label_attr|merge({class: label_attr.class|default('')|replace({'checkbox-inline': '', 'radio-inline': ''})|trim}) -%}
+ {%- set label_attr = label_attr|merge({class: label_attr.class|default('')|replace({'checkbox-inline': '', 'radio-inline': '', 'checkbox-custom': '', 'radio-custom': ''})|trim}) -%}
{{- block('form_label') -}}
{% endblock choice_label %}
diff --git a/src/Symfony/Bridge/Twig/composer.json b/src/Symfony/Bridge/Twig/composer.json
index 5c7d9bfd53..1d08eb246e 100644
--- a/src/Symfony/Bridge/Twig/composer.json
+++ b/src/Symfony/Bridge/Twig/composer.json
@@ -23,7 +23,7 @@
"symfony/asset": "~3.4|~4.0",
"symfony/dependency-injection": "~3.4|~4.0",
"symfony/finder": "~3.4|~4.0",
- "symfony/form": "~3.4|~4.0",
+ "symfony/form": "^3.4.5|^4.0.5",
"symfony/http-foundation": "~3.4|~4.0",
"symfony/http-kernel": "~3.4|~4.0",
"symfony/polyfill-intl-icu": "~1.0",
@@ -41,7 +41,7 @@
"symfony/workflow": "~3.4|~4.0"
},
"conflict": {
- "symfony/form": "<3.4",
+ "symfony/form": "<3.4.5|<4.0.5,>=4.0",
"symfony/console": "<3.4"
},
"suggest": {
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddAnnotationsCachedReaderPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddAnnotationsCachedReaderPass.php
index 35ea20a89a..4f09e52bdc 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddAnnotationsCachedReaderPass.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddAnnotationsCachedReaderPass.php
@@ -26,16 +26,16 @@ class AddAnnotationsCachedReaderPass implements CompilerPassInterface
{
// "annotations.cached_reader" is wired late so that any passes using
// "annotation_reader" at build time don't get any cache
- if ($container->hasDefinition('annotations.cached_reader')) {
- $reader = $container->getDefinition('annotations.cached_reader');
+ foreach ($container->findTaggedServiceIds('annotations.cached_reader') as $id => $tags) {
+ $reader = $container->getDefinition($id);
$properties = $reader->getProperties();
if (isset($properties['cacheProviderBackup'])) {
$provider = $properties['cacheProviderBackup']->getValues()[0];
unset($properties['cacheProviderBackup']);
$reader->setProperties($properties);
- $container->set('annotations.cached_reader', null);
- $container->setDefinition('annotations.cached_reader', $reader->replaceArgument(1, $provider));
+ $container->set($id, null);
+ $container->setDefinition($id, $reader->replaceArgument(1, $provider));
}
}
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/UnusedTagsPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/UnusedTagsPass.php
index ecc4d9e563..cb3366a499 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/UnusedTagsPass.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/UnusedTagsPass.php
@@ -22,6 +22,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
class UnusedTagsPass implements CompilerPassInterface
{
private $whitelist = array(
+ 'annotations.cached_reader',
'cache.pool.clearer',
'console.command',
'container.hot_path',
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
index 95d0264450..f9f3ddf040 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
@@ -1116,7 +1116,9 @@ class FrameworkExtension extends Extension
->replaceArgument(2, $config['debug'])
// temporary property to lazy-reference the cache provider without using it until AddAnnotationsCachedReaderPass runs
->setProperty('cacheProviderBackup', new ServiceClosureArgument(new Reference($cacheService)))
+ ->addTag('annotations.cached_reader')
;
+
$container->setAlias('annotation_reader', 'annotations.cached_reader')->setPrivate(true);
$container->setAlias(Reader::class, new Alias('annotations.cached_reader', false));
} else {
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
index dbc21d897a..72010831a4 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
@@ -25,6 +25,7 @@ use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Adapter\ProxyAdapter;
use Symfony\Component\Cache\Adapter\RedisAdapter;
use Symfony\Component\DependencyInjection\ChildDefinition;
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Loader\ClosureLoader;
@@ -582,10 +583,12 @@ abstract class FrameworkExtensionTest extends TestCase
public function testAnnotations()
{
- $container = $this->createContainerFromFile('full');
+ $container = $this->createContainerFromFile('full', array(), true, false);
+ $container->addCompilerPass(new TestAnnotationsPass());
+ $container->compile();
$this->assertEquals($container->getParameter('kernel.cache_dir').'/annotations', $container->getDefinition('annotations.filesystem_cache')->getArgument(0));
- $this->assertSame('annotations.filesystem_cache', (string) $container->getDefinition('annotations.cached_reader')->getArgument(1));
+ $this->assertSame('annotations.filesystem_cache', (string) $container->getDefinition('annotation_reader')->getArgument(1));
}
public function testFileLinkFormat()
@@ -1029,10 +1032,10 @@ abstract class FrameworkExtensionTest extends TestCase
), $data)));
}
- protected function createContainerFromFile($file, $data = array(), $resetCompilerPasses = true)
+ protected function createContainerFromFile($file, $data = array(), $resetCompilerPasses = true, $compile = true)
{
$cacheKey = md5(get_class($this).$file.serialize($data));
- if (isset(self::$containerCache[$cacheKey])) {
+ if ($compile && isset(self::$containerCache[$cacheKey])) {
return self::$containerCache[$cacheKey];
}
$container = $this->createContainer($data);
@@ -1043,7 +1046,12 @@ abstract class FrameworkExtensionTest extends TestCase
$container->getCompilerPassConfig()->setOptimizationPasses(array());
$container->getCompilerPassConfig()->setRemovingPasses(array());
}
- $container->getCompilerPassConfig()->setBeforeRemovingPasses(array(new AddAnnotationsCachedReaderPass(), new AddConstraintValidatorsPass(), new TranslatorPass('translator.default', 'translation.reader')));
+ $container->getCompilerPassConfig()->setBeforeRemovingPasses(array(new AddConstraintValidatorsPass(), new TranslatorPass('translator.default', 'translation.reader')));
+ $container->getCompilerPassConfig()->setAfterRemovingPasses(array(new AddAnnotationsCachedReaderPass()));
+
+ if (!$compile) {
+ return $container;
+ }
$container->compile();
return self::$containerCache[$cacheKey] = $container;
@@ -1136,3 +1144,15 @@ abstract class FrameworkExtensionTest extends TestCase
}
}
}
+
+/**
+ * Simulates ReplaceAliasByActualDefinitionPass.
+ */
+class TestAnnotationsPass implements CompilerPassInterface
+{
+ public function process(ContainerBuilder $container)
+ {
+ $container->setDefinition('annotation_reader', $container->getDefinition('annotations.cached_reader'));
+ $container->removeDefinition('annotations.cached_reader');
+ }
+}
diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig
index 903d009c98..a1ff4afd01 100644
--- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig
+++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig
@@ -58,7 +58,7 @@
Route name
- {{ collector.route|default('NONE') }}
+ {{ collector.route|default('n/a') }}
diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/open.css.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/open.css.twig
index d0f5cda02d..f69406475a 100644
--- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/open.css.twig
+++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/open.css.twig
@@ -68,7 +68,7 @@ a.doc:hover {
.anchor {
position: relative;
- display: block;
+ display: inline-block;
top: -7em;
visibility: hidden;
}
diff --git a/src/Symfony/Component/Form/Tests/AbstractBootstrap4HorizontalLayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractBootstrap4HorizontalLayoutTest.php
index 23e6f141ca..5934479a90 100644
--- a/src/Symfony/Component/Form/Tests/AbstractBootstrap4HorizontalLayoutTest.php
+++ b/src/Symfony/Component/Form/Tests/AbstractBootstrap4HorizontalLayoutTest.php
@@ -53,7 +53,7 @@ abstract class AbstractBootstrap4HorizontalLayoutTest extends AbstractBootstrap4
$this->assertMatchesXpath($html,
'/legend
- [@class="col-form-label col-sm-2 col-form-legend required"]
+ [@class="col-form-label col-sm-2 col-form-label required"]
[.="[trans]Name[/trans]"]
'
);
@@ -144,7 +144,7 @@ abstract class AbstractBootstrap4HorizontalLayoutTest extends AbstractBootstrap4
$this->assertMatchesXpath($html,
'/legend
- [@class="col-sm-2 col-form-legend required"]
+ [@class="col-sm-2 col-form-label required"]
[.="[trans]Custom label[/trans]"]
'
);
diff --git a/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php
index fdaa07e1c1..197f3ab8d6 100644
--- a/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php
+++ b/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php
@@ -53,7 +53,7 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
$this->assertMatchesXpath($html,
'/legend
- [@class="col-form-legend required"]
+ [@class="col-form-label required"]
[.="[trans]Name[/trans]"]
'
);
@@ -144,7 +144,7 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
$this->assertMatchesXpath($html,
'/legend
- [@class="col-form-legend required"]
+ [@class="col-form-label required"]
[.="[trans]Custom label[/trans]"]
'
);
@@ -184,12 +184,10 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
'/div
[@class="form-check"]
[
- ./label
- [.=" [trans]Name[/trans]"]
+ ./input[@type="checkbox"][@name="name"][@id="my&id"][@class="my&class form-check-input"][@checked="checked"][@value="1"]
+ /following-sibling::label
+ [.="[trans]Name[/trans]"]
[@class="form-check-label required"]
- [
- ./input[@type="checkbox"][@name="name"][@id="my&id"][@class="my&class form-check-input"][@checked="checked"][@value="1"]
- ]
]
'
);
@@ -234,20 +232,16 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
./div
[@class="form-check"]
[
- ./label
- [.=" [trans]Choice&A[/trans]"]
- [
- ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
- ]
+ ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
+ /following-sibling::label
+ [.="[trans]Choice&A[/trans]"]
]
/following-sibling::div
[@class="form-check"]
[
- ./label
- [.=" [trans]Choice&B[/trans]"]
- [
- ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
- ]
+ ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
+ /following-sibling::label
+ [.="[trans]Choice&B[/trans]"]
]
/following-sibling::input[@type="hidden"][@id="name__token"]
]
@@ -263,11 +257,9 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
'/div
[@class="form-check"]
[
- ./label
- [.=" [trans]Name[/trans]"]
- [
- ./input[@type="checkbox"][@name="name"][@id="my&id"][@class="my&class form-check-input"][not(@checked)]
- ]
+ ./input[@type="checkbox"][@name="name"][@id="my&id"][@class="my&class form-check-input"][not(@checked)]
+ /following-sibling::label
+ [.="[trans]Name[/trans]"]
]
'
);
@@ -283,11 +275,9 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
'/div
[@class="form-check"]
[
- ./label
- [.=" [trans]Name[/trans]"]
- [
- ./input[@type="checkbox"][@name="name"][@id="my&id"][@class="my&class form-check-input"][@value="foo&bar"]
- ]
+ ./input[@type="checkbox"][@name="name"][@id="my&id"][@class="my&class form-check-input"][@value="foo&bar"]
+ /following-sibling::label
+ [.="[trans]Name[/trans]"]
]
'
);
@@ -307,20 +297,16 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
./div
[@class="form-check"]
[
- ./label
- [.=" [trans]Choice&A[/trans]"]
- [
- ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
- ]
+ ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
+ /following-sibling::label
+ [.="[trans]Choice&A[/trans]"]
]
/following-sibling::div
[@class="form-check"]
[
- ./label
- [.=" [trans]Choice&B[/trans]"]
- [
- ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
- ]
+ ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
+ /following-sibling::label
+ [.="[trans]Choice&B[/trans]"]
]
/following-sibling::input[@type="hidden"][@id="name__token"]
]
@@ -343,18 +329,14 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
./div
[@class="form-check"]
[
- ./label
- [
- ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
- ]
+ ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
+ /following-sibling::label
]
/following-sibling::div
[@class="form-check"]
[
- ./label
- [
- ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
- ]
+ ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
+ /following-sibling::label
]
/following-sibling::input[@type="hidden"][@id="name__token"]
]
@@ -383,28 +365,22 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
./div
[@class="form-check"]
[
- ./label
- [.=" [trans]label.&a[/trans]"]
- [
- ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
- ]
+ ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
+ /following-sibling::label
+ [.="[trans]label.&a[/trans]"]
]
/following-sibling::div
[@class="form-check"]
[
- ./label
- [
- ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
- ]
+ ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
+ /following-sibling::label
]
/following-sibling::div
[@class="form-check"]
[
- ./label
- [.=" [trans]label.&c[/trans]"]
- [
- ./input[@type="radio"][@name="name"][@id="name_2"][@value="&c"][not(@checked)]
- ]
+ ./input[@type="radio"][@name="name"][@id="name_2"][@value="&c"][not(@checked)]
+ /following-sibling::label
+ [.="[trans]label.&c[/trans]"]
]
/following-sibling::input[@type="hidden"][@id="name__token"]
]
@@ -429,18 +405,14 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
./div
[@class="form-check"]
[
- ./label
- [
- ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
- ]
+ ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
+ /following-sibling::label
]
/following-sibling::div
[@class="form-check"]
[
- ./label
- [
- ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
- ]
+ ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
+ /following-sibling::label
]
/following-sibling::input[@type="hidden"][@id="name__token"]
]
@@ -463,20 +435,16 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
./div
[@class="form-check"]
[
- ./label
- [.=" Choice&A"]
- [
- ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
- ]
+ ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
+ /following-sibling::label
+ [.="Choice&A"]
]
/following-sibling::div
[@class="form-check"]
[
- ./label
- [.=" Choice&B"]
- [
- ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
- ]
+ ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
+ /following-sibling::label
+ [.="Choice&B"]
]
/following-sibling::input[@type="hidden"][@id="name__token"]
]
@@ -499,20 +467,16 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
./div
[@class="form-check"]
[
- ./label
- [.=" [trans]Choice&A[/trans]"]
- [
- ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
- ]
+ ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
+ /following-sibling::label
+ [.="[trans]Choice&A[/trans]"]
]
/following-sibling::div
[@class="form-check"]
[
- ./label
- [.=" [trans]Choice&B[/trans]"]
- [
- ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)][@class="foo&bar form-check-input"]
- ]
+ ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)][@class="foo&bar form-check-input"]
+ /following-sibling::label
+ [.="[trans]Choice&B[/trans]"]
]
/following-sibling::input[@type="hidden"][@id="name__token"]
]
@@ -536,29 +500,23 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
./div
[@class="form-check"]
[
- ./label
- [.=" [trans]Test&Me[/trans]"]
- [
- ./input[@type="radio"][@name="name"][@id="name_placeholder"][not(@checked)]
- ]
+ ./input[@type="radio"][@name="name"][@id="name_placeholder"][not(@checked)]
+ /following-sibling::label
+ [.="[trans]Test&Me[/trans]"]
]
/following-sibling::div
[@class="form-check"]
[
- ./label
- [.=" [trans]Choice&A[/trans]"]
- [
- ./input[@type="radio"][@name="name"][@id="name_0"][@checked]
- ]
+ ./input[@type="radio"][@name="name"][@id="name_0"][@checked]
+ /following-sibling::label
+ [.="[trans]Choice&A[/trans]"]
]
/following-sibling::div
[@class="form-check"]
[
- ./label
- [.=" [trans]Choice&B[/trans]"]
- [
- ./input[@type="radio"][@name="name"][@id="name_1"][not(@checked)]
- ]
+ ./input[@type="radio"][@name="name"][@id="name_1"][not(@checked)]
+ /following-sibling::label
+ [.="[trans]Choice&B[/trans]"]
]
/following-sibling::input[@type="hidden"][@id="name__token"]
]
@@ -583,29 +541,23 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
./div
[@class="form-check"]
[
- ./label
- [.=" Placeholder&Not&Translated"]
- [
- ./input[@type="radio"][@name="name"][@id="name_placeholder"][not(@checked)]
- ]
+ ./input[@type="radio"][@name="name"][@id="name_placeholder"][not(@checked)]
+ /following-sibling::label
+ [.="Placeholder&Not&Translated"]
+ ]
+ /following-sibling::div
+ [@class="form-check"]
+ [
+ ./input[@type="radio"][@name="name"][@id="name_0"][@checked]
+ /following-sibling::label
+ [.="Choice&A"]
]
/following-sibling::div
[@class="form-check"]
[
- ./label
- [.=" Choice&A"]
- [
- ./input[@type="radio"][@name="name"][@id="name_0"][@checked]
- ]
- ]
- /following-sibling::div
- [@class="form-check"]
- [
- ./label
- [.=" Choice&B"]
- [
- ./input[@type="radio"][@name="name"][@id="name_1"][not(@checked)]
- ]
+ ./input[@type="radio"][@name="name"][@id="name_1"][not(@checked)]
+ /following-sibling::label
+ [.="Choice&B"]
]
/following-sibling::input[@type="hidden"][@id="name__token"]
]
@@ -627,20 +579,16 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
./div
[@class="form-check"]
[
- ./label
- [.=" [trans]Choice&A[/trans]"]
- [
- ./input[@type="radio"][@name="name"][@id="name_0"][@checked]
- ]
+ ./input[@type="radio"][@name="name"][@id="name_0"][@checked]
+ /following-sibling::label
+ [.="[trans]Choice&A[/trans]"]
]
/following-sibling::div
[@class="form-check"]
[
- ./label
- [.=" [trans]Choice&B[/trans]"]
- [
- ./input[@type="radio"][@name="name"][@id="name_1"][not(@checked)]
- ]
+ ./input[@type="radio"][@name="name"][@id="name_1"][not(@checked)]
+ /following-sibling::label
+ [.="[trans]Choice&B[/trans]"]
]
/following-sibling::input[@type="hidden"][@id="name__token"]
]
@@ -663,29 +611,23 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
./div
[@class="form-check"]
[
- ./label
- [.=" [trans]Choice&A[/trans]"]
- [
- ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@checked][not(@required)]
- ]
+ ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@checked][not(@required)]
+ /following-sibling::label
+ [.="[trans]Choice&A[/trans]"]
]
/following-sibling::div
[@class="form-check"]
[
- ./label
- [.=" [trans]Choice&B[/trans]"]
- [
- ./input[@type="checkbox"][@name="name[]"][@id="name_1"][not(@checked)][not(@required)]
- ]
+ ./input[@type="checkbox"][@name="name[]"][@id="name_1"][not(@checked)][not(@required)]
+ /following-sibling::label
+ [.="[trans]Choice&B[/trans]"]
]
/following-sibling::div
[@class="form-check"]
[
- ./label
- [.=" [trans]Choice&C[/trans]"]
- [
- ./input[@type="checkbox"][@name="name[]"][@id="name_2"][@checked][not(@required)]
- ]
+ ./input[@type="checkbox"][@name="name[]"][@id="name_2"][@checked][not(@required)]
+ /following-sibling::label
+ [.="[trans]Choice&C[/trans]"]
]
/following-sibling::input[@type="hidden"][@id="name__token"]
]
@@ -708,18 +650,14 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
./div
[@class="form-check"]
[
- ./label
- [
- ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@value="&a"][@checked]
- ]
+ ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@value="&a"][@checked]
+ /following-sibling::label
]
/following-sibling::div
[@class="form-check"]
[
- ./label
- [
- ./input[@type="checkbox"][@name="name[]"][@id="name_1"][@value="&b"][not(@checked)]
- ]
+ ./input[@type="checkbox"][@name="name[]"][@id="name_1"][@value="&b"][not(@checked)]
+ /following-sibling::label
]
/following-sibling::input[@type="hidden"][@id="name__token"]
]
@@ -748,28 +686,22 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
./div
[@class="form-check"]
[
- ./label
- [.=" [trans]label.&a[/trans]"]
- [
- ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@value="&a"][@checked]
- ]
+ ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@value="&a"][@checked]
+ /following-sibling::label
+ [.="[trans]label.&a[/trans]"]
]
/following-sibling::div
[@class="form-check"]
[
- ./label
- [
- ./input[@type="checkbox"][@name="name[]"][@id="name_1"][@value="&b"][not(@checked)]
- ]
+ ./input[@type="checkbox"][@name="name[]"][@id="name_1"][@value="&b"][not(@checked)]
+ /following-sibling::label
]
/following-sibling::div
[@class="form-check"]
[
- ./label
- [.=" [trans]label.&c[/trans]"]
- [
- ./input[@type="checkbox"][@name="name[]"][@id="name_2"][@value="&c"][not(@checked)]
- ]
+ ./input[@type="checkbox"][@name="name[]"][@id="name_2"][@value="&c"][not(@checked)]
+ /following-sibling::label
+ [.="[trans]label.&c[/trans]"]
]
/following-sibling::input[@type="hidden"][@id="name__token"]
]
@@ -794,18 +726,14 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
./div
[@class="form-check"]
[
- ./label
- [
- ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@value="&a"][@checked]
- ]
+ ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@value="&a"][@checked]
+ /following-sibling::label
]
/following-sibling::div
[@class="form-check"]
[
- ./label
- [
- ./input[@type="checkbox"][@name="name[]"][@id="name_1"][@value="&b"][not(@checked)]
- ]
+ ./input[@type="checkbox"][@name="name[]"][@id="name_1"][@value="&b"][not(@checked)]
+ /following-sibling::label
]
/following-sibling::input[@type="hidden"][@id="name__token"]
]
@@ -829,29 +757,23 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
./div
[@class="form-check"]
[
- ./label
- [.=" Choice&A"]
- [
- ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@checked][not(@required)]
- ]
+ ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@checked][not(@required)]
+ /following-sibling::label
+ [.="Choice&A"]
]
/following-sibling::div
[@class="form-check"]
[
- ./label
- [.=" Choice&B"]
- [
- ./input[@type="checkbox"][@name="name[]"][@id="name_1"][not(@checked)][not(@required)]
- ]
+ ./input[@type="checkbox"][@name="name[]"][@id="name_1"][not(@checked)][not(@required)]
+ /following-sibling::label
+ [.="Choice&B"]
]
/following-sibling::div
[@class="form-check"]
[
- ./label
- [.=" Choice&C"]
- [
- ./input[@type="checkbox"][@name="name[]"][@id="name_2"][@checked][not(@required)]
- ]
+ ./input[@type="checkbox"][@name="name[]"][@id="name_2"][@checked][not(@required)]
+ /following-sibling::label
+ [.="Choice&C"]
]
/following-sibling::input[@type="hidden"][@id="name__token"]
]
@@ -875,29 +797,23 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
./div
[@class="form-check"]
[
- ./label
- [.=" [trans]Choice&A[/trans]"]
- [
- ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@checked][not(@required)]
- ]
+ ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@checked][not(@required)]
+ /following-sibling::label
+ [.="[trans]Choice&A[/trans]"]
]
/following-sibling::div
[@class="form-check"]
[
- ./label
- [.=" [trans]Choice&B[/trans]"]
- [
- ./input[@type="checkbox"][@name="name[]"][@id="name_1"][not(@checked)][not(@required)][@class="foo&bar form-check-input"]
- ]
+ ./input[@type="checkbox"][@name="name[]"][@id="name_1"][not(@checked)][not(@required)][@class="foo&bar form-check-input"]
+ /following-sibling::label
+ [.="[trans]Choice&B[/trans]"]
]
/following-sibling::div
[@class="form-check"]
[
- ./label
- [.=" [trans]Choice&C[/trans]"]
- [
- ./input[@type="checkbox"][@name="name[]"][@id="name_2"][@checked][not(@required)]
- ]
+ ./input[@type="checkbox"][@name="name[]"][@id="name_2"][@checked][not(@required)]
+ /following-sibling::label
+ [.="[trans]Choice&C[/trans]"]
]
/following-sibling::input[@type="hidden"][@id="name__token"]
]
@@ -913,17 +829,15 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
'/div
[@class="form-check"]
[
- ./label
+ ./input
+ [@id="my&id"]
+ [@type="radio"]
+ [@name="name"]
+ [@class="my&class form-check-input"]
+ [@checked="checked"]
+ [@value="1"]
+ /following-sibling::label
[@class="form-check-label required"]
- [
- ./input
- [@id="my&id"]
- [@type="radio"]
- [@name="name"]
- [@class="my&class form-check-input"]
- [@checked="checked"]
- [@value="1"]
- ]
]
'
);
@@ -937,16 +851,14 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
'/div
[@class="form-check"]
[
- ./label
+ ./input
+ [@id="my&id"]
+ [@type="radio"]
+ [@name="name"]
+ [@class="my&class form-check-input"]
+ [not(@checked)]
+ /following-sibling::label
[@class="form-check-label required"]
- [
- ./input
- [@id="my&id"]
- [@type="radio"]
- [@name="name"]
- [@class="my&class form-check-input"]
- [not(@checked)]
- ]
]
'
);
@@ -962,16 +874,15 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
'/div
[@class="form-check"]
[
- ./label
+ ./input
+ [@id="my&id"]
+ [@type="radio"]
+ [@name="name"]
+ [@class="my&class form-check-input"]
+ [@value="foo&bar"]
+ /following-sibling::label
[@class="form-check-label required"]
- [
- ./input
- [@id="my&id"]
- [@type="radio"]
- [@name="name"]
- [@class="my&class form-check-input"]
- [@value="foo&bar"]
- ]
+ [@for="my&id"]
]
'
);
@@ -996,6 +907,61 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
$this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class form-control-file')),
'/input
[@type="file"]
+'
+ );
+ }
+
+ public function testMoney()
+ {
+ $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\MoneyType', 1234.56, array(
+ 'currency' => 'EUR',
+ ));
+
+ $this->assertWidgetMatchesXpath($form->createView(), array('id' => 'my&id', 'attr' => array('class' => 'my&class')),
+ '/div
+ [@class="input-group"]
+ [
+ ./div
+ [@class="input-group-prepend"]
+ [
+ ./span
+ [@class="input-group-text"]
+ [contains(.., "€")]
+ ]
+ /following-sibling::input
+ [@id="my&id"]
+ [@type="text"]
+ [@name="name"]
+ [@class="my&class form-control"]
+ [@value="1234.56"]
+ ]
+'
+ );
+ }
+
+ public function testPercent()
+ {
+ $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\PercentType', 0.1);
+
+ $this->assertWidgetMatchesXpath($form->createView(), array('id' => 'my&id', 'attr' => array('class' => 'my&class')),
+ '/div
+ [@class="input-group"]
+ [
+ ./input
+ [@id="my&id"]
+ [@type="text"]
+ [@name="name"]
+ [@class="my&class form-control"]
+ [@value="10"]
+ /following-sibling::div
+ [@class="input-group-append"]
+ [
+ ./span
+ [@class="input-group-text"]
+ [contains(.., "%")]
+ ]
+
+ ]
'
);
}
diff --git a/src/Symfony/Component/HttpKernel/EventListener/AbstractTestSessionListener.php b/src/Symfony/Component/HttpKernel/EventListener/AbstractTestSessionListener.php
index 5f0ea5c0a9..0a153dd943 100644
--- a/src/Symfony/Component/HttpKernel/EventListener/AbstractTestSessionListener.php
+++ b/src/Symfony/Component/HttpKernel/EventListener/AbstractTestSessionListener.php
@@ -29,6 +29,8 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
*/
abstract class AbstractTestSessionListener implements EventSubscriberInterface
{
+ private $sessionId;
+
public function onKernelRequest(GetResponseEvent $event)
{
if (!$event->isMasterRequest()) {
@@ -44,7 +46,8 @@ abstract class AbstractTestSessionListener implements EventSubscriberInterface
$cookies = $event->getRequest()->cookies;
if ($cookies->has($session->getName())) {
- $session->setId($cookies->get($session->getName()));
+ $this->sessionId = $cookies->get($session->getName());
+ $session->setId($this->sessionId);
}
}
@@ -66,9 +69,10 @@ abstract class AbstractTestSessionListener implements EventSubscriberInterface
$session->save();
}
- if ($session instanceof Session ? !$session->isEmpty() : $wasStarted) {
+ if ($session instanceof Session ? !$session->isEmpty() || $session->getId() !== $this->sessionId : $wasStarted) {
$params = session_get_cookie_params();
$event->getResponse()->headers->setCookie(new Cookie($session->getName(), $session->getId(), 0 === $params['lifetime'] ? 0 : time() + $params['lifetime'], $params['path'], $params['domain'], $params['secure'], $params['httponly']));
+ $this->sessionId = $session->getId();
}
}
diff --git a/src/Symfony/Component/HttpKernel/Tests/EventListener/TestSessionListenerTest.php b/src/Symfony/Component/HttpKernel/Tests/EventListener/TestSessionListenerTest.php
index 4452f48771..0a2263d5a8 100644
--- a/src/Symfony/Component/HttpKernel/Tests/EventListener/TestSessionListenerTest.php
+++ b/src/Symfony/Component/HttpKernel/Tests/EventListener/TestSessionListenerTest.php
@@ -13,8 +13,10 @@ namespace Symfony\Component\HttpKernel\Tests\EventListener;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ServiceSubscriberInterface;
+use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\EventListener\SessionListener;
@@ -86,6 +88,22 @@ class TestSessionListenerTest extends TestCase
$this->assertSame(array(), $response->headers->getCookies());
}
+ public function testEmptySessionWithNewSessionIdDoesSendCookie()
+ {
+ $this->sessionHasBeenStarted();
+ $this->sessionIsEmpty();
+ $this->fixSessionId('456');
+
+ $kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
+ $request = Request::create('/', 'GET', array(), array(new Cookie('MOCKSESSID', '123')));
+ $event = new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
+ $this->listener->onKernelRequest($event);
+
+ $response = $this->filterResponse(new Request(), HttpKernelInterface::MASTER_REQUEST);
+
+ $this->assertNotEmpty($response->headers->getCookies());
+ }
+
public function testUnstartedSessionIsNotSave()
{
$this->sessionHasNotBeenStarted();
@@ -150,6 +168,13 @@ class TestSessionListenerTest extends TestCase
->will($this->returnValue(true));
}
+ private function fixSessionId($sessionId)
+ {
+ $this->session->expects($this->any())
+ ->method('getId')
+ ->will($this->returnValue($sessionId));
+ }
+
private function getSession()
{
$mock = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\Session')
diff --git a/src/Symfony/Component/Stopwatch/StopwatchEvent.php b/src/Symfony/Component/Stopwatch/StopwatchEvent.php
index 410f935a26..de1259a9f1 100644
--- a/src/Symfony/Component/Stopwatch/StopwatchEvent.php
+++ b/src/Symfony/Component/Stopwatch/StopwatchEvent.php
@@ -150,7 +150,7 @@ class StopwatchEvent
/**
* Gets the relative time of the start of the first period.
*
- * @return int The time (in milliseconds)
+ * @return int|float The time (in milliseconds)
*/
public function getStartTime()
{
@@ -160,7 +160,7 @@ class StopwatchEvent
/**
* Gets the relative time of the end of the last period.
*
- * @return int The time (in milliseconds)
+ * @return int|float The time (in milliseconds)
*/
public function getEndTime()
{
@@ -172,7 +172,7 @@ class StopwatchEvent
/**
* Gets the duration of the events (including all periods).
*
- * @return int The duration (in milliseconds)
+ * @return int|float The duration (in milliseconds)
*/
public function getDuration()
{
diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php
index 195d3185e4..6c4e55925e 100644
--- a/src/Symfony/Component/Yaml/Parser.php
+++ b/src/Symfony/Component/Yaml/Parser.php
@@ -372,54 +372,39 @@ class Parser
// try to parse the value as a multi-line string as a last resort
if (0 === $this->currentLineNb) {
- $parseError = false;
$previousLineWasNewline = false;
$previousLineWasTerminatedWithBackslash = false;
$value = '';
foreach ($this->lines as $line) {
- try {
- if (isset($line[0]) && ('"' === $line[0] || "'" === $line[0])) {
- $parsedLine = $line;
- } else {
- $parsedLine = Inline::parse($line, $flags, $this->refs);
- }
+ if ('' === trim($line)) {
+ $value .= "\n";
+ } elseif (!$previousLineWasNewline && !$previousLineWasTerminatedWithBackslash) {
+ $value .= ' ';
+ }
- if (!is_string($parsedLine)) {
- $parseError = true;
- break;
- }
+ if ('' !== trim($line) && '\\' === substr($line, -1)) {
+ $value .= ltrim(substr($line, 0, -1));
+ } elseif ('' !== trim($line)) {
+ $value .= trim($line);
+ }
- if ('' === trim($parsedLine)) {
- $value .= "\n";
- } elseif (!$previousLineWasNewline && !$previousLineWasTerminatedWithBackslash) {
- $value .= ' ';
- }
-
- if ('' !== trim($parsedLine) && '\\' === substr($parsedLine, -1)) {
- $value .= ltrim(substr($parsedLine, 0, -1));
- } elseif ('' !== trim($parsedLine)) {
- $value .= trim($parsedLine);
- }
-
- if ('' === trim($parsedLine)) {
- $previousLineWasNewline = true;
- $previousLineWasTerminatedWithBackslash = false;
- } elseif ('\\' === substr($parsedLine, -1)) {
- $previousLineWasNewline = false;
- $previousLineWasTerminatedWithBackslash = true;
- } else {
- $previousLineWasNewline = false;
- $previousLineWasTerminatedWithBackslash = false;
- }
- } catch (ParseException $e) {
- $parseError = true;
- break;
+ if ('' === trim($line)) {
+ $previousLineWasNewline = true;
+ $previousLineWasTerminatedWithBackslash = false;
+ } elseif ('\\' === substr($line, -1)) {
+ $previousLineWasNewline = false;
+ $previousLineWasTerminatedWithBackslash = true;
+ } else {
+ $previousLineWasNewline = false;
+ $previousLineWasTerminatedWithBackslash = false;
}
}
- if (!$parseError) {
+ try {
return Inline::parse(trim($value));
+ } catch (ParseException $e) {
+ // fall-through to the ParseException thrown below
}
}
diff --git a/src/Symfony/Component/Yaml/Tests/ParserTest.php b/src/Symfony/Component/Yaml/Tests/ParserTest.php
index fe3f079860..cd9085a76e 100644
--- a/src/Symfony/Component/Yaml/Tests/ParserTest.php
+++ b/src/Symfony/Component/Yaml/Tests/ParserTest.php
@@ -672,6 +672,42 @@ EOT;
$this->assertSame($expected, $this->parser->parse($yaml));
}
+ public function testNonStringFollowedByCommentEmbeddedInMapping()
+ {
+ $yaml = <<<'EOT'
+a:
+ b:
+ {}
+# comment
+ d:
+ 1.1
+# another comment
+EOT;
+ $expected = array(
+ 'a' => array(
+ 'b' => array(),
+ 'd' => 1.1,
+ ),
+ );
+
+ $this->assertSame($expected, $this->parser->parse($yaml));
+ }
+
+ public function testMultiLineStringLastResortParsing()
+ {
+ $yaml = <<<'EOT'
+test:
+ You can have things that don't look like strings here
+ true
+ yes you can
+EOT;
+ $expected = array(
+ 'test' => 'You can have things that don\'t look like strings here true yes you can',
+ );
+
+ $this->assertSame($expected, $this->parser->parse($yaml));
+ }
+
/**
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
*/