Skip to content

Commit f0c909b

Browse files
authored
Merge pull request #27 from nanasess/php-src-bcmath-tests
Add PHP-src BCMath Tests Integration
2 parents d134539 + 8bc19ce commit f0c909b

6 files changed

Lines changed: 280 additions & 4 deletions

File tree

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: PHP-src BCMath Tests
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
php-src-bcmath-tests:
7+
runs-on: ubuntu-latest
8+
9+
strategy:
10+
matrix:
11+
php-version: ['8.1', '8.2', '8.3', '8.4']
12+
13+
steps:
14+
- uses: actions/checkout@v5
15+
16+
- name: Checkout php-src repository
17+
uses: actions/checkout@v5
18+
with:
19+
repository: php/php-src
20+
path: php-src
21+
22+
- name: Setup PHP
23+
uses: shivammathur/setup-php@v2
24+
with:
25+
php-version: ${{ matrix.php-version }}
26+
extensions: :bcmath
27+
tools: composer:v2
28+
29+
- name: Install dependencies
30+
run: composer install --prefer-dist --no-progress
31+
32+
- name: Prepare php-src BCMath tests
33+
run: |
34+
mkdir -p tests/php-src
35+
cp php-src/ext/bcmath/tests/*.phpt tests/php-src/
36+
cp php-src/ext/bcmath/tests/*.inc tests/php-src/
37+
38+
- name: Run php-src BCMath tests
39+
run: ./scripts/run-php-src-tests.sh --skip gh17398,gh16262,gh15968,bcround_toward_zero,bcround_half_up,bcround_half_odd,bcround_half_even,bcround_half_down,bcround_all,bcround_floor,bcround_early_return,bcround_ceiling,bcround_away_from_zero,bcdivmod,bcpow,bcpow_error2,bcpowmod_zero_modulus,bcsqrt,bug60377,bug78878,bcdiv_error2,bcmod_error3

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,7 @@ build
22
composer.lock
33
vendor
44
phpcs.xml
5-
phpunit.xml
5+
phpunit.xml
6+
tests/php-src/*.phpt
7+
tests/php-src/*.php
8+
tests/php-src/*.inc

.php-cs-fixer.dist.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
->in(__DIR__.'/src')
55
->in(__DIR__.'/lib')
66
->in(__DIR__.'/tests')
7+
->exclude(['php-src'])
78
;
89

910
return (new PhpCsFixer\Config())

rector.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@
1616
->withPreparedSets(typeDeclarations: true, deadCode: true, codeQuality: true)
1717
->withSkip([
1818
UnwrapFutureCompatibleIfPhpVersionRector::class,
19+
__DIR__ . '/tests/php-src',
1920
]);

scripts/run-php-src-tests.sh

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
#!/bin/bash
2+
3+
# PHP-src BCMath Tests Runner
4+
# This script runs php-src BCMath tests against the polyfill
5+
#
6+
# Usage:
7+
# ./scripts/run-php-src-tests.sh [--skip test1,test2,...]
8+
#
9+
# Prerequisites:
10+
# - php-src repository should be checked out in ./php-src/
11+
# - Run these commands first:
12+
# mkdir -p tests/php-src
13+
# cp php-src/ext/bcmath/tests/*.phpt tests/php-src/
14+
# cp php-src/ext/bcmath/tests/*.inc tests/php-src/
15+
#
16+
# Examples:
17+
# ./scripts/run-php-src-tests.sh --skip bcdivmod,bcpowmod
18+
# ./scripts/run-php-src-tests.sh
19+
20+
set -e
21+
22+
# Parse command line arguments
23+
SKIP_TESTS=""
24+
while [[ $# -gt 0 ]]; do
25+
case $1 in
26+
--skip)
27+
SKIP_TESTS="$2"
28+
shift 2
29+
;;
30+
*)
31+
echo "Unknown option: $1"
32+
echo "Usage: $0 [--skip test1,test2,...]"
33+
exit 1
34+
;;
35+
esac
36+
done
37+
38+
# Colors for output
39+
RED='\033[0;31m'
40+
GREEN='\033[0;32m'
41+
YELLOW='\033[1;33m'
42+
NC='\033[0m' # No Color
43+
44+
echo "=== PHP-src BCMath Tests Runner ==="
45+
echo
46+
47+
# Check if we're in the correct directory
48+
if [ ! -f "composer.json" ]; then
49+
echo -e "${RED}Error: Please run this script from the project root directory${NC}"
50+
exit 1
51+
fi
52+
53+
# Check if test files exist
54+
if [ ! -d "tests/php-src" ] || [ -z "$(ls -A tests/php-src/*.phpt 2>/dev/null)" ]; then
55+
echo -e "${RED}Error: php-src test files not found${NC}"
56+
echo "Please run the following commands first:"
57+
echo " mkdir -p tests/php-src"
58+
echo " cp php-src/ext/bcmath/tests/*.phpt tests/php-src/"
59+
echo " cp php-src/ext/bcmath/tests/*.inc tests/php-src/"
60+
exit 1
61+
fi
62+
63+
cd tests/php-src
64+
65+
# Create common test helper
66+
echo "Creating common test helper..."
67+
cat > test_helper.php << 'EOF'
68+
<?php
69+
require_once __DIR__ . '/../../vendor/autoload.php';
70+
require_once __DIR__ . '/../../lib/bcmath.php';
71+
72+
define('STRING_PADDING', 30);
73+
74+
if (!function_exists('run_bcmath_tests')) {
75+
function run_bcmath_tests(array $firstTerms, array $secondTerms, string $symbol, callable $bcmath_function): void
76+
{
77+
foreach ([0, 10] as $scale) {
78+
echo "Scale: {$scale}\n";
79+
foreach ($firstTerms as $firstTerm) {
80+
foreach ($secondTerms as $secondTerm) {
81+
try {
82+
$result = $bcmath_function($firstTerm, $secondTerm, $scale);
83+
echo $firstTerm . ' ' . $symbol . ' ' . str_pad($secondTerm, STRING_PADDING, ' ', STR_PAD_LEFT) . ' = ' . $result . "\n";
84+
} catch (Exception $e) {
85+
echo $firstTerm . ' ' . $symbol . ' ' . str_pad($secondTerm, STRING_PADDING, ' ', STR_PAD_LEFT) . ' Exception: ' . $e->getMessage() . "\n";
86+
}
87+
}
88+
}
89+
echo "\n";
90+
}
91+
}
92+
}
93+
EOF
94+
95+
# Clean up any previously generated PHP files (but keep test_helper.php)
96+
echo "Cleaning up previously generated PHP files..."
97+
find . -name "*.php" -not -name "test_helper.php" -delete
98+
99+
# Convert phpt tests to standalone PHP scripts
100+
echo "Converting phpt tests to PHP scripts..."
101+
php -r "
102+
\$testDir = '.';
103+
\$files = glob(\$testDir . '/*.phpt');
104+
105+
foreach (\$files as \$file) {
106+
\$basename = basename(\$file);
107+
if (\$basename === 'run_bcmath_tests_function.inc' || strpos(\$basename, 'run_bcmath_tests') !== false) continue;
108+
109+
echo 'Processing ' . basename(\$file) . PHP_EOL;
110+
111+
\$content = file_get_contents(\$file);
112+
\$sections = [];
113+
\$currentSection = null;
114+
115+
foreach (explode(PHP_EOL, \$content) as \$line) {
116+
if (preg_match('/^--([A-Z]+)--$/', \$line, \$matches)) {
117+
\$currentSection = \$matches[1];
118+
\$sections[\$currentSection] = '';
119+
} elseif (\$currentSection) {
120+
\$sections[\$currentSection] .= \$line . PHP_EOL;
121+
}
122+
}
123+
124+
if (isset(\$sections['FILE'])) {
125+
\$phpCode = trim(\$sections['FILE']);
126+
\$testName = basename(\$file, '.phpt');
127+
\$outputFile = \$testDir . '/' . \$testName . '.php';
128+
129+
// Remove any require/include statements for run_bcmath_tests_function.inc
130+
\$phpCode = preg_replace('/^\s*require(?:_once)?\s*.*run_bcmath_tests_function\.inc.*$/m', '', \$phpCode);
131+
\$phpCode = preg_replace('/^\s*include(?:_once)?\s*.*run_bcmath_tests_function\.inc.*$/m', '', \$phpCode);
132+
133+
// Check if this test uses run_bcmath_tests function
134+
\$needsTestFunction = strpos(\$phpCode, 'run_bcmath_tests(') !== false;
135+
136+
if (\$needsTestFunction) {
137+
\$wrappedCode = '<?php' . PHP_EOL .
138+
'require_once __DIR__ . \'/test_helper.php\';' . PHP_EOL . PHP_EOL .
139+
trim(str_replace('<?php', '', \$phpCode));
140+
} else {
141+
\$wrappedCode = '<?php' . PHP_EOL .
142+
'require_once __DIR__ . \'/../../vendor/autoload.php\';' . PHP_EOL .
143+
'require_once __DIR__ . \'/../../lib/bcmath.php\';' . PHP_EOL . PHP_EOL .
144+
trim(str_replace('<?php', '', \$phpCode));
145+
}
146+
147+
file_put_contents(\$outputFile, \$wrappedCode);
148+
echo 'Created: ' . \$outputFile . PHP_EOL;
149+
}
150+
}
151+
"
152+
153+
echo
154+
echo "Running php-src BCMath compatibility tests..."
155+
echo "=============================================="
156+
157+
# Convert comma-separated skip list to array
158+
IFS=',' read -ra SKIP_ARRAY <<< "$SKIP_TESTS"
159+
160+
# Function to check if a test should be skipped
161+
should_skip_test() {
162+
local test_name="$1"
163+
local base_name="${test_name%.php}"
164+
165+
for skip_pattern in "${SKIP_ARRAY[@]}"; do
166+
skip_pattern=$(echo "$skip_pattern" | xargs) # trim whitespace
167+
if [[ "$base_name" == *"$skip_pattern"* ]]; then
168+
return 0 # should skip
169+
fi
170+
done
171+
return 1 # should not skip
172+
}
173+
174+
failed_tests=0
175+
total_tests=0
176+
passed_tests=0
177+
skipped_tests=0
178+
179+
for test_file in *.php; do
180+
if [ "$test_file" = "test_helper.php" ]; then
181+
continue
182+
fi
183+
# Skip files that contain run_bcmath_tests in the name
184+
if [[ "$test_file" == *"run_bcmath_tests"* ]]; then
185+
continue
186+
fi
187+
188+
# Check if this test should be skipped
189+
if should_skip_test "$test_file"; then
190+
echo -e "${YELLOW}⏭️ Skipping: $test_file (not implemented)${NC}"
191+
skipped_tests=$((skipped_tests + 1))
192+
echo "----------------------------------------"
193+
continue
194+
fi
195+
196+
echo -e "${YELLOW}Running: $test_file${NC}"
197+
total_tests=$((total_tests + 1))
198+
199+
if timeout 30s php "$test_file" > /dev/null 2>&1; then
200+
echo -e "${GREEN}✅ Test $test_file PASSED${NC}"
201+
passed_tests=$((passed_tests + 1))
202+
else
203+
echo -e "${RED}❌ Test $test_file FAILED${NC}"
204+
echo " Error output:"
205+
timeout 30s php "$test_file" 2>&1 | head -5 | sed 's/^/ /'
206+
failed_tests=$((failed_tests + 1))
207+
fi
208+
echo "----------------------------------------"
209+
done
210+
211+
echo
212+
echo "=============================================="
213+
echo -e "Test Results: ${GREEN}$passed_tests${NC}/${total_tests} passed"
214+
215+
if [ $skipped_tests -gt 0 ]; then
216+
echo -e "${YELLOW}⏭️ $skipped_tests test(s) skipped (not implemented)${NC}"
217+
fi
218+
219+
if [ $failed_tests -gt 0 ]; then
220+
echo -e "${RED}$failed_tests test(s) failed${NC}"
221+
echo
222+
echo "To see detailed error output for a specific test:"
223+
echo " cd tests/php-src && php <test_name>.php"
224+
exit 1
225+
else
226+
echo -e "${GREEN}✅ All executed tests passed${NC}"
227+
fi
228+
229+
echo
230+
echo "Test files are available in tests/php-src/ for individual inspection."
231+
232+
if [ -n "$SKIP_TESTS" ]; then
233+
echo
234+
echo "Skipped tests: $SKIP_TESTS"
235+
fi

tests/BCMathTest.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,6 @@ public static function providePowCases(): iterable
157157
}
158158

159159
/**
160-
* @dataProvider providePowCases
161-
* requires PHP 7.3
162-
*
163160
* @param numeric-string $base
164161
* @param numeric-string $exponent
165162
*/

0 commit comments

Comments
 (0)