mageekguy\atoum\scripts\runner: lines coverage

61% of 2758

OPs

59% of 746

Lines

37% of 307

Branches

1% of 4602

Paths
Method OPs OPs % Lines Line % Branches Branches % Paths Path %
mageekguy\atoum\scripts\runner::setInfoWriter() 31 100% 6 100% 4 100% 2 100%
mageekguy\atoum\scripts\runner::setWarningWriter() 45 100% 9 100% 4 100% 2 100%
mageekguy\atoum\scripts\runner::setErrorWriter() 39 100% 9 100% 4 100% 2 100%
mageekguy\atoum\scripts\runner::getResourcesDirectory() 7 100% 2 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::setRunner() 20 100% 2 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::getRunner() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::setConfiguratorFactory() 12 100% 3 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::getConfiguratorFactory() 6 0% 2 50% 1 0% 1 0%
mageekguy\atoum\scripts\runner::setDefaultReportFactory() 12 100% 6 83% 1 100% 1 100%
mageekguy\atoum\scripts\runner::getDefaultReportFactory() 6 0% 1 0% 1 0% 1 0%
mageekguy\atoum\scripts\runner::autorun() 32 100% 2 100% 7 100% 4 75%
mageekguy\atoum\scripts\runner::setScoreFile() 10 0% 3 33% 1 0% 1 0%
mageekguy\atoum\scripts\runner::getScoreFile() 6 100% 2 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::getArguments() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::setArguments() 9 100% 2 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::addDefaultArguments() 20 100% 2 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::hasDefaultArguments() 12 100% 2 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::getDefaultArguments() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::addTestAllDirectory() 14 100% 3 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::run() 65 72% 12 83% 11 45% 5 20%
mageekguy\atoum\scripts\runner::version() 32 0% 4 0% 1 0% 1 0%
mageekguy\atoum\scripts\runner::useConfigFile() 25 100% 3 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::testIt() 14 0% 2 0% 1 0% 1 0%
mageekguy\atoum\scripts\runner::enableLoopMode() 15 0% 5 0% 4 0% 2 0%
mageekguy\atoum\scripts\runner::disableLoopMode() 9 0% 2 0% 1 0% 1 0%
mageekguy\atoum\scripts\runner::testNamespaces() 23 43% 4 100% 6 67% 3 33%
mageekguy\atoum\scripts\runner::getTestedNamespaces() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::testTags() 9 0% 2 0% 1 0% 1 0%
mageekguy\atoum\scripts\runner::testMethod() 12 0% 2 0% 1 0% 1 0%
mageekguy\atoum\scripts\runner::addDefaultReport() 20 100% 3 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::addReport() 13 100% 2 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::setReport() 13 100% 2 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::getReports() 10 100% 1 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::setPhpPath() 13 100% 2 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::setDefaultReportTitle() 13 100% 2 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::setMaxChildrenNumber() 13 100% 2 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::disableCodeCoverage() 11 100% 2 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::enableBranchCoverage() 11 0% 2 0% 1 0% 1 0%
mageekguy\atoum\scripts\runner::excludeNamespacesFromCoverage() 26 65% 5 100% 6 50% 3 0%
mageekguy\atoum\scripts\runner::excludeDirectoriesFromCoverage() 26 65% 5 100% 6 50% 3 0%
mageekguy\atoum\scripts\runner::excludeClassesFromCoverage() 26 65% 5 100% 6 50% 3 0%
mageekguy\atoum\scripts\runner::excludeMethodsFromCoverage() 26 0% 5 0% 6 0% 3 0%
mageekguy\atoum\scripts\runner::addTest() 13 100% 2 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::addTests() 19 53% 4 100% 6 50% 3 0%
mageekguy\atoum\scripts\runner::addTestsFromDirectory() 13 100% 2 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::addTestsFromDirectories() 19 53% 4 100% 6 50% 3 0%
mageekguy\atoum\scripts\runner::addTestsFromPattern() 13 100% 2 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::addTestsFromPatterns() 19 53% 4 100% 6 50% 3 0%
mageekguy\atoum\scripts\runner::acceptTestFileExtensions() 13 100% 3 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::setBootstrapFile() 13 100% 2 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::enableDebugMode() 11 100% 2 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::setXdebugConfig() 13 100% 2 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::doNotfailIfVoidMethods() 11 100% 2 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::failIfVoidMethods() 11 100% 3 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::shouldFailIfVoidMethods() 10 100% 1 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::doNotfailIfSkippedMethods() 11 100% 3 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::failIfSkippedMethods() 11 100% 2 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::shouldFailIfSkippedMethods() 10 100% 1 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::init() 159 100% 21 100% 16 100% 32 13%
mageekguy\atoum\scripts\runner::setDefaultBootstrapFiles() 50 48% 9 78% 9 44% 4 0%
mageekguy\atoum\scripts\runner::autorunMustBeEnabled() 9 0% 1 0% 1 0% 1 0%
mageekguy\atoum\scripts\runner::enableAutorun() 71 0% 38 5% 7 0% 3 0%
mageekguy\atoum\scripts\runner::disableAutorun() 8 0% 3 33% 1 0% 1 0%
mageekguy\atoum\scripts\runner::runAgain() 17 0% 1 0% 1 0% 1 0%
mageekguy\atoum\scripts\runner::loop() 197 0% 43 0% 47 0% 360 0%
mageekguy\atoum\scripts\runner::saveScore() 41 0% 4 0% 7 0% 4 0%
mageekguy\atoum\scripts\runner::writeHelpUsage() 29 100% 2 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::parseArguments() 40 100% 5 100% 1 100% 1 100%
mageekguy\atoum\scripts\runner::getClassesOf() 27 0% 1 0% 8 0% 4 0%
mageekguy\atoum\scripts\runner::copy() 39 97% 4 100% 4 75% 2 100%
mageekguy\atoum\scripts\runner::getFailMethods() 43 0% 1 0% 1 0% 1 0%
mageekguy\atoum\scripts\runner::mergeMethods() 39 0% 8 0% 10 0% 4 0%
mageekguy\atoum\scripts\runner::doRun() 440 17% 60 22% 65 11% 4096 0%
mageekguy\atoum\scripts\runner::__construct() 26 100% 7 100% 1 0% 1 100%
mageekguy\atoum\scripts\runner::setArgumentHandlers() 583 100% 365 65% 1 100% 1 100%
#
1
<?php
2

                    
3
namespace mageekguy\atoum\scripts;
4

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

                    
7
use
8
	mageekguy\atoum,
