Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
38 / 38
100.00% covered (success)
100.00%
9 / 9
CRAP
100.00% covered (success)
100.00%
1 / 1
Environment
100.00% covered (success)
100.00%
38 / 38
100.00% covered (success)
100.00%
9 / 9
21
100.00% covered (success)
100.00%
1 / 1
 setWrapper
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
4
 setFilters
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 setEscapers
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 wrapper
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 registerFilter
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
3
 registerEscaper
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
3
 filters
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 escapers
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 assertNotSealed
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare(strict_types=1);
4
5namespace Celemas\Boiler;
6
7use Celemas\Boiler\Exception\RuntimeException;
8use Override;
9
10/** @api */
11final class Environment implements Contract\Environment
12{
13    private ?Contract\Wrapper $wrapper = null;
14    private ?Contract\Filters $filters = null;
15    private ?Contract\Escapers $escapers = null;
16    private bool $sealed = false;
17
18    public function setWrapper(Contract\Wrapper $wrapper): void
19    {
20        $this->assertNotSealed();
21
22        if ($this->filters !== null || $this->escapers !== null) {
23            throw new RuntimeException('Cannot set wrapper after filters or escapers are configured');
24        }
25
26        if ($this->wrapper !== null) {
27            throw new RuntimeException('Wrapper is already configured');
28        }
29
30        $this->wrapper = $wrapper;
31    }
32
33    public function setFilters(Contract\Filters $filters): void
34    {
35        $this->assertNotSealed();
36
37        if ($this->wrapper !== null) {
38            throw new RuntimeException('Cannot set filters after wrapper is configured');
39        }
40
41        if ($this->filters !== null) {
42            throw new RuntimeException('Filters are already configured');
43        }
44
45        $this->filters = $filters;
46    }
47
48    public function setEscapers(Contract\Escapers $escapers): void
49    {
50        $this->assertNotSealed();
51
52        if ($this->wrapper !== null) {
53            throw new RuntimeException('Cannot set escapers after wrapper is configured');
54        }
55
56        if ($this->escapers !== null) {
57            throw new RuntimeException('Escapers are already configured');
58        }
59
60        $this->escapers = $escapers;
61    }
62
63    #[Override]
64    public function wrapper(): Contract\Wrapper
65    {
66        $this->sealed = true;
67
68        return $this->wrapper ??= new Wrapper($this->escapers, $this->filters);
69    }
70
71    #[Override]
72    public function registerFilter(string $name, Contract\Filter $filter): void
73    {
74        $this->assertNotSealed();
75
76        if ($this->wrapper !== null) {
77            throw new RuntimeException('Cannot register filter after wrapper is configured');
78        }
79
80        $filters = $this->filters();
81
82        if (!$filters instanceof Contract\RegistersFilters) {
83            throw new RuntimeException('Configured filters registry does not support filter registration');
84        }
85
86        $filters->register($name, $filter);
87    }
88
89    #[Override]
90    public function registerEscaper(string $name, Contract\Escaper $escaper): void
91    {
92        $this->assertNotSealed();
93
94        if ($this->wrapper !== null) {
95            throw new RuntimeException('Cannot register escaper after wrapper is configured');
96        }
97
98        $escapers = $this->escapers();
99
100        if (!$escapers instanceof Contract\RegistersEscapers) {
101            throw new RuntimeException('Configured escapers registry does not support escaper registration');
102        }
103
104        $escapers->register($name, $escaper);
105    }
106
107    private function filters(): Contract\Filters
108    {
109        return $this->filters ??= new Filters();
110    }
111
112    private function escapers(): Contract\Escapers
113    {
114        return $this->escapers ??= new Escapers();
115    }
116
117    private function assertNotSealed(): void
118    {
119        if ($this->sealed) {
120            throw new RuntimeException('Engine configuration is sealed');
121        }
122    }
123}