Completed
Pull Request — master (#86)
by Alessandro
05:32
created

PHPUnitConfig::getBaseDirectory()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
namespace Paraunit\Configuration;
4
5
/**
6
 * Class PHPUnitConfig
7
 * @package Paraunit\Configuration
8
 */
9
class PHPUnitConfig
10
{
11
    const DEFAULT_FILE_NAME = 'phpunit.xml.dist';
12
13
    /** @var  TempFilenameFactory */
14
    private $tempFilenameFactory;
15
16
    /** @var string */
17
    private $configFile;
18
19
    /** @var string */
20
    private $originalFilename;
21
22
    /** @var  PHPUnitOption[] */
23
    private $phpunitOptions;
24
25
    /**
26
     * @param TempFilenameFactory $tempFilenameFactory
27
     * @param string $inputPathOrFileName
28
     * @throws \InvalidArgumentException
29
     */
30 16
    public function __construct(TempFilenameFactory $tempFilenameFactory, $inputPathOrFileName)
31
    {
32 16
        $this->tempFilenameFactory = $tempFilenameFactory;
33 16
        $this->originalFilename = $inputPathOrFileName;
34 16
        $this->phpunitOptions = array();
35 16
    }
36
37
    /**
38
     * Get the full path for this configuration file
39
     * @return string
40
     */
41 16
    public function getFileFullPath()
42
    {
43 16
        if (null === $this->configFile) {
44 16
            $this->loadAndCopyConfigFile();
45
        }
46
47 14
        return $this->configFile;
48
    }
49
50
    /**
51
     * The relative path from where the configuration defines the testsuites
52
     * @return string
53
     */
54 14
    public function getBaseDirectory()
55
    {
56 14
        return dirname($this->originalFilename);
57
    }
58
59
    /**
60
     * @param PHPUnitOption $option
61
     */
62 1
    public function addPhpunitOption(PHPUnitOption $option)
63
    {
64 1
        $this->phpunitOptions[] = $option;
65 1
    }
66
67
    /**
68
     * @return PHPUnitOption[]
69
     */
70 11
    public function getPhpunitOptions()
71
    {
72 11
        return $this->phpunitOptions;
73
    }
74
75 16
    private function loadAndCopyConfigFile()
76
    {
77 16
        $originalConfigFilename = $this->getConfigFileRealpath($this->originalFilename);
78 14
        $this->configFile = $this->copyAndAlterConfig($originalConfigFilename);
79 14
    }
80
81
    /**
82
     * @param string $inputPathOrFileName
83
     * @return string
84
     * @throws \InvalidArgumentException
85
     */
86 16
    private function getConfigFileRealpath($inputPathOrFileName)
87
    {
88 16
        $inputPathOrFileName = realpath($inputPathOrFileName);
89
90 16
        if (false === $inputPathOrFileName) {
91 1
            throw new \InvalidArgumentException('Config path/file provided is not valid (does it exist?)');
92
        }
93
94 15
        $configFile = $inputPathOrFileName;
95
96 15
        if (is_dir($configFile)) {
97 2
            $this->baseDirectory = dirname($configFile);
0 ignored issues
show
Bug introduced by
The property baseDirectory does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
98 2
            $configFile .= DIRECTORY_SEPARATOR . self::DEFAULT_FILE_NAME;
99
        }
100
101 15
        if (! is_file($configFile) || ! is_readable($configFile)) {
102 1
            throw new \InvalidArgumentException('Config file ' . $configFile . ' does not exist or is not readable');
103
        }
104
105 14
        return $configFile;
106
    }
107
108 14
    private function copyAndAlterConfig($originalConfigFilename)
109
    {
110 14
        $originalConfig = file_get_contents($originalConfigFilename);
111 14
        $document = new \DOMDocument;
112 14
        $document->preserveWhiteSpace = false;
113
114 14
        $document->loadXML($originalConfig);
115 14
        $this->alterBoostrap($document);
116 14
        $this->appendLogListener($document);
117
        
118 14
        $newFilename = $this->tempFilenameFactory->getFilenameForConfiguration();
119
120 14
        if (false === file_put_contents($newFilename, $document->saveXML())) {
121
            throw new \RuntimeException('Error while saving temporary config');
122
        }
123
124 14
        return $newFilename;
125
    }
126
127
    /**
128
     * @param string $originalBoostrap
129
     * @return bool
130
     */
131 14
    private function isRelativePath($originalBoostrap)
132
    {
133 14
        return 0 === preg_match('~(^[A-Z]:)|(^/)~', $originalBoostrap);
134
    }
135
136 14
    private function alterBoostrap(\DOMDocument $document)
137
    {
138 14
        $rootNode = $document->documentElement;
139
140 14
        $originalBoostrap = $rootNode->getAttribute('bootstrap');
141 14
        if ($originalBoostrap && $this->isRelativePath($originalBoostrap)) {
142 14
            $newBootstrapPath = $this->getBaseDirectory() . DIRECTORY_SEPARATOR . $originalBoostrap;
143 14
            $rootNode->setAttribute('bootstrap', $newBootstrapPath);
144
        }
145 14
    }
146
147 14
    private function appendLogListener(\DOMDocument $document)
148
    {
149 14
        $rootNode = $document->documentElement;
150
151 14
        $textNode = $document->createTextNode($this->tempFilenameFactory->getPathForLog());
152 14
        $logDirNode = $document->createElement('string');
153 14
        $logDirNode->appendChild($textNode);
154 14
        $argumentsNode = $document->createElement('arguments');
155 14
        $argumentsNode->appendChild($logDirNode);
156 14
        $logListenerNode = $document->createElement('listener');
157 14
        $logListenerNode->setAttribute('class', 'Paraunit\Parser\JSON\LogPrinter');
158 14
        $logListenerNode->appendChild($argumentsNode);
159
160 14
        $listenersNode = $rootNode->getElementsByTagName('listeners')->item(0);
161 14
        if (! $listenersNode) {
162 13
            $listenersNode = $document->createElement('listeners');
163 13
            $rootNode->appendChild($listenersNode);
164
        }
165
166 14
        $listenersNode->appendChild($logListenerNode);
167 14
    }
168
}
169