protected function execute(InputInterface $input, OutputInterface $output)
{
// version, author
$output->writeln('Mutation testing tool for PHP, by Jean-François Lépine <http://www.lepine.pro>');
$output->writeln('');
//
// Cache
$cache = new UnitInfo();
// get adapter
$this->prepare($input, $output);
$factory = new AdapterFactory();
$adapter = $factory->factory($input->getArgument('tool'), $input->getArgument('binary'), $input->getArgument('path'), $input->getOption('options'));
// First run
$log = tempnam(sys_get_temp_dir(), 'ru-mutate');
$output->writeln('Executing test suite...');
$adapter->run(null, array(), $log);
$units = $adapter->getSuiteResult($log);
unlink($log);
// event
$event = new FirstRunEvent($units);
$this->getApplication()->getDispatcher()->dispatch('mutate.firstrun', $event);
// Get the tested files
$output->writeln('Extracting tested files...');
foreach ($units as $k => $unit) {
if (!$cache->has($unit)) {
$adapter->parseTestedFiles($unit);
$cache->persist($unit);
} else {
$unit = $cache->get($unit);
$units->set($k, $unit);
}
$this->getApplication()->getDispatcher()->dispatch('mutate.parseTestedFiles', new ParseTestedFilesEvent($unit));
}
$this->getApplication()->getDispatcher()->dispatch('mutate.parseTestedFilesDone', new UnitsResultEvent($units));
$cache->flush();
$this->strategy = new ScoreSpecification(new Halstead(new Tokenizer(), new TokenType()), $input->getOption('bugs'));
$this->getApplication()->getDispatcher()->addSubscriber($this->strategy);
//
// Preparing mutations
$output->writeln('');
$output->writeln('');
$output->writeln('Building mutations. This will take few minutes...');
$mutaterFactory = new MutaterFactory();
$mutationFactory = new MutationFactory($mutaterFactory, $this->strategy);
$mutations = array();
$nbMutations = 0;
foreach ($units as $unit) {
foreach ($unit->getTestedFiles() as $filename) {
$mainMutation = $mutationFactory->factory($filename, $unit->getFile());
$childs = array();
foreach ($mainMutation->getMutations() as $mutation) {
$childs[] = $mutation;
}
$mutations[] = (object) array('mainMutation' => $mainMutation, 'childs' => $childs);
$nbMutations += sizeof($childs);
}
$this->getApplication()->getDispatcher()->dispatch('mutate.mutationCreated', new MutationCreatedEvent($unit));
}
$this->getApplication()->getDispatcher()->dispatch('mutate.mutationCreatedDone', new MutationCreatedEvent($unit));
//
// Executing mutations
$output->writeln('');
$output->writeln('');
$output->writeln(sprintf('Executing %d mutations. This will take few minutes. Coffee time ?', $nbMutations));
$mutaterFactory = new MutaterFactory();
$mutationFactory = new MutationFactory($mutaterFactory, $this->strategy);
$results = array();
$processManager = new ProcessManager($input->getOption('processes'));
$adapter->setProcessManager($processManager);
foreach ($mutations as $mutationInfo) {
$mainMutation = $mutationInfo->mainMutation;
$childs = $mutationInfo->childs;
foreach ($childs as $mutation) {
$dispatcher = $this->getApplication()->getDispatcher();
$adapter->runMutation($mutation, array(), null, null, function ($unit) use($dispatcher) {
$event = $dispatcher->dispatch('mutate.mutation', new MutationEvent($unit));
$this->success &= $event->getUnit() && !$event->getUnit()->hasFail();
});
}
$results[] = $mainMutation;
}
$processManager->wait();
$this->getApplication()->getDispatcher()->dispatch('mutate.mutationsDone', new MutationsDoneEvent($results));
// terminate
$output->writeln('');
$output->writeln('');
$output->writeln('<info>Done</info>');
return $this->success ? 0 : 1;
}