<commit_before><?php

/**
 * This file is part of CoverallsKit.
 *
 * (c) <NAME> <<EMAIL>>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace coverallskit\report\parser;

use coverallskit\report\ReportParser;
use coverallskit\entity\SourceFile;
use coverallskit\entity\collection\SourceFileCollection;
use coverallskit\entity\CoverageResult;
use Zend\Dom\Query;
use Zend\Dom\NodeList;
use coverallskit\exception\ExceptionCollection;
use coverallskit\exception\LineOutOfRangeException;
use DOMElement;


/**
 * Class CloverReportParser
 * @package coverallskit\report\parser
 */
class CloverReportParser implements ReportParser
{

    /**
     * @var string
     */
    private $reportContent;

    /**
     * @var \coverallskit\entity\SourceFile
     */
    private $source;

    /**
     * @var \coverallskit\entity\collection\SourceFileCollection
     */
    private $sourceCollection;

    /**
     * @var \coverallskit\entity\collection\CoverageCollection
     */
    private $coverages;

    /**
     * @var ExceptionCollection
     */
    private $coveragesErrors;

    /**
     * @var ExceptionCollection
     */
    private $reportParseErrors;


    public function __construct()
    {
        $this->sourceCollection = new SourceFileCollection();
        $this->reportParseErrors = new ExceptionCollection();
    }


    /**
     * @param string $reportContent
     * @return Result
     */
    public function parse($reportContent)
    {
        $this->reportContent = $reportContent;

        $files = $this->findFiles();
        return $this->parseFileNodes($files);
    }

    /**
     * @return NodeList
     */
    private function findFiles()
    {
        $query = new Query($this->reportContent);
        return $query->execute('file');
    }

    /**
     * @param string $fileName
     * @return NodeList
     */
    private function findCoverages($fileName)
    {
        $query = new Query($this->reportContent);
        return $query->execute("file[name='$fileName'] line");
    }

    /**
     * @param \Zend\Dom\NodeList $files
     * @return Result
     */
    private function parseFileNodes(NodeList $files)
    {
        foreach($files as $file) {
            $fileName = (string) $file->getAttribute('name');

            $this->source = new SourceFile($fileName);

            $lines = $this->findCoverages($fileName);
            $this->parseLineNodes($lines);
        }

        $result = new Result(
            $this->sourceCollection,
            $this->reportParseErrors
        );

        return $result;
    }

    /**
     * @param \Zend\Dom\NodeList $lines
     */
    private function parseLineNodes(NodeList $lines)
    {
        $this->coverages = $this->source->getEmptyCoverages();
        $this->coveragesErrors = new ExceptionCollection($this->source->getName());

        foreach ($lines as $line) {
            $this->parseLine($line);
        }

        $this->source->addCoverages($this->coverages);
        $this->sourceCollection->add($this->source);

        $this->reportParseErrors->merge($this->coveragesErrors);
    }

    /**
     * @param DOMElement $line
     */
    private function parseLine(DOMElement $line)
    {
        $lineNumber = (int) $line->getAttribute('num');
        $executeCount = (int) $line->getAttribute('count');

        $analysisResult = ($executeCount >= 1)
            ? CoverageResult::EXECUTED : CoverageResult::UNUSED;

        $coverage = new CoverageResult($lineNumber, $analysisResult);

        try {
            $this->coverages->add($coverage);
        } catch (LineOutOfRangeException $exception) {
            $this->coveragesErrors->add($exception);
        }
    }

}<commit_msg>Replace dom parsee to DomCrawler<commit_after><?php

/**
 * This file is part of CoverallsKit.
 *
 * (c) <NAME> <<EMAIL>>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace coverallskit\report\parser;

use coverallskit\report\ReportParser;
use coverallskit\entity\SourceFile;
use coverallskit\entity\collection\SourceFileCollection;
use coverallskit\entity\CoverageResult;
use Symfony\Component\DomCrawler\Crawler;
use coverallskit\exception\ExceptionCollection;
use coverallskit\exception\LineOutOfRangeException;


/**
 * Class CloverReportParser
 * @package coverallskit\report\parser
 */
class CloverReportParser implements ReportParser
{
    /**
     * @var \Symfony\Component\DomCrawler\Crawler
     */
    private $crawler;

    /**
     * @var \coverallskit\entity\SourceFile
     */
    private $source;

    /**
     * @var \coverallskit\entity\collection\SourceFileCollection
     */
    private $sourceCollection;

    /**
     * @var \coverallskit\entity\collection\CoverageCollection
     */
    private $coverages;

    /**
     * @var ExceptionCollection
     */
    private $coveragesErrors;

    /**
     * @var ExceptionCollection
     */
    private $reportParseErrors;

    public function __construct()
    {
        $this->crawler = new Crawler();
        $this->sourceCollection = new SourceFileCollection();
        $this->reportParseErrors = new ExceptionCollection();
    }

    /**
     * @param string $reportContent
     * @return Result
     */
    public function parse($reportContent)
    {
        $this->crawler->addXmlContent($reportContent);
        $fileNodes = $this->crawler->filter('file');

        return $this->parseFileNodes($fileNodes);
    }

    /**
     * @param Crawler $files
     * @return Result
     */
    private function parseFileNodes(Crawler $files)
    {
        $fileNodeParser = function(Crawler $file) {
            $fileName = $file->attr('name');

            $this->source = new SourceFile($fileName);
            $lines = $this->crawler->filter("file[name='$fileName'] line");

            $this->parseLineNodes($lines);
        };
        $fileNodeParser->bind($this);

        $files->each($fileNodeParser);

        $result = new Result(
            $this->sourceCollection,
            $this->reportParseErrors
        );

        return $result;
    }

    /**
     * @param Crawler $lines
     */
    private function parseLineNodes(Crawler $lines)
    {
        $this->coverages = $this->source->getEmptyCoverages();
        $this->coveragesErrors = new ExceptionCollection($this->source->getName());

        $lineNodeParser = function(Crawler $line) {
            $this->parseLine($line);
        };
        $lineNodeParser->bind($this);

        $lines->each($lineNodeParser);

        $this->source->addCoverages($this->coverages);
        $this->sourceCollection->add($this->source);

        $this->reportParseErrors->merge($this->coveragesErrors);
    }

    /**
     * @param Crawler $line
     */
    private function parseLine(Crawler $line)
    {
        $lineNumber = (int) $line->attr('num');
        $executeCount = (int) $line->attr('count');

        $analysisResult = ($executeCount >= 1)
            ? CoverageResult::EXECUTED : CoverageResult::UNUSED;

        $coverage = new CoverageResult($lineNumber, $analysisResult);

        try {
            $this->coverages->add($coverage);
        } catch (LineOutOfRangeException $exception) {
            $this->coveragesErrors->add($exception);
        }
    }

}
{'fraction_non_alphanumeric': 0.1329519139081869, 'fraction_numerical': 0.0002724424465331699, 'mean_word_length': 2.5332050048123196, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 89, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, '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': '2544922', 'n_tokens_mistral': 2142, 'n_tokens_neox': 2082, 'n_words': 391}