[TASK] Extract ValidatorClassNameResolver from ValidatorResolver 52/59952/4
authorAlexander Schnitzler <git@alexanderschnitzler.de>
Sat, 9 Mar 2019 10:23:14 +0000 (10:23 +0000)
committerAnja Leichsenring <aleichsenring@ab-softlab.de>
Fri, 15 Mar 2019 15:24:20 +0000 (16:24 +0100)
The ValidatorResolver contained a method for resolving validator
class names. Extbase supports various shorthand notations to
make the life of developers more easy. There are notations like:

- NotEmpty
- TYPO3.CMS.Extbase:NotEmpty
- CustomExtension:ValidatorName

Resolving these notations takes place in a dedicated
ValidatorClassNameResolver class now.

Releases: master
Resolves: #87868
Change-Id: Ib0d57127a0e1dc4ae0536a8e76ca497f6d2bd56d
Reviewed-on: https://review.typo3.org/c/59952
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Susanne Moog <susanne.moog@typo3.org>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Reviewed-by: Susanne Moog <susanne.moog@typo3.org>
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
typo3/sysext/extbase/Classes/Reflection/ClassSchema.php
typo3/sysext/extbase/Classes/Validation/ValidatorClassNameResolver.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Validation/ValidatorResolver.php
typo3/sysext/extbase/Tests/Fixture/ValidatorThatDoesNotImplementValidatorInterfaceValidator.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Functional/Validation/ValidatorResolverTest.php
typo3/sysext/extbase/Tests/Unit/Validation/ValidatorClassNameResolverTest.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Unit/Validation/ValidatorResolverTest.php [deleted file]

index 1dd9a30..f5de1b4 100644 (file)
@@ -23,7 +23,6 @@ use Symfony\Component\PropertyInfo\PropertyInfoExtractor;
 use Symfony\Component\PropertyInfo\Type;
 use TYPO3\CMS\Core\SingletonInterface;
 use TYPO3\CMS\Core\Utility\ClassNamingUtility;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Core\Utility\StringUtility;
 use TYPO3\CMS\Extbase\Annotation\IgnoreValidation;
 use TYPO3\CMS\Extbase\Annotation\Inject;
@@ -42,7 +41,7 @@ use TYPO3\CMS\Extbase\Reflection\DocBlock\Tags\Null_;
 use TYPO3\CMS\Extbase\Utility\TypeHandlingUtility;
 use TYPO3\CMS\Extbase\Validation\Exception\InvalidTypeHintException;
 use TYPO3\CMS\Extbase\Validation\Exception\InvalidValidationConfigurationException;