9
	mageekguy\atoum\cli,
10
	mageekguy\atoum\php,
11
	mageekguy\atoum\writers,
12
	mageekguy\atoum\exceptions
13
;
14

                    
15
class runner extends atoum\script\configurable
16
{
17
	const defaultConfigFile = '.atoum.php';
18
	const defaultBootstrapFile = '.bootstrap.atoum.php';
19

                    
20
	protected $runner = null;
21
	protected $configuratorFactory = null;
22
	protected $defaultReportFactory = null;
23
	protected $scoreFile = null;
24
	protected $arguments = array();
25
	protected $defaultArguments = array();
26
	protected $namespaces = array();
27
	protected $tags = array();
28
	protected $methods = array();
29
	protected $loop = false;
30

                    
31
	protected static $autorunner = true;
32
	protected static $runnerFile = null;
33

                    
34
	public function __construct($name, atoum\adapter $adapter = null)
35
	{
36
		parent::__construct($name, $adapter);
37

                    
38
		$this
39
			->setRunner()
40
			->setConfiguratorFactory()
41
			->setDefaultReportFactory()
42
		;
43
	}
44

                    
45
	public function setInfoWriter(atoum\writer $writer = null)100%
46
	{
47
		parent::setInfoWriter($writer);
48

                    
49
		if ($writer === null)
50
		{
51
			$this->infoWriter->addDecorator(new cli\colorizer('0;32'));
52
		}
53

                    
54
		return $this;
55
	}
56

                    
57
	public function setWarningWriter(atoum\writer $writer = null)100%
58
	{
59
		if ($writer === null)
60
		{
61
			$writer = new writers\std\err();
62

                    
63
			$colorizer = new cli\colorizer('0;33');
64
			$colorizer->setPattern('/^([^:]+:)/');
65

                    
66
			$writer->addDecorator($colorizer);
67
		}
68

                    
69
		parent::setWarningWriter($writer);
70

                    
71
		return $this;
72
	}
73

                    
74
	public function setErrorWriter(atoum\writer $writer = null)100%
75
	{
76
		parent::setErrorWriter($writer);
77

                    
78
		if ($writer === null)
79
		{
80
			$colorizer = new cli\colorizer('0;31');
81
			$colorizer->setPattern('/^([^:]+:)/');
82

                    
83
			$this->errorWriter->addDecorator($colorizer);
84
		}
85

                    
86
		return $this;
87
	}
88

                    
89
	public function getResourcesDirectory()
90
	{
91
		return atoum\directory . '/resources';
92
	}
93

                    
94
	public function setRunner(atoum\runner $runner = null)100%
95
	{
96
		$this->runner = $runner ?: new atoum\runner();
97

                    
98
		return $this->setArgumentHandlers();
99
	}
100

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

                    
106
	public function setConfiguratorFactory(\closure $factory = null)
107
	{
108
		$this->configuratorFactory = $factory ?: function($test) { return new atoum\configurator($test); };
109

                    
110
		return $this;
111
	}
112

                    
113
	public function getConfiguratorFactory()
114
	{
115
		return $this->configuratorFactory;
116
	}
117

                    
118
	public function setDefaultReportFactory(\closure $factory = null)83%
119
	{
120
		$this->defaultReportFactory = $factory ?: function($script) {
121
			$report = new atoum\reports\realtime\cli();
122
			$report->addWriter($script->getOutputWriter());
123

                    
124
			return $report;
125
		};
126

                    
127
		return $this;
128
	}
129

                    
130
	public function getDefaultReportFactory()0%
131
	{
132
		return $this->defaultReportFactory;
133
	}
134

                    
135
	public function autorun()100%
136
	{
137
		return (isset($_SERVER['argv']) === false || isset($_SERVER['argv'][0]) === false || $this->adapter->realpath($_SERVER['argv'][0]) !== $this->getName());
138
	}
139

                    
140
	public function setScoreFile($path)33%
141
	{
142
		$this->scoreFile = (string) $path;
143

                    
144
		return $this;
145
	}
146

                    
147
	public function getScoreFile()
148
	{
149
		return $this->scoreFile;
150
	}
151

                    
152
	public function getArguments()100%
153
	{
154
		return $this->arguments;
155
	}
156

                    
157
	public function setArguments(array $arguments)100%
158
	{
159
		$this->arguments = $arguments;
160

                    
161
		return $this;
162
	}
163

                    
164
	public function addDefaultArguments($argument)100%
165
	{
166
		$this->defaultArguments = array_merge($this->defaultArguments, func_get_args());
167

                    
168
		return $this;
169
	}
170

                    
171
	public function hasDefaultArguments()100%
172
	{
173
		return (sizeof($this->defaultArguments) > 0);
174
	}
175

                    
176
	public function getDefaultArguments()100%
177
	{
178
		return $this->defaultArguments;
179
	}
180

                    
181
	public function addTestAllDirectory($directory)
182
	{
183
		$this->writeError('--test-all argument is deprecated, please replace call to ' . __METHOD__ . '(\'path/to/default/tests/directory\') by $runner->addTestsFromDirectory(\'path/to/default/tests/directory\') in your configuration files and use atoum without any argument instead');
184

                    
185
		return $this;
186
	}
187

                    
188
	public function run(array $arguments = array())83%
189
	{
190
		# Default bootstrap file MUST be included here because some arguments on the command line can include some tests which depends of this file.
191
		# So, this file must be included BEFORE argument parsing which is done in script::run().
192
		# Default bootstrap file can be overrided in a default config file included in script\configurable::run() which extends script::run().
193
		# So, if a bootstrap file is defined in a default config file, it will be available when arguments on CLI will be parsed
194
		$this->setDefaultBootstrapFiles();
195

                    
196
		if ($this->autorun() === true && sizeof($this->runner->getDeclaredTestClasses()) > 0)
197
		{
198
			$this->runner->canNotAddTest();
199
		}
200

                    
201
		try
202
		{
203
			parent::run($arguments ?: $this->getArguments());
204
		}
205
		catch (atoum\exception $exception)
206
		{
207
			$this->writeError($exception->getMessage());
208
		}
209

                    
210
		return $this;
211
	}
212

                    
213
	public function version()0%
214
	{
215
		$this
216
			->writeInfo(sprintf($this->locale->_('atoum version %s by %s (%s)'), atoum\version, atoum\author, atoum\directory))
217
			->stopRun()
218
		;
219

                    
220
		return $this;
221
	}
222

                    
223
	public function useConfigFile($path)100%
224
	{
225
		$script = call_user_func($this->configuratorFactory, $this);
226
		$runner = $this->runner;
227

                    
228
		return $this->includeConfigFile($path, function($path) use ($script, $runner) { include_once($path); });
229
	}
230

                    
231
	public function testIt()0%
232
	{
233
		$this->runner->addTestsFromDirectory(atoum\directory . '/tests/units/classes');
234

                    
235
		return $this;
236
	}
237

                    
238
	public function enableLoopMode()0%
239
	{
240
		if ($this->loop !== null)
241
		{
242
			$this->loop = true;
243
		}
244

                    
245
		return $this;
246
	}
247

                    
248
	public function disableLoopMode()0%
249
	{
250
		$this->loop = null;
251

                    
252
		return $this;
253
	}
254

                    
255
	public function testNamespaces(array $namespaces)100%
256
	{
257
		foreach ($namespaces as $namespace)
258
		{
259
			$this->namespaces[] = trim($namespace, '\\');
260
		}
261

                    
262
		return $this;
263
	}
264

                    
265
	public function getTestedNamespaces()100%
266
	{
267
		return $this->namespaces;
268
	}
269

                    
270
	public function testTags(array $tags)0%
271
	{
272
		$this->tags = $tags;
273

                    
274
		return $this;
275
	}
276

                    
277
	public function testMethod($class, $method)0%
278
	{
279
		$this->methods[$class][] = $method;
280

                    
281
		return $this;
282
	}
283

                    
284
	public function addDefaultReport()100%
285
	{
286
		$report = call_user_func($this->defaultReportFactory, $this);
287

                    
288
		$this->addReport($report);
289

                    
290
		return $report;
291
	}
292

                    
293
	public function addReport(atoum\report $report)100%
294
	{
295
		$this->runner->addReport($report);
296

                    
297
		return $this;
298
	}
299

                    
300
	public function setReport(atoum\report $report)100%
301
	{
302
		$this->runner->setReport($report);
303

                    
304
		return $this;
305
	}
306

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

                    
312
	public function setPhpPath($phpPath)100%
313
	{
314
		$this->runner->setPhpPath($phpPath);
315

                    
316
		return $this;
317
	}
318

                    
319
	public function setDefaultReportTitle($reportTitle)100%
320
	{
321
		$this->runner->setDefaultReportTitle($reportTitle);
322

                    
323
		return $this;
324
	}
325

                    
326
	public function setMaxChildrenNumber($childrenNumber)100%
327
	{
328
		$this->runner->setMaxChildrenNumber($childrenNumber);
329

                    
330
		return $this;
331
	}
332

                    
333
	public function disableCodeCoverage()100%
334
	{
335
		$this->runner->disableCodeCoverage();
336

                    
337
		return $this;
338
	}
339

                    
340
	public function enableBranchCoverage()0%
341
	{
342
		$this->runner->enableBranchCoverage();
343

                    
344
		return $this;
345
	}
346

                    
347
	public function excludeNamespacesFromCoverage(array $namespaces)100%
348
	{
349
		$coverage = $this->runner->getCoverage();
350

                    
351
		foreach ($namespaces as $namespace)
352
		{
353
			$coverage->excludeNamespace($namespace);
354
		}
355

                    
356
		return $this;
357
	}
358

                    
359
	public function excludeDirectoriesFromCoverage(array $directories)100%
360
	{
361
		$coverage = $this->runner->getCoverage();
362

                    
363
		foreach ($directories as $directory)
364
		{
365
			$coverage->excludeDirectory($directory);
366
		}
367

                    
368
		return $this;
369
	}
370

                    
371
	public function excludeClassesFromCoverage(array $classes)100%
372
	{
373
		$coverage = $this->runner->getCoverage();
374

                    
375
		foreach ($classes as $class)
376
		{
377
			$coverage->excludeClass($class);
378
		}
379

                    
380
		return $this;
381
	}
382

                    
383
	public function excludeMethodsFromCoverage(array $methods)0%
384
	{
385
		$coverage = $this->runner->getCoverage();
386

                    
387
		foreach ($methods as $method)
388
		{
389
			$coverage->excludeMethod($method);
390
		}
391

                    
392
		return $this;
393
	}
394

                    
395
	public function addTest($testPath)100%
396
	{
397
		$this->runner->addTest($testPath);
398

                    
399
		return $this;
400
	}
401

                    
402
	public function addTests(array $testPaths)100%
403
	{
404
		foreach ($testPaths as $testPath)
405
		{
406
			$this->addTest($testPath);
407
		}
408

                    
409
		return $this;
410
	}
411

                    
412
	public function addTestsFromDirectory($directory)100%
413
	{
414
		$this->runner->addTestsFromDirectory($directory);
415

                    
416
		return $this;
417
	}
418

                    
419
	public function addTestsFromDirectories(array $directories)100%
420
	{
421
		foreach ($directories as $directory)
422
		{
423
			$this->addTestsFromDirectory($directory);
424
		}
425

                    
426
		return $this;
427
	}
428

                    
429
	public function addTestsFromPattern($pattern)100%
430
	{
431
		$this->runner->addTestsFromPattern($pattern);
432

                    
433
		return $this;
434
	}
435

                    
436
	public function addTestsFromPatterns(array $patterns)100%
437
	{
438
		foreach ($patterns as $pattern)
439
		{
440
			$this->addTestsFromPattern($pattern);
441
		}
442

                    
443
		return $this;
444
	}
445

                    
446
	public function acceptTestFileExtensions(array $testFileExtensions)100%
447
	{
448
		$this->runner->acceptTestFileExtensions($testFileExtensions);
449

                    
450
		return $this;
451
	}
452

                    
453
	public function setBootstrapFile($bootstrapFile)100%
454
	{
455
		$this->runner->setBootstrapFile($bootstrapFile);
456

                    
457
		return $this;
458
	}
459

                    
460
	public function enableDebugMode()100%
461
	{
462
		$this->runner->enableDebugMode();
463

                    
464
		return $this;
465
	}
466

                    
467
	public function setXdebugConfig($xdebugConfig)100%
468
	{
469
		$this->runner->setXdebugConfig($xdebugConfig);
470

                    
471
		return $this;
472
	}
473

                    
474
	public function doNotfailIfVoidMethods()100%
475
	{
476
		$this->runner->doNotfailIfVoidMethods();
477

                    
478
		return $this;
479
	}
480

                    
481
	public function failIfVoidMethods()
482
	{
483
		$this->runner->failIfVoidMethods();
484

                    
485
		return $this;
486
	}
487

                    
488
	public function shouldFailIfVoidMethods()100%
489
	{
490
		return $this->runner->shouldFailIfVoidMethods();
491
	}
492

                    
493
	public function doNotfailIfSkippedMethods()100%
494
	{
495
		$this->runner->doNotfailIfSkippedMethods();
496

                    
497
		return $this;
498
	}
499

                    
500
	public function failIfSkippedMethods()100%
501
	{
502
		$this->runner->failIfSkippedMethods();
503

                    
504
		return $this;
505
	}
506

                    
507
	public function shouldFailIfSkippedMethods()100%
508
	{
509
		return $this->runner->shouldFailIfSkippedMethods();
510
	}
511

                    
512
	public function init($directory = null)100%
513
	{
514
		$resourceDirectory = static::getResourcesDirectory();
515
		$currentDirectory = $this->getDirectory();
516

                    
517
		if ($directory !== null)
518
		{
519
			$currentDirectory = rtrim($directory, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
520
		}
521

                    
522
		$defaultConfigFile = $currentDirectory . static::defaultConfigFile;
523

                    
524
		if ($this->adapter->file_exists($defaultConfigFile) === false || $this->prompt($this->locale->_('Default configuration file \'' . static::defaultConfigFile . '\' already exists in ' . $currentDirectory . ', type \'Y\' to overwrite it...')) === 'Y')
525
		{
526
			$this
527
				->copy($resourceDirectory . '/configurations/runner/atoum.php.dist', $defaultConfigFile)
528
				->writeInfo($this->locale->_('Default configuration file \'' . static::defaultConfigFile . '\' was successfully created in ' . $currentDirectory))
529
			;
530
		}
531

                    
532
		$bootstrapFile = $currentDirectory . static::defaultBootstrapFile;
533

                    
534
		if ($this->adapter->file_exists($bootstrapFile) == false || $this->prompt($this->locale->_('Default bootstrap file \'' . static::defaultBootstrapFile . '\' already exists in ' . $currentDirectory . ', type \'Y\' to overwrite it...')) === 'Y')
535
		{
536
			$this
537
				->copy($resourceDirectory . '/configurations/runner/bootstrap.php.dist', $bootstrapFile)
538
				->writeInfo($this->locale->_('Default bootstrap file \'' . static::defaultBootstrapFile . '\' was successfully created in ' . $currentDirectory))
539
			;
540
		}
541

                    
542
		return $this->stopRun();
543
	}
544

                    
545
	public function setDefaultBootstrapFiles($startDirectory = null)78%
546
	{
547
		foreach (self::getSubDirectoryPath($startDirectory ?: $this->getDirectory()) as $directory)
548
		{
549
			$defaultBootstrapFile = $directory . static::defaultBootstrapFile;
550

                    
551
			if ($this->adapter->is_file($defaultBootstrapFile) === true)
552
			{
553
				$this->setBootstrapFile($defaultBootstrapFile);
554

                    
555
				break;
556
			}
557
		}
558

                    
559
		return $this;
560
	}
561

                    
562
	public static function autorunMustBeEnabled()0%
563
	{
564
		return (static::$autorunner === true);
565
	}
566

                    
567
	public static function enableAutorun($name)5%
568
	{
569
		static $autorunIsRegistered = false;
570

                    
571
		if (static::$autorunner instanceof static)
572
		{
573
			throw new exceptions\runtime('Unable to autorun \'' . $name . '\' because \'' . static::$autorunner->getName() . '\' is already set as autorunner');
574
		}
575

                    
576
		if ($autorunIsRegistered === false)
577
		{
578
			$autorunner = & static::$autorunner;
579
			$calledClass = get_called_class();
580

                    
581
			register_shutdown_function(function() use (& $autorunner, $calledClass) {
582
					if ($autorunner instanceof $calledClass)
583
					{
584
						set_error_handler(function($error, $message, $file, $line) use ($autorunner) {
585
								if (error_reporting() !== 0)
586
								{
587
									$autorunner->writeError($message . ' in ' . $file . ' at line ' . $line, $error);
588

                    
589
									exit(3);
590
								}
591
							}
592
						);
593

                    
594
						try
595
						{
596
							$score = $autorunner->run()->getRunner()->getScore();
597

                    
598
							$isSuccess = $score->getFailNumber() <= 0 && $score->getErrorNumber() <= 0 && $score->getExceptionNumber() <= 0;
599

                    
600
							if ($autorunner->shouldFailIfVoidMethods() && $score->getVoidMethodNumber() > 0)
601
							{
602
								$isSuccess = false;
603
							}
604

                    
605
							if ($autorunner->shouldFailIfSkippedMethods() && $score->getSkippedMethodNumber() > 0)
606
							{
607
								$isSuccess = false;
608
							}
609

                    
610
							exit($isSuccess ? 0 : 1);
611
						}
612
						catch (\exception $exception)
613
						{
614
							$autorunner->writeError($exception->getMessage());
615

                    
616
							exit(2);
617
						}
618
					}
619
				}
620
			);
621

                    
622
			$autorunIsRegistered = true;
623
		}
624

                    
625
		static::$autorunner = new static($name);
626

                    
627
		return static::$autorunner;
628
	}
629

                    
630
	public static function disableAutorun()33%
631
	{
632
		static::$autorunner = false;
633
	}
634

                    
635
	protected function setArgumentHandlers()65%
636
	{
637
		parent::setArgumentHandlers()
638
			->addArgumentHandler(
639
					function($script, $argument, $values) {
640
						if (sizeof($values) !== 0)
641
						{
642
							throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName()));
643
						}
644

                    
645
						$script->version();
646
					},
647
					array('-v', '--version'),
648
					null,
649
					$this->locale->_('Display version')
650
				)
651
			->addArgumentHandler(
652
					function($script, $argument, $values) {
653
						if (sizeof($values) !== 0)
654
						{
655
							throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName()));
656
						}
657

                    
658
						$script->resetVerbosityLevel();
659

                    
660
						$verbosityLevel = substr_count($argument, '+');
661

                    
662
						while ($verbosityLevel--)
663
						{
664
							$script->increaseVerbosityLevel();
665
						}
666
					},
