1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/* |
4
|
|
|
* PHPUnit plugin for HiDev |
5
|
|
|
* |
6
|
|
|
* @link https://github.com/hiqdev/hidev-phpunit |
7
|
|
|
* @package hidev-phpunit |
8
|
|
|
* @license BSD-3-Clause |
9
|
|
|
* @copyright Copyright (c) 2015-2016, HiQDev (http://hiqdev.com/) |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
namespace hidev\phpunit\controllers; |
13
|
|
|
|
14
|
|
|
use hidev\base\File; |
15
|
|
|
use hidev\handlers\BaseHandler; |
16
|
|
|
use Yii; |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* Goal for Phpunit. |
20
|
|
|
*/ |
21
|
|
|
class PhpunitController extends \hidev\controllers\CommonController |
22
|
|
|
{ |
23
|
|
|
protected $_before = ['phpunit/bootstrap', 'phpunit.xml.dist']; |
24
|
|
|
|
25
|
|
|
protected $_version; |
26
|
|
|
|
27
|
|
|
protected $_bootstrapFile; |
28
|
|
|
|
29
|
|
|
public $force; |
30
|
|
|
public $colors; |
31
|
|
|
public $coverageText; |
32
|
|
|
public $coverageClover; |
33
|
|
|
|
34
|
|
|
public function getConfiguration() |
35
|
|
|
{ |
36
|
|
|
return $this->getGoal('phpunit.xml.dist'); |
|
|
|
|
37
|
|
|
} |
38
|
|
|
|
39
|
|
|
public function getBootstrapFile() |
40
|
|
|
{ |
41
|
|
|
if ($this->_bootstrapFile === null) { |
42
|
|
|
$this->_bootstrapFile = Yii::createObject([ |
43
|
|
|
'class' => File::class, |
44
|
|
|
'template' => 'phpunit/bootstrap.twig', |
45
|
|
|
'path' => 'tests/_bootstrap.php', |
46
|
|
|
]); |
47
|
|
|
} |
48
|
|
|
|
49
|
|
|
return $this->_bootstrapFile; |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
public function actionBootstrap() |
53
|
|
|
{ |
54
|
|
|
if (!$this->getBootstrapFile()->exists()) { |
55
|
|
|
$this->getBootstrapFile()->save(); |
56
|
|
|
} |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
public function actionMake() |
60
|
|
|
{ |
61
|
|
|
return $this->actionRun(); |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
public function actionRun() |
65
|
|
|
{ |
66
|
|
|
$args = []; |
67
|
|
|
if ($this->coverageText) { |
68
|
|
|
$args[] = '--coverage-text'; |
69
|
|
|
} |
70
|
|
|
if ($this->coverageClover) { |
71
|
|
|
$args[] = '--coverage-clover=' . (is_string($this->coverageClover) ? $this->coverageClover : 'coverage.clover'); |
72
|
|
|
} |
73
|
|
|
if ($this->colors) { |
74
|
|
|
$args[] = '--colors' . (version_compare($this->getVersion(), '4.7.0', '>=') ? '=' . $this->colors : ''); |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
return $this->passthru('phpunit', $args); |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
public function getVersion() |
81
|
|
|
{ |
82
|
|
|
if ($this->_version === null) { |
83
|
|
|
$lines = $this->exec('phpunit', ['--version']); |
|
|
|
|
84
|
|
|
$a = explode(' ', $lines[0], 3)[1]; |
85
|
|
|
$this->_version = $a; |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
return $this->_version; |
89
|
|
|
} |
90
|
|
|
|
91
|
|
View Code Duplication |
public function actionGenfake($file) |
|
|
|
|
92
|
|
|
{ |
93
|
|
|
$path = $this->buildFakePath($file); |
94
|
|
|
if (!$this->force && file_exists($path)) { |
95
|
|
|
Yii::warning("already exists: $path"); |
96
|
|
|
return 1; |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
return $this->genFake($file, $path); |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
public function genFake($file, $path) |
103
|
|
|
{ |
104
|
|
|
$text = $this->getView()->render('phpunit/fake.twig', [ |
105
|
|
|
'class' => $this->buildClass($file), |
106
|
|
|
'namespace' => $this->buildTestNamespace(), |
107
|
|
|
'name' => $file, |
108
|
|
|
]); |
109
|
|
|
BaseHandler::write($path, $text); |
110
|
|
|
} |
111
|
|
|
|
112
|
|
View Code Duplication |
public function actionGentest($file) |
|
|
|
|
113
|
|
|
{ |
114
|
|
|
$path = $this->buildTestPath($file); |
115
|
|
|
if (!$this->force && file_exists($path)) { |
116
|
|
|
Yii::warning("already exists: $path"); |
117
|
|
|
return 1; |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
return $this->genSkel($file); |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
public static function prepareFile($file) |
124
|
|
|
{ |
125
|
|
|
return substr($file, -4) === '.php' ? substr($file, 0, -4) : $file; |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
public function genSkel($file) |
129
|
|
|
{ |
130
|
|
|
$destPath = $this->buildTestPath($file); |
131
|
|
|
$dir = dirname($destPath); |
132
|
|
|
if (!file_exists($dir)) { |
133
|
|
|
mkdir($dir, 0777, true); |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
return $this->passthru('phpunit-skelgen', [ |
137
|
|
|
'generate-test', '--bootstrap', 'tests/_bootstrap.php', '--', |
138
|
|
|
$this->buildClass($file), $this->buildPath($file), $this->buildTestClass($file), $destPath, |
139
|
|
|
]); |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
public function buildNamespace($dir = '') |
143
|
|
|
{ |
144
|
|
|
return $this->takePackage()->namespace . ($dir ? '\\' . strtr($dir, '/', '\\') : ''); |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
public function buildTestNamespace($dir = 'tests\\unit') |
148
|
|
|
{ |
149
|
|
|
return $this->buildNamespace($dir); |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
public function buildClass($file, $dir = '', $postfix = '') |
153
|
|
|
{ |
154
|
|
|
return $this->buildNamespace($dir) . '\\' . strtr(static::prepareFile($file), '/', '\\') . $postfix; |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
public function buildTestClass($file, $dir = 'tests\\unit', $postfix = 'Test') |
158
|
|
|
{ |
159
|
|
|
return $this->buildClass($file, $dir, $postfix); |
160
|
|
|
} |
161
|
|
|
|
162
|
|
|
public function buildPath($file, $dir = 'src', $prefix = '', $postfix = '') |
163
|
|
|
{ |
164
|
|
|
return $dir . DIRECTORY_SEPARATOR . $prefix . static::prepareFile($file) . $postfix . '.php'; |
165
|
|
|
|
166
|
|
|
### XXX getting absolute path, think if needed |
167
|
|
|
#return strncmp($path, '/', 1) === 0 ? $path : Yii::getAlias("@prjdir/$path"); |
|
|
|
|
168
|
|
|
} |
169
|
|
|
|
170
|
|
|
public function buildTestPath($file, $dir = 'tests/unit', $prefix = '', $postfix = 'Test') |
171
|
|
|
{ |
172
|
|
|
return $this->buildPath($file, $dir, $prefix, $postfix); |
173
|
|
|
} |
174
|
|
|
|
175
|
|
|
public function buildFakePath($file, $dir = 'tests/unit', $prefix = 'Fake', $postfix = '') |
176
|
|
|
{ |
177
|
|
|
return $this->buildPath($file, $dir, $prefix, $postfix); |
178
|
|
|
} |
179
|
|
|
} |
180
|
|
|
|
If you implement
__call
and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.This is often the case, when
__call
is implemented by a parent class and only the child class knows which methods exist: