Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
22 / 22
28.89% covered (danger)
28.89%
13 / 45
100.00% covered (success)
100.00%
5 / 5
CRAP
100.00% covered (success)
100.00%
1 / 1
Args
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
22 / 22
28.89% covered (danger)
28.89%
13 / 45
100.00% covered (success)
100.00%
5 / 5
63.78
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
15 / 15
20.00% covered (danger)
20.00%
8 / 40
100.00% covered (success)
100.00%
1 / 1
32.09
 get
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 getNamed
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
 count
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
 type
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\Quma;
6
7use InvalidArgumentException;
8
9/**
10 * @psalm-type ArgsArray = list<mixed>|array<string, mixed>
11 */
12final class Args
13{
14    private ArgType $type;
15    private int $count;
16
17    /** @var list<mixed> */
18    private readonly array $positional;
19
20    /** @var array<string, mixed> */
21    private readonly array $named;
22
23    /** @param array<array-key, mixed> $args */
24    public function __construct(array $args)
25    {
26        $this->count = count($args);
27        $values = $this->count === 1 && array_key_exists(0, $args) && is_array($args[0]) ? $args[0] : $args;
28
29        if (array_is_list($values)) {
30            $this->type = ArgType::Positional;
31            $this->positional = $values;
32            $this->named = [];
33
34            return;
35        }
36
37        $names = [];
38
39        foreach (array_keys($values) as $key) {
40            if (is_int($key)) {
41                throw new InvalidArgumentException(
42                    'Query arguments must be either a list of positional values or named values with string keys',
43                );
44            }
45
46            $names[] = $key;
47        }
48
49        $this->type = ArgType::Named;
50        $this->positional = [];
51        $this->named = array_combine($names, $values);
52    }
53
54    /** @psalm-return ArgsArray */
55    public function get(): array
56    {
57        return $this->type === ArgType::Named ? $this->named : $this->positional;
58    }
59
60    /** @return array<string, mixed> */
61    public function getNamed(): array
62    {
63        return $this->named;
64    }
65
66    public function count(): int
67    {
68        return $this->count;
69    }
70
71    public function type(): ArgType
72    {
73        return $this->type;
74    }
75}

Branches

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

Args->__construct
24    public function __construct(array $args)
25    {
26        $this->count = count($args);
27        $values = $this->count === 1 && array_key_exists(0, $args) && is_array($args[0]) ? $args[0] : $args;
27        $values = $this->count === 1 && array_key_exists(0, $args) && is_array($args[0]) ? $args[0] : $args;
27        $values = $this->count === 1 && array_key_exists(0, $args) && is_array($args[0]) ? $args[0] : $args;
27        $values = $this->count === 1 && array_key_exists(0, $args) && is_array($args[0]) ? $args[0] : $args;
27        $values = $this->count === 1 && array_key_exists(0, $args) && is_array($args[0]) ? $args[0] : $args;
27        $values = $this->count === 1 && array_key_exists(0, $args) && is_array($args[0]) ? $args[0] : $args;
27        $values = $this->count === 1 && array_key_exists(0, $args) && is_array($args[0]) ? $args[0] : $args;
27        $values = $this->count === 1 && array_key_exists(0, $args) && is_array($args[0]) ? $args[0] : $args;
28
29        if (array_is_list($values)) {
30            $this->type = ArgType::Positional;
31            $this->positional = $values;
32            $this->named = [];
33
34            return;
37        $names = [];
38
39        foreach (array_keys($values) as $key) {
39        foreach (array_keys($values) as $key) {
40            if (is_int($key)) {
41                throw new InvalidArgumentException(
42                    'Query arguments must be either a list of positional values or named values with string keys',
39        foreach (array_keys($values) as $key) {
40            if (is_int($key)) {
41                throw new InvalidArgumentException(
42                    'Query arguments must be either a list of positional values or named values with string keys',
43                );
44            }
45
46            $names[] = $key;
39        foreach (array_keys($values) as $key) {
40            if (is_int($key)) {
41                throw new InvalidArgumentException(
42                    'Query arguments must be either a list of positional values or named values with string keys',
43                );
44            }
45
46            $names[] = $key;
47        }
48
49        $this->type = ArgType::Named;
50        $this->positional = [];
51        $this->named = array_combine($names, $values);
52    }
Args->count
68        return $this->count;
69    }
Args->get
57        return $this->type === ArgType::Named ? $this->named : $this->positional;
57        return $this->type === ArgType::Named ? $this->named : $this->positional;
57        return $this->type === ArgType::Named ? $this->named : $this->positional;
57        return $this->type === ArgType::Named ? $this->named : $this->positional;
58    }
Args->getNamed
63        return $this->named;
64    }
Args->type
73        return $this->type;
74    }