diff --git a/composer.json b/composer.json
index 6527ed2f3..e315a9bf4 100644
--- a/composer.json
+++ b/composer.json
@@ -29,7 +29,8 @@
"phpunit/php-text-template": "^1.2",
"sebastian/code-unit-reverse-lookup": "^1.0",
"sebastian/environment": "^2.0",
- "sebastian/version": "^2.0"
+ "sebastian/version": "^2.0",
+ "theseer/tokenizer": "^1.1"
},
"require-dev": {
"phpunit/phpunit": "^6.0",
diff --git a/src/Report/Xml/Facade.php b/src/Report/Xml/Facade.php
index 9cfbd7aaa..d7511bde5 100644
--- a/src/Report/Xml/Facade.php
+++ b/src/Report/Xml/Facade.php
@@ -148,7 +148,7 @@ private function processFile(FileNode $file, Directory $context)
}
foreach ($file->getCoverageData() as $line => $tests) {
- if (!is_array($tests) || count($tests) == 0) {
+ if (!is_array($tests) || count($tests) === 0) {
continue;
}
@@ -161,6 +161,10 @@ private function processFile(FileNode $file, Directory $context)
$coverage->finalize();
}
+ $fileReport->getSource()->setSourceCode(
+ file_get_contents($file->getPath())
+ );
+
$this->saveDocument($fileReport->asDom(), $file->getId());
}
diff --git a/src/Report/Xml/Report.php b/src/Report/Xml/Report.php
index a6e1e63ba..455524fe6 100644
--- a/src/Report/Xml/Report.php
+++ b/src/Report/Xml/Report.php
@@ -70,4 +70,23 @@ private function getUnitObject($tagName, $name)
return new Unit($node, $name);
}
+
+ public function getSource()
+ {
+ $source = $this->getContextNode()->getElementsByTagNameNS(
+ 'http://schema.phpunit.de/coverage/1.0',
+ 'source'
+ )->item(0);
+
+ if (!$source) {
+ $source = $this->getContextNode()->appendChild(
+ $this->getDomDocument()->createElementNS(
+ 'http://schema.phpunit.de/coverage/1.0',
+ 'source'
+ )
+ );
+ }
+
+ return new Source($source);
+ }
}
diff --git a/src/Report/Xml/Source.php b/src/Report/Xml/Source.php
new file mode 100644
index 000000000..f6780f2d5
--- /dev/null
+++ b/src/Report/Xml/Source.php
@@ -0,0 +1,45 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Report\Xml;
+
+use TheSeer\Tokenizer\NamespaceUri;
+use TheSeer\Tokenizer\Tokenizer;
+use TheSeer\Tokenizer\XMLSerializer;
+
+class Source
+{
+ /** @var \DOMElement */
+ private $context;
+
+ /**
+ * @param \DOMElement $context
+ */
+ public function __construct(\DOMElement $context)
+ {
+ $this->context = $context;
+ }
+
+ /**
+ * @param string $source
+ */
+ public function setSourceCode(string $source)
+ {
+ $context = $this->context;
+
+ $tokens = (new Tokenizer())->parse($source);
+ $srcDom = (new XMLSerializer(new NamespaceUri($context->namespaceURI)))->toDom($tokens);
+
+ $context->parentNode->replaceChild(
+ $context->ownerDocument->importNode($srcDom->documentElement, true),
+ $context
+ );
+ }
+}
diff --git a/tests/_files/Report/XML/CoverageForBankAccount/BankAccount.php.xml b/tests/_files/Report/XML/CoverageForBankAccount/BankAccount.php.xml
index 4186c8bf9..63cc369ec 100644
--- a/tests/_files/Report/XML/CoverageForBankAccount/BankAccount.php.xml
+++ b/tests/_files/Report/XML/CoverageForBankAccount/BankAccount.php.xml
@@ -36,5 +36,227 @@
+
+
+ <?php
+
+
+ class
+
+ BankAccount
+
+
+ {
+
+
+
+ protected
+
+ $balance
+
+ =
+
+ 0
+ ;
+
+
+
+
+ public
+
+ function
+
+ getBalance
+ (
+ )
+
+
+
+ {
+
+
+
+ return
+
+ $this
+ ->
+ balance
+ ;
+
+
+
+ }
+
+
+
+
+ protected
+
+ function
+
+ setBalance
+ (
+ $balance
+ )
+
+
+
+ {
+
+
+
+ if
+
+ (
+ $balance
+
+ >=
+
+ 0
+ )
+
+ {
+
+
+
+ $this
+ ->
+ balance
+
+ =
+
+ $balance
+ ;
+
+
+
+ }
+
+ else
+
+ {
+
+
+
+ throw
+
+ new
+
+ RuntimeException
+ ;
+
+
+
+ }
+
+
+
+ }
+
+
+
+
+ public
+
+ function
+
+ depositMoney
+ (
+ $balance
+ )
+
+
+
+ {
+
+
+
+ $this
+ ->
+ setBalance
+ (
+ $this
+ ->
+ getBalance
+ (
+ )
+
+ +
+
+ $balance
+ )
+ ;
+
+
+
+
+ return
+
+ $this
+ ->
+ getBalance
+ (
+ )
+ ;
+
+
+
+ }
+
+
+
+
+ public
+
+ function
+
+ withdrawMoney
+ (
+ $balance
+ )
+
+
+
+ {
+
+
+
+ $this
+ ->
+ setBalance
+ (
+ $this
+ ->
+ getBalance
+ (
+ )
+
+ -
+
+ $balance
+ )
+ ;
+
+
+
+
+ return
+
+ $this
+ ->
+ getBalance
+ (
+ )
+ ;
+
+
+
+ }
+
+
+ }
+
+
+
diff --git a/tests/_files/Report/XML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.xml b/tests/_files/Report/XML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.xml
index d6e1da7ea..c22518d8d 100644
--- a/tests/_files/Report/XML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.xml
+++ b/tests/_files/Report/XML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.xml
@@ -37,5 +37,126 @@
+
+
+ <?php
+
+
+
+ class
+
+ CoveredClassWithAnonymousFunctionInStaticMethod
+
+
+ {
+
+
+
+ public
+
+ static
+
+ function
+
+ runAnonymous
+ (
+ )
+
+
+
+ {
+
+
+
+ $filter
+
+ =
+
+ [
+ 'abc124'
+ ,
+
+ 'abc123'
+ ,
+
+ '123'
+ ]
+ ;
+
+
+
+
+ array_walk
+ (
+
+
+
+ $filter
+ ,
+
+
+
+ function
+
+ (
+ &
+ $val
+ ,
+
+ $key
+ )
+
+ {
+
+
+
+ $val
+
+ =
+
+ preg_replace
+ (
+ '|[^0-9]|'
+ ,
+
+ ''
+ ,
+
+ $val
+ )
+ ;
+
+
+
+ }
+
+
+
+ )
+ ;
+
+
+
+
+ // Should be covered
+
+
+
+ $extravar
+
+ =
+
+ true
+ ;
+
+
+
+ }
+
+
+ }
+
+
+
diff --git a/tests/_files/Report/XML/CoverageForFileWithIgnoredLines/source_with_ignore.php.xml b/tests/_files/Report/XML/CoverageForFileWithIgnoredLines/source_with_ignore.php.xml
index 5f8ce25b6..9a8fc6621 100644
--- a/tests/_files/Report/XML/CoverageForFileWithIgnoredLines/source_with_ignore.php.xml
+++ b/tests/_files/Report/XML/CoverageForFileWithIgnoredLines/source_with_ignore.php.xml
@@ -24,5 +24,164 @@
+
+
+ <?php
+
+
+ if
+
+ (
+ $neverHappens
+ )
+
+ {
+
+
+
+ // @codeCoverageIgnoreStart
+
+
+
+ print
+
+ '*'
+ ;
+
+
+
+ // @codeCoverageIgnoreEnd
+
+
+ }
+
+
+
+ /**
+
+
+ * @codeCoverageIgnore
+
+
+ */
+
+
+ class
+
+ Foo
+
+
+ {
+
+
+
+ public
+
+ function
+
+ bar
+ (
+ )
+
+
+
+ {
+
+
+
+ }
+
+
+ }
+
+
+
+ class
+
+ Bar
+
+
+ {
+
+
+
+ /**
+
+
+ * @codeCoverageIgnore
+
+
+ */
+
+
+
+ public
+
+ function
+
+ foo
+ (
+ )
+
+
+
+ {
+
+
+
+ }
+
+
+ }
+
+
+
+ function
+
+ baz
+ (
+ )
+
+
+ {
+
+
+
+ print
+
+ '*'
+ ;
+
+ // @codeCoverageIgnore
+
+
+ }
+
+
+
+ interface
+
+ Bor
+
+
+ {
+
+
+
+ public
+
+ function
+
+ foo
+ (
+ )
+ ;
+
+
+
+ }
+
+
+