<commit_before><?php

declare(strict_types=1);

namespace Roave\BetterReflectionTest\Reflection;

use PhpParser\BuilderHelpers;
use PhpParser\Node;
use PHPUnit\Framework\TestCase;
use Roave\BetterReflection\Reflection\ReflectionConstant;
use Roave\BetterReflection\Reflector\DefaultReflector;
use Roave\BetterReflection\SourceLocator\Ast\Locator;
use Roave\BetterReflection\SourceLocator\Located\LocatedSource;
use Roave\BetterReflection\SourceLocator\SourceStubber\SourceStubber;
use Roave\BetterReflection\SourceLocator\Type\AggregateSourceLocator;
use Roave\BetterReflection\SourceLocator\Type\PhpInternalSourceLocator;
use Roave\BetterReflection\SourceLocator\Type\SingleFileSourceLocator;
use Roave\BetterReflection\SourceLocator\Type\StringSourceLocator;
use Roave\BetterReflectionTest\BetterReflectionSingleton;

use function sprintf;

use const E_ALL;

/**
 * @covers \Roave\BetterReflection\Reflection\ReflectionConstant
 */
class ReflectionConstantTest extends TestCase
{
    private Locator $astLocator;

    private SourceStubber $sourceStubber;

    protected function setUp(): void
    {
        parent::setUp();

        $configuration       = BetterReflectionSingleton::instance();
        $this->astLocator    = $configuration->astLocator();
        $this->sourceStubber = $configuration->sourceStubber();
    }

    public function testNameMethodsWithNoNamespaceByConst(): void
    {
        $php = '<?php const FOO = 1;';

        $reflector  = new DefaultReflector(new StringSourceLocator($php, $this->astLocator));
        $reflection = $reflector->reflectConstant('FOO');

        self::assertFalse($reflection->inNamespace());
        self::assertSame('FOO', $reflection->getName());
        self::assertSame('', $reflection->getNamespaceName());
        self::assertSame('FOO', $reflection->getShortName());
    }

    public function testNameMethodsWithNoNamespaceByDefine(): void
    {
        $php = '<?php define("FOO", 1);';

        $reflector  = new DefaultReflector(new StringSourceLocator($php, $this->astLocator));
        $reflection = $reflector->reflectConstant('FOO');

        self::assertFalse($reflection->inNamespace());
        self::assertSame('FOO', $reflection->getName());
        self::assertSame('', $reflection->getNamespaceName());
        self::assertSame('FOO', $reflection->getShortName());
    }

    public function testNameMethodsWithNamespaceByDefine(): void
    {
        $php = '<?php define("A\B\FOO", 1);';

        $reflector  = new DefaultReflector(new StringSourceLocator($php, $this->astLocator));
        $reflection = $reflector->reflectConstant('A\B\FOO');

        self::assertTrue($reflection->inNamespace());
        self::assertSame('A\B\FOO', $reflection->getName());
        self::assertSame('A\B', $reflection->getNamespaceName());
        self::assertSame('FOO', $reflection->getShortName());
    }

    public function testNameMethodsInNamespace(): void
    {
        $php = '<?php namespace A\B { const FOO = 1; }';

        $reflector  = new DefaultReflector(new StringSourceLocator($php, $this->astLocator));
        $reflection = $reflector->reflectConstant('A\B\FOO');

        self::assertTrue($reflection->inNamespace());
        self::assertSame('A\B\FOO', $reflection->getName());
        self::assertSame('A\B', $reflection->getNamespaceName());
        self::assertSame('FOO', $reflection->getShortName());
    }

    public function testNameMethodsInExplicitGlobalNamespace(): void
    {
        $php = '<?php namespace { const FOO = 1; }';

        $reflector  = new DefaultReflector(new StringSourceLocator($php, $this->astLocator));
        $reflection = $reflector->reflectConstant('FOO');

        self::assertFalse($reflection->inNamespace());
        self::assertSame('FOO', $reflection->getName());
        self::assertSame('', $reflection->getNamespaceName());
        self::assertSame('FOO', $reflection->getShortName());
    }

