\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 AppendLogChannelis 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( "", "", ), - $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("", ""), }; }); @@ -181,13 +181,13 @@ public function __invoke( } } - if ($failures) { + if ($failures !== 0) { $this->keyValue('Failures', ""); } $this->keyValue('Static pages 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 -%s> -HTML, $is, $attributeString, $content, $is); + <%s %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: '