diff --git a/bin/view-csv b/bin/view-csv index 3aea261..1213f29 100755 --- a/bin/view-csv +++ b/bin/view-csv @@ -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); diff --git a/bin/view-json b/bin/view-json new file mode 100755 index 0000000..372fd0f --- /dev/null +++ b/bin/view-json @@ -0,0 +1,50 @@ +#!/usr/bin/env php +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(); diff --git a/composer.json b/composer.json index bb06ad8..52e8ee2 100644 --- a/composer.json +++ b/composer.json @@ -34,6 +34,7 @@ }, "bin": [ "bin/file-diff", - "bin/view-csv" + "bin/view-csv", + "bin/view-json" ] } diff --git a/src/JsonFileHandler.php b/src/JsonFileHandler.php new file mode 100644 index 0000000..38290eb --- /dev/null +++ b/src/JsonFileHandler.php @@ -0,0 +1,43 @@ +> + * @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; + } + } +} diff --git a/src/config/services.yaml b/src/config/services.yaml index 9cf88c9..8d7df8e 100644 --- a/src/config/services.yaml +++ b/src/config/services.yaml @@ -23,3 +23,7 @@ services: file_hash: class: 'rcsofttech85\FileHandler\FileHashChecker' arguments: [ '%filename%','@csv_file_handler' ] + + json_file_handler: + class: 'rcsofttech85\FileHandler\JsonFileHandler' + diff --git a/tests/Integration/ViewCsvCommandTest.php b/tests/Integration/ViewCsvCommandTest.php index b6b1aac..dac9440 100644 --- a/tests/Integration/ViewCsvCommandTest.php +++ b/tests/Integration/ViewCsvCommandTest.php @@ -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); diff --git a/tests/Integration/ViewJsonCommandTest.php b/tests/Integration/ViewJsonCommandTest.php new file mode 100644 index 0000000..439999c --- /dev/null +++ b/tests/Integration/ViewJsonCommandTest.php @@ -0,0 +1,52 @@ +> + */ + 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); + } +} diff --git a/tests/unit/JsonFileHandlerTest.php b/tests/unit/JsonFileHandlerTest.php new file mode 100644 index 0000000..2584bc9 --- /dev/null +++ b/tests/unit/JsonFileHandlerTest.php @@ -0,0 +1,103 @@ +>>> + */ + 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> $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; + } +}