diff --git a/app/config.php b/app/config.php index 9846ea0f..b96c1db3 100644 --- a/app/config.php +++ b/app/config.php @@ -4,6 +4,7 @@ use Colors\Color; use PhpSchool\PhpWorkshop\Check\FileComparisonCheck; +use PhpSchool\PhpWorkshop\ExerciseRunner\Factory\ServerRunnerFactory; use PhpSchool\PhpWorkshop\Listener\InitialCodeListener; use PhpSchool\PhpWorkshop\Listener\TearDownListener; use PhpSchool\PhpWorkshop\Logger\ConsoleLogger; @@ -96,6 +97,9 @@ 'currentWorkingDirectory' => function (ContainerInterface $c) { return getcwd(); }, + 'basePath' => DI\decorate(function (string $previous) { + return canonicalise_path($previous); + }), WorkshopType::class => WorkshopType::STANDARD(), Psr\Log\LoggerInterface::class => function (ContainerInterface $c) { $appName = $c->get('appName'); @@ -150,7 +154,7 @@ return $colors; }, OutputInterface::class => function (ContainerInterface $c) { - return new StdOutput($c->get(Color::class), $c->get(Terminal::class)); + return new StdOutput($c->get(Color::class), $c->get(Terminal::class), $c->get('basePath')); }, ExerciseRepository::class => function (ContainerInterface $c) { @@ -166,10 +170,10 @@ //Exercise Runners RunnerManager::class => function (ContainerInterface $c) { - $manager = new RunnerManager; + $manager = new RunnerManager(); $manager->addFactory(new CliRunnerFactory($c->get(EventDispatcher::class))); $manager->addFactory(new CgiRunnerFactory($c->get(EventDispatcher::class), $c->get(RequestRenderer::class))); - $manager->addFactory(new CustomVerifyingRunnerFactory); + $manager->addFactory(new CustomVerifyingRunnerFactory()); return $manager; }, diff --git a/src/Application.php b/src/Application.php index 4e3c8a03..0f104b45 100644 --- a/src/Application.php +++ b/src/Application.php @@ -204,9 +204,9 @@ public function configure(bool $debugMode = false): ContainerInterface } } - set_error_handler(function () use ($container): bool { - $this->tearDown($container); - return false; // Use default error handler + //turn all notices & warnings in to exceptions + set_error_handler(function (int $severity, string $message, string $file, int $line) { + throw new \ErrorException($message, 0, $severity, $file, $line); }); $this->container = $container; @@ -259,12 +259,7 @@ public function run(): int $container ->get(OutputInterface::class) - ->printError( - sprintf( - '%s', - $message - ) - ); + ->printException($e); return 1; } @@ -280,13 +275,18 @@ public function run(): int private function getContainer(bool $debugMode): Container { $containerBuilder = new ContainerBuilder(); - $containerBuilder->addDefinitions( - array_merge_recursive( - require $this->frameworkConfigLocation, - require $this->diConfigFile - ) + $diConfig = require $this->diConfigFile; + $fwConfig = require $this->frameworkConfigLocation; + + $fwConfig['eventListeners'] = array_merge_recursive( + $fwConfig['eventListeners'], + $diConfig['eventListeners'] ?? [] ); + unset($diConfig['eventListeners']); + + $containerBuilder->addDefinitions($diConfig, $fwConfig); + $containerBuilder->addDefinitions( [ 'workshopTitle' => $this->workshopTitle, diff --git a/src/Check/CodeExistsCheck.php b/src/Check/CodeExistsCheck.php index a7277db8..859e3d29 100644 --- a/src/Check/CodeExistsCheck.php +++ b/src/Check/CodeExistsCheck.php @@ -52,7 +52,7 @@ public function handleError(Error $error): void if (!$empty) { $openingTag = is_array($statements) && count($statements) === 1 ? $statements[0] : null; - $empty = $openingTag instanceof InlineHTML ? in_array($openingTag->value, ['value, ['getInitialCode()->getFiles() as $file) { - /** @var SolutionFile $file */ if (!file_exists($this->workingDirectory . '/' . $file->getRelativePath())) { copy($file->getAbsolutePath(), $this->workingDirectory . '/' . $file->getRelativePath()); $message = 'File successfully copied to working directory'; diff --git a/src/Logger/Logger.php b/src/Logger/Logger.php index 98c03e37..9716bdaa 100644 --- a/src/Logger/Logger.php +++ b/src/Logger/Logger.php @@ -21,7 +21,7 @@ public function __construct(string $filePath) public function log($level, $message, array $context = []): void { - if (!file_exists($this->filePath)) { + if (!file_exists(dirname($this->filePath))) { if (!mkdir($concurrentDirectory = dirname($this->filePath), 0777, true) && !is_dir($concurrentDirectory)) { throw new \RuntimeException(sprintf('Directory "%s" was not created', $concurrentDirectory)); } diff --git a/src/Output/NullOutput.php b/src/Output/NullOutput.php index d49a7d11..658804f6 100644 --- a/src/Output/NullOutput.php +++ b/src/Output/NullOutput.php @@ -4,6 +4,8 @@ namespace PhpSchool\PhpWorkshop\Output; +use Throwable; + class NullOutput implements OutputInterface { public function printError(string $error): void @@ -11,6 +13,11 @@ public function printError(string $error): void // noop } + public function printException(Throwable $exception): void + { + // noop + } + public function write(string $content): void { // noop diff --git a/src/Output/OutputInterface.php b/src/Output/OutputInterface.php index 745055b3..03b33ce1 100644 --- a/src/Output/OutputInterface.php +++ b/src/Output/OutputInterface.php @@ -4,6 +4,8 @@ namespace PhpSchool\PhpWorkshop\Output; +use Throwable; + /** * Output interface */ @@ -17,6 +19,14 @@ interface OutputInterface */ public function printError(string $error): void; + /** + * Write an Exception. Should be decorated in someway + * which highlights the severity. + * + * @param Throwable $exception + */ + public function printException(Throwable $exception): void; + /** * Write a string to the output. * diff --git a/src/Output/StdOutput.php b/src/Output/StdOutput.php index 2bc15178..35119b21 100644 --- a/src/Output/StdOutput.php +++ b/src/Output/StdOutput.php @@ -6,6 +6,7 @@ use Colors\Color; use PhpSchool\Terminal\Terminal; +use Throwable; /** * Console output interface @@ -22,10 +23,16 @@ class StdOutput implements OutputInterface */ private $terminal; - public function __construct(Color $color, Terminal $terminal) + /** + * @var string + */ + private $workshopBasePath; + + public function __construct(Color $color, Terminal $terminal, string $workshopBasePath = '') { $this->color = $color; $this->terminal = $terminal; + $this->workshopBasePath = $workshopBasePath; } /** @@ -41,6 +48,51 @@ public function printError(string $error): void echo "\n"; } + /** + * @param Throwable $exception + */ + public function printException(Throwable $exception): void + { + $message = $exception->getMessage(); + if (strpos($message, $this->workshopBasePath) !== null) { + $message = str_replace($this->workshopBasePath, '', $message); + } + + $file = $exception->getFile(); + if (strpos($file, $this->workshopBasePath) !== null) { + $file = str_replace($this->workshopBasePath, '', $file); + } + + $lines = [ + sprintf("In %s line %d:", $file, $exception->getLine()), + sprintf("[%s (%s)]:", get_class($exception), $exception->getCode()), + '', + $message + ]; + + $length = max(array_map('strlen', $lines)) + 2; + $this->emptyLine(); + $this->writeLine(' ' . $this->color->__invoke(str_repeat(' ', $length))->bg_red()); + + foreach ($lines as $line) { + $line = str_pad($line, $length - 2, ' ', STR_PAD_RIGHT); + $this->writeLine(' ' . $this->color->__invoke(" $line ")->bg_red()->white()->bold()); + } + + $this->writeLine(' ' . $this->color->__invoke(str_repeat(' ', $length))->bg_red()); + $this->emptyLine(); + + $this->writeLine( + implode( + "\n", + array_map(function ($l) { + return " $l"; + }, + explode("\n", $exception->getTraceAsString())) + ) + ); + } + /** * Write a title section. Should be decorated in a way which makes * the title stand out. diff --git a/src/UserStateSerializer.php b/src/UserStateSerializer.php index 5133fd31..f7991386 100644 --- a/src/UserStateSerializer.php +++ b/src/UserStateSerializer.php @@ -204,6 +204,8 @@ private function readJson(string $filePath): ?array */ private function wipeFile(): void { - @unlink($this->path); + if (file_exists(sprintf('%s/%s', $this->path, static::SAVE_FILE))) { + unlink(sprintf('%s/%s', $this->path, static::SAVE_FILE)); + } } } diff --git a/test/ApplicationTest.php b/test/ApplicationTest.php index 79ea9e1f..dd43f743 100644 --- a/test/ApplicationTest.php +++ b/test/ApplicationTest.php @@ -100,7 +100,7 @@ public function testExceptionIsThrownIfResultRendererClassDoesNotExist(): void public function testTearDownEventIsFiredOnApplicationException(): void { - $configFile = $this->getTemporaryFile('config.php', 'getTemporaryFile('config.php', ' __DIR__ . "../"];'); $application = new Application('Testing TearDown', $configFile); $container = $application->configure(); @@ -125,7 +125,7 @@ public function testTearDownEventIsFiredOnApplicationException(): void public function testLoggingExceptionDuringTearDown(): void { - $configFile = $this->getTemporaryFile('config.php', 'getTemporaryFile('config.php', ' __DIR__ . "../"];'); $application = new Application('Testing tear down logging', $configFile); $exception = new \Exception('Unexpected error'); @@ -159,7 +159,7 @@ static function () use ($exception) { public function testConfigureReturnsSameContainerInstance(): void { - $configFile = $this->getTemporaryFile('config.php', 'getTemporaryFile('config.php', ' __DIR__ . "../"];'); $application = new Application('Testing Configure', $configFile); self::assertSame($application->configure(), $application->configure()); @@ -167,7 +167,7 @@ public function testConfigureReturnsSameContainerInstance(): void public function testDebugFlagSwitchesLoggerToConsoleLogger(): void { - $configFile = $this->getTemporaryFile('config.php', 'getTemporaryFile('config.php', ' __DIR__ . "../"];'); $application = new Application('My workshop', $configFile); $container = $application->configure(true); diff --git a/test/BaseTest.php b/test/BaseTest.php index d25b9061..112d3940 100644 --- a/test/BaseTest.php +++ b/test/BaseTest.php @@ -44,8 +44,8 @@ public function getTemporaryFile(string $filename, string $content = null): stri public function tearDown(): void { - if ($this->tempDirectory) { - (new Filesystem())->remove($this->tempDirectory); + if (file_exists(System::tempDir($this->getName()))) { + (new Filesystem())->remove(System::tempDir($this->getName())); } } } diff --git a/test/Logger/ConsoleLoggerTest.php b/test/Logger/ConsoleLoggerTest.php index 71857270..73371e48 100644 --- a/test/Logger/ConsoleLoggerTest.php +++ b/test/Logger/ConsoleLoggerTest.php @@ -18,6 +18,7 @@ public function setUp(): void $this->container->set('phpschoolGlobalDir', $this->getTemporaryDirectory()); $this->container->set('appName', 'my-workshop'); + $this->container->set('basePath', __DIR__ . '/../'); $this->container->set('debugMode', true); } diff --git a/test/ResultRenderer/ResultsRendererTest.php b/test/ResultRenderer/ResultsRendererTest.php index f853fbaf..7494e290 100644 --- a/test/ResultRenderer/ResultsRendererTest.php +++ b/test/ResultRenderer/ResultsRendererTest.php @@ -7,6 +7,7 @@ use Kadet\Highlighter\KeyLighter; use Kadet\Highlighter\Language\Php; use PhpSchool\PhpWorkshopTest\Asset\CliExerciseImpl; +use PhpSchool\PhpWorkshopTest\BaseTest; use PhpSchool\Terminal\Terminal; use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface; use PhpSchool\PhpWorkshop\Exercise\ProvidesSolution; @@ -22,7 +23,7 @@ use PhpSchool\PhpWorkshop\UserState; use PHPUnit\Framework\TestCase; -class ResultsRendererTest extends TestCase +class ResultsRendererTest extends BaseTest { public function testRenderIndividualResult(): void { @@ -118,9 +119,7 @@ public function testRenderSuccessWithSolution(): void $exerciseRepo = $this->createMock(ExerciseRepository::class); $exerciseRepo->method('count')->willReturn(2); - $tmpFile = sprintf('%s/%s/some-file', sys_get_temp_dir(), $this->getName()); - mkdir(dirname($tmpFile)); - file_put_contents($tmpFile, 'FILE CONTENTS'); + $tmpFile = $this->getTemporaryFile('some-file', 'FILE CONTENTS'); $exercise = new CliExerciseImpl(); $exercise->setSolution(new SingleFileSolution($tmpFile)); @@ -146,9 +145,6 @@ public function testRenderSuccessWithSolution(): void new UserState(['exercise1']), new StdOutput($color, $terminal) ); - - unlink($tmpFile); - rmdir(dirname($tmpFile)); } public function testRenderSuccessWithPhpSolutionFileIsSyntaxHighlighted(): void @@ -164,9 +160,7 @@ public function testRenderSuccessWithPhpSolutionFileIsSyntaxHighlighted(): void $exerciseRepo = $this->createMock(ExerciseRepository::class); $exerciseRepo->method('count')->willReturn(2); - $tmpFile = sprintf('%s/%s/some-file.php', sys_get_temp_dir(), $this->getName()); - mkdir(dirname($tmpFile)); - file_put_contents($tmpFile, 'FILE CONTENTS'); + $tmpFile = $this->getTemporaryFile('some-file.php', 'FILE CONTENTS'); $exercise = new CliExerciseImpl(); $exercise->setSolution(new SingleFileSolution($tmpFile)); @@ -200,9 +194,6 @@ public function testRenderSuccessWithPhpSolutionFileIsSyntaxHighlighted(): void new UserState(['exercise1']), new StdOutput($color, $terminal) ); - - unlink($tmpFile); - rmdir(dirname($tmpFile)); } public function testRenderSuccessAndFailure(): void diff --git a/test/UserStateSerializerTest.php b/test/UserStateSerializerTest.php index 17549bbe..0cbae920 100644 --- a/test/UserStateSerializerTest.php +++ b/test/UserStateSerializerTest.php @@ -6,11 +6,12 @@ use PhpSchool\PhpWorkshop\ExerciseRepository; use PhpSchool\PhpWorkshop\UserState; use PhpSchool\PhpWorkshop\UserStateSerializer; +use PhpSchool\PhpWorkshop\Utils\Path; +use PhpSchool\PhpWorkshop\Utils\System; use PhpSchool\PhpWorkshopTest\Asset\CliExerciseInterface; -use PHPUnit\Framework\TestCase; use Yoast\PHPUnitPolyfills\Polyfills\AssertionRenames; -class UserStateSerializerTest extends TestCase +class UserStateSerializerTest extends BaseTest { use AssertionRenames; @@ -36,29 +37,29 @@ class UserStateSerializerTest extends TestCase public function setUp(): void { - $this->tmpDir = sprintf('%s/%s/%s', sys_get_temp_dir(), $this->getName(), random_int(1, 100)); - $this->tmpFile = sprintf('%s/.phpschool-save.json', $this->tmpDir); $this->exerciseRepository = new ExerciseRepository([]); } public function testIfDirNotExistsItIsCreated(): void { - $this->assertFileDoesNotExist($this->tmpDir); - new UserStateSerializer($this->tmpDir, $this->workshopName, $this->exerciseRepository); - $this->assertFileExists($this->tmpDir); + self::assertFileDoesNotExist(System::tempDir($this->getName())); + new UserStateSerializer(System::tempDir($this->getName()), $this->workshopName, $this->exerciseRepository); + $this->assertFileExists(System::tempDir($this->getName())); } public function testConstructWhenFileExists(): void { - mkdir($this->tmpDir, 0777, true); - $this->assertFileExists($this->tmpDir); - new UserStateSerializer($this->tmpDir, $this->workshopName, $this->exerciseRepository); + $this->assertFileExists($this->getTemporaryDirectory()); + new UserStateSerializer($this->getTemporaryDirectory(), $this->workshopName, $this->exerciseRepository); } public function testSerializeEmptySate(): void { - mkdir($this->tmpDir, 0777, true); - $serializer = new UserStateSerializer($this->tmpDir, $this->workshopName, $this->exerciseRepository); + $serializer = new UserStateSerializer( + $this->getTemporaryDirectory(), + $this->workshopName, + $this->exerciseRepository + ); $state = new UserState(); @@ -70,13 +71,16 @@ public function testSerializeEmptySate(): void ]); $serializer->serialize($state); - $this->assertSame($expected, file_get_contents($this->tmpFile)); + $this->assertSame($expected, file_get_contents($this->getTemporaryFile('.phpschool-save.json'))); } public function testSerialize(): void { - mkdir($this->tmpDir, 0777, true); - $serializer = new UserStateSerializer($this->tmpDir, $this->workshopName, $this->exerciseRepository); + $serializer = new UserStateSerializer( + $this->getTemporaryDirectory(), + $this->workshopName, + $this->exerciseRepository + ); $state = new UserState(['exercise1'], 'exercise2'); $serializer->serialize($state); @@ -90,13 +94,17 @@ public function testSerialize(): void $serializer->serialize($state); - $this->assertSame($expected, file_get_contents($this->tmpFile)); + $this->assertSame($expected, file_get_contents($this->getTemporaryFile('.phpschool-save.json'))); } public function testDeserializeNonExistingFile(): void { - mkdir($this->tmpDir, 0777, true); - $serializer = new UserStateSerializer($this->tmpDir, $this->workshopName, $this->exerciseRepository); + $serializer = new UserStateSerializer( + $this->getTemporaryDirectory(), + $this->workshopName, + $this->exerciseRepository + ); + $state = $serializer->deSerialize(); $this->assertFalse($state->isAssignedExercise()); $this->assertEmpty($state->getCompletedExercises()); @@ -104,9 +112,12 @@ public function testDeserializeNonExistingFile(): void public function testDeserializeEmptyFile(): void { - mkdir($this->tmpDir, 0777, true); - file_put_contents($this->tmpFile, ''); - $serializer = new UserStateSerializer($this->tmpDir, $this->workshopName, $this->exerciseRepository); + $this->getTemporaryFile('.phpschool-save.json', ''); + $serializer = new UserStateSerializer( + $this->getTemporaryDirectory(), + $this->workshopName, + $this->exerciseRepository + ); $state = $serializer->deSerialize(); $this->assertFalse($state->isAssignedExercise()); $this->assertEmpty($state->getCompletedExercises()); @@ -114,9 +125,12 @@ public function testDeserializeEmptyFile(): void public function testDeserializeNonValidJson(): void { - mkdir($this->tmpDir, 0777, true); - file_put_contents($this->tmpFile, 'yayayayayanotjson'); - $serializer = new UserStateSerializer($this->tmpDir, $this->workshopName, $this->exerciseRepository); + $this->getTemporaryFile('.phpschool-save.json', 'yayayayayanotjson'); + $serializer = new UserStateSerializer( + $this->getTemporaryDirectory(), + $this->workshopName, + $this->exerciseRepository + ); $state = $serializer->deSerialize(); $this->assertFalse($state->isAssignedExercise()); $this->assertEmpty($state->getCompletedExercises()); @@ -127,9 +141,12 @@ public function testDeserializeNonValidJson(): void */ public function testDeserialize(array $data, array $expected): void { - mkdir($this->tmpDir, 0777, true); - file_put_contents($this->tmpFile, json_encode($data)); - $serializer = new UserStateSerializer($this->tmpDir, $this->workshopName, $this->exerciseRepository); + $this->getTemporaryFile('.phpschool-save.json', json_encode($data)); + $serializer = new UserStateSerializer( + $this->getTemporaryDirectory(), + $this->workshopName, + $this->exerciseRepository + ); $state = $serializer->deSerialize(); $this->assertEquals($expected['completed_exercises'], $state->getCompletedExercises()); @@ -137,11 +154,6 @@ public function testDeserialize(array $data, array $expected): void $expected['current_exercise'], $state->isAssignedExercise() ? $state->getCurrentExercise() : null ); - - if (file_exists($this->tmpFile)) { - unlink($this->tmpFile); - } - rmdir($this->tmpDir); } public function deserializerProvider(): array @@ -188,9 +200,6 @@ public function deserializerProvider(): array public function testOldDataWillBeMigratedWhenInCorrectWorkshop(): void { - $oldSave = sprintf('%s/.phpschool.json', $this->tmpDir); - $newSave = sprintf('%s/.phpschool-save.json', $this->tmpDir); - $exercise1 = $this->createMock(CliExerciseInterface::class); $exercise2 = $this->createMock(CliExerciseInterface::class); $exercise1->method('getType')->willReturn(ExerciseType::CLI()); @@ -198,22 +207,22 @@ public function testOldDataWillBeMigratedWhenInCorrectWorkshop(): void $exercise1->method('getName')->willReturn('Exercise 1'); $exercise2->method('getName')->willReturn('Exercise 2'); - $exercises = [ - $exercise1, - $exercise2 - ]; - - $repo = new ExerciseRepository($exercises); - $oldData = [ 'current_exercise' => 'Exercise 3', 'completed_exercises' => ['Exercise 1', 'Exercise 2'], ]; - mkdir($this->tmpDir, 0777, true); - file_put_contents($oldSave, json_encode($oldData)); + $oldSave = $this->getTemporaryFile('.phpschool.json', json_encode($oldData)); + + $serializer = new UserStateSerializer( + $this->getTemporaryDirectory(), + $this->workshopName, + new ExerciseRepository([ + $exercise1, + $exercise2 + ]) + ); - $serializer = new UserStateSerializer($this->tmpDir, $this->workshopName, $repo); $state = $serializer->deSerialize(); $this->assertEquals(['Exercise 1', 'Exercise 2'], $state->getCompletedExercises()); @@ -226,16 +235,16 @@ public function testOldDataWillBeMigratedWhenInCorrectWorkshop(): void ], ]; - $this->assertFileDoesNotExist($oldSave); - $this->assertFileExists($newSave); - $this->assertEquals($expected, json_decode(file_get_contents($newSave), true)); + self::assertFileDoesNotExist($oldSave); + $this->assertFileExists(Path::join($this->getTemporaryDirectory(), '.phpschool-save.json')); + $this->assertEquals( + $expected, + json_decode(file_get_contents($this->getTemporaryFile('.phpschool-save.json')), true) + ); } public function testOldDataWillNotBeMigratedWhenNotInCorrectWorkshop(): void { - $oldSave = sprintf('%s/.phpschool.json', $this->tmpDir); - $newSave = sprintf('%s/.phpschool-save.json', $this->tmpDir); - $exercise1 = $this->createMock(CliExerciseInterface::class); $exercise2 = $this->createMock(CliExerciseInterface::class); $exercise1->method('getType')->willReturn(ExerciseType::CLI()); @@ -254,10 +263,9 @@ public function testOldDataWillNotBeMigratedWhenNotInCorrectWorkshop(): void 'completed_exercises' => ['Exercise 1 from a diff workshop', 'Exercise 2 from a diff workshop'], ]; - mkdir($this->tmpDir, 0777, true); - file_put_contents($oldSave, json_encode($oldData)); + $oldSave = $this->getTemporaryFile('.phpschool.json', json_encode($oldData)); - $serializer = new UserStateSerializer($this->tmpDir, $this->workshopName, $repo); + $serializer = new UserStateSerializer($this->getTemporaryDirectory(), $this->workshopName, $repo); $state = $serializer->deSerialize(); $this->assertEquals([], $state->getCompletedExercises()); @@ -265,16 +273,11 @@ public function testOldDataWillNotBeMigratedWhenNotInCorrectWorkshop(): void $this->assertFileExists($oldSave); $this->assertEquals($oldData, json_decode(file_get_contents($oldSave), true)); - $this->assertFileDoesNotExist($newSave); - - unlink($oldSave); + $this->assertFileDoesNotExist(Path::join($this->getTemporaryDirectory(), '.phpschool-save.json')); } public function testOldDataWillNotBeMigratedWhenNotInCorrectWorkshopWithOtherWorkshop(): void { - $oldSave = sprintf('%s/.phpschool.json', $this->tmpDir); - $newSave = sprintf('%s/.phpschool-save.json', $this->tmpDir); - $exercise1 = $this->createMock(CliExerciseInterface::class); $exercise2 = $this->createMock(CliExerciseInterface::class); $exercise1->method('getType')->willReturn(ExerciseType::CLI()); @@ -282,13 +285,6 @@ public function testOldDataWillNotBeMigratedWhenNotInCorrectWorkshopWithOtherWor $exercise1->method('getName')->willReturn('Exercise 1'); $exercise2->method('getName')->willReturn('Exercise 2'); - $exercises = [ - $exercise1, - $exercise2 - ]; - - $repo = new ExerciseRepository($exercises); - $oldData = [ 'current_exercise' => 'Exercise 3', 'completed_exercises' => ['Exercise 1 from a diff workshop', 'Exercise 2 from a diff workshop'], @@ -301,11 +297,17 @@ public function testOldDataWillNotBeMigratedWhenNotInCorrectWorkshopWithOtherWor ], ]; - mkdir($this->tmpDir, 0777, true); - file_put_contents($oldSave, json_encode($oldData)); - file_put_contents($newSave, json_encode($newData)); + $oldSave = $this->getTemporaryFile('.phpschool.json', json_encode($oldData)); + $newSave = $this->getTemporaryFile('.phpschool-save.json', json_encode($newData)); - $serializer = new UserStateSerializer($this->tmpDir, $this->workshopName, $repo); + $serializer = new UserStateSerializer( + $this->getTemporaryDirectory(), + $this->workshopName, + new ExerciseRepository([ + $exercise1, + $exercise2 + ]) + ); $state = $serializer->deSerialize(); $this->assertEquals(['Exercise 1'], $state->getCompletedExercises()); @@ -321,18 +323,5 @@ public function testOldDataWillNotBeMigratedWhenNotInCorrectWorkshopWithOtherWor $this->assertFileExists($newSave); $this->assertEquals($newData, json_decode(file_get_contents($newSave), true)); - - unlink($oldSave); - } - - public function tearDown(): void - { - if (file_exists($this->tmpFile)) { - unlink($this->tmpFile); - } - - if (file_exists($this->tmpDir)) { - rmdir($this->tmpDir); - } } }