This commit is contained in:
Sara Arjona
2025-01-20 16:47:56 +01:00
112 changed files with 1913 additions and 1759 deletions
+18 -31
View File
@@ -20,6 +20,8 @@ use core\http_client;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use PHPUnit\Framework\Attributes\After;
use PHPUnit\Framework\Attributes\Before;
/**
* Advanced PHPUnit test case customised for Moodle.
@@ -46,21 +48,16 @@ abstract class advanced_testcase extends base_testcase {
* Note: use setUp() or setUpBeforeClass() in your test cases.
*
* @param string $name
* @param array $data
* @param string $dataName
*/
final public function __construct($name = null, array $data = [], $dataname = '') {
parent::__construct($name, $data, $dataname);
final public function __construct(string $name) {
parent::__construct($name);
$this->setBackupGlobals(false);
$this->setBackupStaticAttributes(false);
$this->setPreserveGlobalState(false);
}
/**
* Runs the bare test sequence.
*/
final public function runBare(): void {
#[Before]
final public function setup_test_environment(): void {
global $CFG, $DB;
if (phpunit_util::$lastdbwrites != $DB->perf_get_writes()) {
@@ -71,28 +68,18 @@ abstract class advanced_testcase extends base_testcase {
$this->testdbtransaction = $DB->start_delegated_transaction();
}
try {
$this->setCurrentTimeStart();
parent::runBare();
} catch (Exception $ex) {
$e = $ex;
} catch (Throwable $ex) {
// Engine errors in PHP7 throw exceptions of type Throwable (this "catch" will be ignored in PHP5).
$e = $ex;
} finally {
// Reset global state after test and test failure.
$CFG = phpunit_util::get_global_backup('CFG');
$DB = phpunit_util::get_global_backup('DB');
$this->setCurrentTimeStart();
}
// We need to reset the autoloader.
\core_component::reset();
}
#[After]
final public function teardown_test_environment(): void {
global $CFG, $DB;
// Reset global state after test and test failure.
$CFG = phpunit_util::get_global_backup('CFG');
$DB = phpunit_util::get_global_backup('DB');
if (isset($e)) {
// Cleanup after failed expectation.
self::resetAllData();
throw $e;
}
// We need to reset the autoloader.
\core_component::reset();
// Deal with any debugging messages.
$debugerror = phpunit_util::display_debugging_messages(true);
@@ -698,8 +685,8 @@ abstract class advanced_testcase extends base_testcase {
$params['userid'] = $matchuserid;
}
$lock = $this->createMock(\core\lock\lock::class);
$cronlock = $this->createMock(\core\lock\lock::class);
$lock = $this->createStub(\core\lock\lock::class);
$cronlock = $this->createStub(\core\lock\lock::class);
$tasks = $DB->get_recordset('task_adhoc', $params);
foreach ($tasks as $record) {
+102 -3
View File
@@ -1,5 +1,4 @@
<?php
use PHPUnit\Framework\MockObject\Rule\InvocationOrder;
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
@@ -25,6 +24,8 @@ use PHPUnit\Framework\MockObject\Rule\InvocationOrder;
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use PHPUnit\Framework\MockObject\Rule\InvocationOrder;
use PHPUnit\Framework\TestCase;
/**
* Base class for PHPUnit test cases customised for Moodle
@@ -54,12 +55,57 @@ abstract class base_testcase extends PHPUnit\Framework\TestCase {
* @deprecated 3.0
*/
public static function assertTag($matcher, $actual, $message = '', $ishtml = true) {
$dom = (new PHPUnit\Util\Xml\Loader)->load($actual, $ishtml);
if ($ishtml) {
$dom = self::loadHTML($actual);
} else {
$dom = (new PHPUnit\Util\Xml\Loader)->load($actual);
}
$tags = self::findNodes($dom, $matcher, $ishtml);
$matched = (is_array($tags) && count($tags) > 0) && $tags[0] instanceof DOMNode;
self::assertTrue($matched, $message);
}
/**
* Load HTML into a DomDocument.
*
* Note: THis is a replacement for functionality removed from PHPUnit 10.
*
* @param string $actual
* @throws \PHPUnit\Util\Xml\XmlException
* @return DOMDocument
*/
public static function loadHTML(string $actual): DOMDocument {
if ($actual === '') {
throw new \PHPUnit\Util\Xml\XmlException('Could not load XML from empty string');
}
$document = new DOMDocument;
$document->preserveWhiteSpace = false;
$internal = libxml_use_internal_errors(true);
$message = '';
$reporting = error_reporting(0);
$loaded = $document->loadHTML($actual);
foreach (libxml_get_errors() as $error) {
$message .= "\n" . $error->message;
}
libxml_use_internal_errors($internal);
error_reporting($reporting);
if ($loaded === false) {
if ($message === '') {
$message = 'Could not load XML for unknown reason';
}
throw new \PHPUnit\Util\Xml\XmlException($message);
}
return $document;
}
/**
* Note: we are overriding this method to remove the deprecated error
* @see https://tracker.moodle.org/browse/MDL-47129
@@ -72,7 +118,11 @@ abstract class base_testcase extends PHPUnit\Framework\TestCase {
* @deprecated 3.0
*/
public static function assertNotTag($matcher, $actual, $message = '', $ishtml = true) {
$dom = (new PHPUnit\Util\Xml\Loader)->load($actual, $ishtml);
if ($ishtml) {
$dom = self::loadHTML($actual);
} else {
$dom = (new PHPUnit\Util\Xml\Loader)->load($actual);
}
$tags = self::findNodes($dom, $matcher, $ishtml);
$matched = (is_array($tags) && count($tags) > 0) && $tags[0] instanceof DOMNode;
self::assertFalse($matched, $message);
@@ -605,7 +655,56 @@ abstract class base_testcase extends PHPUnit\Framework\TestCase {
* @return int
*/
protected static function getInvocationCount(InvocationOrder $counter): int {
if (method_exists($counter, 'numberOfInvocations')) {
return $counter->numberOfInvocations();
}
return $counter->getInvocationCount();
}
// phpcs:enable
/**
* Get an invokable object for testing.
*
* This is a helper method to create an invokable object for testing which can be used to
* track invocations, including arguments provided.
*
* This can be useful for modifications to the error handler.
*
* @return object
*/
protected static function get_invokable() {
return new class {
private array $invocations = [];
public function __invoke(...$args) {
$this->invocations[] = $args;
}
public function get_invocations(): array {
return $this->invocations;
}
public function get_invocation_count(): int {
return count($this->invocations);
}
public function reset(): void {
$this->invocations = [];
}
};
}
/**
* Determine whether the test is running in isolation.
*
* Note: This was previously a public method of the TestCase, but as removed in PHPUnit 10.
* There is no direct replacement, but we can use reflection to access the protected property.
* @return bool
*/
public function isInIsolation(): bool {
$rc = new \ReflectionClass(TestCase::class);
$rcp = $rc->getProperty('inIsolation');
return $rcp->getValue($this);
}
}
+16 -39
View File
@@ -1,4 +1,5 @@
<?php
use PHPUnit\Framework\Attributes\After;
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
@@ -14,16 +15,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Basic test case.
*
* @package core
* @category phpunit
* @copyright 2012 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* The simplest PHPUnit test case customised for Moodle
*
@@ -35,52 +26,38 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class basic_testcase extends base_testcase {
/**
* Constructs a test case with the given name.
*
* Note: use setUp() or setUpBeforeClass() in your test cases.
*
* @param string $name
* @param array $data
* @param string $dataName
*/
final public function __construct($name = null, array $data = array(), $dataName = '') {
parent::__construct($name, $data, $dataName);
final public function __construct($name = null) {
parent::__construct($name);
$this->setBackupGlobals(false);
$this->setBackupStaticAttributes(false);
$this->setRunTestInSeparateProcess(false);
}
/**
* Runs the bare test sequence and log any changes in global state or database.
* @return void
*/
final public function runBare(): void {
#[After]
final public function test_teardown(): void {
global $DB;
try {
parent::runBare();
} catch (Exception $ex) {
$e = $ex;
} catch (Throwable $ex) {
// Engine errors in PHP7 throw exceptions of type Throwable (this "catch" will be ignored in PHP5).
$e = $ex;
}
if (isset($e)) {
// cleanup after failed expectation
phpunit_util::reset_all_data();
throw $e;
}
if ($DB->is_transaction_started()) {
phpunit_util::reset_all_data();
throw new coding_exception('basic_testcase '.$this->getName().' is not supposed to use database transactions!');
throw new coding_exception('basic_testcase ' . $this->getName() . ' is not supposed to use database transactions!');
}
phpunit_util::reset_all_data(true);
}
/**
* Get the name of the test.
*
* Replaces the original PHPUnit method.
* @return string
*/
final public function getName(): string {
return $this->name();
}
}
@@ -1,4 +1,6 @@
<?php
use PHPUnit\Framework\Attributes\After;
use PHPUnit\Framework\Attributes\Before;
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
@@ -55,14 +57,11 @@ abstract class database_driver_testcase extends base_testcase {
* Constructs a test case with the given name.
*
* @param string $name
* @param array $data
* @param string $dataName
*/
final public function __construct($name = null, array $data = array(), $dataName = '') {
parent::__construct($name, $data, $dataName);
final public function __construct($name = null) {
parent::__construct($name);
$this->setBackupGlobals(false);
$this->setBackupStaticAttributes(false);
$this->setRunTestInSeparateProcess(false);
}
@@ -100,9 +99,9 @@ abstract class database_driver_testcase extends base_testcase {
self::$extradb = $d;
}
protected function setUp(): void {
#[Before]
protected function setup_extradb(): void {
global $DB;
parent::setUp();
if (self::$extradb) {
$this->tdb = self::$extradb;
@@ -111,7 +110,8 @@ abstract class database_driver_testcase extends base_testcase {
}
}
protected function tearDown(): void {
#[After]
protected function teardown_extradb(): void {
// delete all test tables
$dbman = $this->tdb->get_manager();
$tables = $this->tdb->get_tables(false);
@@ -121,7 +121,6 @@ abstract class database_driver_testcase extends base_testcase {
$dbman->drop_table($table);
}
}
parent::tearDown();
}
public static function tearDownAfterClass(): void {
@@ -133,34 +132,13 @@ abstract class database_driver_testcase extends base_testcase {
parent::tearDownAfterClass();
}
/**
* Runs the bare test sequence.
* @return void
*/
public function runBare(): void {
try {
parent::runBare();
// Deal with any debugging messages.
$debugerror = phpunit_util::display_debugging_messages(true);
$this->resetDebugging();
if (!empty($debugerror)) {
trigger_error('Unexpected debugging() call detected.' . "\n" . $debugerror, E_USER_NOTICE);
}
} catch (Exception $ex) {
$e = $ex;
} catch (Throwable $ex) {
// Engine errors in PHP7 throw exceptions of type Throwable (this "catch" will be ignored in PHP5).
$e = $ex;
}
if (isset($e)) {
if ($this->tdb->is_transaction_started()) {
$this->tdb->force_transaction_rollback();
}
$this->tearDown();
throw $e;
#[After]
public function check_debugging(): void {
// Deal with any debugging messages.
$debugerror = phpunit_util::display_debugging_messages(true);
$this->resetDebugging();
if (!empty($debugerror)) {
trigger_error('Unexpected debugging() call detected.' . "\n" . $debugerror, E_USER_NOTICE);
}
}
@@ -0,0 +1,27 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_phpunit\exception;
/**
* An exception thrown when an error is encountered in the setup, teardown, or other non-test parts of a unit test.
*
* @package core_testing
* @copyright Andrew Lyons <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class test_exception extends \core\exception\coding_exception {
}
+1 -1
View File
@@ -314,7 +314,7 @@ class phpunit_util extends testing_util {
if ($warnings) {
$warnings = implode("\n", $warnings);
trigger_error($warnings, E_USER_WARNING);
throw new \core_phpunit\exception\test_exception($warnings);
}
}
+29 -73
View File
@@ -2,7 +2,7 @@
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:annotation>
<xs:documentation source="https://phpunit.de/documentation.html">
This Schema file defines the rules by which the XML configuration file of PHPUnit 9.5 may be structured.
This Schema file defines the rules by which the XML configuration file of PHPUnit 10.0 may be structured.
</xs:documentation>
<xs:appinfo source="https://phpunit.de/documentation.html"/>
</xs:annotation>
@@ -32,7 +32,6 @@
<xs:attribute name="cacheDirectory" type="xs:anyURI"/>
<xs:attribute name="pathCoverage" type="xs:boolean" default="false"/>
<xs:attribute name="includeUncoveredFiles" type="xs:boolean" default="true"/>
<xs:attribute name="processUncoveredFiles" type="xs:boolean" default="false"/>
<xs:attribute name="ignoreDeprecatedCodeUnits" type="xs:boolean" default="false"/>
<xs:attribute name="disableCodeCoverageIgnore" type="xs:boolean" default="false"/>
</xs:complexType>
@@ -57,62 +56,19 @@
</xs:complexType>
<xs:complexType name="extensionsType">
<xs:sequence>
<xs:element name="extension" type="objectType" maxOccurs="unbounded"/>
<xs:element name="bootstrap" type="bootstrapType" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="listenersType">
<xs:complexType name="bootstrapType">
<xs:sequence>
<xs:element name="listener" type="objectType" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="objectType">
<xs:sequence>
<xs:element name="arguments" minOccurs="0">
<xs:complexType>
<xs:group ref="argumentsGroup"/>
</xs:complexType>
</xs:element>
<xs:element name="parameter" type="parameterType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="class" type="xs:string" use="required"/>
<xs:attribute name="file" type="xs:anyURI"/>
</xs:complexType>
<xs:complexType name="arrayType">
<xs:sequence>
<xs:element name="element" type="argumentType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:complexType name="parameterType">
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="value" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="argumentType">
<xs:group ref="argumentChoice"/>
<xs:attribute name="key" use="required"/>
</xs:complexType>
<xs:group name="argumentsGroup">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="array" type="arrayType" />
<xs:element name="integer" type="xs:integer" />
<xs:element name="string" type="xs:string" />
<xs:element name="double" type="xs:double" />
<xs:element name="null" />
<xs:element name="object" type="objectType" />
<xs:element name="file" type="xs:anyURI" />
<xs:element name="directory" type="xs:anyURI" />
<xs:element name="boolean" type="xs:boolean" />
</xs:choice>
</xs:sequence>
</xs:group>
<xs:group name="argumentChoice">
<xs:choice>
<xs:element name="array" type="arrayType" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="integer" type="xs:integer" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="string" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="double" type="xs:double" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="null" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="object" type="objectType" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="file" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="directory" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="boolean" type="xs:boolean" minOccurs="0" maxOccurs="unbounded"/>
</xs:choice>
</xs:group>
<xs:simpleType name="columnsType">
<xs:union>
<xs:simpleType>
@@ -135,7 +91,7 @@
</xs:group>
<xs:complexType name="directoryFilterType">
<xs:simpleContent>
<xs:extension base="xs:anyURI">
<xs:extension base="xs:string">
<xs:attribute type="xs:string" name="prefix" default=""/>
<xs:attribute type="xs:string" name="suffix" default="Test.php"/>
<xs:attributeGroup ref="phpVersionGroup"/>
@@ -207,19 +163,14 @@
</xs:complexType>
<xs:attributeGroup name="configAttributeGroup">
<xs:attribute name="backupGlobals" type="xs:boolean" default="false"/>
<xs:attribute name="backupStaticAttributes" type="xs:boolean" default="false"/>
<xs:attribute name="backupStaticProperties" type="xs:boolean" default="false"/>
<xs:attribute name="bootstrap" type="xs:anyURI"/>
<xs:attribute name="cacheDirectory" type="xs:anyURI"/>
<xs:attribute name="cacheResult" type="xs:boolean" default="true"/>
<xs:attribute name="cacheResultFile" type="xs:anyURI"/>
<xs:attribute name="colors" type="xs:boolean" default="false"/>
<xs:attribute name="columns" type="columnsType" default="80"/>
<xs:attribute name="convertDeprecationsToExceptions" type="xs:boolean" default="true"/>
<xs:attribute name="convertErrorsToExceptions" type="xs:boolean" default="true"/>
<xs:attribute name="convertNoticesToExceptions" type="xs:boolean" default="true"/>
<xs:attribute name="convertWarningsToExceptions" type="xs:boolean" default="true"/>
<xs:attribute name="forceCoversAnnotation" type="xs:boolean" default="false"/>
<xs:attribute name="printerClass" type="xs:string" default="PHPUnit\TextUI\DefaultResultPrinter"/>
<xs:attribute name="printerFile" type="xs:anyURI"/>
<xs:attribute name="requireCoverageMetadata" type="xs:boolean" default="false"/>
<xs:attribute name="processIsolation" type="xs:boolean" default="false"/>
<xs:attribute name="stopOnDefect" type="xs:boolean" default="false"/>
<xs:attribute name="stopOnError" type="xs:boolean" default="false"/>
@@ -235,37 +186,36 @@
<xs:attribute name="failOnWarning" type="xs:boolean" default="false"/>
<xs:attribute name="beStrictAboutChangesToGlobalState" type="xs:boolean" default="false"/>
<xs:attribute name="beStrictAboutOutputDuringTests" type="xs:boolean" default="false"/>
<xs:attribute name="beStrictAboutResourceUsageDuringSmallTests" type="xs:boolean" default="false"/>
<xs:attribute name="beStrictAboutTestsThatDoNotTestAnything" type="xs:boolean" default="true"/>
<xs:attribute name="beStrictAboutTodoAnnotatedTests" type="xs:boolean" default="false"/>
<xs:attribute name="beStrictAboutCoversAnnotation" type="xs:boolean" default="false"/>
<xs:attribute name="beStrictAboutCoverageMetadata" type="xs:boolean" default="false"/>
<xs:attribute name="defaultTimeLimit" type="xs:integer" default="0"/>
<xs:attribute name="enforceTimeLimit" type="xs:boolean" default="false"/>
<xs:attribute name="timeoutForSmallTests" type="xs:integer" default="1"/>
<xs:attribute name="timeoutForMediumTests" type="xs:integer" default="10"/>
<xs:attribute name="timeoutForLargeTests" type="xs:integer" default="60"/>
<xs:attribute name="testSuiteLoaderClass" type="xs:string" default="PHPUnit\Runner\StandardTestSuiteLoader"/>
<xs:attribute name="testSuiteLoaderFile" type="xs:anyURI"/>
<xs:attribute name="defaultTestSuite" type="xs:string" default=""/>
<xs:attribute name="verbose" type="xs:boolean" default="false"/>
<xs:attribute name="testdox" type="xs:boolean" default="false"/>
<xs:attribute name="stderr" type="xs:boolean" default="false"/>
<xs:attribute name="reverseDefectList" type="xs:boolean" default="false"/>
<xs:attribute name="registerMockObjectsFromTestArgumentsRecursively" type="xs:boolean" default="false"/>
<xs:attribute name="extensionsDirectory" type="xs:string"/>
<xs:attribute name="extensionsDirectory" type="xs:anyURI"/>
<xs:attribute name="executionOrder" type="executionOrderType" default="default"/>
<xs:attribute name="resolveDependencies" type="xs:boolean" default="true"/>
<xs:attribute name="noInteraction" type="xs:boolean" default="false"/>
<xs:attribute name="displayDetailsOnIncompleteTests" type="xs:boolean" default="false"/>
<xs:attribute name="displayDetailsOnSkippedTests" type="xs:boolean" default="false"/>
<xs:attribute name="displayDetailsOnTestsThatTriggerDeprecations" type="xs:boolean" default="false"/>
<xs:attribute name="displayDetailsOnTestsThatTriggerErrors" type="xs:boolean" default="false"/>
<xs:attribute name="displayDetailsOnTestsThatTriggerNotices" type="xs:boolean" default="false"/>
<xs:attribute name="displayDetailsOnTestsThatTriggerWarnings" type="xs:boolean" default="false"/>
</xs:attributeGroup>
<xs:group name="configGroup">
<xs:all>
<xs:element ref="testSuiteFacet" minOccurs="0"/>
<xs:element name="groups" type="groupsType" minOccurs="0"/>
<xs:element name="testdoxGroups" type="groupsType" minOccurs="0"/>
<xs:element name="coverage" type="coverageType" minOccurs="0"/>
<xs:element name="logging" type="loggingType" minOccurs="0"/>
<xs:element name="extensions" type="extensionsType" minOccurs="0"/>
<xs:element name="listeners" type="listenersType" minOccurs="0"/>
<xs:element name="php" type="phpType" minOccurs="0"/>
</xs:all>
</xs:group>
@@ -279,8 +229,10 @@
</xs:complexType>
<xs:complexType name="testSuiteType">
<xs:sequence>
<xs:group ref="pathGroup"/>
<xs:element name="exclude" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:group ref="pathGroup"/>
<xs:element name="exclude" type="xs:string"/>
</xs:choice>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
@@ -301,8 +253,6 @@
<xs:element name="teamcity" type="logToFileType" minOccurs="0" />
<xs:element name="testdoxHtml" type="logToFileType" minOccurs="0" />
<xs:element name="testdoxText" type="logToFileType" minOccurs="0" />
<xs:element name="testdoxXml" type="logToFileType" minOccurs="0" />
<xs:element name="text" type="logToFileType" minOccurs="0"/>
</xs:all>
</xs:group>
<xs:complexType name="logToFileType">
@@ -319,6 +269,12 @@
<xs:attribute name="outputDirectory" type="xs:anyURI" use="required"/>
<xs:attribute name="lowUpperBound" type="xs:integer" default="50"/>
<xs:attribute name="highLowerBound" type="xs:integer" default="90"/>
<xs:attribute name="colorSuccessLow" type="xs:string" default="#dff0d8"/>
<xs:attribute name="colorSuccessMedium" type="xs:string" default="#c3e3b5"/>
<xs:attribute name="colorSuccessHigh" type="xs:string" default="#99cb84"/>
<xs:attribute name="colorWarning" type="xs:string" default="#fcf8e3"/>
<xs:attribute name="colorDanger" type="xs:string" default="#f2dede"/>
<xs:attribute name="customCssFile" type="xs:string"/>
</xs:complexType>
<xs:complexType name="coverageReportTextType">
<xs:attribute name="outputFile" type="xs:anyURI" use="required"/>
+26 -18
View File
@@ -16,6 +16,8 @@
namespace core;
use core_phpunit\exception\test_exception;
/**
* Test advanced_testcase extra features.
*
@@ -216,28 +218,29 @@ final class advanced_test extends \advanced_testcase {
// Database change.
$this->assertEquals(1, $DB->get_field('user', 'confirmed', array('id'=>2)));
$DB->set_field('user', 'confirmed', 0, array('id'=>2));
try {
self::resetAllData(true);
} catch (\Exception $e) {
$this->assertInstanceOf('PHPUnit\Framework\Error\Warning', $e);
} catch (test_exception $e) {
$this->assertStringContainsString('unexpected database modification', $e->getMessage());
}
$this->assertEquals(1, $DB->get_field('user', 'confirmed', array('id'=>2)));
$this->assertEquals(1, $DB->get_field('user', 'confirmed', array('id'=>2)));
// Config change.
$CFG->xx = 'yy';
unset($CFG->admin);
$CFG->rolesactive = 0;
try {
self::resetAllData(true);
} catch (\Exception $e) {
$this->assertInstanceOf('PHPUnit\Framework\Error\Warning', $e);
} catch (test_exception $e) {
$this->assertStringContainsString('xx', $e->getMessage());
$this->assertStringContainsString('admin', $e->getMessage());
$this->assertStringContainsString('rolesactive', $e->getMessage());
$this->assertFalse(isset($CFG->xx));
$this->assertTrue(isset($CFG->admin));
$this->assertEquals(1, $CFG->rolesactive);
}
$this->assertFalse(isset($CFG->xx));
$this->assertTrue(isset($CFG->admin));
$this->assertEquals(1, $CFG->rolesactive);
// _GET change.
$_GET['__somethingthatwillnotnormallybepresent__'] = 'yy';
@@ -269,23 +272,28 @@ final class advanced_test extends \advanced_testcase {
$SITE->id = 10;
$COURSE = new \stdClass();
$COURSE->id = 7;
try {
self::resetAllData(true);
} catch (\Exception $e) {
$this->assertInstanceOf('PHPUnit\Framework\Error\Warning', $e);
$this->assertEquals(1, $SITE->id);
$this->assertSame($SITE, $COURSE);
$this->assertSame($SITE, $COURSE);
} catch (test_exception $e) {
$this->assertStringContainsString('unexpected change of $COURSE', $e->getMessage());
}
$this->assertEquals(1, $SITE->id);
$this->assertSame($SITE, $COURSE);
$this->assertSame($SITE, $COURSE);
// USER change.
$this->setUser(2);
try {
self::resetAllData(true);
} catch (\Exception $e) {
$this->assertInstanceOf('PHPUnit\Framework\Error\Warning', $e);
$this->assertEquals(0, $USER->id);
} catch (test_exception $e) {
$this->assertStringContainsString('unexpected change of $USER', $e->getMessage());
}
$this->assertEquals(0, $USER->id);
}
public function test_getDataGenerator(): void {
@@ -666,8 +674,8 @@ final class advanced_test extends \advanced_testcase {
try {
self::resetAllData(true);
} catch (\Exception $e) {
$this->assertInstanceOf('PHPUnit\Framework\Error\Warning', $e);
} catch (test_exception $e) {
$this->assertStringContainsString('unexpected change of locale', $e->getMessage());
}
if ($CFG->ostype === 'WINDOWS') {
+2 -46
View File
@@ -16,6 +16,7 @@
namespace core;
use PHPUnit\Framework\Attributes\WithoutErrorHandler;
use phpunit_util;
/**
@@ -235,16 +236,7 @@ STRING;
global $DB;
$DB->set_field('user', 'confirmed', 1, ['id' => -1]);
// Let's convert the user warnings into an assert-able exception.
set_error_handler(
static function ($errno, $errstr) {
restore_error_handler();
throw new \Exception($errstr, $errno);
},
E_USER_WARNING // Or any other specific E_ that we want to assert.
);
$this->expectException(\Exception::class);
$this->expectException(\core_phpunit\exception\test_exception::class);
$this->expectExceptionMessage('Warning: unexpected database modification');
phpunit_util::reset_all_data(true);
}
@@ -261,15 +253,6 @@ STRING;
unset($CFG->admin);
$CFG->rolesactive = 0;
// Let's convert the user warnings into an assert-able exception.
set_error_handler(
static function ($errno, $errstr) {
restore_error_handler();
throw new \Exception($errstr, $errno);
},
E_USER_WARNING // Or any other specific E_ that we want to assert.
);
$this->expectException(\Exception::class);
$this->expectExceptionMessageMatches('/rolesactive.*xx value.*removal.*admin/ms'); // 3 messages matched.
phpunit_util::reset_all_data(true);
@@ -285,15 +268,6 @@ STRING;
global $USER;
$USER->id = 10;
// Let's convert the user warnings into an assert-able exception.
set_error_handler(
static function ($errno, $errstr) {
restore_error_handler();
throw new \Exception($errstr, $errno);
},
E_USER_WARNING // Or any other specific E_ that we want to assert.
);
$this->expectException(\Exception::class);
$this->expectExceptionMessage('Warning: unexpected change of $USER');
phpunit_util::reset_all_data(true);
@@ -309,15 +283,6 @@ STRING;
global $COURSE;
$COURSE->id = 10;
// Let's convert the user warnings into an assert-able exception.
set_error_handler(
static function ($errno, $errstr) {
restore_error_handler();
throw new \Exception($errstr, $errno);
},
E_USER_WARNING // Or any other specific E_ that we want to assert.
);
$this->expectException(\Exception::class);
$this->expectExceptionMessage('Warning: unexpected change of $COURSE');
phpunit_util::reset_all_data(true);
@@ -338,15 +303,6 @@ STRING;
$USER->id = 10;
$COURSE->id = 10;
// Let's convert the user warnings into an assert-able exception.
set_error_handler(
static function ($errno, $errstr) {
restore_error_handler();
throw new \Exception($errstr, $errno);
},
E_USER_WARNING // Or any other specific E_ that we want to assert.
);
$this->expectException(\Exception::class);
$this->expectExceptionMessageMatches('/resetting.*rolesactive.*new.*removal.*USER.*COURSE/ms'); // 6 messages matched.
phpunit_util::reset_all_data(true);
+2 -2
View File
@@ -199,7 +199,7 @@ final class phpunit_dataset_test extends advanced_testcase {
'rows' => [],
],
'csv loads ok' => [
'fullpath' => file_get_contents(__DIR__ . '/fixtures/sample_dataset.csv'),
'content' => file_get_contents(__DIR__ . '/fixtures/sample_dataset.csv'),
'type' => 'csv',
'tablename' => 'user',
'exception' => null,
@@ -215,7 +215,7 @@ final class phpunit_dataset_test extends advanced_testcase {
],
],
'xml loads ok' => [
'fullpath' => file_get_contents(__DIR__ . '/fixtures/sample_dataset.xml'),
'content' => file_get_contents(__DIR__ . '/fixtures/sample_dataset.xml'),
'type' => 'xml',
'tablename' => 'user',
'exception' => null,