-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
be53db0
commit 5c95d08
Showing
9 changed files
with
423 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<?php | ||
|
||
namespace PhpSchool\PhpWorkshop\Exercise; | ||
|
||
use PhpSchool\PhpWorkshop\ExerciseDispatcher; | ||
|
||
class MockExercise extends AbstractExercise implements ExerciseInterface | ||
{ | ||
public function getName(): string | ||
{ | ||
return 'Mock Exercise'; | ||
} | ||
|
||
public function getDescription(): string | ||
{ | ||
return 'Mock Exercise'; | ||
} | ||
|
||
public function getType(): ExerciseType | ||
{ | ||
return ExerciseType::CUSTOM(); | ||
} | ||
|
||
public function getProblem(): string | ||
{ | ||
return 'problem-file.md'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
<?php | ||
|
||
namespace PhpSchool\PhpWorkshop\ExerciseRunner\Context; | ||
|
||
use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface; | ||
use PhpSchool\PhpWorkshop\Input\Input; | ||
use PhpSchool\PhpWorkshop\Utils\Path; | ||
use PhpSchool\PhpWorkshop\Utils\System; | ||
|
||
class ExecutionContext | ||
{ | ||
public function __construct( | ||
private string $studentExecutionDirectory, | ||
private string $referenceExecutionDirectory, | ||
private ExerciseInterface $exercise, | ||
private Input $input, | ||
) { | ||
} | ||
|
||
public function getExercise(): ExerciseInterface | ||
{ | ||
return $this->exercise; | ||
} | ||
|
||
public function getInput(): Input | ||
{ | ||
return $this->input; | ||
} | ||
|
||
public function hasStudentSolution(): bool | ||
{ | ||
return $this->input->hasArgument('program'); | ||
} | ||
|
||
public function getEntryPoint(): string | ||
{ | ||
if (!$this->hasStudentSolution()) { | ||
throw new NoEntryPoint(); | ||
} | ||
|
||
return Path::join( | ||
$this->studentExecutionDirectory, | ||
basename($this->input->getRequiredArgument('program')) | ||
); | ||
} | ||
|
||
public function getStudentExecutionDirectory(): string | ||
{ | ||
return $this->studentExecutionDirectory; | ||
} | ||
|
||
public function getReferenceExecutionDirectory(): string | ||
{ | ||
return $this->referenceExecutionDirectory; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<?php | ||
|
||
namespace PhpSchool\PhpWorkshop\ExerciseRunner\Context; | ||
|
||
use PhpSchool\PhpWorkshop\Exception\RuntimeException; | ||
|
||
class NoEntryPoint extends RuntimeException | ||
{ | ||
public function __construct() | ||
{ | ||
parent::__construct('No entry point provided'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
<?php | ||
|
||
namespace PhpSchool\PhpWorkshop\ExerciseRunner\Context; | ||
|
||
use PhpSchool\PhpWorkshop\Exception\RuntimeException; | ||
use PhpSchool\PhpWorkshop\Exercise\CgiExercise; | ||
use PhpSchool\PhpWorkshop\Exercise\CliExercise; | ||
use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface; | ||
use PhpSchool\PhpWorkshop\Exercise\MockExercise; | ||
use PhpSchool\PhpWorkshop\Input\Input; | ||
use PhpSchool\PhpWorkshop\Solution\SolutionInterface; | ||
use PhpSchool\PhpWorkshop\Utils\System; | ||
use Symfony\Component\Filesystem\Filesystem; | ||
use PhpSchool\PhpWorkshop\Utils\Path; | ||
|
||
class TestContext extends ExecutionContext | ||
{ | ||
private Filesystem $filesystem; | ||
private ExerciseInterface $exercise; | ||
private bool $studentSolutionDirWasCreated = false; | ||
private bool $referenceSolutionDirWasCreated = false; | ||
|
||
public function __construct( | ||
ExerciseInterface $exercise = null, | ||
Input $input = null, | ||
string $studentDirectory = null, | ||
) { | ||
$this->exercise = $exercise ?? new MockExercise(); | ||
|
||
$this->filesystem = new Filesystem(); | ||
|
||
if ($studentDirectory === null) { | ||
$studentDirectory = System::randomTempDir(); | ||
} | ||
|
||
parent::__construct( | ||
$studentDirectory, | ||
System::randomTempDir(), | ||
$this->exercise, | ||
$input ? $input : new Input('test', ['program' => 'solution.php']), | ||
); | ||
} | ||
|
||
public function createStudentSolutionDirectory(): void | ||
{ | ||
$this->filesystem->mkdir($this->getStudentExecutionDirectory()); | ||
$this->studentSolutionDirWasCreated = true; | ||
} | ||
|
||
public function createReferenceSolutionDirectory(): void | ||
{ | ||
$this->filesystem->mkdir($this->getReferenceExecutionDirectory()); | ||
$this->referenceSolutionDirWasCreated = true; | ||
} | ||
|
||
public function importStudentFileFromString(string $content, string $filename = 'solution.php'): void | ||
{ | ||
if (!$this->studentSolutionDirWasCreated) { | ||
throw new RuntimeException( | ||
sprintf('Student execution directory not created. Call %s::createStudentSolutionDirectory() first.', self::class) | ||
); | ||
} | ||
|
||
file_put_contents(Path::join($this->getStudentExecutionDirectory(), $filename), $content); | ||
} | ||
|
||
public function importReferenceFileFromString(string $content, string $filename = 'solution.php'): void | ||
{ | ||
if (!$this->referenceSolutionDirWasCreated) { | ||
throw new RuntimeException( | ||
sprintf('Reference execution directory not created. Call %s::createReferenceSolutionDirectory() first.', self::class) | ||
); | ||
} | ||
|
||
file_put_contents(Path::join($this->getReferenceExecutionDirectory(), $filename), $content); | ||
} | ||
|
||
public static function fromExerciseAndStudentSolution(ExerciseInterface $exercise, string $file): self | ||
{ | ||
if (file_exists($file)) { | ||
$file = (string) realpath($file); | ||
} | ||
|
||
$input = new Input('test', ['program' => $file]); | ||
return new self( | ||
exercise: $exercise, | ||
input: $input, | ||
studentDirectory: dirname($file) | ||
); | ||
} | ||
|
||
public function __destruct() | ||
{ | ||
if ($this->studentSolutionDirWasCreated) { | ||
$this->filesystem->remove($this->getStudentExecutionDirectory()); | ||
} | ||
|
||
if ($this->referenceSolutionDirWasCreated) { | ||
$this->filesystem->remove($this->getReferenceExecutionDirectory()); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
<?php | ||
|
||
namespace PhpSchool\PhpWorkshopTest\ExerciseRunner\Context; | ||
|
||
use PhpSchool\PhpWorkshop\Exercise\MockExercise; | ||
use PhpSchool\PhpWorkshop\ExerciseRunner\Context\ExecutionContext; | ||
use PhpSchool\PhpWorkshop\ExerciseRunner\Context\NoEntryPoint; | ||
use PhpSchool\PhpWorkshop\Input\Input; | ||
use PHPUnit\Framework\TestCase; | ||
|
||
class ExecutionContextTest extends TestCase | ||
{ | ||
public function testGetters(): void | ||
{ | ||
$exercise = new MockExercise(); | ||
$input = new Input('test', ['program' => 'solution.php']); | ||
$context = new ExecutionContext( | ||
'/student-dir', | ||
'/reference-dir', | ||
$exercise, | ||
$input | ||
); | ||
|
||
static::assertSame($exercise, $context->getExercise()); | ||
static::assertSame($input, $context->getInput()); | ||
static::assertSame('/student-dir', $context->getStudentExecutionDirectory()); | ||
static::assertSame('/reference-dir', $context->getReferenceExecutionDirectory()); | ||
} | ||
|
||
public function testHasStudentSolution(): void | ||
{ | ||
$exercise = new MockExercise(); | ||
$input = new Input('test', ['program' => 'solution.php']); | ||
$context = new ExecutionContext( | ||
'/student-dir', | ||
'/reference-dir', | ||
$exercise, | ||
$input | ||
); | ||
|
||
static::assertTrue($context->hasStudentSolution()); | ||
|
||
$exercise = new MockExercise(); | ||
$input = new Input('test'); | ||
$context = new ExecutionContext( | ||
'/student-dir', | ||
'/reference-dir', | ||
$exercise, | ||
$input | ||
); | ||
|
||
static::assertFalse($context->hasStudentSolution()); | ||
} | ||
|
||
public function testGetEntryPoint(): void | ||
{ | ||
$exercise = new MockExercise(); | ||
$input = new Input('test', ['program' => 'solution.php']); | ||
$context = new ExecutionContext( | ||
'/student-dir', | ||
'/reference-dir', | ||
$exercise, | ||
$input | ||
); | ||
|
||
static::assertSame('/student-dir/solution.php', $context->getEntryPoint()); | ||
} | ||
|
||
public function testGetEntryPointThrowsExceptionWhenNoStudentSolution(): void | ||
{ | ||
static::expectException(NoEntryPoint::class); | ||
|
||
$exercise = new MockExercise(); | ||
$input = new Input('test'); | ||
$context = new ExecutionContext( | ||
'/student-dir', | ||
'/reference-dir', | ||
$exercise, | ||
$input | ||
); | ||
|
||
$context->getEntryPoint(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?php | ||
|
||
namespace PhpSchool\PhpWorkshopTest\ExerciseRunner\Context; | ||
|
||
use PhpSchool\PhpWorkshop\ExerciseRunner\Context\NoEntryPoint; | ||
use PHPUnit\Framework\TestCase; | ||
|
||
class NoEntryPointTest extends TestCase | ||
{ | ||
public function testException(): void | ||
{ | ||
$e = new NoEntryPoint(); | ||
static::assertSame('No entry point provided', $e->getMessage()); | ||
} | ||
} |
Oops, something went wrong.