Completed
Push — master ( 823c18...cc9241 )
by Alessandro
07:14
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
    const COPY_FILE_NAME = 'phpunit-paraunit.xml';
13
14
    /** @var  TempFilenameFactory */
15
    private $tempFilenameFactory;
16
17
    /** @var string */
18
    private $configFile;
19
20
    /** @var string */
21
    private $originalFilename;
22
23
    /** @var  PHPUnitOption[] */
24
    private $phpunitOptions;
25
26
    /**
27
     * @param TempFilenameFactory $tempFilenameFactory
28
     * @param string $inputPathOrFileName
29
     * @throws \InvalidArgumentException
30
     */
31 21
    public function __construct(TempFilenameFactory $tempFilenameFactory, $inputPathOrFileName)
32
    {
33 21
        $this->tempFilenameFactory = $tempFilenameFactory;
34 21
        $this->originalFilename = $this->getConfigFileRealpath($inputPathOrFileName);
35 19
        $this->phpunitOptions = array();
36 19
    }
37
38
    /**
39
     * Get the full path for this configuration file
40
     * @return string
41
     * @throws \RuntimeException
42
     */
43 18
    public function getFileFullPath()
44
    {
45 18
        if (null === $this->configFile) {
46 18
            $this->configFile = $this->copyAndAlterConfig($this->originalFilename);
47
        }
48
49 18
        return $this->configFile;
50
    }
51
52
    /**
53
     * The relative path from where the configuration defines the testsuites
54
     * @return string
55
     */
56 19
    public function getBaseDirectory()
57
    {
58 19
        return dirname($this->originalFilename);
59
    }
60
61
    /**
62
     * @param PHPUnitOption $option
63
     */
64 1
    public function addPhpunitOption(PHPUnitOption $option)
65
    {
66 1
        $this->phpunitOptions[] = $option;
67 1
    }
68
69
    /**
70
     * @return PHPUnitOption[]
71
     */
72 15
    public function getPhpunitOptions()
73
    {
74 15
        return $this->phpunitOptions;
75
    }
76
77
    /**
78
     * @param string $inputPathOrFileName
79
     * @return string
80
     * @throws \InvalidArgumentException
81
     */
82 21
    private function getConfigFileRealpath($inputPathOrFileName)
83
    {
84 21
        $configFile = realpath($inputPathOrFileName);
85
86 21
        if (false === $configFile) {
87 1
            throw new \InvalidArgumentException('Config path/file provided is not valid: ' . $inputPathOrFileName);
88
        }
89
90 20
        if (is_dir($configFile)) {
91 3
            $configFile .= DIRECTORY_SEPARATOR . self::DEFAULT_FILE_NAME;
92
        }
93
94 20
        if (! is_file($configFile) || ! is_readable($configFile)) {
95 1
            throw new \InvalidArgumentException('Config file ' . $configFile . ' does not exist or is not readable');
96
        }
97
98 19
        return $configFile;
99
    }
100
101
    /**
102
     * @param $originalConfigFilename
103
     * @return string The full filename of the new temp config
104
     * @throws \RuntimeException
105
     */
106 18
    private function copyAndAlterConfig($originalConfigFilename)
107
    {
108 18
        $originalConfig = file_get_contents($originalConfigFilename);
109 18
        $document = new \DOMDocument;
110 18
        $document->preserveWhiteSpace = false;
111
112 18
        $document->loadXML($originalConfig);
113 18
        $this->alterBoostrap($document);
114 18
        $this->appendLogListener($document);
115
116 18
        $newFilename = dirname($this->originalFilename) . DIRECTORY_SEPARATOR . 'phpunit-paraunit.xml';
117
118 18
        if (false === file_put_contents($newFilename, $document->saveXML())) {
119
            throw new \RuntimeException('Error while saving temporary config in ' . $newFilename);
120
        }
121
122 18
        return $newFilename;
123
    }
124
125
    /**
126
     * @param string $originalBoostrap
127
     * @return bool
128
     */
129 18
    private function isRelativePath($originalBoostrap)
130
    {
131 18
        return 0 === preg_match('~(^[A-Z]:)|(^/)~', $originalBoostrap);
132
    }
133
134 18
    private function alterBoostrap(\DOMDocument $document)
135
    {
136 18
        $rootNode = $document->documentElement;
137
138 18
        $originalBoostrap = $rootNode->getAttribute('bootstrap');
139 18
        if ($originalBoostrap && $this->isRelativePath($originalBoostrap)) {
140 18
            $newBootstrapPath = $this->getBaseDirectory() . DIRECTORY_SEPARATOR . $originalBoostrap;
141 18
            $rootNode->setAttribute('bootstrap', $newBootstrapPath);
142
        }
143 18
    }
144
145 18
    private function appendLogListener(\DOMDocument $document)
146
    {
147 18
        $rootNode = $document->documentElement;
148
149 18
        $textNode = $document->createTextNode($this->tempFilenameFactory->getPathForLog());
150 18
        $logDirNode = $document->createElement('string');
151 18
        $logDirNode->appendChild($textNode);
152 18
        $argumentsNode = $document->createElement('arguments');
153 18
        $argumentsNode->appendChild($logDirNode);
154 18
        $logListenerNode = $document->createElement('listener');
155 18
        $logListenerNode->setAttribute('class', 'Paraunit\Configuration\StaticOutputPath');
156 18
        $logListenerNode->appendChild($argumentsNode);
157
158 18
        $listenersNode = $rootNode->getElementsByTagName('listeners')->item(0);
159 18
        if (! $listenersNode) {
160 17
            $listenersNode = $document->createElement('listeners');
161 17
            $rootNode->appendChild($listenersNode);
162
        }
163
164 18
        $listenersNode->appendChild($logListenerNode);
165 18
    }
166
}
167