Logging class major change, Debug\Support update

old Debug\Logging is in Debug\LoggingLegacy and Debug\Logging extends
Logging\Logging

Logging\Logging is a new class with most of the functionality except
there is no more print/outout to screen, but we use the default log
levels (RFC5424)
The plan is to be a frontend between the old type class and
Monolog\Monolog

Updated all other classes to use new class interface
This commit is contained in:
Clemens Schwaighofer
2023-05-30 18:12:24 +09:00
parent 7b5ad92e66
commit b0a8783276
75 changed files with 4292 additions and 2019 deletions

View File

@@ -68,13 +68,10 @@ final class CoreLibsACLLoginTest extends TestCase
// logger is always needed
// define basic connection set valid and one invalid
self::$log = new \CoreLibs\Debug\Logging([
self::$log = new \CoreLibs\Logging\Logging([
// 'log_folder' => __DIR__ . DIRECTORY_SEPARATOR . 'log',
'log_folder' => DIRECTORY_SEPARATOR . 'tmp',
'file_id' => 'CoreLibs-ACL-Login-Test',
'debug_all' => true,
'echo_all' => false,
'print_all' => true,
'log_file_id' => 'CoreLibs-ACL-Login-Test',
]);
// test database we need to connect do, if not possible this test is skipped
self::$db = new \CoreLibs\DB\IO(

View File

@@ -22,12 +22,9 @@ final class CoreLibsCreateEmailTest extends TestCase
*/
public static function setUpBeforeClass(): void
{
self::$log = new \CoreLibs\Debug\Logging([
self::$log = new \CoreLibs\Logging\Logging([
'log_folder' => DIRECTORY_SEPARATOR . 'tmp',
'file_id' => 'CoreLibs-Create-Email-Test',
'debug_all' => true,
'echo_all' => false,
'print_all' => true,
'log_file_id' => 'CoreLibs-Create-Email-Test',
]);
}
@@ -624,7 +621,7 @@ final class CoreLibsCreateEmailTest extends TestCase
// force new set for each run
self::$log->setLogUniqueId(true);
// set on of unique log id
self::$log->setLogPer('run', true);
self::$log->setLogFlag(\CoreLibs\Logging\Logger\Flag::per_run);
// init logger
$status = \CoreLibs\Create\Email::sendEmail(
$subject,
@@ -646,7 +643,9 @@ final class CoreLibsCreateEmailTest extends TestCase
// assert content: must load JSON from log file
if ($status == 2) {
// open file, get last entry with 'SEND EMAIL JSON' key
$file = file_get_contents(self::$log->getLogFileName());
$file = file_get_contents(
self::$log->getLogFolder() . self::$log->getLogFile()
);
if ($file !== false) {
// extract SEND EMAIL JSON line
$found = preg_match_all("/^.* <SEND EMAIL JSON> - (.*)$/m", $file, $matches);

View File

@@ -132,13 +132,10 @@ final class CoreLibsDBIOTest extends TestCase
);
}
// define basic connection set valid and one invalid
self::$log = new \CoreLibs\Debug\Logging([
self::$log = new \CoreLibs\Logging\Logging([
// 'log_folder' => __DIR__ . DIRECTORY_SEPARATOR . 'log',
'log_folder' => DIRECTORY_SEPARATOR . 'tmp',
'file_id' => 'CoreLibs-DB-IO-Test',
'debug_all' => false,
'echo_all' => false,
'print_all' => false,
'log_file_id' => 'CoreLibs-DB-IO-Test',
]);
$db = new \CoreLibs\DB\IO(
self::$db_config['valid'],

View File

@@ -10,12 +10,13 @@ use PHPUnit\Framework\TestCase;
/**
* Test class for Debug\Logging
* @coversDefaultClass \CoreLibs\Debug\Logging
* @testdox \CoreLibs\Debug\Logging method tests
* @coversDefaultClass \CoreLibs\Debug\LoggingLegacy
* @testdox \CoreLibs\Debug\LoggingLegacy method tests
*/
final class CoreLibsDebugLoggingTest extends TestCase
final class CoreLibsDebugLoggingLegacyTest extends TestCase
{
private const LOG_FOLDER = __DIR__ . DIRECTORY_SEPARATOR . 'log' . DIRECTORY_SEPARATOR;
/**
* test set for options BASIC
*
@@ -24,7 +25,7 @@ final class CoreLibsDebugLoggingTest extends TestCase
* 1: expected
* 2: override
* override:
* - constant for COSNTANTS
* - constant for CONSTANTS
* - global for _GLOBALS
*
* @return array
@@ -138,7 +139,7 @@ final class CoreLibsDebugLoggingTest extends TestCase
// catch this with the message
$this->expectExceptionMessage($deprecation_message);
}
$log = new \CoreLibs\Debug\Logging($options);
$log = new \CoreLibs\Debug\LoggingLegacy($options);
// reset error handler
restore_error_handler();
// check that settings match
@@ -308,7 +309,7 @@ final class CoreLibsDebugLoggingTest extends TestCase
// catch this with the message
$this->expectExceptionMessage($deprecation_message);
}
$log = new \CoreLibs\Debug\Logging($options);
$log = new \CoreLibs\Debug\LoggingLegacy($options);
// reset error handler
restore_error_handler();
// check current
@@ -385,7 +386,7 @@ final class CoreLibsDebugLoggingTest extends TestCase
bool $expected_get
): void {
// neutral start with default
$log = new \CoreLibs\Debug\Logging([
$log = new \CoreLibs\Debug\LoggingLegacy([
'file_id' => 'testSetGetLogLevelAll',
'log_folder' => self::LOG_FOLDER
]);
@@ -510,7 +511,7 @@ final class CoreLibsDebugLoggingTest extends TestCase
$expected_get
): void {
// neutral start with default
$log = new \CoreLibs\Debug\Logging([
$log = new \CoreLibs\Debug\LoggingLegacy([
'file_id' => 'testSetGetLogLevel',
'log_folder' => self::LOG_FOLDER
]);
@@ -592,7 +593,7 @@ final class CoreLibsDebugLoggingTest extends TestCase
bool $expected_get
): void {
// neutral start with default
$log = new \CoreLibs\Debug\Logging([
$log = new \CoreLibs\Debug\LoggingLegacy([
'file_id' => 'testSetGetLogPer',
'log_folder' => self::LOG_FOLDER
]);
@@ -624,7 +625,7 @@ final class CoreLibsDebugLoggingTest extends TestCase
public function testSetGetLogPrintFileDate(bool $input, bool $expected_set, bool $expected_get): void
{
// neutral start with default
$log = new \CoreLibs\Debug\Logging([
$log = new \CoreLibs\Debug\LoggingLegacy([
'file_id' => 'testSetGetLogPrintFileDate',
'log_folder' => self::LOG_FOLDER
]);
@@ -693,7 +694,7 @@ final class CoreLibsDebugLoggingTest extends TestCase
*/
public function testPrAr(array $input, string $expected): void
{
$log = new \CoreLibs\Debug\Logging([
$log = new \CoreLibs\Debug\LoggingLegacy([
'file_id' => 'testPrAr',
'log_folder' => self::LOG_FOLDER
]);
@@ -757,7 +758,7 @@ final class CoreLibsDebugLoggingTest extends TestCase
*/
public function testPrBl(bool $input, ?string $true, ?string $false, string $expected): void
{
$log = new \CoreLibs\Debug\Logging([
$log = new \CoreLibs\Debug\LoggingLegacy([
'file_id' => 'testPrBl',
'log_folder' => self::LOG_FOLDER
]);
@@ -932,7 +933,7 @@ final class CoreLibsDebugLoggingTest extends TestCase
// remove any files named /tmp/error_log_TestDebug*.log
array_map('unlink', glob($options['log_folder'] . 'error_msg_' . $options['file_id'] . '*.log'));
// init logger
$log = new \CoreLibs\Debug\Logging($options);
$log = new \CoreLibs\Debug\LoggingLegacy($options);
// * debug (A/B)
// NULL check for strip/prefix
$this->assertEquals(
@@ -1046,13 +1047,13 @@ final class CoreLibsDebugLoggingTest extends TestCase
public function testLogUniqueId(bool $option, bool $override): void
{
if ($option === true) {
$log = new \CoreLibs\Debug\Logging([
$log = new \CoreLibs\Debug\LoggingLegacy([
'file_id' => 'testLogUniqueId',
'log_folder' => self::LOG_FOLDER,
'per_run' => $option
]);
} else {
$log = new \CoreLibs\Debug\Logging([
$log = new \CoreLibs\Debug\LoggingLegacy([
'file_id' => 'testLogUniqueId',
'log_folder' => self::LOG_FOLDER
]);

View File

@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
use CoreLibs\Debug\Support;
/**
* Test class for Debug\Support
@@ -40,6 +41,32 @@ final class CoreLibsDebugSupportTest extends TestCase
];
}
/**
* Undocumented function
*
* @cover ::printTime
* @dataProvider printTimeProvider
* @testdox printTime test with $microtime and match to regex [$_dataName]
*
* @param int|null $mircrotime
* @param string $expected
* @return void
*/
public function testPrintTime(?int $microtime, string $regex): void
{
if ($microtime === null) {
$this->assertMatchesRegularExpression(
$regex,
Support::printTime()
);
} else {
$this->assertMatchesRegularExpression(
$regex,
Support::printTime($microtime)
);
}
}
/**
* Undocumented function
*
@@ -50,18 +77,55 @@ final class CoreLibsDebugSupportTest extends TestCase
return [
'empty array' => [
0 => [],
1 => "<pre>Array\n(\n)\n</pre>"
1 => "<pre>Array\n(\n)\n</pre>",
2 => "Array\n(\n)\n",
],
'simple array' => [
0 => ['a', 'b'],
1 => "<pre>Array\n(\n"
. " [0] => a\n"
. " [1] => b\n"
. ")\n</pre>"
. ")\n</pre>",
2 => "Array\n(\n"
. " [0] => a\n"
. " [1] => b\n"
. ")\n",
],
];
}
/**
* Undocumented function
*
* @cover ::printAr
* @cover ::printArray
* @dataProvider printArrayProvider
* @testdox printAr/printArray $input will be $expected [$_dataName]
*
* @param array $input
* @param string $expected
* @param string $expected_strip
* @return void
*/
public function testPrintAr(array $input, string $expected, string $expected_strip): void
{
$this->assertEquals(
$expected,
Support::printAr($input),
'assert printAr'
);
$this->assertEquals(
$expected,
Support::printArray($input),
'assert printArray'
);
$this->assertEquals(
$expected_strip,
Support::prAr($input),
'assert prAr'
);
}
/**
* Undocumented function
*
@@ -73,27 +137,31 @@ final class CoreLibsDebugSupportTest extends TestCase
'true input default' => [
0 => true,
1 => [],
2 => 'true'
2 => 'true',
3 => 'true',
],
'false input default' => [
0 => false,
1 => [],
2 => 'false'
2 => 'false',
3 => 'false'
],
'false input param name' => [
0 => false,
1 => [
'name' => 'param test'
],
2 => '<b>param test</b>: false'
2 => '<b>param test</b>: false',
3 => 'false'
],
'true input param name, true override' => [
0 => true,
1 => [
'name' => 'param test',
'true' => 'ok'
'true' => 'ok',
],
2 => '<b>param test</b>: ok'
2 => '<b>param test</b>: ok',
3 => 'ok',
],
'false input param name, true override, false override' => [
0 => false,
@@ -102,11 +170,77 @@ final class CoreLibsDebugSupportTest extends TestCase
'true' => 'ok',
'false' => 'not',
],
2 => '<b>param test</b>: not'
2 => '<b>param test</b>: not',
3 => 'not'
],
];
}
/**
* Undocumented function
*
* @cover ::printBool
* @dataProvider printBoolProvider
* @testdox printBool $input will be $expected [$_dataName]
*
* @param bool $input
* @param array $params
* @param string $expected
* @param string $expected_strip
* @return void
*/
public function testPrintBool(bool $input, array $params, string $expected, string $expected_strip): void
{
if (
isset($params['name']) &&
isset($params['true']) &&
isset($params['false'])
) {
$string = Support::printBool(
$input,
$params['name'],
$params['true'],
$params['false']
);
$string_strip = Support::prBl(
$input,
$params['true'],
$params['false']
);
} elseif (isset($params['name']) && isset($params['true'])) {
$string = Support::printBool(
$input,
$params['name'],
$params['true']
);
$string_strip = Support::prBl(
$input,
$params['true'],
);
} elseif (isset($params['name'])) {
$string = Support::printBool(
$input,
$params['name']
);
$string_strip = Support::prBl(
$input
);
} else {
$string = Support::printBool($input);
$string_strip = Support::prBl($input);
}
$this->assertEquals(
$expected,
$string,
'assert printBool'
);
$this->assertEquals(
$expected_strip,
$string_strip,
'assert prBl'
);
}
/**
* Undocumented function
*
@@ -169,12 +303,10 @@ final class CoreLibsDebugSupportTest extends TestCase
'an array, no html' => [
['a', 'b'],
true,
"##HTMLPRE##"
. "Array\n(\n"
"Array\n(\n"
. " [0] => a\n"
. " [1] => b\n"
. ")\n"
. "##/HTMLPRE##",
. ")\n",
],
// resource
'a resource' => [
@@ -191,6 +323,253 @@ final class CoreLibsDebugSupportTest extends TestCase
];
}
/**
* Undocumented function
*
* @cover ::printToString
* @dataProvider printToStringProvider
* @testdox printToString $input with $flag will be $expected [$_dataName]
*
* @param mixed $input anything
* @param boolean|null $flag html flag, only for string and array
* @param string $expected always string
* @return void
*/
public function testPrintToString(mixed $input, ?bool $flag, string $expected): void
{
if ($flag === null) {
// if expected starts with / and ends with / then this is a regex compare
if (
substr($expected, 0, 1) == '/' &&
substr($expected, -1, 1) == '/'
) {
$this->assertMatchesRegularExpression(
$expected,
Support::printToString($input)
);
} else {
$this->assertEquals(
$expected,
Support::printToString($input)
);
}
} else {
$this->assertEquals(
$expected,
Support::printToString($input, $flag)
);
}
}
/**
* Undocumented function
*
* @return array
*/
public function providerDumpExportVar(): array
{
return [
'string' => [
'input' => 'string',
'flag' => null,
'expected_dump' => 'string(6) "string"' . "\n",
'expected_export' => "<pre>'string'</pre>",
],
'string, no html' => [
'input' => 'string',
'flag' => true,
'expected_dump' => 'string(6) "string"' . "\n",
'expected_export' => "'string'",
],
// int
'int' => [
'input' => 6,
'flag' => null,
'expected_dump' => 'int(6)' . "\n",
'expected_export' => "<pre>6</pre>",
],
// float
'float' => [
'input' => 1.6,
'flag' => null,
'expected_dump' => 'float(1.6)' . "\n",
'expected_export' => "<pre>1.6</pre>",
],
// bool
'bool' => [
'input' => true,
'flag' => null,
'expected_dump' => 'bool(true)' . "\n",
'expected_export' => "<pre>true</pre>",
],
// array
'array' => [
'input' => ['string', true],
'flag' => null,
'expected_dump' => "array(2) {\n"
. " [0]=>\n"
. " string(6) \"string\"\n"
. " [1]=>\n"
. " bool(true)\n"
. "}\n",
'expected_export' => "<pre>array (\n"
. " 0 => 'string',\n"
. " 1 => true,\n"
. ")</pre>",
],
// more
];
}
/**
* Undocumented function
*
* @cover ::dumpVar
* @cover ::exportVar
* @dataProvider providerDumpExportVar
* @testdox dump/exportVar $input with $flag will be $expected_dump / $expected_export [$_dataName]
*
* @param mixed $input
* @param bool|null $flag
* @param string $expected_dump
* @param string $expected_export
* @return void
*/
public function testDumpExportVar(mixed $input, ?bool $flag, string $expected_dump, string $expected_export): void
{
if ($flag === null) {
$dump = Support::dumpVar($input);
$export = Support::exportVar($input);
} else {
$dump = Support::dumpVar($input, $flag);
$export = Support::exportVar($input, $flag);
}
$this->assertEquals(
$expected_dump,
$dump,
'assert dumpVar'
);
$this->assertEquals(
$expected_export,
$export,
'assert dumpVar'
);
}
/**
* Undocumented function
*
* @cover ::getCallerFileLine
* @testWith ["/storage/var/www/html/developers/clemens/core_data/php_libraries/trunk/www/vendor/phpunit/phpunit/src/Framework/TestCase.php:1608"]
* @testdox getCallerFileLine check if it returns $expected [$_dataName]
*
* @param string $expected
* @return void
*/
public function testGetCallerFileLine(string $expected): void
{
$this->assertEquals(
$expected,
Support::getCallerFileLine()
);
}
/**
* Undocumented function
*
* @cover ::getCallerMethod
* @testWith ["testGetCallerMethod"]
* @testdox getCallerMethod check if it returns $expected [$_dataName]
*
* @return void
*/
public function testGetCallerMethod(string $expected): void
{
$this->assertEquals(
$expected,
Support::getCallerMethod()
);
}
/**
* Undocumented function
*
* @cover ::getCallerMethodList
* @testWith [["main", "run", "run", "run", "run", "run", "run", "runBare", "runTest", "testGetCallerMethodList"]]
* @testdox getCallerMethodList check if it returns $expected [$_dataName]
*
* @param array $expected
* @return void
*/
public function testGetCallerMethodList(array $expected): void
{
$compare = Support::getCallerMethodList();
// 10: legact
// 11: direct
// 12: full call
switch (count($compare)) {
case 10:
// add nothing
$this->assertEquals(
$expected,
Support::getCallerMethodList(),
'assert expected 10'
);
break;
case 11:
// add one "run" before "runBare"
array_splice(
$expected,
7,
0,
['run']
);
$this->assertEquals(
$expected,
Support::getCallerMethodList(),
'assert expected 11'
);
break;
case 12:
// add two "run" before "runBare"
array_splice(
$expected,
7,
0,
['run']
);
array_splice(
$expected,
0,
0,
['include']
);
$this->assertEquals(
$expected,
Support::getCallerMethodList(),
'assert expected 12'
);
break;
}
}
/**
* Undocumented function
*
* @cover ::getCallerClass
* @testWith ["PHPUnit\\TextUI\\Command"]
* @testdox getCallerClass check if it returns $expected [$_dataName]
*
* @return void
*/
public function testGetCallerClass(string $expected): void
{
$this->assertEquals(
$expected,
Support::getCallerClass()
);
}
/**
* Undocumented function
*
@@ -236,205 +615,6 @@ final class CoreLibsDebugSupportTest extends TestCase
];
}
/**
* Undocumented function
*
* @cover ::printTime
* @dataProvider printTimeProvider
* @testdox printTime test with $microtime and match to regex [$_dataName]
*
* @param int|null $mircrotime
* @param string $expected
* @return void
*/
public function testPrintTime(?int $microtime, string $regex): void
{
if ($microtime === null) {
$this->assertMatchesRegularExpression(
$regex,
\CoreLibs\Debug\Support::printTime()
);
} else {
$this->assertMatchesRegularExpression(
$regex,
\CoreLibs\Debug\Support::printTime($microtime)
);
}
}
/**
* Undocumented function
*
* @cover ::printAr
* @cover ::printArray
* @dataProvider printArrayProvider
* @testdox printAr/printArray $input will be $expected [$_dataName]
*
* @param array $input
* @param string $expected
* @return void
*/
public function testPrintAr(array $input, string $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Debug\Support::printAr($input),
'assert printAr'
);
$this->assertEquals(
$expected,
\CoreLibs\Debug\Support::printArray($input),
'assert printArray'
);
}
/**
* Undocumented function
*
* @cover ::printBool
* @dataProvider printBoolProvider
* @testdox printBool $input will be $expected [$_dataName]
*
* @param bool $input
* @param array $params
* @param string $expected
* @return void
*/
public function testPrintBool(bool $input, array $params, string $expected): void
{
if (
isset($params['name']) &&
isset($params['true']) &&
isset($params['false'])
) {
$string = \CoreLibs\Debug\Support::printBool(
$input,
$params['name'],
$params['true'],
$params['false']
);
} elseif (isset($params['name']) && isset($params['true'])) {
$string = \CoreLibs\Debug\Support::printBool(
$input,
$params['name'],
$params['true']
);
} elseif (isset($params['name'])) {
$string = \CoreLibs\Debug\Support::printBool(
$input,
$params['name']
);
} else {
$string = \CoreLibs\Debug\Support::printBool($input);
}
$this->assertEquals(
$expected,
$string,
'assert printBool'
);
}
/**
* Undocumented function
*
* @cover ::printToString
* @dataProvider printToStringProvider
* @testdox printToString $input with $flag will be $expected [$_dataName]
*
* @param mixed $input anything
* @param boolean|null $flag html flag, only for string and array
* @param string $expected always string
* @return void
*/
public function testPrintToString(mixed $input, ?bool $flag, string $expected): void
{
if ($flag === null) {
// if expected starts with / and ends with / then this is a regex compare
if (
substr($expected, 0, 1) == '/' &&
substr($expected, -1, 1) == '/'
) {
$this->assertMatchesRegularExpression(
$expected,
\CoreLibs\Debug\Support::printToString($input)
);
} else {
$this->assertEquals(
$expected,
\CoreLibs\Debug\Support::printToString($input)
);
}
} else {
$this->assertEquals(
$expected,
\CoreLibs\Debug\Support::printToString($input, $flag)
);
}
}
/**
* Undocumented function
*
* @cover ::getCallerMethod
* @testWith ["testGetCallerMethod"]
* @testdox getCallerMethod check if it returns $expected [$_dataName]
*
* @return void
*/
public function testGetCallerMethod(string $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Debug\Support::getCallerMethod()
);
}
/**
* Undocumented function
*
* @cover ::getCallerMethodList
* @testWith [["main", "run", "run", "run", "run", "run", "run", "runBare", "runTest", "testGetCallerMethodList"],["include", "main", "run", "run", "run", "run", "run", "run", "run", "runBare", "runTest", "testGetCallerMethodList"]]
* @testdox getCallerMethodList check if it returns $expected [$_dataName]
*
* @param array $expected
* @return void
*/
public function testGetCallerMethodList(array $expected, array $expected_group): void
{
$compare = \CoreLibs\Debug\Support::getCallerMethodList();
// if we direct call we have 10, if we call as folder we get 11
if (count($compare) == 10) {
$this->assertEquals(
$expected,
\CoreLibs\Debug\Support::getCallerMethodList(),
'assert expected 10'
);
} else {
$this->assertEquals(
$expected_group,
\CoreLibs\Debug\Support::getCallerMethodList(),
'assert expected group'
);
}
}
/**
* Undocumented function
*
* @cover ::getCallerClass
* @testWith ["PHPUnit\\TextUI\\Command"]
* @testdox getCallerClass check if it returns $expected [$_dataName]
*
* @return void
*/
public function testGetCallerClass(string $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Debug\Support::getCallerClass()
);
}
/**
* Undocumented function
*
@@ -453,19 +633,19 @@ final class CoreLibsDebugSupportTest extends TestCase
if ($replace === null && $flag === null) {
$this->assertEquals(
$expected,
\CoreLibs\Debug\Support::debugString($input),
Support::debugString($input),
'assert all default'
);
} elseif ($flag === null) {
$this->assertEquals(
$expected,
\CoreLibs\Debug\Support::debugString($input, $replace),
Support::debugString($input, $replace),
'assert flag default'
);
} else {
$this->assertEquals(
$expected,
\CoreLibs\Debug\Support::debugString($input, $replace, $flag),
Support::debugString($input, $replace, $flag),
'assert all set'
);
}

View File

@@ -0,0 +1,797 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
use CoreLibs\Logging\Logger\Level;
use CoreLibs\Logging\Logger\Flag;
// TODO: setLogPer test log file written matches pattern
/**
* Test class for Logging
* @coversDefaultClass \CoreLibs\Logging\Logging
* @testdox \CoreLibs\Logging\Logging method tests
*/
final class CoreLibsLoggingLoggingTest extends TestCase
{
private const LOG_FOLDER = __DIR__ . DIRECTORY_SEPARATOR . 'log' . DIRECTORY_SEPARATOR;
private const REGEX_BASE = "\[[\d\-\s\.:]+\]\s{1}" // date
. "\[[\w\.]+:\w+\]\s{1}" // host:port
. "\[[\w+\.\/]+\]\s{1}" // folder/file
. "\[\w+\]\s{1}" // run id
. "{[\w\\\\]+}\s{1}"; // class
/**
* test set for options BASIC
*
* 0: options
* - null for NOT set
* 1: expected
* 2: override
* override:
* - constant for COSNTANTS
* - global for _GLOBALS
*
* @return array
*/
public function optionsProvider(): array
{
return [
'log folder set' => [
'options' => [
'log_folder' => DIRECTORY_SEPARATOR . 'tmp',
'log_file_id' => 'testClassInit',
],
'expected' => [
'log_folder' => DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR,
'log_level' => Level::Debug,
'log_file_id' => 'testClassInit',
],
'override' => [],
],
// -> deprecation warning, log_folder must be set
'no log folder set' => [
'options' => [
'log_file_id' => 'testClassInit'
],
'expected' => [
'log_folder' => getcwd() . DIRECTORY_SEPARATOR,
'log_level' => Level::Debug,
'log_file_id' => 'testClassInit',
],
'override' => []
],
// -> upcoming deprecated
'file_id set but not log_file_id' => [
'options' => [
'log_folder' => DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR,
'file_id' => 'testClassInit',
],
'expected' => [
'log_folder' => DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR,
'log_level' => Level::Debug,
'log_file_id' => 'testClassInit',
],
'override' => [],
],
// both file_id and log_file_id set -> WARNING
'file_id and log_file_id set' => [
'options' => [
'log_folder' => DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR,
'file_id' => 'testClassInit',
'log_file_id' => 'testClassInit',
],
'expected' => [
'log_folder' => DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR,
'log_level' => Level::Debug,
'log_file_id' => 'testClassInit',
],
'override' => [],
],
// no log file id set -> error,
/* 'nothing set' => [
'options' => [],
'expected' => [
'log_folder' => getcwd() . DIRECTORY_SEPARATOR,
'log_level' => Level::Debug,
'log_file_id' => 'NOHOST-NOPORT_PHPUnit-TextUI-Command',
],
'override' => []
] */
];
}
/**
* init logging class
*
* @dataProvider optionsProvider
* @testdox init test [$_dataName]
*
* @param array $options
* @param array $expected
* @param array $override
* @return void
*/
public function testClassInit(array $options, array $expected, array $override): void
{
if (!empty($override['constant'])) {
foreach ($override['constant'] as $var => $value) {
if (!defined($var)) {
define($var, $value);
}
}
// for deprecated no log_folder set
// if base is defined and it does have AAASetupData set
// change the log_folder "Debug" to "AAASetupData"
if (
defined('BASE') &&
strpos(BASE, DIRECTORY_SEPARATOR . 'AAASetupData') !== false
) {
$expected['log_folder'] = str_replace(
DIRECTORY_SEPARATOR . 'Debug',
DIRECTORY_SEPARATOR . 'AAASetupData',
$expected['log_folder']
);
}
}
// if not log folder and constant set -> expect E_USER_DEPRECATION
if (!empty($override['constant']) && empty($options['log_folder'])) {
// the deprecation message
$deprecation_message = 'options: log_folder must be set. '
. 'Setting via BASE and LOG constants is deprecated';
// convert E_USER_DEPRECATED to a exception
set_error_handler(
static function (int $errno, string $errstr): never {
throw new \Exception($errstr, $errno);
},
E_USER_DEPRECATED
);
// catch this with the message
$this->expectExceptionMessage($deprecation_message);
}
// alert for log file id with globals
if (!empty($override['constant']) && empty($options['log_file_id'])) {
//
}
// alert for log file id and file id set
if (
!empty($options['log_file_id']) &&
!empty($options['file_id'])
) {
set_error_handler(
static function (int $errno, string $errstr): never {
throw new \InvalidArgumentException($errstr, $errno);
},
E_USER_WARNING
);
$error_message = 'options: "file_id" is deprecated use: "log_file_id".';
$this->expectExceptionMessage($error_message);
$this->expectException(\InvalidArgumentException::class);
set_error_handler(
static function (int $errno, string $errstr): never {
throw new \Exception($errstr, $errno);
},
E_USER_DEPRECATED
);
$this->expectException(\Exception::class);
// $error_message = 'options: both log_file_id and log_id are set at the same time, will use log_file_id';
// $this->expectExceptionMessage($error_message);
}
// empty log folder
if (empty($override['constant']) && empty($options['log_folder'])) {
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessageMatches("/^Missing mandatory option: \"/");
} elseif (empty($options['log_file_id']) && !empty($options['file_id'])) {
// the deprecation message
$deprecation_message = 'options: "file_id" is deprecated use: "log_file_id".';
// convert E_USER_DEPRECATED to a exception
set_error_handler(
static function (int $errno, string $errstr): never {
throw new \Exception($errstr, $errno);
},
E_USER_DEPRECATED
);
// catch this with the message
$this->expectExceptionMessage($deprecation_message);
}
$log = new \CoreLibs\Logging\Logging($options);
// reset error handler
restore_error_handler();
// check that settings match
$this->assertEquals(
$expected['log_folder'],
$log->getLogFolder(),
'log folder not matching'
);
$this->assertEquals(
$expected['log_file_id'],
$log->getLogFileId(),
'log file id not matching'
);
}
// test all setters/getters
// setLoggingLevel
// getLoggingLevel
// getJsDebug
/**
* Undocumented function
*
* @covers ::setLoggingLevel
* @covers ::getLoggingLevel
* @covers ::getJsDebug
* @testdox setLoggingLevel set/get checks
*
* @return void
*/
public function testSetLoggingLevel(): void
{
// valid that is not Debug
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testSetLoggingLevel',
'log_folder' => self::LOG_FOLDER,
'log_level' => Level::Info
]);
$this->assertEquals(
Level::Info,
$log->getLoggingLevel()
);
$this->assertFalse(
$log->getJsDebug()
);
// not set, should be debug]
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testSetLoggingLevel',
'log_folder' => self::LOG_FOLDER,
]);
$this->assertEquals(
Level::Debug,
$log->getLoggingLevel()
);
$this->assertTrue(
$log->getJsDebug()
);
// invalid, should be debug, will throw excpetion too
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Option: "log_level" is not of instance \CoreLibs\Logging\Logger\Level');
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testSetLoggingLevel',
'log_folder' => self::LOG_FOLDER,
'log_level' => 'I'
]);
$this->assertEquals(
Level::Debug,
$log->getLoggingLevel()
);
$this->assertTrue(
$log->getJsDebug()
);
// set valid, then change
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testSetLoggingLevel',
'log_folder' => self::LOG_FOLDER,
'log_level' => Level::Info
]);
$this->assertEquals(
Level::Info,
$log->getLoggingLevel()
);
$log->setLoggingLevel(Level::Notice);
$this->assertEquals(
Level::Notice,
$log->getLoggingLevel()
);
// illegal logging level
$this->expectException(\Psr\Log\InvalidArgumentException::class);
$this->expectExceptionMessageMatches("/^Level \"NotGood\" is not defined, use one of: /");
$log->setLoggingLevel('NotGood');
}
// setLogFileId
// getLogFileId
/**
* Undocumented function
*
* @covers ::setLogFileId
* @covers ::getLogFileId
* @testdox setLogFileId set/get checks
*
* @return void
*/
public function testLogFileId(): void
{
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testLogFileId',
'log_folder' => self::LOG_FOLDER
]);
// bad, keep same
$log->setLogFileId('$$##$%#$%&');
$this->assertEquals(
'testLogFileId',
$log->getLogFileId()
);
// good, change
$log->setLogFileId('validID');
$this->assertEquals(
'validID',
$log->getLogFileId()
);
// invalid on init
$this->expectException(\Psr\Log\InvalidArgumentException::class);
$this->expectExceptionMessage('LogFileId: no log file id set');
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => '$$$"#"#$"#$',
'log_folder' => self::LOG_FOLDER
]);
}
// setLogUniqueId
// getLogUniqueId
/**
* Undocumented function
*
* @return array
*/
public function logUniqueIdProvider(): array
{
return [
'option set' => [
'option' => true,
'override' => false,
],
'direct set' => [
'option' => false,
'override' => false,
],
'override set' => [
'option' => false,
'override' => true,
],
'option and override set' => [
'option' => false,
'override' => true,
],
];
}
/**
* Undocumented function
*
* @covers ::setLogUniqueId
* @covers ::getLogUniqueId
* @dataProvider logUniqueIdProvider
* @testdox per run log id set test: option: $option, override: $override [$_dataName]
*
* @param bool $option
* @param bool $override
* @return void
*/
public function testLogUniqueId(bool $option, bool $override): void
{
if ($option === true) {
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testLogUniqueId',
'log_folder' => self::LOG_FOLDER,
'log_per_run' => $option
]);
} else {
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testLogUniqueId',
'log_folder' => self::LOG_FOLDER
]);
$log->setLogUniqueId();
}
$per_run_id = $log->getLogUniqueId();
$this->assertMatchesRegularExpression(
"/^\d{4}-\d{2}-\d{2}_\d{6}_U_[a-z0-9]{8}$/",
$per_run_id,
'assert per log run id 1st'
);
if ($override === true) {
$log->setLogUniqueId(true);
$per_run_id_2nd = $log->getLogUniqueId();
$this->assertMatchesRegularExpression(
"/^\d{4}-\d{2}-\d{2}_\d{6}_U_[a-z0-9]{8}$/",
$per_run_id_2nd,
'assert per log run id 2nd'
);
$this->assertNotEquals(
$per_run_id,
$per_run_id_2nd,
'1st and 2nd don\'t match'
);
}
}
// setLogDate
// getLogDate
/**
* Undocumented function
*
* @covers ::setLogDate
* @covers ::getLogDate
* @testdox setLogDate set/get checks
*
* @return void
*/
public function testSetLogDate(): void
{
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testLogFileId',
'log_folder' => self::LOG_FOLDER,
'log_per_date' => true,
]);
$this->assertEquals(
date('Y-m-d'),
$log->getLogDate()
);
}
// setLogFlag
// getLogFlag
// unsetLogFlag
// getLogFlags
// Logger\Flag
/**
* Undocumented function
*
* @covers Logger\Flag
* @testdox Logger\Flag enum test
*
* @return void
*/
public function testLoggerFlag(): void
{
// logger flags to check that they exist
$flags = [
'all_off' => 0,
'per_run' => 1,
'per_date' => 2,
'per_group' => 4,
'per_page' => 8,
'per_class' => 16,
'per_level' => 32,
];
// from int -> return value
foreach ($flags as $name => $value) {
$this->assertEquals(
Flag::fromName($name),
Flag::fromValue($value)
);
}
}
/**
* Undocumented function
*
* @covers ::setLogFlag
* @covers ::getLogFlag
* @covers ::unsetLogFlag
* @covers ::getLogFlags
* @testdox setLogDate set/get checks
*
* @return void
*/
public function testSetLogFlag(): void
{
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testSetLogFlag',
'log_folder' => self::LOG_FOLDER,
]);
// set valid log flag
$log->setLogFlag(Flag::per_run);
$this->assertTrue(
$log->getLogFlag(Flag::per_run)
);
// flags seum
$this->assertEquals(
Flag::per_run->value,
$log->getLogFlags(),
);
// unset valid log flag
$log->unsetLogFlag(Flag::per_run);
$this->assertFalse(
$log->getLogFlag(Flag::per_run)
);
// illegal Flags cannot be set, they will throw eerros onrun
// test multi set and sum is equals set
$log->setLogFlag(Flag::per_date);
$log->setLogFlag(Flag::per_group);
$this->assertEquals(
Flag::per_date->value + Flag::per_group->value,
$log->getLogFlags()
);
}
// setLogFolder
// getLogFolder
/**
* Undocumented function
*
* @covers ::setLogFolder
* @covers ::getLogFolder
* @testdox setLogFolder set/get checks, init check
*
* @return void
*/
public function testSetLogFolder(): void
{
// set to good folder
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testSetLogFolder',
'log_folder' => self::LOG_FOLDER,
]);
$this->assertEquals(
self::LOG_FOLDER,
$log->getLogFolder()
);
// set to a good other folder
$log->setLogFolder(DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR);
$this->assertEquals(
DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR,
$log->getLogFolder()
);
// good other folder with missing trailing slash
$log->setLogFolder(DIRECTORY_SEPARATOR . 'tmp');
$this->assertEquals(
DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR,
$log->getLogFolder()
);
// a bad folder -> last good folder
$log->setLogFolder('I-am-not existing');
$this->assertEquals(
DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR,
$log->getLogFolder()
);
// init with a bad folder
$this->expectException(\Psr\Log\InvalidArgumentException::class);
$this->expectExceptionMessage('Folder: "I-am-bad" is not writeable for logging');
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testSetLogFolderInvalid',
'log_folder' => 'I-am-bad',
]);
}
// getLogFile (no set, only correct after log run)
// setLogMaxFileSize
// getLogMaxFileSize
/**
* Undocumented function
*
* @covers ::setLogMaxFileSize
* @covers ::getLogMaxFileSize
* @testdox setLogMaxFileSize set/get checks, init check
*
* @return void
*/
public function testSetLogMaxFileSize(): void
{
// init set to 0
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testSetLogMaxFileSize',
'log_folder' => self::LOG_FOLDER,
]);
$this->assertEquals(
0,
$log->getLogMaxFileSize()
);
// set to new, valid size
$file_size = 200 * 1024;
$valid = $log->setLogMaxFileSize($file_size);
$this->assertTrue($valid);
$this->assertEquals(
$file_size,
$log->getLogMaxFileSize()
);
// invalid size, < 0, will be last and return false
$valid = $log->setLogMaxFileSize(-1);
$this->assertFalse($valid);
$this->assertEquals(
$file_size,
$log->getLogMaxFileSize()
);
// too small (< MIN_LOG_MAX_FILESIZE)
$valid = $log->setLogMaxFileSize($log::MIN_LOG_MAX_FILESIZE - 1);
$this->assertFalse($valid);
$this->assertEquals(
$file_size,
$log->getLogMaxFileSize()
);
}
// getOption (option params)
/**
* Undocumented function
*
* @covers ::getOption
* @testdox getOption checks
*
* @return void
*/
public function testGetOption(): void
{
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testGetOption',
'log_folder' => self::LOG_FOLDER,
]);
$this->assertEquals(
self::LOG_FOLDER,
$log->getOption('log_folder')
);
// not found
$this->assertNull(
$log->getOption('I_do not exist')
);
}
// test all logger functions
// debug (special)
// info
// notice
// warning
// error
// critical
// alert
// emergency
/**
* Undocumented function
*
* @covers ::debug
* @testdox debug checks
*
* @return void
*/
public function testDebug(): void
{
// init logger
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testDebug',
'log_folder' => self::LOG_FOLDER,
]);
// clean all data in folder first
array_map('unlink', glob($log->getLogFolder() . $log->getLogFileId() . '*.log'));
$group_id = 'G';
$message = 'D';
$log_status = $log->debug($group_id, $message);
$this->assertTrue($log_status, 'debug write successful');
$file_content = file_get_contents(
$log->getLogFolder() . $log->getLogFile()
) ?: '';
$log_level = $log->getLoggingLevel()->getName();
// [2023-05-30 15:51:39.36128800] [NOHOST:NOPORT]
// [www/vendor/bin/phpunit] [7b9d0747] {PHPUnit\TextUI\Command}
// <DEBUG:G> D
$this->assertMatchesRegularExpression(
"/" . self::REGEX_BASE
. "<$log_level:$group_id>\s{1}" // log level / group id
. "$message" // message
. "/",
$file_content
);
}
public function providerLoggingLevelWrite(): array
{
return [
'info' => [
'message' => 'I',
'file_id' => Level::Info->name,
'level' => Level::Info
],
'notice' => [
'message' => 'N',
'file_id' => Level::Notice->name,
'level' => Level::Notice
],
'warning' => [
'message' => 'W',
'file_id' => Level::Warning->name,
'level' => Level::Warning
],
'error' => [
'message' => 'E',
'file_id' => Level::Error->name,
'level' => Level::Error
],
'crticial' => [
'message' => 'C',
'file_id' => Level::Critical->name,
'level' => Level::Critical
],
'alert' => [
'message' => 'A',
'file_id' => Level::Alert->name,
'level' => Level::Alert
],
'emergency' => [
'message' => 'Em',
'file_id' => Level::Emergency->name,
'level' => Level::Emergency
],
];
}
/**
* Undocumented function
*
* @covers ::info
* @covers ::notice
* @covers ::warning
* @covers ::error
* @covers ::critical
* @covers ::alert
* @covers ::emergency
* @dataProvider providerLoggingLevelWrite
* @testdox logging level write checks for $level [$_dataName]
*
* @return void
*/
public function testLoggingLevelWrite(string $message, string $file_id, Level $level): void
{
// init logger
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'test' . $file_id,
'log_folder' => self::LOG_FOLDER,
'log_level' => $level,
]);
// clean all data in folder first
array_map('unlink', glob($log->getLogFolder() . $log->getLogFileId() . '*.log'));
switch ($level->value) {
case 200:
$log_status = $log->info($message);
break;
case 250:
$log_status = $log->notice($message);
break;
case 300:
$log_status = $log->warning($message);
break;
case 400:
$log_status = $log->error($message);
break;
case 500:
$log_status = $log->critical($message);
break;
case 550:
$log_status = $log->alert($message);
break;
case 600:
$log_status = $log->emergency($message);
break;
}
$this->assertTrue($log_status, 'log write successful');
$file_content = file_get_contents(
$log->getLogFolder() . $log->getLogFile()
) ?: '';
$log_level = $log->getLoggingLevel()->getName();
$this->assertMatchesRegularExpression(
"/" . self::REGEX_BASE
. "<$log_level>\s{1}" // log level / group id
. "$message" // message
. "/",
$file_content,
'log message regex'
);
}
// deprecated calls check?
}
// __END__

3
4dev/tests/Logging/log/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
*log
*LOG
!.gitignore