Compare commits

..

6 Commits

Author SHA1 Message Date
Clemens Schwaighofer
1716b2c627 Fix in EditUser Table Array query load for languages
Also split all queries into multi line ones
Fixes in Form\Generate for TableArray Interface location move
Update EditBase to new and old edit schema (scheme) file name
2023-02-28 10:41:06 +09:00
Clemens Schwaighofer
a0126f70ab Bug fix release for TableArray Classes
TableArray could not find the Interface class. moved it to a subfolder
nested in the TableArray folder.
2023-02-28 09:07:16 +09:00
Clemens Schwaighofer
9a7399e821 Update phpunit test script and tests 2023-02-24 09:46:03 +09:00
Clemens Schwaighofer
6f653c24a0 VarSetType rename to SetVarType, add phan/phpstan/phpunit tests
Breaking change:
VarSetType/VarSetTypeNull classes have been renamed to
SetVarType/SetVarTypeNull

Added phan/phpstan static checkes and settings
Add phpunit tests (in test/phpunit) that are an exact copy from the
trunk folder unit tests

The phan/phpstan tests have been updated to work with the composer layout

config files with static defines needed for certain classes are stored
in test/configs (config.php, config.other.php, config.master.php)
2023-02-22 07:52:51 +09:00
Clemens Schwaighofer
b56f889c5e Update readme file 2023-02-20 15:41:07 +09:00
Clemens Schwaighofer
0680c2fd4a Update gitignore file and readme 2023-02-17 13:15:55 +09:00
89 changed files with 20161 additions and 72 deletions

1
.gitignore vendored
View File

@@ -1 +1,2 @@
vendor
composer.lock

120
.phan/config.php Normal file
View File

@@ -0,0 +1,120 @@
<?php
/**
* This configuration will be read and overlaid on top of the
* default configuration. Command line arguments will be applied
* after this file is read.
*
* @see src/Phan/Config.php
* See Config for all configurable options.
*
* A Note About Paths
* ==================
*
* Files referenced from this file should be defined as
*
* ```
* Config::projectPath('relative_path/to/file')
* ```
*
* where the relative path is relative to the root of the
* project which is defined as either the working directory
* of the phan executable or a path passed in via the CLI
* '-d' flag.
*/
use Phan\Config;
return [
// "target_php_version" => "8.2",
// turn color on (-C)
"color_issue_messages_if_supported" => true,
// If true, missing properties will be created when
// they are first seen. If false, we'll report an
// error message.
"allow_missing_properties" => false,
// Allow null to be cast as any type and for any
// type to be cast to null.
"null_casts_as_any_type" => false,
// Backwards Compatibility Checking
'backward_compatibility_checks' => false,
// Run a quick version of checks that takes less
// time
"quick_mode" => false,
// Only emit critical issues to start with
// (0 is low severity, 5 is normal severity, 10 is critical)
"minimum_severity" => 0,
// enable for dead code check
// this will spill out errors for all methods never called
// use after all is OK to try to find unused code blocks
// ignore recommended: PhanUnreferencedPublicMethod
// "dead_code_detection" => true,
// default false for include path check
"enable_include_path_checks" => true,
"include_paths" => [
'.',
// '../test/configs/'
],
'ignore_undeclared_variables_in_global_scope' => true,
"file_list" => [
"./test/configs/config.php",
// "./test/configs/config.db.php",
// "./test/configs/config.host.php",
// "./test/configs/config.path.php",
"./test/configs/config.other.php",
"./test/configs/config.master.php",
],
// A list of directories that should be parsed for class and
// method information. After excluding the directories
// defined in exclude_analysis_directory_list, the remaining
// files will be statically analyzed for errors.
//
// Thus, both first-party and third-party code being used by
// your application should be included in this list.
'directory_list' => [
// Change this to include the folders you wish to analyze
// (and the folders of their dependencies)
'src',
// To speed up analysis, we recommend going back later and
// limiting this to only the vendor/ subdirectories your
// project depends on.
// `phan --init` will generate a list of folders for you
'vendor/egrajp/smarty-extended',
],
// A list of directories holding code that we want
// to parse, but not analyze
"exclude_analysis_directory_list" => [
'vendor/egrajp/smarty-extended',
],
'exclude_file_list' => [
],
// what not to show as problem
'suppress_issue_types' => [
// 'PhanUndeclaredMethod',
'PhanEmptyFile',
// ignore unreferences public methods, etc here (for dead code check)
'PhanUnreferencedPublicMethod',
'PhanUnreferencedClass',
'PhanWriteOnlyPublicProperty',
'PhanUnreferencedConstant',
'PhanWriteOnlyPublicProperty',
'PhanReadOnlyPublicProperty'
],
// Override to hardcode existence and types of (non-builtin) globals in the global scope.
// Class names should be prefixed with `\`.
//
// (E.g. `['_FOO' => '\FooClass', 'page' => '\PageClass', 'userId' => 'int']`)
'globals_type_map' => [],
];

View File

@@ -4,20 +4,22 @@ This is just the lib/CoreLibs folder in a composer package.
For local install only
## Setup
**Note**: for following classes the `egrajp/smarty-extended` has to be installed
In the composer.json file add the following
- Template\SmartyExtended
- Admin\EditBase
```json
{
"repositories": [
{
"type": "vcs",
"url": "https://git.egplusww.jp/Composer/CoreLibs-Composer-All"
}
],
"require": {
"egrajp/corelibs-composer-all": "@dev"
}
}
## Setup from central composer
Setup from gitea internal servers
```sh
composer config repositories.git.egplusww.jp.Composer composer https://git.egplusww.jp/api/packages/Composer/composer
```
Alternative setup composer local zip file repot:
`composer config repositories.composer.egplusww.jp composer http://composer.egplusww.jp`
## Install package
`composer require egrajp/corelibs-composer-all:^7.11`

View File

@@ -15,5 +15,19 @@
}
],
"minimum-stability": "dev",
"require": {}
"require": {
"php": ">=8.1"
},
"require-dev": {
"phpstan/phpstan": "1.10.x-dev",
"phan/phan": "v5.x-dev",
"phpunit/phpunit": "^9",
"egrajp/smarty-extended": "^4.3"
},
"repositories": {
"git.egplusww.jp.Composer": {
"type": "composer",
"url": "https://git.egplusww.jp/api/packages/Composer/composer"
}
}
}

47
phpstan-baseline.neon Normal file
View File

@@ -0,0 +1,47 @@
parameters:
ignoreErrors:
-
message: "#^Parameter \\#1 \\$connection of function pg_escape_bytea expects PgSql\\\\Connection\\|string, object\\|resource given\\.$#"
count: 1
path: src/DB/SQL/PgSQL.php
-
message: "#^Parameter \\#1 \\$connection of function pg_escape_identifier expects PgSql\\\\Connection\\|string, object\\|resource given\\.$#"
count: 1
path: src/DB/SQL/PgSQL.php
-
message: "#^Parameter \\#1 \\$connection of function pg_escape_literal expects PgSql\\\\Connection\\|string, object\\|resource given\\.$#"
count: 1
path: src/DB/SQL/PgSQL.php
-
message: "#^Parameter \\#1 \\$connection of function pg_escape_string expects PgSql\\\\Connection\\|string, object\\|resource given\\.$#"
count: 1
path: src/DB/SQL/PgSQL.php
-
message: "#^Parameter \\#1 \\$connection of function pg_execute expects PgSql\\\\Connection\\|string, object\\|resource given\\.$#"
count: 1
path: src/DB/SQL/PgSQL.php
-
message: "#^Parameter \\#1 \\$connection of function pg_parameter_status expects PgSql\\\\Connection\\|string, object\\|resource given\\.$#"
count: 1
path: src/DB/SQL/PgSQL.php
-
message: "#^Parameter \\#1 \\$connection of function pg_prepare expects PgSql\\\\Connection\\|string, object\\|resource given\\.$#"
count: 1
path: src/DB/SQL/PgSQL.php
-
message: "#^Parameter \\#1 \\$connection of function pg_query expects PgSql\\\\Connection\\|string, object\\|resource given\\.$#"
count: 1
path: src/DB/SQL/PgSQL.php
-
message: "#^Parameter \\#1 \\$connection of function pg_query_params expects PgSql\\\\Connection\\|string, object\\|resource given\\.$#"
count: 1
path: src/DB/SQL/PgSQL.php

12
phpstan-bootstrap.php Executable file
View File

@@ -0,0 +1,12 @@
<?php // phpcs:ignore PSR1.Files.SideEffects
// Boostrap file for PHPstand
// sets the _SERVER['HTTP_HOST'] var so we can have DB detection
$_SERVER['HTTP_HOST'] = 'soba.tokyo.tequila.jp';
// so www/includes/edit_base.php works
// require_once('www/lib/Smarty/SmartyBC.class.php');
// for whatever reason it does not load that from the confing.master.php
// for includes/admin_header.php
define('BASE_NAME', '');
// __END__

21
phpstan-conditional.php Normal file
View File

@@ -0,0 +1,21 @@
<?php
// conditional formats for PHP versions
declare(strict_types=1);
$config = [];
if (PHP_VERSION_ID >= 8_00_00) {
// Change of signature in PHP 8.1
/* $config['parameters']['ignoreErrors'][] = [
'message' => '~Parameter #1 \$(result|connection) of function pg_\w+ '
. 'expects resource(\|null)?, object\|resource given\.~',
'path' => 'www/lib/CoreLibs/DB/SQL/PgSQL.php',
// 'count' => 1,
]; */
}
return $config;
// __END_

44
phpstan.neon Normal file
View File

@@ -0,0 +1,44 @@
# PHP Stan Config
includes:
- phpstan-conditional.php
parameters:
tmpDir: /tmp/phpstan-corelibs-composer
level: 8 # max is now 9
checkMissingCallableSignature: true
treatPhpDocTypesAsCertain: false
strictRules:
allRules: false
paths:
- %currentWorkingDirectory%/src
bootstrapFiles:
- %currentWorkingDirectory%/phpstan-bootstrap.php
- %currentWorkingDirectory%/vendor/autoload.php
scanDirectories:
- vendor/egrajp/smarty-extended
scanFiles:
- test/configs/config.php
- test/configs/config.master.php
- test/configs/config.other.php
# excludePaths:
# ignore composer
# - 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%/src/DB/SQL/PgSQL.php
# this is ignored for now
# - '#Expression in empty\(\) is always falsy.#'
# -
# message: '#Reflection error: [a-zA-Z0-9\\_]+ not found.#'
# path: www/includes/edit_base.php
#- 'error regex'
#-
# message: 'error regex'
# path: %currentWorkingDirectory%/www/some/*
# paths:
# - ...
# - ...

6
phpunit.xml Normal file
View File

@@ -0,0 +1,6 @@
<phpunit
cacheResultFile="/tmp/phpunit-corelibs-composer.result.cache"
colors="true"
verbose="true"
>
</phpunit>

View File

@@ -414,6 +414,8 @@ class EditBase
$elements[] = $this->form->formCreateElement('additional_acl');
break;
case 'edit_schemes':
// @deprecated Will be removed
case 'edit_schemas':
$elements[] = $this->form->formCreateElement('enabled');
$elements[] = $this->form->formCreateElement('name');
$elements[] = $this->form->formCreateElement('header_color');

View File

@@ -9,7 +9,7 @@ declare(strict_types=1);
namespace CoreLibs\Convert\Extends;
class VarSetTypeMain
class SetVarTypeMain
{
/**
* If input variable is string then returns it, else returns default set

View File

@@ -11,9 +11,9 @@ declare(strict_types=1);
namespace CoreLibs\Convert;
use CoreLibs\Convert\Extends\VarSetTypeMain;
use CoreLibs\Convert\Extends\SetVarTypeMain;
class VarSetType extends Extends\VarSetTypeMain
class SetVarType extends Extends\SetVarTypeMain
{
/**
* Check is input is string, if not return default string.
@@ -25,7 +25,7 @@ class VarSetType extends Extends\VarSetTypeMain
*/
public static function setStr(mixed $val, string $default = ''): string
{
return (string)VarSetTypeMain::setStrMain($val, $default, false);
return (string)SetVarTypeMain::setStrMain($val, $default, false);
}
/**
@@ -39,7 +39,7 @@ class VarSetType extends Extends\VarSetTypeMain
*/
public static function makeStr(mixed $val, string $default = ''): string
{
return (string)VarSetTypeMain::makeStrMain($val, $default, false);
return (string)SetVarTypeMain::makeStrMain($val, $default, false);
}
/**
@@ -52,7 +52,7 @@ class VarSetType extends Extends\VarSetTypeMain
*/
public static function setInt(mixed $val, int $default = 0): int
{
return (int)VarSetTypeMain::setIntMain($val, $default, false);
return (int)SetVarTypeMain::setIntMain($val, $default, false);
}
/**
@@ -65,7 +65,7 @@ class VarSetType extends Extends\VarSetTypeMain
*/
public static function makeInt(mixed $val, int $default = 0): int
{
return (int)VarSetTypeMain::makeIntMain($val, $default, false);
return (int)SetVarTypeMain::makeIntMain($val, $default, false);
}
/**
@@ -78,7 +78,7 @@ class VarSetType extends Extends\VarSetTypeMain
*/
public static function setFloat(mixed $val, float $default = 0.0): float
{
return (float)VarSetTypeMain::setFloatMain($val, $default, false);
return (float)SetVarTypeMain::setFloatMain($val, $default, false);
}
/**
@@ -91,7 +91,7 @@ class VarSetType extends Extends\VarSetTypeMain
*/
public static function makeFloat(mixed $val, float $default = 0.0): float
{
return (float)VarSetTypeMain::makeFloatMain($val, $default, false);
return (float)SetVarTypeMain::makeFloatMain($val, $default, false);
}
/**
@@ -104,7 +104,7 @@ class VarSetType extends Extends\VarSetTypeMain
*/
public static function setArray(mixed $val, array $default = []): array
{
return (array)VarSetTypeMain::setArrayMain($val, $default, false);
return (array)SetVarTypeMain::setArrayMain($val, $default, false);
}
/**
@@ -117,7 +117,7 @@ class VarSetType extends Extends\VarSetTypeMain
*/
public static function setBool(mixed $val, bool $default = false): bool
{
return (bool)VarSetTypeMain::setBoolMain($val, $default, false);
return (bool)SetVarTypeMain::setBoolMain($val, $default, false);
}
/**
@@ -129,7 +129,7 @@ class VarSetType extends Extends\VarSetTypeMain
*/
public static function makeBool(mixed $val, bool $default = false): bool
{
return (bool)VarSetTypeMain::makeBoolMain($val, $default, false);
return (bool)SetVarTypeMain::makeBoolMain($val, $default, false);
}
}

View File

@@ -9,9 +9,9 @@ declare(strict_types=1);
namespace CoreLibs\Convert;
use CoreLibs\Convert\Extends\VarSetTypeMain;
use CoreLibs\Convert\Extends\SetVarTypeMain;
class VarSetTypeNull extends Extends\VarSetTypeMain
class SetVarTypeNull extends Extends\SetVarTypeMain
{
/**
* Check is input is string, if not return default string.
@@ -23,7 +23,7 @@ class VarSetTypeNull extends Extends\VarSetTypeMain
*/
public static function setStr(mixed $val, ?string $default = null): ?string
{
return VarSetTypeMain::setStrMain($val, $default, true);
return SetVarTypeMain::setStrMain($val, $default, true);
}
/**
@@ -37,7 +37,7 @@ class VarSetTypeNull extends Extends\VarSetTypeMain
*/
public static function makeStr(mixed $val, string $default = null): ?string
{
return VarSetTypeMain::makeStrMain($val, $default, true);
return SetVarTypeMain::makeStrMain($val, $default, true);
}
@@ -50,7 +50,7 @@ class VarSetTypeNull extends Extends\VarSetTypeMain
*/
public static function setInt(mixed $val, ?int $default = null): ?int
{
return VarSetTypeMain::setIntMain($val, $default, true);
return SetVarTypeMain::setIntMain($val, $default, true);
}
/**
@@ -62,7 +62,7 @@ class VarSetTypeNull extends Extends\VarSetTypeMain
*/
public static function makeInt(mixed $val, int $default = null): ?int
{
return VarSetTypeMain::makeIntMain($val, $default, true);
return SetVarTypeMain::makeIntMain($val, $default, true);
}
/**
@@ -74,7 +74,7 @@ class VarSetTypeNull extends Extends\VarSetTypeMain
*/
public static function setFloat(mixed $val, ?float $default = null): ?float
{
return VarSetTypeMain::setFloatMain($val, $default, true);
return SetVarTypeMain::setFloatMain($val, $default, true);
}
/**
@@ -86,7 +86,7 @@ class VarSetTypeNull extends Extends\VarSetTypeMain
*/
public static function makeFloat(mixed $val, float $default = null): ?float
{
return VarSetTypeMain::makeFloatMain($val, $default, true);
return SetVarTypeMain::makeFloatMain($val, $default, true);
}
/**
@@ -98,7 +98,7 @@ class VarSetTypeNull extends Extends\VarSetTypeMain
*/
public static function setArray(mixed $val, ?array $default = null): ?array
{
return VarSetTypeMain::setArrayMain($val, $default, true);
return SetVarTypeMain::setArrayMain($val, $default, true);
}
/**
@@ -110,7 +110,7 @@ class VarSetTypeNull extends Extends\VarSetTypeMain
*/
public static function setBool(mixed $val, ?bool $default = null): ?bool
{
return VarSetTypeMain::setBoolMain($val, $default, true);
return SetVarTypeMain::setBoolMain($val, $default, true);
}
/**
@@ -123,7 +123,7 @@ class VarSetTypeNull extends Extends\VarSetTypeMain
{
// note that the default value here is irrelevant, we return null
// on unsetable string var
return VarSetTypeMain::makeBoolMain($val, false, true);
return SetVarTypeMain::makeBoolMain($val, false, true);
}
}

View File

@@ -1851,7 +1851,6 @@ class IO
// if cursor exists ...
if ($this->cursor_ext[$query_hash]['cursor']) {
/** @phpstan-ignore-next-line claims this is always false, but can be true */
if ($first_call === true) {
$this->cursor_ext[$query_hash]['log'][] = 'First call';
// count the rows returned (if select)
@@ -3048,7 +3047,6 @@ class IO
} else {
// find in all inside the array
$__arr = array_column($this->insert_id_arr, $key);
/** @phpstan-ignore-next-line [Why is this always true?] */
if (count($__arr)) {
return $__arr;
} else {

View File

@@ -366,7 +366,7 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
$config_array = $table_arrays[System::getPageName(1)];
} else {
// primary try to load the class
/** @var \CoreLibs\Output\Form\TableArraysInterface|false $content_class */
/** @var TableArrays\Interface\TableArraysInterface|false $content_class */
$content_class = $this->loadTableArray();
if (is_object($content_class)) {
$config_array = $content_class->setTableArray();
@@ -468,9 +468,9 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
/**
* load table array class based on my page name converted to camel case
* class files are in \TableArrays folder in \Output\Form
* @return object|bool Return class object or false on failure
* @return TableArrays\Interface\TableArraysInterface|false Return class object or false on failure
*/
private function loadTableArray()
private function loadTableArray(): TableArrays\Interface\TableArraysInterface|false
{
// note: it schould be Schemas but an original type made it to this
// this file is kept for the old usage, new one should be EditSchemas
@@ -489,7 +489,7 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
$page_name_camel_case
);
try {
/** @var \CoreLibs\Output\Form\TableArraysInterface|false $class */
/** @var TableArrays\Interface\TableArraysInterface|false $class */
$class = new $class_string($this);
} catch (\Throwable $t) {
$this->log->debug('CLASS LOAD', 'Failed loading: ' . $class_string . ' => ' . $t->getMessage());
@@ -651,7 +651,7 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
$this->base_acl_level >= $this->security_level['new']
) {
if ($this->really_new == 'yes') {
$this->formUnsetTablearray();
$this->formUnsetTableArray();
} else {
$this->msg .= $this->l->__('You have to select the <b>Checkbox for New</b>!<br>');
$this->error = 2;

View File

@@ -4,7 +4,7 @@ declare(strict_types=1);
namespace CoreLibs\Output\Form\TableArrays;
class EditAccess implements \CoreLibs\Output\Form\TableArraysInterface
class EditAccess implements Interface\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;
@@ -87,7 +87,9 @@ class EditAccess implements \CoreLibs\Output\Form\TableArraysInterface
],
],
'table_name' => 'edit_access',
"load_query" => "SELECT edit_access_id, name FROM edit_access ORDER BY name",
"load_query" => "SELECT edit_access_id, name "
. "FROM edit_access "
. "ORDER BY name",
'show_fields' => [
[
'name' => 'name'

View File

@@ -4,7 +4,7 @@ declare(strict_types=1);
namespace CoreLibs\Output\Form\TableArrays;
class EditGroups implements \CoreLibs\Output\Form\TableArraysInterface
class EditGroups implements Interface\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;
@@ -55,14 +55,19 @@ class EditGroups implements \CoreLibs\Output\Form\TableArraysInterface
'mandatory' => 1,
'int' => 1,
'type' => 'drop_down_db',
'query' => "SELECT edit_access_right_id, name FROM edit_access_right ORDER BY level"
'query' => "SELECT edit_access_right_id, name "
. "FROM edit_access_right "
. "ORDER BY level"
],
'edit_scheme_id' => [
'value' => $_POST['edit_scheme_id'] ?? '',
'output_name' => 'Group Scheme',
'int_null' => 1,
'type' => 'drop_down_db',
'query' => "SELECT edit_scheme_id, name FROM edit_scheme WHERE enabled = 1 ORDER BY name"
'query' => "SELECT edit_scheme_id, name "
. "FROM edit_scheme "
. "WHERE enabled = 1 "
. "ORDER BY name"
],
'additional_acl' => [
'value' => $_POST['additional_acl'] ?? '',
@@ -73,7 +78,9 @@ class EditGroups implements \CoreLibs\Output\Form\TableArraysInterface
'cols' => 60
],
],
'load_query' => "SELECT edit_group_id, name, enabled FROM edit_group ORDER BY name",
'load_query' => "SELECT edit_group_id, name, enabled "
. "FROM edit_group "
. "ORDER BY name",
'table_name' => 'edit_group',
'show_fields' => [
[
@@ -115,7 +122,9 @@ class EditGroups implements \CoreLibs\Output\Form\TableArraysInterface
'output_name' => 'Access Level',
'int' => 1,
'preset' => 1, // first of the select
'query' => "SELECT edit_access_right_id, name FROM edit_access_right ORDER BY level"
'query' => "SELECT edit_access_right_id, name "
. "FROM edit_access_right "
. "ORDER BY level"
],
'edit_page_id' => [
'int' => 1,

View File

@@ -4,7 +4,7 @@ declare(strict_types=1);
namespace CoreLibs\Output\Form\TableArrays;
class EditLanguages implements \CoreLibs\Output\Form\TableArraysInterface
class EditLanguages implements Interface\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;

View File

@@ -4,7 +4,7 @@ declare(strict_types=1);
namespace CoreLibs\Output\Form\TableArrays;
class EditMenuGroup implements \CoreLibs\Output\Form\TableArraysInterface
class EditMenuGroup implements Interface\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;
@@ -55,7 +55,9 @@ class EditMenuGroup implements \CoreLibs\Output\Form\TableArraysInterface
],
],
'table_name' => 'edit_menu_group',
'load_query' => "SELECT edit_menu_group_id, name FROM edit_menu_group ORDER BY name",
'load_query' => "SELECT edit_menu_group_id, name "
. "FROM edit_menu_group "
. "ORDER BY name",
'show_fields' => [
[
'name' => 'name'

View File

@@ -4,7 +4,7 @@ declare(strict_types=1);
namespace CoreLibs\Output\Form\TableArrays;
class EditPages implements \CoreLibs\Output\Form\TableArraysInterface
class EditPages implements Interface\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;
@@ -140,7 +140,10 @@ class EditPages implements \CoreLibs\Output\Form\TableArraysInterface
],
],
'load_query' => "SELECT edit_page_id, "
. "CASE WHEN hostname IS NOT NULL THEN hostname ELSE ''::VARCHAR END || filename AS filename, "
. "CASE "
. "WHEN hostname IS NOT NULL THEN hostname "
. "ELSE ''::VARCHAR "
. "END || filename AS filename, "
. "name, online, menu, popup "
. "FROM edit_page "
. "ORDER BY order_number",
@@ -178,7 +181,8 @@ class EditPages implements \CoreLibs\Output\Form\TableArraysInterface
'select_size' => 10,
'selected' => $_POST['edit_visible_group_id'] ?? '',
'query' => "SELECT edit_visible_group_id, 'Name: ' || name || ', ' || 'Flag: ' || flag "
. "FROM edit_visible_group ORDER BY name"
. "FROM edit_visible_group "
. "ORDER BY name"
],
'edit_menu_group' => [
'table_name' => 'edit_page_menu_group',
@@ -188,7 +192,8 @@ class EditPages implements \CoreLibs\Output\Form\TableArraysInterface
'select_size' => 10,
'selected' => $_POST['edit_menu_group_id'] ?? '',
'query' => "SELECT edit_menu_group_id, 'Name: ' || name || ', ' || 'Flag: ' || flag "
. "FROM edit_menu_group ORDER BY order_number"
. "FROM edit_menu_group "
. "ORDER BY order_number"
],
],
'element_list' => [
@@ -259,7 +264,9 @@ class EditPages implements \CoreLibs\Output\Form\TableArraysInterface
'output_name' => 'Access Level',
'int' => 1,
'preset' => 1, // first of the select
'query' => "SELECT edit_access_right_id, name FROM edit_access_right ORDER BY level"
'query' => "SELECT edit_access_right_id, name "
. "FROM edit_access_right "
. "ORDER BY level"
],
'edit_page_content_id' => [
'type' => 'hidden',

View File

@@ -4,7 +4,7 @@ declare(strict_types=1);
namespace CoreLibs\Output\Form\TableArrays;
class EditSchemas implements \CoreLibs\Output\Form\TableArraysInterface
class EditSchemas implements Interface\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;
@@ -68,7 +68,9 @@ class EditSchemas implements \CoreLibs\Output\Form\TableArraysInterface
],
],
'table_name' => 'edit_scheme',
'load_query' => "SELECT edit_scheme_id, name, enabled FROM edit_scheme ORDER BY name",
'load_query' => "SELECT edit_scheme_id, name, enabled "
. "FROM edit_scheme "
. "ORDER BY name",
'show_fields' => [
[
'name' => 'name'

View File

@@ -4,7 +4,7 @@ declare(strict_types=1);
namespace CoreLibs\Output\Form\TableArrays;
class EditUsers implements \CoreLibs\Output\Form\TableArraysInterface
class EditUsers implements Interface\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;
@@ -274,7 +274,7 @@ class EditUsers implements \CoreLibs\Output\Form\TableArraysInterface
'type' => 'drop_down_db',
'query' => "SELECT edit_language_id, long_name "
. "FROM edit_language "
. "WHERE enabled = 1"
. "WHERE enabled = 1 "
. "ORDER BY order_number",
'min_edit_acl' => '100',
'min_show_acl' => '100',
@@ -284,7 +284,10 @@ class EditUsers implements \CoreLibs\Output\Form\TableArraysInterface
'output_name' => 'Scheme',
'int_null' => 1,
'type' => 'drop_down_db',
'query' => "SELECT edit_scheme_id, name FROM edit_scheme WHERE enabled = 1 ORDER BY name",
'query' => "SELECT edit_scheme_id, name "
. "FROM edit_scheme "
. "WHERE enabled = 1 "
. "ORDER BY name",
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
@@ -293,7 +296,10 @@ class EditUsers implements \CoreLibs\Output\Form\TableArraysInterface
'output_name' => 'Group',
'int' => 1,
'type' => 'drop_down_db',
'query' => "SELECT edit_group_id, name FROM edit_group WHERE enabled = 1 ORDER BY name",
'query' => "SELECT edit_group_id, name "
. "FROM edit_group "
. "WHERE enabled = 1 "
. "ORDER BY name",
'mandatory' => 1,
'min_edit_acl' => '100',
'min_show_acl' => '100',
@@ -304,7 +310,9 @@ class EditUsers implements \CoreLibs\Output\Form\TableArraysInterface
'mandatory' => 1,
'int' => 1,
'type' => 'drop_down_db',
'query' => "SELECT edit_access_right_id, name FROM edit_access_right ORDER BY level",
'query' => "SELECT edit_access_right_id, name "
. "FROM edit_access_right "
. "ORDER BY level",
'min_edit_acl' => '100',
'min_show_acl' => '100',
],
@@ -434,7 +442,9 @@ class EditUsers implements \CoreLibs\Output\Form\TableArraysInterface
'output_name' => 'Access Level',
'preset' => 1, // first of the select
'int' => 1,
'query' => "SELECT edit_access_right_id, name FROM edit_access_right ORDER BY level"
'query' => "SELECT edit_access_right_id, name "
. "FROM edit_access_right "
. "ORDER BY level"
],
'edit_default' => [
'type' => 'radio_group',

View File

@@ -4,7 +4,7 @@ declare(strict_types=1);
namespace CoreLibs\Output\Form\TableArrays;
class EditVisibleGroup implements \CoreLibs\Output\Form\TableArraysInterface
class EditVisibleGroup implements Interface\TableArraysInterface
{
/** @var \CoreLibs\Output\Form\Generate */
private $form;
@@ -48,7 +48,9 @@ class EditVisibleGroup implements \CoreLibs\Output\Form\TableArraysInterface
],
],
'table_name' => 'edit_visible_group',
'load_query' => "SELECT edit_visible_group_id, name FROM edit_visible_group ORDER BY name",
'load_query' => "SELECT edit_visible_group_id, name "
. "FROM edit_visible_group "
. "ORDER BY name",
'show_fields' => [
[
'name' => 'name'

View File

@@ -2,7 +2,7 @@
declare(strict_types=1);
namespace CoreLibs\Output\Form;
namespace CoreLibs\Output\Form\TableArrays\Interface;
interface TableArraysInterface
{

View File

@@ -453,7 +453,7 @@ class SmartyExtend extends \Smarty
$this->DATA['nav_menu_count'] = count($this->DATA['nav_menu']);
// messages = ['msg' =>, 'class' => 'error/warning/...']
$this->DATA['messages'] = $cms->messages;
} else { /** @phpstan-ignore-line Because I assume object for phpstan */
} else {
$this->DATA['show_ea_extra'] = false;
$this->DATA['ADMIN'] = 0;
$this->DATA['nav_menu'] = [];

2
test/checking/phan.sh Executable file
View File

@@ -0,0 +1,2 @@
base="/storage/var/www/html/developers/clemens/core_data/composer-packages/CoreLibs-Composer-All/";
vendor/bin/phan --progress-bar -C --analyze-twice

2
test/checking/phpstan.sh Executable file
View File

@@ -0,0 +1,2 @@
base="/storage/var/www/html/developers/clemens/core_data/composer-packages/CoreLibs-Composer-All/";
vendor/bin/phpstan

46
test/checking/phpunit.sh Executable file
View File

@@ -0,0 +1,46 @@
#!/usr/bin/env bash
base="/storage/var/www/html/developers/clemens/core_data/composer-packages/CoreLibs-Composer-All/";
# -c phpunit.xml
# --testdox
# call with "t" to give verbose testdox output
# SUPPORTED: https://www.php.net/supported-versions.php
# call with php version number to force a certain php version
opt_testdox="";
if [ "${1}" = "t" ] || [ "${2}" = "t" ]; then
opt_testdox="--testdox";
fi;
php_bin="";
if [ ! -z "${1}" ]; then
case "${1}" in
# "7.3") php_bin="/usr/bin/php7.3 "; ;;
"7.4") php_bin="/usr/bin/php7.4 "; ;;
"8.0") php_bin="/usr/bin/php8.0 "; ;;
"8.1") php_bin="/usr/bin/php8.1 "; ;;
"8.2") php_bin="/usr/bin/php8.2 "; ;;
*) echo "Not support PHP: ${1}"; exit; ;;
esac;
fi;
if [ ! -z "${2}" ] && [ -z "${php_bin}" ]; then
case "${2}" in
# "7.3") php_bin="/usr/bin/php7.3 "; ;;
"7.4") php_bin="/usr/bin/php7.4 "; ;;
"8.0") php_bin="/usr/bin/php8.0 "; ;;
"8.1") php_bin="/usr/bin/php8.1 "; ;;
"8.2") php_bin="/usr/bin/php8.2 "; ;;
*) echo "Not support PHP: ${1}"; exit; ;;
esac;
fi;
phpunit_call="${php_bin}${base}vendor/bin/phpunit ${opt_testdox} -c ${base}phpunit.xml ${base}test/phpunit/";
${phpunit_call};
if [ ! -z "${php_bin}" ]; then
echo "CALLED WITH PHP: ${php_bin}"$(${php_bin} --version);
else
echo "Default PHP used: "$(php --version);
fi;
# __END__

View File

