Initial import from aternosorg/codex-minecraft
Some checks failed
Tests / Run tests on PHP v8.4 (push) Failing after 32s
Tests / Run tests on PHP v8.5 (push) Failing after 2s

This commit is contained in:
2026-04-30 09:56:57 -05:00
commit 7c7fe5ca80
94 changed files with 7003 additions and 0 deletions

View File

@@ -0,0 +1,177 @@
<?php
namespace Aternos\Codex\Test\Tests\Analyser;
use Aternos\Codex\Analyser\PatternAnalyser;
use Aternos\Codex\Analysis\Analysis;
use Aternos\Codex\Analysis\PatternInsightInterface;
use Aternos\Codex\Log\Entry;
use Aternos\Codex\Log\File\PathLogFile;
use Aternos\Codex\Log\Level;
use Aternos\Codex\Log\Line;
use Aternos\Codex\Test\Src\Analysis\TestPatternInformation;
use Aternos\Codex\Test\Src\Analysis\TestPatternProblem;
use Aternos\Codex\Test\Src\Analysis\TestSolution;
use Aternos\Codex\Test\Src\Log\TestPatternLog;
use PHPUnit\Framework\TestCase;
use ReflectionClass;
class PatternAnalyserTest extends TestCase
{
/**
* @return Analysis
*/
protected function getExpectedAnalysis(): Analysis
{
return (new Analysis())
->addInsight((new TestPatternProblem())
->setCause("ABC")
->increaseCounter()
->setEntry((new Entry())->setTime(2)->setLevel(Level::ERROR)->setPrefix("[01.01.1970 00:00:02] [Log/ERROR]")
->addLine(new Line(2, "[01.01.1970 00:00:02] [Log/ERROR] I have a problem with ABC"))
)
)
->addInsight((new TestPatternProblem())
->setCause("XYZ")
->setEntry((new Entry())->setTime(4)->setLevel(Level::ERROR)->setPrefix("[01.01.1970 00:00:04] [Log/ERROR]")
->addLine(new Line(4, "[01.01.1970 00:00:04] [Log/ERROR] I have a problem with XYZ"))
)
)
->addInsight((new TestPatternProblem())
->setCause("DEF")
->setEntry((new Entry())->setTime(6)->setLevel(Level::ERROR)->setPrefix("[01.01.1970 00:00:06] [Log/ERROR]")
->addLine(new Line(6, "[01.01.1970 00:00:06] [Log/ERROR] I have a problem with DEF"))
->addLine(new Line(7, "I have a problem with GHI"))
)
)
->addInsight((new TestPatternProblem())
->setCause("GHI")
->setEntry((new Entry())->setTime(6)->setLevel(Level::ERROR)->setPrefix("[01.01.1970 00:00:06] [Log/ERROR]")
->addLine(new Line(6, "[01.01.1970 00:00:06] [Log/ERROR] I have a problem with DEF"))
->addLine(new Line(7, "I have a problem with GHI"))
)
)
->addInsight((new TestPatternInformation())
->setValue("v1.2.3")
->setEntry((new Entry())->setTime(7)->setLevel(Level::INFO)->setPrefix("[01.01.1970 00:00:07] [Log/INFO]")
->addLine(new Line(8, "[01.01.1970 00:00:07] [Log/INFO] This log was generated by software v1.2.3"))
)
);
}
public function testAnalyse(): void
{
$logFile = new PathLogFile(__DIR__ . '/../../data/problem.log');
$log = (new TestPatternLog())->setLogFile($logFile);
$log->parse();
$analysis = $log->analyse();
$this->assertJsonStringEqualsJsonString(json_encode($this->getExpectedAnalysis()->getInsights()), json_encode($analysis->getInsights()));
}
public function testAnalyseWithPossibleInsightClasses(): void
{
$logFile = new PathLogFile(__DIR__ . '/../../data/problem.log');
$log = (new TestPatternLog())->setLogFile($logFile);
$log->parse();
$analyser = (new PatternAnalyser())
->setPossibleInsightClasses([
TestPatternInformation::class,
TestPatternProblem::class
]);
$analysis = $log->analyse($analyser);
$this->assertJsonStringEqualsJsonString(json_encode($this->getExpectedAnalysis()->getInsights()), json_encode($analysis->getInsights()));
}
public function testAddPossibleInsightClassThrowsExceptionIfPossibleInsightClassDoesNotImplementPatternInsightInterface(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage("Class " . TestSolution::class . " does not implement " . PatternInsightInterface::class . ".");
(new PatternAnalyser())->addPossibleInsightClass(TestSolution::class);
}
public function testRemovePossibleInsightClass(): void
{
$analyser = (new PatternAnalyser())
->setPossibleInsightClasses([
TestPatternInformation::class,
TestPatternProblem::class
]);
$reflector = new ReflectionClass(PatternAnalyser::class);
$possibleInsightClassesProperty = $reflector->getProperty('possibleInsightClasses');
$this->assertEquals([TestPatternInformation::class, TestPatternProblem::class], $possibleInsightClassesProperty->getValue($analyser));
$analyser->removePossibleInsightClass(TestPatternProblem::class);
$this->assertEquals([TestPatternInformation::class], $possibleInsightClassesProperty->getValue($analyser));
}
public function testRemovePossibleInsightClassThrowsExceptionIfPossibleInsightClassIsNotAdded(): void
{
// Set TestPatternProblem class
$analyser = (new PatternAnalyser())
->setPossibleInsightClasses([
TestPatternProblem::class
]);
$reflector = new ReflectionClass(PatternAnalyser::class);
$possibleInsightClassesProperty = $reflector->getProperty('possibleInsightClasses');
$this->assertEquals([TestPatternProblem::class], $possibleInsightClassesProperty->getValue($analyser));
// Remove TestPatternInformation class -> not found
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage("Class " . TestPatternInformation::class . " not found in possible insight classes.");
$analyser->removePossibleInsightClass(TestPatternInformation::class);
$this->assertEquals([TestPatternInformation::class], $possibleInsightClassesProperty->getValue($analyser));
}
public function testOverridePossibleInsightClass(): void
{
$analyser = (new PatternAnalyser())
->setPossibleInsightClasses([
TestPatternProblem::class
]);
$reflector = new ReflectionClass(PatternAnalyser::class);
$possibleInsightClassesProperty = $reflector->getProperty('possibleInsightClasses');
$this->assertEquals([TestPatternProblem::class], $possibleInsightClassesProperty->getValue($analyser));
$childInsightClass = new class extends TestPatternProblem {
// Is empty child class
};
$analyser->overridePossibleInsightClass(TestPatternProblem::class, get_class($childInsightClass));
$this->assertEquals([get_class($childInsightClass)], $possibleInsightClassesProperty->getValue($analyser));
}
public function testOverridePossibleInsightClassThrowsExceptionIfClassDoesNotExtendParent(): void
{
$analyser = (new PatternAnalyser())
->setPossibleInsightClasses([
TestPatternProblem::class
]);
$reflector = new ReflectionClass(PatternAnalyser::class);
$possibleInsightClassesProperty = $reflector->getProperty('possibleInsightClasses');
$this->assertEquals([TestPatternProblem::class], $possibleInsightClassesProperty->getValue($analyser));
$childInsightClass = new class {
// Is empty and not a child class
};
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage("Class " . get_class($childInsightClass) . " does not extend " . TestPatternProblem::class . ".");
$analyser->overridePossibleInsightClass(TestPatternProblem::class, get_class($childInsightClass));
$this->assertEquals([TestPatternProblem::class], $possibleInsightClassesProperty->getValue($analyser));
}
}

