diff --git a/AbstractType.php b/AbstractType.php index 8fffa379d..485d0b2e3 100644 --- a/AbstractType.php +++ b/AbstractType.php @@ -16,6 +16,10 @@ use Symfony\Component\OptionsResolver\OptionsResolver; /** + * @template T + * + * @implements FormTypeInterface + * * @author Bernhard Schussek */ abstract class AbstractType implements FormTypeInterface @@ -36,6 +40,8 @@ public function configureOptions(OptionsResolver $resolver) } /** + * @param FormBuilderInterface $builder + * * @return void */ public function buildForm(FormBuilderInterface $builder, array $options) @@ -43,6 +49,9 @@ public function buildForm(FormBuilderInterface $builder, array $options) } /** + * @param FormView $form + * @param FormInterface $view + * * @return void */ public function buildView(FormView $view, FormInterface $form, array $options) @@ -50,6 +59,9 @@ public function buildView(FormView $view, FormInterface $form, array $options) } /** + * @param FormView $form + * @param FormInterface $view + * * @return void */ public function finishView(FormView $view, FormInterface $form, array $options) diff --git a/AbstractTypeExtension.php b/AbstractTypeExtension.php index b32f3b522..acf1342f0 100644 --- a/AbstractTypeExtension.php +++ b/AbstractTypeExtension.php @@ -14,6 +14,10 @@ use Symfony\Component\OptionsResolver\OptionsResolver; /** + * @template T + * + * @implements FormTypeExtensionInterface + * * @author Bernhard Schussek */ abstract class AbstractTypeExtension implements FormTypeExtensionInterface @@ -22,14 +26,25 @@ public function configureOptions(OptionsResolver $resolver): void { } + /** + * @param FormBuilderInterface $builder + */ public function buildForm(FormBuilderInterface $builder, array $options): void { } + /** + * @param FormView $form + * @param FormInterface $view + */ public function buildView(FormView $view, FormInterface $form, array $options): void { } + /** + * @param FormView $form + * @param FormInterface $view + */ public function finishView(FormView $view, FormInterface $form, array $options): void { } diff --git a/CHANGELOG.md b/CHANGELOG.md index 00d3b2fc4..f6ef659e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ CHANGELOG ========= +7.4 +--- + + * Add `input=date_point` to `DateTimeType`, `DateType` and `TimeType` + * Add support for guessing form type of enum properties + 7.3 --- diff --git a/Command/DebugCommand.php b/Command/DebugCommand.php index 91db6f1a9..20146f02c 100644 --- a/Command/DebugCommand.php +++ b/Command/DebugCommand.php @@ -56,33 +56,33 @@ protected function configure(): void new InputOption('format', null, InputOption::VALUE_REQUIRED, \sprintf('The output format ("%s")', implode('", "', $this->getAvailableFormatOptions())), 'txt'), ]) ->setHelp(<<<'EOF' -The %command.name% command displays information about form types. + The %command.name% command displays information about form types. - php %command.full_name% + php %command.full_name% -The command lists all built-in types, services types, type extensions and -guessers currently available. + The command lists all built-in types, services types, type extensions and + guessers currently available. - php %command.full_name% Symfony\Component\Form\Extension\Core\Type\ChoiceType - php %command.full_name% ChoiceType + php %command.full_name% Symfony\Component\Form\Extension\Core\Type\ChoiceType + php %command.full_name% ChoiceType -The command lists all defined options that contains the given form type, -as well as their parents and type extensions. + The command lists all defined options that contains the given form type, + as well as their parents and type extensions. - php %command.full_name% ChoiceType choice_value + php %command.full_name% ChoiceType choice_value -Use the --show-deprecated option to display form types with -deprecated options or the deprecated options of the given form type: + Use the --show-deprecated option to display form types with + deprecated options or the deprecated options of the given form type: - php %command.full_name% --show-deprecated - php %command.full_name% ChoiceType --show-deprecated + php %command.full_name% --show-deprecated + php %command.full_name% ChoiceType --show-deprecated -The command displays the definition of the given option name. + The command displays the definition of the given option name. - php %command.full_name% --format=json + php %command.full_name% --format=json -The command lists everything in a machine readable json format. -EOF + The command lists everything in a machine readable json format. + EOF ) ; } diff --git a/DependencyInjection/FormPass.php b/DependencyInjection/FormPass.php index bec1782d4..812a8b98f 100644 --- a/DependencyInjection/FormPass.php +++ b/DependencyInjection/FormPass.php @@ -54,7 +54,7 @@ private function processFormTypes(ContainerBuilder $container): Reference // Add form type service to the service locator $serviceDefinition = $container->getDefinition($serviceId); $servicesMap[$formType = $serviceDefinition->getClass()] = new Reference($serviceId); - $namespaces[substr($formType, 0, strrpos($formType, '\\'))] = true; + $namespaces[substr($formType, 0, strrpos($formType, '\\') ?: \strlen($formType))] = true; if (isset($tag[0]['csrf_token_id'])) { $csrfTokenIds[$formType] = $tag[0]['csrf_token_id']; diff --git a/EnumFormTypeGuesser.php b/EnumFormTypeGuesser.php new file mode 100644 index 000000000..79c3b8abb --- /dev/null +++ b/EnumFormTypeGuesser.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form; + +use Symfony\Component\Form\Extension\Core\Type\EnumType; +use Symfony\Component\Form\Guess\Guess; +use Symfony\Component\Form\Guess\TypeGuess; +use Symfony\Component\Form\Guess\ValueGuess; + +final class EnumFormTypeGuesser implements FormTypeGuesserInterface +{ + /** + * @var array> + */ + private array $cache = []; + + public function guessType(string $class, string $property): ?TypeGuess + { + if (!($enum = $this->getPropertyType($class, $property))) { + return null; + } + + return new TypeGuess(EnumType::class, ['class' => ltrim($enum, '?')], Guess::HIGH_CONFIDENCE); + } + + public function guessRequired(string $class, string $property): ?ValueGuess + { + if (!($enum = $this->getPropertyType($class, $property))) { + return null; + } + + return new ValueGuess('?' !== $enum[0], Guess::HIGH_CONFIDENCE); + } + + public function guessMaxLength(string $class, string $property): ?ValueGuess + { + return null; + } + + public function guessPattern(string $class, string $property): ?ValueGuess + { + return null; + } + + private function getPropertyType(string $class, string $property): string|false + { + if (isset($this->cache[$class][$property])) { + return $this->cache[$class][$property]; + } + + try { + $propertyReflection = new \ReflectionProperty($class, $property); + } catch (\ReflectionException) { + return $this->cache[$class][$property] = false; + } + + $type = $propertyReflection->getType(); + if (!$type instanceof \ReflectionNamedType || !enum_exists($type->getName())) { + $enum = false; + } else { + $enum = $type->getName(); + if ($type->allowsNull()) { + $enum = '?'.$enum; + } + } + + return $this->cache[$class][$property] = $enum; + } +} diff --git a/Event/PostSetDataEvent.php b/Event/PostSetDataEvent.php index 5b6430a81..a78cff092 100644 --- a/Event/PostSetDataEvent.php +++ b/Event/PostSetDataEvent.php @@ -19,6 +19,10 @@ * * It can be used to modify a form depending on the populated data (adding or * removing fields dynamically). + * + * @template T + * + * @extends FormEvent */ final class PostSetDataEvent extends FormEvent { diff --git a/Event/PostSubmitEvent.php b/Event/PostSubmitEvent.php index 88cd5c4eb..137cf23d2 100644 --- a/Event/PostSubmitEvent.php +++ b/Event/PostSubmitEvent.php @@ -19,6 +19,10 @@ * once the model and view data have been denormalized. * * It can be used to fetch data after denormalization. + * + * @template T + * + * @extends FormEvent */ final class PostSubmitEvent extends FormEvent { diff --git a/Event/PreSetDataEvent.php b/Event/PreSetDataEvent.php index 2644fda19..aedd7835e 100644 --- a/Event/PreSetDataEvent.php +++ b/Event/PreSetDataEvent.php @@ -17,6 +17,10 @@ * This event is dispatched at the beginning of the Form::setData() method. * * It can be used to modify the data given during pre-population. + * + * @template T + * + * @extends FormEvent */ final class PreSetDataEvent extends FormEvent { diff --git a/Event/PreSubmitEvent.php b/Event/PreSubmitEvent.php index a72ac5d16..aa5856daa 100644 --- a/Event/PreSubmitEvent.php +++ b/Event/PreSubmitEvent.php @@ -19,6 +19,8 @@ * It can be used to: * - Change data from the request, before submitting the data to the form. * - Add or remove form fields, before submitting the data to the form. + * + * @extends FormEvent> */ final class PreSubmitEvent extends FormEvent { diff --git a/Event/SubmitEvent.php b/Event/SubmitEvent.php index 71d3b06d4..b49ebd7d2 100644 --- a/Event/SubmitEvent.php +++ b/Event/SubmitEvent.php @@ -18,6 +18,10 @@ * transforms back the normalized data to the model and view data. * * It can be used to change data from the normalized representation of the data. + * + * @template T + * + * @extends FormEvent */ final class SubmitEvent extends FormEvent { diff --git a/Extension/Core/DataTransformer/DatePointToDateTimeTransformer.php b/Extension/Core/DataTransformer/DatePointToDateTimeTransformer.php new file mode 100644 index 000000000..dc1f75068 --- /dev/null +++ b/Extension/Core/DataTransformer/DatePointToDateTimeTransformer.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Extension\Core\DataTransformer; + +use Symfony\Component\Clock\DatePoint; +use Symfony\Component\Form\DataTransformerInterface; +use Symfony\Component\Form\Exception\TransformationFailedException; + +/** + * Transforms between a DatePoint object and a DateTime object. + * + * @implements DataTransformerInterface + */ +final class DatePointToDateTimeTransformer implements DataTransformerInterface +{ + /** + * Transforms a DatePoint into a DateTime object. + * + * @param DatePoint|null $value A DatePoint object + * + * @throws TransformationFailedException If the given value is not a DatePoint + */ + public function transform(mixed $value): ?\DateTime + { + if (null === $value) { + return null; + } + + if (!$value instanceof DatePoint) { + throw new TransformationFailedException(\sprintf('Expected a "%s".', DatePoint::class)); + } + + return \DateTime::createFromImmutable($value); + } + + /** + * Transforms a DateTime object into a DatePoint object. + * + * @param \DateTime|null $value A DateTime object + * + * @throws TransformationFailedException If the given value is not a \DateTime + */ + public function reverseTransform(mixed $value): ?DatePoint + { + if (null === $value) { + return null; + } + + if (!$value instanceof \DateTime) { + throw new TransformationFailedException('Expected a \DateTime.'); + } + + return DatePoint::createFromMutable($value); + } +} diff --git a/Extension/Core/Type/ChoiceType.php b/Extension/Core/Type/ChoiceType.php index fc083ee40..5c5503a83 100644 --- a/Extension/Core/Type/ChoiceType.php +++ b/Extension/Core/Type/ChoiceType.php @@ -100,8 +100,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void if ($options['expanded'] || $options['multiple']) { // Make sure that scalar, submitted values are converted to arrays // which can be submitted to the checkboxes/radio buttons - $builder->addEventListener(FormEvents::PRE_SUBMIT, static function (FormEvent $event) use ($choiceList, $options, &$unknownValues) { - /** @var PreSubmitEvent $event */ + $builder->addEventListener(FormEvents::PRE_SUBMIT, static function (PreSubmitEvent $event) use ($choiceList, $options, &$unknownValues) { $form = $event->getForm(); $data = $event->getData(); diff --git a/Extension/Core/Type/DateTimeType.php b/Extension/Core/Type/DateTimeType.php index cf4c2b741..8ecaa63c0 100644 --- a/Extension/Core/Type/DateTimeType.php +++ b/Extension/Core/Type/DateTimeType.php @@ -11,10 +11,12 @@ namespace Symfony\Component\Form\Extension\Core\Type; +use Symfony\Component\Clock\DatePoint; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Exception\LogicException; use Symfony\Component\Form\Extension\Core\DataTransformer\ArrayToPartsTransformer; use Symfony\Component\Form\Extension\Core\DataTransformer\DataTransformerChain; +use Symfony\Component\Form\Extension\Core\DataTransformer\DatePointToDateTimeTransformer; use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeImmutableToDateTimeTransformer; use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToArrayTransformer; use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToHtml5LocalDateTimeTransformer; @@ -178,7 +180,12 @@ public function buildForm(FormBuilderInterface $builder, array $options): void ; } - if ('datetime_immutable' === $options['input']) { + if ('date_point' === $options['input']) { + if (!class_exists(DatePoint::class)) { + throw new LogicException(\sprintf('The "symfony/clock" component is required to use "%s" with option "input=date_point". Try running "composer require symfony/clock".', self::class)); + } + $builder->addModelTransformer(new DatePointToDateTimeTransformer()); + } elseif ('datetime_immutable' === $options['input']) { $builder->addModelTransformer(new DateTimeImmutableToDateTimeTransformer()); } elseif ('string' === $options['input']) { $builder->addModelTransformer(new ReversedTransformer( @@ -194,7 +201,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void )); } - if (\in_array($options['input'], ['datetime', 'datetime_immutable'], true) && null !== $options['model_timezone']) { + if (\in_array($options['input'], ['datetime', 'datetime_immutable', 'date_point'], true) && null !== $options['model_timezone']) { $builder->addEventListener(FormEvents::POST_SET_DATA, static function (FormEvent $event) use ($options): void { $date = $event->getData(); @@ -283,6 +290,7 @@ public function configureOptions(OptionsResolver $resolver): void $resolver->setAllowedValues('input', [ 'datetime', 'datetime_immutable', + 'date_point', 'string', 'timestamp', 'array', diff --git a/Extension/Core/Type/DateType.php b/Extension/Core/Type/DateType.php index 36b430e14..5c8dfaa3c 100644 --- a/Extension/Core/Type/DateType.php +++ b/Extension/Core/Type/DateType.php @@ -11,8 +11,10 @@ namespace Symfony\Component\Form\Extension\Core\Type; +use Symfony\Component\Clock\DatePoint; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Exception\LogicException; +use Symfony\Component\Form\Extension\Core\DataTransformer\DatePointToDateTimeTransformer; use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeImmutableToDateTimeTransformer; use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToArrayTransformer; use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToLocalizedStringTransformer; @@ -156,7 +158,12 @@ public function buildForm(FormBuilderInterface $builder, array $options): void ; } - if ('datetime_immutable' === $options['input']) { + if ('date_point' === $options['input']) { + if (!class_exists(DatePoint::class)) { + throw new LogicException(\sprintf('The "symfony/clock" component is required to use "%s" with option "input=date_point". Try running "composer require symfony/clock".', self::class)); + } + $builder->addModelTransformer(new DatePointToDateTimeTransformer()); + } elseif ('datetime_immutable' === $options['input']) { $builder->addModelTransformer(new DateTimeImmutableToDateTimeTransformer()); } elseif ('string' === $options['input']) { $builder->addModelTransformer(new ReversedTransformer( @@ -172,7 +179,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void )); } - if (\in_array($options['input'], ['datetime', 'datetime_immutable'], true) && null !== $options['model_timezone']) { + if (\in_array($options['input'], ['datetime', 'datetime_immutable', 'date_point'], true) && null !== $options['model_timezone']) { $builder->addEventListener(FormEvents::POST_SET_DATA, static function (FormEvent $event) use ($options): void { $date = $event->getData(); @@ -298,6 +305,7 @@ public function configureOptions(OptionsResolver $resolver): void $resolver->setAllowedValues('input', [ 'datetime', 'datetime_immutable', + 'date_point', 'string', 'timestamp', 'array', diff --git a/Extension/Core/Type/TimeType.php b/Extension/Core/Type/TimeType.php index 92cf42d96..1622301ae 100644 --- a/Extension/Core/Type/TimeType.php +++ b/Extension/Core/Type/TimeType.php @@ -11,9 +11,11 @@ namespace Symfony\Component\Form\Extension\Core\Type; +use Symfony\Component\Clock\DatePoint; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Exception\InvalidConfigurationException; use Symfony\Component\Form\Exception\LogicException; +use Symfony\Component\Form\Extension\Core\DataTransformer\DatePointToDateTimeTransformer; use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeImmutableToDateTimeTransformer; use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToArrayTransformer; use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToStringTransformer; @@ -190,7 +192,12 @@ public function buildForm(FormBuilderInterface $builder, array $options): void $builder->addViewTransformer(new DateTimeToArrayTransformer($options['model_timezone'], $options['view_timezone'], $parts, 'text' === $options['widget'], $options['reference_date'])); } - if ('datetime_immutable' === $options['input']) { + if ('date_point' === $options['input']) { + if (!class_exists(DatePoint::class)) { + throw new LogicException(\sprintf('The "symfony/clock" component is required to use "%s" with option "input=date_point". Try running "composer require symfony/clock".', self::class)); + } + $builder->addModelTransformer(new DatePointToDateTimeTransformer()); + } elseif ('datetime_immutable' === $options['input']) { $builder->addModelTransformer(new DateTimeImmutableToDateTimeTransformer()); } elseif ('string' === $options['input']) { $builder->addModelTransformer(new ReversedTransformer( @@ -206,7 +213,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void )); } - if (\in_array($options['input'], ['datetime', 'datetime_immutable'], true) && null !== $options['model_timezone']) { + if (\in_array($options['input'], ['datetime', 'datetime_immutable', 'date_point'], true) && null !== $options['model_timezone']) { $builder->addEventListener(FormEvents::POST_SET_DATA, static function (FormEvent $event) use ($options): void { $date = $event->getData(); @@ -354,6 +361,7 @@ public function configureOptions(OptionsResolver $resolver): void $resolver->setAllowedValues('input', [ 'datetime', 'datetime_immutable', + 'date_point', 'string', 'timestamp', 'array', diff --git a/Extension/DataCollector/FormDataCollector.php b/Extension/DataCollector/FormDataCollector.php index e6cae863e..7ed4e06db 100644 --- a/Extension/DataCollector/FormDataCollector.php +++ b/Extension/DataCollector/FormDataCollector.php @@ -200,7 +200,7 @@ public function getData(): array|Data /** * @internal */ - public function __sleep(): array + public function __serialize(): array { foreach ($this->data['forms_by_hash'] as &$form) { if (isset($form['type_class']) && !$form['type_class'] instanceof ClassStub) { @@ -208,9 +208,7 @@ public function __sleep(): array } } - $this->data = $this->cloneVar($this->data); - - return parent::__sleep(); + return ['data' => $this->data = $this->cloneVar($this->data)]; } protected function getCasters(): array diff --git a/Extension/Validator/Constraints/Form.php b/Extension/Validator/Constraints/Form.php index 8be25c0b8..6c45090b0 100644 --- a/Extension/Validator/Constraints/Form.php +++ b/Extension/Validator/Constraints/Form.php @@ -11,11 +11,13 @@ namespace Symfony\Component\Form\Extension\Validator\Constraints; +use Symfony\Component\Validator\Attribute\HasNamedArguments; use Symfony\Component\Validator\Constraint; /** * @author Bernhard Schussek */ +#[\Attribute(\Attribute::TARGET_CLASS)] class Form extends Constraint { public const NOT_SYNCHRONIZED_ERROR = '1dafa156-89e1-4736-b832-419c2e501fca'; @@ -26,6 +28,12 @@ class Form extends Constraint self::NO_SUCH_FIELD_ERROR => 'NO_SUCH_FIELD_ERROR', ]; + #[HasNamedArguments] + public function __construct(mixed $options = null, ?array $groups = null, mixed $payload = null) + { + parent::__construct($options, $groups, $payload); + } + public function getTargets(): string|array { return self::CLASS_CONSTRAINT; diff --git a/Extension/Validator/ValidatorTypeGuesser.php b/Extension/Validator/ValidatorTypeGuesser.php index 08dc6e2d5..cb153d88a 100644 --- a/Extension/Validator/ValidatorTypeGuesser.php +++ b/Extension/Validator/ValidatorTypeGuesser.php @@ -207,7 +207,7 @@ public function guessMaxLengthForConstraint(Constraint $constraint): ?ValueGuess break; case Type::class: - if (\in_array($constraint->type, ['double', 'float', 'numeric', 'real'])) { + if (\in_array($constraint->type, ['double', 'float', 'numeric', 'real'], true)) { return new ValueGuess(null, Guess::MEDIUM_CONFIDENCE); } break; @@ -249,7 +249,7 @@ public function guessPatternForConstraint(Constraint $constraint): ?ValueGuess break; case Type::class: - if (\in_array($constraint->type, ['double', 'float', 'numeric', 'real'])) { + if (\in_array($constraint->type, ['double', 'float', 'numeric', 'real'], true)) { return new ValueGuess(null, Guess::MEDIUM_CONFIDENCE); } break; diff --git a/Extension/Validator/ViolationMapper/ViolationMapper.php b/Extension/Validator/ViolationMapper/ViolationMapper.php index c6ef92bf3..981865b2b 100644 --- a/Extension/Validator/ViolationMapper/ViolationMapper.php +++ b/Extension/Validator/ViolationMapper/ViolationMapper.php @@ -228,6 +228,7 @@ private function matchChild(FormInterface $form, PropertyPathIteratorInterface $ $foundAtIndex = null; // Construct mapping rules for the given form + /** @var MappingRule[] $rules */ $rules = []; foreach ($form->getConfig()->getOption('error_mapping') as $propertyPath => $targetPath) { @@ -237,6 +238,7 @@ private function matchChild(FormInterface $form, PropertyPathIteratorInterface $ } } + /** @var FormInterface[] $children */ $children = iterator_to_array(new \RecursiveIteratorIterator(new InheritDataAwareIterator($form)), false); while ($it->valid()) { @@ -248,8 +250,6 @@ private function matchChild(FormInterface $form, PropertyPathIteratorInterface $ // Test mapping rules as long as we have any foreach ($rules as $key => $rule) { - /** @var MappingRule $rule */ - // Mapping rule matches completely, terminate. if (null !== ($form = $rule->match($chunk))) { return $form; @@ -261,7 +261,6 @@ private function matchChild(FormInterface $form, PropertyPathIteratorInterface $ } } - /** @var FormInterface $child */ foreach ($children as $i => $child) { $childPath = (string) $child->getPropertyPath(); if ($childPath === $chunk) { @@ -312,7 +311,6 @@ private function reconstructPath(ViolationPath $violationPath, FormInterface $or // Cut the piece out of the property path and proceed $propertyPathBuilder->remove($i); } else { - /** @var \Symfony\Component\PropertyAccess\PropertyPathInterface $propertyPath */ $propertyPath = $scope->getPropertyPath(); if (null === $propertyPath) { diff --git a/Form.php b/Form.php index 72c60ee41..dc85f52d1 100644 --- a/Form.php +++ b/Form.php @@ -22,11 +22,13 @@ use Symfony\Component\Form\Exception\RuntimeException; use Symfony\Component\Form\Exception\TransformationFailedException; use Symfony\Component\Form\Extension\Core\Type\TextType; +use Symfony\Component\Form\Extension\Validator\Constraints\Form as AssertForm; use Symfony\Component\Form\Util\FormUtil; use Symfony\Component\Form\Util\InheritDataAwareIterator; use Symfony\Component\Form\Util\OrderedHashMap; use Symfony\Component\PropertyAccess\PropertyPath; use Symfony\Component\PropertyAccess\PropertyPathInterface; +use Symfony\Component\Validator\Constraints\Traverse; /** * Form represents a form. @@ -66,8 +68,13 @@ * @author Fabien Potencier * @author Bernhard Schussek * + * @template T + * * @implements \IteratorAggregate + * @implements FormInterface */ +#[AssertForm] +#[Traverse(false)] class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterface { private ?FormInterface $parent = null; @@ -301,7 +308,7 @@ public function setData(mixed $modelData): static if (null !== $dataClass && !$viewData instanceof $dataClass) { $actualType = get_debug_type($viewData); - throw new LogicException('The form\'s view data is expected to be a "'.$dataClass.'", but it is a "'.$actualType.'". You can avoid this error by setting the "data_class" option to null or by adding a view transformer that transforms "'.$actualType.'" to an instance of "'.$dataClass.'".'); + throw new LogicException(\sprintf('The form\'s view data is expected to be a "%s", but it is a "%s". You can avoid this error by setting the "data_class" option to null or by adding a view transformer that transforms "%2$s" to an instance of "%1$s".', $dataClass, $actualType)); } } diff --git a/FormBuilderInterface.php b/FormBuilderInterface.php index 08d29303c..0510d01ba 100644 --- a/FormBuilderInterface.php +++ b/FormBuilderInterface.php @@ -14,6 +14,9 @@ /** * @author Bernhard Schussek * + * @template T + * + * @extends FormConfigBuilderInterface * @extends \Traversable */ interface FormBuilderInterface extends \Traversable, \Countable, FormConfigBuilderInterface @@ -32,9 +35,9 @@ public function add(string|self $child, ?string $type = null, array $options = [ /** * Creates a form builder. * - * @param string $name The name of the form or the name of the property - * @param string|null $type The type of the form or null if name is a property - * @param array $options + * @param string $name The name of the form or the name of the property + * @param class-string|null $type The type of the form or null if name is a property + * @param array $options */ public function create(string $name, ?string $type = null, array $options = []): self; @@ -64,6 +67,8 @@ public function all(): array; /** * Creates the form. + * + * @return FormInterface */ public function getForm(): FormInterface; } diff --git a/FormConfigBuilderInterface.php b/FormConfigBuilderInterface.php index 6b22b9f9e..d8679ab22 100644 --- a/FormConfigBuilderInterface.php +++ b/FormConfigBuilderInterface.php @@ -13,8 +13,17 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\PropertyAccess\PropertyPathInterface; +use Symfony\Component\Form\Event\PreSetDataEvent; +use Symfony\Component\Form\Event\PreSubmitEvent; +use Symfony\Component\Form\Event\PostSetDataEvent; +use Symfony\Component\Form\Event\SubmitEvent; +use Symfony\Component\Form\Event\PostSubmitEvent; /** + * @template T + * + * @extends FormConfigInterface + * * @author Bernhard Schussek */ interface FormConfigBuilderInterface extends FormConfigInterface @@ -22,6 +31,8 @@ interface FormConfigBuilderInterface extends FormConfigInterface /** * Adds an event listener to an event on this form. * + * @param FormEvents::* $eventName + * @param (callable(PreSetDataEvent): void)|(callable(PostSetDataEvent): void)|(callable(PreSubmitEvent): void)|(callable(SubmitEvent): void)|(callable(PostSubmitEvent): void) $listener * @param int $priority The priority of the listener. Listeners * with a higher priority are called before * listeners with a lower priority. @@ -247,6 +258,8 @@ public function setAutoInitialize(bool $initialize): static; /** * Builds and returns the form configuration. + * + * @return FormConfigInterface */ public function getFormConfig(): FormConfigInterface; diff --git a/FormConfigInterface.php b/FormConfigInterface.php index 93d1998ec..a1a035206 100644 --- a/FormConfigInterface.php +++ b/FormConfigInterface.php @@ -17,6 +17,8 @@ /** * The configuration of a {@link Form} object. * + * @template T + * * @author Bernhard Schussek */ interface FormConfigInterface @@ -130,6 +132,8 @@ public function getAttribute(string $name, mixed $default = null): mixed; /** * Returns the initial data of the form. + * + * @return T|null */ public function getData(): mixed; diff --git a/FormError.php b/FormError.php index 335d9e21d..29c9764e5 100644 --- a/FormError.php +++ b/FormError.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Form; use Symfony\Component\Form\Exception\BadMethodCallException; +use Symfony\Component\Translation\Translator; /** * Wraps errors in forms. @@ -38,7 +39,7 @@ class FormError * @param int|null $messagePluralization The value for error message pluralization * @param mixed $cause The cause of the error * - * @see \Symfony\Component\Translation\Translator + * @see Translator */ public function __construct( private string $message, diff --git a/FormEvent.php b/FormEvent.php index e6a3878f6..0f3149f41 100644 --- a/FormEvent.php +++ b/FormEvent.php @@ -14,10 +14,16 @@ use Symfony\Contracts\EventDispatcher\Event; /** + * @template T + * * @author Bernhard Schussek */ class FormEvent extends Event { + /** + * @param FormInterface $form The form at the source of the event + * @param T $data The data associated with this event + */ public function __construct( private FormInterface $form, protected mixed $data, @@ -26,6 +32,8 @@ public function __construct( /** * Returns the form at the source of the event. + * + * @return FormInterface */ public function getForm(): FormInterface { @@ -34,6 +42,8 @@ public function getForm(): FormInterface /** * Returns the data associated with this event. + * + * @return T */ public function getData(): mixed { @@ -42,6 +52,8 @@ public function getData(): mixed /** * Allows updating with some filtered data. + * + * @param T $data The data associated with this event */ public function setData(mixed $data): void { diff --git a/FormFactoryInterface.php b/FormFactoryInterface.php index 0f311c0e5..89a732f9b 100644 --- a/FormFactoryInterface.php +++ b/FormFactoryInterface.php @@ -26,7 +26,12 @@ interface FormFactoryInterface * * @see createBuilder() * - * @param mixed $data The initial data + * @template T + * + * @param class-string> $type + * @param T|null $data The initial data + * + * @return FormInterface * * @throws InvalidOptionsException if any given option is not applicable to the given type */ @@ -37,7 +42,12 @@ public function create(string $type = FormType::class, mixed $data = null, array * * @see createNamedBuilder() * - * @param mixed $data The initial data + * @template T + * + * @param class-string> $type + * @param T|null $data The initial data + * + * @return FormInterface * * @throws InvalidOptionsException if any given option is not applicable to the given type */ @@ -59,7 +69,12 @@ public function createForProperty(string $class, string $property, mixed $data = /** * Returns a form builder. * - * @param mixed $data The initial data + * @template T + * + * @param class-string> $type + * @param T|null $data The initial data + * + * @return FormBuilderInterface * * @throws InvalidOptionsException if any given option is not applicable to the given type */ @@ -68,7 +83,12 @@ public function createBuilder(string $type = FormType::class, mixed $data = null /** * Returns a form builder. * - * @param mixed $data The initial data + * @template T + * + * @param class-string> $type + * @param T|null $data The initial data + * + * @return FormBuilderInterface * * @throws InvalidOptionsException if any given option is not applicable to the given type */ diff --git a/FormInterface.php b/FormInterface.php index 23392c493..8c1db609b 100644 --- a/FormInterface.php +++ b/FormInterface.php @@ -18,6 +18,8 @@ * * @author Bernhard Schussek * + * @template T + * * @extends \ArrayAccess * @extends \Traversable */ @@ -112,9 +114,9 @@ public function setData(mixed $modelData): static; /** * Returns the model data in the format needed for the underlying object. * - * @return mixed When the field is not submitted, the default data is returned. - * When the field is submitted, the default data has been bound - * to the submitted view data. + * @return T|null When the field is not submitted, the default data is returned. + * When the field is submitted, the default data has been bound + * to the submitted view data. * * @throws Exception\RuntimeException If the form inherits data but has no parent */ @@ -285,5 +287,8 @@ public function getRoot(): self; */ public function isRoot(): bool; + /** + * @return FormView + */ public function createView(?FormView $parent = null): FormView; } diff --git a/FormTypeExtensionInterface.php b/FormTypeExtensionInterface.php index 838406d2a..d935c897e 100644 --- a/FormTypeExtensionInterface.php +++ b/FormTypeExtensionInterface.php @@ -14,6 +14,8 @@ use Symfony\Component\OptionsResolver\OptionsResolver; /** + * @template T + * * @author Bernhard Schussek */ interface FormTypeExtensionInterface @@ -33,7 +35,8 @@ public function configureOptions(OptionsResolver $resolver): void; * This method is called after the extended type has built the form to * further modify it. * - * @param array $options + * @param FormBuilderInterface $builder + * @param array $options * * @see FormTypeInterface::buildForm() */ @@ -45,6 +48,8 @@ public function buildForm(FormBuilderInterface $builder, array $options): void; * This method is called after the extended type has built the view to * further modify it. * + * @param FormView $view + * @param FormInterface $form * @param array $options * * @see FormTypeInterface::buildView() @@ -57,6 +62,8 @@ public function buildView(FormView $view, FormInterface $form, array $options): * This method is called after the extended type has finished the view to * further modify it. * + * @param FormView $view + * @param FormInterface $form * @param array $options * * @see FormTypeInterface::finishView() diff --git a/FormTypeInterface.php b/FormTypeInterface.php index 2bc9f7711..8319fe13c 100644 --- a/FormTypeInterface.php +++ b/FormTypeInterface.php @@ -15,6 +15,8 @@ /** * @author Bernhard Schussek + * + * @template T */ interface FormTypeInterface { @@ -41,7 +43,8 @@ public function configureOptions(OptionsResolver $resolver); * This method is called for each type in the hierarchy starting from the * top most type. Type extensions can further modify the form. * - * @param array $options + * @param FormBuilderInterface $builder + * @param array $options * * @return void * @@ -59,7 +62,9 @@ public function buildForm(FormBuilderInterface $builder, array $options); * This means that you cannot access child views in this method. If you need * to do so, move your logic to {@link finishView()} instead. * - * @param array $options + * @param FormView $form + * @param FormInterface $view + * @param array $options * * @return void * @@ -78,7 +83,9 @@ public function buildView(FormView $view, FormInterface $form, array $options); * such logic in this method that actually accesses child views. For everything * else you are recommended to implement {@link buildView()} instead. * - * @param array $options + * @param FormView $form + * @param FormInterface $view + * @param array $options * * @return void * diff --git a/FormView.php b/FormView.php index 93804bb87..2dedf9fc5 100644 --- a/FormView.php +++ b/FormView.php @@ -16,6 +16,8 @@ /** * @author Bernhard Schussek * + * @template T + * * @implements \ArrayAccess * @implements \IteratorAggregate */ @@ -23,6 +25,8 @@ class FormView implements \ArrayAccess, \IteratorAggregate, \Countable { /** * The variables assigned to this view. + * + * @var array{value: T|null, attr: array, ...} */ public array $vars = [ 'value' => null, diff --git a/ResolvedFormType.php b/ResolvedFormType.php index d9553bbbb..e2c518646 100644 --- a/ResolvedFormType.php +++ b/ResolvedFormType.php @@ -117,7 +117,6 @@ public function finishView(FormView $view, FormInterface $form, array $options): $this->innerType->finishView($view, $form, $options); - /** @var FormTypeExtensionInterface $extension */ foreach ($this->typeExtensions as $extension) { $extension->finishView($view, $form, $options); } diff --git a/Tests/AbstractRequestHandlerTestCase.php b/Tests/AbstractRequestHandlerTestCase.php index f80efffb7..68dfafab1 100644 --- a/Tests/AbstractRequestHandlerTestCase.php +++ b/Tests/AbstractRequestHandlerTestCase.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\Form\Extension\Core\DataMapper\DataMapper; @@ -76,9 +77,7 @@ public static function methodProvider(): array ], self::methodExceptGetProvider()); } - /** - * @dataProvider methodProvider - */ + #[DataProvider('methodProvider')] public function testSubmitIfNameInRequest($method) { $form = $this->createForm('param1', $method); @@ -93,9 +92,7 @@ public function testSubmitIfNameInRequest($method) $this->assertSame('DATA', $form->getData()); } - /** - * @dataProvider methodProvider - */ + #[DataProvider('methodProvider')] public function testDoNotSubmitIfWrongRequestMethod($method) { $form = $this->createForm('param1', $method); @@ -111,9 +108,7 @@ public function testDoNotSubmitIfWrongRequestMethod($method) $this->assertFalse($form->isSubmitted()); } - /** - * @dataProvider methodExceptGetProvider - */ + #[DataProvider('methodExceptGetProvider')] public function testDoNoSubmitSimpleFormIfNameNotInRequestAndNotGetRequest($method) { $form = $this->createForm('param1', $method, false); @@ -127,9 +122,7 @@ public function testDoNoSubmitSimpleFormIfNameNotInRequestAndNotGetRequest($meth $this->assertFalse($form->isSubmitted()); } - /** - * @dataProvider methodExceptGetProvider - */ + #[DataProvider('methodExceptGetProvider')] public function testDoNotSubmitCompoundFormIfNameNotInRequestAndNotGetRequest($method) { $form = $this->createForm('param1', $method, true); @@ -156,9 +149,7 @@ public function testDoNotSubmitIfNameNotInRequestAndGetRequest() $this->assertFalse($form->isSubmitted()); } - /** - * @dataProvider methodProvider - */ + #[DataProvider('methodProvider')] public function testSubmitFormWithEmptyNameIfAtLeastOneFieldInRequest($method) { $form = $this->createForm('', $method, true); @@ -185,9 +176,7 @@ public function testSubmitFormWithEmptyNameIfAtLeastOneFieldInRequest($method) $this->assertNull($form->get('param2')->getData()); } - /** - * @dataProvider methodProvider - */ + #[DataProvider('methodProvider')] public function testDoNotSubmitFormWithEmptyNameIfNoFieldInRequest($method) { $form = $this->createForm('', $method, true); @@ -203,9 +192,7 @@ public function testDoNotSubmitFormWithEmptyNameIfNoFieldInRequest($method) $this->assertFalse($form->isSubmitted()); } - /** - * @dataProvider methodExceptGetProvider - */ + #[DataProvider('methodExceptGetProvider')] public function testMergeParamsAndFiles($method) { $form = $this->createForm('param1', $method, true); @@ -248,9 +235,7 @@ public function testIntegerChildren() $this->assertSame('bar', $form->get('1')->getData()); } - /** - * @dataProvider methodExceptGetProvider - */ + #[DataProvider('methodExceptGetProvider')] public function testMergeParamsAndFilesMultiple($method) { $form = $this->createForm('param1', $method, true); @@ -284,9 +269,7 @@ public function testMergeParamsAndFilesMultiple($method) $this->assertSame(['foo', 'bar', 'baz', $file1, $file2], $data); } - /** - * @dataProvider methodExceptGetProvider - */ + #[DataProvider('methodExceptGetProvider')] public function testParamTakesPrecedenceOverFile($method) { $form = $this->createForm('param1', $method); @@ -346,9 +329,7 @@ public function testMergeZeroIndexedCollection() $this->assertNotNull($itemsForm->get('0')->get('file')); } - /** - * @dataProvider methodExceptGetProvider - */ + #[DataProvider('methodExceptGetProvider')] public function testSubmitFileIfNoParam($method) { $form = $this->createBuilder('param1', false, ['allow_file_upload' => true]) @@ -368,9 +349,7 @@ public function testSubmitFileIfNoParam($method) $this->assertSame($file, $form->getData()); } - /** - * @dataProvider methodExceptGetProvider - */ + #[DataProvider('methodExceptGetProvider')] public function testSubmitMultipleFiles($method) { $form = $this->createBuilder('param1', false, ['allow_file_upload' => true]) @@ -392,9 +371,7 @@ public function testSubmitMultipleFiles($method) $this->assertSame($file, $form->getData()); } - /** - * @dataProvider methodExceptGetProvider - */ + #[DataProvider('methodExceptGetProvider')] public function testSubmitFileWithNamelessForm($method) { $form = $this->createForm('', $method, true); @@ -412,9 +389,7 @@ public function testSubmitFileWithNamelessForm($method) $this->assertSame($file, $fileForm->getData()); } - /** - * @dataProvider getPostMaxSizeFixtures - */ + #[DataProvider('getPostMaxSizeFixtures')] public function testAddFormErrorIfPostMaxSizeExceeded(?int $contentLength, string $iniMax, bool $shouldFail, array $errorParams = []) { $this->serverParams->contentLength = $contentLength; @@ -463,9 +438,7 @@ public function testInvalidFilesAreRejected() $this->assertFalse($this->requestHandler->isFileUpload($this->getInvalidFile())); } - /** - * @dataProvider uploadFileErrorCodes - */ + #[DataProvider('uploadFileErrorCodes')] public function testFailedFileUploadIsTurnedIntoFormError($errorCode, $expectedErrorCode) { $this->assertSame($expectedErrorCode, $this->requestHandler->getUploadFileError($this->getFailedUploadedFile($errorCode))); diff --git a/Tests/ButtonBuilderTest.php b/Tests/ButtonBuilderTest.php index 71668dd02..c625b1f25 100644 --- a/Tests/ButtonBuilderTest.php +++ b/Tests/ButtonBuilderTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\Form\ButtonBuilder; use Symfony\Component\Form\Exception\InvalidArgumentException; @@ -31,9 +32,7 @@ public static function getValidNames() ]; } - /** - * @dataProvider getValidNames - */ + #[DataProvider('getValidNames')] public function testValidNames($name) { $this->assertInstanceOf(ButtonBuilder::class, new ButtonBuilder($name)); @@ -51,14 +50,11 @@ public static function getInvalidNames() { return [ [''], - [false], [null], ]; } - /** - * @dataProvider getInvalidNames - */ + #[DataProvider('getInvalidNames')] public function testInvalidNames($name) { $this->expectException(InvalidArgumentException::class); diff --git a/Tests/ButtonTest.php b/Tests/ButtonTest.php index 9431328e2..e0b276e5f 100644 --- a/Tests/ButtonTest.php +++ b/Tests/ButtonTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\Form\ButtonBuilder; @@ -37,9 +38,7 @@ public function testSetParentOnSubmittedButton() $button->setParent($this->getFormBuilder()->getForm()); } - /** - * @dataProvider getDisabledStates - */ + #[DataProvider('getDisabledStates')] public function testDisabledIfParentIsDisabled($parentDisabled, $buttonDisabled, $result) { $form = $this->getFormBuilder() diff --git a/Tests/ChoiceList/ChoiceListAssertionTrait.php b/Tests/ChoiceList/ChoiceListAssertionTrait.php new file mode 100644 index 000000000..f0b03d13e --- /dev/null +++ b/Tests/ChoiceList/ChoiceListAssertionTrait.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\ChoiceList; + +use Symfony\Component\Form\ChoiceList\ArrayChoiceList; +use Symfony\Component\Form\ChoiceList\LazyChoiceList; + +trait ChoiceListAssertionTrait +{ + private function assertEqualsArrayChoiceList(ArrayChoiceList $expected, $actual) + { + $this->assertInstanceOf(ArrayChoiceList::class, $actual); + $this->assertEquals($expected->getChoices(), $actual->getChoices()); + $this->assertEquals($expected->getStructuredValues(), $actual->getStructuredValues()); + $this->assertEquals($expected->getOriginalKeys(), $actual->getOriginalKeys()); + } + + private function assertEqualsLazyChoiceList(LazyChoiceList $expected, $actual) + { + $this->assertInstanceOf(LazyChoiceList::class, $actual); + $this->assertEquals($expected->getChoices(), $actual->getChoices()); + $this->assertEquals($expected->getValues(), $actual->getValues()); + $this->assertEquals($expected->getOriginalKeys(), $actual->getOriginalKeys()); + } +} diff --git a/Tests/ChoiceList/Factory/Cache/ChoiceLoaderTest.php b/Tests/ChoiceList/Factory/Cache/ChoiceLoaderTest.php index 613416004..0ca1de133 100644 --- a/Tests/ChoiceList/Factory/Cache/ChoiceLoaderTest.php +++ b/Tests/ChoiceList/Factory/Cache/ChoiceLoaderTest.php @@ -16,10 +16,13 @@ use Symfony\Component\Form\ChoiceList\Factory\Cache\ChoiceLoader; use Symfony\Component\Form\ChoiceList\Loader\CallbackChoiceLoader; use Symfony\Component\Form\Extension\Core\Type\FormType; +use Symfony\Component\Form\Tests\ChoiceList\ChoiceListAssertionTrait; use Symfony\Component\Form\Tests\Fixtures\ArrayChoiceLoader; class ChoiceLoaderTest extends TestCase { + use ChoiceListAssertionTrait; + public function testSameFormTypeUseCachedLoader() { $choices = ['f' => 'foo', 'b' => 'bar', 'z' => 'baz']; @@ -30,8 +33,8 @@ public function testSameFormTypeUseCachedLoader() $loader1 = new ChoiceLoader($type, $decorated); $loader2 = new ChoiceLoader($type, new ArrayChoiceLoader()); - $this->assertEquals($choiceList, $loader1->loadChoiceList()); - $this->assertEquals($choiceList, $loader2->loadChoiceList()); + $this->assertEqualsArrayChoiceList($choiceList, $loader1->loadChoiceList()); + $this->assertEqualsArrayChoiceList($choiceList, $loader2->loadChoiceList()); $this->assertSame($choices, $loader1->loadChoicesForValues($choices)); $this->assertSame($choices, $loader2->loadChoicesForValues($choices)); diff --git a/Tests/ChoiceList/Factory/CachingFactoryDecoratorTest.php b/Tests/ChoiceList/Factory/CachingFactoryDecoratorTest.php index 67e86208c..fb51e0d57 100644 --- a/Tests/ChoiceList/Factory/CachingFactoryDecoratorTest.php +++ b/Tests/ChoiceList/Factory/CachingFactoryDecoratorTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\ChoiceList\Factory; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\Form\ChoiceList\ArrayChoiceList; use Symfony\Component\Form\ChoiceList\ChoiceList; @@ -21,6 +22,7 @@ use Symfony\Component\Form\ChoiceList\Loader\FilterChoiceLoaderDecorator; use Symfony\Component\Form\ChoiceList\View\ChoiceListView; use Symfony\Component\Form\Extension\Core\Type\FormType; +use Symfony\Component\Form\Tests\ChoiceList\ChoiceListAssertionTrait; use Symfony\Component\Form\Tests\Fixtures\ArrayChoiceLoader; /** @@ -28,6 +30,8 @@ */ class CachingFactoryDecoratorTest extends TestCase { + use ChoiceListAssertionTrait; + private CachingFactoryDecorator $factory; protected function setUp(): void @@ -41,8 +45,8 @@ public function testCreateFromChoicesEmpty() $list2 = $this->factory->createListFromChoices([]); $this->assertSame($list1, $list2); - $this->assertEquals(new ArrayChoiceList([]), $list1); - $this->assertEquals(new ArrayChoiceList([]), $list2); + self::assertEqualsArrayChoiceList(new ArrayChoiceList([]), $list1); + self::assertEqualsArrayChoiceList(new ArrayChoiceList([]), $list2); } public function testCreateFromChoicesComparesTraversableChoicesAsArray() @@ -55,8 +59,8 @@ public function testCreateFromChoicesComparesTraversableChoicesAsArray() $list2 = $this->factory->createListFromChoices($choices2); $this->assertSame($list1, $list2); - $this->assertEquals(new ArrayChoiceList(['A' => 'a']), $list1); - $this->assertEquals(new ArrayChoiceList(['A' => 'a']), $list2); + self::assertEqualsArrayChoiceList(new ArrayChoiceList(['A' => 'a']), $list1); + self::assertEqualsArrayChoiceList(new ArrayChoiceList(['A' => 'a']), $list2); } public function testCreateFromChoicesGroupedChoices() @@ -67,34 +71,30 @@ public function testCreateFromChoicesGroupedChoices() $list2 = $this->factory->createListFromChoices($choices2); $this->assertNotSame($list1, $list2); - $this->assertEquals(new ArrayChoiceList(['key' => ['A' => 'a']]), $list1); - $this->assertEquals(new ArrayChoiceList(['A' => 'a']), $list2); + self::assertEqualsArrayChoiceList(new ArrayChoiceList(['key' => ['A' => 'a']]), $list1); + self::assertEqualsArrayChoiceList(new ArrayChoiceList(['A' => 'a']), $list2); } - /** - * @dataProvider provideSameChoices - */ + #[DataProvider('provideSameChoices')] public function testCreateFromChoicesSameChoices($choice1, $choice2) { $list1 = $this->factory->createListFromChoices([$choice1]); $list2 = $this->factory->createListFromChoices([$choice2]); $this->assertSame($list1, $list2); - $this->assertEquals(new ArrayChoiceList([$choice1]), $list1); - $this->assertEquals(new ArrayChoiceList([$choice2]), $list2); + self::assertEqualsArrayChoiceList(new ArrayChoiceList([$choice1]), $list1); + self::assertEqualsArrayChoiceList(new ArrayChoiceList([$choice2]), $list2); } - /** - * @dataProvider provideDistinguishedChoices - */ + #[DataProvider('provideDistinguishedChoices')] public function testCreateFromChoicesDifferentChoices($choice1, $choice2) { $list1 = $this->factory->createListFromChoices([$choice1]); $list2 = $this->factory->createListFromChoices([$choice2]); $this->assertNotSame($list1, $list2); - $this->assertEquals(new ArrayChoiceList([$choice1]), $list1); - $this->assertEquals(new ArrayChoiceList([$choice2]), $list2); + self::assertEqualsArrayChoiceList(new ArrayChoiceList([$choice1]), $list1); + self::assertEqualsArrayChoiceList(new ArrayChoiceList([$choice2]), $list2); } public function testCreateFromChoicesSameValueClosure() @@ -106,8 +106,8 @@ public function testCreateFromChoicesSameValueClosure() $list2 = $this->factory->createListFromChoices($choices, $closure); $this->assertNotSame($list1, $list2); - $this->assertEquals(new ArrayChoiceList($choices, $closure), $list1); - $this->assertEquals(new ArrayChoiceList($choices, $closure), $list2); + self::assertEqualsArrayChoiceList(new ArrayChoiceList($choices, $closure), $list1); + self::assertEqualsArrayChoiceList(new ArrayChoiceList($choices, $closure), $list2); } public function testCreateFromChoicesSameValueClosureUseCache() @@ -120,8 +120,8 @@ public function testCreateFromChoicesSameValueClosureUseCache() $list2 = $this->factory->createListFromChoices($choices, ChoiceList::value($formType, function () {})); $this->assertSame($list1, $list2); - $this->assertEquals(new ArrayChoiceList($choices, $valueCallback), $list1); - $this->assertEquals(new ArrayChoiceList($choices, function () {}), $list2); + self::assertEqualsArrayChoiceList(new ArrayChoiceList($choices, $valueCallback), $list1); + self::assertEqualsArrayChoiceList(new ArrayChoiceList($choices, function () {}), $list2); } public function testCreateFromChoicesDifferentValueClosure() @@ -133,8 +133,8 @@ public function testCreateFromChoicesDifferentValueClosure() $list2 = $this->factory->createListFromChoices($choices, $closure2); $this->assertNotSame($list1, $list2); - $this->assertEquals(new ArrayChoiceList($choices, $closure1), $list1); - $this->assertEquals(new ArrayChoiceList($choices, $closure2), $list2); + self::assertEqualsArrayChoiceList(new ArrayChoiceList($choices, $closure1), $list1); + self::assertEqualsArrayChoiceList(new ArrayChoiceList($choices, $closure2), $list2); } public function testCreateFromChoicesSameFilterClosure() @@ -146,8 +146,8 @@ public function testCreateFromChoicesSameFilterClosure() $lazyChoiceList = new LazyChoiceList(new FilterChoiceLoaderDecorator(new CallbackChoiceLoader(static fn () => $choices), $filter), null); $this->assertNotSame($list1, $list2); - $this->assertEquals($lazyChoiceList, $list1); - $this->assertEquals($lazyChoiceList, $list2); + self::assertEqualsLazyChoiceList($lazyChoiceList, $list1); + self::assertEqualsLazyChoiceList($lazyChoiceList, $list2); } public function testCreateFromChoicesSameFilterClosureUseCache() @@ -160,8 +160,8 @@ public function testCreateFromChoicesSameFilterClosureUseCache() $lazyChoiceList = new LazyChoiceList(new FilterChoiceLoaderDecorator(new CallbackChoiceLoader(static fn () => $choices), function () {}), null); $this->assertSame($list1, $list2); - $this->assertEquals($lazyChoiceList, $list1); - $this->assertEquals($lazyChoiceList, $list2); + self::assertEqualsLazyChoiceList($lazyChoiceList, $list1); + self::assertEqualsLazyChoiceList($lazyChoiceList, $list2); } public function testCreateFromChoicesDifferentFilterClosure() @@ -174,8 +174,8 @@ public function testCreateFromChoicesDifferentFilterClosure() $lazyChoiceList = new LazyChoiceList(new FilterChoiceLoaderDecorator(new CallbackChoiceLoader(static fn () => $choices), function () {}), null); $this->assertNotSame($list1, $list2); - $this->assertEquals($lazyChoiceList, $list1); - $this->assertEquals($lazyChoiceList, $list2); + self::assertEqualsLazyChoiceList($lazyChoiceList, $list1); + self::assertEqualsLazyChoiceList($lazyChoiceList, $list2); } public function testCreateFromLoaderSameLoader() @@ -185,8 +185,8 @@ public function testCreateFromLoaderSameLoader() $list2 = $this->factory->createListFromLoader($loader); $this->assertNotSame($list1, $list2); - $this->assertEquals(new LazyChoiceList($loader), $list1); - $this->assertEquals(new LazyChoiceList($loader), $list2); + self::assertEqualsLazyChoiceList(new LazyChoiceList($loader), $list1); + self::assertEqualsLazyChoiceList(new LazyChoiceList($loader), $list2); } public function testCreateFromLoaderSameLoaderUseCache() @@ -196,8 +196,8 @@ public function testCreateFromLoaderSameLoaderUseCache() $list2 = $this->factory->createListFromLoader(ChoiceList::loader($type, new ArrayChoiceLoader())); $this->assertSame($list1, $list2); - $this->assertEquals(new LazyChoiceList(new ArrayChoiceLoader(), null), $list1); - $this->assertEquals(new LazyChoiceList(new ArrayChoiceLoader(), null), $list2); + self::assertEqualsLazyChoiceList(new LazyChoiceList(new ArrayChoiceLoader(), null), $list1); + self::assertEqualsLazyChoiceList(new LazyChoiceList(new ArrayChoiceLoader(), null), $list2); } public function testCreateFromLoaderDifferentLoader() @@ -213,8 +213,8 @@ public function testCreateFromLoaderSameValueClosure() $list2 = $this->factory->createListFromLoader($loader, $closure); $this->assertNotSame($list1, $list2); - $this->assertEquals(new LazyChoiceList($loader, $closure), $list1); - $this->assertEquals(new LazyChoiceList($loader, $closure), $list2); + self::assertEqualsLazyChoiceList(new LazyChoiceList($loader, $closure), $list1); + self::assertEqualsLazyChoiceList(new LazyChoiceList($loader, $closure), $list2); } public function testCreateFromLoaderSameValueClosureUseCache() @@ -226,8 +226,8 @@ public function testCreateFromLoaderSameValueClosureUseCache() $list2 = $this->factory->createListFromLoader(ChoiceList::loader($type, new ArrayChoiceLoader()), ChoiceList::value($type, function () {})); $this->assertSame($list1, $list2); - $this->assertEquals(new LazyChoiceList($loader, $closure), $list1); - $this->assertEquals(new LazyChoiceList(new ArrayChoiceLoader(), function () {}), $list2); + self::assertEqualsLazyChoiceList(new LazyChoiceList($loader, $closure), $list1); + self::assertEqualsLazyChoiceList(new LazyChoiceList(new ArrayChoiceLoader(), function () {}), $list2); } public function testCreateFromLoaderDifferentValueClosure() @@ -249,8 +249,8 @@ public function testCreateFromLoaderSameFilterClosure() $list2 = $this->factory->createListFromLoader(ChoiceList::loader($type, new ArrayChoiceLoader()), null, $closure); $this->assertNotSame($list1, $list2); - $this->assertEquals(new LazyChoiceList(new FilterChoiceLoaderDecorator($loader, $closure)), $list1); - $this->assertEquals(new LazyChoiceList(new FilterChoiceLoaderDecorator(new ArrayChoiceLoader(), $closure)), $list2); + self::assertEqualsLazyChoiceList(new LazyChoiceList(new FilterChoiceLoaderDecorator($loader, $closure)), $list1); + self::assertEqualsLazyChoiceList(new LazyChoiceList(new FilterChoiceLoaderDecorator(new ArrayChoiceLoader(), $closure)), $list2); } public function testCreateFromLoaderSameFilterClosureUseCache() @@ -261,8 +261,8 @@ public function testCreateFromLoaderSameFilterClosureUseCache() $list2 = $this->factory->createListFromLoader(ChoiceList::loader($type, new ArrayChoiceLoader()), null, $choiceFilter); $this->assertSame($list1, $list2); - $this->assertEquals(new LazyChoiceList(new FilterChoiceLoaderDecorator(new ArrayChoiceLoader(), function () {})), $list1); - $this->assertEquals(new LazyChoiceList(new FilterChoiceLoaderDecorator(new ArrayChoiceLoader(), function () {})), $list2); + self::assertEqualsLazyChoiceList(new LazyChoiceList(new FilterChoiceLoaderDecorator(new ArrayChoiceLoader(), function () {})), $list1); + self::assertEqualsLazyChoiceList(new LazyChoiceList(new FilterChoiceLoaderDecorator(new ArrayChoiceLoader(), function () {})), $list2); } public function testCreateFromLoaderDifferentFilterClosure() @@ -274,8 +274,8 @@ public function testCreateFromLoaderDifferentFilterClosure() $list2 = $this->factory->createListFromLoader(ChoiceList::loader($type, new ArrayChoiceLoader()), null, $closure2); $this->assertNotSame($list1, $list2); - $this->assertEquals(new LazyChoiceList(new FilterChoiceLoaderDecorator(new ArrayChoiceLoader(), $closure1), null), $list1); - $this->assertEquals(new LazyChoiceList(new FilterChoiceLoaderDecorator(new ArrayChoiceLoader(), $closure2), null), $list2); + self::assertEqualsLazyChoiceList(new LazyChoiceList(new FilterChoiceLoaderDecorator(new ArrayChoiceLoader(), $closure1), null), $list1); + self::assertEqualsLazyChoiceList(new LazyChoiceList(new FilterChoiceLoaderDecorator(new ArrayChoiceLoader(), $closure2), null), $list2); } public function testCreateViewSamePreferredChoices() diff --git a/Tests/ChoiceList/Factory/DefaultChoiceListFactoryTest.php b/Tests/ChoiceList/Factory/DefaultChoiceListFactoryTest.php index 2b1b239e5..0748011a3 100644 --- a/Tests/ChoiceList/Factory/DefaultChoiceListFactoryTest.php +++ b/Tests/ChoiceList/Factory/DefaultChoiceListFactoryTest.php @@ -20,6 +20,7 @@ use Symfony\Component\Form\ChoiceList\View\ChoiceGroupView; use Symfony\Component\Form\ChoiceList\View\ChoiceListView; use Symfony\Component\Form\ChoiceList\View\ChoiceView; +use Symfony\Component\Form\Tests\ChoiceList\ChoiceListAssertionTrait; use Symfony\Component\Form\Tests\Fixtures\ArrayChoiceLoader; use Symfony\Component\Translation\TranslatableMessage; use Symfony\Contracts\Translation\TranslatableInterface; @@ -27,6 +28,8 @@ class DefaultChoiceListFactoryTest extends TestCase { + use ChoiceListAssertionTrait; + private \stdClass $obj1; private \stdClass $obj2; private \stdClass $obj3; @@ -261,7 +264,7 @@ public function testCreateFromLoaderWithFilter() $list = $this->factory->createListFromLoader(new ArrayChoiceLoader(), null, $filter); - $this->assertEquals(new LazyChoiceList(new FilterChoiceLoaderDecorator(new ArrayChoiceLoader(), $filter)), $list); + $this->assertEqualsLazyChoiceList(new LazyChoiceList(new FilterChoiceLoaderDecorator(new ArrayChoiceLoader(), $filter)), $list); } public function testCreateViewFlat() diff --git a/Tests/ChoiceList/Loader/FilterChoiceLoaderDecoratorTest.php b/Tests/ChoiceList/Loader/FilterChoiceLoaderDecoratorTest.php index 5a41e5aff..e8f51dd6b 100644 --- a/Tests/ChoiceList/Loader/FilterChoiceLoaderDecoratorTest.php +++ b/Tests/ChoiceList/Loader/FilterChoiceLoaderDecoratorTest.php @@ -14,17 +14,20 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Form\ChoiceList\ArrayChoiceList; use Symfony\Component\Form\ChoiceList\Loader\FilterChoiceLoaderDecorator; +use Symfony\Component\Form\Tests\ChoiceList\ChoiceListAssertionTrait; use Symfony\Component\Form\Tests\Fixtures\ArrayChoiceLoader; class FilterChoiceLoaderDecoratorTest extends TestCase { + use ChoiceListAssertionTrait; + public function testLoadChoiceList() { $filter = fn ($choice) => 0 === $choice % 2; $loader = new FilterChoiceLoaderDecorator(new ArrayChoiceLoader(range(1, 4)), $filter); - $this->assertEquals(new ArrayChoiceList([1 => 2, 3 => 4]), $loader->loadChoiceList()); + $this->assertEqualsArrayChoiceList(new ArrayChoiceList([1 => 2, 3 => 4]), $loader->loadChoiceList()); } public function testLoadChoiceListWithGroupedChoices() @@ -33,7 +36,7 @@ public function testLoadChoiceListWithGroupedChoices() $loader = new FilterChoiceLoaderDecorator(new ArrayChoiceLoader(['units' => range(1, 9), 'tens' => range(10, 90, 10)]), $filter); - $this->assertEquals(new ArrayChoiceList([ + $this->assertEqualsArrayChoiceList(new ArrayChoiceList([ 'units' => [ 1 => 2, 3 => 4, @@ -50,7 +53,7 @@ public function testLoadChoiceListMixedWithGroupedAndNonGroupedChoices() $choices = array_merge(range(1, 9), ['grouped' => range(10, 40, 5)]); $loader = new FilterChoiceLoaderDecorator(new ArrayChoiceLoader($choices), $filter); - $this->assertEquals(new ArrayChoiceList([ + $this->assertEqualsArrayChoiceList(new ArrayChoiceList([ 1 => 2, 3 => 4, 5 => 6, diff --git a/Tests/Command/DebugCommandTest.php b/Tests/Command/DebugCommandTest.php index cac92addb..1eae6f649 100644 --- a/Tests/Command/DebugCommandTest.php +++ b/Tests/Command/DebugCommandTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Command; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Application; use Symfony\Component\Console\Exception\InvalidArgumentException; @@ -45,14 +46,15 @@ public function testDebugDeprecatedDefaults() $this->assertEquals(0, $ret, 'Returns 0 in case of success'); $this->assertSame(<<getDisplay(true)); + TXT, + $tester->getDisplay(true) + ); } public function testDebugSingleFormType() @@ -93,12 +95,12 @@ public function testDebugSingleFormTypeNotFound() public function testDebugAmbiguousFormType() { $expectedMessage = <<expectException(InvalidArgumentException::class); $this->expectExceptionMessage($expectedMessage); @@ -125,16 +127,17 @@ public function testDebugAmbiguousFormTypeInteractive() $output = $tester->getDisplay(true); $this->assertStringMatchesFormat(<<assertEquals(0, $ret, 'Returns 0 in case of success'); $this->assertStringMatchesFormat(<<<'TXT' -Symfony\Component\Form\Tests\Command\FooType (foo) -================================================== - - ---------------- -----------%s - Info "Info" %s - ---------------- -----------%s - Required true %s - ---------------- -----------%s - Default - %s - ---------------- -----------%s - Allowed types [ %s - "string"%s - ] %s - ---------------- -----------%s - Allowed values [ %s - "bar", %s - "baz" %s - ] %s - ---------------- -----------%s - Normalizers [ %s - Closure(%s - class:%s - this: %s - file: %s - line: %s - } %s - ] %s - ---------------- -----------%s - Nested Options - %s - ---------------- -----------%s - -TXT - , $tester->getDisplay(true)); + Symfony\Component\Form\Tests\Command\FooType (foo) + ================================================== + + ---------------- -----------%s + Info "Info" %s + ---------------- -----------%s + Required true %s + ---------------- -----------%s + Default - %s + ---------------- -----------%s + Allowed types [ %s + "string"%s + ] %s + ---------------- -----------%s + Allowed values [ %s + "bar", %s + "baz" %s + ] %s + ---------------- -----------%s + Normalizers [ %s + Closure(%s + class:%s + this: %s + file: %s + line: %s + } %s + ] %s + ---------------- -----------%s + Nested Options - %s + ---------------- -----------%s + + TXT, + $tester->getDisplay(true) + ); } - /** - * @dataProvider provideCompletionSuggestions - */ + #[DataProvider('provideCompletionSuggestions')] public function testComplete(array $input, array $expectedSuggestions) { $formRegistry = new FormRegistry([], new ResolvedFormTypeFactory()); $command = new DebugCommand($formRegistry); $application = new Application(); - $application->add($command); + if (method_exists($application, 'addCommand')) { + $application->addCommand($command); + } else { + $application->add($command); + } $tester = new CommandCompletionTester($application->get('debug:form')); $this->assertSame($expectedSuggestions, $tester->complete($input)); } @@ -278,7 +284,11 @@ private function createCommandTester(array $namespaces = ['Symfony\Component\For $formRegistry = new FormRegistry([], new ResolvedFormTypeFactory()); $command = new DebugCommand($formRegistry, $namespaces, $types); $application = new Application(); - $application->add($command); + if (method_exists($application, 'addCommand')) { + $application->addCommand($command); + } else { + $application->add($command); + } return new CommandTester($application->find('debug:form')); } diff --git a/Tests/CompoundFormPerformanceTest.php b/Tests/CompoundFormPerformanceTest.php index b9c81f1d1..8177dbf38 100644 --- a/Tests/CompoundFormPerformanceTest.php +++ b/Tests/CompoundFormPerformanceTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests; +use PHPUnit\Framework\Attributes\Group; use Symfony\Component\Form\Test\FormPerformanceTestCase; /** @@ -20,9 +21,8 @@ class CompoundFormPerformanceTest extends FormPerformanceTestCase { /** * Create a compound form multiple times, as happens in a collection form. - * - * @group benchmark */ + #[Group('benchmark')] public function testArrayBasedForm() { $this->setMaxRunningTime(1); diff --git a/Tests/CompoundFormTest.php b/Tests/CompoundFormTest.php index 882e73034..13773b2a0 100644 --- a/Tests/CompoundFormTest.php +++ b/Tests/CompoundFormTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\Form\Exception\AlreadySubmittedException; @@ -585,9 +586,7 @@ public static function requestMethodProvider(): array ]; } - /** - * @dataProvider requestMethodProvider - */ + #[DataProvider('requestMethodProvider')] public function testSubmitPostOrPutRequest($method) { $path = tempnam(sys_get_temp_dir(), 'sf'); @@ -633,9 +632,7 @@ public function testSubmitPostOrPutRequest($method) unlink($path); } - /** - * @dataProvider requestMethodProvider - */ + #[DataProvider('requestMethodProvider')] public function testSubmitPostOrPutRequestWithEmptyRootFormName($method) { $path = tempnam(sys_get_temp_dir(), 'sf'); @@ -681,9 +678,7 @@ public function testSubmitPostOrPutRequestWithEmptyRootFormName($method) unlink($path); } - /** - * @dataProvider requestMethodProvider - */ + #[DataProvider('requestMethodProvider')] public function testSubmitPostOrPutRequestWithSingleChildForm($method) { $path = tempnam(sys_get_temp_dir(), 'sf'); @@ -718,9 +713,7 @@ public function testSubmitPostOrPutRequestWithSingleChildForm($method) unlink($path); } - /** - * @dataProvider requestMethodProvider - */ + #[DataProvider('requestMethodProvider')] public function testSubmitPostOrPutRequestWithSingleChildFormUploadedFile($method) { $path = tempnam(sys_get_temp_dir(), 'sf'); diff --git a/Tests/Console/Descriptor/AbstractDescriptorTestCase.php b/Tests/Console/Descriptor/AbstractDescriptorTestCase.php index 456b433ee..f956c7475 100644 --- a/Tests/Console/Descriptor/AbstractDescriptorTestCase.php +++ b/Tests/Console/Descriptor/AbstractDescriptorTestCase.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Console\Descriptor; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Output\BufferedOutput; @@ -41,7 +42,7 @@ protected function tearDown(): void putenv($this->colSize ? 'COLUMNS='.$this->colSize : 'COLUMNS'); } - /** @dataProvider getDescribeDefaultsTestData */ + #[DataProvider('getDescribeDefaultsTestData')] public function testDescribeDefaults($object, array $options, $fixtureName) { $describedObject = $this->getObjectDescription($object, $options); @@ -54,7 +55,7 @@ public function testDescribeDefaults($object, array $options, $fixtureName) } } - /** @dataProvider getDescribeResolvedFormTypeTestData */ + #[DataProvider('getDescribeResolvedFormTypeTestData')] public function testDescribeResolvedFormType(ResolvedFormTypeInterface $type, array $options, $fixtureName) { $describedObject = $this->getObjectDescription($type, $options); @@ -67,7 +68,7 @@ public function testDescribeResolvedFormType(ResolvedFormTypeInterface $type, ar } } - /** @dataProvider getDescribeOptionTestData */ + #[DataProvider('getDescribeOptionTestData')] public function testDescribeOption(OptionsResolver $optionsResolver, array $options, $fixtureName) { $describedObject = $this->getObjectDescription($optionsResolver, $options); diff --git a/Tests/DependencyInjection/FormPassTest.php b/Tests/DependencyInjection/FormPassTest.php index f0ccd3f09..1e951ae43 100644 --- a/Tests/DependencyInjection/FormPassTest.php +++ b/Tests/DependencyInjection/FormPassTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\DependencyInjection; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\Argument\IteratorArgument; use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; @@ -60,7 +61,7 @@ public function testAddTaggedTypes() $extDefinition = $container->getDefinition('form.extension'); $locator = $extDefinition->getArgument(0); - $this->assertTrue(!$locator->isPublic() || $locator->isPrivate()); + $this->assertTrue($locator->isPrivate()); $this->assertEquals( (new Definition(ServiceLocator::class, [[ __CLASS__.'_Type1' => new ServiceClosureArgument(new Reference('my.type1')), @@ -115,9 +116,7 @@ public function testAddTaggedTypesToCsrfTypeExtension() $this->assertSame([__CLASS__.'_Type1' => 'the_token_id'], $csrfDefinition->getArgument(7)); } - /** - * @dataProvider addTaggedTypeExtensionsDataProvider - */ + #[DataProvider('addTaggedTypeExtensionsDataProvider')] public function testAddTaggedTypeExtensions(array $extensions, array $expectedRegisteredExtensions, array $parameters = []) { $container = $this->createContainerBuilder(); @@ -280,9 +279,7 @@ public function testAddTaggedGuessers() ); } - /** - * @dataProvider privateTaggedServicesProvider - */ + #[DataProvider('privateTaggedServicesProvider')] public function testPrivateTaggedServices($id, $class, $tagName, callable $assertion, array $tagAttributes = []) { $formPass = new FormPass(); diff --git a/Tests/EnumFormTypeGuesserTest.php b/Tests/EnumFormTypeGuesserTest.php new file mode 100644 index 000000000..f0a04c7f5 --- /dev/null +++ b/Tests/EnumFormTypeGuesserTest.php @@ -0,0 +1,208 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests; + +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\TestCase; +use Symfony\Component\Form\EnumFormTypeGuesser; +use Symfony\Component\Form\Extension\Core\Type\EnumType as FormEnumType; +use Symfony\Component\Form\Guess\Guess; +use Symfony\Component\Form\Guess\TypeGuess; +use Symfony\Component\Form\Guess\ValueGuess; +use Symfony\Component\Form\Tests\Fixtures\BackedEnumFormTypeGuesserCaseEnum; +use Symfony\Component\Form\Tests\Fixtures\EnumFormTypeGuesserCase; +use Symfony\Component\Form\Tests\Fixtures\EnumFormTypeGuesserCaseEnum; + +class EnumFormTypeGuesserTest extends TestCase +{ + #[DataProvider('provideGuessTypeCases')] + public function testGuessType(?TypeGuess $expectedTypeGuess, string $class, string $property) + { + $typeGuesser = new EnumFormTypeGuesser(); + + $typeGuess = $typeGuesser->guessType($class, $property); + + self::assertEquals($expectedTypeGuess, $typeGuess); + } + + #[DataProvider('provideGuessRequiredCases')] + public function testGuessRequired(?ValueGuess $expectedValueGuess, string $class, string $property) + { + $typeGuesser = new EnumFormTypeGuesser(); + + $valueGuess = $typeGuesser->guessRequired($class, $property); + + self::assertEquals($expectedValueGuess, $valueGuess); + } + + public static function provideGuessTypeCases(): iterable + { + yield 'Undefined class' => [ + null, + 'UndefinedClass', + 'undefinedProperty', + ]; + + yield 'Undefined property' => [ + null, + EnumFormTypeGuesserCase::class, + 'undefinedProperty', + ]; + + yield 'Undefined enum' => [ + null, + EnumFormTypeGuesserCase::class, + 'undefinedEnum', + ]; + + yield 'Non-enum property' => [ + null, + EnumFormTypeGuesserCase::class, + 'string', + ]; + + yield 'Enum property' => [ + new TypeGuess( + FormEnumType::class, + [ + 'class' => EnumFormTypeGuesserCaseEnum::class, + ], + Guess::HIGH_CONFIDENCE, + ), + EnumFormTypeGuesserCase::class, + 'enum', + ]; + + yield 'Nullable enum property' => [ + new TypeGuess( + FormEnumType::class, + [ + 'class' => EnumFormTypeGuesserCaseEnum::class, + ], + Guess::HIGH_CONFIDENCE, + ), + EnumFormTypeGuesserCase::class, + 'nullableEnum', + ]; + + yield 'Backed enum property' => [ + new TypeGuess( + FormEnumType::class, + [ + 'class' => BackedEnumFormTypeGuesserCaseEnum::class, + ], + Guess::HIGH_CONFIDENCE, + ), + EnumFormTypeGuesserCase::class, + 'backedEnum', + ]; + + yield 'Nullable backed enum property' => [ + new TypeGuess( + FormEnumType::class, + [ + 'class' => BackedEnumFormTypeGuesserCaseEnum::class, + ], + Guess::HIGH_CONFIDENCE, + ), + EnumFormTypeGuesserCase::class, + 'nullableBackedEnum', + ]; + + yield 'Enum union property' => [ + null, + EnumFormTypeGuesserCase::class, + 'enumUnion', + ]; + + yield 'Enum intersection property' => [ + null, + EnumFormTypeGuesserCase::class, + 'enumIntersection', + ]; + } + + public static function provideGuessRequiredCases(): iterable + { + yield 'Unknown class' => [ + null, + 'UndefinedClass', + 'undefinedProperty', + ]; + + yield 'Unknown property' => [ + null, + EnumFormTypeGuesserCase::class, + 'undefinedProperty', + ]; + + yield 'Undefined enum' => [ + null, + EnumFormTypeGuesserCase::class, + 'undefinedEnum', + ]; + + yield 'Non-enum property' => [ + null, + EnumFormTypeGuesserCase::class, + 'string', + ]; + + yield 'Enum property' => [ + new ValueGuess( + true, + Guess::HIGH_CONFIDENCE, + ), + EnumFormTypeGuesserCase::class, + 'enum', + ]; + + yield 'Nullable enum property' => [ + new ValueGuess( + false, + Guess::HIGH_CONFIDENCE, + ), + EnumFormTypeGuesserCase::class, + 'nullableEnum', + ]; + + yield 'Backed enum property' => [ + new ValueGuess( + true, + Guess::HIGH_CONFIDENCE, + ), + EnumFormTypeGuesserCase::class, + 'backedEnum', + ]; + + yield 'Nullable backed enum property' => [ + new ValueGuess( + false, + Guess::HIGH_CONFIDENCE, + ), + EnumFormTypeGuesserCase::class, + 'nullableBackedEnum', + ]; + + yield 'Enum union property' => [ + null, + EnumFormTypeGuesserCase::class, + 'enumUnion', + ]; + + yield 'Enum intersection property' => [ + null, + EnumFormTypeGuesserCase::class, + 'enumIntersection', + ]; + } +} diff --git a/Tests/Extension/Core/DataMapper/DataMapperTest.php b/Tests/Extension/Core/DataMapper/DataMapperTest.php index 1a8f2678d..5ca81ac87 100644 --- a/Tests/Extension/Core/DataMapper/DataMapperTest.php +++ b/Tests/Extension/Core/DataMapper/DataMapperTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\DataMapper; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\Form\Extension\Core\DataAccessor\PropertyPathAccessor; @@ -317,9 +318,7 @@ public function testMapFormsToUninitializedProperties() self::assertSame('BMW', $car->engine); } - /** - * @dataProvider provideDate - */ + #[DataProvider('provideDate')] public function testMapFormsToDataDoesNotChangeEqualDateTimeInstance($date) { $article = []; diff --git a/Tests/Extension/Core/DataTransformer/ChoiceToValueTransformerTest.php b/Tests/Extension/Core/DataTransformer/ChoiceToValueTransformerTest.php index 4c6f74925..5eda911b5 100644 --- a/Tests/Extension/Core/DataTransformer/ChoiceToValueTransformerTest.php +++ b/Tests/Extension/Core/DataTransformer/ChoiceToValueTransformerTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\Form\ChoiceList\ArrayChoiceList; use Symfony\Component\Form\Exception\TransformationFailedException; @@ -41,9 +42,7 @@ public static function transformProvider(): array ]; } - /** - * @dataProvider transformProvider - */ + #[DataProvider('transformProvider')] public function testTransform($in, $out, $inWithNull, $outWithNull) { $this->assertSame($out, $this->transformer->transform($in)); @@ -62,9 +61,7 @@ public static function reverseTransformProvider() ]; } - /** - * @dataProvider reverseTransformProvider - */ + #[DataProvider('reverseTransformProvider')] public function testReverseTransform($in, $out, $inWithNull, $outWithNull) { $this->assertSame($out, $this->transformer->reverseTransform($in)); @@ -81,9 +78,7 @@ public static function reverseTransformExpectsStringOrNullProvider() ]; } - /** - * @dataProvider reverseTransformExpectsStringOrNullProvider - */ + #[DataProvider('reverseTransformExpectsStringOrNullProvider')] public function testReverseTransformExpectsStringOrNull($value) { $this->expectException(TransformationFailedException::class); diff --git a/Tests/Extension/Core/DataTransformer/DateIntervalToStringTransformerTest.php b/Tests/Extension/Core/DataTransformer/DateIntervalToStringTransformerTest.php index 1a978737f..d8545d8de 100644 --- a/Tests/Extension/Core/DataTransformer/DateIntervalToStringTransformerTest.php +++ b/Tests/Extension/Core/DataTransformer/DateIntervalToStringTransformerTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer; +use PHPUnit\Framework\Attributes\DataProvider; use Symfony\Component\Form\Exception\TransformationFailedException; use Symfony\Component\Form\Exception\UnexpectedTypeException; use Symfony\Component\Form\Extension\Core\DataTransformer\DateIntervalToStringTransformer; @@ -52,9 +53,7 @@ public static function dataProviderDate(): array ]; } - /** - * @dataProvider dataProviderISO - */ + #[DataProvider('dataProviderISO')] public function testTransform($format, $output, $input) { $transformer = new DateIntervalToStringTransformer($format); @@ -75,9 +74,7 @@ public function testTransformExpectsDateTime() $transformer->transform('1234'); } - /** - * @dataProvider dataProviderISO - */ + #[DataProvider('dataProviderISO')] public function testReverseTransform($format, $input, $output) { $reverseTransformer = new DateIntervalToStringTransformer($format, true); @@ -85,9 +82,7 @@ public function testReverseTransform($format, $input, $output) $this->assertDateIntervalEquals($interval, $reverseTransformer->reverseTransform($input)); } - /** - * @dataProvider dataProviderDate - */ + #[DataProvider('dataProviderDate')] public function testReverseTransformDateString($format, $input, $output) { $reverseTransformer = new DateIntervalToStringTransformer($format, true); diff --git a/Tests/Extension/Core/DataTransformer/DateTimeImmutableToDateTimeTransformerTest.php b/Tests/Extension/Core/DataTransformer/DateTimeImmutableToDateTimeTransformerTest.php index 04f8e74a4..8de1599f9 100644 --- a/Tests/Extension/Core/DataTransformer/DateTimeImmutableToDateTimeTransformerTest.php +++ b/Tests/Extension/Core/DataTransformer/DateTimeImmutableToDateTimeTransformerTest.php @@ -11,15 +11,14 @@ namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\Form\Exception\TransformationFailedException; use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeImmutableToDateTimeTransformer; class DateTimeImmutableToDateTimeTransformerTest extends TestCase { - /** - * @dataProvider provider - */ + #[DataProvider('provider')] public function testTransform(\DateTime $expectedOutput, \DateTimeImmutable $input) { $transformer = new DateTimeImmutableToDateTimeTransformer(); @@ -61,9 +60,7 @@ public function testTransformFail() $transformer->transform(new \DateTime()); } - /** - * @dataProvider provider - */ + #[DataProvider('provider')] public function testReverseTransform(\DateTime $input, \DateTimeImmutable $expectedOutput) { $transformer = new DateTimeImmutableToDateTimeTransformer(); diff --git a/Tests/Extension/Core/DataTransformer/DateTimeToHtml5LocalDateTimeTransformerTest.php b/Tests/Extension/Core/DataTransformer/DateTimeToHtml5LocalDateTimeTransformerTest.php index f2fb15cf0..cdd7fd473 100644 --- a/Tests/Extension/Core/DataTransformer/DateTimeToHtml5LocalDateTimeTransformerTest.php +++ b/Tests/Extension/Core/DataTransformer/DateTimeToHtml5LocalDateTimeTransformerTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer; +use PHPUnit\Framework\Attributes\DataProvider; use Symfony\Component\Form\Exception\TransformationFailedException; use Symfony\Component\Form\Extension\Core\DataTransformer\BaseDateTimeTransformer; use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToHtml5LocalDateTimeTransformer; @@ -56,9 +57,7 @@ public static function reverseTransformProvider(): array ]; } - /** - * @dataProvider transformProvider - */ + #[DataProvider('transformProvider')] public function testTransform($fromTz, $toTz, $from, $to, bool $withSeconds) { $transformer = new DateTimeToHtml5LocalDateTimeTransformer($fromTz, $toTz, $withSeconds); @@ -66,9 +65,7 @@ public function testTransform($fromTz, $toTz, $from, $to, bool $withSeconds) $this->assertSame($to, $transformer->transform(null !== $from ? new \DateTime($from) : null)); } - /** - * @dataProvider transformProvider - */ + #[DataProvider('transformProvider')] public function testTransformDateTimeImmutable($fromTz, $toTz, $from, $to, bool $withSeconds) { $transformer = new DateTimeToHtml5LocalDateTimeTransformer($fromTz, $toTz, $withSeconds); @@ -83,9 +80,7 @@ public function testTransformRequiresValidDateTime() $transformer->transform('2010-01-01'); } - /** - * @dataProvider reverseTransformProvider - */ + #[DataProvider('reverseTransformProvider')] public function testReverseTransform($toTz, $fromTz, $to, $from) { $transformer = new DateTimeToHtml5LocalDateTimeTransformer($toTz, $fromTz); diff --git a/Tests/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php b/Tests/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php index d0207bbd0..b66716769 100644 --- a/Tests/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php +++ b/Tests/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php @@ -11,6 +11,9 @@ namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\RequiresPhp; +use PHPUnit\Framework\Attributes\RequiresPhpExtension; use Symfony\Component\Form\Exception\InvalidArgumentException; use Symfony\Component\Form\Exception\TransformationFailedException; use Symfony\Component\Form\Extension\Core\DataTransformer\BaseDateTimeTransformer; @@ -49,7 +52,9 @@ protected function setUp(): void protected function tearDown(): void { - \Locale::setDefault($this->defaultLocale); + if (isset($this->defaultLocale)) { + \Locale::setDefault($this->defaultLocale); + } if (\extension_loaded('intl')) { ini_set('intl.use_exceptions', $this->initialTestCaseUseException); @@ -90,9 +95,7 @@ public static function dataProvider() ]; } - /** - * @dataProvider dataProvider - */ + #[DataProvider('dataProvider')] public function testTransform($dateFormat, $timeFormat, $pattern, $output, $input) { IntlTestHelper::requireFullIntl($this, '59.1'); @@ -206,9 +209,7 @@ public function testTransformWrapsIntlErrors() // $transformer->transform(1.5); } - /** - * @dataProvider dataProvider - */ + #[DataProvider('dataProvider')] public function testReverseTransform($dateFormat, $timeFormat, $pattern, $input, $output) { $transformer = new DateTimeToLocalizedStringTransformer( @@ -341,10 +342,8 @@ public function testReverseTransformFiveDigitYearsWithTimestamp() $transformer->reverseTransform('20107-03-21 12:34:56'); } - /** - * @requires extension intl - * @requires PHP < 8.5 - */ + #[RequiresPhpExtension('intl')] + #[RequiresPhp('< 8.5')] public function testReverseTransformWrapsIntlErrorsWithErrorLevel() { $errorLevel = ini_set('intl.error_level', \E_WARNING); @@ -358,9 +357,7 @@ public function testReverseTransformWrapsIntlErrorsWithErrorLevel() } } - /** - * @requires extension intl - */ + #[RequiresPhpExtension('intl')] public function testReverseTransformWrapsIntlErrorsWithExceptions() { $initialUseExceptions = ini_set('intl.use_exceptions', 1); @@ -374,10 +371,8 @@ public function testReverseTransformWrapsIntlErrorsWithExceptions() } } - /** - * @requires extension intl - * @requires PHP < 8.5 - */ + #[RequiresPhpExtension('intl')] + #[RequiresPhp('< 8.5')] public function testReverseTransformWrapsIntlErrorsWithExceptionsAndErrorLevel() { $initialUseExceptions = ini_set('intl.use_exceptions', 1); diff --git a/Tests/Extension/Core/DataTransformer/DateTimeToRfc3339TransformerTest.php b/Tests/Extension/Core/DataTransformer/DateTimeToRfc3339TransformerTest.php index c69ba31be..16115af21 100644 --- a/Tests/Extension/Core/DataTransformer/DateTimeToRfc3339TransformerTest.php +++ b/Tests/Extension/Core/DataTransformer/DateTimeToRfc3339TransformerTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer; +use PHPUnit\Framework\Attributes\DataProvider; use Symfony\Component\Form\Exception\TransformationFailedException; use Symfony\Component\Form\Extension\Core\DataTransformer\BaseDateTimeTransformer; use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToRfc3339Transformer; @@ -57,9 +58,7 @@ public static function reverseTransformProvider(): array ]); } - /** - * @dataProvider transformProvider - */ + #[DataProvider('transformProvider')] public function testTransform($fromTz, $toTz, $from, $to) { $transformer = new DateTimeToRfc3339Transformer($fromTz, $toTz); @@ -67,9 +66,7 @@ public function testTransform($fromTz, $toTz, $from, $to) $this->assertSame($to, $transformer->transform(null !== $from ? new \DateTime($from) : null)); } - /** - * @dataProvider transformProvider - */ + #[DataProvider('transformProvider')] public function testTransformDateTimeImmutable($fromTz, $toTz, $from, $to) { $transformer = new DateTimeToRfc3339Transformer($fromTz, $toTz); @@ -84,9 +81,7 @@ public function testTransformRequiresValidDateTime() $transformer->transform('2010-01-01'); } - /** - * @dataProvider reverseTransformProvider - */ + #[DataProvider('reverseTransformProvider')] public function testReverseTransform($toTz, $fromTz, $to, $from) { $transformer = new DateTimeToRfc3339Transformer($toTz, $fromTz); @@ -113,9 +108,7 @@ public function testReverseTransformWithNonExistingDate() $transformer->reverseTransform('2010-04-31T04:05Z'); } - /** - * @dataProvider invalidDateStringProvider - */ + #[DataProvider('invalidDateStringProvider')] public function testReverseTransformExpectsValidDateString($date) { $this->expectException(TransformationFailedException::class); diff --git a/Tests/Extension/Core/DataTransformer/DateTimeToStringTransformerTest.php b/Tests/Extension/Core/DataTransformer/DateTimeToStringTransformerTest.php index f7ef667e7..a2412c4f8 100644 --- a/Tests/Extension/Core/DataTransformer/DateTimeToStringTransformerTest.php +++ b/Tests/Extension/Core/DataTransformer/DateTimeToStringTransformerTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer; +use PHPUnit\Framework\Attributes\DataProvider; use Symfony\Component\Form\Exception\TransformationFailedException; use Symfony\Component\Form\Extension\Core\DataTransformer\BaseDateTimeTransformer; use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToStringTransformer; @@ -64,9 +65,7 @@ public static function dataProvider(): array ]; } - /** - * @dataProvider dataProvider - */ + #[DataProvider('dataProvider')] public function testTransform($format, $output, $input) { $transformer = new DateTimeToStringTransformer('UTC', 'UTC', $format); @@ -114,9 +113,7 @@ public function testTransformExpectsDateTime() $transformer->transform('1234'); } - /** - * @dataProvider dataProvider - */ + #[DataProvider('dataProvider')] public function testReverseTransform($format, $input, $output) { $reverseTransformer = new DateTimeToStringTransformer('UTC', 'UTC', $format); diff --git a/Tests/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformerTest.php b/Tests/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformerTest.php index 92443e201..01fa5282f 100644 --- a/Tests/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformerTest.php +++ b/Tests/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformerTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\Form\Exception\TransformationFailedException; use Symfony\Component\Form\Extension\Core\DataTransformer\IntegerToLocalizedStringTransformer; @@ -82,9 +83,7 @@ public static function transformWithRoundingProvider() ]; } - /** - * @dataProvider transformWithRoundingProvider - */ + #[DataProvider('transformWithRoundingProvider')] public function testTransformWithRounding($input, $output, $roundingMode) { $transformer = new IntegerToLocalizedStringTransformer(null, $roundingMode); @@ -178,9 +177,7 @@ public static function reverseTransformWithRoundingProvider() ]; } - /** - * @dataProvider reverseTransformWithRoundingProvider - */ + #[DataProvider('reverseTransformWithRoundingProvider')] public function testReverseTransformWithRounding($input, $output, $roundingMode) { $transformer = new IntegerToLocalizedStringTransformer(null, $roundingMode); @@ -204,9 +201,7 @@ public function testReverseTransformExpectsValidNumber() $transformer->reverseTransform('foo'); } - /** - * @dataProvider floatNumberProvider - */ + #[DataProvider('floatNumberProvider')] public function testReverseTransformExpectsInteger($number, $locale) { $this->expectException(TransformationFailedException::class); diff --git a/Tests/Extension/Core/DataTransformer/IntlTimeZoneToStringTransformerTest.php b/Tests/Extension/Core/DataTransformer/IntlTimeZoneToStringTransformerTest.php index ca80a2103..ac9d23582 100644 --- a/Tests/Extension/Core/DataTransformer/IntlTimeZoneToStringTransformerTest.php +++ b/Tests/Extension/Core/DataTransformer/IntlTimeZoneToStringTransformerTest.php @@ -11,13 +11,12 @@ namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer; +use PHPUnit\Framework\Attributes\RequiresPhpExtension; use PHPUnit\Framework\TestCase; use Symfony\Component\Form\Exception\TransformationFailedException; use Symfony\Component\Form\Extension\Core\DataTransformer\IntlTimeZoneToStringTransformer; -/** - * @requires extension intl - */ +#[RequiresPhpExtension('intl')] class IntlTimeZoneToStringTransformerTest extends TestCase { public function testSingle() diff --git a/Tests/Extension/Core/DataTransformer/NumberToLocalizedStringTransformerTest.php b/Tests/Extension/Core/DataTransformer/NumberToLocalizedStringTransformerTest.php index f22fa5da3..be50f9a1d 100644 --- a/Tests/Extension/Core/DataTransformer/NumberToLocalizedStringTransformerTest.php +++ b/Tests/Extension/Core/DataTransformer/NumberToLocalizedStringTransformerTest.php @@ -11,6 +11,9 @@ namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\RequiresPhp; +use PHPUnit\Framework\Attributes\RequiresPhpExtension; use PHPUnit\Framework\TestCase; use Symfony\Component\Form\Exception\TransformationFailedException; use Symfony\Component\Form\Extension\Core\DataTransformer\NumberToLocalizedStringTransformer; @@ -56,9 +59,7 @@ public static function provideTransformations() ]; } - /** - * @dataProvider provideTransformations - */ + #[DataProvider('provideTransformations')] public function testTransform($from, $to, $locale) { // Since we test against other locales, we need the full implementation @@ -82,9 +83,7 @@ public static function provideTransformationsWithGrouping() ]; } - /** - * @dataProvider provideTransformationsWithGrouping - */ + #[DataProvider('provideTransformationsWithGrouping')] public function testTransformWithGrouping($from, $to, $locale) { // Since we test against other locales, we need the full implementation @@ -199,9 +198,7 @@ public static function transformWithRoundingProvider() ]; } - /** - * @dataProvider transformWithRoundingProvider - */ + #[DataProvider('transformWithRoundingProvider')] public function testTransformWithRounding($scale, $input, $output, $roundingMode) { // Since we test against "de_AT", we need the full implementation @@ -226,9 +223,7 @@ public function testTransformDoesNotRoundIfNoScale() $this->assertEquals('1234,547', $transformer->transform(1234.547)); } - /** - * @dataProvider provideTransformations - */ + #[DataProvider('provideTransformations')] public function testReverseTransform($to, $from, $locale) { // Since we test against other locales, we need the full implementation @@ -241,9 +236,7 @@ public function testReverseTransform($to, $from, $locale) $this->assertEquals($to, $transformer->reverseTransform($from)); } - /** - * @dataProvider provideTransformationsWithGrouping - */ + #[DataProvider('provideTransformationsWithGrouping')] public function testReverseTransformWithGrouping($to, $from, $locale) { // Since we test against other locales, we need the full implementation @@ -376,9 +369,7 @@ public static function reverseTransformWithRoundingProvider() ]; } - /** - * @dataProvider reverseTransformWithRoundingProvider - */ + #[DataProvider('reverseTransformWithRoundingProvider')] public function testReverseTransformWithRounding($scale, $input, $output, $roundingMode) { $transformer = new NumberToLocalizedStringTransformer($scale, null, $roundingMode); @@ -518,10 +509,9 @@ public function testReverseTransformExpectsValidNumber() } /** - * @dataProvider nanRepresentationProvider - * * @see https://github.com/symfony/symfony/issues/3161 */ + #[DataProvider('nanRepresentationProvider')] public function testReverseTransformDisallowsNaN($nan) { $this->expectException(TransformationFailedException::class); @@ -645,9 +635,7 @@ public function testReverseTransformSmallInt() $this->assertSame(1.0, $transformer->reverseTransform('1')); } - /** - * @dataProvider eNotationProvider - */ + #[DataProvider('eNotationProvider')] public function testReverseTransformENotation($output, $input) { IntlTestHelper::requireFullIntl($this); @@ -659,10 +647,8 @@ public function testReverseTransformENotation($output, $input) $this->assertSame($output, $transformer->reverseTransform($input)); } - /** - * @requires extension intl - * @requires PHP < 8.5 - */ + #[RequiresPhpExtension('intl')] + #[RequiresPhp('< 8.5')] public function testReverseTransformWrapsIntlErrorsWithErrorLevel() { $errorLevel = ini_set('intl.error_level', \E_WARNING); @@ -676,9 +662,7 @@ public function testReverseTransformWrapsIntlErrorsWithErrorLevel() } } - /** - * @requires extension intl - */ + #[RequiresPhpExtension('intl')] public function testReverseTransformWrapsIntlErrorsWithExceptions() { $initialUseExceptions = ini_set('intl.use_exceptions', 1); @@ -692,10 +676,8 @@ public function testReverseTransformWrapsIntlErrorsWithExceptions() } } - /** - * @requires extension intl - * @requires PHP < 8.5 - */ + #[RequiresPhpExtension('intl')] + #[RequiresPhp('< 8.5')] public function testReverseTransformWrapsIntlErrorsWithExceptionsAndErrorLevel() { $initialUseExceptions = ini_set('intl.use_exceptions', 1); diff --git a/Tests/Extension/Core/DataTransformer/PercentToLocalizedStringTransformerTest.php b/Tests/Extension/Core/DataTransformer/PercentToLocalizedStringTransformerTest.php index ca935d564..8c15a49f1 100644 --- a/Tests/Extension/Core/DataTransformer/PercentToLocalizedStringTransformerTest.php +++ b/Tests/Extension/Core/DataTransformer/PercentToLocalizedStringTransformerTest.php @@ -11,6 +11,9 @@ namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\RequiresPhp; +use PHPUnit\Framework\Attributes\RequiresPhpExtension; use PHPUnit\Framework\TestCase; use Symfony\Component\Form\Exception\TransformationFailedException; use Symfony\Component\Form\Extension\Core\DataTransformer\PercentToLocalizedStringTransformer; @@ -191,9 +194,7 @@ public static function reverseTransformWithRoundingProvider(): array ]; } - /** - * @dataProvider reverseTransformWithRoundingProvider - */ + #[DataProvider('reverseTransformWithRoundingProvider')] public function testReverseTransformWithRounding($type, $scale, $input, $output, $roundingMode) { $transformer = new PercentToLocalizedStringTransformer($scale, $type, $roundingMode); @@ -364,9 +365,7 @@ public function testReverseTransformDisallowsCenteredExtraCharacters() $transformer->reverseTransform('12foo3'); } - /** - * @requires extension mbstring - */ + #[RequiresPhpExtension('mbstring')] public function testReverseTransformDisallowsCenteredExtraCharactersMultibyte() { $this->expectException(TransformationFailedException::class); @@ -390,9 +389,7 @@ public function testReverseTransformDisallowsTrailingExtraCharacters() $transformer->reverseTransform('123foo'); } - /** - * @requires extension mbstring - */ + #[RequiresPhpExtension('mbstring')] public function testReverseTransformDisallowsTrailingExtraCharactersMultibyte() { $this->expectException(TransformationFailedException::class); @@ -487,10 +484,8 @@ public function testReverseTransformForHtml5FormatWithScale() $this->assertEquals(0.1234, $transformer->reverseTransform('12.34')); } - /** - * @requires extension intl - * @requires PHP < 8.5 - */ + #[RequiresPhpExtension('intl')] + #[RequiresPhp('< 8.5')] public function testReverseTransformWrapsIntlErrorsWithErrorLevel() { $errorLevel = ini_set('intl.error_level', \E_WARNING); @@ -504,9 +499,7 @@ public function testReverseTransformWrapsIntlErrorsWithErrorLevel() } } - /** - * @requires extension intl - */ + #[RequiresPhpExtension('intl')] public function testReverseTransformWrapsIntlErrorsWithExceptions() { $initialUseExceptions = ini_set('intl.use_exceptions', 1); @@ -520,10 +513,8 @@ public function testReverseTransformWrapsIntlErrorsWithExceptions() } } - /** - * @requires extension intl - * @requires PHP < 8.5 - */ + #[RequiresPhpExtension('intl')] + #[RequiresPhp('< 8.5')] public function testReverseTransformWrapsIntlErrorsWithExceptionsAndErrorLevel() { $initialUseExceptions = ini_set('intl.use_exceptions', 1); diff --git a/Tests/Extension/Core/DataTransformer/StringToFloatTransformerTest.php b/Tests/Extension/Core/DataTransformer/StringToFloatTransformerTest.php index aaea8b298..9fa8c500e 100644 --- a/Tests/Extension/Core/DataTransformer/StringToFloatTransformerTest.php +++ b/Tests/Extension/Core/DataTransformer/StringToFloatTransformerTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\Form\Exception\TransformationFailedException; use Symfony\Component\Form\Extension\Core\DataTransformer\StringToFloatTransformer; @@ -28,9 +29,7 @@ public static function provideTransformations(): array ]; } - /** - * @dataProvider provideTransformations - */ + #[DataProvider('provideTransformations')] public function testTransform($from, $to) { $transformer = new StringToFloatTransformer(); @@ -68,9 +67,7 @@ public static function provideReverseTransformations(): array ]; } - /** - * @dataProvider provideReverseTransformations - */ + #[DataProvider('provideReverseTransformations')] public function testReverseTransform($from, $to, ?int $scale = null) { $transformer = new StringToFloatTransformer($scale); diff --git a/Tests/Extension/Core/DataTransformer/UlidToStringTransformerTest.php b/Tests/Extension/Core/DataTransformer/UlidToStringTransformerTest.php index 7978941b5..adf70d86b 100644 --- a/Tests/Extension/Core/DataTransformer/UlidToStringTransformerTest.php +++ b/Tests/Extension/Core/DataTransformer/UlidToStringTransformerTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\Form\Exception\TransformationFailedException; use Symfony\Component\Form\Extension\Core\DataTransformer\UlidToStringTransformer; @@ -25,9 +26,7 @@ public static function provideValidUlid() ]; } - /** - * @dataProvider provideValidUlid - */ + #[DataProvider('provideValidUlid')] public function testTransform($output, $input) { $transformer = new UlidToStringTransformer(); @@ -53,9 +52,7 @@ public function testTransformExpectsUlid() $transformer->transform('1234'); } - /** - * @dataProvider provideValidUlid - */ + #[DataProvider('provideValidUlid')] public function testReverseTransform($input, $output) { $reverseTransformer = new UlidToStringTransformer(); diff --git a/Tests/Extension/Core/DataTransformer/WeekToArrayTransformerTest.php b/Tests/Extension/Core/DataTransformer/WeekToArrayTransformerTest.php index 67e7f7a36..e73dd4978 100644 --- a/Tests/Extension/Core/DataTransformer/WeekToArrayTransformerTest.php +++ b/Tests/Extension/Core/DataTransformer/WeekToArrayTransformerTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\Form\Exception\TransformationFailedException; use Symfony\Component\Form\Extension\Core\DataTransformer\WeekToArrayTransformer; @@ -31,9 +32,7 @@ public function testTransformEmpty() $this->assertSame(['year' => null, 'week' => null], $transformer->transform(null)); } - /** - * @dataProvider transformationFailuresProvider - */ + #[DataProvider('transformationFailuresProvider')] public function testTransformationFailures($input, string $message) { $this->expectException(TransformationFailedException::class); @@ -89,9 +88,7 @@ public function testReverseTransformEmpty() $this->assertNull($transformer->reverseTransform([])); } - /** - * @dataProvider reverseTransformationFailuresProvider - */ + #[DataProvider('reverseTransformationFailuresProvider')] public function testReverseTransformFailures($input, string $message) { $this->expectException(TransformationFailedException::class); diff --git a/Tests/Extension/Core/EventListener/FixUrlProtocolListenerTest.php b/Tests/Extension/Core/EventListener/FixUrlProtocolListenerTest.php index 038ca9c2e..09483a4b1 100644 --- a/Tests/Extension/Core/EventListener/FixUrlProtocolListenerTest.php +++ b/Tests/Extension/Core/EventListener/FixUrlProtocolListenerTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\EventListener; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\Form\Extension\Core\EventListener\FixUrlProtocolListener; @@ -20,9 +21,7 @@ class FixUrlProtocolListenerTest extends TestCase { - /** - * @dataProvider provideUrlToFix - */ + #[DataProvider('provideUrlToFix')] public function testFixUrl($data) { $form = new Form(new FormConfigBuilder('name', null, new EventDispatcher())); @@ -46,9 +45,7 @@ public static function provideUrlToFix() ]; } - /** - * @dataProvider provideUrlToSkip - */ + #[DataProvider('provideUrlToSkip')] public function testSkipUrl($url) { $form = new Form(new FormConfigBuilder('name', null, new EventDispatcher())); diff --git a/Tests/Extension/Core/EventListener/MergeCollectionListenerTestCase.php b/Tests/Extension/Core/EventListener/MergeCollectionListenerTestCase.php index 7070db995..a90a11d1a 100644 --- a/Tests/Extension/Core/EventListener/MergeCollectionListenerTestCase.php +++ b/Tests/Extension/Core/EventListener/MergeCollectionListenerTestCase.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\EventListener; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\Form\Exception\UnexpectedTypeException; use Symfony\Component\Form\Extension\Core\EventListener\MergeCollectionListener; @@ -56,9 +57,7 @@ public static function getBooleanMatrix2() abstract protected function getData(array $data); - /** - * @dataProvider getBooleanMatrix1 - */ + #[DataProvider('getBooleanMatrix1')] public function testAddExtraEntriesIfAllowAdd($allowDelete) { $originalData = $this->getData([1 => 'second']); @@ -80,9 +79,7 @@ public function testAddExtraEntriesIfAllowAdd($allowDelete) $this->assertEquals($newData, $event->getData()); } - /** - * @dataProvider getBooleanMatrix1 - */ + #[DataProvider('getBooleanMatrix1')] public function testAddExtraEntriesIfAllowAddDontOverwriteExistingIndices($allowDelete) { $originalData = $this->getData([1 => 'first']); @@ -104,9 +101,7 @@ public function testAddExtraEntriesIfAllowAddDontOverwriteExistingIndices($allow $this->assertEquals($this->getData([1 => 'first', 2 => 'second']), $event->getData()); } - /** - * @dataProvider getBooleanMatrix1 - */ + #[DataProvider('getBooleanMatrix1')] public function testDoNothingIfNotAllowAdd($allowDelete) { $originalDataArray = [1 => 'second']; @@ -129,9 +124,7 @@ public function testDoNothingIfNotAllowAdd($allowDelete) $this->assertEquals($this->getData($originalDataArray), $event->getData()); } - /** - * @dataProvider getBooleanMatrix1 - */ + #[DataProvider('getBooleanMatrix1')] public function testRemoveMissingEntriesIfAllowDelete($allowAdd) { $originalData = $this->getData([0 => 'first', 1 => 'second', 2 => 'third']); @@ -153,9 +146,7 @@ public function testRemoveMissingEntriesIfAllowDelete($allowAdd) $this->assertEquals($newData, $event->getData()); } - /** - * @dataProvider getBooleanMatrix1 - */ + #[DataProvider('getBooleanMatrix1')] public function testDoNothingIfNotAllowDelete($allowAdd) { $originalDataArray = [0 => 'first', 1 => 'second', 2 => 'third']; @@ -178,9 +169,7 @@ public function testDoNothingIfNotAllowDelete($allowAdd) $this->assertEquals($this->getData($originalDataArray), $event->getData()); } - /** - * @dataProvider getBooleanMatrix2 - */ + #[DataProvider('getBooleanMatrix2')] public function testRequireArrayOrTraversable($allowAdd, $allowDelete) { $this->expectException(UnexpectedTypeException::class); @@ -205,9 +194,7 @@ public function testDealWithNullData() $this->assertSame($originalData, $event->getData()); } - /** - * @dataProvider getBooleanMatrix1 - */ + #[DataProvider('getBooleanMatrix1')] public function testDealWithNullOriginalDataIfAllowAdd($allowDelete) { $originalData = null; @@ -223,9 +210,7 @@ public function testDealWithNullOriginalDataIfAllowAdd($allowDelete) $this->assertSame($newData, $event->getData()); } - /** - * @dataProvider getBooleanMatrix1 - */ + #[DataProvider('getBooleanMatrix1')] public function testDontDealWithNullOriginalDataIfNotAllowAdd($allowDelete) { $originalData = null; diff --git a/Tests/Extension/Core/EventListener/ResizeFormListenerTest.php b/Tests/Extension/Core/EventListener/ResizeFormListenerTest.php index 390f6b04a..e185ffb62 100644 --- a/Tests/Extension/Core/EventListener/ResizeFormListenerTest.php +++ b/Tests/Extension/Core/EventListener/ResizeFormListenerTest.php @@ -12,6 +12,8 @@ namespace Symfony\Component\Form\Tests\Extension\Core\EventListener; use Doctrine\Common\Collections\ArrayCollection; +use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\IgnoreDeprecations; use PHPUnit\Framework\TestCase; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\Form\AbstractType; @@ -43,9 +45,8 @@ protected function getBuilder($name = 'name') return new FormBuilder($name, null, new EventDispatcher(), $this->factory); } - /** - * @group legacy - */ + #[IgnoreDeprecations] + #[Group('legacy')] public function testPreSetDataResizesForm() { $this->builder->add($this->getBuilder('0')); @@ -93,9 +94,8 @@ public function testPostSetDataResizesForm() $this->assertSame('string', $form->get('2')->getData()); } - /** - * @group legacy - */ + #[IgnoreDeprecations] + #[Group('legacy')] public function testPreSetDataRequiresArrayOrTraversable() { $this->expectException(UnexpectedTypeException::class); @@ -119,9 +119,8 @@ public function testPostSetDataRequiresArrayOrTraversable() $listener->postSetData($event); } - /** - * @group legacy - */ + #[IgnoreDeprecations] + #[Group('legacy')] public function testPreSetDataDealsWithNullData() { $data = null; diff --git a/Tests/Extension/Core/Type/CheckboxTypeTest.php b/Tests/Extension/Core/Type/CheckboxTypeTest.php index 69fd0fd60..7601d3743 100644 --- a/Tests/Extension/Core/Type/CheckboxTypeTest.php +++ b/Tests/Extension/Core/Type/CheckboxTypeTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\Type; +use PHPUnit\Framework\Attributes\DataProvider; use Symfony\Component\Form\CallbackTransformer; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException; @@ -140,9 +141,7 @@ public function testSubmitWithEmptyValueAndTrueChecked() $this->assertSame('', $form->getViewData()); } - /** - * @dataProvider provideCustomModelTransformerData - */ + #[DataProvider('provideCustomModelTransformerData')] public function testCustomModelTransformer($data, $checked) { // present a binary status field as a checkbox @@ -171,9 +170,7 @@ public static function provideCustomModelTransformerData(): array ]; } - /** - * @dataProvider provideCustomFalseValues - */ + #[DataProvider('provideCustomFalseValues')] public function testCustomFalseValues($falseValue) { $form = $this->factory->create(static::TESTED_TYPE, null, [ diff --git a/Tests/Extension/Core/Type/ChoiceTypePerformanceTest.php b/Tests/Extension/Core/Type/ChoiceTypePerformanceTest.php index 3616a139c..e73a97351 100644 --- a/Tests/Extension/Core/Type/ChoiceTypePerformanceTest.php +++ b/Tests/Extension/Core/Type/ChoiceTypePerformanceTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\Type; +use PHPUnit\Framework\Attributes\Group; use Symfony\Component\Form\Test\FormPerformanceTestCase; /** @@ -21,9 +22,8 @@ class ChoiceTypePerformanceTest extends FormPerformanceTestCase /** * This test case is realistic in collection forms where each * row contains the same choice field. - * - * @group benchmark */ + #[Group('benchmark')] public function testSameChoiceFieldCreatedMultipleTimes() { $this->setMaxRunningTime(1); diff --git a/Tests/Extension/Core/Type/ChoiceTypeTest.php b/Tests/Extension/Core/Type/ChoiceTypeTest.php index 977a8707c..99be68fe3 100644 --- a/Tests/Extension/Core/Type/ChoiceTypeTest.php +++ b/Tests/Extension/Core/Type/ChoiceTypeTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\Type; +use PHPUnit\Framework\Attributes\DataProvider; use Symfony\Component\Form\ChoiceList\Loader\CallbackChoiceLoader; use Symfony\Component\Form\ChoiceList\View\ChoiceGroupView; use Symfony\Component\Form\ChoiceList\View\ChoiceView; @@ -1671,9 +1672,7 @@ public function testPlaceholderIsEmptyStringByDefaultIfNotRequired() $this->assertSame('', $view->vars['placeholder']); } - /** - * @dataProvider getOptionsWithPlaceholder - */ + #[DataProvider('getOptionsWithPlaceholder')] public function testPassPlaceholderToView($multiple, $expanded, $required, $placeholder, $placeholderViewValue, $placeholderAttr, $placeholderAttrViewValue) { $view = $this->factory->create(static::TESTED_TYPE, null, [ @@ -1691,9 +1690,7 @@ public function testPassPlaceholderToView($multiple, $expanded, $required, $plac $this->assertFalse($view->vars['placeholder_in_choices']); } - /** - * @dataProvider getOptionsWithPlaceholder - */ + #[DataProvider('getOptionsWithPlaceholder')] public function testDontPassPlaceholderIfContainedInChoices($multiple, $expanded, $required, $placeholder, $placeholderViewValue, $placeholderAttr, $placeholderAttrViewValue) { $view = $this->factory->create(static::TESTED_TYPE, null, [ @@ -1946,9 +1943,7 @@ public function testCustomChoiceTypeDoesNotInheritChoiceLabels() $this->assertNull($form->get('subChoice')->getConfig()->getOption('choice_label')); } - /** - * @dataProvider invalidNestedValueTestMatrix - */ + #[DataProvider('invalidNestedValueTestMatrix')] public function testSubmitInvalidNestedValue($multiple, $expanded, $submissionData) { $form = $this->factory->create(static::TESTED_TYPE, null, [ @@ -2114,9 +2109,7 @@ public function testSubFormTranslationDomain() $this->assertSame('choice_translation_domain', $form->children[1]->vars['translation_domain']); } - /** - * @dataProvider provideTrimCases - */ + #[DataProvider('provideTrimCases')] public function testTrimIsDisabled($multiple, $expanded) { $form = $this->factory->create(static::TESTED_TYPE, null, [ @@ -2141,9 +2134,7 @@ public function testTrimIsDisabled($multiple, $expanded) } } - /** - * @dataProvider provideTrimCases - */ + #[DataProvider('provideTrimCases')] public function testSubmitValueWithWhiteSpace($multiple, $expanded) { $valueWhitWhiteSpace = '1 '; @@ -2172,9 +2163,7 @@ public static function provideTrimCases() ]; } - /** - * @dataProvider expandedIsEmptyWhenNoRealChoiceIsSelectedProvider - */ + #[DataProvider('expandedIsEmptyWhenNoRealChoiceIsSelectedProvider')] public function testExpandedIsEmptyWhenNoRealChoiceIsSelected($expected, $submittedData, $multiple, $required, $placeholder) { $options = [ diff --git a/Tests/Extension/Core/Type/ColorTypeTest.php b/Tests/Extension/Core/Type/ColorTypeTest.php index 5cfab193e..64a6a71eb 100644 --- a/Tests/Extension/Core/Type/ColorTypeTest.php +++ b/Tests/Extension/Core/Type/ColorTypeTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\Type; +use PHPUnit\Framework\Attributes\DataProvider; use Symfony\Component\Form\Extension\Core\Type\ColorType; use Symfony\Component\Form\FormError; use Symfony\Component\Form\FormErrorIterator; @@ -19,9 +20,7 @@ final class ColorTypeTest extends BaseTypeTestCase { public const TESTED_TYPE = ColorType::class; - /** - * @dataProvider validationShouldPassProvider - */ + #[DataProvider('validationShouldPassProvider')] public function testValidationShouldPass(bool $html5, ?string $submittedValue) { $form = $this->factory->create(static::TESTED_TYPE, null, [ @@ -53,9 +52,7 @@ public static function validationShouldPassProvider(): array ]; } - /** - * @dataProvider validationShouldFailProvider - */ + #[DataProvider('validationShouldFailProvider')] public function testValidationShouldFail(string $expectedValueParameterValue, ?string $submittedValue, bool $trim = true) { $form = $this->factory->create(static::TESTED_TYPE, null, [ diff --git a/Tests/Extension/Core/Type/CountryTypeTest.php b/Tests/Extension/Core/Type/CountryTypeTest.php index 171a7491b..362eb39d5 100644 --- a/Tests/Extension/Core/Type/CountryTypeTest.php +++ b/Tests/Extension/Core/Type/CountryTypeTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\Type; +use PHPUnit\Framework\Attributes\RequiresPhpExtension; use Symfony\Component\Form\ChoiceList\View\ChoiceView; use Symfony\Component\Form\Extension\Core\Type\CountryType; use Symfony\Component\Intl\Util\IntlTestHelper; @@ -39,9 +40,7 @@ public function testCountriesAreSelectable() $this->assertContainsEquals(new ChoiceView('MY', 'MY', 'Malaysia'), $choices); } - /** - * @requires extension intl - */ + #[RequiresPhpExtension('intl')] public function testChoiceTranslationLocaleOption() { $choices = $this->factory @@ -74,9 +73,7 @@ public function testAlpha3Option() $this->assertContainsEquals(new ChoiceView('MYS', 'MYS', 'Malaysia'), $choices); } - /** - * @requires extension intl - */ + #[RequiresPhpExtension('intl')] public function testChoiceTranslationLocaleAndAlpha3Option() { $choices = $this->factory diff --git a/Tests/Extension/Core/Type/CurrencyTypeTest.php b/Tests/Extension/Core/Type/CurrencyTypeTest.php index e5a140392..8dbdace1a 100644 --- a/Tests/Extension/Core/Type/CurrencyTypeTest.php +++ b/Tests/Extension/Core/Type/CurrencyTypeTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\Type; +use PHPUnit\Framework\Attributes\RequiresPhpExtension; use Symfony\Component\Form\ChoiceList\View\ChoiceView; use Symfony\Component\Form\Extension\Core\Type\CurrencyType; use Symfony\Component\Intl\Util\IntlTestHelper; @@ -36,9 +37,7 @@ public function testCurrenciesAreSelectable() $this->assertContainsEquals(new ChoiceView('SIT', 'SIT', 'Slovenian Tolar'), $choices); } - /** - * @requires extension intl - */ + #[RequiresPhpExtension('intl')] public function testChoiceTranslationLocaleOption() { $choices = $this->factory diff --git a/Tests/Extension/Core/Type/DateIntervalTypeTest.php b/Tests/Extension/Core/Type/DateIntervalTypeTest.php index 58e242234..006676c39 100644 --- a/Tests/Extension/Core/Type/DateIntervalTypeTest.php +++ b/Tests/Extension/Core/Type/DateIntervalTypeTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\Type; +use PHPUnit\Framework\Attributes\DataProvider; use Symfony\Component\Form\Extension\Core\Type\DateIntervalType; use Symfony\Component\Form\FormError; use Symfony\Component\Form\FormInterface; @@ -424,9 +425,7 @@ public function testSubmitNullUsesDefaultEmptyData($emptyData = [], $expectedDat $this->assertSame($expectedData, $form->getData()); } - /** - * @dataProvider provideEmptyData - */ + #[DataProvider('provideEmptyData')] public function testSubmitNullUsesDateEmptyData($widget, $emptyData, $expectedData) { $form = $this->factory->create(static::TESTED_TYPE, null, [ diff --git a/Tests/Extension/Core/Type/DateTimeTypeTest.php b/Tests/Extension/Core/Type/DateTimeTypeTest.php index 5067bb05e..d20561277 100644 --- a/Tests/Extension/Core/Type/DateTimeTypeTest.php +++ b/Tests/Extension/Core/Type/DateTimeTypeTest.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Form\Tests\Extension\Core\Type; +use PHPUnit\Framework\Attributes\DataProvider; +use Symfony\Component\Clock\DatePoint; use Symfony\Component\Form\Exception\LogicException; use Symfony\Component\Form\Extension\Core\Type\DateTimeType; use Symfony\Component\Form\FormError; @@ -62,6 +64,37 @@ public function testSubmitDateTime() $this->assertEquals($dateTime, $form->getData()); } + public function testSubmitDatePoint() + { + $form = $this->factory->create(static::TESTED_TYPE, null, [ + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'date_widget' => 'choice', + 'years' => [2010], + 'time_widget' => 'choice', + 'input' => 'date_point', + ]); + + $input = [ + 'date' => [ + 'day' => '2', + 'month' => '6', + 'year' => '2010', + ], + 'time' => [ + 'hour' => '3', + 'minute' => '4', + ], + ]; + + $form->submit($input); + + $this->assertInstanceOf(DatePoint::class, $form->getData()); + $datePoint = DatePoint::createFromMutable(new \DateTime('2010-06-02 03:04:00 UTC')); + $this->assertEquals($datePoint, $form->getData()); + $this->assertEquals($input, $form->getViewData()); + } + public function testSubmitDateTimeImmutable() { $form = $this->factory->create(static::TESTED_TYPE, null, [ @@ -701,9 +734,7 @@ public function testSubmitNullUsesDefaultEmptyData($emptyData = [], $expectedDat $this->assertSame($expectedData, $form->getData()); } - /** - * @dataProvider provideEmptyData - */ + #[DataProvider('provideEmptyData')] public function testSubmitNullUsesDateEmptyData($widget, $emptyData, $expectedData) { $form = $this->factory->create(static::TESTED_TYPE, null, [ diff --git a/Tests/Extension/Core/Type/DateTypeTest.php b/Tests/Extension/Core/Type/DateTypeTest.php index 5b9d9d041..c640997a1 100644 --- a/Tests/Extension/Core/Type/DateTypeTest.php +++ b/Tests/Extension/Core/Type/DateTypeTest.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Form\Tests\Extension\Core\Type; +use PHPUnit\Framework\Attributes\DataProvider; +use Symfony\Component\Clock\DatePoint; use Symfony\Component\Form\ChoiceList\View\ChoiceView; use Symfony\Component\Form\Exception\LogicException; use Symfony\Component\Form\Extension\Core\Type\DateType; @@ -115,6 +117,27 @@ public function testSubmitFromSingleTextDateTime() $this->assertEquals('02.06.2010', $form->getViewData()); } + public function testSubmitFromSingleTextDatePoint() + { + if (!class_exists(DatePoint::class)) { + self::markTestSkipped('The DatePoint class is not available.'); + } + + $form = $this->factory->create(static::TESTED_TYPE, null, [ + 'html5' => false, + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'widget' => 'single_text', + 'input' => 'date_point', + ]); + + $form->submit('2010-06-02'); + + $this->assertInstanceOf(DatePoint::class, $form->getData()); + $this->assertEquals(DatePoint::createFromMutable(new \DateTime('2010-06-02 UTC')), $form->getData()); + $this->assertEquals('2010-06-02', $form->getViewData()); + } + public function testSubmitFromSingleTextDateTimeImmutable() { // we test against "de_DE", so we need the full implementation @@ -396,9 +419,7 @@ public function testSubmitFromInputRawDifferentPattern() $this->assertEquals('06*2010*02', $form->getViewData()); } - /** - * @dataProvider provideDateFormats - */ + #[DataProvider('provideDateFormats')] public function testDatePatternWithFormatOption($format, $pattern) { $view = $this->factory->create(static::TESTED_TYPE, null, [ @@ -955,9 +976,7 @@ public static function provideCompoundWidgets() ]; } - /** - * @dataProvider provideCompoundWidgets - */ + #[DataProvider('provideCompoundWidgets')] public function testYearErrorsBubbleUp($widget) { $error = new FormError('Invalid!'); @@ -970,9 +989,7 @@ public function testYearErrorsBubbleUp($widget) $this->assertSame([$error], iterator_to_array($form->getErrors())); } - /** - * @dataProvider provideCompoundWidgets - */ + #[DataProvider('provideCompoundWidgets')] public function testMonthErrorsBubbleUp($widget) { $error = new FormError('Invalid!'); @@ -985,9 +1002,7 @@ public function testMonthErrorsBubbleUp($widget) $this->assertSame([$error], iterator_to_array($form->getErrors())); } - /** - * @dataProvider provideCompoundWidgets - */ + #[DataProvider('provideCompoundWidgets')] public function testDayErrorsBubbleUp($widget) { $error = new FormError('Invalid!'); @@ -1086,9 +1101,7 @@ public function testSubmitNullUsesDefaultEmptyData($emptyData = [], $expectedDat $this->assertSame($expectedData, $form->getData()); } - /** - * @dataProvider provideEmptyData - */ + #[DataProvider('provideEmptyData')] public function testSubmitNullUsesDateEmptyData($widget, $emptyData, $expectedData) { $form = $this->factory->create(static::TESTED_TYPE, null, [ diff --git a/Tests/Extension/Core/Type/EnumTypeTest.php b/Tests/Extension/Core/Type/EnumTypeTest.php index 045872069..1c2be3476 100644 --- a/Tests/Extension/Core/Type/EnumTypeTest.php +++ b/Tests/Extension/Core/Type/EnumTypeTest.php @@ -11,6 +11,7 @@ namespace Extension\Core\Type; +use PHPUnit\Framework\Attributes\DataProvider; use Symfony\Component\Form\Extension\Core\Type\EnumType; use Symfony\Component\Form\Tests\Extension\Core\Type\BaseTypeTestCase; use Symfony\Component\Form\Tests\Fixtures\Answer; @@ -48,9 +49,7 @@ public function testInvalidClassOptionType() ]); } - /** - * @dataProvider provideSingleSubmitData - */ + #[DataProvider('provideSingleSubmitData')] public function testSubmitSingleNonExpanded(string $class, string $submittedData, \UnitEnum $expectedData) { $form = $this->factory->create($this->getTestedType(), null, [ @@ -66,9 +65,7 @@ public function testSubmitSingleNonExpanded(string $class, string $submittedData $this->assertTrue($form->isSynchronized()); } - /** - * @dataProvider provideSingleSubmitData - */ + #[DataProvider('provideSingleSubmitData')] public function testSubmitSingleExpanded(string $class, string $submittedData, \UnitEnum $expectedData) { $form = $this->factory->create($this->getTestedType(), null, [ @@ -190,9 +187,7 @@ public function testSubmitMultipleChoiceExpandedWithEmptyData() $this->assertSame([Suit::Spades], $form->getData()); } - /** - * @dataProvider provideMultiSubmitData - */ + #[DataProvider('provideMultiSubmitData')] public function testSubmitMultipleNonExpanded(string $class, array $submittedValues, array $expectedValues) { $form = $this->factory->create($this->getTestedType(), null, [ @@ -208,9 +203,7 @@ public function testSubmitMultipleNonExpanded(string $class, array $submittedVal $this->assertTrue($form->isSynchronized()); } - /** - * @dataProvider provideMultiSubmitData - */ + #[DataProvider('provideMultiSubmitData')] public function testSubmitMultipleExpanded(string $class, array $submittedValues, array $expectedValues) { $form = $this->factory->create($this->getTestedType(), null, [ diff --git a/Tests/Extension/Core/Type/ExtendedChoiceTypeTest.php b/Tests/Extension/Core/Type/ExtendedChoiceTypeTest.php index 122ff44b5..b449be41c 100644 --- a/Tests/Extension/Core/Type/ExtendedChoiceTypeTest.php +++ b/Tests/Extension/Core/Type/ExtendedChoiceTypeTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\Type; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\Form\Forms; use Symfony\Component\Form\Tests\Fixtures\ChoiceTypeExtension; @@ -18,9 +19,7 @@ class ExtendedChoiceTypeTest extends TestCase { - /** - * @dataProvider provideTestedTypes - */ + #[DataProvider('provideTestedTypes')] public function testChoicesAreOverridden($type) { ChoiceTypeExtension::$extendedType = $type; @@ -38,9 +37,7 @@ public function testChoicesAreOverridden($type) $this->assertSame('b', $choices[1]->value); } - /** - * @dataProvider provideTestedTypes - */ + #[DataProvider('provideTestedTypes')] public function testChoiceLoaderIsOverridden($type) { LazyChoiceTypeExtension::$extendedType = $type; diff --git a/Tests/Extension/Core/Type/FileTypeTest.php b/Tests/Extension/Core/Type/FileTypeTest.php index 85907b695..55cf4cda3 100644 --- a/Tests/Extension/Core/Type/FileTypeTest.php +++ b/Tests/Extension/Core/Type/FileTypeTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\Type; +use PHPUnit\Framework\Attributes\DataProvider; use Symfony\Component\Form\Extension\Core\CoreExtension; use Symfony\Component\Form\Extension\Core\Type\FileType; use Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationRequestHandler; @@ -41,9 +42,7 @@ public function testSetData() $this->assertSame($data, $form->getData()); } - /** - * @dataProvider requestHandlerProvider - */ + #[DataProvider('requestHandlerProvider')] public function testSubmit(RequestHandlerInterface $requestHandler) { $form = $this->factory->createBuilder(static::TESTED_TYPE)->setRequestHandler($requestHandler)->getForm(); @@ -54,9 +53,7 @@ public function testSubmit(RequestHandlerInterface $requestHandler) $this->assertSame($data, $form->getData()); } - /** - * @dataProvider requestHandlerProvider - */ + #[DataProvider('requestHandlerProvider')] public function testSetDataMultiple(RequestHandlerInterface $requestHandler) { $form = $this->factory->createBuilder(static::TESTED_TYPE, null, [ @@ -72,9 +69,7 @@ public function testSetDataMultiple(RequestHandlerInterface $requestHandler) $this->assertSame($data, $form->getData()); } - /** - * @dataProvider requestHandlerProvider - */ + #[DataProvider('requestHandlerProvider')] public function testSubmitMultiple(RequestHandlerInterface $requestHandler) { $form = $this->factory->createBuilder(static::TESTED_TYPE, null, [ @@ -94,9 +89,7 @@ public function testSubmitMultiple(RequestHandlerInterface $requestHandler) $this->assertArrayHasKey('multiple', $view->vars['attr']); } - /** - * @dataProvider requestHandlerProvider - */ + #[DataProvider('requestHandlerProvider')] public function testDontPassValueToView(RequestHandlerInterface $requestHandler) { $form = $this->factory->createBuilder(static::TESTED_TYPE)->setRequestHandler($requestHandler)->getForm(); @@ -133,9 +126,7 @@ public function testSubmitNullWhenMultiple() $this->assertSame([], $form->getViewData()); } - /** - * @dataProvider requestHandlerProvider - */ + #[DataProvider('requestHandlerProvider')] public function testSubmittedFilePathsAreDropped(RequestHandlerInterface $requestHandler) { $form = $this->factory->createBuilder(static::TESTED_TYPE)->setRequestHandler($requestHandler)->getForm(); @@ -146,9 +137,7 @@ public function testSubmittedFilePathsAreDropped(RequestHandlerInterface $reques $this->assertSame('', $form->getViewData()); } - /** - * @dataProvider requestHandlerProvider - */ + #[DataProvider('requestHandlerProvider')] public function testMultipleSubmittedFilePathsAreDropped(RequestHandlerInterface $requestHandler) { $form = $this->factory @@ -166,9 +155,7 @@ public function testMultipleSubmittedFilePathsAreDropped(RequestHandlerInterface $this->assertCount(1, $form->getData()); } - /** - * @dataProvider requestHandlerProvider - */ + #[DataProvider('requestHandlerProvider')] public function testSubmitNonArrayValueWhenMultiple(RequestHandlerInterface $requestHandler) { $form = $this->factory @@ -192,9 +179,7 @@ public static function requestHandlerProvider(): array ]; } - /** - * @dataProvider uploadFileErrorCodes - */ + #[DataProvider('uploadFileErrorCodes')] public function testFailedFileUploadIsTurnedIntoFormErrorUsingHttpFoundationRequestHandler($errorCode, $expectedErrorMessage) { $requestHandler = new HttpFoundationRequestHandler(); @@ -212,9 +197,7 @@ public function testFailedFileUploadIsTurnedIntoFormErrorUsingHttpFoundationRequ } } - /** - * @dataProvider uploadFileErrorCodes - */ + #[DataProvider('uploadFileErrorCodes')] public function testFailedFileUploadIsTurnedIntoFormErrorUsingNativeRequestHandler($errorCode, $expectedErrorMessage) { $form = $this->factory @@ -237,9 +220,7 @@ public function testFailedFileUploadIsTurnedIntoFormErrorUsingNativeRequestHandl } } - /** - * @dataProvider uploadFileErrorCodes - */ + #[DataProvider('uploadFileErrorCodes')] public function testMultipleSubmittedFailedFileUploadsAreTurnedIntoFormErrorUsingHttpFoundationRequestHandler($errorCode, $expectedErrorMessage) { $requestHandler = new HttpFoundationRequestHandler(); @@ -264,9 +245,7 @@ public function testMultipleSubmittedFailedFileUploadsAreTurnedIntoFormErrorUsin } } - /** - * @dataProvider uploadFileErrorCodes - */ + #[DataProvider('uploadFileErrorCodes')] public function testMultipleSubmittedFailedFileUploadsAreTurnedIntoFormErrorUsingNativeRequestHandler($errorCode, $expectedErrorMessage) { $form = $this->factory diff --git a/Tests/Extension/Core/Type/IntegerTypeTest.php b/Tests/Extension/Core/Type/IntegerTypeTest.php index 9a689d58f..65a695f42 100644 --- a/Tests/Extension/Core/Type/IntegerTypeTest.php +++ b/Tests/Extension/Core/Type/IntegerTypeTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\Type; +use PHPUnit\Framework\Attributes\RequiresPhpExtension; use Symfony\Component\Form\Extension\Core\Type\IntegerType; use Symfony\Component\Intl\Util\IntlTestHelper; @@ -29,12 +30,12 @@ protected function setUp(): void protected function tearDown(): void { - \Locale::setDefault($this->previousLocale); + if (isset($this->defaultLocale)) { + \Locale::setDefault($this->defaultLocale); + } } - /** - * @requires extension intl - */ + #[RequiresPhpExtension('intl')] public function testArabicLocale() { \Locale::setDefault('ar'); @@ -46,9 +47,7 @@ public function testArabicLocale() $this->assertSame('123456', $form->getViewData()); } - /** - * @requires extension intl - */ + #[RequiresPhpExtension('intl')] public function testArabicLocaleNonHtml5() { \Locale::setDefault('ar'); diff --git a/Tests/Extension/Core/Type/LanguageTypeTest.php b/Tests/Extension/Core/Type/LanguageTypeTest.php index 50bd373a0..1c1570e36 100644 --- a/Tests/Extension/Core/Type/LanguageTypeTest.php +++ b/Tests/Extension/Core/Type/LanguageTypeTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\Type; +use PHPUnit\Framework\Attributes\RequiresPhpExtension; use Symfony\Component\Form\ChoiceList\View\ChoiceView; use Symfony\Component\Form\Exception\LogicException; use Symfony\Component\Form\Extension\Core\Type\LanguageType; @@ -37,9 +38,7 @@ public function testCountriesAreSelectable() $this->assertContainsEquals(new ChoiceView('my', 'my', 'Burmese'), $choices); } - /** - * @requires extension intl - */ + #[RequiresPhpExtension('intl')] public function testChoiceTranslationLocaleOption() { $choices = $this->factory @@ -69,9 +68,7 @@ public function testAlpha3Option() $this->assertNotContainsEquals(new ChoiceView('my', 'my', 'Burmese'), $choices); } - /** - * @requires extension intl - */ + #[RequiresPhpExtension('intl')] public function testChoiceTranslationLocaleAndAlpha3Option() { $choices = $this->factory @@ -88,9 +85,7 @@ public function testChoiceTranslationLocaleAndAlpha3Option() $this->assertNotContainsEquals(new ChoiceView('my', 'my', 'бірманська'), $choices); } - /** - * @requires extension intl - */ + #[RequiresPhpExtension('intl')] public function testChoiceSelfTranslationOption() { $choices = $this->factory @@ -108,9 +103,7 @@ public function testChoiceSelfTranslationOption() $this->assertContainsEquals(new ChoiceView('zh', 'zh', '中文'), $choices); } - /** - * @requires extension intl - */ + #[RequiresPhpExtension('intl')] public function testChoiceSelfTranslationAndAlpha3Options() { $choices = $this->factory diff --git a/Tests/Extension/Core/Type/LocaleTypeTest.php b/Tests/Extension/Core/Type/LocaleTypeTest.php index 381cc55be..97dbe0b2f 100644 --- a/Tests/Extension/Core/Type/LocaleTypeTest.php +++ b/Tests/Extension/Core/Type/LocaleTypeTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\Type; +use PHPUnit\Framework\Attributes\RequiresPhpExtension; use Symfony\Component\Form\ChoiceList\View\ChoiceView; use Symfony\Component\Form\Extension\Core\Type\LocaleType; use Symfony\Component\Intl\Util\IntlTestHelper; @@ -36,9 +37,7 @@ public function testLocalesAreSelectable() $this->assertContainsEquals(new ChoiceView('zh_Hant_HK', 'zh_Hant_HK', 'Chinese (Traditional, Hong Kong SAR China)'), $choices); } - /** - * @requires extension intl - */ + #[RequiresPhpExtension('intl')] public function testChoiceTranslationLocaleOption() { $choices = $this->factory diff --git a/Tests/Extension/Core/Type/MoneyTypeTest.php b/Tests/Extension/Core/Type/MoneyTypeTest.php index 41d75346a..88d7eb54a 100644 --- a/Tests/Extension/Core/Type/MoneyTypeTest.php +++ b/Tests/Extension/Core/Type/MoneyTypeTest.php @@ -34,7 +34,9 @@ protected function setUp(): void protected function tearDown(): void { - \Locale::setDefault($this->defaultLocale); + if (isset($this->defaultLocale)) { + \Locale::setDefault($this->defaultLocale); + } } public function testPassMoneyPatternToView() diff --git a/Tests/Extension/Core/Type/NumberTypeTest.php b/Tests/Extension/Core/Type/NumberTypeTest.php index 172096422..45f9192f1 100644 --- a/Tests/Extension/Core/Type/NumberTypeTest.php +++ b/Tests/Extension/Core/Type/NumberTypeTest.php @@ -35,7 +35,9 @@ protected function setUp(): void protected function tearDown(): void { - \Locale::setDefault($this->defaultLocale); + if (isset($this->defaultLocale)) { + \Locale::setDefault($this->defaultLocale); + } } public function testDefaultFormatting() diff --git a/Tests/Extension/Core/Type/PercentTypeTest.php b/Tests/Extension/Core/Type/PercentTypeTest.php index 90d02f8f1..909afb6fd 100644 --- a/Tests/Extension/Core/Type/PercentTypeTest.php +++ b/Tests/Extension/Core/Type/PercentTypeTest.php @@ -34,7 +34,9 @@ protected function setUp(): void protected function tearDown(): void { - \Locale::setDefault($this->defaultLocale); + if (isset($this->defaultLocale)) { + \Locale::setDefault($this->defaultLocale); + } } public function testSubmitWithRoundingMode() diff --git a/Tests/Extension/Core/Type/RepeatedTypeTest.php b/Tests/Extension/Core/Type/RepeatedTypeTest.php index 2d19a0613..1bdfe52f7 100644 --- a/Tests/Extension/Core/Type/RepeatedTypeTest.php +++ b/Tests/Extension/Core/Type/RepeatedTypeTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\Type; +use PHPUnit\Framework\Attributes\DataProvider; use Symfony\Component\Form\Extension\Core\Type\RepeatedType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\Form; @@ -92,9 +93,7 @@ public function testMappedOverridesDefault() $this->assertTrue($form['second']->getConfig()->getMapped()); } - /** - * @dataProvider notMappedConfigurationKeys - */ + #[DataProvider('notMappedConfigurationKeys')] public function testNotMappedInnerIsOverridden($configurationKey) { $form = $this->factory->create(static::TESTED_TYPE, null, [ @@ -190,9 +189,7 @@ public function testSetOptionsPerChildAndOverwrite() $this->assertTrue($form['second']->isRequired()); } - /** - * @dataProvider emptyDataProvider - */ + #[DataProvider('emptyDataProvider')] public function testSubmitNullForTextTypeWithEmptyDataOptionSetToEmptyString($emptyData, $submittedData, $expected) { $form = $this->factory->create(static::TESTED_TYPE, null, [ diff --git a/Tests/Extension/Core/Type/TextTypeTest.php b/Tests/Extension/Core/Type/TextTypeTest.php index 483215168..043b69b58 100644 --- a/Tests/Extension/Core/Type/TextTypeTest.php +++ b/Tests/Extension/Core/Type/TextTypeTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\Type; +use PHPUnit\Framework\Attributes\DataProvider; use Symfony\Component\Form\Extension\Core\Type\TextType; class TextTypeTest extends BaseTypeTestCase @@ -44,10 +45,9 @@ public static function provideZeros(): array } /** - * @dataProvider provideZeros - * * @see https://github.com/symfony/symfony/issues/1986 */ + #[DataProvider('provideZeros')] public function testSetDataThroughParamsWithZero($data, $dataAsString) { $form = $this->factory->create(static::TESTED_TYPE, null, array_merge($this->getTestOptions(), [ diff --git a/Tests/Extension/Core/Type/TimeTypeTest.php b/Tests/Extension/Core/Type/TimeTypeTest.php index 8a2baf1b4..625799c25 100644 --- a/Tests/Extension/Core/Type/TimeTypeTest.php +++ b/Tests/Extension/Core/Type/TimeTypeTest.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Form\Tests\Extension\Core\Type; +use PHPUnit\Framework\Attributes\DataProvider; +use Symfony\Component\Clock\DatePoint; use Symfony\Component\Form\ChoiceList\View\ChoiceView; use Symfony\Component\Form\Exception\InvalidConfigurationException; use Symfony\Component\Form\Exception\LogicException; @@ -45,6 +47,32 @@ public function testSubmitDateTime() $this->assertEquals($input, $form->getViewData()); } + public function testSubmitDatePoint() + { + if (!class_exists(DatePoint::class)) { + self::markTestSkipped('The DatePoint class is not available.'); + } + + $form = $this->factory->create(static::TESTED_TYPE, null, [ + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'widget' => 'choice', + 'input' => 'date_point', + ]); + + $input = [ + 'hour' => '3', + 'minute' => '4', + ]; + + $form->submit($input); + + $this->assertInstanceOf(DatePoint::class, $form->getData()); + $datePoint = DatePoint::createFromMutable(new \DateTime('1970-01-01 03:04:00 UTC')); + $this->assertEquals($datePoint, $form->getData()); + $this->assertEquals($input, $form->getViewData()); + } + public function testSubmitDateTimeImmutable() { $form = $this->factory->create(static::TESTED_TYPE, null, [ @@ -907,9 +935,7 @@ public static function provideCompoundWidgets() ]; } - /** - * @dataProvider provideCompoundWidgets - */ + #[DataProvider('provideCompoundWidgets')] public function testHourErrorsBubbleUp($widget) { $error = new FormError('Invalid!'); @@ -922,9 +948,7 @@ public function testHourErrorsBubbleUp($widget) $this->assertSame([$error], iterator_to_array($form->getErrors())); } - /** - * @dataProvider provideCompoundWidgets - */ + #[DataProvider('provideCompoundWidgets')] public function testMinuteErrorsBubbleUp($widget) { $error = new FormError('Invalid!'); @@ -937,9 +961,7 @@ public function testMinuteErrorsBubbleUp($widget) $this->assertSame([$error], iterator_to_array($form->getErrors())); } - /** - * @dataProvider provideCompoundWidgets - */ + #[DataProvider('provideCompoundWidgets')] public function testSecondErrorsBubbleUp($widget) { $error = new FormError('Invalid!'); @@ -1128,9 +1150,7 @@ public function testArrayTimeWithReferenceDoesUseReferenceDateOnModelTransform() ], $form->getViewData()); } - /** - * @dataProvider provideEmptyData - */ + #[DataProvider('provideEmptyData')] public function testSubmitNullUsesDateEmptyData($widget, $emptyData, $expectedData) { $form = $this->factory->create(static::TESTED_TYPE, null, [ diff --git a/Tests/Extension/Core/Type/TimezoneTypeTest.php b/Tests/Extension/Core/Type/TimezoneTypeTest.php index 1c37229be..267515600 100644 --- a/Tests/Extension/Core/Type/TimezoneTypeTest.php +++ b/Tests/Extension/Core/Type/TimezoneTypeTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\Type; +use PHPUnit\Framework\Attributes\RequiresPhpExtension; use Symfony\Component\Form\ChoiceList\View\ChoiceView; use Symfony\Component\Form\Exception\LogicException; use Symfony\Component\Form\Extension\Core\Type\TimezoneType; @@ -74,9 +75,7 @@ public function testDateTimeZoneInputWithBc() $this->assertContainsEquals('Europe/Saratov', $form->getConfig()->getAttribute('choice_list')->getValues()); } - /** - * @requires extension intl - */ + #[RequiresPhpExtension('intl')] public function testIntlTimeZoneInput() { $form = $this->factory->create(static::TESTED_TYPE, \IntlTimeZone::createTimeZone('America/New_York'), ['input' => 'intltimezone']); @@ -96,9 +95,7 @@ public function testIntlTimeZoneInput() $this->assertEquals([\IntlTimeZone::createTimeZone('Europe/Amsterdam'), \IntlTimeZone::createTimeZone('Europe/Paris')], $form->getData()); } - /** - * @requires extension intl - */ + #[RequiresPhpExtension('intl')] public function testIntlTimeZoneInputWithBc() { $reflector = new \ReflectionExtension('intl'); @@ -119,9 +116,7 @@ public function testIntlTimeZoneInputWithBc() $this->assertNotContains('Europe/Saratov', $form->getConfig()->getAttribute('choice_list')->getValues()); } - /** - * @requires extension intl - */ + #[RequiresPhpExtension('intl')] public function testIntlTimeZoneInputWithBcAndIntl() { $reflector = new \ReflectionExtension('intl'); @@ -153,9 +148,7 @@ public function testTimezonesAreSelectableWithIntl() $this->assertContainsEquals(new ChoiceView('Etc/UTC', 'Etc/UTC', 'Coordinated Universal Time'), $choices); } - /** - * @requires extension intl - */ + #[RequiresPhpExtension('intl')] public function testChoiceTranslationLocaleOptionWithIntl() { $choices = $this->factory diff --git a/Tests/Extension/Core/Type/UrlTypeTest.php b/Tests/Extension/Core/Type/UrlTypeTest.php index a0d335647..5da9ba241 100644 --- a/Tests/Extension/Core/Type/UrlTypeTest.php +++ b/Tests/Extension/Core/Type/UrlTypeTest.php @@ -11,19 +11,17 @@ namespace Symfony\Component\Form\Tests\Extension\Core\Type; -use Symfony\Bridge\PhpUnit\ExpectUserDeprecationMessageTrait; +use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\IgnoreDeprecations; use Symfony\Component\Form\Extension\Core\Type\UrlType; use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException; class UrlTypeTest extends TextTypeTest { - use ExpectUserDeprecationMessageTrait; - public const TESTED_TYPE = UrlType::class; - /** - * @group legacy - */ + #[IgnoreDeprecations] + #[Group('legacy')] public function testSubmitAddsDefaultProtocolIfNoneIsIncluded() { $this->expectUserDeprecationMessage('Since symfony/form 7.1: Not configuring the "default_protocol" option when using the UrlType is deprecated. It will default to "null" in 8.0.'); diff --git a/Tests/Extension/Core/Type/WeekTypeTest.php b/Tests/Extension/Core/Type/WeekTypeTest.php index b4d58fd95..df0ec8fc7 100644 --- a/Tests/Extension/Core/Type/WeekTypeTest.php +++ b/Tests/Extension/Core/Type/WeekTypeTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\Type; +use PHPUnit\Framework\Attributes\DataProvider; use Symfony\Component\Form\Extension\Core\Type\WeekType; use Symfony\Component\Form\FormError; @@ -300,9 +301,7 @@ public function testSubmitNullUsesDefaultEmptyData($emptyData = [], $expectedDat $this->assertSame(['year' => null, 'week' => null], $form->getData()); } - /** - * @dataProvider provideEmptyData - */ + #[DataProvider('provideEmptyData')] public function testSubmitNullUsesDateEmptyDataString($widget, $emptyData, $expectedData) { $form = $this->factory->create(static::TESTED_TYPE, null, [ diff --git a/Tests/Extension/Csrf/Type/FormTypeCsrfExtensionTest.php b/Tests/Extension/Csrf/Type/FormTypeCsrfExtensionTest.php index d5bce6527..3bbfa2920 100644 --- a/Tests/Extension/Csrf/Type/FormTypeCsrfExtensionTest.php +++ b/Tests/Extension/Csrf/Type/FormTypeCsrfExtensionTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Csrf\Type; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\MockObject\MockObject; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Csrf\CsrfExtension; @@ -166,9 +167,7 @@ public static function provideBoolean() ]; } - /** - * @dataProvider provideBoolean - */ + #[DataProvider('provideBoolean')] public function testValidateTokenOnSubmitIfRootAndCompound($valid) { $this->tokenManager->expects($this->once()) @@ -198,9 +197,7 @@ public function testValidateTokenOnSubmitIfRootAndCompound($valid) $this->assertSame($valid, $form->isValid()); } - /** - * @dataProvider provideBoolean - */ + #[DataProvider('provideBoolean')] public function testValidateTokenOnSubmitIfRootAndCompoundUsesFormNameAsIntentionByDefault($valid) { $this->tokenManager->expects($this->once()) @@ -229,9 +226,7 @@ public function testValidateTokenOnSubmitIfRootAndCompoundUsesFormNameAsIntentio $this->assertSame($valid, $form->isValid()); } - /** - * @dataProvider provideBoolean - */ + #[DataProvider('provideBoolean')] public function testValidateTokenOnSubmitIfRootAndCompoundUsesTypeClassAsIntentionIfEmptyFormName($valid) { $this->tokenManager->expects($this->once()) diff --git a/Tests/Extension/PasswordHasher/Type/PasswordTypePasswordHasherExtensionTest.php b/Tests/Extension/PasswordHasher/Type/PasswordTypePasswordHasherExtensionTest.php index 07d1292a3..e46bf82f3 100644 --- a/Tests/Extension/PasswordHasher/Type/PasswordTypePasswordHasherExtensionTest.php +++ b/Tests/Extension/PasswordHasher/Type/PasswordTypePasswordHasherExtensionTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\PasswordHasher\Type; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\MockObject\MockObject; use Symfony\Component\Form\Exception\InvalidConfigurationException; use Symfony\Component\Form\Extension\Core\Type\FormType; @@ -144,9 +145,7 @@ public function testPasswordHashSuccessWithEmptyData() $this->assertSame($user->getPassword(), $hashedPassword); } - /** - * @dataProvider provideRepeatedPasswordField - */ + #[DataProvider('provideRepeatedPasswordField')] public function testRepeatedPasswordField(string $type, array $options = []) { $user = new User(); diff --git a/Tests/Extension/Validator/Constraints/FormValidatorPerformanceTest.php b/Tests/Extension/Validator/Constraints/FormValidatorPerformanceTest.php index b0c7d719a..1388fb480 100644 --- a/Tests/Extension/Validator/Constraints/FormValidatorPerformanceTest.php +++ b/Tests/Extension/Validator/Constraints/FormValidatorPerformanceTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Validator\Constraints; +use PHPUnit\Framework\Attributes\Group; use Symfony\Component\Form\Extension\Validator\ValidatorExtension; use Symfony\Component\Form\Test\FormPerformanceTestCase; use Symfony\Component\Validator\Validation; @@ -29,9 +30,8 @@ protected function getExtensions(): array /** * findClickedButton() used to have an exponential number of calls. - * - * @group benchmark */ + #[Group('benchmark')] public function testValidationPerformance() { $this->setMaxRunningTime(1); diff --git a/Tests/Extension/Validator/ValidatorTypeGuesserTest.php b/Tests/Extension/Validator/ValidatorTypeGuesserTest.php index 1d0e0f872..a915e861b 100644 --- a/Tests/Extension/Validator/ValidatorTypeGuesserTest.php +++ b/Tests/Extension/Validator/ValidatorTypeGuesserTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Validator; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\CollectionType; @@ -60,9 +61,7 @@ protected function setUp(): void $this->guesser = new ValidatorTypeGuesser($this->metadataFactory); } - /** - * @dataProvider guessTypeProvider - */ + #[DataProvider('guessTypeProvider')] public function testGuessType(Constraint $constraint, TypeGuess $guess) { $this->metadata->addPropertyConstraint(self::TEST_PROPERTY, $constraint); @@ -101,9 +100,7 @@ public static function guessRequiredProvider() ]; } - /** - * @dataProvider guessRequiredProvider - */ + #[DataProvider('guessRequiredProvider')] public function testGuessRequired($constraint, $guess) { // add distracting constraint @@ -185,9 +182,7 @@ public static function maxLengthTypeProvider() ]; } - /** - * @dataProvider maxLengthTypeProvider - */ + #[DataProvider('maxLengthTypeProvider')] public function testGuessMaxLengthForConstraintWithType($type) { $constraint = new Type($type); diff --git a/Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php b/Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php index 0aeb35adc..386fde262 100644 --- a/Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php +++ b/Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Validator\ViolationMapper; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\Form\CallbackTransformer; @@ -786,9 +787,7 @@ public static function provideDefaultTests() ]; } - /** - * @dataProvider provideDefaultTests - */ + #[DataProvider('provideDefaultTests')] public function testDefaultErrorMapping($target, $childName, $childPath, $grandChildName, $grandChildPath, $violationPath) { $violation = $this->getConstraintViolation($violationPath); @@ -1241,9 +1240,7 @@ public static function provideCustomDataErrorTests() ]; } - /** - * @dataProvider provideCustomDataErrorTests - */ + #[DataProvider('provideCustomDataErrorTests')] public function testCustomDataErrorMapping($target, $mapFrom, $mapTo, $childName, $childPath, $grandChildName, $grandChildPath, $violationPath) { $violation = $this->getConstraintViolation($violationPath); @@ -1441,9 +1438,7 @@ public static function provideCustomFormErrorTests() ]; } - /** - * @dataProvider provideCustomFormErrorTests - */ + #[DataProvider('provideCustomFormErrorTests')] public function testCustomFormErrorMapping($target, $mapFrom, $mapTo, $errorName, $errorPath, $childName, $childPath, $grandChildName, $grandChildPath, $violationPath) { $violation = $this->getConstraintViolation($violationPath); @@ -1508,9 +1503,7 @@ public static function provideErrorTestsForFormInheritingParentData() ]; } - /** - * @dataProvider provideErrorTestsForFormInheritingParentData - */ + #[DataProvider('provideErrorTestsForFormInheritingParentData')] public function testErrorMappingForFormInheritingParentData($target, $childName, $childPath, $grandChildName, $grandChildPath, $violationPath) { $violation = $this->getConstraintViolation($violationPath); diff --git a/Tests/Extension/Validator/ViolationMapper/ViolationPathTest.php b/Tests/Extension/Validator/ViolationMapper/ViolationPathTest.php index ebae56eb4..09c71d8de 100644 --- a/Tests/Extension/Validator/ViolationMapper/ViolationPathTest.php +++ b/Tests/Extension/Validator/ViolationMapper/ViolationPathTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Extension\Validator\ViolationMapper; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\Form\Extension\Validator\ViolationMapper\ViolationPath; @@ -84,9 +85,7 @@ public static function providePaths() ]; } - /** - * @dataProvider providePaths - */ + #[DataProvider('providePaths')] public function testCreatePath($string, $entries, $slicedPath = null) { $slicedPath ??= $string; @@ -120,9 +119,7 @@ public static function provideParents() ]; } - /** - * @dataProvider provideParents - */ + #[DataProvider('provideParents')] public function testGetParent($violationPath, $parentPath) { $path = new ViolationPath($violationPath); diff --git a/Tests/Fixtures/AlternatingRowType.php b/Tests/Fixtures/AlternatingRowType.php index 3e0bb40c2..9d80f3e13 100644 --- a/Tests/Fixtures/AlternatingRowType.php +++ b/Tests/Fixtures/AlternatingRowType.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Symfony\Component\Form\Tests\Fixtures; use Symfony\Component\Form\AbstractType; diff --git a/Tests/Fixtures/ArrayChoiceLoader.php b/Tests/Fixtures/ArrayChoiceLoader.php index 8c5a3a473..c5e137ec2 100644 --- a/Tests/Fixtures/ArrayChoiceLoader.php +++ b/Tests/Fixtures/ArrayChoiceLoader.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Symfony\Component\Form\Tests\Fixtures; use Symfony\Component\Form\ChoiceList\Loader\CallbackChoiceLoader; diff --git a/Tests/Fixtures/AuthorType.php b/Tests/Fixtures/AuthorType.php index a55dbfeac..df49e0d7a 100644 --- a/Tests/Fixtures/AuthorType.php +++ b/Tests/Fixtures/AuthorType.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Symfony\Component\Form\Tests\Fixtures; use Symfony\Component\Form\AbstractType; diff --git a/Tests/Fixtures/EnumFormTypeGuesserCase.php b/Tests/Fixtures/EnumFormTypeGuesserCase.php new file mode 100644 index 000000000..3028ec8c8 --- /dev/null +++ b/Tests/Fixtures/EnumFormTypeGuesserCase.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Fixtures; + +class EnumFormTypeGuesserCase +{ + public string $string; + public UndefinedEnum $undefinedEnum; + public EnumFormTypeGuesserCaseEnum $enum; + public ?EnumFormTypeGuesserCaseEnum $nullableEnum; + public BackedEnumFormTypeGuesserCaseEnum $backedEnum; + public ?BackedEnumFormTypeGuesserCaseEnum $nullableBackedEnum; + public EnumFormTypeGuesserCaseEnum|BackedEnumFormTypeGuesserCaseEnum $enumUnion; + public EnumFormTypeGuesserCaseEnum&BackedEnumFormTypeGuesserCaseEnum $enumIntersection; +} + +enum EnumFormTypeGuesserCaseEnum +{ + case Foo; + case Bar; +} + +enum BackedEnumFormTypeGuesserCaseEnum: string +{ + case Foo = 'foo'; + case Bar = 'bar'; +} diff --git a/Tests/Fixtures/FixedDataTransformer.php b/Tests/Fixtures/FixedDataTransformer.php index 2a1451c5a..b5e679ba9 100644 --- a/Tests/Fixtures/FixedDataTransformer.php +++ b/Tests/Fixtures/FixedDataTransformer.php @@ -27,7 +27,7 @@ public function transform($value): mixed { $value ??= ''; if (!\array_key_exists($value, $this->mapping)) { - throw new TransformationFailedException(sprintf('No mapping for value "%s"', $value)); + throw new TransformationFailedException(\sprintf('No mapping for value "%s"', $value)); } return $this->mapping[$value]; @@ -38,7 +38,7 @@ public function reverseTransform($value): mixed $result = array_search($value, $this->mapping, true); if (false === $result) { - throw new TransformationFailedException(sprintf('No reverse mapping for value "%s"', $value)); + throw new TransformationFailedException(\sprintf('No reverse mapping for value "%s"', $value)); } return $result; diff --git a/Tests/Fixtures/Organization.php b/Tests/Fixtures/Organization.php index db9cee9f9..f50c732e1 100644 --- a/Tests/Fixtures/Organization.php +++ b/Tests/Fixtures/Organization.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Symfony\Component\Form\Tests\Fixtures; class Organization @@ -19,6 +28,7 @@ public function getAuthors(): array public function addAuthor(Author $author): self { $this->authors[] = $author; + return $this; } @@ -27,6 +37,7 @@ public function removeAuthor(Author $author): self if (false !== $key = array_search($author, $this->authors, true)) { array_splice($this->authors, $key, 1); } + return $this; } } diff --git a/Tests/FormConfigTest.php b/Tests/FormConfigTest.php index 6de3e9416..192ba5c30 100644 --- a/Tests/FormConfigTest.php +++ b/Tests/FormConfigTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\Form\FormConfigBuilder; @@ -62,9 +63,7 @@ public static function getHtml4Ids() ]; } - /** - * @dataProvider getHtml4Ids - */ + #[DataProvider('getHtml4Ids')] public function testNameAcceptsOnlyNamesValidAsIdsInHtml4($name, $expectedException = null) { if (null !== $expectedException) { diff --git a/Tests/FormErrorIteratorTest.php b/Tests/FormErrorIteratorTest.php index 56472c82e..97a7ccd06 100644 --- a/Tests/FormErrorIteratorTest.php +++ b/Tests/FormErrorIteratorTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\Form\FormBuilder; @@ -23,9 +24,7 @@ class FormErrorIteratorTest extends TestCase { - /** - * @dataProvider findByCodesProvider - */ + #[DataProvider('findByCodesProvider')] public function testFindByCodes($code, $violationsCount) { $formBuilder = new FormBuilder( diff --git a/Tests/ResolvedFormTypeTest.php b/Tests/ResolvedFormTypeTest.php index fa28f7547..13a1bc259 100644 --- a/Tests/ResolvedFormTypeTest.php +++ b/Tests/ResolvedFormTypeTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\Form\AbstractType; @@ -151,9 +152,7 @@ public function testGetBlockPrefix() $this->assertSame('configurable_form_prefix', $resolvedType->getBlockPrefix()); } - /** - * @dataProvider provideTypeClassBlockPrefixTuples - */ + #[DataProvider('provideTypeClassBlockPrefixTuples')] public function testBlockPrefixDefaultsToFQCNIfNoName($typeClass, $blockPrefix) { $resolvedType = new ResolvedFormType(new $typeClass()); diff --git a/Tests/Resources/TranslationFilesTest.php b/Tests/Resources/TranslationFilesTest.php index 157335dc6..ccfb8926b 100644 --- a/Tests/Resources/TranslationFilesTest.php +++ b/Tests/Resources/TranslationFilesTest.php @@ -11,14 +11,13 @@ namespace Symfony\Component\Form\Tests\Resources; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\Translation\Util\XliffUtils; class TranslationFilesTest extends TestCase { - /** - * @dataProvider provideTranslationFiles - */ + #[DataProvider('provideTranslationFiles')] public function testTranslationFileIsValid($filePath) { $document = new \DOMDocument(); @@ -29,9 +28,7 @@ public function testTranslationFileIsValid($filePath) $this->assertCount(0, $errors, \sprintf('"%s" is invalid:%s', $filePath, \PHP_EOL.implode(\PHP_EOL, array_column($errors, 'message')))); } - /** - * @dataProvider provideTranslationFiles - */ + #[DataProvider('provideTranslationFiles')] public function testTranslationFileIsValidWithoutEntityLoader($filePath) { $document = new \DOMDocument(); diff --git a/Tests/SimpleFormTest.php b/Tests/SimpleFormTest.php index 0f9a6dc41..01ae6a5a1 100644 --- a/Tests/SimpleFormTest.php +++ b/Tests/SimpleFormTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\Form\Exception\AlreadySubmittedException; @@ -75,9 +76,7 @@ protected function setUp(): void $this->form = $this->createForm(); } - /** - * @dataProvider provideFormNames - */ + #[DataProvider('provideFormNames')] public function testGetPropertyPath($name, $propertyPath) { $config = new FormConfigBuilder($name, null, new EventDispatcher()); @@ -230,9 +229,7 @@ public function testNotRequired() $this->assertFalse($child->isRequired()); } - /** - * @dataProvider getDisabledStates - */ + #[DataProvider('getDisabledStates')] public function testAlwaysDisabledIfParentDisabled($parentDisabled, $disabled, $result) { $parent = $this->getBuilder()->setDisabled($parentDisabled)->getForm(); @@ -1052,7 +1049,7 @@ public function testInitializeSetsDefaultData() $config = $this->getBuilder()->setData('DEFAULT')->getFormConfig(); $form = new Form($config); - /** @var Form $form */ + /* @var Form $form */ $form->initialize(); $this->assertSame('DEFAULT', $form->getData()); diff --git a/Tests/Util/ServerParamsTest.php b/Tests/Util/ServerParamsTest.php index 1904812d8..778819d37 100644 --- a/Tests/Util/ServerParamsTest.php +++ b/Tests/Util/ServerParamsTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Util; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\Form\Util\ServerParams; use Symfony\Component\HttpFoundation\Request; @@ -40,7 +41,7 @@ public function testGetContentLengthFromRequest() $this->assertEquals(1024, $serverParams->getContentLength()); } - /** @dataProvider getGetPostMaxSizeTestData */ + #[DataProvider('getGetPostMaxSizeTestData')] public function testGetPostMaxSize($size, $bytes) { $serverParams = new DummyServerParams($size); diff --git a/Tests/Util/StringUtilTest.php b/Tests/Util/StringUtilTest.php index d51481f6c..a7221e55f 100644 --- a/Tests/Util/StringUtilTest.php +++ b/Tests/Util/StringUtilTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Tests\Util; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\Form\Util\StringUtil; @@ -24,17 +25,13 @@ public static function trimProvider(): array ]; } - /** - * @dataProvider trimProvider - */ + #[DataProvider('trimProvider')] public function testTrim($data, $expectedData) { $this->assertSame($expectedData, StringUtil::trim($data)); } - /** - * @dataProvider spaceProvider - */ + #[DataProvider('spaceProvider')] public function testTrimUtf8Separators($hex) { // Convert hexadecimal representation into binary @@ -87,9 +84,7 @@ public static function spaceProvider(): array ]; } - /** - * @dataProvider fqcnToBlockPrefixProvider - */ + #[DataProvider('fqcnToBlockPrefixProvider')] public function testFqcnToBlockPrefix($fqcn, $expectedBlockPrefix) { $blockPrefix = StringUtil::fqcnToBlockPrefix($fqcn); diff --git a/Util/OrderedHashMapIterator.php b/Util/OrderedHashMapIterator.php index 927a28c04..ed4ee0b84 100644 --- a/Util/OrderedHashMapIterator.php +++ b/Util/OrderedHashMapIterator.php @@ -51,12 +51,12 @@ public function __construct( $this->managedCursors[$this->cursorId] = &$this->cursor; } - public function __sleep(): array + public function __serialize(): array { throw new \BadMethodCallException('Cannot serialize '.__CLASS__); } - public function __wakeup(): void + public function __unserialize(array $data): void { throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); } diff --git a/composer.json b/composer.json index f4403ba74..b6e993205 100644 --- a/composer.json +++ b/composer.json @@ -18,30 +18,31 @@ "require": { "php": ">=8.2", "symfony/deprecation-contracts": "^2.5|^3", - "symfony/event-dispatcher": "^6.4|^7.0", - "symfony/options-resolver": "^7.3", + "symfony/event-dispatcher": "^6.4|^7.0|^8.0", + "symfony/options-resolver": "^7.3|^8.0", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-icu": "^1.21", "symfony/polyfill-mbstring": "~1.0", - "symfony/property-access": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0|^8.0", "symfony/service-contracts": "^2.5|^3" }, "require-dev": { "doctrine/collections": "^1.0|^2.0", - "symfony/validator": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/expression-language": "^6.4|^7.0", - "symfony/config": "^6.4|^7.0", - "symfony/console": "^6.4|^7.0", - "symfony/html-sanitizer": "^6.4|^7.0", - "symfony/http-foundation": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/intl": "^6.4|^7.0", - "symfony/security-core": "^6.4|^7.0", - "symfony/security-csrf": "^6.4|^7.0", - "symfony/translation": "^6.4.3|^7.0.3", - "symfony/var-dumper": "^6.4|^7.0", - "symfony/uid": "^6.4|^7.0" + "symfony/validator": "^6.4.12|^7.1.5|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/expression-language": "^6.4|^7.0|^8.0", + "symfony/clock": "^6.4|^7.0|^8.0", + "symfony/config": "^6.4|^7.0|^8.0", + "symfony/console": "^6.4|^7.0|^8.0", + "symfony/html-sanitizer": "^6.4|^7.0|^8.0", + "symfony/http-foundation": "^6.4|^7.0|^8.0", + "symfony/http-kernel": "^6.4|^7.0|^8.0", + "symfony/intl": "^6.4|^7.0|^8.0", + "symfony/security-core": "^6.4|^7.0|^8.0", + "symfony/security-csrf": "^6.4|^7.0|^8.0", + "symfony/translation": "^6.4.3|^7.0.3|^8.0", + "symfony/var-dumper": "^6.4|^7.0|^8.0", + "symfony/uid": "^6.4|^7.0|^8.0" }, "conflict": { "symfony/console": "<6.4", diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 148f8f58d..b4d578415 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,10 +1,11 @@ @@ -18,7 +19,7 @@ - + ./ @@ -27,5 +28,9 @@ ./Tests ./vendor - + + + + +