mageekguy\atoum\report\fields\runner\coverage: lines coverage

58% of 391

OPs

76% of 76

Lines

48% of 67

Branches

25% of 55

Paths
Method OPs OPs % Lines Line % Branches Branches % Paths Path %
mageekguy\atoum\report\fields\runner\coverage::__construct() 21 100% 5 100% 1 0% 1 100%
mageekguy\atoum\report\fields\runner\coverage::setPhp() 16 100% 2 100% 1 100% 1 100%
mageekguy\atoum\report\fields\runner\coverage::getPhp() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\report\fields\runner\coverage::setAdapter() 16 100% 2 100% 1 100% 1 100%
mageekguy\atoum\report\fields\runner\coverage::getAdapter() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\report\fields\runner\coverage::addSrcDirectory() 38 100% 10 100% 11 100% 4 100%
mageekguy\atoum\report\fields\runner\coverage::getSrcDirectories() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\report\fields\runner\coverage::getSrcDirectoryIterators() 58 28% 8 100% 11 55% 5 20%
mageekguy\atoum\report\fields\runner\coverage::getCoverage() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\report\fields\runner\coverage::handleEvent() 218 43% 45 60% 38 24% 39 5%
#
1
<?php
2

                    
3
namespace mageekguy\atoum\report\fields\runner;
4

                    
5
use
6
	mageekguy\atoum\php,
7
	mageekguy\atoum\adapter,
8
	mageekguy\atoum\exceptions\runtime,
9
	mageekguy\atoum\iterators,
10
	mageekguy\atoum\observable,
11
	mageekguy\atoum\runner,
12
	mageekguy\atoum\report
13
;
14

                    
15
abstract class coverage extends report\field
16
{
17
	protected $php = null;
18
	protected $adapter = null;
19
	protected $coverage = null;
20
	protected $srcDirectories = array();
21

                    
22
	public function __construct()100%
23
	{
24
		parent::__construct(array(runner::runStop));
25

                    
26
		$this
27
			->setPhp()
28
			->setAdapter()
29
		;
30
	}
31

                    
32
	public function setPhp(php $php = null)100%
33
	{
34
		$this->php = $php ?: new php();
35

                    
36
		return $this;
37
	}
38

                    
39
	public function getPhp()100%
40
	{
41
		return $this->php;
42
	}
43

                    
44
	public function setAdapter(adapter $adapter = null)100%
45
	{
46
		$this->adapter = $adapter ?: new adapter();
47

                    
48
		return $this;
49
	}
50

                    
51
	public function getAdapter()100%
52
	{
53
		return $this->adapter;
54
	}
55

                    
56
	public function addSrcDirectory($srcDirectory, \closure $filterClosure = null)100%
57
	{
58
		$srcDirectory = (string) $srcDirectory;
59

                    
60
		if (isset($this->srcDirectories[$srcDirectory]) === false)
61
		{
62
			$this->srcDirectories[$srcDirectory] = $filterClosure === null ? array() : array($filterClosure);
63
		}
64
		else if ($filterClosure !== null)
65
		{
66
			$this->srcDirectories[$srcDirectory][] = $filterClosure;
67
		}
68

                    
69
		return $this;
70
	}
71

                    
72
	public function getSrcDirectories()100%
73
	{
74
		return $this->srcDirectories;
75
	}
76

                    
77
	public function getSrcDirectoryIterators()100%
78
	{
79
		$iterators = array();
80

                    
81
		foreach ($this->srcDirectories as $srcDirectory => $closures)
82
		{
83
			$iterators[] = $iterator = new \recursiveIteratorIterator(new iterators\filters\recursives\closure(new \recursiveDirectoryIterator($srcDirectory, \filesystemIterator::SKIP_DOTS|\filesystemIterator::CURRENT_AS_FILEINFO)), \recursiveIteratorIterator::LEAVES_ONLY);
84

                    
85
			foreach ($closures as $closure)
86
			{
87
				$iterator->addClosure($closure);
88
			}
89
		}
90

                    
91
		return $iterators;
92
	}
93

                    
94
	public function getCoverage()100%
95
	{
96
		return $this->coverage;
97
	}
98

                    
99
	public function handleEvent($event, observable $observable)60%
100
	{
101
		if (parent::handleEvent($event, $observable) === false)
102
		{
103
			return false;
104
		}
105
		else if ($observable->codeCoverageIsEnabled() === true)
106
		{
107
			$this->coverage = $observable->getScore()->getCoverage();
108

                    
109
			if ($this->adapter->extension_loaded('xdebug') === true)
110
			{
111
				$phpCode =
112
					'<?php ' .
113
					'ob_start();' .
114
					'require \'' . \mageekguy\atoum\directory . '/classes/autoloader.php\';'
115
				;
116

                    
117
				$bootstrapFile = $observable->getBootstrapFile();
118

                    
119
				if ($bootstrapFile !== null)
120
				{
121
					$phpCode .=
122
						'$includer = new mageekguy\atoum\includer();' .
123
						'try { $includer->includePath(\'' . $bootstrapFile . '\'); }' .
124
						'catch (mageekguy\atoum\includer\exception $exception)' .
125
						'{ die(\'Unable to include bootstrap file \\\'' . $bootstrapFile . '\\\'\'); }'
126
					;
127
				}
128

                    
129
				$phpCode .=
130
					'$data = array(\'classes\' => get_declared_classes());' .
131
					'ob_start();' .
132
					'xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE' . ($observable->branchCoverageIsEnabled() === true ? ' | XDEBUG_CC_BRANCH_CHECK' : '')  . ');' .
133
					'require_once \'%s\';' .
134
					'$data[\'coverage\'] = xdebug_get_code_coverage();' .
135
					'xdebug_stop_code_coverage();' .
136
					'ob_end_clean();' .
137
					'$data[\'classes\'] = array_diff(get_declared_classes(), $data[\'classes\']);' .
138
					'echo serialize($data);'
139
				;
140

                    
141
				foreach ($this->getSrcDirectoryIterators() as $srcDirectoryIterator)
142
				{
143
					foreach ($srcDirectoryIterator as $file)
144
					{
145
						if (in_array($file->getPathname(), $this->adapter->get_included_files()) === false)
146
						{
147
							if ($this->php->reset()->run(sprintf($phpCode, $file->getPathname()))->getExitCode() > 0)
148
							{
149
								throw new runtime('Unable to get default code coverage for file \'' . $file->getPathname() . '\': ' . $this->php->getStderr());
150
							}
151

                    
152
							$data = unserialize($this->php->getStdOut());
153

                    
154
							foreach ($data['classes'] as $class)
155
							{
156
								$this->coverage->addXdebugDataForClass($class, $data['coverage']);
157
							}
158
						}
159
					}
160
				}
161
			}
162

                    
163
			return true;
164
		}
165
	}
166
}