@@ -0,0 +1,312 @@
<?php // phpcs:ignore PSR1.Files.SideEffects
/********************************************************************
* AUTHOR: Clemens Schwaighofer
* CREATED: 2003/06/10
* SHORT DESCRIPTION:
* configuration file
* HISTORY:
*********************************************************************/
declare(strict_types=1);
/************* PATHS *********************/
// [DEPRECATED] directory seperator
define('DS', DIRECTORY_SEPARATOR);
// ** NEW/BETTER DIR DECLARATIONS **
// path to original file (if symlink)
define('DIR', __DIR__ . DIRECTORY_SEPARATOR);
// base dir root folder level
define('BASE', str_replace('/configs', '', __DIR__) . DIRECTORY_SEPARATOR);
// ** OLD DIR DECLARATIONS **
// path to document root of file called
define('ROOT', getcwd() . DIRECTORY_SEPARATOR);
// libs path
define('LIB', 'lib' . DIRECTORY_SEPARATOR);
define('LIBS', 'lib' . DIRECTORY_SEPARATOR);
// configs folder
define('CONFIGS', 'configs' . DIRECTORY_SEPARATOR);
// includes (strings, arrays for static, etc)
define('INCLUDES', 'includes' . DIRECTORY_SEPARATOR);
// data folder (mostly in includes, or root for internal data)
define('DATA', 'data' . DIRECTORY_SEPARATOR);
// layout base path
define('LAYOUT', 'layout' . DIRECTORY_SEPARATOR);
// pic-root (compatible to CMS)
define('PICTURES', 'images' . DIRECTORY_SEPARATOR);
// images
define('IMAGES', 'images' . DIRECTORY_SEPARATOR);
// icons (below the images/ folder)
define('ICONS', 'icons' . DIRECTORY_SEPARATOR);
// media (accessable from outside)
define('MEDIA', 'media' . DIRECTORY_SEPARATOR);
// uploads (anything to keep or data)
define('UPLOADS', 'uploads' . DIRECTORY_SEPARATOR);
// files (binaries) (below media or data)
define('BINARIES', 'binaries' . DIRECTORY_SEPARATOR);
// files (videos) (below media or data)
define('VIDEOS', 'videos' . DIRECTORY_SEPARATOR);
// files (documents) (below media or data)
define('DOCUMENTS', 'documents' . DIRECTORY_SEPARATOR);
// files (pdfs) (below media or data)
define('PDFS', 'documents' . DIRECTORY_SEPARATOR);
// files (general) (below media or data)
define('FILES', 'files' . DIRECTORY_SEPARATOR);
// CSV
define('CSV', 'csv' . DIRECTORY_SEPARATOR);
// css
define('CSS', 'css' . DIRECTORY_SEPARATOR);
// font (web)
define('FONT', 'font' . DIRECTORY_SEPARATOR);
// js
define('JS', 'javascript' . DIRECTORY_SEPARATOR);
// table arrays
define('TABLE_ARRAYS', 'table_arrays' . DIRECTORY_SEPARATOR);
// smarty libs path
define('SMARTY', 'Smarty' . DIRECTORY_SEPARATOR);
// po locale file
define('LOCALE', 'locale' . DIRECTORY_SEPARATOR);
// cache path
define('CACHE', 'cache' . DIRECTORY_SEPARATOR);
// temp path
define('TMP', 'tmp' . DIRECTORY_SEPARATOR);
// log files
define('LOG', 'log' . DIRECTORY_SEPARATOR);
// compiled template folder
define('TEMPLATES_C', 'templates_c' . DIRECTORY_SEPARATOR);
// template base
define('TEMPLATES', 'templates' . DIRECTORY_SEPARATOR);
/************* HASH / ACL DEFAULT / ERROR SETTINGS / SMARTY *************/
// default hash type
define('DEFAULT_HASH', 'sha256');
// default acl level
define('DEFAULT_ACL_LEVEL', 80);
// SSL host name
// define('SSL_HOST', $_ENV['SSL_HOST'] ?? '');
// error page strictness, Default is 3
// 1: only show error page as the last mesure if really no mid & aid can be loaded and found at all
// 2: if template not found, do not search, show error template
// 3: if default template is not found, show error template, do not fall back to default tree
// 4: very strict, even on normal fixable errors through error
// define('ERROR_STRICT', 3);
// allow page caching in general, set to 'false' if you do debugging or development!
// define('ALLOW_SMARTY_CACHE', false);
// cache life time, in second', default here is 2 days (172800s)
// -1 is never expire cache
// define('SMARTY_CACHE_LIFETIME', -1);
/************* LOGOUT ********************/
// logout target
define('LOGOUT_TARGET', '');
// password change allowed
define('PASSWORD_CHANGE', false);
define('PASSWORD_FORGOT', false);
// min/max password length
define('PASSWORD_MIN_LENGTH', 9);
define('PASSWORD_MAX_LENGTH', 255);
// defines allowed special characters
define('PASSWORD_SPECIAL_RANGE', '@$!%*?&');
// password must have upper case, lower case, number, special
// comment out for not mandatory
define('PASSWORD_LOWER', '(?=.*[a-z])');
define('PASSWORD_UPPER', '(?=.*[A-Z])');
define('PASSWORD_NUMBER', '(?=.*\d)');
define('PASSWORD_SPECIAL', "(?=.*[" . PASSWORD_SPECIAL_RANGE . "])");
// define full regex
define('PASSWORD_REGEX', "/^"
. (defined('PASSWORD_LOWER') ? PASSWORD_LOWER : '')
. (defined('PASSWORD_UPPER') ? PASSWORD_UPPER : '')
. (defined('PASSWORD_NUMBER') ? PASSWORD_NUMBER : '')
. (defined('PASSWORD_SPECIAL') ? PASSWORD_SPECIAL : '')
. "[A-Za-z\d" . PASSWORD_SPECIAL_RANGE . "]{" . PASSWORD_MIN_LENGTH . "," . PASSWORD_MAX_LENGTH . "}$/");
/************* AJAX / ACCESS *************/
// ajax request type
define('AJAX_REQUEST_TYPE', 'POST');
// what AJAX type to use
define('USE_PROTOTYPE', false);
define('USE_SCRIPTACULOUS', false);
define('USE_JQUERY', true);
/************* LAYOUT WIDTHS *************/
define('PAGE_WIDTH', '100%');
define('CONTENT_WIDTH', '100%');
// the default template name
define('MASTER_TEMPLATE_NAME', 'main_body.tpl');
/************* OVERALL CONTROL NAMES *************/
// BELOW has HAS to be changed
// base name for all session and log names
// only alphanumeric characters, strip all others
define('BASE_NAME', preg_replace('/[^A-Za-z0-9]/', '', $_ENV['BASE_NAME'] ?? ''));
/************* SESSION NAMES *************/
// server name HASH
define('SERVER_NAME_HASH', hash('crc32b', $_SERVER['HTTP_HOST']));
define('SERVER_PATH_HASH', hash('crc32b', BASE));
// backend
define('EDIT_SESSION_NAME', BASE_NAME . 'Admin' . SERVER_NAME_HASH . SERVER_PATH_HASH);
// frontend
define('SESSION_NAME', BASE_NAME . SERVER_NAME_HASH . SERVER_PATH_HASH);
/************* CACHE/COMPILE IDS *************/
define('CACHE_ID', 'CACHE_' . BASE_NAME . '_' . SERVER_NAME_HASH);
define('COMPILE_ID', 'COMPILE_' . BASE_NAME . '_' . SERVER_NAME_HASH);
/************* LANGUAGE / ENCODING *******/
// default lang + encoding
define('DEFAULT_LOCALE', 'en_US.UTF-8');
// default web page encoding setting
define('DEFAULT_ENCODING', 'UTF-8');
/************* LOGGING *******************/
// below two can be defined here, but they should be
// defined in either the header file or the file itself
// as $LOG_FILE_ID which takes presence over LOG_FILE_ID
// see Basic class constructor
define('LOG_FILE_ID', BASE_NAME);
/************* QUEUE TABLE *************/
// if we have a dev/live system
// set_live is a per page/per item
// live_queue is a global queue system
// define('QUEUE', 'live_queue');
/************* DB PATHS (PostgreSQL) *****************/
// schema names, can also be defined per <DB INFO>
define('PUBLIC_SCHEMA', 'public');
define('DEV_SCHEMA', 'public');
define('TEST_SCHEMA', 'public');
define('LIVE_SCHEMA', 'public');
define('GLOBAL_DB_SCHEMA', '');
define('LOGIN_DB_SCHEMA', '');
/************* CORE HOST SETTINGS *****************/
if (file_exists(BASE . CONFIGS . 'config.host.php')) {
require BASE . CONFIGS . 'config.host.php';
}
if (!isset($SITE_CONFIG)) {
$SITE_CONFIG = [];
}
/************* DB ACCESS *****************/
if (file_exists(BASE . CONFIGS . 'config.db.php')) {
require BASE . CONFIGS . 'config.db.php';
}
if (!isset($DB_CONFIG)) {
$DB_CONFIG = [];
}
/************* OTHER PATHS *****************/
if (file_exists(BASE . CONFIGS . 'config.path.php')) {
require BASE . CONFIGS . 'config.path.php';
}
/************* MASTER INIT *****************/
// live frontend pages
// ** missing live domains **
// get the name without the port
list($HOST_NAME) = array_pad(explode(':', $_SERVER['HTTP_HOST'], 2), 2, null);
// set HOST name
define('HOST_NAME', $HOST_NAME);
// BAIL ON MISSING MASTER SITE CONFIG
if (!isset($SITE_CONFIG[HOST_NAME]['location'])) {
echo 'Missing SITE_CONFIG entry for: "' . HOST_NAME . '". Contact Administrator';
exit;
}
// BAIL ON MISSING DB CONFIG:
// we have either no db selction for this host but have db config entries
// or we have a db selection but no db config as array or empty
// or we have a selection but no matching db config entry
if (
(!isset($SITE_CONFIG[HOST_NAME]['db_host']) && count($DB_CONFIG)) ||
(isset($SITE_CONFIG[HOST_NAME]['db_host']) &&
// missing DB CONFIG
((is_array($DB_CONFIG) && !count($DB_CONFIG)) ||
!is_array($DB_CONFIG) ||
// has DB CONFIG but no match
empty($DB_CONFIG[$SITE_CONFIG[HOST_NAME]['db_host']]))
)
) {
echo 'No matching DB config found for: "' . HOST_NAME . '". Contact Administrator';
exit;
}
// set SSL on
$is_secure = false;
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
$is_secure = true;
} elseif (
!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' ||
!empty($_SERVER['HTTP_X_FORWARDED_SSL']) && $_SERVER['HTTP_X_FORWARDED_SSL'] == 'on'
) {
$is_secure = true;
}
if ($is_secure) {
define('HOST_SSL', true);
define('HOST_PROTOCOL', 'https://');
} else {
define('HOST_SSL', false);
define('HOST_PROTOCOL', 'http://');
}
// define the db config set name, the db config and the db schema
define('DB_CONFIG_NAME', $SITE_CONFIG[HOST_NAME]['db_host'] ?? '');
define('DB_CONFIG', $DB_CONFIG[DB_CONFIG_NAME] ?? []);
// because we can't change constant, but we want to for db debug flag
$GLOBALS['DB_CONFIG_SET'] = DB_CONFIG;
// define('DB_CONFIG_TARGET', SITE_CONFIG[$HOST_NAME]['db_host_target']);
// define('DB_CONFIG_OTHER', SITE_CONFIG[$HOST_NAME]['db_host_other']);
// override for login and global schemas
// where the edit* tables are
// define('LOGIN_DB_SCHEMA', PUBLIC_SCHEMA);
// where global tables are that are used by all schemas (eg queue tables for online, etc)
// define('GLOBAL_DB_SCHEMA', PUBLIC_SCHEMA);
// debug settings, site lang, etc
define('TARGET', $SITE_CONFIG[HOST_NAME]['location'] ?? 'test');
define('DEBUG', $SITE_CONFIG[HOST_NAME]['debug_flag'] ?? false);
define('SITE_LOCALE', $SITE_CONFIG[HOST_NAME]['site_locale'] ?? DEFAULT_LOCALE);
define('SITE_ENCODING', $SITE_CONFIG[HOST_NAME]['site_encoding'] ?? DEFAULT_ENCODING);
define('LOGIN_ENABLED', $SITE_CONFIG[HOST_NAME]['login_enabled'] ?? false);
define('AUTH', $SITE_CONFIG[HOST_NAME]['auth'] ?? false);
// paths
// define('CSV_PATH', $PATHS[TARGET]['csv_path'] ?? '');
// define('EXPORT_SCRIPT', $PATHS[TARGET]['perl_bin'] ?? '');
// define('REDIRECT_URL', $PATHS[TARGET]['redirect_url'] ?? '');
// show all errors if debug_all & show_error_handling are enabled
define('SHOW_ALL_ERRORS', true);
/************* GENERAL PAGE TITLE ********/
define('G_TITLE', $_ENV['G_TITLE'] ?? '');
/************ STYLE SHEETS / JS **********/
define('ADMIN_STYLESHEET', 'edit.css');
define('ADMIN_JAVASCRIPT', 'edit.js');
define('STYLESHEET', $_ENV['STYLESHEET'] ?? 'frontend.css');
define('JAVASCRIPT', $_ENV['JAVASCRIPT'] ?? 'frontend.js');
// anything optional
/************* INTERNAL ******************/
// any other global definitons in the config.other.php
if (file_exists(BASE . CONFIGS . 'config.other.php')) {
require BASE . CONFIGS . 'config.other.php';
}
/************* DEBUG *******************/
// turn off debug if debug flag is OFF
if (defined('DEBUG') && DEBUG == false) {
$ECHO_ALL = false;
$DEBUG_ALL = false;
$PRINT_ALL = false;
$DB_DEBUG = false;
$ENABLE_ERROR_HANDLING = false;
$DEBUG_ALL_OVERRIDE = false;
} else {
$ECHO_ALL = false;
$DEBUG_ALL = true;
$PRINT_ALL = true;
$DB_DEBUG = true;
$ENABLE_ERROR_HANDLING = false;
$DEBUG_ALL_OVERRIDE = false;
}
// __END__

View File

@@ -0,0 +1,35 @@
<?php // phpcs:ignore PSR1.Files.SideEffects
/********************************************************************
* AUTHOR: Clemens Schwaighofer
* CREATED: 2019/10/28
* SHORT DESCRIPTION:
* other global constant variables
* HISTORY:
*********************************************************************/
declare(strict_types=1);
// define('SOME_ID', <SOME VALUE>);
/************* CONVERT *******************/
// this only needed if the external thumbnail create is used
$paths = [
'/bin',
'/usr/bin',
'/usr/local/bin',
];
// find convert
foreach ($paths as $path) {
if (
file_exists($path . DIRECTORY_SEPARATOR . 'convert') &&
is_file($path . DIRECTORY_SEPARATOR . 'convert')
) {
// image magick convert location
define('CONVERT', $path . DIRECTORY_SEPARATOR . 'convert');
break;
}
}
unset($paths);
// __END__

78
test/configs/config.php Normal file
View File

@@ -0,0 +1,78 @@
<?php // phpcs:ignore warning
/********************************************************************
* AUTHOR: Clemens Schwaighofer
* CREATED: 2018/10/11
* SHORT DESCRIPTION:
* pre config included -> includes master config
* HISTORY:
*********************************************************************/
declare(strict_types=1);
define('CONFIG_PATH', 'configs' . DIRECTORY_SEPARATOR);
// config path prefix search, start with 0, got down each level __DIR__ has,
// if nothing found -> bail
$CONFIG_PATH_PREFIX = '';
// base path for loads
$__DIR__PATH = __DIR__ . DIRECTORY_SEPARATOR;
// don't load autoloader twice
$end_autoload = false;
for (
$dir_pos = 0, $dir_max = count(explode(DIRECTORY_SEPARATOR, __DIR__));
$dir_pos <= $dir_max;
$dir_pos++
) {
$CONFIG_PATH_PREFIX .= '..' . DIRECTORY_SEPARATOR;
if ($end_autoload === false) {
/************* AUTO LOADER *******************/
// composer auto loader, in composer.json file add classmap for lib/:
// "autoload": {
// "classmap": [
// "lib/"
// ]
// },
// NOTE: MUST RUN composer dump-autoload if file/class names are
// changed or new ones are added
if (
is_file(
$__DIR__PATH . $CONFIG_PATH_PREFIX
. 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'
)
) {
require $__DIR__PATH . $CONFIG_PATH_PREFIX
. 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';
$end_autoload = true;
}
}
/************* MASTER CONFIG *******************/
if (
is_file($__DIR__PATH . $CONFIG_PATH_PREFIX . CONFIG_PATH . 'config.master.php')
) {
// load enviorment file if it exists
\CoreLibs\Get\DotEnv::readEnvFile(
$__DIR__PATH . $CONFIG_PATH_PREFIX . CONFIG_PATH
);
// load master config file that loads all other config files
require $__DIR__PATH . $CONFIG_PATH_PREFIX . CONFIG_PATH . 'config.master.php';
break;
}
}
// fail if no base DIR is not set
if (!defined('DIR')) {
exit('Base config could not be loaded');
}
// find trigger name "admin/" or "frontend/" in the getcwd() folder
foreach (['admin', 'frontend'] as $folder) {
if (strstr(getcwd() ?: '', DIRECTORY_SEPARATOR . $folder)) {
break;
}
}
// if content path is empty, fallback is default
/** @phpstan-ignore-next-line can be empty */
if (empty($folder)) {
$folder = 'default';
}
define('CONTENT_PATH', $folder . DIRECTORY_SEPARATOR);
// __END__

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,52 @@
#!/usr/bin/env bash
# note: there is currently no port selection, standard 5432 port is assumed
# note: we use the default in path postgresql commands and connect to whatever default DB is set
# PARAMETER 1: database data file to load
# PARAMETER 2: db user WHO MUST BE ABLE TO CREATE A DATABASE
# PARAMETER 3: db name
# PARAMETER 4: db host
# PARAMETER 5: print out for testing
load_sql="${1}";
# abort with 1 if we cannot find the file
if [ ! -f "${load_sql}" ]; then
echo 1;
exit 1;
fi;
db_user="${2}";
db_name="${3}";
db_host="${4}";
# empty db name or db user -> exit with 2
if [ -z "${db_user}" ] || [ -z "${db_name}" ] || [ -z "${db_host}" ]; then
echo 2;
exit 2;
fi;
# drop database, on error exit with 3
dropdb -U ${db_user} -h ${db_host} ${db_name} 2>&1;
if [ $? -ne 0 ]; then
echo 3;
exit 3;
fi;
# create database, on error exit with 4
createdb -U ${db_user} -O ${db_user} -h ${db_host} -E utf8 ${db_name} 2>&1;
if [ $? -ne 0 ]; then
echo 4;
exit 4;
fi;
# if error 5 thrown, test with enabled below
if [ ! -z "${5}" ]; then
psql -U ${db_user} -h ${db_host} -f ${load_sql} ${db_name};
else
# load data (redirect ALL error to null), on error exit with 5
psql -U ${db_user} -h ${db_host} -f ${load_sql} ${db_name} 2>&1 1>/dev/null 2>/dev/null;
fi;
if [ $? -ne 0 ]; then
echo 5;
exit 5;
fi;
echo 0;
exit 0;
# __END__

View File

@@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Test class for Admin\Backend
* @coversDefaultClass \CoreLibs\Admin\Backend
* @testdox \CoreLibs\Admin\Backend method tests
*/
final class CoreLibsAdminBackendTest extends TestCase
{
/**
* Undocumented function
*
* @return void
*/
protected function setUp(): void
{
if (!extension_loaded('pgsql')) {
$this->markTestSkipped(
'The PgSQL extension is not available.'
);
}
}
/**
* Undocumented function
*
* @testdox Admin\Backend Class tests
*
* @return void
*/
public function testAdminBackend()
{
/* $this->assertTrue(true, 'ACL Login Tests not implemented');
$this->markTestIncomplete(
'ACL\Login Tests have not yet been implemented'
); */
$this->markTestSkipped('No implementation for Admin\Backend at the moment');
}
}
// __END__

View File

@@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Test class for Admin\EditPage
* @coversDefaultClass \CoreLibs\Admin\EditPage
* @testdox \CoreLibs\Admin\EditPage method tests
*/
final class CoreLibsAdminEditPageTest extends TestCase
{
/**
* Undocumented function
*
* @return void
*/
protected function setUp(): void
{
if (!extension_loaded('pgsql')) {
$this->markTestSkipped(
'The PgSQL extension is not available.'
);
}
}
/**
* Undocumented function
*
* @testdox Admin\EditPage Class tests
*
* @return void
*/
public function testAdminEditPage()
{
/* $this->assertTrue(true, 'ACL Login Tests not implemented');
$this->markTestIncomplete(
'ACL\Login Tests have not yet been implemented'
); */
$this->markTestSkipped('No implementation for Admin\EditPage at the moment');
}
}
// __END__

View File

@@ -0,0 +1,329 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Test class for Check\Colors
* @coversDefaultClass \CoreLibs\Check\Colors
* @testdox \CoreLibs\Check\Colors method tests
*/
final class CoreLibsCheckColorsTest extends TestCase
{
public function validateColorProvider(): array
{
/*
0: input color string
1: flag (or flags to set)
2: expected result (bool)
*/
return [
// * hex
'valid hex rgb, flag ALL (default)' => [
'#ab12cd',
null,
true,
],
'valid hex rgb, flag ALL' => [
'#ab12cd',
\CoreLibs\Check\Colors::ALL,
true,
],
'valid hex rgb, flag HEX_RGB' => [
'#ab12cd',
\CoreLibs\Check\Colors::HEX_RGB,
true,
],
'valid hex rgb, wrong flag' => [
'#ab12cd',
\CoreLibs\Check\Colors::RGB,
false,
],
// error
'invalid hex rgb A' => [
'#ab12zz',
null,
false,
],
'invalid hex rgb B' => [
'#ZyQfo',
null,
false,
],
// other valid hex checks
'valid hex rgb, alt A' => [
'#AB12cd',
null,
true,
],
// * hax alpha
'valid hex rgb alpha, flag ALL (default)' => [
'#ab12cd12',
null,
true,
],
'valid hex rgb alpha, flag ALL' => [
'#ab12cd12',
\CoreLibs\Check\Colors::ALL,
true,
],
'valid hex rgb alpha, flag HEX_RGBA' => [
'#ab12cd12',
\CoreLibs\Check\Colors::HEX_RGBA,
true,
],
'valid hex rgb alpha, wrong flag' => [
'#ab12cd12',
\CoreLibs\Check\Colors::RGB,
false,
],
// error
'invalid hex rgb alpha A' => [
'#ab12dd1',
null,
false,
],
'invalid hex rgb alpha B' => [
'#ab12ddzz',
null,
false,
],
'valid hex rgb alpha, alt A' => [
'#ab12cdEE',
null,
true,
],
// * rgb
'valid rgb, flag ALL (default)' => [
'rgb(255, 10, 20)',
null,
true,
],
'valid rgb, flag ALL' => [
'rgb(255, 10, 20)',
\CoreLibs\Check\Colors::ALL,
true,
],
'valid rgb, flag RGB' => [
'rgb(255, 10, 20)',
\CoreLibs\Check\Colors::RGB,
true,
],
'valid rgb, wrong flag' => [
'rgb(255, 10, 20)',
\CoreLibs\Check\Colors::HEX_RGB,
false,
],
// error
'invalid rgb A' => [
'rgb(356, 10, 20)',
null,
false,
],
// other valid rgb conbinations
'valid rgb, alt A (percent)' => [
'rgb(100%, 10%, 20%)',
null,
true,
],
// TODO check all % and non percent combinations
'valid rgb, alt B (percent, mix)' => [
'rgb(100%, 10, 40)',
null,
true,
],
// * rgb alpha
'valid rgba, flag ALL (default)' => [
'rgba(255, 10, 20, 0.5)',
null,
true,
],
'valid rgba, flag ALL' => [
'rgba(255, 10, 20, 0.5)',
\CoreLibs\Check\Colors::ALL,
true,
],
'valid rgba, flag RGB' => [
'rgba(255, 10, 20, 0.5)',
\CoreLibs\Check\Colors::RGBA,
true,
],
'valid rgba, wrong flag' => [
'rgba(255, 10, 20, 0.5)',
\CoreLibs\Check\Colors::HEX_RGB,
false,
],
// error
'invalid rgba A' => [
'rgba(356, 10, 20, 0.5)',
null,
false,
],
// other valid rgba combinations
'valid rgba, alt A (percent)' => [
'rgba(100%, 10%, 20%, 0.5)',
null,
true,
],
// TODO check all % and non percent combinations
'valid rgba, alt B (percent, mix)' => [
'rgba(100%, 10, 40, 0.5)',
null,
true,
],
// TODO check all % and non percent combinations with percent transparent
'valid rgba, alt C (percent transparent)' => [
'rgba(100%, 10%, 20%, 50%)',
null,
true,
],
/*
// hsl
'hsl(100, 50%, 60%)',
'hsl(100, 50.5%, 60.5%)',
'hsla(100, 50%, 60%)',
'hsla(100, 50.5%, 60.5%)',
'hsla(100, 50%, 60%, 0.5)',
'hsla(100, 50.5%, 60.5%, 0.5)',
'hsla(100, 50%, 60%, 50%)',
'hsla(100, 50.5%, 60.5%, 50%)',
*/
// * hsl
'valid hsl, flag ALL (default)' => [
'hsl(100, 50%, 60%)',
null,
true,
],
'valid hsl, flag ALL' => [
'hsl(100, 50%, 60%)',
\CoreLibs\Check\Colors::ALL,
true,
],
'valid hsl, flag RGB' => [
'hsl(100, 50%, 60%)',
\CoreLibs\Check\Colors::HSL,
true,
],
'valid hsl, wrong flag' => [
'hsl(100, 50%, 60%)',
\CoreLibs\Check\Colors::HEX_RGB,
false,
],
'invalid hsl A' => [
'hsl(500, 50%, 60%)',
null,
false,
],
'valid hsl, alt A' => [
'hsl(100, 50.5%, 60.5%)',
null,
true,
],
// * hsl alpha
'valid hsla, flag ALL (default)' => [
'hsla(100, 50%, 60%, 0.5)',
null,
true,
],
'valid hsla, flag ALL' => [
'hsla(100, 50%, 60%, 0.5)',
\CoreLibs\Check\Colors::ALL,
true,
],
'valid hsla, flag RGB' => [
'hsla(100, 50%, 60%, 0.5)',
\CoreLibs\Check\Colors::HSLA,
true,
],
'valid hsla, wrong flag' => [
'hsla(100, 50%, 60%, 0.5)',
\CoreLibs\Check\Colors::HEX_RGB,
false,
],
'invalid hsla A' => [
'hsla(500, 50%, 60%, 0.5)',
null,
false,
],
'valid hsla, alt A (percent alpha' => [
'hsla(100, 50%, 60%, 50%)',
null,
true,
],
'valid hsla, alt A (percent alpha' => [
'hsla(100, 50.5%, 60.5%, 50%)',
null,
true,
],
// * combined flag checks
'valid rgb, flag RGB|RGBA' => [
'rgb(100%, 10%, 20%)',
\CoreLibs\Check\Colors::RGB | \CoreLibs\Check\Colors::RGBA,
true,
],
// TODO other combined flag checks all combinations
// * invalid string
'invalid string A' => [
'invalid string',
null,
false,
],
'invalid string B' => [
'(hsla(100, 100, 100))',
null,
false,
],
'invalid string C' => [
'hsla(100, 100, 100',
null,
false,
],
];
}
/**
* Undocumented function
*
* @covers ::validateColor
* @dataProvider validateColorProvider
* @testdox validateColor $input with flags $flags be $expected [$_dataName]
*
* @param string $input
* @param int|null $flags
* @param bool $expected
* @return void
*/
public function testValidateColor(string $input, ?int $flags, bool $expected)
{
if ($flags === null) {
$result = \CoreLibs\Check\Colors::validateColor($input);
} else {
$result = \CoreLibs\Check\Colors::validateColor($input, $flags);
}
$this->assertEquals(
$expected,
$result
);
}
/**
* Undocumented function
*
* @covers ::validateColor
* @testWith [99]
* @testdox Check Exception throw for $flag
*
* @param int $flag
* @return void
*/
public function testValidateColorException(int $flag): void
{
$this->expectException(\Exception::class);
\CoreLibs\Check\Colors::validateColor('#ffffff', $flag);
}
}
// __END__

View File

@@ -0,0 +1,381 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Undocumented class
* @coversDefaultClass \CoreLibs\Check\Email
* @testdox \CoreLibs\Check\Email method tests
*/
final class CoreLibsCheckEmailTest extends TestCase
{
/**
* Array position to regex
*
* @return array<mixed>
*/
public function emailRegexProvider(): array
{
return [
'get email regex invalid -1, will be 0' => [
-1,
"^[A-Za-z0-9!#$%&'*+\-\/=?^_`{|}~][A-Za-z0-9!#$%:\(\)&'*+\-\/=?^_`{|}~\.]{0,63}@"
. "[a-zA-Z0-9\-]+(\.[a-zA-Z0-9\-]{1,})*\.([a-zA-Z]{2,}){1}$"
],
'get email regex invalid 10, will be 0' => [
10,
"^[A-Za-z0-9!#$%&'*+\-\/=?^_`{|}~][A-Za-z0-9!#$%:\(\)&'*+\-\/=?^_`{|}~\.]{0,63}@"
. "[a-zA-Z0-9\-]+(\.[a-zA-Z0-9\-]{1,})*\.([a-zA-Z]{2,}){1}$"
],
'get email regex valid 1, will be 1' => [
1,
"@(.*)@(.*)"
]
];
}
/**
* Test regex level return
*
* @covers ::getEmailRegex
* @dataProvider emailRegexProvider
* @testdox getEmailRegex $input will be $expected [$_dataName]
*
* @param int $input
* @param string $expected
* @return void
*/
public function testGetEmailRegexReturn(int $input, string $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Check\Email::getEmailRegex($input)
);
}
/**
* provides data for emailCheckProvider and emailCheckFullProvider
*
* @return array
*/
public function emailCheckList(): array
{
return [
'valid email' => ['test@test.com', true, []],
'invalid empty email' => ['', false, [0, 2, 3, 4, 5]],
'invalid email' => ['-@-', false, [0, 3, 4, 5]],
'invalid email leading dot' => ['.test@test.com', false, [0, 2]],
'invalid email invalid domain' => ['test@t_est.com', false, [0, 3, 4]],
'invalid email double @' => ['test@@test.com', false, [0, 1]],
'invalid email double dot' => ['test@test..com', false, [0, 3, 6]],
'invalid email end with dot' => ['test@test.', false, [0, 3, 5, 7]],
'invalid email bad top level' => ['test@test.j', false, [0, 3, 5]],
'invalid email double @ and double dot' => ['test@@test..com', false, [0, 1, 3, 6]],
];
}
/**
* Valids or not valid email address
*
* @return array
*/
public function emailCheckProvider(): array
{
$list = [];
foreach ($this->emailCheckList() as $key => $data) {
$list[$key] = [$data[0], $data[1]];
}
return $list;
}
/**
* Undocumented function
*
* @covers ::checkEmail
* @dataProvider emailCheckProvider
* @testdox checkEmail $input will be $expected [$_dataName]
*
* @return void
*/
public function testCheckEmail(string $input, bool $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Check\Email::checkEmail($input)
);
}
/**
* this is like emailCheckProvider but it has the full detail errors
* All errors should be tetsed in testGetEmailRegexErrorMessage
*
* @return array
*/
public function emailCheckFullProvider(): array
{
$list = [];
foreach ($this->emailCheckList() as $key => $data) {
$list[$key] = [$data[0], $data[2]];
}
return $list;
}
/**
* Undocumented function
*
* @covers ::checkEmailFull
* @dataProvider emailCheckFullProvider
* @testdox checkEmailFull $input will be $expected [$_dataName]
*
* @param string $input
* @param array $expected
* @return void
*/
public function testCheckEmailFull(string $input, array $expected): void
{
$this->assertEqualsCanonicalizing(
$expected,
\CoreLibs\Check\Email::checkEmailFull($input, true)
);
}
/**
* error data returned for each error position
*
* @return array
*/
public function emailRegexErrorProvider(): array
{
return [
'error 0 will return general' => [
0,
[
'error' => 0,
'message' => 'Invalid email address',
'regex' => "^[A-Za-z0-9!#$%&'*+\-\/=?^_`{|}~][A-Za-z0-9!#$%:\(\)&'*+\-\/=?^_`{|}~\.]{0,63}@"
. "[a-zA-Z0-9\-]+(\.[a-zA-Z0-9\-]{1,})*\.([a-zA-Z]{2,}){1}$"
]
],
'error 1 will return double @ error' => [
1,
[
'error' => 1,
'message' => 'Double @ mark in email address',
'regex' => "@(.*)@(.*)"
]
],
'error 2 will be invalid before @' => [
2,
[
'error' => 2,
'message' => 'Invalid email part before @ sign',
'regex' => "^[A-Za-z0-9!#$%&'*+\-\/=?^_`{|}~][A-Za-z0-9!#$%:\(\)&'*+\-\/=?^_`{|}~\.]{0,63}@"
]
],
'error 3 will be invalid domain and top level' => [
3,
[
'error' => 3,
'message' => 'Invalid domain part after @ sign',
'regex' => "@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]{1,})*\.([a-zA-Z]{2,}){1}$"
]
],
'error 4 will be invalid domain' => [
4,
[
'error' => 4,
'message' => 'Invalid domain name part',
'regex' => "@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]{1,})*\."
]
],
'error 5 will be invalid domain top level only' => [
5,
[
'error' => 5,
'message' => 'Wrong domain top level part',
'regex' => "\.([a-zA-Z]{2,6}){1}$"
]
],
'error 6 will be domain double dot' => [
6,
[
'error' => 6,
'message' => 'Double consecutive dots in domain name (..)',
'regex' => "@(.*)\.{2,}"
]
],
'error 7 will domain ends with dot' => [
7,
[
'error' => 7,
'message' => 'Domain ends with a dot or is missing top level part',
'regex' => "@.*\.$"
]
]
];
}
/**
* Undocumented function
*
* @covers ::getEmailRegexErrorMessage
* @dataProvider emailRegexErrorProvider
* @testdox getEmailRegexErrorMessage $input will be $expected [$_dataName]
*
* @param integer $input
* @param array $expected
* @return void
*/
public function testGetEmailRegexErrorMessage(int $input, array $expected): void
{
$this->assertEqualsCanonicalizing(
$expected,
\CoreLibs\Check\Email::getEmailRegexErrorMessage($input)
);
}
/**
* This holds all email type checks normal and short
*
* @return array
*/
public function emailTypeProvider(): array
{
return [
['test@test.com', 'pc_html', 'pc'],
['test@docomo.ne.jp', 'keitai_docomo', 'docomo'],
['test@softbank.ne.jp', 'keitai_softbank', 'softbank'],
['test@i.softbank.ne.jp', 'smartphone_softbank_iphone', 'iphone'],
// TODO: add more test emails here
];
}
/**
* Returns only normal email type checks
*
* @return array<mixed>
*/
public function emailTypeProviderLong(): array
{
$list = [];
foreach ($this->emailTypeProvider() as $set) {
$list['email ' . $set[0] . ' is valid and matches normal ' . $set[1]] = [$set[0], $set[1]];
}
$list['email is empty and not valid normal'] = ['', 'invalid'];
return $list;
}
/**
* only short email type list
*
* @return array<mixed>
*/
public function emailTypeProviderShort(): array
{
$list = [];
foreach ($this->emailTypeProvider() as $set) {
$list['email ' . $set[0] . ' is valid and matches short ' . $set[2]] = [$set[0], $set[2]];
}
$list['email is empty and not valid short'] = ['', 'invalid'];
return $list;
}
/**
* Undocumented function
*
* @covers ::getEmailType
* @dataProvider emailTypeProviderLong
* @testdox getEmailType $input will be normal $expected [$_dataName]
*
* @param string $input
* @param string $expected
* @return void
*/
public function testGetEmailTypeNormal(string $input, string $expected)
{
$this->assertEquals(
$expected,
\CoreLibs\Check\Email::getEmailType($input, false)
);
}
/**
* Undocumented function
*
* @covers ::getEmailType
* @dataProvider emailTypeProviderShort
* @testdox getEmailType $input will be short $expected [$_dataName]
*
* @param string $input
* @param string $expected
* @return void
*/
public function testGetEmailTypeShort(string $input, string $expected)
{
$this->assertEquals(
$expected,
\CoreLibs\Check\Email::getEmailType($input, true)
);
}
/**
* Undocumented function
*
* @return array
*/
public function emailProviderTypeLongToShort(): array
{
$mobile_email_type_short = [
'keitai_docomo' => 'docomo',
'keitai_kddi_ezweb' => 'kddi',
'keitai_kddi' => 'kddi',
'keitai_kddi_tu-ka' => 'kddi',
'keitai_kddi_sky' => 'kddi',
'keitai_softbank' => 'softbank',
'smartphone_softbank_iphone' => 'iphone',
'keitai_softbank_disney' => 'softbank',
'keitai_softbank_vodafone' => 'softbank',
'keitai_softbank_j-phone' => 'softbank',
'keitai_willcom' => 'willcom',
'keitai_willcom_pdx' => 'willcom',
'keitai_willcom_bandai' => 'willcom',
'keitai_willcom_pipopa' => 'willcom',
'keitai_willcom_ymobile' => 'willcom',
'keitai_willcom_emnet' => 'willcom',
'pc_html' => 'pc',
];
$list = [];
// use the static one
foreach ($mobile_email_type_short as $long => $short) {
$list[$long . ' matches to ' . $short] = [$long, $short];
}
// add invalid check
$list['Not found will be bool false'] = ['invalid', false];
return $list;
}
/**
* Undocumented function
*
* @covers ::getShortEmailType
* @dataProvider emailProviderTypeLongToShort
* @testdox getShortEmailType $input will be $expected [$_dataName]
*
* @param string $input
* @param string|bool $expected
* @return void
*/
public function testGetShortEmailType(string $input, $expected)
{
$this->assertEquals(
$expected,
\CoreLibs\Check\Email::getShortEmailType($input)
);
}
}
// __END__

