-
Notifications
You must be signed in to change notification settings - Fork 0
/
runner.php
executable file
·204 lines (177 loc) · 6.84 KB
/
runner.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
#!/usr/bin/php
<?php
$basePath = realpath(__DIR__);
define('DOCTEST_SUITE_FRAMEWORK', $basePath);
putenv('DOCTEST_SUITE_FRAMEWORK=' . DOCTEST_SUITE_FRAMEWORK);
$commandPattern = 'phpdt %(preparams)s %(files)s %(postparams)s';
$_SERVER['DOCTEST_SUITE_FRAMEWORK'] = DOCTEST_SUITE_FRAMEWORK;
$wrapperPath = $basePath . '/lib-test/doctestEnv/atk.doctest.tmpl.php';
include $basePath . '/site-config.php';
include_once 'Console/CommandLine.php';
$parser = new Console_CommandLine(array(
'description' => 'DocTestRunner',
'version' => '0.0.5'
));
$parser->addOption('coverage', array(
'long_name' => '--coverage',
'description' => 'Activate coverage',
'action' => 'StoreTrue'
));
$parser->addOption('singleTest', array(
'short_name' => '-t',
'long_name' => '--single-test',
'description' => 'Run single test',
'action' => 'StoreString'
));
$parser->addOption('phpWrapper', array(
'long_name' => '--php-wrapper',
'description' => 'Define wrapper to php command',
'action' => 'StoreString'
));
$parser->addArgument('path', array('multiple'=>true));
function getSQLite() {
global $config;
$db = new SQLite3(COVERAGE_DB);
$db->exec('CREATE TABLE IF NOT EXISTS coverage_file (file_id INTEGER, file_name STRING UNIQUE, total_lines INTEGER, update_date DATE DEFAULT CURRENT_DATE, doctest INTEGER DEFAULT 0, PRIMARY KEY (file_id), UNIQUE(file_name))');
$db->exec('CREATE TABLE IF NOT EXISTS coverage_data (file_id INTEGER not NULL, line_number INTEGER, covered BOOLEAN, line_type INTEGER, PRIMARY KEY (file_id, line_number))');
$db->exec('CREATE TABLE IF NOT EXISTS coverage_origin (coverage_origin_id INTEGER not NULL, file_id INTEGER not NULL, parent_file_id INTEGER not NULL, PRIMARY KEY(coverage_origin_id) );');
return $db;
}
function getDependencies($filename) {
$q = "select file_name from coverage_file where file_id in (select a.parent_file_id from coverage_origin a, coverage_file b where a.file_id = b.file_id and b.file_name='$filename');";
$db = getSQLite();
$res = $db->query($q);
return $res->fetchArray(SQLITE3_ASSOC) ? : array();
}
function flushAll() {
$db = getSQLite();
$q = "delete from coverage_data;";
$db->exec($q);
$q = "delete from coverage_origin;";
$db->exec($q);
}
function flushFile($filename) {
$db = getSQLite();
$q = "delete from coverage_data WHERE coverage_data.file_id IN (SELECT file_id FROM coverage_file WHERE coverage_file.file_name like '$filename%');";
$db->exec($q);
$q = "delete from coverage_origin WHERE coverage_origin.parent_file_id IN (SELECT file_id FROM coverage_file WHERE coverage_file.file_name like '$filename%');";
$db->exec($q);
}
function updateFile($filename) {
$db = getSQLite();
$q = "update coverage_file set doctest=1 where file_name like '$filename%';";
$db->exec($q);
}
function saveTempDb() {
global $config;
copy(COVERAGE_DB, COVERAGE_STORE);
}
function getCoverage() {
$db = getSQLite();
$q = "select ROUND(((ROUND(SUM(B.covered_lines)) / ROUND(SUM(A.total_lines))) * 100),0) as coverage from coverage_file A, (select file_id,count(*) as covered_lines from coverage_data where covered=1 or covered=-2 group by file_id) B where A.file_id = B.file_id;";
$res = $db->query($q);
$res = $res->fetchArray(SQLITE3_ASSOC);
return $res['coverage'];
}
function getCoverageFile($file) {
if (preg_match('/\/\/\s\[\[([^\]]*)]]/', file_get_contents($file), $matches)) {
$testCaseFile = dirname($file) . '/' . str_replace('_', '/', $matches[1]) . '.php';
} else {
$testCaseFile = $file;
}
$q = "select ROUND(((ROUND(SUM(B.covered_lines)) / ROUND(SUM(A.total_lines))) * 100),0) as coverage, file_name as filename from coverage_file A, (select file_id,count(*) as covered_lines from coverage_data where covered=1 or covered=-2 group by file_id) B where A.file_id = B.file_id and A.file_name='$testCaseFile';";
$db = getSQLite();
$res = $db->query($q);
$res = $res->fetchArray(SQLITE3_ASSOC);
return $res;
}
function sprintf_array($string, $array) {
$keys = array_keys($array);
$keysmap = array_flip($keys);
$values = array_values($array);
while (preg_match('/%\(([a-zA-Z0-9_ -]+)\)/', $string, $m)) {
if (!isset($keysmap[$m[1]])) {
continue;
}
$string = str_replace($m[0], '%' . ($keysmap[$m[1]] + 1) . '$', $string);
}
array_unshift($values, $string);
return call_user_func_array('sprintf', $values);
}
function getFiles ($path) {
$path = implode(' ', $path);
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("file", "/tmp/error-output.txt", "a")
);
$cmd = 'find -H ' . $path . ' -type f -name "*.php" -exec grep -H -l -m 1 "<code>" {} \;';
$process = proc_open($cmd, $descriptorspec, $pipes);
$files = explode("\n", stream_get_contents($pipes[1]));
$ret = array();
foreach ($files as $file) {
$f = realpath($file);
$ret[] = $f;
if (file_exists($f)) {
$ret = array_merge(getDependencies($f), $ret);
}
}
return array_unique($ret);
}
try {
$result = $parser->parse();
$options = $result->options;
$files = getFiles($result->args['path']);
if ($options['coverage']) {
if (empty($files)) {
flushAll();
} else {
foreach ($files as $file) {
flushFile($file);
}
}
}
$preparams = '';
if ($options['singleTest']) {
$preparams = ' -t \'' . $options['singleTest'] . '\' ';
}
$preparams .= ' --template-code=' . $wrapperPath;
if ($options['phpWrapper']) {
$preparams .= ' --php-wrapper=' . $options['phpWrapper'];
}
if ($options['coverage']) {
putenv('DOCTEST_COVERAGE=on');
}
$postparams = '';
$command = sprintf_array(
$commandPattern,
array(
'files' => implode(' ', $files),
'preparams' => $preparams,
'postparams' => $postparams
));
$process = system($command, $status);
if($status !== 0) {
exit($status);
}
if ($options['coverage']) {
foreach ($files as $file) {
updateFile($file);
}
}
echo "\033[0;34mCode Coverage\033[0m\n";
echo "=============\n";
foreach ($files as $file) {
$coverage = getCoverageFile($file);
if (!empty($coverage['filename'])) {
echo $coverage['filename'] . ': ' . ($coverage['coverage'] > 70 ? "\033[1;32m" : "\033[0;31m") . $coverage['coverage'] . "%\033[0m\n";
}
}
echo "=============\n";
$coverage = getCoverage();
echo 'Total: ' . ($coverage > 70 ? "\033[1;32m" : "\033[0;31m") . $coverage . "%\n\n";
echo "\033[0m";
} catch (Exception $e) {
$parser->displayError($e->getMessage());
return 1;
}