Skip to content

Commit

Permalink
Add PHPUnit and add tests for TimeBucket, TimeOrderedArray and Period…
Browse files Browse the repository at this point in the history
…Estimator
  • Loading branch information
lucasnetau committed Jun 21, 2023
1 parent 4455141 commit f748d31
Show file tree
Hide file tree
Showing 10 changed files with 469 additions and 59 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ composer.phar
composer.lock
.idea
.DS_Store
.~lock.*
.~lock.*
.phpunit.*
5 changes: 4 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
"require": {
"php": "^8.0",
"ext-json": "*"
},
},
"require-dev": {
"phpunit/phpunit": "^9.6"
},
"autoload": {
"psr-4": {"EdgeTelemetrics\\TimeBucket\\": "src/"}
}
Expand Down
27 changes: 27 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.6/phpunit.xsd"
bootstrap="vendor/autoload.php"
cacheResultFile=".phpunit.cache/test-results"
executionOrder="depends,defects"
forceCoversAnnotation="true"
beStrictAboutCoversAnnotation="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutTodoAnnotatedTests="true"
convertDeprecationsToExceptions="true"
failOnRisky="true"
failOnWarning="true"
verbose="true">
<testsuites>
<testsuite name="default">
<directory>tests</directory>
</testsuite>
</testsuites>

<coverage cacheDirectory=".phpunit.cache/code-coverage"
processUncoveredFiles="true">
<include>
<directory suffix=".php">src</directory>
</include>
</coverage>
</phpunit>
33 changes: 33 additions & 0 deletions tests/PeriodEstimatorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php declare(strict_types=1);

use EdgeTelemetrics\TimeBucket\PeriodEstimator;
use EdgeTelemetrics\TimeBucket\TimeBucket;
use PHPUnit\Framework\TestCase;

require_once __DIR__ . '/../vendor/autoload.php';

/**
* @covers \EdgeTelemetrics\TimeBucket\PeriodEstimator
* @covers \EdgeTelemetrics\TimeBucket\TimeBucket
* @covers \EdgeTelemetrics\TimeBucket\TimeOrderedArray
*/
class PeriodEstimatorTest extends TestCase
{


public function testEstimator() {
$bucket = new TimeBucket('minute');
$ourEpoch = new DateTimeImmutable("2021-01-02 11:00:00");

for($i = 0; $i < 10; $i++) {
$time = $ourEpoch->add(new DateInterval("PT" . $i*2 . "M"));
$bucket->insert( 'test', $time);
}

$periodEstimator = new PeriodEstimator();
$estimatedPeriod = $periodEstimator->estimate($bucket);

$this->assertEquals('P0Y0M0DT0H2M0S', $estimatedPeriod->format('P%yY%mM%dDT%hH%iM%sS'));
}

}
189 changes: 189 additions & 0 deletions tests/TimeBucketTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
<?php declare(strict_types=1);

use EdgeTelemetrics\TimeBucket\TimeBucket;
use PHPUnit\Framework\TestCase;

require_once __DIR__ . '/../vendor/autoload.php';

