Completed
Push — master ( 4f7a58...17cdc3 )
by Alexander
02:21
created

MissingTestsCommand::execute()   B

Complexity

Conditions 5
Paths 9

Size

Total Lines 35
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 35
ccs 0
cts 29
cp 0
rs 8.439
cc 5
eloc 21
nc 9
nop 2
crap 30
1
<?php
2
namespace ConsoleHelpers\CodeInsight\Command;
3
4
5
use Symfony\Component\Console\Input\InputArgument;
6
use Symfony\Component\Console\Input\InputInterface;
7
use Symfony\Component\Console\Output\OutputInterface;
8
use Symfony\Component\Finder\Finder;
9
10
class MissingTestsCommand extends AbstractCommand
11
{
12
13
	/**
14
	 * {@inheritdoc}
15
	 */
16
	protected function configure()
17
	{
18
		$this
19
			->setName('missing-tests')
20
			->setDescription('Shows classes without tests')
21
			->addArgument(
22
				'src-path',
23
				InputArgument::OPTIONAL,
24
				'Path to folder with source code',
25
				'src'
26
			)
27
			->addArgument(
28
				'tests-path',
29
				InputArgument::OPTIONAL,
30
				'Path to folder with tests',
31
				'tests'
32
			);
33
	}
34
35
	/**
36
	 * {@inheritdoc}
37
	 */
38
	protected function execute(InputInterface $input, OutputInterface $output)
39
	{
40
		$src_path = $this->getPath('src-path');
41
		$tests_path = $this->getPath('tests-path');
42
43
		$finder = new Finder();
44
		$finder->files()->name('*.php')->notName('/^(I[A-Z]|Abstract[A-Z])/')->in($src_path);
45
46
		$missing_tests = array();
47
		$src_path_parent_path = dirname($src_path) . '/';
48
49
		foreach ( $finder as $source_file ) {
50
			$source_file_path = $source_file->getPathname();
51
			$test_file_path = preg_replace(
52
				'/^' . preg_quote($src_path, '/') . '(.*)\.php$/',
53
				$tests_path . '$1Test.php',
54
				$source_file_path
55
			);
56
57
			if ( !file_exists($test_file_path) ) {
58
				$missing_tests[] = str_replace($src_path_parent_path, '', $source_file_path);
59
			}
60
		}
61
62
		if ( !$missing_tests ) {
63
			$this->io->writeln('<info>Tests for all source files are found.</info>');
64
		}
65
		else {
66
			$this->io->writeln('<error>Tests for following source files are missing:</error>');
67
68
			foreach ( $missing_tests as $missing_test ) {
69
				$this->io->writeln(' * ' . $missing_test);
70
			}
71
		}
72
	}
73
74
	/**
75
	 * Returns and validates path.
76
	 *
77
	 * @param string $argument_name Argument name, that contains path.
78
	 *
79
	 * @return string
80
	 * @throws \InvalidArgumentException When path isn't valid.
81
	 */
82
	protected function getPath($argument_name)
83
	{
84
		$raw_path = $this->io->getArgument($argument_name);
85
		$path = realpath($raw_path);
86
87
		if ( !$path || !file_exists($path) || !is_dir($path) ) {
88
			throw new \InvalidArgumentException('The "' . $raw_path . '" path is invalid.');
89
		}
90
91
		return $path;
92
	}
93
94
}
95