summaryrefslogtreecommitdiff
path: root/vendor/phpunit/phpunit/src/Util/Log/JUnit.php
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/phpunit/phpunit/src/Util/Log/JUnit.php')
-rw-r--r--vendor/phpunit/phpunit/src/Util/Log/JUnit.php424
1 files changed, 424 insertions, 0 deletions
diff --git a/vendor/phpunit/phpunit/src/Util/Log/JUnit.php b/vendor/phpunit/phpunit/src/Util/Log/JUnit.php
new file mode 100644
index 000000000..7a97682fc
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/Log/JUnit.php
@@ -0,0 +1,424 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Util\Log;
+
+use function class_exists;
+use function get_class;
+use function method_exists;
+use function sprintf;
+use function str_replace;
+use function trim;
+use DOMDocument;
+use DOMElement;
+use PHPUnit\Framework\AssertionFailedError;
+use PHPUnit\Framework\ExceptionWrapper;
+use PHPUnit\Framework\SelfDescribing;
+use PHPUnit\Framework\Test;
+use PHPUnit\Framework\TestFailure;
+use PHPUnit\Framework\TestListener;
+use PHPUnit\Framework\TestSuite;
+use PHPUnit\Framework\Warning;
+use PHPUnit\Util\Exception;
+use PHPUnit\Util\Filter;
+use PHPUnit\Util\Printer;
+use PHPUnit\Util\Xml;
+use ReflectionClass;
+use ReflectionException;
+use Throwable;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class JUnit extends Printer implements TestListener
+{
+ /**
+ * @var DOMDocument
+ */
+ private $document;
+
+ /**
+ * @var DOMElement
+ */
+ private $root;
+
+ /**
+ * @var bool
+ */
+ private $reportRiskyTests = false;
+
+ /**
+ * @var DOMElement[]
+ */
+ private $testSuites = [];
+
+ /**
+ * @var int[]
+ */
+ private $testSuiteTests = [0];
+
+ /**
+ * @var int[]
+ */
+ private $testSuiteAssertions = [0];
+
+ /**
+ * @var int[]
+ */
+ private $testSuiteErrors = [0];
+
+ /**
+ * @var int[]
+ */
+ private $testSuiteWarnings = [0];
+
+ /**
+ * @var int[]
+ */
+ private $testSuiteFailures = [0];
+
+ /**
+ * @var int[]
+ */
+ private $testSuiteSkipped = [0];
+
+ /**
+ * @var int[]
+ */
+ private $testSuiteTimes = [0];
+
+ /**
+ * @var int
+ */
+ private $testSuiteLevel = 0;
+
+ /**
+ * @var DOMElement
+ */
+ private $currentTestCase;
+
+ /**
+ * @param null|mixed $out
+ */
+ public function __construct($out = null, bool $reportRiskyTests = false)
+ {
+ $this->document = new DOMDocument('1.0', 'UTF-8');
+ $this->document->formatOutput = true;
+
+ $this->root = $this->document->createElement('testsuites');
+ $this->document->appendChild($this->root);
+
+ parent::__construct($out);
+
+ $this->reportRiskyTests = $reportRiskyTests;
+ }
+
+ /**
+ * Flush buffer and close output.
+ */
+ public function flush(): void
+ {
+ $this->write($this->getXML());
+
+ parent::flush();
+ }
+
+ /**
+ * An error occurred.
+ */
+ public function addError(Test $test, Throwable $t, float $time): void
+ {
+ $this->doAddFault($test, $t, 'error');
+ $this->testSuiteErrors[$this->testSuiteLevel]++;
+ }
+
+ /**
+ * A warning occurred.
+ */
+ public function addWarning(Test $test, Warning $e, float $time): void
+ {
+ $this->doAddFault($test, $e, 'warning');
+ $this->testSuiteWarnings[$this->testSuiteLevel]++;
+ }
+
+ /**
+ * A failure occurred.
+ */
+ public function addFailure(Test $test, AssertionFailedError $e, float $time): void
+ {
+ $this->doAddFault($test, $e, 'failure');
+ $this->testSuiteFailures[$this->testSuiteLevel]++;
+ }
+
+ /**
+ * Incomplete test.
+ */
+ public function addIncompleteTest(Test $test, Throwable $t, float $time): void
+ {
+ $this->doAddSkipped();
+ }
+
+ /**
+ * Risky test.
+ */
+ public function addRiskyTest(Test $test, Throwable $t, float $time): void
+ {
+ if (!$this->reportRiskyTests) {
+ return;
+ }
+
+ $this->doAddFault($test, $t, 'error');
+ $this->testSuiteErrors[$this->testSuiteLevel]++;
+ }
+
+ /**
+ * Skipped test.
+ */
+ public function addSkippedTest(Test $test, Throwable $t, float $time): void
+ {
+ $this->doAddSkipped();
+ }
+
+ /**
+ * A testsuite started.
+ */
+ public function startTestSuite(TestSuite $suite): void
+ {
+ $testSuite = $this->document->createElement('testsuite');
+ $testSuite->setAttribute('name', $suite->getName());
+
+ if (class_exists($suite->getName(), false)) {
+ try {
+ $class = new ReflectionClass($suite->getName());
+
+ $testSuite->setAttribute('file', $class->getFileName());
+ } catch (ReflectionException $e) {
+ }
+ }
+
+ if ($this->testSuiteLevel > 0) {
+ $this->testSuites[$this->testSuiteLevel]->appendChild($testSuite);
+ } else {
+ $this->root->appendChild($testSuite);
+ }
+
+ $this->testSuiteLevel++;
+ $this->testSuites[$this->testSuiteLevel] = $testSuite;
+ $this->testSuiteTests[$this->testSuiteLevel] = 0;
+ $this->testSuiteAssertions[$this->testSuiteLevel] = 0;
+ $this->testSuiteErrors[$this->testSuiteLevel] = 0;
+ $this->testSuiteWarnings[$this->testSuiteLevel] = 0;
+ $this->testSuiteFailures[$this->testSuiteLevel] = 0;
+ $this->testSuiteSkipped[$this->testSuiteLevel] = 0;
+ $this->testSuiteTimes[$this->testSuiteLevel] = 0;
+ }
+
+ /**
+ * A testsuite ended.
+ */
+ public function endTestSuite(TestSuite $suite): void
+ {
+ $this->testSuites[$this->testSuiteLevel]->setAttribute(
+ 'tests',
+ (string) $this->testSuiteTests[$this->testSuiteLevel]
+ );
+
+ $this->testSuites[$this->testSuiteLevel]->setAttribute(
+ 'assertions',
+ (string) $this->testSuiteAssertions[$this->testSuiteLevel]
+ );
+
+ $this->testSuites[$this->testSuiteLevel]->setAttribute(
+ 'errors',
+ (string) $this->testSuiteErrors[$this->testSuiteLevel]
+ );
+
+ $this->testSuites[$this->testSuiteLevel]->setAttribute(
+ 'warnings',
+ (string) $this->testSuiteWarnings[$this->testSuiteLevel]
+ );
+
+ $this->testSuites[$this->testSuiteLevel]->setAttribute(
+ 'failures',
+ (string) $this->testSuiteFailures[$this->testSuiteLevel]
+ );
+
+ $this->testSuites[$this->testSuiteLevel]->setAttribute(
+ 'skipped',
+ (string) $this->testSuiteSkipped[$this->testSuiteLevel]
+ );
+
+ $this->testSuites[$this->testSuiteLevel]->setAttribute(
+ 'time',
+ sprintf('%F', $this->testSuiteTimes[$this->testSuiteLevel])
+ );
+
+ if ($this->testSuiteLevel > 1) {
+ $this->testSuiteTests[$this->testSuiteLevel - 1] += $this->testSuiteTests[$this->testSuiteLevel];
+ $this->testSuiteAssertions[$this->testSuiteLevel - 1] += $this->testSuiteAssertions[$this->testSuiteLevel];
+ $this->testSuiteErrors[$this->testSuiteLevel - 1] += $this->testSuiteErrors[$this->testSuiteLevel];
+ $this->testSuiteWarnings[$this->testSuiteLevel - 1] += $this->testSuiteWarnings[$this->testSuiteLevel];
+ $this->testSuiteFailures[$this->testSuiteLevel - 1] += $this->testSuiteFailures[$this->testSuiteLevel];
+ $this->testSuiteSkipped[$this->testSuiteLevel - 1] += $this->testSuiteSkipped[$this->testSuiteLevel];
+ $this->testSuiteTimes[$this->testSuiteLevel - 1] += $this->testSuiteTimes[$this->testSuiteLevel];
+ }
+
+ $this->testSuiteLevel--;
+ }
+
+ /**
+ * A test started.
+ */
+ public function startTest(Test $test): void
+ {
+ $usesDataprovider = false;
+
+ if (method_exists($test, 'usesDataProvider')) {
+ $usesDataprovider = $test->usesDataProvider();
+ }
+
+ $testCase = $this->document->createElement('testcase');
+ $testCase->setAttribute('name', $test->getName());
+
+ try {
+ $class = new ReflectionClass($test);
+ // @codeCoverageIgnoreStart
+ } catch (ReflectionException $e) {
+ throw new Exception(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ $methodName = $test->getName(!$usesDataprovider);
+
+ if ($class->hasMethod($methodName)) {
+ try {
+ $method = $class->getMethod($methodName);
+ // @codeCoverageIgnoreStart
+ } catch (ReflectionException $e) {
+ throw new Exception(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ $testCase->setAttribute('class', $class->getName());
+ $testCase->setAttribute('classname', str_replace('\\', '.', $class->getName()));
+ $testCase->setAttribute('file', $class->getFileName());
+ $testCase->setAttribute('line', (string) $method->getStartLine());
+ }
+
+ $this->currentTestCase = $testCase;
+ }
+
+ /**
+ * A test ended.
+ */
+ public function endTest(Test $test, float $time): void
+ {
+ $numAssertions = 0;
+
+ if (method_exists($test, 'getNumAssertions')) {
+ $numAssertions = $test->getNumAssertions();
+ }
+
+ $this->testSuiteAssertions[$this->testSuiteLevel] += $numAssertions;
+
+ $this->currentTestCase->setAttribute(
+ 'assertions',
+ (string) $numAssertions
+ );
+
+ $this->currentTestCase->setAttribute(
+ 'time',
+ sprintf('%F', $time)
+ );
+
+ $this->testSuites[$this->testSuiteLevel]->appendChild(
+ $this->currentTestCase
+ );
+
+ $this->testSuiteTests[$this->testSuiteLevel]++;
+ $this->testSuiteTimes[$this->testSuiteLevel] += $time;
+
+ $testOutput = '';
+
+ if (method_exists($test, 'hasOutput') && method_exists($test, 'getActualOutput')) {
+ $testOutput = $test->hasOutput() ? $test->getActualOutput() : '';
+ }
+
+ if (!empty($testOutput)) {
+ $systemOut = $this->document->createElement(
+ 'system-out',
+ Xml::prepareString($testOutput)
+ );
+
+ $this->currentTestCase->appendChild($systemOut);
+ }
+
+ $this->currentTestCase = null;
+ }
+
+ /**
+ * Returns the XML as a string.
+ */
+ public function getXML(): string
+ {
+ return $this->document->saveXML();
+ }
+
+ private function doAddFault(Test $test, Throwable $t, string $type): void
+ {
+ if ($this->currentTestCase === null) {
+ return;
+ }
+
+ if ($test instanceof SelfDescribing) {
+ $buffer = $test->toString() . "\n";
+ } else {
+ $buffer = '';
+ }
+
+ $buffer .= trim(
+ TestFailure::exceptionToString($t) . "\n" .
+ Filter::getFilteredStacktrace($t)
+ );
+
+ $fault = $this->document->createElement(
+ $type,
+ Xml::prepareString($buffer)
+ );
+
+ if ($t instanceof ExceptionWrapper) {
+ $fault->setAttribute('type', $t->getClassName());
+ } else {
+ $fault->setAttribute('type', get_class($t));
+ }
+
+ $this->currentTestCase->appendChild($fault);
+ }
+
+ private function doAddSkipped(): void
+ {
+ if ($this->currentTestCase === null) {
+ return;
+ }
+
+ $skipped = $this->document->createElement('skipped');
+
+ $this->currentTestCase->appendChild($skipped);
+
+ $this->testSuiteSkipped[$this->testSuiteLevel]++;
+ }
+}