    public function testIsUserDefined(): void
    {
        $php = '<?php const FOO = 1;';

        $reflector  = new DefaultReflector(new StringSourceLocator($php, $this->astLocator));
        $reflection = $reflector->reflectConstant('FOO');

        self::assertTrue($reflection->isUserDefined());
        self::assertFalse($reflection->isInternal());
        self::assertNull($reflection->getExtensionName());
    }

    public function testIsInternal(): void
    {
        $reflector  = new DefaultReflector(new PhpInternalSourceLocator($this->astLocator, $this->sourceStubber));
        $reflection = $reflector->reflectConstant('E_ALL');

        self::assertTrue($reflection->isInternal());
        self::assertFalse($reflection->isUserDefined());
        self::assertSame('Core', $reflection->getExtensionName());
    }

    public function testGetValueByConst(): void
    {
        $php = '<?php const FOO = 1;';

        $reflector  = new DefaultReflector(new StringSourceLocator($php, $this->astLocator));
        $reflection = $reflector->reflectConstant('FOO');

        self::assertSame(1, $reflection->getValue());
        // Because of code coverage - should use optimization
        self::assertSame(1, $reflection->getValue());
    }

    public function testGetValueByDefine(): void
    {
        $php = '<?php define("FOO", E_ALL);';

        $reflector  = new DefaultReflector(new AggregateSourceLocator([
            new StringSourceLocator($php, $this->astLocator),
            new PhpInternalSourceLocator($this->astLocator, $this->sourceStubber),
        ]));
        $reflection = $reflector->reflectConstant('FOO');

        self::assertSame(E_ALL, $reflection->getValue());
    }

