<commit_before><?php
/**
 * Humbug
 *
 * @category   Humbug
 * @package    Humbug
 * @copyright  Copyright (c) 2015 <NAME> (http://blog.astrumfutura.com)
 * @license    https://github.com/padraic/humbug/blob/master/LICENSE New BSD License
 */

namespace Humbug\Adapter\Phpunit;

use Humbug\Container;
use Humbug\Exception\RuntimeException;
use Humbug\Exception\InvalidArgumentException;

class XmlConfiguration
{
    private static $dom;

    /**
     * @var \DOMElement
     */
    private static $root;

    private static $listeners;

    private static $xpath;

    private static $hasBootstrap;

    /**
     * Wrangle XML to create a PHPUnit configuration, based on the original, that
     * allows for more control over what tests are run, allows JUnit logging,
     * and ensures that Code Coverage (for Humbug use) whitelists all of the
     * relevant source code.
     *
     *
     * @return string
     */
    public static function assemble(Container $container, $firstRun = false, array $testSuites = [])
    {
        self::$hasBootstrap = false;

        /**
         * Basically a carbon copy of how PHPUnit finds its er...config file?
         */
        $conf = null;
        $dir = null;
        $testDir = $container->getTestRunDirectory();

        if (!empty($testDir)) {
            $dir = $testDir;
            $conf = $dir . '/phpunit.xml';
        } else {
            $dir = $container->getBaseDirectory();
            $conf = $dir . '/phpunit.xml';
        }

        if (file_exists($conf)) {
            $conf = realpath($conf);
        } elseif (file_exists($conf . '.dist')) {
            $conf = realpath($conf . '.dist');
        } else {
            throw new RuntimeException('Unable to locate phpunit.xml(.dist) file. This is required by Humbug.');
        }

        if (!empty($dir)) {
            $dir .= '/';
        }

        /**
         * Start the DOMmobile
         */
        $oldValue = libxml_disable_entity_loader(true);
        self::$dom = new \DOMDocument;
        self::$dom->preserveWhiteSpace = false;
        self::$dom->formatOutput = true;
        self::$dom->loadXML(file_get_contents($conf));
        self::$root = self::$dom->documentElement;
        libxml_disable_entity_loader($oldValue);

        self::handleRootAttributes($conf, $container);

        self::$xpath = new \DOMXPath(self::$dom);

        /**
         * On first runs collect a test log and also generate code coverage
         */
        self::handleElementReset();
        if ($firstRun === true) {
            self::handleLogging($container);
            self::handleStartupListeners($container);
        } else {
            self::handleTestSuiteFilterListener($testSuites, $container);
        }

        /** @var \DOMNode[] $nodesToRemove */
        $nodesToRemove = array();
        $suites = self::$xpath->query('/phpunit/testsuites/testsuite');
        foreach ($suites as $suite) {
            // DOMNodeList's Traversable implementation is a bit unpredictable.
            // Iterate over the child nodes using a for loop rather than a
            // foreach so that we can append new children without these being
            // iterated over again.
            $length = $suite->childNodes->length;
            for ($i = 0; $i < $length; $i++) {
                $node = $suite->childNodes->item($i);
                if ($node instanceof \DOMElement
                && ($node->tagName == 'directory'
                || $node->tagName == 'exclude'
                || $node->tagName == 'file')) {
                    $fullPath = $dir . '/' . $node->nodeValue;
                    // Check if the paths exist.
                    $paths = glob($fullPath);
                    if (0 === count($paths)) {
                        // It's no problem if an exclude path is missing.
                        if ($node->tagName !== 'exclude') {
                            throw new RuntimeException('Unable to locate file specified in testsuites: ' . $fullPath);
                        }
                    } else {
                        foreach ($paths as $path) {
                            $clone = $node->cloneNode();
                            $clone->nodeValue = self::makeAbsolutePath($path, getcwd());
                            $node->parentNode->appendChild($clone);
                        }
                    }
                    // Mark the original unprocessed node to be removed.
                    $nodesToRemove[] = $node;
                }
            }
        }<commit_msg>Refactoring - duplication removed<commit_after><?php
/**
 * Humbug
 *
 * @category   Humbug
 * @package    Humbug
 * @copyright  Copyright (c) 2015 <NAME> (http://blog.astrumfutura.com)
 * @license    https://github.com/padraic/humbug/blob/master/LICENSE New BSD License
 */

namespace Humbug\Adapter\Phpunit;

use Humbug\Container;
use Humbug\Exception\RuntimeException;
use Humbug\Exception\InvalidArgumentException;

class XmlConfiguration
{
    private static $dom;

    /**
     * @var \DOMElement
     */
    private static $root;

    private static $listeners;

    private static $xpath;

    private static $hasBootstrap;

    /**
     * Wrangle XML to create a PHPUnit configuration, based on the original, that
     * allows for more control over what tests are run, allows JUnit logging,
     * and ensures that Code Coverage (for Humbug use) whitelists all of the
     * relevant source code.
     *
     *
     * @return string
     */
    public static function assemble(Container $container, $firstRun = false, array $testSuites = [])
    {
        self::$hasBootstrap = false;

        /**
         * Basically a carbon copy of how PHPUnit finds its er...config file?
         */
        $configurationDir = null;
        $testDir = $container->getTestRunDirectory();

        if (!empty($testDir)) {
            $configurationDir = $testDir;
        } else {
            $configurationDir = $container->getBaseDirectory();
        }

        $conf = $configurationDir . '/phpunit.xml';

        if (file_exists($conf)) {
            $conf = realpath($conf);
        } elseif (file_exists($conf . '.dist')) {
            $conf = realpath($conf . '.dist');
        } else {
            throw new RuntimeException('Unable to locate phpunit.xml(.dist) file. This is required by Humbug.');
        }

        if (!empty($configurationDir)) {
            $configurationDir .= '/';
        }

        /**
         * Start the DOMmobile
         */
        $oldValue = libxml_disable_entity_loader(true);
        self::$dom = new \DOMDocument;
        self::$dom->preserveWhiteSpace = false;
        self::$dom->formatOutput = true;
        self::$dom->loadXML(file_get_contents($conf));
        self::$root = self::$dom->documentElement;
        libxml_disable_entity_loader($oldValue);

        self::handleRootAttributes($conf, $container);

        self::$xpath = new \DOMXPath(self::$dom);

        /**
         * On first runs collect a test log and also generate code coverage
         */
        self::handleElementReset();
        if ($firstRun === true) {
            self::handleLogging($container);
            self::handleStartupListeners($container);
        } else {
            self::handleTestSuiteFilterListener($testSuites, $container);
        }

        /** @var \DOMNode[] $nodesToRemove */
        $nodesToRemove = array();
        $suites = self::$xpath->query('/phpunit/testsuites/testsuite');
        foreach ($suites as $suite) {
            // DOMNodeList's Traversable implementation is a bit unpredictable.
            // Iterate over the child nodes using a for loop rather than a
            // foreach so that we can append new children without these being
            // iterated over again.
            $length = $suite->childNodes->length;
            for ($i = 0; $i < $length; $i++) {
                $node = $suite->childNodes->item($i);
                if ($node instanceof \DOMElement
                && ($node->tagName == 'directory'
                || $node->tagName == 'exclude'
                || $node->tagName == 'file')) {
                    $fullPath = $configurationDir . '/' . $node->nodeValue;
                    // Check if the paths exist.
                    $paths = glob($fullPath);
                    if (0 === count($paths)) {
                        // It's no problem if an exclude path is missing.
                        if ($node->tagName !== 'exclude') {
                            throw new RuntimeException('Unable to locate file specified in testsuites: ' . $fullPath);
                        }
                    } else {
                        foreach ($paths as $path) {
                            $clone = $node->cloneNode();
                            $clone->nodeValue = self::makeAbsolutePath($path, getcwd());
                            $node->parentNode->appendChild($clone);
                        }
                    }
                    // Mark the original unprocessed node to be removed.
                    $nodesToRemove[] = $node;
                }
            }
        }
{'fraction_non_alphanumeric': 0.12290319043964477, 'fraction_numerical': 0.0013156452143405328, 'mean_word_length': 1.7286868082560574, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 45, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 9}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4998865', 'n_tokens_mistral': 2430, 'n_tokens_neox': 2352, 'n_words': 625}