Version 5.1 - All the GraphQL #32

Closed
timw4mail wants to merge 1160 commits from develop into master
17 changed files with 303 additions and 272 deletions
Showing only changes of commit fed52cb0cb - Show all commits

View File

@ -53,13 +53,13 @@ return (new Config())
'yield_from', 'yield_from',
], ],
], ],
'braces' => [ // 'braces' => [
'allow_single_line_anonymous_class_with_empty_body' => true, // 'allow_single_line_anonymous_class_with_empty_body' => true,
'allow_single_line_closure' => true, // 'allow_single_line_closure' => true,
'position_after_anonymous_constructs' => 'same', // 'position_after_anonymous_constructs' => 'same',
'position_after_control_structures' => 'next', // 'position_after_control_structures' => 'next',
'position_after_functions_and_oop_constructs' => 'next', // 'position_after_functions_and_oop_constructs' => 'next',
], // ],
'cast_spaces' => ['space' => 'single'], 'cast_spaces' => ['space' => 'single'],
'class_attributes_separation' => [ 'class_attributes_separation' => [
'elements' => [ 'elements' => [
@ -93,7 +93,16 @@ return (new Config())
'compact_nullable_typehint' => true, 'compact_nullable_typehint' => true,
'concat_space' => ['spacing' => 'one'], 'concat_space' => ['spacing' => 'one'],
'constant_case' => ['case' => 'upper'], 'constant_case' => ['case' => 'upper'],
'control_structure_braces' => true,
'control_structure_continuation_position' => ['position' => 'next_line'], 'control_structure_continuation_position' => ['position' => 'next_line'],
'curly_braces_position' => [
'allow_single_line_anonymous_functions' => true,
'allow_single_line_empty_anonymous_classes' => true,
'anonymous_functions_opening_brace' => 'same_line',
'classes_opening_brace' => 'next_line_unless_newline_at_signature_end',
'control_structures_opening_brace' => 'next_line_unless_newline_at_signature_end',
'functions_opening_brace' => 'next_line_unless_newline_at_signature_end',
],
'date_time_immutable' => false, 'date_time_immutable' => false,
'declare_equal_normalize' => ['space' => 'none'], 'declare_equal_normalize' => ['space' => 'none'],
'declare_parentheses' => true, 'declare_parentheses' => true,
@ -108,7 +117,7 @@ return (new Config())
'long_function' => 'echo', 'long_function' => 'echo',
'shorten_simple_statements_only' => false, 'shorten_simple_statements_only' => false,
], ],
'elseif' => true, 'elseif' => false,
'empty_loop_body' => ['style' => 'braces'], 'empty_loop_body' => ['style' => 'braces'],
'empty_loop_condition' => ['style' => 'while'], 'empty_loop_condition' => ['style' => 'while'],
'encoding' => true, 'encoding' => true,
@ -429,8 +438,8 @@ return (new Config())
'single_line_comment_style' => ['comment_types' => ['asterisk', 'hash']], 'single_line_comment_style' => ['comment_types' => ['asterisk', 'hash']],
'single_line_throw' => false, 'single_line_throw' => false,
'single_quote' => ['strings_containing_single_quote_chars' => false], 'single_quote' => ['strings_containing_single_quote_chars' => false],
'single_space_after_construct' => [ 'single_space_around_construct' => [
'constructs' => [ 'constructs_followed_by_a_single_space' => [
'abstract', 'abstract',
'as', 'as',
'attribute', 'attribute',
@ -493,6 +502,7 @@ return (new Config())
'space_after_semicolon' => ['remove_in_empty_for_expressions' => true], 'space_after_semicolon' => ['remove_in_empty_for_expressions' => true],
'standardize_increment' => true, 'standardize_increment' => true,
'standardize_not_equals' => true, 'standardize_not_equals' => true,
'statement_indentation' => true,
'static_lambda' => true, 'static_lambda' => true,
'strict_comparison' => true, 'strict_comparison' => true,
'strict_param' => true, 'strict_param' => true,

View File

@ -13,8 +13,8 @@
"autoload": { "autoload": {
"files": [ "files": [
"src/Ion/functions.php", "src/Ion/functions.php",
"src/AnimeClient/constants.php", "src/AnimeClient.php",
"src/AnimeClient/AnimeClient.php" "src/AnimeClient/constants.php"
], ],
"psr-4": { "psr-4": {
"Aviat\\": "src/" "Aviat\\": "src/"

View File

@ -18,7 +18,7 @@ use Amp\Http\Client\{HttpClient, HttpClientBuilder, Request, Response};
use Aviat\Ion\{ConfigInterface, ImageBuilder}; use Aviat\Ion\{ConfigInterface, ImageBuilder};
use DateTimeImmutable; use DateTimeImmutable;
use Psr\SimpleCache\CacheInterface; use Psr\SimpleCache\{CacheInterface, InvalidArgumentException};
use Throwable; use Throwable;
use Yosymfony\Toml\{Toml, TomlBuilder}; use Yosymfony\Toml\{Toml, TomlBuilder};
@ -218,7 +218,7 @@ function getResponse(Request|string $request): Response
*/ */
function getLocalImg(string $kitsuUrl, bool $webp = TRUE): string function getLocalImg(string $kitsuUrl, bool $webp = TRUE): string
{ {
if (empty($kitsuUrl) || ( ! is_string($kitsuUrl))) if (empty($kitsuUrl))
{ {
return 'images/placeholder.webp'; return 'images/placeholder.webp';
} }
@ -276,6 +276,7 @@ function colNotEmpty(array $search, string $key): bool
/** /**
* Clear the cache, but save user auth data * Clear the cache, but save user auth data
* @throws InvalidArgumentException
*/ */
function clearCache(CacheInterface $cache): bool function clearCache(CacheInterface $cache): bool
{ {

View File

@ -16,16 +16,14 @@ namespace Aviat\AnimeClient\API;
// use Amp\Http\Client\Form; // use Amp\Http\Client\Form;
use Amp\Http\Client\Body\FormBody; use Amp\Http\Client\Body\FormBody;
use Amp\Http\Client\HttpClientBuilder; use Amp\Http\Client\{HttpClientBuilder, HttpException, Request};
use Amp\Http\Client\HttpException;
use Amp\Http\Client\Request;
use Aviat\Ion\Json; use Aviat\Ion\Json;
use Error;
use InvalidArgumentException; use InvalidArgumentException;
use Psr\Log\LoggerAwareTrait; use Psr\Log\LoggerAwareTrait;
use Throwable; use Throwable;
use TypeError; // use function Amp\async;
// use function Amp\Future\await;
use function Amp\Promise\wait; use function Amp\Promise\wait;
use function Aviat\AnimeClient\getResponse; use function Aviat\AnimeClient\getResponse;
use const Aviat\AnimeClient\USER_AGENT; use const Aviat\AnimeClient\USER_AGENT;
@ -221,8 +219,6 @@ abstract class APIRequestBuilder
/** /**
* Get the data from the response of the passed request * Get the data from the response of the passed request
* *
* @param Request $request
* @return mixed
* @throws Throwable * @throws Throwable
*/ */
public function getResponseData(Request $request): mixed public function getResponseData(Request $request): mixed

View File

@ -38,7 +38,6 @@ abstract class AbstractListItem
* Retrieve a list item * Retrieve a list item
* *
* @param string $id - The id of the list item * @param string $id - The id of the list item
* @return mixed[]
*/ */
abstract public function get(string $id): array; abstract public function get(string $id): array;

View File

@ -14,7 +14,7 @@
namespace Aviat\AnimeClient\API; namespace Aviat\AnimeClient\API;
use Psr\SimpleCache\CacheInterface; use Psr\SimpleCache\{CacheInterface, InvalidArgumentException};
/** /**
* Helper methods for dealing with the Cache * Helper methods for dealing with the Cache
@ -44,6 +44,7 @@ trait CacheTrait
/** /**
* Get the cached value if it exists, otherwise set the cache value * Get the cached value if it exists, otherwise set the cache value
* and return it. * and return it.
* @throws InvalidArgumentException
*/ */
public function getCached(string $key, callable $primer, ?array $primeArgs = []): mixed public function getCached(string $key, callable $primer, ?array $primeArgs = []): mixed
{ {

View File

@ -16,7 +16,6 @@ namespace Aviat\AnimeClient\API\Kitsu;
use Amp\Http\Client\{Request, Response}; use Amp\Http\Client\{Request, Response};
use Aviat\AnimeClient\API\APIRequestBuilder; use Aviat\AnimeClient\API\APIRequestBuilder;
use Aviat\AnimeClient\Enum\EventType;
use Aviat\AnimeClient\Kitsu as K; use Aviat\AnimeClient\Kitsu as K;
use Aviat\Ion\Di\{ContainerAware, ContainerInterface}; use Aviat\Ion\Di\{ContainerAware, ContainerInterface};
use Aviat\Ion\{Event, Json, JsonException}; use Aviat\Ion\{Event, Json, JsonException};

View File

@ -54,7 +54,7 @@ final class MangaTransformer extends AbstractTransformer
} }
$details = $rawCharacter['character']; $details = $rawCharacter['character'];
if (array_key_exists($details['id'], (array)$characters[$type])) if (array_key_exists($details['id'], (array) $characters[$type]))
{ {
$characters[$type][$details['id']] = [ $characters[$type][$details['id']] = [
'image' => Kitsu::getImage($details), 'image' => Kitsu::getImage($details),

View File

@ -14,11 +14,12 @@
namespace Aviat\AnimeClient\API; namespace Aviat\AnimeClient\API;
use Amp\Http\Client\Request; use Amp\Http\Client\{HttpException, Request};
use Generator; use Generator;
use Throwable; use Throwable;
use function Amp\call; use function Amp\call;
// use function Amp\Future\{async, await};
use function Amp\Promise\{all, wait}; use function Amp\Promise\{all, wait};
use function Aviat\AnimeClient\getApiClient; use function Aviat\AnimeClient\getApiClient;
@ -65,9 +66,23 @@ final class ParallelAPIRequest
* Make the requests, and return the body for each * Make the requests, and return the body for each
* *
* @throws Throwable * @throws Throwable
* @return mixed[]
*/ */
public function makeRequests(): array public function makeRequests(): array
{
return $this->makeRequestOld();
}
/**
* Make the requests and return the response objects
*
* @throws Throwable
*/
public function getResponses(): array
{
return $this->getResponsesOld();
}
private function makeRequestOld(): array
{ {
$client = getApiClient(); $client = getApiClient();
@ -84,13 +99,19 @@ final class ParallelAPIRequest
return wait(all($promises)); return wait(all($promises));
} }
/** private function makeRequestsNew(): array
* Make the requests and return the response objects {
* $futures = [];
* @throws Throwable
* @return mixed[] foreach ($this->requests as $key => $url)
*/ {
public function getResponses(): array $futures[$key] = async(static fn () => self::bodyHandler($url));
}
return await($futures);
}
private function getResponsesOld(): array
{ {
$client = getApiClient(); $client = getApiClient();
@ -103,4 +124,41 @@ final class ParallelAPIRequest
return wait(all($promises)); return wait(all($promises));
} }
private function getResponsesNew(): array
{
$futures = [];
foreach ($this->requests as $key => $url)
{
$futures[$key] = async(static fn () => self::responseHandler($url));
}
return await($futures);
}
private static function bodyHandler(string|Request $uri): string
{
$client = getApiClient();
if (is_string($uri))
{
$uri = new Request($uri);
}
$response = $client->request($uri);
return $response->getBody()->buffer();
}
private static function responseHandler(string|Request $uri)
{
$client = getApiClient();
if (is_string($uri))
{
$uri = new Request($uri);
}
return $client->request($uri);
}
} }

View File

@ -120,194 +120,185 @@ class Controller
Event::on(EventType::RESET_CACHE_KEY, fn (string $key) => $this->cache->delete($key)); Event::on(EventType::RESET_CACHE_KEY, fn (string $key) => $this->cache->delete($key));
} }
/** /**
* Set the current url in the session as the target of a future redirect * Set the current url in the session as the target of a future redirect
* *
* @throws ContainerException * @throws ContainerException
* @throws NotFoundException * @throws NotFoundException
*/ */
#[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] public function setSessionRedirect(?string $url = NULL): void
public function setSessionRedirect(?string $url = NULL): void {
{ $serverParams = $this->request->getServerParams();
$serverParams = $this->request->getServerParams();
if ( ! array_key_exists('HTTP_REFERER', $serverParams)) if ( ! array_key_exists('HTTP_REFERER', $serverParams))
{ {
return; return;
} }
$util = $this->container->get('util'); $util = $this->container->get('util');
$doubleFormPage = $serverParams['HTTP_REFERER'] === $this->request->getUri(); $doubleFormPage = $serverParams['HTTP_REFERER'] === $this->request->getUri();
$isLoginPage = str_contains($serverParams['HTTP_REFERER'], 'login'); $isLoginPage = str_contains($serverParams['HTTP_REFERER'], 'login');
// Don't attempt to set the redirect url if // Don't attempt to set the redirect url if
// the page is one of the form type pages, // the page is one of the form type pages,
// and the previous page is also a form type // and the previous page is also a form type
if ($doubleFormPage || $isLoginPage) if ($doubleFormPage || $isLoginPage)
{ {
return; return;
} }
if (NULL === $url) if (NULL === $url)
{ {
$url = $util->isViewPage() $url = $util->isViewPage()
? (string) $this->request->getUri() ? (string) $this->request->getUri()
: $serverParams['HTTP_REFERER']; : $serverParams['HTTP_REFERER'];
} }
$this->session->set('redirect_url', $url); $this->session->set('redirect_url', $url);
} }
/** /**
* Redirect to the url previously set in the session * Redirect to the url previously set in the session
* *
* If one is not set, redirect to default url * If one is not set, redirect to default url
* *
* @throws InvalidArgumentException * @throws InvalidArgumentException
*/ */
#[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] public function sessionRedirect(): void
public function sessionRedirect(): void {
{ $target = $this->session->get('redirect_url') ?? '/';
$target = $this->session->get('redirect_url') ?? '/';
$this->redirect($target, 303); $this->redirect($target, 303);
$this->session->set('redirect_url', NULL); $this->session->set('redirect_url', NULL);
} }
/** /**
* Check if the current user is authenticated, else error and exit * Check if the current user is authenticated, else error and exit
*/ */
#[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] protected function checkAuth(): void
protected function checkAuth(): void {
{ if ( ! $this->auth->isAuthenticated())
if ( ! $this->auth->isAuthenticated()) {
{ $this->errorPage(
$this->errorPage( 403,
403, 'Forbidden',
'Forbidden', 'You must <a href="/login">log in</a> to perform this action.'
'You must <a href="/login">log in</a> to perform this action.' );
); }
} }
}
/** /**
* Get the string output of a partial template * Get the string output of a partial template
*/ */
#[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] protected function loadPartial(HtmlView $view, string $template, array $data = []): string
protected function loadPartial(HtmlView $view, string $template, array $data = []): string {
{ $router = $this->container->get('dispatcher');
$router = $this->container->get('dispatcher');
if (isset($this->baseData)) if (isset($this->baseData))
{ {
$data = array_merge($this->baseData, $data); $data = array_merge($this->baseData, $data);
} }
$route = $router->getRoute(); $route = $router->getRoute();
$data['route_path'] = $route !== FALSE ? $route->path : ''; $data['route_path'] = $route !== FALSE ? $route->path : '';
$templatePath = _dir($this->config->get('view_path'), "{$template}.php"); $templatePath = _dir($this->config->get('view_path'), "{$template}.php");
if ( ! is_file($templatePath)) if ( ! is_file($templatePath))
{ {
throw new InvalidArgumentException("Invalid template : {$template}"); throw new InvalidArgumentException("Invalid template : {$template}");
} }
return $view->renderTemplate($templatePath, $data); return $view->renderTemplate($templatePath, $data);
} }
/** /**
* Render a template with header and footer * Render a template with header and footer
*/ */
#[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] protected function renderFullPage(HtmlView $view, string $template, array $data): HtmlView
protected function renderFullPage(HtmlView $view, string $template, array $data): HtmlView {
{ $csp = [
$csp = [ "default-src 'self' media.kitsu.io kitsu-production-media.s3.us-west-002.backblazeb2.com",
"default-src 'self' media.kitsu.io kitsu-production-media.s3.us-west-002.backblazeb2.com", "object-src 'none'",
"object-src 'none'", "child-src 'self' *.youtube.com polyfill.io",
"child-src 'self' *.youtube.com polyfill.io", ];
];
$view->addHeader('Content-Security-Policy', implode('; ', $csp)); $view->addHeader('Content-Security-Policy', implode('; ', $csp));
$view->appendOutput($this->loadPartial($view, 'header', $data)); $view->appendOutput($this->loadPartial($view, 'header', $data));
if (array_key_exists('message', $data) && is_array($data['message'])) if (array_key_exists('message', $data) && is_array($data['message']))
{ {
$view->appendOutput($this->loadPartial($view, 'message', $data['message'])); $view->appendOutput($this->loadPartial($view, 'message', $data['message']));
} }
$view->appendOutput($this->loadPartial($view, $template, $data)); $view->appendOutput($this->loadPartial($view, $template, $data));
$view->appendOutput($this->loadPartial($view, 'footer', $data)); $view->appendOutput($this->loadPartial($view, 'footer', $data));
return $view; return $view;
} }
/** /**
* 404 action * 404 action
* *
* @throws InvalidArgumentException * @throws InvalidArgumentException
*/ */
#[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] public function notFound(
public function notFound( string $title = 'Sorry, page not found',
string $title = 'Sorry, page not found', string $message = 'Page Not Found'
string $message = 'Page Not Found' ): never {
): never { $this->outputHTML('404', [
$this->outputHTML('404', [ 'title' => $title,
'title' => $title, 'message' => $message,
'message' => $message, ], NULL, 404);
], NULL, 404);
exit(); exit();
} }
/** /**
* Display a generic error page * Display a generic error page
* *
* @throws InvalidArgumentException * @throws InvalidArgumentException
*/ */
#[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] public function errorPage(int $httpCode, string $title, string $message, string $longMessage = ''): void
public function errorPage(int $httpCode, string $title, string $message, string $longMessage = ''): void {
{ $this->outputHTML('error', [
$this->outputHTML('error', [ 'title' => $title,
'title' => $title, 'message' => $message,
'message' => $message, 'long_message' => $longMessage,
'long_message' => $longMessage, ], NULL, $httpCode);
], NULL, $httpCode); }
}
/** /**
* Redirect to the default controller/url from an empty path * Redirect to the default controller/url from an empty path
* *
* @throws InvalidArgumentException * @throws InvalidArgumentException
*/ */
#[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] public function redirectToDefaultRoute(): void
public function redirectToDefaultRoute(): void {
{ $defaultType = $this->config->get('default_list');
$defaultType = $this->config->get('default_list'); $this->redirect($this->urlGenerator->defaultUrl($defaultType), 303);
$this->redirect($this->urlGenerator->defaultUrl($defaultType), 303); }
}
/** /**
* Set a session flash variable to display a message on * Set a session flash variable to display a message on
* next page load * next page load
*/ */
#[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] public function setFlashMessage(string $message, string $type = 'info'): void
public function setFlashMessage(string $message, string $type = 'info'): void {
{ static $messages;
static $messages;
if ( ! $messages) if ( ! $messages)
{ {
$messages = []; $messages = [];
} }
$messages[] = [ $messages[] = [
'message_type' => $type, 'message_type' => $type,
'message' => $message, 'message' => $message,
]; ];
$this->session->setFlash('message', $messages); $this->session->setFlash('message', $messages);
} }
/** /**
* Helper for consistent page titles * Helper for consistent page titles
@ -319,62 +310,58 @@ class Controller
return implode(' &middot; ', $parts); return implode(' &middot; ', $parts);
} }
/** /**
* Add a message box to the page * Add a message box to the page
* *
* @throws InvalidArgumentException * @throws InvalidArgumentException
*/ */
#[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] protected function showMessage(HtmlView $view, string $type, string $message): string
protected function showMessage(HtmlView $view, string $type, string $message): string {
{ return $this->loadPartial($view, 'message', [
return $this->loadPartial($view, 'message', [ 'message_type' => $type,
'message_type' => $type, 'message' => $message,
'message' => $message, ]);
]); }
}
/** /**
* Output a template to HTML, using the provided data * Output a template to HTML, using the provided data
* *
* @throws InvalidArgumentException * @throws InvalidArgumentException
*/ */
#[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] protected function outputHTML(string $template, array $data = [], ?HtmlView $view = NULL, int $code = 200): void
protected function outputHTML(string $template, array $data = [], ?HtmlView $view = NULL, int $code = 200): void {
{ if (NULL === $view)
if (NULL === $view) {
{ $view = new HtmlView($this->container);
$view = new HtmlView($this->container); }
}
$view->setStatusCode($code); $view->setStatusCode($code);
$this->renderFullPage($view, $template, $data)->send(); $this->renderFullPage($view, $template, $data)->send();
} }
/** /**
* Output a JSON Response * Output a JSON Response
* *
* @param int $code - the http status code * @param int $code - the http status code
* @throws DoubleRenderException * @throws DoubleRenderException
*/ */
#[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] protected function outputJSON(mixed $data, int $code): void
protected function outputJSON(mixed $data, int $code): void {
{ JsonView::new()
JsonView::new() ->setOutput($data)
->setOutput($data) ->setStatusCode($code)
->setStatusCode($code) ->send();
->send(); }
}
/** /**
* Redirect to the selected page * Redirect to the selected page
*/ */
#[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] protected function redirect(string $url, int $code): void
protected function redirect(string $url, int $code): void {
{ HttpView::new()
HttpView::new() ->redirect($url, $code)
->redirect($url, $code) ->send();
->send(); }
}
} }
// End of BaseController.php // End of BaseController.php

View File

@ -214,8 +214,6 @@ final class Dispatcher extends RoutingBase
/** /**
* Get the list of controllers in the default namespace * Get the list of controllers in the default namespace
*
* @return array
*/ */
public function getControllerList(): array public function getControllerList(): array
{ {

View File

@ -98,9 +98,7 @@ class UrlGenerator extends RoutingBase
if ($defaultPath !== NULL) if ($defaultPath !== NULL)
{ {
// @codeCoverageIgnoreStart
return $this->url("{$type}/{$defaultPath}"); return $this->url("{$type}/{$defaultPath}");
// @codeCoverageIgnoreEnd
} }
throw new InvalidArgumentException("Invalid default type: '{$type}'"); throw new InvalidArgumentException("Invalid default type: '{$type}'");

View File

@ -25,10 +25,7 @@ class Json
/** /**
* Encode data in json format * Encode data in json format
* *
* @param mixed $data
* @param int $options
* @param int<1, max> $depth * @param int<1, max> $depth
* @return string
*/ */
public static function encode(mixed $data, int $options = 0, int $depth = 512): string public static function encode(mixed $data, int $options = 0, int $depth = 512): string
{ {
@ -57,11 +54,7 @@ class Json
/** /**
* Decode data from json * Decode data from json
* *
* @param string|null $json
* @param bool $assoc
* @param int<1, max> $depth * @param int<1, max> $depth
* @param int $options
* @return mixed
*/ */
public static function decode(?string $json, bool $assoc = TRUE, int $depth = 512, int $options = 0): mixed public static function decode(?string $json, bool $assoc = TRUE, int $depth = 512, int $options = 0): mixed
{ {
@ -81,11 +74,7 @@ class Json
/** /**
* Decode json data loaded from the passed filename * Decode json data loaded from the passed filename
* *
* @param string $filename
* @param bool $assoc
* @param int<1, max> $depth * @param int<1, max> $depth
* @param int $options
* @return mixed
*/ */
public static function decodeFile(string $filename, bool $assoc = TRUE, int $depth = 512, int $options = 0): mixed public static function decodeFile(string $filename, bool $assoc = TRUE, int $depth = 512, int $options = 0): mixed
{ {

View File

@ -2138,7 +2138,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess
return mb_regex_encoding(...$args); return mb_regex_encoding(...$args);
} }
return null; return NULL;
} }
protected function supportsEncoding(): bool|null protected function supportsEncoding(): bool|null

View File

@ -15,8 +15,7 @@
namespace Aviat\Ion\Tests; namespace Aviat\Ion\Tests;
use Aviat\Ion\Config; use Aviat\Ion\Config;
use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\{DataProvider, IgnoreMethodForCodeCoverage};
use PHPUnit\Framework\Attributes\IgnoreMethodForCodeCoverage;
/** /**
* @internal * @internal

View File

@ -15,11 +15,8 @@
namespace Aviat\Ion\Tests\Type; namespace Aviat\Ion\Tests\Type;
use Aviat\Ion\Tests\IonTestCase; use Aviat\Ion\Tests\IonTestCase;
use Aviat\Ion\Type\StringType; use Aviat\Ion\Type\{StringType, Stringy};
use Aviat\Ion\Type\Stringy; use PHPUnit\Framework\Attributes\{DataProvider, IgnoreClassForCodeCoverage, Test};
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\IgnoreClassForCodeCoverage;
use PHPUnit\Framework\Attributes\Test;
/** /**
* @internal * @internal

View File

@ -14,8 +14,7 @@
namespace Aviat\Ion\Tests; namespace Aviat\Ion\Tests;
use PHPUnit\Framework\Attributes\IgnoreClassForCodeCoverage; use PHPUnit\Framework\Attributes\{IgnoreClassForCodeCoverage, Test};
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use function Aviat\Ion\_dir; use function Aviat\Ion\_dir;