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; }