Compare commits

..

6 Commits

Author SHA1 Message Date
Clemens Schwaighofer
5c461a6fea core composer settings update 2024-10-18 09:29:44 +09:00
Clemens Schwaighofer
2e59e50df8 Set phpstan to max level for update testing 2024-10-18 09:22:02 +09:00
Clemens Schwaighofer
4b45f8d556 Update and fix composer json file, phars file 2024-10-18 09:20:53 +09:00
Clemens Schwaighofer
4b4e655374 Merge branch 'NewFeatures' into phpstan-strict 2024-10-18 09:16:16 +09:00
Clemens Schwaighofer
da0d939068 First phpstan strict check 2023-02-28 06:54:20 +09:00
Clemens Schwaighofer
537bc0a477 add phpstan strict 2023-02-28 06:39:36 +09:00
459 changed files with 39007 additions and 33895 deletions

43
.eslintrc.js Normal file
View File

@@ -0,0 +1,43 @@
module.exports = {
'env': {
'browser': true,
'es6': true,
'commonjs': true,
'jquery': true
},
'extends': 'eslint:recommended',
'parserOptions': {
'ecmaVersion': 6
},
'rules': {
'indent': [
'error',
'tab',
{
'SwitchCase': 1
}
],
'linebreak-style': [
'error',
'unix'
],
'quotes': [
'error',
'single'
],
'semi': [
'error',
'always'
],
'no-console': 'off',
'no-unused-vars': [
'error', {
'vars': 'all',
'args': 'after-used',
'ignoreRestSiblings': false
}
],
// Requires eslint >= v8.14.0
'no-constant-binary-expression': 'error'
}
};

7
.gitignore vendored
View File

@@ -1,8 +1,5 @@
.libs .libs
node_modules/ node_modules/
**/composer.lock composer.lock
**/vendor/ vendor/
tools/ tools/
**/.env
**/.target
package-lock.json

View File

@@ -26,8 +26,8 @@
use Phan\Config; use Phan\Config;
return [ return [
// "target_php_version" => "8.3", // "target_php_version" => "8.2",
"minimum_target_php_version" => "8.3", "minimum_target_php_version" => "8.1",
// turn color on (-C) // turn color on (-C)
"color_issue_messages_if_supported" => true, "color_issue_messages_if_supported" => true,
// If true, missing properties will be created when // If true, missing properties will be created when

View File

@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<phive xmlns="https://phar.io/phive"> <phive xmlns="https://phar.io/phive">
<phar name="phpunit" version="~9.6" installed="9.6.31" location="./tools/phpunit" copy="false"/> <phar name="phpunit" version="^9.6" installed="9.6.21" location="./tools/phpunit" copy="false"/>
<phar name="phpcbf" version="4" installed="4.0.1" location="./tools/phpcbf" copy="false"/> <phar name="phpcbf" version="^3.7.2" installed="3.10.3" location="./tools/phpcbf" copy="false"/>
<phar name="phpcs" version="4" installed="4.0.1" location="./tools/phpcs" copy="false"/> <phar name="phpcs" version="^3.7.2" installed="3.10.3" location="./tools/phpcs" copy="false"/>
<phar name="phpstan" version="^2.0" installed="2.1.33" location="./tools/phpstan" copy="false"/> <phar name="phpstan" version="^1.10.37" installed="1.12.6" location="./tools/phpstan" copy="false"/>
<phar name="phan" version="^5.4.3" installed="5.5.2" location="./tools/phan" copy="false"/> <phar name="phan" version="^5.4.2" installed="5.4.3" location="./tools/phan" copy="false"/>
<phar name="psalm" version="^5.26.1" installed="5.26.1" location="./tools/psalm" copy="false"/> <phar name="psalm" version="^5.15.0" installed="5.24.0" location="./tools/psalm" copy="false"/>
<phar name="phpdox" version="^0.12.0" installed="0.12.0" location="./tools/phpdox" copy="false"/> <phar name="phpdox" version="^0.12.0" installed="0.12.0" location="./tools/phpdox" copy="false"/>
<phar name="phpdocumentor" version="^3.4.2" installed="3.9.1" location="./tools/phpDocumentor" copy="false"/> <phar name="phpdocumentor" version="^3.4.2" installed="3.4.3" location="./tools/phpDocumentor" copy="false"/>
<phar name="php-cs-fixer" version="^3.34.1" installed="3.92.4" location="./tools/php-cs-fixer" copy="false"/> <phar name="php-cs-fixer" version="^3.34.1" installed="3.57.2" location="./tools/php-cs-fixer" copy="false"/>
</phive> </phive>

View File

@@ -1,100 +1,5 @@
#!/bin/env bash base="/storage/var/www/html/developers/clemens/core_data/php_libraries/trunk/";
function error() {
if [ -t 1 ]; then echo "[MAK] ERROR: $*" >&2; fi; exit 0;
}
usage() {
cat <<EOF
Usage: $(basename "${BASH_SOURCE[0]}") [-h | --help] [-p | --php VERSION] [-c | --composer]
Runs phan static analyzer.
If -p is not set, the default intalled PHP is used.
Available options:
-h, --help Print this help and exit
-p, --php VERSION Chose PHP version in the form of "N.N", if not found will exit
-c, --composer Use composer version and not the default phives bundle
EOF
exit
}
BASE_PATH=$(pwd)"/";
PHP_BIN_PATH=$(which php);
if [ -z "${PHP_BIN_PATH}" ]; then
echo "Cannot find php binary";
exit;
fi;
DEFAULT_PHP_VERSION=$(${PHP_BIN_PATH} -r "echo PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION;");
if [ -z "${DEFAULT_PHP_VERSION}" ]; then
echo "Cannot set default PHP version";
exit;
fi;
php_version="";
no_php_version=0;
use_composer=0;
while [ -n "${1-}" ]; do
case "${1}" in
-p | --php)
php_version="${2-}";
shift
;;
-c | --composer)
use_composer=1;
shift
;;
-h | --help)
usage
;;
# invalid option
-?*)
error "[!] Unknown option: '$1'."
;;
esac
shift;
done;
if [ -z "${php_version}" ]; then
php_version="${DEFAULT_PHP_VERSION}";
no_php_version=1;
fi;
php_bin="${PHP_BIN_PATH}${php_version}";
echo "Use PHP Version: ${php_version}";
if [ "${use_composer}" -eq 1 ]; then
echo "Use composer installed";
else
echo "Use phive installed";
fi;
if [ ! -f "${php_bin}" ]; then
echo "Set php ${php_bin} does not exist";
exit;
fi;
# must be run in ${base} # must be run in ${base}
cd "$BASE_PATH" || exit; cd $base;
export PHAN_DISABLE_XDEBUG_WARN=1; ${base}tools/phan --progress-bar -C --analyze-twice;
PHAN_CALL=( cd ~;
"${php_bin}"
);
if [ "${use_composer}" -eq 1 ]; then
PHAN_CALL+=("${BASE_PATH}vendor/bin/phan");
else
PHAN_CALL+=("${BASE_PATH}tools/phan");
fi;
PHAN_CALL+=(
"--progress-bar"
"-C"
"--analyze-twice"
)
"${PHAN_CALL[@]}";
if [ "${no_php_version}" -eq 0 ]; then
echo "*** CALLED WITH PHP ${php_bin} ***";
${php_bin} --version;
else
echo "Default PHP used: $(php --version)";
fi;
cd ~ || exit;
# __END__

View File

@@ -1,92 +1,5 @@
#!/bin/env bash base="/storage/var/www/html/developers/clemens/core_data/php_libraries/trunk/";
# must be run in ${base}
function error() { cd $base;
if [ -t 1 ]; then echo "[MAK] ERROR: $*" >&2; fi; exit 0; ${base}tools/phpstan;
} cd ~;
usage() {
cat <<EOF
Usage: $(basename "${BASH_SOURCE[0]}") [-h] [-h | --help] [-p | --php VERSION] [-c | --composer]
Runs phan static analyzer.
If -p is not set, the default intalled PHP is used.
Available options:
-h, --help Print this help and exit
-p, --php VERSION Chose PHP version in the form of "N.N", if not found will exit
-c, --composer Use composer version and not the default phives bundle
EOF
exit
}
BASE_PATH=$(pwd)"/";
PHP_BIN_PATH=$(which php);
if [ -z "${PHP_BIN_PATH}" ]; then
echo "Cannot find php binary";
exit;
fi;
DEFAULT_PHP_VERSION=$(${PHP_BIN_PATH} -r "echo PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION;");
if [ -z "${DEFAULT_PHP_VERSION}" ]; then
echo "Cannot set default PHP version";
exit;
fi;
php_version="";
no_php_version=0;
use_composer=0;
while [ -n "${1-}" ]; do
case "${1}" in
-p | --php)
php_version="${2-}";
shift
;;
-c | --composer)
use_composer=1;
shift
;;
-h | --help)
usage
;;
# invalid option
-?*)
error "[!] Unknown option: '$1'."
;;
esac
shift;
done;
if [ -z "${php_version}" ]; then
php_version="${DEFAULT_PHP_VERSION}";
no_php_version=1;
fi;
php_bin="${PHP_BIN_PATH}${php_version}";
echo "Use PHP Version: ${php_version}";
if [ "${use_composer}" -eq 1 ]; then
echo "Use composer installed";
else
echo "Use phive installed";
fi;
if [ ! -f "${php_bin}" ]; then
echo "Set php ${php_bin} does not exist";
exit;
fi;
BASE_PATH=$(pwd)"/";
cd "$BASE_PATH" || exit;
PHPSTAN_CALL=(
"${php_bin}"
);
if [ "${use_composer}" -eq 1 ]; then
PHPSTAN_CALL+=("${BASE_PATH}vendor/bin/phpstan");
else
PHPSTAN_CALL+=("${BASE_PATH}tools/phpstan");
fi;
"${PHPSTAN_CALL[@]}";
if [ "${no_php_version}" -eq 0 ]; then
echo "*** CALLED WITH PHP ${php_bin} ***";
${php_bin} --version;
else
echo "Default PHP used: $(php --version)";
fi;
cd ~ || exit;

View File

@@ -1,130 +1,49 @@
#!/bin/env bash #!/bin/env bash
function error() { base="/storage/var/www/html/developers/clemens/core_data/php_libraries/trunk/";
if [ -t 1 ]; then echo "[MAK] ERROR: $*" >&2; fi; exit 0;
}
usage() {
cat <<EOF
Usage: $(basename "${BASH_SOURCE[0]}") [-h | --help] [-p | --php VERSION] [-c | --composer] [-t | --testdox] [-v | --verbose]
Runs all the PHP unit tests.
If -p is not set, the default intalled PHP is used.
Available options:
-h, --help Print this help and exit
-t, --testdox Enable testdox output for PHPunit
-v, --verbose Enable verbose output for PHPunit
-c, --composer Use composer version and not the default phives bundle
-p, --php VERSION Chose PHP version in the form of "N.N", if not found will exit
-C, --coverage Generate code coverage report in text format (default: disabled)
EOF
exit
}
# set base variables
BASE_PATH=$(pwd)"/";
PHPUNIT_CONFIG="${BASE_PATH}phpunit.xml";
PHP_BIN_PATH=$(which php);
if [ -z "${PHP_BIN_PATH}" ]; then
echo "Cannot find php binary";
exit;
fi;
DEFAULT_PHP_VERSION=$(${PHP_BIN_PATH} -r "echo PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION;");
if [ -z "${DEFAULT_PHP_VERSION}" ]; then
echo "Cannot set default PHP version";
exit;
fi;
# -c phpunit.xml # -c phpunit.xml
# --testdox # --testdox
# call with "-tt" to give verbose testdox output # call with "t" to give verbose testdox output
# SUPPORTED: https://www.php.net/supported-versions.php # SUPPORTED: https://www.php.net/supported-versions.php
# call with -p <php version number> to force a certain php version # call with php version number to force a certain php version
opt_testdox=""; opt_testdox="";
opt_verbose=""; if [ "${1}" = "t" ] || [ "${2}" = "t" ]; then
php_version=""; opt_testdox="--testdox";
no_php_version=0; fi;
use_composer=0; php_bin="";
opt_generate_coverage=""; if [ -n "${1}" ]; then
while [ -n "${1-}" ]; do
case "${1}" in case "${1}" in
-t | --testdox) # "7.3") php_bin="/usr/bin/php7.3 "; ;;
opt_testdox="--testdox"; # "7.4") php_bin="/usr/bin/php7.4 "; ;;
;; # "8.0") php_bin="/usr/bin/php8.0 "; ;;
-v | --verbose) # "8.1") php_bin="/usr/bin/php8.1 "; ;;
opt_verbose="--verbose"; "8.2") php_bin="/usr/bin/php8.2 "; ;;
;; "8.3") php_bin="/usr/bin/php8.4 "; ;;
-c | --composer) *) echo "Not support PHP: ${1}"; exit; ;;
use_composer=1; esac;
shift
;;
-C | --coverage)
opt_generate_coverage="--coverage-text";
shift
;;
-p | --php)
php_version="${2-}";
shift
;;
-h | --help)
usage
;;
# invalid option
-?*)
error "[!] Unknown option: '$1'."
;;
esac
shift;
done;
if [ -z "${php_version}" ]; then
php_version="${DEFAULT_PHP_VERSION}";
no_php_version=1;
fi; fi;
php_bin="${PHP_BIN_PATH}${php_version}"; if [ -n "${2}" ] && [ -z "${php_bin}" ]; then
echo "Use PHP Version: ${php_version}"; case "${2}" in
if [ "${use_composer}" -eq 1 ]; then # "7.3") php_bin="/usr/bin/php7.3 "; ;;
echo "Use composer installed"; # "7.4") php_bin="/usr/bin/php7.4 "; ;;
else # "8.0") php_bin="/usr/bin/php8.0 "; ;;
echo "Use phive installed"; # "8.1") php_bin="/usr/bin/php8.1 "; ;;
fi; "8.2") php_bin="/usr/bin/php8.2 "; ;;
"8.3") php_bin="/usr/bin/php8.3 "; ;;
if [ ! -f "${php_bin}" ]; then *) echo "Not support PHP: ${1}"; exit; ;;
echo "Set php ${php_bin} does not exist"; esac;
exit;
fi; fi;
# Note 4dev/tests/bootstrap.php has to be set as bootstrap file in phpunit.xml # Note 4dev/tests/bootstrap.php has to be set as bootstrap file in phpunit.xml
PHPUNIT_CALL=( phpunit_call="${php_bin}${base}tools/phpunit ${opt_testdox} -c ${base}phpunit.xml ${base}4dev/tests/";
"${php_bin}"
);
if [ "${use_composer}" -eq 1 ]; then
PHPUNIT_CALL+=("${BASE_PATH}vendor/bin/phpunit");
else
PHPUNIT_CALL+=("${BASE_PATH}tools/phpunit");
fi;
if [ -n "${opt_generate_coverage}" ]; then
echo "Will run coverage report";
export XDEBUG_MODE=coverage
fi;
PHPUNIT_CALL+=(
"${opt_testdox}"
"${opt_verbose}"
"${opt_generate_coverage}"
"-c" "${PHPUNIT_CONFIG}"
"${BASE_PATH}4dev/tests/"
);
"${PHPUNIT_CALL[@]}" || exit;
echo -e "\nPHPUnit Config: ${PHPUNIT_CONFIG}"; ${phpunit_call};
if [ "${no_php_version}" -eq 0 ]; then
echo "*** CALLED WITH PHP ${php_bin} ***"; if [ ! -z "${php_bin}" ]; then
${php_bin} --version; echo "CALLED WITH PHP: ${php_bin}"$(${php_bin} --version);
else else
echo "Default PHP used: $(php --version)"; echo "Default PHP used: "$(php --version);
fi; fi;
# __END__ # __END__

View File

@@ -13,7 +13,7 @@ if [ "${GO}" != "go" ]; then
fi; fi;
BASE="/storage/var/www/html/developers/clemens/core_data/"; BASE="/storage/var/www/html/developers/clemens/core_data/";
SOURCE="${BASE}php_libraries/master/" SOURCE="${BASE}php_libraries/trunk/"
TARGET="${BASE}composer-packages/CoreLibs-Composer-All/" TARGET="${BASE}composer-packages/CoreLibs-Composer-All/"
rsync ${DRY_RUN}-Plzvrupt --stats --delete ${SOURCE}4dev/tests/ ${TARGET}test/phpunit/ rsync ${DRY_RUN}-Plzvrupt --stats --delete ${SOURCE}4dev/tests/ ${TARGET}test/phpunit/

View File

@@ -5,9 +5,9 @@ RETURNS TRIGGER AS
$$ $$
BEGIN BEGIN
IF TG_OP = 'INSERT' THEN IF TG_OP = 'INSERT' THEN
NEW.date_created := clock_timestamp(); NEW.date_created := 'now';
ELSIF TG_OP = 'UPDATE' THEN ELSIF TG_OP = 'UPDATE' THEN
NEW.date_updated := clock_timestamp(); NEW.date_updated := 'now';
END IF; END IF;
RETURN NEW; RETURN NEW;
END; END;

View File

@@ -7,11 +7,10 @@ DECLARE
random_length INT = 25; -- that should be long enough random_length INT = 25; -- that should be long enough
BEGIN BEGIN
IF TG_OP = 'INSERT' THEN IF TG_OP = 'INSERT' THEN
NEW.date_created := clock_timestamp(); NEW.date_created := 'now';
NEW.cuid := random_string(random_length); NEW.cuid := random_string(random_length);
NEW.cuuid := gen_random_uuid();
ELSIF TG_OP = 'UPDATE' THEN ELSIF TG_OP = 'UPDATE' THEN
NEW.date_updated := clock_timestamp(); NEW.date_updated := 'now';
END IF; END IF;
RETURN NEW; RETURN NEW;
END; END;

View File

@@ -8,12 +8,12 @@ DECLARE
random_length INT = 32; -- long for massive data random_length INT = 32; -- long for massive data
BEGIN BEGIN
IF TG_OP = 'INSERT' THEN IF TG_OP = 'INSERT' THEN
NEW.date_created := clock_timestamp(); NEW.date_created := 'now';
IF NEW.uid IS NULL THEN IF NEW.uid IS NULL THEN
NEW.uid := random_string(random_length); NEW.uid := random_string(random_length);
END IF; END IF;
ELSIF TG_OP = 'UPDATE' THEN ELSIF TG_OP = 'UPDATE' THEN
NEW.date_updated := clock_timestamp(); NEW.date_updated := 'now';
END IF; END IF;
RETURN NEW; RETURN NEW;
END; END;

View File

@@ -0,0 +1,19 @@
-- adds the created or updated date tags
-- OLD, DEPRECATED, use set_generic.sql
-- CREATE OR REPLACE FUNCTION set_generic()
-- RETURNS TRIGGER AS
-- $$
-- BEGIN
-- IF TG_OP = 'INSERT' THEN
-- NEW.date_created := clock_timestamp();
-- NEW.user_created := current_user;
-- ELSIF TG_OP = 'UPDATE' THEN
-- NEW.date_updated := clock_timestamp();
-- NEW.user_updated := current_user;
-- END IF;
-- RETURN NEW;
-- END;
-- $$
-- LANGUAGE 'plpgsql';

View File

@@ -1,110 +0,0 @@
-- Upgrade serial to identity type
--
-- Original: https://www.enterprisedb.com/blog/postgresql-10-identity-columns-explained#section-6
--
-- @param reclass tbl The table where the column is located, prefix with 'schema.' if different schema
-- @param name col The column to be changed
-- @param varchar identity_type [default=a] Allowed a, d, assigned, default
-- @param varchar col_type [default=''] Allowed smallint, int, bigint, int2, int4, int8
-- @returns varchar status tring
-- @raises EXCEPTON on column not found, no linked sequence, more than one linked sequence found, invalid col type
--
CREATE OR REPLACE FUNCTION upgrade_serial_to_identity(
tbl regclass,
col name,
identity_type varchar = 'a',
col_type varchar = ''
)
RETURNS varchar
LANGUAGE plpgsql
AS $$
DECLARE
colnum SMALLINT;
seqid OID;
count INT;
col_type_oid INT;
col_type_len INT;
current_col_atttypid OID;
current_col_attlen INT;
status_string VARCHAR;
BEGIN
-- switch between always (default) or default identiy type
IF identity_type NOT IN ('a', 'd', 'assigned', 'default') THEN
identity_type := 'a';
ELSE
IF identity_type = 'default' THEN
identity_type := 'd';
ELSIF identity_type = 'assigned' THEN
identity_type := 'a';
END IF;
END IF;
-- find column number, attribute oid and attribute len
SELECT attnum, atttypid, attlen
INTO colnum, current_col_atttypid, current_col_attlen
FROM pg_attribute
WHERE attrelid = tbl AND attname = col;
IF NOT FOUND THEN
RAISE EXCEPTION 'column does not exist';
END IF;
-- find sequence
SELECT INTO seqid objid
FROM pg_depend
WHERE (refclassid, refobjid, refobjsubid) = ('pg_class'::regclass, tbl, colnum)
AND classid = 'pg_class'::regclass AND objsubid = 0
AND deptype = 'a';
GET DIAGNOSTICS count = ROW_COUNT;
IF count < 1 THEN
RAISE EXCEPTION 'no linked sequence found';
ELSIF count > 1 THEN
RAISE EXCEPTION 'more than one linked sequence found';
END IF;
IF col_type <> '' AND col_type NOT IN ('smallint', 'int', 'bigint', 'int2', 'int4', 'int8') THEN
RAISE EXCEPTION 'Invalid col type: %', col_type;
END IF;
-- drop the default
EXECUTE 'ALTER TABLE ' || tbl || ' ALTER COLUMN ' || quote_ident(col) || ' DROP DEFAULT';
-- change the dependency between column and sequence to internal
UPDATE pg_depend
SET deptype = 'i'
WHERE (classid, objid, objsubid) = ('pg_class'::regclass, seqid, 0)
AND deptype = 'a';
-- mark the column as identity column
UPDATE pg_attribute
-- set to 'd' for default
SET attidentity = identity_type
WHERE attrelid = tbl
AND attname = col;
status_string := 'Updated to identity for table "' || tbl || '" and columen "' || col || '" with type "' || identity_type || '"';
-- set type if requested and not empty
IF col_type <> '' THEN
-- rewrite smallint, int, bigint
IF col_type = 'smallint' THEN
col_type := 'int2';
ELSIF col_type = 'int' THEN
col_type := 'int4';
ELSIF col_type = 'bigint' THEN
col_type := 'int8';
END IF;
-- get the length and oid for selected
SELECT oid, typlen INTO col_type_oid, col_type_len FROM pg_type WHERE typname = col_type;
-- set only if diff or hight
IF current_col_atttypid <> col_type_oid AND col_type_len > current_col_attlen THEN
status_string := status_string || '. Change col type: ' || col_type;
-- update type
UPDATE pg_attribute
SET
atttypid = col_type_oid, attlen = col_type_len
WHERE attrelid = tbl
AND attname = col;
END IF;
END IF;
RETURN status_string;
END;
$$;

View File

@@ -7,7 +7,7 @@
-- DROP TABLE edit_access; -- DROP TABLE edit_access;
CREATE TABLE edit_access ( CREATE TABLE edit_access (
edit_access_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, edit_access_id SERIAL PRIMARY KEY,
enabled SMALLINT NOT NULL DEFAULT 0, enabled SMALLINT NOT NULL DEFAULT 0,
protected SMALLINT DEFAULT 0, protected SMALLINT DEFAULT 0,
deleted SMALLINT DEFAULT 0, deleted SMALLINT DEFAULT 0,

View File

@@ -7,7 +7,7 @@
-- DROP TABLE edit_access_data; -- DROP TABLE edit_access_data;
CREATE TABLE edit_access_data ( CREATE TABLE edit_access_data (
edit_access_data_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, edit_access_data_id SERIAL PRIMARY KEY,
edit_access_id INT NOT NULL, edit_access_id INT NOT NULL,
FOREIGN KEY (edit_access_id) REFERENCES edit_access (edit_access_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (edit_access_id) REFERENCES edit_access (edit_access_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
enabled SMALLINT NOT NULL DEFAULT 0, enabled SMALLINT NOT NULL DEFAULT 0,

View File

@@ -8,7 +8,7 @@
-- DROP TABLE edit_access_right; -- DROP TABLE edit_access_right;
CREATE TABLE edit_access_right ( CREATE TABLE edit_access_right (
edit_access_right_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, edit_access_right_id SERIAL PRIMARY KEY,
name VARCHAR, name VARCHAR,
level SMALLINT, level SMALLINT,
type VARCHAR, type VARCHAR,

View File

@@ -7,7 +7,7 @@
-- DROP TABLE edit_access_user; -- DROP TABLE edit_access_user;
CREATE TABLE edit_access_user ( CREATE TABLE edit_access_user (
edit_access_user_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, edit_access_user_id SERIAL PRIMARY KEY,
edit_access_id INT NOT NULL, edit_access_id INT NOT NULL,
FOREIGN KEY (edit_access_id) REFERENCES edit_access (edit_access_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (edit_access_id) REFERENCES edit_access (edit_access_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_user_id INT NOT NULL, edit_user_id INT NOT NULL,

View File

@@ -8,7 +8,6 @@
-- DROP TABLE edit_generic; -- DROP TABLE edit_generic;
CREATE TABLE edit_generic ( CREATE TABLE edit_generic (
cuid VARCHAR, cuid VARCHAR,
cuuid UUID DEFAULT gen_random_uuid(),
date_created TIMESTAMP WITHOUT TIME ZONE DEFAULT clock_timestamp(), date_created TIMESTAMP WITHOUT TIME ZONE DEFAULT clock_timestamp(),
date_updated TIMESTAMP WITHOUT TIME ZONE date_updated TIMESTAMP WITHOUT TIME ZONE
); );

View File

@@ -7,7 +7,7 @@
-- DROP TABLE edit_group; -- DROP TABLE edit_group;
CREATE TABLE edit_group ( CREATE TABLE edit_group (
edit_group_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, edit_group_id SERIAL PRIMARY KEY,
edit_scheme_id INT, edit_scheme_id INT,
FOREIGN KEY (edit_scheme_id) REFERENCES edit_scheme (edit_scheme_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (edit_scheme_id) REFERENCES edit_scheme (edit_scheme_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_access_right_id INT NOT NULL, edit_access_right_id INT NOT NULL,

View File

@@ -8,7 +8,7 @@
-- DROP TABLE edit_language; -- DROP TABLE edit_language;
CREATE TABLE edit_language ( CREATE TABLE edit_language (
edit_language_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, edit_language_id SERIAL PRIMARY KEY,
enabled SMALLINT NOT NULL DEFAULT 0, enabled SMALLINT NOT NULL DEFAULT 0,
lang_default SMALLINT NOT NULL DEFAULT 0, lang_default SMALLINT NOT NULL DEFAULT 0,
long_name VARCHAR, long_name VARCHAR,

View File

@@ -7,54 +7,35 @@
-- DROP TABLE edit_log; -- DROP TABLE edit_log;
CREATE TABLE edit_log ( CREATE TABLE edit_log (
edit_log_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, edit_log_id SERIAL PRIMARY KEY,
euid INT, -- this is a foreign key, but I don't nedd to reference to it euid INT, -- this is a foreign key, but I don't nedd to reference to it
FOREIGN KEY (euid) REFERENCES edit_user (edit_user_id) MATCH FULL ON UPDATE CASCADE ON DELETE SET NULL, FOREIGN KEY (euid) REFERENCES edit_user (edit_user_id) MATCH FULL ON UPDATE CASCADE ON DELETE SET NULL,
eucuid VARCHAR,
eucuuid UUID, -- this is the one we want to use, full UUIDv4 from the edit user table
-- date_created equal, but can be overridden
event_date TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
-- session ID if set
session_id VARCHAR,
-- username
username VARCHAR, username VARCHAR,
-- DEPRECATED [password]
password VARCHAR, password VARCHAR,
ip_address JSONB, -- REMOTE_IP and all other IPs (X_FORWARD, etc) as JSON block event_date TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
-- DEPRECATED [ip] ip VARCHAR,
ip VARCHAR, -- just the REMOTE_IP, full set see ip_address
-- string blocks, general
error TEXT, error TEXT,
event TEXT, event TEXT,
-- bytea or string type storage of any data
data_binary BYTEA, data_binary BYTEA,
data TEXT, data TEXT,
-- set page name only
page VARCHAR, page VARCHAR,
-- various info data sets action VARCHAR,
action_id VARCHAR,
action_yes VARCHAR,
action_flag VARCHAR,
action_menu VARCHAR,
action_loaded VARCHAR,
action_value VARCHAR,
action_type VARCHAR,
action_error VARCHAR,
user_agent VARCHAR, user_agent VARCHAR,
referer VARCHAR, referer VARCHAR,
script_name VARCHAR, script_name VARCHAR,
query_string VARCHAR, query_string VARCHAR,
request_scheme VARCHAR, -- http or https
server_name VARCHAR, server_name VARCHAR,
http_host VARCHAR, http_host VARCHAR,
http_data JSONB, http_accept VARCHAR,
-- DEPRECATED [http*] http_accept_charset VARCHAR,
http_accept VARCHAR, -- in http_data http_accept_encoding VARCHAR,
http_accept_charset VARCHAR, -- in http_data session_id VARCHAR
http_accept_encoding VARCHAR, -- in http_data
-- any action var, -> same set in action_data as JSON
action_data JSONB,
-- DEPRECATED [action*]
action VARCHAR, -- in action_data
action_id VARCHAR, -- in action_data
action_sub_id VARCHAR, -- in action_data
action_yes VARCHAR, -- in action_data
action_flag VARCHAR, -- in action_data
action_menu VARCHAR, -- in action_data
action_loaded VARCHAR, -- in action_data
action_value VARCHAR, -- in action_data
action_type VARCHAR, -- in action_data
action_error VARCHAR -- in action_data
) INHERITS (edit_generic) WITHOUT OIDS; ) INHERITS (edit_generic) WITHOUT OIDS;

View File

@@ -7,8 +7,10 @@
-- DROP TABLE edit_menu_group; -- DROP TABLE edit_menu_group;
CREATE TABLE edit_menu_group ( CREATE TABLE edit_menu_group (
edit_menu_group_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, edit_menu_group_id SERIAL PRIMARY KEY,
name VARCHAR, name VARCHAR,
flag VARCHAR, flag VARCHAR,
order_number INT NOT NULL order_number INT NOT NULL
) INHERITS (edit_generic) WITHOUT OIDS; ) INHERITS (edit_generic) WITHOUT OIDS;

View File

@@ -7,7 +7,7 @@
-- DROP TABLE edit_page; -- DROP TABLE edit_page;
CREATE TABLE edit_page ( CREATE TABLE edit_page (
edit_page_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, edit_page_id SERIAL PRIMARY KEY,
content_alias_edit_page_id INT, -- alias for page content, if the page content is defined on a different page, ege for ajax backend pages content_alias_edit_page_id INT, -- alias for page content, if the page content is defined on a different page, ege for ajax backend pages
FOREIGN KEY (content_alias_edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE RESTRICT ON UPDATE CASCADE, FOREIGN KEY (content_alias_edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE RESTRICT ON UPDATE CASCADE,
filename VARCHAR, filename VARCHAR,

View File

@@ -7,7 +7,7 @@
-- DROP TABLE edit_page_access; -- DROP TABLE edit_page_access;
CREATE TABLE edit_page_access ( CREATE TABLE edit_page_access (
edit_page_access_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, edit_page_access_id SERIAL PRIMARY KEY,
edit_group_id INT NOT NULL, edit_group_id INT NOT NULL,
FOREIGN KEY (edit_group_id) REFERENCES edit_group (edit_group_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (edit_group_id) REFERENCES edit_group (edit_group_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_page_id INT NOT NULL, edit_page_id INT NOT NULL,
@@ -16,3 +16,5 @@ CREATE TABLE edit_page_access (
FOREIGN KEY (edit_access_right_id) REFERENCES edit_access_right (edit_access_right_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (edit_access_right_id) REFERENCES edit_access_right (edit_access_right_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
enabled SMALLINT NOT NULL DEFAULT 0 enabled SMALLINT NOT NULL DEFAULT 0
) INHERITS (edit_generic) WITHOUT OIDS; ) INHERITS (edit_generic) WITHOUT OIDS;

View File

@@ -8,7 +8,7 @@
-- DROP TABLE edit_page_content; -- DROP TABLE edit_page_content;
CREATE TABLE edit_page_content ( CREATE TABLE edit_page_content (
edit_page_content_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, edit_page_content_id SERIAL PRIMARY KEY,
edit_page_id INT NOT NULL, edit_page_id INT NOT NULL,
FOREIGN KEY (edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_access_right_id INT NOT NULL, edit_access_right_id INT NOT NULL,

View File

@@ -7,7 +7,7 @@
-- DROP TABLE edit_query_string; -- DROP TABLE edit_query_string;
CREATE TABLE edit_query_string ( CREATE TABLE edit_query_string (
edit_query_string_id SERIAINT GENERATED ALWAYS AS IDENTITYL PRIMARY KEY, edit_query_string_id SERIAL PRIMARY KEY,
edit_page_id INT NOT NULL, edit_page_id INT NOT NULL,
FOREIGN KEY (edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
enabled SMALLINT NOT NULL DEFAULT 0, enabled SMALLINT NOT NULL DEFAULT 0,

View File

@@ -7,7 +7,7 @@
-- DROP TABLE edit_scheme; -- DROP TABLE edit_scheme;
CREATE TABLE edit_scheme ( CREATE TABLE edit_scheme (
edit_scheme_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, edit_scheme_id SERIAL PRIMARY KEY,
enabled SMALLINT NOT NULL DEFAULT 0, enabled SMALLINT NOT NULL DEFAULT 0,
name VARCHAR, name VARCHAR,
header_color VARCHAR, header_color VARCHAR,

View File

@@ -7,7 +7,7 @@
-- DROP TABLE edit_user; -- DROP TABLE edit_user;
CREATE TABLE edit_user ( CREATE TABLE edit_user (
edit_user_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, edit_user_id SERIAL PRIMARY KEY,
connect_edit_user_id INT, -- possible reference to other user connect_edit_user_id INT, -- possible reference to other user
FOREIGN KEY (connect_edit_user_id) REFERENCES edit_user (edit_user_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (connect_edit_user_id) REFERENCES edit_user (edit_user_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_language_id INT NOT NULL, edit_language_id INT NOT NULL,
@@ -35,10 +35,11 @@ CREATE TABLE edit_user (
strict SMALLINT DEFAULT 0, strict SMALLINT DEFAULT 0,
locked SMALLINT DEFAULT 0, locked SMALLINT DEFAULT 0,
protected SMALLINT NOT NULL DEFAULT 0, protected SMALLINT NOT NULL DEFAULT 0,
-- legacy, debug flags
debug SMALLINT NOT NULL DEFAULT 0,
db_debug SMALLINT NOT NULL DEFAULT 0,
-- is admin user -- is admin user
admin SMALLINT NOT NULL DEFAULT 0, admin SMALLINT NOT NULL DEFAULT 0,
-- force lgout counter
force_logout INT DEFAULT 0,
-- last login log -- last login log
last_login TIMESTAMP WITHOUT TIME ZONE, last_login TIMESTAMP WITHOUT TIME ZONE,
-- login error -- login error
@@ -75,8 +76,9 @@ COMMENT ON COLUMN edit_user.deleted IS 'Login is deleted (master switch), overri
COMMENT ON COLUMN edit_user.strict IS 'If too many failed logins user will be locked, default off'; COMMENT ON COLUMN edit_user.strict IS 'If too many failed logins user will be locked, default off';
COMMENT ON COLUMN edit_user.locked IS 'Locked from too many wrong password logins'; COMMENT ON COLUMN edit_user.locked IS 'Locked from too many wrong password logins';
COMMENT ON COLUMN edit_user.protected IS 'User can only be chnaged by admin user'; COMMENT ON COLUMN edit_user.protected IS 'User can only be chnaged by admin user';
COMMENT ON COLUMN edit_user.debug IS 'Turn debug flag on (legacy)';
COMMENT ON COLUMN edit_user.db_debug IS 'Turn DB debug flag on (legacy)';
COMMENT ON COLUMN edit_user.admin IS 'If set, this user is SUPER admin'; COMMENT ON COLUMN edit_user.admin IS 'If set, this user is SUPER admin';
COMMENT ON COLUMN edit_user.force_logout IS 'Counter for forced log out, if this one is higher than the session set one the session gets terminated';
COMMENT ON COLUMN edit_user.last_login IS 'Last succesfull login tiemstamp'; COMMENT ON COLUMN edit_user.last_login IS 'Last succesfull login tiemstamp';
COMMENT ON COLUMN edit_user.login_error_count IS 'Number of failed logins, reset on successful login'; COMMENT ON COLUMN edit_user.login_error_count IS 'Number of failed logins, reset on successful login';
COMMENT ON COLUMN edit_user.login_error_date_last IS 'Last login error date'; COMMENT ON COLUMN edit_user.login_error_date_last IS 'Last login error date';

View File

@@ -7,7 +7,7 @@
-- DROP TABLE edit_visible_group; -- DROP TABLE edit_visible_group;
CREATE TABLE edit_visible_group ( CREATE TABLE edit_visible_group (
edit_visible_group_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, edit_visible_group_id SERIAL PRIMARY KEY,
name VARCHAR, name VARCHAR,
flag VARCHAR flag VARCHAR
) INHERITS (edit_generic) WITHOUT OIDS; ) INHERITS (edit_generic) WITHOUT OIDS;

View File

@@ -9,6 +9,5 @@
CREATE TABLE generic ( CREATE TABLE generic (
date_created TIMESTAMP WITHOUT TIME ZONE DEFAULT clock_timestamp(), date_created TIMESTAMP WITHOUT TIME ZONE DEFAULT clock_timestamp(),
date_updated TIMESTAMP WITHOUT TIME ZONE, date_updated TIMESTAMP WITHOUT TIME ZONE,
uuid UUID DEFAULT gen_random_uuid(),
uid VARCHAR uid VARCHAR
); );

View File

@@ -1,65 +0,0 @@
<?php // phpcs:ignore PSR1.Files.SideEffects
/**
* AUTHOR: Clemens Schwaighofer
* CREATED: Ymd
* DESCRIPTION:
* DescriptionHere
*/
declare(strict_types=1);
/**
* build return json
*
* @param array<string,mixed> $http_headers
* @param ?string $body
* @return string
*/
function buildContent(array $http_headers, ?string $body): string
{
if (is_string($body) && !empty($body)) {
$_body = json_decode($body, true);
if (!is_array($_body)) {
$body = [$body];
} else {
$body = $_body;
}
} elseif (is_string($body)) {
$body = [];
}
return json_encode([
'HEADERS' => $http_headers,
"REQUEST_TYPE" => $_SERVER['REQUEST_METHOD'],
"PARAMS" => $_GET,
"BODY" => $body,
]);
}
$http_headers = array_filter($_SERVER, function ($value, $key) {
if (str_starts_with($key, 'HTTP_')) {
return true;
}
}, ARRAY_FILTER_USE_BOTH);
header("Content-Type: application/json; charset=UTF-8");
// if the header has Authorization and RunAuthTest then exit with 401
if (!empty($http_headers['HTTP_AUTHORIZATION']) && !empty($http_headers['HTTP_RUNAUTHTEST'])) {
header("HTTP/1.1 401 Unauthorized");
print buildContent($http_headers, '{"code": 401, "content": {"Error": "Not Authorized"}}');
exit(1);
}
// if server request type is get set file_get to null -> no body
if ($_SERVER['REQUEST_METHOD'] == "GET") {
$file_get = null;
} elseif (($file_get = file_get_contents('php://input')) === false) {
header("HTTP/1.1 404 Not Found");
print buildContent($http_headers, '{"code": 404, "content": {"Error": "file_get_contents failed"}}');
exit(1);
}
print buildContent($http_headers, $file_get);
// __END__

View File

@@ -12,8 +12,6 @@ Not yet covered tests:
- loginGetLocale - loginGetLocale
- loginGetHeaderColor - loginGetHeaderColor
- loginGetPages - loginGetPages
- loginGetPageLookupList
- loginPageAccessAllowed
- loginGetEuid - loginGetEuid
*/ */
@@ -24,12 +22,8 @@ Not yet covered tests:
*/ */
final class CoreLibsACLLoginTest extends TestCase final class CoreLibsACLLoginTest extends TestCase
{ {
private static \CoreLibs\DB\IO $db; private static $db;
private static \CoreLibs\Logging\Logging $log; private static $log;
private static string $edit_access_cuid;
private static string $edit_user_cuid;
private static string $edit_user_cuuid;
/** /**
* start DB conneciton, setup DB, etc * start DB conneciton, setup DB, etc
@@ -114,46 +108,21 @@ final class CoreLibsACLLoginTest extends TestCase
self::$db->dbSetMaxQueryCall(-1); self::$db->dbSetMaxQueryCall(-1);
// insert additional content for testing (locked user, etc) // insert additional content for testing (locked user, etc)
$queries = [ $queries = [
<<<SQL "INSERT INTO edit_access_data "
INSERT INTO edit_access_data ( . "(edit_access_id, name, value, enabled) VALUES "
edit_access_id, name, value, enabled . "((SELECT edit_access_id FROM edit_access WHERE uid = 'AdminAccess'), "
) VALUES ( . "'test', 'value', 1)"
(SELECT edit_access_id FROM edit_access WHERE uid = 'AdminAccess'),
'test', 'value', 1
)
SQL
]; ];
foreach ($queries as $query) { foreach ($queries as $query) {
self::$db->dbExec($query); self::$db->dbExec($query);
} }
// read edit access cuid, edit user cuid and edit user cuuid
$row = self::$db->dbReturnRowParams(
"SELECT cuid FROM edit_access WHERE uid = $1",
["AdminAccess"]
);
self::$edit_access_cuid = $row['cuid'] ?? '';
if (empty(self::$edit_access_cuid)) {
self::markTestIncomplete(
'Cannot read edit access cuid for "AdminAccess".'
);
}
$row = self::$db->dbReturnRowParams(
"SELECT cuid, cuuid FROM edit_user WHERE username = $1",
["admin"]
);
self::$edit_user_cuid = $row['cuid'] ?? '';
self::$edit_user_cuuid = $row['cuuid'] ?? '';
if (empty(self::$edit_user_cuid) || empty(self::$edit_user_cuuid)) {
self::markTestIncomplete(
'Cannot read edit user cuid or cuuid for "admin".'
);
}
// define mandatory constant // define mandatory constant
// must set // must set
// TARGET // TARGET
define('TARGET', 'test'); define('TARGET', 'test');
// LOGIN DB SCHEMA // LOGIN DB SCHEMA
// define('LOGIN_DB_SCHEMA', '');
// SHOULD SET // SHOULD SET
// DEFAULT_ACL_LEVEL (d80) // DEFAULT_ACL_LEVEL (d80)
@@ -266,25 +235,22 @@ final class CoreLibsACLLoginTest extends TestCase
'ajax_post_action' => 'login', 'ajax_post_action' => 'login',
], ],
], ],
'load, session eucuuid set only, php error' => [ 'load, session euid set only, php error' => [
[ [
'page_name' => 'edit_users.php', 'page_name' => 'edit_users.php',
], ],
[], [],
[], [],
[ [
'LOGIN_EUID' => 1, 'EUID' => 1,
'LOGIN_EUCUID' => 'abc',
'LOGIN_EUCUUID' => '1233456-1234-1234-1234-123456789012',
], ],
2, 2,
[], [],
], ],
'load, session eucuuid set, all set' => [ 'load, session euid set, all set' => [
[ [
'page_name' => 'edit_users.php', 'page_name' => 'edit_users.php',
'edit_access_id' => 1, 'edit_access_id' => 1,
'edit_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'edit_access_uid' => 'AdminAccess', 'edit_access_uid' => 'AdminAccess',
'edit_access_data' => 'test', 'edit_access_data' => 'test',
'base_access' => 'list', 'base_access' => 'list',
@@ -293,23 +259,20 @@ final class CoreLibsACLLoginTest extends TestCase
[], [],
[], [],
[ [
'LOGIN_EUID' => 1, 'EUID' => 1,
'LOGIN_EUCUID' => 'abc', 'USER_NAME' => '',
'LOGIN_EUCUUID' => 'SET_EUCUUID_IN_TEST', 'GROUP_NAME' => '',
'LOGIN_USER_NAME' => '', 'ADMIN' => 1,
'LOGIN_GROUP_NAME' => '', 'GROUP_ACL_LEVEL' => -1,
'LOGIN_ADMIN' => 1, 'PAGES_ACL_LEVEL' => [],
'LOGIN_GROUP_ACL_LEVEL' => -1, 'USER_ACL_LEVEL' => -1,
'LOGIN_PAGES_ACL_LEVEL' => [], 'USER_ADDITIONAL_ACL' => [],
'LOGIN_USER_ACL_LEVEL' => -1, 'GROUP_ADDITIONAL_ACL' => [],
'LOGIN_USER_ADDITIONAL_ACL' => [], 'UNIT_UID' => [
'LOGIN_GROUP_ADDITIONAL_ACL' => [], 'AdminAccess' => 1,
'LOGIN_UNIT_UID' => [
'AdminAccess' => '123456789012',
], ],
'LOGIN_UNIT' => [ 'UNIT' => [
'123456789012' => [ 1 => [
'id' => 1,
'acl_level' => 80, 'acl_level' => 80,
'name' => 'Admin Access', 'name' => 'Admin Access',
'uid' => 'AdminAccess', 'uid' => 'AdminAccess',
@@ -321,8 +284,8 @@ final class CoreLibsACLLoginTest extends TestCase
'additional_acl' => [] 'additional_acl' => []
], ],
], ],
// 'LOGIN_UNIT_DEFAULT' => '', // 'UNIT_DEFAULT' => '',
// 'LOGIN_DEFAULT_ACL_LIST' => [], // 'DEFAULT_ACL_LIST' => [],
], ],
0, 0,
[ [
@@ -330,7 +293,6 @@ final class CoreLibsACLLoginTest extends TestCase
'admin_flag' => true, 'admin_flag' => true,
'check_access' => true, 'check_access' => true,
'check_access_id' => 1, 'check_access_id' => 1,
'check_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'check_access_data' => 'value', 'check_access_data' => 'value',
'base_access' => true, 'base_access' => true,
'page_access' => true, 'page_access' => true,
@@ -450,7 +412,6 @@ final class CoreLibsACLLoginTest extends TestCase
[ [
'page_name' => 'edit_users.php', 'page_name' => 'edit_users.php',
'edit_access_id' => 1, 'edit_access_id' => 1,
'edit_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'base_access' => 'list', 'base_access' => 'list',
'page_access' => 'list', 'page_access' => 'list',
'test_deleted' => true 'test_deleted' => true
@@ -476,7 +437,6 @@ final class CoreLibsACLLoginTest extends TestCase
[ [
'page_name' => 'edit_users.php', 'page_name' => 'edit_users.php',
'edit_access_id' => 1, 'edit_access_id' => 1,
'edit_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'base_access' => 'list', 'base_access' => 'list',
'page_access' => 'list', 'page_access' => 'list',
'test_enabled' => true 'test_enabled' => true
@@ -502,7 +462,6 @@ final class CoreLibsACLLoginTest extends TestCase
[ [
'page_name' => 'edit_users.php', 'page_name' => 'edit_users.php',
'edit_access_id' => 1, 'edit_access_id' => 1,
'edit_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'base_access' => 'list', 'base_access' => 'list',
'page_access' => 'list', 'page_access' => 'list',
'test_locked' => true 'test_locked' => true
@@ -528,7 +487,6 @@ final class CoreLibsACLLoginTest extends TestCase
[ [
'page_name' => 'edit_users.php', 'page_name' => 'edit_users.php',
'edit_access_id' => 1, 'edit_access_id' => 1,
'edit_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'base_access' => 'list', 'base_access' => 'list',
'page_access' => 'list', 'page_access' => 'list',
'test_get_locked' => true, 'test_get_locked' => true,
@@ -553,7 +511,6 @@ final class CoreLibsACLLoginTest extends TestCase
[ [
'page_name' => 'edit_users.php', 'page_name' => 'edit_users.php',
'edit_access_id' => 1, 'edit_access_id' => 1,
'edit_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'base_access' => 'list', 'base_access' => 'list',
'page_access' => 'list', 'page_access' => 'list',
'test_locked_period_until' => 'on' 'test_locked_period_until' => 'on'
@@ -579,7 +536,6 @@ final class CoreLibsACLLoginTest extends TestCase
[ [
'page_name' => 'edit_users.php', 'page_name' => 'edit_users.php',
'edit_access_id' => 1, 'edit_access_id' => 1,
'edit_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'edit_access_uid' => 'AdminAccess', 'edit_access_uid' => 'AdminAccess',
'edit_access_data' => 'test', 'edit_access_data' => 'test',
'base_access' => 'list', 'base_access' => 'list',
@@ -599,7 +555,6 @@ final class CoreLibsACLLoginTest extends TestCase
'admin_flag' => true, 'admin_flag' => true,
'check_access' => true, 'check_access' => true,
'check_access_id' => 1, 'check_access_id' => 1,
'check_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'check_access_data' => 'value', 'check_access_data' => 'value',
'base_access' => true, 'base_access' => true,
'page_access' => true, 'page_access' => true,
@@ -610,7 +565,6 @@ final class CoreLibsACLLoginTest extends TestCase
[ [
'page_name' => 'edit_users.php', 'page_name' => 'edit_users.php',
'edit_access_id' => 1, 'edit_access_id' => 1,
'edit_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'base_access' => 'list', 'base_access' => 'list',
'page_access' => 'list', 'page_access' => 'list',
'test_locked_period_after' => 'on' 'test_locked_period_after' => 'on'
@@ -636,7 +590,6 @@ final class CoreLibsACLLoginTest extends TestCase
[ [
'page_name' => 'edit_users.php', 'page_name' => 'edit_users.php',
'edit_access_id' => 1, 'edit_access_id' => 1,
'edit_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'base_access' => 'list', 'base_access' => 'list',
'page_access' => 'list', 'page_access' => 'list',
'test_locked_period_until' => 'on', 'test_locked_period_until' => 'on',
@@ -663,7 +616,6 @@ final class CoreLibsACLLoginTest extends TestCase
[ [
'page_name' => 'edit_users.php', 'page_name' => 'edit_users.php',
'edit_access_id' => 1, 'edit_access_id' => 1,
'edit_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'base_access' => 'list', 'base_access' => 'list',
'page_access' => 'list', 'page_access' => 'list',
'test_login_user_id_locked' => true 'test_login_user_id_locked' => true
@@ -689,7 +641,6 @@ final class CoreLibsACLLoginTest extends TestCase
[ [
'page_name' => 'edit_users.php', 'page_name' => 'edit_users.php',
'edit_access_id' => 1, 'edit_access_id' => 1,
'edit_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'edit_access_uid' => 'AdminAccess', 'edit_access_uid' => 'AdminAccess',
'edit_access_data' => 'test', 'edit_access_data' => 'test',
'base_access' => 'list', 'base_access' => 'list',
@@ -708,7 +659,6 @@ final class CoreLibsACLLoginTest extends TestCase
'admin_flag' => true, 'admin_flag' => true,
'check_access' => true, 'check_access' => true,
'check_access_id' => 1, 'check_access_id' => 1,
'check_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'check_access_data' => 'value', 'check_access_data' => 'value',
'base_access' => true, 'base_access' => true,
'page_access' => true, 'page_access' => true,
@@ -719,7 +669,6 @@ final class CoreLibsACLLoginTest extends TestCase
[ [
'page_name' => 'edit_users.php', 'page_name' => 'edit_users.php',
'edit_access_id' => 1, 'edit_access_id' => 1,
'edit_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'edit_access_uid' => 'AdminAccess', 'edit_access_uid' => 'AdminAccess',
'edit_access_data' => 'test', 'edit_access_data' => 'test',
'base_access' => 'list', 'base_access' => 'list',
@@ -739,7 +688,6 @@ final class CoreLibsACLLoginTest extends TestCase
'admin_flag' => true, 'admin_flag' => true,
'check_access' => true, 'check_access' => true,
'check_access_id' => 1, 'check_access_id' => 1,
'check_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'check_access_data' => 'value', 'check_access_data' => 'value',
'base_access' => true, 'base_access' => true,
'page_access' => true, 'page_access' => true,
@@ -750,7 +698,6 @@ final class CoreLibsACLLoginTest extends TestCase
[ [
'page_name' => 'edit_users.php', 'page_name' => 'edit_users.php',
'edit_access_id' => 1, 'edit_access_id' => 1,
'edit_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'edit_access_uid' => 'AdminAccess', 'edit_access_uid' => 'AdminAccess',
'edit_access_data' => 'test', 'edit_access_data' => 'test',
'base_access' => 'list', 'base_access' => 'list',
@@ -770,7 +717,6 @@ final class CoreLibsACLLoginTest extends TestCase
'admin_flag' => true, 'admin_flag' => true,
'check_access' => true, 'check_access' => true,
'check_access_id' => 1, 'check_access_id' => 1,
'check_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'check_access_data' => 'value', 'check_access_data' => 'value',
'base_access' => true, 'base_access' => true,
'page_access' => true, 'page_access' => true,
@@ -781,7 +727,6 @@ final class CoreLibsACLLoginTest extends TestCase
[ [
'page_name' => 'edit_users.php', 'page_name' => 'edit_users.php',
'edit_access_id' => 1, 'edit_access_id' => 1,
'edit_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'edit_access_uid' => 'AdminAccess', 'edit_access_uid' => 'AdminAccess',
'edit_access_data' => 'test', 'edit_access_data' => 'test',
'base_access' => 'list', 'base_access' => 'list',
@@ -801,7 +746,6 @@ final class CoreLibsACLLoginTest extends TestCase
'admin_flag' => true, 'admin_flag' => true,
'check_access' => true, 'check_access' => true,
'check_access_id' => 1, 'check_access_id' => 1,
'check_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'check_access_data' => 'value', 'check_access_data' => 'value',
'base_access' => true, 'base_access' => true,
'page_access' => true, 'page_access' => true,
@@ -833,7 +777,6 @@ final class CoreLibsACLLoginTest extends TestCase
[ [
'page_name' => 'edit_users.php', 'page_name' => 'edit_users.php',
'edit_access_id' => 1, 'edit_access_id' => 1,
'edit_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'edit_access_uid' => 'AdminAccess', 'edit_access_uid' => 'AdminAccess',
'edit_access_data' => 'test', 'edit_access_data' => 'test',
'base_access' => 'list', 'base_access' => 'list',
@@ -857,7 +800,6 @@ final class CoreLibsACLLoginTest extends TestCase
'admin_flag' => true, 'admin_flag' => true,
'check_access' => true, 'check_access' => true,
'check_access_id' => 1, 'check_access_id' => 1,
'check_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'check_access_data' => 'value', 'check_access_data' => 'value',
'base_access' => true, 'base_access' => true,
'page_access' => true, 'page_access' => true,
@@ -868,7 +810,6 @@ final class CoreLibsACLLoginTest extends TestCase
[ [
'page_name' => 'edit_users.php', 'page_name' => 'edit_users.php',
'edit_access_id' => 1, 'edit_access_id' => 1,
'edit_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'edit_access_uid' => 'AdminAccess', 'edit_access_uid' => 'AdminAccess',
'edit_access_data' => 'test', 'edit_access_data' => 'test',
'base_access' => 'list', 'base_access' => 'list',
@@ -892,7 +833,6 @@ final class CoreLibsACLLoginTest extends TestCase
'admin_flag' => true, 'admin_flag' => true,
'check_access' => true, 'check_access' => true,
'check_access_id' => 1, 'check_access_id' => 1,
'check_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'check_access_data' => 'value', 'check_access_data' => 'value',
'base_access' => true, 'base_access' => true,
'page_access' => true, 'page_access' => true,
@@ -903,7 +843,6 @@ final class CoreLibsACLLoginTest extends TestCase
[ [
'page_name' => 'edit_users.php', 'page_name' => 'edit_users.php',
'edit_access_id' => 1, 'edit_access_id' => 1,
'edit_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'base_access' => 'list', 'base_access' => 'list',
'page_access' => 'list', 'page_access' => 'list',
'test_login_user_id_revalidate_after' => 'on', 'test_login_user_id_revalidate_after' => 'on',
@@ -930,7 +869,6 @@ final class CoreLibsACLLoginTest extends TestCase
[ [
'page_name' => 'edit_users.php', 'page_name' => 'edit_users.php',
'edit_access_id' => 1, 'edit_access_id' => 1,
'edit_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'edit_access_uid' => 'AdminAccess', 'edit_access_uid' => 'AdminAccess',
'edit_access_data' => 'test', 'edit_access_data' => 'test',
'base_access' => 'list', 'base_access' => 'list',
@@ -951,7 +889,6 @@ final class CoreLibsACLLoginTest extends TestCase
'admin_flag' => true, 'admin_flag' => true,
'check_access' => true, 'check_access' => true,
'check_access_id' => 1, 'check_access_id' => 1,
'check_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'check_access_data' => 'value', 'check_access_data' => 'value',
'base_access' => true, 'base_access' => true,
'page_access' => true, 'page_access' => true,
@@ -962,7 +899,6 @@ final class CoreLibsACLLoginTest extends TestCase
[ [
'page_name' => 'edit_users.php', 'page_name' => 'edit_users.php',
'edit_access_id' => 1, 'edit_access_id' => 1,
'edit_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'base_access' => 'list', 'base_access' => 'list',
'page_access' => 'list', 'page_access' => 'list',
'test_login_user_id_valid_from' => 'on', 'test_login_user_id_valid_from' => 'on',
@@ -989,7 +925,6 @@ final class CoreLibsACLLoginTest extends TestCase
[ [
'page_name' => 'edit_users.php', 'page_name' => 'edit_users.php',
'edit_access_id' => 1, 'edit_access_id' => 1,
'edit_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'edit_access_uid' => 'AdminAccess', 'edit_access_uid' => 'AdminAccess',
'edit_access_data' => 'test', 'edit_access_data' => 'test',
'base_access' => 'list', 'base_access' => 'list',
@@ -1010,7 +945,6 @@ final class CoreLibsACLLoginTest extends TestCase
'admin_flag' => true, 'admin_flag' => true,
'check_access' => true, 'check_access' => true,
'check_access_id' => 1, 'check_access_id' => 1,
'check_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'check_access_data' => 'value', 'check_access_data' => 'value',
'base_access' => true, 'base_access' => true,
'page_access' => true, 'page_access' => true,
@@ -1021,7 +955,6 @@ final class CoreLibsACLLoginTest extends TestCase
[ [
'page_name' => 'edit_users.php', 'page_name' => 'edit_users.php',
'edit_access_id' => 1, 'edit_access_id' => 1,
'edit_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'base_access' => 'list', 'base_access' => 'list',
'page_access' => 'list', 'page_access' => 'list',
'test_login_user_id_valid_until' => 'on', 'test_login_user_id_valid_until' => 'on',
@@ -1048,7 +981,6 @@ final class CoreLibsACLLoginTest extends TestCase
[ [
'page_name' => 'edit_users.php', 'page_name' => 'edit_users.php',
'edit_access_id' => 1, 'edit_access_id' => 1,
'edit_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'base_access' => 'list', 'base_access' => 'list',
'page_access' => 'list', 'page_access' => 'list',
'test_login_user_id_valid_from' => 'on', 'test_login_user_id_valid_from' => 'on',
@@ -1076,7 +1008,6 @@ final class CoreLibsACLLoginTest extends TestCase
[ [
'page_name' => 'edit_users.php', 'page_name' => 'edit_users.php',
'edit_access_id' => 1, 'edit_access_id' => 1,
'edit_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'edit_access_uid' => 'AdminAccess', 'edit_access_uid' => 'AdminAccess',
'edit_access_data' => 'test', 'edit_access_data' => 'test',
'base_access' => 'list', 'base_access' => 'list',
@@ -1107,7 +1038,6 @@ final class CoreLibsACLLoginTest extends TestCase
'admin_flag' => true, 'admin_flag' => true,
'check_access' => true, 'check_access' => true,
'check_access_id' => 1, 'check_access_id' => 1,
'check_access_cuid' => 'SET_EDIT_ACCESS_CUID_IN_TEST',
'check_access_data' => 'value', 'check_access_data' => 'value',
'base_access' => true, 'base_access' => true,
'page_access' => true, 'page_access' => true,
@@ -1155,9 +1085,9 @@ final class CoreLibsACLLoginTest extends TestCase
/** @var \CoreLibs\Create\Session&MockObject */ /** @var \CoreLibs\Create\Session&MockObject */
$session_mock = $this->createPartialMock( $session_mock = $this->createPartialMock(
\CoreLibs\Create\Session::class, \CoreLibs\Create\Session::class,
['getSessionId', 'checkActiveSession', 'sessionDestroy'] ['startSession', 'checkActiveSession', 'sessionDestroy']
); );
$session_mock->method('getSessionId')->willReturn('ACLLOGINTEST12'); $session_mock->method('startSession')->willReturn('ACLLOGINTEST12');
$session_mock->method('checkActiveSession')->willReturn(true); $session_mock->method('checkActiveSession')->willReturn(true);
$session_mock->method('sessionDestroy')->will( $session_mock->method('sessionDestroy')->will(
$this->returnCallback(function () { $this->returnCallback(function () {
@@ -1177,15 +1107,11 @@ final class CoreLibsACLLoginTest extends TestCase
$_POST[$post_var] = $post_value; $_POST[$post_var] = $post_value;
} }
// set ingoing session cuuid if requested
if (isset($session['LOGIN_EUCUUID']) && $session['LOGIN_EUCUUID'] == 'SET_EUCUUID_IN_TEST') {
$session['LOGIN_EUCUUID'] = self::$edit_user_cuuid;
}
// set _SESSION data // set _SESSION data
foreach ($session as $session_var => $session_value) { foreach ($session as $session_var => $session_value) {
$_SESSION[$session_var] = $session_value; $_SESSION[$session_var] = $session_value;
} }
/** @var \CoreLibs\ACL\Login&MockObject */ /** @var \CoreLibs\ACL\Login&MockObject */
$login_mock = $this->getMockBuilder(\CoreLibs\ACL\Login::class) $login_mock = $this->getMockBuilder(\CoreLibs\ACL\Login::class)
->setConstructorArgs([ ->setConstructorArgs([
@@ -1204,7 +1130,7 @@ final class CoreLibsACLLoginTest extends TestCase
. 'locale' . DIRECTORY_SEPARATOR, . 'locale' . DIRECTORY_SEPARATOR,
] ]
]) ])
->onlyMethods(['loginTerminate', 'loginReadPageName', 'loginPrintLogin', 'loginEnhanceHttpSecurity']) ->onlyMethods(['loginTerminate', 'loginReadPageName', 'loginPrintLogin'])
->getMock(); ->getMock();
$login_mock->expects($this->any()) $login_mock->expects($this->any())
->method('loginTerminate') ->method('loginTerminate')
@@ -1222,10 +1148,6 @@ final class CoreLibsACLLoginTest extends TestCase
->method('loginPrintLogin') ->method('loginPrintLogin')
->willReturnCallback(function () { ->willReturnCallback(function () {
}); });
$login_mock->expects($this->any())
->method('loginEnhanceHttpSecurity')
->willReturnCallback(function () {
});
// if mock_settings: enabled OFF // if mock_settings: enabled OFF
// run DB update and set off // run DB update and set off
@@ -1443,19 +1365,6 @@ final class CoreLibsACLLoginTest extends TestCase
// run test // run test
try { try {
// preset, we cannot set that in the provider
if (
isset($expected['check_access_cuid']) &&
$expected['check_access_cuid'] == 'SET_EDIT_ACCESS_CUID_IN_TEST'
) {
$expected['check_access_cuid'] = self::$edit_access_cuid;
}
if (
isset($mock_settings['edit_access_cuid']) &&
$mock_settings['edit_access_cuid'] == 'SET_EDIT_ACCESS_CUID_IN_TEST'
) {
$mock_settings['edit_access_cuid'] = self::$edit_access_cuid;
}
// if ajax call // if ajax call
// check if parameter, or globals (old type) // check if parameter, or globals (old type)
// else normal call // else normal call
@@ -1514,31 +1423,6 @@ final class CoreLibsACLLoginTest extends TestCase
$login_mock->loginCheckAccessPage($mock_settings['page_access']), $login_mock->loginCheckAccessPage($mock_settings['page_access']),
'Assert page access' 'Assert page access'
); );
// - loginCheckEditAccessCuid
$this->assertEquals(
$expected['check_access'],
$login_mock->loginCheckEditAccessCuid($mock_settings['edit_access_cuid']),
'Assert check access'
);
// - loginCheckEditAccessValidCuid
$this->assertEquals(
$expected['check_access_cuid'],
$login_mock->loginCheckEditAccessValidCuid($mock_settings['edit_access_cuid']),
'Assert check access cuid valid'
);
// - loginGetEditAccessCuidFromUid
$this->assertEquals(
$expected['check_access_cuid'],
$login_mock->loginGetEditAccessCuidFromUid($mock_settings['edit_access_uid']),
'Assert check access uid to cuid valid'
);
// - loginGetEditAccessCuidFromId
$this->assertEquals(
$expected['check_access_cuid'],
$login_mock->loginGetEditAccessCuidFromUid($mock_settings['edit_access_id']),
'Assert check access id to cuid valid'
);
// Deprecated
// - loginCheckEditAccess // - loginCheckEditAccess
$this->assertEquals( $this->assertEquals(
$expected['check_access'], $expected['check_access'],
@@ -1561,7 +1445,7 @@ final class CoreLibsACLLoginTest extends TestCase
$this->assertEquals( $this->assertEquals(
$expected['check_access_data'], $expected['check_access_data'],
$login_mock->loginGetEditAccessData( $login_mock->loginGetEditAccessData(
$mock_settings['edit_access_uid'], $mock_settings['edit_access_id'],
$mock_settings['edit_access_data'] $mock_settings['edit_access_data']
), ),
'Assert check access id data value valid' 'Assert check access id data value valid'
@@ -1592,12 +1476,11 @@ final class CoreLibsACLLoginTest extends TestCase
// - loginCheckPermissions // - loginCheckPermissions
// - loginGetPermissionOkay // - loginGetPermissionOkay
} catch (\Exception $e) { } catch (\Exception $e) {
/* print "[E]: " . $e->getCode() . ", ERROR: " . $login_mock->loginGetLastErrorCode() . "/" // print "[E]: " . $e->getCode() . ", ERROR: " . $login_mock->loginGetLastErrorCode() . "/"
. ($expected['login_error'] ?? 0) . "\n"; // . ($expected['login_error'] ?? 0) . "\n";
print "AJAX: " . $login_mock->loginGetAjaxFlag() . "\n"; // print "AJAX: " . $login_mock->loginGetAjaxFlag() . "\n";
print "AJAX GLOBAL: " . ($GLOBALS['AJAX_PAGE'] ?? '{f}') . "\n"; // print "AJAX GLOBAL: " . ($GLOBALS['AJAX_PAGE'] ?? '{f}') . "\n";
print "Login error expext: " . ($expected['login_error'] ?? '{0}') . "\n"; // print "Login error expext: " . ($expected['login_error'] ?? '{0}') . "\n";
print "POST exit: " . ($_POST['login_exit'] ?? '{0}') . "\n"; */
// if this is 100, then we do further error checks // if this is 100, then we do further error checks
if ( if (
$e->getCode() == 100 || $e->getCode() == 100 ||
@@ -1905,9 +1788,9 @@ final class CoreLibsACLLoginTest extends TestCase
/** @var \CoreLibs\Create\Session&MockObject */ /** @var \CoreLibs\Create\Session&MockObject */
$session_mock = $this->createPartialMock( $session_mock = $this->createPartialMock(
\CoreLibs\Create\Session::class, \CoreLibs\Create\Session::class,
['getSessionId', 'checkActiveSession', 'sessionDestroy'] ['startSession', 'checkActiveSession', 'sessionDestroy']
); );
$session_mock->method('getSessionId')->willReturn('ACLLOGINTEST34'); $session_mock->method('startSession')->willReturn('ACLLOGINTEST34');
$session_mock->method('checkActiveSession')->willReturn(true); $session_mock->method('checkActiveSession')->willReturn(true);
$session_mock->method('sessionDestroy')->will( $session_mock->method('sessionDestroy')->will(
$this->returnCallback(function () { $this->returnCallback(function () {
@@ -2019,9 +1902,9 @@ final class CoreLibsACLLoginTest extends TestCase
/** @var \CoreLibs\Create\Session&MockObject */ /** @var \CoreLibs\Create\Session&MockObject */
$session_mock = $this->createPartialMock( $session_mock = $this->createPartialMock(
\CoreLibs\Create\Session::class, \CoreLibs\Create\Session::class,
['getSessionId', 'checkActiveSession', 'sessionDestroy'] ['startSession', 'checkActiveSession', 'sessionDestroy']
); );
$session_mock->method('getSessionId')->willReturn('ACLLOGINTEST34'); $session_mock->method('startSession')->willReturn('ACLLOGINTEST34');
$session_mock->method('checkActiveSession')->willReturn(true); $session_mock->method('checkActiveSession')->willReturn(true);
$session_mock->method('sessionDestroy')->will( $session_mock->method('sessionDestroy')->will(
$this->returnCallback(function () { $this->returnCallback(function () {
@@ -2107,9 +1990,9 @@ final class CoreLibsACLLoginTest extends TestCase
/** @var \CoreLibs\Create\Session&MockObject */ /** @var \CoreLibs\Create\Session&MockObject */
$session_mock = $this->createPartialMock( $session_mock = $this->createPartialMock(
\CoreLibs\Create\Session::class, \CoreLibs\Create\Session::class,
['getSessionId', 'checkActiveSession', 'sessionDestroy'] ['startSession', 'checkActiveSession', 'sessionDestroy']
); );
$session_mock->method('getSessionId')->willReturn('ACLLOGINTEST34'); $session_mock->method('startSession')->willReturn('ACLLOGINTEST34');
$session_mock->method('checkActiveSession')->willReturn(true); $session_mock->method('checkActiveSession')->willReturn(true);
$session_mock->method('sessionDestroy')->will( $session_mock->method('sessionDestroy')->will(
$this->returnCallback(function () { $this->returnCallback(function () {
@@ -2203,9 +2086,9 @@ final class CoreLibsACLLoginTest extends TestCase
/** @var \CoreLibs\Create\Session&MockObject */ /** @var \CoreLibs\Create\Session&MockObject */
$session_mock = $this->createPartialMock( $session_mock = $this->createPartialMock(
\CoreLibs\Create\Session::class, \CoreLibs\Create\Session::class,
['getSessionId', 'checkActiveSession', 'sessionDestroy'] ['startSession', 'checkActiveSession', 'sessionDestroy']
); );
$session_mock->method('getSessionId')->willReturn('ACLLOGINTEST34'); $session_mock->method('startSession')->willReturn('ACLLOGINTEST34');
$session_mock->method('checkActiveSession')->willReturn(true); $session_mock->method('checkActiveSession')->willReturn(true);
$session_mock->method('sessionDestroy')->will( $session_mock->method('sessionDestroy')->will(
$this->returnCallback(function () { $this->returnCallback(function () {

View File

@@ -24,12 +24,12 @@ final class CoreLibsCheckEmailTest extends TestCase
'get email regex invalid -1, will be 0' => [ 'get email regex invalid -1, will be 0' => [
-1, -1,
"^[A-Za-z0-9!#$%&'*+\-\/=?^_`{|}~][A-Za-z0-9!#$%:\(\)&'*+\-\/=?^_`{|}~\.]{0,63}@" "^[A-Za-z0-9!#$%&'*+\-\/=?^_`{|}~][A-Za-z0-9!#$%:\(\)&'*+\-\/=?^_`{|}~\.]{0,63}@"
. "(?!-)[A-Za-z0-9-]{1,63}(?<!-)(?:\.[A-Za-z0-9-]{1,63}(?<!-))*\.[a-zA-Z]{2,6}$" . "[a-zA-Z0-9\-]+(\.[a-zA-Z0-9\-]{1,})*\.([a-zA-Z]{2,}){1}$"
], ],
'get email regex invalid 10, will be 0' => [ 'get email regex invalid 10, will be 0' => [
10, 10,
"^[A-Za-z0-9!#$%&'*+\-\/=?^_`{|}~][A-Za-z0-9!#$%:\(\)&'*+\-\/=?^_`{|}~\.]{0,63}@" "^[A-Za-z0-9!#$%&'*+\-\/=?^_`{|}~][A-Za-z0-9!#$%:\(\)&'*+\-\/=?^_`{|}~\.]{0,63}@"
. "(?!-)[A-Za-z0-9-]{1,63}(?<!-)(?:\.[A-Za-z0-9-]{1,63}(?<!-))*\.[a-zA-Z]{2,6}$" . "[a-zA-Z0-9\-]+(\.[a-zA-Z0-9\-]{1,})*\.([a-zA-Z]{2,}){1}$"
], ],
'get email regex valid 1, will be 1' => [ 'get email regex valid 1, will be 1' => [
1, 1,
@@ -157,7 +157,7 @@ final class CoreLibsCheckEmailTest extends TestCase
'error' => 0, 'error' => 0,
'message' => 'Invalid email address', 'message' => 'Invalid email address',
'regex' => "^[A-Za-z0-9!#$%&'*+\-\/=?^_`{|}~][A-Za-z0-9!#$%:\(\)&'*+\-\/=?^_`{|}~\.]{0,63}@" 'regex' => "^[A-Za-z0-9!#$%&'*+\-\/=?^_`{|}~][A-Za-z0-9!#$%:\(\)&'*+\-\/=?^_`{|}~\.]{0,63}@"
. "(?!-)[A-Za-z0-9-]{1,63}(?<!-)(?:\.[A-Za-z0-9-]{1,63}(?<!-))*\.[a-zA-Z]{2,6}$" . "[a-zA-Z0-9\-]+(\.[a-zA-Z0-9\-]{1,})*\.([a-zA-Z]{2,}){1}$"
] ]
], ],
'error 1 will return double @ error' => [ 'error 1 will return double @ error' => [
@@ -181,7 +181,7 @@ final class CoreLibsCheckEmailTest extends TestCase
[ [
'error' => 3, 'error' => 3,
'message' => 'Invalid domain part after @ sign', 'message' => 'Invalid domain part after @ sign',
'regex' => "@(?!-)[A-Za-z0-9-]{1,63}(?<!-)(?:\.[A-Za-z0-9-]{1,63}(?<!-))*\.[a-zA-Z]{2,6}$" 'regex' => "@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]{1,})*\.([a-zA-Z]{2,}){1}$"
] ]
], ],
'error 4 will be invalid domain' => [ 'error 4 will be invalid domain' => [
@@ -189,7 +189,7 @@ final class CoreLibsCheckEmailTest extends TestCase
[ [
'error' => 4, 'error' => 4,
'message' => 'Invalid domain name part', 'message' => 'Invalid domain name part',
'regex' => "@(?!-)[A-Za-z0-9-]{1,63}(?<!-)(?:\.[A-Za-z0-9-]{1,63}(?<!-))*\." 'regex' => "@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]{1,})*\."
] ]
], ],
'error 5 will be invalid domain top level only' => [ 'error 5 will be invalid domain top level only' => [
@@ -197,7 +197,7 @@ final class CoreLibsCheckEmailTest extends TestCase
[ [
'error' => 5, 'error' => 5,
'message' => 'Wrong domain top level part', 'message' => 'Wrong domain top level part',
'regex' => "\.[a-zA-Z]{2,6}$" 'regex' => "\.([a-zA-Z]{2,6}){1}$"
] ]
], ],
'error 6 will be domain double dot' => [ 'error 6 will be domain double dot' => [

View File

@@ -1,404 +0,0 @@
<?php
// This code was created by Claude Sonnet 4
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
use CoreLibs\Combined\ArrayHandler;
class CoreLibsCombinedArrayHandlerFindArraysMissingKeyTest extends TestCase
{
private const DATA_SEPARATOR = ':'; // Updated to match your class's separator
/**
* Test finding missing single key when searching by value without specific key
*/
public function testFindMissingSingleKeyWithValueSearch()
{
$array = [
'item1' => [
'name' => 'John',
'age' => 25
// missing 'email' key
],
'item2' => [
'name' => 'Jane',
'age' => 30,
'email' => 'jane@example.com'
],
'item3' => [
'name' => 'John', // same value as item1
'age' => 35,
'email' => 'john2@example.com'
]
];
$result = ArrayHandler::findArraysMissingKey($array, 'John', 'email');
$this->assertCount(1, $result);
$this->assertEquals($array['item1'], $result[0]['content']);
$this->assertEquals('item1', $result[0]['path']);
$this->assertEquals(['email'], $result[0]['missing_key']);
}
/**
* Test finding missing single key when searching by specific key-value pair
*/
public function testFindMissingSingleKeyWithKeyValueSearch()
{
$array = [
'user1' => [
'id' => 1,
'name' => 'Alice'
// missing 'status' key
],
'user2' => [
'id' => 2,
'name' => 'Bob',
'status' => 'active'
],
'user3' => [
'id' => 1, // same id as user1
'name' => 'Charlie',
'status' => 'inactive'
]
];
$result = ArrayHandler::findArraysMissingKey($array, 1, 'status', 'id');
$this->assertCount(1, $result);
$this->assertEquals($array['user1'], $result[0]['content']);
$this->assertEquals('user1', $result[0]['path']);
$this->assertEquals(['status'], $result[0]['missing_key']);
}
/**
* Test finding missing multiple keys
*/
public function testFindMissingMultipleKeys()
{
$array = [
'record1' => [
'name' => 'Test',
'value' => 100
// missing both 'date' and 'status' keys
],
'record2' => [
'name' => 'Test',
'value' => 200,
'date' => '2023-01-01'
// missing 'status' key
],
'record3' => [
'name' => 'Test',
'value' => 300,
'date' => '2023-01-02',
'status' => 'complete'
]
];
$result = ArrayHandler::findArraysMissingKey($array, 'Test', ['date', 'status']);
$this->assertCount(2, $result);
// First result should be record1 missing both keys
$this->assertEquals($array['record1'], $result[0]['content']);
$this->assertEquals('record1', $result[0]['path']);
$this->assertContains('date', $result[0]['missing_key']);
$this->assertContains('status', $result[0]['missing_key']);
$this->assertCount(2, $result[0]['missing_key']);
// Second result should be record2 missing status key
$this->assertEquals($array['record2'], $result[1]['content']);
$this->assertEquals('record2', $result[1]['path']);
$this->assertEquals(['status'], $result[1]['missing_key']);
}
/**
* Test with nested arrays
*/
public function testFindMissingKeyInNestedArrays()
{
$array = [
'section1' => [
'items' => [
'item1' => [
'name' => 'Product A',
'price' => 99.99
// missing 'category' key
],
'item2' => [
'name' => 'Product B',
'price' => 149.99,
'category' => 'electronics'
]
]
],
'section2' => [
'data' => [
'name' => 'Product A', // same name as nested item
'category' => 'books'
]
]
];
$result = ArrayHandler::findArraysMissingKey($array, 'Product A', 'category');
$this->assertCount(1, $result);
$this->assertEquals($array['section1']['items']['item1'], $result[0]['content']);
$this->assertEquals('section1:items:item1', $result[0]['path']);
$this->assertEquals(['category'], $result[0]['missing_key']);
}
/**
* Test when no arrays are missing the required key
*/
public function testNoMissingKeys()
{
$array = [
'item1' => [
'name' => 'John',
'email' => 'john@example.com'
],
'item2' => [
'name' => 'Jane',
'email' => 'jane@example.com'
]
];
$result = ArrayHandler::findArraysMissingKey($array, 'John', 'email');
$this->assertEmpty($result);
}
/**
* Test when search value is not found in any array
*/
public function testSearchValueNotFound()
{
$array = [
'item1' => [
'name' => 'John',
'age' => 25
],
'item2' => [
'name' => 'Jane',
'age' => 30
]
];
$result = ArrayHandler::findArraysMissingKey($array, 'Bob', 'email');
$this->assertEmpty($result);
}
/**
* Test with different data types for search value
*/
public function testDifferentSearchValueTypes()
{
$array = [
'item1' => [
'active' => true,
'count' => 5
// missing 'label' key
],
'item2' => [
'active' => false,
'count' => 10,
'label' => 'test'
],
'item3' => [
'active' => true, // same boolean as item1
'count' => 15,
'label' => 'another'
]
];
// Test with boolean
$result = ArrayHandler::findArraysMissingKey($array, true, 'label', 'active');
$this->assertCount(1, $result);
$this->assertEquals('item1', $result[0]['path']);
// Test with integer
$result = ArrayHandler::findArraysMissingKey($array, 5, 'label', 'count');
$this->assertCount(1, $result);
$this->assertEquals('item1', $result[0]['path']);
}
/**
* Test with empty array
*/
public function testEmptyArray()
{
$array = [];
$result = ArrayHandler::findArraysMissingKey($array, 'test', 'key');
$this->assertEmpty($result);
}
/**
* Test with array containing non-array values
*/
public function testMixedArrayTypes()
{
$array = [
'string_value' => 'hello',
'numeric_value' => 123,
'array_value' => [
'name' => 'test',
// missing 'type' key
],
'another_array' => [
'name' => 'test',
'type' => 'example'
]
];
$result = ArrayHandler::findArraysMissingKey($array, 'test', 'type');
$this->assertCount(1, $result);
$this->assertEquals($array['array_value'], $result[0]['content']);
$this->assertEquals('array_value', $result[0]['path']);
$this->assertEquals(['type'], $result[0]['missing_key']);
}
/**
* Test path building with deeper nesting
*/
public function testDeepNestingPathBuilding()
{
$array = [
'level1' => [
'level2' => [
'level3' => [
'items' => [
'target_item' => [
'name' => 'deep_test',
// missing 'required_field'
]
]
]
]
]
];
$result = ArrayHandler::findArraysMissingKey($array, 'deep_test', 'required_field');
$this->assertCount(1, $result);
$this->assertEquals('level1:level2:level3:items:target_item', $result[0]['path']);
}
/**
* Test with custom path separator
*/
public function testCustomPathSeparator()
{
$array = [
'level1' => [
'level2' => [
'item' => [
'name' => 'test',
// missing 'type' key
]
]
]
];
$result = ArrayHandler::findArraysMissingKey($array, 'test', 'type', null, '/');
$this->assertCount(1, $result);
$this->assertEquals('level1/level2/item', $result[0]['path']);
}
/**
* Test default path separator behavior
*/
public function testDefaultPathSeparator()
{
$array = [
'parent' => [
'child' => [
'name' => 'test',
// missing 'value' key
]
]
];
// Using default separator (should be ':')
$result = ArrayHandler::findArraysMissingKey($array, 'test', 'value');
$this->assertCount(1, $result);
$this->assertEquals('parent:child', $result[0]['path']);
}
/**
* Test different path separators don't affect search logic
*/
public function testPathSeparatorDoesNotAffectSearchLogic()
{
$array = [
'section' => [
'data' => [
'id' => 123,
'name' => 'item'
// missing 'status'
]
]
];
// Test with different separators - results should be identical except for path
$result1 = ArrayHandler::findArraysMissingKey($array, 123, 'status', 'id', ':');
$result2 = ArrayHandler::findArraysMissingKey($array, 123, 'status', 'id', '.');
$result3 = ArrayHandler::findArraysMissingKey($array, 123, 'status', 'id', '/');
$this->assertCount(1, $result1);
$this->assertCount(1, $result2);
$this->assertCount(1, $result3);
// Content and missing_key should be the same
$this->assertEquals($result1[0]['content'], $result2[0]['content']);
$this->assertEquals($result1[0]['content'], $result3[0]['content']);
$this->assertEquals($result1[0]['missing_key'], $result2[0]['missing_key']);
$this->assertEquals($result1[0]['missing_key'], $result3[0]['missing_key']);
// Paths should be different based on separator
$this->assertEquals('section:data', $result1[0]['path']);
$this->assertEquals('section.data', $result2[0]['path']);
$this->assertEquals('section/data', $result3[0]['path']);
}
/**
* test type checking
*/
public function testStrictTypeChecking()
{
$array = [
'item1' => [
'id' => '123', // string
'name' => 'test'
// missing 'status'
],
'item2' => [
'id' => 123, // integer
'name' => 'test2',
'status' => 'active'
]
];
// Search for integer 123 - should only match item2
$result = ArrayHandler::findArraysMissingKey($array, 123, 'status', 'id');
$this->assertEmpty($result); // item2 has the status key
// Search for string '123' - should only match item1
$result = ArrayHandler::findArraysMissingKey($array, '123', 'status', 'id');
$this->assertCount(1, $result);
$this->assertEquals('item1', $result[0]['path']);
}
}
// __END__

View File

@@ -1,333 +0,0 @@
<?php
// This code was created by Claude Sonnet 4
// modification for value checks with assertEqualsCanonicalizing
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
use CoreLibs\Combined\ArrayHandler;
class CoreLibsCombinedArrayHandlerKsortArrayTest extends TestCase
{
/**
* Test basic ascending sort (default behavior)
*/
public function testKsortArrayBasicAscending(): void
{
$input = [
'zebra' => 'value1',
'apple' => 'value2',
'banana' => 'value3',
'cherry' => 'value4'
];
$expected = [
'apple' => 'value2',
'banana' => 'value3',
'cherry' => 'value4',
'zebra' => 'value1'
];
$result = ArrayHandler::ksortArray($input);
$this->assertEquals($expected, $result);
$this->assertEquals(array_keys($expected), array_keys($result));
}
/**
* Test descending sort with reverse=true
*/
public function testKsortArrayDescending(): void
{
$input = [
'zebra' => 'value1',
'apple' => 'value2',
'banana' => 'value3',
'cherry' => 'value4'
];
$expected = [
'zebra' => 'value1',
'cherry' => 'value4',
'banana' => 'value3',
'apple' => 'value2'
];
$result = ArrayHandler::ksortArray($input, false, true);
$this->assertEquals($expected, $result);
$this->assertEquals(array_keys($expected), array_keys($result));
}
/**
* Test case-insensitive ascending sort
*/
public function testKsortArrayCaseInsensitiveAscending(): void
{
$input = [
'Zebra' => 'value1',
'apple' => 'value2',
'Banana' => 'value3',
'cherry' => 'value4'
];
$expected = [
'apple' => 'value2',
'Banana' => 'value3',
'cherry' => 'value4',
'Zebra' => 'value1'
];
$result = ArrayHandler::ksortArray($input, true);
$this->assertEquals($expected, $result);
$this->assertEquals(array_keys($expected), array_keys($result));
}
/**
* Test case-insensitive descending sort
*/
public function testKsortArrayCaseInsensitiveDescending(): void
{
$input = [
'Zebra' => 'value1',
'apple' => 'value2',
'Banana' => 'value3',
'cherry' => 'value4'
];
$expected = [
'Zebra' => 'value1',
'cherry' => 'value4',
'Banana' => 'value3',
'apple' => 'value2'
];
$result = ArrayHandler::ksortArray($input, true, true);
$this->assertEquals($expected, $result);
$this->assertEquals(array_keys($expected), array_keys($result));
}
/**
* Test with mixed case keys to verify case sensitivity behavior
*/
public function testKsortArrayCaseSensitivityComparison(): void
{
$input = [
'B' => 'value1',
'a' => 'value2',
'C' => 'value3',
'b' => 'value4'
];
// Case-sensitive sort (uppercase comes before lowercase in ASCII)
$expectedCaseSensitive = [
'B' => 'value1',
'C' => 'value3',
'a' => 'value2',
'b' => 'value4'
];
// Case-insensitive sort
$expectedCaseInsensitive = [
'a' => 'value2',
'B' => 'value1',
'b' => 'value4',
'C' => 'value3'
];
$resultCaseSensitive = ArrayHandler::ksortArray($input, false);
$resultCaseInsensitive = ArrayHandler::ksortArray($input, true);
$this->assertEquals($expectedCaseSensitive, $resultCaseSensitive);
$this->assertEquals($expectedCaseInsensitive, $resultCaseInsensitive);
}
/**
* Test with numeric string keys
*/
public function testKsortArrayNumericStringKeys(): void
{
$input = [
'10' => 'value1',
'2' => 'value2',
'1' => 'value3',
'20' => 'value4'
];
// String comparison, not numeric
$expected = [
'1' => 'value3',
'10' => 'value1',
'2' => 'value2',
'20' => 'value4'
];
$result = ArrayHandler::ksortArray($input);
$this->assertEquals($expected, $result);
}
/**
* Test with special characters in keys
*/
public function testKsortArraySpecialCharacters(): void
{
$input = [
'key_with_underscore' => 'value1',
'key-with-dash' => 'value2',
'key.with.dot' => 'value3',
'key with space' => 'value4',
'keyWithCamelCase' => 'value5'
];
$result = ArrayHandler::ksortArray($input);
// Verify it doesn't throw an error and maintains all keys
$this->assertCount(5, $result);
$this->assertArrayHasKey('key_with_underscore', $result);
$this->assertArrayHasKey('key-with-dash', $result);
$this->assertArrayHasKey('key.with.dot', $result);
$this->assertArrayHasKey('key with space', $result);
$this->assertArrayHasKey('keyWithCamelCase', $result);
}
/**
* Test with empty array
*/
public function testKsortArrayEmpty(): void
{
$input = [];
$result = ArrayHandler::ksortArray($input);
$this->assertEquals([], $result);
$this->assertIsArray($result);
}
/**
* Test with single element array
*/
public function testKsortArraySingleElement(): void
{
$input = ['onlykey' => 'onlyvalue'];
$result = ArrayHandler::ksortArray($input);
$this->assertEquals($input, $result);
}
/**
* Test that original array is not modified (function returns new array)
*/
public function testKsortArrayDoesNotModifyOriginal(): void
{
$original = [
'zebra' => 'value1',
'apple' => 'value2',
'banana' => 'value3'
];
$originalCopy = $original; // Keep a copy for comparison
$result = ArrayHandler::ksortArray($original);
// Original array should remain unchanged
$this->assertEquals($originalCopy, $original);
$this->assertNotEquals(array_keys($original), array_keys($result));
}
/**
* Test with complex mixed data types as values
*/
public function testKsortArrayMixedValueTypes(): void
{
$input = [
'string_key' => 'string_value',
'array_key' => ['nested', 'array'],
'int_key' => 42,
'bool_key' => true,
'null_key' => null
];
$result = ArrayHandler::ksortArray($input);
// Check that all keys are preserved and sorted
$expectedKeys = ['array_key', 'bool_key', 'int_key', 'null_key', 'string_key'];
$this->assertEquals($expectedKeys, array_keys($result));
// Check that values are preserved correctly
$this->assertEquals('string_value', $result['string_key']);
$this->assertEquals(['nested', 'array'], $result['array_key']);
$this->assertEquals(42, $result['int_key']);
$this->assertTrue($result['bool_key']);
$this->assertNull($result['null_key']);
}
/**
* Test all parameter combinations
*/
public function testKsortArrayAllParameterCombinations(): void
{
$input = [
'Delta' => 'value1',
'alpha' => 'value2',
'Charlie' => 'value3',
'bravo' => 'value4'
];
// Test all 4 combinations
$result1 = ArrayHandler::ksortArray($input, false, false); // default
$result2 = ArrayHandler::ksortArray($input, false, true); // reverse only
$result3 = ArrayHandler::ksortArray($input, true, false); // lowercase only
$result4 = ArrayHandler::ksortArray($input, true, true); // both
// Each should produce different ordering
$this->assertNotEquals(array_keys($result1), array_keys($result2));
$this->assertNotEquals(array_keys($result1), array_keys($result3));
$this->assertNotEquals(array_keys($result1), array_keys($result4));
$this->assertNotEquals(array_keys($result2), array_keys($result3));
$this->assertNotEquals(array_keys($result2), array_keys($result4));
$this->assertNotEquals(array_keys($result3), array_keys($result4));
// But all should have same keys and values, just different order
$this->assertEqualsCanonicalizing(array_values($input), array_values($result1));
$this->assertEqualsCanonicalizing(array_values($input), array_values($result2));
$this->assertEqualsCanonicalizing(array_values($input), array_values($result3));
$this->assertEqualsCanonicalizing(array_values($input), array_values($result4));
}
/**
* Data provider for comprehensive testing
*/
public function sortingParametersProvider(): array
{
return [
'default' => [false, false],
'reverse' => [false, true],
'lowercase' => [true, false],
'lowercase_reverse' => [true, true],
];
}
/**
* Test that function works with all parameter combinations using data provider
*
* @dataProvider sortingParametersProvider
*/
public function testKsortArrayWithDataProvider(bool $lowerCase, bool $reverse): void
{
$input = [
'Zebra' => 'animal1',
'apple' => 'fruit1',
'Banana' => 'fruit2',
'cat' => 'animal2'
];
$result = ArrayHandler::ksortArray($input, $lowerCase, $reverse);
// Basic assertions that apply to all combinations
$this->assertIsArray($result);
$this->assertCount(4, $result);
$this->assertArrayHasKey('Zebra', $result);
$this->assertArrayHasKey('apple', $result);
$this->assertArrayHasKey('Banana', $result);
$this->assertArrayHasKey('cat', $result);
}
}
// __END__

View File

@@ -1,383 +0,0 @@
<?php
// created by Claude Sonnet 4
// testRecursiveSearchWithFlatResult had wrong retunr count
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
use CoreLibs\Combined\ArrayHandler;
class CoreLibsCombinedArrayHandlerSelectArrayFromOptionTest extends TestCase
{
private array $testData;
private array $nestedTestData;
protected function setUp(): void
{
$this->testData = [
'item1' => [
'name' => 'John',
'age' => 25,
'status' => 'active',
'score' => 85.5
],
'item2' => [
'name' => 'jane',
'age' => 30,
'status' => 'inactive',
'score' => 92.0
],
'item3' => [
'name' => 'Bob',
'age' => 25,
'status' => 'active',
'score' => 78.3
],
'item4' => [
'name' => 'Alice',
'age' => 35,
'status' => 'pending',
'score' => 88.7
]
];
$this->nestedTestData = [
'level1_a' => [
'name' => 'Level1A',
'type' => 'parent',
'children' => [
'child1' => [
'name' => 'Child1',
'type' => 'child',
'active' => true
],
'child2' => [
'name' => 'Child2',
'type' => 'child',
'active' => false
]
]
],
'level1_b' => [
'name' => 'Level1B',
'type' => 'parent',
'children' => [
'child3' => [
'name' => 'Child3',
'type' => 'child',
'active' => true,
'nested' => [
'deep1' => [
'name' => 'Deep1',
'type' => 'deep',
'active' => true
]
]
]
]
],
'item5' => [
'name' => 'Direct',
'type' => 'child',
'active' => false
]
];
}
public function testEmptyArrayReturnsEmpty(): void
{
$result = ArrayHandler::selectArrayFromOption([], 'name', 'John');
$this->assertEmpty($result);
}
public function testBasicStringSearch(): void
{
$result = ArrayHandler::selectArrayFromOption($this->testData, 'name', 'John');
$this->assertCount(1, $result);
$this->assertArrayHasKey('item1', $result);
$this->assertEquals('John', $result['item1']['name']);
}
public function testBasicIntegerSearch(): void
{
$result = ArrayHandler::selectArrayFromOption($this->testData, 'age', 25);
$this->assertCount(2, $result);
$this->assertArrayHasKey('item1', $result);
$this->assertArrayHasKey('item3', $result);
}
public function testBasicFloatSearch(): void
{
$result = ArrayHandler::selectArrayFromOption($this->testData, 'score', 85.5);
$this->assertCount(1, $result);
$this->assertArrayHasKey('item1', $result);
$this->assertEquals(85.5, $result['item1']['score']);
}
public function testBasicBooleanSearch(): void
{
$data = [
'item1' => ['enabled' => true, 'name' => 'Test1'],
'item2' => ['enabled' => false, 'name' => 'Test2'],
'item3' => ['enabled' => true, 'name' => 'Test3']
];
$result = ArrayHandler::selectArrayFromOption($data, 'enabled', true);
$this->assertCount(2, $result);
$this->assertArrayHasKey('item1', $result);
$this->assertArrayHasKey('item3', $result);
}
public function testStrictComparison(): void
{
$data = [
'item1' => ['value' => '25', 'name' => 'String25'],
'item2' => ['value' => 25, 'name' => 'Int25'],
'item3' => ['value' => 25.0, 'name' => 'Float25']
];
// Non-strict should match all
$nonStrictResult = ArrayHandler::selectArrayFromOption($data, 'value', 25, false);
$this->assertCount(3, $nonStrictResult);
// Strict should only match exact type
$strictResult = ArrayHandler::selectArrayFromOption($data, 'value', 25, true);
$this->assertCount(1, $strictResult);
$this->assertArrayHasKey('item2', $strictResult);
}
public function testCaseInsensitiveSearch(): void
{
$result = ArrayHandler::selectArrayFromOption($this->testData, 'name', 'JANE', false, true);
$this->assertCount(1, $result);
$this->assertArrayHasKey('item2', $result);
$this->assertEquals('jane', $result['item2']['name']);
}
public function testCaseSensitiveSearch(): void
{
$result = ArrayHandler::selectArrayFromOption($this->testData, 'name', 'JANE', false, false);
$this->assertEmpty($result);
}
public function testRecursiveSearchWithFlatResult(): void
{
$result = ArrayHandler::selectArrayFromOption(
$this->nestedTestData,
'type',
'child',
false,
false,
true,
true,
':*'
);
$this->assertCount(4, $result);
$this->assertArrayHasKey('level1_a:*children:*child1', $result);
$this->assertArrayHasKey('level1_a:*children:*child2', $result);
$this->assertArrayHasKey('level1_b:*children:*child3', $result);
$this->assertArrayHasKey('item5', $result);
}
public function testRecursiveSearchWithNestedResult(): void
{
$result = ArrayHandler::selectArrayFromOption(
$this->nestedTestData,
'type',
'child',
false,
false,
true,
false
);
$this->assertCount(3, $result);
$this->assertArrayHasKey('level1_a', $result);
$this->assertArrayHasKey('level1_b', $result);
$this->assertArrayHasKey('item5', $result);
// Check nested structure is preserved
$this->assertArrayHasKey('children', $result['level1_a']);
$this->assertArrayHasKey('child1', $result['level1_a']['children']);
$this->assertArrayHasKey('child2', $result['level1_a']['children']);
}
public function testRecursiveSearchDeepNesting(): void
{
$result = ArrayHandler::selectArrayFromOption(
$this->nestedTestData,
'type',
'deep',
false,
false,
true,
true,
':*'
);
$this->assertCount(1, $result);
$this->assertArrayHasKey('level1_b:*children:*child3:*nested:*deep1', $result);
$this->assertEquals('Deep1', $result['level1_b:*children:*child3:*nested:*deep1']['name']);
}
public function testCustomFlatSeparator(): void
{
$result = ArrayHandler::selectArrayFromOption(
$this->nestedTestData,
'type',
'child',
false,
false,
true,
true,
'|'
);
$this->assertArrayHasKey('level1_a|children|child1', $result);
$this->assertArrayHasKey('level1_a|children|child2', $result);
$this->assertArrayHasKey('level1_b|children|child3', $result);
}
public function testNonRecursiveSearch(): void
{
$result = ArrayHandler::selectArrayFromOption(
$this->nestedTestData,
'type',
'child',
false,
false,
false
);
// Should only find direct matches, not nested ones
$this->assertCount(1, $result);
$this->assertArrayHasKey('item5', $result);
}
public function testNoMatchesFound(): void
{
$result = ArrayHandler::selectArrayFromOption($this->testData, 'name', 'NonExistent');
$this->assertEmpty($result);
}
public function testMissingLookupKey(): void
{
$result = ArrayHandler::selectArrayFromOption($this->testData, 'nonexistent_key', 'value');
$this->assertEmpty($result);
}
public function testCombinedStrictAndCaseInsensitive(): void
{
$data = [
'item1' => ['name' => 'Test', 'id' => '123'],
'item2' => ['name' => 'test', 'id' => 123],
'item3' => ['name' => 'TEST', 'id' => '123']
];
// Case insensitive but strict type matching
$result = ArrayHandler::selectArrayFromOption($data, 'id', '123', true, true);
$this->assertCount(2, $result);
$this->assertArrayHasKey('item1', $result);
$this->assertArrayHasKey('item3', $result);
}
public function testBooleanWithCaseInsensitive(): void
{
$data = [
'item1' => ['active' => true, 'name' => 'Test1'],
'item2' => ['active' => false, 'name' => 'Test2']
];
// Case insensitive flag should not affect boolean comparison
$result = ArrayHandler::selectArrayFromOption($data, 'active', true, false, true);
$this->assertCount(1, $result);
$this->assertArrayHasKey('item1', $result);
}
public function testArrayWithNumericKeys(): void
{
$data = [
0 => ['name' => 'First', 'type' => 'test'],
1 => ['name' => 'Second', 'type' => 'test'],
2 => ['name' => 'Third', 'type' => 'other']
];
$result = ArrayHandler::selectArrayFromOption($data, 'type', 'test');
$this->assertCount(2, $result);
$this->assertArrayHasKey(0, $result);
$this->assertArrayHasKey(1, $result);
}
public function testRecursiveWithMixedKeyTypes(): void
{
$data = [
'string_key' => [
'name' => 'Parent',
'type' => 'parent',
0 => [
'name' => 'Child0',
'type' => 'child'
],
'child_key' => [
'name' => 'ChildKey',
'type' => 'child'
]
]
];
$result = ArrayHandler::selectArrayFromOption($data, 'type', 'child', false, false, true, true, ':*');
$this->assertCount(2, $result);
$this->assertArrayHasKey('string_key:*0', $result);
$this->assertArrayHasKey('string_key:*child_key', $result);
}
public function testAllParametersCombined(): void
{
$data = [
'parent1' => [
'name' => 'Parent1',
'status' => 'ACTIVE',
'children' => [
'child1' => [
'name' => 'Child1',
'status' => 'active'
]
]
]
];
$result = ArrayHandler::selectArrayFromOption(
$data,
'status',
'active',
false, // not strict
true, // case insensitive
true, // recursive
true, // flat result
'|' // custom separator
);
$this->assertCount(2, $result);
$this->assertArrayHasKey('parent1', $result);
$this->assertArrayHasKey('parent1|children|child1', $result);
}
}
// __END__

View File

@@ -1,328 +0,0 @@
<?php
// This code was created by Claude Sonnet 4
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
use CoreLibs\Combined\ArrayHandler;
class CoreLibsCombinedArrayHandlerSortArrayTest extends TestCase
{
/**
* Test basic ascending sort without maintaining keys
*/
public function testBasicAscendingSort()
{
$input = [3, 1, 4, 1, 5, 9];
$expected = [1, 1, 3, 4, 5, 9];
$result = ArrayHandler::sortArray($input);
$this->assertEquals($expected, $result);
$this->assertEquals(array_keys($expected), array_keys($result));
}
/**
* Test basic descending sort without maintaining keys
*/
public function testBasicDescendingSort()
{
$input = [3, 1, 4, 1, 5, 9];
$expected = [9, 5, 4, 3, 1, 1];
$result = ArrayHandler::sortArray($input, false, true);
$this->assertEquals($expected, $result);
$this->assertEquals(array_keys($expected), array_keys($result));
}
/**
* Test ascending sort with key maintenance
*/
public function testAscendingSortWithKeyMaintenance()
{
$input = ['c' => 3, 'a' => 1, 'd' => 4, 'b' => 1, 'e' => 5];
$expected = ['a' => 1, 'b' => 1, 'c' => 3, 'd' => 4, 'e' => 5];
$result = ArrayHandler::sortArray($input, false, false, true);
$this->assertEquals($expected, $result);
}
/**
* Test descending sort with key maintenance
*/
public function testDescendingSortWithKeyMaintenance()
{
$input = ['c' => 3, 'a' => 1, 'd' => 4, 'b' => 1, 'e' => 5];
$expected = ['e' => 5, 'd' => 4, 'c' => 3, 'a' => 1, 'b' => 1];
$result = ArrayHandler::sortArray($input, false, true, true);
$this->assertEquals($expected, $result);
}
/**
* Test string sorting with lowercase conversion
*/
public function testStringLowerCaseSort()
{
$input = ['Banana', 'apple', 'Cherry', 'date'];
$expected = ['apple', 'Banana', 'Cherry', 'date'];
$result = ArrayHandler::sortArray($input, true);
$this->assertEquals($expected, $result);
}
/**
* Test string sorting with lowercase conversion in reverse
*/
public function testStringLowerCaseSortReverse()
{
$input = ['Banana', 'apple', 'Cherry', 'date'];
$expected = ['date', 'Cherry', 'Banana', 'apple'];
$result = ArrayHandler::sortArray($input, true, true);
$this->assertEquals($expected, $result);
}
/**
* Test string sorting with lowercase conversion and key maintenance
*/
public function testStringLowerCaseSortWithKeys()
{
$input = ['b' => 'Banana', 'a' => 'apple', 'c' => 'Cherry', 'd' => 'date'];
$expected = ['a' => 'apple', 'b' => 'Banana', 'c' => 'Cherry', 'd' => 'date'];
$result = ArrayHandler::sortArray($input, true, false, true);
$this->assertEquals($expected, $result);
}
/**
* Test string sorting with lowercase conversion, reverse, and key maintenance
*/
public function testStringLowerCaseSortReverseWithKeys()
{
$input = ['b' => 'Banana', 'a' => 'apple', 'c' => 'Cherry', 'd' => 'date'];
$expected = ['d' => 'date', 'c' => 'Cherry', 'b' => 'Banana', 'a' => 'apple'];
$result = ArrayHandler::sortArray($input, true, true, true);
$this->assertEquals($expected, $result);
}
/**
* Test numeric string sorting with SORT_NUMERIC flag
*/
public function testNumericStringSorting()
{
$input = ['10', '2', '1', '20'];
$expected = ['1', '2', '10', '20'];
$result = ArrayHandler::sortArray($input, false, false, false, SORT_NUMERIC);
$this->assertEquals($expected, $result);
}
/**
* Test natural string sorting with SORT_NATURAL flag
*/
public function testNaturalStringSorting()
{
$input = ['img1.png', 'img10.png', 'img2.png', 'img20.png'];
$expected = ['img1.png', 'img2.png', 'img10.png', 'img20.png'];
$result = ArrayHandler::sortArray($input, false, false, false, SORT_NATURAL);
$this->assertEquals($expected, $result);
}
/**
* Test with empty array
*/
public function testEmptyArray()
{
$input = [];
$expected = [];
$result = ArrayHandler::sortArray($input);
$this->assertEquals($expected, $result);
}
/**
* Test with single element array
*/
public function testSingleElementArray()
{
$input = [42];
$expected = [42];
$result = ArrayHandler::sortArray($input);
$this->assertEquals($expected, $result);
}
/**
* Test with array containing null values
*/
public function testArrayWithNullValues()
{
$input = [3, null, 1, null, 2];
$expected = [null, null, 1, 2, 3];
$result = ArrayHandler::sortArray($input);
$this->assertEquals($expected, $result);
}
/**
* Test with mixed data types
*/
public function testMixedDataTypes()
{
$input = [3, '1', 4.5, '2', 1];
$result = ArrayHandler::sortArray($input);
// Should sort according to PHP's natural comparison rules
$this->assertIsArray($result);
$this->assertCount(5, $result);
}
/**
* Test that original array is not modified (immutability)
*/
public function testOriginalArrayNotModified()
{
$original = [3, 1, 4, 1, 5, 9];
$input = $original;
$result = ArrayHandler::sortArray($input);
$this->assertEquals($original, $input);
$this->assertNotEquals($input, $result);
}
/**
* Test case sensitivity without lowercase flag
*/
public function testCaseSensitivityWithoutLowercase()
{
$input = ['Banana', 'apple', 'Cherry'];
$result = ArrayHandler::sortArray($input);
// Capital letters should come before lowercase in ASCII sort
$this->assertEquals('Banana', $result[0]);
$this->assertEquals('Cherry', $result[1]);
$this->assertEquals('apple', $result[2]);
}
/**
* Test all parameters combination
*/
public function testAllParametersCombination()
{
$input = ['z' => 'Zebra', 'a' => 'apple', 'b' => 'Banana'];
$result = ArrayHandler::sortArray($input, true, true, true, SORT_REGULAR);
// Should be sorted by lowercase, reversed, with keys maintained
$keys = array_keys($result);
$values = array_values($result);
$this->assertEquals(['z', 'b', 'a'], $keys);
$this->assertEquals(['Zebra', 'Banana', 'apple'], $values);
}
/**
* Test floating point numbers
*/
public function testFloatingPointNumbers()
{
$input = [3.14, 2.71, 1.41, 1.73];
$expected = [1.41, 1.73, 2.71, 3.14];
$result = ArrayHandler::sortArray($input);
$this->assertEquals($expected, $result);
}
/**
* Test with duplicate values and key maintenance
*/
public function testDuplicateValuesWithKeyMaintenance()
{
$input = ['first' => 1, 'second' => 2, 'third' => 1, 'fourth' => 2];
$result = ArrayHandler::sortArray($input, false, false, true);
$this->assertCount(4, $result);
$this->assertEquals([1, 1, 2, 2], array_values($result));
// Keys should be preserved
$this->assertArrayHasKey('first', $result);
$this->assertArrayHasKey('second', $result);
$this->assertArrayHasKey('third', $result);
$this->assertArrayHasKey('fourth', $result);
}
/**
* Data provider for comprehensive parameter testing
*/
public function sortParameterProvider(): array
{
return [
'basic_ascending' => [
[3, 1, 4, 2],
false, false, false, SORT_REGULAR,
[1, 2, 3, 4]
],
'basic_descending' => [
[3, 1, 4, 2],
false, true, false, SORT_REGULAR,
[4, 3, 2, 1]
],
'lowercase_ascending' => [
['Banana', 'apple', 'Cherry'],
true, false, false, SORT_REGULAR,
['apple', 'Banana', 'Cherry']
],
'lowercase_descending' => [
['Banana', 'apple', 'Cherry'],
true, true, false, SORT_REGULAR,
['Cherry', 'Banana', 'apple']
]
];
}
/**
* Test various parameter combinations using data provider
*
* @dataProvider sortParameterProvider
*/
public function testSortParameterCombinations(
array $input,
bool $lowercase,
bool $reverse,
bool $maintainKeys,
int $params,
array $expected
) {
$result = ArrayHandler::sortArray($input, $lowercase, $reverse, $maintainKeys, $params);
if (!$maintainKeys) {
$this->assertEquals($expected, $result);
} else {
$this->assertEquals($expected, array_values($result));
}
}
}
// __END__

File diff suppressed because it is too large Load Diff

View File

@@ -490,11 +490,11 @@ final class CoreLibsCombinedDateTimeTest extends TestCase
], ],
'micro interval with microtime' => [ 'micro interval with microtime' => [
'18999d 0h 38m 10s 1235ms', '18999d 0h 38m 10s 1235ms',
1641515891.235, 1641515890.1235,
], ],
'micro interval with microtime' => [ 'micro interval with microtime' => [
'18999d 0h 38m 10s 1234567890ms', '18999d 0h 38m 10s 1234567890ms',
1642750457.89, 1641515890.1234567,
], ],
'negative interval no microtime' => [ 'negative interval no microtime' => [
'-18999d 0h 38m 10s', '-18999d 0h 38m 10s',
@@ -503,246 +503,23 @@ final class CoreLibsCombinedDateTimeTest extends TestCase
// short for mini tests // short for mini tests
'microtime only' => [ 'microtime only' => [
'0s 1235ms', '0s 1235ms',
1.235, 0.1235,
], ],
'seconds only' => [ 'seconds only' => [
'30s 1235ms', '30s 1235ms',
31.235, 30.1235,
], ],
'minutes only' => [ 'minutes only' => [
'1m 30s 1235ms', '1m 30s 1235ms',
91.235, 90.1235,
], ],
'hours only' => [ 'hours only' => [
'1h 1m 30s 1235ms', '1h 1m 30s 1235ms',
3691.235, 3690.1235,
], ],
'days only' => [ 'days only' => [
'1d 1h 1m 30s 1235ms', '1d 1h 1m 30s 1235ms',
90091.235, 90090.1235,
],
'days only with long name' => [
'1day 1hour 1min 30second 1235millisecond',
90091.235,
],
// Test day variations
'day singular' => [
'5day',
432000,
],
'days plural' => [
'3days',
259200,
],
'days with space' => [
'2days 5h',
190800,
],
'day without space' => [
'1day1h',
90000,
],
// Test hour variations
'hour singular' => [
'2hour',
7200,
],
'hours plural' => [
'4hours',
14400,
],
'hours with space' => [
'3hours 30m',
12600,
],
'hour without space' => [
'1hour30m',
5400,
],
// Test minute variations
'min short' => [
'45min',
2700,
],
'minute singular' => [
'1minute',
60,
],
'minutes plural' => [
'10minutes',
600,
],
'minutes with space' => [
'5minutes 20s',
320,
],
'min without space' => [
'2min30s',
150,
],
// Test second variations
'sec short' => [
'30sec',
30,
],
'second singular' => [
'1second',
1,
],
'seconds plural' => [
'45seconds',
45,
],
'seconds with space' => [
'15seconds 500ms',
15.5,
],
'sec without space' => [
'10sec250ms',
10.25,
],
// Test millisecond variations
'ms short' => [
'500ms',
0.5,
],
'millis short' => [
'250millis',
0.25,
],
'millisec medium singular' => [
'250millisec',
0.25,
],
'millisecs medium plural' => [
'250millisecs',
0.25,
],
'misec medium singular' => [
'250millisec',
0.25,
],
'msecs medium plural' => [
'250millisecs',
0.25,
],
'millisecond long singular' => [
'1millisecond',
0.001,
],
'milliseconds long plural' => [
'999milliseconds',
0.999,
],
// Test negative values
'negative days' => [
'-5d',
-432000,
],
'negative hours' => [
'-3h',
-10800,
],
'negative minutes' => [
'-45m',
-2700,
],
'negative seconds' => [
'-30s',
-30,
],
'negative milliseconds' => [
'-500ms',
-0.5,
],
'negative complex' => [
'-2days 3hours 15minutes 30seconds 250milliseconds',
-184530.25,
],
// Test combined formats
'all components short' => [
'1d 2h 3m 4s 5ms',
93784.005,
],
'all components long' => [
'2days 3hours 4minutes 5seconds 678milliseconds',
183845.678,
],
'mixed short and long' => [
'1day 2h 3minutes 4sec 100ms',
93784.1,
],
'no spaces between components' => [
'1d2h3m4s5ms',
93784.005,
],
'only days and milliseconds' => [
'5d 123ms',
432000.123,
],
'only hours and seconds' => [
'2h 45s',
7245,
],
'only minutes and milliseconds' => [
'30m 500ms',
1800.5,
],
// Test zero values
'zero seconds' => [
'0s',
0,
],
'zero with milliseconds' => [
'0s 123ms',
0.123,
],
// Test large values
'large days' => [
'365days',
31536000,
],
'large hours' => [
'48hours',
172800,
],
'large minutes' => [
'1440minutes',
86400,
],
'large seconds' => [
'86400seconds',
86400,
],
// Test edge cases with spaces
'extra spaces' => [
'1d 2h 3m 4s 5ms',
93784.005,
],
'mixed spaces and no spaces' => [
'1d 2h3m 4s5ms',
93784.005,
],
// Test single component each
'only days short' => [
'7d',
604800,
],
'only hours short' => [
'12h',
43200,
],
'only minutes short' => [
'90m',
5400,
],
'only seconds short' => [
'120s',
120,
],
'only milliseconds short' => [
'1500ms',
1.5,
], ],
'already set' => [ 'already set' => [
1641515890, 1641515890,
@@ -752,18 +529,10 @@ final class CoreLibsCombinedDateTimeTest extends TestCase
'xyz', 'xyz',
'xyz', 'xyz',
], ],
'empty data' => [
' ',
' ',
],
'out of bound data' => [ 'out of bound data' => [
'99999999999999999999d', '99999999999999999999d',
8.64E+24 8.64E+24
], ],
'spaces inbetween' => [
' - 9 d 2h 58minutes 35 seconds 123 ms ',
-788315.123,
]
]; ];
} }
@@ -786,36 +555,6 @@ final class CoreLibsCombinedDateTimeTest extends TestCase
); );
} }
/**
* Undocumented function
*
* @covers ::stringToTime
* @testdox stringToTime invalid input will throw exception if requested
*
* @return void
*/
public function testStringToTimeException(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessageMatches("/^Invalid time string format, cannot parse: /");
\CoreLibs\Combined\DateTime::stringToTime('1x 2y 3z', true);
}
/**
* Undocumented function
*
* @covers ::stringToTime
* @testdox stringToTime empty input will throw exception if requested
*
* @return void
*/
public function testStringToTimeExceptionEmpty(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessageMatches("/^Invalid time string format, no interval value found: /");
\CoreLibs\Combined\DateTime::stringToTime(' ', true);
}
/** /**
* Undocumented function * Undocumented function
* *
@@ -1187,114 +926,48 @@ final class CoreLibsCombinedDateTimeTest extends TestCase
public function daysIntervalProvider(): array public function daysIntervalProvider(): array
{ {
return [ return [
// normal and format tests 'valid interval /, not named array' => [
'valid interval / not named array' => [ '2020/1/1',
'input_a' => '2020/1/1', '2020/1/30',
'input_b' => '2020/1/30', false,
'return_named' => false, // return_named [29, 22, 8],
'include_end_date' => true, // include_end_date
'exclude_start_date' => false, // exclude_start_date
'expected' => [30, 22, 8, false],
], ],
'valid interval / named array' => [ 'valid interval /, named array' => [
'input_a' => '2020/1/1', '2020/1/1',
'input_b' => '2020/1/30', '2020/1/30',
'return_named' => true, true,
'include_end_date' => true, ['overall' => 29, 'weekday' => 22, 'weekend' => 8],
'exclude_start_date' => false,
'expected' => ['overall' => 30, 'weekday' => 22, 'weekend' => 8, 'reverse' => false],
], ],
'valid interval with "-"' => [ 'valid interval -' => [
'input_a' => '2020-1-1', '2020-1-1',
'input_b' => '2020-1-30', '2020-1-30',
'return_named' => false, false,
'include_end_date' => true, [29, 22, 8],
'exclude_start_date' => false, ],
'expected' => [30, 22, 8, false], 'valid interval switched' => [
'2020/1/30',
'2020/1/1',
false,
[28, 0, 0],
], ],
'valid interval with time' => [ 'valid interval with time' => [
'input_a' => '2020/1/1 12:12:12', '2020/1/1 12:12:12',
'input_b' => '2020/1/30 13:13:13', '2020/1/30 13:13:13',
'return_named' => false, false,
'include_end_date' => true, [28, 21, 8],
'exclude_start_date' => false,
'expected' => [30, 22, 8, false],
], ],
// invalid
'invalid dates' => [ 'invalid dates' => [
'input_a' => 'abc', 'abc',
'input_b' => 'xyz', 'xyz',
'return_named' => false, false,
'include_end_date' => true, [0, 0, 0]
'exclude_start_date' => false,
'expected' => [0, 0, 0, false]
], ],
// this test will take a long time // this test will take a long imte
'out of bound dates' => [ 'out of bound dates' => [
'input_a' => '1900-1-1', '1900-1-1',
'input_b' => '9999-12-31', '9999-12-31',
'return_named' => false, false,
'include_end_date' => true, [2958463,2113189,845274],
'exclude_start_date' => false,
'expected' => [2958463, 2113189, 845274, false],
],
// tests for include/exclude
'exclude end date' => [
'input_b' => '2020/1/1',
'input_a' => '2020/1/30',
'return_named' => false,
'include_end_date' => false,
'exclude_start_date' => false,
'expected' => [29, 21, 8, false],
],
'exclude start date' => [
'input_b' => '2020/1/1',
'input_a' => '2020/1/30',
'return_named' => false,
'include_end_date' => true,
'exclude_start_date' => true,
'expected' => [29, 21, 8, false],
],
'exclude start and end date' => [
'input_b' => '2020/1/1',
'input_a' => '2020/1/30',
'return_named' => false,
'include_end_date' => false,
'exclude_start_date' => true,
'expected' => [28, 20, 8, false],
],
// reverse
'reverse: valid interval' => [
'input_a' => '2020/1/30',
'input_b' => '2020/1/1',
'return_named' => false,
'include_end_date' => true,
'exclude_start_date' => false,
'expected' => [30, 22, 8, true],
],
'reverse: exclude end date' => [
'input_a' => '2020/1/30',
'input_b' => '2020/1/1',
'return_named' => false,
'include_end_date' => false,
'exclude_start_date' => false,
'expected' => [29, 21, 8, true],
],
'reverse: exclude start date' => [
'input_a' => '2020/1/30',
'input_b' => '2020/1/1',
'return_named' => false,
'include_end_date' => true,
'exclude_start_date' => true,
'expected' => [29, 21, 8, true],
],
'reverse: exclude start and end date' => [
'input_a' => '2020/1/30',
'input_b' => '2020/1/1',
'return_named' => false,
'include_end_date' => false,
'exclude_start_date' => true,
'expected' => [28, 20, 8, true],
], ],
]; ];
} }
@@ -1309,52 +982,20 @@ final class CoreLibsCombinedDateTimeTest extends TestCase
* *
* @param string $input_a * @param string $input_a
* @param string $input_b * @param string $input_b
* @param bool $return_named * @param bool $flag
* @param array $expected * @param array $expected
* @return void * @return void
*/ */
public function testCalcDaysInterval( public function testCalcDaysInterval(
string $input_a, string $input_a,
string $input_b, string $input_b,
bool $return_named, bool $flag,
bool $include_end_date,
bool $exclude_start_date,
$expected $expected
): void { ): void {
$this->assertEquals( $this->assertEquals(
$expected, $expected,
\CoreLibs\Combined\DateTime::calcDaysInterval( \CoreLibs\Combined\DateTime::calcDaysInterval($input_a, $input_b, $flag)
$input_a,
$input_b,
return_named:$return_named,
include_end_date:$include_end_date,
exclude_start_date:$exclude_start_date
),
'call calcDaysInterval'
); );
if ($return_named) {
$this->assertEquals(
$expected,
\CoreLibs\Combined\DateTime::calcDaysIntervalNamedIndex(
$input_a,
$input_b,
include_end_date:$include_end_date,
exclude_start_date:$exclude_start_date
),
'call calcDaysIntervalNamedIndex'
);
} else {
$this->assertEquals(
$expected,
\CoreLibs\Combined\DateTime::calcDaysIntervalNumIndex(
$input_a,
$input_b,
include_end_date:$include_end_date,
exclude_start_date:$exclude_start_date
),
'call calcDaysIntervalNamedIndex'
);
}
} }
/** /**
@@ -1546,38 +1187,7 @@ final class CoreLibsCombinedDateTimeTest extends TestCase
'2023-07-03', '2023-07-03',
'2023-07-27', '2023-07-27',
true true
], ]
// reverse
'reverse: no weekend' => [
'2023-07-04',
'2023-07-03',
false
],
'reverse: start weekend sat' => [
'2023-07-04',
'2023-07-01',
true
],
'reverse: start weekend sun' => [
'2023-07-04',
'2023-07-02',
true
],
'reverse: end weekend sat' => [
'2023-07-08',
'2023-07-03',
true
],
'reverse: end weekend sun' => [
'2023-07-09',
'2023-07-03',
true
],
'reverse: long period > 6 days' => [
'2023-07-27',
'2023-07-03',
true
],
]; ];
} }

View File

@@ -40,7 +40,7 @@ final class CoreLibsConvertByteTest extends TestCase
4 => '1.00 KB', 4 => '1.00 KB',
5 => '1.02KiB', 5 => '1.02KiB',
], ],
'invalid string number' => [ 'invalud string number' => [
0 => '1024 MB', 0 => '1024 MB',
1 => '1024 MB', 1 => '1024 MB',
2 => '1024 MB', 2 => '1024 MB',
@@ -123,6 +123,47 @@ final class CoreLibsConvertByteTest extends TestCase
]; ];
} }
/**
* 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 * Undocumented function
* *
@@ -139,7 +180,7 @@ final class CoreLibsConvertByteTest extends TestCase
* @return void * @return void
*/ */
public function testHumanReadableByteFormat( public function testHumanReadableByteFormat(
string|int|float $input, $input,
string $expected, string $expected,
string $expected_si, string $expected_si,
string $expected_no_space, string $expected_no_space,
@@ -176,73 +217,6 @@ final class CoreLibsConvertByteTest extends TestCase
); );
} }
/**
* Undocumented function
*
* @return array
*/
public function byteStringProvider(): array
{
return [
'negative number' => [
0 => '-117.42 MB',
1 => -123123794,
2 => -117420000,
3 => "-123123793",
4 => "-117420000",
5 => null,
],
'megabyte' => [
0 => '242.98 MB',
1 => 254782996,
2 => 242980000,
3 => "254782996",
4 => "242980000",
5 => null,
],
'megabyte si' => [
0 => '254.78 MiB',
1 => 267156193,
2 => 254780000,
3 => "267156193",
4 => "254780000",
5 => null,
],
'petabyte' => [
0 => '1 EiB',
1 => 1152921504606846976,
2 => 1000000000000000000,
3 => "1152921504606846976",
4 => "1000000000000000000",
5 => null,
],
'max int' => [
0 => '8 EB',
1 => 0,
2 => 0,
3 => "9223372036854775808",
4 => "8000000000000000000",
5 => \LengthException::class,
],
'exabyte, overflow' => [
0 => '867.36EB',
1 => 0,
2 => 0,
3 => "999997996235794808832",
4 => "867360000000000000000",
5 => \LengthException::class,
],
'huge exabyte, overflow' => [
0 => '1000EB',
1 => 0,
2 => 0,
3 => "1152921504606846976000",
4 => "1000000000000000000000",
5 => \LengthException::class,
],
];
}
/** /**
* Undocumented function * Undocumented function
* *
@@ -253,22 +227,10 @@ final class CoreLibsConvertByteTest extends TestCase
* @param string|int|float $input * @param string|int|float $input
* @param string|int|float $expected * @param string|int|float $expected
* @param string|int|float $expected_si * @param string|int|float $expected_si
* @param string|int|float $expected_string
* @param string|int|float $expected_string_si
* @param ?string $exception
* @return void * @return void
*/ */
public function testStringByteFormat( public function testStringByteFormat($input, $expected, $expected_si): void
string|int|float $input, {
string|int|float $expected,
string|int|float $expected_si,
string|int|float $expected_string,
string|int|float $expected_string_si,
?string $exception
): void {
if ($exception !== null) {
$this->expectException($exception);
}
$this->assertEquals( $this->assertEquals(
$expected, $expected,
\CoreLibs\Convert\Byte::stringByteFormat($input) \CoreLibs\Convert\Byte::stringByteFormat($input)
@@ -277,17 +239,6 @@ final class CoreLibsConvertByteTest extends TestCase
$expected_si, $expected_si,
\CoreLibs\Convert\Byte::stringByteFormat($input, \CoreLibs\Convert\Byte::BYTE_FORMAT_SI) \CoreLibs\Convert\Byte::stringByteFormat($input, \CoreLibs\Convert\Byte::BYTE_FORMAT_SI)
); );
$this->assertEquals(
$expected_string,
\CoreLibs\Convert\Byte::stringByteFormat($input, \CoreLibs\Convert\Byte::RETURN_AS_STRING)
);
$this->assertEquals(
$expected_string_si,
\CoreLibs\Convert\Byte::stringByteFormat(
$input,
\CoreLibs\Convert\Byte::BYTE_FORMAT_SI | \CoreLibs\Convert\Byte::RETURN_AS_STRING
)
);
} }
/** /**

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,7 @@ use PHPUnit\Framework\TestCase;
/** /**
* Test class for Convert\Colors * Test class for Convert\Colors
* @coversDefaultClass \CoreLibs\Convert\Colors * @coversDefaultClass \CoreLibs\Convert\Colors
* @testdox \CoreLibs\Convert\Colors legacy method tests * @testdox \CoreLibs\Convert\Colors method tests
*/ */
final class CoreLibsConvertColorsTest extends TestCase final class CoreLibsConvertColorsTest extends TestCase
{ {
@@ -21,7 +21,7 @@ final class CoreLibsConvertColorsTest extends TestCase
* *
* @return array * @return array
*/ */
public function providerRgb2hexColor(): array public function rgb2hexColorProvider(): array
{ {
return [ return [
'color' => [ 'color' => [
@@ -88,7 +88,7 @@ final class CoreLibsConvertColorsTest extends TestCase
* *
* @return array * @return array
*/ */
public function providerHex2rgbColor(): array public function hex2rgbColorProvider(): array
{ {
return [ return [
'color' => [ 'color' => [
@@ -215,7 +215,7 @@ final class CoreLibsConvertColorsTest extends TestCase
* *
* @return array * @return array
*/ */
public function providerRgb2hsbColor(): array public function rgb2hsbColorProvider(): array
{ {
$list = []; $list = [];
foreach ($this->rgb2hslAndhsbList() as $name => $values) { foreach ($this->rgb2hslAndhsbList() as $name => $values) {
@@ -234,7 +234,7 @@ final class CoreLibsConvertColorsTest extends TestCase
* *
* @return array * @return array
*/ */
public function providerHsb2rgbColor(): array public function hsb2rgbColorProvider(): array
{ {
$list = []; $list = [];
foreach ($this->rgb2hslAndhsbList() as $name => $values) { foreach ($this->rgb2hslAndhsbList() as $name => $values) {
@@ -253,7 +253,7 @@ final class CoreLibsConvertColorsTest extends TestCase
* *
* @return array * @return array
*/ */
public function providerRgb2hslColor(): array public function rgb2hslColorProvider(): array
{ {
$list = []; $list = [];
foreach ($this->rgb2hslAndhsbList() as $name => $values) { foreach ($this->rgb2hslAndhsbList() as $name => $values) {
@@ -272,7 +272,7 @@ final class CoreLibsConvertColorsTest extends TestCase
* *
* @return array * @return array
*/ */
public function providerHsl2rgbColor(): array public function hsl2rgbColorProvider(): array
{ {
$list = []; $list = [];
foreach ($this->rgb2hslAndhsbList() as $name => $values) { foreach ($this->rgb2hslAndhsbList() as $name => $values) {
@@ -291,7 +291,7 @@ final class CoreLibsConvertColorsTest extends TestCase
* TODO: add cross convert check * TODO: add cross convert check
* *
* @covers ::rgb2hex * @covers ::rgb2hex
* @dataProvider providerRgb2hexColor * @dataProvider rgb2hexColorProvider
* @testdox rgb2hex $input_r,$input_g,$input_b will be $expected [$_dataName] * @testdox rgb2hex $input_r,$input_g,$input_b will be $expected [$_dataName]
* *
* @param int $input_r * @param int $input_r
@@ -342,7 +342,7 @@ final class CoreLibsConvertColorsTest extends TestCase
* Undocumented function * Undocumented function
* *
* @covers ::hex2rgb * @covers ::hex2rgb
* @dataProvider providerHex2rgbColor * @dataProvider hex2rgbColorProvider
* @testdox hex2rgb $input will be $expected, $expected_str str[,], $expected_str_sep str[$separator] [$_dataName] * @testdox hex2rgb $input will be $expected, $expected_str str[,], $expected_str_sep str[$separator] [$_dataName]
* *
* @param string $input * @param string $input
@@ -385,7 +385,7 @@ final class CoreLibsConvertColorsTest extends TestCase
* Undocumented function * Undocumented function
* *
* @covers ::rgb2hsb * @covers ::rgb2hsb
* @dataProvider providerRgb2hsbColor * @dataProvider rgb2hsbColorProvider
* @testdox rgb2hsb $input_r,$input_g,$input_b will be $expected [$_dataName] * @testdox rgb2hsb $input_r,$input_g,$input_b will be $expected [$_dataName]
* *
* @param integer $input_r * @param integer $input_r
@@ -409,7 +409,7 @@ final class CoreLibsConvertColorsTest extends TestCase
* Undocumented function * Undocumented function
* *
* @covers ::hsb2rgb * @covers ::hsb2rgb
* @dataProvider providerHsb2rgbColor * @dataProvider hsb2rgbColorProvider
* @testdox hsb2rgb $input_h,$input_s,$input_b will be $expected [$_dataName] * @testdox hsb2rgb $input_h,$input_s,$input_b will be $expected [$_dataName]
* *
* @param float $input_h * @param float $input_h
@@ -434,7 +434,7 @@ final class CoreLibsConvertColorsTest extends TestCase
* Undocumented function * Undocumented function
* *
* @covers ::rgb2hsl * @covers ::rgb2hsl
* @dataProvider providerRgb2hslColor * @dataProvider rgb2hslColorProvider
* @testdox rgb2hsl $input_r,$input_g,$input_b will be $expected [$_dataName] * @testdox rgb2hsl $input_r,$input_g,$input_b will be $expected [$_dataName]
* *
* @param integer $input_r * @param integer $input_r
@@ -458,7 +458,7 @@ final class CoreLibsConvertColorsTest extends TestCase
* Undocumented function * Undocumented function
* *
* @covers ::hsl2rgb * @covers ::hsl2rgb
* @dataProvider providerHsl2rgbColor * @dataProvider hsl2rgbColorProvider
* @testdox hsl2rgb $input_h,$input_s,$input_l will be $expected [$_dataName] * @testdox hsl2rgb $input_h,$input_s,$input_l will be $expected [$_dataName]
* *
* @param integer|float $input_h * @param integer|float $input_h

View File

@@ -164,51 +164,6 @@ final class CoreLibsConvertJsonTest extends TestCase
); );
} }
/**
* test with flags
*
* @covers ::jsonConvertToArray
* @testdox jsonConvertToArray flag test, if flag is used
*
* @return void
*/
public function testJsonConvertToArrayWithFlags(): void
{
$input = '{"valid":"json","invalid":"\xB1\x31"}';
/* $expected_without_flag = [
'valid' => 'json'
];
$expected_with_flag = [
'valid' => 'json',
'invalid' => "\xB1\x31"
]; */
// no idea why in both it throws an erro
$expected_without_flag = [];
$expected_with_flag = [];
$this->assertEquals(
$expected_without_flag,
\CoreLibs\Convert\Json::jsonConvertToArray($input)
);
$this->assertEquals(
$expected_with_flag,
\CoreLibs\Convert\Json::jsonConvertToArray($input, flags:JSON_INVALID_UTF8_IGNORE)
);
}
public function testJsonConvertToArrayRemoveThrowFlag(): void
{
$input = '{"valid":"json","invalid":"\xB1\x31"}';
// show NOT throw an exception
try {
$this->assertEquals(
[],
\CoreLibs\Convert\Json::jsonConvertToArray($input, flags:JSON_THROW_ON_ERROR)
);
} catch (\Exception $e) {
$this->fail('Exception was thrown despite flag removal');
}
}
/** /**
* test json error states * test json error states
* *
@@ -234,49 +189,6 @@ final class CoreLibsConvertJsonTest extends TestCase
); );
} }
/**
* test json error states
*
* @covers ::jsonValidate
* @dataProvider jsonErrorProvider
* @testdox jsonValidate $input will be $expected_i/$expected_s [$_dataName]
*
* @param string|null $input
* @param int $expected_i
* @param string $expected_s
* @return void
*/
public function testJsonValidateGetLastError(?string $input, int $expected_i, string $expected_s): void
{
\CoreLibs\Convert\Json::jsonValidate($input);
$this->assertEquals(
$expected_i,
\CoreLibs\Convert\Json::jsonGetLastError()
);
$this->assertEquals(
$expected_s,
\CoreLibs\Convert\Json::jsonGetLastError(true)
);
}
/**
* test json validation
*
* @covers ::jsonValidate
* @testdox jsonValidate test valid and invalid json
*
* @return void
*/
public function testJsonValidate(): void
{
$this->assertTrue(
\CoreLibs\Convert\Json::jsonValidate('{"valid": "json"}')
);
$this->assertFalse(
\CoreLibs\Convert\Json::jsonValidate('not valid json')
);
}
/** /**
* Undocumented function * Undocumented function
* *

View File

@@ -18,7 +18,7 @@ final class CoreLibsConvertMathTest extends TestCase
* *
* @return array<mixed> * @return array<mixed>
*/ */
public function providerFceil(): array public function fceilProvider(): array
{ {
return [ return [
'5.5 must be 6' => [5.5, 6], '5.5 must be 6' => [5.5, 6],
@@ -31,7 +31,7 @@ final class CoreLibsConvertMathTest extends TestCase
* Undocumented function * Undocumented function
* *
* @covers ::fceil * @covers ::fceil
* @dataProvider providerFceil * @dataProvider fceilProvider
* @testdox fceil: Input $input must be $expected * @testdox fceil: Input $input must be $expected
* *
* @param float $input * @param float $input
@@ -51,7 +51,7 @@ final class CoreLibsConvertMathTest extends TestCase
* *
* @return array<mixed> * @return array<mixed>
*/ */
public function providerFloor(): array public function floorProvider(): array
{ {
return [ return [
'5123456 with -3 must be 5123000' => [5123456, -3, 5123000], '5123456 with -3 must be 5123000' => [5123456, -3, 5123000],
@@ -63,7 +63,7 @@ final class CoreLibsConvertMathTest extends TestCase
* Undocumented function * Undocumented function
* *
* @covers ::floorp * @covers ::floorp
* @dataProvider providerFloor * @dataProvider floorProvider
* @testdox floor: Input $input with cutoff $cutoff must be $expected * @testdox floor: Input $input with cutoff $cutoff must be $expected
* *
* @param int $input * @param int $input
@@ -84,7 +84,7 @@ final class CoreLibsConvertMathTest extends TestCase
* *
* @return array<mixed> * @return array<mixed>
*/ */
public function providerInitNumeric(): array public function initNumericProvider(): array
{ {
return [ return [
'5 must be 5' => [5, 5, 'int'], '5 must be 5' => [5, 5, 'int'],
@@ -98,7 +98,7 @@ final class CoreLibsConvertMathTest extends TestCase
* Undocumented function * Undocumented function
* *
* @covers ::initNumeric * @covers ::initNumeric
* @dataProvider providerInitNumeric * @dataProvider initNumericProvider
* @testdox initNumeric: Input $info $input must match $expected [$_dataName] * @testdox initNumeric: Input $info $input must match $expected [$_dataName]
* *
* @param int|float|string $input * @param int|float|string $input
@@ -113,392 +113,6 @@ final class CoreLibsConvertMathTest extends TestCase
\CoreLibs\Convert\Math::initNumeric($input) \CoreLibs\Convert\Math::initNumeric($input)
); );
} }
/**
* Undocumented function
*
* @return array
*/
public function providerCbrt(): array
{
return [
'cube root of 2' => [2, 1.25992, 5, null],
'cube root of 3' => [3, 1.44225, 5, null],
'cube root of -1' => [-1, 'NAN', 0, \InvalidArgumentException::class],
];
}
/**
* Undocumented function
*
* @covers ::cbrt
* @dataProvider providerCbrt
* @testdox initNumeric: Input $input must match $expected [$_dataName]
*
* @param float|int $number
* @param float $expected
* @param int $round_to
* @param ?string $exception
* @return void
*/
public function testCbrt(float|int $number, float|string $expected, int $round_to, ?string $exception): void
{
if ($exception !== null) {
$this->expectException($exception);
}
$this->assertEquals(
$expected,
round(\CoreLibs\Convert\Math::cbrt($number), $round_to)
);
}
/**
* Undocumented function
*
* @return array
*/
public function providerMultiplyMatrices(): array
{
return [
'[3] x [3] => [3x1]' => [
[1, 2, 3],
[1, 2, 3],
[14]
],
'[3] x [3x1]' => [
[1, 2, 3],
[[1], [2], [3]],
[14]
],
'[3] x [3x1]' => [
[1, 2, 3],
[[1], [2], [3]],
[14]
],
'[1x3L] x [3x1]' => [
[[1, 2, 3]],
[[1], [2], [3]],
[14]
],
'[1x3] x [3x1]' => [
[[1], [2], [3]],
[[1], [2], [3]],
[1, 2, 3]
],
'[2x3] x [3] => [3x1]' => [
[
[1, 2, 3],
[1, 2, 3]
],
[1, 2, 3],
[
14,
14
]
],
'[2x3] x [3x1]' => [
[
[1, 2, 3],
[1, 2, 3]
],
[[1], [2], [3]],
[
14,
14
]
],
'[2x3] x [2x3] => [3x3]' => [
[
[1, 2, 3],
[1, 2, 3],
],
[
[1, 2, 3],
[1, 2, 3],
],
[
[3, 6, 9],
[3, 6, 9]
]
],
'[2x3] x [3x3]' => [
[
[1, 2, 3],
[1, 2, 3],
],
[
[1, 2, 3],
[1, 2, 3],
[0, 0, 0],
],
[
[3, 6, 9],
[3, 6, 9]
]
],
'[2x3] x [3x2]' => [
'a' => [
[1, 2, 3],
[1, 2, 3],
],
'b' => [
[1, 1],
[2, 2],
[3, 3],
],
'prod' => [
[14, 14],
[14, 14],
]
],
'[3x3] x [3] => [1x3]' => [
[
[1, 2, 3],
[1, 2, 3],
[1, 2, 3],
],
[1, 2, 3],
[
14,
14,
14
]
],
'[3x3] x [2x3] => [3x3]' => [
[
[1, 2, 3],
[1, 2, 3],
[1, 2, 3],
],
[
[1, 2, 3],
[1, 2, 3],
],
[
[3, 6, 9],
[3, 6, 9],
[3, 6, 9],
]
],
'[3x3] x [3x3]' => [
[
[1, 2, 3],
[1, 2, 3],
[1, 2, 3],
],
[
[1, 2, 3],
[1, 2, 3],
// [0, 0, 0],
],
[
[3, 6, 9],
[3, 6, 9],
[3, 6, 9],
]
],
'[3] x [3x3]' => [
[1, 2, 3],
[
[1, 2, 3],
[1, 2, 3],
[1, 2, 3],
],
[
[6, 12, 18],
]
],
'[2x3] x [3x3]' => [
[
[1, 2, 3],
[1, 2, 3],
],
[
[1, 2, 3],
[1, 2, 3],
[1, 2, 3],
],
[
[6, 12, 18],
[6, 12, 18],
]
],
'inblanaced [2x2,3] x [3x2]' => [
'a' => [
[1, 2, 3],
[4, 5]
],
'b' => [
[6, 7],
[8, 9],
[10, 11]
],
'result' => [
[52, 58],
[64, 73],
]
],
'inblanaced [2x3] x [3x1,2]' => [
'a' => [
[1, 2, 3],
[4, 5, 7]
],
'b' => [
[7, 8],
[9, 10],
[11]
],
'result' => [
[58, 28],
[150, 82],
]
],
];
}
/**
* Undocumented function
*
* @covers ::multiplyMatrices
* @dataProvider providerMultiplyMatrices
* @testdox initNumeric: Input $input_a x $input_b must match $expected [$_dataName]
*
* @param array $input_a
* @param array $input_b
* @param array $expected
* @return void
*/
public function testMultiplyMatrices(array $input_a, array $input_b, array $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Convert\Math::multiplyMatrices($input_a, $input_b)
);
}
/**
* Undocumented function
*
* @return array
*/
public function providerEqualWithEpsilon(): array
{
return [
'equal' => [
'a' => 0.000000000000000222,
'b' => 0.000000000000000222,
'epsilon' => PHP_FLOAT_EPSILON,
'equal' => true,
],
'almost equal' => [
'a' => 0.000000000000000222,
'b' => 0.000000000000000232,
'epsilon' => PHP_FLOAT_EPSILON,
'equal' => true,
],
'not equal' => [
'a' => 0.000000000000000222,
'b' => 0.000000000000004222,
'epsilon' => PHP_FLOAT_EPSILON,
'equal' => false,
],
'equal, different epsilon' => [
'a' => 0.000000000000000222,
'b' => 0.000000000000004222,
'epsilon' => 0.0001,
'equal' => true,
],
'not equal, different epsilon' => [
'a' => 0.0001,
'b' => 0.0002,
'epsilon' => 0.0001,
'equal' => false,
]
];
}
/**
* Undocumented function
*
* @covers ::equalWithEpsilon
* @dataProvider providerEqualWithEpsilon
* @testdox equalWithEpsilon with $a and $b and Epsilon: $epsilon must be equal: $equal [$_dataName]
*
* @return void
*/
public function testEqualWithEpsilon(float $a, float $b, float $epsilon, bool $equal): void
{
$this->assertEquals(
$equal,
\CoreLibs\Convert\Math::equalWithEpsilon($a, $b, $epsilon)
);
}
/**
* Undocumented function
*
* @return array
*/
public function providerCompareWithEpsilon(): array
{
return [
'smaller, true' => [
'value' => 0.0001,
'compare' => '<',
'limit' => 0.0002,
'epsilon' => 0.00001,
'match' => true,
],
'smaller, false' => [
'value' => 0.0001,
'compare' => '<',
'limit' => 0.0001,
'epsilon' => 0.00001,
'match' => false,
],
'bigger, true' => [
'value' => 0.0002,
'compare' => '>',
'limit' => 0.0001,
'epsilon' => 0.00001,
'match' => true,
],
'bigger, false' => [
'value' => 0.0001,
'compare' => '>',
'limit' => 0.0001,
'epsilon' => 0.00001,
'match' => false,
],
];
}
/**
* Undocumented function
*
* @covers ::compareWithEpsilon
* @dataProvider providerCompareWithEpsilon
* @testdox compareWithEpsilon $value $compare $limit with $epsilon must match: $match [$_dataName]
*
* @param float $value
* @param string $compare
* @param float $limit
* @param float $epslion
* @param bool $match
* @return void
*/
public function testCompareWithEpsilon(
float $value,
string $compare,
float $limit,
float $epsilon,
bool $match
): void {
$this->assertEquals(
$match,
\CoreLibs\Convert\Math::compareWithEpsilon($value, $compare, $limit, $epsilon)
);
}
} }
// __END__ // __END__

View File

@@ -1,283 +0,0 @@
<?php
// This code was created by Claude Sonnet 4
// FIX:
// '/test{/', // Unmatched brace -> this is valid
// '/test{1,}/', // Invalid quantifier -> this is valid
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
use CoreLibs\Convert\Strings;
/**
* Test class for CoreLibs\Convert\Strings regex validation methods
*/
class CoreLibsConvertStringsRegexValidateTest extends TestCase
{
/**
* Test isValidRegex with valid regex patterns
*/
public function testIsValidRegexWithValidPatterns(): void
{
$validPatterns = [
'/^[a-zA-Z0-9]+$/',
'/test/',
'/\d+/',
'/^hello.*world$/',
'/[0-9]{3}-[0-9]{3}-[0-9]{4}/',
'#^https?://.*#i',
'~^[a-z]+~',
'|test|',
'/^$/m',
'/\w+/u',
];
foreach ($validPatterns as $pattern) {
$this->assertTrue(
Strings::isValidRegex($pattern),
"Pattern '{$pattern}' should be valid"
);
}
}
/**
* Test isValidRegex with invalid regex patterns
*/
public function testIsValidRegexWithInvalidPatterns(): void
{
$invalidPatterns = [
'/[/', // Unmatched bracket
'/test[/', // Unmatched bracket
'/(?P<name>/', // Unmatched parenthesis
'/(?P<>test)/', // Invalid named group
'/test\\/', // Invalid escape at end
'/(test/', // Unmatched parenthesis
'/test)/', // Unmatched parenthesis
// '/test{/', // Unmatched brace -> this is valid
// '/test{1,}/', // Invalid quantifier -> this is valid
'/[z-a]/', // Invalid character range
'invalid', // No delimiters
'', // Empty string
'/(?P<123>test)/', // Invalid named group name
];
foreach ($invalidPatterns as $pattern) {
$this->assertFalse(
Strings::isValidRegex($pattern),
"Pattern '{$pattern}' should be invalid"
);
}
}
/**
* Test getLastRegexErrorString returns correct error messages
*/
public function testGetLastRegexErrorStringReturnsCorrectMessages(): void
{
// Test with a valid regex first to ensure clean state
Strings::isValidRegex('/valid/');
$this->assertEquals('No error', Strings::getLastRegexErrorString());
// Test with invalid regex to trigger an error
Strings::isValidRegex('/[/');
$errorMessage = Strings::getLastRegexErrorString();
// The error message should be one of the defined messages
$this->assertContains($errorMessage, array_values(Strings::PREG_ERROR_MESSAGES));
$this->assertNotEquals('Unknown error', $errorMessage);
}
/**
* Test getLastRegexErrorString with unknown error
*/
public function testGetLastRegexErrorStringWithUnknownError(): void
{
// This is harder to test directly since we can't easily mock preg_last_error()
// but we can test the fallback behavior by reflection or assume it works
// At minimum, ensure it returns a string
$result = Strings::getLastRegexErrorString();
$this->assertIsString($result);
$this->assertNotEmpty($result);
}
/**
* Test validateRegex with valid patterns
*/
public function testValidateRegexWithValidPatterns(): void
{
$validPatterns = [
'/^test$/',
'/\d+/',
'/[a-z]+/i',
];
foreach ($validPatterns as $pattern) {
$result = Strings::validateRegex($pattern);
$this->assertIsArray($result);
$this->assertArrayHasKey('valid', $result);
$this->assertArrayHasKey('preg_error', $result);
$this->assertArrayHasKey('error', $result);
$this->assertTrue($result['valid'], "Pattern '{$pattern}' should be valid");
$this->assertEquals(PREG_NO_ERROR, $result['preg_error']);
$this->assertNull($result['error']);
}
}
/**
* Test validateRegex with invalid patterns
*/
public function testValidateRegexWithInvalidPatterns(): void
{
$invalidPatterns = [
'/[/', // Unmatched bracket
'/(?P<name>/', // Unmatched parenthesis
'/test\\/', // Invalid escape at end
'/(test/', // Unmatched parenthesis
];
foreach ($invalidPatterns as $pattern) {
$result = Strings::validateRegex($pattern);
$this->assertIsArray($result);
$this->assertArrayHasKey('valid', $result);
$this->assertArrayHasKey('preg_error', $result);
$this->assertArrayHasKey('error', $result);
$this->assertArrayHasKey('pcre_error', $result);
$this->assertFalse($result['valid'], "Pattern '{$pattern}' should be invalid");
$this->assertNotEquals(PREG_NO_ERROR, $result['preg_error']);
$this->assertIsString($result['error']);
$this->assertNotNull($result['error']);
$this->assertNotEmpty($result['error']);
// Verify error message is from our defined messages or 'Unknown error'
$this->assertTrue(
in_array($result['error'], array_values(Strings::PREG_ERROR_MESSAGES)) ||
$result['error'] === 'Unknown error'
);
}
}
/**
* Test validateRegex array structure
*/
public function testValidateRegexArrayStructure(): void
{
$result = Strings::validateRegex('/test/');
// Test array structure for valid regex
$this->assertIsArray($result);
$this->assertCount(4, $result);
$this->assertArrayHasKey('valid', $result);
$this->assertArrayHasKey('preg_error', $result);
$this->assertArrayHasKey('error', $result);
$result = Strings::validateRegex('/[/');
// Test array structure for invalid regex
$this->assertIsArray($result);
$this->assertCount(4, $result);
$this->assertArrayHasKey('valid', $result);
$this->assertArrayHasKey('preg_error', $result);
$this->assertArrayHasKey('error', $result);
$this->assertArrayHasKey('pcre_error', $result);
}
/**
* Test that methods handle edge cases properly
*/
public function testEdgeCases(): void
{
// Empty string
$this->assertFalse(Strings::isValidRegex(''));
$result = Strings::validateRegex('');
$this->assertFalse($result['valid']);
// Very long pattern
$longPattern = '/' . str_repeat('a', 1000) . '/';
$this->assertTrue(Strings::isValidRegex($longPattern));
// Unicode patterns
$this->assertTrue(Strings::isValidRegex('/\p{L}+/u'));
$this->assertTrue(Strings::isValidRegex('/[α-ω]+/u'));
}
/**
* Test PREG_ERROR_MESSAGES constant accessibility
*/
public function testPregErrorMessagesConstant(): void
{
$this->assertIsArray(Strings::PREG_ERROR_MESSAGES);
$this->assertNotEmpty(Strings::PREG_ERROR_MESSAGES);
// Check that all expected PREG constants are defined
$expectedKeys = [
PREG_NO_ERROR,
PREG_INTERNAL_ERROR,
PREG_BACKTRACK_LIMIT_ERROR,
PREG_RECURSION_LIMIT_ERROR,
PREG_BAD_UTF8_ERROR,
PREG_BAD_UTF8_OFFSET_ERROR,
PREG_JIT_STACKLIMIT_ERROR,
];
foreach ($expectedKeys as $key) {
$this->assertArrayHasKey($key, Strings::PREG_ERROR_MESSAGES);
$this->assertIsString(Strings::PREG_ERROR_MESSAGES[$key]);
$this->assertNotEmpty(Strings::PREG_ERROR_MESSAGES[$key]);
}
}
/**
* Test error state isolation between method calls
*/
public function testErrorStateIsolation(): void
{
// Start with invalid regex
Strings::isValidRegex('/[/');
$firstError = Strings::getLastRegexErrorString();
$this->assertNotEquals('No error', $firstError);
// Use valid regex
Strings::isValidRegex('/valid/');
$secondError = Strings::getLastRegexErrorString();
$this->assertEquals('No error', $secondError);
// Verify validateRegex clears previous errors
$result = Strings::validateRegex('/valid/');
$this->assertTrue($result['valid']);
$this->assertEquals(PREG_NO_ERROR, $result['preg_error']);
}
/**
* Test various regex delimiters
*/
public function testDifferentDelimiters(): void
{
$patterns = [
'/test/', // forward slash
'#test#', // hash
'~test~', // tilde
'|test|', // pipe
'@test@', // at symbol
'!test!', // exclamation
'%test%', // percent
];
foreach ($patterns as $pattern) {
$this->assertTrue(
Strings::isValidRegex($pattern),
"Pattern with delimiter '{$pattern}' should be valid"
);
}
}
}
// __END__

View File

@@ -24,83 +24,117 @@ final class CoreLibsConvertStringsTest extends TestCase
{ {
// 0: input // 0: input
// 1: format // 1: format
// 2: split characters as string, null for default
// 3: expected // 3: expected
return [ return [
'all empty string' => [ 'all empty string' => [
'', '',
'', '',
null,
'' ''
], ],
'empty input string' => [ 'empty input string' => [
'', '',
'2-2', '2-2',
null,
'' ''
], ],
'empty format string string' => [ 'empty format string string' => [
'1234', '1234',
'', '',
null,
'1234' '1234'
], ],
'string format match' => [ 'string format match' => [
'1234', '1234',
'2-2', '2-2',
null,
'12-34' '12-34'
], ],
'string format trailing match' => [ 'string format trailing match' => [
'1234', '1234',
'2-2-', '2-2-',
null,
'12-34' '12-34'
], ],
'string format leading match' => [ 'string format leading match' => [
'1234', '1234',
'-2-2', '-2-2',
null,
'12-34' '12-34'
], ],
'string format double inside match' => [ 'string format double inside match' => [
'1234', '1234',
'2--2', '2--2',
null,
'12--34', '12--34',
], ],
'string format short first' => [ 'string format short first' => [
'1', '1',
'2-2', '2-2',
null,
'1' '1'
], ],
'string format match first' => [ 'string format match first' => [
'12', '12',
'2-2', '2-2',
null,
'12' '12'
], ],
'string format short second' => [ 'string format short second' => [
'123', '123',
'2-2', '2-2',
null,
'12-3' '12-3'
], ],
'string format too long' => [ 'string format too long' => [
'1234567', '1234567',
'2-2', '2-2',
null,
'12-34-567' '12-34-567'
], ],
'string format invalid format string' => [
'1234',
'2_2',
null,
'1234'
],
'different split character' => [ 'different split character' => [
'1234', '1234',
'2_2', '2_2',
'_',
'12_34' '12_34'
], ],
'mixed split characters' => [ 'mixed split characters' => [
'123456', '123456',
'2-2_2', '2-2_2',
'-_',
'12-34_56' '12-34_56'
], ],
'length mixed' => [ 'length mixed' => [
'ABCD12345568ABC13', 'ABCD12345568ABC13',
'2-4_5-2#4', '2-4_5-2#4',
'-_#',
'AB-CD12_34556-8A#BC13' 'AB-CD12_34556-8A#BC13'
], ],
'split with split chars in string' => [ 'split with split chars in string' => [
'12-34', '12-34',
'2-2', '2-2',
null,
'12--3-4' '12--3-4'
], ],
'mutltibyte string' => [
'あいうえ',
'2-2',
null,
'あいうえ'
],
'mutltibyte split string' => [
'1234',
'-',
null,
'1234'
],
]; ];
} }
@@ -109,137 +143,29 @@ final class CoreLibsConvertStringsTest extends TestCase
* *
* @covers ::splitFormatString * @covers ::splitFormatString
* @dataProvider splitFormatStringProvider * @dataProvider splitFormatStringProvider
* @testdox splitFormatString $input with format $format will be $expected [$_dataName] * @testdox splitFormatString $input with format $format and splitters $split_characters will be $expected [$_dataName]
* *
* @param string $input * @param string $input
* @param string $format * @param string $format
* @param string|null $split_characters
* @param string $expected * @param string $expected
* @return void * @return void
*/ */
public function testSplitFormatString( public function testSplitFormatString(
string $input, string $input,
string $format, string $format,
string $expected
): void {
$output = \CoreLibs\Convert\Strings::splitFormatString(
$input,
$format,
);
$this->assertEquals(
$expected,
$output
);
}
/** check exceptions */
public function splitFormatStringExceptionProvider(): array
{
return [
'string format with no splitter match' => [
'1234',
'22',
'12-34'
],
'invalid format string' => [
'1234',
'2あ2',
],
'mutltibyte string' => [
'あいうえ',
'2-2',
],
'mutltibyte split string' => [
'1234',
'-',
],
];
}
/**
* Undocumented function
*
* @covers ::splitFormatStringFixed
* @dataProvider splitFormatStringExceptionProvider
* @testdox splitFormatString Exception catch checks for $input with $format[$_dataName]
*
* @return void
*/
public function testSplitFormatStringExceptions(string $input, string $format): void
{
// catch exception
$this->expectException(\InvalidArgumentException::class);
\CoreLibs\Convert\Strings::splitFormatString($input, $format);
}
/**
* test for split Format string fixed length
*
* @return array
*/
public function splitFormatStringFixedProvider(): array
{
return [
'normal split, default split char' => [
'abcdefg',
4,
null,
'abcd-efg'
],
'noraml split, other single split char' => [
'abcdefg',
4,
"=",
'abcd=efg'
],
'noraml split, other multiple split char' => [
'abcdefg',
4,
"-=-",
'abcd-=-efg'
],
'non ascii characters' => [
'あいうえお',
2,
"-",
'あい-うえ-お'
],
'empty string' => [
'',
4,
"-",
''
]
];
}
/**
* Undocumented function
*
* @covers ::splitFormatStringFixed
* @dataProvider splitFormatStringFixedProvider
* @testdox splitFormatStringFixed $input with length $split_length and split chars $split_characters will be $expected [$_dataName]
*
* @param string $input
* @param int $split_length
* @param string|null $split_characters
* @param string $expected
* @return void
*/
public function testSplitFormatStringFixed(
string $input,
int $split_length,
?string $split_characters, ?string $split_characters,
string $expected string $expected
): void { ): void {
if ($split_characters === null) { if ($split_characters === null) {
$output = \CoreLibs\Convert\Strings::splitFormatStringFixed( $output = \CoreLibs\Convert\Strings::splitFormatString(
$input, $input,
$split_length $format
); );
} else { } else {
$output = \CoreLibs\Convert\Strings::splitFormatStringFixed( $output = \CoreLibs\Convert\Strings::splitFormatString(
$input, $input,
$split_length, $format,
$split_characters $split_characters
); );
} }
@@ -249,36 +175,6 @@ final class CoreLibsConvertStringsTest extends TestCase
); );
} }
public function splitFormatStringFixedExceptionProvider(): array
{
return [
'split length too short' => [
'abcdefg',
-1,
],
'split length longer than string' => [
'abcdefg',
20,
],
];
}
/**
* Undocumented function
*
* @covers ::splitFormatStringFixed
* @dataProvider splitFormatStringFixedExceptionProvider
* @testdox splitFormatStringFixed Exception catch checks for $input with $length [$_dataName]
*
* @return void
*/
public function testSplitFormatStringFixedExceptions(string $input, int $length): void
{
// catch exception
$this->expectException(\InvalidArgumentException::class);
\CoreLibs\Convert\Strings::splitFormatStringFixed($input, $length);
}
/** /**
* Undocumented function * Undocumented function
* *
@@ -482,305 +378,6 @@ final class CoreLibsConvertStringsTest extends TestCase
\CoreLibs\Convert\Strings::stripUTF8BomBytes($file) \CoreLibs\Convert\Strings::stripUTF8BomBytes($file)
); );
} }
/**
* Undocumented function
*
* @return array
*/
public function allCharsInSetProvider(): array
{
return [
'find' => [
'abc',
'abcdef',
true
],
'not found' => [
'abcz',
'abcdef',
false
]
];
}
/**
* Undocumented function
*
* @covers ::allCharsInSet
* @dataProvider allCharsInSetProvider
* @testdox allCharsInSet $input in $haystack with expected $expected [$_dataName]
*
* @param string $needle
* @param string $haystack
* @param bool $expected
* @return void
*/
public function testAllCharsInSet(string $needle, string $haystack, bool $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Convert\Strings::allCharsInSet($needle, $haystack)
);
}
public function buildCharStringFromListsProvider(): array
{
return [
'test a' => [
'abc',
['a', 'b', 'c'],
],
'test b' => [
'abc123',
['a', 'b', 'c'],
['1', '2', '3'],
],
'test c: no params' => [
'',
],
'test c: empty 1' => [
'',
[]
],
'test nested' => [
'abc',
[['a'], ['b'], ['c']],
],
];
}
/**
* Undocumented function
*
* @covers ::buildCharStringFromLists
* @dataProvider buildCharStringFromListsProvider
* @testdox buildCharStringFromLists all $input convert to $expected [$_dataName]
*
* @param string $expected
* @param array ...$input
* @return void
*/
public function testBuildCharStringFromLists(string $expected, array ...$input): void
{
$this->assertEquals(
$expected,
\CoreLibs\Convert\Strings::buildCharStringFromLists(...$input)
);
}
/**
* Undocumented function
*
* @return array
*/
public function removeDuplicatesProvider(): array
{
return [
'test no change' => [
'ABCDEFG',
'ABCDEFG',
],
'test simple' => [
'aa',
'a'
],
'test keep lower and uppwer case' => [
'AaBbCc',
'AaBbCc'
],
'test unqiue' => [
'aabbcc',
'abc'
],
'test multibyte no change' => [
'あいうえお',
'あいうえお',
],
'test multibyte' => [
'ああいいううええおお',
'あいうえお',
],
'test multibyte special' => [
'あぁいぃうぅえぇおぉ',
'あぁいぃうぅえぇおぉ',
]
];
}
/**
* Undocumented function
*
* @covers ::removeDuplicates
* @dataProvider removeDuplicatesProvider
* @testdox removeDuplicates make $input unqiue to $expected [$_dataName]
*
* @param string $input
* @param string $expected
* @return void
*/
public function testRemoveDuplicates(string $input, string $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Convert\Strings::removeDuplicates($input)
);
}
/**
* Undocumented function
*
* @return array
*/
public function isValidRegexSimpleProvider(): array
{
return [
'valid regex' => [
'/^[A-z]$/',
true,
[
'valid' => true,
'preg_error' => 0,
'error' => null,
'pcre_error' => null
],
],
'invalid regex A' => [
'/^[A-z]$',
false,
[
'valid' => false,
'preg_error' => 1,
'error' => 'Internal PCRE error',
'pcre_error' => 'Internal error'
],
],
'invalid regex B' => [
'/^[A-z$',
false,
[
'valid' => false,
'preg_error' => 1,
'error' => 'Internal PCRE error',
'pcre_error' => 'Internal error'
],
],
];
}
/**
* Undocumented function
*
* @covers ::isValidRegexSimple
* @dataProvider isValidRegexSimpleProvider
* @testdox isValidRegexSimple make $input unqiue to $expected [$_dataName]
*
* @param string $input
* @param bool $expected
* @return void
*/
public function testIsValidRegexSimple(string $input, bool $expected, array $expected_extended): void
{
$this->assertEquals(
$expected,
\CoreLibs\Convert\Strings::isValidRegex($input),
'Regex is not valid'
);
$this->assertEquals(
$expected_extended,
\CoreLibs\Convert\Strings::validateRegex($input),
'Validation of regex failed'
);
$this->assertEquals(
// for true null is set, so we get here No Error
$expected_extended['error'] ?? \CoreLibs\Convert\Strings::PREG_ERROR_MESSAGES[0],
\CoreLibs\Convert\Strings::getLastRegexErrorString(),
'Cannot match last preg error string'
);
}
/**
* Undocumented function
*
* @return array
*/
public function parseCharacterRangesProvider(): array
{
return [
'simple a-z' => [
['a-z'],
implode('', range('a', 'z')),
null,
],
'simple A-Z' => [
['A-Z'],
implode('', range('A', 'Z')),
null,
],
'simple 0-9' => [
['0-9'],
implode('', range('0', '9')),
null,
],
'mixed ranges' => [
['a-c', 'X-Z', '3-5'],
'abcXYZ345',
null,
],
'reverse ranges' => [
['z-a'],
'abcdefghijklmnopqrstuvwxyz',
null,
],
'overlapping ranges' => [
['a-f', 'd-j'],
'abcdefghij',
null,
],
'mixed valid and overlap ranges' => [
['a-f', 'z-a', '0-3'],
'abcdefghijklmnopqrstuvwxyz0123',
null,
],
'range without dashes' => [
['abcddfff'],
'abcdf',
null,
],
'invalid ranges' => [
['a-あ', 'A-あ', '0-あ'],
'',
\InvalidArgumentException::class,
],
];
}
/**
* Undocumented function
*
* @covers ::parseCharacterRanges
* @dataProvider parseCharacterRangesProvider
* @testdox parseCharacterRanges $input to $expected [$_dataName]
*
* @param array $input
* @param string $expected
* @param string|null $expected_exception
* @return void
*/
public function testParseCharacterRanges(
array $input,
string $expected,
?string $expected_exception
): void {
if ($expected_exception !== null) {
$this->expectException($expected_exception);
}
$this->assertEquals(
$expected,
implode('', \CoreLibs\Convert\Strings::parseCharacterRanges(implode('', $input)))
);
}
} }
// __END__ // __END__

View File

@@ -21,10 +21,8 @@ final class CoreLibsCreateHashTest extends TestCase
public function hashData(): array public function hashData(): array
{ {
return [ return [
'hash tests' => [ 'any string' => [
// this is the string
'text' => 'Some String Text', 'text' => 'Some String Text',
// hash list special
'crc32b_reverse' => 'c5c21d91', // crc32b (in revere) 'crc32b_reverse' => 'c5c21d91', // crc32b (in revere)
'sha1Short' => '4d2bc9ba0', // sha1Short 'sha1Short' => '4d2bc9ba0', // sha1Short
// via hash // via hash
@@ -33,8 +31,6 @@ final class CoreLibsCreateHashTest extends TestCase
'fnv132' => '9df444f9', // hash: fnv132 'fnv132' => '9df444f9', // hash: fnv132
'fnv1a32' => '2c5f91b9', // hash: fnv1a32 'fnv1a32' => '2c5f91b9', // hash: fnv1a32
'joaat' => '50dab846', // hash: joaat 'joaat' => '50dab846', // hash: joaat
'ripemd160' => 'aeae3f041b20136451519edd9361570909300342', // hash: ripemd160,
'sha256' => '9055080e022f224fa835929b80582b3c71c672206fa3a49a87412c25d9d42ceb', // hash: sha256
] ]
]; ];
} }
@@ -85,7 +81,7 @@ final class CoreLibsCreateHashTest extends TestCase
{ {
$list = []; $list = [];
foreach ($this->hashData() as $name => $values) { foreach ($this->hashData() as $name => $values) {
foreach ([null, 'crc32b', 'adler32', 'fnv132', 'fnv1a32', 'joaat', 'ripemd160', 'sha256'] as $_hash_type) { foreach ([null, 'crc32b', 'adler32', 'fnv132', 'fnv1a32', 'joaat'] as $_hash_type) {
// default value test // default value test
if ($_hash_type === null) { if ($_hash_type === null) {
$hash_type = \CoreLibs\Create\Hash::STANDARD_HASH_SHORT; $hash_type = \CoreLibs\Create\Hash::STANDARD_HASH_SHORT;
@@ -118,22 +114,6 @@ final class CoreLibsCreateHashTest extends TestCase
]; ];
} }
/**
* Undocumented function
*
* @return array
*/
public function hashStandardProvider(): array
{
$hash_source = 'Some String Text';
return [
'Long Hash check: ' . \CoreLibs\Create\Hash::STANDARD_HASH => [
$hash_source,
hash(\CoreLibs\Create\Hash::STANDARD_HASH, $hash_source)
],
];
}
/** /**
* Undocumented function * Undocumented function
* *
@@ -156,13 +136,9 @@ final class CoreLibsCreateHashTest extends TestCase
/** /**
* Undocumented function * Undocumented function
* *
* phpcs:disable Generic.Files.LineLength
* @covers ::__sha1Short * @covers ::__sha1Short
* @covers ::__crc32b
* @covers ::sha1Short
* @dataProvider sha1ShortProvider * @dataProvider sha1ShortProvider
* @testdox __sha1Short/__crc32b/sha1short $input will be $expected (crc32b) and $expected_sha1 (sha1 short) [$_dataName] * @testdox __sha1Short $input will be $expected (crc32b) and $expected_sha1 (sha1 short) [$_dataName]
* phpcs:enable Generic.Files.LineLength
* *
* @param string $input * @param string $input
* @param string $expected * @param string $expected
@@ -173,29 +149,16 @@ final class CoreLibsCreateHashTest extends TestCase
// uses crc32b // uses crc32b
$this->assertEquals( $this->assertEquals(
$expected, $expected,
\CoreLibs\Create\Hash::__sha1Short($input), \CoreLibs\Create\Hash::__sha1Short($input)
'__sha1Short depreacted'
); );
$this->assertEquals( $this->assertEquals(
$expected, $expected,
\CoreLibs\Create\Hash::__sha1Short($input, false), \CoreLibs\Create\Hash::__sha1Short($input, false)
'__sha1Short (false) depreacted'
);
$this->assertEquals(
$expected,
\CoreLibs\Create\Hash::__crc32b($input),
'__crc32b'
); );
// sha1 type // sha1 type
$this->assertEquals( $this->assertEquals(
$expected_sha1, $expected_sha1,
\CoreLibs\Create\Hash::__sha1Short($input, true), \CoreLibs\Create\Hash::__sha1Short($input, true)
'__sha1Short (true) depreacted'
);
$this->assertEquals(
$expected_sha1,
\CoreLibs\Create\Hash::sha1Short($input),
'sha1Short'
); );
} }
@@ -203,10 +166,8 @@ final class CoreLibsCreateHashTest extends TestCase
* Undocumented function * Undocumented function
* *
* @covers ::__hash * @covers ::__hash
* @covers ::hashShort
* @covers ::hashShort
* @dataProvider hashProvider * @dataProvider hashProvider
* @testdox __hash/hashShort/hash $input with $hash_type will be $expected [$_dataName] * @testdox __hash $input with $hash_type will be $expected [$_dataName]
* *
* @param string $input * @param string $input
* @param string|null $hash_type * @param string|null $hash_type
@@ -218,24 +179,12 @@ final class CoreLibsCreateHashTest extends TestCase
if ($hash_type === null) { if ($hash_type === null) {
$this->assertEquals( $this->assertEquals(
$expected, $expected,
\CoreLibs\Create\Hash::__hash($input), \CoreLibs\Create\Hash::__hash($input)
'__hash'
);
$this->assertEquals(
$expected,
\CoreLibs\Create\Hash::hashShort($input),
'hashShort'
); );
} else { } else {
$this->assertEquals( $this->assertEquals(
$expected, $expected,
\CoreLibs\Create\Hash::__hash($input, $hash_type), \CoreLibs\Create\Hash::__hash($input, $hash_type)
'__hash with hash type'
);
$this->assertEquals(
$expected,
\CoreLibs\Create\Hash::hash($input, $hash_type),
'hash with hash type'
); );
} }
} }
@@ -244,9 +193,8 @@ final class CoreLibsCreateHashTest extends TestCase
* Undocumented function * Undocumented function
* *
* @covers ::__hashLong * @covers ::__hashLong
* @covers ::hashLong
* @dataProvider hashLongProvider * @dataProvider hashLongProvider
* @testdox __hashLong/hashLong $input will be $expected [$_dataName] * @testdox __hashLong $input will be $expected [$_dataName]
* *
* @param string $input * @param string $input
* @param string $expected * @param string $expected
@@ -258,168 +206,6 @@ final class CoreLibsCreateHashTest extends TestCase
$expected, $expected,
\CoreLibs\Create\Hash::__hashLong($input) \CoreLibs\Create\Hash::__hashLong($input)
); );
$this->assertEquals(
$expected,
\CoreLibs\Create\Hash::hashLong($input)
);
}
/**
* Undocumented function
*
* @covers ::hash
* @covers ::hashStd
* @dataProvider hashStandardProvider
* @testdox hash/hashStd $input will be $expected [$_dataName]
*
* @param string $input
* @param string $expected
* @return void
*/
public function testHashStandard(string $input, string $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Create\Hash::hashStd($input)
);
$this->assertEquals(
$expected,
\CoreLibs\Create\Hash::hash($input)
);
}
/**
* Undocumented function
*
* @covers ::hash
* @testdox hash with invalid type
*
* @return void
*/
public function testInvalidHashType(): void
{
$hash_source = 'Some String Text';
$expected = hash(\CoreLibs\Create\Hash::STANDARD_HASH, $hash_source);
$this->assertEquals(
$expected,
\CoreLibs\Create\Hash::hash($hash_source, 'DOES_NOT_EXIST')
);
}
/**
* Note: this only tests default sha256
*
* @covers ::hashHmac
* @testdox hash hmac test
*
* @return void
*/
public function testHashMac(): void
{
$hash_key = 'FIX KEY';
$hash_source = 'Some String Text';
$expected = '16479b3ef6fa44e1cdd8b2dcfaadf314d1a7763635e8738f1e7996d714d9b6bf';
$this->assertEquals(
$expected,
\CoreLibs\Create\Hash::hashHmac($hash_source, $hash_key)
);
}
/**
* Undocumented function
*
* @covers ::hashHmac
* @testdox hash hmac with invalid type
*
* @return void
*/
public function testInvalidHashMacType(): void
{
$hash_key = 'FIX KEY';
$hash_source = 'Some String Text';
$expected = hash_hmac(\CoreLibs\Create\Hash::STANDARD_HASH, $hash_source, $hash_key);
$this->assertEquals(
$expected,
\CoreLibs\Create\Hash::hashHmac($hash_source, $hash_key, 'DOES_NOT_EXIST')
);
}
/**
* Undocumented function
*
* @return array<mixed>
*/
public function providerHashTypes(): array
{
return [
'Hash crc32b' => [
'crc32b',
true,
false,
],
'Hash adler32' => [
'adler32',
true,
false,
],
'HAsh fnv132' => [
'fnv132',
true,
false,
],
'Hash fnv1a32' => [
'fnv1a32',
true,
false,
],
'Hash: joaat' => [
'joaat',
true,
false,
],
'Hash: ripemd160' => [
'ripemd160',
true,
true,
],
'Hash: sha256' => [
'sha256',
true,
true,
],
'Hash: invalid' => [
'invalid',
false,
false
]
];
}
/**
* Undocumented function
*
* @covers ::isValidHashType
* @covers ::isValidHashHmacType
* @dataProvider providerHashTypes
* @testdox check if $hash_type is valid for hash $hash_ok and hash hmac $hash_hmac_ok [$_dataName]
*
* @param string $hash_type
* @param bool $hash_ok
* @param bool $hash_hmac_ok
* @return void
*/
public function testIsValidHashAndHashHmacTypes(string $hash_type, bool $hash_ok, bool $hash_hmac_ok): void
{
$this->assertEquals(
$hash_ok,
\CoreLibs\Create\Hash::isValidHashType($hash_type),
'hash valid'
);
$this->assertEquals(
$hash_hmac_ok,
\CoreLibs\Create\Hash::isValidHashHmacType($hash_type),
'hash hmac valid'
);
} }
} }

View File

@@ -18,70 +18,138 @@ final class CoreLibsCreateRandomKeyTest extends TestCase
* *
* @return array * @return array
*/ */
public function randomKeyGenProvider(): array public function keyLenghtProvider(): array
{ {
return [ return [
// just key length 'valid key length' => [
'default key length, default char set' => [
0 => null,
1 => \CoreLibs\Create\RandomKey::KEY_LENGTH_DEFAULT
],
'set -1 key length, default char set' => [
0 => -1,
1 => \CoreLibs\Create\RandomKey::KEY_LENGTH_DEFAULT,
],
'set 0 key length, default char set' => [
0 => -1,
1 => \CoreLibs\Create\RandomKey::KEY_LENGTH_DEFAULT,
],
'set too large key length, default char set' => [
0 => 300,
1 => \CoreLibs\Create\RandomKey::KEY_LENGTH_DEFAULT,
],
'set override key lenght, default char set' => [
0 => 6, 0 => 6,
1 => 6, 1 => true,
2 => 6,
], ],
// just character set 'negative key length' => [
'default key length, different char set A' => [ 0 => -1,
0 => \CoreLibs\Create\RandomKey::KEY_LENGTH_DEFAULT, 1 => false,
1 => \CoreLibs\Create\RandomKey::KEY_LENGTH_DEFAULT, 2 => 4,
2 => [
'A', 'B', 'C'
],
], ],
'different key length, different char set B' => [ 'tpp big key length' => [
0 => 16, 0 => 300,
1 => 16, 1 => false,
2 => [ 2 => 4,
'A', 'B', 'C'
],
3 => [
'1', '2', '3'
]
], ],
]; ];
} }
// Alternative more efficient version using strpos
/** /**
* check if all characters are in set * Undocumented function
* *
* @param string $input * @return array
* @param string $allowed_chars
* @return bool
*/ */
private function allCharsInSet(string $input, string $allowed_chars): bool public function randomKeyGenProvider(): array
{ {
$inputLength = strlen($input); 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,
],
];
}
for ($i = 0; $i < $inputLength; $i++) { /**
if (strpos($allowed_chars, $input[$i]) === false) { * 1
return false; *
} * @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(
return true; $input,
\CoreLibs\Create\RandomKey::getRandomKeyLength()
);
} }
/** /**
@@ -95,41 +163,43 @@ final class CoreLibsCreateRandomKeyTest extends TestCase
* @param integer $expected * @param integer $expected
* @return void * @return void
*/ */
public function testRandomKeyGen(?int $input, int $expected, array ...$key_range): void public function testRandomKeyGen(?int $input, int $expected): void
{ {
$__key_data = \CoreLibs\Create\RandomKey::KEY_CHARACTER_RANGE_DEFAULT;
if (count($key_range)) {
$__key_data = join('', array_unique(array_merge(...$key_range)));
}
if ($input === null) { if ($input === null) {
$this->assertEquals( $this->assertEquals(
$expected, $expected,
strlen(\CoreLibs\Create\RandomKey::randomKeyGen()) strlen(\CoreLibs\Create\RandomKey::randomKeyGen())
); );
} elseif ($input !== null && !count($key_range)) { } else {
$random_key = \CoreLibs\Create\RandomKey::randomKeyGen($input);
$this->assertTrue(
$this->allCharsInSet($random_key, $__key_data),
'Characters not valid'
);
$this->assertEquals( $this->assertEquals(
$expected, $expected,
strlen($random_key), strlen(\CoreLibs\Create\RandomKey::randomKeyGen($input))
'String length not matching'
);
} elseif (count($key_range)) {
$random_key = \CoreLibs\Create\RandomKey::randomKeyGen($input, ...$key_range);
$this->assertTrue(
$this->allCharsInSet($random_key, $__key_data),
'Characters not valid'
);
$this->assertEquals(
$expected,
strlen($random_key),
'String length not matching'
); );
} }
} }
/**
* 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__ // __END__

View File

@@ -22,6 +22,7 @@ final class CoreLibsCreateSessionTest extends TestCase
public function sessionProvider(): array public function sessionProvider(): array
{ {
// 0: session name as parameter or for GLOBAL value // 0: session name as parameter or for GLOBAL value
// 1: type p: parameter, g: global, d: php.ini default
// 2: mock data as array // 2: mock data as array
// checkCliStatus: true/false, // checkCliStatus: true/false,
// getSessionStatus: PHP_SESSION_DISABLED for abort, // getSessionStatus: PHP_SESSION_DISABLED for abort,
@@ -30,10 +31,13 @@ final class CoreLibsCreateSessionTest extends TestCase
// checkActiveSession: true/false, [1st call, 2nd call] // checkActiveSession: true/false, [1st call, 2nd call]
// getSessionId: string or false // getSessionId: string or false
// 3: exepcted name (session)] // 3: exepcted name (session)]
// 4: auto write close flag // 4: Exception thrown on error
// 5: exception code, null for none
// 6: expected error string
return [ return [
'session parameter' => [ 'session parameter' => [
'sessionNameParameter', 'sessionNameParameter',
'p',
[ [
'checkCliStatus' => false, 'checkCliStatus' => false,
'getSessionStatus' => PHP_SESSION_NONE, 'getSessionStatus' => PHP_SESSION_NONE,
@@ -43,9 +47,12 @@ final class CoreLibsCreateSessionTest extends TestCase
], ],
'sessionNameParameter', 'sessionNameParameter',
null, null,
null,
'',
], ],
'session globals' => [ 'session globals' => [
'sessionNameGlobals', 'sessionNameGlobals',
'g',
[ [
'checkCliStatus' => false, 'checkCliStatus' => false,
'getSessionStatus' => PHP_SESSION_NONE, 'getSessionStatus' => PHP_SESSION_NONE,
@@ -54,12 +61,13 @@ final class CoreLibsCreateSessionTest extends TestCase
'getSessionId' => '1234abcd4567' 'getSessionId' => '1234abcd4567'
], ],
'sessionNameGlobals', 'sessionNameGlobals',
[ null,
'auto_write_close' => false, null,
], '',
], ],
'auto write close' => [ 'session name default' => [
'sessionNameAutoWriteClose', '',
'd',
[ [
'checkCliStatus' => false, 'checkCliStatus' => false,
'getSessionStatus' => PHP_SESSION_NONE, 'getSessionStatus' => PHP_SESSION_NONE,
@@ -67,10 +75,109 @@ final class CoreLibsCreateSessionTest extends TestCase
'checkActiveSession' => [false, true], 'checkActiveSession' => [false, true],
'getSessionId' => '1234abcd4567' 'getSessionId' => '1234abcd4567'
], ],
'sessionNameAutoWriteClose', '',
null,
null,
'',
],
// error checks
// 1: we are in cli
'on cli error' => [
'',
'd',
[ [
'auto_write_close' => true, 'checkCliStatus' => true,
'getSessionStatus' => PHP_SESSION_NONE,
'setSessionName' => true,
'checkActiveSession' => [false, true],
'getSessionId' => '1234abcd4567'
], ],
'',
'RuntimeException',
1,
'[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'
],
'',
'RuntimeException',
2,
'[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'
],
'',
'UnexpectedValueException',
3,
'[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'
],
'',
'UnexpectedValueException',
3,
'[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'
],
'',
'RuntimeException',
4,
'[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
],
'',
'UnexpectedValueException',
5,
'[SESSION] getSessionId did not return a session id'
], ],
]; ];
} }
@@ -83,24 +190,32 @@ final class CoreLibsCreateSessionTest extends TestCase
* @testdox startSession $input name for $type will be $expected (error: $expected_error) [$_dataName] * @testdox startSession $input name for $type will be $expected (error: $expected_error) [$_dataName]
* *
* @param string $input * @param string $input
* @param string $type
* @param array<mixed> $mock_data * @param array<mixed> $mock_data
* @param string $expected * @param string $expected
* @param array<string,mixed> $options * @param string|null $exception
* @param string $expected_error
* @return void * @return void
*/ */
public function testStartSession( public function testStartSession(
string $input, string $input,
string $type,
array $mock_data, array $mock_data,
string $expected, string $expected,
?array $options, ?string $exception,
?int $exception_code,
string $expected_error
): void { ): void {
// override expected
if ($type == 'd') {
$expected = ini_get('session.name');
}
/** @var \CoreLibs\Create\Session&MockObject $session_mock */ /** @var \CoreLibs\Create\Session&MockObject $session_mock */
$session_mock = $this->createPartialMock( $session_mock = $this->createPartialMock(
\CoreLibs\Create\Session::class, \CoreLibs\Create\Session::class,
[ [
'checkCliStatus', 'checkCliStatus', 'getSessionStatus', 'checkActiveSession',
'getSessionStatus', 'checkActiveSession', 'setSessionName', 'startSessionCall', 'getSessionId',
'getSessionId',
'getSessionName' 'getSessionName'
] ]
); );
@@ -119,8 +234,12 @@ final class CoreLibsCreateSessionTest extends TestCase
$mock_data['checkActiveSession'][0], $mock_data['checkActiveSession'][0],
$mock_data['checkActiveSession'][1], $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 // set session name & return bsed on request data
$session_mock->method('getSessionName')->willReturn($expected); $session_mock->method('getSessionName')->willReturn($expected);
// will not return anything
$session_mock->method('startSessionCall');
// in test case only return string // in test case only return string
// false: will return false // false: will return false
$session_mock->method('getSessionId')->willReturn($mock_data['getSessionId']); $session_mock->method('getSessionId')->willReturn($mock_data['getSessionId']);
@@ -128,7 +247,25 @@ final class CoreLibsCreateSessionTest extends TestCase
// regex for session id // regex for session id
$ression_id_regex = "/^\w+$/"; $ression_id_regex = "/^\w+$/";
$session_id = $session_mock->getSessionId(); if ($exception !== null) {
$this->expectException($exception);
$this->expectExceptionCode($exception_code);
}
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 // asert checks
if (!empty($session_id)) { if (!empty($session_id)) {
$this->assertMatchesRegularExpression( $this->assertMatchesRegularExpression(
@@ -147,79 +284,6 @@ final class CoreLibsCreateSessionTest extends TestCase
} }
} }
/**
* Undocumented function
*
* @return array
*/
public function providerSessionException(): array
{
return [
'not cli' => [
'TEST_EXCEPTION',
\RuntimeException::class,
1,
'/^\[SESSION\] No sessions in php cli$/',
],
/* 'session disabled ' => [
'TEST_EXCEPTION',
\RuntimeException::class,
2,
'/^\[SESSION\] Sessions are disabled/'
],
'invalid session name' => [
'--#as^-292p-',
\UnexpectedValueException::class,
3,
'/^\[SESSION\] Invalid session name: /'
],
'failed to activate session' => [
'TEST_EXCEPTION',
\RuntimeException::class,
4,
'/^\[SESSION\] Failed to activate session/'
],
'expired session' => [
\RuntimeException::class,
5,
'/^\[SESSION\] Expired session found/'
],
'not a valid session id returned' => [
\UnexpectedValueException::class,
6,
'/^\[SESSION\] getSessionId did not return a session id/'
], */
];
}
/**
* exception checks
*
* @covers ::initSession
* @dataProvider providerSessionException
* @testdox create session $session_name with exception $exception ($exception_code) [$_dataName]
*
* @param string $session_name
* @param string $exception
* @param int $exception_code
* @param string $expected_error
* @return void
*/
public function testSessionException(
string $session_name,
string $exception,
int $exception_code,
string $expected_error,
): void {
//
// throws only on new Object creation
$this->expectException($exception);
$this->expectExceptionCode($exception_code);
$this->expectExceptionMessageMatches($expected_error);
// cannot set ini after header sent, plus we are on command line there are no headers
new \CoreLibs\Create\Session($session_name, ['session_strict' => false]);
}
/** /**
* provider for session name check * provider for session name check
* *
@@ -283,147 +347,109 @@ final class CoreLibsCreateSessionTest extends TestCase
* *
* @return array * @return array
*/ */
public function providerSessionData(): array public function sessionDataProvider(): array
{ {
return [ return [
'test' => [ 'test' => [
'foo', 'foo',
'bar', 'bar',
'bar', 'bar',
null,
], ],
'int key test' => [ 'int key test' => [
123, 123,
'bar', 'bar',
'bar', 'bar',
\UnexpectedValueException::class
], ],
// more complex value tests // more complex value tests
'array values' => [ 'array values' => [
'array', 'array',
[1, 2, 3], [1, 2, 3],
[1, 2, 3], [1, 2, 3],
null,
] ]
]; ];
} }
// NOTE: with auto start session, we cannot test this in the command line
/** /**
* method call test * method call test
* *
* @covers ::set * @covers ::setS
* @covers ::get * @covers ::getS
* @covers ::isset * @covers ::issetS
* @covers ::unset * @covers ::unsetS
* @dataProvider providerSessionData * @dataProvider sessionDataProvider
* @testdox set/get/isset/unset $name with $input is $expected ($exception) [$_dataName] * @testdox setS/getS/issetS/unsetS $name with $input is $expected [$_dataName]
* *
* @param string|int $name * @param string|int $name
* @param mixed $input * @param mixed $input
* @param mixed $expected * @param mixed $expected
* @param ?mixed $exception
* @return void * @return void
*/ */
public function testMethodSetGet($name, $input, $expected, $exception): void public function testMethodSetGet($name, $input, $expected): void
{ {
if (\CoreLibs\Get\System::checkCLI()) { $session = new \CoreLibs\Create\Session();
$this->markTestSkipped('Cannot run testMethodSetGet in CLI'); $session->setS($name, $input);
}
$session = new \CoreLibs\Create\Session('TEST_METHOD');
if ($expected !== null) {
$this->expectException($exception);
}
$session->set($name, $input);
$this->assertEquals( $this->assertEquals(
$expected, $expected,
$session->get($name), $session->getS($name),
'method set assert' 'method set assert'
); );
// isset true // isset true
$this->assertTrue( $this->assertTrue(
$session->isset($name), $session->issetS($name),
'method isset assert ok' 'method isset assert ok'
); );
$session->unset($name); $session->unsetS($name);
$this->assertEquals( $this->assertEquals(
'', '',
$session->get($name), $session->getS($name),
'method unset assert' 'method unset assert'
); );
// isset false // iset false
$this->assertFalse( $this->assertFalse(
$session->isset($name), $session->issetS($name),
'method isset assert false' 'method isset assert false'
); );
} }
/** /**
* Undocumented function * magic call test
* *
* @return array * @covers ::__set
*/ * @covers ::__get
public function providerSessionDataMany(): array * @covers ::__isset
{ * @covers ::__unset
return [ * @dataProvider sessionDataProvider
'valid set' => [ * @testdox __set/__get/__iseet/__unset $name with $input is $expected [$_dataName]
[
'foo 1' => 'bar 1',
'foo 2' => 'bar 1',
],
[
'foo 1' => 'bar 1',
'foo 2' => 'bar 1',
],
null,
],
'invalid entry' => [
[
'foo 1' => 'bar 1',
123 => 'bar 1',
],
[
'foo 1' => 'bar 1',
],
\UnexpectedValueException::class
]
];
}
/**
* Undocumented function
* *
* @covers ::setMany * @param string|int $name
* @covers ::getMany * @param mixed $input
* @dataProvider providerSessionDataMany * @param mixed $expected
* @testdox setMany/getMany/unsetMany $set is $expected ($exception) [$_dataName]
*
* @param array<string|int,mixed> $set
* @param array<string,mixed> $expected
* @param ?mixed $exception
* @return void * @return void
*/ */
public function testMany($set, $expected, $exception): void public function testMagicSetGet($name, $input, $expected): void
{ {
if (\CoreLibs\Get\System::checkCLI()) { $session = new \CoreLibs\Create\Session();
$this->markTestSkipped('Cannot run testMethodSetGet in CLI'); $session->$name = $input;
}
$session = new \CoreLibs\Create\Session('TEST_METHOD');
if ($expected !== null) {
$this->expectException($exception);
}
$session->setMany($set);
$this->assertEquals( $this->assertEquals(
$expected, $expected,
$session->getMany(array_keys($set)), $session->$name,
'set many failed' 'magic set assert'
); );
$session->unsetMany(array_keys($set)); // isset true
$this->assertTrue(
isset($session->$name),
'magic isset assert ok'
);
unset($session->$name);
$this->assertEquals( $this->assertEquals(
[], '',
$session->getMany(array_keys($set)), $session->$name,
'unset many failed' 'magic unset assert'
);
// isset true
$this->assertFalse(
isset($session->$name),
'magic isset assert false'
); );
} }
@@ -437,30 +463,27 @@ final class CoreLibsCreateSessionTest extends TestCase
*/ */
public function testUnsetAll(): void public function testUnsetAll(): void
{ {
if (\CoreLibs\Get\System::checkCLI()) {
$this->markTestSkipped('Cannot run testUnsetAll in CLI');
}
$test_values = [ $test_values = [
'foo' => 'abc', 'foo' => 'abc',
'bar' => '123' 'bar' => '123'
]; ];
$session = new \CoreLibs\Create\Session('TEST_UNSET'); $session = new \CoreLibs\Create\Session();
foreach ($test_values as $name => $value) { foreach ($test_values as $name => $value) {
$session->set($name, $value); $session->setS($name, $value);
// confirm set // confirm set
$this->assertEquals( $this->assertEquals(
$value, $value,
$session->get($name), $session->getS($name),
'set assert: ' . $name 'set assert: ' . $name
); );
} }
// unset all // unset all
$session->clear(); $session->unsetAllS();
// check unset // check unset
foreach (array_keys($test_values) as $name) { foreach (array_keys($test_values) as $name) {
$this->assertEquals( $this->assertEquals(
'', '',
$session->get($name), $session->getS($name),
'unsert assert: ' . $name 'unsert assert: ' . $name
); );
} }

View File

@@ -121,7 +121,6 @@ final class CoreLibsCreateUidsTest extends TestCase
* must match 7e78fe0d-59b8-4637-af7f-e88d221a7d1e * must match 7e78fe0d-59b8-4637-af7f-e88d221a7d1e
* *
* @covers ::uuidv4 * @covers ::uuidv4
* @covers ::validateUuidv4
* @testdox uuidv4 check that return is matching regex [$_dataName] * @testdox uuidv4 check that return is matching regex [$_dataName]
* *
* @return void * @return void
@@ -130,18 +129,13 @@ final class CoreLibsCreateUidsTest extends TestCase
{ {
$uuid = \CoreLibs\Create\Uids::uuidv4(); $uuid = \CoreLibs\Create\Uids::uuidv4();
$this->assertMatchesRegularExpression( $this->assertMatchesRegularExpression(
'/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/', '/^[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}$/',
$uuid, $uuid
'Failed regex check'
);
$this->assertTrue(
\CoreLibs\Create\Uids::validateUuuidv4($uuid),
'Failed validate regex method'
);
$this->assertFalse(
\CoreLibs\Create\Uids::validateUuuidv4('not-a-uuidv4'),
'Failed wrong uuid validated as true'
); );
// $this->assertStringMatchesFormat(
// '%4s%4s-%4s-%4s-%4s-%4s%4s%4s',
// $uuid
// );
} }
/** /**

View File

@@ -10,6 +10,7 @@ use PHPUnit\Framework\TestCase;
* Test class for DB\Extended\ArrayIO * Test class for DB\Extended\ArrayIO
* This will only test the PgSQL parts * This will only test the PgSQL parts
* @coversDefaultClass \CoreLibs\DB\Extended\ArrayIO * @coversDefaultClass \CoreLibs\DB\Extended\ArrayIO
* @coversDefaultClass \CoreLibs\DB\Extended\ArrayIO
* @testdox \CoreLibs\Extended\ArrayIO method tests for extended DB interface * @testdox \CoreLibs\Extended\ArrayIO method tests for extended DB interface
*/ */
final class CoreLibsDBExtendedArrayIOTest extends TestCase final class CoreLibsDBExtendedArrayIOTest extends TestCase

View File

@@ -17,7 +17,7 @@ Table with Primary Key: table_with_primary_key
Table without Primary Key: table_without_primary_key Table without Primary Key: table_without_primary_key
Table with primary key has additional row: Table with primary key has additional row:
row_primary_key INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, row_primary_key SERIAL PRIMARY KEY,
Each table has the following rows Each table has the following rows
row_int INT, row_int INT,
row_numeric NUMERIC, row_numeric NUMERIC,
@@ -37,14 +37,14 @@ namespace tests;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\MockObject\MockObject;
use CoreLibs\Logging; use CoreLibs\Logging\Logger\Level;
use CoreLibs\DB\Options\Convert; use CoreLibs\DB\Options\Convert;
use CoreLibs\DB\Support\ConvertPlaceholder;
/** /**
* Test class for DB\IO + DB\SQL\PgSQL * Test class for DB\IO + DB\SQL\PgSQL
* This will only test the PgSQL parts * This will only test the PgSQL parts
* @coversDefaultClass \CoreLibs\DB\IO * @coversDefaultClass \CoreLibs\DB\IO
* @coversDefaultClass \CoreLibs\DB\SQL\PgSQL
* @testdox \CoreLibs\DB\IO method tests for SQL\PgSQL * @testdox \CoreLibs\DB\IO method tests for SQL\PgSQL
*/ */
final class CoreLibsDBIOTest extends TestCase final class CoreLibsDBIOTest extends TestCase
@@ -117,7 +117,7 @@ final class CoreLibsDBIOTest extends TestCase
); );
} }
// define basic connection set valid and one invalid // define basic connection set valid and one invalid
self::$log = new Logging\Logging([ self::$log = new \CoreLibs\Logging\Logging([
// 'log_folder' => __DIR__ . DIRECTORY_SEPARATOR . 'log', // 'log_folder' => __DIR__ . DIRECTORY_SEPARATOR . 'log',
'log_folder' => DIRECTORY_SEPARATOR . 'tmp', 'log_folder' => DIRECTORY_SEPARATOR . 'tmp',
'log_file_id' => 'CoreLibs-DB-IO-Test', 'log_file_id' => 'CoreLibs-DB-IO-Test',
@@ -134,7 +134,6 @@ final class CoreLibsDBIOTest extends TestCase
} }
// check if they already exist, drop them // check if they already exist, drop them
if ($db->dbShowTableMetaData('table_with_primary_key') !== false) { if ($db->dbShowTableMetaData('table_with_primary_key') !== false) {
$db->dbExec("CREATE EXTENSION IF NOT EXISTS pgcrypto");
$db->dbExec("DROP TABLE table_with_primary_key"); $db->dbExec("DROP TABLE table_with_primary_key");
$db->dbExec("DROP TABLE table_without_primary_key"); $db->dbExec("DROP TABLE table_without_primary_key");
$db->dbExec("DROP TABLE test_meta"); $db->dbExec("DROP TABLE test_meta");
@@ -162,9 +161,13 @@ final class CoreLibsDBIOTest extends TestCase
// primary key name is table + '_id' // primary key name is table + '_id'
<<<SQL <<<SQL
CREATE TABLE table_with_primary_key ( CREATE TABLE table_with_primary_key (
table_with_primary_key_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, table_with_primary_key_id SERIAL PRIMARY KEY,
$base_table $base_table
SQL SQL
/* "CREATE TABLE table_with_primary_key ("
// primary key name is table + '_id'
. "table_with_primary_key_id SERIAL PRIMARY KEY, "
. $base_table */
); );
$db->dbExec( $db->dbExec(
<<<SQL <<<SQL
@@ -567,11 +570,11 @@ final class CoreLibsDBIOTest extends TestCase
); );
$db->dbClose(); $db->dbClose();
// second conenction with log set NOT debug // second conenction with log set NOT debug
$log = new Logging\Logging([ $log = new \CoreLibs\Logging\Logging([
// 'log_folder' => __DIR__ . DIRECTORY_SEPARATOR . 'log', // 'log_folder' => __DIR__ . DIRECTORY_SEPARATOR . 'log',
'log_folder' => DIRECTORY_SEPARATOR . 'tmp', 'log_folder' => DIRECTORY_SEPARATOR . 'tmp',
'log_file_id' => 'CoreLibs-DB-IO-Test', 'log_file_id' => 'CoreLibs-DB-IO-Test',
'log_level' => Logging\Logger\Level::Notice, 'log_level' => \CoreLibs\Logging\Logger\Level::Notice,
]); ]);
$db = new \CoreLibs\DB\IO( $db = new \CoreLibs\DB\IO(
self::$db_config[$connection], self::$db_config[$connection],
@@ -3290,7 +3293,6 @@ final class CoreLibsDBIOTest extends TestCase
'query' => 'INSERT INTO table_with_primary_key (row_int, uid) ' 'query' => 'INSERT INTO table_with_primary_key (row_int, uid) '
. 'VALUES ($1, $2) RETURNING table_with_primary_key_id', . 'VALUES ($1, $2) RETURNING table_with_primary_key_id',
'returning_id' => true, 'returning_id' => true,
'placeholder_converted' => [],
], ],
], ],
// update // update
@@ -3325,7 +3327,6 @@ final class CoreLibsDBIOTest extends TestCase
'query' => 'UPDATE table_with_primary_key SET row_int = $1, ' 'query' => 'UPDATE table_with_primary_key SET row_int = $1, '
. 'row_varchar = $2 WHERE uid = $3', . 'row_varchar = $2 WHERE uid = $3',
'returning_id' => false, 'returning_id' => false,
'placeholder_converted' => [],
], ],
], ],
// select // select
@@ -3355,7 +3356,6 @@ final class CoreLibsDBIOTest extends TestCase
'count' => 1, 'count' => 1,
'query' => 'SELECT row_int, uid FROM table_with_primary_key WHERE uid = $1', 'query' => 'SELECT row_int, uid FROM table_with_primary_key WHERE uid = $1',
'returning_id' => false, 'returning_id' => false,
'placeholder_converted' => [],
], ],
], ],
// any query but with no parameters // any query but with no parameters
@@ -3388,7 +3388,6 @@ final class CoreLibsDBIOTest extends TestCase
'count' => 0, 'count' => 0,
'query' => 'SELECT row_int, uid FROM table_with_primary_key', 'query' => 'SELECT row_int, uid FROM table_with_primary_key',
'returning_id' => false, 'returning_id' => false,
'placeholder_converted' => [],
], ],
], ],
// no statement name (25) // no statement name (25)
@@ -3412,7 +3411,6 @@ final class CoreLibsDBIOTest extends TestCase
'count' => 0, 'count' => 0,
'query' => '', 'query' => '',
'returning_id' => false, 'returning_id' => false,
'placeholder_converted' => [],
], ],
], ],
// no query (prepare 11) // no query (prepare 11)
@@ -3437,7 +3435,6 @@ final class CoreLibsDBIOTest extends TestCase
'count' => 0, 'count' => 0,
'query' => '', 'query' => '',
'returning_id' => false, 'returning_id' => false,
'placeholder_converted' => [],
], ],
], ],
// no db connection (prepare/execute 16) // no db connection (prepare/execute 16)
@@ -3467,7 +3464,6 @@ final class CoreLibsDBIOTest extends TestCase
'count' => 0, 'count' => 0,
'query' => 'SELECT row_int, uid FROM table_with_primary_key', 'query' => 'SELECT row_int, uid FROM table_with_primary_key',
'returning_id' => false, 'returning_id' => false,
'placeholder_converted' => [],
], ],
], ],
// prepare with different statement name // prepare with different statement name
@@ -3493,7 +3489,6 @@ final class CoreLibsDBIOTest extends TestCase
'count' => 0, 'count' => 0,
'query' => 'SELECT row_int, uid FROM table_with_primary_key', 'query' => 'SELECT row_int, uid FROM table_with_primary_key',
'returning_id' => false, 'returning_id' => false,
'placeholder_converted' => [],
], ],
], ],
// insert wrong data count compared to needed (execute 23) // insert wrong data count compared to needed (execute 23)
@@ -3519,12 +3514,10 @@ final class CoreLibsDBIOTest extends TestCase
'query' => 'INSERT INTO table_with_primary_key (row_int, uid) VALUES ' 'query' => 'INSERT INTO table_with_primary_key (row_int, uid) VALUES '
. '($1, $2) RETURNING table_with_primary_key_id', . '($1, $2) RETURNING table_with_primary_key_id',
'returning_id' => true, 'returning_id' => true,
'placeholder_converted' => [],
], ],
], ],
// execute does not return a result (22) // execute does not return a result (22)
// TODO execute does not return a result // TODO execute does not return a result
// TODO prepared statement with placeholder params auto convert
]; ];
} }
@@ -3669,7 +3662,7 @@ final class CoreLibsDBIOTest extends TestCase
} }
// check dbGetPrepareCursorValue // check dbGetPrepareCursorValue
foreach (['pk_name', 'count', 'query', 'returning_id', 'placeholder_converted'] as $key) { foreach (['pk_name', 'count', 'query', 'returning_id'] as $key) {
$this->assertEquals( $this->assertEquals(
$prepare_cursor[$key], $prepare_cursor[$key],
$db->dbGetPrepareCursorValue($stm_name, $key), $db->dbGetPrepareCursorValue($stm_name, $key),
@@ -3692,7 +3685,7 @@ final class CoreLibsDBIOTest extends TestCase
* *
* @return array * @return array
*/ */
public function providerDbGetPrepareCursorValue(): array public function preparedProviderValue(): array
{ {
// 1: query (can be empty for do not set) // 1: query (can be empty for do not set)
// 2: stm name // 2: stm name
@@ -3736,7 +3729,7 @@ final class CoreLibsDBIOTest extends TestCase
* test return prepare cursor errors * test return prepare cursor errors
* *
* @covers ::dbGetPrepareCursorValue * @covers ::dbGetPrepareCursorValue
* @dataProvider providerDbGetPrepareCursorValue * @dataProvider preparedProviderValue
* @testdox prepared query $stm_name with $key expect error id $error_id [$_dataName] * @testdox prepared query $stm_name with $key expect error id $error_id [$_dataName]
* *
* @param string $query * @param string $query
@@ -3769,94 +3762,6 @@ final class CoreLibsDBIOTest extends TestCase
); );
} }
/**
* Undocumented function
*
* @return array
*/
public function providerDbPreparedCursorStatus(): array
{
return [
'empty statement pararm' => [
'query' => 'SELECT row_int, uid FROM table_with_primary_key',
'stm_name' => 'test_stm_a',
'check_stm_name' => '',
'check_query' => '',
'expected' => false
],
'different stm_name' => [
'query' => 'SELECT row_int, uid FROM table_with_primary_key',
'stm_name' => 'test_stm_b',
'check_stm_name' => 'other_name',
'check_query' => '',
'expected' => 0
],
'same stm_name' => [
'query' => 'SELECT row_int, uid FROM table_with_primary_key',
'stm_name' => 'test_stm_c',
'check_stm_name' => 'test_stm_c',
'check_query' => '',
'expected' => 1
],
'same stm_name and query' => [
'query' => 'SELECT row_int, uid FROM table_with_primary_key',
'stm_name' => 'test_stm_d',
'check_stm_name' => 'test_stm_d',
'check_query' => 'SELECT row_int, uid FROM table_with_primary_key',
'expected' => 2
],
'same stm_name and different query' => [
'query' => 'SELECT row_int, uid FROM table_with_primary_key',
'stm_name' => 'test_stm_e',
'check_stm_name' => 'test_stm_e',
'check_query' => 'SELECT row_int, uid, row_int FROM table_with_primary_key',
'expected' => 1
],
'insert query test' => [
'query' => 'INSERT INTO table_with_primary_key (row_int, uid) VALUES ($1, $2)',
'stm_name' => 'test_stm_f',
'check_stm_name' => 'test_stm_f',
'check_query' => 'INSERT INTO table_with_primary_key (row_int, uid) VALUES ($1, $2)',
'expected' => 2
]
];
}
/**
* test cursor status for prepared statement
*
* @covers ::dbPreparedCursorStatus
* @dataProvider providerDbPreparedCursorStatus
* @testdox Check prepared $stm_name ($check_stm_name) status is $expected [$_dataName]
*
* @param string $query
* @param string $stm_name
* @param string $check_stm_name
* @param string $check_query
* @param bool|int $expected
* @return void
*/
public function testDbPreparedCursorStatus(
string $query,
string $stm_name,
string $check_stm_name,
string $check_query,
bool|int $expected
): void {
$db = new \CoreLibs\DB\IO(
self::$db_config['valid'],
self::$log
);
$db->dbPrepare($stm_name, $query);
// $db->dbExecute($stm_name);
$this->assertEquals(
$expected,
$db->dbPreparedCursorStatus($check_stm_name, $check_query),
'check prepared stement cursor status'
);
unset($db);
}
// - schema set/get tests // - schema set/get tests
// dbGetSchema, dbSetSchema // dbGetSchema, dbSetSchema
@@ -4744,7 +4649,7 @@ final class CoreLibsDBIOTest extends TestCase
$res = $db->dbReturnRowParams($query_select, ['CONVERT_TYPE_TEST']); $res = $db->dbReturnRowParams($query_select, ['CONVERT_TYPE_TEST']);
// all hast to be string // all hast to be string
foreach ($res as $key => $value) { foreach ($res as $key => $value) {
$this->assertIsString($value, 'Assert string for column: ' . $key); $this->assertIsString($value, 'Aseert string for column: ' . $key);
} }
// convert base only // convert base only
$db->dbSetConvertFlag(Convert::on); $db->dbSetConvertFlag(Convert::on);
@@ -4757,10 +4662,10 @@ final class CoreLibsDBIOTest extends TestCase
} }
switch ($type_layout[$name]) { switch ($type_layout[$name]) {
case 'int': case 'int':
$this->assertIsInt($value, 'Assert int for column: ' . $key . '/' . $name); $this->assertIsInt($value, 'Aseert int for column: ' . $key . '/' . $name);
break; break;
default: default:
$this->assertIsString($value, 'Assert string for column: ' . $key . '/' . $name); $this->assertIsString($value, 'Aseert string for column: ' . $key . '/' . $name);
break; break;
} }
} }
@@ -4774,13 +4679,13 @@ final class CoreLibsDBIOTest extends TestCase
} }
switch ($type_layout[$name]) { switch ($type_layout[$name]) {
case 'int': case 'int':
$this->assertIsInt($value, 'Assert int for column: ' . $key . '/' . $name); $this->assertIsInt($value, 'Aseert int for column: ' . $key . '/' . $name);
break; break;
case 'float': case 'float':
$this->assertIsFloat($value, 'Assert float for column: ' . $key . '/' . $name); $this->assertIsFloat($value, 'Aseert float for column: ' . $key . '/' . $name);
break; break;
default: default:
$this->assertIsString($value, 'Assert string for column: ' . $key . '/' . $name); $this->assertIsString($value, 'Aseert string for column: ' . $key . '/' . $name);
break; break;
} }
} }
@@ -4794,17 +4699,17 @@ final class CoreLibsDBIOTest extends TestCase
} }
switch ($type_layout[$name]) { switch ($type_layout[$name]) {
case 'int': case 'int':
$this->assertIsInt($value, 'Assert int for column: ' . $key . '/' . $name); $this->assertIsInt($value, 'Aseert int for column: ' . $key . '/' . $name);
break; break;
case 'float': case 'float':
$this->assertIsFloat($value, 'Assert float for column: ' . $key . '/' . $name); $this->assertIsFloat($value, 'Aseert float for column: ' . $key . '/' . $name);
break; break;
case 'json': case 'json':
case 'jsonb': case 'jsonb':
$this->assertIsArray($value, 'Assert array for column: ' . $key . '/' . $name); $this->assertIsArray($value, 'Aseert array for column: ' . $key . '/' . $name);
break; break;
default: default:
$this->assertIsString($value, 'Assert string for column: ' . $key . '/' . $name); $this->assertIsString($value, 'Aseert string for column: ' . $key . '/' . $name);
break; break;
} }
} }
@@ -4818,25 +4723,25 @@ final class CoreLibsDBIOTest extends TestCase
} }
switch ($type_layout[$name]) { switch ($type_layout[$name]) {
case 'int': case 'int':
$this->assertIsInt($value, 'Assert int for column: ' . $key . '/' . $name); $this->assertIsInt($value, 'Aseert int for column: ' . $key . '/' . $name);
break; break;
case 'float': case 'float':
$this->assertIsFloat($value, 'Assert float for column: ' . $key . '/' . $name); $this->assertIsFloat($value, 'Aseert float for column: ' . $key . '/' . $name);
break; break;
case 'json': case 'json':
case 'jsonb': case 'jsonb':
$this->assertIsArray($value, 'Assert array for column: ' . $key . '/' . $name); $this->assertIsArray($value, 'Aseert array for column: ' . $key . '/' . $name);
break; break;
case 'bytea': case 'bytea':
// for hex types it must not start with \x // for hex types it must not start with \x
$this->assertStringStartsNotWith( $this->assertStringStartsNotWith(
'\x', '\x',
$value, $value,
'Assert bytes not starts with \x for column: ' . $key . '/' . $name 'Aseert bytes not starts with \x for column: ' . $key . '/' . $name
); );
break; break;
default: default:
$this->assertIsString($value, 'Assert string for column: ' . $key . '/' . $name); $this->assertIsString($value, 'Aseert string for column: ' . $key . '/' . $name);
break; break;
} }
} }
@@ -5008,8 +4913,8 @@ final class CoreLibsDBIOTest extends TestCase
) )
), ),
($params === null ? ($params === null ?
$db->dbBuildQueryHash($query) : $db->dbGetQueryHash($query) :
$db->dbBuildQueryHash($query, $params) $db->dbGetQueryHash($query, $params)
), ),
'Failed assertdbGetQueryHash ' 'Failed assertdbGetQueryHash '
); );
@@ -5126,285 +5031,8 @@ final class CoreLibsDBIOTest extends TestCase
$db->dbClose(); $db->dbClose();
} }
// MARK: QUERY PLACEHOLDERS // query placeholder convert
// test query placeholder detection for all possible sets
// ::dbPrepare
/**
* placeholder sql
*
* @return array
*/
public function providerDbCountQueryParams(): array
{
return [
'one place holder' => [
'query' => 'SELECT row_varchar FROM table_with_primary_key WHERE row_varchar = $1',
'count' => 1,
'convert' => false,
],
'one place holder, json call' => [
'query' => "SELECT row_varchar FROM table_with_primary_key WHERE row_jsonb->>'data' = $1",
'count' => 1,
'convert' => false,
],
'one place holder, <> compare' => [
'query' => "SELECT row_varchar FROM table_with_primary_key WHERE row_varchar <> $1",
'count' => 1,
'convert' => false,
],
'one place holder, named' => [
'query' => "SELECT row_varchar FROM table_with_primary_key WHERE row_varchar <> :row_varchar",
'count' => 1,
'convert' => true,
],
'no replacement' => [
'query' => "SELECT row_varchar FROM table_with_primary_key WHERE row_varchar = '$1'",
'count' => 0,
'convert' => false,
],
'insert' => [
'query' => "INSERT INTO table_with_primary_key (row_varchar, row_jsonb, row_int) VALUES ($1, $2, $3)",
'count' => 3,
'convert' => false,
],
'update' => [
'query' => "UPDATE table_with_primary_key SET row_varchar = $1, row_jsonb = $2, row_int = $3 WHERE row_numeric = $4",
'count' => 4,
'convert' => false,
],
'multiple, multline' => [
'query' => <<<SQL
SELECT
row_varchar
FROM
table_with_primary_key
WHERE
row_varchar = $1 AND row_int = $2
AND row_numeric = ANY($3)
SQL,
'count' => 3,
'convert' => false,
],
'two digit numbers' => [
'query' => <<<SQL
INSERT INTO table_with_primary_key (
row_int, row_numeric, row_varchar, row_varchar_literal, row_json,
row_jsonb, row_bytea, row_timestamp, row_date, row_interval
) VALUES (
$1, $2, $3, $4, $5,
$6, $7, $8, $9, $10
)
SQL,
'count' => 10,
'convert' => false,
],
'things in brackets' => [
'query' => <<<SQL
SELECT row_varchar
FROM table_with_primary_key
WHERE
row_varchar = $1 AND
(row_int = ANY($2) OR row_int = $3)
AND row_varchar_literal = $4
SQL,
'count' => 4,
'convert' => false,
],
'number compare' => [
'query' => <<<SQL
SELECT row_varchar
FROM table_with_primary_key
WHERE
row_int >= $1 OR row_int <= $2 OR
row_int > $3 OR row_int < $4
OR row_int = $5 OR row_int <> $6
SQL,
'count' => 6,
'convert' => false,
],
'comments in insert' => [
'query' => <<<SQL
INSERT INTO table_with_primary_key (
row_int, row_numeric, row_varchar, row_varchar_literal
) VALUES (
-- comment 1 かな
$1, $2,
-- comment 2 -
$3
-- comment 3
, $4
-- ignore $5, $6
-- $7, $8
-- digest($9, 10)
)
SQL,
'count' => 4,
'convert' => false
],
'comment in update' => [
'query' => <<<SQL
UPDATE table_with_primary_key SET
row_int =
-- COMMENT 1
$1,
row_numeric =
$2 -- COMMENT 2
,
row_varchar -- COMMENT 3
= $3
WHERE
row_varchar = $4
SQL,
'count' => 4,
'convert' => false,
],
// Note some are not set
'a complete set of possible' => [
'query' => <<<SQL
UPDATE table_with_primary_key SET
-- ROW
row_varchar = $1
WHERE
row_varchar = ANY($2) AND row_varchar <> $3
AND row_varchar > $4 AND row_varchar < $5
AND row_varchar >= $6 AND row_varchar <=$7
AND row_jsonb->'a' = $8 AND row_jsonb->>$9 = 'a'
AND row_jsonb<@$10 AND row_jsonb@>$11
AND row_varchar ^@ $12
SQL,
'count' => 12,
'convert' => false,
],
// all the same
'all the same numbered' => [
'query' => <<<SQL
UPDATE table_with_primary_key SET
row_int = $1::INT, row_numeric = $1::NUMERIC, row_varchar = $1
WHERE
row_varchar = $1
SQL,
'count' => 1,
'convert' => false,
],
'update with case' => [
'query' => <<<SQL
UPDATE table_with_primary_key SET
row_int = $1::INT,
row_varchar = CASE WHEN row_int = 1 THEN $2 ELSE 'bar'::VARCHAR END
WHERE
row_varchar = $3
SQL,
'count' => 3,
'convert' => false,
],
'select with case' => [
'query' => <<<SQL
SELECT row_int
FROM table_with_primary_key
WHERE
row_varchar = CASE WHEN row_int = 1 THEN $1 ELSE $2 END
SQL,
'count' => 2,
'convert' => false,
],
// special $$ string case
'text string, with $ placehoders that could be seen as $$ string' => [
'query' => <<<SQL
SELECT row_int
FROM table_with_primary_key
WHERE
row_bytea = digest($3::VARCHAR, $4) OR
row_varchar = encode(digest($3, $4), 'hex') OR
row_bytea = hmac($3, $5, $4) OR
row_varchar = encode(hmac($3, $5, $4), 'hex') OR
row_bytea = pgp_sym_encrypt($3, $6) OR
row_varchar = encode(pgp_sym_encrypt($1, $6), 'hex') OR
row_varchar = CASE WHEN row_int = 1 THEN $1 ELSE $2 END
SQL,
'count' => 6,
'convert' => false,
],
// NOTE, in SQL heredoc we cannot write $$ strings parts
'text string, with $ placehoders are in $$ strings' => [
'query' => '
SELECT row_int
FROM table_with_primary_key
WHERE
row_varchar = $$some string$$ OR
row_varchar = $tag$some string$tag$ OR
row_varchar = $btag$some $1 string$btag$ OR
row_varchar = $btag$some $1 $subtag$ something $subtag$string$btag$ OR
row_varchar = $1
',
'count' => 1,
'convert' => false,
],
// a text string with escaped quite
'text string, with escaped quote' => [
'query' => <<<SQL
SELECT row_int
FROM table_with_primary_key
WHERE
row_varchar = 'foo bar bar baz $5' OR
row_varchar = 'foo bar '' barbar $6' OR
row_varchar = E'foo bar \' barbar $7' OR
row_varchar = CASE WHEN row_int = 1 THEN $1 ELSE $2 END
SQL,
'count' => 2,
'convert' => false,
]
];
$string = <<<SQL
'''
SQL;
}
/**
* Placeholder check and convert tests
*
* @covers ::dbPrepare
* @covers ::__dbCountQueryParams
* @onvers ::convertPlaceholderInQuery
* @dataProvider providerDbCountQueryParams
* @testdox Query replacement count test [$_dataName]
*
* @param string $query
* @param int $count
* @return void
*/
public function testDbCountQueryParams(string $query, int $count, bool $convert): void
{
$db = new \CoreLibs\DB\IO(
self::$db_config['valid'],
self::$log
);
$id = sha1($query);
$db->dbSetConvertPlaceholder($convert);
$db->dbPrepare($id, $query);
// print "\n**\n";
// print "PCount: " . $db->dbGetPrepareCursorValue($id, 'count') . "\n";
// print "\n**\n";
$this->assertEquals(
$count,
$db->dbGetPrepareCursorValue($id, 'count'),
'DB count params'
);
$placeholder = ConvertPlaceholder::convertPlaceholderInQuery($query, null, 'pg');
// print "RES: " . print_r($placeholder, true) . "\n";
$this->assertEquals(
$count,
$placeholder['needed'],
'convert params'
);
}
/**
* query placeholder convert
*
* @return array
*/
public function queryPlaceholderReplaceProvider(): array public function queryPlaceholderReplaceProvider(): array
{ {
// WHERE row_varchar = $1 // WHERE row_varchar = $1
@@ -5448,9 +5076,7 @@ final class CoreLibsDBIOTest extends TestCase
WHERE row_varchar = $1 WHERE row_varchar = $1
SQL, SQL,
'expected_params' => ['string a'], 'expected_params' => ['string a'],
], ]
// TODO: test with multiple entries
// TODO: test with same entry ($1, $1, :var, :var)
]; ];
} }
@@ -5552,8 +5178,6 @@ final class CoreLibsDBIOTest extends TestCase
// - data debug // - data debug
// dbDumpData // dbDumpData
// MARK: ASYNC
// ASYNC at the end because it has 1s timeout // ASYNC at the end because it has 1s timeout
// - asynchronous executions // - asynchronous executions
// dbExecAsync, dbCheckAsync // dbExecAsync, dbCheckAsync

View File

@@ -568,9 +568,6 @@ final class CoreLibsDebugSupportTest extends TestCase
'assert expected 12' 'assert expected 12'
); );
break; break;
default:
$this->assertTrue(true, 'Default fallback as true');
break;
} }
} }

View File

@@ -21,6 +21,341 @@ final class CoreLibsLanguageGetLocaleTest extends TestCase
. 'includes' . DIRECTORY_SEPARATOR . 'includes' . DIRECTORY_SEPARATOR
. 'locale' . DIRECTORY_SEPARATOR; . 'locale' . DIRECTORY_SEPARATOR;
/**
* 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<mixed>
*/
/* public function setLocaleProvider(): array
{
return [
// 0: locale
// 1: domain
// 2: encoding
// 3: path
// 4: SESSION: DEFAULT_LOCALE
// 5: SESSION: DEFAULT_CHARSET
// 6: expected array
// 7: deprecation message
'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\/$/",
],
'setLocale: Unset $locale or unset SESSION locale is deprecated',
],
'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\/$/",
],
'setLocale: Unset $domain is deprecated'
],
'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\/$/",
],
'setLocale: Unset $domain is deprecated',
],
// 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\/$/",
],
'setLocale: Unset $domain is deprecated',
],
// 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\/$/",
],
'setLocale: Unset $domain is deprecated',
],
// 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\/$/",
],
'setLocale: Unset $path is deprecated',
],
// 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\/$/",
],
'setLocale: Unset $path is deprecated'
],
// 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\/$/",
],
null
],
// 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\/$/",
],
null
],
// 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\/$/",
],
'setLocale: Unset $path is deprecated',
],
// 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]
*
* @param string|null $language
* @param string|null $domain
* @param string|null $encoding
* @param string|null $path
* @param string|null $SESSION_DEFAULT_LOCALE
* @param string|null $SESSION_DEFAULT_CHARSET
* @param array<mixed> $expected
* @param string|null $deprecation_message
* @return void
*/
/* public function testsetLocale(
?string $language,
?string $domain,
?string $encoding,
?string $path,
?string $SESSION_DEFAULT_LOCALE,
?string $SESSION_DEFAULT_CHARSET,
array $expected,
?string $deprecation_message
): void {
$return_lang_settings = [];
global $_SESSION;
// set override
if ($SESSION_DEFAULT_LOCALE !== null) {
$_SESSION['DEFAULT_LOCALE'] = $SESSION_DEFAULT_LOCALE;
}
if ($SESSION_DEFAULT_CHARSET !== null) {
$_SESSION['DEFAULT_CHARSET'] = $SESSION_DEFAULT_CHARSET;
}
if ($deprecation_message !== null) {
set_error_handler(
static function (int $errno, string $errstr): never {
throw new \Exception($errstr, $errno);
},
E_USER_DEPRECATED
);
// catch this with the message
$this->expectExceptionMessage($deprecation_message);
}
// 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
);
}
restore_error_handler();
// 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']);
} */
/** /**
* all the test data * all the test data
* *

View File

@@ -1,2 +0,0 @@
*
!.gitignore

View File

@@ -10,7 +10,7 @@ use CoreLibs\Logging\Logger\Level;
/** /**
* Test class for Logging * Test class for Logging
* @coversDefaultClass \CoreLibs\Logging\ErrorMessages * @coversDefaultClass \CoreLibs\Logging\ErrorMessages
* @testdox \CoreLibs\Logging\ErrorMessages method tests * @testdox \CoreLibs\Logging\ErrorMEssages method tests
*/ */
final class CoreLibsLoggingErrorMessagesTest extends TestCase final class CoreLibsLoggingErrorMessagesTest extends TestCase
{ {
@@ -105,15 +105,11 @@ final class CoreLibsLoggingErrorMessagesTest extends TestCase
'log_folder' => self::LOG_FOLDER, 'log_folder' => self::LOG_FOLDER,
'log_level' => Level::Error, 'log_level' => Level::Error,
]); ]);
$errorLogTmpfile = tmpfile();
$errorLogLocationBackup = ini_set('error_log', stream_get_meta_data($errorLogTmpfile)['uri']);
$em = new \CoreLibs\Logging\ErrorMessage($log); $em = new \CoreLibs\Logging\ErrorMessage($log);
$em->setMessage( $em->setMessage(
$level, $level,
$str $str
); );
// for exceptions if log level is set to catch them
$error_log_content = stream_get_contents($errorLogTmpfile);
$this->assertEquals( $this->assertEquals(
[ [
'level' => $expected, 'level' => $expected,
@@ -381,8 +377,6 @@ final class CoreLibsLoggingErrorMessagesTest extends TestCase
?bool $log_warning, ?bool $log_warning,
string $expected string $expected
): void { ): void {
$errorLogTmpfile = tmpfile();
$errorLogLocationBackup = ini_set('error_log', stream_get_meta_data($errorLogTmpfile)['uri']);
$log = new \CoreLibs\Logging\Logging([ $log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testErrorMessagesLogError', 'log_file_id' => 'testErrorMessagesLogError',
'log_folder' => self::LOG_FOLDER, 'log_folder' => self::LOG_FOLDER,
@@ -398,9 +392,6 @@ final class CoreLibsLoggingErrorMessagesTest extends TestCase
log_error: $log_error, log_error: $log_error,
log_warning: $log_warning log_warning: $log_warning
); );
ini_set('error_log', $errorLogLocationBackup);
// for exceptions if log level is set to catch them
$error_log_content = stream_get_contents($errorLogTmpfile);
$file_content = ''; $file_content = '';
if (is_file($log->getLogFolder() . $log->getLogFile())) { if (is_file($log->getLogFolder() . $log->getLogFile())) {
$file_content = file_get_contents( $file_content = file_get_contents(
@@ -456,8 +447,6 @@ final class CoreLibsLoggingErrorMessagesTest extends TestCase
'log_level' => Level::Debug, 'log_level' => Level::Debug,
'log_per_run' => true 'log_per_run' => true
]); ]);
$errorLogTmpfile = tmpfile();
$errorLogLocationBackup = ini_set('error_log', stream_get_meta_data($errorLogTmpfile)['uri']);
$em = new \CoreLibs\Logging\ErrorMessage($log); $em = new \CoreLibs\Logging\ErrorMessage($log);
$em->setErrorMsg( $em->setErrorMsg(
$id, $id,
@@ -467,9 +456,6 @@ final class CoreLibsLoggingErrorMessagesTest extends TestCase
log_error: $log_error, log_error: $log_error,
log_warning: $log_warning log_warning: $log_warning
); );
ini_set('error_log', $errorLogLocationBackup);
// for exceptions if log level is set to catch them
$error_log_content = stream_get_contents($errorLogTmpfile);
$file_content = ''; $file_content = '';
if (is_file($log->getLogFolder() . $log->getLogFile())) { if (is_file($log->getLogFolder() . $log->getLogFile())) {
$file_content = file_get_contents( $file_content = file_get_contents(

View File

@@ -18,7 +18,7 @@ use CoreLibs\Logging\Logger\Flag;
final class CoreLibsLoggingLoggingTest extends TestCase final class CoreLibsLoggingLoggingTest extends TestCase
{ {
private const LOG_FOLDER = __DIR__ . DIRECTORY_SEPARATOR . 'log' . DIRECTORY_SEPARATOR; private const LOG_FOLDER = __DIR__ . DIRECTORY_SEPARATOR . 'log' . DIRECTORY_SEPARATOR;
private const REGEX_BASE = "\[[\d\-\s\.:+T]+\]\s{1}" // date, just basic checks private const REGEX_BASE = "\[[\d\-\s\.:]+\]\s{1}" // date
. "\[[\w\.]+(:\d+)?\]\s{1}" // host:port . "\[[\w\.]+(:\d+)?\]\s{1}" // host:port
. "\[(phar:\/\/)?[\w\-\.\/]+:\d+\]\s{1}" // folder/file [note phar:// is for phpunit] . "\[(phar:\/\/)?[\w\-\.\/]+:\d+\]\s{1}" // folder/file [note phar:// is for phpunit]
. "\[\w+\]\s{1}" // run id . "\[\w+\]\s{1}" // run id
@@ -249,7 +249,7 @@ final class CoreLibsLoggingLoggingTest extends TestCase
$this->assertFalse( $this->assertFalse(
$log->loggingLevelIsDebug() $log->loggingLevelIsDebug()
); );
// not set, should be debug // not set, should be debug]
$log = new \CoreLibs\Logging\Logging([ $log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testSetLoggingLevel', 'log_file_id' => 'testSetLoggingLevel',
'log_folder' => self::LOG_FOLDER, 'log_folder' => self::LOG_FOLDER,
@@ -297,71 +297,6 @@ final class CoreLibsLoggingLoggingTest extends TestCase
$log->setLoggingLevel('NotGood'); $log->setLoggingLevel('NotGood');
} }
/**
* Undocumented function
*
* @covers ::setErrorLogWriteLevel
* @covers ::getErrorLogWriteLevel
* @testdox setErrorLogWriteLevel set/get checks
*
* @return void
*/
public function testSetErrorLogWriteLevel(): void
{
// valid that is not Debug
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testSetErrorLogWriteLevel',
'log_folder' => self::LOG_FOLDER,
'error_log_write_level' => Level::Error
]);
$this->assertEquals(
Level::Error,
$log->getErrorLogWriteLevel()
);
// not set on init
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testSetErrorLogWriteLevel',
'log_folder' => self::LOG_FOLDER,
]);
$this->assertEquals(
Level::Emergency,
$log->getErrorLogWriteLevel()
);
// invalid, should be Emergency, will throw excpetion too
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage(
'Option: "error_log_write_level" is not of instance \CoreLibs\Logging\Logger\Level'
);
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testSetLoggingLevel',
'log_folder' => self::LOG_FOLDER,
'error_log_write_level' => 'I'
]);
$this->assertEquals(
Level::Emergency,
$log->getErrorLogWriteLevel()
);
// set valid then change
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testSetErrorLogWriteLevel',
'log_folder' => self::LOG_FOLDER,
'error_log_write_level' => Level::Error
]);
$this->assertEquals(
Level::Error,
$log->getErrorLogWriteLevel()
);
$log->setErrorLogWriteLevel(Level::Notice);
$this->assertEquals(
Level::Notice,
$log->getErrorLogWriteLevel()
);
// illegal logging level
$this->expectException(\Psr\Log\InvalidArgumentException::class);
$this->expectExceptionMessageMatches("/^Level \"NotGood\" is not defined, use one of: /");
$log->setErrorLogWriteLevel('NotGood');
}
// setLogFileId // setLogFileId
// getLogFileId // getLogFileId
@@ -460,7 +395,7 @@ final class CoreLibsLoggingLoggingTest extends TestCase
} }
$per_run_id = $log->getLogUniqueId(); $per_run_id = $log->getLogUniqueId();
$this->assertMatchesRegularExpression( $this->assertMatchesRegularExpression(
"/^\d{4}-\d{2}-\d{2}_\d{6}\.U_[a-z0-9]{8}$/", "/^\d{4}-\d{2}-\d{2}_\d{6}_U_[a-z0-9]{8}$/",
$per_run_id, $per_run_id,
'assert per log run id 1st' 'assert per log run id 1st'
); );
@@ -468,7 +403,7 @@ final class CoreLibsLoggingLoggingTest extends TestCase
$log->setLogUniqueId(true); $log->setLogUniqueId(true);
$per_run_id_2nd = $log->getLogUniqueId(); $per_run_id_2nd = $log->getLogUniqueId();
$this->assertMatchesRegularExpression( $this->assertMatchesRegularExpression(
"/^\d{4}-\d{2}-\d{2}_\d{6}\.U_[a-z0-9]{8}$/", "/^\d{4}-\d{2}-\d{2}_\d{6}_U_[a-z0-9]{8}$/",
$per_run_id_2nd, $per_run_id_2nd,
'assert per log run id 2nd' 'assert per log run id 2nd'
); );
@@ -889,13 +824,13 @@ final class CoreLibsLoggingLoggingTest extends TestCase
$this->assertTrue($log_ok, 'assert ::log (debug) OK'); $this->assertTrue($log_ok, 'assert ::log (debug) OK');
$this->assertEquals( $this->assertEquals(
$log->getLogFile(), $log->getLogFile(),
$log->getLogFileId() . '.DEBUG.log' $log->getLogFileId() . '_DEBUG.log'
); );
$log_ok = $log->log(Level::Info, 'INFO', group_id: 'GROUP_ID', prefix: 'PREFIX:'); $log_ok = $log->log(Level::Info, 'INFO', group_id: 'GROUP_ID', prefix: 'PREFIX:');
$this->assertTrue($log_ok, 'assert ::log (info) OK'); $this->assertTrue($log_ok, 'assert ::log (info) OK');
$this->assertEquals( $this->assertEquals(
$log->getLogFile(), $log->getLogFile(),
$log->getLogFileId() . '.INFO.log' $log->getLogFileId() . '_INFO.log'
); );
} }

View File

@@ -1,838 +0,0 @@
<?php
declare(strict_types=1);
namespace tests;
use PHPUnit\Framework\TestCase;
use CoreLibs\Security\CreateKey;
use CoreLibs\Security\AsymmetricAnonymousEncryption;
/**
* Test class for Security\AsymmetricAnonymousEncryption and Security\CreateKey
* @coversDefaultClass \CoreLibs\Security\AsymmetricAnonymousEncryption
* @testdox \CoreLibs\Security\AsymmetricAnonymousEncryption method tests
*/
final class CoreLibsSecurityAsymmetricAnonymousEncryptionTest extends TestCase
{
// MARK: key set and compare
/**
* Undocumented function
*
* @covers ::getKeyPair
* @covers ::compareKeyPair
* @covers ::getPublicKey
* @covers ::comparePublicKey
* @testdox Check if init class set key pair matches to created key pair and public key
*
* @return void
*/
public function testKeyPairInitGetCompare(): void
{
$key_pair = CreateKey::createKeyPair();
$public_key = CreateKey::getPublicKey($key_pair);
$crypt = new AsymmetricAnonymousEncryption($key_pair);
$this->assertTrue(
$crypt->compareKeyPair($key_pair),
'set key pair not equal to original key pair'
);
$this->assertTrue(
$crypt->comparePublicKey($public_key),
'automatic set public key not equal to original public key'
);
$this->assertEquals(
$key_pair,
$crypt->getKeyPair(),
'set key pair returned not equal to original key pair'
);
$this->assertEquals(
$public_key,
$crypt->getPublicKey(),
'automatic set public key returned not equal to original public key'
);
}
/**
* Undocumented function
*
* @covers ::getKeyPair
* @covers ::compareKeyPair
* @covers ::getPublicKey
* @covers ::comparePublicKey
* @testdox Check if init class set key pair and public key matches to created key pair and public key
*
* @return void
*/
public function testKeyPairPublicKeyInitGetCompare(): void
{
$key_pair = CreateKey::createKeyPair();
$public_key = CreateKey::getPublicKey($key_pair);
$crypt = new AsymmetricAnonymousEncryption($key_pair, $public_key);
$this->assertTrue(
$crypt->compareKeyPair($key_pair),
'set key pair not equal to original key pair'
);
$this->assertTrue(
$crypt->comparePublicKey($public_key),
'set public key not equal to original public key'
);
$this->assertEquals(
$key_pair,
$crypt->getKeyPair(),
'set key pair returned not equal to original key pair'
);
$this->assertEquals(
$public_key,
$crypt->getPublicKey(),
'set public key returned not equal to original public key'
);
}
/**
* Undocumented function
*
* @covers ::getKeyPair
* @covers ::getPublicKey
* @covers ::comparePublicKey
* @testdox Check if init class set public key matches to created public key
*
* @return void
*/
public function testPublicKeyInitGetCompare(): void
{
$key_pair = CreateKey::createKeyPair();
$public_key = CreateKey::getPublicKey($key_pair);
$crypt = new AsymmetricAnonymousEncryption(public_key:$public_key);
$this->assertTrue(
$crypt->comparePublicKey($public_key),
'set public key not equal to original public key'
);
$this->assertEquals(
null,
$crypt->getKeyPair(),
'unset set key pair returned not equal to original key pair'
);
$this->assertEquals(
$public_key,
$crypt->getPublicKey(),
'set public key returned not equal to original public key'
);
}
/**
* Undocumented function
*
* @covers ::setKeyPair
* @covers ::getKeyPair
* @covers ::compareKeyPair
* @covers ::getPublicKey
* @covers ::comparePublicKey
* @testdox Check if set key pair after class init matches to created key pair and public key
*
* @return void
*/
public function testKeyPairSetGetCompare(): void
{
$key_pair = CreateKey::createKeyPair();
$public_key = CreateKey::getPublicKey($key_pair);
$crypt = new AsymmetricAnonymousEncryption();
$crypt->setKeyPair($key_pair);
$this->assertTrue(
$crypt->compareKeyPair($key_pair),
'post class init set key pair not equal to original key pair'
);
$this->assertTrue(
$crypt->comparePublicKey($public_key),
'post class init automatic set public key not equal to original public key'
);
$this->assertEquals(
$key_pair,
$crypt->getKeyPair(),
'post class init set key pair returned not equal to original key pair'
);
$this->assertEquals(
$public_key,
$crypt->getPublicKey(),
'post class init automatic set public key returned not equal to original public key'
);
}
/**
* Undocumented function
*
* @covers ::setKeyPair
* @covers ::setPublicKey
* @covers ::getKeyPair
* @covers ::compareKeyPair
* @covers ::getPublicKey
* @covers ::comparePublicKey
* @testdox Check if set key pair after class init matches to created key pair and public key
*
* @return void
*/
public function testKeyPairPublicKeySetGetCompare(): void
{
$key_pair = CreateKey::createKeyPair();
$public_key = CreateKey::getPublicKey($key_pair);
$crypt = new AsymmetricAnonymousEncryption();
$crypt->setKeyPair($key_pair);
$crypt->setPublicKey($public_key);
$this->assertTrue(
$crypt->compareKeyPair($key_pair),
'post class init set key pair not equal to original key pair'
);
$this->assertTrue(
$crypt->comparePublicKey($public_key),
'post class init set public key not equal to original public key'
);
$this->assertEquals(
$key_pair,
$crypt->getKeyPair(),
'post class init set key pair returned not equal to original key pair'
);
$this->assertEquals(
$public_key,
$crypt->getPublicKey(),
'post class init set public key returned not equal to original public key'
);
}
/**
* Undocumented function
*
* @covers ::setPublicKey
* @covers ::getKeyPair
* @covers ::compareKeyPair
* @covers ::getPublicKey
* @covers ::comparePublicKey
* @testdox Check if set key pair after class init matches to created key pair and public key
*
* @return void
*/
public function testPublicKeySetGetCompare(): void
{
$key_pair = CreateKey::createKeyPair();
$public_key = CreateKey::getPublicKey($key_pair);
$crypt = new AsymmetricAnonymousEncryption();
$crypt->setPublicKey($public_key);
$this->assertTrue(
$crypt->comparePublicKey($public_key),
'post class init set public key not equal to original public key'
);
$this->assertEquals(
null,
$crypt->getKeyPair(),
'post class init unset key pair returned not equal to original key pair'
);
$this->assertEquals(
$public_key,
$crypt->getPublicKey(),
'post class init set public key returned not equal to original public key'
);
}
/**
* Undocumented function
*
* @testdox Check different key pair and public key set
*
* @return void
*/
public function testDifferentSetKeyPairPublicKey()
{
$key_pair = CreateKey::createKeyPair();
$public_key = CreateKey::getPublicKey($key_pair);
$key_pair_2 = CreateKey::createKeyPair();
$public_key_2 = CreateKey::getPublicKey($key_pair_2);
$crypt = new AsymmetricAnonymousEncryption($key_pair, $public_key_2);
$this->assertTrue(
$crypt->compareKeyPair($key_pair),
'key pair set matches key pair created'
);
$this->assertTrue(
$crypt->comparePublicKey($public_key_2),
'alternate public key set matches alternate public key created'
);
$this->assertFalse(
$crypt->comparePublicKey($public_key),
'alternate public key set does not match key pair public key'
);
}
/**
* Undocumented function
*
* @testdox Check if new set privat key does not overwrite set public key
*
* @return void
*/
public function testUpdateKeyPairNotUpdatePublicKey(): void
{
$key_pair = CreateKey::createKeyPair();
$public_key = CreateKey::getPublicKey($key_pair);
$crypt = new AsymmetricAnonymousEncryption($key_pair);
$this->assertTrue(
$crypt->compareKeyPair($key_pair),
'set key pair not equal to original key pair'
);
$this->assertTrue(
$crypt->comparePublicKey($public_key),
'set public key not equal to original public key'
);
$key_pair_2 = CreateKey::createKeyPair();
$public_key_2 = CreateKey::getPublicKey($key_pair_2);
$crypt->setKeyPair($key_pair_2);
$this->assertTrue(
$crypt->compareKeyPair($key_pair_2),
'new set key pair not equal to original new key pair'
);
$this->assertTrue(
$crypt->comparePublicKey($public_key),
'original set public key not equal to original public key'
);
$this->assertFalse(
$crypt->comparePublicKey($public_key_2),
'new public key equal to original public key'
);
}
// MARK: empty encrytped string
/**
* Undocumented function
*
* @covers ::decryptKey
* @covers ::decrypt
* @testdox Test empty encrypted string to decrypt
*
* @return void
*/
public function testEmptyDecryptionString(): void
{
$this->expectExceptionMessage('Encrypted string cannot be empty');
AsymmetricAnonymousEncryption::decryptKey('', CreateKey::generateRandomKey());
}
// MARK: encrypt/decrypt
/**
* Undocumented function
*
* @return array
*/
public function providerEncryptDecryptSuccess(): array
{
return [
'valid string' => [
'input' => 'I am a secret',
'expected' => 'I am a secret',
],
];
}
/**
* test encrypt/decrypt produce correct output
*
* @covers ::generateRandomKey
* @covers ::encrypt
* @covers ::decrypt
* @dataProvider providerEncryptDecryptSuccess
* @testdox encrypt/decrypt $input must be $expected [$_dataName]
*
* @param string $input
* @param string $expected
* @return void
*/
public function testEncryptDecryptSuccess(string $input, string $expected): void
{
$key_pair = CreateKey::createKeyPair();
$public_key = CreateKey::getPublicKey($key_pair);
// test class
$crypt = new AsymmetricAnonymousEncryption($key_pair);
$encrypted = $crypt->encrypt($input);
$decrypted = $crypt->decrypt($encrypted);
$this->assertEquals(
$expected,
$decrypted,
'Class call',
);
$crypt = new AsymmetricAnonymousEncryption($key_pair, $public_key);
$encrypted = $crypt->encrypt($input);
$decrypted = $crypt->decrypt($encrypted);
$this->assertEquals(
$expected,
$decrypted,
'Class call botjh set',
);
}
/**
* test encrypt/decrypt produce correct output
*
* @covers ::generateRandomKey
* @covers ::encrypt
* @covers ::decrypt
* @dataProvider providerEncryptDecryptSuccess
* @testdox encrypt/decrypt indirect $input must be $expected [$_dataName]
*
* @param string $input
* @param string $expected
* @return void
*/
public function testEncryptDecryptSuccessIndirect(string $input, string $expected): void
{
$key_pair = CreateKey::createKeyPair();
$public_key = CreateKey::getPublicKey($key_pair);
// test indirect
$encrypted = AsymmetricAnonymousEncryption::getInstance(public_key:$public_key)->encrypt($input);
$decrypted = AsymmetricAnonymousEncryption::getInstance($key_pair)->decrypt($encrypted);
$this->assertEquals(
$expected,
$decrypted,
'Class Instance call',
);
}
/**
* test encrypt/decrypt produce correct output
*
* @covers ::generateRandomKey
* @covers ::encrypt
* @covers ::decrypt
* @dataProvider providerEncryptDecryptSuccess
* @testdox encrypt/decrypt indirect with public key $input must be $expected [$_dataName]
*
* @param string $input
* @param string $expected
* @return void
*/
public function testEncryptDecryptSuccessIndirectPublicKey(string $input, string $expected): void
{
$key_pair = CreateKey::createKeyPair();
$public_key = CreateKey::getPublicKey($key_pair);
// test indirect
$encrypted = AsymmetricAnonymousEncryption::getInstance(public_key:$public_key)->encrypt($input);
$decrypted = AsymmetricAnonymousEncryption::getInstance($key_pair)->decrypt($encrypted);
$this->assertEquals(
$expected,
$decrypted,
'Class Instance call public key',
);
}
/**
* test encrypt/decrypt produce correct output
*
* @covers ::generateRandomKey
* @covers ::encrypt
* @covers ::decrypt
* @dataProvider providerEncryptDecryptSuccess
* @testdox encrypt/decrypt static $input must be $expected [$_dataName]
*
* @param string $input
* @param string $expected
* @return void
*/
public function testEncryptDecryptSuccessStatic(string $input, string $expected): void
{
$key_pair = CreateKey::createKeyPair();
$public_key = CreateKey::getPublicKey($key_pair);
// test static
$encrypted = AsymmetricAnonymousEncryption::encryptKey($input, $public_key);
$decrypted = AsymmetricAnonymousEncryption::decryptKey($encrypted, $key_pair);
$this->assertEquals(
$expected,
$decrypted,
'Static call',
);
}
// MARK: invalid decrypt key
/**
* Undocumented function
*
* @return array
*/
public function providerEncryptFailed(): array
{
return [
'wrong decryption key' => [
'input' => 'I am a secret',
'excpetion_message' => 'Invalid key pair'
],
];
}
/**
* Test decryption with wrong key
*
* @covers ::generateRandomKey
* @covers ::encrypt
* @covers ::decrypt
* @dataProvider providerEncryptFailed
* @testdox decrypt with wrong key $input throws $exception_message [$_dataName]
*
* @param string $input
* @param string $exception_message
* @return void
*/
public function testEncryptFailed(string $input, string $exception_message): void
{
$key_pair = CreateKey::createKeyPair();
$public_key = CreateKey::getPublicKey($key_pair);
$wrong_key_pair = CreateKey::createKeyPair();
// wrong key in class call
$crypt = new AsymmetricAnonymousEncryption(public_key:$public_key);
$encrypted = $crypt->encrypt($input);
$this->expectExceptionMessage($exception_message);
$crypt->setKeyPair($wrong_key_pair);
$crypt->decrypt($encrypted);
}
/**
* Test decryption with wrong key
*
* @covers ::generateRandomKey
* @covers ::encrypt
* @covers ::decrypt
* @dataProvider providerEncryptFailed
* @testdox decrypt indirect with wrong key $input throws $exception_message [$_dataName]
*
* @param string $input
* @param string $exception_message
* @return void
*/
public function testEncryptFailedIndirect(string $input, string $exception_message): void
{
$key_pair = CreateKey::createKeyPair();
$public_key = CreateKey::getPublicKey($key_pair);
$wrong_key_pair = CreateKey::createKeyPair();
// class instance
$encrypted = AsymmetricAnonymousEncryption::getInstance(public_key:$public_key)->encrypt($input);
$this->expectExceptionMessage($exception_message);
AsymmetricAnonymousEncryption::getInstance($wrong_key_pair)->decrypt($encrypted);
}
/**
* Test decryption with wrong key
*
* @covers ::generateRandomKey
* @covers ::encrypt
* @covers ::decrypt
* @dataProvider providerEncryptFailed
* @testdox decrypt static with wrong key $input throws $exception_message [$_dataName]
*
* @param string $input
* @param string $exception_message
* @return void
*/
public function testEncryptFailedStatic(string $input, string $exception_message): void
{
$key_pair = CreateKey::createKeyPair();
$public_key = CreateKey::getPublicKey($key_pair);
$wrong_key_pair = CreateKey::createKeyPair();
// class static
$encrypted = AsymmetricAnonymousEncryption::encryptKey($input, $public_key);
$this->expectExceptionMessage($exception_message);
AsymmetricAnonymousEncryption::decryptKey($encrypted, $wrong_key_pair);
}
// MARK: invalid key pair
/**
* Undocumented function
*
* @return array
*/
public function providerWrongKeyPair(): array
{
return [
'not hex key pair' => [
'key_pair' => 'not_a_hex_key_pair',
'exception_message' => 'Invalid hex key pair'
],
'too short hex key pair' => [
'key_pair' => '1cabd5cba9e042f12522f4ff2de5c31d233b',
'excpetion_message' => 'Key pair is not the correct size (must be '
],
'empty key pair' => [
'key_pair' => '',
'excpetion_message' => 'Key pair cannot be empty'
]
];
}
/**
* test invalid key provided to decrypt or encrypt
*
* @covers ::encrypt
* @covers ::decrypt
* @dataProvider providerWrongKeyPair
* @testdox wrong key pair $key_pair throws $exception_message [$_dataName]
*
* @param string $key_pair
* @param string $exception_message
* @return void
*/
public function testWrongKeyPair(string $key_pair, string $exception_message): void
{
$enc_key_pair = CreateKey::createKeyPair();
// class
$this->expectExceptionMessage($exception_message);
$crypt = new AsymmetricAnonymousEncryption($key_pair);
$this->expectExceptionMessage($exception_message);
$crypt->encrypt('test');
$crypt->setKeyPair($enc_key_pair);
$encrypted = $crypt->encrypt('test');
$this->expectExceptionMessage($exception_message);
$crypt->setKeyPair($key_pair);
$crypt->decrypt($encrypted);
}
/**
* test invalid key provided to decrypt or encrypt
*
* @covers ::encrypt
* @covers ::decrypt
* @dataProvider providerWrongKeyPair
* @testdox wrong key pair indirect $key_pair throws $exception_message [$_dataName]
*
* @param string $key_pair
* @param string $exception_message
* @return void
*/
public function testWrongKeyPairIndirect(string $key_pair, string $exception_message): void
{
$enc_key_pair = CreateKey::createKeyPair();
// set valid encryption
$encrypted = AsymmetricAnonymousEncryption::getInstance($enc_key_pair)->encrypt('test');
$this->expectExceptionMessage($exception_message);
AsymmetricAnonymousEncryption::getInstance($key_pair)->decrypt($encrypted);
}
/**
* test invalid key provided to decrypt or encrypt
*
* @covers ::encrypt
* @covers ::decrypt
* @dataProvider providerWrongKeyPair
* @testdox wrong key pair static $key_pair throws $exception_message [$_dataName]
*
* @param string $key_pair
* @param string $exception_message
* @return void
*/
public function testWrongKeyPairStatic(string $key_pair, string $exception_message): void
{
$enc_key_pair = CreateKey::createKeyPair();
// set valid encryption
$encrypted = AsymmetricAnonymousEncryption::encryptKey('test', CreateKey::getPublicKey($enc_key_pair));
$this->expectExceptionMessage($exception_message);
AsymmetricAnonymousEncryption::decryptKey($encrypted, $key_pair);
}
// MARK: invalid public key
/**
* Undocumented function
*
* @return array
*/
public function providerWrongPublicKey(): array
{
return [
'not hex public key' => [
'public_key' => 'not_a_hex_public_key',
'exception_message' => 'Invalid hex public key'
],
'too short hex public key' => [
'public_key' => '1cabd5cba9e042f12522f4ff2de5c31d233b',
'excpetion_message' => 'Public key is not the correct size (must be '
],
'empty public key' => [
'public_key' => '',
'excpetion_message' => 'Public key cannot be empty'
]
];
}
/**
* test invalid key provided to decrypt or encrypt
*
* @covers ::encrypt
* @covers ::decrypt
* @dataProvider providerWrongPublicKey
* @testdox wrong public key $public_key throws $exception_message [$_dataName]
*
* @param string $public_key
* @param string $exception_message
* @return void
*/
public function testWrongPublicKey(string $public_key, string $exception_message): void
{
$enc_key_pair = CreateKey::createKeyPair();
// $enc_public_key = CreateKey::getPublicKey($enc_key_pair);
// class
$this->expectExceptionMessage($exception_message);
$crypt = new AsymmetricAnonymousEncryption(public_key:$public_key);
$this->expectExceptionMessage($exception_message);
$crypt->decrypt('test');
$crypt->setKeyPair($enc_key_pair);
$encrypted = $crypt->encrypt('test');
$this->expectExceptionMessage($exception_message);
$crypt->setPublicKey($public_key);
$crypt->decrypt($encrypted);
}
/**
* test invalid key provided to decrypt or encrypt
*
* @covers ::encrypt
* @covers ::decrypt
* @dataProvider providerWrongPublicKey
* @testdox wrong public key indirect $key throws $exception_message [$_dataName]
*
* @param string $key
* @param string $exception_message
* @return void
*/
public function testWrongPublicKeyIndirect(string $key, string $exception_message): void
{
$enc_key = CreateKey::createKeyPair();
// class instance
$this->expectExceptionMessage($exception_message);
AsymmetricAnonymousEncryption::getInstance(public_key:$key)->encrypt('test');
// we must encrypt valid thing first so we can fail with the wrong key
$encrypted = AsymmetricAnonymousEncryption::getInstance($enc_key)->encrypt('test');
// $this->expectExceptionMessage($exception_message);
AsymmetricAnonymousEncryption::getInstance($key)->decrypt($encrypted);
}
/**
* test invalid key provided to decrypt or encrypt
*
* @covers ::encrypt
* @covers ::decrypt
* @dataProvider providerWrongPublicKey
* @testdox wrong public key static $key throws $exception_message [$_dataName]
*
* @param string $key
* @param string $exception_message
* @return void
*/
public function testWrongPublicKeyStatic(string $key, string $exception_message): void
{
$enc_key = CreateKey::createKeyPair();
// class static
$this->expectExceptionMessage($exception_message);
AsymmetricAnonymousEncryption::encryptKey('test', $key);
// we must encrypt valid thing first so we can fail with the wrong key
$encrypted = AsymmetricAnonymousEncryption::encryptKey('test', $enc_key);
$this->expectExceptionMessage($exception_message);
AsymmetricAnonymousEncryption::decryptKey($encrypted, $key);
}
// MARK: wrong cipher text
/**
* Undocumented function
*
* @return array
*/
public function providerWrongCiphertext(): array
{
return [
'invalid cipher text' => [
'input' => 'short',
'exception_message' => 'base642bin failed: '
],
'cannot decrypt' => [
// phpcs:disable Generic.Files.LineLength
'input' => 'Um8tBGiVfFAOg2YoUgA5fTqK1wXPB1S7uxhPNE1lqDxgntkEhYJDOmjXa0DMpBlYHjab6sC4mgzwZSzGCUnXDAgsHckwYwfAzs/r',
// phpcs:enable Generic.Files.LineLength
'exception_message' => 'Invalid key pair'
],
'invalid text' => [
'input' => 'U29tZSB0ZXh0IGhlcmU=',
'exception_message' => 'Invalid key pair'
]
];
}
/**
* Undocumented function
*
* @covers ::decrypt
* @dataProvider providerWrongCiphertext
* @testdox too short ciphertext $input throws $exception_message [$_dataName]
*
* @param string $input
* @param string $exception_message
* @return void
*/
public function testWrongCiphertext(string $input, string $exception_message): void
{
$key = CreateKey::createKeyPair();
// class
$crypt = new AsymmetricAnonymousEncryption($key);
$this->expectExceptionMessage($exception_message);
$crypt->decrypt($input);
}
/**
* Undocumented function
*
* @covers ::decryptKey
* @dataProvider providerWrongCiphertext
* @testdox too short ciphertext indirect $input throws $exception_message [$_dataName]
*
* @param string $input
* @param string $exception_message
* @return void
*/
public function testWrongCiphertextIndirect(string $input, string $exception_message): void
{
$key = CreateKey::createKeyPair();
// class instance
$this->expectExceptionMessage($exception_message);
AsymmetricAnonymousEncryption::getInstance($key)->decrypt($input);
// class static
$this->expectExceptionMessage($exception_message);
AsymmetricAnonymousEncryption::decryptKey($input, $key);
}
/**
* Undocumented function
*
* @covers ::decryptKey
* @dataProvider providerWrongCiphertext
* @testdox too short ciphertext static $input throws $exception_message [$_dataName]
*
* @param string $input
* @param string $exception_message
* @return void
*/
public function testWrongCiphertextStatic(string $input, string $exception_message): void
{
$key = CreateKey::createKeyPair();
// class static
$this->expectExceptionMessage($exception_message);
AsymmetricAnonymousEncryption::decryptKey($input, $key);
}
}
// __END__

View File

@@ -13,11 +13,6 @@ use PHPUnit\Framework\TestCase;
*/ */
final class CoreLibsSecurityPasswordTest extends TestCase final class CoreLibsSecurityPasswordTest extends TestCase
{ {
/**
* Undocumented function
*
* @return array
*/
public function passwordProvider(): array public function passwordProvider(): array
{ {
return [ return [
@@ -26,11 +21,6 @@ final class CoreLibsSecurityPasswordTest extends TestCase
]; ];
} }
/**
* Note: we need different hash types for PHP versions
*
* @return array
*/
public function passwordRehashProvider(): array public function passwordRehashProvider(): array
{ {
return [ return [
@@ -73,10 +63,6 @@ final class CoreLibsSecurityPasswordTest extends TestCase
*/ */
public function testPasswordRehashCheck(string $input, bool $expected): void public function testPasswordRehashCheck(string $input, bool $expected): void
{ {
// in PHP 8.4 the length is $12
if (PHP_VERSION_ID > 80400) {
$input = str_replace('$2y$10$', '$2y$12$', $input);
}
$this->assertEquals( $this->assertEquals(
$expected, $expected,
\CoreLibs\Security\Password::passwordRehashCheck($input) \CoreLibs\Security\Password::passwordRehashCheck($input)

View File

@@ -15,77 +15,6 @@ use CoreLibs\Security\SymmetricEncryption;
*/ */
final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
{ {
// MARK: key set compare
/**
* Undocumented function
*
* @covers ::compareKey
* @covers ::getKey
* @testdox Check if init class set key matches to created key
*
* @return void
*/
public function testKeyInitGetCompare(): void
{
$key = CreateKey::generateRandomKey();
$crypt = new SymmetricEncryption($key);
$this->assertTrue(
$crypt->compareKey($key),
'set key not equal to original key'
);
$this->assertEquals(
$key,
$crypt->getKey(),
'set key returned not equal to original key'
);
}
/**
* Undocumented function
*
* @covers ::setKey
* @covers ::compareKey
* @covers ::getKey
* @testdox Check if set key after class init matches to created key
*
* @return void
*/
public function testKeySetGetCompare(): void
{
$key = CreateKey::generateRandomKey();
$crypt = new SymmetricEncryption();
$crypt->setKey($key);
$this->assertTrue(
$crypt->compareKey($key),
'set key not equal to original key'
);
$this->assertEquals(
$key,
$crypt->getKey(),
'set key returned not equal to original key'
);
}
// MARK: empty encrypted string
/**
* Undocumented function
*
* @covers ::decryptKey
* @covers ::decrypt
* @testdox Test empty encrypted string to decrypt
*
* @return void
*/
public function testEmptyDecryptionString(): void
{
$this->expectExceptionMessage('Encrypted string cannot be empty');
SymmetricEncryption::decryptKey('', CreateKey::generateRandomKey());
}
// MARK: encrypt/decrypt compare
/** /**
* Undocumented function * Undocumented function
* *
@@ -127,24 +56,7 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
$decrypted, $decrypted,
'Class call', 'Class call',
); );
}
/**
* test encrypt/decrypt produce correct output
*
* @covers ::generateRandomKey
* @covers ::encrypt
* @covers ::decrypt
* @dataProvider providerEncryptDecryptSuccess
* @testdox encrypt/decrypt indirect $input must be $expected [$_dataName]
*
* @param string $input
* @param string $expected
* @return void
*/
public function testEncryptDecryptSuccessIndirect(string $input, string $expected): void
{
$key = CreateKey::generateRandomKey();
// test indirect // test indirect
$encrypted = SymmetricEncryption::getInstance($key)->encrypt($input); $encrypted = SymmetricEncryption::getInstance($key)->encrypt($input);
$decrypted = SymmetricEncryption::getInstance($key)->decrypt($encrypted); $decrypted = SymmetricEncryption::getInstance($key)->decrypt($encrypted);
@@ -153,24 +65,7 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
$decrypted, $decrypted,
'Class Instance call', 'Class Instance call',
); );
}
/**
* test encrypt/decrypt produce correct output
*
* @covers ::generateRandomKey
* @covers ::encryptKey
* @covers ::decryptKey
* @dataProvider providerEncryptDecryptSuccess
* @testdox encrypt/decrypt static $input must be $expected [$_dataName]
*
* @param string $input
* @param string $expected
* @return void
*/
public function testEncryptDecryptSuccessStatic(string $input, string $expected): void
{
$key = CreateKey::generateRandomKey();
// test static // test static
$encrypted = SymmetricEncryption::encryptKey($input, $key); $encrypted = SymmetricEncryption::encryptKey($input, $key);
$decrypted = SymmetricEncryption::decryptKey($encrypted, $key); $decrypted = SymmetricEncryption::decryptKey($encrypted, $key);
@@ -182,8 +77,6 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
); );
} }
// MARK: invalid key
/** /**
* Undocumented function * Undocumented function
* *
@@ -221,51 +114,13 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
$crypt = new SymmetricEncryption($key); $crypt = new SymmetricEncryption($key);
$encrypted = $crypt->encrypt($input); $encrypted = $crypt->encrypt($input);
$this->expectExceptionMessage($exception_message); $this->expectExceptionMessage($exception_message);
$crypt->setKey($wrong_key); $crypt->setKey($key);
$crypt->decrypt($encrypted); $crypt->decrypt($encrypted);
}
/**
* Test decryption with wrong key
*
* @covers ::generateRandomKey
* @covers ::encrypt
* @covers ::decrypt
* @dataProvider providerEncryptFailed
* @testdox decrypt indirect with wrong key $input throws $exception_message [$_dataName]
*
* @param string $input
* @param string $exception_message
* @return void
*/
public function testEncryptFailedIndirect(string $input, string $exception_message): void
{
$key = CreateKey::generateRandomKey();
$wrong_key = CreateKey::generateRandomKey();
// class instance // class instance
$encrypted = SymmetricEncryption::getInstance($key)->encrypt($input); $encrypted = SymmetricEncryption::getInstance($key)->encrypt($input);
$this->expectExceptionMessage($exception_message); $this->expectExceptionMessage($exception_message);
SymmetricEncryption::getInstance($wrong_key)->decrypt($encrypted); SymmetricEncryption::getInstance($wrong_key)->decrypt($encrypted);
}
/**
* Test decryption with wrong key
*
* @covers ::generateRandomKey
* @covers ::encryptKey
* @covers ::decryptKey
* @dataProvider providerEncryptFailed
* @testdox decrypt static with wrong key $input throws $exception_message [$_dataName]
*
* @param string $input
* @param string $exception_message
* @return void
*/
public function testEncryptFailedStatic(string $input, string $exception_message): void
{
$key = CreateKey::generateRandomKey();
$wrong_key = CreateKey::generateRandomKey();
// class static // class static
$encrypted = SymmetricEncryption::encryptKey($input, $key); $encrypted = SymmetricEncryption::encryptKey($input, $key);
@@ -273,8 +128,6 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
SymmetricEncryption::decryptKey($encrypted, $wrong_key); SymmetricEncryption::decryptKey($encrypted, $wrong_key);
} }
// MARK: wrong key
/** /**
* Undocumented function * Undocumented function
* *
@@ -291,10 +144,6 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
'key' => '1cabd5cba9e042f12522f4ff2de5c31d233b', 'key' => '1cabd5cba9e042f12522f4ff2de5c31d233b',
'excpetion_message' => 'Key is not the correct size (must be ' 'excpetion_message' => 'Key is not the correct size (must be '
], ],
'empty key' => [
'key' => '',
'excpetion_message' => 'Key cannot be empty'
]
]; ];
} }
@@ -315,7 +164,6 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
$enc_key = CreateKey::generateRandomKey(); $enc_key = CreateKey::generateRandomKey();
// class // class
$this->expectExceptionMessage($exception_message);
$crypt = new SymmetricEncryption($key); $crypt = new SymmetricEncryption($key);
$this->expectExceptionMessage($exception_message); $this->expectExceptionMessage($exception_message);
$crypt->encrypt('test'); $crypt->encrypt('test');
@@ -324,23 +172,6 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
$this->expectExceptionMessage($exception_message); $this->expectExceptionMessage($exception_message);
$crypt->setKey($key); $crypt->setKey($key);
$crypt->decrypt($encrypted); $crypt->decrypt($encrypted);
}
/**
* test invalid key provided to decrypt or encrypt
*
* @covers ::encrypt
* @covers ::decrypt
* @dataProvider providerWrongKey
* @testdox wrong key indirect $key throws $exception_message [$_dataName]
*
* @param string $key
* @param string $exception_message
* @return void
*/
public function testWrongKeyIndirect(string $key, string $exception_message): void
{
$enc_key = CreateKey::generateRandomKey();
// class instance // class instance
$this->expectExceptionMessage($exception_message); $this->expectExceptionMessage($exception_message);
@@ -349,23 +180,6 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
$encrypted = SymmetricEncryption::getInstance($enc_key)->encrypt('test'); $encrypted = SymmetricEncryption::getInstance($enc_key)->encrypt('test');
$this->expectExceptionMessage($exception_message); $this->expectExceptionMessage($exception_message);
SymmetricEncryption::getInstance($key)->decrypt($encrypted); SymmetricEncryption::getInstance($key)->decrypt($encrypted);
}
/**
* test invalid key provided to decrypt or encrypt
*
* @covers ::encryptKey
* @covers ::decryptKey
* @dataProvider providerWrongKey
* @testdox wrong key static $key throws $exception_message [$_dataName]
*
* @param string $key
* @param string $exception_message
* @return void
*/
public function testWrongKeyStatic(string $key, string $exception_message): void
{
$enc_key = CreateKey::generateRandomKey();
// class static // class static
$this->expectExceptionMessage($exception_message); $this->expectExceptionMessage($exception_message);
@@ -376,8 +190,6 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
SymmetricEncryption::decryptKey($encrypted, $key); SymmetricEncryption::decryptKey($encrypted, $key);
} }
// MARK: wrong input
/** /**
* Undocumented function * Undocumented function
* *
@@ -420,49 +232,6 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
$this->expectExceptionMessage($exception_message); $this->expectExceptionMessage($exception_message);
SymmetricEncryption::decryptKey($input, $key); SymmetricEncryption::decryptKey($input, $key);
} }
/**
* Undocumented function
*
* @covers ::decryptKey
* @dataProvider providerWrongCiphertext
* @testdox too short ciphertext indirect $input throws $exception_message [$_dataName]
*
* @param string $input
* @param string $exception_message
* @return void
*/
public function testWrongCiphertextIndirect(string $input, string $exception_message): void
{
$key = CreateKey::generateRandomKey();
// class instance
$this->expectExceptionMessage($exception_message);
SymmetricEncryption::getInstance($key)->decrypt($input);
// class static
$this->expectExceptionMessage($exception_message);
SymmetricEncryption::decryptKey($input, $key);
}
/**
* Undocumented function
*
* @covers ::decryptKey
* @dataProvider providerWrongCiphertext
* @testdox too short ciphertext static $input throws $exception_message [$_dataName]
*
* @param string $input
* @param string $exception_message
* @return void
*/
public function testWrongCiphertextStatic(string $input, string $exception_message): void
{
$key = CreateKey::generateRandomKey();
// class static
$this->expectExceptionMessage($exception_message);
SymmetricEncryption::decryptKey($input, $key);
}
} }
// __END__ // __END__

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
<?php <?php
$set = 0; $set = 0;
foreach (['/../../www', '/../www', '/../../src', '/../src', '/../..', '/..'] as $src) { foreach (['/../../www', '/../www', '/../..', '/..', '/../../src', '/../src'] as $src) {
if (is_file(dirname(__DIR__) . $src . '/vendor/autoload.php')) { if (is_file(dirname(__DIR__) . $src . '/vendor/autoload.php')) {
require dirname(__DIR__) . $src . '/vendor/autoload.php'; require dirname(__DIR__) . $src . '/vendor/autoload.php';
$set = 1; $set = 1;

View File

@@ -1,36 +0,0 @@
-- 20241203: update edit tables
ALTER TABLE edit_generic ADD cuuid UUID DEFAULT gen_random_uuid();
ALTER TABLE edit_log ADD eucuid VARCHAR;
ALTER TABLE edit_log ADD eucuuid VARCHAR;
ALTER TABLE edit_log ADD action_sub_id VARCHAR;
ALTER TABLE edit_log ADD http_data JSONB;
ALTER TABLE edit_log ADD ip_address JSONB;
ALTER TABLE edit_log ADD action_data JSONB;
ALTER TABLE edit_log ADD request_scheme VARCHAR;
ALTER TABLE edit_user ADD force_logout INT DEFAULT 0;
COMMENT ON COLUMN edit_user.force_logout IS 'Counter for forced log out, if this one is higher than the session set one the session gets terminated';
ALTER TABLE edit_user ADD last_login TIMESTAMP WITHOUT TIME ZONE;
COMMENT ON COLUMN edit_user.last_login IS 'Last succesfull login tiemstamp';
-- update set_edit_gneric
-- adds the created or updated date tags
CREATE OR REPLACE FUNCTION set_edit_generic()
RETURNS TRIGGER AS
$$
DECLARE
random_length INT = 25; -- that should be long enough
BEGIN
IF TG_OP = 'INSERT' THEN
NEW.date_created := clock_timestamp();
NEW.cuid := random_string(random_length);
NEW.cuuid := gen_random_uuid();
ELSIF TG_OP = 'UPDATE' THEN
NEW.date_updated := clock_timestamp();
END IF;
RETURN NEW;
END;
$$
LANGUAGE 'plpgsql';
-- END --

View File

@@ -114,13 +114,3 @@ Add `.libs` to the master .gitingore
### Update phpunit ### Update phpunit
On a version update the old phpunit folder in .libs has to be removed and the new version extracted again On a version update the old phpunit folder in .libs has to be removed and the new version extracted again
## Javascript
The original edit.js javascript functions are now in utils.js or utils.min.js.
The development for those files is located in a different repository
General: <https://[service]/CodeBlocks/JavaScript.utils>
Org: <https://[serverice]/[org]/Code-Blocks.JavaScript.utils>

View File

@@ -1,11 +0,0 @@
# Security Policy
This software follows the [Semver 2.0 scheme](https://semver.org/).
## Supported Versions
Only the latest version is supported
## Reporting a Vulnerability
Open a ticket to report a secuirty problem

View File

@@ -2,18 +2,16 @@
"name": "egrajp/development-corelibs-dev", "name": "egrajp/development-corelibs-dev",
"version": "dev-master", "version": "dev-master",
"description": "CoreLibs: Development package", "description": "CoreLibs: Development package",
"keywords": ["corelib", "logging", "database", "templating", "tools"],
"type": "library", "type": "library",
"require": { "require": {
"php": ">=8.3" "php": ">=8.1"
}, },
"require-dev": { "require-dev": {
"phpstan/phpstan": "^2.0", "phpstan/phpstan": "^1.10",
"phpstan/phpstan-deprecation-rules": "^2.0",
"phpstan/extension-installer": "^1.4",
"phan/phan": "^5.4", "phan/phan": "^5.4",
"phpunit/phpunit": "^9", "phpstan/extension-installer": "^1.2",
"yamadashy/phpstan-friendly-formatter": "^1.1" "phpstan/phpstan-strict-rules": "^1.6",
"phpunit/phpunit": "^9"
}, },
"config": { "config": {
"allow-plugins": { "allow-plugins": {

View File

@@ -1,59 +0,0 @@
import globals from 'globals';
import pluginJs from '@eslint/js';
/*
module.exports = {
// in globals block
'extends': 'eslint:recommended',
'parserOptions': {
'ecmaVersion': 6
},
// rules copied
};
*/
/** @type {import('eslint').Linter.Config[]} */
export default [
{languageOptions: {
globals: {
...globals.browser,
...globals.jquery
}
}},
pluginJs.configs.recommended,
{
'rules': {
'indent': [
'error',
'tab',
{
'SwitchCase': 1
}
],
'linebreak-style': [
'error',
'unix'
],
// 'quotes': [
// 'error',
// 'single'
// ],
'semi': [
'error',
'always'
],
'no-console': 'off',
'no-unused-vars': [
'error', {
'vars': 'all',
'args': 'after-used',
'ignoreRestSiblings': false
}
],
// Requires eslint >= v8.14.0
'no-constant-binary-expression': 'error'
}
}
];
// __END__

View File

@@ -1,11 +1,9 @@
// https://www.typescriptlang.org/tsconfig/#compilerOptions
{ {
"compilerOptions": { "compilerOptions": {
"module": "ESNext", "module": "ESNext",
"moduleResolution": "Node", "moduleResolution": "Node",
"target": "ES2020", "target": "ES2020",
"jsx": "react", "jsx": "react",
"checkJs": true,
"allowImportingTsExtensions": true, "allowImportingTsExtensions": true,
"strictNullChecks": true, "strictNullChecks": true,
"strictFunctionTypes": true "strictFunctionTypes": true

View File

@@ -1,17 +0,0 @@
{
"name": "core-libraries",
"version": "9.26.8",
"main": "",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Clemens Schwaighofer",
"license": "",
"description": "Core Libraries",
"devDependencies": {
"@eslint/js": "^9.20.0",
"esbuild": "^0.25.0",
"eslint": "^9.20.1",
"globals": "^15.15.0"
}
}

View File

@@ -10,6 +10,5 @@ $_SERVER['HTTP_HOST'] = 'soba.tokyo.tequila.jp';
define('BASE_NAME', ''); define('BASE_NAME', '');
define('SITE_DOMAIN', ''); define('SITE_DOMAIN', '');
define('HOST_NAME', 'soba.tokyo.tequila.jp'); define('HOST_NAME', 'soba.tokyo.tequila.jp');
define('DEFAULT_ENCODING', 'en_US.UTF-8');
// __END__ // __END__

View File

@@ -1,22 +1,25 @@
# PHP Stan Config # PHP Stan Config
includes: includes:
- phpstan-conditional.php - phpstan-conditional.php
#- ./vendor/yamadashy/phpstan-friendly-formatter/extension.neon
# - phar://phpstan.phar/conf/bleedingEdge.neon
parameters: parameters:
tmpDir: %currentWorkingDirectory%/tmp/phpstan-corelibs tmpDir: %currentWorkingDirectory%/tmp/phpstan-corelibs
#errorFormat: friendly level: 9 # max is now 9
#friendly:
# lineBefore: 3
# lineAfter: 3
level: 8 # max is now 10
# strictRules:
# allRules: false
checkMissingCallableSignature: true checkMissingCallableSignature: true
treatPhpDocTypesAsCertain: false treatPhpDocTypesAsCertain: false
# phpVersion: strictRules:
# min: 80200 # PHP 8.2.0 allRules: false
# max: 80300 # PHP latest disallowedLooseComparison: false
booleansInConditions: false
uselessCast: true
requireParentConstructorCall: false
disallowedConstructs: false
overwriteVariablesWithLoop: false
closureUsesThis: false
matchingInheritedMethodNames: false
numericOperandsInArithmeticOperators: false
strictCalls: false
switchConditionsMatchingType: false
noVariableVariables: false
paths: paths:
- %currentWorkingDirectory%/www - %currentWorkingDirectory%/www
bootstrapFiles: bootstrapFiles:
@@ -46,6 +49,8 @@ parameters:
- www/log - www/log
- www/media - www/media
- www/tmp - www/tmp
# File uploader
- www/lib/FileUpload
# ignore composer # ignore composer
- www/vendor - www/vendor
# ignore errores with # ignore errores with
@@ -64,6 +69,6 @@ parameters:
# paths: # paths:
# - ... # - ...
# - ... # - ...
# - #-
# message: "#^Call to deprecated method #" # message: "#^Call to deprecated method #"
# path: www/admin/class_test*.php # path: www/admin/class_test*.php

View File

@@ -1,23 +1,8 @@
<phpunit <phpunit
cacheResultFile="/tmp/phpunit-corelibs.result.cache" cacheResultFile="/tmp/phpunit-corelibs.result.cache"
colors="true" colors="true"
verbose="false" verbose="true"
convertDeprecationsToExceptions="true" convertDeprecationsToExceptions="true"
bootstrap="4dev/tests/bootstrap.php" bootstrap="4dev/tests/bootstrap.php"
> >
<testsuites>
<testsuite name="deploy">
<directory>4dev/tests</directory>
</testsuite>
</testsuites>
<coverage processUncoveredFiles="true">
<include>
<directory suffix=".php">./www/lib/CoreLibs</directory>
</include>
</coverage>
<!-- <source>
<include>
<directory>./www/lib/CoreLibs</directory>
</include>
</source> -->
</phpunit> </phpunit>

View File

@@ -1,79 +0,0 @@
<?php // phpcs:ignore PSR1.Files.SideEffects
declare(strict_types=1);
// url requests target test
require 'config.php';
use CoreLibs\Convert\Json;
$LOG_FILE_ID = 'classTest-urlrequests-target';
$log = new CoreLibs\Logging\Logging([
'log_folder' => BASE . LOG,
'log_file_id' => $LOG_FILE_ID,
'log_per_date' => true,
]);
/**
* build return json
*
* @param array<string,mixed> $http_headers
* @param ?string $body
* @return string
*/
function buildContent(array $http_headers, ?string $body): string
{
if (is_string($body) && !empty($body)) {
$_body = Json::jsonConvertToArray($body);
if (Json::jsonGetLastError()) {
$body = [$body];
} else {
$body = $_body;
}
} elseif (is_string($body)) {
$body = [];
}
return Json::jsonConvertArrayTo([
'HEADERS' => $http_headers,
"REQUEST_TYPE" => $_SERVER['REQUEST_METHOD'],
"PARAMS" => $_GET,
"BODY" => $body,
// "STRING_BODY" => $body,
]);
}
$http_headers = array_filter($_SERVER, function ($value, $key) {
if (str_starts_with($key, 'HTTP_')) {
return true;
}
}, ARRAY_FILTER_USE_BOTH);
header("Content-Type: application/json; charset=UTF-8");
// if the header has Authorization and RunAuthTest then exit with 401
if (!empty($http_headers['HTTP_AUTHORIZATION']) && !empty($http_headers['HTTP_RUNAUTHTEST'])) {
header("HTTP/1.1 401 Unauthorized");
print buildContent($http_headers, '{"code": 401, "content": {"Error": "Not Authorized"}}');
exit(1);
}
// if server request type is get set file_get to null -> no body
if ($_SERVER['REQUEST_METHOD'] == "GET") {
$file_get = null;
} elseif (($file_get = file_get_contents('php://input')) === false) {
header("HTTP/1.1 404 Not Found");
print buildContent($http_headers, '{"code": 404, "content": {"Error": "file_get_contents failed"}}');
exit(1);
}
// str_replace('\"', '"', trim($file_get, '"'));
$log->debug('SERVER', $log->prAr($_SERVER));
$log->debug('HEADERS', $log->prAr($http_headers));
$log->debug('REQUEST TYPE', $_SERVER['REQUEST_METHOD']);
$log->debug('GET', $log->prAr($_GET));
$log->debug('POST', $log->prAr($_POST));
$log->debug('PHP-INPUT', $log->prAr($file_get));
print buildContent($http_headers, $file_get);
$log->debug('[END]', '=========================================>');
// __END__

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -42,20 +42,6 @@ $backend = new CoreLibs\Admin\Backend(
$l10n, $l10n,
DEFAULT_ACL_LEVEL DEFAULT_ACL_LEVEL
); );
$login = new CoreLibs\ACL\Login(
$db,
$log,
$session,
[
'auto_login' => false,
'default_acl_level' => DEFAULT_ACL_LEVEL,
'logout_target' => '',
'site_locale' => SITE_LOCALE,
'site_domain' => SITE_DOMAIN,
'site_encoding' => SITE_ENCODING,
'locale_path' => BASE . INCLUDES . LOCALE,
]
);
use CoreLibs\Debug\Support; use CoreLibs\Debug\Support;
$PAGE_NAME = 'TEST CLASS: ADMIN BACKEND'; $PAGE_NAME = 'TEST CLASS: ADMIN BACKEND';
@@ -69,30 +55,10 @@ print '<div><h1>' . $PAGE_NAME . '</h1></div>';
print "SETACL[]: <br>"; print "SETACL[]: <br>";
$backend->setACL(['EMPTY' => 'EMPTY']); $backend->setACL(['EMPTY' => 'EMPTY']);
print "ADBEDITLOG: <br>"; print "ADBEDITLOG: <br>";
$login->writeLog( $backend->adbEditLog('CLASSTEST-ADMIN-BINARY', 'Some info string', 'BINARY');
'CLASSTEST-ADMIN-BINARY', $backend->adbEditLog('CLASSTEST-ADMIN-ZLIB', 'Some info string', 'ZLIB');
'Some info string', $backend->adbEditLog('CLASSTEST-ADMIN-SERIAL', 'Some info string', 'SERIAL');
$backend->adbGetActionSet(), $backend->adbEditLog('CLASSTEST-ADMIN-INVALID', 'Some info string', 'INVALID');
write_type:'BINARY'
);
$login->writeLog(
'CLASSTEST-ADMIN-ZLIB',
'Some info string',
$backend->adbGetActionSet(),
write_type:'ZLIB'
);
$login->writeLog(
'CLASSTEST-ADMIN-SERIAL',
'Some info string',
$backend->adbGetActionSet(),
write_type:'SERIAL'
);
$login->writeLog(
'CLASSTEST-ADMIN-INVALID',
'Some info string',
$backend->adbGetActionSet(),
write_type:'INVALID'
);
// test with various // test with various
$backend->action = 'TEST ACTION'; $backend->action = 'TEST ACTION';
$backend->action_id = 'TEST ACTION ID'; $backend->action_id = 'TEST ACTION ID';
@@ -103,10 +69,10 @@ $backend->action_loaded = 'TEST ACTION LOADED';
$backend->action_value = 'TEST ACTION VALUE'; $backend->action_value = 'TEST ACTION VALUE';
$backend->action_type = 'TEST ACTION TYPE'; $backend->action_type = 'TEST ACTION TYPE';
$backend->action_error = 'TEST ACTION ERROR'; $backend->action_error = 'TEST ACTION ERROR';
$login->writeLog('CLASSTEST-ADMIN-JSON', [ $backend->adbEditLog('CLASSTEST-ADMIN-JSON', [
"_GET" => $_GET, "_GET" => $_GET,
"_POST" => $_POST, "_POST" => $_POST,
], $backend->adbGetActionSet(), write_type:'JSON'); ], 'JSON');
print "ADBTOPMENU(0): " . Support::printAr($backend->adbTopMenu(CONTENT_PATH)) . "<br>"; print "ADBTOPMENU(0): " . Support::printAr($backend->adbTopMenu(CONTENT_PATH)) . "<br>";
print "ADBMSG: <br>"; print "ADBMSG: <br>";

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -51,9 +51,6 @@ $test_array = [
'element_c' => [ 'element_c' => [
'type' => 'email' 'type' => 'email'
], ],
'element_d' => [
'type' => 'butter'
],
], ],
]; ];
@@ -63,8 +60,6 @@ echo "ARRAYSEARCHRECURSIVE(email, [array], type): "
. DgS::printAr(ArrayHandler::arraySearchRecursive('email', $test_array, 'type')) . "<br>"; . DgS::printAr(ArrayHandler::arraySearchRecursive('email', $test_array, 'type')) . "<br>";
echo "ARRAYSEARCHRECURSIVE(email, [array]['input'], type): " echo "ARRAYSEARCHRECURSIVE(email, [array]['input'], type): "
. DgS::printAr(ArrayHandler::arraySearchRecursive('email', $test_array['input'], 'type')) . "<br>"; . DgS::printAr(ArrayHandler::arraySearchRecursive('email', $test_array['input'], 'type')) . "<br>";
echo "ARRAYSEARCHRECURSIVE(email, [array]['input'], wrong): "
. DgS::printAr(ArrayHandler::arraySearchRecursive('email', $test_array['input'], 'wrong')) . "<br>";
// all return // all return
echo "ARRAYSEARCHRECURSIVEALL(email, [array], type): " echo "ARRAYSEARCHRECURSIVEALL(email, [array], type): "
. Dgs::printAr((array)ArrayHandler::arraySearchRecursiveAll('email', $test_array, 'type')) . "<br>"; . Dgs::printAr((array)ArrayHandler::arraySearchRecursiveAll('email', $test_array, 'type')) . "<br>";
@@ -73,15 +68,7 @@ echo "ARRAYSEARCHRECURSIVEALL(email, [array], type): "
// simple search // simple search
echo "ARRAYSEARCHSIMPLE([array], type, email): " echo "ARRAYSEARCHSIMPLE([array], type, email): "
. Dgs::prBl(ArrayHandler::arraySearchSimple($test_array, 'type', 'email')) . "<br>"; . (string)ArrayHandler::arraySearchSimple($test_array, 'type', 'email') . "<br>";
echo "ARRAYSEARCHSIMPLE([array], type, not): "
. Dgs::prBl(ArrayHandler::arraySearchSimple($test_array, 'type', 'not')) . "<br>";
echo "ARRAYSEARCHSIMPLE([array], type, [email,butter]): "
. Dgs::prBl(ArrayHandler::arraySearchSimple($test_array, 'type', ['email', 'butter'])) . "<br>";
echo "ARRAYSEARCHSIMPLE([array], type, [email,not]): "
. Dgs::prBl(ArrayHandler::arraySearchSimple($test_array, 'type', ['email', 'not'])) . "<br>";
echo "ARRAYSEARCHSIMPLE([array], type, [never,not]): "
. Dgs::prBl(ArrayHandler::arraySearchSimple($test_array, 'type', ['never', 'not'])) . "<br>";
$array_1 = [ $array_1 = [
'foo' => 'bar' 'foo' => 'bar'
@@ -128,6 +115,9 @@ print "ARRAYFLATFORKEY: " . DgS::printAr(ArrayHandler::arrayFlatForKey($test_arr
*/ */
function rec(string $pre, string $cur, array $node = []) function rec(string $pre, string $cur, array $node = [])
{ {
if (!is_array($node)) {
$node = [];
}
print "<div style='color: green;'>#### PRE: " . $pre . ", CUR: " . $cur . ", N-c: " print "<div style='color: green;'>#### PRE: " . $pre . ", CUR: " . $cur . ", N-c: "
. count($node) . " [" . join('|', array_keys($node)) . "]</div>"; . count($node) . " [" . join('|', array_keys($node)) . "]</div>";
if (!$pre) { if (!$pre) {
@@ -181,31 +171,6 @@ $data = [
$search = ['image', 'result_image', 'nothing', 'EMPTY']; $search = ['image', 'result_image', 'nothing', 'EMPTY'];
$result = ArrayHandler::arraySearchKey($data, $search); $result = ArrayHandler::arraySearchKey($data, $search);
print "ARRAYSEARCHKEY: Search: " . DgS::printAr($search) . ", Found: " . DgS::printAr($result) . "<br>"; print "ARRAYSEARCHKEY: Search: " . DgS::printAr($search) . ", Found: " . DgS::printAr($result) . "<br>";
$result = ArrayHandler::arraySearchKey($data, $search, true);
print "ARRAYSEARCHKEY: FLAT: Search: " . DgS::printAr($search) . ", Found: " . DgS::printAr($result) . "<br>";
$result = ArrayHandler::arraySearchKey($data, $search, true, true);
print "ARRAYSEARCHKEY: FLAT:PREFIX: Search: " . DgS::printAr($search) . ", Found: " . DgS::printAr($result) . "<br>";
$result = ArrayHandler::arraySearchKey($data, ["EMPTY"], true);
print "ARRAYSEARCHKEY: FLAT:PREFIX: Search: " . DgS::printAr(["EMPTY"]) . ", Found: " . DgS::printAr($result) . "<br>";
// $data = [
// [
// [name] => qrc_apcd,
// [value] => 5834367225,
// ],
// [
// [name] => qrc_other,
// [value] => test,
// ],
// [
// [name] => qrc_car_type,
// [value] => T33P17,
// ],
// [
// [name] => qrc_deaer_store,
// [value] => 9990:001,
// ]
// ]
// $test = [ // $test = [
// 'A' => [ // 'A' => [
@@ -288,246 +253,6 @@ foreach (array_keys($array) as $search) {
} }
print "Key not exists: " . DgS::printAr(ArrayHandler::arrayGetNextKey($array, 'z')) . "<br>"; print "Key not exists: " . DgS::printAr(ArrayHandler::arrayGetNextKey($array, 'z')) . "<br>";
print "<hr>";
$keys = ['b', 'c', 'f'];
print "Return only: " . DgS::printAr($keys) . ": "
. DgS::printAr(ArrayHandler::arrayReturnMatchingKeyOnly($array, $keys)) . "<br>";
$out = array_filter($array, fn($key) => in_array($key, $keys), ARRAY_FILTER_USE_KEY);
print "array filter: " . DgS::printAr($keys) . ": " . DgS::printAr($out) . "<br>";
$out = array_intersect_key(
$array,
array_flip($keys)
);
print "array intersect key: " . DgS::printAr($keys) . ": " . DgS::printAr($out) . "<br>";
print "array + suffix: " . DgS::printAr(ArrayHandler::arrayModifyKey($array, key_mod_suffix:'_attached')) . "<br>";
print "<hr>";
$unsorted = [9, 5, 'A', 4, 'B', 6, 'c', 'C', 'a'];
$unsorted_keys = [
'A' => 9, 'B' => 5, 'C' => 'A', 'D' => 4, 'E' => 'B', 'F' => 6, 'G' => 'c',
'H1' => 'D', 'B1' => 'd', 'H' => 'C', 'I' => 'a'
];
print "Unsorted: " . DgS::printAr($unsorted) . "<br>";
print "(sort): " . DgS::printAr(ArrayHandler::sortArray($unsorted)) . "<br>";
print "(sort, lower): " . DgS::printAr(ArrayHandler::sortArray($unsorted, case_insensitive:true)) . "<br>";
print "(sort, reverse): " . DgS::printAr(ArrayHandler::sortArray($unsorted, reverse:true)) . "<br>";
print "(sort, lower, reverse): "
. DgS::printAr(ArrayHandler::sortArray($unsorted, case_insensitive:true, reverse:true)) . "<br>";
print "(sort, keys): " . DgS::printAr(ArrayHandler::sortArray($unsorted_keys, maintain_keys:true)) . "<br>";
print "(sort, keys, lower): "
. DgS::printAr(ArrayHandler::sortArray($unsorted_keys, maintain_keys:true, case_insensitive:true)) . "<br>";
print "<hr>";
$unsorted = [9 => 'A', 5 => 'B', 'A' => 'C', 4 => 'D', 'B' => 'E', 6 => 'F', 'c' => 'G', 'C' => 'H', 'a' => 'I'];
print "Unsorted Keys: " . DgS::printAr($unsorted) . "<br>";
print "(sort): " . DgS::printAr(ArrayHandler::sortArray($unsorted)) . "<br>";
print "(sort, keys): " . DgS::printAr(ArrayHandler::sortArray($unsorted, maintain_keys:true)) . "<br>";
print "(kosrt): " . DgS::printAr(ArrayHandler::ksortArray($unsorted)) . "<br>";
print "(kosrt, reverse): " . DgS::printAr(ArrayHandler::ksortArray($unsorted, reverse:true)) . "<br>";
print "(kosrt, lower case, reverse): "
. DgS::printAr(ArrayHandler::ksortArray($unsorted, case_insensitive:true, reverse:true)) . "<br>";
print "<hr>";
$nested = [
'B' => 'foo', 'a', '0', 9, /** @phpstan-ignore-line This is a test for wrong index */
'1' => ['z', 'b', 'a'],
'd' => ['zaip', 'bar', 'baz']
];
print "Nested: " . DgS::printAr($nested) . "<br>";
print "(sort): " . DgS::printAr(ArrayHandler::sortArray($nested)) . "<br>";
print "(ksort): " . DgS::printAr(ArrayHandler::ksortArray($nested)) . "<br>";
print "<hr>";
$search_array = [
'table_lookup' => [
'match' => [
['param' => 'access_d_cd', 'data' => 'a_cd', 'time_validation' => 'on_load',],
['param' => 'other_block', 'data' => 'b_cd'],
['pflaume' => 'other_block', 'data' => 'c_cd'],
['param' => 'third_block', 'data' => 'd_cd', 'time_validation' => 'cool'],
['special' => 'other_block', 'data' => 'e_cd', 'time_validation' => 'other'],
]
]
];
print "Search: " . DgS::printAr($search_array) . "<br>";
print "Result (all): " . Dgs::printAr(ArrayHandler::findArraysMissingKey(
$search_array,
'other_block',
'time_validation'
)) . "<br>";
print "Result (key): " . Dgs::printAr(ArrayHandler::findArraysMissingKey(
$search_array,
'other_block',
'time_validation',
'pflaume'
)) . "<br>";
print "Result (key): " . Dgs::printAr(ArrayHandler::findArraysMissingKey(
$search_array,
'other_block',
['data', 'time_validation'],
'pflaume'
)) . "<br>";
print "<hr>";
$search_array = [
'a' => [
'lookup' => 1,
'value' => 'Foo',
'other' => 'Bar',
],
'b' => [
'lookup' => 1,
'value' => 'AAA',
'other' => 'Other',
],
'c' => [
'lookup' => 0,
'value' => 'CCC',
'other' => 'OTHER',
],
'd' => [
'd-1' => [
'lookup' => 1,
'value' => 'D SUB 1',
'other' => 'Other B',
],
'd-2' => [
'lookup' => 0,
'value' => 'D SUB 2',
'other' => 'Other C',
],
'more' => [
'lookup' => 1,
'd-more-1' => [
'lookup' => 1,
'value' => 'D MORE SUB 1',
'other' => 'Other C',
],
'd-more-2' => [
'lookup' => 0,
'value' => 'D MORE SUB 0',
'other' => 'Other C',
],
]
]
];
print "Search: " . DgS::printAr($search_array) . "<br>";
print "Result: " . DgS::printAr(ArrayHandler::selectArrayFromOption(
$search_array,
'lookup',
1,
)) . "<br>";
print "Result: " . DgS::printAr(ArrayHandler::selectArrayFromOption(
$search_array,
'lookup',
1,
recursive:true
)) . "<br>";
print "Result: " . DgS::printAr(ArrayHandler::selectArrayFromOption(
$search_array,
'lookup',
1,
recursive:true,
flat_separator:'-=-'
)) . "<br>";
print "Result: " . DgS::printAr(ArrayHandler::selectArrayFromOption(
$search_array,
'lookup',
1,
recursive:true,
flat_result:false
)) . "<br>";
print "Result: " . DgS::printAr(ArrayHandler::selectArrayFromOption(
$search_array,
'other',
'Other',
case_insensitive:false,
)) . "<br>";
$nestedTestData = [
'level1_a' => [
'name' => 'Level1A',
'type' => 'parent',
'children' => [
'child1' => [
'name' => 'Child1',
'type' => 'child',
'active' => true
],
'child2' => [
'name' => 'Child2',
'type' => 'child',
'active' => false
]
]
],
'level1_b' => [
'name' => 'Level1B',
'type' => 'parent',
'children' => [
'child3' => [
'name' => 'Child3',
'type' => 'child',
'active' => true,
'nested' => [
'deep1' => [
'name' => 'Deep1',
'type' => 'deep',
'active' => true
]
]
]
]
],
'item5' => [
'name' => 'Direct',
'type' => 'child',
'active' => false
]
];
$result = ArrayHandler::selectArrayFromOption(
$nestedTestData,
'type',
'child',
false,
false,
true,
true,
':*'
);
print "*1*Result: " . DgS::printAr($result) . "<br>";
$data = [
'parent1' => [
'name' => 'Parent1',
'status' => 'ACTIVE',
'children' => [
'child1' => [
'name' => 'Child1',
'status' => 'active'
]
]
]
];
$result = ArrayHandler::selectArrayFromOption(
$data,
'status',
'active',
false, // not strict
true, // case insensitive
true, // recursive
true, // flat result
'|' // custom separator
);
print "*2*Result: " . DgS::printAr($result) . "<br>";
print "</body></html>"; print "</body></html>";
// __END__ // __END__

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
// basic class test file // basic class test file

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -74,21 +74,9 @@ foreach ($bytes as $byte) {
print '<div style="width: 35%; text-align: right; padding-right: 2px;">'; print '<div style="width: 35%; text-align: right; padding-right: 2px;">';
print "(" . number_format($byte) . "/" . $byte . ") bytes :"; print "(" . number_format($byte) . "/" . $byte . ") bytes :";
$_bytes = Byte::humanReadableByteFormat($byte); $_bytes = Byte::humanReadableByteFormat($byte);
print '</div>'; print '</div><div style="width: 10%;">' . $_bytes;
print '<div style="width: 10%;">' . $_bytes . '</div>'; print '</div><div style="width: 10%;">';
print '<div style="width: 40%;">'; print Byte::stringByteFormat($_bytes);
try {
print Byte::stringByteFormat($_bytes);
} catch (\LengthException $e) {
print "LengthException 1: " . $e->getMessage();
try {
print "<br>S: " . Byte::stringByteFormat($_bytes, Byte::RETURN_AS_STRING);
} catch (\LengthException $e) {
print "LengthException 2: " . $e->getMessage();
} catch (\RuntimeException $e) {
print "RuntimeException 1: " . $e->getMessage();
}
}
print "</div>"; print "</div>";
// //
print "</div>"; print "</div>";
@@ -99,85 +87,13 @@ foreach ($bytes as $byte) {
print "bytes [si]:"; print "bytes [si]:";
$_bytes = Byte::humanReadableByteFormat($byte, Byte::BYTE_FORMAT_SI); $_bytes = Byte::humanReadableByteFormat($byte, Byte::BYTE_FORMAT_SI);
print '</div><div style="width: 10%;">' . $_bytes; print '</div><div style="width: 10%;">' . $_bytes;
print '</div><div style="width: 40%;">'; print '</div><div style="width: 10%;">';
try { print Byte::stringByteFormat($_bytes);
print Byte::stringByteFormat($_bytes);
} catch (\LengthException $e) {
print "LengthException A: " . $e->getMessage();
try {
print "<br>Ssi: " . Byte::stringByteFormat($_bytes, Byte::RETURN_AS_STRING | Byte::BYTE_FORMAT_SI);
} catch (\LengthException $e) {
print "LengthException B: " . $e->getMessage();
} catch (\RuntimeException $e) {
print "RuntimeException A: " . $e->getMessage();
}
}
print "</div>"; print "</div>";
// //
print "</div>"; print "</div>";
} }
$string_bytes = [
'-117.42 MB',
'242.98 MB',
'254.78 MiB',
'1 EiB',
'8 EB',
'867.36EB',
'1000EB',
'10000EB',
];
print "<b>BYTE STRING TO BYTES TESTS</b><br>";
foreach ($string_bytes as $string) {
print '<div style="display: flex; border-bottom: 1px dashed gray;">';
//
print '<div style="width: 35%; text-align: right; padding-right: 2px;">';
print "string byte ($string) to bytes :";
try {
$_bytes = Byte::stringByteFormat($string);
} catch (\LengthException $e) {
print "<br>LengthException A: " . $e->getMessage();
$_bytes = 0;
}
try {
$_bytes_string = Byte::stringByteFormat($string, Byte::RETURN_AS_STRING);
} catch (\LengthException $e) {
print "<br>LengthException B: " . $e->getMessage();
$_bytes_string = '';
} catch (\RuntimeException $e) {
print "<br>RuntimeException: " . $e->getMessage();
$_bytes_string = '';
}
try {
$_bytes_si = Byte::stringByteFormat($string, Byte::BYTE_FORMAT_SI);
} catch (\LengthException $e) {
print "<br>LengthException A: " . $e->getMessage();
$_bytes_si = 0;
}
try {
$_bytes_string_si = Byte::stringByteFormat($string, Byte::RETURN_AS_STRING | Byte::BYTE_FORMAT_SI);
} catch (\LengthException $e) {
print "<br>LengthException B: " . $e->getMessage();
$_bytes_string_si = '';
} catch (\RuntimeException $e) {
print "<br>RuntimeException: " . $e->getMessage();
$_bytes_string_si = '';
}
print '</div>';
print '<div style="width: 20%;">'
. "F:" . number_format((int)$_bytes)
. '<br>B: ' . $_bytes
. '<br>S: ' . $_bytes_string
. "<br>Fsi:" . number_format((int)$_bytes_si)
. '<br>Bsi: ' . $_bytes_si
. '<br>Ssi: ' . $_bytes_string_si;
print '</div>';
print '<div style="width: 10%;">';
print "B: " . Byte::humanReadableByteFormat($_bytes) . "<br>";
print "Bsi: " . Byte::humanReadableByteFormat($_bytes_si, Byte::BYTE_FORMAT_SI);
print "</div>";
print "</div>";
}
print "</body></html>"; print "</body></html>";
// __END__ // __END__

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -18,9 +18,7 @@ require 'config.php';
$LOG_FILE_ID = 'classTest-convert-colors'; $LOG_FILE_ID = 'classTest-convert-colors';
ob_end_flush(); ob_end_flush();
// use CoreLibs\Convert\Colors; use CoreLibs\Convert\Colors;
use CoreLibs\Convert\Color\Color;
use CoreLibs\Convert\Color\Coordinates;
use CoreLibs\Debug\Support as DgS; use CoreLibs\Debug\Support as DgS;
use CoreLibs\Convert\SetVarType; use CoreLibs\Convert\SetVarType;
@@ -29,36 +27,7 @@ $log = new CoreLibs\Logging\Logging([
'log_file_id' => $LOG_FILE_ID, 'log_file_id' => $LOG_FILE_ID,
'log_per_date' => true, 'log_per_date' => true,
]); ]);
$color_class = 'CoreLibs\Convert\Colors';
/**
* print out a color block with info
*
* @param string $color
* @param string $text
* @param string $text_add
* @return string
*/
function display(string $color, string $text, string $text_add): string
{
$css = 'margin:5px;padding:50px;'
. 'width:10%;'
. 'text-align:center;'
. 'color:white;text-shadow: 0 0 5px black;font-weight:bold;';
$template = <<<HTML
<div style="background-color:{COLOR};{CSS}">
{TEXT}
</div>
HTML;
return str_replace(
["{COLOR}", "{TEXT}", "{CSS}"],
[
$color,
$text . (!empty($text_add) ? '<br>' . $text_add : ''),
$css
],
$template
);
}
$PAGE_NAME = 'TEST CLASS: CONVERT COLORS'; $PAGE_NAME = 'TEST CLASS: CONVERT COLORS';
print "<!DOCTYPE html>"; print "<!DOCTYPE html>";
@@ -67,83 +36,32 @@ print "<body>";
print '<div><a href="class_test.php">Class Test Master</a></div>'; print '<div><a href="class_test.php">Class Test Master</a></div>';
print '<div><h1>' . $PAGE_NAME . '</h1></div>'; print '<div><h1>' . $PAGE_NAME . '</h1></div>';
// out of bounds test
// define a list of from to color sets for conversion test // define a list of from to color sets for conversion test
$hwb = Color::hsbToHwb(new Coordinates\HSB([
160,
0,
50,
]));
print "HWB: " . DgS::printAr($hwb) . "<br>";
$hsb = Color::hwbToHsb($hwb);
print "HSB: " . DgS::printAr($hsb) . "<br>";
$oklch = Color::rgbToOkLch(Coordinates\RGB::create([
250,
0,
0
]));
print "OkLch: " . DgS::printAr($oklch) . "<br>";
$rgb = Color::okLchToRgb($oklch);
print "OkLch -> RGB: " . DgS::printAr($rgb) . "<br>";
$oklab = Color::rgbToOkLab(Coordinates\RGB::create([
250,
0,
0
]));
print "OkLab: " . DgS::printAr($oklab) . "<br>";
print display($oklab->toCssString(), $oklab->toCssString(), 'Oklab');
$rgb = Color::okLabToRgb($oklab);
print "OkLab -> RGB: " . DgS::printAr($rgb) . "<br>";
print display($rgb->toCssString(), $rgb->toCssString(), 'OkLab to RGB');
$rgb = Coordinates\RGB::create([250, 100, 10])->toLinear();
print "RGBlinear: " . DgS::printAr($rgb) . "<br>";
$rgb = Coordinates\RGB::create([0, 0, 0])->toLinear();
print "RGBlinear: " . DgS::printAr($rgb) . "<br>";
$cie_lab = Color::okLabToLab($oklab);
print "CieLab: " . DgS::printAr($cie_lab) . "<br>";
print display($cie_lab->toCssString(), $cie_lab->toCssString(), 'OkLab to Cie Lab');
$rgb = Coordinates\RGB::create([0, 0, 60]);
$hsb = Color::rgbToHsb($rgb);
$rgb_b = Color::hsbToRgb($hsb);
print "RGB: " . DgS::printAr($rgb) . "<br>";
print "RGB->HSB: " . DgS::printAr($hsb) . "<br>";
print "HSB->RGB: " . DgS::printAr($rgb_b) . "<br>";
$hsl = Coordinates\HSL::create([0, 20, 0]);
$hsb = Coordinates\HSB::create([0, 20, 0]);
$hsl_from_hsb = Color::hsbToHsl($hsb);
print "HSL from HSB: " . DgS::printAr($hsl_from_hsb) . "<br>";
print "<hr>";
// A(out of bounds) // A(out of bounds)
try { try {
print "C::S/COLOR invalid rgb->hex (gray 125): -1, -1, -1: " print "C::S/COLOR invalid rgb->hex (gray 125): -1, -1, -1: "
. (new Coordinates\RGB([-1, -1, -1]))->returnAsHex() . "<br>"; . CoreLibs\Convert\Colors::rgb2hex(-1, -1, -1) . "<br>";
} catch (\LengthException $e) { } catch (\LengthException $e) {
print "*Exception: " . $e->getMessage() . "<br><pre>" . print_r($e, true) . "</pre><br>"; print "*Exception: " . $e->getMessage() . "<br>" . $e . "<br>";
}
try {
print "\$C::S/COLOR invalid rgb->hex (gray 125): -1, -1, -1: "
. $color_class::rgb2hex(-1, -1, -1) . "<br>";
} catch (\LengthException $e) {
print "**Exception: " . $e->getMessage() . "<br><pre>" . print_r($e, true) . "</pre><br>";
} }
/* print "<hr>";
print "<h2>LEGACY</h2>";
// B(valid) // B(valid)
$rgb = [50, 20, 30]; $rgb = [10, 20, 30];
$hex = '#0a141e'; $hex = '#0a141e';
$hsb = [210, 67, 12]; $hsb = [210, 67, 12];
$hsb_f = [210.5, 67.5, 12.5]; $hsb_f = [210.5, 67.5, 12.5];
$hsb = [210, 50, 7.8]; $hsl = [210, 50, 7.8];
print "S::COLOR rgb->hex: $rgb[0], $rgb[1], $rgb[2]: " . Colors::rgb2hex($rgb[0], $rgb[1], $rgb[2]) . "<br>"; print "S::COLOR rgb->hex: $rgb[0], $rgb[1], $rgb[2]: " . Colors::rgb2hex($rgb[0], $rgb[1], $rgb[2]) . "<br>";
print "S::COLOR hex->rgb: $hex: " . DgS::printAr(SetVarType::setArray( print "S::COLOR hex->rgb: $hex: " . DgS::printAr(SetVarType::setArray(
Colors::hex2rgb($hex) Colors::hex2rgb($hex)
)) . "<br>"; )) . "<br>";
print "C::S/COLOR rgb->hex: $hex: " . DgS::printAr(SetVarType::setArray( print "C::S/COLOR rgb->hext: $hex: " . DgS::printAr(SetVarType::setArray(
CoreLibs\Convert\Colors::hex2rgb($hex) CoreLibs\Convert\Colors::hex2rgb($hex)
)) . "<br>"; )) . "<br>";
// C(to hsb/hsl) // C(to hsb/hsl)
@@ -164,18 +82,16 @@ print "S::COLOR hsb_f->rgb: $hsb_f[0], $hsb_f[1], $hsb_f[2]: "
. DgS::printAr(SetVarType::setArray( . DgS::printAr(SetVarType::setArray(
Colors::hsb2rgb($hsb_f[0], $hsb_f[1], $hsb_f[2]) Colors::hsb2rgb($hsb_f[0], $hsb_f[1], $hsb_f[2])
)) . "<br>"; )) . "<br>";
print "S::COLOR hsl->rgb: $hsb[0], $hsb[1], $hsb[2]: " print "S::COLOR hsl->rgb: $hsl[0], $hsl[1], $hsl[2]: "
. DgS::printAr(SetVarType::setArray( . DgS::printAr(SetVarType::setArray(
Colors::hsl2rgb($hsb[0], $hsb[1], $hsb[2]) Colors::hsl2rgb($hsl[0], $hsl[1], $hsl[2])
)) . "<br>"; )) . "<br>";
$hsb = [0, 0, 5]; $hsb = [0, 0, 5];
print "S::COLOR hsb->rgb: $hsb[0], $hsb[1], $hsb[2]: " print "S::COLOR hsb->rgb: $hsb[0], $hsb[1], $hsb[2]: "
. DgS::printAr(SetVarType::setArray( . DgS::printAr(SetVarType::setArray(
Colors::hsb2rgb($hsb[0], $hsb[1], $hsb[2]) Colors::hsb2rgb($hsb[0], $hsb[1], $hsb[2])
)) . "<br>"; */ )) . "<br>";
print "<hr>";
// Random text // Random text
$h = rand(0, 359); $h = rand(0, 359);
@@ -183,18 +99,10 @@ $s = rand(15, 70);
$b = 100; $b = 100;
$l = 50; $l = 50;
print "RANDOM IN: H: " . $h . ", S: " . $s . ", B/L: " . $b . "/" . $l . "<br>"; print "RANDOM IN: H: " . $h . ", S: " . $s . ", B/L: " . $b . "/" . $l . "<br>";
print "RANDOM hsb->rgb: <pre>" print "RANDOM hsb->rgb: <pre>" . DgS::printAr(SetVarType::setArray(Colors::hsb2rgb($h, $s, $b))) . "</pre><br>";
. DgS::printAr(SetVarType::setArray(Color::hsbToRgb(new Coordinates\HSB([$h, $s, $b])))) . "</pre><br>"; print "RANDOM hsl->rgb: <pre>" . DgS::printAr(SetVarType::setArray(Colors::hsl2rgb($h, $s, $l))) . "</pre><br>";
print "RANDOM hsl->rgb: <pre>"
. DgS::printAr(SetVarType::setArray(Color::hslToRgb(new Coordinates\HSL([$h, $s, $l])))) . "</pre><br>";
print "<hr>"; // TODO: run compare check input must match output
$rgb = [0, 0, 0];
print "rgb 0,0,0: " . Dgs::printAr($rgb) . " => "
. Dgs::printAr(Color::rgbToHsb(new Coordinates\RGB([$rgb[0], $rgb[1], $rgb[2]]))) . "<br>";
print "<hr>";
print "</body></html>"; print "</body></html>";

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -225,36 +225,6 @@ foreach ($intervals as $interval) {
print "STRINGTOTIME: $reverse_interval: " . DateTime::stringToTime($reverse_interval) . "<br>"; print "STRINGTOTIME: $reverse_interval: " . DateTime::stringToTime($reverse_interval) . "<br>";
} }
print "<hr>"; print "<hr>";
$interval_strings = [
'10d 5h 30m 15s 123456ms',
'18999d 0h 38m 10s 1235ms',
'18999 d 0 h 38 m 10s 1235ms',
'-2h 15m 5s',
'45s 500ms',
'0s',
'0ms',
'1s 5ms',
'1s 50ms',
'1s 500ms',
'1s 5000ms',
'10day 5hour 30min 15sec 123456millis',
'10day 5hour 30min 15sec 123456millisec',
'10day 5hour 30min 15sec 123456msec',
'-2days 3hours 15minutes 30seconds 250milliseconds',
'',
' ',
'invalid',
];
foreach ($interval_strings as $interval_string) {
print "STRINGTOTIME: $interval_string: " . DateTime::stringToTime($interval_string) . "<br>";
try {
// test exception
DateTime::stringToTime($interval_string, throw_exception:true);
} catch (\InvalidArgumentException $e) {
print "ERROR: " . $e->getMessage() . "<br><pre>" . $e . "</pre><br>";
}
}
print "<hr>";
$check_dates = [ $check_dates = [
'2021-05-01', '2021-05-01',
'2021-05-40' '2021-05-40'
@@ -298,9 +268,7 @@ foreach ($compare_datetimes as $compare_datetime) {
print "COMPAREDATE: $compare_datetime[0] = $compare_datetime[1]: " print "COMPAREDATE: $compare_datetime[0] = $compare_datetime[1]: "
. (string)DateTime::compareDateTime($compare_datetime[0], $compare_datetime[1]) . "<br>"; . (string)DateTime::compareDateTime($compare_datetime[0], $compare_datetime[1]) . "<br>";
} }
print "<hr>"; print "<hr>";
print "<h2>calcDaysInterval</h2>";
$compare_dates = [ $compare_dates = [
[ '2021-05-01', '2021-05-10', ], [ '2021-05-01', '2021-05-10', ],
[ '2021-05-10', '2021-05-01', ], [ '2021-05-10', '2021-05-01', ],
@@ -311,21 +279,9 @@ foreach ($compare_dates as $compare_date) {
print "CALCDAYSINTERVAL: $compare_date[0] = $compare_date[1]: " print "CALCDAYSINTERVAL: $compare_date[0] = $compare_date[1]: "
. DgS::printAr(DateTime::calcDaysInterval($compare_date[0], $compare_date[1])) . "<br>"; . DgS::printAr(DateTime::calcDaysInterval($compare_date[0], $compare_date[1])) . "<br>";
print "CALCDAYSINTERVAL(named): $compare_date[0] = $compare_date[1]: " print "CALCDAYSINTERVAL(named): $compare_date[0] = $compare_date[1]: "
. DgS::printAr(DateTime::calcDaysInterval($compare_date[0], $compare_date[1], return_named:true)) . "<br>"; . DgS::printAr(DateTime::calcDaysInterval($compare_date[0], $compare_date[1], true)) . "<br>";
print "CALCDAYSINTERVAL(EXCLUDE END): $compare_date[0] = $compare_date[1]: "
. Dgs::printAr(DateTime::calcDaysInterval($compare_date[0], $compare_date[1], include_end_date:false));
print "CALCDAYSINTERVAL(EXCLUDE START): $compare_date[0] = $compare_date[1]: "
. Dgs::printAr(DateTime::calcDaysInterval($compare_date[0], $compare_date[1], exclude_start_date:true));
print "CALCDAYSINTERVAL(EXCLUDE END, EXCLUDE START): $compare_date[0] = $compare_date[1]: "
. Dgs::printAr(DateTime::calcDaysInterval(
$compare_date[0],
$compare_date[1],
include_end_date:false,
exclude_start_date:true
));
} }
print "<hr>"; print "<hr>";
print "<h2>setWeekdayNameFromIsoDow</h2>";
// test date conversion // test date conversion
$dow = 2; $dow = 2;
print "DOW[$dow]: " . DateTime::setWeekdayNameFromIsoDow($dow) . "<br>"; print "DOW[$dow]: " . DateTime::setWeekdayNameFromIsoDow($dow) . "<br>";
@@ -341,25 +297,26 @@ $date = '2022-70-242';
print "DATE-dow[$date];invalid: " . DateTime::setWeekdayNameFromDate($date) . "<br>"; print "DATE-dow[$date];invalid: " . DateTime::setWeekdayNameFromDate($date) . "<br>";
print "DATE-dow[$date],long;invalid: " . DateTime::setWeekdayNameFromDate($date, true) . "<br>"; print "DATE-dow[$date],long;invalid: " . DateTime::setWeekdayNameFromDate($date, true) . "<br>";
print "DOW-date[$date];invalid: " . DateTime::setWeekdayNumberFromDate($date) . "<br>"; print "DOW-date[$date];invalid: " . DateTime::setWeekdayNumberFromDate($date) . "<br>";
print "<hr>"; print "<hr>";
print "<h2>dateRangeHasWeekend</h2>";
// check date range includes a weekend // check date range includes a weekend
$has_weekend_list = [ // does not:
['2023-07-03', '2023-07-05'], $start_date = '2023-07-03';
['2023-07-03', '2023-07-10'], $end_date = '2023-07-05';
['2023-07-03', '2023-07-31'], print "Has Weekend: " . $start_date . " ~ " . $end_date . ": "
['2023-07-01', '2023-07-03'], . Dgs::prBl(DateTime::dateRangeHasWeekend($start_date, $end_date)) . "<br>";
['2023-07-01', '2023-07-01'], $start_date = '2023-07-03';
['2023-07-01', '2023-07-02'], $end_date = '2023-07-10';
['2023-06-30', '2023-07-01'], print "Has Weekend: " . $start_date . " ~ " . $end_date . ": "
['2023-06-30', '2023-06-30'], . Dgs::prBl(DateTime::dateRangeHasWeekend($start_date, $end_date)) . "<br>";
['2023-07-01', '2023-06-30'], $start_date = '2023-07-03';
]; $end_date = '2023-07-31';
foreach ($has_weekend_list as $days) { print "Has Weekend: " . $start_date . " ~ " . $end_date . ": "
print "Has Weekend: " . $days[0] . " ~ " . $days[1] . ": " . Dgs::prBl(DateTime::dateRangeHasWeekend($start_date, $end_date)) . "<br>";
. Dgs::prBl(DateTime::dateRangeHasWeekend($days[0], $days[1])) . "<br>"; $start_date = '2023-07-01';
} $end_date = '2023-07-03';
print "Has Weekend: " . $start_date . " ~ " . $end_date . ": "
. Dgs::prBl(DateTime::dateRangeHasWeekend($start_date, $end_date)) . "<br>";
print "</body></html>"; print "</body></html>";
@@ -503,10 +460,7 @@ function intervalStringFormatDeprecated(
// print "-> V: $value | $part, $time_name | I: " . is_int($value) . " | F: " . is_float($value) // print "-> V: $value | $part, $time_name | I: " . is_int($value) . " | F: " . is_float($value)
// . " | " . ($value != 0 ? 'Not zero' : 'ZERO') . "<br>"; // . " | " . ($value != 0 ? 'Not zero' : 'ZERO') . "<br>";
// var_dump($skip_last_zero); // var_dump($skip_last_zero);
if ( if ($value != 0 || $skip_zero === false || $skip_last_zero === false) {
is_numeric($value) &&
($value != 0 || $skip_zero === false || $skip_last_zero === false)
) {
if ($part == 'f') { if ($part == 'f') {
if ($truncate_nanoseconds === true) { if ($truncate_nanoseconds === true) {
$value = round($value, 3); $value = round($value, 3);

View File

@@ -1,265 +0,0 @@
<?php // phpcs:ignore warning
/**
* @phan-file-suppress PhanTypeSuspiciousStringExpression
*/
declare(strict_types=1);
// turn on all error reporting
error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start();
// basic class test file
define('USE_DATABASE', true);
// sample config
require 'config.php';
// define log file id
$LOG_FILE_ID = 'classTest-db-convert-placeholder';
ob_end_flush();
use CoreLibs\Debug\Support;
use CoreLibs\DB\Support\ConvertPlaceholder;
use CoreLibs\Convert\Html;
$log = new CoreLibs\Logging\Logging([
'log_folder' => BASE . LOG,
'log_file_id' => $LOG_FILE_ID,
'log_per_date' => true,
]);
$PAGE_NAME = 'TEST CLASS: DB CONVERT PLACEHOLDER';
print "<!DOCTYPE html>";
print "<html><head><title>" . $PAGE_NAME . "</title></head>";
print "<body>";
print '<div><a href="class_test.php">Class Test Master</a></div>';
print '<div><h1>' . $PAGE_NAME . '</h1></div>';
print "LOGFILE NAME: " . $log->getLogFile() . "<br>";
print "LOGFILE ID: " . $log->getLogFileId() . "<br>";
print "Lookup Regex: <pre>" . Html::htmlent(ConvertPlaceholder::REGEX_LOOKUP_PLACEHOLDERS) . "</pre>";
print "Lookup Numbered Regex: <pre>" . Html::htmlent(ConvertPlaceholder::REGEX_LOOKUP_NUMBERED) . "</pre>";
print "Replace Named Regex: <pre>" . Html::htmlent(ConvertPlaceholder::REGEX_REPLACE_NAMED) . "</pre>";
print "Replace Question Mark Regex: <pre>"
. Html::htmlent(ConvertPlaceholder::REGEX_REPLACE_QUESTION_MARK) . "</pre>";
print "Replace Numbered Regex: <pre>" . Html::htmlent(ConvertPlaceholder::REGEX_REPLACE_NUMBERED) . "</pre>";
$uniqid = \CoreLibs\Create\Uids::uniqIdShort();
// $binary_data = $db->dbEscapeBytea(file_get_contents('class_test.db.php') ?: '');
// $binary_data = file_get_contents('class_test.db.php') ?: '';
$binary_data = '';
$params = [
$uniqid,
true,
'STRING A',
2,
2.5,
1,
date('H:m:s'),
date('Y-m-d H:i:s'),
json_encode(['a' => 'string', 'b' => 1, 'c' => 1.5, 'f' => true, 'g' => ['a', 1, 1.5]]),
null,
'{"a", "b"}',
'{1,2}',
'{"(array Text A, 5, 8.8)","(array Text B, 10, 15.2)"}',
'("Text", 4, 6.3)',
$binary_data
];
$query = <<<SQL
INSERT INTO test_foo (
test, some_bool, string_a, number_a, number_a_numeric, smallint_a,
some_time, some_timestamp, json_string, null_var,
array_char_1, array_int_1,
array_composite,
composite_item,
some_binary
) VALUES (
$1, $2, $3, $4, $5, $6,
$7, $8, $9, $10,
$11, $12,
$13,
$14,
$15
)
RETURNING
test_foo_id,
test, some_bool, string_a, number_a, number_a_numeric, smallint_a,
some_time, some_timestamp, json_string, null_var,
array_char_1, array_int_1,
array_composite,
composite_item,
some_binary
SQL;
print "<b>[ALL] Convert</b>: "
. Support::printAr(ConvertPlaceholder::convertPlaceholderInQuery($query, $params))
. "<br>";
echo "<hr>";
$query = "SELECT foo FROM bar WHERE baz = :baz AND buz = :baz AND biz = :biz AND boz = :bez";
$params = [':baz' => 'SETBAZ', ':bez' => 'SETBEZ', ':biz' => 'SETBIZ'];
print "<b>[NO PARAMS] Convert</b>: "
. Support::printAr(ConvertPlaceholder::convertPlaceholderInQuery($query, $params))
. "<br>";
echo "<hr>";
$query = "SELECT foo FROM bar WHERE baz = :baz AND buz = :baz AND biz = :biz AND boz = :bez";
$params = null;
print "<b>[NO PARAMS] Convert</b>: "
. Support::printAr(ConvertPlaceholder::convertPlaceholderInQuery($query, $params))
. "<br>";
echo "<hr>";
$query = "SELECT row_varchar FROM table_with_primary_key WHERE row_varchar <> :row_varchar";
$params = null;
print "<b>[NO PARAMS] Convert</b>: "
. Support::printAr(ConvertPlaceholder::convertPlaceholderInQuery($query, $params))
. "<br>";
echo "<hr>";
$query = "SELECT row_varchar, row_varchar_literal, row_int, row_date FROM table_with_primary_key";
$params = null;
print "<b>[NO PARAMS] TEST</b>: "
. Support::printAr(ConvertPlaceholder::convertPlaceholderInQuery($query, $params))
. "<br>";
echo "<hr>";
$query = <<<SQL
UPDATE table_with_primary_key SET
row_int = $1::INT, row_numeric = $1::NUMERIC, row_varchar = $1
WHERE
row_varchar = $1
SQL;
$params = [1];
print "<b>[All the same params] TEST</b>: "
. Support::printAr(ConvertPlaceholder::convertPlaceholderInQuery($query, $params))
. "<br>";
echo "<hr>";
$query = <<<SQL
SELECT row_varchar, row_varchar_literal, row_int, row_date
FROM table_with_primary_key
WHERE row_varchar = :row_varchar
SQL;
$params = [':row_varchar' => 1];
print "<b>[: param] TEST</b>: "
. Support::printAr(ConvertPlaceholder::convertPlaceholderInQuery($query, $params))
. "<br>";
echo "<hr>";
print "<b>[P-CONV]</b>: "
. Support::printAr(
ConvertPlaceholder::updateParamList([
'original' => [
'query' => 'SELECT foo FROM bar WHERE baz = :baz AND buz = :biz AND biz = :biz AND boz = :bez',
'params' => [':baz' => 'SETBAZ', ':bez' => 'SETBEZ', ':biz' => 'SETBIZ'],
'empty_params' => false,
],
'type' => 'named',
'found' => 3,
// 'matches' => [
// ':baz'
// ],
// 'params_lookup' => [
// ':baz' => '$1'
// ],
// 'query' => "SELECT foo FROM bar WHERE baz = $1",
// 'parms' => [
// 'SETBAZ'
// ],
])
);
echo "<hr>";
// test connectors: = , <> () for query detection
// convert placeholder tests
// ? -> $n
// :name -> $n
// other way around (just visual)
$test_queries = [
'skip' => [
'query' => <<<SQL
SELECT test, string_a, number_a
FROM test_foo
SQL,
'params' => [],
'direction' => 'pg',
],
'numbers' => [
'query' => <<<SQL
SELECT test, string_a, number_a
FROM test_foo
WHERE
foo = $1 AND bar = $1 AND foobar = $2
SQL,
'params' => [\CoreLibs\Create\Uids::uniqIdShort(), 'string A-1', 1234],
'direction' => 'pdo',
],
'a?' => [
'query' => <<<SQL
INSERT INTO test_foo (
test, string_a, number_a
) VALUES (
?, ?, ?
)
SQL,
'params' => [\CoreLibs\Create\Uids::uniqIdShort(), 'string A-1', 1234],
'direction' => 'pg',
],
'b?' => [
'query' => <<<SQL
SELECT test FROM test_foo = ?
SQL,
'params' => [1234],
'direction' => 'pg',
],
'b:' => [
'query' => <<<SQL
INSERT INTO test_foo (
test, string_a, number_a
) VALUES (
:test, :string_a, :number_a
)
SQL,
'params' => [
':test' => \CoreLibs\Create\Uids::uniqIdShort(),
':string_a' => 'string B-1',
':number_a' => 5678
],
'direction' => 'pg',
],
'select, compare $' => [
'query' => <<<SQL
SELECT row_varchar
FROM table_with_primary_key
WHERE
row_int >= $1 OR row_int <= $2 OR
row_int > $3 OR row_int < $4
OR row_int = $5 OR row_int <> $6
SQL,
'params' => null,
'direction' => 'pg'
]
];
foreach ($test_queries as $info => $data) {
$query = $data['query'];
$params = $data['params'];
$direction = $data['direction'];
print "<b>[$info] Convert</b>: "
. Support::printAr(ConvertPlaceholder::convertPlaceholderInQuery($query, $params, $direction))
. "<br>";
echo "<hr>";
}
print "</body></html>";
$log->debug('DEBUGEND', '==================================== [END]');
// __END__

View File

@@ -7,7 +7,7 @@
declare(strict_types=1); declare(strict_types=1);
// turn on all error reporting // turn on all error reporting
error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -70,7 +70,8 @@ for ($i = 1; $i <= 6; $i++) {
print $i . ") " . $cache_flag . ": " print $i . ") " . $cache_flag . ": "
. "res: " . (is_bool($res) ? . "res: " . (is_bool($res) ?
"<b>Bool:</b> " . Support::prBl($res) : "<b>Bool:</b> " . Support::prBl($res) :
"Array: Yes" (is_array($res) ?
"Array: " . Support::prBl(is_array($res)) : '{-}')
) . ", " ) . ", "
. "cursor_ext: <pre>" . Support::printAr( . "cursor_ext: <pre>" . Support::printAr(
SetVarType::setArray($db->dbGetCursorExt($q_db_ret)) SetVarType::setArray($db->dbGetCursorExt($q_db_ret))
@@ -88,7 +89,8 @@ for ($i = 1; $i <= 6; $i++) {
print $i . ") " . $cache_flag . ": " print $i . ") " . $cache_flag . ": "
. "res: " . (is_bool($res) ? . "res: " . (is_bool($res) ?
"<b>Bool:</b> " . Support::prBl($res) : "<b>Bool:</b> " . Support::prBl($res) :
"Array: Yes" (is_array($res) ?
"Array: " . Support::prBl(is_array($res)) : '{-}')
) . ", " ) . ", "
. "cursor_ext: <pre>" . Support::printAr( . "cursor_ext: <pre>" . Support::printAr(
SetVarType::setArray($db->dbGetCursorExt($q_db_ret)) SetVarType::setArray($db->dbGetCursorExt($q_db_ret))
@@ -106,7 +108,8 @@ for ($i = 1; $i <= 6; $i++) {
print $i . ") " . $cache_flag . ": " print $i . ") " . $cache_flag . ": "
. "res: " . (is_bool($res) ? . "res: " . (is_bool($res) ?
"<b>Bool:</b> " . Support::prBl($res) : "<b>Bool:</b> " . Support::prBl($res) :
"Array: Yes" (is_array($res) ?
"Array: " . Support::prBl(is_array($res)) : '{-}')
) . ", " ) . ", "
. "cursor_ext: <pre>" . Support::printAr( . "cursor_ext: <pre>" . Support::printAr(
SetVarType::setArray($db->dbGetCursorExt($q_db_ret)) SetVarType::setArray($db->dbGetCursorExt($q_db_ret))
@@ -124,7 +127,8 @@ for ($i = 1; $i <= 6; $i++) {
print $i . ") " . $cache_flag . ": " print $i . ") " . $cache_flag . ": "
. "res: " . (is_bool($res) ? . "res: " . (is_bool($res) ?
"<b>Bool:</b> " . Support::prBl($res) : "<b>Bool:</b> " . Support::prBl($res) :
"Array: Yes" (is_array($res) ?
"Array: " . Support::prBl(is_array($res)) : '{-}')
) . ", " ) . ", "
. "cursor_ext: <pre>" . Support::printAr( . "cursor_ext: <pre>" . Support::printAr(
SetVarType::setArray($db->dbGetCursorExt($q_db_ret)) SetVarType::setArray($db->dbGetCursorExt($q_db_ret))
@@ -142,7 +146,8 @@ for ($i = 1; $i <= 6; $i++) {
print $i . ") " . $cache_flag . ": " print $i . ") " . $cache_flag . ": "
. "res: " . (is_bool($res) ? . "res: " . (is_bool($res) ?
"<b>Bool:</b> " . Support::prBl($res) : "<b>Bool:</b> " . Support::prBl($res) :
"Array: Yes" (is_array($res) ?
"Array: " . Support::prBl(is_array($res)) : '{-}')
) . ", " ) . ", "
. "cursor_ext: <pre>" . Support::printAr( . "cursor_ext: <pre>" . Support::printAr(
SetVarType::setArray($db->dbGetCursorExt($q_db_ret)) SetVarType::setArray($db->dbGetCursorExt($q_db_ret))

View File

@@ -1,166 +0,0 @@
<?php // phpcs:ignore warning
/**
* @phan-file-suppress PhanTypeSuspiciousStringExpression
*/
declare(strict_types=1);
// turn on all error reporting
error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start();
// basic class test file
define('USE_DATABASE', true);
// sample config
require 'config.php';
// for testing encryption compare
use OpenPGP\OpenPGP;
// define log file id
$LOG_FILE_ID = 'classTest-db-query-encryption';
ob_end_flush();
// use CoreLibs\Debug\Support;
use CoreLibs\Security\SymmetricEncryption;
use CoreLibs\Security\CreateKey;
use CoreLibs\Create\Hash;
use CoreLibs\Debug\Support;
$log = new CoreLibs\Logging\Logging([
'log_folder' => BASE . LOG,
'log_file_id' => $LOG_FILE_ID,
'log_per_date' => true,
]);
// db connection and attach logger
$db = new CoreLibs\DB\IO(DB_CONFIG, $log);
$db->log->debug('START', '=============================>');
$PAGE_NAME = 'TEST CLASS: DB QUERY ENCRYPTION';
print "<!DOCTYPE html>";
print "<html><head><title>" . $PAGE_NAME . "</title></head>";
print "<body>";
print '<div><a href="class_test.php">Class Test Master</a></div>';
print '<div><h1>' . $PAGE_NAME . '</h1></div>';
// encryption key
$key_new = CreateKey::generateRandomKey();
print "Secret Key NEW: " . $key_new . "<br>";
// for reproducable test results
$key = 'e475c19b9a3c8363feb06b51f5b73f1dc9b6f20757d4ab89509bf5cc70ed30ec';
print "Secret Key: " . $key . "<br>";
// test text
$text_string = "I a some deep secret";
$text_string = "I a some deep secret ABC";
//
$crypt = new SymmetricEncryption($key);
$encrypted = $crypt->encrypt($text_string);
$string_hashed = Hash::hashStd($text_string);
$string_hmac = Hash::hashHmac($text_string, $key);
$decrypted = $crypt->decrypt($encrypted);
print "String: " . $text_string . "<br>";
print "Encrypted: " . $encrypted . "<br>";
print "Hashed: " . $string_hashed . "<br>";
print "Hmac: " . $string_hmac . "<br>";
$db->dbExecParams(
<<<SQL
INSERT INTO test_encryption (
-- for compare
plain_text,
-- via php encryption
hash_text, hmac_text, crypt_text,
-- -- in DB encryption
pg_digest_bytea, pg_digest_text,
pg_hmac_bytea, pg_hmac_text,
pg_crypt_bytea, pg_crypt_text
) VALUES (
$1,
$2, $3, $4,
digest($1::VARCHAR, $5),
encode(digest($1, $5), 'hex'),
hmac($1, $6, $5),
encode(hmac($1, $6, $5), 'hex'),
pgp_sym_encrypt($1, $7),
encode(pgp_sym_encrypt($1, $7), 'hex')
) RETURNING cuuid
SQL,
[
// 1: original string
$text_string,
// 2: hashed, 3: hmac, 4: encrypted
$string_hashed, $string_hmac, $encrypted,
// 5: hash type, 6: hmac secret, 7: pgp secret
'sha256', $key, $key
]
);
$cuuid = $db->dbGetReturningExt('cuuid');
print "INSERTED: " . print_r($cuuid, true) . "<br>";
print "LAST ERROR: " . $db->dbGetLastError(true) . "<br>";
// read back
$res = $db->dbReturnRowParams(
<<<SQL
SELECT
-- for compare
plain_text,
-- via php encryption
hash_text, hmac_text, crypt_text,
-- in DB encryption
pg_digest_bytea, pg_digest_text,
pg_hmac_bytea, pg_hmac_text,
pg_crypt_bytea, pg_crypt_text,
encode(pg_crypt_bytea, 'hex') AS pg_crypt_bytea_hex,
pgp_sym_decrypt(pg_crypt_bytea, $2) AS from_pg_crypt_bytea,
pgp_sym_decrypt(decode(pg_crypt_text, 'hex'), $2) AS from_pg_crypt_text
FROM
test_encryption
WHERE
cuuid = $1
SQL,
[
$cuuid, $key
]
);
print "RES: <pre>" . Support::prAr($res) . "</pre><br>";
if ($res === false) {
echo "Failed to run query<br>";
} else {
if (hash_equals($string_hashed, $res['pg_digest_text'])) {
print "libsodium and pgcrypto hash match<br>";
}
if (hash_equals($string_hmac, $res['pg_hmac_text'])) {
print "libsodium and pgcrypto hash hmac match<br>";
}
// do compare for PHP and pgcrypto settings
$encryptedMessage_template = <<<TEXT
-----BEGIN PGP MESSAGE-----
{BASE64}
-----END PGP MESSAGE-----
TEXT;
$base64_string = base64_encode(hex2bin($res['pg_crypt_text']) ?: '');
$encryptedMessage = str_replace(
'{BASE64}',
$base64_string,
$encryptedMessage_template
);
try {
$literalMessage = OpenPGP::decryptMessage($encryptedMessage, passwords: [$key]);
$decrypted = $literalMessage->getLiteralData()->getData();
print "Pg decrypted PHP: " . $decrypted . "<br>";
if ($decrypted == $text_string) {
print "Decryption worked<br>";
}
} catch (\Exception $e) {
print "Error decrypting message: " . $e->getMessage() . "<br>";
}
}
print "</body></html>";
// __END__

View File

@@ -7,7 +7,7 @@
declare(strict_types=1); declare(strict_types=1);
// turn on all error reporting // turn on all error reporting
error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -76,41 +76,41 @@ $db->dbResetEncoding();
// empty calls, none of the below should fail // empty calls, none of the below should fail
// //
$foo = $db->dbGetCursor(); $db->dbGetCursor();
// //
$foo = $db->dbGetCursorExt(); $db->dbGetCursorExt();
// //
$foo = $db->dbGetCursorPos('SELECT foo', ['bar']); $db->dbGetCursorPos('SELECT foo', ['bar']);
// //
$foo = $db->dbGetCursorNumRows('SELECT foo', ['bar']); $db->dbGetCursorNumRows('SELECT foo', ['bar']);
// //
$foo = $db->dbGetInsertPKName(); $db->dbGetInsertPKName();
// //
$foo = $db->dbGetInsertPK(); $db->dbGetInsertPK();
// //
$foo = $db->dbGetReturningExt(); $db->dbGetReturningExt();
$foo = $db->dbGetReturningExt('foo'); $db->dbGetReturningExt('foo');
$foo = $db->dbGetReturningExt('foo', 0); $db->dbGetReturningExt('foo', 0);
$foo = $db->dbGetReturningExt(pos:0); $db->dbGetReturningExt(pos:0);
// //
$foo = $db->dbGetReturningArray(); $db->dbGetReturningArray();
// //
$foo = $db->dbGetNumRows(); $db->dbGetNumRows();
// //
$foo = $db->dbGetNumFields(); $db->dbGetNumFields();
// //
$foo = $db->dbGetFieldNames(); $db->dbGetFieldNames();
// //
$foo = $db->dbGetFieldTypes(); $db->dbGetFieldTypes();
// //
$foo = $db->dbGetFieldNameTypes(); $db->dbGetFieldNameTypes();
// //
$foo = $db->dbGetFieldName(0); $db->dbGetFieldName(0);
// //
$foo = $db->dbGetFieldType(0); $db->dbGetFieldType(0);
$foo = $db->dbGetFieldType('foo'); $db->dbGetFieldType('foo');
// //
$foo = $db->dbGetPrepareCursorValue('foo', 'bar'); $db->dbGetPrepareCursorValue('foo', 'bar');
// TEST CACHE READS // TEST CACHE READS
@@ -228,7 +228,7 @@ print "RETURN ROW PARAMS: " . print_r(
$db->dbPrepare("ins_test_foo", "INSERT INTO test_foo (test) VALUES ($1) RETURNING test"); $db->dbPrepare("ins_test_foo", "INSERT INTO test_foo (test) VALUES ($1) RETURNING test");
$status = $db->dbExecute("ins_test_foo", ['BAR TEST ' . time()]); $status = $db->dbExecute("ins_test_foo", ['BAR TEST ' . time()]);
print "PREPARE INSERT[ins_test_foo] STATUS: " . Support::printToString($status) . " |<br>" print "PREPARE INSERT[ins_test_foo] STATUS: " . Support::printToString($status) . " |<br>"
. "QUERY: " . Support::printToString($db->dbGetPrepareCursorValue('ins_test_foo', 'query')) . " |<br>" . "QUERY: " . $db->dbGetPrepareCursorValue('ins_test_foo', 'query') . " |<br>"
. "PRIMARY KEY: " . Support::printToString($db->dbGetInsertPK()) . " | " . "PRIMARY KEY: " . Support::printToString($db->dbGetInsertPK()) . " | "
. "RETURNING EXT: " . print_r($db->dbGetReturningExt(), true) . " | " . "RETURNING EXT: " . print_r($db->dbGetReturningExt(), true) . " | "
. "RETURNING RETURN: " . print_r($db->dbGetReturningArray(), true) . "<br>"; . "RETURNING RETURN: " . print_r($db->dbGetReturningArray(), true) . "<br>";
@@ -239,7 +239,7 @@ print "PREPARE INSERT PREVIOUS INSERTED: "
print "PREPARE CURSOR RETURN:<br>"; print "PREPARE CURSOR RETURN:<br>";
foreach (['pk_name', 'count', 'query', 'returning_id'] as $key) { foreach (['pk_name', 'count', 'query', 'returning_id'] as $key) {
print "KEY: " . $key . ': ' . Support::prAr($db->dbGetPrepareCursorValue('ins_test_foo', $key)) . "<br>"; print "KEY: " . $key . ': ' . $db->dbGetPrepareCursorValue('ins_test_foo', $key) . "<br>";
} }
$query = <<<SQL $query = <<<SQL
@@ -255,7 +255,7 @@ SQL;
$db->dbPrepare("ins_test_foo_eom", $query); $db->dbPrepare("ins_test_foo_eom", $query);
$status = $db->dbExecute("ins_test_foo_eom", ['EOM BAR TEST ' . time()]); $status = $db->dbExecute("ins_test_foo_eom", ['EOM BAR TEST ' . time()]);
print "EOM STRING PREPARE INSERT[ins_test_foo_eom] STATUS: " . Support::printToString($status) . " |<br>" print "EOM STRING PREPARE INSERT[ins_test_foo_eom] STATUS: " . Support::printToString($status) . " |<br>"
. "QUERY: " . Support::printToString($db->dbGetPrepareCursorValue('ins_test_foo_eom', 'query')) . " |<br>" . "QUERY: " . $db->dbGetPrepareCursorValue('ins_test_foo_eom', 'query') . " |<br>"
. "PRIMARY KEY: " . Support::printToString($db->dbGetInsertPK()) . " | " . "PRIMARY KEY: " . Support::printToString($db->dbGetInsertPK()) . " | "
. "RETURNING EXT: " . print_r($db->dbGetReturningExt(), true) . " | " . "RETURNING EXT: " . print_r($db->dbGetReturningExt(), true) . " | "
. "RETURNING RETURN: " . print_r($db->dbGetReturningArray(), true) . "<br>"; . "RETURNING RETURN: " . print_r($db->dbGetReturningArray(), true) . "<br>";
@@ -273,8 +273,8 @@ $query_insert = <<<SQL
INSERT INTO INSERT INTO
test_foo test_foo
( (
test, some_bool, string_a, number_a, numeric_a, test, some_bool, string_a, number_a, number_a_numeric,
some_internval, some_timestamp, json_string some_time, some_timestamp, json_string
) VALUES ( ) VALUES (
$1, $2, $3, $4, $5, $1, $2, $3, $4, $5,
$6, $7, $8 $6, $7, $8
@@ -283,8 +283,8 @@ RETURNING test
SQL; SQL;
$query_select = <<<SQL $query_select = <<<SQL
SELECT SELECT
test, some_bool, string_a, number_a, numeric_a, test, some_bool, string_a, number_a, number_a_numeric,
some_time, some_internval, some_timestamp, json_string some_time, some_time, some_timestamp, json_string
FROM FROM
test_foo test_foo
WHERE WHERE
@@ -316,8 +316,7 @@ print "EOM STRING EXEC RETURN TEST: " . print_r(
$db->dbReturnRowParams( $db->dbReturnRowParams(
$query_select, $query_select,
[$__last_insert_id] [$__last_insert_id]
), )
true
) . "<br>"; ) . "<br>";
// B // B
$status = $db->dbExecParams( $status = $db->dbExecParams(
@@ -346,8 +345,7 @@ print "EOM STRING EXEC RETURN TEST: " . print_r(
$db->dbReturnRowParams( $db->dbReturnRowParams(
$query_select, $query_select,
[$__last_insert_id] [$__last_insert_id]
), )
true
) . "<br>"; ) . "<br>";
// params > 10 for debug // params > 10 for debug
// error catcher // error catcher
@@ -554,7 +552,7 @@ print "<b>PREPARE QUERIES</b><br>";
// READ PREPARE // READ PREPARE
$q_prep = <<<SQL $q_prep = <<<SQL
SELECT test_foo_id, test, some_bool, string_a, number_a, SELECT test_foo_id, test, some_bool, string_a, number_a,
numeric_a, some_time number_a_numeric, some_time
FROM test_foo FROM test_foo
WHERE test = $1 WHERE test = $1
ORDER BY test_foo_id DESC LIMIT 5 ORDER BY test_foo_id DESC LIMIT 5
@@ -582,7 +580,7 @@ if ($db->dbPrepare('sel_test_foo', $q_prep) === false) {
// sel test with ANY () type // sel test with ANY () type
$q_prep = "SELECT test_foo_id, test, some_bool, string_a, number_a, " $q_prep = "SELECT test_foo_id, test, some_bool, string_a, number_a, "
. "numeric_a, some_time " . "number_a_numeric, some_time "
. "FROM test_foo " . "FROM test_foo "
. "WHERE test = ANY($1) " . "WHERE test = ANY($1) "
. "ORDER BY test_foo_id DESC LIMIT 5"; . "ORDER BY test_foo_id DESC LIMIT 5";
@@ -618,7 +616,7 @@ $test_bar = $db->dbEscapeLiteral('SOMETHING DIFFERENT');
$q = <<<SQL $q = <<<SQL
SELECT test_foo_id, test, some_bool, string_a, number_a, SELECT test_foo_id, test, some_bool, string_a, number_a,
-- comment -- comment
numeric_a, some_time number_a_numeric, some_time
FROM test_foo FROM test_foo
WHERE test = $test_bar WHERE test = $test_bar
ORDER BY test_foo_id DESC LIMIT 5 ORDER BY test_foo_id DESC LIMIT 5
@@ -631,7 +629,7 @@ print "DB RETURN PARAMS<br>";
$q = <<<SQL $q = <<<SQL
SELECT test_foo_id, test, some_bool, string_a, number_a, SELECT test_foo_id, test, some_bool, string_a, number_a,
-- comment -- comment
numeric_a, some_time number_a_numeric, some_time
FROM test_foo FROM test_foo
WHERE test = $1 WHERE test = $1
ORDER BY test_foo_id DESC LIMIT 5 ORDER BY test_foo_id DESC LIMIT 5
@@ -646,7 +644,7 @@ echo "<hr>";
print "DB RETURN PARAMS LIKE<br>"; print "DB RETURN PARAMS LIKE<br>";
$q = <<<SQL $q = <<<SQL
SELECT SELECT
test_foo_id, test, some_bool, string_a, number_a, numeric_a test_foo_id, test, some_bool, string_a, number_a, number_a_numeric
FROM test_foo FROM test_foo
WHERE string_a LIKE $1; WHERE string_a LIKE $1;
SQL; SQL;
@@ -660,7 +658,7 @@ echo "<hr>";
print "DB RETURN PARAMS ANY<br>"; print "DB RETURN PARAMS ANY<br>";
$q = <<<SQL $q = <<<SQL
SELECT SELECT
test_foo_id, test, some_bool, string_a, number_a, numeric_a test_foo_id, test, some_bool, string_a, number_a, number_a_numeric
FROM test_foo FROM test_foo
WHERE string_a = ANY($1); WHERE string_a = ANY($1);
SQL; SQL;
@@ -676,7 +674,7 @@ echo "<hr>";
print "COMPOSITE ELEMENT READ<br>"; print "COMPOSITE ELEMENT READ<br>";
$res = $db->dbReturnRow("SELECT item, count, (item).name, (item).price, (item).supplier_id FROM on_hand"); $res = $db->dbReturnRow("SELECT item, count, (item).name, (item).price, (item).supplier_id FROM on_hand");
print "ROW: <pre>" . print_r($res, true) . "</pre>"; print "ROW: <pre>" . print_r($res) . "</pre>";
var_dump($res); var_dump($res);
print "Field Name/Types: <pre>" . print_r($db->dbGetFieldNameTypes(), true) . "</pre>"; print "Field Name/Types: <pre>" . print_r($db->dbGetFieldNameTypes(), true) . "</pre>";
echo "<hr>"; echo "<hr>";
@@ -707,17 +705,6 @@ if (
} else { } else {
print "[PGB] [3] pgb_sel_test_foo prepare OK<br>"; print "[PGB] [3] pgb_sel_test_foo prepare OK<br>";
} }
$stm_status = $db->dbPreparedCursorStatus('');
print "[PGB] Empty statement name: " . $log->prAr($stm_status) . "<br>";
$stm_status = $db->dbPreparedCursorStatus('pgb_sel_test_foobar');
print "[PGB] Prepared name not match status: $stm_status<br>";
$stm_status = $db->dbPreparedCursorStatus('pgb_sel_test_foo');
print "[PGB] Prepared name match status: $stm_status<br>";
$stm_status = $db->dbPreparedCursorStatus('pgb_sel_test_foo', $q_prep);
print "[PGB] prepared exists and query match status: $stm_status<br>";
$stm_status = $db->dbPreparedCursorStatus('pgb_sel_test_foo', "SELECT * FROM test_foo");
print "[PGB] prepared exists and query not match status: $stm_status<br>";
$db_pgb->dbClose(); $db_pgb->dbClose();
# db write class test # db write class test

View File

@@ -7,7 +7,7 @@
declare(strict_types=1); declare(strict_types=1);
// turn on all error reporting // turn on all error reporting
error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -53,9 +53,6 @@ if (($dbh = $db->dbGetDbh()) instanceof \PgSql\Connection) {
} else { } else {
print "NO DB HANDLER<br>"; print "NO DB HANDLER<br>";
} }
// REGEX for placeholder count
print "Placeholder lookup regex: <pre>" . CoreLibs\DB\Support\ConvertPlaceholder::REGEX_LOOKUP_NUMBERED . "</pre>";
// turn on debug replace for placeholders // turn on debug replace for placeholders
$db->dbSetDebugReplacePlaceholder(true); $db->dbSetDebugReplacePlaceholder(true);
@@ -65,136 +62,59 @@ $db->dbExec("TRUNCATE test_foo");
$uniqid = \CoreLibs\Create\Uids::uniqIdShort(); $uniqid = \CoreLibs\Create\Uids::uniqIdShort();
$binary_data = $db->dbEscapeBytea(file_get_contents('class_test.db.php') ?: ''); $binary_data = $db->dbEscapeBytea(file_get_contents('class_test.db.php') ?: '');
$query_params = [ $query_params = [
$uniqid, // test $uniqid,
true, // some_bool true,
'STRING A', // string_a 'STRING A',
2, // number_a 2,
2.5, // numeric_a 2.5,
1, // smallint 1,
date('H:m:s'), // some_internval date('H:m:s'),
date('Y-m-d H:i:s'), // some_timestamp date('Y-m-d H:i:s'),
json_encode(['a' => 'string', 'b' => 1, 'c' => 1.5, 'f' => true, 'g' => ['a', 1, 1.5]]), // json_string json_encode(['a' => 'string', 'b' => 1, 'c' => 1.5, 'f' => true, 'g' => ['a', 1, 1.5]]),
null, // null_var null,
'{"a", "b"}', // array_char_1 '{"a", "b"}',
'{1,2}', // array_int_1 '{1,2}',
'{"(array Text A, 5, 8.8)","(array Text B, 10, 15.2)"}', // array_composite '{"(array Text A, 5, 8.8)","(array Text B, 10, 15.2)"}',
'("Text", 4, 6.3)', // composite_item '("Text", 4, 6.3)',
$binary_data, // some_binary $binary_data
date('Y-m-d'), // some_date
date('H:i:s'), // some_time
'{"c", "d", "e"}', // array_char_2
'{3,4,5}', // array_int_2
12345667778818, // bigint
1.56, // numbrer_real
3.75, // number_double
124.5, // numeric_3
\CoreLibs\Create\Uids::uuidv4() // uuid_var
]; ];
$query_insert = <<<SQL $query_insert = <<<SQL
INSERT INTO test_foo ( INSERT INTO test_foo (
-- row 1 test, some_bool, string_a, number_a, number_a_numeric, smallint_a,
test, some_bool, string_a, number_a, numeric_a, smallint_a, some_time, some_timestamp, json_string, null_var,
-- row 2
some_internval, some_timestamp, json_string, null_var,
-- row 3
array_char_1, array_int_1, array_char_1, array_int_1,
-- row 4
array_composite, array_composite,
-- row 5
composite_item, composite_item,
-- row 6 some_binary
some_binary,
-- row 7
some_date, some_time,
-- row 8
array_char_2, array_int_2,
-- row 9
bigint_a, number_real, number_double, numeric_3,
-- row 10
uuid_var
) VALUES ( ) VALUES (
-- row 1
$1, $2, $3, $4, $5, $6, $1, $2, $3, $4, $5, $6,
-- row 2
$7, $8, $9, $10, $7, $8, $9, $10,
-- row 3
$11, $12, $11, $12,
-- row 4
$13, $13,
-- row 5
$14, $14,
-- row 6 $15
$15,
-- row 7
$16, $17,
-- row 8
$18, $19,
-- row 9
$20, $21, $22, $23,
-- row 10
$24
) )
RETURNING RETURNING
test_foo_id, number_serial, identity_always, identitiy_default, default_uuid, test_foo_id,
test, some_bool, string_a, number_a, numeric_a, smallint_a, test, some_bool, string_a, number_a, number_a_numeric, smallint_a,
some_internval, some_timestamp, json_string, null_var, some_time, some_timestamp, json_string, null_var,
array_char_1, array_int_1, array_char_1, array_int_1,
array_composite, array_composite,
composite_item, composite_item,
some_binary, some_binary
some_date,
array_char_2, array_int_2,
bigint_a, number_real, number_double, numeric_3,
uuid_var
SQL; SQL;
print "Placeholders: <pre>" . print_r($db->dbGetQueryParamPlaceholders($query_insert), true) . "<pre>";
$status = $db->dbExecParams($query_insert, $query_params); $status = $db->dbExecParams($query_insert, $query_params);
echo "<b>*</b><br>"; echo "<b>*</b><br>";
echo "INSERT ALL COLUMN TYPES: " echo "INSERT ALL COLUMN TYPES: "
. Support::printToString($query_params) . " |<br>" . Support::printToString($query_params) . " |<br>"
. "QUERY: <pre>" . $db->dbGetQuery() . "</pre> |<br>" . "QUERY: " . $db->dbGetQuery() . " |<br>"
. "PRIMARY KEY: " . Support::printToString($db->dbGetInsertPK()) . " |<br>" . "PRIMARY KEY: " . Support::printToString($db->dbGetInsertPK()) . " |<br>"
. "RETURNING EXT: <pre>" . print_r($db->dbGetReturningExt(), true) . "</pre> |<br>" . "RETURNING EXT: <pre>" . print_r($db->dbGetReturningExt(), true) . "</pre> |<br>"
. "RETURNING RETURN: <pre>" . print_r($db->dbGetReturningArray(), true) . "<pre> |<br>" . "RETURNING RETURN: <pre>" . print_r($db->dbGetReturningArray(), true) . "<pre> |<br>"
. "ERROR: " . $db->dbGetLastError(true) . "<br>"; . "ERROR: " . $db->dbGetLastError(true) . "<br>";
echo "<hr>"; echo "<hr>";
print "<b>ANY call</b><br>";
$query = <<<SQL
SELECT test
FROM test_foo
WHERE string_a = ANY($1)
SQL;
$query_value = '{'
. join(',', ['STRING A'])
. '}';
while (is_array($res = $db->dbReturnParams($query, [$query_value]))) {
print "Result: " . Support::prAr($res) . "<br>";
}
echo "<hr>";
echo "<b>CASE part</b><br>";
$query = <<<SQL
UPDATE
test_foo
SET
some_timestamp = NOW(),
-- if not 1 set, else keep at one
smallint_a = (CASE
WHEN smallint_a <> 1 THEN $1
ELSE 1::INT
END)::INT
WHERE
string_a = $2
SQL;
echo "QUERY: <pre>" . $query . "</pre>";
$res = $db->dbExecParams($query, [1, 'foobar']);
print "ERROR: " . $db->dbGetLastError(true) . "<br>";
echo "<hr>";
// test connectors: = , <> () for query detection // test connectors: = , <> () for query detection
// convert placeholder tests // convert placeholder tests
@@ -211,16 +131,6 @@ SQL,
'params' => [], 'params' => [],
'direction' => 'pg', 'direction' => 'pg',
], ],
'numbers' => [
'query' => <<<SQL
SELECT test, string_a, number_a
FROM test_foo
WHERE
foo = $1 AND bar = $1 AND foobar = $2
SQL,
'params' => [\CoreLibs\Create\Uids::uniqIdShort(), 'string A-1', 1234],
'direction' => 'pdo',
],
'a?' => [ 'a?' => [
'query' => <<<SQL 'query' => <<<SQL
INSERT INTO test_foo ( INSERT INTO test_foo (
@@ -247,18 +157,6 @@ SQL,
], ],
'direction' => 'pg', 'direction' => 'pg',
], ],
'select, compare $' => [
'query' => <<<SQL
SELECT string_a
FROM test_foo
WHERE
number_a >= $1 OR number_a <= $2 OR
number_a > $3 OR number_a < $4
OR number_a = $5 OR number_a <> $6
SQL,
'params' => [1, 2, 3, 4, 5, 6],
'direction' => 'pg'
],
]; ];
$db->dbSetConvertPlaceholder(true); $db->dbSetConvertPlaceholder(true);
@@ -271,12 +169,11 @@ foreach ($test_queries as $info => $data) {
// . "<br>"; // . "<br>";
if ($db->dbCheckQueryForSelect($query)) { if ($db->dbCheckQueryForSelect($query)) {
$row = $db->dbReturnRowParams($query, $params); $row = $db->dbReturnRowParams($query, $params);
print "<b>[$info]</b> SELECT: " . Support::prAr($row) . "<br>"; print "[$info] SELECT: " . Support::prAr($row) . "<br>";
} else { } else {
$db->dbExecParams($query, $params); $db->dbExecParams($query, $params);
} }
print "ERROR: " . $db->dbGetLastError(true) . "<br>"; print "[$info] " . Support::printAr($db->dbGetPlaceholderConverted()) . "<br>";
print "<b>[$info]</b> " . Support::printAr($db->dbGetPlaceholderConverted()) . "<br>";
echo "<hr>"; echo "<hr>";
} }
@@ -291,44 +188,21 @@ SQL,
['string A-1'] ['string A-1']
)) ))
) { ) {
print "<b>RES</b>: " . Support::prAr($res) . "<br>"; print "RES: " . Support::prAr($res) . "<br>";
} }
print "ERROR: " . $db->dbGetLastError(true) . "<br>";
echo "<hr>";
print "CursorExt: " . Support::prAr($db->dbGetCursorExt(<<<SQL print "CursorExt: " . Support::prAr($db->dbGetCursorExt(<<<SQL
SELECT test, string_a, number_a SELECT test, string_a, number_a
FROM test_foo FROM test_foo
WHERE string_a = ? WHERE string_a = ?
SQL, ['string A-1'])); SQL, ['string A-1']));
echo "<hr>";
// ERROR BELOW: missing params
$res = $db->dbReturnRowParams(<<<SQL $res = $db->dbReturnRowParams(<<<SQL
SELECT test, string_a, number_a SELECT test, string_a, number_a
FROM test_foo FROM test_foo
WHERE string_a = $1 WHERE string_a = $1
SQL, []); SQL, []);
print "PL: " . Support::PrAr($db->dbGetPlaceholderConverted()) . "<br>"; print "PL: " . Support::PrAr($db->dbGetPlaceholderConverted()) . "<br>";
print "ERROR: " . $db->dbGetLastError(true) . "<br>";
echo "<hr>";
// ERROR BELOW: LIKE cannot have placeholder
echo "dbReturn read LIKE: <br>";
while (
is_array($res = $db->dbReturnParams(
<<<SQL
SELECT test, string_a, number_a
FROM test_foo
WHERE string_a LIKE ?
SQL,
['%A-1%']
))
) {
print "RES: " . Support::prAr($res) . "<br>";
}
print "PL: " . Support::PrAr($db->dbGetPlaceholderConverted()) . "<br>";
print "ERROR: " . $db->dbGetLastError(true) . "<br>";
print "</body></html>"; print "</body></html>";
$db->log->debug('DEBUGEND', '==================================== [END]'); $db->log->debug('DEBUGEND', '==================================== [END]');

View File

@@ -7,7 +7,7 @@
declare(strict_types=1); declare(strict_types=1);
// turn on all error reporting // turn on all error reporting
error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();

View File

@@ -7,7 +7,7 @@
declare(strict_types=1); declare(strict_types=1);
// turn on all error reporting // turn on all error reporting
error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -57,43 +57,6 @@ if (($dbh = $db->dbGetDbh()) instanceof \PgSql\Connection) {
print "<b>TRUNCATE test_foo</b><br>"; print "<b>TRUNCATE test_foo</b><br>";
$db->dbExec("TRUNCATE test_foo"); $db->dbExec("TRUNCATE test_foo");
/*
BELOW IS THE FULL TABLE WITH ALL PostgreSQL Types
=> \d test_foo
Table "public.test_foo"
Column | Type | Nullable | Default
------------------+-----------------------------+----------+-----------------------------------------------
test | character varying | |
some_bool | boolean | |
string_a | character varying | |
number_a | integer | |
numeric_a | numeric | |
some_internval | interval | |
test_foo_id | integer | not null | generated always as identity
json_string | jsonb | |
some_timestamp | timestamp without time zone | |
some_binary | bytea | |
null_var | character varying | |
smallint_a | smallint | |
number_real | real | |
number_double | double precision | |
number_serial | integer | not null | nextval('test_foo_number_serial_seq'::regclass)
array_char_1 | character varying[] | |
array_char_2 | character varying[] | |
array_int_1 | integer[] | |
array_int_2 | integer[] | |
composite_item | inventory_item | |
array_composite | inventory_item[] | |
numeric_3 | numeric(3,0) | |
identity_always | bigint | not null | generated always as identity
identitiy_default | bigint | not null | generated by default as identity
uuid_var | uuid | | gen_random_uuid()
some_date | date | |
some_time | time without time zone | |
bigint_a | bigint | |
default_uuid | uuid | | gen_random_uuid()
*/
/* $q = <<<SQL /* $q = <<<SQL
INSERT INTO test_foo (test, array_composite) VALUES ('C', '{"(a,1,1.5)","(b,2,2.5)"}') INSERT INTO test_foo (test, array_composite) VALUES ('C', '{"(a,1,1.5)","(b,2,2.5)"}')
SQL; SQL;
@@ -127,7 +90,7 @@ $query_params = [
$query_insert = <<<SQL $query_insert = <<<SQL
INSERT INTO test_foo ( INSERT INTO test_foo (
test, some_bool, string_a, number_a, numeric_a, smallint_a, test, some_bool, string_a, number_a, number_a_numeric, smallint_a,
some_time, some_timestamp, json_string, null_var, some_time, some_timestamp, json_string, null_var,
array_char_1, array_int_1, array_char_1, array_int_1,
array_composite, array_composite,
@@ -143,7 +106,7 @@ INSERT INTO test_foo (
) )
RETURNING RETURNING
test_foo_id, test_foo_id,
test, some_bool, string_a, number_a, numeric_a, smallint_a, test, some_bool, string_a, number_a, number_a_numeric, smallint_a,
some_time, some_timestamp, json_string, null_var, some_time, some_timestamp, json_string, null_var,
array_char_1, array_int_1, array_char_1, array_int_1,
array_composite, array_composite,
@@ -164,8 +127,8 @@ echo "<hr>";
$query_select = <<<SQL $query_select = <<<SQL
SELECT SELECT
test_foo_id, test_foo_id,
test, some_bool, string_a, number_a, numeric_a, smallint_a, test, some_bool, string_a, number_a, number_a_numeric, smallint_a,
number_real, number_double, numeric_3, number_serial, number_real, number_double, number_numeric_3, number_serial,
some_time, some_timestamp, json_string, null_var, some_time, some_timestamp, json_string, null_var,
array_char_1, array_char_2, array_int_1, array_int_2, array_composite, array_char_1, array_char_2, array_int_1, array_int_2, array_composite,
composite_item, (composite_item).*, composite_item, (composite_item).*,

View File

@@ -12,7 +12,7 @@ $PRINT_ALL = false;
$ECHO_ALL = true; $ECHO_ALL = true;
$DB_DEBUG = true; $DB_DEBUG = true;
error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -68,14 +68,6 @@ function test2(): array
return DebugSupport::getCallerMethodList(1); return DebugSupport::getCallerMethodList(1);
} }
// date stueff
print "printTime(-1): " . DebugSupport::printTime() . "<br>";
print "printTime(2): " . DebugSupport::printTime(2) . "<br>";
print "printTime(3): " . DebugSupport::printTime(3) . "<br>";
print "printTime(5): " . DebugSupport::printTime(5) . "<br>";
print "printIsoTime(): " . DebugSupport::printIsoTime() . "<br>";
print "printIsoTime(false): " . DebugSupport::printIsoTime(false) . "<br>";
print "S::GETCALLERMETHOD: " . DebugSupport::getCallerMethod(0) . "<br>"; print "S::GETCALLERMETHOD: " . DebugSupport::getCallerMethod(0) . "<br>";
print "S::GETCALLERMETHOD: " . test() . "<br>"; print "S::GETCALLERMETHOD: " . test() . "<br>";
print "S::GETCALLERMETHODLIST: <pre>" . print_r(test2(), true) . "</pre><br>"; print "S::GETCALLERMETHODLIST: <pre>" . print_r(test2(), true) . "</pre><br>";
@@ -154,7 +146,7 @@ print "LOG LEVEL: " . DebugSupport::printAr(\CoreLibs\Convert\SetVarType::setAr
$new_log->getLogLevel('debug', 'on') $new_log->getLogLevel('debug', 'on')
)) . "<br>"; )) . "<br>";
echo "<b>CLASS DEBUG CALL LEGACY</b><br>"; echo "<b>CLASS DEBUG CALL</b><br>";
// @codingStandardsIgnoreLine // @codingStandardsIgnoreLine
class TestL class TestL

View File

@@ -1,110 +0,0 @@
<?php // phpcs:ignore warning
/**
* @phan-file-suppress PhanTypeSuspiciousStringExpression
*/
declare(strict_types=1);
error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start();
// basic class test file
define('USE_DATABASE', false);
// sample config
require 'config.php';
// define log file id
$LOG_FILE_ID = 'classTest-phpv';
ob_end_flush();
$log = new CoreLibs\Logging\Logging([
'log_folder' => BASE . LOG,
'log_file_id' => $LOG_FILE_ID,
'log_per_date' => true,
]);
$_phpv = new CoreLibs\Check\PhpVersion();
$phpv_class = 'CoreLibs\Check\PhpVersion';
$PAGE_NAME = 'TEST CLASS: PHP VERSION';
print "<!DOCTYPE html>";
print "<html><head><title>" . $PAGE_NAME . "</title></head>";
print "<body>";
print '<div><a href="class_test.php">Class Test Master</a></div>';
print '<div><h1>' . $PAGE_NAME . '</h1></div>';
// fputcsv
print "<h3>\CoreLibs\DeprecatedHelper\Deprecated84::fputcsv()</h3>";
$test_csv = BASE . TMP . 'DeprecatedHelper.test.csv';
print "File: $test_csv<br>";
$fp = fopen($test_csv, "w");
if (!is_resource($fp)) {
die("Cannot open file: $test_csv");
}
\CoreLibs\DeprecatedHelper\Deprecated84::fputcsv($fp, ["A", "B", "C"]);
fclose($fp);
$fp = fopen($test_csv, "r");
if (!is_resource($fp)) {
die("Cannot open file: $test_csv");
}
while ($entry = \CoreLibs\DeprecatedHelper\Deprecated84::fgetcsv($fp)) {
print "fgetcsv: <pre>" . print_r($entry, true) . "</pre>";
}
fclose($fp);
$out = \CoreLibs\DeprecatedHelper\Deprecated84::str_getcsv("A,B,C");
print "str_getcsv: <pre>" . print_r($out, true) . "</pre>";
/**
* temporary different CSV function, because fgetcsv seems to be broken on some systems
* (does not read out japanese text)
*
* @param string $string full line for csv split
* @param string $encoding optional, if given, converts string to the internal encoding
* before we do anything
* @param string $delimiter sepperate character, default ','
* @param string $enclosure string line marker, default '"'
* @param string $flag INTERN | EXTERN. if INTERN uses the PHP function, else uses explode
* @return array<int,string|null> array with split data from input line
*/
function mtParseCSV(
string $string,
string $encoding = '',
string $delimiter = ',',
string $enclosure = '"',
string $flag = 'INTERN'
): array {
$lines = [];
if ($encoding) {
$string = \CoreLibs\Convert\Encoding::convertEncoding(
$string,
'UTF-8',
$encoding
);
if ($string === false) {
return $lines;
}
}
if ($flag == 'INTERN') {
// split with PHP function
$lines = str_getcsv($string, $delimiter, $enclosure);
} else {
// split up with delimiter
$lines = explode(',', $string) ?: [];
}
// strip " from beginning and end of line
for ($i = 0; $i < count($lines); $i++) {
// remove line breaks
$lines[$i] = preg_replace("/\r\n?/", '', (string)$lines[$i]) ?? '';
// lingering " at the beginning and end of the line
$lines[$i] = preg_replace("/^\"/", '', (string)$lines[$i]) ?? '';
$lines[$i] = preg_replace("/\"$/", '', (string)$lines[$i]) ?? '';
}
return $lines;
}
print "</body></html>";
// __END__

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -18,7 +18,6 @@ require 'config.php';
$LOG_FILE_ID = 'classTest-encryption'; $LOG_FILE_ID = 'classTest-encryption';
ob_end_flush(); ob_end_flush();
use CoreLibs\Security\AsymmetricAnonymousEncryption;
use CoreLibs\Security\SymmetricEncryption; use CoreLibs\Security\SymmetricEncryption;
use CoreLibs\Security\CreateKey; use CoreLibs\Security\CreateKey;
@@ -37,8 +36,6 @@ print "<body>";
print '<div><a href="class_test.php">Class Test Master</a></div>'; print '<div><a href="class_test.php">Class Test Master</a></div>';
print '<div><h1>' . $PAGE_NAME . '</h1></div>'; print '<div><h1>' . $PAGE_NAME . '</h1></div>';
print "<h2>Symmetric Encryption</h2>";
$key = CreateKey::generateRandomKey(); $key = CreateKey::generateRandomKey();
print "Secret Key: " . $key . "<br>"; print "Secret Key: " . $key . "<br>";
@@ -108,49 +105,6 @@ try {
// $encrypted = $se->encrypt($string); // $encrypted = $se->encrypt($string);
// $decrypted = $se->decrypt($encrypted); // $decrypted = $se->decrypt($encrypted);
echo "<hr>";
print "<h2>Asymmetric Encryption</h2>";
$key_pair = CreateKey::createKeyPair();
$public_key = CreateKey::getPublicKey($key_pair);
$string = "I am some asymmetric secret";
print "Message: " . $string . "<br>";
$encrypted = sodium_crypto_box_seal($string, CreateKey::hex2bin($public_key));
$message = sodium_bin2base64($encrypted, SODIUM_BASE64_VARIANT_ORIGINAL);
print "Encrypted PL: " . $message . "<br>";
$result = sodium_base642bin($message, SODIUM_BASE64_VARIANT_ORIGINAL);
$decrypted = sodium_crypto_box_seal_open($result, CreateKey::hex2bin($key_pair));
print "Decrypted PL: " . $decrypted . "<br>";
$encrypted = AsymmetricAnonymousEncryption::encryptKey($string, $public_key);
print "Encrypted ST: " . $encrypted . "<br>";
$decrypted = AsymmetricAnonymousEncryption::decryptKey($encrypted, $key_pair);
print "Decrypted ST: " . $decrypted . "<br>";
$aa_crypt = new AsymmetricAnonymousEncryption($key_pair, $public_key);
$encrypted = $aa_crypt->encrypt($string);
print "Encrypted: " . $encrypted . "<br>";
$decrypted = $aa_crypt->decrypt($encrypted);
print "Decrypted: " . $decrypted . "<br>";
print "Base64 encode: " . base64_encode('Some text here') . "<Br>";
/// this has to fail
$crypt = new AsymmetricAnonymousEncryption();
$crypt->setPublicKey(CreateKey::getPublicKey(CreateKey::createKeyPair()));
print "Public Key: " . $crypt->getPublicKey() . "<br>";
try {
$crypt->setPublicKey(CreateKey::createKeyPair());
} catch (RangeException $e) {
print "Invalid range: <pre>$e</pre>";
}
try {
$crypt->setKeyPair(CreateKey::getPublicKey(CreateKey::createKeyPair()));
} catch (RangeException $e) {
print "Invalid range: <pre>$e</pre>";
}
print "</body></html>"; print "</body></html>";
// __END__ // __END__

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -40,8 +40,6 @@ print "Log ERROR: " . $log->prAr($em->getFlagLogError()) . "<br>";
print "FN: " . ml::fromName('Affe')->name . "<br>"; print "FN: " . ml::fromName('Affe')->name . "<br>";
print "NU: " . ml::fromValue(100)->name . "<br>"; print "NU: " . ml::fromValue(100)->name . "<br>";
print "NU: " . ml::fromValue(1000)->name . "<br>"; print "NU: " . ml::fromValue(1000)->name . "<br>";
print "OK.: " . ml::ok->name . "<br>";
print "OK^: " . ml::fromName('OK')->name . "<br>";
$em->setErrorMsg('123', 'error', 'msg this is bad, auto logged if debug'); $em->setErrorMsg('123', 'error', 'msg this is bad, auto logged if debug');
$em->setErrorMsg('123', 'error', 'msg this is bad, auto logged if debug', 'target-id', 'other-style'); $em->setErrorMsg('123', 'error', 'msg this is bad, auto logged if debug', 'target-id', 'other-style');
@@ -58,14 +56,6 @@ $em->setErrorMsg('100-2', 'error', 'Input wring', jump_target:['target' => 'foo-
$em->setMessage('error', 'I have no id set', jump_target:['target' => 'bar-123', 'info' => 'Jump Bar']); $em->setMessage('error', 'I have no id set', jump_target:['target' => 'bar-123', 'info' => 'Jump Bar']);
$em->setMessage('error', 'Jump empty', jump_target:['target' => 'bar-empty']); $em->setMessage('error', 'Jump empty', jump_target:['target' => 'bar-empty']);
function inLine(\CoreLibs\Logging\ErrorMessage $em): void
{
$em->log->error('Direct log before from ', context:['function' => __FUNCTION__]);
$em->setMessage('error', 'Inline call', context:['test' => 'inLine Function']);
$em->log->error('Direct log from ', context:['function' => __FUNCTION__]);
}
inLine($em);
print "ErrorsLast: <pre>" . $log->prAr($em->getLastErrorMsg()) . "</pre>"; print "ErrorsLast: <pre>" . $log->prAr($em->getLastErrorMsg()) . "</pre>";
print "ErrorsIds: <pre>" . $log->prAr($em->getErrorIds()) . "</pre>"; print "ErrorsIds: <pre>" . $log->prAr($em->getErrorIds()) . "</pre>";
print "Errors: <pre>" . $log->prAr($em->getErrorMsg()) . "</pre>"; print "Errors: <pre>" . $log->prAr($em->getErrorMsg()) . "</pre>";

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -19,7 +19,6 @@ $LOG_FILE_ID = 'classTest-hash';
ob_end_flush(); ob_end_flush();
use CoreLibs\Create\Hash; use CoreLibs\Create\Hash;
use CoreLibs\Security\CreateKey;
$log = new CoreLibs\Logging\Logging([ $log = new CoreLibs\Logging\Logging([
'log_folder' => BASE . LOG, 'log_folder' => BASE . LOG,
@@ -39,66 +38,28 @@ print '<div><h1>' . $PAGE_NAME . '</h1></div>';
$to_crc = 'Some text block'; $to_crc = 'Some text block';
// static // static
print "S::__CRC32B: $to_crc: " . Hash::__crc32b($to_crc) . "<br>"; print "S::__CRC32B: $to_crc: " . $hash_class::__crc32b($to_crc) . "<br>";
// print "S::__SHA1SHORT(off): $to_crc: " . Hash::__sha1short($to_crc) . "<br>"; print "S::__SHA1SHORT(off): $to_crc: " . $hash_class::__sha1short($to_crc) . "<br>";
print "S::hashShort(__sha1Short replace): $to_crc: " . Hash::hashShort($to_crc) . "<br>"; print "S::__SHA1SHORT(on): $to_crc: " . $hash_class::__sha1short($to_crc, true) . "<br>";
// print "S::__SHA1SHORT(on): $to_crc: " . Hash::__sha1short($to_crc, true) . "<br>"; print "S::__hash(d): " . $to_crc . "/"
print "S::sha1Short(__sha1Short replace): $to_crc: " . Hash::sha1Short($to_crc) . "<br>"; . Hash::STANDARD_HASH_SHORT . ": " . $hash_class::__hash($to_crc) . "<br>";
// print "S::__hash(d): " . $to_crc . "/" foreach (['adler32', 'fnv132', 'fnv1a32', 'joaat', 'sha512'] as $__hash_c) {
// . Hash::STANDARD_HASH_SHORT . ": " . $hash_class::__hash($to_crc) . "<br>"; print "S::__hash($__hash_c): $to_crc: " . $hash_class::__hash($to_crc, $__hash_c) . "<br>";
$to_crc_list = [
'Some text block',
'Some String Text',
'any string',
];
foreach ($to_crc_list as $__to_crc) {
foreach (['adler32', 'fnv132', 'fnv1a32', 'joaat', 'ripemd160', 'sha256', 'sha512'] as $__hash_c) {
print "Hash::hash($__hash_c): $__to_crc: " . Hash::hash($to_crc, $__hash_c) . "<br>";
}
} }
// static use // static use
print "U-S::__CRC32B: $to_crc: " . Hash::__crc32b($to_crc) . "<br>"; print "U-S::__CRC32B: $to_crc: " . Hash::__crc32b($to_crc) . "<br>";
echo "<hr>"; echo "<hr>";
$text = 'Some String Text'; $text = 'Some String Text';
// $text = 'any string';
$type = 'crc32b'; $type = 'crc32b';
print "Hash: " . $type . ": " . hash($type, $text) . "<br>"; print "Hash: " . $type . ": " . hash($type, $text) . "<br>";
// print "Class (old): " . $type . ": " . Hash::__hash($text, $type) . "<br>"; print "Class: " . $type . ": " . Hash::__hash($text, $type) . "<br>";
print "Class (new): " . $type . ": " . Hash::hash($text, $type) . "<br>";
echo "<hr>"; echo "<hr>";
print "CURRENT STANDARD_HASH_SHORT: " . Hash::STANDARD_HASH_SHORT . "<br>"; print "<br>CURRENT STANDARD_HASH_SHORT: " . Hash::STANDARD_HASH_SHORT . "<br>";
print "CURRENT STANDARD_HASH_LONG: " . Hash::STANDARD_HASH_LONG . "<br>"; print "<br>CURRENT STANDARD_HASH_LONG: " . Hash::STANDARD_HASH_LONG . "<br>";
print "CURRENT STANDARD_HASH: " . Hash::STANDARD_HASH . "<br>"; print "HASH SHORT: " . $to_crc . ": " . Hash::__hash($to_crc) . "<br>";
print "HASH SHORT: " . $to_crc . ": " . Hash::hashShort($to_crc) . "<br>"; print "HASH LONG: " . $to_crc . ": " . Hash::__hashLong($to_crc) . "<br>";
print "HASH LONG: " . $to_crc . ": " . Hash::hashLong($to_crc) . "<br>";
print "HASH DEFAULT: " . $to_crc . ": " . Hash::hashStd($to_crc) . "<br>";
echo "<hr>";
$key = CreateKey::generateRandomKey();
$key = "FIX KEY";
print "Secret Key: " . $key . "<br>";
print "HASHMAC DEFAULT (fix): " . $to_crc . ": " . Hash::hashHmac($to_crc, $key) . "<br>";
$key = CreateKey::generateRandomKey();
print "Secret Key: " . $key . "<br>";
print "HASHMAC DEFAULT (random): " . $to_crc . ": " . Hash::hashHmac($to_crc, $key) . "<br>";
echo "<hr>";
$hash_types = ['crc32b', 'sha256', 'invalid'];
foreach ($hash_types as $hash_type) {
echo "<b>Checking $hash_type:</b><br>";
if (Hash::isValidHashType($hash_type)) {
echo "hash type: $hash_type is valid<br>";
} else {
echo "hash type: $hash_type is INVALID<br>";
}
if (Hash::isValidHashHmacType($hash_type)) {
echo "hash hmac type: $hash_type is valid<br>";
} else {
echo "hash hmac type: $hash_type is INVALID<br>";
}
}
// print "UNIQU ID SHORT : " . Hash::__uniqId() . "<br>"; // print "UNIQU ID SHORT : " . Hash::__uniqId() . "<br>";
// print "UNIQU ID LONG : " . Hash::__uniqIdLong() . "<br>"; // print "UNIQU ID LONG : " . Hash::__uniqIdLong() . "<br>";

Some files were not shown because too many files have changed in this diff Show More