Compare commits

...

23 Commits

Author SHA1 Message Date
cliphouse 92581a6fd3 PHP Check update 2026-07-02 14:29:33 +09:00
cliphouse 0f11fe9194 Release: v9.41.3 2026-06-25 19:01:01 +09:00
cliphouse 1b7c8ecd25 Add logging to phpunit.xml 2026-06-25 19:00:23 +09:00
cliphouse de912d837e DB IO postgresql: supress warning on connection failure 2026-06-25 18:24:00 +09:00
cliphouse d991a1d663 Test updates 2026-06-25 18:10:44 +09:00
cliphouse e881854583 Test updates 2026-06-25 17:26:48 +09:00
cliphouse 55aebb5373 Test updates 2026-06-25 16:42:02 +09:00
cliphouse 6aa79dacc9 Test updates 2026-06-25 16:28:03 +09:00
cliphouse c0236ee4d9 Test updates 2026-06-25 15:55:20 +09:00
cliphouse 8c5ce49f70 Github action call updates 2026-06-25 15:35:55 +09:00
cliphouse e935e0c6d3 Error test for debug support, try to print out the error
Set correct phpunit version too
2026-06-25 15:16:24 +09:00
cliphouse 5e972b7aec Wrong folders set for PHP check 2026-06-25 15:06:24 +09:00
cliphouse b262b4be0f Update split call for local and remote 2026-06-25 15:04:03 +09:00
cliphouse 5cba8ca9ac Fixes from phpstan checks, add PHP CI/CD github action 2026-06-25 14:49:14 +09:00
Clemens Schwaighofer 397fcb25ff Release: v9.41.1 2026-05-12 11:48:27 +09:00
Clemens Schwaighofer 1e3ce162e5 L10n phpdoc updates 2026-05-12 11:46:19 +09:00
Clemens Schwaighofer 22806d6add README file name update and content fixes for URLs 2026-05-12 10:00:25 +09:00
Clemens Schwaighofer 46e39fa85d publish script update 2026-05-11 17:49:38 +09:00
Clemens Schwaighofer 8eb8e33dc4 Version: 9.41.0.2 2026-05-11 17:46:58 +09:00
Clemens Schwaighofer afcb953d2d Fix publish workflow with auth and no prefix 2026-05-11 17:45:46 +09:00
Clemens Schwaighofer 742b4087aa Update minimum PHP to 8.3 2026-05-11 17:06:09 +09:00
Clemens Schwaighofer f0c8daf26a Version: 9.41.0 actual push 2026-05-11 16:03:39 +09:00
Clemens Schwaighofer ee32a90ff9 Version: 9.41.0 2026-05-11 15:59:33 +09:00
38 changed files with 774 additions and 289 deletions
-33
View File
@@ -1,33 +0,0 @@
name: CI
run-name: ${{ github.actor}} runs CI
on: [push]
jobs:
phpstan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# - uses: php-actions/composer@v6
# env:
# COMPOSER_ROOT_VERSION: dev-master
- name: "Restore result cache"
uses: actions/cache/restore@v4
with:
path: ./tmp
key: "result-cache-v1-${{ matrix.php-version }}-${{ github.run_id }}"
restore-keys: |
result-cache-v1-${{ matrix.php-version }}-
- name: PHPStan Static Analysis
uses: php-actions/phpstan@v3
with:
path: src/
- name: "Save result cache"
uses: actions/cache/save@v4
if: always()
with:
path: ./tmp
key: "result-cache-v1-${{ matrix.php-version }}-${{ github.run_id }}"
# - name: PHPunit Tests
# run: |
# vendor/bin/phpunit
@@ -0,0 +1,35 @@
name: Call PHP Static Checks and Tests
run-name: ${{ github.actor }} calls Content.github-actions/php-static-checks-and-tests
on:
workflow_dispatch:
push:
branches: [master, staging, development]
jobs:
call-check-and-build-local:
# call local workflow if repository name is NOT Composer.corelibs-composer-all
if: github.event.repository.name != 'Composer.corelibs-composer-all'
uses: ./.github/workflows/php-static-checks-and-tests.yml
with:
php-version: '8.4,8.5'
phpunit-version: '^9'
composer-directory: './'
source-directory: './src'
disable-phan: ${{ vars.DISABLE_PHAN_CHECK == 'true' || false }}
secrets:
opj-package-registry: "${{ secrets.OPJ_PACKAGE_USER }}|${{ secrets.OPJ_PACKAGE_API_KEY }}|${{ vars.OPJ_PACKAGE_URL }}"
call-check-and-build-remote:
# call remote workflow if repository name is Composer.corelibs-composer-all
if: github.event.repository.name == 'Composer.corelibs-composer-all'
uses: OmnicomProduction-Japan/Content.github-actions/.github/workflows/php-static-checks-and-tests.yml@v1
with:
php-version: '8.4,8.5'
phpunit-version: '^9'
composer-directory: './'
source-directory: './src'
disable-phan: ${{ vars.DISABLE_PHAN_CHECK == 'true' || false }}
secrets:
opj-package-registry: "${{ secrets.OPJ_PACKAGE_USER }}|${{ secrets.OPJ_PACKAGE_API_KEY }}|${{ vars.OPJ_PACKAGE_URL }}"
@@ -0,0 +1,371 @@
# external call not yet setup, only copy to repo at the moment
name: PHP Static Checks and Tests Matrix Workflow
run-name: ${{ github.actor}} runs PHP-MATRIX-CI
on:
workflow_call:
inputs:
php-version:
type: string
required: false
default: '8.5'
description: 'PHP versions to use for the checks and tests, default is 8.4 and 8.5, can be a comma-separated list of versions'
phpunit-version:
type: string
required: false
default: '^13'
description: 'PHPUnit versions to use for the tests, default is ^13, can be a comma-separated list of versions'
operating-system:
type: string
required: false
default: 'ubuntu-latest'
description: 'Operating systems to run the tests on, default is ubuntu-latest, can be a comma-separated list of operating systems'
disable-phan:
type: boolean
default: false
required: false
description: 'Set to "true" to skip running phan'
composer-directory:
type: string
required: false
default: './'
description: 'Directory where composer.json is located, relative to the repository root'
source-directory:
type: string
required: false
default: './src'
description: 'Directory where the PHP source code is located, relative to the repository root'
secrets:
opj-package-registry:
required: false
description: 'Package registry login infos: user|token|url[:user|token|url:...]'
jobs:
setup:
runs-on: ubuntu-latest
outputs:
php-version: ${{ steps.set-matrix.outputs.php-version }}
phpunit-version: ${{ steps.set-matrix.outputs.phpunit-version }}
operating-system: ${{ steps.set-matrix.outputs.operating-system }}
opj-package-registry: ${{ steps.set-matrix.outputs.opj-package-registry }}
steps:
- name: Set matrix values
id: set-matrix
env:
OPJ_PACKAGE_REGISTRY: ${{ secrets.opj-package-registry }}
run: |
echo "php-version=$(echo '${{ inputs.php-version }}' | tr ',' '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | jq -R . | jq -cs .)" >> $GITHUB_OUTPUT
echo "phpunit-version=$(echo '${{ inputs.phpunit-version }}' | tr ',' '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | jq -R . | jq -cs .)" >> $GITHUB_OUTPUT
echo "operating-system=$(echo '${{ inputs.operating-system }}' | tr ',' '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | jq -R . | jq -cs .)" >> $GITHUB_OUTPUT
# take the secrets opj-package-registry, split by ":" for each entry
# then split by "|" for each entry to get user, token, url
# then create a JSON array of objects with user, token, url
if [ -n "$OPJ_PACKAGE_REGISTRY" ]; then
echo "opj-package-registry=$(echo "$OPJ_PACKAGE_REGISTRY" | tr ':' '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | jq -R 'split("|") | {user: .[0], token: .[1], url: .[2]}' | jq -cs .)" >> $GITHUB_OUTPUT
else
echo "opj-package-registry=[]" >> $GITHUB_OUTPUT
fi;
php-check-and-test-matrix:
needs: setup
runs-on: ${{ matrix.operating-system }}
strategy:
matrix:
operating-system: ${{fromJSON(needs.setup.outputs.operating-system)}}
php-version: ${{fromJSON(needs.setup.outputs.php-version)}}
phpunit-version: ${{fromJSON(needs.setup.outputs.phpunit-version)}}
# include:
# - operating-system: ubuntu-latest
# php-version: '8.4'
# phpunit-version: '^13'
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
extensions: mbstring, intl, sqlite, pdo_sqlite
# ini-values: post_max_size=256M, max_execution_time=180
tools: composer, ${{ inputs.disable-phan == false && 'phan, ' || '' }}phpstan, phpcs, phpunit:${{ matrix.phpunit-version }}, cs2pr
# coverage: pcov
coverage: xdebug
- name: Check Tools setup
id: check-tools
run: |
REQUIRED_TOOLS=("composer" "phpunit" "phpstan" ${{ inputs.disable-phan == false && '"phan" ' || '' }}"phpcs" "cs2pr")
SKIP_IF_FAILED=("phan")
for tool in "${REQUIRED_TOOLS[@]}"; do
if ! command -v "$tool" &> /dev/null; then
if [[ " ${SKIP_IF_FAILED[@]} " =~ " ${tool} " ]]; then
echo "⚠️ Warning: $tool is not installed, but it's optional. Skipping..."
echo "${tool}=skip" >> $GITHUB_OUTPUT
continue
fi
echo "❌ Error: $tool failed to load!"
exit 1
else
# the tool path does not have "setup-php/tools/ inside
tool_path=$(which "$tool")
if [[ "$tool_path" != */setup-php/tools/* ]]; then
if [[ " ${SKIP_IF_FAILED[@]} " =~ " ${tool} " ]]; then
echo "⚠️ Warning: $tool installation check failed, but it's optional. Skipping..."
echo "${tool}=skip" >> $GITHUB_OUTPUT
continue
fi
echo "❌ Error: $tool path lookup failed!"
exit 1
fi
tool_version=$("$tool" --version 2>&1)
echo "✅ $tool loaded successfully: $tool_version ($(which $tool))"
echo "${tool}=ok" >> $GITHUB_OUTPUT
fi
done
- name: Check source folder and composer.json setup
run: |
if [ ! -d "${{ inputs.source-directory }}" ]; then
echo "❌ Error: Source directory '${{ inputs.source-directory }}' does not exist!"
exit 1
fi
if [ ! -f "${{ inputs.composer-directory }}/composer.json" ]; then
echo "❌ Error: composer.json not found in '${{ inputs.composer-directory }}'!"
exit 1
fi
- name: Setup problem matchers for PHP
run: echo "::add-matcher::${{ runner.tool_cache }}/php.json"
- name: Setup problem matchers for PHPUnit
run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
- name: Get composer cache directory
id: composer-cache
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
working-directory: ${{ inputs.composer-directory }}
- name: Cache dependencies
uses: actions/cache@v5
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
restore-keys: ${{ runner.os }}-composer-
- name: Authenticate to private package repository
env:
OPJ_PACKAGE_REGISTRY: ${{ needs.setup.outputs.opj-package-registry }}
run: |
# opj-package-registry is a JSON array of objects with user, token, url
for entry in $(echo "$OPJ_PACKAGE_REGISTRY" | jq -c '.[]'); do
user=$(echo "$entry" | jq -r '.user')
token=$(echo "$entry" | jq -r '.token')
url=$(echo "$entry" | jq -r '.url')
# if user, token or url is empty, skip this entry
if [ -z "$user" ] || [ -z "$token" ] || [ -z "$url" ]; then
echo "⚠️ Warning: Skipping invalid registry entry: $entry"
continue
fi
echo "Authenticating to private package repository: $url with user: $user"
composer config http-basic."$url" "$user" "$token"
done
composer install --prefer-dist
working-directory: ${{ inputs.composer-directory }}
- name: Run composer audit
id: run-composer-audit
run: composer audit --format=json --no-scripts --no-plugins --no-interaction > composer-audit-output.json
# some post action with the composer output format file
working-directory: ${{ inputs.composer-directory }}
- name: Run phpcs
id: run-phpcs
run: phpcs -q --report=checkstyle --standard=phpcs.xml --ignore=vendor/ ${{ inputs.source-directory }} | cs2pr
- name: Run phan
id: run-phan
if: ${{ ! inputs.disable-phan && steps.check-tools.outputs.phan == 'ok' }}
run: phan --analyze-twice --no-progress-bar --config-file=./.phan/config.php
# Must have "./tmp" directory set in configuration
# if we have "./tmp/phpstan" or anything different adjust the path below
- name: "Restore result cache"
uses: actions/cache/restore@v5
with:
path: ./tmp
key: "result-cache-${{ github.run_id }}"
restore-keys: |
result-cache-v1-
- name: Run PHPStan
id: run-phpstan
run: phpstan analyse --no-progress --configuration=phpstan.neon
- name: "Save result cache"
uses: actions/cache/save@v5
if: always()
with:
path: ./tmp
key: "result-cache-${{ github.run_id }}"
- name: Test with phpunit
id: run-phpunit
run: |
# if we are older than 12 there is no openclover
# version can start with ^ and then have numbers, so we need to remove the ^ and then compare the version numbers
phpunit_version="${{ matrix.phpunit-version }}"
phpunit_version="${phpunit_version#^}"
phpunit_version="${phpunit_version%%.*}"
if [ "$phpunit_version" -lt 12 ]; then
phpunit --colors=never \
--no-coverage \
--coverage-text=phpunit-coverage.txt \
--coverage-clover=phpunit-openclover.xml \
--log-junit=phpunit-junit.log
else
phpunit --colors=never \
--no-coverage \
--coverage-text=phpunit-coverage.txt \
--only-summary-for-coverage-text \
--coverage-openclover=phpunit-openclover.xml \
--log-junit=phpunit-junit.log \
--log-otr=phpunit-otr.log
fi;
- name: Code Coverage Summary Report
uses: saschanowak/CloverCodeCoverageSummary@1.1.1
with:
filename: phpunit-openclover.xml
- name: Summary
if: always()
env:
COMPOSER_AUDIT_RESULT: ${{ steps.run-composer-audit.outcome }}
COMPOSER_AUDIT_FILE: ${{ inputs.composer-directory }}/composer-audit-output.json
PHPCS_RESULT: ${{ steps.run-phpcs.outcome }}
PHAN_RESULT: ${{ steps.run-phan.outcome }}
PHPSTAN_RESULT: ${{ steps.run-phpstan.outcome }}
PHPUNIT_RESULT: ${{ steps.run-phpunit.outcome }}
run: |
icon() { if [[ "$1" == "success" ]]; then echo "✅"; elif [[ "$1" == "skipped" ]]; then echo "⏭️"; else echo "❌"; fi; }
row() { echo "<tr><td><b>$1</b></td><td>$(icon $2) $2</td></tr>"; }
cat >> $GITHUB_STEP_SUMMARY << EOF
<h2>PHP CI Results</h2>
<table>
<thead>
<tr><th>Check</th><th>Status</th></tr>
</thead>
<tbody>
$(row "composer audit" "$COMPOSER_AUDIT_RESULT")
$(row "phpcs" "$PHPCS_RESULT")
$(row "phan" "$PHAN_RESULT")
$(row "phpstan" "$PHPSTAN_RESULT")
$(row "phpunit" "$PHPUNIT_RESULT")
</tbody>
</table>
<details>
<summary>Run details</summary>
| Input | Value |
| --- | --- |
| PHP version | \`${{ inputs.php-version }}\` |
| PHPUnit version | \`${{ inputs.phpunit-version }}\` |
| Operating system | \`${{ inputs.operating-system }}\` |
| Phan disabled | \`${{ inputs.disable-phan }}\` |
| Composer directory | \`${{ inputs.composer-directory }}\` |
| Source directory | \`${{ inputs.source-directory }}\` |
</details>
EOF
if [ -f "$COMPOSER_AUDIT_FILE" ] && jq empty "$COMPOSER_AUDIT_FILE" 2>/dev/null; then
{
echo "<h3>Composer Audit</h3>"
echo ""
PACKAGES_AUDITED=$(jq -r '.metadata["packages-audited"] // "?"' "$COMPOSER_AUDIT_FILE")
ADVISORIES_COUNT=$(jq -r '.metadata["packages-with-advisories"] // 0' "$COMPOSER_AUDIT_FILE")
echo "| Packages audited | With advisories |"
echo "| --- | --- |"
echo "| $PACKAGES_AUDITED | $ADVISORIES_COUNT |"
echo ""
ADVISORY_ROWS=$(jq -r '
.packages[]
| select(.advisories and (.advisories | length) > 0)
| .name as $name | .version as $ver
| .advisories[]
| "| \($name) | \($ver) | \(.cve // "N/A") | \(.title) |"
' "$COMPOSER_AUDIT_FILE" 2>/dev/null || true)
if [ -n "$ADVISORY_ROWS" ]; then
echo "| Package | Version | CVE | Title |"
echo "| --- | --- | --- | --- |"
echo "$ADVISORY_ROWS"
echo ""
fi
echo "<details><summary>Full audit output</summary>"
echo ""
echo '```json'
cat "$COMPOSER_AUDIT_FILE"
echo '```'
echo ""
echo "</details>"
} >> $GITHUB_STEP_SUMMARY
fi
if [ -f phpunit-junit.log ]; then
{
echo "<h3>PHPUnit Test Results</h3>"
echo ""
# Extract totals from the top-level testsuite element (first testsuite line)
JUNIT_LINE=$(grep -m1 '<testsuite ' phpunit-junit.log)
TESTS=$(echo "$JUNIT_LINE" | grep -oP 'tests="\K[0-9]+')
ASSERTIONS=$(echo "$JUNIT_LINE" | grep -oP 'assertions="\K[0-9]+')
ERRORS=$(echo "$JUNIT_LINE" | grep -oP 'errors="\K[0-9]+')
FAILURES=$(echo "$JUNIT_LINE" | grep -oP 'failures="\K[0-9]+')
SKIPPED=$(echo "$JUNIT_LINE" | grep -oP 'skipped="\K[0-9]+')
TIME=$(echo "$JUNIT_LINE" | grep -oP 'time="\K[0-9]+\.[0-9]+')
PASSED=$(( TESTS - ERRORS - FAILURES - SKIPPED ))
test_icon() {
if [ "$1" -gt 0 ]; then echo "❌"; else echo "✅"; fi
}
echo "| Metric | Value |"
echo "| --- | --- |"
echo "| Tests | $TESTS |"
echo "| Passed | $PASSED |"
echo "| Assertions | $ASSERTIONS |"
echo "| Skipped | $(test_icon "${SKIPPED:-0}") ${SKIPPED:-0} |"
echo "| Failures | $(test_icon "${FAILURES:-0}") ${FAILURES:-0} |"
echo "| Errors | $(test_icon "${ERRORS:-0}") ${ERRORS:-0} |"
echo "| Time | ${TIME}s |"
echo ""
} >> $GITHUB_STEP_SUMMARY
fi
if [ -f phpunit-coverage.txt ]; then
{
echo "<h3>Code Coverage</h3>"
echo ""
echo "| Metric | Coverage | Status |"
echo "| --- | --- | --- |"
grep -E '^\s+(Classes|Methods|Lines):' phpunit-coverage.txt | head -3 | while IFS= read -r line; do
name=$(echo "$line" | sed 's/^[[:space:]]*//' | cut -d: -f1)
value=$(echo "$line" | cut -d: -f2- | sed 's/^[[:space:]]*//')
pct=$(echo "$value" | grep -oE '[0-9]+\.[0-9]+' | head -1)
circle=$(awk -v p="$pct" 'BEGIN { if (p+0 == 100) print "🟢"; else if (p+0 >= 60) print "🟠"; else print "🔴" }')
echo "| $name | $value | $circle |"
done
echo ""
echo "<details><summary>Full coverage report</summary>"
echo ""
echo '```'
cat phpunit-coverage.txt
echo '```'
echo ""
echo "</details>"
} >> $GITHUB_STEP_SUMMARY
fi
if [ -f phpunit-openclover.xml ]; then
if [ -f code-coverage-summary.md ]; then
cat code-coverage-summary.md >> $GITHUB_STEP_SUMMARY
fi
if [ -f code-coverage-details.md ]; then
cat code-coverage-details.md >> $GITHUB_STEP_SUMMARY
fi
fi
+2 -2
View File
@@ -1,9 +1,9 @@
<?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="phpunit" version="^9.6" installed="9.6.34" location="./tools/phpunit" copy="false"/>
<phar name="phpcs" version="^4.0.0" installed="4.0.1" location="./tools/phpcs" copy="false"/>
<phar name="phpcbf" version="^4.0.0" installed="4.0.1" location="./tools/phpcbf" copy="false"/>
<phar name="psalm" version="^5.15.0" installed="5.26.1" location="./tools/psalm" copy="false"/>
<phar name="phpstan" version="^2.0.0" installed="2.1.33" location="./tools/phpstan" copy="false"/>
<phar name="phpstan" version="^2.0.0" installed="2.2.2" location="./tools/phpstan" copy="false"/>
<phar name="phan" version="^5.4.2" installed="5.5.2" location="./tools/phan" copy="false"/>
</phive>
@@ -17,7 +17,7 @@ Run `publish/publish.sh` script to create composer packages.
This will automatically run all commands to create the packages
### composer.egplusww.jp web host
### composer.omnicomproduction.jp web host
For the local composer package host.
@@ -30,7 +30,7 @@ The entry is a copy of the `composer.json` with the following new entries:
"version": "X.Y.Z",
...
"dist": {
"url": "https://git.egplusww.jp/Composer/CoreLibs-Composer-All/archive/vX.Y.Z.zip",
"url": "https://packages.omnicomproduction.jp/Composer/CoreLibs-Composer-All/archive/vX.Y.Z.zip",
"type": "zip"
},
...
View File
+1 -1
View File
@@ -18,7 +18,7 @@
"minimum-stability": "stable",
"prefer-stable": true,
"require": {
"php": ">=8.2",
"php": ">=8.3",
"psr/log": "^3.0"
},
"require-dev": {
+16 -1
View File
@@ -1,7 +1,8 @@
<phpunit
cacheResultFile="/tmp/phpunit-corelibs-composer.result.cache"
colors="true"
verbose="true"
verbose="false"
convertDeprecationsToExceptions="true"
bootstrap="test/phpunit/bootstrap.php"
>
<testsuites>
@@ -9,4 +10,18 @@
<directory>test/phpunit</directory>
</testsuite>
</testsuites>
<coverage processUncoveredFiles="true">
<include>
<directory suffix=".php">./src</directory>
</include>
<!-- <report>
<html outputDirectory="build/coverage-report"/>
</report> -->
</coverage>
<logging>
<!-- JUnit XML log (Most Common for CI/CD) -->
<junit outputFile="build/logs/junit.xml"/>
<!-- TestDox HTML log -->
<testdoxHtml outputFile="build/testdox.html"/>
</logging>
</phpunit>
+1 -1
View File
@@ -1 +1 @@
9.40.0.1
9.41.3
+32 -14
View File
@@ -11,6 +11,9 @@ go_flag="$1";
function gitea_publish
{
# MUST have in app.ini, else upload will fail
# [repository]
# PREFIX_ARCHIVE_FILES = false
_GITEA_PUBLISH="${1}"
_GITEA_UPLOAD_FILENAME="${2}"
_GITEA_URL_DL="${3}"
@@ -28,26 +31,40 @@ function gitea_publish
[ -n "${_GITEA_URL_DL}" ] && [ -n "${_GITEA_URL_PUSH}" ] &&
[ -n "${_GITEA_USER}" ] && [ -n "${_GITEA_TOKEN}" ]; then
echo "> Publish ${_GITEA_UPLOAD_FILENAME} with ${_VERSION} to: ${_GITEA_URL_PUSH}";
error=0;
if [ ! -f "${_PACKAGE_DOWNLOAD}${_GITEA_UPLOAD_FILENAME}-v${_VERSION}.zip" ]; then
echo "> Download: ${_GITEA_UPLOAD_FILENAME}-v${_VERSION}.zip";
curl -LJO \
--output-dir "${_PACKAGE_DOWNLOAD}" \
"${_GITEA_URL_DL}"/v"${_VERSION}".zip;
http_response=$(curl -LJO \
-w "%{http_code}" \
--output-dir "${_PACKAGE_DOWNLOAD}" \
-H "Authorization: token ${_GITEA_TOKEN}" \
"${_GITEA_URL_DL}/v${_VERSION}.zip"
);
if [ "$http_response" -ne 200 ]; then
echo "[!] Error downloading file: ${http_response}";
error=1;
fi;
fi;
if [ ! -f "${_PACKAGE_DOWNLOAD}${_GITEA_UPLOAD_FILENAME}-v${_VERSION}.zip" ]; then
echo "[!] Package file does not exist for version: ${_VERSION}";
else
response=$(curl --user "${_GITEA_USER}":"${_GITEA_TOKEN}" \
if [ $error -eq 0 ]; then
# if this is the short name rename to long name, if long name down load does not work
if [ -f "${_PACKAGE_DOWNLOAD}v${_VERSION}.zip" ]; then
mv "${_PACKAGE_DOWNLOAD}v${_VERSION}.zip" "${_PACKAGE_DOWNLOAD}${_GITEA_UPLOAD_FILENAME}-v${_VERSION}.zip";
fi;
if [ ! -f "${_PACKAGE_DOWNLOAD}${_GITEA_UPLOAD_FILENAME}-v${_VERSION}.zip" ]; then
echo "[!] Package file does not exist for version: ${_VERSION}";
else
response=$(curl --user "${_GITEA_USER}":"${_GITEA_TOKEN}" \
--upload-file "${_PACKAGE_DOWNLOAD}${_GITEA_UPLOAD_FILENAME}-v${_VERSION}.zip" \
"${_GITEA_URL_PUSH}"?version="${_VERSION}");
status=$(echo "${response}" | jq .errors[].status);
message=$(echo "${response}" | jq .errors[].message);
if [ -n "${status}" ]; then
echo "[!] Error ${status}: ${message}";
else
echo "> Publish completed";
status=$(echo "${response}" | jq .errors[].status);
message=$(echo "${response}" | jq .errors[].message);
if [ -n "${status}" ]; then
echo "[!] Error ${status}: ${message}";
else
echo "> Publish completed";
echo "${_VERSION}" > "${_file_last_published}";
fi;
fi;
echo "${_VERSION}" > "${_file_last_published}";
fi;
else
echo "[!] Missing either GITEA_UPLOAD_FILENAME, GITEA_URL_DL, GITEA_URL_PUSH, GITEA_USER or GITEA_TOKEN environment variable";
@@ -88,6 +105,7 @@ if [ -f "${file_last_published}" ]; then
LAST_PUBLISHED_VERSION=$(cat "${file_last_published}");
if dpkg --compare-versions "${VERSION}" le "${LAST_PUBLISHED_VERSION}"; then
echo "[!] git tag version ${VERSION} is not newer than previous published version ${LAST_PUBLISHED_VERSION}";
exit;
fi;
fi;
+61 -62
View File
@@ -43,71 +43,70 @@ class Byte
public static function humanReadableByteFormat(string|int|float $bytes, int $flags = 0): string
{
// if not numeric, return as is
if (is_numeric($bytes)) {
// flags bit wise check
// remove space between number and suffix
if ($flags & self::BYTE_FORMAT_NOSPACE) {
$space = false;
} else {
$space = true;
}
// use sprintf instead of round
if ($flags & self::BYTE_FORMAT_ADJUST) {
$adjust = true;
} else {
$adjust = false;
}
// use SI 1000 mod and not 1024 mod
if ($flags & self::BYTE_FORMAT_SI) {
$si = true;
} else {
$si = false;
}
if ($flags > 7) {
throw new \InvalidArgumentException("Invalid flags parameter: $flags", 1);
}
// si or normal
$unit = $si ? 1000 : 1024;
// always positive
$abs_bytes = $bytes == PHP_INT_MIN ? PHP_INT_MAX : abs((float)$bytes);
// smaller than unit is always B
if ($abs_bytes < $unit) {
return $bytes . 'B';
}
// labels in order of size [Y, Z]
$labels = ['', 'K', 'M', 'G', 'T', 'P', 'E'];
// exp position calculation
$exp = (int)floor(log($abs_bytes, $unit));
// avoid printing out anything larger than max labels
if ($exp >= count($labels)) {
$exp = count($labels) - 1;
}
// deviation calculation
$dev = pow($unit, $exp) * ($unit - 0.05);
// shift the exp +1 for on the border units
if (
$exp < 6 &&
$abs_bytes > ($dev - (((int)$dev & 0xfff) == 0xd00 ? 52 : 0))
) {
$exp++;
}
// label name, including leading space if flagged
$pre = ($space ? ' ' : '') . ($labels[$exp] ?? '>E') . ($si ? 'i' : '') . 'B';
$bytes_calc = $abs_bytes / pow($unit, $exp);
// if original is negative, reverse
if ($bytes < 0) {
$bytes_calc *= -1;
}
if ($adjust) {
return sprintf("%.2f%s", $bytes_calc, $pre);
} else {
return round($bytes_calc, 2) . $pre;
}
} else {
if (!is_numeric($bytes)) {
// if anything other return as string
return (string)$bytes;
}
// flags bit wise check
// remove space between number and suffix
if ($flags & self::BYTE_FORMAT_NOSPACE) {
$space = false;
} else {
$space = true;
}
// use sprintf instead of round
if ($flags & self::BYTE_FORMAT_ADJUST) {
$adjust = true;
} else {
$adjust = false;
}
// use SI 1000 mod and not 1024 mod
if ($flags & self::BYTE_FORMAT_SI) {
$si = true;
} else {
$si = false;
}
if ($flags > 7) {
throw new \InvalidArgumentException("Invalid flags parameter: $flags", 1);
}
// si or normal
$unit = $si ? 1000 : 1024;
// always positive
$abs_bytes = $bytes == PHP_INT_MIN ? PHP_INT_MAX : abs((float)$bytes);
// smaller than unit is always B
if ($abs_bytes < $unit) {
return $bytes . 'B';
}
// labels in order of size [Y, Z]
$labels = ['', 'K', 'M', 'G', 'T', 'P', 'E'];
// exp position calculation
$exp = (int)floor(log($abs_bytes, $unit));
// avoid printing out anything larger than max labels
if ($exp >= count($labels)) {
$exp = count($labels) - 1;
}
// deviation calculation
$dev = pow($unit, $exp) * ($unit - 0.05);
// shift the exp +1 for on the border units
if (
$exp < 6 &&
$abs_bytes > ($dev - (((int)$dev & 0xfff) == 0xd00 ? 52 : 0))
) {
$exp++;
}
// label name, including leading space if flagged
$pre = ($space ? ' ' : '') . ($labels[$exp] ?? '>E') . ($si ? 'i' : '') . 'B';
$bytes_calc = $abs_bytes / pow($unit, $exp);
// if original is negative, reverse
if ($bytes < 0) {
$bytes_calc *= -1;
}
if ($adjust) {
return sprintf("%.2f%s", $bytes_calc, $pre);
} else {
return round($bytes_calc, 2) . $pre;
}
}
/**
+3 -3
View File
@@ -2232,9 +2232,9 @@ class IO
$milliseconds = $matches[13] ?? '';
// clean up, hide entries that have 00 in the time group
$hour = $hour != '00' ? preg_replace('/^0/', '', $hour) : '';
$minutes = $minutes != '00' ? preg_replace('/^0/', '', $minutes) : '';
$seconds = $seconds != '00' ? preg_replace('/^0/', '', $seconds) : '';
$hour = !empty($hour) ? preg_replace('/^0/', '', $hour) : '';
$minutes = !empty($minutes) ? preg_replace('/^0/', '', $minutes) : '';
$seconds = !empty($seconds) ? preg_replace('/^0/', '', $seconds) : '';
// strip any leading or trailing spaces
$time_string = trim(
+1 -1
View File
@@ -536,7 +536,7 @@ class PgSQL implements Interface\SqlFunctions
$connection_string[] = 'sslmode=' . $db_ssl;
}
// connect
$this->dbh = pg_connect(join(' ', $connection_string));
$this->dbh = @pg_connect(join(' ', $connection_string));
return $this->dbh;
}
+4 -4
View File
@@ -32,11 +32,11 @@ class FileWriter
if (!is_writeable($folder)) {
return false;
}
// if last is not / then add
if (substr($folder, -1, 1) != DIRECTORY_SEPARATOR) {
$folder .= DIRECTORY_SEPARATOR;
if (!is_dir($folder)) {
return false;
}
self::$debug_folder = $folder;
// if last is not / then add
self::$debug_folder = rtrim($folder, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
return true;
}
+3 -3
View File
@@ -146,7 +146,7 @@ class L10n
* @param string $locale language name, if not set, try previous set
* @param string $domain set name for mo file, if not set, try previous set
* @param string $path path, if not set try to get from paths array, else self
* @param string $override_encoding if locale does not env encoding set, use this one
* @param string $override_encoding if locale does not have encoding set, use this one
* @return GetTextReader the main gettext reader object
*/
public function getTranslator(
@@ -301,7 +301,7 @@ class L10n
* Get the local as array same to the GetLocale::setLocale return
* This does not set from outside, but only what is set in the l10n class
*
* @return array{locale: string, lang: string, lang_short: string, domain: string, encoding: string, path: string}
* @return array{locale:string,lang:string,lang_short:string,domain:string,encoding:string,path:string}
*/
public function getLocaleAsArray(): array
{
@@ -321,7 +321,7 @@ class L10n
* parse the locale string for further processing
*
* @param string $locale Locale to parse
* @return array<string,string|null> array with lang, country, charset, modifier
* @return array{lang:string|null,country:string|null,charset:string|null,modifier:string|null} parsed locale
*/
public static function parseLocale(string $locale = ''): array
{
+2 -2
View File
@@ -86,7 +86,7 @@ enum Level: int
/**
* @param value-of<self::NAMES>|LogLevel::*|'Debug'|'Info'|'Notice'|'Warning'|'Error'|'Critical'|'Alert'|'Emergency' $name
* @return static
* @return self
*/
public static function fromName(string $name): self
{
@@ -104,7 +104,7 @@ enum Level: int
/**
* @param value-of<self::VALUES> $value
* @return static
* @return self
*/
public static function fromValue(int $value): self
{
+20 -13
View File
@@ -232,8 +232,15 @@ class Elements
* @param string $class style sheet
* @return string correct string for url href process
*/
private static function createUrl($href, $atag, $_1, $_2, $_3, $name, $class): string
{
private static function createUrl(
string $href,
string $atag,
string $_1,
string $_2,
string $_3,
string $name,
string $class
): string {
// $this->debug('URL', "1: $_1 - 2: $_2 - $_3 - atag: $atag - name: $name - class: $class");
// if $_1 ends with //, then we strip $_1 complete & target is also blanked (its an internal link)
if (preg_match("/\/\/$/", $_1) && preg_match("/^\//", $_2)) {
@@ -250,11 +257,8 @@ class Elements
. "##GT##" . ($name ? $name : $_2 . $_3) . "##LT##/a##GT##";
} elseif ($href && !$atag) {
return "href=##QUOT##$_1$_2$_3##QUOT##";
} elseif ($atag) {
return $atag . $_2 . $_3;
} else {
return $href;
}
return $atag . $_2 . $_3;
}
/**
@@ -269,8 +273,15 @@ class Elements
* @param string $class style sheet
* @return string created html email a href string
*/
private static function createEmail($mailto, $atag, $_1, $_2, $_3, $title, $class)
{
private static function createEmail(
string $mailto,
string $atag,
string $_1,
string $_2,
string $_3,
string $title,
string $class
): string {
$email = $_1 . "@" . $_2 . "." . $_3;
if (!$mailto && !$atag) {
return "##LT##a href=##QUOT##mailto:" . $email . "##QUOT##"
@@ -278,12 +289,8 @@ class Elements
. "##GT##" . ($title ? $title : $email) . "##LT##/a##GT##";
} elseif ($mailto && !$atag) {
return "mailto:" . $email;
} elseif ($atag) {
return $atag . $email;
} else {
// else just return email as is
return $email;
}
return $atag . $email;
}
}
+11 -8
View File
@@ -954,11 +954,10 @@ class Curl implements Interface\RequestsInterface
)
) {
unset($this->config['headers'][$header_key]);
unset($this->headers_named[$header_key]);
unset($this->headers_named[strtolower($header_key)]);
} elseif (
// string value, array keys = in
// or both array and not a full match in the one before
(is_string($value) || is_array($value)) &&
// right side is array, and value is anything string or array
// if right side is string, and we give value array, we do nothing
is_array($this->config['headers'][$header_key])
) {
// part remove of key, value must be array
@@ -966,10 +965,14 @@ class Curl implements Interface\RequestsInterface
$value = [$value];
}
// array values so we rewrite the key pos
$this->config['headers'][$header_key] = array_values(array_diff(
$this->config['headers'][$header_key],
$value
));
/** @var array<int|string,string> $headers */
$headers = $this->config['headers'][$header_key];
$this->config['headers'][$header_key] = array_values(
array_diff(
$headers,
$value
)
);
}
}
}
@@ -12,6 +12,8 @@ use PHPUnit\Framework\TestCase;
*/
final class CoreLibsAAASetupDataTest extends TestCase
{
public const TIME_ZONE = 'Asia/Tokyo';
/**
* Covers nothing
*
@@ -34,6 +36,9 @@ final class CoreLibsAAASetupDataTest extends TestCase
BASE,
'BASE Path set check'
);
// if time zone is not set, errors can happen
ini_set('date.timezone', self::TIME_ZONE);
}
}
+21 -15
View File
@@ -80,21 +80,27 @@ final class CoreLibsACLLoginTest extends TestCase
'log_file_id' => 'CoreLibs-ACL-Login-Test',
]);
// test database we need to connect do, if not possible this test is skipped
self::$db = new \CoreLibs\DB\IO(
[
'db_name' => $db_name,
'db_user' => $db_user,
'db_pass' => $db_password,
'db_host' => $db_host,
'db_port' => 5432,
'db_schema' => 'public',
'db_type' => 'pgsql',
'db_encoding' => '',
'db_ssl' => 'allow', // allow, disable, require, prefer
'db_debug' => true,
],
self::$log
);
try {
self::$db = new \CoreLibs\DB\IO(
[
'db_name' => $db_name,
'db_user' => $db_user,
'db_pass' => $db_password,
'db_host' => $db_host,
'db_port' => 5432,
'db_schema' => 'public',
'db_type' => 'pgsql',
'db_encoding' => '',
'db_ssl' => 'allow', // allow, disable, require, prefer
'db_debug' => true,
],
self::$log
);
} catch (\Exception $e) {
self::markTestSkipped(
'Cannot connect to Test DB for ACL\Login test: ' . $e->getMessage()
);
}
// ALWAYS drop DB and RECREATE DB
// dropdb -U corelibs_acl_login_test -h localhost corelibs_acl_login_test
// createdb -U corelibs_acl_login_test -O corelibs_acl_login_test -E utf8 corelibs_acl_login_test;
@@ -15,6 +15,12 @@ if [ ! -f "${load_sql}" ]; then
echo 1;
exit 1;
fi;
# if we have no dropdb, createdb, psql, exit with 6
if ! command -v dropdb &> /dev/null || ! command -v createdb &> /dev/null || ! command -v psql &> /dev/null; then
echo 6;
exit 6;
fi;
db_user="${2}";
db_name="${3}";
db_host="${4}";
@@ -24,25 +30,25 @@ if [ -z "${db_user}" ] || [ -z "${db_name}" ] || [ -z "${db_host}" ]; then
exit 2;
fi;
# drop database, on error exit with 3
dropdb -U ${db_user} -h ${db_host} ${db_name} 2>&1;
if [ $? -ne 0 ]; then
dropdb -U "${db_user}" -h "${db_host}" "${db_name}" 2>&1;
if [ ! $? ]; then
echo 3;
exit 3;
fi;
# create database, on error exit with 4
createdb -U ${db_user} -O ${db_user} -h ${db_host} -E utf8 ${db_name} 2>&1;
if [ $? -ne 0 ]; then
createdb -U "${db_user}" -O "${db_user}" -h "${db_host}" -E utf8 "${db_name}" 2>&1;
if [ ! $? ]; then
echo 4;
exit 4;
fi;
# if error 5 thrown, test with enabled below
if [ ! -z "${5}" ]; then
psql -U ${db_user} -h ${db_host} -f ${load_sql} ${db_name};
if [ -n "${5}" ]; then
psql -U "${db_user}" -h "${db_host}" -f "${load_sql}" "${db_name}";
else
# load data (redirect ALL error to null), on error exit with 5
psql -U ${db_user} -h ${db_host} -f ${load_sql} ${db_name} 2>&1 1>/dev/null 2>/dev/null;
psql -U "${db_user}" -h "${db_host}" -f "${load_sql}" "${db_name}" 2>&1 1>/dev/null 2>/dev/null;
fi;
if [ $? -ne 0 ]; then
if [ ! $? ]; then
echo 5;
exit 5;
fi;
@@ -1266,7 +1266,8 @@ final class CoreLibsCombinedArrayHandlerTest extends TestCase
/**
* Undocumented function
*
* @covers ::arrayGetPrevKey, ::arrayGetNextKey
* @covers ::arrayGetPrevKey
* @covers ::arrayGetNextKey
* @dataProvider providerArrayGetNextPrevKey
* @testdox arrayGetNextPrevKey get next/prev key for $search wtih $expected_prev/$expected_next [$_dataName]
*
@@ -1,4 +1,4 @@
<?php
<?php // phpcs:disable Generic.Files.LineLength
declare(strict_types=1);
@@ -71,15 +71,16 @@ final class CoreLibsCombinedDateTimeTest extends TestCase
*
* @covers ::dateStringFormat
* @dataProvider timestampProvider
* @testdox dateStringFormat $input (microtime $flag) will be $expected [$_dataName]
* @testdox dateStringFormat $input (mt $flag_show_micro, float mt $flag_micro_as_float) will be $expected [$_dataName]
*
* @param int|float $input
* @param bool $flag
* @param bool $flag_show_micro
* @param bool $flag_micro_as_float
* @param string $expected
* @return void
*/
public function testDateStringFormat(
$input,
int|float $input,
bool $flag_show_micro,
bool $flag_micro_as_float,
string $expected
@@ -101,7 +101,7 @@ final class CoreLibsConvertColorTest extends TestCase
* @covers ::rgbToHwb
* @covers ::hsbToRgb
* @covers ::hslToRgb
* @covers ::hwebToRgb
* @covers ::hwbToRgb
* @testdox Convert from and to RGB via HSL, HWB, HSB/V
*
* @return void
@@ -298,7 +298,6 @@ final class CoreLibsConvertColorTest extends TestCase
/**
* Undocumented function
*
* @covers ::returnAsHex()
* @testdox Convert from and to RGB via hex
*
* @return void
@@ -342,8 +341,6 @@ final class CoreLibsConvertColorTest extends TestCase
/**
* linear RGB conversion tests
*
* @covers ::fromLinear
* @covers ::toLinear
* @testdox Convert from and to RGB linear conversion check
*
* @return void
@@ -933,7 +930,6 @@ final class CoreLibsConvertColorTest extends TestCase
/**
* Undocumented function
*
* @covers ::__get
* @testdox Exception handling for RGB general calls
*
* @return void
@@ -958,7 +954,6 @@ final class CoreLibsConvertColorTest extends TestCase
/**
* Undocumented function
*
* @covers ::setFromHex
* @testdox Exception handling for RGB setFromHex failues
*
* @return void
@@ -1086,7 +1081,6 @@ final class CoreLibsConvertColorTest extends TestCase
/**
* Undocumented function
*
* @covers ::__get
* @testdox Exception handling for Lab general calls
*
* @return void
@@ -1120,7 +1114,6 @@ final class CoreLibsConvertColorTest extends TestCase
/**
* Undocumented function
*
* @covers ::__get
* @testdox Exception handling for LCH general calls
*
* @return void
@@ -1155,7 +1148,6 @@ final class CoreLibsConvertColorTest extends TestCase
/**
* Undocumented function
*
* @covers ::__get
* @testdox Exception handling for XYZ general calls
*
* @return void
@@ -671,7 +671,7 @@ final class CoreLibsConvertStringsTest extends TestCase
/**
* Undocumented function
*
* @covers ::isValidRegexSimple
* @covers ::isValidRegex
* @dataProvider isValidRegexSimpleProvider
* @testdox isValidRegexSimple make $input unqiue to $expected [$_dataName]
*
@@ -87,7 +87,7 @@ final class CoreLibsCreateRandomKeyTest extends TestCase
/**
* Undocumented function
*
* @covers ::randomKeyGeyn
* @covers ::randomKeyGen
* @dataProvider randomKeyGenProvider
* @testdox randomKeyGen use $input key length $expected [$_dataName]
*
@@ -78,7 +78,6 @@ final class CoreLibsCreateSessionTest extends TestCase
/**
* Test session start
*
* @covers ::startSession
* @dataProvider sessionProvider
* @testdox startSession $input name for $type will be $expected (error: $expected_error) [$_dataName]
*
@@ -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
+10 -8
View File
@@ -123,10 +123,16 @@ final class CoreLibsDBIOTest extends TestCase
'log_file_id' => 'CoreLibs-DB-IO-Test',
]);
// will be true, default logging is true
$db = new \CoreLibs\DB\IO(
self::$db_config['valid'],
self::$log
);
try {
$db = new \CoreLibs\DB\IO(
self::$db_config['valid'],
self::$log
);
} catch (\Exception $e) {
self::markTestSkipped(
'Cannot connect to Test DB for DB\IO test: ' . $e->getMessage()
);
}
if (!$db->dbGetConnectionStatus()) {
self::markTestSkipped(
'Cannot connect to valid Test DB for DB\IO test.'
@@ -543,8 +549,6 @@ final class CoreLibsDBIOTest extends TestCase
/**
* Test dbSetDbug, dbGetDebug
*
* @covers ::dbGetDbug
* @covers ::dbSetDebug
* @testdox Set and Get Debug flag
*
* @return void
@@ -3021,8 +3025,6 @@ final class CoreLibsDBIOTest extends TestCase
* @covers ::dbReturnParams
* @covers ::dbCacheReset
* @covers ::dbGetCursorExt
* @covers ::dbCursorPos
* @covers ::dbCursorNumRows
* @dataProvider dbReturnProvider
* @testdox dbReturn Read First $read_first_only only and cache $flag_cache and assoc $flag_assoc with (Warning: $warning/Error: $error) [$_dataName]
*
@@ -13,29 +13,6 @@ use PHPUnit\Framework\TestCase;
*/
final class CoreLibsDebugFileWriterTest extends TestCase
{
/**
* Undocumented function
*
* @return array
*/
public function fsetFolderProvider(): array
{
return [
'valid log folder name' => [
0 => '/tmp/',
1 => true,
],
'invalid log folder name' => [
0 => 'some name',
1 => false,
],
'not writeable log folder name' => [
0 => '/opt',
1 => false,
]
];
}
/**
* Undocumented function
*
@@ -85,18 +62,59 @@ final class CoreLibsDebugFileWriterTest extends TestCase
/**
* Undocumented function
*
* @dataProvider fsetFolderProvider
* @testdox fsetFolder $input will match $expected [$_dataName]
* @testdox fsetFolder test correct return code
*
* @param string $input
* @param boolean $expected
* @return void
*/
public function testFsetFolder(string $input, bool $expected): void
public function testFsetFolder(): void
{
// check the following
// - valid folder, writeable
// - valid folder, not writeable
// - invalid folder (eg file)
// - invalid folder name (eg contains spaces), must match ^[\w\-\/]+
// if we have no /tmp/ folder, we cannot test this, so skip the test
if (!is_dir('/tmp')) {
$this->markTestSkipped('No /tmp folder found, cannot test fsetFolder');
}
// TEST 3:
// create a file in /tmp/ to test invalid folder (eg file)
$test_file = '/tmp/somefile.txt';
if (!is_file($test_file)) {
touch($test_file);
}
$this->assertEquals(
$expected,
\CoreLibs\Debug\FileWriter::fsetFolder($input)
false,
\CoreLibs\Debug\FileWriter::fsetFolder($test_file)
);
// TEST 4:
// test invalid folder name (eg contains spaces), must match ^[\w\-\/]+
$this->assertEquals(
false,
\CoreLibs\Debug\FileWriter::fsetFolder('some name')
);
// TEST 1:
// create a folder in /tmp/ to test valid folder, writeable
$test_folder = '/tmp/somefolder';
if (!is_dir($test_folder)) {
mkdir($test_folder);
}
$this->assertEquals(
true,
\CoreLibs\Debug\FileWriter::fsetFolder($test_folder)
);
// TEST 2:
// create a folder in /tmp/ to test valid folder, not writeable
$test_folder = '/tmp/somefolder2';
if (!is_dir($test_folder)) {
mkdir($test_folder);
}
// remove all write permissions for the folder
chmod($test_folder, 0555);
$this->assertEquals(
false,
\CoreLibs\Debug\FileWriter::fsetFolder($test_folder)
);
}
+35 -22
View File
@@ -48,8 +48,8 @@ final class CoreLibsDebugSupportTest extends TestCase
* @dataProvider printTimeProvider
* @testdox printTime test with $microtime and match to regex [$_dataName]
*
* @param int|null $mircrotime
* @param string $expected
* @param ?int $microtime
* @param string $regex
* @return void
*/
public function testPrintTime(?int $microtime, string $regex): void
@@ -460,10 +460,8 @@ final class CoreLibsDebugSupportTest extends TestCase
* Undocumented function
*
* @cover ::getCallerFileLine
* @testWith ["vendor/phpunit/phpunit/src/Framework/TestCase.php:6434","phar:///home/clemens/.phive/phars/phpunit-9.6.13.phar/phpunit/Framework/TestCase.php:6434"]
* @testdox getCallerFileLine check based on regex .../Framework/TestCase.php:\d+ [$_dataName]
*
* @param string $expected
* @return void
*/
public function testGetCallerFileLine(): void
@@ -471,15 +469,19 @@ final class CoreLibsDebugSupportTest extends TestCase
// regex prefix with path "/../" and then fixed vendor + \d+
// or phar start if phiev installed
// phar:///home/clemens/.phive/phars/phpunit-9.6.13.phar/phpunit/Framework/TestCase.php
// phar:///usr/local/bin/phpunit/phpunit/Framework/TestCase.php
$regex = "/^("
. "\/.*\/vendor\/phpunit\/phpunit\/src"
. "|"
. "phar:\/\/\/.*\.phive\/phars\/phpunit-\d+\.\d+\.\d+\.phar\/phpunit"
. "|"
. "phar:\/\/\/usr\/local\/bin\/phpunit\/phpunit"
. ")"
. "\/Framework\/TestCase.php:\d+$/";
$this->assertMatchesRegularExpression(
$regex,
Support::getCallerFileLine()
Support::getCallerFileLine(),
'Failed for: ' . Support::getCallerFileLine()
);
}
@@ -522,7 +524,7 @@ final class CoreLibsDebugSupportTest extends TestCase
$this->assertEquals(
$expected,
$compare,
'assert expected 10'
'assert expected 10: ' . print_r($compare, true)
);
break;
case 11:
@@ -545,27 +547,38 @@ final class CoreLibsDebugSupportTest extends TestCase
$this->assertEquals(
$expected,
$compare,
'assert expected 11'
'assert expected 11: ' . print_r($compare, true)
);
break;
case 12:
// add two "run" before "runBare"
array_splice(
$expected,
7,
0,
['run']
);
array_splice(
$expected,
0,
0,
['include']
);
// if compare starts with "main"
if ($compare[0] == 'main') {
// add two more run after main
array_splice(
$expected,
1,
0,
['run', 'run']
);
} else {
// add two "run" before "runBare"
array_splice(
$expected,
7,
0,
['run']
);
array_splice(
$expected,
0,
0,
['include']
);
}
$this->assertEquals(
$expected,
$compare,
'assert expected 12'
'assert expected 12: ' . print_r($compare, true)
);
break;
default:
@@ -589,7 +602,7 @@ final class CoreLibsDebugSupportTest extends TestCase
if ($call_stack < 8) {
$this->assertFalse(true, 'getCallStack too low: 8');
} else {
$this->assertTrue(true, 'getCallSteck ok');
$this->assertTrue(true, 'getCallStack ok');
}
// just test top entry
$first = array_shift($call_stack);
+1
View File
@@ -0,0 +1 @@
test.env
@@ -442,7 +442,6 @@ final class CoreLibsLanguageL10nTest extends TestCase
* init check and connected change translation
*
* @covers ::getTranslator
* @covers ::l10nReloadMOfile
* @dataProvider getTranslatorProvider
* @testdox change locale from $locale and domain $domain to locale $locale_new and domain $domain_new [$_dataName]
*
@@ -639,7 +638,7 @@ final class CoreLibsLanguageL10nTest extends TestCase
* plural and plural context
*
* @covers ::__n
* @covers ::__pn
* @covers ::__np
* @dataProvider ngettextProvider
* @testdox plural string test for locale $locale and domain $domain with $context [$_dataName]
*
@@ -865,6 +864,7 @@ final class CoreLibsLanguageL10nTest extends TestCase
string $value,
string $expected
): void {
$old_value = null;
switch ($type) {
case 'global':
$GLOBALS[$var] = $value;
@@ -1101,11 +1101,11 @@ final class CoreLibsLanguageL10nTest extends TestCase
* fuctions check
* TODO: others d/dn/dp/dnp gettext functions
*
* @covers __setlocale
* @covers __bindtextdomain
* @covers __bind_textdomain_codeset
* @covers __textdomain
* @covers __gettext
* @covers _setlocale
* @covers _bindtextdomain
* @covers _bind_textdomain_codeset
* @covers _textdomain
* @covers _gettext
* @covers __
* @dataProvider functionsProvider
* @testdox check functions with locale $locale and domain $domain [$_dataName]
@@ -514,7 +514,6 @@ final class CoreLibsLoggingLoggingTest extends TestCase
/**
* Undocumented function
*
* @covers Logger\Flag
* @testdox Logger\Flag enum test
*
* @return void
@@ -828,6 +827,7 @@ final class CoreLibsLoggingLoggingTest extends TestCase
// clean all data in folder first
array_map('unlink', glob($log->getLogFolder() . $log->getLogFileId() . '*.log'));
$log_status = false;
switch ($level->value) {
case 200:
$log_status = $log->info($message);
@@ -851,7 +851,7 @@ final class CoreLibsLoggingLoggingTest extends TestCase
$log_status = $log->emergency($message);
break;
}
$this->assertTrue($log_status, 'log write successful');
$this->assertTrue($log_status, 'log write unsuccessful for level: ' . $level->getName());
$file_content = file_get_contents(
$log->getLogFolder() . $log->getLogFile()
) ?: '';
@@ -334,7 +334,6 @@ final class CoreLibsSecurityAsymmetricAnonymousEncryptionTest extends TestCase
/**
* test encrypt/decrypt produce correct output
*
* @covers ::generateRandomKey
* @covers ::encrypt
* @covers ::decrypt
* @dataProvider providerEncryptDecryptSuccess
@@ -370,7 +369,6 @@ final class CoreLibsSecurityAsymmetricAnonymousEncryptionTest extends TestCase
/**
* test encrypt/decrypt produce correct output
*
* @covers ::generateRandomKey
* @covers ::encrypt
* @covers ::decrypt
* @dataProvider providerEncryptDecryptSuccess
@@ -397,7 +395,6 @@ final class CoreLibsSecurityAsymmetricAnonymousEncryptionTest extends TestCase
/**
* test encrypt/decrypt produce correct output
*
* @covers ::generateRandomKey
* @covers ::encrypt
* @covers ::decrypt
* @dataProvider providerEncryptDecryptSuccess
@@ -424,7 +421,6 @@ final class CoreLibsSecurityAsymmetricAnonymousEncryptionTest extends TestCase
/**
* test encrypt/decrypt produce correct output
*
* @covers ::generateRandomKey
* @covers ::encrypt
* @covers ::decrypt
* @dataProvider providerEncryptDecryptSuccess
@@ -469,7 +465,6 @@ final class CoreLibsSecurityAsymmetricAnonymousEncryptionTest extends TestCase
/**
* Test decryption with wrong key
*
* @covers ::generateRandomKey
* @covers ::encrypt
* @covers ::decrypt
* @dataProvider providerEncryptFailed
@@ -496,7 +491,6 @@ final class CoreLibsSecurityAsymmetricAnonymousEncryptionTest extends TestCase
/**
* Test decryption with wrong key
*
* @covers ::generateRandomKey
* @covers ::encrypt
* @covers ::decrypt
* @dataProvider providerEncryptFailed
@@ -521,7 +515,6 @@ final class CoreLibsSecurityAsymmetricAnonymousEncryptionTest extends TestCase
/**
* Test decryption with wrong key
*
* @covers ::generateRandomKey
* @covers ::encrypt
* @covers ::decrypt
* @dataProvider providerEncryptFailed
@@ -104,7 +104,6 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
/**
* test encrypt/decrypt produce correct output
*
* @covers ::generateRandomKey
* @covers ::encrypt
* @covers ::decrypt
* @dataProvider providerEncryptDecryptSuccess
@@ -132,7 +131,6 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
/**
* test encrypt/decrypt produce correct output
*
* @covers ::generateRandomKey
* @covers ::encrypt
* @covers ::decrypt
* @dataProvider providerEncryptDecryptSuccess
@@ -158,7 +156,6 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
/**
* test encrypt/decrypt produce correct output
*
* @covers ::generateRandomKey
* @covers ::encryptKey
* @covers ::decryptKey
* @dataProvider providerEncryptDecryptSuccess
@@ -202,7 +199,6 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
/**
* Test decryption with wrong key
*
* @covers ::generateRandomKey
* @covers ::encrypt
* @covers ::decrypt
* @dataProvider providerEncryptFailed
@@ -228,7 +224,6 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
/**
* Test decryption with wrong key
*
* @covers ::generateRandomKey
* @covers ::encrypt
* @covers ::decrypt
* @dataProvider providerEncryptFailed
@@ -252,7 +247,6 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
/**
* Test decryption with wrong key
*
* @covers ::generateRandomKey
* @covers ::encryptKey
* @covers ::decryptKey
* @dataProvider providerEncryptFailed
@@ -42,7 +42,6 @@ final class CoreLibsTemplateHtmlBuilderElementTest extends TestCase
/**
* Undocumented function
*
* @covers ::Element
* @covers ::buildHtml
* @covers ::getTag
* @covers ::getId
@@ -58,6 +58,11 @@ final class CoreLibsUrlRequestsCurlTest extends TestCase
if ($handle === false) {
continue;
}
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
$status = curl_exec($handle);
if ($status === false) {
continue;
}
$this->url_basic = $url;
// print "Open: $url\n";
break;
@@ -459,20 +464,19 @@ final class CoreLibsUrlRequestsCurlTest extends TestCase
/**
* set setup + header, base uri change
*
* @covers ::Curl
* @covers ::setBaseUri
* @covers ::addHeader
* @covers ::removeHEader
* @covers ::setHeaders
* @covers ::removeHeaders
* @dataProvider providerUrlRequestsCurlSetup
* @testdox UrlRequests\Curl Class setup tasks [$_dataName]
*
* @param null|array $config
* @param array $expected
* @param null|string $new_base_uri
* @param null|array $set_header
* @param null|bool $set_header_add
* @param null|array $remove_header
* @param null|array $expected_change
* @param null|array $config
* @param array<string,mixed> $expected_set
* @param null|string $new_base_uri
* @param null|array $set_header
* @param null|bool $set_header_add
* @param null|array $remove_header
* @param null|array $expected_change
* @return void
*/
public function testUrlRequestsCurlSetupConfig(
@@ -492,10 +496,18 @@ final class CoreLibsUrlRequestsCurlTest extends TestCase
};
// if ($new_base_uri === null && $set_header === null && $remove_header === null) {
// }
$this->assertEquals($expected_set, $curl->getConfig(), 'Class setup config mismatch');
$this->assertEquals(
$expected_set,
$curl->getConfig(),
'Class setup config mismatch'
);
if ($new_base_uri !== null) {
$curl->setBaseUri($new_base_uri);
$this->assertEquals($expected_change, $curl->getConfig(), 'new base_uri not matching');
$this->assertEquals(
$expected_change,
$curl->getConfig(),
'new base_uri not matching'
);
}
if ($set_header !== null) {
if ($set_header_add !== null) {
@@ -503,11 +515,19 @@ final class CoreLibsUrlRequestsCurlTest extends TestCase
} else {
$curl->setHeaders($set_header);
}
$this->assertEquals($expected_change, $curl->getConfig(), 'new headers not matching');
$this->assertEquals(
$expected_change,
$curl->getConfig(),
'new headers not matching'
);
}
if ($remove_header !== null) {
$curl->removeHeaders($remove_header);
$this->assertEquals($expected_change, $curl->getConfig(), 'removed headers not matching');
$this->assertEquals(
$expected_change,
$curl->getConfig(),
'removed headers not matching'
);
}
}
@@ -877,7 +897,7 @@ final class CoreLibsUrlRequestsCurlTest extends TestCase
string $return_content
) {
if (!$this->url_basic) {
$this->markTestSkipped('No backend interface setup for testing: GET');
$this->markTestSkipped('No backend interface setup for testing');
}
$curl = new \CoreLibs\UrlRequests\Curl();
// options
@@ -960,6 +980,9 @@ final class CoreLibsUrlRequestsCurlTest extends TestCase
*/
public function testUrlRequestsCurlRequestMultiple()
{
if (!$this->url_basic) {
$this->markTestSkipped('No backend interface setup for testing');
}
$curl = new \CoreLibs\UrlRequests\Curl();
// get
$response = $curl->get($this->url_basic, [
@@ -1051,6 +1074,9 @@ final class CoreLibsUrlRequestsCurlTest extends TestCase
*/
public function testUrlRequestsCurlAuthHeader()
{
if (!$this->url_basic) {
$this->markTestSkipped('No backend interface setup for testing');
}
$curl = new \CoreLibs\UrlRequests\Curl([
"auth" => ["user", "pass", "basic"],
"http_errors" => false,
@@ -1117,6 +1143,9 @@ final class CoreLibsUrlRequestsCurlTest extends TestCase
*/
public function testExceptionInvalidHeaderKey(): void
{
if (!$this->url_basic) {
$this->markTestSkipped('No backend interface setup for testing');
}
$curl = new \CoreLibs\UrlRequests\Curl();
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessageMatches("/InvalidHeaderKey/");
@@ -1137,6 +1166,9 @@ final class CoreLibsUrlRequestsCurlTest extends TestCase
*/
public function testExceptionInvalidHeaderValue(): void
{
if (!$this->url_basic) {
$this->markTestSkipped('No backend interface setup for testing');
}
$curl = new \CoreLibs\UrlRequests\Curl();
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessageMatches("/InvalidHeaderValue/");
@@ -1186,6 +1218,9 @@ final class CoreLibsUrlRequestsCurlTest extends TestCase
*/
public function testExceptionBadRequest(): void
{
if (!$this->url_basic) {
$this->markTestSkipped('No backend interface setup for testing');
}
$curl = new \CoreLibs\UrlRequests\Curl(["http_errors" => true]);
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessageMatches("/ClientError/");
@@ -1207,6 +1242,9 @@ final class CoreLibsUrlRequestsCurlTest extends TestCase
*/
public function testExceptionBadRequestEnable(): void
{
if (!$this->url_basic) {
$this->markTestSkipped('No backend interface setup for testing');
}
$curl = new \CoreLibs\UrlRequests\Curl(["http_errors" => false]);
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessageMatches("/ClientError/");
@@ -1229,6 +1267,9 @@ final class CoreLibsUrlRequestsCurlTest extends TestCase
*/
public function testExceptionBadRequestUnset(): void
{
if (!$this->url_basic) {
$this->markTestSkipped('No backend interface setup for testing');
}
// if true, with false it has to be off
$curl = new \CoreLibs\UrlRequests\Curl(["http_errors" => true]);
$response = $curl->request('get', $this->url_basic, [