From 3226de989cc0d4b4c1a4cb353f0aeeb2768a1df3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20St=C5=99=C3=ADte=C5=BEsk=C3=BD?= Date: Sun, 14 Oct 2018 10:30:56 +0200 Subject: [PATCH 01/13] Add loading input state file --- src/BaseComponent.php | 21 ++++++ tests/BaseComponentTest.php | 71 +++++++++++++++++++ .../empty-state-file/config.json | 1 + .../empty-state-file/in/state.json | 0 .../state-file/config.json | 1 + .../state-file/in/state.json | 12 ++++ .../undefined-state-file/config.json | 1 + 7 files changed, 107 insertions(+) create mode 100644 tests/BaseComponentTest.php create mode 100644 tests/fixtures/base-component-data-dir/empty-state-file/config.json create mode 100644 tests/fixtures/base-component-data-dir/empty-state-file/in/state.json create mode 100644 tests/fixtures/base-component-data-dir/state-file/config.json create mode 100644 tests/fixtures/base-component-data-dir/state-file/in/state.json create mode 100644 tests/fixtures/base-component-data-dir/undefined-state-file/config.json diff --git a/src/BaseComponent.php b/src/BaseComponent.php index f435e32c..87d8f893 100644 --- a/src/BaseComponent.php +++ b/src/BaseComponent.php @@ -32,6 +32,9 @@ class BaseComponent /** @var LoggerInterface */ private $logger; + /** @var array */ + private $inputState; + public function __construct(LoggerInterface $logger) { static::setEnvironment(); @@ -41,6 +44,7 @@ public function __construct(LoggerInterface $logger) $this->setDataDir($dataDir); $this->loadConfig(); + $this->loadInputState(); $this->loadManifestManager(); @@ -85,6 +89,18 @@ protected function loadConfig(): void $this->logger->debug('Config loaded'); } + protected function loadInputState(): void + { + $inputStateFile = $this->getDataDir() . '/in/state.json'; + if (file_exists($inputStateFile)) { + $jsonContents = (string) file_get_contents($inputStateFile); + $jsonEncoder = new JsonEncoder(); + $this->inputState = $jsonEncoder->decode($jsonContents, JsonEncoder::FORMAT); + } else { + $this->inputState = []; + } + } + protected function getRawConfig(): array { $jsonContents = file_get_contents($this->dataDir . '/config.json'); @@ -137,6 +153,11 @@ public function getLogger() : LoggerInterface return $this->logger; } + public function getInputState(): array + { + return $this->inputState; + } + /** * This is the main method for your code to run in. You have the `Config` * and `ManifestManager` ready as well as environment set up. diff --git a/tests/BaseComponentTest.php b/tests/BaseComponentTest.php new file mode 100644 index 00000000..1e2d671d --- /dev/null +++ b/tests/BaseComponentTest.php @@ -0,0 +1,71 @@ +getInputState(); + $this->assertCount(4, $inputStateFile); + + $this->assertArrayHasKey('key1', $inputStateFile); + $this->assertEquals('value1', $inputStateFile['key1']); + + $this->assertArrayHasKey('key2', $inputStateFile); + $this->assertEquals(2, $inputStateFile['key2']); + + $this->assertArrayHasKey('list', $inputStateFile); + $this->assertCount(3, $inputStateFile['list']); + $this->assertEquals('a', $inputStateFile['list'][0]); + $this->assertEquals('b', $inputStateFile['list'][1]); + $this->assertEquals('c', $inputStateFile['list'][2]); + + $this->assertArrayHasKey('dict', $inputStateFile); + $this->assertCount(1, $inputStateFile['dict']); + $this->assertArrayHasKey('key', $inputStateFile['dict']); + $this->assertEquals('value', $inputStateFile['dict']['key']); + } + + public function testLoadInputStateFileEmptyThrowsException(): void + { + putenv(sprintf( + 'KBC_DATADIR=%s', + __DIR__ . '/fixtures/base-component-data-dir/empty-state-file' + )); + + $logger = new Logger(); + + $this->expectException(NotEncodableValueException::class); + $this->expectExceptionMessage('Syntax error'); + new BaseComponent($logger); + } + + public function testLoadInputStateFileUndefined(): void + { + putenv(sprintf( + 'KBC_DATADIR=%s', + __DIR__ . '/fixtures/base-component-data-dir/undefined-state-file' + )); + + $logger = new Logger(); + $baseComponent = new BaseComponent($logger); + + $this->assertEmpty($baseComponent->getInputState()); + } +} diff --git a/tests/fixtures/base-component-data-dir/empty-state-file/config.json b/tests/fixtures/base-component-data-dir/empty-state-file/config.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/tests/fixtures/base-component-data-dir/empty-state-file/config.json @@ -0,0 +1 @@ +{} diff --git a/tests/fixtures/base-component-data-dir/empty-state-file/in/state.json b/tests/fixtures/base-component-data-dir/empty-state-file/in/state.json new file mode 100644 index 00000000..e69de29b diff --git a/tests/fixtures/base-component-data-dir/state-file/config.json b/tests/fixtures/base-component-data-dir/state-file/config.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/tests/fixtures/base-component-data-dir/state-file/config.json @@ -0,0 +1 @@ +{} diff --git a/tests/fixtures/base-component-data-dir/state-file/in/state.json b/tests/fixtures/base-component-data-dir/state-file/in/state.json new file mode 100644 index 00000000..b54a1dd9 --- /dev/null +++ b/tests/fixtures/base-component-data-dir/state-file/in/state.json @@ -0,0 +1,12 @@ +{ + "key1": "value1", + "key2": 2, + "list": [ + "a", + "b", + "c" + ], + "dict": { + "key": "value" + } +} diff --git a/tests/fixtures/base-component-data-dir/undefined-state-file/config.json b/tests/fixtures/base-component-data-dir/undefined-state-file/config.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/tests/fixtures/base-component-data-dir/undefined-state-file/config.json @@ -0,0 +1 @@ +{} From b3e6c25f31dde81f291e98f6f4561dbdb330b1ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20St=C5=99=C3=ADte=C5=BEsk=C3=BD?= Date: Sun, 14 Oct 2018 12:21:18 +0200 Subject: [PATCH 02/13] Add write state file method --- src/BaseComponent.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/BaseComponent.php b/src/BaseComponent.php index 87d8f893..4c2217ab 100644 --- a/src/BaseComponent.php +++ b/src/BaseComponent.php @@ -101,6 +101,21 @@ protected function loadInputState(): void } } + protected function writeOutputStateToFile(array $state): void + { + $outDataDir = $this->getDataDir() . '/out'; + if (!is_dir($outDataDir)) { + mkdir($outDataDir); + } + + $outputStateFile = $outDataDir . '/state.json'; + $jsonEncode = new JsonEncoder(); + file_put_contents( + $outputStateFile, + $jsonEncode->encode($state, JsonEncoder::FORMAT, ['json_encode_options' => JSON_PRETTY_PRINT]) + ); + } + protected function getRawConfig(): array { $jsonContents = file_get_contents($this->dataDir . '/config.json'); From 6a353fa3c1064a9ae63911df192a3b318b23d2b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20St=C5=99=C3=ADte=C5=BEsk=C3=BD?= Date: Mon, 15 Oct 2018 20:27:07 +0200 Subject: [PATCH 03/13] Use more strict assertion --- tests/BaseComponentTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/BaseComponentTest.php b/tests/BaseComponentTest.php index 1e2d671d..c4694bf6 100644 --- a/tests/BaseComponentTest.php +++ b/tests/BaseComponentTest.php @@ -66,6 +66,6 @@ public function testLoadInputStateFileUndefined(): void $logger = new Logger(); $baseComponent = new BaseComponent($logger); - $this->assertEmpty($baseComponent->getInputState()); + $this->assertSame([], $baseComponent->getInputState()); } } From f9d0455ce885cafc0699e27f3f5aa512c5836cb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20St=C5=99=C3=ADte=C5=BEsk=C3=BD?= Date: Mon, 15 Oct 2018 20:28:36 +0200 Subject: [PATCH 04/13] Remove folder check --- src/BaseComponent.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/BaseComponent.php b/src/BaseComponent.php index 4c2217ab..9d302015 100644 --- a/src/BaseComponent.php +++ b/src/BaseComponent.php @@ -103,12 +103,7 @@ protected function loadInputState(): void protected function writeOutputStateToFile(array $state): void { - $outDataDir = $this->getDataDir() . '/out'; - if (!is_dir($outDataDir)) { - mkdir($outDataDir); - } - - $outputStateFile = $outDataDir . '/state.json'; + $outputStateFile = $this->getDataDir() . '/out/state.json'; $jsonEncode = new JsonEncoder(); file_put_contents( $outputStateFile, From 13de6c0a525965f27cfcdb2f487a5952cb976279 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20St=C5=99=C3=ADte=C5=BEsk=C3=BD?= Date: Mon, 15 Oct 2018 21:14:09 +0200 Subject: [PATCH 05/13] Create JsonFileHelper class for read/write operations --- src/BaseComponent.php | 25 ++---- src/JsonFileHelper.php | 31 +++++++ tests/JsonFileHelperTest.php | 85 +++++++++++++++++++ .../fixtures/json-file-helper-test/file.json | 7 ++ .../invalidJsonFile.json | 3 + 5 files changed, 135 insertions(+), 16 deletions(-) create mode 100644 src/JsonFileHelper.php create mode 100644 tests/JsonFileHelperTest.php create mode 100644 tests/fixtures/json-file-helper-test/file.json create mode 100644 tests/fixtures/json-file-helper-test/invalidJsonFile.json diff --git a/src/BaseComponent.php b/src/BaseComponent.php index 9d302015..df461119 100644 --- a/src/BaseComponent.php +++ b/src/BaseComponent.php @@ -10,9 +10,8 @@ use Keboola\Component\Manifest\ManifestManager; use Psr\Log\LoggerInterface; use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; -use Symfony\Component\Serializer\Encoder\JsonEncoder; +use Symfony\Component\Filesystem\Exception\FileNotFoundException; use function error_reporting; -use function file_get_contents; /** * This is the core class that does all the heavy lifting. By default you don't need to setup anything. There are some @@ -91,31 +90,25 @@ protected function loadConfig(): void protected function loadInputState(): void { - $inputStateFile = $this->getDataDir() . '/in/state.json'; - if (file_exists($inputStateFile)) { - $jsonContents = (string) file_get_contents($inputStateFile); - $jsonEncoder = new JsonEncoder(); - $this->inputState = $jsonEncoder->decode($jsonContents, JsonEncoder::FORMAT); - } else { + try { + $this->inputState = (new JsonFileHelper())->read($this->getDataDir() . '/in/state.json'); + } catch (FileNotFoundException $exception) { $this->inputState = []; } } protected function writeOutputStateToFile(array $state): void { - $outputStateFile = $this->getDataDir() . '/out/state.json'; - $jsonEncode = new JsonEncoder(); - file_put_contents( - $outputStateFile, - $jsonEncode->encode($state, JsonEncoder::FORMAT, ['json_encode_options' => JSON_PRETTY_PRINT]) + (new JsonFileHelper())->write( + $this->getDataDir() . '/out/state.json', + $state, + ['json_encode_options' => JSON_PRETTY_PRINT] ); } protected function getRawConfig(): array { - $jsonContents = file_get_contents($this->dataDir . '/config.json'); - $jsonEncoder = new JsonEncoder(); - return $jsonEncoder->decode($jsonContents, JsonEncoder::FORMAT); + return (new JsonFileHelper())->read($this->dataDir . '/config.json'); } /** diff --git a/src/JsonFileHelper.php b/src/JsonFileHelper.php new file mode 100644 index 00000000..1767ea7c --- /dev/null +++ b/src/JsonFileHelper.php @@ -0,0 +1,31 @@ +decode($jsonContents, JsonEncoder::FORMAT); + } + + public function write(string $filePath, array $data, ?array $context = []): void + { + $jsonEncoder = new JsonEncoder(); + file_put_contents( + $filePath, + $jsonEncoder->encode($data,JsonEncoder::FORMAT, $context) + ); + } +} diff --git a/tests/JsonFileHelperTest.php b/tests/JsonFileHelperTest.php new file mode 100644 index 00000000..fcdecefd --- /dev/null +++ b/tests/JsonFileHelperTest.php @@ -0,0 +1,85 @@ +jsonFileHelper = new JsonFileHelper(); + } + + public function testReadNonExistingFileThrowsException(): void + { + $this->expectException(FileNotFoundException::class); + $this->expectExceptionMessage('File "/dev/null/file.json" could not be found.'); + $this->jsonFileHelper->read('/dev/null/file.json'); + } + + public function testReadInvalidFileThrowsException(): void + { + $this->expectException(NotEncodableValueException::class); + $this->expectExceptionMessage('Syntax error'); + $this->jsonFileHelper->read(__DIR__ . '/fixtures/json-file-helper-test/invalidJsonFile.json'); + } + + public function testReadFileSuccessfully(): void + { + $array = $this->jsonFileHelper->read(__DIR__ . '/fixtures/json-file-helper-test/file.json'); + $this->assertSame( + [ + 'key' => 'value', + 'keys' => ['a', 'b'], + ], + $array + ); + } + + public function testWriteToFileSuccessfully(): void + { + $filePath = __DIR__ . '/fixtures/json-file-helper-test/tmp.json'; + $array = [ + 'key' => 'val', + 'keys' => [0, 1, 2], + ]; + $this->jsonFileHelper->write($filePath, $array); + + $this->assertSame( + '{"key":"val","keys":[0,1,2]}', + file_get_contents($filePath) + ); + } + + public function testWriteToFilePrettyPrintedSuccessfully(): void + { + $filePath = __DIR__ . '/fixtures/json-file-helper-test/tmp.json'; + $array = [ + 'key' => 'val', + 'keys' => [0, 1, 2], + ]; + $this->jsonFileHelper->write($filePath, $array, ['json_encode_options' => JSON_PRETTY_PRINT]); + + $this->assertSame( + '{ + "key": "val", + "keys": [ + 0, + 1, + 2 + ] +}', + file_get_contents($filePath) + ); + unlink($filePath); + } +} diff --git a/tests/fixtures/json-file-helper-test/file.json b/tests/fixtures/json-file-helper-test/file.json new file mode 100644 index 00000000..b7ce7859 --- /dev/null +++ b/tests/fixtures/json-file-helper-test/file.json @@ -0,0 +1,7 @@ +{ + "key": "value", + "keys": [ + "a", + "b" + ] +} diff --git a/tests/fixtures/json-file-helper-test/invalidJsonFile.json b/tests/fixtures/json-file-helper-test/invalidJsonFile.json new file mode 100644 index 00000000..9338a490 --- /dev/null +++ b/tests/fixtures/json-file-helper-test/invalidJsonFile.json @@ -0,0 +1,3 @@ +{ + "key" => "value" +} From d47bbd821bceaa588ea2db000ea0904dd89c116a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20St=C5=99=C3=ADte=C5=BEsk=C3=BD?= Date: Mon, 15 Oct 2018 21:17:43 +0200 Subject: [PATCH 06/13] Fix code style --- src/JsonFileHelper.php | 4 ++-- tests/JsonFileHelperTest.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/JsonFileHelper.php b/src/JsonFileHelper.php index 1767ea7c..207aaa20 100644 --- a/src/JsonFileHelper.php +++ b/src/JsonFileHelper.php @@ -20,12 +20,12 @@ public function read(string $filePath): array return $jsonEncoder->decode($jsonContents, JsonEncoder::FORMAT); } - public function write(string $filePath, array $data, ?array $context = []): void + public function write(string $filePath, array $data, array $context = []): void { $jsonEncoder = new JsonEncoder(); file_put_contents( $filePath, - $jsonEncoder->encode($data,JsonEncoder::FORMAT, $context) + $jsonEncoder->encode($data, JsonEncoder::FORMAT, $context) ); } } diff --git a/tests/JsonFileHelperTest.php b/tests/JsonFileHelperTest.php index fcdecefd..a7b93071 100644 --- a/tests/JsonFileHelperTest.php +++ b/tests/JsonFileHelperTest.php @@ -14,7 +14,7 @@ class JsonFileHelperTest extends TestCase /** @var JsonFileHelper */ private $jsonFileHelper; - public function setUp() + public function setUp(): void { $this->jsonFileHelper = new JsonFileHelper(); } From f31734ab58d2f081e5c1ccec75ebb1f5974b11da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20St=C5=99=C3=ADte=C5=BEsk=C3=BD?= Date: Tue, 16 Oct 2018 12:42:11 +0200 Subject: [PATCH 07/13] Add missing test --- tests/JsonFileHelperTest.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/JsonFileHelperTest.php b/tests/JsonFileHelperTest.php index a7b93071..5824ddcb 100644 --- a/tests/JsonFileHelperTest.php +++ b/tests/JsonFileHelperTest.php @@ -82,4 +82,19 @@ public function testWriteToFilePrettyPrintedSuccessfully(): void ); unlink($filePath); } + + public function testWriteToNonExistingDirectoryThrowsException(): void + { + $filePath = __DIR__ . '/non-existing-folder/tmp.json'; + $array = [ + 'key' => 'val', + ]; + + $this->expectException(\ErrorException::class); + $this->expectExceptionMessage( + 'file_put_contents(/Users/ds/projects/keboola/php-component/tests/non-existing-folder/tmp.json):' + . ' failed to open stream: No such file or directory' + ); + $this->jsonFileHelper->write($filePath, $array); + } } From a945165ffeeef8740fed585e14dc01897e13e528 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20St=C5=99=C3=ADte=C5=BEsk=C3=BD?= Date: Tue, 16 Oct 2018 12:44:55 +0200 Subject: [PATCH 08/13] Do not pass whole context, use true/false for pretty printed json --- src/BaseComponent.php | 3 +-- src/JsonFileHelper.php | 7 ++++++- tests/JsonFileHelperTest.php | 10 +++++----- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/BaseComponent.php b/src/BaseComponent.php index df461119..b7571265 100644 --- a/src/BaseComponent.php +++ b/src/BaseComponent.php @@ -101,8 +101,7 @@ protected function writeOutputStateToFile(array $state): void { (new JsonFileHelper())->write( $this->getDataDir() . '/out/state.json', - $state, - ['json_encode_options' => JSON_PRETTY_PRINT] + $state ); } diff --git a/src/JsonFileHelper.php b/src/JsonFileHelper.php index 207aaa20..39b518a3 100644 --- a/src/JsonFileHelper.php +++ b/src/JsonFileHelper.php @@ -20,8 +20,13 @@ public function read(string $filePath): array return $jsonEncoder->decode($jsonContents, JsonEncoder::FORMAT); } - public function write(string $filePath, array $data, array $context = []): void + public function write(string $filePath, array $data, bool $formatted = true): void { + $context = []; + if ($formatted) { + $context = ['json_encode_options' => JSON_PRETTY_PRINT]; + } + $jsonEncoder = new JsonEncoder(); file_put_contents( $filePath, diff --git a/tests/JsonFileHelperTest.php b/tests/JsonFileHelperTest.php index 5824ddcb..c9384929 100644 --- a/tests/JsonFileHelperTest.php +++ b/tests/JsonFileHelperTest.php @@ -52,7 +52,7 @@ public function testWriteToFileSuccessfully(): void 'key' => 'val', 'keys' => [0, 1, 2], ]; - $this->jsonFileHelper->write($filePath, $array); + $this->jsonFileHelper->write($filePath, $array, false); $this->assertSame( '{"key":"val","keys":[0,1,2]}', @@ -67,7 +67,7 @@ public function testWriteToFilePrettyPrintedSuccessfully(): void 'key' => 'val', 'keys' => [0, 1, 2], ]; - $this->jsonFileHelper->write($filePath, $array, ['json_encode_options' => JSON_PRETTY_PRINT]); + $this->jsonFileHelper->write($filePath, $array); $this->assertSame( '{ @@ -91,9 +91,9 @@ public function testWriteToNonExistingDirectoryThrowsException(): void ]; $this->expectException(\ErrorException::class); - $this->expectExceptionMessage( - 'file_put_contents(/Users/ds/projects/keboola/php-component/tests/non-existing-folder/tmp.json):' - . ' failed to open stream: No such file or directory' + $this->expectExceptionMessageRegExp( + '~^file_put_contents(.*):' + . ' failed to open stream: No such file or directory$~' ); $this->jsonFileHelper->write($filePath, $array); } From d61c9095fbf6508cefb4a105d4ce9160ed2f6065 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20St=C5=99=C3=ADte=C5=BEsk=C3=BD?= Date: Tue, 16 Oct 2018 14:22:24 +0200 Subject: [PATCH 09/13] Create directory if does not exist --- src/JsonFileHelper.php | 5 +++++ tests/JsonFileHelperTest.php | 12 +++++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/JsonFileHelper.php b/src/JsonFileHelper.php index 39b518a3..084361b5 100644 --- a/src/JsonFileHelper.php +++ b/src/JsonFileHelper.php @@ -22,6 +22,11 @@ public function read(string $filePath): array public function write(string $filePath, array $data, bool $formatted = true): void { + $filePathDir = pathinfo($filePath, PATHINFO_DIRNAME); + if (!is_dir($filePathDir)) { + mkdir($filePathDir, 0777, true); + } + $context = []; if ($formatted) { $context = ['json_encode_options' => JSON_PRETTY_PRINT]; diff --git a/tests/JsonFileHelperTest.php b/tests/JsonFileHelperTest.php index c9384929..a3e3d434 100644 --- a/tests/JsonFileHelperTest.php +++ b/tests/JsonFileHelperTest.php @@ -83,18 +83,16 @@ public function testWriteToFilePrettyPrintedSuccessfully(): void unlink($filePath); } - public function testWriteToNonExistingDirectoryThrowsException(): void + public function testWriteToNonExistingDirectorySuccessfully(): void { $filePath = __DIR__ . '/non-existing-folder/tmp.json'; $array = [ 'key' => 'val', ]; - $this->expectException(\ErrorException::class); - $this->expectExceptionMessageRegExp( - '~^file_put_contents(.*):' - . ' failed to open stream: No such file or directory$~' - ); - $this->jsonFileHelper->write($filePath, $array); + $this->jsonFileHelper->write($filePath, $array, false); + $this->assertSame('{"key":"val"}', file_get_contents($filePath)); + + unlink($filePath); } } From 5f22108c394ab15df0ad600243118189932e3ae1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20St=C5=99=C3=ADte=C5=BEsk=C3=BD?= Date: Tue, 16 Oct 2018 14:26:03 +0200 Subject: [PATCH 10/13] Use static methods --- src/BaseComponent.php | 6 +++--- src/JsonFileHelper.php | 4 ++-- tests/JsonFileHelperTest.php | 20 ++++++-------------- 3 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/BaseComponent.php b/src/BaseComponent.php index b7571265..b5af7fc9 100644 --- a/src/BaseComponent.php +++ b/src/BaseComponent.php @@ -91,7 +91,7 @@ protected function loadConfig(): void protected function loadInputState(): void { try { - $this->inputState = (new JsonFileHelper())->read($this->getDataDir() . '/in/state.json'); + $this->inputState = JsonFileHelper::read($this->getDataDir() . '/in/state.json'); } catch (FileNotFoundException $exception) { $this->inputState = []; } @@ -99,7 +99,7 @@ protected function loadInputState(): void protected function writeOutputStateToFile(array $state): void { - (new JsonFileHelper())->write( + JsonFileHelper::write( $this->getDataDir() . '/out/state.json', $state ); @@ -107,7 +107,7 @@ protected function writeOutputStateToFile(array $state): void protected function getRawConfig(): array { - return (new JsonFileHelper())->read($this->dataDir . '/config.json'); + return JsonFileHelper::read($this->dataDir . '/config.json'); } /** diff --git a/src/JsonFileHelper.php b/src/JsonFileHelper.php index 084361b5..7fe58fb3 100644 --- a/src/JsonFileHelper.php +++ b/src/JsonFileHelper.php @@ -9,7 +9,7 @@ class JsonFileHelper { - public function read(string $filePath): array + public static function read(string $filePath): array { if (!file_exists($filePath)) { throw new FileNotFoundException(null, 0, null, $filePath); @@ -20,7 +20,7 @@ public function read(string $filePath): array return $jsonEncoder->decode($jsonContents, JsonEncoder::FORMAT); } - public function write(string $filePath, array $data, bool $formatted = true): void + public static function write(string $filePath, array $data, bool $formatted = true): void { $filePathDir = pathinfo($filePath, PATHINFO_DIRNAME); if (!is_dir($filePathDir)) { diff --git a/tests/JsonFileHelperTest.php b/tests/JsonFileHelperTest.php index a3e3d434..3073b21a 100644 --- a/tests/JsonFileHelperTest.php +++ b/tests/JsonFileHelperTest.php @@ -11,31 +11,23 @@ class JsonFileHelperTest extends TestCase { - /** @var JsonFileHelper */ - private $jsonFileHelper; - - public function setUp(): void - { - $this->jsonFileHelper = new JsonFileHelper(); - } - public function testReadNonExistingFileThrowsException(): void { $this->expectException(FileNotFoundException::class); $this->expectExceptionMessage('File "/dev/null/file.json" could not be found.'); - $this->jsonFileHelper->read('/dev/null/file.json'); + JsonFileHelper::read('/dev/null/file.json'); } public function testReadInvalidFileThrowsException(): void { $this->expectException(NotEncodableValueException::class); $this->expectExceptionMessage('Syntax error'); - $this->jsonFileHelper->read(__DIR__ . '/fixtures/json-file-helper-test/invalidJsonFile.json'); + JsonFileHelper::read(__DIR__ . '/fixtures/json-file-helper-test/invalidJsonFile.json'); } public function testReadFileSuccessfully(): void { - $array = $this->jsonFileHelper->read(__DIR__ . '/fixtures/json-file-helper-test/file.json'); + $array = JsonFileHelper::read(__DIR__ . '/fixtures/json-file-helper-test/file.json'); $this->assertSame( [ 'key' => 'value', @@ -52,7 +44,7 @@ public function testWriteToFileSuccessfully(): void 'key' => 'val', 'keys' => [0, 1, 2], ]; - $this->jsonFileHelper->write($filePath, $array, false); + JsonFileHelper::write($filePath, $array, false); $this->assertSame( '{"key":"val","keys":[0,1,2]}', @@ -67,7 +59,7 @@ public function testWriteToFilePrettyPrintedSuccessfully(): void 'key' => 'val', 'keys' => [0, 1, 2], ]; - $this->jsonFileHelper->write($filePath, $array); + JsonFileHelper::write($filePath, $array); $this->assertSame( '{ @@ -90,7 +82,7 @@ public function testWriteToNonExistingDirectorySuccessfully(): void 'key' => 'val', ]; - $this->jsonFileHelper->write($filePath, $array, false); + JsonFileHelper::write($filePath, $array, false); $this->assertSame('{"key":"val"}', file_get_contents($filePath)); unlink($filePath); From eef6976f7d36f1efc158ddb1d786714a4c8ecdef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20St=C5=99=C3=ADte=C5=BEsk=C3=BD?= Date: Tue, 16 Oct 2018 14:50:46 +0200 Subject: [PATCH 11/13] Throws ErrorException when there was nothing written --- src/JsonFileHelper.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/JsonFileHelper.php b/src/JsonFileHelper.php index 7fe58fb3..b728da81 100644 --- a/src/JsonFileHelper.php +++ b/src/JsonFileHelper.php @@ -33,9 +33,13 @@ public static function write(string $filePath, array $data, bool $formatted = tr } $jsonEncoder = new JsonEncoder(); - file_put_contents( + $result = file_put_contents( $filePath, $jsonEncoder->encode($data, JsonEncoder::FORMAT, $context) ); + + if ($result === false) { + throw new \ErrorException('Could not write to file "%s".'); + } } } From 99f513c30f48ed88f128ffe6c7259af59909b6e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20St=C5=99=C3=ADte=C5=BEsk=C3=BD?= Date: Tue, 16 Oct 2018 23:04:28 +0200 Subject: [PATCH 12/13] Add test --- tests/JsonFileHelperTest.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/JsonFileHelperTest.php b/tests/JsonFileHelperTest.php index 3073b21a..ba102b2f 100644 --- a/tests/JsonFileHelperTest.php +++ b/tests/JsonFileHelperTest.php @@ -87,4 +87,14 @@ public function testWriteToNonExistingDirectorySuccessfully(): void unlink($filePath); } + + public function testWriteToDevFullThrowsException(): void + { + $filePath = '/dev/full'; + $array = ['key']; + + $this->expectException(\ErrorException::class); + $this->expectExceptionMessage('file_put_contents(/dev/full): failed to open stream: Operation not permitted'); + JsonFileHelper::write($filePath, $array); + } } From 31c4abb9a11034e72d0764505abb6b63186da03b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20St=C5=99=C3=ADte=C5=BEsk=C3=BD?= Date: Tue, 16 Oct 2018 23:22:42 +0200 Subject: [PATCH 13/13] Fix test --- tests/JsonFileHelperTest.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/JsonFileHelperTest.php b/tests/JsonFileHelperTest.php index ba102b2f..ae692745 100644 --- a/tests/JsonFileHelperTest.php +++ b/tests/JsonFileHelperTest.php @@ -86,15 +86,16 @@ public function testWriteToNonExistingDirectorySuccessfully(): void $this->assertSame('{"key":"val"}', file_get_contents($filePath)); unlink($filePath); + rmdir(pathinfo($filePath, PATHINFO_DIRNAME)); } - public function testWriteToDevFullThrowsException(): void + public function testWriteToProtectedDirectoryThrowsException(): void { - $filePath = '/dev/full'; + $filePath = '/tmp.json'; $array = ['key']; $this->expectException(\ErrorException::class); - $this->expectExceptionMessage('file_put_contents(/dev/full): failed to open stream: Operation not permitted'); + $this->expectExceptionMessageRegExp('~^file_put_contents(.*): failed to open stream: Permission denied$~'); JsonFileHelper::write($filePath, $array); } }