<commit_before><?php

namespace StrictPhpTest\TypeFinder;

use phpDocumentor\Reflection\Type;
use ReflectionClass;
use ReflectionProperty;
use StrictPhp\TypeFinder\PropertyTypeFinder;
use StrictPhpTestAsset\ClassWithGenericNonTypedProperty;
use StrictPhpTestAsset\ClassWithGenericStringTypedProperty;

/**
 * Tests for {@see \StrictPhp\TypeFinder\PropertyTypeFinder}
 *
 * @author <NAME> <<EMAIL>>
 * @license MIT
 *
 * @group Coverage
 */
class PropertyTypeFinderTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @covers \StrictPhp\TypeFinder\PropertyTypeFinder::__invoke
     */
    public function testInvalidReflectionPropertyReturnAEmptyArray()
    {
        $this->assertSame(
            [],
            (new PropertyTypeFinder())->__invoke(new ReflectionProperty(
                ClassWithGenericNonTypedProperty::class,
                'property'
            ))
        );
    }

    /**
     * @covers       \StrictPhp\TypeFinder\PropertyTypeFinder::__invoke
     *
     * @dataProvider mixedAnnotationTypes
     *
     * @param string $annotation with annotation
     * @param array  $expected
     */
    public function testValidReflectionPropertyReturnAEmptyArray($annotation, array $expected)
    {
        /** @var \ReflectionProperty|\PHPUnit_Framework_MockObject_MockObject $reflectionProperty */
        $reflectionProperty = $this->getMockBuilder(ReflectionProperty::class)
            ->setMethods(['getDocComment', 'getDeclaringClass'])
            ->disableOriginalConstructor()
            ->getMock();

        $reflectionProperty
            ->expects($this->any())
            ->method('getDeclaringClass')
            ->will($this->returnValue(new ReflectionClass(ClassWithGenericStringTypedProperty::class)));

        $reflectionProperty
            ->expects($this->once())
            ->method('getDocComment')
            ->will($this->returnValue($annotation));

        $this->assertSame(
            $expected,
            array_map(
                function (Type $type) {
                    return (string) $type;
                },
                (new PropertyTypeFinder())->__invoke($reflectionProperty)
            )
        );
    }

    /**
     * @return mixed[][] - string with annotation declaration
     *                   - array with result expected
     */
    public function mixedAnnotationTypes()
    {
        return [
            ['/** */', []],
            ['/** @var */', []],
            ['/** @var string */', ['string']],
            ['/** @var integer */', ['int']],
            ['/** @var int */', ['int']],
            ['/** @var bool */', ['bool']],
            ['/** @var boolean */', ['bool']],
            ['/** @var array */', ['array']],
            ['/** @var string[] */', ['string[]']],
            ['/** @var null */', ['null']],
            ['/** @var StdClass */', ['\StdClass']],
            ['/** @var \StdClass */', ['\StdClass']],
            ['/** @var \StdClass[] */', ['\StdClass[]']],
            ['/** @var \StdClass|null|array */', ['\StdClass', 'null', 'array']],
            ['/** @var \StdClass|AnotherClass */', ['\StdClass', '\AnotherClass']],
            ['/** @var mixed */', ['mixed']],
        ];
    }
}<commit_msg>Testing also complex type collections<commit_after><?php

namespace StrictPhpTest\TypeFinder;

use phpDocumentor\Reflection\Type;
use ReflectionClass;
use ReflectionProperty;
use StrictPhp\TypeFinder\PropertyTypeFinder;
use StrictPhpTestAsset\ClassWithGenericNonTypedProperty;
use StrictPhpTestAsset\ClassWithGenericStringTypedProperty;

/**
 * Tests for {@see \StrictPhp\TypeFinder\PropertyTypeFinder}
 *
 * @author <NAME> <<EMAIL>>
 * @license MIT
 *
 * @group Coverage
 */
class PropertyTypeFinderTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @covers \StrictPhp\TypeFinder\PropertyTypeFinder::__invoke
     */
    public function testInvalidReflectionPropertyReturnAEmptyArray()
    {
        $this->assertSame(
            [],
            (new PropertyTypeFinder())->__invoke(new ReflectionProperty(
                ClassWithGenericNonTypedProperty::class,
                'property'
            ))
        );
    }

    /**
     * @covers       \StrictPhp\TypeFinder\PropertyTypeFinder::__invoke
     *
     * @dataProvider mixedAnnotationTypes
     *
     * @param string $annotation with annotation
     * @param array  $expected
     */
    public function testValidReflectionPropertyReturnAEmptyArray($annotation, array $expected)
    {
        /** @var \ReflectionProperty|\PHPUnit_Framework_MockObject_MockObject $reflectionProperty */
        $reflectionProperty = $this->getMockBuilder(ReflectionProperty::class)
            ->setMethods(['getDocComment', 'getDeclaringClass'])
            ->disableOriginalConstructor()
            ->getMock();

        $reflectionProperty
            ->expects($this->any())
            ->method('getDeclaringClass')
            ->will($this->returnValue(new ReflectionClass(ClassWithGenericStringTypedProperty::class)));

        $reflectionProperty
            ->expects($this->once())
            ->method('getDocComment')
            ->will($this->returnValue($annotation));

        $this->assertSame(
            $expected,
            array_map(
                function (Type $type) {
                    return (string) $type;
                },
                (new PropertyTypeFinder())->__invoke($reflectionProperty)
            )
        );
    }

    /**
     * @return mixed[][] - string with annotation declaration
     *                   - array with result expected
     */
    public function mixedAnnotationTypes()
    {
        return [
            ['/** */', []],
            ['/** @var */', []],
            ['/** @var string */', ['string']],
            ['/** @var integer */', ['int']],
            ['/** @var int */', ['int']],
            ['/** @var bool */', ['bool']],
            ['/** @var boolean */', ['bool']],
            ['/** @var array */', ['array']],
            ['/** @var string[] */', ['string[]']],
            ['/** @var null */', ['null']],
            ['/** @var StdClass */', ['\StdClass']],
            ['/** @var \StdClass */', ['\StdClass']],
            ['/** @var \StdClass[] */', ['\StdClass[]']],
            ['/** @var \StdClass|null|array */', ['\StdClass', 'null', 'array']],
            ['/** @var \StdClass|AnotherClass */', ['\StdClass', '\AnotherClass']],
            ['/** @var \My\Collection|\Some\Thing[] */', ['\My\Collection', '\Some\Thing[]']],
            ['/** @var mixed */', ['mixed']],
        ];
    }
}
{'fraction_non_alphanumeric': 0.1707056851089773, 'fraction_numerical': 0.0, 'mean_word_length': 2.17772397094431, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5560649', 'n_tokens_mistral': 1777, 'n_tokens_neox': 1775, 'n_words': 302}