Version 5.1 - All the GraphQL #32

Closed
timw4mail wants to merge 1160 commits from develop into master
54 changed files with 218 additions and 434 deletions
Showing only changes of commit 461d074d41 - Show all commits

View File

@ -1,8 +1,8 @@
# Hummingbird Anime Client # Hummingbird Anime Client
Update your anime/manga list on Kitsu.io and MyAnimeList.net Update your anime/manga list on Kitsu.io and Anilist
[![Build Status](https://travis-ci.org/timw4mail/HummingBirdAnimeClient.svg?branch=master)](https://travis-ci.org/timw4mail/HummingBirdAnimeClient) [![Build Status](https://travis-ci.com/timw4mail/HummingBirdAnimeClient.svg?branch=master)](https://travis-ci.com/github/timw4mail/HummingBirdAnimeClient)
[![Build Status](https://jenkins.timshomepage.net/buildStatus/icon?job=timw4mail/HummingBirdAnimeClient/develop)](https://jenkins.timshomepage.net/job/timw4mail/HummingBirdAnimeClient/develop) [![Build Status](https://jenkins.timshomepage.net/buildStatus/icon?job=timw4mail/HummingBirdAnimeClient/develop)](https://jenkins.timshomepage.net/job/timw4mail/HummingBirdAnimeClient/develop)
[[Hosted Example](https://list.timshomepage.net)] [[Hosted Example](https://list.timshomepage.net)]
@ -31,7 +31,7 @@ Update your anime/manga list on Kitsu.io and MyAnimeList.net
### Requirements ### Requirements
* PHP 7.3+ * PHP 7.4+
* PDO SQLite or PDO PostgreSQL (For collection tab) * PDO SQLite or PDO PostgreSQL (For collection tab)
* GD extension for caching images * GD extension for caching images

View File

@ -28,14 +28,15 @@ use Aviat\AnimeClient\Model;
use Aviat\Banker\Pool; use Aviat\Banker\Pool;
use Aviat\Ion\Config; use Aviat\Ion\Config;
use Aviat\Ion\Di\Container; use Aviat\Ion\Di\Container;
use Aviat\Ion\Di\ContainerInterface;
use Laminas\Diactoros\{Response, ServerRequestFactory};
use Monolog\Handler\RotatingFileHandler; use Monolog\Handler\RotatingFileHandler;
use Monolog\Logger; use Monolog\Logger;
use Zend\Diactoros\{Response, ServerRequestFactory};
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Setup DI container // Setup DI container
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
return static function ($configArray = []) { return static function (array $configArray = []): Container {
$container = new Container(); $container = new Container();
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
@ -60,26 +61,20 @@ return static function ($configArray = []) {
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Create Config Object // Create Config Object
$container->set('config', static function() use ($configArray) { $container->set('config', fn () => new Config($configArray));
return new Config($configArray);
});
// Create Cache Object // Create Cache Object
$container->set('cache', static function($container): Pool { $container->set('cache', static function(ContainerInterface $container): Pool {
$logger = $container->getLogger(); $logger = $container->getLogger();
$config = $container->get('config')->get('cache'); $config = $container->get('config')->get('cache');
return new Pool($config, $logger); return new Pool($config, $logger);
}); });
// Create List Cache
// Create Aura Router Object // Create Aura Router Object
$container->set('aura-router', static function() { $container->set('aura-router', fn() => new RouterContainer);
return new RouterContainer;
});
// Create Html helper Object // Create Html helper Object
$container->set('html-helper', static function($container) { $container->set('html-helper', static function(ContainerInterface $container) {
$htmlHelper = (new HelperLocatorFactory)->newInstance(); $htmlHelper = (new HelperLocatorFactory)->newInstance();
$htmlHelper->set('menu', static function() use ($container) { $htmlHelper->set('menu', static function() use ($container) {
$menuHelper = new Helper\Menu(); $menuHelper = new Helper\Menu();
@ -101,31 +96,23 @@ return static function ($configArray = []) {
}); });
// Create Request/Response Objects // Create Request/Response Objects
$container->set('request', static function() { $container->set('request', fn () => ServerRequestFactory::fromGlobals(
return ServerRequestFactory::fromGlobals(
$_SERVER, $_SERVER,
$_GET, $_GET,
$_POST, $_POST,
$_COOKIE, $_COOKIE,
$_FILES $_FILES
); ));
}); $container->set('response', fn () => new Response);
$container->set('response', static function() {
return new Response;
});
// Create session Object // Create session Object
$container->set('session', static function() { $container->set('session', fn () => (new SessionFactory())->newInstance($_COOKIE));
return (new SessionFactory())->newInstance($_COOKIE);
});
// Miscellaneous helper methods // Miscellaneous helper methods
$container->set('util', static function($container): Util { $container->set('util', fn ($container) => new Util($container));
return new Util($container);
});
// Models // Models
$container->set('kitsu-model', static function($container): Kitsu\Model { $container->set('kitsu-model', static function(ContainerInterface $container): Kitsu\Model {
$requestBuilder = new KitsuRequestBuilder(); $requestBuilder = new KitsuRequestBuilder();
$requestBuilder->setLogger($container->getLogger('kitsu-request')); $requestBuilder->setLogger($container->getLogger('kitsu-request'));
@ -141,7 +128,7 @@ return static function ($configArray = []) {
$model->setCache($cache); $model->setCache($cache);
return $model; return $model;
}); });
$container->set('anilist-model', static function($container): Anilist\Model { $container->set('anilist-model', static function(ContainerInterface $container): Anilist\Model {
$requestBuilder = new Anilist\AnilistRequestBuilder(); $requestBuilder = new Anilist\AnilistRequestBuilder();
$requestBuilder->setLogger($container->getLogger('anilist-request')); $requestBuilder->setLogger($container->getLogger('anilist-request'));
@ -155,19 +142,10 @@ return static function ($configArray = []) {
return $model; return $model;
}); });
$container->set('anime-model', fn ($container) => new Model\Anime($container));
$container->set('anime-model', static function($container) { $container->set('manga-model', fn ($container) => new Model\Manga($container));
return new Model\Anime($container); $container->set('anime-collection-model', fn ($container) => new Model\AnimeCollection($container));
}); $container->set('manga-collection-model', fn ($container) => new Model\MangaCollection($container));
$container->set('manga-model', static function($container) {
return new Model\Manga($container);
});
$container->set('anime-collection-model', static function($container) {
return new Model\AnimeCollection($container);
});
$container->set('manga-collection-model', static function($container) {
return new Model\MangaCollection($container);
});
$container->set('settings-model', static function($container) { $container->set('settings-model', static function($container) {
$model = new Model\Settings($container->get('config')); $model = new Model\Settings($container->get('config'));
$model->setContainer($container); $model->setContainer($container);
@ -175,19 +153,13 @@ return static function ($configArray = []) {
}); });
// Miscellaneous Classes // Miscellaneous Classes
$container->set('auth', static function($container) { $container->set('auth', fn ($container) => new Kitsu\Auth($container));
return new Kitsu\Auth($container); $container->set('url-generator', fn ($container) => new UrlGenerator($container));
});
$container->set('url-generator', static function($container) {
return new UrlGenerator($container);
});
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Dispatcher // Dispatcher
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
$container->set('dispatcher', static function($container) { $container->set('dispatcher', fn ($container) => new Dispatcher($container));
return new Dispatcher($container);
});
return $container; return $container;
}; };

View File

@ -75,20 +75,20 @@
<?php foreach($item['anime']['streaming_links'] as $link): ?> <?php foreach($item['anime']['streaming_links'] as $link): ?>
<?php if ($link['meta']['link'] !== FALSE): ?> <?php if ($link['meta']['link'] !== FALSE): ?>
<a href="<?= $link['link'] ?>" title="Stream '<?= $item['anime']['title'] ?>' on <?= $link['meta']['name'] ?>"> <a href="<?= $link['link'] ?>" title="Stream '<?= $item['anime']['title'] ?>' on <?= $link['meta']['name'] ?>">
<?= $helper->picture("images/{$link['meta']['image']}", 'svg', [ <?= $helper->img("/public/images/{$link['meta']['image']}", [
'class' => 'streaming-logo', 'class' => 'streaming-logo',
'width' => 50, 'width' => 50,
'height' => 50, 'height' => 50,
'alt' => "{$link['meta']['name']} logo", 'alt' => "{$link['meta']['name']} logo",
]); ?> ]) ?>
</a> </a>
<?php else: ?> <?php else: ?>
<?= $helper->picture("images/{$link['meta']['image']}", 'svg', [ <?= $helper->img("/public/images/{$link['meta']['image']}", [
'class' => 'streaming-logo', 'class' => 'streaming-logo',
'width' => 50, 'width' => 50,
'height' => 50, 'height' => 50,
'alt' => "{$link['meta']['name']} logo", 'alt' => "{$link['meta']['name']} logo",
]); ?> ]) ?>
<?php endif ?> <?php endif ?>
<?php endforeach ?> <?php endforeach ?>
</td> </td>

View File

@ -38,37 +38,37 @@ abstract class APIRequestBuilder {
* Url prefix for making url requests * Url prefix for making url requests
* @var string * @var string
*/ */
protected $baseUrl = ''; protected string $baseUrl = '';
/** /**
* Url path of the request * Url path of the request
* @var string * @var string
*/ */
protected $path = ''; protected string $path = '';
/** /**
* Query string for the request * Query string for the request
* @var string * @var string
*/ */
protected $query = ''; protected string $query = '';
/** /**
* Default request headers * Default request headers
* @var array * @var array
*/ */
protected $defaultHeaders = []; protected array $defaultHeaders = [];
/** /**
* Valid HTTP request methods * Valid HTTP request methods
* @var array * @var array
*/ */
protected $validMethods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS']; protected array $validMethods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'];
/** /**
* The current request * The current request
* @var Request * @var Request
*/ */
protected $request; protected Request $request;
/** /**
* Do a basic minimal GET request * Do a basic minimal GET request
@ -78,8 +78,10 @@ abstract class APIRequestBuilder {
*/ */
public static function simpleRequest(string $uri): Request public static function simpleRequest(string $uri): Request
{ {
return (new Request($uri)) $request = (new Request($uri));
->setHeader('User-Agent', USER_AGENT); $request->setHeader('User-Agent', USER_AGENT);
return $request;
} }
/** /**

View File

@ -26,20 +26,20 @@ final class AnilistRequestBuilder extends APIRequestBuilder {
* The base url for api requests * The base url for api requests
* @var string $base_url * @var string $base_url
*/ */
protected $baseUrl = 'https://graphql.anilist.co'; protected string $baseUrl = 'https://graphql.anilist.co';
/** /**
* Valid HTTP request methods * Valid HTTP request methods
* @var array * @var array
*/ */
protected $validMethods = ['POST']; protected array $validMethods = ['POST'];
/** /**
* HTTP headers to send with every request * HTTP headers to send with every request
* *
* @var array * @var array
*/ */
protected $defaultHeaders = [ protected array $defaultHeaders = [
'User-Agent' => USER_AGENT, 'User-Agent' => USER_AGENT,
'Accept' => 'application/json', 'Accept' => 'application/json',
'Content-Type' => 'application/json', 'Content-Type' => 'application/json',

View File

@ -38,20 +38,20 @@ trait AnilistTrait {
* The request builder for the Anilist API * The request builder for the Anilist API
* @var AnilistRequestBuilder * @var AnilistRequestBuilder
*/ */
protected $requestBuilder; protected AnilistRequestBuilder $requestBuilder;
/** /**
* The base url for api requests * The base url for api requests
* @var string $base_url * @var string $base_url
*/ */
protected $baseUrl = Anilist::BASE_URL; protected string $baseUrl = Anilist::BASE_URL;
/** /**
* HTTP headers to send with every request * HTTP headers to send with every request
* *
* @var array * @var array
*/ */
protected $defaultHeaders = [ protected array $defaultHeaders = [
'Accept' => 'application/json', 'Accept' => 'application/json',
'Accept-Encoding' => 'gzip', 'Accept-Encoding' => 'gzip',
'Content-type' => 'application/json', 'Content-type' => 'application/json',

View File

@ -39,7 +39,7 @@ final class Model
/** /**
* @var ListItem * @var ListItem
*/ */
private $listItem; private ListItem $listItem;
/** /**
* Constructor * Constructor

View File

@ -26,7 +26,7 @@ trait CacheTrait {
/** /**
* @var Pool * @var Pool
*/ */
protected $cache; protected Pool $cache;
/** /**
* Inject the cache object * Inject the cache object

View File

@ -42,14 +42,14 @@ final class Auth {
* *
* @var Model * @var Model
*/ */
private $model; private Model $model;
/** /**
* Session object * Session object
* *
* @var Segment * @var Segment
*/ */
private $segment; private Segment $segment;
/** /**
* Constructor * Constructor

View File

@ -25,14 +25,14 @@ final class KitsuRequestBuilder extends APIRequestBuilder {
* The base url for api requests * The base url for api requests
* @var string $base_url * @var string $base_url
*/ */
protected $baseUrl = 'https://kitsu.io/api/edge/'; protected string $baseUrl = 'https://kitsu.io/api/edge/';
/** /**
* HTTP headers to send with every request * HTTP headers to send with every request
* *
* @var array * @var array
*/ */
protected $defaultHeaders = [ protected array $defaultHeaders = [
'User-Agent' => USER_AGENT, 'User-Agent' => USER_AGENT,
'Accept' => 'application/vnd.api+json', 'Accept' => 'application/vnd.api+json',
'Content-Type' => 'application/vnd.api+json', 'Content-Type' => 'application/vnd.api+json',

View File

@ -38,7 +38,7 @@ trait KitsuTrait {
* The request builder for the Kitsu API * The request builder for the Kitsu API
* @var KitsuRequestBuilder * @var KitsuRequestBuilder
*/ */
protected $requestBuilder; protected KitsuRequestBuilder $requestBuilder;
/** /**
* Set the request builder object * Set the request builder object

View File

@ -65,27 +65,27 @@ final class Model {
* *
* @var AnimeListTransformer * @var AnimeListTransformer
*/ */
private $animeListTransformer; private AnimeListTransformer $animeListTransformer;
/** /**
* @var AnimeTransformer * @var AnimeTransformer
*/ */
private $animeTransformer; private AnimeTransformer $animeTransformer;
/** /**
* @var ListItem * @var ListItem
*/ */
private $listItem; private ListItem $listItem;
/** /**
* @var MangaTransformer * @var MangaTransformer
*/ */
private $mangaTransformer; private MangaTransformer $mangaTransformer;
/** /**
* @var MangaListTransformer * @var MangaListTransformer
*/ */
private $mangaListTransformer; private MangaListTransformer $mangaListTransformer;
/** /**
* Constructor * Constructor

View File

@ -22,6 +22,7 @@ use Aviat\AnimeClient\Types\{
AnimeListItem AnimeListItem
}; };
use Aviat\Ion\Transformer\AbstractTransformer; use Aviat\Ion\Transformer\AbstractTransformer;
use Aviat\Ion\Type\StringType;
/** /**
* Transformer for anime list * Transformer for anime list
@ -100,7 +101,7 @@ final class AnimeListTransformer extends AbstractTransformer {
'title' => $title, 'title' => $title,
'titles' => $titles, 'titles' => $titles,
'slug' => $anime['slug'], 'slug' => $anime['slug'],
'show_type' => (string)$this->string($anime['subtype'])->upperCaseFirst(), 'show_type' => (string)StringType::from($anime['subtype'])->upperCaseFirst(),
'cover_image' => $anime['posterImage']['small'], 'cover_image' => $anime['posterImage']['small'],
'genres' => $genres, 'genres' => $genres,
'streaming_links' => $streamingLinks, 'streaming_links' => $streamingLinks,

View File

@ -19,6 +19,7 @@ namespace Aviat\AnimeClient\API\Kitsu\Transformer;
use Aviat\AnimeClient\API\{JsonAPI, Kitsu}; use Aviat\AnimeClient\API\{JsonAPI, Kitsu};
use Aviat\AnimeClient\Types\AnimePage; use Aviat\AnimeClient\Types\AnimePage;
use Aviat\Ion\Transformer\AbstractTransformer; use Aviat\Ion\Transformer\AbstractTransformer;
use Aviat\Ion\Type\StringType;
/** /**
* Transformer for anime description page * Transformer for anime description page
@ -114,7 +115,7 @@ final class AnimeTransformer extends AbstractTransformer {
'genres' => $item['genres'], 'genres' => $item['genres'],
'id' => $item['id'], 'id' => $item['id'],
'included' => $item['included'], 'included' => $item['included'],
'show_type' => (string)$this->string($item['showType'])->upperCaseFirst(), 'show_type' => (string)StringType::from($item['showType'])->upperCaseFirst(),
'slug' => $item['slug'], 'slug' => $item['slug'],
'staff' => $staff, 'staff' => $staff,
'status' => Kitsu::getAiringStatus($item['startDate'], $item['endDate']), 'status' => Kitsu::getAiringStatus($item['startDate'], $item['endDate']),

View File

@ -21,16 +21,13 @@ use Aviat\AnimeClient\Types\{
FormItem, FormItemData, FormItem, FormItemData,
MangaListItem, MangaListItemDetail MangaListItem, MangaListItemDetail
}; };
use Aviat\Ion\StringWrapper;
use Aviat\Ion\Transformer\AbstractTransformer; use Aviat\Ion\Transformer\AbstractTransformer;
use Aviat\Ion\Type\StringType;
/** /**
* Data transformation class for zippered Hummingbird manga * Data transformation class for zippered Hummingbird manga
*/ */
final class MangaListTransformer extends AbstractTransformer { final class MangaListTransformer extends AbstractTransformer {
use StringWrapper;
/** /**
* Remap zipped anime data to a more logical form * Remap zipped anime data to a more logical form
* *
@ -103,7 +100,7 @@ final class MangaListTransformer extends AbstractTransformer {
'slug' => $manga['slug'], 'slug' => $manga['slug'],
'title' => $title, 'title' => $title,
'titles' => $titles, 'titles' => $titles,
'type' => (string)$this->string($manga['subtype'])->upperCaseFirst(), 'type' => (string)StringType::from($manga['subtype'])->upperCaseFirst(),
'url' => 'https://kitsu.io/manga/' . $manga['slug'], 'url' => 'https://kitsu.io/manga/' . $manga['slug'],
]), ]),
'reading_status' => $item['attributes']['status'], 'reading_status' => $item['attributes']['status'],

View File

@ -33,7 +33,7 @@ final class ParallelAPIRequest {
* *
* @var array * @var array
*/ */
private $requests = []; private array $requests = [];
/** /**
* Add a request * Add a request

View File

@ -29,9 +29,9 @@ use Aviat\Ion\Config;
use Aviat\Ion\Di\{Container, ContainerAware}; use Aviat\Ion\Di\{Container, ContainerAware};
use ConsoleKit\{Command, ConsoleException}; use ConsoleKit\{Command, ConsoleException};
use ConsoleKit\Widgets\Box; use ConsoleKit\Widgets\Box;
use Laminas\Diactoros\{Response, ServerRequestFactory};
use Monolog\Handler\RotatingFileHandler; use Monolog\Handler\RotatingFileHandler;
use Monolog\Logger; use Monolog\Logger;
use Zend\Diactoros\{Response, ServerRequestFactory};
/** /**
* Base class for console command setup * Base class for console command setup

View File

@ -44,13 +44,13 @@ final class SyncLists extends BaseCommand {
* Model for making requests to Anilist API * Model for making requests to Anilist API
* @var AnilistModel * @var AnilistModel
*/ */
protected $anilistModel; protected AnilistModel $anilistModel;
/** /**
* Model for making requests to Kitsu API * Model for making requests to Kitsu API
* @var KitsuModel * @var KitsuModel
*/ */
protected $kitsuModel; protected KitsuModel $kitsuModel;
/** /**
* Run the Kitsu <=> Anilist sync script * Run the Kitsu <=> Anilist sync script

View File

@ -17,7 +17,7 @@
namespace Aviat\AnimeClient\Command; namespace Aviat\AnimeClient\Command;
use Aviat\AnimeClient\API\JsonAPI; use Aviat\AnimeClient\API\JsonAPI;
use Aviat\AnimeClient\API\Kitsu\Model; use Aviat\AnimeClient\API\Kitsu\Model as KitsuModel;
use Aviat\AnimeClient\Controller\Images; use Aviat\AnimeClient\Controller\Images;
/** /**
@ -27,14 +27,14 @@ use Aviat\AnimeClient\Controller\Images;
final class UpdateThumbnails extends ClearThumbnails { final class UpdateThumbnails extends ClearThumbnails {
/** /**
* Model for making requests to Kitsu API * Model for making requests to Kitsu API
* @var Model * @var KitsuModel
*/ */
protected $kitsuModel; protected KitsuModel $kitsuModel;
/** /**
* The default controller, which has the method to cache the images * The default controller, which has the method to cache the images
*/ */
protected $controller; protected Images $controller;
public function execute(array $args, array $options = []): void public function execute(array $args, array $options = []): void
{ {

View File

@ -47,55 +47,55 @@ class Controller {
* The authentication object * The authentication object
* @var Auth $auth ; * @var Auth $auth ;
*/ */
protected $auth; protected Auth $auth;
/** /**
* Cache manager * Cache manager
* @var CacheItemPoolInterface * @var CacheItemPoolInterface
*/ */
protected $cache; protected CacheItemPoolInterface $cache;
/** /**
* The global configuration object * The global configuration object
* @var ConfigInterface $config * @var ConfigInterface $config
*/ */
public $config; public ConfigInterface $config;
/** /**
* Request object * Request object
* @var ServerRequestInterface $request * @var ServerRequestInterface $request
*/ */
protected $request; protected ServerRequestInterface $request;
/** /**
* Response object * Response object
* @var ResponseInterface $response * @var ResponseInterface $response
*/ */
public $response; public ResponseInterface $response;
/** /**
* Url generation class * Url generation class
* @var UrlGenerator * @var UrlGenerator
*/ */
protected $urlGenerator; protected UrlGenerator $urlGenerator;
/** /**
* Aura url generator * Aura url generator
* @var Generator * @var Generator
*/ */
protected $url; protected Generator $url;
/** /**
* Session segment * Session segment
* @var Segment * @var Segment
*/ */
protected $session; protected Segment $session;
/** /**
* Common data to be sent to views * Common data to be sent to views
* @var array * @var array
*/ */
protected $baseData = []; protected array $baseData = [];
/** /**
* Controller constructor. * Controller constructor.

View File

@ -21,6 +21,7 @@ use Aviat\AnimeClient\Controller as BaseController;
use Aviat\AnimeClient\API\Kitsu\Transformer\AnimeListTransformer; use Aviat\AnimeClient\API\Kitsu\Transformer\AnimeListTransformer;
use Aviat\AnimeClient\API\Enum\AnimeWatchingStatus\Kitsu as KitsuWatchingStatus; use Aviat\AnimeClient\API\Enum\AnimeWatchingStatus\Kitsu as KitsuWatchingStatus;
use Aviat\AnimeClient\API\Mapping\AnimeWatchingStatus; use Aviat\AnimeClient\API\Mapping\AnimeWatchingStatus;
use Aviat\AnimeClient\Model\Anime as AnimeModel;
use Aviat\AnimeClient\Types\FormItem; use Aviat\AnimeClient\Types\FormItem;
use Aviat\Ion\Di\ContainerInterface; use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\Di\Exception\ContainerException; use Aviat\Ion\Di\Exception\ContainerException;
@ -37,9 +38,9 @@ final class Anime extends BaseController {
/** /**
* The anime list model * The anime list model
* @var \Aviat\AnimeClient\Model\Anime $model * @var AnimeModel $model
*/ */
protected $model; protected AnimeModel $model;
/** /**
* Constructor * Constructor

View File

@ -38,13 +38,13 @@ final class AnimeCollection extends BaseController {
* The anime collection model * The anime collection model
* @var AnimeCollectionModel $animeCollectionModel * @var AnimeCollectionModel $animeCollectionModel
*/ */
private $animeCollectionModel; private AnimeCollectionModel $animeCollectionModel;
/** /**
* The anime API model * The anime API model
* @var AnimeModel $animeModel * @var AnimeModel $animeModel
*/ */
private $animeModel; private AnimeModel $animeModel;
/** /**
* Constructor * Constructor

View File

@ -32,7 +32,7 @@ class Character extends BaseController {
/** /**
* @var Model * @var Model
*/ */
private $model; private Model $model;
/** /**
* Character constructor. * Character constructor.

View File

@ -38,7 +38,7 @@ final class Manga extends Controller {
* The manga model * The manga model
* @var MangaModel $model * @var MangaModel $model
*/ */
protected $model; protected MangaModel $model;
/** /**
* Constructor * Constructor

View File

@ -32,7 +32,7 @@ final class People extends BaseController {
/** /**
* @var Model * @var Model
*/ */
private $model; private Model $model;
/** /**
* People constructor. * People constructor.

View File

@ -17,8 +17,9 @@
namespace Aviat\AnimeClient\Controller; namespace Aviat\AnimeClient\Controller;
use Aura\Router\Exception\RouteNotFound; use Aura\Router\Exception\RouteNotFound;
use Aviat\AnimeClient\API\Anilist\Model; use Aviat\AnimeClient\API\Anilist\Model as AnilistModel;
use Aviat\AnimeClient\Controller as BaseController; use Aviat\AnimeClient\Controller as BaseController;
use Aviat\AnimeClient\Model\Settings as SettingsModel;
use Aviat\Ion\Di\ContainerInterface; use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\Di\Exception\ContainerException; use Aviat\Ion\Di\Exception\ContainerException;
use Aviat\Ion\Di\Exception\NotFoundException; use Aviat\Ion\Di\Exception\NotFoundException;
@ -29,14 +30,14 @@ use Aviat\Ion\Di\Exception\NotFoundException;
final class Settings extends BaseController { final class Settings extends BaseController {
/** /**
* @var Model * @var AnilistModel
*/ */
private $anilistModel; private AnilistModel $anilistModel;
/** /**
* @var \Aviat\AnimeClient\Model\Settings * @var SettingsModel
*/ */
private $settingsModel; private SettingsModel $settingsModel;
/** /**
* Settings constructor. * Settings constructor.

View File

@ -32,7 +32,7 @@ final class User extends BaseController {
/** /**
* @var Model * @var Model
*/ */
private $kitsuModel; private Model $kitsuModel;
/** /**
* User constructor. * User constructor.

View File

@ -18,13 +18,12 @@ namespace Aviat\AnimeClient;
use function Aviat\Ion\_dir; use function Aviat\Ion\_dir;
use Aura\Router\{Matcher, Route, Rule}; use Aura\Router\{Map, Matcher, Route, Rule};
use Aviat\AnimeClient\API\FailedResponseException; use Aviat\AnimeClient\API\FailedResponseException;
use Aviat\Ion\Di\ContainerInterface; use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\Friend; use Aviat\Ion\Friend;
use Aviat\Ion\StringWrapper; use Aviat\Ion\Type\StringType;
use LogicException; use LogicException;
use ReflectionException; use ReflectionException;
@ -33,31 +32,29 @@ use ReflectionException;
*/ */
final class Dispatcher extends RoutingBase { final class Dispatcher extends RoutingBase {
use StringWrapper;
/** /**
* The route-matching object * The route-matching object
* @var object $router * @var Map $router
*/ */
protected $router; protected Map $router;
/** /**
* The route matcher * The route matcher
* @var Matcher $matcher * @var Matcher $matcher
*/ */
protected $matcher; protected Matcher $matcher;
/** /**
* Routing array * Routing array
* @var array * @var array
*/ */
protected $routes; protected array $routes;
/** /**
* Routes added to router * Routes added to router
* @var array $outputRoutes * @var array $outputRoutes
*/ */
protected $outputRoutes; protected array $outputRoutes;
/** /**
* Constructor * Constructor
@ -254,7 +251,7 @@ final class Dispatcher extends RoutingBase {
foreach ($classFiles as $file) foreach ($classFiles as $file)
{ {
$rawClassName = basename(str_replace('.php', '', $file)); $rawClassName = basename(str_replace('.php', '', $file));
$path = (string)$this->string($rawClassName)->dasherize(); $path = (string)StringType::from($rawClassName)->dasherize();
$className = trim($defaultNamespace . '\\' . $rawClassName, '\\'); $className = trim($defaultNamespace . '\\' . $rawClassName, '\\');
$controllers[$path] = $className; $controllers[$path] = $className;

View File

@ -30,7 +30,7 @@ final class FormGenerator {
* *
* @var HelperLocator * @var HelperLocator
*/ */
private $helper; private HelperLocator $helper;
/** /**
* FormGenerator constructor. * FormGenerator constructor.
@ -93,6 +93,9 @@ final class FormGenerator {
$params['type'] = 'select'; $params['type'] = 'select';
$params['options'] = array_flip($form['options']); $params['options'] = array_flip($form['options']);
break; break;
default:
break;
} }
foreach (['readonly', 'disabled'] as $key) foreach (['readonly', 'disabled'] as $key)

View File

@ -16,11 +16,12 @@
namespace Aviat\AnimeClient; namespace Aviat\AnimeClient;
use Aviat\Ion\{ArrayWrapper, StringWrapper};
use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException}; use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException};
use Aura\Html\HelperLocator; use Aura\Html\HelperLocator;
use Aviat\Ion\Di\ContainerInterface; use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\Exception\ConfigException; use Aviat\Ion\Exception\ConfigException;
use Aviat\Ion\Type\ArrayType;
use Aviat\Ion\Type\StringType;
use Psr\Http\Message\RequestInterface; use Psr\Http\Message\RequestInterface;
/** /**
@ -28,22 +29,19 @@ use Psr\Http\Message\RequestInterface;
*/ */
final class MenuGenerator extends UrlGenerator { final class MenuGenerator extends UrlGenerator {
use ArrayWrapper;
use StringWrapper;
/** /**
* Html generation helper * Html generation helper
* *
* @var HelperLocator * @var HelperLocator
*/ */
protected $helper; protected HelperLocator $helper;
/** /**
* Request object * Request object
* *
* @var RequestInterface * @var RequestInterface
*/ */
protected $request; protected RequestInterface $request;
/** /**
* MenuGenerator constructor. * MenuGenerator constructor.
@ -74,8 +72,8 @@ final class MenuGenerator extends UrlGenerator {
$parsed[$name] = []; $parsed[$name] = [];
foreach ($menu['items'] as $pathName => $partialPath) foreach ($menu['items'] as $pathName => $partialPath)
{ {
$title = (string)$this->string($pathName)->humanize()->titleize(); $title = (string)StringType::from($pathName)->humanize()->titleize();
$parsed[$name][$title] = (string)$this->string($menu['route_prefix'])->append($partialPath); $parsed[$name][$title] = (string)StringType::from($menu['route_prefix'])->append($partialPath);
} }
} }
@ -95,7 +93,7 @@ final class MenuGenerator extends UrlGenerator {
$parsedConfig = $this->parseConfig($menus); $parsedConfig = $this->parseConfig($menus);
// Bail out early on invalid menu // Bail out early on invalid menu
if ( ! $this->arr($parsedConfig)->hasKey($menu)) if ( ! ArrayType::from($parsedConfig)->hasKey($menu))
{ {
return ''; return '';
} }
@ -104,7 +102,7 @@ final class MenuGenerator extends UrlGenerator {
foreach ($menuConfig as $title => $path) foreach ($menuConfig as $title => $path)
{ {
$has = $this->string($this->path())->contains($path); $has = StringType::from($this->path())->contains($path);
$selected = ($has && mb_strlen($this->path()) >= mb_strlen($path)); $selected = ($has && mb_strlen($this->path()) >= mb_strlen($path));
$link = $this->helper->a($this->url($path), $title); $link = $this->helper->a($this->url($path), $title);

View File

@ -40,21 +40,21 @@ class Anime extends API {
* *
* @var boolean * @var boolean
*/ */
protected $anilistEnabled; protected bool $anilistEnabled;
/** /**
* Model for making requests to Anilist API * Model for making requests to Anilist API
* *
* @var AnilistModel * @var AnilistModel
*/ */
protected $anilistModel; protected AnilistModel $anilistModel;
/** /**
* Model for making requests to Kitsu API * Model for making requests to Kitsu API
* *
* @var KitsuModel * @var KitsuModel
*/ */
protected $kitsuModel; protected KitsuModel $kitsuModel;
/** /**
* Anime constructor. * Anime constructor.

View File

@ -29,7 +29,7 @@ final class AnimeCollection extends Collection {
* Anime API Model * Anime API Model
* @var Anime $animeModel * @var Anime $animeModel
*/ */
protected $animeModel; protected Anime $animeModel;
/** /**
* Create the collection model * Create the collection model

View File

@ -31,13 +31,13 @@ class Collection extends DB {
* The query builder object * The query builder object
* @var Query_Builder_Interface * @var Query_Builder_Interface
*/ */
protected $db; protected Query_Builder_Interface $db;
/** /**
* Whether the database is valid for querying * Whether the database is valid for querying
* @var boolean * @var boolean
*/ */
protected $validDatabase = FALSE; protected bool $validDatabase = FALSE;
/** /**
* Create a new collection object * Create a new collection object

View File

@ -26,6 +26,7 @@ use Aviat\AnimeClient\Types\{
MangaListItem, MangaListItem,
MangaPage MangaPage
}; };
use Aviat\AnimeClient\API\{Anilist, Kitsu};
use Aviat\Ion\Di\ContainerInterface; use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\Json; use Aviat\Ion\Json;
@ -40,19 +41,19 @@ class Manga extends API {
* *
* @var boolean * @var boolean
*/ */
protected $anilistEnabled; protected bool $anilistEnabled;
/** /**
* Model for making requests to the Anilist API * Model for making requests to the Anilist API
* @var \Aviat\AnimeClient\API\Anilist\Model * @var Anilist\Model
*/ */
protected $anilistModel; protected Anilist\Model $anilistModel;
/** /**
* Model for making requests to Kitsu API * Model for making requests to Kitsu API
* @var \Aviat\AnimeClient\API\Kitsu\Model * @var Kitsu\Model
*/ */
protected $kitsuModel; protected Kitsu\Model $kitsuModel;
/** /**
* Constructor * Constructor

View File

@ -25,16 +25,14 @@ use Aviat\AnimeClient\Types\{Config, UndefinedPropertyException};
use Aviat\Ion\ConfigInterface; use Aviat\Ion\ConfigInterface;
use Aviat\Ion\Di\ContainerAware; use Aviat\Ion\Di\ContainerAware;
use Aviat\Ion\StringWrapper;
/** /**
* Model for handling settings control panel * Model for handling settings control panel
*/ */
final class Settings { final class Settings {
use ContainerAware; use ContainerAware;
use StringWrapper;
private $config; private ConfigInterface $config;
public function __construct(ConfigInterface $config) public function __construct(ConfigInterface $config)
{ {

View File

@ -16,38 +16,36 @@
namespace Aviat\AnimeClient; namespace Aviat\AnimeClient;
use Aviat\Ion\Config; use Aviat\Ion\ConfigInterface;
use Aviat\Ion\Di\ContainerInterface; use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\Di\Exception\ContainerException; use Aviat\Ion\Di\Exception\ContainerException;
use Aviat\Ion\Di\Exception\NotFoundException; use Aviat\Ion\Di\Exception\NotFoundException;
use Aviat\Ion\Exception\ConfigException; use Aviat\Ion\Exception\ConfigException;
use Aviat\Ion\StringWrapper; use Aviat\Ion\Type\StringType;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\RequestInterface;
/** /**
* Base for routing/url classes * Base for routing/url classes
*/ */
class RoutingBase { class RoutingBase {
use StringWrapper;
/** /**
* Injection Container * Injection Container
* @var ContainerInterface $container * @var ContainerInterface $container
*/ */
protected $container; protected ContainerInterface $container;
/** /**
* Config Object * Config Object
* @var Config * @var ConfigInterface
*/ */
protected $config; protected ConfigInterface $config;
/** /**
* Class wrapper for input superglobals * Class wrapper for input superglobals
* @var ServerRequestInterface * @var RequestInterface
*/ */
protected $request; protected RequestInterface $request;
/** /**
* Constructor * Constructor
@ -73,7 +71,7 @@ class RoutingBase {
public function path(): string public function path(): string
{ {
$path = $this->request->getUri()->getPath(); $path = $this->request->getUri()->getPath();
$cleanedPath = $this->string($path) $cleanedPath = StringType::from($path)
->replace('%20', '') ->replace('%20', '')
->trim() ->trim()
->trimRight('/') ->trimRight('/')

View File

@ -30,7 +30,7 @@ class UrlGenerator extends RoutingBase {
* The current HTTP host * The current HTTP host
* @var string * @var string
*/ */
protected $host; protected string $host;
/** /**
* Constructor * Constructor
@ -49,7 +49,7 @@ class UrlGenerator extends RoutingBase {
/** /**
* Get the base url for css/js/images * Get the base url for css/js/images
* *
* @param string ...$args * @param array $args
* @return string * @return string
*/ */
public function assetUrl(string ...$args): string public function assetUrl(string ...$args): string

View File

@ -30,7 +30,7 @@ class Util {
* Routes that don't require a second navigation level * Routes that don't require a second navigation level
* @var array * @var array
*/ */
private static $formPages = [ private static array $formPages = [
'edit', 'edit',
'add', 'add',
'update', 'update',

View File

@ -1,38 +0,0 @@
<?php declare(strict_types=1);
/**
* Hummingbird Anime List Client
*
* An API client for Kitsu to manage anime and manga watch lists
*
* PHP version 7.4
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2020 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 5
* @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
*/
namespace Aviat\Ion;
use Aviat\Ion\Type\ArrayType;
/**
* Wrapper to shortcut creating ArrayType objects
*/
trait ArrayWrapper {
/**
* Convenience method for wrapping an array
* with the array type class
*
* @param array $arr
* @return ArrayType
*/
public function arr(array $arr): ArrayType
{
return new ArrayType($arr);
}
}
// End of ArrayWrapper.php

View File

@ -25,14 +25,12 @@ use InvalidArgumentException;
*/ */
class Config implements ConfigInterface { class Config implements ConfigInterface {
use ArrayWrapper;
/** /**
* Config object * Config object
* *
* @var ArrayType * @var ArrayType
*/ */
protected $map; protected ArrayType $map;
/** /**
* Constructor * Constructor
@ -41,7 +39,7 @@ class Config implements ConfigInterface {
*/ */
public function __construct(array $configArray = []) public function __construct(array $configArray = [])
{ {
$this->map = $this->arr($configArray); $this->map = ArrayType::from($configArray);
} }
/** /**

View File

@ -20,6 +20,5 @@ namespace Aviat\Ion;
* Common base for all Models * Common base for all Models
*/ */
class Model { class Model {
use StringWrapper;
} }
// End of Model.php // End of Model.php

View File

@ -1,55 +0,0 @@
<?php declare(strict_types=1);
/**
* Hummingbird Anime List Client
*
* An API client for Kitsu to manage anime and manga watch lists
*
* PHP version 7.4
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2020 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 5
* @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
*/
namespace Aviat\Ion\Model;
use Aviat\Ion\ConfigInterface;
use Aviat\Ion\Model as BaseModel;
/**
* Base model for database interaction
*/
class DB extends BaseModel {
/**
* The query builder object
* @var object $db
*/
protected $db;
/**
* The config manager
* @var ConfigInterface
*/
protected $config;
/**
* The database connection information array
* @var array $db_config
*/
protected $db_config;
/**
* Constructor
*
* @param ConfigInterface $config
*/
public function __construct(ConfigInterface $config)
{
$this->config = $config;
$this->db_config = (array)$config->get('database');
}
}
// End of DB.php

View File

@ -1,38 +0,0 @@
<?php declare(strict_types=1);
/**
* Hummingbird Anime List Client
*
* An API client for Kitsu to manage anime and manga watch lists
*
* PHP version 7.4
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2020 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 5
* @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
*/
namespace Aviat\Ion;
use Aviat\Ion\Type\StringType;
/**
* Trait to add convenience method for creating StringType objects
*/
trait StringWrapper {
/**
* Wrap the String in the Stringy class
*
* @param string $str
* @throws \InvalidArgumentException
* @return StringType
*/
public function string($str): StringType
{
return StringType::create($str);
}
}
// End of StringWrapper.php

View File

@ -16,17 +16,12 @@
namespace Aviat\Ion\Transformer; namespace Aviat\Ion\Transformer;
use Aviat\Ion\StringWrapper;
use BadMethodCallException; use BadMethodCallException;
/** /**
* Base class for data transformation * Base class for data transformation
*/ */
abstract class AbstractTransformer implements TransformerInterface { abstract class AbstractTransformer implements TransformerInterface {
use StringWrapper;
/** /**
* Mutate the data structure * Mutate the data structure
* *

View File

@ -32,14 +32,14 @@ class ArrayType {
* *
* @var array * @var array
*/ */
protected $arr; protected array $arr;
/** /**
* Map generated methods to their native implementations * Map generated methods to their native implementations
* *
* @var array * @var array
*/ */
protected $nativeMethods = [ protected array $nativeMethods = [
'chunk' => 'array_chunk', 'chunk' => 'array_chunk',
'diff' => 'array_diff', 'diff' => 'array_diff',
'filter' => 'array_filter', 'filter' => 'array_filter',
@ -64,7 +64,7 @@ class ArrayType {
* *
* @var array * @var array
*/ */
protected $nativeInPlaceMethods = [ protected array $nativeInPlaceMethods = [
'shuffle' => 'shuffle', 'shuffle' => 'shuffle',
'shift' => 'array_shift', 'shift' => 'array_shift',
'unshift' => 'array_unshift', 'unshift' => 'array_unshift',
@ -72,12 +72,23 @@ class ArrayType {
'pop' => 'array_pop', 'pop' => 'array_pop',
]; ];
/**
* Create an ArrayType wrapper class from an array
*
* @param array $arr
* @return ArrayType
*/
public static function from(array $arr): ArrayType
{
return new ArrayType($arr);
}
/** /**
* Create an ArrayType wrapper class * Create an ArrayType wrapper class
* *
* @param array $arr * @param array $arr
*/ */
public function __construct(array &$arr) private function __construct(array &$arr)
{ {
$this->arr =& $arr; $this->arr =& $arr;
} }
@ -227,7 +238,7 @@ class ArrayType {
/** /**
* Return a reference to the value of an arbitrary key on the array * Return a reference to the value of an arbitrary key on the array
* *
* @example $arr = new ArrayType([0 => ['data' => ['foo' => 'bar']]]); * @example $arr = ArrayType::from([0 => ['data' => ['foo' => 'bar']]]);
* $val = $arr->getDeepKey([0, 'data', 'foo']); * $val = $arr->getDeepKey([0, 'data', 'foo']);
* // returns 'bar' * // returns 'bar'
* @param array $key An array of keys of the array * @param array $key An array of keys of the array

View File

@ -23,6 +23,17 @@ use Stringy\Stringy;
*/ */
class StringType extends Stringy { class StringType extends Stringy {
/**
* Alias for `create` static constructor
*
* @param string $str
* @return $this
*/
public static function from(string $str): self
{
return self::create($str);
}
/** /**
* See if two strings match, despite being delimited differently, * See if two strings match, despite being delimited differently,
* such as camelCase, PascalCase, kebab-case, or snake_case. * such as camelCase, PascalCase, kebab-case, or snake_case.

View File

@ -29,14 +29,13 @@ abstract class View
implements ViewInterface { implements ViewInterface {
use Di\ContainerAware; use Di\ContainerAware;
use StringWrapper;
/** /**
* HTTP response Object * HTTP response Object
* *
* @var ResponseInterface * @var ResponseInterface
*/ */
public $response; public ResponseInterface $response;
/** /**
* If the view has sent output via * If the view has sent output via
@ -44,7 +43,7 @@ abstract class View
* *
* @var boolean * @var boolean
*/ */
protected $hasRendered = FALSE; protected bool $hasRendered = FALSE;
/** /**
* Constructor * Constructor

View File

@ -30,9 +30,9 @@ class APIRequestBuilderTest extends TestCase {
public function setUp(): void { public function setUp(): void {
$this->builder = new class extends APIRequestBuilder { $this->builder = new class extends APIRequestBuilder {
protected $baseUrl = 'https://httpbin.org/'; protected string $baseUrl = 'https://httpbin.org/';
protected $defaultHeaders = ['User-Agent' => "Tim's Anime Client Testsuite / 4.0"]; protected array $defaultHeaders = ['User-Agent' => "Tim's Anime Client Testsuite / 4.0"];
}; };
$this->builder->setLogger(new NullLogger); $this->builder->setLogger(new NullLogger);

View File

@ -31,7 +31,7 @@ class Aware {
class ContainerAwareTest extends IonTestCase { class ContainerAwareTest extends IonTestCase {
protected $aware; protected Aware $aware;
public function setUp(): void public function setUp(): void
{ {

View File

@ -18,6 +18,7 @@ namespace Aviat\Ion\Tests;
use function Aviat\Ion\_dir; use function Aviat\Ion\_dir;
use Aviat\Ion\Di\ContainerInterface;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Laminas\Diactoros\ServerRequestFactory; use Laminas\Diactoros\ServerRequestFactory;
@ -31,7 +32,7 @@ class IonTestCase extends TestCase {
public const TEST_DATA_DIR = __DIR__ . '/test_data'; public const TEST_DATA_DIR = __DIR__ . '/test_data';
public const TEST_VIEW_DIR = __DIR__ . '/test_views'; public const TEST_VIEW_DIR = __DIR__ . '/test_views';
protected $container; protected ContainerInterface $container;
protected static $staticContainer; protected static $staticContainer;
protected static $session_handler; protected static $session_handler;

View File

@ -1,29 +0,0 @@
<?php declare(strict_types=1);
/**
* Hummingbird Anime List Client
*
* An API client for Kitsu to manage anime and manga watch lists
*
* PHP version 7.4
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2020 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 5
* @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
*/
namespace Aviat\Ion\Tests\Model;
use Aviat\Ion\Model\DB as BaseDBModel;
use Aviat\Ion\Tests\IonTestCase;
class BaseDBModelTest extends IonTestCase {
public function testBaseDBModelSanity()
{
$baseDBModel = new BaseDBModel($this->container->get('config'));
$this->assertTrue(is_object($baseDBModel));
}
}

View File

@ -1,39 +0,0 @@
<?php declare(strict_types=1);
/**
* Hummingbird Anime List Client
*
* An API client for Kitsu to manage anime and manga watch lists
*
* PHP version 7.4
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2020 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 5
* @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
*/
namespace Aviat\Ion\Tests;
use Aviat\Ion\StringWrapper;
use Aviat\Ion\Type\StringType;
use PHPUnit\Framework\TestCase;
class StringWrapperTest extends TestCase {
protected $wrapper;
public function setUp(): void {
$this->wrapper = new class {
use StringWrapper;
};
}
public function testString()
{
$str = $this->wrapper->string('foo');
$this->assertInstanceOf(StringType::class, $str);
}
}

View File

@ -16,16 +16,10 @@
namespace Aviat\Ion\Tests\Type; namespace Aviat\Ion\Tests\Type;
use Aviat\Ion\ArrayWrapper; use Aviat\Ion\Type\ArrayType;
use Aviat\Ion\Tests\IonTestCase; use Aviat\Ion\Tests\IonTestCase;
class ArrayTypeTest extends IonTestCase { class ArrayTypeTest extends IonTestCase {
use ArrayWrapper;
public function setUp(): void {
parent::setUp();
}
public function dataCall() public function dataCall()
{ {
$method_map = [ $method_map = [
@ -88,33 +82,37 @@ class ArrayTypeTest extends IonTestCase {
* Test the array methods defined for the __Call method * Test the array methods defined for the __Call method
* *
* @dataProvider dataCall * @dataProvider dataCall
* @param string $method
* @param array $array
* @param array $args
* @param $expected
*/ */
public function testCall($method, $array, $args, $expected) public function testCall(string $method, array $array, array $args, $expected): void
{ {
$obj = $this->arr($array); $obj = ArrayType::from($array);
$actual = $obj->__call($method, $args); $actual = $obj->__call($method, $args);
$this->assertEquals($expected, $actual); $this->assertEquals($expected, $actual);
} }
public function testSet() public function testSet(): void
{ {
$obj = $this->arr([]); $obj = ArrayType::from([]);
$arraytype = $obj->set('foo', 'bar'); $arraytype = $obj->set('foo', 'bar');
$this->assertInstanceOf('Aviat\Ion\Type\ArrayType', $arraytype); $this->assertInstanceOf(ArrayType::class, $arraytype);
$this->assertEquals('bar', $obj->get('foo')); $this->assertEquals('bar', $obj->get('foo'));
} }
public function testGet() public function testGet(): void
{ {
$array = [1, 2, 3, 4, 5]; $array = [1, 2, 3, 4, 5];
$obj = $this->arr($array); $obj = ArrayType::from($array);
$this->assertEquals($array, $obj->get()); $this->assertEquals($array, $obj->get());
$this->assertEquals(1, $obj->get(0)); $this->assertEquals(1, $obj->get(0));
$this->assertEquals(5, $obj->get(4)); $this->assertEquals(5, $obj->get(4));
} }
public function testGetDeepKey() public function testGetDeepKey(): void
{ {
$arr = [ $arr = [
'foo' => 'bar', 'foo' => 'bar',
@ -122,14 +120,14 @@ class ArrayTypeTest extends IonTestCase {
'bar' => 'foobar' 'bar' => 'foobar'
] ]
]; ];
$obj = $this->arr($arr); $obj = ArrayType::from($arr);
$this->assertEquals('foobar', $obj->getDeepKey(['baz', 'bar'])); $this->assertEquals('foobar', $obj->getDeepKey(['baz', 'bar']));
$this->assertNull($obj->getDeepKey(['foo', 'bar', 'baz'])); $this->assertNull($obj->getDeepKey(['foo', 'bar', 'baz']));
} }
public function testMap() public function testMap(): void
{ {
$obj = $this->arr([1, 2, 3]); $obj = ArrayType::from([1, 2, 3]);
$actual = $obj->map(function($item) { $actual = $obj->map(function($item) {
return $item * 2; return $item * 2;
}); });
@ -137,9 +135,9 @@ class ArrayTypeTest extends IonTestCase {
$this->assertEquals([2, 4, 6], $actual); $this->assertEquals([2, 4, 6], $actual);
} }
public function testBadCall() public function testBadCall(): void
{ {
$obj = $this->arr([]); $obj = ArrayType::from([]);
$this->expectException('InvalidArgumentException'); $this->expectException('InvalidArgumentException');
$this->expectExceptionMessage("Method 'foo' does not exist"); $this->expectExceptionMessage("Method 'foo' does not exist");
@ -147,20 +145,20 @@ class ArrayTypeTest extends IonTestCase {
$obj->foo(); $obj->foo();
} }
public function testShuffle() public function testShuffle(): void
{ {
$original = [1, 2, 3, 4]; $original = [1, 2, 3, 4];
$test = [1, 2, 3, 4]; $test = [1, 2, 3, 4];
$obj = $this->arr($test); $obj = ArrayType::from($test);
$actual = $obj->shuffle(); $actual = $obj->shuffle();
//$this->assertNotEquals($actual, $original); //$this->assertNotEquals($actual, $original);
$this->assertTrue(is_array($actual)); $this->assertTrue(is_array($actual));
} }
public function testHasKey() public function testHasKey(): void
{ {
$obj = $this->arr([ $obj = ArrayType::from([
'a' => 'b', 'a' => 'b',
'z' => 'y' 'z' => 'y'
]); ]);
@ -168,9 +166,9 @@ class ArrayTypeTest extends IonTestCase {
$this->assertFalse($obj->hasKey('b')); $this->assertFalse($obj->hasKey('b'));
} }
public function testHasKeyArray() public function testHasKeyArray(): void
{ {
$obj = $this->arr([ $obj = ArrayType::from([
'foo' => [ 'foo' => [
'bar' => [ 'bar' => [
'baz' => [ 'baz' => [
@ -191,23 +189,23 @@ class ArrayTypeTest extends IonTestCase {
$this->assertFalse($obj->hasKey(['bar', 'baz'])); $this->assertFalse($obj->hasKey(['bar', 'baz']));
} }
public function testHas() public function testHas(): void
{ {
$obj = $this->arr([1, 2, 6, 8, 11]); $obj = ArrayType::from([1, 2, 6, 8, 11]);
$this->assertTrue($obj->has(8)); $this->assertTrue($obj->has(8));
$this->assertFalse($obj->has(8745)); $this->assertFalse($obj->has(8745));
} }
public function testSearch() public function testSearch(): void
{ {
$obj = $this->arr([1, 2, 5, 7, 47]); $obj = ArrayType::from([1, 2, 5, 7, 47]);
$actual = $obj->search(47); $actual = $obj->search(47);
$this->assertEquals(4, $actual); $this->assertEquals(4, $actual);
} }
public function testFill() public function testFill(): void
{ {
$obj = $this->arr([]); $obj = ArrayType::from([]);
$expected = ['?', '?', '?']; $expected = ['?', '?', '?'];
$actual = $obj->fill(0, 3, '?'); $actual = $obj->fill(0, 3, '?');
$this->assertEquals($actual, $expected); $this->assertEquals($actual, $expected);

View File

@ -16,14 +16,12 @@
namespace Aviat\Ion\Tests\Type; namespace Aviat\Ion\Tests\Type;
use Aviat\Ion\StringWrapper; use Aviat\Ion\Type\StringType;
use Aviat\Ion\Tests\IonTestCase; use Aviat\Ion\Tests\IonTestCase;
class StringTypeTest extends IonTestCase { class StringTypeTest extends IonTestCase {
use StringWrapper;
public function dataFuzzyCaseMatch(): array
public function dataFuzzyCaseMatch()
{ {
return [ return [
'space separated' => [ 'space separated' => [
@ -56,10 +54,13 @@ class StringTypeTest extends IonTestCase {
/** /**
* @dataProvider dataFuzzyCaseMatch * @dataProvider dataFuzzyCaseMatch
* @param string $str1
* @param string $str2
* @param bool $expected
*/ */
public function testFuzzyCaseMatch($str1, $str2, $expected) public function testFuzzyCaseMatch(string $str1, string $str2, bool $expected): void
{ {
$actual = $this->string($str1)->fuzzyCaseMatch($str2); $actual = StringType::from($str1)->fuzzyCaseMatch($str2);
$this->assertEquals($expected, $actual); $this->assertEquals($expected, $actual);
} }