diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index f068a23b68..c4c01b5f03 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -14,6 +14,7 @@ /.github/workflows/benchmark.yml @xHeaven /.github/workflows/benchmark-comment.yml @xHeaven /src/ @brendt +/utils/rector/ @xHeaven /docs/ @brendt @innocenzi /packages/auth/ @innocenzi /packages/cache/ @innocenzi diff --git a/.github/workflows/coding-conventions.yml b/.github/workflows/coding-conventions.yml index 8a69535a1a..913f97d808 100644 --- a/.github/workflows/coding-conventions.yml +++ b/.github/workflows/coding-conventions.yml @@ -24,7 +24,6 @@ jobs: - name: Install dependencies run: | composer update --prefer-dist --no-interaction --ignore-platform-reqs - composer mago:install-binary - name: Run Mago run: | diff --git a/composer.json b/composer.json index ce22082b6f..5703809bcb 100644 --- a/composer.json +++ b/composer.json @@ -52,7 +52,7 @@ "aws/aws-sdk-php": "^3.338.0", "azure-oss/storage-blob-flysystem": "^1.2", "brianium/paratest": "^7.14", - "carthage-software/mago": "1.0.0-beta.28", + "carthage-software/mago": "^1.0", "guzzlehttp/psr7": "^2.6.1", "league/flysystem-aws-s3-v3": "^3.25.1", "league/flysystem-ftp": "^3.25.1", @@ -237,7 +237,8 @@ "Tempest\\Validation\\Tests\\": "packages/validation/tests", "Tempest\\View\\Tests\\": "packages/view/tests", "Tempest\\Vite\\Tests\\": "packages/vite/tests", - "Tests\\Tempest\\": "tests" + "Tests\\Tempest\\": "tests", + "Tempest\\Rector\\": "utils/rector/src" } }, "bin": [ diff --git a/mago.toml b/mago.toml index 2dd5090904..28dd67d5a9 100644 --- a/mago.toml +++ b/mago.toml @@ -15,6 +15,7 @@ excludes = [ "**/*.expected.php", "**/.tempest", "./vendor/rector", #see https://github.com/carthage-software/mago/issues/1237 rector clashes and throws errors in tests + "packages/intl/bin/plural-rules.php", ] [formatter] @@ -42,12 +43,12 @@ trait-name = { psr = false } class-name = { psr = false } literal-named-argument = { enabled = false } # todo no-error-control-operator = { enabled = false } -no-boolean-literal-comparison = { enabled = false } +#no-boolean-literal-comparison = { enabled = false } too-many-methods = { enabled = false } kan-defect = { enabled = false } cyclomatic-complexity = { enabled = false } -return-type = { ignore-arrow-function = true, ignore-closure = true } -parameter-type = { ignore-arrow-function = true, ignore-closure = true } +#return-type = { ignore-arrow-function = true, ignore-closure = true } +#parameter-type = { ignore-arrow-function = true, ignore-closure = true } too-many-enum-cases = { enabled = false } no-redundant-file = { enabled = false } assertion-style = { style = "this" } @@ -65,3 +66,8 @@ prefer-first-class-callable = { enabled = false } # enable when arguments are fi strict-behavior = { allow-loose-behavior = true } no-redundant-use = { enabled = true } no-empty-comment = { enabled = false } +single-class-per-file = { enabled = false } +no-isset = { enabled = false } +instanceof-stringable = { enabled = false } +prefer-static-closure = { enabled = false } +sensitive-parameter = { enabled = false } diff --git a/packages/auth/src/AccessControl/PolicyBasedAccessControl.php b/packages/auth/src/AccessControl/PolicyBasedAccessControl.php index 3751de141e..88cb780da9 100644 --- a/packages/auth/src/AccessControl/PolicyBasedAccessControl.php +++ b/packages/auth/src/AccessControl/PolicyBasedAccessControl.php @@ -13,6 +13,7 @@ use Tempest\Reflection\ParameterReflector; use Tempest\Support\Arr\ImmutableArray; use Tempest\Support\Str; +use Throwable; use UnitEnum; /** @@ -45,7 +46,7 @@ public function isGranted(UnitEnum|string $action, object|string $resource, ?obj throw new NoPolicyWereFoundForResource($resource); } - $resource = ! is_object($resource) ? null : $resource; + $resource = is_object($resource) ? $resource : null; foreach ($policies as $policy) { $decision = $this->evaluatePolicy($policy, $resource, $subject); @@ -60,13 +61,13 @@ public function isGranted(UnitEnum|string $action, object|string $resource, ?obj private function resolveSubject(?object $subject): ?object { - if ($subject) { + if ($subject !== null) { return $subject; } try { return $this->container->get(Authenticator::class)->current(); - } catch (\Throwable) { + } catch (Throwable) { return null; } } @@ -113,9 +114,9 @@ private function evaluatePolicy(MethodReflector $policy, ?object $resource, ?obj return AccessDecision::from($decision); } - private function ensureParameterAcceptsInput(?ParameterReflector $reflector, mixed $input, \Closure $throw): void + private function ensureParameterAcceptsInput(?ParameterReflector $reflector, mixed $input, Closure $throw): void { - if ($reflector === null || $input === null) { + if (! $reflector instanceof ParameterReflector || $input === null) { return; } diff --git a/packages/auth/src/AccessControl/PolicyDiscovery.php b/packages/auth/src/AccessControl/PolicyDiscovery.php index 92f28c4aa6..85319bdff0 100644 --- a/packages/auth/src/AccessControl/PolicyDiscovery.php +++ b/packages/auth/src/AccessControl/PolicyDiscovery.php @@ -2,7 +2,6 @@ namespace Tempest\Auth\AccessControl; -use Tempest\Auth\AccessControl\Policy; use Tempest\Auth\AuthConfig; use Tempest\Discovery\Discovery; use Tempest\Discovery\DiscoveryLocation; diff --git a/packages/auth/src/Authentication/Authenticatable.php b/packages/auth/src/Authentication/Authenticatable.php index 6abf1008f7..6db39727ea 100644 --- a/packages/auth/src/Authentication/Authenticatable.php +++ b/packages/auth/src/Authentication/Authenticatable.php @@ -7,6 +7,4 @@ /** * Represents an entity that may be authenticated. */ -interface Authenticatable -{ -} +interface Authenticatable {} diff --git a/packages/auth/src/Authentication/SessionAuthenticator.php b/packages/auth/src/Authentication/SessionAuthenticator.php index a7357f9794..6d43b69c44 100644 --- a/packages/auth/src/Authentication/SessionAuthenticator.php +++ b/packages/auth/src/Authentication/SessionAuthenticator.php @@ -10,6 +10,7 @@ final readonly class SessionAuthenticator implements Authenticator { public const string AUTHENTICATABLE_KEY = '#authenticatable:id'; + public const string AUTHENTICATABLE_CLASS = '#authenticatable:class'; public function __construct( @@ -35,6 +36,7 @@ public function deauthenticate(): void { $this->session->remove(self::AUTHENTICATABLE_KEY); $this->session->remove(self::AUTHENTICATABLE_CLASS); + $this->sessionManager->save($this->session); } diff --git a/packages/auth/src/Exceptions/AuthenticationException.php b/packages/auth/src/Exceptions/AuthenticationException.php index c7c62e0826..acaea6737e 100644 --- a/packages/auth/src/Exceptions/AuthenticationException.php +++ b/packages/auth/src/Exceptions/AuthenticationException.php @@ -2,6 +2,4 @@ namespace Tempest\Auth\Exceptions; -interface AuthenticationException -{ -} +interface AuthenticationException {} diff --git a/packages/auth/src/Exceptions/NoPolicyWereFoundForResource.php b/packages/auth/src/Exceptions/NoPolicyWereFoundForResource.php index 97bef581ec..7519211b97 100644 --- a/packages/auth/src/Exceptions/NoPolicyWereFoundForResource.php +++ b/packages/auth/src/Exceptions/NoPolicyWereFoundForResource.php @@ -9,6 +9,6 @@ final class NoPolicyWereFoundForResource extends Exception implements Authentica public function __construct( public readonly string|object $resource, ) { - parent::__construct(sprintf('No policies were found for resource `%s`.', is_object($resource) ? get_class($resource) : $resource)); + parent::__construct(sprintf('No policies were found for resource `%s`.', is_object($resource) ? $resource::class : $resource)); } } diff --git a/packages/auth/src/Exceptions/OAuthStateWasInvalid.php b/packages/auth/src/Exceptions/OAuthStateWasInvalid.php index deecb77be7..06243d4c26 100644 --- a/packages/auth/src/Exceptions/OAuthStateWasInvalid.php +++ b/packages/auth/src/Exceptions/OAuthStateWasInvalid.php @@ -6,6 +6,4 @@ use Exception; -final class OAuthStateWasInvalid extends Exception implements AuthenticationException -{ -} +final class OAuthStateWasInvalid extends Exception implements AuthenticationException {} diff --git a/packages/auth/src/Installer/AuthenticationInstaller.php b/packages/auth/src/Installer/AuthenticationInstaller.php index 29ec896e0a..2a068dee46 100644 --- a/packages/auth/src/Installer/AuthenticationInstaller.php +++ b/packages/auth/src/Installer/AuthenticationInstaller.php @@ -7,6 +7,7 @@ use Tempest\Console\Console; use Tempest\Console\ConsoleCommand; use Tempest\Console\Input\ConsoleArgumentBag; +use Tempest\Console\Input\ConsoleInputArgument; use Tempest\Container\Container; use Tempest\Core\Installer; use Tempest\Core\PublishesFiles; @@ -47,7 +48,7 @@ private function shouldMigrate(): bool { $argument = $this->consoleArgumentBag->get('migrate'); - if ($argument === null || ! is_bool($argument->value)) { + if (! $argument instanceof ConsoleInputArgument || ! is_bool($argument->value)) { return $this->console->confirm('Do you want to execute migrations?', default: false); } @@ -58,7 +59,7 @@ private function shouldInstallOAuth(): bool { $argument = $this->consoleArgumentBag->get('oauth'); - if ($argument === null || ! is_bool($argument->value)) { + if (! $argument instanceof ConsoleInputArgument || ! is_bool($argument->value)) { return $this->console->confirm('Do you want to install OAuth?', default: false); } diff --git a/packages/auth/src/Installer/OAuthInstaller.php b/packages/auth/src/Installer/OAuthInstaller.php index 8915b44d3d..d5ec5f1640 100644 --- a/packages/auth/src/Installer/OAuthInstaller.php +++ b/packages/auth/src/Installer/OAuthInstaller.php @@ -30,7 +30,7 @@ public function install(): void { $providers = $this->getProviders(); - if (count($providers) === 0) { + if ($providers === []) { return; } diff --git a/packages/auth/src/OAuth/OAuthConfig.php b/packages/auth/src/OAuth/OAuthConfig.php index 250bd851a7..6722f7c429 100644 --- a/packages/auth/src/OAuth/OAuthConfig.php +++ b/packages/auth/src/OAuth/OAuthConfig.php @@ -14,32 +14,24 @@ interface OAuthConfig extends HasTag /** * The OAuth provider class name. */ - public string $provider { - get; - } + public string $provider { get; } /** * The authorization scopes for this OAuth provider. * * @return string[] */ - public array $scopes { - get; - } + public array $scopes { get; } /** * The client ID for the OAuth provider. */ - public string $clientId { - get; - } + public string $clientId { get; } /** * The controller action to redirect to after the user authorizes the application. */ - public string|array $redirectTo { - get; - } + public string|array $redirectTo { get; } /** * Creates the OAuth provider instance. diff --git a/packages/auth/tests/AuthenticationAndOAuthSafetyTest.php b/packages/auth/tests/AuthenticationAndOAuthSafetyTest.php index f3e8732d0d..09ae269d8e 100644 --- a/packages/auth/tests/AuthenticationAndOAuthSafetyTest.php +++ b/packages/auth/tests/AuthenticationAndOAuthSafetyTest.php @@ -9,6 +9,7 @@ use PHPUnit\Framework\TestCase; use ReflectionClass; use ReflectionMethod; +use stdClass; use Tempest\Auth\Authentication\DatabaseAuthenticatableResolver; use Tempest\Auth\Exceptions\ModelWasNotAuthenticatable; use Tempest\Auth\OAuth\GenericOAuthClient; @@ -23,7 +24,7 @@ public function database_authenticatable_resolver_rejects_non_authenticatable_cl $this->expectException(ModelWasNotAuthenticatable::class); - $resolve->invoke($resolver, 1, \stdClass::class); + $resolve->invoke($resolver, 1, stdClass::class); } #[Test] diff --git a/packages/auth/tests/OAuthTest.php b/packages/auth/tests/OAuthTest.php index 8f9271d556..503f16643d 100644 --- a/packages/auth/tests/OAuthTest.php +++ b/packages/auth/tests/OAuthTest.php @@ -185,7 +185,7 @@ public function oauth_user_creation(): void avatar: 'https://example.com/avatar.jpg', provider: 'github', raw: [ - 'id' => 123456, + 'id' => 123_456, 'login' => 'frieren', 'name' => 'Frieren the Mage', 'email' => 'frieren@elven-mage.magic', diff --git a/packages/cache/src/Cache.php b/packages/cache/src/Cache.php index e46f189e96..19647a7146 100644 --- a/packages/cache/src/Cache.php +++ b/packages/cache/src/Cache.php @@ -15,10 +15,7 @@ interface Cache /** * Whether the cache is enabled. */ - public bool $enabled { - get; - set; - } + public bool $enabled { get; set; } /** * Returns a lock for the specified key. The lock is not acquired until `acquire()` is called. diff --git a/packages/cache/src/CacheCouldNotBeCleared.php b/packages/cache/src/CacheCouldNotBeCleared.php index f7e3c2214c..c74d7dba1d 100644 --- a/packages/cache/src/CacheCouldNotBeCleared.php +++ b/packages/cache/src/CacheCouldNotBeCleared.php @@ -6,6 +6,4 @@ use Exception; -final class CacheCouldNotBeCleared extends Exception implements CacheException -{ -} +final class CacheCouldNotBeCleared extends Exception implements CacheException {} diff --git a/packages/cache/src/CacheException.php b/packages/cache/src/CacheException.php index 56297fdd43..3b72346ea6 100644 --- a/packages/cache/src/CacheException.php +++ b/packages/cache/src/CacheException.php @@ -2,6 +2,4 @@ namespace Tempest\Cache; -interface CacheException -{ -} +interface CacheException {} diff --git a/packages/cache/src/CacheInitializer.php b/packages/cache/src/CacheInitializer.php index d6379daed6..685c98c70f 100644 --- a/packages/cache/src/CacheInitializer.php +++ b/packages/cache/src/CacheInitializer.php @@ -39,7 +39,7 @@ private function shouldCacheBeEnabled(null|string|UnitEnum $tag): bool { $globalCacheEnabled = (bool) env('CACHE_ENABLED', default: true); - if (! $tag) { + if ($tag === null) { return $globalCacheEnabled; } diff --git a/packages/cache/src/Commands/CacheClearCommand.php b/packages/cache/src/Commands/CacheClearCommand.php index fb1c7b13cb..19d699bef3 100644 --- a/packages/cache/src/Commands/CacheClearCommand.php +++ b/packages/cache/src/Commands/CacheClearCommand.php @@ -21,7 +21,7 @@ use function Tempest\Support\arr; -if (class_exists(\Tempest\Console\ConsoleCommand::class)) { +if (class_exists(ConsoleCommand::class)) { final readonly class CacheClearCommand { use HasConsole; diff --git a/packages/cache/src/GenericCache.php b/packages/cache/src/GenericCache.php index 2023dd58be..b22329bcaa 100644 --- a/packages/cache/src/GenericCache.php +++ b/packages/cache/src/GenericCache.php @@ -56,7 +56,7 @@ public function put(Stringable|string $key, mixed $value, null|Duration|DateTime $expiration = DateTime::now()->plus($expiration); } - if ($expiration !== null) { + if ($expiration instanceof DateTimeInterface) { $item = $item->expiresAt($expiration->toNativeDateTime()); } @@ -74,6 +74,7 @@ public function putMany(iterable $values, null|Duration|DateTimeInterface $expir foreach ($values as $key => $value) { $items[(string) $key] = $this->put($key, $value, $expiration); } + return $items; } @@ -149,7 +150,7 @@ public function resolve(Stringable|string $key, Closure $callback, null|Duration return $callback(); } - if ($stale) { + if ($stale instanceof Duration) { if ($expiration instanceof Duration) { $expiration = DateTime::now()->plus($expiration); } @@ -168,7 +169,7 @@ public function resolve(Stringable|string $key, Closure $callback, null|Duration private function resolveAllowingStale(Stringable|string $key, Closure $callback, DateTimeInterface $expiration, Duration $stale): mixed { - if (! $this->deferredTasks) { + if (! $this->deferredTasks instanceof DeferredTasks) { return $this->resolve($key, $callback, $expiration); } diff --git a/packages/cache/src/GenericLock.php b/packages/cache/src/GenericLock.php index 98b6963aec..c752845539 100644 --- a/packages/cache/src/GenericLock.php +++ b/packages/cache/src/GenericLock.php @@ -32,7 +32,7 @@ public function acquire(): bool return false; } - $expiration = $this->duration !== null + $expiration = $this->duration instanceof Duration ? DateTime::now()->plus($this->duration) : null; diff --git a/packages/cache/src/Lock.php b/packages/cache/src/Lock.php index 908df168b4..e6ad9fc2ed 100644 --- a/packages/cache/src/Lock.php +++ b/packages/cache/src/Lock.php @@ -12,23 +12,17 @@ interface Lock /** * The key used to identify the lock. This should be unique across all locks. */ - public string $key { - get; - } + public string $key { get; } /** * The duration of the lock. If null, the lock will not expire. */ - public ?Duration $duration { - get; - } + public ?Duration $duration { get; } /** * The owner of the lock. This is used to verify that the lock is being released by the correct owner. */ - public string $owner { - get; - } + public string $owner { get; } /** * Attempts to acquire a lock. diff --git a/packages/cache/src/Testing/CacheTester.php b/packages/cache/src/Testing/CacheTester.php index 84a04e748c..c8023a706f 100644 --- a/packages/cache/src/Testing/CacheTester.php +++ b/packages/cache/src/Testing/CacheTester.php @@ -2,6 +2,7 @@ namespace Tempest\Cache\Testing; +use RuntimeException; use Tempest\Cache\Cache; use Tempest\Cache\CacheInitializer; use Tempest\Clock\Clock; @@ -37,7 +38,7 @@ public function fake(null|string|UnitEnum $tag = null): TestingCache public function preventUsageWithoutFake(): void { if (! $this->container instanceof GenericContainer) { - throw new \RuntimeException('Container is not a GenericContainer, unable to prevent usage without fake.'); + throw new RuntimeException('Container is not a GenericContainer, unable to prevent usage without fake.'); } $this->container->unregister(Cache::class, tagged: true); diff --git a/packages/cache/src/Testing/TestingCache.php b/packages/cache/src/Testing/TestingCache.php index 3313a8352f..72748ac153 100644 --- a/packages/cache/src/Testing/TestingCache.php +++ b/packages/cache/src/Testing/TestingCache.php @@ -28,6 +28,7 @@ final class TestingCache implements Cache } private Cache $cache; + private ArrayAdapter $adapter; public function __construct( diff --git a/packages/cache/src/Testing/TestingLock.php b/packages/cache/src/Testing/TestingLock.php index 1cccdb33a9..73bb7f98b3 100644 --- a/packages/cache/src/Testing/TestingLock.php +++ b/packages/cache/src/Testing/TestingLock.php @@ -61,7 +61,7 @@ public function assertLocked(null|Stringable|string $by = null, null|DateTimeInt : "Lock `{$this->key}` is not being held.", ); - if ($for) { + if ($for !== null) { if ($for instanceof DateTimeInterface) { $for = $for->since(DateTime::now()); } diff --git a/packages/cache/src/UserCacheInsightsProvider.php b/packages/cache/src/UserCacheInsightsProvider.php index 81d1ef18e5..6fb6cbc88c 100644 --- a/packages/cache/src/UserCacheInsightsProvider.php +++ b/packages/cache/src/UserCacheInsightsProvider.php @@ -45,7 +45,7 @@ public function getInsights(): array private function getInsight(Cache $cache): array { $type = $cache instanceof GenericCache - ? match (get_class($cache->adapter)) { + ? match ($cache->adapter::class) { FilesystemAdapter::class => new Insight('Filesystem'), PhpFilesAdapter::class => new Insight('PHP'), ArrayAdapter::class => new Insight('In-memory'), diff --git a/packages/command-bus/src/Async.php b/packages/command-bus/src/Async.php index eb1b35a497..b3b6b5852f 100644 --- a/packages/command-bus/src/Async.php +++ b/packages/command-bus/src/Async.php @@ -7,6 +7,4 @@ use Attribute; #[Attribute] -final readonly class Async -{ -} +final readonly class Async {} diff --git a/packages/command-bus/src/GenericCommandBus.php b/packages/command-bus/src/GenericCommandBus.php index 9c071545bf..5ae0e156cd 100644 --- a/packages/command-bus/src/GenericCommandBus.php +++ b/packages/command-bus/src/GenericCommandBus.php @@ -20,7 +20,7 @@ public function dispatch(object $command): void { $commandHandler = $this->getCommandHandler($command); - if ($commandHandler === null) { + if (! $commandHandler instanceof CommandHandler) { throw new CommandHandlerWasNotFound($command); } diff --git a/packages/command-bus/src/HandleAsyncCommand.php b/packages/command-bus/src/HandleAsyncCommand.php index 7947189fa8..88fadf9c95 100644 --- a/packages/command-bus/src/HandleAsyncCommand.php +++ b/packages/command-bus/src/HandleAsyncCommand.php @@ -13,7 +13,7 @@ use function Tempest\Support\arr; -if (class_exists(\Tempest\Console\ConsoleCommand::class)) { +if (class_exists(ConsoleCommand::class)) { final readonly class HandleAsyncCommand { use HasConsole; diff --git a/packages/command-bus/src/MonitorAsyncCommands.php b/packages/command-bus/src/MonitorAsyncCommands.php index 03187e00b7..1faa47600a 100644 --- a/packages/command-bus/src/MonitorAsyncCommands.php +++ b/packages/command-bus/src/MonitorAsyncCommands.php @@ -13,7 +13,7 @@ use function Tempest\Support\arr; -if (class_exists(\Tempest\Console\ConsoleCommand::class)) { +if (class_exists(ConsoleCommand::class)) { final readonly class MonitorAsyncCommands { use HasConsole; @@ -35,29 +35,35 @@ public function __invoke(): void while (true) { // @phpstan-ignore-line foreach ($processes as $uuid => $process) { - if ($process->isTerminated()) { - if ($process->isSuccessful()) { - $this->console->keyValue( - key: "{$uuid}", - value: "SUCCESS", - ); - } else { - $this->console->keyValue( - key: "{$uuid}", - value: "FAILED", - ); - } - - if ($output = trim($process->getOutput())) { - $this->writeln($output); - } - - if ($errorOutput = trim($process->getErrorOutput())) { - $this->writeln($errorOutput); - } - - unset($processes[$uuid]); + if (! $process->isTerminated()) { + continue; } + + if ($process->isSuccessful()) { + $this->console->keyValue( + key: "{$uuid}", + value: "SUCCESS", + ); + } else { + $this->console->keyValue( + key: "{$uuid}", + value: "FAILED", + ); + } + + $output = trim($process->getOutput()); + + if ($output !== '' && $output !== '0') { + $this->writeln($output); + } + + $errorOutput = trim($process->getErrorOutput()); + + if ($errorOutput !== '' && $errorOutput !== '0') { + $this->writeln($errorOutput); + } + + unset($processes[$uuid]); } $availableCommands = arr($this->repository->getPendingCommands()) diff --git a/packages/command-bus/src/functions.php b/packages/command-bus/src/functions.php index e9dfbceda2..3333d44a53 100644 --- a/packages/command-bus/src/functions.php +++ b/packages/command-bus/src/functions.php @@ -4,7 +4,6 @@ namespace Tempest\CommandBus; -use Tempest\CommandBus\CommandBus; use Tempest\Container; /** diff --git a/packages/console/src/Actions/RenderConsoleCommand.php b/packages/console/src/Actions/RenderConsoleCommand.php index 8015f7293b..6ef462af5b 100644 --- a/packages/console/src/Actions/RenderConsoleCommand.php +++ b/packages/console/src/Actions/RenderConsoleCommand.php @@ -30,10 +30,8 @@ public function __invoke(ConsoleCommand $consoleCommand): void } } - if ($this->renderDescription) { - if ($consoleCommand->description !== null && $consoleCommand->description !== '') { - $parts[] = "{$consoleCommand->description}"; - } + if ($this->renderDescription && ($consoleCommand->description !== null && $consoleCommand->description !== '')) { + $parts[] = "{$consoleCommand->description}"; } $this->console->writeln(implode(' ', $parts)); diff --git a/packages/console/src/CanOpenInEditor.php b/packages/console/src/CanOpenInEditor.php index 3ff635bb0e..f39561b98c 100644 --- a/packages/console/src/CanOpenInEditor.php +++ b/packages/console/src/CanOpenInEditor.php @@ -4,6 +4,4 @@ namespace Tempest\Console; -interface CanOpenInEditor -{ -} +interface CanOpenInEditor {} diff --git a/packages/console/src/Commands/AboutCommand.php b/packages/console/src/Commands/AboutCommand.php index c5ca553993..33a85b403d 100644 --- a/packages/console/src/Commands/AboutCommand.php +++ b/packages/console/src/Commands/AboutCommand.php @@ -22,9 +22,9 @@ final readonly class AboutCommand { public function __construct( - private readonly Console $console, - private readonly Container $container, - private readonly AppConfig $appConfig, + private Console $console, + private Container $container, + private AppConfig $appConfig, ) {} #[ConsoleCommand(name: 'about', description: 'Shows insights about the application', aliases: ['insights'])] diff --git a/packages/console/src/Commands/CompletionInstallCommand.php b/packages/console/src/Commands/CompletionInstallCommand.php index 434591d51e..a60477837e 100644 --- a/packages/console/src/Commands/CompletionInstallCommand.php +++ b/packages/console/src/Commands/CompletionInstallCommand.php @@ -51,7 +51,7 @@ public function __invoke( $shell ??= ($this->resolveShell)('Which shell do you want to install completions for?'); - if ($shell === null) { + if (! $shell instanceof Shell) { $this->console->error('Could not detect shell. Please specify one using the --shell option. Possible values are: zsh, bash, fish.'); return ExitCode::ERROR; diff --git a/packages/console/src/Commands/CompletionShowCommand.php b/packages/console/src/Commands/CompletionShowCommand.php index e816b04b6e..2bee1e1356 100644 --- a/packages/console/src/Commands/CompletionShowCommand.php +++ b/packages/console/src/Commands/CompletionShowCommand.php @@ -43,7 +43,7 @@ public function __invoke( $shell ??= ($this->resolveShell)('Which shell completion script do you want to see?'); - if ($shell === null) { + if (! $shell instanceof Shell) { $this->console->error('Could not detect shell. Please specify one using the --shell option. Possible values are: zsh, bash, fish.'); return ExitCode::ERROR; diff --git a/packages/console/src/Commands/CompletionUninstallCommand.php b/packages/console/src/Commands/CompletionUninstallCommand.php index 21bc32f16b..1ece3d629c 100644 --- a/packages/console/src/Commands/CompletionUninstallCommand.php +++ b/packages/console/src/Commands/CompletionUninstallCommand.php @@ -42,7 +42,7 @@ public function __invoke( $shell ??= ($this->resolveShell)('Which shell completions do you want to uninstall?'); - if ($shell === null) { + if (! $shell instanceof Shell) { $this->console->error('Could not detect shell. Please specify one using the --shell option. Possible values are: zsh, bash, fish.'); return ExitCode::ERROR; diff --git a/packages/console/src/Commands/MakeConfigCommand.php b/packages/console/src/Commands/MakeConfigCommand.php index eee7a984c0..73183f7580 100644 --- a/packages/console/src/Commands/MakeConfigCommand.php +++ b/packages/console/src/Commands/MakeConfigCommand.php @@ -68,7 +68,11 @@ private function getStubFileFromConfigType(ConfigType $configType): StubFile default => throw new InvalidArgumentException(sprintf('The "%s" config type has no supported stub file.', $configType->value)), }; } catch (InvalidArgumentException $invalidArgumentException) { - throw new FileGenerationFailedException(sprintf('Cannot retrieve stub file: %s', $invalidArgumentException->getMessage())); + throw new FileGenerationFailedException( + sprintf('Cannot retrieve stub file: %s', $invalidArgumentException->getMessage()), + $invalidArgumentException->getCode(), + $invalidArgumentException, + ); } } } diff --git a/packages/console/src/Completion/CompletionEngine.php b/packages/console/src/Completion/CompletionEngine.php index ecc53dc374..de86d1b3eb 100644 --- a/packages/console/src/Completion/CompletionEngine.php +++ b/packages/console/src/Completion/CompletionEngine.php @@ -47,7 +47,11 @@ private function completeCommands(CompletionMetadata $metadata, string $current) $candidates = []; foreach ($metadata->commands as $name => $command) { - if (! is_string($name) || ! $command instanceof CompletionCommand) { + if (! is_string($name)) { + continue; + } + + if (! $command instanceof CompletionCommand) { continue; } @@ -131,9 +135,11 @@ private function selectCompletionValue(CompletionFlag $flag, string $current): ? $candidates[] = $flag->flag; foreach ($flag->aliases as $alias) { - if (str_starts_with($alias, '--')) { - $candidates[] = $alias; + if (! str_starts_with($alias, '--')) { + continue; } + + $candidates[] = $alias; } } elseif (str_starts_with($current, '-')) { foreach ($flag->aliases as $alias) { diff --git a/packages/console/src/Components/Interactive/MultipleChoiceComponent.php b/packages/console/src/Components/Interactive/MultipleChoiceComponent.php index c9f52f263e..3c69024628 100644 --- a/packages/console/src/Components/Interactive/MultipleChoiceComponent.php +++ b/packages/console/src/Components/Interactive/MultipleChoiceComponent.php @@ -109,12 +109,12 @@ public function input(string $key): void if (! $this->bufferEnabled && $key === '/') { $this->bufferEnabled = true; $this->updateQuery(); - return; - } elseif ($this->bufferEnabled && $key === '/') { + } + + if ($this->bufferEnabled && $key === '/') { $this->bufferEnabled = false; $this->updateQuery(); - return; } diff --git a/packages/console/src/Components/Interactive/SearchComponent.php b/packages/console/src/Components/Interactive/SearchComponent.php index a1665d6c94..055e4bdf1e 100644 --- a/packages/console/src/Components/Interactive/SearchComponent.php +++ b/packages/console/src/Components/Interactive/SearchComponent.php @@ -9,6 +9,7 @@ use Tempest\Console\Components\Concerns\HasState; use Tempest\Console\Components\Concerns\HasTextBuffer; use Tempest\Console\Components\Concerns\RendersControls; +use Tempest\Console\Components\Option; use Tempest\Console\Components\OptionCollection; use Tempest\Console\Components\Renderers\ChoiceRenderer; use Tempest\Console\Components\Static\StaticSearchComponent; @@ -157,7 +158,7 @@ public function enter(): mixed return $this->options->getRawSelectedOptions() ?: $this->default; } - if (($active = $this->options->getActive()) !== null) { + if (($active = $this->options->getActive()) instanceof Option) { return $active->value; } diff --git a/packages/console/src/Components/Interactive/SingleChoiceComponent.php b/packages/console/src/Components/Interactive/SingleChoiceComponent.php index b0d9cc44e7..75c4100f2b 100644 --- a/packages/console/src/Components/Interactive/SingleChoiceComponent.php +++ b/packages/console/src/Components/Interactive/SingleChoiceComponent.php @@ -113,11 +113,11 @@ public function input(string $key): void { if (! $this->bufferEnabled && $key === '/') { $this->bufferEnabled = true; - return; - } elseif ($this->bufferEnabled && $key === '/') { - $this->bufferEnabled = false; + } + if ($this->bufferEnabled && $key === '/') { + $this->bufferEnabled = false; return; } diff --git a/packages/console/src/Components/Interactive/TaskComponent.php b/packages/console/src/Components/Interactive/TaskComponent.php index 4ccb73edec..8e30a6f6c3 100644 --- a/packages/console/src/Components/Interactive/TaskComponent.php +++ b/packages/console/src/Components/Interactive/TaskComponent.php @@ -139,9 +139,11 @@ private function renderTask(Terminal $terminal, ?string $line = null): string private function cleanupSockets(): void { foreach ($this->sockets as $socket) { - if (is_resource($socket)) { - @fclose($socket); + if (! is_resource($socket)) { + continue; } + + @fclose($socket); } $this->sockets = []; @@ -171,17 +173,17 @@ private function resolveHandler(null|Process|Closure $handler): ?Closure } if ($handler instanceof Process) { - return static function (Closure $log) use ($handler): bool { - return $handler->run(function (string $type, string $buffer) use ($log): void { - if ($type === Process::ERR) { - return; - } - - if ($line = trim($buffer)) { - $log($line); - } - }) === 0; - }; + return static fn (Closure $log): bool => $handler->run(function (string $type, string $buffer) use ($log): void { + if ($type === Process::ERR) { + return; + } + + $line = trim($buffer); + + if ($line !== '' && $line !== '0') { + $log($line); + } + }) === 0; } return $handler; diff --git a/packages/console/src/Components/InteractiveComponentRenderer.php b/packages/console/src/Components/InteractiveComponentRenderer.php index 63bb076d28..a77ccc571a 100644 --- a/packages/console/src/Components/InteractiveComponentRenderer.php +++ b/packages/console/src/Components/InteractiveComponentRenderer.php @@ -66,7 +66,7 @@ private function renderComponent(Console $console, InteractiveConsoleComponent $ // If we're running within a fiber, we'll suspend here as well so that the parent can continue // This is needed for our testing helper - if (Fiber::getCurrent() !== null) { + if (Fiber::getCurrent() instanceof Fiber) { Fiber::suspend(); } } @@ -246,11 +246,7 @@ public function isComponentSupported(Console $console, InteractiveConsoleCompone return false; } - if (! Terminal::supportsTty()) { - return false; - } - - return true; + return Terminal::supportsTty(); } private function createTerminal(Console $console): Terminal diff --git a/packages/console/src/Components/OptionCollection.php b/packages/console/src/Components/OptionCollection.php index 16243f1be6..12aeb37c4f 100644 --- a/packages/console/src/Components/OptionCollection.php +++ b/packages/console/src/Components/OptionCollection.php @@ -83,7 +83,7 @@ public function next(): void public function toggleCurrent(): void { - if (($active = $this->getActive()) === null) { + if (! ($active = $this->getActive()) instanceof Option) { return; } @@ -133,7 +133,7 @@ public function getRawActiveOption(mixed $default = null): mixed { $option = $this->getActive(); - if ($option === null) { + if (! $option instanceof Option) { return $default; } diff --git a/packages/console/src/Components/Renderers/ChoiceRenderer.php b/packages/console/src/Components/Renderers/ChoiceRenderer.php index 463140131b..bceb85f73c 100644 --- a/packages/console/src/Components/Renderers/ChoiceRenderer.php +++ b/packages/console/src/Components/Renderers/ChoiceRenderer.php @@ -56,9 +56,9 @@ public function render( // Otherwise, display the filter line $this->line( $this->style($filtering ? 'fg-magenta' : 'fg-gray', '/ '), - ! $query->text - ? $this->style('fg-gray dim', $placeholder ?? ($this->multiple && ! $filtering ? count($options->getSelectedOptions()) . ' selected' : '')) - : $this->style($filtering ? 'fg-cyan' : 'fg-gray', $this->truncateLeft($query->text, maxLineOffset: 2)), + $query->text + ? $this->style($filtering ? 'fg-cyan' : 'fg-gray', $this->truncateLeft($query->text, maxLineOffset: 2)) + : $this->style('fg-gray dim', $placeholder ?? ($this->multiple && ! $filtering ? count($options->getSelectedOptions()) . ' selected' : '')), )->newLine(); // And the choices. diff --git a/packages/console/src/Components/Renderers/ConfirmRenderer.php b/packages/console/src/Components/Renderers/ConfirmRenderer.php index 95808b08c9..ff6ad382cb 100644 --- a/packages/console/src/Components/Renderers/ConfirmRenderer.php +++ b/packages/console/src/Components/Renderers/ConfirmRenderer.php @@ -36,7 +36,7 @@ public function render( }, "\n"), default => $this->line( $this->style( - $answer === true ? 'fg-green bold' : 'fg-gray dim', + $answer ? 'fg-green bold' : 'fg-gray dim', '→ ' . $this->yes, ), ' ', diff --git a/packages/console/src/Components/Renderers/TaskRenderer.php b/packages/console/src/Components/Renderers/TaskRenderer.php index 0e73f87a9d..d4e1ffa7fa 100644 --- a/packages/console/src/Components/Renderers/TaskRenderer.php +++ b/packages/console/src/Components/Renderers/TaskRenderer.php @@ -23,7 +23,7 @@ public function render(Terminal $terminal, ComponentState $state, float $started $this->prepareRender($terminal, $state); $this->label($this->label); - $runtime = fn (float $finishedAt) => $finishedAt + $runtime = fn (float $finishedAt) => $finishedAt !== 0.0 ? number_format(($finishedAt - $startedAt) / 1_000_000, decimals: 0) : null; diff --git a/packages/console/src/Components/Static/StaticMultipleChoiceComponent.php b/packages/console/src/Components/Static/StaticMultipleChoiceComponent.php index 76e3a8a0db..46c529b437 100644 --- a/packages/console/src/Components/Static/StaticMultipleChoiceComponent.php +++ b/packages/console/src/Components/Static/StaticMultipleChoiceComponent.php @@ -41,7 +41,7 @@ public function render(Console $console): array ->toString() ?: 'no option'; $continue = $console->confirm( - question: $answers + question: $answers !== [] ? "You picked {$answerAsString}; continue?" : "Continue with {$answerAsString}?", default: true, @@ -97,11 +97,7 @@ private function askQuestion(Console $console): array return true; } - if ($this->options->getOptions()->isList() && $answer === (string) $option->key) { - return true; - } - - return false; + return $this->options->getOptions()->isList() && $answer === (string) $option->key; }); }) ->filter() diff --git a/packages/console/src/Components/Static/StaticSearchComponent.php b/packages/console/src/Components/Static/StaticSearchComponent.php index 9630c65ce6..ba62597aa6 100644 --- a/packages/console/src/Components/Static/StaticSearchComponent.php +++ b/packages/console/src/Components/Static/StaticSearchComponent.php @@ -43,8 +43,8 @@ public function render(Console $console): null|array|string $answer = $console->ask( question: 'Please select a result', options: $options, - multiple: $this->multiple, default: $this->multiple ? [] : self::CANCEL, + multiple: $this->multiple, ); if ($answer === self::SEARCH_AGAIN) { diff --git a/packages/console/src/Components/Static/StaticSingleChoiceComponent.php b/packages/console/src/Components/Static/StaticSingleChoiceComponent.php index 8010ad1cd8..41853a12ba 100644 --- a/packages/console/src/Components/Static/StaticSingleChoiceComponent.php +++ b/packages/console/src/Components/Static/StaticSingleChoiceComponent.php @@ -71,11 +71,7 @@ public function render(Console $console): null|int|UnitEnum|string return true; } - if ($this->options->getOptions()->isList() && $answer === (string) $option->key) { - return true; - } - - return false; + return $this->options->getOptions()->isList() && $answer === (string) $option->key; }); if ($selectedOption !== null) { diff --git a/packages/console/src/Console.php b/packages/console/src/Console.php index 056ce55845..57875c72d4 100644 --- a/packages/console/src/Console.php +++ b/packages/console/src/Console.php @@ -161,7 +161,5 @@ public function disablePrompting(): self; /** * Whether the console is in forced mode (skipping confirmations). */ - public bool $isForced { - get; - } + public bool $isForced { get; } } diff --git a/packages/console/src/ConsoleInputBuilder.php b/packages/console/src/ConsoleInputBuilder.php index 2b8f0aad9a..1a93db3548 100644 --- a/packages/console/src/ConsoleInputBuilder.php +++ b/packages/console/src/ConsoleInputBuilder.php @@ -42,7 +42,7 @@ public function build(): array ? $this->argumentBag->findArrayFor($argumentDefinition) : $this->argumentBag->findFor($argumentDefinition); - if ($argument === null) { + if (! $argument instanceof ConsoleInputArgument) { $invalidArguments[] = $argumentDefinition; continue; diff --git a/packages/console/src/Exceptions/InvalidCommandException.php b/packages/console/src/Exceptions/InvalidCommandException.php index cff1141f92..3301854b3c 100644 --- a/packages/console/src/Exceptions/InvalidCommandException.php +++ b/packages/console/src/Exceptions/InvalidCommandException.php @@ -24,7 +24,7 @@ public function render(Console $console): void $this->invalidArguments, )); - if ($missingArguments) { + if ($missingArguments !== '' && $missingArguments !== '0') { $console->writeln(); $console->error("Missing arguments: {$missingArguments}"); } else { diff --git a/packages/console/src/GenericConsole.php b/packages/console/src/GenericConsole.php index c22bc951fa..06185f7b0b 100644 --- a/packages/console/src/GenericConsole.php +++ b/packages/console/src/GenericConsole.php @@ -195,7 +195,7 @@ public function keyValue(string $key, ?string $value = null, bool $useAvailableW public function component(InteractiveConsoleComponent $component, array $validation = []): mixed { - if ($this->componentRenderer !== null && $this->supportsPrompting() && $this->componentRenderer->isComponentSupported($this, $component)) { + if ($this->componentRenderer instanceof InteractiveComponentRenderer && $this->supportsPrompting() && $this->componentRenderer->isComponentSupported($this, $component)) { return $this->componentRenderer->render($this, $component, $validation); } @@ -310,10 +310,6 @@ public function supportsPrompting(): bool return false; } - if ($this->argumentBag->get(GlobalFlags::INTERACTION->value)?->value === false) { - return false; - } - - return true; + return $this->argumentBag->get(GlobalFlags::INTERACTION->value)?->value !== false; } } diff --git a/packages/console/src/HasStaticComponent.php b/packages/console/src/HasStaticComponent.php index c23fa81ace..ef896911ca 100644 --- a/packages/console/src/HasStaticComponent.php +++ b/packages/console/src/HasStaticComponent.php @@ -6,7 +6,5 @@ interface HasStaticComponent { - public StaticConsoleComponent $staticComponent { - get; - } + public StaticConsoleComponent $staticComponent { get; } } diff --git a/packages/console/src/Highlight/IsTagInjection.php b/packages/console/src/Highlight/IsTagInjection.php index 740263d00e..bb519ea81f 100644 --- a/packages/console/src/Highlight/IsTagInjection.php +++ b/packages/console/src/Highlight/IsTagInjection.php @@ -26,7 +26,7 @@ public function parse(string $content, Highlighter $highlighter): ParsedInjectio callback: function ($matches) use ($highlighter) { $content = $matches['match'] ?? ''; - if (! $content) { + if ($content === '' || $content === '0') { return $matches[0]; } diff --git a/packages/console/src/Highlight/TempestConsoleLanguage/Injections/DynamicInjection.php b/packages/console/src/Highlight/TempestConsoleLanguage/Injections/DynamicInjection.php index cbaae269b8..66ed85f539 100644 --- a/packages/console/src/Highlight/TempestConsoleLanguage/Injections/DynamicInjection.php +++ b/packages/console/src/Highlight/TempestConsoleLanguage/Injections/DynamicInjection.php @@ -19,7 +19,6 @@ public function parse(string $content, Highlighter $highlighter): ParsedInjectio do { $content = preg_replace_callback( - subject: $content, pattern: $pattern, callback: function ($matches) use ($highlighter) { $theme = $highlighter->getTheme(); @@ -40,6 +39,7 @@ public function parse(string $content, Highlighter $highlighter): ParsedInjectio ->replaceLast('', $after) ->toString(); }, + subject: $content, ); } while (preg_match($pattern, $content)); diff --git a/packages/console/src/Highlight/TempestConsoleLanguage/Injections/FileInjection.php b/packages/console/src/Highlight/TempestConsoleLanguage/Injections/FileInjection.php index b455eb5d3d..fc0868ddf2 100644 --- a/packages/console/src/Highlight/TempestConsoleLanguage/Injections/FileInjection.php +++ b/packages/console/src/Highlight/TempestConsoleLanguage/Injections/FileInjection.php @@ -18,7 +18,6 @@ public function parse(string $content, Highlighter $highlighter): ParsedInjection { return new ParsedInjection(preg_replace_callback( - subject: $content, pattern: '/(?\[\"\'])(?.+)\k\s*\/?>)/', callback: function (array $matches) { $href = $matches['file']; @@ -29,6 +28,7 @@ public function parse(string $content, Highlighter $highlighter): ParsedInjectio return TerminalStyle::UNDERLINE((string) $file); }, + subject: $content, )); } } diff --git a/packages/console/src/Highlight/TempestConsoleLanguage/Injections/LinkInjection.php b/packages/console/src/Highlight/TempestConsoleLanguage/Injections/LinkInjection.php index cc5d3a47f7..79b068e046 100644 --- a/packages/console/src/Highlight/TempestConsoleLanguage/Injections/LinkInjection.php +++ b/packages/console/src/Highlight/TempestConsoleLanguage/Injections/LinkInjection.php @@ -15,7 +15,6 @@ public function parse(string $content, Highlighter $highlighter): ParsedInjection { return new ParsedInjection(preg_replace_callback( - subject: $content, pattern: '/(?\[\"\'])(?.+)\k\>(?:(?!\)/', callback: function (array $matches) { $quote = $matches['quote']; @@ -27,6 +26,7 @@ public function parse(string $content, Highlighter $highlighter): ParsedInjectio ->replaceLast('', "\x1b]8;;\x1b\\") ->toString(); }, + subject: $content, )); } } diff --git a/packages/console/src/Input/ConsoleArgumentBag.php b/packages/console/src/Input/ConsoleArgumentBag.php index 6cb10bbcad..b8d396b538 100644 --- a/packages/console/src/Input/ConsoleArgumentBag.php +++ b/packages/console/src/Input/ConsoleArgumentBag.php @@ -117,9 +117,11 @@ public function findArrayFor(ConsoleArgumentDefinition $argumentDefinition): Con $values = []; foreach ($this->arguments as $argument) { - if ($argumentDefinition->matchesArgument($argument)) { - $values[] = $argument->value; + if (! $argumentDefinition->matchesArgument($argument)) { + continue; } + + $values[] = $argument->value; } return new ConsoleInputArgument( @@ -137,13 +139,15 @@ public function findForVariadicArgument(ConsoleArgumentDefinition $argumentDefin $arguments = []; foreach ($this->arguments as $argument) { - if ($argument->position >= $argumentDefinition->position) { - $arguments[] = new ConsoleInputArgument( - name: $argumentDefinition->name, - position: $argument->position, - value: $this->resolveArgumentValue($argumentDefinition, $argument)->value, - ); + if ($argument->position < $argumentDefinition->position) { + continue; } + + $arguments[] = new ConsoleInputArgument( + name: $argumentDefinition->name, + position: $argument->position, + value: $this->resolveArgumentValue($argumentDefinition, $argument)->value, + ); } return $arguments; @@ -173,16 +177,18 @@ public function addMany(array $arguments): self // Otherwise, $arguments is an array of flags or positional argument. foreach ($arguments as $key => $argument) { - if (str_starts_with($argument, '-') && ! str_starts_with($argument, '--')) { - $flags = str_split($argument); - unset($flags[0]); + if (! (str_starts_with($argument, '-') && ! str_starts_with($argument, '--'))) { + continue; + } - foreach ($flags as $flag) { - $arguments[] = "-{$flag}"; - } + $flags = str_split($argument); + unset($flags[0]); - unset($arguments[$key]); + foreach ($flags as $flag) { + $arguments[] = "-{$flag}"; } + + unset($arguments[$key]); } $position = count($this->arguments); diff --git a/packages/console/src/Input/ConsoleArgumentDefinition.php b/packages/console/src/Input/ConsoleArgumentDefinition.php index c636990d8d..1991097557 100644 --- a/packages/console/src/Input/ConsoleArgumentDefinition.php +++ b/packages/console/src/Input/ConsoleArgumentDefinition.php @@ -32,7 +32,7 @@ public static function fromParameter(ParameterReflector $parameter): ConsoleArgu $boolean = $type->getName() === 'bool' || is_bool($default); return new ConsoleArgumentDefinition( - name: static::normalizeName($attribute->name ?? $parameter->getName(), boolean: $boolean), + name: self::normalizeName($attribute->name ?? $parameter->getName(), boolean: $boolean), type: $type->getName(), default: $default, hasDefault: $parameter->isDefaultValueAvailable(), @@ -56,7 +56,7 @@ public function matchesArgument(ConsoleInputArgument $argument): bool return array_any( array: [$this->name, ...$this->aliases], - callback: fn ($match) => $argument->matches(static::normalizeName($match, $this->type === 'bool')), + callback: fn ($match) => $argument->matches(self::normalizeName($match, $this->type === 'bool')), ); } diff --git a/packages/console/src/Input/MemoryInputBuffer.php b/packages/console/src/Input/MemoryInputBuffer.php index 63676ce4e0..0600eb26f8 100644 --- a/packages/console/src/Input/MemoryInputBuffer.php +++ b/packages/console/src/Input/MemoryInputBuffer.php @@ -7,6 +7,7 @@ use Exception; use Fiber; use FiberError; +use RuntimeException; use Tempest\Console\InputBuffer; use Tempest\Console\Key; @@ -29,7 +30,7 @@ public function add(int|string|Key ...$input): void try { $this->fiber?->resume(); } catch (FiberError) { - throw new \RuntimeException(sprintf( + throw new RuntimeException(sprintf( 'Tried to send [%s] to the console, but no input was expected.', implode( separator: ', ', diff --git a/packages/console/src/Middleware/ForceMiddleware.php b/packages/console/src/Middleware/ForceMiddleware.php index 65ae19620d..8f15f4af0f 100644 --- a/packages/console/src/Middleware/ForceMiddleware.php +++ b/packages/console/src/Middleware/ForceMiddleware.php @@ -22,10 +22,11 @@ public function __construct( public function __invoke(Invocation $invocation, ConsoleMiddlewareCallable $next): ExitCode|int { - if ($invocation->argumentBag->get(GlobalFlags::FORCE_SHORTHAND->value) || $invocation->argumentBag->get(GlobalFlags::FORCE->value)) { - if ($this->console instanceof GenericConsole) { - $this->console->setForced(); - } + if ( + ($invocation->argumentBag->get(GlobalFlags::FORCE_SHORTHAND->value) || $invocation->argumentBag->get(GlobalFlags::FORCE->value)) + && $this->console instanceof GenericConsole + ) { + $this->console->setForced(); } return $next($invocation); diff --git a/packages/console/src/Middleware/OverviewMiddleware.php b/packages/console/src/Middleware/OverviewMiddleware.php index f68ce82273..0e51b8a8dc 100644 --- a/packages/console/src/Middleware/OverviewMiddleware.php +++ b/packages/console/src/Middleware/OverviewMiddleware.php @@ -31,7 +31,7 @@ public function __construct( public function __invoke(Invocation $invocation, ConsoleMiddlewareCallable $next): ExitCode|int { - if (! $invocation->argumentBag->getCommandName()) { + if ($invocation->argumentBag->getCommandName() === '' || $invocation->argumentBag->getCommandName() === '0') { $this->renderOverview(showHidden: $invocation->argumentBag->has('--all', '-a')); return ExitCode::SUCCESS; diff --git a/packages/console/src/Middleware/ResolveOrRescueMiddleware.php b/packages/console/src/Middleware/ResolveOrRescueMiddleware.php index 1f252fc2e5..97771ee3f3 100644 --- a/packages/console/src/Middleware/ResolveOrRescueMiddleware.php +++ b/packages/console/src/Middleware/ResolveOrRescueMiddleware.php @@ -92,12 +92,9 @@ private function getSimilarCommands(ImmutableString $search): ImmutableArray $searchParts = $search->explode(':'); // `dis:st` will match `discovery:status` - if ($searchParts->count() === $currentParts->count()) { - if ($searchParts->every(fn (string $part, int $index) => str_starts_with($currentParts[$index], $part))) { - $suggestions[$currentName->toString()] = $currentName; - - continue; - } + if ($searchParts->count() === $currentParts->count() && $searchParts->every(fn (string $part, int $index) => str_starts_with($currentParts[$index], $part))) { + $suggestions[$currentName->toString()] = $currentName; + continue; } // `generate` will match `discovery:generate` diff --git a/packages/console/src/Middleware/ValidateNamedArgumentsMiddleware.php b/packages/console/src/Middleware/ValidateNamedArgumentsMiddleware.php index c7b4cd1435..375102a9e0 100644 --- a/packages/console/src/Middleware/ValidateNamedArgumentsMiddleware.php +++ b/packages/console/src/Middleware/ValidateNamedArgumentsMiddleware.php @@ -24,12 +24,8 @@ public function __invoke(Invocation $invocation, ConsoleMiddlewareCallable $next } $allowedParameterNames = arr($invocation->consoleCommand->getArgumentDefinitions()) - ->flatMap(function (ConsoleArgumentDefinition $definition) { - return [$definition->name, ...$definition->aliases]; - }) - ->map(function (string $name) { - return ltrim($name, '-'); - }); + ->flatMap(fn (ConsoleArgumentDefinition $definition) => [$definition->name, ...$definition->aliases]) + ->map(fn (string $name) => ltrim($name, '-')); $invalidInput = arr($invocation->argumentBag->arguments) ->filter(fn (ConsoleInputArgument $argument) => $argument->name !== null) diff --git a/packages/console/src/Output/TailReader.php b/packages/console/src/Output/TailReader.php index 4191a8128b..b4024fa684 100644 --- a/packages/console/src/Output/TailReader.php +++ b/packages/console/src/Output/TailReader.php @@ -20,7 +20,7 @@ public function tail(string $path, ?Closure $format = null): void /** @phpstan-ignore-next-line */ while (true) { - if (Fiber::getCurrent() !== null) { + if (Fiber::getCurrent() instanceof Fiber) { Fiber::suspend(); } diff --git a/packages/console/src/Scheduler/NullScheduler.php b/packages/console/src/Scheduler/NullScheduler.php index 7cd1d58ad0..3ca9e1eb68 100644 --- a/packages/console/src/Scheduler/NullScheduler.php +++ b/packages/console/src/Scheduler/NullScheduler.php @@ -9,7 +9,5 @@ final class NullScheduler implements Scheduler { - public function run(?DateTime $date = null): void - { - } + public function run(?DateTime $date = null): void {} } diff --git a/packages/console/src/Testing/ConsoleTester.php b/packages/console/src/Testing/ConsoleTester.php index 088f695c5c..a33541c9dd 100644 --- a/packages/console/src/Testing/ConsoleTester.php +++ b/packages/console/src/Testing/ConsoleTester.php @@ -68,7 +68,7 @@ public function call(string|Closure|array $command, string|array $arguments = [] $console->disablePrompting(); } - if ($this->componentRenderer !== null) { + if ($this->componentRenderer instanceof InteractiveComponentRenderer) { $console->setComponentRenderer($this->componentRenderer); } @@ -94,7 +94,7 @@ public function call(string|Closure|array $command, string|array $arguments = [] $fiber->start(); - if ($clone->componentRenderer !== null) { + if ($clone->componentRenderer instanceof InteractiveComponentRenderer) { $clone->input("\e[1;1R"); // Set cursor for interactive testing } @@ -162,7 +162,7 @@ public function printFormatted(): self public function getBuffer(?callable $callback = null): array { - $buffer = array_map('trim', $this->output->getBufferWithoutFormatting()); + $buffer = array_map(trim(...), $this->output->getBufferWithoutFormatting()); $this->output->clear(); diff --git a/packages/console/tests/CompletionHelperPhpTest.php b/packages/console/tests/CompletionHelperPhpTest.php index 4940f60954..518a4340d3 100644 --- a/packages/console/tests/CompletionHelperPhpTest.php +++ b/packages/console/tests/CompletionHelperPhpTest.php @@ -16,7 +16,9 @@ final class CompletionHelperPhpTest extends TestCase { private CompletionEngine $engine; + private CompletionInputNormalizer $inputNormalizer; + private CompletionMetadataParser $metadataParser; protected function setUp(): void diff --git a/packages/console/tests/OptionCollectionTest.php b/packages/console/tests/OptionCollectionTest.php index 2a4f86da82..81ab5effb1 100644 --- a/packages/console/tests/OptionCollectionTest.php +++ b/packages/console/tests/OptionCollectionTest.php @@ -31,7 +31,7 @@ public function test_filter(): void $options->filter('ergljherkigjerg'); $this->assertCount(0, $options->getOptions()); - $this->assertSame(null, $options->getActive()); + $this->assertNull($options->getActive()); } public function test_keeps_active_on_filter(): void @@ -50,7 +50,7 @@ public function test_keeps_active_on_filter(): void $this->assertSame('baz', $options->getActive()->value); $options->filter('bazz'); - $this->assertSame(null, $options->getActive()); + $this->assertNull($options->getActive()); } public function test_navigate(): void diff --git a/packages/console/tests/TextBufferTest.php b/packages/console/tests/TextBufferTest.php index af26f5b62d..76b6a5267d 100644 --- a/packages/console/tests/TextBufferTest.php +++ b/packages/console/tests/TextBufferTest.php @@ -137,10 +137,10 @@ public function test_move_cursor_to_start(): void $this->assertSame(0, $buffer->cursor); $buffer = new TextBuffer(<<moveCursorX(100); $buffer->moveCursorToStart(); $this->assertSame(0, $buffer->cursor); @@ -155,10 +155,10 @@ public function test_move_cursor_to_end(): void $this->assertSame(13, $buffer->cursor); $buffer = new TextBuffer(<<setCursorIndex(0); $buffer->moveCursorToEnd(); $this->assertSame(48, $buffer->cursor); @@ -185,10 +185,10 @@ public function test_move_cursor_to_start_of_line(): void public function test_move_cursor_to_start_of_line_multiline(int $initial, int $expected): void { $buffer = new TextBuffer(<<setCursorIndex($initial); $buffer->moveCursorToStartOfLine(); @@ -217,10 +217,10 @@ public function test_move_cursor_to_end_of_line(): void public function test_move_cursor_to_end_of_line_multiline(int $initial, int $expected): void { $buffer = new TextBuffer(<<setCursorIndex($initial); $buffer->moveCursorToEndOfLine(); @@ -258,10 +258,10 @@ public function test_move_cursor_x(int $initialCursor, int $offsetX, int $expect public function move_cursor_y(int $initialCursor, int $offsetY, int $expectedPosition): void { $buffer = new TextBuffer(<<setCursorIndex($initialCursor); $buffer->moveCursorY($offsetY); diff --git a/packages/container/src/Autowire.php b/packages/container/src/Autowire.php index 8297e2d2ef..adc5f433e8 100644 --- a/packages/container/src/Autowire.php +++ b/packages/container/src/Autowire.php @@ -7,6 +7,4 @@ use Attribute; #[Attribute(Attribute::TARGET_CLASS)] -final class Autowire -{ -} +final class Autowire {} diff --git a/packages/container/src/Commands/ContainerShowCommand.php b/packages/container/src/Commands/ContainerShowCommand.php index 0542e21c59..5c2cd62d3c 100644 --- a/packages/container/src/Commands/ContainerShowCommand.php +++ b/packages/container/src/Commands/ContainerShowCommand.php @@ -18,7 +18,7 @@ use function Tempest\Support\Str\before_last; use function Tempest\Support\Str\contains; -if (class_exists(\Tempest\Console\ConsoleCommand::class)) { +if (class_exists(ConsoleCommand::class)) { final readonly class ContainerShowCommand { public function __construct( @@ -68,12 +68,12 @@ public function __invoke(): ExitCode private function listBindings(string $title, array $bindings, ?Closure $formatKey = null, ?Closure $formatValue = null, ?Closure $reject = null): void { - if (! $bindings) { + if ($bindings === []) { return; } $reject ??= static fn (): bool => false; - $formatKey ??= fn (int|string $key): string => $this->formatClassKey($key); + $formatKey ??= $this->formatClassKey(...); $formatValue ??= fn (int|string $key, mixed $value): string => $this->formatClassValue($value, $key); $this->console->header($title); diff --git a/packages/container/src/Commands/MakeInitializerCommand.php b/packages/container/src/Commands/MakeInitializerCommand.php index dff9019d0f..bc86fd0d70 100644 --- a/packages/container/src/Commands/MakeInitializerCommand.php +++ b/packages/container/src/Commands/MakeInitializerCommand.php @@ -13,7 +13,7 @@ use Tempest\Generation\Php\ClassManipulator; use Tempest\Generation\Php\DataObjects\StubFile; -if (class_exists(\Tempest\Console\ConsoleCommand::class)) { +if (class_exists(ConsoleCommand::class)) { final class MakeInitializerCommand { use PublishesFiles; diff --git a/packages/container/src/Dependency.php b/packages/container/src/Dependency.php index 39b9a6aed8..149d60f3d0 100644 --- a/packages/container/src/Dependency.php +++ b/packages/container/src/Dependency.php @@ -40,7 +40,7 @@ public function getTypeName(): string if (is_string($dependency)) { $parts = explode('\\', $dependency); - return $parts[array_key_last($parts)]; + return array_last($parts); } return match ($dependency::class) { diff --git a/packages/container/src/DependencyChain.php b/packages/container/src/DependencyChain.php index 41af43699d..210cfb4c4e 100644 --- a/packages/container/src/DependencyChain.php +++ b/packages/container/src/DependencyChain.php @@ -34,12 +34,12 @@ public function add(Reflector|Closure|string $dependency): self public function first(): Dependency { - return $this->dependencies[array_key_first($this->dependencies)]; + return array_first($this->dependencies); } public function last(): Dependency { - return $this->dependencies[array_key_last($this->dependencies)]; + return array_last($this->dependencies); } /** @return \Tempest\Container\Dependency[] */ diff --git a/packages/container/src/Exceptions/CircularDependencyEncountered.php b/packages/container/src/Exceptions/CircularDependencyEncountered.php index d4ed8de8b1..36c75e5dc5 100644 --- a/packages/container/src/Exceptions/CircularDependencyEncountered.php +++ b/packages/container/src/Exceptions/CircularDependencyEncountered.php @@ -35,9 +35,7 @@ public function __construct(DependencyChain $chain, Dependency $circularDependen $selectionLine = preg_replace_callback( pattern: '/(?(.*))(?' . $circularDependency->getTypeName() . '\s\$\w+)(.*)/', - callback: function ($matches) { - return '└' . str_repeat('─', strlen($matches['prefix']) + 3) . str_repeat('▒', strlen($matches['selection'])); - }, + callback: fn ($matches) => '└' . str_repeat('─', strlen($matches['prefix']) + 3) . str_repeat('▒', strlen($matches['selection'])), subject: $chain->last()->getShortName(), ); diff --git a/packages/container/src/Exceptions/ContainerException.php b/packages/container/src/Exceptions/ContainerException.php index 02809f491a..aac08af639 100644 --- a/packages/container/src/Exceptions/ContainerException.php +++ b/packages/container/src/Exceptions/ContainerException.php @@ -4,6 +4,4 @@ namespace Tempest\Container\Exceptions; -interface ContainerException -{ -} +interface ContainerException {} diff --git a/packages/container/src/Exceptions/DependencyCouldNotBeAutowired.php b/packages/container/src/Exceptions/DependencyCouldNotBeAutowired.php index 8a6e33be77..da50c70203 100644 --- a/packages/container/src/Exceptions/DependencyCouldNotBeAutowired.php +++ b/packages/container/src/Exceptions/DependencyCouldNotBeAutowired.php @@ -34,9 +34,7 @@ public function __construct(DependencyChain $chain, Dependency $brokenDependency $selectionLine = preg_replace_callback( pattern: '/(?(.*))(?' . $brokenDependency->getTypeName() . '\s\$\w+)(.*)/', - callback: function ($matches) { - return str_repeat(' ', strlen($matches['prefix']) + 4) . str_repeat('▒', strlen($matches['selection'])); - }, + callback: fn ($matches) => str_repeat(' ', strlen($matches['prefix']) + 4) . str_repeat('▒', strlen($matches['selection'])), subject: $chain->last()->getShortName(), ); diff --git a/packages/container/src/Exceptions/TaggedDependencyCouldNotBeResolved.php b/packages/container/src/Exceptions/TaggedDependencyCouldNotBeResolved.php index f9541f8502..62a6b336ca 100644 --- a/packages/container/src/Exceptions/TaggedDependencyCouldNotBeResolved.php +++ b/packages/container/src/Exceptions/TaggedDependencyCouldNotBeResolved.php @@ -47,9 +47,7 @@ public function __construct(DependencyChain $chain, Dependency $brokenDependency $selectionLine = preg_replace_callback( pattern: '/(?(.*))(?' . $brokenDependency->getTypeName() . '\s\$\w+)(.*)/', - callback: function ($matches) { - return str_repeat(' ', strlen($matches['prefix']) + 4) . str_repeat('▒', strlen($matches['selection'])); - }, + callback: fn ($matches) => str_repeat(' ', strlen($matches['prefix']) + 4) . str_repeat('▒', strlen($matches['selection'])), subject: $chain->last()->getShortName(), ); diff --git a/packages/container/src/GenericContainer.php b/packages/container/src/GenericContainer.php index 2483f0640b..b69d44ca87 100644 --- a/packages/container/src/GenericContainer.php +++ b/packages/container/src/GenericContainer.php @@ -326,7 +326,7 @@ private function resolve(string $className, null|string|UnitEnum $tag = null, mi $instance = $this->resolveDependency($className, $tag, ...$params); if ($this->decorators[$className] ?? null) { - $instance = $this->resolveDecorator($className, $instance, $tag, ...$params); + return $this->resolveDecorator($className, $instance, $tag, ...$params); } return $instance; @@ -378,7 +378,7 @@ private function resolveDependency(string $className, null|string|UnitEnum $tag } // If we're requesting a tagged dependency and haven't resolved it at this point, something's wrong - if ($tag) { + if ($tag !== null) { throw new TaggedDependencyCouldNotBeResolved($this->chain, new Dependency($className), $tag); } @@ -433,15 +433,15 @@ private function autowire(string $className, mixed ...$params): object throw new DependencyCouldNotBeInstantiated($classReflector, $this->chain); } - $instance = $constructor === null + $instance = $constructor instanceof MethodReflector // trying to build it. // If there isn't a constructor, don't waste time - ? $classReflector->newInstanceWithoutConstructor() + ? $classReflector->newInstanceArgs( + $this->autowireDependencies($constructor, $params), + ) // build up each parameter. // Otherwise, use our autowireDependencies helper to automagically - : $classReflector->newInstanceArgs( - $this->autowireDependencies($constructor, $params), - ); + : $classReflector->newInstanceWithoutConstructor(); if ( ! $classReflector->getType()->matches(Initializer::class) @@ -546,9 +546,7 @@ private function autowireObjectDependency(TypeReflector $type, null|string|UnitE return $type ->asClass() ->getReflection() - ->newLazyProxy(function () use ($type, $tag) { - return $this->resolve(className: $type->getName(), tag: $tag); - }); + ->newLazyProxy(fn () => $this->resolve(className: $type->getName(), tag: $tag)); } // If we can successfully retrieve an instance @@ -612,7 +610,7 @@ private function clone(): self private function resolveChain(): DependencyChain { - if ($this->chain === null) { + if (! $this->chain instanceof DependencyChain) { $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); $this->chain = new DependencyChain($trace[1]['file'] . ':' . $trace[1]['line']); diff --git a/packages/container/src/HasTag.php b/packages/container/src/HasTag.php index 0aa252f6ac..535bccf5a6 100644 --- a/packages/container/src/HasTag.php +++ b/packages/container/src/HasTag.php @@ -6,7 +6,5 @@ interface HasTag { - public null|string|UnitEnum $tag { - get; - } + public null|string|UnitEnum $tag { get; } } diff --git a/packages/container/src/Proxy.php b/packages/container/src/Proxy.php index 10cfee4290..7fa29f7c68 100644 --- a/packages/container/src/Proxy.php +++ b/packages/container/src/Proxy.php @@ -12,6 +12,4 @@ * The container may then decide to do lazy initialization */ #[Attribute(Attribute::TARGET_PROPERTY | Attribute::TARGET_PARAMETER)] -final readonly class Proxy -{ -} +final readonly class Proxy {} diff --git a/packages/container/src/functions.php b/packages/container/src/functions.php index 32eee772ba..a58062e56e 100644 --- a/packages/container/src/functions.php +++ b/packages/container/src/functions.php @@ -4,7 +4,6 @@ namespace Tempest\Container; -use Tempest\Container\GenericContainer; use Tempest\Reflection\FunctionReflector; use Tempest\Reflection\MethodReflector; diff --git a/packages/container/tests/ContainerTest.php b/packages/container/tests/ContainerTest.php index effa97435e..1431f0f2a7 100644 --- a/packages/container/tests/ContainerTest.php +++ b/packages/container/tests/ContainerTest.php @@ -325,9 +325,9 @@ public function test_autowired_tagged_dependency_exception(): void } catch (TaggedDependencyCouldNotBeResolved $cannotResolveTaggedDependency) { $this->assertStringContainsStringIgnoringLineEndings( <<<'TXT' - ┌── DependencyWithTaggedDependency::__construct(TaggedDependency $dependency) - └── Tempest\Container\Tests\Fixtures\TaggedDependency - TXT, + ┌── DependencyWithTaggedDependency::__construct(TaggedDependency $dependency) + └── Tempest\Container\Tests\Fixtures\TaggedDependency + TXT, $cannotResolveTaggedDependency->getMessage(), ); } diff --git a/packages/container/tests/Exceptions/CannotAutowireExceptionTest.php b/packages/container/tests/Exceptions/CannotAutowireExceptionTest.php index 58e8f2cb06..349fd2dd3a 100644 --- a/packages/container/tests/Exceptions/CannotAutowireExceptionTest.php +++ b/packages/container/tests/Exceptions/CannotAutowireExceptionTest.php @@ -26,11 +26,11 @@ public function test_autowire_without_exception(): void $this->assertStringContainsString('Cannot autowire ' . AutowireA::class . '::__construct because string cannot be resolved', $cannotAutowireException->getMessage()); $expected = <<<'TXT' - ┌── AutowireA::__construct(AutowireB $b) - ├── AutowireB::__construct(AutowireC $c) - └── AutowireC::__construct(ContainerObjectA $other, string $unknown) - ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ - TXT; + ┌── AutowireA::__construct(AutowireB $b) + ├── AutowireB::__construct(AutowireC $c) + └── AutowireC::__construct(ContainerObjectA $other, string $unknown) + ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ + TXT; $this->assertStringContainsStringIgnoringLineEndings($expected, $cannotAutowireException->getMessage()); $this->assertStringContainsString('CannotAutowireExceptionTest.php:24', $cannotAutowireException->getMessage()); diff --git a/packages/container/tests/Exceptions/CircularDependencyExceptionTest.php b/packages/container/tests/Exceptions/CircularDependencyExceptionTest.php index 6ec8887d5b..147f28acc8 100644 --- a/packages/container/tests/Exceptions/CircularDependencyExceptionTest.php +++ b/packages/container/tests/Exceptions/CircularDependencyExceptionTest.php @@ -30,11 +30,11 @@ public function test_circular_dependency_test(): void ); $expected = <<<'TXT' - ┌─► CircularA::__construct(ContainerObjectA $other, CircularB $b) - │ CircularB::__construct(CircularC $c) - │ CircularC::__construct(ContainerObjectA $other, CircularA $a) - └───────────────────────────────────────────────────▒▒▒▒▒▒▒▒▒▒▒▒ - TXT; + ┌─► CircularA::__construct(ContainerObjectA $other, CircularB $b) + │ CircularB::__construct(CircularC $c) + │ CircularC::__construct(ContainerObjectA $other, CircularA $a) + └───────────────────────────────────────────────────▒▒▒▒▒▒▒▒▒▒▒▒ + TXT; $this->assertStringContainsStringIgnoringLineEndings($expected, $circularDependencyException->getMessage()); @@ -59,12 +59,12 @@ public function test_circular_dependency_as_a_child_test(): void ); $expected = <<<'TXT' - CircularZ::__construct(CircularA $a) - ┌─► CircularA::__construct(ContainerObjectA $other, CircularB $b) - │ CircularB::__construct(CircularC $c) - │ CircularC::__construct(ContainerObjectA $other, CircularA $a) - └───────────────────────────────────────────────────▒▒▒▒▒▒▒▒▒▒▒▒ - TXT; + CircularZ::__construct(CircularA $a) + ┌─► CircularA::__construct(ContainerObjectA $other, CircularB $b) + │ CircularB::__construct(CircularC $c) + │ CircularC::__construct(ContainerObjectA $other, CircularA $a) + └───────────────────────────────────────────────────▒▒▒▒▒▒▒▒▒▒▒▒ + TXT; $this->assertStringContainsStringIgnoringLineEndings($expected, $circularDependencyException->getMessage()); diff --git a/packages/container/tests/Fixtures/ContainerObjectA.php b/packages/container/tests/Fixtures/ContainerObjectA.php index aceae4de09..8f616a804f 100644 --- a/packages/container/tests/Fixtures/ContainerObjectA.php +++ b/packages/container/tests/Fixtures/ContainerObjectA.php @@ -4,6 +4,4 @@ namespace Tempest\Container\Tests\Fixtures; -final class ContainerObjectA -{ -} +final class ContainerObjectA {} diff --git a/packages/container/tests/Fixtures/DecoratedClass.php b/packages/container/tests/Fixtures/DecoratedClass.php index da11df34ad..5e1cee0225 100644 --- a/packages/container/tests/Fixtures/DecoratedClass.php +++ b/packages/container/tests/Fixtures/DecoratedClass.php @@ -4,6 +4,4 @@ namespace Tempest\Container\Tests\Fixtures; -final class DecoratedClass implements DecoratedInterface -{ -} +final class DecoratedClass implements DecoratedInterface {} diff --git a/packages/container/tests/Fixtures/DecoratedInterface.php b/packages/container/tests/Fixtures/DecoratedInterface.php index ddae1db5aa..1a9d08396e 100644 --- a/packages/container/tests/Fixtures/DecoratedInterface.php +++ b/packages/container/tests/Fixtures/DecoratedInterface.php @@ -4,6 +4,4 @@ namespace Tempest\Container\Tests\Fixtures; -interface DecoratedInterface -{ -} +interface DecoratedInterface {} diff --git a/packages/container/tests/Fixtures/DecoratorWithoutConstructor.php b/packages/container/tests/Fixtures/DecoratorWithoutConstructor.php index 6adabcc371..de30c8b5e5 100644 --- a/packages/container/tests/Fixtures/DecoratorWithoutConstructor.php +++ b/packages/container/tests/Fixtures/DecoratorWithoutConstructor.php @@ -7,6 +7,4 @@ use Tempest\Container\Decorates; #[Decorates(DecoratedInterface::class)] -final class DecoratorWithoutConstructor implements DecoratedInterface -{ -} +final class DecoratorWithoutConstructor implements DecoratedInterface {} diff --git a/packages/container/tests/Fixtures/ImplementsInterfaceA.php b/packages/container/tests/Fixtures/ImplementsInterfaceA.php index 81404be605..9b14c30f78 100644 --- a/packages/container/tests/Fixtures/ImplementsInterfaceA.php +++ b/packages/container/tests/Fixtures/ImplementsInterfaceA.php @@ -6,7 +6,5 @@ final class ImplementsInterfaceA implements InterfaceA { - public function __invoke(): void - { - } + public function __invoke(): void {} } diff --git a/packages/container/tests/Fixtures/InjectB.php b/packages/container/tests/Fixtures/InjectB.php index 81e0ddc788..f7564219bf 100644 --- a/packages/container/tests/Fixtures/InjectB.php +++ b/packages/container/tests/Fixtures/InjectB.php @@ -4,6 +4,4 @@ namespace Tempest\Container\Tests\Fixtures; -final readonly class InjectB -{ -} +final readonly class InjectB {} diff --git a/packages/container/tests/Fixtures/InterfaceA.php b/packages/container/tests/Fixtures/InterfaceA.php index 81206885f9..86e374a176 100644 --- a/packages/container/tests/Fixtures/InterfaceA.php +++ b/packages/container/tests/Fixtures/InterfaceA.php @@ -4,6 +4,4 @@ namespace Tempest\Container\Tests\Fixtures; -interface InterfaceA -{ -} +interface InterfaceA {} diff --git a/packages/container/tests/Fixtures/SlowDependency.php b/packages/container/tests/Fixtures/SlowDependency.php index 087c275025..868ab27002 100644 --- a/packages/container/tests/Fixtures/SlowDependency.php +++ b/packages/container/tests/Fixtures/SlowDependency.php @@ -12,7 +12,7 @@ public function __construct(float $delay = 0.1, int $counter = 0) // usleep apparently is buggy on windows... $start = microtime(true); while ((microtime(true) - $start) < $delay) { - usleep(intval($delay * 1000000)); + usleep(intval($delay * 1_000_000)); } $this->value = 'value' . $counter; diff --git a/packages/container/tests/Fixtures/UnionImplementation.php b/packages/container/tests/Fixtures/UnionImplementation.php index ce931a18b7..e663b1906d 100644 --- a/packages/container/tests/Fixtures/UnionImplementation.php +++ b/packages/container/tests/Fixtures/UnionImplementation.php @@ -4,6 +4,4 @@ namespace Tempest\Container\Tests\Fixtures; -final readonly class UnionImplementation implements UnionInterfaceA, UnionInterfaceB -{ -} +final readonly class UnionImplementation implements UnionInterfaceA, UnionInterfaceB {} diff --git a/packages/container/tests/Fixtures/UnionInterfaceA.php b/packages/container/tests/Fixtures/UnionInterfaceA.php index 6574213e88..e645839890 100644 --- a/packages/container/tests/Fixtures/UnionInterfaceA.php +++ b/packages/container/tests/Fixtures/UnionInterfaceA.php @@ -4,6 +4,4 @@ namespace Tempest\Container\Tests\Fixtures; -interface UnionInterfaceA -{ -} +interface UnionInterfaceA {} diff --git a/packages/container/tests/Fixtures/UnionInterfaceB.php b/packages/container/tests/Fixtures/UnionInterfaceB.php index 0619139347..1cb98985bf 100644 --- a/packages/container/tests/Fixtures/UnionInterfaceB.php +++ b/packages/container/tests/Fixtures/UnionInterfaceB.php @@ -4,6 +4,4 @@ namespace Tempest\Container\Tests\Fixtures; -interface UnionInterfaceB -{ -} +interface UnionInterfaceB {} diff --git a/packages/core/src/Commands/DiscoveryClearCommand.php b/packages/core/src/Commands/DiscoveryClearCommand.php index b31776e113..5bcba5189b 100644 --- a/packages/core/src/Commands/DiscoveryClearCommand.php +++ b/packages/core/src/Commands/DiscoveryClearCommand.php @@ -8,7 +8,7 @@ use Tempest\Console\ConsoleCommand; use Tempest\Core\DiscoveryCache; -if (class_exists(\Tempest\Console\ConsoleCommand::class)) { +if (class_exists(ConsoleCommand::class)) { final readonly class DiscoveryClearCommand { public function __construct( diff --git a/packages/core/src/Commands/DiscoveryGenerateCommand.php b/packages/core/src/Commands/DiscoveryGenerateCommand.php index ca286ddfa6..a3dafeff04 100644 --- a/packages/core/src/Commands/DiscoveryGenerateCommand.php +++ b/packages/core/src/Commands/DiscoveryGenerateCommand.php @@ -16,7 +16,7 @@ use Tempest\Core\Kernel; use Tempest\Core\Kernel\LoadDiscoveryClasses; -if (class_exists(\Tempest\Console\ConsoleCommand::class)) { +if (class_exists(ConsoleCommand::class)) { final readonly class DiscoveryGenerateCommand { use HasConsole; diff --git a/packages/core/src/Commands/DiscoveryStatusCommand.php b/packages/core/src/Commands/DiscoveryStatusCommand.php index 1f037ff114..91f3c9cfb8 100644 --- a/packages/core/src/Commands/DiscoveryStatusCommand.php +++ b/packages/core/src/Commands/DiscoveryStatusCommand.php @@ -15,7 +15,7 @@ use function Tempest\root_path; use function Tempest\Support\str; -if (class_exists(\Tempest\Console\ConsoleCommand::class)) { +if (class_exists(ConsoleCommand::class)) { final readonly class DiscoveryStatusCommand { public function __construct( diff --git a/packages/core/src/Commands/InstallCommand.php b/packages/core/src/Commands/InstallCommand.php index 1b49eea046..1d3a197380 100644 --- a/packages/core/src/Commands/InstallCommand.php +++ b/packages/core/src/Commands/InstallCommand.php @@ -14,7 +14,7 @@ use function Tempest\Support\arr; -if (class_exists(\Tempest\Console\ConsoleCommand::class)) { +if (class_exists(ConsoleCommand::class)) { final readonly class InstallCommand { use HasConsole; @@ -35,7 +35,7 @@ public function __invoke(?string $installer = null, bool $_tailwind = false): vo { $installer = $this->resolveInstaller($installer); - if ($installer === null) { + if (! $installer instanceof Installer) { $this->error('Installer not found'); return; diff --git a/packages/core/src/Composer.php b/packages/core/src/Composer.php index e3c6917b9a..c74ea335eb 100644 --- a/packages/core/src/Composer.php +++ b/packages/core/src/Composer.php @@ -44,11 +44,13 @@ public function load(): self ->toArray(); foreach ($this->namespaces as $namespace) { - if (Str\starts_with(Str\ensure_ends_with($namespace->path, '/'), ['app/', 'src/', 'source/', 'lib/'])) { - $this->mainNamespace = $namespace; - - break; + if (! Str\starts_with(Str\ensure_ends_with($namespace->path, '/'), ['app/', 'src/', 'source/', 'lib/'])) { + continue; } + + $this->mainNamespace = $namespace; + + break; } if (! isset($this->mainNamespace) && count($this->namespaces)) { @@ -112,7 +114,7 @@ public function save(): self public function executeUpdate(): self { - if ($this->executor) { + if ($this->executor instanceof ProcessExecutor) { $this->executor->run('composer up'); } else { exec('composer update'); diff --git a/packages/core/src/ComposerJsonCouldNotBeLocated.php b/packages/core/src/ComposerJsonCouldNotBeLocated.php index 10bf4b2c7d..4c3bcd1dcf 100644 --- a/packages/core/src/ComposerJsonCouldNotBeLocated.php +++ b/packages/core/src/ComposerJsonCouldNotBeLocated.php @@ -6,6 +6,4 @@ use Exception; -final class ComposerJsonCouldNotBeLocated extends Exception -{ -} +final class ComposerJsonCouldNotBeLocated extends Exception {} diff --git a/packages/core/src/ConfigCache.php b/packages/core/src/ConfigCache.php index 5a156b5cec..bc3a5c491d 100644 --- a/packages/core/src/ConfigCache.php +++ b/packages/core/src/ConfigCache.php @@ -38,7 +38,7 @@ public function put(string $key, mixed $value, null|Duration|DateTimeInterface $ $expiresAt = DateTime::now()->plus($expiresAt); } - if ($expiresAt !== null) { + if ($expiresAt instanceof DateTimeInterface) { $item = $item->expiresAt($expiresAt->toNativeDateTime()); } diff --git a/packages/core/src/CouldNotStoreDiscoveryCache.php b/packages/core/src/CouldNotStoreDiscoveryCache.php index 0fdd882457..1733e51e70 100644 --- a/packages/core/src/CouldNotStoreDiscoveryCache.php +++ b/packages/core/src/CouldNotStoreDiscoveryCache.php @@ -10,7 +10,7 @@ final class CouldNotStoreDiscoveryCache extends Exception public function __construct(DiscoveryLocation $location) { parent::__construct(sprintf( - 'Could not store discovery cache for %s. This is likely because you\'re trying to store unserializable data like reflection classes or closures in discovery items.', + "Could not store discovery cache for %s. This is likely because you're trying to store unserializable data like reflection classes or closures in discovery items.", $location->path, )); } diff --git a/packages/core/src/DiscoveryCacheInitializer.php b/packages/core/src/DiscoveryCacheInitializer.php index 0370519a66..378cb3743b 100644 --- a/packages/core/src/DiscoveryCacheInitializer.php +++ b/packages/core/src/DiscoveryCacheInitializer.php @@ -51,7 +51,7 @@ private function isDiscoveryGenerateCommand(): bool $command = $_SERVER['argv'][1] ?? null; - return $command === 'dg' || $command === 'discovery:generate' || $command === 'd:g'; + return in_array($command, ['dg', 'discovery:generate', 'd:g'], true); } private function isDiscoveryClearCommand(): bool @@ -62,6 +62,6 @@ private function isDiscoveryClearCommand(): bool $command = $_SERVER['argv'][1] ?? null; - return $command === 'dc' || $command === 'discovery:clear' || $command === 'd:c'; + return in_array($command, ['dc', 'discovery:clear', 'd:c'], true); } } diff --git a/packages/core/src/Exceptions/ExceptionTester.php b/packages/core/src/Exceptions/ExceptionTester.php index 0290234cdd..a8e72ad894 100644 --- a/packages/core/src/Exceptions/ExceptionTester.php +++ b/packages/core/src/Exceptions/ExceptionTester.php @@ -50,7 +50,7 @@ public function assertProcessed(string|object $exception, ?Closure $callback = n Assert::assertCount($count, $reports, sprintf('Expected %s report(s), got %s.', $count, count($reports))); } - if ($callback !== null) { + if ($callback instanceof Closure) { foreach ($reports as $dispatch) { Assert::assertNotFalse($callback($dispatch), 'The callback failed.'); } @@ -92,11 +92,7 @@ private function findRecordedProcessings(string|object $exception): array return true; } - if (class_exists($exception) && is_a($reported, $exception, allow_string: true)) { - return true; - } - - return false; + return class_exists($exception) && is_a($reported, $exception, allow_string: true); }); } diff --git a/packages/core/src/Exceptions/GenericExceptionProcessor.php b/packages/core/src/Exceptions/GenericExceptionProcessor.php index fa9e723349..b6d02f9b94 100644 --- a/packages/core/src/Exceptions/GenericExceptionProcessor.php +++ b/packages/core/src/Exceptions/GenericExceptionProcessor.php @@ -8,11 +8,11 @@ /** * Reports exceptions to registered exception processors. */ -final class GenericExceptionProcessor implements ExceptionProcessor +final readonly class GenericExceptionProcessor implements ExceptionProcessor { public function __construct( - private readonly ExceptionsConfig $config, - private readonly Container $container, + private ExceptionsConfig $config, + private Container $container, ) {} public function process(Throwable $throwable): void diff --git a/packages/core/src/Exceptions/LoggingExceptionReporter.php b/packages/core/src/Exceptions/LoggingExceptionReporter.php index 8454a4b471..bb56479bb8 100644 --- a/packages/core/src/Exceptions/LoggingExceptionReporter.php +++ b/packages/core/src/Exceptions/LoggingExceptionReporter.php @@ -9,10 +9,10 @@ /** * An exception reporter that write exceptions through the {@see Logger}. */ -final class LoggingExceptionReporter implements ExceptionReporter +final readonly class LoggingExceptionReporter implements ExceptionReporter { public function __construct( - private readonly Logger $logger, + private Logger $logger, ) {} public function report(Throwable $throwable): void diff --git a/packages/core/src/FrameworkKernel.php b/packages/core/src/FrameworkKernel.php index 9fb47ddfeb..42969f3ea7 100644 --- a/packages/core/src/FrameworkKernel.php +++ b/packages/core/src/FrameworkKernel.php @@ -183,7 +183,7 @@ public function loadConfig(): self public function registerInternalStorage(): self { - $path = isset($this->internalStorage) ? $this->internalStorage : $this->root . '/.tempest'; + $path = $this->internalStorage ?? $this->root . '/.tempest'; if (! is_dir($path)) { if (file_exists($path)) { diff --git a/packages/core/src/InsightsProvider.php b/packages/core/src/InsightsProvider.php index c361318ed5..2c9fbed894 100644 --- a/packages/core/src/InsightsProvider.php +++ b/packages/core/src/InsightsProvider.php @@ -10,9 +10,7 @@ interface InsightsProvider /** * Display name of this provider. */ - public string $name { - get; - } + public string $name { get; } /** * Gets insights in the form of key/value pairs. diff --git a/packages/core/src/InsightsProviderDiscovery.php b/packages/core/src/InsightsProviderDiscovery.php index f456bf22bc..bad0006518 100644 --- a/packages/core/src/InsightsProviderDiscovery.php +++ b/packages/core/src/InsightsProviderDiscovery.php @@ -4,7 +4,6 @@ namespace Tempest\Core; -use Tempest\Core\AppConfig; use Tempest\Discovery\Discovery; use Tempest\Discovery\DiscoveryLocation; use Tempest\Discovery\IsDiscovery; diff --git a/packages/core/src/Installer.php b/packages/core/src/Installer.php index 9f8cb3cf06..cb9698b2a7 100644 --- a/packages/core/src/Installer.php +++ b/packages/core/src/Installer.php @@ -6,9 +6,7 @@ interface Installer { - public string $name { - get; - } + public string $name { get; } public function install(): void; } diff --git a/packages/core/src/Kernel.php b/packages/core/src/Kernel.php index 65f45fb96d..7a8b97cf9d 100644 --- a/packages/core/src/Kernel.php +++ b/packages/core/src/Kernel.php @@ -10,27 +10,15 @@ interface Kernel { public const string VERSION = '3.3.1'; - public string $root { - get; - } - - public string $internalStorage { - get; - } - - public array $discoveryLocations { - get; - set; - } - - public array $discoveryClasses { - get; - set; - } - - public Container $container { - get; - } + public string $root { get; } + + public string $internalStorage { get; } + + public array $discoveryLocations { get; set; } + + public array $discoveryClasses { get; set; } + + public Container $container { get; } public static function boot( string $root, diff --git a/packages/core/src/Kernel/LoadConfig.php b/packages/core/src/Kernel/LoadConfig.php index 6c916f1664..1c22ee9d26 100644 --- a/packages/core/src/Kernel/LoadConfig.php +++ b/packages/core/src/Kernel/LoadConfig.php @@ -113,7 +113,11 @@ private function scan(string $path, MutableArray $configPaths): void foreach ($subPaths as $subPath) { // `.` and `..` are skipped - if ($subPath === '.' || $subPath === '..') { + if ($subPath === '.') { + continue; + } + + if ($subPath === '..') { continue; } diff --git a/packages/core/src/Kernel/LoadDiscoveryClasses.php b/packages/core/src/Kernel/LoadDiscoveryClasses.php index f6ae0b8cf6..289531902e 100644 --- a/packages/core/src/Kernel/LoadDiscoveryClasses.php +++ b/packages/core/src/Kernel/LoadDiscoveryClasses.php @@ -24,6 +24,7 @@ final class LoadDiscoveryClasses { private array $appliedDiscovery = []; + private array $shouldSkipForClass = []; public function __construct( @@ -72,7 +73,7 @@ public function build( // Resolve all other discoveries from the container, optionally loading their cache $discoveries = array_map( - fn (string $discoveryClass) => $this->resolveDiscovery($discoveryClass), + $this->resolveDiscovery(...), $kernel->discoveryClasses, ); @@ -80,17 +81,15 @@ public function build( $this->discover($discoveries, $discoveryLocations); return [$discoveryDiscovery, ...$discoveries]; - } else { - // Resolve all manually specified discoveries - $discoveries = array_map( - fn (string $discoveryClass) => $this->resolveDiscovery($discoveryClass), - $discoveryClasses, - ); - - $this->discover($discoveries, $discoveryLocations); - - return $discoveries; } + + // Resolve all manually specified discoveries + $discoveries = array_map( + $this->resolveDiscovery(...), + $discoveryClasses, + ); + $this->discover($discoveries, $discoveryLocations); + return $discoveries; } /** @@ -175,7 +174,11 @@ private function scan(DiscoveryLocation $location, array $discoveries, string $p foreach ($subPaths as $subPath) { // `.` and `..` are skipped - if ($subPath === '.' || $subPath === '..') { + if ($subPath === '.') { + continue; + } + + if ($subPath === '..') { continue; } @@ -256,9 +259,11 @@ private function discoverPath(string $input, DiscoveryLocation $location, array } foreach ($discoveries as $discovery) { - if ($discovery instanceof DiscoversPath) { - $discovery->discoverPath($location, $input); + if (! $discovery instanceof DiscoversPath) { + continue; } + + $discovery->discoverPath($location, $input); } } diff --git a/packages/core/src/PublishesFiles.php b/packages/core/src/PublishesFiles.php index 410d5d156b..09b1a1fd99 100644 --- a/packages/core/src/PublishesFiles.php +++ b/packages/core/src/PublishesFiles.php @@ -103,7 +103,7 @@ public function publish(string $source, string $destination, ?Closure $callback $this->publishedFiles[] = $destination; - if ($callback !== null) { + if ($callback instanceof Closure) { $callback($source, $destination); } @@ -115,10 +115,7 @@ public function publish(string $source, string $destination, ?Closure $callback throw $throwable; } - throw new FileGenerationFailedException( - message: 'The file could not be published.', - previous: $throwable, - ); + throw new FileGenerationFailedException(message: 'The file could not be published.', code: $throwable->getCode(), previous: $throwable); } } @@ -248,9 +245,11 @@ function (string $content) use ($callback) { // PHP will output empty arrays for empty dependencies, // which is invalid and will make package managers crash. foreach (['dependencies', 'devDependencies', 'peerDependencies'] as $key) { - if (isset($json[$key]) && ! $json[$key]) { - unset($json[$key]); + if (! (isset($json[$key]) && ! $json[$key])) { + continue; } + + unset($json[$key]); } $content = preg_replace_callback( diff --git a/packages/core/src/functions.php b/packages/core/src/functions.php index 3e93e0267e..4d64ccfd45 100644 --- a/packages/core/src/functions.php +++ b/packages/core/src/functions.php @@ -6,7 +6,6 @@ use Closure; use Stringable; -use Tempest\Container; use Tempest\Core\Composer; use Tempest\Core\DeferredTasks; use Tempest\Core\EnvironmentVariableValidationFailed; diff --git a/packages/cryptography/src/Encryption/Encrypter.php b/packages/cryptography/src/Encryption/Encrypter.php index 20f3087e55..f26d4703b0 100644 --- a/packages/cryptography/src/Encryption/Encrypter.php +++ b/packages/cryptography/src/Encryption/Encrypter.php @@ -2,16 +2,16 @@ namespace Tempest\Cryptography\Encryption; +use SensitiveParameter; + interface Encrypter { - public EncryptionAlgorithm $algorithm { - get; - } + public EncryptionAlgorithm $algorithm { get; } /** * Encrypts the specified data. */ - public function encrypt(#[\SensitiveParameter] string $data): EncryptedData; + public function encrypt(#[SensitiveParameter] string $data): EncryptedData; /** * Decrypts the specified data. diff --git a/packages/cryptography/src/Encryption/EncryptionConfig.php b/packages/cryptography/src/Encryption/EncryptionConfig.php index ffd2de0a23..1d70a404de 100644 --- a/packages/cryptography/src/Encryption/EncryptionConfig.php +++ b/packages/cryptography/src/Encryption/EncryptionConfig.php @@ -2,6 +2,8 @@ namespace Tempest\Cryptography\Encryption; +use SensitiveParameter; + final class EncryptionConfig { /** @@ -10,7 +12,7 @@ final class EncryptionConfig */ public function __construct( public EncryptionAlgorithm $algorithm, - #[\SensitiveParameter] + #[SensitiveParameter] public readonly ?string $key, ) {} } diff --git a/packages/cryptography/src/Encryption/Exceptions/EncryptionException.php b/packages/cryptography/src/Encryption/Exceptions/EncryptionException.php index b590b3c2b6..bc252de37e 100644 --- a/packages/cryptography/src/Encryption/Exceptions/EncryptionException.php +++ b/packages/cryptography/src/Encryption/Exceptions/EncryptionException.php @@ -2,6 +2,4 @@ namespace Tempest\Cryptography\Encryption\Exceptions; -interface EncryptionException -{ -} +interface EncryptionException {} diff --git a/packages/cryptography/src/Encryption/GenericEncrypter.php b/packages/cryptography/src/Encryption/GenericEncrypter.php index 1b2e68c980..c238921498 100644 --- a/packages/cryptography/src/Encryption/GenericEncrypter.php +++ b/packages/cryptography/src/Encryption/GenericEncrypter.php @@ -2,6 +2,7 @@ namespace Tempest\Cryptography\Encryption; +use SensitiveParameter; use Tempest\Cryptography\Encryption\Exceptions\AlgorithmMismatched; use Tempest\Cryptography\Encryption\Exceptions\DecryptionFailed; use Tempest\Cryptography\Encryption\Exceptions\EncryptionFailed; @@ -23,7 +24,7 @@ public function __construct( private readonly EncryptionConfig $config, ) {} - public function encrypt(#[\SensitiveParameter] string $data): EncryptedData + public function encrypt(#[SensitiveParameter] string $data): EncryptedData { $iv = random_bytes($this->algorithm->getIvLength()); $tag = ''; diff --git a/packages/cryptography/src/GenerateSigningKeyCommand.php b/packages/cryptography/src/GenerateSigningKeyCommand.php index f65b1da33c..e953230fdf 100644 --- a/packages/cryptography/src/GenerateSigningKeyCommand.php +++ b/packages/cryptography/src/GenerateSigningKeyCommand.php @@ -13,7 +13,7 @@ use function Tempest\root_path; -if (class_exists(\Tempest\Console\ConsoleCommand::class)) { +if (class_exists(ConsoleCommand::class)) { final readonly class GenerateSigningKeyCommand { public function __construct( diff --git a/packages/cryptography/src/Password/Exceptions/PasswordHashingException.php b/packages/cryptography/src/Password/Exceptions/PasswordHashingException.php index 7a993a6d0a..0bc2a05c6f 100644 --- a/packages/cryptography/src/Password/Exceptions/PasswordHashingException.php +++ b/packages/cryptography/src/Password/Exceptions/PasswordHashingException.php @@ -2,6 +2,4 @@ namespace Tempest\Cryptography\Password\Exceptions; -interface PasswordHashingException -{ -} +interface PasswordHashingException {} diff --git a/packages/cryptography/src/Password/GenericPasswordHasher.php b/packages/cryptography/src/Password/GenericPasswordHasher.php index 22c97ca609..ee7fd50eb0 100644 --- a/packages/cryptography/src/Password/GenericPasswordHasher.php +++ b/packages/cryptography/src/Password/GenericPasswordHasher.php @@ -3,6 +3,7 @@ namespace Tempest\Cryptography\Password; use Error; +use SensitiveParameter; use Tempest\Cryptography\Password\Exceptions\HashingFailed; use ValueError; @@ -16,7 +17,7 @@ public function __construct( private readonly PasswordHashingConfig $config, ) {} - public function hash(#[\SensitiveParameter] string $password): string + public function hash(#[SensitiveParameter] string $password): string { if ($password === '') { throw HashingFailed::forEmptyPassword(); @@ -33,7 +34,7 @@ public function hash(#[\SensitiveParameter] string $password): string return $hash; } - public function verify(#[\SensitiveParameter] string $password, #[\SensitiveParameter] string $hash): bool + public function verify(#[SensitiveParameter] string $password, #[SensitiveParameter] string $hash): bool { if ($password === '' || $hash === '') { return false; @@ -42,7 +43,7 @@ public function verify(#[\SensitiveParameter] string $password, #[\SensitivePara return password_verify($password, $hash); } - public function needsRehash(#[\SensitiveParameter] string $hash): bool + public function needsRehash(#[SensitiveParameter] string $hash): bool { if ($hash === '') { return false; @@ -51,7 +52,7 @@ public function needsRehash(#[\SensitiveParameter] string $hash): bool return password_needs_rehash($hash, $this->algorithm->value, $this->config->options); } - public function analyze(#[\SensitiveParameter] string $hash): ?Hash + public function analyze(#[SensitiveParameter] string $hash): ?Hash { if ($hash === '') { return null; diff --git a/packages/cryptography/src/Password/Hash.php b/packages/cryptography/src/Password/Hash.php index d1242fb7ee..6dd12ceddf 100644 --- a/packages/cryptography/src/Password/Hash.php +++ b/packages/cryptography/src/Password/Hash.php @@ -2,10 +2,12 @@ namespace Tempest\Cryptography\Password; +use SensitiveParameter; + final readonly class Hash { public function __construct( - #[\SensitiveParameter] + #[SensitiveParameter] public string $hash, public HashingAlgorithm $algorithm, public PasswordHashingConfig $config, diff --git a/packages/cryptography/src/Password/PasswordHasher.php b/packages/cryptography/src/Password/PasswordHasher.php index e2a2567656..46d224a9a3 100644 --- a/packages/cryptography/src/Password/PasswordHasher.php +++ b/packages/cryptography/src/Password/PasswordHasher.php @@ -2,30 +2,30 @@ namespace Tempest\Cryptography\Password; +use SensitiveParameter; + interface PasswordHasher { - public HashingAlgorithm $algorithm { - get; - } + public HashingAlgorithm $algorithm { get; } /** * Hashes the specified password. */ - public function hash(#[\SensitiveParameter] string $password): string; + public function hash(#[SensitiveParameter] string $password): string; /** * Checks if the given plain-text password matches the given hash. */ - public function verify(#[\SensitiveParameter] string $password, string $hash): bool; + public function verify(#[SensitiveParameter] string $password, string $hash): bool; /** * Checks if the given hash needs to be rehashed, which happens * when the initial hash was created with different algorithm options. */ - public function needsRehash(#[\SensitiveParameter] string $hash): bool; + public function needsRehash(#[SensitiveParameter] string $hash): bool; /** * Returns information about the given hash, such as the algorithm used and its options. */ - public function analyze(#[\SensitiveParameter] string $hash): ?Hash; + public function analyze(#[SensitiveParameter] string $hash): ?Hash; } diff --git a/packages/cryptography/src/Password/PasswordHashingConfig.php b/packages/cryptography/src/Password/PasswordHashingConfig.php index a561ed49b9..683dac6a49 100644 --- a/packages/cryptography/src/Password/PasswordHashingConfig.php +++ b/packages/cryptography/src/Password/PasswordHashingConfig.php @@ -4,14 +4,10 @@ interface PasswordHashingConfig { - public HashingAlgorithm $algorithm { - get; - } + public HashingAlgorithm $algorithm { get; } /** * Options for PHP's `password_hash` and `password_verify` functions. */ - public array $options { - get; - } + public array $options { get; } } diff --git a/packages/cryptography/src/Signing/Exceptions/SigningException.php b/packages/cryptography/src/Signing/Exceptions/SigningException.php index 48e42aab57..89dad5655f 100644 --- a/packages/cryptography/src/Signing/Exceptions/SigningException.php +++ b/packages/cryptography/src/Signing/Exceptions/SigningException.php @@ -2,6 +2,4 @@ namespace Tempest\Cryptography\Signing\Exceptions; -interface SigningException -{ -} +interface SigningException {} diff --git a/packages/cryptography/src/Signing/Signer.php b/packages/cryptography/src/Signing/Signer.php index 6d40b6108a..88002be90a 100644 --- a/packages/cryptography/src/Signing/Signer.php +++ b/packages/cryptography/src/Signing/Signer.php @@ -4,9 +4,7 @@ interface Signer { - public SigningAlgorithm $algorithm { - get; - } + public SigningAlgorithm $algorithm { get; } /** * Signs the given data. diff --git a/packages/cryptography/src/Signing/SigningConfig.php b/packages/cryptography/src/Signing/SigningConfig.php index d2d26a5bae..785fb7da67 100644 --- a/packages/cryptography/src/Signing/SigningConfig.php +++ b/packages/cryptography/src/Signing/SigningConfig.php @@ -2,6 +2,7 @@ namespace Tempest\Cryptography\Signing; +use SensitiveParameter; use Tempest\DateTime\Duration; final class SigningConfig @@ -13,7 +14,7 @@ final class SigningConfig */ public function __construct( public SigningAlgorithm $algorithm, - #[\SensitiveParameter] + #[SensitiveParameter] public readonly ?string $key, public false|Duration $minimumExecutionDuration, ) {} diff --git a/packages/cryptography/src/Timelock.php b/packages/cryptography/src/Timelock.php index 99408c40e6..30eb757860 100644 --- a/packages/cryptography/src/Timelock.php +++ b/packages/cryptography/src/Timelock.php @@ -4,6 +4,7 @@ use Tempest\Clock\Clock; use Tempest\DateTime\Duration; +use Throwable; final class Timelock { @@ -32,7 +33,7 @@ public function invoke(callable $callback, Duration $duration): mixed try { $result = $callback($this); - } catch (\Throwable $thrown) { + } catch (Throwable $thrown) { $exception = $thrown; } @@ -42,7 +43,7 @@ public function invoke(callable $callback, Duration $duration): mixed $this->clock->sleep(Duration::microseconds($remainderInMicroseconds)); } - if ($exception) { + if ($exception instanceof Throwable) { throw $exception; } diff --git a/packages/cryptography/tests/TimelockTest.php b/packages/cryptography/tests/TimelockTest.php index 08c073905a..ef68a2b994 100644 --- a/packages/cryptography/tests/TimelockTest.php +++ b/packages/cryptography/tests/TimelockTest.php @@ -3,6 +3,7 @@ namespace Tempest\Cryptography\Tests; use PHPUnit\Framework\TestCase; +use RuntimeException; use Tempest\Clock\GenericClock; use Tempest\Clock\MockClock; use Tempest\Cryptography\Timelock; @@ -57,10 +58,10 @@ public function test_throws_exception_after_delay(): void try { $timelock->invoke( - callback: fn () => throw new \RuntimeException('This is an error.'), + callback: fn () => throw new RuntimeException('This is an error.'), duration: Duration::milliseconds(100), ); - } catch (\RuntimeException) { + } catch (RuntimeException) { $elapsed = microtime(true) - $start; $this->assertEqualsToMoreOrLess(0.1, $elapsed, margin: 0.015, windowsMargin: 0.025); } diff --git a/packages/database/src/BelongsTo.php b/packages/database/src/BelongsTo.php index 2478fdf32d..8d5a566812 100644 --- a/packages/database/src/BelongsTo.php +++ b/packages/database/src/BelongsTo.php @@ -42,9 +42,9 @@ public function getOwnerFieldName(): string if ($this->ownerJoin) { if (str_contains($this->ownerJoin, '.')) { return explode('.', $this->ownerJoin)[1]; - } else { - return $this->ownerJoin; } + + return $this->ownerJoin; } $relationModel = inspect($this->property->getType()->asClass()); @@ -66,15 +66,13 @@ public function getSelectFields(): ImmutableArray return $relationModel ->getSelectFields() - ->map(function ($field) use ($tableReference) { - return new FieldStatement( - $tableReference . '.' . $field, + ->map(fn ($field) => new FieldStatement( + $tableReference . '.' . $field, + ) + ->withAlias( + sprintf('%s.%s', $this->property->getName(), $field), ) - ->withAlias( - sprintf('%s.%s', $this->property->getName(), $field), - ) - ->withAliasPrefix($this->parent); - }); + ->withAliasPrefix($this->parent)); } public function getJoinStatement(): JoinStatement diff --git a/packages/database/src/Builder/ModelInspector.php b/packages/database/src/Builder/ModelInspector.php index d39dab76d2..be33d03d2f 100644 --- a/packages/database/src/Builder/ModelInspector.php +++ b/packages/database/src/Builder/ModelInspector.php @@ -89,7 +89,7 @@ public function __construct( public function isObjectModel(): bool { - return $this->reflector !== null; + return $this->reflector instanceof ClassReflector; } public function getTableDefinition(): TableDefinition @@ -113,12 +113,10 @@ public function getTableDefinition(): TableDefinition public function getFieldDefinition(string $field): FieldDefinition { - return $this->memoize('getFieldDefinition' . $field, function () use ($field) { - return new FieldDefinition( - $this->getTableDefinition(), - $field, - ); - }); + return $this->memoize('getFieldDefinition' . $field, fn () => new FieldDefinition( + $this->getTableDefinition(), + $field, + )); } public function getTableName(): string @@ -152,7 +150,11 @@ public function getPropertyValues(): array continue; } - if ($this->getHasMany($property->getName()) || $this->getHasOne($property->getName())) { + if ($this->getHasMany($property->getName()) instanceof HasMany) { + continue; + } + + if ($this->getHasOne($property->getName()) instanceof HasOne) { continue; } @@ -186,7 +188,7 @@ public function getBelongsTo(string $name): ?BelongsTo $property = $this->reflector->getProperty($name); - if ($belongsTo = $property->getAttribute(BelongsTo::class)) { + if (($belongsTo = $property->getAttribute(BelongsTo::class)) instanceof BelongsTo) { return $belongsTo; } @@ -238,7 +240,7 @@ public function getHasOne(string $name): ?HasOne $property = $this->reflector->getProperty($name); - if ($hasOne = $property->getAttribute(HasOne::class)) { + if (($hasOne = $property->getAttribute(HasOne::class)) instanceof HasOne) { return $hasOne; } @@ -261,7 +263,7 @@ public function getHasMany(string $name): ?HasMany $property = $this->reflector->getProperty($name); - if ($hasMany = $property->getAttribute(HasMany::class)) { + if (($hasMany = $property->getAttribute(HasMany::class)) instanceof HasMany) { return $hasMany; } @@ -284,18 +286,17 @@ public function isRelation(string|PropertyReflector $name): bool { $name = $name instanceof PropertyReflector ? $name->getName() : $name; - return $this->memoize('isRelation' . $name, function () use ($name) { - return $this->getBelongsTo($name) !== null || $this->getHasOne($name) !== null || $this->getHasMany($name) !== null; - }); + return $this->memoize( + 'isRelation' . $name, + fn () => $this->getBelongsTo($name) instanceof BelongsTo || $this->getHasOne($name) instanceof HasOne || $this->getHasMany($name) instanceof HasMany, + ); } public function getRelation(string|PropertyReflector $name): ?Relation { $name = $name instanceof PropertyReflector ? $name->getName() : $name; - return $this->memoize('getRelation' . $name, function () use ($name) { - return $this->getBelongsTo($name) ?? $this->getHasOne($name) ?? $this->getHasMany($name); - }); + return $this->memoize('getRelation' . $name, fn () => $this->getBelongsTo($name) ?? $this->getHasOne($name) ?? $this->getHasMany($name)); } /** @@ -311,9 +312,11 @@ public function getRelations(): ImmutableArray $relationFields = arr(); foreach ($this->reflector->getPublicProperties() as $property) { - if ($relation = $this->getRelation($property->getName())) { - $relationFields[] = $relation; + if (! ($relation = $this->getRelation($property->getName())) instanceof Relation) { + continue; } + + $relationFields[] = $relation; } return $relationFields; @@ -360,7 +363,7 @@ public function isRelationLoaded(string|PropertyReflector|Relation $relation): b $relation = $this->getRelation($relation); } - if (! $relation) { + if (! $relation instanceof Relation) { return false; } @@ -368,11 +371,7 @@ public function isRelationLoaded(string|PropertyReflector|Relation $relation): b return false; } - if ($relation->property->getValue($this->instance) === null) { - return false; - } - - return true; + return $relation->property->getValue($this->instance) !== null; } public function getSelectFields(): ImmutableArray @@ -383,18 +382,25 @@ public function getSelectFields(): ImmutableArray $selectFields = arr(); - if ($primaryKey = $this->getPrimaryKeyProperty()) { + if (($primaryKey = $this->getPrimaryKeyProperty()) instanceof PropertyReflector) { $selectFields[] = $primaryKey->getName(); } foreach ($this->reflector->getPublicProperties() as $property) { $relation = $this->getRelation($property->getName()); + if ($relation instanceof HasMany) { + continue; + } - if ($relation instanceof HasMany || $relation instanceof HasOne) { + if ($relation instanceof HasOne) { continue; } - if ($property->isVirtual() || $property->hasAttribute(Virtual::class)) { + if ($property->isVirtual()) { + continue; + } + + if ($property->hasAttribute(Virtual::class)) { continue; } @@ -428,7 +434,7 @@ public function resolveRelations(string $relationString, string $parent = '', ar $currentRelation = $this->getRelation($currentRelationName); - if ($currentRelation === null) { + if (! $currentRelation instanceof Relation) { return []; } @@ -473,7 +479,7 @@ public function resolveEagerRelations(string $parent = '', array $visitedPaths = $currentRelationName = $property->getName(); $currentRelation = $this->getRelation($currentRelationName); - if (! $currentRelation) { + if (! $currentRelation instanceof Relation) { continue; } @@ -537,7 +543,7 @@ public function validate(mixed ...$data): void public function getName(): string { - if ($this->reflector) { + if ($this->reflector instanceof ClassReflector) { return $this->reflector->getName(); } @@ -560,7 +566,7 @@ public function getPrimaryKey(): ?string public function hasPrimaryKey(): bool { - return $this->getPrimaryKeyProperty() !== null; + return $this->getPrimaryKeyProperty() instanceof PropertyReflector; } public function getPrimaryKeyProperty(): ?PropertyReflector @@ -590,7 +596,7 @@ public function getPrimaryKeyValue(): ?PrimaryKey $primaryKeyProperty = $this->getPrimaryKeyProperty(); - if ($primaryKeyProperty === null) { + if (! $primaryKeyProperty instanceof PropertyReflector) { return null; } diff --git a/packages/database/src/Builder/QueryBuilders/BuildsQuery.php b/packages/database/src/Builder/QueryBuilders/BuildsQuery.php index 712ac65b2b..9ec20e8857 100644 --- a/packages/database/src/Builder/QueryBuilders/BuildsQuery.php +++ b/packages/database/src/Builder/QueryBuilders/BuildsQuery.php @@ -16,23 +16,17 @@ interface BuildsQuery * * @return array */ - public array $bindings { - get; - } + public array $bindings { get; } /** * The model inspector for this query builder. */ - public ModelInspector $model { - get; - } + public ModelInspector $model { get; } /** * The database tag for targeting a specific database connection. */ - public null|string|UnitEnum $onDatabase { - get; - } + public null|string|UnitEnum $onDatabase { get; } /** * Creates a {@see Query} instance with the specified optional bindings. diff --git a/packages/database/src/Builder/QueryBuilders/DeleteQueryBuilder.php b/packages/database/src/Builder/QueryBuilders/DeleteQueryBuilder.php index ec415c455f..49a29ee4ab 100644 --- a/packages/database/src/Builder/QueryBuilders/DeleteQueryBuilder.php +++ b/packages/database/src/Builder/QueryBuilders/DeleteQueryBuilder.php @@ -4,6 +4,7 @@ use Tempest\Database\Builder\ModelInspector; use Tempest\Database\OnDatabase; +use Tempest\Database\PrimaryKey; use Tempest\Database\Query; use Tempest\Database\QueryStatements\DeleteStatement; use Tempest\Support\Arr\ImmutableArray; @@ -118,7 +119,7 @@ public function build(mixed ...$bindings): Query if ($this->model->isObjectModel() && is_object($this->model->instance) && $this->model->hasPrimaryKey()) { $primaryKeyValue = $this->model->getPrimaryKeyValue(); - if ($primaryKeyValue !== null) { + if ($primaryKeyValue instanceof PrimaryKey) { $this->where($this->model->getPrimaryKey(), $primaryKeyValue->value); } } diff --git a/packages/database/src/Builder/QueryBuilders/HasConvenientWhereMethods.php b/packages/database/src/Builder/QueryBuilders/HasConvenientWhereMethods.php index 30f94d7306..a6927bef04 100644 --- a/packages/database/src/Builder/QueryBuilders/HasConvenientWhereMethods.php +++ b/packages/database/src/Builder/QueryBuilders/HasConvenientWhereMethods.php @@ -5,6 +5,7 @@ use ArrayAccess; use BackedEnum; use Countable; +use InvalidArgumentException; use Tempest\Database\Builder\WhereOperator; use Tempest\DateTime\DateTime; use Tempest\DateTime\DateTimeInterface; @@ -42,7 +43,7 @@ protected function buildCondition(string $fieldDefinition, WhereOperator $operat } if (! is_array($value)) { - throw new \InvalidArgumentException("{$operator->value} operator requires an array of values"); + throw new InvalidArgumentException("{$operator->value} operator requires an array of values"); } $value = array_map(fn (mixed $value) => match (true) { @@ -60,7 +61,7 @@ protected function buildCondition(string $fieldDefinition, WhereOperator $operat case WhereOperator::BETWEEN: case WhereOperator::NOT_BETWEEN: if (! is_array($value) || count($value) !== 2) { - throw new \InvalidArgumentException("{$operator->value} operator requires an array with exactly 2 values"); + throw new InvalidArgumentException("{$operator->value} operator requires an array with exactly 2 values"); } $sql .= " {$operator->value} ? AND ?"; @@ -75,7 +76,7 @@ protected function buildCondition(string $fieldDefinition, WhereOperator $operat default: if ($operator->requiresValue() && $value === null) { - throw new \InvalidArgumentException("{$operator->value} operator requires a value"); + throw new InvalidArgumentException("{$operator->value} operator requires a value"); } if ($operator->requiresValue()) { @@ -84,6 +85,7 @@ protected function buildCondition(string $fieldDefinition, WhereOperator $operat } else { $sql .= " {$operator->value}"; } + break; } @@ -99,11 +101,7 @@ private function looksLikeWhereRawStatement(string $statement, array $bindings): return false; } - if (! Str\contains($statement, [' ', ...array_map(fn (WhereOperator $op) => $op->value, WhereOperator::cases())])) { - return false; - } - - return true; + return Str\contains($statement, [' ', ...array_map(fn (WhereOperator $op) => $op->value, WhereOperator::cases())]); } /** diff --git a/packages/database/src/Builder/QueryBuilders/InsertQueryBuilder.php b/packages/database/src/Builder/QueryBuilders/InsertQueryBuilder.php index cfd009c08b..098da200b6 100644 --- a/packages/database/src/Builder/QueryBuilders/InsertQueryBuilder.php +++ b/packages/database/src/Builder/QueryBuilders/InsertQueryBuilder.php @@ -3,12 +3,14 @@ namespace Tempest\Database\Builder\QueryBuilders; use Closure; +use Tempest\Database\BelongsTo; use Tempest\Database\Builder\ModelInspector; use Tempest\Database\Database; use Tempest\Database\DatabaseContext; use Tempest\Database\Exceptions\HasManyRelationCouldNotBeInsterted; use Tempest\Database\Exceptions\HasOneRelationCouldNotBeInserted; use Tempest\Database\Exceptions\ModelDidNotHavePrimaryColumn; +use Tempest\Database\HasMany; use Tempest\Database\HasOne; use Tempest\Database\OnDatabase; use Tempest\Database\PrimaryKey; @@ -34,7 +36,9 @@ */ final class InsertQueryBuilder implements BuildsQuery { - use HasConditions, OnDatabase, TransformsQueryBuilder; + use HasConditions; + use OnDatabase; + use TransformsQueryBuilder; private InsertStatement $insert; @@ -71,7 +75,7 @@ public function execute(mixed ...$bindings): ?PrimaryKey { $id = $this->build()->execute(...$bindings); - if ($id === null) { + if (! $id instanceof PrimaryKey) { return null; } @@ -209,7 +213,7 @@ private function addHasManyRelationCallback(string $relationName, array $relatio { $hasMany = $this->model->getHasMany($relationName); - if ($hasMany === null) { + if (! $hasMany instanceof HasMany) { return; } @@ -243,7 +247,7 @@ private function addHasOneRelationCallback(string $relationName, object|iterable { $hasOne = $this->model->getHasOne($relationName); - if ($hasOne === null) { + if (! $hasOne instanceof HasOne) { return; } @@ -346,7 +350,7 @@ private function handleHasManyRelation(string $key, mixed $relations): bool { $hasMany = $this->model->getHasMany($key); - if ($hasMany === null) { + if (! $hasMany instanceof HasMany) { return false; } @@ -363,7 +367,7 @@ private function handleHasOneRelation(string $key, mixed $relation): bool { $hasOne = $this->model->getHasOne($key); - if ($hasOne === null) { + if (! $hasOne instanceof HasOne) { return false; } @@ -380,7 +384,7 @@ private function handleBelongsToRelation(string $key, mixed $value, array &$entr { $belongsTo = $this->model->getBelongsTo($key); - if ($belongsTo === null || ! is_object($value) && ! is_array($value)) { + if (! $belongsTo instanceof BelongsTo || ! is_object($value) && ! is_array($value)) { return false; } @@ -424,7 +428,7 @@ private function resolveObjectData(object $model): array $value = $property->getValue($model); - if ($definition->getHasMany($propertyName)) { + if ($definition->getHasMany($propertyName) instanceof HasMany) { if (is_iterable($value)) { $this->addHasManyRelationCallback($propertyName, $value); } @@ -432,7 +436,7 @@ private function resolveObjectData(object $model): array continue; } - if ($definition->getHasOne($propertyName)) { + if ($definition->getHasOne($propertyName) instanceof HasOne) { if (is_object($value) || is_array($value)) { $this->addHasOneRelationCallback($propertyName, $value); } @@ -468,7 +472,7 @@ private function resolveRelationProperty(ModelInspector $definition, PropertyRef } $belongsTo = $definition->getBelongsTo($property->getName()); - $column = $belongsTo + $column = $belongsTo instanceof BelongsTo ? $belongsTo->getOwnerFieldName() : $property->getName() . '_' . $primaryKey; diff --git a/packages/database/src/Builder/QueryBuilders/QueryBuilder.php b/packages/database/src/Builder/QueryBuilders/QueryBuilder.php index d725161a47..8f99aa2bd3 100644 --- a/packages/database/src/Builder/QueryBuilders/QueryBuilder.php +++ b/packages/database/src/Builder/QueryBuilders/QueryBuilder.php @@ -6,6 +6,7 @@ use Tempest\Database\OnDatabase; use Tempest\Database\PrimaryKey; use Tempest\Mapper\SerializerFactory; +use Tempest\Reflection\PropertyReflector; use function Tempest\Container\get; use function Tempest\Database\inspect; @@ -200,7 +201,8 @@ public function get(string|int|PrimaryKey $id, array $relations = []): ?object default => new PrimaryKey($id), }; - return $this->select() + return $this + ->select() ->with(...$relations) ->get($id); } @@ -212,7 +214,8 @@ public function get(string|int|PrimaryKey $id, array $relations = []): ?object */ public function all(array $relations = []): array { - return $this->select() + return $this + ->select() ->with(...$relations) ->all(); } @@ -259,7 +262,7 @@ public function create(mixed ...$params): object $inspector = inspect($this->model); $primaryKeyProperty = $inspector->getPrimaryKeyProperty(); - if ($id !== null && $primaryKeyProperty !== null) { + if ($id instanceof PrimaryKey && $primaryKeyProperty instanceof PropertyReflector) { $primaryKeyName = $primaryKeyProperty->getName(); if (! $inspector->hasUuidPrimaryKey() || $model->{$primaryKeyName} === null) { diff --git a/packages/database/src/Builder/QueryBuilders/SelectQueryBuilder.php b/packages/database/src/Builder/QueryBuilders/SelectQueryBuilder.php index e05fc333e6..bc71150144 100644 --- a/packages/database/src/Builder/QueryBuilders/SelectQueryBuilder.php +++ b/packages/database/src/Builder/QueryBuilders/SelectQueryBuilder.php @@ -104,7 +104,7 @@ public function first(mixed ...$bindings): mixed return null; } - return $result[array_key_first($result)]; + return array_first($result); } /** @@ -203,7 +203,8 @@ public function chunk(Closure $closure, int $amountPerChunk = 200): void $offset = 0; do { - $data = $this->clone() + $data = $this + ->clone() ->limit($amountPerChunk) ->offset($offset) ->all(); diff --git a/packages/database/src/Builder/QueryBuilders/SupportsJoins.php b/packages/database/src/Builder/QueryBuilders/SupportsJoins.php index 7e6dd41824..28ef8fe107 100644 --- a/packages/database/src/Builder/QueryBuilders/SupportsJoins.php +++ b/packages/database/src/Builder/QueryBuilders/SupportsJoins.php @@ -14,7 +14,5 @@ interface SupportsJoins * * @return array */ - public array $joins { - get; - } + public array $joins { get; } } diff --git a/packages/database/src/Builder/QueryBuilders/SupportsRelations.php b/packages/database/src/Builder/QueryBuilders/SupportsRelations.php index 17bccd029b..366aedd930 100644 --- a/packages/database/src/Builder/QueryBuilders/SupportsRelations.php +++ b/packages/database/src/Builder/QueryBuilders/SupportsRelations.php @@ -14,9 +14,7 @@ interface SupportsRelations * * @return array */ - public array $relations { - get; - } + public array $relations { get; } /** * Gets all resolved relations with their join statements. diff --git a/packages/database/src/Builder/QueryBuilders/SupportsWhereStatements.php b/packages/database/src/Builder/QueryBuilders/SupportsWhereStatements.php index ce48e8dbe4..90eb7158e9 100644 --- a/packages/database/src/Builder/QueryBuilders/SupportsWhereStatements.php +++ b/packages/database/src/Builder/QueryBuilders/SupportsWhereStatements.php @@ -17,9 +17,7 @@ interface SupportsWhereStatements * * @var ImmutableArray */ - public ImmutableArray $wheres { - get; - } + public ImmutableArray $wheres { get; } /** * Adds a WHERE condition to the query. diff --git a/packages/database/src/Builder/QueryBuilders/UpdateQueryBuilder.php b/packages/database/src/Builder/QueryBuilders/UpdateQueryBuilder.php index ec4f2d8def..cc043ed21c 100644 --- a/packages/database/src/Builder/QueryBuilders/UpdateQueryBuilder.php +++ b/packages/database/src/Builder/QueryBuilders/UpdateQueryBuilder.php @@ -2,6 +2,7 @@ namespace Tempest\Database\Builder\QueryBuilders; +use Tempest\Database\BelongsTo; use Tempest\Database\Builder\ModelInspector; use Tempest\Database\Builder\WhereOperator; use Tempest\Database\Database; @@ -10,6 +11,8 @@ use Tempest\Database\Exceptions\HasManyRelationCouldNotBeUpdated; use Tempest\Database\Exceptions\HasOneRelationCouldNotBeUpdated; use Tempest\Database\Exceptions\ModelDidNotHavePrimaryColumn; +use Tempest\Database\HasMany; +use Tempest\Database\HasOne; use Tempest\Database\OnDatabase; use Tempest\Database\PrimaryKey; use Tempest\Database\Query; @@ -17,6 +20,7 @@ use Tempest\Database\QueryStatements\WhereStatement; use Tempest\Database\Virtual; use Tempest\Intl; +use Tempest\Mapper\Serializer; use Tempest\Mapper\SerializerFactory; use Tempest\Reflection\ClassReflector; use Tempest\Reflection\PropertyReflector; @@ -112,7 +116,7 @@ public function execute(mixed ...$bindings): ?PrimaryKey } // Execute after callbacks for relation updates - if ($this->model->hasPrimaryKey() && $this->after !== [] && $this->primaryKeyForRelations !== null) { + if ($this->model->hasPrimaryKey() && $this->after !== [] && $this->primaryKeyForRelations instanceof PrimaryKey) { foreach ($this->after as $after) { $query = $after($this->primaryKeyForRelations); @@ -239,7 +243,7 @@ private function resolveRelationValue(PropertyReflector $property, string $colum { $belongsTo = $this->model->getBelongsTo($column); - if ($belongsTo) { + if ($belongsTo instanceof BelongsTo) { $column = $belongsTo->getOwnerFieldName(); $relationModel = inspect($property->getType()->asClass()); $this->ensureModelHasPrimaryKey($relationModel, 'BelongsTo'); @@ -271,7 +275,7 @@ private function serializeValue(PropertyReflector $property, mixed $value): mixe ->in($this->context) ->forProperty($property); - if ($value !== null && $serializer !== null) { + if ($value !== null && $serializer instanceof Serializer) { return $serializer->serialize($value); } @@ -289,7 +293,7 @@ private function handleHasManyRelation(string $key, mixed $relations): bool { $hasMany = $this->model->getHasMany($key); - if ($hasMany === null) { + if (! $hasMany instanceof HasMany) { return false; } @@ -306,7 +310,7 @@ private function handleHasOneRelation(string $key, mixed $relation): bool { $hasOne = $this->model->getHasOne($key); - if ($hasOne === null) { + if (! $hasOne instanceof HasOne) { return false; } @@ -323,7 +327,7 @@ private function addHasManyRelationCallback(string $relationName, iterable $rela { $hasMany = $this->model->getHasMany($relationName); - if ($hasMany === null) { + if (! $hasMany instanceof HasMany) { return; } @@ -357,7 +361,7 @@ private function addHasOneRelationCallback(string $relationName, object|array $r { $hasOne = $this->model->getHasOne($relationName); - if ($hasOne === null) { + if (! $hasOne instanceof HasOne) { return; } @@ -544,10 +548,13 @@ public function whereField(string $field, mixed $value, string|WhereOperator $op { $operator = WhereOperator::fromOperator($operator); - if ($this->model->hasPrimaryKey() && $field === $this->model->getPrimaryKey() && $this->hasRelationUpdates()) { - if ($operator === WhereOperator::EQUALS && (is_string($value) || is_int($value) || $value instanceof PrimaryKey)) { - $this->primaryKeyForRelations = new PrimaryKey($value); - } + if ( + $this->model->hasPrimaryKey() && $field === $this->model->getPrimaryKey() && $this->hasRelationUpdates() && ( + $operator === WhereOperator::EQUALS + && (is_string($value) || is_int($value) || $value instanceof PrimaryKey) + ) + ) { + $this->primaryKeyForRelations = new PrimaryKey($value); } $fieldDefinition = $this->model->getFieldDefinition($field); @@ -602,7 +609,7 @@ private function validateRelationUpdateConstraints(): void throw CouldNotUpdateRelation::requiresPrimaryKey($this->model); } - if ($this->primaryKeyForRelations === null) { + if (! $this->primaryKeyForRelations instanceof PrimaryKey) { throw CouldNotUpdateRelation::requiresSingleRecord($this->model); } } @@ -613,7 +620,7 @@ private function setWhereForObjectModel(): void return; } - if ($primaryKeyValue = $this->model->getPrimaryKeyValue()) { + if (($primaryKeyValue = $this->model->getPrimaryKeyValue()) instanceof PrimaryKey) { $this->whereField($this->model->getPrimaryKey(), $primaryKeyValue->value); } } diff --git a/packages/database/src/Casters/DataTransferObjectCaster.php b/packages/database/src/Casters/DataTransferObjectCaster.php index 4f9d6dfc5c..a18bb67c96 100644 --- a/packages/database/src/Casters/DataTransferObjectCaster.php +++ b/packages/database/src/Casters/DataTransferObjectCaster.php @@ -34,13 +34,7 @@ public static function accepts(PropertyReflector|TypeReflector $type): bool : $type; if ($type->isUnion()) { - foreach ($type->split() as $memberType) { - if (static::accepts($memberType)) { - return true; - } - } - - return false; + return array_any($type->split(), fn ($memberType) => self::accepts($memberType)); } return $type->isClass() && $type->asClass()->getAttribute(SerializeAs::class) !== null; @@ -77,7 +71,7 @@ private function deserialize(mixed $input): mixed } if (is_array($input)) { - return array_map(fn (mixed $value) => $this->deserialize($value), $input); + return array_map($this->deserialize(...), $input); } return $input; diff --git a/packages/database/src/Commands/MakeMigrationCommand.php b/packages/database/src/Commands/MakeMigrationCommand.php index 7e6c09507f..8a7cfa19d7 100644 --- a/packages/database/src/Commands/MakeMigrationCommand.php +++ b/packages/database/src/Commands/MakeMigrationCommand.php @@ -9,6 +9,7 @@ use Tempest\Core\PublishesFiles; use Tempest\Database\Config\DatabaseConfig; use Tempest\Database\Enums\MigrationType; +use Tempest\Database\Migrations\TableGuess; use Tempest\Database\Migrations\TableGuesser; use Tempest\Database\Stubs\ObjectAlterMigrationStub; use Tempest\Database\Stubs\ObjectMigrationStub; @@ -81,10 +82,10 @@ public function __invoke( ); $alter ??= $yes - ? $guess !== null && ! $guess->isCreate + ? $guess instanceof TableGuess && ! $guess->isCreate : $this->confirm( question: 'Is this an alteration?', - default: $guess !== null && ! $guess->isCreate, + default: $guess instanceof TableGuess && ! $guess->isCreate, ); $table = $this->resolveTableName($table); diff --git a/packages/database/src/Config/DatabaseConfig.php b/packages/database/src/Config/DatabaseConfig.php index 581a5b878b..ced0c3d8c2 100644 --- a/packages/database/src/Config/DatabaseConfig.php +++ b/packages/database/src/Config/DatabaseConfig.php @@ -13,56 +13,40 @@ interface DatabaseConfig extends HasTag /** * PDO data source name connection string. */ - public string $dsn { - get; - } + public string $dsn { get; } /** * The naming strategy for database tables and columns. */ - public NamingStrategy $namingStrategy { - get; - } + public NamingStrategy $namingStrategy { get; } /** * The naming strategy for migration file prefixes. */ - public MigrationNamingStrategy $migrationNamingStrategy { - get; - } + public MigrationNamingStrategy $migrationNamingStrategy { get; } /** * The database dialect (MySQL, PostgreSQL, SQLite). */ - public DatabaseDialect $dialect { - get; - } + public DatabaseDialect $dialect { get; } /** * The database username for authentication. */ - public ?string $username { - get; - } + public ?string $username { get; } /** * The database password for authentication. */ - public ?string $password { - get; - } + public ?string $password { get; } /** * Whether to use persistent database connections. */ - public bool $usePersistentConnection { - get; - } + public bool $usePersistentConnection { get; } /** * PDO connection options built from configuration properties. */ - public array $options { - get; - } + public array $options { get; } } diff --git a/packages/database/src/Connection/PDOConnection.php b/packages/database/src/Connection/PDOConnection.php index 1b3e6ae98e..16a5cd9e79 100644 --- a/packages/database/src/Connection/PDOConnection.php +++ b/packages/database/src/Connection/PDOConnection.php @@ -20,7 +20,7 @@ public function __construct( public function beginTransaction(): bool { - if ($this->pdo === null) { + if (! $this->pdo instanceof PDO) { throw new ConnectionClosed(); } @@ -29,7 +29,7 @@ public function beginTransaction(): bool public function commit(): bool { - if ($this->pdo === null) { + if (! $this->pdo instanceof PDO) { throw new ConnectionClosed(); } @@ -38,7 +38,7 @@ public function commit(): bool public function rollback(): bool { - if ($this->pdo === null) { + if (! $this->pdo instanceof PDO) { throw new ConnectionClosed(); } @@ -47,7 +47,7 @@ public function rollback(): bool public function lastInsertId(): false|string { - if ($this->pdo === null) { + if (! $this->pdo instanceof PDO) { throw new ConnectionClosed(); } @@ -56,7 +56,7 @@ public function lastInsertId(): false|string public function prepare(string $sql): PDOStatement { - if ($this->pdo === null) { + if (! $this->pdo instanceof PDO) { throw new ConnectionClosed(); } @@ -94,7 +94,7 @@ public function close(): void public function connect(): void { - if ($this->pdo !== null) { + if ($this->pdo instanceof PDO) { return; } diff --git a/packages/database/src/Database.php b/packages/database/src/Database.php index 6f12cf132c..966e492dee 100644 --- a/packages/database/src/Database.php +++ b/packages/database/src/Database.php @@ -17,16 +17,12 @@ interface Database /** * The dialect of this database. */ - public DatabaseDialect $dialect { - get; - } + public DatabaseDialect $dialect { get; } /** * The tag associated with this database, if any. */ - public null|string|UnitEnum $tag { - get; - } + public null|string|UnitEnum $tag { get; } /** * Executes the given query. diff --git a/packages/database/src/DatabaseInsightsProvider.php b/packages/database/src/DatabaseInsightsProvider.php index a3afaba7e8..59d37b5254 100644 --- a/packages/database/src/DatabaseInsightsProvider.php +++ b/packages/database/src/DatabaseInsightsProvider.php @@ -11,6 +11,7 @@ use Tempest\Database\Config\SQLiteConfig; use Tempest\Support\Arr; use Tempest\Support\Regex; +use Throwable; use function Tempest\Support\Path\normalize; use function Tempest\Support\Path\to_relative_path; @@ -35,7 +36,7 @@ public function getInsights(): array private function getDatabaseEngine(): string { - return match (get_class($this->databaseConfig)) { + return match ($this->databaseConfig::class) { SQLiteConfig::class => 'SQLite', PostgresConfig::class => 'PostgreSQL', MysqlConfig::class => 'MySQL', @@ -46,7 +47,7 @@ private function getDatabaseEngine(): string private function getDatabaseVersion(): Insight { // TODO: support displaying multiple databases, after cache PR - [$versionQuery, $regex] = match (get_class($this->databaseConfig)) { + [$versionQuery, $regex] = match ($this->databaseConfig::class) { SQLiteConfig::class => ['SELECT sqlite_version() AS version;', '/(?.*)/'], PostgresConfig::class => ['SELECT version() AS version;', "/PostgreSQL (?\S+)/"], MysqlConfig::class => ['SELECT version() AS version;', '/^(?\d+\.\d+\.\d+)(?:-\w+)?/'], @@ -63,7 +64,7 @@ private function getDatabaseVersion(): Insight pattern: $regex, match: 'version', )); - } catch (\Throwable $e) { + } catch (Throwable) { return new Insight('Unavailable', InsightType::ERROR); } } diff --git a/packages/database/src/Eager.php b/packages/database/src/Eager.php index cd3767dc61..9efd7e34ee 100644 --- a/packages/database/src/Eager.php +++ b/packages/database/src/Eager.php @@ -7,6 +7,4 @@ use Attribute; #[Attribute(Attribute::TARGET_PROPERTY)] -final readonly class Eager -{ -} +final readonly class Eager {} diff --git a/packages/database/src/Exceptions/DatabaseException.php b/packages/database/src/Exceptions/DatabaseException.php index f7ae18e52d..c9e7b4a996 100644 --- a/packages/database/src/Exceptions/DatabaseException.php +++ b/packages/database/src/Exceptions/DatabaseException.php @@ -4,6 +4,4 @@ namespace Tempest\Database\Exceptions; -interface DatabaseException -{ -} +interface DatabaseException {} diff --git a/packages/database/src/Exceptions/ModelDidNotHavePrimaryColumn.php b/packages/database/src/Exceptions/ModelDidNotHavePrimaryColumn.php index e60b2890a4..e311557f60 100644 --- a/packages/database/src/Exceptions/ModelDidNotHavePrimaryColumn.php +++ b/packages/database/src/Exceptions/ModelDidNotHavePrimaryColumn.php @@ -11,7 +11,7 @@ final class ModelDidNotHavePrimaryColumn extends Exception implements DatabaseEx public static function neededForMethod(string|object $model, string $method): self { if (is_object($model)) { - $model = get_class($model); + $model = $model::class; } return new self("`{$model}` does not have a primary column defined, which is required for the `{$method}` method."); @@ -20,7 +20,7 @@ public static function neededForMethod(string|object $model, string $method): se public static function neededForRelation(string|object $model, string $relationType): self { if (is_object($model)) { - $model = get_class($model); + $model = $model::class; } return new self("`{$model}` does not have a primary column defined, which is required for `{$relationType}` relationships."); diff --git a/packages/database/src/Exceptions/QueryWasInvalid.php b/packages/database/src/Exceptions/QueryWasInvalid.php index 5afe13807f..3da5a17841 100644 --- a/packages/database/src/Exceptions/QueryWasInvalid.php +++ b/packages/database/src/Exceptions/QueryWasInvalid.php @@ -11,21 +11,17 @@ final class QueryWasInvalid extends Exception implements ProvidesContext { - public readonly PDOException $pdoException; - public function __construct( private(set) Query $query, private(set) array $bindings, - PDOException $previous, + public readonly PDOException $pdoException, ) { - $this->pdoException = $previous; - - $message = $previous->getMessage(); + $message = $this->pdoException->getMessage(); $message .= PHP_EOL . PHP_EOL . $query->toRawSql(); parent::__construct( message: $message, - previous: $previous, + previous: $this->pdoException, ); } diff --git a/packages/database/src/GenericDatabase.php b/packages/database/src/GenericDatabase.php index 06d0184027..60390ec57f 100644 --- a/packages/database/src/GenericDatabase.php +++ b/packages/database/src/GenericDatabase.php @@ -13,6 +13,7 @@ use Tempest\Database\Connection\PDOConnection; use Tempest\Database\Exceptions\QueryWasInvalid; use Tempest\Database\Transactions\TransactionManager; +use Tempest\Mapper\Serializer; use Tempest\Mapper\SerializerFactory; use Tempest\Support\Str\ImmutableString; use Throwable; @@ -23,6 +24,7 @@ final class GenericDatabase implements Database { private ?PDOStatement $lastStatement = null; + private ?Query $lastQuery = null; public DatabaseDialect $dialect { @@ -152,7 +154,7 @@ private function resolveBindings(Query $query): array $value = $value->execute(); } elseif (is_string($value) || is_numeric($value)) { // Keep value as is - } elseif ($serializer = $serializerFactory->forValue($value)) { + } elseif (($serializer = $serializerFactory->forValue($value)) instanceof Serializer) { $value = $serializer->serialize($value); } diff --git a/packages/database/src/HasLeadingStatements.php b/packages/database/src/HasLeadingStatements.php index d6f126fe10..42946c0ae5 100644 --- a/packages/database/src/HasLeadingStatements.php +++ b/packages/database/src/HasLeadingStatements.php @@ -4,7 +4,5 @@ interface HasLeadingStatements { - public array $leadingStatements { - get; - } + public array $leadingStatements { get; } } diff --git a/packages/database/src/HasTrailingStatements.php b/packages/database/src/HasTrailingStatements.php index 0812207052..b91b4ce66f 100644 --- a/packages/database/src/HasTrailingStatements.php +++ b/packages/database/src/HasTrailingStatements.php @@ -4,7 +4,5 @@ interface HasTrailingStatements { - public array $trailingStatements { - get; - } + public array $trailingStatements { get; } } diff --git a/packages/database/src/IsDatabaseModel.php b/packages/database/src/IsDatabaseModel.php index ebb837d6ae..ba7eafd14d 100644 --- a/packages/database/src/IsDatabaseModel.php +++ b/packages/database/src/IsDatabaseModel.php @@ -51,10 +51,7 @@ public function onDatabase(null|string|UnitEnum $databaseTag): self /** @return QueryBuilder */ protected static function queryBuilder(): QueryBuilder { - /** @var QueryBuilder $query */ - $query = query(self::class); - - return $query; + return query(self::class); } /** @@ -64,9 +61,7 @@ protected static function queryBuilder(): QueryBuilder */ public static function select(): SelectQueryBuilder { - $query = self::queryBuilder()->select(); - - return $query; + return self::queryBuilder()->select(); } /** diff --git a/packages/database/src/Lazy.php b/packages/database/src/Lazy.php index b112d9e031..a43fcc67f2 100644 --- a/packages/database/src/Lazy.php +++ b/packages/database/src/Lazy.php @@ -7,6 +7,4 @@ use Attribute; #[Attribute(Attribute::TARGET_PROPERTY)] -final readonly class Lazy -{ -} +final readonly class Lazy {} diff --git a/packages/database/src/Mappers/SelectModelMapper.php b/packages/database/src/Mappers/SelectModelMapper.php index 12d8477d95..910a23d286 100644 --- a/packages/database/src/Mappers/SelectModelMapper.php +++ b/packages/database/src/Mappers/SelectModelMapper.php @@ -155,7 +155,7 @@ public function normalizeRow(ModelInspector $model, array $row, MutableArray $da $currentModel = inspect($relation); } - if ($key) { + if ($key !== '' && $key !== '0') { $data->set($key, $value); } } diff --git a/packages/database/src/MigratesDown.php b/packages/database/src/MigratesDown.php index a18004d879..a3414f14df 100644 --- a/packages/database/src/MigratesDown.php +++ b/packages/database/src/MigratesDown.php @@ -6,9 +6,7 @@ interface MigratesDown { - public string $name { - get; - } + public string $name { get; } public function down(): QueryStatement; } diff --git a/packages/database/src/MigratesUp.php b/packages/database/src/MigratesUp.php index 9a436fb8b0..c25a084092 100644 --- a/packages/database/src/MigratesUp.php +++ b/packages/database/src/MigratesUp.php @@ -6,9 +6,7 @@ interface MigratesUp { - public string $name { - get; - } + public string $name { get; } public function up(): QueryStatement; } diff --git a/packages/database/src/MigrationDiscovery.php b/packages/database/src/MigrationDiscovery.php index 205a29fd24..c8af947bca 100644 --- a/packages/database/src/MigrationDiscovery.php +++ b/packages/database/src/MigrationDiscovery.php @@ -49,7 +49,11 @@ public function discoverPath(DiscoveryLocation $location, string $path): void $contents = explode(';', Filesystem\read_file($path)); foreach ($contents as $i => $content) { - if (! $content) { + if ($content === '') { + continue; + } + + if ($content === '0') { continue; } diff --git a/packages/database/src/Migrations/MigrationException.php b/packages/database/src/Migrations/MigrationException.php index c9e7cb3073..96d065ecad 100644 --- a/packages/database/src/Migrations/MigrationException.php +++ b/packages/database/src/Migrations/MigrationException.php @@ -4,6 +4,4 @@ namespace Tempest\Database\Migrations; -interface MigrationException -{ -} +interface MigrationException {} diff --git a/packages/database/src/Migrations/MigrationManager.php b/packages/database/src/Migrations/MigrationManager.php index bfcabca2a6..edc25a22c7 100644 --- a/packages/database/src/Migrations/MigrationManager.php +++ b/packages/database/src/Migrations/MigrationManager.php @@ -211,8 +211,11 @@ public function executeUp(MigratesUp $migration): void try { foreach ($statements as $statement) { $sql = $statement->compile($this->dialect); + if (trim($sql) === '') { + continue; + } - if (! trim($sql)) { + if (trim($sql) === '0') { continue; } @@ -292,7 +295,7 @@ private function getTableDefinitions(): array fn (array $item) => match ($this->dialect) { DatabaseDialect::SQLITE => new TableMigrationDefinition($item['name']), DatabaseDialect::POSTGRESQL => new TableMigrationDefinition($item['table_name']), - DatabaseDialect::MYSQL => new TableMigrationDefinition(array_values($item)[0]), + DatabaseDialect::MYSQL => new TableMigrationDefinition(array_first($item)), }, new ShowTablesStatement()->fetch($this->dialect), ); @@ -315,7 +318,7 @@ private function getMigrationHash(MigratesUp|MigratesDown $migration): string private function getMinifiedSqlFromStatement(?QueryStatement $statement): string { - if ($statement === null) { + if (! $statement instanceof QueryStatement) { return ''; } @@ -326,8 +329,6 @@ private function getMinifiedSqlFromStatement(?QueryStatement $statement): string $sql = preg_replace('/\/\*[\s\S]*?\*\//', '', $sql); // Remove block comments // Remove blank lines and excessive spaces - $sql = preg_replace('/\s+/', ' ', trim($sql)); - - return $sql; + return preg_replace('/\s+/', ' ', trim($sql)); } } diff --git a/packages/database/src/Migrations/RunnableMigrations.php b/packages/database/src/Migrations/RunnableMigrations.php index c90a8de193..1fabaa7068 100644 --- a/packages/database/src/Migrations/RunnableMigrations.php +++ b/packages/database/src/Migrations/RunnableMigrations.php @@ -36,9 +36,11 @@ public function getIterator(): Traversable public function up(): Traversable { foreach ($this->getIterator() as $migration) { - if ($migration instanceof MigratesUp) { - yield $migration; + if (! $migration instanceof MigratesUp) { + continue; } + + yield $migration; } } @@ -48,9 +50,11 @@ public function up(): Traversable public function down(): Traversable { foreach ($this->getIterator() as $migration) { - if ($migration instanceof MigratesDown) { - yield $migration; + if (! $migration instanceof MigratesDown) { + continue; } + + yield $migration; } } } diff --git a/packages/database/src/Migrations/TableGuesser.php b/packages/database/src/Migrations/TableGuesser.php index 8413661020..0a194a460d 100644 --- a/packages/database/src/Migrations/TableGuesser.php +++ b/packages/database/src/Migrations/TableGuesser.php @@ -15,7 +15,7 @@ public static function guess(string $migration): ?TableGuess if (Str\starts_with($migration, 'create_')) { $table = Str\strip_end(Str\after_first($migration, 'create_'), '_table'); - return ! Str\is_empty($table) ? new TableGuess($table, isCreate: true) : null; + return Str\is_empty($table) ? null : new TableGuess($table, isCreate: true); } if (! Str\contains($migration, self::PREPOSITIONS)) { @@ -24,6 +24,6 @@ public static function guess(string $migration): ?TableGuess $table = Str\strip_end(Str\after_last($migration, self::PREPOSITIONS), '_table'); - return ! Str\is_empty($table) ? new TableGuess($table, isCreate: false) : null; + return Str\is_empty($table) ? null : new TableGuess($table, isCreate: false); } } diff --git a/packages/database/src/QueryStatements/AlterTableStatement.php b/packages/database/src/QueryStatements/AlterTableStatement.php index 1ba8b7421b..d1d7530c0f 100644 --- a/packages/database/src/QueryStatements/AlterTableStatement.php +++ b/packages/database/src/QueryStatements/AlterTableStatement.php @@ -90,7 +90,7 @@ public function modify(QueryStatement $column): self public function compile(DatabaseDialect $dialect): string { if ($this->statements !== []) { - $alterTable = sprintf( + return sprintf( 'ALTER TABLE %s %s;', new TableDefinition($this->tableName), arr($this->statements) @@ -100,10 +100,8 @@ public function compile(DatabaseDialect $dialect): string ->wrap(before: PHP_EOL . ' ', after: PHP_EOL) ->toString(), ); - } else { - $alterTable = ''; } - return $alterTable; + return ''; } } diff --git a/packages/database/src/QueryStatements/CreateEnumTypeStatement.php b/packages/database/src/QueryStatements/CreateEnumTypeStatement.php index 9640b4e8ee..bf359c4377 100644 --- a/packages/database/src/QueryStatements/CreateEnumTypeStatement.php +++ b/packages/database/src/QueryStatements/CreateEnumTypeStatement.php @@ -30,8 +30,8 @@ public function compile(DatabaseDialect $dialect): string DatabaseDialect::MYSQL, DatabaseDialect::SQLITE => '', DatabaseDialect::POSTGRESQL => sprintf( <<<'PSQL' - CREATE TYPE "%s" AS ENUM (%s); - PSQL, + CREATE TYPE "%s" AS ENUM (%s); + PSQL, str($this->enumClass)->replace('\\\\', '_'), $cases->implode(', '), ), diff --git a/packages/database/src/QueryStatements/CreateTableStatement.php b/packages/database/src/QueryStatements/CreateTableStatement.php index 3e759a985b..28e9b2d6e0 100644 --- a/packages/database/src/QueryStatements/CreateTableStatement.php +++ b/packages/database/src/QueryStatements/CreateTableStatement.php @@ -395,7 +395,7 @@ public function raw(string $statement): self public function compile(DatabaseDialect $dialect): string { - $createTable = sprintf( + return sprintf( 'CREATE TABLE %s (%s);', new TableDefinition($this->tableName), arr($this->statements) @@ -407,7 +407,5 @@ public function compile(DatabaseDialect $dialect): string ->wrap(before: PHP_EOL . ' ', after: PHP_EOL) ->toString(), ); - - return $createTable; } } diff --git a/packages/database/src/QueryStatements/DatetimeStatement.php b/packages/database/src/QueryStatements/DatetimeStatement.php index 6b2dea5fac..c4aa33997e 100644 --- a/packages/database/src/QueryStatements/DatetimeStatement.php +++ b/packages/database/src/QueryStatements/DatetimeStatement.php @@ -19,7 +19,7 @@ public function __construct( public function compile(DatabaseDialect $dialect): string { - if ($this->default !== null && $this->current === true) { + if ($this->default !== null && $this->current) { throw new InvalidArgumentException("Cannot set both `default` and `current` for datetime column `{$this->name}`."); } diff --git a/packages/database/src/QueryStatements/DropEnumTypeStatement.php b/packages/database/src/QueryStatements/DropEnumTypeStatement.php index 35fddb0dad..16396dcf78 100644 --- a/packages/database/src/QueryStatements/DropEnumTypeStatement.php +++ b/packages/database/src/QueryStatements/DropEnumTypeStatement.php @@ -24,8 +24,8 @@ public function compile(DatabaseDialect $dialect): string DatabaseDialect::MYSQL, DatabaseDialect::SQLITE => '', DatabaseDialect::POSTGRESQL => sprintf( <<<'PSQL' - DROP TYPE IF EXISTS "%s"; - PSQL, + DROP TYPE IF EXISTS "%s"; + PSQL, str($this->enumClass)->replace('\\\\', '_'), ), }; diff --git a/packages/database/src/QueryStatements/EnumStatement.php b/packages/database/src/QueryStatements/EnumStatement.php index 29d05bcd83..26ba7f5eb9 100644 --- a/packages/database/src/QueryStatements/EnumStatement.php +++ b/packages/database/src/QueryStatements/EnumStatement.php @@ -29,7 +29,7 @@ public function compile(DatabaseDialect $dialect): string ->map(fn (string $value) => str_replace('\\', '\\\\', $value)) ->map(fn (string $value) => "'{$value}'"); - if ($this->default !== null) { + if ($this->default instanceof UnitEnum) { $defaultValue = $this->default instanceof BackedEnum ? $this->default->value : $this->default->name; } else { $defaultValue = null; diff --git a/packages/database/src/QueryStatements/FieldStatement.php b/packages/database/src/QueryStatements/FieldStatement.php index 9492b13971..26dd22cfd2 100644 --- a/packages/database/src/QueryStatements/FieldStatement.php +++ b/packages/database/src/QueryStatements/FieldStatement.php @@ -11,6 +11,7 @@ final class FieldStatement implements QueryStatement { private null|bool|string $alias = null; + private ?string $aliasPrefix = null; public function __construct( diff --git a/packages/database/src/QueryStatements/HasWhereStatements.php b/packages/database/src/QueryStatements/HasWhereStatements.php index 91869b1046..def5277312 100644 --- a/packages/database/src/QueryStatements/HasWhereStatements.php +++ b/packages/database/src/QueryStatements/HasWhereStatements.php @@ -7,7 +7,5 @@ interface HasWhereStatements { /** @var ImmutableArray */ - public ImmutableArray $where { - get; - } + public ImmutableArray $where { get; } } diff --git a/packages/database/src/QueryStatements/JoinStatement.php b/packages/database/src/QueryStatements/JoinStatement.php index 23ab04d0b2..a05d9f7f95 100644 --- a/packages/database/src/QueryStatements/JoinStatement.php +++ b/packages/database/src/QueryStatements/JoinStatement.php @@ -18,7 +18,7 @@ public function compile(DatabaseDialect $dialect): string $statement = $this->statement; if (! str($statement)->lower()->startsWith(['join', 'inner join', 'left join', 'right join', 'full join', 'full outer join', 'self join'])) { - $statement = sprintf('INNER JOIN %s', $statement); + return sprintf('INNER JOIN %s', $statement); } return $statement; diff --git a/packages/database/src/QueryStatements/ShowTablesStatement.php b/packages/database/src/QueryStatements/ShowTablesStatement.php index 23d79dd54b..c29826f743 100644 --- a/packages/database/src/QueryStatements/ShowTablesStatement.php +++ b/packages/database/src/QueryStatements/ShowTablesStatement.php @@ -23,11 +23,11 @@ public function compile(DatabaseDialect $dialect): string DatabaseDialect::MYSQL => "SHOW FULL TABLES WHERE table_type = 'BASE TABLE'", DatabaseDialect::SQLITE => "select type, name from sqlite_master where type = 'table' and name not like 'sqlite_%'", DatabaseDialect::POSTGRESQL => << $this->context ??= new RawSqlDatabaseContext($this->dialect); @@ -83,7 +85,7 @@ private function resolveBindingsForDisplay(): array continue; } - if ($serializer = $this->serializerFactory->in($this->context)->forValue($value)) { + if (($serializer = $this->serializerFactory->in($this->context)->forValue($value)) instanceof Serializer) { $bindings[$key] = $serializer->serialize($value); continue; } diff --git a/packages/database/src/Relation.php b/packages/database/src/Relation.php index c53139f0b5..ea40f63a6a 100644 --- a/packages/database/src/Relation.php +++ b/packages/database/src/Relation.php @@ -8,9 +8,7 @@ interface Relation extends PropertyAttribute { - public string $name { - get; - } + public string $name { get; } public function setParent(string $name): self; diff --git a/packages/database/src/Serializers/DataTransferObjectSerializer.php b/packages/database/src/Serializers/DataTransferObjectSerializer.php index a9aacf5f06..1b67d77560 100644 --- a/packages/database/src/Serializers/DataTransferObjectSerializer.php +++ b/packages/database/src/Serializers/DataTransferObjectSerializer.php @@ -34,13 +34,7 @@ public static function accepts(PropertyReflector|TypeReflector $type): bool : $type; if ($type->isUnion()) { - foreach ($type->split() as $memberType) { - if (static::accepts($memberType)) { - return true; - } - } - - return false; + return array_any($type->split(), fn ($memberType) => self::accepts($memberType)); } return $type->isClass() && $type->asClass()->getAttribute(SerializeAs::class) !== null; @@ -76,7 +70,7 @@ private function serializeWithType(mixed $input): mixed $data[$key] = $this->serializeWithType($value); } - $type = $this->mapperConfig->serializationMap[get_class($input)] ?? get_class($input); + $type = $this->mapperConfig->serializationMap[$input::class] ?? $input::class; return [ 'type' => $type, diff --git a/packages/database/src/Serializers/HashedSerializer.php b/packages/database/src/Serializers/HashedSerializer.php index b02ed9f07a..7791a29020 100644 --- a/packages/database/src/Serializers/HashedSerializer.php +++ b/packages/database/src/Serializers/HashedSerializer.php @@ -2,6 +2,7 @@ namespace Tempest\Database\Serializers; +use Tempest\Cryptography\Password\Hash; use Tempest\Cryptography\Password\PasswordHasher; use Tempest\Mapper\Exceptions\ValueCouldNotBeSerialized; use Tempest\Mapper\Serializer; @@ -18,7 +19,7 @@ public function serialize(mixed $input): string throw new ValueCouldNotBeSerialized('string'); } - if (! $this->passwordHasher->analyze($input)) { + if (! $this->passwordHasher->analyze($input) instanceof Hash) { return $this->passwordHasher->hash($input); } diff --git a/packages/database/src/Testing/DatabaseTester.php b/packages/database/src/Testing/DatabaseTester.php index 93d80430f1..4165258f73 100644 --- a/packages/database/src/Testing/DatabaseTester.php +++ b/packages/database/src/Testing/DatabaseTester.php @@ -46,7 +46,7 @@ public function migrate(string|object ...$migrationClasses): void { $migrationManager = $this->container->get(MigrationManager::class); - if (count($migrationClasses) === 0) { + if ($migrationClasses === []) { $migrationManager->up(); return; } diff --git a/packages/database/src/Uuid.php b/packages/database/src/Uuid.php index e93d7a9233..2087295e04 100644 --- a/packages/database/src/Uuid.php +++ b/packages/database/src/Uuid.php @@ -24,6 +24,4 @@ * ``` */ #[Attribute(Attribute::TARGET_PROPERTY)] -final readonly class Uuid -{ -} +final readonly class Uuid {} diff --git a/packages/database/src/Virtual.php b/packages/database/src/Virtual.php index 6d44eb7b66..1a314d41cf 100644 --- a/packages/database/src/Virtual.php +++ b/packages/database/src/Virtual.php @@ -10,6 +10,4 @@ * Virtual properties are ignored by the database mapper. */ #[Attribute(Attribute::TARGET_PROPERTY)] -final readonly class Virtual -{ -} +final readonly class Virtual {} diff --git a/packages/database/src/functions.php b/packages/database/src/functions.php index 73c135a175..423f932126 100644 --- a/packages/database/src/functions.php +++ b/packages/database/src/functions.php @@ -14,10 +14,7 @@ */ function query(string|object $model): QueryBuilder { - /** @var QueryBuilder $query */ - $query = new QueryBuilder($model); - - return $query; + return new QueryBuilder($model); } /** diff --git a/packages/database/tests/Config/DatabaseConfigTest.php b/packages/database/tests/Config/DatabaseConfigTest.php index 02df0a7223..ad7e54770a 100644 --- a/packages/database/tests/Config/DatabaseConfigTest.php +++ b/packages/database/tests/Config/DatabaseConfigTest.php @@ -76,8 +76,8 @@ public static function provide_database_drivers_with_options(): Generator { yield 'mysql with SSL' => [ new MysqlConfig( - certificateAuthority: '/etc/ssl/certs/ca-certificates.crt', persistent: true, + certificateAuthority: '/etc/ssl/certs/ca-certificates.crt', ), [ PDO::ATTR_PERSISTENT => true, @@ -87,8 +87,8 @@ public static function provide_database_drivers_with_options(): Generator yield 'mysql with all SSL options' => [ new MysqlConfig( - certificateAuthority: '/etc/ssl/certs/ca-certificates.crt', verifyServerCertificate: false, + certificateAuthority: '/etc/ssl/certs/ca-certificates.crt', clientCertificate: '/path/to/cert.pem', clientKey: '/path/to/key.pem', ), diff --git a/packages/database/tests/GenericDatabaseTest.php b/packages/database/tests/GenericDatabaseTest.php index ead08fdd67..b22cfd63c3 100644 --- a/packages/database/tests/GenericDatabaseTest.php +++ b/packages/database/tests/GenericDatabaseTest.php @@ -37,9 +37,7 @@ public function test_it_executes_transactions(): void new SerializerFactory(new GenericContainer()), ); - $result = $database->withinTransaction(function () { - return true; - }); + $result = $database->withinTransaction(fn () => true); $this->assertTrue($result); } diff --git a/packages/database/tests/Migrations/RunnableMigrationsTest.php b/packages/database/tests/Migrations/RunnableMigrationsTest.php index a15805d7f0..f53ef50331 100644 --- a/packages/database/tests/Migrations/RunnableMigrationsTest.php +++ b/packages/database/tests/Migrations/RunnableMigrationsTest.php @@ -18,7 +18,7 @@ final class RunnableMigrationsTest extends TestCase #[Test] public function migration_ordering(array $migrationNames, array $expectedOrder): void { - $migrations = array_map(fn (string $name) => $this->createDatabaseMigration($name), $migrationNames); + $migrations = array_map($this->createDatabaseMigration(...), $migrationNames); $this->assertSame( expected: $expectedOrder, diff --git a/packages/database/tests/QueryStatements/AlterTableStatementTest.php b/packages/database/tests/QueryStatements/AlterTableStatementTest.php index 5478773875..e06f14e6f5 100644 --- a/packages/database/tests/QueryStatements/AlterTableStatementTest.php +++ b/packages/database/tests/QueryStatements/AlterTableStatementTest.php @@ -35,12 +35,12 @@ public function test_alter_for_only_indexes(DatabaseDialect $dialect): void #[TestWith([DatabaseDialect::SQLITE])] public function test_alter_add_column(DatabaseDialect $dialect): void { - $expected = 'ALTER TABLE `table` ADD `bar` VARCHAR(42) DEFAULT \'xx\' ;'; + $expected = "ALTER TABLE `table` ADD `bar` VARCHAR(42) DEFAULT 'xx' ;"; $statement = new AlterTableStatement('table') ->add(new VarcharStatement('bar', 42, true, 'xx')) ->compile($dialect); - $normalized = self::removeDuplicateWhitespace($statement); + $normalized = $this->removeDuplicateWhitespace($statement); $this->assertEqualsIgnoringCase($expected, $normalized); } @@ -53,7 +53,7 @@ public function test_alter_add_belongs_to_mysql(DatabaseDialect $dialect): void ->add(new BelongsToStatement('table.foo', 'parent.bar')) ->compile($dialect); - $normalized = self::removeDuplicateWhitespace($statement); + $normalized = $this->removeDuplicateWhitespace($statement); $this->assertEqualsIgnoringCase($expected, $normalized); } @@ -66,7 +66,7 @@ public function test_alter_add_belongs_to_postgresql(DatabaseDialect $dialect): ->add(new BelongsToStatement('table.foo', 'parent.bar')) ->compile($dialect); - $normalized = self::removeDuplicateWhitespace($statement); + $normalized = $this->removeDuplicateWhitespace($statement); $this->assertEqualsIgnoringCase($expected, $normalized); } @@ -91,7 +91,7 @@ public function test_alter_table_drop_column(DatabaseDialect $dialect): void ->dropColumn('foo') ->compile($dialect); - $normalized = self::removeDuplicateWhitespace($statement); + $normalized = $this->removeDuplicateWhitespace($statement); $this->assertEqualsIgnoringCase($expected, $normalized); } @@ -104,7 +104,7 @@ public function test_alter_table_drop_constraint(DatabaseDialect $dialect, strin ->dropConstraint('foo') ->compile($dialect); - $normalized = self::removeDuplicateWhitespace($statement); + $normalized = $this->removeDuplicateWhitespace($statement); $this->assertEqualsIgnoringCase($expected, $normalized); } @@ -118,19 +118,19 @@ public function test_alter_table_drop_constraint_unsupported_dialects(DatabaseDi ->compile($dialect); } - #[TestWith([DatabaseDialect::MYSQL, 'ALTER TABLE `table` ADD `foo` VARCHAR(42) DEFAULT \'bar\' NOT NULL ;'])] + #[TestWith([DatabaseDialect::MYSQL, "ALTER TABLE `table` ADD `foo` VARCHAR(42) DEFAULT 'bar' NOT NULL ;"])] #[TestWith([ DatabaseDialect::POSTGRESQL, - 'ALTER TABLE `table` ADD `foo` VARCHAR(42) DEFAULT \'bar\' NOT NULL ;', + "ALTER TABLE `table` ADD `foo` VARCHAR(42) DEFAULT 'bar' NOT NULL ;", ])] - #[TestWith([DatabaseDialect::SQLITE, 'ALTER TABLE `table` ADD `foo` VARCHAR(42) DEFAULT \'bar\' NOT NULL ;'])] + #[TestWith([DatabaseDialect::SQLITE, "ALTER TABLE `table` ADD `foo` VARCHAR(42) DEFAULT 'bar' NOT NULL ;"])] public function test_alter_table_add_column(DatabaseDialect $dialect, string $expected): void { $statement = new AlterTableStatement('table') ->add(new VarcharStatement('foo', 42, false, 'bar')) ->compile($dialect); - $normalized = self::removeDuplicateWhitespace($statement); + $normalized = $this->removeDuplicateWhitespace($statement); $this->assertEqualsIgnoringCase($expected, $normalized); } @@ -145,20 +145,20 @@ public function test_alter_table_rename_column(DatabaseDialect $dialect): void ->rename('foo', 'bar') ->compile($dialect); - $normalized = self::removeDuplicateWhitespace($statement); + $normalized = $this->removeDuplicateWhitespace($statement); $this->assertEqualsIgnoringCase($expected, $normalized); } - #[TestWith([DatabaseDialect::MYSQL, 'ALTER TABLE `table` MODIFY COLUMN `foo` VARCHAR(42) DEFAULT \'bar\' NOT NULL ;'])] - #[TestWith([DatabaseDialect::POSTGRESQL, 'ALTER TABLE `table` ALTER COLUMN `foo` VARCHAR(42) DEFAULT \'bar\' NOT NULL ;'])] + #[TestWith([DatabaseDialect::MYSQL, "ALTER TABLE `table` MODIFY COLUMN `foo` VARCHAR(42) DEFAULT 'bar' NOT NULL ;"])] + #[TestWith([DatabaseDialect::POSTGRESQL, "ALTER TABLE `table` ALTER COLUMN `foo` VARCHAR(42) DEFAULT 'bar' NOT NULL ;"])] public function test_alter_table_modify_column(DatabaseDialect $dialect, string $expected): void { $statement = new AlterTableStatement('table') ->modify(new VarcharStatement('foo', 42, false, 'bar')) ->compile($dialect); - $normalized = self::removeDuplicateWhitespace($statement); + $normalized = $this->removeDuplicateWhitespace($statement); $this->assertEqualsIgnoringCase($expected, $normalized); } @@ -173,7 +173,7 @@ public function test_alter_table_modify_column_unsupported(DatabaseDialect $dial ->compile($dialect); } - private static function removeDuplicateWhitespace(string $string): string + private function removeDuplicateWhitespace(string $string): string { return trim(preg_replace('/(\n|\s)+/m', ' ', $string)); } diff --git a/packages/database/tests/QueryStatements/CreateTableStatementTest.php b/packages/database/tests/QueryStatements/CreateTableStatementTest.php index 9ae4eb9a8e..1c93557d63 100644 --- a/packages/database/tests/QueryStatements/CreateTableStatementTest.php +++ b/packages/database/tests/QueryStatements/CreateTableStatementTest.php @@ -36,31 +36,31 @@ public static function provide_create_table_database_dialects(): iterable yield 'mysql' => [ DatabaseDialect::MYSQL, << [ DatabaseDialect::POSTGRESQL, << [ DatabaseDialect::SQLITE, << [ DatabaseDialect::MYSQL, << [ DatabaseDialect::POSTGRESQL, << [ DatabaseDialect::SQLITE, << [ DatabaseDialect::MYSQL, << [ DatabaseDialect::POSTGRESQL, << [ DatabaseDialect::SQLITE, << [ DatabaseDialect::MYSQL, << [ DatabaseDialect::POSTGRESQL, << [ DatabaseDialect::SQLITE, << [ DatabaseDialect::MYSQL, << [ DatabaseDialect::POSTGRESQL, << [ DatabaseDialect::SQLITE, <<', $queryBuilder); diff --git a/packages/datetime/src/DateTime.php b/packages/datetime/src/DateTime.php index 830da8487d..bea06dfd00 100644 --- a/packages/datetime/src/DateTime.php +++ b/packages/datetime/src/DateTime.php @@ -5,7 +5,12 @@ namespace Tempest\DateTime; use DateTimeInterface as NativeDateTimeInterface; +use DateTimeZone; use IntlCalendar; +use Override; +use Tempest\DateTime\Exception\InvalidArgumentException; +use Tempest\DateTime\Exception\OverflowException; +use Tempest\DateTime\Exception\UnexpectedValueException; use Tempest\Intl\Locale; /** @@ -72,27 +77,27 @@ private function __construct( int $nanoseconds, ) { if ($nanoseconds < 0 || $nanoseconds >= NANOSECONDS_PER_SECOND) { - throw Exception\InvalidArgumentException::forNanoseconds($nanoseconds); + throw InvalidArgumentException::forNanoseconds($nanoseconds); } if ($seconds < 0 || $seconds >= 60) { - throw Exception\InvalidArgumentException::forSeconds($seconds); + throw InvalidArgumentException::forSeconds($seconds); } if ($minutes < 0 || $minutes >= 60) { - throw Exception\InvalidArgumentException::forMinutes($minutes); + throw InvalidArgumentException::forMinutes($minutes); } if ($hours < 0 || $hours >= 24) { - throw Exception\InvalidArgumentException::forHours($hours); + throw InvalidArgumentException::forHours($hours); } if ($month < 1 || $month > 12) { - throw Exception\InvalidArgumentException::forMonth($month); + throw InvalidArgumentException::forMonth($month); } if ($day < 1 || $day > 31 || $day > Month::from($month)->getDaysForYear($year)) { - throw Exception\InvalidArgumentException::forDay($day, $month, $year); + throw InvalidArgumentException::forDay($day, $month, $year); } $this->year = $year; @@ -179,34 +184,34 @@ public static function fromParts(Timezone $timezone, int $year, Month|int $month $calendarSeconds = $calendar->get(IntlCalendar::FIELD_SECOND); if ($calendarYear === false || $calendarMonth === false || $calendarDay === false || $calendarHours === false || $calendarMinutes === false || $calendarSeconds === false) { - throw new Exception\OverflowException(sprintf( + throw new OverflowException(sprintf( 'The year value "%d" exceeds the range supported by the calendar.', $year, )); } if ($seconds !== $calendarSeconds) { - throw Exception\UnexpectedValueException::forSeconds($seconds, $calendarSeconds); + throw UnexpectedValueException::forSeconds($seconds, $calendarSeconds); } if ($minutes !== $calendarMinutes) { - throw Exception\UnexpectedValueException::forMinutes($minutes, $calendarMinutes); + throw UnexpectedValueException::forMinutes($minutes, $calendarMinutes); } if ($hours !== $calendarHours) { - throw Exception\UnexpectedValueException::forHours($hours, $calendarHours); + throw UnexpectedValueException::forHours($hours, $calendarHours); } if ($day !== $calendarDay) { - throw Exception\UnexpectedValueException::forDay($day, $calendarDay); + throw UnexpectedValueException::forDay($day, $calendarDay); } if ($month !== ($calendarMonth + 1)) { - throw Exception\UnexpectedValueException::forMonth($month, $calendarMonth + 1); + throw UnexpectedValueException::forMonth($month, $calendarMonth + 1); } if ($year !== $calendarYear) { - throw Exception\UnexpectedValueException::forYear($year, $calendarYear); + throw UnexpectedValueException::forYear($year, $calendarYear); } $timestamp_in_seconds = (int) ($calendar->getTime() / (float) MILLISECONDS_PER_SECOND); @@ -223,7 +228,7 @@ public static function fromParts(Timezone $timezone, int $year, Month|int $month * * @see Timezone::default() */ - #[\Override] + #[Override] public static function fromTimestamp(int|Timestamp $timestamp, ?Timezone $timezone = null): static { $timezone ??= Timezone::default(); @@ -245,7 +250,7 @@ public static function fromTimestamp(int|Timestamp $timestamp, ?Timezone $timezo $second = $calendar->get(IntlCalendar::FIELD_SECOND); $nanoseconds = $timestamp->getNanoseconds(); - return new static($timezone, $timestamp, $year, $month, $day, $hour, $minute, $second, $nanoseconds); + return new self($timezone, $timestamp, $year, $month, $day, $hour, $minute, $second, $nanoseconds); } /** @@ -281,7 +286,7 @@ public static function parse(NativeDateTimeInterface|TemporalInterface|string|in return self::fromTimestamp( timestamp: Timestamp::fromParts($string->getTimestamp()), - timezone: $timezone ?? ($nativeTimezone instanceof \DateTimeZone ? Timezone::tryFrom($nativeTimezone->getName()) : null), + timezone: $timezone ?? ($nativeTimezone instanceof DateTimeZone ? Timezone::tryFrom($nativeTimezone->getName()) : null), ); } @@ -368,7 +373,7 @@ public static function fromString(string $rawString, ?DateStyle $dateStyle = nul /** * Returns the timestamp representation of this date time object. */ - #[\Override] + #[Override] public function getTimestamp(): Timestamp { return $this->timestamp; @@ -386,7 +391,7 @@ public function getTimestamp(): Timestamp * * @return int The year, formatted according to ISO-8601 standards, where 1 AD is 1, 1 BC is 0, 2 BC is -1, etc. */ - #[\Override] + #[Override] public function getYear(): int { return $this->year; @@ -397,7 +402,7 @@ public function getYear(): int * * @return int<1, 12> */ - #[\Override] + #[Override] public function getMonth(): int { return $this->month; @@ -408,7 +413,7 @@ public function getMonth(): int * * @return int<1, 31> */ - #[\Override] + #[Override] public function getDay(): int { return $this->day; @@ -419,7 +424,7 @@ public function getDay(): int * * @return int<0, 23> */ - #[\Override] + #[Override] public function getHours(): int { return $this->hours; @@ -430,7 +435,7 @@ public function getHours(): int * * @return int<0, 59> */ - #[\Override] + #[Override] public function getMinutes(): int { return $this->minutes; @@ -441,7 +446,7 @@ public function getMinutes(): int * * @return int<0, 59> */ - #[\Override] + #[Override] public function getSeconds(): int { return $this->seconds; @@ -452,7 +457,7 @@ public function getSeconds(): int * * @return int<0, 999999999> */ - #[\Override] + #[Override] public function getNanoseconds(): int { return $this->nanoseconds; @@ -461,7 +466,7 @@ public function getNanoseconds(): int /** * Gets the timezone associated with the date and time. */ - #[\Override] + #[Override] public function getTimezone(): Timezone { return $this->timezone; @@ -475,10 +480,10 @@ public function getTimezone(): Timezone * * @throws Exception\UnexpectedValueException If any of the provided date components do not align with calendar expectations. */ - #[\Override] + #[Override] public function withDate(int $year, Month|int $month, int $day): static { - return static::fromParts( + return self::fromParts( $this->timezone, $year, $month, @@ -500,10 +505,10 @@ public function withDate(int $year, Month|int $month, int $day): static * * @throws Exception\UnexpectedValueException If any of the provided time components do not align with calendar expectations. */ - #[\Override] + #[Override] public function withTime(int $hours, int $minutes, int $seconds = 0, int $nanoseconds = 0): static { - return static::fromParts( + return self::fromParts( $this->timezone, $this->year, $this->month, @@ -515,7 +520,7 @@ public function withTime(int $hours, int $minutes, int $seconds = 0, int $nanose ); } - #[\Override] + #[Override] public function jsonSerialize(): array { return [ diff --git a/packages/datetime/src/DateTimeConvenienceMethods.php b/packages/datetime/src/DateTimeConvenienceMethods.php index 24536f7eed..b1a50acbbe 100644 --- a/packages/datetime/src/DateTimeConvenienceMethods.php +++ b/packages/datetime/src/DateTimeConvenienceMethods.php @@ -4,6 +4,7 @@ namespace Tempest\DateTime; +use Override; use Tempest\Intl\Locale; use Tempest\Support\Math; @@ -61,10 +62,10 @@ public function isDaylightSavingTime(): bool * * @param null|Timezone $timezone The timezone to convert to. */ - #[\Override] + #[Override] public function convertToTimezone(?Timezone $timezone): static { - if ($timezone === null) { + if (! $timezone instanceof Timezone) { return $this; } @@ -925,7 +926,7 @@ public function isEndOfWeek(): bool * @see https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax * @see Locale::default() */ - #[\Override] + #[Override] public function format(null|FormatPattern|string $pattern = null, ?Timezone $timezone = null, ?Locale $locale = null): string { $timestamp = $this->getTimestamp(); @@ -964,7 +965,7 @@ public function format(null|FormatPattern|string $pattern = null, ?Timezone $tim * * @see https://datatracker.ietf.org/doc/html/rfc3339 */ - #[\Override] + #[Override] public function toRfc3339(?SecondsStyle $secondsStyle = null, bool $useZ = false): string { return namespace\format_rfc3339($this->getTimestamp(), $secondsStyle, $useZ, $this->getTimezone()); @@ -996,7 +997,7 @@ public function toRfc3339(?SecondsStyle $secondsStyle = null, bool $useZ = false * @see TimeStyle::default() * @see Locale::default() */ - #[\Override] + #[Override] public function toString( ?DateStyle $dateStyle = null, ?TimeStyle $timeStyle = null, diff --git a/packages/datetime/src/DateTimeInterface.php b/packages/datetime/src/DateTimeInterface.php index 069b9edce3..837693c98c 100644 --- a/packages/datetime/src/DateTimeInterface.php +++ b/packages/datetime/src/DateTimeInterface.php @@ -4,6 +4,7 @@ namespace Tempest\DateTime; +use Override; use Tempest\Intl\Locale; interface DateTimeInterface extends TemporalInterface @@ -633,7 +634,7 @@ public function isEndOfWeek(): bool; * @see https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax * @see Locale::default() */ - #[\Override] + #[Override] public function format(null|FormatPattern|string $pattern = null, ?Timezone $timezone = null, ?Locale $locale = null): string; /** @@ -662,7 +663,7 @@ public function format(null|FormatPattern|string $pattern = null, ?Timezone $tim * @see TimeStyle::default() * @see Locale::default() */ - #[\Override] + #[Override] public function toString(?DateStyle $dateStyle = null, ?TimeStyle $timeStyle = null, ?Timezone $timezone = null, ?Locale $locale = null): string; /** @@ -690,7 +691,7 @@ public function toString(?DateStyle $dateStyle = null, ?TimeStyle $timeStyle = n * * @see https://datatracker.ietf.org/doc/html/rfc3339 */ - #[\Override] + #[Override] public function toRfc3339(?SecondsStyle $secondsStyle = null, bool $useZ = false): string; /** @@ -709,7 +710,7 @@ public function toRfc3339(?SecondsStyle $secondsStyle = null, bool $useZ = false * * @see TemporalInterface::toString() */ - #[\Override] + #[Override] public function __toString(): string; /** @@ -717,6 +718,6 @@ public function __toString(): string; * * @param null|Timezone $timezone The timezone to convert to. */ - #[\Override] + #[Override] public function convertToTimezone(?Timezone $timezone): static; } diff --git a/packages/datetime/src/Duration.php b/packages/datetime/src/Duration.php index 8badb32ae9..21aba22c76 100644 --- a/packages/datetime/src/Duration.php +++ b/packages/datetime/src/Duration.php @@ -5,8 +5,12 @@ namespace Tempest\DateTime; use JsonSerializable; +use Override; use Stringable; use Tempest\Support\Comparison; +use Tempest\Support\Comparison\Comparable; +use Tempest\Support\Comparison\Equable; +use Tempest\Support\Comparison\Order; use Tempest\Support\Str; /** @@ -23,7 +27,7 @@ * @implements Comparison\Comparable * @implements Comparison\Equable */ -final readonly class Duration implements Comparison\Comparable, Comparison\Equable, JsonSerializable, Stringable +final readonly class Duration implements Comparable, Equable, JsonSerializable, Stringable { /** * Initializes a new instance of Duration with specified hours, minutes, seconds, and nanoseconds. @@ -405,22 +409,22 @@ public function withNanoseconds(int $nanoseconds): self * * @param Duration $other */ - #[\Override] - public function compare(mixed $other): Comparison\Order + #[Override] + public function compare(mixed $other): Order { if ($this->hours !== $other->hours) { - return Comparison\Order::from($this->hours <=> $other->hours); + return Order::from($this->hours <=> $other->hours); } if ($this->minutes !== $other->minutes) { - return Comparison\Order::from($this->minutes <=> $other->minutes); + return Order::from($this->minutes <=> $other->minutes); } if ($this->seconds !== $other->seconds) { - return Comparison\Order::from($this->seconds <=> $other->seconds); + return Order::from($this->seconds <=> $other->seconds); } - return Comparison\Order::from($this->nanoseconds <=> $other->nanoseconds); + return Order::from($this->nanoseconds <=> $other->nanoseconds); } /** @@ -428,10 +432,10 @@ public function compare(mixed $other): Comparison\Order * * @param Duration $other */ - #[\Override] + #[Override] public function equals(mixed $other): bool { - return $this->compare($other) === Comparison\Order::EQUAL; + return $this->compare($other) === Order::EQUAL; } /** @@ -439,7 +443,7 @@ public function equals(mixed $other): bool */ public function shorter(self $other): bool { - return $this->compare($other) === Comparison\Order::LESS; + return $this->compare($other) === Order::LESS; } /** @@ -447,7 +451,7 @@ public function shorter(self $other): bool */ public function shorterOrEqual(self $other): bool { - return $this->compare($other) !== Comparison\Order::GREATER; + return $this->compare($other) !== Order::GREATER; } /** @@ -455,7 +459,7 @@ public function shorterOrEqual(self $other): bool */ public function longer(self $other): bool { - return $this->compare($other) === Comparison\Order::GREATER; + return $this->compare($other) === Order::GREATER; } /** @@ -463,7 +467,7 @@ public function longer(self $other): bool */ public function longerOrEqual(self $other): bool { - return $this->compare($other) !== Comparison\Order::LESS; + return $this->compare($other) !== Order::LESS; } /** @@ -477,7 +481,7 @@ public function betweenInclusive(self $a, self $b): bool $ca = $this->compare($a); $cb = $this->compare($b); - return $ca === Comparison\Order::EQUAL || $ca !== $cb; + return $ca === Order::EQUAL || $ca !== $cb; } /** @@ -491,7 +495,7 @@ public function betweenExclusive(self $a, self $b): bool $ca = $this->compare($a); $cb = $this->compare($b); - return $ca !== Comparison\Order::EQUAL && $cb !== Comparison\Order::EQUAL && $ca !== $cb; + return $ca !== Order::EQUAL && $cb !== Order::EQUAL && $ca !== $cb; } /** @@ -613,7 +617,7 @@ public function toString(int $max_decimals = 3): string /** * Returns a string representation of the time duration. */ - #[\Override] + #[Override] public function __toString(): string { return $this->toString(); @@ -624,7 +628,7 @@ public function __toString(): string * * @return array{hours: int, minutes: int, seconds: int, nanoseconds: int} */ - #[\Override] + #[Override] public function jsonSerialize(): array { return [ diff --git a/packages/datetime/src/Exception/DateTimeException.php b/packages/datetime/src/Exception/DateTimeException.php index f2a011621e..465fb7fad8 100644 --- a/packages/datetime/src/Exception/DateTimeException.php +++ b/packages/datetime/src/Exception/DateTimeException.php @@ -4,6 +4,4 @@ namespace Tempest\DateTime\Exception; -interface DateTimeException -{ -} +interface DateTimeException {} diff --git a/packages/datetime/src/Exception/OverflowException.php b/packages/datetime/src/Exception/OverflowException.php index 889ff5d0c1..aac737522a 100644 --- a/packages/datetime/src/Exception/OverflowException.php +++ b/packages/datetime/src/Exception/OverflowException.php @@ -6,6 +6,4 @@ use OverflowException as PhpOverflowException; -final class OverflowException extends PhpOverflowException implements DateTimeException -{ -} +final class OverflowException extends PhpOverflowException implements DateTimeException {} diff --git a/packages/datetime/src/Exception/ParserException.php b/packages/datetime/src/Exception/ParserException.php index 1993916519..62edddb612 100644 --- a/packages/datetime/src/Exception/ParserException.php +++ b/packages/datetime/src/Exception/ParserException.php @@ -4,6 +4,4 @@ namespace Tempest\DateTime\Exception; -final class ParserException extends RuntimeException -{ -} +final class ParserException extends RuntimeException {} diff --git a/packages/datetime/src/Exception/RuntimeException.php b/packages/datetime/src/Exception/RuntimeException.php index a3228748af..709ce27edb 100644 --- a/packages/datetime/src/Exception/RuntimeException.php +++ b/packages/datetime/src/Exception/RuntimeException.php @@ -7,6 +7,4 @@ use RuntimeException as PhpRuntimeException; // @phpstan-ignore-next-line -class RuntimeException extends PhpRuntimeException implements DateTimeException -{ -} +class RuntimeException extends PhpRuntimeException implements DateTimeException {} diff --git a/packages/datetime/src/Exception/UnderflowException.php b/packages/datetime/src/Exception/UnderflowException.php index a299869665..87b6c29362 100644 --- a/packages/datetime/src/Exception/UnderflowException.php +++ b/packages/datetime/src/Exception/UnderflowException.php @@ -6,6 +6,4 @@ use UnderflowException as PhpUnderflowException; -final class UnderflowException extends PhpUnderflowException implements DateTimeException -{ -} +final class UnderflowException extends PhpUnderflowException implements DateTimeException {} diff --git a/packages/datetime/src/SecondsStyle.php b/packages/datetime/src/SecondsStyle.php index ed6bb914aa..5b2b82540b 100644 --- a/packages/datetime/src/SecondsStyle.php +++ b/packages/datetime/src/SecondsStyle.php @@ -38,7 +38,7 @@ public static function fromTimestamp(Timestamp $timestamp): SecondsStyle return match (true) { $nanoseconds === 0 => static::Seconds, - ($nanoseconds % 1000000) === 0 => static::Milliseconds, + ($nanoseconds % 1_000_000) === 0 => static::Milliseconds, ($nanoseconds % 1000) === 0 => static::Microseconds, default => static::Nanoseconds, }; diff --git a/packages/datetime/src/TemporalConvenienceMethods.php b/packages/datetime/src/TemporalConvenienceMethods.php index e024805030..99eae1d9c3 100644 --- a/packages/datetime/src/TemporalConvenienceMethods.php +++ b/packages/datetime/src/TemporalConvenienceMethods.php @@ -6,6 +6,7 @@ use DateTimeImmutable as NativeDateTimeImmutable; use DateTimeInterface as NativeDateTimeInterface; +use Override; use Tempest\Intl\Locale; use Tempest\Support\Comparison; use Tempest\Support\Comparison\Order; @@ -33,7 +34,7 @@ public function compare(mixed $other): Order $a = $this->getTimestamp()->toParts(); $b = $other->getTimestamp()->toParts(); - return Comparison\Order::from($a[0] !== $b[0] ? $a[0] <=> $b[0] : $a[1] <=> $b[1]); + return Order::from($a[0] !== $b[0] ? $a[0] <=> $b[0] : $a[1] <=> $b[1]); } /** @@ -59,7 +60,7 @@ public function atTheSameTime(TemporalInterface|string $other): bool $other = DateTime::parse($other); } - return $this->compare($other) === Comparison\Order::EQUAL; + return $this->compare($other) === Order::EQUAL; } /** @@ -67,7 +68,7 @@ public function atTheSameTime(TemporalInterface|string $other): bool */ public function before(TemporalInterface $other): bool { - return $this->compare($other) === Comparison\Order::LESS; + return $this->compare($other) === Order::LESS; } /** @@ -75,7 +76,7 @@ public function before(TemporalInterface $other): bool */ public function beforeOrAtTheSameTime(TemporalInterface $other): bool { - return $this->compare($other) !== Comparison\Order::GREATER; + return $this->compare($other) !== Order::GREATER; } /** @@ -83,7 +84,7 @@ public function beforeOrAtTheSameTime(TemporalInterface $other): bool */ public function after(TemporalInterface $other): bool { - return $this->compare($other) === Comparison\Order::GREATER; + return $this->compare($other) === Order::GREATER; } /** @@ -91,7 +92,7 @@ public function after(TemporalInterface $other): bool */ public function afterOrAtTheSameTime(TemporalInterface $other): bool { - return $this->compare($other) !== Comparison\Order::LESS; + return $this->compare($other) !== Order::LESS; } /** @@ -102,7 +103,7 @@ public function betweenTimeInclusive(TemporalInterface $a, TemporalInterface $b) $ca = $this->compare($a); $cb = $this->compare($b); - return $ca === Comparison\Order::EQUAL || $ca !== $cb; + return $ca === Order::EQUAL || $ca !== $cb; } /** @@ -113,7 +114,7 @@ public function betweenTimeExclusive(TemporalInterface $a, TemporalInterface $b) $ca = $this->compare($a); $cb = $this->compare($b); - return $ca !== Comparison\Order::EQUAL && $cb !== Comparison\Order::EQUAL && $ca !== $cb; + return $ca !== Order::EQUAL && $cb !== Order::EQUAL && $ca !== $cb; } /** @@ -549,7 +550,7 @@ public function toString(?DateStyle $dateStyle = null, ?TimeStyle $timeStyle = n * * @see TemporalInterface::toString() */ - #[\Override] + #[Override] public function __toString(): string { return $this->toString(); diff --git a/packages/datetime/src/TemporalInterface.php b/packages/datetime/src/TemporalInterface.php index 2e0c16d11e..3b2c573d9d 100644 --- a/packages/datetime/src/TemporalInterface.php +++ b/packages/datetime/src/TemporalInterface.php @@ -6,6 +6,7 @@ use DateTimeInterface as NativeDateTimeInterface; use JsonSerializable; +use Override; use Stringable; use Tempest\Intl\Locale; use Tempest\Support\Comparison\Comparable; @@ -35,7 +36,7 @@ public function getTimestamp(): Timestamp; * * @param TemporalInterface $other */ - #[\Override] + #[Override] public function compare(mixed $other): Order; /** @@ -45,7 +46,7 @@ public function compare(mixed $other): Order; * * @param TemporalInterface|string $other */ - #[\Override] + #[Override] public function equals(mixed $other): bool; /** @@ -419,7 +420,7 @@ public function toString(?DateStyle $dateStyle = null, ?TimeStyle $timeStyle = n * * @see TemporalInterface::toString() */ - #[\Override] + #[Override] public function __toString(): string; /** diff --git a/packages/datetime/src/Timestamp.php b/packages/datetime/src/Timestamp.php index a7ac0bb198..a49d7b2f40 100644 --- a/packages/datetime/src/Timestamp.php +++ b/packages/datetime/src/Timestamp.php @@ -4,8 +4,11 @@ namespace Tempest\DateTime; +use Override; use Tempest\Clock\Clock; use Tempest\Container\GenericContainer; +use Tempest\DateTime\Exception\OverflowException; +use Tempest\DateTime\Exception\UnderflowException; use Tempest\Intl\Locale; use Tempest\Support\Math; use Tempest\Support\Math\Exception\ArithmeticException; @@ -46,11 +49,11 @@ public static function fromParts(int $seconds, int $nanoseconds = 0): Timestamp { // Check for potential overflow or underflow before doing any operation if ($seconds === Math\INT64_MAX && $nanoseconds >= NANOSECONDS_PER_SECOND) { - throw new Exception\OverflowException('Adding nanoseconds would cause an overflow.'); + throw new OverflowException('Adding nanoseconds would cause an overflow.'); } if ($seconds === Math\INT64_MIN && $nanoseconds <= -NANOSECONDS_PER_SECOND) { - throw new Exception\UnderflowException('Subtracting nanoseconds would cause an underflow.'); + throw new UnderflowException('Subtracting nanoseconds would cause an underflow.'); } $seconds_adjustment = Math\div($nanoseconds, NANOSECONDS_PER_SECOND); @@ -170,7 +173,7 @@ public static function fromString(string $rawString, ?DateStyle $dateStyle = nul /** * Returns this Timestamp instance itself, as it already represents a timestamp. */ - #[\Override] + #[Override] public function getTimestamp(): self { return $this; @@ -224,7 +227,7 @@ public function getNanoseconds(): int * @throws Exception\UnderflowException If adding the duration results in an arithmetic underflow. * @throws Exception\OverflowException If adding the duration results in an arithmetic overflow. */ - #[\Override] + #[Override] public function plus(Duration $duration): static { [$h, $m, $s, $ns] = $duration->getParts(); @@ -242,7 +245,7 @@ public function plus(Duration $duration): static * @throws Exception\UnderflowException If subtracting the duration results in an arithmetic underflow. * @throws Exception\OverflowException If subtracting the duration results in an arithmetic overflow. */ - #[\Override] + #[Override] public function minus(Duration $duration): static { [$h, $m, $s, $ns] = $duration->getParts(); @@ -273,7 +276,7 @@ private static function resolveFromContainer(): ?Timestamp ->timestamp(); } - #[\Override] + #[Override] public function jsonSerialize(): array { return [ diff --git a/packages/datetime/src/functions.php b/packages/datetime/src/functions.php index 63233bcf7d..40f83707ba 100644 --- a/packages/datetime/src/functions.php +++ b/packages/datetime/src/functions.php @@ -6,14 +6,8 @@ use IntlDateFormatter; use IntlTimeZone; use RuntimeException; -use Tempest\DateTime\DateStyle; use Tempest\DateTime\Exception\OverflowException; use Tempest\DateTime\Exception\ParserException; -use Tempest\DateTime\FormatPattern; -use Tempest\DateTime\SecondsStyle; -use Tempest\DateTime\Timestamp; -use Tempest\DateTime\TimeStyle; -use Tempest\DateTime\Timezone; use Tempest\Intl\Locale; use ValueError; @@ -21,8 +15,6 @@ use function microtime; use function Tempest\Intl\current_locale; -use const Tempest\DateTime\NANOSECONDS_PER_SECOND; - /** * Get the current date and time as a {@see \Tempest\DateTime\DateTime} object. */ @@ -51,7 +43,7 @@ function format_rfc3339(Timestamp $timestamp, ?SecondsStyle $secondsStyle = null { $secondsStyle ??= SecondsStyle::fromTimestamp($timestamp); - if (null === $timezone) { + if (! $timezone instanceof Timezone) { $timezone = Timezone::UTC; } elseif ($useZ) { $useZ = Timezone::UTC === $timezone; @@ -159,7 +151,7 @@ function high_resolution_time(): array $offset = hrtime(); if ($offset === false) { // @phpstan-ignore-line identical.alwaysFalse - throw new \RuntimeException('The system does not provide a monotonic timer.'); + throw new RuntimeException('The system does not provide a monotonic timer.'); } $time = system_time(); @@ -252,7 +244,7 @@ function to_intl_timezone(Timezone $timezone): IntlTimeZone $tz = IntlTimeZone::createTimeZone($value); if ($tz === null) { // @phpstan-ignore-line identical.alwaysFalse - throw new \RuntimeException(sprintf( + throw new RuntimeException(sprintf( 'Failed to create intl timezone from timezone "%s" ("%s" / "%s").', $timezone->name, $timezone->value, @@ -261,7 +253,7 @@ function to_intl_timezone(Timezone $timezone): IntlTimeZone } if ($tz->getID() === 'Etc/Unknown' && $tz->getRawOffset() === 0) { - throw new \RuntimeException(sprintf( + throw new RuntimeException(sprintf( 'Failed to create a valid intl timezone, unknown timezone "%s" ("%s" / "%s") given.', $timezone->name, $timezone->value, diff --git a/packages/datetime/tests/DateTimeTest.php b/packages/datetime/tests/DateTimeTest.php index ba74285734..26f1342e57 100644 --- a/packages/datetime/tests/DateTimeTest.php +++ b/packages/datetime/tests/DateTimeTest.php @@ -242,13 +242,13 @@ public function test_parse_icu(): void $parsed = DateTime::fromPattern('2025-01-01 10:00', pattern: 'yyyy-MM-dd HH:mm'); $this->assertEquals('2025-01-01 10:00', $parsed->format(pattern: 'yyyy-MM-dd HH:mm')); - $this->assertEquals(1735725600, $parsed->getTimestamp()->getSeconds()); + $this->assertEquals(1_735_725_600, $parsed->getTimestamp()->getSeconds()); } public function test_parse_timestamp(): void { - $expected = DateTime::fromTimestamp(1747670452940); - $parsed = DateTime::parse(1747670452940); + $expected = DateTime::fromTimestamp(1_747_670_452_940); + $parsed = DateTime::parse(1_747_670_452_940); $this->assertEquals($expected->getTimestamp(), $parsed->getTimestamp()); $this->assertSame($expected->getTimezone(), $parsed->getTimezone()); @@ -629,7 +629,7 @@ public function test_end_of_day(): void $this->assertSame(23, $new->getHours()); $this->assertSame(59, $new->getMinutes()); $this->assertSame(59, $new->getSeconds()); - $this->assertSame(999999999, $new->getNanoseconds()); + $this->assertSame(999_999_999, $new->getNanoseconds()); } public function test_start_of_week(): void @@ -696,7 +696,7 @@ public function test_convert_time_zone(): void public function test_is_same_year(): void { $date1 = DateTime::fromParts(Timezone::default(), 2024, Month::JANUARY, 1, 12, 0, 0, 0); - $date2 = DateTime::fromParts(Timezone::default(), 2024, Month::DECEMBER, 31, 23, 59, 59, 999999999); + $date2 = DateTime::fromParts(Timezone::default(), 2024, Month::DECEMBER, 31, 23, 59, 59, 999_999_999); $date3 = DateTime::fromParts(Timezone::default(), 2025, Month::JANUARY, 1, 0, 0, 0, 0); $this->assertTrue($date1->isSameYear($date2)); @@ -707,7 +707,7 @@ public function test_is_same_year(): void public function test_is_same_month(): void { $date1 = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 1, 12, 0, 0, 0); - $date2 = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 29, 23, 59, 59, 999999999); + $date2 = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 29, 23, 59, 59, 999_999_999); $date3 = DateTime::fromParts(Timezone::default(), 2024, Month::MARCH, 1, 0, 0, 0, 0); $date4 = DateTime::fromParts(Timezone::default(), 2025, Month::FEBRUARY, 15, 12, 0, 0, 0); @@ -733,7 +733,7 @@ public function test_is_same_week(): void public function test_is_same_day(): void { $morning = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 5, 8, 30, 0, 0); - $evening = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 5, 20, 45, 30, 123456789); + $evening = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 5, 20, 45, 30, 123_456_789); $nextDay = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 6, 8, 30, 0, 0); $this->assertTrue($morning->isSameDay($evening)); @@ -744,7 +744,7 @@ public function test_is_same_day(): void public function test_is_same_hour(): void { $time1 = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 5, 14, 15, 30, 0); - $time2 = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 5, 14, 45, 59, 999999999); + $time2 = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 5, 14, 45, 59, 999_999_999); $time3 = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 5, 15, 15, 30, 0); $differentDay = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 6, 14, 15, 30, 0); @@ -757,7 +757,7 @@ public function test_is_same_hour(): void public function test_is_same_minute(): void { $time1 = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 5, 14, 30, 15, 0); - $time2 = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 5, 14, 30, 45, 999999999); + $time2 = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 5, 14, 30, 45, 999_999_999); $time3 = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 5, 14, 31, 15, 0); $differentHour = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 5, 15, 30, 15, 0); @@ -770,7 +770,7 @@ public function test_is_same_minute(): void public function test_is_next_day(): void { $today = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 5, 12, 0, 0, 0); - $tomorrow = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 6, 15, 30, 45, 123456789); + $tomorrow = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 6, 15, 30, 45, 123_456_789); $dayAfterTomorrow = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 7, 8, 0, 0, 0); $this->assertTrue($tomorrow->isNextDay($today)); @@ -782,7 +782,7 @@ public function test_is_next_day(): void public function test_is_previous_day(): void { $today = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 5, 12, 0, 0, 0); - $yesterday = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 4, 8, 15, 30, 987654321); + $yesterday = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 4, 8, 15, 30, 987_654_321); $dayBeforeYesterday = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 3, 20, 0, 0, 0); $this->assertTrue($yesterday->isPreviousDay($today)); @@ -846,9 +846,9 @@ public function test_is_last_day_of_month(): void public function test_is_first_day_of_year(): void { $newYearsDay = DateTime::fromParts(Timezone::default(), 2024, Month::JANUARY, 1, 0, 0, 0, 0); - $newYearsDayDifferentTime = DateTime::fromParts(Timezone::default(), 2024, Month::JANUARY, 1, 23, 59, 59, 999999999); + $newYearsDayDifferentTime = DateTime::fromParts(Timezone::default(), 2024, Month::JANUARY, 1, 23, 59, 59, 999_999_999); $secondDay = DateTime::fromParts(Timezone::default(), 2024, Month::JANUARY, 2, 0, 0, 0, 0); - $december31 = DateTime::fromParts(Timezone::default(), 2023, Month::DECEMBER, 31, 23, 59, 59, 999999999); + $december31 = DateTime::fromParts(Timezone::default(), 2023, Month::DECEMBER, 31, 23, 59, 59, 999_999_999); $this->assertTrue($newYearsDay->isFirstDayOfYear()); $this->assertTrue($newYearsDayDifferentTime->isFirstDayOfYear()); @@ -859,8 +859,8 @@ public function test_is_first_day_of_year(): void public function test_is_last_day_of_year(): void { $december31 = DateTime::fromParts(Timezone::default(), 2024, Month::DECEMBER, 31, 0, 0, 0, 0); - $december31DifferentTime = DateTime::fromParts(Timezone::default(), 2024, Month::DECEMBER, 31, 23, 59, 59, 999999999); - $december30 = DateTime::fromParts(Timezone::default(), 2024, Month::DECEMBER, 30, 23, 59, 59, 999999999); + $december31DifferentTime = DateTime::fromParts(Timezone::default(), 2024, Month::DECEMBER, 31, 23, 59, 59, 999_999_999); + $december30 = DateTime::fromParts(Timezone::default(), 2024, Month::DECEMBER, 30, 23, 59, 59, 999_999_999); $january1 = DateTime::fromParts(Timezone::default(), 2025, Month::JANUARY, 1, 0, 0, 0, 0); $this->assertTrue($december31->isLastDayOfYear()); @@ -917,13 +917,13 @@ public function test_time_of_day_methods(): void public function test_time_edge_cases(): void { - $boundary5_59 = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 5, 5, 59, 59, 999999999); + $boundary5_59 = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 5, 5, 59, 59, 999_999_999); $boundary6_00 = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 5, 6, 0, 0, 0); - $boundary11_59 = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 5, 11, 59, 59, 999999999); + $boundary11_59 = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 5, 11, 59, 59, 999_999_999); $boundary12_00 = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 5, 12, 0, 0, 0); - $boundary17_59 = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 5, 17, 59, 59, 999999999); + $boundary17_59 = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 5, 17, 59, 59, 999_999_999); $boundary18_00 = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 5, 18, 0, 0, 0); - $boundary21_59 = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 5, 21, 59, 59, 999999999); + $boundary21_59 = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 5, 21, 59, 59, 999_999_999); $boundary22_00 = DateTime::fromParts(Timezone::default(), 2024, Month::FEBRUARY, 5, 22, 0, 0, 0); $this->assertTrue($boundary5_59->isNight()); diff --git a/packages/datetime/tests/DurationTest.php b/packages/datetime/tests/DurationTest.php index 7d58f9929c..053de5a5cb 100644 --- a/packages/datetime/tests/DurationTest.php +++ b/packages/datetime/tests/DurationTest.php @@ -8,6 +8,7 @@ use PHPUnit\Framework\Attributes\TestWith; use PHPUnit\Framework\TestCase; use Tempest\DateTime; +use Tempest\DateTime\Duration; use Tempest\Support\Comparison\Order; use Tempest\Support\Json; @@ -20,7 +21,7 @@ final class DurationTest extends TestCase public function test_getters(): void { - $t = DateTime\Duration::fromParts(1, 2, 3, 4); + $t = Duration::fromParts(1, 2, 3, 4); $this->assertSame(1, $t->getHours()); $this->assertSame(2, $t->getMinutes()); @@ -31,30 +32,30 @@ public function test_getters(): void public function test_named_constructors(): void { - $this->assertSame(168.0, DateTime\Duration::weeks(1)->getTotalHours()); - $this->assertSame(168.0, DateTime\Duration::week()->getTotalHours()); - $this->assertSame(24.0, DateTime\Duration::days(1)->getTotalHours()); - $this->assertSame(24.0, DateTime\Duration::day()->getTotalHours()); - $this->assertSame(1.0, DateTime\Duration::hours(1)->getTotalHours()); - $this->assertSame(1.0, DateTime\Duration::hour()->getTotalHours()); - $this->assertSame(1.0, DateTime\Duration::minutes(1)->getTotalMinutes()); - $this->assertSame(1.0, DateTime\Duration::minute()->getTotalMinutes()); - $this->assertSame(1.0, DateTime\Duration::seconds(1)->getTotalSeconds()); - $this->assertSame(1.0, DateTime\Duration::second()->getTotalSeconds()); - $this->assertSame(1.0, DateTime\Duration::milliseconds(1)->getTotalMilliseconds()); - $this->assertSame(1.0, DateTime\Duration::microseconds(1)->getTotalMicroseconds()); - $this->assertSame(1, DateTime\Duration::nanoseconds(1)->getNanoseconds()); - $this->assertSame(0.0, DateTime\Duration::zero()->getTotalSeconds()); + $this->assertSame(168.0, Duration::weeks(1)->getTotalHours()); + $this->assertSame(168.0, Duration::week()->getTotalHours()); + $this->assertSame(24.0, Duration::days(1)->getTotalHours()); + $this->assertSame(24.0, Duration::day()->getTotalHours()); + $this->assertSame(1.0, Duration::hours(1)->getTotalHours()); + $this->assertSame(1.0, Duration::hour()->getTotalHours()); + $this->assertSame(1.0, Duration::minutes(1)->getTotalMinutes()); + $this->assertSame(1.0, Duration::minute()->getTotalMinutes()); + $this->assertSame(1.0, Duration::seconds(1)->getTotalSeconds()); + $this->assertSame(1.0, Duration::second()->getTotalSeconds()); + $this->assertSame(1.0, Duration::milliseconds(1)->getTotalMilliseconds()); + $this->assertSame(1.0, Duration::microseconds(1)->getTotalMicroseconds()); + $this->assertSame(1, Duration::nanoseconds(1)->getNanoseconds()); + $this->assertSame(0.0, Duration::zero()->getTotalSeconds()); } #[TestWith([0, 0, 0, 0, 0.0])] - #[TestWith([0, 0, 0, 1, 2.777777777777778E-13])] + #[TestWith([0, 0, 0, 1, 2.777_777_777_777_778E-13])] #[TestWith([1, 0, 0, 0, 1.0])] #[TestWith([1, 30, 0, 0, 1.5])] - #[TestWith([2, 15, 30, 0, 2.2583333333333333])] + #[TestWith([2, 15, 30, 0, 2.258_333_333_333_333_3])] #[TestWith([-1, 0, 0, 0, -1.0])] #[TestWith([-1, -30, 0, 0, -1.5])] - #[TestWith([-2, -15, -30, 0, -2.2583333333333333])] + #[TestWith([-2, -15, -30, 0, -2.258_333_333_333_333_3])] public function test_get_total_hours( int $hours, int $minutes, @@ -62,12 +63,12 @@ public function test_get_total_hours( int $nanoseconds, float $expectedHours, ): void { - $time = DateTime\Duration::fromParts($hours, $minutes, $seconds, $nanoseconds); + $time = Duration::fromParts($hours, $minutes, $seconds, $nanoseconds); $this->assertSame($expectedHours, $time->getTotalHours()); } #[TestWith([0, 0, 0, 0, 0.0])] - #[TestWith([0, 0, 0, 1, 1.6666666666666667E-11])] + #[TestWith([0, 0, 0, 1, 1.666_666_666_666_666_7E-11])] #[TestWith([1, 0, 0, 0, 60.0])] #[TestWith([1, 30, 0, 0, 90.0])] #[TestWith([2, 15, 30, 0, 135.5])] @@ -76,12 +77,12 @@ public function test_get_total_hours( #[TestWith([-2, -15, -30, 0, -135.5])] public function test_get_total_minutes(int $hours, int $minutes, int $seconds, int $nanoseconds, float $expectedMinutes): void { - $time = DateTime\Duration::fromParts($hours, $minutes, $seconds, $nanoseconds); + $time = Duration::fromParts($hours, $minutes, $seconds, $nanoseconds); $this->assertSame($expectedMinutes, $time->getTotalMinutes()); } #[TestWith([0, 0, 0, 0, 0.0])] - #[TestWith([0, 0, 0, 1, 0.000000001])] + #[TestWith([0, 0, 0, 1, 0.000_000_001])] #[TestWith([1, 0, 0, 0, 3600.0])] #[TestWith([1, 30, 0, 0, 5400.0])] #[TestWith([2, 15, 30, 0, 8130.0])] @@ -90,41 +91,41 @@ public function test_get_total_minutes(int $hours, int $minutes, int $seconds, i #[TestWith([-2, -15, -30, 0, -8130.0])] public function test_get_total_seconds(int $hours, int $minutes, int $seconds, int $nanoseconds, float $expectedSeconds): void { - $time = DateTime\Duration::fromParts($hours, $minutes, $seconds, $nanoseconds); + $time = Duration::fromParts($hours, $minutes, $seconds, $nanoseconds); $this->assertSame($expectedSeconds, $time->getTotalSeconds()); } #[TestWith([0, 0, 0, 0, 0.0])] - #[TestWith([0, 0, 0, 1, 0.000001])] - #[TestWith([1, 0, 0, 0, 3600000.0])] - #[TestWith([1, 30, 0, 0, 5400000.0])] - #[TestWith([2, 15, 30, 0, 8130000.0])] - #[TestWith([-1, 0, 0, 0, -3600000.0])] - #[TestWith([-1, -30, 0, 0, -5400000.0])] - #[TestWith([-2, -15, -30, 0, -8130000.0])] + #[TestWith([0, 0, 0, 1, 0.000_001])] + #[TestWith([1, 0, 0, 0, 3_600_000.0])] + #[TestWith([1, 30, 0, 0, 5_400_000.0])] + #[TestWith([2, 15, 30, 0, 8_130_000.0])] + #[TestWith([-1, 0, 0, 0, -3_600_000.0])] + #[TestWith([-1, -30, 0, 0, -5_400_000.0])] + #[TestWith([-2, -15, -30, 0, -8_130_000.0])] public function test_get_total_milliseconds(int $hours, int $minutes, int $seconds, int $nanoseconds, float $expectedMilliseconds): void { - $time = DateTime\Duration::fromParts($hours, $minutes, $seconds, $nanoseconds); + $time = Duration::fromParts($hours, $minutes, $seconds, $nanoseconds); $this->assertSame($expectedMilliseconds, $time->getTotalMilliseconds()); } #[TestWith([0, 0, 0, 0, 0.0])] #[TestWith([0, 0, 0, 1, 0.001])] - #[TestWith([1, 0, 0, 0, 3600000000.0])] - #[TestWith([1, 30, 0, 0, 5400000000.0])] - #[TestWith([2, 15, 30, 0, 8130000000.0])] - #[TestWith([-1, 0, 0, 0, -3600000000.0])] - #[TestWith([-1, -30, 0, 0, -5400000000.0])] - #[TestWith([-2, -15, -30, 0, -8130000000.0])] + #[TestWith([1, 0, 0, 0, 3_600_000_000.0])] + #[TestWith([1, 30, 0, 0, 5_400_000_000.0])] + #[TestWith([2, 15, 30, 0, 8_130_000_000.0])] + #[TestWith([-1, 0, 0, 0, -3_600_000_000.0])] + #[TestWith([-1, -30, 0, 0, -5_400_000_000.0])] + #[TestWith([-2, -15, -30, 0, -8_130_000_000.0])] public function test_get_total_microseconds(int $hours, int $minutes, int $seconds, int $nanoseconds, float $expectedMicroseconds): void { - $time = DateTime\Duration::fromParts($hours, $minutes, $seconds, $nanoseconds); + $time = Duration::fromParts($hours, $minutes, $seconds, $nanoseconds); $this->assertSame($expectedMicroseconds, $time->getTotalMicroseconds()); } public function test_setters(): void { - $t = DateTime\Duration::fromParts(1, 2, 3, 4); + $t = Duration::fromParts(1, 2, 3, 4); $this->assertSame([42, 2, 3, 4], $t->withHours(42)->getParts()); $this->assertSame([1, 42, 3, 4], $t->withMinutes(42)->getParts()); @@ -138,16 +139,16 @@ public function test_setters(): void public function test_fractions_of_second(): void { - $this->assertSame([0, 0, 0, 0], DateTime\Duration::zero()->getParts()); - $this->assertSame([0, 0, 0, 42], DateTime\Duration::nanoseconds(42)->getParts()); + $this->assertSame([0, 0, 0, 0], Duration::zero()->getParts()); + $this->assertSame([0, 0, 0, 42], Duration::nanoseconds(42)->getParts()); $this->assertSame( [0, 0, 1, 42], - DateTime\Duration::nanoseconds(DateTime\NANOSECONDS_PER_SECOND + 42)->getParts(), + Duration::nanoseconds(DateTime\NANOSECONDS_PER_SECOND + 42)->getParts(), ); - $this->assertSame([0, 0, 0, 42000], DateTime\Duration::microseconds(42)->getParts()); - $this->assertSame([0, 0, 1, 42000], DateTime\Duration::microseconds(1000042)->getParts()); - $this->assertSame([0, 0, 0, 42000000], DateTime\Duration::milliseconds(42)->getParts()); - $this->assertSame([0, 0, 1, 42000000], DateTime\Duration::milliseconds(1042)->getParts()); + $this->assertSame([0, 0, 0, 42_000], Duration::microseconds(42)->getParts()); + $this->assertSame([0, 0, 1, 42_000], Duration::microseconds(1_000_042)->getParts()); + $this->assertSame([0, 0, 0, 42_000_000], Duration::milliseconds(42)->getParts()); + $this->assertSame([0, 0, 1, 42_000_000], Duration::milliseconds(1042)->getParts()); } #[TestWith([0, 0, 0, 0])] @@ -164,22 +165,22 @@ public function test_normalized(int $input_s, int $input_ns, int $normalized_s, { $this->assertSame( [0, 0, $normalized_s, $normalized_ns], - DateTime\Duration::fromParts(0, 0, $input_s, $input_ns)->getParts(), + Duration::fromParts(0, 0, $input_s, $input_ns)->getParts(), ); } public function test_normalized_hms(): void { - $this->assertSame([3, 5, 4, 0], DateTime\Duration::fromParts(2, 63, 124)->getParts()); - $this->assertSame([0, 59, 4, 0], DateTime\Duration::fromParts(2, -63, 124)->getParts()); + $this->assertSame([3, 5, 4, 0], Duration::fromParts(2, 63, 124)->getParts()); + $this->assertSame([0, 59, 4, 0], Duration::fromParts(2, -63, 124)->getParts()); $this->assertSame( [-1, 0, -55, -(DateTime\NANOSECONDS_PER_SECOND - 42)], - DateTime\Duration::fromParts(0, -63, 124, 42)->getParts(), + Duration::fromParts(0, -63, 124, 42)->getParts(), ); - $this->assertSame([42, 0, 0, 0], DateTime\Duration::hours(42)->getParts()); - $this->assertSame([1, 3, 0, 0], DateTime\Duration::minutes(63)->getParts()); - $this->assertSame([0, -1, -3, 0], DateTime\Duration::seconds(-63)->getParts()); - $this->assertSame([0, 0, -1, 0], DateTime\Duration::nanoseconds(-DateTime\NANOSECONDS_PER_SECOND)->getParts()); + $this->assertSame([42, 0, 0, 0], Duration::hours(42)->getParts()); + $this->assertSame([1, 3, 0, 0], Duration::minutes(63)->getParts()); + $this->assertSame([0, -1, -3, 0], Duration::seconds(-63)->getParts()); + $this->assertSame([0, 0, -1, 0], Duration::nanoseconds(-DateTime\NANOSECONDS_PER_SECOND)->getParts()); } #[TestWith([0, 0, 0, 0, 0])] @@ -188,7 +189,7 @@ public function test_normalized_hms(): void #[TestWith([1, -63, 0, 0, -1])] public function test_positive_negative(int $h, int $m, int $s, int $ns, int $expected_sign): void { - $t = DateTime\Duration::fromParts($h, $m, $s, $ns); + $t = Duration::fromParts($h, $m, $s, $ns); $this->assertSame($expected_sign === 0, $t->isZero()); $this->assertSame($expected_sign === 1, $t->isPositive()); $this->assertSame($expected_sign === -1, $t->isNegative()); @@ -200,17 +201,17 @@ public function test_positive_negative(int $h, int $m, int $s, int $ns, int $exp public static function provide_compare_data(): array { return [ - [DateTime\Duration::seconds(20), DateTime\Duration::seconds(10), Order::GREATER], - [DateTime\Duration::seconds(10), DateTime\Duration::seconds(20), Order::LESS], - [DateTime\Duration::seconds(10), DateTime\Duration::seconds(10), Order::EQUAL], - [DateTime\Duration::hours(1), DateTime\Duration::minutes(42), Order::GREATER], - [DateTime\Duration::minutes(2), DateTime\Duration::seconds(120), Order::EQUAL], - [DateTime\Duration::zero(), DateTime\Duration::nanoseconds(1), Order::LESS], + [Duration::seconds(20), Duration::seconds(10), Order::GREATER], + [Duration::seconds(10), Duration::seconds(20), Order::LESS], + [Duration::seconds(10), Duration::seconds(10), Order::EQUAL], + [Duration::hours(1), Duration::minutes(42), Order::GREATER], + [Duration::minutes(2), Duration::seconds(120), Order::EQUAL], + [Duration::zero(), Duration::nanoseconds(1), Order::LESS], ]; } #[DataProvider('provide_compare_data')] - public function test_compare(DateTime\Duration $a, DateTime\Duration $b, Order $expected): void + public function test_compare(Duration $a, Duration $b, Order $expected): void { $opposite = Order::from(-$expected->value); @@ -233,9 +234,9 @@ public function test_compare(DateTime\Duration $a, DateTime\Duration $b, Order $ public function test_is_between(): void { - $a = DateTime\Duration::hours(1); - $b = DateTime\Duration::minutes(64); - $c = DateTime\Duration::fromParts(1, 30); + $a = Duration::hours(1); + $b = Duration::minutes(64); + $c = Duration::fromParts(1, 30); $this->assertTrue($b->betweenExclusive($a, $c)); $this->assertTrue($b->betweenExclusive($c, $a)); $this->assertTrue($b->betweenInclusive($a, $c)); @@ -248,9 +249,9 @@ public function test_is_between(): void public function test_operations(): void { - $z = DateTime\Duration::zero(); - $a = DateTime\Duration::fromParts(0, 2, 25); - $b = DateTime\Duration::fromParts(0, 0, -63, 42); + $z = Duration::zero(); + $a = Duration::fromParts(0, 2, 25); + $b = Duration::fromParts(0, 0, -63, 42); $this->assertSame([0, 0, 0, 0], $z->invert()->getParts()); $this->assertSame([0, -2, -25, 0], $a->invert()->getParts()); $this->assertSame([0, 1, 2, DateTime\NANOSECONDS_PER_SECOND - 42], $b->invert()->getParts()); @@ -271,23 +272,23 @@ public function test_operations(): void #[TestWith([0, 0, 0, 0, '0 second(s)'])] #[TestWith([0, 0, 0, 42, '0 second(s)'])] #[TestWith([0, 0, 1, 42, '1 second(s)'])] - #[TestWith([0, 0, 1, 20000000, '1.02 second(s)'])] + #[TestWith([0, 0, 1, 20_000_000, '1.02 second(s)'])] #[TestWith([1, 2, 0, 0, '1 hour(s), 2 minute(s)'])] #[TestWith([1, 0, 3, 0, '1 hour(s), 0 minute(s), 3 second(s)'])] #[TestWith([0, 2, 3, 0, '2 minute(s), 3 second(s)'])] #[TestWith([1, 2, 3, 0, '1 hour(s), 2 minute(s), 3 second(s)'])] - #[TestWith([1, 0, 0, 42000000, '1 hour(s), 0 minute(s), 0.042 second(s)'])] + #[TestWith([1, 0, 0, 42_000_000, '1 hour(s), 0 minute(s), 0.042 second(s)'])] #[TestWith([-42, 0, -42, 0, '-42 hour(s), 0 minute(s), -42 second(s)'])] - #[TestWith([-42, 0, -42, -420000000, '-42 hour(s), 0 minute(s), -42.42 second(s)'])] - #[TestWith([0, 0, 0, -420000000, '-0.42 second(s)'])] + #[TestWith([-42, 0, -42, -420_000_000, '-42 hour(s), 0 minute(s), -42.42 second(s)'])] + #[TestWith([0, 0, 0, -420_000_000, '-0.42 second(s)'])] public function test_to_string(int $h, int $m, int $s, int $ns, string $expected): void { - $this->assertSame($expected, DateTime\Duration::fromParts($h, $m, $s, $ns)->toString()); + $this->assertSame($expected, Duration::fromParts($h, $m, $s, $ns)->toString()); } public function test_serialization(): void { - $timeInterval = DateTime\Duration::fromParts(1, 30, 45, 500000000); + $timeInterval = Duration::fromParts(1, 30, 45, 500_000_000); $serialized = serialize($timeInterval); $deserialized = unserialize($serialized); @@ -296,10 +297,10 @@ public function test_serialization(): void public function test_json_encoding(): void { - $timeInterval = DateTime\Duration::fromParts(1, 30, 45, 500000000); + $timeInterval = Duration::fromParts(1, 30, 45, 500_000_000); $jsonEncoded = Json\encode($timeInterval); $jsonDecoded = Json\decode($jsonEncoded, associative: true); - $this->assertSame(['hours' => 1, 'minutes' => 30, 'seconds' => 45, 'nanoseconds' => 500000000], $jsonDecoded); + $this->assertSame(['hours' => 1, 'minutes' => 30, 'seconds' => 45, 'nanoseconds' => 500_000_000], $jsonDecoded); } } diff --git a/packages/datetime/tests/SecondsStyleTest.php b/packages/datetime/tests/SecondsStyleTest.php index a0efa3c9f1..b2c092dbbf 100644 --- a/packages/datetime/tests/SecondsStyleTest.php +++ b/packages/datetime/tests/SecondsStyleTest.php @@ -23,7 +23,7 @@ public static function provide_from_timestamp_data(): array { return [ [SecondsStyle::Seconds, Timestamp::fromParts(0)], - [SecondsStyle::Milliseconds, Timestamp::fromParts(0, 1000000)], + [SecondsStyle::Milliseconds, Timestamp::fromParts(0, 1_000_000)], [SecondsStyle::Microseconds, Timestamp::fromParts(0, 1000)], [SecondsStyle::Nanoseconds, Timestamp::fromParts(0, 1)], ]; diff --git a/packages/datetime/tests/TimestampTest.php b/packages/datetime/tests/TimestampTest.php index 297abff2a5..42ba40ed50 100644 --- a/packages/datetime/tests/TimestampTest.php +++ b/packages/datetime/tests/TimestampTest.php @@ -144,50 +144,50 @@ public function test_parse_fails(): void public static function provide_format_parsing_data(): iterable { yield [ - 1711917897, + 1_711_917_897, FormatPattern::FULL_DATE_TIME, Timezone::UTC, Locale::ENGLISH, 'Sunday, March 31, 2024 20:44:57', ]; yield [ - 1711917897, + 1_711_917_897, FormatPattern::FULL_DATE_TIME, Timezone::ASIA_SHANGHAI, Locale::CHINESE_TRADITIONAL, '星期一, 4月 01, 2024 04:44:57', ]; yield [ - 1711917897, + 1_711_917_897, FormatPattern::COOKIE, Timezone::AMERICA_NEW_YORK, Locale::ENGLISH_UNITED_STATES, 'Sunday, 31-Mar-2024 16:44:57 EDT', ]; yield [ - 1711917897, + 1_711_917_897, FormatPattern::HTTP, Timezone::EUROPE_VIENNA, Locale::GERMAN_AUSTRIA, 'So., 31 März 2024 22:44:57 MESZ', ]; yield [ - 1711917897, + 1_711_917_897, FormatPattern::EMAIL, Timezone::EUROPE_MADRID, Locale::SPANISH_SPAIN, 'dom, 31 mar 2024 22:44:57 GMT+02:00', ]; yield [ - 1711917897, + 1_711_917_897, FormatPattern::SQL_DATE_TIME, Timezone::AFRICA_TUNIS, Locale::ARABIC_TUNISIA, '2024-03-31 21:44:57', ]; - yield [1711832400, FormatPattern::ISO_ORDINAL_DATE, Timezone::EUROPE_MOSCOW, Locale::RUSSIAN_RUSSIA, '2024-091']; + yield [1_711_832_400, FormatPattern::ISO_ORDINAL_DATE, Timezone::EUROPE_MOSCOW, Locale::RUSSIAN_RUSSIA, '2024-091']; yield [ - 1711917897, + 1_711_917_897, FormatPattern::ISO8601, Timezone::EUROPE_LONDON, Locale::ENGLISH_UNITED_KINGDOM, @@ -444,15 +444,15 @@ public function test_convert_to_timezone(): void public function test_json_serialization(): void { - $serialized = Timestamp::fromParts(1711917232, 12)->jsonSerialize(); + $serialized = Timestamp::fromParts(1_711_917_232, 12)->jsonSerialize(); - $this->assertSame(1711917232, $serialized['seconds']); + $this->assertSame(1_711_917_232, $serialized['seconds']); $this->assertSame(12, $serialized['nanoseconds']); } public function test_to_rfc3999(): void { - $timestamp = Timestamp::fromParts(1711917232, 12); + $timestamp = Timestamp::fromParts(1_711_917_232, 12); $this->assertSame('2024-03-31T20:33:52.12+00:00', $timestamp->toRfc3339()); $this->assertSame('2024-03-31T20:33:52+00:00', $timestamp->toRfc3339(secondsStyle: SecondsStyle::Seconds)); @@ -494,9 +494,9 @@ public function test_temporal_convenience_methods(): void public function test_at_the_same_time_edge_cases(): void { - $timestamp1 = Timestamp::fromParts(1234567890, 123456789); - $timestamp2 = Timestamp::fromParts(1234567890, 123456789); - $timestamp3 = Timestamp::fromParts(1234567890, 123456790); + $timestamp1 = Timestamp::fromParts(1_234_567_890, 123_456_789); + $timestamp2 = Timestamp::fromParts(1_234_567_890, 123_456_789); + $timestamp3 = Timestamp::fromParts(1_234_567_890, 123_456_790); $this->assertTrue($timestamp1->atTheSameTime($timestamp2)); $this->assertFalse($timestamp1->atTheSameTime($timestamp3)); @@ -547,9 +547,9 @@ public function test_between_time_reversed_parameters(): void public function test_nano_precision_temporal_comparisons(): void { - $base = Timestamp::fromParts(1234567890, 0); - $plusOneNano = Timestamp::fromParts(1234567890, 1); - $minusOneNano = Timestamp::fromParts(1234567889, 999999999); + $base = Timestamp::fromParts(1_234_567_890, 0); + $plusOneNano = Timestamp::fromParts(1_234_567_890, 1); + $minusOneNano = Timestamp::fromParts(1_234_567_889, 999_999_999); $this->assertTrue($base->isAfter($minusOneNano)); $this->assertTrue($base->isBefore($plusOneNano)); @@ -592,20 +592,20 @@ public function test_future_past_comprehensive(): void public function test_since_and_between_duration_methods(): void { - $start = Timestamp::fromParts(1000, 500000000); - $end = Timestamp::fromParts(1005, 750000000); + $start = Timestamp::fromParts(1000, 500_000_000); + $end = Timestamp::fromParts(1005, 750_000_000); $duration = $end->since($start); $this->assertSame(5, $duration->getSeconds()); - $this->assertSame(250000000, $duration->getNanoseconds()); + $this->assertSame(250_000_000, $duration->getNanoseconds()); $reverseDuration = $start->since($end); $this->assertSame(-5, $reverseDuration->getSeconds()); - $this->assertSame(-250000000, $reverseDuration->getNanoseconds()); + $this->assertSame(-250_000_000, $reverseDuration->getNanoseconds()); $betweenDuration = $start->between($end); $this->assertSame(-5, $betweenDuration->getSeconds()); - $this->assertSame(-250000000, $betweenDuration->getNanoseconds()); + $this->assertSame(-250_000_000, $betweenDuration->getNanoseconds()); $sameDuration = $start->since($start); $this->assertSame(0, $sameDuration->getSeconds()); @@ -614,8 +614,8 @@ public function test_since_and_between_duration_methods(): void public function test_temporal_comparison_with_large_values(): void { - $large1 = Timestamp::fromParts(9223372036, 999999999); - $large2 = Timestamp::fromParts(9223372036, 999999998); + $large1 = Timestamp::fromParts(9_223_372_036, 999_999_999); + $large2 = Timestamp::fromParts(9_223_372_036, 999_999_998); $this->assertTrue($large1->isAfter($large2)); $this->assertFalse($large1->isBefore($large2)); @@ -626,8 +626,8 @@ public function test_temporal_comparison_with_large_values(): void public function test_temporal_comparison_edge_case_overflow_boundary(): void { - $maxSeconds = Timestamp::fromParts(9223372036854775806, 0); - $nearMax = Timestamp::fromParts(9223372036854775805, 999999999); + $maxSeconds = Timestamp::fromParts(9_223_372_036_854_775_806, 0); + $nearMax = Timestamp::fromParts(9_223_372_036_854_775_805, 999_999_999); $this->assertTrue($maxSeconds->isAfter($nearMax)); $this->assertFalse($maxSeconds->isBefore($nearMax)); diff --git a/packages/datetime/tests/TimezoneTest.php b/packages/datetime/tests/TimezoneTest.php index 526e83a48e..73d8ebca18 100644 --- a/packages/datetime/tests/TimezoneTest.php +++ b/packages/datetime/tests/TimezoneTest.php @@ -24,13 +24,13 @@ public function test_default(): void public function test_get_offset(): void { - $temporal = Timestamp::fromParts(seconds: 1716956903); + $temporal = Timestamp::fromParts(seconds: 1_716_956_903); $this->assertSame(3600., Timezone::EUROPE_LONDON->getOffset($temporal)->getTotalSeconds()); - $this->assertSame(-14400., Timezone::AMERICA_NEW_YORK->getOffset($temporal)->getTotalSeconds()); - $this->assertSame(28800., Timezone::ASIA_SHANGHAI->getOffset($temporal)->getTotalSeconds()); - $this->assertSame(12600., Timezone::PLUS_0330->getOffset($temporal)->getTotalSeconds()); - $this->assertSame(-12600., Timezone::MINUS_0330->getOffset($temporal)->getTotalSeconds()); + $this->assertSame(-14_400., Timezone::AMERICA_NEW_YORK->getOffset($temporal)->getTotalSeconds()); + $this->assertSame(28_800., Timezone::ASIA_SHANGHAI->getOffset($temporal)->getTotalSeconds()); + $this->assertSame(12_600., Timezone::PLUS_0330->getOffset($temporal)->getTotalSeconds()); + $this->assertSame(-12_600., Timezone::MINUS_0330->getOffset($temporal)->getTotalSeconds()); $this->assertSame(3600., Timezone::PLUS_0100->getOffset($temporal)->getTotalSeconds()); $this->assertSame(-3600., Timezone::MINUS_0100->getOffset($temporal)->getTotalSeconds()); @@ -45,8 +45,8 @@ public function test_get_offset(): void } #[TestWith([Timezone::EUROPE_LONDON, 0])] - #[TestWith([Timezone::AMERICA_NEW_YORK, -18000])] - #[TestWith([Timezone::ASIA_SHANGHAI, 28800])] + #[TestWith([Timezone::AMERICA_NEW_YORK, -18_000])] + #[TestWith([Timezone::ASIA_SHANGHAI, 28_800])] public function test_raw_offset(Timezone $timezone, int $expected): void { $this->assertSame($expected, (int) $timezone->getRawOffset()->getTotalSeconds()); diff --git a/packages/debug/src/Debug.php b/packages/debug/src/Debug.php index cd17c4ef24..4899fb2f0d 100644 --- a/packages/debug/src/Debug.php +++ b/packages/debug/src/Debug.php @@ -97,16 +97,16 @@ private function writeToOut(array $items, string $callPath): void echo vsprintf( <<%s (%s) - HTML, + %s (%s) + HTML, [ 'Source Code Pro, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace', $key, diff --git a/packages/debug/src/DebugConfig.php b/packages/debug/src/DebugConfig.php index 11cc9fad50..b7b47682fc 100644 --- a/packages/debug/src/DebugConfig.php +++ b/packages/debug/src/DebugConfig.php @@ -2,12 +2,12 @@ namespace Tempest\Debug; -final class DebugConfig +final readonly class DebugConfig { /** * @param string $logPath The file path where debug logs will be written. */ public function __construct( - public readonly string $logPath, + public string $logPath, ) {} } diff --git a/packages/debug/src/Stacktrace/Frame.php b/packages/debug/src/Stacktrace/Frame.php index 95592f4508..8d86f24a1e 100644 --- a/packages/debug/src/Stacktrace/Frame.php +++ b/packages/debug/src/Stacktrace/Frame.php @@ -7,6 +7,7 @@ use ReflectionFunction; use ReflectionMethod; use ReflectionParameter; +use Throwable; use function Tempest\Support\Path\to_relative_path; @@ -74,7 +75,7 @@ public static function extractArguments(array $frame): array callback: fn (ReflectionParameter $param) => $param->getName(), array: $reflection->getParameters(), ); - } catch (\Throwable) { + } catch (Throwable) { // @mago-expect lint:no-empty-catch-clause } diff --git a/packages/debug/src/TailDebugCommand.php b/packages/debug/src/TailDebugCommand.php index 98397faa71..8c94fe550d 100644 --- a/packages/debug/src/TailDebugCommand.php +++ b/packages/debug/src/TailDebugCommand.php @@ -21,7 +21,7 @@ public function __invoke(bool $clear = true): void { $debugLogPath = $this->debugConfig->logPath; - if (! $debugLogPath) { + if ($debugLogPath === '' || $debugLogPath === '0') { $this->console->error('No debug log configured in DebugConfig.'); return; diff --git a/packages/debug/src/functions.php b/packages/debug/src/functions.php index 3aa00a0cdd..a9e75f1f62 100644 --- a/packages/debug/src/functions.php +++ b/packages/debug/src/functions.php @@ -45,7 +45,7 @@ function ll(mixed ...$input): void */ function le(mixed ...$input): void { - Debug::resolve()->log($input, writeToOut: false, writeToLog: false); + Debug::resolve()->log($input, writeToLog: false, writeToOut: false); } } diff --git a/packages/debug/tests/StacktraceTest.php b/packages/debug/tests/StacktraceTest.php index 6edf46f7be..5e78c6afdb 100644 --- a/packages/debug/tests/StacktraceTest.php +++ b/packages/debug/tests/StacktraceTest.php @@ -213,9 +213,11 @@ public function stacktrace_uses_root_path_for_vendor_detection(): void $this->assertNotEmpty($frames); foreach ($frames as $frame) { - if (str_starts_with($frame->absoluteFile, $rootPath)) { - $this->assertFalse($frame->isVendor); + if (! str_starts_with($frame->absoluteFile, $rootPath)) { + continue; } + + $this->assertFalse($frame->isVendor); } } diff --git a/packages/discovery/src/Commands/MakeDiscoveryCommand.php b/packages/discovery/src/Commands/MakeDiscoveryCommand.php index ddbb812957..48d5369220 100644 --- a/packages/discovery/src/Commands/MakeDiscoveryCommand.php +++ b/packages/discovery/src/Commands/MakeDiscoveryCommand.php @@ -12,7 +12,7 @@ use Tempest\Generation\Php\ClassManipulator; use Tempest\Generation\Php\DataObjects\StubFile; -if (class_exists(\Tempest\Console\ConsoleCommand::class)) { +if (class_exists(ConsoleCommand::class)) { final class MakeDiscoveryCommand { use PublishesFiles; diff --git a/packages/discovery/src/DiscoveryLocation.php b/packages/discovery/src/DiscoveryLocation.php index 13dd3c8b35..84b33b4946 100644 --- a/packages/discovery/src/DiscoveryLocation.php +++ b/packages/discovery/src/DiscoveryLocation.php @@ -9,7 +9,6 @@ final class DiscoveryLocation { - public readonly string $namespace; public readonly string $path; public string $key { @@ -17,10 +16,9 @@ final class DiscoveryLocation } public function __construct( - string $namespace, + public readonly string $namespace, string $path, ) { - $this->namespace = $namespace; $this->path = Filesystem\normalize_path(rtrim($path, '\\/')); } diff --git a/packages/event-bus/src/StopsPropagation.php b/packages/event-bus/src/StopsPropagation.php index ac3241e036..a296547f93 100644 --- a/packages/event-bus/src/StopsPropagation.php +++ b/packages/event-bus/src/StopsPropagation.php @@ -5,6 +5,4 @@ use Attribute; #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)] -final readonly class StopsPropagation -{ -} +final readonly class StopsPropagation {} diff --git a/packages/event-bus/src/Testing/EventBusTester.php b/packages/event-bus/src/Testing/EventBusTester.php index 668e4651b0..383a7af975 100644 --- a/packages/event-bus/src/Testing/EventBusTester.php +++ b/packages/event-bus/src/Testing/EventBusTester.php @@ -62,7 +62,7 @@ public function assertDispatched(string|object $event, ?Closure $callback = null Assert::assertCount($count, $dispatches, 'The number of dispatches does not match.'); } - if ($callback !== null) { + if ($callback instanceof Closure) { foreach ($dispatches as $dispatch) { Assert::assertNotFalse($callback($dispatch), 'The callback failed.'); } @@ -111,11 +111,7 @@ private function findDispatches(string|object $event): array return true; } - if (class_exists($event) && $dispatched instanceof $event) { - return true; - } - - return false; + return class_exists($event) && $dispatched instanceof $event; }); } diff --git a/packages/event-bus/src/functions.php b/packages/event-bus/src/functions.php index 3869d85c16..01a7064ad1 100644 --- a/packages/event-bus/src/functions.php +++ b/packages/event-bus/src/functions.php @@ -6,8 +6,6 @@ use Closure; use Tempest\Container; -use Tempest\EventBus\EventBus; -use Tempest\EventBus\EventBusConfig; /** * Dispatches the given `$event`, triggering all associated event listeners. diff --git a/packages/event-bus/tests/Fixtures/EventInterface.php b/packages/event-bus/tests/Fixtures/EventInterface.php index 0cfc74c279..1be6844569 100644 --- a/packages/event-bus/tests/Fixtures/EventInterface.php +++ b/packages/event-bus/tests/Fixtures/EventInterface.php @@ -4,6 +4,4 @@ namespace Tempest\EventBus\Tests\Fixtures; -interface EventInterface -{ -} +interface EventInterface {} diff --git a/packages/event-bus/tests/Fixtures/EventInterfaceImplementation.php b/packages/event-bus/tests/Fixtures/EventInterfaceImplementation.php index 9b9fa79210..8f56d225d0 100644 --- a/packages/event-bus/tests/Fixtures/EventInterfaceImplementation.php +++ b/packages/event-bus/tests/Fixtures/EventInterfaceImplementation.php @@ -4,6 +4,4 @@ namespace Tempest\EventBus\Tests\Fixtures; -final readonly class EventInterfaceImplementation implements EventInterface -{ -} +final readonly class EventInterfaceImplementation implements EventInterface {} diff --git a/packages/event-bus/tests/Fixtures/ItHappened.php b/packages/event-bus/tests/Fixtures/ItHappened.php index 37fcd827c5..2dd32f315b 100644 --- a/packages/event-bus/tests/Fixtures/ItHappened.php +++ b/packages/event-bus/tests/Fixtures/ItHappened.php @@ -4,6 +4,4 @@ namespace Tempest\EventBus\Tests\Fixtures; -final readonly class ItHappened -{ -} +final readonly class ItHappened {} diff --git a/packages/generation/src/Php/Exceptions/FileGenerationException.php b/packages/generation/src/Php/Exceptions/FileGenerationException.php index 6c9e18f780..00d8bac3f5 100644 --- a/packages/generation/src/Php/Exceptions/FileGenerationException.php +++ b/packages/generation/src/Php/Exceptions/FileGenerationException.php @@ -4,6 +4,4 @@ namespace Tempest\Generation\Php\Exceptions; -interface FileGenerationException -{ -} +interface FileGenerationException {} diff --git a/packages/generation/src/Php/Exceptions/FileGenerationWasAborted.php b/packages/generation/src/Php/Exceptions/FileGenerationWasAborted.php index 1e30044329..9a08bb47e9 100644 --- a/packages/generation/src/Php/Exceptions/FileGenerationWasAborted.php +++ b/packages/generation/src/Php/Exceptions/FileGenerationWasAborted.php @@ -6,6 +6,4 @@ use Exception; -final class FileGenerationWasAborted extends Exception implements FileGenerationException -{ -} +final class FileGenerationWasAborted extends Exception implements FileGenerationException {} diff --git a/packages/generation/src/Php/ManipulatesPhpClasses.php b/packages/generation/src/Php/ManipulatesPhpClasses.php index c4eeea3e81..fb9e1221f5 100644 --- a/packages/generation/src/Php/ManipulatesPhpClasses.php +++ b/packages/generation/src/Php/ManipulatesPhpClasses.php @@ -89,9 +89,11 @@ public function removeClassAttribute(string $attributeName): self $attributes = $this->classType->getAttributes(); foreach ($attributes as $key => $attribute) { - if ($attribute->getName() === $attributeName) { - unset($attributes[$key]); + if ($attribute->getName() !== $attributeName) { + continue; } + + unset($attributes[$key]); } $this->classType->setAttributes($attributes); diff --git a/packages/generation/src/Php/SimplifiesClassNames.php b/packages/generation/src/Php/SimplifiesClassNames.php index 20aff5779d..acd890ba57 100644 --- a/packages/generation/src/Php/SimplifiesClassNames.php +++ b/packages/generation/src/Php/SimplifiesClassNames.php @@ -136,9 +136,11 @@ function ($param) use (&$types): void { } foreach ($type->getTypes() as $subtype) { - if ($subtype->isClass() && ! $subtype->isClassKeyword()) { - $namespace->addUse((string) $subtype); + if (! ($subtype->isClass() && ! $subtype->isClassKeyword())) { + continue; } + + $namespace->addUse((string) $subtype); } } } diff --git a/packages/generation/src/Php/StubFileGenerator.php b/packages/generation/src/Php/StubFileGenerator.php index 61a7e0fee9..32fac0ba85 100644 --- a/packages/generation/src/Php/StubFileGenerator.php +++ b/packages/generation/src/Php/StubFileGenerator.php @@ -8,7 +8,6 @@ use Tempest\Generation\Php\DataObjects\StubFile; use Tempest\Generation\Php\Exceptions\FileGenerationFailedException; use Tempest\Generation\Php\Exceptions\FileGenerationWasAborted; -use Tempest\Generation\Php\StubFileType; use Tempest\Support\Filesystem; use Tempest\Support\Str\ImmutableString; use Throwable; @@ -82,7 +81,7 @@ public function generateClassFile( $classManipulator->save($targetPath); } catch (Throwable $throwable) { - throw new FileGenerationFailedException(sprintf('The file could not be written. %s', $throwable->getMessage())); + throw new FileGenerationFailedException(sprintf('The file could not be written. %s', $throwable->getMessage()), $throwable->getCode(), $throwable); } } @@ -129,8 +128,8 @@ public function generateRawFile( // Run all manipulations $fileContent = array_reduce( array: $manipulations, - initial: $fileContent, callback: fn (ImmutableString $content, Closure $manipulation) => $manipulation($content), + initial: $fileContent, ); if (Filesystem\is_file($targetPath) && $shouldOverride) { @@ -139,7 +138,7 @@ public function generateRawFile( Filesystem\write_file($targetPath, $fileContent); } catch (Throwable $throwable) { - throw new FileGenerationFailedException(sprintf('The file could not be written. %s', $throwable->getMessage())); + throw new FileGenerationFailedException(sprintf('The file could not be written. %s', $throwable->getMessage()), $throwable->getCode(), $throwable); } } diff --git a/packages/generation/src/TypeScript/AsType.php b/packages/generation/src/TypeScript/AsType.php index dd4fc72e4b..b4b18db825 100644 --- a/packages/generation/src/TypeScript/AsType.php +++ b/packages/generation/src/TypeScript/AsType.php @@ -8,6 +8,4 @@ * Marks this class as a source for TypeScript type generation. */ #[Attribute(Attribute::TARGET_CLASS)] -final class AsType -{ -} +final class AsType {} diff --git a/packages/generation/src/TypeScript/GenerateTypesCommand.php b/packages/generation/src/TypeScript/GenerateTypesCommand.php index b4e83dc064..6685e3ef4e 100644 --- a/packages/generation/src/TypeScript/GenerateTypesCommand.php +++ b/packages/generation/src/TypeScript/GenerateTypesCommand.php @@ -8,14 +8,14 @@ use Tempest\Console\HasConsole; use Tempest\Container\Container; -final class GenerateTypesCommand +final readonly class GenerateTypesCommand { use HasConsole; public function __construct( - private readonly TypeScriptGenerationConfig $config, - private readonly TypeScriptGenerator $generator, - private readonly Container $container, + private TypeScriptGenerationConfig $config, + private TypeScriptGenerator $generator, + private Container $container, ) {} #[ConsoleCommand( diff --git a/packages/generation/src/TypeScript/StructureResolvers/ClassStructureResolver.php b/packages/generation/src/TypeScript/StructureResolvers/ClassStructureResolver.php index 4dd9a85b29..9c8e5696b7 100644 --- a/packages/generation/src/TypeScript/StructureResolvers/ClassStructureResolver.php +++ b/packages/generation/src/TypeScript/StructureResolvers/ClassStructureResolver.php @@ -17,11 +17,11 @@ /** * Resolves PHP classes into TypeScript interfaces. */ -final class ClassStructureResolver implements StructureResolver +final readonly class ClassStructureResolver implements StructureResolver { public function __construct( - private readonly TypeScriptGenerationConfig $config, - private readonly Container $container, + private TypeScriptGenerationConfig $config, + private Container $container, ) {} public function resolve(TypeReflector $type, TypeScriptGenerator $generator): InterfaceDefinition @@ -47,7 +47,7 @@ private function resolveProperty(PropertyReflector $property, TypeScriptGenerato if ($type->isIterable()) { $elementTypeReflector = $property->getIterableType(); - if ($elementTypeReflector !== null) { + if ($elementTypeReflector instanceof TypeReflector) { $result = $this->resolveType($elementTypeReflector, $generator); return new PropertyDefinition( diff --git a/packages/generation/src/TypeScript/StructureResolvers/EnumStructureResolver.php b/packages/generation/src/TypeScript/StructureResolvers/EnumStructureResolver.php index 7293fec25e..a0151d97fc 100644 --- a/packages/generation/src/TypeScript/StructureResolvers/EnumStructureResolver.php +++ b/packages/generation/src/TypeScript/StructureResolvers/EnumStructureResolver.php @@ -17,11 +17,11 @@ /** * Resolves PHP enums into TypeScript union types. */ -final class EnumStructureResolver implements StructureResolver +final readonly class EnumStructureResolver implements StructureResolver { public function __construct( - private readonly TypeScriptGenerationConfig $config, - private readonly Container $container, + private TypeScriptGenerationConfig $config, + private Container $container, ) {} public function resolve(TypeReflector $type, TypeScriptGenerator $generator): TypeDefinition diff --git a/packages/generation/src/TypeScript/TypeResolvers/ScalarTypeResolver.php b/packages/generation/src/TypeScript/TypeResolvers/ScalarTypeResolver.php index ae88f7df35..322434cde0 100644 --- a/packages/generation/src/TypeScript/TypeResolvers/ScalarTypeResolver.php +++ b/packages/generation/src/TypeScript/TypeResolvers/ScalarTypeResolver.php @@ -4,6 +4,7 @@ namespace Tempest\Generation\TypeScript\TypeResolvers; +use LogicException; use Tempest\Core\Priority; use Tempest\Generation\TypeScript\ResolvedType; use Tempest\Generation\TypeScript\TypeResolver; @@ -27,7 +28,7 @@ public function canResolve(TypeReflector $type): bool public function resolve(TypeReflector $type, TypeScriptGenerator $generator): ResolvedType { - $type = self::SCALAR_TYPE_MAP[$type->getName()] ?? throw new \LogicException(sprintf('Unsupported scalar type "%s".', $type->getName())); + $type = self::SCALAR_TYPE_MAP[$type->getName()] ?? throw new LogicException(sprintf('Unsupported scalar type "%s".', $type->getName())); return new ResolvedType($type); } diff --git a/packages/generation/src/TypeScript/TypeScriptGenerationConfig.php b/packages/generation/src/TypeScript/TypeScriptGenerationConfig.php index fdcc7c8921..3294dcf56f 100644 --- a/packages/generation/src/TypeScript/TypeScriptGenerationConfig.php +++ b/packages/generation/src/TypeScript/TypeScriptGenerationConfig.php @@ -11,27 +11,19 @@ interface TypeScriptGenerationConfig * * @var class-string */ - public string $writer { - get; - } + public string $writer { get; } /** * The list of source classes to generate types for. * * @var array */ - public array $sources { - get; - set; - } + public array $sources { get; set; } /** * The list of type resolvers for property-level type mapping. * * @var array> */ - public array $resolvers { - get; - set; - } + public array $resolvers { get; set; } } diff --git a/packages/generation/src/TypeScript/TypeSourceDiscovery.php b/packages/generation/src/TypeScript/TypeSourceDiscovery.php index 3d69a7fc0a..92943518bd 100644 --- a/packages/generation/src/TypeScript/TypeSourceDiscovery.php +++ b/packages/generation/src/TypeScript/TypeSourceDiscovery.php @@ -18,7 +18,7 @@ public function __construct( public function discover(DiscoveryLocation $location, ClassReflector $class): void { - if ($class->getAttribute(AsType::class)) { + if ($class->getAttribute(AsType::class) instanceof AsType) { $this->discoveryItems->add($location, [$class->getName()]); } diff --git a/packages/generation/src/TypeScript/Writers/DirectoryWriter.php b/packages/generation/src/TypeScript/Writers/DirectoryWriter.php index 647d0cbf8c..3005b5d52c 100644 --- a/packages/generation/src/TypeScript/Writers/DirectoryWriter.php +++ b/packages/generation/src/TypeScript/Writers/DirectoryWriter.php @@ -16,10 +16,10 @@ /** * Writes TypeScript definitions to separate .ts files organized by namespace in a directory structure. */ -final class DirectoryWriter implements TypeScriptWriter +final readonly class DirectoryWriter implements TypeScriptWriter { public function __construct( - private readonly DirectoryTypeScriptGenerationConfig $config, + private DirectoryTypeScriptGenerationConfig $config, ) {} public function write(TypeScriptOutput $output): void @@ -88,24 +88,26 @@ private function collectImports(array $namespaces, TypeScriptOutput $output): ar foreach ($namespaces as $namespace => $definitions) { foreach ($definitions as $definition) { - if ($definition instanceof InterfaceDefinition) { - foreach ($definition->properties as $property) { - if ($property->fqcn === null) { - continue; - } - - $targetNamespace = Str\before_last($property->fqcn, '\\'); + if (! $definition instanceof InterfaceDefinition) { + continue; + } - if (in_array($targetNamespace, $currentNamespaces, strict: true)) { - continue; - } + foreach ($definition->properties as $property) { + if ($property->fqcn === null) { + continue; + } - $typeName = Str\after_last($property->fqcn, '\\'); - $importPath = $this->computeImportPath($namespace, $targetNamespace); - $importKey = "{$importPath}::{$typeName}"; + $targetNamespace = Str\before_last($property->fqcn, '\\'); - $imports[$importKey] ??= "import type { {$typeName} } from '{$importPath}';"; + if (in_array($targetNamespace, $currentNamespaces, strict: true)) { + continue; } + + $typeName = Str\after_last($property->fqcn, '\\'); + $importPath = $this->computeImportPath($namespace, $targetNamespace); + $importKey = "{$importPath}::{$typeName}"; + + $imports[$importKey] ??= "import type { {$typeName} } from '{$importPath}';"; } } } @@ -179,15 +181,13 @@ private function computeImportPath(string $sourceNamespace, string $targetNamesp $targetDiff = array_slice($targetParts, $commonLength); $targetKebab = Arr\map($targetDiff, fn (string $part) => Str\to_kebab_case($part)); - if ($upLevels === 0 && count($targetKebab) === 0) { + if ($upLevels === 0 && $targetKebab === []) { return './'; } $upPath = $upLevels > 0 ? str_repeat('../', $upLevels) : './'; - $downPath = count($targetKebab) > 0 ? (string) Arr\implode($targetKebab, glue: '/') : ''; - - $fullPath = rtrim($upPath . $downPath, '/'); + $downPath = $targetKebab !== [] ? (string) Arr\implode($targetKebab, glue: '/') : ''; - return $fullPath; + return rtrim($upPath . $downPath, '/'); } } diff --git a/packages/generation/src/TypeScript/Writers/NamespacedFileWriter.php b/packages/generation/src/TypeScript/Writers/NamespacedFileWriter.php index c8c5a7a989..f593fc478f 100644 --- a/packages/generation/src/TypeScript/Writers/NamespacedFileWriter.php +++ b/packages/generation/src/TypeScript/Writers/NamespacedFileWriter.php @@ -16,10 +16,10 @@ /** * Writes TypeScript definitions to a single .d.ts file using TypeScript namespaces. */ -final class NamespacedFileWriter implements TypeScriptWriter +final readonly class NamespacedFileWriter implements TypeScriptWriter { public function __construct( - private readonly NamespacedTypeScriptGenerationConfig $config, + private NamespacedTypeScriptGenerationConfig $config, ) {} public function write(TypeScriptOutput $output): void diff --git a/packages/generation/tests/Php/ClassGeneratorTest.php b/packages/generation/tests/Php/ClassGeneratorTest.php index 2a3072e460..b18bc5d65b 100644 --- a/packages/generation/tests/Php/ClassGeneratorTest.php +++ b/packages/generation/tests/Php/ClassGeneratorTest.php @@ -28,14 +28,14 @@ public function creates_class_from_scratch(): void $class->setReadOnly(); $class->addMethod('up', body: <<primary() - ->text('name'); - PHP, returnType: FakeQueryStatement::class); + return (new \Tempest\Generation\Tests\Fixtures\Database\FakeCreateTableStatement(\Tempest\Generation\Tests\Fixtures\Database\MigrationModel::table())) + ->primary() + ->text('name'); + PHP, returnType: FakeQueryStatement::class); $class->addMethod('getName', body: <<assertMatchesSnapshot($class->print()); } @@ -50,8 +50,8 @@ public function creates_methods_with_parameters(): void $class->setReadOnly(); $class->addMethod('findById', body: << 'int'], returnType: '?App\\Models\\User'); + // + PHP, parameters: ['id' => 'int'], returnType: '?App\\Models\\User'); $this->assertMatchesSnapshot($class->print()); } @@ -73,10 +73,10 @@ public function simplify_class_names_by_default(): void $class = new ClassGenerator('CreateUsersTable', namespace: 'App'); $class->addMethod('up', body: <<primary() - ->text('name'); - PHP, returnType: FakeQueryStatement::class); + return (new \Tempest\Generation\Tests\Fixtures\Database\FakeCreateTableStatement(\Tempest\Generation\Tests\Fixtures\Database\MigrationModel::table())) + ->primary() + ->text('name'); + PHP, returnType: FakeQueryStatement::class); $this->assertMatchesSnapshot($class->print()); } @@ -88,10 +88,10 @@ public function does_not_simplify_class_names(): void $class->simplifyClassNamesInMethodBodies(false); $class->addMethod('up', body: <<primary() - ->text('name'); - PHP, returnType: FakeQueryStatement::class); + return (new \Tempest\Generation\Tests\Fixtures\Database\FakeCreateTableStatement(\Tempest\Generation\Tests\Fixtures\Database\MigrationModel::table())) + ->primary() + ->text('name'); + PHP, returnType: FakeQueryStatement::class); $this->assertMatchesSnapshot($class->print()); } diff --git a/packages/generation/tests/Php/Fixtures/ClassFromFile.php b/packages/generation/tests/Php/Fixtures/ClassFromFile.php index 7243470724..2ca7a96e47 100644 --- a/packages/generation/tests/Php/Fixtures/ClassFromFile.php +++ b/packages/generation/tests/Php/Fixtures/ClassFromFile.php @@ -4,6 +4,4 @@ namespace Tempest\Generation\Tests\Php\Fixtures; -final readonly class ClassFromFile -{ -} +final readonly class ClassFromFile {} diff --git a/packages/generation/tests/Php/Fixtures/ClassWithMethodParameterAttributes.php b/packages/generation/tests/Php/Fixtures/ClassWithMethodParameterAttributes.php index 98ce82e66b..5cdf78f0e9 100644 --- a/packages/generation/tests/Php/Fixtures/ClassWithMethodParameterAttributes.php +++ b/packages/generation/tests/Php/Fixtures/ClassWithMethodParameterAttributes.php @@ -11,6 +11,5 @@ final class ClassWithMethodParameterAttributes public function example( #[SampleParameterAttribute] string $parameter, - ): void { - } + ): void {} } diff --git a/packages/generation/tests/Php/Fixtures/SampleNamespace/DummyFqcn.php b/packages/generation/tests/Php/Fixtures/SampleNamespace/DummyFqcn.php index ae38bb730b..179cd4746c 100644 --- a/packages/generation/tests/Php/Fixtures/SampleNamespace/DummyFqcn.php +++ b/packages/generation/tests/Php/Fixtures/SampleNamespace/DummyFqcn.php @@ -4,6 +4,4 @@ namespace Tempest\Generation\Tests\Php\Fixtures\SampleNamespace; -final class DummyFqcn -{ -} +final class DummyFqcn {} diff --git a/packages/generation/tests/Php/Fixtures/SampleNamespace/ExampleTrait.php b/packages/generation/tests/Php/Fixtures/SampleNamespace/ExampleTrait.php index 7205acca8c..811dbc7d2c 100644 --- a/packages/generation/tests/Php/Fixtures/SampleNamespace/ExampleTrait.php +++ b/packages/generation/tests/Php/Fixtures/SampleNamespace/ExampleTrait.php @@ -6,7 +6,5 @@ trait ExampleTrait { - public function traitMethod(): void - { - } + public function traitMethod(): void {} } diff --git a/packages/generation/tests/Php/Fixtures/SampleNamespace/SampleParameterAttribute.php b/packages/generation/tests/Php/Fixtures/SampleNamespace/SampleParameterAttribute.php index 9d2bf33184..5ac1bc345f 100644 --- a/packages/generation/tests/Php/Fixtures/SampleNamespace/SampleParameterAttribute.php +++ b/packages/generation/tests/Php/Fixtures/SampleNamespace/SampleParameterAttribute.php @@ -7,6 +7,4 @@ use Attribute; #[Attribute(Attribute::TARGET_PARAMETER)] -final class SampleParameterAttribute -{ -} +final class SampleParameterAttribute {} diff --git a/packages/generation/tests/Php/Fixtures/TestAttribute.php b/packages/generation/tests/Php/Fixtures/TestAttribute.php index 91486e42bb..4eace32571 100644 --- a/packages/generation/tests/Php/Fixtures/TestAttribute.php +++ b/packages/generation/tests/Php/Fixtures/TestAttribute.php @@ -7,6 +7,4 @@ use Attribute; #[Attribute(Attribute::TARGET_CLASS)] -final class TestAttribute -{ -} +final class TestAttribute {} diff --git a/packages/generation/tests/TypeScript/StructureResolvers/ClassStructureResolverTest.php b/packages/generation/tests/TypeScript/StructureResolvers/ClassStructureResolverTest.php index 578ca75fd6..dbadca2132 100644 --- a/packages/generation/tests/TypeScript/StructureResolvers/ClassStructureResolverTest.php +++ b/packages/generation/tests/TypeScript/StructureResolvers/ClassStructureResolverTest.php @@ -23,6 +23,7 @@ final class ClassStructureResolverTest extends TestCase { private ClassStructureResolver $resolver; + private GenericTypeScriptGenerator $generator; #[PreCondition] @@ -78,5 +79,6 @@ public function resolves_scalar_properties(): void final class Badge { public string $name; + public int $value; } diff --git a/packages/http-client/src/Testing/MockClient.php b/packages/http-client/src/Testing/MockClient.php index 75636d3c86..ae033c413e 100644 --- a/packages/http-client/src/Testing/MockClient.php +++ b/packages/http-client/src/Testing/MockClient.php @@ -97,11 +97,11 @@ public function sendRequest(RequestInterface $request): ResponseInterface $this->lastRequest = $request; $this->requests[] = $request; - if ($response = $this->resolveFakeResponse($request)) { + if (($response = $this->resolveFakeResponse($request)) instanceof ResponseInterface) { return $response; } - if ($response = $this->resolveWildcardFakeResponse($request)) { + if (($response = $this->resolveWildcardFakeResponse($request)) instanceof ResponseInterface) { return $response; } diff --git a/packages/http/src/Cookie/Cookie.php b/packages/http/src/Cookie/Cookie.php index 36f235faa7..9d56219433 100644 --- a/packages/http/src/Cookie/Cookie.php +++ b/packages/http/src/Cookie/Cookie.php @@ -60,15 +60,15 @@ public function __toString(): string $parts[] = 'Path=' . $this->path; } - if ($this->secure === true) { + if ($this->secure) { $parts[] = 'Secure'; } - if ($this->httpOnly === true) { + if ($this->httpOnly) { $parts[] = 'HttpOnly'; } - if ($this->sameSite !== null) { + if ($this->sameSite instanceof SameSite) { $parts[] = 'SameSite=' . $this->sameSite->value; } diff --git a/packages/http/src/HttpRequestFailed.php b/packages/http/src/HttpRequestFailed.php index ed3999c3d7..b207921de7 100644 --- a/packages/http/src/HttpRequestFailed.php +++ b/packages/http/src/HttpRequestFailed.php @@ -34,7 +34,7 @@ public function context(): array 'request_uri' => $this->request?->uri, 'request_method' => $this->request?->method->value, 'status_code' => $this->status->value, - 'original_response' => $this->cause ? $this->cause::class : null, + 'original_response' => $this->cause instanceof Response ? $this->cause::class : null, ]); } } diff --git a/packages/http/src/Request.php b/packages/http/src/Request.php index 794d42c860..7193d4f579 100644 --- a/packages/http/src/Request.php +++ b/packages/http/src/Request.php @@ -8,43 +8,25 @@ interface Request { - public Method $method { - get; - } + public Method $method { get; } - public string $uri { - get; - } + public string $uri { get; } - public ?string $raw { - get; - } + public ?string $raw { get; } - public array $body { - get; - } + public array $body { get; } - public RequestHeaders $headers { - get; - } + public RequestHeaders $headers { get; } - public string $path { - get; - } + public string $path { get; } - public array $query { - get; - } + public array $query { get; } /** @var \Tempest\Http\Upload[] $files */ - public array $files { - get; - } + public array $files { get; } /** @var Cookie[] $cookies */ - public array $cookies { - get; - } + public array $cookies { get; } public function has(string $key): bool; diff --git a/packages/http/src/Response.php b/packages/http/src/Response.php index ea7bac8b36..2c92b36b66 100644 --- a/packages/http/src/Response.php +++ b/packages/http/src/Response.php @@ -15,25 +15,19 @@ interface Response /** * Gets the status code of the response. */ - public Status $status { - get; - } + public Status $status { get; } /** * Gets the headers of the response. * * @var \Tempest\Http\Header[] $headers */ - public array $headers { - get; - } + public array $headers { get; } /** * Gets the body of the response. */ - public View|string|array|Generator|JsonSerializable|null $body { - get; - } + public View|string|array|Generator|JsonSerializable|null $body { get; } /** * Gets a header by its name, case insensitive. diff --git a/packages/http/src/Responses/Download.php b/packages/http/src/Responses/Download.php index 75b08fcd01..a5ee7f9e2a 100644 --- a/packages/http/src/Responses/Download.php +++ b/packages/http/src/Responses/Download.php @@ -16,7 +16,8 @@ public function __construct(string $path, ?string $filename = null) { $filename ??= pathinfo($path, PATHINFO_BASENAME); - $this->addHeader('Content-Disposition', "attachment; filename=\"{$filename}\"") + $this + ->addHeader('Content-Disposition', "attachment; filename=\"{$filename}\"") ->setContentType(ContentType::fromPath($path)) ->removeHeader('Transfer-Encoding'); diff --git a/packages/http/src/Responses/File.php b/packages/http/src/Responses/File.php index f940def4d1..c75213a39c 100644 --- a/packages/http/src/Responses/File.php +++ b/packages/http/src/Responses/File.php @@ -16,7 +16,8 @@ public function __construct(string $path, ?string $filename = null) { $filename ??= pathinfo($path, PATHINFO_BASENAME); - $this->addHeader('Content-Disposition', "inline; filename=\"{$filename}\"") + $this + ->addHeader('Content-Disposition', "inline; filename=\"{$filename}\"") ->setContentType(ContentType::fromPath($path)) ->removeHeader('Transfer-Encoding'); diff --git a/packages/http/src/Responses/ServerError.php b/packages/http/src/Responses/ServerError.php index 21ef41b98d..024fb4ead4 100644 --- a/packages/http/src/Responses/ServerError.php +++ b/packages/http/src/Responses/ServerError.php @@ -15,12 +15,11 @@ final class ServerError implements Response { use IsResponse; - private(set) ?Exception $exception = null; - - public function __construct(View|Generator|string|array|null $body = null, ?Exception $exception = null) - { + public function __construct( + View|Generator|string|array|null $body = null, + private(set) ?Exception $exception = null, + ) { $this->status = Status::INTERNAL_SERVER_ERROR; $this->body = $body; - $this->exception = $exception; } } diff --git a/packages/http/src/SensitiveField.php b/packages/http/src/SensitiveField.php index 0a01792ccb..2204b7f0da 100644 --- a/packages/http/src/SensitiveField.php +++ b/packages/http/src/SensitiveField.php @@ -7,6 +7,4 @@ use Attribute; #[Attribute(Attribute::TARGET_PROPERTY)] -final class SensitiveField -{ -} +final class SensitiveField {} diff --git a/packages/http/src/ServerSentEvent.php b/packages/http/src/ServerSentEvent.php index 8a8c8d5d25..847bb0aaad 100644 --- a/packages/http/src/ServerSentEvent.php +++ b/packages/http/src/ServerSentEvent.php @@ -11,16 +11,12 @@ interface ServerSentEvent /** * Defines the ID of this event, which sets the `Last-Event-ID` header in case of a reconnection. */ - public ?int $id { - get; - } + public ?int $id { get; } /** * Defines the event stream's reconnection time in case of a reconnection attempt. */ - public null|Duration|int $retryAfter { - get; - } + public null|Duration|int $retryAfter { get; } /** * The name of the event, which may be listened to by `EventSource#addEventListener`. @@ -33,14 +29,10 @@ interface ServerSentEvent * }) * ``` */ - public ?string $event { - get; - } + public ?string $event { get; } /** * Content of the event. */ - public JsonSerializable|Stringable|string|iterable $data { - get; - } + public JsonSerializable|Stringable|string|iterable $data { get; } } diff --git a/packages/http/src/Session/Config/session.config.php b/packages/http/src/Session/Config/session.config.php index 1c6cebdc39..8864f4abbb 100644 --- a/packages/http/src/Session/Config/session.config.php +++ b/packages/http/src/Session/Config/session.config.php @@ -4,6 +4,6 @@ use Tempest\Http\Session\Config\FileSessionConfig; return new FileSessionConfig( - path: 'sessions', expiration: Duration::days(30), + path: 'sessions', ); diff --git a/packages/http/src/Session/FormSession.php b/packages/http/src/Session/FormSession.php index e349a12cfb..a6cc7da406 100644 --- a/packages/http/src/Session/FormSession.php +++ b/packages/http/src/Session/FormSession.php @@ -14,6 +14,7 @@ final readonly class FormSession { private const string VALIDATION_ERRORS_KEY = '#validation_errors'; + private const string ORIGINAL_VALUES_KEY = '#original_values'; public function __construct( diff --git a/packages/http/src/Session/Installer/DatabaseSessionInstaller.php b/packages/http/src/Session/Installer/DatabaseSessionInstaller.php index 316131f883..6037c7d633 100644 --- a/packages/http/src/Session/Installer/DatabaseSessionInstaller.php +++ b/packages/http/src/Session/Installer/DatabaseSessionInstaller.php @@ -6,6 +6,7 @@ use Tempest\Console\Console; use Tempest\Console\Input\ConsoleArgumentBag; +use Tempest\Console\Input\ConsoleInputArgument; use Tempest\Core\Installer; use Tempest\Core\PublishesFiles; use Tempest\Database\Migrations\MigrationManager; @@ -47,7 +48,7 @@ private function shouldMigrate(): bool { $argument = $this->consoleArgumentBag->get('migrate'); - if ($argument === null || ! is_bool($argument->value)) { + if (! $argument instanceof ConsoleInputArgument || ! is_bool($argument->value)) { return $this->console->confirm('Do you want to execute migrations?'); } diff --git a/packages/http/src/Session/Managers/DatabaseSessionManager.php b/packages/http/src/Session/Managers/DatabaseSessionManager.php index 788eaf5643..ad6f1cf964 100644 --- a/packages/http/src/Session/Managers/DatabaseSessionManager.php +++ b/packages/http/src/Session/Managers/DatabaseSessionManager.php @@ -28,7 +28,7 @@ public function getOrCreate(SessionId $id): Session $now = $this->clock->now(); $session = $this->load($id); - if ($session === null) { + if (! $session instanceof Session) { $session = new Session( id: $id, createdAt: $now, diff --git a/packages/http/src/Session/Managers/FileSessionManager.php b/packages/http/src/Session/Managers/FileSessionManager.php index 6cfe992ed2..aebe39a599 100644 --- a/packages/http/src/Session/Managers/FileSessionManager.php +++ b/packages/http/src/Session/Managers/FileSessionManager.php @@ -29,7 +29,7 @@ public function getOrCreate(SessionId $id): Session $now = $this->clock->now(); $session = $this->load($id); - if ($session === null) { + if (! $session instanceof Session) { $session = new Session( id: $id, createdAt: $now, @@ -81,7 +81,7 @@ public function deleteExpiredSessions(): void $id = new SessionId(pathinfo($sessionFile, flags: PATHINFO_FILENAME)); $session = $this->load($id); - if ($session === null) { + if (! $session instanceof Session) { continue; } diff --git a/packages/http/src/Session/Managers/RedisSessionManager.php b/packages/http/src/Session/Managers/RedisSessionManager.php index a2450ff4cc..6e19e9f4ab 100644 --- a/packages/http/src/Session/Managers/RedisSessionManager.php +++ b/packages/http/src/Session/Managers/RedisSessionManager.php @@ -30,7 +30,7 @@ public function getOrCreate(SessionId $id): Session $now = $this->clock->now(); $session = $this->load($id); - if ($session === null) { + if (! $session instanceof Session) { $session = new Session( id: $id, createdAt: $now, @@ -80,7 +80,7 @@ public function deleteExpiredSessions(): void $sessionId = $this->getSessionIdFromKey($key); $session = $this->load($sessionId); - if ($session === null) { + if (! $session instanceof Session) { continue; } diff --git a/packages/http/src/Session/PreviousUrl.php b/packages/http/src/Session/PreviousUrl.php index f5b78c094d..9fe22a66eb 100644 --- a/packages/http/src/Session/PreviousUrl.php +++ b/packages/http/src/Session/PreviousUrl.php @@ -13,6 +13,7 @@ final readonly class PreviousUrl { private const string PREVIOUS_URL_SESSION_KEY = '#previous_url'; + private const string INTENDED_URL_SESSION_KEY = '#intended_url'; public function __construct( @@ -65,10 +66,6 @@ private function shouldNotTrack(Request $request): bool return true; } - if ($request->headers->get('purpose') === 'prefetch') { - return true; - } - - return false; + return $request->headers->get('purpose') === 'prefetch'; } } diff --git a/packages/http/src/Session/SessionConfig.php b/packages/http/src/Session/SessionConfig.php index 6bbc9264c0..425d34025a 100644 --- a/packages/http/src/Session/SessionConfig.php +++ b/packages/http/src/Session/SessionConfig.php @@ -10,9 +10,7 @@ interface SessionConfig /** * Time required for a session to expire. */ - public Duration $expiration { - get; - } + public Duration $expiration { get; } public function createManager(Container $container): SessionManager; } diff --git a/packages/http/src/Session/SessionIdResolverInitializer.php b/packages/http/src/Session/SessionIdResolverInitializer.php index 1fb27a9b2e..72c9cc2dee 100644 --- a/packages/http/src/Session/SessionIdResolverInitializer.php +++ b/packages/http/src/Session/SessionIdResolverInitializer.php @@ -11,7 +11,6 @@ use Tempest\Http\Cookie\CookieManager; use Tempest\Http\Request; use Tempest\Http\Session\Resolvers\CookieSessionIdResolver; -use Tempest\Http\Session\SessionConfig; final readonly class SessionIdResolverInitializer implements Initializer { diff --git a/packages/http/tests/Mappers/PsrRequestToGenericRequestMapperTest.php b/packages/http/tests/Mappers/PsrRequestToGenericRequestMapperTest.php index 0d94bb81e0..b368c3a26d 100644 --- a/packages/http/tests/Mappers/PsrRequestToGenericRequestMapperTest.php +++ b/packages/http/tests/Mappers/PsrRequestToGenericRequestMapperTest.php @@ -27,6 +27,7 @@ final class PsrRequestToGenericRequestMapperTest extends TestCase { private PsrRequestToGenericRequestMapper $mapper; + private ReflectionMethod $requestMethod; protected function setUp(): void @@ -145,8 +146,6 @@ private function createServerRequest(string $method, array $body = []): ServerRe } $stream = new Stream('php://temp', 'r+'); - $request = $request->withBody($stream); - - return $request; + return $request->withBody($stream); } } diff --git a/packages/http/tests/StatusTest.php b/packages/http/tests/StatusTest.php index e14d5fbd75..5b16f6a84d 100644 --- a/packages/http/tests/StatusTest.php +++ b/packages/http/tests/StatusTest.php @@ -15,7 +15,7 @@ */ final class StatusTest extends TestCase { - private static function descriptionToStatus(string $description): Status + private function descriptionToStatus(string $description): Status { $description = strtoupper( str_replace("'", '', str_replace([' ', '-'], '_', $description)), @@ -30,7 +30,7 @@ public function test_status_code(int $code, string $description): void $status = Status::fromCode($code); $this->assertSame( - self::descriptionToStatus($description), + $this->descriptionToStatus($description), $status, ); diff --git a/packages/icon/src/IconCache.php b/packages/icon/src/IconCache.php index d630707998..d3f3b05f4c 100644 --- a/packages/icon/src/IconCache.php +++ b/packages/icon/src/IconCache.php @@ -60,7 +60,7 @@ public function put(string $key, mixed $value, null|Duration|DateTimeInterface $ $expiresAt = DateTime::now()->plus($expiresAt); } - if ($expiresAt !== null) { + if ($expiresAt instanceof DateTimeInterface) { $item = $item->expiresAt($expiresAt->toNativeDateTime()); } diff --git a/packages/idempotency/src/Exceptions/IdempotencyException.php b/packages/idempotency/src/Exceptions/IdempotencyException.php index 9891226836..5f0eed9ced 100644 --- a/packages/idempotency/src/Exceptions/IdempotencyException.php +++ b/packages/idempotency/src/Exceptions/IdempotencyException.php @@ -6,6 +6,4 @@ use Exception; -abstract class IdempotencyException extends Exception -{ -} +abstract class IdempotencyException extends Exception {} diff --git a/packages/idempotency/src/Store/CacheIdempotencyStore.php b/packages/idempotency/src/Store/CacheIdempotencyStore.php index cbcad5b9d1..1bce72c13f 100644 --- a/packages/idempotency/src/Store/CacheIdempotencyStore.php +++ b/packages/idempotency/src/Store/CacheIdempotencyStore.php @@ -44,7 +44,7 @@ public function updateHeartbeat(string $scope, string $key, string $owner, int $ { $record = $this->find($scope, $key); - if ($record === null || $record->state !== IdempotencyState::PENDING || $record->pendingOwner !== $owner) { + if (! $record instanceof IdempotencyRecord || $record->state !== IdempotencyState::PENDING || $record->pendingOwner !== $owner) { return; } diff --git a/packages/idempotency/tests/IdempotencyMiddlewareTest.php b/packages/idempotency/tests/IdempotencyMiddlewareTest.php index 1abdaf9958..90bfa0a8d2 100644 --- a/packages/idempotency/tests/IdempotencyMiddlewareTest.php +++ b/packages/idempotency/tests/IdempotencyMiddlewareTest.php @@ -25,6 +25,7 @@ use Tempest\Idempotency\Fingerprint\RequestFingerprintGenerator; use Tempest\Idempotency\Middleware\IdempotencyMiddleware; use Tempest\Idempotency\Store\CacheIdempotencyStore; +use Tempest\Idempotency\Store\IdempotencyRecord; use Tempest\Idempotency\Store\IdempotencyState; use Tempest\Idempotency\Store\IdempotencyStore; use Tempest\Idempotency\Store\StoredResponse; @@ -454,7 +455,7 @@ public function takes_over_a_pending_record_owned_by_a_dead_process(): void key: 'stale-order', fingerprint: new RequestFingerprintGenerator()->generate($request), ttlInSeconds: 120, - pendingOwner: sprintf('%s|%d|%s', php_uname('n'), 99999999, 'stale-owner'), + pendingOwner: sprintf('%s|%d|%s', php_uname('n'), 99_999_999, 'stale-owner'), pendingHeartbeatAt: time(), ); @@ -694,7 +695,7 @@ public function __construct( private readonly IdempotencyStore $store, ) {} - public function find(string $scope, string $key): ?\Tempest\Idempotency\Store\IdempotencyRecord + public function find(string $scope, string $key): ?IdempotencyRecord { throw new RuntimeException('Simulated store read failure.'); } diff --git a/packages/idempotency/tests/IdempotentCommandMiddlewareTest.php b/packages/idempotency/tests/IdempotentCommandMiddlewareTest.php index 52c9c11f40..33850d36c8 100644 --- a/packages/idempotency/tests/IdempotentCommandMiddlewareTest.php +++ b/packages/idempotency/tests/IdempotentCommandMiddlewareTest.php @@ -181,7 +181,7 @@ public function takes_over_a_pending_record_owned_by_a_dead_process(): void key: $fingerprint, fingerprint: $fingerprint, ttlInSeconds: 120, - pendingOwner: sprintf('%s|%d|%s', php_uname('n'), 99999999, 'stale-owner'), + pendingOwner: sprintf('%s|%d|%s', php_uname('n'), 99_999_999, 'stale-owner'), pendingHeartbeatAt: time(), ); @@ -338,7 +338,5 @@ final class SyncInventoryHandler { #[Idempotent] #[CommandHandler] - public function handle(SyncInventoryCommand $command): void - { - } + public function handle(SyncInventoryCommand $command): void {} } diff --git a/packages/intl/src/Catalog/CatalogInitializer.php b/packages/intl/src/Catalog/CatalogInitializer.php index db4ac01175..1712c70f57 100644 --- a/packages/intl/src/Catalog/CatalogInitializer.php +++ b/packages/intl/src/Catalog/CatalogInitializer.php @@ -2,6 +2,7 @@ namespace Tempest\Intl\Catalog; +use RuntimeException; use Symfony\Component\Yaml\Yaml; use Tempest\Container\Container; use Tempest\Container\Initializer; @@ -30,7 +31,7 @@ public function initialize(Container $container): Catalog $messages = match (true) { Str\ends_with($path, '.json') => Json\decode($contents), Str\ends_with($path, ['.yaml', '.yml']) => Yaml::parse($contents), - default => throw new \RuntimeException("Unsupported translation file format: {$path}"), + default => throw new RuntimeException("Unsupported translation file format: {$path}"), }; foreach (Arr\dot($messages) as $key => $message) { diff --git a/packages/intl/src/GenericTranslator.php b/packages/intl/src/GenericTranslator.php index 338f5eb85f..ccf0df00a5 100644 --- a/packages/intl/src/GenericTranslator.php +++ b/packages/intl/src/GenericTranslator.php @@ -4,9 +4,8 @@ use Tempest\EventBus\EventBus; use Tempest\Intl\Catalog\Catalog; -use Tempest\Intl\IntlConfig; -use Tempest\Intl\Locale; use Tempest\Intl\MessageFormat\Formatter\MessageFormatter; +use Throwable; final readonly class GenericTranslator implements Translator { @@ -34,7 +33,7 @@ public function translateForLocale(Locale $locale, string $key, mixed ...$argume try { return $this->formatter->format(mb_trim($message), ...$arguments); - } catch (\Throwable $exception) { + } catch (Throwable $exception) { $this->eventBus?->dispatch(new TranslationFailure( locale: $locale, key: $key, diff --git a/packages/intl/src/IntlConfig.php b/packages/intl/src/IntlConfig.php index 2d141be772..d7e4ad2e92 100644 --- a/packages/intl/src/IntlConfig.php +++ b/packages/intl/src/IntlConfig.php @@ -2,7 +2,6 @@ namespace Tempest\Intl; -use Tempest\Intl\Locale; use Tempest\Intl\MessageFormat\FormattingFunction; use Tempest\Intl\MessageFormat\MarkupFormatter; use Tempest\Intl\MessageFormat\SelectorFunction; diff --git a/packages/intl/src/Locale.php b/packages/intl/src/Locale.php index faa3bc407c..1062777be1 100644 --- a/packages/intl/src/Locale.php +++ b/packages/intl/src/Locale.php @@ -829,11 +829,11 @@ public static function default(): self $locale = to_lower_case($language); - if ($script) { + if ($script !== '' && $script !== '0') { $locale .= '_' . upper_first($script); } - if ($region) { + if ($region !== '' && $region !== '0') { $locale .= '_' . to_upper_case($region); } diff --git a/packages/intl/src/MessageFormat/Formatter/FormattingException.php b/packages/intl/src/MessageFormat/Formatter/FormattingException.php index abb0c1de06..26330a1def 100644 --- a/packages/intl/src/MessageFormat/Formatter/FormattingException.php +++ b/packages/intl/src/MessageFormat/Formatter/FormattingException.php @@ -2,9 +2,10 @@ namespace Tempest\Intl\MessageFormat\Formatter; +use Exception; use Tempest\Core\ProvidesContext; -final class FormattingException extends \Exception implements ProvidesContext +final class FormattingException extends Exception implements ProvidesContext { public function __construct( string $message, diff --git a/packages/intl/src/MessageFormat/Formatter/MessageFormatter.php b/packages/intl/src/MessageFormat/Formatter/MessageFormatter.php index c0acb0f83f..fea3ed83b0 100644 --- a/packages/intl/src/MessageFormat/Formatter/MessageFormatter.php +++ b/packages/intl/src/MessageFormat/Formatter/MessageFormatter.php @@ -108,7 +108,7 @@ private function formatMessage(MessageNode $message): string } elseif ($declaration instanceof LocalDeclaration) { $variableName = $declaration->variable->name->name; - $functionName = $declaration->expression->function + $functionName = $declaration->expression->function instanceof FunctionCall ? (string) $declaration->expression->function->identifier : null; @@ -132,7 +132,7 @@ private function formatMessage(MessageNode $message): string } } - throw new FormattingException('Unknown message type: ' . get_class($message)); + throw new FormattingException('Unknown message type: ' . $message::class); } private function formatComplexBody(ComplexBody $body): string @@ -149,7 +149,7 @@ private function formatComplexBody(ComplexBody $body): string return $this->formatMatcher($body); } - throw new FormattingException('Unknown complex body type: ' . get_class($body)); + throw new FormattingException('Unknown complex body type: ' . $body::class); } private function formatMatcher(Matcher $matcher): string @@ -176,8 +176,9 @@ private function formatMatcher(Matcher $matcher): string $matches = true; $hasWildcard = false; + $counter = count($variant->keys); - for ($i = 0; $i < count($variant->keys); $i++) { + for ($i = 0; $i < $counter; $i++) { $keyNode = $variant->keys[$i]; $variable = $selectorVariables[$i]; @@ -194,7 +195,7 @@ private function formatMatcher(Matcher $matcher): string $variantKey = $keyNode->value; $isMatch = false; - if ($variable->selector) { + if ($variable->selector instanceof SelectorFunction) { $isMatch = $variable->selector->match($variantKey, $variable->value, $variable->parameters); } else { $isMatch = $variable->value === $variantKey; @@ -259,7 +260,7 @@ private function formatPlaceholder(Placeholder $placeholder): string return $this->formatPattern($placeholder->pattern); } - throw new FormattingException('Unknown placeholder type: ' . get_class($placeholder)); + throw new FormattingException('Unknown placeholder type: ' . $placeholder::class); } private function evaluateExpression(Expression $expression): FormattedValue @@ -284,7 +285,7 @@ private function evaluateExpression(Expression $expression): FormattedValue $value = null; // Function-only expressions start with null } - if ($expression->function !== null) { + if ($expression->function instanceof FunctionCall) { $functionName = (string) $expression->function->identifier; $parameters = $this->evaluateOptions($expression->function->options); @@ -293,7 +294,7 @@ private function evaluateExpression(Expression $expression): FormattedValue } } - if ($formattingFunction) { + if ($formattingFunction instanceof FormattingFunction) { return $formattingFunction->format($value, $parameters); } diff --git a/packages/intl/src/MessageFormat/FormattingFunction.php b/packages/intl/src/MessageFormat/FormattingFunction.php index 1268844083..fc15e67d35 100644 --- a/packages/intl/src/MessageFormat/FormattingFunction.php +++ b/packages/intl/src/MessageFormat/FormattingFunction.php @@ -9,9 +9,7 @@ interface FormattingFunction /** * Identifier of the formatting function. */ - public string $name { - get; - } + public string $name { get; } /** * Formats the given value with the given parameters. diff --git a/packages/intl/src/MessageFormat/Functions/DateTimeFunction.php b/packages/intl/src/MessageFormat/Functions/DateTimeFunction.php index 9e005dc062..331ad2fb70 100644 --- a/packages/intl/src/MessageFormat/Functions/DateTimeFunction.php +++ b/packages/intl/src/MessageFormat/Functions/DateTimeFunction.php @@ -2,6 +2,7 @@ namespace Tempest\Intl\MessageFormat\Functions; +use RuntimeException; use Tempest\DateTime\DateStyle; use Tempest\DateTime\DateTime; use Tempest\DateTime\TimeStyle; @@ -16,7 +17,7 @@ final class DateTimeFunction implements FormattingFunction public function format(mixed $value, array $parameters): FormattedValue { if (! class_exists(DateTime::class)) { - throw new \RuntimeException('`tempest/datetime` is required to use the `datetime` function.'); + throw new RuntimeException('`tempest/datetime` is required to use the `datetime` function.'); } $datetime = DateTime::parse($value); diff --git a/packages/intl/src/MessageFormat/Functions/NumberFunction.php b/packages/intl/src/MessageFormat/Functions/NumberFunction.php index 13ffa552e7..b728176d7d 100644 --- a/packages/intl/src/MessageFormat/Functions/NumberFunction.php +++ b/packages/intl/src/MessageFormat/Functions/NumberFunction.php @@ -36,11 +36,7 @@ public function match(string $key, mixed $value, array $parameters): bool return true; } - if ($key === $this->pluralRules->getPluralCategory($this->intlConfig->currentLocale, $number)) { - return true; - } - - return false; + return $key === $this->pluralRules->getPluralCategory($this->intlConfig->currentLocale, $number); } private function matchExists(string $key, mixed $value): bool diff --git a/packages/intl/src/MessageFormat/Markup/IconMarkupFormatter.php b/packages/intl/src/MessageFormat/Markup/IconMarkupFormatter.php index 0aa8e008cd..6bb0505f56 100644 --- a/packages/intl/src/MessageFormat/Markup/IconMarkupFormatter.php +++ b/packages/intl/src/MessageFormat/Markup/IconMarkupFormatter.php @@ -2,6 +2,7 @@ namespace Tempest\Intl\MessageFormat\Markup; +use RuntimeException; use Tempest\Container\Container; use Tempest\Icon\Icon; use Tempest\Intl\MessageFormat\StandaloneMarkupFormatter; @@ -21,7 +22,7 @@ public function supportsTag(string $tag): bool public function format(string $tag, array $options): string { if (! class_exists(Icon::class)) { - throw new \RuntimeException('The `tempest\icon` package is required to use the `icon` tag inside a translation string.'); + throw new RuntimeException('The `tempest\icon` package is required to use the `icon` tag inside a translation string.'); } $icon = Str\after_first($tag, 'icon-'); diff --git a/packages/intl/src/MessageFormat/Parser/MessageFormatParser.php b/packages/intl/src/MessageFormat/Parser/MessageFormatParser.php index 95f288065e..60aa5974a8 100644 --- a/packages/intl/src/MessageFormat/Parser/MessageFormatParser.php +++ b/packages/intl/src/MessageFormat/Parser/MessageFormatParser.php @@ -35,7 +35,9 @@ final class MessageFormatParser { private string $input; + private int $pos = 0; + private int $len; /** @@ -213,6 +215,7 @@ private function parseVariant(): Variant } else { $keys[] = $this->parseLiteral(); } + $this->consumeOptionalWhitespace(); } while ($this->peek() !== '{'); @@ -331,7 +334,7 @@ private function parseExpressionBody(): Expression $this->consumeOptionalWhitespace(); - if ($function === null && $this->peek() === ':') { + if (! $function instanceof FunctionCall && $this->peek() === ':') { $function = $this->parseFunction(); } @@ -349,7 +352,7 @@ private function parseExpressionBody(): Expression return new LiteralExpression($subject, $function, $attributes); } - if ($function !== null) { + if ($function instanceof FunctionCall) { return new FunctionExpression($function, $attributes); } diff --git a/packages/intl/src/MessageFormat/Parser/Node/Declaration/Declaration.php b/packages/intl/src/MessageFormat/Parser/Node/Declaration/Declaration.php index df661703fd..b5a039765e 100644 --- a/packages/intl/src/MessageFormat/Parser/Node/Declaration/Declaration.php +++ b/packages/intl/src/MessageFormat/Parser/Node/Declaration/Declaration.php @@ -4,6 +4,4 @@ use Tempest\Intl\MessageFormat\Parser\Node\Node; -interface Declaration extends Node -{ -} +interface Declaration extends Node {} diff --git a/packages/intl/src/MessageFormat/Parser/Node/Identifier.php b/packages/intl/src/MessageFormat/Parser/Node/Identifier.php index fce8c06490..e6ca4f0bca 100644 --- a/packages/intl/src/MessageFormat/Parser/Node/Identifier.php +++ b/packages/intl/src/MessageFormat/Parser/Node/Identifier.php @@ -2,7 +2,9 @@ namespace Tempest\Intl\MessageFormat\Parser\Node; -final readonly class Identifier implements Node +use Stringable; + +final readonly class Identifier implements Node, Stringable { public function __construct( public string $name, diff --git a/packages/intl/src/MessageFormat/Parser/Node/Key/Key.php b/packages/intl/src/MessageFormat/Parser/Node/Key/Key.php index 5cb1a73784..8159960025 100644 --- a/packages/intl/src/MessageFormat/Parser/Node/Key/Key.php +++ b/packages/intl/src/MessageFormat/Parser/Node/Key/Key.php @@ -4,6 +4,4 @@ use Tempest\Intl\MessageFormat\Parser\Node\Node; -interface Key extends Node -{ -} +interface Key extends Node {} diff --git a/packages/intl/src/MessageFormat/Parser/Node/Key/WildcardKey.php b/packages/intl/src/MessageFormat/Parser/Node/Key/WildcardKey.php index 81d144d045..4512d01472 100644 --- a/packages/intl/src/MessageFormat/Parser/Node/Key/WildcardKey.php +++ b/packages/intl/src/MessageFormat/Parser/Node/Key/WildcardKey.php @@ -2,6 +2,4 @@ namespace Tempest\Intl\MessageFormat\Parser\Node\Key; -final class WildcardKey implements Key -{ -} +final class WildcardKey implements Key {} diff --git a/packages/intl/src/MessageFormat/Parser/Node/Literal/QuotedLiteral.php b/packages/intl/src/MessageFormat/Parser/Node/Literal/QuotedLiteral.php index a50fdfae64..1096737628 100644 --- a/packages/intl/src/MessageFormat/Parser/Node/Literal/QuotedLiteral.php +++ b/packages/intl/src/MessageFormat/Parser/Node/Literal/QuotedLiteral.php @@ -2,6 +2,4 @@ namespace Tempest\Intl\MessageFormat\Parser\Node\Literal; -final class QuotedLiteral extends Literal -{ -} +final class QuotedLiteral extends Literal {} diff --git a/packages/intl/src/MessageFormat/Parser/Node/Literal/UnquotedLiteral.php b/packages/intl/src/MessageFormat/Parser/Node/Literal/UnquotedLiteral.php index 7fda533db3..7b11090961 100644 --- a/packages/intl/src/MessageFormat/Parser/Node/Literal/UnquotedLiteral.php +++ b/packages/intl/src/MessageFormat/Parser/Node/Literal/UnquotedLiteral.php @@ -2,6 +2,4 @@ namespace Tempest\Intl\MessageFormat\Parser\Node\Literal; -final class UnquotedLiteral extends Literal -{ -} +final class UnquotedLiteral extends Literal {} diff --git a/packages/intl/src/MessageFormat/Parser/Node/Node.php b/packages/intl/src/MessageFormat/Parser/Node/Node.php index bea306511d..675f8bda35 100644 --- a/packages/intl/src/MessageFormat/Parser/Node/Node.php +++ b/packages/intl/src/MessageFormat/Parser/Node/Node.php @@ -2,6 +2,4 @@ namespace Tempest\Intl\MessageFormat\Parser\Node; -interface Node -{ -} +interface Node {} diff --git a/packages/intl/src/MessageFormat/Parser/Node/ParsingException.php b/packages/intl/src/MessageFormat/Parser/Node/ParsingException.php index c306762ba1..14ea21cd91 100644 --- a/packages/intl/src/MessageFormat/Parser/Node/ParsingException.php +++ b/packages/intl/src/MessageFormat/Parser/Node/ParsingException.php @@ -2,7 +2,9 @@ namespace Tempest\Intl\MessageFormat\Parser\Node; -final class ParsingException extends \Exception +use Exception; + +final class ParsingException extends Exception { public function __construct( string $message, diff --git a/packages/intl/src/MessageFormat/Parser/Node/Pattern/Placeholder.php b/packages/intl/src/MessageFormat/Parser/Node/Pattern/Placeholder.php index 30b38dbd4b..94fb62f9b6 100644 --- a/packages/intl/src/MessageFormat/Parser/Node/Pattern/Placeholder.php +++ b/packages/intl/src/MessageFormat/Parser/Node/Pattern/Placeholder.php @@ -4,6 +4,4 @@ use Tempest\Intl\MessageFormat\Parser\Node\Node; -interface Placeholder extends Node -{ -} +interface Placeholder extends Node {} diff --git a/packages/intl/src/MessageFormat/Parser/Node/SimpleMessage.php b/packages/intl/src/MessageFormat/Parser/Node/SimpleMessage.php index dbc597e90d..b0fb3b404c 100644 --- a/packages/intl/src/MessageFormat/Parser/Node/SimpleMessage.php +++ b/packages/intl/src/MessageFormat/Parser/Node/SimpleMessage.php @@ -2,6 +2,4 @@ namespace Tempest\Intl\MessageFormat\Parser\Node; -final class SimpleMessage extends MessageNode -{ -} +final class SimpleMessage extends MessageNode {} diff --git a/packages/intl/src/MessageFormat/SelectorFunction.php b/packages/intl/src/MessageFormat/SelectorFunction.php index 0d2a312079..e3020b3a9d 100644 --- a/packages/intl/src/MessageFormat/SelectorFunction.php +++ b/packages/intl/src/MessageFormat/SelectorFunction.php @@ -7,9 +7,7 @@ interface SelectorFunction /** * Identifier of the selector function. */ - public string $name { - get; - } + public string $name { get; } /** * Defines whether the matcher key matches with the given value. diff --git a/packages/intl/src/Number/functions.php b/packages/intl/src/Number/functions.php index e67d018634..6f8b4ad576 100644 --- a/packages/intl/src/Number/functions.php +++ b/packages/intl/src/Number/functions.php @@ -163,13 +163,16 @@ function to_human_readable(int|float $number, int $precision = 0, ?int $maxPreci ]; } - switch (true) { - case floatval($number) === 0.0: - return $precision > 0 ? namespace\format(0, $precision, $maxPrecision) : '0'; - case $number < 0: - return sprintf('-%s', namespace\to_human_readable(Math\abs($number), $precision, $maxPrecision, $units)); - case $number >= 1e15: - return sprintf('%s' . end($units), namespace\to_human_readable($number / 1e15, $precision, $maxPrecision, $units)); + if (floatval($number) === 0.0) { + return $precision > 0 ? namespace\format(0, $precision, $maxPrecision) : '0'; + } + + if ($number < 0) { + return sprintf('-%s', namespace\to_human_readable(Math\abs($number), $precision, $maxPrecision, $units)); + } + + if ($number >= 1e15) { + return sprintf('%s' . end($units), namespace\to_human_readable($number / 1e15, $precision, $maxPrecision, $units)); } $numberExponent = (int) Math\floor(Math\log($number, base: 10)); diff --git a/packages/intl/src/PluralRules/PluralRulesMatcher.php b/packages/intl/src/PluralRules/PluralRulesMatcher.php index eb89ced577..3ed30faa4b 100644 --- a/packages/intl/src/PluralRules/PluralRulesMatcher.php +++ b/packages/intl/src/PluralRules/PluralRulesMatcher.php @@ -57,7 +57,7 @@ private static function getCompactExponent(float|int $n): int $abs = abs($n); - if ($abs >= 1000000) { + if ($abs >= 1_000_000) { return 6; } @@ -518,7 +518,7 @@ private static function getPluralCategoryBr(float|int $n): string return 'few'; } - if (! self::isEqual($n, 0) && self::isEqual($n % 1000000, 0)) { + if (! self::isEqual($n, 0) && self::isEqual($n % 1_000_000, 0)) { return 'many'; } @@ -580,7 +580,7 @@ private static function getPluralCategoryCa(float|int $n): string return 'one'; } - if (self::isEqual($e, 0) && ! self::isEqual($i, 0) && self::isEqual($i % 1000000, 0) && self::isEqual($v, 0) || ! self::inRange($e, 0, 5)) { + if (self::isEqual($e, 0) && ! self::isEqual($i, 0) && self::isEqual($i % 1_000_000, 0) && self::isEqual($v, 0) || ! self::inRange($e, 0, 5)) { return 'many'; } @@ -980,7 +980,7 @@ private static function getPluralCategoryEs(float|int $n): string return 'one'; } - if (self::isEqual($e, 0) && ! self::isEqual($i, 0) && self::isEqual($i % 1000000, 0) && self::isEqual($v, 0) || ! self::inRange($e, 0, 5)) { + if (self::isEqual($e, 0) && ! self::isEqual($i, 0) && self::isEqual($i % 1_000_000, 0) && self::isEqual($v, 0) || ! self::inRange($e, 0, 5)) { return 'many'; } @@ -1132,7 +1132,7 @@ private static function getPluralCategoryFr(float|int $n): string return 'one'; } - if (self::isEqual($e, 0) && self::isEqual($i % 1000000, 0) && self::isEqual($v, 0) || ! self::inRange($e, 0, 5)) { + if (self::isEqual($e, 0) && self::isEqual($i % 1_000_000, 0) && self::isEqual($v, 0) || ! self::inRange($e, 0, 5)) { return 'many'; } @@ -1639,7 +1639,7 @@ private static function getPluralCategoryIt(float|int $n): string return 'one'; } - if (self::isEqual($e, 0) && ! self::isEqual($i, 0) && self::isEqual($i % 1000000, 0) && self::isEqual($v, 0) || ! self::inRange($e, 0, 5)) { + if (self::isEqual($e, 0) && ! self::isEqual($i, 0) && self::isEqual($i % 1_000_000, 0) && self::isEqual($v, 0) || ! self::inRange($e, 0, 5)) { return 'many'; } @@ -2098,8 +2098,8 @@ private static function getPluralCategoryKw(float|int $n): string || self::isEqual($n % 100, 62) || self::isEqual($n % 100, 82) || self::isEqual($n % 1000, 0) - && (self::inRange($n % 100000, 1000, 20000) || self::isEqual($n % 100000, 40000) || self::isEqual($n % 100000, 60000) || self::isEqual($n % 100000, 80000)) - || self::isEqual($n % 1000000, 100000) + && (self::inRange($n % 100_000, 1000, 20_000) || self::isEqual($n % 100_000, 40_000) || self::isEqual($n % 100_000, 60_000) || self::isEqual($n % 100_000, 80_000)) + || self::isEqual($n % 1_000_000, 100_000) ) { return 'two'; } @@ -2238,7 +2238,7 @@ private static function getPluralCategoryLld(float|int $n): string return 'one'; } - if (self::isEqual($e, 0) && ! self::isEqual($i, 0) && self::isEqual($i % 1000000, 0) && self::isEqual($v, 0) || ! self::inRange($e, 0, 5)) { + if (self::isEqual($e, 0) && ! self::isEqual($i, 0) && self::isEqual($i % 1_000_000, 0) && self::isEqual($v, 0) || ! self::inRange($e, 0, 5)) { return 'many'; } @@ -2998,7 +2998,7 @@ private static function getPluralCategoryPt(float|int $n): string return 'one'; } - if (self::isEqual($e, 0) && ! self::isEqual($i, 0) && self::isEqual($i % 1000000, 0) && self::isEqual($v, 0) || ! self::inRange($e, 0, 5)) { + if (self::isEqual($e, 0) && ! self::isEqual($i, 0) && self::isEqual($i % 1_000_000, 0) && self::isEqual($v, 0) || ! self::inRange($e, 0, 5)) { return 'many'; } @@ -3020,7 +3020,7 @@ private static function getPluralCategoryPt_PT(float|int $n): string return 'one'; } - if (self::isEqual($e, 0) && ! self::isEqual($i, 0) && self::isEqual($i % 1000000, 0) && self::isEqual($v, 0) || ! self::inRange($e, 0, 5)) { + if (self::isEqual($e, 0) && ! self::isEqual($i, 0) && self::isEqual($i % 1_000_000, 0) && self::isEqual($v, 0) || ! self::inRange($e, 0, 5)) { return 'many'; } @@ -3216,7 +3216,7 @@ private static function getPluralCategoryScn(float|int $n): string return 'one'; } - if (self::isEqual($e, 0) && ! self::isEqual($i, 0) && self::isEqual($i % 1000000, 0) && self::isEqual($v, 0) || ! self::inRange($e, 0, 5)) { + if (self::isEqual($e, 0) && ! self::isEqual($i, 0) && self::isEqual($i % 1_000_000, 0) && self::isEqual($v, 0) || ! self::inRange($e, 0, 5)) { return 'many'; } @@ -4150,7 +4150,7 @@ private static function getPluralCategoryVec(float|int $n): string return 'one'; } - if (self::isEqual($e, 0) && ! self::isEqual($i, 0) && self::isEqual($i % 1000000, 0) && self::isEqual($v, 0) || ! self::inRange($e, 0, 5)) { + if (self::isEqual($e, 0) && ! self::isEqual($i, 0) && self::isEqual($i % 1_000_000, 0) && self::isEqual($v, 0) || ! self::inRange($e, 0, 5)) { return 'many'; } diff --git a/packages/intl/src/TranslationFailure.php b/packages/intl/src/TranslationFailure.php index 810e7a8cc4..8f1462559d 100644 --- a/packages/intl/src/TranslationFailure.php +++ b/packages/intl/src/TranslationFailure.php @@ -2,13 +2,13 @@ namespace Tempest\Intl; -use Tempest\Intl\Locale; +use Throwable; final readonly class TranslationFailure { public function __construct( public Locale $locale, public string $key, - public \Throwable $exception, + public Throwable $exception, ) {} } diff --git a/packages/intl/src/TranslationMessageDiscovery.php b/packages/intl/src/TranslationMessageDiscovery.php index 9f3a884667..f0662fda3e 100644 --- a/packages/intl/src/TranslationMessageDiscovery.php +++ b/packages/intl/src/TranslationMessageDiscovery.php @@ -8,7 +8,6 @@ use Tempest\Discovery\Discovery; use Tempest\Discovery\DiscoveryLocation; use Tempest\Discovery\IsDiscovery; -use Tempest\Intl\Locale; use Tempest\Reflection\ClassReflector; use function Tempest\Support\arr; diff --git a/packages/intl/src/TranslationMiss.php b/packages/intl/src/TranslationMiss.php index 394a1647db..fe86fead29 100644 --- a/packages/intl/src/TranslationMiss.php +++ b/packages/intl/src/TranslationMiss.php @@ -2,8 +2,6 @@ namespace Tempest\Intl; -use Tempest\Intl\Locale; - final readonly class TranslationMiss { public function __construct( diff --git a/packages/intl/src/Translator.php b/packages/intl/src/Translator.php index def5ead838..e4e25c3165 100644 --- a/packages/intl/src/Translator.php +++ b/packages/intl/src/Translator.php @@ -2,8 +2,6 @@ namespace Tempest\Intl; -use Tempest\Intl\Locale; - interface Translator { /** diff --git a/packages/intl/src/TranslatorInitializer.php b/packages/intl/src/TranslatorInitializer.php index 477b7a77df..4f1a1cbbe7 100644 --- a/packages/intl/src/TranslatorInitializer.php +++ b/packages/intl/src/TranslatorInitializer.php @@ -7,7 +7,6 @@ use Tempest\Container\Singleton; use Tempest\EventBus\EventBus; use Tempest\Intl\Catalog\Catalog; -use Tempest\Intl\IntlConfig; use Tempest\Intl\MessageFormat\Formatter\MessageFormatter; final class TranslatorInitializer implements Initializer diff --git a/packages/intl/src/functions.php b/packages/intl/src/functions.php index 768d7ce0da..ac45bd815b 100644 --- a/packages/intl/src/functions.php +++ b/packages/intl/src/functions.php @@ -5,9 +5,7 @@ use Countable; use Stringable; use Tempest\Container\GenericContainer; -use Tempest\Intl\Locale; use Tempest\Intl\Pluralizer\Pluralizer; -use Tempest\Intl\Translator; use function Tempest\Container\get; diff --git a/packages/intl/tests/FormatterTest.php b/packages/intl/tests/FormatterTest.php index e7428c305c..3bfc6da4e4 100644 --- a/packages/intl/tests/FormatterTest.php +++ b/packages/intl/tests/FormatterTest.php @@ -44,8 +44,8 @@ public function test_placeholder_variable(): void { $formatter = new MessageFormatter(); $value = $formatter->format(<<<'TXT' - Hello, {$name}! - TXT, name: 'Jon'); + Hello, {$name}! + TXT, name: 'Jon'); $this->assertSame('Hello, Jon!', $value); } @@ -59,8 +59,8 @@ public function test_format_datetime_function_and_parameters(): void $formatter = new MessageFormatter([$this->createDateTimeFunction()]); $value = $formatter->format(<<<'TXT' - Today is {$today :datetime pattern=|yyyy/MM/dd|}. - TXT, today: '2024-01-01'); + Today is {$today :datetime pattern=|yyyy/MM/dd|}. + TXT, today: '2024-01-01'); $this->assertSame('Today is 2024/01/01.', $value); } @@ -70,8 +70,8 @@ public function test_format_number_function(): void $formatter = new MessageFormatter([$this->createNumberFunction()]); $value = $formatter->format(<<<'TXT' - The total was {31 :number style=percent}. - TXT); + The total was {31 :number style=percent}. + TXT); $this->assertSame('The total was 31%.', $value); } @@ -84,12 +84,12 @@ public function test_match_number(int $count, string $expected): void $formatter = new MessageFormatter([$this->createNumberFunction()]); $value = $formatter->format(<<<'TXT' - .input {$aircraft :number} - .match $aircraft - 0 {{pas d‘avion}} - 1 {{un avion}} - * {{{$aircraft} avions}} - TXT, aircraft: $count); + .input {$aircraft :number} + .match $aircraft + 0 {{pas d‘avion}} + 1 {{un avion}} + * {{{$aircraft} avions}} + TXT, aircraft: $count); $this->assertSame($expected, $value); } @@ -99,16 +99,16 @@ public function test_default_input(): void $formatter = new MessageFormatter([]); $value = $formatter->format(<<<'TXT' - .input {$field :string default=unknown} - field is {$field} - TXT); + .input {$field :string default=unknown} + field is {$field} + TXT); $this->assertSame('field is unknown', $value); $value = $formatter->format(<<<'TXT' - .input {$field :string default=unknown} - field is {$field} - TXT, field: 'here'); + .input {$field :string default=unknown} + field is {$field} + TXT, field: 'here'); $this->assertSame('field is here', $value); } @@ -117,8 +117,8 @@ public function test_unquoted_text(): void { $formatter = new MessageFormatter(); $value = $formatter->format(<<<'TXT' - Hello, {world}! - TXT); + Hello, {world}! + TXT); $this->assertSame('Hello, world!', $value); } @@ -127,8 +127,8 @@ public function test_quoted_text(): void { $formatter = new MessageFormatter(); $value = $formatter->format(<<<'TXT' - My name is {|John Doe|}. - TXT); + My name is {|John Doe|}. + TXT); $this->assertSame('My name is John Doe.', $value); } @@ -137,11 +137,11 @@ public function test_number_matcher(): void { $formatter = new MessageFormatter([$this->createNumberFunction()]); $value = $formatter->format(<<<'TXT' - .input {$count :number} - .match $count - one {{You have {$count} notification.}} - * {{You have {$count} notifications.}} - TXT, count: 1); + .input {$count :number} + .match $count + one {{You have {$count} notification.}} + * {{You have {$count} notifications.}} + TXT, count: 1); $this->assertSame('You have 1 notification.', $value); } @@ -150,11 +150,11 @@ public function test_number_matcher_exact(): void { $formatter = new MessageFormatter([$this->createNumberFunction()]); $value = $formatter->format(<<<'TXT' - .input {$count :number select=exact} - .match $count - one {{You have {$count} notification.}} - * {{You have {$count} notifications.}} - TXT, count: 1); + .input {$count :number select=exact} + .match $count + one {{You have {$count} notification.}} + * {{You have {$count} notifications.}} + TXT, count: 1); $this->assertSame('You have 1 notifications.', $value); } @@ -163,12 +163,12 @@ public function test_local_declaration(): void { $formatter = new MessageFormatter([new StringFunction()]); $value = $formatter->format(<<<'TXT' - .local $val = {foo2 :string} - .match $val - foo {{Foo}} - bar {{Bar}} - * {{No match}} - TXT); + .local $val = {foo2 :string} + .match $val + foo {{Foo}} + bar {{Bar}} + * {{No match}} + TXT); $this->assertSame('No match', $value); } @@ -177,11 +177,11 @@ public function test_local_declarations_unquoted_literals(): void { $formatter = new MessageFormatter(); $value = $formatter->format(<<<'TXT' - .local $x = {42} - .local $y = {number42} - .local $z = {_number} - {{{$x} {$y} {$z}}} - TXT); + .local $x = {42} + .local $y = {number42} + .local $z = {_number} + {{{$x} {$y} {$z}}} + TXT); $this->assertSame('42 number42 _number', $value); } @@ -190,11 +190,11 @@ public function test_local_declarations_quoted_literals(): void { $formatter = new MessageFormatter(); $value = $formatter->format(<<<'TXT' - .local $x = {|@literal|} - .local $y = {|white space|} - .local $z = {|{{curly braces}}|} - {{{$x} {$y} {$z} {|and \\, a backslash|}}} - TXT); + .local $x = {|@literal|} + .local $y = {|white space|} + .local $z = {|{{curly braces}}|} + {{{$x} {$y} {$z} {|and \\, a backslash|}}} + TXT); $this->assertSame('@literal white space {{curly braces}} and \, a backslash', $value); } @@ -203,9 +203,9 @@ public function test_whitespace(): void { $formatter = new MessageFormatter(); $value = $formatter->format(<<<'TXT' - .input {$num :number} - {{ This is the {$num} pattern }} - TXT, num: 5); + .input {$num :number} + {{ This is the {$num} pattern }} + TXT, num: 5); $this->assertSame(' This is the 5 pattern ', $value); } @@ -214,8 +214,8 @@ public function test_escape(): void { $formatter = new MessageFormatter(); $value = $formatter->format(<<<'TXT' - Backslash: \\, left curly brace \{, right curly brace \} - TXT); + Backslash: \\, left curly brace \{, right curly brace \} + TXT); $this->assertSame('Backslash: \, left curly brace {, right curly brace }', $value); } @@ -224,12 +224,12 @@ public function test_matchers_escape(): void { $formatter = new MessageFormatter(); $value = $formatter->format(<<<'TXT' - .input {$char :string} - .match $char - | | {{You entered a space character.}} - |\|| {{You entered a pipe character.}} - * {{You entered something else.}} - TXT, char: '|'); + .input {$char :string} + .match $char + | | {{You entered a space character.}} + |\|| {{You entered a pipe character.}} + * {{You entered something else.}} + TXT, char: '|'); $this->assertSame('You entered a pipe character.', $value); } @@ -239,12 +239,12 @@ public function test_matchers_number_exact_match(): void $formatter = new MessageFormatter([$this->createNumberFunction()]); $value = $formatter->format(<<<'TXT' - .input {$numDays :number select=exact} - .match $numDays - 1 {{{$numDays} one}} - 2 {{{$numDays} two}} - 3 {{{$numDays} three}} - TXT, numDays: 2); + .input {$numDays :number select=exact} + .match $numDays + 1 {{{$numDays} one}} + 2 {{{$numDays} two}} + 3 {{{$numDays} three}} + TXT, numDays: 2); $this->assertSame('2 two', $value); } @@ -260,13 +260,13 @@ public function test_matchers_czech(int|float $days, string $expected): void $formatter = new MessageFormatter([$this->createNumberFunction()]); $value = $formatter->format(<<<'TXT' - .input {$days :number} - .match $days - one {{{$days} den}} - few {{{$days} dny}} - many {{{$days} dne}} - * {{{$days} dní}} - TXT, days: $days); + .input {$days :number} + .match $days + one {{{$days} den}} + few {{{$days} dny}} + many {{{$days} dne}} + * {{{$days} dní}} + TXT, days: $days); $this->assertSame($expected, $value); } @@ -279,12 +279,12 @@ public function test_string_function(): void ]); $value = $formatter->format(<<<'TXT' - .input {$operand :string} - .match $operand - 1 {{Number 1}} - one {{String "one"}} - * {{Something else}} - TXT, operand: 1); + .input {$operand :string} + .match $operand + 1 {{Number 1}} + one {{String "one"}} + * {{Something else}} + TXT, operand: 1); $this->assertSame('Number 1', $value); } @@ -298,8 +298,8 @@ public function test_string_formatting(mixed $input, string $expected): void $formatter = new MessageFormatter([new StringFunction()]); $value = $formatter->format(<<<'TXT' - {$value :string} - TXT, value: $input); + {$value :string} + TXT, value: $input); $this->assertSame($expected, $value); } @@ -316,8 +316,8 @@ public function test_string_formatting_options(mixed $input, string $expected, s $formatter = new MessageFormatter([new StringFunction()]); $value = $formatter->format(<<assertSame($expected, $value); } @@ -327,8 +327,8 @@ public function test_number_currency(): void $formatter = new MessageFormatter([$this->createNumberFunction()]); $value = $formatter->format(<<<'TXT' - You have {42 :number style=currency currency=$currency}. - TXT, currency: Currency::USD); + You have {42 :number style=currency currency=$currency}. + TXT, currency: Currency::USD); $this->assertSame('You have $42.00.', $value); } @@ -338,9 +338,9 @@ public function test_shadowing(): void $formatter = new MessageFormatter([$this->createNumberFunction()]); $value = $formatter->format(<<<'TXT' - .local $count = {42} - {{The count is: {$count}}} - TXT, count: 32); + .local $count = {42} + {{The count is: {$count}}} + TXT, count: 32); $this->assertSame('The count is: 42', $value); } @@ -353,12 +353,12 @@ public function test_pluralization(int $count, string $expected): void $formatter = new MessageFormatter([$this->createNumberFunction()]); $value = $formatter->format(<<<'TXT' - .input {$count :number} - .match $count - 0 {{No items.}} - one {{1 item.}} - * {{{$count} items.}} - TXT, count: $count); + .input {$count :number} + .match $count + 0 {{No items.}} + one {{1 item.}} + * {{{$count} items.}} + TXT, count: $count); $this->assertSame($expected, $value); } @@ -371,22 +371,22 @@ public function test_multiple_selectors(): void ]); $value = $formatter->format(<<<'TXT' - .input {$hostGender :string} - .input {$guestCount :number} - .match $hostGender $guestCount - female 0 {{{$hostName} does not give a party.}} - female 1 {{{$hostName} invites {$guestName} to her party.}} - female 2 {{{$hostName} invites {$guestName} and one other person to her party.}} - female * {{{$hostName} invites {$guestCount} people, including {$guestName}, to her party.}} - male 0 {{{$hostName} does not give a party.}} - male 1 {{{$hostName} invites {$guestName} to his party.}} - male 2 {{{$hostName} invites {$guestName} and one other person to his party.}} - male * {{{$hostName} invites {$guestCount} people, including {$guestName}, to his party.}} - * 0 {{{$hostName} does not give a party.}} - * 1 {{{$hostName} invites {$guestName} to their party.}} - * 2 {{{$hostName} invites {$guestName} and one other person to their party.}} - * * {{{$hostName} invites {$guestCount} people, including {$guestName}, to their party.}} - TXT, hostGender: 'female', hostName: 'Alice', guestCount: 2, guestName: 'Bob'); + .input {$hostGender :string} + .input {$guestCount :number} + .match $hostGender $guestCount + female 0 {{{$hostName} does not give a party.}} + female 1 {{{$hostName} invites {$guestName} to her party.}} + female 2 {{{$hostName} invites {$guestName} and one other person to her party.}} + female * {{{$hostName} invites {$guestCount} people, including {$guestName}, to her party.}} + male 0 {{{$hostName} does not give a party.}} + male 1 {{{$hostName} invites {$guestName} to his party.}} + male 2 {{{$hostName} invites {$guestName} and one other person to his party.}} + male * {{{$hostName} invites {$guestCount} people, including {$guestName}, to his party.}} + * 0 {{{$hostName} does not give a party.}} + * 1 {{{$hostName} invites {$guestName} to their party.}} + * 2 {{{$hostName} invites {$guestName} and one other person to their party.}} + * * {{{$hostName} invites {$guestCount} people, including {$guestName}, to their party.}} + TXT, hostGender: 'female', hostName: 'Alice', guestCount: 2, guestName: 'Bob'); $this->assertSame('Alice invites Bob and one other person to her party.', $value); } @@ -405,8 +405,8 @@ public function format(mixed $value, array $parameters): FormattedValue ]); $value = $formatter->format(<<<'TXT' - Check out {MessageFormat :uppercase}. - TXT); + Check out {MessageFormat :uppercase}. + TXT); $this->assertSame('Check out MESSAGEFORMAT.', $value); } diff --git a/packages/intl/tests/FunctionsTest.php b/packages/intl/tests/FunctionsTest.php index 3d3c1914d2..1bce006204 100644 --- a/packages/intl/tests/FunctionsTest.php +++ b/packages/intl/tests/FunctionsTest.php @@ -21,12 +21,12 @@ public function test_format_number(): void $this->assertSame('10', Number\format(10)); $this->assertSame('25', Number\format(25)); $this->assertSame('100', Number\format(100)); - $this->assertSame('100,000', Number\format(100000)); - $this->assertSame('100,000.00', Number\format(100000, precision: 2)); - $this->assertSame('100,000.12', Number\format(100000.123, precision: 2)); - $this->assertSame('100,000.123', Number\format(100000.1234, maxPrecision: 3)); - $this->assertSame('100,000.124', Number\format(100000.1236, maxPrecision: 3)); - $this->assertSame('123,456,789', Number\format(123456789)); + $this->assertSame('100,000', Number\format(100_000)); + $this->assertSame('100,000.00', Number\format(100_000, precision: 2)); + $this->assertSame('100,000.12', Number\format(100_000.123, precision: 2)); + $this->assertSame('100,000.123', Number\format(100_000.123_4, maxPrecision: 3)); + $this->assertSame('100,000.124', Number\format(100_000.123_6, maxPrecision: 3)); + $this->assertSame('123,456,789', Number\format(123_456_789)); $this->assertSame('-1', Number\format(-1)); $this->assertSame('-10', Number\format(-10)); @@ -77,8 +77,8 @@ public function test_spellout_with_threshold(): void $this->assertSame('10', Number\spell_out(10, until: 10)); $this->assertSame('11', Number\spell_out(11, until: 10)); - $this->assertSame('ten thousand', Number\spell_out(10000, until: 50000)); - $this->assertSame('100,000', Number\spell_out(100000, until: 50000)); + $this->assertSame('ten thousand', Number\spell_out(10_000, until: 50_000)); + $this->assertSame('100,000', Number\spell_out(100_000, until: 50_000)); } #[RequiresPhpExtension('intl')] @@ -114,10 +114,10 @@ public function test_to_percent(): void $this->assertSame('2%', Number\to_percentage(1.75)); $this->assertSame('1.75%', Number\to_percentage(1.75, precision: 2)); $this->assertSame('1.750%', Number\to_percentage(1.75, precision: 3)); - $this->assertSame('0%', Number\to_percentage(0.12345)); + $this->assertSame('0%', Number\to_percentage(0.123_45)); $this->assertSame('0.00%', Number\to_percentage(0, precision: 2)); - $this->assertSame('0.12%', Number\to_percentage(0.12345, precision: 2)); - $this->assertSame('0.1235%', Number\to_percentage(0.12345, precision: 4)); + $this->assertSame('0.12%', Number\to_percentage(0.123_45, precision: 2)); + $this->assertSame('0.1235%', Number\to_percentage(0.123_45, precision: 4)); } #[RequiresPhpExtension('intl')] @@ -147,8 +147,8 @@ public function test_to_currency_with_different_locale(): void $this->assertSame('1,00 $', Number\currency(1, Currency::USD, Locale::GERMAN)); $this->assertSame('1,00 £', Number\currency(1, Currency::GBP, Locale::GERMAN)); - $this->assertSame('123.456.789,12 $', Number\currency(123456789.12345, Currency::USD, Locale::GERMAN)); - $this->assertSame('123.456.789,12 €', Number\currency(123456789.12345, Currency::EUR, Locale::GERMAN)); + $this->assertSame('123.456.789,12 $', Number\currency(123_456_789.123_45, Currency::USD, Locale::GERMAN)); + $this->assertSame('123.456.789,12 €', Number\currency(123_456_789.123_45, Currency::EUR, Locale::GERMAN)); $this->assertSame('1 234,56 $US', Number\currency(1234.56, Currency::USD, Locale::FRENCH)); } @@ -180,7 +180,7 @@ public function test_bytes_to_human(): void $this->assertSame('2 KiB', Number\to_file_size(2048, useBinaryPrefix: true)); $this->assertSame('2.00 KiB', Number\to_file_size(2048, precision: 2, useBinaryPrefix: true)); $this->assertSame('1.23 KiB', Number\to_file_size(1264, precision: 2, useBinaryPrefix: true)); - $this->assertSame('1.234 KiB', Number\to_file_size(1264.12345, maxPrecision: 3, useBinaryPrefix: true)); + $this->assertSame('1.234 KiB', Number\to_file_size(1_264.123_45, maxPrecision: 3, useBinaryPrefix: true)); $this->assertSame('1.234 KiB', Number\to_file_size(1264, 3, useBinaryPrefix: true)); $this->assertSame('5 GiB', Number\to_file_size(1024 * 1024 * 1024 * 5, useBinaryPrefix: true)); $this->assertSame('10 TiB', Number\to_file_size((1024 ** 4) * 10, useBinaryPrefix: true)); @@ -204,31 +204,31 @@ public function test_summarize(): void $this->assertSame('1K', Number\to_human_readable(1000, maxPrecision: 2)); $this->assertSame('1K', Number\to_human_readable(1230)); $this->assertSame('1.2K', Number\to_human_readable(1230, maxPrecision: 1)); - $this->assertSame('1M', Number\to_human_readable(1000000)); - $this->assertSame('1B', Number\to_human_readable(1000000000)); - $this->assertSame('1T', Number\to_human_readable(1000000000000)); - $this->assertSame('1Q', Number\to_human_readable(1000000000000000)); - $this->assertSame('1KQ', Number\to_human_readable(1000000000000000000)); + $this->assertSame('1M', Number\to_human_readable(1_000_000)); + $this->assertSame('1B', Number\to_human_readable(1_000_000_000)); + $this->assertSame('1T', Number\to_human_readable(1_000_000_000_000)); + $this->assertSame('1Q', Number\to_human_readable(1_000_000_000_000_000)); + $this->assertSame('1KQ', Number\to_human_readable(1_000_000_000_000_000_000)); $this->assertSame('123', Number\to_human_readable(123)); $this->assertSame('1K', Number\to_human_readable(1234)); $this->assertSame('1.23K', Number\to_human_readable(1234, precision: 2)); - $this->assertSame('12K', Number\to_human_readable(12345)); - $this->assertSame('1M', Number\to_human_readable(1234567)); - $this->assertSame('1B', Number\to_human_readable(1234567890)); - $this->assertSame('1T', Number\to_human_readable(1234567890123)); - $this->assertSame('1.23T', Number\to_human_readable(1234567890123, precision: 2)); - $this->assertSame('1Q', Number\to_human_readable(1234567890123456)); - $this->assertSame('1.23KQ', Number\to_human_readable(1234567890123456789, precision: 2)); - $this->assertSame('490K', Number\to_human_readable(489939)); - $this->assertSame('489.9390K', Number\to_human_readable(489939, precision: 4)); - $this->assertSame('500.00000M', Number\to_human_readable(500000000, precision: 5)); - - $this->assertSame('1MQ', Number\to_human_readable(1000000000000000000000)); - $this->assertSame('1BQ', Number\to_human_readable(1000000000000000000000000)); - $this->assertSame('1TQ', Number\to_human_readable(1000000000000000000000000000)); - $this->assertSame('1QQ', Number\to_human_readable(1000000000000000000000000000000)); - $this->assertSame('1KQQ', Number\to_human_readable(1000000000000000000000000000000000)); + $this->assertSame('12K', Number\to_human_readable(12_345)); + $this->assertSame('1M', Number\to_human_readable(1_234_567)); + $this->assertSame('1B', Number\to_human_readable(1_234_567_890)); + $this->assertSame('1T', Number\to_human_readable(1_234_567_890_123)); + $this->assertSame('1.23T', Number\to_human_readable(1_234_567_890_123, precision: 2)); + $this->assertSame('1Q', Number\to_human_readable(1_234_567_890_123_456)); + $this->assertSame('1.23KQ', Number\to_human_readable(1_234_567_890_123_456_789, precision: 2)); + $this->assertSame('490K', Number\to_human_readable(489_939)); + $this->assertSame('489.9390K', Number\to_human_readable(489_939, precision: 4)); + $this->assertSame('500.00000M', Number\to_human_readable(500_000_000, precision: 5)); + + $this->assertSame('1MQ', Number\to_human_readable(1_000_000_000_000_000_000_000)); + $this->assertSame('1BQ', Number\to_human_readable(1_000_000_000_000_000_000_000_000)); + $this->assertSame('1TQ', Number\to_human_readable(1_000_000_000_000_000_000_000_000_000)); + $this->assertSame('1QQ', Number\to_human_readable(1_000_000_000_000_000_000_000_000_000_000)); + $this->assertSame('1KQQ', Number\to_human_readable(1_000_000_000_000_000_000_000_000_000_000_000)); $this->assertSame('0', Number\to_human_readable(0)); $this->assertSame('0', Number\to_human_readable(0.0)); @@ -241,12 +241,12 @@ public function test_summarize(): void $this->assertSame('-1K', Number\to_human_readable(-1000)); $this->assertSame('-1.23K', Number\to_human_readable(-1234, precision: 2)); $this->assertSame('-1.2K', Number\to_human_readable(-1234, maxPrecision: 1)); - $this->assertSame('-1M', Number\to_human_readable(-1000000)); - $this->assertSame('-1B', Number\to_human_readable(-1000000000)); - $this->assertSame('-1T', Number\to_human_readable(-1000000000000)); - $this->assertSame('-1.1T', Number\to_human_readable(-1100000000000, maxPrecision: 1)); - $this->assertSame('-1Q', Number\to_human_readable(-1000000000000000)); - $this->assertSame('-1KQ', Number\to_human_readable(-1000000000000000000)); + $this->assertSame('-1M', Number\to_human_readable(-1_000_000)); + $this->assertSame('-1B', Number\to_human_readable(-1_000_000_000)); + $this->assertSame('-1T', Number\to_human_readable(-1_000_000_000_000)); + $this->assertSame('-1.1T', Number\to_human_readable(-1_100_000_000_000, maxPrecision: 1)); + $this->assertSame('-1Q', Number\to_human_readable(-1_000_000_000_000_000)); + $this->assertSame('-1KQ', Number\to_human_readable(-1_000_000_000_000_000_000)); } public function test_parse_int(): void diff --git a/packages/intl/tests/GenericTranslatorTest.php b/packages/intl/tests/GenericTranslatorTest.php index fcc76a9f8d..7863c3a7bb 100644 --- a/packages/intl/tests/GenericTranslatorTest.php +++ b/packages/intl/tests/GenericTranslatorTest.php @@ -17,7 +17,9 @@ final class GenericTranslatorTest extends TestCase { private Catalog $catalog; + private Translator $translator; + private IntlConfig $config; protected function setUp(): void @@ -66,12 +68,12 @@ public function test_complex_message(): void $this->config->currentLocale = Locale::FRENCH; $this->catalog->add(Locale::FRENCH, 'aircraft_count', <<<'MF2' - .input {$aircraft :number} - .match $aircraft - 0 {{pas d'avion}} - 1 {{un avion}} - * {{{$aircraft} avions}} - MF2); + .input {$aircraft :number} + .match $aircraft + 0 {{pas d'avion}} + 1 {{un avion}} + * {{{$aircraft} avions}} + MF2); $this->assertSame("pas d'avion", $this->translator->translate('aircraft_count', aircraft: 0)); $this->assertSame('un avion', $this->translator->translate('aircraft_count', aircraft: 1)); diff --git a/packages/intl/tests/LocaleTest.php b/packages/intl/tests/LocaleTest.php index e914d8632c..79c3d5715a 100644 --- a/packages/intl/tests/LocaleTest.php +++ b/packages/intl/tests/LocaleTest.php @@ -5,6 +5,7 @@ namespace Tempest\Intl\Tests; use Generator; +use Override; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Tempest\Intl\Locale; @@ -18,13 +19,13 @@ final class LocaleTest extends TestCase { private ?string $defaultLocale = null; - #[\Override] + #[Override] protected function setUp(): void { $this->defaultLocale = locale_get_default(); } - #[\Override] + #[Override] protected function tearDown(): void { if (null !== $this->defaultLocale) { @@ -174,9 +175,11 @@ public function test_it_returns_the_language_and_human_readable_name(Locale $loc public static function getLocalesWithScript(): Generator { foreach (Locale::cases() as $locale) { - if ($locale->hasScript()) { - yield $locale->value => [$locale]; + if (! $locale->hasScript()) { + continue; } + + yield $locale->value => [$locale]; } return null; @@ -195,9 +198,11 @@ public function test_it_returns_the_script(Locale $locale): void public static function getLocalesWithoutScript(): Generator { foreach (Locale::cases() as $locale) { - if (! $locale->hasScript()) { - yield $locale->value => [$locale]; + if ($locale->hasScript()) { + continue; } + + yield $locale->value => [$locale]; } return null; @@ -216,9 +221,11 @@ public function test_it_does_not_returns_the_script(Locale $locale): void public static function getLocalesWithRegion(): Generator { foreach (Locale::cases() as $locale) { - if ($locale->hasRegion()) { - yield $locale->value => [$locale]; + if (! $locale->hasRegion()) { + continue; } + + yield $locale->value => [$locale]; } return null; @@ -238,9 +245,11 @@ public function test_it_returns_the_region(Locale $locale): void public static function getLocalesWithoutRegion(): Generator { foreach (Locale::cases() as $locale) { - if (! $locale->hasRegion()) { - yield $locale->value => [$locale]; + if ($locale->hasRegion()) { + continue; } + + yield $locale->value => [$locale]; } return null; diff --git a/packages/intl/tests/ParserTest.php b/packages/intl/tests/ParserTest.php index 9860918397..9138034599 100644 --- a/packages/intl/tests/ParserTest.php +++ b/packages/intl/tests/ParserTest.php @@ -30,9 +30,9 @@ public function test_local_declaration(): void { /** @var ComplexMessage $ast */ $ast = new MessageFormatParser(<<<'MF2' - .local $time = {$launch_date :datetime style=|medium|} - Launch time: {$time} - MF2)->parse(); + .local $time = {$launch_date :datetime style=|medium|} + Launch time: {$time} + MF2)->parse(); $this->assertInstanceOf(ComplexMessage::class, $ast); $this->assertInstanceOf(Text::class, $ast->pattern->elements[0]); @@ -53,12 +53,12 @@ public function test_input_declaration(): void { /** @var ComplexMessage $ast */ $ast = new MessageFormatParser(<<<'MF2' - .input {$numDays :number select=exact} - .match $numDays - 1 {{{$numDays} one}} - 2 {{{$numDays} two}} - 3 {{{$numDays} three}} - MF2)->parse(); + .input {$numDays :number select=exact} + .match $numDays + 1 {{{$numDays} one}} + 2 {{{$numDays} two}} + 3 {{{$numDays} three}} + MF2)->parse(); $this->assertInstanceOf(ComplexMessage::class, $ast); $this->assertInstanceOf(InputDeclaration::class, $ast->declarations[0]); @@ -88,8 +88,8 @@ public function test_input_declaration(): void public function test_function_with_option_quoted_literal(): void { $ast = new MessageFormatParser(<<<'MF2' - Today is {$today :datetime pattern=|yyyy/MM/dd|}. - MF2)->parse(); + Today is {$today :datetime pattern=|yyyy/MM/dd|}. + MF2)->parse(); $this->assertInstanceOf(SimpleMessage::class, $ast); $this->assertInstanceOf(VariableExpression::class, $ast->pattern->elements[1]); diff --git a/packages/kv-store/src/Redis/PhpRedisClient.php b/packages/kv-store/src/Redis/PhpRedisClient.php index 8002e1486b..9947924ba5 100644 --- a/packages/kv-store/src/Redis/PhpRedisClient.php +++ b/packages/kv-store/src/Redis/PhpRedisClient.php @@ -2,6 +2,7 @@ namespace Tempest\KeyValue\Redis; +use InvalidArgumentException; use Stringable; use Tempest\DateTime\DateTime; use Tempest\DateTime\DateTimeInterface; @@ -57,7 +58,7 @@ public function connect(): void } if ($this->config->options && ! is_associative($this->config->options)) { - throw new \InvalidArgumentException('The `options` property of the Redis configuration must be an associative array.'); + throw new InvalidArgumentException('The `options` property of the Redis configuration must be an associative array.'); } foreach ($this->config->options as $key => $value) { @@ -109,7 +110,7 @@ public function set(Stringable|string $key, mixed $value, null|Duration|DateTime $this->command('SET', ...array_filter([ (string) $key, // key $this->serializeValue($value), // value - $expiration ? 'PX' : null, // ttl format + $expiration instanceof Duration ? 'PX' : null, // ttl format (int) $expiration?->getTotalMilliseconds(), // ttl ])); } diff --git a/packages/kv-store/src/Redis/PredisClient.php b/packages/kv-store/src/Redis/PredisClient.php index d2f01d3773..d4a424a87f 100644 --- a/packages/kv-store/src/Redis/PredisClient.php +++ b/packages/kv-store/src/Redis/PredisClient.php @@ -72,7 +72,7 @@ public function set(Stringable|string $key, mixed $value, null|Duration|DateTime $this->command('SET', ...array_filter([ (string) $key, // key $this->serializeValue($value), // value - $expiration ? 'PX' : null, // ttl format + $expiration instanceof Duration ? 'PX' : null, // ttl format (int) $expiration?->getTotalMilliseconds(), // ttl ])); } diff --git a/packages/kv-store/src/Redis/Redis.php b/packages/kv-store/src/Redis/Redis.php index 459272789f..9793d91467 100644 --- a/packages/kv-store/src/Redis/Redis.php +++ b/packages/kv-store/src/Redis/Redis.php @@ -2,6 +2,7 @@ namespace Tempest\KeyValue\Redis; +use Predis\Client; use Stringable; use Tempest\DateTime\DateTimeInterface; use Tempest\DateTime\Duration; @@ -11,7 +12,7 @@ interface Redis /** * Get the underlying client. This breaks abstraction and should only be used if absolutely necessary. */ - public function getClient(): \Redis|\Predis\Client; + public function getClient(): \Redis|Client; /** * Flushes the Redis database. diff --git a/packages/kv-store/src/Redis/RedisException.php b/packages/kv-store/src/Redis/RedisException.php index ea92d27bd7..4e1d824d8a 100644 --- a/packages/kv-store/src/Redis/RedisException.php +++ b/packages/kv-store/src/Redis/RedisException.php @@ -4,6 +4,4 @@ use Throwable; -interface RedisException extends Throwable -{ -} +interface RedisException extends Throwable {} diff --git a/packages/kv-store/src/Redis/RedisExtensionWasMissing.php b/packages/kv-store/src/Redis/RedisExtensionWasMissing.php index 19a05154ae..be65dae71e 100644 --- a/packages/kv-store/src/Redis/RedisExtensionWasMissing.php +++ b/packages/kv-store/src/Redis/RedisExtensionWasMissing.php @@ -4,6 +4,7 @@ use Exception; use Predis; +use Predis\Client; final class RedisExtensionWasMissing extends Exception implements RedisException { @@ -12,7 +13,7 @@ public function __construct(string $fqcn) parent::__construct( 'Redis client not found.' . match ($fqcn) { \Redis::class => ' You may be missing the `redis` extension.', - Predis\Client::class => ' You may need to install the `predis/predis` package.', + Client::class => ' You may need to install the `predis/predis` package.', default => ' Install the `redis` extension or the `predis/predis` package.', }, ); diff --git a/packages/kv-store/src/Redis/RedisInitializer.php b/packages/kv-store/src/Redis/RedisInitializer.php index 9eeccfe570..68339f3dd7 100644 --- a/packages/kv-store/src/Redis/RedisInitializer.php +++ b/packages/kv-store/src/Redis/RedisInitializer.php @@ -3,6 +3,7 @@ namespace Tempest\KeyValue\Redis; use Predis; +use Predis\Client; use Tempest\Container\Container; use Tempest\Container\Initializer; use Tempest\Container\Singleton; @@ -33,13 +34,13 @@ private function buildPhpRedisClient(): \Redis return new \Redis(); } - private function buildPredisClient(RedisConfig $config): Predis\Client + private function buildPredisClient(RedisConfig $config): Client { - if (! class_exists(Predis\Client::class)) { - throw new RedisExtensionWasMissing(Predis\Client::class); + if (! class_exists(Client::class)) { + throw new RedisExtensionWasMissing(Client::class); } - return new Predis\Client( + return new Client( parameters: array_filter([ 'scheme' => $config->scheme->value, 'host' => $config->host ?? '127.0.0.1', diff --git a/packages/kv-store/src/Redis/RedisInsightsProvider.php b/packages/kv-store/src/Redis/RedisInsightsProvider.php index 7ef93de84f..fb1e803b54 100644 --- a/packages/kv-store/src/Redis/RedisInsightsProvider.php +++ b/packages/kv-store/src/Redis/RedisInsightsProvider.php @@ -3,11 +3,13 @@ namespace Tempest\KeyValue\Redis; use Predis; +use Predis\Client; use Tempest\Container\Container; use Tempest\Core\Insight; use Tempest\Core\InsightsProvider; use Tempest\Core\InsightType; use Tempest\Support\Regex; +use Throwable; final class RedisInsightsProvider implements InsightsProvider { @@ -26,14 +28,14 @@ public function getInsights(): array $version = Regex\get_match($redis->command('info', 'server'), '/redis_version:(?[0-9.]+)/', match: 'version'); return [ - 'Engine' => match (get_class($redis->getClient())) { + 'Engine' => match ($redis->getClient()::class) { \Redis::class => 'Redis extension', - Predis\Client::class => 'Predis', + Client::class => 'Predis', default => new Insight('None', InsightType::WARNING), }, 'Version' => $version ?: new Insight('Unknown', InsightType::WARNING), ]; - } catch (\Throwable) { + } catch (Throwable) { return [ 'Engine' => new Insight('Disconnected', InsightType::ERROR), ]; diff --git a/packages/kv-store/tests/PredisClientTest.php b/packages/kv-store/tests/PredisClientTest.php index 72ee2fa352..16d53ed709 100644 --- a/packages/kv-store/tests/PredisClientTest.php +++ b/packages/kv-store/tests/PredisClientTest.php @@ -6,6 +6,7 @@ use PHPUnit\Framework\Attributes\PreCondition; use PHPUnit\Framework\TestCase; use Predis; +use Predis\Client; use Tempest\KeyValue\Redis\PredisClient; use Throwable; @@ -16,12 +17,12 @@ final class PredisClientTest extends TestCase #[PreCondition] protected function configure(): void { - if (! class_exists(Predis\Client::class)) { + if (! class_exists(Client::class)) { $this->markTestSkipped('The `predis/predis` package is not installed.'); } $this->redis = new PredisClient( - client: new Predis\Client( + client: new Client( parameters: [ 'scheme' => 'tcp', 'host' => '127.0.0.1', @@ -52,7 +53,7 @@ protected function cleanup(): void public function test_basic(): void { $this->assertSame('response', $this->redis->command('PING', 'response')); - $this->assertInstanceOf(Predis\Client::class, $this->redis->getClient()); + $this->assertInstanceOf(Client::class, $this->redis->getClient()); } public function test_set(): void diff --git a/packages/log/src/Channels/SlackLogChannel.php b/packages/log/src/Channels/SlackLogChannel.php index b080a0aa4e..b572d703fc 100644 --- a/packages/log/src/Channels/SlackLogChannel.php +++ b/packages/log/src/Channels/SlackLogChannel.php @@ -41,9 +41,9 @@ public function getHandlers(Level $level): array webhookUrl: $this->webhookUrl, channel: $this->channelId, username: $this->username, - level: $level, useAttachment: $this->mode === PresentationMode::BLOCKS || $this->mode === PresentationMode::BLOCKS_WITH_CONTEXT, includeContextAndExtra: $this->mode === PresentationMode::BLOCKS_WITH_CONTEXT, + level: $level, ), ]; } diff --git a/packages/log/src/LogConfig.php b/packages/log/src/LogConfig.php index 4e3502073f..f78d941069 100644 --- a/packages/log/src/LogConfig.php +++ b/packages/log/src/LogConfig.php @@ -11,16 +11,12 @@ interface LogConfig extends HasTag /** * An optional prefix displayed in all log messages. By default, the current environment is used. */ - public ?string $prefix { - get; - } + public ?string $prefix { get; } /** * The log channels to which log messages will be sent. * * @var LogChannel[] */ - public array $logChannels { - get; - } + public array $logChannels { get; } } diff --git a/packages/log/src/Logger.php b/packages/log/src/Logger.php index 0ebe03df39..e8ba8017ee 100644 --- a/packages/log/src/Logger.php +++ b/packages/log/src/Logger.php @@ -6,6 +6,4 @@ use Psr\Log\LoggerInterface; -interface Logger extends LoggerInterface -{ -} +interface Logger extends LoggerInterface {} diff --git a/packages/log/src/TailLogsCommand.php b/packages/log/src/TailLogsCommand.php index b4cd35543c..c3d36f6230 100644 --- a/packages/log/src/TailLogsCommand.php +++ b/packages/log/src/TailLogsCommand.php @@ -11,7 +11,6 @@ use Tempest\Container\Tag; use Tempest\Highlight\Highlighter; use Tempest\Log\Channels\AppendLogChannel; -use Tempest\Log\LogConfig; use Tempest\Support\Filesystem; final readonly class TailLogsCommand @@ -26,15 +25,7 @@ public function __construct( #[ConsoleCommand('tail:logs', description: 'Tails the project logs', aliases: ['log:tail', 'logs:tail'])] public function __invoke(): void { - $appendLogChannel = null; - - foreach ($this->config->logChannels as $channel) { - if ($channel instanceof AppendLogChannel) { - $appendLogChannel = $channel; - break; - } - } - + $appendLogChannel = array_find($this->config->logChannels, fn ($channel) => $channel instanceof AppendLogChannel); if ($appendLogChannel === null) { $this->console->error('Tailing logs is only supported when a AppendLogChannel is configured.'); return; diff --git a/packages/log/src/logging.config.php b/packages/log/src/logging.config.php index 227806df96..696b2e2eaa 100644 --- a/packages/log/src/logging.config.php +++ b/packages/log/src/logging.config.php @@ -9,6 +9,6 @@ return new DailyLogConfig( path: Tempest\internal_storage_path('logs', 'tempest.log'), - prefix: Tempest\env('ENVIRONMENT', default: 'tempest'), maxFiles: Tempest\env('LOG_MAX_FILES', default: 31), + prefix: Tempest\env('ENVIRONMENT', default: 'tempest'), ); diff --git a/packages/mail/src/Email.php b/packages/mail/src/Email.php index d8221cfdb5..74a856af4e 100644 --- a/packages/mail/src/Email.php +++ b/packages/mail/src/Email.php @@ -12,14 +12,10 @@ interface Email /** * The envelope of the email. */ - public Envelope $envelope { - get; - } + public Envelope $envelope { get; } /** * The content of the email can be a path to a view file, raw HTML, or a View object */ - public string|View $html { - get; - } + public string|View $html { get; } } diff --git a/packages/mail/src/Exceptions/MailerException.php b/packages/mail/src/Exceptions/MailerException.php index fc51bd89ca..0a4747668c 100644 --- a/packages/mail/src/Exceptions/MailerException.php +++ b/packages/mail/src/Exceptions/MailerException.php @@ -2,6 +2,4 @@ namespace Tempest\Mail\Exceptions; -interface MailerException -{ -} +interface MailerException {} diff --git a/packages/mail/src/HasAttachments.php b/packages/mail/src/HasAttachments.php index 70423315cd..6ef8742ff8 100644 --- a/packages/mail/src/HasAttachments.php +++ b/packages/mail/src/HasAttachments.php @@ -7,7 +7,5 @@ interface HasAttachments /** * @var \Tempest\Mail\Attachment[] $attachments */ - public array $attachments { - get; - } + public array $attachments { get; } } diff --git a/packages/mail/src/HasTextContent.php b/packages/mail/src/HasTextContent.php index d1e5e6f95e..d4b6a33c6b 100644 --- a/packages/mail/src/HasTextContent.php +++ b/packages/mail/src/HasTextContent.php @@ -6,7 +6,5 @@ interface HasTextContent { - public string|View|null $text { - get; - } + public string|View|null $text { get; } } diff --git a/packages/mail/src/MailerConfig.php b/packages/mail/src/MailerConfig.php index 4cbfbb618e..28c1ac6f47 100644 --- a/packages/mail/src/MailerConfig.php +++ b/packages/mail/src/MailerConfig.php @@ -11,9 +11,7 @@ interface MailerConfig * * @var class-string */ - public string $transport { - get; - } + public string $transport { get; } /** * Creates the transport. diff --git a/packages/mail/src/MailerInitializer.php b/packages/mail/src/MailerInitializer.php index 3a5da65eb1..3869579ac2 100644 --- a/packages/mail/src/MailerInitializer.php +++ b/packages/mail/src/MailerInitializer.php @@ -6,7 +6,6 @@ use Tempest\Container\Initializer; use Tempest\Container\Singleton; use Tempest\EventBus\EventBus; -use Tempest\Mail\MailerConfig; final class MailerInitializer implements Initializer { diff --git a/packages/mail/src/Testing/MailTester.php b/packages/mail/src/Testing/MailTester.php index 1d19951bcf..c569806855 100644 --- a/packages/mail/src/Testing/MailTester.php +++ b/packages/mail/src/Testing/MailTester.php @@ -52,7 +52,7 @@ public function assertSent(string $email, ?Closure $callback = null): self message: sprintf('Email `%s` was not sent.', $email), ); - if ($callback) { + if ($callback instanceof Closure) { try { if ($callback($sentEmail) === false) { throw new ExpectationFailedException('The assertion callback returned `false`.'); @@ -369,13 +369,15 @@ public function assertAttached(string $filename, ?Closure $callback = null): sel ); foreach ($attachments as $attachment) { - if ($attachment->getFilename() === $filename) { - if ($callback && $callback(new AttachmentTester($attachment)) === false) { - Assert::fail(sprintf('The assertion callback returned `false` for attachment `%s`.', $filename)); - } + if ($attachment->getFilename() !== $filename) { + continue; + } - return $this; + if ($callback && $callback(new AttachmentTester($attachment)) === false) { + Assert::fail(sprintf('The assertion callback returned `false` for attachment `%s`.', $filename)); } + + return $this; } Assert::fail(sprintf( @@ -444,12 +446,10 @@ private function assertAddressListDoesNotContain(null|string|array|EmailAddress private function convertAddresses(null|string|array|EmailAddress $addresses): array { return arr($addresses) - ->map(function (string|EmailAddress|SymfonyAddress $address) { - return match (true) { - $address instanceof SymfonyAddress => $address->getAddress(), - $address instanceof EmailAddress => $address->email, - default => $address, - }; + ->map(fn (string|EmailAddress|SymfonyAddress $address) => match (true) { + $address instanceof SymfonyAddress => $address->getAddress(), + $address instanceof EmailAddress => $address->email, + default => $address, }) ->filter() ->toArray(); diff --git a/packages/mail/src/Transports/ProvidesDefaultSender.php b/packages/mail/src/Transports/ProvidesDefaultSender.php index 20486a4439..fceb3701ae 100644 --- a/packages/mail/src/Transports/ProvidesDefaultSender.php +++ b/packages/mail/src/Transports/ProvidesDefaultSender.php @@ -9,7 +9,5 @@ interface ProvidesDefaultSender /** * The default address from which emails will be sent. */ - public null|string|EmailAddress $defaultSender { - get; - } + public null|string|EmailAddress $defaultSender { get; } } diff --git a/packages/mapper/src/CasterFactory.php b/packages/mapper/src/CasterFactory.php index f9f488a27b..43fcd6268c 100644 --- a/packages/mapper/src/CasterFactory.php +++ b/packages/mapper/src/CasterFactory.php @@ -65,19 +65,17 @@ public function forProperty(PropertyReflector $property): ?Caster $castWith = $type->asClass()->getAttribute(CastWith::class, recursive: true); } - if ($castWith) { + if ($castWith instanceof CastWith) { return $this->container->get($castWith->className, context: $context); } - if ($casterAttribute = $property->getAttribute(ProvidesCaster::class)) { + if (($casterAttribute = $property->getAttribute(ProvidesCaster::class)) instanceof ProvidesCaster) { return $this->container->get($casterAttribute->caster, context: $context); } foreach ($this->resolveCasters() as [$casterClass]) { - if (is_a($casterClass, DynamicCaster::class, allow_string: true)) { - if (! $casterClass::accepts($property)) { - continue; - } + if (is_a($casterClass, DynamicCaster::class, allow_string: true) && ! $casterClass::accepts($property)) { + continue; } if (is_a($casterClass, ConfigurableCaster::class, allow_string: true)) { diff --git a/packages/mapper/src/Casters/ArrayToObjectCollectionCaster.php b/packages/mapper/src/Casters/ArrayToObjectCollectionCaster.php index 12e99b11f6..67cdb2a755 100644 --- a/packages/mapper/src/Casters/ArrayToObjectCollectionCaster.php +++ b/packages/mapper/src/Casters/ArrayToObjectCollectionCaster.php @@ -26,7 +26,7 @@ public static function accepts(PropertyReflector|TypeReflector $input): bool return false; } - return $input->getIterableType() !== null; + return $input->getIterableType() instanceof TypeReflector; } public static function configure(PropertyReflector $property, Context $context): self @@ -53,11 +53,7 @@ public function cast(mixed $input): mixed $values = []; foreach ($input as $key => $item) { - if (is_object($item) && $iterableType->matches($item::class)) { - $values[$key] = $item; - } else { - $values[$key] = $caster->cast($item); - } + $values[$key] = is_object($item) && $iterableType->matches($item::class) ? $item : $caster->cast($item); } return $values; diff --git a/packages/mapper/src/Casters/DateTimeCaster.php b/packages/mapper/src/Casters/DateTimeCaster.php index f6b42f4201..c3a11ae841 100644 --- a/packages/mapper/src/Casters/DateTimeCaster.php +++ b/packages/mapper/src/Casters/DateTimeCaster.php @@ -15,6 +15,7 @@ use Tempest\Reflection\PropertyReflector; use Tempest\Reflection\TypeReflector; use Tempest\Validation\Rules\HasDateTimeFormat; +use Throwable; #[Priority(Priority::HIGHEST)] final readonly class DateTimeCaster implements Caster, DynamicCaster, ConfigurableCaster @@ -55,7 +56,7 @@ public function cast(mixed $input): ?DateTimeInterface } return DateTime::parse($input); - } catch (\Throwable) { + } catch (Throwable) { return null; } } diff --git a/packages/mapper/src/Casters/EnumCaster.php b/packages/mapper/src/Casters/EnumCaster.php index c3fa26e67a..7de8fba526 100644 --- a/packages/mapper/src/Casters/EnumCaster.php +++ b/packages/mapper/src/Casters/EnumCaster.php @@ -4,6 +4,7 @@ namespace Tempest\Mapper\Casters; +use BackedEnum; use Tempest\Core\Priority; use Tempest\Mapper\Caster; use Tempest\Mapper\ConfigurableCaster; @@ -51,7 +52,7 @@ public function cast(mixed $input): ?object return constant("{$this->enum}::{$input}"); } - if (! is_a($this->enum, \BackedEnum::class, allow_string: true)) { + if (! is_a($this->enum, BackedEnum::class, allow_string: true)) { return null; } diff --git a/packages/mapper/src/Context.php b/packages/mapper/src/Context.php index 917e1d8b7b..444d8f179c 100644 --- a/packages/mapper/src/Context.php +++ b/packages/mapper/src/Context.php @@ -10,7 +10,5 @@ interface Context /** * A unique name for this context. */ - public string $name { - get; - } + public string $name { get; } } diff --git a/packages/mapper/src/Exceptions/MappingValuesWereMissing.php b/packages/mapper/src/Exceptions/MappingValuesWereMissing.php index 64782e50c3..d9bb0caaa0 100644 --- a/packages/mapper/src/Exceptions/MappingValuesWereMissing.php +++ b/packages/mapper/src/Exceptions/MappingValuesWereMissing.php @@ -10,11 +10,7 @@ final class MappingValuesWereMissing extends Exception { public function __construct(object|string $objectOrClass, array $missingValues) { - if (is_string($objectOrClass)) { - $className = $objectOrClass; - } else { - $className = $objectOrClass::class; - } + $className = is_string($objectOrClass) ? $objectOrClass : $objectOrClass::class; $missingValues = implode(', ', $missingValues); diff --git a/packages/mapper/src/Hidden.php b/packages/mapper/src/Hidden.php index 9c9e94f05c..964c4379c9 100644 --- a/packages/mapper/src/Hidden.php +++ b/packages/mapper/src/Hidden.php @@ -10,6 +10,4 @@ * Hidden properties are excluded from SELECT queries and serialization. */ #[Attribute(Attribute::TARGET_PROPERTY)] -final readonly class Hidden -{ -} +final readonly class Hidden {} diff --git a/packages/mapper/src/Mappers/ArrayToObjectMapper.php b/packages/mapper/src/Mappers/ArrayToObjectMapper.php index 3d95d8645a..8b4ff4bc73 100644 --- a/packages/mapper/src/Mappers/ArrayToObjectMapper.php +++ b/packages/mapper/src/Mappers/ArrayToObjectMapper.php @@ -12,6 +12,7 @@ use Tempest\Mapper\Strict; use Tempest\Reflection\ClassReflector; use Tempest\Reflection\PropertyReflector; +use Tempest\Reflection\TypeReflector; use Tempest\Support\Arr; use Tempest\Support\Memoization\HasMemoization; use Throwable; @@ -122,7 +123,11 @@ private function resolveObject(mixed $objectOrClass): object private function setParentRelations(object $parent, ClassReflector $parentClass): void { foreach ($parentClass->getPublicProperties() as $property) { - if (! $property->isInitialized($parent) || $property->isVirtual()) { + if (! $property->isInitialized($parent)) { + continue; + } + + if ($property->isVirtual()) { continue; } @@ -165,11 +170,9 @@ private function setChildParentRelation(object $parent, mixed $child, ClassRefle public function resolveValue(PropertyReflector $property, mixed $value): mixed { - $caster = $this->memoize((string) $property, function () use ($property) { - return $this->casterFactory - ->in($this->context) - ->forProperty($property); - }); + $caster = $this->memoize((string) $property, fn () => $this->casterFactory + ->in($this->context) + ->forProperty($property)); if ($property->isNullable() && $value === null) { return null; @@ -179,7 +182,7 @@ public function resolveValue(PropertyReflector $property, mixed $value): mixed return $value; } - if ($property->getIterableType() !== null) { + if ($property->getIterableType() instanceof TypeReflector) { return $caster->cast($value); } diff --git a/packages/mapper/src/Mappers/ObjectToArrayMapper.php b/packages/mapper/src/Mappers/ObjectToArrayMapper.php index f72f411d24..675d1c0125 100644 --- a/packages/mapper/src/Mappers/ObjectToArrayMapper.php +++ b/packages/mapper/src/Mappers/ObjectToArrayMapper.php @@ -9,6 +9,7 @@ use Tempest\Mapper\Hidden; use Tempest\Mapper\Mapper; use Tempest\Mapper\MapTo; +use Tempest\Mapper\Serializer; use Tempest\Mapper\SerializerFactory; use Tempest\Reflection\ClassReflector; use Tempest\Reflection\PropertyReflector; @@ -64,15 +65,17 @@ private function resolvePropertyValue(PropertyReflector $property, object $objec if ($property->getIterableType()?->isClass()) { foreach ($propertyValue as $key => $value) { - if (is_object($value)) { - $propertyValue[$key] = map($value)->toArray(); + if (! is_object($value)) { + continue; } + + $propertyValue[$key] = map($value)->toArray(); } return $propertyValue; } - if ($propertyValue !== null && ($serializer = $this->serializerFactory->in($this->context)->forProperty($property)) !== null) { + if ($propertyValue !== null && ($serializer = $this->serializerFactory->in($this->context)->forProperty($property)) instanceof Serializer) { return $serializer->serialize($propertyValue); } diff --git a/packages/mapper/src/MappingContext.php b/packages/mapper/src/MappingContext.php index 1215c1f33f..b75ee40d9f 100644 --- a/packages/mapper/src/MappingContext.php +++ b/packages/mapper/src/MappingContext.php @@ -18,7 +18,7 @@ public static function default(): Context public static function from(Context|UnitEnum|string|null $context): Context { - if (! $context) { + if ($context === null) { return self::default(); } diff --git a/packages/mapper/src/ProvidesCaster.php b/packages/mapper/src/ProvidesCaster.php index 921357c6a1..9d23e9aa5e 100644 --- a/packages/mapper/src/ProvidesCaster.php +++ b/packages/mapper/src/ProvidesCaster.php @@ -8,7 +8,5 @@ interface ProvidesCaster { /** @var class-string */ - public string $caster { - get; - } + public string $caster { get; } } diff --git a/packages/mapper/src/ProvidesSerializer.php b/packages/mapper/src/ProvidesSerializer.php index 86efbfb38d..0f9cab41b0 100644 --- a/packages/mapper/src/ProvidesSerializer.php +++ b/packages/mapper/src/ProvidesSerializer.php @@ -8,7 +8,5 @@ interface ProvidesSerializer { /** @var class-string */ - public string $serializer { - get; - } + public string $serializer { get; } } diff --git a/packages/mapper/src/SerializationMapDiscovery.php b/packages/mapper/src/SerializationMapDiscovery.php index 72dc82d4b3..0a526b2744 100644 --- a/packages/mapper/src/SerializationMapDiscovery.php +++ b/packages/mapper/src/SerializationMapDiscovery.php @@ -17,7 +17,7 @@ public function __construct( public function discover(DiscoveryLocation $location, ClassReflector $class): void { - if ($attribute = $class->getAttribute(SerializeAs::class)) { + if (($attribute = $class->getAttribute(SerializeAs::class)) instanceof SerializeAs) { $this->discoveryItems->add($location, [$class->getName(), $attribute->name]); } } diff --git a/packages/mapper/src/SerializerFactory.php b/packages/mapper/src/SerializerFactory.php index 5917fd6d09..2bbe04b11b 100644 --- a/packages/mapper/src/SerializerFactory.php +++ b/packages/mapper/src/SerializerFactory.php @@ -71,15 +71,13 @@ public function forProperty(PropertyReflector $property): ?Serializer return $this->container->get($serializeWith->className, context: $context); } - if ($serializerAttribute = $property->getAttribute(ProvidesSerializer::class)) { + if (($serializerAttribute = $property->getAttribute(ProvidesSerializer::class)) instanceof ProvidesSerializer) { return $this->container->get($serializerAttribute->serializer, context: $context); } foreach ($this->resolveSerializers() as [$serializerClass]) { - if (is_a($serializerClass, DynamicSerializer::class, allow_string: true)) { - if (! $serializerClass::accepts($property)) { - continue; - } + if (is_a($serializerClass, DynamicSerializer::class, allow_string: true) && ! $serializerClass::accepts($property)) { + continue; } return $this->resolveSerializer($serializerClass, $property); @@ -102,10 +100,8 @@ public function forValue(mixed $value): ?Serializer } foreach ($this->resolveSerializers() as [$serializerClass]) { - if (is_a($serializerClass, DynamicSerializer::class, allow_string: true)) { - if (! $serializerClass::accepts($input)) { - continue; - } + if (is_a($serializerClass, DynamicSerializer::class, allow_string: true) && ! $serializerClass::accepts($input)) { + continue; } return $this->resolveSerializer($serializerClass, $input); diff --git a/packages/mapper/src/Serializers/ArrayOfObjectsSerializer.php b/packages/mapper/src/Serializers/ArrayOfObjectsSerializer.php index 0d3a71c7c3..0a8af6346c 100644 --- a/packages/mapper/src/Serializers/ArrayOfObjectsSerializer.php +++ b/packages/mapper/src/Serializers/ArrayOfObjectsSerializer.php @@ -23,7 +23,7 @@ public static function accepts(PropertyReflector|TypeReflector $input): bool return false; } - return $input->getIterableType() !== null; + return $input->getIterableType() instanceof TypeReflector; } public function serialize(mixed $input): array diff --git a/packages/mapper/src/Strict.php b/packages/mapper/src/Strict.php index 35a389a175..5f2593655d 100644 --- a/packages/mapper/src/Strict.php +++ b/packages/mapper/src/Strict.php @@ -7,6 +7,4 @@ use Attribute; #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_PROPERTY)] -final readonly class Strict -{ -} +final readonly class Strict {} diff --git a/packages/mapper/src/UnknownValue.php b/packages/mapper/src/UnknownValue.php index 170a5c7124..e7b599665e 100644 --- a/packages/mapper/src/UnknownValue.php +++ b/packages/mapper/src/UnknownValue.php @@ -4,6 +4,4 @@ namespace Tempest\Mapper; -final readonly class UnknownValue -{ -} +final readonly class UnknownValue {} diff --git a/packages/mapper/src/functions.php b/packages/mapper/src/functions.php index 59aeb2f297..1329d23984 100644 --- a/packages/mapper/src/functions.php +++ b/packages/mapper/src/functions.php @@ -5,7 +5,6 @@ namespace Tempest\Mapper; use Tempest\Container; -use Tempest\Mapper\ObjectFactory; /** * Creates a factory which allows instantiating `$objectOrClass` with the data specified by the {@see \Tempest\Mapper\ObjectFactory::from()} method. diff --git a/packages/process/src/Exceptions/ProcessException.php b/packages/process/src/Exceptions/ProcessException.php index 00c0f69251..7d00205dee 100644 --- a/packages/process/src/Exceptions/ProcessException.php +++ b/packages/process/src/Exceptions/ProcessException.php @@ -4,6 +4,4 @@ use Throwable; -interface ProcessException extends Throwable -{ -} +interface ProcessException extends Throwable {} diff --git a/packages/process/src/GenericProcessExecutor.php b/packages/process/src/GenericProcessExecutor.php index 0683b9b22b..5cda6fc7ab 100644 --- a/packages/process/src/GenericProcessExecutor.php +++ b/packages/process/src/GenericProcessExecutor.php @@ -3,6 +3,7 @@ namespace Tempest\Process; use Symfony\Component\Process\Process as SymfonyProcess; +use Tempest\DateTime\Duration; use Tempest\Support\Arr\ImmutableArray; final class GenericProcessExecutor implements ProcessExecutor @@ -52,7 +53,7 @@ private function createSymfonyProcess(PendingProcess $pending): SymfonyProcess $process->setWorkingDirectory((string) ($pending->path ?? getcwd())); $process->setTimeout($pending->timeout?->getTotalSeconds()); - if ($pending->idleTimeout) { + if ($pending->idleTimeout instanceof Duration) { $process->setIdleTimeout($pending->idleTimeout->getTotalSeconds()); } diff --git a/packages/process/src/InvokedProcess.php b/packages/process/src/InvokedProcess.php index 7465f258c3..216abf4220 100644 --- a/packages/process/src/InvokedProcess.php +++ b/packages/process/src/InvokedProcess.php @@ -9,30 +9,22 @@ interface InvokedProcess /** * Gets the process identifier. */ - public ?int $pid { - get; - } + public ?int $pid { get; } /** * Whether the process is running. */ - public bool $running { - get; - } + public bool $running { get; } /** * Gets the output of the process. */ - public string $output { - get; - } + public string $output { get; } /** * Gets the error output of the process. */ - public string $errorOutput { - get; - } + public string $errorOutput { get; } /** * Sends a signal to the process. diff --git a/packages/process/src/InvokedProcessPool.php b/packages/process/src/InvokedProcessPool.php index 1e8598bb12..949a6a1395 100644 --- a/packages/process/src/InvokedProcessPool.php +++ b/packages/process/src/InvokedProcessPool.php @@ -64,7 +64,7 @@ public function wait(): ProcessPoolResults * * @param Closure(InvokedProcess): mixed $callback */ - public function forEachRunning(\Closure $callback): self + public function forEachRunning(Closure $callback): self { $this->running->each(fn (InvokedProcess $process) => $callback($process)); @@ -76,7 +76,7 @@ public function forEachRunning(\Closure $callback): self * * @param Closure(InvokedProcess): mixed $callback */ - public function forEach(\Closure $callback): self + public function forEach(Closure $callback): self { $this->processes->each(fn (InvokedProcess $process) => $callback($process)); diff --git a/packages/process/src/OutputChannel.php b/packages/process/src/OutputChannel.php index fa3f546c6a..bdc1b82477 100644 --- a/packages/process/src/OutputChannel.php +++ b/packages/process/src/OutputChannel.php @@ -3,6 +3,7 @@ namespace Tempest\Process; use Symfony\Component\Process\Process; +use UnexpectedValueException; enum OutputChannel: string { @@ -14,7 +15,7 @@ public static function fromSymfonyOutputType(string $type): self return match ($type) { Process::OUT => self::OUTPUT, Process::ERR => self::ERROR, - default => throw new \UnexpectedValueException(sprintf('Unsupported output type "%s".', $type)), + default => throw new UnexpectedValueException(sprintf('Unsupported output type "%s".', $type)), }; } } diff --git a/packages/process/src/ProcessPoolResults.php b/packages/process/src/ProcessPoolResults.php index 5bf7a55fa2..7379fab64b 100644 --- a/packages/process/src/ProcessPoolResults.php +++ b/packages/process/src/ProcessPoolResults.php @@ -3,6 +3,7 @@ namespace Tempest\Process; use ArrayAccess; +use BadMethodCallException; use Countable; use Iterator; use Tempest\Support\Arr\ImmutableArray; @@ -109,12 +110,12 @@ public function offsetGet(mixed $offset): ProcessResult public function offsetSet(mixed $offset, mixed $value): void { - throw new \BadMethodCallException('ProcessPoolResults is immutable and cannot be modified.'); + throw new BadMethodCallException('ProcessPoolResults is immutable and cannot be modified.'); } public function offsetUnset(mixed $offset): void { - throw new \BadMethodCallException('ProcessPoolResults is immutable and cannot be modified.'); + throw new BadMethodCallException('ProcessPoolResults is immutable and cannot be modified.'); } public function count(): int diff --git a/packages/process/src/Testing/InvokedTestingProcess.php b/packages/process/src/Testing/InvokedTestingProcess.php index 9a19383025..5044ebf1e9 100644 --- a/packages/process/src/Testing/InvokedTestingProcess.php +++ b/packages/process/src/Testing/InvokedTestingProcess.php @@ -2,6 +2,7 @@ namespace Tempest\Process\Testing; +use Closure; use Tempest\DateTime\Duration; use Tempest\Process\InvokedProcess; use Tempest\Process\OutputChannel; @@ -42,9 +43,11 @@ final class InvokedTestingProcess implements InvokedProcess $output = []; for ($i = 0; $i < $this->nextOutputIndex; $i++) { - if ($this->description->output[$i]['type'] === OutputChannel::OUTPUT) { - $output[] = $this->description->output[$i]['buffer']; + if ($this->description->output[$i]['type'] !== OutputChannel::OUTPUT) { + continue; } + + $output[] = $this->description->output[$i]['buffer']; } return rtrim(implode('', $output), "\n") . "\n"; @@ -58,9 +61,11 @@ final class InvokedTestingProcess implements InvokedProcess $output = []; for ($i = 0; $i < $this->nextErrorOutputIndex; $i++) { - if ($this->description->output[$i]['type'] === OutputChannel::ERROR) { - $output[] = $this->description->output[$i]['buffer']; + if ($this->description->output[$i]['type'] !== OutputChannel::ERROR) { + continue; } + + $output[] = $this->description->output[$i]['buffer']; } return rtrim(implode('', $output), "\n") . "\n"; @@ -72,7 +77,7 @@ final class InvokedTestingProcess implements InvokedProcess * * @var null|\Closure(OutputChannel, string): void */ - private ?\Closure $outputHandler = null; + private ?Closure $outputHandler = null; /** * The number of times the process should indicate that it is "running". @@ -118,12 +123,12 @@ public function stop(float|int|Duration $timeout = 10, ?int $signal = null): sel public function wait(?callable $output = null): ProcessResult { if ($output !== null) { - $this->outputHandler = $output instanceof \Closure + $this->outputHandler = $output instanceof Closure ? $output - : \Closure::fromCallable($output); + : Closure::fromCallable($output); } - if (! $this->outputHandler) { + if (! $this->outputHandler instanceof Closure) { $this->remainingRunIterations = 0; return $this->getProcessResult(); @@ -185,7 +190,7 @@ public function latestErrorOutput(): string */ private function invokeOutputHandlerWithNextLineOfOutput(): bool { - if (! $this->outputHandler) { + if (! $this->outputHandler instanceof Closure) { return false; } diff --git a/packages/process/src/Testing/ProcessTester.php b/packages/process/src/Testing/ProcessTester.php index ba75c8d330..f000ef21d9 100644 --- a/packages/process/src/Testing/ProcessTester.php +++ b/packages/process/src/Testing/ProcessTester.php @@ -5,6 +5,7 @@ use Closure; use PHPUnit\Framework\Assert; use PHPUnit\Framework\ExpectationFailedException; +use RuntimeException; use Tempest\Container\Container; use Tempest\Container\Singleton; use Tempest\Process\GenericProcessExecutor; @@ -73,7 +74,7 @@ public function allowRunningActualProcesses(): void { $this->allowRunningActualProcesses = true; - if ($this->executor) { + if ($this->executor instanceof TestingProcessExecutor) { $this->executor->allowRunningActualProcesses = true; } else { $this->recordProcessExecutions(); @@ -87,7 +88,7 @@ public function preventRunningActualProcesses(): void { $this->allowRunningActualProcesses = false; - if ($this->executor) { + if ($this->executor instanceof TestingProcessExecutor) { $this->executor->allowRunningActualProcesses = false; } else { $this->recordProcessExecutions(); @@ -109,7 +110,7 @@ public function debugExecutedProcesses(): never { $this->ensureTestingSetUp(); - throw new \RuntimeException(var_export($this->executor->executions, true)); + throw new RuntimeException(var_export($this->executor->executions, true)); } /** @@ -125,7 +126,7 @@ public function describe(): InvokedProcessDescription * * @param null|Closure(): mixed|Closure(ProcessResult): mixed|Closure(ProcessResult, PendingProcess): mixed $callback */ - public function assertCommandRan(string $command, ?\Closure $callback = null): self + public function assertCommandRan(string $command, ?Closure $callback = null): self { $this->ensureTestingSetUp(); @@ -160,7 +161,7 @@ public function assertCommandRan(string $command, ?\Closure $callback = null): s * * @param Closure(PendingProcess): mixed|Closure(PendingProcess, ProcessResult): mixed $callback */ - public function assertRan(\Closure $callback): self + public function assertRan(Closure $callback): self { $this->ensureTestingSetUp(); @@ -188,7 +189,7 @@ public function assertRan(\Closure $callback): self * * @param string|Closure(): mixed|Closure(PendingProcess): mixed|Closure(PendingProcess, ProcessResult): mixed $command */ - public function assertCommandDidNotRun(string|\Closure $command): self + public function assertCommandDidNotRun(string|Closure $command): self { $this->ensureTestingSetUp(); @@ -238,17 +239,19 @@ public function assertNothingRan(): self * * @param string|\Closure(PendingProcess,ProcessResult):bool $command */ - public function assertRanTimes(string|\Closure $command, int $times): self + public function assertRanTimes(string|Closure $command, int $times): self { $this->ensureTestingSetUp(); - if ($command instanceof \Closure) { + if ($command instanceof Closure) { $count = 0; foreach ($this->executor->executions as $executions) { foreach ($executions as [$process, $result]) { - if ($command($process, $result) === true) { - $count++; + if ($command($process, $result) !== true) { + continue; } + + $count++; } } } else { // @mago-expects linter:no-else-clause @@ -274,9 +277,11 @@ private function findExecutionsByPattern(string $pattern): array $executions = []; foreach ($this->executor->executions as $command => $commandExecutions) { - if ($this->executor->commandMatchesPattern($command, $pattern)) { - $executions[] = $commandExecutions; + if (! $this->executor->commandMatchesPattern($command, $pattern)) { + continue; } + + $executions[] = $commandExecutions; } return Arr\flatten($executions, depth: 1); diff --git a/packages/process/src/Testing/TestingProcessExecutor.php b/packages/process/src/Testing/TestingProcessExecutor.php index 0b5381e186..c40f6d2911 100644 --- a/packages/process/src/Testing/TestingProcessExecutor.php +++ b/packages/process/src/Testing/TestingProcessExecutor.php @@ -2,6 +2,7 @@ namespace Tempest\Process\Testing; +use RuntimeException; use Tempest\Process\GenericProcessExecutor; use Tempest\Process\InvokedProcess; use Tempest\Process\InvokedSystemProcess; @@ -29,7 +30,7 @@ public function __construct( public function run(string|PendingProcess $command): ProcessResult { - if ($result = $this->findMockedProcess($command)) { + if (($result = $this->findMockedProcess($command)) instanceof ProcessResult) { return $this->recordExecution($command, $result); } @@ -42,7 +43,7 @@ public function run(string|PendingProcess $command): ProcessResult public function start(string|PendingProcess $command): InvokedProcess { - if ($processResult = $this->findInvokedProcessDescription($command)) { + if (($processResult = $this->findInvokedProcessDescription($command)) instanceof InvokedProcessDescription) { $this->recordExecution($command, $process = new InvokedTestingProcess($processResult)); } else { if (! $this->allowRunningActualProcesses) { @@ -117,7 +118,7 @@ private function recordExecution(string|PendingProcess $command, InvokedProcess| $result instanceof ProcessResult => $result, $result instanceof InvokedTestingProcess => $result->getProcessResult(), $result instanceof InvokedSystemProcess => $result->wait(), // TODO: fix - default => throw new \RuntimeException('Unexpected result type.'), + default => throw new RuntimeException('Unexpected result type.'), }; $this->executions[$process->command] ??= []; diff --git a/packages/reflection/src/ClassReflector.php b/packages/reflection/src/ClassReflector.php index 3a388beefb..5c0797719f 100644 --- a/packages/reflection/src/ClassReflector.php +++ b/packages/reflection/src/ClassReflector.php @@ -19,6 +19,7 @@ final class ClassReflector implements Reflector private array $memoize = []; private readonly PHPReflectionClass $reflectionClass; + private string $name; /** @@ -157,19 +158,19 @@ public function newInstanceArgs(array $args = []): object public function callStatic(string $method, mixed ...$args): mixed { - $className = $this->getName(); + $className = $this->name; return $className::$method(...$args); } public function is(string $className): bool { - return is_a($this->getName(), $className, allow_string: true); + return is_a($this->name, $className, allow_string: true); } public function implements(string $interface): bool { - return $this->isInstantiable() && is_a($this->getName(), $interface, allow_string: true); + return $this->isInstantiable() && is_a($this->name, $interface, allow_string: true); } private function memoize(string $key, Closure $closure): mixed @@ -183,7 +184,7 @@ private function memoize(string $key, Closure $closure): mixed public function __serialize(): array { - return ['name' => $this->getName()]; + return ['name' => $this->name]; } public function __unserialize(array $data): void diff --git a/packages/reflection/src/EnumReflector.php b/packages/reflection/src/EnumReflector.php index f1d204b569..a60f04b9f1 100644 --- a/packages/reflection/src/EnumReflector.php +++ b/packages/reflection/src/EnumReflector.php @@ -7,6 +7,7 @@ use Closure; use ReflectionEnum as PHPReflectionEnum; use ReflectionEnumUnitCase; +use ReflectionNamedType; use UnitEnum; /** @@ -73,7 +74,7 @@ public function getBackingType(): ?TypeReflector { $backingType = $this->reflectionEnum->getBackingType(); - if ($backingType === null) { + if (! $backingType instanceof ReflectionNamedType) { return null; } diff --git a/packages/reflection/src/HasAttributes.php b/packages/reflection/src/HasAttributes.php index 14ac258984..0a82ccbdaf 100644 --- a/packages/reflection/src/HasAttributes.php +++ b/packages/reflection/src/HasAttributes.php @@ -72,7 +72,7 @@ private function instantiate(?ReflectionAttribute $attribute): ?object { $object = $attribute?->newInstance(); - if (! $object) { + if ($object === null) { return null; } diff --git a/packages/reflection/src/MethodReflector.php b/packages/reflection/src/MethodReflector.php index 6667e8cb02..523287b139 100644 --- a/packages/reflection/src/MethodReflector.php +++ b/packages/reflection/src/MethodReflector.php @@ -7,13 +7,14 @@ use Generator; use ReflectionMethod as PHPReflectionMethod; use ReflectionParameter; +use ReflectionType; -final class MethodReflector implements Reflector +final readonly class MethodReflector implements Reflector { use HasAttributes; public function __construct( - private readonly PHPReflectionMethod $reflectionMethod, + private PHPReflectionMethod $reflectionMethod, ) {} public static function fromParts(string|object $class, string $name): self @@ -55,7 +56,7 @@ public function invokeArgs(?object $object, array $args = []): mixed public function getReturnType(): ?TypeReflector { - if ($this->reflectionMethod->getReturnType() === null) { + if (! $this->reflectionMethod->getReturnType() instanceof ReflectionType) { return null; } diff --git a/packages/reflection/src/ParameterReflector.php b/packages/reflection/src/ParameterReflector.php index 02d92188ee..d9126d83a2 100644 --- a/packages/reflection/src/ParameterReflector.php +++ b/packages/reflection/src/ParameterReflector.php @@ -6,12 +6,12 @@ use ReflectionParameter as PHPReflectionParameter; -final class ParameterReflector implements Reflector +final readonly class ParameterReflector implements Reflector { use HasAttributes; public function __construct( - private readonly PHPReflectionParameter $reflectionParameter, + private PHPReflectionParameter $reflectionParameter, ) {} public function getReflection(): PHPReflectionParameter diff --git a/packages/reflection/src/PropertyAttribute.php b/packages/reflection/src/PropertyAttribute.php index 0e669c9cea..8b5683076e 100644 --- a/packages/reflection/src/PropertyAttribute.php +++ b/packages/reflection/src/PropertyAttribute.php @@ -4,8 +4,5 @@ interface PropertyAttribute { - public PropertyReflector $property { - set; - get; - } + public PropertyReflector $property { set; get; } } diff --git a/packages/reflection/src/PropertyReflector.php b/packages/reflection/src/PropertyReflector.php index 3eda1ce131..eafb3dae44 100644 --- a/packages/reflection/src/PropertyReflector.php +++ b/packages/reflection/src/PropertyReflector.php @@ -6,13 +6,14 @@ use Error; use ReflectionProperty as PHPReflectionProperty; +use Stringable; -final class PropertyReflector implements Reflector +final readonly class PropertyReflector implements Reflector, Stringable { use HasAttributes; public function __construct( - private readonly PHPReflectionProperty $reflectionProperty, + private PHPReflectionProperty $reflectionProperty, ) {} public static function fromParts(string|object $class, string $name): self diff --git a/packages/reflection/src/TypeReflector.php b/packages/reflection/src/TypeReflector.php index 739cfd4e58..a9b5bd2f14 100644 --- a/packages/reflection/src/TypeReflector.php +++ b/packages/reflection/src/TypeReflector.php @@ -7,7 +7,9 @@ use BackedEnum; use DateTimeInterface; use Generator; +use InvalidArgumentException; use Iterator; +use LogicException; use ReflectionClass as PHPReflectionClass; use ReflectionClassConstant as PHPReflectionClassConstant; use ReflectionEnumUnitCase as PHPReflectionEnumUnitCase; @@ -141,7 +143,7 @@ public function getShortName(): string { $parts = explode('\\', $this->definition); - return $parts[array_key_last($parts)]; + return array_last($parts); } public function isBuiltIn(): bool @@ -172,7 +174,7 @@ public function isEnumCase(): bool public function asEnumCase(): PHPReflectionEnumUnitCase { if (! $this->reflector instanceof PHPReflectionEnumUnitCase) { - throw new \LogicException(sprintf('Cannot get enum case from `%s`.', $this->definition)); + throw new LogicException(sprintf('Cannot get enum case from `%s`.', $this->definition)); } return $this->reflector; @@ -214,7 +216,7 @@ public function isStringable(): bool return true; } - return in_array($this->cleanDefinition, ['string'], strict: true); + return $this->cleanDefinition === 'string'; } public function isNullable(): bool @@ -271,19 +273,19 @@ private function resolveDefinition(PHPReflector|PHPReflectionType|string $reflec if ($reflector instanceof PHPReflectionUnionType) { return implode('|', array_map( - fn (PHPReflectionType $reflectionType) => $this->resolveDefinition($reflectionType), + $this->resolveDefinition(...), $reflector->getTypes(), )); } if ($reflector instanceof PHPReflectionIntersectionType) { return implode('&', array_map( - fn (PHPReflectionType $reflectionType) => $this->resolveDefinition($reflectionType), + $this->resolveDefinition(...), $reflector->getTypes(), )); } - throw new \InvalidArgumentException( + throw new InvalidArgumentException( sprintf('Could not resolve type for reflector of type: %s', get_debug_type($reflector)), ); } diff --git a/packages/reflection/src/functions.php b/packages/reflection/src/functions.php index 20f07a96eb..ee66d5e29e 100644 --- a/packages/reflection/src/functions.php +++ b/packages/reflection/src/functions.php @@ -6,8 +6,6 @@ use ReflectionClass as PHPReflectionClass; use ReflectionProperty as PHPReflectionProperty; -use Tempest\Reflection\ClassReflector; -use Tempest\Reflection\PropertyReflector; /** * Creates a new {@see Reflector} instance based on the given `$classOrProperty`. diff --git a/packages/reflection/tests/EnumReflectorTest.php b/packages/reflection/tests/EnumReflectorTest.php index 2af7df7d43..e2e562ea69 100644 --- a/packages/reflection/tests/EnumReflectorTest.php +++ b/packages/reflection/tests/EnumReflectorTest.php @@ -4,11 +4,16 @@ namespace Tempest\Reflection\Tests; +use Attribute; +use BackedEnum; +use JsonSerializable; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use ReflectionEnum; +use stdClass; use Tempest\Reflection\EnumReflector; use Tempest\Reflection\TypeReflector; +use UnitEnum; /** * @internal @@ -153,9 +158,9 @@ public function is_method(): void { $reflector = new EnumReflector(TestBackedEnum::class); - $this->assertTrue($reflector->is(\BackedEnum::class)); - $this->assertTrue($reflector->is(\UnitEnum::class)); - $this->assertFalse($reflector->is(\stdClass::class)); + $this->assertTrue($reflector->is(BackedEnum::class)); + $this->assertTrue($reflector->is(UnitEnum::class)); + $this->assertFalse($reflector->is(stdClass::class)); } #[Test] @@ -164,7 +169,7 @@ public function implements_method(): void $reflector = new EnumReflector(TestEnumWithInterface::class); $this->assertTrue($reflector->implements(TestInterface::class)); - $this->assertFalse($reflector->implements(\JsonSerializable::class)); + $this->assertFalse($reflector->implements(JsonSerializable::class)); } #[Test] @@ -271,16 +276,14 @@ enum TestIntBackedEnum: int case SECOND = 2; } -interface TestInterface -{ -} +interface TestInterface {} enum TestEnumWithInterface: string implements TestInterface { case VALUE = 'value'; } -#[\Attribute] +#[Attribute] final class TestAttribute { public function __construct( diff --git a/packages/reflection/tests/Fixtures/AnnulledInvoice.php b/packages/reflection/tests/Fixtures/AnnulledInvoice.php index f5d5c7f8fc..76bb96e170 100644 --- a/packages/reflection/tests/Fixtures/AnnulledInvoice.php +++ b/packages/reflection/tests/Fixtures/AnnulledInvoice.php @@ -4,6 +4,4 @@ namespace Tempest\Reflection\Tests\Fixtures; -final readonly class AnnulledInvoice -{ -} +final readonly class AnnulledInvoice {} diff --git a/packages/reflection/tests/Fixtures/ChildWithRecursiveAttribute.php b/packages/reflection/tests/Fixtures/ChildWithRecursiveAttribute.php index 1483015aea..622d60770b 100644 --- a/packages/reflection/tests/Fixtures/ChildWithRecursiveAttribute.php +++ b/packages/reflection/tests/Fixtures/ChildWithRecursiveAttribute.php @@ -4,6 +4,4 @@ namespace Tempest\Reflection\Tests\Fixtures; -final class ChildWithRecursiveAttribute extends ParentWithRecursiveAttribute -{ -} +final class ChildWithRecursiveAttribute extends ParentWithRecursiveAttribute {} diff --git a/packages/reflection/tests/Fixtures/ClassWithInterfaceWithRecursiveAttribute.php b/packages/reflection/tests/Fixtures/ClassWithInterfaceWithRecursiveAttribute.php index 39ecc50d5c..9558fb05fb 100644 --- a/packages/reflection/tests/Fixtures/ClassWithInterfaceWithRecursiveAttribute.php +++ b/packages/reflection/tests/Fixtures/ClassWithInterfaceWithRecursiveAttribute.php @@ -4,6 +4,4 @@ namespace Tempest\Reflection\Tests\Fixtures; -final class ClassWithInterfaceWithRecursiveAttribute implements InterfaceWithRecursiveAttribute -{ -} +final class ClassWithInterfaceWithRecursiveAttribute implements InterfaceWithRecursiveAttribute {} diff --git a/packages/reflection/tests/Fixtures/InterfaceWithRecursiveAttribute.php b/packages/reflection/tests/Fixtures/InterfaceWithRecursiveAttribute.php index 7282e56871..d8f1f2c525 100644 --- a/packages/reflection/tests/Fixtures/InterfaceWithRecursiveAttribute.php +++ b/packages/reflection/tests/Fixtures/InterfaceWithRecursiveAttribute.php @@ -5,6 +5,4 @@ namespace Tempest\Reflection\Tests\Fixtures; #[RecursiveAttribute] -interface InterfaceWithRecursiveAttribute -{ -} +interface InterfaceWithRecursiveAttribute {} diff --git a/packages/reflection/tests/Fixtures/NoReturnType.php b/packages/reflection/tests/Fixtures/NoReturnType.php index bf5dbbb1d8..9d686184c9 100644 --- a/packages/reflection/tests/Fixtures/NoReturnType.php +++ b/packages/reflection/tests/Fixtures/NoReturnType.php @@ -6,7 +6,6 @@ final class NoReturnType { - // @mago-expect lint:return-type public function noReturnType() { return 2137; diff --git a/packages/reflection/tests/Fixtures/NullableClass.php b/packages/reflection/tests/Fixtures/NullableClass.php index a2af1e599c..6f745ad02d 100644 --- a/packages/reflection/tests/Fixtures/NullableClass.php +++ b/packages/reflection/tests/Fixtures/NullableClass.php @@ -4,6 +4,4 @@ namespace Tempest\Reflection\Tests\Fixtures; -final readonly class NullableClass -{ -} +final readonly class NullableClass {} diff --git a/packages/reflection/tests/Fixtures/ParentWithRecursiveAttribute.php b/packages/reflection/tests/Fixtures/ParentWithRecursiveAttribute.php index 9cf1cfe574..76cd13221d 100644 --- a/packages/reflection/tests/Fixtures/ParentWithRecursiveAttribute.php +++ b/packages/reflection/tests/Fixtures/ParentWithRecursiveAttribute.php @@ -5,6 +5,4 @@ namespace Tempest\Reflection\Tests\Fixtures; #[RecursiveAttribute] -abstract class ParentWithRecursiveAttribute -{ -} +abstract class ParentWithRecursiveAttribute {} diff --git a/packages/reflection/tests/Fixtures/RecursiveAttribute.php b/packages/reflection/tests/Fixtures/RecursiveAttribute.php index 32d3856c7a..cd6814e67e 100644 --- a/packages/reflection/tests/Fixtures/RecursiveAttribute.php +++ b/packages/reflection/tests/Fixtures/RecursiveAttribute.php @@ -7,6 +7,4 @@ use Attribute; #[Attribute] -final class RecursiveAttribute -{ -} +final class RecursiveAttribute {} diff --git a/packages/reflection/tests/Fixtures/TestBackedEnum.php b/packages/reflection/tests/Fixtures/TestBackedEnum.php index e33bbd8d9f..6d300b8996 100644 --- a/packages/reflection/tests/Fixtures/TestBackedEnum.php +++ b/packages/reflection/tests/Fixtures/TestBackedEnum.php @@ -2,6 +2,4 @@ namespace Tempest\Reflection\Tests\Fixtures; -enum TestBackedEnum: string -{ -} +enum TestBackedEnum: string {} diff --git a/packages/reflection/tests/Fixtures/TestEnum.php b/packages/reflection/tests/Fixtures/TestEnum.php index b9f6052b5b..9d1c8b6291 100644 --- a/packages/reflection/tests/Fixtures/TestEnum.php +++ b/packages/reflection/tests/Fixtures/TestEnum.php @@ -2,6 +2,4 @@ namespace Tempest\Reflection\Tests\Fixtures; -enum TestEnum -{ -} +enum TestEnum {} diff --git a/packages/router/src/Commands/MakeControllerCommand.php b/packages/router/src/Commands/MakeControllerCommand.php index 5052d4aede..5e0cd4c91e 100644 --- a/packages/router/src/Commands/MakeControllerCommand.php +++ b/packages/router/src/Commands/MakeControllerCommand.php @@ -12,7 +12,7 @@ use Tempest\Generation\Php\DataObjects\StubFile; use Tempest\Router\Stubs\ControllerStub; -if (class_exists(\Tempest\Console\ConsoleCommand::class)) { +if (class_exists(ConsoleCommand::class)) { final class MakeControllerCommand { use PublishesFiles; diff --git a/packages/router/src/Commands/RoutesCommand.php b/packages/router/src/Commands/RoutesCommand.php index 73e6c0a425..2cf51e9e12 100644 --- a/packages/router/src/Commands/RoutesCommand.php +++ b/packages/router/src/Commands/RoutesCommand.php @@ -17,7 +17,7 @@ use function Tempest\Support\Str\after_last; use function Tempest\Support\Str\before_last; -if (class_exists(\Tempest\Console\ConsoleCommand::class)) { +if (class_exists(ConsoleCommand::class)) { final readonly class RoutesCommand { public function __construct( diff --git a/packages/router/src/Commands/ServeCommand.php b/packages/router/src/Commands/ServeCommand.php index 76bf4b01d9..998559ad4d 100644 --- a/packages/router/src/Commands/ServeCommand.php +++ b/packages/router/src/Commands/ServeCommand.php @@ -8,7 +8,7 @@ use Tempest\Intl\Number; use Tempest\Support\Str; -if (class_exists(\Tempest\Console\ConsoleCommand::class)) { +if (class_exists(ConsoleCommand::class)) { final readonly class ServeCommand { #[ConsoleCommand( diff --git a/packages/router/src/Connect.php b/packages/router/src/Connect.php index 280c5752e3..dfce369a63 100644 --- a/packages/router/src/Connect.php +++ b/packages/router/src/Connect.php @@ -10,7 +10,7 @@ #[Attribute(Attribute::IS_REPEATABLE | Attribute::TARGET_METHOD)] final class Connect implements Route { - public Method $method; + public Method $method = Method::CONNECT; /** * @param class-string[] $middleware Middleware specific to this route. @@ -20,7 +20,5 @@ public function __construct( public string $uri, public array $middleware = [], public array $without = [], - ) { - $this->method = Method::CONNECT; - } + ) {} } diff --git a/packages/router/src/Delete.php b/packages/router/src/Delete.php index 40724d91c9..7bb003c6d4 100644 --- a/packages/router/src/Delete.php +++ b/packages/router/src/Delete.php @@ -10,7 +10,7 @@ #[Attribute(Attribute::IS_REPEATABLE | Attribute::TARGET_METHOD)] final class Delete implements Route { - public Method $method; + public Method $method = Method::DELETE; /** * @param class-string[] $middleware Middleware specific to this route. @@ -20,7 +20,5 @@ public function __construct( public string $uri, public array $middleware = [], public array $without = [], - ) { - $this->method = Method::DELETE; - } + ) {} } diff --git a/packages/router/src/Exceptions/ConvertsToResponse.php b/packages/router/src/Exceptions/ConvertsToResponse.php index f49d1258d4..587ce2f0fa 100644 --- a/packages/router/src/Exceptions/ConvertsToResponse.php +++ b/packages/router/src/Exceptions/ConvertsToResponse.php @@ -3,11 +3,12 @@ namespace Tempest\Router\Exceptions; use Tempest\Http\Response; +use Throwable; /** * Marks this exception class as one that can be converted to a response. */ -interface ConvertsToResponse extends \Throwable +interface ConvertsToResponse extends Throwable { /** * Gets a response to be sent to the client. diff --git a/packages/router/src/Exceptions/DevelopmentException.php b/packages/router/src/Exceptions/DevelopmentException.php index 9cb242712d..659bf49d00 100644 --- a/packages/router/src/Exceptions/DevelopmentException.php +++ b/packages/router/src/Exceptions/DevelopmentException.php @@ -86,7 +86,7 @@ private function enhanceStacktraceForViewCompilation(ViewCompilationFailed $exce { $previous = $exception->getPrevious(); - if (! $previous) { + if (! $previous instanceof Throwable) { return $stacktrace; } diff --git a/packages/router/src/Exceptions/HtmlExceptionRenderer.php b/packages/router/src/Exceptions/HtmlExceptionRenderer.php index e4bf13fbcb..ed5b1f0be5 100644 --- a/packages/router/src/Exceptions/HtmlExceptionRenderer.php +++ b/packages/router/src/Exceptions/HtmlExceptionRenderer.php @@ -113,11 +113,7 @@ private function shouldRenderDevelopmentException(Throwable $throwable): bool return true; } - if ($throwable->status === Status::NOT_FOUND) { - return false; - } - - return true; + return $throwable->status !== Status::NOT_FOUND; } private function renderValidationFailedResponse(ValidationFailed $exception): Response @@ -163,9 +159,11 @@ private function filterSensitiveFields(Request $request, ?string $targetClass): $reflector = new ClassReflector($targetClass); foreach ($reflector->getPublicProperties() as $property) { - if ($property->hasAttribute(SensitiveField::class)) { - unset($body[$property->getName()]); + if (! $property->hasAttribute(SensitiveField::class)) { + continue; } + + unset($body[$property->getName()]); } return $body; diff --git a/packages/router/src/Exceptions/JsonExceptionRenderer.php b/packages/router/src/Exceptions/JsonExceptionRenderer.php index 9a3c247be2..f86ef7fbe5 100644 --- a/packages/router/src/Exceptions/JsonExceptionRenderer.php +++ b/packages/router/src/Exceptions/JsonExceptionRenderer.php @@ -88,10 +88,10 @@ private function renderErrorResponse(Status $status, ?string $message = null, ?T 'message' => $message ?? $status->description(), ]; - if ($this->environment->isLocal() && $throwable !== null) { + if ($this->environment->isLocal() && $throwable instanceof Throwable) { $body['debug'] = array_filter([ 'message' => $throwable->getMessage(), - 'exception' => get_class($throwable), + 'exception' => $throwable::class, 'file' => $throwable->getFile(), 'line' => $throwable->getLine(), 'trace' => Arr\map( diff --git a/packages/router/src/Exceptions/RouteBindingFailed.php b/packages/router/src/Exceptions/RouteBindingFailed.php index dbd261b54d..879ca6d9a8 100644 --- a/packages/router/src/Exceptions/RouteBindingFailed.php +++ b/packages/router/src/Exceptions/RouteBindingFailed.php @@ -6,6 +6,4 @@ use Exception; -final class RouteBindingFailed extends Exception implements RouterException -{ -} +final class RouteBindingFailed extends Exception implements RouterException {} diff --git a/packages/router/src/Exceptions/RouterException.php b/packages/router/src/Exceptions/RouterException.php index 3f357efb23..e4ecbde434 100644 --- a/packages/router/src/Exceptions/RouterException.php +++ b/packages/router/src/Exceptions/RouterException.php @@ -2,6 +2,4 @@ namespace Tempest\Router\Exceptions; -interface RouterException -{ -} +interface RouterException {} diff --git a/packages/router/src/GenericResponseSender.php b/packages/router/src/GenericResponseSender.php index 45a8e38428..be9f1f4c8d 100644 --- a/packages/router/src/GenericResponseSender.php +++ b/packages/router/src/GenericResponseSender.php @@ -130,7 +130,7 @@ private function sendEventStream(EventStream $response): void } foreach ($response->body as $message) { - if (connection_aborted()) { + if (connection_aborted() !== 0) { break; } @@ -142,7 +142,7 @@ private function sendEventStream(EventStream $response): void echo "id: {$message->id}\n"; } - if ($message->retryAfter) { + if ($message->retryAfter !== null) { $retry = match (true) { is_int($message->retryAfter) => $message->retryAfter, $message->retryAfter instanceof Duration => $message->retryAfter->getTotalMilliseconds(), diff --git a/packages/router/src/Get.php b/packages/router/src/Get.php index e73c048136..6d5f23bc36 100644 --- a/packages/router/src/Get.php +++ b/packages/router/src/Get.php @@ -10,7 +10,7 @@ #[Attribute(Attribute::IS_REPEATABLE | Attribute::TARGET_METHOD)] final class Get implements Route { - public Method $method; + public Method $method = Method::GET; /** * @param class-string[] $middleware Middleware specific to this route. @@ -20,7 +20,5 @@ public function __construct( public string $uri, public array $middleware = [], public array $without = [], - ) { - $this->method = Method::GET; - } + ) {} } diff --git a/packages/router/src/Head.php b/packages/router/src/Head.php index 74530c1c02..a21be9c535 100644 --- a/packages/router/src/Head.php +++ b/packages/router/src/Head.php @@ -10,7 +10,7 @@ #[Attribute(Attribute::IS_REPEATABLE | Attribute::TARGET_METHOD)] final class Head implements Route { - public Method $method; + public Method $method = Method::HEAD; /** * @param class-string[] $middleware Middleware specific to this route. @@ -20,7 +20,5 @@ public function __construct( public string $uri, public array $middleware = [], public array $without = [], - ) { - $this->method = Method::HEAD; - } + ) {} } diff --git a/packages/router/src/IsBindingValue.php b/packages/router/src/IsBindingValue.php index d2f6339363..a345c6096d 100644 --- a/packages/router/src/IsBindingValue.php +++ b/packages/router/src/IsBindingValue.php @@ -5,6 +5,4 @@ use Attribute; #[Attribute(Attribute::TARGET_PROPERTY)] -final class IsBindingValue -{ -} +final class IsBindingValue {} diff --git a/packages/router/src/MatchRouteMiddleware.php b/packages/router/src/MatchRouteMiddleware.php index ab8a44a329..efef027acf 100644 --- a/packages/router/src/MatchRouteMiddleware.php +++ b/packages/router/src/MatchRouteMiddleware.php @@ -26,11 +26,11 @@ public function __invoke(Request $request, HttpMiddlewareCallable $next): Respon { $matchedRoute = $this->routeMatcher->match($request); - if ($matchedRoute === null && $request->method === Method::HEAD && $request instanceof GenericRequest) { + if (! $matchedRoute instanceof MatchedRoute && $request->method === Method::HEAD && $request instanceof GenericRequest) { $matchedRoute = $this->routeMatcher->match($request->withMethod(Method::GET)); } - if ($matchedRoute === null) { + if (! $matchedRoute instanceof MatchedRoute) { return new NotFound(); } @@ -56,16 +56,17 @@ private function resolveRequest(Request $request, MatchedRoute $matchedRoute): R // We'll loop over all the handler's parameters foreach ($matchedRoute->route->handler->getParameters() as $parameter) { // If the parameter's type is an instance of Request… - if ($parameter->getType()->matches(Request::class)) { - // We'll use that specific request class - $requestClass = $parameter->getType()->getName(); - - break; + if (! $parameter->getType()->matches(Request::class)) { + continue; } + + $requestClass = $parameter->getType()->getName(); + + break; } if ($requestClass !== Request::class && $requestClass !== GenericRequest::class) { - $request = map($request)->with(RequestToObjectMapper::class)->to($requestClass); + return map($request)->with(RequestToObjectMapper::class)->to($requestClass); } return $request; diff --git a/packages/router/src/Options.php b/packages/router/src/Options.php index 60d370ddfb..e66634f1a7 100644 --- a/packages/router/src/Options.php +++ b/packages/router/src/Options.php @@ -10,7 +10,7 @@ #[Attribute(Attribute::IS_REPEATABLE | Attribute::TARGET_METHOD)] final class Options implements Route { - public Method $method; + public Method $method = Method::OPTIONS; /** * @param class-string[] $middleware Middleware specific to this route. @@ -20,7 +20,5 @@ public function __construct( public string $uri, public array $middleware = [], public array $without = [], - ) { - $this->method = Method::OPTIONS; - } + ) {} } diff --git a/packages/router/src/Patch.php b/packages/router/src/Patch.php index c00c875c4f..ffaed917c5 100644 --- a/packages/router/src/Patch.php +++ b/packages/router/src/Patch.php @@ -10,7 +10,7 @@ #[Attribute(Attribute::IS_REPEATABLE | Attribute::TARGET_METHOD)] final class Patch implements Route { - public Method $method; + public Method $method = Method::PATCH; /** * @param class-string[] $middleware Middleware specific to this route. @@ -20,7 +20,5 @@ public function __construct( public string $uri, public array $middleware = [], public array $without = [], - ) { - $this->method = Method::PATCH; - } + ) {} } diff --git a/packages/router/src/Post.php b/packages/router/src/Post.php index 83711e1db8..d9d1f953a0 100644 --- a/packages/router/src/Post.php +++ b/packages/router/src/Post.php @@ -10,7 +10,7 @@ #[Attribute(Attribute::IS_REPEATABLE | Attribute::TARGET_METHOD)] final class Post implements Route { - public Method $method; + public Method $method = Method::POST; /** * @param class-string[] $middleware Middleware specific to this route. @@ -20,7 +20,5 @@ public function __construct( public string $uri, public array $middleware = [], public array $without = [], - ) { - $this->method = Method::POST; - } + ) {} } diff --git a/packages/router/src/PreventCrossSiteRequestsMiddleware.php b/packages/router/src/PreventCrossSiteRequestsMiddleware.php index b1bf73f4fc..645a884aa8 100644 --- a/packages/router/src/PreventCrossSiteRequestsMiddleware.php +++ b/packages/router/src/PreventCrossSiteRequestsMiddleware.php @@ -50,11 +50,7 @@ public function __invoke(Request $request, HttpMiddlewareCallable $next): Respon */ private function shouldValidate(Request $request): bool { - if (in_array($request->method, self::SAFE_METHODS, strict: true)) { - return false; - } - - return true; + return ! in_array($request->method, self::SAFE_METHODS, strict: true); } /** @@ -76,10 +72,6 @@ private function isValidRequest(Request $request): bool } // same origin, same site and user-originated requests are always allowed - if ($secFetchSite !== SecFetchSite::CROSS_SITE) { - return true; - } - - return false; + return $secFetchSite !== SecFetchSite::CROSS_SITE; } } diff --git a/packages/router/src/Put.php b/packages/router/src/Put.php index 4e990b83b2..9995d4c2bd 100644 --- a/packages/router/src/Put.php +++ b/packages/router/src/Put.php @@ -10,7 +10,7 @@ #[Attribute(Attribute::IS_REPEATABLE | Attribute::TARGET_METHOD)] final class Put implements Route { - public Method $method; + public Method $method = Method::PUT; /** * @param class-string[] $middleware Middleware specific to this route. @@ -20,7 +20,5 @@ public function __construct( public string $uri, public array $middleware = [], public array $without = [], - ) { - $this->method = Method::PUT; - } + ) {} } diff --git a/packages/router/src/Route.php b/packages/router/src/Route.php index 3387556c1c..082d0ed843 100644 --- a/packages/router/src/Route.php +++ b/packages/router/src/Route.php @@ -8,25 +8,13 @@ interface Route { - public Method $method { - get; - set; - } + public Method $method { get; set; } - public string $uri { - get; - set; - } + public string $uri { get; set; } /** @var class-string[] */ - public array $middleware { - get; - set; - } + public array $middleware { get; set; } /** @var class-string[] */ - public array $without { - get; - set; - } + public array $without { get; set; } } diff --git a/packages/router/src/RouteBindingInitializer.php b/packages/router/src/RouteBindingInitializer.php index b9f3b00fc4..027e83d49b 100644 --- a/packages/router/src/RouteBindingInitializer.php +++ b/packages/router/src/RouteBindingInitializer.php @@ -24,11 +24,13 @@ public function initialize(ClassReflector $class, null|string|UnitEnum $tag, Con $parameter = null; foreach ($matchedRoute->route->handler->getParameters() as $searchParameter) { - if ($searchParameter->getType()->equals($class->getType())) { - $parameter = $searchParameter; - - break; + if (! $searchParameter->getType()->equals($class->getType())) { + continue; } + + $parameter = $searchParameter; + + break; } if ($parameter === null) { diff --git a/packages/router/src/Routing/Construction/DiscoveredRoute.php b/packages/router/src/Routing/Construction/DiscoveredRoute.php index be603c8821..a32e9e22a7 100644 --- a/packages/router/src/Routing/Construction/DiscoveredRoute.php +++ b/packages/router/src/Routing/Construction/DiscoveredRoute.php @@ -6,6 +6,7 @@ use Tempest\Http\Method; use Tempest\Reflection\MethodReflector; +use Tempest\Reflection\ParameterReflector; use Tempest\Router\Route; final class DiscoveredRoute implements Route @@ -88,7 +89,7 @@ private static function parseUriAndParameters(string $uri, MethodReflector $meth $parameter = $methodReflector->getParameter($paramName); - if ($parameter === null) { + if (! $parameter instanceof ParameterReflector) { return $matches[0]; } diff --git a/packages/router/src/Routing/Construction/RouteMatchingRegexBuilder.php b/packages/router/src/Routing/Construction/RouteMatchingRegexBuilder.php index 7a71c6c7ec..d526eca01f 100644 --- a/packages/router/src/Routing/Construction/RouteMatchingRegexBuilder.php +++ b/packages/router/src/Routing/Construction/RouteMatchingRegexBuilder.php @@ -9,7 +9,7 @@ final readonly class RouteMatchingRegexBuilder { // This limit is guesstimated using a small script with an ever in pattern feed into preg_match - private const int PREG_REGEX_SIZE_LIMIT = 32768; + private const int PREG_REGEX_SIZE_LIMIT = 32_768; private const int REGEX_SIZE_MARGIN = 256; @@ -59,14 +59,14 @@ public function toRegex(): MatchingRegex // Rebuild the regex match prefix based on the current visited parent nodes, known as 'the stack' foreach ($stack as $previousNode) { - $regex .= '|' . self::routeNodeSegmentRegex($previousNode); + $regex .= '|' . $this->routeNodeSegmentRegex($previousNode); $regex .= '(?'; } } // Add the node route segment to the current regex - $regex .= '|' . self::routeNodeSegmentRegex($node); - $targetRouteRegex = self::routeNodeTargetRegex($node); + $regex .= '|' . $this->routeNodeSegmentRegex($node); + $targetRouteRegex = $this->routeNodeTargetRegex($node); // Check if node has children to ensure we only use branches if the node has children if ($node->dynamicPaths !== [] || $node->staticPaths !== []) { @@ -77,7 +77,7 @@ public function toRegex(): MatchingRegex $stack[] = $node; // Add target route regex as an alteration group - if ($targetRouteRegex) { + if ($targetRouteRegex !== '' && $targetRouteRegex !== '0') { $regex .= '|' . $targetRouteRegex; } @@ -112,9 +112,9 @@ public function toRegex(): MatchingRegex * a key `"MARK"` with value `"x"`, it is used to track which route has been matched. * Returns an empty string for nodes without a target. */ - private static function routeNodeTargetRegex(RouteTreeNode $node): string + private function routeNodeTargetRegex(RouteTreeNode $node): string { - if ($node->targetRoute === null) { + if (! $node->targetRoute instanceof MarkedRoute) { return ''; } @@ -124,7 +124,7 @@ private static function routeNodeTargetRegex(RouteTreeNode $node): string /** * Creates the regex for a route node's segment */ - private static function routeNodeSegmentRegex(RouteTreeNode $node): string + private function routeNodeSegmentRegex(RouteTreeNode $node): string { return match ($node->type) { RouteTreeNodeType::Root => '^', diff --git a/packages/router/src/Routing/Construction/RouteTreeNode.php b/packages/router/src/Routing/Construction/RouteTreeNode.php index 7e4ed16408..566e165534 100644 --- a/packages/router/src/Routing/Construction/RouteTreeNode.php +++ b/packages/router/src/Routing/Construction/RouteTreeNode.php @@ -40,7 +40,7 @@ public static function createStaticRouteNode(string $name): self public function findOrCreateNodeForSegment(string $routeSegment): self { // Translates a path segment like {id} into it's matching regex. Static segments remain the same - $regexRouteSegment = self::convertDynamicSegmentToRegex($routeSegment); + $regexRouteSegment = $this->convertDynamicSegmentToRegex($routeSegment); // Returns a static or dynamic child node depending on the segment is dynamic or static if ($routeSegment === $regexRouteSegment) { @@ -52,14 +52,14 @@ public function findOrCreateNodeForSegment(string $routeSegment): self public function setTargetRoute(MarkedRoute $markedRoute): void { - if ($this->targetRoute !== null) { + if ($this->targetRoute instanceof MarkedRoute) { throw new DuplicateRouteException($markedRoute->route); } $this->targetRoute = $markedRoute; } - private static function convertDynamicSegmentToRegex(string $uriPart): string + private function convertDynamicSegmentToRegex(string $uriPart): string { $regex = '#\{' . DiscoveredRoute::ROUTE_PARAM_OPTIONAL_REGEX . DiscoveredRoute::ROUTE_PARAM_NAME_REGEX . DiscoveredRoute::ROUTE_PARAM_CUSTOM_REGEX . '\}#'; diff --git a/packages/router/src/Routing/Construction/RoutingTree.php b/packages/router/src/Routing/Construction/RoutingTree.php index e8f658ab3e..6bac79e0e4 100644 --- a/packages/router/src/Routing/Construction/RoutingTree.php +++ b/packages/router/src/Routing/Construction/RoutingTree.php @@ -12,12 +12,9 @@ final class RoutingTree { /** @var array */ - private array $roots; + private array $roots = []; - public function __construct() - { - $this->roots = []; - } + public function __construct() {} public function add(MarkedRoute $markedRoute): void { diff --git a/packages/router/src/Routing/Matching/GenericRouteMatcher.php b/packages/router/src/Routing/Matching/GenericRouteMatcher.php index e7298976b7..ba52658592 100644 --- a/packages/router/src/Routing/Matching/GenericRouteMatcher.php +++ b/packages/router/src/Routing/Matching/GenericRouteMatcher.php @@ -19,7 +19,7 @@ public function __construct( public function match(Request $request): ?MatchedRoute { // Try to match routes without any parameters - if (($staticRoute = $this->matchStaticRoute($request)) !== null) { + if (($staticRoute = $this->matchStaticRoute($request)) instanceof MatchedRoute) { return $staticRoute; } diff --git a/packages/router/src/Routing/Matching/MatchingRegex.php b/packages/router/src/Routing/Matching/MatchingRegex.php index ec382c847a..ffc4a95ccc 100644 --- a/packages/router/src/Routing/Matching/MatchingRegex.php +++ b/packages/router/src/Routing/Matching/MatchingRegex.php @@ -25,7 +25,7 @@ public function match(string $uri): ?RouteMatch throw new RuntimeException('Failed to use matching regex. Got error ' . preg_last_error()); } - if (! $matchResult) { + if ($matchResult === 0) { continue; } diff --git a/packages/router/src/Static/Exceptions/StaticPageException.php b/packages/router/src/Static/Exceptions/StaticPageException.php index d6c563afcd..44810abb4a 100644 --- a/packages/router/src/Static/Exceptions/StaticPageException.php +++ b/packages/router/src/Static/Exceptions/StaticPageException.php @@ -4,7 +4,5 @@ interface StaticPageException { - public string $uri { - get; - } + public string $uri { get; } } diff --git a/packages/router/src/Static/StaticCleanCommand.php b/packages/router/src/Static/StaticCleanCommand.php index a85a569a42..057fd0f751 100644 --- a/packages/router/src/Static/StaticCleanCommand.php +++ b/packages/router/src/Static/StaticCleanCommand.php @@ -56,9 +56,11 @@ private function removeFiles(RecursiveDirectoryIterator $directoryIterator): voi /** @var SplFileInfo $file */ foreach (new RecursiveIteratorIterator($directoryIterator) as $file) { - if ($file->getExtension() === 'html') { - $files[] = $file; + if ($file->getExtension() !== 'html') { + continue; } + + $files[] = $file; } foreach ($files as $file) { diff --git a/packages/router/src/Static/StaticGenerateCommand.php b/packages/router/src/Static/StaticGenerateCommand.php index ecef517c65..440ee29f36 100644 --- a/packages/router/src/Static/StaticGenerateCommand.php +++ b/packages/router/src/Static/StaticGenerateCommand.php @@ -99,7 +99,7 @@ public function __invoke( "{$event->path}", "NO CONTENT", ), - $verbose === true => $this->error("Failed to generate static page: {$event->exception->getMessage()}"), + $verbose => $this->error("Failed to generate static page: {$event->exception->getMessage()}"), default => $this->keyValue("{$event->path}", "FAILED"), }; }); @@ -181,13 +181,13 @@ public function __invoke( } } - if ($failures) { + if ($failures !== 0) { $this->keyValue('Failures', "{$failures}"); } $this->keyValue('Static pages generated', "{$generated}"); - if ($deadlinks) { + if ($deadlinks !== []) { $this->console->header('Dead links'); foreach ($deadlinks as $uri => $deadLinks) { @@ -197,7 +197,7 @@ public function __invoke( } } - return $failures > 0 || count($deadlinks) > 0 + return $failures > 0 || $deadlinks !== [] ? ExitCode::ERROR : ExitCode::SUCCESS; } @@ -224,7 +224,7 @@ private function detectDeadLinks(string $uri, string $html, bool $checkExternal // Check anchors (#) if (Str\starts_with($link, '#')) { - if (! Regex\matches($html, "/id=\"" . preg_quote(Str\strip_start($link, '#'), '/') . "\"/")) { + if (! Regex\matches($html, '/id="' . preg_quote(Str\strip_start($link, '#'), '/') . '"/')) { $deadlinks[] = $link; } diff --git a/packages/router/src/Trace.php b/packages/router/src/Trace.php index 24b8857af1..fa85c0dd11 100644 --- a/packages/router/src/Trace.php +++ b/packages/router/src/Trace.php @@ -10,7 +10,7 @@ #[Attribute(Attribute::IS_REPEATABLE | Attribute::TARGET_METHOD)] final class Trace implements Route { - public Method $method; + public Method $method = Method::TRACE; /** * @param class-string[] $middleware Middleware specific to this route. @@ -20,7 +20,5 @@ public function __construct( public string $uri, public array $middleware = [], public array $without = [], - ) { - $this->method = Method::TRACE; - } + ) {} } diff --git a/packages/router/src/functions.php b/packages/router/src/functions.php index 083c5f8379..fa96034e91 100644 --- a/packages/router/src/functions.php +++ b/packages/router/src/functions.php @@ -7,7 +7,6 @@ use Tempest\DateTime\DateTime; use Tempest\DateTime\Duration; use Tempest\Reflection\MethodReflector; -use Tempest\Router\UriGenerator; use function Tempest\Container\get; diff --git a/packages/router/tests/FakeRouteBuilder.php b/packages/router/tests/FakeRouteBuilder.php index 1d041c7996..08f523e8f7 100644 --- a/packages/router/tests/FakeRouteBuilder.php +++ b/packages/router/tests/FakeRouteBuilder.php @@ -47,7 +47,5 @@ public function asDiscoveredRoute(): DiscoveredRoute return DiscoveredRoute::fromRoute($this, [], $this->handler); } - public function handler(): void - { - } + public function handler(): void {} } diff --git a/packages/router/tests/FakeRouteBuilderWithOptionalParams.php b/packages/router/tests/FakeRouteBuilderWithOptionalParams.php index ed03e644e8..95e71f3161 100644 --- a/packages/router/tests/FakeRouteBuilderWithOptionalParams.php +++ b/packages/router/tests/FakeRouteBuilderWithOptionalParams.php @@ -53,19 +53,11 @@ public function asDiscoveredRoute(): DiscoveredRoute return DiscoveredRoute::fromRoute($this, [], $this->handler); } - public function handler(): void - { - } + public function handler(): void {} - public function handlerWithOptionalId(string $id = 'default-id'): void - { - } + public function handlerWithOptionalId(string $id = 'default-id'): void {} - public function handlerWithTwoOptionalParams(string $id = 'default-id', string $slug = 'default-slug'): void - { - } + public function handlerWithTwoOptionalParams(string $id = 'default-id', string $slug = 'default-slug'): void {} - public function handlerWithRequiredAndOptional(string $id, string $slug = 'default-slug'): void - { - } + public function handlerWithRequiredAndOptional(string $id, string $slug = 'default-slug'): void {} } diff --git a/packages/storage/src/Config/R2StorageConfig.php b/packages/storage/src/Config/R2StorageConfig.php index 4acb8d1e7d..6325d1d350 100644 --- a/packages/storage/src/Config/R2StorageConfig.php +++ b/packages/storage/src/Config/R2StorageConfig.php @@ -57,12 +57,12 @@ public function createAdapter(): FilesystemAdapter return new S3StorageConfig( bucket: $this->bucket, region: 'auto', - endpoint: $this->endpoint, accessKeyId: $this->accessKeyId, secretAccessKey: $this->secretAccessKey, sessionToken: null, prefix: $this->prefix, readonly: $this->readonly, + endpoint: $this->endpoint, usePathStyleEndpoint: true, options: $this->options, )->createAdapter(); diff --git a/packages/storage/src/Config/StorageConfig.php b/packages/storage/src/Config/StorageConfig.php index 1c0b4b921b..33b8b33f90 100644 --- a/packages/storage/src/Config/StorageConfig.php +++ b/packages/storage/src/Config/StorageConfig.php @@ -10,17 +10,12 @@ interface StorageConfig extends HasTag /** * Whether the storage is read-only. */ - public bool $readonly { - get; - set; - } + public bool $readonly { get; set; } /** * The adapter class. */ - public string $adapter { - get; - } + public string $adapter { get; } /** * Creates the adapter. diff --git a/packages/storage/src/DirectoryListing.php b/packages/storage/src/DirectoryListing.php index af3705f66a..44e95e7502 100644 --- a/packages/storage/src/DirectoryListing.php +++ b/packages/storage/src/DirectoryListing.php @@ -26,7 +26,7 @@ public function __construct( */ public function filter(callable $filter): static { - return new static(parent::filter($filter)); + return new self(parent::filter($filter)); } /** @@ -38,7 +38,7 @@ public function filter(callable $filter): static */ public function map(callable $mapper): static { - return new static(parent::map($mapper)); + return new self(parent::map($mapper)); } /** @@ -46,7 +46,7 @@ public function map(callable $mapper): static */ public function sortByPath(): static { - return new static(parent::sortByPath()); + return new self(parent::sortByPath()); } /** diff --git a/packages/storage/src/StorageException.php b/packages/storage/src/StorageException.php index 9136ec1d71..f4a4bcb0c3 100644 --- a/packages/storage/src/StorageException.php +++ b/packages/storage/src/StorageException.php @@ -2,6 +2,4 @@ namespace Tempest\Storage; -interface StorageException -{ -} +interface StorageException {} diff --git a/packages/storage/src/Testing/StorageTester.php b/packages/storage/src/Testing/StorageTester.php index 3ca86ead75..ab13946c26 100644 --- a/packages/storage/src/Testing/StorageTester.php +++ b/packages/storage/src/Testing/StorageTester.php @@ -2,6 +2,7 @@ namespace Tempest\Storage\Testing; +use RuntimeException; use Tempest\Container\Container; use Tempest\Container\GenericContainer; use Tempest\Storage\Storage; @@ -37,7 +38,7 @@ public function fake(null|string|UnitEnum $tag = null, bool $persist = false): T public function preventUsageWithoutFake(): void { if (! $this->container instanceof GenericContainer) { - throw new \RuntimeException('Container is not a GenericContainer, unable to prevent usage without fake.'); + throw new RuntimeException('Container is not a GenericContainer, unable to prevent usage without fake.'); } $this->container->unregister(Storage::class, tagged: true); diff --git a/packages/storage/src/Testing/TestingStorage.php b/packages/storage/src/Testing/TestingStorage.php index c841e7e510..7d2e9f0f08 100644 --- a/packages/storage/src/Testing/TestingStorage.php +++ b/packages/storage/src/Testing/TestingStorage.php @@ -189,9 +189,9 @@ private function createStorage(?string $path = null, ?TemporaryUrlGenerator $tem public function createTemporaryUrlsUsing(Closure $closure): void { - $generator = new class($closure) implements TemporaryUrlGenerator { + $generator = new readonly class($closure) implements TemporaryUrlGenerator { public function __construct( - private readonly Closure $closure, + private Closure $closure, ) {} public function temporaryUrl(string $path, DateTimeInterface $expiresAt, Config $config): string @@ -205,9 +205,9 @@ public function temporaryUrl(string $path, DateTimeInterface $expiresAt, Config public function createPublicUrlsUsing(Closure $closure): void { - $generator = new class($closure) implements PublicUrlGenerator { + $generator = new readonly class($closure) implements PublicUrlGenerator { public function __construct( - private readonly Closure $closure, + private Closure $closure, ) {} public function publicUrl(string $path, Config $config): string diff --git a/packages/support/src/Arr/ManipulatesArray.php b/packages/support/src/Arr/ManipulatesArray.php index e038d9f17a..ee1f49cecc 100644 --- a/packages/support/src/Arr/ManipulatesArray.php +++ b/packages/support/src/Arr/ManipulatesArray.php @@ -6,6 +6,7 @@ use Closure; use Stringable; +use Tempest\Debug\Debug; use Tempest\Mapper; use Tempest\Support\Str\ImmutableString; @@ -825,7 +826,7 @@ public function dd(mixed ...$dd): void private function debugLog(array $items, bool $terminate = false): void { - $debugClass = \Tempest\Debug\Debug::class; + $debugClass = Debug::class; if (class_exists($debugClass)) { $debugClass::resolve()->log($items); diff --git a/packages/support/src/Arr/OffsetDidNotExist.php b/packages/support/src/Arr/OffsetDidNotExist.php index e99cd224ee..6099e582f5 100644 --- a/packages/support/src/Arr/OffsetDidNotExist.php +++ b/packages/support/src/Arr/OffsetDidNotExist.php @@ -6,6 +6,4 @@ use Exception; -final class OffsetDidNotExist extends Exception -{ -} +final class OffsetDidNotExist extends Exception {} diff --git a/packages/support/src/Arr/functions.php b/packages/support/src/Arr/functions.php index 96c97c720a..e4ab61dbff 100644 --- a/packages/support/src/Arr/functions.php +++ b/packages/support/src/Arr/functions.php @@ -4,6 +4,7 @@ namespace Tempest\Support\Arr; +use ArrayAccess; use Closure; use Countable; use Generator; @@ -62,11 +63,7 @@ function chunk(iterable $array, int $size, bool $preserveKeys = true): array } $chunks = []; - foreach (array_chunk($array, $size, $preserveKeys) as $chunk) { - $chunks[] = $chunk; - } - - return $chunks; + return array_chunk($array, $size, $preserveKeys); } /** @@ -202,9 +199,11 @@ function forget_values(array &$array, mixed $values): array $values = is_array($values) ? $values : [$values]; foreach ($values as $value) { - if (! is_null($key = array_find_key($array, fn (mixed $match) => $value === $match))) { - unset($array[$key]); + if (is_null($key = array_find_key($array, fn (mixed $match) => $value === $match))) { + continue; } + + unset($array[$key]); } return $array; @@ -615,8 +614,8 @@ function first(iterable $array, ?Closure $filter = null, mixed $default = null): return $default; } - if ($filter === null) { - return $array[array_key_first($array)] ?? $default; + if (! $filter instanceof Closure) { + return array_first($array) ?? $default; } return array_find($array, static fn ($value, $key) => $filter($value, $key)) ?? $default; @@ -666,8 +665,8 @@ function last(iterable $array, ?Closure $filter = null, mixed $default = null): return $default; } - if ($filter === null) { - return $array[array_key_last($array)] ?? $default; + if (! $filter instanceof Closure) { + return array_last($array) ?? $default; } return array_find(namespace\reverse($array), static fn ($value, $key) => $filter($value, $key)) ?? $default; @@ -756,10 +755,7 @@ function implode(iterable $array, string $glue): ImmutableString */ function keys(iterable $array): array { - /** @var list $result */ - $result = array_keys(to_array($array)); - - return $result; + return array_keys(to_array($array)); } /** @@ -774,10 +770,7 @@ function keys(iterable $array): array */ function values(iterable $array): array { - /** @var list $result */ - $result = array_values(to_array($array)); - - return $result; + return array_values(to_array($array)); } /** @@ -798,9 +791,11 @@ function filter(iterable $array, ?Closure $filter = null): array $filter ??= static fn (mixed $value, mixed $_) => ! in_array($value, [false, null], strict: true); foreach (to_array($array) as $key => $value) { - if ($filter($value, $key)) { - $result[$key] = $value; + if (! $filter($value, $key)) { + continue; } + + $result[$key] = $value; } return $result; @@ -907,7 +902,7 @@ function get_by_key(iterable $array, int|string $key, mixed $default = null): mi : explode('.', $key); foreach ($keys as $key) { - if (! is_array($value) && ! $value instanceof \ArrayAccess) { + if (! is_array($value) && ! $value instanceof ArrayAccess) { return $default; } @@ -1534,9 +1529,11 @@ function to_array(mixed $input): array $result = []; for ($i = 0; $i < $count; $i++) { - if (isset($input[$i])) { - $result[$i] = $input[$i]; + if (! isset($input[$i])) { + continue; } + + $result[$i] = $input[$i]; } return $result; diff --git a/packages/support/src/Comparison/Exception/IncomparableException.php b/packages/support/src/Comparison/Exception/IncomparableException.php index 97ca678595..b49c928f76 100644 --- a/packages/support/src/Comparison/Exception/IncomparableException.php +++ b/packages/support/src/Comparison/Exception/IncomparableException.php @@ -16,7 +16,7 @@ public static function fromValues(mixed $a, mixed $b, string $additionalInfo = ' 'Unable to compare "%s" with "%s"%s', get_debug_type($a), get_debug_type($b), - $additionalInfo ? ': ' . $additionalInfo : '.', + $additionalInfo !== '' && $additionalInfo !== '0' ? ': ' . $additionalInfo : '.', )); } } diff --git a/packages/support/src/Filesystem/Exceptions/FilesystemException.php b/packages/support/src/Filesystem/Exceptions/FilesystemException.php index 4a0ffcf5dd..574811e3cc 100644 --- a/packages/support/src/Filesystem/Exceptions/FilesystemException.php +++ b/packages/support/src/Filesystem/Exceptions/FilesystemException.php @@ -2,6 +2,4 @@ namespace Tempest\Support\Filesystem\Exceptions; -interface FilesystemException -{ -} +interface FilesystemException {} diff --git a/packages/support/src/Filesystem/Exceptions/RuntimeException.php b/packages/support/src/Filesystem/Exceptions/RuntimeException.php index 145b290ee2..de5084684a 100644 --- a/packages/support/src/Filesystem/Exceptions/RuntimeException.php +++ b/packages/support/src/Filesystem/Exceptions/RuntimeException.php @@ -6,6 +6,4 @@ use RuntimeException as PhpRuntimeException; -final class RuntimeException extends PhpRuntimeException implements FilesystemException -{ -} +final class RuntimeException extends PhpRuntimeException implements FilesystemException {} diff --git a/packages/support/src/Filesystem/functions.php b/packages/support/src/Filesystem/functions.php index 6f8da69160..f69c05d418 100644 --- a/packages/support/src/Filesystem/functions.php +++ b/packages/support/src/Filesystem/functions.php @@ -5,6 +5,14 @@ namespace Tempest\Support\Filesystem; use FilesystemIterator; +use Phar; +use Tempest\Support\Filesystem\Exceptions\NameWasInvalid; +use Tempest\Support\Filesystem\Exceptions\PathWasNotADirectory; +use Tempest\Support\Filesystem\Exceptions\PathWasNotAFile; +use Tempest\Support\Filesystem\Exceptions\PathWasNotASymbolicLink; +use Tempest\Support\Filesystem\Exceptions\PathWasNotFound; +use Tempest\Support\Filesystem\Exceptions\PathWasNotReadable; +use Tempest\Support\Filesystem\Exceptions\RuntimeException; use Tempest\Support\Json; use Tempest\Support\Str; @@ -49,15 +57,15 @@ function copy_file(string $source, string $destination, bool $overwrite = false) } if (namespace\is_directory($source)) { - throw new Exceptions\PathWasNotAFile($source); + throw new PathWasNotAFile($source); } if (! namespace\is_file($source)) { - throw Exceptions\PathWasNotFound::forFile($source); + throw PathWasNotFound::forFile($source); } if (! namespace\is_readable($source)) { - throw Exceptions\PathWasNotReadable::forFile($source); + throw PathWasNotReadable::forFile($source); } namespace\create_directory_for_file($destination); @@ -65,7 +73,7 @@ function copy_file(string $source, string $destination, bool $overwrite = false) [$result, $errorMessage] = box(static fn (): bool => php_copy($source, $destination)); if ($result === false) { - throw new Exceptions\RuntimeException( + throw new RuntimeException( sprintf('Failed to copy source file "%s" to destination "%s": %s', $source, $destination, $errorMessage), ); } @@ -77,15 +85,15 @@ function copy_file(string $source, string $destination, bool $overwrite = false) function copy_directory(string $source, string $destination, bool $overwrite = false): void { if (! namespace\exists($source)) { - throw Exceptions\PathWasNotFound::forDirectory($source); + throw PathWasNotFound::forDirectory($source); } if (! namespace\is_directory($source)) { - throw new Exceptions\PathWasNotADirectory($source); + throw new PathWasNotADirectory($source); } if (! namespace\is_readable($source)) { - throw Exceptions\PathWasNotReadable::forDirectory($source); + throw PathWasNotReadable::forDirectory($source); } if (! $overwrite && namespace\is_directory($destination)) { @@ -138,7 +146,7 @@ function write_file(string $filename, mixed $content, int $flags = 0): void [$result, $errorMessage] = box(static fn (): int|false => file_put_contents($filename, $content, $flags)); if (false === $result) { - throw new Exceptions\RuntimeException(sprintf( + throw new RuntimeException(sprintf( 'Failed to write to file "%s": %s.', $filename, $errorMessage ?? 'internal error', @@ -160,17 +168,17 @@ function read_json(string $filename, bool $associative = true): array function read_file(string $filename): string { if (! namespace\exists($filename)) { - throw Exceptions\PathWasNotFound::forFile($filename); + throw PathWasNotFound::forFile($filename); } if (! namespace\is_readable($filename)) { - throw Exceptions\PathWasNotReadable::forFile($filename); + throw PathWasNotReadable::forFile($filename); } [$result, $message] = box(static fn (): false|string => file_get_contents($filename)); if (false === $result) { - throw new Exceptions\RuntimeException(sprintf( + throw new RuntimeException(sprintf( 'Failed to read file "%s": %s', $filename, $message ?? 'internal error', @@ -186,17 +194,17 @@ function read_file(string $filename): string function read_locked_file(string $filename, LockType $type = LockType::SHARED): string { if (! namespace\exists($filename)) { - throw Exceptions\PathWasNotFound::forFile($filename); + throw PathWasNotFound::forFile($filename); } if (! namespace\is_readable($filename)) { - throw Exceptions\PathWasNotReadable::forFile($filename); + throw PathWasNotReadable::forFile($filename); } [$handle, $openMessage] = box(static fn () => fopen($filename, 'rb')); if ($handle === false) { - throw new Exceptions\RuntimeException(sprintf( + throw new RuntimeException(sprintf( 'Failed to open file "%s": %s', $filename, $openMessage ?? 'internal error', @@ -206,7 +214,7 @@ function read_locked_file(string $filename, LockType $type = LockType::SHARED): if (! flock($handle, $type->value)) { fclose($handle); - throw new Exceptions\RuntimeException(sprintf( + throw new RuntimeException(sprintf( 'Failed to acquire lock on file "%s"', $filename, )); @@ -218,7 +226,7 @@ function read_locked_file(string $filename, LockType $type = LockType::SHARED): fclose($handle); if ($content === false) { - throw new Exceptions\RuntimeException(sprintf( + throw new RuntimeException(sprintf( 'Failed to read file "%s": %s', $filename, $readMessage ?? 'internal error', @@ -250,7 +258,7 @@ function create_directory(string $directory, int $permissions = 0o777): void [$result, $errorMessage] = box(static fn (): bool => mkdir($directory, $permissions, recursive: true)); if ($result === false && ! namespace\is_directory($directory)) { // @phpstan-ignore booleanNot.alwaysTrue - throw new Exceptions\RuntimeException(sprintf( + throw new RuntimeException(sprintf( 'Failed to create directory "%s": %s.', $directory, $errorMessage ?? 'internal error', @@ -306,7 +314,7 @@ function create_file(string $filename, ?int $time = null, ?int $accessTime = nul [$result, $errorMessage] = box($fun); if (false === $result && ! namespace\is_file($filename)) { - throw new Exceptions\RuntimeException(sprintf( + throw new RuntimeException(sprintf( 'Failed to create file "%s": %s.', $filename, $errorMessage ?? 'internal error', @@ -347,7 +355,7 @@ function delete_file(string $file): void [$result, $errorMessage] = box(static fn (): bool => unlink($file)); if ($result === false && namespace\is_symbolic_link($file)) { // @phpstan-ignore booleanAnd.rightAlwaysTrue - throw new Exceptions\RuntimeException(sprintf( + throw new RuntimeException(sprintf( 'Failed to delete symbolic link "%s": %s.', $file, $errorMessage ?? 'internal error', @@ -358,17 +366,17 @@ function delete_file(string $file): void } if (! namespace\exists($file)) { - throw Exceptions\PathWasNotFound::forFile($file); + throw PathWasNotFound::forFile($file); } if (! namespace\is_file($file)) { - throw new Exceptions\PathWasNotAFile($file); + throw new PathWasNotAFile($file); } [$result, $errorMessage] = box(static fn (): bool => unlink($file)); if ($result === false && namespace\is_file($file)) { // @phpstan-ignore booleanAnd.rightAlwaysTrue - throw new Exceptions\RuntimeException(sprintf( + throw new RuntimeException(sprintf( 'Failed to delete file "%s": %s.', $file, $errorMessage ?? 'internal error', @@ -382,13 +390,13 @@ function delete_file(string $file): void function get_permissions(string $path): int { if (! namespace\exists($path)) { - throw Exceptions\PathWasNotFound::forPath($path); + throw PathWasNotFound::forPath($path); } [$result, $message] = box(static fn (): int|false => fileperms($path)); if (false === $result) { - throw new Exceptions\RuntimeException(sprintf( + throw new RuntimeException(sprintf( 'Failed to retrieve permissions of file "%s": %s', $path, $message ?? 'internal error', @@ -404,7 +412,7 @@ function get_permissions(string $path): int function ensure_directory_empty(string $directory): void { if (namespace\exists($directory) && ! namespace\is_directory($directory)) { - throw new Exceptions\PathWasNotADirectory($directory); + throw new PathWasNotADirectory($directory); } if (! namespace\is_directory($directory)) { @@ -444,18 +452,18 @@ function delete_directory(string $directory, bool $recursive = true): void } } else { if (! namespace\exists($directory)) { - throw Exceptions\PathWasNotFound::forDirectory($directory); + throw PathWasNotFound::forDirectory($directory); } if (! namespace\is_directory($directory)) { - throw new Exceptions\PathWasNotADirectory($directory); + throw new PathWasNotADirectory($directory); } } [$result, $errorMessage] = box(static fn (): bool => rmdir($directory)); if (false === $result && namespace\is_directory($directory)) { - throw new Exceptions\RuntimeException(sprintf( + throw new RuntimeException(sprintf( 'Failed to delete directory "%s": %s.', $directory, $errorMessage ?? 'internal error', @@ -469,7 +477,7 @@ function delete_directory(string $directory, bool $recursive = true): void function rename(string $source, string $name, bool $overwrite = false): void { if (Str\contains($name, ['/', '\\'])) { - throw Exceptions\NameWasInvalid::forName($name); + throw NameWasInvalid::forName($name); } namespace\move( @@ -485,11 +493,11 @@ function rename(string $source, string $name, bool $overwrite = false): void function move(string $source, string $destination, bool $overwrite = false): void { if (! namespace\exists($source)) { - throw Exceptions\PathWasNotFound::forPath($source); + throw PathWasNotFound::forPath($source); } if (! namespace\is_readable($source)) { - throw Exceptions\PathWasNotReadable::forFile($source); + throw PathWasNotReadable::forFile($source); } if (namespace\exists($destination) && $overwrite === false) { @@ -505,7 +513,7 @@ function move(string $source, string $destination, bool $overwrite = false): voi [$result, $errorMessage] = box(static fn (): bool => php_rename($source, $destination)); if ($result === false) { - throw new Exceptions\RuntimeException(sprintf( + throw new RuntimeException(sprintf( 'Failed to move "%s" to "%s": %s', $source, $destination, @@ -571,15 +579,15 @@ function is_directory(string $path): bool function list_directory(string $directory): array { if (! namespace\exists($directory)) { - throw Exceptions\PathWasNotFound::forDirectory($directory); + throw PathWasNotFound::forDirectory($directory); } if (! namespace\is_directory($directory)) { - throw new Exceptions\PathWasNotADirectory($directory); + throw new PathWasNotADirectory($directory); } if (! namespace\is_readable($directory)) { - throw Exceptions\PathWasNotReadable::forDirectory($directory); + throw PathWasNotReadable::forDirectory($directory); } /** @var array */ @@ -595,17 +603,17 @@ function list_directory(string $directory): array function read_symbolic_link(string $path): string { if (! namespace\exists($path)) { - throw Exceptions\PathWasNotFound::forSymbolicLink($path); + throw PathWasNotFound::forSymbolicLink($path); } if (! namespace\is_symbolic_link($path)) { - throw new Exceptions\PathWasNotASymbolicLink($path); + throw new PathWasNotASymbolicLink($path); } [$result, $message] = box(static fn (): false|string => readlink($path)); if (false === $result) { - throw new Exceptions\RuntimeException(sprintf( + throw new RuntimeException(sprintf( 'Failed to retrieve the target of symbolic link "%s": %s', $path, $message ?? 'internal error', @@ -620,7 +628,7 @@ function read_symbolic_link(string $path): string */ function normalize_path(string $path): ?string { - if (str_starts_with($path, 'phar:') && class_exists(\Phar::class) && \Phar::running(false) !== '') { + if (str_starts_with($path, 'phar:') && class_exists(Phar::class) && Phar::running(false) !== '') { return $path; } diff --git a/packages/support/src/Html/HtmlString.php b/packages/support/src/Html/HtmlString.php index 8c5e1cf546..828cae81fd 100644 --- a/packages/support/src/Html/HtmlString.php +++ b/packages/support/src/Html/HtmlString.php @@ -47,6 +47,6 @@ public function toMutableString(): MutableString */ protected function createOrModify(Stringable|string $string): self { - return new static($string); + return new self($string); } } diff --git a/packages/support/src/JavaScript/PackageManager.php b/packages/support/src/JavaScript/PackageManager.php index f354f743f6..b2649ff8ac 100644 --- a/packages/support/src/JavaScript/PackageManager.php +++ b/packages/support/src/JavaScript/PackageManager.php @@ -62,9 +62,9 @@ public static function detect(string $cwd): ?self { return array_find( array: PackageManager::cases(), - callback: fn (PackageManager $packageManager): bool => array_any($packageManager->getLockFiles(), fn (string $lockFile): bool => Filesystem\is_file($cwd - . '/' - . $lockFile)), + callback: fn (PackageManager $packageManager): bool => array_any($packageManager->getLockFiles(), fn (string $lockFile): bool => Filesystem\is_file( + $cwd . '/' . $lockFile, + )), ); } } diff --git a/packages/support/src/Json/Exception/JsonCouldNotBeDecoded.php b/packages/support/src/Json/Exception/JsonCouldNotBeDecoded.php index 9b2c4ac99f..73d53c7af0 100644 --- a/packages/support/src/Json/Exception/JsonCouldNotBeDecoded.php +++ b/packages/support/src/Json/Exception/JsonCouldNotBeDecoded.php @@ -5,8 +5,5 @@ namespace Tempest\Support\Json\Exception; use InvalidArgumentException; -use Tempest\Support\Json\Exception\JsonException; -final class JsonCouldNotBeDecoded extends InvalidArgumentException implements JsonException -{ -} +final class JsonCouldNotBeDecoded extends InvalidArgumentException implements JsonException {} diff --git a/packages/support/src/Json/Exception/JsonCouldNotBeEncoded.php b/packages/support/src/Json/Exception/JsonCouldNotBeEncoded.php index 5548f1f33c..9148a3c7be 100644 --- a/packages/support/src/Json/Exception/JsonCouldNotBeEncoded.php +++ b/packages/support/src/Json/Exception/JsonCouldNotBeEncoded.php @@ -5,8 +5,5 @@ namespace Tempest\Support\Json\Exception; use InvalidArgumentException; -use Tempest\Support\Json\Exception\JsonException; -final class JsonCouldNotBeEncoded extends InvalidArgumentException implements JsonException -{ -} +final class JsonCouldNotBeEncoded extends InvalidArgumentException implements JsonException {} diff --git a/packages/support/src/Json/Exception/JsonException.php b/packages/support/src/Json/Exception/JsonException.php index 43a580f29a..39462316d6 100644 --- a/packages/support/src/Json/Exception/JsonException.php +++ b/packages/support/src/Json/Exception/JsonException.php @@ -4,6 +4,4 @@ namespace Tempest\Support\Json\Exception; -interface JsonException -{ -} +interface JsonException {} diff --git a/packages/support/src/Json/functions.php b/packages/support/src/Json/functions.php index cc54c39ea5..8d8129989b 100644 --- a/packages/support/src/Json/functions.php +++ b/packages/support/src/Json/functions.php @@ -5,6 +5,8 @@ namespace Tempest\Support\Json; use JsonException; +use Tempest\Support\Json\Exception\JsonCouldNotBeDecoded; +use Tempest\Support\Json\Exception\JsonCouldNotBeEncoded; use function json_decode; use function json_encode; @@ -27,7 +29,7 @@ function decode(string $json, bool $associative = true, bool $base64 = false): m $json = base64_decode($json, strict: true); if ($json === false) { - throw new Exception\JsonCouldNotBeDecoded('The provided base64 string is not valid.'); + throw new JsonCouldNotBeDecoded('The provided base64 string is not valid.'); } } @@ -35,7 +37,7 @@ function decode(string $json, bool $associative = true, bool $base64 = false): m /** @var mixed $value */ $value = json_decode($json, $associative, 512, JSON_BIGINT_AS_STRING | JSON_THROW_ON_ERROR); } catch (JsonException $jsonException) { - throw new Exception\JsonCouldNotBeDecoded(sprintf('%s.', $jsonException->getMessage()), $jsonException->getCode(), $jsonException); + throw new JsonCouldNotBeDecoded(sprintf('%s.', $jsonException->getMessage()), $jsonException->getCode(), $jsonException); } return $value; @@ -60,7 +62,7 @@ function encode(mixed $value, bool $pretty = false, int $flags = 0, bool $base64 /** @var non-empty-string $json */ $json = json_encode($value, $flags); } catch (JsonException $jsonException) { - throw new Exception\JsonCouldNotBeEncoded(sprintf('%s.', $jsonException->getMessage()), $jsonException->getCode(), $jsonException); + throw new JsonCouldNotBeEncoded(sprintf('%s.', $jsonException->getMessage()), $jsonException->getCode(), $jsonException); } if ($base64) { diff --git a/packages/support/src/Math/Exception/ArithmeticException.php b/packages/support/src/Math/Exception/ArithmeticException.php index 8ea8a23a9d..76c4f935ed 100644 --- a/packages/support/src/Math/Exception/ArithmeticException.php +++ b/packages/support/src/Math/Exception/ArithmeticException.php @@ -7,6 +7,4 @@ use InvalidArgumentException; // @phpstan-ignore-next-line -class ArithmeticException extends InvalidArgumentException implements MathException -{ -} +class ArithmeticException extends InvalidArgumentException implements MathException {} diff --git a/packages/support/src/Math/Exception/DivisionByZeroException.php b/packages/support/src/Math/Exception/DivisionByZeroException.php index 24ad588217..517aed1d73 100644 --- a/packages/support/src/Math/Exception/DivisionByZeroException.php +++ b/packages/support/src/Math/Exception/DivisionByZeroException.php @@ -4,6 +4,4 @@ namespace Tempest\Support\Math\Exception; -final class DivisionByZeroException extends ArithmeticException -{ -} +final class DivisionByZeroException extends ArithmeticException {} diff --git a/packages/support/src/Math/Exception/InvalidArgumentException.php b/packages/support/src/Math/Exception/InvalidArgumentException.php index ade156b765..0279d738cf 100644 --- a/packages/support/src/Math/Exception/InvalidArgumentException.php +++ b/packages/support/src/Math/Exception/InvalidArgumentException.php @@ -6,6 +6,4 @@ use InvalidArgumentException as PhpInvalidArgumentException; -final class InvalidArgumentException extends PhpInvalidArgumentException implements MathException -{ -} +final class InvalidArgumentException extends PhpInvalidArgumentException implements MathException {} diff --git a/packages/support/src/Math/Exception/MathException.php b/packages/support/src/Math/Exception/MathException.php index da1558aeb3..7537b33a33 100644 --- a/packages/support/src/Math/Exception/MathException.php +++ b/packages/support/src/Math/Exception/MathException.php @@ -4,6 +4,4 @@ namespace Tempest\Support\Math\Exception; -interface MathException -{ -} +interface MathException {} diff --git a/packages/support/src/Math/Exception/OverflowException.php b/packages/support/src/Math/Exception/OverflowException.php index bfbd53e395..3415a94034 100644 --- a/packages/support/src/Math/Exception/OverflowException.php +++ b/packages/support/src/Math/Exception/OverflowException.php @@ -6,6 +6,4 @@ use OverflowException as PhpOverflowException; -final class OverflowException extends PhpOverflowException implements MathException -{ -} +final class OverflowException extends PhpOverflowException implements MathException {} diff --git a/packages/support/src/Math/constants.php b/packages/support/src/Math/constants.php index 8d296b2907..3c6f7b4037 100644 --- a/packages/support/src/Math/constants.php +++ b/packages/support/src/Math/constants.php @@ -26,21 +26,21 @@ * * @var float */ -const E = 2.7182818284590452353602875; +const E = 2.718_281_828_459_045_235_360_287_5; /** * The ratio of the circumference of a circle to its diameter, or approximately 3.141592653589793238462643. * * @var float */ -const PI = 3.141592653589793238462643; +const PI = 3.141_592_653_589_793_238_462_643; /** * The maximum integer value representable in a 64-bit binary-coded decimal. * * @var int */ -const INT64_MAX = 9223372036854775807; +const INT64_MAX = 9_223_372_036_854_775_807; /** * The minimum integer value representable in a 64-bit binary-coded decimal. @@ -54,42 +54,42 @@ * * @var int */ -const INT53_MAX = 9007199254740992; +const INT53_MAX = 9_007_199_254_740_992; /** * The minimum integer value representable in a 53-bit binary-coded decimal. * * @var int */ -const INT53_MIN = -9007199254740993; +const INT53_MIN = -9_007_199_254_740_993; /** * The maximum integer value representable in a 32-bit binary-coded decimal. * * @var int */ -const INT32_MAX = 2147483647; +const INT32_MAX = 2_147_483_647; /** * The minimum integer value representable in a 32-bit binary-coded decimal. * * @var int */ -const INT32_MIN = -2147483648; +const INT32_MIN = -2_147_483_648; /** * The maximum integer value representable in a 16-bit binary-coded decimal. * * @var int */ -const INT16_MAX = 32767; +const INT16_MAX = 32_767; /** * The minimum integer value representable in a 16-bit binary-coded decimal. * * @var int */ -const INT16_MIN = -32768; +const INT16_MIN = -32_768; /** * The maximum integer value representable in a 8-bit binary-coded decimal. @@ -110,14 +110,14 @@ * * @var int */ -const UINT32_MAX = 4294967295; +const UINT32_MAX = 4_294_967_295; /** * The maximum unsigned integer value representable in a 16-bit binary-coded decimal. * * @var int */ -const UINT16_MAX = 65535; +const UINT16_MAX = 65_535; /** * The maximum unsigned integer value representable in a 8-bit binary-coded decimal. @@ -131,25 +131,25 @@ * * @var float */ -const FLOAT32_MAX = 3.40282347E+38; +const FLOAT32_MAX = 3.402_823_47E+38; /** * The minimum floating point value representable in a 32-bit binary-coded decimal. * * @var float */ -const FLOAT32_MIN = -3.40282347E+38; +const FLOAT32_MIN = -3.402_823_47E+38; /** * The maximum floating point value representable in a 64-bit binary-coded decimal. * * @var float */ -const FLOAT64_MAX = 1.7976931348623157E+308; +const FLOAT64_MAX = 1.797_693_134_862_315_7E+308; /** * The minimum floating point value representable in a 64-bit binary-coded decimal. * * @var float */ -const FLOAT64_MIN = -1.7976931348623157E+308; +const FLOAT64_MIN = -1.797_693_134_862_315_7E+308; diff --git a/packages/support/src/Math/functions.php b/packages/support/src/Math/functions.php index 9fbc603730..298464ae40 100644 --- a/packages/support/src/Math/functions.php +++ b/packages/support/src/Math/functions.php @@ -5,6 +5,10 @@ use ArithmeticError; use Closure; use DivisionByZeroError; +use Tempest\Support\Math\Exception\ArithmeticException; +use Tempest\Support\Math\Exception\DivisionByZeroException; +use Tempest\Support\Math\Exception\InvalidArgumentException; +use Tempest\Support\Math\Exception\OverflowException; use Tempest\Support\Str; use function acos as php_acos; @@ -38,7 +42,7 @@ function sqrt(float $number): float { if ($number < 0) { - throw new Exception\InvalidArgumentException('$number must be a non-negative number.'); + throw new InvalidArgumentException('$number must be a non-negative number.'); } return php_sqrt($number); @@ -115,7 +119,7 @@ function base_convert(string $value, int $fromBase, int $toBase): string $digitNumeric = stripos($fromAlphabet, $digit); if (false === $digitNumeric) { - throw new Exception\InvalidArgumentException(sprintf('Invalid digit %s in base %d', $digit, $fromBase)); + throw new InvalidArgumentException(sprintf('Invalid digit %s in base %d', $digit, $fromBase)); } $resultDecimal = bcadd($resultDecimal, bcmul((string) $digitNumeric, $placeValue)); @@ -161,7 +165,7 @@ function ceil(float $number): float function clamp(int|float $number, int|float $min, int|float $max): int|float { if ($max < $min) { - throw new Exception\InvalidArgumentException('Expected $min to be lower or equal to $max.'); + throw new InvalidArgumentException('Expected $min to be lower or equal to $max.'); } if ($number < $min) { @@ -194,9 +198,9 @@ function div(int $numerator, int $denominator): int try { return intdiv($numerator, $denominator); } catch (DivisionByZeroError $error) { - throw new Exception\DivisionByZeroException(sprintf('%s.', $error->getMessage()), $error->getCode(), $error); + throw new DivisionByZeroException(sprintf('%s.', $error->getMessage()), $error->getCode(), $error); } catch (ArithmeticError $error) { - throw new Exception\ArithmeticException( + throw new ArithmeticException( 'Division of Math\INT64_MIN by -1 is not an integer.', $error->getCode(), $error, @@ -236,7 +240,7 @@ function from_base(string $number, int $fromBase): int $result = 0; foreach (str_split($number) as $digit) { - $oval = ord($digit); + $oval = ord($digit[0]); // Branches sorted by guesstimated frequency of use. */ if (/* '0' - '9' */ $oval <= 57 && $oval >= 48) { @@ -250,13 +254,13 @@ function from_base(string $number, int $fromBase): int } if ($fromBase < $dval) { - throw new Exception\InvalidArgumentException(sprintf('Invalid digit %s in base %d', $digit, $fromBase)); + throw new InvalidArgumentException(sprintf('Invalid digit %s in base %d', $digit, $fromBase)); } $oldval = $result; $result = ($fromBase * $result) + $dval; if ($oldval > $limit || $oldval > $result) { - throw new Exception\OverflowException(sprintf('Unexpected integer overflow parsing %s from base %d', $number, $fromBase)); + throw new OverflowException(sprintf('Unexpected integer overflow parsing %s from base %d', $number, $fromBase)); } } @@ -293,7 +297,7 @@ function to_base(int $number, int $base): string function log(float $number, ?float $base = null): float { if ($number <= 0) { - throw new Exception\InvalidArgumentException('$number must be positive.'); + throw new InvalidArgumentException('$number must be positive.'); } if (null === $base) { @@ -301,11 +305,11 @@ function log(float $number, ?float $base = null): float } if ($base <= 0) { - throw new Exception\InvalidArgumentException('$base must be positive.'); + throw new InvalidArgumentException('$base must be positive.'); } if ($base === 1.0) { - throw new Exception\InvalidArgumentException('Logarithm undefined for $base of 1.0.'); + throw new InvalidArgumentException('Logarithm undefined for $base of 1.0.'); } return php_log($number, $base); @@ -356,9 +360,11 @@ function max(array $numbers): null|int|float $max = null; foreach ($numbers as $number) { - if (null === $max || $number > $max) { - $max = $number; + if (null !== $max && $number <= $max) { + continue; } + + $max = $number; } return $max; @@ -380,9 +386,11 @@ function maxva(int|float $first, int|float $second, int|float ...$rest): int|flo $max = \max($first, $second); foreach ($rest as $number) { - if ($number > $max) { - $max = $number; + if ($number <= $max) { + continue; } + + $max = $number; } return $max; @@ -488,9 +496,11 @@ function min(array $numbers): null|float|int $min = null; foreach ($numbers as $number) { - if (null === $min || $number < $min) { - $min = $number; + if (null !== $min && $number >= $min) { + continue; } + + $min = $number; } return $min; @@ -512,9 +522,11 @@ function minva(int|float $first, int|float $second, int|float ...$rest): int|flo $min = \min($first, $second); foreach ($rest as $number) { - if ($number < $min) { - $min = $number; + if ($number >= $min) { + continue; } + + $min = $number; } return $min; diff --git a/packages/support/src/Namespace/functions.php b/packages/support/src/Namespace/functions.php index 06bc5ba26d..22308bdb11 100644 --- a/packages/support/src/Namespace/functions.php +++ b/packages/support/src/Namespace/functions.php @@ -123,9 +123,11 @@ function prepare_namespace(Stringable|string $path, null|Stringable|string $root // If the path is a to a PHP file, we exclude the file name. Otherwise, // it's a path to a directory, which should be included in the namespace. if ($normalized->endsWith('.php')) { - return $normalized->contains(['/', '\\']) - ? $normalized->beforeLast(['/', '\\']) - : new ImmutableString(); + return ( + $normalized->contains(['/', '\\']) + ? $normalized->beforeLast(['/', '\\']) + : new ImmutableString() + ); } return $normalized; diff --git a/packages/support/src/Paginator/Exceptions/ArgumentWasInvalid.php b/packages/support/src/Paginator/Exceptions/ArgumentWasInvalid.php index 8d332b2bc2..e4462f07ea 100644 --- a/packages/support/src/Paginator/Exceptions/ArgumentWasInvalid.php +++ b/packages/support/src/Paginator/Exceptions/ArgumentWasInvalid.php @@ -4,6 +4,4 @@ use InvalidArgumentException as PhpInvalidArgumentException; -final class ArgumentWasInvalid extends PhpInvalidArgumentException implements PaginationException -{ -} +final class ArgumentWasInvalid extends PhpInvalidArgumentException implements PaginationException {} diff --git a/packages/support/src/Paginator/Exceptions/PaginationException.php b/packages/support/src/Paginator/Exceptions/PaginationException.php index 2615082658..1baf9d68a3 100644 --- a/packages/support/src/Paginator/Exceptions/PaginationException.php +++ b/packages/support/src/Paginator/Exceptions/PaginationException.php @@ -2,6 +2,4 @@ namespace Tempest\Support\Paginator\Exceptions; -interface PaginationException -{ -} +interface PaginationException {} diff --git a/packages/support/src/Path/Path.php b/packages/support/src/Path/Path.php index f5f3206209..c24967c114 100644 --- a/packages/support/src/Path/Path.php +++ b/packages/support/src/Path/Path.php @@ -24,7 +24,7 @@ public function __construct(Stringable|string ...$paths) protected function createOrModify(Stringable|string $string): self { - return new static($string); + return new self($string); } /** diff --git a/packages/support/src/Path/functions.php b/packages/support/src/Path/functions.php index 4a8295234b..f11d6675fd 100644 --- a/packages/support/src/Path/functions.php +++ b/packages/support/src/Path/functions.php @@ -55,7 +55,7 @@ function is_absolute_path(null|Stringable|string ...$parts): bool { $path = namespace\normalize(...$parts); - if (strlen($path) === 0 || '.' === $path[0]) { + if ($path === '' || '.' === $path[0]) { return false; } @@ -149,7 +149,7 @@ function normalize(null|Stringable|string ...$paths): string // Restore virtual phar prefix if (str_starts_with($path, 'phar:')) { - $path = str_replace('phar:', 'phar://', $path); + return str_replace('phar:', 'phar://', $path); } return $path; diff --git a/packages/support/src/Regex/InvalidPatternException.php b/packages/support/src/Regex/InvalidPatternException.php index c607821b72..6814b90a16 100644 --- a/packages/support/src/Regex/InvalidPatternException.php +++ b/packages/support/src/Regex/InvalidPatternException.php @@ -6,6 +6,4 @@ use RuntimeException; -final class InvalidPatternException extends RuntimeException -{ -} +final class InvalidPatternException extends RuntimeException {} diff --git a/packages/support/src/Str/ImmutableString.php b/packages/support/src/Str/ImmutableString.php index 86302f21f3..b29d8a9315 100644 --- a/packages/support/src/Str/ImmutableString.php +++ b/packages/support/src/Str/ImmutableString.php @@ -56,6 +56,6 @@ public function when(mixed $condition, Closure $callback): self */ protected function createOrModify(Stringable|string $string): self { - return new static($string); + return new self($string); } } diff --git a/packages/support/src/Str/ManipulatesString.php b/packages/support/src/Str/ManipulatesString.php index 140f4e72cb..868d6e82ca 100644 --- a/packages/support/src/Str/ManipulatesString.php +++ b/packages/support/src/Str/ManipulatesString.php @@ -7,8 +7,11 @@ use ArrayAccess; use Closure; use Countable; +use RuntimeException; use Stringable; +use Tempest\Debug\Debug; use Tempest\Intl; +use Tempest\Intl\Pluralizer\Pluralizer; use Tempest\Support\Arr\ImmutableArray; use Tempest\Support\Random; use Tempest\Support\Regex; @@ -837,8 +840,8 @@ public function length(): int private function ensurePluralizerInstalled(string $function): void { - if (! interface_exists(Intl\Pluralizer\Pluralizer::class)) { - throw new \RuntimeException("The `tempest/intl` package is required to use `{$function}`."); + if (! interface_exists(Pluralizer::class)) { + throw new RuntimeException("The `tempest/intl` package is required to use `{$function}`."); } } @@ -874,7 +877,7 @@ public function dump(mixed ...$dumps): self private function debugLog(array $items, bool $terminate = false): void { - $debugClass = \Tempest\Debug\Debug::class; + $debugClass = Debug::class; if (class_exists($debugClass)) { $debugClass::resolve()->log($items); diff --git a/packages/support/src/Str/StringInterface.php b/packages/support/src/Str/StringInterface.php index 1fc7f43f21..c56f727003 100644 --- a/packages/support/src/Str/StringInterface.php +++ b/packages/support/src/Str/StringInterface.php @@ -10,6 +10,4 @@ /** * @internal This interface is not meant to be used in userland. */ -interface StringInterface extends Stringable, JsonSerializable -{ -} +interface StringInterface extends Stringable, JsonSerializable {} diff --git a/packages/support/src/Str/functions.php b/packages/support/src/Str/functions.php index 5842b86a7c..17fc68cd2e 100644 --- a/packages/support/src/Str/functions.php +++ b/packages/support/src/Str/functions.php @@ -29,7 +29,7 @@ function to_title_case(Stringable|string $string): string function to_sentence_case(Stringable|string $string): string { $words = array_map( - callback: fn (string $string) => to_lower_case($string), + callback: to_lower_case(...), array: to_words($string), ); @@ -658,13 +658,7 @@ function slice(Stringable|string $string, int $start, ?int $length = null): stri */ function contains(Stringable|string $string, Stringable|string|array $needle): bool { - foreach (Arr\wrap($needle) as $item) { - if (str_contains((string) $string, (string) $item)) { - return true; - } - } - - return false; + return array_any(Arr\wrap($needle), fn ($item) => str_contains((string) $string, (string) $item)); } /** @@ -698,11 +692,7 @@ function chunk(Stringable|string $string, int $length): array $chunks = []; - foreach (str_split($string, $length) as $chunk) { - $chunks[] = $chunk; - } - - return $chunks; + return str_split($string, $length); } /** diff --git a/packages/support/src/Uri/Uri.php b/packages/support/src/Uri/Uri.php index aedf22f6d9..4070039bfb 100644 --- a/packages/support/src/Uri/Uri.php +++ b/packages/support/src/Uri/Uri.php @@ -4,20 +4,21 @@ namespace Tempest\Support\Uri; +use Stringable; use Tempest\Support\Str; use Tempest\Support\Str\ImmutableString; use Tempest\Support\Str\MutableString; use function parse_url; -final class Uri +final class Uri implements Stringable { /** * The path segments as an array. */ public array $segments { get { - if ($this->path === null || $this->path === '' || $this->path === '/') { + if (in_array($this->path, [null, '', '/'], true)) { return []; } @@ -180,10 +181,8 @@ public function withoutQuery(mixed ...$query): self foreach ($query as $key => $value) { if (is_int($key)) { unset($currentQuery[$value]); - } else { - if (isset($currentQuery[$key]) && $currentQuery[$key] === $value) { - unset($currentQuery[$key]); - } + } elseif (isset($currentQuery[$key]) && $currentQuery[$key] === $value) { + unset($currentQuery[$key]); } } @@ -263,9 +262,7 @@ private function buildQueryString(array $query): ?string } $queryString = http_build_query($processedQuery, arg_separator: '&', encoding_type: PHP_QUERY_RFC3986); - $queryString = preg_replace('/([^=&]+)=(?=&|$)/', replacement: '$1', subject: $queryString); - - return $queryString; + return preg_replace('/([^=&]+)=(?=&|$)/', replacement: '$1', subject: $queryString); } /** diff --git a/packages/support/src/Uri/functions.php b/packages/support/src/Uri/functions.php index 325c5308af..ce250ea3ad 100644 --- a/packages/support/src/Uri/functions.php +++ b/packages/support/src/Uri/functions.php @@ -25,7 +25,7 @@ function merge_query(string $uri, mixed ...$query): string */ function without_query(string $uri, mixed ...$query): string { - if (count($query) === 0) { + if ($query === []) { return Uri::from($uri)->removeQuery()->toString(); } diff --git a/packages/support/src/VarExport/EmptyFileNameException.php b/packages/support/src/VarExport/EmptyFileNameException.php index ea0c884e9a..971c27016b 100644 --- a/packages/support/src/VarExport/EmptyFileNameException.php +++ b/packages/support/src/VarExport/EmptyFileNameException.php @@ -6,6 +6,4 @@ use RuntimeException; -final class EmptyFileNameException extends RuntimeException -{ -} +final class EmptyFileNameException extends RuntimeException {} diff --git a/packages/support/src/VarExport/FileDoesNotExistException.php b/packages/support/src/VarExport/FileDoesNotExistException.php index 4b60ade07c..42e029314e 100644 --- a/packages/support/src/VarExport/FileDoesNotExistException.php +++ b/packages/support/src/VarExport/FileDoesNotExistException.php @@ -6,6 +6,4 @@ use RuntimeException; -final class FileDoesNotExistException extends RuntimeException -{ -} +final class FileDoesNotExistException extends RuntimeException {} diff --git a/packages/support/src/VarExport/VarExportPhpFile.php b/packages/support/src/VarExport/VarExportPhpFile.php index 3cc6252665..fb17b7e3a7 100644 --- a/packages/support/src/VarExport/VarExportPhpFile.php +++ b/packages/support/src/VarExport/VarExportPhpFile.php @@ -47,9 +47,9 @@ public function export(mixed $data): void $serializedData = VarExporter::export($data); $phpFileContent = <<filename, $phpFileContent, LOCK_EX); } diff --git a/packages/support/tests/Arr/ImmutableArrayTest.php b/packages/support/tests/Arr/ImmutableArrayTest.php index 07cdb1ebeb..77ffa5a231 100644 --- a/packages/support/tests/Arr/ImmutableArrayTest.php +++ b/packages/support/tests/Arr/ImmutableArrayTest.php @@ -62,8 +62,8 @@ public function test_add_diverse_values(): void ); $this->assertSame( - actual: $collection->add('name')->toArray(), expected: ['name'], + actual: $collection->add('name')->toArray(), ); } diff --git a/packages/support/tests/Arr/ManipulatesArrayTest.php b/packages/support/tests/Arr/ManipulatesArrayTest.php index 46744bc845..f1150610ea 100644 --- a/packages/support/tests/Arr/ManipulatesArrayTest.php +++ b/packages/support/tests/Arr/ManipulatesArrayTest.php @@ -203,7 +203,7 @@ public function test_unshift(): void public function test_last(): void { - $this->assertSame(null, arr()->last()); + $this->assertNull(arr()->last()); $this->assertSame('c', arr(['a', 'b', 'c'])->last()); $this->assertSame('foo', arr()->last(default: 'foo')); @@ -213,7 +213,7 @@ public function test_last(): void public function test_first(): void { $this->assertSame('a', arr(['a', 'b', 'c'])->first()); - $this->assertSame(null, arr()->first()); + $this->assertNull(arr()->first()); $this->assertSame('foo', arr()->first(default: 'foo')); $this->assertSame(1, arr([1, 2])->first(default: 'foo')); @@ -950,8 +950,8 @@ public function test_add_diverse_values(): void ); $this->assertSame( - actual: $collection->add('name')->toArray(), expected: ['name'], + actual: $collection->add('name')->toArray(), ); } @@ -1639,9 +1639,7 @@ public function test_find_key_with_complex_closure(): void ['age' => 35, 'active' => true], ]); - $result = $collection->findKey(function ($item) { - return $item['age'] > 28 && $item['active'] === true; - }); + $result = $collection->findKey(fn ($item) => $item['age'] > 28 && $item['active'] === true); $this->assertSame(2, $result); } @@ -1698,18 +1696,18 @@ public function test_append(): void $collection = arr(['foo', 'bar']); $this->assertSame( - actual: $collection->append('foo')->toArray(), expected: ['foo', 'bar', 'foo'], + actual: $collection->append('foo')->toArray(), ); $this->assertSame( - actual: $collection->append(1, 'b')->toArray(), expected: ['foo', 'bar', 1, 'b'], + actual: $collection->append(1, 'b')->toArray(), ); $this->assertSame( - actual: $collection->append(['a' => 'b'])->toArray(), expected: ['foo', 'bar', ['a' => 'b']], + actual: $collection->append(['a' => 'b'])->toArray(), ); } @@ -1718,18 +1716,18 @@ public function test_prepend(): void $collection = arr(['foo', 'bar']); $this->assertSame( - actual: $collection->prepend('foo')->toArray(), expected: ['foo', 'foo', 'bar'], + actual: $collection->prepend('foo')->toArray(), ); $this->assertSame( - actual: $collection->prepend(1, 'b')->toArray(), expected: [1, 'b', 'foo', 'bar'], + actual: $collection->prepend(1, 'b')->toArray(), ); $this->assertSame( - actual: $collection->prepend(['a' => 'b'])->toArray(), expected: [['a' => 'b'], 'foo', 'bar'], + actual: $collection->prepend(['a' => 'b'])->toArray(), ); } @@ -1809,7 +1807,7 @@ public function test_at(array $input, int $index, mixed $expected, mixed $defaul public function test_partition(): void { - $this->assertSame([[true, true], [false]], arr([true, true, false])->partition(fn (bool $value) => $value === true)->toArray()); + $this->assertSame([[true, true], [false]], arr([true, true, false])->partition(fn (bool $value) => $value)->toArray()); } public function test_json_encode(): void diff --git a/packages/support/tests/Arr/MutableArrayTest.php b/packages/support/tests/Arr/MutableArrayTest.php index 561b85268e..e159cf5993 100644 --- a/packages/support/tests/Arr/MutableArrayTest.php +++ b/packages/support/tests/Arr/MutableArrayTest.php @@ -62,8 +62,8 @@ public function test_add_diverse_values(): void ); $this->assertSame( - actual: $collection->add('name')->toArray(), expected: [1, 2, '', null, false, [], 'name'], + actual: $collection->add('name')->toArray(), ); } diff --git a/packages/support/tests/Comparison/ComparisonTest.php b/packages/support/tests/Comparison/ComparisonTest.php index 2eea88cc74..9d5379926c 100644 --- a/packages/support/tests/Comparison/ComparisonTest.php +++ b/packages/support/tests/Comparison/ComparisonTest.php @@ -3,6 +3,7 @@ namespace Tempest\Support\Tests\Comparison; use Generator; +use Override; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Tempest\Support\Comparison; @@ -20,10 +21,10 @@ public function test_it_can_compare(mixed $a, mixed $b, Order $expected): void public function test_it_can_fail_comparing(): void { - $a = static::createIncomparableWrapper(1); - $b = static::createIncomparableWrapper(2); + $a = $this->createIncomparableWrapper(1); + $b = $this->createIncomparableWrapper(2); - $this->expectException(Comparison\Exception\IncomparableException::class); + $this->expectException(IncomparableException::class); $this->expectExceptionMessage('Unable to compare "int" with "int".'); Comparison\compare($a, $b); @@ -31,10 +32,10 @@ public function test_it_can_fail_comparing(): void public function test_it_can_fail_comparing_with_additional_info(): void { - $a = static::createIncomparableWrapper(1, 'Can only compare even numbers'); - $b = static::createIncomparableWrapper(2); + $a = $this->createIncomparableWrapper(1, 'Can only compare even numbers'); + $b = $this->createIncomparableWrapper(2); - $this->expectException(Comparison\Exception\IncomparableException::class); + $this->expectException(IncomparableException::class); $this->expectExceptionMessage('Unable to compare "int" with "int": Can only compare even numbers'); Comparison\compare($a, $b); @@ -48,35 +49,35 @@ public static function provideComparisonCases(): Generator yield 'scalar-greater' => [1, 0, Order::GREATER]; yield 'comparable-default' => [ - static::createComparableIntWrapper(0), - static::createComparableIntWrapper(0), + self::createComparableIntWrapper(0), + self::createComparableIntWrapper(0), Order::default(), ]; yield 'comparable-equal' => [ - static::createComparableIntWrapper(0), - static::createComparableIntWrapper(0), + self::createComparableIntWrapper(0), + self::createComparableIntWrapper(0), Order::EQUAL, ]; yield 'comparable-less' => [ - static::createComparableIntWrapper(0), - static::createComparableIntWrapper(1), + self::createComparableIntWrapper(0), + self::createComparableIntWrapper(1), Order::LESS, ]; yield 'comparable-greater' => [ - static::createComparableIntWrapper(1), - static::createComparableIntWrapper(0), + self::createComparableIntWrapper(1), + self::createComparableIntWrapper(0), Order::GREATER, ]; } private static function createComparableIntWrapper(int $i): Comparable { - return new class($i) implements Comparable { + return new readonly class($i) implements Comparable { public function __construct( - public readonly int $int, + public int $int, ) {} - #[\Override] + #[Override] public function compare(mixed $other): Order { return Order::from($this->int <=> $other->int); @@ -84,15 +85,15 @@ public function compare(mixed $other): Order }; } - private static function createIncomparableWrapper(int $i, string $additionalInfo = ''): Comparable + private function createIncomparableWrapper(int $i, string $additionalInfo = ''): Comparable { - return new class($i, $additionalInfo) implements Comparable { + return new readonly class($i, $additionalInfo) implements Comparable { public function __construct( - public readonly int $int, - public readonly string $additionalInfo, + public int $int, + public string $additionalInfo, ) {} - #[\Override] + #[Override] public function compare(mixed $other): Order { throw IncomparableException::fromValues($this->int, $other->int, $this->additionalInfo); diff --git a/packages/support/tests/Filesystem/UnixFunctionsTest.php b/packages/support/tests/Filesystem/UnixFunctionsTest.php index d30c3a8a7f..7838eea553 100644 --- a/packages/support/tests/Filesystem/UnixFunctionsTest.php +++ b/packages/support/tests/Filesystem/UnixFunctionsTest.php @@ -2,6 +2,8 @@ namespace Tempest\Support\Tests\Filesystem; +use JsonSerializable; +use Phar; use PHPUnit\Framework\Attributes\PostCondition; use PHPUnit\Framework\Attributes\PreCondition; use PHPUnit\Framework\Attributes\Test; @@ -849,7 +851,7 @@ public function write_json_serializable(): void { $file = $this->fixtures . '/tmp/file.json'; - $data = new class implements \JsonSerializable { + $data = new class implements JsonSerializable { public function jsonSerialize(): array { return ['key' => 'value']; @@ -1008,12 +1010,12 @@ public function delete_file_for_invalid_symlink(): void #[Test] public function normalize_path_in_phar(): void { - if (\Phar::canWrite() === false) { + if (Phar::canWrite() === false) { $this->markTestSkipped('phar.readonly is enabled in php.ini.'); } $pharFile = $this->fixtures . '/phar.phar'; - $phar = new \Phar($pharFile, 0, 'phar.phar'); + $phar = new Phar($pharFile, 0, 'phar.phar'); $phar->addFile(__DIR__ . '/../../src/Filesystem/functions.php', 'functions.php'); $phar->addFile(__DIR__ . '/../Fixtures/Phar/normalize_path.php', 'index.php'); $phar->createDefaultStub('index.php'); diff --git a/packages/support/tests/Json/JsonTest.php b/packages/support/tests/Json/JsonTest.php index f8b7467600..e944de6f33 100644 --- a/packages/support/tests/Json/JsonTest.php +++ b/packages/support/tests/Json/JsonTest.php @@ -4,6 +4,8 @@ use PHPUnit\Framework\TestCase; use Tempest\Support\Json; +use Tempest\Support\Json\Exception\JsonCouldNotBeDecoded; +use Tempest\Support\Json\Exception\JsonCouldNotBeEncoded; use Tempest\Support\Math; use Tempest\Support\Str; @@ -33,7 +35,7 @@ public function test_decode(): void public function test_decode_throws_for_invalid_syntax(): void { - $this->expectException(Json\Exception\JsonCouldNotBeDecoded::class); + $this->expectException(JsonCouldNotBeDecoded::class); $this->expectExceptionMessage('The decoded property name is invalid.'); Json\decode('{"\u0000": 1}', false); @@ -41,7 +43,7 @@ public function test_decode_throws_for_invalid_syntax(): void public function test_decode_malformed_utf8(): void { - $this->expectException(Json\Exception\JsonCouldNotBeDecoded::class); + $this->expectException(JsonCouldNotBeDecoded::class); $this->expectExceptionMessage('Malformed UTF-8 characters, possibly incorrectly encoded.'); Json\decode("\"\xC1\xBF\""); @@ -65,27 +67,27 @@ public function test_pretty_encode(): void ], true); $json = Str\replace(<<assertSame($json, $actual); } public function test_encode_throws_for_malformed_utf8(): void { - $this->expectException(Json\Exception\JsonCouldNotBeEncoded::class); + $this->expectException(JsonCouldNotBeEncoded::class); $this->expectExceptionMessage('Malformed UTF-8 characters, possibly incorrectly encoded.'); Json\encode(["bad utf\xFF"]); @@ -93,7 +95,7 @@ public function test_encode_throws_for_malformed_utf8(): void public function test_encode_throws_with_nan(): void { - $this->expectException(Json\Exception\JsonCouldNotBeEncoded::class); + $this->expectException(JsonCouldNotBeEncoded::class); $this->expectExceptionMessage('Inf and NaN cannot be JSON encoded.'); Json\encode(Math\NAN); @@ -101,7 +103,7 @@ public function test_encode_throws_with_nan(): void public function test_encode_throws_with_inf(): void { - $this->expectException(Json\Exception\JsonCouldNotBeEncoded::class); + $this->expectException(JsonCouldNotBeEncoded::class); $this->expectExceptionMessage('Inf and NaN cannot be JSON encoded.'); Json\encode(Math\INFINITY); @@ -143,7 +145,7 @@ public function test_base64_encode_and_decode(): void public function test_base64_decode_failure(): void { - $this->expectException(Json\Exception\JsonCouldNotBeDecoded::class); + $this->expectException(JsonCouldNotBeDecoded::class); $this->expectExceptionMessage('The provided base64 string is not valid.'); Json\decode('invalid_base64', base64: true); diff --git a/packages/support/tests/Math/MathsTest.php b/packages/support/tests/Math/MathsTest.php index 937195336a..8c3a094235 100644 --- a/packages/support/tests/Math/MathsTest.php +++ b/packages/support/tests/Math/MathsTest.php @@ -8,6 +8,10 @@ use PHPUnit\Framework\Attributes\TestWith; use PHPUnit\Framework\TestCase; use Tempest\Support\Math; +use Tempest\Support\Math\Exception\ArithmeticException; +use Tempest\Support\Math\Exception\DivisionByZeroException; +use Tempest\Support\Math\Exception\InvalidArgumentException; +use Tempest\Support\Math\Exception\OverflowException; use function Tempest\Support\Arr\range; @@ -23,37 +27,37 @@ public function test_abs(int|float $expected, int|float $number): void } #[TestWith([0.0, 1.0])] - #[TestWith([1.2661036727794992, 0.3])] - #[TestWith([1.0471975511965979, 0.5])] + #[TestWith([1.266_103_672_779_499_2, 0.3])] + #[TestWith([1.047_197_551_196_597_9, 0.5])] public function test_acos(float $expected, float $number): void { $this->assertFloatEquals($expected, Math\acos($number)); } - #[TestWith([0.5235987755982989, 0.5])] - #[TestWith([0.9272952180016123, 0.8])] + #[TestWith([0.523_598_775_598_298_9, 0.5])] + #[TestWith([0.927_295_218_001_612_3, 0.8])] #[TestWith([0.0, 0.0])] - #[TestWith([0.41151684606748806, 0.4])] + #[TestWith([0.411_516_846_067_488_06, 0.4])] public function test_asin(float $expected, float $number): void { $this->assertFloatEquals($expected, Math\asin($number)); } - #[TestWith([0.7853981633974483, 1.0, 1.0])] - #[TestWith([0.8960553845713439, 1.0, 0.8])] + #[TestWith([0.785_398_163_397_448_3, 1.0, 1.0])] + #[TestWith([0.896_055_384_571_343_9, 1.0, 0.8])] #[TestWith([0.0, 0.0, 0.0])] - #[TestWith([0.7853981633974483, 0.4, 0.4])] - #[TestWith([-2.260001062633476, -0.5, -0.412])] + #[TestWith([0.785_398_163_397_448_3, 0.4, 0.4])] + #[TestWith([-2.260_001_062_633_476, -0.5, -0.412])] public function test_atan2(float $expected, float $y, float $x): void { $this->assertFloatEquals($expected, Math\atan2($y, $x)); } - #[TestWith([0.7853981633974483, 1.0])] - #[TestWith([0.6747409422235527, 0.8])] + #[TestWith([0.785_398_163_397_448_3, 1.0])] + #[TestWith([0.674_740_942_223_552_7, 0.8])] #[TestWith([0.0, 0.0])] - #[TestWith([0.3805063771123649, 0.4])] - #[TestWith([-0.4636476090008061, -0.5])] + #[TestWith([0.380_506_377_112_364_9, 0.4])] + #[TestWith([-0.463_647_609_000_806_1, -0.5])] public function test_atan(float $expected, float $number): void { $this->assertFloatEquals($expected, Math\atan($number)); @@ -96,17 +100,17 @@ public function test_clamp(int|float $expected, int|float $number, int|float $mi public function test_clamp_invalid_min_max(): void { - $this->expectException(Math\Exception\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Expected $min to be lower or equal to $max.'); Math\clamp(10, 20, 10); } - #[TestWith([0.5403023058681398, 1.0])] + #[TestWith([0.540_302_305_868_139_8, 1.0])] #[TestWith([1.0, 0.0])] - #[TestWith([0.10291095660695612, 45.45])] - #[TestWith([0.28366218546322625, -5])] - #[TestWith([-0.9983206000589924, -15.65])] + #[TestWith([0.102_910_956_606_956_12, 45.45])] + #[TestWith([0.283_662_185_463_226_25, -5])] + #[TestWith([-0.998_320_600_058_992_4, -15.65])] public function test_cos(float $expected, float $number): void { $this->assertFloatEquals($expected, Math\cos($number)); @@ -123,7 +127,7 @@ public function test_div(int $expected, int $numerator, int $denominator): void public function test_div_by_zero(): void { - $this->expectException(Math\Exception\DivisionByZeroException::class); + $this->expectException(DivisionByZeroException::class); $this->expectExceptionMessage('Division by zero.'); Math\div(10, 0); @@ -131,15 +135,15 @@ public function test_div_by_zero(): void public function test_div_int64_min_by_minus_one(): void { - $this->expectException(Math\Exception\ArithmeticException::class); + $this->expectException(ArithmeticException::class); $this->expectExceptionMessage('Division of Math\INT64_MIN by -1 is not an integer.'); Math\div(Math\INT64_MIN, -1); } - #[TestWith([162754.79141900392, 12.0])] - #[TestWith([298.8674009670603, 5.7])] - #[TestWith([Math\INFINITY, 1000000])] + #[TestWith([162_754.791_419_003_92, 12.0])] + #[TestWith([298.867_400_967_060_3, 5.7])] + #[TestWith([Math\INFINITY, 1_000_000])] public function test_exp(float $expected, float $number): void { $this->assertSame($expected, Math\exp($number)); @@ -156,7 +160,7 @@ public function test_floor(float $expected, float $number): void } #[TestWith([5497, '1010101111001', 2])] - #[TestWith([2014587925987, 'pphlmw9v', 36])] + #[TestWith([2_014_587_925_987, 'pphlmw9v', 36])] #[TestWith([Math\INT32_MAX, 'zik0zj', 36])] #[TestWith([15, 'F', 16])] public function test_from_base(int $expected, string $value, int $from_base): void @@ -166,7 +170,7 @@ public function test_from_base(int $expected, string $value, int $from_base): vo public function test_invalid_digit_throws(): void { - $this->expectException(Math\Exception\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Invalid digit Z in base 16'); Math\from_base('Z', 16); @@ -174,7 +178,7 @@ public function test_invalid_digit_throws(): void public function test_special_char_throws(): void { - $this->expectException(Math\Exception\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Invalid digit * in base 16'); Math\from_base('*', 16); @@ -184,15 +188,15 @@ public function test_throws_for_overflow(): void { $number = str_repeat('A', times: 100); - $this->expectException(Math\Exception\OverflowException::class); + $this->expectException(OverflowException::class); $this->expectExceptionMessage('Unexpected integer overflow parsing ' . $number . ' from base 32'); Math\from_base($number, 32); } - #[TestWith([1.6863989535702288, 5.4, null])] - #[TestWith([0.6574784600188808, 5.4, 13])] - #[TestWith([1.7323937598229686, 54.0, 10])] + #[TestWith([1.686_398_953_570_228_8, 5.4, null])] + #[TestWith([0.657_478_460_018_880_8, 5.4, 13])] + #[TestWith([1.732_393_759_822_968_6, 54.0, 10])] #[TestWith([0, 1, null])] public function test_log(float $expected, float $number, ?float $base = null): void { @@ -201,7 +205,7 @@ public function test_log(float $expected, float $number, ?float $base = null): v public function test_negative_input_throws(): void { - $this->expectException(Math\Exception\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('$number must be positive.'); Math\log(-45); @@ -209,7 +213,7 @@ public function test_negative_input_throws(): void public function test_non_positive_base_throws(): void { - $this->expectException(Math\Exception\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('$base must be positive.'); Math\log(4.4, 0.0); @@ -217,7 +221,7 @@ public function test_non_positive_base_throws(): void public function test_base_one_throws_for_undefined_logarithm(): void { - $this->expectException(Math\Exception\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Logarithm undefined for $base of 1.0.'); Math\log(4.4, 1.0); @@ -234,7 +238,7 @@ public static function provide_max_by_cases(): Generator yield [ 'bazqux', ['foo', 'bar', 'baz', 'qux', 'foobar', 'bazqux'], - static fn (string $value): int => mb_strlen($value), + mb_strlen(...), ]; yield [ @@ -244,7 +248,7 @@ public static function provide_max_by_cases(): Generator ['foo', 'bar'], ['foo', 'bar', 'baz'], ], - static fn (array $arr): int => count($arr), + count(...), ]; yield [ @@ -293,8 +297,8 @@ public static function provide_mean_cases(): array { return [ [5.0, [10, 5, 0, 2, 4, 6, 8]], - [7.357142857142858, [18, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15]], - [26.785714285714285, [19, 15, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 52, 64]], + [7.357_142_857_142_858, [18, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15]], + [26.785_714_285_714_285, [19, 15, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 52, 64]], [100.0, array_fill(0, 100, 100)], [null, []], ]; @@ -328,7 +332,7 @@ public static function provide_min_by_cases(): Generator yield [ 'qux', ['foo', 'bar', 'baz', 'qux', 'foobar', 'bazqux'], - static fn (string $value): int => mb_strlen($value), + mb_strlen(...), ]; yield [ @@ -338,7 +342,7 @@ public static function provide_min_by_cases(): Generator ['foo', 'bar'], ['foo', 'bar', 'baz'], ], - static fn (array $arr): int => count($arr), + count(...), ]; yield [ @@ -384,33 +388,33 @@ public static function provide_min_va_cases(): array ]; } - #[TestWith([5.46, 5.45663, 2])] + #[TestWith([5.46, 5.456_63, 2])] #[TestWith([4.8, 4.811, 1])] #[TestWith([5.0, 5.42, 0])] #[TestWith([5.0, 4.8, 0])] #[TestWith([0.0, 0.4242, 0])] #[TestWith([0.5, 0.4634, 1])] - #[TestWith([-6.57778, -6.5777777777, 5])] + #[TestWith([-6.577_78, -6.577_777_777_7, 5])] public function test_round(float $expected, float $number, int $precision = 0): void { $this->assertSame($expected, Math\round($number, $precision)); } - #[TestWith([-0.9589242746631385, 5.0])] - #[TestWith([-0.9961646088358407, 4.8])] + #[TestWith([-0.958_924_274_663_138_5, 5.0])] + #[TestWith([-0.996_164_608_835_840_7, 4.8])] #[TestWith([0.0, 0.0])] - #[TestWith([0.3894183423086505, 0.4])] - #[TestWith([-0.21511998808781552, -6.5])] + #[TestWith([0.389_418_342_308_650_5, 0.4])] + #[TestWith([-0.215_119_988_087_815_52, -6.5])] public function test_sin(float $expected, float $number): void { $this->assertFloatEquals($expected, Math\sin($number)); } - #[TestWith([2.23606797749979, 5.0])] - #[TestWith([2.1908902300206643, 4.8])] - #[TestWith([0.6324555320336759, 0.4])] - #[TestWith([2.5495097567963922, 6.5])] - #[TestWith([1.4142135623730951, 2])] + #[TestWith([2.236_067_977_499_79, 5.0])] + #[TestWith([2.190_890_230_020_664_3, 4.8])] + #[TestWith([0.632_455_532_033_675_9, 0.4])] + #[TestWith([2.549_509_756_796_392_2, 6.5])] + #[TestWith([1.414_213_562_373_095_1, 2])] #[TestWith([1, 1])] public function test_sqrt(float $expected, float $number): void { @@ -426,7 +430,7 @@ public function test_sum_floats(float $expected, array $numbers): void public static function provide_sum_floats_data(): array { return [ - [116.70000000000005, [10.9, 5, ...range(0, 9.8798, 0.48)]], + [116.700_000_000_000_05, [10.9, 5, ...range(0, 9.8798, 0.48)]], [103.0, [18, 15, ...range(0, 10), 15]], [323.54, [19.5, 15.8, ...range(0.5, 45, 5.98), 52.8, 64]], ]; @@ -447,18 +451,18 @@ public static function provide_sum_data(): array ]; } - #[TestWith([-3.380515006246586, 5.0, 0.00000000000001])] - #[TestWith([-11.384870654242922, 4.8])] + #[TestWith([-3.380_515_006_246_586, 5.0, 0.000_000_000_000_01])] + #[TestWith([-11.384_870_654_242_922, 4.8])] #[TestWith([0.0, 0.0])] - #[TestWith([0.4227932187381618, 0.4])] - #[TestWith([-0.22027720034589682, -6.5])] + #[TestWith([0.422_793_218_738_161_8, 0.4])] + #[TestWith([-0.220_277_200_345_896_82, -6.5])] public function test_tan(float $expected, float $number, float $epsilon = PHP_FLOAT_EPSILON): void { $this->assertFloatEquals($expected, Math\tan($number), $epsilon); } #[TestWith(['1010101111001', 5497, 2])] - #[TestWith(['pphlmw9v', 2014587925987, 36])] + #[TestWith(['pphlmw9v', 2_014_587_925_987, 36])] #[TestWith(['zik0zj', Math\INT32_MAX, 36])] #[TestWith(['f', 15, 16])] public function test_to_base(string $expected, int $value, int $to_base): void diff --git a/packages/support/tests/Namespace/FunctionsTest.php b/packages/support/tests/Namespace/FunctionsTest.php index 6deb9d9231..e0057a6b2e 100644 --- a/packages/support/tests/Namespace/FunctionsTest.php +++ b/packages/support/tests/Namespace/FunctionsTest.php @@ -7,6 +7,7 @@ use PHPUnit\Framework\TestCase; use Tempest\Support\Namespace\PathCouldNotBeMappedToNamespace; use Tempest\Support\Namespace\Psr4Namespace; +use Tempest\Vite\Vite; use function Tempest\Support\Namespace\to_base_class_name; use function Tempest\Support\Namespace\to_fqcn; @@ -72,7 +73,7 @@ public function to_composer_namespace_exceptions(string $path, string $expected, #[TestWith(['spp/Vite.php', 'Vite'])] #[TestWith(['Vite.php', 'Vite'])] #[TestWith(['Vite', 'Vite'])] - #[TestWith([\Tempest\Vite\Vite::class, 'Vite'])] + #[TestWith([Vite::class, 'Vite'])] #[Test] public function to_base_class_name(string $path, string $expected): void { diff --git a/packages/support/tests/Paginator/PaginatorTest.php b/packages/support/tests/Paginator/PaginatorTest.php index c93a7b3fd5..f48db6711b 100644 --- a/packages/support/tests/Paginator/PaginatorTest.php +++ b/packages/support/tests/Paginator/PaginatorTest.php @@ -140,9 +140,7 @@ public function test_it_creates_paginated_data_with_callback(): void { $paginator = $this->createPaginator(totalItems: 100, itemsPerPage: 10, currentPage: 3); - $dataFetcher = function (int $_limit, int $offset): array { - return ["item_{$offset}_1", "item_{$offset}_2"]; - }; + $dataFetcher = fn (int $_limit, int $offset): array => ["item_{$offset}_1", "item_{$offset}_2"]; $paginatedData = $paginator->paginateWith($dataFetcher); diff --git a/packages/support/tests/Regex/FunctionsTest.php b/packages/support/tests/Regex/FunctionsTest.php index 47e4b2033f..e616102bb4 100644 --- a/packages/support/tests/Regex/FunctionsTest.php +++ b/packages/support/tests/Regex/FunctionsTest.php @@ -87,7 +87,7 @@ public function test_get_match(): void $this->assertSame('10', get_match('10-abc', '/(\d+)-.*/', match: 1)); $this->assertSame([0 => '10-abc', 1 => '10'], get_match('10-abc', '/(\d+)-.*/')); $this->assertSame('10-abc', get_match('10-abc', '/\d+-.*/', match: 0)); - $this->assertSame(null, get_match('10-abc', '/\d+-.*/', match: 1)); + $this->assertNull(get_match('10-abc', '/\d+-.*/', match: 1)); $this->assertSame( expected: [ diff --git a/packages/support/tests/Str/FunctionsTest.php b/packages/support/tests/Str/FunctionsTest.php index 0f8278043a..ee16f2315d 100644 --- a/packages/support/tests/Str/FunctionsTest.php +++ b/packages/support/tests/Str/FunctionsTest.php @@ -16,7 +16,7 @@ public function test_parse(): void $this->assertSame('1', Str\parse('1')); $this->assertSame('1', Str\parse(1)); $this->assertSame('', Str\parse(new stdClass())); - $this->assertSame(null, Str\parse(new stdClass(), default: null)); + $this->assertNull(Str\parse(new stdClass(), default: null)); $this->assertSame('', Str\parse(new stdClass(), default: '')); $this->assertSame('foo', Str\parse(new stdClass(), default: 'foo')); $this->assertSame('foo', Str\parse(new MutableString('foo'))); diff --git a/packages/upgrade/src/Set/TempestLevelSetList.php b/packages/upgrade/src/Set/TempestLevelSetList.php index 859b32034c..663a943988 100644 --- a/packages/upgrade/src/Set/TempestLevelSetList.php +++ b/packages/upgrade/src/Set/TempestLevelSetList.php @@ -7,6 +7,8 @@ final class TempestLevelSetList { public const string UP_TO_TEMPEST_20 = __DIR__ . '/../../config/sets/level/up-to-tempest-20.php'; + public const string UP_TO_TEMPEST_28 = __DIR__ . '/../../config/sets/level/up-to-tempest-28.php'; + public const string UP_TO_TEMPEST_30 = __DIR__ . '/../../config/sets/level/up-to-tempest-30.php'; } diff --git a/packages/upgrade/src/Set/TempestSetList.php b/packages/upgrade/src/Set/TempestSetList.php index 8c4bcaa293..1c6f091540 100644 --- a/packages/upgrade/src/Set/TempestSetList.php +++ b/packages/upgrade/src/Set/TempestSetList.php @@ -7,6 +7,8 @@ final class TempestSetList { public const string TEMPEST_20 = __DIR__ . '/../../config/sets/tempest20.php'; + public const string TEMPEST_28 = __DIR__ . '/../../config/sets/tempest28.php'; + public const string TEMPEST_30 = __DIR__ . '/../../config/sets/tempest30.php'; } diff --git a/packages/upgrade/src/Tempest2/MigrationRector.php b/packages/upgrade/src/Tempest2/MigrationRector.php index d0c36722f4..674bd03315 100644 --- a/packages/upgrade/src/Tempest2/MigrationRector.php +++ b/packages/upgrade/src/Tempest2/MigrationRector.php @@ -3,8 +3,11 @@ namespace Tempest\Upgrade\Tempest2; use PhpParser\Node; +use PhpParser\Node\Expr\ConstFetch; use PhpParser\Node\Name; +use PhpParser\Node\Stmt\Class_; use PhpParser\Node\Stmt\ClassMethod; +use PhpParser\Node\Stmt\Return_; use Rector\Rector\AbstractRector; final class MigrationRector extends AbstractRector @@ -12,13 +15,13 @@ final class MigrationRector extends AbstractRector public function getNodeTypes(): array { return [ - Node\Stmt\Class_::class, + Class_::class, ]; } public function refactor(Node $node): ?int { - if (! $node instanceof Node\Stmt\Class_) { + if (! $node instanceof Class_) { return null; } @@ -27,7 +30,7 @@ public function refactor(Node $node): ?int $implementsDatabaseMigration = array_find_key( $implements, - static fn (Node\Name $name) => $name->toString() === 'Tempest\Database\DatabaseMigration', + static fn (Name $name) => $name->toString() === 'Tempest\Database\DatabaseMigration', ); if ($implementsDatabaseMigration === null) { @@ -38,7 +41,7 @@ public function refactor(Node $node): ?int unset($implements[$implementsDatabaseMigration]); // Add the new MigrateUp interface - $implements[] = new Node\Name('\Tempest\Database\MigratesUp'); + $implements[] = new Name('\Tempest\Database\MigratesUp'); $node->getMethod('up')->returnType = new Name('QueryStatement'); // Check whether the migration has a down method implemented or not @@ -47,11 +50,11 @@ public function refactor(Node $node): ?int $migratesDown = true; foreach ($downStatements as $statement) { - if (! $statement instanceof Node\Stmt\Return_) { + if (! $statement instanceof Return_) { continue; } - if (! $statement->expr instanceof Node\Expr\ConstFetch) { + if (! $statement->expr instanceof ConstFetch) { continue; } @@ -62,7 +65,7 @@ public function refactor(Node $node): ?int if ($migratesDown) { // If the migration has a down method implemented, we'll add the new MigrateDown interface - $implements[] = new Node\Name('\Tempest\Database\MigratesDown'); + $implements[] = new Name('\Tempest\Database\MigratesDown'); $node->getMethod('down')->returnType = new Name('QueryStatement'); } else { // If the migration does not have a down method implemented, we'll remove it entirely diff --git a/packages/upgrade/src/Tempest2/RemoveDatabaseMigrationImportRector.php b/packages/upgrade/src/Tempest2/RemoveDatabaseMigrationImportRector.php index c6d627480d..90906215b1 100644 --- a/packages/upgrade/src/Tempest2/RemoveDatabaseMigrationImportRector.php +++ b/packages/upgrade/src/Tempest2/RemoveDatabaseMigrationImportRector.php @@ -3,6 +3,7 @@ namespace Tempest\Upgrade\Tempest2; use PhpParser\Node; +use PhpParser\Node\UseItem; use PhpParser\NodeVisitor; use Rector\Rector\AbstractRector; @@ -11,13 +12,13 @@ final class RemoveDatabaseMigrationImportRector extends AbstractRector public function getNodeTypes(): array { return [ - Node\UseItem::class, + UseItem::class, ]; } public function refactor(Node $node): ?int { - if (! $node instanceof Node\UseItem) { + if (! $node instanceof UseItem) { return null; } diff --git a/packages/upgrade/src/Tempest2/RemoveIdImportRector.php b/packages/upgrade/src/Tempest2/RemoveIdImportRector.php index d8b5ccf287..2481736ec6 100644 --- a/packages/upgrade/src/Tempest2/RemoveIdImportRector.php +++ b/packages/upgrade/src/Tempest2/RemoveIdImportRector.php @@ -3,6 +3,7 @@ namespace Tempest\Upgrade\Tempest2; use PhpParser\Node; +use PhpParser\Node\UseItem; use PhpParser\NodeVisitor; use Rector\Rector\AbstractRector; @@ -11,13 +12,13 @@ final class RemoveIdImportRector extends AbstractRector public function getNodeTypes(): array { return [ - Node\UseItem::class, + UseItem::class, ]; } public function refactor(Node $node): ?int { - if (! $node instanceof Node\UseItem) { + if (! $node instanceof UseItem) { return null; } diff --git a/packages/upgrade/src/Tempest2/UpdateUriImportsRector.php b/packages/upgrade/src/Tempest2/UpdateUriImportsRector.php index 0ee1a6f0c9..323b16c8c0 100644 --- a/packages/upgrade/src/Tempest2/UpdateUriImportsRector.php +++ b/packages/upgrade/src/Tempest2/UpdateUriImportsRector.php @@ -3,6 +3,8 @@ namespace Tempest\Upgrade\Tempest2; use PhpParser\Node; +use PhpParser\Node\Name; +use PhpParser\Node\UseItem; use Rector\Rector\AbstractRector; final class UpdateUriImportsRector extends AbstractRector @@ -10,22 +12,22 @@ final class UpdateUriImportsRector extends AbstractRector public function getNodeTypes(): array { return [ - Node\UseItem::class, + UseItem::class, ]; } public function refactor(Node $node): ?int { - if (! $node instanceof Node\UseItem) { + if (! $node instanceof UseItem) { return null; } if ($node->name->toString() === 'Tempest\uri') { - $node->name = new Node\Name('Tempest\Router\uri'); + $node->name = new Name('Tempest\Router\uri'); } if ($node->name->toString() === 'Tempest\is_current_uri') { - $node->name = new Node\Name('Tempest\Router\is_current_uri'); + $node->name = new Name('Tempest\Router\is_current_uri'); } return null; diff --git a/packages/upgrade/src/Tempest28/WriteableRouteRector.php b/packages/upgrade/src/Tempest28/WriteableRouteRector.php index 630a8055e3..ce93fe661b 100644 --- a/packages/upgrade/src/Tempest28/WriteableRouteRector.php +++ b/packages/upgrade/src/Tempest28/WriteableRouteRector.php @@ -4,6 +4,8 @@ use PhpParser\Modifiers; use PhpParser\Node; +use PhpParser\Node\Name; +use PhpParser\Node\Stmt\Class_; use Rector\Rector\AbstractRector; use Tempest\Router\Route; @@ -12,13 +14,13 @@ final class WriteableRouteRector extends AbstractRector public function getNodeTypes(): array { return [ - Node\Stmt\Class_::class, + Class_::class, ]; } public function refactor(Node $node): ?int { - if (! $node instanceof Node\Stmt\Class_) { + if (! $node instanceof Class_) { return null; } @@ -27,7 +29,7 @@ public function refactor(Node $node): ?int $implementsRoute = array_find_key( $implements, - static fn (Node\Name $name) => $name->toString() === Route::class, + static fn (Name $name) => $name->toString() === Route::class, ); if ($implementsRoute === null) { diff --git a/packages/upgrade/src/Tempest3/UpdateArrMapFunctionRector.php b/packages/upgrade/src/Tempest3/UpdateArrMapFunctionRector.php index 1433c62e41..aa6fefc97f 100644 --- a/packages/upgrade/src/Tempest3/UpdateArrMapFunctionRector.php +++ b/packages/upgrade/src/Tempest3/UpdateArrMapFunctionRector.php @@ -3,6 +3,10 @@ namespace Tempest\Upgrade\Tempest3; use PhpParser\Node; +use PhpParser\Node\Expr\FuncCall; +use PhpParser\Node\Name; +use PhpParser\Node\Name\FullyQualified; +use PhpParser\Node\UseItem; use Rector\Rector\AbstractRector; final class UpdateArrMapFunctionRector extends AbstractRector @@ -10,26 +14,26 @@ final class UpdateArrMapFunctionRector extends AbstractRector public function getNodeTypes(): array { return [ - Node\UseItem::class, - Node\Expr\FuncCall::class, + UseItem::class, + FuncCall::class, ]; } public function refactor(Node $node): ?int { - if ($node instanceof Node\UseItem) { + if ($node instanceof UseItem) { if ($node->name->toString() === 'Tempest\Support\Arr\map_iterable') { - $node->name = new Node\Name('Tempest\Support\Arr\map'); + $node->name = new Name('Tempest\Support\Arr\map'); } return null; } - if ($node instanceof Node\Expr\FuncCall && $node->name instanceof Node\Name) { + if ($node instanceof FuncCall && $node->name instanceof Name) { $functionName = $node->name->toString(); if ($functionName === 'Tempest\Support\Arr\map_iterable') { - $node->name = new Node\Name\FullyQualified('Tempest\Support\Arr\map'); + $node->name = new FullyQualified('Tempest\Support\Arr\map'); return null; } diff --git a/packages/upgrade/src/Tempest3/UpdateBindableResolveReturnTypeRector.php b/packages/upgrade/src/Tempest3/UpdateBindableResolveReturnTypeRector.php index 43544b8de8..2fb3472162 100644 --- a/packages/upgrade/src/Tempest3/UpdateBindableResolveReturnTypeRector.php +++ b/packages/upgrade/src/Tempest3/UpdateBindableResolveReturnTypeRector.php @@ -6,6 +6,7 @@ use PhpParser\Node\Identifier; use PhpParser\Node\Name; use PhpParser\Node\NullableType; +use PhpParser\Node\Stmt\Class_; use PhpParser\Node\Stmt\ClassMethod; use PhpParser\Node\Stmt\Interface_; use Rector\Rector\AbstractRector; @@ -15,7 +16,7 @@ final class UpdateBindableResolveReturnTypeRector extends AbstractRector public function getNodeTypes(): array { return [ - Node\Stmt\Class_::class, + Class_::class, Interface_::class, ]; } @@ -32,7 +33,7 @@ public function refactor(Node $node): ?int return null; } - if (! $node instanceof Node\Stmt\Class_) { + if (! $node instanceof Class_) { return null; } @@ -67,7 +68,11 @@ private function hasBindableName(array $names): bool private function refactorMethods(array $methods): void { foreach ($methods as $method) { - if ($method->name->toString() !== 'resolve' || ! $method->isStatic()) { + if ($method->name->toString() !== 'resolve') { + continue; + } + + if (! $method->isStatic()) { continue; } diff --git a/packages/upgrade/src/Tempest3/UpdateCommandFunctionImportsRector.php b/packages/upgrade/src/Tempest3/UpdateCommandFunctionImportsRector.php index 9aad37e1a0..8233e11b2f 100644 --- a/packages/upgrade/src/Tempest3/UpdateCommandFunctionImportsRector.php +++ b/packages/upgrade/src/Tempest3/UpdateCommandFunctionImportsRector.php @@ -3,6 +3,10 @@ namespace Tempest\Upgrade\Tempest3; use PhpParser\Node; +use PhpParser\Node\Expr\FuncCall; +use PhpParser\Node\Name; +use PhpParser\Node\Name\FullyQualified; +use PhpParser\Node\UseItem; use Rector\Rector\AbstractRector; final class UpdateCommandFunctionImportsRector extends AbstractRector @@ -10,26 +14,26 @@ final class UpdateCommandFunctionImportsRector extends AbstractRector public function getNodeTypes(): array { return [ - Node\UseItem::class, - Node\Expr\FuncCall::class, + UseItem::class, + FuncCall::class, ]; } public function refactor(Node $node): ?int { - if ($node instanceof Node\UseItem) { + if ($node instanceof UseItem) { if ($node->name->toString() === 'Tempest\command') { - $node->name = new Node\Name('Tempest\CommandBus\command'); + $node->name = new Name('Tempest\CommandBus\command'); } return null; } - if ($node instanceof Node\Expr\FuncCall && $node->name instanceof Node\Name) { + if ($node instanceof FuncCall && $node->name instanceof Name) { $functionName = $node->name->toString(); if ($functionName === 'Tempest\command') { - $node->name = new Node\Name\FullyQualified('Tempest\CommandBus\command'); + $node->name = new FullyQualified('Tempest\CommandBus\command'); return null; } diff --git a/packages/upgrade/src/Tempest3/UpdateContainerFunctionImportsRector.php b/packages/upgrade/src/Tempest3/UpdateContainerFunctionImportsRector.php index 106193e620..cbbd9934c8 100644 --- a/packages/upgrade/src/Tempest3/UpdateContainerFunctionImportsRector.php +++ b/packages/upgrade/src/Tempest3/UpdateContainerFunctionImportsRector.php @@ -3,6 +3,10 @@ namespace Tempest\Upgrade\Tempest3; use PhpParser\Node; +use PhpParser\Node\Expr\FuncCall; +use PhpParser\Node\Name; +use PhpParser\Node\Name\FullyQualified; +use PhpParser\Node\UseItem; use Rector\Rector\AbstractRector; final class UpdateContainerFunctionImportsRector extends AbstractRector @@ -10,36 +14,36 @@ final class UpdateContainerFunctionImportsRector extends AbstractRector public function getNodeTypes(): array { return [ - Node\UseItem::class, - Node\Expr\FuncCall::class, + UseItem::class, + FuncCall::class, ]; } public function refactor(Node $node): ?int { - if ($node instanceof Node\UseItem) { + if ($node instanceof UseItem) { if ($node->name->toString() === 'Tempest\get') { - $node->name = new Node\Name('Tempest\Container\get'); + $node->name = new Name('Tempest\Container\get'); } if ($node->name->toString() === 'Tempest\invoke') { - $node->name = new Node\Name('Tempest\Container\invoke'); + $node->name = new Name('Tempest\Container\invoke'); } return null; } - if ($node instanceof Node\Expr\FuncCall && $node->name instanceof Node\Name) { + if ($node instanceof FuncCall && $node->name instanceof Name) { $functionName = $node->name->toString(); if ($functionName === 'Tempest\get') { - $node->name = new Node\Name\FullyQualified('Tempest\Container\get'); + $node->name = new FullyQualified('Tempest\Container\get'); return null; } if ($functionName === 'Tempest\invoke') { - $node->name = new Node\Name\FullyQualified('Tempest\Container\invoke'); + $node->name = new FullyQualified('Tempest\Container\invoke'); return null; } diff --git a/packages/upgrade/src/Tempest3/UpdateEventFunctionImportsRector.php b/packages/upgrade/src/Tempest3/UpdateEventFunctionImportsRector.php index 30962f6b53..e62e5c27d3 100644 --- a/packages/upgrade/src/Tempest3/UpdateEventFunctionImportsRector.php +++ b/packages/upgrade/src/Tempest3/UpdateEventFunctionImportsRector.php @@ -3,6 +3,10 @@ namespace Tempest\Upgrade\Tempest3; use PhpParser\Node; +use PhpParser\Node\Expr\FuncCall; +use PhpParser\Node\Name; +use PhpParser\Node\Name\FullyQualified; +use PhpParser\Node\UseItem; use Rector\Rector\AbstractRector; final class UpdateEventFunctionImportsRector extends AbstractRector @@ -10,36 +14,36 @@ final class UpdateEventFunctionImportsRector extends AbstractRector public function getNodeTypes(): array { return [ - Node\UseItem::class, - Node\Expr\FuncCall::class, + UseItem::class, + FuncCall::class, ]; } public function refactor(Node $node): ?int { - if ($node instanceof Node\UseItem) { + if ($node instanceof UseItem) { if ($node->name->toString() === 'Tempest\event') { - $node->name = new Node\Name('Tempest\EventBus\event'); + $node->name = new Name('Tempest\EventBus\event'); } if ($node->name->toString() === 'Tempest\listen') { - $node->name = new Node\Name('Tempest\EventBus\listen'); + $node->name = new Name('Tempest\EventBus\listen'); } return null; } - if ($node instanceof Node\Expr\FuncCall && $node->name instanceof Node\Name) { + if ($node instanceof FuncCall && $node->name instanceof Name) { $functionName = $node->name->toString(); if ($functionName === 'Tempest\event') { - $node->name = new Node\Name\FullyQualified('Tempest\EventBus\event'); + $node->name = new FullyQualified('Tempest\EventBus\event'); return null; } if ($functionName === 'Tempest\listen') { - $node->name = new Node\Name\FullyQualified('Tempest\EventBus\listen'); + $node->name = new FullyQualified('Tempest\EventBus\listen'); return null; } diff --git a/packages/upgrade/src/Tempest3/UpdateExceptionProcessorRector.php b/packages/upgrade/src/Tempest3/UpdateExceptionProcessorRector.php index 7bb7dc54a4..157c539b9a 100644 --- a/packages/upgrade/src/Tempest3/UpdateExceptionProcessorRector.php +++ b/packages/upgrade/src/Tempest3/UpdateExceptionProcessorRector.php @@ -3,8 +3,11 @@ namespace Tempest\Upgrade\Tempest3; use PhpParser\Node; +use PhpParser\Node\Identifier; use PhpParser\Node\Name; +use PhpParser\Node\Stmt\Class_; use PhpParser\Node\Stmt\ClassMethod; +use PhpParser\Node\UseItem; use Rector\Rector\AbstractRector; final class UpdateExceptionProcessorRector extends AbstractRector @@ -12,24 +15,24 @@ final class UpdateExceptionProcessorRector extends AbstractRector public function getNodeTypes(): array { return [ - Node\UseItem::class, - Node\Stmt\Class_::class, + UseItem::class, + Class_::class, ]; } public function refactor(Node $node): ?int { - if ($node instanceof Node\UseItem) { + if ($node instanceof UseItem) { $name = $node->name->toString(); if ($name === 'Tempest\Core\ExceptionProcessor' || $name === 'ExceptionProcessor') { - $node->name = new Node\Name('Tempest\Core\Exceptions\ExceptionReporter'); + $node->name = new Name('Tempest\Core\Exceptions\ExceptionReporter'); } return null; } - if (! $node instanceof Node\Stmt\Class_) { + if (! $node instanceof Class_) { return null; } @@ -37,14 +40,14 @@ public function refactor(Node $node): ?int $implementsExceptionProcessor = array_find_key( array: $implements, - callback: static fn (Node\Name $name) => $name->toString() === 'Tempest\Core\ExceptionProcessor' || $name->toString() === 'ExceptionProcessor', + callback: static fn (Name $name) => $name->toString() === 'Tempest\Core\ExceptionProcessor' || $name->toString() === 'ExceptionProcessor', ); if ($implementsExceptionProcessor === null) { return null; } - $implements[$implementsExceptionProcessor] = new Node\Name('\Tempest\Core\Exceptions\ExceptionReporter'); + $implements[$implementsExceptionProcessor] = new Name('\Tempest\Core\Exceptions\ExceptionReporter'); $node->implements = $implements; foreach ($node->stmts as $statement) { @@ -53,7 +56,7 @@ public function refactor(Node $node): ?int } if ($statement->name->toString() === 'process') { - $statement->name = new Node\Identifier('report'); + $statement->name = new Identifier('report'); break; } } diff --git a/packages/upgrade/src/Tempest3/UpdateHasContextRector.php b/packages/upgrade/src/Tempest3/UpdateHasContextRector.php index 20c115c46d..6cf7b0d5d3 100644 --- a/packages/upgrade/src/Tempest3/UpdateHasContextRector.php +++ b/packages/upgrade/src/Tempest3/UpdateHasContextRector.php @@ -3,6 +3,9 @@ namespace Tempest\Upgrade\Tempest3; use PhpParser\Node; +use PhpParser\Node\Name; +use PhpParser\Node\Stmt\Class_; +use PhpParser\Node\UseItem; use Rector\Rector\AbstractRector; final class UpdateHasContextRector extends AbstractRector @@ -10,24 +13,24 @@ final class UpdateHasContextRector extends AbstractRector public function getNodeTypes(): array { return [ - Node\UseItem::class, - Node\Stmt\Class_::class, + UseItem::class, + Class_::class, ]; } public function refactor(Node $node): ?int { - if ($node instanceof Node\UseItem) { + if ($node instanceof UseItem) { $name = $node->name->toString(); if ($name === 'Tempest\Core\HasContext' || $name === 'HasContext') { - $node->name = new Node\Name('Tempest\Core\ProvidesContext'); + $node->name = new Name('Tempest\Core\ProvidesContext'); } return null; } - if (! $node instanceof Node\Stmt\Class_) { + if (! $node instanceof Class_) { return null; } @@ -35,14 +38,14 @@ public function refactor(Node $node): ?int $implementsHasContext = array_find_key( array: $implements, - callback: static fn (Node\Name $name) => $name->toString() === 'Tempest\Core\HasContext' || $name->toString() === 'HasContext', + callback: static fn (Name $name) => $name->toString() === 'Tempest\Core\HasContext' || $name->toString() === 'HasContext', ); if ($implementsHasContext === null) { return null; } - $implements[$implementsHasContext] = new Node\Name('\Tempest\Core\ProvidesContext'); + $implements[$implementsHasContext] = new Name('\Tempest\Core\ProvidesContext'); $node->implements = $implements; return null; diff --git a/packages/upgrade/src/Tempest3/UpdateMapperFunctionImportsRector.php b/packages/upgrade/src/Tempest3/UpdateMapperFunctionImportsRector.php index 310bc19295..60c8b4bf67 100644 --- a/packages/upgrade/src/Tempest3/UpdateMapperFunctionImportsRector.php +++ b/packages/upgrade/src/Tempest3/UpdateMapperFunctionImportsRector.php @@ -3,6 +3,10 @@ namespace Tempest\Upgrade\Tempest3; use PhpParser\Node; +use PhpParser\Node\Expr\FuncCall; +use PhpParser\Node\Name; +use PhpParser\Node\Name\FullyQualified; +use PhpParser\Node\UseItem; use Rector\Rector\AbstractRector; final class UpdateMapperFunctionImportsRector extends AbstractRector @@ -10,36 +14,36 @@ final class UpdateMapperFunctionImportsRector extends AbstractRector public function getNodeTypes(): array { return [ - Node\UseItem::class, - Node\Expr\FuncCall::class, + UseItem::class, + FuncCall::class, ]; } public function refactor(Node $node): ?int { - if ($node instanceof Node\UseItem) { + if ($node instanceof UseItem) { if ($node->name->toString() === 'Tempest\map') { - $node->name = new Node\Name('Tempest\Mapper\map'); + $node->name = new Name('Tempest\Mapper\map'); } if ($node->name->toString() === 'Tempest\make') { - $node->name = new Node\Name('Tempest\Mapper\make'); + $node->name = new Name('Tempest\Mapper\make'); } return null; } - if ($node instanceof Node\Expr\FuncCall && $node->name instanceof Node\Name) { + if ($node instanceof FuncCall && $node->name instanceof Name) { $functionName = $node->name->toString(); if ($functionName === 'Tempest\map') { - $node->name = new Node\Name\FullyQualified('Tempest\Mapper\map'); + $node->name = new FullyQualified('Tempest\Mapper\map'); return null; } if ($functionName === 'Tempest\make') { - $node->name = new Node\Name\FullyQualified('Tempest\Mapper\make'); + $node->name = new FullyQualified('Tempest\Mapper\make'); return null; } diff --git a/packages/upgrade/src/Tempest3/UpdateReflectionFunctionImportsRector.php b/packages/upgrade/src/Tempest3/UpdateReflectionFunctionImportsRector.php index 1d12c45eac..7fa793c7c9 100644 --- a/packages/upgrade/src/Tempest3/UpdateReflectionFunctionImportsRector.php +++ b/packages/upgrade/src/Tempest3/UpdateReflectionFunctionImportsRector.php @@ -3,6 +3,10 @@ namespace Tempest\Upgrade\Tempest3; use PhpParser\Node; +use PhpParser\Node\Expr\FuncCall; +use PhpParser\Node\Name; +use PhpParser\Node\Name\FullyQualified; +use PhpParser\Node\UseItem; use Rector\Rector\AbstractRector; final class UpdateReflectionFunctionImportsRector extends AbstractRector @@ -10,26 +14,26 @@ final class UpdateReflectionFunctionImportsRector extends AbstractRector public function getNodeTypes(): array { return [ - Node\UseItem::class, - Node\Expr\FuncCall::class, + UseItem::class, + FuncCall::class, ]; } public function refactor(Node $node): ?int { - if ($node instanceof Node\UseItem) { + if ($node instanceof UseItem) { if ($node->name->toString() === 'Tempest\reflect') { - $node->name = new Node\Name('Tempest\Reflection\reflect'); + $node->name = new Name('Tempest\Reflection\reflect'); } return null; } - if ($node instanceof Node\Expr\FuncCall && $node->name instanceof Node\Name) { + if ($node instanceof FuncCall && $node->name instanceof Name) { $functionName = $node->name->toString(); if ($functionName === 'Tempest\reflect') { - $node->name = new Node\Name\FullyQualified('Tempest\Reflection\reflect'); + $node->name = new FullyQualified('Tempest\Reflection\reflect'); return null; } diff --git a/packages/upgrade/src/Tempest3/UpdateViewFunctionImportsRector.php b/packages/upgrade/src/Tempest3/UpdateViewFunctionImportsRector.php index fdef676f55..c01f1b383b 100644 --- a/packages/upgrade/src/Tempest3/UpdateViewFunctionImportsRector.php +++ b/packages/upgrade/src/Tempest3/UpdateViewFunctionImportsRector.php @@ -3,6 +3,10 @@ namespace Tempest\Upgrade\Tempest3; use PhpParser\Node; +use PhpParser\Node\Expr\FuncCall; +use PhpParser\Node\Name; +use PhpParser\Node\Name\FullyQualified; +use PhpParser\Node\UseItem; use Rector\Rector\AbstractRector; final class UpdateViewFunctionImportsRector extends AbstractRector @@ -10,26 +14,26 @@ final class UpdateViewFunctionImportsRector extends AbstractRector public function getNodeTypes(): array { return [ - Node\UseItem::class, - Node\Expr\FuncCall::class, + UseItem::class, + FuncCall::class, ]; } public function refactor(Node $node): ?int { - if ($node instanceof Node\UseItem) { + if ($node instanceof UseItem) { if ($node->name->toString() === 'Tempest\view') { - $node->name = new Node\Name('Tempest\View\view'); + $node->name = new Name('Tempest\View\view'); } return null; } - if ($node instanceof Node\Expr\FuncCall && $node->name instanceof Node\Name) { + if ($node instanceof FuncCall && $node->name instanceof Name) { $functionName = $node->name->toString(); if ($functionName === 'Tempest\view') { - $node->name = new Node\Name\FullyQualified('Tempest\View\view'); + $node->name = new FullyQualified('Tempest\View\view'); return null; } diff --git a/packages/upgrade/tests/RectorTester.php b/packages/upgrade/tests/RectorTester.php index b4925df5d0..f3aa25ed1b 100644 --- a/packages/upgrade/tests/RectorTester.php +++ b/packages/upgrade/tests/RectorTester.php @@ -12,6 +12,7 @@ final class RectorTester { private(set) string $fixturePath; + private(set) string $actual; public function __construct( diff --git a/packages/upgrade/tests/Tempest20/Tempest20RectorTest.php b/packages/upgrade/tests/Tempest20/Tempest20RectorTest.php index 774a100361..71df9adb79 100644 --- a/packages/upgrade/tests/Tempest20/Tempest20RectorTest.php +++ b/packages/upgrade/tests/Tempest20/Tempest20RectorTest.php @@ -23,7 +23,7 @@ public function test_migration_with_up_and_down(): void $this->rector ->runFixture(__DIR__ . '/Fixtures/MigrateUpAndDownMigration.input.php') ->assertContains('implements \Tempest\Database\MigratesUp, \Tempest\Database\MigratesDown') - ->assertContains('return new DropTableStatement(\'table\')') + ->assertContains("return new DropTableStatement('table')") ->assertNotContains('Tempest\Database\DatabaseMigration') ->assertContains('public function down(): QueryStatement'); } diff --git a/packages/validation/src/Rules/HasCount.php b/packages/validation/src/Rules/HasCount.php index 7f8d62bf0b..f22030918d 100644 --- a/packages/validation/src/Rules/HasCount.php +++ b/packages/validation/src/Rules/HasCount.php @@ -5,6 +5,7 @@ namespace Tempest\Validation\Rules; use Attribute; +use Countable; use InvalidArgumentException; use Tempest\Validation\HasTranslationVariables; use Tempest\Validation\Rule; @@ -26,7 +27,7 @@ public function __construct( public function isValid(mixed $value): bool { - if (! is_array($value) && ! $value instanceof \Countable) { + if (! is_array($value) && ! $value instanceof Countable) { return false; } diff --git a/packages/validation/src/Rules/HasDateTimeFormat.php b/packages/validation/src/Rules/HasDateTimeFormat.php index 6e53f12870..7f67b121e8 100644 --- a/packages/validation/src/Rules/HasDateTimeFormat.php +++ b/packages/validation/src/Rules/HasDateTimeFormat.php @@ -10,6 +10,7 @@ use Tempest\DateTime\FormatPattern; use Tempest\Validation\HasTranslationVariables; use Tempest\Validation\Rule; +use Throwable; /** * Validates that the value is a valid date string in a specified format. @@ -37,7 +38,7 @@ private function validateIcuFormat(string $value): bool { try { return $value === DateTime::fromPattern($value, $this->format)->format($this->format); - } catch (\Throwable) { + } catch (Throwable) { return false; } } diff --git a/packages/validation/src/Rules/IsBetweenDates.php b/packages/validation/src/Rules/IsBetweenDates.php index 7ba9a4d434..703d1f1198 100644 --- a/packages/validation/src/Rules/IsBetweenDates.php +++ b/packages/validation/src/Rules/IsBetweenDates.php @@ -19,6 +19,7 @@ final readonly class IsBetweenDates implements Rule, HasTranslationVariables { private DateTimeInterface $first; + private DateTimeInterface $second; public function __construct( diff --git a/packages/validation/src/Rules/IsFloat.php b/packages/validation/src/Rules/IsFloat.php index 27b0813c42..87714f44c5 100644 --- a/packages/validation/src/Rules/IsFloat.php +++ b/packages/validation/src/Rules/IsFloat.php @@ -24,7 +24,7 @@ public function isValid(mixed $value): bool return true; } - if ($value === null || $value === false || $value === '' || $value === []) { + if (in_array($value, [null, false, '', []], true)) { return false; } diff --git a/packages/validation/src/Rules/IsInteger.php b/packages/validation/src/Rules/IsInteger.php index 883647debb..237161ef79 100644 --- a/packages/validation/src/Rules/IsInteger.php +++ b/packages/validation/src/Rules/IsInteger.php @@ -24,7 +24,7 @@ public function isValid(mixed $value): bool return true; } - if ($value === null || $value === false || $value === '' || $value === []) { + if (in_array($value, [null, false, '', []], true)) { return false; } diff --git a/packages/validation/src/Rules/IsNumeric.php b/packages/validation/src/Rules/IsNumeric.php index bbb3adcd00..9090bb6053 100644 --- a/packages/validation/src/Rules/IsNumeric.php +++ b/packages/validation/src/Rules/IsNumeric.php @@ -19,6 +19,6 @@ public function isValid(mixed $value): bool return false; } - return boolval(preg_match('/^[0-9]+$/', $value)); + return boolval(preg_match('/^\d+$/', $value)); } } diff --git a/packages/validation/src/Rules/IsPassword.php b/packages/validation/src/Rules/IsPassword.php index 04447f0815..85f059fe68 100644 --- a/packages/validation/src/Rules/IsPassword.php +++ b/packages/validation/src/Rules/IsPassword.php @@ -48,11 +48,7 @@ public function isValid(mixed $value): bool return false; } - if ($this->symbols && ! preg_match('/\p{Z}|\p{S}|\p{P}/u', $value)) { - return false; - } - - return true; + return ! ($this->symbols && ! preg_match('/\p{Z}|\p{S}|\p{P}/u', $value)); } public function getTranslationVariables(): array diff --git a/packages/validation/src/Rules/IsTime.php b/packages/validation/src/Rules/IsTime.php index 3d41add976..86759024b8 100644 --- a/packages/validation/src/Rules/IsTime.php +++ b/packages/validation/src/Rules/IsTime.php @@ -25,10 +25,10 @@ public function isValid(mixed $value): bool } if ($this->twentyFourHour) { - return preg_match('/^([0-1][0-9]|2[0-3]):?[0-5][0-9]$|^(([0-1]?[0-9]|2[0-3]):[0-5][0-9])$/', $value) === 1; + return preg_match('/^([0-1]\d|2[0-3]):?[0-5]\d$|^(([0-1]?\d|2[0-3]):[0-5]\d)$/', $value) === 1; } - return preg_match('/^([0-1]?[0-9]):[0-5][0-9]\s([aApP].[mM].|[aApP][mM])$/', $value) === 1; + return preg_match('/^([0-1]?\d):[0-5]\d\s([aApP].[mM].|[aApP][mM])$/', $value) === 1; } public function getTranslationVariables(): array diff --git a/packages/validation/src/Rules/ValidateWith.php b/packages/validation/src/Rules/ValidateWith.php index 28a1c9ff4e..a56d690815 100644 --- a/packages/validation/src/Rules/ValidateWith.php +++ b/packages/validation/src/Rules/ValidateWith.php @@ -18,14 +18,10 @@ #[Attribute(Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)] final readonly class ValidateWith implements Rule { - private Closure $callback; - public function __construct( - Closure $callback, + private Closure $callback, ) { - $this->callback = $callback; - - $reflection = new ReflectionFunction($callback); + $reflection = new ReflectionFunction($this->callback); // Must be static if (! $reflection->isStatic()) { diff --git a/packages/validation/src/SkipValidation.php b/packages/validation/src/SkipValidation.php index dddf690fc0..0ae0fa7b16 100644 --- a/packages/validation/src/SkipValidation.php +++ b/packages/validation/src/SkipValidation.php @@ -7,6 +7,4 @@ use Attribute; #[Attribute(Attribute::TARGET_PROPERTY)] -final class SkipValidation -{ -} +final class SkipValidation {} diff --git a/packages/validation/src/Validator.php b/packages/validation/src/Validator.php index 7c692884f3..3ed45600ef 100644 --- a/packages/validation/src/Validator.php +++ b/packages/validation/src/Validator.php @@ -68,9 +68,7 @@ public function createValidationFailureException(array $failingRules, null|objec return new ValidationFailed( failingRules: $failingRules, subject: $subject, - errorMessages: Arr\map($failingRules, function (array $rules, string $field) { - return Arr\map($rules, fn (FailingRule $rule) => $this->getErrorMessage($rule, $field)); - }), + errorMessages: Arr\map($failingRules, fn (array $rules, string $field) => Arr\map($rules, fn (FailingRule $rule) => $this->getErrorMessage($rule, $field))), targetClass: $targetClass, ); } diff --git a/packages/validation/tests/Rules/IsJsonStringTest.php b/packages/validation/tests/Rules/IsJsonStringTest.php index 0003c143f4..dc94da5f03 100644 --- a/packages/validation/tests/Rules/IsJsonStringTest.php +++ b/packages/validation/tests/Rules/IsJsonStringTest.php @@ -37,7 +37,7 @@ public function test_it_allows_to_specify_flags(): void { // Not sure if there is a better way of asserting that a php function was called with a given argument $this->expectException(ValueError::class); - $rule = new IsJsonString(flags: 232312312); // we intentionally send something that is not valid + $rule = new IsJsonString(flags: 232_312_312); // we intentionally send something that is not valid $rule->isValid('{"test": "test"}'); } } diff --git a/packages/validation/tests/Rules/IsPasswordTest.php b/packages/validation/tests/Rules/IsPasswordTest.php index 09b306e651..964d5d84ae 100644 --- a/packages/validation/tests/Rules/IsPasswordTest.php +++ b/packages/validation/tests/Rules/IsPasswordTest.php @@ -23,8 +23,8 @@ public function test_defaults(): void public function test_invalid_input(): void { $rule = new IsPassword(); - $this->assertFalse($rule->isValid(123456789012)); - $this->assertFalse($rule->isValid([123456789012])); + $this->assertFalse($rule->isValid(123_456_789_012)); + $this->assertFalse($rule->isValid([123_456_789_012])); } public function test_minimum(): void diff --git a/packages/validation/tests/Rules/IsTimeTest.php b/packages/validation/tests/Rules/IsTimeTest.php index 9b0987e48d..673f3a4d64 100644 --- a/packages/validation/tests/Rules/IsTimeTest.php +++ b/packages/validation/tests/Rules/IsTimeTest.php @@ -5,6 +5,7 @@ namespace Tempest\Validation\Tests\Rules; use PHPUnit\Framework\TestCase; +use stdClass; use Tempest\Validation\Rules\IsTime; /** @@ -85,7 +86,7 @@ public function test_non_string_pregmatch_subject(): void $rule = new IsTime(twentyFourHour: true); $this->assertFalse($rule->isValid([])); - $this->assertFalse($rule->isValid(new \stdClass())); + $this->assertFalse($rule->isValid(new stdClass())); $this->assertFalse($rule->isValid(null)); } } diff --git a/packages/validation/tests/Rules/MatchesRegExTest.php b/packages/validation/tests/Rules/MatchesRegExTest.php index 06971c5dca..5752755e25 100644 --- a/packages/validation/tests/Rules/MatchesRegExTest.php +++ b/packages/validation/tests/Rules/MatchesRegExTest.php @@ -5,6 +5,7 @@ namespace Tempest\Validation\Tests\Rules; use PHPUnit\Framework\TestCase; +use stdClass; use Tempest\Validation\Rules\MatchesRegEx; /** @@ -26,12 +27,12 @@ public function test_regex_rule(): void public function test_non_imvalid_types(): void { - $rule = new MatchesRegEx('/^[0-9]+$/'); + $rule = new MatchesRegEx('/^\d+$/'); // Invalid types should return false, not a TypeError. $this->assertFalse($rule->isValid(false)); $this->assertFalse($rule->isValid([])); - $this->assertFalse($rule->isValid(new \stdClass())); + $this->assertFalse($rule->isValid(new stdClass())); $this->assertFalse($rule->isValid(null)); } } diff --git a/packages/validation/tests/Rules/ValidateWithTest.php b/packages/validation/tests/Rules/ValidateWithTest.php index 8e7b9996b4..371b3b2c93 100644 --- a/packages/validation/tests/Rules/ValidateWithTest.php +++ b/packages/validation/tests/Rules/ValidateWithTest.php @@ -4,6 +4,7 @@ namespace Tempest\Validation\Tests\Rules; +use InvalidArgumentException; use PHPUnit\Framework\TestCase; use ReflectionProperty; use Tempest\Validation\Rules\ValidateWith; @@ -45,14 +46,14 @@ public function test_non_string_value_fails(): void { $rule = new ValidateWith(static fn (mixed $value): bool => str_contains((string) $value, '@')); - $this->assertFalse($rule->isValid(12345)); + $this->assertFalse($rule->isValid(12_345)); $this->assertFalse($rule->isValid(null)); $this->assertFalse($rule->isValid(false)); } public function test_static_closure_required(): void { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); new ValidateWith(fn (mixed $value): bool => str_contains((string) $value, '@')); } diff --git a/packages/validation/tests/ValidatorTest.php b/packages/validation/tests/ValidatorTest.php index 6631364a90..e817df8937 100644 --- a/packages/validation/tests/ValidatorTest.php +++ b/packages/validation/tests/ValidatorTest.php @@ -51,18 +51,14 @@ public function test_validate_value(): void public function test_closure_fails_with_false_response(): void { - $failingRules = $this->validator->validateValue('a', function (mixed $_) { - return false; - }); + $failingRules = $this->validator->validateValue('a', fn (mixed $_) => false); $this->assertCount(1, $failingRules); } public function test_closure_fails_with_string_response(): void { - $failingRules = $this->validator->validateValue('a', function (mixed $_) { - return 'I expected b'; - }); + $failingRules = $this->validator->validateValue('a', fn (mixed $_) => 'I expected b'); $rule = $failingRules[0]->rule; @@ -74,9 +70,7 @@ public function test_closure_fails_with_string_response(): void public function test_closure_passes_with_null_response(): void { $validator = $this->validator; - $validator->validateValue('a', function (mixed $_) { - return null; - }); + $validator->validateValue('a', fn (mixed $_) => null); $this->expectNotToPerformAssertions(); } @@ -84,9 +78,7 @@ public function test_closure_passes_with_null_response(): void public function test_closure_passes_with_true_response(): void { $validator = $this->validator; - $validator->validateValue('a', function (mixed $_) { - return true; - }); + $validator->validateValue('a', fn (mixed $_) => true); $this->expectNotToPerformAssertions(); } @@ -95,17 +87,9 @@ public function test_closure_passes(): void { $validator = $this->validator; - $validator->validateValue('a', function (mixed $value) { - return $value === 'a'; - }); + $validator->validateValue('a', fn (mixed $value) => $value === 'a'); - $validator->validateValue('a', function (mixed $value) { - if ($value === 'a') { - return true; - } - - return false; - }); + $validator->validateValue('a', fn (mixed $value) => $value === 'a'); $this->expectNotToPerformAssertions(); } diff --git a/packages/view/src/Attributes/ExpressionAttribute.php b/packages/view/src/Attributes/ExpressionAttribute.php index 75b09d39f5..43f8b57d91 100644 --- a/packages/view/src/Attributes/ExpressionAttribute.php +++ b/packages/view/src/Attributes/ExpressionAttribute.php @@ -35,7 +35,7 @@ public function apply(Element $element): Element $element->setAttribute( ltrim($this->name, ':'), - sprintf('%s', $value), + $value, ); } else { $attributeName = ltrim($this->name, ':'); diff --git a/packages/view/src/Commands/ClearViewCacheCommand.php b/packages/view/src/Commands/ClearViewCacheCommand.php index e293687b09..c1ceb8c91e 100644 --- a/packages/view/src/Commands/ClearViewCacheCommand.php +++ b/packages/view/src/Commands/ClearViewCacheCommand.php @@ -10,7 +10,7 @@ use Tempest\Container\Container; use Tempest\View\ViewCache; -if (class_exists(\Tempest\Console\ConsoleCommand::class)) { +if (class_exists(ConsoleCommand::class)) { final readonly class ClearViewCacheCommand { use HasConsole; diff --git a/packages/view/src/Commands/MakeViewCommand.php b/packages/view/src/Commands/MakeViewCommand.php index ecb515cf66..a49cf41972 100644 --- a/packages/view/src/Commands/MakeViewCommand.php +++ b/packages/view/src/Commands/MakeViewCommand.php @@ -17,7 +17,7 @@ use function Tempest\Support\str; -if (class_exists(\Tempest\Console\ConsoleCommand::class)) { +if (class_exists(ConsoleCommand::class)) { final class MakeViewCommand { use PublishesFiles; @@ -82,7 +82,11 @@ private function getStubFileFromViewType(ViewType $viewType): StubFile default => throw new InvalidArgumentException(sprintf('The "%s" view type has no supported stub file.', $viewType->value)), }; } catch (InvalidArgumentException $invalidArgumentException) { - throw new FileGenerationFailedException(sprintf('Cannot retrieve stub file: %s', $invalidArgumentException->getMessage())); + throw new FileGenerationFailedException( + sprintf('Cannot retrieve stub file: %s', $invalidArgumentException->getMessage()), + $invalidArgumentException->getCode(), + $invalidArgumentException, + ); } } } diff --git a/packages/view/src/Components/x-component.view.php b/packages/view/src/Components/x-component.view.php index c35181f9d2..7847fd8c48 100644 --- a/packages/view/src/Components/x-component.view.php +++ b/packages/view/src/Components/x-component.view.php @@ -17,10 +17,10 @@ $content = $slots[Slot::DEFAULT]->content ?? ''; $template = sprintf(<<<'HTML' -<%s %s> -%s - -HTML, $is, $attributeString, $content, $is); + <%s %s> + %s + + HTML, $is, $attributeString, $content, $is); $data = $scopedVariables ?? $_data ?? []; $data = is_array($data) ? $data : []; diff --git a/packages/view/src/Components/x-form.view.php b/packages/view/src/Components/x-form.view.php index 95bd8ee2a4..c8f43f47a7 100644 --- a/packages/view/src/Components/x-form.view.php +++ b/packages/view/src/Components/x-form.view.php @@ -14,7 +14,7 @@ $method = $method->value; } -$needsSpoofing = Method::trySpoofingFrom($method) !== null; +$needsSpoofing = Method::trySpoofingFrom($method) instanceof Method; $formMethod = $needsSpoofing ? 'POST' : $method; ?> diff --git a/packages/view/src/Components/x-icon.view.php b/packages/view/src/Components/x-icon.view.php index f6bb76c746..8e1e46d474 100644 --- a/packages/view/src/Components/x-icon.view.php +++ b/packages/view/src/Components/x-icon.view.php @@ -24,7 +24,7 @@ fn (ImmutableString $s): ImmutableString => str(""), ) ->replace( - search: " width=\"1em\" height=\"1em\"", + search: ' width="1em" height="1em"', replace: '', ) ->when( @@ -54,7 +54,7 @@ fn (ImmutableString $s): ImmutableString => $s ->replace( search: 'toString(); diff --git a/packages/view/src/Elements/ElementFactory.php b/packages/view/src/Elements/ElementFactory.php index 2ee353519b..f656ede431 100644 --- a/packages/view/src/Elements/ElementFactory.php +++ b/packages/view/src/Elements/ElementFactory.php @@ -44,12 +44,7 @@ public function withIsHtml(bool $isHtml): self public function make(Token $token, Element $parent): ?Element { - if ( - $token->type === TokenType::OPEN_TAG_END - || $token->type === TokenType::ATTRIBUTE_NAME - || $token->type === TokenType::ATTRIBUTE_VALUE - || $token->type === TokenType::SELF_CLOSING_TAG_END - ) { + if (in_array($token->type, [TokenType::OPEN_TAG_END, TokenType::ATTRIBUTE_NAME, TokenType::ATTRIBUTE_VALUE, TokenType::SELF_CLOSING_TAG_END], true)) { return null; } diff --git a/packages/view/src/Elements/GenericElement.php b/packages/view/src/Elements/GenericElement.php index b0266a9b70..662fdd9d47 100644 --- a/packages/view/src/Elements/GenericElement.php +++ b/packages/view/src/Elements/GenericElement.php @@ -41,11 +41,7 @@ public function compile(): string $attributes = []; foreach ($this->getAttributes() as $name => $value) { - if ($value !== null && $value !== '') { - $attributes[] = $name . '="' . $value . '"'; - } else { - $attributes[] = $name; - } + $attributes[] = $value !== null && $value !== '' ? $name . '="' . $value . '"' : $name; } $attributes = implode(' ', [...$attributes, ...$this->rawAttributes]); @@ -58,9 +54,9 @@ public function compile(): string if (is_void_tag($this->tag)) { if ($this->isHtml) { return "<{$this->tag}{$attributes}>"; - } else { - return "<{$this->tag}{$attributes} />"; } + + return "<{$this->tag}{$attributes} />"; } return "<{$this->tag}{$attributes}>{$content}tag}>"; diff --git a/packages/view/src/Elements/IsElement.php b/packages/view/src/Elements/IsElement.php index 415566d216..ce501bb480 100644 --- a/packages/view/src/Elements/IsElement.php +++ b/packages/view/src/Elements/IsElement.php @@ -26,21 +26,19 @@ trait IsElement public function getAttributes(): array { - if ($this instanceof WrapsElement) { - $wrappingAttributes = $this->getWrappingElement()->getAttributes(); - } else { - $wrappingAttributes = []; - } + $wrappingAttributes = $this instanceof WrapsElement ? $this->getWrappingElement()->getAttributes() : []; $attributes = [...$this->attributes, ...$wrappingAttributes]; $tailingAttributes = []; foreach ($attributes as $name => $value) { - if ($name === ':foreach' || $name === ':if') { - unset($attributes[$name]); - $tailingAttributes[$name] = $value; + if ($name !== ':foreach' && $name !== ':if') { + continue; } + + unset($attributes[$name]); + $tailingAttributes[$name] = $value; } // Tailing attributes are reversed because they need to be applied in reverse order diff --git a/packages/view/src/Elements/PhpForeachElement.php b/packages/view/src/Elements/PhpForeachElement.php index ef85107db2..63da10c88c 100644 --- a/packages/view/src/Elements/PhpForeachElement.php +++ b/packages/view/src/Elements/PhpForeachElement.php @@ -27,7 +27,7 @@ public function getWrappingElement(): Element public function setElse(Element $element): self { - if ($this->else !== null) { + if ($this->else instanceof Element) { throw new ElementWasInvalid('There can only be one forelse element.'); } @@ -40,7 +40,7 @@ public function compile(): string { $foreachAttribute = $this->wrappingElement->consumeAttribute(':foreach'); - if ($viewComponent = $this->unwrap(ViewComponentElement::class)) { + if (($viewComponent = $this->unwrap(ViewComponentElement::class)) instanceof ViewComponentElement) { $name = trim(str($foreachAttribute)->explode('as')->last()); $viewComponent->addVariable($name); @@ -59,7 +59,7 @@ public function compile(): string $compiled, ); - if ($this->else !== null) { + if ($this->else instanceof Element) { $collectionName = str($foreachAttribute)->match('/^(?.*)\s+as/', 'match'); $this->else->consumeAttribute(':forelse'); diff --git a/packages/view/src/Elements/PhpIfElement.php b/packages/view/src/Elements/PhpIfElement.php index 6f40d221cf..55160f1c1b 100644 --- a/packages/view/src/Elements/PhpIfElement.php +++ b/packages/view/src/Elements/PhpIfElement.php @@ -35,7 +35,7 @@ public function addElseif(Element $element): self public function setElse(Element $element): self { - if ($this->else !== null) { + if ($this->else instanceof Element) { throw new ElementWasInvalid('There can only be one else element.'); } @@ -70,7 +70,7 @@ public function compile(): string ); } - if ($this->else !== null) { + if ($this->else instanceof Element) { $this->else->consumeAttribute(':else'); $compiled = sprintf( diff --git a/packages/view/src/Elements/RawElement.php b/packages/view/src/Elements/RawElement.php index cb071cea8e..800288b768 100644 --- a/packages/view/src/Elements/RawElement.php +++ b/packages/view/src/Elements/RawElement.php @@ -34,17 +34,9 @@ public function compile(): string foreach ($this->getAttributes() as $name => $value) { $name = str($name); - if ($name->startsWith(':')) { - $name = ':' . $name->kebab()->toString(); - } else { - $name = $name->kebab()->toString(); - } - - if ($value) { - $attributes[] = $name . '="' . $value . '"'; - } else { - $attributes[] = $name; - } + $name = $name->startsWith(':') ? ':' . $name->kebab()->toString() : $name->kebab()->toString(); + + $attributes[] = $value ? $name . '="' . $value . '"' : $name; } $attributes = implode(' ', [...$attributes, ...$this->rawAttributes]); diff --git a/packages/view/src/Elements/RootElement.php b/packages/view/src/Elements/RootElement.php index ec54f92a3f..e4fc209c5b 100644 --- a/packages/view/src/Elements/RootElement.php +++ b/packages/view/src/Elements/RootElement.php @@ -19,7 +19,7 @@ public function compile(): string $compiled[] = $element->compile(); } - return implode($compiled); + return implode('', $compiled); } public function getImports(): array @@ -29,9 +29,11 @@ public function getImports(): array $this->mergeImports($imports, $this->inheritedImports); foreach ($this->children as $child) { - if ($child instanceof PhpElement) { - $this->mergeImports($imports, $child->getImports()); + if (! $child instanceof PhpElement) { + continue; } + + $this->mergeImports($imports, $child->getImports()); } return array_values($imports); diff --git a/packages/view/src/Elements/TextElement.php b/packages/view/src/Elements/TextElement.php index 41db6c5902..361028c4ea 100644 --- a/packages/view/src/Elements/TextElement.php +++ b/packages/view/src/Elements/TextElement.php @@ -22,16 +22,12 @@ public function compile(): string // Render {{ ->replaceRegex( regex: '/{{(?.*?)}}/', - replace: function (array $matches): string { - return sprintf('escape(%s); ?>', $matches['match']); - }, + replace: fn (array $matches): string => sprintf('escape(%s); ?>', $matches['match']), ) // Render {!! ->replaceRegex( regex: '/{!!(?.*?)!!}/', - replace: function (array $matches): string { - return sprintf('', $matches['match']); - }, + replace: fn (array $matches): string => sprintf('', $matches['match']), ) ->toString(); } diff --git a/packages/view/src/Elements/ViewComponentElement.php b/packages/view/src/Elements/ViewComponentElement.php index 4f42d06271..d4bf9180be 100644 --- a/packages/view/src/Elements/ViewComponentElement.php +++ b/packages/view/src/Elements/ViewComponentElement.php @@ -255,6 +255,7 @@ private function applyFallthroughAttribute(ImmutableArray $attributes, string $n if ($hasDataAttribute) { $attributes[$name]->append(' ' . $this->dataAttributes[$name]); } + if ($hasExpressionAttribute) { $attributes[$name]->append(sprintf(' ', $name)); } @@ -283,14 +284,16 @@ public function getImports(): array { $imports = []; - if ($this->parent) { + if ($this->parent instanceof Element) { $imports = [...$imports, ...$this->parent->getImports()]; } foreach ($this->getChildren() as $child) { - if ($child instanceof PhpElement) { - $imports = [...$imports, ...$child->getImports()]; + if (! $child instanceof PhpElement) { + continue; } + + $imports = [...$imports, ...$child->getImports()]; } return $imports; diff --git a/packages/view/src/Exceptions/ViewCompilationFailed.php b/packages/view/src/Exceptions/ViewCompilationFailed.php index 0b5273e5b4..2b6e94782b 100644 --- a/packages/view/src/Exceptions/ViewCompilationFailed.php +++ b/packages/view/src/Exceptions/ViewCompilationFailed.php @@ -18,7 +18,7 @@ public function __construct( private(set) readonly ?int $sourceLine = null, ) { parent::__construct( - message: sprintf($previous->getMessage()), + message: $previous->getMessage(), previous: $previous, ); diff --git a/packages/view/src/Exceptions/XmlDeclarationCouldNotBeParsed.php b/packages/view/src/Exceptions/XmlDeclarationCouldNotBeParsed.php index bafa5a6937..b61502ec88 100644 --- a/packages/view/src/Exceptions/XmlDeclarationCouldNotBeParsed.php +++ b/packages/view/src/Exceptions/XmlDeclarationCouldNotBeParsed.php @@ -10,6 +10,6 @@ final class XmlDeclarationCouldNotBeParsed extends Exception { public function __construct() { - parent::__construct('Cannot compile views with XML declarations when PHP\'s `short_open_tag` is enabled.'); + parent::__construct("Cannot compile views with XML declarations when PHP's `short_open_tag` is enabled."); } } diff --git a/packages/view/src/Export/ExportableViewObject.php b/packages/view/src/Export/ExportableViewObject.php index c05f647745..4be43a25a0 100644 --- a/packages/view/src/Export/ExportableViewObject.php +++ b/packages/view/src/Export/ExportableViewObject.php @@ -6,9 +6,7 @@ interface ExportableViewObject { - public ImmutableArray $exportData { - get; - } + public ImmutableArray $exportData { get; } public static function restore(mixed ...$data): self; } diff --git a/packages/view/src/Initializers/ViewCacheInitializer.php b/packages/view/src/Initializers/ViewCacheInitializer.php index 14befdca9b..f1e3c888cb 100644 --- a/packages/view/src/Initializers/ViewCacheInitializer.php +++ b/packages/view/src/Initializers/ViewCacheInitializer.php @@ -15,11 +15,9 @@ final class ViewCacheInitializer implements Initializer #[Singleton] public function initialize(Container $container): ViewCache { - $viewCache = new ViewCache( + return new ViewCache( enabled: $this->shouldCacheBeEnabled(), ); - - return $viewCache; } private function shouldCacheBeEnabled(): bool diff --git a/packages/view/src/Parser/TempestViewCompiler.php b/packages/view/src/Parser/TempestViewCompiler.php index 0a7b21d70d..41dee82357 100644 --- a/packages/view/src/Parser/TempestViewCompiler.php +++ b/packages/view/src/Parser/TempestViewCompiler.php @@ -172,11 +172,7 @@ private function applyAttributes(Element $parentElement): Element foreach ($childElement->getAttributes() as $name => $value) { // TODO: possibly refactor attribute construction to ElementFactory? - if ($value instanceof Attribute) { - $attribute = $value; - } else { - $attribute = $this->attributeFactory->make($name); - } + $attribute = $value instanceof Attribute ? $value : $this->attributeFactory->make($name); $childElement = $attribute->apply($childElement); @@ -210,11 +206,11 @@ public function compileElement(Element $rootElement): string $sourcePath = $sourceLocation['sourcePath']; if ($sourcePath !== null) { - $compiled[] = self::sourcePathMarker($sourcePath); + $compiled[] = $this->sourcePathMarker($sourcePath); } } - $compiled[] = self::sourceLineMarker($sourceLocation['sourceLine']); + $compiled[] = $this->sourceLineMarker($sourceLocation['sourceLine']); } $compiled[] = $element->compile(); @@ -225,12 +221,12 @@ public function compileElement(Element $rootElement): string ->toString(); } - private static function sourcePathMarker(string $sourcePath): string + private function sourcePathMarker(string $sourcePath): string { return sprintf('', self::SOURCE_PATH_MARKER, base64_encode($sourcePath)); } - private static function sourceLineMarker(int $sourceLine): string + private function sourceLineMarker(int $sourceLine): string { return sprintf('', self::SOURCE_LINE_MARKER, $sourceLine); } @@ -348,8 +344,11 @@ private function extractSourceMap(string $compiled, ?string $sourcePath): array $compiledLine++; $cleanedLines[] = $line; + if ($sourceLine === null) { + continue; + } - if ($sourceLine === null || $currentSourcePath === null) { + if ($currentSourcePath === null) { continue; } diff --git a/packages/view/src/Parser/TempestViewLexer.php b/packages/view/src/Parser/TempestViewLexer.php index 1f5c8931d1..36750baaec 100644 --- a/packages/view/src/Parser/TempestViewLexer.php +++ b/packages/view/src/Parser/TempestViewLexer.php @@ -148,8 +148,8 @@ private function lexTag(): array ); if ($hasValue) { - $quote = $this->seek() === '\'' - ? '\'' + $quote = $this->seek() === "'" + ? "'" : '"'; $attributeValueLine = $this->line; diff --git a/packages/view/src/Parser/TempestViewParser.php b/packages/view/src/Parser/TempestViewParser.php index 77309107bc..7c4402ca3c 100644 --- a/packages/view/src/Parser/TempestViewParser.php +++ b/packages/view/src/Parser/TempestViewParser.php @@ -29,7 +29,7 @@ public function parse(): TempestViewAst $withinTag = false; foreach ($this->tokens as $token) { - if ($this->currentScope === null) { + if (! $this->currentScope instanceof Token) { $ast->add($token); } diff --git a/packages/view/src/Renderers/TempestViewRenderer.php b/packages/view/src/Renderers/TempestViewRenderer.php index 1b2f3e6042..3fc747beab 100644 --- a/packages/view/src/Renderers/TempestViewRenderer.php +++ b/packages/view/src/Renderers/TempestViewRenderer.php @@ -12,6 +12,7 @@ use Tempest\Support\Filesystem; use Tempest\Support\Html\HtmlString; use Tempest\View\Attributes\AttributeFactory; +use Tempest\View\CompiledView; use Tempest\View\Elements\ElementFactory; use Tempest\View\Exceptions\ViewCompilationFailed; use Tempest\View\Exceptions\ViewVariableWasReserved; @@ -93,7 +94,7 @@ public function render(string|View $view): string }, ); - if ($compiledView !== null) { + if ($compiledView instanceof CompiledView) { $this->viewCache->saveSourceMap($path, $compiledView->sourcePath, $compiledView->lineMap); } @@ -111,7 +112,7 @@ public function includeViewComponent(string $path): Closure private function processView(View $view): View { foreach ($this->viewConfig->viewProcessors as $viewProcessorClass) { - if ($this->container) { + if ($this->container instanceof Container) { /** @var \Tempest\View\ViewProcessor $viewProcessor */ $viewProcessor = $this->container->get($viewProcessorClass); } else { @@ -226,8 +227,11 @@ private function resolveSourceLocationFromThrowable(Throwable $throwable, string foreach ($throwable->getTrace() as $frame) { $framePath = $frame['file'] ?? null; $frameLine = $frame['line'] ?? null; + if (! is_string($framePath)) { + continue; + } - if (! is_string($framePath) || ! is_int($frameLine)) { + if (! is_int($frameLine)) { continue; } @@ -397,7 +401,11 @@ private function closestLineToFallback(array $lines, int $fallbackLine): int private function resolveSourceLine(int $compiledLine, ?string $defaultSourcePath, array $lineMap): ?array { foreach ($lineMap as $entry) { - if ($compiledLine < $entry['compiledStartLine'] || $compiledLine > $entry['compiledEndLine']) { + if ($compiledLine < $entry['compiledStartLine']) { + continue; + } + + if ($compiledLine > $entry['compiledEndLine']) { continue; } diff --git a/packages/view/src/ShouldBeRemoved.php b/packages/view/src/ShouldBeRemoved.php index 017adba67b..318373f378 100644 --- a/packages/view/src/ShouldBeRemoved.php +++ b/packages/view/src/ShouldBeRemoved.php @@ -2,6 +2,4 @@ namespace Tempest\View; -interface ShouldBeRemoved -{ -} +interface ShouldBeRemoved {} diff --git a/packages/view/src/View.php b/packages/view/src/View.php index 0f9695dc07..9a585116d4 100644 --- a/packages/view/src/View.php +++ b/packages/view/src/View.php @@ -6,17 +6,11 @@ interface View { - public string $path { - get; - } + public string $path { get; } - public ?string $relativeRootPath { - get; - } + public ?string $relativeRootPath { get; } - public array $data { - get; - } + public array $data { get; } public function get(string $key): mixed; diff --git a/packages/view/src/WithToken.php b/packages/view/src/WithToken.php index 23e4fe2ab8..20922797eb 100644 --- a/packages/view/src/WithToken.php +++ b/packages/view/src/WithToken.php @@ -8,7 +8,5 @@ interface WithToken { - public Token $token { - get; - } + public Token $token { get; } } diff --git a/packages/view/src/functions.php b/packages/view/src/functions.php index 49c43d5f08..ce34bc3fd5 100644 --- a/packages/view/src/functions.php +++ b/packages/view/src/functions.php @@ -4,9 +4,6 @@ namespace Tempest\View; -use Tempest\View\GenericView; -use Tempest\View\View; - /** * Returns a {@see View} instance for the specified `$path`. */ diff --git a/packages/view/tests/FallthroughAttributesTest.php b/packages/view/tests/FallthroughAttributesTest.php index 89a6f84751..d6670dec6f 100644 --- a/packages/view/tests/FallthroughAttributesTest.php +++ b/packages/view/tests/FallthroughAttributesTest.php @@ -29,10 +29,10 @@ public function render(): void ); $this->assertEquals(str_replace([' ', PHP_EOL], '', <<<'HTML' -
-
-
-
- HTML), str_replace([' ', PHP_EOL], '', $html)); +
+
+
+
+ HTML), str_replace([' ', PHP_EOL], '', $html)); } } diff --git a/packages/view/tests/StandaloneViewRendererTest.php b/packages/view/tests/StandaloneViewRendererTest.php index 0a8ab79105..6630e9d211 100644 --- a/packages/view/tests/StandaloneViewRendererTest.php +++ b/packages/view/tests/StandaloneViewRendererTest.php @@ -33,10 +33,10 @@ public function test_render(): void ); $this->assertSnippetsMatch(<<<'HTML' -
- Hi -
- HTML, $html); +
+ Hi +
+ HTML, $html); } public function test_invalid_view_component_paths(): void @@ -86,10 +86,10 @@ public function test_with_cache_enabled(): void ); $this->assertSnippetsMatch(<<<'HTML' - - Hi - - HTML, $html); + + Hi + + HTML, $html); } public function test_with_cache_disabled(): void @@ -103,10 +103,10 @@ public function test_with_cache_disabled(): void ); $this->assertSnippetsMatch(<<<'HTML' - - Hi - - HTML, $html); + + Hi + + HTML, $html); } public function test_xml_declaration_with_short_open_tag(): void diff --git a/packages/view/tests/TempestViewLexerTest.php b/packages/view/tests/TempestViewLexerTest.php index 0ba62e2882..335d580695 100644 --- a/packages/view/tests/TempestViewLexerTest.php +++ b/packages/view/tests/TempestViewLexerTest.php @@ -14,8 +14,8 @@ final class TempestViewLexerTest extends TestCase public function test_lexer(): void { $html = <<hello - HTML; + hello + HTML; $tokens = new TempestViewLexer($html)->lex(); @@ -144,15 +144,15 @@ public function test_closing_tag(string $tag): void public function test_multiline_attributes(): void { $html = <<<'HTML' -
+
-
- HTML; +
+ HTML; $tokens = new TempestViewLexer($html)->lex(); @@ -183,8 +183,8 @@ class=', TokenType::ATTRIBUTE_NAME), public function test_whitespace(): void { $html = <<<'HTML' -

Test Test

- HTML; +

Test Test

+ HTML; $tokens = new TempestViewLexer($html)->lex(); @@ -210,8 +210,8 @@ public function test_whitespace(): void public function test_lexer_with_falsy_values(): void { $html = <<<'HTML' - a0a - HTML; + a0a + HTML; $tokens = new TempestViewLexer($html)->lex(); @@ -245,8 +245,8 @@ public function test_lexer_attribute_values(): void public function test_php_within_tag(): void { $html = <<<'HTML' -
class="foo" >
- HTML; +
class="foo" >
+ HTML; $tokens = new TempestViewLexer($html)->lex(); @@ -267,8 +267,8 @@ public function test_php_within_tag(): void public function test_doctype(): void { $html = <<<'HTML' - - HTML; + + HTML; $tokens = new TempestViewLexer($html)->lex(); @@ -283,8 +283,8 @@ public function test_doctype(): void ); $html = <<<'HTML' - - HTML; + + HTML; $tokens = new TempestViewLexer($html)->lex(); @@ -343,8 +343,8 @@ public function test_unclosed_comment_tag(): void public function test_cdata(): void { $tokens = new TempestViewLexer(<<<'RSS' - <![CDATA[ {{ $post['title'] }} ]]> - RSS)->lex(); + <![CDATA[ {{ $post['title'] }} ]]> + RSS)->lex(); $this->assertTokens( expected: [ @@ -362,8 +362,8 @@ public function test_cdata(): void public function test_xml(): void { $tokens = new TempestViewLexer(<<<'XML' - - XML)->lex(); + + XML)->lex(); $this->assertTokens( expected: [ @@ -376,8 +376,8 @@ public function test_xml(): void public function test_single_quote_attributes(): void { $html = << - HTML; +
+ HTML; $tokens = new TempestViewLexer($html)->lex(); @@ -385,7 +385,7 @@ public function test_single_quote_attributes(): void expected: [ new Token('', TokenType::OPEN_TAG_END), new Token('', TokenType::CLOSING_TAG), ], diff --git a/packages/view/tests/TempestViewParserTest.php b/packages/view/tests/TempestViewParserTest.php index c38135f419..0b1cff5e1f 100644 --- a/packages/view/tests/TempestViewParserTest.php +++ b/packages/view/tests/TempestViewParserTest.php @@ -34,8 +34,8 @@ public function test_parser(): void $parsed = new TempestViewParser($tokens)->parse(); $this->assertSame(<<<'HTML' - hello - HTML, $parsed->compile()); + hello + HTML, $parsed->compile()); } public function test_parse_self_closing_tag_with_attributes(): void @@ -52,8 +52,8 @@ public function test_parse_self_closing_tag_with_attributes(): void $parsed = new TempestViewParser($tokens)->parse(); $this->assertSame(<<<'HTML' - - HTML, $parsed->compile()); + + HTML, $parsed->compile()); } public function test_self_closing_tags_with_attributes(): void @@ -63,8 +63,8 @@ public function test_self_closing_tags_with_attributes(): void $ast = new TempestViewParser($tokens)->parse(); $this->assertSame(<<<'HTML' - - HTML, $ast->compile()); + + HTML, $ast->compile()); } public function test_invalid_closing_tag(): void @@ -79,19 +79,19 @@ public function test_invalid_closing_tag(): void public function test_invalid_closing_tag_ignores_commented_out_code(): void { $tokens = new TempestViewLexer(<< - - - HTML)->lex(); +

+ +

+ HTML)->lex(); $compiled = new TempestViewParser($tokens)->parse()->compile(); $this->assertSame(<< - - - HTML, $compiled); +

+ +

+ HTML, $compiled); } public function test_doctype(): void @@ -106,15 +106,15 @@ public function test_doctype(): void $parsed = new TempestViewParser($tokens)->parse(); $this->assertSame(<<<'HTML' - - HTML, $parsed->compile()); + + HTML, $parsed->compile()); } public function test_void_tags(): void { $html = <<<'HTML' -
- HTML; +
+ HTML; $tokens = new TempestViewLexer($html)->lex(); diff --git a/packages/vite/src/Exceptions/EntrypointNotFoundException.php b/packages/vite/src/Exceptions/EntrypointNotFoundException.php index 980fc94644..f81400d091 100644 --- a/packages/vite/src/Exceptions/EntrypointNotFoundException.php +++ b/packages/vite/src/Exceptions/EntrypointNotFoundException.php @@ -4,6 +4,4 @@ namespace Tempest\Vite\Exceptions; -interface EntrypointNotFoundException extends ViteException -{ -} +interface EntrypointNotFoundException extends ViteException {} diff --git a/packages/vite/src/Exceptions/ViteException.php b/packages/vite/src/Exceptions/ViteException.php index e65746b26d..4d176327d4 100644 --- a/packages/vite/src/Exceptions/ViteException.php +++ b/packages/vite/src/Exceptions/ViteException.php @@ -4,6 +4,4 @@ namespace Tempest\Vite\Exceptions; -interface ViteException -{ -} +interface ViteException {} diff --git a/packages/vite/src/Installer/ViteInstaller.php b/packages/vite/src/Installer/ViteInstaller.php index 4c428a5cd4..35eef9dc0f 100644 --- a/packages/vite/src/Installer/ViteInstaller.php +++ b/packages/vite/src/Installer/ViteInstaller.php @@ -5,6 +5,7 @@ namespace Tempest\Vite\Installer; use Tempest\Console\Input\ConsoleArgumentBag; +use Tempest\Console\Input\ConsoleInputArgument; use Tempest\Core\Installer; use Tempest\Core\PublishesFiles; use Tempest\Support\JavaScript\DependencyInstaller; @@ -31,7 +32,7 @@ private function shouldInstallTailwind(): bool { $argument = $this->consoleArgumentBag->get('tailwindcss'); - if ($argument === null || ! is_bool($argument->value)) { + if (! $argument instanceof ConsoleInputArgument || ! is_bool($argument->value)) { return $this->console->confirm('Install Tailwind CSS as well?', default: true); } diff --git a/packages/vite/src/Manifest/Chunk.php b/packages/vite/src/Manifest/Chunk.php index 9815fc41ef..fc8515d842 100644 --- a/packages/vite/src/Manifest/Chunk.php +++ b/packages/vite/src/Manifest/Chunk.php @@ -25,7 +25,7 @@ public static function fromArray(array $manifestEntry): static $isEntry = $manifestEntry['isEntry'] ?? false; $isLegacyEntry = str_contains($file, '-legacy'); - return new static( + return new self( file: $file, src: $manifestEntry['src'] ?? null, isEntry: $isEntry, diff --git a/packages/vite/src/TagsResolver/DevelopmentTagsResolver.php b/packages/vite/src/TagsResolver/DevelopmentTagsResolver.php index 9e86e52d10..ab8b83a1c3 100644 --- a/packages/vite/src/TagsResolver/DevelopmentTagsResolver.php +++ b/packages/vite/src/TagsResolver/DevelopmentTagsResolver.php @@ -71,13 +71,13 @@ private function fileToAssetPath(string $file): string private function createReactRefreshTag(): string { return << - import RefreshRuntime from '{$this->bridgeFile->url}/@react-refresh'; - RefreshRuntime.injectIntoGlobalHook(window); - window.\$RefreshReg$ = () => {}; - window.\$RefreshSig$ = () => (type) => type; - window.__vite_plugin_react_preamble_installed__ = true; - - HTML; + + HTML; } } diff --git a/packages/vite/src/TagsResolver/ManifestTagsResolver.php b/packages/vite/src/TagsResolver/ManifestTagsResolver.php index 17da4e616d..5fe0f004f6 100644 --- a/packages/vite/src/TagsResolver/ManifestTagsResolver.php +++ b/packages/vite/src/TagsResolver/ManifestTagsResolver.php @@ -179,11 +179,11 @@ private function resolvePrefetchingScript(Chunk $chunk): ?string }; $assets = array_values(array_map( - callback: fn (array $asset) => array_map('strval', $asset), + callback: fn (array $asset) => array_map(strval(...), $asset), array: array_unique($findPrefetchableAssets($chunk), flags: SORT_REGULAR), )); - if (count($assets) === 0) { + if ($assets === []) { return null; } @@ -191,48 +191,48 @@ private function resolvePrefetchingScript(Chunk $chunk): ?string $script = match ($this->viteConfig->prefetching->strategy) { PrefetchStrategy::AGGRESSIVE => <<viteConfig->prefetching->prefetchEvent}', () => window.setTimeout(() => { - function makeLink(asset) { - const link = document.createElement('link') - Object.keys(asset).forEach((attribute) => link.setAttribute(attribute, asset[attribute])) - return link - } + window.addEventListener('{$this->viteConfig->prefetching->prefetchEvent}', () => window.setTimeout(() => { + function makeLink(asset) { + const link = document.createElement('link') + Object.keys(asset).forEach((attribute) => link.setAttribute(attribute, asset[attribute])) + return link + } - const fragment = new DocumentFragment(); - {$assets}.forEach((asset) => fragment.append(makeLink(asset))) - document.head.append(fragment) - })) - JS, + const fragment = new DocumentFragment(); + {$assets}.forEach((asset) => fragment.append(makeLink(asset))) + document.head.append(fragment) + })) + JS, PrefetchStrategy::WATERFALL => <<viteConfig->prefetching->prefetchEvent}', () => { - function makeLink(asset) { - const link = document.createElement('link') - Object.entries(asset).forEach(([key, value]) => link.setAttribute(key, value)) - return link - } + window.addEventListener('{$this->viteConfig->prefetching->prefetchEvent}', () => { + function makeLink(asset) { + const link = document.createElement('link') + Object.entries(asset).forEach(([key, value]) => link.setAttribute(key, value)) + return link + } - function loadNext(assets, count) { - if (!assets.length) return + function loadNext(assets, count) { + if (!assets.length) return - const fragment = new DocumentFragment() - const limit = Math.min(count, assets.length) + const fragment = new DocumentFragment() + const limit = Math.min(count, assets.length) - for (let i = 0; i < limit; i++) { - const link = makeLink(assets.shift()) - fragment.append(link) + for (let i = 0; i < limit; i++) { + const link = makeLink(assets.shift()) + fragment.append(link) - if (assets.length) { - link.onload = () => loadNext(assets, 1) - link.onerror = () => loadNext(assets, 1) + if (assets.length) { + link.onload = () => loadNext(assets, 1) + link.onerror = () => loadNext(assets, 1) + } } - } - document.head.append(fragment) - } + document.head.append(fragment) + } - setTimeout(() => loadNext({$assets}, {$this->viteConfig->prefetching->concurrent})) - }) - JS, + setTimeout(() => loadNext({$assets}, {$this->viteConfig->prefetching->concurrent})) + }) + JS, PrefetchStrategy::NONE => '', }; diff --git a/packages/vite/src/Vite.php b/packages/vite/src/Vite.php index fe21d7a39b..2d15d94a3c 100644 --- a/packages/vite/src/Vite.php +++ b/packages/vite/src/Vite.php @@ -58,7 +58,7 @@ public function getTags(?array $entrypoints = null): array */ public function clearManifestCache(): self { - static::$manifest = null; + self::$manifest = null; return $this; } @@ -68,7 +68,7 @@ public function clearManifestCache(): self */ public function clearBridgeCache(): self { - static::$bridgeFile = null; + self::$bridgeFile = null; return $this; } @@ -94,15 +94,15 @@ private function getTagsResolver(): TagsResolver private function getManifest(): Manifest { - if (static::$manifest !== null) { - return static::$manifest; + if (self::$manifest instanceof Manifest) { + return self::$manifest; } if (! is_file($path = root_path('public', $this->viteConfig->buildDirectory, $this->viteConfig->manifest))) { throw new ManifestWasNotFound($path); } - return static::$manifest = Manifest::fromArray(Json\decode( + return self::$manifest = Manifest::fromArray(Json\decode( Filesystem\read_file($path), )); } @@ -113,11 +113,7 @@ private function shouldUseManifest(): bool return false; } - if ($this->isDevelopmentServerRunning()) { - return false; - } - - return true; + return ! $this->isDevelopmentServerRunning(); } private function isDevelopmentServerRunning(): bool @@ -127,8 +123,8 @@ private function isDevelopmentServerRunning(): bool private function getBridgeFile(): ViteBridgeFile { - if (static::$bridgeFile !== null) { - return static::$bridgeFile; + if (self::$bridgeFile instanceof ViteBridgeFile) { + return self::$bridgeFile; } if (! $this->isDevelopmentServerRunning()) { @@ -138,7 +134,7 @@ private function getBridgeFile(): ViteBridgeFile $file = Filesystem\read_file($this->getBridgeFilePath()); $content = arr(Json\decode($file)); - return static::$bridgeFile = new ViteBridgeFile( + return self::$bridgeFile = new ViteBridgeFile( url: $content->get('url'), needsReactRefresh: $content->get('needsReactRefresh', default: false), ); diff --git a/packages/vite/src/ViteDiscovery.php b/packages/vite/src/ViteDiscovery.php index ffbde22b3f..4ab4d0ed2c 100644 --- a/packages/vite/src/ViteDiscovery.php +++ b/packages/vite/src/ViteDiscovery.php @@ -9,7 +9,6 @@ use Tempest\Discovery\DiscoveryLocation; use Tempest\Discovery\IsDiscovery; use Tempest\Reflection\ClassReflector; -use Tempest\Vite\ViteConfig; use function Tempest\Support\str; diff --git a/packages/vite/src/functions.php b/packages/vite/src/functions.php index b217c05043..217fb0e4df 100644 --- a/packages/vite/src/functions.php +++ b/packages/vite/src/functions.php @@ -4,8 +4,6 @@ namespace Tempest\Vite; -use Tempest\Vite\Vite; - use function Tempest\Container\get; /** diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 2d624b923b..bb0b91c2b4 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -9,10 +9,6 @@ parameters: identifier: method.templateTypeNotInParameter paths: - packages/database/src/functions.php - - - identifier: return.type - paths: - - packages/database/src/functions.php - identifier: return.unresolvableType paths: diff --git a/rector.php b/rector.php index b511c8c6c9..00becf98dd 100644 --- a/rector.php +++ b/rector.php @@ -2,32 +2,30 @@ declare(strict_types=1); -use Rector\Arguments\Rector\ClassMethod\ArgumentAdderRector; use Rector\Caching\ValueObject\Storage\FileCacheStorage; +use Rector\CodeQuality\Rector\Isset_\IssetOnPropertyObjectToPropertyExistsRector; +use Rector\CodingStyle\Rector\Catch_\CatchExceptionNameMatchingTypeRector; use Rector\CodingStyle\Rector\Encapsed\EncapsedStringsToSprintfRector; use Rector\Config\RectorConfig; -use Rector\DeadCode\Rector\PropertyProperty\RemoveNullPropertyInitializationRector; +use Rector\EarlyReturn\Rector\Return_\ReturnBinaryOrToEarlyReturnRector; +use Rector\Php55\Rector\String_\StringClassNameToClassConstantRector; use Rector\Php70\Rector\StaticCall\StaticCallOnNonStaticToInstanceCallRector; -use Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector; use Rector\Php74\Rector\Property\RestoreDefaultNullToNullableTypePropertyRector; use Rector\Php81\Rector\Array_\ArrayToFirstClassCallableRector; use Rector\Php81\Rector\FuncCall\NullToStrictStringFuncCallArgRector; use Rector\Php81\Rector\Property\ReadOnlyPropertyRector; -use Rector\Php82\Rector\Class_\ReadOnlyClassRector; use Rector\Php82\Rector\Param\AddSensitiveParameterAttributeRector; use Rector\Php83\Rector\ClassMethod\AddOverrideAttributeToOverriddenMethodsRector; -use Rector\Php84\Rector\Param\ExplicitNullableParamTypeRector; +use Rector\Php85\Rector\FuncCall\ArrayKeyExistsNullToEmptyStringRector; use Rector\Privatization\Rector\ClassMethod\PrivatizeFinalClassMethodRector; -use Rector\TypeDeclaration\Rector\ArrowFunction\AddArrowFunctionReturnTypeRector; -use Rector\TypeDeclaration\Rector\ClassMethod\NarrowObjectReturnTypeRector; -use Rector\TypeDeclaration\Rector\ClassMethod\ReturnNeverTypeRector; -use Rector\TypeDeclaration\Rector\Empty_\EmptyOnNullableObjectToInstanceOfRector; +use Tempest\Rector\ImportClassNamesRector; return RectorConfig::configure() ->withCache('./.cache/rector', FileCacheStorage::class) ->withPaths([ __DIR__ . '/src', __DIR__ . '/tests', + __DIR__ . '/packages', ]) ->withConfiguredRule(AddSensitiveParameterAttributeRector::class, [ 'sensitive_parameters' => [ @@ -35,37 +33,38 @@ 'secret', ], ]) - ->withRules([ - ExplicitNullableParamTypeRector::class, - ]) ->withSkip([ + '*.stub.php', + '*.input.php', + '*.expected.php', + '*/Fixtures/*', + __DIR__ . '/packages/intl/bin/plural-rules.php', AddOverrideAttributeToOverriddenMethodsRector::class, - ArgumentAdderRector::class, - ClosureToArrowFunctionRector::class, - EmptyOnNullableObjectToInstanceOfRector::class, ArrayToFirstClassCallableRector::class, NullToStrictStringFuncCallArgRector::class, - ReadOnlyClassRector::class, ReadOnlyPropertyRector::class, - RemoveNullPropertyInitializationRector::class, AddSensitiveParameterAttributeRector::class, RestoreDefaultNullToNullableTypePropertyRector::class, - ReturnNeverTypeRector::class, StaticCallOnNonStaticToInstanceCallRector::class, EncapsedStringsToSprintfRector::class, - AddArrowFunctionReturnTypeRector::class, PrivatizeFinalClassMethodRector::class, - NarrowObjectReturnTypeRector::class, + IssetOnPropertyObjectToPropertyExistsRector::class, + CatchExceptionNameMatchingTypeRector::class, + ArrayKeyExistsNullToEmptyStringRector::class, + StringClassNameToClassConstantRector::class, + ReturnBinaryOrToEarlyReturnRector::class, + ]) + ->withConfiguredRule(ImportClassNamesRector::class, [ + 'importShortClasses' => true, + 'excludedClasses' => [ + '\Redis', + ], ]) - ->withParallel(300, 10, 10) ->withPreparedSets( - codeQuality: false, + codeQuality: true, codingStyle: true, privatization: true, naming: false, earlyReturn: true, ) - ->withDeadCodeLevel(40) - ->withMemoryLimit('3G') - ->withPhpSets(php83: true) - ->withTypeCoverageLevel(37); + ->withPhpSets(php85: true); diff --git a/src/Tempest/Framework/Commands/DatabaseSeedCommand.php b/src/Tempest/Framework/Commands/DatabaseSeedCommand.php index 1c79e48f3b..d33579c20a 100644 --- a/src/Tempest/Framework/Commands/DatabaseSeedCommand.php +++ b/src/Tempest/Framework/Commands/DatabaseSeedCommand.php @@ -10,13 +10,13 @@ use Tempest\Container\Container; use Tempest\Database\Config\SeederConfig; -final class DatabaseSeedCommand +final readonly class DatabaseSeedCommand { use HasConsole; public function __construct( - private readonly Container $container, - private readonly SeederConfig $seederConfig, + private Container $container, + private SeederConfig $seederConfig, ) {} #[ConsoleCommand( diff --git a/src/Tempest/Framework/Commands/MetaViewComponentCommand.php b/src/Tempest/Framework/Commands/MetaViewComponentCommand.php index 1ce98f187c..ef9c5b0e14 100644 --- a/src/Tempest/Framework/Commands/MetaViewComponentCommand.php +++ b/src/Tempest/Framework/Commands/MetaViewComponentCommand.php @@ -15,12 +15,12 @@ use function Tempest\Support\Filesystem\is_file; use function Tempest\Support\str; -final class MetaViewComponentCommand +final readonly class MetaViewComponentCommand { use HasConsole; public function __construct( - private readonly ViewConfig $viewConfig, + private ViewConfig $viewConfig, ) {} #[ConsoleCommand(name: 'meta:view-component', hidden: true)] @@ -33,7 +33,7 @@ public function __invoke( $viewComponent = $this->resolveViewComponent($viewComponentName); - if ($viewComponent === null) { + if (! $viewComponent instanceof ViewComponent) { $this->error('Unknown view component `' . $viewComponentName . '`'); return; } diff --git a/src/Tempest/Framework/Testing/Http/HttpRouterTester.php b/src/Tempest/Framework/Testing/Http/HttpRouterTester.php index f5bf6cddfd..2f11ad8f50 100644 --- a/src/Tempest/Framework/Testing/Http/HttpRouterTester.php +++ b/src/Tempest/Framework/Testing/Http/HttpRouterTester.php @@ -262,11 +262,7 @@ public function makePsrRequest( $_COOKIE = $cookies; - if (is_array($body)) { - $_POST = $body; - } else { - $_POST = []; - } + $_POST = is_array($body) ? $body : []; return ServerRequestFactory::fromGlobals()->withUploadedFiles($files); } @@ -278,11 +274,11 @@ private function createHeaders(array $headers = []): array callback: fn (mixed $_, string $headerKey): bool => strcasecmp($headerKey, 'accept') === 0, ); - if ($this->contentType !== null) { + if ($this->contentType instanceof ContentType) { $headers[$key ?? 'accept'] = $this->contentType->value; } - if ($this->includeSecFetchHeaders === true) { + if ($this->includeSecFetchHeaders) { if (! array_key_exists('sec-fetch-site', array_change_key_case($headers, case: CASE_LOWER))) { $headers['sec-fetch-site'] = SecFetchSite::SAME_ORIGIN; } diff --git a/src/Tempest/Framework/Testing/Http/TestResponseHelper.php b/src/Tempest/Framework/Testing/Http/TestResponseHelper.php index 497669ed02..977af753d3 100644 --- a/src/Tempest/Framework/Testing/Http/TestResponseHelper.php +++ b/src/Tempest/Framework/Testing/Http/TestResponseHelper.php @@ -327,7 +327,7 @@ public function assertHasSession(string $key, ?Closure $callback = null): self ), ); - if ($callback !== null) { + if ($callback instanceof Closure) { $callback($session, $data); } @@ -352,7 +352,7 @@ public function assertHasValidationError(string $key, ?Closure $callback = null) ), ); - if ($callback !== null) { + if ($callback instanceof Closure) { $callback($validationErrors); } @@ -428,7 +428,7 @@ public function assertViewData(string $key, ?Closure $callback = null): self ), ); - if ($callback !== null && $callback($data, $value) === false) { + if ($callback instanceof Closure && $callback($data, $value) === false) { Assert::fail(sprintf('Failed validating view data for [%s]', $key)); } @@ -509,7 +509,7 @@ public function assertViewModel(string $expected, ?Closure $callback = null): se actual: $this->body, ); - if ($callback !== null && $callback($this->body) === false) { + if ($callback instanceof Closure && $callback($this->body) === false) { Assert::fail('Failed validating view model'); } @@ -711,7 +711,7 @@ public function assertHasNoJsonValidationErrors(): self */ public function dd(): never { - if ($this->throwable !== null) { + if ($this->throwable instanceof Throwable) { dump(sprintf('There was a [%s] exception during this request handling: %s', $this->throwable::class, $this->throwable->getMessage())); // @phpstan-ignore disallowed.function } @@ -720,7 +720,7 @@ public function dd(): never private function assertHasContainer(): void { - if ($this->container === null) { + if (! $this->container instanceof Container) { Assert::fail('This assertion requires a container.'); } } diff --git a/src/Tempest/Framework/Testing/IntegrationTest.php b/src/Tempest/Framework/Testing/IntegrationTest.php index 7c600b78ba..af00cfcb15 100644 --- a/src/Tempest/Framework/Testing/IntegrationTest.php +++ b/src/Tempest/Framework/Testing/IntegrationTest.php @@ -120,7 +120,8 @@ protected function setUp(): void { parent::setUp(); - $this->setupKernel() + $this + ->setupKernel() ->setupConsole() ->setupTesters() ->setupBaseRequest(); @@ -246,7 +247,7 @@ protected function assertException(string $expectedExceptionClass, Closure $hand } catch (Throwable $throwable) { $this->assertInstanceOf($expectedExceptionClass, $throwable); - if ($assertException !== null) { + if ($assertException instanceof Closure) { $assertException($throwable); } diff --git a/tests/Benchmark/Extension/MarkdownExtension.php b/tests/Benchmark/Extension/MarkdownExtension.php index e0108766ec..790629033c 100644 --- a/tests/Benchmark/Extension/MarkdownExtension.php +++ b/tests/Benchmark/Extension/MarkdownExtension.php @@ -13,20 +13,16 @@ final class MarkdownExtension implements ExtensionInterface { - public function configure(OptionsResolver $resolver): void - { - } + public function configure(OptionsResolver $resolver): void {} public function load(Container $container): void { $container->register( MarkdownRenderer::class, - function (Container $container) { - return new MarkdownRenderer( - $container->get(ConsoleExtension::SERVICE_OUTPUT_STD), - $container->get(ExpressionExtension::SERVICE_PLAIN_PRINTER), - ); - }, + fn (Container $container) => new MarkdownRenderer( + $container->get(ConsoleExtension::SERVICE_OUTPUT_STD), + $container->get(ExpressionExtension::SERVICE_PLAIN_PRINTER), + ), [ ReportExtension::TAG_REPORT_RENDERER => [ 'name' => 'markdown', diff --git a/tests/Benchmark/Extension/MarkdownRendererTest.php b/tests/Benchmark/Extension/MarkdownRendererTest.php index 4faae9d60c..fc0efaee54 100644 --- a/tests/Benchmark/Extension/MarkdownRendererTest.php +++ b/tests/Benchmark/Extension/MarkdownRendererTest.php @@ -40,14 +40,14 @@ public function it_renders_a_compact_aggregate_report_table(): void $renderer->render($reports, new Config('markdown', ['file' => null])); $this->assertSame(<<<'MARKDOWN' - ## Benchmark Results + ## Benchmark Results - | Benchmark | Set | Mem. Peak | Time | Variability | - | --------- | --- | --------- | ---- | ----------- | - | ContainerBench(benchAutowireSimple) | - | 3.952mb 0.00% | 4.187μs +0.17% | ±2.05% +108.06% | + | Benchmark | Set | Mem. Peak | Time | Variability | + | --------- | --- | --------- | ---- | ----------- | + | ContainerBench(benchAutowireSimple) | - | 3.952mb 0.00% | 4.187μs +0.17% | ±2.05% +108.06% | - MARKDOWN, + MARKDOWN, $output->fetch()); } @@ -70,12 +70,12 @@ public function it_keeps_non_aggregate_table_columns_unchanged(): void $renderer->render($reports, new Config('markdown', ['file' => null])); $this->assertSame(<<<'MARKDOWN' - | name | value | - | ---- | ----- | - | Example | 123 | + | name | value | + | ---- | ----- | + | Example | 123 | - MARKDOWN, $output->fetch()); + MARKDOWN, $output->fetch()); } #[Test] @@ -113,14 +113,14 @@ public function it_can_filter_compact_rows_by_minimum_time_difference(): void $renderer->render($reports, new Config('markdown', ['file' => null, 'outlier_min_diff' => 1.0])); $this->assertSame(<<<'MARKDOWN' - ## Benchmark Results + ## Benchmark Results - | Benchmark | Set | Mem. Peak | Time | Variability | - | --------- | --- | --------- | ---- | ----------- | - | ContainerBench(benchAutowireNested) | - | 3.952mb +0.10% | 14.791μs +1.55% | ±0.69% +0.50% | + | Benchmark | Set | Mem. Peak | Time | Variability | + | --------- | --- | --------- | ---- | ----------- | + | ContainerBench(benchAutowireNested) | - | 3.952mb +0.10% | 14.791μs +1.55% | ±0.69% +0.50% | - MARKDOWN, + MARKDOWN, $output->fetch()); } @@ -160,12 +160,12 @@ public function it_shows_an_informative_message_when_no_outliers_match(): void $renderer->render($reports, new Config('markdown', ['file' => null, 'outlier_min_diff' => 5.0])); $this->assertSame(<<<'MARKDOWN' - ## Benchmark Results + ## Benchmark Results - _No benchmark changes above ±5%._ + _No benchmark changes above ±5%._ - MARKDOWN, + MARKDOWN, $output->fetch()); } diff --git a/tests/Benchmark/Http/GenericRouterBench.php b/tests/Benchmark/Http/GenericRouterBench.php index d99bcb26d1..85918bfe93 100644 --- a/tests/Benchmark/Http/GenericRouterBench.php +++ b/tests/Benchmark/Http/GenericRouterBench.php @@ -36,7 +36,7 @@ final class GenericRouterBench public function setUp(): void { - $routeConfig = self::makeRouteConfig(); + $routeConfig = $this->makeRouteConfig(); $routeConfig->middleware = new Middleware( HandleRouteExceptionMiddleware::class, @@ -53,7 +53,7 @@ public function setUp(): void $this->router = new GenericRouter($container, $routeConfig); - $routeConfigWithoutExceptionMiddleware = self::makeRouteConfig(); + $routeConfigWithoutExceptionMiddleware = $this->makeRouteConfig(); $routeConfigWithoutExceptionMiddleware->middleware = new Middleware( MatchRouteMiddleware::class, ); @@ -109,7 +109,7 @@ public function handleWithParam(string $id): Ok return new Ok('OK'); } - private static function makeRouteConfig(): RouteConfig + private function makeRouteConfig(): RouteConfig { $handler = new MethodReflector(new ReflectionMethod(self::class, 'handle')); $handlerWithParam = new MethodReflector(new ReflectionMethod(self::class, 'handleWithParam')); diff --git a/tests/Benchmark/Http/Routing/Matching/GenericRouteMatcherBench.php b/tests/Benchmark/Http/Routing/Matching/GenericRouteMatcherBench.php index 95794f418d..34c3ee0390 100644 --- a/tests/Benchmark/Http/Routing/Matching/GenericRouteMatcherBench.php +++ b/tests/Benchmark/Http/Routing/Matching/GenericRouteMatcherBench.php @@ -22,7 +22,7 @@ final class GenericRouteMatcherBench public function __construct() { - $config = self::makeRouteConfig(); + $config = $this->makeRouteConfig(); $this->matcher = new GenericRouteMatcher($config); } @@ -46,7 +46,7 @@ public function provideDynamicMatchingCases(): Generator yield 'Static route' => ['uri' => '/test/5']; } - private static function makeRouteConfig(): RouteConfig + private function makeRouteConfig(): RouteConfig { $routeBuilder = new FakeRouteBuilder(); $constructor = new RouteConfigurator(); diff --git a/tests/Fixtures/Commands/HelloWorldTestCommand.php b/tests/Fixtures/Commands/HelloWorldTestCommand.php index 313d75eb9a..88a406a095 100644 --- a/tests/Fixtures/Commands/HelloWorldTestCommand.php +++ b/tests/Fixtures/Commands/HelloWorldTestCommand.php @@ -9,7 +9,5 @@ final readonly class HelloWorldTestCommand { #[ConsoleCommand] - public function __invoke(): void - { - } + public function __invoke(): void {} } diff --git a/tests/Fixtures/Commands/MyBrokenCommand.php b/tests/Fixtures/Commands/MyBrokenCommand.php index 29aad2368e..3bf5bb19ec 100644 --- a/tests/Fixtures/Commands/MyBrokenCommand.php +++ b/tests/Fixtures/Commands/MyBrokenCommand.php @@ -4,6 +4,4 @@ namespace Tests\Tempest\Fixtures\Commands; -final class MyBrokenCommand -{ -} +final class MyBrokenCommand {} diff --git a/tests/Fixtures/Commands/MyCommand.php b/tests/Fixtures/Commands/MyCommand.php index 24ea8316d0..6bc340beea 100644 --- a/tests/Fixtures/Commands/MyCommand.php +++ b/tests/Fixtures/Commands/MyCommand.php @@ -4,6 +4,4 @@ namespace Tests\Tempest\Fixtures\Commands; -final class MyCommand -{ -} +final class MyCommand {} diff --git a/tests/Fixtures/Console/CommandWithDifferentArguments.php b/tests/Fixtures/Console/CommandWithDifferentArguments.php index 3bcf7c6cbf..3a488f0e03 100644 --- a/tests/Fixtures/Console/CommandWithDifferentArguments.php +++ b/tests/Fixtures/Console/CommandWithDifferentArguments.php @@ -21,6 +21,5 @@ public function __invoke( string $camelCaseStringWithDefault = 'foo', bool $camelCaseBoolWithTrueDefault = true, bool $camelCaseBoolWithFalseDefault = false, - ): void { - } + ): void {} } diff --git a/tests/Fixtures/Console/StylingCommand.php b/tests/Fixtures/Console/StylingCommand.php index 3d5f252cf7..475490226c 100644 --- a/tests/Fixtures/Console/StylingCommand.php +++ b/tests/Fixtures/Console/StylingCommand.php @@ -14,7 +14,8 @@ #[ConsoleCommand(name: 'test:style')] public function __invoke(): void { - $this->info('info') + $this + ->info('info') ->success('success') ->warning('warning') ->error('error'); diff --git a/tests/Fixtures/Controllers/DocsController.php b/tests/Fixtures/Controllers/DocsController.php index 56d4ccda04..d8367974ba 100644 --- a/tests/Fixtures/Controllers/DocsController.php +++ b/tests/Fixtures/Controllers/DocsController.php @@ -9,7 +9,5 @@ final readonly class DocsController { #[Get('/docs/{category}/{slug}')] - public function __invoke(string $category, string $slug): void - { - } + public function __invoke(string $category, string $slug): void {} } diff --git a/tests/Fixtures/Events/EventForListenerWithoutPropagation.php b/tests/Fixtures/Events/EventForListenerWithoutPropagation.php index 3dc5f4037a..ccf11b102c 100644 --- a/tests/Fixtures/Events/EventForListenerWithoutPropagation.php +++ b/tests/Fixtures/Events/EventForListenerWithoutPropagation.php @@ -2,6 +2,4 @@ namespace Tests\Tempest\Fixtures\Events; -final readonly class EventForListenerWithoutPropagation -{ -} +final readonly class EventForListenerWithoutPropagation {} diff --git a/tests/Fixtures/Events/EventInterface.php b/tests/Fixtures/Events/EventInterface.php index 55882c827e..8af3a02011 100644 --- a/tests/Fixtures/Events/EventInterface.php +++ b/tests/Fixtures/Events/EventInterface.php @@ -4,6 +4,4 @@ namespace Tests\Tempest\Fixtures\Events; -interface EventInterface -{ -} +interface EventInterface {} diff --git a/tests/Fixtures/Events/EventInterfaceImplementation.php b/tests/Fixtures/Events/EventInterfaceImplementation.php index 3f6002b47f..d0d06f3a08 100644 --- a/tests/Fixtures/Events/EventInterfaceImplementation.php +++ b/tests/Fixtures/Events/EventInterfaceImplementation.php @@ -4,6 +4,4 @@ namespace Tests\Tempest\Fixtures\Events; -final readonly class EventInterfaceImplementation implements EventInterface -{ -} +final readonly class EventInterfaceImplementation implements EventInterface {} diff --git a/tests/Fixtures/Events/EventWithoutPropagation.php b/tests/Fixtures/Events/EventWithoutPropagation.php index c18a33a2bd..63674a3201 100644 --- a/tests/Fixtures/Events/EventWithoutPropagation.php +++ b/tests/Fixtures/Events/EventWithoutPropagation.php @@ -5,6 +5,4 @@ use Tempest\EventBus\StopsPropagation; #[StopsPropagation] -final readonly class EventWithoutPropagation -{ -} +final readonly class EventWithoutPropagation {} diff --git a/tests/Fixtures/Events/ItHappened.php b/tests/Fixtures/Events/ItHappened.php index 09dac2f71d..5b7a4df832 100644 --- a/tests/Fixtures/Events/ItHappened.php +++ b/tests/Fixtures/Events/ItHappened.php @@ -4,6 +4,4 @@ namespace Tests\Tempest\Fixtures\Events; -final readonly class ItHappened -{ -} +final readonly class ItHappened {} diff --git a/tests/Fixtures/GlobalHiddenDiscovery.php b/tests/Fixtures/GlobalHiddenDiscovery.php index dc75910e72..a784f8c7e5 100644 --- a/tests/Fixtures/GlobalHiddenDiscovery.php +++ b/tests/Fixtures/GlobalHiddenDiscovery.php @@ -13,9 +13,7 @@ final class GlobalHiddenDiscovery implements Discovery use IsDiscovery; - public function discover(DiscoveryLocation $location, ClassReflector $class): void - { - } + public function discover(DiscoveryLocation $location, ClassReflector $class): void {} public function apply(): void { diff --git a/tests/Fixtures/GlobalHiddenPathDiscovery.php b/tests/Fixtures/GlobalHiddenPathDiscovery.php index 737b4694c7..7c12bcf711 100644 --- a/tests/Fixtures/GlobalHiddenPathDiscovery.php +++ b/tests/Fixtures/GlobalHiddenPathDiscovery.php @@ -13,9 +13,7 @@ final class GlobalHiddenPathDiscovery implements Discovery use IsDiscovery; - public function discover(DiscoveryLocation $location, ClassReflector $class): void - { - } + public function discover(DiscoveryLocation $location, ClassReflector $class): void {} public function apply(): void { diff --git a/tests/Fixtures/Handlers/MyCommandHandler.php b/tests/Fixtures/Handlers/MyCommandHandler.php index 4b6a9d1e3d..be53f3b947 100644 --- a/tests/Fixtures/Handlers/MyCommandHandler.php +++ b/tests/Fixtures/Handlers/MyCommandHandler.php @@ -10,7 +10,5 @@ final class MyCommandHandler { #[CommandHandler] - public function __invoke(MyCommand $command): void - { - } + public function __invoke(MyCommand $command): void {} } diff --git a/tests/Fixtures/TestInstallerClass.php b/tests/Fixtures/TestInstallerClass.php index 25e10c22c8..e3a6abdbc1 100644 --- a/tests/Fixtures/TestInstallerClass.php +++ b/tests/Fixtures/TestInstallerClass.php @@ -7,6 +7,4 @@ use Tempest\Discovery\SkipDiscovery; #[SkipDiscovery] -final readonly class TestInstallerClass -{ -} +final readonly class TestInstallerClass {} diff --git a/tests/Integration/Auth/AccessControl/AccessControlTest.php b/tests/Integration/Auth/AccessControl/AccessControlTest.php index 7bde205153..33be4a3828 100644 --- a/tests/Integration/Auth/AccessControl/AccessControlTest.php +++ b/tests/Integration/Auth/AccessControl/AccessControlTest.php @@ -134,7 +134,7 @@ public function view(): bool #[Policy(Article::class, action: 'edit')] public function edit(Article $article, ?TestUser $subject): bool { - if ($subject === null) { + if (! $subject instanceof TestUser) { return false; } @@ -144,7 +144,7 @@ public function edit(Article $article, ?TestUser $subject): bool #[Policy(Article::class, action: 'delete')] public function delete(Article $article, ?TestUser $subject): bool|AccessDecision { - if ($subject === null) { + if (! $subject instanceof TestUser) { return AccessDecision::denied('Authentication required'); } @@ -177,7 +177,7 @@ public function view(): bool #[Policy(ArticleComment::class, action: 'edit')] public function edit(ArticleComment $comment, ?TestUser $subject): bool { - if ($subject === null) { + if (! $subject instanceof TestUser) { return false; } diff --git a/tests/Integration/Auth/AccessControl/HasPolicyTests.php b/tests/Integration/Auth/AccessControl/HasPolicyTests.php index e0dfdae9c3..493e3a20ff 100644 --- a/tests/Integration/Auth/AccessControl/HasPolicyTests.php +++ b/tests/Integration/Auth/AccessControl/HasPolicyTests.php @@ -16,9 +16,11 @@ public function registerPoliciesFrom(string|object $class): self $config = $this->container->get(AuthConfig::class); foreach (new ClassReflector($class)->getPublicMethods() as $method) { - if ($policy = $method->getAttribute(Policy::class)) { - $config->registerPolicy($method, $policy); + if (! ($policy = $method->getAttribute(Policy::class))) { + continue; } + + $config->registerPolicy($method, $policy); } return $this; diff --git a/tests/Integration/Auth/AccessControl/PolicyBasedAccessControlTest.php b/tests/Integration/Auth/AccessControl/PolicyBasedAccessControlTest.php index 4c4d1bde6f..9adc1746c6 100644 --- a/tests/Integration/Auth/AccessControl/PolicyBasedAccessControlTest.php +++ b/tests/Integration/Auth/AccessControl/PolicyBasedAccessControlTest.php @@ -474,11 +474,7 @@ final class MultiAuthenticatablePolicy #[Policy] public function view(?Document $_resource, null|User|ServiceAccount $subject): bool { - if (! $subject instanceof Authenticatable) { - return false; - } - - return true; + return $subject instanceof Authenticatable; } } @@ -517,7 +513,7 @@ final class PolicyWithoutActionNames #[Policy(Post::class)] public function canMarkAsPublished(?Post $post, ?User $user): bool { - if ($user === null) { + if (! $user instanceof User) { return false; } @@ -527,7 +523,7 @@ public function canMarkAsPublished(?Post $post, ?User $user): bool #[Policy(Post::class)] public function approveForPublication(?Post $post, ?User $user): bool { - if ($user === null) { + if (! $user instanceof User) { return false; } diff --git a/tests/Integration/Auth/Authentication/SessionAuthenticatorTest.php b/tests/Integration/Auth/Authentication/SessionAuthenticatorTest.php index c23d41d08c..b061e602b3 100644 --- a/tests/Integration/Auth/Authentication/SessionAuthenticatorTest.php +++ b/tests/Integration/Auth/Authentication/SessionAuthenticatorTest.php @@ -42,7 +42,7 @@ protected function configure(): void Filesystem\ensure_directory_empty($this->path); $this->container->get(FrameworkKernel::class)->internalStorage = realpath($this->path); - $this->container->config(new FileSessionConfig(path: 'sessions', expiration: Duration::hours(2))); + $this->container->config(new FileSessionConfig(expiration: Duration::hours(2), path: 'sessions')); $this->container->config(new AuthConfig(authenticatables: [User::class])); $this->container->singleton(SessionManager::class, fn () => new FileSessionManager( $this->container->get(Clock::class), diff --git a/tests/Integration/Cache/CacheTest.php b/tests/Integration/Cache/CacheTest.php index 3d11de9e68..cd59661cd8 100644 --- a/tests/Integration/Cache/CacheTest.php +++ b/tests/Integration/Cache/CacheTest.php @@ -38,7 +38,7 @@ public function test_put(): void $item = $pool->getItem('a'); $this->assertFalse($item->isHit()); - $this->assertSame(null, $item->get()); + $this->assertNull($item->get()); $item = $pool->getItem('b'); $this->assertTrue($item->isHit()); @@ -152,7 +152,7 @@ public function test_get(): void $clock->plus($interval); - $this->assertSame(null, $cache->get('a')); + $this->assertNull($cache->get('a')); $this->assertSame('b', $cache->get('b')); } @@ -171,7 +171,7 @@ public function test_get_many(): void $values = $cache->getMany(['foo2', 'foo3']); $this->assertSame('bar2', $values['foo2']); - $this->assertSame(null, $values['foo3']); + $this->assertNull($values['foo3']); } public function test_resolve(): void @@ -188,7 +188,7 @@ public function test_resolve(): void $clock->plus($interval); - $this->assertSame(null, $cache->get('a')); + $this->assertNull($cache->get('a')); $this->assertSame('b', $cache->get('b')); $b = $cache->resolve('b', fn () => 'b'); diff --git a/tests/Integration/Cache/RedisCacheTest.php b/tests/Integration/Cache/RedisCacheTest.php index 690ef341e0..9f7531eabe 100644 --- a/tests/Integration/Cache/RedisCacheTest.php +++ b/tests/Integration/Cache/RedisCacheTest.php @@ -3,12 +3,14 @@ namespace Tests\Tempest\Integration\Cache; use Predis; +use Predis\Client; use Symfony\Component\Cache\Adapter\RedisAdapter; use Tempest\Cache\GenericCache; use Tempest\KeyValue\Redis\Config\RedisConfig; use Tempest\KeyValue\Redis\PhpRedisClient; use Tempest\KeyValue\Redis\PredisClient; use Tests\Tempest\Integration\FrameworkIntegrationTestCase; +use Throwable; final class RedisCacheTest extends FrameworkIntegrationTestCase { @@ -38,7 +40,7 @@ public function test_php_redis_cache(): void try { $redis->connect(); - } catch (\Throwable) { + } catch (Throwable) { $this->markTestSkipped('Could not connect to Redis.'); } @@ -52,11 +54,11 @@ public function test_php_redis_cache(): void public function test_predis_cache(): void { - if (! class_exists(Predis\Client::class)) { + if (! class_exists(Client::class)) { $this->markTestSkipped('The `predis/predis` package is not installed.'); } - $redis = new PredisClient(new Predis\Client( + $redis = new PredisClient(new Client( parameters: [ 'database' => 6, 'timeout' => .2, @@ -66,7 +68,7 @@ public function test_predis_cache(): void try { $redis->connect(); - } catch (\Throwable) { + } catch (Throwable) { $this->markTestSkipped('Could not connect to Redis.'); } diff --git a/tests/Integration/Console/Components/Static/StaticProgressBarComponentTest.php b/tests/Integration/Console/Components/Static/StaticProgressBarComponentTest.php index e4cb3ac201..c5d6358b64 100644 --- a/tests/Integration/Console/Components/Static/StaticProgressBarComponentTest.php +++ b/tests/Integration/Console/Components/Static/StaticProgressBarComponentTest.php @@ -25,11 +25,11 @@ public function test_progress_bar(): void }) ->assertContains( << ] (1/3) - [====================> ] (2/3) - [===============================] (3/3) - ["aa","bb","cc"] - TXT, + [==========> ] (1/3) + [====================> ] (2/3) + [===============================] (3/3) + ["aa","bb","cc"] + TXT, true, ); } diff --git a/tests/Integration/Console/Components/Static/StaticSearchComponentTest.php b/tests/Integration/Console/Components/Static/StaticSearchComponentTest.php index 447de2dce4..c1608c9746 100644 --- a/tests/Integration/Console/Components/Static/StaticSearchComponentTest.php +++ b/tests/Integration/Console/Components/Static/StaticSearchComponentTest.php @@ -26,22 +26,22 @@ public function test_search_component(): void ->submit('a') ->assertContains( <<submit(1) ->submit('b') ->assertContains( <<submit(2) @@ -62,9 +62,9 @@ public function test_no_answer(): void ->submit() ->assertContains( text: <<submit(0) @@ -86,9 +86,9 @@ public function test_default_answer(): void ->submit() ->assertContains( text: <<submit(0) diff --git a/tests/Integration/Console/Components/TaskComponentTest.php b/tests/Integration/Console/Components/TaskComponentTest.php index 68428409e6..9b633ba60c 100644 --- a/tests/Integration/Console/Components/TaskComponentTest.php +++ b/tests/Integration/Console/Components/TaskComponentTest.php @@ -64,7 +64,7 @@ public function test_process_task(): void $frames = iterator_to_array($component->render($terminal)); $this->assertStringContainsString('Task in progress', $frames[0]); - $this->assertStringContainsString('Done in', $frames[array_key_last($frames)]); + $this->assertStringContainsString('Done in', array_last($frames)); }); } @@ -100,7 +100,7 @@ public function test_failing_task(): void $frames = iterator_to_array($component->render($terminal)); $this->assertStringContainsString('Task in progress', $frames[0]); - $this->assertStringContainsString('An error occurred.', $frames[array_key_last($frames)]); + $this->assertStringContainsString('An error occurred.', array_last($frames)); }); } } diff --git a/tests/Integration/Console/ConsoleArgumentBagTest.php b/tests/Integration/Console/ConsoleArgumentBagTest.php index b9999ac955..8423d1358a 100644 --- a/tests/Integration/Console/ConsoleArgumentBagTest.php +++ b/tests/Integration/Console/ConsoleArgumentBagTest.php @@ -36,13 +36,13 @@ public function test_argument_bag_works(): void $this->assertNull($firstArg->name); $forceFlag = $bag->all()[1]; - $this->assertSame(true, $forceFlag->value); - $this->assertSame(null, $forceFlag->position); + $this->assertTrue($forceFlag->value); + $this->assertNull($forceFlag->position); $this->assertSame('force', $forceFlag->name); $timesFlag = $bag->all()[2]; $this->assertSame('2', $timesFlag->value); - $this->assertSame(null, $timesFlag->position); + $this->assertNull($timesFlag->position); $this->assertSame('times', $timesFlag->name); $this->assertSame( diff --git a/tests/Integration/Console/Fixtures/CommandWithNonCommandMethods.php b/tests/Integration/Console/Fixtures/CommandWithNonCommandMethods.php index 48118f0f08..ec9b88813e 100644 --- a/tests/Integration/Console/Fixtures/CommandWithNonCommandMethods.php +++ b/tests/Integration/Console/Fixtures/CommandWithNonCommandMethods.php @@ -8,16 +8,10 @@ final class CommandWithNonCommandMethods { - public function __invoke(): void - { - } + public function __invoke(): void {} #[ConsoleCommand('test:not-empty')] - public function do(): void - { - } + public function do(): void {} - public function empty(): void - { - } + public function empty(): void {} } diff --git a/tests/Integration/Console/Fixtures/CompletionTestCommand.php b/tests/Integration/Console/Fixtures/CompletionTestCommand.php index a41a366905..9cc3c6c420 100644 --- a/tests/Integration/Console/Fixtures/CompletionTestCommand.php +++ b/tests/Integration/Console/Fixtures/CompletionTestCommand.php @@ -13,6 +13,5 @@ public function __invoke( string $value, bool $flag = false, array $items = [], - ): void { - } + ): void {} } diff --git a/tests/Integration/Console/Fixtures/InteractiveCommand.php b/tests/Integration/Console/Fixtures/InteractiveCommand.php index afa941cbba..429ee2492e 100644 --- a/tests/Integration/Console/Fixtures/InteractiveCommand.php +++ b/tests/Integration/Console/Fixtures/InteractiveCommand.php @@ -132,7 +132,7 @@ public function progress(): void $result = $this->console->progressBar( data: array_fill(0, 10, 'a'), handler: function ($i) { - usleep(100000); + usleep(100_000); return $i . $i; }, diff --git a/tests/Integration/Console/Fixtures/MyConsole.php b/tests/Integration/Console/Fixtures/MyConsole.php index d45b635e81..453fd24548 100644 --- a/tests/Integration/Console/Fixtures/MyConsole.php +++ b/tests/Integration/Console/Fixtures/MyConsole.php @@ -17,6 +17,5 @@ public function handle( int $times = 1, bool $force = false, ?string $optional = null, - ): void { - } + ): void {} } diff --git a/tests/Integration/Console/Fixtures/Package.php b/tests/Integration/Console/Fixtures/Package.php index 56dd3b7b5c..44239f29ea 100644 --- a/tests/Integration/Console/Fixtures/Package.php +++ b/tests/Integration/Console/Fixtures/Package.php @@ -10,9 +10,7 @@ final readonly class Package { #[ConsoleCommand] - public function list(): void - { - } + public function list(): void {} #[ConsoleCommand(help: 'help text')] public function info( @@ -23,6 +21,5 @@ public function info( aliases: ['n'], )] string $name, - ): void { - } + ): void {} } diff --git a/tests/Integration/Console/Fixtures/TestConsoleException.php b/tests/Integration/Console/Fixtures/TestConsoleException.php index 5ba91f6e11..e8f42d415f 100644 --- a/tests/Integration/Console/Fixtures/TestConsoleException.php +++ b/tests/Integration/Console/Fixtures/TestConsoleException.php @@ -9,7 +9,5 @@ final class TestConsoleException extends ConsoleException { - public function render(Console $console): void - { - } + public function render(Console $console): void {} } diff --git a/tests/Integration/Console/Input/ConsoleInputArgumentTest.php b/tests/Integration/Console/Input/ConsoleInputArgumentTest.php index 6f53ef679f..e708acc1ca 100644 --- a/tests/Integration/Console/Input/ConsoleInputArgumentTest.php +++ b/tests/Integration/Console/Input/ConsoleInputArgumentTest.php @@ -41,19 +41,19 @@ public function test_parse_named_arguments(): void $input = ConsoleInputArgument::fromString('--noFooBar'); $this->assertSame('foo-bar', $input->name); - $this->assertSame(false, $input->value); + $this->assertFalse($input->value); $input = ConsoleInputArgument::fromString('--no-interaction'); $this->assertSame('interaction', $input->name); - $this->assertSame(false, $input->value); + $this->assertFalse($input->value); $input = ConsoleInputArgument::fromString('--no-interaction=true'); $this->assertSame('interaction', $input->name); - $this->assertSame(false, $input->value); + $this->assertFalse($input->value); $input = ConsoleInputArgument::fromString('--no-interaction=false'); $this->assertSame('interaction', $input->name); - $this->assertSame(true, $input->value); + $this->assertTrue($input->value); $input = ConsoleInputArgument::fromString('--no-foo=baz'); $this->assertSame('no-foo', $input->name); diff --git a/tests/Integration/Console/Scheduler/GenericSchedulerTest.php b/tests/Integration/Console/Scheduler/GenericSchedulerTest.php index 341f23e52d..552c26c262 100644 --- a/tests/Integration/Console/Scheduler/GenericSchedulerTest.php +++ b/tests/Integration/Console/Scheduler/GenericSchedulerTest.php @@ -117,12 +117,8 @@ public function test_scheduler_only_dispatches_the_command_in_desired_times(): v } // dummy handler for testing - public function handler(): void - { - } + public function handler(): void {} // dummy command for testing - public function command(): void - { - } + public function command(): void {} } diff --git a/tests/Integration/Console/Scheduler/HandlerInvocationTest.php b/tests/Integration/Console/Scheduler/HandlerInvocationTest.php index 30e697d493..54c058a4f8 100644 --- a/tests/Integration/Console/Scheduler/HandlerInvocationTest.php +++ b/tests/Integration/Console/Scheduler/HandlerInvocationTest.php @@ -30,7 +30,5 @@ public function test_name_gets_constructed_properly(): void } // dummy handler method - public function handler(): void - { - } + public function handler(): void {} } diff --git a/tests/Integration/Core/Config/LoadConfigTest.php b/tests/Integration/Core/Config/LoadConfigTest.php index 365fff006f..d3b51d6b36 100644 --- a/tests/Integration/Core/Config/LoadConfigTest.php +++ b/tests/Integration/Core/Config/LoadConfigTest.php @@ -117,14 +117,14 @@ private function setupFixtures(array $configs): void $db = str_replace('.php', '.sqlite', $config); Filesystem\write_file(__DIR__ . '/Fixtures/' . $config, <<logs[] = ['level' => 'emergency', 'message' => $message, 'context' => $context]; } - public function alert(string|\Stringable $message, array $context = []): void + public function alert(string|Stringable $message, array $context = []): void { $this->logs[] = ['level' => 'alert', 'message' => $message, 'context' => $context]; } - public function critical(string|\Stringable $message, array $context = []): void + public function critical(string|Stringable $message, array $context = []): void { $this->logs[] = ['level' => 'critical', 'message' => $message, 'context' => $context]; } - public function error(string|\Stringable $message, array $context = []): void + public function error(string|Stringable $message, array $context = []): void { $this->logs[] = ['level' => 'error', 'message' => $message, 'context' => $context]; } - public function warning(string|\Stringable $message, array $context = []): void + public function warning(string|Stringable $message, array $context = []): void { $this->logs[] = ['level' => 'warning', 'message' => $message, 'context' => $context]; } - public function notice(string|\Stringable $message, array $context = []): void + public function notice(string|Stringable $message, array $context = []): void { $this->logs[] = ['level' => 'notice', 'message' => $message, 'context' => $context]; } - public function info(string|\Stringable $message, array $context = []): void + public function info(string|Stringable $message, array $context = []): void { $this->logs[] = ['level' => 'info', 'message' => $message, 'context' => $context]; } - public function debug(string|\Stringable $message, array $context = []): void + public function debug(string|Stringable $message, array $context = []): void { $this->logs[] = ['level' => 'debug', 'message' => $message, 'context' => $context]; } - public function log(mixed $level, string|\Stringable $message, array $context = []): void + public function log(mixed $level, string|Stringable $message, array $context = []): void { $this->logs[] = ['level' => $level, 'message' => $message, 'context' => $context]; } diff --git a/tests/Integration/Core/Fixtures/MiddlewareA.php b/tests/Integration/Core/Fixtures/MiddlewareA.php index 255c68684a..29fb6aec2a 100644 --- a/tests/Integration/Core/Fixtures/MiddlewareA.php +++ b/tests/Integration/Core/Fixtures/MiddlewareA.php @@ -2,6 +2,4 @@ namespace Tests\Tempest\Integration\Core\Fixtures; -final class MiddlewareA -{ -} +final class MiddlewareA {} diff --git a/tests/Integration/Core/Fixtures/MiddlewareB.php b/tests/Integration/Core/Fixtures/MiddlewareB.php index a70fe5fd86..4347a2fc82 100644 --- a/tests/Integration/Core/Fixtures/MiddlewareB.php +++ b/tests/Integration/Core/Fixtures/MiddlewareB.php @@ -2,6 +2,4 @@ namespace Tests\Tempest\Integration\Core\Fixtures; -final class MiddlewareB -{ -} +final class MiddlewareB {} diff --git a/tests/Integration/Core/Fixtures/MiddlewareC.php b/tests/Integration/Core/Fixtures/MiddlewareC.php index b845eaeb46..281c47798d 100644 --- a/tests/Integration/Core/Fixtures/MiddlewareC.php +++ b/tests/Integration/Core/Fixtures/MiddlewareC.php @@ -2,6 +2,4 @@ namespace Tests\Tempest\Integration\Core\Fixtures; -final class MiddlewareC -{ -} +final class MiddlewareC {} diff --git a/tests/Integration/Core/Fixtures/MiddlewareFramework.php b/tests/Integration/Core/Fixtures/MiddlewareFramework.php index 7e538bb6d9..932d6ae1f1 100644 --- a/tests/Integration/Core/Fixtures/MiddlewareFramework.php +++ b/tests/Integration/Core/Fixtures/MiddlewareFramework.php @@ -5,6 +5,4 @@ use Tempest\Core\Priority; #[Priority(Priority::FRAMEWORK)] -final class MiddlewareFramework -{ -} +final class MiddlewareFramework {} diff --git a/tests/Integration/Core/Fixtures/MiddlewareHigh.php b/tests/Integration/Core/Fixtures/MiddlewareHigh.php index 2eb5fcb6b1..b8831399d4 100644 --- a/tests/Integration/Core/Fixtures/MiddlewareHigh.php +++ b/tests/Integration/Core/Fixtures/MiddlewareHigh.php @@ -5,6 +5,4 @@ use Tempest\Core\Priority; #[Priority(Priority::HIGH)] -final class MiddlewareHigh -{ -} +final class MiddlewareHigh {} diff --git a/tests/Integration/Core/Fixtures/MiddlewareHighest.php b/tests/Integration/Core/Fixtures/MiddlewareHighest.php index 74c7ee1fcf..0ddae4af66 100644 --- a/tests/Integration/Core/Fixtures/MiddlewareHighest.php +++ b/tests/Integration/Core/Fixtures/MiddlewareHighest.php @@ -5,6 +5,4 @@ use Tempest\Core\Priority; #[Priority(Priority::HIGHEST)] -final class MiddlewareHighest -{ -} +final class MiddlewareHighest {} diff --git a/tests/Integration/Core/Fixtures/MiddlewareLow.php b/tests/Integration/Core/Fixtures/MiddlewareLow.php index 3dc6f0af81..7dfff0f0f2 100644 --- a/tests/Integration/Core/Fixtures/MiddlewareLow.php +++ b/tests/Integration/Core/Fixtures/MiddlewareLow.php @@ -5,6 +5,4 @@ use Tempest\Core\Priority; #[Priority(Priority::LOW)] -final class MiddlewareLow -{ -} +final class MiddlewareLow {} diff --git a/tests/Integration/Core/Fixtures/MiddlewareLowest.php b/tests/Integration/Core/Fixtures/MiddlewareLowest.php index f1c635a874..4302774b90 100644 --- a/tests/Integration/Core/Fixtures/MiddlewareLowest.php +++ b/tests/Integration/Core/Fixtures/MiddlewareLowest.php @@ -5,6 +5,4 @@ use Tempest\Core\Priority; #[Priority(Priority::LOWEST)] -final class MiddlewareLowest -{ -} +final class MiddlewareLowest {} diff --git a/tests/Integration/Core/Fixtures/MiddlewareNormal.php b/tests/Integration/Core/Fixtures/MiddlewareNormal.php index 7b45ef132c..7201eca48e 100644 --- a/tests/Integration/Core/Fixtures/MiddlewareNormal.php +++ b/tests/Integration/Core/Fixtures/MiddlewareNormal.php @@ -5,6 +5,4 @@ use Tempest\Core\Priority; #[Priority(Priority::NORMAL)] -final class MiddlewareNormal -{ -} +final class MiddlewareNormal {} diff --git a/tests/Integration/Database/Builder/InsertQueryBuilderTest.php b/tests/Integration/Database/Builder/InsertQueryBuilderTest.php index 0fe939733a..c367d1d959 100644 --- a/tests/Integration/Database/Builder/InsertQueryBuilderTest.php +++ b/tests/Integration/Database/Builder/InsertQueryBuilderTest.php @@ -189,11 +189,11 @@ public function test_insert_mapping(): void $expected = match ($dialect) { DatabaseDialect::POSTGRESQL => <<<'SQL' - INSERT INTO authors (name) VALUES (?) RETURNING * - SQL, + INSERT INTO authors (name) VALUES (?) RETURNING * + SQL, default => <<<'SQL' - INSERT INTO `authors` (`name`) VALUES (?) - SQL, + INSERT INTO `authors` (`name`) VALUES (?) + SQL, }; $this->assertSame($expected, $query->compile()->toString()); diff --git a/tests/Integration/Database/Builder/InsertRelationsTest.php b/tests/Integration/Database/Builder/InsertRelationsTest.php index 0f6c6c0920..75068f4d28 100644 --- a/tests/Integration/Database/Builder/InsertRelationsTest.php +++ b/tests/Integration/Database/Builder/InsertRelationsTest.php @@ -364,7 +364,7 @@ final class Spell public PrimaryKey $spell_id; - #[BelongsTo(ownerJoin: 'creator_uuid', relationJoin: 'mage_uuid')] + #[BelongsTo(relationJoin: 'mage_uuid', ownerJoin: 'creator_uuid')] public ?Mage $creator = null; public function __construct( @@ -395,7 +395,7 @@ final class Adventurer public PrimaryKey $adventurer_id; - #[BelongsTo(ownerJoin: 'party_uuid', relationJoin: 'party_id')] + #[BelongsTo(relationJoin: 'party_id', ownerJoin: 'party_uuid')] public ?Party $party = null; public function __construct( diff --git a/tests/Integration/Database/Builder/IsDatabaseModelTest.php b/tests/Integration/Database/Builder/IsDatabaseModelTest.php index 1a312bad0f..f3a60efe7f 100644 --- a/tests/Integration/Database/Builder/IsDatabaseModelTest.php +++ b/tests/Integration/Database/Builder/IsDatabaseModelTest.php @@ -771,6 +771,7 @@ public function test_on_database_does_not_mutate_original(): void // Original still works against default database $foo->update(bar: 'updated'); + $refreshed = Foo::get($foo->id); $this->assertSame('updated', $refreshed->bar); diff --git a/tests/Integration/Database/Builder/SelectQueryBuilderTest.php b/tests/Integration/Database/Builder/SelectQueryBuilderTest.php index c4d257591d..2b3b84909e 100644 --- a/tests/Integration/Database/Builder/SelectQueryBuilderTest.php +++ b/tests/Integration/Database/Builder/SelectQueryBuilderTest.php @@ -316,9 +316,11 @@ public function test_chunk(): void $this->assertCount(4, $results); $results = []; - Book::select()->whereRaw("title <> 'A'")->chunk(function (array $chunk) use (&$results): void { - $results = [...$results, ...$chunk]; - }, 2); + Book::select() + ->whereRaw("title <> 'A'") + ->chunk(function (array $chunk) use (&$results): void { + $results = [...$results, ...$chunk]; + }, 2); $this->assertCount(3, $results); } @@ -337,9 +339,11 @@ public function test_chunk_with_relation(): void Book::new(title: 'B', author: $author)->save(); $results = []; - Book::select()->with('author')->chunk(function (array $chunk) use (&$results): void { - $results = [...$results, ...$chunk]; - }, 1); + Book::select() + ->with('author') + ->chunk(function (array $chunk) use (&$results): void { + $results = [...$results, ...$chunk]; + }, 1); $this->assertCount(2, $results); } @@ -530,9 +534,9 @@ public function test_paginate(): void $this->assertSame(0, $page1->offset); $this->assertSame(2, $page1->limit); $this->assertSame(2, $page1->nextPage); - $this->assertSame(null, $page1->previousPage); - $this->assertSame(true, $page1->hasNext); - $this->assertSame(false, $page1->hasPrevious); + $this->assertNull($page1->previousPage); + $this->assertTrue($page1->hasNext); + $this->assertFalse($page1->hasPrevious); $this->assertSame('LOTR 1.1', $page1->data[0]->title); $this->assertSame('LOTR 1.2', $page1->data[1]->title); diff --git a/tests/Integration/Database/Builder/UpdateQueryBuilderTest.php b/tests/Integration/Database/Builder/UpdateQueryBuilderTest.php index 0fd8271dbe..a81f9a9984 100644 --- a/tests/Integration/Database/Builder/UpdateQueryBuilderTest.php +++ b/tests/Integration/Database/Builder/UpdateQueryBuilderTest.php @@ -310,11 +310,11 @@ public function test_update_mapping(): void $expected = match ($dialect) { DatabaseDialect::POSTGRESQL => <<<'SQL' - UPDATE authors SET name = ? WHERE authors.id = ? - SQL, + UPDATE authors SET name = ? WHERE authors.id = ? + SQL, default => <<<'SQL' - UPDATE `authors` SET `name` = ? WHERE `authors`.`id` = ? - SQL, + UPDATE `authors` SET `name` = ? WHERE `authors`.`id` = ? + SQL, }; $this->assertSame($expected, $query->compile()->toString()); diff --git a/tests/Integration/Database/Builder/UpdateRelationsTest.php b/tests/Integration/Database/Builder/UpdateRelationsTest.php index 8763cba18a..9309bf6a94 100644 --- a/tests/Integration/Database/Builder/UpdateRelationsTest.php +++ b/tests/Integration/Database/Builder/UpdateRelationsTest.php @@ -506,7 +506,7 @@ final class UpdateSpell public PrimaryKey $spell_id; - #[BelongsTo(ownerJoin: 'creator_uuid', relationJoin: 'mage_uuid')] + #[BelongsTo(relationJoin: 'mage_uuid', ownerJoin: 'creator_uuid')] public ?UpdateMage $creator = null; public function __construct( @@ -539,7 +539,7 @@ final class UpdateAdventurer public PrimaryKey $adventurer_id; - #[BelongsTo(ownerJoin: 'party_uuid', relationJoin: 'party_id')] + #[BelongsTo(relationJoin: 'party_id', ownerJoin: 'party_uuid')] public ?UpdateParty $party = null; public function __construct( diff --git a/tests/Integration/Database/ConvenientDateWhereMethodsTest.php b/tests/Integration/Database/ConvenientDateWhereMethodsTest.php index 39ee9049a8..a3b7985502 100644 --- a/tests/Integration/Database/ConvenientDateWhereMethodsTest.php +++ b/tests/Integration/Database/ConvenientDateWhereMethodsTest.php @@ -226,9 +226,11 @@ public function test_where_this_year(): void $this->assertCount(10, $events); foreach ($events as $event) { - if ($event->name !== 'Last year event') { - $this->assertTrue($event->event_date->isCurrentYear()); + if ($event->name === 'Last year event') { + continue; } + + $this->assertTrue($event->event_date->isCurrentYear()); } } diff --git a/tests/Integration/Database/ConvenientWhereMethodsTest.php b/tests/Integration/Database/ConvenientWhereMethodsTest.php index c64f156bb7..6917c3c935 100644 --- a/tests/Integration/Database/ConvenientWhereMethodsTest.php +++ b/tests/Integration/Database/ConvenientWhereMethodsTest.php @@ -4,6 +4,7 @@ namespace Tests\Tempest\Integration\Database; +use InvalidArgumentException; use Tempest\Database\Builder\WhereOperator; use Tempest\Database\IsDatabaseModel; use Tempest\Database\MigratesUp; @@ -363,7 +364,7 @@ public function test_chaining_or_conditions(): void public function test_where_in_throws_exception_for_invalid_value(): void { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('IN operator requires an array of values'); query(User::class) @@ -374,7 +375,7 @@ public function test_where_in_throws_exception_for_invalid_value(): void public function test_where_between_throws_exception_for_invalid_array(): void { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('BETWEEN operator requires an array with exactly 2 values'); query(User::class) @@ -385,7 +386,7 @@ public function test_where_between_throws_exception_for_invalid_array(): void public function test_where_between_throws_exception_for_too_many_values(): void { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('BETWEEN operator requires an array with exactly 2 values'); query(User::class) diff --git a/tests/Integration/Database/GenericDatabaseTest.php b/tests/Integration/Database/GenericDatabaseTest.php index a8a2571018..8ca68639f3 100644 --- a/tests/Integration/Database/GenericDatabaseTest.php +++ b/tests/Integration/Database/GenericDatabaseTest.php @@ -65,9 +65,9 @@ public function test_query_with_semicolons(): void $db = $this->container->get(Database::class); $db->execute( new Query(<<assertSame(1, query(Publisher::class)->count()->execute()); diff --git a/tests/Integration/Database/ModelInspector/BelongsToTest.php b/tests/Integration/Database/ModelInspector/BelongsToTest.php index 11ca419007..0cf57fd75f 100644 --- a/tests/Integration/Database/ModelInspector/BelongsToTest.php +++ b/tests/Integration/Database/ModelInspector/BelongsToTest.php @@ -256,10 +256,10 @@ final class SelfReferencingCategoryModel public string $name; - #[BelongsTo(ownerJoin: 'parent_id', relationJoin: 'id')] + #[BelongsTo(relationJoin: 'id', ownerJoin: 'parent_id')] public ?SelfReferencingCategoryModel $parent = null; - #[BelongsTo(ownerJoin: 'category_parent_id', relationJoin: 'id')] + #[BelongsTo(relationJoin: 'id', ownerJoin: 'category_parent_id')] public ?SelfReferencingCategoryModel $parentWithCustomOwnerJoin = null; /** @var \Tests\Tempest\Integration\Database\ModelInspector\SelfReferencingCategoryModel[] */ diff --git a/tests/Integration/Database/QueryStatements/CompoundStatementTest.php b/tests/Integration/Database/QueryStatements/CompoundStatementTest.php index ad98a5e17a..6090a01d49 100644 --- a/tests/Integration/Database/QueryStatements/CompoundStatementTest.php +++ b/tests/Integration/Database/QueryStatements/CompoundStatementTest.php @@ -18,9 +18,9 @@ public function test_it_can_compile_create_enum_type_statement(): void $this->assertSame( <<compile(DatabaseDialect::SQLITE), ); } diff --git a/tests/Integration/Database/QueryStatements/CreateEnumTypeStatementTest.php b/tests/Integration/Database/QueryStatements/CreateEnumTypeStatementTest.php index 3fa2f59281..f8dddf12fb 100644 --- a/tests/Integration/Database/QueryStatements/CreateEnumTypeStatementTest.php +++ b/tests/Integration/Database/QueryStatements/CreateEnumTypeStatementTest.php @@ -16,8 +16,8 @@ enumClass: CreateEnumTypeStatementTestEnumForCreateTable::class, $this->assertSame( <<compile(DatabaseDialect::POSTGRESQL), ); } diff --git a/tests/Integration/Database/QueryStatements/DropEnumTypeStatementTest.php b/tests/Integration/Database/QueryStatements/DropEnumTypeStatementTest.php index 83a0fccd0b..191efae8a1 100644 --- a/tests/Integration/Database/QueryStatements/DropEnumTypeStatementTest.php +++ b/tests/Integration/Database/QueryStatements/DropEnumTypeStatementTest.php @@ -16,8 +16,8 @@ enumClass: DropEnumTypeStatementTestEnumForCreateTable::class, $this->assertSame( <<compile(DatabaseDialect::POSTGRESQL), ); } diff --git a/tests/Integration/EventBus/EventBusTesterTest.php b/tests/Integration/EventBus/EventBusTesterTest.php index 1c4c419003..e20a7ec391 100644 --- a/tests/Integration/EventBus/EventBusTesterTest.php +++ b/tests/Integration/EventBus/EventBusTesterTest.php @@ -56,14 +56,10 @@ public function assert_dispatched_with_callback(): void $this->eventBus->preventEventHandling(); $this->bus->dispatch('event-bus-fake-event'); - $this->eventBus->assertDispatched('event-bus-fake-event', function (string $event) { - return $event === 'event-bus-fake-event'; - }); + $this->eventBus->assertDispatched('event-bus-fake-event', fn (string $event) => $event === 'event-bus-fake-event'); $this->bus->dispatch(new FakeEvent('foo')); - $this->eventBus->assertDispatched(FakeEvent::class, function (FakeEvent $event) { - return $event->value === 'foo'; - }); + $this->eventBus->assertDispatched(FakeEvent::class, fn (FakeEvent $event) => $event->value === 'foo'); } #[Test] @@ -108,9 +104,7 @@ public function assert_dispatched_with_callback_failure(): void $this->eventBus->preventEventHandling(); $this->bus->dispatch('event-bus-fake-event'); - $this->eventBus->assertDispatched('event-bus-fake-event', function (string $event) { - return $event !== 'event-bus-fake-event'; - }); + $this->eventBus->assertDispatched('event-bus-fake-event', fn (string $event) => $event !== 'event-bus-fake-event'); } #[Test] @@ -122,9 +116,7 @@ public function assert_dispatched_object_with_callback_failure(): void $this->eventBus->preventEventHandling(); $this->bus->dispatch(new FakeEvent('foo')); - $this->eventBus->assertDispatched(FakeEvent::class, function (FakeEvent $event) { - return $event->value === 'foobar'; - }); + $this->eventBus->assertDispatched(FakeEvent::class, fn (FakeEvent $event) => $event->value === 'foobar'); } #[Test] diff --git a/tests/Integration/Framework/Commands/MetaViewComponentCommandTest.php b/tests/Integration/Framework/Commands/MetaViewComponentCommandTest.php index 7be91e7e82..ad74ad7925 100644 --- a/tests/Integration/Framework/Commands/MetaViewComponentCommandTest.php +++ b/tests/Integration/Framework/Commands/MetaViewComponentCommandTest.php @@ -29,33 +29,33 @@ public function test_show_meta_for_view_component(): void ->assertSee('x-view-component-with-named-slots.view.php') ->assertSee('"name": "x-view-component-with-named-slots",') ->assertSee(<<<'JSON' - "variables": [ - { - "type": "string", - "name": "$title", - "attributeName": "title", - "description": null - }, - { - "type": "\\Tests\\Tempest\\Fixtures\\Modules\\Books\\Models\\Book", - "name": "$book", - "attributeName": "book", - "description": "Any kind of book will work" - }, - { - "type": "string", - "name": "$dataFoo", - "attributeName": "data-foo", - "description": null - } - ] - JSON) + "variables": [ + { + "type": "string", + "name": "$title", + "attributeName": "title", + "description": null + }, + { + "type": "\\Tests\\Tempest\\Fixtures\\Modules\\Books\\Models\\Book", + "name": "$book", + "attributeName": "book", + "description": "Any kind of book will work" + }, + { + "type": "string", + "name": "$dataFoo", + "attributeName": "data-foo", + "description": null + } + ] + JSON) ->assertSee(<<<'JSON' - "slots": [ - "default", - "foo", - "bar" - ], - JSON); + "slots": [ + "default", + "foo", + "bar" + ], + JSON); } } diff --git a/tests/Integration/FrameworkIntegrationTestCase.php b/tests/Integration/FrameworkIntegrationTestCase.php index 87ce6e6560..6a1c91959d 100644 --- a/tests/Integration/FrameworkIntegrationTestCase.php +++ b/tests/Integration/FrameworkIntegrationTestCase.php @@ -60,12 +60,10 @@ protected function assertSnippetsMatch(string $expected, string $actual): void protected function assertSameWithoutBackticks(Stringable|string $expected, Stringable|string $actual): void { - $clean = function (string $string): string { - return str($string) - ->replace('`', '') - ->replaceRegex('/AS \"(?.*?)\"/', fn (array $matches) => "AS {$matches['alias']}") - ->toString(); - }; + $clean = fn (string $string): string => str($string) + ->replace('`', '') + ->replaceRegex('/AS \"(?.*?)\"/', fn (array $matches) => "AS {$matches['alias']}") + ->toString(); $this->assertSame( $clean((string) $expected), diff --git a/tests/Integration/Http/CleanupSessionsCommandTest.php b/tests/Integration/Http/CleanupSessionsCommandTest.php index ded6c52a9c..982297fb45 100644 --- a/tests/Integration/Http/CleanupSessionsCommandTest.php +++ b/tests/Integration/Http/CleanupSessionsCommandTest.php @@ -28,8 +28,8 @@ public function destroy_sessions(): void $clock = $this->clock('2024-01-01 00:00:00'); $this->container->config(new FileSessionConfig( - path: 'tests/sessions', expiration: Duration::seconds(10), + path: 'tests/sessions', )); $sessionManager = $this->container->get(SessionManager::class); diff --git a/tests/Integration/Http/DatabaseSessionTest.php b/tests/Integration/Http/DatabaseSessionTest.php index 17cb0457da..f6315c2a45 100644 --- a/tests/Integration/Http/DatabaseSessionTest.php +++ b/tests/Integration/Http/DatabaseSessionTest.php @@ -8,6 +8,7 @@ use PHPUnit\Framework\Attributes\Test; use Tempest\Clock\Clock; use Tempest\Database\Migrations\CreateMigrationsTable; +use Tempest\DateTime\DateTime; use Tempest\DateTime\Duration; use Tempest\Http\Session\Config\DatabaseSessionConfig; use Tempest\Http\Session\Installer\CreateSessionsTable; @@ -270,7 +271,7 @@ private function assertSessionDataInDatabase(SessionId $sessionId, array $data): } } - private function getSessionLastActiveTimestamp(SessionId $sessionId): \Tempest\DateTime\DateTime + private function getSessionLastActiveTimestamp(SessionId $sessionId): DateTime { $session = query(DatabaseSession::class) ->select() diff --git a/tests/Integration/Http/Exceptions/ExceptionRendererTest.php b/tests/Integration/Http/Exceptions/ExceptionRendererTest.php index 653695a589..2b7cde3b97 100644 --- a/tests/Integration/Http/Exceptions/ExceptionRendererTest.php +++ b/tests/Integration/Http/Exceptions/ExceptionRendererTest.php @@ -201,9 +201,7 @@ private function callExceptionHandler(Closure $callback): void } } -final class CustomValidationException extends Exception -{ -} +final class CustomValidationException extends Exception {} #[Priority(Priority::HIGH)] final readonly class CustomJsonValidationRenderer implements ExceptionRenderer diff --git a/tests/Integration/Http/FileSessionTest.php b/tests/Integration/Http/FileSessionTest.php index eb87ddb835..2e624e4f87 100644 --- a/tests/Integration/Http/FileSessionTest.php +++ b/tests/Integration/Http/FileSessionTest.php @@ -45,8 +45,8 @@ protected function configure(): void $this->container->get(FrameworkKernel::class)->internalStorage = realpath($this->path); $this->container->config(new FileSessionConfig( - path: 'sessions', expiration: Duration::hours(2), + path: 'sessions', )); $this->container->singleton(SessionManager::class, fn () => new FileSessionManager( @@ -160,8 +160,8 @@ public function is_valid_checks_expiration(): void $clock = $this->clock('2025-01-01 00:00:00'); $this->container->config(new FileSessionConfig( - path: 'test_sessions', expiration: Duration::seconds(10), + path: 'test_sessions', )); $session = $this->manager->getOrCreate(new SessionId('expiration_test')); @@ -185,8 +185,8 @@ public function delete_expired_sessions_removes_old_files(): void $clock = $this->clock('2023-01-01 00:00:00'); $this->container->config(new FileSessionConfig( - path: 'test_sessions', expiration: Duration::minutes(30), + path: 'test_sessions', )); $active = $this->manager->getOrCreate(new SessionId('active')); diff --git a/tests/Integration/Http/SessionFromCookieTest.php b/tests/Integration/Http/SessionFromCookieTest.php index 50f009dea3..7e3b8a6393 100644 --- a/tests/Integration/Http/SessionFromCookieTest.php +++ b/tests/Integration/Http/SessionFromCookieTest.php @@ -18,8 +18,8 @@ final class SessionFromCookieTest extends FrameworkIntegrationTestCase public function test_resolving_session_from_cookie(): void { $this->container->config(new FileSessionConfig( - path: 'test_sessions', expiration: Duration::hours(2), + path: 'test_sessions', )); $cookieManager = $this->container->get(CookieManager::class); @@ -38,8 +38,8 @@ public function test_cookie_expiration(): void $clock = $this->clock('2023-01-01 00:00:00'); $this->container->config(new FileSessionConfig( - path: 'test_sessions', expiration: Duration::second(), + path: 'test_sessions', )); // Resolve the session so that the ID is set diff --git a/tests/Integration/Icon/IconTest.php b/tests/Integration/Icon/IconTest.php index a5b040b79c..5ad73e2c3b 100644 --- a/tests/Integration/Icon/IconTest.php +++ b/tests/Integration/Icon/IconTest.php @@ -14,6 +14,7 @@ use Tempest\Http\Status; use Tempest\HttpClient\HttpClient; use Tempest\Icon; +use Tempest\Icon\IconCache; use Tempest\Icon\IconConfig; use Tempest\Icon\IconDownloaded; use Tempest\Icon\IconDownloadFailed; @@ -68,7 +69,7 @@ public function test_failure_retry_after(): void serverHits: $this->exactly(2), ); - $iconCache = $this->container->get(Icon\IconCache::class); + $iconCache = $this->container->get(IconCache::class); $icon = $this->container->get(Icon\Icon::class); // first fetch, we cache the failure @@ -136,7 +137,7 @@ private function registerMocks( $this->container->register(HttpClient::class, fn () => $mockHttpClient); - $this->container->singleton(Icon\IconCache::class, new Icon\IconCache( + $this->container->singleton(IconCache::class, new IconCache( enabled: true, pool: new ArrayAdapter(clock: $clock?->toPsrClock()), )); diff --git a/tests/Integration/Intl/FunctionsTest.php b/tests/Integration/Intl/FunctionsTest.php index 2a6ec3e5fa..fe8524d465 100644 --- a/tests/Integration/Intl/FunctionsTest.php +++ b/tests/Integration/Intl/FunctionsTest.php @@ -7,6 +7,7 @@ use Countable; use PHPUnit\Framework\Attributes\TestWith; use Tempest\Intl; +use Tempest\Intl\Locale; use Tests\Tempest\Integration\FrameworkIntegrationTestCase; /** @@ -48,6 +49,6 @@ public function test_pluralize_last_word(): void public function test_current_locale(): void { - $this->assertSame(Intl\Locale::ENGLISH_UNITED_STATES, Intl\current_locale()); + $this->assertSame(Locale::ENGLISH_UNITED_STATES, Intl\current_locale()); } } diff --git a/tests/Integration/KeyValue/RedisTest.php b/tests/Integration/KeyValue/RedisTest.php index 2a756ba197..009c0390b0 100644 --- a/tests/Integration/KeyValue/RedisTest.php +++ b/tests/Integration/KeyValue/RedisTest.php @@ -29,7 +29,7 @@ protected function configure(): void try { $this->redis->connect(); - } catch (\Throwable) { + } catch (Throwable) { $this->markTestSkipped('Could not connect to Redis.'); } } diff --git a/tests/Integration/Mailer/SentEmailTest.php b/tests/Integration/Mailer/SentEmailTest.php index 79e4b01680..39d396cb98 100644 --- a/tests/Integration/Mailer/SentEmailTest.php +++ b/tests/Integration/Mailer/SentEmailTest.php @@ -68,10 +68,11 @@ public function test_with_default_sender(): void public function test_send_to_address_vo(): void { - $this->sendTestEmail( - to: [new EmailAddress('recipient1@example.com', 'Jon Doe'), 'recipient2@example.com'], - from: 'no-reply@tempestphp.com', - ) + $this + ->sendTestEmail( + to: [new EmailAddress('recipient1@example.com', 'Jon Doe'), 'recipient2@example.com'], + from: 'no-reply@tempestphp.com', + ) ->assertSentTo('recipient1@example.com') ->assertSentTo('recipient2@example.com'); } @@ -89,10 +90,11 @@ public function test_send_to_address_with_brackets(): void public function test_assert_sent_to(): void { - $this->sendTestEmail( - to: ['recipient1@example.com', 'recipient2@example.com'], - from: 'no-reply@tempestphp.com', - ) + $this + ->sendTestEmail( + to: ['recipient1@example.com', 'recipient2@example.com'], + from: 'no-reply@tempestphp.com', + ) ->assertSentTo('recipient1@example.com') ->assertSentTo('recipient2@example.com') ->assertSentTo(['recipient1@example.com', 'recipient2@example.com']) @@ -205,12 +207,12 @@ private function sendTestEmail( $content = match (true) { $html instanceof View => $html, $html !== null => << - -

{$html}

- - - HTML_WRAP, + + +

{$html}

+ + + HTML_WRAP, $text !== null => $text, default => 'Hello Jon in Text', }; diff --git a/tests/Integration/Mapper/Fixtures/SerializableObject.php b/tests/Integration/Mapper/Fixtures/SerializableObject.php index 3c61c6a39d..4f1a29b118 100644 --- a/tests/Integration/Mapper/Fixtures/SerializableObject.php +++ b/tests/Integration/Mapper/Fixtures/SerializableObject.php @@ -6,11 +6,7 @@ final class SerializableObject implements Serializable { - /* - * @mago-expect lint:return-type - * @phpstan-ignore return.unusedType - */ - public function serialize() + public function serialize(): string { return 'a'; } diff --git a/tests/Integration/Mapper/MapperContextTest.php b/tests/Integration/Mapper/MapperContextTest.php index 66f58e2376..46117d97a3 100644 --- a/tests/Integration/Mapper/MapperContextTest.php +++ b/tests/Integration/Mapper/MapperContextTest.php @@ -6,6 +6,12 @@ use PHPUnit\Framework\Attributes\TestWith; use Tempest\Core\Priority; use Tempest\Mapper; +use Tempest\Mapper\Caster; +use Tempest\Mapper\CasterFactory; +use Tempest\Mapper\DynamicCaster; +use Tempest\Mapper\DynamicSerializer; +use Tempest\Mapper\Serializer; +use Tempest\Mapper\SerializerFactory; use Tempest\Reflection\PropertyReflector; use Tempest\Reflection\TypeReflector; use Tests\Tempest\Fixtures\Modules\Books\Models\Author; @@ -36,8 +42,8 @@ public function uses_serializers_from_given_context(mixed $context): void name: 'test', ); - $factory = $this->container->get(Mapper\SerializerFactory::class); - $factory->addSerializer(CustomStringSerializer::class, context: $context, priority: Priority::HIGHEST); + $factory = $this->container->get(SerializerFactory::class); + $factory->addSerializer(CustomStringSerializer::class, priority: Priority::HIGHEST, context: $context); $serialized = Mapper\map($author) ->in($context) @@ -51,7 +57,7 @@ public function uses_serializers_from_given_context(mixed $context): void #[TestWith([TestMapperContextEnum::VALUE], name: 'enum')] public function uses_casters_from_given_context(mixed $context): void { - $factory = $this->container->get(Mapper\CasterFactory::class); + $factory = $this->container->get(CasterFactory::class); $factory->addCaster(CustomStringSerializer::class, context: $context); $author = Mapper\make(Author::class) @@ -64,7 +70,7 @@ public function uses_casters_from_given_context(mixed $context): void } } -final readonly class CustomStringSerializer implements Mapper\Serializer, Mapper\Caster, Mapper\DynamicSerializer, Mapper\DynamicCaster +final readonly class CustomStringSerializer implements Serializer, Caster, DynamicSerializer, DynamicCaster { public static function accepts(PropertyReflector|TypeReflector $input): bool { diff --git a/tests/Integration/Process/ProcessTesterAssertNotRanTest.php b/tests/Integration/Process/ProcessTesterAssertNotRanTest.php index 61e992a6af..03a6e07b29 100644 --- a/tests/Integration/Process/ProcessTesterAssertNotRanTest.php +++ b/tests/Integration/Process/ProcessTesterAssertNotRanTest.php @@ -30,10 +30,10 @@ public function test_succeeds_with_callback_when_other_commands_ran(): void $this->process->mockProcessResult('echo *', 'hello'); $this->executor->run('echo "hello"'); - $this->process->assertCommandDidNotRun(function (PendingProcess $process) { + $this->process->assertCommandDidNotRun( // this returns false, so expectation succeeds - return $process->command === 'echo "world"'; - }); + fn (PendingProcess $process) => $process->command === 'echo "world"', + ); } public function test_fails_with_callback_when_returning_false(): void @@ -44,9 +44,9 @@ public function test_fails_with_callback_when_returning_false(): void $this->process->mockProcessResult('echo *', 'hello'); $this->executor->run('echo "hello"'); - $this->process->assertCommandDidNotRun(function (PendingProcess $process) { + $this->process->assertCommandDidNotRun( // this returns true, so expectation fails - return $process->command === 'echo "hello"'; - }); + fn (PendingProcess $process) => $process->command === 'echo "hello"', + ); } } diff --git a/tests/Integration/Process/ProcessTesterAssertRanTest.php b/tests/Integration/Process/ProcessTesterAssertRanTest.php index 3e0472bec7..0048d2e74a 100644 --- a/tests/Integration/Process/ProcessTesterAssertRanTest.php +++ b/tests/Integration/Process/ProcessTesterAssertRanTest.php @@ -29,9 +29,7 @@ public function test_expectation_succeeds_when_command_is_ran_and_callback_retur { $this->process->mockProcessResult('echo *', "hello\n"); $this->executor->run('echo "hello"'); - $this->process->assertCommandRan('echo *', function (ProcessResult $result) { - return $result->output === "hello\n"; - }); + $this->process->assertCommandRan('echo *', fn (ProcessResult $result) => $result->output === "hello\n"); } public function test_expectation_fails_when_specified_command_is_not_ran(): void @@ -51,9 +49,7 @@ public function test_expectation_fails_when_command_is_ran_and_callback_returns_ $this->process->mockProcessResult('echo *', "hello\n"); $this->executor->run('echo "hello"'); - $this->process->assertCommandRan('echo *', function (ProcessResult $result) { - return $result->output !== "hello\n"; - }); + $this->process->assertCommandRan('echo *', fn (ProcessResult $result) => $result->output !== "hello\n"); } public function test_expectation_succeeds_when_callback_returns_nothing(): void @@ -68,9 +64,7 @@ public function test_expectation_succeeds_when_callback_returns_true(): void $this->process->mockProcessResult('echo *', "hello\n"); $this->executor->run('echo "hello"'); - $this->process->assertRan(function (PendingProcess $process): bool { - return $process->command === 'echo "hello"'; - }); + $this->process->assertRan(fn (PendingProcess $process): bool => $process->command === 'echo "hello"'); } public function test_returning_false_from_callback_fails_expectation(): void @@ -81,9 +75,7 @@ public function test_returning_false_from_callback_fails_expectation(): void $this->process->mockProcessResult('echo *', "hello\n"); $this->executor->run('echo "hello"'); - $this->process->assertRan(function (PendingProcess $_process): bool { - return false; - }); + $this->process->assertRan(fn (PendingProcess $_process): bool => false); } public function test_returning_true_from_callback_skips_other_iterations(): void diff --git a/tests/Integration/Route/ClientTest.php b/tests/Integration/Route/ClientTest.php index e5e93dbf18..f8ccf0357d 100644 --- a/tests/Integration/Route/ClientTest.php +++ b/tests/Integration/Route/ClientTest.php @@ -31,7 +31,7 @@ protected function setUp(): void $this->server->start(); // Server needs to start - usleep(100000); + usleep(100_000); // We'll use the client interface directly because we want to write raw post data in this test $this->driver = $this->container->get(ClientInterface::class); diff --git a/tests/Integration/Route/RequestToObjectMapperTest.php b/tests/Integration/Route/RequestToObjectMapperTest.php index 176ccc11f6..2e56801144 100644 --- a/tests/Integration/Route/RequestToObjectMapperTest.php +++ b/tests/Integration/Route/RequestToObjectMapperTest.php @@ -81,7 +81,7 @@ public function test_query_params_with_types(): void $this->assertSame(1, $request->intParam); $this->assertSame('a', $request->stringParam); - $this->assertSame(true, $request->boolParam); + $this->assertTrue($request->boolParam); $this->assertSame(0.1, $request->floatParam); } diff --git a/tests/Integration/Validator/ExistsRuleTest.php b/tests/Integration/Validator/ExistsRuleTest.php index c4f328521f..fe0d38849a 100644 --- a/tests/Integration/Validator/ExistsRuleTest.php +++ b/tests/Integration/Validator/ExistsRuleTest.php @@ -45,8 +45,8 @@ public function non_existent_record_returns_false(): void { Book::create(title: 'Timeline Taxi'); - $this->assertFalse(new Exists(Book::class)->isValid(99999)); - $this->assertFalse(new Exists(Book::class)->isValid(12345)); + $this->assertFalse(new Exists(Book::class)->isValid(99_999)); + $this->assertFalse(new Exists(Book::class)->isValid(12_345)); $this->assertFalse(new Exists(Book::class, column: 'title')->isValid('Timeline Taxi 2')); } @@ -60,6 +60,6 @@ public function validates_multiple_existing_records(): void $this->assertTrue(new Exists(Book::class)->isValid($book1->id)); $this->assertTrue(new Exists(Book::class)->isValid($book2->id)); $this->assertTrue(new Exists(Book::class)->isValid($book3->id)); - $this->assertFalse(new Exists(Book::class)->isValid(99999)); + $this->assertFalse(new Exists(Book::class)->isValid(99_999)); } } diff --git a/tests/Integration/Validator/TranslationKeyTest.php b/tests/Integration/Validator/TranslationKeyTest.php index 52bafe0ed0..20de2461ed 100644 --- a/tests/Integration/Validator/TranslationKeyTest.php +++ b/tests/Integration/Validator/TranslationKeyTest.php @@ -7,6 +7,7 @@ use Tempest\Intl\Locale; use Tempest\Validation\Exceptions\ValidationFailed; use Tempest\Validation\Rules; +use Tempest\Validation\Rules\HasLength; use Tempest\Validation\TranslationKey; use Tempest\Validation\Validator; use Tests\Tempest\Integration\FrameworkIntegrationTestCase; @@ -35,7 +36,7 @@ public function translates_property_key(): void final class ValidatableObject { public function __construct( - #[Rules\HasLength(min: 5, max: 50)] + #[HasLength(min: 5, max: 50)] #[TranslationKey('book_title')] public string $title, ) {} diff --git a/tests/Integration/Validator/TranslationsTest.php b/tests/Integration/Validator/TranslationsTest.php index e2e0691e8f..1553cba1e6 100644 --- a/tests/Integration/Validator/TranslationsTest.php +++ b/tests/Integration/Validator/TranslationsTest.php @@ -6,6 +6,55 @@ use Tempest\DateTime\FormatPattern; use Tempest\Validation\Rule; use Tempest\Validation\Rules; +use Tempest\Validation\Rules\DoesNotEndWith; +use Tempest\Validation\Rules\DoesNotStartWith; +use Tempest\Validation\Rules\EndsWith; +use Tempest\Validation\Rules\Exists; +use Tempest\Validation\Rules\HasCount; +use Tempest\Validation\Rules\HasDateTimeFormat; +use Tempest\Validation\Rules\HasLength; +use Tempest\Validation\Rules\IsAfterDate; +use Tempest\Validation\Rules\IsAlpha; +use Tempest\Validation\Rules\IsAlphaNumeric; +use Tempest\Validation\Rules\IsArrayList; +use Tempest\Validation\Rules\IsBeforeDate; +use Tempest\Validation\Rules\IsBetween; +use Tempest\Validation\Rules\IsBetweenDates; +use Tempest\Validation\Rules\IsBoolean; +use Tempest\Validation\Rules\IsDivisibleBy; +use Tempest\Validation\Rules\IsEmail; +use Tempest\Validation\Rules\IsEnum; +use Tempest\Validation\Rules\IsEvenNumber; +use Tempest\Validation\Rules\IsFalsy; +use Tempest\Validation\Rules\IsFloat; +use Tempest\Validation\Rules\IsHexColor; +use Tempest\Validation\Rules\IsIn; +use Tempest\Validation\Rules\IsInteger; +use Tempest\Validation\Rules\IsIP; +use Tempest\Validation\Rules\IsIPv4; +use Tempest\Validation\Rules\IsIPv6; +use Tempest\Validation\Rules\IsJsonString; +use Tempest\Validation\Rules\IsLowercase; +use Tempest\Validation\Rules\IsMacAddress; +use Tempest\Validation\Rules\IsMultipleOf; +use Tempest\Validation\Rules\IsNotEmptyString; +use Tempest\Validation\Rules\IsNotIn; +use Tempest\Validation\Rules\IsNotNull; +use Tempest\Validation\Rules\IsNumeric; +use Tempest\Validation\Rules\IsOddNumber; +use Tempest\Validation\Rules\IsPassword; +use Tempest\Validation\Rules\IsPhoneNumber; +use Tempest\Validation\Rules\IsString; +use Tempest\Validation\Rules\IsTime; +use Tempest\Validation\Rules\IsTimezone; +use Tempest\Validation\Rules\IsTruthy; +use Tempest\Validation\Rules\IsUlid; +use Tempest\Validation\Rules\IsUnixTimestamp; +use Tempest\Validation\Rules\IsUppercase; +use Tempest\Validation\Rules\IsUrl; +use Tempest\Validation\Rules\IsUuid; +use Tempest\Validation\Rules\MatchesRegEx; +use Tempest\Validation\Rules\StartsWith; use Tempest\Validation\Validator; use Tests\Tempest\Integration\FrameworkIntegrationTestCase; @@ -29,12 +78,12 @@ public function test_after_date(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be after or equal to January 1, 2024', $field, expected: 'Date'), - actual: $this->translate(new Rules\IsAfterDate(date: '2024-01-01', inclusive: true), field: $field), + actual: $this->translate(new IsAfterDate(date: '2024-01-01', inclusive: true), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must be after January 1, 2024', $field, expected: 'Date'), - actual: $this->translate(new Rules\IsAfterDate(date: '2024-01-01', inclusive: false), field: $field), + actual: $this->translate(new IsAfterDate(date: '2024-01-01', inclusive: false), field: $field), ); } @@ -44,12 +93,12 @@ public function test_before_date(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be a date before or equal to January 1, 2024', $field, expected: 'Date'), - actual: $this->translate(new Rules\IsBeforeDate(date: '2024-01-01', inclusive: true), field: $field), + actual: $this->translate(new IsBeforeDate(date: '2024-01-01', inclusive: true), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must be a date before January 1, 2024', $field, expected: 'Date'), - actual: $this->translate(new Rules\IsBeforeDate(date: '2024-01-01', inclusive: false), field: $field), + actual: $this->translate(new IsBeforeDate(date: '2024-01-01', inclusive: false), field: $field), ); } @@ -59,12 +108,12 @@ public function test_between_dates(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be a date between January 1, 2024 and January 1, 2025, included', $field, expected: 'Date'), - actual: $this->translate(new Rules\IsBetweenDates(first: '2024-01-01', second: '2025-01-01', inclusive: true), field: $field), + actual: $this->translate(new IsBetweenDates(first: '2024-01-01', second: '2025-01-01', inclusive: true), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must be a date between January 1, 2024 and January 1, 2025', $field, expected: 'Date'), - actual: $this->translate(new Rules\IsBetweenDates(first: '2024-01-01', second: '2025-01-01'), field: $field), + actual: $this->translate(new IsBetweenDates(first: '2024-01-01', second: '2025-01-01'), field: $field), ); } @@ -74,7 +123,7 @@ public function test_alpha(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must contain only alphabetic characters', $field), - actual: $this->translate(new Rules\IsAlpha(), field: $field), + actual: $this->translate(new IsAlpha(), field: $field), ); } @@ -84,7 +133,7 @@ public function test_alpha_numeric(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must contain only alphanumeric characters', $field), - actual: $this->translate(new Rules\IsAlphaNumeric(), field: $field), + actual: $this->translate(new IsAlphaNumeric(), field: $field), ); } @@ -94,7 +143,7 @@ public function test_array_list(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be a list', $field), - actual: $this->translate(new Rules\IsArrayList(), field: $field), + actual: $this->translate(new IsArrayList(), field: $field), ); } @@ -104,12 +153,12 @@ public function test_between(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be between 0 and 2', $field, expected: 'Number'), - actual: $this->translate(new Rules\IsBetween(min: 0, max: 2), field: $field), + actual: $this->translate(new IsBetween(min: 0, max: 2), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must be between 2 and 4', $field, expected: 'Number'), - actual: $this->translate(new Rules\IsBetween(min: 2, max: 4), field: $field), + actual: $this->translate(new IsBetween(min: 2, max: 4), field: $field), ); } @@ -119,27 +168,27 @@ public function test_count(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must have at least 3 items', $field), - actual: $this->translate(new Rules\HasCount(min: 3), field: $field), + actual: $this->translate(new HasCount(min: 3), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must have at least 0 items', $field), - actual: $this->translate(new Rules\HasCount(min: 0), field: $field), + actual: $this->translate(new HasCount(min: 0), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must have at most 10 items', $field), - actual: $this->translate(new Rules\HasCount(max: 10), field: $field), + actual: $this->translate(new HasCount(max: 10), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must have between 3 and 10 items', $field), - actual: $this->translate(new Rules\HasCount(min: 3, max: 10), field: $field), + actual: $this->translate(new HasCount(min: 3, max: 10), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must have between 0 and 2 items', $field), - actual: $this->translate(new Rules\HasCount(min: 0, max: 2), field: $field), + actual: $this->translate(new HasCount(min: 0, max: 2), field: $field), ); } @@ -149,12 +198,12 @@ public function test_date_time_format(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must use the format yyyy-MM-dd', $field), - actual: $this->translate(new Rules\HasDateTimeFormat('yyyy-MM-dd'), field: $field), + actual: $this->translate(new HasDateTimeFormat('yyyy-MM-dd'), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must use the format MM/dd/yyyy', $field), - actual: $this->translate(new Rules\HasDateTimeFormat(FormatPattern::AMERICAN), field: $field), + actual: $this->translate(new HasDateTimeFormat(FormatPattern::AMERICAN), field: $field), ); } @@ -164,7 +213,7 @@ public function test_divisible_by(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be divisible by 1', $field, expected: 'Number'), - actual: $this->translate(new Rules\IsDivisibleBy(divisor: 1), field: $field), + actual: $this->translate(new IsDivisibleBy(divisor: 1), field: $field), ); } @@ -174,7 +223,7 @@ public function test_does_not_end_with(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must not end with "foo"', $field), - actual: $this->translate(new Rules\DoesNotEndWith(needle: 'foo'), field: $field), + actual: $this->translate(new DoesNotEndWith(needle: 'foo'), field: $field), ); } @@ -184,7 +233,7 @@ public function test_email(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be a valid email address', $field, expected: 'Email'), - actual: $this->translate(new Rules\IsEmail(), field: $field), + actual: $this->translate(new IsEmail(), field: $field), ); } @@ -194,7 +243,7 @@ public function test_does_not_start_with(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must not start with "foo"', $field), - actual: $this->translate(new Rules\DoesNotStartWith(needle: 'foo'), field: $field), + actual: $this->translate(new DoesNotStartWith(needle: 'foo'), field: $field), ); } @@ -204,7 +253,7 @@ public function test_ends_with(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must end with "foo"', $field), - actual: $this->translate(new Rules\EndsWith(needle: 'foo'), field: $field), + actual: $this->translate(new EndsWith(needle: 'foo'), field: $field), ); } @@ -214,7 +263,7 @@ public function test_exists(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s could not be found', $field), - actual: $this->translate(new Rules\Exists(table: 'non-existing-table', column: 'non-existing-column'), field: $field), + actual: $this->translate(new Exists(table: 'non-existing-table', column: 'non-existing-column'), field: $field), ); } @@ -224,7 +273,7 @@ public function test_even(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be even', $field, expected: 'Number'), - actual: $this->translate(new Rules\IsEvenNumber(), field: $field), + actual: $this->translate(new IsEvenNumber(), field: $field), ); } @@ -234,7 +283,7 @@ public function test_hex_color(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be a hexadecimal color', $field), - actual: $this->translate(new Rules\IsHexColor(), field: $field), + actual: $this->translate(new IsHexColor(), field: $field), ); } @@ -244,17 +293,17 @@ public function test_in(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be a', $field), - actual: $this->translate(new Rules\IsIn(['a']), field: $field), + actual: $this->translate(new IsIn(['a']), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must be a or b', $field), - actual: $this->translate(new Rules\IsIn(['a', 'b']), field: $field), + actual: $this->translate(new IsIn(['a', 'b']), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must be a, b or c', $field), - actual: $this->translate(new Rules\IsIn(['a', 'b', 'c']), field: $field), + actual: $this->translate(new IsIn(['a', 'b', 'c']), field: $field), ); } @@ -267,9 +316,9 @@ public function test_in(?string $field = null): void public function test_ip(string $ip, ?string $field = null): void { $class = match ($ip) { - 'IPv4' => Rules\IsIPv4::class, - 'IPv6' => Rules\IsIPv6::class, - default => Rules\IsIP::class, + 'IPv4' => IsIPv4::class, + 'IPv6' => IsIPv6::class, + default => IsIP::class, }; $this->assertSame( @@ -299,12 +348,12 @@ public function test_is_boolean(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be a boolean', $field), - actual: $this->translate(new Rules\IsBoolean(), field: $field), + actual: $this->translate(new IsBoolean(), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must be a boolean if specified', $field), - actual: $this->translate(new Rules\IsBoolean(orNull: true), field: $field), + actual: $this->translate(new IsBoolean(orNull: true), field: $field), ); } @@ -314,22 +363,22 @@ public function test_is_enum(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be FOO, BAR or BAZ', $field), - actual: $this->translate(new Rules\IsEnum(UnitEnumFixture::class), field: $field), + actual: $this->translate(new IsEnum(UnitEnumFixture::class), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must be FOO or BAZ', $field), - actual: $this->translate(new Rules\IsEnum(UnitEnumFixture::class, except: [UnitEnumFixture::BAR]), field: $field), + actual: $this->translate(new IsEnum(UnitEnumFixture::class, except: [UnitEnumFixture::BAR]), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must be foo, bar or baz', $field), - actual: $this->translate(new Rules\IsEnum(BackedEnumFixture::class), field: $field), + actual: $this->translate(new IsEnum(BackedEnumFixture::class), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must be foo or baz', $field), - actual: $this->translate(new Rules\IsEnum(BackedEnumFixture::class, except: [BackedEnumFixture::BAR]), field: $field), + actual: $this->translate(new IsEnum(BackedEnumFixture::class, except: [BackedEnumFixture::BAR]), field: $field), ); } @@ -339,12 +388,12 @@ public function test_is_float(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be a floating point number', $field), - actual: $this->translate(new Rules\IsFloat(), field: $field), + actual: $this->translate(new IsFloat(), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must be a floating point number if specified', $field), - actual: $this->translate(new Rules\IsFloat(orNull: true), field: $field), + actual: $this->translate(new IsFloat(orNull: true), field: $field), ); } @@ -354,12 +403,12 @@ public function test_is_integer(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be a number', $field), - actual: $this->translate(new Rules\IsInteger(), field: $field), + actual: $this->translate(new IsInteger(), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must be a number if specified', $field), - actual: $this->translate(new Rules\IsInteger(orNull: true), field: $field), + actual: $this->translate(new IsInteger(orNull: true), field: $field), ); } @@ -369,12 +418,12 @@ public function test_is_string(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be a string', $field), - actual: $this->translate(new Rules\IsString(), field: $field), + actual: $this->translate(new IsString(), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must be a string or be empty', $field), - actual: $this->translate(new Rules\IsString(orNull: true), field: $field), + actual: $this->translate(new IsString(orNull: true), field: $field), ); } @@ -384,7 +433,7 @@ public function test_is_json(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be a valid JSON string', $field), - actual: $this->translate(new Rules\IsJsonString(), field: $field), + actual: $this->translate(new IsJsonString(), field: $field), ); } @@ -394,17 +443,17 @@ public function test_length(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be at least 0', $field), - actual: $this->translate(new Rules\HasLength(min: 0), field: $field), + actual: $this->translate(new HasLength(min: 0), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must be at most 0', $field), - actual: $this->translate(new Rules\HasLength(max: 0), field: $field), + actual: $this->translate(new HasLength(max: 0), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must be between 0 and 2', $field), - actual: $this->translate(new Rules\HasLength(min: 0, max: 2), field: $field), + actual: $this->translate(new HasLength(min: 0, max: 2), field: $field), ); } @@ -414,7 +463,7 @@ public function test_lowercase(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be a lowercase string', $field), - actual: $this->translate(new Rules\IsLowercase(), field: $field), + actual: $this->translate(new IsLowercase(), field: $field), ); } @@ -424,7 +473,7 @@ public function test_mac_address(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be a valid MAC address', $field), - actual: $this->translate(new Rules\IsMacAddress(), field: $field), + actual: $this->translate(new IsMacAddress(), field: $field), ); } @@ -434,7 +483,7 @@ public function test_multiple_of(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be a multiple of 5', $field, expected: 'Number'), - actual: $this->translate(new Rules\IsMultipleOf(divisor: 5), field: $field), + actual: $this->translate(new IsMultipleOf(divisor: 5), field: $field), ); } @@ -444,7 +493,7 @@ public function test_not_empty(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must not be empty', $field), - actual: $this->translate(new Rules\IsNotEmptyString(), field: $field), + actual: $this->translate(new IsNotEmptyString(), field: $field), ); } @@ -454,17 +503,17 @@ public function test_not_in(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must not be a', $field), - actual: $this->translate(new Rules\IsNotIn(['a']), field: $field), + actual: $this->translate(new IsNotIn(['a']), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must not be a or b', $field), - actual: $this->translate(new Rules\IsNotIn(['a', 'b']), field: $field), + actual: $this->translate(new IsNotIn(['a', 'b']), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must not be a, b or c', $field), - actual: $this->translate(new Rules\IsNotIn(['a', 'b', 'c']), field: $field), + actual: $this->translate(new IsNotIn(['a', 'b', 'c']), field: $field), ); } @@ -474,7 +523,7 @@ public function test_not_null(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be specified', $field), - actual: $this->translate(new Rules\IsNotNull(), field: $field), + actual: $this->translate(new IsNotNull(), field: $field), ); } @@ -484,7 +533,7 @@ public function test_numeric(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be numeric', $field), - actual: $this->translate(new Rules\IsNumeric(), field: $field), + actual: $this->translate(new IsNumeric(), field: $field), ); } @@ -494,7 +543,7 @@ public function test_odd(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be odd', $field, expected: 'Number'), - actual: $this->translate(new Rules\IsOddNumber(), field: $field), + actual: $this->translate(new IsOddNumber(), field: $field), ); } @@ -504,32 +553,32 @@ public function test_password(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must contain at least 12 characters', $field, expected: 'Password'), - actual: $this->translate(new Rules\IsPassword(), field: $field), + actual: $this->translate(new IsPassword(), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must contain at least 4 characters', $field, expected: 'Password'), - actual: $this->translate(new Rules\IsPassword(min: 4), field: $field), + actual: $this->translate(new IsPassword(min: 4), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must contain at least 12 characters, one uppercase and one lowercase letter', $field, expected: 'Password'), - actual: $this->translate(new Rules\IsPassword(mixedCase: true), field: $field), + actual: $this->translate(new IsPassword(mixedCase: true), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must contain at least 12 characters and one number', $field, expected: 'Password'), - actual: $this->translate(new Rules\IsPassword(numbers: true), field: $field), + actual: $this->translate(new IsPassword(numbers: true), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must contain at least 12 characters and one symbol', $field, expected: 'Password'), - actual: $this->translate(new Rules\IsPassword(symbols: true), field: $field), + actual: $this->translate(new IsPassword(symbols: true), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must contain at least 12 characters and one letter', $field, expected: 'Password'), - actual: $this->translate(new Rules\IsPassword(letters: true), field: $field), + actual: $this->translate(new IsPassword(letters: true), field: $field), ); $this->assertSame( @@ -538,42 +587,42 @@ public function test_password(?string $field = null): void $field, expected: 'Password', ), - actual: $this->translate(new Rules\IsPassword(mixedCase: true, numbers: true, symbols: true), field: $field), + actual: $this->translate(new IsPassword(mixedCase: true, numbers: true, symbols: true), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must contain at least 12 characters, one uppercase and one lowercase letter, and one number', $field, expected: 'Password'), - actual: $this->translate(new Rules\IsPassword(mixedCase: true, numbers: true), field: $field), + actual: $this->translate(new IsPassword(mixedCase: true, numbers: true), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must contain at least 12 characters, one uppercase and one lowercase letter, and one symbol', $field, expected: 'Password'), - actual: $this->translate(new Rules\IsPassword(mixedCase: true, symbols: true), field: $field), + actual: $this->translate(new IsPassword(mixedCase: true, symbols: true), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must contain at least 12 characters, one number, one letter and one symbol', $field, expected: 'Password'), - actual: $this->translate(new Rules\IsPassword(letters: true, numbers: true, symbols: true), field: $field), + actual: $this->translate(new IsPassword(numbers: true, letters: true, symbols: true), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must contain at least 12 characters, one number and one letter', $field, expected: 'Password'), - actual: $this->translate(new Rules\IsPassword(letters: true, numbers: true), field: $field), + actual: $this->translate(new IsPassword(numbers: true, letters: true), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must contain at least 12 characters, one letter and one symbol', $field, expected: 'Password'), - actual: $this->translate(new Rules\IsPassword(letters: true, symbols: true), field: $field), + actual: $this->translate(new IsPassword(letters: true, symbols: true), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must contain at least 12 characters, one number and one symbol', $field, expected: 'Password'), - actual: $this->translate(new Rules\IsPassword(numbers: true, symbols: true), field: $field), + actual: $this->translate(new IsPassword(numbers: true, symbols: true), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must contain at least 12 characters, one number and one letter', $field, expected: 'Password'), - actual: $this->translate(new Rules\IsPassword(letters: true, numbers: true), field: $field), + actual: $this->translate(new IsPassword(numbers: true, letters: true), field: $field), ); } @@ -583,7 +632,7 @@ public function test_phone_number(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be a phone number', $field), - actual: $this->translate(new Rules\IsPhoneNumber(), field: $field), + actual: $this->translate(new IsPhoneNumber(), field: $field), ); } @@ -593,7 +642,7 @@ public function test_regex(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must match the pattern /[A-Z]/', $field), - actual: $this->translate(new Rules\MatchesRegEx('/[A-Z]/'), field: $field), + actual: $this->translate(new MatchesRegEx('/[A-Z]/'), field: $field), ); } @@ -603,7 +652,7 @@ public function test_should_be_false(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be false', $field), - actual: $this->translate(new Rules\IsFalsy(), field: $field), + actual: $this->translate(new IsFalsy(), field: $field), ); } @@ -613,7 +662,7 @@ public function test_should_be_true(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be true', $field), - actual: $this->translate(new Rules\IsTruthy(), field: $field), + actual: $this->translate(new IsTruthy(), field: $field), ); } @@ -623,7 +672,7 @@ public function test_starts_with(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must start with foo', $field), - actual: $this->translate(new Rules\StartsWith('foo'), field: $field), + actual: $this->translate(new StartsWith('foo'), field: $field), ); } @@ -633,12 +682,12 @@ public function test_time(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be a valid time in 24-hour format', $field), - actual: $this->translate(new Rules\IsTime(), field: $field), + actual: $this->translate(new IsTime(), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must be a valid time in 12-hour format', $field), - actual: $this->translate(new Rules\IsTime(false), field: $field), + actual: $this->translate(new IsTime(false), field: $field), ); } @@ -648,7 +697,7 @@ public function test_timestamp(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be a valid timestamp', $field), - actual: $this->translate(new Rules\IsUnixTimestamp(), field: $field), + actual: $this->translate(new IsUnixTimestamp(), field: $field), ); } @@ -658,7 +707,7 @@ public function test_timezone(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be a valid timezone', $field), - actual: $this->translate(new Rules\IsTimezone(), field: $field), + actual: $this->translate(new IsTimezone(), field: $field), ); } @@ -668,7 +717,7 @@ public function test_ulid(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be a lexicographically sortable identifier', $field), - actual: $this->translate(new Rules\IsUlid(), field: $field), + actual: $this->translate(new IsUlid(), field: $field), ); } @@ -678,7 +727,7 @@ public function test_uppercase(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be an uppercase string', $field), - actual: $this->translate(new Rules\IsUppercase(), field: $field), + actual: $this->translate(new IsUppercase(), field: $field), ); } @@ -688,22 +737,22 @@ public function test_url(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be a valid URL', $field), - actual: $this->translate(new Rules\IsUrl(), field: $field), + actual: $this->translate(new IsUrl(), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must be a URL using https', $field), - actual: $this->translate(new Rules\IsUrl(['https']), field: $field), + actual: $this->translate(new IsUrl(['https']), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must be a URL using https or http', $field), - actual: $this->translate(new Rules\IsUrl(['https', 'http']), field: $field), + actual: $this->translate(new IsUrl(['https', 'http']), field: $field), ); $this->assertSame( expected: $this->formatWithField('%s must be a URL using ftp, https or http', $field), - actual: $this->translate(new Rules\IsUrl(['ftp', 'https', 'http']), field: $field), + actual: $this->translate(new IsUrl(['ftp', 'https', 'http']), field: $field), ); } @@ -713,7 +762,7 @@ public function test_uuid(?string $field = null): void { $this->assertSame( expected: $this->formatWithField('%s must be a universally unique identifier', $field), - actual: $this->translate(new Rules\IsUuid(), field: $field), + actual: $this->translate(new IsUuid(), field: $field), ); } } diff --git a/tests/Integration/View/BladeViewRendererTest.php b/tests/Integration/View/BladeViewRendererTest.php index 3aec90c9c1..9492407f9b 100644 --- a/tests/Integration/View/BladeViewRendererTest.php +++ b/tests/Integration/View/BladeViewRendererTest.php @@ -33,10 +33,10 @@ public function test_blade(): void $html = $renderer->render(view('index')); $this->assertSame(<< - Hi - + + Hi + - HTML, $html); + HTML, $html); } } diff --git a/tests/Integration/View/Components/MarkdownComponentTest.php b/tests/Integration/View/Components/MarkdownComponentTest.php index 77faeaaf10..4bf287c907 100644 --- a/tests/Integration/View/Components/MarkdownComponentTest.php +++ b/tests/Integration/View/Components/MarkdownComponentTest.php @@ -9,8 +9,8 @@ final class MarkdownComponentTest extends FrameworkIntegrationTestCase public function test_render_markdown_as_content(): void { $html = $this->view->render(<<<'HTML' - # hi - HTML); + # hi + HTML); $this->assertSame('

hi

', $html); } @@ -18,8 +18,8 @@ public function test_render_markdown_as_content(): void public function test_render_markdown_as_variable(): void { $html = $this->view->render(<<<'HTML' - - HTML, text: '# hi'); + + HTML, text: '# hi'); $this->assertSame('

hi

', $html); } diff --git a/tests/Integration/View/ElementFactoryTest.php b/tests/Integration/View/ElementFactoryTest.php index c9f1aa76a4..603fa90729 100644 --- a/tests/Integration/View/ElementFactoryTest.php +++ b/tests/Integration/View/ElementFactoryTest.php @@ -24,16 +24,16 @@ public function test_parental_relations(): void { // See https://github.com/php/php-src/issues/16960 $contents = <<<'HTML' - - - - Hello - - - - - - HTML; + + + + Hello + + + + + + HTML; $ast = TempestViewParser::ast($contents); diff --git a/tests/Integration/View/TempestViewRendererCombinedExpressionsTest.php b/tests/Integration/View/TempestViewRendererCombinedExpressionsTest.php index 57389816ac..6368562107 100644 --- a/tests/Integration/View/TempestViewRendererCombinedExpressionsTest.php +++ b/tests/Integration/View/TempestViewRendererCombinedExpressionsTest.php @@ -24,44 +24,44 @@ protected function setUp(): void public function test_if_with_data_expression(): void { $view = <<<'HTML' - - {{ $label }} - - - {{ $label }} - -
Nothing
- HTML; + + {{ $label }} + + + {{ $label }} + +
Nothing
+ HTML; $html = $this->view->render(view($view, href: '#', label: 'Label')); $this->assertStringEqualsStringIgnoringLineEndings(<<<'HTML' - - Label - HTML, $html); + + Label + HTML, $html); $html = $this->view->render(view($view, label: 'Label')); $this->assertStringEqualsStringIgnoringLineEndings(<<<'HTML' - - Label - HTML, $html); + + Label + HTML, $html); $html = $this->view->render(view($view)); $this->assertStringEqualsStringIgnoringLineEndings(<<<'HTML' -
Nothing
- HTML, $html); +
Nothing
+ HTML, $html); } public function test_foreach_with_if_and_else_expression(): void { $view = <<<'HTML' -
- {{ $label }} {{ $item }} -
- - No label - - HTML; +
+ {{ $label }} {{ $item }} +
+ + No label + + HTML; $html = $this->view->render(view($view, items: ['a', 'b'], label: 'Label')); $this->assertStringContainsString('Label a', $html); @@ -76,16 +76,16 @@ public function test_foreach_with_if_and_else_expression(): void public function test_foreach_with_if_and_forelse_expression(): void { $view = <<<'HTML' -
- {{ $label }} {{ $item }} -
- - No items - - - No label - - HTML; +
+ {{ $label }} {{ $item }} +
+ + No items + + + No label + + HTML; $html = $this->view->render(view($view)); $this->assertStringNotContainsString('Label a', $html); diff --git a/tests/Integration/View/TempestViewRendererDataPassingTest.php b/tests/Integration/View/TempestViewRendererDataPassingTest.php index 1bd3d479b5..f9df80e92c 100644 --- a/tests/Integration/View/TempestViewRendererDataPassingTest.php +++ b/tests/Integration/View/TempestViewRendererDataPassingTest.php @@ -63,8 +63,8 @@ public function test_normal_attribute_with_php_short_echo(): void 'a', $this->view->render( <<<'HTML' - a - HTML, + a + HTML, href: 'https://', ), ); @@ -77,8 +77,8 @@ public function test_normal_attribute_with_view_echo(): void 'a', $this->view->render( <<<'HTML' - a - HTML, + a + HTML, href: 'https://&', ), ); @@ -91,8 +91,8 @@ public function test_normal_attribute_with_raw_view_echo(): void 'a', $this->view->render( <<<'HTML' - a - HTML, + a + HTML, href: 'https://&', ), ); @@ -105,8 +105,8 @@ public function test_expression_attribute_with_view_echo_not_allowed(): void $this->view->render( <<<'HTML' - a - HTML, + a + HTML, ); } @@ -117,8 +117,8 @@ public function test_expression_attribute_with_raw_view_echo_not_allowed(): void $this->view->render( <<<'HTML' - a - HTML, + a + HTML, ); } @@ -129,8 +129,8 @@ public function test_expression_attribute_with_short_php_echo_not_allowed(): voi $this->view->render( <<<'HTML' - a - HTML, + a + HTML, ); } @@ -141,8 +141,8 @@ public function test_expression_attribute_with_object_without_view_component_not $this->view->render( <<<'HTML' - a - HTML, + a + HTML, object: new class() {}, ); } @@ -154,16 +154,16 @@ public function test_expression_attribute_with_object_on_view_component(): void $this->view->registerViewComponent( 'x-link', <<<'HTML' - - HTML, + + HTML, ); $this->assertSame( 'a', $this->view->render( <<<'HTML' - a - HTML, + a + HTML, object: new class() { public string $url = 'https://'; }, @@ -178,16 +178,16 @@ public function test_expression_attribute_on_view_component(): void $this->view->registerViewComponent( 'x-link', <<<'HTML' - - HTML, + + HTML, ); $this->assertSame( 'a', $this->view->render( <<<'HTML' - a - HTML, + a + HTML, href: 'https://', ), ); @@ -200,16 +200,16 @@ public function test_normal_attribute_on_view_component(): void $this->view->registerViewComponent( 'x-link', <<<'HTML' - - HTML, + + HTML, ); $this->assertSame( 'a', $this->view->render( <<<'HTML' - a - HTML, + a + HTML, ), ); } @@ -221,8 +221,8 @@ public function test_expression_attribute_with_same_name(): void $this->view->registerViewComponent( 'x-link', <<<'HTML' - - HTML, + + HTML, ); /* There's a name collision here: @@ -237,8 +237,8 @@ public function test_expression_attribute_with_same_name(): void 'a', $this->view->render( <<<'HTML' - a - HTML, + a + HTML, object: new class() { public string $url = 'https://'; }, @@ -251,15 +251,15 @@ public function test_boolean_attributes(): void $this->assertSame( '', $this->view->render(<<<'HTML' - - HTML, value: 'value', selected: true, name: 'name'), + + HTML, value: 'value', selected: true, name: 'name'), ); $this->assertSame( '', $this->view->render(<<<'HTML' - - HTML, value: 'value', selected: false, name: 'name'), + + HTML, value: 'value', selected: false, name: 'name'), ); $this->assertSame( @@ -275,12 +275,12 @@ public function test_boolean_attributes(): void public function test_falsy_bool_attribute(mixed $value): void { $html = $this->view->render(<< - HTML, show: false); +
+ HTML, show: false); $this->assertStringEqualsStringIgnoringLineEndings(<<<'HTML' -
- HTML, $html); +
+ HTML, $html); } #[TestWith(['true'])] @@ -288,23 +288,23 @@ public function test_falsy_bool_attribute(mixed $value): void public function test_truthy_bool_attribute(mixed $value): void { $html = $this->view->render(<< - HTML, show: true); +
+ HTML, show: true); $this->assertStringEqualsStringIgnoringLineEndings(<<<'HTML' -
- HTML, $html); +
+ HTML, $html); } public function test_multiple_boolean_attribute(): void { $html = $this->view->render(<< - HTML); +
+ HTML); $this->assertSnippetsMatch(<<<'HTML' -
- HTML, $html); +
+ HTML, $html); } public function test_expression_attribute_in_raw_element(): void @@ -312,20 +312,20 @@ public function test_expression_attribute_in_raw_element(): void $this->view->registerViewComponent( 'x-test', <<<'HTML' -
- HTML, +
+ HTML, ); $html = $this->view->render(<<<'HTML' - -
foo

bar

-
- HTML, language: 'php'); + +
foo

bar

+
+ HTML, language: 'php'); $this->assertSnippetsMatch( <<<'HTML' -
foo

bar

- HTML, +
foo

bar

+ HTML, $html, ); } @@ -335,31 +335,31 @@ public function test_echo_in_attributes(): void $this->assertSame( '
', $this->view->render(<< - HTML), +
+ HTML), ); $this->assertSame( '
', $this->view->render(<< - HTML), +
+ HTML), ); } public function test_boolean_attributes_in_view_component(): void { $this->view->registerViewComponent('x-test', << - -
- HTML); +
+ +
+ HTML); $html = $this->view->render(<<<'HTML' - - - - HTML); + + + + HTML); $this->assertStringContainsString(' href="hi"', $html); } @@ -367,19 +367,19 @@ public function test_boolean_attributes_in_view_component(): void public function test_global_variables_are_kept(): void { $this->view->registerViewComponent('x-test', <<<'HTML' -
{{ $item }}
- HTML); +
{{ $item }}
+ HTML); $html = $this->view->render(<<<'HTML' - - - - HTML, item: 'foo'); + + + + HTML, item: 'foo'); $this->assertSnippetsMatch(<<<'HTML' -
foo
-
foo
-
foo
- HTML, $html); +
foo
+
foo
+
foo
+ HTML, $html); } } diff --git a/tests/Integration/View/TempestViewRendererTest.php b/tests/Integration/View/TempestViewRendererTest.php index cbd9aaf583..cd516aa043 100644 --- a/tests/Integration/View/TempestViewRendererTest.php +++ b/tests/Integration/View/TempestViewRendererTest.php @@ -270,9 +270,9 @@ public function test_foreach_attribute(): void { $this->assertStringEqualsStringIgnoringLineEndings( <<<'HTML' -
a
-
b
- HTML, +
a
+
b
+ HTML, $this->view->render(view('
{{ $foo }}
')->data(items: ['a', 'b'])), ); } @@ -281,39 +281,39 @@ public function test_foreach_consumes_attribute(): void { $html = $this->view->render( <<<'HTML' - - - - - -
{{ $item }}
-
- HTML, + + + + + +
{{ $item }}
+
+ HTML, items: ['a', 'b'], ); $this->assertSnippetsMatch( <<<'HTML' - - - Home - - - - - - - - - - - -
a
b
- - - - - HTML, + + + Home + + + + + + + + + + + +
a
b
+ + + + + HTML, $html, ); } @@ -322,15 +322,15 @@ public function test_forelse_attribute(): void { $this->assertSame( <<<'HTML' -
Empty
- HTML, +
Empty
+ HTML, $this->view->render(view('
{{ $foo }}
Empty
')->data(items: [])), ); $this->assertSame( <<<'HTML' -
a
- HTML, +
a
+ HTML, $this->view->render(view('
{{ $foo }}
Empty
')->data(items: ['a'])), ); } @@ -339,8 +339,8 @@ public function test_forelse_with_other_expression_attribute(): void { $this->assertSame( <<<'HTML' -
Empty
- HTML, +
Empty
+ HTML, $this->view->render('
{{ $foo }}
Empty
', items: [], data: 'test'), ); } @@ -349,14 +349,14 @@ public function test_default_slot(): void { $this->assertSnippetsMatch( <<<'HTML' -
Test
- HTML, +
Test
+ HTML, $this->view->render( <<<'HTML' - - Test - - HTML, + + Test + + HTML, ), ); } @@ -365,18 +365,18 @@ public function test_implicit_default_slot(): void { $this->assertSnippetsMatch( <<<'HTML' -
- - Test +
+ + Test -
- HTML, +
+ HTML, $this->view->render( <<<'HTML' - - Test - - HTML, + + Test + + HTML, ), ); } @@ -385,41 +385,41 @@ public function test_multiple_slots(): void { $this->assertSnippetsMatch( <<<'HTML' - injected scripts - + injected scripts + -
- - Test - - +
+ + Test + + - - Hi + + Hi -
+
- injected styles - HTML, - $this->view->render( - <<<'HTML' - - Test - - - injected scripts - - - injected styles - - - Hi - HTML, + $this->view->render( + <<<'HTML' + + Test + + + injected scripts + + + + injected styles + + + Hi + + HTML, ), ); } @@ -428,18 +428,18 @@ public function test_pre(): void { $this->assertStringEqualsStringIgnoringLineEndings( <<<'HTML' -
a
-                    b
-                c
-            
- HTML, - $this->view->render( - <<<'HTML'
a
                         b
                     c
                 
HTML, + $this->view->render( + <<<'HTML' +
a
+                            b
+                        c
+                    
+ HTML, ), ); } @@ -456,10 +456,10 @@ public function test_raw_and_escaped(): void $html = $this->view->render(view(__DIR__ . '/../../Fixtures/Views/raw-escaped.view.php', var: '

hi

')); $this->assertStringEqualsStringIgnoringLineEndings(<<<'HTML' - <h1>hi</h1> - <H1>HI</H1> -

hi

- HTML, $html); + <h1>hi</h1> + <H1>HI</H1> +

hi

+ HTML, $html); } public function test_html_string(): void @@ -468,10 +468,10 @@ public function test_html_string(): void $this->assertStringEqualsStringIgnoringLineEndings( expected: <<<'HTML' -

hi

- <H1>HI</H1> -

hi

- HTML, +

hi

+ <H1>HI</H1> +

hi

+ HTML, actual: $html, ); } @@ -482,10 +482,10 @@ public function test_no_double_else_attributes(): void $this->view->render( <<<'HTML' -
-
-
- HTML, +
+
+
+ HTML, ); } @@ -493,25 +493,25 @@ public function test_else_must_be_after_if_or_elseif(): void { $this->view->render( <<<'HTML' -
-
- HTML, +
+
+ HTML, ); $this->view->render( <<<'HTML' -
-
-
- HTML, +
+
+
+ HTML, ); $this->expectException(ElementWasInvalid::class); $this->view->render( <<<'HTML' -
- HTML, +
+ HTML, ); } @@ -519,18 +519,18 @@ public function test_elseif_must_be_after_if_or_elseif(): void { $this->view->render( <<<'HTML' -
-
-
- HTML, +
+
+
+ HTML, ); $this->expectException(ElementWasInvalid::class); $this->view->render( <<<'HTML' -
- HTML, +
+ HTML, ); } @@ -538,17 +538,17 @@ public function test_forelse_must_be_before_foreach(): void { $this->view->render( view(<<<'HTML' -
-
- HTML, foo: []), +
+
+ HTML, foo: []), ); $this->expectException(ElementWasInvalid::class); $this->view->render( <<<'HTML' -
- HTML, +
+ HTML, ); } @@ -556,19 +556,19 @@ public function test_no_double_forelse_attributes(): void { $this->view->render( view(<<<'HTML' -
-
- HTML, foo: []), +
+
+ HTML, foo: []), ); $this->expectException(ElementWasInvalid::class); $this->view->render( view(<<<'HTML' -
-
-
- HTML, foo: []), +
+
+
+ HTML, foo: []), ); } @@ -576,8 +576,8 @@ public function test_render_element_with_attribute_with_dash(): void { $view = view( <<
- HTML, +
+ HTML, ); $html = $this->view->render($view); @@ -612,19 +612,19 @@ public function test_slot_with_comment(): void { $this->assertSnippetsMatch( <<<'HTML' -
+
- Test + Test -
- HTML, +
+ HTML, $this->view->render( <<<'HTML' - - - Test - - HTML, + + + Test + + HTML, ), ); } @@ -652,21 +652,21 @@ public function test_self_closing_component_tags_are_compiled(): void public function test_html_tags(): void { $view = <<<'HTML' - - - - - Tempest - - - - - - -

Tempest

- - - HTML; + + + + + Tempest + + + + + + +

Tempest

+ + + HTML; $html = $this->view->render($view); @@ -693,8 +693,8 @@ public function test_with_at_symbol_in_html_tag(): void $this->assertStringEqualsStringIgnoringLineEndings( <<test - HTML, + + HTML, $rendered, ); } @@ -707,8 +707,8 @@ public function test_with_colon_symbol_in_html_tag(): void $this->assertStringEqualsStringIgnoringLineEndings( <<test - HTML, + + HTML, $rendered, ); } @@ -718,10 +718,10 @@ public function test_loop_variable_can_be_used_within_the_looped_tag(): void $html = $this->view->render( view( <<<'HTML' - - {{ $item->title }} - - HTML, + + {{ $item->title }} + + HTML, ) ->data(items: [ new class { @@ -738,16 +738,16 @@ public function test_loop_variable_can_be_used_within_the_looped_tag(): void ); $this->assertSnippetsMatch(<<<'HTML' - Item 1Item 2 - HTML, $html); + Item 1Item 2 + HTML, $html); } public function test_if_and_foreach_precedence(): void { $html = $this->view->render( <<<'HTML' -
{{ $item->name }}
- HTML, +
{{ $item->name }}
+ HTML, items: [ (object) ['name' => 'A', 'show' => true], (object) ['name' => 'B', 'show' => false], @@ -759,8 +759,8 @@ public function test_if_and_foreach_precedence(): void $html = $this->view->render( <<<'HTML' -
{{ $item->name }}
- HTML, +
{{ $item->name }}
+ HTML, show: true, items: [ (object) ['name' => 'A', 'show' => true], @@ -773,8 +773,8 @@ public function test_if_and_foreach_precedence(): void $html = $this->view->render( <<<'HTML' -
{{ $item->name }}
- HTML, +
{{ $item->name }}
+ HTML, show: true, items: [ (object) ['name' => 'A', 'show' => true], @@ -787,8 +787,8 @@ public function test_if_and_foreach_precedence(): void $html = $this->view->render( <<<'HTML' -
{{ $item->name }}
- HTML, +
{{ $item->name }}
+ HTML, show: false, items: [ (object) ['name' => 'A', 'show' => true], @@ -801,8 +801,8 @@ public function test_if_and_foreach_precedence(): void $html = $this->view->render( <<<'HTML' -
{{ $item->name }}
- HTML, +
{{ $item->name }}
+ HTML, show: false, items: [ (object) ['name' => 'A', 'show' => true], @@ -815,8 +815,8 @@ public function test_if_and_foreach_precedence(): void $html = $this->view->render( <<<'HTML' -
{{ $item->name }}
- HTML, +
{{ $item->name }}
+ HTML, item: (object) ['show' => true], items: [ (object) ['name' => 'A', 'show' => true], @@ -829,8 +829,8 @@ public function test_if_and_foreach_precedence(): void $html = $this->view->render( <<<'HTML' -
{{ $item->name }}
- HTML, +
{{ $item->name }}
+ HTML, items: [ (object) ['name' => 'A', 'show' => true], (object) ['name' => 'B', 'show' => false], @@ -851,8 +851,8 @@ public function test_escape_expression_attribute(): void public function test_unclosed_php_tag(): void { $html = $this->view->render(<<<'HTML' - assertSame('hi', $html); } @@ -860,8 +860,8 @@ public function test_unclosed_php_tag(): void public function test_view_comments(): void { $html = $this->view->render(<<<'HTML' -

{{-- this is a comment --}}this is rendered text

{{-- this is a comment --}} - HTML); +

{{-- this is a comment --}}this is rendered text

{{-- this is a comment --}} + HTML); $this->assertSnippetsMatch('

this is rendered text

', $html); } @@ -869,19 +869,19 @@ public function test_view_comments(): void public function test_multiline_view_comments(): void { $html = $this->view->render(<<<'HTML' - {{-- this is a comment -
- - {{ Tempest\Intl\translate('test_2') }} - - -
- --}} -

This should be rendered

- HTML); + {{-- this is a comment +
+ + {{ Tempest\Intl\translate('test_2') }} + + +
+ --}} +

This should be rendered

+ HTML); $this->assertSnippetsMatch('

This should be rendered

', $html); } @@ -893,17 +893,17 @@ public function test_parse_rss_feed(): void } $rss = <<<'XML' - - - https://tempestphp.com/rss - - Tempest - - <![CDATA[ {!! $post['title'] !!} ]]> - - - - XML; + + + https://tempestphp.com/rss + + Tempest + + <![CDATA[ {!! $post['title'] !!} ]]> + + + + XML; $parsed = $this->view->render($rss, posts: [ ['title' => '

A

', 'url' => 'https://tempestphp.com/a'], @@ -911,27 +911,27 @@ public function test_parse_rss_feed(): void ]); $this->assertSnippetsMatch(<<<'RSS' - - - https://tempestphp.com/rss - - Tempest - - <![CDATA[ <h1>A</h1> ]]> - - - <![CDATA[ B ]]> - - - - RSS, $parsed); + + + https://tempestphp.com/rss + + Tempest + + <![CDATA[ <h1>A</h1> ]]> + + + <![CDATA[ B ]]> + + + + RSS, $parsed); } public function test_attributes_with_single_quotes(): void { $html = $this->view->render(<<<'HTML' -
- HTML); +
+ HTML); $this->assertSnippetsMatch('
', $html); } @@ -939,8 +939,8 @@ public function test_attributes_with_single_quotes(): void public function test_zero_in_attribute(): void { $html = $this->view->render(<<<'HTML' -
- HTML); +
+ HTML); $this->assertSnippetsMatch('
', $html); } diff --git a/tests/Integration/View/TwigViewRendererTest.php b/tests/Integration/View/TwigViewRendererTest.php index 68fbb9b2f1..0a009df02a 100644 --- a/tests/Integration/View/TwigViewRendererTest.php +++ b/tests/Integration/View/TwigViewRendererTest.php @@ -33,9 +33,9 @@ public function test_twig(): void $html = $renderer->render(view('index.twig', ...['foo' => 'bar'])); $this->assertStringEqualsStringIgnoringLineEndings(<< - bar - - HTML, $html); + + bar + + HTML, $html); } } diff --git a/tests/Integration/View/ViewComponentDiscoveryTest.php b/tests/Integration/View/ViewComponentDiscoveryTest.php index 5953dff517..117daef48d 100644 --- a/tests/Integration/View/ViewComponentDiscoveryTest.php +++ b/tests/Integration/View/ViewComponentDiscoveryTest.php @@ -87,8 +87,8 @@ public function test_auto_registration(): void $discovery->apply(); $html = $this->view->render(<<<'HTML' - - HTML); + + HTML); $this->assertSame('Hello World', $html); } @@ -101,8 +101,8 @@ public function test_auto_registration_with_x_component(): void $discovery->apply(); $html = $this->view->render(<<<'HTML' - - HTML); + + HTML); $this->assertSame('Hello World', $html); } diff --git a/tests/Integration/View/ViewComponentTest.php b/tests/Integration/View/ViewComponentTest.php index 5b1a471037..2ed4064ed9 100644 --- a/tests/Integration/View/ViewComponentTest.php +++ b/tests/Integration/View/ViewComponentTest.php @@ -59,8 +59,8 @@ public function test_view_component_with_php_code_in_attribute(): void expected: '
', actual: $this->view->render( <<<'HTML' - - HTML, + + HTML, input: 'hello', ), ); @@ -77,47 +77,47 @@ public function test_view_component_with_php_code_in_slot(): void public function test_view_can_access_dynamic_slots(): void { $this->view->registerViewComponent('x-test', <<<'HTML' -
-
{{ $slot->name }}
-
{{ $slot->attributes['language'] }}
-
{{ $slot->language }}
-
{!! $slot->content !!}
-
- HTML); +
+
{{ $slot->name }}
+
{{ $slot->attributes['language'] }}
+
{{ $slot->language }}
+
{!! $slot->content !!}
+
+ HTML); $html = $this->view->render(<<<'HTML_WRAP' - - PHP Body - HTML Body - - HTML_WRAP); + + PHP Body + HTML Body + + HTML_WRAP); $this->assertSnippetsMatch(<<<'HTML_WRAP' -
slot-php
PHP
PHP
PHP Body
-
slot-html
HTML
HTML
HTML Body
- HTML_WRAP, $html); +
slot-php
PHP
PHP
PHP Body
+
slot-html
HTML
HTML
HTML Body
+ HTML_WRAP, $html); } public function test_dynamic_slots_are_cleaned_up(): void { $this->view->registerViewComponent('x-test', <<<'HTML' -
-
{{ $slot->name }}
-
- - HTML); +
+
{{ $slot->name }}
+
+ + HTML); $html = $this->view->render(<<<'HTML' - - - -
internal slots still here
-
internal slots are cleared
-
+ + + +
internal slots still here
+
internal slots are cleared
+
-
slots still here
-
slots are cleared
- HTML); +
slots still here
+
slots are cleared
+ HTML); $this->assertStringContainsString('
internal slots still here
', $html); $this->assertStringContainsString('
slots are cleared
', $html); @@ -126,17 +126,17 @@ public function test_dynamic_slots_are_cleaned_up(): void public function test_dynamic_slots_include_the_default_slot(): void { $this->view->registerViewComponent('x-test', <<<'HTML' -
{{ $slots['default']->name }}
-
{{ $slots['default']->content }}
- HTML); +
{{ $slots['default']->name }}
+
{{ $slots['default']->content }}
+ HTML); $html = $this->view->render('Hello'); $this->assertSnippetsMatch( <<<'HTML' -
default
-
Hello
- HTML, +
default
+
Hello
+ HTML, $html, ); } @@ -144,29 +144,29 @@ public function test_dynamic_slots_include_the_default_slot(): void public function test_slots_with_nested_view_components(): void { $this->view->registerViewComponent('x-a', <<<'HTML' - -
-
A{{ $slot->name }}
-
- HTML); + +
+
A{{ $slot->name }}
+
+ HTML); $this->view->registerViewComponent('x-b', <<<'HTML' -
-
B{{ $slot->name }}
-
- HTML); +
+
B{{ $slot->name }}
+
+ HTML); $html = $this->view->render(<<<'HTML' - - - - - + + + + + - - - - HTML); + + + + HTML); $this->assertStringContainsString('
B1
', $html); $this->assertStringContainsString('
B2
', $html); @@ -185,9 +185,9 @@ public function test_slots_is_a_reserved_variable(): void public function test_scope_does_not_leak_data(): void { $html = $this->view->render(<<<'HTML' - - - HTML); + + + HTML); $this->assertStringContainsString('', $html); $this->assertStringContainsString('view->render(''); $this->assertSnippetsMatch(<<<'HTML' - hi + hi - -
- HTML, $html); + +
+ HTML, $html); } public function test_component_with_anther_component_included_with_slot(): void @@ -213,13 +213,13 @@ public function test_component_with_anther_component_included_with_slot(): void $html = $this->view->render('test'); $this->assertSnippetsMatch(<<<'HTML' - hi + hi - -
- test -
- HTML, $html); + +
+ test +
+ HTML, $html); } public function test_view_component_with_injected_view(): void @@ -238,8 +238,8 @@ public function test_view_component_with_injected_view(): void $html = $this->view->render(view( <<<'HTML' - - HTML, + + HTML, )); $validator = $this->container->get(Validator::class); @@ -265,8 +265,8 @@ public function test_component_with_if(): void public function test_component_with_foreach(): void { $this->view->registerViewComponent('x-test', <<<'HTML' -
- HTML); +
+ HTML); $this->assertSnippetsMatch( expected: '
a
b
', @@ -278,8 +278,8 @@ public function test_anonymous_view_component(): void { $this->assertSame( <<hi - HTML, +
hi
+ HTML, $this->view->render('hi'), ); } @@ -302,8 +302,8 @@ public function test_with_passed_variable(): void $this->assertSnippetsMatch( <<test - HTML, +
test
+ HTML, $rendered, ); } @@ -316,8 +316,8 @@ public function test_with_passed_data(): void $this->assertSnippetsMatch( <<test - HTML, +
test
+ HTML, $rendered, ); } @@ -326,14 +326,14 @@ public function test_with_passed_php_data(): void { $rendered = $this->view->render( view(<< - HTML), + + HTML), ); $this->assertSnippetsMatch( <<TEST - HTML, +
TEST
+ HTML, $rendered, ); } @@ -360,8 +360,8 @@ public function test_with_passed_variable_within_loop(): void { $rendered = $this->view->render( <<<'HTML' - - HTML, + + HTML, variables: ['a', 'b', 'c'], ); @@ -386,8 +386,8 @@ public function test_view_component_attribute_variables_without_this(): void $html = $this->view->render(view(__DIR__ . '/../../Fixtures/Views/view-component-attribute-without-this-b.view.php')); $this->assertSame(<<view->render(view(__DIR__ . '/../../Fixtures/Views/view-component-with-non-self-closing-slot-b.view.php')); $this->assertSnippetsMatch(<<view->registerViewComponent('x-test', <<<'HTML' - {{ $metaType ?? 'nothing' }} - HTML); + {{ $metaType ?? 'nothing' }} + HTML); $this->assertSame('test', $this->view->render('')); $this->assertSame('test', $this->view->render('')); @@ -432,19 +432,19 @@ public function test_template_component(): void { $html = $this->view->render( <<<'HTML' - -
item {{ $item }}
-
boo
-
- HTML, + +
item {{ $item }}
+
boo
+
+ HTML, items: ['a', 'b', 'c'], ); $this->assertSnippetsMatch(<<<'HTML' -
item a
boo
-
item b
boo
-
item c
boo
- HTML, $html); +
item a
boo
+
item b
boo
+
item c
boo
+ HTML, $html); } public static function view_components(): Generator @@ -480,29 +480,29 @@ public static function view_components(): Generator public function test_full_html_document_as_component(): void { $this->view->registerViewComponent('x-layout', <<<'HTML' - - - Tempest View - - - - - - HTML); + + + Tempest View + + + + + + HTML); $html = $this->view->render(<<<'HTML' - - Hello World - - HTML); + + Hello World + + HTML); $this->assertStringContainsString(<<<'HTML' - - - Tempest View - - - HTML, $html); + + + Tempest View + + + HTML, $html); $this->assertStringContainsString('Hello World', $html); $this->assertStringContainsString('', $html); $this->assertStringContainsString('', $html); @@ -513,23 +513,23 @@ public function test_empty_slots_are_commented_out(): void $this->container->singleton(Environment::class, Environment::LOCAL); $this->view->registerViewComponent('x-layout', <<<'HTML' - - - - - - - - HTML); + + + + + + + + HTML); $html = $this->view->render(<<<'HTML' - - - HTML); + + + HTML); $this->assertSnippetsMatch(<<<'HTML' - - HTML, $html); + + HTML, $html); } public function test_empty_slots_are_removed_in_production(): void @@ -537,131 +537,131 @@ public function test_empty_slots_are_removed_in_production(): void $this->container->singleton(Environment::class, Environment::PRODUCTION); $this->view->registerViewComponent('x-layout', <<<'HTML' - - - - - - - - HTML); + + + + + + + + HTML); $html = $this->view->render(<<<'HTML' - - - HTML); + + + HTML); $this->assertSnippetsMatch(<<<'HTML' - - HTML, $html); + + HTML, $html); } public function test_custom_components_in_head(): void { $this->view->registerViewComponent('x-custom-link', <<<'HTML' - - HTML); + + HTML); $html = $this->view->render(<<<'HTML' - - - - - - - HTML); + + + + + + + HTML); $this->assertSnippetsMatch(<<<'HTML' - - - HTML, $html); + + + HTML, $html); } public function test_head_injection(): void { $this->view->registerViewComponent('x-custom-link', <<<'HTML' - - HTML); + + HTML); $html = $this->view->render(<<<'HTML' - - - - Foo - - - - - b - - HTML); + + + + Foo + + + + + b + + HTML); $this->assertSnippetsMatch(<<<'HTML' - - Foo - b - - HTML, $html); + + Foo + b + + HTML, $html); } public function test_attributes_variable_in_view_component(): void { $this->view->registerViewComponent('x-test', <<<'HTML' -
- HTML); +
+ HTML); $html = $this->view->render(<<<'HTML' - - HTML); + + HTML); $this->assertSnippetsMatch(<<<'HTML' -
- HTML, $html); +
+ HTML, $html); } public function test_fallthrough_attributes(): void { $this->view->registerViewComponent('x-test', <<<'HTML' -
- HTML); +
+ HTML); $html = $this->view->render(<<<'HTML' - - HTML); + + HTML); $this->assertSnippetsMatch(<<<'HTML' -
- HTML, $html); +
+ HTML, $html); } public function test_merged_fallthrough_attributes(): void { $this->view->registerViewComponent('x-test', <<<'HTML' -
- HTML); +
+ HTML); $html = $this->view->render(<<<'HTML' - - HTML); + + HTML); $this->assertSnippetsMatch(<<<'HTML' -
- HTML, $html); +
+ HTML, $html); } public function test_fallthrough_attributes_with_other_attributes(): void { $this->view->registerViewComponent('x-test', <<<'HTML' -
- HTML); +
+ HTML); $html = $this->view->render(<<<'HTML' - - HTML); + + HTML); $this->assertSnippetsMatch(<<<'HTML' -
- HTML, $html); +
+ HTML, $html); } public function test_file_name_component(): void @@ -674,79 +674,79 @@ public function test_file_name_component(): void public function test_array_attribute(): void { $html = $this->view->render(<<<'HTML' -
- HTML); +
+ HTML); $this->assertSnippetsMatch(<<<'HTML' -
- HTML, $html); +
+ HTML, $html); } public function test_merge_class(): void { $this->view->registerViewComponent('x-test', <<<'HTML' -
- HTML); +
+ HTML); $html = $this->view->render(<<<'HTML' - - HTML); + + HTML); $this->assertSnippetsMatch(<<<'HTML' -
- HTML, $html); +
+ HTML, $html); } public function test_merge_class_from_template_to_component(): void { $this->view->registerViewComponent('x-test', <<<'HTML' -
- HTML); +
+ HTML); $html = $this->view->render(<<<'HTML' - - HTML); + + HTML); $this->assertSnippetsMatch(<<<'HTML' -
- HTML, $html); +
+ HTML, $html); } public function test_does_not_duplicate_br(): void { $this->view->registerViewComponent('x-html-base', <<<'HTML' - - - - - - - - - HTML); + + + + + + + + + HTML); $html = $this->view->render(<<<'HTML' - -
-
-
- HTML); + +
+
+
+ HTML); $this->assertSnippetsMatch(<<<'HTML' - -

- HTML, $html); + +

+ HTML, $html); } public function test_renders_minified_html_with_void_elements(): void { $html = $this->view->render(<<<'HTML' - - HTML); + + HTML); $this->assertSnippetsMatch(<<<'HTML' - - HTML, $html); + + HTML, $html); } public function test_multiple_instances_of_custom_component_using_slots(): void @@ -754,48 +754,48 @@ public function test_multiple_instances_of_custom_component_using_slots(): void $this->view->registerViewComponent('x-foo-bar', 'FOO-BAR'); $this->view->registerViewComponent('x-test', <<<'HTML' -
- - -
- HTML); +
+ + +
+ HTML); $html = $this->view->render(<<<'HTML' - - - - - - HTML); + + + + + + HTML); $this->assertSnippetsMatch(<<<'HTML' -
FOO-BAR - FOO-BAR -
- HTML, $html); +
FOO-BAR + FOO-BAR +
+ HTML, $html); } public function test_slots_with_hyphens(): void { $this->view->registerViewComponent('x-test', <<<'HTML' -
- -
- HTML); +
+ +
+ HTML); $html = $this->view->render(<<<'HTML' - - - Hi - - - HTML); + + + Hi + + + HTML); $this->assertSnippetsMatch(<<<'HTML' -
- Hi -
- HTML, $html); +
+ Hi +
+ HTML, $html); } public function test_nested_table_components(): void @@ -807,34 +807,34 @@ public function test_nested_table_components(): void $this->view->registerViewComponent('x-my-table-th', ''); $html = $this->view->render(<<<'HTML' - - - - Header 1 - - - - - Row 1, Cell 1 - - -
- HTML); - - $this->assertSnippetsMatch(<<<'HTML' - - - - - - - - - - + + + Header 1 + + + + + Row 1, Cell 1 + +
Header1
Row 1, Cell 1
- HTML, $html); + HTML); + + $this->assertSnippetsMatch(<<<'HTML' + + + + + + + + + + + +
Header1
Row 1, Cell 1
+ HTML, $html); } public function test_dynamic_view_component_with_string_name(): void @@ -842,8 +842,8 @@ public function test_dynamic_view_component_with_string_name(): void $this->view->registerViewComponent('x-test', '
{{ $prop }}
'); $html = $this->view->render(<<<'HTML' - - HTML); + + HTML); $this->assertSame('
test
', $html); } @@ -853,8 +853,8 @@ public function test_dynamic_view_component_with_expression_name(): void $this->view->registerViewComponent('x-test', '
{{ $prop }}
'); $html = $this->view->render(<<<'HTML' - - HTML, name: 'x-test'); + + HTML, name: 'x-test'); $this->assertSame('
test
', $html); } @@ -864,8 +864,8 @@ public function test_dynamic_view_component_with_variable_attribute(): void $this->view->registerViewComponent('x-test', '
{{ $prop }}
'); $html = $this->view->render(<<<'HTML' - - HTML, name: 'x-test', input: 'test'); + + HTML, name: 'x-test', input: 'test'); $this->assertSame('
test
', $html); } @@ -875,8 +875,8 @@ public function test_dynamic_view_component_with_slot(): void $this->view->registerViewComponent('x-test', '
'); $html = $this->view->render(<<<'HTML' - test - HTML, name: 'x-test'); + test + HTML, name: 'x-test'); $this->assertSnippetsMatch('
test
', $html); } @@ -888,8 +888,8 @@ public function dynamic_view_component_keeps_foreach_scope(): void $html = $this->view->render( <<<'HTML' - {{ $item }} - HTML, + {{ $item }} + HTML, name: 'x-test', items: ['a', 'b'], ); @@ -903,10 +903,10 @@ public function test_nested_slots(): void $this->view->registerViewComponent('x-b', ''); $html = $this->view->render(<<<'HTML' - - hi - - HTML); + + hi + + HTML); $this->assertSnippetsMatch('hi', $html); } @@ -915,18 +915,18 @@ public function test_nested_slots_with_escaping(): void { $this->view->registerViewComponent('x-a', ''); $this->view->registerViewComponent('x-b', <<<'HTML' - - {{ get(Environment::class)->value }} - HTML); + + {{ get(Environment::class)->value }} + HTML); $html = $this->view->render(<<<'HTML' - - - - HTML); + + + + HTML); $this->assertSnippetsMatch('testing', $html); } @@ -936,10 +936,10 @@ public function test_repeated_local_var_across_view_components(): void $this->view->registerViewComponent('x-test', '
{{ $thing }}
'); $html = $this->view->render(<<<'HTML' - - - - HTML); + + + + HTML); $this->assertSnippetsMatch('
a
@@ -960,17 +960,17 @@ public function test_escape_expression_attribute_in_view_components(): void public function test_default_slot_value(): void { $this->view->registerViewComponent('x-test', <<<'HTML' - Default - Default A - Default B - HTML); + Default + Default A + Default B + HTML); $this->assertSnippetsMatch( <<<'HTML' - Overwritten - Overwritten A - Overwritten B - HTML, + Overwritten + Overwritten A + Overwritten B + HTML, $this->view->render(' Overwritten Overwritten A @@ -980,10 +980,10 @@ public function test_default_slot_value(): void $this->assertSnippetsMatch( <<<'HTML' - Overwritten - Default A - Overwritten B - HTML, + Overwritten + Default A + Overwritten B + HTML, $this->view->render(' Overwritten Overwritten B @@ -991,10 +991,10 @@ public function test_default_slot_value(): void ); $this->assertSnippetsMatch(<<<'HTML' - Default - Default A - Default B - HTML, $this->view->render('')); + Default + Default A + Default B + HTML, $this->view->render('')); } public function test_view_variables_are_passed_into_the_component(): void @@ -1002,10 +1002,10 @@ public function test_view_variables_are_passed_into_the_component(): void $this->view->registerViewComponent('x-a', ''); $html = $this->view->render(<<<'HTML' - - {{ $title }} - - HTML, title: 'test'); + + {{ $title }} + + HTML, title: 'test'); $this->assertSnippetsMatch('test', $html); } @@ -1017,12 +1017,12 @@ public function test_capture_outer_scope_view_component_variables(): void $html = $this->view->render( <<<'HTML' - - - {{ $item }} - - - HTML, + + + {{ $item }} + + + HTML, items: ['a', 'b'], ); @@ -1042,13 +1042,13 @@ public function test_imports_in_slots_from_root_node(): void $this->view->registerViewComponent('x-test', '
'); $html = $this->view->render(<<<'HTML' - + - {{ uri(HomeController::class) }} - HTML); + {{ uri(HomeController::class) }} + HTML); $this->assertSame('
/
', $html); } @@ -1056,25 +1056,25 @@ public function test_imports_in_slots_from_root_node(): void public function test_combined_imports_from_root_node_and_view_component(): void { $this->view->registerViewComponent('x-parent', <<<'HTML' -
- HTML); +
+ HTML); $this->view->registerViewComponent('x-child', <<<'HTML' - -
- HTML); + +
+ HTML); $html = $this->view->render(<<<'HTML' - + - - {{ uri(HomeController::class) }} - - HTML); + + {{ uri(HomeController::class) }} + + HTML); $this->assertSnippetsMatch('
/
', $html); } @@ -1173,22 +1173,22 @@ function (ViewCompilationFailed $exception) use ($exceptionRenderer): void { public function test_imports_with_nested_view_components(): void { $this->view->registerViewComponent('x-card', <<<'HTML' -
- HTML); +
+ HTML); $this->view->registerViewComponent('x-footer', <<<'HTML' - - HTML); + + HTML); $html = $this->view->render(<<<'HTML' - - - {{ uri(HomeController::class) }} - - HTML); + + + {{ uri(HomeController::class) }} + + HTML); $this->assertSnippetsMatch('
/
', $html); } @@ -1199,18 +1199,18 @@ public function test_imports_in_nested_html_elements(): void $this->view->registerViewComponent('x-b', '
">'); $html = $this->view->render(<<<'HTML' - - -
- - {{ uri(HomeController::class) }} - -
-
- HTML); + + +
+ + {{ uri(HomeController::class) }} + +
+
+ HTML); $this->assertSnippetsMatch('
/
">
">', $html); } diff --git a/tests/Integration/View/ViewTest.php b/tests/Integration/View/ViewTest.php index 90a8c587d4..317043aa16 100644 --- a/tests/Integration/View/ViewTest.php +++ b/tests/Integration/View/ViewTest.php @@ -41,8 +41,8 @@ public function test_render_with_view_model(): void $html = $this->view->render($view); $expected = <<assertEquals($expected, $html); } diff --git a/tests/Integration/Vite/DevelopmentTagsResolverTest.php b/tests/Integration/Vite/DevelopmentTagsResolverTest.php index 20fa380083..cc67d2e77d 100644 --- a/tests/Integration/Vite/DevelopmentTagsResolverTest.php +++ b/tests/Integration/Vite/DevelopmentTagsResolverTest.php @@ -29,11 +29,6 @@ protected function setUp(): void public function test_resolve_tags(): void { $this->vite->call( - files: [ - 'src/main.ts' => '', - 'src/foo.ts' => '', - 'src/tailwind.css' => '', - ], callback: function (): void { $resolver = new DevelopmentTagsResolver( bridgeFile: new ViteBridgeFile(url: 'http://localhost'), @@ -50,6 +45,11 @@ public function test_resolve_tags(): void actual: $resolver->resolveTags(['src/main.ts', 'src/foo.ts', 'src/tailwind.css']), ); }, + files: [ + 'src/main.ts' => '', + 'src/foo.ts' => '', + 'src/tailwind.css' => '', + ], ); } @@ -58,9 +58,6 @@ public function test_throw_if_entrypoint_not_found(): void $this->expectException(FileSystemEntrypointWasNotFoundException::class); $this->vite->call( - files: [ - 'src/main.ts' => '', - ], callback: function (): void { $resolver = new DevelopmentTagsResolver( bridgeFile: new ViteBridgeFile(url: 'http://localhost'), @@ -69,6 +66,9 @@ public function test_throw_if_entrypoint_not_found(): void $resolver->resolveTags(['src/main.ts', 'src/foo.ts']); }, + files: [ + 'src/main.ts' => '', + ], ); } @@ -80,11 +80,6 @@ public function test_automatically_converts_relative_paths(): void ); $this->vite->call( - files: [ - 'src/main.ts' => '', - 'src/foo.ts' => '', - 'src/bar/baz.ts' => '', - ], callback: function (): void { $resolver = new DevelopmentTagsResolver( bridgeFile: new ViteBridgeFile(url: 'http://localhost'), @@ -101,6 +96,11 @@ public function test_automatically_converts_relative_paths(): void actual: $resolver->resolveTags(['src/main.ts', 'src/foo.ts', './src/bar/baz.ts']), ); }, + files: [ + 'src/main.ts' => '', + 'src/foo.ts' => '', + 'src/bar/baz.ts' => '', + ], ); } } diff --git a/tests/Integration/Vite/GenericTagCompilerTest.php b/tests/Integration/Vite/GenericTagCompilerTest.php index 36aa6387ac..7b68197885 100644 --- a/tests/Integration/Vite/GenericTagCompilerTest.php +++ b/tests/Integration/Vite/GenericTagCompilerTest.php @@ -41,7 +41,7 @@ public function test_generate_legacy_script_tag(): void public function test_generate_legacy_script_tag_with_polyfills(): void { $generator = $this->container->get(GenericTagCompiler::class); - $tag = $generator->compileScriptTag('/build/main.js', $this->createChunk(legacy: true, src: 'vite/legacy-polyfills')); + $tag = $generator->compileScriptTag('/build/main.js', $this->createChunk(src: 'vite/legacy-polyfills', legacy: true)); $this->assertStringContainsString('Foo - - HTML, + Foo + + HTML, actual: $html, ); }, @@ -63,19 +63,19 @@ public function test_dev_entrypoints(): void )); $html = $this->view->render(<<<'HTML' - - - - - Foo - - HTML); + + + + + Foo + + HTML); $this->assertSnippetsMatch( expected: <<Foo - - HTML, + Foo + + HTML, actual: $html, ); }, @@ -96,19 +96,19 @@ public function test_dev_entrypoints_from_config(): void )); $html = $this->view->render(<<<'HTML' - - - - - Foo - - HTML); + + + + + Foo + + HTML); $this->assertSnippetsMatch( expected: <<Foo - - HTML, + Foo + + HTML, actual: $html, ); }, @@ -129,26 +129,26 @@ public function test_dev_entrypoints_from_config_and_react_refresh_from_bridgefi )); $html = $this->view->render(<<<'HTML' - - - - - Foo - - HTML); + + + + + Foo + + HTML); $this->assertSnippetsMatch( expected: << - Foo - - HTML, + + Foo + + HTML, actual: $html, ); }, @@ -173,17 +173,17 @@ public function test_production_entrypoint_from_config(): void )); $html = $this->view->render(<<<'HTML' - - - - - - - HTML); + + + + + + + HTML); $this->assertSnippetsMatch(<<<'HTML' - - HTML, $html); + + HTML, $html); }, files: [ 'public/build/manifest.json' => $this->fixture('two-unrelated-entrypoints.json'), @@ -201,17 +201,17 @@ public function test_production_entrypoint(): void )); $html = $this->view->render(<<<'HTML' - - - - - - - HTML); + + + + + + + HTML); $this->assertSnippetsMatch(<<<'HTML' - - HTML, $html); + + HTML, $html); }, files: [ 'public/build/manifest.json' => $this->fixture('two-unrelated-entrypoints.json'), @@ -229,17 +229,17 @@ public function test_production_entrypoints(): void )); $html = $this->view->render(<<<'HTML' - - - - - - - HTML); + + + + + + + HTML); $this->assertSnippetsMatch(<<<'HTML' - - HTML, $html); + + HTML, $html); }, files: [ 'public/build/manifest.json' => $this->fixture('two-unrelated-entrypoints.json'), diff --git a/tests/Integration/Vite/ViteTest.php b/tests/Integration/Vite/ViteTest.php index 9fcceb0cfc..1cee1c9559 100644 --- a/tests/Integration/Vite/ViteTest.php +++ b/tests/Integration/Vite/ViteTest.php @@ -190,7 +190,6 @@ public function test_get_tags_with_entrypoints_and_global_entrypoints(): void public function test_discovery(): void { $this->vite->call( - root: __DIR__ . '/Fixtures/tmp', callback: function (string $path): void { $discovery = $this->container->get(ViteDiscovery::class); $discovery->setItems(new DiscoveryItems([])); @@ -209,6 +208,7 @@ public function test_discovery(): void 'src/main.entrypoint.ts' => '', 'public/vite-tempest' => ['url' => 'http://localhost:5173'], ], + root: __DIR__ . '/Fixtures/tmp', ); } } diff --git a/utils/rector/src/ImportClassNamesRector.php b/utils/rector/src/ImportClassNamesRector.php new file mode 100644 index 0000000000..337338cd7a --- /dev/null +++ b/utils/rector/src/ImportClassNamesRector.php @@ -0,0 +1,173 @@ + */ + private array $excludedClasses = []; + + public function __construct( + private readonly NameImporter $nameImporter, + private readonly UseImportsResolver $useImportsResolver, + ) { + } + + /** + * @param array{importShortClasses?: bool, excludedClasses?: list} $configuration + */ + public function configure(array $configuration): void + { + SimpleParameterProvider::setParameter( + Option::IMPORT_SHORT_CLASSES, + $configuration['importShortClasses'] ?? true, + ); + + $this->excludedClasses = array_map( + static fn (string $class): string => ltrim($class, '\\'), + $configuration['excludedClasses'] ?? [], + ); + } + + public function getNodeTypes(): array + { + return [FullyQualified::class]; + } + + public function refactor(Node $node): ?Name + { + if (! $node instanceof FullyQualified) { + return null; + } + + if ($node->getAttribute(AttributeKey::IS_FUNCCALL_NAME) === true) { + return null; + } + + if ($node->getAttribute(AttributeKey::IS_CONSTFETCH_NAME) === true) { + return null; + } + + if ($this->isAlreadyShortInSource($node)) { + return null; + } + + if (in_array($node->toString(), $this->excludedClasses, true)) { + return null; + } + + $currentUses = $this->useImportsResolver->resolve(); + + $imported = $this->nameImporter->importName($node, $this->file, $currentUses); + + if ($imported instanceof Name) { + return $imported; + } + + return $this->shortenSameNamespaceName($node, $currentUses); + } + + /** + * @param array $currentUses + */ + private function shortenSameNamespaceName(FullyQualified $node, array $currentUses): ?Name + { + $namespaceName = $this->resolveCurrentNamespace(); + + if ($namespaceName === null) { + return null; + } + + $fqcn = $node->toString(); + $shortName = $node->getLast(); + $fqcnNamespace = substr($fqcn, 0, -(strlen($shortName) + 1)); + + if ($fqcnNamespace !== $namespaceName) { + return null; + } + + if ($this->hasConflictingUseStatement($shortName, $fqcn, $currentUses)) { + return null; + } + + return new Name($shortName); + } + + private function isAlreadyShortInSource(FullyQualified $node): bool + { + $startTokenPos = $node->getStartTokenPos(); + $oldTokens = $this->file->getOldTokens(); + if (! isset($oldTokens[$startTokenPos])) { + return false; + } + $originalText = $oldTokens[$startTokenPos]->text; + return ! str_contains($originalText, '\\'); + } + + private function resolveCurrentNamespace(): ?string + { + $filePath = $this->file->getFilePath(); + + if ($this->currentFilePath === $filePath) { + return $this->currentNamespace; + } + + $this->currentFilePath = $filePath; + $this->currentNamespace = null; + + $fileNode = $this->file->getFileNode(); + + if ($fileNode === null) { + return null; + } + + $namespace = $fileNode->getNamespace(); + + if ($namespace?->name !== null) { + $this->currentNamespace = $namespace->name->toString(); + } + + return $this->currentNamespace; + } + + /** + * @param array $currentUses + */ + private function hasConflictingUseStatement(string $shortName, string $fqcn, array $currentUses): bool + { + foreach ($currentUses as $use) { + foreach ($use->uses as $useUse) { + $importedName = $use instanceof GroupUse + ? $use->prefix . '\\' . $useUse->name->toString() + : $useUse->name->toString(); + + $alias = $useUse->alias?->toString() ?? $useUse->name->getLast(); + + if ($alias === $shortName && $importedName !== $fqcn) { + return true; + } + } + } + + return false; + } +}