/**
* @covers \EdgeTelemetrics\TimeBucket\TimeBucket
* @covers \EdgeTelemetrics\TimeBucket\TimeOrderedArray
*/
class TimeBucketTest extends TestCase
{
public function testConstructorDefaultUTC() {
$bucket = new TimeBucket();
$this->assertEquals('UTC', $bucket->getTimezone()->getName());
}

public function testConstructorTakesTimezoneString() {
$timezone = 'Australia/Sydney';
$bucket = new TimeBucket('second', $timezone);
$this->assertEquals($timezone, $bucket->getTimezone()->getName());
}

public function testConstructorTakesTimezoneObject() {
$timezone = new DateTimeZone('Australia/Sydney');
$bucket = new TimeBucket('second', $timezone);
$this->assertEquals($timezone, $bucket->getTimezone());
}

public function testEmptyBucketIsEmpty() {
$bucket = new TimeBucket();
$this->assertTrue($bucket->isEmpty());
$this->assertFalse($bucket->nextTimeSlice());
$this->assertNull($bucket->getTimeSlices()->getReturn());

$this->expectException(RuntimeException::class);
$bucket->extractTimeSlice();
}

public function testEmptyBucketHasNoTimeIndex() {
$bucket = new TimeBucket();
$gen = $bucket->getTimeIndex();

$this->assertNull($gen->getReturn());
}

public function testBucketAfterSingleInsert() {
$bucket = new TimeBucket();
$this->assertTrue($bucket->isEmpty());

$bucket->insert('test', 1);
$this->assertFalse($bucket->isEmpty());
$this->assertEquals(1, $bucket->count());
$this->assertEquals(1, $bucket->sliceCount());
$this->assertEquals(1, $bucket->nextTimeSliceCount());
}

public function testNextTimeSliceReturnsOneSlice() {
$bucket = new TimeBucket('unixtime');

$now = time();
$bucket->insert('correct', $now);
$bucket->insert('incorrect', $now+1);

['time' => $timestamp, 'data' => $data] = $bucket->nextTimeSlice();

$this->assertEquals(1, count($data));
}

public function testCorrectTimesliceRetrieval() {
$bucket = new TimeBucket('unixtime');

$now = time();
$bucket->insert('slice1', $now);
$bucket->insert('slice2-1', $now+1);
$bucket->insert('slice2-2', $now+1);
$bucket->insert('slice3', $now+2);

$slices = iterator_to_array($bucket->getTimeSlices());

$this->assertEquals(3, count($slices));
$this->assertEquals(1, count($slices[0]['data']));
$this->assertEquals(2, count($slices[1]['data']));
$this->assertEquals(1, count($slices[2]['data']));

$this->assertFalse($bucket->isEmpty()); //getTimeSlices is non-destructive
$this->assertEquals(4, $bucket->count());
}

public function testCanInsertTimestampPriority() {
$bucket = new TimeBucket('unixtime');

$now = time();
$bucket->insert('test', $now);

['time' => $timestamp, 'data' => $data] = $bucket->nextTimeSlice();

$this->assertEquals($now, $timestamp);
}

public function testCanInsertDateTimePriority() {
$bucket = new TimeBucket('unixtime');

$now = new DateTime();
$bucket->insert('test', $now);

['time' => $timestamp, 'data' => $data] = $bucket->nextTimeSlice();
$this->assertEquals($now->format('U'), $timestamp);
}

public function testCanInsertDateTimeImmutablePriority() {
$bucket = new TimeBucket('unixtime');

$now = new DateTimeImmutable();
$bucket->insert('test', $now);

['time' => $timestamp, 'data' => $data] = $bucket->nextTimeSlice();
$this->assertEquals($now->format('U'), $timestamp);
}

public function testCanInsertDateTimeString() {
$bucket = new TimeBucket('unixtime');

$now = time();
$bucket->insert('test', 'now');
$then = time();

['time' => $timestamp, 'data' => $data] = $bucket->nextTimeSlice();

$this->assertGreaterThanOrEqual($now, $timestamp);
$this->assertLessThanOrEqual($then, $timestamp);
}

public function testConstructorSliceFormat() {
$bucket = new TimeBucket('quarter');

$this->assertEquals(TimeBucket::SLICE_FORMATS['quarter'], $bucket->getTimeFormat());
}

public function testMinuteIntervalsCanBeUser() {
$bucket = new TimeBucket('5 minute');

$time = new DateTimeImmutable('2023-01-01 12:31:00');

$bucket->insert('test', $time);

['time' => $timestamp, 'data' => $data] = $bucket->nextTimeSlice();

$this->assertEquals($time->format('Y-m-d H:30:00'), $timestamp);
}

public function testCorrectTimesliceExtractionToEmpty() {
$bucket = new TimeBucket('unixtime');

$now = time();
$bucket->insert('slice1', $now);
$bucket->insert('slice2-1', $now+1);
$bucket->insert('slice2-2', $now+1);
$bucket->insert('slice3', $now+2);

$slices = [];
while(!$bucket->isEmpty()) {
$slices[] = $bucket->extractTimeSlice();
}

$this->assertEquals(3, count($slices));
$this->assertEquals(1, count($slices[0]['data']));
$this->assertEquals(2, count($slices[1]['data']));
$this->assertEquals(1, count($slices[2]['data']));

$this->assertTrue($bucket->isEmpty()); //extractTimeSlice is destructive
}

public function testBucketClonesNotLinked() {
$bucket = new TimeBucket('unixtime');

$bucket->insert('test', 1);

$clone = clone $bucket;
$clone->insert('abc', 2);
$clone->extractTimeSlice();
$clone->extractTimeSlice();

$this->assertEquals(0, $clone->count());
$this->assertEquals(1, $bucket->count());
}

}
File renamed without changes.
80 changes: 80 additions & 0 deletions tests/old_tests/quicktest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php declare(strict_types=1);