View File

@@ -0,0 +1,157 @@
<?php
namespace Aternos\Codex\Test\Tests\Analysis;
use Aternos\Codex\Analysis\Analysis;
use Aternos\Codex\Test\Src\Analysis\TestInformation;
use Aternos\Codex\Test\Src\Analysis\TestInsight;
use Aternos\Codex\Test\Src\Analysis\TestPatternProblem;
use Aternos\Codex\Test\Src\Analysis\TestProblem;
use PHPUnit\Framework\TestCase;
class AnalysisTest extends TestCase
{
public function testSetGetInsights(): void
{
$analysis = new Analysis();
$insight = new TestInsight();
$this->assertSame($analysis, $analysis->setInsights([$insight]));
$this->assertSame([$insight], $analysis->getInsights());
}
public function testAddInsight(): void
{
$analysis = new Analysis();
$insight = new TestInsight();
$this->assertSame($analysis, $analysis->addInsight($insight));
$this->assertSame([$insight], $analysis->getInsights());
}
public function testGetProblems(): void
{
$analysis = new Analysis();
$problem = new TestProblem();
$information = new TestInformation();
$analysis->addInsight($problem);
$analysis->addInsight($information);
$this->assertEquals([$problem], $analysis->getProblems());
}
public function testGetInformation(): void
{
$analysis = new Analysis();
$problem = new TestProblem();
$information = new TestInformation();
$analysis->addInsight($problem);
$analysis->addInsight($information);
$this->assertEquals([$information], $analysis->getInformation());
}
public function testKey(): void
{
$analysis = new Analysis();
$problem = new TestProblem();
$information = new TestInformation();
$analysis->addInsight($problem);
$this->assertEquals(0, $analysis->key());
$analysis->addInsight($information);
$this->assertEquals(1, $analysis->key());
}
public function testCount(): void
{
$analysis = new Analysis();
$problem = new TestProblem();
$information = new TestInformation();
$this->assertEquals(0, $analysis->count());
$analysis->addInsight($problem);
$this->assertEquals(1, $analysis->count());
$analysis->addInsight($information);
$this->assertEquals(2, $analysis->count());
}
public function testAddingTheSameInsightIncreasesInternalCounter(): void
{
// Adding the same insight to an analysis does not add it to the insights, and therefore it
// does not increase the counter of the analysis, but the internal counter of the insight.
// See Analysis->addInsight()
$analysis = new Analysis();
$problem = new TestPatternProblem();
$problem2 = new TestPatternProblem();
$analysis->addInsight($problem);
$this->assertEquals(1, $analysis->count());
$this->assertEquals(1, $problem->getCounterValue());
$analysis->addInsight($problem2);
$this->assertEquals(1, $analysis->count());
$this->assertEquals(2, $problem->getCounterValue());
}
public function testOffsetExists(): void
{
$analysis = new Analysis();
$information = new TestInformation();
$this->assertArrayNotHasKey(0, $analysis);
$this->assertEquals(0, $analysis->count());
$analysis->addInsight($information);
$this->assertArrayHasKey(0, $analysis);
$this->assertEquals($information, $analysis[0]);
}
public function testOffsetGet(): void
{
$analysis = new Analysis();
$information = new TestInformation();
$analysis->addInsight($information);
// Exists
$this->assertEquals($information, $analysis[0]);
// Does not exist -> "undefined array key" error
$this->assertArrayNotHasKey(1, $analysis);
}
public function testOffsetSet(): void
{
$analysis = new Analysis();
$information = new TestInformation();
$this->assertArrayNotHasKey(0, $analysis);
$this->assertEquals(0, $analysis->count());
$analysis->addInsight($information);
$this->assertArrayHasKey(0, $analysis);
$this->assertEquals($information, $analysis[0]);
// Overwrite $information on $analysis[0] using the offsetSet
$problem = new TestProblem();
$analysis[0] = $problem;
$this->assertEquals($problem, $analysis[0]);
}
public function testOffsetUnset(): void
{
$analysis = new Analysis();
$information = new TestInformation();
$this->assertArrayNotHasKey(0, $analysis);
$this->assertEquals(0, $analysis->count());
$analysis->addInsight($information);
$this->assertArrayHasKey(0, $analysis);
$this->assertEquals($information, $analysis[0]);
// Unset $information on $analysis[0] using the offsetUnset
unset($analysis[0]);
$this->assertArrayNotHasKey(0, $analysis);
$this->assertArrayNotHasKey(1, $analysis);
}
}

