Skip to content

handling json file #32

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 1 commit into from
Sep 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bin/view-csv
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ $command = (new SingleCommandApplication())
return Command::FAILURE;
}

$headers = array_keys($data[0]);
$headers = array_keys(reset($data));
$io->title($csvFile);
$table = $io->createTable();
$table->setHeaders($headers);
Expand Down
50 changes: 50 additions & 0 deletions bin/view-json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/usr/bin/env php
<?php

use rcsofttech85\FileHandler\DI\ServiceContainer;
use rcsofttech85\FileHandler\Exception\FileHandlerException;
use rcsofttech85\FileHandler\JsonFileHandler;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\SingleCommandApplication;
use Symfony\Component\Console\Style\SymfonyStyle;

require 'vendor/autoload.php';

$command = (new SingleCommandApplication())
->addArgument('jsonFile', InputArgument::REQUIRED, 'json file name')
->addOption('hide-column', null, InputOption::VALUE_REQUIRED, 'Columns to hide (comma-separated)')
->addOption('limit', null, InputOption::VALUE_REQUIRED, 'limit number of records')
->setCode(function (InputInterface $input, OutputInterface $output): int {
$io = new SymfonyStyle($input, $output);
$jsonFile = $input->getArgument('jsonFile');

if (!file_exists($jsonFile)) {
$io->error("{$jsonFile} does not exists");
return Command::FAILURE;
}

$serviceContainer = new ServiceContainer();
/** @var JsonFileHandler $jsonFileHandler */
$jsonFileHandler = $serviceContainer->getContainerBuilder()->get('json_file_handler');

try {
$data = $jsonFileHandler->toArray($jsonFile);
} catch (FileHandlerException) {
$io->error('invalid json file');
return Command::FAILURE;
}

$headers = array_keys(reset($data));
$io->title($jsonFile);
$table = $io->createTable();
$table->setHeaders($headers);
$table->setRows($data);
$table->render();
$io->newLine();

return Command::SUCCESS;
})->run();
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
},
"bin": [
"bin/file-diff",
"bin/view-csv"
"bin/view-csv",
"bin/view-json"
]
}
43 changes: 43 additions & 0 deletions src/JsonFileHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

namespace rcsofttech85\FileHandler;

use Generator;
use rcsofttech85\FileHandler\Exception\FileHandlerException;

readonly class JsonFileHandler
{
/**
* @return array<int,array<string,string>>
* @throws FileHandlerException
*/
public function toArray(string $filename): array
{
return iterator_to_array($this->getRows($filename));
}

/**
* @return Generator
* @throws FileHandlerException
*/
private function getRows(string $filename): Generator
{
if (!file_exists($filename)) {
throw new FileHandlerException('file not found');
}
$jsonContents = file_get_contents($filename);

if (!$jsonContents) {
throw new FileHandlerException("{$filename} is not valid");
}

$contents = json_decode($jsonContents, true);
if (!$contents || json_last_error() !== JSON_ERROR_NONE) {
throw new FileHandlerException(json_last_error_msg());
}

foreach ($contents as $content) {
yield $content;
}
}
}
4 changes: 4 additions & 0 deletions src/config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,7 @@ services:
file_hash:
class: 'rcsofttech85\FileHandler\FileHashChecker'
arguments: [ '%filename%','@csv_file_handler' ]

json_file_handler:
class: 'rcsofttech85\FileHandler\JsonFileHandler'

2 changes: 1 addition & 1 deletion tests/Integration/ViewCsvCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public function viewCsvFileDisplayInformationCorrectly(string $file): void
}

#[Test]
public function IfLimitIsSetToNonNumericCommandShouldFail(): void
public function ifLimitIsSetToNonNumericCommandShouldFail(): void
{
$command = "php bin/view-csv movie.csv --limit hello";
exec($command, $output, $exitCode);
Expand Down
52 changes: 52 additions & 0 deletions tests/Integration/ViewJsonCommandTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

namespace Integration;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;

class ViewJsonCommandTest extends TestCase
{
/**
* @return iterable<array<string>>
*/
public static function fileProvider(): iterable
{
$file = "book.json";
$csvData = '[
{
"title": "The Catcher in the Rye",
"author": "J.D. Salinger",
"published_year": 1951
},
{
"title": "To Kill a Mockingbird",
"author": "Harper Lee",
"published_year": 1960
},
{
"title": "1984",
"author": "George Orwell",
"published_year": 1949
}
]';
file_put_contents($file, $csvData);

yield [$file];
}

#[Test]
#[DataProvider('fileProvider')]
public function viewJsonFileDisplayInformationCorrectly(string $file): void
{
$command = "php bin/view-json {$file}";
exec($command, $output, $exitCode);
$actualOutput = implode("\n", $output);

$this->assertSame(0, $exitCode);
$this->assertStringContainsString($file, $actualOutput);
$this->assertStringContainsString('The Catcher in the Rye', $actualOutput);
unlink($file);
}
}
103 changes: 103 additions & 0 deletions tests/unit/JsonFileHandlerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<?php

namespace unit;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;
use rcsofttech85\FileHandler\Exception\FileHandlerException;
use rcsofttech85\FileHandler\JsonFileHandler;

class JsonFileHandlerTest extends TestCase
{
private JsonFileHandler|null $jsonFileHandler;

public static function setUpBeforeClass(): void
{
parent::setUpBeforeClass();

$content = '[
{
"title": "The Catcher in the Rye",
"author": "J.D. Salinger",
"published_year": 1951
},
{
"title": "To Kill a Mockingbird",
"author": "Harper Lee",
"published_year": 1960
},
{
"title": "1984",
"author": "George Orwell",
"published_year": 1949
}
]
';
file_put_contents("book.json", $content);
}

public static function tearDownAfterClass(): void
{
parent::tearDownAfterClass();
unlink('book.json');
}

/**
* @return array<int,array<int, array<int, array<string, string>>>>
*/
public static function bookListProvider(): iterable
{
yield
[
[
[
'title' => 'The Catcher in the Rye',
'author' => 'J.D. Salinger',
'published_year' => '1951'
],
[
'title' => 'To Kill a Mockingbird',
'author' => 'Harper Lee',
'published_year' => '1960'
],
[
'title' => '1984',
'author' => 'George Orwell',
'published_year' => '1949'
],


]

];
}

/**
* @param array<int,array<string,string>> $book
* @return void
* @throws FileHandlerException
*/
#[Test]
#[DataProvider('bookListProvider')]
public function jsonFormatToArray(array $book): void
{
$data = $this->jsonFileHandler->toArray('book.json');

$this->assertSame(3, count($data));
$this->assertEquals($data, $book);
}

protected function setUp(): void
{
parent::setUp();
$this->jsonFileHandler = new JsonFileHandler();
}

protected function tearDown(): void
{
parent::tearDown();

$this->jsonFileHandler = null;
}
}