Passed
Branch feature/v2 (61dd95)
by Valentin
05:53
created

testSamePeriodOccurrenceSourceFindByGroupedInterval()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 64
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 64
rs 9.3956
c 0
b 0
f 0
cc 1
eloc 45
nc 1
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Spiral\Tests\Statistics\Extract\Intervals;
4
5
use Spiral\Statistics\Database\Statistics;
6
use Spiral\Statistics\Extract;
7
use Spiral\Statistics\Extract\Range;
8
use Spiral\Tests\BaseTest;
9
10
abstract class AbstractInterval extends BaseTest
11
{
12
    const RANGE_INTERVAL = null;
13
    const RANGE_FORMAT   = null;
14
15
    const START = null; //extract start date
16
    const END   = null; //extract end date
17
18
    const DT1 = null; //track first datetime
19
    const DT2 = null; //track second datetime in same interval
20
    const DT3 = null; //track second datetime in another interval
21
22
    public function testRange()
23
    {
24
        $range = $this->range();
25
        $this->assertEquals(new \DateInterval(static::RANGE_INTERVAL), $range->getInterval());
26
        $this->assertEquals(static::RANGE_FORMAT, $range->getFormat());
27
    }
28
29
    /**
30
     * Method shortcut.
31
     *
32
     * @param \DateTimeInterface $periodValue
33
     * @param \DateTimeInterface $start
34
     * @param \DateTimeInterface $end
35
     * @param array              $events
36
     * @return array
37
     */
38
    protected function find(
39
        \DateTimeInterface $periodValue,
40
        \DateTimeInterface $start,
41
        \DateTimeInterface $end,
42
        array $events = []
43
    ): array
44
    {
45
        $result = [];
46
        /** @var Statistics $row */
47
        foreach ($this->getSource()->findExtract($start, $end, $events) as $row) {
48
            $converted = $this->getConverter()->convert($row->timestamp, $this->range());
49
            if ($converted->getTimestamp() == $periodValue->getTimestamp()) {
50
                $result[] = $row;
51
            }
52
        }
53
54
        return $result;
55
    }
56
57
    public function testSamePeriodSourceFindExtract()
58
    {
59
        $converter = $this->getConverter();
60
        $track = $this->getTrack();
61
62
        $this->assertCount(0, $this->orm->source(Statistics::class));
63
64
        $start = $this->start();
65
        $end = $this->end();
66
67
        $datetime1 = $this->datetime1();
68
        $datetime2 = $this->datetime2();
69
        $period = $converter->convert($datetime1, $this->range());
70
71
        $this->assertCount(0, $this->orm->source(Statistics::class));
72
        $this->assertCount(0, $this->find($period, $start, $end));
73
74
        $track->events(['event 1' => 1, 'event 2' => 2, 'event 3' => 3], $datetime1);
75
        $track->events(['event 3' => 3, 'event 4' => 4], $datetime2);
76
77
        $this->assertCount(5, $this->orm->source(Statistics::class));
78
79
        /*
80
         * Check if passed events make difference
81
         * Start-end cover all occurrences
82
         */
83
        $this->assertCount(5, $this->find($period, $start, $end, []));
84
        $this->assertCount(1, $this->find($period, $start, $end, ['event 1']));
85
        $this->assertCount(2, $this->find($period, $start, $end, ['event 1', 'event 2']));
86
        $this->assertCount(3, $this->find($period, $start, $end, ['event 1', 'event 3']));
87
        $this->assertCount(5,
88
            $this->find($period, $start, $end, ['event 1', 'event 2', 'event 3', 'event 4']));
89
        $this->assertCount(1, $this->find($period, $start, $end, ['event 4']));
90
        $this->assertCount(0, $this->find($period, $start, $end, ['event 5']));
91
92
        //Check if passed time and events make difference
93
        $start1 = clone $datetime1;
94
        $start1->setTime(13, 0, 0);
95
96
        $end1 = clone $datetime1;
97
        $end1->setTime(13, 0, 0);
98
99
        /*
100
         * Check if passed start time and events make difference
101
         * Start-end cover second occurrences
102
         */
103
        $this->assertCount(2, $this->find($period, $start1, $end, []));
104
        $this->assertCount(0, $this->find($period, $start1, $end, ['event 1']));
105
        $this->assertCount(0, $this->find($period, $start1, $end, ['event 1', 'event 2']));
106
        $this->assertCount(1, $this->find($period, $start1, $end, ['event 1', 'event 3']));
107
        $this->assertCount(2,
108
            $this->find($period, $start1, $end, ['event 1', 'event 2', 'event 3', 'event 4']));
109
        $this->assertCount(1, $this->find($period, $start1, $end, ['event 4']));
110
        $this->assertCount(0, $this->find($period, $start1, $end, ['event 5']));
111
112
        /*
113
         * Check if passed end time and events make difference
114
         * Start-end cover first occurrences
115
         */
116
        $this->assertCount(3, $this->find($period, $start, $end1, []));
117
        $this->assertCount(1, $this->find($period, $start, $end1, ['event 1']));
118
        $this->assertCount(2, $this->find($period, $start, $end1, ['event 1', 'event 2']));
119
        $this->assertCount(2, $this->find($period, $start, $end1, ['event 1', 'event 3']));
120
        $this->assertCount(3,
121
            $this->find($period, $start, $end1, ['event 1', 'event 2', 'event 3', 'event 4']));
122
        $this->assertCount(0, $this->find($period, $start, $end1, ['event 4']));
123
        $this->assertCount(0, $this->find($period, $start, $end1, ['event 5']));
124
    }
125
126
    public function testAnotherPeriodSourceFindExtract()
127
    {
128
        $converter = $this->getConverter();
129
        $track = $this->getTrack();
130
131
        $this->assertCount(0, $this->orm->source(Statistics::class));
132
133
        $start = $this->start();
134
        $end = $this->end();
135
136
        $datetime1 = $this->datetime1();
137
        $datetime2 = $this->datetime3();
138
        $period1 = $converter->convert($datetime1, $this->range());
139
        $period2 = $converter->convert($datetime2, $this->range());
140
141
        $this->assertCount(0, $this->orm->source(Statistics::class));
142
        $this->assertCount(0, $this->find($period1, $start, $end));
143
        $this->assertCount(0, $this->find($period2, $start, $end));
144
145
        $track->events(['event 1' => 1, 'event 2' => 2, 'event 3' => 3], $datetime1);
146
        $track->events(['event 3' => 3, 'event 4' => 4], $datetime2);
147
148
        $this->assertCount(5, $this->orm->source(Statistics::class));
149
150
        /*
151
         * Check if passed events make difference
152
         * Start-end cover all occurrences
153
         *
154
         * Only first occurrences
155
         */
156
        $this->assertCount(3, $this->find($period1, $start, $end, []));
157
        $this->assertCount(1, $this->find($period1, $start, $end, ['event 1']));
158
        $this->assertCount(2, $this->find($period1, $start, $end, ['event 1', 'event 2']));
159
        $this->assertCount(2, $this->find($period1, $start, $end, ['event 1', 'event 3']));
160
        $this->assertCount(3,
161
            $this->find($period1, $start, $end, ['event 1', 'event 2', 'event 3', 'event 4']));
162
        $this->assertCount(0, $this->find($period1, $start, $end, ['event 4']));
163
        $this->assertCount(0, $this->find($period1, $start, $end, ['event 5']));
164
165
        /*
166
         * Only second occurrences
167
         */
168
        $this->assertCount(2, $this->find($period2, $start, $end, []));
169
        $this->assertCount(0, $this->find($period2, $start, $end, ['event 1']));
170
        $this->assertCount(0, $this->find($period2, $start, $end, ['event 1', 'event 2']));
171
        $this->assertCount(1, $this->find($period2, $start, $end, ['event 1', 'event 3']));
172
        $this->assertCount(2,
173
            $this->find($period2, $start, $end, ['event 1', 'event 2', 'event 3', 'event 4']));
174
        $this->assertCount(1, $this->find($period2, $start, $end, ['event 4']));
175
        $this->assertCount(0, $this->find($period2, $start, $end, ['event 5']));
176
177
        //Check if passed start time and events make difference
178
        $start1 = clone $datetime1;
179
        $start1->setTime(13, 0, 0);
180
181
        $end1 = clone $datetime1;
182
        $end1->setTime(13, 0, 0);
183
184
        /*
185
         * Check if passed start time and events and period make difference
186
         * Start-end cover second occurrences
187
         */
188
        $this->assertCount(0, $this->find($period1, $start1, $end, []));
189
        $this->assertCount(0, $this->find($period1, $start1, $end, ['event 1']));
190
        $this->assertCount(0, $this->find($period1, $start1, $end, ['event 1', 'event 2']));
191
        $this->assertCount(0, $this->find($period1, $start1, $end, ['event 1', 'event 3']));
192
        $this->assertCount(0,
193
            $this->find($period1, $start1, $end, ['event 1', 'event 2', 'event 3', 'event 4']));
194
        $this->assertCount(0, $this->find($period1, $start1, $end, ['event 4']));
195
        $this->assertCount(0, $this->find($period1, $start1, $end, ['event 5']));
196
197
        $this->assertCount(2, $this->find($period2, $start1, $end, []));
198
        $this->assertCount(0, $this->find($period2, $start1, $end, ['event 1']));
199
        $this->assertCount(0, $this->find($period2, $start1, $end, ['event 1', 'event 2']));
200
        $this->assertCount(1, $this->find($period2, $start1, $end, ['event 1', 'event 3']));
201
        $this->assertCount(2,
202
            $this->find($period2, $start1, $end, ['event 1', 'event 2', 'event 3', 'event 4']));
203
        $this->assertCount(1, $this->find($period2, $start1, $end, ['event 4']));
204
        $this->assertCount(0, $this->find($period2, $start1, $end, ['event 5']));
205
206
        /*
207
         * Check if passed end time and events make difference
208
         * Start-end cover first occurrences
209
         */
210
        $this->assertCount(3, $this->find($period1, $start, $end1, []));
211
        $this->assertCount(1, $this->find($period1, $start, $end1, ['event 1']));
212
        $this->assertCount(2, $this->find($period1, $start, $end1, ['event 1', 'event 2']));
213
        $this->assertCount(2, $this->find($period1, $start, $end1, ['event 1', 'event 3']));
214
        $this->assertCount(3,
215
            $this->find($period1, $start, $end1, ['event 1', 'event 2', 'event 3', 'event 4']));
216
        $this->assertCount(0, $this->find($period1, $start, $end1, ['event 4']));
217
        $this->assertCount(0, $this->find($period1, $start, $end1, ['event 5']));
218
219
        $this->assertCount(0, $this->find($period2, $start, $end1, []));
220
        $this->assertCount(0, $this->find($period2, $start, $end1, ['event 1']));
221
        $this->assertCount(0, $this->find($period2, $start, $end1, ['event 1', 'event 2']));
222
        $this->assertCount(0, $this->find($period2, $start, $end1, ['event 1', 'event 3']));
223
        $this->assertCount(0,
224
            $this->find($period2, $start, $end1, ['event 1', 'event 2', 'event 3', 'event 4']));
225
        $this->assertCount(0, $this->find($period2, $start, $end1, ['event 4']));
226
        $this->assertCount(0, $this->find($period2, $start, $end1, ['event 5']));
227
    }
228
229
    public function testSamePeriodExtractEvents()
230
    {
231
        $converter = $this->getConverter();
232
        $track = $this->getTrack();
233
234
        $this->assertCount(0, $this->orm->source(Statistics::class));
235
236
        $start = $this->start();
237
        $end = $this->end();
238
239
        $datetime1 = $this->datetime1();
240
        $datetime2 = $this->datetime2();
241
        $period = $converter->convert($datetime1, $this->range());
242
243
        $this->assertCount(0, $this->orm->source(Statistics::class));
244
        $this->assertCount(0, $this->find($period, $start, $end));
245
246
        $track->events(['event 1' => 1, 'event 2' => 2, 'event 3' => 3], $datetime1);
247
        $track->events(['event 3' => 4, 'event 4' => 4], $datetime2);
248
249
        $this->assertCount(5, $this->orm->source(Statistics::class));
250
251
        //Check if passed time and events make difference
252
        $start1 = clone $datetime1;
253
        $start1->setTime(13, 0, 0);
254
255
        $end1 = clone $datetime1;
256
        $end1->setTime(13, 0, 0);
257
258
        $this->extractTest($period, $start, $end,
259
            ['event 1' => 1, 'event 2' => 2, 'event 3' => 7, 'event 4' => 4, 'event 5' => 0]);
260
261
        $this->extractTest($period, $start1, $end,
262
            ['event 1' => 0, 'event 2' => 0, 'event 3' => 4, 'event 4' => 4, 'event 5' => 0]);
263
264
        $this->extractTest($period, $start, $end1,
265
            ['event 1' => 1, 'event 2' => 2, 'event 3' => 3, 'event 4' => 0, 'event 5' => 0]);
266
    }
267
268
    public function testAnotherPeriodExtractEvents()
269
    {
270
        $converter = $this->getConverter();
271
        $track = $this->getTrack();
272
273
        $this->assertCount(0, $this->orm->source(Statistics::class));
274
275
        $start = $this->start();
276
        $end = $this->end();
277
278
        $datetime1 = $this->datetime1();
279
        $datetime2 = $this->datetime3();
280
        $period1 = $converter->convert($datetime1, $this->range());
281
        $period2 = $converter->convert($datetime2, $this->range());
282
283
        $this->assertCount(0, $this->orm->source(Statistics::class));
284
        $this->assertCount(0, $this->find($period1, $start, $end));
285
        $this->assertCount(0, $this->find($period2, $start, $end));
286
287
        $track->events(['event 1' => 1, 'event 2' => 2, 'event 3' => 3], $datetime1);
288
        $track->events(['event 3' => 4, 'event 4' => 4], $datetime2);
289
290
        $this->assertCount(5, $this->orm->source(Statistics::class));
291
292
        //Check if passed time and events make difference
293
        $start1 = clone $datetime1;
294
        $start1->setTime(13, 0, 0);
295
296
        $end1 = clone $datetime1;
297
        $end1->setTime(13, 0, 0);
298
299
        $this->extractTest($period1, $start, $end,
300
            ['event 1' => 1, 'event 2' => 2, 'event 3' => 3, 'event 4' => 0, 'event 5' => 0]);
301
302
        $this->extractTest($period1, $start1, $end,
303
            ['event 1' => 0, 'event 2' => 0, 'event 3' => 0, 'event 4' => 0, 'event 5' => 0]);
304
305
        $this->extractTest($period1, $start, $end1,
306
            ['event 1' => 1, 'event 2' => 2, 'event 3' => 3, 'event 4' => 0, 'event 5' => 0]);
307
308
        $this->extractTest($period2, $start, $end,
309
            ['event 1' => 0, 'event 2' => 0, 'event 3' => 4, 'event 4' => 4, 'event 5' => 0]);
310
311
        $this->extractTest($period2, $start1, $end,
312
            ['event 1' => 0, 'event 2' => 0, 'event 3' => 4, 'event 4' => 4, 'event 5' => 0]);
313
314
        $this->extractTest($period2, $start, $end1,
315
            ['event 1' => 0, 'event 2' => 0, 'event 3' => 0, 'event 4' => 0, 'event 5' => 0]);
316
    }
317
318
    protected function extractTest(
319
        \DateTimeInterface $period,
320
        \DateTimeInterface $start,
321
        \DateTimeInterface $end,
322
        array $arr
323
    ) {
324
        $extract = $this->getExtract();
325
        $count = $this->calculateRows($start, $end);
326
327
        $events = $extract->events($start, $end, $this->range(), array_keys($arr));
328
329
        $rows = $events->getRows();
330
331
        //Same count of rows as expected due to grouping
332
        $this->assertCount($count, $rows);
333
334
        /** @var Extract\Events\Row $row */
335
        foreach ($rows as $label => $row) {
336
            //Same events with same values in result rows
337
            if ($period->format(static::RANGE_FORMAT) == $row->getLabel()) {
338
                $this->assertEquals($arr, $row->getEvents());
339
            }
340
        }
341
    }
342
343
    protected function calculateRows(\DateTimeInterface $start, \DateTimeInterface $end)
344
    {
345
        $converter = $this->getConverter();
346
        $start = $converter->immutable($start);
347
        $end = $converter->immutable($end);
348
349
        $count = 0;
350
        while (
351
            $this->getConverter()->convert($start, $this->range()) <=
352
            $this->getConverter()->convert($end, $this->range())
353
        ) {
354
            $count++;
355
            $start = $start->add(new \DateInterval(static::RANGE_INTERVAL));
356
        }
357
358
        return $count;
359
    }
360
361
    abstract protected function range(): Extract\RangeInterface;
362
363
    protected function start(): \DateTime
364
    {
365
        return new \DateTime(static::START);
366
    }
367
368
    protected function end(): \DateTime
369
    {
370
        return new \DateTime(static::END);
371
    }
372
373
    protected function datetime1(): \DateTime
374
    {
375
        return new \DateTime(static::DT1);
376
    }
377
378
    protected function datetime2(): \DateTime
379
    {
380
        return new \DateTime(static::DT2);
381
    }
382
383
    protected function datetime3(): \DateTime
384
    {
385
        return new \DateTime(static::DT3);
386
    }
387
}