    public function testStaticCreationFromNameByConst(): void
    {
        require_once __DIR__ . '/../Fixture/Constants.php';<commit_msg>Added missing test for ReflectionConstant<commit_after><?php

declare(strict_types=1);

namespace Roave\BetterReflectionTest\Reflection;

use PhpParser\BuilderHelpers;
use PhpParser\Node;
use PHPUnit\Framework\TestCase;
use Roave\BetterReflection\Reflection\Exception\InvalidConstantNode;
use Roave\BetterReflection\Reflection\ReflectionConstant;
use Roave\BetterReflection\Reflector\DefaultReflector;
use Roave\BetterReflection\Reflector\Reflector;
use Roave\BetterReflection\SourceLocator\Ast\Locator;
use Roave\BetterReflection\SourceLocator\Located\LocatedSource;
use Roave\BetterReflection\SourceLocator\SourceStubber\SourceStubber;
use Roave\BetterReflection\SourceLocator\Type\AggregateSourceLocator;
use Roave\BetterReflection\SourceLocator\Type\PhpInternalSourceLocator;
use Roave\BetterReflection\SourceLocator\Type\SingleFileSourceLocator;
use Roave\BetterReflection\SourceLocator\Type\StringSourceLocator;
use Roave\BetterReflectionTest\BetterReflectionSingleton;

use function sprintf;

use const E_ALL;

/**
 * @covers \Roave\BetterReflection\Reflection\ReflectionConstant
 */
class ReflectionConstantTest extends TestCase
{
    private Locator $astLocator;

    private SourceStubber $sourceStubber;

    protected function setUp(): void
    {
        parent::setUp();

        $configuration       = BetterReflectionSingleton::instance();
        $this->astLocator    = $configuration->astLocator();
        $this->sourceStubber = $configuration->sourceStubber();
    }

    public function testNameMethodsWithNoNamespaceByConst(): void
    {
        $php = '<?php const FOO = 1;';

        $reflector  = new DefaultReflector(new StringSourceLocator($php, $this->astLocator));
        $reflection = $reflector->reflectConstant('FOO');

        self::assertFalse($reflection->inNamespace());
        self::assertSame('FOO', $reflection->getName());
        self::assertSame('', $reflection->getNamespaceName());
        self::assertSame('FOO', $reflection->getShortName());
    }

    public function testNameMethodsWithNoNamespaceByDefine(): void
    {
        $php = '<?php define("FOO", 1);';

        $reflector  = new DefaultReflector(new StringSourceLocator($php, $this->astLocator));
        $reflection = $reflector->reflectConstant('FOO');

        self::assertFalse($reflection->inNamespace());
        self::assertSame('FOO', $reflection->getName());
        self::assertSame('', $reflection->getNamespaceName());
        self::assertSame('FOO', $reflection->getShortName());
    }

    public function testNameMethodsWithNamespaceByDefine(): void
    {
        $php = '<?php define("A\B\FOO", 1);';

        $reflector  = new DefaultReflector(new StringSourceLocator($php, $this->astLocator));
        $reflection = $reflector->reflectConstant('A\B\FOO');

        self::assertTrue($reflection->inNamespace());
        self::assertSame('A\B\FOO', $reflection->getName());
        self::assertSame('A\B', $reflection->getNamespaceName());
        self::assertSame('FOO', $reflection->getShortName());
    }

    public function testNameMethodsInNamespace(): void
    {
        $php = '<?php namespace A\B { const FOO = 1; }';

        $reflector  = new DefaultReflector(new StringSourceLocator($php, $this->astLocator));
        $reflection = $reflector->reflectConstant('A\B\FOO');

        self::assertTrue($reflection->inNamespace());
        self::assertSame('A\B\FOO', $reflection->getName());
        self::assertSame('A\B', $reflection->getNamespaceName());
        self::assertSame('FOO', $reflection->getShortName());
    }

    public function testNameMethodsInExplicitGlobalNamespace(): void
    {
        $php = '<?php namespace { const FOO = 1; }';

        $reflector  = new DefaultReflector(new StringSourceLocator($php, $this->astLocator));
        $reflection = $reflector->reflectConstant('FOO');

        self::assertFalse($reflection->inNamespace());
        self::assertSame('FOO', $reflection->getName());
        self::assertSame('', $reflection->getNamespaceName());
        self::assertSame('FOO', $reflection->getShortName());
    }

    public function testIsUserDefined(): void
    {
        $php = '<?php const FOO = 1;';

        $reflector  = new DefaultReflector(new StringSourceLocator($php, $this->astLocator));
        $reflection = $reflector->reflectConstant('FOO');

        self::assertTrue($reflection->isUserDefined());
        self::assertFalse($reflection->isInternal());
        self::assertNull($reflection->getExtensionName());
    }

    public function testIsInternal(): void
    {
        $reflector  = new DefaultReflector(new PhpInternalSourceLocator($this->astLocator, $this->sourceStubber));
        $reflection = $reflector->reflectConstant('E_ALL');

        self::assertTrue($reflection->isInternal());
        self::assertFalse($reflection->isUserDefined());
        self::assertSame('Core', $reflection->getExtensionName());
    }

    public function testGetValueByConst(): void
    {
        $php = '<?php const FOO = 1;';

        $reflector  = new DefaultReflector(new StringSourceLocator($php, $this->astLocator));
        $reflection = $reflector->reflectConstant('FOO');

        self::assertSame(1, $reflection->getValue());
        // Because of code coverage - should use optimization
        self::assertSame(1, $reflection->getValue());
    }

    public function testGetValueByDefine(): void
    {
        $php = '<?php define("FOO", E_ALL);';

        $reflector  = new DefaultReflector(new AggregateSourceLocator([
            new StringSourceLocator($php, $this->astLocator),
            new PhpInternalSourceLocator($this->astLocator, $this->sourceStubber),
        ]));
        $reflection = $reflector->reflectConstant('FOO');

        self::assertSame(E_ALL, $reflection->getValue());
    }

    public function testCreateFromNodeWithInvalidDefine(): void
    {
        self::expectException(InvalidConstantNode::class);
        ReflectionConstant::createFromNode(
            $this->createMock(Reflector::class),
            new Node\Expr\FuncCall(new Node\Expr\Variable('foo')),
            $this->createMock(LocatedSource::class),
        );
    }

    public function testStaticCreationFromNameByConst(): void
    {
        require_once __DIR__ . '/../Fixture/Constants.php';
{'fraction_non_alphanumeric': 0.14352043777464554, 'fraction_numerical': 0.0016582372937567365, 'mean_word_length': 3.933333333333333, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 113, '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': '6606297', 'n_tokens_mistral': 3469, 'n_tokens_neox': 3402, 'n_words': 548}