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
455 changed files with 38973 additions and 23536 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'
}
};

5
.gitignore vendored
View File

@@ -3,8 +3,3 @@ node_modules/
composer.lock
vendor/
tools/
www/composer.lock
www/vendor
**/.env
**/.target
package-lock.json

View File

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

View File

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

View File

@@ -1,100 +1,5 @@
#!/bin/env bash
function error() {
if [ -t 1 ]; then echo "[MAK] ERROR: $*" >&2; fi; exit 0;
}
usage() {
cat <<EOF
Usage: $(basename "${BASH_SOURCE[0]}") [-h] [-p VERSION]
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 phan";
else
echo "Use phan installed via phives";
fi;
if [ ! -f "${php_bin}" ]; then
echo "Set php ${php_bin} does not exist";
exit;
fi;
base="/storage/var/www/html/developers/clemens/core_data/php_libraries/trunk/";
# must be run in ${base}
cd "$BASE_PATH" || exit;
export PHAN_DISABLE_XDEBUG_WARN=1;
PHAN_CALL=(
"${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__
cd $base;
${base}tools/phan --progress-bar -C --analyze-twice;
cd ~;

View File

@@ -1,92 +1,5 @@
#!/bin/env bash
function error() {
if [ -t 1 ]; then echo "[MAK] ERROR: $*" >&2; fi; exit 0;
}
usage() {
cat <<EOF
Usage: $(basename "${BASH_SOURCE[0]}") [-h] [-p VERSION]
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 phan";
else
echo "Use phan installed via phives";
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;
base="/storage/var/www/html/developers/clemens/core_data/php_libraries/trunk/";
# must be run in ${base}
cd $base;
${base}tools/phpstan;
cd ~;

View File

@@ -1,119 +1,49 @@
#!/bin/env bash
function error() {
if [ -t 1 ]; then echo "[MAK] ERROR: $*" >&2; fi; exit 0;
}
usage() {
cat <<EOF
Usage: $(basename "${BASH_SOURCE[0]}") [-h] [-t] [-v] [-p VERSION]
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
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;
base="/storage/var/www/html/developers/clemens/core_data/php_libraries/trunk/";
# -c phpunit.xml
# --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
# 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_verbose="";
php_version="";
no_php_version=0;
use_composer=0;
while [ -n "${1-}" ]; do
if [ "${1}" = "t" ] || [ "${2}" = "t" ]; then
opt_testdox="--testdox";
fi;
php_bin="";
if [ -n "${1}" ]; then
case "${1}" in
-t | --testdox)
opt_testdox="--testdox";
;;
-v | --verbose)
opt_verbose="--verbose";
;;
-c | --composer)
use_composer=1;
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;
# "7.3") php_bin="/usr/bin/php7.3 "; ;;
# "7.4") php_bin="/usr/bin/php7.4 "; ;;
# "8.0") php_bin="/usr/bin/php8.0 "; ;;
# "8.1") php_bin="/usr/bin/php8.1 "; ;;
"8.2") php_bin="/usr/bin/php8.2 "; ;;
"8.3") php_bin="/usr/bin/php8.4 "; ;;
*) echo "Not support PHP: ${1}"; exit; ;;
esac;
fi;
php_bin="${PHP_BIN_PATH}${php_version}";
echo "Use PHP Version: ${php_version}";
if [ "${use_composer}" -eq 1 ]; then
echo "Use composer installed phan";
else
echo "Use phan installed via phives";
fi;
if [ ! -f "${php_bin}" ]; then
echo "Set php ${php_bin} does not exist";
exit;
if [ -n "${2}" ] && [ -z "${php_bin}" ]; then
case "${2}" in
# "7.3") php_bin="/usr/bin/php7.3 "; ;;
# "7.4") php_bin="/usr/bin/php7.4 "; ;;
# "8.0") php_bin="/usr/bin/php8.0 "; ;;
# "8.1") php_bin="/usr/bin/php8.1 "; ;;
"8.2") php_bin="/usr/bin/php8.2 "; ;;
"8.3") php_bin="/usr/bin/php8.3 "; ;;
*) echo "Not support PHP: ${1}"; exit; ;;
esac;
fi;
# Note 4dev/tests/bootstrap.php has to be set as bootstrap file in phpunit.xml
PHPUNIT_CALL=(
"${php_bin}"
);
if [ "${use_composer}" -eq 1 ]; then
PHPUNIT_CALL+=("${BASE_PATH}vendor/bin/phpunit");
else
PHPUNIT_CALL+=("${BASE_PATH}tools/phpunit");
fi;
PHPUNIT_CALL+=(
"${opt_testdox}"
"${opt_verbose}"
"-c" "${PHPUNIT_CONFIG}"
"${BASE_PATH}4dev/tests/"
);
"${PHPUNIT_CALL[@]}" || exit;
phpunit_call="${php_bin}${base}tools/phpunit ${opt_testdox} -c ${base}phpunit.xml ${base}4dev/tests/";
echo -e "\nPHPUnit Config: ${PHPUNIT_CONFIG}";
if [ "${no_php_version}" -eq 0 ]; then
echo "*** CALLED WITH PHP ${php_bin} ***";
${php_bin} --version;
${phpunit_call};
if [ ! -z "${php_bin}" ]; then
echo "CALLED WITH PHP: ${php_bin}"$(${php_bin} --version);
else
echo "Default PHP used: $(php --version)";
echo "Default PHP used: "$(php --version);
fi;
# __END__

View File

@@ -13,7 +13,7 @@ if [ "${GO}" != "go" ]; then
fi;
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/"
rsync ${DRY_RUN}-Plzvrupt --stats --delete ${SOURCE}4dev/tests/ ${TARGET}test/phpunit/

View File

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

View File

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

View File

@@ -8,12 +8,12 @@ DECLARE
random_length INT = 32; -- long for massive data
BEGIN
IF TG_OP = 'INSERT' THEN
NEW.date_created := clock_timestamp();
NEW.date_created := 'now';
IF NEW.uid IS NULL THEN
NEW.uid := random_string(random_length);
END IF;
ELSIF TG_OP = 'UPDATE' THEN
NEW.date_updated := clock_timestamp();
NEW.date_updated := 'now';
END IF;
RETURN NEW;
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;
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,
protected SMALLINT DEFAULT 0,
deleted SMALLINT DEFAULT 0,

View File

@@ -7,7 +7,7 @@
-- DROP 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,
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,

View File

@@ -8,7 +8,7 @@
-- DROP 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,
level SMALLINT,
type VARCHAR,

View File

@@ -7,7 +7,7 @@
-- DROP 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,
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,

View File

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

View File

@@ -7,7 +7,7 @@
-- DROP 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,
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,

View File

@@ -8,7 +8,7 @@
-- DROP 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,
lang_default SMALLINT NOT NULL DEFAULT 0,
long_name VARCHAR,

View File

@@ -7,54 +7,35 @@
-- DROP 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
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,
-- DEPRECATED [password]
password VARCHAR,
ip_address JSONB, -- REMOTE_IP and all other IPs (X_FORWARD, etc) as JSON block
-- DEPRECATED [ip]
ip VARCHAR, -- just the REMOTE_IP, full set see ip_address
-- string blocks, general
event_date TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
ip VARCHAR,
error TEXT,
event TEXT,
-- bytea or string type storage of any data
data_binary BYTEA,
data TEXT,
-- set page name only
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,
referer VARCHAR,
script_name VARCHAR,
query_string VARCHAR,
request_scheme VARCHAR, -- http or https
server_name VARCHAR,
http_host VARCHAR,
http_data JSONB,
-- DEPRECATED [http*]
http_accept VARCHAR, -- in http_data
http_accept_charset VARCHAR, -- in http_data
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
http_accept VARCHAR,
http_accept_charset VARCHAR,
http_accept_encoding VARCHAR,
session_id VARCHAR
) INHERITS (edit_generic) WITHOUT OIDS;

View File

@@ -7,8 +7,10 @@
-- DROP 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,
flag VARCHAR,
order_number INT NOT NULL
) INHERITS (edit_generic) WITHOUT OIDS;

View File

@@ -7,7 +7,7 @@
-- DROP 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
FOREIGN KEY (content_alias_edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE RESTRICT ON UPDATE CASCADE,
filename VARCHAR,

View File

@@ -7,7 +7,7 @@
-- DROP 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,
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,
@@ -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,
enabled SMALLINT NOT NULL DEFAULT 0
) INHERITS (edit_generic) WITHOUT OIDS;

View File

@@ -8,7 +8,7 @@
-- DROP 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,
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,

View File

@@ -7,7 +7,7 @@
-- DROP 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,
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,

View File

@@ -7,7 +7,7 @@
-- DROP 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,
name VARCHAR,
header_color VARCHAR,

View File

@@ -7,7 +7,7 @@
-- DROP 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
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,
@@ -35,10 +35,11 @@ CREATE TABLE edit_user (
strict SMALLINT DEFAULT 0,
locked SMALLINT 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
admin SMALLINT NOT NULL DEFAULT 0,
-- force lgout counter
force_logout INT DEFAULT 0,
-- last login log
last_login TIMESTAMP WITHOUT TIME ZONE,
-- 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.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.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.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.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';

View File

@@ -7,7 +7,7 @@
-- DROP 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,
flag VARCHAR
) INHERITS (edit_generic) WITHOUT OIDS;

View File

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

View File