-use TYPO3\CMS\Extbase\Validation\ValidatorResolver;
+use TYPO3\CMS\Extbase\Validation\ValidatorClassNameResolver;
 
 /**
  * A class schema
@@ -239,10 +238,8 @@ class ClassSchema
             });
 
             if (count($validateAnnotations) > 0) {
-                $validatorResolver = GeneralUtility::makeInstance(ValidatorResolver::class);
-
                 foreach ($validateAnnotations as $validateAnnotation) {
-                    $validatorObjectName = $validatorResolver->resolveValidatorObjectName($validateAnnotation->validator);
+                    $validatorObjectName = ValidatorClassNameResolver::resolve($validateAnnotation->validator);
 
                     $this->properties[$propertyName]['validators'][] = [
                         'name' => $validateAnnotation->validator,
@@ -331,11 +328,9 @@ class ClassSchema
             });
 
             if ($this->isController && $this->methods[$methodName]['isAction'] && count($validateAnnotations) > 0) {
-                $validatorResolver = GeneralUtility::makeInstance(ValidatorResolver::class);
-
                 foreach ($validateAnnotations as $validateAnnotation) {
                     $validatorName = $validateAnnotation->validator;
-                    $validatorObjectName = $validatorResolver->resolveValidatorObjectName($validatorName);
+                    $validatorObjectName = ValidatorClassNameResolver::resolve($validatorName);
 
                     $argumentValidators[$validateAnnotation->param][] = [
                         'name' => $validatorName,
diff --git a/typo3/sysext/extbase/Classes/Validation/ValidatorClassNameResolver.php b/typo3/sysext/extbase/Classes/Validation/ValidatorClassNameResolver.php
new file mode 100644 (file)
index 0000000..89932c4
--- /dev/null
@@ -0,0 +1,121 @@
+<?php
+declare(strict_types = 1);
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+namespace TYPO3\CMS\Extbase\Validation;
+
+use TYPO3\CMS\Core\Utility\StringUtility;
+use TYPO3\CMS\Extbase\Validation\Exception\NoSuchValidatorException;
+use TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface;
+
+/**
+ * Class TYPO3\CMS\Extbase\Validation\ValidatorClassNameResolver
+ */
+final class ValidatorClassNameResolver
+{
+    /**
+     * This method is marked internal due to several facts:
+     *
+     * - The functionality is not 100% tested and still contains some bugs
+     * - The functionality might not be needed any longer if Extbase switches
+     *   to the symfony/validator component.
+     *
+     * This method can be used by extension developers. As long as it remains,
+     * its functionality will not change. It might even become more stable.
+     * However, developers should be aware that this method might vanish
+     * without any deprecation.
+     *
+     * @param string $validatorIdentifier
+     * @return string
+     * @throws NoSuchValidatorException
+     * @internal
+     */
+    public static function resolve(string $validatorIdentifier): string
+    {
+        // Trim leading slash if $validatorName is FQCN like \TYPO3\CMS\Extbase\Validation\Validator\FloatValidator
+        $validatorIdentifier = ltrim($validatorIdentifier, '\\');
+
+        $validatorClassName = $validatorIdentifier;
+        if (strpbrk($validatorIdentifier, ':') !== false) {
+            // Found shorthand validator, either extbase or foreign extension
+            // NotEmpty or Acme.MyPck.Ext:MyValidator
+            [$vendorNamespace, $validatorBaseName] = explode(':', $validatorIdentifier);
+
+            // todo: at this point ($validatorIdentifier !== $vendorNamespace) is always true as $validatorIdentifier
+            // todo: contains a colon ":" and $vendorNamespace doesn't.
+            if ($validatorIdentifier !== $vendorNamespace && $validatorBaseName !== '') {
+                // Shorthand custom
+                if (strpos($vendorNamespace, '.') !== false) {
+                    $extensionNameParts = explode('.', $vendorNamespace);
+                    $vendorNamespace = array_pop($extensionNameParts);
+                    $vendorName = implode('\\', $extensionNameParts);
+                    $validatorClassName = $vendorName . '\\' . $vendorNamespace . '\\Validation\\Validator\\' . $validatorBaseName;
+                }
+            } else {
+                // todo: the only way to reach this path is to use a validator identifier like "Integer:"
+                // todo: as we are using $validatorIdentifier here, this path always fails.
+                // Shorthand built in
+                $validatorClassName = 'TYPO3\\CMS\\Extbase\\Validation\\Validator\\' . self::getValidatorType($validatorIdentifier);
+            }
+        } elseif (strpbrk($validatorIdentifier, '\\') === false) {
+            // Shorthand built in
+            $validatorClassName = 'TYPO3\\CMS\\Extbase\\Validation\\Validator\\' . self::getValidatorType($validatorIdentifier);
+        }
+
+        if (!StringUtility::endsWith($validatorClassName, 'Validator')) {
+            $validatorClassName .= 'Validator';
+        }
+
+        if (!class_exists($validatorClassName)) {
+            throw new NoSuchValidatorException('Validator class ' . $validatorClassName . ' does not exist', 1365799920);
+        }
+
+        if (!is_subclass_of($validatorClassName, ValidatorInterface::class)) {
+            throw new NoSuchValidatorException(
+                'Validator class ' . $validatorClassName . ' must implement ' . ValidatorInterface::class,
+                1365776838
+            );
+        }
+
+        return $validatorClassName;
+    }
+
+    /**
+     * Used to map PHP types to validator types.
+     *
+     * @param string $type Data type to unify
+     * @return string unified data type
+     */
+    private static function getValidatorType(string $type): string
+    {
+        switch ($type) {
+            case 'int':
+                $type = 'Integer';
+                break;
+            case 'bool':
+                $type = 'Boolean';
+                break;
+            case 'double':
+                $type = 'Float';
+                break;
+            case 'numeric':
+                $type = 'Number';
+                break;
+            default:
+                $type = ucfirst($type);
+        }
+        return $type;
+    }
+}
index e689c64..3a9cfbb 100644 (file)
@@ -75,7 +75,7 @@ class ValidatorResolver implements \TYPO3\CMS\Core\SingletonInterface
             /**
              * @todo remove throwing Exceptions in resolveValidatorObjectName
              */
