ScenarioRepository::add()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 6
ccs 4
cts 4
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace WSW\BrowserAutomation\Scenario;
6
7
use Facebook\WebDriver\WebDriver;
8
use InvalidArgumentException;
9
use RuntimeException;
10
use SplObjectStorage;
11
use WSW\BrowserAutomation\Scenario\Dispatcher\Dispatcher;
12
use WSW\BrowserAutomation\Scenario\Dispatcher\DispatcherInterface;
13
14
/**
15
 * Class ScenarioRepository
16
 *
17
 * @package WSW\BrowserAutomation\Scenario
18
 */
19
class ScenarioRepository implements ScenarioRepositoryInterface
20
{
21
    /**
22
     * @var string control characters for keys.
23
     */
24
    const KEY_REGEX = '/[^a-z_\-0-9.]/i';
25
26
    /**
27
     * @var SplObjectStorage
28
     */
29
    private $storage;
30
31
    /**
32
     * @var DispatcherInterface
33
     */
34
    private $dispatcher;
35
36
    /**
37
     * Scenario constructor.
38
     *
39
     * @param DispatcherInterface $dispatcher
40
     */
41 33
    public function __construct(DispatcherInterface $dispatcher = null)
42
    {
43 33
        $this->storage = new SplObjectStorage;
44 33
        $this->dispatcher = $dispatcher ?? new Dispatcher();
45 33
    }
46
47
    /**
48
     * {@inheritdoc}
49
     */
50 30
    public function add(string $name, callable $callback): ScenarioRepositoryInterface
51
    {
52 30
        $this->validateKey($name);
53 24
        $this->storage->attach(new Scenario($name, $callback));
54
55 24
        return $this;
56
    }
57
58
    /**
59
     * {@inheritdoc}
60
     */
61 24
    public function has(string $name): bool
62
    {
63 24
        $this->validateKey($name);
64
65 18
        return !is_null($this->search($name));
66
    }
67
68
    /**
69
     * {@inheritdoc}
70
     */
71 18
    public function get(string $name): Scenario
72
    {
73 18
        if (!$this->has($name)) {
74 6
            throw new RuntimeException('The scenario "' . $name . '" does not exists.', 404);
75
        }
76
77 9
        return $this->search($name);
78
    }
79
80
    /**
81
     * {@inheritdoc}
82
     */
83 9
    public function dispatch(array $scenarios, WebDriver $driver): array
84
    {
85 9
        $result = ['scenarios' => []];
86
87 9
        foreach ($scenarios as $item) {
88 9
            $scenario = $this->get($item);
89 6
            $result['scenarios'][] = $this->dispatcher->dispatch($scenario, $driver);
90
        }
91
92 6
        return $result;
93
    }
94
95
    /**
96
     * Check if scenario name is valid.
97
     *
98
     * @param string $key
99
     * @throws InvalidArgumentException
100
     *
101
     * @return void
102
     */
103 33
    private function validateKey(string $key): void
104
    {
105 33
        if (preg_match(static::KEY_REGEX, $key)) {
106 12
            throw new InvalidArgumentException('Invalid character in scenario name: "'.$key.'"', 400);
107
        }
108 27
    }
109
110
    /**
111
     * Search object in our storage.
112
     *
113
     * @param string $name
114
     *
115
     * @return Scenario|null
116
     */
117 18
    private function search(string $name): ?Scenario
118
    {
119 18
        foreach ($this->storage as $scenario) {
120 15
            if ($scenario->getName() === $name) {
121 12
                return $scenario;
122
            }
123
        }
124
125 9
        return null;
126
    }
127
}
128