Skip to content

Commit

Permalink
Update: Add unit tests for AbstractLogger
Browse files Browse the repository at this point in the history
  • Loading branch information
vdonchev committed Mar 19, 2021
1 parent 4240908 commit 045877a
Show file tree
Hide file tree
Showing 4 changed files with 385 additions and 1 deletion.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.idea/
/vendor
*.log
composer.lock
composer.lock
.phpunit.result.cache
3 changes: 3 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,8 @@
"psr-4": {
"Donchev\\Log\\": "src"
}
},
"require-dev": {
"phpunit/phpunit": "^9.5"
}
}
19 changes: 19 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bootstrap="vendor/autoload.php" backupGlobals="false"
backupStaticAttributes="false" colors="true" convertErrorsToExceptions="true" convertNoticesToExceptions="true"
convertWarningsToExceptions="true" processIsolation="false" stopOnFailure="false"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
<coverage>
<include>
<directory suffix=".php">src/</directory>
</include>
</coverage>
<testsuites>
<testsuite name="Project Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<php>
<env name="APP_ENV" value="testing"/>
</php>
</phpunit>
361 changes: 361 additions & 0 deletions tests/AbstractLoggerTests.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,361 @@
<?php

use Donchev\Log\AbstractLogger;
use PHPUnit\Framework\TestCase;
use Psr\Log\LogLevel;

