diff --git a/app/appConf/base_config.php b/app/appConf/base_config.php index 18a96c66..612592ca 100644 --- a/app/appConf/base_config.php +++ b/app/appConf/base_config.php @@ -14,7 +14,7 @@ * @link https://github.com/timw4mail/HummingBirdAnimeClient */ -use function Aviat\AnimeClient\loadToml; +use function Aviat\AnimeClient\loadConfig; // ---------------------------------------------------------------------------- // Lower level configuration @@ -24,7 +24,7 @@ use function Aviat\AnimeClient\loadToml; $APP_DIR = realpath(__DIR__ . '/../'); $ROOT_DIR = realpath("{$APP_DIR}/../"); -$tomlConfig = loadToml(__DIR__); +$tomlConfig = loadConfig(__DIR__); return array_merge($tomlConfig, [ 'asset_dir' => "{$ROOT_DIR}/public", diff --git a/build/phpunit.xml b/build/phpunit.xml index c9cc1c97..02c0a25e 100644 --- a/build/phpunit.xml +++ b/build/phpunit.xml @@ -11,8 +11,11 @@ - ../tests + ../tests/AnimeClient + + ../tests/Ion + diff --git a/index.php b/index.php index 8a931bff..2791d0af 100644 --- a/index.php +++ b/index.php @@ -45,7 +45,7 @@ $CONF_DIR = _dir($APP_DIR, 'config'); $baseConfig = require "{$APPCONF_DIR}/base_config.php"; $di = require "{$APP_DIR}/bootstrap.php"; -$config = loadToml($CONF_DIR); +$config = loadConfig($CONF_DIR); $overrideFile = "{$CONF_DIR}/admin-override.toml"; $overrideConfig = file_exists($overrideFile) diff --git a/src/AnimeClient/AnimeClient.php b/src/AnimeClient/AnimeClient.php index 4064009e..079a36a8 100644 --- a/src/AnimeClient/AnimeClient.php +++ b/src/AnimeClient/AnimeClient.php @@ -38,10 +38,11 @@ use Throwable; /** * Load configuration options from .toml files * + * @codeCoverageIgnore * @param string $path - Path to load config * @return array */ -function loadToml(string $path): array +function loadConfig(string $path): array { $output = []; $files = glob("{$path}/*.toml"); @@ -75,6 +76,7 @@ function loadToml(string $path): array /** * Load config from one specific TOML file * + * @codeCoverageIgnore * @param string $filename * @return array */ @@ -83,6 +85,36 @@ function loadTomlFile(string $filename): array return Toml::parseFile($filename); } +function _iterateToml(TomlBuilder $builder, iterable $data, $parentKey = NULL): void +{ + foreach ($data as $key => $value) + { + // Skip unsupported empty value + if ($value === NULL) + { + continue; + } + + + if (is_scalar($value) || isSequentialArray($value)) + { + $builder->addValue($key, $value); + continue; + } + + $newKey = ($parentKey !== NULL) + ? "{$parentKey}.{$key}" + : $key; + + if ( ! isSequentialArray($value)) + { + $builder->addTable($newKey); + } + + _iterateToml($builder, $value, $newKey); + } +} + /** * Serialize config data into a Toml file * @@ -92,35 +124,6 @@ function loadTomlFile(string $filename): array function arrayToToml(iterable $data): string { $builder = new TomlBuilder(); - function _iterateToml(TomlBuilder $builder, iterable $data, $parentKey = NULL): void - { - foreach ($data as $key => $value) - { - if ($value === NULL) - { - continue; - } - - - if (is_scalar($value) || isSequentialArray($value)) - { - // $builder->addTable(''); - $builder->addValue($key, $value); - continue; - } - - $newKey = ($parentKey !== NULL) - ? "{$parentKey}.{$key}" - : $key; - - if ( ! isSequentialArray($value)) - { - $builder->addTable($newKey); - } - - _iterateToml($builder, $value, $newKey); - } - } _iterateToml($builder, $data); @@ -339,7 +342,7 @@ function createPlaceholderImage ($path, ?int $width, ?int $height, $text = 'Imag */ function colNotEmpty(array $search, string $key): bool { - $items = array_filter(array_column($search, $key), fn ($x) => ( ! empty($x))); + $items = array_filter(array_column($search, $key), static fn ($x) => ( ! empty($x))); return count($items) > 0; } @@ -358,7 +361,7 @@ function clearCache(CacheInterface $cache): bool Kitsu::AUTH_TOKEN_CACHE_KEY, Kitsu::AUTH_TOKEN_EXP_CACHE_KEY, Kitsu::AUTH_TOKEN_REFRESH_CACHE_KEY, - ], NULL); + ]); $userData = array_filter((array)$userData, static fn ($value) => $value !== NULL); $cleared = $cache->clear(); @@ -373,6 +376,7 @@ function clearCache(CacheInterface $cache): bool /** * Render a PHP code template as a string * + * @codeCoverageIgnore * @param string $path * @param array $data * @return string diff --git a/src/AnimeClient/Command/BaseCommand.php b/src/AnimeClient/Command/BaseCommand.php index 3ea93792..a6845f43 100644 --- a/src/AnimeClient/Command/BaseCommand.php +++ b/src/AnimeClient/Command/BaseCommand.php @@ -17,7 +17,7 @@ namespace Aviat\AnimeClient\Command; use Monolog\Formatter\JsonFormatter; -use function Aviat\AnimeClient\loadToml; +use function Aviat\AnimeClient\loadConfig; use function Aviat\AnimeClient\loadTomlFile; use Aura\Router\RouterContainer; @@ -113,7 +113,7 @@ abstract class BaseCommand extends Command { $CONF_DIR = realpath("{$APP_DIR}/config/"); $baseConfig = require $APPCONF_DIR . '/base_config.php'; - $config = loadToml($CONF_DIR); + $config = loadConfig($CONF_DIR); $overrideFile = $CONF_DIR . '/admin-override.toml'; $overrideConfig = file_exists($overrideFile) diff --git a/src/AnimeClient/FormGenerator.php b/src/AnimeClient/FormGenerator.php index e9a31f44..6cf69b3b 100644 --- a/src/AnimeClient/FormGenerator.php +++ b/src/AnimeClient/FormGenerator.php @@ -52,15 +52,7 @@ final class FormGenerator { */ public static function new(ContainerInterface $container): self { - try - { - return new self($container); - } - catch (\Throwable $e) - { - dump($e); - die(); - } + return new self($container); } /** diff --git a/src/AnimeClient/Kitsu.php b/src/AnimeClient/Kitsu.php index 415f9870..b14471f4 100644 --- a/src/AnimeClient/Kitsu.php +++ b/src/AnimeClient/Kitsu.php @@ -412,17 +412,12 @@ final class Kitsu { /** * Determine if an alternate title is unique enough to list * - * @param string|null $title + * @param string $title * @param array $existingTitles * @return bool */ - private static function titleIsUnique(?string $title = NULL, array $existingTitles = []): bool + private static function titleIsUnique(string $title = '', array $existingTitles = []): bool { - if (empty($title)) - { - return FALSE; - } - foreach($existingTitles as $existing) { $isSubset = mb_substr_count($existing, $title) > 0; diff --git a/tests/AnimeClient/AnimeClientTest.php b/tests/AnimeClient/AnimeClientTest.php index d4d9361f..4856321c 100644 --- a/tests/AnimeClient/AnimeClientTest.php +++ b/tests/AnimeClient/AnimeClientTest.php @@ -16,13 +16,16 @@ namespace Aviat\AnimeClient\Tests; +use Amp\Http\Client\Response; + use function Aviat\AnimeClient\arrayToToml; +use function Aviat\AnimeClient\getResponse; use function Aviat\AnimeClient\isSequentialArray; use function Aviat\AnimeClient\tomlToArray; class AnimeClientTest extends AnimeClientTestCase { - public function testArrayToToml () + public function testArrayToToml (): void { $arr = [ 'cat' => false, @@ -57,11 +60,33 @@ class AnimeClientTest extends AnimeClientTestCase $this->assertEquals($arr, $parsedArray); } - public function testIsSequentialArray() + public function testArrayToTomlNullValue(): void + { + $arr = [ + 'cat' => false, + 'bat' => null, + 'foo' => 'bar', + ]; + + $toml = arrayToToml($arr); + $parsedArray = tomlToArray($toml); + + $this->assertEquals([ + 'cat' => false, + 'foo' => 'bar', + ], $parsedArray); + } + + public function testIsSequentialArray(): void { $this->assertFalse(isSequentialArray(0)); $this->assertFalse(isSequentialArray([50 => 'foo'])); $this->assertTrue(isSequentialArray([])); $this->assertTrue(isSequentialArray([1,2,3,4,5])); } + + public function testGetResponse(): void + { + $this->assertNotEmpty(getResponse('https://example.com')); + } } \ No newline at end of file diff --git a/tests/AnimeClient/KitsuTest.php b/tests/AnimeClient/KitsuTest.php index a75e0aaa..3849febc 100644 --- a/tests/AnimeClient/KitsuTest.php +++ b/tests/AnimeClient/KitsuTest.php @@ -16,19 +16,110 @@ namespace Aviat\AnimeClient\Tests\API; +use Aviat\AnimeClient\API\Kitsu\Enum\MangaPublishingStatus; use Aviat\AnimeClient\Kitsu; use Aviat\AnimeClient\API\Kitsu\Enum\AnimeAiringStatus; use PHPUnit\Framework\TestCase; class KitsuTest extends TestCase { - public function testGetAiringStatus() + public function testGetAiringStatus(): void { $actual = Kitsu::getAiringStatus('next week', 'next year'); $this->assertEquals(AnimeAiringStatus::NOT_YET_AIRED, $actual); } - public function testParseStreamingLinksEmpty() + public function testParseStreamingLinksEmpty(): void { $this->assertEquals([], Kitsu::parseStreamingLinks([])); } + + public function testParseStreamingLinks(): void + { + $nodes = [[ + 'url' => 'www.hulu.com/chobits', + 'dubs' => ['ja'], + 'subs' => ['en'] + ]]; + + $expected = [[ + 'meta' => [ + 'name' => 'Hulu', + 'link' => TRUE, + 'image' => 'streaming-logos/hulu.svg', + ], + 'link' => 'www.hulu.com/chobits', + 'dubs' => ['ja'], + 'subs' => ['en'], + ]]; + + $this->assertEquals($expected, Kitsu::parseStreamingLinks($nodes)); + } + + public function testGetAiringStatusEmptyArguments(): void + { + $this->assertEquals(AnimeAiringStatus::NOT_YET_AIRED, Kitsu::getAiringStatus()); + } + + public function testGetAiringStatusIsAiring(): void + { + $this->assertEquals(AnimeAiringStatus::AIRING, Kitsu::getAiringStatus('yesterday')); + } + + public function getPublishingStatus(): array + { + return [ + 'current' => [ + 'kitsuStatus' => 'CURRENT', + 'expected' => MangaPublishingStatus::CURRENT, + ], + 'future' => [ + 'kitsuStatus' => 'foo', + 'expected' => MangaPublishingStatus::NOT_YET_PUBLISHED, + ] + ]; + } + + /** + * @param string $kitsuStatus + * @param string $expected + * @dataProvider getPublishingStatus + */ + public function testGetPublishingStatus(string $kitsuStatus, string $expected): void + { + $actual = Kitsu::getPublishingStatus($kitsuStatus); + $this->assertEquals($expected, $actual); + } + + public function getFriendlyTime(): array + { + $SECONDS_IN_DAY = Kitsu::SECONDS_IN_MINUTE * Kitsu::MINUTES_IN_DAY; + $SECONDS_IN_HOUR = Kitsu::SECONDS_IN_MINUTE * Kitsu::MINUTES_IN_HOUR; + $SECONDS_IN_YEAR = Kitsu::SECONDS_IN_MINUTE * Kitsu::MINUTES_IN_YEAR; + + return [[ + 'seconds' => $SECONDS_IN_YEAR, + 'expected' => '1 year', + ], [ + 'seconds' => $SECONDS_IN_HOUR, + 'expected' => '1 hour', + ], [ + 'seconds' => (2 * $SECONDS_IN_YEAR) + 30, + 'expected' => '2 years, 30 seconds' + ], [ + 'seconds' => (5 * $SECONDS_IN_YEAR) + (3 * $SECONDS_IN_DAY) + (17 * Kitsu::SECONDS_IN_MINUTE), + 'expected' => '5 years, 3 days, and 17 minutes' + ]]; + } + + /** + * @param int $seconds + * @param string $expected + * @dataProvider getFriendlyTime + */ + public function testGetFriendlyTime(int $seconds, string $expected): void + { + $actual = Kitsu::friendlyTime($seconds); + + $this->assertEquals($expected, $actual); + } } \ No newline at end of file