-            $validatorObjectName = $this->resolveValidatorObjectName($validatorType);
+            $validatorObjectName = ValidatorClassNameResolver::resolve($validatorType);
 
             $validator = $this->objectManager->get($validatorObjectName, $validatorOptions);
 
@@ -253,95 +253,4 @@ class ValidatorResolver implements \TYPO3\CMS\Core\SingletonInterface
 
         // @todo: find polytype validator for class
     }
-
-    /**
-     * Returns an object of an appropriate validator for the given class. If no validator is available
-     * FALSE is returned
-     *
-     * @param string $validatorName Either the fully qualified class name of the validator or the short name of a built-in validator
-     *
-     * @throws Exception\NoSuchValidatorException
-     * @return string Name of the validator object
-     * @internal
-     */
-    public function resolveValidatorObjectName($validatorName)
-    {
-        // todo: this functionality should be extracted into a separate class. It should be a final class with
-        // todo: static public functions, completely covered by unit tests.
-        if (strpos($validatorName, ':') !== false) {
-            // Found shorthand validator, either extbase or foreign extension
-            // NotEmpty or Acme.MyPck.Ext:MyValidator
-            list($extensionName, $extensionValidatorName) = explode(':', $validatorName);
-
-            if ($validatorName !== $extensionName && $extensionValidatorName !== '') {
-                // Shorthand custom
-                if (strpos($extensionName, '.') !== false) {
-                    $extensionNameParts = explode('.', $extensionName);
-                    $extensionName = array_pop($extensionNameParts);
-                    $vendorName = implode('\\', $extensionNameParts);
-                    $possibleClassName = $vendorName . '\\' . $extensionName . '\\Validation\\Validator\\' . $extensionValidatorName;
-                }
-            } else {
-                // Shorthand built in
-                $possibleClassName = 'TYPO3\\CMS\\Extbase\\Validation\\Validator\\' . $this->getValidatorType($validatorName);
-            }
-        } elseif (strpbrk($validatorName, '\\') === false) {
-            // Shorthand built in
-            $possibleClassName = 'TYPO3\\CMS\\Extbase\\Validation\\Validator\\' . $this->getValidatorType($validatorName);
-        } else {
-            // Full qualified
-            // Example: \Acme\Ext\Validation\Validator\FooValidator
-            $possibleClassName = $validatorName;
-            if (!empty($possibleClassName) && $possibleClassName[0] === '\\') {
-                $possibleClassName = substr($possibleClassName, 1);
-            }
-        }
-
-        if (substr($possibleClassName, - strlen('Validator')) !== 'Validator') {
-            $possibleClassName .= 'Validator';
-        }
-
-        if (class_exists($possibleClassName)) {
-            $possibleClassNameInterfaces = class_implements($possibleClassName);
-            if (!in_array(\TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface::class, $possibleClassNameInterfaces)) {
-                // The guessed validatorname is a valid class name, but does not implement the ValidatorInterface
-                throw new NoSuchValidatorException('Validator class ' . $validatorName . ' must implement \TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface', 1365776838);
-            }
-            $resolvedValidatorName = $possibleClassName;
-        } else {
-            throw new NoSuchValidatorException('Validator class ' . $validatorName . ' does not exist', 1365799920);
-        }
-
-        return $resolvedValidatorName;
-    }
-
-    /**
-     * Used to map PHP types to validator types.
-     *
-     * @param string $type Data type to unify
-     * @return string unified data type
-     */
-    protected function getValidatorType($type)
-    {
-        switch ($type) {
-            case 'int':
-                $type = 'Integer';
-                break;
-            case 'bool':
-                $type = 'Boolean';
-                break;
-            case 'double':
-                $type = 'Float';
-                break;
-            case 'numeric':
-                $type = 'Number';
-                break;
-            case 'mixed':
-                $type = 'Raw';
-                break;
-            default:
-                $type = ucfirst($type);
-        }
-        return $type;
-    }
 }