View File

@@ -0,0 +1,120 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Test class for Check\Encoding
* @coversDefaultClass \CoreLibs\Check\Encoding
* @testdox \CoreLibs\Check\Encoding method tests
*/
final class CoreLibsCheckEncodingTest extends TestCase
{
/**
* Undocumented function
*
* @return array
*/
public function checkConvertEncodingProvider(): array
{
return [
// 0: string to test
// 1: source encoding
// 2: target encoding
// 3: substitue character
// 4: false for ok, array with error list
'valid test UTF-8 to SJIS (default)' => [
'日本語',
'UTF-8',
'SJIS',
null,
false
],
'invalid test UTF-8 to SJIS (dots as code point)' => [
'❶',
'UTF-8',
'SJIS',
0x2234,
['❶']
],
'invalid test UTF-8 to SJIS (dots as string)' => [
'❶',
'UTF-8',
'SJIS',
'∴',
['❶']
],
'invalid test UTF-8 to SJIS (none)' => [
'❶',
'UTF-8',
'SJIS',
'none',
['❶']
],
'invalid test UTF-8 to SJIS (long)' => [
'❶',
'UTF-8',
'SJIS',
'long',
['❶']
],
'invalid test UTF-8 to SJIS (entity)' => [
'❶',
'UTF-8',
'SJIS',
'entity',
['❶']
],
];
}
/**
* Undocumented function
*
* @covers ::checkConvertEncoding
* @dataProvider checkConvertEncodingProvider
* @testdox check encoding convert from $from_encoding to $to_encoding [$_dataName]
*
* @param string $input
* @param string $from_encoding
* @param string $to_encoding
* @param string|int|null $error_char
* @param array|bool $expected
* @return void
*/
public function testCheckConvertEncoding(
string $input,
string $from_encoding,
string $to_encoding,
$error_char,
$expected
): void {
$current_subsitute_character = mb_substitute_character();
if ($error_char !== null) {
\CoreLibs\Check\Encoding::setErrorChar($error_char);
if (!in_array($error_char, ['none', 'long', 'entity'])) {
$this->assertEquals(
\IntlChar::chr($error_char),
\CoreLibs\Check\Encoding::getErrorChar()
);
} else {
$this->assertEquals(
$error_char,
\CoreLibs\Check\Encoding::getErrorChar()
);
}
}
$return = \CoreLibs\Check\Encoding::checkConvertEncoding($input, $from_encoding, $to_encoding);
$this->assertEquals(
$expected,
$return
);
// reset after test
mb_substitute_character($current_subsitute_character);
}
}
// __END__

View File

@@ -0,0 +1,120 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Test class for Check\File
* @coversDefaultClass \CoreLibs\Check\File
* @testdox \CoreLibs\Check\File method tests
*/
final class CoreLibsCheckFileTest extends TestCase
{
/** @var array<mixed> */
// private $files_list = [];
/** @var string */
private $base_folder = DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR;
/**
* main file list + data provider
*
* filename, file extension matching, lines in file, -1 for nothing
*
* @return array
*/
public function filesList(): array
{
return [
['filename.txt', 'txt', 5],
['filename.csv', 'csv', 15],
['filename.tsv', 'tsv', 0],
['file_does_not_exits', '', -1],
];
}
/**
* Undocumented function
*
* @return array
*/
public function filesExtensionProvider(): array
{
$list = [];
foreach ($this->filesList() as $row) {
$list[$row[0] . ' must be extension ' . $row[1]] = [$row[0], $row[1]];
}
return $list;
}
/**
* Undocumented function
*
* @return array
*/
public function filesLinesProvider(): array
{
$list = [];
foreach ($this->filesList() as $row) {
$list[$row[0] . ' must have ' . $row[2] . ' lines'] = [$row[0], $row[2]];
}
return $list;
}
/**
* Tests if file extension matches
*
* @covers ::getFilenameEnding
* @dataProvider filesExtensionProvider
* @testdox getFilenameEnding $input must be extension $expected [$_dataName]
*
* @param string $input
* @param string $expected
* @return void
*/
public function testGetFilenameEnding(string $input, string $expected): void
{
// getFilenameEnding
$this->assertEquals(
$expected,
\CoreLibs\Check\File::getFilenameEnding($input)
);
}
/**
* Tests the file line read
*
* @covers ::getLinesFromFile
* @dataProvider filesLinesProvider
* @testdox getLinesFromFile $input must have $expected lines [$_dataName]
*
* @param string $input file name
* @param int $expected lines in file
* @return void
*/
public function testGetLinesFromFile(string $input, int $expected): void
{
// create file
if ($expected > -1) {
$file = $this->base_folder . $input;
$fp = fopen($file, 'w');
for ($i = 0; $i < $expected; $i++) {
fwrite($fp, 'This is row ' . ($i + 1) . PHP_EOL);
}
fclose($fp);
}
// test
$this->assertEquals(
$expected,
\CoreLibs\Check\File::getLinesFromFile($this->base_folder . $input)
);
// unlink file
if (is_file($this->base_folder . $input)) {
unlink($this->base_folder . $input);
}
}
}
// __END__

View File

@@ -0,0 +1,73 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Test class for Check\Password
* @coversDefaultClass \CoreLibs\Check\Password
* @testdox \CoreLibs\Check\Password method tests
*/
final class CoreLibsCheckPasswordTest extends TestCase
{
public function passwordProvider(): array
{
return [
'matching password' => ['test', 'test', true],
'not matching password' => ['test', 'not_test', false],
];
}
public function passwordRehashProvider(): array
{
return [
'no rehash needed' => ['$2y$10$EgWJ2WE73DWi.hIyFRCdpejLXTvHbmTK3LEOclO1tAvXAXUNuUS4W', false],
'rehash needed' => ['9c42a1346e333a770904b2a2b37fa7d3', true],
];
}
/**
* Undocumented function
*
* @covers ::passwordVerify
* @covers ::passwordSet
* @dataProvider passwordProvider
* @testdox passwordSet $input compare to $input_hash: passwordVerify $expected [$_dataName]
*
* @param string $input
* @param string $input_hash
* @param boolean $expected
* @return void
*/
public function testPasswordSetVerify(string $input, string $input_hash, bool $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Check\Password::passwordVerify($input, \CoreLibs\Check\Password::passwordSet($input_hash))
);
}
/**
* Undocumented function
*
* @covers ::passwordRehashCheck
* @dataProvider passwordRehashProvider
* @testdox passwordRehashCheck $input will be $expected [$_dataName]
*
* @param string $input
* @param boolean $expected
* @return void
*/
public function testPasswordRehashCheck(string $input, bool $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Check\Password::passwordRehashCheck($input)
);
}
}
// __END__

View File

@@ -0,0 +1,73 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Test class for Check\PHPVersion
* @coversDefaultClass \CoreLibs\Check\PHPVersion
* @testdox \CoreLibs\Check\PHPVersion method tests
*/
final class CoreLibsCheckPhpVersionTest extends TestCase
{
/**
* NOTE: The checks must be adapted to the PHP version or they will fail
*
* @return array
*/
public function phpVersionProvider(): array
{
return [
// min
'min 7' => ['7', '', true],
'min 7.4' => ['7.4', '', true],
'min 7.4.1' => ['7.4.1', '', true],
// NOTE: update if php version bigger than 10
'min 10' => ['10', '', false],
'min 10.0' => ['10.0', '', false],
'min 10.0.0' => ['10.0.0', '', false],
// min/max version, NOTE: update if php version bigger than 10
'min 7/max 10' => ['7', '10', true],
'min 7/max 10.0' => ['7', '10.0', true],
'min 7/max 10.0.0' => ['7', '10.0.0', true],
// min/max version
'min 5/max 7' => ['5', '7', false],
'min 5/max 7.4' => ['5', '7.4', false],
'min 5/max 7.4.1' => ['5', '7.4.1', false],
// max only
'max 7' => ['', '7', false],
'max 7.4' => ['', '7.4', false],
'max 7.4.1' => ['', '7.4.1', false],
// max over
'max 10' => ['', '10', true],
'max 10.0' => ['', '10.0', true],
'max 10.0.0' => ['', '10.0.0', true],
// TODO: add null tests
];
}
/**
* Undocumented function
*
* @covers ::checkPHPVersion
* @dataProvider phpVersionProvider
* @testdox checkPHPVersion $input_min and $input_max will be $expected [$_dataName]
*
* @param string $input_min
* @param string $input_max
* @param string $expected
* @return void
*/
public function testCheckPHPVersion(string $input_min, string $input_max, bool $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Check\PhpVersion::checkPHPVersion($input_min, $input_max)
);
}
}
// __END__

View File

@@ -0,0 +1,873 @@
<?php
// because we have long testdox lines
// phpcs:disable Generic.Files.LineLength
declare(strict_types=1);
namespace tests;
use Exception;
use PHPUnit\Framework\TestCase;
/**
* Test class for Combined\ArrayHandler
* @coversDefaultClass \CoreLibs\Combined\ArrayHandler
* @testdox \CoreLibs\Combined\ArrayHandler method tests
*/
final class CoreLibsCombinedArrayHandlerTest extends TestCase
{
// we use that for all
public static $array = [
'a' => [
'b' => 'bar',
'c' => 'foo',
'same' => 'same',
3 => 'foobar',
'foobar' => 4,
'true' => true,
],
'd',
4,
'b',
'c' => 'test',
'same' => 'same',
'deep' => [
'sub' => [
'nested' => 'bar',
'same' => 'same',
'more' => 'test'
]
]
];
/**
* Undocumented function
*
* @return array
*/
public function arraySearchRecursiveProvider(): array
{
return [
'find value' => [
0 => 'bar',
1 => self::$array,
2 => null,
3 => ['a', 'b'],
],
'find value with key' => [
0 => 'bar',
1 => self::$array,
2 => 'nested',
3 => ['deep', 'sub', 'nested']
],
'not existing value' => [
0 => 'not exists',
1 => self::$array,
2 => null,
3 => [],
],
'find value int' => [
0 => 4,
1 => self::$array,
2 => null,
3 => ['a', 'foobar']
],
'find value int as string' => [
0 => '4',
1 => self::$array,
2 => null,
3 => []
],
'find value int as string with key' => [
0 => '4',
1 => self::$array,
2 => 'foobar',
3 => []
],
'first level value' => [
0 => 'd',
1 => self::$array,
2 => null,
4 => [0]
],
'find value, return int key' => [
0 => 'foobar',
1 => self::$array,
2 => null,
3 => ['a', 3]
]
];
}
/**
* Undocumented function
*
* @return array
*/
public function arraySearchRecursiveAllProvider(): array
{
return [
'find value' => [
0 => 'bar',
1 => self::$array,
2 => null,
3 => true,
4 => [
'level' => -1,
'work' => [],
'found' => [
0 => ['a', 'b'],
1 => ['deep', 'sub', 'nested']
]
]
],
'find value, new type' => [
0 => 'bar',
1 => self::$array,
2 => null,
3 => false,
4 => [
0 => ['a', 'b'],
1 => ['deep', 'sub', 'nested']
]
],
'find value with key' => [
0 => 'bar',
1 => self::$array,
2 => 'nested',
3 => true,
4 => [
'level' => -1,
'work' => [],
'found' => [
0 => ['deep', 'sub', 'nested']
]
]
],
'not existing value' => [
0 => 'not exists',
1 => self::$array,
2 => null,
3 => true,
4 => [
'level' => -1,
'work' => [],
],
],
'not existing value, new type' => [
0 => 'not exists',
1 => self::$array,
2 => null,
3 => false,
4 => [],
],
];
}
/**
* Undocumented function
*
* @return array
*/
public function arraySearchSimpleProvider(): array
{
return [
'key/value exist' => [
0 => self::$array,
1 => 'c',
2 => 'foo',
3 => false,
4 => true,
],
'key/value exists twice' => [
0 => self::$array,
1 => 'same',
2 => 'same',
3 => false,
4 => true,
],
'key/value not found' => [
0 => self::$array,
1 => 'not exists',
2 => 'not exists',
3 => false,
4 => false,
],
'key exists, value not' => [
0 => self::$array,
1 => 'b',
2 => 'not exists',
3 => false,
4 => false,
],
'key not, value exists' => [
0 => self::$array,
1 => 'not exists',
2 => 'bar',
3 => false,
4 => false,
],
'numeric key, value exists' => [
0 => self::$array,
1 => 0,
2 => 'd',
3 => false,
4 => true,
],
'numeric key as string, value exists' => [
0 => self::$array,
1 => '0',
2 => 'd',
3 => false,
4 => true,
],
'numeric key as string, value exists, strinct' => [
0 => self::$array,
1 => '0',
2 => 'd',
3 => true,
4 => false,
],
'key exists, value numeric' => [
0 => self::$array,
1 => 'foobar',
2 => 4,
3 => false,
4 => true,
],
'key exists, value numeric as string' => [
0 => self::$array,
1 => 'foobar',
2 => '4',
3 => false,
4 => true,
],
'key exists, value numeric as string, strict' => [
0 => self::$array,
1 => 'foobar',
2 => '4',
3 => true,
4 => false,
],
'key exists, value bool' => [
0 => self::$array,
1 => 'true',
2 => true,
3 => false,
4 => true,
],
'key exists, value bool as string' => [
0 => self::$array,
1 => 'true',
2 => 'true',
3 => false,
4 => true,
],
'key exists, value bool as string, strict' => [
0 => self::$array,
1 => 'true',
2 => 'true',
3 => true,
4 => false,
],
];
}
/**
* provides array listing for the merge test
*
* @return array
*/
public function arrayMergeRecursiveProvider(): array
{
return [
// 0: expected
// 1..n: to merge arrays
// n+1: trigger for handle keys as string
'two arrays' => [
['a' => 1, 'b' => 2, 'c' => 3],
['a' => 1, 'b' => 2],
['b' => 2, 'c' => 3],
],
'two arrays, string flag' => [
['a' => 1, 'b' => 2, 'c' => 3],
['a' => 1, 'b' => 2],
['b' => 2, 'c' => 3],
true,
],
// non hash arrays
'non hash array merge, no string flag' => [
[3, 4, 5],
[1, 2, 3],
[3, 4, 5],
],
'non hash array merge, string flag' => [
[1, 2, 3, 3, 4, 5],
[1, 2, 3],
[3, 4, 5],
true
],
];
}
/**
* for warning checks
*
* @return array
*/
public function arrayMergeRecursiveProviderWarning(): array
{
return [
// error <2 arguments
'too view arguments' => [
'arrayMergeRecursive needs two or more array arguments',
[1]
],
// error <2 arrays
'only one array' => [
'arrayMergeRecursive needs two or more array arguments',
[1],
true,
],
// error element is not array
'non array between array' => [
'arrayMergeRecursive encountered a non array argument',
[1],
'string',
[2]
],
];
}
/**
* Undocumented function
*
* @return array
*/
public function arrayCompareProvider(): array
{
return [
'one matching' => [
['a', 'b', 'c'],
['c', 'd', 'e'],
['a', 'b', 'd', 'e']
],
'all the same' => [
['a', 'b', 'c'],
['a', 'b', 'c'],
[]
],
'all different' => [
['a', 'b'],
['c', 'd'],
['a', 'b', 'c', 'd']
],
'empty arrays' => [
[],
[],
[]
]
];
}
/**
* Undocumented function
*
* @return array
*/
public function inArrayAnyProvider(): array
{
return [
'all exist in haystack' => [
[1],
[1, 2, 3, 4],
[1]
],
'not all exist in haystack' => [
[1, 5],
[1, 2, 3, 4],
[1]
],
'none exist in haystack' => [
[5],
[1, 2, 3, 4],
false
],
];
}
public function genAssocArrayProvider(): array
{
return [
'non set' => [
[
0 => ['a' => 'a1', 'b' => 2],
1 => ['a' => 'a2', 'b' => 3],
2 => ['a' => '', 'b' => null],
],
false,
false,
false,
[],
],
'key set' => [
[
0 => ['a' => 'a1', 'b' => 2],
1 => ['a' => 'a2', 'b' => 3],
2 => ['a' => '', 'b' => null],
],
'a',
false,
false,
['a1' => 0, 'a2' => 1],
],
'value set' => [
[
0 => ['a' => 'a1', 'b' => 2],
1 => ['a' => 'a2', 'b' => 3],
2 => ['a' => '', 'b' => null],
],
false,
'a',
false,
[0 => 'a1', 1 => 'a2', 2 => ''],
],
'key and value set, add empty, null' => [
[
0 => ['a' => 'a1', 'b' => 2],
1 => ['a' => 'a2', 'b' => 3],
2 => ['a' => '', 'b' => null],
],
'a',
'b',
false,
['a1' => 2, 'a2' => 3],
],
'key and value set, add empty' => [
[
0 => ['a' => 'a1', 'b' => 2],
1 => ['a' => 'a2', 'b' => 3],
2 => ['a' => '', 'b' => ''],
3 => ['a' => 'a4', 'b' => ''],
],
'a',
'b',
false,
['a1' => 2, 'a2' => 3, 'a4' => ''],
],
'key/value set, skip empty' => [
[
0 => ['a' => 'a1', 'b' => 2],
1 => ['a' => 'a2', 'b' => 3],
2 => ['a' => '', 'b' => null],
],
'a',
'b',
true,
['a1' => 2, 'a2' => 3],
],
];
}
/**
* Undocumented function
*
* @return array
*/
public function flattenArrayProvider(): array
{
return [
'array key/value, single' => [
0 => ['a' => 'foo', 1 => 'bar', 'c' => 2],
1 => ['foo', 'bar', 2],
2 => ['a', 1, 'c'],
3 => ['a', 1, 'c'],
],
'array values, single' => [
0 => ['foo', 'bar', 2],
1 => ['foo', 'bar', 2],
2 => [0, 1, 2],
3 => [0, 1, 2],
],
'array key/value, multi' => [
0 => [
'a' => ['a1' => 'a1foo', 'a2' => 'a1bar'],
1 => 'bar',
'c' => [2, 3, 4],
'd' => [
'e' => [
'de1' => 'subfoo', 'de2' => 'subbar', 'a2' => 'a1bar'
]
]
],
1 => ['a1foo', 'a1bar', 'bar', 2, 3, 4, 'subfoo', 'subbar', 'a1bar'],
2 => ['a', 'a1', 'a2', 1, 'c', 0, 1, 2, 'd', 'e', 'de1', 'de2', 'a2'],
3 => ['a1', 'a2', 1, 0, 1, 2, 'de1', 'de2', 'a2'],
],
'array with double values' => [
0 => ['a', 'a', 'b'],
1 => ['a', 'a', 'b'],
2 => [0, 1, 2],
3 => [0, 1, 2],
]
];
}
/**
* use the flattenArrayProvider and replace 1 with 2 array pos
*
* @return array
*/
public function flattenArrayKeyProvider(): array
{
$list = [];
foreach ($this->flattenArrayProvider() as $key => $row) {
$list[$key] = [
$row[0],
$row[2],
];
}
return $list;
}
/**
* use the flattenArrayProvider and replace 1 with array pos
*
* @return array
*/
public function flattenArrayKeyLeavesOnlyProvider(): array
{
$list = [];
foreach ($this->flattenArrayProvider() as $key => $row) {
$list[$key] = [
$row[0],
$row[3],
];
}
return $list;
}
/**
* Undocumented function
*
* @return array
*/
public function arrayFlatForKeyProvider(): array
{
return [
'all present, single level' => [
0 => [
'a' => ['b1' => 'foo', 'a2' => 'a-foo'],
'b' => ['b1' => 'bar', 'a2' => 'b-foo'],
'c' => ['b1' => 'foobar', 'a2' => 'c-foo'],
],
1 => 'a2',
2 => [
'a' => 'a-foo',
'b' => 'b-foo',
'c' => 'c-foo',
],
],
'no sub arrays' => [
0 => ['a', 'b', 'c'],
1 => 'a',
2 => ['a', 'b', 'c'],
],
'sub arrays with missing' => [
0 => [
'a' => ['b1' => 'foo', 'a2' => 'a-foo'],
'b' => ['b1' => 'bar'],
'c' => ['b1' => 'foobar', 'a2' => 'c-foo'],
],
1 => 'a2',
2 => [
'a' => 'a-foo',
'b' => ['b1' => 'bar'],
'c' => 'c-foo',
],
],
'deep nested sub arrays' => [
0 => [
'a' => [
'b1' => 'foo',
'a2' => [
'text' => ['a-foo', 'a-bar'],
],
],
'b' => [
'b1' => 'bar',
'a2' => [
'text' => 'b-foo',
],
],
],
1 => 'a2',
2 => [
'a' => [
'text' => ['a-foo', 'a-bar'],
],
'b' => [
'text' => 'b-foo',
],
],
]
];
}
/**
* Undocumented function
*
* @covers ::arraySearchRecursive
* @dataProvider arraySearchRecursiveProvider
* @testdox arraySearchRecursive $needle (key $key_search_for) in $input and will be $expected [$_dataName]
*
* @param string|null $needle
* @param array $input
* @param string|null $key_search_for
* @return void
*/
public function testArraySearchRecursive($needle, array $input, ?string $key_search_for, array $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Combined\ArrayHandler::arraySearchRecursive($needle, $input, $key_search_for)
);
}
/**
* Undocumented function
*
* @covers ::arraySearchRecursiveAll
* @dataProvider arraySearchRecursiveAllProvider
* @testdox arraySearchRecursiveAll $needle (key $key_search_for) in $input and will be $expected (old: $flag) [$_dataName]
*
* @param string|null $needle
* @param array $input
* @param string|null $key_search_for
* @param bool $flag
* @return void
*/
public function testArraySearchRecursiveAll($needle, array $input, ?string $key_search_for, bool $flag, array $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Combined\ArrayHandler::arraySearchRecursiveAll($needle, $input, $key_search_for, $flag)
);
}
/**
* Undocumented function
*
* @covers ::arraySearchSimple
* @dataProvider arraySearchSimpleProvider
* @testdox arraySearchSimple $input searched with key: $key / value: $value (strict: $flag) will be $expected [$_dataName]
*
* @param array $input
* @param string|int $key
* @param string|int $value
* @param bool $expected
* @return void
*/
public function testArraySearchSimple(array $input, $key, $value, bool $flag, bool $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Combined\ArrayHandler::arraySearchSimple($input, $key, $value, $flag)
);
}
/**
* Undocumented function
*
* @covers ::arrayMergeRecursive
* @dataProvider arrayMergeRecursiveProvider
* @testdox arrayMergeRecursive ... [$_dataName]
*
* @return void
*
*/
public function testArrayMergeRecursive(): void
{
$arrays = func_get_args();
// first is expected array, always
$expected = array_shift($arrays);
$output = \CoreLibs\Combined\ArrayHandler::arrayMergeRecursive(
...$arrays
);
$this->assertEquals(
$expected,
$output
);
}
/**
* Undocumented function
*
* @covers ::arrayMergeRecursive
* @dataProvider arrayMergeRecursiveProviderWarning
* @testdox arrayMergeRecursive with E_USER_WARNING [$_dataName]
*
* @return void
*/
public function testArrayMergeRecursiveWarningA(): void
{
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
$warning = array_shift($arrays);
// phpunit 10.0 compatible
$this->expectExceptionMessage(($warning));
\CoreLibs\Combined\ArrayHandler::arrayMergeRecursive(...$arrays);
restore_error_handler();
}
/**
* Undocumented function
*
* @covers ::arrayDiff
* @dataProvider arrayCompareProvider
* @testdox arrayDiff $input_a diff $input_b will be $expected [$_dataName]
*
* @param array $input_a
* @param array $input_b
* @param array $expected
* @return void
*/
public function testArrayDiff(array $input_a, array $input_b, array $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Combined\ArrayHandler::arrayDiff($input_a, $input_b)
);
}
/**
* Undocumented function
*
* @covers ::inArrayAny
* @dataProvider inArrayAnyProvider
* @testdox inArrayAny needle $input_a in haystack $input_b will be $expected [$_dataName]
*
* @param array $input_a
* @param array $input_b
* @param array|bool $expected
* @return void
*/
public function testInArrayAny(array $input_a, array $input_b, $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Combined\ArrayHandler::inArrayAny($input_a, $input_b)
);
}
/**
* Undocumented function
*
* @covers ::genAssocArray
* @dataProvider genAssocArrayProvider
* @testdox genAssocArray array $input with $key or $value and flag set only $flag will be $expected [$_dataName]
*
* @param array $input
* @param string|int|bool $key
* @param string|int|bool $value
* @param bool $flag
* @param array $expected
* @return void
*/
public function testGenAssocArray(array $input, $key, $value, bool $flag, array $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Combined\ArrayHandler::genAssocArray($input, $key, $value, $flag)
);
}
/**
* Undocumented function
*
* @covers ::flattenArray
* @dataProvider flattenArrayProvider
* @testdox testFlattenArray array $input will be $expected [$_dataName]
*
* @param array $input
* @param array $expected
* @return void
*/
public function testFlattenyArray(array $input, array $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Combined\ArrayHandler::flattenArray($input)
);
}
/**
* Undocumented function
*
* @covers ::flattenArrayKey
* @dataProvider flattenArrayKeyProvider
* @testdox flattenArrayKey array $input will be $expected [$_dataName]
*
* @param array $input
* @param array $expected
* @return void
*/
public function testFlattenArrayKey(array $input, array $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Combined\ArrayHandler::flattenArrayKey($input)
);
}
/**
* Undocumented function
*
* @covers ::flattenArrayKeyLeavesOnly
* @dataProvider flattenArrayKeyLeavesOnlyProvider
* @testdox flattenArrayKeyLeavesOnly array $input will be $expected [$_dataName]
*
* @param array $input
* @param array $expected
* @return void
*/
public function testFlattenArrayKeyLeavesOnly(array $input, array $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Combined\ArrayHandler::flattenArrayKeyLeavesOnly($input)
);
}
/**
* Undocumented function
*
* @covers ::arrayFlatForKey
* @dataProvider arrayFlatForKeyProvider
* @testdox arrayFlatForKey array $input will be $expected [$_dataName]
*
* @param array $input
* @param array $expected
* @return void
*/
public function testArrayFlatForKey(array $input, $search, array $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Combined\ArrayHandler::arrayFlatForKey($input, $search)
);
}
}
// __END__

View File