667
					array('+verbose', '++verbose'),
668
					null,
669
					$this->locale->_('Enable verbose mode')
670
				)
671
			->addArgumentHandler(
672
					function($script, $argument, $values) {
673
						if (sizeof($values) === 0)
674
						{
675
							$values = array(getcwd());
676
						}
677

                    
678
						$script->init(current($values));
679
					},
680
					array('--init'),
681
					'<path/to/directory>',
682
					sprintf($this->locale->_('Create configuration and bootstrap files in <path/to/directory> (Optional, default: %s)'), $this->getDirectory())
683
				)
684
			->addArgumentHandler(
685
					function($script, $argument, $path) {
686
						if (sizeof($path) != 1)
687
						{
688
							throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName()));
689
						}
690

                    
691
						$script->setPhpPath(reset($path));
692
					},
693
					array('-p', '--php'),
694
					'<path/to/php/binary>',
695
					$this->locale->_('Path to PHP binary which must be used to run tests')
696
				)
697
			->addArgumentHandler(
698
					function($script, $argument, $defaultReportTitle) {
699
						if (sizeof($defaultReportTitle) != 1)
700
						{
701
							throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName()));
702
						}
703

                    
704
						$script->setDefaultReportTitle(reset($defaultReportTitle));
705
					},
