mageekguy\atoum\runner: lines coverage

62% of 1973

OPs

70% of 354

Lines

49% of 291

Branches

6% of 1383

Paths
Method OPs OPs % Lines Line % Branches Branches % Paths Path %
mageekguy\atoum\runner::__construct() 64 100% 14 100% 1 0% 1 100%
mageekguy\atoum\runner::setAdapter() 16 100% 2 100% 1 100% 1 100%
mageekguy\atoum\runner::getAdapter() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\runner::setLocale() 16 100% 2 100% 1 100% 1 100%
mageekguy\atoum\runner::getLocale() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\runner::setIncluder() 16 100% 2 100% 1 100% 1 100%
mageekguy\atoum\runner::getIncluder() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\runner::setScore() 16 100% 3 100% 1 100% 1 100%
mageekguy\atoum\runner::getScore() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\runner::setTestGenerator() 16 100% 3 100% 1 100% 1 100%
mageekguy\atoum\runner::getTestGenerator() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\runner::setTestDirectoryIterator() 16 100% 2 100% 1 100% 1 100%
mageekguy\atoum\runner::getTestDirectoryIterator() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\runner::setGlobIteratorFactory() 12 100% 2 100% 1 100% 1 100%
mageekguy\atoum\runner::getGlobIteratorFactory() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\runner::setReflectionClassFactory() 12 100% 2 100% 1 100% 1 100%
mageekguy\atoum\runner::getReflectionClassFactory() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\runner::enableDebugMode() 9 100% 2 100% 1 100% 1 100%
mageekguy\atoum\runner::disableDebugMode() 9 100% 2 100% 1 100% 1 100%
mageekguy\atoum\runner::debugModeIsEnabled() 6 100% 2 100% 1 100% 1 100%
mageekguy\atoum\runner::disallowUndefinedMethodInInterface() 9 0% 1 0% 1 0% 1 0%
mageekguy\atoum\runner::disallowUsageOfUndefinedMethodInMock() 9 100% 2 100% 1 100% 1 100%
mageekguy\atoum\runner::allowUndefinedMethodInInterface() 9 0% 1 0% 1 0% 1 0%
mageekguy\atoum\runner::allowUsageOfUndefinedMethodInMock() 9 100% 2 100% 1 100% 1 100%
mageekguy\atoum\runner::undefinedMethodInInterfaceAreAllowed() 9 0% 1 100% 1 0% 1 0%
mageekguy\atoum\runner::usageOfUndefinedMethodInMockAreAllowed() 8 100% 1 100% 1 100% 1 100%
mageekguy\atoum\runner::setXdebugConfig() 9 100% 2 100% 1 100% 1 100%
mageekguy\atoum\runner::getXdebugConfig() 6 100% 2 100% 1 100% 1 100%
mageekguy\atoum\runner::setMaxChildrenNumber() 21 0% 5 0% 4 0% 2 0%
mageekguy\atoum\runner::acceptTestFileExtensions() 13 100% 2 100% 1 100% 1 100%
mageekguy\atoum\runner::setDefaultReportTitle() 10 100% 2 100% 1 100% 1 100%
mageekguy\atoum\runner::setBootstrapFile() 44 45% 6 83% 5 40% 2 50%
mageekguy\atoum\runner::getDefaultReportTitle() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\runner::setPhp() 16 100% 2 100% 1 100% 1 100%
mageekguy\atoum\runner::getPhp() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\runner::setPhpPath() 13 100% 2 100% 1 100% 1 100%
mageekguy\atoum\runner::getPhpPath() 10 100% 1 100% 1 100% 1 100%
mageekguy\atoum\runner::getTestNumber() 6 100% 2 100% 1 100% 1 100%
mageekguy\atoum\runner::getTestMethodNumber() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\runner::getObservers() 19 68% 5 100% 6 67% 3 33%
mageekguy\atoum\runner::getBootstrapFile() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\runner::getTestMethods() 57 0% 12 0% 12 0% 5 0%
mageekguy\atoum\runner::getCoverage() 10 100% 1 100% 1 100% 1 100%
mageekguy\atoum\runner::enableCodeCoverage() 9 100% 2 100% 1 100% 1 100%
mageekguy\atoum\runner::disableCodeCoverage() 9 100% 2 100% 1 100% 1 100%
mageekguy\atoum\runner::codeCoverageIsEnabled() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\runner::enableBranchCoverage() 12 0% 2 0% 1 0% 1 0%
mageekguy\atoum\runner::disableBranchCoverage() 9 0% 2 0% 1 0% 1 0%
mageekguy\atoum\runner::branchCoverageIsEnabled() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\runner::doNotfailIfVoidMethods() 9 0% 2 0% 1 0% 1 0%
mageekguy\atoum\runner::failIfVoidMethods() 9 0% 2 0% 1 0% 1 0%
mageekguy\atoum\runner::shouldFailIfVoidMethods() 6 0% 1 0% 1 0% 1 0%
mageekguy\atoum\runner::doNotfailIfSkippedMethods() 9 0% 2 0% 1 0% 1 0%
mageekguy\atoum\runner::failIfSkippedMethods() 9 0% 2 0% 1 0% 1 0%
mageekguy\atoum\runner::shouldFailIfSkippedMethods() 6 0% 1 0% 1 0% 1 0%
mageekguy\atoum\runner::addObserver() 13 100% 3 100% 1 100% 1 100%
mageekguy\atoum\runner::removeObserver() 13 100% 2 100% 1 100% 1 100%
mageekguy\atoum\runner::callObservers() 21 52% 4 100% 6 67% 3 33%
mageekguy\atoum\runner::setPathAndVersionInScore() 118 99% 10 100% 12 92% 8 38%
mageekguy\atoum\runner::getTestFactory() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\runner::setTestFactory() 17 100% 12 100% 1 100% 1 100%
mageekguy\atoum\runner::run() 330 67% 69 75% 50 40% 1200 0%
mageekguy\atoum\runner::getTestPaths() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\runner::setTestPaths() 9 100% 2 100% 1 100% 1 100%
mageekguy\atoum\runner::resetTestPaths() 9 100% 2 100% 1 100% 1 100%
mageekguy\atoum\runner::canAddTest() 9 100% 2 100% 1 100% 1 100%
mageekguy\atoum\runner::canNotAddTest() 9 100% 2 100% 1 100% 1 100%
mageekguy\atoum\runner::addTest() 31 100% 9 100% 7 100% 3 100%
mageekguy\atoum\runner::addTestsFromDirectory() 63 0% 11 0% 15 0% 10 0%
mageekguy\atoum\runner::addTestsFromPattern() 81 0% 15 0% 19 0% 13 0%
mageekguy\atoum\runner::getRunningDuration() 21 100% 1 100% 8 100% 4 50%
mageekguy\atoum\runner::getDeclaredTestClasses() 11 100% 1 100% 1 100% 1 100%
mageekguy\atoum\runner::setReport() 25 100% 6 100% 4 100% 2 100%
mageekguy\atoum\runner::addReport() 33 100% 6 100% 7 100% 4 50%
mageekguy\atoum\runner::removeReport() 27 100% 6 100% 4 100% 2 100%
mageekguy\atoum\runner::removeReports() 31 71% 6 100% 6 67% 3 33%
mageekguy\atoum\runner::hasReports() 12 100% 1 100% 1 100% 1 100%
mageekguy\atoum\runner::getReports() 19 68% 5 100% 6 67% 3 33%
mageekguy\atoum\runner::getExtensions() 11 100% 1 100% 1 100% 1 100%
mageekguy\atoum\runner::removeExtension() 18 100% 2 100% 1 100% 1 100%
mageekguy\atoum\runner::removeExtensions() 27 67% 5 100% 6 67% 3 33%
mageekguy\atoum\runner::addExtension() 36 100% 7 100% 4 100% 2 100%
mageekguy\atoum\runner::isIgnored() 81 0% 11 0% 16 0% 24 0%
mageekguy\atoum\runner::findTestClasses() 26 100% 6 100% 1 100% 1 100%
mageekguy\atoum\runner::includeTestPaths() 194 7% 23 22% 29 7% 22 5%
#
1
<?php
2

                    
3
namespace mageekguy\atoum;
4

                    
5
use
6
	mageekguy\atoum,