@@ -0,0 +1,785 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Test class for Combined\DateTime
* @coversDefaultClass \CoreLibs\Combined\DateTime
* @testdox \CoreLibs\Combined\DateTime method tests
*/
final class CoreLibsCombinedDateTimeTest extends TestCase
{
/**
* timestamps
*
* @return array
*/
public function timestampProvider(): array
{
return [
'valid timestamp no microtime' => [
1641515890,
false,
false,
'2022-01-07 09:38:10',
],
'valid timestamp with microtime' => [
1641515890,
true,
false,
'2022-01-07 09:38:10',
],
'valid timestamp with microtime float' => [
1641515890,
true,
true,
'2022-01-07 09:38:10',
],
'valid micro timestamp with microtime' => [
1641515890.123456,
true,
false,
'2022-01-07 09:38:10 1235ms',
],
'valid micro timestamp with microtime float' => [
1641515890.123456,
true,
true,
'2022-01-07 09:38:10.1235',
],
'valid micro timestamp no microtime' => [
1641515890.123456,
false,
false,
'2022-01-07 09:38:10',
],
'invalid timestamp' => [
-123123,
false,
false,
'1969-12-30 22:47:57',
],
];
}
/**
* interval for both directions
*
* @return array
*/
public function intervalProvider(): array
{
return [
'interval no microtime' => [
1641515890,
false,
'18999d 0h 38m 10s',
],
'interval with microtime' => [
1641515890,
true,
'18999d 0h 38m 10s',
],
'micro interval no microtime' => [
1641515890.123456,
false,
'18999d 0h 38m 10s',
],
'micro interval with microtime' => [
1641515890.123456,
true,
'18999d 0h 38m 10s 1235ms',
],
'negative interval no microtime' => [
-1641515890,
false,
'-18999d 0h 38m 10s',
],
// short for mini tests
'microtime only' => [
0.123456,
true,
'0s 1235ms',
],
'seconds only' => [
30.123456,
true,
'30s 1235ms',
],
'minutes only' => [
90.123456,
true,
'1m 30s 1235ms',
],
'hours only' => [
3690.123456,
true,
'1h 1m 30s 1235ms',
],
'days only' => [
90090.123456,
true,
'1d 1h 1m 30s 1235ms',
],
'already set' => [
'1d 1h 1m 30s 1235ms',
true,
'1d 1h 1m 30s 1235ms',
],
'invalid data' => [
'xyz',
true,
'0s',
],
'out of bounds timestamp' => [
999999999999999,
false,
'1s'
]
];
}
/**
* Undocumented function
*
* @return array
*/
public function reverseIntervalProvider(): array
{
return [
'interval no microtime' => [
'18999d 0h 38m 10s',
1641515890,
],
'micro interval with microtime' => [
'18999d 0h 38m 10s 1235ms',
1641515890.1235,
],
'micro interval with microtime' => [
'18999d 0h 38m 10s 1234567890ms',
1641515890.1234567,
],
'negative interval no microtime' => [
'-18999d 0h 38m 10s',
-1641515890,
],
// short for mini tests
'microtime only' => [
'0s 1235ms',
0.1235,
],
'seconds only' => [
'30s 1235ms',
30.1235,
],
'minutes only' => [
'1m 30s 1235ms',
90.1235,
],
'hours only' => [
'1h 1m 30s 1235ms',
3690.1235,
],
'days only' => [
'1d 1h 1m 30s 1235ms',
90090.1235,
],
'already set' => [
1641515890,
1641515890,
],
'invalid data' => [
'xyz',
'xyz',
],
'out of bound data' => [
'99999999999999999999d',
8.64E+24
],
];
}
/**
* Undocumented function
*
* @return array
*/
public function dateProvider(): array
{
return [
'valid date with -' => [
'2021-12-12',
true,
],
'valid date with /' => [
'2021/12/12',
true,
],
'valid date time with -' => [
'2021-12-12 12:12:12',
true,
],
'invalid date' => [
'2021-31-31',
false,
],
'invalid date string' => [
'xyz',
false,
],
'out of bound date' => [
'9999-12-31',
true
]
];
}
/**
* Undocumented function
*
* @return array
*/
public function dateTimeProvider(): array
{
return [
'valid date time with -' => [
'2021-12-12 12:12:12',
true,
],
'valid date time with /' => [
'2021/12/12 12:12:12',
true,
],
'vald date time with hour/min' => [
'2021/12/12 12:12',
true,
],
'valid date missing time' => [
'2021-12-12',
false,
],
'valid date invalid time string' => [
'2021-12-12 ab:cd',
false,
],
'invalid hour +' => [
'2021-12-12 35:12',
false,
],
'invalid hour -' => [
'2021-12-12 -12:12',
false,
],
'invalid minute +' => [
'2021-12-12 23:65:12',
false,
],
'invalid minute -' => [
'2021-12-12 23:-12:12',
false,
],
'invalid seconds +' => [
'2021-12-12 23:12:99',
false,
],
'invalid seconds -' => [
'2021-12-12 23:12:-12',
false,
],
'invalid seconds string' => [
'2021-12-12 23:12:ss',
false,
],
];
}
/**
* Undocumented function
*
* @return array
*/
public function dateCompareProvider(): array
{
return [
'first date smaller' => [
'2020-12-12',
'2021-12-12',
-1,
],
'dates equal' => [
'2020-12-12',
'2020-12-12',
0,
],
'second date smaller' => [
'2021-12-12',
'2020-12-12',
1
],
'dates equal with different time' => [
'2020-12-12 12:12:12',
'2020-12-12 13:13:13',
0,
],
'invalid dates --' => [
'--',
'--',
false
],
'empty dates' => [
'',
'',
false
],
'invalid dates' => [
'not a date',
'not a date either',
false,
],
'out of bound dates' => [
'1900-1-1',
'9999-12-31',
-1
]
];
}
public function dateTimeCompareProvider(): array
{
return [
'first date smaller no time' => [
'2020-12-12',
'2021-12-12',
-1,
],
'dates equal no timestamp' => [
'2020-12-12',
'2020-12-12',
0,
],
'second date smaller no timestamp' => [
'2021-12-12',
'2020-12-12',
1
],
'date equal first time smaller' => [
'2020-12-12 12:12:12',
'2020-12-12 13:13:13',
-1,
],
'date equal time equal' => [
'2020-12-12 12:12:12',
'2020-12-12 12:12:12',
0,
],
'date equal second time smaller' => [
'2020-12-12 13:13:13',
'2020-12-12 12:12:12',
1,
],
'valid date invalid time' => [
'2020-12-12 13:99:13',
'2020-12-12 12:12:99',
false,
],
'invalid datetimes --' => [
'--',
'--',
false,
],
'empty datetimess' => [
'',
'',
false,
],
'invalid datetimes' => [
'not a date',
'not a date either',
false,
],
];
}
/**
* Undocumented function
*
* @return array
*/
public function daysIntervalProvider(): array
{
return [
'valid interval /, not named array' => [
'2020/1/1',
'2020/1/30',
false,
[29, 22, 8],
],
'valid interval /, named array' => [
'2020/1/1',
'2020/1/30',
true,
['overall' => 29, 'weekday' => 22, 'weekend' => 8],
],
'valid interval -' => [
'2020-1-1',
'2020-1-30',
false,
[29, 22, 8],
],
'valid interval switched' => [
'2020/1/30',
'2020/1/1',
false,
[28, 0, 0],
],
'valid interval with time' => [
'2020/1/1 12:12:12',
'2020/1/30 13:13:13',
false,
[28, 21, 8],
],
'invalid dates' => [
'abc',
'xyz',
false,
[0, 0, 0]
],
// this test will take a long imte
'out of bound dates' => [
'1900-1-1',
'9999-12-31',
false,
[2958463,2113189,845274],
],
];
}
/**
* date string convert test
*
* @covers ::dateStringFormat
* @dataProvider timestampProvider
* @testdox dateStringFormat $input (microtime $flag) will be $expected [$_dataName]
*
* @param int|float $input
* @param bool $flag
* @param string $expected
* @return void
*/
public function testDateStringFormat(
$input,
bool $flag_show_micro,
bool $flag_micro_as_float,
string $expected
): void {
$this->assertEquals(
$expected,
\CoreLibs\Combined\DateTime::dateStringFormat(
$input,
$flag_show_micro,
$flag_micro_as_float
)
);
}
/**
* interval convert test
*
* @covers ::timeStringFormat
* @dataProvider intervalProvider
* @testdox timeStringFormat $input (microtime $flag) will be $expected [$_dataName]
*
* @param int|float $input
* @param bool $flag
* @param string $expected
* @return void
*/
public function testTimeStringFormat($input, bool $flag, string $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Combined\DateTime::timeStringFormat($input, $flag)
);
}
/**
* Undocumented function
*
* @covers ::stringToTime
* @dataProvider reverseIntervalProvider
* @testdox stringToTime $input will be $expected [$_dataName]
*
* @param string|int|float $input
* @param string|int|float $expected
* @return void
*/
public function testStringToTime($input, $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Combined\DateTime::stringToTime($input)
);
}
/**
* Undocumented function
*
* @covers ::checkDate
* @dataProvider dateProvider
* @testdox checkDate $input will be $expected [$_dataName]
*
* @param string $input
* @param bool $expected
* @return void
*/
public function testCheckDate(string $input, bool $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Combined\DateTime::checkDate($input)
);
}
/**
* Undocumented function
*
* @covers ::checkDateTime
* @dataProvider dateTimeProvider
* @testdox checkDateTime $input will be $expected [$_dataName]
*
* @param string $input
* @param bool $expected
* @return void
*/
public function testCheckDateTime(string $input, bool $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Combined\DateTime::checkDateTime($input)
);
}
/**
* Undocumented function
*
* @covers ::compareDate
* @dataProvider dateCompareProvider
* @testdox compareDate $input_a compared to $input_b will be $expected [$_dataName]
*
* @param string $input_a
* @param string $input_b
* @param int|bool $expected
* @return void
*/
public function testCompareDate(string $input_a, string $input_b, $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Combined\DateTime::compareDate($input_a, $input_b)
);
}
/**
* Undocumented function
*
* @covers ::compareDateTime
* @dataProvider dateTimeCompareProvider
* @testdox compareDateTime $input_a compared to $input_b will be $expected [$_dataName]
*
* @param string $input_a
* @param string $input_b
* @param int|bool $expected
* @return void
*/
public function testCompareDateTime(string $input_a, string $input_b, $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Combined\DateTime::compareDateTime($input_a, $input_b)
);
}
/**
* Undocumented function
*
* @covers ::calcDaysInterval
* @dataProvider daysIntervalProvider
* @testdox calcDaysInterval $input_a compared to $input_b will be $expected [$_dataName]
* @medium
*
* @param string $input_a
* @param string $input_b
* @param bool $flag
* @param array $expected
* @return void
*/
public function testCalcDaysInterval(
string $input_a,
string $input_b,
bool $flag,
$expected
): void {
$this->assertEquals(
$expected,
\CoreLibs\Combined\DateTime::calcDaysInterval($input_a, $input_b, $flag)
);
}
/**
* Undocumented function
*
* @return array
*/
public function weekdayNumberProvider(): array
{
return [
'0 invalid' => [0, null, 'Inv',],
'0 invalid long' => [0, true, 'Invalid',],
'1 short' => [1, null, 'Mon',],
'1 long' => [1, true, 'Monday',],
'2 short' => [2, null, 'Tue',],
'2 long' => [2, true, 'Tuesday',],
'3 short' => [3, null, 'Wed',],
'3 long' => [3, true, 'Wednesday',],
'4 short' => [4, null, 'Thu',],
'4 long' => [4, true, 'Thursday',],
'5 short' => [5, null, 'Fri',],
'5 long' => [5, true, 'Friday',],
'6 short' => [6, null, 'Sat',],
'6 long' => [6, true, 'Saturday',],
'7 short' => [7, null, 'Sun',],
'7 long' => [7, true, 'Sunday',],
'8 invalid' => [8, null, 'Inv',],
'8 invalid long' => [8, true, 'Invalid',],
];
}
/**
* int weekday number to string weekday
*
* @covers ::setWeekdayNameFromIsoDow
* @dataProvider weekdayNumberProvider
* @testdox weekdayListProvider $input (short $flag) will be $expected [$_dataName]
*
* @param int $input
* @param bool|null $flag
* @param string $expected
* @return void
*/
public function testSetWeekdayNameFromIsoDow(
int $input,
?bool $flag,
string $expected
): void {
if ($flag === null) {
$output = \CoreLibs\Combined\DateTime::setWeekdayNameFromIsoDow($input);
} else {
$output = \CoreLibs\Combined\DateTime::setWeekdayNameFromIsoDow($input, $flag);
}
$this->assertEquals(
$expected,
$output
);
}
/**
* Undocumented function
*
* @return array
*/
public function weekdayDateProvider(): array
{
return [
'invalid date' => ['2022-02-31', -1],
'1: monday' => ['2022-07-25', 1],
'2: tuesday' => ['2022-07-26', 2],
'3: wednesday' => ['2022-07-27', 3],
'4: thursday' => ['2022-07-28', 4],
'5: friday' => ['2022-07-29', 5],
'6: saturday' => ['2022-07-30', 6],
'7: sunday' => ['2022-07-31', 7],
];
}
/**
* date to weekday number
*
* @covers ::setWeekdayNumberFromDate
* @dataProvider weekdayDateProvider
* @testdox setWeekdayNumberFromDate $input will be $expected [$_dataName]
*
* @param string $input
* @param int $expected
* @return void
*/
public function testSetWeekdayNumberFromDate(
string $input,
int $expected
): void {
$this->assertEquals(
$expected,
\CoreLibs\Combined\DateTime::setWeekdayNumberFromDate($input)
);
}
/**
* Undocumented function
*
* @return array
*/
public function weekdayDateNameProvider(): array
{
return [
'invalid date short' => ['2022-02-31', null, 'Inv'],
'invalid date long' => ['2022-02-31', true, 'Invalid'],
'Mon short' => ['2022-07-25', null, 'Mon'],
'Monday long' => ['2022-07-25', true, 'Monday'],
'Tue short' => ['2022-07-26', null, 'Tue'],
'Tuesday long' => ['2022-07-26', true, 'Tuesday'],
'Wed short' => ['2022-07-27', null, 'Wed'],
'Wednesday long' => ['2022-07-27', true, 'Wednesday'],
'Thu short' => ['2022-07-28', null, 'Thu'],
'Thursday long' => ['2022-07-28', true, 'Thursday'],
'Fri short' => ['2022-07-29', null, 'Fri'],
'Friday long' => ['2022-07-29', true, 'Friday'],
'Sat short' => ['2022-07-30', null, 'Sat'],
'Saturday long' => ['2022-07-30', true, 'Saturday'],
'Sun short' => ['2022-07-31', null, 'Sun'],
'Sunday long' => ['2022-07-31', true, 'Sunday'],
];
}
/**
* date to weekday name
*
* @covers ::setWeekdayNameFromDate
* @dataProvider weekdayDateNameProvider
* @testdox setWeekdayNameFromDate $input (short $flag) will be $expected [$_dataName]
*
* @param string $input
* @param bool|null $flag
* @param string $expected
* @return void
*/
public function testSetWeekdayNameFromDate(
string $input,
?bool $flag,
string $expected
): void {
if ($flag === null) {
$output = \CoreLibs\Combined\DateTime::setWeekdayNameFromDate($input);
} else {
$output = \CoreLibs\Combined\DateTime::setWeekdayNameFromDate($input, $flag);
}
$this->assertEquals(
$expected,
$output
);
}
}
// __END__

View File

@@ -0,0 +1,280 @@
<?php
// because we have long testdox lines
// phpcs:disable Generic.Files.LineLength
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Test class for Convert\Byte
* @coversDefaultClass \CoreLibs\Convert\Byte
* @testdox \CoreLibs\Convert\Byte method tests
*/
final class CoreLibsConvertByteTest extends TestCase
{
/**
* Undocumented function
*
* @return array
*/
public function byteProvider(): array
{
/*
* 0: input string
* 1: default flags
* 2: BYTE_FORMAT_SI
* 3: BYTE_FORMAT_NOSPACE
* 4: BYTE_FORMAT_ADJUST
* 5: BYTE_FORMAT_SI | BYTE_FORMAT_NOSPACE
*/
return [
'string number' => [
0 => '1024',
1 => '1 KB',
2 => '1.02 KiB',
3 => '1KB',
4 => '1.00 KB',
5 => '1.02KiB',
],
'invalud string number' => [
0 => '1024 MB',
1 => '1024 MB',
2 => '1024 MB',
3 => '1024 MB',
4 => '1024 MB',
5 => '1024 MB',
],
'negative number' => [
0 => -123123123,
1 => '-117.42 MB',
2 => '-123.12 MiB',
3 => '-117.42MB',
4 => '-117.42 MB',
5 => '-123.12MiB',
],
'kilobyte minus one' => [
0 => 999999, // KB-1
1 => '976.56 KB',
2 => '1 MiB',
3 => '976.56KB',
4 => '976.56 KB',
5 => '1MiB',
],
'megabyte minus one' => [
0 => 999999999, // MB-1
1 => '953.67 MB',
2 => '1 GiB',
3 => '953.67MB',
4 => '953.67 MB',
5 => '1GiB',
],
'megabyte' => [
0 => 254779258,
1 => '242.98 MB',
2 => '254.78 MiB',
3 => '242.98MB',
4 => '242.98 MB',
5 => '254.78MiB',
],
'terabyte minus one' => [
0 => 999999999999999, // TB-1
1 => '909.49 TB',
2 => '1 PiB',
3 => '909.49TB',
4 => '909.49 TB',
5 => '1PiB',
],
'terabyte' => [
0 => 588795544887632, // TB-n
1 => '535.51 TB',
2 => '588.8 TiB',
3 => '535.51TB',
4 => '535.51 TB',
5 => '588.8TiB',
],
'petabyte minus one' => [
0 => 999999999999999999, // PB-1
1 => '888.18 PB',
2 => '1 EiB',
3 => '888.18PB',
4 => '888.18 PB',
5 => '1EiB',
],
'max int value' => [
0 => 9223372036854775807, // MAX INT
1 => '8 EB',
2 => '9.22 EiB',
3 => '8EB',
4 => '8.00 EB',
5 => '9.22EiB',
],
'exabyte minus 1' => [
0 => 999999999999999999999, // EB-1
1 => '867.36 EB',
2 => '1000 EiB',
3 => '867.36EB',
4 => '867.36 EB',
5 => '1000EiB',
],
];
}
/**
* Undocumented function
*
* @return array
*/
public function byteStringProvider(): array
{
return [
'negative number' => [
0 => '-117.42 MB',
1 => -123123794,
2 => -117420000,
],
'megabyte' => [
0 => '242.98 MB',
1 => 254782996,
2 => 242980000
],
'megabyte si' => [
0 => '254.78 MiB',
1 => 267156193,
2 => 254780000
],
'petabyte' => [
0 => '1 EiB',
1 => 1152921504606846976,
2 => 1000000000000000000,
],
'max int' => [
0 => '8 EB',
1 => -9223372036854775807 - 1,
2 => 8000000000000000000,
],
'exabyte, overflow' => [
0 => '867.36EB',
1 => 3873816255479021568,
2 => 363028535651074048,
]
];
}
/**
* Undocumented function
*
* @covers ::humanReadableByteFormat
* @dataProvider byteProvider
* @testdox humanReadableByteFormat $input will be $expected, $expected_si SI, $expected_no_space no space, $expected_adjust adjust, $expected_si_no_space SI/no space [$_dataName]
*
* @param string|int|float $input
* @param string $expected
* @param string $expected_si
* @param string $expected_no_space
* @param string $expected_adjust
* @param string $expected_si_no_space
* @return void
*/
public function testHumanReadableByteFormat(
$input,
string $expected,
string $expected_si,
string $expected_no_space,
string $expected_adjust,
string $expected_si_no_space
): void {
// 1024
$this->assertEquals(
$expected,
\CoreLibs\Convert\Byte::humanReadableByteFormat($input)
);
// 1000
$this->assertEquals(
$expected_si,
\CoreLibs\Convert\Byte::humanReadableByteFormat($input, \CoreLibs\Convert\Byte::BYTE_FORMAT_SI)
);
// no space
$this->assertEquals(
$expected_no_space,
\CoreLibs\Convert\Byte::humanReadableByteFormat($input, \CoreLibs\Convert\Byte::BYTE_FORMAT_NOSPACE)
);
// always 2 decimals
$this->assertEquals(
$expected_adjust,
\CoreLibs\Convert\Byte::humanReadableByteFormat($input, \CoreLibs\Convert\Byte::BYTE_FORMAT_ADJUST)
);
// combined si + no space
$this->assertEquals(
$expected_si_no_space,
\CoreLibs\Convert\Byte::humanReadableByteFormat(
$input,
\CoreLibs\Convert\Byte::BYTE_FORMAT_SI | \CoreLibs\Convert\Byte::BYTE_FORMAT_NOSPACE
)
);
}
/**
* Undocumented function
*
* @covers ::stringByteFormat
* @dataProvider byteStringProvider
* @testdox stringByteFormat $input will be $expected and $expected_si SI [$_dataName]
*
* @param string|int|float $input
* @param string|int|float $expected
* @param string|int|float $expected_si
* @return void
*/
public function testStringByteFormat($input, $expected, $expected_si): void
{
$this->assertEquals(
$expected,
\CoreLibs\Convert\Byte::stringByteFormat($input)
);
$this->assertEquals(
$expected_si,
\CoreLibs\Convert\Byte::stringByteFormat($input, \CoreLibs\Convert\Byte::BYTE_FORMAT_SI)
);
}
/**
* Exceptions tests
*
* @covers ::humanReadableByteFormat
* @testWith [99]
* @testdox Test exception for humanReadableByteFormat with flag $flag
*
* @param int $flag
* @return void
*/
public function testHumanReadableByteFormatException(int $flag): void
{
$this->expectException(\Exception::class);
\CoreLibs\Convert\Byte::humanReadableByteFormat(12, $flag);
}
/**
* Exceptions tests
* can only be 4, try 1,2 and over
*
* @covers ::stringByteFormat
* @testWith [1]
* [2]
* [99]
* @testdox Test exception for stringByteFormat with flag $flag
*
* @param int $flag
* @return void
*/
public function testStringByteFormatException(int $flag): void
{
$this->expectException(\Exception::class);
\CoreLibs\Convert\Byte::stringByteFormat(12, $flag);
}
}
// __END__

View File

@@ -0,0 +1,420 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Test class for Convert\Colors
* @coversDefaultClass \CoreLibs\Convert\Colors
* @testdox \CoreLibs\Convert\Colors method tests
*/
final class CoreLibsConvertColorsTest extends TestCase
{
// convert list
public static $colors = [];
/**
* Undocumented function
*
* @return array
*/
public function rgb2hexColorProvider(): array
{
return [
'color' => [
0 => 10,
1 => 100,
2 => 200,
3 => '#0a64c8',
4 => '0a64c8'
],
'gray' => [
0 => 12,
1 => 12,
2 => 12,
3 => '#0c0c0c',
4 => '0c0c0c',
],
'black' => [
0 => 0,
1 => 0,
2 => 0,
3 => '#000000',
4 => '000000',
],
'white' => [
0 => 255,
1 => 255,
2 => 255,
3 => '#ffffff',
4 => 'ffffff',
],
'invalid color red & green' => [
0 => -12,
1 => 300,
2 => 12,
3 => false,
4 => false
],
];
}
/**
* Undocumented function
*
* @return array
*/
public function hex2rgbColorProvider(): array
{
return [
'color' => [
0 => '#0a64c8',
1 => ['r' => 10, 'g' => 100, 'b' => 200],
2 => '10,100,200',
3 => ';',
4 => '10;100;200',
],
'gray, long' => [
0 => '0c0c0c',
1 => ['r' => 12, 'g' => 12, 'b' => 12],
2 => '12,12,12',
3 => ';',
4 => '12;12;12',
],
'gray, short' => [
0 => 'ccc',
1 => ['r' => 204, 'g' => 204, 'b' => 204],
2 => '204,204,204',
3 => ';',
4 => '204;204;204',
],
'hex string with #' => [
0 => '#0c0c0c',
1 => ['r' => 12, 'g' => 12, 'b' => 12],
2 => '12,12,12',
3 => ';',
4 => '12;12;12',
],
'a too long hex string' => [
0 => '#0c0c0c0c',
1 => false,
2 => false,
3 => ';',
4 => false,
],
'a too short hex string' => [
0 => '0c0c',
1 => false,
2 => false,
3 => ';',
4 => false,
]
];
}
/**
* Undocumented function
*
* @return array
*/
public function rgb2hslAndhsbList(): array
{
// if hsb_from or hsl_from is set, this will be used in hsb/hsl convert
// hsb_rgb is used for adjusted rgb valus due to round error to in
return [
'valid gray' => [
'rgb' => [12, 12, 12],
'hsb' => [0, 0, 5],
'hsb_rgb' => [13, 13, 13], // should be rgb, but rounding in this
'hsl' => [0.0, 0.0, 4.7],
'valid' => true,
],
'valid color' => [
'rgb' => [10, 100, 200],
'hsb' => [212, 95, 78.0],
'hsb_rgb' => [10, 98, 199], // should be rgb, but rounding error
'hsl' => [211.6, 90.5, 41.2],
'valid' => true,
],
// hsg/hsl with 360 which is seen as 0
'valid color hue 360' => [
'rgb' => [200, 10, 10],
'hsb' => [0, 95, 78.0],
'hsb_from' => [360, 95, 78.0],
'hsb_rgb' => [199, 10, 10], // should be rgb, but rounding error
'hsl' => [0.0, 90.5, 41.2],
'hsl_from' => [360.0, 90.5, 41.2],
'valid' => true,
],
// invalid values
'invalid color' => [
'rgb' => [-12, 300, 12],
'hsb' => [-12, 300, 12],
'hsl' => [-12, 300, 12],
'valid' => false,
],
];
}
/**
* Undocumented function
*
* @return array
*/
public function rgb2hsbColorProvider(): array
{
$list = [];
foreach ($this->rgb2hslAndhsbList() as $name => $values) {
$list[$name . ', rgb to hsb'] = [
0 => $values['rgb'][0],
1 => $values['rgb'][1],
2 => $values['rgb'][2],
3 => $values['valid'] ? $values['hsb'] : false
];
}
return $list;
}
/**
* Undocumented function
*
* @return array
*/
public function hsb2rgbColorProvider(): array
{
$list = [];
foreach ($this->rgb2hslAndhsbList() as $name => $values) {
$list[$name . ', hsb to rgb'] = [
0 => $values['hsb_from'][0] ?? $values['hsb'][0],
1 => $values['hsb_from'][1] ?? $values['hsb'][1],
2 => $values['hsb_from'][2] ?? $values['hsb'][2],
3 => $values['valid'] ? $values['hsb_rgb'] : false
];
}
return $list;
}
/**
* Undocumented function
*
* @return array
*/
public function rgb2hslColorProvider(): array
{
$list = [];
foreach ($this->rgb2hslAndhsbList() as $name => $values) {
$list[$name . ', rgb to hsl'] = [
0 => $values['rgb'][0],
1 => $values['rgb'][1],
2 => $values['rgb'][2],
3 => $values['valid'] ? $values['hsl'] : false
];
}
return $list;
}
/**
* Undocumented function
*
* @return array
*/
public function hsl2rgbColorProvider(): array
{
$list = [];
foreach ($this->rgb2hslAndhsbList() as $name => $values) {
$list[$name . ', hsl to rgb'] = [
0 => $values['hsl_from'][0] ?? $values['hsl'][0],
1 => $values['hsl_from'][1] ?? $values['hsl'][1],
2 => $values['hsl_from'][2] ?? $values['hsl'][2],
3 => $values['valid'] ? $values['rgb'] : false
];
}
return $list;
}
/**
* Undocumented function
* TODO: add cross convert check
*
* @covers ::rgb2hex
* @dataProvider rgb2hexColorProvider
* @testdox rgb2hex $input_r,$input_g,$input_b will be $expected [$_dataName]
*
* @param int $input_r
* @param int $input_g
* @param int $input_b
* @param string|bool $expected
* @return void
*/
public function testRgb2hex(int $input_r, int $input_g, int $input_b, $expected_hash, $expected)
{
// with #
$this->assertEquals(
$expected_hash,
\CoreLibs\Convert\Colors::rgb2hex($input_r, $input_g, $input_b)
);
// without #
$this->assertEquals(
$expected,
\CoreLibs\Convert\Colors::rgb2hex($input_r, $input_g, $input_b, false)
);
// cross convert must match
// $rgb = \CoreLibs\Convert\Colors::hex2rgb($expected_hash);
// if ($rgb === false) {
// $rgb = [
// 'r' => $input_r,
// 'g' => $input_g,
// 'b' => $input_b,
// ];
// }
// $this->assertEquals(
// $expected_hash,
// \CoreLibs\Convert\Colors::rgb2hex($rgb['r'], $rgb['g'], $rgb['b'])
// );
}
/**
* Undocumented function
*
* @covers ::hex2rgb
* @dataProvider hex2rgbColorProvider
* @testdox hex2rgb $input will be $expected, $expected_str str[,], $expected_str_sep str[$separator] [$_dataName]
*
* @param string $input
* @param array|bool $expected
* @param string|bool $expected_str
* @param string $separator
* @param string|bool $expected_str_sep
* @return void
*/
public function testHex2rgb(
string $input,
$expected,
$expected_str,
string $separator,
$expected_str_sep
): void {
$this->assertEquals(
$expected,
\CoreLibs\Convert\Colors::hex2rgb($input)
);
$this->assertEquals(
$expected_str,
\CoreLibs\Convert\Colors::hex2rgb($input, true)
);
$this->assertEquals(
$expected_str_sep,
\CoreLibs\Convert\Colors::hex2rgb($input, true, $separator)
);
}
/**
* Undocumented function
*
* @covers ::rgb2hsb
* @dataProvider rgb2hsbColorProvider
* @testdox rgb2hsb $input_r,$input_g,$input_b will be $expected [$_dataName]
*
* @param integer $input_r
* @param integer $input_g
* @param integer $input_b
* @param array|bool $expected
* @return void
*/
public function testRgb2hsb(int $input_r, int $input_g, int $input_b, $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Convert\Colors::rgb2hsb($input_r, $input_g, $input_b)
);
}
/**
* Undocumented function
*
* @covers ::hsb2rgb
* @dataProvider hsb2rgbColorProvider
* @testdox hsb2rgb $input_h,$input_s,$input_b will be $expected [$_dataName]
*
* @param float $input_h
* @param float $input_s
* @param float $input_b
* @param array|bool $expected
* @return void
*/
public function testHsb2rgb(float $input_h, float $input_s, float $input_b, $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Convert\Colors::hsb2rgb($input_h, $input_s, $input_b)
);
}
/**
* Undocumented function
*
* @covers ::rgb2hsl
* @dataProvider rgb2hslColorProvider
* @testdox rgb2hsl $input_r,$input_g,$input_b will be $expected [$_dataName]
*
* @param integer $input_r
* @param integer $input_g
* @param integer $input_b
* @param array|bool $expected
* @return void
*/
public function testRgb2hsl(int $input_r, int $input_g, int $input_b, $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Convert\Colors::rgb2hsl($input_r, $input_g, $input_b)
);
}
/**
* Undocumented function
*
* @covers ::hsl2rgb
* @dataProvider hsl2rgbColorProvider
* @testdox hsl2rgb $input_h,$input_s,$input_l will be $expected [$_dataName]
*
* @param integer|float $input_h
* @param integer $input_s
* @param integer $input_l
* @param array|bool $expected
* @return void
*/
public function testHsl2rgb($input_h, float $input_s, float $input_l, $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Convert\Colors::hsl2rgb($input_h, $input_s, $input_l)
);
}
/**
* edge case check hsl/hsb and hue 360 (= 0)
*
* @covers ::hsl2rgb
* @covers ::hsb2rgb
* @testdox hsl2rgb/hsb2rgb hue 360 valid check
*
* @return void
*/
public function testHslHsb360hue(): void
{
$this->assertNotFalse(
\CoreLibs\Convert\Colors::hsl2rgb(360.0, 90.5, 41.2),
'HSL to RGB with 360 hue'
);
$this->assertNotFalse(
\CoreLibs\Convert\Colors::hsb2rgb(360, 95, 78.0),
'HSB to RGB with 360 hue'
);
}
}
// __END__

View File

@@ -0,0 +1,102 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Test class for Convert\Encoding
* @coversDefaultClass \CoreLibs\Convert\Encoding
* @testdox \CoreLibs\Convert\Encoding method tests
*/
final class CoreLibsConvertEncodingTest extends TestCase
{
/**
* Undocumented function
*
* @return array
*/
public function convertEncodingProvider(): array
{
return [
// 0: original string
// 1: target encoding
// 2: optional source encoding
// 3: auto check (not used)
// 4: expected string
// 5: expected string encoding
'simple from UTF-8 to SJIS' => [
'input string',
'SJIS',
null,
null,
'input string',
'SJIS'
],
'kanji from UTF-8 to SJIS' => [
'日本語',
'SJIS',
null,
null,
'日本語',
'SJIS'
],
'kanji from UTF-8 to SJIS with source' => [
'日本語',
'SJIS',
'UTF-8',
null,
'日本語',
'SJIS'
],
];
}
/**
* Undocumented function
*
* @covers ::convertEncoding
* @dataProvider convertEncodingProvider
* @testdox convert encoding $target_encoding, source: $source_encoding, auto: $auto_check [$_dataName]
*
* @param string $input
* @param string $target_encoding
* @param string $source_encoding
* @param bool $auto_check
* @param string $expected
* @param string $expected_encoding
* @return void
*/
public function testConvertEncoding(
string $input,
string $target_encoding,
?string $source_encoding,
?bool $auto_check,
string $expected,
string $expected_encoding
): void {
if ($source_encoding === null and $auto_check === null) {
$string = \CoreLibs\Convert\Encoding::convertEncoding($input, $target_encoding);
} elseif ($auto_check === null) {
$string = \CoreLibs\Convert\Encoding::convertEncoding($input, $target_encoding, $source_encoding);
} else {
$string = \CoreLibs\Convert\Encoding::convertEncoding(
$input,
$target_encoding,
$source_encoding,
$auto_check
);
}
// because we can't store encoding in here anyway
$target = mb_convert_encoding($expected, $expected_encoding, 'UTF-8');
// print "IN: $input, $target_encoding\n";
$this->assertEquals(
$target,
$string
);
}
}
// __END__

View File

@@ -0,0 +1,188 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Test class for Convert\Html
* @coversDefaultClass \CoreLibs\Convert\Html
* @testdox \CoreLibs\Convert\Html method tests
*/
final class CoreLibsConvertHtmlTest extends TestCase
{
/**
* Undocumented function
*
* @return array
*/
public function htmlentProvider(): array
{
return [
'no conversion' => [
0 => 'I am some string',
1 => 'I am some string',
],
'conversion' => [
0 => 'I have special <> inside',
1 => 'I have special &lt;&gt; inside',
],
'skip number' => [
0 => 1234,
1 => 1234,
],
'utf8' => [
0 => '日本語 <>',
1 => '日本語 &lt;&gt;'
]
];
}
/**
* Undocumented function
*
* @return array
*/
public function removeLBProvider(): array
{
return [
'nothing replaced, default' => [
0 => 'I am some string',
1 => null,
2 => 'I am some string',
],
'string with \n replace -' => [
0 => "I am\nsome string",
1 => '-',
2 => 'I am-some string',
],
'string with \r replace _' => [
0 => "I am\rsome string",
1 => '_',
2 => 'I am_some string',
],
'string with \n\r, default' => [
0 => "I am\n\rsome string",
1 => null,
2 => 'I am some string',
],
'string with \n\r replae ##BR##' => [
0 => "I am\n\rsome string",
1 => '##BR##',
2 => 'I am##BR##some string',
]
];
}
/**
* Undocumented function
*
* @return array
*/
public function checkedProvider(): array
{
return [
'haystack is a string and matching selected' => [
0 => 'string',
1 => 'string',
2 => \CoreLibs\Convert\Html::SELECTED,
3 => 'selected'
],
'haystack is a string and matching checked' => [
0 => 'string',
1 => 'string',
2 => \CoreLibs\Convert\Html::CHECKED,
3 => 'checked'
],
'haystack is a string and not matching' => [
0 => 'string',
1 => 'not matching',
2 => \CoreLibs\Convert\Html::CHECKED,
3 => null
],
'haystack is array and matching' => [
0 => ['a', 'b', 'c'],
1 => 'a',
2 => \CoreLibs\Convert\Html::SELECTED,
3 => 'selected'
],
'haystack is array and not matching' => [
0 => ['a', 'b', 'c'],
1 => 'not matching',
2 => \CoreLibs\Convert\Html::SELECTED,
3 => null
],
];
}
/**
* Undocumented function
*
* @covers ::htmlent
* @dataProvider htmlentProvider
* @testdox htmlent $input will be $expected [$_dataName]
*
* @param mixed $input
* @param mixed $expected
* @return void
*/
public function testHtmlent($input, $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Convert\Html::htmlent($input)
);
}
/**
* Undocumented function
*
* @covers ::removeLB
* @dataProvider removeLBProvider
* @testdox removeLB $input with replace $replace will be $expected [$_dataName]
*
* @param string $input
* @param string|null $replace
* @param string $expected
* @return void
*/
public function testRemoveLB(string $input, ?string $replace, string $expected): void
{
if ($replace !== null) {
$this->assertEquals(
$expected,
\CoreLibs\Convert\Html::removeLB($input, $replace)
);
} else {
$this->assertEquals(
$expected,
\CoreLibs\Convert\Html::removeLB($input)
);
}
}
/**
* Undocumented function
*
* @covers ::checked
* @dataProvider checkedProvider
* @testdox checked find $needle in $haystack and return $type will be $expected [$_dataName]
*
* @param array<mixed>|string $haystack
* @param string $needle
* @param integer $type
* @param string|null $expected
* @return void
*/
public function testChecked($haystack, string $needle, int $type, ?string $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Convert\Html::checked($haystack, $needle, $type)
);
}
}
// __END__

View File

