Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
41 / 41
100.00% covered (success)
100.00%
34 / 34
79.31% covered (warning)
79.31%
23 / 29
100.00% covered (success)
100.00%
15 / 15
CRAP
100.00% covered (success)
100.00%
1 / 1
Entry
100.00% covered (success)
100.00%
41 / 41
100.00% covered (success)
100.00%
34 / 34
79.31% covered (warning)
79.31%
23 / 29
100.00% covered (success)
100.00%
15 / 15
29.10
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 lifetime
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
7 / 7
50.00% covered (danger)
50.00%
4 / 8
100.00% covered (success)
100.00%
1 / 1
6.00
 shared
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 scoped
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 transient
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLifetime
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 value
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 shouldReturnValue
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 args
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
14 / 14
75.00% covered (warning)
75.00%
6 / 8
100.00% covered (success)
100.00%
1 / 1
7.77
 getArgs
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 constructor
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getConstructor
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 call
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCalls
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 definition
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace Celema\Container;
6
7use Celema\Container\Exception\ContainerException;
8use Celema\Wire\Call;
9use Closure;
10
11/** @psalm-api */
12class Entry
13{
14    /** @var array<array-key, mixed>|Closure|null */
15    protected array|Closure|null $args = null;
16
17    protected ?string $constructor = null;
18    protected bool $value = false;
19    protected Lifetime $lifetime = Lifetime::Shared;
20
21    /** @var list<Call> */
22    protected array $calls = [];
23
24    /**
25     * @param non-empty-string $id
26     */
27    public function __construct(
28        public readonly string $id,
29        protected mixed $definition,
30    ) {}
31
32    public function lifetime(Lifetime $lifetime): static
33    {
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
35            throw new ContainerException(
36                "Entry '{$this->id}' is a prebuilt object, which can only be shared. Register a class name "
37                    . 'or a closure to create one instance per scope or per resolution.',
38            );
39        }
40
41        $this->lifetime = $lifetime;
42
43        return $this;
44    }
45
46    public function shared(): static
47    {
48        return $this->lifetime(Lifetime::Shared);
49    }
50
51    public function scoped(): static
52    {
53        return $this->lifetime(Lifetime::Scoped);
54    }
55
56    public function transient(): static
57    {
58        return $this->lifetime(Lifetime::Transient);
59    }
60
61    public function getLifetime(): Lifetime
62    {
63        return $this->lifetime;
64    }
65
66    public function value(bool $value = true): static
67    {
68        $this->value = $value;
69
70        return $this;
71    }
72
73    public function shouldReturnValue(): bool
74    {
75        return $this->value;
76    }
77
78    public function args(mixed ...$args): static
79    {
80        $numArgs = count($args);
81
82        if ($numArgs === 1) {
83            if (is_string(array_key_first($args))) {
84                $this->args = $args;
85            } elseif (is_array($args[0]) || $args[0] instanceof Closure) {
86                $this->args = $args[0];
87            } else {
88                throw new ContainerException(
89                    'Container entry arguments can be passed as a single associative array, '
90                        . 'as named arguments, or as a Closure',
91                );
92            }
93        } elseif ($numArgs > 1) {
94            if (!is_string(array_key_first($args))) {
95                throw new ContainerException(
96                    'Container entry arguments can be passed as a single associative array, '
97                        . 'as named arguments, or as a Closure',
98                );
99            }
100
101            $this->args = $args;
102        }
103
104        return $this;
105    }
106
107    /** @return array<array-key, mixed>|Closure|null */
108    public function getArgs(): array|Closure|null
109    {
110        return $this->args;
111    }
112
113    public function constructor(string $methodName): static
114    {
115        $this->constructor = $methodName;
116
117        return $this;
118    }
119
120    public function getConstructor(): ?string
121    {
122        return $this->constructor;
123    }
124
125    public function call(string $method, mixed ...$args): static
126    {
127        $this->calls[] = new Call($method, ...$args);
128
129        return $this;
130    }
131
132    /** @return list<Call> */
133    public function getCalls(): array
134    {
135        return $this->calls;
136    }
137
138    public function definition(): mixed
139    {
140        return $this->definition;
141    }
142}

Paths

Below are the source code lines that represent each code path as identified by Xdebug. Please note a path is not necessarily coterminous with a line, a line may contain multiple paths and therefore show up more than once. Please also be aware that some paths may include implicit rather than explicit branches, e.g. an if statement always has an else as part of its logical flow even if you didn't write one.