7
	mageekguy\atoum\iterators,
8
	mageekguy\atoum\exceptions
9
;
10

                    
11
class runner implements observable
12
{
13
	const atoumVersionConstant = 'mageekguy\atoum\version';
14
	const atoumDirectoryConstant = 'mageekguy\atoum\directory';
15

                    
16
	const runStart = 'runnerStart';
17
	const runStop = 'runnerStop';
18

                    
19
	protected $score = null;
20
	protected $adapter = null;
21
	protected $locale = null;
22
	protected $includer = null;
23
	protected $testGenerator = null;
24
	protected $globIteratorFactory = null;
25
	protected $reflectionClassFactory = null;
26
	protected $testFactory = null;
27
	protected $observers = null;
28
	protected $reports = null;
29
	protected $reportSet = null;
30
	protected $testPaths = array();
31
	protected $testNumber = 0;
32
	protected $testMethodNumber = 0;
33
	protected $codeCoverage = true;
34
	protected $branchCoverage = false;
35
	protected $php = null;
36
	protected $defaultReportTitle = null;
37
	protected $maxChildrenNumber = null;
38
	protected $bootstrapFile = null;
39
	protected $testDirectoryIterator = null;
40
	protected $debugMode = false;
41
	protected $xdebugConfig = null;
42
	protected $failIfVoidMethods = false;
43
	protected $failIfSkippedMethods = false;
44
	protected $disallowUsageOfUndefinedMethodInMock = false;
45
	protected $extensions = null;
46

                    
47
	private $start = null;
48
	private $stop = null;
49
	private $canAddTest = true;
50

                    
51
	public function __construct()100%
52
	{
53
		$this
54
			->setAdapter()
55
			->setLocale()
56
			->setIncluder()
57
			->setScore()
58
			->setPhp()
59
			->setTestDirectoryIterator()
60
			->setGlobIteratorFactory()
61
			->setReflectionClassFactory()
62
			->setTestFactory()
63
		;
64

                    
65
		$this->observers = new \splObjectStorage();
66
		$this->reports = new \splObjectStorage();
67
		$this->extensions = new \splObjectStorage();
68
	}
69

                    
70
	public function setAdapter(adapter $adapter = null)100%
71
	{
72
		$this->adapter = $adapter ?: new adapter();
73

                    
74
		return $this;
75
	}
76

                    
77
	public function getAdapter()100%
78
	{
79
		return $this->adapter;
80
	}
81

                    
82
	public function setLocale(locale $locale = null)100%
83
	{
84
		$this->locale = $locale ?: new locale();
85

                    
86
		return $this;
87
	}
88

                    
89
	public function getLocale()100%
90
	{
91
		return $this->locale;
92
	}
93

                    
94
	public function setIncluder(includer $includer = null)100%
95
	{
96
		$this->includer = $includer ?: new includer();
97

                    
98
		return $this;
99
	}
100

                    
101
	public function getIncluder()100%
102
	{
103
		return $this->includer;
104
	}
105

                    
106
	public function setScore(runner\score $score = null)
107
	{
108
		$this->score = $score ?: new runner\score();
109

                    
110
		return $this;
111
	}
112

                    
113
	public function getScore()100%
114
	{
115
		return $this->score;
116
	}
117

                    
118
	public function setTestGenerator(atoum\test\generator $generator = null)100%
119
	{
120
		$this->testGenerator = $generator ?: new atoum\test\generator();
121

                    
122
		return $this;
123
	}
124

                    
125
	public function getTestGenerator()100%
126
	{
127
		return $this->testGenerator;
128
	}
129

                    
130
	public function setTestDirectoryIterator(iterators\recursives\directory\factory $iterator = null)100%
131
	{
132
		$this->testDirectoryIterator = $iterator ?: new iterators\recursives\directory\factory();
133

                    
134
		return $this;
135
	}
136

                    
137
	public function getTestDirectoryIterator()100%
138
	{
139
		return $this->testDirectoryIterator;
140
	}
141

                    
142
	public function setGlobIteratorFactory(\closure $factory = null)100%
143
	{
144
		$this->globIteratorFactory = $factory ?: function($pattern) { return new \globIterator($pattern); };
145

                    
146
		return $this;
147
	}
148

                    
149
	public function getGlobIteratorFactory()100%
150
	{
151
		return $this->globIteratorFactory;
152
	}
153

                    
154
	public function setReflectionClassFactory(\closure $factory = null)100%
155
	{
156
		$this->reflectionClassFactory = $factory ?: function($class) { return new \reflectionClass($class); };
157

                    
158
		return $this;
159
	}
160

                    
161
	public function getReflectionClassFactory()100%
162
	{
163
		return $this->reflectionClassFactory;
164
	}
165

                    
166
	public function enableDebugMode()100%
167
	{
168
		$this->debugMode = true;
169

                    
170
		return $this;
171
	}
172

                    
173
	public function disableDebugMode()100%
174
	{
175
		$this->debugMode = false;
176

                    
177
		return $this;
178
	}
179

                    
180
	public function debugModeIsEnabled()100%
181
	{
182
		return $this->debugMode;
183
	}
184

                    
185
	public function disallowUndefinedMethodInInterface()0%
186
	{
187
		return $this->disallowUsageOfUndefinedMethodInMock();
188
	}
189

                    
190
	public function disallowUsageOfUndefinedMethodInMock()100%
191
	{
192
		$this->disallowUsageOfUndefinedMethodInMock = true;
193

                    
194
		return $this;
195
	}
196

                    
197
	public function allowUndefinedMethodInInterface()0%
198
	{
199
		return $this->allowUsageOfUndefinedMethodInMock();
200
	}
201

                    
202
	public function allowUsageOfUndefinedMethodInMock()100%
203
	{
204
		$this->disallowUsageOfUndefinedMethodInMock = false;
205

                    
206
		return $this;
207
	}
208

                    
209
	public function undefinedMethodInInterfaceAreAllowed()100%
210
	{
211
		return $this->usageOfUndefinedMethodInMockAreAllowed();
212
	}
213

                    
214
	public function usageOfUndefinedMethodInMockAreAllowed()100%
215
	{
216
		return $this->disallowUsageOfUndefinedMethodInMock === false;
217
	}
218

                    
219
	public function setXdebugConfig($value)100%
220
	{
221
		$this->xdebugConfig = $value;
222

                    
223
		return $this;
224
	}
225

                    
226
	public function getXdebugConfig()100%
227
	{
228
		return $this->xdebugConfig;
229
	}
230

                    
231
	public function setMaxChildrenNumber($number)0%
232
	{
233
		if ($number < 1)
234
		{
235
			throw new exceptions\logic\invalidArgument('Maximum number of children must be greater or equal to 1');
236
		}
237

                    
238
		$this->maxChildrenNumber = $number;
239

                    
240
		return $this;
241
	}
242

                    
243
	public function acceptTestFileExtensions(array $testFileExtensions)100%
244
	{
245
		$this->testDirectoryIterator->acceptExtensions($testFileExtensions);
246

                    
247
		return $this;
248
	}
249

                    
250
	public function setDefaultReportTitle($title)100%
251
	{
252
		$this->defaultReportTitle = (string) $title;
253

                    
254
		return $this;
255
	}
256

                    
257
	public function setBootstrapFile($path)83%
258
	{
259
		try
260
		{
261
			$this->includer->includePath($path, function($path) { include_once($path); });
262
		}
263
		catch (atoum\includer\exception $exception)
264
		{
265
			throw new exceptions\runtime\file(sprintf($this->getLocale()->_('Unable to use bootstrap file \'%s\''), $path));
266
		}
267

                    
268
		$this->bootstrapFile = $path;
269

                    
270
		return $this;
271
	}
272

                    
273
	public function getDefaultReportTitle()100%
274
	{
275
		return $this->defaultReportTitle;
276
	}
277

                    
278
	public function setPhp(atoum\php $php = null)100%
279
	{
280
		$this->php = $php ?: new atoum\php();
281

                    
282
		return $this;
283
	}
284

                    
285
	public function getPhp()100%
286
	{
287
		return $this->php;
288
	}
289

                    
290
	public function setPhpPath($path)100%
291
	{
292
		$this->php->setBinaryPath($path);
293

                    
294
		return $this;
295
	}
296

                    
297
	public function getPhpPath()100%
298
	{
299
		return $this->php->getBinaryPath();
300
	}
301

                    
302
	public function getTestNumber()
303
	{
304
		return $this->testNumber;
305
	}
306

                    
307
	public function getTestMethodNumber()100%
308
	{
309
		return $this->testMethodNumber;
310
	}
311

                    
312
	public function getObservers()100%
313
	{
314
		$observers = array();
315

                    
316
		foreach ($this->observers as $observer)
317
		{
318
			$observers[] = $observer;
319
		}
320

                    
321
		return $observers;
322
	}
323

                    
324
	public function getBootstrapFile()100%
325
	{
326
		return $this->bootstrapFile;
327
	}
328

                    
329
	public function getTestMethods(array $namespaces = array(), array $tags = array(), array $testMethods = array(), $testBaseClass = null)0%
330
	{
331
		$classes = array();
332

                    
333
		foreach ($this->getDeclaredTestClasses($testBaseClass) as $testClass)
334
		{
335
			$test = new $testClass();
336

                    
337
			if ($test->isIgnored($namespaces, $tags) === false)
338
			{
339
				$methods = $test->runTestMethods($testMethods, $tags);
340

                    
341
				if ($methods)
342
				{
343
					$classes[$testClass] = $methods;
344
				}
345
			}
346
		}
347

                    
348
		return $classes;
349
	}
350

                    
351
	public function getCoverage()100%
352
	{
353
		return $this->score->getCoverage();
354
	}
355

                    
356
	public function enableCodeCoverage()100%
357
	{
358
		$this->codeCoverage = true;
359

                    
360
		return $this;
361
	}
362

                    
363
	public function disableCodeCoverage()100%
364
	{
365
		$this->codeCoverage = false;
366

                    
367
		return $this;
368
	}
369

                    
370
	public function codeCoverageIsEnabled()100%
371
	{
372
		return $this->codeCoverage;
373
	}
374

                    
375
	public function enableBranchCoverage()0%
376
	{
377
		$this->branchCoverage = $this->codeCoverageIsEnabled();
378

                    
379
		return $this;
380
	}
381

                    
382
	public function disableBranchCoverage()0%
383
	{
384
		$this->branchCoverage = false;
385

                    
386
		return $this;
387
	}
388

                    
389
	public function branchCoverageIsEnabled()100%
390
	{
391
		return $this->branchCoverage;
392
	}
393

                    
394
	public function doNotfailIfVoidMethods()0%
395
	{
396
		$this->failIfVoidMethods = false;
397

                    
398
		return $this;
399
	}
400

                    
401
	public function failIfVoidMethods()0%
402
	{
403
		$this->failIfVoidMethods = true;
404

                    
405
		return $this;
406
	}
407

                    
408
	public function shouldFailIfVoidMethods()0%
409
	{
410
		return $this->failIfVoidMethods;
411
	}
412

                    
413
	public function doNotfailIfSkippedMethods()0%
414
	{
415
		$this->failIfSkippedMethods = false;
416

                    
417
		return $this;
418
	}
419

                    
420
	public function failIfSkippedMethods()0%
421
	{
422
		$this->failIfSkippedMethods = true;
423

                    
424
		return $this;
425
	}
426

                    
427
	public function shouldFailIfSkippedMethods()0%
428
	{
429
		return $this->failIfSkippedMethods;
430
	}
431

                    
432
	public function addObserver(atoum\observer $observer)100%
433
	{
434
		$this->observers->attach($observer);
435

                    
436
		return $this;
437
	}
438

                    
439
	public function removeObserver(atoum\observer $observer)100%
440
	{
441
		$this->observers->detach($observer);
442

                    
443
		return $this;
444
	}
445

                    
446
	public function callObservers($event)100%
447
	{
448
		foreach ($this->observers as $observer)
449
		{
450
			$observer->handleEvent($event, $this);
451
		}
452

                    
453
		return $this;
454
	}
455

                    
456
	public function setPathAndVersionInScore()100%
457
	{
458
		$this->score
459
			->setAtoumVersion($this->adapter->defined(static::atoumVersionConstant) === false ? null : $this->adapter->constant(static::atoumVersionConstant))
460
			->setAtoumPath($this->adapter->defined(static::atoumDirectoryConstant) === false ? null : $this->adapter->constant(static::atoumDirectoryConstant))
461
		;
462

                    
463
		if ($this->php->reset()->addOption('--version')->run()->getExitCode() > 0)
464
		{
465
			throw new exceptions\runtime('Unable to get PHP version from \'' . $this->php . '\'');
466
		}
467

                    
468
		$this->score
469
			->setPhpPath($this->php->getBinaryPath())
470
			->setPhpVersion($this->php->getStdout())
471
		;
472

                    
473
		return $this;
474
	}
475

                    
476
	public function getTestFactory()100%
477
	{
478
		return $this->testFactory;
479
	}
480

                    
481
	public function setTestFactory($testFactory = null)100%
482
	{
483
		$testFactory = $testFactory ?: function($testClass) {
484
			return new $testClass();
485
		};
486

                    
487
		$runner = $this;
488

                    
489
		$this->testFactory = function($testClass) use ($testFactory, $runner) {
490
			$test = call_user_func($testFactory, $testClass);
491

                    
492
			if ($runner->usageOfUndefinedMethodInMockAreAllowed() === false)
493
			{
494
				$test->getMockGenerator()->disallowUndefinedMethodUsage();
495
			}
496

                    
497
			return $test;
498
		};
499

                    
500
		return $this;
501
	}
502

                    
503
	public function run(array $namespaces = array(), array $tags = array(), array $runTestClasses = array(), array $runTestMethods = array(), $testBaseClass = null)75%
504
	{
505
		$this->includeTestPaths();
506

                    
507
		$this->testNumber = 0;
508
		$this->testMethodNumber = 0;
509

                    
510
		$this->score->reset();
511

                    
512
		$this->setPathAndVersionInScore();
513

                    
514
		if ($this->defaultReportTitle !== null)
515
		{
516
			foreach ($this->reports as $report)
517
			{
518
				if ($report->getTitle() === null)
519
				{
520
					$report->setTitle($this->defaultReportTitle);
521
				}
522
			}
523
		}
524

                    
525
		$declaredTestClasses = $this->getDeclaredTestClasses($testBaseClass);
526

                    
527
		if (sizeof($runTestClasses) <= 0)
528
		{
529
			$runTestClasses = $declaredTestClasses;
530
		}
531
		else
532
		{
533
			$runTestClasses = array_intersect($runTestClasses, $declaredTestClasses);
534
		}
535

                    
536
		natsort($runTestClasses);
537

                    
538
		$tests = array();
539

                    
540
		foreach ($runTestClasses as $runTestClass)
541
		{
542
			$test = call_user_func($this->testFactory, $runTestClass);
543

                    
544
			if ($test->isIgnored($namespaces, $tags) === false)
545
			{
546
				$testMethodNumber = sizeof($test->runTestMethods($runTestMethods, $tags));
547

                    
548
				if ($testMethodNumber > 0)
549
				{
550
					$tests[] = $test;
551
					$test->addExtensions($this->extensions);
552

                    
553
					$this->testNumber++;
554
					$this->testMethodNumber += $testMethodNumber;
555

                    
556
					$test
557
						->setPhpPath($this->php->getBinaryPath())
558
						->setAdapter($this->adapter)
559
						->setLocale($this->locale)
560
						->setBootstrapFile($this->bootstrapFile)
561
					;
562

                    
563
					if ($this->debugMode === true)
564
					{
565
						$test->enableDebugMode();
566
					}
567

                    
568
					$test->setXdebugConfig($this->xdebugConfig);
569

                    
570
					if ($this->maxChildrenNumber !== null)
571
					{
572
						$test->setMaxChildrenNumber($this->maxChildrenNumber);
573
					}
574

                    
575
					if ($this->codeCoverageIsEnabled() === false)
576
					{
577
						$test->disableCodeCoverage();
578
					}
579
					else
580
					{
581
						if ($this->branchCoverageIsEnabled())
582
						{
583
							$test->enableBranchCoverage();
584
						}
585

                    
586
						$test->getScore()->setCoverage($this->getCoverage());
587
					}
588

                    
589
					foreach ($this->observers as $observer)
590
					{
591
						$test->addObserver($observer);
592
					}
593
				}
594
			}
595
		}
596

                    
597
		$this->start = $this->adapter->microtime(true);
598

                    
599
		$this->callObservers(self::runStart);
600

                    
601
		foreach ($tests as $test)
602
		{
603
			$this->score->merge($test->run()->getScore());
604
		}
605

                    
606
		$this->stop = $this->adapter->microtime(true);
607

                    
608
		$this->callObservers(self::runStop);
609

                    
610
		return $this->score;
611
	}
612

                    
613
	public function getTestPaths()100%
614
	{
615
		return $this->testPaths;
616
	}
617

                    
618
	public function setTestPaths(array $testPaths)100%
619
	{
620
		$this->testPaths = $testPaths;
621

                    
622
		return $this;
623
	}
624

                    
625
	public function resetTestPaths()100%
626
	{
627
		$this->testPaths = array();
628

                    
629
		return $this;
630
	}
631

                    
632
	public function canAddTest()100%
633
	{
634
		$this->canAddTest = true;
635

                    
636
		return $this;
637
	}
638

                    
639
	public function canNotAddTest()100%
640
	{
641
		$this->canAddTest = false;
642

                    
643
		return $this;
644
	}
645

                    
646
	public function addTest($path)100%
647
	{
648
		if ($this->canAddTest === true)
649
		{
650
			$path = (string) $path;
651

                    
652
			if (in_array($path, $this->testPaths) === false)
653
			{
654
				$this->testPaths[] = $path;
655
			}
656
		}
657

                    
658
		return $this;
659
	}
660

                    
661
	public function addTestsFromDirectory($directory)0%
662
	{
663
		try
664
		{
665
			$paths = array();
666

                    
667
			foreach (new \recursiveIteratorIterator($this->testDirectoryIterator->getIterator($directory)) as $path)
668
			{
669
				$paths[] = $path;
670
			}
671
		}
672
		catch (\UnexpectedValueException $exception)
673
		{
674
			throw new exceptions\runtime('Unable to read test directory \'' . $directory . '\'');
675
		}
676

                    
677
		natcasesort($paths);
678

                    
679
		foreach ($paths as $path)
680
		{
681
			$this->addTest($path);
682
		}
683

                    
684
		return $this;
685
	}
686

                    
687
	public function addTestsFromPattern($pattern)0%
688
	{
689
		try
690
		{
691
			$paths = array();
692

                    
693
			foreach (call_user_func($this->globIteratorFactory, rtrim($pattern, DIRECTORY_SEPARATOR)) as $path)
694
			{
695
				$paths[] = $path;
696
			}
697
		}
698
		catch (\UnexpectedValueException $exception)
699
		{
700
			throw new exceptions\runtime('Unable to read test from pattern \'' . $pattern . '\'');
701
		}
702

                    
703
		natcasesort($paths);
704

                    
705
		foreach ($paths as $path)
706
		{
707
			if ($path->isDir() === false)
708
			{
709
				$this->addTest($path);
710
			}
711
			else
712
			{
713
				$this->addTestsFromDirectory($path);
714
			}
715
		}
716

                    
717
		return $this;
718
	}
719

                    
720
	public function getRunningDuration()100%
721
	{
722
		return ($this->start === null || $this->stop === null ? null : $this->stop - $this->start);
723
	}
724

                    
725
	public function getDeclaredTestClasses($testBaseClass = null)100%
726
	{
727
		return $this->findTestClasses($testBaseClass);
728
	}
729

                    
730
	public function setReport(atoum\report $report)100%
731
	{
732
		if ($this->reportSet === null)
733
		{
734
			$this->removeReports()->addReport($report);
735

                    
736
			$this->reportSet = $report;
737
		}
738

                    
739
		return $this;
740
	}
741

                    
742
	public function addReport(atoum\report $report)100%
743
	{
744
		if ($this->reportSet === null || $this->reportSet->isOverridableBy($report))
745
		{
746
			$this->reports->attach($report);
747

                    
748
			$this->addObserver($report);
749
		}
750

                    
751
		return $this;
752
	}
753

                    
754
	public function removeReport(atoum\report $report)100%
755
	{
756
		if ($this->reportSet === $report)
757
		{
758
			$this->reportSet = null;
759
		}
760

                    
761
		$this->reports->detach($report);
762

                    
763
		return $this->removeObserver($report);
764
	}
765

                    
766
	public function removeReports()100%
767
	{
768
		foreach ($this->reports as $report)
769
		{
770
			$this->removeObserver($report);
771
		}
772

                    
773
		$this->reports = new \splObjectStorage();
774
		$this->reportSet = null;
775

                    
776
		return $this;
777
	}
778

                    
779
	public function hasReports()100%
780
	{
781
		return (sizeof($this->reports) > 0);
782
	}
783

                    
784
	public function getReports()100%
785
	{
786
		$reports = array();
787

                    
788
		foreach ($this->reports as $report)
789
		{
790
			$reports[] = $report;
791
		}
792

                    
793
		return $reports;
794
	}
795

                    
796
	public function getExtensions()100%
797
	{
798
		return iterator_to_array($this->extensions);
799
	}
800

                    
801
	public function removeExtension(atoum\extension $extension)100%
802
	{
803
		$this->extensions->detach($extension);
804

                    
805
		return $this->removeObserver($extension);
806
	}
807

                    
808
	public function removeExtensions()100%
809
	{
810
		foreach ($this->extensions as $extension)
811
		{
812
			$this->removeObserver($extension);
813
		}
814

                    
815
		$this->extensions = new \splObjectStorage();
816

                    
817
		return $this;
818
	}
819

                    
820

                    
821
	public function addExtension(atoum\extension $extension)100%
822
	{
823
		if ($this->extensions->contains($extension) === false)
824
		{
825
			$extension->setRunner($this);
826

                    
827
			$this->extensions->attach($extension);
828

                    
829
			$this->addObserver($extension);
830
		}
831

                    
832
		return $this;
833
	}
834

                    
835
	public static function isIgnored(test $test, array $namespaces, array $tags)0%
836
	{
837
		$isIgnored = $test->isIgnored();
838

                    
839
		if ($isIgnored === false && $namespaces)
840
		{
841
			$classNamespace = strtolower($test->getClassNamespace());
842

                    
843
			$isIgnored = sizeof(array_filter($namespaces, function($value) use ($classNamespace) { return strpos($classNamespace, strtolower($value)) === 0; })) <= 0;
844
		}
845

                    
846
		if ($isIgnored === false && $tags)
847
		{
848
			$isIgnored = sizeof($testTags = $test->getAllTags()) <= 0 || sizeof(array_intersect($tags, $testTags)) == 0;
849
		}
850

                    
851
		return $isIgnored;
852
	}
853

                    
854
	protected function findTestClasses($testBaseClass = null)100%
855
	{
856
		$reflectionClassFactory = $this->reflectionClassFactory;
857
		$testBaseClass = $testBaseClass ?: __NAMESPACE__ . '\test';
858

                    
859
		return array_filter($this->adapter->get_declared_classes(), function($class) use ($reflectionClassFactory, $testBaseClass) {
860
				$class = $reflectionClassFactory($class);
861

                    
862
				return ($class->isSubClassOf($testBaseClass) === true && $class->isAbstract() === false);
863
			}
864
		);
865
	}
866

                    
867
	private function includeTestPaths()22%
868
	{
869
		$runner = $this;
870
		$includer = function($path) use ($runner) { include_once($path); };
871

                    
872
		foreach ($this->testPaths as $testPath)
873
		{
874
			try
875
			{
876
				$declaredTestClasses = $this->findTestClasses();
877
				$numberOfIncludedFiles = sizeof(get_included_files());
878

                    
879
				$this->includer->includePath($testPath, $includer);
880

                    
881
				if ($numberOfIncludedFiles < sizeof(get_included_files()) && sizeof(array_diff($this->findTestClasses(), $declaredTestClasses)) <= 0 && $this->testGenerator !== null)
882
				{
883
					$this->testGenerator->generate($testPath);
884

                    
885
					try
886
					{
887
						$this->includer->includePath($testPath, function($testPath) use ($runner) { include($testPath); });
888
					}
889
					catch (atoum\includer\exception $exception)
890
					{
891
						throw new exceptions\runtime\file(sprintf($this->getLocale()->_('Unable to add test file \'%s\''), $testPath));
892
					}
893
				}
894
			}
895
			catch (atoum\includer\exception $exception)
896
			{
897
				if ($this->testGenerator === null)
898
				{
899
					throw new exceptions\runtime\file(sprintf($this->getLocale()->_('Unable to add test file \'%s\''), $testPath));
900
				}
901
				else
902
				{
903
					$this->testGenerator->generate($testPath);
904

                    
905
					try
906
					{
907
						$this->includer->includePath($testPath, $includer);
908
					}
909
					catch (atoum\includer\exception $exception)
910
					{
911
						throw new exceptions\runtime\file(sprintf($this->getLocale()->_('Unable to generate test file \'%s\''), $testPath));
912
					}
913
				}
914
			}
915
		}
916

                    
917
		return $this;
918
	}
919
}