706
					array('-drt', '--default-report-title'),
707
					'<string>',
708
					$this->locale->_('Define default report title with <string>')
709
				)
710
			->addArgumentHandler(
711
					function($script, $argument, $file) {
712
						if (sizeof($file) != 1)
713
						{
714
							throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName()));
715
						}
716

                    
717
						$script->setScoreFile(reset($file));
718
					},
719
					array('-sf', '--score-file'),
720
					'<file>',
721
					$this->locale->_('Save score in file <file>')
722
				)
723
			->addArgumentHandler(
724
					function($script, $argument, $maxChildrenNumber) {
725
						if (sizeof($maxChildrenNumber) != 1)
726
						{
727
							throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName()));
728
						}
729

                    
730
						$script->setMaxChildrenNumber(reset($maxChildrenNumber));
731
					},
732
					array('-mcn', '--max-children-number'),
733
					'<integer>',
734
					$this->locale->_('Maximum number of sub-processus which will be run simultaneously')
735
				)
736
			->addArgumentHandler(
737
					function($script, $argument, $empty) {
738
						if ($empty)
739
						{
740
							throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName()));
741
						}
742

                    
743
						$script->disableCodeCoverage();
744
					},
745
					array('-ncc', '--no-code-coverage'),
746
					null,
