develop #37
@ -14,7 +14,7 @@
|
|||||||
* @link https://github.com/timw4mail/HummingBirdAnimeClient
|
* @link https://github.com/timw4mail/HummingBirdAnimeClient
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use function Aviat\AnimeClient\loadToml;
|
use function Aviat\AnimeClient\loadConfig;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Lower level configuration
|
// Lower level configuration
|
||||||
@ -24,7 +24,7 @@ use function Aviat\AnimeClient\loadToml;
|
|||||||
$APP_DIR = realpath(__DIR__ . '/../');
|
$APP_DIR = realpath(__DIR__ . '/../');
|
||||||
$ROOT_DIR = realpath("{$APP_DIR}/../");
|
$ROOT_DIR = realpath("{$APP_DIR}/../");
|
||||||
|
|
||||||
$tomlConfig = loadToml(__DIR__);
|
$tomlConfig = loadConfig(__DIR__);
|
||||||
|
|
||||||
return array_merge($tomlConfig, [
|
return array_merge($tomlConfig, [
|
||||||
'asset_dir' => "{$ROOT_DIR}/public",
|
'asset_dir' => "{$ROOT_DIR}/public",
|
||||||
|
@ -11,7 +11,10 @@
|
|||||||
</coverage>
|
</coverage>
|
||||||
<testsuites>
|
<testsuites>
|
||||||
<testsuite name="AnimeClient">
|
<testsuite name="AnimeClient">
|
||||||
<directory>../tests</directory>
|
<directory>../tests/AnimeClient</directory>
|
||||||
|
</testsuite>
|
||||||
|
<testsuite name="Ion">
|
||||||
|
<directory>../tests/Ion</directory>
|
||||||
</testsuite>
|
</testsuite>
|
||||||
</testsuites>
|
</testsuites>
|
||||||
<logging/>
|
<logging/>
|
||||||
|
@ -45,7 +45,7 @@ $CONF_DIR = _dir($APP_DIR, 'config');
|
|||||||
$baseConfig = require "{$APPCONF_DIR}/base_config.php";
|
$baseConfig = require "{$APPCONF_DIR}/base_config.php";
|
||||||
$di = require "{$APP_DIR}/bootstrap.php";
|
$di = require "{$APP_DIR}/bootstrap.php";
|
||||||
|
|
||||||
$config = loadToml($CONF_DIR);
|
$config = loadConfig($CONF_DIR);
|
||||||
|
|
||||||
$overrideFile = "{$CONF_DIR}/admin-override.toml";
|
$overrideFile = "{$CONF_DIR}/admin-override.toml";
|
||||||
$overrideConfig = file_exists($overrideFile)
|
$overrideConfig = file_exists($overrideFile)
|
||||||
|
@ -38,10 +38,11 @@ use Throwable;
|
|||||||
/**
|
/**
|
||||||
* Load configuration options from .toml files
|
* Load configuration options from .toml files
|
||||||
*
|
*
|
||||||
|
* @codeCoverageIgnore
|
||||||
* @param string $path - Path to load config
|
* @param string $path - Path to load config
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
function loadToml(string $path): array
|
function loadConfig(string $path): array
|
||||||
{
|
{
|
||||||
$output = [];
|
$output = [];
|
||||||
$files = glob("{$path}/*.toml");
|
$files = glob("{$path}/*.toml");
|
||||||
@ -75,6 +76,7 @@ function loadToml(string $path): array
|
|||||||
/**
|
/**
|
||||||
* Load config from one specific TOML file
|
* Load config from one specific TOML file
|
||||||
*
|
*
|
||||||
|
* @codeCoverageIgnore
|
||||||
* @param string $filename
|
* @param string $filename
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
@ -83,19 +85,11 @@ function loadTomlFile(string $filename): array
|
|||||||
return Toml::parseFile($filename);
|
return Toml::parseFile($filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
function _iterateToml(TomlBuilder $builder, iterable $data, $parentKey = NULL): void
|
||||||
* Serialize config data into a Toml file
|
|
||||||
*
|
|
||||||
* @param mixed $data
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
function arrayToToml(iterable $data): string
|
|
||||||
{
|
{
|
||||||
$builder = new TomlBuilder();
|
|
||||||
function _iterateToml(TomlBuilder $builder, iterable $data, $parentKey = NULL): void
|
|
||||||
{
|
|
||||||
foreach ($data as $key => $value)
|
foreach ($data as $key => $value)
|
||||||
{
|
{
|
||||||
|
// Skip unsupported empty value
|
||||||
if ($value === NULL)
|
if ($value === NULL)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
@ -104,7 +98,6 @@ function arrayToToml(iterable $data): string
|
|||||||
|
|
||||||
if (is_scalar($value) || isSequentialArray($value))
|
if (is_scalar($value) || isSequentialArray($value))
|
||||||
{
|
{
|
||||||
// $builder->addTable('');
|
|
||||||
$builder->addValue($key, $value);
|
$builder->addValue($key, $value);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -120,7 +113,17 @@ function arrayToToml(iterable $data): string
|
|||||||
|
|
||||||
_iterateToml($builder, $value, $newKey);
|
_iterateToml($builder, $value, $newKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialize config data into a Toml file
|
||||||
|
*
|
||||||
|
* @param mixed $data
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function arrayToToml(iterable $data): string
|
||||||
|
{
|
||||||
|
$builder = new TomlBuilder();
|
||||||
|
|
||||||
_iterateToml($builder, $data);
|
_iterateToml($builder, $data);
|
||||||
|
|
||||||
@ -339,7 +342,7 @@ function createPlaceholderImage ($path, ?int $width, ?int $height, $text = 'Imag
|
|||||||
*/
|
*/
|
||||||
function colNotEmpty(array $search, string $key): bool
|
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;
|
return count($items) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,7 +361,7 @@ function clearCache(CacheInterface $cache): bool
|
|||||||
Kitsu::AUTH_TOKEN_CACHE_KEY,
|
Kitsu::AUTH_TOKEN_CACHE_KEY,
|
||||||
Kitsu::AUTH_TOKEN_EXP_CACHE_KEY,
|
Kitsu::AUTH_TOKEN_EXP_CACHE_KEY,
|
||||||
Kitsu::AUTH_TOKEN_REFRESH_CACHE_KEY,
|
Kitsu::AUTH_TOKEN_REFRESH_CACHE_KEY,
|
||||||
], NULL);
|
]);
|
||||||
|
|
||||||
$userData = array_filter((array)$userData, static fn ($value) => $value !== NULL);
|
$userData = array_filter((array)$userData, static fn ($value) => $value !== NULL);
|
||||||
$cleared = $cache->clear();
|
$cleared = $cache->clear();
|
||||||
@ -373,6 +376,7 @@ function clearCache(CacheInterface $cache): bool
|
|||||||
/**
|
/**
|
||||||
* Render a PHP code template as a string
|
* Render a PHP code template as a string
|
||||||
*
|
*
|
||||||
|
* @codeCoverageIgnore
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @param array $data
|
* @param array $data
|
||||||
* @return string
|
* @return string
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
namespace Aviat\AnimeClient\Command;
|
namespace Aviat\AnimeClient\Command;
|
||||||
|
|
||||||
use Monolog\Formatter\JsonFormatter;
|
use Monolog\Formatter\JsonFormatter;
|
||||||
use function Aviat\AnimeClient\loadToml;
|
use function Aviat\AnimeClient\loadConfig;
|
||||||
use function Aviat\AnimeClient\loadTomlFile;
|
use function Aviat\AnimeClient\loadTomlFile;
|
||||||
|
|
||||||
use Aura\Router\RouterContainer;
|
use Aura\Router\RouterContainer;
|
||||||
@ -113,7 +113,7 @@ abstract class BaseCommand extends Command {
|
|||||||
$CONF_DIR = realpath("{$APP_DIR}/config/");
|
$CONF_DIR = realpath("{$APP_DIR}/config/");
|
||||||
$baseConfig = require $APPCONF_DIR . '/base_config.php';
|
$baseConfig = require $APPCONF_DIR . '/base_config.php';
|
||||||
|
|
||||||
$config = loadToml($CONF_DIR);
|
$config = loadConfig($CONF_DIR);
|
||||||
|
|
||||||
$overrideFile = $CONF_DIR . '/admin-override.toml';
|
$overrideFile = $CONF_DIR . '/admin-override.toml';
|
||||||
$overrideConfig = file_exists($overrideFile)
|
$overrideConfig = file_exists($overrideFile)
|
||||||
|
@ -51,17 +51,9 @@ final class FormGenerator {
|
|||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public static function new(ContainerInterface $container): self
|
public static function new(ContainerInterface $container): self
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
return new self($container);
|
return new self($container);
|
||||||
}
|
}
|
||||||
catch (\Throwable $e)
|
|
||||||
{
|
|
||||||
dump($e);
|
|
||||||
die();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate the html structure of the form
|
* Generate the html structure of the form
|
||||||
|
@ -412,17 +412,12 @@ final class Kitsu {
|
|||||||
/**
|
/**
|
||||||
* Determine if an alternate title is unique enough to list
|
* Determine if an alternate title is unique enough to list
|
||||||
*
|
*
|
||||||
* @param string|null $title
|
* @param string $title
|
||||||
* @param array $existingTitles
|
* @param array $existingTitles
|
||||||
* @return bool
|
* @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)
|
foreach($existingTitles as $existing)
|
||||||
{
|
{
|
||||||
$isSubset = mb_substr_count($existing, $title) > 0;
|
$isSubset = mb_substr_count($existing, $title) > 0;
|
||||||
|
@ -16,13 +16,16 @@
|
|||||||
|
|
||||||
namespace Aviat\AnimeClient\Tests;
|
namespace Aviat\AnimeClient\Tests;
|
||||||
|
|
||||||
|
use Amp\Http\Client\Response;
|
||||||
|
|
||||||
use function Aviat\AnimeClient\arrayToToml;
|
use function Aviat\AnimeClient\arrayToToml;
|
||||||
|
use function Aviat\AnimeClient\getResponse;
|
||||||
use function Aviat\AnimeClient\isSequentialArray;
|
use function Aviat\AnimeClient\isSequentialArray;
|
||||||
use function Aviat\AnimeClient\tomlToArray;
|
use function Aviat\AnimeClient\tomlToArray;
|
||||||
|
|
||||||
class AnimeClientTest extends AnimeClientTestCase
|
class AnimeClientTest extends AnimeClientTestCase
|
||||||
{
|
{
|
||||||
public function testArrayToToml ()
|
public function testArrayToToml (): void
|
||||||
{
|
{
|
||||||
$arr = [
|
$arr = [
|
||||||
'cat' => false,
|
'cat' => false,
|
||||||
@ -57,11 +60,33 @@ class AnimeClientTest extends AnimeClientTestCase
|
|||||||
$this->assertEquals($arr, $parsedArray);
|
$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(0));
|
||||||
$this->assertFalse(isSequentialArray([50 => 'foo']));
|
$this->assertFalse(isSequentialArray([50 => 'foo']));
|
||||||
$this->assertTrue(isSequentialArray([]));
|
$this->assertTrue(isSequentialArray([]));
|
||||||
$this->assertTrue(isSequentialArray([1,2,3,4,5]));
|
$this->assertTrue(isSequentialArray([1,2,3,4,5]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testGetResponse(): void
|
||||||
|
{
|
||||||
|
$this->assertNotEmpty(getResponse('https://example.com'));
|
||||||
|
}
|
||||||
}
|
}
|
@ -16,19 +16,110 @@
|
|||||||
|
|
||||||
namespace Aviat\AnimeClient\Tests\API;
|
namespace Aviat\AnimeClient\Tests\API;
|
||||||
|
|
||||||
|
use Aviat\AnimeClient\API\Kitsu\Enum\MangaPublishingStatus;
|
||||||
use Aviat\AnimeClient\Kitsu;
|
use Aviat\AnimeClient\Kitsu;
|
||||||
use Aviat\AnimeClient\API\Kitsu\Enum\AnimeAiringStatus;
|
use Aviat\AnimeClient\API\Kitsu\Enum\AnimeAiringStatus;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
class KitsuTest extends TestCase {
|
class KitsuTest extends TestCase {
|
||||||
public function testGetAiringStatus()
|
public function testGetAiringStatus(): void
|
||||||
{
|
{
|
||||||
$actual = Kitsu::getAiringStatus('next week', 'next year');
|
$actual = Kitsu::getAiringStatus('next week', 'next year');
|
||||||
$this->assertEquals(AnimeAiringStatus::NOT_YET_AIRED, $actual);
|
$this->assertEquals(AnimeAiringStatus::NOT_YET_AIRED, $actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testParseStreamingLinksEmpty()
|
public function testParseStreamingLinksEmpty(): void
|
||||||
{
|
{
|
||||||
$this->assertEquals([], Kitsu::parseStreamingLinks([]));
|
$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);
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user