View File

@@ -0,0 +1,61 @@
<?php
namespace Aternos\Codex\Test\Tests\Analysis;
use Aternos\Codex\Log\File\PathLogFile;
use Aternos\Codex\Test\Src\Analysis\TestInformation;
use Aternos\Codex\Test\Src\Analysis\TestPatternInformation;
use Aternos\Codex\Test\Src\Log\TestPatternLog;
use PHPUnit\Framework\TestCase;
class InformationTest extends TestCase
{
public function testSetGetValue(): void
{
$value = uniqid();
$information = new TestInformation();
$information->setValue($value);
$this->assertEquals($value, $information->getValue());
}
public function testGetLabel(): void
{
$this->assertEquals("Label", (new TestInformation())->getLabel());
}
public function testGetMessage(): void
{
$value = uniqid();
$information = new TestInformation();
$information->setValue($value);
$this->assertEquals("Label: " . $value, $information->getMessage());
$this->assertEquals("Label: " . $value, (string)$information);
}
public function testIsEqual(): void
{
$value = uniqid();
$informationA = new TestInformation();
$informationA->setValue($value);
$informationB = new TestInformation();
$informationB->setValue($value);
$this->assertTrue($informationA->isEqual($informationB));
$this->assertTrue($informationA->isEqual($informationA));
}
public function testGetLogContent(): void
{
$logFile = new PathLogFile(__DIR__ . '/../../data/problem.log');
$log = (new TestPatternLog())->setLogFile($logFile);
$log->parse();
$analysis = $log->analyse();
foreach ($analysis->getInformation() as $information) {
/** @var TestPatternInformation $information */
$this->assertNotNull($information->getLogContent());
$this->assertEquals($logFile->getContent(), $information->getLogContent());
}
}
}

View File

@@ -0,0 +1,113 @@
<?php
namespace Aternos\Codex\Test\Tests\Analysis;
use Aternos\Codex\Test\Src\Analysis\TestProblem;
use Aternos\Codex\Test\Src\Analysis\TestSolution;
use PHPUnit\Framework\TestCase;
class ProblemTest extends TestCase
{
public function testSetGetSolutions(): void
{
$problem = new TestProblem();
$solution = new TestSolution();
$this->assertSame($problem, $problem->setSolutions([$solution]));
$this->assertEquals([$solution], $problem->getSolutions());
}
public function testAddSolutions(): void
{
$problem = new TestProblem();
$solution = new TestSolution();
$this->assertSame($problem, $problem->addSolution($solution));
$this->assertEquals([$solution], $problem->getSolutions());
}
public function testKey(): void
{
$problem = new TestProblem();
$solution = new TestSolution();
$problem->addSolution($solution);
/** @noinspection PhpStatementHasEmptyBodyInspection */
foreach ($problem as $ignored) {
// do nothing
}
$this->assertEquals(1, $problem->key());
}
public function testCount(): void
{
$problem = new TestProblem();
$solution1 = new TestSolution();
$solution2 = new TestSolution();
$this->assertEquals(0, $problem->count());
$problem->addSolution($solution1);
$this->assertEquals(1, $problem->count());
$problem->addSolution($solution2);
$this->assertEquals(2, $problem->count());
}
public function testOffsetExists(): void
{
$problem = new TestProblem();
$solution = new TestSolution();
$this->assertArrayNotHasKey(0, $problem);
$this->assertEquals(0, $problem->count());
$problem->addSolution($solution);
$this->assertArrayHasKey(0, $problem);
$this->assertEquals($solution, $problem[0]);
}
public function testOffsetGet(): void
{
$problem = new TestProblem();
$solution = new TestSolution();
$problem->addSolution($solution);
// Exists
$this->assertEquals($solution, $problem[0]);
// Does not exist -> "undefined array key" error
$this->assertArrayNotHasKey(1, $problem);
}
public function testOffsetSet(): void
{
$problem = new TestProblem();
$solution1 = new TestSolution();
$this->assertArrayNotHasKey(0, $problem);
$this->assertEquals(0, $problem->count());
$problem->addSolution($solution1);
$this->assertArrayHasKey(0, $problem);
$this->assertEquals($solution1, $problem[0]);
// Overwrite $solution1 on $problem[0] using the offsetSet
$TestSolution2 = new TestSolution();
$problem[0] = $TestSolution2;
$this->assertEquals($TestSolution2, $problem[0]);
}
public function testOffsetUnset(): void
{
$problem = new TestProblem();
$solution = new TestSolution();
$this->assertArrayNotHasKey(0, $problem);
$this->assertEquals(0, $problem->count());
$problem->addSolution($solution);
$this->assertArrayHasKey(0, $problem);
$this->assertEquals($solution, $problem[0]);
// Unset $solution on $problem[0] using the offsetUnset
unset($problem[0]);
$this->assertArrayNotHasKey(0, $problem);
$this->assertArrayNotHasKey(1, $problem);
}
}