@@ -0,0 +1,166 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Test class for Check\Json
* @coversDefaultClass \CoreLibs\Convert\Json
* @testdox \CoreLibs\Convert\Json method tests
*/
final class CoreLibsConvertJsonTest extends TestCase
{
/**
* test list for json convert tests
*
* @return array
*/
public function jsonProvider(): array
{
return [
'valid json' => [
'{"m":2,"f":"sub_2"}',
false,
[
'm' => 2,
'f' => 'sub_2'
]
],
'empty json' => [
'',
false,
[]
],
'invalid json override' => [
'not valid',
true,
[
'not valid'
]
],
'invalid json' => [
'not valid',
false,
[]
],
'null json' => [
null,
false,
[]
]
];
}
/**
* json error list
*
* @return array JSON error list
*/
public function jsonErrorProvider(): array
{
return [
'no error' => [
'{}',
JSON_ERROR_NONE, ''
],
'depth error' => [
'[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[['
. '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[['
. '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[['
. '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[['
. '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[['
. '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[['
. '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[['
. '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[['
. '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'
. ']]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'
. ']]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'
. ']]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'
. ']]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'
. ']]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'
. ']]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'
. ']]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'
. ']]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'
. ']]]]',
JSON_ERROR_DEPTH, 'Maximum stack depth exceeded'
],
// 'state mismatch error' => [
// '{foo:}',
// JSON_ERROR_STATE_MISMATCH, 'Underflow or the modes mismatch'
// ],
// 'ctrl char error' => [
// ' {"data":"data","data":"data","data":"data","data":"data"}',
// JSON_ERROR_CTRL_CHAR, 'Unexpected control character found'
// ],
'syntax error' => [
'not valid',
JSON_ERROR_SYNTAX, 'Syntax error, malformed JSON'
],
// 'utf8 error' => [
// '{"invalid":"\xB1\x31"}',
// JSON_ERROR_UTF8, 'Malformed UTF-8 characters, possibly incorrectly encoded'
// ],
// 'invalid property' => [
// '{"\u0000":"abc"}',
// JSON_ERROR_INVALID_PROPERTY_NAME, 'A key starting with \u0000 character was in the string'
// ],
// 'utf-16 error' => [
// '',
// JSON_ERROR_UTF16, 'Single unpaired UTF-16 surrogate in unicode escape'
// ],
// 'unknown error' => [
// '',
// -999999, 'Unknown error'
// ]
];
}
/**
* test json convert states
*
* @covers ::jsonConvertToArray
* @dataProvider jsonProvider
* @testdox jsonConvertToArray $input (Override: $flag) will be $expected [$_dataName]
*
* @param string|null $input
* @param bool $flag
* @param array $expected
* @return void
*/
public function testJsonConvertToArray(?string $input, bool $flag, array $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Convert\Json::jsonConvertToArray($input, $flag)
);
}
/**
* test json error states
*
* @covers ::jsonGetLastError
* @dataProvider jsonErrorProvider
* @testdox jsonGetLastError $input will be $expected_i/$expected_s [$_dataName]
*
* @param string|null $input
* @param string $expected
* @return void
*/
public function testJsonGetLastError(?string $input, int $expected_i, string $expected_s): void
{
\CoreLibs\Convert\Json::jsonConvertToArray($input);
$this->assertEquals(
$expected_i,
\CoreLibs\Convert\Json::jsonGetLastError()
);
$this->assertEquals(
$expected_s,
\CoreLibs\Convert\Json::jsonGetLastError(true)
);
}
}
// __END__

View File

@@ -0,0 +1,118 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Undocumented class
* @coversDefaultClass \CoreLibs\Convert\Math
* @testdox \CoreLibs\Convert\Math method tests
*/
final class CoreLibsConvertMathTest extends TestCase
{
/**
* Undocumented function
*
* @return array<mixed>
*/
public function fceilProvider(): array
{
return [
'5.5 must be 6' => [5.5, 6],
'5.1234567890 with 5 must be 6' => [5.1234567890, 6],
'6 must be 6' => [6, 6]
];
}
/**
* Undocumented function
*
* @covers ::fceil
* @dataProvider fceilProvider
* @testdox fceil: Input $input must be $expected
*
* @param float $input
* @param int $expected
* @return void
*/
public function testMathFceilValue(float $input, int $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Convert\Math::fceil($input)
);
}
/**
* Undocumented function
*
* @return array<mixed>
*/
public function floorProvider(): array
{
return [
'5123456 with -3 must be 5123000' => [5123456, -3, 5123000],
'5123456 with -10 must be 5000000' => [5123456, -10, 5000000]
];
}
/**
* Undocumented function
*
* @covers ::floorp
* @dataProvider floorProvider
* @testdox floor: Input $input with cutoff $cutoff must be $expected
*
* @param int $input
* @param int $cutoff
* @param int $expected
* @return void
*/
public function testMathFloorValue(int $input, int $cutoff, int $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Convert\Math::floorp($input, $cutoff)
);
}
/**
* Undocumented function
*
* @return array<mixed>
*/
public function initNumericProvider(): array
{
return [
'5 must be 5' => [5, 5, 'int'],
'5.123 must be 5.123' => [5.123, 5.123, 'float'],
"'5' must be 5" => ['5', 5, 'string'],
"'5.123' must be 5.123" => ['5.123', 5.123, 'string'],
];
}
/**
* Undocumented function
*
* @covers ::initNumeric
* @dataProvider initNumericProvider
* @testdox initNumeric: Input $info $input must match $expected [$_dataName]
*
* @param int|float|string $input
* @param float $expected
* @param string $info
* @return void
*/
public function testMathInitNumericValue($input, float $expected, string $info): void
{
$this->assertEquals(
$expected,
\CoreLibs\Convert\Math::initNumeric($input)
);
}
}
// __END__

View File

@@ -0,0 +1,60 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Test class for Convert\MimeAppName
* @coversDefaultClass \CoreLibs\Convert\MimeAppName
* @testdox \CoreLibs\Convert\MimeAppName method tests
*/
final class CoreLibsConvertMimeAppNameTest extends TestCase
{
public function mimeProvider(): array
{
return [
'find matching app' => [
0 => 'foo/bar',
1 => 'FooBar Application',
2 => 'FooBar Application',
],
'try to set empty mime type' => [
0 => '',
1 => 'Some app',
2 => 'Other file'
],
'try to set empty app name' => [
0 => 'some/app',
1 => '',
2 => 'Other file'
],
];
}
/**
* Undocumented function
*
* @covers ::mimeGetAppName
* @covers ::mimeSetAppName
* @dataProvider mimeProvider
* @testdox mimeSetAppName set $mime with $app and will be $expected [$_dataName]
*
* @param string $mime
* @param string $app
* @return void
*/
public function testMimeSetAppName(string $mime, string $app, string $expected): void
{
\CoreLibs\Convert\MimeAppName::mimeSetAppName($mime, $app);
$this->assertEquals(
$expected,
\CoreLibs\Convert\MimeAppName::mimeGetAppName($mime)
);
}
}
// __END__

View File

@@ -0,0 +1,101 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Test class for Convert\MimeEncode
* @coversDefaultClass \CoreLibs\Convert\MimeEncode
* @testdox \CoreLibs\Convert\MimeEncode method tests
*/
final class CoreLibsConvertMimeEncodeTest extends TestCase
{
/**
* Undocumented function
*
* @return array
*/
public function mbMimeEncodeProvider(): array
{
return [
// 0: input string
// 1: encoding
// 2: expected
'standard UTF-8' => [
'Test string',
'UTF-8',
'Test string'
],
'long text UTF-8' => [
'The quick brown fox jumps over the lazy sheep that sleeps in the ravine '
. 'and has no idea what is going on here',
'UTF-8',
'The quick brown fox jumps over the lazy sheep that sleeps in the ravine '
. 'and has no idea what is going on here'
],
'standard with special chars UTF-8' => [
'This is ümläßtと漢字もカタカナ!^$%&',
'UTF-8',
'This is =?UTF-8?B?w7xtbMOkw59044Go5ryi5a2X44KC44Kr44K/44Kr44OK77yBIV4k?='
. "\r\n"
. ' =?UTF-8?B?JQ==?=&'
],
'35 chars and space at the end UTF-8' => [
'12345678901234567890123456789012345 '
. 'is there a space?',
'UTF-8',
'12345678901234567890123456789012345 '
. 'is there a =?UTF-8?B?c3BhY2U/?='
],
'36 chars and space at the end UTF-8' => [
'123456789012345678901234567890123456 '
. 'is there a space?',
'UTF-8',
'123456789012345678901234567890123456 '
. 'is there a =?UTF-8?B?c3BhY2U/?='
],
'36 kanji and space UTF-8' => [
'カタカナカタカナかなカタカナカタカナかなカタカナカタカナかなカタカナカタ '
. 'is there a space?',
'UTF-8',
"=?UTF-8?B?44Kr44K/44Kr44OK44Kr44K/44Kr44OK44GL44Gq44Kr44K/44Kr44OK44Kr?=\r\n"
. " =?UTF-8?B?44K/44Kr44OK?=\r\n"
. " =?UTF-8?B?44GL44Gq44Kr44K/44Kr44OK44Kr44K/44Kr44OK44GL44Gq44Kr44K/44Kr?=\r\n"
. " =?UTF-8?B?44OK44Kr44K/?= is there a =?UTF-8?B?c3BhY2U/?="
]
];
}
/**
* mb mime header encoding test
*
* @covers ::__mbMimeEncode
* @dataProvider mbMimeEncodeProvider
* @testdox mb encoding target $encoding [$_dataName]
*
* @return void
*/
public function testUuMbMimeEncode(string $input, string $encoding, string $expected): void
{
// encode string first
$encoded = \CoreLibs\Convert\MimeEncode::__mbMimeEncode($input, $encoding);
// print "MIME: -" . $encoded . "-\n";
$this->assertEquals(
$expected,
$encoded
);
$decoded = mb_decode_mimeheader($encoded);
// print "INPUT : " . $input . "\n";
// print "DECODED: " . $decoded . "\n";
// back compare decoded
$this->assertEquals(
$input,
$decoded
);
}
}
// __END__

View File

@@ -0,0 +1,652 @@
<?php // phpcs:disable Generic.Files.LineLength
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
use CoreLibs\Convert\SetVarTypeNull;
/**
* Test class for Convert\Strings
* @coversDefaultClass \CoreLibs\Convert\SetVarTypeNull
* @testdox \CoreLibs\Convert\SetVarTypeNull method tests
*/
final class CoreLibsConvertSetVarTypeNullTest extends TestCase
{
/**
* Undocumented function
*
* @return array
*/
public function varSetTypeStringProvider(): array
{
// 0: input
// 1: default (null default)
// 2: expected
return [
'empty string' => [
'',
null,
''
],
'filled string' => [
'string',
null,
'string'
],
'valid string, override set' => [
'string',
'override',
'string'
],
'int, no override' => [
1,
null,
null
],
'int, override set' => [
1,
'not int',
'not int'
]
];
}
/**
* Undocumented function
* @covers ::setStr
* @dataProvider varSetTypeStringProvider
* @testdox setStr $input with override $default will be $expected [$_dataName]
*
* @param mixed $input
* @param string|null $default
* @param string|null $expected
* @return void
*/
public function testSetString(mixed $input, ?string $default, ?string $expected): void
{
$set_var = SetVarTypeNull::setStr($input, $default);
if ($expected !== null) {
$this->assertIsString($set_var);
} else {
$this->assertNull($set_var);
}
$this->assertEquals(
$expected,
$set_var
);
}
/**
* Undocumented function
*
* @return array
*/
public function varMakeTypeStringProvider(): array
{
// 0: input
// 1: default (null default)
// 2: expected
return [
'empty string' => [
'',
null,
''
],
'filled string' => [
'string',
null,
'string'
],
'valid string, override set' => [
'string',
'override',
'string'
],
'int, no override' => [
1,
null,
'1'
],
'int, override set' => [
1,
'not int',
'1'
],
'float, no override' => [
1.5,
null,
'1.5'
],
// all the strange things here
'function, override set' => [
$foo = function () {
return '';
},
'function',
'function'
],
'function, no override' => [
$foo = function () {
return '';
},
null,
null
],
'hex value, override set' => [
0x55,
'hex',
'85'
]
];
}
/**
* Undocumented function
* @covers ::makeStr
* @dataProvider varMakeTypeStringProvider
* @testdox makeStr $input with override $default will be $expected [$_dataName]
*
* @param mixed $input
* @param string|null $default
* @param string|null $expected
* @return void
*/
public function testMakeString(mixed $input, ?string $default, ?string $expected): void
{
$set_var = SetVarTypeNull::makeStr($input, $default);
if ($expected !== null) {
$this->assertIsString($set_var);
} else {
$this->assertNull($set_var);
}
$this->assertEquals(
$expected,
$set_var
);
}
/**
* Undocumented function
*
* @return array
*/
public function varSetTypeIntProvider(): array
{
// 0: input
// 1: default (null default)
// 2: expected
return [
'int' => [
1,
null,
1
],
'int, override set' => [
1,
-1,
1
],
'string, no override' => [
'string',
null,
null
],
'string, override' => [
'string',
-1,
-1
],
'float' => [
1.5,
null,
null
]
];
}
/**
* Undocumented function
* @covers ::setInt
* @dataProvider varSetTypeIntProvider
* @testdox setInt $input with override $default will be $expected [$_dataName]
*
* @param mixed $input
* @param int|null $default
* @param int|null $expected
* @return void
*/
public function testSetInt(mixed $input, ?int $default, ?int $expected): void
{
$set_var = SetVarTypeNull::setInt($input, $default);
if ($expected !== null) {
$this->assertIsInt($set_var);
} else {
$this->assertNull($set_var);
}
$this->assertEquals(
$expected,
$set_var
);
}
/**
* Undocumented function
*
* @return array
*/
public function varMakeTypeIntProvider(): array
{
// 0: input
// 1: default (null default)
// 2: expected
return [
'int' => [
1,
null,
1
],
'int, override set' => [
1,
-1,
1
],
'string, no override' => [
'string',
null,
0
],
'string, override' => [
'string',
-1,
0
],
'float' => [
1.5,
null,
1
],
// all the strange things here
'function, override set' => [
$foo = function () {
return '';
},
-1,
-1
],
'function, no override ' => [
$foo = function () {
return '';
},
null,
null
],
'hex value, override set' => [
0x55,
-1,
85
],
];
}
/**
* Undocumented function
* @covers ::makeInt
* @dataProvider varMakeTypeIntProvider
* @testdox makeInt $input with override $default will be $expected [$_dataName]
*
* @param mixed $input
* @param int|null $default
* @param int|null $expected
* @return void
*/
public function testMakeInt(mixed $input, ?int $default, ?int $expected): void
{
$set_var = SetVarTypeNull::makeInt($input, $default);
if ($expected !== null) {
$this->assertIsInt($set_var);
} else {
$this->assertNull($set_var);
}
$this->assertEquals(
$expected,
$set_var
);
}
/**
* Undocumented function
*
* @return array
*/
public function varSetTypeFloatProvider(): array
{
// 0: input
// 1: default (null default)
// 2: expected
return [
'float' => [
1.5,
null,
1.5
],
'float, override set' => [
1.5,
-1.5,
1.5
],
'string, no override' => [
'string',
null,
null
],
'string, override' => [
'string',
1.5,
1.5
],
'int' => [
1,
null,
null
]
];
}
/**
* Undocumented function
* @covers ::setFloat
* @dataProvider varSetTypeFloatProvider
* @testdox setFloat $input with override $default will be $expected [$_dataName]
*
* @param mixed $input
* @param float|null $default
* @param float|null $expected
* @return void
*/
public function testSetFloat(mixed $input, ?float $default, ?float $expected): void
{
$set_var = SetVarTypeNull::setFloat($input, $default);
if ($expected !== null) {
$this->assertIsFloat($set_var);
} else {
$this->assertNull($set_var);
}
$this->assertEquals(
$expected,
$set_var
);
}
/**
* Undocumented function
*
* @return array
*/
public function varMakeTypeFloatProvider(): array
{
// 0: input
// 1: default (null default)
// 2: expected
return [
'float' => [
1.5,
null,
1.5
],
'float, override set' => [
1.5,
-1.5,
1.5
],
'string, no override' => [
'string',
null,
0.0
],
'string, override' => [
'string',
1.5,
0.0
],
'int' => [
1,
null,
1.0
],
// all the strange things here
'function, override set' => [
$foo = function () {
return '';
},
-1.0,
-1.0
],
// all the strange things here
'function, no override' => [
$foo = function () {
return '';
},
null,
null
],
'hex value, override set' => [
0x55,
-1,
85.0
],
];
}
/**
* Undocumented function
* @covers ::makeFloat
* @dataProvider varMakeTypeFloatProvider
* @testdox makeFloat $input with override $default will be $expected [$_dataName]
*
* @param mixed $input
* @param float|null $default
* @param float|null $expected
* @return void
*/
public function testMakeFloat(mixed $input, ?float $default, ?float $expected): void
{
$set_var = SetVarTypeNull::makeFloat($input, $default);
if ($expected !== null) {
$this->assertIsFloat($set_var);
} else {
$this->assertNull($set_var);
}
$this->assertEquals(
$expected,
$set_var
);
}
/**
* Undocumented function
*
* @return array
*/
public function varSetTypeArrayProvider(): array
{
// 0: input
// 1: default (null default)
// 2: expected
return [
'array, empty' => [
[],
null,
[]
],
'array, filled' => [
['array'],
null,
['array']
],
'string, no override' => [
'string',
null,
null
],
'string, override' => [
'string',
['string'],
['string']
]
];
}
/**
* Undocumented function
* @covers ::setArray
* @dataProvider varSetTypeArrayProvider
* @testdox setArray $input with override $default will be $expected [$_dataName]
*
* @param mixed $input
* @param array|null $default
* @param array|null $expected
* @return void
*/
public function testSetArray(mixed $input, ?array $default, ?array $expected): void
{
$set_var = SetVarTypeNull::setArray($input, $default);
if ($expected !== null) {
$this->assertIsArray($set_var);
} else {
$this->assertNull($set_var);
}
$this->assertEquals(
$expected,
$set_var
);
}
/**
* Undocumented function
*
* @return array
*/
public function varSetTypeBoolProvider(): array
{
// 0: input
// 1: default (null default)
// 2: expected
return [
'bool true' => [
true,
null,
true
],
'bool false' => [
false,
null,
false
],
'string, no override' => [
'string',
null,
null
],
'string, override' => [
'string',
true,
true
]
];
}
/**
* Undocumented function
* @covers ::setBool
* @dataProvider varSetTypeBoolProvider
* @testdox setBool $input with override $default will be $expected [$_dataName]
*
* @param mixed $input
* @param bool|null $default
* @param bool|null $expected
* @return void
*/
public function testSetBool(mixed $input, ?bool $default, ?bool $expected): void
{
$set_var = SetVarTypeNull::setBool($input, $default);
if ($expected !== null) {
$this->assertIsBool($set_var);
} else {
$this->assertNull($set_var);
}
$this->assertEquals(
$expected,
$set_var
);
}
/**
* Undocumented function
*
* @return array
*/
public function varMakeTypeBoolProvider(): array
{
// 0: input
// 2: expected
return [
'true' => [
true,
true
],
'false' => [
false,
false
],
'string on' => [
'on',
true
],
'string off' => [
'off',
false
],
'invalid string' => [
'sulzenbacher',
null,
],
'invalid string, override' => [
'sulzenbacher',
null,
],
'array to default' => [
[],
false
],
];
}
/**
* Undocumented function
* @covers ::setBool
* @dataProvider varMakeTypeBoolProvider
* @testdox setBool $input will be $expected [$_dataName]
*
* @param mixed $input
* @param bool|null $default
* @param bool|null $expected
* @return void
*/
public function testMakeBool(mixed $input, ?bool $expected): void
{
$set_var = SetVarTypeNull::makeBool($input);
if ($expected !== null) {
$this->assertIsBool($set_var);
} else {
$this->assertNull($set_var);
}
$this->assertEquals(
$expected,
$set_var
);
}
}
// __END__

View File

@@ -0,0 +1,632 @@
<?php // phpcs:disable Generic.Files.LineLength
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
use CoreLibs\Convert\SetVarType;
/**
* Test class for Convert\Strings
* @coversDefaultClass \CoreLibs\Convert\SetVarType
* @testdox \CoreLibs\Convert\SetVarType method tests
*/
final class CoreLibsConvertSetVarTypeTest extends TestCase
{
/**
* Undocumented function
*
* @return array
*/
public function varSetTypeStringProvider(): array
{
// 0: input
// 1: default (null default)
// 2: expected
return [
'empty string' => [
'',
null,
''
],
'filled string' => [
'string',
null,
'string'
],
'valid string, override set' => [
'string',
'override',
'string'
],
'int, no override' => [
1,
null,
''
],
'int, override set' => [
1,
'not int',
'not int'
]
];
}
/**
* Undocumented function
* @covers ::setStr
* @dataProvider varSetTypeStringProvider
* @testdox setStr $input with override $default will be $expected [$_dataName]
*
* @param mixed $input
* @param string|null $default
* @param string $expected
* @return void
*/
public function testSetString(mixed $input, ?string $default, string $expected): void
{
if ($default === null) {
$set_var = SetVarType::setStr($input);
} else {
$set_var = SetVarType::setStr($input, $default);
}
$this->assertIsString($set_var);
$this->assertEquals(
$expected,
$set_var
);
}
/**
* Undocumented function
*
* @return array
*/
public function varMakeTypeStringProvider(): array
{
// 0: input
// 1: default (null default)
// 2: expected
return [
'empty string' => [
'',
null,
''
],
'filled string' => [
'string',
null,
'string'
],
'valid string, override set' => [
'string',
'override',
'string'
],
'int, no override' => [
1,
null,
'1'
],
'int, override set' => [
1,
'not int',
'1'
],
// all the strange things here
'function, override set' => [
$foo = function () {
return '';
},
'function',
'function'
],
'hex value, override set' => [
0x55,
'hex',
'85'
]
];
}
/**
* Undocumented function
* @covers ::makeStr
* @dataProvider varMakeTypeStringProvider
* @testdox makeStr $input with override $default will be $expected [$_dataName]
*
* @param mixed $input
* @param string|null $default
* @param string $expected
* @return void
*/
public function testMakeString(mixed $input, ?string $default, string $expected): void
{
if ($default === null) {
$set_var = SetVarType::makeStr($input);
} else {
$set_var = SetVarType::makeStr($input, $default);
}
$this->assertIsString($set_var);
$this->assertEquals(
$expected,
$set_var
);
}
/**
* Undocumented function
*
* @return array
*/
public function varSetTypeIntProvider(): array
{
// 0: input
// 1: default (null default)
// 2: expected
return [
'int' => [
1,
null,
1
],
'int, override set' => [
1,
-1,
1
],
'string, no override' => [
'string',
null,
0
],
'string, override' => [
'string',
-1,
-1
],
'float' => [
1.5,
null,
0
]
];
}
/**
* Undocumented function
* @covers ::setInt
* @dataProvider varSetTypeIntProvider
* @testdox setInt $input with override $default will be $expected [$_dataName]
*
* @param mixed $input
* @param int|null $default
* @param int $expected
* @return void
*/
public function testSetInt(mixed $input, ?int $default, int $expected): void
{
if ($default === null) {
$set_var = SetVarType::setInt($input);
} else {
$set_var = SetVarType::setInt($input, $default);
}
$this->assertIsInt($set_var);
$this->assertEquals(
$expected,
$set_var
);
}
/**
* Undocumented function
*
* @return array
*/
public function varMakeTypeIntProvider(): array
{
// 0: input
// 1: default (null default)
// 2: expected
return [
'int' => [
1,
null,
1
],
'int, override set' => [
1,
-1,
1
],
'string, no override' => [
'string',
null,
0
],
'string, override' => [
'string',
-1,
0
],
'float' => [
1.5,
null,
1
],
// all the strange things here
'function, override set' => [
$foo = function () {
return '';
},
-1,
-1
],
'hex value, override set' => [
0x55,
-1,
85
],
];
}
/**
* Undocumented function
* @covers ::makeInt
* @dataProvider varMakeTypeIntProvider
* @testdox makeInt $input with override $default will be $expected [$_dataName]
*
* @param mixed $input
* @param int|null $default
* @param int $expected
* @return void
*/
public function testMakeInt(mixed $input, ?int $default, int $expected): void
{
if ($default === null) {
$set_var = SetVarType::makeInt($input);
} else {
$set_var = SetVarType::makeInt($input, $default);
}
$this->assertIsInt($set_var);
$this->assertEquals(
$expected,
$set_var
);
}
/**
* Undocumented function
*
* @return array
*/
public function varSetTypeFloatProvider(): array
{
// 0: input
// 1: default (null default)
// 2: expected
return [
'float' => [
1.5,
null,
1.5
],
'float, override set' => [
1.5,
-1.5,
1.5
],
'string, no override' => [
'string',
null,
0.0
],
'string, override' => [
'string',
1.5,
1.5
],
'int' => [
1,
null,
0.0
]
];
}
/**
* Undocumented function
* @covers ::setFloat
* @dataProvider varSetTypeFloatProvider
* @testdox setFloat $input with override $default will be $expected [$_dataName]
*
* @param mixed $input
* @param float|null $default
* @param float $expected
* @return void
*/
public function testSetFloat(mixed $input, ?float $default, float $expected): void
{
if ($default === null) {
$set_var = SetVarType::setFloat($input);
} else {
$set_var = SetVarType::setFloat($input, $default);
}
$this->assertIsFloat($set_var);
$this->assertEquals(
$expected,
$set_var
);
}
/**
* Undocumented function
*
* @return array
*/
public function varMakeTypeFloatProvider(): array
{
// 0: input
// 1: default (null default)
// 2: expected
return [
'float' => [
1.5,
null,
1.5
],
'float, override set' => [
1.5,
-1.5,
1.5
],
'string, no override' => [
'string',
null,
0.0
],
'string, override' => [
'string',
1.5,
0.0
],
'int' => [
1,
null,
1.0
],
// all the strange things here
'function, override set' => [
$foo = function () {
return '';
},
-1.0,
-1.0
],
'hex value, override set' => [
0x55,
-1,
85.0
],
];
}
/**
* Undocumented function
* @covers ::makeFloat
* @dataProvider varMakeTypeFloatProvider
* @testdox makeFloat $input with override $default will be $expected [$_dataName]
*
* @param mixed $input
* @param float|null $default
* @param float $expected
* @return void
*/
public function testMakeFloat(mixed $input, ?float $default, float $expected): void
{
if ($default === null) {
$set_var = SetVarType::makeFloat($input);
} else {
$set_var = SetVarType::makeFloat($input, $default);
}
$this->assertIsFloat($set_var);
$this->assertEquals(
$expected,
$set_var
);
}
/**
* Undocumented function
*
* @return array
*/
public function varSetTypeArrayProvider(): array
{
// 0: input
// 1: default (null default)
// 2: expected
return [
'array, empty' => [
[],
null,
[]
],
'array, filled' => [
['array'],
null,
['array']
],
'string, no override' => [
'string',
null,
[]
],
'string, override' => [
'string',
['string'],
['string']
]
];
}
/**
* Undocumented function
* @covers ::setArray
* @dataProvider varSetTypeArrayProvider
* @testdox setArray $input with override $default will be $expected [$_dataName]
*
* @param mixed $input
* @param array|null $default
* @param array $expected
* @return void
*/
public function testSetArray(mixed $input, ?array $default, array $expected): void
{
if ($default === null) {
$set_var = SetVarType::setArray($input);
} else {
$set_var = SetVarType::setArray($input, $default);
}
$this->assertIsArray($set_var);
$this->assertEquals(
$expected,
$set_var
);
}
/**
* Undocumented function
*
* @return array
*/
public function varSetTypeBoolProvider(): array
{
// 0: input
// 1: default (null default)
// 2: expected
return [
'bool true' => [
true,
null,
true
],
'bool false' => [
false,
null,
false
],
'string, no override' => [
'string',
null,
false
],
'string, override' => [
'string',
true,
true
]
];
}
/**
* Undocumented function
* @covers ::setBool
* @dataProvider varSetTypeBoolProvider
* @testdox setBool $input with override $default will be $expected [$_dataName]
*
* @param mixed $input
* @param bool|null $default
* @param bool $expected
* @return void
*/
public function testSetBool(mixed $input, ?bool $default, bool $expected): void
{
if ($default === null) {
$set_var = SetVarType::setBool($input);
} else {
$set_var = SetVarType::setBool($input, $default);
}
$this->assertIsBool($set_var);
$this->assertEquals(
$expected,
$set_var
);
}
/**
* Undocumented function
*
* @return array
*/
public function varMakeTypeBoolProvider(): array
{
// 0: input
// 2: expected
return [
'true' => [
true,
null,
true
],
'false' => [
false,
null,
false
],
'string on' => [
'on',
null,
true
],
'string off' => [
'off',
null,
false
],
'invalid string' => [
'sulzenbacher',
null,
false,
],
'invalid string, override' => [
'sulzenbacher',
true,
true,
],
'array to default' => [
[],
null,
false
],
];
}
/**
* Undocumented function
* @covers ::setBool
* @dataProvider varMakeTypeBoolProvider
* @testdox setBool $input will be $expected [$_dataName]
*
* @param mixed $input
* @param bool|null $default
* @param bool $expected
* @return void
*/
public function testMakeBool(mixed $input, ?bool $default, bool $expected): void
{
if ($default === null) {
$set_var = SetVarType::makeBool($input);
} else {
$set_var = SetVarType::makeBool($input, $default);
}
$this->assertIsBool($set_var);
$this->assertEquals(
$expected,
$set_var
);
}
}
// __END__

View File

@@ -0,0 +1,261 @@
<?php // phpcs:disable Generic.Files.LineLength
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Test class for Convert\Strings
* @coversDefaultClass \CoreLibs\Convert\Strings
* @testdox \CoreLibs\Convert\Strings method tests
*/
final class CoreLibsConvertStringsTest extends TestCase
{
/**
* Undocumented function
*
* @return array
*/
public function splitFormatStringProvider(): array
{
// 0: input
// 1: format
// 2: split characters as string, null for default
// 3: expected
return [
'all empty string' => [
'',
'',
null,
''
],
'empty input string' => [
'',
'2-2',
null,
''
],
'empty format string string' => [
'1234',
'',
null,
'1234'
],
'string format match' => [
'1234',
'2-2',
null,
'12-34'
],
'string format trailing match' => [
'1234',
'2-2-',
null,
'12-34'
],
'string format leading match' => [
'1234',
'-2-2',
null,
'12-34'
],
'string format double inside match' => [
'1234',
'2--2',
null,
'12--34',
],
'string format short first' => [
'1',
'2-2',
null,
'1'
],
'string format match first' => [
'12',
'2-2',
null,
'12'
],
'string format short second' => [
'123',
'2-2',
null,
'12-3'
],
'string format too long' => [
'1234567',
'2-2',
null,
'12-34-567'
],
'string format invalid format string' => [
'1234',
'2_2',
null,
'1234'
],
'different split character' => [
'1234',
'2_2',
'_',
'12_34'
],
'mixed split characters' => [
'123456',
'2-2_2',
'-_',
'12-34_56'
],
'length mixed' => [
'ABCD12345568ABC13',
'2-4_5-2#4',
'-_#',
'AB-CD12_34556-8A#BC13'
],
'split with split chars in string' => [
'12-34',
'2-2',
null,
'12--3-4'
],
'mutltibyte string' => [
'あいうえ',
'2-2',
null,
'あいうえ'
],
'mutltibyte split string' => [
'1234',
'-',
null,
'1234'
],
];
}
/**
* split format string
*
* @covers ::splitFormatString
* @dataProvider splitFormatStringProvider
* @testdox splitFormatString $input with format $format and splitters $split_characters will be $expected [$_dataName]
*
* @param string $input
* @param string $format
* @param string|null $split_characters
* @param string $expected
* @return void
*/
public function testSplitFormatString(
string $input,
string $format,
?string $split_characters,
string $expected
): void {
if ($split_characters === null) {
$output = \CoreLibs\Convert\Strings::splitFormatString(
$input,
$format
);
} else {
$output = \CoreLibs\Convert\Strings::splitFormatString(
$input,
$format,
$split_characters
);
}
$this->assertEquals(
$expected,
$output
);
}
/**
* Undocumented function
*
* @return array
*/
public function countSplitPartsProvider(): array
{
return [
'0 elements' => [
'',
null,
0
],
'1 element' => [
'1',
null,
1,
],
'2 elements, trailing' => [
'1-2-',
null,
2
],
'2 elements, leading' => [
'-1-2',
null,
2
],
'2 elements, midde double' => [
'1--2',
null,
2
],
'4 elements' => [
'1-2-3-4',
null,
4
],
'3 elemenst, other splitter' => [
'2-3_3',
'-_',
3
],
'illegal splitter' => [
'あsdf',
null,
0
]
];
}
/**
* count split parts
*
* @covers ::countSplitParts
* @dataProvider countSplitPartsProvider
* @testdox countSplitParts $input with splitters $split_characters will be $expected [$_dataName]
*
* @param string $input
* @param string|null $split_characters
* @param int $expected
* @return void
*/
public function testCountSplitParts(
string $input,
?string $split_characters,
int $expected
): void {
if ($split_characters === null) {
$output = \CoreLibs\Convert\Strings::countSplitParts(
$input
);
} else {
$output = \CoreLibs\Convert\Strings::countSplitParts(
$input,
$split_characters
);
}
$this->assertEquals(
$expected,
$output
);
}
}
// __END__

View File

