<commit_before><?php

namespace mageekguy\atoum\report\fields\runner\coverage;

require_once __DIR__ . '/../../../../../constants.php';

use
	mageekguy\atoum,
	mageekguy\atoum\report,
	mageekguy\atoum\template,
	mageekguy\atoum\exceptions,
	mageekguy\atoum\cli\prompt,
	mageekguy\atoum\cli\colorizer
;

class html extends report\fields\runner\coverage\cli
{
	const htmlExtensionFile = '.html';

	protected $urlPrompt = null;
	protected $urlColorizer = null;
	protected $rootUrl = '';
	protected $projectName = '';
	protected $templatesDirectory = null;
	protected $destinationDirectory = null;
	protected $templateParser = null;
	protected $reflectionClassInjector = null;
	protected $bootstrapFile = null;

	public function __construct($projectName, $destinationDirectory)
	{
		parent::__construct();

		$this
			->setProjectName($projectName)
			->setDestinationDirectory($destinationDirectory)
			->setUrlPrompt()
			->setUrlColorizer()
			->setTemplatesDirectory()
			->setTemplateParser()
			->setRootUrl('/')
		;
	}

	public function __toString()
	{
		$string = '';

		if (sizeof($this->coverage) > 0)
		{
			try
			{
				$this->cleanDestinationDirectory();

				$this->adapter->copy($this->templatesDirectory . DIRECTORY_SEPARATOR . 'screen.css', $this->destinationDirectory . DIRECTORY_SEPARATOR . 'screen.css');

				$classes = $this->coverage->getClasses();

				$indexTemplate = $this->templateParser->parseFile($this->templatesDirectory . DIRECTORY_SEPARATOR . 'index.tpl');
				$indexTemplate->projectName = $this->projectName;
				$indexTemplate->rootUrl = $this->rootUrl;

				$coverageValue = $this->coverage->getValue();

				if ($coverageValue === null)
				{
					$indexTemplate->coverageUnavailable->build();
				}
				else
				{
					$indexTemplate->coverageAvailable->build(array('coverageValue' => round($coverageValue * 100, 2)));
				}

				$classCoverageTemplates = $indexTemplate->classCoverage;

				$classCoverageAvailableTemplates = $classCoverageTemplates->classCoverageAvailable;
				$classCoverageUnavailableTemplates = $classCoverageTemplates->classCoverageUnavailable;

				ksort($classes, \SORT_STRING);

				foreach ($classes as $className => $classFile)
				{
					$classCoverageTemplates->className = $className;
					$classCoverageTemplates->classUrl = str_replace('\\', '/', $className) . self::htmlExtensionFile;

					$classCoverageValue = $this->coverage->getValueForClass($className);

					$classCoverageAvailableTemplates->build(array('classCoverageValue' => round($classCoverageValue * 100, 2)));

					$classCoverageTemplates->build();

					$classCoverageAvailableTemplates->resetData();
					$classCoverageUnavailableTemplates->resetData();
				}

				$this->adapter->file_put_contents($this->destinationDirectory . DIRECTORY_SEPARATOR . 'index.html', (string) $indexTemplate->build());

				$classTemplate = $this->templateParser->parseFile($this->templatesDirectory . DIRECTORY_SEPARATOR . 'class.tpl');

				$classTemplate->rootUrl = $this->rootUrl;
				$classTemplate->projectName = $this->projectName;

				$classCoverageAvailableTemplates = $classTemplate->classCoverageAvailable;
				$classCoverageUnavailableTemplates = $classTemplate->classCoverageUnavailable;

				$methodsTemplates = $classTemplate->methods;
				$methodTemplates = $methodsTemplates->method;

				$methodCoverageAvailableTemplates = $methodTemplates->methodCoverageAvailable;
				$methodCoverageUnavailableTemplates = $methodTemplates->methodCoverageUnavailable;

				$sourceFileTemplates = $classTemplate->sourceFile;

				$lineTemplates = $sourceFileTemplates->line;
				$coveredLineTemplates = $sourceFileTemplates->coveredLine;
				$notCoveredLineTemplates = $sourceFileTemplates->notCoveredLine;

				foreach ($this->coverage->getMethods() as $className => $methods)
				{
					$classTemplate->className = $className;
					$classTemplate->relativeRootUrl = rtrim(str_repeat('../', substr_count($className, '\\')), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;

					$classCoverageValue = $this->coverage->getValueForClass($className);

					if ($classCoverageValue === null)
					{
						$classCoverageUnavailableTemplates->build();
					}
					else
					{
						$classCoverageAvailableTemplates->build(array('classCoverageValue' => round($classCoverageValue * 100, 2)));
					}

					$reflectedMethods = array();

					foreach (array_filter($this->getReflectionClass($className)->getMethods(), function($reflectedMethod) use ($className) { return $reflectedMethod->isAbstract() === false && $reflectedMethod->getDeclaringClass()->getName() === $className; }) as $reflectedMethod)
					{
						$reflectedMethods[$reflectedMethod->getName()] = $reflectedMethod;
					}

					if (sizeof($reflectedMethods) > 0)
					{
						foreach (array_intersect(array_keys($reflectedMethods), array_keys($methods)) as $methodName)
						{
							$methodCoverageValue = $this->coverage->getValueForMethod($className, $methodName);

							if ($methodCoverageValue === null)
							{
								$methodCoverageUnavailableTemplates->build(array('methodName' => $methodName));
							}
							else<commit_msg>Fix stylesheet path of HTML coverage report when tested class is in the root namespace<commit_after><?php

namespace mageekguy\atoum\report\fields\runner\coverage;

require_once __DIR__ . '/../../../../../constants.php';

use
	mageekguy\atoum,
	mageekguy\atoum\report,
	mageekguy\atoum\template,
	mageekguy\atoum\exceptions,
	mageekguy\atoum\cli\prompt,
	mageekguy\atoum\cli\colorizer
;

class html extends report\fields\runner\coverage\cli
{
	const htmlExtensionFile = '.html';

	protected $urlPrompt = null;
	protected $urlColorizer = null;
	protected $rootUrl = '';
	protected $projectName = '';
	protected $templatesDirectory = null;
	protected $destinationDirectory = null;
	protected $templateParser = null;
	protected $reflectionClassInjector = null;
	protected $bootstrapFile = null;

	public function __construct($projectName, $destinationDirectory)
	{
		parent::__construct();

		$this
			->setProjectName($projectName)
			->setDestinationDirectory($destinationDirectory)
			->setUrlPrompt()
			->setUrlColorizer()
			->setTemplatesDirectory()
			->setTemplateParser()
			->setRootUrl('/')
		;
	}

	public function __toString()
	{
		$string = '';

		if (sizeof($this->coverage) > 0)
		{
			try
			{
				$this->cleanDestinationDirectory();

				$this->adapter->copy($this->templatesDirectory . DIRECTORY_SEPARATOR . 'screen.css', $this->destinationDirectory . DIRECTORY_SEPARATOR . 'screen.css');

				$classes = $this->coverage->getClasses();

				$indexTemplate = $this->templateParser->parseFile($this->templatesDirectory . DIRECTORY_SEPARATOR . 'index.tpl');
				$indexTemplate->projectName = $this->projectName;
				$indexTemplate->rootUrl = $this->rootUrl;

				$coverageValue = $this->coverage->getValue();

				if ($coverageValue === null)
				{
					$indexTemplate->coverageUnavailable->build();
				}
				else
				{
					$indexTemplate->coverageAvailable->build(array('coverageValue' => round($coverageValue * 100, 2)));
				}

				$classCoverageTemplates = $indexTemplate->classCoverage;

				$classCoverageAvailableTemplates = $classCoverageTemplates->classCoverageAvailable;
				$classCoverageUnavailableTemplates = $classCoverageTemplates->classCoverageUnavailable;

				ksort($classes, \SORT_STRING);

				foreach ($classes as $className => $classFile)
				{
					$classCoverageTemplates->className = $className;
					$classCoverageTemplates->classUrl = str_replace('\\', '/', $className) . self::htmlExtensionFile;

					$classCoverageValue = $this->coverage->getValueForClass($className);

					$classCoverageAvailableTemplates->build(array('classCoverageValue' => round($classCoverageValue * 100, 2)));

					$classCoverageTemplates->build();

					$classCoverageAvailableTemplates->resetData();
					$classCoverageUnavailableTemplates->resetData();
				}

				$this->adapter->file_put_contents($this->destinationDirectory . DIRECTORY_SEPARATOR . 'index.html', (string) $indexTemplate->build());

				$classTemplate = $this->templateParser->parseFile($this->templatesDirectory . DIRECTORY_SEPARATOR . 'class.tpl');

				$classTemplate->rootUrl = $this->rootUrl;
				$classTemplate->projectName = $this->projectName;

				$classCoverageAvailableTemplates = $classTemplate->classCoverageAvailable;
				$classCoverageUnavailableTemplates = $classTemplate->classCoverageUnavailable;

				$methodsTemplates = $classTemplate->methods;
				$methodTemplates = $methodsTemplates->method;

				$methodCoverageAvailableTemplates = $methodTemplates->methodCoverageAvailable;
				$methodCoverageUnavailableTemplates = $methodTemplates->methodCoverageUnavailable;

				$sourceFileTemplates = $classTemplate->sourceFile;

				$lineTemplates = $sourceFileTemplates->line;
				$coveredLineTemplates = $sourceFileTemplates->coveredLine;
				$notCoveredLineTemplates = $sourceFileTemplates->notCoveredLine;

				foreach ($this->coverage->getMethods() as $className => $methods)
				{
					$classTemplate->className = $className;

					if (substr_count($className, '\\') >= 1)
					{
						$classTemplate->relativeRootUrl = rtrim(str_repeat('../', substr_count($className, '\\')), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
					}

					$classCoverageValue = $this->coverage->getValueForClass($className);

					if ($classCoverageValue === null)
					{
						$classCoverageUnavailableTemplates->build();
					}
					else
					{
						$classCoverageAvailableTemplates->build(array('classCoverageValue' => round($classCoverageValue * 100, 2)));
					}

					$reflectedMethods = array();

					foreach (array_filter($this->getReflectionClass($className)->getMethods(), function($reflectedMethod) use ($className) { return $reflectedMethod->isAbstract() === false && $reflectedMethod->getDeclaringClass()->getName() === $className; }) as $reflectedMethod)
					{
						$reflectedMethods[$reflectedMethod->getName()] = $reflectedMethod;
					}

					if (sizeof($reflectedMethods) > 0)
					{
						foreach (array_intersect(array_keys($reflectedMethods), array_keys($methods)) as $methodName)
						{
							$methodCoverageValue = $this->coverage->getValueForMethod($className, $methodName);

							if ($methodCoverageValue === null)
							{
								$methodCoverageUnavailableTemplates->build(array('methodName' => $methodName));
							}
							else
{'fraction_non_alphanumeric': 0.1384363250747132, 'fraction_numerical': 0.002795719656801311, 'mean_word_length': 4.684383561643836, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 174, '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': '2131923', 'n_tokens_mistral': 3775, 'n_tokens_neox': 2989, 'n_words': 438}