#!/usr/bin/env php =')) { $phpunit = findCommand('phpunit6'); $argFilters[] = function ($argv) { $pos = array_search('--tap', $argv); if ($pos !== FALSE) { array_splice($argv, $pos, 1, ['--printer', '\Civi\Test\TAP']); } return $argv; }; } elseif (version_compare(PHP_VERSION, '5.6', '>=')) { $phpunit = findCommand('phpunit5'); } else { $phpunit = findCommand('phpunit4'); } if (!$phpunit) { $phpunit = findCommand('phpunit'); } if (!$phpunit) { echo "Plesae ensure that:\n"; echo " * PHPUnit is installed.\n"; echo " * The extensions for dbunit and selenium are installed.\n" ; echo " * The command \"phpunit\" is in the PATH.\n"; echo "See also: https://github.com/civicrm/civicrm-buildkit/\n"; exit(127); } chdir(dirname(dirname(__DIR__))); // civicrm-core root dir array_shift($argv); // Convert class names to file names $CIVICRM_UF = 'UnitTests'; foreach ($argv as $k => $v) { if (preg_match('/^(CRM_|api_v3_|api_v4_|EnvTest|WebTest_|E2E_)/', $v)) { $argv[$k] = 'tests/phpunit/' . strtr($v, '_', '/') . '.php'; } elseif (preg_match('/^Civi\\\\/', $v)) { $argv[$k] = 'tests/phpunit/' . strtr($v, '\\', '/') . '.php'; } if (preg_match('/^(WebTest|E2E)/', $v)) { $CIVICRM_UF=''; } } putenv("CIVICRM_UF=$CIVICRM_UF"); // Transition: Make sure we use phpunit code from PATH, not // civicrm-packages. This will be unnecessary once civicrm-packages is // updated. if (is_dir('packages/PHPUnit/')) { if (!rename('packages/PHPUnit', 'packages/PHPUnit.bak')) { echo "Failed to move aside stale copy of PHPUnit.\n"; exit(1); } } foreach ($argFilters as $filter) { $argv = $filter($argv); } $cmd = findPhp() // In case this system has multiple copies of PHP, use the active/preferred one. // . ' -ddisplay_errors=1' . ' ' . escapeshellarg($phpunit) . ' ' . implode(' ', array_map('escapeshellarg', $argv)); passthru($cmd); function findPhp() { // The autodetect behavior here is a potential point of contention. These two cases are hard to reconcile: // 1. `php` is actually a wrapper script which delegates to another PHP binary and // passes options (such as INI's and PECL extensions). Subprocesses should use the wrapper script. // Examples: bitnami, bknix // 2. There are multiple PHP binaries (eg `php55`, `php70`). Subprocesses should use // the final executable (regardless of its name). // Example: using MAMP and adding 'ln -s /Application/MAMP/.../php7.1.2/bin/php ~/bin/php71` // Since the test infra uses a wrapper script like (1), we use autodetect logic that works there. // If you're in situation (2), then set an env-var or just skip on using `tools/scripts/phpunit`. if (getenv('PHP')) { return getenv('PHP'); } else { return 'php'; } } function findCommand($name) { $paths = explode(PATH_SEPARATOR, getenv('PATH')); foreach ($paths as $path) { if (file_exists("$path/$name")) { return "$path/$name"; } } return NULL; }