diff --git a/typo3/sysext/extbase/Tests/Fixture/ValidatorThatDoesNotImplementValidatorInterfaceValidator.php b/typo3/sysext/extbase/Tests/Fixture/ValidatorThatDoesNotImplementValidatorInterfaceValidator.php
new file mode 100644 (file)
index 0000000..de3582c
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+declare(strict_types = 1);
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+namespace TYPO3\CMS\Extbase\Tests\Fixture;
+
+/**
+ * Class TYPO3\CMS\Extbase\Tests\Fixture\ValidatorThatDoesNotImplementValidatorInterfaceValidator
+ */
+class ValidatorThatDoesNotImplementValidatorInterfaceValidator
+{
+}
index a7bc2db..c245fef 100644 (file)
@@ -18,7 +18,6 @@ namespace TYPO3\CMS\Extbase\Tests\Functional\Validation;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Extbase\Object\ObjectManager;
 use TYPO3\CMS\Extbase\Reflection\ReflectionService;
-use TYPO3\CMS\Extbase\Validation\Exception\NoSuchValidatorException;
 use TYPO3\CMS\Extbase\Validation\Validator\CollectionValidator;
 use TYPO3\CMS\Extbase\Validation\Validator\ConjunctionValidator;
 use TYPO3\CMS\Extbase\Validation\Validator\GenericObjectValidator;