747
					$this->locale->_('Disable code coverage')
748
				)
749
			->addArgumentHandler(
750
					function($script, $argument, $directories) {
751
						if (sizeof($directories) <= 0)
752
						{
753
							throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName()));
754
						}
755

                    
756
						$script->excludeDirectoriesFromCoverage($directories);
757
					},
758
					array('-nccid', '--no-code-coverage-in-directories'),
759
					'<directory>...',
760
					$this->locale->_('Disable code coverage in directories <directory>')
761
				)
762
			->addArgumentHandler(
763
					function($script, $argument, $namespaces) {
764
						if (sizeof($namespaces) <= 0)
765
						{
766
							throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName()));
767
						}
768

                    
769
						$script->excludeNamespacesFromCoverage($namespaces);
770
					},
771
					array('-nccfns', '--no-code-coverage-for-namespaces'),
772
					'<namespace>...',
773
					$this->locale->_('Disable code coverage for namespaces <namespace>')
774
				)
775
			->addArgumentHandler(
776
					function($script, $argument, $classes) {
777
						if (sizeof($classes) <= 0)
778
						{
779
							throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName()));
780
						}
781

                    
782
						$script->excludeClassesFromCoverage($classes);
783
					},
784
					array('-nccfc', '--no-code-coverage-for-classes'),
