/** * @param EventDispatcher $eventDispatcher */ public function attach(EventDispatcher $eventDispatcher) { $studentClient = CouchDBClient::create(['dbname' => static::$studentDb]); $solutionClient = CouchDBClient::create(['dbname' => static::$solutionDb]); $studentClient->createDatabase($studentClient->getDatabase()); $solutionClient->createDatabase($solutionClient->getDatabase()); $eventDispatcher->listen('verify.start', function (Event $e) use($studentClient, $solutionClient) { $e->getParameter('exercise')->seed($studentClient); $this->replicateDbFromStudentToSolution($studentClient, $solutionClient); }); $eventDispatcher->listen('run.start', function (Event $e) use($studentClient) { $e->getParameter('exercise')->seed($studentClient); }); $eventDispatcher->listen('cli.verify.reference-execute.pre', function (CliExecuteEvent $e) { $e->prependArg('phpschool'); }); $eventDispatcher->listen(['cli.verify.student-execute.pre', 'cli.run.student-execute.pre'], function (CliExecuteEvent $e) { $e->prependArg('phpschool-student'); }); $eventDispatcher->insertVerifier('verify.finish', function (Event $e) use($studentClient) { $verifyResult = $e->getParameter('exercise')->verify($studentClient); if (false === $verifyResult) { return Failure::fromNameAndReason($this->getName(), 'Database verification failed'); } return Success::fromCheck($this); }); $eventDispatcher->listen(['cli.verify.reference-execute.fail', 'verify.finish', 'run.finish'], function (Event $e) use($studentClient, $solutionClient) { $studentClient->deleteDatabase(static::$studentDb); $solutionClient->deleteDatabase(static::$solutionDb); }); }
/** * @param ExerciseInterface $exercise * @param string $fileName * @return ResultInterface */ public function check(ExerciseInterface $exercise, $fileName) { if (!$exercise instanceof FunctionRequirementsExerciseCheck) { throw new \InvalidArgumentException(); } $requiredFunctions = $exercise->getRequiredFunctions(); $bannedFunctions = $exercise->getBannedFunctions(); $code = file_get_contents($fileName); try { $ast = $this->parser->parse($code); } catch (Error $e) { return Failure::fromCheckAndCodeParseFailure($this, $e, $fileName); } $visitor = new FunctionVisitor($requiredFunctions, $bannedFunctions); $traverser = new NodeTraverser(); $traverser->addVisitor($visitor); $traverser->traverse($ast); $bannedFunctions = []; if ($visitor->hasUsedBannedFunctions()) { $bannedFunctions = array_map(function (FuncCall $node) { return ['function' => $node->name->__toString(), 'line' => $node->getLine()]; }, $visitor->getBannedUsages()); } $missingFunctions = []; if (!$visitor->hasMetFunctionRequirements()) { $missingFunctions = $visitor->getMissingRequirements(); } if (!empty($bannedFunctions) || !empty($missingFunctions)) { return new FunctionRequirementsFailure($this, $bannedFunctions, $missingFunctions); } return Success::fromCheck($this); }
/** * Simply check that the file exists. * * @param ExerciseInterface $exercise The exercise to check against. * @param Input $input The command line arguments passed to the command. * @return ResultInterface The result of the check. */ public function check(ExerciseInterface $exercise, Input $input) { if (file_exists($input->getArgument('program'))) { return Success::fromCheck($this); } return Failure::fromCheckAndReason($this, sprintf('File: "%s" does not exist', $input->getArgument('program'))); }
/** * Simply check that the file exists. * * @param ExerciseInterface $exercise The exercise to check against. * @param string $fileName The absolute path to the student's solution. * @return ResultInterface The result of the check. */ public function check(ExerciseInterface $exercise, $fileName) { if (file_exists($fileName)) { return Success::fromCheck($this); } return Failure::fromCheckAndReason($this, sprintf('File: "%s" does not exist', $fileName)); }
public function testSuccessFromCheck() { $check = $this->createMock(CheckInterface::class); $check->expects($this->any())->method('getName')->will($this->returnValue('Some Check')); $success = Success::fromCheck($check); $this->assertInstanceOf(ResultInterface::class, $success); $this->assertEquals('Some Check', $success->getCheckName()); }
/** * @param ExerciseInterface $exercise * @param string $fileName * @return Failure|Success */ public function check(ExerciseInterface $exercise, $fileName) { $process = new Process(sprintf('%s -l %s', PHP_BINARY, $fileName)); $process->run(); if ($process->isSuccessful()) { return Success::fromCheck($this); } return Failure::fromCheckAndReason($this, $process->getErrorOutput()); }
/** * This check grabs the contents of the student's solution and * attempts to parse it with `nikic/php-parser`. If any exceptions are thrown * by the parser, it is treated as a failure. * * @param ExerciseInterface $exercise The exercise to check against. * @param Input $input The command line arguments passed to the command. * @return ResultInterface The result of the check. */ public function check(ExerciseInterface $exercise, Input $input) { $code = file_get_contents($input->getArgument('program')); try { $this->parser->parse($code); } catch (Error $e) { return Failure::fromCheckAndCodeParseFailure($this, $e, $input->getArgument('program')); } return Success::fromCheck($this); }
/** * @param ExerciseInterface $exercise * @param string $fileName * @return ResultInterface */ public function check(ExerciseInterface $exercise, $fileName) { $code = file_get_contents($fileName); try { $this->parser->parse($code); } catch (Error $e) { return Failure::fromCheckAndCodeParseFailure($this, $e, $fileName); } return Success::fromCheck($this); }