Hoa central
Run.php
Go to the documentation of this file.
1 <?php
2 
37 namespace Hoa\Test\Bin;
38 
39 use Hoa\Console;
40 use Hoa\Core;
41 use Hoa\File;
42 
52 {
58  protected $options = [
59  ['all', Console\GetOption::NO_ARGUMENT, 'a'],
60  ['libraries', Console\GetOption::REQUIRED_ARGUMENT, 'l'],
61  ['namespaces', Console\GetOption::REQUIRED_ARGUMENT, 'n'],
62  ['directories', Console\GetOption::REQUIRED_ARGUMENT, 'd'],
64  ['filter', Console\GetOption::REQUIRED_ARGUMENT, 'F'],
65  ['debug', Console\GetOption::NO_ARGUMENT, 'D'],
66  ['php-binary', Console\GetOption::REQUIRED_ARGUMENT, 'p'],
67  ['concurrent-processes', Console\GetOption::REQUIRED_ARGUMENT, 'P'],
68  ['help', Console\GetOption::NO_ARGUMENT, 'h'],
69  ['help', Console\GetOption::NO_ARGUMENT, '?']
70  ];
71 
72 
73 
79  public function main()
80  {
81  $directories = [];
82  $files = [];
83  $namespaces = [];
84  $filter = [];
85  $debug = false;
86  $php = null;
87  $concurrentProcesses = 2;
88 
89  while (false !== $c = $this->getOption($v)) {
90  switch ($c) {
91  case 'a':
92  $iterator = new File\Finder();
93  $iterator->in(resolve('hoa://Library/', true, true))
94  ->directories()
95  ->maxDepth(1);
96 
97  foreach ($iterator as $fileinfo) {
98  $libraryName = $fileinfo->getBasename();
99 
100  if (true === Core\Consistency::isKeyword($libraryName)) {
101  continue;
102  }
103 
104  $pathname = resolve('hoa://Library/' . $libraryName);
105  $tests = $pathname . DS . 'Test' . DS;
106  $manualTests = $tests . 'Unit';
107  $automaticTests = $tests . 'Praspel' . DS . 'Unit';
108 
109  if (is_dir($manualTests)) {
110  $directories[] = $manualTests;
111  }
112 
113  if (is_dir($automaticTests)) {
114  $directories[] = $automaticTests;
115  }
116  }
117 
118  break;
119 
120  case 'l':
121  foreach ($this->parser->parseSpecialValue($v) as $library) {
122  $libraryName = ucfirst(strtolower($library));
123  $pathname = resolve('hoa://Library/' . $libraryName);
124  $tests = $pathname . DS . 'Test';
125 
126  if (!is_dir($tests)) {
127  throw new Console\Exception(
128  'Library %s does not exist or has no test.',
129  0,
130  $libraryName
131  );
132  }
133 
134  $directories[] = $tests;
135  $namespaces[] = 'Hoa\\' . $libraryName;
136  }
137 
138  break;
139 
140  case 'n':
141  foreach ($this->parser->parseSpecialValue($v) as $namespace) {
142  $namespace = str_replace('.', '\\', $namespace);
143  $parts = explode('\\', $namespace);
144 
145  if (2 > count($parts)) {
146  throw new Console\Exception(
147  'Namespace %s is too short.',
148  1,
149  $namespace
150  );
151  }
152 
153  $head = resolve('hoa://Library/' . $parts[1]);
154  $tail = implode(DS, array_slice($parts, 2));
155  $namespaceDirectory = $head . DS . $tail;
156 
157  if (!is_dir($namespaceDirectory)) {
158  throw new Console\Exception(
159  'Namespace %s does not exist.',
160  2,
161  $namespace
162  );
163  }
164 
165  $tests = $head . DS . 'Test' . DS;
166  $manualTests = $tests . 'Unit' . DS . $tail;
167  $automaticTests = $tests . 'Praspel' . DS . 'Unit' . DS . $tail;
168 
169  if (is_dir($manualTests)) {
170  $directories[] = $manualTests;
171  }
172 
173  if (is_dir($automaticTests)) {
174  $directories[] = $automaticTests;
175  }
176 
177  $namespaces[] = $namespace;
178  }
179 
180  break;
181 
182  case 'd':
183  foreach ($this->parser->parseSpecialValue($v) as $directory) {
184  if (!is_dir($directory)) {
185  throw new Console\Exception(
186  'Directory %s does not exist.',
187  3,
188  $directory
189  );
190  }
191 
192  $directories[] = $directory;
193  }
194 
195  break;
196 
197  case 'f':
198  foreach ($this->parser->parseSpecialValue($v) as $file) {
199  if (!file_exists($file)) {
200  throw new Console\Exception(
201  'File %s does not exist.',
202  4,
203  $file
204  );
205  }
206 
207  $files[] = $file;
208  }
209 
210  break;
211 
212  case 'F':
213  $filter = $v;
214 
215  break;
216 
217  case 'D':
218  $debug = $v;
219 
220  break;
221 
222  case 'p':
223  $php = $v;
224 
225  break;
226 
227  case 'P':
228  $concurrentProcesses = intval($v);
229 
230  break;
231 
232  case '__ambiguous':
233  $this->resolveOptionAmbiguity($v);
234 
235  break;
236 
237  case 'h':
238  case '?':
239  default:
240  return $this->usage();
241 
242  break;
243  }
244  }
245 
246  $atoum = 'atoum';
247 
248  if (WITH_COMPOSER) {
249  $atoum =
250  __DIR__ . DS .
251  '..' . DS .
252  '..' . DS .
253  '..' . DS .
254  'bin' . DS .
255  'atoum';
256  } elseif (isset($_SERVER['HOA_ATOUM_BIN'])) {
257  $atoum = $_SERVER['HOA_ATOUM_BIN'];
258  }
259 
260  $command =
261  $atoum .
262  ' --configurations ' .
263  resolve('hoa://Library/Test/.atoum.php') .
264  ' --bootstrap-file ' .
265  resolve('hoa://Library/Test/.bootstrap.atoum.php') .
266  ' --force-terminal' .
267  ' --max-children-number ' . $concurrentProcesses;
268 
269  if (true === $debug) {
270  $command .= ' --debug';
271  }
272 
273  if (null !== $php) {
274  $command .= ' --php ' . $php;
275  }
276 
277  if (!empty($directories)) {
278  $command .= ' --directories ' . implode(' ', $directories);
279  } elseif (!empty($files)) {
280  $command .= ' --files ' . implode(' ', $files);
281  } else {
282  return $this->usage();
283  }
284 
285  if (!empty($namespaces)) {
286  $command .= ' --namespaces ' . implode(' ', $namespaces);
287  }
288 
289  if (!empty($filter)) {
290  $command .= ' --filter \'' . str_replace('\'', '\'"\'"\'', $filter) . '\'';
291  }
292 
293  $processus = new Processus($command);
294  $processus->on('input', function ($bucket) {
295  return false;
296  });
297  $processus->on('output', function ($bucket) {
298  $data = $bucket->getData();
299 
300  echo $data['line'], "\n";
301 
302  return;
303  });
304  $processus->run();
305 
306  return;
307  }
308 
314  public function usage()
315  {
316  echo
317  'Usage : test:run <options>', "\n",
318  'Options :', "\n",
319  $this->makeUsageOptionsList([
320  'a' => 'Run tests of all libraries.',
321  'l' => 'Run tests of some libraries.',
322  'n' => 'Run tests of some namespaces.',
323  'd' => 'Run tests of some directories.',
324  'f' => 'Run tests of some files.',
325  'F' => 'Filter tests with a ruler expression (see ' .
326  'Hoa\Ruler).',
327  'D' => 'Activate the debugging mode.',
328  'p' => 'Path to a specific PHP binary.',
329  'P' => 'Maximum concurrent processes that can run.',
330  'help' => 'This help.'
331  ]), "\n\n",
332  'Available variables for filter expressions:', "\n",
333  ' * method,', "\n",
334  ' * class,', "\n",
335  ' * namespace,', "\n",
336  ' * tags.', "\n";
337 
338  return;
339  }
340 }
341 
343 {
350  protected function setCommand($command)
351  {
352  $old = $this->getCommand();
353  $this->_command = $command;
354 
355  return $old;
356  }
357 }
358 
359 __halt_compiler();
360 Run tests.
makeUsageOptionsList(Array $definitions=[])
Definition: Kit.php:149
setCommand($command)
Definition: Run.php:350
getOption(&$optionValue, $short=null)
Definition: Kit.php:104
resolveOptionAmbiguity(Array $solutions)
Definition: Kit.php:190