View File

@@ -0,0 +1,122 @@
<?php
namespace Aternos\Codex\Test\Tests\Detective;
use Aternos\Codex\Detective\Detective;
use Aternos\Codex\Detective\DetectorInterface;
use Aternos\Codex\Log\DetectableLogInterface;
use Aternos\Codex\Log\Log;
use Aternos\Codex\Test\Src\Analysis\TestSolution;
use Aternos\Codex\Test\Src\Log\TestAlwaysDetectableLog;
use Aternos\Codex\Test\Src\Log\TestLessDetectableLog;
use Aternos\Codex\Test\Src\Log\TestMoreDetectableLog;
use Aternos\Codex\Test\Src\Log\TestNeverDetectableLog;
use PHPUnit\Framework\TestCase;
class DetectiveTest extends TestCase
{
/**
* @param array $possibleLogClasses
* @return Detective
*/
protected function getDetective(array $possibleLogClasses): Detective
{
$detective = new Detective();
$detective->setLogFile(new \Aternos\Codex\Log\File\PathLogFile(__DIR__ . '/../../data/simple.log'));
$detective->setPossibleLogClasses($possibleLogClasses);
return $detective;
}
public function testDetect(): void
{
$this->assertEquals(TestAlwaysDetectableLog::class,
get_class($this->getDetective([
TestAlwaysDetectableLog::class,
TestLessDetectableLog::class,
TestMoreDetectableLog::class,
TestNeverDetectableLog::class])->detect()));
$this->assertEquals(TestMoreDetectableLog::class,
get_class($this->getDetective([
TestLessDetectableLog::class,
TestMoreDetectableLog::class,
TestNeverDetectableLog::class])->detect()));
$this->assertEquals(TestLessDetectableLog::class,
get_class($this->getDetective([
TestLessDetectableLog::class,
TestNeverDetectableLog::class])->detect()));
$this->assertEquals(Log::class,
get_class($this->getDetective([
TestNeverDetectableLog::class])->detect()));
}
public function testAddPossibleLogClassThrowsExceptionIfPossibleClassDoesNotImplementDetectableLogInterface(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage("Class " . TestSolution::class . " does not implement " . DetectableLogInterface::class . ".");
(new Detective())->addPossibleLogClass(TestSolution::class);
}
public function testDetectThrowsExceptionIfDetectorClassDoesNotImplementDetectorInterface(): void
{
$invalidDetectorClass = new class {
// Is empty and not a child class of DetectorInterface
};
$customLogClass = new class() extends Log implements DetectableLogInterface {
private static array $detectors = [];
public static function setDetectors($detectors): void
{
self::$detectors = $detectors;
}
public static function getDetectors(): array
{
return self::$detectors;
}
};
$customLogClass::setDetectors([$invalidDetectorClass]);
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage("Class " . get_class($invalidDetectorClass) . " does not implement " . DetectorInterface::class . ".");
$this->getDetective([get_class($customLogClass)])->detect();
}
public function testGetPossibleLogClasses(): void
{
$possibleLogClasses = [
TestAlwaysDetectableLog::class,
TestLessDetectableLog::class,
TestMoreDetectableLog::class,
TestNeverDetectableLog::class
];
$detective = $this->getDetective($possibleLogClasses);
$this->assertEquals($possibleLogClasses, $detective->getPossibleLogClasses());
}
public function testAddDetective(): void
{
$possibleLogClasses1 = [
TestAlwaysDetectableLog::class,
TestLessDetectableLog::class
];
$possibleLogClasses2 = [
TestMoreDetectableLog::class,
TestNeverDetectableLog::class
];
$detective1 = $this->getDetective($possibleLogClasses1);
$detective2 = $this->getDetective($possibleLogClasses2);
$detective1->addDetective($detective2);
$this->assertEquals(array_merge($possibleLogClasses1, $possibleLogClasses2), $detective1->getPossibleLogClasses());
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace Aternos\Codex\Test\Tests\Detective;
use Aternos\Codex\Detective\LinePatternDetector;
use PHPUnit\Framework\TestCase;
class LinePatternDetectorTest extends TestCase
{
public function testDetect(): void
{
$this->assertEquals(5 / 7, (new LinePatternDetector())
->setLogFile(new \Aternos\Codex\Log\File\PathLogFile(__DIR__ . '/../../data/simple.log'))
->setPattern('/information/')
->detect()
);
$this->assertFalse((new LinePatternDetector())
->setLogFile(new \Aternos\Codex\Log\File\PathLogFile(__DIR__ . '/../../data/simple.log'))
->setPattern('/missing/')
->detect()
);
$this->assertEquals(1, (new LinePatternDetector())
->setLogFile(new \Aternos\Codex\Log\File\PathLogFile(__DIR__ . '/../../data/simple.log'))
->setPattern('/This/')
->detect()
);
}
}

View File

@@ -0,0 +1,40 @@
<?php
namespace Aternos\Codex\Test\Tests\Detective;
use Aternos\Codex\Detective\MultiPatternDetector;
use Aternos\Codex\Log\File\StringLogFile;
use PHPUnit\Framework\TestCase;
class MultiPatternDetectorTest extends TestCase
{
public function testDetectSinglePattern(): void
{
$this->assertTrue((new MultiPatternDetector())
->setLogFile(new StringLogFile("You can detect this."))
->addPattern('/detect/')
->detect()
);
}
public function testDetectMultiplePatterns(): void
{
$this->assertTrue((new MultiPatternDetector())
->setLogFile(new StringLogFile("You can detect this and this."))
->addPattern('/detect/')
->addPattern('/and this/')
->detect()
);
}
public function testNotDetectMissingFromMultiplePatterns(): void
{
$this->assertFalse((new MultiPatternDetector())
->setLogFile(new StringLogFile("You can detect this and this."))
->addPattern('/detect/')
->addPattern('/and this/')
->addPattern('/but not this/')
->detect()
);
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace Aternos\Codex\Test\Tests\Detective;
use Aternos\Codex\Detective\SinglePatternDetector;
use Aternos\Codex\Log\File\StringLogFile;
use PHPUnit\Framework\TestCase;
class SinglePatternDetectorTest extends TestCase
{
public function testDetect(): void
{
$this->assertTrue((new SinglePatternDetector())
->setLogFile(new StringLogFile("You can detect this."))
->setPattern('/detect/')
->detect()
);
$this->assertFalse((new SinglePatternDetector())
->setLogFile(new StringLogFile("You cannot detect this."))
->setPattern('/missing/')
->detect()
);
}
}

View File

@@ -0,0 +1,40 @@
<?php
namespace Aternos\Codex\Test\Tests\Detective;
use Aternos\Codex\Detective\WeightedSinglePatternDetector;
use Aternos\Codex\Log\File\StringLogFile;
use PHPUnit\Framework\TestCase;
class WeightedSinglePatternDetectorTest extends TestCase
{
public function testDetect(): void
{
$this->assertEquals(1, (new WeightedSinglePatternDetector())
->setLogFile(new \Aternos\Codex\Log\File\PathLogFile(__DIR__ . '/../../data/simple.log'))
->setPattern('/This/')
->setWeight(1)
->detect()
);
$this->assertEquals(0.5, (new WeightedSinglePatternDetector())
->setLogFile(new \Aternos\Codex\Log\File\PathLogFile(__DIR__ . '/../../data/simple.log'))
->setPattern('/This/')
->setWeight(0.5)
->detect()
);
$this->assertEquals(0, (new WeightedSinglePatternDetector())
->setLogFile(new \Aternos\Codex\Log\File\PathLogFile(__DIR__ . '/../../data/simple.log'))
->setPattern('/This/')
->setWeight(0)
->detect()
);
$this->assertFalse((new WeightedSinglePatternDetector())
->setLogFile(new StringLogFile("You cannot detect this."))
->setPattern('/missing/')
->detect()
);
}
}

View File

@@ -0,0 +1,138 @@
<?php
namespace Aternos\Codex\Test\Tests\Log;
use Aternos\Codex\Log\Entry;
use Aternos\Codex\Log\Level;
use Aternos\Codex\Log\Line;
use PHPUnit\Framework\TestCase;
class EntryTest extends TestCase
{
public function testAddLine(): void
{
$entry = new Entry();
$line = new Line(1, uniqid());
$this->assertSame($entry, $entry->addLine($line));
$this->assertEquals([$line], $entry->getLines());
}
public function testSetGetLines(): void
{
$entry = new Entry();
$line = new Line(1, uniqid());
$this->assertSame($entry, $entry->setLines([$line]));
$this->assertEquals([$line], $entry->getLines());
}
public function testSetGetLevel(): void
{
$entry = new Entry();
$level = Level::CRITICAL;
$this->assertSame($entry, $entry->setLevel($level));
$this->assertEquals($level, $entry->getLevel());
}
public function testSetGetTime(): void
{
$entry = new Entry();
$time = time();
$this->assertSame($entry, $entry->setTime($time));
$this->assertEquals($time, $entry->getTime());
}
public function testSetGetPrefix(): void
{
$entry = new Entry();
$prefix = uniqid();
$this->assertSame($entry, $entry->setPrefix($prefix));
$this->assertEquals($prefix, $entry->getPrefix());
}
public function testKey(): void
{
$entry = new Entry();
$line = new Line(1, uniqid());
$entry->addLine($line);
/** @noinspection PhpStatementHasEmptyBodyInspection */
foreach ($entry as $ignored) {
// do nothing
}
$this->assertEquals(1, $entry->key());
}
public function testCount(): void
{
$entry = new Entry();
$line1 = new Line(1, uniqid());
$line2 = new Line(2, uniqid());
$this->assertEquals(0, $entry->count());
$entry->addLine($line1);
$this->assertEquals(1, $entry->count());
$entry->addLine($line2);
$this->assertEquals(2, $entry->count());
}
public function testOffsetExists(): void
{
$entry = new Entry();
$line = new Line(1, uniqid());
$this->assertArrayNotHasKey(0, $entry);
$this->assertEquals(0, $entry->count());
$entry->addLine($line);
$this->assertArrayHasKey(0, $entry);
$this->assertEquals($line, $entry[0]);
}
public function testOffsetGet(): void
{
$entry = new Entry();
$line = new Line(1, uniqid());
$entry->addLine($line);
// Exists
$this->assertEquals($line, $entry[0]);
// Does not exist -> "undefined array key" error
$this->assertArrayNotHasKey(1, $entry);
}
public function testOffsetSet(): void
{
$entry = new Entry();
$line1 = new Line(1, uniqid());
$this->assertArrayNotHasKey(0, $entry);
$this->assertEquals(0, $entry->count());
$entry->addLine($line1);
$this->assertArrayHasKey(0, $entry);
$this->assertEquals($line1, $entry[0]);
// Overwrite $line1 on $entry[0] using the offsetSet
$line2 = new Line(2, uniqid());
$entry[0] = $line2;
$this->assertEquals($line2, $entry[0]);
}
public function testOffsetUnset(): void
{
$entry = new Entry();
$line = new Line(1, uniqid());
$this->assertArrayNotHasKey(0, $entry);
$this->assertEquals(0, $entry->count());
$entry->addLine($line);
$this->assertArrayHasKey(0, $entry);
$this->assertEquals($line, $entry[0]);
// Unset $line1 on $entry[0] using the offsetUnset
unset($entry[0]);
$this->assertArrayNotHasKey(0, $entry);
$this->assertArrayNotHasKey(1, $entry);
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace Aternos\Codex\Test\Tests\Log\File;
use Aternos\Codex\Log\File\PathLogFile;
use PHPUnit\Framework\TestCase;
class PathLogFileTest extends TestCase
{
public function testGetContent(): void
{
$path = __DIR__ . "/../../../data/simple.log";
$logFile = new PathLogFile($path);
$this->assertStringEqualsFile($path, $logFile->getContent());
}
}

View File

@@ -0,0 +1,18 @@
<?php
namespace Aternos\Codex\Test\Tests\Log\File;
use Aternos\Codex\Log\File\StreamLogFile;
use PHPUnit\Framework\TestCase;
class StreamLogFileTest extends TestCase
{
public function testGetContent(): void
{
$path = __DIR__ . "/../../../data/simple.log";
$streamResource = fopen($path, 'r');
$logFile = new StreamLogFile($streamResource);
$this->assertStringEqualsFile($path, $logFile->getContent());
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace Aternos\Codex\Test\Tests\Log\File;
use Aternos\Codex\Log\File\StringLogFile;
use PHPUnit\Framework\TestCase;
class StringLogFileTest extends TestCase
{
public function testGetContent(): void
{
$content = uniqid();
$logFile = new StringLogFile($content);
$this->assertEquals($content, $logFile->getContent());
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace Aternos\Codex\Test\Tests\Log;
use Aternos\Codex\Log\Line;
use PHPUnit\Framework\TestCase;
class LineTest extends TestCase
{
public function testSetGetText(): void
{
$text = uniqid();
$line = new Line(1, "");
$this->assertSame($line, $line->setText($text));
$this->assertEquals($text, $line->getText());
}
public function testSetGetNumber(): void
{
$number = rand(0, 100);
$line = new Line(999, "");
$this->assertSame($line, $line->setNumber($number));
$this->assertEquals($number, $line->getNumber());
}
public function test__toString(): void
{
$text = uniqid();
$line = new Line(1, $text);
$this->assertSame($line, $line->setText($text));
$this->assertEquals($text, (string)$line);
}
}

103
test/tests/Log/LogTest.php Normal file
View File

@@ -0,0 +1,103 @@
<?php
namespace Aternos\Codex\Test\Tests\Log;
use Aternos\Codex\Log\Entry;
use Aternos\Codex\Log\Log;
use PHPUnit\Framework\TestCase;
class LogTest extends TestCase
{
public function testAddEntry(): void
{
$log = new Log();
$entry = new Entry();
$this->assertSame($log, $log->addEntry($entry));
$this->assertEquals([$entry], $log->getEntries());
}
public function testSetGetEntries(): void
{
$log = new Log();
$entry = new Entry();
$this->assertSame($log, $log->setEntries([$entry]));
$this->assertEquals([$entry], $log->getEntries());
}
public function testKey(): void
{
$log = new Log();
$entry = new Entry();
$log->addEntry($entry);
/** @noinspection PhpStatementHasEmptyBodyInspection */
foreach ($log as $ignored) {
// do nothing
}
$this->assertEquals(1, $log->key());
}
public function testCount(): void
{
$log = new Log();
$entry1 = new Entry();
$entry2 = new Entry();
$this->assertEquals(0, $log->count());
$log->addEntry($entry1);
$this->assertEquals(1, $log->count());
$log->addEntry($entry2);
$this->assertEquals(2, $log->count());
}
public function testOffsetExists(): void
{
$log = new Log();
$entry = new Entry();
$this->assertArrayNotHasKey(0, $log);
$this->assertEquals(0, $log->count());
$log->addEntry($entry);
$this->assertArrayHasKey(0, $log);
$this->assertEquals($entry, $log[0]);
}
public function testOffsetGet(): void
{
$log = new Log();
$entry = new Entry();
$log->addEntry($entry);
// Exists
$this->assertEquals($entry, $log[0]);
// Does not exist -> "undefined array key" error
$this->assertArrayNotHasKey(1, $log);
}
public function testOffsetSet(): void
{
$log = new Log();
$entry1 = new Entry();
$log->addEntry($entry1);
// Overwrite $entry1 on $log[0] using the offsetSet
$entry2 = new Entry();
$log[0] = $entry2;
$this->assertEquals($entry2, $log[0]);
}
public function testOffsetUnset(): void
{
$log = new Log();
$entry = new Entry();
$log->addEntry($entry);
// Unset $entry on $log[0] using the offsetUnset
unset($log[0]);
$this->assertArrayNotHasKey(0, $log);
$this->assertArrayNotHasKey(1, $log);
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace Aternos\Codex\Test\Tests\Parser;
use Aternos\Codex\Log\Entry;
use Aternos\Codex\Log\File\PathLogFile;
use Aternos\Codex\Log\Line;
use Aternos\Codex\Log\Log;
use PHPUnit\Framework\TestCase;
class DefaultParserTest extends TestCase
{
/**
* Get the log object expected from parsing data/simple.log
*
* @return Log
*/
protected function getSimpleExpectedLog(): Log
{
return (new Log())
->setLogFile(new PathLogFile(__DIR__ . '/../../data/simple.log'))
->addEntry((new Entry())
->addLine(new Line(1, "[01.01.1970 00:00:01] [Log/INFO] This is the first message containing information.")))
->addEntry((new Entry())
->addLine(new Line(2, "[01.01.1970 00:00:02] [Log/DEBUG] This is the second message containing a debug information.")))
->addEntry((new Entry())
->addLine(new Line(3, "[01.01.1970 00:00:03] [Log/WARN] This is the third message containing a warning information.")))
->addEntry((new Entry())
->addLine(new Line(4, "[01.01.1970 00:00:04] [Log/ERROR] This is the third message containing an error information.")))
->addEntry((new Entry())
->addLine(new Line(5, "This line continues the error entry to add even more information.")))
->addEntry((new Entry())
->addLine(new Line(6, "This line is also part of the error entry.")))
->addEntry((new Entry())
->addLine(new Line(7, "[01.01.1970 00:00:05] [Log/INFO] This is the last message of the log.")));
}
public function testParse(): void
{
$logFile = new PathLogFile(__DIR__ . '/../../data/simple.log');
$log = (new Log())->setLogFile($logFile);
$log->parse();
$this->assertEquals($this->getSimpleExpectedLog(), $log);
}
}

View File

@@ -0,0 +1,76 @@
<?php
namespace Aternos\Codex\Test\Tests\Parser;
use Aternos\Codex\Log\Entry;
use Aternos\Codex\Log\File\PathLogFile;
use Aternos\Codex\Log\Level;
use Aternos\Codex\Log\Line;
use Aternos\Codex\Log\Log;
use Aternos\Codex\Parser\PatternParser;
use Aternos\Codex\Test\Src\Log\TestPatternLog;
use PHPUnit\Framework\TestCase;
class PatternParserTest extends TestCase
{
/**
* Get the log object expected from parsing data/simple.log
*
* @return Log
*/
protected function getSimpleExpectedLog(): Log
{
return (new TestPatternLog())
->setLogFile(new PathLogFile(__DIR__ . '/../../data/simple.log'))
->addEntry((new Entry())->setLevel(Level::INFO)->setTime(1)->setPrefix("[01.01.1970 00:00:01] [Log/INFO]")
->addLine(new Line(1, "[01.01.1970 00:00:01] [Log/INFO] This is the first message containing information.")))
->addEntry((new Entry())->setLevel(Level::DEBUG)->setTime(2)->setPrefix("[01.01.1970 00:00:02] [Log/DEBUG]")
->addLine(new Line(2, "[01.01.1970 00:00:02] [Log/DEBUG] This is the second message containing a debug information.")))
->addEntry((new Entry())->setLevel(Level::WARNING)->setTime(3)->setPrefix("[01.01.1970 00:00:03] [Log/WARN]")
->addLine(new Line(3, "[01.01.1970 00:00:03] [Log/WARN] This is the third message containing a warning information.")))
->addEntry((new Entry())->setLevel(Level::ERROR)->setTime(4)->setPrefix("[01.01.1970 00:00:04] [Log/ERROR]")
->addLine(new Line(4, "[01.01.1970 00:00:04] [Log/ERROR] This is the third message containing an error information."))
->addLine(new Line(5, "This line continues the error entry to add even more information."))
->addLine(new Line(6, "This line is also part of the error entry.")))
->addEntry((new Entry())->setLevel(Level::INFO)->setTime(5)->setPrefix("[01.01.1970 00:00:05] [Log/INFO]")
->addLine(new Line(7, "[01.01.1970 00:00:05] [Log/INFO] This is the last message of the log.")));
}
public function testParse(): void
{
$logFile = new PathLogFile(__DIR__ . '/../../data/simple.log');
$log = (new TestPatternLog())->setLogFile($logFile);
$log->parse();
$this->assertEquals($this->getSimpleExpectedLog(), $log);
}
public function testParseWithCustomParser(): void
{
$logFile = new PathLogFile(__DIR__ . '/../../data/simple.log');
$log = (new TestPatternLog())->setLogFile($logFile);
$patternParser = (new PatternParser())
->setPattern('/(\[([^\]]+)\] \[[^\/]+\/([^\]]+)\]).*/')
->setMatches([PatternParser::PREFIX, PatternParser::TIME, PatternParser::LEVEL])
->setTimeFormat('d.m.Y H:i:s');
$log->parse($patternParser);
$this->assertEquals($this->getSimpleExpectedLog(), $log);
}
public function testGetPattern(): void
{
$pattern = '/\[([^\]]+)\] \[[^\/]+\/([^\]]+)\].*/';
$patternParser = (new PatternParser())
->setPattern($pattern)
->setMatches([PatternParser::TIME, PatternParser::LEVEL])
->setTimezone(new \DateTimeZone('Europe/Berlin'))
->setTimeFormat('d.m.Y H:i:s');
$this->assertEquals($pattern, $patternParser->getPattern());
}
}

View File

@@ -0,0 +1,35 @@
<?php
namespace Aternos\Codex\Test\Tests\Printer;
use Aternos\Codex\Log\Entry;
use Aternos\Codex\Log\File\PathLogFile;
use Aternos\Codex\Log\Line;
use Aternos\Codex\Log\Log;
use Aternos\Codex\Printer\DefaultPrinter;
use PHPUnit\Framework\TestCase;
class DefaultPrinterTest extends TestCase
{
public function testPrint(): void
{
$logFile = new PathLogFile(__DIR__ . "/../../data/simple.log");
$log = new Log();
$log->setLogFile($logFile);
$log->parse();
$printer = new DefaultPrinter();
$printer->setLog($log);
$this->assertEquals($logFile->getContent(), trim($printer->print()));
}
public function testPrintEntry(): void
{
$text = uniqid();
$entry = (new Entry())->addLine(new Line(1, $text));
$printer = new DefaultPrinter();
$printer->setEntry($entry);
$this->assertEquals($text, trim($printer->print()));
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace Aternos\Codex\Test\Tests\Printer;
use Aternos\Codex\Log\Entry;
use Aternos\Codex\Log\File\StringLogFile;
use Aternos\Codex\Log\Line;
use Aternos\Codex\Log\Log;
use Aternos\Codex\Printer\ModifiableDefaultPrinter;
use Aternos\Codex\Test\Src\Printer\TestModification;
use PHPUnit\Framework\TestCase;
class ModifiableDefaultPrinterTest extends TestCase
{
public function testPrint(): void
{
$logFile = new StringLogFile("This is foo!");
$log = new Log();
$log->setLogFile($logFile);
$log->parse();
$printer = new ModifiableDefaultPrinter();
$printer->addModification(new TestModification());
$printer->setLog($log);
$this->assertEquals("This is bar!", trim($printer->print()));
}
public function testPrintEntry(): void
{
$entry = (new Entry())->addLine(new Line(1, "This is foo!"));
$printer = new ModifiableDefaultPrinter();
$printer->setModifications([new TestModification()]);
$printer->setEntry($entry);
$this->assertEquals("This is bar!", trim($printer->print()));
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace Aternos\Codex\Test\Tests\Printer;
use Aternos\Codex\Log\File\StringLogFile;
use Aternos\Codex\Log\Log;
use Aternos\Codex\Printer\ModifiableDefaultPrinter;
use Aternos\Codex\Printer\PatternModification;
use PHPUnit\Framework\TestCase;
class PatternModificationTest extends TestCase
{
public function testPrint(): void
{
$logFile = new StringLogFile("This is foo!");
$log = new Log();
$log->setLogFile($logFile);
$log->parse();
$printer = new ModifiableDefaultPrinter();
$printer->addModification(new PatternModification('/foo/', 'bar'));
$printer->setLog($log);
$this->assertEquals("This is bar!", trim($printer->print()));
}
}