DocBlockResolverTest   A
last analyzed

Complexity

Total Complexity 5

Size/Duplication

Total Lines 92
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 40
dl 0
loc 92
rs 10
c 0
b 0
f 0
wmc 5

5 Methods

Rating   Name   Duplication   Size   Complexity  
A test_throws_exception_when_class_definition_is_missing() 0 5 1
A serviceResolutionProvider() 0 28 1
A setUp() 0 4 1
A test_resolves_service_type_from_docblock() 0 19 1
A test_throws_exception_when_service_name_is_empty() 0 7 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace GacelaTest\Integration\Framework\ServiceResolver;
6
7
use Gacela\Framework\Bootstrap\GacelaConfig;
8
use Gacela\Framework\ClassResolver\DocBlockService\DocBlockServiceNotFoundException;
9
use Gacela\Framework\ClassResolver\DocBlockService\DocBlockServiceResolver;
10
use Gacela\Framework\ClassResolver\DocBlockService\MissingClassDefinitionException;
11
use Gacela\Framework\Gacela;
12
use Gacela\Framework\ServiceResolver\DocBlockResolvable;
13
use Gacela\Framework\ServiceResolver\DocBlockResolver;
14
use GacelaTest\Integration\Framework\ServiceResolver\Module\FakeCommand;
15
use GacelaTest\Integration\Framework\ServiceResolver\Module\FakeConfig;
16
use GacelaTest\Integration\Framework\ServiceResolver\Module\FakeFacade;
17
use GacelaTest\Integration\Framework\ServiceResolver\Module\FakeFactory;
18
use GacelaTest\Integration\Framework\ServiceResolver\Module\FakeRandomService;
19
use PHPUnit\Framework\TestCase;
20
21
use function sprintf;
22
23
final class DocBlockResolverTest extends TestCase
24
{
25
    protected function setUp(): void
26
    {
27
        Gacela::bootstrap(__DIR__, static function (GacelaConfig $config): void {
28
            $config->resetInMemoryCache();
29
        });
30
    }
31
32
    /**
33
     * Verifies that attempting to resolve a non-existent class from a @method annotation
34
     * throws MissingClassDefinitionException.
35
     */
36
    public function test_throws_exception_when_class_definition_is_missing(): void
37
    {
38
        $this->expectException(MissingClassDefinitionException::class);
39
40
        (new FakeCommand())->getUnknown();
41
    }
42
43
    /**
44
     * Verifies that DocBlockServiceResolver throws an exception when given an empty
45
     * service name, as there's no valid service to resolve.
46
     */
47
    public function test_throws_exception_when_service_name_is_empty(): void
48
    {
49
        $this->expectException(DocBlockServiceNotFoundException::class);
50
51
        $resolver = new DocBlockServiceResolver('');
52
        $command = new FakeCommand();
53
        $resolver->resolve($command);
54
    }
55
56
    /**
57
     * Tests that DocBlockResolver correctly resolves service types from @method annotations.
58
     */
59
    #[\PHPUnit\Framework\Attributes\DataProvider('serviceResolutionProvider')]
60
    public function test_resolves_service_type_from_docblock(
61
        object $caller,
62
        string $methodName,
63
        string $expectedClass,
64
        string $expectedSuffix,
65
    ): void {
66
        $resolver = DocBlockResolver::fromCaller($caller);
67
        $actual = $resolver->getDocBlockResolvable($methodName);
68
        $expected = new DocBlockResolvable($expectedClass, $expectedSuffix);
69
70
        self::assertEquals(
71
            $expected,
72
            $actual,
73
            sprintf(
74
                'Failed to resolve %s() from %s to %s',
75
                $methodName,
76
                $caller::class,
77
                $expectedClass,
78
            ),
79
        );
80
    }
81
82
    /**
83
     * Provides test cases for service resolution from different callers.
84
     *
85
     * @return iterable<string, array{object, string, class-string, string}>
86
     */
87
    public static function serviceResolutionProvider(): iterable
88
    {
89
        yield 'Facade resolution from Command' => [
90
            new FakeCommand(),
91
            'getFacade',
92
            FakeFacade::class,
93
            'Facade',
94
        ];
95
96
        yield 'Factory resolution from Facade' => [
97
            new FakeFacade(),
98
            'getFactory',
99
            FakeFactory::class,
100
            'Factory',
101
        ];
102
103
        yield 'Config resolution from Factory' => [
104
            new FakeFactory(),
105
            'getConfig',
106
            FakeConfig::class,
107
            'Config',
108
        ];
109
110
        yield 'Custom service resolution from Command' => [
111
            new FakeCommand(),
112
            'getRandom',
113
            FakeRandomService::class,
114
            'FakeRandomService',
115
        ];
116
    }
117
}
118