Entry->__construct
28        public readonly string $id,
29        protected mixed $definition,
30    ) {}
Entry->args
78    public function args(mixed ...$args): static
79    {
80        $numArgs = count($args);
81
82        if ($numArgs === 1) {
 
83            if (is_string(array_key_first($args))) {
 
83            if (is_string(array_key_first($args))) {
84                $this->args = $args;
 
82        if ($numArgs === 1) {
 
104        return $this;
105    }
78    public function args(mixed ...$args): static
79    {
80        $numArgs = count($args);
81
82        if ($numArgs === 1) {
 
83            if (is_string(array_key_first($args))) {
 
85            } elseif (is_array($args[0]) || $args[0] instanceof Closure) {
 
85            } elseif (is_array($args[0]) || $args[0] instanceof Closure) {
 
85            } elseif (is_array($args[0]) || $args[0] instanceof Closure) {
 
85            } elseif (is_array($args[0]) || $args[0] instanceof Closure) {
86                $this->args = $args[0];
 
82        if ($numArgs === 1) {
 
104        return $this;
105    }
78    public function args(mixed ...$args): static
79    {
80        $numArgs = count($args);
81
82        if ($numArgs === 1) {
 
83            if (is_string(array_key_first($args))) {
 
85            } elseif (is_array($args[0]) || $args[0] instanceof Closure) {
 
85            } elseif (is_array($args[0]) || $args[0] instanceof Closure) {
 
85            } elseif (is_array($args[0]) || $args[0] instanceof Closure) {
 
88                throw new ContainerException(
89                    'Container entry arguments can be passed as a single associative array, '
90                        . 'as named arguments, or as a Closure',
78    public function args(mixed ...$args): static
79    {
80        $numArgs = count($args);
81
82        if ($numArgs === 1) {
 
83            if (is_string(array_key_first($args))) {
 
85            } elseif (is_array($args[0]) || $args[0] instanceof Closure) {
 
85            } elseif (is_array($args[0]) || $args[0] instanceof Closure) {
 
85            } elseif (is_array($args[0]) || $args[0] instanceof Closure) {
86                $this->args = $args[0];
 
82        if ($numArgs === 1) {
 
104        return $this;
105    }
78    public function args(mixed ...$args): static
79    {
80        $numArgs = count($args);
81
82        if ($numArgs === 1) {
 
83            if (is_string(array_key_first($args))) {
 
85            } elseif (is_array($args[0]) || $args[0] instanceof Closure) {
 
85            } elseif (is_array($args[0]) || $args[0] instanceof Closure) {
 
88                throw new ContainerException(
89                    'Container entry arguments can be passed as a single associative array, '
90                        . 'as named arguments, or as a Closure',
78    public function args(mixed ...$args): static
79    {
80        $numArgs = count($args);
81
82        if ($numArgs === 1) {
 
93        } elseif ($numArgs > 1) {
 
94            if (!is_string(array_key_first($args))) {
 
95                throw new ContainerException(
96                    'Container entry arguments can be passed as a single associative array, '
97                        . 'as named arguments, or as a Closure',
78    public function args(mixed ...$args): static
79    {
80        $numArgs = count($args);
81
82        if ($numArgs === 1) {
 
93        } elseif ($numArgs > 1) {
 
94            if (!is_string(array_key_first($args))) {
 
101            $this->args = $args;
102        }
103
104        return $this;
 
104        return $this;
105    }
78    public function args(mixed ...$args): static
79    {
80        $numArgs = count($args);
81
82        if ($numArgs === 1) {
 
93        } elseif ($numArgs > 1) {
 
104        return $this;
105    }
Entry->call
125    public function call(string $method, mixed ...$args): static
126    {
127        $this->calls[] = new Call($method, ...$args);
128
129        return $this;
130    }
Entry->constructor
113    public function constructor(string $methodName): static
114    {
115        $this->constructor = $methodName;
116
117        return $this;
118    }
Entry->definition
140        return $this->definition;
141    }
Entry->getArgs
110        return $this->args;
111    }
Entry->getCalls
135        return $this->calls;
136    }
Entry->getConstructor
122        return $this->constructor;
123    }
Entry->getLifetime
63        return $this->lifetime;
64    }
Entry->lifetime
32    public function lifetime(Lifetime $lifetime): static
33    {
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
35            throw new ContainerException(
36                "Entry '{$this->id}' is a prebuilt object, which can only be shared. Register a class name "
37                    . 'or a closure to create one instance per scope or per resolution.',
32    public function lifetime(Lifetime $lifetime): static
33    {
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
41        $this->lifetime = $lifetime;
42
43        return $this;
44    }
32    public function lifetime(Lifetime $lifetime): static
33    {
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
35            throw new ContainerException(
36                "Entry '{$this->id}' is a prebuilt object, which can only be shared. Register a class name "
37                    . 'or a closure to create one instance per scope or per resolution.',
32    public function lifetime(Lifetime $lifetime): static
33    {
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
41        $this->lifetime = $lifetime;
42
43        return $this;
44    }
32    public function lifetime(Lifetime $lifetime): static
33    {
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
35            throw new ContainerException(
36                "Entry '{$this->id}' is a prebuilt object, which can only be shared. Register a class name "
37                    . 'or a closure to create one instance per scope or per resolution.',
32    public function lifetime(Lifetime $lifetime): static
33    {
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
41        $this->lifetime = $lifetime;
42
43        return $this;
44    }
32    public function lifetime(Lifetime $lifetime): static
33    {
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
35            throw new ContainerException(
36                "Entry '{$this->id}' is a prebuilt object, which can only be shared. Register a class name "
37                    . 'or a closure to create one instance per scope or per resolution.',
32    public function lifetime(Lifetime $lifetime): static
33    {
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
34        if ($lifetime !== Lifetime::Shared && is_object($this->definition) && !$this->definition instanceof Closure) {
 
41        $this->lifetime = $lifetime;
42
43        return $this;
44    }
Entry->scoped
53        return $this->lifetime(Lifetime::Scoped);
54    }
Entry->shared
48        return $this->lifetime(Lifetime::Shared);
49    }
Entry->shouldReturnValue
75        return $this->value;
76    }
Entry->transient
58        return $this->lifetime(Lifetime::Transient);
59    }
Entry->value
66    public function value(bool $value = true): static
67    {
68        $this->value = $value;
69
70        return $this;
71    }