@@ -0,0 +1,700 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Test class for Create\Email
* @coversDefaultClass \CoreLibs\Create\Email
* @testdox \CoreLibs\Create\Email method tests
*/
final class CoreLibsCreateEmailTest extends TestCase
{
private static $log;
/**
* start DB conneciton, setup DB, etc
*
* @return void
*/
public static function setUpBeforeClass(): void
{
self::$log = new \CoreLibs\Debug\Logging([
'log_folder' => DIRECTORY_SEPARATOR . 'tmp',
'file_id' => 'CoreLibs-Create-Email-Test',
'debug_all' => true,
'echo_all' => false,
'print_all' => true,
]);
}
/**
* Undocumented function
*
* @return array
*/
public function encodeEmailNameProvider(): array
{
// 0: email
// 1: name
// 2: encoding
// 3: kv_folding
// 4: expected
return [
'all empty' => [
'',
null,
null,
null,
''
],
'email only' => [
'test@test.com',
null,
null,
null,
'test@test.com'
],
'email and name' => [
'test@test.com',
'Test Name',
null,
null,
'"Test Name" <test@test.com>'
],
'name in mime encoded, default UTF-8' => [
'test@test.com',
'日本語',
null,
null,
'"=?UTF-8?B?5pel5pys6Kqe?=" <test@test.com>'
],
'name in mime encoded with half width Katakana, default UTF-8' => [
'test@test.com',
'日本語カタカナパ',
null,
null,
'"=?UTF-8?B?5pel5pys6Kqe7722776A7722776F776K776f?=" <test@test.com>'
],
'name in mime encoded with half width Katakana, folding on, default UTF-8' => [
'test@test.com',
'日本語カタカナパ',
'UTF-8',
true,
'"=?UTF-8?B?5pel5pys6Kqe44Kr44K/44Kr44OK44OR?=" <test@test.com>'
],
'name in mime encoded, UTF-8 parameter' => [
'test@test.com',
'日本語',
'UTF-8',
null,
'"=?UTF-8?B?5pel5pys6Kqe?=" <test@test.com>'
],
// does internal UTF-8 to ISO-2022-JP convert
'encoding in ISO-2022-JP' => [
'test@test.com',
'日本語',
'ISO-2022-JP',
null,
'"=?ISO-2022-JP?B?GyRCRnxLXDhsGyhC?=" <test@test.com>'
],
'encoding with half width Katakana in ISO-2022-JP' => [
'test@test.com',
'日本語カタカナパ',
'ISO-2022-JP',
null,
'"=?ISO-2022-JP?B?GyRCRnxLXDhsGyhCPz8/Pz8/?=" <test@test.com>'
],
'encoding with half width Katakana, folding on in ISO-2022-JP' => [
'test@test.com',
'日本語カタカナパ',
'ISO-2022-JP',
true,
// was ok php 8.1
// '"=?ISO-2022-JP?B?GyRCRnxLXDhsGyhCPz8/Pz8=?=" <test@test.com>'
// below ok php 8.1.12, 2022/12/9
'"=?ISO-2022-JP?B?GyRCRnxLXDhsGyhCPz8/Pz8/?=" <test@test.com>'
]
];
}
/**
* Undocumented function
*
* @dataProvider encodeEmailNameProvider
* @testdox encode email $email, name $name, encoding $encoding, folding $kv_folding will be $expected [$_dataName]
*
* @param string $email
* @param string|null $name
* @param string|null $encoding
* @param bool|null $kv_folding
* @param string $expected
* @return void
*/
public function testEncodeEmailName(
string $email,
?string $name,
?string $encoding,
?bool $kv_folding,
string $expected
): void {
if ($name === null && $encoding === null && $kv_folding === null) {
$encoded_email = \CoreLibs\Create\Email::encodeEmailName($email);
} elseif ($encoding === null && $kv_folding === null) {
$encoded_email = \CoreLibs\Create\Email::encodeEmailName($email, $name);
} elseif ($kv_folding === null) {
$encoded_email = \CoreLibs\Create\Email::encodeEmailName($email, $name, $encoding);
} else {
$encoded_email = \CoreLibs\Create\Email::encodeEmailName($email, $name, $encoding, $kv_folding);
}
$this->assertEquals(
$expected,
$encoded_email
);
}
public function sendEmailProvider(): array
{
// 0: subject
// 1: body
// 2: from email
// 3: from name ('')
// 4: array for to email
// 5: replace content ([]/null)
// 6: encoding (UTF-8/null)
// 7: kv_folding
// 8: return status
// 9: expected content
return [
'all empty, fail -1' => [
'subject' => '',
'body' => '',
'from_email' => '',
'from_name' => '',
'to_email' => [],
'replace' => null,
'encoding' => null,
'kv_folding' => null,
'expected_status' => -1,
'expected_content' => [],
],
'missing to entry, fail -2' => [
'subject' => 'SUBJECT',
'body' => 'BODY',
'from_email' => 'test@test.com',
'from_name' => '',
'to_email' => [],
'replace' => null,
'encoding' => null,
'kv_folding' => null,
'expected_status' => -2,
'expected_content' => [],
],
'bad encoding, fail -3' => [
'subject' => 'SUBJECT',
'body' => 'BODY',
'from_email' => 'test@test.com',
'from_name' => '',
'to_email' => ['to@test.com'],
'replace' => null,
'encoding' => 'IDONTEXISTENCODING',
'kv_folding' => null,
'expected_status' => -3,
'expected_content' => [],
],
'sending email 1' => [
'subject' => 'SUBJECT',
'body' => 'BODY',
'from_email' => 'test@test.com',
'from_name' => '',
'to_email' => [
'test@test.com'
],
'replace' => null,
'encoding' => null,
'kv_folding' => null,
'expected_status' => 2,
'expected_content' => [
[
'header' => [
'From' => 'test@test.com'
],
'to' => 'test@test.com',
'subject' => 'SUBJECT',
'body' => 'BODY',
]
],
],
'sending email 1, encoded' => [
'subject' => 'SUBJECT 日本語',
'body' => 'BODY 日本語',
'from_email' => 'test@test.com',
'from_name' => '',
'to_email' => [
'test@test.com'
],
'replace' => null,
'encoding' => null,
'kv_folding' => null,
'expected_status' => 2,
'expected_content' => [
[
'header' => [
'From' => 'test@test.com'
],
'to' => 'test@test.com',
'subject' => 'SUBJECT =?UTF-8?B?5pel5pys6Kqe?=',
'body' => 'BODY 日本語',
]
],
],
'sending email 1, encoded, with half width katakanata' => [
'subject' => 'SUBJECT 日本語カタカナパ',
'body' => 'BODY 日本語',
'from_email' => 'test@test.com',
'from_name' => '',
'to_email' => [
'test@test.com'
],
'replace' => null,
'encoding' => 'UTF-8',
'kv_folding' => null,
'expected_status' => 2,
'expected_content' => [
[
'header' => [
'From' => 'test@test.com'
],
'to' => 'test@test.com',
'subject' => 'SUBJECT =?UTF-8?B?5pel5pys6Kqe7722776A7722776F776K776f?=',
'body' => 'BODY 日本語',
]
],
],
'sending email 1, encoded, with half width katakanata, folding on' => [
'subject' => 'SUBJECT 日本語カタカナパ',
'body' => 'BODY 日本語',
'from_email' => 'test@test.com',
'from_name' => '',
'to_email' => [
'test@test.com'
],
'replace' => null,
'encoding' => 'UTF-8',
'kv_folding' => true,
'expected_status' => 2,
'expected_content' => [
[
'header' => [
'From' => 'test@test.com'
],
'to' => 'test@test.com',
'subject' => 'SUBJECT =?UTF-8?B?5pel5pys6Kqe44Kr44K/44Kr44OK44OR?=',
'body' => 'BODY 日本語',
]
],
],
'sending email 1, encoded subject ISO-2022-JP' => [
'subject' => 'SUBJECT 日本語',
'body' => 'BODY 日本語',
'from_email' => 'test@test.com',
'from_name' => '',
'to_email' => [
'test@test.com'
],
'replace' => null,
'encoding' => 'ISO-2022-JP',
'kv_folding' => null,
'expected_status' => 2,
'expected_content' => [
[
'header' => [
'From' => 'test@test.com'
],
'to' => 'test@test.com',
'subject' => 'SUBJECT =?ISO-2022-JP?B?GyRCRnxLXDhsGyhC?=',
// body is stored as UTF-8 in log and here, so both must be translated
'body' => 'BODY 日本語',
]
],
],
'sending email 2' => [
'subject' => 'SUBJECT',
'body' => 'BODY',
'from_email' => 'test@test.com',
'from_name' => '',
'to_email' => [
'e1@test.com',
'e2@test.com'
],
'replace' => null,
'encoding' => null,
'kv_folding' => null,
'expected_status' => 2,
'expected_content' => [
[
'header' => [
'From' => 'test@test.com'
],
'to' => 'e1@test.com',
'subject' => 'SUBJECT',
'body' => 'BODY',
],
[
'header' => [
'From' => 'test@test.com'
],
'to' => 'e2@test.com',
'subject' => 'SUBJECT',
'body' => 'BODY',
]
],
],
'sending email 1: dynamic' => [
'subject' => 'SUBJECT {FOO}',
'body' => 'BODY {FOO} {VAR}',
'from_email' => 'test@test.com',
'from_name' => '',
'to_email' => [
'test@test.com'
],
'replace' => [
'FOO' => 'foo',
'VAR' => 'bar',
],
'encoding' => null,
'kv_folding' => null,
'expected_status' => 2,
'expected_content' => [
[
'header' => [
'From' => 'test@test.com'
],
'to' => 'test@test.com',
'subject' => 'SUBJECT foo',
'body' => 'BODY foo bar',
]
],
],
'sending email 1: dynamic encoded' => [
'subject' => 'SUBJECT 日本語 {FOO}',
'body' => 'BODY 日本語 {FOO} {VAR}',
'from_email' => 'test@test.com',
'from_name' => '',
'to_email' => [
'test@test.com'
],
'replace' => [
'FOO' => 'foo',
'VAR' => 'bar',
],
'encoding' => null,
'kv_folding' => null,
'expected_status' => 2,
'expected_content' => [
[
'header' => [
'From' => 'test@test.com'
],
'to' => 'test@test.com',
'subject' => 'SUBJECT =?UTF-8?B?5pel5pys6KqeIGZvbw==?=',
'body' => 'BODY 日本語 foo bar',
]
],
],
'sending email 1: dynamic, to override' => [
'subject' => 'SUBJECT {FOO}',
'body' => 'BODY {FOO} {VAR}',
'from_email' => 'test@test.com',
'from_name' => '',
'to_email' => [
[
'email' => 'test@test.com',
'replace' => [
'FOO' => 'foo to'
]
]
],
'replace' => [
'FOO' => 'foo',
'VAR' => 'bar',
],
'encoding' => null,
'kv_folding' => null,
'expected_status' => 2,
'expected_content' => [
[
'header' => [
'From' => 'test@test.com'
],
'to' => 'test@test.com',
'subject' => 'SUBJECT foo to',
'body' => 'BODY foo to bar',
]
],
],
'sending email 1: dynamic, to override encoded' => [
'subject' => 'SUBJECT 日本語 {FOO}',
'body' => 'BODY 日本語 {FOO} {VAR}',
'from_email' => 'test@test.com',
'from_name' => '',
'to_email' => [
[
'email' => 'test@test.com',
'replace' => [
'FOO' => 'foo to'
]
]
],
'replace' => [
'FOO' => 'foo',
'VAR' => 'bar',
],
'encoding' => null,
'kv_folding' => null,
'expected_status' => 2,
'expected_content' => [
[
'header' => [
'From' => 'test@test.com'
],
'to' => 'test@test.com',
'subject' => 'SUBJECT =?UTF-8?B?5pel5pys6KqeIGZvbyB0bw==?=',
'body' => 'BODY 日本語 foo to bar',
]
],
],
'sending email 3: dynamic, to mixed override' => [
'subject' => 'SUBJECT {FOO}',
'body' => 'BODY {FOO} {VAR}',
'from_email' => 'test@test.com',
'from_name' => '',
'to_email' => [
[
'email' => 't1@test.com',
'replace' => [
'FOO' => 'foo to 1'
]
],
[
'email' => 't2@test.com',
'replace' => [
'FOO' => 'foo to 2'
]
],
[
'email' => 't3@test.com',
],
],
'replace' => [
'FOO' => 'foo',
'VAR' => 'bar',
],
'encoding' => null,
'kv_folding' => null,
'expected_status' => 2,
'expected_content' => [
[
'header' => [
'From' => 'test@test.com'
],
'to' => 't1@test.com',
'subject' => 'SUBJECT foo to 1',
'body' => 'BODY foo to 1 bar',
],
[
'header' => [
'From' => 'test@test.com'
],
'to' => 't2@test.com',
'subject' => 'SUBJECT foo to 2',
'body' => 'BODY foo to 2 bar',
],
[
'header' => [
'From' => 'test@test.com'
],
'to' => 't3@test.com',
'subject' => 'SUBJECT foo',
'body' => 'BODY foo bar',
],
],
],
'sending email 3: dynamic, to mixed override encoded' => [
'subject' => 'SUBJECT 日本語 {FOO}',
'body' => 'BODY 日本語 {FOO} {VAR}',
'from_email' => 'test@test.com',
'from_name' => '',
'to_email' => [
[
'email' => 't1@test.com',
'replace' => [
'FOO' => 'foo to 1'
]
],
[
'email' => 't2@test.com',
'replace' => [
'FOO' => 'foo to 2'
]
],
[
'email' => 't3@test.com',
],
],
'replace' => [
'FOO' => 'foo',
'VAR' => 'bar',
],
'encoding' => null,
'kv_folding' => null,
'expected_status' => 2,
'expected_content' => [
[
'header' => [
'From' => 'test@test.com'
],
'to' => 't1@test.com',
'subject' => 'SUBJECT =?UTF-8?B?5pel5pys6KqeIGZvbyB0byAx?=',
'body' => 'BODY 日本語 foo to 1 bar',
],
[
'header' => [
'From' => 'test@test.com'
],
'to' => 't2@test.com',
'subject' => 'SUBJECT =?UTF-8?B?5pel5pys6KqeIGZvbyB0byAy?=',
'body' => 'BODY 日本語 foo to 2 bar',
],
[
'header' => [
'From' => 'test@test.com'
],
'to' => 't3@test.com',
'subject' => 'SUBJECT =?UTF-8?B?5pel5pys6KqeIGZvbw==?=',
'body' => 'BODY 日本語 foo bar',
],
],
],
];
}
/**
* Undocumented function
*
* @dataProvider sendEmailProvider
* @testdox email sending with expected status $expected_status [$_dataName]
*
* @param string $subject
* @param string $body
* @param string $from_email
* @param string $from_name
* @param array $to_email
* @param array|null $replace
* @param string|null $encoding
* @param bool|null $kv_folding
* @param int $expected_status
* @param array $expected_content
* @return void
*/
public function testSendEmail(
string $subject,
string $body,
string $from_email,
string $from_name,
array $to_email,
?array $replace,
?string $encoding,
?bool $kv_folding,
int $expected_status,
array $expected_content
): void {
if ($replace === null) {
$replace = [];
}
if ($encoding === null) {
$encoding = 'UTF-8';
}
if ($kv_folding === null) {
$kv_folding = false;
}
// force new set for each run
self::$log->setLogUniqueId(true);
// set on of unique log id
self::$log->setLogPer('run', true);
// init logger
$status = \CoreLibs\Create\Email::sendEmail(
$subject,
$body,
$from_email,
$from_name,
$to_email,
$replace,
$encoding,
$kv_folding,
true,
self::$log
);
$this->assertEquals(
$expected_status,
$status,
'Assert sending status'
);
// 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());
if ($file !== false) {
// extract SEND EMAIL JSON line
$found = preg_match_all("/^.* <SEND EMAIL JSON> - (.*)$/m", $file, $matches);
// print "Found: $found | EMAIL: " . print_r($matches, true) . "\n";
if (!empty($matches[1])) {
foreach ($matches[1] as $pos => $email_json) {
$email = \CoreLibs\Convert\Json::jsonConvertToArray($email_json);
// print "EMAIL: " . print_r($email, true) . "\n";
$this->assertEquals(
$expected_content[$pos]['header']['From'] ?? 'MISSING FROM',
$email['header']['From'] ?? '',
'Email check: assert header from'
);
$this->assertEquals(
'text/plain; charset=' . $encoding ?? 'UTF-8',
$email['header']['Content-type'] ?? '',
'Email check: assert header content type'
);
$this->assertEquals(
'1.0',
$email['header']['MIME-Version'] ?? '',
'Email check: assert header mime version'
);
$this->assertEquals(
$expected_content[$pos]['to'] ?? 'MISSING TO',
$email['to'] ?? '',
'Email check: assert to'
);
$this->assertEquals(
$expected_content[$pos]['subject'] ?? 'MISSING SUBJECT',
$email['subject'] ?? '',
'Email check: assert subject'
);
// body must be translated back to encoding if encoding is not UTF-8
$this->assertEquals(
$encoding != 'UTF-8' ?
mb_convert_encoding($expected_content[$pos]['body'] ?? '', $encoding, 'UTF-8') :
$expected_content[$pos]['body'] ?? 'MISSING BODY',
$email['encoding'] != 'UTF-8' ?
mb_convert_encoding($email['body'] ?? '', $email['encoding'], 'UTF-8') :
$email['body'] ?? '',
'Email check: assert body'
);
}
}
}
}
}
}
// __END__

View File

@@ -0,0 +1,212 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Test class for Create\Hash
* @coversDefaultClass \CoreLibs\Create\Hash
* @testdox \CoreLibs\Create\Hash method tests
*/
final class CoreLibsCreateHashTest extends TestCase
{
/**
* Undocumented function
*
* @return array
*/
public function hashData(): array
{
return [
'any string' => [
'text' => 'Some String Text',
'crc32b_reverse' => 'c5c21d91', // crc32b (in revere)
'sha1Short' => '4d2bc9ba0', // sha1Short
// via hash
'crc32b' => '911dc2c5', // hash: crc32b
'adler32' => '31aa05f1', // hash: alder32
'fnv132' => '9df444f9', // hash: fnv132
'fnv1a32' => '2c5f91b9', // hash: fnv1a32
'joaat' => '50dab846', // hash: joaat
]
];
}
/**
* Undocumented function
*
* @return array
*/
public function crc32bProvider(): array
{
$list = [];
foreach ($this->hashData() as $name => $values) {
$list[$name . ' to crc32b reverse'] = [
0 => $values['text'],
1 => $values['crc32b_reverse'],
];
}
return $list;
}
/**
* Undocumented function
*
* @return array
*/
public function sha1ShortProvider(): array
{
$list = [];
foreach ($this->hashData() as $name => $values) {
$list[$name . ' to sha1 short'] = [
0 => $values['text'],
1 => $values['crc32b_reverse'],
2 => $values['sha1Short'],
];
}
return $list;
}
/**
* test all hash functions
* NOTE: if we add new hash functions in the __hash method
* they need to be added here too (and in the master hashData array too)
*
* @return array
*/
public function hashProvider(): array
{
$list = [];
foreach ($this->hashData() as $name => $values) {
foreach ([null, 'crc32b', 'adler32', 'fnv132', 'fnv1a32', 'joaat'] as $_hash_type) {
// default value test
if ($_hash_type === null) {
$hash_type = \CoreLibs\Create\Hash::STANDARD_HASH_SHORT;
} else {
$hash_type = $_hash_type;
}
$list[$name . ' to ' . $hash_type] = [
0 => $values['text'],
1 => $_hash_type,
2 => $values[$hash_type]
];
}
}
return $list;
}
/**
* Undocumented function
*
* @return array
*/
public function hashLongProvider(): array
{
$hash_source = 'Some String Text';
return [
'Long Hash check: ' . \CoreLibs\Create\Hash::STANDARD_HASH_LONG => [
$hash_source,
hash(\CoreLibs\Create\Hash::STANDARD_HASH_LONG, $hash_source)
],
];
}
/**
* Undocumented function
*
* @covers ::__crc32b
* @dataProvider crc32bProvider
* @testdox __crc32b $input will be $expected [$_dataName]
*
* @param string $input
* @param string $expected
* @return void
*/
public function testCrc32b(string $input, string $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Create\Hash::__crc32b($input)
);
}
/**
* Undocumented function
*
* @covers ::__sha1Short
* @dataProvider sha1ShortProvider
* @testdox __sha1Short $input will be $expected (crc32b) and $expected_sha1 (sha1 short) [$_dataName]
*
* @param string $input
* @param string $expected
* @return void
*/
public function testSha1Short(string $input, string $expected, string $expected_sha1): void
{
// uses crc32b
$this->assertEquals(
$expected,
\CoreLibs\Create\Hash::__sha1Short($input)
);
$this->assertEquals(
$expected,
\CoreLibs\Create\Hash::__sha1Short($input, false)
);
// sha1 type
$this->assertEquals(
$expected_sha1,
\CoreLibs\Create\Hash::__sha1Short($input, true)
);
}
/**
* Undocumented function
*
* @covers ::__hash
* @dataProvider hashProvider
* @testdox __hash $input with $hash_type will be $expected [$_dataName]
*
* @param string $input
* @param string|null $hash_type
* @param string $expected
* @return void
*/
public function testHash(string $input, ?string $hash_type, string $expected): void
{
if ($hash_type === null) {
$this->assertEquals(
$expected,
\CoreLibs\Create\Hash::__hash($input)
);
} else {
$this->assertEquals(
$expected,
\CoreLibs\Create\Hash::__hash($input, $hash_type)
);
}
}
/**
* Undocumented function
*
* @covers ::__hashLong
* @dataProvider hashLongProvider
* @testdox __hashLong $input will be $expected [$_dataName]
*
* @param string $input
* @param string $expected
* @return void
*/
public function testHashLong(string $input, string $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Create\Hash::__hashLong($input)
);
}
}
// __END__

View File

@@ -0,0 +1,205 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Test class for Create\RandomKey
* @coversDefaultClass \CoreLibs\Create\RandomKey
* @testdox \CoreLibs\Create\RandomKey method tests
*/
final class CoreLibsCreateRandomKeyTest extends TestCase
{
/**
* Undocumented function
*
* @return array
*/
public function keyLenghtProvider(): array
{
return [
'valid key length' => [
0 => 6,
1 => true,
2 => 6,
],
'negative key length' => [
0 => -1,
1 => false,
2 => 4,
],
'tpp big key length' => [
0 => 300,
1 => false,
2 => 4,
],
];
}
/**
* Undocumented function
*
* @return array
*/
public function randomKeyGenProvider(): array
{
return [
'default key length' => [
0 => null,
1 => 4
],
'set -1 key length default' => [
0 => -1,
1 => 4,
],
'set too large key length' => [
0 => 300,
1 => 4,
],
'set override key lenght' => [
0 => 6,
1 => 6,
],
];
}
/**
* 1
*
* @return array
*/
public function keepKeyLengthProvider(): array
{
return [
'set too large' => [
0 => 6,
1 => 300,
2 => 6,
],
'set too small' => [
0 => 8,
1 => -2,
2 => 8,
],
'change valid' => [
0 => 10,
1 => 6,
2 => 6,
]
];
}
/**
* run before each test and reset to default 4
*
* @before
*
* @return void
*/
public function resetKeyLength(): void
{
\CoreLibs\Create\RandomKey::setRandomKeyLength(4);
}
/**
* check that first length is 4
*
* @covers ::getRandomKeyLength
* @testWith [4]
* @testdox getRandomKeyLength on init will be $expected [$_dataName]
*
* @param integer $expected
* @return void
*/
public function testGetRandomKeyLengthInit(int $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Create\RandomKey::getRandomKeyLength()
);
}
/**
* Undocumented function
*
* @covers ::setRandomKeyLength
* @covers ::getRandomKeyLength
* @dataProvider keyLenghtProvider
* @testdox setRandomKeyLength $input will be $expected, compare to $compare [$_dataName]
*
* @param integer $input
* @param boolean $expected
* @param integer $compare
* @return void
*/
public function testSetRandomKeyLength(int $input, bool $expected, int $compare): void
{
// set
$this->assertEquals(
$expected,
\CoreLibs\Create\RandomKey::setRandomKeyLength($input)
);
// read test, if false, use compare check
if ($expected === false) {
$input = $compare;
}
$this->assertEquals(
$input,
\CoreLibs\Create\RandomKey::getRandomKeyLength()
);
}
/**
* Undocumented function
*
* @covers ::randomKeyGeyn
* @dataProvider randomKeyGenProvider
* @testdox randomKeyGen use $input key length $expected [$_dataName]
*
* @param integer|null $input
* @param integer $expected
* @return void
*/
public function testRandomKeyGen(?int $input, int $expected): void
{
if ($input === null) {
$this->assertEquals(
$expected,
strlen(\CoreLibs\Create\RandomKey::randomKeyGen())
);
} else {
$this->assertEquals(
$expected,
strlen(\CoreLibs\Create\RandomKey::randomKeyGen($input))
);
}
}
/**
* Check that if set to n and then invalid, it keeps the previous one
* or if second change valid, second will be shown
*
* @covers ::setRandomKeyLength
* @dataProvider keepKeyLengthProvider
* @testdox keep setRandomKeyLength set with $input_valid and then $input_invalid will be $expected [$_dataName]
*
* @param integer $input_valid
* @param integer $input_invalid
* @param integer $expected
* @return void
*/
public function testKeepKeyLength(int $input_valid, int $input_invalid, int $expected): void
{
\CoreLibs\Create\RandomKey::setRandomKeyLength($input_valid);
\CoreLibs\Create\RandomKey::setRandomKeyLength($input_invalid);
$this->assertEquals(
$expected,
\CoreLibs\Create\RandomKey::getRandomKeyLength()
);
}
}
// __END__

View File

@@ -0,0 +1,472 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\MockObject\MockObject;
/**
* Test class for Create\Session
* @coversDefaultClass \CoreLibs\Create\Session
* @testdox \CoreLibs\Create\Session method tests
*/
final class CoreLibsCreateSessionTest extends TestCase
{
/**
* Undocumented function
*
* @return array
*/
public function sessionProvider(): array
{
// 0: session name as parameter or for GLOBAL value
// 1: type p: parameter, g: global, d: php.ini default
// 2: mock data as array
// checkCliStatus: true/false,
// getSessionStatus: PHP_SESSION_DISABLED for abort,
// PHP_SESSION_NONE/ACTIVE for ok
// setSessionName: true/false,
// checkActiveSession: true/false, [1st call, 2nd call]
// getSessionId: string or false
// 3: exepcted name (session)
// 4: expected error string
return [
'session parameter' => [
'sessionNameParameter',
'p',
[
'checkCliStatus' => false,
'getSessionStatus' => PHP_SESSION_NONE,
'setSessionName' => true,
'checkActiveSession' => [false, true],
'getSessionId' => '1234abcd4567'
],
'sessionNameParameter',
''
],
'session globals' => [
'sessionNameGlobals',
'g',
[
'checkCliStatus' => false,
'getSessionStatus' => PHP_SESSION_NONE,
'setSessionName' => true,
'checkActiveSession' => [false, true],
'getSessionId' => '1234abcd4567'
],
'sessionNameGlobals',
''
],
'session name default' => [
'',
'd',
[
'checkCliStatus' => false,
'getSessionStatus' => PHP_SESSION_NONE,
'setSessionName' => true,
'checkActiveSession' => [false, true],
'getSessionId' => '1234abcd4567'
],
'',
''
],
// error checks
// 1: we are in cli
'on cli error' => [
'',
'd',
[
'checkCliStatus' => true,
'getSessionStatus' => PHP_SESSION_NONE,
'setSessionName' => true,
'checkActiveSession' => [false, true],
'getSessionId' => '1234abcd4567'
],
'',
'[SESSION] No sessions in php cli'
],
// 2: session disabled
'session disabled error' => [
'',
'd',
[
'checkCliStatus' => false,
'getSessionStatus' => PHP_SESSION_DISABLED,
'setSessionName' => true,
'checkActiveSession' => [false, true],
'getSessionId' => '1234abcd4567'
],
'',
'[SESSION] Sessions are disabled'
],
// 3: invalid session name: string
'invalid name chars error' => [
'1invalid$session#;',
'p',
[
'checkCliStatus' => false,
'getSessionStatus' => PHP_SESSION_NONE,
'setSessionName' => false,
'checkActiveSession' => [false, true],
'getSessionId' => '1234abcd4567'
],
'',
'[SESSION] Invalid session name: 1invalid$session#;'
],
// 3: invalid session name: only numbers
'invalid name numbers only error' => [
'123',
'p',
[
'checkCliStatus' => false,
'getSessionStatus' => PHP_SESSION_NONE,
'setSessionName' => false,
'checkActiveSession' => [false, true],
'getSessionId' => '1234abcd4567'
],
'',
'[SESSION] Invalid session name: 123'
],
// 3: invalid session name: invalid name short
// 3: invalid session name: too long (128)
// 4: failed to start session (2nd false on check active session)
'invalid name numbers only error' => [
'',
'd',
[
'checkCliStatus' => false,
'getSessionStatus' => PHP_SESSION_NONE,
'setSessionName' => true,
'checkActiveSession' => [false, false],
'getSessionId' => '1234abcd4567'
],
'',
'[SESSION] Failed to activate session'
],
// 5: get session id return false
'invalid name numbers only error' => [
'',
'd',
[
'checkCliStatus' => false,
'getSessionStatus' => PHP_SESSION_NONE,
'setSessionName' => true,
'checkActiveSession' => [false, true],
'getSessionId' => false
],
'',
'[SESSION] getSessionId did not return a session id'
],
];
}
/**
* Test session start
*
* @covers ::startSession
* @dataProvider sessionProvider
* @testdox startSession $input name for $type will be $expected (error: $expected_error) [$_dataName]
*
* @param string $input
* @param string $type
* @param array<mixed> $mock_data
* @param string $expected
* @param string $expected_error
* @return void
*/
public function testStartSession(
string $input,
string $type,
array $mock_data,
string $expected,
string $expected_error
): void {
// override expected
if ($type == 'd') {
$expected = ini_get('session.name');
}
/** @var \CoreLibs\Create\Session&MockObject $session_mock */
$session_mock = $this->createPartialMock(
\CoreLibs\Create\Session::class,
[
'checkCliStatus', 'getSessionStatus', 'checkActiveSession',
'setSessionName', 'startSessionCall', 'getSessionId',
'getSessionName'
]
);
// set return values based requested input values
// OK: true
// error: false
$session_mock->method('checkCliStatus')->willReturn($mock_data['checkCliStatus']);
// OK: PHP_SESSION_ACTIVE, PHP_SESSION_NONE
// error: PHP_SESSION_DISABLED
$session_mock->method('getSessionStatus')->willReturn($mock_data['getSessionStatus']);
// false: try start
// true: skip start
// note that on second call if false -> error
$session_mock->method('checkActiveSession')
->willReturnOnConsecutiveCalls(
$mock_data['checkActiveSession'][0],
$mock_data['checkActiveSession'][1],
);
// dummy set for session name
$session_mock->method('setSessionName')->with($input)->willReturn($mock_data['setSessionName']);
// set session name & return bsed on request data
$session_mock->method('getSessionName')->willReturn($expected);
// will not return anything
$session_mock->method('startSessionCall');
// in test case only return string
// false: will return false
$session_mock->method('getSessionId')->willReturn($mock_data['getSessionId']);
// regex for session id
$ression_id_regex = "/^\w+$/";
unset($GLOBALS['SET_SESSION_NAME']);
$session_id = '';
switch ($type) {
case 'p':
$session_id = $session_mock->startSession($input);
break;
case 'g':
$GLOBALS['SET_SESSION_NAME'] = $input;
$session_id = $session_mock->startSession();
break;
case 'd':
$session_id = $session_mock->startSession();
break;
}
// asert checks
if (!empty($session_id)) {
$this->assertMatchesRegularExpression(
$ression_id_regex,
(string)$session_id,
'session id regex from retrun'
);
$this->assertMatchesRegularExpression(
$ression_id_regex,
(string)$session_mock->getSessionId()
);
$this->assertEquals(
$expected,
$session_mock->getSessionName()
);
} else {
// false checks
$this->assertEquals(
$expected_error,
$session_mock->getErrorStr(),
'error assert'
);
}
}
/**
* provider for session name check
*
* @return array
*/
public function sessionNameProvider(): array
{
// 0: string for session
// 1: expected return as bool
return [
'valid name' => [
'abc',
true
],
'valid name longer' => [
'something-abc-123',
true
],
'invalid name' => [
'abc#abc',
false
],
'only numbers' => [
'123',
false
],
'longer than 128 chars' => [
'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz'
. 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz'
. 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz',
false
],
'too short' => [
'',
false
],
];
}
/**
* test valid session name
*
* @covers ::checkValidSessionName
* @dataProvider sessionNameProvider
* @testdox checkValidSessionName $input seessionn name is $expected [$_dataName]
*
* @param string $input
* @param bool $expected
* @return void
*/
public function testCheckValidSessionName(string $input, bool $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Create\Session::checkValidSessionName($input)
);
}
/**
* provider for set/get tests
*
* @return array
*/
public function sessionDataProvider(): array
{
return [
'test' => [
'foo',
'bar',
'bar',
],
'int key test' => [
123,
'bar',
'bar',
],
// more complex value tests
'array values' => [
'array',
[1, 2, 3],
[1, 2, 3],
]
];
}
/**
* method call test
*
* @covers ::setS
* @covers ::getS
* @covers ::issetS
* @covers ::unsetS
* @dataProvider sessionDataProvider
* @testdox setS/getS/issetS/unsetS $name with $input is $expected [$_dataName]
*
* @param string|int $name
* @param mixed $input
* @param mixed $expected
* @return void
*/
public function testMethodSetGet($name, $input, $expected): void
{
$session = new \CoreLibs\Create\Session();
$session->setS($name, $input);
$this->assertEquals(
$expected,
$session->getS($name),
'method set assert'
);
// isset true
$this->assertTrue(
$session->issetS($name),
'method isset assert ok'
);
$session->unsetS($name);
$this->assertEquals(
'',
$session->getS($name),
'method unset assert'
);
// iset false
$this->assertFalse(
$session->issetS($name),
'method isset assert false'
);
}
/**
* magic call test
*
* @covers ::__set
* @covers ::__get
* @covers ::__isset
* @covers ::__unset
* @dataProvider sessionDataProvider
* @testdox __set/__get/__iseet/__unset $name with $input is $expected [$_dataName]
*
* @param string|int $name
* @param mixed $input
* @param mixed $expected
* @return void
*/
public function testMagicSetGet($name, $input, $expected): void
{
$session = new \CoreLibs\Create\Session();
$session->$name = $input;
$this->assertEquals(
$expected,
$session->$name,
'magic set assert'
);
// isset true
$this->assertTrue(
isset($session->$name),
'magic isset assert ok'
);
unset($session->$name);
$this->assertEquals(
'',
$session->$name,
'magic unset assert'
);
// isset true
$this->assertFalse(
isset($session->$name),
'magic isset assert false'
);
}
/**
* unset all test
*
* @covers ::unsetAllS
* @testdox unsetAllS test
*
* @return void
*/
public function testUnsetAll(): void
{
$test_values = [
'foo' => 'abc',
'bar' => '123'
];
$session = new \CoreLibs\Create\Session();
foreach ($test_values as $name => $value) {
$session->setS($name, $value);
// confirm set
$this->assertEquals(
$value,
$session->getS($name),
'set assert: ' . $name
);
}
// unset all
$session->unsetAllS();
// check unset
foreach (array_keys($test_values) as $name) {
$this->assertEquals(
'',
$session->getS($name),
'unsert assert: ' . $name
);
}
}
}
// __END__