785
					'<class>...',
786
					$this->locale->_('Disable code coverage for classes <class>')
787
				)
788
			->addArgumentHandler(
789
					function($script, $argument, $classes) {
790
						if (sizeof($classes) <= 0)
791
						{
792
							throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName()));
793
						}
794

                    
795
						$script->excludeMethodsFromCoverage($classes);
796
					},
797
					array('-nccfm', '--no-code-coverage-for-methods'),
798
					'<method>...',
799
					$this->locale->_('Disable code coverage for methods <method>')
800
				)
801
			->addArgumentHandler(
802
					function($script, $argument, $empty) {
803
						if ($empty)
804
						{
805
							throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName()));
806
						}
807

                    
808
						$script->enableBranchCoverage();
809
					},
810
					array('-ebpc', '--enable-branch-and-path-coverage'),
811
					null,
812
					$this->locale->_('Enable branch and path coverage')
813
				)
814
			->addArgumentHandler(
815
					function($script, $argument, $files) {
816
						if (sizeof($files) <= 0)
817
						{
818
							throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName()));
819
						}
820

                    
821
						$script->addTests($files);
822
					},
823
					array('-f', '--files'),
824
					'<file>...',
825
					$this->locale->_('Execute all unit test files <file>')
826
				)
827
			->addArgumentHandler(
828
					function($script, $argument, $directories) {
829
						if (sizeof($directories) <= 0)
830
						{
831
							throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName()));
832
						}
833

                    
834
						$script->addTestsFromDirectories($directories);
835
					},
836
					array('-d', '--directories'),
837
					'<directory>...',
838
					$this->locale->_('Execute unit test files in all <directory>')
839
				)
840
			->addArgumentHandler(
841
					function($script, $argument, $extensions) {
842
						if (sizeof($extensions) <= 0)
843
						{
844
							throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName()));
845
						}
846

                    
847
						$script->acceptTestFileExtensions($extensions);
848
					},
849
					array('-tfe', '--test-file-extensions'),
850
					'<extension>...',
851
					$this->locale->_('Execute unit test files with one of extensions <extension>')
852
				)
853
			->addArgumentHandler(
854
					function($script, $argument, $patterns) {
855
						if (sizeof($patterns) <= 0)
856
						{
857
							throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName()));
858
						}
859

                    
860
						$script->addTestsFromPatterns($patterns);
861
					},
862
					array('-g', '--glob'),
863
					'<pattern>...',
864
					$this->locale->_('Execute unit test files which match <pattern>')
865
				)
866
			->addArgumentHandler(
867
					function($script, $argument, $tags) {
868
						if (sizeof($tags) <= 0)
869
						{
870
							throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName()));
871
						}
872

                    
873
						$script->testTags($tags);
874
					},
875
					array('-t', '--tags'),
876
					'<tag>...',
877
					$this->locale->_('Execute only unit test with tags <tag>')
878
				)
879
			->addArgumentHandler(
880
					function($script, $argument, $methods) {
881
						if (sizeof($methods) <= 0)
882
						{
883
							throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName()));
884
						}
885

                    
886
						foreach ($methods as $method)
887
						{
888
							$method = explode('::', $method);
889

                    
890
							if (sizeof($method) != 2)
891
							{
892
								throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName()));
893
							}
894

                    
895
							$script->testMethod($method[0], $method[1]);
896
						}
897
					},
898
					array('-m', '--methods'),
899
					'<class::method>...',
900
					$this->locale->_('Execute all <class::method>, * may be used as wildcard for class name or method name')
901
				)
902
			->addArgumentHandler(
903
					function($script, $argument, $namespaces) {
904
						if (sizeof($namespaces) <= 0)
905
						{
906
							throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName()));
907
						}
908

                    
909
						$script->testNamespaces($namespaces);
910
					},
911
					array('-ns', '--namespaces'),
912
					'<namespace>...',
913
					$this->locale->_('Execute all classes in all namespaces <namespace>')
914
				)
915
			->addArgumentHandler(
916
					function($script, $argument, $values) {
917
						if ($values)
918
						{
919
							throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName()));
920
						}
921

                    
922
						$script->enableLoopMode();
923
					},
924
					array('-l', '--loop'),
925
					null,
926
					$this->locale->_('Execute tests in an infinite loop')
927
				)
928
			->addArgumentHandler(
929
					function($script, $argument, $values) {
930
						if (sizeof($values) !== 0)
931
						{
932
							throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName()));
933
						}
934

                    
935
						$script->disableLoopMode();
936
					},
937
					array('--disable-loop-mode'),
938
					null,
939
					null,
940
					3
941
				)
942
			->addArgumentHandler(
943
					function($script, $argument, $values) {
944
						if (sizeof($values) !== 0)
945
						{
946
							throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName()));
947
						}
948

                    
949
						$script->testIt();
950
					},
951
					array('--test-it'),
952
					null,
953
					$this->locale->_('Execute atoum unit tests')
954
				)
955
			->addArgumentHandler(
956
					function($script, $argument, $values) {
957
						$script->writeError('--test-all argument is deprecated, please do $runner->addTestsFromDirectory(\'path/to/default/tests/directory\') in a configuration file and use atoum without any argument instead');
958
					},
959
					array('--test-all'),
960
					null,
961
					$this->locale->_('DEPRECATED, please do $runner->addTestsFromDirectory(\'path/to/default/tests/directory\') in a configuration file and use atoum without any argument instead')
962
				)
963
			->addArgumentHandler(
964
					function($script, $argument, $values) {
965
						if ($values)
966
						{
967
							throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName()));
968
						}
969

                    
970
						\mageekguy\atoum\cli::forceTerminal();
971
					},
972
					array('-ft', '--force-terminal'),
973
					null,
974
					$this->locale->_('Force output as in terminal')
975
				)