class AbstractLoggerTests extends TestCase
{
protected static function getMethod(string $name): ReflectionMethod
{
$class = new ReflectionClass(AbstractLogger::class);
$method = $class->getMethod($name);
$method->setAccessible(true);

return $method;
}

public function getLevels(): array
{
$levels = new ReflectionClass(LogLevel::class);
$levels = $levels->getConstants();

$items = [];
foreach ($levels as $level) {
$items[] = [$level];
}

return $items;
}

public function getMessagesWithoutPlaceholders(): array
{
return [
["Are you opening {{{{ the door?"],
["Could I { open the door?"],
["What room am I in?"],
["Leapin' lizards!"],
["No problem {{} !That's all !Time is up"],
["Will you open the door?"],
["China is much bigger } than Japan."],
["I was born as a baby."],
["He never {{{}}} wants to go on a rollercoaster again!"],
["When did you open } the door?"],
];
}

public function getMessagesWithPlaceholders(): array
{
return [
["Are you opening {key} the door?", "Are you opening key the door?"],
["Could I open the {door}?", "Could I open the door?"],
["What room am I in?", "What room am I in?"],
["Leapin' {room} lizards!", "Leapin' room lizards!"],
["No problem {{wall} !That's all !Time is up", "No problem {wall !That's all !Time is up"],
["Will you open the door?", "Will you open the door?"],
["China is much bigger } than Japan.", "China is much bigger } than Japan."],
["I was born as a baby.", "I was born as a baby."],
[
"He never {{{lucky}}} wants to go on a rollercoaster again!",
"He never {{lucky}} wants to go on a rollercoaster again!"
],
["When did you open } the door?", "When did you open } the door?"],
];
}

public function getContextWithInvalidExceptions(): array
{
return [
[['not_exception_key' => new InvalidArgumentException()], RuntimeException::class],
[[new InvalidArgumentException()], RuntimeException::class],
];
}

public function getContextWithValidExceptions(): array
{
return [
[['exception' => new InvalidArgumentException()]],
[[123, 'asd', 'key' => 69, 'exception' => new InvalidArgumentException()]],
];
}

public function getMessageArray(): array
{
return [
[
[
'timestamp' => '2021-03-19 13:21:48 CET',
'level' => strtoupper(LogLevel::DEBUG),
'message' => 'Some Message',
'context' => [1, 2, 3]
],
'"[2021-03-19 13:21:48 CET] [DEBUG]: Some Message \r\nContext:\n(\n [0] => 1\n [1] => 2\n [2] => 3\n)"'
],
[
[
'timestamp' => '2021-03-19 13:21:48 CET',
'level' => strtoupper(LogLevel::INFO),
'message' => 'Message',
'context' => ['key' => 'value']
],
'"[2021-03-19 13:21:48 CET] [INFO]: Message \r\nContext:\n(\n [key] => value\n)"'
],
];
}

public function getMessageArrayForJson(): array
{
return [
[
[
'timestamp' => '2021-03-19 13:21:48 CET',
'level' => strtoupper(LogLevel::DEBUG),
'message' => 'Some Message',
'context' => [1, 2, 3]
],
'{"timestamp":"2021-03-19 13:21:48 CET","level":"DEBUG","message":"Some Message","context":[1,2,3]}'
],
[
[
'timestamp' => '2021-03-19 13:21:48 CET',
'level' => strtoupper(LogLevel::INFO),
'message' => 'Message',
'context' => ['key' => 'value']
],
'{"timestamp":"2021-03-19 13:21:48 CET","level":"INFO","message":"Message","context":{"key":"value"}}'
],
];
}

/**
* @dataProvider getLevels
*/
public function testValidateLevelNameWithCorrectLevels($level)
{
$logger = $this->getAbstractLogger();
$validateMinLevel = $this->getMethod('validateLevelName');

$this->assertNull($validateMinLevel->invokeArgs($logger, [$level]));
}

/**
* @dataProvider getLevels
*/
public function testValidateLevelNameWithCorrectLevelsIncorrectCasing($level)
{
$logger = $this->getAbstractLogger();
$validateMinLevel = $this->getMethod('validateLevelName');

$level = ucwords($level);
$level[3] = strtoupper($level[3]);

$this->assertNull($validateMinLevel->invokeArgs($logger, [$level]));
}

/**
* @dataProvider getLevels
*/
public function testValidateLevelNameWithIncorrectLevel($level)
{
$logger = $this->getAbstractLogger();
$validateLevelName = $this->getMethod('validateLevelName');

$level .= '_fake';

$this->expectException(InvalidArgumentException::class);
$validateLevelName->invokeArgs($logger, [$level]);
}

public function testMinLeveReachedWithLowerPriorityLevels()
{
$logger = $this->getAbstractLogger(LogLevel::ERROR);
$validateMinLevel = $this->getMethod('minLevelReached');

$this->assertFalse($validateMinLevel->invokeArgs($logger, [LogLevel::DEBUG]));
$this->assertFalse($validateMinLevel->invokeArgs($logger, [LogLevel::INFO]));
$this->assertFalse($validateMinLevel->invokeArgs($logger, [LogLevel::NOTICE]));
$this->assertFalse($validateMinLevel->invokeArgs($logger, [LogLevel::WARNING]));
}

public function testMinLeveReachedWithHigherPriorityLevels()
{
$logger = $this->getAbstractLogger(LogLevel::ERROR);
$validateMinLevel = $this->getMethod('minLevelReached');

$this->assertTrue($validateMinLevel->invokeArgs($logger, [LogLevel::ERROR]));
$this->assertTrue($validateMinLevel->invokeArgs($logger, [LogLevel::CRITICAL]));
$this->assertTrue($validateMinLevel->invokeArgs($logger, [LogLevel::ALERT]));
$this->assertTrue($validateMinLevel->invokeArgs($logger, [LogLevel::EMERGENCY]));
}

/**
* @dataProvider getMessagesWithoutPlaceholders
*/
public function testInterpolateWithNoPlaceholdersAndNoContext($message)
{
$logger = $this->getAbstractLogger();
$interpolate = $this->getMethod('interpolate');

$interpolatedMessage = $interpolate->invokeArgs($logger, [$message, []]);

$this->assertEquals($message, $interpolatedMessage);
}

/**
* @dataProvider getMessagesWithoutPlaceholders
*/
public function testInterpolateWithNoPlaceholdersAndContext($message)
{
$logger = $this->getAbstractLogger();
$interpolate = $this->getMethod('interpolate');

$interpolatedMessage = $interpolate->invokeArgs($logger, [$message, ['test' => 'Some text']]);

$this->assertEquals($message, $interpolatedMessage);
}

/**
* @dataProvider getMessagesWithPlaceholders
*/
public function testInterpolateWithPlaceholdersAndNoContext($message)
{
$logger = $this->getAbstractLogger();
$interpolate = $this->getMethod('interpolate');

$interpolatedMessage = $interpolate->invokeArgs($logger, [$message, []]);

$this->assertEquals($message, $interpolatedMessage);
}

/**
* @dataProvider getMessagesWithPlaceholders
*/
public function testInterpolateWithPlaceholdersAndContext($message, $expected)
{
$logger = $this->getAbstractLogger();
$interpolate = $this->getMethod('interpolate');

$interpolatedMessage = $interpolate->invokeArgs(
$logger,
[
$message,
[
"key" => "key",
"room" => "room",
"door" => "door",
"wall" => "wall",
"lucky" => "lucky"
]
]
);

$this->assertEquals($expected, $interpolatedMessage);
}

public function testGetExceptionNameWithEmptyExceptionMessage()
{
$logger = $this->getAbstractLogger();
$getExceptionName = $this->getMethod('getExceptionName');

$res = $getExceptionName->invokeArgs($logger, [new RuntimeException()]);
$this->assertEquals('RuntimeException Object', $res);

$res = $getExceptionName->invokeArgs($logger, [new Exception()]);
$this->assertEquals('Exception Object', $res);

$res = $getExceptionName->invokeArgs($logger, [new InvalidArgumentException()]);
$this->assertEquals('InvalidArgumentException Object', $res);
}

public function testGetExceptionNameWithExceptionMessage()
{
$logger = $this->getAbstractLogger();
$getExceptionName = $this->getMethod('getExceptionName');

$res = $getExceptionName->invokeArgs($logger, [new RuntimeException('Some text')]);
$this->assertEquals('RuntimeException Object (Message: Some text)', $res);

$res = $getExceptionName->invokeArgs($logger, [new Exception('Some text')]);
$this->assertEquals('Exception Object (Message: Some text)', $res);

$res = $getExceptionName->invokeArgs($logger, [new InvalidArgumentException('Some text')]);
$this->assertEquals('InvalidArgumentException Object (Message: Some text)', $res);
}

public function testValidateContextExceptionsWithoutExceptions()
{
$logger = $this->getAbstractLogger();
$validateContextExceptions = $this->getMethod('validateContextExceptions');

$res = $validateContextExceptions->invokeArgs($logger, [[1, 2, 3, 4]]);
$this->assertEquals([1, 2, 3, 4], $res);

$res = $validateContextExceptions->invokeArgs($logger, [['key' => 'value']]);
$this->assertEquals(['key' => 'value'], $res);

$res = $validateContextExceptions->invokeArgs($logger, [[]]);
$this->assertEquals([], $res);

$now = new DateTime();
$res = $validateContextExceptions->invokeArgs($logger, [[1, $now]]);
$this->assertEquals([1, $now], $res);
}

/**
* @dataProvider getContextWithInvalidExceptions
*/
public function testValidateContextExceptionsWithExceptionsThatAreNotUnderExceptionKey($context, $expected)
{
$logger = $this->getAbstractLogger();
$validateContextExceptions = $this->getMethod('validateContextExceptions');

$this->expectException($expected);
$validateContextExceptions->invokeArgs($logger, [$context]);
}

/**
* @dataProvider getContextWithValidExceptions
*/
public function testValidateContextExceptionsWithExceptions($context)
{
$logger = $this->getAbstractLogger();
$validateContextExceptions = $this->getMethod('validateContextExceptions');

$res = $validateContextExceptions->invokeArgs($logger, [$context]);
$this->assertEquals($context, $res);
}

/**
* @dataProvider getMessageArrayForJson
*/
public function testFormatLineAsJson($line, $output)
{
$logger = $this->getAbstractLogger();
$formatLineAsJson = $this->getMethod('formatLineAsJson');

$res = $formatLineAsJson->invokeArgs($logger, [$line]);

$this->assertEquals($output, $res);
}

/**
* @dataProvider getMessageArray
*/
public function testFormatLineAsString($line, $output)
{
$logger = $this->getAbstractLogger();
$formatLineAsString = $this->getMethod('formatLineAsString');

$res = $formatLineAsString->invokeArgs($logger, [$line]);

$this->assertEquals($output, json_encode($res));
}

protected function getAbstractLogger(string $level = null, array $config = []): AbstractLogger
{
return $this->getMockForAbstractClass(
AbstractLogger::class,
[$level ?? LogLevel::DEBUG, $config]
);
}
}

0 comments on commit 045877a

Please sign in to comment.