Completed
Push — develop ( ca99c7...b953bd )
by Alec
03:03
created

AbstractCounter::buildReport()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace AlecRabbit\Tools;
4
5
use AlecRabbit\Tools\Contracts\CounterInterface;
6
use AlecRabbit\Tools\Reports\Contracts\ReportableInterface;
7
use AlecRabbit\Tools\Reports\SimpleCounterReport;
8
use AlecRabbit\Tools\Reports\Traits\HasReport;
9
use AlecRabbit\Tools\Traits\SimpleCounterFields;
10
11
abstract class AbstractCounter implements CounterInterface, ReportableInterface
12
{
13
    use SimpleCounterFields, HasReport;
14
15
16
    protected const DEFAULT_STEP = 1;
17
18
    /**
19
     * Counter constructor
20
     * @param null|string $name
21
     * @param null|int $step
22
     * @param int $initialValue
23
     * @throws \Exception
24
     */
25 28
    public function __construct(?string $name = null, ?int $step = null, int $initialValue = 0)
26
    {
27 28
        $this->name = $this->defaultName($name);
28 28
        $this->setInitialValue($initialValue);
29 28
        $this->setStep($step);
30 28
        $this->buildReport();
31 28
    }
32
33
    /**
34
     * @param int $initialValue
35
     * @return AbstractCounter
36
     */
37 28
    public function setInitialValue(int $initialValue): AbstractCounter
38
    {
39 28
        if (false === $this->isStarted()) {
40 28
            $this->updateValues($initialValue);
41
        } else {
42 1
            throw new \RuntimeException('You can\'t set counter initial value, it has been bumped already.');
43
        }
44 28
        return $this;
45
    }
46
47
    /**
48
     * @param int $initialValue
49
     */
50 18
    protected function updateValues(int $initialValue): void
51
    {
52 18
        $this->value = $this->initialValue = $initialValue;
53 18
    }
54
55
    /**
56
     * @param null|int $step
57
     * @return AbstractCounter
58
     */
59 28
    public function setStep(?int $step = null): AbstractCounter
60
    {
61 28
        $step = $this->assertStep($step);
62 28
        if (false === $this->isStarted()) {
63 28
            $this->step = $step;
64
        } else {
65 1
            throw new \RuntimeException('You can\'t set counter step value, it has been bumped already.');
66
        }
67 28
        return $this;
68
    }
69
70
    /**
71
     * @param null|int $step
72
     * @return int
73
     */
74 28
    protected function assertStep(?int $step = null): int
75
    {
76 28
        $step = $step ?? self::DEFAULT_STEP;
77 28
        if ($step === 0) {
78 1
            throw new \RuntimeException('Counter step should be non-zero integer.');
79
        }
80 28
        return $step;
81
    }
82
83
    /**
84
     * @throws \Exception
85
     */
86 18
    protected function buildReport(): void
87
    {
88 18
        $this->report = (new SimpleCounterReport())->buildOn($this);
89 18
    }
90
91
    /**
92
     * @param int $times
93
     * @return int
94
     */
95 14
    public function bump(int $times = 1): int
96
    {
97 14
        $times = $this->assertTimes($times);
98 12
        if ($this->isNotStarted()) {
99 12
            $this->start();
100
        }
101 12
        $this->value += $times * $this->step;
102 12
        $this->bumped++;
103
        return
104 12
            $this->value;
105
    }
106
107 23
    protected function assertTimes(int $times): int
108
    {
109 23
        if ($times < 1) {
110 2
            throw new \RuntimeException(
111 2
                'Parameter 0 for bump() or bumpBack() should be positive non-zero integer.'
112
            );
113
        }
114 21
        return $times;
115
    }
116
}
117