Skip to content

Commit 5f478a4

Browse files
authored
Merge pull request #37 from nanasess/phpt-tests
feat: Add Docker-based PHPT test runner for comprehensive bcmath polyfill testing
2 parents 41852cf + 640479a commit 5f478a4

7 files changed

Lines changed: 342 additions & 274 deletions

File tree

.github/workflows/ci.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,25 @@ jobs:
7777
fail-fast: false
7878
matrix:
7979
php-version: ['8.1', '8.2', '8.3', '8.4']
80+
81+
docker-phpt-tests:
82+
name: Docker PHPT Tests
83+
needs: phpstan
84+
timeout-minutes: 15
85+
runs-on: ubuntu-latest
86+
steps:
87+
- name: Checkout
88+
uses: actions/checkout@v5
89+
- name: Checkout php-src repository
90+
uses: actions/checkout@v5
91+
with:
92+
repository: php/php-src
93+
path: php-src
94+
- name: Build Docker test image
95+
run: docker build -f Dockerfile.test-without-bcmath --build-arg PHP_VERSION=${{ matrix.php-version }} -t bcmath-phpt-test:${{ matrix.php-version }} .
96+
- name: Run Docker-based PHPT tests
97+
run: docker run --rm -v $PWD:/app bcmath-phpt-test:${{ matrix.php-version }} --skip bcceil,bccomp,bcdivmod,bcfloor,bcmod,bcpow,bcpowmod,bcround,bcscale,bug54598,bug72093,bug75178,gh15968,gh16262,scale_ini,str2num_formatting,bcmul_check_overflow,bug78878,bccomp_variation001,bccomp_variation002,bcdivmod_by_zero,bcmod_error2,bcpow_div_by_zero,bcpow_error1,bcpow_error2,bcpow_error3,bcpow_large_numbers,bcpow_zero,bcpowmod_error,bcpowmod_with_mod_1,bcpowmod_zero_modulus,bcround_all,bcround_away_from_zero,bcround_ceiling,bcround_early_return,bcround_floor,bcround_half_down,bcround_toward_zero,bcscale_variation003
98+
strategy:
99+
fail-fast: false
100+
matrix:
101+
php-version: ['8.1', '8.2', '8.3', '8.4']

.github/workflows/php-src-bcmath-tests.yml