View File

@@ -0,0 +1,186 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Test class for Create\Uids
* @coversDefaultClass \CoreLibs\Create\Uids
* @testdox \CoreLibs\Create\Uids method tests
*/
final class CoreLibsCreateUidsTest extends TestCase
{
/**
* Undocumented function
*
* @return array
*/
public function uniqIdProvider(): array
{
return [
'md5 hash' => [
0 => 'md5',
1 => 32,
],
'sha256 hash' => [
0 => 'sha256',
1 => 64
],
'ripemd160 hash' => [
0 => 'ripemd160',
1 => 40
],
'adler32 hash' => [
0 => 'adler32',
1 => 8
],
'not in list hash but valid' => [
0 => 'sha3-512',
1 => strlen(hash('sha3-512', 'A'))
],
'default hash not set' => [
0 => null,
1 => 64,
],
'invalid name' => [
0 => 'iamnotavalidhash',
1 => 64,
],
'auto: ' . \CoreLibs\Create\Uids::DEFAULT_HASH => [
0 => \CoreLibs\Create\Uids::DEFAULT_HASH,
1 => strlen(hash(\CoreLibs\Create\Uids::DEFAULT_HASH, 'A'))
],
'auto: ' . \CoreLibs\Create\Uids::STANDARD_HASH_LONG => [
0 => \CoreLibs\Create\Uids::STANDARD_HASH_LONG,
1 => strlen(hash(\CoreLibs\Create\Uids::STANDARD_HASH_LONG, 'A'))
],
'auto: ' . \CoreLibs\Create\Uids::STANDARD_HASH_SHORT => [
0 => \CoreLibs\Create\Uids::STANDARD_HASH_SHORT,
1 => strlen(hash(\CoreLibs\Create\Uids::STANDARD_HASH_SHORT, 'A'))
],
];
}
/**
* Undocumented function
*
* @return array
*/
public function uniqIdLongProvider(): array
{
return [
'uniq id long: ' . \CoreLibs\Create\Uids::STANDARD_HASH_LONG => [
strlen(hash(\CoreLibs\Create\Uids::STANDARD_HASH_LONG, 'A'))
],
];
}
/**
* must match 7e78fe0d-59b8-4637-af7f-e88d221a7d1e
*
* @covers ::uuidv4
* @testdox uuidv4 check that return is matching regex [$_dataName]
*
* @return void
*/
public function testUuidv4(): void
{
$uuid = \CoreLibs\Create\Uids::uuidv4();
$this->assertMatchesRegularExpression(
'/^[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}$/',
$uuid
);
// $this->assertStringMatchesFormat(
// '%4s%4s-%4s-%4s-%4s-%4s%4s%4s',
// $uuid
// );
}
/**
* Undocumented function
*
* @covers ::uniqId
* @dataProvider uniqIdProvider
* @testdox uniqId $input will be length $expected [$_dataName]
*
* @param string|null $input
* @param string $expected
* @return void
*/
public function testUniqId(?string $input, int $expected): void
{
if ($input === null) {
$this->assertEquals(
$expected,
strlen(\CoreLibs\Create\Uids::uniqId())
);
} else {
$this->assertEquals(
$expected,
strlen(\CoreLibs\Create\Uids::uniqId($input))
);
}
}
/**
* Because we set a constant here, we can only run one test
* so we test invalid one to force check
*
* @covers ::uniqId
* @#dataProvider uniqIdProvider
* @testWith ["invalidhash", 64]
* @testdox uniqId use DEFAULT_HASH set $input with length $expected [$_dataName]
*
* @return void
*/
public function testUnidIdDefaultHash(string $input, int $expected): void
{
define('DEFAULT_HASH', $input);
$this->assertEquals(
$expected,
strlen(\CoreLibs\Create\Uids::uniqId())
);
}
/**
* Short id, always 8 in length
*
* @covers ::uniqIdShort
* @testWith [8]
* @testdox uniqIdShort will be length $expected [$_dataName]
*
* @param integer $expected
* @return void
*/
public function testUniqIdShort(int $expected): void
{
$this->assertEquals(
$expected,
strlen(\CoreLibs\Create\Uids::uniqIdShort())
);
}
/**
* Long Id, length can change
*
* @covers ::uniqIdLong
* @dataProvider uniqIdLongProvider
* @testdox uniqIdLong will be length $expected [$_dataName]
*
* @param integer $expected
* @return void
*/
public function testUniqIdLong(int $expected): void
{
$this->assertEquals(
$expected,
strlen(\CoreLibs\Create\Uids::uniqIdLong())
);
}
}
// __END__

View File

@@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Test class for DB\Extended\ArrayIO
* This will only test the PgSQL parts
* @coversDefaultClass \CoreLibs\DB\Extended\ArrayIO
* @coversDefaultClass \CoreLibs\DB\Extended\ArrayIO
* @testdox \CoreLibs\Extended\ArrayIO method tests for extended DB interface
*/
final class CoreLibsDBExtendedArrayIOTest extends TestCase
{
/**
* Undocumented function
*
* @return void
*/
protected function setUp(): void
{
if (!extension_loaded('pgsql')) {
$this->markTestSkipped(
'The PgSQL extension is not available.'
);
}
}
/**
* Undocumented function
*
* @testdox DB\Extended\ArrayIO Class tests
*
* @return void
*/
public function testArrayDBIO()
{
// $this->assertTrue(true, 'DB Extended ArrayIO Tests not implemented');
$this->markTestIncomplete(
'DB\Extended\ArrayIO Tests have not yet been implemented'
);
}
}
// __END__

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,176 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Test class for Debug\FileWriter
* @coversDefaultClass \CoreLibs\Debug\FileWriter
* @testdox \CoreLibs\Debug\FileWriter method tests
*/
final class CoreLibsDebugFileWriterTest extends TestCase
{
/**
* Undocumented function
*
* @return array
*/
public function fsetFolderProvider(): array
{
return [
'valid log folder name' => [
0 => '/tmp/',
1 => true,
],
'invalid log folder name' => [
0 => 'some name',
1 => false,
],
'not writeable log folder name' => [
0 => '/opt',
1 => false,
]
];
}
/**
* Undocumented function
*
* @return array
*/
public function fsetFilenameProvider(): array
{
return [
'valid log file name' => [
0 => 'some_valid_name.log',
1 => true,
],
'file name contains path' => [
0 => 'log/debug.log',
1 => false,
],
'invalid log file name' => [
0 => 'invalid name',
1 => false,
]
];
}
/**
* Undocumented function
*
* @return array
*/
public function fdebugProvider(): array
{
return [
'debug with default enter' => [
0 => 'test string',
1 => null,
2 => true,
3 => 'test string' . "\n"
],
'debug with no enter' => [
0 => 'test string',
1 => false,
2 => true,
3 => 'test string'
]
];
}
/**
* Undocumented function
*
* @dataProvider fsetFolderProvider
* @testdox fsetFolder $input will match $expected [$_dataName]
*
* @param string $input
* @param boolean $expected
* @return void
*/
public function testFsetFolder(string $input, bool $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Debug\FileWriter::fsetFolder($input)
);
}
/**
* Undocumented function
*
* @dataProvider fsetFilenameProvider
* @testdox fsetFilename $input will match $expected [$_dataName]
*
* @param string $input
* @param boolean $expected
* @return void
*/
public function testFsetFilename(string $input, bool $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Debug\FileWriter::fsetFilename($input)
);
}
/**
* Undocumented function
*
* @dataProvider fdebugProvider
* @testdox fdebug write $input with enter $enter and will be $expected and written $expected_log [$_dataName]
*
* @param string $input
* @param boolean|null $enter
* @param boolean $expected
* @param string $expected_log
* @return void
*/
public function testFdebug(string $input, ?bool $enter, bool $expected, string $expected_log): void
{
// set debug log folder
$file = 'FileWriterTest.log';
$folder = '/tmp';
$debug_file = $folder . DIRECTORY_SEPARATOR . $file;
$valid_folder = \CoreLibs\Debug\FileWriter::fsetFolder($folder);
$this->assertTrue(
$valid_folder
);
$valid_file = \CoreLibs\Debug\FileWriter::fsetFilename($file);
$this->assertTrue(
$valid_file
);
// write the log line
if ($enter === null) {
$this->assertEquals(
$expected,
\CoreLibs\Debug\FileWriter::fdebug($input)
);
} else {
$this->assertEquals(
$expected,
\CoreLibs\Debug\FileWriter::fdebug($input, $enter)
);
}
if (is_file($debug_file)) {
// open file, load data, compre to expected_log
$log_data = file_get_contents($debug_file);
if ($log_data === false) {
$this->fail('fdebug file not readable or not data: ' . $debug_file);
}
$this->assertStringEndsWith(
$expected_log,
$log_data
);
unlink($debug_file);
} else {
$this->fail('fdebug file not found: ' . $debug_file);
}
}
}
// __END__

View File

@@ -0,0 +1,990 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
// TODO: setLogPer test log file written matches pattern
/**
* Test class for Debug\Logging
* @coversDefaultClass \CoreLibs\Debug\Logging
* @testdox \CoreLibs\Debug\Logging method tests
*/
final class CoreLibsDebugLoggingTest extends TestCase
{
/**
* 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' => [
[
'log_folder' => '/tmp'
],
[
'log_folder' => '/tmp/',
'debug_all' => false,
'print_all' => false,
],
[]
],
'nothing set' => [
null,
[
'log_folder' => getcwd() . DIRECTORY_SEPARATOR,
'debug_all' => false,
'print_all' => false,
],
[]
],
'no options set, constant set' => [
null,
[
'log_folder' => str_replace('/configs', '', __DIR__)
. DIRECTORY_SEPARATOR . 'log/',
'debug_all' => false,
'print_all' => false,
],
[
'constant' => [
'BASE' => str_replace('/configs', '', __DIR__)
. DIRECTORY_SEPARATOR,
'LOG' => 'log/'
]
]
],
'standard test set' => [
[
'log_folder' => '/tmp',
'debug_all' => true,
'print_all' => true,
],
[
'log_folder' => '/tmp/',
'debug_all' => true,
'print_all' => true,
],
[]
]
];
}
/**
* init logging class
*
* @dataProvider optionsProvider
* @testdox init test [$_dataName]
*
* @param array|null $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) {
define($var, $value);
}
}
if ($options === null) {
$log = new \CoreLibs\Debug\Logging();
} else {
$log = new \CoreLibs\Debug\Logging($options);
}
// check that settings match
$this->assertEquals(
$expected['log_folder'],
$log->getSetting('log_folder')
);
$this->assertEquals(
$expected['debug_all'],
$log->getSetting('debug_output_all')
);
$this->assertEquals(
$expected['print_all'],
$log->getSetting('print_output_all')
);
// print "LOG: " . $log->getSetting('log_folder') . "\n";
// print "DEBUG: " . $log->getSetting('debug_output_all') . "\n";
// print "PRINT: " . $log->getSetting('print_output_all') . "\n";
}
/**
* adds log ID settings based on basic options
*
* @return array
*/
public function logIdOptionsProvider(): array
{
// 0: options
// 1: expected
// 2: override
return [
'no log id set' => [
null,
[
'log_file_id' => ''
],
[]
],
// set log id manually afterwards
'set log id manually' => [
null,
[
'log_file_id' => '',
'set_log_file_id' => 'abc123',
],
[
// set post launch
'values' => [
'log_file_id' => 'abc123'
]
]
],
// set log id from options
'set log id via options' => [
[
'file_id' => 'abc456',
],
[
'log_file_id' => 'abc456'
],
[]
],
// set log id from GLOBALS [DEPRECATED]
'set log id via globals' => [
null,
[
'log_file_id' => 'def123'
],
[
'globals' => [
'LOG_FILE_ID' => 'def123'
]
]
],
// set log id from CONSTANT [DEPRECATED]
'set log id via constant' => [
null,
[
'log_file_id' => 'ghi123'
],
[
// reset global
'globals' => [
'LOG_FILE_ID' => null
],
'constant' => [
'LOG_FILE_ID' => 'ghi123'
]
]
],
// invalid, keep previous set
'invalid log id' => [
[
'file_id' => 'jkl456'
],
[
'log_file_id' => 'jkl456',
'set_log_file_id' => 'jkl456',
],
[
'values' => [
'log_file_id' => './#'
]
]
]
];
}
/**
* test the setting and getting of LogId
*
* @covers ::setLogId
* @dataProvider logIdOptionsProvider
* @testdox log id set/get tests [$_dataName]
*
* @param array|null $options
* @param array $expected
* @param array $override
* @return void
*/
public function testLogId(?array $options, array $expected, array $override): void
{
// we need to set with file_id option, globals LOG_FILE_ID, constant LOG_FILE_ID
if (!empty($override['constant'])) {
foreach ($override['constant'] as $var => $value) {
define($var, $value);
}
}
if (!empty($override['globals'])) {
foreach ($override['globals'] as $var => $value) {
$GLOBALS[$var] = $value;
}
}
if ($options === null) {
$log = new \CoreLibs\Debug\Logging();
} else {
$log = new \CoreLibs\Debug\Logging($options);
}
// check current
$this->assertEquals(
$log->getLogId(),
$expected['log_file_id']
);
// we need to override now too
if (!empty($override['values'])) {
// check if we have values, set them post and assert
$log->setLogId($override['values']['log_file_id']);
$this->assertEquals(
$log->getLogId(),
$expected['set_log_file_id']
);
}
}
/**
* Undocumented function
*
* @return array
*/
public function logLevelAllProvider(): array
{
// 0: type
// 1: flag
// 2: expected set
// 3: expected get
return [
'debug all true' => [
'debug',
true,
true,
true,
],
'echo all true' => [
'echo',
true,
true,
true,
],
'print all true' => [
'print',
true,
true,
true,
],
'set invalid level' => [
'invalud',
true,
false,
false,
],
];
}
/**
* check set/get for log level all flag
*
* @dataProvider logLevelAllProvider
* @testdox set/get all log level $type with flag $flag [$_dataName]
*
* @param string $type
* @param bool $flag
* @param bool $expected_set
* @param bool $expected_get
* @return void
*/
public function testSetGetLogLevelAll(
string $type,
bool $flag,
bool $expected_set,
bool $expected_get
): void {
// neutral start with default
$log = new \CoreLibs\Debug\Logging();
// set and check
$this->assertEquals(
$log->setLogLevelAll($type, $flag),
$expected_set
);
// get and check
$this->assertEquals(
$log->getLogLevelAll($type),
$expected_get
);
}
/**
* Undocumented function
*
* @return array
*/
public function logLevelProvider(): array
{
// 0: type
// 1: flag
// 2: debug on (array)
// 3: expected set
// 4: level
// 5: expected get
return [
'set debug on for level A,B,C and check full set' => [
'debug',
'on',
['A', 'B', 'C'],
true,
null,
[
'A' => true,
'B' => true,
'C' => true,
]
],
'set debug off for level A,B,C and check A' => [
'debug',
'off',
['A', 'B', 'C'],
true,
'A',
true,
],
// set one to false
'set debug off for level A, B to false and check all' => [
'debug',
'off',
['A', 'B' => false],
true,
null,
[
'A' => true,
'B' => false,
],
],
// set invalid type
'set invalid level' => [
'invalid',
'',
[],
false,
null,
false
],
// set invalid flag
'set invalid on flag' => [
'print',
'invalid',
[],
false,
null,
false
],
// missing debug array set
'missing debug level array' => [
'print',
'off',
[],
false,
null,
[]
],
// set but check no existing
'set level but check no exisitng' => [
'print',
'on',
['A'],
true,
'C',
false
]
];
}
/**
* checks setting for per log info level
*
* @covers ::setLogLevel
* @dataProvider logLevelProvider
* @testdox set/get log level $type to $flag check with $level [$_dataName]
*
* @param string $type
* @param string $flag
* @param array $debug_on
* @param bool $expected_set
* @param string|null $level
* @param bool|array<mixed> $expected_get
* @return void
*/
public function testSetGetLogLevel(
string $type,
string $flag,
array $debug_on,
bool $expected_set,
?string $level,
$expected_get
): void {
// neutral start with default
$log = new \CoreLibs\Debug\Logging();
// set
$this->assertEquals(
$log->setLogLevel($type, $flag, $debug_on),
$expected_set
);
// get, if level is null compare to?
$this->assertEquals(
$log->getLogLevel($type, $flag, $level),
$expected_get
);
}
/**
* Undocumented function
*
* @return array
*/
public function logPerProvider(): array
{
// 0: type
// 1: set
// 2: expected set
// 3: expected get
return [
'level set true' => [
'level',
true,
true,
true,
],
'class set true' => [
'class',
true,
true,
true,
],
'page set true' => [
'page',
true,
true,
true,
],
'run set true' => [
'run',
true,
true,
true,
],
'set invalid type' => [
'invalid',
true,
false,
false,
]
];
}
/**
* set and get per log
* for level/class/page/run flags
*
* @covers ::setLogPer
* @dataProvider logPerProvider
* @testdox set/get log per $type with $set [$_dataName]
*
* @param string $type
* @param boolean $set
* @param boolean $expected_set
* @param boolean $expected_get
* @return void
*/
public function testSetGetLogPer(
string $type,
bool $set,
bool $expected_set,
bool $expected_get
): void {
// neutral start with default
$log = new \CoreLibs\Debug\Logging();
// set and check
$this->assertEquals(
$log->setLogPer($type, $set),
$expected_set
);
// get and check
$this->assertEquals(
$log->getLogPer($type),
$expected_get
);
}
/**
* set the print log file date part
*
* @covers ::setGetLogPrintFileDate
* @testWith [true, true, true]
* [false, false, false]
* @testdox set/get log file date to $input [$_dataName]
*
* @param boolean $input
* @param boolean $expected_set
* @param boolean $expected_get
* @return void
*/
public function testSetGetLogPrintFileDate(bool $input, bool $expected_set, bool $expected_get): void
{
// neutral start with default
$log = new \CoreLibs\Debug\Logging();
// set and check
$this->assertEquals(
$log->setGetLogPrintFileDate($input),
$expected_set
);
$this->assertEquals(
$log->setGetLogPrintFileDate(),
$expected_get
);
}
/**
* Undocumented function
*
* @return array
*/
public function prArProvider(): array
{
return [
'simple array' => [
[
'A' => 'foobar'
],
"##HTMLPRE##Array\n(\n"
. " [A] => foobar\n"
. ")\n"
. "##/HTMLPRE##"
],
'empty array' => [
[],
"##HTMLPRE##Array\n(\n"
. ")\n"
. "##/HTMLPRE##"
],
'nested array' => [
[
'A' => [
'B' => 'bar'
]
],
"##HTMLPRE##Array\n(\n"
. " [A] => Array\n"
. " (\n"
. " [B] => bar\n"
. " )\n"
. "\n"
. ")\n"
. "##/HTMLPRE##"
],
];
}
/**
* convert array to string with ## pre replace space holders
*
* @covers ::prAr
* @dataProvider prArProvider
* @testdox check prAr array to string conversion [$_dataName]
*
* @param array $input
* @param string $expected
* @return void
*/
public function testPrAr(array $input, string $expected): void
{
$log = new \CoreLibs\Debug\Logging();
$this->assertEquals(
$log->prAr($input),
$expected
);
}
/**
* Undocumented function
*
* @return array
*/
public function prBlProvider(): array
{
// 0: input flag (bool)
// 1: is true
// 2: is flase
// 3: epxected
return [
'true bool default' => [
true,
null,
null,
'true'
],
'false bool default' => [
false,
null,
null,
'false'
],
'true bool override' => [
true,
'ok',
'not ok',
'ok'
],
'false bool override' => [
false,
'ok',
'not ok',
'not ok'
],
];
}
/**
* check bool to string converter
*
* @covers ::prBl
* @dataProvider prBlProvider
* @testdox check prBl $input ($true/$false) is expected $false [$_dataName]
*
* @param bool $input
* @param string|null $true
* @param string|null $false
* @param string $expected
* @return void
*/
public function testPrBl(bool $input, ?string $true, ?string $false, string $expected): void
{
$log = new \CoreLibs\Debug\Logging();
$return = '';
if ($true === null && $false === null) {
$return = $log->prBl($input);
} elseif ($true !== null || $false !== null) {
$return = $log->prBl($input, $true ?? '', $false ?? '');
}
$this->assertEquals(
$expected,
$return
);
}
// from here are complex debug tests
/**
* Undocumented function
*
* 0: array $options
* 1: array $debug_msg
* 2: boolean $expected_debug
* 3: string $expected_file
* 4: string $expected_string_start
* 5: string $expected_string_contains
*
* @return array
*/
public function debugProvider(): array
{
// error message to pass in
$error_msg['A'] = [
'level' => 'A',
'string' => 'error msg',
'strip' => false,
'prefix' => '',
];
// file content to check
$file_msg['A'] = "{PHPUnit\TextUI\Command} <A> - error msg\n";
// string messages to check
$string_msg['A'] = [
's' => '<div style="text-align: left; padding: 5px; font-size: 10px; '
. 'font-family: sans-serif; border-top: 1px solid black; '
. 'border-bottom: 1px solid black; margin: 10px 0 10px 0; '
. 'background-color: white; color: black;">'
. '<div style="font-size: 12px;">{<span style="font-style: '
. 'italic; color: #928100;">PHPUnit\TextUI\Command</span>}'
. '</div><div style="font-size: 12px;">[<span style="font-style: '
. 'italic; color: #c56c00;">A</span>] </div><div>[<span '
. 'style="font-weight: bold; color: #5e8600;">',
'c' => 'PHPUnit\TextUI\Command</span>} - error msg</div><!--#BR#-->',
];
// array provider
return [
'A debug: on, print: on, echo: on' => [
[
'debug_all' => true,
'print_all' => true,
'echo_all' => true,
],
$error_msg['A'],
true,
$file_msg['A'],
$string_msg['A']['s'],
$string_msg['A']['c'],
],
'B debug: on, print: off, echo: on' => [
[
'debug_all' => true,
'print_all' => false,
'echo_all' => true,
],
$error_msg['A'],
true,
'',
$string_msg['A']['s'],
$string_msg['A']['c'],
],
'C debug: on, print: on, echo: off' => [
[
'debug_all' => true,
'print_all' => true,
'echo_all' => false,
],
$error_msg['A'],
true,
$file_msg['A'],
'',
'',
],
'D debug: on, print: off, echo: off' => [
[
'debug_all' => true,
'print_all' => false,
'echo_all' => false,
],
$error_msg['A'],
false,
'',
'',
''
],
'E debug: off, print: off, echo: off' => [
[
'debug_all' => false,
'print_all' => false,
'echo_all' => false,
],
$error_msg['A'],
false,
'',
'',
''
]
// TODO more tests with different error messages
];
}
/**
* Test debug flow
*
* @covers ::debug
* @dataProvider debugProvider
* @testdox check debug flow: $expected_debug [$_dataName]
*
* @param array $options
* @param array $debug_msg
* @param boolean $expected_debug
* @param string $expected_file
* @param string $expected_string_start
* @param string $expected_string_contains
* @return void
*/
public function testDebug(
array $options,
array $debug_msg,
bool $expected_debug,
string $expected_file,
string $expected_string_start,
string $expected_string_contains
): void {
// must run with below matrix
// level | debug | print | echo | debug() | printErrorMsg() | file
// A 1/1/1 | on | on | on | true | 'string' | on
// B 1/0/1 | on | off | on | true | 'string' | off
// C 1/1/0 | on | on | off | true | '' | on
// D 1/0/0 | on | off | off | false | '' | off
// E 0/1/1 | off | on | on | false | '' | off
// F 0/0/1 | off | off | on | false | '' | off
// G 0/1/0 | off | on | off | false | '' | off
// H 0/0/0 | off | off | off | false | '' | off
// * debug off
// return false on debug(),
// return false on writeErrorMsg()
// empty string on printErrorMsg
// * print off
// return true on debug(),
// return false on writeErrorMsg()
// empty string on printErrorMsg
// * echo off
// return true on debug(),
// empty string on printErrorMsg
// fillxed error_msg array
// overwrite any previous set from test
$options['file_id'] = 'TestDebug';
// set log folder to temp
$options['log_folder'] = '/tmp/';
// 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);
// * debug (A/B)
// NULL check for strip/prefix
$this->assertEquals(
$log->debug(
$debug_msg['level'],
$debug_msg['string'],
$debug_msg['strip'],
$debug_msg['prefix'],
),
$expected_debug
);
// * if print check data in log file
$log_file = $log->getLogFileName();
if (!empty($options['debug_all']) && !empty($options['print_all'])) {
// file name matching
$this->assertStringStartsWith(
$options['log_folder'] . 'error_msg_' . $options['file_id'],
$log_file,
);
// cotents check
if (!is_file($log_file)) {
$this->fail('error msg file not found: ' . $log_file);
} else {
$log_data = file_get_contents($log_file);
if ($log_data === null) {
$this->fail('error msg file not readable or not data: ' . $log_file);
}
// file content matching
$this->assertStringEndsWith(
$expected_file,
$log_data,
);
}
} else {
// there should be no file there
$this->assertEquals(
$log_file,
''
);
}
// ** ECHO ON
$log_string = $log->printErrorMsg();
// * print
if (!empty($options['debug_all']) && !empty($options['echo_all'])) {
// print $log->printErrorMsg() . "\n";
// echo string must start with
$this->assertStringStartsWith(
$expected_string_start,
$log_string
);
// echo string must containt
$this->assertStringContainsString(
$expected_string_contains,
$log_string
);
// TODO: as printing directly is not really done anymore tests below are todo
// * get error msg (getErrorMsg)
// * merge error msg (mergeErrors)
// * print merged (printErrorMsg)
// * reset A (resetErrorMsg)
// * reset ALL (resetErrorMsg)
} else {
$this->assertEquals(
$log_string,
''
);
}
}
// TODO: 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\Debug\Logging(['per_run' => $option]);
} else {
$log = new \CoreLibs\Debug\Logging();
$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'
);
}
}
}
// __END__

View File

@@ -0,0 +1,119 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
use CoreLibs\Debug\MemoryUsage;
/**
* Test class for Debug\MemoryUsage
* @coversDefaultClass \CoreLibs\Debug\MemoryUsage
* @testdox \CoreLibs\Debug\MemoryUsage method tests
*/
final class CoreLibsDebugMemoryUsageTest extends TestCase
{
/**
* Undocumented function
*
* @return array
*/
public function memoryUsageProvider(): array
{
$regex_raw_off = '/^\[[\w\s_-]+\] Peak\/Curr\/Change: \d+(\.\d+)? ?\w{1,2}\/'
. '\d+(\.\d+)? ?\w{1,2}\/'
. 'Since Start: \d+(\.\d+)? ?\w{1,2} \| '
. 'Since Last: \d+(\.\d+)? ?\w{1,2} \| '
. 'Since Set: \d+(\.\d+)? ?\w{1,2}$/';
$regex_raw_on = '/^\[[\w\s_-]+\] Peak\/Curr\/'
// . 'Change: \d+(\.\d+)? ?\w{1,2}\/\d+(\.\d+)? ?\w{1,2} \[\d+\]\/'
. 'Change: \d+(\.\d+)? ?\w{1,2}\/\d+(\.\d+)? ?\w{1,2}/'
. 'Since Start: \d+(\.\d+)? ?\w{1,2} \[\d+\] \| '
. 'Since Last: \d+(\.\d+)? ?\w{1,2} \[\d+\] \| '
. 'Since Set: \d+(\.\d+)? ?\w{1,2} \[\d+\]$/';
$regex_array = [
'prefix' => '/^[\w\s_-]+$/',
'peak' => '/^\d+$/',
'usage' => '/^\d+$/',
'start' => '/^\d+$/',
'last' => '/^\d+$/',
'set' => '/^\d+$/',
];
// 0: prefix
// 1: raw flag
// 2: set flags array
// 3: array output expected (as regex)
// 4: string output expected (as regex)
return [
'test normal' => [
'test',
null,
[],
$regex_array,
$regex_raw_off,
]
];
}
/**
* Undocumented function
*
* @cover ::resetMemory
* @cover ::debugMemoryFlag
* @cover ::setStartMemory
* @cover ::setMemory
* @cover ::memoryUsage
* @cover ::printMemoryUsage
* @dataProvider memoryUsageProvider
* @testdox memoryUsage with $prefix, raw memory $raw [$_dataName]
*
* @param string $prefix
* @param bool|null $raw
* @param array $set_flags
* @param array $expected_array
* @param string $expected_string
* @return void
*/
public function testMemoryUsage(
string $prefix,
?bool $raw,
array $settings,
array $expected_array,
string $expected_string
): void {
// always reeset to null
MemoryUsage::resetMemory();
MemoryUsage::debugMemoryFlag(true);
MemoryUsage::setStartMemory();
MemoryUsage::setMemory();
// run collector
$memory = MemoryUsage::memoryUsage($prefix);
if ($raw === null) {
$string = MemoryUsage::printMemoryUsage($memory);
} else {
$string = MemoryUsage::printMemoryUsage($memory, $raw);
}
// expected_array for each
foreach ($expected_array as $name => $regex) {
$this->assertMatchesRegularExpression(
$regex,
(string)$memory[$name],
'assert memory usage array ' . $name
);
}
// regex match string
$this->assertMatchesRegularExpression(
$expected_string,
$string,
'assert memory usage string as regex'
);
// TODO additional tests with use more memory and check diff matching
// TODO reset memory usage test
}
}
// __END__

View File

@@ -0,0 +1,183 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Test class for Debug\RunningTime
* @coversDefaultClass \CoreLibs\Debug\RunningTime
* @testdox \CoreLibs\Debug\RunningTime method tests
*/
final class CoreLibsDebugRunningTimeTest extends TestCase
{
public function hrRunningTimeProvider(): array
{
// 0: return time difference
// 1: return time on first run in regex
return [
'default time' => [
0 => null,
1 => '/^\d{4}\.\d{1,}$/'
],
'nanoseconds' => [
0 => 'ns',
1 => '/^\d{10}$/'
],
'microseconds' => [
0 => 'ys',
1 => '/^\d{7}\.\d{1,}$/'
],
'milliseconds' => [
0 => 'ms',
1 => '/^\d{4}\.\d{1,}$/'
],
'seconds' => [
0 => 's',
1 => '/^\d{1}\.\d{4,}$/'
],
'invalid fallback to ms' => [
0 => 'invalid',
1 => '/^\d{4}\.\d{1,}$/'
]
];
}
public function runningTimeProvider(): array
{
return [
'run time test' => [
0 => '/^\d{1,}\.\d{1,}$/',
1 => '/^Start: \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} 0\.\d{8}, $/',
2 => '/^Start: \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} 0\.\d{8}, '
. 'End: \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} 0\.\d{8}, '
. 'Run: \d{1,}\.\d{1,} s$/'
]
];
}
/**
* Undocumented function
*
* @cover ::hrRunningTime
* @dataProvider hrRunningTimeProvider
* @testdox hrRunningTime with $out_time matching $expected [$_dataName]
*
* @param string|null $out_time
* @param string $expected
* @return void
*/
public function testHrRunningTime(?string $out_time, string $expected): void
{
// reset for each run
\CoreLibs\Debug\RunningTime::hrRunningTimeReset();
$start = \CoreLibs\Debug\RunningTime::hrRunningTime();
$this->assertEquals(
0,
$start,
'assert first run 0'
);
time_nanosleep(1, 500);
if ($out_time === null) {
$second = \CoreLibs\Debug\RunningTime::hrRunningTime();
} else {
$second = \CoreLibs\Debug\RunningTime::hrRunningTime($out_time);
}
// print "E: " . $end . "\n";
$this->assertMatchesRegularExpression(
$expected,
(string)$second,
'assert second run regex'
);
if ($out_time === null) {
$end_second = \CoreLibs\Debug\RunningTime::hrRunningTimeFromStart();
} else {
$end_second = \CoreLibs\Debug\RunningTime::hrRunningTimeFromStart($out_time);
}
$this->assertEquals(
$end_second,
$second,
'assert end is equal second'
);
// sleep again, second messurement
time_nanosleep(1, 500);
if ($out_time === null) {
$third = \CoreLibs\Debug\RunningTime::hrRunningTime();
} else {
$third = \CoreLibs\Debug\RunningTime::hrRunningTime($out_time);
}
// third call is not null
$this->assertNotEquals(
0,
$third,
'assert third call not null'
);
// third call is bigger than end
$this->assertNotEquals(
$second,
$third,
'assert third different second'
);
// last messurement, must match start - end + last
if ($out_time === null) {
$end = \CoreLibs\Debug\RunningTime::hrRunningTimeFromStart();
} else {
$end = \CoreLibs\Debug\RunningTime::hrRunningTimeFromStart($out_time);
}
$this->assertGreaterThan(
$third,
$end,
'assert end greater third'
);
// new start
\CoreLibs\Debug\RunningTime::hrRunningTimeReset();
$new_start = \CoreLibs\Debug\RunningTime::hrRunningTime();
$this->assertEquals(
0,
$new_start,
'assert new run 0'
);
}
/**
* Undocumented function
*
* @dataProvider runningTimeProvider
* @testdox runningTime matching return $expected_number and start $expected_start end $expected_end [$_dataName]
*
* @param string $expected_number
* @param string $expected_start
* @param string $expected_end
* @return void
*/
public function testRunningTime(string $expected_number, string $expected_start, string $expected_end): void
{
$start = \CoreLibs\Debug\RunningTime::runningTime(true);
// print "Start: " . $start . "\n";
$this->assertEquals(
0,
$start
);
// print "STRING: " . \CoreLibs\Debug\RunningTime::runningTimeString() . "\n";
$this->assertMatchesRegularExpression(
$expected_start,
\CoreLibs\Debug\RunningTime::runningTimeString()
);
time_nanosleep(1, 500);
$end = \CoreLibs\Debug\RunningTime::runningTime(true);
// print "Start: " . $end . "\n";
$this->assertMatchesRegularExpression(
$expected_number,
(string)$end
);
// print "STRING: " . \CoreLibs\Debug\RunningTime::runningTimeString() . "\n";
$this->assertMatchesRegularExpression(
$expected_end,
\CoreLibs\Debug\RunningTime::runningTimeString()
);
}
}
// __END__

