Completed
Push — master ( 6a7da5...1827cf )
by Alec
08:13 queued 02:32
created

Counter::updateMaxAndMin()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 4
nc 4
nop 0
dl 0
loc 7
ccs 5
cts 5
cp 1
crap 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * User: alec
4
 * Date: 14.10.18
5
 * Time: 2:18
6
 */
7
8
namespace AlecRabbit\Tools;
9
10
use AlecRabbit\Tools\Contracts\CounterInterface;
11
use AlecRabbit\Tools\Reports\Contracts\ReportableInterface;
12
use AlecRabbit\Tools\Reports\Traits\Reportable;
13
use AlecRabbit\Tools\Traits\CounterFields;
14
15
class Counter implements CounterInterface, ReportableInterface
16
{
17
    use CounterFields, Reportable;
18
19
    protected const DEFAULT_STEP = 1;
20
21
    /**
22
     * Counter constructor
23
     * @param null|string $name
24
     * @param null|int $step
25
     * @param int $initialValue
26
     */
27 29
    public function __construct(?string $name = null, ?int $step = null, int $initialValue = 0)
28
    {
29 29
        $this->name = $this->defaultName($name);
30 29
        $this->setInitialValue($initialValue);
31 29
        $this->setStep($step);
32 29
        $this->updateMaxAndMin();
33 29
    }
34
35
    /**
36
     * @param int $initialValue
37
     * @return Counter
38
     */
39 29
    public function setInitialValue(int $initialValue): Counter
40
    {
41 29
        if (false === $this->isStarted()) {
42 29
            $this->value = $this->initialValue = $this->length = $this->max = $this->min = $initialValue;
43
        } else {
44 2
            throw new \RuntimeException('You can\'t set counter initial value, it has been bumped already.');
45
        }
46 29
        return $this;
47
    }
48
49
    /**
50
     * @param null|int $step
51
     * @return Counter
52
     */
53 29
    public function setStep(?int $step = null): Counter
54
    {
55 29
        $step = $this->assertStep($step);
56 29
        if (false === $this->isStarted()) {
57 29
            $this->step = $step;
58
        } else {
59 1
            throw new \RuntimeException('You can\'t set counter step value, it has been bumped already.');
60
        }
61 29
        return $this;
62
    }
63
64
    /**
65
     * @param null|int $step
66
     * @return int
67
     */
68 29
    protected function assertStep(?int $step = null): int
69
    {
70 29
        $step = $step ?? self::DEFAULT_STEP;
71 29
        if ($step === 0) {
72 1
            throw new \RuntimeException('Counter step should be non-zero integer.');
73
        }
74 29
        return $step;
75
    }
76
77 29
    private function updateMaxAndMin(): void
78
    {
79 29
        if ($this->value > $this->max) {
80 20
            $this->max = $this->value;
81
        }
82 29
        if ($this->value < $this->min) {
83 1
            $this->min = $this->value;
84
        }
85 29
    }
86
87
    /**
88
     * @param int $times
89
     * @return int
90
     */
91 4
    public function bumpBack(int $times = 1): int
92
    {
93
        return
94 4
            $this->bump($times, false);
95
    }
96
97
    /**
98
     * @param int $times
99
     * @param bool $forward
100
     * @return int
101
     */
102 23
    public function bump(int $times = 1, bool $forward = true): int
103
    {
104 23
        $times = $this->assertTimes($times);
105 20
        $this->start();
106 20
        $this->path += $times * $this->step;
107 20
        $this->length += $times * $this->step;
108 20
        if ($forward) {
109 20
            $this->value += $times * $this->step;
110 20
            $this->bumpedForward++;
111
        } else {
112 5
            $this->value -= $times * $this->step;
113 5
            $this->bumpedBack++;
114
        }
115 20
        $this->updateMaxAndMin();
116
        return
117 20
            $this->value;
118
    }
119
120 23
    protected function assertTimes(int $times): int
121
    {
122 23
        if ($times < 1) {
123
            throw new
124 3
            \RuntimeException('Parameter 0 for bump() or bumpBack()  should be positive non-zero integer.');
125
        }
126 20
        return $times;
127
    }
128
129 20
    protected function start(): void
130
    {
131 20
        $this->started = true;
132 20
    }
133
134
//    // todo move to helpers
135
//    private function callingMethod(int $depth = 2): string
136
//    {
137
//        $e = new \Exception();
138
//        $trace = $e->getTrace();
139
//        $caller = $trace[$depth];
140
//        $r = '';
141
//        $r .= $caller['function'] . '()';
142
//        if (isset($caller['class'])) {
143
//            $r .= ' in ' . $caller['class'];
144
//        }
145
//        if (isset($caller['object'])) {
146
//            $r .= ' (' . get_class($caller['object']) . ')';
147
//        }
148
//        unset($e);
149
//        return $r;
150
//    }
151
}
152