976
			->addArgumentHandler(
977
					function($script, $argument, $values) {
978
						if (sizeof($values) != 1)
979
						{
980
							throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName()));
981
						}
982

                    
983
						$script->setBootstrapFile($values[0]);
984
					},
985
					array('-bf', '--bootstrap-file'),
986
					'<file>',
987
					$this->locale->_('Include <file> before executing each test method'),
988
					2
989
				)
990
			->addArgumentHandler(
991
					function($script, $argument, $values) {
992
						if (sizeof($values) != 0)
993
						{
994
							throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName()));
995
						}
996

                    
997
						$lightReport = new atoum\reports\realtime\cli\light();
998
						$lightReport->addWriter($script->getOutputWriter());
999

                    
1000
						$script->setReport($lightReport);
1001
					},
1002
					array('-ulr', '--use-light-report'),
1003
					null,
1004
					$this->locale->_('Use "light" CLI report'),
1005
					PHP_INT_MAX
1006
				)
1007
			->addArgumentHandler(
1008
					function($script, $argument, $values) {
1009
						if (sizeof($values) != 0)
1010
						{
1011
							throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName()));
1012
						}
1013

                    
1014
						$tapReport = new atoum\reports\realtime\tap();
1015
						$tapReport->addWriter($script->getOutputWriter());
1016

                    
1017
						$script->setReport($tapReport);
1018
					},
1019
					array('-utr', '--use-tap-report'),
1020
					null,
1021
					$this->locale->_('Use TAP report'),
1022
					PHP_INT_MAX
1023
				)
1024
			->addArgumentHandler(
1025
					function($script, $argument, $values) {
1026
						if (sizeof($values) != 0)
1027
						{
1028
							throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName()));
1029
						}
1030

                    
1031
						$script->enableDebugMode();
1032
					},
1033
					array('--debug'),
1034
					null,
1035
					$this->locale->_('Enable debug mode')
1036
				)
1037
			->addArgumentHandler(
1038
					function($script, $argument, $values) {
1039
						if (sizeof($values) != 1)
1040
						{
1041
							throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName()));
1042
						}
1043

                    
1044
						$script->setXdebugConfig($values[0]);
1045
					},
1046
					array('-xc', '--xdebug-config'),
1047
					null,
1048
					$this->locale->_('Set XDEBUG_CONFIG variable')
1049
				)
1050
			->addArgumentHandler(
1051
					function($script, $argument, $values) {
1052
						$script->failIfVoidMethods();
1053
					},
1054
					array('-fivm', '--fail-if-void-methods'),
1055
					null,
1056
					$this->locale->_('Make the test suite fail if there is at least one void test method')
1057
				)
1058
			->addArgumentHandler(
1059
					function($script, $argument, $values) {
1060
						$script->failIfSkippedMethods();
1061
					},
1062
					array('-fism', '--fail-if-skipped-methods'),
1063
					null,
1064
					$this->locale->_('Make the test suite fail if there is at least one skipped test method')
1065
				)
1066
		;
1067

                    
1068
		$this->setDefaultArgumentHandler(function($script, $argument) {
1069
				try
1070
				{
1071
					$script->getRunner()->addTest($argument);
1072
				}
1073
				catch (\exception $exception)
1074
				{
1075
					return false;
1076
				}
1077

                    
1078
				return true;
1079
			}
1080
		);
1081

                    
1082
		return $this;
1083
	}
1084

                    
1085
	protected function doRun()22%
1086
	{
1087
		parent::doRun();
1088

                    
1089
		if ($this->argumentsParser->hasFoundArguments() === false)
1090
		{
1091
			$this->argumentsParser->parse($this, $this->defaultArguments);
1092
		}
1093

                    
1094
		if (sizeof($this->runner->getTestPaths()) <= 0 && sizeof($this->runner->getDeclaredTestClasses()) <= 0)
1095
		{
1096
			$this->writeError($this->locale->_('No test found'))->help();
1097
		}
1098
		else
1099
		{
1100
			$arguments = $this->argumentsParser->getValues();
1101

                    
1102
			if (sizeof($arguments) <= 0)
1103
			{
1104
				$this->verbose(sprintf($this->locale->_('Using no CLI argument…')));
1105
			}
1106
			else
1107
			{
1108
				$this->verbose(sprintf($this->locale->__('Using %s CLI argument…', 'Using %s arguments…', sizeof($arguments)), $this->argumentsParser));
1109
			}
1110

                    
1111
			if (sizeof($this->configFiles) > 0)
1112
			{
1113
				foreach ($this->configFiles as $configFile)
1114
				{
1115
					$this->verbose(sprintf($this->locale->_('Using \'%s\' configuration file…'), $configFile));
1116
				}
1117
			}
1118

                    
1119
			$bootstrapFile = $this->runner->getBootstrapFile();
1120

                    
1121
			if ($bootstrapFile !== null)
1122
			{
1123
				$this->verbose(sprintf($this->locale->_('Using \'%s\' bootstrap file…'), $bootstrapFile));
1124
			}
1125

                    
1126
			foreach (atoum\autoloader::getRegisteredAutoloaders() as $autoloader)
1127
			{
1128
				$this->verbose(sprintf($this->locale->_('Using \'%s\' autoloader cache file…'), $autoloader->getCacheFileForInstance()));
1129
			}
1130

                    
1131
			foreach ($this->runner->getTestPaths() as $testPath)
1132
			{
1133
				$this->verbose(sprintf($this->locale->_('Using \'%s\' test file…'), $testPath), 2);
1134
			}
1135

                    
1136
			if ($this->loop === true)
1137
			{
1138
				$this->loop();
1139
			}
1140
			else
1141
			{
1142
				if ($this->runner->hasReports() === false)
1143
				{
1144
					$this->addDefaultReport();
1145
				}
1146

                    
1147
				$methods = $this->methods;
1148
				$oldFailMethods = array();
1149

                    
1150
				if ($this->scoreFile !== null && ($scoreFileContents = @file_get_contents($this->scoreFile)) !== false && ($oldScore = @unserialize($scoreFileContents)) instanceof atoum\score)
1151
				{
1152
					$oldFailMethods = self::getFailMethods($oldScore);
1153

                    
1154
					if ($oldFailMethods)
1155
					{
1156
						$methods = $oldFailMethods;
1157
					}
1158
				}
1159

                    
1160
				$newScore = $this->runner->run($this->namespaces, $this->tags, $this->getClassesOf($methods), $methods);
1161

                    
1162
				$this->saveScore($newScore);
1163

                    
1164
				if ($oldFailMethods && sizeof(self::getFailMethods($newScore)) <= 0)
1165
				{
1166
					$testMethods = $this->runner->getTestMethods($this->namespaces, $this->tags, $this->methods);
1167

                    
1168
					if (sizeof($testMethods) > 1 || sizeof(current($testMethods)) > 1)
1169
					{
1170
						$this->saveScore($this->runner->run($this->namespaces, $this->tags, $this->getClassesOf($this->methods), $this->methods));
1171
					}
1172
				}
1173
			}
1174
		}
1175

                    
1176
		return $this;
1177
	}
