Completed
Push — master ( 979448...f8182d )
by Alessandro
05:10
created

PHPUnitConfig::alterBoostrap()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

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