Completed
Push — develop ( a410d7...efad38 )
by Alec
04:48 queued 01:47
created

AbstractCounter::assertTimes()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

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