1178

                    
1179
	protected function runAgain()0%
1180
	{
1181
		return ($this->prompt($this->locale->_('Press <Enter> to reexecute, press any other key and <Enter> to stop...')) == '');
1182
	}
1183

                    
1184
	protected function loop()0%
1185
	{
1186
		$php = new php();
1187
		$php
1188
			->addOption('-f', $_SERVER['argv'][0])
1189
			->addArgument('--disable-loop-mode')
1190
		;
1191

                    
1192
		if ($this->cli->isTerminal() === true)
1193
		{
1194
			$php->addArgument('--force-terminal');
1195
		}
1196

                    
1197
		$addScoreFile = false;
1198

                    
1199
		foreach ($this->argumentsParser->getValues() as $argument => $values)
1200
		{
1201
			switch ($argument)
1202
			{
1203
				case '-l':
1204
				case '--loop':
1205
				case '--disable-loop-mode':
1206
					break;
1207

                    
1208
				case '-sf':
1209
				case '--score-file':
1210
					$addScoreFile = true;
1211
					break;
1212

                    
1213
				default:
1214
					if ($this->argumentsParser->argumentHasHandler($argument) === false)
1215
					{
1216
						$php->addArgument('-f', $argument);
1217
					}
1218
					else
1219
					{
1220
						$php->addArgument($argument, join(' ', $values));
1221
					}
1222
			}
1223
		}
1224

                    
1225
		if ($this->scoreFile === null)
1226
		{
1227
			$this->scoreFile = sys_get_temp_dir() . '/atoum.score';
1228

                    
1229
			@unlink($this->scoreFile);
1230

                    
1231
			$addScoreFile = true;
1232
		}
1233

                    
1234
		if ($addScoreFile === true)
1235
		{
1236
			$php->addArgument('--score-file', $this->scoreFile);
1237
		}
1238

                    
1239
		while ($this->canRun() === true)
1240
		{
1241
			passthru((string) $php);
1242

                    
1243
			if ($this->loop === false || $this->runAgain() === false)
1244
			{
1245
				$this->stopRun();
1246
			}
1247
		}
1248

                    
1249
		return $this;
1250
	}
1251

                    
1252
	protected function saveScore(atoum\score $score)0%
1253
	{
1254
		if ($this->scoreFile !== null && $this->adapter->file_put_contents($this->scoreFile, serialize($score), \LOCK_EX) === false)
1255
		{
1256
			throw new exceptions\runtime('Unable to save score in \'' . $this->scoreFile . '\'');
1257
		}
1258

                    
1259
		return $this;
1260
	}
1261

                    
1262
	protected function writeHelpUsage()100%
1263
	{
1264
		$this->writeHelp(sprintf($this->locale->_('Usage: %s [path/to/test/file] [options]'), $this->getName()) . PHP_EOL);
1265

                    
1266
		return $this;
1267
	}
1268

                    
1269
	protected function parseArguments(array $arguments)100%
1270
	{
1271
		$configTestPaths = $this->runner->getTestPaths();
1272

                    
1273
		$this->runner->resetTestPaths();
1274

                    
1275
		parent::parseArguments($arguments);
1276

                    
1277
		$this->runner->setTestPaths($this->runner->getTestPaths() ?: $configTestPaths);
1278

                    
1279
		return $this;
1280
	}
1281

                    
1282
	private function getClassesOf($methods)0%
1283
	{
1284
		return sizeof($methods) <= 0 || isset($methods['*']) === true ? array() : array_keys($methods);
1285
	}
1286

                    
1287
	private function copy($from, $to)100%
1288
	{
1289
		if (@$this->adapter->copy($from, $to) === false)
1290
		{
1291
			throw new exceptions\runtime($this->locale->_('Unable to write \'' . $from . '\' to \'' . $to . '\''));
1292
		}
1293

                    
1294
		return $this;
1295
	}
1296

                    
1297
	private static function getFailMethods(atoum\score $score)0%
1298
	{
1299
		return self::mergeMethods(self::mergeMethods(self::mergeMethods($score->getMethodsWithFail(), $score->getMethodsWithError()), $score->getMethodsWithException()), $score->getMethodsNotCompleted());
1300
	}
1301

                    
1302
	private static function mergeMethods(array $methods, array $newMethods)0%
1303
	{
1304
		foreach ($newMethods as $class => $classMethods)
1305
		{
1306
			if (isset($methods[$class]) === false)
1307
			{
1308
				$methods[$class] = $classMethods;
1309
			}
1310
			else
1311
			{
1312
				$methods[$class] = array_unique(array_merge($methods[$class], $classMethods));
1313
			}
1314
		}
1315

                    
1316
		return $methods;
1317
	}
1318
}