View File

@@ -0,0 +1,475 @@
<?php // phpcs:disable Generic.Files.LineLength
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Test class for Debug\Support
* @coversDefaultClass \CoreLibs\Debug\Support
* @testdox \CoreLibs\Debug\Support method tests
*/
final class CoreLibsDebugSupportTest extends TestCase
{
/**
* Undocumented function
*
* @return array
*/
public function printTimeProvider(): array
{
return [
'default microtime' => [
0 => null,
1 => "/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{8}$/",
],
'microtime -1' => [
0 => -1,
1 => "/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{8}$/",
],
'microtime 0' => [
0 => 0,
1 => "/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/",
],
'microtime 4' => [
0 => 4,
1 => "/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{4}$/",
],
];
}
/**
* Undocumented function
*
* @return array
*/
public function printArrayProvider(): array
{
return [
'empty array' => [
0 => [],
1 => "<pre>Array\n(\n)\n</pre>"
],
'simple array' => [
0 => ['a', 'b'],
1 => "<pre>Array\n(\n"
. " [0] => a\n"
. " [1] => b\n"
. ")\n</pre>"
],
];
}
/**
* Undocumented function
*
* @return array
*/
public function printBoolProvider(): array
{
return [
'true input default' => [
0 => true,
1 => [],
2 => 'true'
],
'false input default' => [
0 => false,
1 => [],
2 => 'false'
],
'false input param name' => [
0 => false,
1 => [
'name' => 'param test'
],
2 => '<b>param test</b>: false'
],
'true input param name, true override' => [
0 => true,
1 => [
'name' => 'param test',
'true' => 'ok'
],
2 => '<b>param test</b>: ok'
],
'false input param name, true override, false override' => [
0 => false,
1 => [
'name' => 'param test',
'true' => 'ok',
'false' => 'not',
],
2 => '<b>param test</b>: not'
],
];
}
/**
* Undocumented function
*
* @return array
*/
public function printToStringProvider(): array
{
// 0: unput
// 1: html flag (only for strings and arry)
// 2: expected
return [
'null' => [
null,
null,
'NULL',
],
'string' => [
'a string',
null,
'a string',
],
'string with html chars, encode' => [
'a string with <> &',
true,
'a string with &lt;&gt; &amp;',
],
'string with html chars' => [
'a string with <> &',
null,
'a string with <> &',
],
'a number' => [
1234,
null,
'1234',
],
'a float number' => [
1234.5678,
null,
'1234.5678',
],
'bool true' => [
true,
null,
'TRUE',
],
'bool false' => [
false,
null,
'FALSE',
],
'an array default' => [
['a', 'b'],
null,
"<pre>Array\n(\n"
. " [0] => a\n"
. " [1] => b\n"
. ")\n</pre>",
],
'an array, no html' => [
['a', 'b'],
true,
"##HTMLPRE##"
. "Array\n(\n"
. " [0] => a\n"
. " [1] => b\n"
. ")\n"
. "##/HTMLPRE##",
],
// resource
'a resource' => [
tmpfile(),
null,
'/^Resource id #\d+$/',
],
// object
'an object' => [
new \CoreLibs\Debug\Support(),
null,
'CoreLibs\Debug\Support',
]
];
}
/**
* Undocumented function
*
* @return array
*/
public function debugStringProvider(): array
{
// 0: input string
// 1: replace
// 2: html flag
// 3: expected
return [
'null string, default' => [
null,
null,
null,
'-'
],
'empty string, ... replace' => [
'',
'...',
null,
'...'
],
'filled string' => [
'some string',
null,
null,
'some string'
],
'string with html chars, encode' => [
'a string with <> &',
'-',
true,
'a string with &lt;&gt; &amp;',
],
'string with html chars' => [
'a string with <> &',
'-',
null,
'a string with <> &',
],
];
}
/**
* 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
*
* @cover ::debugString
* @dataProvider debugStringProvider
* @testdox debugString $input with replace $replace and html $flag will be $expected [$_dataName]
*
* @param string|null $input
* @param string|null $replace
* @param bool|null $flag
* @param string $expected
* @return void
*/
public function testDebugString(?string $input, ?string $replace, ?bool $flag, string $expected): void
{
if ($replace === null && $flag === null) {
$this->assertEquals(
$expected,
\CoreLibs\Debug\Support::debugString($input),
'assert all default'
);
} elseif ($flag === null) {
$this->assertEquals(
$expected,
\CoreLibs\Debug\Support::debugString($input, $replace),
'assert flag default'
);
} else {
$this->assertEquals(
$expected,
\CoreLibs\Debug\Support::debugString($input, $replace, $flag),
'assert all set'
);
}
}
}
// __END__

View File

@@ -0,0 +1,162 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
use CoreLibs\Get\DotEnv;
/**
* Test class for ACL\Login
* @coversDefaultClass \CoreLibs\Get\DotEnv
* @testdox \CoreLibs\Get\DotEnv method tests
*/
final class CoreLibsGetDotEnvTest extends TestCase
{
/**
* Undocumented function
*
* @return array
*/
public function envFileProvider(): array
{
$dot_env_content = [
'SOMETHING' => 'A',
'OTHER' => 'B IS B',
'Complex' => 'A B \"D is F',
'HAS_SPACE' => 'ABC',
'HAS_COMMENT_QUOTES_SPACE' => 'Comment at end with quotes and space',
'HAS_COMMENT_QUOTES_NO_SPACE' => 'Comment at end with quotes no space',
'HAS_COMMENT_NO_QUOTES_SPACE' => 'Comment at end no quotes and space',
'HAS_COMMENT_NO_QUOTES_NO_SPACE' => 'Comment at end no quotes no space',
'COMMENT_IN_TEXT_QUOTES' => 'Foo bar # comment in here',
'FAILURE' => 'ABC',
'SIMPLEBOX' => 'A B C',
'TITLE' => '1',
'FOO' => '1.2',
'SOME.TEST' => 'Test Var',
'SOME.LIVE' => 'Live Var',
'A_TEST1' => 'foo',
'A_TEST2' => '${TEST1:-bar}',
'A_TEST3' => '${TEST4:-bar}',
'A_TEST5' => 'null',
'A_TEST6' => '${TEST5-bar}',
'A_TEST7' => '${TEST6:-bar}',
'B_TEST1' => 'foo',
'B_TEST2' => '${TEST1:=bar}',
'B_TEST3' => '${TEST4:=bar}',
'B_TEST5' => 'null',
'B_TEST6' => '${TEST5=bar}',
'B_TEST7' => '${TEST6=bar}',
'Test' => 'A',
'TEST' => 'B',
'LINE' => "ABC\nDEF",
'OTHERLINE' => "ABC\nAF\"ASFASDF\nMORESHIT",
'SUPERLINE' => '',
'__FOO_BAR_1' => 'b',
'__FOOFOO' => 'f ',
123123 => 'number',
'EMPTY' => '',
];
// 0: folder relative to test folder, if unset __DIR__
// 1: file, if unset .env
// 2: status to be returned
// 3: _ENV file content to be set
// 4: override chmod as octect in string
return [
'default' => [
'folder' => null,
'file' => null,
'status' => 3,
'content' => [],
'chmod' => null,
],
'cannot open file' => [
'folder' => __DIR__ . DIRECTORY_SEPARATOR . 'dotenv',
'file' => 'cannot_read.env',
'status' => 2,
'content' => [],
'chmod' => '000',
],
'empty file' => [
'folder' => __DIR__ . DIRECTORY_SEPARATOR . 'dotenv',
'file' => 'empty.env',
'status' => 1,
'content' => [],
'chmod' => null,
],
'override all' => [
'folder' => __DIR__ . DIRECTORY_SEPARATOR . 'dotenv',
'file' => 'test.env',
'status' => 0,
'content' => $dot_env_content,
'chmod' => null,
],
'override directory' => [
'folder' => __DIR__ . DIRECTORY_SEPARATOR . 'dotenv',
'file' => null,
'status' => 0,
'content' => $dot_env_content,
'chmod' => null,
],
];
}
/**
* test read .env file
*
* @covers ::readEnvFile
* @dataProvider envFileProvider
* @testdox Read _ENV file from $folder / $file with expected status: $expected_status and chmod $chmod [$_dataName]
*
* @param string|null $folder
* @param string|null $file
* @param int $expected_status
* @param array $expected_env
* @param string|null $chmod
* @return void
*/
public function testReadEnvFile(
?string $folder,
?string $file,
int $expected_status,
array $expected_env,
?string $chmod
): void {
// if we have file + chmod set
$old_chmod = null;
if (
is_file($folder . DIRECTORY_SEPARATOR . $file) &&
!empty($chmod)
) {
// get the old permissions
$old_chmod = fileperms($folder . DIRECTORY_SEPARATOR . $file);
chmod($folder . DIRECTORY_SEPARATOR . $file, octdec($chmod));
}
if ($folder !== null && $file !== null) {
$status = DotEnv::readEnvFile($folder, $file);
} elseif ($folder !== null) {
$status = DotEnv::readEnvFile($folder);
} else {
$status = DotEnv::readEnvFile();
}
$this->assertEquals(
$status,
$expected_status,
'Assert returned status equal'
);
// now assert read data
$this->assertEquals(
$_ENV,
$expected_env,
'Assert _ENV correct'
);
// if we have file and chmod unset
if ($old_chmod !== null) {
chmod($folder . DIRECTORY_SEPARATOR . $file, $old_chmod);
}
}
}
// __END__

View File

@@ -0,0 +1,221 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Test class for Get\System
* @coversDefaultClass \CoreLibs\Get\System
* @testdox \CoreLibs\Get\System method tests
*/
final class CoreLibsGetSystemTest extends TestCase
{
/**
* Undocumented function
*
* @return array
*/
public function fileUploadErrorMessageProvider(): array
{
return [
'upload err init size' => [
0 => UPLOAD_ERR_INI_SIZE,
1 => 'The uploaded file exceeds the upload_max_filesize directive in php.ini',
],
'upload err from size' => [
0 => UPLOAD_ERR_FORM_SIZE,
1 => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form'
],
'upload err partial' => [
0 => UPLOAD_ERR_PARTIAL,
1 => 'The uploaded file was only partially uploaded'
],
'upload err no file' => [
0 => UPLOAD_ERR_NO_FILE,
1 => 'No file was uploaded'
],
'upload err no tmp dir' => [
0 => UPLOAD_ERR_NO_TMP_DIR,
1 => 'Missing a temporary folder'
],
'upload err cant write' => [
0 => UPLOAD_ERR_CANT_WRITE,
1 => 'Failed to write file to disk'
],
'upload err extension' => [
0 => UPLOAD_ERR_EXTENSION,
1 => 'File upload stopped by extension'
],
'unkown error' => [
0 => 99999,
1 => 'Unknown upload error'
]
];
}
/**
* Undocumented function
*
* @return array
*/
public function getHostNameProvider(): array
{
return [
'original set' => [
0 => null,
1 => 'NOHOST',
2 => 'NOPORT',
],
'override set no port' => [
0 => 'foo.org',
1 => 'foo.org',
2 => '80'
],
'override set with port' => [
0 => 'foo.org:443',
1 => 'foo.org',
2 => '443'
]
];
}
/**
* Undocumented function
*
* @return array
*/
public function getPageNameProvider(): array
{
return [
// 0: input
// 1: expected default/WITH_EXTENSION
// 2: expected NO_EXTENSION
// 3: expected FULL_PATH, if first and last character are / use regex
'original set' => [
0 => null,
1 => 'phpunit',
2 => 'phpunit',
// NOTE: this can change, so it is a regex check
3 => "/^(\/?.*\/?)?vendor\/bin\/phpunit$/",
],
'some path with extension' => [
0 => '/some/path/to/file.txt',
1 => 'file.txt',
2 => 'file',
3 => '/some/path/to/file.txt',
]
];
}
/**
* Undocumented function
*
* @covers ::fileUploadErrorMessage
* @dataProvider fileUploadErrorMessageProvider
* @testdox fileUploadErrorMessage $input error matches $expected [$_dataName]
*
* @param integer $input
* @param string $expected
* @return void
*/
public function testFileUploadErrorMessage(int $input, string $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Get\System::fileUploadErrorMessage($input)
);
}
/**
* Undocumented function
*
* @covers ::getHostName
* @dataProvider getHostNameProvider
* @testdox getHostName $input must match $expected_host:$expected_port [$_dataName]
*
* @param string|null $input
* @param string $expected_host
* @param string $expected_port
* @return void
*/
public function testGetHostNanme(?string $input, string $expected_host, string $expected_port): void
{
// print "HOSTNAME: " . $_SERVER['HTTP_HOST'] . "<br>";
// print "SERVER: " . print_r($_SERVER, true) . "\n";
// print "SELF: " . $_SERVER['PHP_SELF'] . "\n";
if ($input !== null) {
$_SERVER['HTTP_HOST'] = $input;
}
list ($host, $port) = \CoreLibs\Get\System::getHostName();
$this->assertEquals(
$expected_host,
$host,
'failed expected host assert'
);
$this->assertEquals(
$expected_port,
$port,
'faile expected port assert'
);
}
/**
* Undocumented function
*
* @covers ::getPageName
* @dataProvider getPageNameProvider
* @testdox getPageName $input will match 0: $expected_0, 1: $expected_1, 2: $expected_2 [$_dataName]
*
* @param string|null $input
* @param string $expected_0 default with extension
* @param string $expected_1 no extension
* @param string $expected_2 full path
* @return void
*/
public function testGetPageName(?string $input, string $expected_0, string $expected_1, string $expected_2)
{
if ($input !== null) {
$_SERVER['PHP_SELF'] = $input;
}
// default 0,
$this->assertEquals(
$expected_0,
\CoreLibs\Get\System::getPageName(),
'failed default assert'
);
$this->assertEquals(
$expected_0,
\CoreLibs\Get\System::getPageName(\CoreLibs\Get\System::WITH_EXTENSION),
'failed WITH_EXTESION assert'
);
$this->assertEquals(
$expected_1,
\CoreLibs\Get\System::getPageName(\CoreLibs\Get\System::NO_EXTENSION),
'failed NO_EXTENSION assert'
);
// FULL PATH check can be equals or regex
$page_name_full_path = \CoreLibs\Get\System::getPageName(\CoreLibs\Get\System::FULL_PATH);
if (
substr($expected_2, 0, 1) == '/' &&
substr($expected_2, -1, 1) == '/'
) {
// this is regex
$this->assertMatchesRegularExpression(
$expected_2,
$page_name_full_path,
'failed FULL_PATH assert regex'
);
} else {
$this->assertEquals(
$expected_2,
$page_name_full_path,
'failed FULL_PATH assert equals'
);
}
}
}
// __END__

View File

@@ -0,0 +1,310 @@
<?php // phpcs:disable Generic.Files.LineLength
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Test class for Language\GetLocale
*
* @coversDefaultClass \CoreLibs\Language\GetLocale
* @testdox \CoreLibs\Language\GetLocale method tests
*/
final class CoreLibsLanguageGetLocaleTest extends TestCase
{
/**
* set all constant variables that must be set before call
*
* @return void
*/
public static function setUpBeforeClass(): void
{
// default web page encoding setting
if (!defined('DEFAULT_ENCODING')) {
define('DEFAULT_ENCODING', 'UTF-8');
}
if (!defined('DEFAULT_LOCALE')) {
// default lang + encoding
define('DEFAULT_LOCALE', 'en_US.UTF-8');
}
// site
if (!defined('SITE_ENCODING')) {
define('SITE_ENCODING', DEFAULT_ENCODING);
}
if (!defined('SITE_LOCALE')) {
define('SITE_LOCALE', DEFAULT_LOCALE);
}
// just set
if (!defined('BASE')) {
define('BASE', str_replace('/configs', '', __DIR__) . DIRECTORY_SEPARATOR);
}
if (!defined('INCLUDES')) {
define('INCLUDES', 'includes' . DIRECTORY_SEPARATOR);
}
if (!defined('LANG')) {
define('LANG', 'lang' . DIRECTORY_SEPARATOR);
}
if (!defined('LOCALE')) {
define('LOCALE', 'locale' . DIRECTORY_SEPARATOR);
}
if (!defined('CONTENT_PATH')) {
define('CONTENT_PATH', 'frontend' . DIRECTORY_SEPARATOR);
}
// array session
$_SESSION = [];
global $_SESSION;
}
/**
* all the test data
*
* @return array
*/
public function setLocaleProvider(): array
{
return [
// 0: locale
// 1: domain
// 2: encoding
// 3: path
// 4: SESSION: DEFAULT_LOCALE
// 5: SESSION: DEFAULT_CHARSET
// 6: expected array
'no params, all default constants' => [
// lang, domain, encoding, path
null, null, null, null,
// SESSION DEFAULT_LOCALE, SESSION: DEFAULT_CHARSET
null, null,
// return array
[
'locale' => 'en_US.UTF-8',
'lang' => 'en_US',
'domain' => 'frontend',
'encoding' => 'UTF-8',
'path' => "/^\/(.*\/)?includes\/locale\/$/",
],
],
'no params, session charset and lang' => [
// lang, domain, encoding, path
null, null, null, null,
// SESSION DEFAULT_LOCALE, SESSION: DEFAULT_CHARSET
'ja_JP', 'UTF-8',
// return array
[
'locale' => 'ja_JP',
'lang' => 'ja_JP',
'domain' => 'frontend',
'encoding' => 'UTF-8',
'path' => "/^\/(.*\/)?includes\/locale\/$/",
],
],
'no params, session charset and lang short' => [
// lang, domain, encoding, path
null, null, null, null,
// SESSION DEFAULT_LOCALE, SESSION: DEFAULT_CHARSET
'ja', 'UTF-8',
// return array
[
'locale' => 'ja',
'lang' => 'ja',
'domain' => 'frontend',
'encoding' => 'UTF-8',
'path' => "/^\/(.*\/)?includes\/locale\/$/",
],
],
// param lang (no sessions)
'locale param only, no sessions' => [
// lang, domain, encoding, path
'ja.UTF-8', null, null, null,
// SESSION DEFAULT_LOCALE, SESSION: DEFAULT_CHARSET
null, null,
// return array
[
'locale' => 'ja.UTF-8',
'lang' => 'ja',
'domain' => 'frontend',
'encoding' => 'UTF-8',
'path' => "/^\/(.*\/)?includes\/locale\/$/",
],
],
// different locale setting
'locale complex param only, no sessions' => [
// lang, domain, encoding, path
'ja_JP.SJIS', null, null, null,
// SESSION DEFAULT_LOCALE, SESSION: DEFAULT_CHARSET
null, null,
// return array
[
'locale' => 'ja_JP.SJIS',
'lang' => 'ja_JP',
'domain' => 'frontend',
'encoding' => 'SJIS',
'path' => "/^\/(.*\/)?includes\/locale\/$/",
],
],
// param lang and domain (no override)
'locale, domain params, no sessions' => [
// lang, domain, encoding, path
'ja.UTF-8', 'admin', null, null,
// SESSION DEFAULT_LOCALE, SESSION: DEFAULT_CHARSET
null, null,
// return array
[
'locale' => 'ja.UTF-8',
'lang' => 'ja',
'domain' => 'admin',
'encoding' => 'UTF-8',
'path' => "/^\/(.*\/)?includes\/locale\/$/",
],
],
// param lang and domain (no override)
'locale, domain, encoding params, no sessions' => [
// lang, domain, encoding, path
'ja.UTF-8', 'admin', 'UTF-8', null,
// SESSION DEFAULT_LOCALE, SESSION: DEFAULT_CHARSET
null, null,
// return array
[
'locale' => 'ja.UTF-8',
'lang' => 'ja',
'domain' => 'admin',
'encoding' => 'UTF-8',
'path' => "/^\/(.*\/)?includes\/locale\/$/",
],
],
// lang, domain, path (no override)
'locale, domain and path, no sessions' => [
// lang, domain, encoding, path
'ja.UTF-8', 'admin', '', __DIR__ . '/locale_other/',
// SESSION DEFAULT_LOCALE, SESSION: DEFAULT_CHARSET
null, null,
// return array
[
'locale' => 'ja.UTF-8',
'lang' => 'ja',
'domain' => 'admin',
'encoding' => 'UTF-8',
'path' => "/^\/(.*\/)?locale_other\/$/",
],
],
// all params set (no override)
'all parameter, no sessions' => [
// lang, domain, encoding, path
'ja', 'admin', 'UTF-8', __DIR__ . '/locale_other/',
// SESSION DEFAULT_LOCALE, SESSION: DEFAULT_CHARSET
null, null,
// return array
[
'locale' => 'ja',
'lang' => 'ja',
'domain' => 'admin',
'encoding' => 'UTF-8',
'path' => "/^\/(.*\/)?locale_other\/$/",
],
],
// param lang and domain (no override)
'long locale, domain, encoding params, no sessions' => [
// lang, domain, encoding, path
'de_CH.UTF-8@euro', 'admin', 'UTF-8', null,
// SESSION DEFAULT_LOCALE, SESSION: DEFAULT_CHARSET
null, null,
// return array
[
'locale' => 'de_CH.UTF-8@euro',
'lang' => 'de_CH',
'domain' => 'admin',
'encoding' => 'UTF-8',
'path' => "/^\/(.*\/)?includes\/locale\/$/",
],
],
// TODO invalid params (bad path) (no override)
// TODO param calls, but with override set
];
}
/**
* Undocumented function
*
* @covers ::setLocale
* @dataProvider setLocaleProvider
* @testdox lang settings lang $language, domain $domain, encoding $encoding, path $path; session lang: $SESSION_DEFAULT_LOCALE, session char: $SESSION_DEFAULT_CHARSET [$_dataName]
*
* @return void
*/
public function testsetLocale(
?string $language,
?string $domain,
?string $encoding,
?string $path,
?string $SESSION_DEFAULT_LOCALE,
?string $SESSION_DEFAULT_CHARSET,
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;
}
// function call
if ($language === null && $domain === null && $encoding === null && $path === null) {
$return_lang_settings = \CoreLibs\Language\GetLocale::setLocale();
} elseif ($language !== null && $domain === null && $encoding === null && $path === null) {
$return_lang_settings = \CoreLibs\Language\GetLocale::setLocale(
$language
);
} elseif ($language !== null && $domain !== null && $encoding === null && $path === null) {
$return_lang_settings = \CoreLibs\Language\GetLocale::setLocale(
$language,
$domain
);
} elseif ($language !== null && $domain !== null && $encoding !== null && $path === null) {
$return_lang_settings = \CoreLibs\Language\GetLocale::setLocale(
$language,
$domain,
$encoding
);
} else {
$return_lang_settings = \CoreLibs\Language\GetLocale::setLocale(
$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 (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']);
}
}
// __END__

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Test class for Output\Form\Elements
* @coversDefaultClass \CoreLibs\Output\Form\Elements
* @testdox \CoreLibs\Output\Form\Elements method tests
*/
final class CoreLibsOutputFormElementsTest extends TestCase
{
/**
* Undocumented function
*
* @testdox Output\Form\Elements Class tests
*
* @return void
*/
public function testOutputFormElements()
{
// $this->assertTrue(true, 'Output Form Elements Tests not implemented');
$this->markTestIncomplete(
'Output\Form\Elements Tests have not yet been implemented'
);
// $this->markTestSkipped('No implementation for Output\Form\Elements at the moment');
}
}
// __END__

View File

@@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Test class for Output\Form\Generate
* @coversDefaultClass \CoreLibs\Output\Form\Generate
* @testdox \CoreLibs\Output\Form\Generate method tests
*/
final class CoreLibsOutputFormGenerateTest extends TestCase
{
/**
* Undocumented function
*
* @testdox Output\Form\Generate Class tests
*
* @return void
*/
public function testOutputFormGenerate()
{
/* $this->assertTrue(true, 'Output Form Generate Tests not implemented');
$this->markTestIncomplete(
'Output\Form\Generate Tests have not yet been implemented'
); */
$this->markTestSkipped('No implementation for Output\Form\Generate at the moment');
}
}
// __END__

View File

@@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Test class for Output\Form\Token
* @coversDefaultClass \CoreLibs\Output\Form\Token
* @testdox \CoreLibs\Output\Form\Token method tests
*/
final class CoreLibsOutputFormTokenTest extends TestCase
{
/**
* Undocumented function
*
* @testdox Output\Form\Token Class tests
*
* @return void
*/
public function testOutputFormToken()
{
// $this->assertTrue(true, 'Output Form Token Tests not implemented');
$this->markTestIncomplete(
'Output\Form\Token Tests have not yet been implemented'
);
// $this->markTestSkipped('No implementation for Output\Form\Token at the moment');
}
}
// __END__

View File

@@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Test class for Output\Image
* @coversDefaultClass \CoreLibs\Output\Image
* @testdox \CoreLibs\Output\Image method tests
*/
final class CoreLibsOutputImageTest extends TestCase
{
/**
* Undocumented function
*
* @testdox Output\Image Class tests
*
* @return void
*/
public function testOutputImage()
{
// $this->assertTrue(true, 'Output Image Tests not implemented');
$this->markTestIncomplete(
'Output\Image Tests have not yet been implemented'
);
// $this->markTestSkipped('No implementation for Output\Image at the moment');
}
}
// __END__

View File

@@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
/**
* Test class for Output\Progressbar
* @coversDefaultClass \CoreLibs\Output\Progressbar
* @testdox \CoreLibs\Output\Progressbar method tests
*/
final class CoreLibsOutputProgressbarTest extends TestCase
{
/**
* Undocumented function
*
* @testdox Output\Progressbar Class tests
*
* @return void
*/
public function testOutputProgressbar()
{
// $this->assertTrue(true, 'Output Progressbar Tests not implemented');
// $this->markTestIncomplete(
// 'Output\Progressbar Tests have not yet been implemented'
// );
$this->markTestSkipped('No implementation for Output\Progressbar at the moment');
}
}
// __END__

File diff suppressed because it is too large Load Diff

View File

View File

View File

@@ -0,0 +1,49 @@
# enviroment file
SOMETHING=A
OTHER="B IS B"
Complex="A B \"D is F"
# COMMENT
HAS_SPACE= "ABC";
# COMMENT AT END
HAS_COMMENT_QUOTES_SPACE="Comment at end with quotes and space" # Comment QE
HAS_COMMENT_QUOTES_NO_SPACE="Comment at end with quotes no space"# Comment QES
HAS_COMMENT_NO_QUOTES_SPACE=Comment at end no quotes and space # Comment NQE
HAS_COMMENT_NO_QUOTES_NO_SPACE=Comment at end no quotes no space# Comment NQES
COMMENT_IN_TEXT_QUOTES="Foo bar # comment in here"
FAILURE = ABC
SIMPLEBOX= A B C
TITLE=1
FOO=1.2
SOME.TEST=Test Var
SOME.LIVE=Live Var
# VAR TESTS -
A_TEST1 = foo
A_TEST2 = ${TEST1:-bar} # TEST1 is set so the value of TEST2 = foo
A_TEST3 = ${TEST4:-bar} # TEST4 is not set so the value of TEST3 = bar
A_TEST5 = null
A_TEST6 = ${TEST5-bar} # TEST5 is set but empty so the value of TEST6 = null
A_TEST7 = ${TEST6:-bar} # TEST5 is set and empty so the value of TEST7 = bar
# VAR TESTS =
B_TEST1 = foo
B_TEST2 = ${TEST1:=bar} # TEST1 is set so the value of TEST2 = foo
B_TEST3 = ${TEST4:=bar} # TEST4 is not set so the value of TEST3 = bar and TEST4 = bar
B_TEST5 = null
B_TEST6 = ${TEST5=bar} # TEST5 is set but emtpy so the value of TEST6 = null
B_TEST7 = ${TEST6=bar} # TEST5 is set and empty so the value of TEST7 = bar and TEST5 = bar
# VAR TEST END
Test="A"
TEST="B"
TEST="D"
LINE="ABC
DEF"
OTHERLINE="ABC
AF\"ASFASDF
MORESHIT"
SUPERLINE=
"asfasfasf"
__FOO_BAR_1 = b
__FOOFOO = f
123123=number
EMPTY=
= flase
asfasdf

View File

@@ -0,0 +1,16 @@
#!/usr/bin/env bash
# if we don't have one base file we are in the wrong folder
if [ ! -f "locale/en_US/LC_MESSAGES/admin.mo" ]; then
echo "Locale file is missing, wrong base folder?"
echo "Should be: 4dev/tests/includes/"
exit;
fi;
for file in $(ls -1 locale/*.po); do
echo $file;
file=$(basename $file .po);
locale=$(echo "${file}" | cut -d "-" -f 1);
domain=$(echo "${file}" | cut -d "-" -f 2);
msgfmt -o locale/${locale}/LC_MESSAGES/${domain}.mo locale/${locale}-${domain}.po;
done;

View File

@@ -0,0 +1,34 @@
msgid ""
msgstr ""
"Project-Id-Version: en_US.UTF-8 LC_MESSAGES admin\n"
"Report-Msgid-Bugs-To: clemens.schwaighofer@egplusww.com\n"
"POT-Creation-Date: 2018-03-28 10:40+0900\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: clemens.schwaighofer@egplusww.co\n"
"Language-Team: E-GRAPHICS COMMUNICATIONS Japan <info.jp@egplusww.com>\n"
"Language: en_US\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
msgid "Original"
msgstr "Translated admin en_US"
msgid "single"
msgid_plural "multi"
msgstr[0] "Multi admin en_US 0"
msgstr[1] "Multi admin en_US 1"
msgstr[2] "Multi admin en_US 2"
msgctxt "context"
msgid "Original"
msgstr "Original context admin en_US"
msgctxt "context"
msgid "single"
msgid_plural "multi"
msgstr[0] "Multi context admin en_US 0"
msgstr[1] "Multi context admin en_US 1"
msgstr[2] "Multi context admin en_US 2"

View File

@@ -0,0 +1,34 @@
msgid ""
msgstr ""
"Project-Id-Version: en_US.UTF-8 LC_MESSAGES frontend\n"
"Report-Msgid-Bugs-To: clemens.schwaighofer@egplusww.com\n"
"POT-Creation-Date: 2018-03-28 10:40+0900\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: clemens.schwaighofer@egplusww.co\n"
"Language-Team: E-GRAPHICS COMMUNICATIONS Japan <info.jp@egplusww.com>\n"
"Language: en_US\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
msgid "Original"
msgstr "Translated frontend en_US"
msgid "single"
msgid_plural "multi"
msgstr[0] "Multi frontend en_US 0"
msgstr[1] "Multi frontend en_US 1"
msgstr[2] "Multi frontend en_US 2"
msgctxt "context"
msgid "Original"
msgstr "Original context frontend en_US"
msgctxt "context"
msgid "single"
msgid_plural "multi"
msgstr[0] "Multi context frontend en_US 0"
msgstr[1] "Multi context frontend en_US 1"
msgstr[2] "Multi context frontend en_US 2"

View File

@@ -0,0 +1,35 @@
msgid ""
msgstr ""
"Project-Id-Version: ja_JP.UTF-8 LC_MESSAGES admin\n"
"Report-Msgid-Bugs-To: clemens.schwaighofer@egplusww.com\n"
"POT-Creation-Date: 2018-03-28 10:40+0900\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: clemens.schwaighofer@egplusww.co\n"
"Language-Team: E-GRAPHICS COMMUNICATIONS Japan <info.jp@egplusww.com>\n"
"Language: ja\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2;\n"
# 0, 1, 2 plural
msgid "Original"
msgstr "Translated admin ja_JP"
msgid "single"
msgid_plural "multi"
msgstr[0] "Multi admin ja_JP 0"
msgstr[1] "Multi admin ja_JP 1"
msgstr[2] "Multi admin ja_JP 2"
msgctxt "context"
msgid "Original"
msgstr "Original context admin ja_JP"
msgctxt "context"
msgid "single"
msgid_plural "multi"
msgstr[0] "Multi context admin ja_JP 0"
msgstr[1] "Multi context admin ja_JP 1"
msgstr[2] "Multi context admin ja_JP 2"

View File

@@ -0,0 +1,35 @@
msgid ""
msgstr ""
"Project-Id-Version: ja_JP.UTF-8 LC_MESSAGES frontend\n"
"Report-Msgid-Bugs-To: clemens.schwaighofer@egplusww.com\n"
"POT-Creation-Date: 2018-03-28 10:40+0900\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: clemens.schwaighofer@egplusww.co\n"
"Language-Team: E-GRAPHICS COMMUNICATIONS Japan <info.jp@egplusww.com>\n"
"Language: ja\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2;\n"
# 0, 1, 2 plural
msgid "Original"
msgstr "Translated frontend ja_JP"
msgid "single"
msgid_plural "multi"
msgstr[0] "Multi frontend ja_JP 0"
msgstr[1] "Multi frontend ja_JP 1"
msgstr[2] "Multi frontend ja_JP 2"
msgctxt "context"
msgid "Original"
msgstr "Original context frontend ja_JP"
msgctxt "context"
msgid "single"
msgid_plural "multi"
msgstr[0] "Multi context frontend ja_JP 0"
msgstr[1] "Multi context frontend ja_JP 1"
msgstr[2] "Multi context frontend ja_JP 2"

3
test/phpunit/log/.gitignore vendored Normal file
View File

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