Compare commits
104 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
65132d8a4a | ||
|
|
b2243cd06d | ||
|
|
8f09b67d86 | ||
|
|
fe459aec80 | ||
|
|
de0ed058ca | ||
|
|
f90bd193d9 | ||
|
|
0e31180868 | ||
|
|
68c9164eaa | ||
|
|
c2389db1c9 | ||
|
|
f9558cd3aa | ||
|
|
ae3011fe22 | ||
|
|
9b9dfeac69 | ||
|
|
33cb05a002 | ||
|
|
ec110499a8 | ||
|
|
09839f3451 | ||
|
|
067e0aed5d | ||
|
|
545de5c4a1 | ||
|
|
2fe37bf92a | ||
|
|
cd81d15d9a | ||
|
|
8a33ee5c15 | ||
|
|
46e1419ef5 | ||
|
|
c441063437 | ||
|
|
5290d5f351 | ||
|
|
2635ccb82b | ||
|
|
4f2ac2ed1b | ||
|
|
5b8e4e4e3e | ||
|
|
53192da571 | ||
|
|
f29e915068 | ||
|
|
46bc5f2da6 | ||
|
|
d70182a84e | ||
|
|
7243f69826 | ||
|
|
1fc144e178 | ||
|
|
c383a7b7b7 | ||
|
|
69077c384c | ||
|
|
cfd49947ad | ||
|
|
6985dc4e9d | ||
|
|
5f2668b011 | ||
|
|
eba1ef9c59 | ||
|
|
8497144053 | ||
|
|
2006798388 | ||
|
|
bf63d850ca | ||
|
|
53e267ce24 | ||
|
|
1754ecf2ee | ||
|
|
3c37899a48 | ||
|
|
0436cfe3da | ||
|
|
3606de1a00 | ||
|
|
3081439eda | ||
|
|
7af0e74b85 | ||
|
|
7748b83a6b | ||
|
|
f83293ff1a | ||
|
|
9c3be2942e | ||
|
|
ee62bd98ee | ||
|
|
02e9610fad | ||
|
|
8a41db4649 | ||
|
|
e27ea3dc9f | ||
|
|
ec4bf54d81 | ||
|
|
ec3ca787fa | ||
|
|
86acbbb85b | ||
|
|
8e0af7a5f7 | ||
|
|
b022662dfc | ||
|
|
3039ebf913 | ||
|
|
e2e080c404 | ||
|
|
4671143d1c | ||
|
|
b492558cca | ||
|
|
64e76530d4 | ||
|
|
0b93f9f146 | ||
|
|
4c6fe1cd6c | ||
|
|
83ba48f598 | ||
|
|
62c6de8244 | ||
|
|
1c2f9f0c2c | ||
|
|
30bb0e8895 | ||
|
|
75c4c98de8 | ||
|
|
f72055909b | ||
|
|
b0a8783276 | ||
|
|
7b5ad92e66 | ||
|
|
250067927a | ||
|
|
7c2cbbaca7 | ||
|
|
ac037eabde | ||
|
|
0250b86b3f | ||
|
|
e45acc412b | ||
|
|
854206bc70 | ||
|
|
b192e98a8a | ||
|
|
c4e2c781c6 | ||
|
|
e80b3b8dfd | ||
|
|
2b079ff836 | ||
|
|
37201799b5 | ||
|
|
b9d8911c7b | ||
|
|
c51ceb926e | ||
|
|
b4b33d6873 | ||
|
|
959240b0fa | ||
|
|
7eace1013e | ||
|
|
be1e55cad7 | ||
|
|
11a8c6440b | ||
|
|
742cbc31df | ||
|
|
28909fdc03 | ||
|
|
c3b29ad0d7 | ||
|
|
6d481657df | ||
|
|
fc57aabf5d | ||
|
|
d56ee68482 | ||
|
|
b89ab09e12 | ||
|
|
e873ade6c0 | ||
|
|
5910b884ac | ||
|
|
e3bd2c1c3b | ||
|
|
90a8c5540f |
@@ -96,8 +96,6 @@ return [
|
||||
"exclude_analysis_directory_list" => [
|
||||
'www/vendor',
|
||||
'www/tests',
|
||||
'www/lib/Smarty',
|
||||
'www/lib/smarty-4.3.0',
|
||||
'www/templates_c',
|
||||
'www/log',
|
||||
'www/tmp',
|
||||
@@ -118,10 +116,6 @@ return [
|
||||
// ignore the old qq tests
|
||||
'www/admin/qq_file_upload_front.php',
|
||||
'www/admin/qq_file_upload_ajax.php',
|
||||
// symlink ignore
|
||||
'www/lib/smarty-4.3.0/libs/Smarty.class.php',
|
||||
// legacy edit base (until removal)
|
||||
'www/includes/edit_base.LEGACY.php'
|
||||
],
|
||||
|
||||
// what not to show as problem
|
||||
@@ -134,7 +128,12 @@ return [
|
||||
'PhanWriteOnlyPublicProperty',
|
||||
'PhanUnreferencedConstant',
|
||||
'PhanWriteOnlyPublicProperty',
|
||||
'PhanReadOnlyPublicProperty'
|
||||
'PhanReadOnlyPublicProperty',
|
||||
// start ignore annotations
|
||||
'PhanUnextractableAnnotationElementName',
|
||||
'PhanUnextractableAnnotationSuffix',
|
||||
// enum problems in comments
|
||||
'PhanCommentObjectInClassConstantType'
|
||||
],
|
||||
|
||||
// Override to hardcode existence and types of (non-builtin) globals in the global scope.
|
||||
|
||||
@@ -7,6 +7,14 @@ namespace tests;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
|
||||
/*
|
||||
Not yet covered tests:
|
||||
- loginGetLocale
|
||||
- loginGetHeaderColor
|
||||
- loginGetPages
|
||||
- loginGetEuid
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test class for ACL\Login
|
||||
* @coversDefaultClass \CoreLibs\ACL\Login
|
||||
@@ -60,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(
|
||||
@@ -162,8 +167,10 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
// change_password, pw_username, pw_old_password, pw_new_password,
|
||||
// pw_new_password_confirm
|
||||
// 3[session]: override session set
|
||||
// 4[error] : expected error code, 0 for all ok, 3000 for login page view
|
||||
// note that 1000 (no db), 2000 (no session) must be tested too
|
||||
// 4[error] : expected error code, 0 for all ok, 100 for login page view
|
||||
// note that 1000 (no db), 2000 (no session), 3000 (options set error)
|
||||
// must be tested too
|
||||
// <1000 info, >=1000 critical error
|
||||
// 5[return] : expected return array, eg login_error code,
|
||||
// or other info data to match
|
||||
$tests = [
|
||||
@@ -175,7 +182,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
3000,
|
||||
100,
|
||||
[
|
||||
'login_error' => 0,
|
||||
'error_string' => 'Success: <b>No error</b>',
|
||||
@@ -193,7 +200,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
3000,
|
||||
100,
|
||||
[
|
||||
'login_error' => 0,
|
||||
'error_string' => 'Success: <b>No error</b>',
|
||||
@@ -216,7 +223,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
3000,
|
||||
100,
|
||||
[
|
||||
'login_error' => 0,
|
||||
'error_string' => 'Success: <b>No error</b>',
|
||||
@@ -259,6 +266,8 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
'GROUP_ACL_LEVEL' => -1,
|
||||
'PAGES_ACL_LEVEL' => [],
|
||||
'USER_ACL_LEVEL' => -1,
|
||||
'USER_ADDITIONAL_ACL' => [],
|
||||
'GROUP_ADDITIONAL_ACL' => [],
|
||||
'UNIT_UID' => [
|
||||
'AdminAccess' => 1,
|
||||
],
|
||||
@@ -272,6 +281,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
'data' => [
|
||||
'test' => 'value',
|
||||
],
|
||||
'additional_acl' => []
|
||||
],
|
||||
],
|
||||
// 'UNIT_DEFAULT' => '',
|
||||
@@ -300,7 +310,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
'login_password' => '',
|
||||
],
|
||||
[],
|
||||
3000,
|
||||
100,
|
||||
[
|
||||
'login_error' => 102,
|
||||
'error_string' => '<span style="color: red;">Fatal Error:</span> '
|
||||
@@ -321,7 +331,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
'login_password' => 'abc',
|
||||
],
|
||||
[],
|
||||
3000,
|
||||
100,
|
||||
[
|
||||
'login_error' => 102,
|
||||
'error_string' => '<span style="color: red;">Fatal Error:</span> '
|
||||
@@ -342,7 +352,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
'login_password' => '',
|
||||
],
|
||||
[],
|
||||
3000,
|
||||
100,
|
||||
[
|
||||
'login_error' => 102,
|
||||
'error_string' => '<span style="color: red;">Fatal Error:</span> '
|
||||
@@ -363,7 +373,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
'login_password' => 'abc',
|
||||
],
|
||||
[],
|
||||
3000,
|
||||
100,
|
||||
[
|
||||
'login_error' => 1010,
|
||||
'error_string' => '<span style="color: red;">Fatal Error:</span> '
|
||||
@@ -387,7 +397,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
'login_password' => 'abc',
|
||||
],
|
||||
[],
|
||||
3000,
|
||||
100,
|
||||
[
|
||||
// default password is plain text
|
||||
'login_error' => 1012,
|
||||
@@ -413,7 +423,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
'login_password' => 'admin',
|
||||
],
|
||||
[],
|
||||
3000,
|
||||
100,
|
||||
[
|
||||
'login_error' => 106,
|
||||
'error_string' => '<span style="color: red;">Fatal Error:</span> '
|
||||
@@ -438,7 +448,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
'login_password' => 'admin',
|
||||
],
|
||||
[],
|
||||
3000,
|
||||
100,
|
||||
[
|
||||
'login_error' => 104,
|
||||
'error_string' => '<span style="color: red;">Fatal Error:</span> '
|
||||
@@ -463,7 +473,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
'login_password' => 'admin',
|
||||
],
|
||||
[],
|
||||
3000,
|
||||
100,
|
||||
[
|
||||
'login_error' => 105,
|
||||
'error_string' => '<span style="color: red;">Fatal Error:</span> '
|
||||
@@ -512,7 +522,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
'login_password' => 'admin',
|
||||
],
|
||||
[],
|
||||
3000,
|
||||
100,
|
||||
[
|
||||
'login_error' => 107,
|
||||
'error_string' => '<span style="color: red;">Fatal Error:</span> '
|
||||
@@ -566,7 +576,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
'login_password' => 'admin',
|
||||
],
|
||||
[],
|
||||
3000,
|
||||
100,
|
||||
[
|
||||
'login_error' => 107,
|
||||
'error_string' => '<span style="color: red;">Fatal Error:</span> '
|
||||
@@ -592,7 +602,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
'login_password' => 'admin',
|
||||
],
|
||||
[],
|
||||
3000,
|
||||
100,
|
||||
[
|
||||
'login_error' => 107,
|
||||
'error_string' => '<span style="color: red;">Fatal Error:</span> '
|
||||
@@ -617,7 +627,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
'login_password' => 'admin',
|
||||
],
|
||||
[],
|
||||
3000,
|
||||
100,
|
||||
[
|
||||
'login_error' => 108,
|
||||
'error_string' => '<span style="color: red;">Fatal Error:</span> '
|
||||
@@ -753,7 +763,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
],
|
||||
[],
|
||||
[],
|
||||
3000,
|
||||
100,
|
||||
[
|
||||
'login_error' => 1010,
|
||||
'error_string' => '<span style="color: red;">Fatal Error:</span> '
|
||||
@@ -845,7 +855,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
],
|
||||
[],
|
||||
[],
|
||||
3000,
|
||||
100,
|
||||
[
|
||||
'login_error' => 1101,
|
||||
'error_string' => '<span style="color: red;">Fatal Error:</span> '
|
||||
@@ -901,7 +911,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
],
|
||||
[],
|
||||
[],
|
||||
3000,
|
||||
100,
|
||||
[
|
||||
'login_error' => 1102,
|
||||
'error_string' => '<span style="color: red;">Fatal Error:</span> '
|
||||
@@ -957,7 +967,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
],
|
||||
[],
|
||||
[],
|
||||
3000,
|
||||
100,
|
||||
[
|
||||
'login_error' => 1102,
|
||||
'error_string' => '<span style="color: red;">Fatal Error:</span> '
|
||||
@@ -984,7 +994,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
],
|
||||
[],
|
||||
[],
|
||||
3000,
|
||||
100,
|
||||
[
|
||||
'login_error' => 1102,
|
||||
'error_string' => '<span style="color: red;">Fatal Error:</span> '
|
||||
@@ -1114,6 +1124,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
'logout_target' => '',
|
||||
'site_locale' => 'en_US.UTF-8',
|
||||
'site_domain' => 'admin',
|
||||
'site_encoding' => 'UTF-8',
|
||||
'locale_path' => __DIR__ . DIRECTORY_SEPARATOR
|
||||
. 'includes' . DIRECTORY_SEPARATOR
|
||||
. 'locale' . DIRECTORY_SEPARATOR,
|
||||
@@ -1124,7 +1135,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
$login_mock->expects($this->any())
|
||||
->method('loginTerminate')
|
||||
->will(
|
||||
$this->returnCallback(function ($code) {
|
||||
$this->returnCallback(function ($message, $code) {
|
||||
throw new \Exception('', $code);
|
||||
})
|
||||
);
|
||||
@@ -1218,7 +1229,11 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
$login_mock->loginSetMaxLoginErrorCount($mock_settings['max_login_error_count']);
|
||||
// temporary wrong password
|
||||
$_POST['login_password'] = 'wrong';
|
||||
for ($run = 1, $max_run = $login_mock->loginGetMaxLoginErrorCount(); $run <= $max_run; $run++) {
|
||||
for (
|
||||
$run = 1, $max_run = $login_mock->loginGetMaxLoginErrorCount();
|
||||
$run <= $max_run;
|
||||
$run++
|
||||
) {
|
||||
try {
|
||||
$login_mock->loginMainCall();
|
||||
} catch (\Exception $e) {
|
||||
@@ -1466,10 +1481,10 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
// print "AJAX: " . $login_mock->loginGetAjaxFlag() . "\n";
|
||||
// print "AJAX GLOBAL: " . ($GLOBALS['AJAX_PAGE'] ?? '{f}') . "\n";
|
||||
// print "Login error expext: " . ($expected['login_error'] ?? '{0}') . "\n";
|
||||
// if this is 3000, then we do further error checks
|
||||
// if this is 100, then we do further error checks
|
||||
if (
|
||||
$e->getCode() == 3000 ||
|
||||
!empty($_POST['login_exit']) && $_POST['login_exit'] == 3000
|
||||
$e->getCode() == 100 ||
|
||||
!empty($_POST['login_exit']) && $_POST['login_exit'] == 100
|
||||
) {
|
||||
$this->assertEquals(
|
||||
$expected['login_error'],
|
||||
@@ -1796,6 +1811,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
'logout_target' => '',
|
||||
'site_locale' => 'en_US.UTF-8',
|
||||
'site_domain' => 'admin',
|
||||
'site_encoding' => 'UTF-8',
|
||||
'locale_path' => __DIR__ . DIRECTORY_SEPARATOR
|
||||
. 'includes' . DIRECTORY_SEPARATOR
|
||||
. 'locale' . DIRECTORY_SEPARATOR,
|
||||
@@ -1806,7 +1822,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
$login_mock->expects($this->any())
|
||||
->method('loginTerminate')
|
||||
->will(
|
||||
$this->returnCallback(function ($code) {
|
||||
$this->returnCallback(function ($message, $code) {
|
||||
throw new \Exception('', $code);
|
||||
})
|
||||
);
|
||||
@@ -1909,6 +1925,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
'logout_target' => '',
|
||||
'site_locale' => 'en_US.UTF-8',
|
||||
'site_domain' => 'admin',
|
||||
'site_encoding' => 'UTF-8',
|
||||
'locale_path' => __DIR__ . DIRECTORY_SEPARATOR
|
||||
. 'includes' . DIRECTORY_SEPARATOR
|
||||
. 'locale' . DIRECTORY_SEPARATOR,
|
||||
@@ -1919,7 +1936,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
$login_mock->expects($this->any())
|
||||
->method('loginTerminate')
|
||||
->will(
|
||||
$this->returnCallback(function ($code) {
|
||||
$this->returnCallback(function ($message, $code) {
|
||||
throw new \Exception('', $code);
|
||||
})
|
||||
);
|
||||
@@ -1996,6 +2013,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
'logout_target' => '',
|
||||
'site_locale' => 'en_US.UTF-8',
|
||||
'site_domain' => 'admin',
|
||||
'site_encoding' => 'UTF-8',
|
||||
'locale_path' => __DIR__ . DIRECTORY_SEPARATOR
|
||||
. 'includes' . DIRECTORY_SEPARATOR
|
||||
. 'locale' . DIRECTORY_SEPARATOR,
|
||||
@@ -2006,7 +2024,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
$login_mock->expects($this->any())
|
||||
->method('loginTerminate')
|
||||
->will(
|
||||
$this->returnCallback(function ($code) {
|
||||
$this->returnCallback(function ($message, $code) {
|
||||
throw new \Exception('', $code);
|
||||
})
|
||||
);
|
||||
@@ -2091,6 +2109,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
'logout_target' => '',
|
||||
'site_locale' => 'en_US.UTF-8',
|
||||
'site_domain' => 'admin',
|
||||
'site_encoding' => 'UTF-8',
|
||||
'locale_path' => __DIR__ . DIRECTORY_SEPARATOR
|
||||
. 'includes' . DIRECTORY_SEPARATOR
|
||||
. 'locale' . DIRECTORY_SEPARATOR,
|
||||
@@ -2101,7 +2120,7 @@ final class CoreLibsACLLoginTest extends TestCase
|
||||
$login_mock->expects($this->any())
|
||||
->method('loginTerminate')
|
||||
->will(
|
||||
$this->returnCallback(function ($code) {
|
||||
$this->returnCallback(function ($message, $code) {
|
||||
throw new \Exception('', $code);
|
||||
})
|
||||
);
|
||||
|
||||
@@ -13,6 +13,11 @@ use PHPUnit\Framework\TestCase;
|
||||
*/
|
||||
final class CoreLibsCheckColorsTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @return array<mixed>
|
||||
*/
|
||||
public function validateColorProvider(): array
|
||||
{
|
||||
/*
|
||||
@@ -321,7 +326,7 @@ final class CoreLibsCheckColorsTest extends TestCase
|
||||
*/
|
||||
public function testValidateColorException(int $flag): void
|
||||
{
|
||||
$this->expectException(\Exception::class);
|
||||
$this->expectException(\UnexpectedValueException::class);
|
||||
\CoreLibs\Check\Colors::validateColor('#ffffff', $flag);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ final class CoreLibsCombinedArrayHandlerTest extends TestCase
|
||||
4,
|
||||
'b',
|
||||
'c' => 'test',
|
||||
'single' => 'single',
|
||||
'same' => 'same',
|
||||
'deep' => [
|
||||
'sub' => [
|
||||
@@ -288,6 +289,188 @@ final class CoreLibsCombinedArrayHandlerTest extends TestCase
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function arraySearchKeyProvider(): array
|
||||
{
|
||||
/*
|
||||
0: search in array
|
||||
1: search keys
|
||||
2: flat flag
|
||||
3: prefix flag
|
||||
4: expected array
|
||||
*/
|
||||
return [
|
||||
// single
|
||||
'find single, standard' => [
|
||||
0 => self::$array,
|
||||
1 => ['single'],
|
||||
2 => null,
|
||||
3 => null,
|
||||
4 => [
|
||||
0 => [
|
||||
'value' => 'single',
|
||||
'path' => ['single'],
|
||||
],
|
||||
],
|
||||
],
|
||||
'find single, prefix' => [
|
||||
0 => self::$array,
|
||||
1 => ['single'],
|
||||
2 => null,
|
||||
3 => true,
|
||||
4 => [
|
||||
'single' => [
|
||||
0 => [
|
||||
'value' => 'single',
|
||||
'path' => ['single'],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
'find single, flat' => [
|
||||
0 => self::$array,
|
||||
1 => ['single'],
|
||||
2 => true,
|
||||
3 => null,
|
||||
4 => [
|
||||
'single',
|
||||
],
|
||||
],
|
||||
'find single, flat, prefix' => [
|
||||
0 => self::$array,
|
||||
1 => ['single'],
|
||||
2 => true,
|
||||
3 => true,
|
||||
4 => [
|
||||
'single' => [
|
||||
'single',
|
||||
],
|
||||
],
|
||||
],
|
||||
// not found
|
||||
'not found, standard' => [
|
||||
0 => self::$array,
|
||||
1 => ['NOT FOUND'],
|
||||
2 => null,
|
||||
3 => null,
|
||||
4 => [],
|
||||
],
|
||||
'not found, standard, prefix' => [
|
||||
0 => self::$array,
|
||||
1 => ['NOT FOUND'],
|
||||
2 => null,
|
||||
3 => true,
|
||||
4 => [
|
||||
'NOT FOUND' => [],
|
||||
],
|
||||
],
|
||||
'not found, flat' => [
|
||||
0 => self::$array,
|
||||
1 => ['NOT FOUND'],
|
||||
2 => true,
|
||||
3 => null,
|
||||
4 => [],
|
||||
],
|
||||
'not found, flat, prefix' => [
|
||||
0 => self::$array,
|
||||
1 => ['NOT FOUND'],
|
||||
2 => true,
|
||||
3 => true,
|
||||
4 => [
|
||||
'NOT FOUND' => [],
|
||||
],
|
||||
],
|
||||
// multi
|
||||
'multiple found, standard' => [
|
||||
0 => self::$array,
|
||||
1 => ['same'],
|
||||
2 => null,
|
||||
3 => null,
|
||||
4 => [
|
||||
[
|
||||
'value' => 'same',
|
||||
'path' => ['a', 'same', ],
|
||||
],
|
||||
[
|
||||
'value' => 'same',
|
||||
'path' => ['same', ],
|
||||
],
|
||||
[
|
||||
'value' => 'same',
|
||||
'path' => ['deep', 'sub', 'same', ],
|
||||
],
|
||||
]
|
||||
],
|
||||
'multiple found, flat' => [
|
||||
0 => self::$array,
|
||||
1 => ['same'],
|
||||
2 => true,
|
||||
3 => null,
|
||||
4 => ['same', 'same', 'same', ],
|
||||
],
|
||||
// search with multiple
|
||||
'search multiple, standard' => [
|
||||
0 => self::$array,
|
||||
1 => ['single', 'nested'],
|
||||
2 => null,
|
||||
3 => null,
|
||||
4 => [
|
||||
[
|
||||
'value' => 'single',
|
||||
'path' => ['single'],
|
||||
],
|
||||
[
|
||||
'value' => 'bar',
|
||||
'path' => ['deep', 'sub', 'nested', ],
|
||||
],
|
||||
],
|
||||
],
|
||||
'search multiple, prefix' => [
|
||||
0 => self::$array,
|
||||
1 => ['single', 'nested'],
|
||||
2 => null,
|
||||
3 => true,
|
||||
4 => [
|
||||
'single' => [
|
||||
[
|
||||
'value' => 'single',
|
||||
'path' => ['single'],
|
||||
],
|
||||
],
|
||||
'nested' => [
|
||||
[
|
||||
'value' => 'bar',
|
||||
'path' => ['deep', 'sub', 'nested', ],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
'search multiple, flat' => [
|
||||
0 => self::$array,
|
||||
1 => ['single', 'nested'],
|
||||
2 => true,
|
||||
3 => null,
|
||||
4 => [
|
||||
'single', 'bar',
|
||||
],
|
||||
],
|
||||
'search multiple, flat, prefix' => [
|
||||
0 => self::$array,
|
||||
1 => ['single', 'nested'],
|
||||
2 => true,
|
||||
3 => true,
|
||||
4 => [
|
||||
'single' => ['single', ],
|
||||
'nested' => ['bar', ],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* provides array listing for the merge test
|
||||
*
|
||||
@@ -335,17 +518,20 @@ final class CoreLibsCombinedArrayHandlerTest extends TestCase
|
||||
return [
|
||||
// error <2 arguments
|
||||
'too view arguments' => [
|
||||
'ArgumentCountError',
|
||||
'arrayMergeRecursive needs two or more array arguments',
|
||||
[1]
|
||||
],
|
||||
// error <2 arrays
|
||||
'only one array' => [
|
||||
'ArgumentCountError',
|
||||
'arrayMergeRecursive needs two or more array arguments',
|
||||
[1],
|
||||
true,
|
||||
],
|
||||
// error element is not array
|
||||
'non array between array' => [
|
||||
'TypeError',
|
||||
'arrayMergeRecursive encountered a non array argument',
|
||||
[1],
|
||||
'string',
|
||||
@@ -691,6 +877,44 @@ final class CoreLibsCombinedArrayHandlerTest extends TestCase
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @covers::arraySearchKey
|
||||
* @dataProvider arraySearchKeyProvider
|
||||
* @testdox arraySearchKey Search array with keys and flat: $flat, prefix: $prefix [$_dataName]
|
||||
*
|
||||
* @param array $input
|
||||
* @param array $needles
|
||||
* @param bool|null $flat
|
||||
* @param bool|null $prefix
|
||||
* @param array $expected
|
||||
* @return void
|
||||
*/
|
||||
public function testArraySearchKey(
|
||||
array $input,
|
||||
array $needles,
|
||||
?bool $flat,
|
||||
?bool $prefix,
|
||||
array $expected
|
||||
): void {
|
||||
if ($flat === null && $prefix === null) {
|
||||
$result = \CoreLibs\Combined\ArrayHandler::arraySearchKey($input, $needles);
|
||||
} elseif ($flat === null) {
|
||||
$result = \CoreLibs\Combined\ArrayHandler::arraySearchKey($input, $needles, prefix: $prefix);
|
||||
} elseif ($prefix === null) {
|
||||
$result = \CoreLibs\Combined\ArrayHandler::arraySearchKey($input, $needles, flat: $flat);
|
||||
} else {
|
||||
$result = \CoreLibs\Combined\ArrayHandler::arraySearchKey($input, $needles, $flat, $prefix);
|
||||
}
|
||||
// print "E: " . print_r($expected, true) . "\n";
|
||||
// print "R: " . print_r($result, true) . "\n";
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
$result
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
@@ -726,18 +950,20 @@ final class CoreLibsCombinedArrayHandlerTest extends TestCase
|
||||
*/
|
||||
public function testArrayMergeRecursiveWarningA(): void
|
||||
{
|
||||
set_error_handler(
|
||||
static function (int $errno, string $errstr): never {
|
||||
throw new Exception($errstr, $errno);
|
||||
},
|
||||
E_USER_WARNING
|
||||
);
|
||||
// set_error_handler(
|
||||
// static function (int $errno, string $errstr): never {
|
||||
// throw new Exception($errstr, $errno);
|
||||
// },
|
||||
// E_USER_WARNING
|
||||
// );
|
||||
|
||||
$arrays = func_get_args();
|
||||
// first is expected warning
|
||||
$exception = array_shift($arrays);
|
||||
$warning = array_shift($arrays);
|
||||
|
||||
// phpunit 10.0 compatible
|
||||
$this->expectException($exception);
|
||||
$this->expectExceptionMessage($warning);
|
||||
|
||||
\CoreLibs\Combined\ArrayHandler::arrayMergeRecursive(...$arrays);
|
||||
|
||||
@@ -309,45 +309,73 @@ final class CoreLibsCombinedDateTimeTest extends TestCase
|
||||
'2020-12-12',
|
||||
'2021-12-12',
|
||||
-1,
|
||||
null,
|
||||
null,
|
||||
],
|
||||
'dates equal' => [
|
||||
'2020-12-12',
|
||||
'2020-12-12',
|
||||
0,
|
||||
null,
|
||||
null,
|
||||
],
|
||||
'second date smaller' => [
|
||||
'2021-12-12',
|
||||
'2020-12-12',
|
||||
1
|
||||
1,
|
||||
null,
|
||||
null,
|
||||
],
|
||||
'dates equal with different time' => [
|
||||
'2020-12-12 12:12:12',
|
||||
'2020-12-12 13:13:13',
|
||||
0,
|
||||
null,
|
||||
null,
|
||||
],
|
||||
'invalid dates --' => [
|
||||
'--',
|
||||
'--',
|
||||
false
|
||||
false,
|
||||
'UnexpectedValueException',
|
||||
1,
|
||||
],
|
||||
'empty dates' => [
|
||||
'',
|
||||
'',
|
||||
false
|
||||
false,
|
||||
'UnexpectedValueException',
|
||||
1
|
||||
],
|
||||
'invalid dates' => [
|
||||
'not a date',
|
||||
'not a date either',
|
||||
false,
|
||||
'UnexpectedValueException',
|
||||
2
|
||||
],
|
||||
'invalid end date' => [
|
||||
'1990-01-01',
|
||||
'not a date either',
|
||||
false,
|
||||
'UnexpectedValueException',
|
||||
3
|
||||
],
|
||||
'out of bound dates' => [
|
||||
'1900-1-1',
|
||||
'9999-12-31',
|
||||
-1
|
||||
-1,
|
||||
null,
|
||||
null,
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @return array<mixed>
|
||||
*/
|
||||
public function dateTimeCompareProvider(): array
|
||||
{
|
||||
return [
|
||||
@@ -355,51 +383,85 @@ final class CoreLibsCombinedDateTimeTest extends TestCase
|
||||
'2020-12-12',
|
||||
'2021-12-12',
|
||||
-1,
|
||||
null,
|
||||
null,
|
||||
],
|
||||
'dates equal no timestamp' => [
|
||||
'2020-12-12',
|
||||
'2020-12-12',
|
||||
0,
|
||||
null,
|
||||
null,
|
||||
],
|
||||
'second date smaller no timestamp' => [
|
||||
'2021-12-12',
|
||||
'2020-12-12',
|
||||
1
|
||||
1,
|
||||
null,
|
||||
null,
|
||||
],
|
||||
'date equal first time smaller' => [
|
||||
'2020-12-12 12:12:12',
|
||||
'2020-12-12 13:13:13',
|
||||
-1,
|
||||
null,
|
||||
null,
|
||||
],
|
||||
'date equal time equal' => [
|
||||
'2020-12-12 12:12:12',
|
||||
'2020-12-12 12:12:12',
|
||||
0,
|
||||
null,
|
||||
null,
|
||||
],
|
||||
'date equal second time smaller' => [
|
||||
'2020-12-12 13:13:13',
|
||||
'2020-12-12 12:12:12',
|
||||
1,
|
||||
null,
|
||||
null,
|
||||
],
|
||||
'valid date invalid time' => [
|
||||
'2020-12-12 13:99:13',
|
||||
'2020-12-12 12:12:99',
|
||||
false,
|
||||
'UnexpectedValueException',
|
||||
2
|
||||
],
|
||||
'valid date invalid end time' => [
|
||||
'2020-12-12 13:12:13',
|
||||
'2020-12-12 12:12:99',
|
||||
false,
|
||||
'UnexpectedValueException',
|
||||
3
|
||||
],
|
||||
'invalid datetimes --' => [
|
||||
'--',
|
||||
'--',
|
||||
false,
|
||||
'UnexpectedValueException',
|
||||
1
|
||||
],
|
||||
'empty datetimess' => [
|
||||
'',
|
||||
'',
|
||||
false,
|
||||
'UnexpectedValueException',
|
||||
1
|
||||
],
|
||||
'invalid datetimes' => [
|
||||
'invalid date times' => [
|
||||
'not a date',
|
||||
'not a date either',
|
||||
false,
|
||||
'UnexpectedValueException',
|
||||
2
|
||||
],
|
||||
'invalid end date time' => [
|
||||
'1990-01-01 12:12:12',
|
||||
'not a date either',
|
||||
false,
|
||||
'UnexpectedValueException',
|
||||
3
|
||||
],
|
||||
];
|
||||
}
|
||||
@@ -458,6 +520,47 @@ final class CoreLibsCombinedDateTimeTest extends TestCase
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function dateRangeHasWeekendProvider(): array
|
||||
{
|
||||
return [
|
||||
'no weekend' => [
|
||||
'2023-07-03',
|
||||
'2023-07-04',
|
||||
false
|
||||
],
|
||||
'start weekend sat' => [
|
||||
'2023-07-01',
|
||||
'2023-07-04',
|
||||
true
|
||||
],
|
||||
'start weekend sun' => [
|
||||
'2023-07-02',
|
||||
'2023-07-04',
|
||||
true
|
||||
],
|
||||
'end weekend sat' => [
|
||||
'2023-07-03',
|
||||
'2023-07-08',
|
||||
true
|
||||
],
|
||||
'end weekend sun' => [
|
||||
'2023-07-03',
|
||||
'2023-07-09',
|
||||
true
|
||||
],
|
||||
'long period > 6 days' => [
|
||||
'2023-07-03',
|
||||
'2023-07-27',
|
||||
true
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* date string convert test
|
||||
*
|
||||
@@ -573,10 +676,21 @@ final class CoreLibsCombinedDateTimeTest extends TestCase
|
||||
* @param string $input_a
|
||||
* @param string $input_b
|
||||
* @param int|bool $expected
|
||||
* @param string|null $exception
|
||||
* @param int|null $exception_code
|
||||
* @return void
|
||||
*/
|
||||
public function testCompareDate(string $input_a, string $input_b, $expected): void
|
||||
{
|
||||
public function testCompareDate(
|
||||
string $input_a,
|
||||
string $input_b,
|
||||
int|bool $expected,
|
||||
?string $exception,
|
||||
?int $exception_code
|
||||
): void {
|
||||
if ($expected === false) {
|
||||
$this->expectException($exception);
|
||||
$this->expectExceptionCode($exception_code);
|
||||
}
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
\CoreLibs\Combined\DateTime::compareDate($input_a, $input_b)
|
||||
@@ -593,10 +707,21 @@ final class CoreLibsCombinedDateTimeTest extends TestCase
|
||||
* @param string $input_a
|
||||
* @param string $input_b
|
||||
* @param int|bool $expected
|
||||
* @param string|null $exception
|
||||
* @param int|null $exception_code
|
||||
* @return void
|
||||
*/
|
||||
public function testCompareDateTime(string $input_a, string $input_b, $expected): void
|
||||
{
|
||||
public function testCompareDateTime(
|
||||
string $input_a,
|
||||
string $input_b,
|
||||
int|bool $expected,
|
||||
?string $exception,
|
||||
?int $exception_code
|
||||
): void {
|
||||
if ($expected === false) {
|
||||
$this->expectException($exception);
|
||||
$this->expectExceptionCode($exception_code);
|
||||
}
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
\CoreLibs\Combined\DateTime::compareDateTime($input_a, $input_b)
|
||||
@@ -780,6 +905,29 @@ final class CoreLibsCombinedDateTimeTest extends TestCase
|
||||
$output
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @covers ::dateRangeHasWeekend
|
||||
* @dataProvider dateRangeHasWeekendProvider
|
||||
* @testdox dateRangeHasWeekend $start_date and $end_date are expected weekend $expected [$_dataName]
|
||||
*
|
||||
* @param string $start_date
|
||||
* @param string $end_date
|
||||
* @param bool $expected
|
||||
* @return void
|
||||
*/
|
||||
public function testDateRangeHasWeekend(
|
||||
string $start_date,
|
||||
string $end_date,
|
||||
bool $expected
|
||||
): void {
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
\CoreLibs\Combined\DateTime::dateRangeHasWeekend($start_date, $end_date)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// __END__
|
||||
|
||||
@@ -59,6 +59,27 @@ final class CoreLibsConvertColorsTest extends TestCase
|
||||
3 => false,
|
||||
4 => false
|
||||
],
|
||||
'invalid color red ' => [
|
||||
0 => -12,
|
||||
1 => 12,
|
||||
2 => 12,
|
||||
3 => false,
|
||||
4 => false
|
||||
],
|
||||
'invalid color green ' => [
|
||||
0 => 12,
|
||||
1 => -12,
|
||||
2 => 12,
|
||||
3 => false,
|
||||
4 => false
|
||||
],
|
||||
'invalid color blue ' => [
|
||||
0 => 12,
|
||||
1 => 12,
|
||||
2 => -12,
|
||||
3 => false,
|
||||
4 => false
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -150,10 +171,40 @@ final class CoreLibsConvertColorsTest extends TestCase
|
||||
'valid' => true,
|
||||
],
|
||||
// invalid values
|
||||
'invalid color' => [
|
||||
'rgb' => [-12, 300, 12],
|
||||
'hsb' => [-12, 300, 12],
|
||||
'hsl' => [-12, 300, 12],
|
||||
'invalid color r/h/h low' => [
|
||||
'rgb' => [-1, 12, 12],
|
||||
'hsb' => [-1, 50, 50],
|
||||
'hsl' => [-1, 50, 50],
|
||||
'valid' => false,
|
||||
],
|
||||
'invalid color r/h/h high' => [
|
||||
'rgb' => [256, 12, 12],
|
||||
'hsb' => [361, 50, 50],
|
||||
'hsl' => [361, 50, 50],
|
||||
'valid' => false,
|
||||
],
|
||||
'invalid color g/s/s low' => [
|
||||
'rgb' => [12, -1, 12],
|
||||
'hsb' => [1, -1, 50],
|
||||
'hsl' => [1, -1, 50],
|
||||
'valid' => false,
|
||||
],
|
||||
'invalid color g/s/s high' => [
|
||||
'rgb' => [12, 256, 12],
|
||||
'hsb' => [1, 101, 50],
|
||||
'hsl' => [1, 101, 50],
|
||||
'valid' => false,
|
||||
],
|
||||
'invalid color b/b/l low' => [
|
||||
'rgb' => [12, 12, -1],
|
||||
'hsb' => [1, 50, -1],
|
||||
'hsl' => [1, 50, -1],
|
||||
'valid' => false,
|
||||
],
|
||||
'invalid color b/b/l high' => [
|
||||
'rgb' => [12, 12, 256],
|
||||
'hsb' => [1, 50, 101],
|
||||
'hsl' => [1, 50, 101],
|
||||
'valid' => false,
|
||||
],
|
||||
];
|
||||
@@ -246,11 +297,22 @@ final class CoreLibsConvertColorsTest extends TestCase
|
||||
* @param int $input_r
|
||||
* @param int $input_g
|
||||
* @param int $input_b
|
||||
* @param string|bool $expected_hash
|
||||
* @param string|bool $expected
|
||||
* @return void
|
||||
*/
|
||||
public function testRgb2hex(int $input_r, int $input_g, int $input_b, $expected_hash, $expected)
|
||||
{
|
||||
public function testRgb2hex(
|
||||
int $input_r,
|
||||
int $input_g,
|
||||
int $input_b,
|
||||
string|bool $expected_hash,
|
||||
string|bool $expected
|
||||
) {
|
||||
// if expected hash is or expected is false, we need to check for
|
||||
// LengthException
|
||||
if ($expected_hash === false || $expected === false) {
|
||||
$this->expectException(\LengthException::class);
|
||||
}
|
||||
// with #
|
||||
$this->assertEquals(
|
||||
$expected_hash,
|
||||
@@ -292,11 +354,19 @@ final class CoreLibsConvertColorsTest extends TestCase
|
||||
*/
|
||||
public function testHex2rgb(
|
||||
string $input,
|
||||
$expected,
|
||||
$expected_str,
|
||||
array|bool $expected,
|
||||
string|bool $expected_str,
|
||||
string $separator,
|
||||
$expected_str_sep
|
||||
string|bool $expected_str_sep
|
||||
): void {
|
||||
if ($expected === false || $expected_str === false || $expected_str_sep === false) {
|
||||
$hex_string = preg_replace("/[^0-9A-Fa-f]/", '', $input);
|
||||
if (!is_string($hex_string)) {
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
} else {
|
||||
$this->expectException(\UnexpectedValueException::class);
|
||||
}
|
||||
}
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
\CoreLibs\Convert\Colors::hex2rgb($input)
|
||||
@@ -324,8 +394,11 @@ final class CoreLibsConvertColorsTest extends TestCase
|
||||
* @param array|bool $expected
|
||||
* @return void
|
||||
*/
|
||||
public function testRgb2hsb(int $input_r, int $input_g, int $input_b, $expected): void
|
||||
public function testRgb2hsb(int $input_r, int $input_g, int $input_b, array|bool $expected): void
|
||||
{
|
||||
if ($expected === false) {
|
||||
$this->expectException(\LengthException::class);
|
||||
}
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
\CoreLibs\Convert\Colors::rgb2hsb($input_r, $input_g, $input_b)
|
||||
@@ -345,8 +418,12 @@ final class CoreLibsConvertColorsTest extends TestCase
|
||||
* @param array|bool $expected
|
||||
* @return void
|
||||
*/
|
||||
public function testHsb2rgb(float $input_h, float $input_s, float $input_b, $expected): void
|
||||
public function testHsb2rgb(float $input_h, float $input_s, float $input_b, array|bool $expected): void
|
||||
{
|
||||
if ($expected === false) {
|
||||
$this->expectException(\LengthException::class);
|
||||
$expected = [];
|
||||
}
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
\CoreLibs\Convert\Colors::hsb2rgb($input_h, $input_s, $input_b)
|
||||
@@ -366,8 +443,11 @@ final class CoreLibsConvertColorsTest extends TestCase
|
||||
* @param array|bool $expected
|
||||
* @return void
|
||||
*/
|
||||
public function testRgb2hsl(int $input_r, int $input_g, int $input_b, $expected): void
|
||||
public function testRgb2hsl(int $input_r, int $input_g, int $input_b, array|bool $expected): void
|
||||
{
|
||||
if ($expected === false) {
|
||||
$this->expectException(\LengthException::class);
|
||||
}
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
\CoreLibs\Convert\Colors::rgb2hsl($input_r, $input_g, $input_b)
|
||||
@@ -387,8 +467,11 @@ final class CoreLibsConvertColorsTest extends TestCase
|
||||
* @param array|bool $expected
|
||||
* @return void
|
||||
*/
|
||||
public function testHsl2rgb($input_h, float $input_s, float $input_l, $expected): void
|
||||
public function testHsl2rgb(int|float $input_h, float $input_s, float $input_l, array|bool $expected): void
|
||||
{
|
||||
if ($expected === false) {
|
||||
$this->expectException(\LengthException::class);
|
||||
}
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
\CoreLibs\Convert\Colors::hsl2rgb($input_h, $input_s, $input_l)
|
||||
@@ -406,11 +489,11 @@ final class CoreLibsConvertColorsTest extends TestCase
|
||||
*/
|
||||
public function testHslHsb360hue(): void
|
||||
{
|
||||
$this->assertNotFalse(
|
||||
$this->assertIsArray(
|
||||
\CoreLibs\Convert\Colors::hsl2rgb(360.0, 90.5, 41.2),
|
||||
'HSL to RGB with 360 hue'
|
||||
);
|
||||
$this->assertNotFalse(
|
||||
$this->assertIsArray(
|
||||
\CoreLibs\Convert\Colors::hsb2rgb(360, 95, 78.0),
|
||||
'HSB to RGB with 360 hue'
|
||||
);
|
||||
|
||||
@@ -16,7 +16,7 @@ final class CoreLibsConvertJsonTest extends TestCase
|
||||
/**
|
||||
* test list for json convert tests
|
||||
*
|
||||
* @return array
|
||||
* @return array<mixed>
|
||||
*/
|
||||
public function jsonProvider(): array
|
||||
{
|
||||
@@ -54,10 +54,36 @@ final class CoreLibsConvertJsonTest extends TestCase
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @return array<mixed>
|
||||
*/
|
||||
public function jsonArrayProvider(): array
|
||||
{
|
||||
return [
|
||||
'valid json' => [
|
||||
[
|
||||
'm' => 2,
|
||||
'f' => 'sub_2'
|
||||
],
|
||||
'{"m":2,"f":"sub_2"}',
|
||||
],
|
||||
'empty json array' => [
|
||||
[],
|
||||
'[]'
|
||||
],
|
||||
'empty json hash' => [
|
||||
['' => ''],
|
||||
'{"":""}'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* json error list
|
||||
*
|
||||
* @return array JSON error list
|
||||
* @return array<mixed> JSON error list
|
||||
*/
|
||||
public function jsonErrorProvider(): array
|
||||
{
|
||||
@@ -127,7 +153,7 @@ final class CoreLibsConvertJsonTest extends TestCase
|
||||
*
|
||||
* @param string|null $input
|
||||
* @param bool $flag
|
||||
* @param array $expected
|
||||
* @param array<mixed> $expected
|
||||
* @return void
|
||||
*/
|
||||
public function testJsonConvertToArray(?string $input, bool $flag, array $expected): void
|
||||
@@ -146,7 +172,8 @@ final class CoreLibsConvertJsonTest extends TestCase
|
||||
* @testdox jsonGetLastError $input will be $expected_i/$expected_s [$_dataName]
|
||||
*
|
||||
* @param string|null $input
|
||||
* @param string $expected
|
||||
* @param int $expected_i
|
||||
* @param string $expected_s
|
||||
* @return void
|
||||
*/
|
||||
public function testJsonGetLastError(?string $input, int $expected_i, string $expected_s): void
|
||||
@@ -161,6 +188,25 @@ final class CoreLibsConvertJsonTest extends TestCase
|
||||
\CoreLibs\Convert\Json::jsonGetLastError(true)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @covers ::jsonConvertArrayTo
|
||||
* @dataProvider jsonArrayProvider
|
||||
* @testdox jsonConvertArrayTo $input (Override: $flag) will be $expected [$_dataName]
|
||||
*
|
||||
* @param array<mixed> $input
|
||||
* @param string $expected
|
||||
* @return void
|
||||
*/
|
||||
public function testJsonConvertArrayto(array $input, string $expected): void
|
||||
{
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
\CoreLibs\Convert\Json::jsonConvertArrayTo($input)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// __END__
|
||||
|
||||
@@ -43,12 +43,17 @@ final class CoreLibsConvertSetVarTypeNullTest extends TestCase
|
||||
'int, no override' => [
|
||||
1,
|
||||
null,
|
||||
null
|
||||
'1'
|
||||
],
|
||||
'int, override set' => [
|
||||
1,
|
||||
'not int',
|
||||
'not int'
|
||||
'1'
|
||||
],
|
||||
'array, override set' => [
|
||||
[1, 2],
|
||||
null,
|
||||
null
|
||||
]
|
||||
];
|
||||
}
|
||||
@@ -201,7 +206,7 @@ final class CoreLibsConvertSetVarTypeNullTest extends TestCase
|
||||
'float' => [
|
||||
1.5,
|
||||
null,
|
||||
null
|
||||
1
|
||||
]
|
||||
];
|
||||
}
|
||||
@@ -349,7 +354,7 @@ final class CoreLibsConvertSetVarTypeNullTest extends TestCase
|
||||
'int' => [
|
||||
1,
|
||||
null,
|
||||
null
|
||||
1.0
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
@@ -43,11 +43,16 @@ final class CoreLibsConvertSetVarTypeTest extends TestCase
|
||||
'int, no override' => [
|
||||
1,
|
||||
null,
|
||||
''
|
||||
'1'
|
||||
],
|
||||
'int, override set' => [
|
||||
1,
|
||||
'not int',
|
||||
'1'
|
||||
],
|
||||
'array, override set' => [
|
||||
[1, 2],
|
||||
'not int',
|
||||
'not int'
|
||||
]
|
||||
];
|
||||
@@ -189,7 +194,7 @@ final class CoreLibsConvertSetVarTypeTest extends TestCase
|
||||
'float' => [
|
||||
1.5,
|
||||
null,
|
||||
0
|
||||
1
|
||||
]
|
||||
];
|
||||
}
|
||||
@@ -330,7 +335,7 @@ final class CoreLibsConvertSetVarTypeTest extends TestCase
|
||||
'int' => [
|
||||
1,
|
||||
null,
|
||||
0.0
|
||||
1.0
|
||||
]
|
||||
];
|
||||
}
|
||||
@@ -341,7 +346,7 @@ final class CoreLibsConvertSetVarTypeTest extends TestCase
|
||||
* @dataProvider varSetTypeFloatProvider
|
||||
* @testdox setFloat $input with override $default will be $expected [$_dataName]
|
||||
*
|
||||
* @param mixed $input
|
||||
* @param mixed $input
|
||||
* @param float|null $default
|
||||
* @param float $expected
|
||||
* @return void
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -30,8 +30,10 @@ final class CoreLibsCreateSessionTest extends TestCase
|
||||
// setSessionName: true/false,
|
||||
// checkActiveSession: true/false, [1st call, 2nd call]
|
||||
// getSessionId: string or false
|
||||
// 3: exepcted name (session)
|
||||
// 4: expected error string
|
||||
// 3: exepcted name (session)]
|
||||
// 4: Exception thrown on error
|
||||
// 5: exception code, null for none
|
||||
// 6: expected error string
|
||||
return [
|
||||
'session parameter' => [
|
||||
'sessionNameParameter',
|
||||
@@ -44,7 +46,9 @@ final class CoreLibsCreateSessionTest extends TestCase
|
||||
'getSessionId' => '1234abcd4567'
|
||||
],
|
||||
'sessionNameParameter',
|
||||
''
|
||||
null,
|
||||
null,
|
||||
'',
|
||||
],
|
||||
'session globals' => [
|
||||
'sessionNameGlobals',
|
||||
@@ -57,7 +61,9 @@ final class CoreLibsCreateSessionTest extends TestCase
|
||||
'getSessionId' => '1234abcd4567'
|
||||
],
|
||||
'sessionNameGlobals',
|
||||
''
|
||||
null,
|
||||
null,
|
||||
'',
|
||||
],
|
||||
'session name default' => [
|
||||
'',
|
||||
@@ -70,7 +76,9 @@ final class CoreLibsCreateSessionTest extends TestCase
|
||||
'getSessionId' => '1234abcd4567'
|
||||
],
|
||||
'',
|
||||
''
|
||||
null,
|
||||
null,
|
||||
'',
|
||||
],
|
||||
// error checks
|
||||
// 1: we are in cli
|
||||
@@ -85,6 +93,8 @@ final class CoreLibsCreateSessionTest extends TestCase
|
||||
'getSessionId' => '1234abcd4567'
|
||||
],
|
||||
'',
|
||||
'RuntimeException',
|
||||
1,
|
||||
'[SESSION] No sessions in php cli'
|
||||
],
|
||||
// 2: session disabled
|
||||
@@ -99,6 +109,8 @@ final class CoreLibsCreateSessionTest extends TestCase
|
||||
'getSessionId' => '1234abcd4567'
|
||||
],
|
||||
'',
|
||||
'RuntimeException',
|
||||
2,
|
||||
'[SESSION] Sessions are disabled'
|
||||
],
|
||||
// 3: invalid session name: string
|
||||
@@ -113,6 +125,8 @@ final class CoreLibsCreateSessionTest extends TestCase
|
||||
'getSessionId' => '1234abcd4567'
|
||||
],
|
||||
'',
|
||||
'UnexpectedValueException',
|
||||
3,
|
||||
'[SESSION] Invalid session name: 1invalid$session#;'
|
||||
],
|
||||
// 3: invalid session name: only numbers
|
||||
@@ -127,6 +141,8 @@ final class CoreLibsCreateSessionTest extends TestCase
|
||||
'getSessionId' => '1234abcd4567'
|
||||
],
|
||||
'',
|
||||
'UnexpectedValueException',
|
||||
3,
|
||||
'[SESSION] Invalid session name: 123'
|
||||
],
|
||||
// 3: invalid session name: invalid name short
|
||||
@@ -143,6 +159,8 @@ final class CoreLibsCreateSessionTest extends TestCase
|
||||
'getSessionId' => '1234abcd4567'
|
||||
],
|
||||
'',
|
||||
'RuntimeException',
|
||||
4,
|
||||
'[SESSION] Failed to activate session'
|
||||
],
|
||||
// 5: get session id return false
|
||||
@@ -157,6 +175,8 @@ final class CoreLibsCreateSessionTest extends TestCase
|
||||
'getSessionId' => false
|
||||
],
|
||||
'',
|
||||
'UnexpectedValueException',
|
||||
5,
|
||||
'[SESSION] getSessionId did not return a session id'
|
||||
],
|
||||
];
|
||||
@@ -173,6 +193,7 @@ final class CoreLibsCreateSessionTest extends TestCase
|
||||
* @param string $type
|
||||
* @param array<mixed> $mock_data
|
||||
* @param string $expected
|
||||
* @param string|null $exception
|
||||
* @param string $expected_error
|
||||
* @return void
|
||||
*/
|
||||
@@ -181,6 +202,8 @@ final class CoreLibsCreateSessionTest extends TestCase
|
||||
string $type,
|
||||
array $mock_data,
|
||||
string $expected,
|
||||
?string $exception,
|
||||
?int $exception_code,
|
||||
string $expected_error
|
||||
): void {
|
||||
// override expected
|
||||
@@ -224,6 +247,11 @@ final class CoreLibsCreateSessionTest extends TestCase
|
||||
// regex for session id
|
||||
$ression_id_regex = "/^\w+$/";
|
||||
|
||||
if ($exception !== null) {
|
||||
$this->expectException($exception);
|
||||
$this->expectExceptionCode($exception_code);
|
||||
}
|
||||
|
||||
unset($GLOBALS['SET_SESSION_NAME']);
|
||||
$session_id = '';
|
||||
switch ($type) {
|
||||
@@ -253,13 +281,6 @@ final class CoreLibsCreateSessionTest extends TestCase
|
||||
$expected,
|
||||
$session_mock->getSessionName()
|
||||
);
|
||||
} else {
|
||||
// false checks
|
||||
$this->assertEquals(
|
||||
$expected_error,
|
||||
$session_mock->getErrorStr(),
|
||||
'error assert'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,45 +21,83 @@ final class CoreLibsCreateUidsTest extends TestCase
|
||||
public function uniqIdProvider(): array
|
||||
{
|
||||
return [
|
||||
// number length
|
||||
'too short' => [
|
||||
0 => 1,
|
||||
1 => 4,
|
||||
2 => null
|
||||
],
|
||||
'valid length: 10' => [
|
||||
0 => 10,
|
||||
1 => 10,
|
||||
2 => null
|
||||
],
|
||||
'valid length: 9, auto length' => [
|
||||
0 => 9,
|
||||
1 => 8,
|
||||
2 => null
|
||||
],
|
||||
'valid length: 9, force length' => [
|
||||
0 => 9,
|
||||
1 => 9,
|
||||
2 => true,
|
||||
],
|
||||
'very long: 512' => [
|
||||
0 => 512,
|
||||
1 => 512,
|
||||
2 => null
|
||||
],
|
||||
// below is all legacy
|
||||
'md5 hash' => [
|
||||
0 => 'md5',
|
||||
1 => 32,
|
||||
2 => null
|
||||
],
|
||||
'sha256 hash' => [
|
||||
0 => 'sha256',
|
||||
1 => 64
|
||||
1 => 64,
|
||||
2 => null
|
||||
],
|
||||
'ripemd160 hash' => [
|
||||
0 => 'ripemd160',
|
||||
1 => 40
|
||||
1 => 40,
|
||||
2 => null
|
||||
],
|
||||
'adler32 hash' => [
|
||||
0 => 'adler32',
|
||||
1 => 8
|
||||
1 => 8,
|
||||
2 => null
|
||||
],
|
||||
'not in list hash but valid' => [
|
||||
'not in list, set default length' => [
|
||||
0 => 'sha3-512',
|
||||
1 => strlen(hash('sha3-512', 'A'))
|
||||
1 => 64,
|
||||
2 => null
|
||||
],
|
||||
'default hash not set' => [
|
||||
0 => null,
|
||||
1 => 64,
|
||||
2 => null
|
||||
],
|
||||
'invalid name' => [
|
||||
0 => 'iamnotavalidhash',
|
||||
1 => 64,
|
||||
2 => null
|
||||
],
|
||||
'auto: ' . \CoreLibs\Create\Uids::DEFAULT_HASH => [
|
||||
0 => \CoreLibs\Create\Uids::DEFAULT_HASH,
|
||||
1 => strlen(hash(\CoreLibs\Create\Uids::DEFAULT_HASH, 'A'))
|
||||
// auto calls
|
||||
'auto: ' . \CoreLibs\Create\Uids::DEFAULT_UNNIQ_ID_LENGTH => [
|
||||
0 => \CoreLibs\Create\Uids::DEFAULT_UNNIQ_ID_LENGTH,
|
||||
1 => 64,
|
||||
2 => null
|
||||
],
|
||||
'auto: ' . \CoreLibs\Create\Uids::STANDARD_HASH_LONG => [
|
||||
0 => \CoreLibs\Create\Uids::STANDARD_HASH_LONG,
|
||||
1 => strlen(hash(\CoreLibs\Create\Uids::STANDARD_HASH_LONG, 'A'))
|
||||
1 => strlen(hash(\CoreLibs\Create\Uids::STANDARD_HASH_LONG, 'A')),
|
||||
2 => null
|
||||
],
|
||||
'auto: ' . \CoreLibs\Create\Uids::STANDARD_HASH_SHORT => [
|
||||
0 => \CoreLibs\Create\Uids::STANDARD_HASH_SHORT,
|
||||
1 => strlen(hash(\CoreLibs\Create\Uids::STANDARD_HASH_SHORT, 'A'))
|
||||
1 => strlen(hash(\CoreLibs\Create\Uids::STANDARD_HASH_SHORT, 'A')),
|
||||
2 => null
|
||||
],
|
||||
];
|
||||
}
|
||||
@@ -105,25 +143,26 @@ final class CoreLibsCreateUidsTest extends TestCase
|
||||
*
|
||||
* @covers ::uniqId
|
||||
* @dataProvider uniqIdProvider
|
||||
* @testdox uniqId $input will be length $expected [$_dataName]
|
||||
* @testdox uniqId $input will be length $expected (Force $flag) [$_dataName]
|
||||
*
|
||||
* @param string|null $input
|
||||
* @param int|string|null $input
|
||||
* @param string $expected
|
||||
* @param bool|null $flag
|
||||
* @return void
|
||||
*/
|
||||
public function testUniqId(?string $input, int $expected): void
|
||||
public function testUniqId(int|string|null $input, int $expected, ?bool $flag): void
|
||||
{
|
||||
if ($input === null) {
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
strlen(\CoreLibs\Create\Uids::uniqId())
|
||||
);
|
||||
$uniq_id_length = strlen(\CoreLibs\Create\Uids::uniqId());
|
||||
} elseif ($flag === null) {
|
||||
$uniq_id_length = strlen(\CoreLibs\Create\Uids::uniqId($input));
|
||||
} else {
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
strlen(\CoreLibs\Create\Uids::uniqId($input))
|
||||
);
|
||||
$uniq_id_length = strlen(\CoreLibs\Create\Uids::uniqId($input, $flag));
|
||||
}
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
$uniq_id_length
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
]);
|
||||
@@ -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,295 @@ 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 ["vendor/phpunit/phpunit/src/Framework/TestCase.php:"]
|
||||
* @testdox getCallerFileLine check based on regex /[\w\-\/]/vendor/phpunit/phpunit/src/Framework/TestCase.php:\d+ [$_dataName]
|
||||
*
|
||||
* @param string $expected
|
||||
* @return void
|
||||
*/
|
||||
public function testGetCallerFileLine(): void
|
||||
{
|
||||
// regex prefix with path "/../" and then fixed vendor + \d+
|
||||
$regex = "/^\/[\w\-\/]+\/vendor\/phpunit\/phpunit\/src\/Framework\/TestCase.php:\d+$/";
|
||||
$this->assertMatchesRegularExpression(
|
||||
$regex,
|
||||
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']
|
||||
// );
|
||||
array_splice(
|
||||
$expected,
|
||||
0,
|
||||
0,
|
||||
['include']
|
||||
);
|
||||
$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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* test the lowest one (one above base)
|
||||
*
|
||||
* @cover ::getCallerClass
|
||||
* @testWith ["tests\\CoreLibsDebugSupportTest"]
|
||||
* @testdox getCallerClass check if it returns $expected [$_dataName]
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetCallerClass(string $expected): void
|
||||
{
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
Support::getCallerClass()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* test highest return (top level)
|
||||
*
|
||||
* @cover ::getCallerTopLevelClass
|
||||
* @testWith ["PHPUnit\\TextUI\\Command"]
|
||||
* @testdox getCallerTopLevelClass check if it returns $expected [$_dataName]
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetCallerTopLevelClass(string $expected): void
|
||||
{
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
Support::getCallerTopLevelClass()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* test highest return (top level)
|
||||
*
|
||||
* @cover ::getCallerClassMethod
|
||||
* @testWith ["tests\\CoreLibsDebugSupportTest->testGetCallerClassMethod"]
|
||||
* @testdox getCallerClassMethod check if it returns $expected [$_dataName]
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetCallerClassMethod(string $expected): void
|
||||
{
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
Support::getCallerClassMethod()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
@@ -236,205 +657,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 +675,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'
|
||||
);
|
||||
}
|
||||
|
||||
@@ -67,17 +67,17 @@ final class CoreLibsGetSystemTest extends TestCase
|
||||
'original set' => [
|
||||
0 => null,
|
||||
1 => 'NOHOST',
|
||||
2 => 'NOPORT',
|
||||
2 => 0,
|
||||
],
|
||||
'override set no port' => [
|
||||
0 => 'foo.org',
|
||||
1 => 'foo.org',
|
||||
2 => '80'
|
||||
2 => 80
|
||||
],
|
||||
'override set with port' => [
|
||||
0 => 'foo.org:443',
|
||||
1 => 'foo.org',
|
||||
2 => '443'
|
||||
2 => 443
|
||||
]
|
||||
];
|
||||
}
|
||||
@@ -138,10 +138,10 @@ final class CoreLibsGetSystemTest extends TestCase
|
||||
*
|
||||
* @param string|null $input
|
||||
* @param string $expected_host
|
||||
* @param string $expected_port
|
||||
* @param int $expected_port
|
||||
* @return void
|
||||
*/
|
||||
public function testGetHostNanme(?string $input, string $expected_host, string $expected_port): void
|
||||
public function testGetHostNanme(?string $input, string $expected_host, int $expected_port): void
|
||||
{
|
||||
// print "HOSTNAME: " . $_SERVER['HTTP_HOST'] . "<br>";
|
||||
// print "SERVER: " . print_r($_SERVER, true) . "\n";
|
||||
|
||||
@@ -14,6 +14,13 @@ use PHPUnit\Framework\TestCase;
|
||||
*/
|
||||
final class CoreLibsLanguageGetLocaleTest extends TestCase
|
||||
{
|
||||
public const SITE_ENCODING = 'UTF-8';
|
||||
public const SITE_LOCALE = 'en_US.UTF-8';
|
||||
public const SITE_DOMAIN = 'admin';
|
||||
public const LOCALE_PATH = __DIR__ . DIRECTORY_SEPARATOR
|
||||
. 'includes' . DIRECTORY_SEPARATOR
|
||||
. 'locale' . DIRECTORY_SEPARATOR;
|
||||
|
||||
/**
|
||||
* set all constant variables that must be set before call
|
||||
*
|
||||
@@ -22,7 +29,7 @@ final class CoreLibsLanguageGetLocaleTest extends TestCase
|
||||
public static function setUpBeforeClass(): void
|
||||
{
|
||||
// default web page encoding setting
|
||||
if (!defined('DEFAULT_ENCODING')) {
|
||||
/* if (!defined('DEFAULT_ENCODING')) {
|
||||
define('DEFAULT_ENCODING', 'UTF-8');
|
||||
}
|
||||
if (!defined('DEFAULT_LOCALE')) {
|
||||
@@ -35,9 +42,9 @@ final class CoreLibsLanguageGetLocaleTest extends TestCase
|
||||
}
|
||||
if (!defined('SITE_LOCALE')) {
|
||||
define('SITE_LOCALE', DEFAULT_LOCALE);
|
||||
}
|
||||
} */
|
||||
// just set
|
||||
if (!defined('BASE')) {
|
||||
/* if (!defined('BASE')) {
|
||||
define('BASE', str_replace('/configs', '', __DIR__) . DIRECTORY_SEPARATOR);
|
||||
}
|
||||
if (!defined('INCLUDES')) {
|
||||
@@ -51,7 +58,7 @@ final class CoreLibsLanguageGetLocaleTest extends TestCase
|
||||
}
|
||||
if (!defined('CONTENT_PATH')) {
|
||||
define('CONTENT_PATH', 'frontend' . DIRECTORY_SEPARATOR);
|
||||
}
|
||||
} */
|
||||
// array session
|
||||
$_SESSION = [];
|
||||
global $_SESSION;
|
||||
@@ -62,7 +69,7 @@ final class CoreLibsLanguageGetLocaleTest extends TestCase
|
||||
*
|
||||
* @return array<mixed>
|
||||
*/
|
||||
public function setLocaleProvider(): array
|
||||
/* public function setLocaleProvider(): array
|
||||
{
|
||||
return [
|
||||
// 0: locale
|
||||
@@ -233,7 +240,7 @@ final class CoreLibsLanguageGetLocaleTest extends TestCase
|
||||
// TODO invalid params (bad path) (no override)
|
||||
// TODO param calls, but with override set
|
||||
];
|
||||
}
|
||||
} */
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
@@ -252,7 +259,7 @@ final class CoreLibsLanguageGetLocaleTest extends TestCase
|
||||
* @param string|null $deprecation_message
|
||||
* @return void
|
||||
*/
|
||||
public function testsetLocale(
|
||||
/* public function testsetLocale(
|
||||
?string $language,
|
||||
?string $domain,
|
||||
?string $encoding,
|
||||
@@ -347,6 +354,214 @@ final class CoreLibsLanguageGetLocaleTest extends TestCase
|
||||
// unset all vars
|
||||
$_SESSION = [];
|
||||
unset($GLOBALS['OVERRIDE_LANG']);
|
||||
} */
|
||||
|
||||
/**
|
||||
* all the test data
|
||||
*
|
||||
* @return array<mixed>
|
||||
*/
|
||||
public function setLocaleFromSessionProvider(): array
|
||||
{
|
||||
return [
|
||||
// 0: locale
|
||||
// 1: domain
|
||||
// 2: encoding
|
||||
// 3: path
|
||||
// 4: SESSION: DEFAULT_LOCALE
|
||||
// 5: SESSION: DEFAULT_CHARSET
|
||||
// 5: SESSION: DEFAULT_DOMAIN
|
||||
// 6: SESSION: LOCALE_PATH
|
||||
// 6: expected array
|
||||
// 7: deprecation message
|
||||
'all session vars set' => [
|
||||
// lang, domain, encoding, path
|
||||
self::SITE_LOCALE, self::SITE_DOMAIN, self::SITE_ENCODING, self::LOCALE_PATH,
|
||||
// SESSION SETTINGS: locale, charset, domain, path
|
||||
'ja_JP.UTF-8', 'UTF-8', 'admin', __DIR__ . '/locale_other/',
|
||||
// return array
|
||||
[
|
||||
'locale' => 'ja_JP.UTF-8',
|
||||
'lang' => 'ja_JP',
|
||||
'domain' => 'admin',
|
||||
'encoding' => 'UTF-8',
|
||||
'path' => "/^\/(.*\/)?locale_other\/$/",
|
||||
],
|
||||
],
|
||||
// param lang and domain (no override)
|
||||
'no session set, only parameters' => [
|
||||
// lang, domain, encoding, path
|
||||
self::SITE_LOCALE, self::SITE_DOMAIN, self::SITE_ENCODING, self::LOCALE_PATH,
|
||||
// SESSION SETTINGS: locale, charset, domain, path
|
||||
null, null, null, null,
|
||||
// return array
|
||||
[
|
||||
'locale' => 'en_US.UTF-8',
|
||||
'lang' => 'en_US',
|
||||
'domain' => 'admin',
|
||||
'encoding' => 'UTF-8',
|
||||
'path' => "/^\/(.*\/)?includes\/locale\/$/",
|
||||
],
|
||||
],
|
||||
// special parse session check for locales
|
||||
'all session vars set, short lang' => [
|
||||
// lang, domain, encoding, path
|
||||
self::SITE_LOCALE, self::SITE_DOMAIN, self::SITE_ENCODING, self::LOCALE_PATH,
|
||||
// SESSION SETTINGS: locale, charset, domain, path
|
||||
'ja', 'UTF-8', 'admin', __DIR__ . '/locale_other/',
|
||||
// return array
|
||||
[
|
||||
'locale' => 'ja',
|
||||
'lang' => 'ja',
|
||||
'domain' => 'admin',
|
||||
'encoding' => 'UTF-8',
|
||||
'path' => "/^\/(.*\/)?locale_other\/$/",
|
||||
],
|
||||
],
|
||||
// lang with modifier
|
||||
// param lang and domain (no override)
|
||||
'long locale, domain, encoding params, no sessions' => [
|
||||
// lang, domain, encoding, path
|
||||
self::SITE_LOCALE, self::SITE_DOMAIN, self::SITE_ENCODING, self::LOCALE_PATH,
|
||||
// SESSION SETTINGS: locale, charset, domain, path
|
||||
'de_CH.UTF-8@euro', 'admin', 'UTF-8', __DIR__ . '/includes/locale/',
|
||||
// return array
|
||||
[
|
||||
'locale' => 'de_CH.UTF-8@euro',
|
||||
'lang' => 'de_CH',
|
||||
'domain' => 'admin',
|
||||
'encoding' => 'UTF-8',
|
||||
'path' => "/^\/(.*\/)?includes\/locale\/$/",
|
||||
],
|
||||
],
|
||||
// missing session values check
|
||||
// special parse session check for locales
|
||||
'session missing encoding, set from parameters' => [
|
||||
// lang, domain, encoding, path
|
||||
self::SITE_LOCALE, self::SITE_DOMAIN, self::SITE_ENCODING, self::LOCALE_PATH,
|
||||
// SESSION SETTINGS: locale, charset, domain, path
|
||||
'ja', null, 'admin', __DIR__ . '/locale_other/',
|
||||
// return array
|
||||
[
|
||||
'locale' => 'ja',
|
||||
'lang' => 'ja',
|
||||
'domain' => 'admin',
|
||||
'encoding' => 'UTF-8',
|
||||
'path' => "/^\/(.*\/)?locale_other\/$/",
|
||||
],
|
||||
],
|
||||
// null return check for invalid entries
|
||||
'no session set, only parameters, all invalid' => [
|
||||
// lang, domain, encoding, path
|
||||
'###', '&&&&', '$$$$', 'foo_bar_path',
|
||||
// SESSION SETTINGS: locale, charset, domain, path
|
||||
null, null, null, null,
|
||||
// return array
|
||||
[
|
||||
'locale' => null,
|
||||
'lang' => null,
|
||||
'domain' => null,
|
||||
'encoding' => null,
|
||||
'path' => null,
|
||||
],
|
||||
],
|
||||
// invalid session names, fall backup
|
||||
'all session vars are invalid, fallback' => [
|
||||
// lang, domain, encoding, path
|
||||
self::SITE_LOCALE, self::SITE_DOMAIN, self::SITE_ENCODING, self::LOCALE_PATH,
|
||||
// SESSION SETTINGS: locale, charset, domain, path
|
||||
'###', '&&&&', '$$$$', 'foo_bar_path',
|
||||
// return array
|
||||
[
|
||||
'locale' => 'en_US.UTF-8',
|
||||
'lang' => 'en_US',
|
||||
'domain' => 'admin',
|
||||
'encoding' => 'UTF-8',
|
||||
'path' => "/^\/(.*\/)?includes\/locale\/$/",
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @covers ::setLocale
|
||||
* @dataProvider setLocaleFromSessionProvider
|
||||
* @testdox lang settings lang $language, domain $domain, encoding $encoding, path $path; session lang: $SESSION_DEFAULT_LOCALE, session char: $SESSION_DEFAULT_CHARSET [$_dataName]
|
||||
*
|
||||
* @param string| $language
|
||||
* @param string| $domain
|
||||
* @param string| $encoding
|
||||
* @param string| $path
|
||||
* @param string|null $SESSION_DEFAULT_LOCALE
|
||||
* @param string|null $SESSION_DEFAULT_CHARSET
|
||||
* @param string|null $SESSION_DEFAULT_DOMAIN
|
||||
* @param string|null $SESSION_LOCALE_PATH
|
||||
* @param array<mixed> $expected
|
||||
* @return void
|
||||
*/
|
||||
public function testsetLocaleFromSession(
|
||||
string $language,
|
||||
string $domain,
|
||||
string $encoding,
|
||||
string $path,
|
||||
?string $SESSION_DEFAULT_LOCALE,
|
||||
?string $SESSION_DEFAULT_CHARSET,
|
||||
?string $SESSION_DEFAULT_DOMAIN,
|
||||
?string $SESSION_LOCALE_PATH,
|
||||
array $expected,
|
||||
): void {
|
||||
$return_lang_settings = [];
|
||||
global $_SESSION;
|
||||
// set override
|
||||
if ($SESSION_DEFAULT_LOCALE !== null) {
|
||||
$_SESSION['DEFAULT_LOCALE'] = $SESSION_DEFAULT_LOCALE;
|
||||
}
|
||||
if ($SESSION_DEFAULT_CHARSET !== null) {
|
||||
$_SESSION['DEFAULT_CHARSET'] = $SESSION_DEFAULT_CHARSET;
|
||||
}
|
||||
if ($SESSION_DEFAULT_DOMAIN !== null) {
|
||||
$_SESSION['DEFAULT_DOMAIN'] = $SESSION_DEFAULT_DOMAIN;
|
||||
}
|
||||
if ($SESSION_LOCALE_PATH !== null) {
|
||||
$_SESSION['LOCALE_PATH'] = $SESSION_LOCALE_PATH;
|
||||
}
|
||||
$return_lang_settings = \CoreLibs\Language\GetLocale::setLocaleFromSession(
|
||||
$language,
|
||||
$domain,
|
||||
$encoding,
|
||||
$path
|
||||
);
|
||||
// print "RETURN: " . print_r($return_lang_settings, true) . "\n";
|
||||
foreach (
|
||||
[
|
||||
'locale', 'lang', 'domain', 'encoding', 'path'
|
||||
] as $key
|
||||
) {
|
||||
$value = $expected[$key];
|
||||
if (
|
||||
!empty($value) &&
|
||||
strpos($value, "/") === 0
|
||||
) {
|
||||
// this is regex
|
||||
$this->assertMatchesRegularExpression(
|
||||
$value,
|
||||
$return_lang_settings[$key] ?? '',
|
||||
'assert regex failed for ' . $key
|
||||
);
|
||||
} else {
|
||||
// assert equal
|
||||
$this->assertEquals(
|
||||
$value,
|
||||
$return_lang_settings[$key],
|
||||
'assert equal failed for ' . $key
|
||||
);
|
||||
}
|
||||
}
|
||||
// unset all vars
|
||||
$_SESSION = [];
|
||||
unset($GLOBALS['OVERRIDE_LANG']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -84,94 +84,141 @@ final class CoreLibsLanguageL10nTest extends TestCase
|
||||
{
|
||||
return [
|
||||
// 0: locale
|
||||
// 1: domain
|
||||
// 2: encoding
|
||||
// 1: encoding
|
||||
// 2: domain
|
||||
// 3: path
|
||||
// 4: locale expected
|
||||
// 5: locale set expected
|
||||
// 6: lang expected
|
||||
// 7: encoding expected
|
||||
// 8: domain exepcted
|
||||
// 9: context (null for none)
|
||||
// 10: test string in
|
||||
// 11: test translated
|
||||
// 12: deprecation message (until removed)
|
||||
// 7: lang short expected
|
||||
// 8: encoding expected
|
||||
// 9: domain exepcted
|
||||
// 10: context (null for none)
|
||||
// 11: test string in
|
||||
// 12: test translated
|
||||
// 13: deprecation message (until removed)
|
||||
// new style load
|
||||
'gettext load en' => [
|
||||
'en_US.UTF-8',
|
||||
'UTF-8',
|
||||
'frontend',
|
||||
__DIR__ . DIRECTORY_SEPARATOR . 'includes' . DIRECTORY_SEPARATOR . 'locale' . DIRECTORY_SEPARATOR,
|
||||
//
|
||||
// 4, 5, 6, 7, 8, 9
|
||||
'en_US.UTF-8',
|
||||
'en_US',
|
||||
'en_US',
|
||||
'en',
|
||||
'UTF-8',
|
||||
'frontend',
|
||||
// 10
|
||||
null,
|
||||
// 11, 12
|
||||
'Original',
|
||||
'Translated frontend en_US',
|
||||
// 13
|
||||
null,
|
||||
],
|
||||
'gettext load en' => [
|
||||
'en_US.UTF-8',
|
||||
'UTF-8',
|
||||
'frontend',
|
||||
__DIR__ . DIRECTORY_SEPARATOR . 'includes' . DIRECTORY_SEPARATOR . 'locale' . DIRECTORY_SEPARATOR,
|
||||
//
|
||||
'en_US.UTF-8',
|
||||
'en_US',
|
||||
'en_US',
|
||||
'en',
|
||||
'UTF-8',
|
||||
'frontend',
|
||||
//
|
||||
'context',
|
||||
//
|
||||
'Original',
|
||||
'Original context frontend en_US',
|
||||
//
|
||||
null,
|
||||
],
|
||||
'gettext load ja' => [
|
||||
'ja_JP.UTF-8',
|
||||
'UTF-8',
|
||||
'admin',
|
||||
__DIR__ . DIRECTORY_SEPARATOR . 'includes' . DIRECTORY_SEPARATOR . 'locale' . DIRECTORY_SEPARATOR,
|
||||
//
|
||||
'ja_JP.UTF-8',
|
||||
'ja_JP',
|
||||
'ja_JP',
|
||||
'ja',
|
||||
'UTF-8',
|
||||
'admin',
|
||||
//
|
||||
null,
|
||||
//
|
||||
'Original',
|
||||
'Translated admin ja_JP',
|
||||
//
|
||||
null,
|
||||
],
|
||||
// load short locale with different encoding
|
||||
'gettext load short ja no encoding' => [
|
||||
'ja',
|
||||
'SJIS',
|
||||
'admin',
|
||||
__DIR__ . DIRECTORY_SEPARATOR . 'includes' . DIRECTORY_SEPARATOR . 'locale' . DIRECTORY_SEPARATOR,
|
||||
//
|
||||
'ja',
|
||||
'ja',
|
||||
'ja',
|
||||
'ja',
|
||||
'SJIS',
|
||||
'admin',
|
||||
//
|
||||
null,
|
||||
//
|
||||
'Original',
|
||||
'Translated admin ja_JP',
|
||||
//
|
||||
null,
|
||||
],
|
||||
// mixed path and domain [DEPRECATED]
|
||||
'mixed path and domain [DEPRECATED]' => [
|
||||
'en_US.UTF-8',
|
||||
'UTF-8',
|
||||
__DIR__ . DIRECTORY_SEPARATOR . 'includes' . DIRECTORY_SEPARATOR . 'locale' . DIRECTORY_SEPARATOR,
|
||||
'frontend',
|
||||
//
|
||||
'en_US.UTF-8',
|
||||
'en_US',
|
||||
'en_US',
|
||||
'en',
|
||||
'UTF-8',
|
||||
'frontend',
|
||||
//
|
||||
'context',
|
||||
//
|
||||
'Original',
|
||||
'Original context frontend en_US',
|
||||
//
|
||||
'L10n constructor parameter switch is no longer supported. domain is 2nd, path is 3rd parameter'
|
||||
],
|
||||
// unset path
|
||||
'unset path with locale and domain [DEPRECATED]' => [
|
||||
'ja_JP.UTF-8',
|
||||
'UTF-8',
|
||||
'admin',
|
||||
null,
|
||||
//
|
||||
'ja_JP.UTF-8',
|
||||
'ja_JP',
|
||||
'ja_JP',
|
||||
'ja',
|
||||
'UTF-8',
|
||||
'admin',
|
||||
//
|
||||
null,
|
||||
//
|
||||
'Original',
|
||||
'Translated admin ja_JP',
|
||||
//
|
||||
'Empty path parameter is no longer allowed if locale and domain are set',
|
||||
],
|
||||
// null set
|
||||
@@ -179,15 +226,20 @@ final class CoreLibsLanguageL10nTest extends TestCase
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
//
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'', // unset on empty call
|
||||
'',
|
||||
//
|
||||
null,
|
||||
//
|
||||
'Original',
|
||||
'Original',
|
||||
//
|
||||
null,
|
||||
]
|
||||
];
|
||||
@@ -201,11 +253,13 @@ final class CoreLibsLanguageL10nTest extends TestCase
|
||||
* @testdox check l10n init with Locale $locale, Path $path, Domain $domain, Legacy: $legacy with $context [$_dataName]
|
||||
*
|
||||
* @param string|null $locale
|
||||
* @param string|null $encoding
|
||||
* @param string|null $domain
|
||||
* @param string|null $path
|
||||
* @param string $locale_expected
|
||||
* @param string $locale_set_expected
|
||||
* @param string $lang_expected
|
||||
* @param string $lang_short_expected
|
||||
* @param string $encoding_expected
|
||||
* @param string $domain_expected
|
||||
* @param string|null $context
|
||||
@@ -216,11 +270,13 @@ final class CoreLibsLanguageL10nTest extends TestCase
|
||||
*/
|
||||
public function testL10nObject(
|
||||
?string $locale,
|
||||
?string $encoding,
|
||||
?string $domain,
|
||||
?string $path,
|
||||
string $locale_expected,
|
||||
string $locale_set_expected,
|
||||
string $lang_expected,
|
||||
string $lang_short_expected,
|
||||
string $encoding_expected,
|
||||
string $domain_expected,
|
||||
?string $context,
|
||||
@@ -241,16 +297,18 @@ final class CoreLibsLanguageL10nTest extends TestCase
|
||||
if ($locale === null) {
|
||||
$l10n = new \CoreLibs\Language\L10n();
|
||||
} elseif ($domain === null) {
|
||||
// same as if locale is null
|
||||
// deprecated, locale + domain must be set, handled like empty calls
|
||||
$l10n = new \CoreLibs\Language\L10n($locale);
|
||||
} elseif ($path === null) {
|
||||
// deprecated, path must be set
|
||||
// deprecated, path must be set, will thow DEPRECATION error, handled like empty
|
||||
$l10n = new \CoreLibs\Language\L10n($locale, $domain);
|
||||
} else {
|
||||
} elseif ($encoding === null) {
|
||||
// if encoding not found will be UTF-8
|
||||
$l10n = new \CoreLibs\Language\L10n($locale, $domain, $path);
|
||||
} else {
|
||||
$l10n = new \CoreLibs\Language\L10n($locale, $domain, $path, $encoding);
|
||||
}
|
||||
restore_error_handler();
|
||||
// print "LOC: " . $locale . ", " . $l10n->getLocale() . ", " . $locale_expected . "\n";
|
||||
// print "MO: " . $l10n->getMoFile() . "\n";
|
||||
$this->assertEquals(
|
||||
$locale_expected,
|
||||
@@ -286,6 +344,7 @@ final class CoreLibsLanguageL10nTest extends TestCase
|
||||
[
|
||||
'locale' => $locale_expected,
|
||||
'lang' => $lang_expected,
|
||||
'lang_short' => $lang_short_expected,
|
||||
'domain' => $domain_expected,
|
||||
'encoding' => $encoding_expected,
|
||||
'path' => $path
|
||||
|
||||
1
4dev/tests/Language/includes/locale/ja
Symbolic link
1
4dev/tests/Language/includes/locale/ja
Symbolic link
@@ -0,0 +1 @@
|
||||
ja_JP
|
||||
349
4dev/tests/Logging/CoreLibsLoggingErrorMessagesTest.php
Normal file
349
4dev/tests/Logging/CoreLibsLoggingErrorMessagesTest.php
Normal file
@@ -0,0 +1,349 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace tests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use CoreLibs\Logging\Logger\Level;
|
||||
|
||||
/**
|
||||
* Test class for Logging
|
||||
* @coversDefaultClass \CoreLibs\Logging\ErrorMessages
|
||||
* @testdox \CoreLibs\Logging\ErrorMEssages method tests
|
||||
*/
|
||||
final class CoreLibsLoggingErrorMessagesTest extends TestCase
|
||||
{
|
||||
private const LOG_FOLDER = __DIR__ . DIRECTORY_SEPARATOR . 'log' . DIRECTORY_SEPARATOR;
|
||||
|
||||
/**
|
||||
* tear down and remove log data
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function tearDownAfterClass(): void
|
||||
{
|
||||
array_map('unlink', glob(self::LOG_FOLDER . '*.log'));
|
||||
}
|
||||
|
||||
/**
|
||||
* for checking level only
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function providerErrorMessageLevel(): array
|
||||
{
|
||||
return [
|
||||
'ok' => [
|
||||
'level' => 'ok',
|
||||
'str' => 'OK',
|
||||
'expected' => 'ok',
|
||||
],
|
||||
'info' => [
|
||||
'level' => 'info',
|
||||
'str' => 'INFO',
|
||||
'expected' => 'info',
|
||||
],
|
||||
'warn' => [
|
||||
'level' => 'warn',
|
||||
'str' => 'WARN',
|
||||
'expected' => 'warn'
|
||||
],
|
||||
'warning' => [
|
||||
'level' => 'warning',
|
||||
'str' => 'WARN',
|
||||
'expected' => 'warn'
|
||||
],
|
||||
'error' => [
|
||||
'level' => 'error',
|
||||
'str' => 'ERROR',
|
||||
'expected' => 'error'
|
||||
],
|
||||
'abort' => [
|
||||
'level' => 'abort',
|
||||
'str' => 'ABORT',
|
||||
'expected' => 'abort'
|
||||
],
|
||||
'crash' => [
|
||||
'level' => 'crash',
|
||||
'str' => 'CRASH',
|
||||
'expected' => 'crash'
|
||||
],
|
||||
'wrong level' => [
|
||||
'level' => 'wrong',
|
||||
'str' => 'WRONG',
|
||||
'expected' => 'unknown'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @dataProvider providerErrorMessageLevel
|
||||
* @testdox error message level: $level will be $expected [$_dataName]
|
||||
*
|
||||
* @param string $level
|
||||
* @param string $str
|
||||
* @param string $expected
|
||||
* @return void
|
||||
*/
|
||||
public function testErrorMessageLevelOk(string $level, string $str, string $expected): void
|
||||
{
|
||||
$log = new \CoreLibs\Logging\Logging([
|
||||
'log_file_id' => 'testErrorMessages',
|
||||
'log_folder' => self::LOG_FOLDER,
|
||||
'log_level' => Level::Debug,
|
||||
]);
|
||||
$em = new \CoreLibs\Logging\ErrorMessage($log);
|
||||
$em->setMessage(
|
||||
$level,
|
||||
$str
|
||||
);
|
||||
$this->assertEquals(
|
||||
[
|
||||
'level' => $expected,
|
||||
'str' => $str,
|
||||
'id' => '',
|
||||
'target' => '',
|
||||
'target_style' => '',
|
||||
'highlight' => [],
|
||||
],
|
||||
$em->getLastErrorMsg()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @testdox Test of all methods for n messages [$_dataName]
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testErrorMessageOk(): void
|
||||
{
|
||||
$log = new \CoreLibs\Logging\Logging([
|
||||
'log_file_id' => 'testErrorMessages',
|
||||
'log_folder' => self::LOG_FOLDER,
|
||||
'log_level' => Level::Debug
|
||||
]);
|
||||
$em = new \CoreLibs\Logging\ErrorMessage($log);
|
||||
$em->setErrorMsg(
|
||||
'100',
|
||||
'info',
|
||||
'INFO MESSAGE'
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
[
|
||||
'id' => '100',
|
||||
'level' => 'info',
|
||||
'str' => 'INFO MESSAGE',
|
||||
'target' => '',
|
||||
'target_style' => '',
|
||||
'highlight' => [],
|
||||
],
|
||||
$em->getLastErrorMsg()
|
||||
);
|
||||
$this->assertEquals(
|
||||
['100'],
|
||||
$em->getErrorIds()
|
||||
);
|
||||
$this->assertEquals(
|
||||
[
|
||||
[
|
||||
'id' => '100',
|
||||
'level' => 'info',
|
||||
'str' => 'INFO MESSAGE',
|
||||
'target' => '',
|
||||
'target_style' => '',
|
||||
'highlight' => [],
|
||||
]
|
||||
],
|
||||
$em->getErrorMsg()
|
||||
);
|
||||
|
||||
$em->setErrorMsg(
|
||||
'200',
|
||||
'error',
|
||||
'ERROR MESSAGE'
|
||||
);
|
||||
$this->assertEquals(
|
||||
[
|
||||
'id' => '200',
|
||||
'level' => 'error',
|
||||
'str' => 'ERROR MESSAGE',
|
||||
'target' => '',
|
||||
'target_style' => '',
|
||||
'highlight' => [],
|
||||
],
|
||||
$em->getLastErrorMsg()
|
||||
);
|
||||
$this->assertEquals(
|
||||
['100', '200'],
|
||||
$em->getErrorIds()
|
||||
);
|
||||
$this->assertEquals(
|
||||
[
|
||||
[
|
||||
'id' => '100',
|
||||
'level' => 'info',
|
||||
'str' => 'INFO MESSAGE',
|
||||
'target' => '',
|
||||
'target_style' => '',
|
||||
'highlight' => [],
|
||||
],
|
||||
[
|
||||
'id' => '200',
|
||||
'level' => 'error',
|
||||
'str' => 'ERROR MESSAGE',
|
||||
'target' => '',
|
||||
'target_style' => '',
|
||||
'highlight' => [],
|
||||
]
|
||||
],
|
||||
$em->getErrorMsg()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function providerErrorMessageLog(): array
|
||||
{
|
||||
return [
|
||||
'error, not logged' => [
|
||||
'id' => '200',
|
||||
'level' => 'error',
|
||||
'str' => 'ERROR MESSAGE',
|
||||
'message' => null,
|
||||
'log_error' => null,
|
||||
'expected' => '<ERROR> ERROR MESSAGE',
|
||||
],
|
||||
'error, logged' => [
|
||||
'id' => '200',
|
||||
'level' => 'error',
|
||||
'str' => 'ERROR MESSAGE',
|
||||
'message' => null,
|
||||
'log_error' => true,
|
||||
'expected' => '<ERROR> ERROR MESSAGE',
|
||||
],
|
||||
'error, logged, message' => [
|
||||
'id' => '200',
|
||||
'level' => 'error',
|
||||
'str' => 'ERROR MESSAGE',
|
||||
'message' => 'OTHER ERROR MESSAGE',
|
||||
'log_error' => true,
|
||||
'expected' => '<ERROR> OTHER ERROR MESSAGE',
|
||||
],
|
||||
'crash' => [
|
||||
'id' => '300',
|
||||
'level' => 'crash',
|
||||
'str' => 'CRASH MESSAGE',
|
||||
'message' => null,
|
||||
'log_error' => null,
|
||||
'expected' => '<ALERT> CRASH MESSAGE',
|
||||
],
|
||||
'crash, message' => [
|
||||
'id' => '300',
|
||||
'level' => 'crash',
|
||||
'str' => 'CRASH MESSAGE',
|
||||
'message' => 'OTHER CRASH MESSAGE',
|
||||
'log_error' => null,
|
||||
'expected' => '<ALERT> OTHER CRASH MESSAGE',
|
||||
],
|
||||
'abort' => [
|
||||
'id' => '200',
|
||||
'level' => 'abort',
|
||||
'str' => 'ABORT MESSAGE',
|
||||
'message' => null,
|
||||
'log_error' => null,
|
||||
'expected' => '<CRITICAL> ABORT MESSAGE',
|
||||
],
|
||||
'abort, message' => [
|
||||
'id' => '200',
|
||||
'level' => 'abort',
|
||||
'str' => 'ABORT MESSAGE',
|
||||
'message' => 'OTHER ABORT MESSAGE',
|
||||
'log_error' => null,
|
||||
'expected' => '<CRITICAL> OTHER ABORT MESSAGE',
|
||||
],
|
||||
'unknown' => [
|
||||
'id' => '400',
|
||||
'level' => 'wrong level',
|
||||
'str' => 'WRONG LEVEL MESSAGE',
|
||||
'message' => null,
|
||||
'log_error' => null,
|
||||
'expected' => '<EMERGENCY> WRONG LEVEL MESSAGE',
|
||||
],
|
||||
'unknown, message' => [
|
||||
'id' => '400',
|
||||
'level' => 'wrong level',
|
||||
'str' => 'WRONG LEVEL MESSAGE',
|
||||
'message' => 'OTHER WRONG LEVEL MESSAGE',
|
||||
'log_error' => null,
|
||||
'expected' => '<EMERGENCY> OTHER WRONG LEVEL MESSAGE',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @dataProvider providerErrorMessageLog
|
||||
* @testdox Test Log writing [$_dataName]
|
||||
*
|
||||
* @param string $id
|
||||
* @param string $level
|
||||
* @param string $str
|
||||
* @param string|null $message
|
||||
* @param bool|null $log_error
|
||||
* @param string $expected
|
||||
* @return void
|
||||
*/
|
||||
public function testErrorMessageLog(
|
||||
string $id,
|
||||
string $level,
|
||||
string $str,
|
||||
?string $message,
|
||||
?bool $log_error,
|
||||
string $expected
|
||||
): void {
|
||||
$log = new \CoreLibs\Logging\Logging([
|
||||
'log_file_id' => 'testErrorMessages',
|
||||
'log_folder' => self::LOG_FOLDER,
|
||||
'log_level' => Level::Debug,
|
||||
'log_per_run' => true
|
||||
]);
|
||||
$em = new \CoreLibs\Logging\ErrorMessage($log);
|
||||
$em->setErrorMsg(
|
||||
$id,
|
||||
$level,
|
||||
$str,
|
||||
message: $message,
|
||||
log_error: $log_error
|
||||
);
|
||||
$file_content = '';
|
||||
if (is_file($log->getLogFolder() . $log->getLogFile())) {
|
||||
$file_content = file_get_contents(
|
||||
$log->getLogFolder() . $log->getLogFile()
|
||||
) ?: '';
|
||||
}
|
||||
// if n
|
||||
if ($level == 'error' && ($log_error === null || $log_error === false)) {
|
||||
$this->assertStringNotContainsString(
|
||||
$expected,
|
||||
$file_content
|
||||
);
|
||||
} else {
|
||||
$this->assertStringContainsString(
|
||||
$expected,
|
||||
$file_content
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// __END__
|
||||
847
4dev/tests/Logging/CoreLibsLoggingLoggingTest.php
Normal file
847
4dev/tests/Logging/CoreLibsLoggingLoggingTest.php
Normal file
@@ -0,0 +1,847 @@
|
||||
<?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\.]+(:\d+)?\]\s{1}" // host:port
|
||||
. "\[[\w\-\.\/]+:\d+\]\s{1}" // folder/file
|
||||
. "\[\w+\]\s{1}" // run id
|
||||
. "{[\w\\\\]+((::|->)\w+)?}\s{1}"; // class
|
||||
|
||||
public static function tearDownAfterClass(): void
|
||||
{
|
||||
array_map('unlink', glob(self::LOG_FOLDER . '*.log'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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-0_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
|
||||
// loggingLevelIsDebug
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @covers ::setLoggingLevel
|
||||
* @covers ::getLoggingLevel
|
||||
* @covers ::loggingLevelIsDebug
|
||||
* @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->loggingLevelIsDebug()
|
||||
);
|
||||
// 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->loggingLevelIsDebug()
|
||||
);
|
||||
// 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->loggingLevelIsDebug()
|
||||
);
|
||||
// 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:0]
|
||||
// [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
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
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'
|
||||
);
|
||||
}
|
||||
|
||||
// check log level that writer writes in correct level
|
||||
// also that non debug ignores prefix/group
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @covers ::log
|
||||
* @testdox log() general call test
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testLoggingLog(): void
|
||||
{
|
||||
// init logger
|
||||
$log = new \CoreLibs\Logging\Logging([
|
||||
'log_file_id' => 'testLoggingLog',
|
||||
'log_folder' => self::LOG_FOLDER,
|
||||
'log_per_level' => true,
|
||||
]);
|
||||
$log_ok = $log->log(Level::Debug, 'DEBUG', group_id: 'GROUP_ID', prefix: 'PREFIX:');
|
||||
$this->assertTrue($log_ok, 'assert ::log (debug) OK');
|
||||
$this->assertEquals(
|
||||
$log->getLogFile(),
|
||||
$log->getLogFileId() . '_DEBUG.log'
|
||||
);
|
||||
$log_ok = $log->log(Level::Info, 'INFO', group_id: 'GROUP_ID', prefix: 'PREFIX:');
|
||||
$this->assertTrue($log_ok, 'assert ::log (info) OK');
|
||||
$this->assertEquals(
|
||||
$log->getLogFile(),
|
||||
$log->getLogFileId() . '_INFO.log'
|
||||
);
|
||||
}
|
||||
|
||||
// must test flow:
|
||||
// init normal
|
||||
// log -> check file name
|
||||
// set per date
|
||||
// log -> check file name
|
||||
// and same for per_run
|
||||
|
||||
// deprecated calls check?
|
||||
}
|
||||
|
||||
// __END__
|
||||
3
4dev/tests/Logging/log/.gitignore
vendored
Normal file
3
4dev/tests/Logging/log/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
*log
|
||||
*LOG
|
||||
!.gitignore
|
||||
@@ -7,11 +7,11 @@ namespace tests;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* Test class for Check\Password
|
||||
* @coversDefaultClass \CoreLibs\Check\Password
|
||||
* @testdox \CoreLibs\Check\Password method tests
|
||||
* Test class for Security\Password
|
||||
* @coversDefaultClass \CoreLibs\Security\Password
|
||||
* @testdox \CoreLibs\Security\Password method tests
|
||||
*/
|
||||
final class CoreLibsCheckPasswordTest extends TestCase
|
||||
final class CoreLibsSecurityPasswordTest extends TestCase
|
||||
{
|
||||
public function passwordProvider(): array
|
||||
{
|
||||
@@ -46,7 +46,7 @@ final class CoreLibsCheckPasswordTest extends TestCase
|
||||
{
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
\CoreLibs\Check\Password::passwordVerify($input, \CoreLibs\Check\Password::passwordSet($input_hash))
|
||||
\CoreLibs\Security\Password::passwordVerify($input, \CoreLibs\Security\Password::passwordSet($input_hash))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ final class CoreLibsCheckPasswordTest extends TestCase
|
||||
{
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
\CoreLibs\Check\Password::passwordRehashCheck($input)
|
||||
\CoreLibs\Security\Password::passwordRehashCheck($input)
|
||||
);
|
||||
}
|
||||
}
|
||||
172
4dev/tests/Security/CoreLibsSecuritySymmetricEncryptionTest.php
Normal file
172
4dev/tests/Security/CoreLibsSecuritySymmetricEncryptionTest.php
Normal file
@@ -0,0 +1,172 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace tests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use CoreLibs\Security\CreateKey;
|
||||
use CoreLibs\Security\SymmetricEncryption;
|
||||
|
||||
/**
|
||||
* Test class for Security\SymmetricEncryption and Security\CreateKey
|
||||
* @coversDefaultClass \CoreLibs\Security\SymmetricEncryption
|
||||
* @testdox \CoreLibs\Security\SymmetricEncryption method tests
|
||||
*/
|
||||
final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function providerEncryptDecryptSuccess(): array
|
||||
{
|
||||
return [
|
||||
'valid string' => [
|
||||
'input' => 'I am a secret',
|
||||
'expected' => 'I am a secret',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* test encrypt/decrypt produce correct output
|
||||
*
|
||||
* @covers ::generateRandomKey
|
||||
* @covers ::encrypt
|
||||
* @covers ::decrypt
|
||||
* @dataProvider providerEncryptDecryptSuccess
|
||||
* @testdox encrypt/decrypt $input must be $expected [$_dataName]
|
||||
*
|
||||
* @param string $input
|
||||
* @param string $expected
|
||||
* @return void
|
||||
*/
|
||||
public function testEncryptDecryptSuccess(string $input, string $expected): void
|
||||
{
|
||||
$key = CreateKey::generateRandomKey();
|
||||
$encrypted = SymmetricEncryption::encrypt($input, $key);
|
||||
$decrypted = SymmetricEncryption::decrypt($encrypted, $key);
|
||||
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
$decrypted
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function providerEncryptFailed(): array
|
||||
{
|
||||
return [
|
||||
'wrong decryption key' => [
|
||||
'input' => 'I am a secret',
|
||||
'excpetion_message' => 'Invalid Key'
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test decryption with wrong key
|
||||
*
|
||||
* @covers ::generateRandomKey
|
||||
* @covers ::encrypt
|
||||
* @covers ::decrypt
|
||||
* @dataProvider providerEncryptFailed
|
||||
* @testdox decrypt with wrong key $input throws $exception_message [$_dataName]
|
||||
*
|
||||
* @param string $input
|
||||
* @param string $exception_message
|
||||
* @return void
|
||||
*/
|
||||
public function testEncryptFailed(string $input, string $exception_message): void
|
||||
{
|
||||
$key = CreateKey::generateRandomKey();
|
||||
$encrypted = SymmetricEncryption::encrypt($input, $key);
|
||||
$wrong_key = CreateKey::generateRandomKey();
|
||||
$this->expectExceptionMessage($exception_message);
|
||||
SymmetricEncryption::decrypt($encrypted, $wrong_key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function providerWrongKey(): array
|
||||
{
|
||||
return [
|
||||
'not hex key' => [
|
||||
'key' => 'not_a_hex_key',
|
||||
'exception_message' => 'Invalid hex key'
|
||||
],
|
||||
'too short hex key' => [
|
||||
'key' => '1cabd5cba9e042f12522f4ff2de5c31d233b',
|
||||
'excpetion_message' => 'Key is not the correct size (must be '
|
||||
. 'SODIUM_CRYPTO_SECRETBOX_KEYBYTES bytes long).'
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* test invalid key provided to decrypt or encrypt
|
||||
*
|
||||
* @covers ::encrypt
|
||||
* @covers ::decrypt
|
||||
* @dataProvider providerWrongKey
|
||||
* @testdox wrong key $key throws $exception_message [$_dataName]
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $exception_message
|
||||
* @return void
|
||||
*/
|
||||
public function testWrongKey(string $key, string $exception_message): void
|
||||
{
|
||||
$this->expectExceptionMessage($exception_message);
|
||||
SymmetricEncryption::encrypt('test', $key);
|
||||
// we must encrypt valid thing first so we can fail with the wrong kjey
|
||||
$enc_key = CreateKey::generateRandomKey();
|
||||
$encrypted = SymmetricEncryption::encrypt('test', $enc_key);
|
||||
$this->expectExceptionMessage($exception_message);
|
||||
SymmetricEncryption::decrypt($encrypted, $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function providerWrongCiphertext(): array
|
||||
{
|
||||
return [
|
||||
'too short ciphertext' => [
|
||||
'input' => 'short',
|
||||
'exception_message' => 'Invalid ciphertext (too short)'
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @covers ::decrypt
|
||||
* @dataProvider providerWrongCiphertext
|
||||
* @testdox too short ciphertext $input throws $exception_message [$_dataName]
|
||||
*
|
||||
* @param string $input
|
||||
* @param string $exception_message
|
||||
* @return void
|
||||
*/
|
||||
public function testWrongCiphertext(string $input, string $exception_message): void
|
||||
{
|
||||
$key = CreateKey::generateRandomKey();
|
||||
$this->expectExceptionMessage($exception_message);
|
||||
SymmetricEncryption::decrypt($input, $key);
|
||||
}
|
||||
}
|
||||
|
||||
// __END__
|
||||
34
4dev/tests/Template/CoreLibsTemplateHtmlBuilderBlockTest.php
Normal file
34
4dev/tests/Template/CoreLibsTemplateHtmlBuilderBlockTest.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace tests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use CoreLibs\Template\HtmlBuilder\Block;
|
||||
|
||||
/**
|
||||
* Test class for Template\HtmlBuilder\Block
|
||||
* @coversDefaultClass \CoreLibs\Template\HtmlBuilder\Block
|
||||
* @testdox \CoreLibs\Template\HtmlBuilder\Block method tests
|
||||
*/
|
||||
final class CoreLibsTemplateHtmlBuilderBlockTest extends TestCase
|
||||
{
|
||||
public function testCreateBlock(): void
|
||||
{
|
||||
$el = Block::cel('div', 'id', 'content', ['css'], ['onclick' => 'foo();']);
|
||||
$this->assertEquals(
|
||||
'<div id="id" class="css" onclick="foo();">content</div>',
|
||||
Block::buildHtml($el)
|
||||
);
|
||||
}
|
||||
|
||||
// ael
|
||||
// aelx|addSub
|
||||
// resetSub
|
||||
// acssel/rcssel/scssel
|
||||
// buildHtml
|
||||
// buildHtmlFromList|printHtmlFromArray
|
||||
}
|
||||
|
||||
// __END__
|
||||
546
4dev/tests/Template/CoreLibsTemplateHtmlBuilderElementTest.php
Normal file
546
4dev/tests/Template/CoreLibsTemplateHtmlBuilderElementTest.php
Normal file
@@ -0,0 +1,546 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace tests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use CoreLibs\Template\HtmlBuilder\Element;
|
||||
use CoreLibs\Template\HtmlBuilder\General\Error;
|
||||
use CoreLibs\Template\HtmlBuilder\General\HtmlBuilderExcpetion;
|
||||
|
||||
/**
|
||||
* Test class for Template\HtmlBuilder\Element
|
||||
* @coversDefaultClass \CoreLibs\Template\HtmlBuilder\Element
|
||||
* @testdox \CoreLibs\Template\HtmlBuilder\Element method tests
|
||||
*/
|
||||
final class CoreLibsTemplateHtmlBuilderElementTest extends TestCase
|
||||
{
|
||||
public function providerCreateElements(): array
|
||||
{
|
||||
return [
|
||||
'simple div' => [
|
||||
'tag' => 'div',
|
||||
'id' => 'id',
|
||||
'content' => 'content',
|
||||
'css' => ['css'],
|
||||
'options' => ['onclick' => 'foo();'],
|
||||
'expected' => '<div id="id" class="css" onclick="foo();">content</div>'
|
||||
],
|
||||
'simple input' => [
|
||||
'tag' => 'input',
|
||||
'id' => 'id',
|
||||
'content' => null,
|
||||
'css' => ['css'],
|
||||
'options' => ['name' => 'name', 'onclick' => 'foo();'],
|
||||
'expected' => '<input id="id" name="name" class="css" onclick="foo();">'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @covers ::Element
|
||||
* @covers ::buildHtml
|
||||
* @covers ::getTag
|
||||
* @covers ::getId
|
||||
* @covers ::getContent
|
||||
* @covers ::getOptions
|
||||
* @covers ::getCss
|
||||
* @dataProvider providerCreateElements
|
||||
* @testdox create single new Element test [$_dataName]
|
||||
*
|
||||
* @param string $tag
|
||||
* @param string|null $id
|
||||
* @param string|null $content
|
||||
* @param array|null $css
|
||||
* @param array|null $options
|
||||
* @param string $expected
|
||||
* @return void
|
||||
*/
|
||||
public function testCreateElement(
|
||||
string $tag,
|
||||
?string $id,
|
||||
?string $content,
|
||||
?array $css,
|
||||
?array $options,
|
||||
string $expected
|
||||
): void {
|
||||
$el = new Element($tag, $id ?? '', $content ?? '', $css ?? [], $options ?? []);
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
$el->buildHtml(),
|
||||
'element creation failed'
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
$tag,
|
||||
$el->getTag(),
|
||||
'get tag failed'
|
||||
);
|
||||
|
||||
if ($id !== null) {
|
||||
$this->assertEquals(
|
||||
$id,
|
||||
$el->getId(),
|
||||
'get id failed'
|
||||
);
|
||||
}
|
||||
if ($content !== null) {
|
||||
$this->assertEquals(
|
||||
$content,
|
||||
$el->getContent(),
|
||||
'get content failed'
|
||||
);
|
||||
}
|
||||
if ($css !== null) {
|
||||
$this->assertEquals(
|
||||
$css,
|
||||
$el->getCss(),
|
||||
'get css failed'
|
||||
);
|
||||
}
|
||||
if ($options !== null) {
|
||||
$this->assertEquals(
|
||||
$options,
|
||||
$el->getOptions(),
|
||||
'get options failed'
|
||||
);
|
||||
}
|
||||
if (!empty($options['name'])) {
|
||||
$this->assertEquals(
|
||||
$options['name'],
|
||||
$el->getName(),
|
||||
'get name failed'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* css add/remove
|
||||
*
|
||||
* @cover ::getCss
|
||||
* @cover ::addCss
|
||||
* @cover ::removeCss
|
||||
* @testdox test handling of adding and removing css classes
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCssHandling(): void
|
||||
{
|
||||
$el = new Element('div', 'css-test', 'CSS content');
|
||||
$this->assertEqualsCanonicalizing(
|
||||
[],
|
||||
$el->getCss(),
|
||||
'check empty css'
|
||||
);
|
||||
$el->addCss('foo');
|
||||
$this->assertEqualsCanonicalizing(
|
||||
['foo'],
|
||||
$el->getCss(),
|
||||
'check added one css'
|
||||
);
|
||||
$el->removeCss('foo');
|
||||
$this->assertEqualsCanonicalizing(
|
||||
[],
|
||||
$el->getCss(),
|
||||
'check remove added css'
|
||||
);
|
||||
// add serveral
|
||||
// remove some of them
|
||||
$el->addCss('a', 'b', 'c');
|
||||
$this->assertEqualsCanonicalizing(
|
||||
['a', 'b', 'c'],
|
||||
$el->getCss(),
|
||||
'check added some css'
|
||||
);
|
||||
$el->removeCss('a', 'c');
|
||||
// $this->assertArray
|
||||
$this->assertEqualsCanonicalizing(
|
||||
['b'],
|
||||
$el->getCss(),
|
||||
'check remove some css'
|
||||
);
|
||||
// chained add and remove
|
||||
$el->addCss('a', 'b', 'c', 'd')->removeCss('b', 'd');
|
||||
$this->assertEqualsCanonicalizing(
|
||||
['a', 'c'],
|
||||
$el->getCss(),
|
||||
'check chain add remove some css'
|
||||
);
|
||||
$el->resetCss();
|
||||
$this->assertEqualsCanonicalizing(
|
||||
[],
|
||||
$el->getCss(),
|
||||
'check reset css'
|
||||
);
|
||||
// remove something that does not eixst
|
||||
$el->addCss('exists');
|
||||
$el->removeCss('not');
|
||||
$this->assertEqualsCanonicalizing(
|
||||
['exists'],
|
||||
$el->getCss(),
|
||||
'check remove not exitsing'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* nested test
|
||||
*
|
||||
* @testdox nested test and loop assign detection
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testBuildNested(): void
|
||||
{
|
||||
Error::resetMessages();
|
||||
$el = new Element('div', 'build-test');
|
||||
$el_sub = new Element('div', 'sub-1');
|
||||
$el->addSub($el_sub);
|
||||
$this->assertEquals(
|
||||
'<div id="build-test"><div id="sub-1"></div></div>',
|
||||
$el->buildHtml(),
|
||||
'nested build failed'
|
||||
);
|
||||
// this would create a loop, throws error
|
||||
$this->expectException(HtmlBuilderExcpetion::class);
|
||||
$this->expectExceptionMessage("Cannot assign Element to itself, this would create an infinite loop");
|
||||
$el_sub->addSub($el_sub);
|
||||
$this->assertEquals(
|
||||
'<div id="sub-1"></div>',
|
||||
$el_sub->buildHtml(),
|
||||
'loop detection failed'
|
||||
);
|
||||
$this->assertTrue(
|
||||
Error::hasError(),
|
||||
'failed to throw error post loop detection'
|
||||
);
|
||||
$this->assertEquals(
|
||||
[[
|
||||
'level' => 'Error',
|
||||
'id' => '100',
|
||||
'message' => 'Cannot assign Element to itself, this would create an infinite loop',
|
||||
'context' => ['tag' => 'div', 'id' => 'sub-1']
|
||||
]],
|
||||
Error::getMessages(),
|
||||
'check error is 100 failed'
|
||||
);
|
||||
// get sub
|
||||
$this->assertEquals(
|
||||
[$el_sub],
|
||||
$el->getSub(),
|
||||
'get sub failed'
|
||||
);
|
||||
// reset sub
|
||||
$el->resetSub();
|
||||
$this->assertEquals(
|
||||
[],
|
||||
$el->getSub(),
|
||||
'reset sub failed'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @testdox updated nested connection
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testNestedChangeContent(): void
|
||||
{
|
||||
$el = new Element('div', 'build-test');
|
||||
$el_s_1 = new Element('div', 'sub-1');
|
||||
$el_s_2 = new Element('div', 'sub-2');
|
||||
$el_s_3 = new Element('div', 'sub-3');
|
||||
$el_s_4 = new Element('div', 'sub-4');
|
||||
|
||||
$el->addSub($el_s_1, $el_s_2);
|
||||
// only sub -1, -2
|
||||
$this->assertEquals(
|
||||
'<div id="build-test"><div id="sub-1"></div><div id="sub-2"></div></div>',
|
||||
$el->buildHtml(),
|
||||
'check basic nested'
|
||||
);
|
||||
|
||||
// now add -3, -4 to both -1 and -2
|
||||
$el_s_1->addSub($el_s_3, $el_s_4);
|
||||
$el_s_2->addSub($el_s_3, $el_s_4);
|
||||
$this->assertEquals(
|
||||
'<div id="build-test"><div id="sub-1"><div id="sub-3"></div><div id="sub-4">'
|
||||
. '</div></div><div id="sub-2"><div id="sub-3"></div><div id="sub-4"></div>'
|
||||
. '</div></div>',
|
||||
$el->buildHtml(),
|
||||
'check nested added'
|
||||
);
|
||||
|
||||
// now add some css to el_s_3, will update in both sets
|
||||
$el_s_3->addCss('red');
|
||||
$this->assertEquals(
|
||||
'<div id="build-test"><div id="sub-1"><div id="sub-3" class="red"></div><div id="sub-4">'
|
||||
. '</div></div><div id="sub-2"><div id="sub-3" class="red"></div><div id="sub-4"></div>'
|
||||
. '</div></div>',
|
||||
$el->buildHtml(),
|
||||
'check nested u@dated'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @testdox test change tag/id/content
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testChangeElementData(): void
|
||||
{
|
||||
$el = new Element('div', 'id', 'Content');
|
||||
// content change
|
||||
$this->assertEquals(
|
||||
'Content',
|
||||
$el->getContent(),
|
||||
'set content'
|
||||
);
|
||||
$el->setContent('New Content');
|
||||
$this->assertEquals(
|
||||
'New Content',
|
||||
$el->getContent(),
|
||||
'changed content'
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
'div',
|
||||
$el->getTag(),
|
||||
'set tag'
|
||||
);
|
||||
$el->setTag('span');
|
||||
$this->assertEquals(
|
||||
'span',
|
||||
$el->getTag(),
|
||||
'changed tag'
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
'id',
|
||||
$el->getId(),
|
||||
'set id'
|
||||
);
|
||||
$el->setId('id-2');
|
||||
$this->assertEquals(
|
||||
'id-2',
|
||||
$el->getId(),
|
||||
'changed id'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @testdox test change options
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testChangeOptions(): void
|
||||
{
|
||||
$el = new Element('button', 'id', 'Action', ['css'], ['value' => '3']);
|
||||
$this->assertEquals(
|
||||
['value' => '3'],
|
||||
$el->getOptions(),
|
||||
'set option'
|
||||
);
|
||||
$el->setOptions([
|
||||
'value' => '2'
|
||||
]);
|
||||
$this->assertEquals(
|
||||
['value' => '2'],
|
||||
$el->getOptions(),
|
||||
'changed option'
|
||||
);
|
||||
// add a new one
|
||||
$el->setOptions([
|
||||
'Foo' => 'bar',
|
||||
'Moo' => 'cow'
|
||||
]);
|
||||
$this->assertEquals(
|
||||
[
|
||||
'value' => '2',
|
||||
'Foo' => 'bar',
|
||||
'Moo' => 'cow'
|
||||
],
|
||||
$el->getOptions(),
|
||||
'changed option'
|
||||
);
|
||||
}
|
||||
|
||||
// build output
|
||||
// build from array list
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @testdox build element tree from object
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testBuildHtmlObject(): void
|
||||
{
|
||||
// build a simple block
|
||||
// div -> div -> button
|
||||
// -> div -> span
|
||||
// -> div -> input
|
||||
$el = new Element('div', 'master', '', ['master']);
|
||||
$el->addSub(
|
||||
Element::addElement(
|
||||
new Element('div', 'div-button', '', ['dv-bt']),
|
||||
new Element('button', 'button-id', 'Click me', ['bt-red'], [
|
||||
'OnClick' => 'action();',
|
||||
'value' => 'click',
|
||||
'type' => 'button'
|
||||
]),
|
||||
),
|
||||
Element::addElement(
|
||||
new Element('div', 'div-span', '', ['dv-sp']),
|
||||
new Element('span', 'span-id', 'Big important message<br>other', ['red']),
|
||||
),
|
||||
Element::addElement(
|
||||
new Element('div', 'div-input', '', ['dv-in']),
|
||||
new Element('input', 'input-id', '', ['in-blue'], [
|
||||
'OnClick' => 'otherAction();',
|
||||
'value' => 'Touch',
|
||||
'type' => 'button'
|
||||
]),
|
||||
),
|
||||
);
|
||||
$this->assertEquals(
|
||||
'<div id="master" class="master">'
|
||||
. '<div id="div-button" class="dv-bt">'
|
||||
. '<button id="button-id" name="button-id" class="bt-red" OnClick="action();" '
|
||||
. 'value="click" type="button">Click me</button>'
|
||||
. '</div>'
|
||||
. '<div id="div-span" class="dv-sp">'
|
||||
. '<span id="span-id" class="red">Big important message<br>other</span>'
|
||||
. '</div>'
|
||||
. '<div id="div-input" class="dv-in">'
|
||||
. '<input id="input-id" name="input-id" '
|
||||
. 'class="in-blue" OnClick="otherAction();" value="Touch" type="button">'
|
||||
. '</div>'
|
||||
. '</div>',
|
||||
$el->buildHtml()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @testdox build elements from array list
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testbuildHtmlArray(): void
|
||||
{
|
||||
$this->assertEquals(
|
||||
'<div id="id-1">A</div>'
|
||||
. '<div id="id-2">B</div>'
|
||||
. '<div id="id-3">C</div>',
|
||||
Element::buildHtmlFromList([
|
||||
new Element('div', 'id-1', 'A'),
|
||||
new Element('div', 'id-2', 'B'),
|
||||
new Element('div', 'id-3', 'C'),
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @testdox check for invalid tag detection, possible invalid id, possible invalid css
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testInvalidElement(): void
|
||||
{
|
||||
Error::resetMessages();
|
||||
$this->expectException(HtmlBuilderExcpetion::class);
|
||||
$this->expectExceptionMessage("Could not create Element");
|
||||
$el = new Element('');
|
||||
$this->assertTrue(
|
||||
Error::hasError(),
|
||||
'failed to set error invalid tag detection'
|
||||
);
|
||||
$this->assertEquals(
|
||||
[[
|
||||
'level' => 'Error',
|
||||
'id' => '201',
|
||||
'message' => 'invalid or empty tag',
|
||||
'context' => ['tag' => '']
|
||||
]],
|
||||
Error::getMessages(),
|
||||
'check error message failed'
|
||||
);
|
||||
|
||||
// if we set invalid tag
|
||||
$el = new Element('div');
|
||||
$this->expectException(HtmlBuilderExcpetion::class);
|
||||
$this->expectExceptionMessageMatches("/^Invalid or empty tag: /");
|
||||
$this->expectExceptionMessage("Invalid or empty tag: 123123");
|
||||
$el->setTag('123123');
|
||||
$this->assertTrue(
|
||||
Error::hasError(),
|
||||
'failed to set error invalid tag detection'
|
||||
);
|
||||
$this->assertEquals(
|
||||
[[
|
||||
'level' => 'Error',
|
||||
'id' => '201',
|
||||
'message' => 'invalid or empty tag',
|
||||
'context' => ['tag' => '']
|
||||
]],
|
||||
Error::getMessages(),
|
||||
'check error message failed'
|
||||
);
|
||||
|
||||
|
||||
// invalid id (warning)
|
||||
Error::resetMessages();
|
||||
$el = new Element('div', '-$a15');
|
||||
$this->assertTrue(
|
||||
Error::hasWarning(),
|
||||
'failed to set warning invalid id detection'
|
||||
);
|
||||
$this->assertEquals(
|
||||
[[
|
||||
'level' => 'Warning',
|
||||
'id' => '202',
|
||||
'message' => 'possible invalid id',
|
||||
'context' => ['id' => '-$a15', 'tag' => 'div']
|
||||
]],
|
||||
Error::getMessages(),
|
||||
'check error message failed'
|
||||
);
|
||||
|
||||
// invalid name
|
||||
Error::resetMessages();
|
||||
$el = new Element('div', 'valid', '', [], ['name' => '-$asdf&']);
|
||||
$this->assertTrue(
|
||||
Error::hasWarning(),
|
||||
'failed to set warning invalid name detection'
|
||||
);
|
||||
$this->assertEquals(
|
||||
[[
|
||||
'level' => 'Warning',
|
||||
'id' => '203',
|
||||
'message' => 'possible invalid name',
|
||||
'context' => ['name' => '-$asdf&', 'id' => 'valid', 'tag' => 'div']
|
||||
]],
|
||||
Error::getMessages(),
|
||||
'check error message failed'
|
||||
);
|
||||
}
|
||||
|
||||
// static add element
|
||||
// print object/array
|
||||
}
|
||||
|
||||
// __END__
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace tests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use CoreLibs\Template\HtmlBuilder\StringReplace;
|
||||
|
||||
/**
|
||||
* Test class for Template\HtmlBuilder\StringReplace
|
||||
* @coversDefaultClass \CoreLibs\Template\HtmlBuilder\StringReplace
|
||||
* @testdox \CoreLibs\Template\HtmlBuilder\StringReplace method tests
|
||||
*/
|
||||
final class CoreLibsTemplateHtmlBuilderStringReplaceTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @covers ::replaceData
|
||||
* @testdox test basic replaceData
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testReplaceData(): void
|
||||
{
|
||||
$html_block = <<<HTML
|
||||
<div id="{ID}" class="{CSS}">
|
||||
{CONTENT}
|
||||
</div>
|
||||
HTML;
|
||||
|
||||
$this->assertEquals(
|
||||
<<<HTML
|
||||
<div id="block-id" class="blue,red">
|
||||
Some content here<br>with bla bla inside
|
||||
</div>
|
||||
HTML,
|
||||
StringReplace::replaceData(
|
||||
$html_block,
|
||||
[
|
||||
'ID' => 'block-id',
|
||||
'CSS' => join(',', ['blue', 'red']),
|
||||
'{CONTENT}' => 'Some content here<br>with bla bla inside',
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @testdox replaceData error
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
/* public function testReplaceDataErrors(): void
|
||||
{
|
||||
$this->expectException(HtmlBuilderExcpetion::class);
|
||||
$this->expectExceptionMessage("Replace and content array count differ");
|
||||
StringReplace::replaceData('<span>{FOO}</span>', ['{FOO}', '{BAR}'], ['foo']);
|
||||
} */
|
||||
}
|
||||
|
||||
// __END__
|
||||
@@ -7,7 +7,8 @@
|
||||
"phpstan/phpstan": "^1.10",
|
||||
"phan/phan": "^5.4",
|
||||
"phpstan/extension-installer": "^1.2",
|
||||
"vimeo/psalm": "^5.7"
|
||||
"vimeo/psalm": "^5.7",
|
||||
"phpstan/phpstan-deprecation-rules": "^1.1"
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
@@ -15,6 +16,7 @@
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.1"
|
||||
"php": ">=8.1",
|
||||
"psr/log": "^2.0 || ^3.0"
|
||||
}
|
||||
}
|
||||
|
||||
608
composer.lock
generated
608
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -1,47 +0,0 @@
|
||||
parameters:
|
||||
ignoreErrors:
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$connection of function pg_escape_bytea expects PgSql\\\\Connection\\|string, object\\|resource given\\.$#"
|
||||
count: 1
|
||||
path: www/lib/CoreLibs/DB/SQL/PgSQL.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$connection of function pg_escape_identifier expects PgSql\\\\Connection\\|string, object\\|resource given\\.$#"
|
||||
count: 1
|
||||
path: www/lib/CoreLibs/DB/SQL/PgSQL.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$connection of function pg_escape_literal expects PgSql\\\\Connection\\|string, object\\|resource given\\.$#"
|
||||
count: 1
|
||||
path: www/lib/CoreLibs/DB/SQL/PgSQL.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$connection of function pg_escape_string expects PgSql\\\\Connection\\|string, object\\|resource given\\.$#"
|
||||
count: 1
|
||||
path: www/lib/CoreLibs/DB/SQL/PgSQL.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$connection of function pg_execute expects PgSql\\\\Connection\\|string, object\\|resource given\\.$#"
|
||||
count: 1
|
||||
path: www/lib/CoreLibs/DB/SQL/PgSQL.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$connection of function pg_parameter_status expects PgSql\\\\Connection\\|string, object\\|resource given\\.$#"
|
||||
count: 1
|
||||
path: www/lib/CoreLibs/DB/SQL/PgSQL.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$connection of function pg_prepare expects PgSql\\\\Connection\\|string, object\\|resource given\\.$#"
|
||||
count: 1
|
||||
path: www/lib/CoreLibs/DB/SQL/PgSQL.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$connection of function pg_query expects PgSql\\\\Connection\\|string, object\\|resource given\\.$#"
|
||||
count: 1
|
||||
path: www/lib/CoreLibs/DB/SQL/PgSQL.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$connection of function pg_query_params expects PgSql\\\\Connection\\|string, object\\|resource given\\.$#"
|
||||
count: 1
|
||||
path: www/lib/CoreLibs/DB/SQL/PgSQL.php
|
||||
|
||||
25
phpstan.neon
25
phpstan.neon
@@ -10,23 +10,15 @@ parameters:
|
||||
- %currentWorkingDirectory%/www
|
||||
bootstrapFiles:
|
||||
- %currentWorkingDirectory%/phpstan-bootstrap.php
|
||||
# - %currentWorkingDirectory%/www/lib/autoloader.php
|
||||
- %currentWorkingDirectory%/www/vendor/autoload.php
|
||||
scanDirectories:
|
||||
- www/vendor
|
||||
scanFiles:
|
||||
- www/configs/config.php
|
||||
- www/configs/config.master.php
|
||||
# if composer.json autoloader defined, this is not needed
|
||||
# - www/lib/autoloader.php
|
||||
# - www/vendor/autoload.php
|
||||
excludePaths:
|
||||
# do not check old qq file uploader tests
|
||||
- www/admin/qq_file_upload_*.php
|
||||
# ignore all test files
|
||||
# - www/admin/class_test*.php
|
||||
# extra in sub folder
|
||||
- www/admin/subfolder/class_test*.php
|
||||
- www/admin/error_test.php
|
||||
# admin synlink files
|
||||
- www/admin/edit_*.php
|
||||
@@ -37,10 +29,6 @@ parameters:
|
||||
# ignore admin header stuff
|
||||
# - www/includes/admin_header.php # ignore the admin include stuff
|
||||
- www/includes/admin_footer.php # ignore the admin include stuff
|
||||
# deprecated files
|
||||
- www/includes/admin_set_paths.php # ignore the admin include stuff
|
||||
- www/includes/admin_smarty.php # ignore the admin include stuff
|
||||
- www/includes/edit_base.LEGACY.php # old style
|
||||
# folders with data no check needed
|
||||
- www/templates_c
|
||||
- www/cache
|
||||
@@ -51,13 +39,9 @@ parameters:
|
||||
- www/vendor
|
||||
# ignore errores with
|
||||
ignoreErrors:
|
||||
#- # this error is ignore because of the PHP 8.0 to 8.1 change for pg_*, only for 8.0 or lower
|
||||
# message: "#^Parameter \\#1 \\$(result|connection) of function pg_\\w+ expects resource(\\|null)?, object\\|resource(\\|bool)? given\\.$#"
|
||||
# path: %currentWorkingDirectory%/www/lib/CoreLibs/DB/SQL/PgSQL.php
|
||||
# - # this is for 8.1 or newer
|
||||
# message: "#^Parameter \\#1 \\$(result|connection) of function pg_\\w+ expects PgSql\\\\(Result|Connection(\\|string)?(\\|null)?), object\\|resource given\\.$#"
|
||||
# path: %currentWorkingDirectory%/www/lib/CoreLibs/DB/SQL/PgSQL.php
|
||||
# this is ignored for now
|
||||
# - # in the class_test tree we allow deprecated calls
|
||||
# message: "#^Call to deprecated method #"
|
||||
# path: %currentWorkingDirectory%/www/admin/class_test.*.php
|
||||
# - '#Expression in empty\(\) is always falsy.#'
|
||||
# -
|
||||
# message: '#Reflection error: [a-zA-Z0-9\\_]+ not found.#'
|
||||
@@ -69,3 +53,6 @@ parameters:
|
||||
# paths:
|
||||
# - ...
|
||||
# - ...
|
||||
-
|
||||
message: "#^Call to deprecated method #"
|
||||
path: www/admin/class_test*.php
|
||||
|
||||
2
vendor/composer/autoload_files.php
vendored
2
vendor/composer/autoload_files.php
vendored
@@ -14,8 +14,8 @@ return array(
|
||||
'76cd0796156622033397994f25b0d8fc' => $vendorDir . '/amphp/amp/lib/Internal/functions.php',
|
||||
'6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
|
||||
'b6b991a57620e2fb6b2f66f03fe9ddc2' => $vendorDir . '/symfony/string/Resources/functions.php',
|
||||
'6cd5651c4fef5ed6b63e8d8b8ffbf3cc' => $vendorDir . '/amphp/byte-stream/lib/functions.php',
|
||||
'9b38cf48e83f5d8f60375221cd213eee' => $vendorDir . '/phpstan/phpstan/bootstrap.php',
|
||||
'6cd5651c4fef5ed6b63e8d8b8ffbf3cc' => $vendorDir . '/amphp/byte-stream/lib/functions.php',
|
||||
'2b9d0f43f9552984cfa82fee95491826' => $vendorDir . '/sabre/event/lib/coroutine.php',
|
||||
'd81bab31d3feb45bfe2f283ea3c8fdf7' => $vendorDir . '/sabre/event/lib/Loop/functions.php',
|
||||
'a1cce3d26cc15c00fcd0b3354bd72c88' => $vendorDir . '/sabre/event/lib/Promise/functions.php',
|
||||
|
||||
4
vendor/composer/autoload_psr4.php
vendored
4
vendor/composer/autoload_psr4.php
vendored
@@ -26,11 +26,13 @@ return array(
|
||||
'Psalm\\' => array($vendorDir . '/vimeo/psalm/src/Psalm'),
|
||||
'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'),
|
||||
'Phan\\' => array($vendorDir . '/phan/phan/src/Phan'),
|
||||
'PackageVersions\\' => array($vendorDir . '/composer/package-versions-deprecated/src/PackageVersions'),
|
||||
'PHPStan\\PhpDocParser\\' => array($vendorDir . '/phpstan/phpdoc-parser/src'),
|
||||
'PHPStan\\ExtensionInstaller\\' => array($vendorDir . '/phpstan/extension-installer/src'),
|
||||
'PHPStan\\' => array($vendorDir . '/phpstan/phpstan-deprecation-rules/src'),
|
||||
'Microsoft\\PhpParser\\' => array($vendorDir . '/microsoft/tolerant-php-parser/src'),
|
||||
'LanguageServerProtocol\\' => array($vendorDir . '/felixfbecker/language-server-protocol/src'),
|
||||
'Fidry\\CpuCoreCounter\\' => array($vendorDir . '/fidry/cpu-core-counter/src'),
|
||||
'Doctrine\\Deprecations\\' => array($vendorDir . '/doctrine/deprecations/lib/Doctrine/Deprecations'),
|
||||
'Composer\\XdebugHandler\\' => array($vendorDir . '/composer/xdebug-handler/src'),
|
||||
'Composer\\Semver\\' => array($vendorDir . '/composer/semver/src'),
|
||||
'Composer\\Pcre\\' => array($vendorDir . '/composer/pcre/src'),
|
||||
|
||||
21
vendor/composer/autoload_static.php
vendored
21
vendor/composer/autoload_static.php
vendored
@@ -15,8 +15,8 @@ class ComposerStaticInitdd705c6e8ab22e0d642372dec7767718
|
||||
'76cd0796156622033397994f25b0d8fc' => __DIR__ . '/..' . '/amphp/amp/lib/Internal/functions.php',
|
||||
'6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php',
|
||||
'b6b991a57620e2fb6b2f66f03fe9ddc2' => __DIR__ . '/..' . '/symfony/string/Resources/functions.php',
|
||||
'6cd5651c4fef5ed6b63e8d8b8ffbf3cc' => __DIR__ . '/..' . '/amphp/byte-stream/lib/functions.php',
|
||||
'9b38cf48e83f5d8f60375221cd213eee' => __DIR__ . '/..' . '/phpstan/phpstan/bootstrap.php',
|
||||
'6cd5651c4fef5ed6b63e8d8b8ffbf3cc' => __DIR__ . '/..' . '/amphp/byte-stream/lib/functions.php',
|
||||
'2b9d0f43f9552984cfa82fee95491826' => __DIR__ . '/..' . '/sabre/event/lib/coroutine.php',
|
||||
'd81bab31d3feb45bfe2f283ea3c8fdf7' => __DIR__ . '/..' . '/sabre/event/lib/Loop/functions.php',
|
||||
'a1cce3d26cc15c00fcd0b3354bd72c88' => __DIR__ . '/..' . '/sabre/event/lib/Promise/functions.php',
|
||||
@@ -62,8 +62,9 @@ class ComposerStaticInitdd705c6e8ab22e0d642372dec7767718
|
||||
'Psalm\\' => 6,
|
||||
'PhpParser\\' => 10,
|
||||
'Phan\\' => 5,
|
||||
'PackageVersions\\' => 16,
|
||||
'PHPStan\\PhpDocParser\\' => 21,
|
||||
'PHPStan\\ExtensionInstaller\\' => 27,
|
||||
'PHPStan\\' => 8,
|
||||
),
|
||||
'M' =>
|
||||
array (
|
||||
@@ -77,6 +78,10 @@ class ComposerStaticInitdd705c6e8ab22e0d642372dec7767718
|
||||
array (
|
||||
'Fidry\\CpuCoreCounter\\' => 21,
|
||||
),
|
||||
'D' =>
|
||||
array (
|
||||
'Doctrine\\Deprecations\\' => 22,
|
||||
),
|
||||
'C' =>
|
||||
array (
|
||||
'Composer\\XdebugHandler\\' => 23,
|
||||
@@ -174,14 +179,18 @@ class ComposerStaticInitdd705c6e8ab22e0d642372dec7767718
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/phan/phan/src/Phan',
|
||||
),
|
||||
'PackageVersions\\' =>
|
||||
'PHPStan\\PhpDocParser\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/composer/package-versions-deprecated/src/PackageVersions',
|
||||
0 => __DIR__ . '/..' . '/phpstan/phpdoc-parser/src',
|
||||
),
|
||||
'PHPStan\\ExtensionInstaller\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/phpstan/extension-installer/src',
|
||||
),
|
||||
'PHPStan\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/phpstan/phpstan-deprecation-rules/src',
|
||||
),
|
||||
'Microsoft\\PhpParser\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/microsoft/tolerant-php-parser/src',
|
||||
@@ -194,6 +203,10 @@ class ComposerStaticInitdd705c6e8ab22e0d642372dec7767718
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/fidry/cpu-core-counter/src',
|
||||
),
|
||||
'Doctrine\\Deprecations\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/doctrine/deprecations/lib/Doctrine/Deprecations',
|
||||
),
|
||||
'Composer\\XdebugHandler\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/composer/xdebug-handler/src',
|
||||
|
||||
558
vendor/composer/installed.json
vendored
558
vendor/composer/installed.json
vendored
File diff suppressed because it is too large
Load Diff
160
vendor/composer/installed.php
vendored
160
vendor/composer/installed.php
vendored
@@ -28,15 +28,6 @@
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => true,
|
||||
),
|
||||
'composer/package-versions-deprecated' => array(
|
||||
'pretty_version' => '1.11.99.5',
|
||||
'version' => '1.11.99.5',
|
||||
'reference' => 'b4f54f74ef3453349c24a845d22392cd31e65f1d',
|
||||
'type' => 'composer-plugin',
|
||||
'install_path' => __DIR__ . '/./package-versions-deprecated',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => true,
|
||||
),
|
||||
'composer/pcre' => array(
|
||||
'pretty_version' => '3.1.0',
|
||||
'version' => '3.1.0.0',
|
||||
@@ -47,9 +38,9 @@
|
||||
'dev_requirement' => true,
|
||||
),
|
||||
'composer/semver' => array(
|
||||
'pretty_version' => '3.3.2',
|
||||
'version' => '3.3.2.0',
|
||||
'reference' => '3953f23262f2bff1919fc82183ad9acb13ff62c9',
|
||||
'pretty_version' => '3.4.0',
|
||||
'version' => '3.4.0.0',
|
||||
'reference' => '35e8d0af4486141bc745f23a29cc2091eb624a32',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/./semver',
|
||||
'aliases' => array(),
|
||||
@@ -73,6 +64,15 @@
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => true,
|
||||
),
|
||||
'doctrine/deprecations' => array(
|
||||
'pretty_version' => 'v1.1.1',
|
||||
'version' => '1.1.1.0',
|
||||
'reference' => '612a3ee5ab0d5dd97b7cf3874a6efe24325efac3',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../doctrine/deprecations',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => true,
|
||||
),
|
||||
'egrajp/development-corelibs-dev' => array(
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
@@ -119,29 +119,23 @@
|
||||
'dev_requirement' => true,
|
||||
),
|
||||
'netresearch/jsonmapper' => array(
|
||||
'pretty_version' => 'v4.1.0',
|
||||
'version' => '4.1.0.0',
|
||||
'reference' => 'cfa81ea1d35294d64adb9c68aa4cb9e92400e53f',
|
||||
'pretty_version' => 'v4.2.0',
|
||||
'version' => '4.2.0.0',
|
||||
'reference' => 'f60565f8c0566a31acf06884cdaa591867ecc956',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../netresearch/jsonmapper',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => true,
|
||||
),
|
||||
'nikic/php-parser' => array(
|
||||
'pretty_version' => 'v4.15.4',
|
||||
'version' => '4.15.4.0',
|
||||
'reference' => '6bb5176bc4af8bcb7d926f88718db9b96a2d4290',
|
||||
'pretty_version' => 'v4.17.1',
|
||||
'version' => '4.17.1.0',
|
||||
'reference' => 'a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../nikic/php-parser',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => true,
|
||||
),
|
||||
'ocramius/package-versions' => array(
|
||||
'dev_requirement' => true,
|
||||
'replaced' => array(
|
||||
0 => '1.11.99',
|
||||
),
|
||||
),
|
||||
'phan/phan' => array(
|
||||
'pretty_version' => '5.4.2',
|
||||
'version' => '5.4.2.0',
|
||||
@@ -170,36 +164,54 @@
|
||||
'dev_requirement' => true,
|
||||
),
|
||||
'phpdocumentor/type-resolver' => array(
|
||||
'pretty_version' => '1.6.2',
|
||||
'version' => '1.6.2.0',
|
||||
'reference' => '48f445a408c131e38cab1c235aa6d2bb7a0bb20d',
|
||||
'pretty_version' => '1.7.3',
|
||||
'version' => '1.7.3.0',
|
||||
'reference' => '3219c6ee25c9ea71e3d9bbaf39c67c9ebd499419',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../phpdocumentor/type-resolver',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => true,
|
||||
),
|
||||
'phpstan/extension-installer' => array(
|
||||
'pretty_version' => '1.2.0',
|
||||
'version' => '1.2.0.0',
|
||||
'reference' => 'f06dbb052ddc394e7896fcd1cfcd533f9f6ace40',
|
||||
'pretty_version' => '1.3.1',
|
||||
'version' => '1.3.1.0',
|
||||
'reference' => 'f45734bfb9984c6c56c4486b71230355f066a58a',
|
||||
'type' => 'composer-plugin',
|
||||
'install_path' => __DIR__ . '/../phpstan/extension-installer',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => true,
|
||||
),
|
||||
'phpstan/phpdoc-parser' => array(
|
||||
'pretty_version' => '1.24.0',
|
||||
'version' => '1.24.0.0',
|
||||
'reference' => '3510b0a6274cc42f7219367cb3abfc123ffa09d6',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../phpstan/phpdoc-parser',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => true,
|
||||
),
|
||||
'phpstan/phpstan' => array(
|
||||
'pretty_version' => '1.10.5',
|
||||
'version' => '1.10.5.0',
|
||||
'reference' => '1fb6f494d82455151ecf15c5c191923f5d84324e',
|
||||
'pretty_version' => '1.10.34',
|
||||
'version' => '1.10.34.0',
|
||||
'reference' => '7f806b6f1403e6914c778140e2ba07c293cb4901',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../phpstan/phpstan',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => true,
|
||||
),
|
||||
'phpstan/phpstan-deprecation-rules' => array(
|
||||
'pretty_version' => '1.1.4',
|
||||
'version' => '1.1.4.0',
|
||||
'reference' => '089d8a8258ed0aeefdc7b68b6c3d25572ebfdbaa',
|
||||
'type' => 'phpstan-extension',
|
||||
'install_path' => __DIR__ . '/../phpstan/phpstan-deprecation-rules',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => true,
|
||||
),
|
||||
'psalm/psalm' => array(
|
||||
'dev_requirement' => true,
|
||||
'provided' => array(
|
||||
0 => '5.7.7',
|
||||
0 => '5.15.0',
|
||||
),
|
||||
),
|
||||
'psr/container' => array(
|
||||
@@ -218,7 +230,7 @@
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/log',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => true,
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/log-implementation' => array(
|
||||
'dev_requirement' => true,
|
||||
@@ -236,108 +248,108 @@
|
||||
'dev_requirement' => true,
|
||||
),
|
||||
'sebastian/diff' => array(
|
||||
'pretty_version' => '5.0.0',
|
||||
'version' => '5.0.0.0',
|
||||
'reference' => '70dd1b20bc198da394ad542e988381b44e64e39f',
|
||||
'pretty_version' => '5.0.3',
|
||||
'version' => '5.0.3.0',
|
||||
'reference' => '912dc2fbe3e3c1e7873313cc801b100b6c68c87b',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../sebastian/diff',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => true,
|
||||
),
|
||||
'spatie/array-to-xml' => array(
|
||||
'pretty_version' => '3.1.5',
|
||||
'version' => '3.1.5.0',
|
||||
'reference' => '13f76acef5362d15c71ae1ac6350cc3df5e25e43',
|
||||
'pretty_version' => '3.2.0',
|
||||
'version' => '3.2.0.0',
|
||||
'reference' => 'f9ab39c808500c347d5a8b6b13310bd5221e39e7',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../spatie/array-to-xml',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => true,
|
||||
),
|
||||
'symfony/console' => array(
|
||||
'pretty_version' => 'v6.2.7',
|
||||
'version' => '6.2.7.0',
|
||||
'reference' => 'cbad09eb8925b6ad4fb721c7a179344dc4a19d45',
|
||||
'pretty_version' => 'v6.3.4',
|
||||
'version' => '6.3.4.0',
|
||||
'reference' => 'eca495f2ee845130855ddf1cf18460c38966c8b6',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/console',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => true,
|
||||
),
|
||||
'symfony/deprecation-contracts' => array(
|
||||
'pretty_version' => 'v3.2.1',
|
||||
'version' => '3.2.1.0',
|
||||
'reference' => 'e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e',
|
||||
'pretty_version' => 'v3.3.0',
|
||||
'version' => '3.3.0.0',
|
||||
'reference' => '7c3aff79d10325257a001fcf92d991f24fc967cf',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/deprecation-contracts',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => true,
|
||||
),
|
||||
'symfony/filesystem' => array(
|
||||
'pretty_version' => 'v6.2.7',
|
||||
'version' => '6.2.7.0',
|
||||
'reference' => '82b6c62b959f642d000456f08c6d219d749215b3',
|
||||
'pretty_version' => 'v6.3.1',
|
||||
'version' => '6.3.1.0',
|
||||
'reference' => 'edd36776956f2a6fcf577edb5b05eb0e3bdc52ae',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/filesystem',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => true,
|
||||
),
|
||||
'symfony/polyfill-ctype' => array(
|
||||
'pretty_version' => 'v1.27.0',
|
||||
'version' => '1.27.0.0',
|
||||
'reference' => '5bbc823adecdae860bb64756d639ecfec17b050a',
|
||||
'pretty_version' => 'v1.28.0',
|
||||
'version' => '1.28.0.0',
|
||||
'reference' => 'ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-ctype',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => true,
|
||||
),
|
||||
'symfony/polyfill-intl-grapheme' => array(
|
||||
'pretty_version' => 'v1.27.0',
|
||||
'version' => '1.27.0.0',
|
||||
'reference' => '511a08c03c1960e08a883f4cffcacd219b758354',
|
||||
'pretty_version' => 'v1.28.0',
|
||||
'version' => '1.28.0.0',
|
||||
'reference' => '875e90aeea2777b6f135677f618529449334a612',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-intl-grapheme',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => true,
|
||||
),
|
||||
'symfony/polyfill-intl-normalizer' => array(
|
||||
'pretty_version' => 'v1.27.0',
|
||||
'version' => '1.27.0.0',
|
||||
'reference' => '19bd1e4fcd5b91116f14d8533c57831ed00571b6',
|
||||
'pretty_version' => 'v1.28.0',
|
||||
'version' => '1.28.0.0',
|
||||
'reference' => '8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-intl-normalizer',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => true,
|
||||
),
|
||||
'symfony/polyfill-mbstring' => array(
|
||||
'pretty_version' => 'v1.27.0',
|
||||
'version' => '1.27.0.0',
|
||||
'reference' => '8ad114f6b39e2c98a8b0e3bd907732c207c2b534',
|
||||
'pretty_version' => 'v1.28.0',
|
||||
'version' => '1.28.0.0',
|
||||
'reference' => '42292d99c55abe617799667f454222c54c60e229',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-mbstring',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => true,
|
||||
),
|
||||
'symfony/polyfill-php80' => array(
|
||||
'pretty_version' => 'v1.27.0',
|
||||
'version' => '1.27.0.0',
|
||||
'reference' => '7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936',
|
||||
'pretty_version' => 'v1.28.0',
|
||||
'version' => '1.28.0.0',
|
||||
'reference' => '6caa57379c4aec19c0a12a38b59b26487dcfe4b5',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-php80',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => true,
|
||||
),
|
||||
'symfony/service-contracts' => array(
|
||||
'pretty_version' => 'v3.2.1',
|
||||
'version' => '3.2.1.0',
|
||||
'reference' => 'a8c9cedf55f314f3a186041d19537303766df09a',
|
||||
'pretty_version' => 'v3.3.0',
|
||||
'version' => '3.3.0.0',
|
||||
'reference' => '40da9cc13ec349d9e4966ce18b5fbcd724ab10a4',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/service-contracts',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => true,
|
||||
),
|
||||
'symfony/string' => array(
|
||||
'pretty_version' => 'v6.2.7',
|
||||
'version' => '6.2.7.0',
|
||||
'reference' => '67b8c1eec78296b85dc1c7d9743830160218993d',
|
||||
'pretty_version' => 'v6.3.2',
|
||||
'version' => '6.3.2.0',
|
||||
'reference' => '53d1a83225002635bca3482fcbf963001313fb68',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/string',
|
||||
'aliases' => array(),
|
||||
@@ -353,9 +365,9 @@
|
||||
'dev_requirement' => true,
|
||||
),
|
||||
'vimeo/psalm' => array(
|
||||
'pretty_version' => '5.7.7',
|
||||
'version' => '5.7.7.0',
|
||||
'reference' => 'e028ba46ba0d7f9a78bc3201c251e137383e145f',
|
||||
'pretty_version' => '5.15.0',
|
||||
'version' => '5.15.0.0',
|
||||
'reference' => '5c774aca4746caf3d239d9c8cadb9f882ca29352',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../vimeo/psalm',
|
||||
'aliases' => array(),
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
# CHANGELOG
|
||||
|
||||
## 1.1.3 - 2017-09-06
|
||||
|
||||
This release fixes a bug that caused PackageVersions to prevent
|
||||
the `composer remove` and `composer update` commands to fail when
|
||||
this package is removed.
|
||||
|
||||
In addition to that, mutation testing has been added to the suite,
|
||||
ensuring that the package is accurately and extensively tested.
|
||||
|
||||
Total issues resolved: **3**
|
||||
|
||||
- [40: Mutation testing, PHP 7.1 testing](https://github.com/Ocramius/PackageVersions/pull/40) thanks to @Ocramius
|
||||
- [41: Removing this package on install results in file access error](https://github.com/Ocramius/PackageVersions/issues/41) thanks to @Xerkus
|
||||
- [46: #41 Avoid issues when the package is scheduled for removal](https://github.com/Ocramius/PackageVersions/pull/46) thanks to @Jean85
|
||||
|
||||
## 1.1.2 - 2016-12-30
|
||||
|
||||
This release fixes a bug that caused PackageVersions to be enabled
|
||||
even when it was part of a globally installed package.
|
||||
|
||||
Total issues resolved: **3**
|
||||
|
||||
- [35: remove all temp directories](https://github.com/Ocramius/PackageVersions/pull/35)
|
||||
- [38: Interferes with other projects when installed globally](https://github.com/Ocramius/PackageVersions/issues/38)
|
||||
- [39: Ignore the global plugin when updating local projects](https://github.com/Ocramius/PackageVersions/pull/39)
|
||||
|
||||
## 1.1.1 - 2016-07-25
|
||||
|
||||
This release removes the [`"files"`](https://getcomposer.org/doc/04-schema.md#files) directive from
|
||||
[`composer.json`](https://github.com/Ocramius/PackageVersions/commit/86f2636f7c5e7b56fa035fa3826d5fcf80b6dc72),
|
||||
as it is no longer needed for `composer install --classmap-authoritative`.
|
||||
Also, that directive was causing issues with HHVM installations, since
|
||||
PackageVersions is not compatible with it.
|
||||
|
||||
Total issues resolved: **1**
|
||||
|
||||
- [34: Fatal error during travis build after update to 1.1.0](https://github.com/Ocramius/PackageVersions/issues/34)
|
||||
|
||||
## 1.1.0 - 2016-07-22
|
||||
|
||||
This release introduces support for running `composer install --classmap-authoritative`
|
||||
and `composer install --no-scripts`. Please note that performance
|
||||
while using these modes may be degraded, but the package will
|
||||
still work.
|
||||
|
||||
Additionally, the package was tuned to prevent the plugin from
|
||||
running twice at installation.
|
||||
|
||||
Total issues resolved: **10**
|
||||
|
||||
- [18: Fails when using composer install --no-scripts](https://github.com/Ocramius/PackageVersions/issues/18)
|
||||
- [20: CS (spacing)](https://github.com/Ocramius/PackageVersions/pull/20)
|
||||
- [22: Document the way the require-dev section is treated](https://github.com/Ocramius/PackageVersions/issues/22)
|
||||
- [23: Underline that composer.lock is used as source of information](https://github.com/Ocramius/PackageVersions/pull/23)
|
||||
- [27: Fix incompatibility with --classmap-authoritative](https://github.com/Ocramius/PackageVersions/pull/27)
|
||||
- [29: mention optimize-autoloader composer.json config option in README](https://github.com/Ocramius/PackageVersions/pull/29)
|
||||
- [30: The version class is generated twice during composer update](https://github.com/Ocramius/PackageVersions/issues/30)
|
||||
- [31: Remove double registration of the event listeners](https://github.com/Ocramius/PackageVersions/pull/31)
|
||||
- [32: Update the usage of mock APIs to use the new API](https://github.com/Ocramius/PackageVersions/pull/32)
|
||||
- [33: Fix for #18 - support running with --no-scripts flag](https://github.com/Ocramius/PackageVersions/pull/33)
|
||||
|
||||
## 1.0.4 - 2016-04-23
|
||||
|
||||
This release includes a fix/workaround for composer/composer#5237,
|
||||
which causes `ocramius/package-versions` to sometimes generate a
|
||||
`Versions` class with malformed name (something like
|
||||
`Versions_composer_tmp0`) when running `composer require <package-name>`.
|
||||
|
||||
Total issues resolved: **2**
|
||||
|
||||
- [16: Workaround for composer/composer#5237 - class parsing](https://github.com/Ocramius/PackageVersions/pull/16)
|
||||
- [17: Weird Class name being generated](https://github.com/Ocramius/PackageVersions/issues/17)
|
||||
|
||||
## 1.0.3 - 2016-02-26
|
||||
|
||||
This release fixes an issue related to concurrent autoloader
|
||||
re-generation caused by multiple composer plugins being installed.
|
||||
The issue was solved by removing autoloader re-generation from this
|
||||
package, but it may still affect other packages.
|
||||
|
||||
It is now recommended that you run `composer dump-autoload --optimize`
|
||||
after installation when using this particular package.
|
||||
Please note that `composer (install|update) -o` is not sufficient
|
||||
to avoid autoload overhead when using this particular package.
|
||||
|
||||
Total issues resolved: **1**
|
||||
|
||||
- [15: Remove autoload re-dump optimization](https://github.com/Ocramius/PackageVersions/pull/15)
|
||||
|
||||
## 1.0.2 - 2016-02-24
|
||||
|
||||
This release fixes issues related to installing the component without
|
||||
any dev dependencies or with packages that don't have a source or dist
|
||||
reference, which is usual with packages defined directly in the
|
||||
`composer.json`.
|
||||
|
||||
Total issues resolved: **3**
|
||||
|
||||
- [11: fix composer install --no-dev PHP7](https://github.com/Ocramius/PackageVersions/pull/11)
|
||||
- [12: Packages don't always have a source/reference](https://github.com/Ocramius/PackageVersions/issues/12)
|
||||
- [13: Fix #12 - support dist and missing package version references](https://github.com/Ocramius/PackageVersions/pull/13)
|
||||
|
||||
## 1.0.1 - 2016-02-01
|
||||
|
||||
This release fixes an issue related with composer updates to
|
||||
already installed versions.
|
||||
Using `composer require` within a package that already used
|
||||
`ocramius/package-versions` caused the installation to be unable
|
||||
to write the `PackageVersions\Versions` class to a file.
|
||||
|
||||
Total issues resolved: **6**
|
||||
|
||||
- [2: remove unused use statement](https://github.com/Ocramius/PackageVersions/pull/2)
|
||||
- [3: Remove useless files from dist package](https://github.com/Ocramius/PackageVersions/pull/3)
|
||||
- [5: failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly](https://github.com/Ocramius/PackageVersions/issues/5)
|
||||
- [6: Fix/#5 use composer vendor dir](https://github.com/Ocramius/PackageVersions/pull/6)
|
||||
- [7: Hotfix - #5 generate package versions also when in phar context](https://github.com/Ocramius/PackageVersions/pull/7)
|
||||
- [8: Versions class should be ignored by VCS, as it is an install-time artifact](https://github.com/Ocramius/PackageVersions/pull/8)
|
||||
@@ -1,39 +0,0 @@
|
||||
---
|
||||
title: Contributing
|
||||
---
|
||||
|
||||
# Contributing
|
||||
|
||||
* Coding standard for the project is [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)
|
||||
* The project will follow strict [object calisthenics](http://www.slideshare.net/guilhermeblanco/object-calisthenics-applied-to-php)
|
||||
* Any contribution must provide tests for additional introduced conditions
|
||||
* Any un-confirmed issue needs a failing test case before being accepted
|
||||
* Pull requests must be sent from a new hotfix/feature branch, not from `master`.
|
||||
|
||||
## Installation
|
||||
|
||||
To install the project and run the tests, you need to clone it first:
|
||||
|
||||
```sh
|
||||
$ git clone git://github.com/Ocramius/PackageVersions.git
|
||||
```
|
||||
|
||||
You will then need to run a composer installation:
|
||||
|
||||
```sh
|
||||
$ cd PackageVersions
|
||||
$ curl -s https://getcomposer.org/installer | php
|
||||
$ php composer.phar update
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
The PHPUnit version to be used is the one installed as a dev- dependency via composer:
|
||||
|
||||
```sh
|
||||
$ ./vendor/bin/phpunit
|
||||
```
|
||||
|
||||
Accepted coverage for new contributions is 80%. Any contribution not satisfying this requirement
|
||||
won't be merged.
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
# Package Versions
|
||||
|
||||
**`composer/package-versions-deprecated` is a fully-compatible fork of [`ocramius/package-versions`](https://github.com/Ocramius/PackageVersions)** which provides compatibility with Composer 1 and 2 on PHP 7+. It replaces ocramius/package-versions so if you have a dependency requiring it and you want to use Composer v2 but can not upgrade to PHP 7.4 just yet, you can require this package instead.
|
||||
|
||||
If you have a **direct** dependency on `ocramius/package-versions`, we recommend that once you migrated to Composer 2.x you also migrate to use the [`Composer\InstalledVersions`](https://getcomposer.org/doc/07-runtime.md#installed-versions) class which offers the functionality present here out of the box. You can then remove the require on this package.
|
||||
|
||||
This package is EOL / deprecated and you should aim to migrate away from it as soon as possible!
|
||||
@@ -1,5 +0,0 @@
|
||||
## Security contact information
|
||||
|
||||
To report a security vulnerability, please use the
|
||||
[Tidelift security contact](https://tidelift.com/security).
|
||||
Tidelift will coordinate the fix and disclosure.
|
||||
@@ -1,48 +0,0 @@
|
||||
{
|
||||
"name": "composer/package-versions-deprecated",
|
||||
"description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)",
|
||||
"type": "composer-plugin",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Marco Pivetta",
|
||||
"email": "ocramius@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Jordi Boggiano",
|
||||
"email": "j.boggiano@seld.be"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^7 || ^8",
|
||||
"composer-plugin-api": "^1.1.0 || ^2.0"
|
||||
},
|
||||
"replace": {
|
||||
"ocramius/package-versions": "1.11.99"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^6.5 || ^7",
|
||||
"composer/composer": "^1.9.3 || ^2.0@dev",
|
||||
"ext-zip": "^1.13"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"PackageVersions\\": "src/PackageVersions"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"PackageVersionsTest\\": "test/PackageVersionsTest"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"class": "PackageVersions\\Installer",
|
||||
"branch-alias": {
|
||||
"dev-master": "1.x-dev"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"post-update-cmd": "PackageVersions\\Installer::dumpVersionsClass",
|
||||
"post-install-cmd": "PackageVersions\\Installer::dumpVersionsClass"
|
||||
}
|
||||
}
|
||||
2603
vendor/composer/package-versions-deprecated/composer.lock
generated
vendored
2603
vendor/composer/package-versions-deprecated/composer.lock
generated
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,128 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PackageVersions;
|
||||
|
||||
use Generator;
|
||||
use OutOfBoundsException;
|
||||
use UnexpectedValueException;
|
||||
use function array_key_exists;
|
||||
use function array_merge;
|
||||
use function basename;
|
||||
use function file_exists;
|
||||
use function file_get_contents;
|
||||
use function getcwd;
|
||||
use function iterator_to_array;
|
||||
use function json_decode;
|
||||
use function json_encode;
|
||||
use function sprintf;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* This is a fallback for {@see \PackageVersions\Versions::getVersion()}
|
||||
* Do not use this class directly: it is intended to be only used when
|
||||
* {@see \PackageVersions\Versions} fails to be generated, which typically
|
||||
* happens when running composer with `--no-scripts` flag)
|
||||
*/
|
||||
final class FallbackVersions
|
||||
{
|
||||
const ROOT_PACKAGE_NAME = 'unknown/root-package@UNKNOWN';
|
||||
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws OutOfBoundsException If a version cannot be located.
|
||||
* @throws UnexpectedValueException If the composer.lock file could not be located.
|
||||
*/
|
||||
public static function getVersion(string $packageName): string
|
||||
{
|
||||
$versions = iterator_to_array(self::getVersions(self::getPackageData()));
|
||||
|
||||
if (! array_key_exists($packageName, $versions)) {
|
||||
throw new OutOfBoundsException(
|
||||
'Required package "' . $packageName . '" is not installed: check your ./vendor/composer/installed.json and/or ./composer.lock files'
|
||||
);
|
||||
}
|
||||
|
||||
return $versions[$packageName];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]
|
||||
*
|
||||
* @throws UnexpectedValueException
|
||||
*/
|
||||
private static function getPackageData(): array
|
||||
{
|
||||
$checkedPaths = [
|
||||
// The top-level project's ./vendor/composer/installed.json
|
||||
getcwd() . '/vendor/composer/installed.json',
|
||||
__DIR__ . '/../../../../composer/installed.json',
|
||||
// The top-level project's ./composer.lock
|
||||
getcwd() . '/composer.lock',
|
||||
__DIR__ . '/../../../../../composer.lock',
|
||||
// This package's composer.lock
|
||||
__DIR__ . '/../../composer.lock',
|
||||
];
|
||||
|
||||
$packageData = [];
|
||||
foreach ($checkedPaths as $path) {
|
||||
if (! file_exists($path)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$data = json_decode(file_get_contents($path), true);
|
||||
switch (basename($path)) {
|
||||
case 'installed.json':
|
||||
// composer 2.x installed.json format
|
||||
if (isset($data['packages'])) {
|
||||
$packageData[] = $data['packages'];
|
||||
} else {
|
||||
// composer 1.x installed.json format
|
||||
$packageData[] = $data;
|
||||
}
|
||||
|
||||
break;
|
||||
case 'composer.lock':
|
||||
$packageData[] = $data['packages'] + ($data['packages-dev'] ?? []);
|
||||
break;
|
||||
default:
|
||||
// intentionally left blank
|
||||
}
|
||||
}
|
||||
|
||||
if ($packageData !== []) {
|
||||
return array_merge(...$packageData);
|
||||
}
|
||||
|
||||
throw new UnexpectedValueException(sprintf(
|
||||
'PackageVersions could not locate the `vendor/composer/installed.json` or your `composer.lock` '
|
||||
. 'location. This is assumed to be in %s. If you customized your composer vendor directory and ran composer '
|
||||
. 'installation with --no-scripts, or if you deployed without the required composer files, PackageVersions '
|
||||
. 'can\'t detect installed versions.',
|
||||
json_encode($checkedPaths)
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $packageData
|
||||
*
|
||||
* @return Generator&string[]
|
||||
*
|
||||
* @psalm-return Generator<string, string>
|
||||
*/
|
||||
private static function getVersions(array $packageData): Generator
|
||||
{
|
||||
foreach ($packageData as $package) {
|
||||
yield $package['name'] => $package['version'] . '@' . (
|
||||
$package['source']['reference'] ?? $package['dist']['reference'] ?? ''
|
||||
);
|
||||
}
|
||||
|
||||
yield self::ROOT_PACKAGE_NAME => self::ROOT_PACKAGE_NAME;
|
||||
}
|
||||
}
|
||||
@@ -1,290 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PackageVersions;
|
||||
|
||||
use Composer\Composer;
|
||||
use Composer\Config;
|
||||
use Composer\EventDispatcher\EventSubscriberInterface;
|
||||
use Composer\IO\IOInterface;
|
||||
use Composer\Package\AliasPackage;
|
||||
use Composer\Package\Locker;
|
||||
use Composer\Package\PackageInterface;
|
||||
use Composer\Package\RootPackageInterface;
|
||||
use Composer\Plugin\PluginInterface;
|
||||
use Composer\Script\Event;
|
||||
use Composer\Script\ScriptEvents;
|
||||
use Generator;
|
||||
use RuntimeException;
|
||||
|
||||
use function array_key_exists;
|
||||
use function array_merge;
|
||||
use function chmod;
|
||||
use function dirname;
|
||||
use function file_exists;
|
||||
use function file_put_contents;
|
||||
use function is_writable;
|
||||
use function iterator_to_array;
|
||||
use function rename;
|
||||
use function sprintf;
|
||||
use function uniqid;
|
||||
use function var_export;
|
||||
|
||||
final class Installer implements PluginInterface, EventSubscriberInterface
|
||||
{
|
||||
private static $generatedClassTemplate = <<<'PHP'
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PackageVersions;
|
||||
|
||||
use Composer\InstalledVersions;
|
||||
use OutOfBoundsException;
|
||||
|
||||
class_exists(InstalledVersions::class);
|
||||
|
||||
/**
|
||||
* This class is generated by composer/package-versions-deprecated, specifically by
|
||||
* @see \PackageVersions\Installer
|
||||
*
|
||||
* This file is overwritten at every run of `composer install` or `composer update`.
|
||||
*
|
||||
* @deprecated in favor of the Composer\InstalledVersions class provided by Composer 2. Require composer-runtime-api:^2 to ensure it is present.
|
||||
*/
|
||||
%s
|
||||
{
|
||||
/**
|
||||
* @deprecated please use {@see self::rootPackageName()} instead.
|
||||
* This constant will be removed in version 2.0.0.
|
||||
*/
|
||||
const ROOT_PACKAGE_NAME = '%s';
|
||||
|
||||
/**
|
||||
* Array of all available composer packages.
|
||||
* Dont read this array from your calling code, but use the \PackageVersions\Versions::getVersion() method instead.
|
||||
*
|
||||
* @var array<string, string>
|
||||
* @internal
|
||||
*/
|
||||
const VERSIONS = %s;
|
||||
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-pure
|
||||
*
|
||||
* @psalm-suppress ImpureMethodCall we know that {@see InstalledVersions} interaction does not
|
||||
* cause any side effects here.
|
||||
*/
|
||||
public static function rootPackageName() : string
|
||||
{
|
||||
if (!self::composer2ApiUsable()) {
|
||||
return self::ROOT_PACKAGE_NAME;
|
||||
}
|
||||
|
||||
return InstalledVersions::getRootPackage()['name'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws OutOfBoundsException If a version cannot be located.
|
||||
*
|
||||
* @psalm-param key-of<self::VERSIONS> $packageName
|
||||
* @psalm-pure
|
||||
*
|
||||
* @psalm-suppress ImpureMethodCall we know that {@see InstalledVersions} interaction does not
|
||||
* cause any side effects here.
|
||||
*/
|
||||
public static function getVersion(string $packageName): string
|
||||
{
|
||||
if (self::composer2ApiUsable()) {
|
||||
return InstalledVersions::getPrettyVersion($packageName)
|
||||
. '@' . InstalledVersions::getReference($packageName);
|
||||
}
|
||||
|
||||
if (isset(self::VERSIONS[$packageName])) {
|
||||
return self::VERSIONS[$packageName];
|
||||
}
|
||||
|
||||
throw new OutOfBoundsException(
|
||||
'Required package "' . $packageName . '" is not installed: check your ./vendor/composer/installed.json and/or ./composer.lock files'
|
||||
);
|
||||
}
|
||||
|
||||
private static function composer2ApiUsable(): bool
|
||||
{
|
||||
if (!class_exists(InstalledVersions::class, false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (method_exists(InstalledVersions::class, 'getAllRawData')) {
|
||||
$rawData = InstalledVersions::getAllRawData();
|
||||
if (count($rawData) === 1 && count($rawData[0]) === 0) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$rawData = InstalledVersions::getRawData();
|
||||
if ($rawData === null || $rawData === []) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
PHP;
|
||||
|
||||
public function activate(Composer $composer, IOInterface $io)
|
||||
{
|
||||
// Nothing to do here, as all features are provided through event listeners
|
||||
}
|
||||
|
||||
public function deactivate(Composer $composer, IOInterface $io)
|
||||
{
|
||||
// Nothing to do here, as all features are provided through event listeners
|
||||
}
|
||||
|
||||
public function uninstall(Composer $composer, IOInterface $io)
|
||||
{
|
||||
// Nothing to do here, as all features are provided through event listeners
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [ScriptEvents::POST_AUTOLOAD_DUMP => 'dumpVersionsClass'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public static function dumpVersionsClass(Event $composerEvent)
|
||||
{
|
||||
$composer = $composerEvent->getComposer();
|
||||
$rootPackage = $composer->getPackage();
|
||||
$versions = iterator_to_array(self::getVersions($composer->getLocker(), $rootPackage));
|
||||
|
||||
if (! array_key_exists('composer/package-versions-deprecated', $versions)) {
|
||||
//plugin must be globally installed - we only want to generate versions for projects which specifically
|
||||
//require composer/package-versions-deprecated
|
||||
return;
|
||||
}
|
||||
|
||||
$versionClass = self::generateVersionsClass($rootPackage->getName(), $versions);
|
||||
|
||||
self::writeVersionClassToFile($versionClass, $composer, $composerEvent->getIO());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $versions
|
||||
*/
|
||||
private static function generateVersionsClass(string $rootPackageName, array $versions): string
|
||||
{
|
||||
return sprintf(
|
||||
self::$generatedClassTemplate,
|
||||
'fin' . 'al ' . 'cla' . 'ss ' . 'Versions', // note: workaround for regex-based code parsers :-(
|
||||
$rootPackageName,
|
||||
var_export($versions, true)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
private static function writeVersionClassToFile(string $versionClassSource, Composer $composer, IOInterface $io)
|
||||
{
|
||||
$installPath = self::locateRootPackageInstallPath($composer->getConfig(), $composer->getPackage())
|
||||
. '/src/PackageVersions/Versions.php';
|
||||
|
||||
$installDir = dirname($installPath);
|
||||
if (! file_exists($installDir)) {
|
||||
$io->write('<info>composer/package-versions-deprecated:</info> Package not found (probably scheduled for removal); generation of version class skipped.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (! is_writable($installDir)) {
|
||||
$io->write(
|
||||
sprintf(
|
||||
'<info>composer/package-versions-deprecated:</info> %s is not writable; generation of version class skipped.',
|
||||
$installDir
|
||||
)
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$io->write('<info>composer/package-versions-deprecated:</info> Generating version class...');
|
||||
|
||||
$installPathTmp = $installPath . '_' . uniqid('tmp', true);
|
||||
file_put_contents($installPathTmp, $versionClassSource);
|
||||
chmod($installPathTmp, 0664);
|
||||
rename($installPathTmp, $installPath);
|
||||
|
||||
$io->write('<info>composer/package-versions-deprecated:</info> ...done generating version class');
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
private static function locateRootPackageInstallPath(
|
||||
Config $composerConfig,
|
||||
RootPackageInterface $rootPackage
|
||||
): string {
|
||||
if (self::getRootPackageAlias($rootPackage)->getName() === 'composer/package-versions-deprecated') {
|
||||
return dirname($composerConfig->get('vendor-dir'));
|
||||
}
|
||||
|
||||
return $composerConfig->get('vendor-dir') . '/composer/package-versions-deprecated';
|
||||
}
|
||||
|
||||
private static function getRootPackageAlias(RootPackageInterface $rootPackage): PackageInterface
|
||||
{
|
||||
$package = $rootPackage;
|
||||
|
||||
while ($package instanceof AliasPackage) {
|
||||
$package = $package->getAliasOf();
|
||||
}
|
||||
|
||||
return $package;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Generator&string[]
|
||||
*
|
||||
* @psalm-return Generator<string, string>
|
||||
*/
|
||||
private static function getVersions(Locker $locker, RootPackageInterface $rootPackage): Generator
|
||||
{
|
||||
$lockData = $locker->getLockData();
|
||||
|
||||
$lockData['packages-dev'] = $lockData['packages-dev'] ?? [];
|
||||
|
||||
$packages = $lockData['packages'];
|
||||
if (getenv('COMPOSER_DEV_MODE') !== '0') {
|
||||
$packages = array_merge($packages, $lockData['packages-dev']);
|
||||
}
|
||||
foreach ($packages as $package) {
|
||||
yield $package['name'] => $package['version'] . '@' . (
|
||||
$package['source']['reference'] ?? $package['dist']['reference'] ?? ''
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($rootPackage->getReplaces() as $replace) {
|
||||
$version = $replace->getPrettyConstraint();
|
||||
if ($version === 'self.version') {
|
||||
$version = $rootPackage->getPrettyVersion();
|
||||
}
|
||||
|
||||
yield $replace->getTarget() => $version . '@' . $rootPackage->getSourceReference();
|
||||
}
|
||||
|
||||
yield $rootPackage->getName() => $rootPackage->getPrettyVersion() . '@' . $rootPackage->getSourceReference();
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PackageVersions;
|
||||
|
||||
use Composer\InstalledVersions;
|
||||
use OutOfBoundsException;
|
||||
use UnexpectedValueException;
|
||||
|
||||
class_exists(InstalledVersions::class);
|
||||
|
||||
/**
|
||||
* This is a stub class: it is in place only for scenarios where PackageVersions
|
||||
* is installed with a `--no-scripts` flag, in which scenarios the Versions class
|
||||
* is not being replaced.
|
||||
*
|
||||
* If you are reading this docBlock inside your `vendor/` dir, then this means
|
||||
* that PackageVersions didn't correctly install, and is in "fallback" mode.
|
||||
*
|
||||
* @deprecated in favor of the Composer\InstalledVersions class provided by Composer 2. Require composer-runtime-api:^2 to ensure it is present.
|
||||
*/
|
||||
final class Versions
|
||||
{
|
||||
/**
|
||||
* @deprecated please use {@see self::rootPackageName()} instead.
|
||||
* This constant will be removed in version 2.0.0.
|
||||
*/
|
||||
const ROOT_PACKAGE_NAME = 'unknown/root-package@UNKNOWN';
|
||||
|
||||
/** @internal */
|
||||
const VERSIONS = [];
|
||||
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-pure
|
||||
*
|
||||
* @psalm-suppress ImpureMethodCall we know that {@see InstalledVersions} interaction does not
|
||||
* cause any side effects here.
|
||||
*/
|
||||
public static function rootPackageName() : string
|
||||
{
|
||||
if (!class_exists(InstalledVersions::class, false) || !InstalledVersions::getRawData()) {
|
||||
return self::ROOT_PACKAGE_NAME;
|
||||
}
|
||||
|
||||
return InstalledVersions::getRootPackage()['name'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws OutOfBoundsException if a version cannot be located.
|
||||
* @throws UnexpectedValueException if the composer.lock file could not be located.
|
||||
*/
|
||||
public static function getVersion(string $packageName): string
|
||||
{
|
||||
if (!self::composer2ApiUsable()) {
|
||||
return FallbackVersions::getVersion($packageName);
|
||||
}
|
||||
|
||||
/** @psalm-suppress DeprecatedConstant */
|
||||
if ($packageName === self::ROOT_PACKAGE_NAME) {
|
||||
$rootPackage = InstalledVersions::getRootPackage();
|
||||
|
||||
return $rootPackage['pretty_version'] . '@' . $rootPackage['reference'];
|
||||
}
|
||||
|
||||
return InstalledVersions::getPrettyVersion($packageName)
|
||||
. '@' . InstalledVersions::getReference($packageName);
|
||||
}
|
||||
|
||||
private static function composer2ApiUsable(): bool
|
||||
{
|
||||
if (!class_exists(InstalledVersions::class, false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (method_exists(InstalledVersions::class, 'getAllRawData')) {
|
||||
$rawData = InstalledVersions::getAllRawData();
|
||||
if (count($rawData) === 1 && count($rawData[0]) === 0) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$rawData = InstalledVersions::getRawData();
|
||||
if ($rawData === null || $rawData === []) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
5
vendor/composer/semver/CHANGELOG.md
vendored
5
vendor/composer/semver/CHANGELOG.md
vendored
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
### [3.4.0] 2023-08-31
|
||||
|
||||
* Support larger major version numbers (#149)
|
||||
|
||||
### [3.3.2] 2022-04-01
|
||||
|
||||
* Fixed handling of non-string values (#134)
|
||||
@@ -175,6 +179,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- Namespace: `Composer\Test\Package\LinkConstraint` -> `Composer\Test\Semver\Constraint`
|
||||
* Changed: code style using php-cs-fixer.
|
||||
|
||||
[3.4.0]: https://github.com/composer/semver/compare/3.3.2...3.4.0
|
||||
[3.3.2]: https://github.com/composer/semver/compare/3.3.1...3.3.2
|
||||
[3.3.1]: https://github.com/composer/semver/compare/3.3.0...3.3.1
|
||||
[3.3.0]: https://github.com/composer/semver/compare/3.2.9...3.3.0
|
||||
|
||||
7
vendor/composer/semver/README.md
vendored
7
vendor/composer/semver/README.md
vendored
@@ -6,8 +6,9 @@ Semver (Semantic Versioning) library that offers utilities, version constraint p
|
||||
Originally written as part of [composer/composer](https://github.com/composer/composer),
|
||||
now extracted and made available as a stand-alone library.
|
||||
|
||||
[](https://github.com/composer/semver/actions)
|
||||
|
||||
[](https://github.com/composer/semver/actions/workflows/continuous-integration.yml)
|
||||
[](https://github.com/composer/semver/actions/workflows/lint.yml)
|
||||
[](https://github.com/composer/semver/actions/workflows/phpstan.yml)
|
||||
|
||||
Installation
|
||||
------------
|
||||
@@ -15,7 +16,7 @@ Installation
|
||||
Install the latest version with:
|
||||
|
||||
```bash
|
||||
$ composer require composer/semver
|
||||
composer require composer/semver
|
||||
```
|
||||
|
||||
|
||||
|
||||
2
vendor/composer/semver/composer.json
vendored
2
vendor/composer/semver/composer.json
vendored
@@ -27,7 +27,7 @@
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"irc": "irc://irc.freenode.org/composer",
|
||||
"irc": "ircs://irc.libera.chat:6697/composer",
|
||||
"issues": "https://github.com/composer/semver/issues"
|
||||
},
|
||||
"require": {
|
||||
|
||||
11
vendor/composer/semver/phpstan-baseline.neon
vendored
Normal file
11
vendor/composer/semver/phpstan-baseline.neon
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
parameters:
|
||||
ignoreErrors:
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$operator of class Composer\\\\Semver\\\\Constraint\\\\Constraint constructor expects '\\!\\='\\|'\\<'\\|'\\<\\='\\|'\\<\\>'\\|'\\='\\|'\\=\\='\\|'\\>'\\|'\\>\\=', non\\-falsy\\-string given\\.$#"
|
||||
count: 1
|
||||
path: src/VersionParser.php
|
||||
|
||||
-
|
||||
message: "#^Strict comparison using \\=\\=\\= between null and non\\-empty\\-string will always evaluate to false\\.$#"
|
||||
count: 2
|
||||
path: src/VersionParser.php
|
||||
24
vendor/composer/semver/src/VersionParser.php
vendored
24
vendor/composer/semver/src/VersionParser.php
vendored
@@ -134,15 +134,15 @@ class VersionParser
|
||||
}
|
||||
|
||||
// match classical versioning
|
||||
if (preg_match('{^v?(\d{1,5})(\.\d++)?(\.\d++)?(\.\d++)?' . self::$modifierRegex . '$}i', $version, $matches)) {
|
||||
if (preg_match('{^v?(\d{1,5}+)(\.\d++)?(\.\d++)?(\.\d++)?' . self::$modifierRegex . '$}i', $version, $matches)) {
|
||||
$version = $matches[1]
|
||||
. (!empty($matches[2]) ? $matches[2] : '.0')
|
||||
. (!empty($matches[3]) ? $matches[3] : '.0')
|
||||
. (!empty($matches[4]) ? $matches[4] : '.0');
|
||||
$index = 5;
|
||||
// match date(time) based versioning
|
||||
} elseif (preg_match('{^v?(\d{4}(?:[.:-]?\d{2}){1,6}(?:[.:-]?\d{1,3})?)' . self::$modifierRegex . '$}i', $version, $matches)) {
|
||||
$version = preg_replace('{\D}', '.', $matches[1]);
|
||||
} elseif (preg_match('{^v?(\d{4}(?:[.:-]?\d{2}){1,6}(?:[.:-]?\d{1,3}){0,2})' . self::$modifierRegex . '$}i', $version, $matches)) {
|
||||
$version = (string) preg_replace('{\D}', '.', $matches[1]);
|
||||
$index = 2;
|
||||
}
|
||||
|
||||
@@ -260,16 +260,16 @@ class VersionParser
|
||||
}
|
||||
$orGroups = array();
|
||||
|
||||
foreach ($orConstraints as $constraints) {
|
||||
$andConstraints = preg_split('{(?<!^|as|[=>< ,]) *(?<!-)[, ](?!-) *(?!,|as|$)}', $constraints);
|
||||
foreach ($orConstraints as $orConstraint) {
|
||||
$andConstraints = preg_split('{(?<!^|as|[=>< ,]) *(?<!-)[, ](?!-) *(?!,|as|$)}', $orConstraint);
|
||||
if (false === $andConstraints) {
|
||||
throw new \RuntimeException('Failed to preg_split string: '.$constraints);
|
||||
throw new \RuntimeException('Failed to preg_split string: '.$orConstraint);
|
||||
}
|
||||
if (\count($andConstraints) > 1) {
|
||||
$constraintObjects = array();
|
||||
foreach ($andConstraints as $constraint) {
|
||||
foreach ($this->parseConstraint($constraint) as $parsedConstraint) {
|
||||
$constraintObjects[] = $parsedConstraint;
|
||||
foreach ($andConstraints as $andConstraint) {
|
||||
foreach ($this->parseConstraint($andConstraint) as $parsedAndConstraint) {
|
||||
$constraintObjects[] = $parsedAndConstraint;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -285,11 +285,11 @@ class VersionParser
|
||||
$orGroups[] = $constraint;
|
||||
}
|
||||
|
||||
$constraint = MultiConstraint::create($orGroups, false);
|
||||
$parsedConstraint = MultiConstraint::create($orGroups, false);
|
||||
|
||||
$constraint->setPrettyString($prettyConstraint);
|
||||
$parsedConstraint->setPrettyString($prettyConstraint);
|
||||
|
||||
return $constraint;
|
||||
return $parsedConstraint;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2016 Marco Pivetta
|
||||
Copyright (c) 2020-2021 Doctrine Project
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
157
vendor/doctrine/deprecations/README.md
vendored
Normal file
157
vendor/doctrine/deprecations/README.md
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
# Doctrine Deprecations
|
||||
|
||||
A small (side-effect free by default) layer on top of
|
||||
`trigger_error(E_USER_DEPRECATED)` or PSR-3 logging.
|
||||
|
||||
- no side-effects by default, making it a perfect fit for libraries that don't know how the error handler works they operate under
|
||||
- options to avoid having to rely on error handlers global state by using PSR-3 logging
|
||||
- deduplicate deprecation messages to avoid excessive triggering and reduce overhead
|
||||
|
||||
We recommend to collect Deprecations using a PSR logger instead of relying on
|
||||
the global error handler.
|
||||
|
||||
## Usage from consumer perspective:
|
||||
|
||||
Enable Doctrine deprecations to be sent to a PSR3 logger:
|
||||
|
||||
```php
|
||||
\Doctrine\Deprecations\Deprecation::enableWithPsrLogger($logger);
|
||||
```
|
||||
|
||||
Enable Doctrine deprecations to be sent as `@trigger_error($message, E_USER_DEPRECATED)`
|
||||
messages by setting the `DOCTRINE_DEPRECATIONS` environment variable to `trigger`.
|
||||
Alternatively, call:
|
||||
|
||||
```php
|
||||
\Doctrine\Deprecations\Deprecation::enableWithTriggerError();
|
||||
```
|
||||
|
||||
If you only want to enable deprecation tracking, without logging or calling `trigger_error`
|
||||
then set the `DOCTRINE_DEPRECATIONS` environment variable to `track`.
|
||||
Alternatively, call:
|
||||
|
||||
```php
|
||||
\Doctrine\Deprecations\Deprecation::enableTrackingDeprecations();
|
||||
```
|
||||
|
||||
Tracking is enabled with all three modes and provides access to all triggered
|
||||
deprecations and their individual count:
|
||||
|
||||
```php
|
||||
$deprecations = \Doctrine\Deprecations\Deprecation::getTriggeredDeprecations();
|
||||
|
||||
foreach ($deprecations as $identifier => $count) {
|
||||
echo $identifier . " was triggered " . $count . " times\n";
|
||||
}
|
||||
```
|
||||
|
||||
### Suppressing Specific Deprecations
|
||||
|
||||
Disable triggering about specific deprecations:
|
||||
|
||||
```php
|
||||
\Doctrine\Deprecations\Deprecation::ignoreDeprecations("https://link/to/deprecations-description-identifier");
|
||||
```
|
||||
|
||||
Disable all deprecations from a package
|
||||
|
||||
```php
|
||||
\Doctrine\Deprecations\Deprecation::ignorePackage("doctrine/orm");
|
||||
```
|
||||
|
||||
### Other Operations
|
||||
|
||||
When used within PHPUnit or other tools that could collect multiple instances of the same deprecations
|
||||
the deduplication can be disabled:
|
||||
|
||||
```php
|
||||
\Doctrine\Deprecations\Deprecation::withoutDeduplication();
|
||||
```
|
||||
|
||||
Disable deprecation tracking again:
|
||||
|
||||
```php
|
||||
\Doctrine\Deprecations\Deprecation::disable();
|
||||
```
|
||||
|
||||
## Usage from a library/producer perspective:
|
||||
|
||||
When you want to unconditionally trigger a deprecation even when called
|
||||
from the library itself then the `trigger` method is the way to go:
|
||||
|
||||
```php
|
||||
\Doctrine\Deprecations\Deprecation::trigger(
|
||||
"doctrine/orm",
|
||||
"https://link/to/deprecations-description",
|
||||
"message"
|
||||
);
|
||||
```
|
||||
|
||||
If variable arguments are provided at the end, they are used with `sprintf` on
|
||||
the message.
|
||||
|
||||
```php
|
||||
\Doctrine\Deprecations\Deprecation::trigger(
|
||||
"doctrine/orm",
|
||||
"https://github.com/doctrine/orm/issue/1234",
|
||||
"message %s %d",
|
||||
"foo",
|
||||
1234
|
||||
);
|
||||
```
|
||||
|
||||
When you want to trigger a deprecation only when it is called by a function
|
||||
outside of the current package, but not trigger when the package itself is the cause,
|
||||
then use:
|
||||
|
||||
```php
|
||||
\Doctrine\Deprecations\Deprecation::triggerIfCalledFromOutside(
|
||||
"doctrine/orm",
|
||||
"https://link/to/deprecations-description",
|
||||
"message"
|
||||
);
|
||||
```
|
||||
|
||||
Based on the issue link each deprecation message is only triggered once per
|
||||
request.
|
||||
|
||||
A limited stacktrace is included in the deprecation message to find the
|
||||
offending location.
|
||||
|
||||
Note: A producer/library should never call `Deprecation::enableWith` methods
|
||||
and leave the decision how to handle deprecations to application and
|
||||
frameworks.
|
||||
|
||||
## Usage in PHPUnit tests
|
||||
|
||||
There is a `VerifyDeprecations` trait that you can use to make assertions on
|
||||
the occurrence of deprecations within a test.
|
||||
|
||||
```php
|
||||
use Doctrine\Deprecations\PHPUnit\VerifyDeprecations;
|
||||
|
||||
class MyTest extends TestCase
|
||||
{
|
||||
use VerifyDeprecations;
|
||||
|
||||
public function testSomethingDeprecation()
|
||||
{
|
||||
$this->expectDeprecationWithIdentifier('https://github.com/doctrine/orm/issue/1234');
|
||||
|
||||
triggerTheCodeWithDeprecation();
|
||||
}
|
||||
|
||||
public function testSomethingDeprecationFixed()
|
||||
{
|
||||
$this->expectNoDeprecationWithIdentifier('https://github.com/doctrine/orm/issue/1234');
|
||||
|
||||
triggerTheCodeWithoutDeprecation();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## What is a deprecation identifier?
|
||||
|
||||
An identifier for deprecations is just a link to any resource, most often a
|
||||
Github Issue or Pull Request explaining the deprecation and potentially its
|
||||
alternative.
|
||||
38
vendor/doctrine/deprecations/composer.json
vendored
Normal file
38
vendor/doctrine/deprecations/composer.json
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "doctrine/deprecations",
|
||||
"description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.",
|
||||
"license": "MIT",
|
||||
"type": "library",
|
||||
"homepage": "https://www.doctrine-project.org/",
|
||||
"require": {
|
||||
"php": "^7.1 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/coding-standard": "^9",
|
||||
"phpstan/phpstan": "1.4.10 || 1.10.15",
|
||||
"phpstan/phpstan-phpunit": "^1.0",
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
|
||||
"psalm/plugin-phpunit": "0.18.4",
|
||||
"psr/log": "^1 || ^2 || ^3",
|
||||
"vimeo/psalm": "4.30.0 || 5.12.0"
|
||||
},
|
||||
"suggest": {
|
||||
"psr/log": "Allows logging deprecations via PSR-3 logger implementation"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"DeprecationTests\\": "test_fixtures/src",
|
||||
"Doctrine\\Foo\\": "test_fixtures/vendor/doctrine/foo"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": true
|
||||
}
|
||||
}
|
||||
}
|
||||
312
vendor/doctrine/deprecations/lib/Doctrine/Deprecations/Deprecation.php
vendored
Normal file
312
vendor/doctrine/deprecations/lib/Doctrine/Deprecations/Deprecation.php
vendored
Normal file
@@ -0,0 +1,312 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Deprecations;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
use function array_key_exists;
|
||||
use function array_reduce;
|
||||
use function assert;
|
||||
use function debug_backtrace;
|
||||
use function sprintf;
|
||||
use function strpos;
|
||||
use function strrpos;
|
||||
use function substr;
|
||||
use function trigger_error;
|
||||
|
||||
use const DEBUG_BACKTRACE_IGNORE_ARGS;
|
||||
use const DIRECTORY_SEPARATOR;
|
||||
use const E_USER_DEPRECATED;
|
||||
|
||||
/**
|
||||
* Manages Deprecation logging in different ways.
|
||||
*
|
||||
* By default triggered exceptions are not logged.
|
||||
*
|
||||
* To enable different deprecation logging mechanisms you can call the
|
||||
* following methods:
|
||||
*
|
||||
* - Minimal collection of deprecations via getTriggeredDeprecations()
|
||||
* \Doctrine\Deprecations\Deprecation::enableTrackingDeprecations();
|
||||
*
|
||||
* - Uses @trigger_error with E_USER_DEPRECATED
|
||||
* \Doctrine\Deprecations\Deprecation::enableWithTriggerError();
|
||||
*
|
||||
* - Sends deprecation messages via a PSR-3 logger
|
||||
* \Doctrine\Deprecations\Deprecation::enableWithPsrLogger($logger);
|
||||
*
|
||||
* Packages that trigger deprecations should use the `trigger()` or
|
||||
* `triggerIfCalledFromOutside()` methods.
|
||||
*/
|
||||
class Deprecation
|
||||
{
|
||||
private const TYPE_NONE = 0;
|
||||
private const TYPE_TRACK_DEPRECATIONS = 1;
|
||||
private const TYPE_TRIGGER_ERROR = 2;
|
||||
private const TYPE_PSR_LOGGER = 4;
|
||||
|
||||
/** @var int-mask-of<self::TYPE_*>|null */
|
||||
private static $type;
|
||||
|
||||
/** @var LoggerInterface|null */
|
||||
private static $logger;
|
||||
|
||||
/** @var array<string,bool> */
|
||||
private static $ignoredPackages = [];
|
||||
|
||||
/** @var array<string,int> */
|
||||
private static $triggeredDeprecations = [];
|
||||
|
||||
/** @var array<string,bool> */
|
||||
private static $ignoredLinks = [];
|
||||
|
||||
/** @var bool */
|
||||
private static $deduplication = true;
|
||||
|
||||
/**
|
||||
* Trigger a deprecation for the given package and identfier.
|
||||
*
|
||||
* The link should point to a Github issue or Wiki entry detailing the
|
||||
* deprecation. It is additionally used to de-duplicate the trigger of the
|
||||
* same deprecation during a request.
|
||||
*
|
||||
* @param float|int|string $args
|
||||
*/
|
||||
public static function trigger(string $package, string $link, string $message, ...$args): void
|
||||
{
|
||||
$type = self::$type ?? self::getTypeFromEnv();
|
||||
|
||||
if ($type === self::TYPE_NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset(self::$ignoredLinks[$link])) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (array_key_exists($link, self::$triggeredDeprecations)) {
|
||||
self::$triggeredDeprecations[$link]++;
|
||||
} else {
|
||||
self::$triggeredDeprecations[$link] = 1;
|
||||
}
|
||||
|
||||
if (self::$deduplication === true && self::$triggeredDeprecations[$link] > 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset(self::$ignoredPackages[$package])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
|
||||
|
||||
$message = sprintf($message, ...$args);
|
||||
|
||||
self::delegateTriggerToBackend($message, $backtrace, $link, $package);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger a deprecation for the given package and identifier when called from outside.
|
||||
*
|
||||
* "Outside" means we assume that $package is currently installed as a
|
||||
* dependency and the caller is not a file in that package. When $package
|
||||
* is installed as a root package then deprecations triggered from the
|
||||
* tests folder are also considered "outside".
|
||||
*
|
||||
* This deprecation method assumes that you are using Composer to install
|
||||
* the dependency and are using the default /vendor/ folder and not a
|
||||
* Composer plugin to change the install location. The assumption is also
|
||||
* that $package is the exact composer packge name.
|
||||
*
|
||||
* Compared to {@link trigger()} this method causes some overhead when
|
||||
* deprecation tracking is enabled even during deduplication, because it
|
||||
* needs to call {@link debug_backtrace()}
|
||||
*
|
||||
* @param float|int|string $args
|
||||
*/
|
||||
public static function triggerIfCalledFromOutside(string $package, string $link, string $message, ...$args): void
|
||||
{
|
||||
$type = self::$type ?? self::getTypeFromEnv();
|
||||
|
||||
if ($type === self::TYPE_NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
|
||||
|
||||
// first check that the caller is not from a tests folder, in which case we always let deprecations pass
|
||||
if (isset($backtrace[1]['file'], $backtrace[0]['file']) && strpos($backtrace[1]['file'], DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR) === false) {
|
||||
$path = DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . $package . DIRECTORY_SEPARATOR;
|
||||
|
||||
if (strpos($backtrace[0]['file'], $path) === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (strpos($backtrace[1]['file'], $path) !== false) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset(self::$ignoredLinks[$link])) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (array_key_exists($link, self::$triggeredDeprecations)) {
|
||||
self::$triggeredDeprecations[$link]++;
|
||||
} else {
|
||||
self::$triggeredDeprecations[$link] = 1;
|
||||
}
|
||||
|
||||
if (self::$deduplication === true && self::$triggeredDeprecations[$link] > 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset(self::$ignoredPackages[$package])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$message = sprintf($message, ...$args);
|
||||
|
||||
self::delegateTriggerToBackend($message, $backtrace, $link, $package);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<array{function: string, line?: int, file?: string, class?: class-string, type?: string, args?: mixed[], object?: object}> $backtrace
|
||||
*/
|
||||
private static function delegateTriggerToBackend(string $message, array $backtrace, string $link, string $package): void
|
||||
{
|
||||
$type = self::$type ?? self::getTypeFromEnv();
|
||||
|
||||
if (($type & self::TYPE_PSR_LOGGER) > 0) {
|
||||
$context = [
|
||||
'file' => $backtrace[0]['file'] ?? null,
|
||||
'line' => $backtrace[0]['line'] ?? null,
|
||||
'package' => $package,
|
||||
'link' => $link,
|
||||
];
|
||||
|
||||
assert(self::$logger !== null);
|
||||
|
||||
self::$logger->notice($message, $context);
|
||||
}
|
||||
|
||||
if (! (($type & self::TYPE_TRIGGER_ERROR) > 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$message .= sprintf(
|
||||
' (%s:%d called by %s:%d, %s, package %s)',
|
||||
self::basename($backtrace[0]['file'] ?? 'native code'),
|
||||
$backtrace[0]['line'] ?? 0,
|
||||
self::basename($backtrace[1]['file'] ?? 'native code'),
|
||||
$backtrace[1]['line'] ?? 0,
|
||||
$link,
|
||||
$package
|
||||
);
|
||||
|
||||
@trigger_error($message, E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
/**
|
||||
* A non-local-aware version of PHPs basename function.
|
||||
*/
|
||||
private static function basename(string $filename): string
|
||||
{
|
||||
$pos = strrpos($filename, DIRECTORY_SEPARATOR);
|
||||
|
||||
if ($pos === false) {
|
||||
return $filename;
|
||||
}
|
||||
|
||||
return substr($filename, $pos + 1);
|
||||
}
|
||||
|
||||
public static function enableTrackingDeprecations(): void
|
||||
{
|
||||
self::$type = self::$type ?? 0;
|
||||
self::$type |= self::TYPE_TRACK_DEPRECATIONS;
|
||||
}
|
||||
|
||||
public static function enableWithTriggerError(): void
|
||||
{
|
||||
self::$type = self::$type ?? 0;
|
||||
self::$type |= self::TYPE_TRIGGER_ERROR;
|
||||
}
|
||||
|
||||
public static function enableWithPsrLogger(LoggerInterface $logger): void
|
||||
{
|
||||
self::$type = self::$type ?? 0;
|
||||
self::$type |= self::TYPE_PSR_LOGGER;
|
||||
self::$logger = $logger;
|
||||
}
|
||||
|
||||
public static function withoutDeduplication(): void
|
||||
{
|
||||
self::$deduplication = false;
|
||||
}
|
||||
|
||||
public static function disable(): void
|
||||
{
|
||||
self::$type = self::TYPE_NONE;
|
||||
self::$logger = null;
|
||||
self::$deduplication = true;
|
||||
self::$ignoredLinks = [];
|
||||
|
||||
foreach (self::$triggeredDeprecations as $link => $count) {
|
||||
self::$triggeredDeprecations[$link] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static function ignorePackage(string $packageName): void
|
||||
{
|
||||
self::$ignoredPackages[$packageName] = true;
|
||||
}
|
||||
|
||||
public static function ignoreDeprecations(string ...$links): void
|
||||
{
|
||||
foreach ($links as $link) {
|
||||
self::$ignoredLinks[$link] = true;
|
||||
}
|
||||
}
|
||||
|
||||
public static function getUniqueTriggeredDeprecationsCount(): int
|
||||
{
|
||||
return array_reduce(self::$triggeredDeprecations, static function (int $carry, int $count) {
|
||||
return $carry + $count;
|
||||
}, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns each triggered deprecation link identifier and the amount of occurrences.
|
||||
*
|
||||
* @return array<string,int>
|
||||
*/
|
||||
public static function getTriggeredDeprecations(): array
|
||||
{
|
||||
return self::$triggeredDeprecations;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int-mask-of<self::TYPE_*>
|
||||
*/
|
||||
private static function getTypeFromEnv(): int
|
||||
{
|
||||
switch ($_SERVER['DOCTRINE_DEPRECATIONS'] ?? $_ENV['DOCTRINE_DEPRECATIONS'] ?? null) {
|
||||
case 'trigger':
|
||||
self::$type = self::TYPE_TRIGGER_ERROR;
|
||||
break;
|
||||
|
||||
case 'track':
|
||||
self::$type = self::TYPE_TRACK_DEPRECATIONS;
|
||||
break;
|
||||
|
||||
default:
|
||||
self::$type = self::TYPE_NONE;
|
||||
break;
|
||||
}
|
||||
|
||||
return self::$type;
|
||||
}
|
||||
}
|
||||
66
vendor/doctrine/deprecations/lib/Doctrine/Deprecations/PHPUnit/VerifyDeprecations.php
vendored
Normal file
66
vendor/doctrine/deprecations/lib/Doctrine/Deprecations/PHPUnit/VerifyDeprecations.php
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Deprecations\PHPUnit;
|
||||
|
||||
use Doctrine\Deprecations\Deprecation;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
trait VerifyDeprecations
|
||||
{
|
||||
/** @var array<string,int> */
|
||||
private $doctrineDeprecationsExpectations = [];
|
||||
|
||||
/** @var array<string,int> */
|
||||
private $doctrineNoDeprecationsExpectations = [];
|
||||
|
||||
public function expectDeprecationWithIdentifier(string $identifier): void
|
||||
{
|
||||
$this->doctrineDeprecationsExpectations[$identifier] = Deprecation::getTriggeredDeprecations()[$identifier] ?? 0;
|
||||
}
|
||||
|
||||
public function expectNoDeprecationWithIdentifier(string $identifier): void
|
||||
{
|
||||
$this->doctrineNoDeprecationsExpectations[$identifier] = Deprecation::getTriggeredDeprecations()[$identifier] ?? 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @before
|
||||
*/
|
||||
public function enableDeprecationTracking(): void
|
||||
{
|
||||
Deprecation::enableTrackingDeprecations();
|
||||
}
|
||||
|
||||
/**
|
||||
* @after
|
||||
*/
|
||||
public function verifyDeprecationsAreTriggered(): void
|
||||
{
|
||||
foreach ($this->doctrineDeprecationsExpectations as $identifier => $expectation) {
|
||||
$actualCount = Deprecation::getTriggeredDeprecations()[$identifier] ?? 0;
|
||||
|
||||
$this->assertTrue(
|
||||
$actualCount > $expectation,
|
||||
sprintf(
|
||||
"Expected deprecation with identifier '%s' was not triggered by code executed in test.",
|
||||
$identifier
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($this->doctrineNoDeprecationsExpectations as $identifier => $expectation) {
|
||||
$actualCount = Deprecation::getTriggeredDeprecations()[$identifier] ?? 0;
|
||||
|
||||
$this->assertTrue(
|
||||
$actualCount === $expectation,
|
||||
sprintf(
|
||||
"Expected deprecation with identifier '%s' was triggered by code executed in test, but expected not to.",
|
||||
$identifier
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
22
vendor/doctrine/deprecations/phpcs.xml
vendored
Normal file
22
vendor/doctrine/deprecations/phpcs.xml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0"?>
|
||||
<ruleset>
|
||||
<arg name="basepath" value="."/>
|
||||
<arg name="extensions" value="php"/>
|
||||
<arg name="parallel" value="80"/>
|
||||
<arg name="cache" value=".phpcs-cache"/>
|
||||
<arg name="colors"/>
|
||||
|
||||
<!-- Ignore warnings, show progress of the run and show sniff names -->
|
||||
<arg value="nps"/>
|
||||
|
||||
<config name="php_version" value="70100"/>
|
||||
|
||||
<!-- Directories to be checked -->
|
||||
<file>lib</file>
|
||||
<file>tests</file>
|
||||
|
||||
<!-- Include full Doctrine Coding Standard -->
|
||||
<rule ref="Doctrine">
|
||||
<exclude name="SlevomatCodingStandard.TypeHints.PropertyTypeHint.MissingNativeTypeHint" />
|
||||
</rule>
|
||||
</ruleset>
|
||||
9
vendor/doctrine/deprecations/phpstan.neon
vendored
Normal file
9
vendor/doctrine/deprecations/phpstan.neon
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
parameters:
|
||||
level: 6
|
||||
paths:
|
||||
- lib
|
||||
- tests
|
||||
|
||||
includes:
|
||||
- vendor/phpstan/phpstan-phpunit/extension.neon
|
||||
- vendor/phpstan/phpstan-phpunit/rules.neon
|
||||
30
vendor/doctrine/deprecations/psalm.xml
vendored
Normal file
30
vendor/doctrine/deprecations/psalm.xml
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0"?>
|
||||
<psalm
|
||||
errorLevel="1"
|
||||
resolveFromConfigFile="true"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="https://getpsalm.org/schema/config"
|
||||
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
|
||||
findUnusedBaselineEntry="true"
|
||||
findUnusedCode="false"
|
||||
>
|
||||
<projectFiles>
|
||||
<directory name="lib/Doctrine/Deprecations" />
|
||||
<directory name="tests/Doctrine/Deprecations" />
|
||||
<ignoreFiles>
|
||||
<directory name="vendor" />
|
||||
</ignoreFiles>
|
||||
</projectFiles>
|
||||
<plugins>
|
||||
<pluginClass class="Psalm\PhpUnitPlugin\Plugin"/>
|
||||
</plugins>
|
||||
<issueHandlers>
|
||||
<DeprecatedMethod>
|
||||
<errorLevel type="suppress">
|
||||
<!-- Remove when dropping support for PHPUnit 9.6 -->
|
||||
<referencedMethod name="PHPUnit\Framework\TestCase::expectDeprecation"/>
|
||||
<referencedMethod name="PHPUnit\Framework\TestCase::expectDeprecationMessage"/>
|
||||
</errorLevel>
|
||||
</DeprecatedMethod>
|
||||
</issueHandlers>
|
||||
</psalm>
|
||||
46
vendor/netresearch/jsonmapper/.github/workflows/test.yml
vendored
Normal file
46
vendor/netresearch/jsonmapper/.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
name: JsonMapper tests
|
||||
on: [push, workflow_dispatch]
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions:
|
||||
- '7.1'
|
||||
- '7.2'
|
||||
- '7.3'
|
||||
- '7.4'
|
||||
- '8.0'
|
||||
- '8.1'
|
||||
- '8.2'
|
||||
name: PHP ${{ matrix.php-versions }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
tools: composer
|
||||
coverage: xdebug
|
||||
|
||||
- name: Get composer cache directory
|
||||
id: composer-cache
|
||||
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-composer-${{ matrix.php-versions }}-${{ hashFiles('**/composer.lock') }}
|
||||
restore-keys: ${{ runner.os }}-composer-${{ matrix.php-versions }}-
|
||||
|
||||
- name: Install dependencies
|
||||
run: composer install --no-interaction --prefer-dist
|
||||
|
||||
- name: Run unit tests
|
||||
run: XDEBUG_MODE=coverage ./vendor/bin/phpunit --coverage-text
|
||||
|
||||
- name: Check codestyle
|
||||
run: ./vendor/bin/phpcs --standard=PEAR src/
|
||||
70
vendor/netresearch/jsonmapper/src/JsonMapper.php
vendored
70
vendor/netresearch/jsonmapper/src/JsonMapper.php
vendored
@@ -75,7 +75,7 @@ class JsonMapper
|
||||
public $bStrictNullTypes = true;
|
||||
|
||||
/**
|
||||
* Allow mapping of private and proteted properties.
|
||||
* Allow mapping of private and protected properties.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
@@ -131,8 +131,8 @@ class JsonMapper
|
||||
/**
|
||||
* Map data all data in $json into the given $object instance.
|
||||
*
|
||||
* @param object|array $json JSON object structure from json_decode()
|
||||
* @param object $object Object to map $json data into
|
||||
* @param object|array $json JSON object structure from json_decode()
|
||||
* @param object|class-string $object Object to map $json data into
|
||||
*
|
||||
* @return mixed Mapped object is returned.
|
||||
* @see mapArray()
|
||||
@@ -145,13 +145,18 @@ class JsonMapper
|
||||
. ', ' . gettype($json) . ' given.'
|
||||
);
|
||||
}
|
||||
if (!is_object($object)) {
|
||||
if (!is_object($object) && (!is_string($object) || !class_exists($object))) {
|
||||
throw new InvalidArgumentException(
|
||||
'JsonMapper::map() requires second argument to be an object'
|
||||
'JsonMapper::map() requires second argument to '
|
||||
. 'be an object or existing class name'
|
||||
. ', ' . gettype($object) . ' given.'
|
||||
);
|
||||
}
|
||||
|
||||
if (is_string($object)) {
|
||||
$object = $this->createInstance($object);
|
||||
}
|
||||
|
||||
$strClassName = get_class($object);
|
||||
$rc = new ReflectionClass($object);
|
||||
$strNs = $rc->getNamespaceName();
|
||||
@@ -177,10 +182,15 @@ class JsonMapper
|
||||
. ' in object of type ' . $strClassName
|
||||
);
|
||||
} else if ($this->undefinedPropertyHandler !== null) {
|
||||
call_user_func(
|
||||
$undefinedPropertyKey = call_user_func(
|
||||
$this->undefinedPropertyHandler,
|
||||
$object, $key, $jvalue
|
||||
);
|
||||
|
||||
if (is_string($undefinedPropertyKey)) {
|
||||
list($hasProperty, $accessor, $type, $isNullable)
|
||||
= $this->inspectProperty($rc, $undefinedPropertyKey);
|
||||
}
|
||||
} else {
|
||||
$this->log(
|
||||
'info',
|
||||
@@ -188,7 +198,10 @@ class JsonMapper
|
||||
array('property' => $key, 'class' => $strClassName)
|
||||
);
|
||||
}
|
||||
continue;
|
||||
|
||||
if (!$hasProperty) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ($accessor === null) {
|
||||
@@ -229,7 +242,9 @@ class JsonMapper
|
||||
} else if ($this->isObjectOfSameType($type, $jvalue)) {
|
||||
$this->setProperty($object, $accessor, $jvalue);
|
||||
continue;
|
||||
} else if ($this->isSimpleType($type)) {
|
||||
} else if ($this->isSimpleType($type)
|
||||
&& !(is_array($jvalue) && $this->hasVariadicArrayType($accessor))
|
||||
) {
|
||||
if ($type === 'string' && is_object($jvalue)) {
|
||||
throw new JsonMapper_Exception(
|
||||
'JSON property "' . $key . '" in class "'
|
||||
@@ -268,8 +283,11 @@ class JsonMapper
|
||||
} else {
|
||||
$array = $this->createInstance($proptype, false, $jvalue);
|
||||
}
|
||||
} else if (is_array($jvalue) && $this->hasVariadicArrayType($accessor)) {
|
||||
$array = array();
|
||||
$subtype = $type;
|
||||
} else {
|
||||
if (is_a($type, 'ArrayObject', true)) {
|
||||
if (is_a($type, 'ArrayAccess', true)) {
|
||||
$array = $this->createInstance($type, false, $jvalue);
|
||||
}
|
||||
}
|
||||
@@ -625,6 +643,8 @@ class JsonMapper
|
||||
}
|
||||
if ($accessor instanceof ReflectionProperty) {
|
||||
$accessor->setValue($object, $value);
|
||||
} else if (is_array($value) && $this->hasVariadicArrayType($accessor)) {
|
||||
$accessor->invoke($object, ...$value);
|
||||
} else {
|
||||
//setter method
|
||||
$accessor->invoke($object, $value);
|
||||
@@ -647,6 +667,12 @@ class JsonMapper
|
||||
$class, $useParameter = false, $jvalue = null
|
||||
) {
|
||||
if ($useParameter) {
|
||||
if (PHP_VERSION_ID >= 80100
|
||||
&& is_subclass_of($class, \BackedEnum::class)
|
||||
) {
|
||||
return $class::from($jvalue);
|
||||
}
|
||||
|
||||
return new $class($jvalue);
|
||||
} else {
|
||||
$reflectClass = new ReflectionClass($class);
|
||||
@@ -758,6 +784,32 @@ class JsonMapper
|
||||
return substr($strType, -2) === '[]';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if accessor is a method and has only one parameter
|
||||
* which is variadic.
|
||||
*
|
||||
* @param ReflectionMethod|ReflectionProperty|null $accessor accessor
|
||||
* to set value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function hasVariadicArrayType($accessor)
|
||||
{
|
||||
if (!$accessor instanceof ReflectionMethod) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$parameters = $accessor->getParameters();
|
||||
|
||||
if (count($parameters) !== 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$parameter = $parameters[0];
|
||||
|
||||
return $parameter->isVariadic();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given type is nullable
|
||||
*
|
||||
|
||||
2
vendor/nikic/php-parser/grammar/php5.y
vendored
2
vendor/nikic/php-parser/grammar/php5.y
vendored
@@ -1008,7 +1008,7 @@ array_pair:
|
||||
| expr { $$ = Expr\ArrayItem[$1, null, false]; }
|
||||
| expr T_DOUBLE_ARROW ampersand variable { $$ = Expr\ArrayItem[$4, $1, true]; }
|
||||
| ampersand variable { $$ = Expr\ArrayItem[$2, null, true]; }
|
||||
| T_ELLIPSIS expr { $$ = Expr\ArrayItem[$2, null, false, attributes(), true]; }
|
||||
| T_ELLIPSIS expr { $$ = new Expr\ArrayItem($2, null, false, attributes(), true); }
|
||||
;
|
||||
|
||||
encaps_list:
|
||||
|
||||
16
vendor/nikic/php-parser/grammar/php7.y
vendored
16
vendor/nikic/php-parser/grammar/php7.y
vendored
@@ -221,7 +221,10 @@ non_empty_class_const_list:
|
||||
;
|
||||
|
||||
class_const:
|
||||
identifier_maybe_reserved '=' expr { $$ = Node\Const_[$1, $3]; }
|
||||
T_STRING '=' expr
|
||||
{ $$ = Node\Const_[new Node\Identifier($1, stackAttributes(#1)), $3]; }
|
||||
| semi_reserved '=' expr
|
||||
{ $$ = Node\Const_[new Node\Identifier($1, stackAttributes(#1)), $3]; }
|
||||
;
|
||||
|
||||
inner_statement_list_ex:
|
||||
@@ -722,6 +725,9 @@ class_statement:
|
||||
| optional_attributes method_modifiers T_CONST class_const_list semi
|
||||
{ $$ = new Stmt\ClassConst($4, $2, attributes(), $1);
|
||||
$this->checkClassConst($$, #2); }
|
||||
| optional_attributes method_modifiers T_CONST type_expr class_const_list semi
|
||||
{ $$ = new Stmt\ClassConst($5, $2, attributes(), $1, $4);
|
||||
$this->checkClassConst($$, #2); }
|
||||
| optional_attributes method_modifiers T_FUNCTION optional_ref identifier_maybe_reserved '(' parameter_list ')'
|
||||
optional_return_type method_body
|
||||
{ $$ = Stmt\ClassMethod[$5, ['type' => $2, 'byRef' => $4, 'params' => $7, 'returnType' => $9, 'stmts' => $10, 'attrGroups' => $1]];
|
||||
@@ -943,8 +949,8 @@ expr:
|
||||
;
|
||||
|
||||
anonymous_class:
|
||||
optional_attributes T_CLASS ctor_arguments extends_from implements_list '{' class_statement_list '}'
|
||||
{ $$ = array(Stmt\Class_[null, ['type' => 0, 'extends' => $4, 'implements' => $5, 'stmts' => $7, 'attrGroups' => $1]], $3);
|
||||
optional_attributes class_entry_type ctor_arguments extends_from implements_list '{' class_statement_list '}'
|
||||
{ $$ = array(Stmt\Class_[null, ['type' => $2, 'extends' => $4, 'implements' => $5, 'stmts' => $7, 'attrGroups' => $1]], $3);
|
||||
$this->checkClass($$[0], -1); }
|
||||
;
|
||||
|
||||
@@ -1040,6 +1046,8 @@ constant:
|
||||
class_constant:
|
||||
class_name_or_var T_PAAMAYIM_NEKUDOTAYIM identifier_maybe_reserved
|
||||
{ $$ = Expr\ClassConstFetch[$1, $3]; }
|
||||
| class_name_or_var T_PAAMAYIM_NEKUDOTAYIM '{' expr '}'
|
||||
{ $$ = Expr\ClassConstFetch[$1, $4]; }
|
||||
/* We interpret an isolated FOO:: as an unfinished class constant fetch. It could also be
|
||||
an unfinished static property fetch or unfinished scoped call. */
|
||||
| class_name_or_var T_PAAMAYIM_NEKUDOTAYIM error
|
||||
@@ -1194,7 +1202,7 @@ array_pair:
|
||||
| expr T_DOUBLE_ARROW expr { $$ = Expr\ArrayItem[$3, $1, false]; }
|
||||
| expr T_DOUBLE_ARROW ampersand variable { $$ = Expr\ArrayItem[$4, $1, true]; }
|
||||
| expr T_DOUBLE_ARROW list_expr { $$ = Expr\ArrayItem[$3, $1, false]; }
|
||||
| T_ELLIPSIS expr { $$ = Expr\ArrayItem[$2, null, false, attributes(), true]; }
|
||||
| T_ELLIPSIS expr { $$ = new Expr\ArrayItem($2, null, false, attributes(), true); }
|
||||
| /* empty */ { $$ = null; }
|
||||
;
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ class ClassConst implements PhpParser\Builder
|
||||
|
||||
/** @var Node\AttributeGroup[] */
|
||||
protected $attributeGroups = [];
|
||||
/** @var Identifier|Node\Name|Node\ComplexType */
|
||||
protected $type;
|
||||
|
||||
/**
|
||||
* Creates a class constant builder
|
||||
@@ -116,6 +118,19 @@ class ClassConst implements PhpParser\Builder
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the constant type.
|
||||
*
|
||||
* @param string|Node\Name|Identifier|Node\ComplexType $type
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setType($type) {
|
||||
$this->type = BuilderHelpers::normalizeType($type);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the built class node.
|
||||
*
|
||||
@@ -126,7 +141,8 @@ class ClassConst implements PhpParser\Builder
|
||||
$this->constants,
|
||||
$this->flags,
|
||||
$this->attributes,
|
||||
$this->attributeGroups
|
||||
$this->attributeGroups,
|
||||
$this->type
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ class Param implements PhpParser\Builder
|
||||
|
||||
protected $variadic = false;
|
||||
|
||||
protected $flags = 0;
|
||||
|
||||
/** @var Node\AttributeGroup[] */
|
||||
protected $attributeGroups = [];
|
||||
|
||||
@@ -95,6 +97,50 @@ class Param implements PhpParser\Builder
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the (promoted) parameter public.
|
||||
*
|
||||
* @return $this The builder instance (for fluid interface)
|
||||
*/
|
||||
public function makePublic() {
|
||||
$this->flags = BuilderHelpers::addModifier($this->flags, Node\Stmt\Class_::MODIFIER_PUBLIC);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the (promoted) parameter protected.
|
||||
*
|
||||
* @return $this The builder instance (for fluid interface)
|
||||
*/
|
||||
public function makeProtected() {
|
||||
$this->flags = BuilderHelpers::addModifier($this->flags, Node\Stmt\Class_::MODIFIER_PROTECTED);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the (promoted) parameter private.
|
||||
*
|
||||
* @return $this The builder instance (for fluid interface)
|
||||
*/
|
||||
public function makePrivate() {
|
||||
$this->flags = BuilderHelpers::addModifier($this->flags, Node\Stmt\Class_::MODIFIER_PRIVATE);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the (promoted) parameter readonly.
|
||||
*
|
||||
* @return $this The builder instance (for fluid interface)
|
||||
*/
|
||||
public function makeReadonly() {
|
||||
$this->flags = BuilderHelpers::addModifier($this->flags, Node\Stmt\Class_::MODIFIER_READONLY);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an attribute group.
|
||||
*
|
||||
@@ -116,7 +162,7 @@ class Param implements PhpParser\Builder
|
||||
public function getNode() : Node {
|
||||
return new Node\Param(
|
||||
new Node\Expr\Variable($this->name),
|
||||
$this->default, $this->type, $this->byRef, $this->variadic, [], 0, $this->attributeGroups
|
||||
$this->default, $this->type, $this->byRef, $this->variadic, [], $this->flags, $this->attributeGroups
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,15 +349,15 @@ class BuilderFactory
|
||||
/**
|
||||
* Creates a class constant fetch node.
|
||||
*
|
||||
* @param string|Name|Expr $class Class name
|
||||
* @param string|Identifier $name Constant name
|
||||
* @param string|Name|Expr $class Class name
|
||||
* @param string|Identifier|Expr $name Constant name
|
||||
*
|
||||
* @return Expr\ClassConstFetch
|
||||
*/
|
||||
public function classConstFetch($class, $name): Expr\ClassConstFetch {
|
||||
return new Expr\ClassConstFetch(
|
||||
BuilderHelpers::normalizeNameOrExpr($class),
|
||||
BuilderHelpers::normalizeIdentifier($name)
|
||||
BuilderHelpers::normalizeIdentifierOrExpr($name)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ class PrintableNewAnonClassNode extends Expr
|
||||
{
|
||||
/** @var Node\AttributeGroup[] PHP attribute groups */
|
||||
public $attrGroups;
|
||||
/** @var int Modifiers */
|
||||
public $flags;
|
||||
/** @var Node\Arg[] Arguments */
|
||||
public $args;
|
||||
/** @var null|Node\Name Name of extended class */
|
||||
@@ -29,11 +31,12 @@ class PrintableNewAnonClassNode extends Expr
|
||||
public $stmts;
|
||||
|
||||
public function __construct(
|
||||
array $attrGroups, array $args, Node\Name $extends = null, array $implements,
|
||||
array $attrGroups, int $flags, array $args, Node\Name $extends = null, array $implements,
|
||||
array $stmts, array $attributes
|
||||
) {
|
||||
parent::__construct($attributes);
|
||||
$this->attrGroups = $attrGroups;
|
||||
$this->flags = $flags;
|
||||
$this->args = $args;
|
||||
$this->extends = $extends;
|
||||
$this->implements = $implements;
|
||||
@@ -46,7 +49,7 @@ class PrintableNewAnonClassNode extends Expr
|
||||
// We don't assert that $class->name is null here, to allow consumers to assign unique names
|
||||
// to anonymous classes for their own purposes. We simplify ignore the name here.
|
||||
return new self(
|
||||
$class->attrGroups, $newNode->args, $class->extends, $class->implements,
|
||||
$class->attrGroups, $class->flags, $newNode->args, $class->extends, $class->implements,
|
||||
$class->stmts, $newNode->getAttributes()
|
||||
);
|
||||
}
|
||||
@@ -56,6 +59,6 @@ class PrintableNewAnonClassNode extends Expr
|
||||
}
|
||||
|
||||
public function getSubNodeNames() : array {
|
||||
return ['attrGroups', 'args', 'extends', 'implements', 'stmts'];
|
||||
return ['attrGroups', 'flags', 'args', 'extends', 'implements', 'stmts'];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,15 +10,15 @@ class ClassConstFetch extends Expr
|
||||
{
|
||||
/** @var Name|Expr Class name */
|
||||
public $class;
|
||||
/** @var Identifier|Error Constant name */
|
||||
/** @var Identifier|Expr|Error Constant name */
|
||||
public $name;
|
||||
|
||||
/**
|
||||
* Constructs a class const fetch node.
|
||||
*
|
||||
* @param Name|Expr $class Class name
|
||||
* @param string|Identifier|Error $name Constant name
|
||||
* @param array $attributes Additional attributes
|
||||
* @param Name|Expr $class Class name
|
||||
* @param string|Identifier|Expr|Error $name Constant name
|
||||
* @param array $attributes Additional attributes
|
||||
*/
|
||||
public function __construct($class, $name, array $attributes = []) {
|
||||
$this->attributes = $attributes;
|
||||
@@ -29,7 +29,7 @@ class ClassConstFetch extends Expr
|
||||
public function getSubNodeNames() : array {
|
||||
return ['class', 'name'];
|
||||
}
|
||||
|
||||
|
||||
public function getType() : string {
|
||||
return 'Expr_ClassConstFetch';
|
||||
}
|
||||
|
||||
@@ -6,7 +6,10 @@ use PhpParser\NodeAbstract;
|
||||
|
||||
class Name extends NodeAbstract
|
||||
{
|
||||
/** @var string[] Parts of the name */
|
||||
/**
|
||||
* @var string[] Parts of the name
|
||||
* @deprecated Use getParts() instead
|
||||
*/
|
||||
public $parts;
|
||||
|
||||
private static $specialClassNames = [
|
||||
@@ -30,6 +33,15 @@ class Name extends NodeAbstract
|
||||
return ['parts'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get parts of name (split by the namespace separator).
|
||||
*
|
||||
* @return string[] Parts of name
|
||||
*/
|
||||
public function getParts(): array {
|
||||
return $this->parts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first part of the name, i.e. everything before the first namespace separator.
|
||||
*
|
||||
|
||||
@@ -10,31 +10,36 @@ class ClassConst extends Node\Stmt
|
||||
public $flags;
|
||||
/** @var Node\Const_[] Constant declarations */
|
||||
public $consts;
|
||||
/** @var Node\AttributeGroup[] */
|
||||
/** @var Node\AttributeGroup[] PHP attribute groups */
|
||||
public $attrGroups;
|
||||
/** @var Node\Identifier|Node\Name|Node\ComplexType|null Type declaration */
|
||||
public $type;
|
||||
|
||||
/**
|
||||
* Constructs a class const list node.
|
||||
*
|
||||
* @param Node\Const_[] $consts Constant declarations
|
||||
* @param int $flags Modifiers
|
||||
* @param array $attributes Additional attributes
|
||||
* @param Node\AttributeGroup[] $attrGroups PHP attribute groups
|
||||
* @param Node\Const_[] $consts Constant declarations
|
||||
* @param int $flags Modifiers
|
||||
* @param array $attributes Additional attributes
|
||||
* @param Node\AttributeGroup[] $attrGroups PHP attribute groups
|
||||
* @param null|string|Node\Identifier|Node\Name|Node\ComplexType $type Type declaration
|
||||
*/
|
||||
public function __construct(
|
||||
array $consts,
|
||||
int $flags = 0,
|
||||
array $attributes = [],
|
||||
array $attrGroups = []
|
||||
array $attrGroups = [],
|
||||
$type = null
|
||||
) {
|
||||
$this->attributes = $attributes;
|
||||
$this->flags = $flags;
|
||||
$this->consts = $consts;
|
||||
$this->attrGroups = $attrGroups;
|
||||
$this->type = \is_string($type) ? new Node\Identifier($type) : $type;
|
||||
}
|
||||
|
||||
public function getSubNodeNames() : array {
|
||||
return ['attrGroups', 'flags', 'consts'];
|
||||
return ['attrGroups', 'flags', 'type', 'consts'];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2627,7 +2627,7 @@ class Php5 extends \PhpParser\ParserAbstract
|
||||
$this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(2-2)], null, true, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes);
|
||||
},
|
||||
552 => function ($stackPos) {
|
||||
$this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(2-2)], null, false, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes, true, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes);
|
||||
$this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(2-2)], null, false, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes, true);
|
||||
},
|
||||
553 => function ($stackPos) {
|
||||
$this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)];
|
||||
|
||||
2610
vendor/nikic/php-parser/lib/PhpParser/Parser/Php7.php
vendored
2610
vendor/nikic/php-parser/lib/PhpParser/Parser/Php7.php
vendored
File diff suppressed because it is too large
Load Diff
@@ -529,7 +529,7 @@ class Standard extends PrettyPrinterAbstract
|
||||
}
|
||||
|
||||
protected function pExpr_StaticCall(Expr\StaticCall $node) {
|
||||
return $this->pDereferenceLhs($node->class) . '::'
|
||||
return $this->pStaticDereferenceLhs($node->class) . '::'
|
||||
. ($node->name instanceof Expr
|
||||
? ($node->name instanceof Expr\Variable
|
||||
? $this->p($node->name)
|
||||
@@ -606,7 +606,7 @@ class Standard extends PrettyPrinterAbstract
|
||||
}
|
||||
|
||||
protected function pExpr_ClassConstFetch(Expr\ClassConstFetch $node) {
|
||||
return $this->pDereferenceLhs($node->class) . '::' . $this->p($node->name);
|
||||
return $this->pStaticDereferenceLhs($node->class) . '::' . $this->pObjectProperty($node->name);
|
||||
}
|
||||
|
||||
protected function pExpr_PropertyFetch(Expr\PropertyFetch $node) {
|
||||
@@ -618,7 +618,7 @@ class Standard extends PrettyPrinterAbstract
|
||||
}
|
||||
|
||||
protected function pExpr_StaticPropertyFetch(Expr\StaticPropertyFetch $node) {
|
||||
return $this->pDereferenceLhs($node->class) . '::$' . $this->pObjectProperty($node->name);
|
||||
return $this->pStaticDereferenceLhs($node->class) . '::$' . $this->pObjectProperty($node->name);
|
||||
}
|
||||
|
||||
protected function pExpr_ShellExec(Expr\ShellExec $node) {
|
||||
@@ -814,7 +814,9 @@ class Standard extends PrettyPrinterAbstract
|
||||
protected function pStmt_ClassConst(Stmt\ClassConst $node) {
|
||||
return $this->pAttrGroups($node->attrGroups)
|
||||
. $this->pModifiers($node->flags)
|
||||
. 'const ' . $this->pCommaSeparated($node->consts) . ';';
|
||||
. 'const '
|
||||
. (null !== $node->type ? $this->p($node->type) . ' ' : '')
|
||||
. $this->pCommaSeparated($node->consts) . ';';
|
||||
}
|
||||
|
||||
protected function pStmt_Function(Stmt\Function_ $node) {
|
||||
@@ -1067,6 +1069,14 @@ class Standard extends PrettyPrinterAbstract
|
||||
}
|
||||
}
|
||||
|
||||
protected function pStaticDereferenceLhs(Node $node) {
|
||||
if (!$this->staticDereferenceLhsRequiresParens($node)) {
|
||||
return $this->p($node);
|
||||
} else {
|
||||
return '(' . $this->p($node) . ')';
|
||||
}
|
||||
}
|
||||
|
||||
protected function pCallLhs(Node $node) {
|
||||
if (!$this->callLhsRequiresParens($node)) {
|
||||
return $this->p($node);
|
||||
@@ -1075,9 +1085,12 @@ class Standard extends PrettyPrinterAbstract
|
||||
}
|
||||
}
|
||||
|
||||
protected function pNewVariable(Node $node) {
|
||||
// TODO: This is not fully accurate.
|
||||
return $this->pDereferenceLhs($node);
|
||||
protected function pNewVariable(Node $node): string {
|
||||
if (!$this->newOperandRequiresParens($node)) {
|
||||
return $this->p($node);
|
||||
} else {
|
||||
return '(' . $this->p($node) . ')';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,6 +21,8 @@ abstract class PrettyPrinterAbstract
|
||||
const FIXUP_BRACED_NAME = 4; // Name operand that may require bracing
|
||||
const FIXUP_VAR_BRACED_NAME = 5; // Name operand that may require ${} bracing
|
||||
const FIXUP_ENCAPSED = 6; // Encapsed string part
|
||||
const FIXUP_NEW = 7; // New/instanceof operand
|
||||
const FIXUP_STATIC_DEREF_LHS = 8; // LHS of static dereferencing operation
|
||||
|
||||
protected $precedenceMap = [
|
||||
// [precedence, associativity]
|
||||
@@ -977,6 +979,19 @@ abstract class PrettyPrinterAbstract
|
||||
return '(' . $this->p($subNode) . ')';
|
||||
}
|
||||
break;
|
||||
case self::FIXUP_STATIC_DEREF_LHS:
|
||||
if ($this->staticDereferenceLhsRequiresParens($subNode)
|
||||
&& !$this->origTokens->haveParens($subStartPos, $subEndPos)
|
||||
) {
|
||||
return '(' . $this->p($subNode) . ')';
|
||||
}
|
||||
break;
|
||||
case self::FIXUP_NEW:
|
||||
if ($this->newOperandRequiresParens($subNode)
|
||||
&& !$this->origTokens->haveParens($subStartPos, $subEndPos)) {
|
||||
return '(' . $this->p($subNode) . ')';
|
||||
}
|
||||
break;
|
||||
case self::FIXUP_BRACED_NAME:
|
||||
case self::FIXUP_VAR_BRACED_NAME:
|
||||
if ($subNode instanceof Expr
|
||||
@@ -1047,13 +1062,26 @@ abstract class PrettyPrinterAbstract
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the LHS of a dereferencing operation must be wrapped in parenthesis.
|
||||
* Determines whether the LHS of an array/object operation must be wrapped in parentheses.
|
||||
*
|
||||
* @param Node $node LHS of dereferencing operation
|
||||
*
|
||||
* @return bool Whether parentheses are required
|
||||
*/
|
||||
protected function dereferenceLhsRequiresParens(Node $node) : bool {
|
||||
// A constant can occur on the LHS of an array/object deref, but not a static deref.
|
||||
return $this->staticDereferenceLhsRequiresParens($node)
|
||||
&& !$node instanceof Expr\ConstFetch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the LHS of a static operation must be wrapped in parentheses.
|
||||
*
|
||||
* @param Node $node LHS of dereferencing operation
|
||||
*
|
||||
* @return bool Whether parentheses are required
|
||||
*/
|
||||
protected function staticDereferenceLhsRequiresParens(Node $node): bool {
|
||||
return !($node instanceof Expr\Variable
|
||||
|| $node instanceof Node\Name
|
||||
|| $node instanceof Expr\ArrayDimFetch
|
||||
@@ -1066,10 +1094,31 @@ abstract class PrettyPrinterAbstract
|
||||
|| $node instanceof Expr\StaticCall
|
||||
|| $node instanceof Expr\Array_
|
||||
|| $node instanceof Scalar\String_
|
||||
|| $node instanceof Expr\ConstFetch
|
||||
|| $node instanceof Expr\ClassConstFetch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether an expression used in "new" or "instanceof" requires parentheses.
|
||||
*
|
||||
* @param Node $node New or instanceof operand
|
||||
*
|
||||
* @return bool Whether parentheses are required
|
||||
*/
|
||||
protected function newOperandRequiresParens(Node $node): bool {
|
||||
if ($node instanceof Node\Name || $node instanceof Expr\Variable) {
|
||||
return false;
|
||||
}
|
||||
if ($node instanceof Expr\ArrayDimFetch || $node instanceof Expr\PropertyFetch ||
|
||||
$node instanceof Expr\NullsafePropertyFetch
|
||||
) {
|
||||
return $this->newOperandRequiresParens($node->var);
|
||||
}
|
||||
if ($node instanceof Expr\StaticPropertyFetch) {
|
||||
return $this->newOperandRequiresParens($node->class);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print modifiers, including trailing whitespace.
|
||||
*
|
||||
@@ -1171,7 +1220,7 @@ abstract class PrettyPrinterAbstract
|
||||
Expr\PostDec::class => ['var' => self::FIXUP_PREC_LEFT],
|
||||
Expr\Instanceof_::class => [
|
||||
'expr' => self::FIXUP_PREC_LEFT,
|
||||
'class' => self::FIXUP_PREC_RIGHT, // TODO: FIXUP_NEW_VARIABLE
|
||||
'class' => self::FIXUP_NEW,
|
||||
],
|
||||
Expr\Ternary::class => [
|
||||
'cond' => self::FIXUP_PREC_LEFT,
|
||||
@@ -1179,10 +1228,13 @@ abstract class PrettyPrinterAbstract
|
||||
],
|
||||
|
||||
Expr\FuncCall::class => ['name' => self::FIXUP_CALL_LHS],
|
||||
Expr\StaticCall::class => ['class' => self::FIXUP_DEREF_LHS],
|
||||
Expr\StaticCall::class => ['class' => self::FIXUP_STATIC_DEREF_LHS],
|
||||
Expr\ArrayDimFetch::class => ['var' => self::FIXUP_DEREF_LHS],
|
||||
Expr\ClassConstFetch::class => ['var' => self::FIXUP_DEREF_LHS],
|
||||
Expr\New_::class => ['class' => self::FIXUP_DEREF_LHS], // TODO: FIXUP_NEW_VARIABLE
|
||||
Expr\ClassConstFetch::class => [
|
||||
'class' => self::FIXUP_STATIC_DEREF_LHS,
|
||||
'name' => self::FIXUP_BRACED_NAME,
|
||||
],
|
||||
Expr\New_::class => ['class' => self::FIXUP_NEW],
|
||||
Expr\MethodCall::class => [
|
||||
'var' => self::FIXUP_DEREF_LHS,
|
||||
'name' => self::FIXUP_BRACED_NAME,
|
||||
@@ -1192,7 +1244,7 @@ abstract class PrettyPrinterAbstract
|
||||
'name' => self::FIXUP_BRACED_NAME,
|
||||
],
|
||||
Expr\StaticPropertyFetch::class => [
|
||||
'class' => self::FIXUP_DEREF_LHS,
|
||||
'class' => self::FIXUP_STATIC_DEREF_LHS,
|
||||
'name' => self::FIXUP_VAR_BRACED_NAME,
|
||||
],
|
||||
Expr\PropertyFetch::class => [
|
||||
@@ -1278,6 +1330,7 @@ abstract class PrettyPrinterAbstract
|
||||
'Param->default' => $stripEquals,
|
||||
'Stmt_Break->num' => $stripBoth,
|
||||
'Stmt_Catch->var' => $stripLeft,
|
||||
'Stmt_ClassConst->type' => $stripRight,
|
||||
'Stmt_ClassMethod->returnType' => $stripColon,
|
||||
'Stmt_Class->extends' => ['left' => \T_EXTENDS],
|
||||
'Stmt_Enum->scalarType' => $stripColon,
|
||||
@@ -1319,6 +1372,7 @@ abstract class PrettyPrinterAbstract
|
||||
'Stmt_Break->num' => [\T_BREAK, false, ' ', null],
|
||||
'Stmt_Catch->var' => [null, false, ' ', null],
|
||||
'Stmt_ClassMethod->returnType' => [')', false, ' : ', null],
|
||||
'Stmt_ClassConst->type' => [\T_CONST, false, ' ', null],
|
||||
'Stmt_Class->extends' => [null, false, ' extends ', null],
|
||||
'Stmt_Enum->scalarType' => [null, false, ' : ', null],
|
||||
'Stmt_EnumCase->expr' => [null, false, ' = ', null],
|
||||
@@ -1508,6 +1562,7 @@ abstract class PrettyPrinterAbstract
|
||||
'Stmt_ClassMethod->flags' => \T_FUNCTION,
|
||||
'Stmt_Class->flags' => \T_CLASS,
|
||||
'Stmt_Property->flags' => \T_VARIABLE,
|
||||
'Expr_PrintableNewAnonClass->flags' => \T_CLASS,
|
||||
'Param->flags' => \T_VARIABLE,
|
||||
//'Stmt_TraitUseAdaptation_Alias->newModifier' => 0, // TODO
|
||||
];
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
extends: "default"
|
||||
|
||||
ignore: |
|
||||
.build/
|
||||
.notes/
|
||||
vendor/
|
||||
rules:
|
||||
braces:
|
||||
max-spaces-inside-empty: 0
|
||||
max-spaces-inside: 1
|
||||
min-spaces-inside-empty: 0
|
||||
min-spaces-inside: 1
|
||||
brackets:
|
||||
max-spaces-inside-empty: 0
|
||||
max-spaces-inside: 0
|
||||
min-spaces-inside-empty: 0
|
||||
min-spaces-inside: 0
|
||||
colons:
|
||||
max-spaces-after: 1
|
||||
max-spaces-before: 0
|
||||
commas:
|
||||
max-spaces-after: 1
|
||||
max-spaces-before: 0
|
||||
min-spaces-after: 1
|
||||
comments:
|
||||
ignore-shebangs: true
|
||||
min-spaces-from-content: 1
|
||||
require-starting-space: true
|
||||
comments-indentation: "enable"
|
||||
document-end:
|
||||
present: false
|
||||
document-start:
|
||||
present: false
|
||||
indentation:
|
||||
check-multi-line-strings: false
|
||||
indent-sequences: true
|
||||
spaces: 2
|
||||
empty-lines:
|
||||
max-end: 0
|
||||
max-start: 0
|
||||
max: 1
|
||||
empty-values:
|
||||
forbid-in-block-mappings: true
|
||||
forbid-in-flow-mappings: true
|
||||
hyphens:
|
||||
max-spaces-after: 2
|
||||
key-duplicates: "enable"
|
||||
key-ordering: "disable"
|
||||
line-length: "disable"
|
||||
new-line-at-end-of-file: "enable"
|
||||
new-lines:
|
||||
type: "unix"
|
||||
octal-values:
|
||||
forbid-implicit-octal: true
|
||||
quoted-strings:
|
||||
quote-type: "double"
|
||||
trailing-spaces: "enable"
|
||||
truthy:
|
||||
allowed-values:
|
||||
- "false"
|
||||
- "true"
|
||||
|
||||
yaml-files:
|
||||
- "*.yaml"
|
||||
- "*.yml"
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"symbol-whitelist" : [
|
||||
"null", "true", "false",
|
||||
"static", "self", "parent",
|
||||
"array", "string", "int", "float", "bool", "iterable", "callable", "void", "object", "XSLTProcessor",
|
||||
"T_NAME_QUALIFIED", "T_NAME_FULLY_QUALIFIED"
|
||||
],
|
||||
"php-core-extensions" : [
|
||||
"Core",
|
||||
"pcre",
|
||||
"Reflection",
|
||||
"tokenizer",
|
||||
"SPL",
|
||||
"standard"
|
||||
]
|
||||
}
|
||||
@@ -11,7 +11,9 @@
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.4 || ^8.0",
|
||||
"phpdocumentor/reflection-common": "^2.0"
|
||||
"phpdocumentor/reflection-common": "^2.0",
|
||||
"phpstan/phpdoc-parser": "^1.13",
|
||||
"doctrine/deprecations": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-tokenizer": "*",
|
||||
@@ -20,7 +22,8 @@
|
||||
"phpstan/phpstan-phpunit": "^1.1",
|
||||
"phpstan/extension-installer": "^1.1",
|
||||
"vimeo/psalm": "^4.25",
|
||||
"rector/rector": "^0.13.9"
|
||||
"rector/rector": "^0.13.9",
|
||||
"phpbench/phpbench": "^1.2"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
||||
26
vendor/phpdocumentor/type-resolver/rector.php
vendored
26
vendor/phpdocumentor/type-resolver/rector.php
vendored
@@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\CodeQuality\Rector\Class_\InlineConstructorDefaultToPropertyRector;
|
||||
use Rector\Config\RectorConfig;
|
||||
use Rector\Set\ValueObject\LevelSetList;
|
||||
|
||||
return static function (RectorConfig $rectorConfig): void {
|
||||
$rectorConfig->paths([
|
||||
__DIR__ . '/src',
|
||||
__DIR__ . '/tests/unit'
|
||||
]);
|
||||
|
||||
// register a single rule
|
||||
$rectorConfig->rule(InlineConstructorDefaultToPropertyRector::class);
|
||||
$rectorConfig->rule(Rector\CodeQuality\Rector\Class_\CompleteDynamicPropertiesRector::class);
|
||||
$rectorConfig->rule(Rector\TypeDeclaration\Rector\Closure\AddClosureReturnTypeRector::class);
|
||||
$rectorConfig->rule(Rector\PHPUnit\Rector\Class_\AddProphecyTraitRector::class);
|
||||
$rectorConfig->importNames();
|
||||
|
||||
// define sets of rules
|
||||
$rectorConfig->sets([
|
||||
LevelSetList::UP_TO_PHP_74
|
||||
]);
|
||||
};
|
||||
44
vendor/phpdocumentor/type-resolver/src/PseudoTypes/ArrayShape.php
vendored
Normal file
44
vendor/phpdocumentor/type-resolver/src/PseudoTypes/ArrayShape.php
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of phpDocumentor.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @link http://phpdoc.org
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace phpDocumentor\Reflection\PseudoTypes;
|
||||
|
||||
use phpDocumentor\Reflection\PseudoType;
|
||||
use phpDocumentor\Reflection\Type;
|
||||
use phpDocumentor\Reflection\Types\Array_;
|
||||
use phpDocumentor\Reflection\Types\ArrayKey;
|
||||
use phpDocumentor\Reflection\Types\Mixed_;
|
||||
|
||||
use function implode;
|
||||
|
||||
/** @psalm-immutable */
|
||||
class ArrayShape implements PseudoType
|
||||
{
|
||||
/** @var ArrayShapeItem[] */
|
||||
private array $items;
|
||||
|
||||
public function __construct(ArrayShapeItem ...$items)
|
||||
{
|
||||
$this->items = $items;
|
||||
}
|
||||
|
||||
public function underlyingType(): Type
|
||||
{
|
||||
return new Array_(new Mixed_(), new ArrayKey());
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return 'array{' . implode(', ', $this->items) . '}';
|
||||
}
|
||||
}
|
||||
62
vendor/phpdocumentor/type-resolver/src/PseudoTypes/ArrayShapeItem.php
vendored
Normal file
62
vendor/phpdocumentor/type-resolver/src/PseudoTypes/ArrayShapeItem.php
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of phpDocumentor.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @link http://phpdoc.org
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace phpDocumentor\Reflection\PseudoTypes;
|
||||
|
||||
use phpDocumentor\Reflection\Type;
|
||||
use phpDocumentor\Reflection\Types\Mixed_;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
final class ArrayShapeItem
|
||||
{
|
||||
private ?string $key;
|
||||
private Type $value;
|
||||
private bool $optional;
|
||||
|
||||
public function __construct(?string $key, ?Type $value, bool $optional)
|
||||
{
|
||||
$this->key = $key;
|
||||
$this->value = $value ?? new Mixed_();
|
||||
$this->optional = $optional;
|
||||
}
|
||||
|
||||
public function getKey(): ?string
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
public function getValue(): Type
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
public function isOptional(): bool
|
||||
{
|
||||
return $this->optional;
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
if ($this->key !== null) {
|
||||
return sprintf(
|
||||
'%s%s: %s',
|
||||
$this->key,
|
||||
$this->optional ? '?' : '',
|
||||
(string) $this->value
|
||||
);
|
||||
}
|
||||
|
||||
return (string) $this->value;
|
||||
}
|
||||
}
|
||||
53
vendor/phpdocumentor/type-resolver/src/PseudoTypes/ConstExpression.php
vendored
Normal file
53
vendor/phpdocumentor/type-resolver/src/PseudoTypes/ConstExpression.php
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of phpDocumentor.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @link http://phpdoc.org
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace phpDocumentor\Reflection\PseudoTypes;
|
||||
|
||||
use phpDocumentor\Reflection\PseudoType;
|
||||
use phpDocumentor\Reflection\Type;
|
||||
use phpDocumentor\Reflection\Types\Mixed_;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
/** @psalm-immutable */
|
||||
final class ConstExpression implements PseudoType
|
||||
{
|
||||
private Type $owner;
|
||||
private string $expression;
|
||||
|
||||
public function __construct(Type $owner, string $expression)
|
||||
{
|
||||
$this->owner = $owner;
|
||||
$this->expression = $expression;
|
||||
}
|
||||
|
||||
public function getOwner(): Type
|
||||
{
|
||||
return $this->owner;
|
||||
}
|
||||
|
||||
public function getExpression(): string
|
||||
{
|
||||
return $this->expression;
|
||||
}
|
||||
|
||||
public function underlyingType(): Type
|
||||
{
|
||||
return new Mixed_();
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return sprintf('%s::%s', (string) $this->owner, $this->expression);
|
||||
}
|
||||
}
|
||||
44
vendor/phpdocumentor/type-resolver/src/PseudoTypes/FloatValue.php
vendored
Normal file
44
vendor/phpdocumentor/type-resolver/src/PseudoTypes/FloatValue.php
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of phpDocumentor.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @link http://phpdoc.org
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace phpDocumentor\Reflection\PseudoTypes;
|
||||
|
||||
use phpDocumentor\Reflection\PseudoType;
|
||||
use phpDocumentor\Reflection\Type;
|
||||
use phpDocumentor\Reflection\Types\Float_;
|
||||
|
||||
/** @psalm-immutable */
|
||||
class FloatValue implements PseudoType
|
||||
{
|
||||
private float $value;
|
||||
|
||||
public function __construct(float $value)
|
||||
{
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
public function getValue(): float
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
public function underlyingType(): Type
|
||||
{
|
||||
return new Float_();
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return (string) $this->value;
|
||||
}
|
||||
}
|
||||
44
vendor/phpdocumentor/type-resolver/src/PseudoTypes/IntegerValue.php
vendored
Normal file
44
vendor/phpdocumentor/type-resolver/src/PseudoTypes/IntegerValue.php
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of phpDocumentor.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @link http://phpdoc.org
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace phpDocumentor\Reflection\PseudoTypes;
|
||||
|
||||
use phpDocumentor\Reflection\PseudoType;
|
||||
use phpDocumentor\Reflection\Type;
|
||||
use phpDocumentor\Reflection\Types\Integer;
|
||||
|
||||
/** @psalm-immutable */
|
||||
final class IntegerValue implements PseudoType
|
||||
{
|
||||
private int $value;
|
||||
|
||||
public function __construct(int $value)
|
||||
{
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
public function getValue(): int
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
public function underlyingType(): Type
|
||||
{
|
||||
return new Integer();
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return (string) $this->value;
|
||||
}
|
||||
}
|
||||
50
vendor/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyList.php
vendored
Normal file
50
vendor/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyList.php
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* This file is part of phpDocumentor.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @link http://phpdoc.org
|
||||
*/
|
||||
|
||||
namespace phpDocumentor\Reflection\PseudoTypes;
|
||||
|
||||
use phpDocumentor\Reflection\PseudoType;
|
||||
use phpDocumentor\Reflection\Type;
|
||||
use phpDocumentor\Reflection\Types\Array_;
|
||||
use phpDocumentor\Reflection\Types\Integer;
|
||||
use phpDocumentor\Reflection\Types\Mixed_;
|
||||
|
||||
/**
|
||||
* Value Object representing the type 'non-empty-list'.
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
final class NonEmptyList extends Array_ implements PseudoType
|
||||
{
|
||||
public function underlyingType(): Type
|
||||
{
|
||||
return new Array_();
|
||||
}
|
||||
|
||||
public function __construct(?Type $valueType = null)
|
||||
{
|
||||
parent::__construct($valueType, new Integer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a rendered output of the Type as it would be used in a DocBlock.
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
if ($this->valueType instanceof Mixed_) {
|
||||
return 'non-empty-list';
|
||||
}
|
||||
|
||||
return 'non-empty-list<' . $this->valueType . '>';
|
||||
}
|
||||
}
|
||||
46
vendor/phpdocumentor/type-resolver/src/PseudoTypes/StringValue.php
vendored
Normal file
46
vendor/phpdocumentor/type-resolver/src/PseudoTypes/StringValue.php
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of phpDocumentor.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @link http://phpdoc.org
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace phpDocumentor\Reflection\PseudoTypes;
|
||||
|
||||
use phpDocumentor\Reflection\PseudoType;
|
||||
use phpDocumentor\Reflection\Type;
|
||||
use phpDocumentor\Reflection\Types\String_;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
/** @psalm-immutable */
|
||||
class StringValue implements PseudoType
|
||||
{
|
||||
private string $value;
|
||||
|
||||
public function __construct(string $value)
|
||||
{
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
public function getValue(): string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
public function underlyingType(): Type
|
||||
{
|
||||
return new String_();
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return sprintf('"%s"', $this->value);
|
||||
}
|
||||
}
|
||||
@@ -13,27 +13,36 @@ declare(strict_types=1);
|
||||
|
||||
namespace phpDocumentor\Reflection;
|
||||
|
||||
use ArrayIterator;
|
||||
use Doctrine\Deprecations\Deprecation;
|
||||
use InvalidArgumentException;
|
||||
use phpDocumentor\Reflection\PseudoTypes\ArrayShape;
|
||||
use phpDocumentor\Reflection\PseudoTypes\ArrayShapeItem;
|
||||
use phpDocumentor\Reflection\PseudoTypes\CallableString;
|
||||
use phpDocumentor\Reflection\PseudoTypes\ConstExpression;
|
||||
use phpDocumentor\Reflection\PseudoTypes\False_;
|
||||
use phpDocumentor\Reflection\PseudoTypes\FloatValue;
|
||||
use phpDocumentor\Reflection\PseudoTypes\HtmlEscapedString;
|
||||
use phpDocumentor\Reflection\PseudoTypes\IntegerRange;
|
||||
use phpDocumentor\Reflection\PseudoTypes\IntegerValue;
|
||||
use phpDocumentor\Reflection\PseudoTypes\List_;
|
||||
use phpDocumentor\Reflection\PseudoTypes\LiteralString;
|
||||
use phpDocumentor\Reflection\PseudoTypes\LowercaseString;
|
||||
use phpDocumentor\Reflection\PseudoTypes\NegativeInteger;
|
||||
use phpDocumentor\Reflection\PseudoTypes\NonEmptyList;
|
||||
use phpDocumentor\Reflection\PseudoTypes\NonEmptyLowercaseString;
|
||||
use phpDocumentor\Reflection\PseudoTypes\NonEmptyString;
|
||||
use phpDocumentor\Reflection\PseudoTypes\Numeric_;
|
||||
use phpDocumentor\Reflection\PseudoTypes\NumericString;
|
||||
use phpDocumentor\Reflection\PseudoTypes\PositiveInteger;
|
||||
use phpDocumentor\Reflection\PseudoTypes\StringValue;
|
||||
use phpDocumentor\Reflection\PseudoTypes\TraitString;
|
||||
use phpDocumentor\Reflection\PseudoTypes\True_;
|
||||
use phpDocumentor\Reflection\Types\AggregatedType;
|
||||
use phpDocumentor\Reflection\Types\Array_;
|
||||
use phpDocumentor\Reflection\Types\ArrayKey;
|
||||
use phpDocumentor\Reflection\Types\Boolean;
|
||||
use phpDocumentor\Reflection\Types\Callable_;
|
||||
use phpDocumentor\Reflection\Types\CallableParameter;
|
||||
use phpDocumentor\Reflection\Types\ClassString;
|
||||
use phpDocumentor\Reflection\Types\Collection;
|
||||
use phpDocumentor\Reflection\Types\Compound;
|
||||
@@ -57,46 +66,51 @@ use phpDocumentor\Reflection\Types\Static_;
|
||||
use phpDocumentor\Reflection\Types\String_;
|
||||
use phpDocumentor\Reflection\Types\This;
|
||||
use phpDocumentor\Reflection\Types\Void_;
|
||||
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprFloatNode;
|
||||
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprIntegerNode;
|
||||
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprStringNode;
|
||||
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstFetchNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\ArrayShapeItemNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\ArrayShapeNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\ArrayTypeNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\CallableTypeNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\CallableTypeParameterNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\ConditionalTypeForParameterNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\ConditionalTypeNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\ConstTypeNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\GenericTypeNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\IntersectionTypeNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\NullableTypeNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\OffsetAccessTypeNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\ThisTypeNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\UnionTypeNode;
|
||||
use PHPStan\PhpDocParser\Lexer\Lexer;
|
||||
use PHPStan\PhpDocParser\Parser\ConstExprParser;
|
||||
use PHPStan\PhpDocParser\Parser\ParserException;
|
||||
use PHPStan\PhpDocParser\Parser\TokenIterator;
|
||||
use PHPStan\PhpDocParser\Parser\TypeParser;
|
||||
use RuntimeException;
|
||||
|
||||
use function array_filter;
|
||||
use function array_key_exists;
|
||||
use function array_key_last;
|
||||
use function array_pop;
|
||||
use function array_values;
|
||||
use function array_map;
|
||||
use function array_reverse;
|
||||
use function class_exists;
|
||||
use function class_implements;
|
||||
use function count;
|
||||
use function current;
|
||||
use function get_class;
|
||||
use function in_array;
|
||||
use function is_numeric;
|
||||
use function preg_split;
|
||||
use function sprintf;
|
||||
use function strpos;
|
||||
use function strtolower;
|
||||
use function trim;
|
||||
|
||||
use const PREG_SPLIT_DELIM_CAPTURE;
|
||||
use const PREG_SPLIT_NO_EMPTY;
|
||||
|
||||
final class TypeResolver
|
||||
{
|
||||
/** @var string Definition of the ARRAY operator for types */
|
||||
private const OPERATOR_ARRAY = '[]';
|
||||
|
||||
/** @var string Definition of the NAMESPACE operator in PHP */
|
||||
private const OPERATOR_NAMESPACE = '\\';
|
||||
|
||||
/** @var int the iterator parser is inside a compound context */
|
||||
private const PARSER_IN_COMPOUND = 0;
|
||||
|
||||
/** @var int the iterator parser is inside a nullable expression context */
|
||||
private const PARSER_IN_NULLABLE = 1;
|
||||
|
||||
/** @var int the iterator parser is inside an array expression context */
|
||||
private const PARSER_IN_ARRAY_EXPRESSION = 2;
|
||||
|
||||
/** @var int the iterator parser is inside a collection expression context */
|
||||
private const PARSER_IN_COLLECTION_EXPRESSION = 3;
|
||||
|
||||
/**
|
||||
* @var array<string, string> List of recognized keywords and unto which Value Object they map
|
||||
* @psalm-var array<string, class-string<Type>>
|
||||
@@ -142,10 +156,15 @@ final class TypeResolver
|
||||
'iterable' => Iterable_::class,
|
||||
'never' => Never_::class,
|
||||
'list' => List_::class,
|
||||
'non-empty-list' => NonEmptyList::class,
|
||||
];
|
||||
|
||||
/** @psalm-readonly */
|
||||
private FqsenResolver $fqsenResolver;
|
||||
/** @psalm-readonly */
|
||||
private TypeParser $typeParser;
|
||||
/** @psalm-readonly */
|
||||
private Lexer $lexer;
|
||||
|
||||
/**
|
||||
* Initializes this TypeResolver with the means to create and resolve Fqsen objects.
|
||||
@@ -153,6 +172,8 @@ final class TypeResolver
|
||||
public function __construct(?FqsenResolver $fqsenResolver = null)
|
||||
{
|
||||
$this->fqsenResolver = $fqsenResolver ?: new FqsenResolver();
|
||||
$this->typeParser = new TypeParser(new ConstExprParser());
|
||||
$this->lexer = new Lexer();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -165,9 +186,9 @@ final class TypeResolver
|
||||
* This method only works as expected if the namespace and aliases are set;
|
||||
* no dynamic reflection is being performed here.
|
||||
*
|
||||
* @uses Context::getNamespace() to determine with what to prefix the type name.
|
||||
* @uses Context::getNamespaceAliases() to check whether the first part of the relative type name should not be
|
||||
* replaced with another namespace.
|
||||
* @uses Context::getNamespace() to determine with what to prefix the type name.
|
||||
*
|
||||
* @param string $type The relative or absolute type.
|
||||
*/
|
||||
@@ -182,178 +203,219 @@ final class TypeResolver
|
||||
$context = new Context('');
|
||||
}
|
||||
|
||||
// split the type string into tokens `|`, `?`, `<`, `>`, `,`, `(`, `)`, `[]`, '<', '>' and type names
|
||||
$tokens = preg_split(
|
||||
'/(\\||\\?|<|>|&|, ?|\\(|\\)|\\[\\]+)/',
|
||||
$type,
|
||||
-1,
|
||||
PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE
|
||||
);
|
||||
$tokens = $this->lexer->tokenize($type);
|
||||
$tokenIterator = new TokenIterator($tokens);
|
||||
|
||||
if ($tokens === false) {
|
||||
throw new InvalidArgumentException('Unable to split the type string "' . $type . '" into tokens');
|
||||
}
|
||||
$ast = $this->parse($tokenIterator);
|
||||
$type = $this->createType($ast, $context);
|
||||
|
||||
/** @var ArrayIterator<int, string|null> $tokenIterator */
|
||||
$tokenIterator = new ArrayIterator($tokens);
|
||||
|
||||
return $this->parseTypes($tokenIterator, $context, self::PARSER_IN_COMPOUND);
|
||||
return $this->tryParseRemainingCompoundTypes($tokenIterator, $context, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyse each tokens and creates types
|
||||
*
|
||||
* @param ArrayIterator<int, string|null> $tokens the iterator on tokens
|
||||
* @param int $parserContext on of self::PARSER_* constants, indicating
|
||||
* the context where we are in the parsing
|
||||
*/
|
||||
private function parseTypes(ArrayIterator $tokens, Context $context, int $parserContext): Type
|
||||
public function createType(?TypeNode $type, Context $context): Type
|
||||
{
|
||||
$types = [];
|
||||
$token = '';
|
||||
$compoundToken = '|';
|
||||
while ($tokens->valid()) {
|
||||
$token = $tokens->current();
|
||||
if ($token === null) {
|
||||
throw new RuntimeException(
|
||||
'Unexpected nullable character'
|
||||
);
|
||||
}
|
||||
if ($type === null) {
|
||||
return new Mixed_();
|
||||
}
|
||||
|
||||
if ($token === '|' || $token === '&') {
|
||||
if (count($types) === 0) {
|
||||
switch (get_class($type)) {
|
||||
case ArrayTypeNode::class:
|
||||
return new Array_(
|
||||
$this->createType($type->type, $context)
|
||||
);
|
||||
|
||||
case ArrayShapeNode::class:
|
||||
return new ArrayShape(
|
||||
...array_map(
|
||||
fn (ArrayShapeItemNode $item) => new ArrayShapeItem(
|
||||
(string) $item->keyName,
|
||||
$this->createType($item->valueType, $context),
|
||||
$item->optional
|
||||
),
|
||||
$type->items
|
||||
)
|
||||
);
|
||||
|
||||
case CallableTypeNode::class:
|
||||
return $this->createFromCallable($type, $context);
|
||||
|
||||
case ConstTypeNode::class:
|
||||
return $this->createFromConst($type, $context);
|
||||
|
||||
case GenericTypeNode::class:
|
||||
return $this->createFromGeneric($type, $context);
|
||||
|
||||
case IdentifierTypeNode::class:
|
||||
return $this->resolveSingleType($type->name, $context);
|
||||
|
||||
case IntersectionTypeNode::class:
|
||||
return new Intersection(
|
||||
array_filter(
|
||||
array_map(
|
||||
function (TypeNode $nestedType) use ($context) {
|
||||
$type = $this->createType($nestedType, $context);
|
||||
if ($type instanceof AggregatedType) {
|
||||
return new Expression($type);
|
||||
}
|
||||
|
||||
return $type;
|
||||
},
|
||||
$type->types
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
case NullableTypeNode::class:
|
||||
$nestedType = $this->createType($type->type, $context);
|
||||
|
||||
return new Nullable($nestedType);
|
||||
|
||||
case UnionTypeNode::class:
|
||||
return new Compound(
|
||||
array_filter(
|
||||
array_map(
|
||||
function (TypeNode $nestedType) use ($context) {
|
||||
$type = $this->createType($nestedType, $context);
|
||||
if ($type instanceof AggregatedType) {
|
||||
return new Expression($type);
|
||||
}
|
||||
|
||||
return $type;
|
||||
},
|
||||
$type->types
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
case ThisTypeNode::class:
|
||||
return new This();
|
||||
|
||||
case ConditionalTypeNode::class:
|
||||
case ConditionalTypeForParameterNode::class:
|
||||
case OffsetAccessTypeNode::class:
|
||||
default:
|
||||
return new Mixed_();
|
||||
}
|
||||
}
|
||||
|
||||
private function createFromGeneric(GenericTypeNode $type, Context $context): Type
|
||||
{
|
||||
switch (strtolower($type->type->name)) {
|
||||
case 'array':
|
||||
return $this->createArray($type->genericTypes, $context);
|
||||
|
||||
case 'class-string':
|
||||
$subType = $this->createType($type->genericTypes[0], $context);
|
||||
if (!$subType instanceof Object_ || $subType->getFqsen() === null) {
|
||||
throw new RuntimeException(
|
||||
'A type is missing before a type separator'
|
||||
$subType . ' is not a class string'
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
!in_array($parserContext, [
|
||||
self::PARSER_IN_COMPOUND,
|
||||
self::PARSER_IN_ARRAY_EXPRESSION,
|
||||
self::PARSER_IN_COLLECTION_EXPRESSION,
|
||||
self::PARSER_IN_NULLABLE,
|
||||
], true)
|
||||
) {
|
||||
return new ClassString(
|
||||
$subType->getFqsen()
|
||||
);
|
||||
|
||||
case 'interface-string':
|
||||
$subType = $this->createType($type->genericTypes[0], $context);
|
||||
if (!$subType instanceof Object_ || $subType->getFqsen() === null) {
|
||||
throw new RuntimeException(
|
||||
'Unexpected type separator'
|
||||
$subType . ' is not a class string'
|
||||
);
|
||||
}
|
||||
|
||||
$compoundToken = $token;
|
||||
$tokens->next();
|
||||
} elseif ($token === '?') {
|
||||
if (
|
||||
!in_array($parserContext, [
|
||||
self::PARSER_IN_COMPOUND,
|
||||
self::PARSER_IN_ARRAY_EXPRESSION,
|
||||
self::PARSER_IN_COLLECTION_EXPRESSION,
|
||||
self::PARSER_IN_NULLABLE,
|
||||
], true)
|
||||
) {
|
||||
throw new RuntimeException(
|
||||
'Unexpected nullable character'
|
||||
return new InterfaceString(
|
||||
$subType->getFqsen()
|
||||
);
|
||||
|
||||
case 'list':
|
||||
return new List_(
|
||||
$this->createType($type->genericTypes[0], $context)
|
||||
);
|
||||
|
||||
case 'non-empty-list':
|
||||
return new NonEmptyList(
|
||||
$this->createType($type->genericTypes[0], $context)
|
||||
);
|
||||
|
||||
case 'int':
|
||||
if (isset($type->genericTypes[1]) === false) {
|
||||
throw new RuntimeException('int<min,max> has not the correct format');
|
||||
}
|
||||
|
||||
return new IntegerRange(
|
||||
(string) $type->genericTypes[0],
|
||||
(string) $type->genericTypes[1],
|
||||
);
|
||||
|
||||
case 'iterable':
|
||||
return new Iterable_(
|
||||
...array_reverse(
|
||||
array_map(
|
||||
fn (TypeNode $genericType) => $this->createType($genericType, $context),
|
||||
$type->genericTypes
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
default:
|
||||
$collectionType = $this->createType($type->type, $context);
|
||||
if ($collectionType instanceof Object_ === false) {
|
||||
throw new RuntimeException(sprintf('%s is not a collection', (string) $collectionType));
|
||||
}
|
||||
|
||||
return new Collection(
|
||||
$collectionType->getFqsen(),
|
||||
...array_reverse(
|
||||
array_map(
|
||||
fn (TypeNode $genericType) => $this->createType($genericType, $context),
|
||||
$type->genericTypes
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function createFromCallable(CallableTypeNode $type, Context $context): Callable_
|
||||
{
|
||||
return new Callable_(
|
||||
array_map(
|
||||
function (CallableTypeParameterNode $param) use ($context) {
|
||||
return new CallableParameter(
|
||||
$this->createType($param->type, $context),
|
||||
$param->parameterName !== '' ? trim($param->parameterName, '$') : null,
|
||||
$param->isReference,
|
||||
$param->isVariadic,
|
||||
$param->isOptional
|
||||
);
|
||||
}
|
||||
},
|
||||
$type->parameters
|
||||
),
|
||||
$this->createType($type->returnType, $context),
|
||||
);
|
||||
}
|
||||
|
||||
$tokens->next();
|
||||
$type = $this->parseTypes($tokens, $context, self::PARSER_IN_NULLABLE);
|
||||
$types[] = new Nullable($type);
|
||||
} elseif ($token === '(') {
|
||||
$tokens->next();
|
||||
$type = $this->parseTypes($tokens, $context, self::PARSER_IN_ARRAY_EXPRESSION);
|
||||
private function createFromConst(ConstTypeNode $type, Context $context): Type
|
||||
{
|
||||
switch (true) {
|
||||
case $type->constExpr instanceof ConstExprIntegerNode:
|
||||
return new IntegerValue((int) $type->constExpr->value);
|
||||
|
||||
$token = $tokens->current();
|
||||
if ($token === null) { // Someone did not properly close their array expression ..
|
||||
break;
|
||||
}
|
||||
case $type->constExpr instanceof ConstExprFloatNode:
|
||||
return new FloatValue((float) $type->constExpr->value);
|
||||
|
||||
$tokens->next();
|
||||
case $type->constExpr instanceof ConstExprStringNode:
|
||||
return new StringValue($type->constExpr->value);
|
||||
|
||||
$resolvedType = new Expression($type);
|
||||
|
||||
$types[] = $resolvedType;
|
||||
} elseif ($parserContext === self::PARSER_IN_ARRAY_EXPRESSION && isset($token[0]) && $token[0] === ')') {
|
||||
break;
|
||||
} elseif ($token === '<') {
|
||||
if (count($types) === 0) {
|
||||
throw new RuntimeException(
|
||||
'Unexpected collection operator "<", class name is missing'
|
||||
);
|
||||
}
|
||||
|
||||
$classType = array_pop($types);
|
||||
if ($classType !== null) {
|
||||
if ((string) $classType === 'class-string') {
|
||||
$types[] = $this->resolveClassString($tokens, $context);
|
||||
} elseif ((string) $classType === 'int') {
|
||||
$types[] = $this->resolveIntRange($tokens);
|
||||
} elseif ((string) $classType === 'interface-string') {
|
||||
$types[] = $this->resolveInterfaceString($tokens, $context);
|
||||
} else {
|
||||
$types[] = $this->resolveCollection($tokens, $classType, $context);
|
||||
}
|
||||
}
|
||||
|
||||
$tokens->next();
|
||||
} elseif (
|
||||
$parserContext === self::PARSER_IN_COLLECTION_EXPRESSION
|
||||
&& ($token === '>' || trim($token) === ',')
|
||||
) {
|
||||
break;
|
||||
} elseif ($token === self::OPERATOR_ARRAY) {
|
||||
$last = array_key_last($types);
|
||||
if ($last === null) {
|
||||
throw new InvalidArgumentException('Unexpected array operator');
|
||||
}
|
||||
|
||||
$lastItem = $types[$last];
|
||||
if ($lastItem instanceof Expression) {
|
||||
$lastItem = $lastItem->getValueType();
|
||||
}
|
||||
|
||||
$types[$last] = new Array_($lastItem);
|
||||
|
||||
$tokens->next();
|
||||
} else {
|
||||
$types[] = $this->resolveSingleType($token, $context);
|
||||
$tokens->next();
|
||||
}
|
||||
}
|
||||
|
||||
if ($token === '|' || $token === '&') {
|
||||
throw new RuntimeException(
|
||||
'A type is missing after a type separator'
|
||||
);
|
||||
}
|
||||
|
||||
if (count($types) === 0) {
|
||||
if ($parserContext === self::PARSER_IN_NULLABLE) {
|
||||
throw new RuntimeException(
|
||||
'A type is missing after a nullable character'
|
||||
case $type->constExpr instanceof ConstFetchNode:
|
||||
return new ConstExpression(
|
||||
$this->resolve($type->constExpr->className, $context),
|
||||
$type->constExpr->name
|
||||
);
|
||||
}
|
||||
|
||||
if ($parserContext === self::PARSER_IN_ARRAY_EXPRESSION) {
|
||||
throw new RuntimeException(
|
||||
'A type is missing in an array expression'
|
||||
);
|
||||
}
|
||||
|
||||
if ($parserContext === self::PARSER_IN_COLLECTION_EXPRESSION) {
|
||||
throw new RuntimeException(
|
||||
'A type is missing in a collection expression'
|
||||
);
|
||||
}
|
||||
} elseif (count($types) === 1) {
|
||||
return current($types);
|
||||
default:
|
||||
throw new RuntimeException(sprintf('Unsupported constant type %s', get_class($type)));
|
||||
}
|
||||
|
||||
if ($compoundToken === '|') {
|
||||
return new Compound(array_values($types));
|
||||
}
|
||||
|
||||
return new Intersection(array_values($types));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -475,244 +537,87 @@ final class TypeResolver
|
||||
return new Object_($this->fqsenResolver->resolve($type, $context));
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves class string
|
||||
*
|
||||
* @param ArrayIterator<int, (string|null)> $tokens
|
||||
*/
|
||||
private function resolveClassString(ArrayIterator $tokens, Context $context): Type
|
||||
/** @param TypeNode[] $typeNodes */
|
||||
private function createArray(array $typeNodes, Context $context): Array_
|
||||
{
|
||||
$tokens->next();
|
||||
$types = array_reverse(
|
||||
array_map(
|
||||
fn (TypeNode $node) => $this->createType($node, $context),
|
||||
$typeNodes
|
||||
)
|
||||
);
|
||||
|
||||
$classType = $this->parseTypes($tokens, $context, self::PARSER_IN_COLLECTION_EXPRESSION);
|
||||
|
||||
if (!$classType instanceof Object_ || $classType->getFqsen() === null) {
|
||||
throw new RuntimeException(
|
||||
$classType . ' is not a class string'
|
||||
);
|
||||
if (isset($types[1]) === false) {
|
||||
return new Array_(...$types);
|
||||
}
|
||||
|
||||
$token = $tokens->current();
|
||||
if ($token !== '>') {
|
||||
if (empty($token)) {
|
||||
throw new RuntimeException(
|
||||
'class-string: ">" is missing'
|
||||
);
|
||||
if ($this->validArrayKeyType($types[1]) || $types[1] instanceof ArrayKey) {
|
||||
return new Array_(...$types);
|
||||
}
|
||||
|
||||
if ($types[1] instanceof Compound && $types[1]->getIterator()->count() === 2) {
|
||||
if ($this->validArrayKeyType($types[1]->get(0)) && $this->validArrayKeyType($types[1]->get(1))) {
|
||||
return new Array_(...$types);
|
||||
}
|
||||
|
||||
throw new RuntimeException(
|
||||
'Unexpected character "' . $token . '", ">" is missing'
|
||||
);
|
||||
}
|
||||
|
||||
return new ClassString($classType->getFqsen());
|
||||
throw new RuntimeException('An array can have only integers or strings as keys');
|
||||
}
|
||||
|
||||
private function validArrayKeyType(?Type $type): bool
|
||||
{
|
||||
return $type instanceof String_ || $type instanceof Integer;
|
||||
}
|
||||
|
||||
private function parse(TokenIterator $tokenIterator): TypeNode
|
||||
{
|
||||
try {
|
||||
$ast = $this->typeParser->parse($tokenIterator);
|
||||
} catch (ParserException $e) {
|
||||
throw new RuntimeException($e->getMessage(), 0, $e);
|
||||
}
|
||||
|
||||
return $ast;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves integer ranges
|
||||
* Will try to parse unsupported type notations by phpstan
|
||||
*
|
||||
* @param ArrayIterator<int, (string|null)> $tokens
|
||||
* The phpstan parser doesn't support the illegal nullable combinations like this library does.
|
||||
* This method will warn the user about those notations but for bc purposes we will still have it here.
|
||||
*/
|
||||
private function resolveIntRange(ArrayIterator $tokens): Type
|
||||
private function tryParseRemainingCompoundTypes(TokenIterator $tokenIterator, Context $context, Type $type): Type
|
||||
{
|
||||
$tokens->next();
|
||||
|
||||
$token = '';
|
||||
$minValue = null;
|
||||
$maxValue = null;
|
||||
$commaFound = false;
|
||||
$tokenCounter = 0;
|
||||
while ($tokens->valid()) {
|
||||
$tokenCounter++;
|
||||
$token = $tokens->current();
|
||||
if ($token === null) {
|
||||
throw new RuntimeException(
|
||||
'Unexpected nullable character'
|
||||
);
|
||||
}
|
||||
|
||||
$token = trim($token);
|
||||
|
||||
if ($token === '>') {
|
||||
break;
|
||||
}
|
||||
|
||||
if ($token === ',') {
|
||||
$commaFound = true;
|
||||
}
|
||||
|
||||
if ($commaFound === false && $minValue === null) {
|
||||
if (is_numeric($token) || $token === 'max' || $token === 'min') {
|
||||
$minValue = $token;
|
||||
}
|
||||
}
|
||||
|
||||
if ($commaFound === true && $maxValue === null) {
|
||||
if (is_numeric($token) || $token === 'max' || $token === 'min') {
|
||||
$maxValue = $token;
|
||||
}
|
||||
}
|
||||
|
||||
$tokens->next();
|
||||
}
|
||||
|
||||
if ($token !== '>') {
|
||||
if (empty($token)) {
|
||||
throw new RuntimeException(
|
||||
'interface-string: ">" is missing'
|
||||
);
|
||||
}
|
||||
|
||||
throw new RuntimeException(
|
||||
'Unexpected character "' . $token . '", ">" is missing'
|
||||
);
|
||||
}
|
||||
|
||||
if ($minValue === null || $maxValue === null || $tokenCounter > 4) {
|
||||
throw new RuntimeException(
|
||||
'int<min,max> has not the correct format'
|
||||
);
|
||||
}
|
||||
|
||||
return new IntegerRange($minValue, $maxValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves class string
|
||||
*
|
||||
* @param ArrayIterator<int, (string|null)> $tokens
|
||||
*/
|
||||
private function resolveInterfaceString(ArrayIterator $tokens, Context $context): Type
|
||||
{
|
||||
$tokens->next();
|
||||
|
||||
$classType = $this->parseTypes($tokens, $context, self::PARSER_IN_COLLECTION_EXPRESSION);
|
||||
|
||||
if (!$classType instanceof Object_ || $classType->getFqsen() === null) {
|
||||
throw new RuntimeException(
|
||||
$classType . ' is not a interface string'
|
||||
);
|
||||
}
|
||||
|
||||
$token = $tokens->current();
|
||||
if ($token !== '>') {
|
||||
if (empty($token)) {
|
||||
throw new RuntimeException(
|
||||
'interface-string: ">" is missing'
|
||||
);
|
||||
}
|
||||
|
||||
throw new RuntimeException(
|
||||
'Unexpected character "' . $token . '", ">" is missing'
|
||||
);
|
||||
}
|
||||
|
||||
return new InterfaceString($classType->getFqsen());
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the collection values and keys
|
||||
*
|
||||
* @param ArrayIterator<int, (string|null)> $tokens
|
||||
*
|
||||
* @return Array_|Iterable_|Collection
|
||||
*/
|
||||
private function resolveCollection(ArrayIterator $tokens, Type $classType, Context $context): Type
|
||||
{
|
||||
$isArray = ((string) $classType === 'array');
|
||||
$isIterable = ((string) $classType === 'iterable');
|
||||
$isList = ((string) $classType === 'list');
|
||||
|
||||
// allow only "array", "iterable" or class name before "<"
|
||||
if (
|
||||
!$isArray && !$isIterable && !$isList
|
||||
&& (!$classType instanceof Object_ || $classType->getFqsen() === null)
|
||||
$tokenIterator->isCurrentTokenType(Lexer::TOKEN_UNION) ||
|
||||
$tokenIterator->isCurrentTokenType(Lexer::TOKEN_INTERSECTION)
|
||||
) {
|
||||
throw new RuntimeException(
|
||||
$classType . ' is not a collection'
|
||||
Deprecation::trigger(
|
||||
'phpdocumentor/type-resolver',
|
||||
'https://github.com/phpDocumentor/TypeResolver/issues/184',
|
||||
'Legacy nullable type detected, please update your code as
|
||||
you are using nullable types in a docblock. support will be removed in v2.0.0',
|
||||
);
|
||||
}
|
||||
|
||||
$tokens->next();
|
||||
|
||||
$valueType = $this->parseTypes($tokens, $context, self::PARSER_IN_COLLECTION_EXPRESSION);
|
||||
$keyType = null;
|
||||
|
||||
$token = $tokens->current();
|
||||
if ($token !== null && trim($token) === ',' && !$isList) {
|
||||
// if we have a comma, then we just parsed the key type, not the value type
|
||||
$keyType = $valueType;
|
||||
if ($isArray) {
|
||||
// check the key type for an "array" collection. We allow only
|
||||
// strings or integers.
|
||||
if (
|
||||
!$keyType instanceof ArrayKey &&
|
||||
!$keyType instanceof String_ &&
|
||||
!$keyType instanceof Integer &&
|
||||
!$keyType instanceof Compound
|
||||
) {
|
||||
throw new RuntimeException(
|
||||
'An array can have only integers or strings as keys'
|
||||
);
|
||||
}
|
||||
|
||||
if ($keyType instanceof Compound) {
|
||||
foreach ($keyType->getIterator() as $item) {
|
||||
if (
|
||||
!$item instanceof ArrayKey &&
|
||||
!$item instanceof String_ &&
|
||||
!$item instanceof Integer
|
||||
) {
|
||||
throw new RuntimeException(
|
||||
'An array can have only integers or strings as keys'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
$continue = true;
|
||||
while ($continue) {
|
||||
$continue = false;
|
||||
while ($tokenIterator->tryConsumeTokenType(Lexer::TOKEN_UNION)) {
|
||||
$ast = $this->parse($tokenIterator);
|
||||
$type2 = $this->createType($ast, $context);
|
||||
$type = new Compound([$type, $type2]);
|
||||
$continue = true;
|
||||
}
|
||||
|
||||
$tokens->next();
|
||||
// now let's parse the value type
|
||||
$valueType = $this->parseTypes($tokens, $context, self::PARSER_IN_COLLECTION_EXPRESSION);
|
||||
}
|
||||
|
||||
$token = $tokens->current();
|
||||
if ($token !== '>') {
|
||||
if (empty($token)) {
|
||||
throw new RuntimeException(
|
||||
'Collection: ">" is missing'
|
||||
);
|
||||
while ($tokenIterator->tryConsumeTokenType(Lexer::TOKEN_INTERSECTION)) {
|
||||
$ast = $this->typeParser->parse($tokenIterator);
|
||||
$type2 = $this->createType($ast, $context);
|
||||
$type = new Intersection([$type, $type2]);
|
||||
$continue = true;
|
||||
}
|
||||
|
||||
throw new RuntimeException(
|
||||
'Unexpected character "' . $token . '", ">" is missing'
|
||||
);
|
||||
}
|
||||
|
||||
if ($isArray) {
|
||||
return new Array_($valueType, $keyType);
|
||||
}
|
||||
|
||||
if ($isIterable) {
|
||||
return new Iterable_($valueType, $keyType);
|
||||
}
|
||||
|
||||
if ($isList) {
|
||||
return new List_($valueType);
|
||||
}
|
||||
|
||||
if ($classType instanceof Object_) {
|
||||
return $this->makeCollectionFromObject($classType, $valueType, $keyType);
|
||||
}
|
||||
|
||||
throw new RuntimeException('Invalid $classType provided');
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-pure
|
||||
*/
|
||||
private function makeCollectionFromObject(Object_ $object, Type $valueType, ?Type $keyType = null): Collection
|
||||
{
|
||||
return new Collection($object->getFqsen(), $valueType, $keyType);
|
||||
return $type;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ abstract class AggregatedType implements Type, IteratorAggregate
|
||||
*/
|
||||
private function add(Type $type): void
|
||||
{
|
||||
if ($type instanceof self) {
|
||||
if ($type instanceof static) {
|
||||
foreach ($type->getIterator() as $subType) {
|
||||
$this->add($subType);
|
||||
}
|
||||
|
||||
72
vendor/phpdocumentor/type-resolver/src/Types/CallableParameter.php
vendored
Normal file
72
vendor/phpdocumentor/type-resolver/src/Types/CallableParameter.php
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of phpDocumentor.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @link http://phpdoc.org
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace phpDocumentor\Reflection\Types;
|
||||
|
||||
use phpDocumentor\Reflection\Type;
|
||||
|
||||
/**
|
||||
* Value Object representing a Callable parameters.
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
final class CallableParameter
|
||||
{
|
||||
private Type $type;
|
||||
|
||||
private bool $isReference;
|
||||
|
||||
private bool $isVariadic;
|
||||
|
||||
private bool $isOptional;
|
||||
|
||||
private ?string $name;
|
||||
|
||||
public function __construct(
|
||||
Type $type,
|
||||
?string $name = null,
|
||||
bool $isReference = false,
|
||||
bool $isVariadic = false,
|
||||
bool $isOptional = false
|
||||
) {
|
||||
$this->type = $type;
|
||||
$this->isReference = $isReference;
|
||||
$this->isVariadic = $isVariadic;
|
||||
$this->isOptional = $isOptional;
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function getName(): ?string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getType(): Type
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function isReference(): bool
|
||||
{
|
||||
return $this->isReference;
|
||||
}
|
||||
|
||||
public function isVariadic(): bool
|
||||
{
|
||||
return $this->isVariadic;
|
||||
}
|
||||
|
||||
public function isOptional(): bool
|
||||
{
|
||||
return $this->isOptional;
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,30 @@ use phpDocumentor\Reflection\Type;
|
||||
*/
|
||||
final class Callable_ implements Type
|
||||
{
|
||||
private ?Type $returnType;
|
||||
/** @var CallableParameter[] */
|
||||
private array $parameters;
|
||||
|
||||
/**
|
||||
* @param CallableParameter[] $parameters
|
||||
*/
|
||||
public function __construct(array $parameters = [], ?Type $returnType = null)
|
||||
{
|
||||
$this->parameters = $parameters;
|
||||
$this->returnType = $returnType;
|
||||
}
|
||||
|
||||
/** @return CallableParameter[] */
|
||||
public function getParameters(): array
|
||||
{
|
||||
return $this->parameters;
|
||||
}
|
||||
|
||||
public function getReturnType(): ?Type
|
||||
{
|
||||
return $this->returnType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a rendered output of the Type as it would be used in a DocBlock.
|
||||
*/
|
||||
|
||||
@@ -181,6 +181,7 @@ final class ContextFactory
|
||||
$currentNamespace = $this->parseNamespace($tokens);
|
||||
break;
|
||||
case T_CLASS:
|
||||
case T_TRAIT:
|
||||
// Fast-forward the iterator through the class so that any
|
||||
// T_USE tokens found within are skipped - these are not
|
||||
// valid namespace use statements so should be ignored.
|
||||
|
||||
16
vendor/phpstan/extension-installer/README.md
vendored
16
vendor/phpstan/extension-installer/README.md
vendored
@@ -72,6 +72,22 @@ Add `phpstan` key in the extension `composer.json`'s `extra` section:
|
||||
}
|
||||
```
|
||||
|
||||
## Ignoring a particular extension
|
||||
|
||||
You may want to disable auto-installation of a particular extension to handle installation manually. Ignore an extension by adding an `extra.phpstan/extension-installer.ignore` array in `composer.json` that specifies a list of packages to ignore:
|
||||
|
||||
```json
|
||||
{
|
||||
"extra": {
|
||||
"phpstan/extension-installer": {
|
||||
"ignore": [
|
||||
"phpstan/phpstan-phpunit"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Limitations
|
||||
|
||||
The extension installer depends on Composer script events, therefore you cannot use `--no-scripts` flag.
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
{
|
||||
"require-dev": {
|
||||
"consistence-community/coding-standard": "^3.10",
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
|
||||
"slevomat/coding-standard": "^7.0"
|
||||
"consistence-community/coding-standard": "^3.11.0",
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^1.0.0",
|
||||
"slevomat/coding-standard": "^8.8.0",
|
||||
"squizlabs/php_codesniffer": "^3.5.3"
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
|
||||
119
vendor/phpstan/extension-installer/build-cs/composer.lock
generated
vendored
119
vendor/phpstan/extension-installer/build-cs/composer.lock
generated
vendored
@@ -4,35 +4,35 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "4485bbedba7bcc71ace5f69dbb9b6c47",
|
||||
"content-hash": "e69c1916405a7e3c8001c1b609a0ee61",
|
||||
"packages": [],
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "consistence-community/coding-standard",
|
||||
"version": "3.11.1",
|
||||
"version": "3.11.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/consistence-community/coding-standard.git",
|
||||
"reference": "4632fead8c9ee8f50044fcbce9f66c797b34c0df"
|
||||
"reference": "f38e06327d5bf80ff5ff523a2c05e623b5e8d8b1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/consistence-community/coding-standard/zipball/4632fead8c9ee8f50044fcbce9f66c797b34c0df",
|
||||
"reference": "4632fead8c9ee8f50044fcbce9f66c797b34c0df",
|
||||
"url": "https://api.github.com/repos/consistence-community/coding-standard/zipball/f38e06327d5bf80ff5ff523a2c05e623b5e8d8b1",
|
||||
"reference": "f38e06327d5bf80ff5ff523a2c05e623b5e8d8b1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.4",
|
||||
"slevomat/coding-standard": "~7.0",
|
||||
"squizlabs/php_codesniffer": "~3.6.0"
|
||||
"php": "~8.0",
|
||||
"slevomat/coding-standard": "~8.0",
|
||||
"squizlabs/php_codesniffer": "~3.7.0"
|
||||
},
|
||||
"replace": {
|
||||
"consistence/coding-standard": "3.10.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"phing/phing": "2.16.4",
|
||||
"php-parallel-lint/php-parallel-lint": "1.3.0",
|
||||
"phpunit/phpunit": "9.5.4"
|
||||
"phing/phing": "2.17.0",
|
||||
"php-parallel-lint/php-parallel-lint": "1.3.1",
|
||||
"phpunit/phpunit": "9.5.10"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@@ -70,41 +70,44 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/consistence-community/coding-standard/issues",
|
||||
"source": "https://github.com/consistence-community/coding-standard/tree/3.11.1"
|
||||
"source": "https://github.com/consistence-community/coding-standard/tree/3.11.3"
|
||||
},
|
||||
"time": "2021-05-03T18:13:22+00:00"
|
||||
"time": "2023-03-27T14:55:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "dealerdirect/phpcodesniffer-composer-installer",
|
||||
"version": "v0.7.2",
|
||||
"version": "v1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git",
|
||||
"reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db"
|
||||
"url": "https://github.com/PHPCSStandards/composer-installer.git",
|
||||
"reference": "4be43904336affa5c2f70744a348312336afd0da"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db",
|
||||
"reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db",
|
||||
"url": "https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/4be43904336affa5c2f70744a348312336afd0da",
|
||||
"reference": "4be43904336affa5c2f70744a348312336afd0da",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer-plugin-api": "^1.0 || ^2.0",
|
||||
"php": ">=5.3",
|
||||
"php": ">=5.4",
|
||||
"squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"composer/composer": "*",
|
||||
"ext-json": "*",
|
||||
"ext-zip": "*",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.3.1",
|
||||
"phpcompatibility/php-compatibility": "^9.0"
|
||||
"phpcompatibility/php-compatibility": "^9.0",
|
||||
"yoast/phpunit-polyfills": "^1.0"
|
||||
},
|
||||
"type": "composer-plugin",
|
||||
"extra": {
|
||||
"class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin"
|
||||
"class": "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/"
|
||||
"PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
@@ -120,7 +123,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Contributors",
|
||||
"homepage": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer/graphs/contributors"
|
||||
"homepage": "https://github.com/PHPCSStandards/composer-installer/graphs/contributors"
|
||||
}
|
||||
],
|
||||
"description": "PHP_CodeSniffer Standards Composer Installer Plugin",
|
||||
@@ -144,23 +147,23 @@
|
||||
"tests"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues",
|
||||
"source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer"
|
||||
"issues": "https://github.com/PHPCSStandards/composer-installer/issues",
|
||||
"source": "https://github.com/PHPCSStandards/composer-installer"
|
||||
},
|
||||
"time": "2022-02-04T12:51:07+00:00"
|
||||
"time": "2023-01-05T11:28:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpdoc-parser",
|
||||
"version": "1.5.1",
|
||||
"version": "1.20.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpstan/phpdoc-parser.git",
|
||||
"reference": "981cc368a216c988e862a75e526b6076987d1b50"
|
||||
"reference": "7d568c87a9df9c5f7e8b5f075fc469aa8cb0a4cd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/981cc368a216c988e862a75e526b6076987d1b50",
|
||||
"reference": "981cc368a216c988e862a75e526b6076987d1b50",
|
||||
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/7d568c87a9df9c5f7e8b5f075fc469aa8cb0a4cd",
|
||||
"reference": "7d568c87a9df9c5f7e8b5f075fc469aa8cb0a4cd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -170,6 +173,7 @@
|
||||
"php-parallel-lint/php-parallel-lint": "^1.2",
|
||||
"phpstan/extension-installer": "^1.0",
|
||||
"phpstan/phpstan": "^1.5",
|
||||
"phpstan/phpstan-phpunit": "^1.1",
|
||||
"phpstan/phpstan-strict-rules": "^1.0",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"symfony/process": "^5.2"
|
||||
@@ -189,48 +193,48 @@
|
||||
"description": "PHPDoc parser with support for nullable, intersection and generic types",
|
||||
"support": {
|
||||
"issues": "https://github.com/phpstan/phpdoc-parser/issues",
|
||||
"source": "https://github.com/phpstan/phpdoc-parser/tree/1.5.1"
|
||||
"source": "https://github.com/phpstan/phpdoc-parser/tree/1.20.4"
|
||||
},
|
||||
"time": "2022-05-05T11:32:40+00:00"
|
||||
"time": "2023-05-02T09:19:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "slevomat/coding-standard",
|
||||
"version": "7.2.1",
|
||||
"version": "8.12.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/slevomat/coding-standard.git",
|
||||
"reference": "aff06ae7a84e4534bf6f821dc982a93a5d477c90"
|
||||
"reference": "cc04334ed0ce5a251389112fbd2dbe1dbc931ae8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/slevomat/coding-standard/zipball/aff06ae7a84e4534bf6f821dc982a93a5d477c90",
|
||||
"reference": "aff06ae7a84e4534bf6f821dc982a93a5d477c90",
|
||||
"url": "https://api.github.com/repos/slevomat/coding-standard/zipball/cc04334ed0ce5a251389112fbd2dbe1dbc931ae8",
|
||||
"reference": "cc04334ed0ce5a251389112fbd2dbe1dbc931ae8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7",
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7 || ^1.0",
|
||||
"php": "^7.2 || ^8.0",
|
||||
"phpstan/phpdoc-parser": "^1.5.1",
|
||||
"squizlabs/php_codesniffer": "^3.6.2"
|
||||
"phpstan/phpdoc-parser": ">=1.20.0 <1.21.0",
|
||||
"squizlabs/php_codesniffer": "^3.7.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phing/phing": "2.17.3",
|
||||
"phing/phing": "2.17.4",
|
||||
"php-parallel-lint/php-parallel-lint": "1.3.2",
|
||||
"phpstan/phpstan": "1.4.10|1.7.1",
|
||||
"phpstan/phpstan-deprecation-rules": "1.0.0",
|
||||
"phpstan/phpstan-phpunit": "1.0.0|1.1.1",
|
||||
"phpstan/phpstan-strict-rules": "1.2.3",
|
||||
"phpunit/phpunit": "7.5.20|8.5.21|9.5.20"
|
||||
"phpstan/phpstan": "1.10.15",
|
||||
"phpstan/phpstan-deprecation-rules": "1.1.3",
|
||||
"phpstan/phpstan-phpunit": "1.3.11",
|
||||
"phpstan/phpstan-strict-rules": "1.5.1",
|
||||
"phpunit/phpunit": "7.5.20|8.5.21|9.6.8|10.1.3"
|
||||
},
|
||||
"type": "phpcodesniffer-standard",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "7.x-dev"
|
||||
"dev-master": "8.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"SlevomatCodingStandard\\": "SlevomatCodingStandard"
|
||||
"SlevomatCodingStandard\\": "SlevomatCodingStandard/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
@@ -238,9 +242,13 @@
|
||||
"MIT"
|
||||
],
|
||||
"description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.",
|
||||
"keywords": [
|
||||
"dev",
|
||||
"phpcs"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/slevomat/coding-standard/issues",
|
||||
"source": "https://github.com/slevomat/coding-standard/tree/7.2.1"
|
||||
"source": "https://github.com/slevomat/coding-standard/tree/8.12.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -252,20 +260,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-05-25T10:58:12+00:00"
|
||||
"time": "2023-05-14T20:06:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "squizlabs/php_codesniffer",
|
||||
"version": "3.6.2",
|
||||
"version": "3.7.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
|
||||
"reference": "5e4e71592f69da17871dba6e80dd51bce74a351a"
|
||||
"reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/5e4e71592f69da17871dba6e80dd51bce74a351a",
|
||||
"reference": "5e4e71592f69da17871dba6e80dd51bce74a351a",
|
||||
"url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ed8e00df0a83aa96acf703f8c2979ff33341f879",
|
||||
"reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -301,14 +309,15 @@
|
||||
"homepage": "https://github.com/squizlabs/PHP_CodeSniffer",
|
||||
"keywords": [
|
||||
"phpcs",
|
||||
"standards"
|
||||
"standards",
|
||||
"static analysis"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues",
|
||||
"source": "https://github.com/squizlabs/PHP_CodeSniffer",
|
||||
"wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki"
|
||||
},
|
||||
"time": "2021-12-12T21:44:58+00:00"
|
||||
"time": "2023-02-22T23:07:41+00:00"
|
||||
}
|
||||
],
|
||||
"aliases": [],
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"require": {
|
||||
"php": "^7.2 || ^8.0",
|
||||
"composer-plugin-api": "^2.0",
|
||||
"phpstan/phpstan": "^1.8.0"
|
||||
"phpstan/phpstan": "^1.9.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"composer/composer": "^2.0",
|
||||
|
||||
@@ -3,21 +3,30 @@
|
||||
namespace PHPStan\ExtensionInstaller;
|
||||
|
||||
/**
|
||||
* This is a stub class: it is in place only for scenarios where Composer
|
||||
* is run with a `--no-scripts` flag, in which scenarios this stub class
|
||||
* is not being replaced.
|
||||
*
|
||||
* If you are reading this docBlock inside your `vendor/` dir, then this means
|
||||
* that phpstan/extension-installer didn't correctly install.
|
||||
*
|
||||
* This class is generated by phpstan/extension-installer.
|
||||
* @internal
|
||||
*/
|
||||
final class GeneratedConfig
|
||||
{
|
||||
|
||||
public const EXTENSIONS = [];
|
||||
public const EXTENSIONS = array (
|
||||
'phpstan/phpstan-deprecation-rules' =>
|
||||
array (
|
||||
'install_path' => '/storage/var/www/html/developers/clemens/core_data/php_libraries/trunk/vendor/phpstan/phpstan-deprecation-rules',
|
||||
'relative_install_path' => '../../phpstan-deprecation-rules',
|
||||
'extra' =>
|
||||
array (
|
||||
'includes' =>
|
||||
array (
|
||||
0 => 'rules.neon',
|
||||
),
|
||||
),
|
||||
'version' => '1.1.3',
|
||||
),
|
||||
);
|
||||
|
||||
public const NOT_INSTALLED = [];
|
||||
public const NOT_INSTALLED = array (
|
||||
);
|
||||
|
||||
private function __construct()
|
||||
{
|
||||
|
||||
@@ -19,6 +19,7 @@ use function is_file;
|
||||
use function ksort;
|
||||
use function md5;
|
||||
use function md5_file;
|
||||
use function sort;
|
||||
use function sprintf;
|
||||
use function strpos;
|
||||
use function var_export;
|
||||
@@ -97,9 +98,18 @@ PHP;
|
||||
}
|
||||
$notInstalledPackages = [];
|
||||
$installedPackages = [];
|
||||
$ignoredPackages = [];
|
||||
|
||||
$data = [];
|
||||
$fs = new Filesystem();
|
||||
$ignore = [];
|
||||
|
||||
$packageExtra = $composer->getPackage()->getExtra();
|
||||
|
||||
if (isset($packageExtra['phpstan/extension-installer']['ignore'])) {
|
||||
$ignore = $packageExtra['phpstan/extension-installer']['ignore'];
|
||||
}
|
||||
|
||||
foreach ($composer->getRepositoryManager()->getLocalRepository()->getPackages() as $package) {
|
||||
if (
|
||||
$package->getType() !== 'phpstan-extension'
|
||||
@@ -119,7 +129,15 @@ PHP;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (in_array($package->getName(), $ignore, true)) {
|
||||
$ignoredPackages[] = $package->getName();
|
||||
continue;
|
||||
}
|
||||
|
||||
$installPath = $installationManager->getInstallPath($package);
|
||||
if ($installPath === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$absoluteInstallPath = $fs->isAbsolutePath($installPath)
|
||||
? $installPath
|
||||
@@ -138,6 +156,7 @@ PHP;
|
||||
ksort($data);
|
||||
ksort($installedPackages);
|
||||
ksort($notInstalledPackages);
|
||||
sort($ignoredPackages);
|
||||
|
||||
$generatedConfigFileContents = sprintf(self::$generatedFileTemplate, var_export($data, true), var_export($notInstalledPackages, true));
|
||||
file_put_contents($generatedConfigFilePath, $generatedConfigFileContents);
|
||||
@@ -154,6 +173,10 @@ PHP;
|
||||
foreach (array_keys($notInstalledPackages) as $name) {
|
||||
$io->write(sprintf('> <comment>%s:</comment> not supported', $name));
|
||||
}
|
||||
|
||||
foreach ($ignoredPackages as $name) {
|
||||
$io->write(sprintf('> <comment>%s:</comment> ignored', $name));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
21
vendor/phpstan/phpdoc-parser/LICENSE
vendored
Normal file
21
vendor/phpstan/phpdoc-parser/LICENSE
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2016 Ondřej Mirtes
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
121
vendor/phpstan/phpdoc-parser/README.md
vendored
Normal file
121
vendor/phpstan/phpdoc-parser/README.md
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
<h1 align="center">PHPDoc Parser for PHPStan</h1>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/phpstan/phpdoc-parser/actions"><img src="https://github.com/phpstan/phpdoc-parser/workflows/Build/badge.svg" alt="Build Status"></a>
|
||||
<a href="https://packagist.org/packages/phpstan/phpdoc-parser"><img src="https://poser.pugx.org/phpstan/phpdoc-parser/v/stable" alt="Latest Stable Version"></a>
|
||||
<a href="https://choosealicense.com/licenses/mit/"><img src="https://poser.pugx.org/phpstan/phpstan/license" alt="License"></a>
|
||||
<a href="https://phpstan.org/"><img src="https://img.shields.io/badge/PHPStan-enabled-brightgreen.svg?style=flat" alt="PHPStan Enabled"></a>
|
||||
</p>
|
||||
|
||||
This library `phpstan/phpdoc-parser` represents PHPDocs with an AST (Abstract Syntax Tree). It supports parsing and modifying PHPDocs.
|
||||
|
||||
For the complete list of supported PHPDoc features check out PHPStan documentation. PHPStan is the main (but not the only) user of this library.
|
||||
|
||||
* [PHPDoc Basics](https://phpstan.org/writing-php-code/phpdocs-basics) (list of PHPDoc tags)
|
||||
* [PHPDoc Types](https://phpstan.org/writing-php-code/phpdoc-types) (list of PHPDoc types)
|
||||
* [phpdoc-parser API Reference](https://phpstan.github.io/phpdoc-parser/namespace-PHPStan.PhpDocParser.html) with all the AST node types etc.
|
||||
|
||||
This parser also supports parsing [Doctrine Annotations](https://github.com/doctrine/annotations). The AST nodes live in the [PHPStan\PhpDocParser\Ast\PhpDoc\Doctrine namespace](https://phpstan.github.io/phpdoc-parser/namespace-PHPStan.PhpDocParser.Ast.PhpDoc.Doctrine.html). The support needs to be turned on by setting `bool $parseDoctrineAnnotations` to `true` in `Lexer` and `PhpDocParser` class constructors.
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
composer require phpstan/phpdoc-parser
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
|
||||
use PHPStan\PhpDocParser\Lexer\Lexer;
|
||||
use PHPStan\PhpDocParser\Parser\ConstExprParser;
|
||||
use PHPStan\PhpDocParser\Parser\PhpDocParser;
|
||||
use PHPStan\PhpDocParser\Parser\TokenIterator;
|
||||
use PHPStan\PhpDocParser\Parser\TypeParser;
|
||||
|
||||
// basic setup
|
||||
|
||||
$lexer = new Lexer();
|
||||
$constExprParser = new ConstExprParser();
|
||||
$typeParser = new TypeParser($constExprParser);
|
||||
$phpDocParser = new PhpDocParser($typeParser, $constExprParser);
|
||||
|
||||
// parsing and reading a PHPDoc string
|
||||
|
||||
$tokens = new TokenIterator($lexer->tokenize('/** @param Lorem $a */'));
|
||||
$phpDocNode = $phpDocParser->parse($tokens); // PhpDocNode
|
||||
$paramTags = $phpDocNode->getParamTagValues(); // ParamTagValueNode[]
|
||||
echo $paramTags[0]->parameterName; // '$a'
|
||||
echo $paramTags[0]->type; // IdentifierTypeNode - 'Lorem'
|
||||
```
|
||||
|
||||
### Format-preserving printer
|
||||
|
||||
This component can be used to modify the AST
|
||||
and print it again as close as possible to the original.
|
||||
|
||||
It's heavily inspired by format-preserving printer component in [nikic/PHP-Parser](https://github.com/nikic/PHP-Parser).
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeTraverser;
|
||||
use PHPStan\PhpDocParser\Ast\NodeVisitor\CloningVisitor;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
|
||||
use PHPStan\PhpDocParser\Lexer\Lexer;
|
||||
use PHPStan\PhpDocParser\Parser\ConstExprParser;
|
||||
use PHPStan\PhpDocParser\Parser\PhpDocParser;
|
||||
use PHPStan\PhpDocParser\Parser\TokenIterator;
|
||||
use PHPStan\PhpDocParser\Parser\TypeParser;
|
||||
use PHPStan\PhpDocParser\Printer\Printer;
|
||||
|
||||
// basic setup with enabled required lexer attributes
|
||||
|
||||
$usedAttributes = ['lines' => true, 'indexes' => true];
|
||||
|
||||
$lexer = new Lexer();
|
||||
$constExprParser = new ConstExprParser(true, true, $usedAttributes);
|
||||
$typeParser = new TypeParser($constExprParser, true, $usedAttributes);
|
||||
$phpDocParser = new PhpDocParser($typeParser, $constExprParser, true, true, $usedAttributes);
|
||||
|
||||
$tokens = new TokenIterator($lexer->tokenize('/** @param Lorem $a */'));
|
||||
$phpDocNode = $phpDocParser->parse($tokens); // PhpDocNode
|
||||
|
||||
$cloningTraverser = new NodeTraverser([new CloningVisitor()]);
|
||||
|
||||
/** @var PhpDocNode $newPhpDocNode */
|
||||
[$newPhpDocNode] = $cloningTraverser->traverse([$phpDocNode]);
|
||||
|
||||
// change something in $newPhpDocNode
|
||||
$newPhpDocNode->getParamTagValues()[0]->type = new IdentifierTypeNode('Ipsum');
|
||||
|
||||
// print changed PHPDoc
|
||||
$printer = new Printer();
|
||||
$newPhpDoc = $printer->printFormatPreserving($newPhpDocNode, $phpDocNode, $tokens);
|
||||
echo $newPhpDoc; // '/** @param Ipsum $a */'
|
||||
```
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
This project adheres to a [Contributor Code of Conduct](CODE_OF_CONDUCT.md). By participating in this project and its community, you are expected to uphold this code.
|
||||
|
||||
## Building
|
||||
|
||||
Initially you need to run `composer install`, or `composer update` in case you aren't working in a folder which was built before.
|
||||
|
||||
Afterwards you can either run the whole build including linting and coding standards using
|
||||
|
||||
make
|
||||
|
||||
or run only tests using
|
||||
|
||||
make tests
|
||||
44
vendor/phpstan/phpdoc-parser/composer.json
vendored
Normal file
44
vendor/phpstan/phpdoc-parser/composer.json
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"name": "phpstan/phpdoc-parser",
|
||||
"description": "PHPDoc parser with support for nullable, intersection and generic types",
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^7.2 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/annotations": "^2.0",
|
||||
"nikic/php-parser": "^4.15",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.2",
|
||||
"phpstan/extension-installer": "^1.0",
|
||||
"phpstan/phpstan": "^1.5",
|
||||
"phpstan/phpstan-phpunit": "^1.1",
|
||||
"phpstan/phpstan-strict-rules": "^1.0",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"symfony/process": "^5.2"
|
||||
},
|
||||
"config": {
|
||||
"platform": {
|
||||
"php": "7.4.6"
|
||||
},
|
||||
"sort-packages": true,
|
||||
"allow-plugins": {
|
||||
"phpstan/extension-installer": true
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"PHPStan\\PhpDocParser\\": [
|
||||
"src/"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"PHPStan\\PhpDocParser\\": [
|
||||
"tests/PHPStan"
|
||||
]
|
||||
}
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true
|
||||
}
|
||||
31
vendor/phpstan/phpdoc-parser/phpstan-baseline.neon
vendored
Normal file
31
vendor/phpstan/phpdoc-parser/phpstan-baseline.neon
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
parameters:
|
||||
ignoreErrors:
|
||||
-
|
||||
message: "#^Method PHPStan\\\\PhpDocParser\\\\Ast\\\\ConstExpr\\\\QuoteAwareConstExprStringNode\\:\\:escapeDoubleQuotedString\\(\\) should return string but returns string\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/Ast/ConstExpr/QuoteAwareConstExprStringNode.php
|
||||
|
||||
-
|
||||
message: "#^Cannot use array destructuring on array\\<int, array\\<PHPStan\\\\PhpDocParser\\\\Ast\\\\Node\\>\\|int\\|string\\>\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/Ast/NodeTraverser.php
|
||||
|
||||
-
|
||||
message: "#^Strict comparison using \\=\\=\\= between 2 and 2 will always evaluate to true\\.$#"
|
||||
count: 2
|
||||
path: src/Ast/NodeTraverser.php
|
||||
|
||||
-
|
||||
message: "#^Variable property access on PHPStan\\\\PhpDocParser\\\\Ast\\\\Node\\.$#"
|
||||
count: 1
|
||||
path: src/Ast/NodeTraverser.php
|
||||
|
||||
-
|
||||
message: "#^Method PHPStan\\\\PhpDocParser\\\\Parser\\\\StringUnescaper\\:\\:parseEscapeSequences\\(\\) should return string but returns string\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/Parser/StringUnescaper.php
|
||||
|
||||
-
|
||||
message: "#^Variable property access on PHPStan\\\\PhpDocParser\\\\Ast\\\\Node\\.$#"
|
||||
count: 2
|
||||
path: src/Printer/Printer.php
|
||||
34
vendor/phpstan/phpdoc-parser/src/Ast/AbstractNodeVisitor.php
vendored
Normal file
34
vendor/phpstan/phpdoc-parser/src/Ast/AbstractNodeVisitor.php
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace PHPStan\PhpDocParser\Ast;
|
||||
|
||||
/**
|
||||
* Inspired by https://github.com/nikic/PHP-Parser/tree/36a6dcd04e7b0285e8f0868f44bd4927802f7df1
|
||||
*
|
||||
* Copyright (c) 2011, Nikita Popov
|
||||
* All rights reserved.
|
||||
*/
|
||||
abstract class AbstractNodeVisitor implements NodeVisitor // phpcs:ignore SlevomatCodingStandard.Classes.SuperfluousAbstractClassNaming.SuperfluousPrefix
|
||||
{
|
||||
|
||||
public function beforeTraverse(array $nodes): ?array
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function enterNode(Node $node)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function leaveNode(Node $node)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function afterTraverse(array $nodes): ?array
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user