<NME> TypeGeneratorTest.php
<BEF> <?php
/**
 * Zend Framework (http://framework.zend.com/)
 *
 * @link      http://github.com/zendframework/zf2 for the canonical source repository
 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd New BSD License
 */

namespace ZendTest\Code\Generator;

use PHPUnit\Framework\TestCase;
use Zend\Code\Exception\InvalidArgumentException;
use Zend\Code\Generator\GeneratorInterface;
use Zend\Code\Generator\TypeGenerator;

use function array_combine;
use function array_filter;
use function array_map;
use function class_implements;
use function ltrim;
use function strpos;

/**
 * @group zendframework/zend-code#29
 *
 * @covers \Zend\Code\Generator\TypeGenerator
    }

    /**
     * @dataProvider validReturnTypeProvider
     *
     * @param string $typeString
     * @param string $expectedReturnType

    /**
     * @dataProvider validType
     *
     * @param string $typeString
     * @param string $expectedReturnType
    }

    /**
     * @dataProvider validReturnTypeProvider
     *
     * @param string $typeString
     * @param string $expectedReturnType

    /**
     * @dataProvider validType
     *
     * @param string $typeString
     * @param string $expectedReturnType
    }

    /**
     * @dataProvider invalidReturnTypeProvider
     *
     * @param string $typeString
     */

    /**
     * @dataProvider invalidType
     *
        TypeGenerator::fromTypeString($typeString);
    }

    public function validReturnTypeProvider()
    {
        return [
            ['foo', '\\foo'],
     * @return string[][]
     */
    public function validType()
    {
        $valid = [
            ['foo', '\\foo'],
            ['foo', '\\foo'],
            ['foo1', '\\foo1'],
            ['foo\\bar', '\\foo\\bar'],
            ['a\\b\\c', '\\a\\b\\c'],
            ['foo\\bar\\baz', '\\foo\\bar\\baz'],
            ['foo\\bar\\baz1', '\\foo\\bar\\baz1'],
            ['FOO', '\\FOO'],
            ['FOO1', '\\FOO1'],
            ['void', 'void'],
            ['Void', 'void'],
            ['VOID', 'void'],
            ['array', 'array'],
            ['Array', 'array'],
            ['ARRAY', 'array'],
            ['callable', 'callable'],
            ['Callable', 'callable'],
            ['CALLABLE', 'callable'],
            ['string', 'string'],
            ['String', 'string'],
            ['STRING', 'string'],
            ['int', 'int'],
            ['Int', 'int'],
            ['INT', 'int'],
            ['float', 'float'],
            ['Float', 'float'],
            ['FLOAT', 'float'],
            ['bool', 'bool'],
            ['Bool', 'bool'],
            ['BOOL', 'bool'],
            ['iterable', 'iterable'],
        ];
    }

    public function invalidReturnTypeProvider()
    {
        return [
            [''],
            ['\\foo'],
            ['\\FOO'],
            ['1'],
            ['?Int', '?int'],
            ['?INT', '?int'],
            ['?float', '?float'],
            ['?Float', '?float'],
            ['?FLOAT', '?float'],
            ['?bool', '?bool'],
            ['?Bool', '?bool'],
            ['?BOOL', '?bool'],
            ['?iterable', '?iterable'],
            ['?Iterable', '?iterable'],
            ['?ITERABLE', '?iterable'],
            ['?object', '?object'],
            ['?Object', '?object'],
            ['?OBJECT', '?object'],
            ['?mixed', '?\\mixed'],
            ['?Mixed', '?\\Mixed'],
            ['?MIXED', '?\\MIXED'],
            ['?resource', '?\\resource'],
            ['?Resource', '?\\Resource'],
            ['?RESOURCE', '?\\RESOURCE'],
            ['?foo_bar', '?\\foo_bar'],
            ["\x80", "\\\x80"],
            ["\x80\\\x80", "\\\x80\\\x80"],
        ];

        return array_combine(
            array_map('reset', $valid),
            $valid
        );
    }

    /**
     * Valid class names - just the same as validType, but with only those elements prefixed by '\\'
     *
     * @return string[][]
     */
    public function validClassName()
    {
        return array_filter(
            $this->validType(),
            function (array $pair) {
                return 0 === strpos($pair[1], '\\');
            }
        );
    }

    /**
     * @return string[][]
     */
    public function invalidType()
    {
        $invalid = [
            [''],
            ['\\'],
            ['\\\\'],
            ['\\\\foo'],
            ["\x7f"],
            ["foo\\\x7f"],
            ["foo\x7f\\foo"],
            ['1'],
            ['\\1'],
            ['\\1\\2'],
            ['foo\\1'],
            ['foo\\bar\\1'],
            ['1foo'],
            ['foo\\1foo'],
            ['*'],
            ["\0"],
            ['\\array'],
            ['\\Array'],
            ['\\ARRAY'],
            ['\\callable'],
            ['\\Callable'],
            ['\\CALLABLE'],
            ['\\string'],
            ['\\String'],
            ['\\STRING'],
            ['\\int'],
            ['\\Int'],
            ['\\INT'],
            ['\\float'],
            ['\\Float'],
            ['\\FLOAT'],
            ['\\bool'],
            ['\\Bool'],
            ['\\BOOL'],
            ['\\void'],
            ['\\Void'],
            ['\\VOID'],
            ['?void'],
            ['?Void'],
            ['?VOID'],
            ['\\iterable'],
            ['\\Iterable'],
            ['\\ITERABLE'],
            ['\\object'],
            ['\\Object'],
            ['\\OBJECT'],
        ];

        return array_combine(
            array_map('reset', $invalid),
            $invalid
        );
    }
}

