Passed
Pull Request — master (#9)
by Jakub
10:17 queued 11s
created

ServiceContainer.php$1 ➔ has()   A

Complexity

Conditions 2

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 2
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Zalas\Toolbox\Cli;
4
5
use Psr\Container\ContainerExceptionInterface;
6
use Psr\Container\ContainerInterface;
7
use Psr\Container\NotFoundExceptionInterface;
8
use RuntimeException;
9
use Symfony\Component\Console\Input\InputInterface;
10
use Symfony\Component\Console\Output\OutputInterface;
11
use Zalas\Toolbox\Cli\Command\InstallCommand;
12
use Zalas\Toolbox\Cli\Command\ListCommand;
13
use Zalas\Toolbox\Cli\Command\TestCommand;
14
use Zalas\Toolbox\Cli\ServiceContainer\LazyRunner;
15
use Zalas\Toolbox\Cli\ServiceContainer\RunnerFactory;
16
use Zalas\Toolbox\Json\JsonTools;
17
use Zalas\Toolbox\Runner\Runner;
18
use Zalas\Toolbox\Tool\Tools;
19
use Zalas\Toolbox\UseCase\InstallTools;
20
use Zalas\Toolbox\UseCase\ListTools;
21
use Zalas\Toolbox\UseCase\TestTools;
22
23
class ServiceContainer implements ContainerInterface
24
{
25
    private $services = [
26
        InstallCommand::class => 'createInstallCommand',
27
        ListCommand::class => 'createListCommand',
28
        TestCommand::class => 'createTestCommand',
29
        Runner::class => 'createRunner',
30
        InstallTools::class => 'createInstallToolsUseCase',
31
        ListTools::class => 'createListToolsUseCase',
32
        TestTools::class => 'createTestToolsUseCase',
33
        Tools::class => 'createTools',
34
    ];
35
36
    private $runtimeServices = [
37
        InputInterface::class => null,
38
        OutputInterface::class => null,
39
    ];
40
41 13
    public function set(string $id, /*object */$service): void
42
    {
43 13
        if (!\array_key_exists($id, $this->runtimeServices)) {
44
            throw new class(\sprintf('The "%s" runtime service is not expected.', $id)) extends RuntimeException implements ContainerExceptionInterface {
45
            };
46
        }
47
48 13
        $this->runtimeServices[$id] = $service;
49
    }
50
51
    /**
52
     * {@inheritdoc}
53
     */
54 21
    public function get($id)
55
    {
56 21
        if (isset($this->runtimeServices[$id])) {
57 3
            return $this->runtimeServices[$id];
58
        }
59
60 20
        if (isset($this->services[$id])) {
61 18
            return \call_user_func([$this, $this->services[$id]]);
62
        }
63
64
        throw new class(\sprintf('The "%s" service is not registered in the service container.', $id)) extends RuntimeException implements NotFoundExceptionInterface {
65
        };
66
    }
67
68
    /**
69
     * {@inheritdoc}
70
     */
71 21
    public function has($id)
72
    {
73 21
        return isset($this->services[$id]) || isset($this->runtimeServices[$id]);
74
    }
75
76 7
    private function createInstallCommand(): InstallCommand
77
    {
78 7
        return new InstallCommand($this->get(InstallTools::class), $this->get(Runner::class));
79
    }
80
81 4
    private function createListCommand(): ListCommand
82
    {
83 4
        return new ListCommand($this->get(ListTools::class));
84
    }
85
86 6
    private function createTestCommand(): TestCommand
87
    {
88 6
        return new TestCommand($this->get(TestTools::class), $this->get(Runner::class));
89
    }
90
91 4
    private function createRunner(): Runner
92
    {
93 4
        return new LazyRunner(new RunnerFactory($this));
94
    }
95
96 2
    private function createInstallToolsUseCase(): InstallTools
97
    {
98 2
        return new InstallTools($this->get(Tools::class));
99
    }
100
101 2
    private function createListToolsUseCase(): ListTools
102
    {
103 2
        return new ListTools($this->get(Tools::class));
104
    }
105
106 1
    private function createTestToolsUseCase(): TestTools
107
    {
108 1
        return new TestTools($this->get(Tools::class));
109
    }
110
111 5
    private function createTools(): Tools
112
    {
113
        return new JsonTools(function (): array {
114 2
            return $this->get(InputInterface::class)->getOption('tools');
115 5
        });
116
    }
117
}
118