/*
* This file is part of the TimeBucket package.
*
* (c) James Lucas <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

error_reporting(E_ALL);
ini_set('display_errors', "on");

use \EdgeTelemetrics\TimeBucket\TimeOrderedArray;
use \EdgeTelemetrics\TimeBucket\TimeOrderedQueue;

// Load Composer
require '../vendor/autoload.php';

$spl = new TimeOrderedQueue();
$spl->insert("test c", 3);
$spl->insert("test b", 2);
$spl->insert("test a", 1);
$spl->insert("test b2", 2);

echo "TimeOrderedQueue" . PHP_EOL;
$spl->setExtractFlags(SplPriorityQueue::EXTR_DATA);
echo "Data Only: ";
print_r($spl->extract());
$spl->setExtractFlags(SplPriorityQueue::EXTR_PRIORITY);
echo PHP_EOL . "Priority Only: ";
print_r($spl->extract());
$spl->setExtractFlags(SplPriorityQueue::EXTR_BOTH);
echo PHP_EOL . "Both: ";
print_r($spl->extract());
echo PHP_EOL . "Final: ";
print_r($spl->extract());

$bucket = new TimeOrderedArray();

$bucket->insert("test c", 3);
$bucket->insert("test b", 2);
$bucket->insert("test a", 1);
$bucket->insert("test b2", 2);

echo PHP_EOL . PHP_EOL . "TimeOrderedArray" . PHP_EOL;

$bucket->setExtractFlags(SplPriorityQueue::EXTR_DATA);
echo "Data Only: ";
print_r($bucket->extract());
$bucket->setExtractFlags(SplPriorityQueue::EXTR_PRIORITY);
echo PHP_EOL . "Priority Only: ";
print_r($bucket->extract());
$bucket->setExtractFlags(SplPriorityQueue::EXTR_BOTH);
echo PHP_EOL . "Both: ";
print_r($bucket->extract());
echo PHP_EOL . "Final: ";
print_r($bucket->extract());

$bucket = new \EdgeTelemetrics\TimeBucket\TimeOrderedSqlite();

$bucket->insert("test c", 3);
$bucket->insert("test b", 2);
$bucket->insert("test a", 1);
$bucket->insert("test b2", 2);

echo PHP_EOL . PHP_EOL . "TimeOrderedSql" . PHP_EOL;

$bucket->setExtractFlags(SplPriorityQueue::EXTR_DATA);
echo "Data Only: ";
print_r($bucket->extract());
$bucket->setExtractFlags(SplPriorityQueue::EXTR_PRIORITY);
echo PHP_EOL . "Priority Only: ";
print_r($bucket->extract());
$bucket->setExtractFlags(SplPriorityQueue::EXTR_BOTH);
echo PHP_EOL . "Both: ";
print_r($bucket->extract());
echo PHP_EOL . "Final: ";
print_r($bucket->extract());
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public function __construct($array)
echo '**** Validate nextTimeSlice()' . PHP_EOL;
['time' => $time, 'data' => $data] = $bucket->nextTimeSlice();
echo $time . PHP_EOL;
echo count($data) . PHP_EOL;
echo timeBucketOrderTest . phpcount($data) . PHP_EOL;

echo '**** Validate getTimeSlices()' . PHP_EOL;
$totalDatapoints = 0;
Expand All @@ -97,7 +97,7 @@ public function __construct($array)
echo "Before Extract - SliceCount: " . $bucket->sliceCount() . ", DataPoints: " . count($bucket) . ", NextSliceCount: " . $bucket->nextTimeSliceCount() . PHP_EOL;
['time' => $time, 'data' => $data] = $bucket->extractTimeSlice();
echo $time . PHP_EOL;
echo count($data) . PHP_EOL;
echo timeBucketOrderTest . phpcount($data) . PHP_EOL;
echo "After Extract - SliceCount: " . $bucket->sliceCount() . ", DataPoints: " . count($bucket) . ", NextSliceCount: " . $bucket->nextTimeSliceCount() . PHP_EOL;

echo "Memory before emptying TimeBucket : " . round(memory_get_usage(false) / 1024) . "KB" . PHP_EOL;
Expand Down
File renamed without changes.
Loading

0 comments on commit f748d31

Please sign in to comment.