@@ -49,101 +48,6 @@ class ValidatorResolverTest extends \TYPO3\TestingFramework\Core\Functional\Func
     }
 
     /**
-     * @return array
-     */
-    public function namespacedShorthandValidatorNamesDataProvider(): array
-    {
-        return [
-            'TYPO3.CMS.Extbase:NotEmpty' => [
-                'TYPO3.CMS.Extbase:NotEmpty',
-                NotEmptyValidator::class
-            ],
-            'TYPO3.CMS.Extbase.Tests.Functional.Validation.Fixture:Custom' => [
-                'TYPO3.CMS.Extbase.Tests.Functional.Validation.Fixture:Custom',
-                Fixture\Validation\Validator\CustomValidator::class
-            ]
-        ];
-    }
-
-    /**
-     * @test
-     * @dataProvider namespacedShorthandValidatorNamesDataProvider
-     *
-     * @param string $validatorName
-     * @param string $expectedClassName
-     */
-    public function resolveValidatorObjectNameWithShortHandNotationReturnsValidatorNameIfClassExists(string $validatorName, string $expectedClassName)
-    {
-        static::assertEquals(
-            $expectedClassName,
-            $this->validatorResolver->_call('resolveValidatorObjectName', $validatorName)
-        );
-    }
-
-    /**
-     * @test
-     */
-    public function resolveValidatorObjectNameWithShortHandNotationThrowsExceptionIfClassDoesNotExist()
-    {
-        $this->expectException(NoSuchValidatorException::class);
-        $this->expectExceptionCode(1365799920);
-
-        $validatorName = 'TYPO3.CMS.Extbase.Tests.Functional.Validation.Fixture:NonExistentValidator';
-        $this->validatorResolver->_call('resolveValidatorObjectName', $validatorName);
-    }
-
-    /**
-     * @test
-     */
-    public function resolveValidatorObjectNameWithShortHandNotationReturnsValidatorNameIfClassExistsButDoesNotImplementValidatorInterface()
-    {
-        $this->expectException(NoSuchValidatorException::class);
-        $this->expectExceptionCode(1365776838);
-
-        $validatorName = 'TYPO3.CMS.Extbase.Tests.Functional.Validation.Fixture:CustomValidatorThatDoesNotImplementValidatorInterface';
-        $this->validatorResolver->_call('resolveValidatorObjectName', $validatorName);
-    }
-
-    /**
-     * @test
-     */
-    public function resolveValidatorObjectNameReturnsValidatorNameForFullQualifiedValidatorName()
-    {
-        $validatorName = Fixture\Validation\Validator\CustomValidator::class;
-        $className = Fixture\Validation\Validator\CustomValidator::class;
-
-        static::assertEquals(
-            $className,
-            $this->validatorResolver->_call('resolveValidatorObjectName', $validatorName)
-        );
-    }
-
-    /**
-     * @test
-     */
-    public function resolveValidatorObjectNameReturnsValidatorNameForFullQualifiedValidatorNameWithLeadingBackslash()
-    {
-        $validatorName = '\\' . Fixture\Validation\Validator\CustomValidator::class;
-        $className = Fixture\Validation\Validator\CustomValidator::class;
-
-        static::assertEquals(
-            $className,
-            $this->validatorResolver->_call('resolveValidatorObjectName', $validatorName)
-        );
-    }
-
-    /**
-     * @test
-     */
-    public function resolveValidatorObjectNameThrowsNoSuchValidatorExceptionIfClassDoesNotExist()
-    {
-        $className = $this->getUniqueId('Foo\\Bar');
-        $this->expectException(NoSuchValidatorException::class);
-        $this->expectExceptionCode(1365799920);
-        $this->validatorResolver->_call('resolveValidatorObjectName', $className);
-    }
-
-    /**
      * @test
      */
     public function buildBaseValidatorConjunctionAddsValidatorsDefinedByAnnotationsInTheClassToTheReturnedConjunction()