<MSG> zendframework/zend-code#29 - types prefixed with `\\` should also be accepted (if they are classes/interfaces)

<DFF> @@ -28,7 +28,7 @@ class TypeGeneratorTest extends \PHPUnit_Framework_TestCase
     }
 
     /**
-     * @dataProvider validReturnTypeProvider
+     * @dataProvider validTypeProvider
      *
      * @param string $typeString
      * @param string $expectedReturnType
@@ -41,7 +41,7 @@ class TypeGeneratorTest extends \PHPUnit_Framework_TestCase
     }
 
     /**
-     * @dataProvider validReturnTypeProvider
+     * @dataProvider validTypeProvider
      *
      * @param string $typeString
      * @param string $expectedReturnType
@@ -54,7 +54,21 @@ class TypeGeneratorTest extends \PHPUnit_Framework_TestCase
     }
 
     /**
-     * @dataProvider invalidReturnTypeProvider
+     * @dataProvider validClassNameProvider
+     *
+     * @param string $typeString
+     * @param string $expectedReturnType
+     */
+    public function testStripsPrefixingBackslashFromClassNames(string $typeString, string $expectedReturnType)
+    {
+        $generator = TypeGenerator::fromTypeString('\\' . $typeString);
+
+        self::assertSame($expectedReturnType, $generator->generate());
+        self::assertSame($expectedReturnType, (string) $generator);
+    }
+
+    /**
+     * @dataProvider invalidTypeProvider
      *
      * @param string $typeString
      */
@@ -65,7 +79,10 @@ class TypeGeneratorTest extends \PHPUnit_Framework_TestCase
         TypeGenerator::fromTypeString($typeString);
     }
 
-    public function validReturnTypeProvider()
+    /**
+     * @return string[][]
+     */
+    public function validTypeProvider()
     {
         return [
             ['foo', '\\foo'],
@@ -108,10 +125,31 @@ class TypeGeneratorTest extends \PHPUnit_Framework_TestCase
         ];
     }
 
-    public function invalidReturnTypeProvider()
+    /**
+     * Valid class names - just the same as validTypeProvider, but with only those elements prefixed by '\\'
+     *
+     * @return string[][]
+     */
+    public function validClassNameProvider()
+    {
+        return array_filter(
+            $this->validTypeProvider(),
+            function (array $pair) {
+                return 0 === strpos($pair[1], '\\');
+            }
+        );
+    }
+
+    /**
+     * @return string[][]
+     */
+    public function invalidTypeProvider()
     {
         return [
             [''],
+            ['\\'],
+            ['\\\\'],
+            ['\\\\foo'],
             ['\\foo'],
             ['\\FOO'],
             ['1'],

zendframework/zend-code#29 - types prefixed with `\\` should also be accepted (if they are classes/interfaces)