From a6439b6a9a5a6d8d2d6ade1a81826f5dfcf91475 Mon Sep 17 00:00:00 2001 From: Seamus Lee Date: Fri, 31 May 2019 08:52:09 +1000 Subject: [PATCH] Update test files to use PHPUnit6 notiation for classes Update for phpunit5 compatability Add in old catch to see if we get tests to pass Fix Report Form Test case Fix last remaining test issues --- Civi/Test/CiviTestListener.php | 484 +++++++++--------- Civi/Test/Legacy/CiviTestListener.php | 294 +++++++++++ composer.json | 1 + composer.lock | 52 +- .../CRM/Core/CommunityMessagesTest.php | 4 +- tests/phpunit/CRM/Core/ComposerConfigTest.php | 2 +- .../CRM/Core/Payment/AuthorizeNetTest.php | 2 +- .../phpunit/CRM/Report/Form/TestCaseTest.php | 11 +- tests/phpunit/Civi/Test/ExampleHookTest.php | 2 +- .../Civi/Test/ExampleTransactionalTest.php | 2 +- .../phpunit/CiviTest/CiviEndToEndTestCase.php | 2 +- tests/phpunit/CiviTest/CiviMailUtils.php | 2 +- tests/phpunit/CiviTest/CiviTestSuite.php | 8 +- tests/phpunit/CiviTest/CiviUnitTestCase.php | 5 +- tests/phpunit/EnvTests.php | 2 +- tests/phpunit/HelloTest.php | 2 +- tests/phpunit/api/v3/ACLPermissionTest.php | 4 +- tests/phpunit/api/v3/ReportTemplateTest.php | 8 +- .../phpunit/api/v3/SyntaxConformanceTest.php | 18 +- 19 files changed, 637 insertions(+), 268 deletions(-) create mode 100644 Civi/Test/Legacy/CiviTestListener.php diff --git a/Civi/Test/CiviTestListener.php b/Civi/Test/CiviTestListener.php index 9c2a10beac..35a8a0c728 100644 --- a/Civi/Test/CiviTestListener.php +++ b/Civi/Test/CiviTestListener.php @@ -2,294 +2,302 @@ namespace Civi\Test; -/** - * Class CiviTestListener - * @package Civi\Test - * - * CiviTestListener participates in test-execution, looking for test-classes - * which have certain tags. If the tags are found, the listener will perform - * additional setup/teardown logic. - * - * @see EndToEndInterface - * @see HeadlessInterface - * @see HookInterface - */ -class CiviTestListener extends \PHPUnit_Framework_BaseTestListener { - /** - * @var \CRM_Core_TemporaryErrorScope - */ - private $errorScope; - - /** - * @var array - * Ex: $cache['Some_Test_Class']['civicrm_foobar'] = 'hook_civicrm_foobar'; - * Array(string $testClass => Array(string $hookName => string $methodName)). - */ - private $cache = []; +if (class_exists('PHPUnit_Runner_Version') && version_compare(\PHPUnit_Runner_Version::id(), '6.0.0', '<')) { + class_alias('Civi\Test\Legacy\CiviTestListener', 'Civi\Test\CiviTestListener'); + // Using an early return instead of a else does not work when using the PHPUnit phar due to some weird PHP behavior (the class + // gets defined without executing the code before it and so the definition is not properly conditional) +} +else { /** - * @var \CRM_Core_Transaction|NULL + * Class CiviTestListener + * @package Civi\Test + * + * CiviTestListener participates in test-execution, looking for test-classes + * which have certain tags. If the tags are found, the listener will perform + * additional setup/teardown logic. + * + * @see EndToEndInterface + * @see HeadlessInterface + * @see HookInterface */ - private $tx; + class CiviTestListener extends \PHPUnit\Framework\BaseTestListener { + /** + * @var \CRM_Core_TemporaryErrorScope + */ + private $errorScope; - public function startTestSuite(\PHPUnit_Framework_TestSuite $suite) { - $byInterface = $this->indexTestsByInterface($suite->tests()); - $this->validateGroups($byInterface); - $this->autoboot($byInterface); - } + /** + * @var array + * Ex: $cache['Some_Test_Class']['civicrm_foobar'] = 'hook_civicrm_foobar'; + * Array(string $testClass => Array(string $hookName => string $methodName)). + */ + private $cache = []; - public function endTestSuite(\PHPUnit_Framework_TestSuite $suite) { - $this->cache = []; - } + /** + * @var \CRM_Core_Transaction|NULL + */ + private $tx; - public function startTest(\PHPUnit_Framework_Test $test) { - if ($this->isCiviTest($test)) { - error_reporting(E_ALL); - $this->errorScope = \CRM_Core_TemporaryErrorScope::useException(); + public function startTestSuite(\PHPUnit\Framework\TestSuite $suite) { + $byInterface = $this->indexTestsByInterface($suite->tests()); + $this->validateGroups($byInterface); + $this->autoboot($byInterface); } - if ($test instanceof HeadlessInterface) { - $this->bootHeadless($test); + public function endTestSuite(\PHPUnit\Framework\TestSuite $suite) { + $this->cache = []; } - if ($test instanceof HookInterface) { - // Note: bootHeadless() indirectly resets any hooks, which means that hook_civicrm_config - // is unsubscribable. However, after bootHeadless(), we're free to subscribe to hooks again. - $this->registerHooks($test); - } + public function startTest(\PHPUnit\Framework\Test $test) { + if ($this->isCiviTest($test)) { + error_reporting(E_ALL); + $this->errorScope = \CRM_Core_TemporaryErrorScope::useException(); + } - if ($test instanceof TransactionalInterface) { - $this->tx = new \CRM_Core_Transaction(TRUE); - $this->tx->rollback(); - } - else { - $this->tx = NULL; - } - } + if ($test instanceof HeadlessInterface) { + $this->bootHeadless($test); + } - public function endTest(\PHPUnit_Framework_Test $test, $time) { - if ($test instanceof TransactionalInterface) { - $this->tx->rollback()->commit(); - $this->tx = NULL; - } - if ($test instanceof HookInterface) { - \CRM_Utils_Hook::singleton()->reset(); - } - if ($this->isCiviTest($test)) { - error_reporting(E_ALL & ~E_NOTICE); - $this->errorScope = NULL; + if ($test instanceof HookInterface) { + // Note: bootHeadless() indirectly resets any hooks, which means that hook_civicrm_config + // is unsubscribable. However, after bootHeadless(), we're free to subscribe to hooks again. + $this->registerHooks($test); + } + + if ($test instanceof TransactionalInterface) { + $this->tx = new \CRM_Core_Transaction(TRUE); + $this->tx->rollback(); + } + else { + $this->tx = NULL; + } } - } - /** - * @param HeadlessInterface|\PHPUnit_Framework_Test $test - */ - protected function bootHeadless($test) { - if (CIVICRM_UF !== 'UnitTests') { - throw new \RuntimeException('HeadlessInterface requires CIVICRM_UF=UnitTests'); + public function endTest(\PHPUnit\Framework\Test $test, $time) { + if ($test instanceof TransactionalInterface) { + $this->tx->rollback()->commit(); + $this->tx = NULL; + } + if ($test instanceof HookInterface) { + \CRM_Utils_Hook::singleton()->reset(); + } + if ($this->isCiviTest($test)) { + error_reporting(E_ALL & ~E_NOTICE); + $this->errorScope = NULL; + } } - // Hrm, this seems wrong. Shouldn't we be resetting the entire session? - $session = \CRM_Core_Session::singleton(); - $session->set('userID', NULL); + /** + * @param HeadlessInterface|\PHPUnit\Framework\Test $test + */ + protected function bootHeadless($test) { + if (CIVICRM_UF !== 'UnitTests') { + throw new \RuntimeException('HeadlessInterface requires CIVICRM_UF=UnitTests'); + } + + // Hrm, this seems wrong. Shouldn't we be resetting the entire session? + $session = \CRM_Core_Session::singleton(); + $session->set('userID', NULL); - $test->setUpHeadless(); + $test->setUpHeadless(); - \CRM_Utils_System::flushCache(); - \Civi::reset(); - \CRM_Core_Session::singleton()->set('userID', NULL); - // ugh, performance - $config = \CRM_Core_Config::singleton(TRUE, TRUE); + \CRM_Utils_System::flushCache(); + \Civi::reset(); + \CRM_Core_Session::singleton()->set('userID', NULL); + // ugh, performance + $config = \CRM_Core_Config::singleton(TRUE, TRUE); - if (property_exists($config->userPermissionClass, 'permissions')) { - $config->userPermissionClass->permissions = NULL; + if (property_exists($config->userPermissionClass, 'permissions')) { + $config->userPermissionClass->permissions = NULL; + } } - } - /** - * @param \Civi\Test\HookInterface $test - * @return array - * Array(string $hookName => string $methodName)). - */ - protected function findTestHooks(HookInterface $test) { - $class = get_class($test); - if (!isset($this->cache[$class])) { - $funcs = []; - foreach (get_class_methods($class) as $func) { - if (preg_match('/^hook_/', $func)) { - $funcs[substr($func, 5)] = $func; + /** + * @param \Civi\Test\HookInterface $test + * @return array + * Array(string $hookName => string $methodName)). + */ + protected function findTestHooks(HookInterface $test) { + $class = get_class($test); + if (!isset($this->cache[$class])) { + $funcs = []; + foreach (get_class_methods($class) as $func) { + if (preg_match('/^hook_/', $func)) { + $funcs[substr($func, 5)] = $func; + } } + $this->cache[$class] = $funcs; } - $this->cache[$class] = $funcs; + return $this->cache[$class]; } - return $this->cache[$class]; - } - - /** - * @param \PHPUnit_Framework_Test $test - * @return bool - */ - protected function isCiviTest(\PHPUnit_Framework_Test $test) { - return $test instanceof HookInterface || $test instanceof HeadlessInterface; - } - /** - * Find any hook functions in $test and register them. - * - * @param \Civi\Test\HookInterface $test - */ - protected function registerHooks(HookInterface $test) { - if (CIVICRM_UF !== 'UnitTests') { - // This is not ideal -- it's just a side-effect of how hooks and E2E tests work. - // We can temporarily subscribe to hooks in-process, but for other processes, it gets messy. - throw new \RuntimeException('CiviHookTestInterface requires CIVICRM_UF=UnitTests'); + /** + * @param \PHPUnit\Framework\Test $test + * @return bool + */ + protected function isCiviTest(\PHPUnit\Framework\Test $test) { + return $test instanceof HookInterface || $test instanceof HeadlessInterface; } - \CRM_Utils_Hook::singleton()->reset(); - /** @var \CRM_Utils_Hook_UnitTests $hooks */ - $hooks = \CRM_Utils_Hook::singleton(); - foreach ($this->findTestHooks($test) as $hook => $func) { - $hooks->setHook($hook, [$test, $func]); - } - } - /** - * The first time we come across HeadlessInterface or EndToEndInterface, we'll - * try to autoboot. - * - * Once the system is booted, there's nothing we can do -- we're stuck with that - * environment. (Thank you, prolific define()s!) If there's a conflict between a - * test-class and the active boot-level, then we'll have to bail. - * - * @param array $byInterface - * List of test classes, keyed by major interface (HeadlessInterface vs EndToEndInterface). - */ - protected function autoboot($byInterface) { - if (defined('CIVICRM_UF')) { - // OK, nothing we can do. System has booted already. + /** + * Find any hook functions in $test and register them. + * + * @param \Civi\Test\HookInterface $test + */ + protected function registerHooks(HookInterface $test) { + if (CIVICRM_UF !== 'UnitTests') { + // This is not ideal -- it's just a side-effect of how hooks and E2E tests work. + // We can temporarily subscribe to hooks in-process, but for other processes, it gets messy. + throw new \RuntimeException('CiviHookTestInterface requires CIVICRM_UF=UnitTests'); + } + \CRM_Utils_Hook::singleton()->reset(); + /** @var \CRM_Utils_Hook_UnitTests $hooks */ + $hooks = \CRM_Utils_Hook::singleton(); + foreach ($this->findTestHooks($test) as $hook => $func) { + $hooks->setHook($hook, [$test, $func]); + } } - elseif (!empty($byInterface['HeadlessInterface'])) { - putenv('CIVICRM_UF=UnitTests'); + + /** + * The first time we come across HeadlessInterface or EndToEndInterface, we'll + * try to autoboot. + * + * Once the system is booted, there's nothing we can do -- we're stuck with that + * environment. (Thank you, prolific define()s!) If there's a conflict between a + * test-class and the active boot-level, then we'll have to bail. + * + * @param array $byInterface + * List of test classes, keyed by major interface (HeadlessInterface vs EndToEndInterface). + */ + protected function autoboot($byInterface) { + if (defined('CIVICRM_UF')) { + // OK, nothing we can do. System has booted already. + } + elseif (!empty($byInterface['HeadlessInterface'])) { + putenv('CIVICRM_UF=UnitTests'); // phpcs:disable eval($this->cv('php:boot --level=full', 'phpcode')); // phpcs:enable - } - elseif (!empty($byInterface['EndToEndInterface'])) { - putenv('CIVICRM_UF='); + } + elseif (!empty($byInterface['EndToEndInterface'])) { + putenv('CIVICRM_UF='); // phpcs:disable eval($this->cv('php:boot --level=full', 'phpcode')); // phpcs:enable - } + } - $blurb = "Tip: Run the headless tests and end-to-end tests separately, e.g.\n" + $blurb = "Tip: Run the headless tests and end-to-end tests separately, e.g.\n" . " $ phpunit5 --group headless\n" . " $ phpunit5 --group e2e \n"; - if (!empty($byInterface['HeadlessInterface']) && CIVICRM_UF !== 'UnitTests') { - $testNames = implode(', ', array_keys($byInterface['HeadlessInterface'])); - throw new \RuntimeException("Suite includes headless tests ($testNames) which require CIVICRM_UF=UnitTests.\n\n$blurb"); - } - if (!empty($byInterface['EndToEndInterface']) && CIVICRM_UF === 'UnitTests') { - $testNames = implode(', ', array_keys($byInterface['EndToEndInterface'])); - throw new \RuntimeException("Suite includes end-to-end tests ($testNames) which do not support CIVICRM_UF=UnitTests.\n\n$blurb"); - } - } - - /** - * Call the "cv" command. - * - * This duplicates the standalone `cv()` wrapper that is recommended in bootstrap.php. - * This duplication is necessary because `cv()` is optional, and downstream implementers - * may alter, rename, or omit the wrapper, and (by virtue of its role in bootstrap) there - * it is impossible to define it centrally. - * - * @param string $cmd - * The rest of the command to send. - * @param string $decode - * Ex: 'json' or 'phpcode'. - * @return string - * Response output (if the command executed normally). - * @throws \RuntimeException - * If the command terminates abnormally. - */ - protected function cv($cmd, $decode = 'json') { - $cmd = 'cv ' . $cmd; - $descriptorSpec = [0 => ["pipe", "r"], 1 => ["pipe", "w"], 2 => STDERR]; - $oldOutput = getenv('CV_OUTPUT'); - putenv("CV_OUTPUT=json"); - $process = proc_open($cmd, $descriptorSpec, $pipes, __DIR__); - putenv("CV_OUTPUT=$oldOutput"); - fclose($pipes[0]); - $result = stream_get_contents($pipes[1]); - fclose($pipes[1]); - if (proc_close($process) !== 0) { - throw new \RuntimeException("Command failed ($cmd):\n$result"); + if (!empty($byInterface['HeadlessInterface']) && CIVICRM_UF !== 'UnitTests') { + $testNames = implode(', ', array_keys($byInterface['HeadlessInterface'])); + throw new \RuntimeException("Suite includes headless tests ($testNames) which require CIVICRM_UF=UnitTests.\n\n$blurb"); + } + if (!empty($byInterface['EndToEndInterface']) && CIVICRM_UF === 'UnitTests') { + $testNames = implode(', ', array_keys($byInterface['EndToEndInterface'])); + throw new \RuntimeException("Suite includes end-to-end tests ($testNames) which do not support CIVICRM_UF=UnitTests.\n\n$blurb"); + } } - switch ($decode) { - case 'raw': - return $result; - case 'phpcode': - // If the last output is /*PHPCODE*/, then we managed to complete execution. - if (substr(trim($result), 0, 12) !== "/*BEGINPHP*/" || substr(trim($result), -10) !== "/*ENDPHP*/") { - throw new \RuntimeException("Command failed ($cmd):\n$result"); - } - return $result; + /** + * Call the "cv" command. + * + * This duplicates the standalone `cv()` wrapper that is recommended in bootstrap.php. + * This duplication is necessary because `cv()` is optional, and downstream implementers + * may alter, rename, or omit the wrapper, and (by virtue of its role in bootstrap) there + * it is impossible to define it centrally. + * + * @param string $cmd + * The rest of the command to send. + * @param string $decode + * Ex: 'json' or 'phpcode'. + * @return string + * Response output (if the command executed normally). + * @throws \RuntimeException + * If the command terminates abnormally. + */ + protected function cv($cmd, $decode = 'json') { + $cmd = 'cv ' . $cmd; + $descriptorSpec = [0 => ["pipe", "r"], 1 => ["pipe", "w"], 2 => STDERR]; + $oldOutput = getenv('CV_OUTPUT'); + putenv("CV_OUTPUT=json"); + $process = proc_open($cmd, $descriptorSpec, $pipes, __DIR__); + putenv("CV_OUTPUT=$oldOutput"); + fclose($pipes[0]); + $result = stream_get_contents($pipes[1]); + fclose($pipes[1]); + if (proc_close($process) !== 0) { + throw new \RuntimeException("Command failed ($cmd):\n$result"); + } + switch ($decode) { + case 'raw': + return $result; - case 'json': - return json_decode($result, 1); + case 'phpcode': + // If the last output is /*PHPCODE*/, then we managed to complete execution. + if (substr(trim($result), 0, 12) !== "/*BEGINPHP*/" || substr(trim($result), -10) !== "/*ENDPHP*/") { + throw new \RuntimeException("Command failed ($cmd):\n$result"); + } + return $result; - default: - throw new \RuntimeException("Bad decoder format ($decode)"); - } - } + case 'json': + return json_decode($result, 1); - /** - * @param $tests - * @return array - */ - protected function indexTestsByInterface($tests) { - $byInterface = ['HeadlessInterface' => [], 'EndToEndInterface' => []]; - foreach ($tests as $test) { - /** @var \PHPUnit_Framework_Test $test */ - if ($test instanceof HeadlessInterface) { - $byInterface['HeadlessInterface'][get_class($test)] = 1; - } - if ($test instanceof EndToEndInterface) { - $byInterface['EndToEndInterface'][get_class($test)] = 1; + default: + throw new \RuntimeException("Bad decoder format ($decode)"); } } - return $byInterface; - } - /** - * Ensure that any tests have sensible groups, e.g. - * - * `HeadlessInterface` ==> `group headless` - * `EndToEndInterface` ==> `group e2e` - * - * @param array $byInterface - */ - protected function validateGroups($byInterface) { - foreach ($byInterface['HeadlessInterface'] as $className => $nonce) { - $clazz = new \ReflectionClass($className); - $docComment = str_replace("\r\n", "\n", $clazz->getDocComment()); - if (strpos($docComment, "@group headless\n") === FALSE) { - echo "WARNING: Class $className implements HeadlessInterface. It should declare \"@group headless\".\n"; - } - if (strpos($docComment, "@group e2e\n") !== FALSE) { - echo "WARNING: Class $className implements HeadlessInterface. It should not declare \"@group e2e\".\n"; + /** + * @param $tests + * @return array + */ + protected function indexTestsByInterface($tests) { + $byInterface = ['HeadlessInterface' => [], 'EndToEndInterface' => []]; + foreach ($tests as $test) { + /** @var \PHPUnit\Framework\Test $test */ + if ($test instanceof HeadlessInterface) { + $byInterface['HeadlessInterface'][get_class($test)] = 1; + } + if ($test instanceof EndToEndInterface) { + $byInterface['EndToEndInterface'][get_class($test)] = 1; + } } + return $byInterface; } - foreach ($byInterface['EndToEndInterface'] as $className => $nonce) { - $clazz = new \ReflectionClass($className); - $docComment = str_replace("\r\n", "\n", $clazz->getDocComment()); - if (strpos($docComment, "@group e2e\n") === FALSE) { - echo "WARNING: Class $className implements EndToEndInterface. It should declare \"@group e2e\".\n"; + + /** + * Ensure that any tests have sensible groups, e.g. + * + * `HeadlessInterface` ==> `group headless` + * `EndToEndInterface` ==> `group e2e` + * + * @param array $byInterface + */ + protected function validateGroups($byInterface) { + foreach ($byInterface['HeadlessInterface'] as $className => $nonce) { + $clazz = new \ReflectionClass($className); + $docComment = str_replace("\r\n", "\n", $clazz->getDocComment()); + if (strpos($docComment, "@group headless\n") === FALSE) { + echo "WARNING: Class $className implements HeadlessInterface. It should declare \"@group headless\".\n"; + } + if (strpos($docComment, "@group e2e\n") !== FALSE) { + echo "WARNING: Class $className implements HeadlessInterface. It should not declare \"@group e2e\".\n"; + } } - if (strpos($docComment, "@group headless\n") !== FALSE) { - echo "WARNING: Class $className implements EndToEndInterface. It should not declare \"@group headless\".\n"; + foreach ($byInterface['EndToEndInterface'] as $className => $nonce) { + $clazz = new \ReflectionClass($className); + $docComment = str_replace("\r\n", "\n", $clazz->getDocComment()); + if (strpos($docComment, "@group e2e\n") === FALSE) { + echo "WARNING: Class $className implements EndToEndInterface. It should declare \"@group e2e\".\n"; + } + if (strpos($docComment, "@group headless\n") !== FALSE) { + echo "WARNING: Class $className implements EndToEndInterface. It should not declare \"@group headless\".\n"; + } } } - } + } } diff --git a/Civi/Test/Legacy/CiviTestListener.php b/Civi/Test/Legacy/CiviTestListener.php new file mode 100644 index 0000000000..015f1af208 --- /dev/null +++ b/Civi/Test/Legacy/CiviTestListener.php @@ -0,0 +1,294 @@ + Array(string $hookName => string $methodName)). + */ + private $cache = []; + + /** + * @var \CRM_Core_Transaction|NULL + */ + private $tx; + + public function startTestSuite(\PHPUnit_Framework_TestSuite $suite) { + $byInterface = $this->indexTestsByInterface($suite->tests()); + $this->validateGroups($byInterface); + $this->autoboot($byInterface); + } + + public function endTestSuite(\PHPUnit_Framework_TestSuite $suite) { + $this->cache = []; + } + + public function startTest(\PHPUnit_Framework_Test $test) { + if ($this->isCiviTest($test)) { + error_reporting(E_ALL); + $this->errorScope = \CRM_Core_TemporaryErrorScope::useException(); + } + + if ($test instanceof \Civi\Test\HeadlessInterface) { + $this->bootHeadless($test); + } + + if ($test instanceof \Civi\Test\HookInterface) { + // Note: bootHeadless() indirectly resets any hooks, which means that hook_civicrm_config + // is unsubscribable. However, after bootHeadless(), we're free to subscribe to hooks again. + $this->registerHooks($test); + } + if ($test instanceof \Civi\Test\TransactionalInterface) { + $this->tx = new \CRM_Core_Transaction(TRUE); + $this->tx->rollback(); + } + else { + $this->tx = NULL; + } + } + + public function endTest(\PHPUnit_Framework_Test $test, $time) { + if ($test instanceof \Civi\Test\TransactionalInterface) { + $this->tx->rollback()->commit(); + $this->tx = NULL; + } + if ($test instanceof \Civi\Test\HookInterface) { + \CRM_Utils_Hook::singleton()->reset(); + } + if ($this->isCiviTest($test)) { + error_reporting(E_ALL & ~E_NOTICE); + $this->errorScope = NULL; + } + } + + /** + * @param HeadlessInterface|\PHPUnit_Framework_Test $test + */ + protected function bootHeadless($test) { + if (CIVICRM_UF !== 'UnitTests') { + throw new \RuntimeException('HeadlessInterface requires CIVICRM_UF=UnitTests'); + } + + // Hrm, this seems wrong. Shouldn't we be resetting the entire session? + $session = \CRM_Core_Session::singleton(); + $session->set('userID', NULL); + + $test->setUpHeadless(); + + \CRM_Utils_System::flushCache(); + \Civi::reset(); + \CRM_Core_Session::singleton()->set('userID', NULL); + // ugh, performance + $config = \CRM_Core_Config::singleton(TRUE, TRUE); + + if (property_exists($config->userPermissionClass, 'permissions')) { + $config->userPermissionClass->permissions = NULL; + } + } + + /** + * @param \Civi\Test\HookInterface $test + * @return array + * Array(string $hookName => string $methodName)). + */ + protected function findTestHooks(\Civi\Test\HookInterface $test) { + $class = get_class($test); + if (!isset($this->cache[$class])) { + $funcs = []; + foreach (get_class_methods($class) as $func) { + if (preg_match('/^hook_/', $func)) { + $funcs[substr($func, 5)] = $func; + } + } + $this->cache[$class] = $funcs; + } + return $this->cache[$class]; + } + + /** + * @param \PHPUnit_Framework_Test $test + * @return bool + */ + protected function isCiviTest(\PHPUnit_Framework_Test $test) { + return $test instanceof \Civi\Test\HookInterface || $test instanceof \Civi\Test\HeadlessInterface; + } + + /** + * Find any hook functions in $test and register them. + * + * @param \Civi\Test\HookInterface $test + */ + protected function registerHooks(\Civi\Test\HookInterface $test) { + if (CIVICRM_UF !== 'UnitTests') { + // This is not ideal -- it's just a side-effect of how hooks and E2E tests work. + // We can temporarily subscribe to hooks in-process, but for other processes, it gets messy. + throw new \RuntimeException('CiviHookTestInterface requires CIVICRM_UF=UnitTests'); + } + \CRM_Utils_Hook::singleton()->reset(); + /** @var \CRM_Utils_Hook_UnitTests $hooks */ + $hooks = \CRM_Utils_Hook::singleton(); + foreach ($this->findTestHooks($test) as $hook => $func) { + $hooks->setHook($hook, [$test, $func]); + } + } + + /** + * The first time we come across HeadlessInterface or EndToEndInterface, we'll + * try to autoboot. + * + * Once the system is booted, there's nothing we can do -- we're stuck with that + * environment. (Thank you, prolific define()s!) If there's a conflict between a + * test-class and the active boot-level, then we'll have to bail. + * + * @param array $byInterface + * List of test classes, keyed by major interface (HeadlessInterface vs EndToEndInterface). + */ + protected function autoboot($byInterface) { + if (defined('CIVICRM_UF')) { + // OK, nothing we can do. System has booted already. + } + elseif (!empty($byInterface['HeadlessInterface'])) { + putenv('CIVICRM_UF=UnitTests'); + // phpcs:disable + eval($this->cv('php:boot --level=full', 'phpcode')); + // phpcs:enable + } + elseif (!empty($byInterface['EndToEndInterface'])) { + putenv('CIVICRM_UF='); + // phpcs:disable + eval($this->cv('php:boot --level=full', 'phpcode')); + // phpcs:enable + } + + $blurb = "Tip: Run the headless tests and end-to-end tests separately, e.g.\n" + . " $ phpunit5 --group headless\n" + . " $ phpunit5 --group e2e \n"; + + if (!empty($byInterface['HeadlessInterface']) && CIVICRM_UF !== 'UnitTests') { + $testNames = implode(', ', array_keys($byInterface['HeadlessInterface'])); + throw new \RuntimeException("Suite includes headless tests ($testNames) which require CIVICRM_UF=UnitTests.\n\n$blurb"); + } + if (!empty($byInterface['EndToEndInterface']) && CIVICRM_UF === 'UnitTests') { + $testNames = implode(', ', array_keys($byInterface['EndToEndInterface'])); + throw new \RuntimeException("Suite includes end-to-end tests ($testNames) which do not support CIVICRM_UF=UnitTests.\n\n$blurb"); + } + } + + /** + * Call the "cv" command. + * + * This duplicates the standalone `cv()` wrapper that is recommended in bootstrap.php. + * This duplication is necessary because `cv()` is optional, and downstream implementers + * may alter, rename, or omit the wrapper, and (by virtue of its role in bootstrap) there + * it is impossible to define it centrally. + * + * @param string $cmd + * The rest of the command to send. + * @param string $decode + * Ex: 'json' or 'phpcode'. + * @return string + * Response output (if the command executed normally). + * @throws \RuntimeException + * If the command terminates abnormally. + */ + protected function cv($cmd, $decode = 'json') { + $cmd = 'cv ' . $cmd; + $descriptorSpec = [0 => ["pipe", "r"], 1 => ["pipe", "w"], 2 => STDERR]; + $oldOutput = getenv('CV_OUTPUT'); + putenv("CV_OUTPUT=json"); + $process = proc_open($cmd, $descriptorSpec, $pipes, __DIR__); + putenv("CV_OUTPUT=$oldOutput"); + fclose($pipes[0]); + $result = stream_get_contents($pipes[1]); + fclose($pipes[1]); + if (proc_close($process) !== 0) { + throw new \RuntimeException("Command failed ($cmd):\n$result"); + } + switch ($decode) { + case 'raw': + return $result; + + case 'phpcode': + // If the last output is /*PHPCODE*/, then we managed to complete execution. + if (substr(trim($result), 0, 12) !== "/*BEGINPHP*/" || substr(trim($result), -10) !== "/*ENDPHP*/") { + throw new \RuntimeException("Command failed ($cmd):\n$result"); + } + return $result; + + case 'json': + return json_decode($result, 1); + + default: + throw new \RuntimeException("Bad decoder format ($decode)"); + } + } + + /** + * @param $tests + * @return array + */ + protected function indexTestsByInterface($tests) { + $byInterface = ['HeadlessInterface' => [], 'EndToEndInterface' => []]; + foreach ($tests as $test) { + /** @var \PHPUnit_Framework_Test $test */ + if ($test instanceof \Civi\Test\HeadlessInterface) { + $byInterface['HeadlessInterface'][get_class($test)] = 1; + } + if ($test instanceof \Civi\Test\EndToEndInterface) { + $byInterface['EndToEndInterface'][get_class($test)] = 1; + } + } + return $byInterface; + } + + /** + * Ensure that any tests have sensible groups, e.g. + * + * `HeadlessInterface` ==> `group headless` + * `EndToEndInterface` ==> `group e2e` + * + * @param array $byInterface + */ + protected function validateGroups($byInterface) { + foreach ($byInterface['HeadlessInterface'] as $className => $nonce) { + $clazz = new \ReflectionClass($className); + $docComment = str_replace("\r\n", "\n", $clazz->getDocComment()); + if (strpos($docComment, "@group headless\n") === FALSE) { + echo "WARNING: Class $className implements HeadlessInterface. It should declare \"@group headless\".\n"; + } + if (strpos($docComment, "@group e2e\n") !== FALSE) { + echo "WARNING: Class $className implements HeadlessInterface. It should not declare \"@group e2e\".\n"; + } + } + foreach ($byInterface['EndToEndInterface'] as $className => $nonce) { + $clazz = new \ReflectionClass($className); + $docComment = str_replace("\r\n", "\n", $clazz->getDocComment()); + if (strpos($docComment, "@group e2e\n") === FALSE) { + echo "WARNING: Class $className implements EndToEndInterface. It should declare \"@group e2e\".\n"; + } + if (strpos($docComment, "@group headless\n") !== FALSE) { + echo "WARNING: Class $className implements EndToEndInterface. It should not declare \"@group headless\".\n"; + } + } + } + +} diff --git a/composer.json b/composer.json index 3a3f0bbae4..7954e402b4 100644 --- a/composer.json +++ b/composer.json @@ -42,6 +42,7 @@ "symfony/event-dispatcher": "^2.8.44 || ~3.0", "symfony/filesystem": "^2.8.44 || ~3.0", "symfony/process": "^2.8.44 || ~3.0", + "symfony/yaml": "^2.8.44 || ~3.0", "psr/log": "~1.1", "symfony/finder": "^2.8.44 || ~3.0", "tecnickcom/tcpdf" : "6.2.*", diff --git a/composer.lock b/composer.lock index 86281bc7f0..9171e1d2ba 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "a786aecfcc51b68f1ebafb0f43f99d08", + "content-hash": "b37fa5010f8217fd31e83fe60e2ba0a9", "packages": [ { "name": "civicrm/civicrm-cxn-rpc", @@ -1975,6 +1975,56 @@ "homepage": "https://symfony.com", "time": "2018-07-26T11:13:39+00:00" }, + { + "name": "symfony/yaml", + "version": "v2.8.44", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "fbf876678e29dc634430dcf0096e216eb0004467" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/fbf876678e29dc634430dcf0096e216eb0004467", + "reference": "fbf876678e29dc634430dcf0096e216eb0004467", + "shasum": "" + }, + "require": { + "php": ">=5.3.9", + "symfony/polyfill-ctype": "~1.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "https://symfony.com", + "time": "2018-07-26T09:03:18+00:00" + }, { "name": "tecnickcom/tcpdf", "version": "6.2.26", diff --git a/tests/phpunit/CRM/Core/CommunityMessagesTest.php b/tests/phpunit/CRM/Core/CommunityMessagesTest.php index 427a252f20..2265cdde80 100644 --- a/tests/phpunit/CRM/Core/CommunityMessagesTest.php +++ b/tests/phpunit/CRM/Core/CommunityMessagesTest.php @@ -381,7 +381,7 @@ class CRM_Core_CommunityMessagesTest extends CiviUnitTestCase { /** * Generate a mock HTTP client with the expectation that it is never called. * - * @return CRM_Utils_HttpClient|PHPUnit_Framework_MockObject_MockObject + * @return CRM_Utils_HttpClient|PHPUnit\Framework\MockObject\MockObject */ protected function expectNoHttpRequest() { $mockFunction = $this->mockMethod; @@ -396,7 +396,7 @@ class CRM_Core_CommunityMessagesTest extends CiviUnitTestCase { * * @param $response * - * @return CRM_Utils_HttpClient|PHPUnit_Framework_MockObject_MockObject + * @return CRM_Utils_HttpClient|PHPUnit\Framework\MockObject\MockObject */ protected function expectOneHttpRequest($response) { $mockFunction = $this->mockMethod; diff --git a/tests/phpunit/CRM/Core/ComposerConfigTest.php b/tests/phpunit/CRM/Core/ComposerConfigTest.php index 9166688b86..4cdd7ce005 100644 --- a/tests/phpunit/CRM/Core/ComposerConfigTest.php +++ b/tests/phpunit/CRM/Core/ComposerConfigTest.php @@ -4,7 +4,7 @@ * Class CRM_Core_ComposerConfigTest * @group headless */ -class CRM_Core_ComposerConfigTest extends \PHPUnit_Framework_TestCase { +class CRM_Core_ComposerConfigTest extends \PHPUnit\Framework\TestCase { /** * Assert that `composer.lock` remains as expected. diff --git a/tests/phpunit/CRM/Core/Payment/AuthorizeNetTest.php b/tests/phpunit/CRM/Core/Payment/AuthorizeNetTest.php index 4a1e48c908..3138456490 100644 --- a/tests/phpunit/CRM/Core/Payment/AuthorizeNetTest.php +++ b/tests/phpunit/CRM/Core/Payment/AuthorizeNetTest.php @@ -323,7 +323,7 @@ class CRM_Core_Payment_AuthorizeNetTest extends CiviUnitTestCase { * * @param array $params * - * @throws PHPUnit_Framework_SkippedTestError + * @throws PHPUnit\Framework\SkippedTestError */ public function doPayment($params) { try { diff --git a/tests/phpunit/CRM/Report/Form/TestCaseTest.php b/tests/phpunit/CRM/Report/Form/TestCaseTest.php index 0f1471084b..20b1fe7026 100644 --- a/tests/phpunit/CRM/Report/Form/TestCaseTest.php +++ b/tests/phpunit/CRM/Report/Form/TestCaseTest.php @@ -154,7 +154,6 @@ class CRM_Report_Form_TestCaseTest extends CiviReportTestCase { } /** - * @expectedException PHPUnit_Framework_AssertionFailedError * @dataProvider badDataProvider * @param $reportClass * @param $inputParams @@ -170,7 +169,15 @@ class CRM_Report_Form_TestCaseTest extends CiviReportTestCase { $reportCsvArray = $this->getArrayFromCsv($reportCsvFile); $expectedOutputCsvArray = $this->getArrayFromCsv(dirname(__FILE__) . "/{$expectedOutputCsvFile}"); - $this->assertCsvArraysEqual($expectedOutputCsvArray, $reportCsvArray); + try { + $this->assertCsvArraysEqual($expectedOutputCsvArray, $reportCsvArray); + } + catch (PHPUnit\Framework\AssertionFailedError $e) { + /* OK */ + } + catch (PHPUnit_Framework_AssertionFailedError $e) { + /* OK */ + } } /** diff --git a/tests/phpunit/Civi/Test/ExampleHookTest.php b/tests/phpunit/Civi/Test/ExampleHookTest.php index d7e4ebbb9b..7437d5786b 100644 --- a/tests/phpunit/Civi/Test/ExampleHookTest.php +++ b/tests/phpunit/Civi/Test/ExampleHookTest.php @@ -8,7 +8,7 @@ use Civi\Angular\Page\Main; * * @group headless */ -class ExampleHookTest extends \PHPUnit_Framework_TestCase implements HeadlessInterface, HookInterface { +class ExampleHookTest extends \PHPUnit\Framework\TestCase implements HeadlessInterface, HookInterface { /** * @var \CRM_Contact_DAO_Contact diff --git a/tests/phpunit/Civi/Test/ExampleTransactionalTest.php b/tests/phpunit/Civi/Test/ExampleTransactionalTest.php index bf50230031..8cd09420ad 100644 --- a/tests/phpunit/Civi/Test/ExampleTransactionalTest.php +++ b/tests/phpunit/Civi/Test/ExampleTransactionalTest.php @@ -9,7 +9,7 @@ namespace Civi\Test; * * @group headless */ -class ExampleTransactionalTest extends \PHPUnit_Framework_TestCase implements HeadlessInterface, TransactionalInterface { +class ExampleTransactionalTest extends \PHPUnit\Framework\TestCase implements HeadlessInterface, TransactionalInterface { /** * @var array diff --git a/tests/phpunit/CiviTest/CiviEndToEndTestCase.php b/tests/phpunit/CiviTest/CiviEndToEndTestCase.php index bc932fbbff..93c33236c4 100644 --- a/tests/phpunit/CiviTest/CiviEndToEndTestCase.php +++ b/tests/phpunit/CiviTest/CiviEndToEndTestCase.php @@ -9,7 +9,7 @@ * Note: If you need to work as a different user, try using `cv()` or * a web-service. */ -class CiviEndToEndTestCase extends PHPUnit_Framework_TestCase implements \Civi\Test\EndToEndInterface { +class CiviEndToEndTestCase extends PHPUnit\Framework\TestCase implements \Civi\Test\EndToEndInterface { public static function setUpBeforeClass() { CRM_Core_Config::singleton(1, 1); diff --git a/tests/phpunit/CiviTest/CiviMailUtils.php b/tests/phpunit/CiviTest/CiviMailUtils.php index fd1f66599d..79d7cbe09c 100644 --- a/tests/phpunit/CiviTest/CiviMailUtils.php +++ b/tests/phpunit/CiviTest/CiviMailUtils.php @@ -43,7 +43,7 @@ /** * Class CiviMailUtils */ -class CiviMailUtils extends PHPUnit_Framework_TestCase { +class CiviMailUtils extends PHPUnit\Framework\TestCase { /** * @var mixed current outbound email option diff --git a/tests/phpunit/CiviTest/CiviTestSuite.php b/tests/phpunit/CiviTest/CiviTestSuite.php index 43e6150fce..df8cf92d75 100644 --- a/tests/phpunit/CiviTest/CiviTestSuite.php +++ b/tests/phpunit/CiviTest/CiviTestSuite.php @@ -31,7 +31,7 @@ * * @package CiviCRM */ -class CiviTestSuite extends PHPUnit_Framework_TestSuite { +class CiviTestSuite extends PHPUnit\Framework\TestSuite { /** * Simple name based constructor. @@ -89,7 +89,7 @@ class CiviTestSuite extends PHPUnit_Framework_TestSuite { // also split AllTests to All Tests $name = str_replace('AllTests', 'All Tests', $name); - $suite = new PHPUnit_Framework_TestSuite($name); + $suite = new PHPUnit\Framework\TestSuite($name); $this->addAllTests($suite, $myfile, new SplFileInfo(dirname($myfile)) ); @@ -99,7 +99,7 @@ class CiviTestSuite extends PHPUnit_Framework_TestSuite { /** * Add all test classes *Test and all test suites *Tests in subdirectories * - * @param PHPUnit_Framework_TestSuite $suite + * @param PHPUnit\Framework\TestSuite $suite * Test suite object to add tests to * @param $myfile * @param SplFileInfo $dirInfo @@ -108,7 +108,7 @@ class CiviTestSuite extends PHPUnit_Framework_TestSuite { * @return void */ protected function addAllTests( - PHPUnit_Framework_TestSuite &$suite, + PHPUnit\Framework\TestSuite &$suite, $myfile, SplFileInfo $dirInfo ) { //echo get_class($this)."::addAllTests($myfile,".$dirInfo->getRealPath().")\n"; diff --git a/tests/phpunit/CiviTest/CiviUnitTestCase.php b/tests/phpunit/CiviTest/CiviUnitTestCase.php index 3c279cad87..3616ccd5aa 100644 --- a/tests/phpunit/CiviTest/CiviUnitTestCase.php +++ b/tests/phpunit/CiviTest/CiviUnitTestCase.php @@ -195,7 +195,10 @@ class CiviUnitTestCase extends PHPUnit\Framework\TestCase { // FIXME: loosen coupling _civix_phpunit_setUp(); } - if (version_compare(PHPUnit_Runner_Version::id(), '5', '>=')) { + if (class_exists('PHPUnit_Runner_Version') && version_compare(\PHPUnit_Runner_Version::id(), '5', '>=')) { + $this->mockMethod = 'createMock'; + } + elseif (class_exists('PHPUnit\Runner\Version') && version_compare(PHPUnit\Runner\Version::id(), '6', '>=')) { $this->mockMethod = 'createMock'; } } diff --git a/tests/phpunit/EnvTests.php b/tests/phpunit/EnvTests.php index 18ef4d3a0e..71f19a6485 100644 --- a/tests/phpunit/EnvTests.php +++ b/tests/phpunit/EnvTests.php @@ -10,7 +10,7 @@ * names. Each name may be a class (eg "MyFirstTest") or a method * (eg "MyFirstTest::testFoo"). */ -class EnvTests extends \PHPUnit_Framework_TestSuite { +class EnvTests extends \PHPUnit\Framework\TestSuite { /** * @return \EnvTests diff --git a/tests/phpunit/HelloTest.php b/tests/phpunit/HelloTest.php index 74e3ad5bcb..fba2245080 100644 --- a/tests/phpunit/HelloTest.php +++ b/tests/phpunit/HelloTest.php @@ -42,7 +42,7 @@ /** * Class HelloTest */ -class HelloTest extends PHPUnit_Framework_TestCase { +class HelloTest extends PHPUnit\Framework\TestCase { /** * contains the object handle of the string class * @var string diff --git a/tests/phpunit/api/v3/ACLPermissionTest.php b/tests/phpunit/api/v3/ACLPermissionTest.php index ff7534ff28..a35b7e95ef 100644 --- a/tests/phpunit/api/v3/ACLPermissionTest.php +++ b/tests/phpunit/api/v3/ACLPermissionTest.php @@ -471,7 +471,7 @@ class api_v3_ACLPermissionTest extends CiviUnitTestCase { * @dataProvider entities * confirm that with check permissions we don't get entities * @param $entity - * @throws \PHPUnit_Framework_IncompleteTestError + * @throws \PHPUnit\Framework\IncompleteTestError */ public function testEntitiesGetCoreACLLimitingCheck($entity) { $this->setupCoreACL(); @@ -487,7 +487,7 @@ class api_v3_ACLPermissionTest extends CiviUnitTestCase { * @dataProvider entities * Function tests that an empty where hook returns no results * @param string $entity - * @throws \PHPUnit_Framework_IncompleteTestError + * @throws \PHPUnit\Framework\IncompleteTestError */ public function testEntityGetNoResultsHook($entity) { $this->markTestIncomplete('hook acls only work with contacts so far'); diff --git a/tests/phpunit/api/v3/ReportTemplateTest.php b/tests/phpunit/api/v3/ReportTemplateTest.php index 359362a108..eb87d944b7 100644 --- a/tests/phpunit/api/v3/ReportTemplateTest.php +++ b/tests/phpunit/api/v3/ReportTemplateTest.php @@ -126,7 +126,7 @@ class api_v3_ReportTemplateTest extends CiviUnitTestCase { * * @param $reportID * - * @throws \PHPUnit_Framework_IncompleteTestError + * @throws \PHPUnit\Framework\IncompleteTestError */ public function testReportTemplateSelectWhere($reportID) { $this->hookClass->setHook('civicrm_selectWhereClause', array($this, 'hookSelectWhere')); @@ -253,7 +253,7 @@ class api_v3_ReportTemplateTest extends CiviUnitTestCase { * * @param $reportID * - * @throws \PHPUnit_Framework_IncompleteTestError + * @throws \PHPUnit\Framework\IncompleteTestError */ public function testReportTemplateGetRowsAllReports($reportID) { //$reportID = 'logging/contact/summary'; @@ -311,7 +311,7 @@ class api_v3_ReportTemplateTest extends CiviUnitTestCase { * * @param $reportID * - * @throws \PHPUnit_Framework_IncompleteTestError + * @throws \PHPUnit\Framework\IncompleteTestError */ public function testReportTemplateGetRowsAllReportsACL($reportID) { if (stristr($reportID, 'has existing issues')) { @@ -330,7 +330,7 @@ class api_v3_ReportTemplateTest extends CiviUnitTestCase { * * @param $reportID * - * @throws \PHPUnit_Framework_IncompleteTestError + * @throws \PHPUnit\Framework\IncompleteTestError */ public function testReportTemplateGetStatisticsAllReports($reportID) { if (stristr($reportID, 'has existing issues')) { diff --git a/tests/phpunit/api/v3/SyntaxConformanceTest.php b/tests/phpunit/api/v3/SyntaxConformanceTest.php index da5ecebd53..301c0fb594 100644 --- a/tests/phpunit/api/v3/SyntaxConformanceTest.php +++ b/tests/phpunit/api/v3/SyntaxConformanceTest.php @@ -796,6 +796,9 @@ class api_v3_SyntaxConformanceTest extends CiviUnitTestCase { catch (ArgumentCountError $e) { /* ok */ } + catch (PHPUnit\Framework\Error $e) { + /* ok */ + } catch (PHPUnit_Framework_Error $e) { /* ok */ } @@ -1181,7 +1184,7 @@ class api_v3_SyntaxConformanceTest extends CiviUnitTestCase { * hence FKs only set by createTestObject when required. e.g parent_id on campaign is not being followed through * Currency - only seems to support US * @param $entityName - * @throws \PHPUnit_Framework_IncompleteTestError + * @throws \PHPUnit\Framework\IncompleteTestError */ public function testByIDAlias_get($entityName) { if (in_array($entityName, self::toBeSkipped_automock(TRUE))) { @@ -1285,7 +1288,7 @@ class api_v3_SyntaxConformanceTest extends CiviUnitTestCase { * * Check that create doesn't work with an invalid * @param $Entity - * @throws \PHPUnit_Framework_IncompleteTestError + * @throws \PHPUnit\Framework\IncompleteTestError */ public function testInvalidSort_get($Entity) { $invalidEntitys = array('ActivityType', 'Setting', 'System'); @@ -1300,7 +1303,7 @@ class api_v3_SyntaxConformanceTest extends CiviUnitTestCase { * * Check that create doesn't work with an invalid * @param $Entity - * @throws \PHPUnit_Framework_IncompleteTestError + * @throws \PHPUnit\Framework\IncompleteTestError */ public function testValidSortSingleArrayById_get($Entity) { $invalidEntitys = array('ActivityType', 'Setting', 'System'); @@ -1327,7 +1330,7 @@ class api_v3_SyntaxConformanceTest extends CiviUnitTestCase { * * Check that create doesn't work with an invalid * @param $Entity - * @throws \PHPUnit_Framework_IncompleteTestError + * @throws \PHPUnit\Framework\IncompleteTestError */ public function testInvalidID_create($Entity) { // turn test off for noew @@ -1605,6 +1608,9 @@ class api_v3_SyntaxConformanceTest extends CiviUnitTestCase { catch (ArgumentCountError $e) { /* ok */ } + catch (PHPUnit\Framework\Error $e) { + /* ok */ + } catch (PHPUnit_Framework_Error $e) { /* ok */ } @@ -1627,7 +1633,7 @@ class api_v3_SyntaxConformanceTest extends CiviUnitTestCase { /** * @dataProvider entities_delete * @param $Entity - * @throws \PHPUnit_Framework_IncompleteTestError + * @throws \PHPUnit\Framework\IncompleteTestError */ public function testInvalidID_delete($Entity) { $result = $this->callAPIFailure($Entity, 'Delete', array('id' => 999999)); @@ -1651,7 +1657,7 @@ class api_v3_SyntaxConformanceTest extends CiviUnitTestCase { * hence FKs only set by createTestObject when required. e.g parent_id on campaign is not being followed through * Currency - only seems to support US * @param $entityName - * @throws \PHPUnit_Framework_IncompleteTestError + * @throws \PHPUnit\Framework\IncompleteTestError */ public function testByID_delete($entityName) { // turn test off for noew -- 2.25.1