diff --git a/typo3/sysext/extbase/Tests/Unit/Validation/ValidatorClassNameResolverTest.php b/typo3/sysext/extbase/Tests/Unit/Validation/ValidatorClassNameResolverTest.php
new file mode 100644 (file)
index 0000000..fc8dbcb
--- /dev/null
@@ -0,0 +1,177 @@
+<?php
+declare(strict_types = 1);
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+namespace TYPO3\CMS\Extbase\Tests\Unit\Validation;
+
+use TYPO3\CMS\Extbase\Tests\Fixture\ValidatorThatDoesNotImplementValidatorInterfaceValidator;
+use TYPO3\CMS\Extbase\Tests\Functional\Validation\Fixture\Validation\Validator\CustomValidator;
+use TYPO3\CMS\Extbase\Validation\Exception\NoSuchValidatorException;
+use TYPO3\CMS\Extbase\Validation\Validator\BooleanValidator;
+use TYPO3\CMS\Extbase\Validation\Validator\FloatValidator;
+use TYPO3\CMS\Extbase\Validation\Validator\IntegerValidator;
+use TYPO3\CMS\Extbase\Validation\Validator\NotEmptyValidator;
+use TYPO3\CMS\Extbase\Validation\Validator\NumberValidator;
+use TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface;
+use TYPO3\CMS\Extbase\Validation\ValidatorClassNameResolver;
+use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
+
+/**
+ * Class TYPO3\CMS\Extbase\Tests\Unit\Validation\ValidatorClassNameResolverTest
+ */
+class ValidatorClassNameResolverTest extends UnitTestCase
+{
+    /**
+     * @test
+     */
+    public function resolveResolvesFullyQualifiedClassNames(): void
+    {
+        $validatorIdentifier = IntegerValidator::class;
+        static::assertSame($validatorIdentifier, ValidatorClassNameResolver::resolve($validatorIdentifier));
+    }
+
+    /**
+     * @test
+     */
+    public function resolveResolvesCoreShorthandIdentifiers(): void
+    {
+        static::assertSame(IntegerValidator::class, ValidatorClassNameResolver::resolve('int'));
+        static::assertSame(BooleanValidator::class, ValidatorClassNameResolver::resolve('bool'));
+        static::assertSame(FloatValidator::class, ValidatorClassNameResolver::resolve('double'));
+        static::assertSame(NumberValidator::class, ValidatorClassNameResolver::resolve('numeric'));
+        static::assertSame(FloatValidator::class, ValidatorClassNameResolver::resolve('float'));
+    }
+
+    /**
+     * @test
+     */
+    public function resolveResolvesExtensionShorthandIdentifiers(): void
+    {
+        static::assertSame(IntegerValidator::class, ValidatorClassNameResolver::resolve('TYPO3.CMS.Extbase:Integer'));
+    }
+
+    /**
+     * @test
+     */
+    public function resolveThrowsNoSuchValidatorExceptionDueToMissingClass(): void
+    {
+        $this->expectExceptionCode(1365799920);
+        $this->expectExceptionMessage('Validator class TYPO3\CMS\Extbase\Validation\Validator\NonExistingValidator does not exist');
+
+        static::assertSame(IntegerValidator::class, ValidatorClassNameResolver::resolve('NonExisting'));
+    }
+
+    /**
+     * @test
+     */
+    public function resolveThrowsNoSuchValidatorExceptionDueToClassInheritence(): void
+    {
+        $this->expectExceptionCode(1365776838);
+        $this->expectExceptionMessage(sprintf(
+            'Validator class %s must implement %s',
+            ValidatorThatDoesNotImplementValidatorInterfaceValidator::class,
+            ValidatorInterface::class
+        ));
+
+        static::assertSame(
+            IntegerValidator::class,
+            ValidatorClassNameResolver::resolve(ValidatorThatDoesNotImplementValidatorInterfaceValidator::class)
+        );
+    }
+
+    /**
+     * @return array
+     */
+    public function namespacedShorthandValidatorNamesDataProvider(): array
+    {
+        return [
+            'TYPO3.CMS.Extbase:NotEmpty' => [
+                'TYPO3.CMS.Extbase:NotEmpty',
+                NotEmptyValidator::class
+            ],
+            'TYPO3.CMS.Extbase.Tests.Functional.Validation.Fixture:Custom' => [
+                'TYPO3.CMS.Extbase.Tests.Functional.Validation.Fixture:Custom',
+                CustomValidator::class
+            ]
+        ];
+    }
+
+    /**
+     * @test
+     * @dataProvider namespacedShorthandValidatorNamesDataProvider
+     *
+     * @param string $validatorName
+     * @param string $expectedClassName
+     */
+    public function resolveWithShortHandNotationReturnsValidatorNameIfClassExists(string $validatorName, string $expectedClassName): void
+    {
+        static::assertSame(
+            $expectedClassName,
+            ValidatorClassNameResolver::resolve($validatorName)
+        );
+    }
+
+    /**
+     * @test
+     */
+    public function resolveWithShortHandNotationThrowsExceptionIfClassDoesNotExist(): void
+    {
+        $this->expectException(NoSuchValidatorException::class);
+        $this->expectExceptionCode(1365799920);
+
+        $validatorName = 'TYPO3.CMS.Extbase.Tests.Functional.Validation.Fixture:NonExistentValidator';
+        ValidatorClassNameResolver::resolve($validatorName);
+    }
+
+    /**
+     * @test
+     */
+    public function resolveThrowsExceptionWithValidatorThatDoesNotImplementValidatorInterface(): void
+    {
+        $this->expectException(NoSuchValidatorException::class);
+        $this->expectExceptionCode(1365776838);
+
+        $validatorName = 'TYPO3.CMS.Extbase.Tests.Functional.Validation.Fixture:CustomValidatorThatDoesNotImplementValidatorInterface';
+        ValidatorClassNameResolver::resolve($validatorName);
+    }
+
+    /**
+     * @test
+     */
+    public function resolveReturnsValidatorNameForFullQualifiedValidatorName(): void
+    {
+        $validatorName = CustomValidator::class;
+        $className = CustomValidator::class;
+
+        static::assertSame(
+            $className,
+            ValidatorClassNameResolver::resolve($validatorName)
+        );
+    }
+
+    /**
+     * @test
+     */
+    public function resolveReturnsValidatorNameForFullQualifiedValidatorNameWithLeadingBackslash(): void
+    {
+        $validatorName = '\\' . CustomValidator::class;
+        $className = CustomValidator::class;
+
+        static::assertSame(
+            $className,
+            ValidatorClassNameResolver::resolve($validatorName)
+        );
+    }
+}
diff --git a/typo3/sysext/extbase/Tests/Unit/Validation/ValidatorResolverTest.php b/typo3/sysext/extbase/Tests/Unit/Validation/ValidatorResolverTest.php
deleted file mode 100644 (file)
index 489489e..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-<?php
-declare(strict_types = 1);
-namespace TYPO3\CMS\Extbase\Tests\Unit\Validation;
-
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
-
-/**
- * Test case
- */
-class ValidatorResolverTest extends UnitTestCase
-{
-    /**
-     * @var \TYPO3\CMS\Extbase\Validation\ValidatorResolver | \PHPUnit_Framework_MockObject_MockObject | \TYPO3\TestingFramework\Core\AccessibleObjectInterface
-     */
-    protected $validatorResolver;
-
-    /**
-     * @var \TYPO3\CMS\Extbase\Object\ObjectManager | \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $mockObjectManager;
-
-    protected function setUp()
-    {
-        $this->validatorResolver = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Validation\ValidatorResolver::class, ['dummy']);
-    }
-
-    /**
-     * @test
-     */
-    public function getValidatorTypeCorrectlyRenamesPhpDataTypes()
-    {
-        static::assertEquals('Integer', $this->validatorResolver->_call('getValidatorType', 'integer'));
-        static::assertEquals('Integer', $this->validatorResolver->_call('getValidatorType', 'int'));
-        static::assertEquals('String', $this->validatorResolver->_call('getValidatorType', 'string'));
-        static::assertEquals('Array', $this->validatorResolver->_call('getValidatorType', 'array'));
-        static::assertEquals('Float', $this->validatorResolver->_call('getValidatorType', 'float'));
-        static::assertEquals('Float', $this->validatorResolver->_call('getValidatorType', 'double'));
-        static::assertEquals('Boolean', $this->validatorResolver->_call('getValidatorType', 'boolean'));
-        static::assertEquals('Boolean', $this->validatorResolver->_call('getValidatorType', 'bool'));
-        static::assertEquals('Boolean', $this->validatorResolver->_call('getValidatorType', 'bool'));
-        static::assertEquals('Number', $this->validatorResolver->_call('getValidatorType', 'number'));
-        static::assertEquals('Number', $this->validatorResolver->_call('getValidatorType', 'numeric'));
-    }
-
-    /**
-     * @test
-     */
-    public function getValidatorTypeRenamesMixedToRaw()
-    {
-        static::assertEquals('Raw', $this->validatorResolver->_call('getValidatorType', 'mixed'));
-    }
-}