-
Notifications
You must be signed in to change notification settings - Fork 1
Add loading input state file #48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
3226de9
Add loading input state file
Actimel b3e6c25
Add write state file method
Actimel 6a353fa
Use more strict assertion
Actimel f9d0455
Remove folder check
Actimel 13de6c0
Create JsonFileHelper class for read/write operations
Actimel d47bbd8
Fix code style
Actimel f31734a
Add missing test
Actimel a945165
Do not pass whole context, use true/false for pretty printed json
Actimel d61c909
Create directory if does not exist
Actimel 5f22108
Use static methods
Actimel eef6976
Throws ErrorException when there was nothing written
Actimel 99f513c
Add test
Actimel 31c4abb
Fix test
Actimel File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 hidden or 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,45 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Keboola\Component; | ||
|
||
use Symfony\Component\Filesystem\Exception\FileNotFoundException; | ||
use Symfony\Component\Serializer\Encoder\JsonEncoder; | ||
|
||
class JsonFileHelper | ||
{ | ||
public static function read(string $filePath): array | ||
{ | ||
if (!file_exists($filePath)) { | ||
throw new FileNotFoundException(null, 0, null, $filePath); | ||
} | ||
|
||
$jsonEncoder = new JsonEncoder(); | ||
$jsonContents = file_get_contents($filePath); | ||
return $jsonEncoder->decode($jsonContents, JsonEncoder::FORMAT); | ||
} | ||
|
||
public static 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]; | ||
} | ||
|
||
$jsonEncoder = new JsonEncoder(); | ||
$result = file_put_contents( | ||
$filePath, | ||
$jsonEncoder->encode($data, JsonEncoder::FORMAT, $context) | ||
); | ||
|
||
if ($result === false) { | ||
throw new \ErrorException('Could not write to file "%s".'); | ||
} | ||
} | ||
} |
This file contains hidden or 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,71 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Keboola\Component\Tests; | ||
|
||
use Keboola\Component\BaseComponent; | ||
use Keboola\Component\Logger; | ||
use PHPUnit\Framework\TestCase; | ||
use Symfony\Component\Serializer\Exception\NotEncodableValueException; | ||
|
||
class BaseComponentTest extends TestCase | ||
{ | ||
public function testLoadInputStateFile(): void | ||
{ | ||
putenv(sprintf( | ||
'KBC_DATADIR=%s', | ||
__DIR__ . '/fixtures/base-component-data-dir/state-file' | ||
)); | ||
|
||
$logger = new Logger(); | ||
$baseComponent = new BaseComponent($logger); | ||
|
||
$inputStateFile = $baseComponent->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->assertSame([], $baseComponent->getInputState()); | ||
} | ||
} |
This file contains hidden or 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,101 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Keboola\Component\Tests; | ||
|
||
use Keboola\Component\JsonFileHelper; | ||
use PHPUnit\Framework\TestCase; | ||
use Symfony\Component\Filesystem\Exception\FileNotFoundException; | ||
use Symfony\Component\Serializer\Exception\NotEncodableValueException; | ||
|
||
class JsonFileHelperTest extends TestCase | ||
{ | ||
public function testReadNonExistingFileThrowsException(): void | ||
{ | ||
$this->expectException(FileNotFoundException::class); | ||
$this->expectExceptionMessage('File "/dev/null/file.json" could not be found.'); | ||
JsonFileHelper::read('/dev/null/file.json'); | ||
} | ||
|
||
public function testReadInvalidFileThrowsException(): void | ||
{ | ||
$this->expectException(NotEncodableValueException::class); | ||
$this->expectExceptionMessage('Syntax error'); | ||
JsonFileHelper::read(__DIR__ . '/fixtures/json-file-helper-test/invalidJsonFile.json'); | ||
} | ||
|
||
public function testReadFileSuccessfully(): void | ||
{ | ||
$array = 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], | ||
]; | ||
JsonFileHelper::write($filePath, $array, false); | ||
|
||
$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], | ||
]; | ||
JsonFileHelper::write($filePath, $array); | ||
|
||
$this->assertSame( | ||
'{ | ||
"key": "val", | ||
"keys": [ | ||
0, | ||
1, | ||
2 | ||
] | ||
}', | ||
file_get_contents($filePath) | ||
); | ||
unlink($filePath); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. chybí test writeToDirectoryThatDoesNotExist There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doplnil jsem. |
||
|
||
public function testWriteToNonExistingDirectorySuccessfully(): void | ||
{ | ||
$filePath = __DIR__ . '/non-existing-folder/tmp.json'; | ||
$array = [ | ||
'key' => 'val', | ||
]; | ||
|
||
JsonFileHelper::write($filePath, $array, false); | ||
$this->assertSame('{"key":"val"}', file_get_contents($filePath)); | ||
|
||
unlink($filePath); | ||
rmdir(pathinfo($filePath, PATHINFO_DIRNAME)); | ||
} | ||
|
||
public function testWriteToProtectedDirectoryThrowsException(): void | ||
{ | ||
$filePath = '/tmp.json'; | ||
$array = ['key']; | ||
|
||
$this->expectException(\ErrorException::class); | ||
$this->expectExceptionMessageRegExp('~^file_put_contents(.*): failed to open stream: Permission denied$~'); | ||
JsonFileHelper::write($filePath, $array); | ||
} | ||
} |
1 change: 1 addition & 0 deletions
1
tests/fixtures/base-component-data-dir/empty-state-file/config.json
This file contains hidden or 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 @@ | ||
{} |
Empty file.
This file contains hidden or 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 @@ | ||
{} |
12 changes: 12 additions & 0 deletions
12
tests/fixtures/base-component-data-dir/state-file/in/state.json
This file contains hidden or 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,12 @@ | ||
{ | ||
"key1": "value1", | ||
"key2": 2, | ||
"list": [ | ||
"a", | ||
"b", | ||
"c" | ||
], | ||
"dict": { | ||
"key": "value" | ||
} | ||
} |
1 change: 1 addition & 0 deletions
1
tests/fixtures/base-component-data-dir/undefined-state-file/config.json
This file contains hidden or 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 @@ | ||
{} |
This file contains hidden or 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,7 @@ | ||
{ | ||
"key": "value", | ||
"keys": [ | ||
"a", | ||
"b" | ||
] | ||
} |
This file contains hidden or 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,3 @@ | ||
{ | ||
"key" => "value" | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tady je jeden potencionalni problem, kdyz bude ve state
{}
nebo[]
a prozene se to pres assoc decoder, takze z toho vzdycky vznikne[]
. Vzhledem k tomu, ze state jsou interni data jedne aplikace a ta aplikace je vzdycky v PHP, tak si myslim, ze to vubec nevadi. Presto jsem to sem napsal, abyste se nad tim s @tomasfejfar zamysleli jestli vas nenapadne sitauce ve ktere by to mohl byt problem.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@odinuv Kdyz bude ve state
{}
/[]
, tak je to uplne jedno, oboji je validni prazdny json. To by nemelo vadit nikde.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ja vim, ze je oboji validni, jde o to, ze se prazdny objekty konvertuji na pole a nelze rozlisit mezi tim jestli to byl prazdny objekt nebo prazdne pole
python by se na tom treba vysypal
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To uz je pak ale na pythonovou komponentu. Jak si psal toto je vstup pouze pro php, takze je to jedno. Na vystupu nikdy prazdny state zapisovat nebudeme, coz bych videl jeko potencialni nekonzistenci.