@@ -24,12 +24,12 @@ final class CoreLibsCheckEmailTest extends TestCase
'get email regex invalid -1, will be 0' => [
-1,
"^[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' => [
10,
"^[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' => [
1,
@@ -157,7 +157,7 @@ final class CoreLibsCheckEmailTest extends TestCase
'error' => 0,
'message' => 'Invalid email address',
'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' => [
@@ -181,7 +181,7 @@ final class CoreLibsCheckEmailTest extends TestCase
[
'error' => 3,
'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' => [
@@ -189,7 +189,7 @@ final class CoreLibsCheckEmailTest extends TestCase
[
'error' => 4,
'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' => [
@@ -197,7 +197,7 @@ final class CoreLibsCheckEmailTest extends TestCase
[
'error' => 5,
'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' => [

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

@@ -926,114 +926,48 @@ final class CoreLibsCombinedDateTimeTest extends TestCase
public function daysIntervalProvider(): array
{
return [
// normal and format tests
'valid interval / not named array' => [
'input_a' => '2020/1/1',
'input_b' => '2020/1/30',
'return_named' => false, // return_named
'include_end_date' => true, // include_end_date
'exclude_start_date' => false, // exclude_start_date
'expected' => [30, 22, 8, false],
'valid interval /, not named array' => [
'2020/1/1',
'2020/1/30',
false,
[29, 22, 8],
],
'valid interval / named array' => [
'input_a' => '2020/1/1',
'input_b' => '2020/1/30',
'return_named' => true,
'include_end_date' => true,
'exclude_start_date' => false,
'expected' => ['overall' => 30, 'weekday' => 22, 'weekend' => 8, 'reverse' => false],
'valid interval /, named array' => [
'2020/1/1',
'2020/1/30',
true,
['overall' => 29, 'weekday' => 22, 'weekend' => 8],
],
'valid interval with "-"' => [
'input_a' => '2020-1-1',
'input_b' => '2020-1-30',
'return_named' => false,
'include_end_date' => true,
'exclude_start_date' => false,
'expected' => [30, 22, 8, false],
'valid interval -' => [
'2020-1-1',
'2020-1-30',
false,
[29, 22, 8],
],
'valid interval switched' => [
'2020/1/30',
'2020/1/1',
false,
[28, 0, 0],
],
'valid interval with time' => [
'input_a' => '2020/1/1 12:12:12',
'input_b' => '2020/1/30 13:13:13',
'return_named' => false,
'include_end_date' => true,
'exclude_start_date' => false,
'expected' => [30, 22, 8, false],
'2020/1/1 12:12:12',
'2020/1/30 13:13:13',
false,
[28, 21, 8],
],
// invalid
'invalid dates' => [
'input_a' => 'abc',
'input_b' => 'xyz',
'return_named' => false,
'include_end_date' => true,
'exclude_start_date' => false,
'expected' => [0, 0, 0, false]
'abc',
'xyz',
false,
[0, 0, 0]
],
// this test will take a long time
// this test will take a long imte
'out of bound dates' => [
'input_a' => '1900-1-1',
'input_b' => '9999-12-31',
'return_named' => false,
'include_end_date' => true,
'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],
'1900-1-1',
'9999-12-31',
false,
[2958463,2113189,845274],
],
];
}
@@ -1048,52 +982,20 @@ final class CoreLibsCombinedDateTimeTest extends TestCase
*
* @param string $input_a
* @param string $input_b
* @param bool $return_named
* @param array $expected
* @param bool $flag
* @param array $expected
* @return void
*/
public function testCalcDaysInterval(
string $input_a,
string $input_b,
bool $return_named,
bool $include_end_date,
bool $exclude_start_date,
bool $flag,
$expected
): void {
$this->assertEquals(
$expected,
\CoreLibs\Combined\DateTime::calcDaysInterval(
$input_a,
$input_b,
return_named:$return_named,
include_end_date:$include_end_date,
exclude_start_date:$exclude_start_date
),
'call calcDaysInterval'
\CoreLibs\Combined\DateTime::calcDaysInterval($input_a, $input_b, $flag)
);
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'
);
}
}
/**
@@ -1285,38 +1187,7 @@ final class CoreLibsCombinedDateTimeTest extends TestCase
'2023-07-03',
'2023-07-27',
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',
5 => '1.02KiB',
],
'invalid string number' => [
'invalud string number' => [
0 => '1024 MB',
1 => '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
*
@@ -139,7 +180,7 @@ final class CoreLibsConvertByteTest extends TestCase
* @return void
*/
public function testHumanReadableByteFormat(
string|int|float $input,
$input,
string $expected,
string $expected_si,
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
*
@@ -253,22 +227,10 @@ final class CoreLibsConvertByteTest extends TestCase
* @param string|int|float $input
* @param string|int|float $expected
* @param string|int|float $expected_si
* @param string|int|float $expected_string
* @param string|int|float $expected_string_si
* @param ?string $exception
* @return void
*/
public function testStringByteFormat(
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);
}
public function testStringByteFormat($input, $expected, $expected_si): void
{
$this->assertEquals(
$expected,
\CoreLibs\Convert\Byte::stringByteFormat($input)
@@ -277,17 +239,6 @@ final class CoreLibsConvertByteTest extends TestCase
$expected_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
* @coversDefaultClass \CoreLibs\Convert\Colors
* @testdox \CoreLibs\Convert\Colors legacy method tests
* @testdox \CoreLibs\Convert\Colors method tests
*/
final class CoreLibsConvertColorsTest extends TestCase
{
@@ -21,7 +21,7 @@ final class CoreLibsConvertColorsTest extends TestCase
*
* @return array
*/
public function providerRgb2hexColor(): array
public function rgb2hexColorProvider(): array
{
return [
'color' => [
@@ -88,7 +88,7 @@ final class CoreLibsConvertColorsTest extends TestCase
*
* @return array
*/
public function providerHex2rgbColor(): array
public function hex2rgbColorProvider(): array
{
return [
'color' => [
@@ -215,7 +215,7 @@ final class CoreLibsConvertColorsTest extends TestCase
*
* @return array
*/
public function providerRgb2hsbColor(): array
public function rgb2hsbColorProvider(): array
{
$list = [];
foreach ($this->rgb2hslAndhsbList() as $name => $values) {
@@ -234,7 +234,7 @@ final class CoreLibsConvertColorsTest extends TestCase
*
* @return array
*/
public function providerHsb2rgbColor(): array
public function hsb2rgbColorProvider(): array
{
$list = [];
foreach ($this->rgb2hslAndhsbList() as $name => $values) {
@@ -253,7 +253,7 @@ final class CoreLibsConvertColorsTest extends TestCase
*
* @return array
*/
public function providerRgb2hslColor(): array
public function rgb2hslColorProvider(): array
{
$list = [];
foreach ($this->rgb2hslAndhsbList() as $name => $values) {
@@ -272,7 +272,7 @@ final class CoreLibsConvertColorsTest extends TestCase
*
* @return array
*/
public function providerHsl2rgbColor(): array
public function hsl2rgbColorProvider(): array
{
$list = [];
foreach ($this->rgb2hslAndhsbList() as $name => $values) {
@@ -291,7 +291,7 @@ final class CoreLibsConvertColorsTest extends TestCase
* TODO: add cross convert check
*
* @covers ::rgb2hex
* @dataProvider providerRgb2hexColor
* @dataProvider rgb2hexColorProvider
* @testdox rgb2hex $input_r,$input_g,$input_b will be $expected [$_dataName]
*
* @param int $input_r
@@ -342,7 +342,7 @@ final class CoreLibsConvertColorsTest extends TestCase
* Undocumented function
*
* @covers ::hex2rgb
* @dataProvider providerHex2rgbColor
* @dataProvider hex2rgbColorProvider
* @testdox hex2rgb $input will be $expected, $expected_str str[,], $expected_str_sep str[$separator] [$_dataName]
*
* @param string $input
@@ -385,7 +385,7 @@ final class CoreLibsConvertColorsTest extends TestCase
* Undocumented function
*
* @covers ::rgb2hsb
* @dataProvider providerRgb2hsbColor
* @dataProvider rgb2hsbColorProvider
* @testdox rgb2hsb $input_r,$input_g,$input_b will be $expected [$_dataName]
*
* @param integer $input_r
@@ -409,7 +409,7 @@ final class CoreLibsConvertColorsTest extends TestCase
* Undocumented function
*
* @covers ::hsb2rgb
* @dataProvider providerHsb2rgbColor
* @dataProvider hsb2rgbColorProvider
* @testdox hsb2rgb $input_h,$input_s,$input_b will be $expected [$_dataName]
*
* @param float $input_h
@@ -434,7 +434,7 @@ final class CoreLibsConvertColorsTest extends TestCase
* Undocumented function
*
* @covers ::rgb2hsl
* @dataProvider providerRgb2hslColor
* @dataProvider rgb2hslColorProvider
* @testdox rgb2hsl $input_r,$input_g,$input_b will be $expected [$_dataName]
*
* @param integer $input_r
@@ -458,7 +458,7 @@ final class CoreLibsConvertColorsTest extends TestCase
* Undocumented function
*
* @covers ::hsl2rgb
* @dataProvider providerHsl2rgbColor
* @dataProvider hsl2rgbColorProvider
* @testdox hsl2rgb $input_h,$input_s,$input_l will be $expected [$_dataName]
*
* @param integer|float $input_h

View File

@@ -18,7 +18,7 @@ final class CoreLibsConvertMathTest extends TestCase
*
* @return array<mixed>
*/
public function providerFceil(): array
public function fceilProvider(): array
{
return [
'5.5 must be 6' => [5.5, 6],
@@ -31,7 +31,7 @@ final class CoreLibsConvertMathTest extends TestCase
* Undocumented function
*
* @covers ::fceil
* @dataProvider providerFceil
* @dataProvider fceilProvider
* @testdox fceil: Input $input must be $expected
*
* @param float $input
@@ -51,7 +51,7 @@ final class CoreLibsConvertMathTest extends TestCase
*
* @return array<mixed>
*/
public function providerFloor(): array
public function floorProvider(): array
{
return [
'5123456 with -3 must be 5123000' => [5123456, -3, 5123000],
@@ -63,7 +63,7 @@ final class CoreLibsConvertMathTest extends TestCase
* Undocumented function
*
* @covers ::floorp
* @dataProvider providerFloor
* @dataProvider floorProvider
* @testdox floor: Input $input with cutoff $cutoff must be $expected
*
* @param int $input
@@ -84,7 +84,7 @@ final class CoreLibsConvertMathTest extends TestCase
*
* @return array<mixed>
*/
public function providerInitNumeric(): array
public function initNumericProvider(): array
{
return [
'5 must be 5' => [5, 5, 'int'],
@@ -98,7 +98,7 @@ final class CoreLibsConvertMathTest extends TestCase
* Undocumented function
*
* @covers ::initNumeric
* @dataProvider providerInitNumeric
* @dataProvider initNumericProvider
* @testdox initNumeric: Input $info $input must match $expected [$_dataName]
*
* @param int|float|string $input
@@ -113,392 +113,6 @@ final class CoreLibsConvertMathTest extends TestCase
\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__

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
// 1: format
// 2: split characters as string, null for default
// 3: expected
return [
'all empty string' => [
'',
'',
null,
''
],
'empty input string' => [
'',
'2-2',
null,
''
],
'empty format string string' => [
'1234',
'',
null,
'1234'
],
'string format match' => [
'1234',
'2-2',
null,
'12-34'
],
'string format trailing match' => [
'1234',
'2-2-',
null,
'12-34'
],
'string format leading match' => [
'1234',
'-2-2',
null,
'12-34'
],
'string format double inside match' => [
'1234',
'2--2',
null,
'12--34',
],
'string format short first' => [
'1',
'2-2',
null,
'1'
],
'string format match first' => [
'12',
'2-2',
null,
'12'
],
'string format short second' => [
'123',
'2-2',
null,
'12-3'
],
'string format too long' => [
'1234567',
'2-2',
null,
'12-34-567'
],
'string format invalid format string' => [
'1234',
'2_2',
null,
'1234'
],
'different split character' => [
'1234',
'2_2',
'_',
'12_34'
],
'mixed split characters' => [
'123456',
'2-2_2',
'-_',
'12-34_56'
],
'length mixed' => [
'ABCD12345568ABC13',
'2-4_5-2#4',
'-_#',
'AB-CD12_34556-8A#BC13'
],
'split with split chars in string' => [
'12-34',
'2-2',
null,
'12--3-4'
],
'mutltibyte string' => [
'あいうえ',
'2-2',
null,
'あいうえ'
],
'mutltibyte split string' => [
'1234',
'-',
null,
'1234'
],
];
}
@@ -109,137 +143,29 @@ final class CoreLibsConvertStringsTest extends TestCase
*
* @covers ::splitFormatString
* @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 $format
* @param string|null $split_characters
* @param string $expected
* @return void
*/
public function testSplitFormatString(
string $input,
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 $expected
): void {
if ($split_characters === null) {
$output = \CoreLibs\Convert\Strings::splitFormatStringFixed(
$output = \CoreLibs\Convert\Strings::splitFormatString(
$input,
$split_length
$format
);
} else {
$output = \CoreLibs\Convert\Strings::splitFormatStringFixed(
$output = \CoreLibs\Convert\Strings::splitFormatString(
$input,
$split_length,
$format,
$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
*
@@ -482,222 +378,6 @@ final class CoreLibsConvertStringsTest extends TestCase
\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'
);
}
}
// __END__

View File

@@ -21,10 +21,8 @@ final class CoreLibsCreateHashTest extends TestCase
public function hashData(): array
{
return [
'hash tests' => [
// this is the string
'any string' => [
'text' => 'Some String Text',
// hash list special
'crc32b_reverse' => 'c5c21d91', // crc32b (in revere)
'sha1Short' => '4d2bc9ba0', // sha1Short
// via hash
@@ -33,8 +31,6 @@ final class CoreLibsCreateHashTest extends TestCase
'fnv132' => '9df444f9', // hash: fnv132
'fnv1a32' => '2c5f91b9', // hash: fnv1a32
'joaat' => '50dab846', // hash: joaat
'ripemd160' => 'aeae3f041b20136451519edd9361570909300342', // hash: ripemd160,
'sha256' => '9055080e022f224fa835929b80582b3c71c672206fa3a49a87412c25d9d42ceb', // hash: sha256
]
];
}
@@ -85,7 +81,7 @@ final class CoreLibsCreateHashTest extends TestCase
{
$list = [];
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
if ($_hash_type === null) {
$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
*
@@ -156,13 +136,9 @@ final class CoreLibsCreateHashTest extends TestCase
/**
* Undocumented function
*
* phpcs:disable Generic.Files.LineLength
* @covers ::__sha1Short
* @covers ::__crc32b
* @covers ::sha1Short
* @dataProvider sha1ShortProvider
* @testdox __sha1Short/__crc32b/sha1short $input will be $expected (crc32b) and $expected_sha1 (sha1 short) [$_dataName]
* phpcs:enable Generic.Files.LineLength
* @testdox __sha1Short $input will be $expected (crc32b) and $expected_sha1 (sha1 short) [$_dataName]
*
* @param string $input
* @param string $expected
@@ -173,29 +149,16 @@ final class CoreLibsCreateHashTest extends TestCase
// uses crc32b
$this->assertEquals(
$expected,
\CoreLibs\Create\Hash::__sha1Short($input),
'__sha1Short depreacted'
\CoreLibs\Create\Hash::__sha1Short($input)
);
$this->assertEquals(
$expected,
\CoreLibs\Create\Hash::__sha1Short($input, false),
'__sha1Short (false) depreacted'
);
$this->assertEquals(
$expected,
\CoreLibs\Create\Hash::__crc32b($input),
'__crc32b'
\CoreLibs\Create\Hash::__sha1Short($input, false)
);
// sha1 type
$this->assertEquals(
$expected_sha1,
\CoreLibs\Create\Hash::__sha1Short($input, true),
'__sha1Short (true) depreacted'
);
$this->assertEquals(
$expected_sha1,
\CoreLibs\Create\Hash::sha1Short($input),
'sha1Short'
\CoreLibs\Create\Hash::__sha1Short($input, true)
);
}
@@ -203,10 +166,8 @@ final class CoreLibsCreateHashTest extends TestCase
* Undocumented function
*
* @covers ::__hash
* @covers ::hashShort
* @covers ::hashShort
* @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|null $hash_type
@@ -218,24 +179,12 @@ final class CoreLibsCreateHashTest extends TestCase
if ($hash_type === null) {
$this->assertEquals(
$expected,
\CoreLibs\Create\Hash::__hash($input),
'__hash'
);
$this->assertEquals(
$expected,
\CoreLibs\Create\Hash::hashShort($input),
'hashShort'
\CoreLibs\Create\Hash::__hash($input)
);
} else {
$this->assertEquals(
$expected,
\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'
\CoreLibs\Create\Hash::__hash($input, $hash_type)
);
}
}
@@ -244,9 +193,8 @@ final class CoreLibsCreateHashTest extends TestCase
* Undocumented function
*
* @covers ::__hashLong
* @covers ::hashLong
* @dataProvider hashLongProvider
* @testdox __hashLong/hashLong $input will be $expected [$_dataName]
* @testdox __hashLong $input will be $expected [$_dataName]
*
* @param string $input
* @param string $expected
@@ -258,168 +206,6 @@ final class CoreLibsCreateHashTest extends TestCase
$expected,
\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
*/
public function randomKeyGenProvider(): array
public function keyLenghtProvider(): array
{
return [
// just 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' => [
'valid key length' => [
0 => 6,
1 => 6,
1 => true,
2 => 6,
],
// just character set
'default key length, different char set A' => [
0 => \CoreLibs\Create\RandomKey::KEY_LENGTH_DEFAULT,
1 => \CoreLibs\Create\RandomKey::KEY_LENGTH_DEFAULT,
2 => [
'A', 'B', 'C'
],
'negative key length' => [
0 => -1,
1 => false,
2 => 4,
],
'different key length, different char set B' => [
0 => 16,
1 => 16,
2 => [
'A', 'B', 'C'
],
3 => [
'1', '2', '3'
]
'tpp big key length' => [
0 => 300,
1 => false,
2 => 4,
],
];
}
// Alternative more efficient version using strpos
/**
* check if all characters are in set
* Undocumented function
*
* @param string $input
* @param string $allowed_chars
* @return bool
* @return array
*/
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) {
return false;
}
/**
* 1
*
* @return array
*/
public function keepKeyLengthProvider(): array
{
return [
'set too large' => [
0 => 6,
1 => 300,
2 => 6,
],
'set too small' => [
0 => 8,
1 => -2,
2 => 8,
],
'change valid' => [
0 => 10,
1 => 6,
2 => 6,
]
];
}
/**
* run before each test and reset to default 4
*
* @before
*
* @return void
*/
public function resetKeyLength(): void
{
\CoreLibs\Create\RandomKey::setRandomKeyLength(4);
}
/**
* check that first length is 4
*
* @covers ::getRandomKeyLength
* @testWith [4]
* @testdox getRandomKeyLength on init will be $expected [$_dataName]
*
* @param integer $expected
* @return void
*/
public function testGetRandomKeyLengthInit(int $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Create\RandomKey::getRandomKeyLength()
);
}
/**
* Undocumented function
*
* @covers ::setRandomKeyLength
* @covers ::getRandomKeyLength
* @dataProvider keyLenghtProvider
* @testdox setRandomKeyLength $input will be $expected, compare to $compare [$_dataName]
*
* @param integer $input
* @param boolean $expected
* @param integer $compare
* @return void
*/
public function testSetRandomKeyLength(int $input, bool $expected, int $compare): void
{
// set
$this->assertEquals(
$expected,
\CoreLibs\Create\RandomKey::setRandomKeyLength($input)
);
// read test, if false, use compare check
if ($expected === false) {
$input = $compare;
}
return true;
$this->assertEquals(
$input,
\CoreLibs\Create\RandomKey::getRandomKeyLength()
);
}
/**
@@ -95,41 +163,43 @@ final class CoreLibsCreateRandomKeyTest extends TestCase
* @param integer $expected
* @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) {
$this->assertEquals(
$expected,
strlen(\CoreLibs\Create\RandomKey::randomKeyGen())
);
} elseif ($input !== null && !count($key_range)) {
$random_key = \CoreLibs\Create\RandomKey::randomKeyGen($input);
$this->assertTrue(
$this->allCharsInSet($random_key, $__key_data),
'Characters not valid'
);
} else {
$this->assertEquals(
$expected,
strlen($random_key),
'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'
strlen(\CoreLibs\Create\RandomKey::randomKeyGen($input))
);
}
}
/**
* Check that if set to n and then invalid, it keeps the previous one
* or if second change valid, second will be shown
*
* @covers ::setRandomKeyLength
* @dataProvider keepKeyLengthProvider
* @testdox keep setRandomKeyLength set with $input_valid and then $input_invalid will be $expected [$_dataName]
*
* @param integer $input_valid
* @param integer $input_invalid
* @param integer $expected
* @return void
*/
public function testKeepKeyLength(int $input_valid, int $input_invalid, int $expected): void
{
\CoreLibs\Create\RandomKey::setRandomKeyLength($input_valid);
\CoreLibs\Create\RandomKey::setRandomKeyLength($input_invalid);
$this->assertEquals(
$expected,
\CoreLibs\Create\RandomKey::getRandomKeyLength()
);
}
}
// __END__

View File

@@ -22,6 +22,7 @@ final class CoreLibsCreateSessionTest extends TestCase
public function sessionProvider(): array
{
// 0: session name as parameter or for GLOBAL value
// 1: type p: parameter, g: global, d: php.ini default
// 2: mock data as array
// checkCliStatus: true/false,
// getSessionStatus: PHP_SESSION_DISABLED for abort,
@@ -30,10 +31,13 @@ final class CoreLibsCreateSessionTest extends TestCase
// checkActiveSession: true/false, [1st call, 2nd call]
// getSessionId: string or false
// 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 [
'session parameter' => [
'sessionNameParameter',
'p',
[
'checkCliStatus' => false,
'getSessionStatus' => PHP_SESSION_NONE,
@@ -43,9 +47,12 @@ final class CoreLibsCreateSessionTest extends TestCase
],
'sessionNameParameter',
null,
null,
'',
],
'session globals' => [
'sessionNameGlobals',
'g',
[
'checkCliStatus' => false,
'getSessionStatus' => PHP_SESSION_NONE,
@@ -54,12 +61,13 @@ final class CoreLibsCreateSessionTest extends TestCase
'getSessionId' => '1234abcd4567'
],
'sessionNameGlobals',
[
'auto_write_close' => false,
],
null,
null,
'',
],
'auto write close' => [
'sessionNameAutoWriteClose',
'session name default' => [
'',
'd',
[
'checkCliStatus' => false,
'getSessionStatus' => PHP_SESSION_NONE,
@@ -67,10 +75,109 @@ final class CoreLibsCreateSessionTest extends TestCase
'checkActiveSession' => [false, true],
'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]
*
* @param string $input
* @param string $type
* @param array<mixed> $mock_data
* @param string $expected
* @param array<string,mixed> $options
* @param string|null $exception
* @param string $expected_error
* @return void
*/
public function testStartSession(
string $input,
string $type,
array $mock_data,
string $expected,
?array $options,
?string $exception,
?int $exception_code,
string $expected_error
): void {
// override expected
if ($type == 'd') {
$expected = ini_get('session.name');
}
/** @var \CoreLibs\Create\Session&MockObject $session_mock */
$session_mock = $this->createPartialMock(
\CoreLibs\Create\Session::class,
[
'checkCliStatus',
'getSessionStatus', 'checkActiveSession',
'getSessionId',
'checkCliStatus', 'getSessionStatus', 'checkActiveSession',
'setSessionName', 'startSessionCall', 'getSessionId',
'getSessionName'
]
);
@@ -119,8 +234,12 @@ final class CoreLibsCreateSessionTest extends TestCase
$mock_data['checkActiveSession'][0],
$mock_data['checkActiveSession'][1],
);
// dummy set for session name
$session_mock->method('setSessionName')->with($input)->willReturn($mock_data['setSessionName']);
// set session name & return bsed on request data
$session_mock->method('getSessionName')->willReturn($expected);
// will not return anything
$session_mock->method('startSessionCall');
// in test case only return string
// false: will return false
$session_mock->method('getSessionId')->willReturn($mock_data['getSessionId']);
@@ -128,7 +247,25 @@ final class CoreLibsCreateSessionTest extends TestCase
// regex for session id
$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
if (!empty($session_id)) {
$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
*
@@ -283,147 +347,109 @@ final class CoreLibsCreateSessionTest extends TestCase
*
* @return array
*/
public function providerSessionData(): array
public function sessionDataProvider(): array
{
return [
'test' => [
'foo',
'bar',
'bar',
null,
],
'int key test' => [
123,
'bar',
'bar',
\UnexpectedValueException::class
],
// more complex value tests
'array values' => [
'array',
[1, 2, 3],
[1, 2, 3],
null,
]
];
}
// NOTE: with auto start session, we cannot test this in the command line
/**
* method call test
*
* @covers ::set
* @covers ::get
* @covers ::isset
* @covers ::unset
* @dataProvider providerSessionData
* @testdox set/get/isset/unset $name with $input is $expected ($exception) [$_dataName]
* @covers ::setS
* @covers ::getS
* @covers ::issetS
* @covers ::unsetS
* @dataProvider sessionDataProvider
* @testdox setS/getS/issetS/unsetS $name with $input is $expected [$_dataName]
*
* @param string|int $name
* @param mixed $input
* @param mixed $expected
* @param ?mixed $exception
* @return void
*/
public function testMethodSetGet($name, $input, $expected, $exception): void
public function testMethodSetGet($name, $input, $expected): void
{
if (\CoreLibs\Get\System::checkCLI()) {
$this->markTestSkipped('Cannot run testMethodSetGet in CLI');
}
$session = new \CoreLibs\Create\Session('TEST_METHOD');
if ($expected !== null) {
$this->expectException($exception);
}
$session->set($name, $input);
$session = new \CoreLibs\Create\Session();
$session->setS($name, $input);
$this->assertEquals(
$expected,
$session->get($name),
$session->getS($name),
'method set assert'
);
// isset true
$this->assertTrue(
$session->isset($name),
$session->issetS($name),
'method isset assert ok'
);
$session->unset($name);
$session->unsetS($name);
$this->assertEquals(
'',
$session->get($name),
$session->getS($name),
'method unset assert'
);
// isset false
// iset false
$this->assertFalse(
$session->isset($name),
$session->issetS($name),
'method isset assert false'
);
}
/**
* Undocumented function
* magic call test
*
* @return array
*/
public function providerSessionDataMany(): array
{
return [
'valid set' => [
[
'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 ::__set
* @covers ::__get
* @covers ::__isset
* @covers ::__unset
* @dataProvider sessionDataProvider
* @testdox __set/__get/__iseet/__unset $name with $input is $expected [$_dataName]
*
* @covers ::setMany
* @covers ::getMany
* @dataProvider providerSessionDataMany
* @testdox setMany/getMany/unsetMany $set is $expected ($exception) [$_dataName]
*
* @param array<string|int,mixed> $set
* @param array<string,mixed> $expected
* @param ?mixed $exception
* @param string|int $name
* @param mixed $input
* @param mixed $expected
* @return void
*/
public function testMany($set, $expected, $exception): void
public function testMagicSetGet($name, $input, $expected): void
{
if (\CoreLibs\Get\System::checkCLI()) {
$this->markTestSkipped('Cannot run testMethodSetGet in CLI');
}
$session = new \CoreLibs\Create\Session('TEST_METHOD');
if ($expected !== null) {
$this->expectException($exception);
}
$session->setMany($set);
$session = new \CoreLibs\Create\Session();
$session->$name = $input;
$this->assertEquals(
$expected,
$session->getMany(array_keys($set)),
'set many failed'
$session->$name,
'magic set assert'
);
$session->unsetMany(array_keys($set));
// isset true
$this->assertTrue(
isset($session->$name),
'magic isset assert ok'
);
unset($session->$name);
$this->assertEquals(
[],
$session->getMany(array_keys($set)),
'unset many failed'
'',
$session->$name,
'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
{
if (\CoreLibs\Get\System::checkCLI()) {
$this->markTestSkipped('Cannot run testUnsetAll in CLI');
}
$test_values = [
'foo' => 'abc',
'bar' => '123'
];
$session = new \CoreLibs\Create\Session('TEST_UNSET');
$session = new \CoreLibs\Create\Session();
foreach ($test_values as $name => $value) {
$session->set($name, $value);
$session->setS($name, $value);
// confirm set
$this->assertEquals(
$value,
$session->get($name),
$session->getS($name),
'set assert: ' . $name
);
}
// unset all
$session->clear();
$session->unsetAllS();
// check unset
foreach (array_keys($test_values) as $name) {
$this->assertEquals(
'',
$session->get($name),
$session->getS($name),
'unsert assert: ' . $name
);
}

View File

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

View File

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

View File

@@ -17,7 +17,7 @@ Table with Primary Key: table_with_primary_key
Table without Primary Key: table_without_primary_key
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
row_int INT,
row_numeric NUMERIC,
@@ -37,9 +37,8 @@ namespace tests;
use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\MockObject\MockObject;
use CoreLibs\Logging;
use CoreLibs\Logging\Logger\Level;
use CoreLibs\DB\Options\Convert;
use CoreLibs\DB\Support\ConvertPlaceholder;
/**
* Test class for DB\IO + DB\SQL\PgSQL
@@ -118,7 +117,7 @@ final class CoreLibsDBIOTest extends TestCase
);
}
// 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' => DIRECTORY_SEPARATOR . 'tmp',
'log_file_id' => 'CoreLibs-DB-IO-Test',
@@ -135,7 +134,6 @@ final class CoreLibsDBIOTest extends TestCase
}
// check if they already exist, drop them
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_without_primary_key");
$db->dbExec("DROP TABLE test_meta");
@@ -163,9 +161,13 @@ final class CoreLibsDBIOTest extends TestCase
// primary key name is table + '_id'
<<<SQL
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
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(
<<<SQL
@@ -568,11 +570,11 @@ final class CoreLibsDBIOTest extends TestCase
);
$db->dbClose();
// second conenction with log set NOT debug
$log = new Logging\Logging([
$log = new \CoreLibs\Logging\Logging([
// 'log_folder' => __DIR__ . DIRECTORY_SEPARATOR . 'log',
'log_folder' => DIRECTORY_SEPARATOR . 'tmp',
'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(
self::$db_config[$connection],
@@ -3291,7 +3293,6 @@ final class CoreLibsDBIOTest extends TestCase
'query' => 'INSERT INTO table_with_primary_key (row_int, uid) '
. 'VALUES ($1, $2) RETURNING table_with_primary_key_id',
'returning_id' => true,
'placeholder_converted' => [],
],
],
// update
@@ -3326,7 +3327,6 @@ final class CoreLibsDBIOTest extends TestCase
'query' => 'UPDATE table_with_primary_key SET row_int = $1, '
. 'row_varchar = $2 WHERE uid = $3',
'returning_id' => false,
'placeholder_converted' => [],
],
],
// select
@@ -3356,7 +3356,6 @@ final class CoreLibsDBIOTest extends TestCase
'count' => 1,
'query' => 'SELECT row_int, uid FROM table_with_primary_key WHERE uid = $1',
'returning_id' => false,
'placeholder_converted' => [],
],
],
// any query but with no parameters
@@ -3389,7 +3388,6 @@ final class CoreLibsDBIOTest extends TestCase
'count' => 0,
'query' => 'SELECT row_int, uid FROM table_with_primary_key',
'returning_id' => false,
'placeholder_converted' => [],
],
],
// no statement name (25)
@@ -3413,7 +3411,6 @@ final class CoreLibsDBIOTest extends TestCase
'count' => 0,
'query' => '',
'returning_id' => false,
'placeholder_converted' => [],
],
],
// no query (prepare 11)
@@ -3438,7 +3435,6 @@ final class CoreLibsDBIOTest extends TestCase
'count' => 0,
'query' => '',
'returning_id' => false,
'placeholder_converted' => [],
],
],
// no db connection (prepare/execute 16)
@@ -3468,7 +3464,6 @@ final class CoreLibsDBIOTest extends TestCase
'count' => 0,
'query' => 'SELECT row_int, uid FROM table_with_primary_key',
'returning_id' => false,
'placeholder_converted' => [],
],
],
// prepare with different statement name
@@ -3494,7 +3489,6 @@ final class CoreLibsDBIOTest extends TestCase
'count' => 0,
'query' => 'SELECT row_int, uid FROM table_with_primary_key',
'returning_id' => false,
'placeholder_converted' => [],
],
],
// insert wrong data count compared to needed (execute 23)
@@ -3520,12 +3514,10 @@ final class CoreLibsDBIOTest extends TestCase
'query' => 'INSERT INTO table_with_primary_key (row_int, uid) VALUES '
. '($1, $2) RETURNING table_with_primary_key_id',
'returning_id' => true,
'placeholder_converted' => [],
],
],
// execute does not return a result (22)
// TODO execute does not return a result
// TODO prepared statement with placeholder params auto convert
];
}
@@ -3670,7 +3662,7 @@ final class CoreLibsDBIOTest extends TestCase
}
// check dbGetPrepareCursorValue
foreach (['pk_name', 'count', 'query', 'returning_id', 'placeholder_converted'] as $key) {
foreach (['pk_name', 'count', 'query', 'returning_id'] as $key) {
$this->assertEquals(
$prepare_cursor[$key],
$db->dbGetPrepareCursorValue($stm_name, $key),
@@ -3693,7 +3685,7 @@ final class CoreLibsDBIOTest extends TestCase
*
* @return array
*/
public function providerDbGetPrepareCursorValue(): array
public function preparedProviderValue(): array
{
// 1: query (can be empty for do not set)
// 2: stm name
@@ -3737,7 +3729,7 @@ final class CoreLibsDBIOTest extends TestCase
* test return prepare cursor errors
*
* @covers ::dbGetPrepareCursorValue
* @dataProvider providerDbGetPrepareCursorValue
* @dataProvider preparedProviderValue
* @testdox prepared query $stm_name with $key expect error id $error_id [$_dataName]
*
* @param string $query
@@ -3770,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
// dbGetSchema, dbSetSchema
@@ -4745,7 +4649,7 @@ final class CoreLibsDBIOTest extends TestCase
$res = $db->dbReturnRowParams($query_select, ['CONVERT_TYPE_TEST']);
// all hast to be string
foreach ($res as $key => $value) {
$this->assertIsString($value, 'Assert string for column: ' . $key);
$this->assertIsString($value, 'Aseert string for column: ' . $key);
}
// convert base only
$db->dbSetConvertFlag(Convert::on);
@@ -4758,10 +4662,10 @@ final class CoreLibsDBIOTest extends TestCase
}
switch ($type_layout[$name]) {
case 'int':
$this->assertIsInt($value, 'Assert int for column: ' . $key . '/' . $name);
$this->assertIsInt($value, 'Aseert int for column: ' . $key . '/' . $name);
break;
default:
$this->assertIsString($value, 'Assert string for column: ' . $key . '/' . $name);
$this->assertIsString($value, 'Aseert string for column: ' . $key . '/' . $name);
break;
}
}
@@ -4775,13 +4679,13 @@ final class CoreLibsDBIOTest extends TestCase
}
switch ($type_layout[$name]) {
case 'int':
$this->assertIsInt($value, 'Assert int for column: ' . $key . '/' . $name);
$this->assertIsInt($value, 'Aseert int for column: ' . $key . '/' . $name);
break;
case 'float':
$this->assertIsFloat($value, 'Assert float for column: ' . $key . '/' . $name);
$this->assertIsFloat($value, 'Aseert float for column: ' . $key . '/' . $name);
break;
default:
$this->assertIsString($value, 'Assert string for column: ' . $key . '/' . $name);
$this->assertIsString($value, 'Aseert string for column: ' . $key . '/' . $name);
break;
}
}
@@ -4795,17 +4699,17 @@ final class CoreLibsDBIOTest extends TestCase
}
switch ($type_layout[$name]) {
case 'int':
$this->assertIsInt($value, 'Assert int for column: ' . $key . '/' . $name);
$this->assertIsInt($value, 'Aseert int for column: ' . $key . '/' . $name);
break;
case 'float':
$this->assertIsFloat($value, 'Assert float for column: ' . $key . '/' . $name);
$this->assertIsFloat($value, 'Aseert float for column: ' . $key . '/' . $name);
break;
case 'json':
case 'jsonb':
$this->assertIsArray($value, 'Assert array for column: ' . $key . '/' . $name);
$this->assertIsArray($value, 'Aseert array for column: ' . $key . '/' . $name);
break;
default:
$this->assertIsString($value, 'Assert string for column: ' . $key . '/' . $name);
$this->assertIsString($value, 'Aseert string for column: ' . $key . '/' . $name);
break;
}
}
@@ -4819,25 +4723,25 @@ final class CoreLibsDBIOTest extends TestCase
}
switch ($type_layout[$name]) {
case 'int':
$this->assertIsInt($value, 'Assert int for column: ' . $key . '/' . $name);
$this->assertIsInt($value, 'Aseert int for column: ' . $key . '/' . $name);
break;
case 'float':
$this->assertIsFloat($value, 'Assert float for column: ' . $key . '/' . $name);
$this->assertIsFloat($value, 'Aseert float for column: ' . $key . '/' . $name);
break;
case 'json':
case 'jsonb':
$this->assertIsArray($value, 'Assert array for column: ' . $key . '/' . $name);
$this->assertIsArray($value, 'Aseert array for column: ' . $key . '/' . $name);
break;
case 'bytea':
// for hex types it must not start with \x
$this->assertStringStartsNotWith(
'\x',
$value,
'Assert bytes not starts with \x for column: ' . $key . '/' . $name
'Aseert bytes not starts with \x for column: ' . $key . '/' . $name
);
break;
default:
$this->assertIsString($value, 'Assert string for column: ' . $key . '/' . $name);
$this->assertIsString($value, 'Aseert string for column: ' . $key . '/' . $name);
break;
}
}
@@ -5009,8 +4913,8 @@ final class CoreLibsDBIOTest extends TestCase
)
),
($params === null ?
$db->dbBuildQueryHash($query) :
$db->dbBuildQueryHash($query, $params)
$db->dbGetQueryHash($query) :
$db->dbGetQueryHash($query, $params)
),
'Failed assertdbGetQueryHash '
);
@@ -5127,285 +5031,8 @@ final class CoreLibsDBIOTest extends TestCase
$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
{
// WHERE row_varchar = $1
@@ -5449,9 +5076,7 @@ final class CoreLibsDBIOTest extends TestCase
WHERE row_varchar = $1
SQL,
'expected_params' => ['string a'],
],
// TODO: test with multiple entries
// TODO: test with same entry ($1, $1, :var, :var)
]
];
}
@@ -5553,8 +5178,6 @@ final class CoreLibsDBIOTest extends TestCase
// - data debug
// dbDumpData
// MARK: ASYNC
// ASYNC at the end because it has 1s timeout
// - asynchronous executions
// dbExecAsync, dbCheckAsync

View File

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

View File

@@ -21,6 +21,341 @@ final class CoreLibsLanguageGetLocaleTest extends TestCase
. 'includes' . 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
*

View File

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

View File

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

View File

@@ -18,7 +18,7 @@ use CoreLibs\Logging\Logger\Flag;
final class CoreLibsLoggingLoggingTest extends TestCase
{
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
. "\[(phar:\/\/)?[\w\-\.\/]+:\d+\]\s{1}" // folder/file [note phar:// is for phpunit]
. "\[\w+\]\s{1}" // run id
@@ -249,7 +249,7 @@ final class CoreLibsLoggingLoggingTest extends TestCase
$this->assertFalse(
$log->loggingLevelIsDebug()
);
// not set, should be debug
// not set, should be debug]
$log = new \CoreLibs\Logging\Logging([
'log_file_id' => 'testSetLoggingLevel',
'log_folder' => self::LOG_FOLDER,
@@ -297,71 +297,6 @@ final class CoreLibsLoggingLoggingTest extends TestCase
$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
// getLogFileId
@@ -460,7 +395,7 @@ final class CoreLibsLoggingLoggingTest extends TestCase
}
$per_run_id = $log->getLogUniqueId();
$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,
'assert per log run id 1st'
);
@@ -468,7 +403,7 @@ final class CoreLibsLoggingLoggingTest extends TestCase
$log->setLogUniqueId(true);
$per_run_id_2nd = $log->getLogUniqueId();
$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,
'assert per log run id 2nd'
);
@@ -889,13 +824,13 @@ final class CoreLibsLoggingLoggingTest extends TestCase
$this->assertTrue($log_ok, 'assert ::log (debug) OK');
$this->assertEquals(
$log->getLogFile(),
$log->getLogFileId() . '.DEBUG.log'
$log->getLogFileId() . '_DEBUG.log'
);
$log_ok = $log->log(Level::Info, 'INFO', group_id: 'GROUP_ID', prefix: 'PREFIX:');
$this->assertTrue($log_ok, 'assert ::log (info) OK');
$this->assertEquals(
$log->getLogFile(),
$log->getLogFileId() . '.INFO.log'
$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
{
/**
* Undocumented function
*
* @return array
*/
public function passwordProvider(): array
{
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
{
return [
@@ -73,10 +63,6 @@ final class CoreLibsSecurityPasswordTest extends TestCase
*/
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(
$expected,
\CoreLibs\Security\Password::passwordRehashCheck($input)

View File

@@ -15,77 +15,6 @@ use CoreLibs\Security\SymmetricEncryption;
*/
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
*
@@ -127,24 +56,7 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
$decrypted,
'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
$encrypted = SymmetricEncryption::getInstance($key)->encrypt($input);
$decrypted = SymmetricEncryption::getInstance($key)->decrypt($encrypted);
@@ -153,24 +65,7 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
$decrypted,
'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
$encrypted = SymmetricEncryption::encryptKey($input, $key);
$decrypted = SymmetricEncryption::decryptKey($encrypted, $key);
@@ -182,8 +77,6 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
);
}
// MARK: invalid key
/**
* Undocumented function
*
@@ -221,51 +114,13 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
$crypt = new SymmetricEncryption($key);
$encrypted = $crypt->encrypt($input);
$this->expectExceptionMessage($exception_message);
$crypt->setKey($wrong_key);
$crypt->setKey($key);
$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
$encrypted = SymmetricEncryption::getInstance($key)->encrypt($input);
$this->expectExceptionMessage($exception_message);
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
$encrypted = SymmetricEncryption::encryptKey($input, $key);
@@ -273,8 +128,6 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
SymmetricEncryption::decryptKey($encrypted, $wrong_key);
}
// MARK: wrong key
/**
* Undocumented function
*
@@ -291,10 +144,6 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
'key' => '1cabd5cba9e042f12522f4ff2de5c31d233b',
'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();
// class
$this->expectExceptionMessage($exception_message);
$crypt = new SymmetricEncryption($key);
$this->expectExceptionMessage($exception_message);
$crypt->encrypt('test');
@@ -324,23 +172,6 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
$this->expectExceptionMessage($exception_message);
$crypt->setKey($key);
$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
$this->expectExceptionMessage($exception_message);
@@ -349,23 +180,6 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
$encrypted = SymmetricEncryption::getInstance($enc_key)->encrypt('test');
$this->expectExceptionMessage($exception_message);
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
$this->expectExceptionMessage($exception_message);
@@ -376,8 +190,6 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
SymmetricEncryption::decryptKey($encrypted, $key);
}
// MARK: wrong input
/**
* Undocumented function
*
@@ -420,49 +232,6 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
$this->expectExceptionMessage($exception_message);
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__

File diff suppressed because it is too large Load Diff

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
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",
"version": "dev-master",
"description": "CoreLibs: Development package",
"keywords": ["corelib", "logging", "database", "templating", "tools"],
"type": "library",
"require": {
"php": ">=8.3"
"php": ">=8.1"
},
"require-dev": {
"phpstan/phpstan": "^2.0",
"phpstan/phpstan-deprecation-rules": "^2.0",
"phpstan/extension-installer": "^1.4",
"phpstan/phpstan": "^1.10",
"phan/phan": "^5.4",
"phpunit/phpunit": "^9",
"yamadashy/phpstan-friendly-formatter": "^1.1"
"phpstan/extension-installer": "^1.2",
"phpstan/phpstan-strict-rules": "^1.6",
"phpunit/phpunit": "^9"
},
"config": {
"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": {
"module": "ESNext",
"moduleResolution": "Node",
"target": "ES2020",
"jsx": "react",
"checkJs": true,
"allowImportingTsExtensions": true,
"strictNullChecks": 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('SITE_DOMAIN', '');
define('HOST_NAME', 'soba.tokyo.tequila.jp');
define('DEFAULT_ENCODING', 'en_US.UTF-8');
// __END__

View File

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

View File

@@ -1,13 +1,8 @@
<phpunit
cacheResultFile="/tmp/phpunit-corelibs.result.cache"
colors="true"
verbose="false"
verbose="true"
convertDeprecationsToExceptions="true"
bootstrap="4dev/tests/bootstrap.php"
>
<testsuites>
<testsuite name="deploy">
<directory>4dev/tests</directory>
</testsuite>
</testsuites>
</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);
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();
@@ -42,20 +42,6 @@ $backend = new CoreLibs\Admin\Backend(
$l10n,
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;
$PAGE_NAME = 'TEST CLASS: ADMIN BACKEND';
@@ -69,30 +55,10 @@ print '<div><h1>' . $PAGE_NAME . '</h1></div>';
print "SETACL[]: <br>";
$backend->setACL(['EMPTY' => 'EMPTY']);
print "ADBEDITLOG: <br>";
$login->writeLog(
'CLASSTEST-ADMIN-BINARY',
'Some info string',
$backend->adbGetActionSet(),
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'
);
$backend->adbEditLog('CLASSTEST-ADMIN-BINARY', 'Some info string', 'BINARY');
$backend->adbEditLog('CLASSTEST-ADMIN-ZLIB', 'Some info string', 'ZLIB');
$backend->adbEditLog('CLASSTEST-ADMIN-SERIAL', 'Some info string', 'SERIAL');
$backend->adbEditLog('CLASSTEST-ADMIN-INVALID', 'Some info string', 'INVALID');
// test with various
$backend->action = 'TEST ACTION';
$backend->action_id = 'TEST ACTION ID';
@@ -103,10 +69,10 @@ $backend->action_loaded = 'TEST ACTION LOADED';
$backend->action_value = 'TEST ACTION VALUE';
$backend->action_type = 'TEST ACTION TYPE';
$backend->action_error = 'TEST ACTION ERROR';
$login->writeLog('CLASSTEST-ADMIN-JSON', [
$backend->adbEditLog('CLASSTEST-ADMIN-JSON', [
"_GET" => $_GET,
"_POST" => $_POST,
], $backend->adbGetActionSet(), write_type:'JSON');
], 'JSON');
print "ADBTOPMENU(0): " . Support::printAr($backend->adbTopMenu(CONTENT_PATH)) . "<br>";
print "ADBMSG: <br>";

View File

@@ -6,7 +6,7 @@
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();
@@ -51,9 +51,6 @@ $test_array = [
'element_c' => [
'type' => 'email'
],
'element_d' => [
'type' => 'butter'
],
],
];
@@ -63,8 +60,6 @@ echo "ARRAYSEARCHRECURSIVE(email, [array], type): "
. DgS::printAr(ArrayHandler::arraySearchRecursive('email', $test_array, 'type')) . "<br>";
echo "ARRAYSEARCHRECURSIVE(email, [array]['input'], type): "
. 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
echo "ARRAYSEARCHRECURSIVEALL(email, [array], type): "
. Dgs::printAr((array)ArrayHandler::arraySearchRecursiveAll('email', $test_array, 'type')) . "<br>";
@@ -73,15 +68,7 @@ echo "ARRAYSEARCHRECURSIVEALL(email, [array], type): "
// simple search
echo "ARRAYSEARCHSIMPLE([array], type, email): "
. Dgs::prBl(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>";
. (string)ArrayHandler::arraySearchSimple($test_array, 'type', 'email') . "<br>";
$array_1 = [
'foo' => 'bar'
@@ -128,6 +115,9 @@ print "ARRAYFLATFORKEY: " . DgS::printAr(ArrayHandler::arrayFlatForKey($test_arr
*/
function rec(string $pre, string $cur, array $node = [])
{
if (!is_array($node)) {
$node = [];
}
print "<div style='color: green;'>#### PRE: " . $pre . ", CUR: " . $cur . ", N-c: "
. count($node) . " [" . join('|', array_keys($node)) . "]</div>";
if (!$pre) {
@@ -181,31 +171,6 @@ $data = [
$search = ['image', 'result_image', 'nothing', 'EMPTY'];
$result = ArrayHandler::arraySearchKey($data, $search);
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 = [
// 'A' => [
@@ -288,246 +253,6 @@ foreach (array_keys($array) as $search) {
}
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>";
// __END__

View File

@@ -6,7 +6,7 @@
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();
// basic class test file

View File

@@ -6,7 +6,7 @@
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();
@@ -74,21 +74,9 @@ foreach ($bytes as $byte) {
print '<div style="width: 35%; text-align: right; padding-right: 2px;">';
print "(" . number_format($byte) . "/" . $byte . ") bytes :";
$_bytes = Byte::humanReadableByteFormat($byte);
print '</div>';
print '<div style="width: 10%;">' . $_bytes . '</div>';
print '<div style="width: 40%;">';
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><div style="width: 10%;">' . $_bytes;
print '</div><div style="width: 10%;">';
print Byte::stringByteFormat($_bytes);
print "</div>";
//
print "</div>";
@@ -99,85 +87,13 @@ foreach ($bytes as $byte) {
print "bytes [si]:";
$_bytes = Byte::humanReadableByteFormat($byte, Byte::BYTE_FORMAT_SI);
print '</div><div style="width: 10%;">' . $_bytes;
print '</div><div style="width: 40%;">';
try {
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><div style="width: 10%;">';
print Byte::stringByteFormat($_bytes);
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>";
// __END__

View File

@@ -6,7 +6,7 @@
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();

View File

@@ -6,7 +6,7 @@
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();

View File

@@ -6,7 +6,7 @@
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();

View File

@@ -6,7 +6,7 @@
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();

View File

@@ -6,7 +6,7 @@
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();
@@ -18,9 +18,7 @@ require 'config.php';
$LOG_FILE_ID = 'classTest-convert-colors';
ob_end_flush();
// use CoreLibs\Convert\Colors;
use CoreLibs\Convert\Color\Color;
use CoreLibs\Convert\Color\Coordinates;
use CoreLibs\Convert\Colors;
use CoreLibs\Debug\Support as DgS;
use CoreLibs\Convert\SetVarType;
@@ -29,36 +27,7 @@ $log = new CoreLibs\Logging\Logging([
'log_file_id' => $LOG_FILE_ID,
'log_per_date' => true,
]);
/**
* 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
);
}
$color_class = 'CoreLibs\Convert\Colors';
$PAGE_NAME = 'TEST CLASS: CONVERT COLORS';
print "<!DOCTYPE html>";
@@ -67,83 +36,32 @@ print "<body>";
print '<div><a href="class_test.php">Class Test Master</a></div>';
print '<div><h1>' . $PAGE_NAME . '</h1></div>';
// out of bounds 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)
try {
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) {
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)
$rgb = [50, 20, 30];
$rgb = [10, 20, 30];
$hex = '#0a141e';
$hsb = [210, 67, 12];
$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 hex->rgb: $hex: " . DgS::printAr(SetVarType::setArray(
Colors::hex2rgb($hex)
)) . "<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)
)) . "<br>";
// 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(
Colors::hsb2rgb($hsb_f[0], $hsb_f[1], $hsb_f[2])
)) . "<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(
Colors::hsl2rgb($hsb[0], $hsb[1], $hsb[2])
Colors::hsl2rgb($hsl[0], $hsl[1], $hsl[2])
)) . "<br>";
$hsb = [0, 0, 5];
print "S::COLOR hsb->rgb: $hsb[0], $hsb[1], $hsb[2]: "
. DgS::printAr(SetVarType::setArray(
Colors::hsb2rgb($hsb[0], $hsb[1], $hsb[2])
)) . "<br>"; */
print "<hr>";
)) . "<br>";
// Random text
$h = rand(0, 359);
@@ -183,18 +99,10 @@ $s = rand(15, 70);
$b = 100;
$l = 50;
print "RANDOM IN: H: " . $h . ", S: " . $s . ", B/L: " . $b . "/" . $l . "<br>";
print "RANDOM hsb->rgb: <pre>"
. DgS::printAr(SetVarType::setArray(Color::hsbToRgb(new Coordinates\HSB([$h, $s, $b])))) . "</pre><br>";
print "RANDOM hsl->rgb: <pre>"
. DgS::printAr(SetVarType::setArray(Color::hslToRgb(new Coordinates\HSL([$h, $s, $l])))) . "</pre><br>";
print "RANDOM hsb->rgb: <pre>" . DgS::printAr(SetVarType::setArray(Colors::hsb2rgb($h, $s, $b))) . "</pre><br>";
print "RANDOM hsl->rgb: <pre>" . DgS::printAr(SetVarType::setArray(Colors::hsl2rgb($h, $s, $l))) . "</pre><br>";
print "<hr>";
$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>";
// TODO: run compare check input must match output
print "</body></html>";

View File

@@ -6,7 +6,7 @@
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();

View File

@@ -6,7 +6,7 @@
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();
@@ -268,9 +268,7 @@ foreach ($compare_datetimes as $compare_datetime) {
print "COMPAREDATE: $compare_datetime[0] = $compare_datetime[1]: "
. (string)DateTime::compareDateTime($compare_datetime[0], $compare_datetime[1]) . "<br>";
}
print "<hr>";
print "<h2>calcDaysInterval</h2>";
$compare_dates = [
[ '2021-05-01', '2021-05-10', ],
[ '2021-05-10', '2021-05-01', ],
@@ -281,21 +279,9 @@ foreach ($compare_dates as $compare_date) {
print "CALCDAYSINTERVAL: $compare_date[0] = $compare_date[1]: "
. DgS::printAr(DateTime::calcDaysInterval($compare_date[0], $compare_date[1])) . "<br>";
print "CALCDAYSINTERVAL(named): $compare_date[0] = $compare_date[1]: "
. DgS::printAr(DateTime::calcDaysInterval($compare_date[0], $compare_date[1], return_named: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
));
. DgS::printAr(DateTime::calcDaysInterval($compare_date[0], $compare_date[1], true)) . "<br>";
}
print "<hr>";
print "<h2>setWeekdayNameFromIsoDow</h2>";
// test date conversion
$dow = 2;
print "DOW[$dow]: " . DateTime::setWeekdayNameFromIsoDow($dow) . "<br>";
@@ -311,25 +297,26 @@ $date = '2022-70-242';
print "DATE-dow[$date];invalid: " . DateTime::setWeekdayNameFromDate($date) . "<br>";
print "DATE-dow[$date],long;invalid: " . DateTime::setWeekdayNameFromDate($date, true) . "<br>";
print "DOW-date[$date];invalid: " . DateTime::setWeekdayNumberFromDate($date) . "<br>";
print "<hr>";
print "<h2>dateRangeHasWeekend</h2>";
// check date range includes a weekend
$has_weekend_list = [
['2023-07-03', '2023-07-05'],
['2023-07-03', '2023-07-10'],
['2023-07-03', '2023-07-31'],
['2023-07-01', '2023-07-03'],
['2023-07-01', '2023-07-01'],
['2023-07-01', '2023-07-02'],
['2023-06-30', '2023-07-01'],
['2023-06-30', '2023-06-30'],
['2023-07-01', '2023-06-30'],
];
foreach ($has_weekend_list as $days) {
print "Has Weekend: " . $days[0] . " ~ " . $days[1] . ": "
. Dgs::prBl(DateTime::dateRangeHasWeekend($days[0], $days[1])) . "<br>";
}
// does not:
$start_date = '2023-07-03';
$end_date = '2023-07-05';
print "Has Weekend: " . $start_date . " ~ " . $end_date . ": "
. Dgs::prBl(DateTime::dateRangeHasWeekend($start_date, $end_date)) . "<br>";
$start_date = '2023-07-03';
$end_date = '2023-07-10';
print "Has Weekend: " . $start_date . " ~ " . $end_date . ": "
. Dgs::prBl(DateTime::dateRangeHasWeekend($start_date, $end_date)) . "<br>";
$start_date = '2023-07-03';
$end_date = '2023-07-31';
print "Has Weekend: " . $start_date . " ~ " . $end_date . ": "
. Dgs::prBl(DateTime::dateRangeHasWeekend($start_date, $end_date)) . "<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>";
@@ -473,10 +460,7 @@ function intervalStringFormatDeprecated(
// print "-> V: $value | $part, $time_name | I: " . is_int($value) . " | F: " . is_float($value)
// . " | " . ($value != 0 ? 'Not zero' : 'ZERO') . "<br>";
// var_dump($skip_last_zero);
if (
is_numeric($value) &&
($value != 0 || $skip_zero === false || $skip_last_zero === false)
) {
if ($value != 0 || $skip_zero === false || $skip_last_zero === false) {
if ($part == 'f') {
if ($truncate_nanoseconds === true) {
$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);
// 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();
@@ -70,7 +70,8 @@ for ($i = 1; $i <= 6; $i++) {
print $i . ") " . $cache_flag . ": "
. "res: " . (is_bool($res) ?
"<b>Bool:</b> " . Support::prBl($res) :
"Array: Yes"
(is_array($res) ?
"Array: " . Support::prBl(is_array($res)) : '{-}')
) . ", "
. "cursor_ext: <pre>" . Support::printAr(
SetVarType::setArray($db->dbGetCursorExt($q_db_ret))
@@ -88,7 +89,8 @@ for ($i = 1; $i <= 6; $i++) {
print $i . ") " . $cache_flag . ": "
. "res: " . (is_bool($res) ?
"<b>Bool:</b> " . Support::prBl($res) :
"Array: Yes"
(is_array($res) ?
"Array: " . Support::prBl(is_array($res)) : '{-}')
) . ", "
. "cursor_ext: <pre>" . Support::printAr(
SetVarType::setArray($db->dbGetCursorExt($q_db_ret))
@@ -106,7 +108,8 @@ for ($i = 1; $i <= 6; $i++) {
print $i . ") " . $cache_flag . ": "
. "res: " . (is_bool($res) ?
"<b>Bool:</b> " . Support::prBl($res) :
"Array: Yes"
(is_array($res) ?
"Array: " . Support::prBl(is_array($res)) : '{-}')
) . ", "
. "cursor_ext: <pre>" . Support::printAr(
SetVarType::setArray($db->dbGetCursorExt($q_db_ret))
@@ -124,7 +127,8 @@ for ($i = 1; $i <= 6; $i++) {
print $i . ") " . $cache_flag . ": "
. "res: " . (is_bool($res) ?
"<b>Bool:</b> " . Support::prBl($res) :
"Array: Yes"
(is_array($res) ?
"Array: " . Support::prBl(is_array($res)) : '{-}')
) . ", "
. "cursor_ext: <pre>" . Support::printAr(
SetVarType::setArray($db->dbGetCursorExt($q_db_ret))
@@ -142,7 +146,8 @@ for ($i = 1; $i <= 6; $i++) {
print $i . ") " . $cache_flag . ": "
. "res: " . (is_bool($res) ?
"<b>Bool:</b> " . Support::prBl($res) :
"Array: Yes"
(is_array($res) ?
"Array: " . Support::prBl(is_array($res)) : '{-}')
) . ", "
. "cursor_ext: <pre>" . Support::printAr(
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);
// 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();
@@ -76,41 +76,41 @@ $db->dbResetEncoding();
// 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();
$foo = $db->dbGetReturningExt('foo');
$foo = $db->dbGetReturningExt('foo', 0);
$foo = $db->dbGetReturningExt(pos:0);
$db->dbGetReturningExt();
$db->dbGetReturningExt('foo');
$db->dbGetReturningExt('foo', 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);
$foo = $db->dbGetFieldType('foo');
$db->dbGetFieldType(0);
$db->dbGetFieldType('foo');
//
$foo = $db->dbGetPrepareCursorValue('foo', 'bar');
$db->dbGetPrepareCursorValue('foo', 'bar');
// 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");
$status = $db->dbExecute("ins_test_foo", ['BAR TEST ' . time()]);
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()) . " | "
. "RETURNING EXT: " . print_r($db->dbGetReturningExt(), true) . " | "
. "RETURNING RETURN: " . print_r($db->dbGetReturningArray(), true) . "<br>";
@@ -239,7 +239,7 @@ print "PREPARE INSERT PREVIOUS INSERTED: "
print "PREPARE CURSOR RETURN:<br>";
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
@@ -255,7 +255,7 @@ SQL;
$db->dbPrepare("ins_test_foo_eom", $query);
$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>"
. "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()) . " | "
. "RETURNING EXT: " . print_r($db->dbGetReturningExt(), true) . " | "
. "RETURNING RETURN: " . print_r($db->dbGetReturningArray(), true) . "<br>";
@@ -273,8 +273,8 @@ $query_insert = <<<SQL
INSERT INTO
test_foo
(
test, some_bool, string_a, number_a, numeric_a,
some_internval, some_timestamp, json_string
test, some_bool, string_a, number_a, number_a_numeric,
some_time, some_timestamp, json_string
) VALUES (
$1, $2, $3, $4, $5,
$6, $7, $8
@@ -283,8 +283,8 @@ RETURNING test
SQL;
$query_select = <<<SQL
SELECT
test, some_bool, string_a, number_a, numeric_a,
some_time, some_internval, some_timestamp, json_string
test, some_bool, string_a, number_a, number_a_numeric,
some_time, some_time, some_timestamp, json_string
FROM
test_foo
WHERE
@@ -316,8 +316,7 @@ print "EOM STRING EXEC RETURN TEST: " . print_r(
$db->dbReturnRowParams(
$query_select,
[$__last_insert_id]
),
true
)
) . "<br>";
// B
$status = $db->dbExecParams(
@@ -346,8 +345,7 @@ print "EOM STRING EXEC RETURN TEST: " . print_r(
$db->dbReturnRowParams(
$query_select,
[$__last_insert_id]
),
true
)
) . "<br>";
// params > 10 for debug
// error catcher
@@ -554,7 +552,7 @@ print "<b>PREPARE QUERIES</b><br>";
// READ PREPARE
$q_prep = <<<SQL
SELECT test_foo_id, test, some_bool, string_a, number_a,
numeric_a, some_time
number_a_numeric, some_time
FROM test_foo
WHERE test = $1
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
$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 "
. "WHERE test = ANY($1) "
. "ORDER BY test_foo_id DESC LIMIT 5";
@@ -618,7 +616,7 @@ $test_bar = $db->dbEscapeLiteral('SOMETHING DIFFERENT');
$q = <<<SQL
SELECT test_foo_id, test, some_bool, string_a, number_a,
-- comment
numeric_a, some_time
number_a_numeric, some_time
FROM test_foo
WHERE test = $test_bar
ORDER BY test_foo_id DESC LIMIT 5
@@ -631,7 +629,7 @@ print "DB RETURN PARAMS<br>";
$q = <<<SQL
SELECT test_foo_id, test, some_bool, string_a, number_a,
-- comment
numeric_a, some_time
number_a_numeric, some_time
FROM test_foo
WHERE test = $1
ORDER BY test_foo_id DESC LIMIT 5
@@ -646,7 +644,7 @@ echo "<hr>";
print "DB RETURN PARAMS LIKE<br>";
$q = <<<SQL
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
WHERE string_a LIKE $1;
SQL;
@@ -660,7 +658,7 @@ echo "<hr>";
print "DB RETURN PARAMS ANY<br>";
$q = <<<SQL
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
WHERE string_a = ANY($1);
SQL;
@@ -676,7 +674,7 @@ echo "<hr>";
print "COMPOSITE ELEMENT READ<br>";
$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);
print "Field Name/Types: <pre>" . print_r($db->dbGetFieldNameTypes(), true) . "</pre>";
echo "<hr>";
@@ -707,17 +705,6 @@ if (
} else {
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 write class test

View File

@@ -7,7 +7,7 @@
declare(strict_types=1);
// 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();
@@ -53,9 +53,6 @@ if (($dbh = $db->dbGetDbh()) instanceof \PgSql\Connection) {
} else {
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
$db->dbSetDebugReplacePlaceholder(true);
@@ -65,136 +62,59 @@ $db->dbExec("TRUNCATE test_foo");
$uniqid = \CoreLibs\Create\Uids::uniqIdShort();
$binary_data = $db->dbEscapeBytea(file_get_contents('class_test.db.php') ?: '');
$query_params = [
$uniqid, // test
true, // some_bool
'STRING A', // string_a
2, // number_a
2.5, // numeric_a
1, // smallint
date('H:m:s'), // some_internval
date('Y-m-d H:i:s'), // some_timestamp
json_encode(['a' => 'string', 'b' => 1, 'c' => 1.5, 'f' => true, 'g' => ['a', 1, 1.5]]), // json_string
null, // null_var
'{"a", "b"}', // array_char_1
'{1,2}', // array_int_1
'{"(array Text A, 5, 8.8)","(array Text B, 10, 15.2)"}', // array_composite
'("Text", 4, 6.3)', // composite_item
$binary_data, // some_binary
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
$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_insert = <<<SQL
INSERT INTO test_foo (
-- row 1
test, some_bool, string_a, number_a, numeric_a, smallint_a,
-- row 2
some_internval, some_timestamp, json_string, null_var,
-- row 3
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,
-- row 4
array_composite,
-- row 5
composite_item,
-- row 6
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
some_binary
) VALUES (
-- row 1
$1, $2, $3, $4, $5, $6,
-- row 2
$7, $8, $9, $10,
-- row 3
$11, $12,
-- row 4
$13,
-- row 5
$14,
-- row 6
$15,
-- row 7
$16, $17,
-- row 8
$18, $19,
-- row 9
$20, $21, $22, $23,
-- row 10
$24
$15
)
RETURNING
test_foo_id, number_serial, identity_always, identitiy_default, default_uuid,
test, some_bool, string_a, number_a, numeric_a, smallint_a,
some_internval, some_timestamp, json_string, null_var,
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,
some_date,
array_char_2, array_int_2,
bigint_a, number_real, number_double, numeric_3,
uuid_var
some_binary
SQL;
print "Placeholders: <pre>" . print_r($db->dbGetQueryParamPlaceholders($query_insert), true) . "<pre>";
$status = $db->dbExecParams($query_insert, $query_params);
echo "<b>*</b><br>";
echo "INSERT ALL COLUMN TYPES: "
. Support::printToString($query_params) . " |<br>"
. "QUERY: <pre>" . $db->dbGetQuery() . "</pre> |<br>"
. "QUERY: " . $db->dbGetQuery() . " |<br>"
. "PRIMARY KEY: " . Support::printToString($db->dbGetInsertPK()) . " |<br>"
. "RETURNING EXT: <pre>" . print_r($db->dbGetReturningExt(), true) . "</pre> |<br>"
. "RETURNING RETURN: <pre>" . print_r($db->dbGetReturningArray(), true) . "<pre> |<br>"
. "ERROR: " . $db->dbGetLastError(true) . "<br>";
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
// convert placeholder tests
@@ -211,16 +131,6 @@ 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 (
@@ -247,18 +157,6 @@ SQL,
],
'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);
@@ -271,12 +169,11 @@ foreach ($test_queries as $info => $data) {
// . "<br>";
if ($db->dbCheckQueryForSelect($query)) {
$row = $db->dbReturnRowParams($query, $params);
print "<b>[$info]</b> SELECT: " . Support::prAr($row) . "<br>";
print "[$info] SELECT: " . Support::prAr($row) . "<br>";
} else {
$db->dbExecParams($query, $params);
}
print "ERROR: " . $db->dbGetLastError(true) . "<br>";
print "<b>[$info]</b> " . Support::printAr($db->dbGetPlaceholderConverted()) . "<br>";
print "[$info] " . Support::printAr($db->dbGetPlaceholderConverted()) . "<br>";
echo "<hr>";
}
@@ -291,44 +188,21 @@ SQL,
['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
SELECT test, string_a, number_a
FROM test_foo
WHERE string_a = ?
SQL, ['string A-1']));
echo "<hr>";
// ERROR BELOW: missing params
$res = $db->dbReturnRowParams(<<<SQL
SELECT test, string_a, number_a
FROM test_foo
WHERE string_a = $1
SQL, []);
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>";
$db->log->debug('DEBUGEND', '==================================== [END]');

View File

@@ -7,7 +7,7 @@
declare(strict_types=1);
// 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();

View File

@@ -7,7 +7,7 @@
declare(strict_types=1);
// 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();
@@ -57,43 +57,6 @@ if (($dbh = $db->dbGetDbh()) instanceof \PgSql\Connection) {
print "<b>TRUNCATE test_foo</b><br>";
$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
INSERT INTO test_foo (test, array_composite) VALUES ('C', '{"(a,1,1.5)","(b,2,2.5)"}')
SQL;
@@ -127,7 +90,7 @@ $query_params = [
$query_insert = <<<SQL
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,
array_char_1, array_int_1,
array_composite,
@@ -143,7 +106,7 @@ INSERT INTO test_foo (
)
RETURNING
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,
array_char_1, array_int_1,
array_composite,
@@ -164,8 +127,8 @@ echo "<hr>";
$query_select = <<<SQL
SELECT
test_foo_id,
test, some_bool, string_a, number_a, numeric_a, smallint_a,
number_real, number_double, numeric_3, number_serial,
test, some_bool, string_a, number_a, number_a_numeric, smallint_a,
number_real, number_double, number_numeric_3, number_serial,
some_time, some_timestamp, json_string, null_var,
array_char_1, array_char_2, array_int_1, array_int_2, array_composite,
composite_item, (composite_item).*,

View File

@@ -12,7 +12,7 @@ $PRINT_ALL = false;
$ECHO_ALL = 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();
@@ -68,14 +68,6 @@ function test2(): array
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: " . test() . "<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')
)) . "<br>";
echo "<b>CLASS DEBUG CALL LEGACY</b><br>";
echo "<b>CLASS DEBUG CALL</b><br>";
// @codingStandardsIgnoreLine
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);
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();

View File

@@ -6,7 +6,7 @@
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();

View File

@@ -6,7 +6,7 @@
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();
@@ -18,7 +18,6 @@ require 'config.php';
$LOG_FILE_ID = 'classTest-encryption';
ob_end_flush();
use CoreLibs\Security\AsymmetricAnonymousEncryption;
use CoreLibs\Security\SymmetricEncryption;
use CoreLibs\Security\CreateKey;
@@ -37,8 +36,6 @@ print "<body>";
print '<div><a href="class_test.php">Class Test Master</a></div>';
print '<div><h1>' . $PAGE_NAME . '</h1></div>';
print "<h2>Symmetric Encryption</h2>";
$key = CreateKey::generateRandomKey();
print "Secret Key: " . $key . "<br>";
@@ -108,49 +105,6 @@ try {
// $encrypted = $se->encrypt($string);
// $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>";
// __END__

View File

@@ -6,7 +6,7 @@
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();
@@ -40,8 +40,6 @@ print "Log ERROR: " . $log->prAr($em->getFlagLogError()) . "<br>";
print "FN: " . ml::fromName('Affe')->name . "<br>";
print "NU: " . ml::fromValue(100)->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', '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', '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 "ErrorsIds: <pre>" . $log->prAr($em->getErrorIds()) . "</pre>";
print "Errors: <pre>" . $log->prAr($em->getErrorMsg()) . "</pre>";

View File

@@ -6,7 +6,7 @@
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();

View File

@@ -6,7 +6,7 @@
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();
@@ -19,7 +19,6 @@ $LOG_FILE_ID = 'classTest-hash';
ob_end_flush();
use CoreLibs\Create\Hash;
use CoreLibs\Security\CreateKey;
$log = new CoreLibs\Logging\Logging([
'log_folder' => BASE . LOG,
@@ -39,66 +38,28 @@ print '<div><h1>' . $PAGE_NAME . '</h1></div>';
$to_crc = 'Some text block';
// static
print "S::__CRC32B: $to_crc: " . Hash::__crc32b($to_crc) . "<br>";
// print "S::__SHA1SHORT(off): $to_crc: " . Hash::__sha1short($to_crc) . "<br>";
print "S::hashShort(__sha1Short replace): $to_crc: " . Hash::hashShort($to_crc) . "<br>";
// print "S::__SHA1SHORT(on): $to_crc: " . Hash::__sha1short($to_crc, true) . "<br>";
print "S::sha1Short(__sha1Short replace): $to_crc: " . Hash::sha1Short($to_crc) . "<br>";
// print "S::__hash(d): " . $to_crc . "/"
// . Hash::STANDARD_HASH_SHORT . ": " . $hash_class::__hash($to_crc) . "<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>";
}
print "S::__CRC32B: $to_crc: " . $hash_class::__crc32b($to_crc) . "<br>";
print "S::__SHA1SHORT(off): $to_crc: " . $hash_class::__sha1short($to_crc) . "<br>";
print "S::__SHA1SHORT(on): $to_crc: " . $hash_class::__sha1short($to_crc, true) . "<br>";
print "S::__hash(d): " . $to_crc . "/"
. Hash::STANDARD_HASH_SHORT . ": " . $hash_class::__hash($to_crc) . "<br>";
foreach (['adler32', 'fnv132', 'fnv1a32', 'joaat', 'sha512'] as $__hash_c) {
print "S::__hash($__hash_c): $to_crc: " . $hash_class::__hash($to_crc, $__hash_c) . "<br>";
}
// static use
print "U-S::__CRC32B: $to_crc: " . Hash::__crc32b($to_crc) . "<br>";
echo "<hr>";
$text = 'Some String Text';
// $text = 'any string';
$type = 'crc32b';
print "Hash: " . $type . ": " . hash($type, $text) . "<br>";
// print "Class (old): " . $type . ": " . Hash::__hash($text, $type) . "<br>";
print "Class (new): " . $type . ": " . Hash::hash($text, $type) . "<br>";
print "Class: " . $type . ": " . Hash::__hash($text, $type) . "<br>";
echo "<hr>";
print "CURRENT STANDARD_HASH_SHORT: " . Hash::STANDARD_HASH_SHORT . "<br>";
print "CURRENT STANDARD_HASH_LONG: " . Hash::STANDARD_HASH_LONG . "<br>";
print "CURRENT STANDARD_HASH: " . Hash::STANDARD_HASH . "<br>";
print "HASH SHORT: " . $to_crc . ": " . Hash::hashShort($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 "<br>CURRENT STANDARD_HASH_SHORT: " . Hash::STANDARD_HASH_SHORT . "<br>";
print "<br>CURRENT STANDARD_HASH_LONG: " . Hash::STANDARD_HASH_LONG . "<br>";
print "HASH SHORT: " . $to_crc . ": " . Hash::__hash($to_crc) . "<br>";
print "HASH LONG: " . $to_crc . ": " . Hash::__hashLong($to_crc) . "<br>";
// print "UNIQU ID SHORT : " . Hash::__uniqId() . "<br>";
// print "UNIQU ID LONG : " . Hash::__uniqIdLong() . "<br>";

View File

@@ -6,7 +6,7 @@
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();

View File

@@ -6,7 +6,7 @@
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();

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