public function setUp()
 {
     $this->exercise = $this->createMock(CgiExerciseInterface::class);
     $this->runner = new CgiRunner($this->exercise, new EventDispatcher(new ResultAggregator()));
     $this->exercise->expects($this->any())->method('getType')->will($this->returnValue(ExerciseType::CGI()));
     $this->assertEquals('CGI Program Runner', $this->runner->getName());
 }
 public function testSupports()
 {
     $exercise1 = $this->prophesize(ExerciseInterface::class);
     $exercise2 = $this->prophesize(ExerciseInterface::class);
     $exercise1->getType()->willReturn(ExerciseType::CLI());
     $exercise2->getType()->willReturn(ExerciseType::CGI());
     $this->assertTrue($this->factory->supports($exercise1->reveal()));
     $this->assertFalse($this->factory->supports($exercise2->reveal()));
 }
 public function setUp()
 {
     $this->check = new ComposerCheck();
     $this->exercise = new ComposerExercise();
     $this->assertEquals('Composer Dependency Check', $this->check->getName());
     $this->assertEquals(ComposerExerciseCheck::class, $this->check->getExerciseInterface());
     $this->assertTrue($this->check->canRun(ExerciseType::CGI()));
     $this->assertTrue($this->check->canRun(ExerciseType::CLI()));
 }
 public function setUp()
 {
     $this->check = new PhpLintCheck();
     $this->exercise = $this->getMock(ExerciseInterface::class);
     $this->assertEquals('PHP Code Check', $this->check->getName());
     $this->assertEquals(ExerciseInterface::class, $this->check->getExerciseInterface());
     $this->assertTrue($this->check->canRun(ExerciseType::CGI()));
     $this->assertTrue($this->check->canRun(ExerciseType::CLI()));
 }
 public function setUp()
 {
     $this->testDir = sprintf('%s/%s', sys_get_temp_dir(), $this->getName());
     mkdir($this->testDir, 0777, true);
     $this->check = new FileExistsCheck();
     $this->exercise = $this->getMock(ExerciseInterface::class);
     $this->assertEquals('File Exists Check', $this->check->getName());
     $this->assertEquals(ExerciseInterface::class, $this->check->getExerciseInterface());
     $this->assertTrue($this->check->canRun(ExerciseType::CGI()));
     $this->assertTrue($this->check->canRun(ExerciseType::CLI()));
 }
 public function testFromCheckAndExerciseConstructor()
 {
     $exercise = $this->createMock(ExerciseInterface::class);
     $exercise->expects($this->once())->method('getName')->will($this->returnValue('Some Exercise'));
     $exercise->expects($this->once())->method('getType')->will($this->returnValue(ExerciseType::CLI()));
     $check = $this->createMock(CheckInterface::class);
     $check->expects($this->once())->method('getName')->will($this->returnValue('Some Check'));
     $e = CheckNotApplicableException::fromCheckAndExercise($check, $exercise);
     $msg = 'Check: "Some Check" cannot process exercise: "Some Exercise" with type: "CLI"';
     $this->assertSame($msg, $e->getMessage());
 }
 public function setUp()
 {
     $parserFactory = new ParserFactory();
     $this->parser = $parserFactory->create(ParserFactory::PREFER_PHP7);
     $this->check = new FunctionRequirementsCheck($this->parser);
     $this->exercise = new FunctionRequirementsExercise();
     $this->assertEquals('Function Requirements Check', $this->check->getName());
     $this->assertEquals(FunctionRequirementsExerciseCheck::class, $this->check->getExerciseInterface());
     $this->assertTrue($this->check->canRun(ExerciseType::CGI()));
     $this->assertTrue($this->check->canRun(ExerciseType::CLI()));
 }
 public function setUp()
 {
     $this->check = new CodeParseCheck((new ParserFactory())->create(ParserFactory::PREFER_PHP7));
     $this->assertEquals('Code Parse Check', $this->check->getName());
     $this->assertEquals(ExerciseInterface::class, $this->check->getExerciseInterface());
     $this->assertTrue($this->check->canRun(ExerciseType::CGI()));
     $this->assertTrue($this->check->canRun(ExerciseType::CLI()));
     $this->file = sprintf('%s/%s/submission.php', str_replace('\\', '/', sys_get_temp_dir()), $this->getName());
     mkdir(dirname($this->file), 0775, true);
     touch($this->file);
 }
 public function setUp()
 {
     $containerBuilder = new ContainerBuilder();
     $containerBuilder->addDefinitions(__DIR__ . '/../../app/config.php');
     $container = $containerBuilder->build();
     $this->checkRepository = $container->get(CheckRepository::class);
     $this->check = new DatabaseCheck();
     $this->exercise = $this->createMock(DatabaseExerciseInterface::class);
     $this->exercise->expects($this->any())->method('getType')->willReturn(ExerciseType::CLI());
     $this->dbDir = sprintf('%s/PhpSchool_PhpWorkshop_Check_DatabaseCheck', str_replace('\\', '/', realpath(sys_get_temp_dir())));
     $this->assertEquals('Database Verification Check', $this->check->getName());
     $this->assertEquals(DatabaseExerciseCheck::class, $this->check->getExerciseInterface());
 }
 public function testExerciseIsPrintedIfAssigned()
 {
     $file = tempnam(sys_get_temp_dir(), 'pws');
     file_put_contents($file, '### Exercise 1');
     $exercise = $this->prophesize(CliExerciseInterface::class);
     $exercise->getProblem()->willReturn($file);
     $exercise->getType()->willReturn(ExerciseType::CLI());
     $exercise->getName()->willReturn('some-exercise');
     $repo = new ExerciseRepository([$exercise->reveal()]);
     $state = new UserState();
     $state->setCurrentExercise('some-exercise');
     $output = $this->createMock(OutputInterface::class);
     $renderer = $this->createMock(MarkdownRenderer::class);
     $renderer->expects($this->once())->method('render')->with('### Exercise 1')->will($this->returnValue('### Exercise 1'));
     $output->expects($this->once())->method('write')->with('### Exercise 1');
     $command = new PrintCommand('phpschool', $repo, $state, $renderer, $output);
     $command->__invoke();
     unlink($file);
 }
 public function testAlteringDatabaseInSolutionDoesNotEffectDatabaseInUserSolution()
 {
     $solution = SingleFileSolution::fromFile(realpath(__DIR__ . '/../res/database/solution-alter-db.php'));
     $this->exercise->expects($this->once())->method('getSolution')->will($this->returnValue($solution));
     $this->exercise->expects($this->any())->method('getArgs')->will($this->returnValue([]));
     $this->exercise->expects($this->atLeastOnce())->method('getType')->will($this->returnValue(ExerciseType::CLI()));
     $this->exercise->expects($this->once())->method('configure')->will($this->returnCallback(function (ExerciseDispatcher $dispatcher) {
         $dispatcher->requireCheck(DatabaseCheck::class);
     }));
     $this->exercise->expects($this->once())->method('seed')->with($this->isInstanceOf(PDO::class))->will($this->returnCallback(function (PDO $db) {
         $db->exec('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER, gender TEXT)');
         $stmt = $db->prepare('INSERT into users (name, age, gender) VALUES (:name, :age, :gender)');
         $stmt->execute([':name' => 'Jimi Hendrix', ':age' => 27, ':gender' => 'Male']);
     }));
     $this->exercise->expects($this->once())->method('verify')->with($this->isInstanceOf(PDO::class))->will($this->returnCallback(function (PDO $db) {
         $users = $db->query('SELECT * FROM users');
         $users = $users->fetchAll(PDO::FETCH_ASSOC);
         $this->assertEquals([['id' => 1, 'name' => 'Jimi Hendrix', 'age' => '27', 'gender' => 'Male'], ['id' => 2, 'name' => 'Kurt Cobain', 'age' => '27', 'gender' => 'Male']], $users);
     }));
     $results = new ResultAggregator();
     $eventDispatcher = new EventDispatcher($results);
     $checkRepository = new CheckRepository([$this->check]);
     $dispatcher = new ExerciseDispatcher(new RunnerFactory(), $results, $eventDispatcher, $checkRepository);
     $dispatcher->verify($this->exercise, __DIR__ . '/../res/database/user-solution-alter-db.php');
 }
 /**
  * @return ExerciseType
  */
 public function getType()
 {
     return ExerciseType::CLI();
 }
 /**
  * This check can run on any exercise type.
  *
  * @param ExerciseType $exerciseType
  * @return bool
  */
 public function canRun(ExerciseType $exerciseType)
 {
     return in_array($exerciseType->getValue(), [ExerciseType::CGI, ExerciseType::CLI]);
 }
 public function testOldDataWillNotBeMigratedWhenNotInCorrectWorkshopWithOtherWorkshop()
 {
     $oldSave = sprintf('%s/.phpschool.json', $this->tmpDir);
     $newSave = sprintf('%s/.phpschool-save.json', $this->tmpDir);
     $exercise1 = $this->prophesize(CliExerciseInterface::class);
     $exercise2 = $this->prophesize(CliExerciseInterface::class);
     $exercise1->getType()->willReturn(ExerciseType::CLI());
     $exercise2->getType()->willReturn(ExerciseType::CLI());
     $exercise1->getName()->willReturn('Exercise 1');
     $exercise2->getName()->willReturn('Exercise 2');
     $exercises = [$exercise1->reveal(), $exercise2->reveal()];
     $repo = new ExerciseRepository($exercises);
     $oldData = ['current_exercise' => 'Exercise 3', 'completed_exercises' => ['Exercise 1 from a diff workshop', 'Exercise 2 from a diff workshop']];
     $newData = ['My Workshop' => ['current_exercise' => 'Exercise 2', 'completed_exercises' => ['Exercise 1']]];
     mkdir($this->tmpDir, 0777, true);
     file_put_contents($oldSave, json_encode($oldData));
     file_put_contents($newSave, json_encode($newData));
     $serializer = new UserStateSerializer($this->tmpDir, $this->workshopName, $repo);
     $state = $serializer->deSerialize();
     $this->assertEquals(['Exercise 1'], $state->getCompletedExercises());
     $this->assertEquals('Exercise 2', $state->getCurrentExercise());
     $expected = ['current_exercise' => 'Exercise 3', 'completed_exercises' => ['Exercise 1 from a diff workshop', 'Exercise 2 from a diff workshop']];
     $this->assertFileExists($oldSave);
     $this->assertEquals($expected, json_decode(file_get_contents($oldSave), true));
     $this->assertFileExists($newSave);
     $this->assertEquals($newData, json_decode(file_get_contents($newSave), true));
     unlink($oldSave);
 }
 /**
  * Return the type of exercise. This is an ENUM. See `PhpSchool\PhpWorkshop\Exercise\ExerciseType`.
  *
  * @return ExerciseType
  */
 public function getType()
 {
     return ExerciseType::CUSTOM();
 }