Lines changed: 0 additions & 39 deletions
This file was deleted.

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,9 @@ phpunit.xml
66
tests/php-src/*.phpt
77
tests/php-src/*.php
88
tests/php-src/*.inc
9+
tests/php-src/*.diff
10+
tests/php-src/*.exp
11+
tests/php-src/*.log
12+
tests/php-src/*.out
13+
tests/php-src/*.sh
14+
*.cache

Dockerfile.test-without-bcmath

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
ARG PHP_VERSION=8.3
2+
FROM php:${PHP_VERSION}-cli
3+
4+
# Install system dependencies
5+
RUN apt-get update && apt-get install -y \
6+
git \
7+
unzip \
8+
&& rm -rf /var/lib/apt/lists/*
9+
10+
# Install Composer
11+
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
12+
13+
# Ensure bcmath extension is not available
14+
RUN php -m | grep bcmath && echo 'extension=' > /usr/local/etc/php/conf.d/disable-bcmath.ini || echo "bcmath not loaded"
15+
16+
# Verify bcmath is not available
17+
RUN php -m | grep bcmath && exit 1 || echo "bcmath extension not loaded - ready for testing"
18+
RUN php -r "var_dump(extension_loaded('bcmath')); exit(extension_loaded('bcmath') ? 1 : 0);"
19+
20+
# Set working directory
21+
WORKDIR /app
22+
23+
# Copy and setup PHPT test runner script
24+
COPY scripts/docker-phpt-runner.sh /usr/local/bin/
25+
RUN chmod +x /usr/local/bin/docker-phpt-runner.sh
26+
27+
# Default entrypoint
28+
ENTRYPOINT ["docker-phpt-runner.sh"]

README.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,58 @@ composer remove phpseclib/bcmath_compat
146146
composer require nanasess/bcmath-polyfill
147147
```
148148

149+
## 🧪 Testing
150+
151+
### Running PHPUnit Tests
152+
153+
```bash
154+
# Install dependencies
155+
composer install
156+
157+
# Run all tests
158+
composer test
159+
# or
160+
vendor/bin/phpunit
161+
162+
# Run tests without bcmath extension
163+
vendor/bin/phpunit --group without-bcmath
164+
```
165+
166+
### Docker-based PHPT Testing
167+
168+
This project includes comprehensive Docker-based testing using official PHP core bcmath tests to ensure 100% compatibility:
169+
170+
```bash
171+
# Build Docker test environment (PHP 8.3 by default)
172+
docker build -f Dockerfile.test-without-bcmath -t bcmath-phpt-test .
173+
174+
# Run all PHPT tests
175+
docker run --rm -v $PWD:/app bcmath-phpt-test
176+
177+
# Build and test with specific PHP version
178+
docker build -f Dockerfile.test-without-bcmath --build-arg PHP_VERSION=8.4 -t bcmath-phpt-test:8.4 .
179+
docker run --rm -v $PWD:/app bcmath-phpt-test:8.4
180+
181+
# Skip specific tests (supports exact test name matching)
182+
docker run --rm -v $PWD:/app bcmath-phpt-test --skip bcceil,bcround,bcpowmod
183+
184+
# Run specific test file
185+
docker run --rm -v $PWD:/app bcmath-phpt-test tests/php-src/bcadd.phpt
186+
187+
# Show help
188+
docker run --rm bcmath-phpt-test --help
189+
```
190+
191+
#### Available Options
192+
193+
- `--skip TESTS` - Comma-separated list of test names to skip (exact matching)
194+
- `--help, -h` - Show usage information
195+
196+
#### Supported PHP Versions
197+
- PHP 8.1, 8.2, 8.3, 8.4
198+
199+
The Docker PHPT tests automatically run on GitHub Actions CI across all supported PHP versions to ensure comprehensive compatibility with the official PHP core bcmath test suite.
200+
149201
## 🤝 Contributing
150202

151203
Contributions are welcome! Please feel free to submit a Pull Request.

scripts/docker-phpt-runner.sh

Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
#!/bin/bash
2+
set -e
3+
4+
# Parse command line options
5+
SKIP_TESTS=""
6+
TEST_FILES=()
7+
8+
while [[ $# -gt 0 ]]; do
9+
case $1 in
10+
--skip)
11+
SKIP_TESTS="$2"
12+
shift 2
13+
;;
14+
--help|-h)
15+
echo "Usage: $0 [OPTIONS] [TEST_FILES...]"
16+
echo ""
17+
echo "Options:"
18+
echo " --skip TESTS Comma-separated list of test patterns to skip"
19+
echo " (e.g., --skip bcround,bcdivmod,bug60377)"
20+
echo " --help, -h Show this help message"
21+
echo ""
22+
echo "Examples:"
23+
echo " $0 # Run all tests"
24+
echo " $0 tests/php-src/bcadd.phpt # Run specific test"
25+
echo " $0 --skip bcround tests/php-src/bcadd*.phpt # Skip bcround tests, run bcadd tests"
26+
echo " $0 --skip bcround,bcdivmod # Skip multiple test patterns"
27+
exit 0
28+
;;
29+
*)
30+
TEST_FILES+=("$1")
31+
shift
32+
;;
33+
esac
34+
done
35+
36+
echo "=== PHPT Test Runner (without bcmath extension) ==="
37+
echo "bcmath extension loaded: $(php -r "var_dump(extension_loaded('bcmath'));")"
38+
39+
if [ -n "$SKIP_TESTS" ]; then
40+
echo "Skipping tests matching: $SKIP_TESTS"
41+
fi
42+
43+
# Install dependencies if needed (for volume mounting)
44+
if [ ! -d "vendor" ]; then
45+
echo "Installing composer dependencies..."
46+
composer install --optimize-autoloader --no-dev -q
47+
fi
48+
49+
# Prepare test environment
50+
if [ -d "php-src" ]; then
51+
echo "Setting up PHPT test environment..."
52+
mkdir -p tests/php-src
53+
54+
echo "Copying test files from php-src..."
55+
if cp php-src/ext/bcmath/tests/*.phpt tests/php-src/ 2>/dev/null; then
56+
echo "Successfully copied .phpt files"
57+
else
58+
echo "Error: Could not copy .phpt files from php-src/ext/bcmath/tests/"
59+
exit 1
60+
fi
61+
62+
if cp php-src/ext/bcmath/tests/*.inc tests/php-src/ 2>/dev/null; then
63+
echo "Successfully copied .inc files"
64+
else
65+
echo "Warning: Could not copy .inc files (may not exist)"
66+
fi
67+
68+
if cp php-src/run-tests.php ./ 2>/dev/null; then
69+
echo "Successfully copied run-tests.php"
70+
else
71+
echo "Error: Could not copy run-tests.php from php-src/"
72+
exit 1
73+
fi
74+
75+
# Remove --EXTENSIONS-- sections (integrated function)
76+
remove_extensions_from_phpt() {
77+
local phpt_dir="$1"
78+
79+
if [ ! -d "$phpt_dir" ]; then
80+
echo "Error: Directory $phpt_dir does not exist"
81+
return 1
82+
fi
83+
84+
echo "Removing --EXTENSIONS-- sections from PHPT files in $phpt_dir..."
85+
86+
local processed=0
87+
for phpt_file in "$phpt_dir"/*.phpt; do
88+
if [ -f "$phpt_file" ]; then
89+
echo "Processing $(basename "$phpt_file")"
90+
91+
# Create temporary file
92+
local temp_file=$(mktemp)
93+
94+
# Remove --EXTENSIONS-- section completely
95+
awk '
96+
BEGIN { in_extensions = 0 }
97+
/^--EXTENSIONS--$/ {
98+
in_extensions = 1
99+
next
100+
}
101+
/^--[A-Z]+--$/ && in_extensions {
102+
in_extensions = 0
103+
print
104+
next
105+
}
106+
!in_extensions { print }
107+
' "$phpt_file" > "$temp_file"
108+
109+
# Replace original file
110+
mv "$temp_file" "$phpt_file"
111+
processed=$((processed + 1))
112+
fi
113+
done
114+
115+
echo "Processed $processed PHPT files"
116+
echo "All --EXTENSIONS-- sections have been removed"
117+
}
118+
119+
remove_extensions_from_phpt tests/php-src
120+
121+
# Add bootstrap to each PHPT file
122+
echo "Adding bootstrap to PHPT files..."
123+
for phpt_file in tests/php-src/*.phpt; do
124+
if [ -f "$phpt_file" ]; then
125+
# Create backup
126+
cp "$phpt_file" "$phpt_file.bak"
127+
128+
# Add bootstrap at the beginning of the --FILE-- section
129+
awk '
130+
/^--FILE--$/ {
131+
print
132+
getline
133+
print "<?php"
134+
print "require_once \"/app/vendor/autoload.php\";"
135+
print "require_once \"/app/lib/bcmath.php\";"
136+
if ($0 == "<?php") {
137+
# Skip the original <?php line
138+
next
139+
}
140+
print
141+
next
142+
}
143+
{ print }
144+
' "$phpt_file.bak" > "$phpt_file"
145+
146+
rm "$phpt_file.bak"
147+
fi
148+
done
149+
echo "Added bootstrap to PHPT files"
150+
fi
151+
152+
# Test if polyfill file exists
153+
if [ ! -f "lib/bcmath.php" ]; then
154+
echo "Error: lib/bcmath.php not found. Make sure you've mounted the project correctly."
155+
exit 1
156+
fi
157+
158+
# Test polyfill functionality using -d option
159+
echo "Testing polyfill functionality:"
160+
161+
# Set environment for run-tests.php
162+
export TEST_PHP_EXECUTABLE="/usr/local/bin/php"
163+
164+
# Run PHPT tests
165+
if [ -f "run-tests.php" ] && [ -d "tests/php-src" ]; then
166+
echo "Running PHPT tests with EXPECT validation..."
167+
168+
# Function to check if a test should be skipped
169+
should_skip_test() {
170+
local test_file="$1"
171+
local base_name=$(basename "$test_file" .phpt)
172+
173+
if [ -z "$SKIP_TESTS" ]; then
174+
return 1 # Don't skip
175+
fi
176+
177+
# Convert comma-separated list to array
178+
IFS=',' read -ra SKIP_ARRAY <<< "$SKIP_TESTS"
179+
180+
for skip_pattern in "${SKIP_ARRAY[@]}"; do
181+
skip_pattern=$(echo "$skip_pattern" | xargs) # trim whitespace
182+
# Remove .phpt extension from skip_pattern if present
183+
skip_pattern="${skip_pattern%.phpt}"
184+
if [[ "$base_name" == "$skip_pattern" ]]; then
185+
return 0 # Should skip
186+
fi
187+
done
188+
return 1 # Don't skip
189+
}
190+
191+
# Build test file list based on arguments and skip patterns
192+
FINAL_TEST_FILES=()
193+
194+
if [ ${#TEST_FILES[@]} -gt 0 ]; then
195+
# Specific test files provided
196+
echo "Processing specific test files..."
197+
for test_file in "${TEST_FILES[@]}"; do
198+
if should_skip_test "$test_file"; then
199+
echo "Skipping: $test_file (matches skip pattern)"
200+
else
201+
FINAL_TEST_FILES+=("$test_file")
202+
fi
203+
done
204+
else
205+
# No specific files, process all files in tests/php-src/
206+
echo "Processing all test files in tests/php-src/..."
207+
for test_file in tests/php-src/*.phpt; do
208+
if [ -f "$test_file" ] && ! should_skip_test "$test_file"; then
209+
FINAL_TEST_FILES+=("$test_file")
210+
elif should_skip_test "$test_file"; then
211+
echo "Skipping: $test_file (matches skip pattern)"
212+
fi
213+
done
214+
fi
215+
216+
# Run the tests
217+
if [ ${#FINAL_TEST_FILES[@]} -gt 0 ]; then
218+
echo "Running ${#FINAL_TEST_FILES[@]} test file(s):"
219+
printf ' %s\n' "${FINAL_TEST_FILES[@]}"
220+
php run-tests.php \
221+
--show-diff \
222+
--no-clean \
223+
"${FINAL_TEST_FILES[@]}"
224+
else
225+
echo "No tests to run (all tests were skipped or no matching files found)"
226+
fi
227+
else
228+
echo "Error: run-tests.php or tests/php-src not found"
229+
echo "Make sure to:"
230+
echo " 1. Mount your project directory with -v \$PWD:/app"
231+
echo " 2. Have php-src/ directory in your project"
232+
echo " 3. Run the container to set up test files"
233+
exit 1
234+
fi

0 commit comments

Comments
 (0)